From e9de693b7f32c82ef36b22d2aefb5177c3ff43fa Mon Sep 17 00:00:00 2001 From: Francesco Paolo Severino Date: Wed, 4 Jun 2025 17:36:56 +0200 Subject: [PATCH 01/47] Add an external mu variant of the ML-DSA API (65 and 87 variants) --- .../_CryptoExtras/MLDSA/MLDSA_boring.swift | 201 ++++++++++++++++++ .../MLDSA/MLDSA_boring.swift.gyb | 102 +++++++++ Tests/_CryptoExtrasTests/MLDSATests.swift | 26 +++ 3 files changed, 329 insertions(+) diff --git a/Sources/_CryptoExtras/MLDSA/MLDSA_boring.swift b/Sources/_CryptoExtras/MLDSA/MLDSA_boring.swift index 51941f563..329b90ae9 100644 --- a/Sources/_CryptoExtras/MLDSA/MLDSA_boring.swift +++ b/Sources/_CryptoExtras/MLDSA/MLDSA_boring.swift @@ -75,6 +75,17 @@ extension MLDSA65 { try self.backing.signature(for: data, context: context) } + /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). + /// + /// > Note: The message representative should be obtained via calls to ``MLDSA65/PublicKey/prehash(for:context:)``. + /// + /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). + /// + /// - Returns: The signature of the prehashed message representative. + public func signature(forPrehashedMessageRepresentative mu: M) throws -> Data { + try self.backing.signature(forPrehashedMessageRepresentative: mu) + } + /// The size of the private key in bytes. static let byteCount = Backing.byteCount @@ -175,6 +186,38 @@ extension MLDSA65 { return signature } + /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). + /// + /// > Note: The message representative should be obtained via calls to ``MLDSA65/PublicKey/prehash(for:context:)``. + /// + /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). + /// + /// - Returns: The signature of the prehashed message representative. + func signature(forPrehashedMessageRepresentative mu: M) throws -> Data { + guard mu.count == MLDSA.muByteCount else { + throw CryptoKitError.incorrectParameterSize + } + + var signature = Data(repeating: 0, count: MLDSA65.signatureByteCount) + + let rc: CInt = signature.withUnsafeMutableBytes { signaturePtr in + let muBytes: ContiguousBytes = mu.regions.count == 1 ? mu.regions.first! : Array(mu) + return muBytes.withUnsafeBytes { muPtr in + CCryptoBoringSSL_MLDSA65_sign_message_representative( + signaturePtr.baseAddress, + &self.key, + muPtr.baseAddress + ) + } + } + + guard rc == 1 else { + throw CryptoKitError.internalBoringSSLError() + } + + return signature + } + /// The size of the private key in bytes. static let byteCount = Int(MLDSA65_PRIVATE_KEY_BYTES) } @@ -233,6 +276,27 @@ extension MLDSA65 { self.backing.isValidSignature(signature, for: data, context: context) } + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameter data: The message to prehash. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + public func prehash(for data: D) throws -> Data { + let context: Data? = nil + return try self.backing.prehash(for: data, context: context) + } + + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameters: + /// - data: The message to prehash. + /// - context: The context of the message. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + public func prehash(for data: D, context: C) throws -> Data { + try self.backing.prehash(for: data, context: context) + } + /// The size of the public key in bytes. static let byteCount = Backing.byteCount @@ -314,6 +378,41 @@ extension MLDSA65 { } } + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameters: + /// - data: The message to prehash. + /// - context: The context of the message. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + func prehash(for data: D, context: C?) throws -> Data { + var mu = Data(repeating: 0, count: MLDSA.muByteCount) + + let dataBytes: ContiguousBytes = data.regions.count == 1 ? data.regions.first! : Array(data) + let rc: CInt = mu.withUnsafeMutableBytes { muPtr in + dataBytes.withUnsafeBytes { dataPtr in + context.withUnsafeBytes { contextPtr in + var prehash = MLDSA65_prehash() + let rc = CCryptoBoringSSL_MLDSA65_prehash_init( + &prehash, + &key, + contextPtr.baseAddress, + contextPtr.count + ) + CCryptoBoringSSL_MLDSA65_prehash_update(&prehash, dataPtr.baseAddress, dataPtr.count) + CCryptoBoringSSL_MLDSA65_prehash_finalize(muPtr.baseAddress, &prehash) + return rc + } + } + } + + guard rc == 1 else { + throw CryptoKitError.internalBoringSSLError() + } + + return mu + } + /// The size of the public key in bytes. static let byteCount = Int(MLDSA65_PUBLIC_KEY_BYTES) } @@ -381,6 +480,17 @@ extension MLDSA87 { try self.backing.signature(for: data, context: context) } + /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). + /// + /// > Note: The message representative should be obtained via calls to ``MLDSA87/PublicKey/prehash(for:context:)``. + /// + /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). + /// + /// - Returns: The signature of the prehashed message representative. + public func signature(forPrehashedMessageRepresentative mu: M) throws -> Data { + try self.backing.signature(forPrehashedMessageRepresentative: mu) + } + /// The size of the private key in bytes. static let byteCount = Backing.byteCount @@ -481,6 +591,38 @@ extension MLDSA87 { return signature } + /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). + /// + /// > Note: The message representative should be obtained via calls to ``MLDSA87/PublicKey/prehash(for:context:)``. + /// + /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). + /// + /// - Returns: The signature of the prehashed message representative. + func signature(forPrehashedMessageRepresentative mu: M) throws -> Data { + guard mu.count == MLDSA.muByteCount else { + throw CryptoKitError.incorrectParameterSize + } + + var signature = Data(repeating: 0, count: MLDSA87.signatureByteCount) + + let rc: CInt = signature.withUnsafeMutableBytes { signaturePtr in + let muBytes: ContiguousBytes = mu.regions.count == 1 ? mu.regions.first! : Array(mu) + return muBytes.withUnsafeBytes { muPtr in + CCryptoBoringSSL_MLDSA87_sign_message_representative( + signaturePtr.baseAddress, + &self.key, + muPtr.baseAddress + ) + } + } + + guard rc == 1 else { + throw CryptoKitError.internalBoringSSLError() + } + + return signature + } + /// The size of the private key in bytes. static let byteCount = Int(MLDSA87_PRIVATE_KEY_BYTES) } @@ -539,6 +681,27 @@ extension MLDSA87 { self.backing.isValidSignature(signature, for: data, context: context) } + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameter data: The message to prehash. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + public func prehash(for data: D) throws -> Data { + let context: Data? = nil + return try self.backing.prehash(for: data, context: context) + } + + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameters: + /// - data: The message to prehash. + /// - context: The context of the message. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + public func prehash(for data: D, context: C) throws -> Data { + try self.backing.prehash(for: data, context: context) + } + /// The size of the public key in bytes. static let byteCount = Backing.byteCount @@ -620,6 +783,41 @@ extension MLDSA87 { } } + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameters: + /// - data: The message to prehash. + /// - context: The context of the message. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + func prehash(for data: D, context: C?) throws -> Data { + var mu = Data(repeating: 0, count: MLDSA.muByteCount) + + let dataBytes: ContiguousBytes = data.regions.count == 1 ? data.regions.first! : Array(data) + let rc: CInt = mu.withUnsafeMutableBytes { muPtr in + dataBytes.withUnsafeBytes { dataPtr in + context.withUnsafeBytes { contextPtr in + var prehash = MLDSA87_prehash() + let rc = CCryptoBoringSSL_MLDSA87_prehash_init( + &prehash, + &key, + contextPtr.baseAddress, + contextPtr.count + ) + CCryptoBoringSSL_MLDSA87_prehash_update(&prehash, dataPtr.baseAddress, dataPtr.count) + CCryptoBoringSSL_MLDSA87_prehash_finalize(muPtr.baseAddress, &prehash) + return rc + } + } + } + + guard rc == 1 else { + throw CryptoKitError.internalBoringSSLError() + } + + return mu + } + /// The size of the public key in bytes. static let byteCount = Int(MLDSA87_PUBLIC_KEY_BYTES) } @@ -635,4 +833,7 @@ extension MLDSA87 { private enum MLDSA { /// The size of the seed in bytes. fileprivate static let seedByteCount = 32 + + /// The size of the "mu" value in bytes. + fileprivate static let muByteCount = 64 } diff --git a/Sources/_CryptoExtras/MLDSA/MLDSA_boring.swift.gyb b/Sources/_CryptoExtras/MLDSA/MLDSA_boring.swift.gyb index 91a86c18d..a5ddd98ee 100644 --- a/Sources/_CryptoExtras/MLDSA/MLDSA_boring.swift.gyb +++ b/Sources/_CryptoExtras/MLDSA/MLDSA_boring.swift.gyb @@ -79,6 +79,17 @@ extension MLDSA${parameter_set} { try self.backing.signature(for: data, context: context) } + /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). + /// + /// > Note: The message representative should be obtained via calls to ``MLDSA${parameter_set}/PublicKey/prehash(for:context:)``. + /// + /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). + /// + /// - Returns: The signature of the prehashed message representative. + public func signature(forPrehashedMessageRepresentative mu: M) throws -> Data { + try self.backing.signature(forPrehashedMessageRepresentative: mu) + } + /// The size of the private key in bytes. static let byteCount = Backing.byteCount @@ -179,6 +190,38 @@ extension MLDSA${parameter_set} { return signature } + /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). + /// + /// > Note: The message representative should be obtained via calls to ``MLDSA${parameter_set}/PublicKey/prehash(for:context:)``. + /// + /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). + /// + /// - Returns: The signature of the prehashed message representative. + func signature(forPrehashedMessageRepresentative mu: M) throws -> Data { + guard mu.count == MLDSA.muByteCount else { + throw CryptoKitError.incorrectParameterSize + } + + var signature = Data(repeating: 0, count: MLDSA${parameter_set}.signatureByteCount) + + let rc: CInt = signature.withUnsafeMutableBytes { signaturePtr in + let muBytes: ContiguousBytes = mu.regions.count == 1 ? mu.regions.first! : Array(mu) + return muBytes.withUnsafeBytes { muPtr in + CCryptoBoringSSL_MLDSA${parameter_set}_sign_message_representative( + signaturePtr.baseAddress, + &self.key, + muPtr.baseAddress + ) + } + } + + guard rc == 1 else { + throw CryptoKitError.internalBoringSSLError() + } + + return signature + } + /// The size of the private key in bytes. static let byteCount = Int(MLDSA${parameter_set}_PRIVATE_KEY_BYTES) } @@ -237,6 +280,27 @@ extension MLDSA${parameter_set} { self.backing.isValidSignature(signature, for: data, context: context) } + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameter data: The message to prehash. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + public func prehash(for data: D) throws -> Data { + let context: Data? = nil + return try self.backing.prehash(for: data, context: context) + } + + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameters: + /// - data: The message to prehash. + /// - context: The context of the message. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + public func prehash(for data: D, context: C) throws -> Data { + try self.backing.prehash(for: data, context: context) + } + /// The size of the public key in bytes. static let byteCount = Backing.byteCount @@ -318,6 +382,41 @@ extension MLDSA${parameter_set} { } } + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameters: + /// - data: The message to prehash. + /// - context: The context of the message. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + func prehash(for data: D, context: C?) throws -> Data { + var mu = Data(repeating: 0, count: MLDSA.muByteCount) + + let dataBytes: ContiguousBytes = data.regions.count == 1 ? data.regions.first! : Array(data) + let rc: CInt = mu.withUnsafeMutableBytes { muPtr in + dataBytes.withUnsafeBytes { dataPtr in + context.withUnsafeBytes { contextPtr in + var prehash = MLDSA${parameter_set}_prehash() + let rc = CCryptoBoringSSL_MLDSA${parameter_set}_prehash_init( + &prehash, + &key, + contextPtr.baseAddress, + contextPtr.count + ) + CCryptoBoringSSL_MLDSA${parameter_set}_prehash_update(&prehash, dataPtr.baseAddress, dataPtr.count) + CCryptoBoringSSL_MLDSA${parameter_set}_prehash_finalize(muPtr.baseAddress, &prehash) + return rc + } + } + } + + guard rc == 1 else { + throw CryptoKitError.internalBoringSSLError() + } + + return mu + } + /// The size of the public key in bytes. static let byteCount = Int(MLDSA${parameter_set}_PUBLIC_KEY_BYTES) } @@ -334,4 +433,7 @@ extension MLDSA${parameter_set} { private enum MLDSA { /// The size of the seed in bytes. fileprivate static let seedByteCount = 32 + + /// The size of the "mu" value in bytes. + fileprivate static let muByteCount = 64 } diff --git a/Tests/_CryptoExtrasTests/MLDSATests.swift b/Tests/_CryptoExtrasTests/MLDSATests.swift index e19582dc5..24ca3bb52 100644 --- a/Tests/_CryptoExtrasTests/MLDSATests.swift +++ b/Tests/_CryptoExtrasTests/MLDSATests.swift @@ -157,6 +157,32 @@ final class MLDSATests: XCTestCase { XCTAssertThrowsError(try MLDSA87.PublicKey(rawRepresentation: encodedPublicKey)) } + func testMLDSA65PrehashedSigning() throws { + let message = "Hello, world!".data(using: .utf8)! + let context = "ctx".data(using: .utf8)! + + let key = try MLDSA65.PrivateKey() + let publicKey = key.publicKey + + let mu = try publicKey.prehash(for: message, context: context) + + let muSignature = try key.signature(forPrehashedMessageRepresentative: mu) + XCTAssertTrue(publicKey.isValidSignature(muSignature, for: message, context: context)) + } + + func testMLDSA87PrehashedSigning() throws { + let message = "Hello, world!".data(using: .utf8)! + let context = "ctx".data(using: .utf8)! + + let key = try MLDSA87.PrivateKey() + let publicKey = key.publicKey + + let mu = try publicKey.prehash(for: message, context: context) + + let muSignature = try key.signature(forPrehashedMessageRepresentative: mu) + XCTAssertTrue(publicKey.isValidSignature(muSignature, for: message, context: context)) + } + func testMLDSA65NISTKeyGenFile() throws { try nistTest(jsonName: "mldsa_nist_keygen_65_tests") { (testVector: NISTKeyGenTestVector) in let seed = try Data(hexString: testVector.seed) From b5dde9c658c58fbd61751b0e4cad1cdd4fe5b2fe Mon Sep 17 00:00:00 2001 From: Cory Benfield Date: Mon, 16 Jun 2025 14:54:28 +0100 Subject: [PATCH 02/47] Bring swift-crypto up to date with CryptoKit 2025 Beta 1 (#359) This PR sets swift-crypto up for alignment with the WWDC 2025 CryptoKit APIs. This includes the parity APIs for MLKEM and MLDSA, as well as XWing. At this time the SHA3 APIs are disabled, as they require a novel implementation strategy. This will come later in the summer. All API features that require SHA3 are therefore also disabled at runtime. --- .swiftformatignore | 11 + Package.swift | 9 +- .../include/CCryptoBoringSSL.h | 2 + Sources/Crypto/AEADs/AES/GCM/AES-GCM.swift | 35 +- .../Crypto/AEADs/ChachaPoly/ChaChaPoly.swift | 18 +- Sources/Crypto/AEADs/Cipher.swift | 12 +- Sources/Crypto/AEADs/Nonces.swift | 45 +- Sources/Crypto/AEADs/Nonces.swift.gyb | 34 +- Sources/Crypto/ASN1/ASN1.swift | 134 +-- .../ASN1/Basic ASN1 Types/ASN1Any.swift | 19 +- .../ASN1/Basic ASN1 Types/ASN1BitString.swift | 21 +- .../ASN1/Basic ASN1 Types/ASN1Boolean.swift | 17 +- .../Basic ASN1 Types/ASN1Identifier.swift | 11 +- .../ASN1/Basic ASN1 Types/ASN1Integer.swift | 43 +- .../ASN1/Basic ASN1 Types/ASN1Null.swift | 15 +- .../Basic ASN1 Types/ASN1OctetString.swift | 19 +- .../ASN1/Basic ASN1 Types/ASN1Strings.swift | 159 +++- .../Basic ASN1 Types/ArraySliceBigint.swift | 13 +- .../Basic ASN1 Types/GeneralizedTime.swift | 99 +- .../Basic ASN1 Types/ObjectIdentifier.swift | 23 +- Sources/Crypto/ASN1/ECDSASignature.swift | 13 +- Sources/Crypto/ASN1/PEMDocument.swift | 5 + Sources/Crypto/ASN1/PKCS8PrivateKey.swift | 18 +- Sources/Crypto/ASN1/SEC1PrivateKey.swift | 27 +- .../Crypto/ASN1/SubjectPublicKeyInfo.swift | 25 +- Sources/Crypto/CMakeLists.txt | 12 + Sources/Crypto/CryptoKitErrors.swift | 55 ++ Sources/Crypto/Digests/Digest.swift | 26 +- Sources/Crypto/Digests/Digests.swift | 346 ++++++- Sources/Crypto/Digests/Digests.swift.gyb | 129 ++- Sources/Crypto/Digests/HashFunctions.swift | 15 +- .../Crypto/Digests/HashFunctions_SHA2.swift | 93 +- .../Crypto/Digests/HashFunctions_SHA3.swift | 234 +++++ .../Crypto/HPKE/Ciphersuite/HPKE-AEAD.swift | 29 +- .../HPKE/Ciphersuite/HPKE-Ciphersuite.swift | 14 +- .../Crypto/HPKE/Ciphersuite/HPKE-KDF.swift | 20 +- .../Ciphersuite/HPKE-KexKeyDerivation.swift | 10 +- .../Ciphersuite/HPKE-LabeledExtract.swift | 6 + .../Crypto/HPKE/Ciphersuite/HPKE-Utils.swift | 12 + .../Ciphersuite/KEM/Conformances/DHKEM.swift | 43 +- .../Conformances/HPKE-KEM-Curve25519.swift | 8 +- .../KEM/Conformances/HPKE-NIST-EC-KEMs.swift | 7 +- .../HPKE/Ciphersuite/KEM/HPKE-KEM.swift | 63 +- Sources/Crypto/HPKE/HPKE-Errors.swift | 5 + Sources/Crypto/HPKE/HPKE.swift | 63 +- .../HPKE/Key Schedule/HPKE-Context.swift | 23 +- .../HPKE/Key Schedule/HPKE-KeySchedule.swift | 20 +- Sources/Crypto/Insecure/Insecure.swift | 2 +- .../Insecure/Insecure_HashFunctions.swift | 28 +- .../KEM/BoringSSL}/MLKEM_boring.swift | 106 ++- .../KEM/BoringSSL}/MLKEM_boring.swift.gyb | 67 +- .../Crypto/KEM/BoringSSL/MLKEM_wrapper.swift | 269 ++++++ .../Crypto/KEM/BoringSSL/XWing_boring.swift | 236 +++++ Sources/Crypto/KEM/KEM-Errors.swift | 37 + Sources/Crypto/KEM/KEM.swift | 54 +- Sources/Crypto/KEM/MLKEM.swift | 282 ++++++ Sources/Crypto/KEM/MLKEM.swift.gyb | 158 ++++ Sources/Crypto/KEM/XWing.swift | 193 ++++ Sources/Crypto/Key Agreement/DH.swift | 88 +- Sources/Crypto/Key Agreement/ECDH.swift | 236 +++-- Sources/Crypto/Key Agreement/ECDH.swift.gyb | 48 +- Sources/Crypto/Key Derivation/ANSIx963.swift | 72 ++ Sources/Crypto/Key Derivation/HKDF.swift | 20 +- Sources/Crypto/Key Wrapping/AESWrap.swift | 13 +- Sources/Crypto/Keys/EC/Curve25519.swift | 2 +- Sources/Crypto/Keys/EC/Ed25519Keys.swift | 18 +- Sources/Crypto/Keys/EC/NISTCurvesKeys.swift | 12 +- Sources/Crypto/Keys/EC/X25519Keys.swift | 26 +- .../Crypto/Keys/Symmetric/SymmetricKeys.swift | 23 +- .../HMAC/HMAC.swift | 29 +- .../MACFunctions.swift | 6 +- .../MessageAuthenticationCode.swift | 23 +- Sources/Crypto/PRF/AES.swift | 2 +- .../Signatures/BoringSSL}/MLDSA_boring.swift | 95 +- .../BoringSSL}/MLDSA_boring.swift.gyb | 53 +- .../Signatures/BoringSSL/MLDSA_wrapper.swift | 150 +++ Sources/Crypto/Signatures/ECDSA.swift | 100 +- Sources/Crypto/Signatures/ECDSA.swift.gyb | 40 +- Sources/Crypto/Signatures/Ed25519.swift | 12 +- Sources/Crypto/Signatures/MLDSA.swift | 286 ++++++ Sources/Crypto/Signatures/MLDSA.swift.gyb | 163 ++++ Sources/Crypto/Signatures/Signature.swift | 10 +- .../Optional+withUnsafeBytes_boring.swift} | 0 Sources/Crypto/Util/PrettyBytes.swift | 18 +- Sources/Crypto/Util/SafeCompare.swift | 6 +- Sources/Crypto/Util/SecureBytes.swift | 219 ++++- Sources/Crypto/Util/Zeroization.swift | 6 +- Sources/_CryptoExtras/CMakeLists.txt | 4 +- Sources/_CryptoExtras/Reexport.swift | 15 + Tests/CryptoTests/ASN1/ASN1Tests.swift | 148 ++- .../ASN1/GeneralizedTimeTests.swift | 2 +- .../AES-GCM-Runner.swift | 23 +- .../ChaChaPoly-Runner.swift | 23 +- Tests/CryptoTests/Digests/DigestsTests.swift | 65 +- .../Encodings/ECKeyEncodingsTests.swift | 863 +++++++----------- .../HPKE/HPKETests-TestVectors.swift | 9 +- Tests/CryptoTests/HPKE/HPKETests.swift | 83 +- .../KEM/Boring/XWingTests_boring.swift | 52 ++ Tests/CryptoTests/KEM/MLKEM1024KAT.json | 702 ++++++++++++++ Tests/CryptoTests/KEM/MLKEM1024_BSSLKAT.json | 503 ++++++++++ Tests/CryptoTests/KEM/MLKEM768KAT.json | 703 ++++++++++++++ Tests/CryptoTests/KEM/MLKEM768_BSSLKAT.json | 502 ++++++++++ Tests/CryptoTests/KEM/MLKEMKeyGenTests.swift | 118 +++ Tests/CryptoTests/KEM/MLKEMTests.swift | 167 ++++ Tests/CryptoTests/KEM/XWingTests.swift | 123 +++ Tests/CryptoTests/KEM/test-vectors.json | 1 + .../SecureBytes/SecureBytesTests.swift | 7 +- .../ECDSA/ECDSASignatureTests.swift | 26 +- .../Signatures/EdDSA/Ed25519-Runner.swift | 2 +- .../Signatures/MLDSA/MLDSA65_KeyGen_KAT.json | 127 +++ .../Signatures/MLDSA/MLDSA87_KeyGen_KAT.json | 127 +++ .../Signatures/MLDSA/MLDSAKeyGenTests.swift | 117 +++ .../Signatures/MLDSA/MLDSATests.swift | 89 ++ Tests/CryptoTests/Utils/Boring/CTRDRBG.swift | 72 ++ .../Utils/Boring/SequenceDRBG.swift | 30 + Tests/CryptoTests/Utils/PrettyBytes.swift | 18 +- Tests/CryptoTests/Utils/XCTestUtils.swift | 12 + Tests/_CryptoExtrasTests/MLDSATests.swift | 105 ++- Tests/_CryptoExtrasTests/MLKEMTests.swift | 26 +- scripts/vendor-boringssl.sh | 2 + 120 files changed, 8480 insertions(+), 1654 deletions(-) create mode 100644 Sources/Crypto/Digests/HashFunctions_SHA3.swift rename Sources/{_CryptoExtras/MLKEM => Crypto/KEM/BoringSSL}/MLKEM_boring.swift (85%) rename Sources/{_CryptoExtras/MLKEM => Crypto/KEM/BoringSSL}/MLKEM_boring.swift.gyb (85%) create mode 100644 Sources/Crypto/KEM/BoringSSL/MLKEM_wrapper.swift create mode 100644 Sources/Crypto/KEM/BoringSSL/XWing_boring.swift create mode 100644 Sources/Crypto/KEM/KEM-Errors.swift create mode 100644 Sources/Crypto/KEM/MLKEM.swift create mode 100644 Sources/Crypto/KEM/MLKEM.swift.gyb create mode 100644 Sources/Crypto/KEM/XWing.swift create mode 100644 Sources/Crypto/Key Derivation/ANSIx963.swift rename Sources/{_CryptoExtras/MLDSA => Crypto/Signatures/BoringSSL}/MLDSA_boring.swift (88%) rename Sources/{_CryptoExtras/MLDSA => Crypto/Signatures/BoringSSL}/MLDSA_boring.swift.gyb (90%) create mode 100644 Sources/Crypto/Signatures/BoringSSL/MLDSA_wrapper.swift create mode 100644 Sources/Crypto/Signatures/MLDSA.swift create mode 100644 Sources/Crypto/Signatures/MLDSA.swift.gyb rename Sources/{_CryptoExtras/Util/Optional+withUnsafeBytes.swift => Crypto/Util/BoringSSL/Optional+withUnsafeBytes_boring.swift} (100%) create mode 100644 Sources/_CryptoExtras/Reexport.swift create mode 100644 Tests/CryptoTests/KEM/Boring/XWingTests_boring.swift create mode 100644 Tests/CryptoTests/KEM/MLKEM1024KAT.json create mode 100644 Tests/CryptoTests/KEM/MLKEM1024_BSSLKAT.json create mode 100644 Tests/CryptoTests/KEM/MLKEM768KAT.json create mode 100644 Tests/CryptoTests/KEM/MLKEM768_BSSLKAT.json create mode 100644 Tests/CryptoTests/KEM/MLKEMKeyGenTests.swift create mode 100644 Tests/CryptoTests/KEM/MLKEMTests.swift create mode 100644 Tests/CryptoTests/KEM/XWingTests.swift create mode 100644 Tests/CryptoTests/KEM/test-vectors.json create mode 100644 Tests/CryptoTests/Signatures/MLDSA/MLDSA65_KeyGen_KAT.json create mode 100644 Tests/CryptoTests/Signatures/MLDSA/MLDSA87_KeyGen_KAT.json create mode 100644 Tests/CryptoTests/Signatures/MLDSA/MLDSAKeyGenTests.swift create mode 100644 Tests/CryptoTests/Signatures/MLDSA/MLDSATests.swift create mode 100644 Tests/CryptoTests/Utils/Boring/CTRDRBG.swift create mode 100644 Tests/CryptoTests/Utils/Boring/SequenceDRBG.swift diff --git a/.swiftformatignore b/.swiftformatignore index 03469d9a9..997aafb9c 100644 --- a/.swiftformatignore +++ b/.swiftformatignore @@ -25,6 +25,7 @@ Sources/Crypto/Digests/Digest.swift Sources/Crypto/Digests/Digests.swift Sources/Crypto/Digests/HashFunctions.swift Sources/Crypto/Digests/HashFunctions_SHA2.swift +Sources/Crypto/Digests/HashFunctions_SHA3.swift Sources/Crypto/HPKE/Ciphersuite/HPKE-AEAD.swift Sources/Crypto/HPKE/Ciphersuite/HPKE-Ciphersuite.swift Sources/Crypto/HPKE/Ciphersuite/HPKE-KDF.swift @@ -43,8 +44,12 @@ Sources/Crypto/HPKE/Modes/HPKE-Modes.swift Sources/Crypto/Insecure/Insecure.swift Sources/Crypto/Insecure/Insecure_HashFunctions.swift Sources/Crypto/KEM/KEM.swift +Sources/Crypto/KEM/KEM-Errors.swift +Sources/Crypto/KEM/MLKEM.swift +Sources/Crypto/KEM/XWing.swift Sources/Crypto/Key Agreement/DH.swift Sources/Crypto/Key Agreement/ECDH.swift +Sources/Crypto/Key Derivation/ANSIx963.swift Sources/Crypto/Key Derivation/HKDF.swift Sources/Crypto/Key Wrapping/AESWrap.swift Sources/Crypto/Keys/EC/Curve25519.swift @@ -58,6 +63,7 @@ Sources/Crypto/Message Authentication Codes/MessageAuthenticationCode.swift Sources/Crypto/PRF/AES.swift Sources/Crypto/Signatures/ECDSA.swift Sources/Crypto/Signatures/Ed25519.swift +Sources/Crypto/Signatures/MLDSA.swift Sources/Crypto/Signatures/Signature.swift Sources/Crypto/Util/PrettyBytes.swift Sources/Crypto/Util/SafeCompare.swift @@ -116,6 +122,9 @@ Tests/CryptoTests/Encodings/DERTests.swift Tests/CryptoTests/Encodings/ECKeyEncodingsTests.swift Tests/CryptoTests/HPKE/HPKETests-TestVectors.swift Tests/CryptoTests/HPKE/HPKETests.swift +Tests/CryptoTests/KEM/MLKEMKeyGenTests.swift +Tests/CryptoTests/KEM/MLKEMTests.swift +Tests/CryptoTests/KEM/XWingTests.swift Tests/CryptoTests/Key Derivation/ECprivateKeysFromSeeds.swift Tests/CryptoTests/Key Derivation/HKDFTests.swift Tests/CryptoTests/Key Derivation/SharedSecretTests.swift @@ -126,6 +135,8 @@ Tests/CryptoTests/SecureBytes/SecureBytesTests.swift Tests/CryptoTests/Signatures/ECDSA/ECDSASignatureTests.swift Tests/CryptoTests/Signatures/ECDSA/RawECDSASignaturesTests.swift Tests/CryptoTests/Signatures/EdDSA/Ed25519-Runner.swift +Tests/CryptoTests/Signatures/MLDSA/MLDSAKeyGenTests.swift +Tests/CryptoTests/Signatures/MLDSA/MLDSATests.swift Tests/CryptoTests/Utils/PrettyBytes.swift Tests/CryptoTests/Utils/RFCVector.swift Tests/CryptoTests/Utils/SplitData.swift diff --git a/Package.swift b/Package.swift index 28d7d715d..4f177f4ac 100644 --- a/Package.swift +++ b/Package.swift @@ -177,7 +177,14 @@ let package = Package( name: "CryptoTests", dependencies: ["Crypto"], resources: [ - .copy("HPKE/hpke-test-vectors.json") + .copy("HPKE/hpke-test-vectors.json"), + .copy("KEM/MLKEM768_BSSLKAT.json"), + .copy("KEM/MLKEM768KAT.json"), + .copy("KEM/MLKEM1024_BSSLKAT.json"), + .copy("KEM/MLKEM1024KAT.json"), + .copy("KEM/test-vectors.json"), + .copy("Signatures/MLDSA/MLDSA65_KeyGen_KAT.json"), + .copy("Signatures/MLDSA/MLDSA87_KeyGen_KAT.json"), ], swiftSettings: swiftSettings ), diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL.h index a7bdf1440..7b5a35ab2 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL.h @@ -31,6 +31,7 @@ #include "CCryptoBoringSSL_cmac.h" #include "CCryptoBoringSSL_conf.h" #include "CCryptoBoringSSL_cpu.h" +#include "CCryptoBoringSSL_ctrdrbg.h" #include "CCryptoBoringSSL_curve25519.h" #include "CCryptoBoringSSL_des.h" #include "CCryptoBoringSSL_e_os2.h" @@ -62,5 +63,6 @@ #include "CCryptoBoringSSL_siphash.h" #include "CCryptoBoringSSL_trust_token.h" #include "CCryptoBoringSSL_x509v3.h" +#include "CCryptoBoringSSL_xwing.h" #endif // C_CRYPTO_BORINGSSL_H diff --git a/Sources/Crypto/AEADs/AES/GCM/AES-GCM.swift b/Sources/Crypto/AEADs/AES/GCM/AES-GCM.swift index f91fa950a..1ba3ca8ad 100644 --- a/Sources/Crypto/AEADs/AES/GCM/AES-GCM.swift +++ b/Sources/Crypto/AEADs/AES/GCM/AES-GCM.swift @@ -14,23 +14,26 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else -#if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +#if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) typealias AESGCMImpl = CoreCryptoGCMImpl -import Security #else @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) typealias AESGCMImpl = OpenSSLAESGCMImpl #endif -import Foundation +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +public import SwiftSystem +#else +public import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension AES { /// The Advanced Encryption Standard (AES) Galois Counter Mode (GCM) cipher /// suite. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public enum GCM: Cipher { + public enum GCM: Cipher, Sendable { static let tagByteCount = 16 static let defaultNonceByteCount = 12 @@ -41,12 +44,12 @@ extension AES { /// - Parameters: /// - message: The plaintext data to seal. /// - key: A cryptographic key used to seal the message. - /// - nonce: The nonce the sealing process requires. If you don't provide a nonce, the method generates a random one by invoking ``AES.GCM.Nonce()``. + /// - nonce: The nonce the sealing process requires. If you don't provide a nonce, the method generates a random one by invoking ``AES/GCM/Nonce/init()``. /// - authenticatedData: Additional data to be authenticated. /// /// - Returns: The sealed message. public static func seal - (_ message: Plaintext, using key: SymmetricKey, nonce: Nonce? = nil, authenticating authenticatedData: AuthenticatedData) throws -> SealedBox { + (_ message: Plaintext, using key: SymmetricKey, nonce: Nonce? = nil, authenticating authenticatedData: AuthenticatedData) throws(CryptoKitMetaError) -> SealedBox { return try AESGCMImpl.seal(key: key, message: message, nonce: nonce, authenticatedData: authenticatedData) } @@ -56,11 +59,11 @@ extension AES { /// - Parameters: /// - message: The plaintext data to seal. /// - key: A cryptographic key used to seal the message. - /// - nonce: The nonce the sealing process requires. If you don't provide a nonce, the method generates a random one by invoking ``AES.GCM.Nonce()``. + /// - nonce: The nonce the sealing process requires. If you don't provide a nonce, the method generates a random one by invoking ``AES/GCM/Nonce/init()``. /// /// - Returns: The sealed message. public static func seal - (_ message: Plaintext, using key: SymmetricKey, nonce: Nonce? = nil) throws -> SealedBox { + (_ message: Plaintext, using key: SymmetricKey, nonce: Nonce? = nil) throws(CryptoKitMetaError) -> SealedBox { return try AESGCMImpl.seal(key: key, message: message, nonce: nonce, authenticatedData: Data?.none) } @@ -76,7 +79,7 @@ extension AES { /// box, as long as the correct key is used and authentication succeeds. /// The call throws an error if decryption or authentication fail. public static func open - (_ sealedBox: SealedBox, using key: SymmetricKey, authenticating authenticatedData: AuthenticatedData) throws -> Data { + (_ sealedBox: SealedBox, using key: SymmetricKey, authenticating authenticatedData: AuthenticatedData) throws(CryptoKitMetaError) -> Data { return try AESGCMImpl.open(key: key, sealedBox: sealedBox, authenticatedData: authenticatedData) } @@ -89,7 +92,7 @@ extension AES { /// - Returns: The original plaintext message that was sealed in the /// box, as long as the correct key is used and authentication succeeds. /// The call throws an error if decryption or authentication fail. - public static func open(_ sealedBox: SealedBox, using key: SymmetricKey) throws -> Data { + public static func open(_ sealedBox: SealedBox, using key: SymmetricKey) throws(CryptoKitMetaError) -> Data { return try AESGCMImpl.open(key: key, sealedBox: sealedBox, authenticatedData: Data?.none) } } @@ -112,7 +115,7 @@ extension AES.GCM { /// The receiver uses another instance of the same cipher, like the /// ``open(_:using:)`` method, to open the box. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public struct SealedBox: AEADSealedBox { + public struct SealedBox: AEADSealedBox, Sendable { private let combinedRepresentation: Data private let nonceByteCount: Int @@ -167,13 +170,17 @@ extension AES.GCM { /// - combined: The combined bytes of the nonce, encrypted data, and /// authentication tag. @inlinable - public init(combined: D) throws { + public init(combined: D) throws(CryptoKitMetaError) { // AES minimum nonce (12 bytes) + AES tag (16 bytes) // While we have these values in the internal APIs, we can't use it in inlinable code. let aesGCMOverhead = 12 + 16 if combined.count < aesGCMOverhead { + #if hasFeature(Embedded) + throw CryptoKitMetaError.cryptoKitError(underlyingError: CryptoKitError.incorrectParameterSize) + #else throw CryptoKitError.incorrectParameterSize + #endif } self.init(combined: Data(combined)) @@ -185,9 +192,9 @@ extension AES.GCM { /// - nonce: The nonce. /// - ciphertext: The encrypted data. /// - tag: The authentication tag. - public init(nonce: AES.GCM.Nonce, ciphertext: C, tag: T) throws { + public init(nonce: AES.GCM.Nonce, ciphertext: C, tag: T) throws(CryptoKitMetaError) { guard tag.count == AES.GCM.tagByteCount else { - throw CryptoKitError.incorrectParameterSize + throw error(CryptoKitError.incorrectParameterSize) } let nonceByteCount = nonce.bytes.count diff --git a/Sources/Crypto/AEADs/ChachaPoly/ChaChaPoly.swift b/Sources/Crypto/AEADs/ChachaPoly/ChaChaPoly.swift index b1aee7cb3..223cb521b 100644 --- a/Sources/Crypto/AEADs/ChachaPoly/ChaChaPoly.swift +++ b/Sources/Crypto/AEADs/ChachaPoly/ChaChaPoly.swift @@ -14,20 +14,24 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else -#if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +#if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) typealias ChaChaPolyImpl = CoreCryptoChaChaPolyImpl -import Security #else @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) typealias ChaChaPolyImpl = OpenSSLChaChaPolyImpl #endif -import Foundation +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +public import SwiftSystem +#else +public import Foundation +#endif + /// An implementation of the ChaCha20-Poly1305 cipher. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -public enum ChaChaPoly: Cipher { +public enum ChaChaPoly: Cipher, Sendable { static let tagByteCount = 16 static let keyBitsCount = 256 static let nonceByteCount = 12 @@ -39,7 +43,7 @@ public enum ChaChaPoly: Cipher { /// - Parameters: /// - message: The plaintext data to seal. /// - key: A cryptographic key used to seal the message. - /// - nonce: The nonce the sealing process requires. If you don't provide a nonce, the method generates a random one by invoking ``ChaChaPoly.Nonce()``. + /// - nonce: The nonce the sealing process requires. If you don't provide a nonce, the method generates a random one by invoking ``ChaChaPoly/Nonce/init()``. /// - authenticatedData: Additional data to be authenticated. /// /// - Returns: The sealed message. @@ -54,7 +58,7 @@ public enum ChaChaPoly: Cipher { /// - Parameters: /// - message: The plaintext data to seal. /// - key: A cryptographic key used to seal the message. - /// - nonce: The nonce the sealing process requires. If you don't provide a nonce, the method generates a random one by invoking ``ChaChaPoly.Nonce()``. + /// - nonce: The nonce the sealing process requires. If you don't provide a nonce, the method generates a random one by invoking ``ChaChaPoly/Nonce/init()``. /// /// - Returns: The sealed message. public static func seal @@ -111,7 +115,7 @@ extension ChaChaPoly { /// ``open(_:using:)`` method, to open the box. @frozen @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public struct SealedBox: AEADSealedBox { + public struct SealedBox: AEADSealedBox, Sendable { /// A combined element composed of the tag, the nonce, and the /// ciphertext. /// diff --git a/Sources/Crypto/AEADs/Cipher.swift b/Sources/Crypto/AEADs/Cipher.swift index 9d6293f8a..8ac46f1e7 100644 --- a/Sources/Crypto/AEADs/Cipher.swift +++ b/Sources/Crypto/AEADs/Cipher.swift @@ -14,10 +14,16 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else + +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else import Foundation +#endif + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -protocol AEADSealedBox { +protocol AEADSealedBox: Sendable { associatedtype Nonce: Sequence /// The authentication tag var tag: Data { get } @@ -52,7 +58,7 @@ protocol Cipher { /// - Returns: The sealed box containing the ciphertext and authentication tag /// - Throws: An error occurred while encrypting or authenticating. static func seal - (_ message: Plaintext, using key: SymmetricKey, nonce: Nonce?, authenticating: AuthenticatedData) throws -> SealedBox + (_ message: Plaintext, using key: SymmetricKey, nonce: Nonce?, authenticating: AuthenticatedData) throws(CryptoKitMetaError) -> SealedBox /// Opens the sealed box. This decrypts and verifies the authenticity of the message, /// and optionally verifies the authenticity of the authenticated data. @@ -65,6 +71,6 @@ protocol Cipher { /// - Returns: Returns the data, if the correct key is used and the authenticated data matches the one from the seal operation. /// - Throws: An error occurred while decrypting or authenticating. static func open - (_ sealedBox: SealedBox, using key: Key, authenticating: AuthenticatedData) throws -> Data + (_ sealedBox: SealedBox, using key: Key, authenticating: AuthenticatedData) throws(CryptoKitMetaError) -> Data } #endif diff --git a/Sources/Crypto/AEADs/Nonces.swift b/Sources/Crypto/AEADs/Nonces.swift index fb03ebe7f..7310294a3 100644 --- a/Sources/Crypto/AEADs/Nonces.swift +++ b/Sources/Crypto/AEADs/Nonces.swift @@ -14,11 +14,18 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else -import Foundation +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +public import SwiftSystem +#else +public import Foundation +#endif // MARK: - Generated file, do NOT edit // any edits of this file WILL be overwritten and thus discarded // see section `gyb` in `README` for details. + + + // MARK: - AES.GCM + Nonce @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension AES.GCM { @@ -28,7 +35,7 @@ extension AES.GCM { /// that nonces are unique per call to encryption APIs in order to protect the /// integrity of the encryption. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public struct Nonce: ContiguousBytes, Sequence { + public struct Nonce: ContiguousBytes, Sequence, Sendable { let bytes: Data /// Creates a new random nonce. @@ -49,11 +56,11 @@ extension AES.GCM { /// ``init()`` method to instead create a random nonce. /// /// - Parameters: - /// - data: A 12-byte data representation of the nonce. The initializer throws an - /// error if the data has a length other than 12 bytes. - public init(data: D) throws { +/// - data: A data representation of the nonce. +/// The initializer throws an error if the data has a length smaller than 12 bytes. + public init(data: D) throws(CryptoKitMetaError) { if data.count < AES.GCM.defaultNonceByteCount { - throw CryptoKitError.incorrectParameterSize + throw error(CryptoKitError.incorrectParameterSize) } self.bytes = Data(data) @@ -70,10 +77,16 @@ extension AES.GCM { /// the duration of the closure’s execution. /// /// - Returns: The return value, if any, of the body closure parameter. +#if !hasFeature(Embedded) public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R { return try self.bytes.withUnsafeBytes(body) } - +#else + public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws(E) -> R) throws(E) -> R { + return try self.bytes.withUnsafeBytes(body) + } +#endif + /// Returns an iterator over the elements of the nonce. public func makeIterator() -> Array.Iterator { self.withUnsafeBytes({ (buffPtr) in @@ -92,7 +105,7 @@ extension ChaChaPoly { /// that nonces are unique per call to encryption APIs in order to protect the /// integrity of the encryption. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public struct Nonce: ContiguousBytes, Sequence { + public struct Nonce: ContiguousBytes, Sequence, Sendable { let bytes: Data /// Creates a new random nonce. @@ -113,11 +126,11 @@ extension ChaChaPoly { /// ``init()`` method to instead create a random nonce. /// /// - Parameters: - /// - data: A 12-byte data representation of the nonce. The initializer throws an - /// error if the data has a length other than 12 bytes. - public init(data: D) throws { +/// - data: A 12-byte data representation of the nonce. +/// The initializer throws an error if the data isn't 12 bytes long. + public init(data: D) throws(CryptoKitMetaError) { if data.count != ChaChaPoly.nonceByteCount { - throw CryptoKitError.incorrectParameterSize + throw error(CryptoKitError.incorrectParameterSize) } self.bytes = Data(data) @@ -134,10 +147,16 @@ extension ChaChaPoly { /// the duration of the closure’s execution. /// /// - Returns: The return value, if any, of the body closure parameter. +#if !hasFeature(Embedded) public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R { return try self.bytes.withUnsafeBytes(body) } - +#else + public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws(E) -> R) throws(E) -> R { + return try self.bytes.withUnsafeBytes(body) + } +#endif + /// Returns an iterator over the elements of the nonce. public func makeIterator() -> Array.Iterator { self.withUnsafeBytes({ (buffPtr) in diff --git a/Sources/Crypto/AEADs/Nonces.swift.gyb b/Sources/Crypto/AEADs/Nonces.swift.gyb index 19a25bb2a..9b05da21d 100644 --- a/Sources/Crypto/AEADs/Nonces.swift.gyb +++ b/Sources/Crypto/AEADs/Nonces.swift.gyb @@ -14,18 +14,31 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else -import Foundation +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +public import SwiftSystem +#else +public import Foundation +#endif // MARK: - Generated file, do NOT edit // any edits of this file WILL be overwritten and thus discarded // see section `gyb` in `README` for details. + %{ -ciphers = [{"name": "AES.GCM", "recommendedNonceSize": "AES.GCM.defaultNonceByteCount", "nonceValidation": "< AES.GCM.defaultNonceByteCount"},{"name": "ChaChaPoly", "recommendedNonceSize": "ChaChaPoly.nonceByteCount", "nonceValidation": "!= ChaChaPoly.nonceByteCount"}] +ciphers = [{"name": "AES.GCM", "recommendedNonceSize": "AES.GCM.defaultNonceByteCount", "nonceValidation": "< AES.GCM.defaultNonceByteCount", "dataDescription": "/// - data: A data representation of the nonce.\n/// The initializer throws an error if the data has a length smaller than 12 bytes."}] + +if "NO_CHACHAPOLY" in globals(): + pass +else: + ciphers.append({"name": "ChaChaPoly", "recommendedNonceSize": "ChaChaPoly.nonceByteCount", "nonceValidation": "!= ChaChaPoly.nonceByteCount", "dataDescription": "/// - data: A 12-byte data representation of the nonce.\n/// The initializer throws an error if the data isn't 12 bytes long."}) }% + + % for cipher in ciphers: %{ name = cipher["name"] nonceSize = cipher["recommendedNonceSize"] nonceValidation = cipher["nonceValidation"] +dataDescription = cipher["dataDescription"] }% // MARK: - ${name} + Nonce @@ -35,7 +48,7 @@ extension ${name} { /// Don’t reuse the same nonce for multiple calls to encryption APIs. It’s critical /// that nonces are unique per call to encryption APIs in order to protect the /// integrity of the encryption. - public struct Nonce: ContiguousBytes, Sequence { + public struct Nonce: ContiguousBytes, Sequence, Sendable { let bytes: Data /// Creates a new random nonce. @@ -56,11 +69,10 @@ extension ${name} { /// ``init()`` method to instead create a random nonce. /// /// - Parameters: - /// - data: A 12-byte data representation of the nonce. The initializer throws an - /// error if the data has a length other than 12 bytes. - public init(data: D) throws { +${dataDescription} + public init(data: D) throws(CryptoKitMetaError) { if data.count ${nonceValidation} { - throw CryptoKitError.incorrectParameterSize + throw error(CryptoKitError.incorrectParameterSize) } self.bytes = Data(data) @@ -77,10 +89,16 @@ extension ${name} { /// the duration of the closure’s execution. /// /// - Returns: The return value, if any, of the body closure parameter. +#if !hasFeature(Embedded) public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R { return try self.bytes.withUnsafeBytes(body) } - +#else + public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws(E) -> R) throws(E) -> R { + return try self.bytes.withUnsafeBytes(body) + } +#endif + /// Returns an iterator over the elements of the nonce. public func makeIterator() -> Array.Iterator { self.withUnsafeBytes({ (buffPtr) in diff --git a/Sources/Crypto/ASN1/ASN1.swift b/Sources/Crypto/ASN1/ASN1.swift index dc189d9e6..fdd17f81a 100644 --- a/Sources/Crypto/ASN1/ASN1.swift +++ b/Sources/Crypto/ASN1/ASN1.swift @@ -14,7 +14,12 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else + +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else import Foundation +#endif // This module implements "just enough" ASN.1. Specifically, we implement exactly enough ASN.1 DER parsing to handle // the following use-cases: @@ -130,20 +135,22 @@ extension ASN1 { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1.ASN1ParserNode: Hashable { } +#if !hasFeature(Embedded) @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1.ASN1ParserNode: CustomStringConvertible { var description: String { return "ASN1.ASN1ParserNode(identifier: \(self.identifier), depth: \(self.depth), dataBytes: \(self.dataBytes?.count ?? 0))" } } +#endif // MARK: - Sequence, SequenceOf, and Set @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1 { /// Parse the node as an ASN.1 sequence. - internal static func sequence(_ node: ASN1Node, identifier: ASN1.ASN1Identifier, _ builder: (inout ASN1.ASN1NodeCollection.Iterator) throws -> T) throws -> T { + internal static func sequence(_ node: ASN1Node, identifier: ASN1.ASN1Identifier, _ builder: (inout ASN1.ASN1NodeCollection.Iterator) throws(CryptoKitMetaError) -> T) throws(CryptoKitMetaError) -> T { guard node.identifier == identifier, case .constructed(let nodes) = node.content else { - throw CryptoKitASN1Error.unexpectedFieldType + throw error(CryptoKitASN1Error.unexpectedFieldType) } var iterator = nodes.makeIterator() @@ -151,31 +158,36 @@ extension ASN1 { let result = try builder(&iterator) guard iterator.next() == nil else { - throw CryptoKitASN1Error.invalidASN1Object + throw error(CryptoKitASN1Error.invalidASN1Object) } return result } - internal static func sequence(of: T.Type = T.self, identifier: ASN1.ASN1Identifier, rootNode: ASN1Node) throws -> [T] { + internal static func sequence(of: T.Type = T.self, identifier: ASN1.ASN1Identifier, rootNode: ASN1Node) throws(CryptoKitMetaError) -> [T] { guard rootNode.identifier == identifier, case .constructed(let nodes) = rootNode.content else { - throw CryptoKitASN1Error.unexpectedFieldType + throw error(CryptoKitASN1Error.unexpectedFieldType) } - return try nodes.map { try T(asn1Encoded: $0) } + var sequence = [T]() + // sequence.reserveCapacity(?) + for node in nodes { + sequence.append(try T(asn1Encoded: node)) + } + return sequence } - internal static func sequence(of: T.Type = T.self, identifier: ASN1.ASN1Identifier, nodes: inout ASN1.ASN1NodeCollection.Iterator) throws -> [T] { + internal static func sequence(of: T.Type = T.self, identifier: ASN1.ASN1Identifier, nodes: inout ASN1.ASN1NodeCollection.Iterator) throws(CryptoKitMetaError) -> [T] { guard let node = nodes.next() else { // Not present, throw. - throw CryptoKitASN1Error.invalidASN1Object + throw error(CryptoKitASN1Error.invalidASN1Object) } return try sequence(of: T.self, identifier: identifier, rootNode: node) } /// Parse the node as an ASN.1 set. - internal static func set(_ node: ASN1Node, identifier: ASN1.ASN1Identifier, _ builder: (inout ASN1.ASN1NodeCollection.Iterator) throws -> T) throws -> T { + internal static func set(_ node: ASN1Node, identifier: ASN1.ASN1Identifier, _ builder: (inout ASN1.ASN1NodeCollection.Iterator) throws(CryptoKitMetaError) -> T) throws(CryptoKitMetaError) -> T { // Shhhh these two are secretly the same with identifier. return try sequence(node, identifier: identifier, builder) } @@ -187,7 +199,7 @@ extension ASN1 { /// Parses an optional explicitly tagged element. Throws on a tag mismatch, returns nil if the element simply isn't there. /// /// Expects to be used with the `ASN1.sequence` helper function. - internal static func optionalExplicitlyTagged(_ nodes: inout ASN1.ASN1NodeCollection.Iterator, tagNumber: Int, tagClass: ASN1.ASN1Identifier.TagClass, _ builder: (ASN1Node) throws -> T) throws -> T? { + internal static func optionalExplicitlyTagged(_ nodes: inout ASN1.ASN1NodeCollection.Iterator, tagNumber: Int, tagClass: ASN1.ASN1Identifier.TagClass, _ builder: (ASN1Node) throws(CryptoKitMetaError) -> T) throws(CryptoKitMetaError) -> T? { var localNodesCopy = nodes guard let node = localNodesCopy.next() else { // Node not present, return nil. @@ -212,7 +224,7 @@ extension ASN1 { var nodeIterator = nodes.makeIterator() guard let child = nodeIterator.next(), nodeIterator.next() == nil else { - throw CryptoKitASN1Error.invalidASN1Object + throw error(CryptoKitASN1Error.invalidASN1Object) } return try builder(child) @@ -226,7 +238,7 @@ extension ASN1 { /// be replaced with its default. /// /// Expects to be used with the `ASN1.sequence` helper function. - internal static func decodeDefault(_ nodes: inout ASN1.ASN1NodeCollection.Iterator, identifier: ASN1.ASN1Identifier, defaultValue: T, _ builder: (ASN1Node) throws -> T) throws -> T { + internal static func decodeDefault(_ nodes: inout ASN1.ASN1NodeCollection.Iterator, identifier: ASN1.ASN1Identifier, defaultValue: T, _ builder: (ASN1Node) throws(CryptoKitMetaError) -> T) throws(CryptoKitMetaError) -> T { // A weird trick here: we only want to consume the next node _if_ it has the right tag. To achieve that, // we work on a copy. var localNodesCopy = nodes @@ -247,18 +259,18 @@ extension ASN1 { // DER forbids encoding DEFAULT values at their default state. // We can lift this in BER. guard parsed != defaultValue else { - throw CryptoKitASN1Error.invalidASN1Object + throw error(CryptoKitASN1Error.invalidASN1Object) } return parsed } - internal static func decodeDefaultExplicitlyTagged(_ nodes: inout ASN1.ASN1NodeCollection.Iterator, tagNumber: Int, tagClass: ASN1.ASN1Identifier.TagClass, defaultValue: T, _ builder: (ASN1Node) throws -> T) throws -> T { + internal static func decodeDefaultExplicitlyTagged(_ nodes: inout ASN1.ASN1NodeCollection.Iterator, tagNumber: Int, tagClass: ASN1.ASN1Identifier.TagClass, defaultValue: T, _ builder: (ASN1Node) throws(CryptoKitMetaError) -> T) throws(CryptoKitMetaError) -> T { if let result = try optionalExplicitlyTagged(&nodes, tagNumber: tagNumber, tagClass: tagClass, builder) { guard result != defaultValue else { // DER forbids encoding DEFAULT values at their default state. // We can lift this in BER. - throw CryptoKitASN1Error.invalidASN1Object + throw error(CryptoKitASN1Error.invalidASN1Object) } return result @@ -282,46 +294,46 @@ extension ASN1 { self.nodes = nodes } - fileprivate static func parse(_ data: ArraySlice) throws -> ASN1ParseResult { + fileprivate static func parse(_ data: ArraySlice) throws(CryptoKitMetaError) -> ASN1ParseResult { var data = data var nodes = [ASN1ParserNode]() nodes.reserveCapacity(16) try parseNode(from: &data, depth: 1, into: &nodes) guard data.count == 0 else { - throw CryptoKitASN1Error.invalidASN1Object + throw error(CryptoKitASN1Error.invalidASN1Object) } return ASN1ParseResult(nodes[...]) } /// Parses a single ASN.1 node from the data and appends it to the buffer. This may recursively /// call itself when there are child nodes for constructed nodes. - private static func parseNode(from data: inout ArraySlice, depth: Int, into nodes: inout [ASN1ParserNode]) throws { + private static func parseNode(from data: inout ArraySlice, depth: Int, into nodes: inout [ASN1ParserNode]) throws(CryptoKitMetaError) { guard depth <= ASN1.ASN1ParseResult.maximumNodeDepth else { // We defend ourselves against stack overflow by refusing to allocate more than 10 stack frames to // the parsing. - throw CryptoKitASN1Error.invalidASN1Object + throw error(CryptoKitASN1Error.invalidASN1Object) } guard let rawIdentifier = data.popFirst() else { - throw CryptoKitASN1Error.truncatedASN1Field + throw error(CryptoKitASN1Error.truncatedASN1Field) } let identifier = try ASN1Identifier(rawIdentifier: rawIdentifier) guard let wideLength = try data.readASN1Length() else { - throw CryptoKitASN1Error.truncatedASN1Field + throw error(CryptoKitASN1Error.truncatedASN1Field) } // UInt is sometimes too large for us! guard let length = Int(exactly: wideLength) else { - throw CryptoKitASN1Error.invalidASN1Object + throw error(CryptoKitASN1Error.invalidASN1Object) } var subData = data.prefix(length) data = data.dropFirst(length) guard subData.count == length else { - throw CryptoKitASN1Error.truncatedASN1Field + throw error(CryptoKitASN1Error.truncatedASN1Field) } if identifier.constructed { @@ -341,11 +353,11 @@ extension ASN1.ASN1ParseResult: Hashable { } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1 { - static func parse(_ data: [UInt8]) throws -> ASN1Node { + static func parse(_ data: [UInt8]) throws(CryptoKitMetaError) -> ASN1Node { return try parse(data[...]) } - static func parse(_ data: ArraySlice) throws -> ASN1Node { + static func parse(_ data: ArraySlice) throws(CryptoKitMetaError) -> ASN1Node { var result = try ASN1ParseResult.parse(data) // There will always be at least one node if the above didn't throw, so we can safely just removeFirst here. @@ -471,48 +483,50 @@ extension ASN1 { } /// Appends a single, non-constructed node to the content. - mutating func appendPrimitiveNode(identifier: ASN1.ASN1Identifier, _ contentWriter: (inout [UInt8]) throws -> Void) rethrows { + mutating func appendPrimitiveNode(identifier: ASN1.ASN1Identifier, _ contentWriter: (inout [UInt8]) throws(CryptoKitMetaError) -> Void) throws(CryptoKitMetaError) { assert(identifier.primitive) - try self._appendNode(identifier: identifier) { try contentWriter(&$0.serializedBytes) } + try self._appendNode(identifier: identifier) { coder throws(CryptoKitMetaError) in + try contentWriter(&coder.serializedBytes) + } } - mutating func appendConstructedNode(identifier: ASN1.ASN1Identifier, _ contentWriter: (inout Serializer) throws -> Void) rethrows { + mutating func appendConstructedNode(identifier: ASN1.ASN1Identifier, _ contentWriter: (inout Serializer) throws(CryptoKitMetaError) -> Void) throws(CryptoKitMetaError) { assert(identifier.constructed) try self._appendNode(identifier: identifier, contentWriter) } - mutating func serialize(_ node: T) throws { + mutating func serialize(_ node: T) throws(CryptoKitMetaError) { try node.serialize(into: &self) } - mutating func serialize(_ node: T, explicitlyTaggedWithTagNumber tagNumber: Int, tagClass: ASN1.ASN1Identifier.TagClass) throws { - return try self.serialize(explicitlyTaggedWithTagNumber: tagNumber, tagClass: tagClass) { coder in + mutating func serialize(_ node: T, explicitlyTaggedWithTagNumber tagNumber: Int, tagClass: ASN1.ASN1Identifier.TagClass) throws(CryptoKitMetaError) { + return try self.serialize(explicitlyTaggedWithTagNumber: tagNumber, tagClass: tagClass) { coder throws(CryptoKitMetaError) in try coder.serialize(node) } } - mutating func serialize(explicitlyTaggedWithTagNumber tagNumber: Int, tagClass: ASN1.ASN1Identifier.TagClass, _ block: (inout Serializer) throws -> Void) rethrows { + mutating func serialize(explicitlyTaggedWithTagNumber tagNumber: Int, tagClass: ASN1.ASN1Identifier.TagClass, _ block: (inout Serializer) throws(CryptoKitMetaError) -> Void) throws(CryptoKitMetaError) { let identifier = ASN1Identifier(explicitTagWithNumber: tagNumber, tagClass: tagClass) - try self.appendConstructedNode(identifier: identifier) { coder in + try self.appendConstructedNode(identifier: identifier) { coder throws(CryptoKitMetaError) in try block(&coder) } } - mutating func serializeSequenceOf(_ elements: Elements, identifier: ASN1.ASN1Identifier = .sequence) throws where Elements.Element: ASN1Serializable { - try self.appendConstructedNode(identifier: identifier) { coder in + mutating func serializeSequenceOf(_ elements: Elements, identifier: ASN1.ASN1Identifier = .sequence) throws(CryptoKitMetaError) where Elements.Element: ASN1Serializable { + try self.appendConstructedNode(identifier: identifier) { coder throws(CryptoKitMetaError) in for element in elements { try coder.serialize(element) } } } - mutating func serialize(_ node: ASN1.ASN1Node) { + mutating func serialize(_ node: ASN1.ASN1Node) throws(CryptoKitMetaError) { let identifier = node.identifier - self._appendNode(identifier: identifier) { coder in + try self._appendNode(identifier: identifier) { coder throws(CryptoKitMetaError) in switch node.content { case .constructed(let nodes): for node in nodes { - coder.serialize(node) + try coder.serialize(node) } case .primitive(let baseData): coder.serializedBytes.append(contentsOf: baseData) @@ -522,7 +536,7 @@ extension ASN1 { // This is the base logical function that all other append methods are built on. This one has most of the logic, and doesn't // police what we expect to happen in the content writer. - private mutating func _appendNode(identifier: ASN1.ASN1Identifier, _ contentWriter: (inout Serializer) throws -> Void) rethrows { + private mutating func _appendNode(identifier: ASN1.ASN1Identifier, _ contentWriter: (inout Serializer) throws(CryptoKitMetaError) -> Void) throws(CryptoKitMetaError) { // This is a tricky game to play. We want to write the identifier and the length, but we don't know what the // length is here. To get around that, we _assume_ the length will be one byte, and let the writer write their content. // If it turns out to have been longer, we recalculate how many bytes we need and shuffle them in the buffer, @@ -570,31 +584,31 @@ extension ASN1 { // MARK: - Helpers @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) internal protocol ASN1Parseable { - init(asn1Encoded: ASN1.ASN1Node) throws + init(asn1Encoded: ASN1.ASN1Node) throws(CryptoKitMetaError) } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1Parseable { - internal init(asn1Encoded sequenceNodeIterator: inout ASN1.ASN1NodeCollection.Iterator) throws { + internal init(asn1Encoded sequenceNodeIterator: inout ASN1.ASN1NodeCollection.Iterator) throws(CryptoKitMetaError) { guard let node = sequenceNodeIterator.next() else { - throw CryptoKitASN1Error.invalidASN1Object + throw error(CryptoKitASN1Error.invalidASN1Object) } self = try .init(asn1Encoded: node) } - internal init(asn1Encoded: [UInt8]) throws { + internal init(asn1Encoded: [UInt8]) throws(CryptoKitMetaError) { self = try .init(asn1Encoded: ASN1.parse(asn1Encoded)) } - internal init(asn1Encoded: ArraySlice) throws { + internal init(asn1Encoded: ArraySlice) throws(CryptoKitMetaError) { self = try .init(asn1Encoded: ASN1.parse(asn1Encoded)) } } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) internal protocol ASN1Serializable { - func serialize(into coder: inout ASN1.Serializer) throws + func serialize(into coder: inout ASN1.Serializer) throws(CryptoKitMetaError) } /// Covers ASN.1 types that may be implicitly tagged. Not all nodes can be! @@ -604,42 +618,42 @@ internal protocol ASN1ImplicitlyTaggable: ASN1Parseable, ASN1Serializable { /// any more specific tag definition. static var defaultIdentifier: ASN1.ASN1Identifier { get } - init(asn1Encoded: ASN1.ASN1Node, withIdentifier identifier: ASN1.ASN1Identifier) throws + init(asn1Encoded: ASN1.ASN1Node, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) - func serialize(into coder: inout ASN1.Serializer, withIdentifier identifier: ASN1.ASN1Identifier) throws + func serialize(into coder: inout ASN1.Serializer, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1ImplicitlyTaggable { internal init(asn1Encoded sequenceNodeIterator: inout ASN1.ASN1NodeCollection.Iterator, - withIdentifier identifier: ASN1.ASN1Identifier = Self.defaultIdentifier) throws { + withIdentifier identifier: ASN1.ASN1Identifier = Self.defaultIdentifier) throws(CryptoKitMetaError) { guard let node = sequenceNodeIterator.next() else { - throw CryptoKitASN1Error.invalidASN1Object + throw error(CryptoKitASN1Error.invalidASN1Object) } self = try .init(asn1Encoded: node, withIdentifier: identifier) } - internal init(asn1Encoded: [UInt8], withIdentifier identifier: ASN1.ASN1Identifier = Self.defaultIdentifier) throws { + internal init(asn1Encoded: [UInt8], withIdentifier identifier: ASN1.ASN1Identifier = Self.defaultIdentifier) throws(CryptoKitMetaError) { self = try .init(asn1Encoded: ASN1.parse(asn1Encoded), withIdentifier: identifier) } - internal init(asn1Encoded: ArraySlice, withIdentifier identifier: ASN1.ASN1Identifier = Self.defaultIdentifier) throws { + internal init(asn1Encoded: ArraySlice, withIdentifier identifier: ASN1.ASN1Identifier = Self.defaultIdentifier) throws(CryptoKitMetaError) { self = try .init(asn1Encoded: ASN1.parse(asn1Encoded), withIdentifier: identifier) } - init(asn1Encoded: ASN1.ASN1Node) throws { + init(asn1Encoded: ASN1.ASN1Node) throws(CryptoKitMetaError) { try self.init(asn1Encoded: asn1Encoded, withIdentifier: Self.defaultIdentifier) } - func serialize(into coder: inout ASN1.Serializer) throws { + func serialize(into coder: inout ASN1.Serializer) throws(CryptoKitMetaError) { try self.serialize(into: &coder, withIdentifier: Self.defaultIdentifier) } } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ArraySlice where Element == UInt8 { - fileprivate mutating func readASN1Length() throws -> UInt? { + fileprivate mutating func readASN1Length() throws(CryptoKitMetaError) -> UInt? { guard let firstByte = self.popFirst() else { return nil } @@ -647,7 +661,7 @@ extension ArraySlice where Element == UInt8 { switch firstByte { case 0x80: // Indefinite form. Unsupported. - throw CryptoKitASN1Error.unsupportedFieldLength + throw error(CryptoKitASN1Error.unsupportedFieldLength) case let val where val & 0x80 == 0x80: // Top bit is set, this is the long form. The remaining 7 bits of this octet // determine how long the length field is. @@ -666,16 +680,16 @@ extension ArraySlice where Element == UInt8 { switch requiredBits { case 0...7: // For 0 to 7 bits, the long form is unacceptable and we require the short. - throw CryptoKitASN1Error.unsupportedFieldLength + throw error(CryptoKitASN1Error.unsupportedFieldLength) case 8...: // For 8 or more bits, fieldLength should be the minimum required. let requiredBytes = (requiredBits + 7) / 8 if fieldLength > requiredBytes { - throw CryptoKitASN1Error.unsupportedFieldLength + throw error(CryptoKitASN1Error.unsupportedFieldLength) } default: // This is not reachable, but we'll error anyway. - throw CryptoKitASN1Error.unsupportedFieldLength + throw error(CryptoKitASN1Error.unsupportedFieldLength) } return length @@ -688,9 +702,9 @@ extension ArraySlice where Element == UInt8 { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension FixedWidthInteger { - internal init(bigEndianBytes bytes: Bytes) throws where Bytes.Element == UInt8 { + internal init(bigEndianBytes bytes: Bytes) throws(CryptoKitMetaError) where Bytes.Element == UInt8 { guard bytes.count <= (Self.bitWidth / 8) else { - throw CryptoKitASN1Error.invalidASN1Object + throw error(CryptoKitASN1Error.invalidASN1Object) } self = 0 diff --git a/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Any.swift b/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Any.swift index c4148099c..575d23d81 100644 --- a/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Any.swift +++ b/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Any.swift @@ -14,7 +14,12 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else + +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1 { @@ -29,28 +34,28 @@ extension ASN1 { struct ASN1Any: ASN1Parseable, ASN1Serializable, Hashable { fileprivate var serializedBytes: ArraySlice - init(erasing: ASN1Type) throws { + init(erasing: ASN1Type) throws(CryptoKitMetaError) { var serializer = ASN1.Serializer() try erasing.serialize(into: &serializer) self.serializedBytes = ArraySlice(serializer.serializedBytes) } - init(erasing: ASN1Type, withIdentifier identifier: ASN1.ASN1Identifier) throws { + init(erasing: ASN1Type, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) { var serializer = ASN1.Serializer() try erasing.serialize(into: &serializer, withIdentifier: identifier) self.serializedBytes = ArraySlice(serializer.serializedBytes) } - init(asn1Encoded rootNode: ASN1.ASN1Node) { + init(asn1Encoded rootNode: ASN1.ASN1Node) throws(CryptoKitMetaError) { // This is a bit sad: we just re-serialize this data. In an ideal world // we'd update the parse representation so that all nodes can point at their // complete backing storage, but for now this is better. var serializer = ASN1.Serializer() - serializer.serialize(rootNode) + try serializer.serialize(rootNode) self.serializedBytes = ArraySlice(serializer.serializedBytes) } - func serialize(into coder: inout ASN1.Serializer) throws { + func serialize(into coder: inout ASN1.Serializer) throws(CryptoKitMetaError) { // Dangerous to just reach in there like this, but it's the right way to serialize this. coder.serializedBytes.append(contentsOf: self.serializedBytes) } @@ -59,14 +64,14 @@ extension ASN1 { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1Parseable { - init(asn1Any: ASN1.ASN1Any) throws { + init(asn1Any: ASN1.ASN1Any) throws(CryptoKitMetaError) { try self.init(asn1Encoded: asn1Any.serializedBytes) } } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1ImplicitlyTaggable { - init(asn1Any: ASN1.ASN1Any, withIdentifier identifier: ASN1.ASN1Identifier) throws { + init(asn1Any: ASN1.ASN1Any, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) { try self.init(asn1Encoded: asn1Any.serializedBytes, withIdentifier: identifier) } } diff --git a/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1BitString.swift b/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1BitString.swift index 5ef695309..ce43673ca 100644 --- a/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1BitString.swift +++ b/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1BitString.swift @@ -14,7 +14,12 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else + +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1 { @@ -27,9 +32,9 @@ extension ASN1 { var bytes: ArraySlice - init(asn1Encoded node: ASN1.ASN1Node, withIdentifier identifier: ASN1.ASN1Identifier) throws { + init(asn1Encoded node: ASN1.ASN1Node, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) { guard node.identifier == identifier else { - throw CryptoKitASN1Error.unexpectedFieldType + throw error(CryptoKitASN1Error.unexpectedFieldType) } guard case .primitive(let content) = node.content else { @@ -39,7 +44,7 @@ extension ASN1 { // The initial octet explains how many of the bits in the _final_ octet are not part of the bitstring. // The only value we support here is 0. guard content.first == 0 else { - throw CryptoKitASN1Error.invalidASN1Object + throw error(CryptoKitASN1Error.invalidASN1Object) } self.bytes = content.dropFirst() @@ -49,8 +54,8 @@ extension ASN1 { self.bytes = bytes } - func serialize(into coder: inout ASN1.Serializer, withIdentifier identifier: ASN1.ASN1Identifier) throws { - coder.appendPrimitiveNode(identifier: identifier) { bytes in + func serialize(into coder: inout ASN1.Serializer, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) { + try coder.appendPrimitiveNode(identifier: identifier) { bytes in bytes.append(0) bytes.append(contentsOf: self.bytes) } @@ -63,9 +68,15 @@ extension ASN1.ASN1BitString: Hashable { } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1.ASN1BitString: ContiguousBytes { + #if hasFeature(Embedded) + func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws(E) -> R) throws(E) -> R { + return try self.bytes.withUnsafeBytes(body) + } + #else func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R { return try self.bytes.withUnsafeBytes(body) } + #endif } #endif // Linux or !SwiftPM diff --git a/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Boolean.swift b/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Boolean.swift index 1786aa5d3..a2c1c3f19 100644 --- a/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Boolean.swift +++ b/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Boolean.swift @@ -14,7 +14,12 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else + +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension Bool: ASN1ImplicitlyTaggable { @@ -22,13 +27,13 @@ extension Bool: ASN1ImplicitlyTaggable { .boolean } - init(asn1Encoded node: ASN1.ASN1Node, withIdentifier identifier: ASN1.ASN1Identifier) throws { + init(asn1Encoded node: ASN1.ASN1Node, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) { guard node.identifier == identifier else { - throw CryptoKitASN1Error.invalidASN1Object + throw error(CryptoKitASN1Error.invalidASN1Object) } guard case .primitive(let bytes) = node.content, bytes.count == 1 else { - throw CryptoKitASN1Error.invalidASN1Object + throw error(CryptoKitASN1Error.invalidASN1Object) } switch bytes[bytes.startIndex] { @@ -40,12 +45,12 @@ extension Bool: ASN1ImplicitlyTaggable { self = true default: // If we come to support BER then these values are all "true" as well. - throw CryptoKitASN1Error.invalidASN1Object + throw error(CryptoKitASN1Error.invalidASN1Object) } } - func serialize(into coder: inout ASN1.Serializer, withIdentifier identifier: ASN1.ASN1Identifier) throws { - coder.appendPrimitiveNode(identifier: identifier) { bytes in + func serialize(into coder: inout ASN1.Serializer, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) { + try coder.appendPrimitiveNode(identifier: identifier) { bytes in if self { bytes.append(0xff) } else { diff --git a/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Identifier.swift b/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Identifier.swift index 0e41f8ca7..c47477cb7 100644 --- a/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Identifier.swift +++ b/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Identifier.swift @@ -14,7 +14,12 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else + +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1 { @@ -59,10 +64,10 @@ extension ASN1 { } } - init(rawIdentifier: UInt8) throws { + init(rawIdentifier: UInt8) throws(CryptoKitMetaError) { // We don't support multibyte identifiers, which are signalled when the bottom 5 bits are all 1. guard rawIdentifier & 0x1F != 0x1F else { - throw CryptoKitASN1Error.invalidFieldIdentifier + throw error(CryptoKitASN1Error.invalidFieldIdentifier) } self.baseTag = rawIdentifier @@ -141,11 +146,13 @@ extension ASN1.ASN1Identifier { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1.ASN1Identifier: Hashable { } +#if !hasFeature(Embedded) @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1.ASN1Identifier: CustomStringConvertible { var description: String { return "ASN1Identifier(\(self.baseTag))" } } +#endif #endif // Linux or !SwiftPM diff --git a/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Integer.swift b/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Integer.swift index 8c4c4e9f7..7026f634e 100644 --- a/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Integer.swift +++ b/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Integer.swift @@ -14,10 +14,15 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else + +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else import Foundation +#endif -/// A protocol that represents any internal object that can present itself as an INTEGER, or be parsed from -/// an INTEGER. +/// A protocol that represents any internal object that can present itself as a INTEGER, or be parsed from +/// a INTEGER. /// /// This is not a very good solution for a fully-fledged ASN.1 library: we'd rather have a better numerics /// protocol that could both initialize from and serialize to either bytes or words. However, no such @@ -30,9 +35,9 @@ protocol ASN1IntegerRepresentable: ASN1ImplicitlyTaggable { /// parser will automatically handle padding with leading zero bytes as needed. static var isSigned: Bool { get } - init(asn1IntegerBytes: ArraySlice) throws + init(asn1IntegerBytes: ArraySlice) throws(CryptoKitMetaError) - func withBigEndianIntegerBytes(_ body: (IntegerBytes) throws -> ReturnType) rethrows -> ReturnType + func withBigEndianIntegerBytes(_ body: (IntegerBytes) throws(CryptoKitMetaError) -> ReturnType) throws(CryptoKitMetaError) -> ReturnType } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) @@ -41,9 +46,9 @@ extension ASN1IntegerRepresentable { .integer } - internal init(asn1Encoded node: ASN1.ASN1Node, withIdentifier identifier: ASN1.ASN1Identifier) throws { + internal init(asn1Encoded node: ASN1.ASN1Node, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) { guard node.identifier == identifier else { - throw CryptoKitASN1Error.unexpectedFieldType + throw error(CryptoKitASN1Error.unexpectedFieldType) } guard case .primitive(var dataBytes) = node.content else { @@ -52,7 +57,7 @@ extension ASN1IntegerRepresentable { // Zero bytes of integer is not an acceptable encoding. guard dataBytes.count > 0 else { - throw CryptoKitASN1Error.invalidASN1IntegerEncoding + throw error(CryptoKitASN1Error.invalidASN1IntegerEncoding) } // 8.3.2 If the contents octets of an integer value encoding consist of more than one octet, then the bits of the first octet and bit 8 of the second octet: @@ -64,7 +69,7 @@ extension ASN1IntegerRepresentable { if let first = dataBytes.first, let second = dataBytes.dropFirst().first { if (first == 0xFF) && second.topBitSet || (first == 0x00) && !second.topBitSet { - throw CryptoKitASN1Error.invalidASN1IntegerEncoding + throw error(CryptoKitASN1Error.invalidASN1IntegerEncoding) } } @@ -74,16 +79,16 @@ extension ASN1IntegerRepresentable { if first == 0x00 { dataBytes = dataBytes.dropFirst() } else if first & 0x80 == 0x80 { - throw CryptoKitASN1Error.invalidASN1IntegerEncoding + throw error(CryptoKitASN1Error.invalidASN1IntegerEncoding) } } self = try Self(asn1IntegerBytes: dataBytes) } - internal func serialize(into coder: inout ASN1.Serializer, withIdentifier identifier: ASN1.ASN1Identifier) throws { - coder.appendPrimitiveNode(identifier: identifier) { bytes in - self.withBigEndianIntegerBytes { integerBytes in + internal func serialize(into coder: inout ASN1.Serializer, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) { + try coder.appendPrimitiveNode(identifier: identifier) { bytes throws(CryptoKitMetaError) in + try self.withBigEndianIntegerBytes { integerBytes throws(CryptoKitMetaError) in // If the number of bytes is 0, we're encoding a zero. That actually _does_ require one byte. if integerBytes.count == 0 { bytes.append(0) @@ -106,7 +111,7 @@ extension ASN1IntegerRepresentable { // MARK: - Auto-conformance for FixedWidthInteger with fixed width magnitude. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1IntegerRepresentable where Self: FixedWidthInteger { - init(asn1IntegerBytes bytes: ArraySlice) throws { + init(asn1IntegerBytes bytes: ArraySlice) throws(CryptoKitMetaError) { // Defer to the FixedWidthInteger constructor. // There's a wrinkle here: if this is a signed integer, and the top bit of the data bytes was set, // then we need to 1-extend the bytes. This is because ASN.1 tries to delete redundant bytes that @@ -120,7 +125,7 @@ extension ASN1IntegerRepresentable where Self: FixedWidthInteger { } } - func withBigEndianIntegerBytes(_ body: (IntegerBytesCollection) throws -> ReturnType) rethrows -> ReturnType { + func withBigEndianIntegerBytes(_ body: (IntegerBytesCollection) throws(CryptoKitMetaError) -> ReturnType) throws(CryptoKitMetaError) -> ReturnType { return try body(IntegerBytesCollection(self)) } } @@ -205,24 +210,34 @@ extension IntegerBytesCollection.Index: Strideable { } } +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension Int8: ASN1IntegerRepresentable { } +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension UInt8: ASN1IntegerRepresentable { } +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension Int16: ASN1IntegerRepresentable { } +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension UInt16: ASN1IntegerRepresentable { } +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension Int32: ASN1IntegerRepresentable { } +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension UInt32: ASN1IntegerRepresentable { } +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension Int64: ASN1IntegerRepresentable { } +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension UInt64: ASN1IntegerRepresentable { } +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension Int: ASN1IntegerRepresentable { } +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension UInt: ASN1IntegerRepresentable { } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) diff --git a/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Null.swift b/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Null.swift index f95b8a7b3..850d81747 100644 --- a/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Null.swift +++ b/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Null.swift @@ -14,7 +14,12 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else + +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1 { @@ -27,18 +32,18 @@ extension ASN1 { init() { } - init(asn1Encoded node: ASN1.ASN1Node, withIdentifier identifier: ASN1.ASN1Identifier) throws { + init(asn1Encoded node: ASN1.ASN1Node, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) { guard node.identifier == identifier, case .primitive(let content) = node.content else { - throw CryptoKitASN1Error.unexpectedFieldType + throw error(CryptoKitASN1Error.unexpectedFieldType) } guard content.count == 0 else { - throw CryptoKitASN1Error.invalidASN1Object + throw error(CryptoKitASN1Error.invalidASN1Object) } } - func serialize(into coder: inout ASN1.Serializer, withIdentifier identifier: ASN1.ASN1Identifier) { - coder.appendPrimitiveNode(identifier: identifier, { _ in }) + func serialize(into coder: inout ASN1.Serializer, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) { + try coder.appendPrimitiveNode(identifier: identifier, { _ in }) } } } diff --git a/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1OctetString.swift b/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1OctetString.swift index a2f5d0070..1b6374a50 100644 --- a/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1OctetString.swift +++ b/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1OctetString.swift @@ -14,7 +14,12 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else + +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1 { @@ -27,9 +32,9 @@ extension ASN1 { var bytes: ArraySlice - init(asn1Encoded node: ASN1.ASN1Node, withIdentifier identifier: ASN1.ASN1Identifier) throws { + init(asn1Encoded node: ASN1.ASN1Node, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) { guard node.identifier == identifier else { - throw CryptoKitASN1Error.unexpectedFieldType + throw error(CryptoKitASN1Error.unexpectedFieldType) } guard case .primitive(let content) = node.content else { @@ -43,8 +48,8 @@ extension ASN1 { self.bytes = contentBytes } - func serialize(into coder: inout ASN1.Serializer, withIdentifier identifier: ASN1.ASN1Identifier) throws { - coder.appendPrimitiveNode(identifier: identifier) { bytes in + func serialize(into coder: inout ASN1.Serializer, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) { + try coder.appendPrimitiveNode(identifier: identifier) { bytes in bytes.append(contentsOf: self.bytes) } } @@ -56,9 +61,15 @@ extension ASN1.ASN1OctetString: Hashable { } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1.ASN1OctetString: ContiguousBytes { +#if hasFeature(Embedded) + func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws(E) -> R) throws(E) -> R { + return try self.bytes.withUnsafeBytes(body) + } +#else func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R { return try self.bytes.withUnsafeBytes(body) } +#endif } #endif // Linux or !SwiftPM diff --git a/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Strings.swift b/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Strings.swift index 7f7443f77..794150b53 100644 --- a/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Strings.swift +++ b/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Strings.swift @@ -14,21 +14,42 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else + +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else import Foundation +#endif + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +private func contents(of string: StaticString) -> ArraySlice { + if string.hasPointerRepresentation { + return ArraySlice( + UnsafeBufferPointer(start: string.utf8Start, count: string.utf8CodeUnitCount) + ) + } else { + return string.withUTF8Buffer { ptr in + // Here ptr points to a word-sized temporary value that holds the + // UTF-8 representation of the single Unicode codepoint held in `string`. + // We need to copy this because it's only valid inside the closure. + ArraySlice(Array(ptr)) + } + } +} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1 { /// A UTF8String is roughly what it sounds like. We note that all the string types are encoded as implicitly tagged /// octet strings, and so for now we just piggyback on the decoder and encoder for that type. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - struct ASN1UTF8String: ASN1ImplicitlyTaggable, Hashable, ContiguousBytes, ExpressibleByStringLiteral { + struct ASN1UTF8String: ASN1ImplicitlyTaggable, Hashable, ContiguousBytes { static var defaultIdentifier: ASN1.ASN1Identifier { .primitiveUTF8String } var bytes: ArraySlice - init(asn1Encoded node: ASN1.ASN1Node, withIdentifier identifier: ASN1.ASN1Identifier) throws { + init(asn1Encoded node: ASN1.ASN1Node, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) { self.bytes = try ASN1OctetString(asn1Encoded: node, withIdentifier: identifier).bytes } @@ -36,35 +57,43 @@ extension ASN1 { self.bytes = contentBytes } - init(stringLiteral value: StringLiteralType) { - self.bytes = ArraySlice(value.utf8) +#if hasFeature(Embedded) + init(_ string: StaticString) { + self.bytes = contents(of: string) } - +#else init(_ string: String) { self.bytes = ArraySlice(string.utf8) } +#endif - func serialize(into coder: inout ASN1.Serializer, withIdentifier identifier: ASN1.ASN1Identifier) throws { + func serialize(into coder: inout ASN1.Serializer, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) { let octet = ASN1OctetString(contentBytes: self.bytes) try octet.serialize(into: &coder, withIdentifier: identifier) } + #if hasFeature(Embedded) + func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws(E) -> R) throws(E) -> R { + return try self.bytes.withUnsafeBytes(body) + } + #else func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R { return try self.bytes.withUnsafeBytes(body) } + #endif } /// We note that all the string types are encoded as implicitly tagged /// octet strings, and so for now we just piggyback on the decoder and encoder for that type. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - struct ASN1TeletexString: ASN1ImplicitlyTaggable, Hashable, ContiguousBytes, ExpressibleByStringLiteral { + struct ASN1TeletexString: ASN1ImplicitlyTaggable, Hashable, ContiguousBytes { static var defaultIdentifier: ASN1.ASN1Identifier { .primitiveTeletexString } var bytes: ArraySlice - init(asn1Encoded node: ASN1.ASN1Node, withIdentifier identifier: ASN1.ASN1Identifier) throws { + init(asn1Encoded node: ASN1.ASN1Node, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) { self.bytes = try ASN1OctetString(asn1Encoded: node, withIdentifier: identifier).bytes } @@ -72,35 +101,43 @@ extension ASN1 { self.bytes = contentBytes } - init(stringLiteral value: StringLiteralType) { - self.bytes = ArraySlice(value.utf8) +#if hasFeature(Embedded) + init(_ string: StaticString) { + self.bytes = contents(of: string) } - +#else init(_ string: String) { self.bytes = ArraySlice(string.utf8) } +#endif - func serialize(into coder: inout ASN1.Serializer, withIdentifier identifier: ASN1.ASN1Identifier) throws { + func serialize(into coder: inout ASN1.Serializer, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) { let octet = ASN1OctetString(contentBytes: self.bytes) try octet.serialize(into: &coder, withIdentifier: identifier) } + #if hasFeature(Embedded) + func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws(E) -> R) throws(E) -> R { + return try self.bytes.withUnsafeBytes(body) + } + #else func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R { return try self.bytes.withUnsafeBytes(body) } + #endif } /// We note that all the string types are encoded as implicitly tagged /// octet strings, and so for now we just piggyback on the decoder and encoder for that type. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - struct ASN1PrintableString: ASN1ImplicitlyTaggable, Hashable, ContiguousBytes, ExpressibleByStringLiteral { + struct ASN1PrintableString: ASN1ImplicitlyTaggable, Hashable, ContiguousBytes { static var defaultIdentifier: ASN1.ASN1Identifier { .primitivePrintableString } var bytes: ArraySlice - init(asn1Encoded node: ASN1.ASN1Node, withIdentifier identifier: ASN1.ASN1Identifier) throws { + init(asn1Encoded node: ASN1.ASN1Node, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) { self.bytes = try ASN1OctetString(asn1Encoded: node, withIdentifier: identifier).bytes } @@ -108,35 +145,43 @@ extension ASN1 { self.bytes = contentBytes } - init(stringLiteral value: StringLiteralType) { - self.bytes = ArraySlice(value.utf8) +#if hasFeature(Embedded) + init(_ string: StaticString) { + self.bytes = contents(of: string) } - +#else init(_ string: String) { self.bytes = ArraySlice(string.utf8) } +#endif - func serialize(into coder: inout ASN1.Serializer, withIdentifier identifier: ASN1.ASN1Identifier) throws { + func serialize(into coder: inout ASN1.Serializer, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) { let octet = ASN1OctetString(contentBytes: self.bytes) try octet.serialize(into: &coder, withIdentifier: identifier) } + #if hasFeature(Embedded) + func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws(E) -> R) throws(E) -> R { + return try self.bytes.withUnsafeBytes(body) + } + #else func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R { return try self.bytes.withUnsafeBytes(body) } + #endif } /// We note that all the string types are encoded as implicitly tagged /// octet strings, and so for now we just piggyback on the decoder and encoder for that type. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - struct ASN1UniversalString: ASN1ImplicitlyTaggable, Hashable, ContiguousBytes, ExpressibleByStringLiteral { + struct ASN1UniversalString: ASN1ImplicitlyTaggable, Hashable, ContiguousBytes { static var defaultIdentifier: ASN1.ASN1Identifier { .primitiveUniversalString } var bytes: ArraySlice - init(asn1Encoded node: ASN1.ASN1Node, withIdentifier identifier: ASN1.ASN1Identifier) throws { + init(asn1Encoded node: ASN1.ASN1Node, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) { self.bytes = try ASN1OctetString(asn1Encoded: node, withIdentifier: identifier).bytes } @@ -144,35 +189,43 @@ extension ASN1 { self.bytes = contentBytes } - init(stringLiteral value: StringLiteralType) { - self.bytes = ArraySlice(value.utf8) +#if hasFeature(Embedded) + init(_ string: StaticString) { + self.bytes = contents(of: string) } - +#else init(_ string: String) { self.bytes = ArraySlice(string.utf8) } +#endif - func serialize(into coder: inout ASN1.Serializer, withIdentifier identifier: ASN1.ASN1Identifier) throws { + func serialize(into coder: inout ASN1.Serializer, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) { let octet = ASN1OctetString(contentBytes: self.bytes) try octet.serialize(into: &coder, withIdentifier: identifier) } + #if hasFeature(Embedded) + func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws(E) -> R) throws(E) -> R { + return try self.bytes.withUnsafeBytes(body) + } + #else func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R { return try self.bytes.withUnsafeBytes(body) } + #endif } /// We note that all the string types are encoded as implicitly tagged /// octet strings, and so for now we just piggyback on the decoder and encoder for that type. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - struct ASN1BMPString: ASN1ImplicitlyTaggable, Hashable, ContiguousBytes, ExpressibleByStringLiteral { + struct ASN1BMPString: ASN1ImplicitlyTaggable, Hashable, ContiguousBytes { static var defaultIdentifier: ASN1.ASN1Identifier { .primitiveBMPString } var bytes: ArraySlice - init(asn1Encoded node: ASN1.ASN1Node, withIdentifier identifier: ASN1.ASN1Identifier) throws { + init(asn1Encoded node: ASN1.ASN1Node, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) { self.bytes = try ASN1OctetString(asn1Encoded: node, withIdentifier: identifier).bytes } @@ -180,23 +233,69 @@ extension ASN1 { self.bytes = contentBytes } - init(stringLiteral value: StringLiteralType) { - self.bytes = ArraySlice(value.utf8) +#if hasFeature(Embedded) + init(_ string: StaticString) { + self.bytes = contents(of: string) } - +#else init(_ string: String) { self.bytes = ArraySlice(string.utf8) } +#endif - func serialize(into coder: inout ASN1.Serializer, withIdentifier identifier: ASN1.ASN1Identifier) throws { + func serialize(into coder: inout ASN1.Serializer, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) { let octet = ASN1OctetString(contentBytes: self.bytes) try octet.serialize(into: &coder, withIdentifier: identifier) } + #if hasFeature(Embedded) + func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws(E) -> R) throws(E) -> R { + return try self.bytes.withUnsafeBytes(body) + } + #else func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R { return try self.bytes.withUnsafeBytes(body) } + #endif + } +} + +#if !hasFeature(Embedded) +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension ASN1.ASN1TeletexString: ExpressibleByStringLiteral { + public init(stringLiteral value: StringLiteralType) { + self.bytes = ArraySlice(value.utf8) + } +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension ASN1.ASN1UTF8String: ExpressibleByStringLiteral { + public init(stringLiteral value: StringLiteralType) { + self.bytes = ArraySlice(value.utf8) + } +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension ASN1.ASN1PrintableString: ExpressibleByStringLiteral { + public init(stringLiteral value: StringLiteralType) { + self.bytes = ArraySlice(value.utf8) + } +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension ASN1.ASN1UniversalString: ExpressibleByStringLiteral { + public init(stringLiteral value: StringLiteralType) { + self.bytes = ArraySlice(value.utf8) + } +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension ASN1.ASN1BMPString: ExpressibleByStringLiteral { + public init(stringLiteral value: StringLiteralType) { + self.bytes = ArraySlice(value.utf8) } } +#endif + #endif // Linux or !SwiftPM diff --git a/Sources/Crypto/ASN1/Basic ASN1 Types/ArraySliceBigint.swift b/Sources/Crypto/ASN1/Basic ASN1 Types/ArraySliceBigint.swift index fbdb63326..7a00fd1e2 100644 --- a/Sources/Crypto/ASN1/Basic ASN1 Types/ArraySliceBigint.swift +++ b/Sources/Crypto/ASN1/Basic ASN1 Types/ArraySliceBigint.swift @@ -15,11 +15,20 @@ @_exported import CryptoKit #else +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else +import Foundation +#endif + // For temporary purposes we pretend that ArraySlice is our "bigint" type. We don't really need anything else. +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ArraySlice: ASN1Serializable where Element == UInt8 { } +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ArraySlice: ASN1Parseable where Element == UInt8 { } +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ArraySlice: ASN1ImplicitlyTaggable where Element == UInt8 { } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) @@ -29,11 +38,11 @@ extension ArraySlice: ASN1IntegerRepresentable where Element == UInt8 { return false } - init(asn1IntegerBytes: ArraySlice) throws { + init(asn1IntegerBytes: ArraySlice) throws(CryptoKitMetaError) { self = asn1IntegerBytes } - func withBigEndianIntegerBytes(_ body: (ArraySlice) throws -> ReturnType) rethrows -> ReturnType { + func withBigEndianIntegerBytes(_ body: (ArraySlice) throws(CryptoKitMetaError) -> ReturnType) throws(CryptoKitMetaError) -> ReturnType { return try body(self) } } diff --git a/Sources/Crypto/ASN1/Basic ASN1 Types/GeneralizedTime.swift b/Sources/Crypto/ASN1/Basic ASN1 Types/GeneralizedTime.swift index 74177f76d..bec502fd4 100644 --- a/Sources/Crypto/ASN1/Basic ASN1 Types/GeneralizedTime.swift +++ b/Sources/Crypto/ASN1/Basic ASN1 Types/GeneralizedTime.swift @@ -14,7 +14,12 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else + +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1 { @@ -102,7 +107,7 @@ extension ASN1 { private var _seconds: Int private var _fractionalSeconds: Double - init(year: Int, month: Int, day: Int, hours: Int, minutes: Int, seconds: Int, fractionalSeconds: Double) throws { + init(year: Int, month: Int, day: Int, hours: Int, minutes: Int, seconds: Int, fractionalSeconds: Double) throws(CryptoKitMetaError) { self._year = year self._month = month self._day = day @@ -114,9 +119,9 @@ extension ASN1 { try self.validate() } - init(asn1Encoded node: ASN1.ASN1Node, withIdentifier identifier: ASN1.ASN1Identifier) throws { + init(asn1Encoded node: ASN1.ASN1Node, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) { guard node.identifier == identifier else { - throw CryptoKitASN1Error.unexpectedFieldType + throw error(CryptoKitASN1Error.unexpectedFieldType) } guard case .primitive(let content) = node.content else { @@ -126,33 +131,33 @@ extension ASN1 { self = try .parseDateBytes(content) } - func serialize(into coder: inout ASN1.Serializer, withIdentifier identifier: ASN1.ASN1Identifier) throws { - coder.appendPrimitiveNode(identifier: identifier) { bytes in + func serialize(into coder: inout ASN1.Serializer, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) { + try coder.appendPrimitiveNode(identifier: identifier) { bytes in bytes.append(self) } } - private func validate() throws { + private func validate() throws(CryptoKitMetaError) { // Validate that the structure is well-formed. guard self._year >= 0 && self._year <= 9999 else { - throw CryptoKitASN1Error.invalidASN1Object + throw error(CryptoKitASN1Error.invalidASN1Object) } // This also validates the month. guard let daysInMonth = ASN1.GeneralizedTime.daysInMonth(self._month, ofYear: self._year) else { - throw CryptoKitASN1Error.invalidASN1Object + throw error(CryptoKitASN1Error.invalidASN1Object) } guard self._day >= 1 && self._day <= daysInMonth else { - throw CryptoKitASN1Error.invalidASN1Object + throw error(CryptoKitASN1Error.invalidASN1Object) } guard self._hours >= 0 && self._hours < 24 else { - throw CryptoKitASN1Error.invalidASN1Object + throw error(CryptoKitASN1Error.invalidASN1Object) } guard self._minutes >= 0 && self._minutes < 60 else { - throw CryptoKitASN1Error.invalidASN1Object + throw error(CryptoKitASN1Error.invalidASN1Object) } // We allow leap seconds here, but don't validate it. @@ -160,12 +165,12 @@ extension ASN1 { // comparison here. We should consider whether this needs to be transformable // to `Date` or similar. guard self._seconds >= 0 && self._seconds <= 61 else { - throw CryptoKitASN1Error.invalidASN1Object + throw error(CryptoKitASN1Error.invalidASN1Object) } // Fractional seconds may not be negative and may not be 1 or more. guard self._fractionalSeconds >= 0 && self._fractionalSeconds < 1 else { - throw CryptoKitASN1Error.invalidASN1Object + throw error(CryptoKitASN1Error.invalidASN1Object) } } } @@ -173,7 +178,7 @@ extension ASN1 { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1.GeneralizedTime { - fileprivate static func parseDateBytes(_ bytes: ArraySlice) throws -> ASN1.GeneralizedTime { + fileprivate static func parseDateBytes(_ bytes: ArraySlice) throws(CryptoKitMetaError) -> ASN1.GeneralizedTime { var bytes = bytes // First, there must always be a calendar date. No separators, 4 @@ -181,7 +186,7 @@ extension ASN1.GeneralizedTime { guard let rawYear = bytes.readFourDigitDecimalInteger(), let rawMonth = bytes.readTwoDigitDecimalInteger(), let rawDay = bytes.readTwoDigitDecimalInteger() else { - throw CryptoKitASN1Error.invalidASN1Object + throw error(CryptoKitASN1Error.invalidASN1Object) } // Next there must be a _time_. Per DER rules, this time must always go @@ -190,23 +195,23 @@ extension ASN1.GeneralizedTime { guard let rawHour = bytes.readTwoDigitDecimalInteger(), let rawMinutes = bytes.readTwoDigitDecimalInteger(), let rawSeconds = bytes.readTwoDigitDecimalInteger() else { - throw CryptoKitASN1Error.invalidASN1Object + throw error(CryptoKitASN1Error.invalidASN1Object) } // There may be some fractional seconds. var fractionalSeconds: Double = 0 - if bytes.first == UInt8(ascii: ".") { + if bytes.first == UInt8(46 /* "." */) { fractionalSeconds = try bytes.readFractionalSeconds() } // The next character _must_ be Z, or the encoding is invalid. - guard bytes.popFirst() == UInt8(ascii: "Z") else { - throw CryptoKitASN1Error.invalidASN1Object + guard bytes.popFirst() == UInt8(90 /* "Z" */) else { + throw error(CryptoKitASN1Error.invalidASN1Object) } // Great! There better not be anything left. guard bytes.count == 0 else { - throw CryptoKitASN1Error.invalidASN1Object + throw error(CryptoKitASN1Error.invalidASN1Object) } return try ASN1.GeneralizedTime(year: rawYear, @@ -284,8 +289,8 @@ extension ArraySlice where Element == UInt8 { } /// This may only be called if there's a leading period: we precondition on this fact. - fileprivate mutating func readFractionalSeconds() throws -> Double { - precondition(self.popFirst() == UInt8(ascii: ".")) + fileprivate mutating func readFractionalSeconds() throws(CryptoKitMetaError) -> Double { + precondition(self.popFirst() == UInt8(46 /* "." */)) var numerator = 0 var denominator = 1 @@ -304,7 +309,7 @@ extension ArraySlice where Element == UInt8 { // If the numerator overflows, we don't support the result. if multiplyOverflow || addingOverflow { - throw CryptoKitASN1Error.invalidASN1Object + throw error(CryptoKitASN1Error.invalidASN1Object) } numerator = newNumeratorWithAdded @@ -313,7 +318,7 @@ extension ArraySlice where Element == UInt8 { // Ok, we're either at the end or the next character is a Z. One final check: there may not have // been any trailing zeros here. This means the number may not be 0 mod 10. if numerator % 10 == 0 { - throw CryptoKitASN1Error.invalidASN1Object + throw error(CryptoKitASN1Error.invalidASN1Object) } return Double(numerator) / Double(denominator) @@ -332,18 +337,40 @@ extension Array where Element == UInt8 { // Ok, tricky moment here. Is the fractional part non-zero? If it is, we need to write it out as well. if generalizedTime.fractionalSeconds != 0 { - let stringified = String(generalizedTime.fractionalSeconds) - assert(stringified.starts(with: "0.")) - - self.append(contentsOf: stringified.utf8.dropFirst(1)) - // Remove any trailing zeros from self, they are forbidden. - while self.last == 0 { - self = self.dropLast() - } + self._appendFractionalPart(generalizedTime.fractionalSeconds) } - self.append(UInt8(ascii: "Z")) + self.append(UInt8(90 /* "Z" */)) + } + +#if hasFeature(Embedded) + private mutating func _appendFractionalPart(_ d: Double) { + precondition(d > 0 && d < 1) + let digitZero: UInt8 = 48 /* "0" */ + var d = d - d.rounded(.down) + for _ in 0..<16 { + d *= 10 + let x = d.rounded(.down) + self.append(UInt8(x) + digitZero) + d = d - x + } + while self.count > 1 && self.last == UInt8(48 /* "0" */) { + self = self.dropLast() + } + } +#else + private mutating func _appendFractionalPart(_ d: Double) { + precondition(d > 0 && d < 1) + let stringified = String(d) + assert(stringified.starts(with: "0.")) + + self.append(contentsOf: stringified.utf8.dropFirst(1)) + // Remove any trailing zeros from self, they are forbidden. + while self.last == UInt8(48 /* "0" */) { + self = self.dropLast() + } } +#endif fileprivate mutating func appendFourDigitDecimal(_ number: Int) { assert(number >= 0 && number <= 9999) @@ -351,7 +378,7 @@ extension Array where Element == UInt8 { // Each digit can be isolated by dividing by the place and then taking the result modulo 10. // This is annoyingly division heavy. There may be a better algorithm floating around. // Unchecked math is fine, there cannot be an overflow here. - let asciiZero = UInt8(ascii: "0") + let asciiZero = UInt8(48 /* "0" */) self.append(UInt8(truncatingIfNeeded: (number / 1000) % 10) &+ asciiZero) self.append(UInt8(truncatingIfNeeded: (number / 100) % 10) &+ asciiZero) self.append(UInt8(truncatingIfNeeded: (number / 10) % 10) &+ asciiZero) @@ -364,7 +391,7 @@ extension Array where Element == UInt8 { // Each digit can be isolated by dividing by the place and then taking the result modulo 10. // This is annoyingly division heavy. There may be a better algorithm floating around. // Unchecked math is fine, there cannot be an overflow here. - let asciiZero = UInt8(ascii: "0") + let asciiZero = UInt8(48 /* "0" */) self.append(UInt8(truncatingIfNeeded: (number / 10) % 10) &+ asciiZero) self.append(UInt8(truncatingIfNeeded: number % 10) &+ asciiZero) } @@ -373,7 +400,7 @@ extension Array where Element == UInt8 { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension Int { fileprivate init?(fromDecimalASCII ascii: UInt8) { - let asciiZero = UInt8(ascii: "0") + let asciiZero = UInt8(48 /* "0" */) let zeroToNine = 0...9 // These are all coming from UInt8space, the subtraction cannot overflow. diff --git a/Sources/Crypto/ASN1/Basic ASN1 Types/ObjectIdentifier.swift b/Sources/Crypto/ASN1/Basic ASN1 Types/ObjectIdentifier.swift index 81de77eaf..2d21798e0 100644 --- a/Sources/Crypto/ASN1/Basic ASN1 Types/ObjectIdentifier.swift +++ b/Sources/Crypto/ASN1/Basic ASN1 Types/ObjectIdentifier.swift @@ -14,7 +14,12 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else + +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1 { @@ -31,9 +36,9 @@ extension ASN1 { private var oidComponents: [UInt] - init(asn1Encoded node: ASN1.ASN1Node, withIdentifier identifier: ASN1.ASN1Identifier) throws { + init(asn1Encoded node: ASN1.ASN1Node, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) { guard node.identifier == identifier else { - throw CryptoKitASN1Error.unexpectedFieldType + throw error(CryptoKitASN1Error.unexpectedFieldType) } guard case .primitive(var content) = node.content else { @@ -67,7 +72,7 @@ extension ASN1 { } guard subcomponents.count >= 2 else { - throw CryptoKitASN1Error.invalidObjectIdentifier + throw error(CryptoKitASN1Error.invalidObjectIdentifier) } // Now we need to expand the subcomponents out. This means we need to undo the step above. The first component will be in the range 0..<40 @@ -92,8 +97,8 @@ extension ASN1 { self.oidComponents = oidComponents } - func serialize(into coder: inout ASN1.Serializer, withIdentifier identifier: ASN1.ASN1Identifier) throws { - coder.appendPrimitiveNode(identifier: identifier) { bytes in + func serialize(into coder: inout ASN1.Serializer, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) { + try coder.appendPrimitiveNode(identifier: identifier) { bytes in var components = self.oidComponents[...] guard let firstComponent = components.popFirst(), let secondComponent = components.popFirst() else { preconditionFailure("Invalid number of OID components: must be at least two!") @@ -191,11 +196,11 @@ extension ASN1.ASN1ObjectIdentifier { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ArraySlice where Element == UInt8 { - mutating fileprivate func readOIDSubidentifier() throws -> UInt { + mutating fileprivate func readOIDSubidentifier() throws(CryptoKitMetaError) -> UInt { // In principle OID subidentifiers can be too large to fit into a UInt. We are choosing to not care about that // because for us it shouldn't matter. guard let subidentifierEndIndex = self.firstIndex(where: { $0 & 0x80 == 0x00 }) else { - throw CryptoKitASN1Error.invalidASN1Object + throw error(CryptoKitASN1Error.invalidASN1Object) } let oidSlice = self[self.startIndex ... subidentifierEndIndex] @@ -208,10 +213,10 @@ extension ArraySlice where Element == UInt8 { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension UInt { - fileprivate init(sevenBitBigEndianBytes bytes: Bytes) throws where Bytes.Element == UInt8 { + fileprivate init(sevenBitBigEndianBytes bytes: Bytes) throws(CryptoKitMetaError) where Bytes.Element == UInt8 { // We need to know how many bytes we _need_ to store this "int". guard ((bytes.count * 7) + 7) / 8 <= MemoryLayout.size else { - throw CryptoKitASN1Error.invalidASN1Object + throw error(CryptoKitASN1Error.invalidASN1Object) } self = 0 diff --git a/Sources/Crypto/ASN1/ECDSASignature.swift b/Sources/Crypto/ASN1/ECDSASignature.swift index 249453870..6029e5a9b 100644 --- a/Sources/Crypto/ASN1/ECDSASignature.swift +++ b/Sources/Crypto/ASN1/ECDSASignature.swift @@ -14,7 +14,12 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else + +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1 { @@ -40,8 +45,8 @@ extension ASN1 { self.s = s } - init(asn1Encoded rootNode: ASN1.ASN1Node, withIdentifier identifier: ASN1.ASN1Identifier) throws { - self = try ASN1.sequence(rootNode, identifier: identifier) { nodes in + init(asn1Encoded rootNode: ASN1.ASN1Node, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) { + self = try ASN1.sequence(rootNode, identifier: identifier) { nodes throws(CryptoKitMetaError) in let r = try IntegerType(asn1Encoded: &nodes) let s = try IntegerType(asn1Encoded: &nodes) @@ -49,8 +54,8 @@ extension ASN1 { } } - func serialize(into coder: inout ASN1.Serializer, withIdentifier identifier: ASN1.ASN1Identifier) throws { - try coder.appendConstructedNode(identifier: identifier) { coder in + func serialize(into coder: inout ASN1.Serializer, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) { + try coder.appendConstructedNode(identifier: identifier) { coder throws(CryptoKitMetaError) in try coder.serialize(self.r) try coder.serialize(self.s) } diff --git a/Sources/Crypto/ASN1/PEMDocument.swift b/Sources/Crypto/ASN1/PEMDocument.swift index f73141170..05319a6b3 100644 --- a/Sources/Crypto/ASN1/PEMDocument.swift +++ b/Sources/Crypto/ASN1/PEMDocument.swift @@ -14,7 +14,12 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else + +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1 { diff --git a/Sources/Crypto/ASN1/PKCS8PrivateKey.swift b/Sources/Crypto/ASN1/PKCS8PrivateKey.swift index 22d7cee08..3c3003edf 100644 --- a/Sources/Crypto/ASN1/PKCS8PrivateKey.swift +++ b/Sources/Crypto/ASN1/PKCS8PrivateKey.swift @@ -14,7 +14,11 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1 { @@ -50,11 +54,11 @@ extension ASN1 { var privateKey: ASN1.SEC1PrivateKey - init(asn1Encoded rootNode: ASN1.ASN1Node, withIdentifier identifier: ASN1.ASN1Identifier) throws { - self = try ASN1.sequence(rootNode, identifier: identifier) { nodes in + init(asn1Encoded rootNode: ASN1.ASN1Node, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) { + self = try ASN1.sequence(rootNode, identifier: identifier) { nodes throws(CryptoKitMetaError) in let version = try Int(asn1Encoded: &nodes) guard version == 0 else { - throw CryptoKitASN1Error.invalidASN1Object + throw error(CryptoKitASN1Error.invalidASN1Object) } let algorithm = try ASN1.RFC5480AlgorithmIdentifier(asn1Encoded: &nodes) @@ -66,14 +70,14 @@ extension ASN1 { let sec1PrivateKeyNode = try ASN1.parse(privateKeyBytes.bytes) let sec1PrivateKey = try ASN1.SEC1PrivateKey(asn1Encoded: sec1PrivateKeyNode) if let innerAlgorithm = sec1PrivateKey.algorithm, innerAlgorithm != algorithm { - throw CryptoKitASN1Error.invalidASN1Object + throw error(CryptoKitASN1Error.invalidASN1Object) } return try .init(algorithm: algorithm, privateKey: sec1PrivateKey) } } - private init(algorithm: ASN1.RFC5480AlgorithmIdentifier, privateKey: ASN1.SEC1PrivateKey) throws { + private init(algorithm: ASN1.RFC5480AlgorithmIdentifier, privateKey: ASN1.SEC1PrivateKey) throws(CryptoKitMetaError) { self.privateKey = privateKey self.algorithm = algorithm } @@ -86,8 +90,8 @@ extension ASN1 { self.privateKey = ASN1.SEC1PrivateKey(privateKey: privateKey, algorithm: nil, publicKey: publicKey) } - func serialize(into coder: inout ASN1.Serializer, withIdentifier identifier: ASN1.ASN1Identifier) throws { - try coder.appendConstructedNode(identifier: identifier) { coder in + func serialize(into coder: inout ASN1.Serializer, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) { + try coder.appendConstructedNode(identifier: identifier) { coder throws(CryptoKitMetaError) in try coder.serialize(0) // version try coder.serialize(self.algorithm) diff --git a/Sources/Crypto/ASN1/SEC1PrivateKey.swift b/Sources/Crypto/ASN1/SEC1PrivateKey.swift index 4bde009ae..86cd7b522 100644 --- a/Sources/Crypto/ASN1/SEC1PrivateKey.swift +++ b/Sources/Crypto/ASN1/SEC1PrivateKey.swift @@ -14,7 +14,12 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else + +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1 { @@ -38,18 +43,18 @@ extension ASN1 { var publicKey: ASN1.ASN1BitString? - init(asn1Encoded rootNode: ASN1.ASN1Node, withIdentifier identifier: ASN1.ASN1Identifier) throws { - self = try ASN1.sequence(rootNode, identifier: identifier) { nodes in + init(asn1Encoded rootNode: ASN1.ASN1Node, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) { + self = try ASN1.sequence(rootNode, identifier: identifier) { nodes throws(CryptoKitMetaError) in let version = try Int(asn1Encoded: &nodes) guard 1 == version else { - throw CryptoKitASN1Error.invalidASN1Object + throw error(CryptoKitASN1Error.invalidASN1Object) } let privateKey = try ASN1OctetString(asn1Encoded: &nodes) - let parameters = try ASN1.optionalExplicitlyTagged(&nodes, tagNumber: 0, tagClass: .contextSpecific) { node in + let parameters = try ASN1.optionalExplicitlyTagged(&nodes, tagNumber: 0, tagClass: .contextSpecific) { node throws(CryptoKitMetaError) in return try ASN1.ASN1ObjectIdentifier(asn1Encoded: node) } - let publicKey = try ASN1.optionalExplicitlyTagged(&nodes, tagNumber: 1, tagClass: .contextSpecific) { node in + let publicKey = try ASN1.optionalExplicitlyTagged(&nodes, tagNumber: 1, tagClass: .contextSpecific) { node throws(CryptoKitMetaError) in return try ASN1.ASN1BitString(asn1Encoded: node) } @@ -57,10 +62,10 @@ extension ASN1 { } } - private init(privateKey: ASN1.ASN1OctetString, algorithm: ASN1.ASN1ObjectIdentifier?, publicKey: ASN1.ASN1BitString?) throws { + private init(privateKey: ASN1.ASN1OctetString, algorithm: ASN1.ASN1ObjectIdentifier?, publicKey: ASN1.ASN1BitString?) throws(CryptoKitMetaError) { self.privateKey = privateKey self.publicKey = publicKey - self.algorithm = try algorithm.map { algorithmOID in + self.algorithm = try algorithm.map { algorithmOID throws(CryptoKitMetaError) in switch algorithmOID { case ASN1ObjectIdentifier.NamedCurves.secp256r1: return .ecdsaP256 @@ -69,7 +74,7 @@ extension ASN1 { case ASN1ObjectIdentifier.NamedCurves.secp521r1: return .ecdsaP521 default: - throw CryptoKitASN1Error.invalidASN1Object + throw error(CryptoKitASN1Error.invalidASN1Object) } } } @@ -80,8 +85,8 @@ extension ASN1 { self.publicKey = ASN1BitString(bytes: publicKey[...]) } - func serialize(into coder: inout ASN1.Serializer, withIdentifier identifier: ASN1.ASN1Identifier) throws { - try coder.appendConstructedNode(identifier: identifier) { coder in + func serialize(into coder: inout ASN1.Serializer, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) { + try coder.appendConstructedNode(identifier: identifier) { coder throws(CryptoKitMetaError) in try coder.serialize(1) // version try coder.serialize(self.privateKey) @@ -95,7 +100,7 @@ extension ASN1 { case .ecdsaP521: oid = ASN1ObjectIdentifier.NamedCurves.secp521r1 default: - throw CryptoKitASN1Error.invalidASN1Object + throw error(CryptoKitASN1Error.invalidASN1Object) } try coder.serialize(oid, explicitlyTaggedWithTagNumber: 0, tagClass: .contextSpecific) diff --git a/Sources/Crypto/ASN1/SubjectPublicKeyInfo.swift b/Sources/Crypto/ASN1/SubjectPublicKeyInfo.swift index cf48a0328..9e113a104 100644 --- a/Sources/Crypto/ASN1/SubjectPublicKeyInfo.swift +++ b/Sources/Crypto/ASN1/SubjectPublicKeyInfo.swift @@ -14,7 +14,12 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else + +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1 { @@ -28,14 +33,14 @@ extension ASN1 { var key: ASN1.ASN1BitString - init(asn1Encoded rootNode: ASN1.ASN1Node, withIdentifier identifier: ASN1.ASN1Identifier) throws { + init(asn1Encoded rootNode: ASN1.ASN1Node, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) { // The SPKI block looks like this: // // SubjectPublicKeyInfo ::= SEQUENCE { // algorithm AlgorithmIdentifier, // subjectPublicKey BIT STRING // } - self = try ASN1.sequence(rootNode, identifier: identifier) { nodes in + self = try ASN1.sequence(rootNode, identifier: identifier) { nodes throws(CryptoKitMetaError) in let algorithmIdentifier = try ASN1.RFC5480AlgorithmIdentifier(asn1Encoded: &nodes) let key = try ASN1.ASN1BitString(asn1Encoded: &nodes) @@ -53,8 +58,8 @@ extension ASN1 { self.key = ASN1BitString(bytes: key[...]) } - func serialize(into coder: inout ASN1.Serializer, withIdentifier identifier: ASN1.ASN1Identifier) throws { - try coder.appendConstructedNode(identifier: identifier) { coder in + func serialize(into coder: inout ASN1.Serializer, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) { + try coder.appendConstructedNode(identifier: identifier) { coder throws(CryptoKitMetaError) in try coder.serialize(self.algorithmIdentifier) try coder.serialize(self.key) } @@ -76,7 +81,7 @@ extension ASN1 { self.parameters = parameters } - init(asn1Encoded rootNode: ASN1.ASN1Node, withIdentifier identifier: ASN1.ASN1Identifier) throws { + init(asn1Encoded rootNode: ASN1.ASN1Node, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) { // The AlgorithmIdentifier block looks like this. // // AlgorithmIdentifier ::= SEQUENCE { @@ -91,17 +96,17 @@ extension ASN1 { // } // // We don't bother with helpers: we just try to decode it directly. - self = try ASN1.sequence(rootNode, identifier: identifier) { nodes in + self = try ASN1.sequence(rootNode, identifier: identifier) { nodes throws(CryptoKitMetaError) in let algorithmOID = try ASN1.ASN1ObjectIdentifier(asn1Encoded: &nodes) - let parameters = nodes.next().map { ASN1.ASN1Any(asn1Encoded: $0) } - + let n = nodes.next() + let parameters = if let n { try ASN1.ASN1Any(asn1Encoded: n) } else { nil as ASN1.ASN1Any? } return .init(algorithm: algorithmOID, parameters: parameters) } } - func serialize(into coder: inout ASN1.Serializer, withIdentifier identifier: ASN1.ASN1Identifier) throws { - try coder.appendConstructedNode(identifier: identifier) { coder in + func serialize(into coder: inout ASN1.Serializer, withIdentifier identifier: ASN1.ASN1Identifier) throws(CryptoKitMetaError) { + try coder.appendConstructedNode(identifier: identifier) { coder throws(CryptoKitMetaError) in try coder.serialize(self.algorithm) if let parameters = self.parameters { try coder.serialize(parameters) diff --git a/Sources/Crypto/CMakeLists.txt b/Sources/Crypto/CMakeLists.txt index ec399ffe5..7c0479080 100644 --- a/Sources/Crypto/CMakeLists.txt +++ b/Sources/Crypto/CMakeLists.txt @@ -42,6 +42,7 @@ add_library(Crypto "Digests/Digests.swift" "Digests/HashFunctions.swift" "Digests/HashFunctions_SHA2.swift" + "Digests/HashFunctions_SHA3.swift" "HPKE/Ciphersuite/HPKE-AEAD.swift" "HPKE/Ciphersuite/HPKE-Ciphersuite.swift" "HPKE/Ciphersuite/HPKE-KDF.swift" @@ -59,10 +60,17 @@ add_library(Crypto "HPKE/Modes/HPKE-Modes.swift" "Insecure/Insecure.swift" "Insecure/Insecure_HashFunctions.swift" + "KEM/BoringSSL/MLKEM_boring.swift" + "KEM/BoringSSL/MLKEM_wrapper.swift" + "KEM/BoringSSL/XWing_boring.swift" + "KEM/KEM-Errors.swift" "KEM/KEM.swift" + "KEM/MLKEM.swift" + "KEM/XWing.swift" "Key Agreement/BoringSSL/ECDH_boring.swift" "Key Agreement/DH.swift" "Key Agreement/ECDH.swift" + "Key Derivation/ANSIx963.swift" "Key Derivation/HKDF.swift" "Key Wrapping/AESWrap.swift" "Key Wrapping/BoringSSL/AESWrap_boring.swift" @@ -81,10 +89,14 @@ add_library(Crypto "Signatures/BoringSSL/ECDSASignature_boring.swift" "Signatures/BoringSSL/ECDSA_boring.swift" "Signatures/BoringSSL/EdDSA_boring.swift" + "Signatures/BoringSSL/MLDSA_boring.swift" + "Signatures/BoringSSL/MLDSA_wrapper.swift" "Signatures/ECDSA.swift" "Signatures/Ed25519.swift" + "Signatures/MLDSA.swift" "Signatures/Signature.swift" "Util/BoringSSL/CryptoKitErrors_boring.swift" + "Util/BoringSSL/Optional+withUnsafeBytes_boring.swift" "Util/BoringSSL/RNG_boring.swift" "Util/BoringSSL/SafeCompare_boring.swift" "Util/BoringSSL/Zeroization_boring.swift" diff --git a/Sources/Crypto/CryptoKitErrors.swift b/Sources/Crypto/CryptoKitErrors.swift index 4bc957d5c..6823f6bae 100644 --- a/Sources/Crypto/CryptoKitErrors.swift +++ b/Sources/Crypto/CryptoKitErrors.swift @@ -66,4 +66,59 @@ public enum CryptoKitASN1Error: Equatable, Error, Hashable { /// The string doesn’t parse as a PEM document. case invalidPEMDocument } + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +enum RSAPSSSPKIErrors: Error { + case invalidPSSOID + case missingParameters + case incorrectHashFunction + case incorrectMGF + case missingMGFHashFunction + case incorrectMGFHashFunction + case invalidSaltLength +} + +#if hasFeature(Embedded) +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +public struct RSAPSSSPKIError: Error { + internal var error: RSAPSSSPKIErrors +} +#else +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +struct RSAPSSSPKIError: Error { + internal var error: RSAPSSSPKIErrors +} +#endif + +#if hasFeature(Embedded) +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +public enum CryptoKitMetaError: Error { + case cryptoKitError(underlyingError: CryptoKitError) + case asn1Error(underlyingError: CryptoKitASN1Error) + case rsapssspkiError(underlyingError: RSAPSSSPKIError) +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +internal func error(_ error: CryptoKitError) -> CryptoKitMetaError { + .cryptoKitError(underlyingError: error) +} +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +internal func error(_ error: CryptoKitASN1Error) -> CryptoKitMetaError { + .asn1Error(underlyingError: error) +} +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +internal func error(_ error: RSAPSSSPKIErrors) -> CryptoKitMetaError { + .rsapssspkiError(underlyingError: RSAPSSSPKIError(error: error)) +} +#else /* !hasFeature(Embedded) */ +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +public typealias CryptoKitMetaError = any Error +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +internal func error(_ error: CryptoKitError) -> CryptoKitError { error } +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +internal func error(_ error: CryptoKitASN1Error) -> CryptoKitASN1Error { error } +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +internal func error(_ error: RSAPSSSPKIErrors) -> RSAPSSSPKIErrors { error } +#endif + #endif diff --git a/Sources/Crypto/Digests/Digest.swift b/Sources/Crypto/Digests/Digest.swift index 9a73eb90c..b42e30cd6 100644 --- a/Sources/Crypto/Digests/Digest.swift +++ b/Sources/Crypto/Digests/Digest.swift @@ -14,14 +14,30 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else -import Foundation +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +public import SwiftSystem +#else +public import Foundation +#endif + +#if hasFeature(Embedded) /// A type that represents the output of a hash. +@preconcurrency @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -public protocol Digest: Hashable, ContiguousBytes, CustomStringConvertible, Sequence where Element == UInt8 { +public protocol Digest: Hashable, Sendable, ContiguousBytes, Sequence where Element == UInt8 { /// The number of bytes in the digest. static var byteCount: Int { get } } +#else // hasFeature(Embedded) +/// A type that represents the output of a hash. +@preconcurrency +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +public protocol Digest: Hashable, Sendable, ContiguousBytes, CustomStringConvertible, Sequence where Element == UInt8 { + /// The number of bytes in the digest. + static var byteCount: Int { get } +} +#endif // hasFeature(Embedded) @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) protocol DigestPrivate: Digest { @@ -84,9 +100,15 @@ extension Digest { return safeCompare(lhs, rhs.regions.first!) } } +} +#if !hasFeature(Embedded) +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension Digest { public var description: String { return "\(Self.self): \(Array(self).hexString)" } } +#endif + #endif // Linux or !SwiftPM diff --git a/Sources/Crypto/Digests/Digests.swift b/Sources/Crypto/Digests/Digests.swift index e539bb26a..b394aceed 100644 --- a/Sources/Crypto/Digests/Digests.swift +++ b/Sources/Crypto/Digests/Digests.swift @@ -18,6 +18,8 @@ // any edits of this file WILL be overwritten and thus discarded // see section `gyb` in `README` for details. + + // MARK: - SHA256Digest + DigestPrivate /// The output of a Secure Hashing Algorithm 2 (SHA-2) hash with a 256-bit digest. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) @@ -49,6 +51,7 @@ public struct SHA256Digest: DigestPrivate { /// and returns the digest. /// /// - Returns: The digest, as returned from the body closure. +#if !hasFeature(Embedded) public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R { return try Swift.withUnsafeBytes(of: bytes) { let boundsCheckedPtr = UnsafeRawBufferPointer(start: $0.baseAddress, @@ -56,6 +59,15 @@ public struct SHA256Digest: DigestPrivate { return try body(boundsCheckedPtr) } } +#else + public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws(E) -> R) throws(E) -> R { + return try Swift.withUnsafeBytes(of: bytes) { ptr throws(E) -> R in + let boundsCheckedPtr = UnsafeRawBufferPointer(start: ptr.baseAddress, + count: Self.byteCount) + return try body(boundsCheckedPtr) + } + } +#endif private func toArray() -> ArraySlice { var array = [UInt8]() @@ -63,14 +75,16 @@ public struct SHA256Digest: DigestPrivate { array.appendByte(bytes.1) array.appendByte(bytes.2) array.appendByte(bytes.3) - return array.prefix(upTo: SHA256Digest.byteCount) + return array.prefix(SHA256Digest.byteCount) } - + +#if !hasFeature(Embedded) /// A human-readable description of the digest. public var description: String { return "\("SHA256") digest: \(toArray().hexString)" } - +#endif + /// Hashes the essential components of the digest by feeding them into the /// given hash function. /// @@ -120,6 +134,7 @@ public struct SHA384Digest: DigestPrivate { /// and returns the digest. /// /// - Returns: The digest, as returned from the body closure. +#if !hasFeature(Embedded) public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R { return try Swift.withUnsafeBytes(of: bytes) { let boundsCheckedPtr = UnsafeRawBufferPointer(start: $0.baseAddress, @@ -127,6 +142,15 @@ public struct SHA384Digest: DigestPrivate { return try body(boundsCheckedPtr) } } +#else + public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws(E) -> R) throws(E) -> R { + return try Swift.withUnsafeBytes(of: bytes) { ptr throws(E) -> R in + let boundsCheckedPtr = UnsafeRawBufferPointer(start: ptr.baseAddress, + count: Self.byteCount) + return try body(boundsCheckedPtr) + } + } +#endif private func toArray() -> ArraySlice { var array = [UInt8]() @@ -136,14 +160,16 @@ public struct SHA384Digest: DigestPrivate { array.appendByte(bytes.3) array.appendByte(bytes.4) array.appendByte(bytes.5) - return array.prefix(upTo: SHA384Digest.byteCount) + return array.prefix(SHA384Digest.byteCount) } - + +#if !hasFeature(Embedded) /// A human-readable description of the digest. public var description: String { return "\("SHA384") digest: \(toArray().hexString)" } - +#endif + /// Hashes the essential components of the digest by feeding them into the /// given hash function. /// @@ -193,6 +219,7 @@ public struct SHA512Digest: DigestPrivate { /// and returns the digest. /// /// - Returns: The digest, as returned from the body closure. +#if !hasFeature(Embedded) public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R { return try Swift.withUnsafeBytes(of: bytes) { let boundsCheckedPtr = UnsafeRawBufferPointer(start: $0.baseAddress, @@ -200,6 +227,15 @@ public struct SHA512Digest: DigestPrivate { return try body(boundsCheckedPtr) } } +#else + public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws(E) -> R) throws(E) -> R { + return try Swift.withUnsafeBytes(of: bytes) { ptr throws(E) -> R in + let boundsCheckedPtr = UnsafeRawBufferPointer(start: ptr.baseAddress, + count: Self.byteCount) + return try body(boundsCheckedPtr) + } + } +#endif private func toArray() -> ArraySlice { var array = [UInt8]() @@ -211,14 +247,16 @@ public struct SHA512Digest: DigestPrivate { array.appendByte(bytes.5) array.appendByte(bytes.6) array.appendByte(bytes.7) - return array.prefix(upTo: SHA512Digest.byteCount) + return array.prefix(SHA512Digest.byteCount) } - + +#if !hasFeature(Embedded) /// A human-readable description of the digest. public var description: String { return "\("SHA512") digest: \(toArray().hexString)" } - +#endif + /// Hashes the essential components of the digest by feeding them into the /// given hash function. /// @@ -269,6 +307,7 @@ public struct SHA1Digest: DigestPrivate { /// and returns the digest. /// /// - Returns: The digest, as returned from the body closure. +#if !hasFeature(Embedded) public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R { return try Swift.withUnsafeBytes(of: bytes) { let boundsCheckedPtr = UnsafeRawBufferPointer(start: $0.baseAddress, @@ -276,20 +315,31 @@ public struct SHA1Digest: DigestPrivate { return try body(boundsCheckedPtr) } } +#else + public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws(E) -> R) throws(E) -> R { + return try Swift.withUnsafeBytes(of: bytes) { ptr throws(E) -> R in + let boundsCheckedPtr = UnsafeRawBufferPointer(start: ptr.baseAddress, + count: Self.byteCount) + return try body(boundsCheckedPtr) + } + } +#endif private func toArray() -> ArraySlice { var array = [UInt8]() array.appendByte(bytes.0) array.appendByte(bytes.1) array.appendByte(bytes.2) - return array.prefix(upTo: SHA1Digest.byteCount) + return array.prefix(SHA1Digest.byteCount) } - + +#if !hasFeature(Embedded) /// A human-readable description of the digest. public var description: String { return "\("SHA1") digest: \(toArray().hexString)" } - +#endif + /// Hashes the essential components of the digest by feeding them into the /// given hash function. /// @@ -340,6 +390,7 @@ public struct MD5Digest: DigestPrivate { /// and returns the digest. /// /// - Returns: The digest, as returned from the body closure. +#if !hasFeature(Embedded) public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R { return try Swift.withUnsafeBytes(of: bytes) { let boundsCheckedPtr = UnsafeRawBufferPointer(start: $0.baseAddress, @@ -347,19 +398,30 @@ public struct MD5Digest: DigestPrivate { return try body(boundsCheckedPtr) } } +#else + public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws(E) -> R) throws(E) -> R { + return try Swift.withUnsafeBytes(of: bytes) { ptr throws(E) -> R in + let boundsCheckedPtr = UnsafeRawBufferPointer(start: ptr.baseAddress, + count: Self.byteCount) + return try body(boundsCheckedPtr) + } + } +#endif private func toArray() -> ArraySlice { var array = [UInt8]() array.appendByte(bytes.0) array.appendByte(bytes.1) - return array.prefix(upTo: MD5Digest.byteCount) + return array.prefix(MD5Digest.byteCount) } - + +#if !hasFeature(Embedded) /// A human-readable description of the digest. public var description: String { return "\("MD5") digest: \(toArray().hexString)" } - +#endif + /// Hashes the essential components of the digest by feeding them into the /// given hash function. /// @@ -377,4 +439,258 @@ public struct MD5Digest: DigestPrivate { } } } + + +#if !CRYPTOKIT_IN_SEP + +// MARK: - SHA3_256Digest + DigestPrivate +/// The output of a Secure Hashing Algorithm 3 (SHA-2) hash with a 256-bit digest. +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +public struct SHA3_256Digest: DigestPrivate { + let bytes: (UInt64, UInt64, UInt64, UInt64) + + init?(bufferPointer: UnsafeRawBufferPointer) { + guard bufferPointer.count == 32 else { + return nil + } + + var bytes = (UInt64(0), UInt64(0), UInt64(0), UInt64(0)) + withUnsafeMutableBytes(of: &bytes) { targetPtr in + targetPtr.copyMemory(from: bufferPointer) + } + self.bytes = bytes + } + + /// The number of bytes in the digest. + public static var byteCount: Int { + return 32 + } + + /// Invokes the given closure with a buffer pointer covering the raw bytes of + /// the digest. + /// + /// - Parameters: + /// - body: A closure that takes a raw buffer pointer to the bytes of the digest + /// and returns the digest. + /// + /// - Returns: The digest, as returned from the body closure. +#if !hasFeature(Embedded) + public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R { + return try Swift.withUnsafeBytes(of: bytes) { + let boundsCheckedPtr = UnsafeRawBufferPointer(start: $0.baseAddress, + count: Self.byteCount) + return try body(boundsCheckedPtr) + } + } +#else + public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws(E) -> R) throws(E) -> R { + return try Swift.withUnsafeBytes(of: bytes) { ptr throws(E) -> R in + let boundsCheckedPtr = UnsafeRawBufferPointer(start: ptr.baseAddress, + count: Self.byteCount) + return try body(boundsCheckedPtr) + } + } +#endif + + private func toArray() -> ArraySlice { + var array = [UInt8]() + array.appendByte(bytes.0) + array.appendByte(bytes.1) + array.appendByte(bytes.2) + array.appendByte(bytes.3) + return array.prefix(upTo: SHA3_256Digest.byteCount) + } + +#if !hasFeature(Embedded) + /// A human-readable description of the digest. + public var description: String { + return "\("SHA3_256") digest: \(toArray().hexString)" + } +#endif + + /// Hashes the essential components of the digest by feeding them into the + /// given hash function. + /// + /// This method is part of the digest’s conformance to Swift standard library’s + /// protocol, making + /// it possible to compare digests. Don’t confuse that hashing with the + /// cryptographically secure hashing that you use to create the digest in the + /// first place by, for example, calling ``SHA3_256/hash(data:)``. + /// + /// - Parameters: + /// - hasher: The hash function to use when combining the components of + /// the digest. + public func hash(into hasher: inout Hasher) { + self.withUnsafeBytes { hasher.combine(bytes: $0) } + } +} +// MARK: - SHA3_384Digest + DigestPrivate +/// The output of a Secure Hashing Algorithm 3 (SHA-2) hash with a 384-bit digest. +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +public struct SHA3_384Digest: DigestPrivate { + let bytes: (UInt64, UInt64, UInt64, UInt64, UInt64, UInt64) + + init?(bufferPointer: UnsafeRawBufferPointer) { + guard bufferPointer.count == 48 else { + return nil + } + + var bytes = (UInt64(0), UInt64(0), UInt64(0), UInt64(0), UInt64(0), UInt64(0)) + withUnsafeMutableBytes(of: &bytes) { targetPtr in + targetPtr.copyMemory(from: bufferPointer) + } + self.bytes = bytes + } + + /// The number of bytes in the digest. + public static var byteCount: Int { + return 48 + } + + /// Invokes the given closure with a buffer pointer covering the raw bytes of + /// the digest. + /// + /// - Parameters: + /// - body: A closure that takes a raw buffer pointer to the bytes of the digest + /// and returns the digest. + /// + /// - Returns: The digest, as returned from the body closure. +#if !hasFeature(Embedded) + public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R { + return try Swift.withUnsafeBytes(of: bytes) { + let boundsCheckedPtr = UnsafeRawBufferPointer(start: $0.baseAddress, + count: Self.byteCount) + return try body(boundsCheckedPtr) + } + } +#else + public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws(E) -> R) throws(E) -> R { + return try Swift.withUnsafeBytes(of: bytes) { ptr throws(E) -> R in + let boundsCheckedPtr = UnsafeRawBufferPointer(start: ptr.baseAddress, + count: Self.byteCount) + return try body(boundsCheckedPtr) + } + } +#endif + + private func toArray() -> ArraySlice { + var array = [UInt8]() + array.appendByte(bytes.0) + array.appendByte(bytes.1) + array.appendByte(bytes.2) + array.appendByte(bytes.3) + array.appendByte(bytes.4) + array.appendByte(bytes.5) + return array.prefix(upTo: SHA3_384Digest.byteCount) + } + +#if !hasFeature(Embedded) + /// A human-readable description of the digest. + public var description: String { + return "\("SHA3_384") digest: \(toArray().hexString)" + } +#endif + + /// Hashes the essential components of the digest by feeding them into the + /// given hash function. + /// + /// This method is part of the digest’s conformance to Swift standard library’s + /// protocol, making + /// it possible to compare digests. Don’t confuse that hashing with the + /// cryptographically secure hashing that you use to create the digest in the + /// first place by, for example, calling ``SHA3_384/hash(data:)``. + /// + /// - Parameters: + /// - hasher: The hash function to use when combining the components of + /// the digest. + public func hash(into hasher: inout Hasher) { + self.withUnsafeBytes { hasher.combine(bytes: $0) } + } +} +// MARK: - SHA3_512Digest + DigestPrivate +/// The output of a Secure Hashing Algorithm 3 (SHA-2) hash with a 512-bit digest. +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +public struct SHA3_512Digest: DigestPrivate { + let bytes: (UInt64, UInt64, UInt64, UInt64, UInt64, UInt64, UInt64, UInt64) + + init?(bufferPointer: UnsafeRawBufferPointer) { + guard bufferPointer.count == 64 else { + return nil + } + + var bytes = (UInt64(0), UInt64(0), UInt64(0), UInt64(0), UInt64(0), UInt64(0), UInt64(0), UInt64(0)) + withUnsafeMutableBytes(of: &bytes) { targetPtr in + targetPtr.copyMemory(from: bufferPointer) + } + self.bytes = bytes + } + + /// The number of bytes in the digest. + public static var byteCount: Int { + return 64 + } + + /// Invokes the given closure with a buffer pointer covering the raw bytes of + /// the digest. + /// + /// - Parameters: + /// - body: A closure that takes a raw buffer pointer to the bytes of the digest + /// and returns the digest. + /// + /// - Returns: The digest, as returned from the body closure. +#if !hasFeature(Embedded) + public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R { + return try Swift.withUnsafeBytes(of: bytes) { + let boundsCheckedPtr = UnsafeRawBufferPointer(start: $0.baseAddress, + count: Self.byteCount) + return try body(boundsCheckedPtr) + } + } +#else + public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws(E) -> R) throws(E) -> R { + return try Swift.withUnsafeBytes(of: bytes) { ptr throws(E) -> R in + let boundsCheckedPtr = UnsafeRawBufferPointer(start: ptr.baseAddress, + count: Self.byteCount) + return try body(boundsCheckedPtr) + } + } +#endif + + private func toArray() -> ArraySlice { + var array = [UInt8]() + array.appendByte(bytes.0) + array.appendByte(bytes.1) + array.appendByte(bytes.2) + array.appendByte(bytes.3) + array.appendByte(bytes.4) + array.appendByte(bytes.5) + array.appendByte(bytes.6) + array.appendByte(bytes.7) + return array.prefix(upTo: SHA3_512Digest.byteCount) + } + +#if !hasFeature(Embedded) + /// A human-readable description of the digest. + public var description: String { + return "\("SHA3_512") digest: \(toArray().hexString)" + } +#endif + + /// Hashes the essential components of the digest by feeding them into the + /// given hash function. + /// + /// This method is part of the digest’s conformance to Swift standard library’s + /// protocol, making + /// it possible to compare digests. Don’t confuse that hashing with the + /// cryptographically secure hashing that you use to create the digest in the + /// first place by, for example, calling ``SHA3_512/hash(data:)``. + /// + /// - Parameters: + /// - hasher: The hash function to use when combining the components of + /// the digest. + public func hash(into hasher: inout Hasher) { + self.withUnsafeBytes { hasher.combine(bytes: $0) } + } +} +#endif // !CRYPTOKIT_IN_SEP #endif // Linux or !SwiftPM diff --git a/Sources/Crypto/Digests/Digests.swift.gyb b/Sources/Crypto/Digests/Digests.swift.gyb index e059db61d..f5104fab3 100644 --- a/Sources/Crypto/Digests/Digests.swift.gyb +++ b/Sources/Crypto/Digests/Digests.swift.gyb @@ -17,9 +17,15 @@ // MARK: - Generated file, do NOT edit // any edits of this file WILL be overwritten and thus discarded // see section `gyb` in `README` for details. + %{ -digests_and_length = [{"name": "SHA256", "count": 32},{"name": "SHA384","count":48},{"name":"SHA512", "count": 64},{"name":"SHA1", "count":20, "prefix":"Insecure "},{"name":"MD5", "count":16, "prefix":"Insecure "}] +digests_and_length = [{"name": "SHA256", "count": 32},{"name": "SHA384","count":48},{"name":"SHA512", "count": 64}] +if "NO_INSECURE_DIGEST" in globals(): + pass +else: + digests_and_length.extend([{"name":"SHA1", "count":20, "prefix":"Insecure "},{"name":"MD5", "count":16, "prefix":"Insecure "}]) }% + % for HF in digests_and_length: %{ name = HF["name"] @@ -73,6 +79,7 @@ public struct ${name}Digest: DigestPrivate { /// and returns the digest. /// /// - Returns: The digest, as returned from the body closure. +#if !hasFeature(Embedded) public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R { return try Swift.withUnsafeBytes(of: bytes) { let boundsCheckedPtr = UnsafeRawBufferPointer(start: $0.baseAddress, @@ -80,6 +87,15 @@ public struct ${name}Digest: DigestPrivate { return try body(boundsCheckedPtr) } } +#else + public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws(E) -> R) throws(E) -> R { + return try Swift.withUnsafeBytes(of: bytes) { ptr throws(E) -> R in + let boundsCheckedPtr = UnsafeRawBufferPointer(start: ptr.baseAddress, + count: Self.byteCount) + return try body(boundsCheckedPtr) + } + } +#endif private func toArray() -> ArraySlice { var array = [UInt8]() @@ -87,14 +103,16 @@ public struct ${name}Digest: DigestPrivate { % for index in range(wordsCount-1): array.appendByte(bytes.${index+1}) % end - return array.prefix(upTo: ${name}Digest.byteCount) + return array.prefix(${name}Digest.byteCount) } - + +#if !hasFeature(Embedded) /// A human-readable description of the digest. public var description: String { return "\("${name}") digest: \(toArray().hexString)" } - +#endif + /// Hashes the essential components of the digest by feeding them into the /// given hash function. /// @@ -113,4 +131,107 @@ public struct ${name}Digest: DigestPrivate { } ${protocol_suffix} % end + + +#if !CRYPTOKIT_IN_SEP +%{ +digests_and_length = [ + {"name": "SHA3_256", "count": 32}, + {"name": "SHA3_384", "count": 48}, + {"name": "SHA3_512", "count": 64} +] +}% + +% for HF in digests_and_length: +%{ + name = HF["name"] + byteCount = HF["count"] + wordsCount = (byteCount*8)//64 + (0 if ((byteCount*8)%64) == 0 else 1) +}% +%{ + parent = name + abstract = "The output of a Secure Hashing Algorithm 3 (SHA-2) hash with a " + name[-3:] + "-bit digest." +}% +// MARK: - ${name}Digest + DigestPrivate +/// ${abstract} +public struct ${name}Digest: DigestPrivate { + let bytes: (${(wordsCount-1)*"UInt64, "+"UInt64"}) + + init?(bufferPointer: UnsafeRawBufferPointer) { + guard bufferPointer.count == ${byteCount} else { + return nil + } + + var bytes = (${(wordsCount-1)*"UInt64(0), "+"UInt64(0)"}) + withUnsafeMutableBytes(of: &bytes) { targetPtr in + targetPtr.copyMemory(from: bufferPointer) + } + self.bytes = bytes + } + + /// The number of bytes in the digest. + public static var byteCount: Int { + return ${byteCount} + } + + /// Invokes the given closure with a buffer pointer covering the raw bytes of + /// the digest. + /// + /// - Parameters: + /// - body: A closure that takes a raw buffer pointer to the bytes of the digest + /// and returns the digest. + /// + /// - Returns: The digest, as returned from the body closure. +#if !hasFeature(Embedded) + public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R { + return try Swift.withUnsafeBytes(of: bytes) { + let boundsCheckedPtr = UnsafeRawBufferPointer(start: $0.baseAddress, + count: Self.byteCount) + return try body(boundsCheckedPtr) + } + } +#else + public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws(E) -> R) throws(E) -> R { + return try Swift.withUnsafeBytes(of: bytes) { ptr throws(E) -> R in + let boundsCheckedPtr = UnsafeRawBufferPointer(start: ptr.baseAddress, + count: Self.byteCount) + return try body(boundsCheckedPtr) + } + } +#endif + + private func toArray() -> ArraySlice { + var array = [UInt8]() + array.appendByte(bytes.0) + % for index in range(wordsCount-1): + array.appendByte(bytes.${index+1}) + % end + return array.prefix(upTo: ${name}Digest.byteCount) + } + +#if !hasFeature(Embedded) + /// A human-readable description of the digest. + public var description: String { + return "\("${name}") digest: \(toArray().hexString)" + } +#endif + + /// Hashes the essential components of the digest by feeding them into the + /// given hash function. + /// + /// This method is part of the digest’s conformance to Swift standard library’s + /// protocol, making + /// it possible to compare digests. Don’t confuse that hashing with the + /// cryptographically secure hashing that you use to create the digest in the + /// first place by, for example, calling ``${parent}/hash(data:)``. + /// + /// - Parameters: + /// - hasher: The hash function to use when combining the components of + /// the digest. + public func hash(into hasher: inout Hasher) { + self.withUnsafeBytes { hasher.combine(bytes: $0) } + } +} +% end +#endif // !CRYPTOKIT_IN_SEP #endif // Linux or !SwiftPM diff --git a/Sources/Crypto/Digests/HashFunctions.swift b/Sources/Crypto/Digests/HashFunctions.swift index 96e2b19f0..887296e65 100644 --- a/Sources/Crypto/Digests/HashFunctions.swift +++ b/Sources/Crypto/Digests/HashFunctions.swift @@ -14,7 +14,7 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else -#if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +#if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) typealias DigestImpl = CoreCryptoDigestImpl #else @@ -22,7 +22,11 @@ typealias DigestImpl = CoreCryptoDigestImpl typealias DigestImpl = OpenSSLDigestImpl #endif -import Foundation +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +public import SwiftSystem +#else +public import Foundation +#endif /// A type that performs cryptographically secure hashing. /// @@ -42,11 +46,12 @@ import Foundation /// authentication code (MAC) like ``HMAC`` instead. MACs rely on hashing, but /// incorporate a secret cryptographic key into the digest computation. Only a /// user that has the key can generate a valid MAC. +@preconcurrency @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -public protocol HashFunction { +public protocol HashFunction: Sendable { /// The number of bytes that represents the hash function’s internal state. static var blockByteCount: Int { get } - #if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API + #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION /// The type of the digest returned by the hash function. associatedtype Digest: CryptoKit.Digest #else @@ -111,7 +116,7 @@ extension HashFunction { return hasher.finalize() } - /// Computes the SHA1 digest of the bytes in the given data instance and + /// Computes the digest of the bytes in the given data instance and /// returns the computed digest. /// /// Use this method if all your data fits into a single data instance. If diff --git a/Sources/Crypto/Digests/HashFunctions_SHA2.swift b/Sources/Crypto/Digests/HashFunctions_SHA2.swift index a87a03d6a..4ef40d754 100644 --- a/Sources/Crypto/Digests/HashFunctions_SHA2.swift +++ b/Sources/Crypto/Digests/HashFunctions_SHA2.swift @@ -14,6 +14,21 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else +/// An implementation of Secure Hashing Algorithm 2 (SHA-2) hashing with a +/// 256-bit digest. +/// +/// The ``SHA2_256`` hash implements the ``HashFunction`` protocol for the +/// specific case of SHA-2 hashing with a 256-bit digest (``SHA256Digest``). +/// Larger digests take more space but are more secure. +/// +/// You can compute the digest by calling the static ``hash(data:)`` method +/// once. Alternatively, if the data that you want to hash is too large to fit +/// in memory, you can compute the digest iteratively by creating a new hash +/// instance, calling the ``update(data:)`` method repeatedly with blocks of +/// data, and then calling the ``finalize()`` method to get the result. +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +public typealias SHA2_256 = SHA256 + /// An implementation of Secure Hashing Algorithm 2 (SHA-2) hashing with a /// 256-bit digest. /// @@ -27,19 +42,11 @@ /// instance, calling the ``update(data:)`` method repeatedly with blocks of /// data, and then calling the ``finalize()`` method to get the result. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -public struct SHA256: HashFunctionImplementationDetails { +public struct SHA256: HashFunctionImplementationDetails, Sendable { /// The number of bytes that represents the hash function’s internal state. - public static var blockByteCount: Int { - get { 64 } - - set { fatalError("Cannot set SHA256.blockByteCount") } - } + public static let blockByteCount: Int = 64 /// The number of bytes in a SHA256 digest. - public static var byteCount: Int { - get { 32 } - - set { fatalError("Cannot set SHA256.byteCount") } - } + public static let byteCount: Int = 32 /// The digest type for a SHA256 hash function. public typealias Digest = SHA256Digest @@ -59,9 +66,6 @@ public struct SHA256: HashFunctionImplementationDetails { impl = DigestImpl() } - // Once https://github.com/apple/swift-evolution/pull/910 is landed, - // we will be able to implement `init` here and remove the duplicate code. - /// Incrementally updates the hash function with the contents of the buffer. /// /// Call this method one or more times to provide data to the hash function @@ -97,6 +101,21 @@ public struct SHA256: HashFunctionImplementationDetails { } } +/// An implementation of Secure Hashing Algorithm 2 (SHA-2) hashing with a +/// 384-bit digest. +/// +/// The ``SHA2_384`` hash implements the ``HashFunction`` protocol for the +/// specific case of SHA-2 hashing with a 384-bit digest (``SHA384Digest``). +/// Larger digests take more space but are more secure. +/// +/// You can compute the digest by calling the static ``hash(data:)`` method +/// once. Alternatively, if the data that you want to hash is too large to fit +/// in memory, you can compute the digest iteratively by creating a new hash +/// instance, calling the ``update(data:)`` method repeatedly with blocks of +/// data, and then calling the ``finalize()`` method to get the result. +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +public typealias SHA2_384 = SHA384 + /// An implementation of Secure Hashing Algorithm 2 (SHA-2) hashing with a /// 384-bit digest. /// @@ -110,19 +129,11 @@ public struct SHA256: HashFunctionImplementationDetails { /// instance, calling the ``update(data:)`` method repeatedly with blocks of /// data, and then calling the ``finalize()`` method to get the result. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -public struct SHA384: HashFunctionImplementationDetails { +public struct SHA384: HashFunctionImplementationDetails, Sendable { /// The number of bytes that represents the hash function’s internal state. - public static var blockByteCount: Int { - get { 128 } - - set { fatalError("Cannot set SHA384.blockByteCount") } - } + public static let blockByteCount: Int = 128 /// The number of bytes in a SHA384 digest. - public static var byteCount: Int { - get { 48 } - - set { fatalError("Cannot set SHA384.byteCount") } - } + public static let byteCount: Int = 48 /// The digest type for a SHA384 hash function. public typealias Digest = SHA384Digest @@ -143,9 +154,6 @@ public struct SHA384: HashFunctionImplementationDetails { impl = DigestImpl() } - // Once https://github.com/apple/swift-evolution/pull/910 is landed, - // we will be able to implement `init` here and remove the duplicate code. - /// Incrementally updates the hash function with the contents of the buffer. /// /// Call this method one or more times to provide data to the hash function @@ -181,6 +189,21 @@ public struct SHA384: HashFunctionImplementationDetails { } } +/// An implementation of Secure Hashing Algorithm 2 (SHA-2) hashing with a +/// 512-bit digest. +/// +/// The ``SHA2_512`` hash implements the ``HashFunction`` protocol for the +/// specific case of SHA-2 hashing with a 512-bit digest (``SHA512Digest``). +/// Larger digests take more space but are more secure. +/// +/// You can compute the digest by calling the static ``hash(data:)`` method +/// once. Alternatively, if the data that you want to hash is too large to fit +/// in memory, you can compute the digest iteratively by creating a new hash +/// instance, calling the ``update(data:)`` method repeatedly with blocks of +/// data, and then calling the ``finalize()`` method to get the result. +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +public typealias SHA2_512 = SHA512 + /// An implementation of Secure Hashing Algorithm 2 (SHA-2) hashing with a /// 512-bit digest. /// @@ -194,19 +217,11 @@ public struct SHA384: HashFunctionImplementationDetails { /// instance, calling the ``update(data:)`` method repeatedly with blocks of /// data, and then calling the ``finalize()`` method to get the result. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -public struct SHA512: HashFunctionImplementationDetails { +public struct SHA512: HashFunctionImplementationDetails, Sendable { /// The number of bytes that represents the hash function’s internal state. - public static var blockByteCount: Int { - get { 128 } - - set { fatalError("Cannot set SHA512.blockByteCount") } - } + public static let blockByteCount: Int = 128 /// The number of bytes in a SHA512 digest. - public static var byteCount: Int { - get { 64 } - - set { fatalError("Cannot set SHA512.byteCount") } - } + public static let byteCount: Int = 64 /// The digest type for a SHA512 hash function. public typealias Digest = SHA512Digest diff --git a/Sources/Crypto/Digests/HashFunctions_SHA3.swift b/Sources/Crypto/Digests/HashFunctions_SHA3.swift new file mode 100644 index 000000000..77ad3ce64 --- /dev/null +++ b/Sources/Crypto/Digests/HashFunctions_SHA3.swift @@ -0,0 +1,234 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2019-2020 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +// No BoringSSL support for SHA3. +#if false +#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +@_exported import CryptoKit +#else +#if !CRYPTOKIT_IN_SEP +/// An implementation of Secure Hashing Algorithm 3 (SHA-3) hashing with a 256-bit digest. +/// +/// The ``SHA3_256`` hash implements the ``HashFunction`` protocol for the +/// specific case of SHA-3 hashing with a 256-bit digest (``SHA3_256Digest``). +/// Larger digests take more space but are more secure. +/// +/// Applications can compute the digest by calling the static ``hash(data:)`` +/// method once. Alternatively, if the data to hash is too large to fit in memory, +/// applications can compute the digest iteratively by creating a new hash +/// instance, calling the ``update(data:)`` method repeatedly with blocks of +/// data, and then calling the ``finalize()`` method to get the result. +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +public struct SHA3_256: HashFunctionImplementationDetails, Sendable { + /// The number of bytes that represents the hash function’s internal state. + public static let blockByteCount: Int = 136 + /// The number of bytes in a SHA3-256 digest. + public static let byteCount: Int = 32 + /// The digest type for a SHA3-256 hash function. + public typealias Digest = SHA3_256Digest + + var impl: DigestImpl + + /// Creates a SHA3-256 hash function. + /// + /// Initialize a new hash function by calling this method if you want to + /// hash data iteratively, such as when you don’t have a buffer large enough + /// to hold all the data at once. Provide data blocks to the hash function + /// using the ``update(data:)`` or ``update(bufferPointer:)`` method. After + /// providing all the data, call ``finalize()`` to get the digest. + /// + /// If your data fits into a single buffer, you can use the ``hash(data:)`` + /// method instead, to compute the digest in a single call. + public init() { + impl = DigestImpl() + } + + /// Incrementally updates the hash function with the contents of the buffer. + /// + /// Call this method one or more times to provide data to the hash function + /// in blocks. After providing the last block of data, call the + /// ``finalize()`` method to get the computed digest. Don’t call the update + /// method again after finalizing the hash function. + /// + /// - Note: Typically, it’s safer to use an instance of + /// , or some + /// other type that conforms to the + /// , + /// to hold your data. When possible, use the ``update(data:)`` method + /// instead. + /// + /// - Parameters: + /// - bufferPointer: A pointer to the next block of data for the ongoing + /// digest calculation. + public mutating func update(bufferPointer: UnsafeRawBufferPointer) { + impl.update(data: bufferPointer) + } + + /// Finalizes the hash function and returns the computed digest. + /// + /// Call this method after you provide the hash function with all the data + /// to hash by making one or more calls to the ``update(data:)`` or + /// ``update(bufferPointer:)`` method. After finalizing the hash function, + /// discard it. To compute a new digest, create a new hash function with a + /// call to the ``init()`` method. + /// + /// - Returns: The computed digest of the data. + public func finalize() -> Self.Digest { + return impl.finalize() + } +} + +/// An implementation of Secure Hashing Algorithm 3 (SHA-3) hashing with a 384-bit digest. +/// +/// The ``SHA3_384`` hash implements the ``HashFunction`` protocol for the +/// specific case of SHA-3 hashing with a 384-bit digest (``SHA3_384Digest``). +/// Larger digests take more space but are more secure. +/// +/// Applications can compute the digest by calling the static ``hash(data:)`` +/// method once. Alternatively, if the data to hash is too large to fit in memory, +/// applications can compute the digest iteratively by creating a new hash +/// instance, calling the ``update(data:)`` method repeatedly with blocks of +/// data, and then calling the ``finalize()`` method to get the result. +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +public struct SHA3_384: HashFunctionImplementationDetails, Sendable { + /// The number of bytes that represents the hash function’s internal state. + public static let blockByteCount: Int = 104 + /// The number of bytes in a SHA3-384 digest. + public static let byteCount: Int = 48 + /// The digest type for a SHA3-384 hash function. + public typealias Digest = SHA3_384Digest + + var impl: DigestImpl + + /// Creates a SHA3-384 hash function. + /// + /// Initialize a new hash function by calling this method if you want to + /// hash data iteratively, such as when you don’t have a buffer large enough + /// to hold all the data at once. Provide data blocks to the hash function + /// using the ``update(data:)`` or ``update(bufferPointer:)`` method. After + /// providing all the data, call ``finalize()`` to get the digest. + /// + /// If your data fits into a single buffer, you can use the ``hash(data:)`` + /// method instead, to compute the digest in a single call. + public init() { + impl = DigestImpl() + } + + /// Incrementally updates the hash function with the contents of the buffer. + /// + /// Call this method one or more times to provide data to the hash function + /// in blocks. After providing the last block of data, call the + /// ``finalize()`` method to get the computed digest. Don’t call the update + /// method again after finalizing the hash function. + /// + /// - Note: Typically, it’s safer to use an instance of + /// , or some + /// other type that conforms to the + /// , + /// to hold your data. When possible, use the ``update(data:)`` method + /// instead. + /// + /// - Parameters: + /// - bufferPointer: A pointer to the next block of data for the ongoing + /// digest calculation. + public mutating func update(bufferPointer: UnsafeRawBufferPointer) { + impl.update(data: bufferPointer) + } + + /// Finalizes the hash function and returns the computed digest. + /// + /// Call this method after you provide the hash function with all the data + /// to hash by making one or more calls to the ``update(data:)`` or + /// ``update(bufferPointer:)`` method. After finalizing the hash function, + /// discard it. To compute a new digest, create a new hash function with a + /// call to the ``init()`` method. + /// + /// - Returns: The computed digest of the data. + public func finalize() -> Self.Digest { + return impl.finalize() + } +} + +/// An implementation of Secure Hashing Algorithm 3 (SHA-3) hashing with a 512-bit digest. +/// +/// The ``SHA3_512`` hash implements the ``HashFunction`` protocol for the +/// specific case of SHA-3 hashing with a 512-bit digest (``SHA3_512Digest``). +/// Larger digests take more space but are more secure. +/// +/// Applications can compute the digest by calling the static ``hash(data:)`` +/// method once. Alternatively, if the data to hash is too large to fit in memory, +/// applications can compute the digest iteratively by creating a new hash +/// instance, calling the ``update(data:)`` method repeatedly with blocks of +/// data, and then calling the ``finalize()`` method to get the result. +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +public struct SHA3_512: HashFunctionImplementationDetails, Sendable { + /// The number of bytes that represents the hash function’s internal state. + public static let blockByteCount: Int = 72 + /// The number of bytes in a SHA3-512 digest. + public static let byteCount: Int = 64 + /// The digest type for a SHA3-512 hash function. + public typealias Digest = SHA3_512Digest + + var impl: DigestImpl + + /// Creates a SHA3-512 hash function. + /// + /// Initialize a new hash function by calling this method if you want to + /// hash data iteratively, such as when you don’t have a buffer large enough + /// to hold all the data at once. Provide data blocks to the hash function + /// using the ``update(data:)`` or ``update(bufferPointer:)`` method. After + /// providing all the data, call ``finalize()`` to get the digest. + /// + /// If your data fits into a single buffer, you can use the ``hash(data:)`` + /// method instead, to compute the digest in a single call. + public init() { + impl = DigestImpl() + } + + /// Incrementally updates the hash function with the contents of the buffer. + /// + /// Call this method one or more times to provide data to the hash function + /// in blocks. After providing the last block of data, call the + /// ``finalize()`` method to get the computed digest. Don’t call the update + /// method again after finalizing the hash function. + /// + /// - Note: Typically, it’s safer to use an instance of + /// , or some + /// other type that conforms to the + /// , + /// to hold your data. When possible, use the ``update(data:)`` method + /// instead. + /// + /// - Parameters: + /// - bufferPointer: A pointer to the next block of data for the ongoing + /// digest calculation. + public mutating func update(bufferPointer: UnsafeRawBufferPointer) { + impl.update(data: bufferPointer) + } + + /// Finalizes the hash function and returns the computed digest. + /// + /// Call this method after you provide the hash function with all the data + /// to hash by making one or more calls to the ``update(data:)`` or + /// ``update(bufferPointer:)`` method. After finalizing the hash function, + /// discard it. To compute a new digest, create a new hash function with a + /// call to the ``init()`` method. + /// + /// - Returns: The computed digest of the data. + public func finalize() -> Self.Digest { + return impl.finalize() + } +} +#endif // !CRYPTOKIT_IN_SEP +#endif // Linux or !SwiftPM +#endif // No BoringSSL support for SHA3. diff --git a/Sources/Crypto/HPKE/Ciphersuite/HPKE-AEAD.swift b/Sources/Crypto/HPKE/Ciphersuite/HPKE-AEAD.swift index 90764659d..4a501269b 100644 --- a/Sources/Crypto/HPKE/Ciphersuite/HPKE-AEAD.swift +++ b/Sources/Crypto/HPKE/Ciphersuite/HPKE-AEAD.swift @@ -14,14 +14,19 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else + +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension HPKE { /// The authenticated encryption with associated data (AEAD) algorithms to use in HPKE. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public enum AEAD: CaseIterable, Hashable { + public enum AEAD: CaseIterable, Hashable, Sendable { /// An Advanced Encryption Standard cipher in Galois/Counter Mode with a key length of 128 bits. case AES_GCM_128 /// An Advanced Encryption Standard cipher in Galois/Counter Mode with a key length of 256 bits. @@ -33,7 +38,9 @@ extension HPKE { /// In export-only mode, HPKE negotiates key derivation, but you can't use it to encrypt or decrypt data. case exportOnly - internal var value: UInt16 { + /// Return the AEAD algorithm identifier as defined in section 7.3 of [RFC 9180](https://www.ietf.org/rfc/rfc9180.pdf). + @_spi(HPKEAlgID) + public var value: UInt16 { switch self { case .AES_GCM_128: return 0x0001 case .AES_GCM_256: return 0x0002 @@ -46,7 +53,9 @@ extension HPKE { return self == .exportOnly } - internal var keyByteCount: Int { + /// Return the AEAD key size in bytes + @_spi(HPKEAlgID) + public var keyByteCount: Int { switch self { case .AES_GCM_128: return 16 @@ -59,7 +68,9 @@ extension HPKE { } } - internal var nonceByteCount: Int { + /// Return the AEAD nonce size in bytes + @_spi(HPKEAlgID) + public var nonceByteCount: Int { switch self { case .AES_GCM_128, .AES_GCM_256, .chaChaPoly: return 12 @@ -68,7 +79,9 @@ extension HPKE { } } - internal var tagByteCount: Int { + /// Return the AEAD tag size in bytes + @_spi(HPKEAlgID) + public var tagByteCount: Int { switch self { case .AES_GCM_128, .AES_GCM_256, .chaChaPoly: return 16 @@ -81,7 +94,8 @@ extension HPKE { return I2OSP(value: Int(self.value), outputByteCount: 2) } - internal func seal(_ message: D, authenticating aad: AD, nonce: Data, using key: SymmetricKey) throws -> Data { + @_spi(MLS) + public func seal(_ message: D, authenticating aad: AD, nonce: Data, using key: SymmetricKey) throws -> Data { switch self { case .chaChaPoly: return try ChaChaPoly.seal(message, using: key, nonce: ChaChaPoly.Nonce(data: nonce), authenticating: aad).combined.dropFirst(nonce.count) @@ -90,7 +104,8 @@ extension HPKE { } } - internal func open(_ ct: C, nonce: Data, authenticating aad: AD, using key: SymmetricKey) throws -> Data { + @_spi(MLS) + public func open(_ ct: C, nonce: Data, authenticating aad: AD, using key: SymmetricKey) throws -> Data { guard ct.count >= self.tagByteCount else { throw HPKE.Errors.expectedPSK } diff --git a/Sources/Crypto/HPKE/Ciphersuite/HPKE-Ciphersuite.swift b/Sources/Crypto/HPKE/Ciphersuite/HPKE-Ciphersuite.swift index 5a145ce11..5bfa85f53 100644 --- a/Sources/Crypto/HPKE/Ciphersuite/HPKE-Ciphersuite.swift +++ b/Sources/Crypto/HPKE/Ciphersuite/HPKE-Ciphersuite.swift @@ -14,19 +14,24 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else + +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension HPKE { - /// Cipher suites to use in hybrid public key encryption. + /// Cipher suites to use in hybrid public key encryption (HPKE). /// /// HPKE cipher suites identify the authenticated encryption with additional data (AEAD) algorithm for encrypting /// and decrypting messages, the key derivation function (KDF) for deriving the shared key, and the key encapsulation /// mechanism (KEM) for sharing the symmetric key. The sender and recipient of encrypted messages need to use the /// same cipher suite. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public struct Ciphersuite { + public struct Ciphersuite: Sendable { /// A cipher suite for HPKE that uses NIST P-256 elliptic curve key agreement, SHA-2 key derivation /// with a 256-bit digest, and the Advanced Encryption Standard cipher in Galois/Counter Mode with a key length of 256 bits. public static let P256_SHA256_AES_GCM_256 = Ciphersuite(kem: .P256_HKDF_SHA256, kdf: .HKDF_SHA256, aead: .AES_GCM_256) @@ -39,7 +44,10 @@ extension HPKE { /// A cipher suite for HPKE that uses X25519 elliptic curve key agreement, SHA-2 key derivation /// with a 256-bit digest, and the ChaCha20 stream cipher with the Poly1305 message authentication code. public static let Curve25519_SHA256_ChachaPoly = Ciphersuite(kem: .Curve25519_HKDF_SHA256, kdf: .HKDF_SHA256, aead: .chaChaPoly) - + /// A cipher suite for HPKE that uses the X-Wing KEM (ML-KEM-768 with X25519), SHA-2 key derivation + /// with a 256-bit digest, and the Advanced Encryption Standard cipher in Galois/Counter Mode with a key length of 256 bits. + public static let XWingMLKEM768X25519_SHA256_AES_GCM_256 = Ciphersuite(kem: .XWingMLKEM768X25519, kdf: .HKDF_SHA256, aead: .AES_GCM_256) + fileprivate static let ciphersuiteLabel = Data("HPKE".utf8) /// The key encapsulation mechanism (KEM) for encapsulating the symmetric key. diff --git a/Sources/Crypto/HPKE/Ciphersuite/HPKE-KDF.swift b/Sources/Crypto/HPKE/Ciphersuite/HPKE-KDF.swift index 5109adaeb..eed03a15d 100644 --- a/Sources/Crypto/HPKE/Ciphersuite/HPKE-KDF.swift +++ b/Sources/Crypto/HPKE/Ciphersuite/HPKE-KDF.swift @@ -14,22 +14,28 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else + +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension HPKE { /// The key derivation functions to use in HPKE. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public enum KDF: CaseIterable, Hashable { + public enum KDF: CaseIterable, Hashable, Sendable { /// An HMAC-based key derivation function that uses SHA-2 hashing with a 256-bit digest. case HKDF_SHA256 /// An HMAC-based key derivation function that uses SHA-2 hashing with a 384-bit digest. case HKDF_SHA384 /// An HMAC-based key derivation function that uses SHA-2 hashing with a 512-bit digest. case HKDF_SHA512 - - /// Assigned value - internal var value: UInt16 { + + /// Return the KDF algorithm identifier as defined in section 7.2 of [RFC 9180](https://www.ietf.org/rfc/rfc9180.pdf). + @_spi(HPKEAlgID) + public var value: UInt16 { switch self { case .HKDF_SHA256: return 0x0001 case .HKDF_SHA384: return 0x0002 @@ -63,7 +69,8 @@ extension HPKE { /// - ikm: The initial key material the derivation function uses to derive a key. /// /// - Returns: A pseudorandom, cryptographically strong key in the form of a hashed authentication code. - func extract(salt: S, ikm: SymmetricKey) -> SymmetricKey { + @_spi(MLS) + public func extract(salt: S, ikm: SymmetricKey) -> SymmetricKey { switch self { case .HKDF_SHA256: return SymmetricKey(data: HKDF.extract(inputKeyMaterial: ikm, salt: salt)) @@ -85,7 +92,8 @@ extension HPKE { /// - outputByteCount: The length in bytes of the resulting symmetric key. /// /// - Returns: The derived symmetric key. - func expand(prk: SymmetricKey, info: Data, outputByteCount: Int) -> SymmetricKey { + @_spi(MLS) + public func expand(prk: SymmetricKey, info: Data, outputByteCount: Int) -> SymmetricKey { switch self { case .HKDF_SHA256: return SymmetricKey(data: HKDF.expand(pseudoRandomKey: prk, info: info, outputByteCount: outputByteCount)) diff --git a/Sources/Crypto/HPKE/Ciphersuite/HPKE-KexKeyDerivation.swift b/Sources/Crypto/HPKE/Ciphersuite/HPKE-KexKeyDerivation.swift index 05026a107..f37ba8006 100644 --- a/Sources/Crypto/HPKE/Ciphersuite/HPKE-KexKeyDerivation.swift +++ b/Sources/Crypto/HPKE/Ciphersuite/HPKE-KexKeyDerivation.swift @@ -14,7 +14,13 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else + +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else import Foundation +#endif + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) private let suiteIDLabel = Data("KEM".utf8) @@ -27,7 +33,7 @@ extension HPKE { pkRm: Data, pkSm: Data? = nil, kem: HPKE.KEM, kdf: HPKE.KDF) -> SymmetricKey { var suiteID = suiteIDLabel suiteID.append(kem.identifier) - #if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API + #if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API return CryptoKit.ExtractAndExpand(zz: dh, kemContext: kemContext(enc: enc, pkRm: pkRm, pkSm: pkSm), suiteID: suiteID, kem: kem, kdf: kdf) #else @@ -40,7 +46,7 @@ extension HPKE { var context = Data() context.append(enc) context.append(pkRm) - if let pkSm = pkSm { context.append(pkSm) } + if let pkSm { context.append(pkSm) } return context } } diff --git a/Sources/Crypto/HPKE/Ciphersuite/HPKE-LabeledExtract.swift b/Sources/Crypto/HPKE/Ciphersuite/HPKE-LabeledExtract.swift index 8f3ae5f9d..8e5d97e60 100644 --- a/Sources/Crypto/HPKE/Ciphersuite/HPKE-LabeledExtract.swift +++ b/Sources/Crypto/HPKE/Ciphersuite/HPKE-LabeledExtract.swift @@ -14,7 +14,13 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else + +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else import Foundation +#endif + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) private let protocolLabel = Data("HPKE-v1".utf8) diff --git a/Sources/Crypto/HPKE/Ciphersuite/HPKE-Utils.swift b/Sources/Crypto/HPKE/Ciphersuite/HPKE-Utils.swift index d0e8f8121..a84c60d96 100644 --- a/Sources/Crypto/HPKE/Ciphersuite/HPKE-Utils.swift +++ b/Sources/Crypto/HPKE/Ciphersuite/HPKE-Utils.swift @@ -14,15 +14,27 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else + +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else import Foundation +#endif + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) internal func I2OSP(value: Int, outputByteCount: Int) -> Data { precondition(outputByteCount > 0, "Cannot I2OSP with no output length.") precondition(value >= 0, "I2OSP requires a non-null value.") + #if !CRYPTOKIT_NO_ACCESS_TO_FOUNDATION @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) let requiredBytes = Int(ceil(log2(Double(max(value, 1) + 1)) / 8)) + #else + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) + let requiredBytes = Int((log2_bridge(Double(max(value, 1) + 1)) / 8).rounded(.up)) + #endif + precondition(outputByteCount >= requiredBytes) @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) diff --git a/Sources/Crypto/HPKE/Ciphersuite/KEM/Conformances/DHKEM.swift b/Sources/Crypto/HPKE/Ciphersuite/KEM/Conformances/DHKEM.swift index b62007047..5e06baf88 100644 --- a/Sources/Crypto/HPKE/Ciphersuite/KEM/Conformances/DHKEM.swift +++ b/Sources/Crypto/HPKE/Ciphersuite/KEM/Conformances/DHKEM.swift @@ -14,11 +14,17 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else -import Foundation + +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else +public import Foundation +#endif /// A type that ``HPKE`` uses to encode the public key. +@preconcurrency @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -public protocol HPKEPublicKeySerialization { +public protocol HPKEPublicKeySerialization: Sendable { /// Creates a public key from an encoded representation. /// /// - Parameters: @@ -35,35 +41,58 @@ public protocol HPKEPublicKeySerialization { } /// A type that represents the public key in a Diffie-Hellman key exchange. +@preconcurrency @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -public protocol HPKEDiffieHellmanPublicKey: HPKEPublicKeySerialization where EphemeralPrivateKey.PublicKey == Self { +public protocol HPKEDiffieHellmanPublicKey: HPKEPublicKeySerialization, Sendable where EphemeralPrivateKey.PublicKey == Self { /// The type of the ephemeral private key. associatedtype EphemeralPrivateKey: HPKEDiffieHellmanPrivateKeyGeneration } +/// A type that represents the public key in HPKE +@preconcurrency +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +public protocol HPKEKEMPublicKey: KEMPublicKey, HPKEPublicKeySerialization where EphemeralPrivateKey.PublicKey == Self { + /// The type of the ephemeral private key. + associatedtype EphemeralPrivateKey: HPKEKEMPrivateKeyGeneration +} + /// A type that represents the private key in a Diffie-Hellman key exchange. +@preconcurrency +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +public protocol HPKEDiffieHellmanPrivateKey: Sendable, DiffieHellmanKeyAgreement where PublicKey: HPKEDiffieHellmanPublicKey {} +/// A type that represents the private key in HPKE. +@preconcurrency @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -public protocol HPKEDiffieHellmanPrivateKey: DiffieHellmanKeyAgreement where PublicKey: HPKEDiffieHellmanPublicKey {} +public protocol HPKEKEMPrivateKey: Sendable, KEMPrivateKey where PublicKey: HPKEKEMPublicKey {} /// A type that represents the generation of private keys in a Diffie-Hellman key exchange. +@preconcurrency @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -public protocol HPKEDiffieHellmanPrivateKeyGeneration: HPKEDiffieHellmanPrivateKey { +public protocol HPKEDiffieHellmanPrivateKeyGeneration: HPKEDiffieHellmanPrivateKey, Sendable { /// Creates a private key generator. init() } +/// A type that represents the generation of private keys in HPKE +@preconcurrency +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +public protocol HPKEKEMPrivateKeyGeneration: HPKEKEMPrivateKey, Sendable { + /// Creates a private key generator. + init() throws +} + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension HPKE { /// A container for Diffie-Hellman key encapsulation mechanisms (KEMs). @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public enum DHKEM { + public enum DHKEM: Sendable { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) struct PublicKey: KEMPublicKey where DHPK == DHPK.EphemeralPrivateKey.PublicKey { let kem: HPKE.KEM let key: DHPK - #if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API + #if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API typealias EncapsulationResult = CryptoKit.KEM.EncapsulationResult #else typealias EncapsulationResult = Crypto.KEM.EncapsulationResult diff --git a/Sources/Crypto/HPKE/Ciphersuite/KEM/Conformances/HPKE-KEM-Curve25519.swift b/Sources/Crypto/HPKE/Ciphersuite/KEM/Conformances/HPKE-KEM-Curve25519.swift index e271956e8..59d78feaf 100644 --- a/Sources/Crypto/HPKE/Ciphersuite/KEM/Conformances/HPKE-KEM-Curve25519.swift +++ b/Sources/Crypto/HPKE/Ciphersuite/KEM/Conformances/HPKE-KEM-Curve25519.swift @@ -14,7 +14,13 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else -import Foundation + +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +public import SwiftSystem +#else +public import Foundation +#endif + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension Curve25519.KeyAgreement.PrivateKey: HPKEDiffieHellmanPrivateKeyGeneration {} diff --git a/Sources/Crypto/HPKE/Ciphersuite/KEM/Conformances/HPKE-NIST-EC-KEMs.swift b/Sources/Crypto/HPKE/Ciphersuite/KEM/Conformances/HPKE-NIST-EC-KEMs.swift index 3a8f2ad14..e7e942b1e 100644 --- a/Sources/Crypto/HPKE/Ciphersuite/KEM/Conformances/HPKE-NIST-EC-KEMs.swift +++ b/Sources/Crypto/HPKE/Ciphersuite/KEM/Conformances/HPKE-NIST-EC-KEMs.swift @@ -14,9 +14,12 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else -import Foundation - +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +public import SwiftSystem +#else +public import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension P256.KeyAgreement.PrivateKey: HPKEDiffieHellmanPrivateKeyGeneration { diff --git a/Sources/Crypto/HPKE/Ciphersuite/KEM/HPKE-KEM.swift b/Sources/Crypto/HPKE/Ciphersuite/KEM/HPKE-KEM.swift index 6cc3f466f..3a0bbc937 100644 --- a/Sources/Crypto/HPKE/Ciphersuite/KEM/HPKE-KEM.swift +++ b/Sources/Crypto/HPKE/Ciphersuite/KEM/HPKE-KEM.swift @@ -14,13 +14,26 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension HPKE { /// The key encapsulation mechanisms to use in HPKE. + /// + /// The module-lattice key encapsulation mechanism (ML-KEM) is designed to offer increased security in situations + /// where an adversary uses a quantum computer. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public enum KEM: CaseIterable, Hashable { + public enum KEM: CaseIterable, Hashable, Sendable { + public static var allCases: [HPKE.KEM] { + var cases = [KEM.P256_HKDF_SHA256, KEM.P384_HKDF_SHA384, KEM.P521_HKDF_SHA512, KEM.Curve25519_HKDF_SHA256] + cases.append(KEM.XWingMLKEM768X25519) + return cases + } + /// A key encapsulation mechanism using NIST P-256 elliptic curve key agreement /// and SHA-2 hashing with a 256-bit digest. case P256_HKDF_SHA256 @@ -33,22 +46,29 @@ extension HPKE { /// A key encapsulation mechanism using X25519 elliptic curve key agreement /// and SHA-2 hashing with a 256-bit digest. case Curve25519_HKDF_SHA256 - - internal var value: UInt16 { + /// A key encapsulation mechanism using the X-Wing (ML-KEM-768 with X25519) key encapsulation mechanism + /// and SHA-2 hashing with a 256-bit digest. + case XWingMLKEM768X25519 + + /// Return the KEM algorithm identifier as defined in section 7.1 of [RFC 9180](https://www.ietf.org/rfc/rfc9180.pdf). + @_spi(HPKEAlgID) + public var value: UInt16 { switch self { - case .P256_HKDF_SHA256: return 0x0010 - case .P384_HKDF_SHA384: return 0x0011 - case .P521_HKDF_SHA512: return 0x0012 - case .Curve25519_HKDF_SHA256: return 0x0020 + case .P256_HKDF_SHA256: return 0x0010 + case .P384_HKDF_SHA384: return 0x0011 + case .P521_HKDF_SHA512: return 0x0012 + case .Curve25519_HKDF_SHA256: return 0x0020 + case .XWingMLKEM768X25519: return 0x647a // https://datatracker.ietf.org/doc/html/draft-connolly-cfrg-xwing-kem-06#name-iana-considerations } } internal var kdf: HPKE.KDF { switch self { - case .P256_HKDF_SHA256: return .HKDF_SHA256 - case .P384_HKDF_SHA384: return .HKDF_SHA384 - case .P521_HKDF_SHA512: return .HKDF_SHA512 - case .Curve25519_HKDF_SHA256: return .HKDF_SHA256 + case .P256_HKDF_SHA256: return .HKDF_SHA256 + case .P384_HKDF_SHA384: return .HKDF_SHA384 + case .P521_HKDF_SHA512: return .HKDF_SHA512 + case .Curve25519_HKDF_SHA256: return .HKDF_SHA256 + case .XWingMLKEM768X25519: return .HKDF_SHA256 } } @@ -58,10 +78,23 @@ extension HPKE { internal var nSecret: UInt16 { switch self { - case .P256_HKDF_SHA256: return 32 - case .P384_HKDF_SHA384: return 48 - case .P521_HKDF_SHA512: return 64 - case .Curve25519_HKDF_SHA256: return 32 + case .P256_HKDF_SHA256: return 32 + case .P384_HKDF_SHA384: return 48 + case .P521_HKDF_SHA512: return 64 + case .Curve25519_HKDF_SHA256: return 32 + case .XWingMLKEM768X25519: return 32 + } + } + + /// Return the size of the encapsulation in bytes + @_spi(HPKEAlgID) + public var nEnc: UInt16 { + switch self { + case .P256_HKDF_SHA256: return 65 + case .P384_HKDF_SHA384: return 97 + case .P521_HKDF_SHA512: return 133 + case .Curve25519_HKDF_SHA256: return 32 + case .XWingMLKEM768X25519: return 1120 } } } diff --git a/Sources/Crypto/HPKE/HPKE-Errors.swift b/Sources/Crypto/HPKE/HPKE-Errors.swift index 21764150b..f94306851 100644 --- a/Sources/Crypto/HPKE/HPKE-Errors.swift +++ b/Sources/Crypto/HPKE/HPKE-Errors.swift @@ -14,7 +14,12 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else + +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension HPKE { diff --git a/Sources/Crypto/HPKE/HPKE.swift b/Sources/Crypto/HPKE/HPKE.swift index 83fe17417..756926988 100644 --- a/Sources/Crypto/HPKE/HPKE.swift +++ b/Sources/Crypto/HPKE/HPKE.swift @@ -14,7 +14,11 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else -import Foundation +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else +public import Foundation +#endif /// A container for hybrid public key encryption (HPKE) operations. /// @@ -46,10 +50,14 @@ import Foundation /// ### Handling errors /// - ``Errors`` @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -public enum HPKE {} +public enum HPKE: Sendable {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension HPKE { + /// Static constant used to store the fixed-string label for the HPKE export API + /// See: https://datatracker.ietf.org/doc/html/rfc9180#name-secret-export + fileprivate static let exportLabel = Data("sec".utf8) + /// A type that represents the sending side of an HPKE message exchange. /// /// To create encrypted messages, initialize a `Sender` specifying the appropriate cipher suite, @@ -59,11 +67,11 @@ extension HPKE { /// same order as the `Sender`, using the same encryption mode, cipher suite, and key schedule information /// (`info`), as well as the `Sender`'s ``encapsulatedKey``. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public struct Sender { + public struct Sender: Sendable { private var context: Context /// The encapsulated symmetric key that the recipient uses to decrypt messages. public let encapsulatedKey: Data - + /// The exporter secret. internal var exporterSecret: SymmetricKey { return context.keySchedule.exporterSecret @@ -77,13 +85,13 @@ extension HPKE { public func exportSecret(context: Context, outputByteCount: Int) throws -> SymmetricKey { precondition(outputByteCount > 0); return LabeledExpand(prk: self.exporterSecret, - label: Data("sec".utf8), + label: exportLabel, info: context, outputByteCount: UInt16(outputByteCount), suiteID: self.context.keySchedule.ciphersuite.identifier, kdf: self.context.keySchedule.ciphersuite.kdf) } - + /// Creates a sender in base mode. /// /// The `Sender` encrypts messages in base mode with a symmetric encryption key it derives using a key derivation function (KDF). @@ -100,7 +108,24 @@ extension HPKE { self.context = try Context(senderRoleWithCiphersuite: ciphersuite, mode: .base, psk: nil, pskID: nil, pkR: recipientKey, info: info) self.encapsulatedKey = context.encapsulated } - + + /// Creates a sender in base mode. + /// + /// The `Sender` encrypts messages in base mode with a symmetric encryption key it derives using a key derivation function (KDF). + /// The KDF uses the key schedule data in `info` as input to generate the key. + /// The `Sender` encapsulates the derived key using the recipient's public key. + /// You access the encapsulated key using ``encapsulatedKey``. + /// + /// - Parameters: + /// - recipientKey: The recipient's public key for encrypting the messages. + /// - ciphersuite: The cipher suite that defines the cryptographic algorithms to use. + /// - info: Data that the key derivation function uses to compute the symmetric key material. The sender and the recipient need to use the same `info` data. + /// - Note: The system throws errors from ``CryptoKit/HPKE/Errors`` when it encounters them. + public init(recipientKey: PK, ciphersuite: Ciphersuite, info: Data) throws { + self.context = try Context(senderRoleWithCiphersuite: ciphersuite, mode: .base, psk: nil, pskID: nil, pkR: recipientKey, info: info) + self.encapsulatedKey = context.encapsulated + } + /// Creates a sender in preshared key (PSK) mode. /// /// The `Sender` encrypts messages in PSK mode using a symmetric encryption key that the sender and recipient both know in advance, in combination with a key it derives using a key derivation function (KDF) and @@ -197,15 +222,15 @@ extension HPKE { /// (`info` data). /// Use a separate `Recipient` instance for each stream of messages. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public struct Recipient { + public struct Recipient: Sendable { private var context: Context - + /// The exporter secret. internal var exporterSecret: SymmetricKey { return context.keySchedule.exporterSecret } - + /// Exports a secret given domain-separation context and the desired output length. /// - Parameters: /// - context: Application-specific information providing context on the use of this key. @@ -214,13 +239,13 @@ extension HPKE { public func exportSecret(context: Context, outputByteCount: Int) throws -> SymmetricKey { precondition(outputByteCount > 0); return LabeledExpand(prk: self.exporterSecret, - label: Data("sec".utf8), + label: exportLabel, info: context, outputByteCount: UInt16(outputByteCount), suiteID: self.context.keySchedule.ciphersuite.identifier, kdf: self.context.keySchedule.ciphersuite.kdf) } - + /// Creates a recipient in base mode. /// /// The `Receiver` decrypts messages in base mode using the encapsulated key with the key schedule information (`info` data). @@ -235,6 +260,20 @@ extension HPKE { self.context = try Context(recipientRoleWithCiphersuite: ciphersuite, mode: .base, enc: encapsulatedKey, psk: nil, pskID: nil, skR: privateKey, info: info, pkS: nil) } + /// Creates a recipient in base mode. + /// + /// The `Receiver` decrypts messages in base mode using the encapsulated key with the key schedule information (`info` data). + /// + /// - Parameters: + /// - privateKey: The recipient's private key for decrypting the incoming messages. + /// - ciphersuite: The cipher suite that defines the cryptographic algorithms to use. + /// - info: Data that the key derivation function uses to compute the symmetric key material. The sender and the recipient need to use the same `info` data. + /// - encapsulatedKey: The encapsulated symmetric key that the sender provides. + /// - Note: The system throws errors from ``CryptoKit/HPKE/Errors`` when it encounters them. + public init(privateKey: SK, ciphersuite: Ciphersuite, info: Data, encapsulatedKey: Data) throws { + self.context = try Context(recipientRoleWithCiphersuite: ciphersuite, mode: .base, enc: encapsulatedKey, psk: nil, pskID: nil, skR: privateKey, info: info, pkS: nil) + } + /// Creates a recipient in preshared key (PSK) mode. /// /// The `Receiver` decrypts messages in PSK mode using the encapsulated key with the key schedule information (`info` data), diff --git a/Sources/Crypto/HPKE/Key Schedule/HPKE-Context.swift b/Sources/Crypto/HPKE/Key Schedule/HPKE-Context.swift index f072a6644..267688503 100644 --- a/Sources/Crypto/HPKE/Key Schedule/HPKE-Context.swift +++ b/Sources/Crypto/HPKE/Key Schedule/HPKE-Context.swift @@ -14,12 +14,17 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else + +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension HPKE { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - struct Context { + struct Context: Sendable { var keySchedule: KeySchedule var encapsulated: Data @@ -31,7 +36,14 @@ extension HPKE { self.keySchedule = try KeySchedule(mode: mode, sharedSecret: encapsulationResult.sharedSecret, info: info, psk: psk, pskID: pskID, ciphersuite: ciphersuite) } - + + init(senderRoleWithCiphersuite ciphersuite: Ciphersuite, mode: Mode, psk: SymmetricKey?, pskID: Data?, pkR: PublicKey, info: Data) throws { + let encapsulationResult = try pkR.encapsulate() + encapsulated = encapsulationResult.encapsulated + self.keySchedule = try KeySchedule(mode: mode, + sharedSecret: encapsulationResult.sharedSecret, info: info, psk: psk, pskID: pskID, ciphersuite: ciphersuite) + } + init(senderRoleWithCiphersuite ciphersuite: Ciphersuite, mode: Mode, psk: SymmetricKey?, pskID: Data?, pkR: SK.PublicKey, info: Data, skS: SK) throws { let skSKEM = try HPKE.DHKEM.PrivateKey(skS, kem: ciphersuite.kem) @@ -47,7 +59,7 @@ extension HPKE { let skRKEM = try HPKE.DHKEM.PrivateKey(skR, kem: ciphersuite.kem) let sharedSecret: SymmetricKey - if let pkS = pkS { + if let pkS { sharedSecret = try skRKEM.decapsulate(enc, authenticating: pkS) } else { sharedSecret = try skRKEM.decapsulate(enc) @@ -57,6 +69,11 @@ extension HPKE { self.keySchedule = try KeySchedule(mode: mode, sharedSecret: sharedSecret, info: info, psk: psk, pskID: pskID, ciphersuite: ciphersuite) } + init(recipientRoleWithCiphersuite ciphersuite: Ciphersuite, mode: Mode, enc: Data, psk: SymmetricKey?, pskID: Data?, skR: PrivateKey, info: Data, pkS: PrivateKey.PublicKey?) throws { + let sharedSecret = try skR.decapsulate(enc) + self.encapsulated = enc + self.keySchedule = try KeySchedule(mode: mode, sharedSecret: sharedSecret, info: info, psk: psk, pskID: pskID, ciphersuite: ciphersuite) + } } } diff --git a/Sources/Crypto/HPKE/Key Schedule/HPKE-KeySchedule.swift b/Sources/Crypto/HPKE/Key Schedule/HPKE-KeySchedule.swift index 72e22da9e..a45a7b40f 100644 --- a/Sources/Crypto/HPKE/Key Schedule/HPKE-KeySchedule.swift +++ b/Sources/Crypto/HPKE/Key Schedule/HPKE-KeySchedule.swift @@ -14,12 +14,17 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else + +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension HPKE { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - internal struct KeySchedule { + internal struct KeySchedule: Sendable { fileprivate static let pksIDHashLabel = Data("psk_id_hash".utf8) fileprivate static let infoHashLabel = Data("info_hash".utf8) fileprivate static let secretLabel = Data("secret".utf8) @@ -103,8 +108,19 @@ extension HPKE { self.ciphersuite = ciphersuite } + var maxSequenceNumber: UInt64 { + get { + let nonceBitCount = UInt64(self.ciphersuite.aead.nonceByteCount * 8) + if (nonceBitCount >= 64) { + return UInt64.max + } + + return ((UInt64(1) << nonceBitCount) - 1) + } + } + mutating func incrementSequenceNumber() throws { - if self.sequenceNumber >= ((1 << (self.ciphersuite.aead.nonceByteCount)) - 1) { + if self.sequenceNumber >= maxSequenceNumber { throw HPKE.Errors.outOfRangeSequenceNumber } sequenceNumber += 1 diff --git a/Sources/Crypto/Insecure/Insecure.swift b/Sources/Crypto/Insecure/Insecure.swift index 19adb1f26..da38f7c8f 100644 --- a/Sources/Crypto/Insecure/Insecure.swift +++ b/Sources/Crypto/Insecure/Insecure.swift @@ -20,5 +20,5 @@ /// but the framework provides them for backward compatibility with older /// services that require them. For new services, avoid these algorithms. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -public enum Insecure {} +public enum Insecure: Sendable {} #endif // Linux or !SwiftPM diff --git a/Sources/Crypto/Insecure/Insecure_HashFunctions.swift b/Sources/Crypto/Insecure/Insecure_HashFunctions.swift index a82e5330b..6d12e6a34 100644 --- a/Sources/Crypto/Insecure/Insecure_HashFunctions.swift +++ b/Sources/Crypto/Insecure/Insecure_HashFunctions.swift @@ -33,21 +33,13 @@ extension Insecure { /// that require it. For new services, prefer one of the secure hashes, like /// ``SHA512``. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public struct SHA1: HashFunctionImplementationDetails { + public struct SHA1: HashFunctionImplementationDetails, Sendable { /// The number of bytes that represents the hash function’s internal /// state. - public static var blockByteCount: Int { - get { 64 } - - set { fatalError("Cannot set SHA1.blockByteCount") } - } + public static let blockByteCount: Int = 64 /// The number of bytes in a SHA1 digest. - public static var byteCount: Int { - get { 20 } - - set { fatalError("Cannot set SHA1.byteCount") } - } + public static let byteCount: Int = 20 /// The digest type for a SHA1 hash function. public typealias Digest = Insecure.SHA1Digest @@ -122,20 +114,12 @@ extension Insecure { /// that require it. For new services, prefer one of the secure hashes, like /// ``SHA512``. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public struct MD5: HashFunctionImplementationDetails { + public struct MD5: HashFunctionImplementationDetails, Sendable { /// The number of bytes that represents the hash function’s internal /// state. - public static var blockByteCount: Int { - get { 64 } - - set { fatalError("Cannot set MD5.blockByteCount") } - } + public static let blockByteCount: Int = 64 /// The number of bytes in an MD5 digest. - public static var byteCount: Int { - get { 16 } - - set { fatalError("Cannot set MD5.byteCount") } - } + public static let byteCount: Int = 16 /// The digest type for a MD5 hash function. public typealias Digest = Insecure.MD5Digest diff --git a/Sources/_CryptoExtras/MLKEM/MLKEM_boring.swift b/Sources/Crypto/KEM/BoringSSL/MLKEM_boring.swift similarity index 85% rename from Sources/_CryptoExtras/MLKEM/MLKEM_boring.swift rename to Sources/Crypto/KEM/BoringSSL/MLKEM_boring.swift index 28d19733b..035478808 100644 --- a/Sources/_CryptoExtras/MLKEM/MLKEM_boring.swift +++ b/Sources/Crypto/KEM/BoringSSL/MLKEM_boring.swift @@ -2,7 +2,7 @@ // // This source file is part of the SwiftCrypto open source project // -// Copyright (c) 2024 Apple Inc. and the SwiftCrypto project authors +// Copyright (c) 2024-2025 Apple Inc. and the SwiftCrypto project authors // Licensed under Apache License v2.0 // // See LICENSE.txt for license information @@ -16,29 +16,27 @@ // any edits of this file WILL be overwritten and thus discarded // see section `gyb` in `README` for details. +#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +@_exported import CryptoKit +#else @_implementationOnly import CCryptoBoringSSL -import Crypto import Foundation -/// A module-lattice-based key encapsulation mechanism that provides security against quantum computing attacks. -@available(macOS 14.0, iOS 17, watchOS 10, tvOS 17, macCatalyst 17, visionOS 1.0, *) -public enum MLKEM768 {} - -@available(macOS 14.0, iOS 17, watchOS 10, tvOS 17, macCatalyst 17, visionOS 1.0, *) +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLKEM768 { /// A ML-KEM-768 private key. - public struct PrivateKey: Sendable, KEMPrivateKey { + struct InternalPrivateKey: Sendable, KEMPrivateKey { private var backing: Backing /// Initialize a ML-KEM-768 private key from a random seed. - public init() { + init() { self.backing = Backing() } /// Generate a ML-KEM-768 private key from a random seed. /// /// - Returns: The generated private key. - public static func generate() -> MLKEM768.PrivateKey { + static func generate() -> MLKEM768.InternalPrivateKey { .init() } @@ -47,17 +45,17 @@ extension MLKEM768 { /// - Parameter seedRepresentation: The seed to use to generate the private key. /// /// - Throws: `CryptoKitError.incorrectKeySize` if the seed is not 64 bytes long. - public init(seedRepresentation: some DataProtocol) throws { + init(seedRepresentation: some DataProtocol) throws { self.backing = try Backing(seedRepresentation: seedRepresentation) } /// The seed from which this private key was generated. - public var seedRepresentation: Data { + var seedRepresentation: Data { self.backing.seed } /// The public key associated with this private key. - public var publicKey: PublicKey { + var publicKey: InternalPublicKey { self.backing.publicKey } @@ -68,7 +66,7 @@ extension MLKEM768 { /// - Throws: `CryptoKitError.incorrectParameterSize` if the encapsulated shared secret is not 1088 bytes long. /// /// - Returns: The symmetric key. - public func decapsulate(_ encapsulated: some DataProtocol) throws -> SymmetricKey { + func decapsulate(_ encapsulated: some DataProtocol) throws -> SymmetricKey { try self.backing.decapsulate(encapsulated) } @@ -87,7 +85,7 @@ extension MLKEM768 { ) { seedPtr in withUnsafeTemporaryAllocation( of: UInt8.self, - capacity: MLKEM768.PublicKey.byteCount + capacity: MLKEM768.InternalPublicKey.byteCount ) { publicKeyPtr in CCryptoBoringSSL_MLKEM768_generate_key( publicKeyPtr.baseAddress, @@ -127,8 +125,8 @@ extension MLKEM768 { } /// The public key associated with this private key. - var publicKey: PublicKey { - PublicKey(privateKeyBacking: self) + var publicKey: InternalPublicKey { + InternalPublicKey(privateKeyBacking: self) } /// Decapsulate a shared secret and create a symmetric key. @@ -170,13 +168,13 @@ extension MLKEM768 { } } -@available(macOS 14.0, iOS 17, watchOS 10, tvOS 17, macCatalyst 17, visionOS 1.0, *) +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLKEM768 { /// A ML-KEM-768 public key. - public struct PublicKey: Sendable, KEMPublicKey { + struct InternalPublicKey: Sendable, KEMPublicKey { private var backing: Backing - fileprivate init(privateKeyBacking: PrivateKey.Backing) { + fileprivate init(privateKeyBacking: InternalPrivateKey.Backing) { self.backing = Backing(privateKeyBacking: privateKeyBacking) } @@ -185,19 +183,19 @@ extension MLKEM768 { /// - Parameter rawRepresentation: The public key bytes. /// /// - Throws: `CryptoKitError.incorrectKeySize` if the raw representation is not the correct size. - public init(rawRepresentation: some DataProtocol) throws { + init(rawRepresentation: some DataProtocol) throws { self.backing = try Backing(rawRepresentation: rawRepresentation) } /// The raw binary representation of the public key. - public var rawRepresentation: Data { + var rawRepresentation: Data { self.backing.rawRepresentation } /// Encapsulate a shared secret. /// /// - Returns: The shared secret and its encapsulated version. - public func encapsulate() -> KEM.EncapsulationResult { + func encapsulate() -> KEM.EncapsulationResult { self.backing.encapsulate() } @@ -207,7 +205,7 @@ extension MLKEM768 { fileprivate final class Backing { var key: MLKEM768_public_key - init(privateKeyBacking: PrivateKey.Backing) { + init(privateKeyBacking: InternalPrivateKey.Backing) { self.key = .init() CCryptoBoringSSL_MLKEM768_public_from_private(&self.key, &privateKeyBacking.key) } @@ -218,7 +216,7 @@ extension MLKEM768 { /// /// - Throws: `CryptoKitError.incorrectKeySize` if the raw representation is not the correct size. init(rawRepresentation: some DataProtocol) throws { - guard rawRepresentation.count == MLKEM768.PublicKey.byteCount else { + guard rawRepresentation.count == MLKEM768.InternalPublicKey.byteCount else { throw CryptoKitError.incorrectKeySize } @@ -242,7 +240,7 @@ extension MLKEM768 { var rawRepresentation: Data { var cbb = CBB() // The following BoringSSL functions can only fail on allocation failure, which we define as impossible. - CCryptoBoringSSL_CBB_init(&cbb, MLKEM768.PublicKey.Backing.byteCount) + CCryptoBoringSSL_CBB_init(&cbb, MLKEM768.InternalPublicKey.Backing.byteCount) defer { CCryptoBoringSSL_CBB_cleanup(&cbb) } CCryptoBoringSSL_MLKEM768_marshal_public_key(&cbb, &self.key) return Data(bytes: CCryptoBoringSSL_CBB_data(&cbb), count: CCryptoBoringSSL_CBB_len(&cbb)) @@ -285,31 +283,27 @@ extension MLKEM768 { } } -@available(macOS 14.0, iOS 17, watchOS 10, tvOS 17, macCatalyst 17, visionOS 1.0, *) +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLKEM768 { /// The size of the encapsulated shared secret in bytes. private static let ciphertextByteCount = Int(MLKEM768_CIPHERTEXT_BYTES) } -/// A module-lattice-based key encapsulation mechanism that provides security against quantum computing attacks. -@available(macOS 14.0, iOS 17, watchOS 10, tvOS 17, macCatalyst 17, visionOS 1.0, *) -public enum MLKEM1024 {} - -@available(macOS 14.0, iOS 17, watchOS 10, tvOS 17, macCatalyst 17, visionOS 1.0, *) +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLKEM1024 { /// A ML-KEM-1024 private key. - public struct PrivateKey: Sendable, KEMPrivateKey { + struct InternalPrivateKey: Sendable, KEMPrivateKey { private var backing: Backing /// Initialize a ML-KEM-1024 private key from a random seed. - public init() { + init() { self.backing = Backing() } /// Generate a ML-KEM-1024 private key from a random seed. /// /// - Returns: The generated private key. - public static func generate() -> MLKEM1024.PrivateKey { + static func generate() -> MLKEM1024.InternalPrivateKey { .init() } @@ -318,17 +312,17 @@ extension MLKEM1024 { /// - Parameter seedRepresentation: The seed to use to generate the private key. /// /// - Throws: `CryptoKitError.incorrectKeySize` if the seed is not 64 bytes long. - public init(seedRepresentation: some DataProtocol) throws { + init(seedRepresentation: some DataProtocol) throws { self.backing = try Backing(seedRepresentation: seedRepresentation) } /// The seed from which this private key was generated. - public var seedRepresentation: Data { + var seedRepresentation: Data { self.backing.seed } /// The public key associated with this private key. - public var publicKey: PublicKey { + var publicKey: InternalPublicKey { self.backing.publicKey } @@ -339,7 +333,7 @@ extension MLKEM1024 { /// - Throws: `CryptoKitError.incorrectParameterSize` if the encapsulated shared secret is not 1088 bytes long. /// /// - Returns: The symmetric key. - public func decapsulate(_ encapsulated: some DataProtocol) throws -> SymmetricKey { + func decapsulate(_ encapsulated: some DataProtocol) throws -> SymmetricKey { try self.backing.decapsulate(encapsulated) } @@ -358,7 +352,7 @@ extension MLKEM1024 { ) { seedPtr in withUnsafeTemporaryAllocation( of: UInt8.self, - capacity: MLKEM1024.PublicKey.byteCount + capacity: MLKEM1024.InternalPublicKey.byteCount ) { publicKeyPtr in CCryptoBoringSSL_MLKEM1024_generate_key( publicKeyPtr.baseAddress, @@ -398,8 +392,8 @@ extension MLKEM1024 { } /// The public key associated with this private key. - var publicKey: PublicKey { - PublicKey(privateKeyBacking: self) + var publicKey: InternalPublicKey { + InternalPublicKey(privateKeyBacking: self) } /// Decapsulate a shared secret and create a symmetric key. @@ -441,13 +435,13 @@ extension MLKEM1024 { } } -@available(macOS 14.0, iOS 17, watchOS 10, tvOS 17, macCatalyst 17, visionOS 1.0, *) +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLKEM1024 { /// A ML-KEM-1024 public key. - public struct PublicKey: Sendable, KEMPublicKey { + struct InternalPublicKey: Sendable, KEMPublicKey { private var backing: Backing - fileprivate init(privateKeyBacking: PrivateKey.Backing) { + fileprivate init(privateKeyBacking: InternalPrivateKey.Backing) { self.backing = Backing(privateKeyBacking: privateKeyBacking) } @@ -456,19 +450,19 @@ extension MLKEM1024 { /// - Parameter rawRepresentation: The public key bytes. /// /// - Throws: `CryptoKitError.incorrectKeySize` if the raw representation is not the correct size. - public init(rawRepresentation: some DataProtocol) throws { + init(rawRepresentation: some DataProtocol) throws { self.backing = try Backing(rawRepresentation: rawRepresentation) } /// The raw binary representation of the public key. - public var rawRepresentation: Data { + var rawRepresentation: Data { self.backing.rawRepresentation } /// Encapsulate a shared secret. /// /// - Returns: The shared secret and its encapsulated version. - public func encapsulate() -> KEM.EncapsulationResult { + func encapsulate() -> KEM.EncapsulationResult { self.backing.encapsulate() } @@ -478,7 +472,7 @@ extension MLKEM1024 { fileprivate final class Backing { var key: MLKEM1024_public_key - init(privateKeyBacking: PrivateKey.Backing) { + init(privateKeyBacking: InternalPrivateKey.Backing) { self.key = .init() CCryptoBoringSSL_MLKEM1024_public_from_private(&self.key, &privateKeyBacking.key) } @@ -489,7 +483,7 @@ extension MLKEM1024 { /// /// - Throws: `CryptoKitError.incorrectKeySize` if the raw representation is not the correct size. init(rawRepresentation: some DataProtocol) throws { - guard rawRepresentation.count == MLKEM1024.PublicKey.byteCount else { + guard rawRepresentation.count == MLKEM1024.InternalPublicKey.byteCount else { throw CryptoKitError.incorrectKeySize } @@ -513,7 +507,7 @@ extension MLKEM1024 { var rawRepresentation: Data { var cbb = CBB() // The following BoringSSL functions can only fail on allocation failure, which we define as impossible. - CCryptoBoringSSL_CBB_init(&cbb, MLKEM1024.PublicKey.Backing.byteCount) + CCryptoBoringSSL_CBB_init(&cbb, MLKEM1024.InternalPublicKey.Backing.byteCount) defer { CCryptoBoringSSL_CBB_cleanup(&cbb) } CCryptoBoringSSL_MLKEM1024_marshal_public_key(&cbb, &self.key) return Data(bytes: CCryptoBoringSSL_CBB_data(&cbb), count: CCryptoBoringSSL_CBB_len(&cbb)) @@ -556,16 +550,18 @@ extension MLKEM1024 { } } -@available(macOS 14.0, iOS 17, watchOS 10, tvOS 17, macCatalyst 17, visionOS 1.0, *) +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLKEM1024 { /// The size of the encapsulated shared secret in bytes. private static let ciphertextByteCount = Int(MLKEM1024_CIPHERTEXT_BYTES) } -private enum MLKEM { +enum MLKEM { /// The size of the seed in bytes. - fileprivate static let seedByteCount = 64 + static let seedByteCount = 64 // The size of the shared secret in bytes. - fileprivate static let sharedSecretByteCount = 32 + static let sharedSecretByteCount = 32 } + +#endif // CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API diff --git a/Sources/_CryptoExtras/MLKEM/MLKEM_boring.swift.gyb b/Sources/Crypto/KEM/BoringSSL/MLKEM_boring.swift.gyb similarity index 85% rename from Sources/_CryptoExtras/MLKEM/MLKEM_boring.swift.gyb rename to Sources/Crypto/KEM/BoringSSL/MLKEM_boring.swift.gyb index cfe11c73b..a4b056e01 100644 --- a/Sources/_CryptoExtras/MLKEM/MLKEM_boring.swift.gyb +++ b/Sources/Crypto/KEM/BoringSSL/MLKEM_boring.swift.gyb @@ -2,7 +2,7 @@ // // This source file is part of the SwiftCrypto open source project // -// Copyright (c) 2024 Apple Inc. and the SwiftCrypto project authors +// Copyright (c) 2024-2025 Apple Inc. and the SwiftCrypto project authors // Licensed under Apache License v2.0 // // See LICENSE.txt for license information @@ -16,33 +16,31 @@ // any edits of this file WILL be overwritten and thus discarded // see section `gyb` in `README` for details. +#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +@_exported import CryptoKit +#else @_implementationOnly import CCryptoBoringSSL -import Crypto import Foundation %{ parameter_sets = ["768", "1024"] }% % for parameter_set in parameter_sets: -/// A module-lattice-based key encapsulation mechanism that provides security against quantum computing attacks. -@available(macOS 14.0, iOS 17, watchOS 10, tvOS 17, macCatalyst 17, visionOS 1.0, *) -public enum MLKEM${parameter_set} {} - -@available(macOS 14.0, iOS 17, watchOS 10, tvOS 17, macCatalyst 17, visionOS 1.0, *) +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLKEM${parameter_set} { /// A ML-KEM-${parameter_set} private key. - public struct PrivateKey: Sendable, KEMPrivateKey { + struct InternalPrivateKey: Sendable, KEMPrivateKey { private var backing: Backing /// Initialize a ML-KEM-${parameter_set} private key from a random seed. - public init() { + init() { self.backing = Backing() } /// Generate a ML-KEM-${parameter_set} private key from a random seed. /// /// - Returns: The generated private key. - public static func generate() -> MLKEM${parameter_set}.PrivateKey { + static func generate() -> MLKEM${parameter_set}.InternalPrivateKey { .init() } @@ -51,17 +49,17 @@ extension MLKEM${parameter_set} { /// - Parameter seedRepresentation: The seed to use to generate the private key. /// /// - Throws: `CryptoKitError.incorrectKeySize` if the seed is not 64 bytes long. - public init(seedRepresentation: some DataProtocol) throws { + init(seedRepresentation: some DataProtocol) throws { self.backing = try Backing(seedRepresentation: seedRepresentation) } /// The seed from which this private key was generated. - public var seedRepresentation: Data { + var seedRepresentation: Data { self.backing.seed } /// The public key associated with this private key. - public var publicKey: PublicKey { + var publicKey: InternalPublicKey { self.backing.publicKey } @@ -72,7 +70,7 @@ extension MLKEM${parameter_set} { /// - Throws: `CryptoKitError.incorrectParameterSize` if the encapsulated shared secret is not 1088 bytes long. /// /// - Returns: The symmetric key. - public func decapsulate(_ encapsulated: some DataProtocol) throws -> SymmetricKey { + func decapsulate(_ encapsulated: some DataProtocol) throws -> SymmetricKey { try self.backing.decapsulate(encapsulated) } @@ -91,7 +89,7 @@ extension MLKEM${parameter_set} { ) { seedPtr in withUnsafeTemporaryAllocation( of: UInt8.self, - capacity: MLKEM${parameter_set}.PublicKey.byteCount + capacity: MLKEM${parameter_set}.InternalPublicKey.byteCount ) { publicKeyPtr in CCryptoBoringSSL_MLKEM${parameter_set}_generate_key( publicKeyPtr.baseAddress, @@ -131,8 +129,8 @@ extension MLKEM${parameter_set} { } /// The public key associated with this private key. - var publicKey: PublicKey { - PublicKey(privateKeyBacking: self) + var publicKey: InternalPublicKey { + InternalPublicKey(privateKeyBacking: self) } /// Decapsulate a shared secret and create a symmetric key. @@ -174,13 +172,13 @@ extension MLKEM${parameter_set} { } } -@available(macOS 14.0, iOS 17, watchOS 10, tvOS 17, macCatalyst 17, visionOS 1.0, *) +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLKEM${parameter_set} { /// A ML-KEM-${parameter_set} public key. - public struct PublicKey: Sendable, KEMPublicKey { + struct InternalPublicKey: Sendable, KEMPublicKey { private var backing: Backing - fileprivate init(privateKeyBacking: PrivateKey.Backing) { + fileprivate init(privateKeyBacking: InternalPrivateKey.Backing) { self.backing = Backing(privateKeyBacking: privateKeyBacking) } @@ -189,29 +187,36 @@ extension MLKEM${parameter_set} { /// - Parameter rawRepresentation: The public key bytes. /// /// - Throws: `CryptoKitError.incorrectKeySize` if the raw representation is not the correct size. - public init(rawRepresentation: some DataProtocol) throws { + init(rawRepresentation: some DataProtocol) throws { self.backing = try Backing(rawRepresentation: rawRepresentation) } /// The raw binary representation of the public key. - public var rawRepresentation: Data { + var rawRepresentation: Data { self.backing.rawRepresentation } /// Encapsulate a shared secret. /// /// - Returns: The shared secret and its encapsulated version. - public func encapsulate() -> KEM.EncapsulationResult { + func encapsulate() -> KEM.EncapsulationResult { self.backing.encapsulate() } + /// Encapsulate a shared secret using a fixed RNG result. + /// + /// - Returns: The shared secret and its encapsulated version. + func encapsulateWithSeed(_ encapWithSeed: Data) -> KEM.EncapsulationResult { + self.backing.encapsulate(encapWithSeed) + } + /// The size of the public key in bytes. static let byteCount = Backing.byteCount fileprivate final class Backing { var key: MLKEM${parameter_set}_public_key - init(privateKeyBacking: PrivateKey.Backing) { + init(privateKeyBacking: InternalPrivateKey.Backing) { self.key = .init() CCryptoBoringSSL_MLKEM${parameter_set}_public_from_private(&self.key, &privateKeyBacking.key) } @@ -222,7 +227,7 @@ extension MLKEM${parameter_set} { /// /// - Throws: `CryptoKitError.incorrectKeySize` if the raw representation is not the correct size. init(rawRepresentation: some DataProtocol) throws { - guard rawRepresentation.count == MLKEM${parameter_set}.PublicKey.byteCount else { + guard rawRepresentation.count == MLKEM${parameter_set}.InternalPublicKey.byteCount else { throw CryptoKitError.incorrectKeySize } @@ -246,7 +251,7 @@ extension MLKEM${parameter_set} { var rawRepresentation: Data { var cbb = CBB() // The following BoringSSL functions can only fail on allocation failure, which we define as impossible. - CCryptoBoringSSL_CBB_init(&cbb, MLKEM${parameter_set}.PublicKey.Backing.byteCount) + CCryptoBoringSSL_CBB_init(&cbb, MLKEM${parameter_set}.InternalPublicKey.Backing.byteCount) defer { CCryptoBoringSSL_CBB_cleanup(&cbb) } CCryptoBoringSSL_MLKEM${parameter_set}_marshal_public_key(&cbb, &self.key) return Data(bytes: CCryptoBoringSSL_CBB_data(&cbb), count: CCryptoBoringSSL_CBB_len(&cbb)) @@ -289,17 +294,19 @@ extension MLKEM${parameter_set} { } } -@available(macOS 14.0, iOS 17, watchOS 10, tvOS 17, macCatalyst 17, visionOS 1.0, *) +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLKEM${parameter_set} { /// The size of the encapsulated shared secret in bytes. private static let ciphertextByteCount = Int(MLKEM${parameter_set}_CIPHERTEXT_BYTES) } % end -private enum MLKEM { +enum MLKEM { /// The size of the seed in bytes. - fileprivate static let seedByteCount = 64 + static let seedByteCount = 64 // The size of the shared secret in bytes. - fileprivate static let sharedSecretByteCount = 32 + static let sharedSecretByteCount = 32 } + +#endif // CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API diff --git a/Sources/Crypto/KEM/BoringSSL/MLKEM_wrapper.swift b/Sources/Crypto/KEM/BoringSSL/MLKEM_wrapper.swift new file mode 100644 index 000000000..fbb84921e --- /dev/null +++ b/Sources/Crypto/KEM/BoringSSL/MLKEM_wrapper.swift @@ -0,0 +1,269 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2025 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +@_exported import CryptoKit +#else +@_implementationOnly import CCryptoBoringSSL +import Foundation + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +protocol BoringSSLBackedMLKEMPrivateKey { + associatedtype InteriorPublicKey: BoringSSLBackedMLKEMPublicKey + + static func generatePrivateKey() throws -> Self + + static func generateWithSeed(_ seed: Data) throws -> Self + + init(seedRepresentation: Bytes, publicKeyRawRepresentation: Data?) throws + + init(seedRepresentation: Bytes, publicKeyHash: SHA3_256Digest?) throws + + var seedRepresentation: Data { get } + + func decapsulate(_ encapsulated: Bytes) throws -> SymmetricKey + + var interiorPublicKey: InteriorPublicKey { get } + + var integrityCheckedRepresentation: Data { get } +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension BoringSSLBackedMLKEMPrivateKey { + func decapsulate(encapsulated: Bytes) throws -> SymmetricKey { + try self.decapsulate(encapsulated) + } +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +protocol BoringSSLBackedMLKEMPublicKey { + init(rawRepresentation: Bytes) throws + + var rawRepresentation: Data { get } + + func encapsulate() throws -> KEM.EncapsulationResult + + func encapsulateWithSeed(_ encapSeed: Data) throws -> KEM.EncapsulationResult +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +protocol BoringSSLBackedMLKEMOuterPublicKey { + init(rawRepresentation: Data) throws +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +protocol BoringSSLBackedMLKEMParameters { + associatedtype BackingPrivateKey: BoringSSLBackedMLKEMPrivateKey + where BackingPrivateKey.InteriorPublicKey == BackingPublicKey + associatedtype BackingPublicKey: BoringSSLBackedMLKEMPublicKey + associatedtype PublicKey: BoringSSLBackedMLKEMOuterPublicKey +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension MLKEM768: BoringSSLBackedMLKEMParameters { + typealias BackingPrivateKey = MLKEM768.InternalPrivateKey + typealias BackingPublicKey = MLKEM768.InternalPublicKey +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension MLKEM768.PublicKey: BoringSSLBackedMLKEMOuterPublicKey {} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension MLKEM768.InternalPrivateKey: BoringSSLBackedMLKEMPrivateKey { + static func generatePrivateKey() throws -> Self { + .generate() + } + + static func generateWithSeed(_ seed: Data) throws -> Self { + let seed = Array(seed) + var fullSeed: [UInt8] = [] + fullSeed.reserveCapacity(MLKEM.seedByteCount) + + for i in 0..(seedRepresentation: Bytes, publicKeyRawRepresentation: Data?) throws where Bytes: DataProtocol { + precondition(publicKeyRawRepresentation == nil) + self = try .init(seedRepresentation: seedRepresentation) + } + + init(seedRepresentation: Bytes, publicKeyHash: SHA3_256Digest?) throws { + precondition(publicKeyHash == nil) + self = try .init(seedRepresentation: seedRepresentation) + } + + var integrityCheckedRepresentation: Data { + fatalError() + } + + var interiorPublicKey: MLKEM768.InternalPublicKey { + self.publicKey + } +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension MLKEM768.InternalPublicKey: BoringSSLBackedMLKEMPublicKey { + func encapsulateWithSeed(_ encapSeed: Data) throws -> KEM.EncapsulationResult { + fatalError() + } +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension MLKEM1024: BoringSSLBackedMLKEMParameters { + typealias BackingPrivateKey = MLKEM1024.InternalPrivateKey + typealias BackingPublicKey = MLKEM1024.InternalPublicKey +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension MLKEM1024.PublicKey: BoringSSLBackedMLKEMOuterPublicKey {} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension MLKEM1024.InternalPrivateKey: BoringSSLBackedMLKEMPrivateKey { + static func generatePrivateKey() throws -> Self { + .generate() + } + + static func generateWithSeed(_ seed: Data) throws -> Self { + let seed = Array(seed) + var fullSeed: [UInt8] = [] + fullSeed.reserveCapacity(MLKEM.seedByteCount) + + for i in 0..(seedRepresentation: Bytes, publicKeyRawRepresentation: Data?) throws where Bytes: DataProtocol { + precondition(publicKeyRawRepresentation == nil) + self = try .init(seedRepresentation: seedRepresentation) + } + + init(seedRepresentation: Bytes, publicKeyHash: SHA3_256Digest?) throws { + precondition(publicKeyHash == nil) + self = try .init(seedRepresentation: seedRepresentation) + } + + var integrityCheckedRepresentation: Data { + fatalError() + } + + var interiorPublicKey: MLKEM1024.InternalPublicKey { + self.publicKey + } +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension MLKEM1024.InternalPublicKey: BoringSSLBackedMLKEMPublicKey { + func encapsulateWithSeed(_ encapSeed: Data) throws -> KEM.EncapsulationResult { + fatalError() + } +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +struct OpenSSLMLKEMPublicKeyImpl: BoringSSLBackedMLKEMPublicKey { + private var backing: Parameters.BackingPublicKey + + init(backing: Parameters.BackingPublicKey) { + self.backing = backing + } + + init(rawRepresentation: Bytes) throws where Bytes: DataProtocol { + self.backing = try .init(rawRepresentation: rawRepresentation) + } + + var rawRepresentation: Data { + self.backing.rawRepresentation + } + + func encapsulate() throws -> KEM.EncapsulationResult { + try self.backing.encapsulate() + } + + func encapsulateWithSeed(_ encapSeed: Data) throws -> KEM.EncapsulationResult { + try self.backing.encapsulateWithSeed(encapSeed) + } +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +struct OpenSSLMLKEMPrivateKeyImpl: BoringSSLBackedMLKEMPrivateKey { + typealias InteriorPublicKey = OpenSSLMLKEMPublicKeyImpl + + private var backing: Parameters.BackingPrivateKey + + init(backing: Parameters.BackingPrivateKey) { + self.backing = backing + } + + static func generatePrivateKey() throws -> Self { + try Self(backing: .generatePrivateKey()) + } + + static func generateWithSeed(_ seed: Data) throws -> Self { + try Self(backing: .generateWithSeed(seed)) + } + + init( + seedRepresentation: Bytes, + publicKeyRawRepresentation: Data? + ) throws { + self.backing = try .init( + seedRepresentation: seedRepresentation, + publicKeyRawRepresentation: publicKeyRawRepresentation + ) + } + + init( + seedRepresentation: Bytes, + publicKeyHash: SHA3_256Digest? + ) throws { + self.backing = try .init( + seedRepresentation: seedRepresentation, + publicKeyHash: publicKeyHash + ) + } + + var seedRepresentation: Data { + self.backing.seedRepresentation + } + + func decapsulate(_ encapsulated: Bytes) throws -> SymmetricKey where Bytes: DataProtocol { + try self.backing.decapsulate(encapsulated) + } + + var interiorPublicKey: InteriorPublicKey { + .init(backing: self.backing.interiorPublicKey) + } + + var publicKey: Parameters.PublicKey { + get { + try! .init(rawRepresentation: self.interiorPublicKey.rawRepresentation) + } + } + + var integrityCheckedRepresentation: Data { + self.backing.integrityCheckedRepresentation + } + + static var seedSize: Int { + MLKEM.seedByteCount + } +} + +#endif // CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API diff --git a/Sources/Crypto/KEM/BoringSSL/XWing_boring.swift b/Sources/Crypto/KEM/BoringSSL/XWing_boring.swift new file mode 100644 index 000000000..9a6a7f600 --- /dev/null +++ b/Sources/Crypto/KEM/BoringSSL/XWing_boring.swift @@ -0,0 +1,236 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2019-2020 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +@_exported import CryptoKit +#else +@_implementationOnly import CCryptoBoringSSL +import Foundation + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +struct OpenSSLXWingPublicKeyImpl: Sendable { + private var publicKeyBytes: Data + + fileprivate init(publicKeyBytes: Data) { + self.publicKeyBytes = publicKeyBytes + } + + init(dataRepresentation: D) throws { + self.publicKeyBytes = try dataRepresentation.withUnsafeBytes { + guard $0.count == XWING_PUBLIC_KEY_BYTES else { + throw CryptoKitError.incorrectKeySize + } + return Data($0) + } + } + + var rawRepresentation: Data { + self.publicKeyBytes + } + + func encapsulate() throws -> KEM.EncapsulationResult { + try self.encapsulateWithOptionalEntropy(entropy: nil) + } + + func encapsulateWithOptionalEntropy(entropy: [UInt8]?) throws -> KEM.EncapsulationResult { + let (sharedSecret, encapsulatedSecret) = try self.publicKeyBytes.withUnsafeBytes { publicKeyBuffer in + try withUnsafeTemporaryAllocation(byteCount: Int(XWING_CIPHERTEXT_BYTES), alignment: 1) { + ciphertextBuffer in + let sharedSecret = try SymmetricKey(unsafeUninitializedCapacity: Int(XWING_SHARED_SECRET_BYTES)) { + sharedSecretBuffer, + count in + let rc: CInt + + if let entropy { + rc = CCryptoBoringSSL_XWING_encap_external_entropy( + ciphertextBuffer.baseAddress, + sharedSecretBuffer.baseAddress, + publicKeyBuffer.baseAddress, + entropy + ) + } else { + rc = CCryptoBoringSSL_XWING_encap( + ciphertextBuffer.baseAddress, + sharedSecretBuffer.baseAddress, + publicKeyBuffer.baseAddress + ) + } + guard rc == 1 else { + throw CryptoKitError.internalBoringSSLError() + } + count = Int(XWING_SHARED_SECRET_BYTES) + } + let encapsulatedSecret = Data(ciphertextBuffer) + return (sharedSecret, encapsulatedSecret) + } + } + + return .init(sharedSecret: sharedSecret, encapsulated: encapsulatedSecret) + } +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +struct OpenSSLXWingPrivateKeyImpl: Sendable { + private var backing: Backing + + var seedRepresentation: Data { + self.backing.seedRepresentation + } + + var integrityCheckedRepresentation: Data { + self.backing.integrityCheckedRepresentation + } + + init(bytes: D) throws { + self.backing = try .init(bytes: bytes) + } + + init(seedRepresentation: D, publicKeyHash: SHA3_256Digest?) throws { + self.backing = try .init(seedRepresentation: seedRepresentation, publicKeyHash: publicKeyHash) + } + + private init(_ backing: Backing) { + self.backing = backing + } + + var dataRepresentation: Data { + self.backing.dataRepresentation + } + + static func generate() throws -> Self { + try Self(.generate()) + } + + func decapsulate(_ encapsulated: Data) throws -> SymmetricKey { + try self.backing.decapsulate(encapsulated) + } + + var publicKey: OpenSSLXWingPublicKeyImpl { + OpenSSLXWingPublicKeyImpl(publicKeyBytes: self.backing.publicKey) + } +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension OpenSSLXWingPrivateKeyImpl { + final class Backing: @unchecked Sendable { + private var privateKey: XWING_private_key + + init(privateKey: XWING_private_key) { + self.privateKey = privateKey + } + + init() throws { + self.privateKey = .init() + try withUnsafeTemporaryAllocation(byteCount: Int(XWING_PUBLIC_KEY_BYTES), alignment: 1) { + let rc = CCryptoBoringSSL_XWING_generate_key($0.baseAddress, &self.privateKey) + if rc != 1 { + throw CryptoKitError.internalBoringSSLError() + } + } + } + + init(bytes: D) throws { + self.privateKey = .init() + + // The first bytes are the private key (in "seed representation"), the latter bytes are the public key. + try bytes.withUnsafeBytes { ptr in + guard ptr.count == Int(XWING_PRIVATE_KEY_BYTES) + Int(XWING_PUBLIC_KEY_BYTES) else { + throw CryptoKitError.incorrectKeySize + } + let privateKeyBytes = UnsafeRawBufferPointer(rebasing: ptr.prefix(Int(XWING_PRIVATE_KEY_BYTES))) + let publicKeyBytes = UnsafeRawBufferPointer(rebasing: ptr.suffix(Int(XWING_PUBLIC_KEY_BYTES))) + + var cbs = CBS() + CCryptoBoringSSL_CBS_init(&cbs, privateKeyBytes.baseAddress, privateKeyBytes.count) + + let rc = CCryptoBoringSSL_XWING_parse_private_key(&self.privateKey, &cbs) + guard rc == 1 else { + throw CryptoKitError.internalBoringSSLError() + } + + // Matching CryptoKit, we only care that this _is_ a public key, not that it matches. + let _ = try OpenSSLXWingPublicKeyImpl(dataRepresentation: publicKeyBytes) + } + } + + init(seedRepresentation: D, publicKeyHash: SHA3_256Digest?) throws { + self.privateKey = .init() + + let seedRepresentation: ContiguousBytes = + seedRepresentation.regions.count == 1 ? seedRepresentation.regions.first! : Array(seedRepresentation) + + try seedRepresentation.withUnsafeBytes { privateKeyBytes in + guard privateKeyBytes.count == Int(XWING_PRIVATE_KEY_BYTES) else { + throw CryptoKitError.incorrectKeySize + } + + var cbs = CBS() + CCryptoBoringSSL_CBS_init(&cbs, privateKeyBytes.baseAddress, privateKeyBytes.count) + + let rc = CCryptoBoringSSL_XWING_parse_private_key(&self.privateKey, &cbs) + guard rc == 1 else { + throw CryptoKitError.internalBoringSSLError() + } + } + } + + var seedRepresentation: Data { + withUnsafeTemporaryAllocation(byteCount: Int(XWING_PRIVATE_KEY_BYTES), alignment: 1) { + var cbb = CBB() + CCryptoBoringSSL_CBB_init_fixed(&cbb, $0.baseAddress, $0.count) + let rc = CCryptoBoringSSL_XWING_marshal_private_key(&cbb, &self.privateKey) + precondition(rc == 1) + return Data($0.prefix(CCryptoBoringSSL_CBB_len(&cbb))) + } + } + + var integrityCheckedRepresentation: Data { + fatalError() + } + + var dataRepresentation: Data { + self.seedRepresentation + self.publicKey + } + + var publicKey: Data { + withUnsafeTemporaryAllocation(byteCount: Int(XWING_PUBLIC_KEY_BYTES), alignment: 1) { + let rc = CCryptoBoringSSL_XWING_public_from_private($0.baseAddress, &self.privateKey) + precondition(rc == 1) + return Data($0) + } + } + + static func generate() throws -> Self { + try Self() + } + + func decapsulate(_ encapsulated: Data) throws -> SymmetricKey { + try SymmetricKey(unsafeUninitializedCapacity: Int(XWING_SHARED_SECRET_BYTES)) { sharedSecretBytes, count in + try encapsulated.withUnsafeBytes { encapsulatedSecretBytes in + let rc = CCryptoBoringSSL_XWING_decap( + sharedSecretBytes.baseAddress, + encapsulatedSecretBytes.baseAddress, + &self.privateKey + ) + guard rc == 1 else { + throw CryptoKitError.internalBoringSSLError() + } + count = Int(XWING_SHARED_SECRET_BYTES) + } + } + } + } +} + +#endif // CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API diff --git a/Sources/Crypto/KEM/KEM-Errors.swift b/Sources/Crypto/KEM/KEM-Errors.swift new file mode 100644 index 000000000..3d4b79bb8 --- /dev/null +++ b/Sources/Crypto/KEM/KEM-Errors.swift @@ -0,0 +1,37 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2019-2020 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +@_exported import CryptoKit +#else + +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else +import Foundation +#endif + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension KEM { + /// Errors that CryptoKit throws when it encounters problems in key encapsulation mechanism (KEM) operations. + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) + public enum Errors: Error { + /// The public key CryptoKit receives when it initializes a key encapsulation operation doesn't match the expected value. + case publicKeyMismatchDuringInitialization + + /// The seed value supplied for deriving a key isn't valid. + case invalidSeed + } +} + +#endif // Linux or !SwiftPM diff --git a/Sources/Crypto/KEM/KEM.swift b/Sources/Crypto/KEM/KEM.swift index e3939b654..584e9d69e 100644 --- a/Sources/Crypto/KEM/KEM.swift +++ b/Sources/Crypto/KEM/KEM.swift @@ -14,19 +14,27 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else -import Foundation -/// A Key Encapsulation Mechanism +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +public import SwiftSystem +#else +public import Foundation +#endif + +/// A key encapsulation mechanism. +/// +/// Use a key encapsulation mechanism (KEM) to protect a symmetric cryptographic key that you share with another party. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -public enum KEM { - /// The result of an encapsulation operation +public enum KEM: Sendable { + /// The result of a key encapsulation operation. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public struct EncapsulationResult { - /// The shared secret + public struct EncapsulationResult: Sendable { + /// The shared secret. public let sharedSecret: SymmetricKey - /// The encapsulated secret + /// The encapsulated representation of the shared secret. public let encapsulated: Data + /// Initializes a key encapsulation result. public init(sharedSecret: SymmetricKey, encapsulated: Data) { self.sharedSecret = sharedSecret self.encapsulated = encapsulated @@ -34,29 +42,37 @@ public enum KEM { } } -/// A Key Encapsulation Mechanism's Public Key +/// The public key for a key encapsulation mechanism. +@preconcurrency @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -public protocol KEMPublicKey { - /// Encapsulates the generated shared secret - /// - Returns: The shared secret and its encapsulated version +public protocol KEMPublicKey: Sendable { + /// Generates and encapsulates a shared secret. + /// + /// Share the encapsulated secret with the person who has the ``KEMPrivateKey``. + /// They use ``KEMPrivateKey/decapsulate(_:)`` to recover the shared secret. + /// - Returns: The shared secret, and its encapsulated version. func encapsulate() throws -> KEM.EncapsulationResult } -/// A Key Encapsulation Mechanism's Private Key +/// The private key for a key encapsulation mechanism. +@preconcurrency @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -public protocol KEMPrivateKey { +public protocol KEMPrivateKey: Sendable { associatedtype PublicKey: KEMPublicKey - /// Generate a new random Private Key - /// - Returns: The generated private key + /// Generates a new random private key. + /// - Returns: The generated private key. + /// + /// Give the ``publicKey`` to another person so that they can encapsulate + /// shared secrets that you recover by calling ``decapsulate(_:)``. static func generate() throws -> Self - /// Decapsulates the encapsulated shared secret - /// - Parameter encapsulated: The encapsulated shared secret - /// - Returns: The decapsulated shared secret + /// Recovers a shared secret from an encapsulated representation. + /// - Parameter encapsulated: The encapsulated shared secret that someone created using this key's ``publicKey``. + /// - Returns: The decapsulated shared secret. func decapsulate(_ encapsulated: Data) throws -> SymmetricKey - /// Returns the associated public key + /// The associated public key. var publicKey: PublicKey { get } } #endif // Linux or !SwiftPM diff --git a/Sources/Crypto/KEM/MLKEM.swift b/Sources/Crypto/KEM/MLKEM.swift new file mode 100644 index 000000000..a93d860c1 --- /dev/null +++ b/Sources/Crypto/KEM/MLKEM.swift @@ -0,0 +1,282 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2019-2020 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +@_exported import CryptoKit +#else +public import Foundation + +#if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +typealias MLKEMPublicKeyImpl = CoreCryptoMLKEMPublicKeyImpl +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +typealias MLKEMPrivateKeyImpl = CoreCryptoMLKEMPrivateKeyImpl +#else +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +typealias MLKEMPublicKeyImpl = OpenSSLMLKEMPublicKeyImpl +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +typealias MLKEMPrivateKeyImpl = OpenSSLMLKEMPrivateKeyImpl +#endif + + +/// The Module-Lattice key encapsulation mechanism (KEM). +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +public enum MLKEM768: Sendable {} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension MLKEM768 { + /// A public key you use to encapsulate shared secrets with the Module-Lattice key encapsulation mechanism. + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) + public struct PublicKey: KEMPublicKey, Sendable { + var impl: MLKEMPublicKeyImpl + + /// Initializes a public key from a raw representation. + /// - Parameter rawRepresentation: Data that represents the public key. + public init(rawRepresentation: D) throws { + self.impl = try MLKEMPublicKeyImpl(rawRepresentation: rawRepresentation) + } + + /// A serialized representation of the public key. + public var rawRepresentation: Data { + get { + return self.impl.rawRepresentation + } + } + + /// Generates and encapsulates a shared secret. + /// + /// - Returns: an encapsulated shared secret, that you decapsulate by calling ``MLKEM768/PrivateKey/decapsulate(_:)`` on the corresponding private key. + public func encapsulate() throws -> KEM.EncapsulationResult { + return try self.impl.encapsulate() + } + + func encapsulateWithSeed(encapSeed: Data) throws -> KEM.EncapsulationResult { + return try self.impl.encapsulateWithSeed(encapSeed) + } + } + + /// A private key you use to decapsulate shared secrets with the Module-Lattice key encapsulation mechanism. + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) + public struct PrivateKey: KEMPrivateKey { + internal let impl: MLKEMPrivateKeyImpl + + internal init(_ impl: MLKEMPrivateKeyImpl) { + self.impl = impl + } + + /// Generates a new, random private key. + public static func generate() throws -> MLKEM768.PrivateKey { + let impl = try MLKEMPrivateKeyImpl.generatePrivateKey() + return PrivateKey(impl) + } + + static func generateWithSeed(_ seed: Data) throws -> MLKEM768.PrivateKey { + let impl = try MLKEMPrivateKeyImpl.generateWithSeed(seed) + return PrivateKey(impl) + } + + /// Initializes a random private key. + public init() throws { + self = try PrivateKey.generate() + } + + /// Initializes a private key from a seed representation and optional public key. + /// + /// - Parameters: + /// - seedRepresentation: The seed representation `d||z`, as specified in the `ML-KEM.KeyGen_internal(d,z)` algorithm (Algorithm 16) of FIPS 203. + /// - publicKey: An optional public key. Pass this to check that the initialized private key is consistent with the public key. The initializer throws if the public key doesn't match the expected value. + public init(seedRepresentation: D, publicKey: MLKEM768.PublicKey?) throws { + var publicKeyRawRepresentation: Data? = nil + if publicKey != nil { + publicKeyRawRepresentation = publicKey!.rawRepresentation + } + self.impl = try MLKEMPrivateKeyImpl(seedRepresentation: seedRepresentation, publicKeyRawRepresentation: publicKeyRawRepresentation) + } + + /// The private key's seed representation. + /// + /// The seed is `d||z`, as specified in the algorithm `ML-KEM.KeyGen_internal(d,z)` (Algorithm 16) of FIPS 203. + public var seedRepresentation: Data { + get { + return self.impl.seedRepresentation + } + } + + /// Decapsulated a shared secret. + /// + /// - Parameters: + /// - encapsulated: An encapsulated shared secret, that you get by calling ``MLKEM768/PublicKey/encapsulate()`` on the corresponding public key. + /// - Returns: The shared secret. + public func decapsulate(_ encapsulated: D) throws -> SymmetricKey { + return try impl.decapsulate(encapsulated: encapsulated) + } + + /// The corresponding public key. + public var publicKey: MLKEM768.PublicKey { + get { + try self.impl.publicKey + } + } + + /// Initializes a private key from an integrity-checked representation. + /// + /// - Parameter integrityCheckedRepresentation: A representation of the private key that includes the seed value, and a hash of the corresponding public key. + public init(integrityCheckedRepresentation: D) throws { + guard integrityCheckedRepresentation.count == MLKEMPrivateKeyImpl.seedSize + 32 else { + throw KEM.Errors.invalidSeed + } + let seed = Data(integrityCheckedRepresentation).subdata(in: 0...seedSize) + let publicKeyHashData = Data(integrityCheckedRepresentation).subdata(in: MLKEMPrivateKeyImpl.seedSize..(seedRepresentation: seed, publicKeyHash: publicKeyHash) + } + + /// An integrity-checked representation of the private key. + /// + /// This representation includes the seed value, and a hash of the corresponding public key. + public var integrityCheckedRepresentation: Data { + get { + return self.impl.integrityCheckedRepresentation + } + } + } +} + + +/// The Module-Lattice key encapsulation mechanism (KEM). +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +public enum MLKEM1024: Sendable {} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension MLKEM1024 { + /// A public key you use to encapsulate shared secrets with the Module-Lattice key encapsulation mechanism. + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) + public struct PublicKey: KEMPublicKey, Sendable { + var impl: MLKEMPublicKeyImpl + + /// Initializes a public key from a raw representation. + /// - Parameter rawRepresentation: Data that represents the public key. + public init(rawRepresentation: D) throws { + self.impl = try MLKEMPublicKeyImpl(rawRepresentation: rawRepresentation) + } + + /// A serialized representation of the public key. + public var rawRepresentation: Data { + get { + return self.impl.rawRepresentation + } + } + + /// Generates and encapsulates a shared secret. + /// + /// - Returns: an encapsulated shared secret, that you decapsulate by calling ``MLKEM1024/PrivateKey/decapsulate(_:)`` on the corresponding private key. + public func encapsulate() throws -> KEM.EncapsulationResult { + return try self.impl.encapsulate() + } + + func encapsulateWithSeed(encapSeed: Data) throws -> KEM.EncapsulationResult { + return try self.impl.encapsulateWithSeed(encapSeed) + } + } + + /// A private key you use to decapsulate shared secrets with the Module-Lattice key encapsulation mechanism. + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) + public struct PrivateKey: KEMPrivateKey { + internal let impl: MLKEMPrivateKeyImpl + + internal init(_ impl: MLKEMPrivateKeyImpl) { + self.impl = impl + } + + /// Generates a new, random private key. + public static func generate() throws -> MLKEM1024.PrivateKey { + let impl = try MLKEMPrivateKeyImpl.generatePrivateKey() + return PrivateKey(impl) + } + + static func generateWithSeed(_ seed: Data) throws -> MLKEM1024.PrivateKey { + let impl = try MLKEMPrivateKeyImpl.generateWithSeed(seed) + return PrivateKey(impl) + } + + /// Initializes a random private key. + public init() throws { + self = try PrivateKey.generate() + } + + /// Initializes a private key from a seed representation and optional public key. + /// + /// - Parameters: + /// - seedRepresentation: The seed representation `d||z`, as specified in the `ML-KEM.KeyGen_internal(d,z)` algorithm (Algorithm 16) of FIPS 203. + /// - publicKey: An optional public key. Pass this to check that the initialized private key is consistent with the public key. The initializer throws if the public key doesn't match the expected value. + public init(seedRepresentation: D, publicKey: MLKEM1024.PublicKey?) throws { + var publicKeyRawRepresentation: Data? = nil + if publicKey != nil { + publicKeyRawRepresentation = publicKey!.rawRepresentation + } + self.impl = try MLKEMPrivateKeyImpl(seedRepresentation: seedRepresentation, publicKeyRawRepresentation: publicKeyRawRepresentation) + } + + /// The private key's seed representation. + /// + /// The seed is `d||z`, as specified in the algorithm `ML-KEM.KeyGen_internal(d,z)` (Algorithm 16) of FIPS 203. + public var seedRepresentation: Data { + get { + return self.impl.seedRepresentation + } + } + + /// Decapsulated a shared secret. + /// + /// - Parameters: + /// - encapsulated: An encapsulated shared secret, that you get by calling ``MLKEM1024/PublicKey/encapsulate()`` on the corresponding public key. + /// - Returns: The shared secret. + public func decapsulate(_ encapsulated: D) throws -> SymmetricKey { + return try impl.decapsulate(encapsulated: encapsulated) + } + + /// The corresponding public key. + public var publicKey: MLKEM1024.PublicKey { + get { + try self.impl.publicKey + } + } + + /// Initializes a private key from an integrity-checked representation. + /// + /// - Parameter integrityCheckedRepresentation: A representation of the private key that includes the seed value, and a hash of the corresponding public key. + public init(integrityCheckedRepresentation: D) throws { + guard integrityCheckedRepresentation.count == MLKEMPrivateKeyImpl.seedSize + 32 else { + throw KEM.Errors.invalidSeed + } + let seed = Data(integrityCheckedRepresentation).subdata(in: 0...seedSize) + let publicKeyHashData = Data(integrityCheckedRepresentation).subdata(in: MLKEMPrivateKeyImpl.seedSize..(seedRepresentation: seed, publicKeyHash: publicKeyHash) + } + + /// An integrity-checked representation of the private key. + /// + /// This representation includes the seed value, and a hash of the corresponding public key. + public var integrityCheckedRepresentation: Data { + get { + return self.impl.integrityCheckedRepresentation + } + } + } +} + + +#endif // Linux or !SwiftPM diff --git a/Sources/Crypto/KEM/MLKEM.swift.gyb b/Sources/Crypto/KEM/MLKEM.swift.gyb new file mode 100644 index 000000000..bdc85b20a --- /dev/null +++ b/Sources/Crypto/KEM/MLKEM.swift.gyb @@ -0,0 +1,158 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2019-2020 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +@_exported import CryptoKit +#else +public import Foundation +%{ + MLKEM_VARIANTS = [{"name": "MLKEM768", "ccinfo": "cckem_mlkem768()!"}, {"name": "MLKEM1024", "ccinfo": "cckem_mlkem1024()!"}] +}% + +#if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +typealias MLKEMPublicKeyImpl = CoreCryptoMLKEMPublicKeyImpl +typealias MLKEMPrivateKeyImpl = CoreCryptoMLKEMPrivateKeyImpl +#else +typealias MLKEMPublicKeyImpl = OpenSSLMLKEMPublicKeyImpl +typealias MLKEMPrivateKeyImpl = OpenSSLMLKEMPrivateKeyImpl +#endif + +% for MLKEM_VARIANT in MLKEM_VARIANTS: +%{ + NAME = MLKEM_VARIANT["name"] + INFO = MLKEM_VARIANT["ccinfo"] +}% + +/// The Module-Lattice key encapsulation mechanism (KEM). +public enum ${NAME}: Sendable {} + +extension ${NAME} { + /// A public key you use to encapsulate shared secrets with the Module-Lattice key encapsulation mechanism. + public struct PublicKey: KEMPublicKey, Sendable { + var impl: MLKEMPublicKeyImpl<${NAME}> + + /// Initializes a public key from a raw representation. + /// - Parameter rawRepresentation: Data that represents the public key. + public init(rawRepresentation: D) throws { + self.impl = try MLKEMPublicKeyImpl(rawRepresentation: rawRepresentation) + } + + /// A serialized representation of the public key. + public var rawRepresentation: Data { + get { + return self.impl.rawRepresentation + } + } + + /// Generates and encapsulates a shared secret. + /// + /// - Returns: an encapsulated shared secret, that you decapsulate by calling ``${NAME}/PrivateKey/decapsulate(_:)`` on the corresponding private key. + public func encapsulate() throws -> KEM.EncapsulationResult { + return try self.impl.encapsulate() + } + + func encapsulateWithSeed(encapSeed: Data) throws -> KEM.EncapsulationResult { + return try self.impl.encapsulateWithSeed(encapSeed) + } + } + + /// A private key you use to decapsulate shared secrets with the Module-Lattice key encapsulation mechanism. + public struct PrivateKey: KEMPrivateKey { + internal let impl: MLKEMPrivateKeyImpl<${NAME}> + + internal init(_ impl: MLKEMPrivateKeyImpl<${NAME}>) { + self.impl = impl + } + + /// Generates a new, random private key. + public static func generate() throws -> ${NAME}.PrivateKey { + let impl = try MLKEMPrivateKeyImpl<${NAME}>.generatePrivateKey() + return PrivateKey(impl) + } + + static func generateWithSeed(_ seed: Data) throws -> ${NAME}.PrivateKey { + let impl = try MLKEMPrivateKeyImpl<${NAME}>.generateWithSeed(seed) + return PrivateKey(impl) + } + + /// Initializes a random private key. + public init() throws { + self = try PrivateKey.generate() + } + + /// Initializes a private key from a seed representation and optional public key. + /// + /// - Parameters: + /// - seedRepresentation: The seed representation `d||z`, as specified in the `ML-KEM.KeyGen_internal(d,z)` algorithm (Algorithm 16) of FIPS 203. + /// - publicKey: An optional public key. Pass this to check that the initialized private key is consistent with the public key. The initializer throws if the public key doesn't match the expected value. + public init(seedRepresentation: D, publicKey: ${NAME}.PublicKey?) throws { + var publicKeyRawRepresentation: Data? = nil + if publicKey != nil { + publicKeyRawRepresentation = publicKey!.rawRepresentation + } + self.impl = try MLKEMPrivateKeyImpl<${NAME}>(seedRepresentation: seedRepresentation, publicKeyRawRepresentation: publicKeyRawRepresentation) + } + + /// The private key's seed representation. + /// + /// The seed is `d||z`, as specified in the algorithm `ML-KEM.KeyGen_internal(d,z)` (Algorithm 16) of FIPS 203. + public var seedRepresentation: Data { + get { + return self.impl.seedRepresentation + } + } + + /// Decapsulated a shared secret. + /// + /// - Parameters: + /// - encapsulated: An encapsulated shared secret, that you get by calling ``${NAME}/PublicKey/encapsulate()`` on the corresponding public key. + /// - Returns: The shared secret. + public func decapsulate(_ encapsulated: D) throws -> SymmetricKey { + return try impl.decapsulate(encapsulated: encapsulated) + } + + /// The corresponding public key. + public var publicKey: ${NAME}.PublicKey { + get { + try self.impl.publicKey + } + } + + /// Initializes a private key from an integrity-checked representation. + /// + /// - Parameter integrityCheckedRepresentation: A representation of the private key that includes the seed value, and a hash of the corresponding public key. + public init(integrityCheckedRepresentation: D) throws { + guard integrityCheckedRepresentation.count == MLKEMPrivateKeyImpl<${NAME}>.seedSize + 32 else { + throw KEM.Errors.invalidSeed + } + let seed = Data(integrityCheckedRepresentation).subdata(in: 0...seedSize) + let publicKeyHashData = Data(integrityCheckedRepresentation).subdata(in: MLKEMPrivateKeyImpl<${NAME}>.seedSize..(seedRepresentation: seed, publicKeyHash: publicKeyHash) + } + + /// An integrity-checked representation of the private key. + /// + /// This representation includes the seed value, and a hash of the corresponding public key. + public var integrityCheckedRepresentation: Data { + get { + return self.impl.integrityCheckedRepresentation + } + } + } +} + +% end + +#endif // Linux or !SwiftPM diff --git a/Sources/Crypto/KEM/XWing.swift b/Sources/Crypto/KEM/XWing.swift new file mode 100644 index 000000000..e90c94a18 --- /dev/null +++ b/Sources/Crypto/KEM/XWing.swift @@ -0,0 +1,193 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2019-2020 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +@_exported import CryptoKit +#else +public import Foundation + +#if _runtime(_ObjC) && CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +@_exported import CryptoKit +#else + +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else +import Foundation +#endif + +#if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +typealias XWingPublicKeyImpl = CoreCryptoXWingPublicKeyImpl +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +typealias XWingPrivateKeyImpl = CoreCryptoXWingPrivateKeyImpl +#else +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +typealias XWingPublicKeyImpl = OpenSSLXWingPublicKeyImpl +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +typealias XWingPrivateKeyImpl = OpenSSLXWingPrivateKeyImpl +#endif + +/// The X-Wing (ML-KEM768 with X25519) Key Encapsulation Mechanism, defined in +/// https://datatracker.ietf.org/doc/html/draft-connolly-cfrg-xwing-kem-06 +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +public enum XWingMLKEM768X25519: Sendable {} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension XWingMLKEM768X25519 { + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) + public struct PublicKey: KEMPublicKey { + var impl: XWingPublicKeyImpl + + internal init(impl: XWingPublicKeyImpl) { + self.impl = impl + } + + public init(dataRepresentation: D) throws { + self.impl = try .init(dataRepresentation: dataRepresentation) + } + + public var rawRepresentation: Data { + get { + self.impl.rawRepresentation + } + } + + public func encapsulate() throws -> KEM.EncapsulationResult { + return try self.impl.encapsulate() + } + } + + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) + public struct PrivateKey: KEMPrivateKey { + private var impl: XWingPrivateKeyImpl + + public var seedRepresentation: Data { + get { + self.impl.seedRepresentation + } + } + + public var integrityCheckedRepresentation: Data { + get { + self.impl.integrityCheckedRepresentation + } + } + + internal init(impl: XWingPrivateKeyImpl) { + self.impl = impl + } + + public init(bytes: D) throws { + self.impl = try .init(bytes: bytes) + } + + internal init(seedRepresentation: D, publicKeyHash: SHA3_256Digest?) throws { + self.impl = try .init(seedRepresentation: seedRepresentation, publicKeyHash: publicKeyHash) + } + + public var dataRepresentation: Data { + get { + self.impl.dataRepresentation + } + } + + public static func generate() throws -> XWingMLKEM768X25519.PrivateKey { + return try Self(impl: XWingPrivateKeyImpl.generate()) + } + + public func decapsulate(_ encapsulated: Data) throws -> SymmetricKey { + try self.impl.decapsulate(encapsulated) + } + + public var publicKey: XWingMLKEM768X25519.PublicKey { + get { + XWingMLKEM768X25519.PublicKey(impl: self.impl.publicKey) + } + } + } +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension XWingMLKEM768X25519.PrivateKey: HPKEKEMPrivateKeyGeneration { + public init() throws { + self = try Self.generate() + } + + public init(seedRepresentation: D, publicKey: XWingMLKEM768X25519.PublicKey?) throws { + #if false + var publicKeyHash: SHA3_256Digest? = nil + if publicKey != nil { + publicKeyHash = SHA3_256.hash(data: publicKey!.rawRepresentation) + } + + self = try XWingMLKEM768X25519.PrivateKey.init(seedRepresentation: seedRepresentation, publicKeyHash: publicKeyHash) + #else + precondition(publicKey == nil) + self = try XWingMLKEM768X25519.PrivateKey.init(seedRepresentation: seedRepresentation, publicKeyHash: nil) + #endif + } + + public init(integrityCheckedRepresentation: D) throws { + let seed = integrityCheckedRepresentation.dropLast(32) // sizeof(SHA3-256 digest) + let publicKeyHashBytes = integrityCheckedRepresentation.dropFirst(32) + let publicKeyHash = SHA3_256Digest(bytes: [UInt8](publicKeyHashBytes)) + + self = try XWingMLKEM768X25519.PrivateKey.init(seedRepresentation: seed, publicKeyHash: publicKeyHash) + } +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension XWingMLKEM768X25519.PublicKey: HPKEKEMPublicKey { + /// The type of the ephemeral private key associated with this public key. + public typealias EphemeralPrivateKey = XWingMLKEM768X25519.PrivateKey + + static func validateCiphersuite(_ kem: HPKE.KEM) throws { + switch kem { + case .XWingMLKEM768X25519: do {} + default: do { + throw HPKE.Errors.inconsistentCiphersuiteAndKey + } + } + } + + /// Creates an X-Wing public key for use with HPKE. + /// + /// - Parameters: + /// - serialization: The serialized bytes of the public key. + /// - kem: The key encapsulation mechanism to use with the public key. + /// + /// - Throws: ``CryptoKit/HPKE/Errors/inconsistentCiphersuiteAndKey`` if the key encapsulation mechanism requested is incompatible with this public key. + public init(_ serialization: D, kem: HPKE.KEM) throws where D: ContiguousBytes { + try Self.validateCiphersuite(kem) + try self.init(dataRepresentation: serialization) + } + + /// Creates a serialized representation of the public key. + /// + /// - Parameters: + /// - kem: The Key Encapsulation Mechanism to use with the public key. + /// + /// - Throws: ``CryptoKit/HPKE/Errors/inconsistentCiphersuiteAndKey`` if the key encapsulation mechanism requested is incompatible with this public key. + /// + /// - Returns: The serialized representation of the public key. + public func hpkeRepresentation(kem: HPKE.KEM) throws -> Data { + try Self.validateCiphersuite(kem) + return self.rawRepresentation + } + + /// The type of the ephemeral private key associated with this public key. + public typealias HPKEEphemeralPrivateKey = XWingMLKEM768X25519.PrivateKey +} +#endif +#endif // Linux or !SwiftPM diff --git a/Sources/Crypto/Key Agreement/DH.swift b/Sources/Crypto/Key Agreement/DH.swift index 4eead0b61..3a299b389 100644 --- a/Sources/Crypto/Key Agreement/DH.swift +++ b/Sources/Crypto/Key Agreement/DH.swift @@ -14,13 +14,19 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else -import Foundation + +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +public import SwiftSystem +#else +public import Foundation +#endif /// A Diffie-Hellman Key Agreement Key +@preconcurrency @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -public protocol DiffieHellmanKeyAgreement { +public protocol DiffieHellmanKeyAgreement: Sendable { /// The public key share type to perform the DH Key Agreement - associatedtype PublicKey + associatedtype PublicKey: Sendable var publicKey: PublicKey { get } /// Performs a Diffie-Hellman Key Agreement. @@ -28,7 +34,7 @@ public protocol DiffieHellmanKeyAgreement { /// - Parameters: /// - publicKeyShare: The public key share. /// - Returns: The resulting key agreement result. - func sharedSecretFromKeyAgreement(with publicKeyShare: PublicKey) throws -> SharedSecret + func sharedSecretFromKeyAgreement(with publicKeyShare: PublicKey) throws(CryptoKitMetaError) -> SharedSecret } /// A key agreement result from which you can derive a symmetric cryptographic @@ -37,7 +43,7 @@ public protocol DiffieHellmanKeyAgreement { /// Generate a shared secret by calling your private key’s /// `sharedSecretFromKeyAgreement(publicKeyShare:)` method with the public key /// from another party. The other party computes the same secret by passing your -/// public key to the equivalent method on their own private key. +/// public key to the the equivalent method on their own private key. /// /// The shared secret isn’t suitable as a symmetric cryptographic key /// (``SymmetricKey``) by itself. However, you use it to generate a key by @@ -49,9 +55,13 @@ public protocol DiffieHellmanKeyAgreement { /// ``HMAC``, or for opening and closing a sealed box with a cipher like /// ``ChaChaPoly`` or ``AES``. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -public struct SharedSecret: ContiguousBytes { +public struct SharedSecret: ContiguousBytes, Sendable { var ss: SecureBytes - + + internal init(ss: SecureBytes){ + self.ss = ss + } + /// Invokes the given closure with a buffer pointer covering the raw bytes /// of the shared secret. /// @@ -60,9 +70,15 @@ public struct SharedSecret: ContiguousBytes { /// shared secret and returns the shared secret. /// /// - Returns: The shared secret, as returned from the body closure. + #if hasFeature(Embedded) + public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws(E) -> R) throws(E) -> R { + return try ss.withUnsafeBytes(body) + } + #else public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R { return try ss.withUnsafeBytes(body) } + #endif /// Derives a symmetric encryption key from the secret using x9.63 key /// derivation. @@ -74,57 +90,10 @@ public struct SharedSecret: ContiguousBytes { /// /// - Returns: The derived symmetric key. public func x963DerivedSymmetricKey(using hashFunction: H.Type, sharedInfo: SI, outputByteCount: Int) -> SymmetricKey { - // SEC1 defines 3 inputs to the KDF: - // - // 1. An octet string Z which is the shared secret value. That's `self` here. - // 2. An integer `keydatalen` which is the length in octets of the keying data to be generated. Here that's `outputByteCount`. - // 3. An optional octet string `SharedInfo` which consists of other shared data. Here, that's `sharedInfo`. - // - // We then need to perform the following steps: - // - // 1. Check that keydatalen < hashlen × (2³² − 1). If keydatalen ≥ hashlen × (2³² − 1), fail. - // 2. Initiate a 4 octet, big-endian octet string Counter as 0x00000001. - // 3. For i = 1 to ⌈keydatalen/hashlen⌉, do the following: - // 1. Compute: Ki = Hash(Z || Counter || [SharedInfo]). - // 2. Increment Counter. - // 3. Increment i. - // 4. Set K to be the leftmost keydatalen octets of: K1 || K2 || . . . || K⌈keydatalen/hashlen⌉. - // 5. Output K. - // - // The loop in step 3 is not very Swifty, so instead we generate the counter directly. - // Step 1: Check that keydatalen < hashlen × (2³² − 1). - // We do this math in UInt64-space, because we'll overflow 32-bit integers. - guard UInt64(outputByteCount) < (UInt64(H.Digest.byteCount) * UInt64(UInt32.max)) else { - fatalError("Invalid parameter size") - } - - var key = SecureBytes() - key.reserveCapacity(outputByteCount) - - var remainingBytes = outputByteCount - var counter = UInt32(1) - while remainingBytes > 0 { - // 1. Compute: Ki = Hash(Z || Counter || [SharedInfo]). - var hasher = H() - hasher.update(self) - hasher.update(counter.bigEndian) - hasher.update(data: sharedInfo) - let digest = hasher.finalize() - - // 2. Increment Counter. - counter += 1 - - // Append the bytes of the digest. We don't want to append more than the remaining number of bytes. - let bytesToAppend = min(remainingBytes, H.Digest.byteCount) - digest.withUnsafeBytes { digestPtr in - key.append(digestPtr.prefix(bytesToAppend)) - } - remainingBytes -= bytesToAppend + return self.ss.withUnsafeBytes { ssBytes in + return ANSIKDFx963.deriveKey(inputKeyMaterial: SymmetricKey(data: ssBytes), info: sharedInfo, outputByteCount: outputByteCount) } - - precondition(key.count == outputByteCount) - return SymmetricKey(data: key) } /// Derives a symmetric encryption key from the secret using HKDF key @@ -155,7 +124,7 @@ extension SharedSecret: Hashable { // We want to implement constant-time comparison for digests. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -extension SharedSecret: CustomStringConvertible, Equatable { +extension SharedSecret: Equatable { public static func == (lhs: Self, rhs: Self) -> Bool { return safeCompare(lhs, rhs) } @@ -177,11 +146,16 @@ extension SharedSecret: CustomStringConvertible, Equatable { return safeCompare(lhs, rhs.regions.first!) } } +} +#if !hasFeature(Embedded) +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension SharedSecret: CustomStringConvertible { public var description: String { return "\(Self.self): \(ss.hexString)" } } +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension HashFunction { diff --git a/Sources/Crypto/Key Agreement/ECDH.swift b/Sources/Crypto/Key Agreement/ECDH.swift index 56bf0dc51..041c95c80 100644 --- a/Sources/Crypto/Key Agreement/ECDH.swift +++ b/Sources/Crypto/Key Agreement/ECDH.swift @@ -14,7 +14,7 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else -#if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +#if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) typealias NISTCurvePublicKeyImpl = CoreCryptoNISTCurvePublicKeyImpl @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) @@ -26,7 +26,11 @@ typealias NISTCurvePublicKeyImpl = OpenSSLNISTCurvePublicKeyImpl typealias NISTCurvePrivateKeyImpl = OpenSSLNISTCurvePrivateKeyImpl #endif -import Foundation +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +public import SwiftSystem +#else +public import Foundation +#endif // MARK: - Generated file, do NOT edit // any edits of this file WILL be overwritten and thus discarded @@ -39,11 +43,11 @@ extension P256 { /// A mechanism used to create or verify a cryptographic signature using /// the NIST P-256 elliptic curve digital signature algorithm (ECDSA). @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public enum Signing { - + public enum Signing: Sendable { + /// A P-256 public key used to verify cryptographic signatures. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public struct PublicKey: NISTECPublicKey { + public struct PublicKey: NISTECPublicKey, Sendable { var impl: NISTCurvePublicKeyImpl /// Creates a P-256 public key for signing from a collection of bytes. @@ -51,7 +55,7 @@ extension P256 { /// - Parameters: /// - rawRepresentation: A raw representation of the key as a collection of /// contiguous bytes. - public init(rawRepresentation: D) throws { + public init(rawRepresentation: D) throws(CryptoKitMetaError) { impl = try NISTCurvePublicKeyImpl(rawRepresentation: rawRepresentation) } @@ -61,7 +65,7 @@ extension P256 { /// - Parameters: /// - compactRepresentation: A compact representation of the key /// as a collection of contiguous bytes. - public init(compactRepresentation: Bytes) throws { + public init(compactRepresentation: Bytes) throws(CryptoKitMetaError) { impl = try NISTCurvePublicKeyImpl(compactRepresentation: compactRepresentation) } @@ -70,7 +74,7 @@ extension P256 { /// /// - Parameters: /// - x963Representation: An ANSI x9.63 representation of the key. - public init(x963Representation: Bytes) throws { + public init(x963Representation: Bytes) throws(CryptoKitMetaError) { impl = try NISTCurvePublicKeyImpl(x963Representation: x963Representation) } @@ -80,29 +84,31 @@ extension P256 { /// - Parameters: /// - compressedRepresentation: A compressed representation of the key as a collection /// of contiguous bytes. - public init(compressedRepresentation: Bytes) throws { + public init(compressedRepresentation: Bytes) throws(CryptoKitMetaError) { impl = try NISTCurvePublicKeyImpl(compressedRepresentation: compressedRepresentation) } +#if !hasFeature(Embedded) /// Creates a P-256 public key for signing from a Privacy-Enhanced Mail /// (PEM) representation. /// /// - Parameters: /// - pemRepresentation: A PEM representation of the key. - public init(pemRepresentation: String) throws { + public init(pemRepresentation: String) throws(CryptoKitMetaError) { let pem = try ASN1.PEMDocument(pemString: pemRepresentation) guard pem.type == "PUBLIC KEY" else { throw CryptoKitASN1Error.invalidPEMDocument } self = try .init(derRepresentation: pem.derBytes) } +#endif /// Creates a P-256 public key for signing from a Distinguished Encoding /// Rules (DER) encoded representation. /// /// - Parameters: /// - derRepresentation: A DER-encoded representation of the key. - public init(derRepresentation: Bytes) throws where Bytes.Element == UInt8 { + public init(derRepresentation: Bytes) throws(CryptoKitMetaError) where Bytes.Element == UInt8 { let bytes = Array(derRepresentation) let parsed = try ASN1.SubjectPublicKeyInfo(asn1Encoded: bytes) self = try .init(x963Representation: parsed.key) @@ -134,16 +140,18 @@ extension P256 { return Data(serializer.serializedBytes) } +#if !hasFeature(Embedded) /// A Privacy-Enhanced Mail (PEM) representation of the public key. public var pemRepresentation: String { let pemDocument = ASN1.PEMDocument(type: "PUBLIC KEY", derBytes: self.derRepresentation) return pemDocument.pemString } +#endif } /// A P-256 private key used to create cryptographic signatures. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public struct PrivateKey: NISTECPrivateKey { + public struct PrivateKey: NISTECPrivateKey, Sendable { let impl: NISTCurvePrivateKeyImpl /// Creates a random P-256 private key for signing. @@ -164,7 +172,7 @@ extension P256 { /// /// - Parameters: /// - x963Representation: An ANSI x9.63 representation of the key. - public init(x963Representation: Bytes) throws { + public init(x963Representation: Bytes) throws(CryptoKitMetaError) { impl = try NISTCurvePrivateKeyImpl(x963: x963Representation) } @@ -173,16 +181,17 @@ extension P256 { /// - Parameters: /// - rawRepresentation: A raw representation of the key as a collection of /// contiguous bytes. - public init(rawRepresentation: Bytes) throws { + public init(rawRepresentation: Bytes) throws(CryptoKitMetaError) { impl = try NISTCurvePrivateKeyImpl(data: rawRepresentation) } +#if !hasFeature(Embedded) /// Creates a P-256 private key for signing from a Privacy-Enhanced Mail /// PEM) representation. /// /// - Parameters: /// - pemRepresentation: A PEM representation of the key. - public init(pemRepresentation: String) throws { + public init(pemRepresentation: String) throws(CryptoKitMetaError) { let pem = try ASN1.PEMDocument(pemString: pemRepresentation) switch pem.type { @@ -196,13 +205,14 @@ extension P256 { throw CryptoKitASN1Error.invalidPEMDocument } } +#endif /// Creates a P-256 private key for signing from a Distinguished Encoding /// Rules (DER) encoded representation. /// /// - Parameters: /// - derRepresentation: A DER-encoded representation of the key. - public init(derRepresentation: Bytes) throws where Bytes.Element == UInt8 { + public init(derRepresentation: Bytes) throws(CryptoKitMetaError) where Bytes.Element == UInt8 { let bytes = Array(derRepresentation) // We have to try to parse this twice because we have no information about what kind of key this is. @@ -242,11 +252,13 @@ extension P256 { return Data(serializer.serializedBytes) } +#if !hasFeature(Embedded) /// A Privacy-Enhanced Mail (PEM) representation of the private key. public var pemRepresentation: String { let pemDocument = ASN1.PEMDocument(type: "PRIVATE KEY", derBytes: self.derRepresentation) return pemDocument.pemString } +#endif } } } @@ -258,11 +270,11 @@ extension P256 { /// performing NIST P-256 elliptic curve Diffie Hellman (ECDH) key /// exchange. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public enum KeyAgreement { - + public enum KeyAgreement: Sendable { + /// A P-256 public key used for key agreement. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public struct PublicKey: NISTECPublicKey { + public struct PublicKey: NISTECPublicKey, Sendable { var impl: NISTCurvePublicKeyImpl /// Creates a P-256 public key for key agreement from a collection of bytes. @@ -270,7 +282,7 @@ extension P256 { /// - Parameters: /// - rawRepresentation: A raw representation of the key as a collection of /// contiguous bytes. - public init(rawRepresentation: D) throws { + public init(rawRepresentation: D) throws(CryptoKitMetaError) { impl = try NISTCurvePublicKeyImpl(rawRepresentation: rawRepresentation) } @@ -280,7 +292,7 @@ extension P256 { /// - Parameters: /// - compactRepresentation: A compact representation of the key /// as a collection of contiguous bytes. - public init(compactRepresentation: Bytes) throws { + public init(compactRepresentation: Bytes) throws(CryptoKitMetaError) { impl = try NISTCurvePublicKeyImpl(compactRepresentation: compactRepresentation) } @@ -289,7 +301,7 @@ extension P256 { /// /// - Parameters: /// - x963Representation: An ANSI x9.63 representation of the key. - public init(x963Representation: Bytes) throws { + public init(x963Representation: Bytes) throws(CryptoKitMetaError) { impl = try NISTCurvePublicKeyImpl(x963Representation: x963Representation) } @@ -299,29 +311,31 @@ extension P256 { /// - Parameters: /// - compressedRepresentation: A compressed representation of the key as a collection /// of contiguous bytes. - public init(compressedRepresentation: Bytes) throws { + public init(compressedRepresentation: Bytes) throws(CryptoKitMetaError) { impl = try NISTCurvePublicKeyImpl(compressedRepresentation: compressedRepresentation) } +#if !hasFeature(Embedded) /// Creates a P-256 public key for key agreement from a Privacy-Enhanced Mail /// (PEM) representation. /// /// - Parameters: /// - pemRepresentation: A PEM representation of the key. - public init(pemRepresentation: String) throws { + public init(pemRepresentation: String) throws(CryptoKitMetaError) { let pem = try ASN1.PEMDocument(pemString: pemRepresentation) guard pem.type == "PUBLIC KEY" else { throw CryptoKitASN1Error.invalidPEMDocument } self = try .init(derRepresentation: pem.derBytes) } +#endif /// Creates a P-256 public key for key agreement from a Distinguished Encoding /// Rules (DER) encoded representation. /// /// - Parameters: /// - derRepresentation: A DER-encoded representation of the key. - public init(derRepresentation: Bytes) throws where Bytes.Element == UInt8 { + public init(derRepresentation: Bytes) throws(CryptoKitMetaError) where Bytes.Element == UInt8 { let bytes = Array(derRepresentation) let parsed = try ASN1.SubjectPublicKeyInfo(asn1Encoded: bytes) self = try .init(x963Representation: parsed.key) @@ -353,16 +367,18 @@ extension P256 { return Data(serializer.serializedBytes) } +#if !hasFeature(Embedded) /// A Privacy-Enhanced Mail (PEM) representation of the public key. public var pemRepresentation: String { let pemDocument = ASN1.PEMDocument(type: "PUBLIC KEY", derBytes: self.derRepresentation) return pemDocument.pemString } +#endif } /// A P-256 private key used for key agreement. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public struct PrivateKey: NISTECPrivateKey { + public struct PrivateKey: NISTECPrivateKey, Sendable { let impl: NISTCurvePrivateKeyImpl /// Creates a random P-256 private key for key agreement. @@ -383,7 +399,7 @@ extension P256 { /// /// - Parameters: /// - x963Representation: An ANSI x9.63 representation of the key. - public init(x963Representation: Bytes) throws { + public init(x963Representation: Bytes) throws(CryptoKitMetaError) { impl = try NISTCurvePrivateKeyImpl(x963: x963Representation) } @@ -392,16 +408,17 @@ extension P256 { /// - Parameters: /// - rawRepresentation: A raw representation of the key as a collection of /// contiguous bytes. - public init(rawRepresentation: Bytes) throws { + public init(rawRepresentation: Bytes) throws(CryptoKitMetaError) { impl = try NISTCurvePrivateKeyImpl(data: rawRepresentation) } +#if !hasFeature(Embedded) /// Creates a P-256 private key for key agreement from a Privacy-Enhanced Mail /// PEM) representation. /// /// - Parameters: /// - pemRepresentation: A PEM representation of the key. - public init(pemRepresentation: String) throws { + public init(pemRepresentation: String) throws(CryptoKitMetaError) { let pem = try ASN1.PEMDocument(pemString: pemRepresentation) switch pem.type { @@ -415,13 +432,14 @@ extension P256 { throw CryptoKitASN1Error.invalidPEMDocument } } +#endif /// Creates a P-256 private key for key agreement from a Distinguished Encoding /// Rules (DER) encoded representation. /// /// - Parameters: /// - derRepresentation: A DER-encoded representation of the key. - public init(derRepresentation: Bytes) throws where Bytes.Element == UInt8 { + public init(derRepresentation: Bytes) throws(CryptoKitMetaError) where Bytes.Element == UInt8 { let bytes = Array(derRepresentation) // We have to try to parse this twice because we have no information about what kind of key this is. @@ -461,11 +479,13 @@ extension P256 { return Data(serializer.serializedBytes) } +#if !hasFeature(Embedded) /// A Privacy-Enhanced Mail (PEM) representation of the private key. public var pemRepresentation: String { let pemDocument = ASN1.PEMDocument(type: "PRIVATE KEY", derBytes: self.derRepresentation) return pemDocument.pemString } +#endif } } } @@ -476,11 +496,11 @@ extension P384 { /// A mechanism used to create or verify a cryptographic signature using /// the NIST P-384 elliptic curve digital signature algorithm (ECDSA). @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public enum Signing { - + public enum Signing: Sendable { + /// A P-384 public key used to verify cryptographic signatures. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public struct PublicKey: NISTECPublicKey { + public struct PublicKey: NISTECPublicKey, Sendable { var impl: NISTCurvePublicKeyImpl /// Creates a P-384 public key for signing from a collection of bytes. @@ -488,7 +508,7 @@ extension P384 { /// - Parameters: /// - rawRepresentation: A raw representation of the key as a collection of /// contiguous bytes. - public init(rawRepresentation: D) throws { + public init(rawRepresentation: D) throws(CryptoKitMetaError) { impl = try NISTCurvePublicKeyImpl(rawRepresentation: rawRepresentation) } @@ -498,7 +518,7 @@ extension P384 { /// - Parameters: /// - compactRepresentation: A compact representation of the key /// as a collection of contiguous bytes. - public init(compactRepresentation: Bytes) throws { + public init(compactRepresentation: Bytes) throws(CryptoKitMetaError) { impl = try NISTCurvePublicKeyImpl(compactRepresentation: compactRepresentation) } @@ -507,7 +527,7 @@ extension P384 { /// /// - Parameters: /// - x963Representation: An ANSI x9.63 representation of the key. - public init(x963Representation: Bytes) throws { + public init(x963Representation: Bytes) throws(CryptoKitMetaError) { impl = try NISTCurvePublicKeyImpl(x963Representation: x963Representation) } @@ -517,29 +537,31 @@ extension P384 { /// - Parameters: /// - compressedRepresentation: A compressed representation of the key as a collection /// of contiguous bytes. - public init(compressedRepresentation: Bytes) throws { + public init(compressedRepresentation: Bytes) throws(CryptoKitMetaError) { impl = try NISTCurvePublicKeyImpl(compressedRepresentation: compressedRepresentation) } +#if !hasFeature(Embedded) /// Creates a P-384 public key for signing from a Privacy-Enhanced Mail /// (PEM) representation. /// /// - Parameters: /// - pemRepresentation: A PEM representation of the key. - public init(pemRepresentation: String) throws { + public init(pemRepresentation: String) throws(CryptoKitMetaError) { let pem = try ASN1.PEMDocument(pemString: pemRepresentation) guard pem.type == "PUBLIC KEY" else { throw CryptoKitASN1Error.invalidPEMDocument } self = try .init(derRepresentation: pem.derBytes) } +#endif /// Creates a P-384 public key for signing from a Distinguished Encoding /// Rules (DER) encoded representation. /// /// - Parameters: /// - derRepresentation: A DER-encoded representation of the key. - public init(derRepresentation: Bytes) throws where Bytes.Element == UInt8 { + public init(derRepresentation: Bytes) throws(CryptoKitMetaError) where Bytes.Element == UInt8 { let bytes = Array(derRepresentation) let parsed = try ASN1.SubjectPublicKeyInfo(asn1Encoded: bytes) self = try .init(x963Representation: parsed.key) @@ -571,16 +593,18 @@ extension P384 { return Data(serializer.serializedBytes) } +#if !hasFeature(Embedded) /// A Privacy-Enhanced Mail (PEM) representation of the public key. public var pemRepresentation: String { let pemDocument = ASN1.PEMDocument(type: "PUBLIC KEY", derBytes: self.derRepresentation) return pemDocument.pemString } +#endif } /// A P-384 private key used to create cryptographic signatures. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public struct PrivateKey: NISTECPrivateKey { + public struct PrivateKey: NISTECPrivateKey, Sendable { let impl: NISTCurvePrivateKeyImpl /// Creates a random P-384 private key for signing. @@ -601,7 +625,7 @@ extension P384 { /// /// - Parameters: /// - x963Representation: An ANSI x9.63 representation of the key. - public init(x963Representation: Bytes) throws { + public init(x963Representation: Bytes) throws(CryptoKitMetaError) { impl = try NISTCurvePrivateKeyImpl(x963: x963Representation) } @@ -610,16 +634,17 @@ extension P384 { /// - Parameters: /// - rawRepresentation: A raw representation of the key as a collection of /// contiguous bytes. - public init(rawRepresentation: Bytes) throws { + public init(rawRepresentation: Bytes) throws(CryptoKitMetaError) { impl = try NISTCurvePrivateKeyImpl(data: rawRepresentation) } +#if !hasFeature(Embedded) /// Creates a P-384 private key for signing from a Privacy-Enhanced Mail /// PEM) representation. /// /// - Parameters: /// - pemRepresentation: A PEM representation of the key. - public init(pemRepresentation: String) throws { + public init(pemRepresentation: String) throws(CryptoKitMetaError) { let pem = try ASN1.PEMDocument(pemString: pemRepresentation) switch pem.type { @@ -633,13 +658,14 @@ extension P384 { throw CryptoKitASN1Error.invalidPEMDocument } } +#endif /// Creates a P-384 private key for signing from a Distinguished Encoding /// Rules (DER) encoded representation. /// /// - Parameters: /// - derRepresentation: A DER-encoded representation of the key. - public init(derRepresentation: Bytes) throws where Bytes.Element == UInt8 { + public init(derRepresentation: Bytes) throws(CryptoKitMetaError) where Bytes.Element == UInt8 { let bytes = Array(derRepresentation) // We have to try to parse this twice because we have no information about what kind of key this is. @@ -679,11 +705,13 @@ extension P384 { return Data(serializer.serializedBytes) } +#if !hasFeature(Embedded) /// A Privacy-Enhanced Mail (PEM) representation of the private key. public var pemRepresentation: String { let pemDocument = ASN1.PEMDocument(type: "PRIVATE KEY", derBytes: self.derRepresentation) return pemDocument.pemString } +#endif } } } @@ -695,11 +723,11 @@ extension P384 { /// performing NIST P-384 elliptic curve Diffie Hellman (ECDH) key /// exchange. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public enum KeyAgreement { - + public enum KeyAgreement: Sendable { + /// A P-384 public key used for key agreement. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public struct PublicKey: NISTECPublicKey { + public struct PublicKey: NISTECPublicKey, Sendable { var impl: NISTCurvePublicKeyImpl /// Creates a P-384 public key for key agreement from a collection of bytes. @@ -707,7 +735,7 @@ extension P384 { /// - Parameters: /// - rawRepresentation: A raw representation of the key as a collection of /// contiguous bytes. - public init(rawRepresentation: D) throws { + public init(rawRepresentation: D) throws(CryptoKitMetaError) { impl = try NISTCurvePublicKeyImpl(rawRepresentation: rawRepresentation) } @@ -717,7 +745,7 @@ extension P384 { /// - Parameters: /// - compactRepresentation: A compact representation of the key /// as a collection of contiguous bytes. - public init(compactRepresentation: Bytes) throws { + public init(compactRepresentation: Bytes) throws(CryptoKitMetaError) { impl = try NISTCurvePublicKeyImpl(compactRepresentation: compactRepresentation) } @@ -726,7 +754,7 @@ extension P384 { /// /// - Parameters: /// - x963Representation: An ANSI x9.63 representation of the key. - public init(x963Representation: Bytes) throws { + public init(x963Representation: Bytes) throws(CryptoKitMetaError) { impl = try NISTCurvePublicKeyImpl(x963Representation: x963Representation) } @@ -736,29 +764,31 @@ extension P384 { /// - Parameters: /// - compressedRepresentation: A compressed representation of the key as a collection /// of contiguous bytes. - public init(compressedRepresentation: Bytes) throws { + public init(compressedRepresentation: Bytes) throws(CryptoKitMetaError) { impl = try NISTCurvePublicKeyImpl(compressedRepresentation: compressedRepresentation) } +#if !hasFeature(Embedded) /// Creates a P-384 public key for key agreement from a Privacy-Enhanced Mail /// (PEM) representation. /// /// - Parameters: /// - pemRepresentation: A PEM representation of the key. - public init(pemRepresentation: String) throws { + public init(pemRepresentation: String) throws(CryptoKitMetaError) { let pem = try ASN1.PEMDocument(pemString: pemRepresentation) guard pem.type == "PUBLIC KEY" else { throw CryptoKitASN1Error.invalidPEMDocument } self = try .init(derRepresentation: pem.derBytes) } +#endif /// Creates a P-384 public key for key agreement from a Distinguished Encoding /// Rules (DER) encoded representation. /// /// - Parameters: /// - derRepresentation: A DER-encoded representation of the key. - public init(derRepresentation: Bytes) throws where Bytes.Element == UInt8 { + public init(derRepresentation: Bytes) throws(CryptoKitMetaError) where Bytes.Element == UInt8 { let bytes = Array(derRepresentation) let parsed = try ASN1.SubjectPublicKeyInfo(asn1Encoded: bytes) self = try .init(x963Representation: parsed.key) @@ -790,16 +820,18 @@ extension P384 { return Data(serializer.serializedBytes) } +#if !hasFeature(Embedded) /// A Privacy-Enhanced Mail (PEM) representation of the public key. public var pemRepresentation: String { let pemDocument = ASN1.PEMDocument(type: "PUBLIC KEY", derBytes: self.derRepresentation) return pemDocument.pemString } +#endif } /// A P-384 private key used for key agreement. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public struct PrivateKey: NISTECPrivateKey { + public struct PrivateKey: NISTECPrivateKey, Sendable { let impl: NISTCurvePrivateKeyImpl /// Creates a random P-384 private key for key agreement. @@ -820,7 +852,7 @@ extension P384 { /// /// - Parameters: /// - x963Representation: An ANSI x9.63 representation of the key. - public init(x963Representation: Bytes) throws { + public init(x963Representation: Bytes) throws(CryptoKitMetaError) { impl = try NISTCurvePrivateKeyImpl(x963: x963Representation) } @@ -829,16 +861,17 @@ extension P384 { /// - Parameters: /// - rawRepresentation: A raw representation of the key as a collection of /// contiguous bytes. - public init(rawRepresentation: Bytes) throws { + public init(rawRepresentation: Bytes) throws(CryptoKitMetaError) { impl = try NISTCurvePrivateKeyImpl(data: rawRepresentation) } +#if !hasFeature(Embedded) /// Creates a P-384 private key for key agreement from a Privacy-Enhanced Mail /// PEM) representation. /// /// - Parameters: /// - pemRepresentation: A PEM representation of the key. - public init(pemRepresentation: String) throws { + public init(pemRepresentation: String) throws(CryptoKitMetaError) { let pem = try ASN1.PEMDocument(pemString: pemRepresentation) switch pem.type { @@ -852,13 +885,14 @@ extension P384 { throw CryptoKitASN1Error.invalidPEMDocument } } +#endif /// Creates a P-384 private key for key agreement from a Distinguished Encoding /// Rules (DER) encoded representation. /// /// - Parameters: /// - derRepresentation: A DER-encoded representation of the key. - public init(derRepresentation: Bytes) throws where Bytes.Element == UInt8 { + public init(derRepresentation: Bytes) throws(CryptoKitMetaError) where Bytes.Element == UInt8 { let bytes = Array(derRepresentation) // We have to try to parse this twice because we have no information about what kind of key this is. @@ -898,11 +932,13 @@ extension P384 { return Data(serializer.serializedBytes) } +#if !hasFeature(Embedded) /// A Privacy-Enhanced Mail (PEM) representation of the private key. public var pemRepresentation: String { let pemDocument = ASN1.PEMDocument(type: "PRIVATE KEY", derBytes: self.derRepresentation) return pemDocument.pemString } +#endif } } } @@ -913,11 +949,11 @@ extension P521 { /// A mechanism used to create or verify a cryptographic signature using /// the NIST P-521 elliptic curve digital signature algorithm (ECDSA). @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public enum Signing { - + public enum Signing: Sendable { + /// A P-521 public key used to verify cryptographic signatures. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public struct PublicKey: NISTECPublicKey { + public struct PublicKey: NISTECPublicKey, Sendable { var impl: NISTCurvePublicKeyImpl /// Creates a P-521 public key for signing from a collection of bytes. @@ -925,7 +961,7 @@ extension P521 { /// - Parameters: /// - rawRepresentation: A raw representation of the key as a collection of /// contiguous bytes. - public init(rawRepresentation: D) throws { + public init(rawRepresentation: D) throws(CryptoKitMetaError) { impl = try NISTCurvePublicKeyImpl(rawRepresentation: rawRepresentation) } @@ -935,7 +971,7 @@ extension P521 { /// - Parameters: /// - compactRepresentation: A compact representation of the key /// as a collection of contiguous bytes. - public init(compactRepresentation: Bytes) throws { + public init(compactRepresentation: Bytes) throws(CryptoKitMetaError) { impl = try NISTCurvePublicKeyImpl(compactRepresentation: compactRepresentation) } @@ -944,7 +980,7 @@ extension P521 { /// /// - Parameters: /// - x963Representation: An ANSI x9.63 representation of the key. - public init(x963Representation: Bytes) throws { + public init(x963Representation: Bytes) throws(CryptoKitMetaError) { impl = try NISTCurvePublicKeyImpl(x963Representation: x963Representation) } @@ -954,29 +990,31 @@ extension P521 { /// - Parameters: /// - compressedRepresentation: A compressed representation of the key as a collection /// of contiguous bytes. - public init(compressedRepresentation: Bytes) throws { + public init(compressedRepresentation: Bytes) throws(CryptoKitMetaError) { impl = try NISTCurvePublicKeyImpl(compressedRepresentation: compressedRepresentation) } +#if !hasFeature(Embedded) /// Creates a P-521 public key for signing from a Privacy-Enhanced Mail /// (PEM) representation. /// /// - Parameters: /// - pemRepresentation: A PEM representation of the key. - public init(pemRepresentation: String) throws { + public init(pemRepresentation: String) throws(CryptoKitMetaError) { let pem = try ASN1.PEMDocument(pemString: pemRepresentation) guard pem.type == "PUBLIC KEY" else { throw CryptoKitASN1Error.invalidPEMDocument } self = try .init(derRepresentation: pem.derBytes) } +#endif /// Creates a P-521 public key for signing from a Distinguished Encoding /// Rules (DER) encoded representation. /// /// - Parameters: /// - derRepresentation: A DER-encoded representation of the key. - public init(derRepresentation: Bytes) throws where Bytes.Element == UInt8 { + public init(derRepresentation: Bytes) throws(CryptoKitMetaError) where Bytes.Element == UInt8 { let bytes = Array(derRepresentation) let parsed = try ASN1.SubjectPublicKeyInfo(asn1Encoded: bytes) self = try .init(x963Representation: parsed.key) @@ -1008,16 +1046,18 @@ extension P521 { return Data(serializer.serializedBytes) } +#if !hasFeature(Embedded) /// A Privacy-Enhanced Mail (PEM) representation of the public key. public var pemRepresentation: String { let pemDocument = ASN1.PEMDocument(type: "PUBLIC KEY", derBytes: self.derRepresentation) return pemDocument.pemString } +#endif } /// A P-521 private key used to create cryptographic signatures. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public struct PrivateKey: NISTECPrivateKey { + public struct PrivateKey: NISTECPrivateKey, Sendable { let impl: NISTCurvePrivateKeyImpl /// Creates a random P-521 private key for signing. @@ -1038,7 +1078,7 @@ extension P521 { /// /// - Parameters: /// - x963Representation: An ANSI x9.63 representation of the key. - public init(x963Representation: Bytes) throws { + public init(x963Representation: Bytes) throws(CryptoKitMetaError) { impl = try NISTCurvePrivateKeyImpl(x963: x963Representation) } @@ -1047,16 +1087,17 @@ extension P521 { /// - Parameters: /// - rawRepresentation: A raw representation of the key as a collection of /// contiguous bytes. - public init(rawRepresentation: Bytes) throws { + public init(rawRepresentation: Bytes) throws(CryptoKitMetaError) { impl = try NISTCurvePrivateKeyImpl(data: rawRepresentation) } +#if !hasFeature(Embedded) /// Creates a P-521 private key for signing from a Privacy-Enhanced Mail /// PEM) representation. /// /// - Parameters: /// - pemRepresentation: A PEM representation of the key. - public init(pemRepresentation: String) throws { + public init(pemRepresentation: String) throws(CryptoKitMetaError) { let pem = try ASN1.PEMDocument(pemString: pemRepresentation) switch pem.type { @@ -1070,13 +1111,14 @@ extension P521 { throw CryptoKitASN1Error.invalidPEMDocument } } +#endif /// Creates a P-521 private key for signing from a Distinguished Encoding /// Rules (DER) encoded representation. /// /// - Parameters: /// - derRepresentation: A DER-encoded representation of the key. - public init(derRepresentation: Bytes) throws where Bytes.Element == UInt8 { + public init(derRepresentation: Bytes) throws(CryptoKitMetaError) where Bytes.Element == UInt8 { let bytes = Array(derRepresentation) // We have to try to parse this twice because we have no information about what kind of key this is. @@ -1116,11 +1158,13 @@ extension P521 { return Data(serializer.serializedBytes) } +#if !hasFeature(Embedded) /// A Privacy-Enhanced Mail (PEM) representation of the private key. public var pemRepresentation: String { let pemDocument = ASN1.PEMDocument(type: "PRIVATE KEY", derBytes: self.derRepresentation) return pemDocument.pemString } +#endif } } } @@ -1132,11 +1176,11 @@ extension P521 { /// performing NIST P-521 elliptic curve Diffie Hellman (ECDH) key /// exchange. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public enum KeyAgreement { - + public enum KeyAgreement: Sendable { + /// A P-521 public key used for key agreement. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public struct PublicKey: NISTECPublicKey { + public struct PublicKey: NISTECPublicKey, Sendable { var impl: NISTCurvePublicKeyImpl /// Creates a P-521 public key for key agreement from a collection of bytes. @@ -1144,7 +1188,7 @@ extension P521 { /// - Parameters: /// - rawRepresentation: A raw representation of the key as a collection of /// contiguous bytes. - public init(rawRepresentation: D) throws { + public init(rawRepresentation: D) throws(CryptoKitMetaError) { impl = try NISTCurvePublicKeyImpl(rawRepresentation: rawRepresentation) } @@ -1154,7 +1198,7 @@ extension P521 { /// - Parameters: /// - compactRepresentation: A compact representation of the key /// as a collection of contiguous bytes. - public init(compactRepresentation: Bytes) throws { + public init(compactRepresentation: Bytes) throws(CryptoKitMetaError) { impl = try NISTCurvePublicKeyImpl(compactRepresentation: compactRepresentation) } @@ -1163,7 +1207,7 @@ extension P521 { /// /// - Parameters: /// - x963Representation: An ANSI x9.63 representation of the key. - public init(x963Representation: Bytes) throws { + public init(x963Representation: Bytes) throws(CryptoKitMetaError) { impl = try NISTCurvePublicKeyImpl(x963Representation: x963Representation) } @@ -1173,29 +1217,31 @@ extension P521 { /// - Parameters: /// - compressedRepresentation: A compressed representation of the key as a collection /// of contiguous bytes. - public init(compressedRepresentation: Bytes) throws { + public init(compressedRepresentation: Bytes) throws(CryptoKitMetaError) { impl = try NISTCurvePublicKeyImpl(compressedRepresentation: compressedRepresentation) } +#if !hasFeature(Embedded) /// Creates a P-521 public key for key agreement from a Privacy-Enhanced Mail /// (PEM) representation. /// /// - Parameters: /// - pemRepresentation: A PEM representation of the key. - public init(pemRepresentation: String) throws { + public init(pemRepresentation: String) throws(CryptoKitMetaError) { let pem = try ASN1.PEMDocument(pemString: pemRepresentation) guard pem.type == "PUBLIC KEY" else { throw CryptoKitASN1Error.invalidPEMDocument } self = try .init(derRepresentation: pem.derBytes) } +#endif /// Creates a P-521 public key for key agreement from a Distinguished Encoding /// Rules (DER) encoded representation. /// /// - Parameters: /// - derRepresentation: A DER-encoded representation of the key. - public init(derRepresentation: Bytes) throws where Bytes.Element == UInt8 { + public init(derRepresentation: Bytes) throws(CryptoKitMetaError) where Bytes.Element == UInt8 { let bytes = Array(derRepresentation) let parsed = try ASN1.SubjectPublicKeyInfo(asn1Encoded: bytes) self = try .init(x963Representation: parsed.key) @@ -1227,16 +1273,18 @@ extension P521 { return Data(serializer.serializedBytes) } +#if !hasFeature(Embedded) /// A Privacy-Enhanced Mail (PEM) representation of the public key. public var pemRepresentation: String { let pemDocument = ASN1.PEMDocument(type: "PUBLIC KEY", derBytes: self.derRepresentation) return pemDocument.pemString } +#endif } /// A P-521 private key used for key agreement. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public struct PrivateKey: NISTECPrivateKey { + public struct PrivateKey: NISTECPrivateKey, Sendable { let impl: NISTCurvePrivateKeyImpl /// Creates a random P-521 private key for key agreement. @@ -1257,7 +1305,7 @@ extension P521 { /// /// - Parameters: /// - x963Representation: An ANSI x9.63 representation of the key. - public init(x963Representation: Bytes) throws { + public init(x963Representation: Bytes) throws(CryptoKitMetaError) { impl = try NISTCurvePrivateKeyImpl(x963: x963Representation) } @@ -1266,16 +1314,17 @@ extension P521 { /// - Parameters: /// - rawRepresentation: A raw representation of the key as a collection of /// contiguous bytes. - public init(rawRepresentation: Bytes) throws { + public init(rawRepresentation: Bytes) throws(CryptoKitMetaError) { impl = try NISTCurvePrivateKeyImpl(data: rawRepresentation) } +#if !hasFeature(Embedded) /// Creates a P-521 private key for key agreement from a Privacy-Enhanced Mail /// PEM) representation. /// /// - Parameters: /// - pemRepresentation: A PEM representation of the key. - public init(pemRepresentation: String) throws { + public init(pemRepresentation: String) throws(CryptoKitMetaError) { let pem = try ASN1.PEMDocument(pemString: pemRepresentation) switch pem.type { @@ -1289,13 +1338,14 @@ extension P521 { throw CryptoKitASN1Error.invalidPEMDocument } } +#endif /// Creates a P-521 private key for key agreement from a Distinguished Encoding /// Rules (DER) encoded representation. /// /// - Parameters: /// - derRepresentation: A DER-encoded representation of the key. - public init(derRepresentation: Bytes) throws where Bytes.Element == UInt8 { + public init(derRepresentation: Bytes) throws(CryptoKitMetaError) where Bytes.Element == UInt8 { let bytes = Array(derRepresentation) // We have to try to parse this twice because we have no information about what kind of key this is. @@ -1335,11 +1385,13 @@ extension P521 { return Data(serializer.serializedBytes) } +#if !hasFeature(Embedded) /// A Privacy-Enhanced Mail (PEM) representation of the private key. public var pemRepresentation: String { let pemDocument = ASN1.PEMDocument(type: "PRIVATE KEY", derBytes: self.derRepresentation) return pemDocument.pemString } +#endif } } } @@ -1353,8 +1405,8 @@ extension P256.KeyAgreement.PrivateKey: DiffieHellmanKeyAgreement { /// - publicKeyShare: The public key from another party to be combined with the private /// key from this user to create the shared secret. /// - Returns: The computed shared secret. - public func sharedSecretFromKeyAgreement(with publicKeyShare: P256.KeyAgreement.PublicKey) throws -> SharedSecret { - #if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API + public func sharedSecretFromKeyAgreement(with publicKeyShare: P256.KeyAgreement.PublicKey) throws(CryptoKitMetaError) -> SharedSecret { + #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION return try self.coreCryptoSharedSecretFromKeyAgreement(with: publicKeyShare) #else return try self.openSSLSharedSecretFromKeyAgreement(with: publicKeyShare) @@ -1370,8 +1422,8 @@ extension P384.KeyAgreement.PrivateKey: DiffieHellmanKeyAgreement { /// - publicKeyShare: The public key from another party to be combined with the private /// key from this user to create the shared secret. /// - Returns: The computed shared secret. - public func sharedSecretFromKeyAgreement(with publicKeyShare: P384.KeyAgreement.PublicKey) throws -> SharedSecret { - #if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API + public func sharedSecretFromKeyAgreement(with publicKeyShare: P384.KeyAgreement.PublicKey) throws(CryptoKitMetaError) -> SharedSecret { + #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION return try self.coreCryptoSharedSecretFromKeyAgreement(with: publicKeyShare) #else return try self.openSSLSharedSecretFromKeyAgreement(with: publicKeyShare) @@ -1387,8 +1439,8 @@ extension P521.KeyAgreement.PrivateKey: DiffieHellmanKeyAgreement { /// - publicKeyShare: The public key from another party to be combined with the private /// key from this user to create the shared secret. /// - Returns: The computed shared secret. - public func sharedSecretFromKeyAgreement(with publicKeyShare: P521.KeyAgreement.PublicKey) throws -> SharedSecret { - #if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API + public func sharedSecretFromKeyAgreement(with publicKeyShare: P521.KeyAgreement.PublicKey) throws(CryptoKitMetaError) -> SharedSecret { + #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION return try self.coreCryptoSharedSecretFromKeyAgreement(with: publicKeyShare) #else return try self.openSSLSharedSecretFromKeyAgreement(with: publicKeyShare) diff --git a/Sources/Crypto/Key Agreement/ECDH.swift.gyb b/Sources/Crypto/Key Agreement/ECDH.swift.gyb index d4aae6b7a..3976519b3 100644 --- a/Sources/Crypto/Key Agreement/ECDH.swift.gyb +++ b/Sources/Crypto/Key Agreement/ECDH.swift.gyb @@ -14,7 +14,7 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else -#if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +#if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION typealias NISTCurvePublicKeyImpl = CoreCryptoNISTCurvePublicKeyImpl typealias NISTCurvePrivateKeyImpl = CoreCryptoNISTCurvePrivateKeyImpl #else @@ -22,7 +22,11 @@ typealias NISTCurvePublicKeyImpl = OpenSSLNISTCurvePublicKeyImpl typealias NISTCurvePrivateKeyImpl = OpenSSLNISTCurvePrivateKeyImpl #endif -import Foundation +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +public import SwiftSystem +#else +public import Foundation +#endif // MARK: - Generated file, do NOT edit // any edits of this file WILL be overwritten and thus discarded @@ -46,8 +50,8 @@ extension ${CURVE} { /// performing NIST ${DISPLAY_CURVE} elliptic curve Diffie Hellman (ECDH) key /// exchange. % end - public enum ${FUNC} { - + public enum ${FUNC}: Sendable { + % if FUNC == "Signing": %{ READABLE_FUNC = "signing" }% /// A ${DISPLAY_CURVE} public key used to verify cryptographic signatures. @@ -55,7 +59,7 @@ extension ${CURVE} { %{ READABLE_FUNC = "key agreement" }% /// A ${DISPLAY_CURVE} public key used for key agreement. % end - public struct PublicKey: NISTECPublicKey { + public struct PublicKey: NISTECPublicKey, Sendable { var impl: NISTCurvePublicKeyImpl<${CURVE}> /// Creates a ${DISPLAY_CURVE} public key for ${READABLE_FUNC} from a collection of bytes. @@ -63,7 +67,7 @@ extension ${CURVE} { /// - Parameters: /// - rawRepresentation: A raw representation of the key as a collection of /// contiguous bytes. - public init(rawRepresentation: D) throws { + public init(rawRepresentation: D) throws(CryptoKitMetaError) { impl = try NISTCurvePublicKeyImpl(rawRepresentation: rawRepresentation) } @@ -73,7 +77,7 @@ extension ${CURVE} { /// - Parameters: /// - compactRepresentation: A compact representation of the key /// as a collection of contiguous bytes. - public init(compactRepresentation: Bytes) throws { + public init(compactRepresentation: Bytes) throws(CryptoKitMetaError) { impl = try NISTCurvePublicKeyImpl(compactRepresentation: compactRepresentation) } @@ -82,7 +86,7 @@ extension ${CURVE} { /// /// - Parameters: /// - x963Representation: An ANSI x9.63 representation of the key. - public init(x963Representation: Bytes) throws { + public init(x963Representation: Bytes) throws(CryptoKitMetaError) { impl = try NISTCurvePublicKeyImpl(x963Representation: x963Representation) } @@ -92,29 +96,31 @@ extension ${CURVE} { /// - Parameters: /// - compressedRepresentation: A compressed representation of the key as a collection /// of contiguous bytes. - public init(compressedRepresentation: Bytes) throws { + public init(compressedRepresentation: Bytes) throws(CryptoKitMetaError) { impl = try NISTCurvePublicKeyImpl(compressedRepresentation: compressedRepresentation) } +#if !hasFeature(Embedded) /// Creates a ${DISPLAY_CURVE} public key for ${READABLE_FUNC} from a Privacy-Enhanced Mail /// (PEM) representation. /// /// - Parameters: /// - pemRepresentation: A PEM representation of the key. - public init(pemRepresentation: String) throws { + public init(pemRepresentation: String) throws(CryptoKitMetaError) { let pem = try ASN1.PEMDocument(pemString: pemRepresentation) guard pem.type == "PUBLIC KEY" else { throw CryptoKitASN1Error.invalidPEMDocument } self = try .init(derRepresentation: pem.derBytes) } +#endif /// Creates a ${DISPLAY_CURVE} public key for ${READABLE_FUNC} from a Distinguished Encoding /// Rules (DER) encoded representation. /// /// - Parameters: /// - derRepresentation: A DER-encoded representation of the key. - public init(derRepresentation: Bytes) throws where Bytes.Element == UInt8 { + public init(derRepresentation: Bytes) throws(CryptoKitMetaError) where Bytes.Element == UInt8 { let bytes = Array(derRepresentation) let parsed = try ASN1.SubjectPublicKeyInfo(asn1Encoded: bytes) self = try .init(x963Representation: parsed.key) @@ -146,11 +152,13 @@ extension ${CURVE} { return Data(serializer.serializedBytes) } +#if !hasFeature(Embedded) /// A Privacy-Enhanced Mail (PEM) representation of the public key. public var pemRepresentation: String { let pemDocument = ASN1.PEMDocument(type: "PUBLIC KEY", derBytes: self.derRepresentation) return pemDocument.pemString } +#endif } % if FUNC == "Signing": @@ -158,7 +166,7 @@ extension ${CURVE} { % else: /// A ${DISPLAY_CURVE} private key used for key agreement. % end - public struct PrivateKey: NISTECPrivateKey { + public struct PrivateKey: NISTECPrivateKey, Sendable { let impl: NISTCurvePrivateKeyImpl<${CURVE}> /// Creates a random ${DISPLAY_CURVE} private key for ${READABLE_FUNC}. @@ -179,7 +187,7 @@ extension ${CURVE} { /// /// - Parameters: /// - x963Representation: An ANSI x9.63 representation of the key. - public init(x963Representation: Bytes) throws { + public init(x963Representation: Bytes) throws(CryptoKitMetaError) { impl = try NISTCurvePrivateKeyImpl(x963: x963Representation) } @@ -188,16 +196,17 @@ extension ${CURVE} { /// - Parameters: /// - rawRepresentation: A raw representation of the key as a collection of /// contiguous bytes. - public init(rawRepresentation: Bytes) throws { + public init(rawRepresentation: Bytes) throws(CryptoKitMetaError) { impl = try NISTCurvePrivateKeyImpl(data: rawRepresentation) } +#if !hasFeature(Embedded) /// Creates a ${DISPLAY_CURVE} private key for ${READABLE_FUNC} from a Privacy-Enhanced Mail /// PEM) representation. /// /// - Parameters: /// - pemRepresentation: A PEM representation of the key. - public init(pemRepresentation: String) throws { + public init(pemRepresentation: String) throws(CryptoKitMetaError) { let pem = try ASN1.PEMDocument(pemString: pemRepresentation) switch pem.type { @@ -211,13 +220,14 @@ extension ${CURVE} { throw CryptoKitASN1Error.invalidPEMDocument } } +#endif /// Creates a ${DISPLAY_CURVE} private key for ${READABLE_FUNC} from a Distinguished Encoding /// Rules (DER) encoded representation. /// /// - Parameters: /// - derRepresentation: A DER-encoded representation of the key. - public init(derRepresentation: Bytes) throws where Bytes.Element == UInt8 { + public init(derRepresentation: Bytes) throws(CryptoKitMetaError) where Bytes.Element == UInt8 { let bytes = Array(derRepresentation) // We have to try to parse this twice because we have no information about what kind of key this is. @@ -257,11 +267,13 @@ extension ${CURVE} { return Data(serializer.serializedBytes) } +#if !hasFeature(Embedded) /// A Privacy-Enhanced Mail (PEM) representation of the private key. public var pemRepresentation: String { let pemDocument = ASN1.PEMDocument(type: "PRIVATE KEY", derBytes: self.derRepresentation) return pemDocument.pemString } +#endif } } } @@ -277,8 +289,8 @@ extension ${CURVE}.KeyAgreement.PrivateKey: DiffieHellmanKeyAgreement { /// - publicKeyShare: The public key from another party to be combined with the private /// key from this user to create the shared secret. /// - Returns: The computed shared secret. - public func sharedSecretFromKeyAgreement(with publicKeyShare: ${CURVE}.KeyAgreement.PublicKey) throws -> SharedSecret { - #if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API + public func sharedSecretFromKeyAgreement(with publicKeyShare: ${CURVE}.KeyAgreement.PublicKey) throws(CryptoKitMetaError) -> SharedSecret { + #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION return try self.coreCryptoSharedSecretFromKeyAgreement(with: publicKeyShare) #else return try self.openSSLSharedSecretFromKeyAgreement(with: publicKeyShare) diff --git a/Sources/Crypto/Key Derivation/ANSIx963.swift b/Sources/Crypto/Key Derivation/ANSIx963.swift new file mode 100644 index 000000000..e222a5680 --- /dev/null +++ b/Sources/Crypto/Key Derivation/ANSIx963.swift @@ -0,0 +1,72 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2019-2020 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +@_exported import CryptoKit +#else + +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +public import SwiftSystem +#else +public import Foundation +#endif + +@_spi(ANSIKDF) +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +public struct ANSIKDFx963: Sendable { + public static func deriveKey(inputKeyMaterial: SymmetricKey, info: Info, outputByteCount: Int) -> SymmetricKey { + + guard UInt64(outputByteCount) < (UInt64(H.Digest.byteCount) * UInt64(UInt32.max)) else { + fatalError("Invalid parameter size") + } + + var key = SecureBytes() + key.reserveCapacity(outputByteCount) + + var remainingBytes = outputByteCount + var counter = UInt32(1) + + while remainingBytes > 0 { + // 1. Compute: Ki = Hash(Z || Counter || [SharedInfo]). + var hasher = H() + inputKeyMaterial.withUnsafeBytes { ikmBytes in + hasher.update(data: ikmBytes) + } + hasher.update(counter.bigEndian) + hasher.update(data: info) + let digest = hasher.finalize() + + // 2. Increment Counter. + counter += 1 + + // Append the bytes of the digest. We don't want to append more than the remaining number of bytes. + let bytesToAppend = min(remainingBytes, H.Digest.byteCount) + digest.withUnsafeBytes { digestPtr in + key.append(digestPtr.prefix(bytesToAppend)) + } + remainingBytes -= bytesToAppend + } + + precondition(key.count == outputByteCount) + return SymmetricKey(data: key) + } + + public static func deriveKey(inputKeyMaterial: SymmetricKey, + outputByteCount: Int) -> SymmetricKey { + return deriveKey(inputKeyMaterial: inputKeyMaterial, info: [UInt8](), outputByteCount: outputByteCount) + } +} + + +#endif + diff --git a/Sources/Crypto/Key Derivation/HKDF.swift b/Sources/Crypto/Key Derivation/HKDF.swift index 9208634b1..e3d12d165 100644 --- a/Sources/Crypto/Key Derivation/HKDF.swift +++ b/Sources/Crypto/Key Derivation/HKDF.swift @@ -14,9 +14,11 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else -import Foundation -#if canImport(Android) -import Android + +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +public import SwiftSystem +#else +public import Foundation #endif /// A standards-based implementation of an HMAC-based Key Derivation Function @@ -35,7 +37,7 @@ import Android /// ``expand(pseudoRandomKey:info:outputByteCount:)`` using that key material to /// generate a symmetric key of the length you specify. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -public struct HKDF { +public struct HKDF: Sendable { /// Derives a symmetric encryption key from a main key or passcode using /// HKDF key derivation with information and salt you specify. /// @@ -116,7 +118,7 @@ public struct HKDF { /// hashed authentication code. public static func extract(inputKeyMaterial: SymmetricKey, salt: Salt?) -> HashedAuthenticationCode { let key: SymmetricKey - if let salt = salt { + if let salt { if salt.regions.count != 1 { let contiguousBytes = Array(salt) key = SymmetricKey(data: contiguousBytes) @@ -146,21 +148,23 @@ public struct HKDF { /// /// - Returns: The derived symmetric key. public static func expand(pseudoRandomKey prk: PRK, info: Info?, outputByteCount: Int) -> SymmetricKey { - let iterations: UInt8 = UInt8(ceil((Float(outputByteCount) / Float(H.Digest.byteCount)))) + + let iterations: UInt8 = UInt8((Double(outputByteCount) / Double(H.Digest.byteCount)).rounded(.up)) + var output = SecureBytes() let key = SymmetricKey(data: prk) var TMinusOne = SecureBytes() for i in 1...iterations { var hmac = HMAC(key: key) hmac.update(data: TMinusOne) - if let info = info { + if let info { hmac.update(data: info) } withUnsafeBytes(of: i) { counter in hmac.update(bufferPointer: counter) } - TMinusOne = SecureBytes(hmac.finalize()) + TMinusOne = SecureBytes(bytes: hmac.finalize()) output.append(TMinusOne) } diff --git a/Sources/Crypto/Key Wrapping/AESWrap.swift b/Sources/Crypto/Key Wrapping/AESWrap.swift index 33626e6da..8558dd7e8 100644 --- a/Sources/Crypto/Key Wrapping/AESWrap.swift +++ b/Sources/Crypto/Key Wrapping/AESWrap.swift @@ -2,7 +2,7 @@ // // This source file is part of the SwiftCrypto open source project // -// Copyright (c) 2019-2021 Apple Inc. and the SwiftCrypto project authors +// Copyright (c) 2019-2020 Apple Inc. and the SwiftCrypto project authors // Licensed under Apache License v2.0 // // See LICENSE.txt for license information @@ -14,9 +14,14 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else -import Foundation -#if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +public import SwiftSystem +#else +public import Foundation +#endif + +#if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) typealias AESWRAPImpl = CoreCryptoAESWRAPImpl #else @@ -29,7 +34,7 @@ extension AES { /// An implementation of AES Key Wrapping in accordance with the IETF RFC /// 3394 specification. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public enum KeyWrap { + public enum KeyWrap: Sendable { /// Wraps a key using the AES wrap algorithm. /// /// Wrap is an implementation of the AES key wrap algorithm as specified diff --git a/Sources/Crypto/Keys/EC/Curve25519.swift b/Sources/Crypto/Keys/EC/Curve25519.swift index 9f8b4a13b..83d6a6085 100644 --- a/Sources/Crypto/Keys/EC/Curve25519.swift +++ b/Sources/Crypto/Keys/EC/Curve25519.swift @@ -16,5 +16,5 @@ #else /// An elliptic curve that enables X25519 key agreement and Ed25519 signatures. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -public enum Curve25519 {} +public enum Curve25519: Sendable {} #endif // Linux or !SwiftPM diff --git a/Sources/Crypto/Keys/EC/Ed25519Keys.swift b/Sources/Crypto/Keys/EC/Ed25519Keys.swift index a5ba229e7..a35bde781 100644 --- a/Sources/Crypto/Keys/EC/Ed25519Keys.swift +++ b/Sources/Crypto/Keys/EC/Ed25519Keys.swift @@ -14,7 +14,11 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else -import Foundation +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +public import SwiftSystem +#else +public import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension Curve25519.Signing { @@ -28,8 +32,8 @@ extension Curve25519 { /// A mechanism used to create or verify a cryptographic signature using /// Ed25519. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public enum Signing { - #if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API + public enum Signing: Sendable { + #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION typealias Curve25519PrivateKeyImpl = Curve25519.Signing.CoreCryptoCurve25519PrivateKeyImpl typealias Curve25519PublicKeyImpl = Curve25519.Signing.CoreCryptoCurve25519PublicKeyImpl #else @@ -39,7 +43,7 @@ extension Curve25519 { /// A Curve25519 private key used to create cryptographic signatures. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public struct PrivateKey: ECPrivateKey { + public struct PrivateKey: ECPrivateKey, Sendable { private var baseKey: Curve25519.Signing.Curve25519PrivateKeyImpl /// Creates a random Curve25519 private key for signing. @@ -58,7 +62,7 @@ extension Curve25519 { /// - Parameters: /// - data: A representation of the key as contiguous bytes from /// which to create the key. - public init(rawRepresentation data: D) throws { + public init(rawRepresentation data: D) throws(CryptoKitMetaError) { self.baseKey = try Curve25519.Signing.Curve25519PrivateKeyImpl(rawRepresentation: data) } @@ -75,7 +79,7 @@ extension Curve25519 { /// A Curve25519 public key used to verify cryptographic signatures. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public struct PublicKey { + public struct PublicKey: Sendable { private var baseKey: Curve25519.Signing.Curve25519PublicKeyImpl /// Creates a Curve25519 public key from a data representation. @@ -83,7 +87,7 @@ extension Curve25519 { /// - Parameters: /// - rawRepresentation: A representation of the key as contiguous /// bytes from which to create the key. - public init(rawRepresentation: D) throws { + public init(rawRepresentation: D) throws(CryptoKitMetaError) { self.baseKey = try Curve25519.Signing.Curve25519PublicKeyImpl(rawRepresentation: rawRepresentation) } diff --git a/Sources/Crypto/Keys/EC/NISTCurvesKeys.swift b/Sources/Crypto/Keys/EC/NISTCurvesKeys.swift index 2bb00bb38..41c23f03d 100644 --- a/Sources/Crypto/Keys/EC/NISTCurvesKeys.swift +++ b/Sources/Crypto/Keys/EC/NISTCurvesKeys.swift @@ -11,12 +11,16 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else import Foundation +#endif #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else -#if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +#if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) typealias SupportedCurveDetailsImpl = CorecryptoSupportedNISTCurve #else @@ -54,13 +58,13 @@ protocol NISTECPrivateKey: ECPrivateKey where PK: NISTECPublicKey { /// An elliptic curve that enables NIST P-256 signatures and key agreement. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -public enum P256 { } +public enum P256: Sendable { } /// An elliptic curve that enables NIST P-384 signatures and key agreement. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -public enum P384 { } +public enum P384: Sendable { } /// An elliptic curve that enables NIST P-521 signatures and key agreement. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -public enum P521 { } +public enum P521: Sendable { } #endif // Linux or !SwiftPM diff --git a/Sources/Crypto/Keys/EC/X25519Keys.swift b/Sources/Crypto/Keys/EC/X25519Keys.swift index 78b26e128..ffd319ee9 100644 --- a/Sources/Crypto/Keys/EC/X25519Keys.swift +++ b/Sources/Crypto/Keys/EC/X25519Keys.swift @@ -14,7 +14,11 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else -import Foundation +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +public import SwiftSystem +#else +public import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension Curve25519.KeyAgreement { @@ -28,8 +32,8 @@ extension Curve25519 { /// A mechanism used to create a shared secret between two users by /// performing X25519 key agreement. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public enum KeyAgreement { - #if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API + public enum KeyAgreement: Sendable { + #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION typealias Curve25519PrivateKeyImpl = Curve25519.KeyAgreement.CoreCryptoCurve25519PrivateKeyImpl typealias Curve25519PublicKeyImpl = Curve25519.KeyAgreement.CoreCryptoCurve25519PublicKeyImpl #else @@ -39,7 +43,7 @@ extension Curve25519 { /// A Curve25519 public key used for key agreement. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public struct PublicKey: ECPublicKey { + public struct PublicKey: ECPublicKey, Sendable { fileprivate var baseKey: Curve25519PublicKeyImpl /// Creates a Curve25519 public key for key agreement from a @@ -48,7 +52,7 @@ extension Curve25519 { /// - Parameters: /// - rawRepresentation: A raw representation of the key as a /// collection of contiguous bytes. - public init(rawRepresentation: D) throws { + public init(rawRepresentation: D) throws(CryptoKitMetaError) { self.baseKey = try Curve25519PublicKeyImpl(rawRepresentation: rawRepresentation) } @@ -66,14 +70,20 @@ extension Curve25519 { return self.baseKey.keyBytes } + #if hasFeature(Embedded) + private func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws(E) -> R) throws(E) -> R { + return try self.baseKey.keyBytes.withUnsafeBytes(body) + } + #else private func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R { return try self.baseKey.keyBytes.withUnsafeBytes(body) } + #endif } /// A Curve25519 private key used for key agreement. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public struct PrivateKey: DiffieHellmanKeyAgreement { + public struct PrivateKey: DiffieHellmanKeyAgreement, Sendable { fileprivate var baseKey: Curve25519PrivateKeyImpl /// Creates a random Curve25519 private key for key agreement. @@ -92,7 +102,7 @@ extension Curve25519 { /// - Parameters: /// - rawRepresentation: A raw representation of the key as a /// collection of contiguous bytes. - public init(rawRepresentation: D) throws { + public init(rawRepresentation: D) throws(CryptoKitMetaError) { self.baseKey = try Curve25519PrivateKeyImpl(rawRepresentation: rawRepresentation) } @@ -105,7 +115,7 @@ extension Curve25519 { /// shared secret. /// /// - Returns: The computed shared secret. - public func sharedSecretFromKeyAgreement(with publicKeyShare: Curve25519.KeyAgreement.PublicKey) throws -> SharedSecret { + public func sharedSecretFromKeyAgreement(with publicKeyShare: Curve25519.KeyAgreement.PublicKey) throws(CryptoKitMetaError) -> SharedSecret { return try self.baseKey.sharedSecretFromKeyAgreement(with: publicKeyShare.baseKey) } diff --git a/Sources/Crypto/Keys/Symmetric/SymmetricKeys.swift b/Sources/Crypto/Keys/Symmetric/SymmetricKeys.swift index dfc842204..2e7535591 100644 --- a/Sources/Crypto/Keys/Symmetric/SymmetricKeys.swift +++ b/Sources/Crypto/Keys/Symmetric/SymmetricKeys.swift @@ -14,7 +14,12 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else -import Foundation + +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else +public import Foundation +#endif /// The sizes that a symmetric cryptographic key can take. /// @@ -24,7 +29,7 @@ import Foundation /// need a key with a non-standard length, use the ``init(bitCount:)`` /// initializer to create a `SymmetricKeySize` instance with a custom bit count. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -public struct SymmetricKeySize { +public struct SymmetricKeySize: Sendable { /// The number of bits in the key. public let bitCount: Int @@ -65,7 +70,7 @@ public struct SymmetricKeySize { /// open and close a sealed box (``ChaChaPoly/SealedBox`` or /// ``AES/GCM/SealedBox``) using a cipher like ``ChaChaPoly`` or ``AES``. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -public struct SymmetricKey: ContiguousBytes { +public struct SymmetricKey: ContiguousBytes, Sendable { let sb: SecureBytes /// Invokes the given closure with a buffer pointer covering the raw bytes @@ -76,9 +81,15 @@ public struct SymmetricKey: ContiguousBytes { /// key and returns the key. /// /// - Returns: The key, as returned from the body closure. + #if hasFeature(Embedded) + public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws(E) -> R) throws(E) -> R { + return try sb.withUnsafeBytes(body) + } + #else public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R { return try sb.withUnsafeBytes(body) } + #endif /// Creates a key from the given data. /// @@ -99,9 +110,15 @@ public struct SymmetricKey: ContiguousBytes { self.init(key: SecureBytes(count: Int(size.bitCount / 8))) } + #if hasFeature(Embedded) + internal init(unsafeUninitializedCapacity: Int, initializingWith callback: (inout UnsafeMutableRawBufferPointer, inout Int) throws(E) -> Void) throws(E) { + self.init(key: try SecureBytes(unsafeUninitializedCapacity: unsafeUninitializedCapacity, initializingWith: callback)) + } + #else internal init(unsafeUninitializedCapacity: Int, initializingWith callback: (inout UnsafeMutableRawBufferPointer, inout Int) throws -> Void) rethrows { self.init(key: try SecureBytes(unsafeUninitializedCapacity: unsafeUninitializedCapacity, initializingWith: callback)) } + #endif // Fast-path alias for cases whe know we have a SecureBytes object. internal init(data: SecureBytes) { diff --git a/Sources/Crypto/Message Authentication Codes/HMAC/HMAC.swift b/Sources/Crypto/Message Authentication Codes/HMAC/HMAC.swift index 3d7221854..207a6d953 100644 --- a/Sources/Crypto/Message Authentication Codes/HMAC/HMAC.swift +++ b/Sources/Crypto/Message Authentication Codes/HMAC/HMAC.swift @@ -14,7 +14,11 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else -import Foundation +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +public import SwiftSystem +#else +public import Foundation +#endif /// A hash-based message authentication algorithm. /// @@ -30,7 +34,7 @@ import Foundation /// ``AES`` or ``ChaChaPoly`` to put the data into a sealed box (an instance of /// ``AES/GCM/SealedBox`` or ``ChaChaPoly/SealedBox``). @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -public struct HMAC: MACAlgorithm { +public struct HMAC: MACAlgorithm, Sendable { /// An alias for the symmetric key type used to compute or verify a message /// authentication code. public typealias Key = SymmetricKey @@ -61,8 +65,7 @@ public struct HMAC: MACAlgorithm { #if os(iOS) && (arch(arm) || arch(i386)) fatalError("Unsupported architecture") #else - var K: ContiguousBytes - + var K: SymmetricKey if key.byteCount == H.blockByteCount { K = key } else if key.byteCount > H.blockByteCount { @@ -71,15 +74,15 @@ public struct HMAC: MACAlgorithm { K = key.withUnsafeBytes { (keyBytes) in let hash = H.hash(bufferPointer: keyBytes) - return hash.withUnsafeBytes({ (hashBytes) in + return SymmetricKey(data: hash.withUnsafeBytes({ (hashBytes) in memcpy(&array, hashBytes.baseAddress!, hashBytes.count) return array - }) + })) } } else { var keyArray = Array(repeating: UInt8(0), count: H.blockByteCount) key.withUnsafeBytes { keyArray.replaceSubrange(0..<$0.count, with: $0) } - K = keyArray + K = SymmetricKey(data: keyArray) } self.innerHasher = H() @@ -195,7 +198,7 @@ public struct HMAC: MACAlgorithm { /// A hash-based message authentication code. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -public struct HashedAuthenticationCode: MessageAuthenticationCode { +public struct HashedAuthenticationCode: MessageAuthenticationCode, Sendable { let digest: H.Digest /// The number of bytes in the message authentication code. @@ -203,11 +206,13 @@ public struct HashedAuthenticationCode: MessageAuthenticationCo return H.Digest.byteCount } +#if !hasFeature(Embedded) /// A human-readable description of the code. public var description: String { return "HMAC with \(H.self): \(Array(digest).hexString)" } - +#endif + /// Invokes the given closure with a buffer pointer covering the raw bytes /// of the code. /// @@ -216,8 +221,14 @@ public struct HashedAuthenticationCode: MessageAuthenticationCo /// code and returns the code. /// /// - Returns: The code, as returned from the body closure. + #if hasFeature(Embedded) + public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws(E) -> R) throws(E) -> R { + return try digest.withUnsafeBytes(body) + } + #else public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R { return try digest.withUnsafeBytes(body) } + #endif } #endif // Linux or !SwiftPM diff --git a/Sources/Crypto/Message Authentication Codes/MACFunctions.swift b/Sources/Crypto/Message Authentication Codes/MACFunctions.swift index 851d49123..02132a861 100644 --- a/Sources/Crypto/Message Authentication Codes/MACFunctions.swift +++ b/Sources/Crypto/Message Authentication Codes/MACFunctions.swift @@ -14,12 +14,16 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) protocol MACAlgorithm { associatedtype Key - #if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API + #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION associatedtype MAC: CryptoKit.MessageAuthenticationCode #else associatedtype MAC: Crypto.MessageAuthenticationCode diff --git a/Sources/Crypto/Message Authentication Codes/MessageAuthenticationCode.swift b/Sources/Crypto/Message Authentication Codes/MessageAuthenticationCode.swift index a5b881b57..4c546139f 100644 --- a/Sources/Crypto/Message Authentication Codes/MessageAuthenticationCode.swift +++ b/Sources/Crypto/Message Authentication Codes/MessageAuthenticationCode.swift @@ -14,14 +14,29 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else -import Foundation +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +public import SwiftSystem +#else +public import Foundation +#endif +#if hasFeature(Embedded) /// A type that represents a message authentication code. +@preconcurrency @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -public protocol MessageAuthenticationCode: Hashable, ContiguousBytes, CustomStringConvertible, Sequence where Element == UInt8 { +public protocol MessageAuthenticationCode: Hashable, ContiguousBytes, Sendable, Sequence where Element == UInt8 { /// The number of bytes in the message authentication code. var byteCount: Int { get } } +#else +/// A type that represents a message authentication code. +@preconcurrency +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +public protocol MessageAuthenticationCode: Hashable, ContiguousBytes, Sendable, CustomStringConvertible, Sequence where Element == UInt8 { + /// The number of bytes in the message authentication code. + var byteCount: Int { get } +} +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MessageAuthenticationCode { @@ -61,9 +76,11 @@ extension MessageAuthenticationCode { return Array(buffPtr.bindMemory(to: UInt8.self)).makeIterator() }) } - + +#if !hasFeature(Embedded) public var description: String { return "\(Self.self): \(Array(self).hexString)" } +#endif } #endif // Linux or !SwiftPM diff --git a/Sources/Crypto/PRF/AES.swift b/Sources/Crypto/PRF/AES.swift index da5d082b3..bd58060fd 100644 --- a/Sources/Crypto/PRF/AES.swift +++ b/Sources/Crypto/PRF/AES.swift @@ -16,7 +16,7 @@ #else /// A container for Advanced Encryption Standard (AES) ciphers. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -public enum AES { +public enum AES: Sendable { static let blockSizeByteCount = 16 } diff --git a/Sources/_CryptoExtras/MLDSA/MLDSA_boring.swift b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift similarity index 88% rename from Sources/_CryptoExtras/MLDSA/MLDSA_boring.swift rename to Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift index 51941f563..f784d36f2 100644 --- a/Sources/_CryptoExtras/MLDSA/MLDSA_boring.swift +++ b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift @@ -12,26 +12,27 @@ // //===----------------------------------------------------------------------===// +#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +@_exported import CryptoKit +#else +@_implementationOnly import CCryptoBoringSSL +import Foundation + // MARK: - Generated file, do NOT edit // any edits of this file WILL be overwritten and thus discarded // see section `gyb` in `README` for details. @_implementationOnly import CCryptoBoringSSL -import Crypto import Foundation -/// A module-lattice-based digital signature algorithm that provides security against quantum computing attacks. -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -public enum MLDSA65 {} - @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLDSA65 { /// A ML-DSA-65 private key. - public struct PrivateKey: Sendable { + struct InternalPrivateKey: Sendable { private var backing: Backing /// Initialize a ML-DSA-65 private key from a random seed. - public init() throws { + init() throws { self.backing = try Backing() } @@ -40,17 +41,17 @@ extension MLDSA65 { /// - Parameter seedRepresentation: The seed to use to generate the private key. /// /// - Throws: `CryptoKitError.incorrectKeySize` if the seed is not 32 bytes long. - public init(seedRepresentation: some DataProtocol) throws { + init(seedRepresentation: some DataProtocol) throws { self.backing = try Backing(seedRepresentation: seedRepresentation) } /// The seed from which this private key was generated. - public var seedRepresentation: Data { + var seedRepresentation: Data { self.backing.seed } /// The public key associated with this private key. - public var publicKey: PublicKey { + var publicKey: InternalPublicKey { self.backing.publicKey } @@ -59,7 +60,7 @@ extension MLDSA65 { /// - Parameter data: The message to sign. /// /// - Returns: The signature of the message. - public func signature(for data: D) throws -> Data { + func signature(for data: D) throws -> Data { let context: Data? = nil return try self.backing.signature(for: data, context: context) } @@ -71,7 +72,7 @@ extension MLDSA65 { /// - context: The context to use for the signature. /// /// - Returns: The signature of the message. - public func signature(for data: D, context: C) throws -> Data { + func signature(for data: D, context: C) throws -> Data { try self.backing.signature(for: data, context: context) } @@ -94,7 +95,7 @@ extension MLDSA65 { ) { seedPtr in try withUnsafeTemporaryAllocation( of: UInt8.self, - capacity: MLDSA65.PublicKey.Backing.byteCount + capacity: MLDSA65.InternalPublicKey.Backing.byteCount ) { publicKeyPtr in guard CCryptoBoringSSL_MLDSA65_generate_key( @@ -138,8 +139,8 @@ extension MLDSA65 { } /// The public key associated with this private key. - var publicKey: PublicKey { - PublicKey(privateKeyBacking: self) + var publicKey: InternalPublicKey { + InternalPublicKey(privateKeyBacking: self) } /// Generate a signature for the given data. @@ -184,10 +185,10 @@ extension MLDSA65 { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLDSA65 { /// A ML-DSA-65 public key. - public struct PublicKey: Sendable { + struct InternalPublicKey: Sendable { private var backing: Backing - fileprivate init(privateKeyBacking: PrivateKey.Backing) { + fileprivate init(privateKeyBacking: InternalPrivateKey.Backing) { self.backing = Backing(privateKeyBacking: privateKeyBacking) } @@ -196,12 +197,12 @@ extension MLDSA65 { /// - Parameter rawRepresentation: The public key bytes. /// /// - Throws: `CryptoKitError.incorrectKeySize` if the raw representation is not the correct size. - public init(rawRepresentation: some DataProtocol) throws { + init(rawRepresentation: some DataProtocol) throws { self.backing = try Backing(rawRepresentation: rawRepresentation) } /// The raw binary representation of the public key. - public var rawRepresentation: Data { + var rawRepresentation: Data { self.backing.rawRepresentation } @@ -212,7 +213,7 @@ extension MLDSA65 { /// - data: The message to verify the signature against. /// /// - Returns: `true` if the signature is valid, `false` otherwise. - public func isValidSignature(_ signature: S, for data: D) -> Bool { + func isValidSignature(_ signature: S, for data: D) -> Bool { let context: Data? = nil return self.backing.isValidSignature(signature, for: data, context: context) } @@ -225,7 +226,7 @@ extension MLDSA65 { /// - context: The context to use for the signature verification. /// /// - Returns: `true` if the signature is valid, `false` otherwise. - public func isValidSignature( + func isValidSignature( _ signature: S, for data: D, context: C @@ -239,7 +240,7 @@ extension MLDSA65 { fileprivate final class Backing { private var key: MLDSA65_public_key - init(privateKeyBacking: PrivateKey.Backing) { + init(privateKeyBacking: InternalPrivateKey.Backing) { self.key = .init() CCryptoBoringSSL_MLDSA65_public_from_private(&self.key, &privateKeyBacking.key) } @@ -250,7 +251,7 @@ extension MLDSA65 { /// /// - Throws: `CryptoKitError.incorrectKeySize` if the raw representation is not the correct size. init(rawRepresentation: some DataProtocol) throws { - guard rawRepresentation.count == MLDSA65.PublicKey.Backing.byteCount else { + guard rawRepresentation.count == MLDSA65.InternalPublicKey.Backing.byteCount else { throw CryptoKitError.incorrectKeySize } @@ -274,7 +275,7 @@ extension MLDSA65 { var rawRepresentation: Data { var cbb = CBB() // The following BoringSSL functions can only fail on allocation failure, which we define as impossible. - CCryptoBoringSSL_CBB_init(&cbb, MLDSA65.PublicKey.Backing.byteCount) + CCryptoBoringSSL_CBB_init(&cbb, MLDSA65.InternalPublicKey.Backing.byteCount) defer { CCryptoBoringSSL_CBB_cleanup(&cbb) } CCryptoBoringSSL_MLDSA65_marshal_public_key(&cbb, &self.key) return Data(bytes: CCryptoBoringSSL_CBB_data(&cbb), count: CCryptoBoringSSL_CBB_len(&cbb)) @@ -326,18 +327,14 @@ extension MLDSA65 { private static let signatureByteCount = Int(MLDSA65_SIGNATURE_BYTES) } -/// A module-lattice-based digital signature algorithm that provides security against quantum computing attacks. -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -public enum MLDSA87 {} - @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLDSA87 { /// A ML-DSA-87 private key. - public struct PrivateKey: Sendable { + struct InternalPrivateKey: Sendable { private var backing: Backing /// Initialize a ML-DSA-87 private key from a random seed. - public init() throws { + init() throws { self.backing = try Backing() } @@ -346,17 +343,17 @@ extension MLDSA87 { /// - Parameter seedRepresentation: The seed to use to generate the private key. /// /// - Throws: `CryptoKitError.incorrectKeySize` if the seed is not 32 bytes long. - public init(seedRepresentation: some DataProtocol) throws { + init(seedRepresentation: some DataProtocol) throws { self.backing = try Backing(seedRepresentation: seedRepresentation) } /// The seed from which this private key was generated. - public var seedRepresentation: Data { + var seedRepresentation: Data { self.backing.seed } /// The public key associated with this private key. - public var publicKey: PublicKey { + var publicKey: InternalPublicKey { self.backing.publicKey } @@ -365,7 +362,7 @@ extension MLDSA87 { /// - Parameter data: The message to sign. /// /// - Returns: The signature of the message. - public func signature(for data: D) throws -> Data { + func signature(for data: D) throws -> Data { let context: Data? = nil return try self.backing.signature(for: data, context: context) } @@ -377,7 +374,7 @@ extension MLDSA87 { /// - context: The context to use for the signature. /// /// - Returns: The signature of the message. - public func signature(for data: D, context: C) throws -> Data { + func signature(for data: D, context: C) throws -> Data { try self.backing.signature(for: data, context: context) } @@ -400,7 +397,7 @@ extension MLDSA87 { ) { seedPtr in try withUnsafeTemporaryAllocation( of: UInt8.self, - capacity: MLDSA87.PublicKey.Backing.byteCount + capacity: MLDSA87.InternalPublicKey.Backing.byteCount ) { publicKeyPtr in guard CCryptoBoringSSL_MLDSA87_generate_key( @@ -444,8 +441,8 @@ extension MLDSA87 { } /// The public key associated with this private key. - var publicKey: PublicKey { - PublicKey(privateKeyBacking: self) + var publicKey: InternalPublicKey { + InternalPublicKey(privateKeyBacking: self) } /// Generate a signature for the given data. @@ -490,10 +487,10 @@ extension MLDSA87 { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLDSA87 { /// A ML-DSA-87 public key. - public struct PublicKey: Sendable { + struct InternalPublicKey: Sendable { private var backing: Backing - fileprivate init(privateKeyBacking: PrivateKey.Backing) { + fileprivate init(privateKeyBacking: InternalPrivateKey.Backing) { self.backing = Backing(privateKeyBacking: privateKeyBacking) } @@ -502,12 +499,12 @@ extension MLDSA87 { /// - Parameter rawRepresentation: The public key bytes. /// /// - Throws: `CryptoKitError.incorrectKeySize` if the raw representation is not the correct size. - public init(rawRepresentation: some DataProtocol) throws { + init(rawRepresentation: some DataProtocol) throws { self.backing = try Backing(rawRepresentation: rawRepresentation) } /// The raw binary representation of the public key. - public var rawRepresentation: Data { + var rawRepresentation: Data { self.backing.rawRepresentation } @@ -518,7 +515,7 @@ extension MLDSA87 { /// - data: The message to verify the signature against. /// /// - Returns: `true` if the signature is valid, `false` otherwise. - public func isValidSignature(_ signature: S, for data: D) -> Bool { + func isValidSignature(_ signature: S, for data: D) -> Bool { let context: Data? = nil return self.backing.isValidSignature(signature, for: data, context: context) } @@ -531,7 +528,7 @@ extension MLDSA87 { /// - context: The context to use for the signature verification. /// /// - Returns: `true` if the signature is valid, `false` otherwise. - public func isValidSignature( + func isValidSignature( _ signature: S, for data: D, context: C @@ -545,7 +542,7 @@ extension MLDSA87 { fileprivate final class Backing { private var key: MLDSA87_public_key - init(privateKeyBacking: PrivateKey.Backing) { + init(privateKeyBacking: InternalPrivateKey.Backing) { self.key = .init() CCryptoBoringSSL_MLDSA87_public_from_private(&self.key, &privateKeyBacking.key) } @@ -556,7 +553,7 @@ extension MLDSA87 { /// /// - Throws: `CryptoKitError.incorrectKeySize` if the raw representation is not the correct size. init(rawRepresentation: some DataProtocol) throws { - guard rawRepresentation.count == MLDSA87.PublicKey.Backing.byteCount else { + guard rawRepresentation.count == MLDSA87.InternalPublicKey.Backing.byteCount else { throw CryptoKitError.incorrectKeySize } @@ -580,7 +577,7 @@ extension MLDSA87 { var rawRepresentation: Data { var cbb = CBB() // The following BoringSSL functions can only fail on allocation failure, which we define as impossible. - CCryptoBoringSSL_CBB_init(&cbb, MLDSA87.PublicKey.Backing.byteCount) + CCryptoBoringSSL_CBB_init(&cbb, MLDSA87.InternalPublicKey.Backing.byteCount) defer { CCryptoBoringSSL_CBB_cleanup(&cbb) } CCryptoBoringSSL_MLDSA87_marshal_public_key(&cbb, &self.key) return Data(bytes: CCryptoBoringSSL_CBB_data(&cbb), count: CCryptoBoringSSL_CBB_len(&cbb)) @@ -632,7 +629,9 @@ extension MLDSA87 { private static let signatureByteCount = Int(MLDSA87_SIGNATURE_BYTES) } -private enum MLDSA { +enum MLDSA { /// The size of the seed in bytes. fileprivate static let seedByteCount = 32 } + +#endif // CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API diff --git a/Sources/_CryptoExtras/MLDSA/MLDSA_boring.swift.gyb b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb similarity index 90% rename from Sources/_CryptoExtras/MLDSA/MLDSA_boring.swift.gyb rename to Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb index 91a86c18d..ed70dd236 100644 --- a/Sources/_CryptoExtras/MLDSA/MLDSA_boring.swift.gyb +++ b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb @@ -12,30 +12,31 @@ // //===----------------------------------------------------------------------===// +#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +@_exported import CryptoKit +#else +@_implementationOnly import CCryptoBoringSSL +import Foundation + // MARK: - Generated file, do NOT edit // any edits of this file WILL be overwritten and thus discarded // see section `gyb` in `README` for details. @_implementationOnly import CCryptoBoringSSL -import Crypto import Foundation %{ parameter_sets = ["65", "87"] }% % for parameter_set in parameter_sets: -/// A module-lattice-based digital signature algorithm that provides security against quantum computing attacks. -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -public enum MLDSA${parameter_set} {} - @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLDSA${parameter_set} { /// A ML-DSA-${parameter_set} private key. - public struct PrivateKey: Sendable { + struct InternalPrivateKey: Sendable { private var backing: Backing /// Initialize a ML-DSA-${parameter_set} private key from a random seed. - public init() throws { + init() throws { self.backing = try Backing() } @@ -44,17 +45,17 @@ extension MLDSA${parameter_set} { /// - Parameter seedRepresentation: The seed to use to generate the private key. /// /// - Throws: `CryptoKitError.incorrectKeySize` if the seed is not 32 bytes long. - public init(seedRepresentation: some DataProtocol) throws { + init(seedRepresentation: some DataProtocol) throws { self.backing = try Backing(seedRepresentation: seedRepresentation) } /// The seed from which this private key was generated. - public var seedRepresentation: Data { + var seedRepresentation: Data { self.backing.seed } /// The public key associated with this private key. - public var publicKey: PublicKey { + var publicKey: InternalPublicKey { self.backing.publicKey } @@ -63,7 +64,7 @@ extension MLDSA${parameter_set} { /// - Parameter data: The message to sign. /// /// - Returns: The signature of the message. - public func signature(for data: D) throws -> Data { + func signature(for data: D) throws -> Data { let context: Data? = nil return try self.backing.signature(for: data, context: context) } @@ -75,7 +76,7 @@ extension MLDSA${parameter_set} { /// - context: The context to use for the signature. /// /// - Returns: The signature of the message. - public func signature(for data: D, context: C) throws -> Data { + func signature(for data: D, context: C) throws -> Data { try self.backing.signature(for: data, context: context) } @@ -98,7 +99,7 @@ extension MLDSA${parameter_set} { ) { seedPtr in try withUnsafeTemporaryAllocation( of: UInt8.self, - capacity: MLDSA${parameter_set}.PublicKey.Backing.byteCount + capacity: MLDSA${parameter_set}.InternalPublicKey.Backing.byteCount ) { publicKeyPtr in guard CCryptoBoringSSL_MLDSA${parameter_set}_generate_key( @@ -142,8 +143,8 @@ extension MLDSA${parameter_set} { } /// The public key associated with this private key. - var publicKey: PublicKey { - PublicKey(privateKeyBacking: self) + var publicKey: InternalPublicKey { + InternalPublicKey(privateKeyBacking: self) } /// Generate a signature for the given data. @@ -188,10 +189,10 @@ extension MLDSA${parameter_set} { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLDSA${parameter_set} { /// A ML-DSA-${parameter_set} public key. - public struct PublicKey: Sendable { + struct InternalPublicKey: Sendable { private var backing: Backing - fileprivate init(privateKeyBacking: PrivateKey.Backing) { + fileprivate init(privateKeyBacking: InternalPrivateKey.Backing) { self.backing = Backing(privateKeyBacking: privateKeyBacking) } @@ -200,12 +201,12 @@ extension MLDSA${parameter_set} { /// - Parameter rawRepresentation: The public key bytes. /// /// - Throws: `CryptoKitError.incorrectKeySize` if the raw representation is not the correct size. - public init(rawRepresentation: some DataProtocol) throws { + init(rawRepresentation: some DataProtocol) throws { self.backing = try Backing(rawRepresentation: rawRepresentation) } /// The raw binary representation of the public key. - public var rawRepresentation: Data { + var rawRepresentation: Data { self.backing.rawRepresentation } @@ -216,7 +217,7 @@ extension MLDSA${parameter_set} { /// - data: The message to verify the signature against. /// /// - Returns: `true` if the signature is valid, `false` otherwise. - public func isValidSignature(_ signature: S, for data: D) -> Bool { + func isValidSignature(_ signature: S, for data: D) -> Bool { let context: Data? = nil return self.backing.isValidSignature(signature, for: data, context: context) } @@ -229,7 +230,7 @@ extension MLDSA${parameter_set} { /// - context: The context to use for the signature verification. /// /// - Returns: `true` if the signature is valid, `false` otherwise. - public func isValidSignature( + func isValidSignature( _ signature: S, for data: D, context: C @@ -243,7 +244,7 @@ extension MLDSA${parameter_set} { fileprivate final class Backing { private var key: MLDSA${parameter_set}_public_key - init(privateKeyBacking: PrivateKey.Backing) { + init(privateKeyBacking: InternalPrivateKey.Backing) { self.key = .init() CCryptoBoringSSL_MLDSA${parameter_set}_public_from_private(&self.key, &privateKeyBacking.key) } @@ -254,7 +255,7 @@ extension MLDSA${parameter_set} { /// /// - Throws: `CryptoKitError.incorrectKeySize` if the raw representation is not the correct size. init(rawRepresentation: some DataProtocol) throws { - guard rawRepresentation.count == MLDSA${parameter_set}.PublicKey.Backing.byteCount else { + guard rawRepresentation.count == MLDSA${parameter_set}.InternalPublicKey.Backing.byteCount else { throw CryptoKitError.incorrectKeySize } @@ -278,7 +279,7 @@ extension MLDSA${parameter_set} { var rawRepresentation: Data { var cbb = CBB() // The following BoringSSL functions can only fail on allocation failure, which we define as impossible. - CCryptoBoringSSL_CBB_init(&cbb, MLDSA${parameter_set}.PublicKey.Backing.byteCount) + CCryptoBoringSSL_CBB_init(&cbb, MLDSA${parameter_set}.InternalPublicKey.Backing.byteCount) defer { CCryptoBoringSSL_CBB_cleanup(&cbb) } CCryptoBoringSSL_MLDSA${parameter_set}_marshal_public_key(&cbb, &self.key) return Data(bytes: CCryptoBoringSSL_CBB_data(&cbb), count: CCryptoBoringSSL_CBB_len(&cbb)) @@ -331,7 +332,9 @@ extension MLDSA${parameter_set} { } % end -private enum MLDSA { +enum MLDSA { /// The size of the seed in bytes. fileprivate static let seedByteCount = 32 } + +#endif // CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API diff --git a/Sources/Crypto/Signatures/BoringSSL/MLDSA_wrapper.swift b/Sources/Crypto/Signatures/BoringSSL/MLDSA_wrapper.swift new file mode 100644 index 000000000..5d18b7d74 --- /dev/null +++ b/Sources/Crypto/Signatures/BoringSSL/MLDSA_wrapper.swift @@ -0,0 +1,150 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2025 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +@_exported import CryptoKit +#else +@_implementationOnly import CCryptoBoringSSL +import Foundation + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +protocol BoringSSLBackedMLDSAPrivateKey { + associatedtype AssociatedPublicKey: BoringSSLBackedMLDSAPublicKey + + init() throws + + init(seedRepresentation: D) throws + + func signature(for data: D) throws -> Data + + func signature(for data: D, context: C) throws -> Data + + var publicKey: AssociatedPublicKey { get } + + var seedRepresentation: Data { get } +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +protocol BoringSSLBackedMLDSAPublicKey { + init(rawRepresentation: D) throws + + func isValidSignature(_: S, for data: D) -> Bool + + func isValidSignature(_: S, for data: D, context: C) -> Bool + + var rawRepresentation: Data { get } +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +protocol BoringSSLBackedMLDSAParameters { + associatedtype BackingPrivateKey: BoringSSLBackedMLDSAPrivateKey + where BackingPrivateKey.AssociatedPublicKey == BackingPublicKey + associatedtype BackingPublicKey: BoringSSLBackedMLDSAPublicKey +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension MLDSA65: BoringSSLBackedMLDSAParameters { + typealias BackingPrivateKey = MLDSA65.InternalPrivateKey + typealias BackingPublicKey = MLDSA65.InternalPublicKey +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension MLDSA87: BoringSSLBackedMLDSAParameters { + typealias BackingPrivateKey = MLDSA87.InternalPrivateKey + typealias BackingPublicKey = MLDSA87.InternalPublicKey +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension MLDSA65.InternalPrivateKey: BoringSSLBackedMLDSAPrivateKey {} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension MLDSA65.InternalPublicKey: BoringSSLBackedMLDSAPublicKey {} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension MLDSA87.InternalPrivateKey: BoringSSLBackedMLDSAPrivateKey {} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension MLDSA87.InternalPublicKey: BoringSSLBackedMLDSAPublicKey {} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +struct OpenSSLMLDSAPrivateKeyImpl { + private var backing: Parameters.BackingPrivateKey + + init() throws { + self.backing = try .init() + } + + init(seedRepresentation: D, publicKey: OpenSSLMLDSAPublicKeyImpl?) throws { + precondition(publicKey == nil) + self.backing = try .init(seedRepresentation: seedRepresentation) + } + + init(integrityCheckedRepresentation: D) throws { + fatalError() + } + + func signature(for data: D) throws -> Data { + try self.backing.signature(for: data) + } + + func signature(for data: D, context: C) throws -> Data { + try self.backing.signature(for: data, context: context) + } + + var publicKey: OpenSSLMLDSAPublicKeyImpl { + .init(backing: self.backing.publicKey) + } + + var seedRepresentation: Data { + self.backing.seedRepresentation + } + + var integrityCheckedRepresentation: Data { + fatalError() + } +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +struct OpenSSLMLDSAPublicKeyImpl { + private var backing: Parameters.BackingPublicKey + + fileprivate init(backing: Parameters.BackingPublicKey) { + self.backing = backing + } + + init(rawRepresentation: D) throws { + self.backing = try .init(rawRepresentation: rawRepresentation) + } + + func isValidSignature( + signature: S, + for data: D + ) -> Bool { + self.backing.isValidSignature(signature, for: data) + } + + func isValidSignature( + signature: S, + for data: D, + context: C + ) -> Bool { + self.backing.isValidSignature(signature, for: data, context: context) + } + + var rawRepresentation: Data { + self.backing.rawRepresentation + } +} + +#endif // CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API diff --git a/Sources/Crypto/Signatures/ECDSA.swift b/Sources/Crypto/Signatures/ECDSA.swift index 84959ee52..85261a9f5 100644 --- a/Sources/Crypto/Signatures/ECDSA.swift +++ b/Sources/Crypto/Signatures/ECDSA.swift @@ -14,15 +14,19 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else -import Foundation +#if !CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +public import Foundation +#else +public import SwiftSystem +#endif // MARK: - Generated file, do NOT edit // any edits of this file WILL be overwritten and thus discarded // see section `gyb` in `README` for details. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) protocol NISTECDSASignature { - init(rawRepresentation: D) throws - init(derRepresentation: D) throws + init(rawRepresentation: D) throws(CryptoKitMetaError) + init(derRepresentation: D) throws(CryptoKitMetaError) var derRepresentation: Data { get } var rawRepresentation: Data { get } } @@ -40,8 +44,8 @@ extension P256.Signing { /// A P-256 elliptic curve digital signature algorithm (ECDSA) signature. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public struct ECDSASignature: ContiguousBytes, NISTECDSASignature { - + public struct ECDSASignature: ContiguousBytes, NISTECDSASignature, Sendable { + /// A raw data representation of a P-256 digital signature. public var rawRepresentation: Data @@ -50,17 +54,17 @@ extension P256.Signing { /// - Parameters: /// - rawRepresentation: A raw representation of the signature as a /// collection of contiguous bytes. - public init(rawRepresentation: D) throws { + public init(rawRepresentation: D) throws(CryptoKitMetaError) { guard rawRepresentation.count == 2 * P256.coordinateByteCount else { - throw CryptoKitError.incorrectParameterSize + throw error(CryptoKitError.incorrectParameterSize) } self.rawRepresentation = Data(rawRepresentation) } - internal init(_ dataRepresentation: Data) throws { + internal init(_ dataRepresentation: Data) throws(CryptoKitMetaError) { guard dataRepresentation.count == 2 * P256.coordinateByteCount else { - throw CryptoKitError.incorrectParameterSize + throw error(CryptoKitError.incorrectParameterSize) } self.rawRepresentation = dataRepresentation @@ -79,7 +83,7 @@ extension P256.Signing { /// - Parameters: /// - derRepresentation: The DER-encoded representation of the /// signature. - public init(derRepresentation: D) throws { + public init(derRepresentation: D) throws(CryptoKitMetaError) { #if os(iOS) && (arch(arm) || arch(i386)) fatalError("Unsupported architecture") #else @@ -89,7 +93,7 @@ extension P256.Signing { let coordinateByteCount = P256.coordinateByteCount guard signature.r.count <= coordinateByteCount && signature.s.count <= coordinateByteCount else { - throw CryptoKitError.incorrectParameterSize + throw error(CryptoKitError.incorrectParameterSize) } // r and s must be padded out to the coordinate byte count. @@ -107,9 +111,15 @@ extension P256.Signing { /// Invokes the given closure with a buffer pointer covering the raw /// bytes of the signature. +#if hasFeature(Embedded) + public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws(E) -> R) throws(E) -> R { + try self.rawRepresentation.withUnsafeBytes(body) + } +#else public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R { try self.rawRepresentation.withUnsafeBytes(body) } +#endif /// A Distinguished Encoding Rules (DER) encoded representation of a /// P-256 digital signature. @@ -145,8 +155,8 @@ extension P256.Signing.PrivateKey: DigestSigner { /// - Returns: The signature corresponding to the digest. The signing /// algorithm employs randomization to generate a different signature on /// every call, even for the same data and key. - public func signature(for digest: D) throws -> P256.Signing.ECDSASignature { - #if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API + public func signature(for digest: D) throws(CryptoKitMetaError) -> P256.Signing.ECDSASignature { + #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION return try self.coreCryptoSignature(for: digest) #else return try self.openSSLSignature(for: digest) @@ -165,7 +175,7 @@ extension P256.Signing.PrivateKey: Signer { /// - Returns: The signature corresponding to the data. The signing /// algorithm employs randomization to generate a different signature on /// every call, even for the same data and key. - public func signature(for data: D) throws -> P256.Signing.ECDSASignature { + public func signature(for data: D) throws(CryptoKitMetaError) -> P256.Signing.ECDSASignature { return try self.signature(for: SHA256.hash(data: data)) } } @@ -181,7 +191,7 @@ extension P256.Signing.PublicKey: DigestValidator { /// - Returns: A Boolean value that’s `true` if the signature is valid for /// the given digest; otherwise, `false`. public func isValidSignature(_ signature: P256.Signing.ECDSASignature, for digest: D) -> Bool { - #if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API + #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION return self.coreCryptoIsValidSignature(signature, for: digest) #else return self.openSSLIsValidSignature(signature, for: digest) @@ -210,8 +220,8 @@ extension P384.Signing { /// A P-384 elliptic curve digital signature algorithm (ECDSA) signature. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public struct ECDSASignature: ContiguousBytes, NISTECDSASignature { - + public struct ECDSASignature: ContiguousBytes, NISTECDSASignature, Sendable { + /// A raw data representation of a P-384 digital signature. public var rawRepresentation: Data @@ -220,17 +230,17 @@ extension P384.Signing { /// - Parameters: /// - rawRepresentation: A raw representation of the signature as a /// collection of contiguous bytes. - public init(rawRepresentation: D) throws { + public init(rawRepresentation: D) throws(CryptoKitMetaError) { guard rawRepresentation.count == 2 * P384.coordinateByteCount else { - throw CryptoKitError.incorrectParameterSize + throw error(CryptoKitError.incorrectParameterSize) } self.rawRepresentation = Data(rawRepresentation) } - internal init(_ dataRepresentation: Data) throws { + internal init(_ dataRepresentation: Data) throws(CryptoKitMetaError) { guard dataRepresentation.count == 2 * P384.coordinateByteCount else { - throw CryptoKitError.incorrectParameterSize + throw error(CryptoKitError.incorrectParameterSize) } self.rawRepresentation = dataRepresentation @@ -249,7 +259,7 @@ extension P384.Signing { /// - Parameters: /// - derRepresentation: The DER-encoded representation of the /// signature. - public init(derRepresentation: D) throws { + public init(derRepresentation: D) throws(CryptoKitMetaError) { #if os(iOS) && (arch(arm) || arch(i386)) fatalError("Unsupported architecture") #else @@ -259,7 +269,7 @@ extension P384.Signing { let coordinateByteCount = P384.coordinateByteCount guard signature.r.count <= coordinateByteCount && signature.s.count <= coordinateByteCount else { - throw CryptoKitError.incorrectParameterSize + throw error(CryptoKitError.incorrectParameterSize) } // r and s must be padded out to the coordinate byte count. @@ -277,9 +287,15 @@ extension P384.Signing { /// Invokes the given closure with a buffer pointer covering the raw /// bytes of the signature. +#if hasFeature(Embedded) + public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws(E) -> R) throws(E) -> R { + try self.rawRepresentation.withUnsafeBytes(body) + } +#else public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R { try self.rawRepresentation.withUnsafeBytes(body) } +#endif /// A Distinguished Encoding Rules (DER) encoded representation of a /// P-384 digital signature. @@ -315,8 +331,8 @@ extension P384.Signing.PrivateKey: DigestSigner { /// - Returns: The signature corresponding to the digest. The signing /// algorithm employs randomization to generate a different signature on /// every call, even for the same data and key. - public func signature(for digest: D) throws -> P384.Signing.ECDSASignature { - #if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API + public func signature(for digest: D) throws(CryptoKitMetaError) -> P384.Signing.ECDSASignature { + #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION return try self.coreCryptoSignature(for: digest) #else return try self.openSSLSignature(for: digest) @@ -335,7 +351,7 @@ extension P384.Signing.PrivateKey: Signer { /// - Returns: The signature corresponding to the data. The signing /// algorithm employs randomization to generate a different signature on /// every call, even for the same data and key. - public func signature(for data: D) throws -> P384.Signing.ECDSASignature { + public func signature(for data: D) throws(CryptoKitMetaError) -> P384.Signing.ECDSASignature { return try self.signature(for: SHA384.hash(data: data)) } } @@ -351,7 +367,7 @@ extension P384.Signing.PublicKey: DigestValidator { /// - Returns: A Boolean value that’s `true` if the signature is valid for /// the given digest; otherwise, `false`. public func isValidSignature(_ signature: P384.Signing.ECDSASignature, for digest: D) -> Bool { - #if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API + #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION return self.coreCryptoIsValidSignature(signature, for: digest) #else return self.openSSLIsValidSignature(signature, for: digest) @@ -380,8 +396,8 @@ extension P521.Signing { /// A P-521 elliptic curve digital signature algorithm (ECDSA) signature. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public struct ECDSASignature: ContiguousBytes, NISTECDSASignature { - + public struct ECDSASignature: ContiguousBytes, NISTECDSASignature, Sendable { + /// A raw data representation of a P-521 digital signature. public var rawRepresentation: Data @@ -390,17 +406,17 @@ extension P521.Signing { /// - Parameters: /// - rawRepresentation: A raw representation of the signature as a /// collection of contiguous bytes. - public init(rawRepresentation: D) throws { + public init(rawRepresentation: D) throws(CryptoKitMetaError) { guard rawRepresentation.count == 2 * P521.coordinateByteCount else { - throw CryptoKitError.incorrectParameterSize + throw error(CryptoKitError.incorrectParameterSize) } self.rawRepresentation = Data(rawRepresentation) } - internal init(_ dataRepresentation: Data) throws { + internal init(_ dataRepresentation: Data) throws(CryptoKitMetaError) { guard dataRepresentation.count == 2 * P521.coordinateByteCount else { - throw CryptoKitError.incorrectParameterSize + throw error(CryptoKitError.incorrectParameterSize) } self.rawRepresentation = dataRepresentation @@ -419,7 +435,7 @@ extension P521.Signing { /// - Parameters: /// - derRepresentation: The DER-encoded representation of the /// signature. - public init(derRepresentation: D) throws { + public init(derRepresentation: D) throws(CryptoKitMetaError) { #if os(iOS) && (arch(arm) || arch(i386)) fatalError("Unsupported architecture") #else @@ -429,7 +445,7 @@ extension P521.Signing { let coordinateByteCount = P521.coordinateByteCount guard signature.r.count <= coordinateByteCount && signature.s.count <= coordinateByteCount else { - throw CryptoKitError.incorrectParameterSize + throw error(CryptoKitError.incorrectParameterSize) } // r and s must be padded out to the coordinate byte count. @@ -447,9 +463,15 @@ extension P521.Signing { /// Invokes the given closure with a buffer pointer covering the raw /// bytes of the signature. +#if hasFeature(Embedded) + public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws(E) -> R) throws(E) -> R { + try self.rawRepresentation.withUnsafeBytes(body) + } +#else public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R { try self.rawRepresentation.withUnsafeBytes(body) } +#endif /// A Distinguished Encoding Rules (DER) encoded representation of a /// P-521 digital signature. @@ -485,8 +507,8 @@ extension P521.Signing.PrivateKey: DigestSigner { /// - Returns: The signature corresponding to the digest. The signing /// algorithm employs randomization to generate a different signature on /// every call, even for the same data and key. - public func signature(for digest: D) throws -> P521.Signing.ECDSASignature { - #if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API + public func signature(for digest: D) throws(CryptoKitMetaError) -> P521.Signing.ECDSASignature { + #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION return try self.coreCryptoSignature(for: digest) #else return try self.openSSLSignature(for: digest) @@ -505,7 +527,7 @@ extension P521.Signing.PrivateKey: Signer { /// - Returns: The signature corresponding to the data. The signing /// algorithm employs randomization to generate a different signature on /// every call, even for the same data and key. - public func signature(for data: D) throws -> P521.Signing.ECDSASignature { + public func signature(for data: D) throws(CryptoKitMetaError) -> P521.Signing.ECDSASignature { return try self.signature(for: SHA512.hash(data: data)) } } @@ -521,7 +543,7 @@ extension P521.Signing.PublicKey: DigestValidator { /// - Returns: A Boolean value that’s `true` if the signature is valid for /// the given digest; otherwise, `false`. public func isValidSignature(_ signature: P521.Signing.ECDSASignature, for digest: D) -> Bool { - #if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API + #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION return self.coreCryptoIsValidSignature(signature, for: digest) #else return self.openSSLIsValidSignature(signature, for: digest) diff --git a/Sources/Crypto/Signatures/ECDSA.swift.gyb b/Sources/Crypto/Signatures/ECDSA.swift.gyb index f297738f4..ae9564c70 100644 --- a/Sources/Crypto/Signatures/ECDSA.swift.gyb +++ b/Sources/Crypto/Signatures/ECDSA.swift.gyb @@ -14,7 +14,11 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else -import Foundation +#if !CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +public import Foundation +#else +public import SwiftSystem +#endif // MARK: - Generated file, do NOT edit // any edits of this file WILL be overwritten and thus discarded // see section `gyb` in `README` for details. @@ -23,8 +27,8 @@ import Foundation }% protocol NISTECDSASignature { - init(rawRepresentation: D) throws - init(derRepresentation: D) throws + init(rawRepresentation: D) throws(CryptoKitMetaError) + init(derRepresentation: D) throws(CryptoKitMetaError) var derRepresentation: Data { get } var rawRepresentation: Data { get } } @@ -46,8 +50,8 @@ protocol NISTSigning { extension ${CURVE}.Signing { /// A ${DISPLAY_CURVE} elliptic curve digital signature algorithm (ECDSA) signature. - public struct ECDSASignature: ContiguousBytes, NISTECDSASignature { - + public struct ECDSASignature: ContiguousBytes, NISTECDSASignature, Sendable { + /// A raw data representation of a ${DISPLAY_CURVE} digital signature. public var rawRepresentation: Data @@ -56,17 +60,17 @@ extension ${CURVE}.Signing { /// - Parameters: /// - rawRepresentation: A raw representation of the signature as a /// collection of contiguous bytes. - public init(rawRepresentation: D) throws { + public init(rawRepresentation: D) throws(CryptoKitMetaError) { guard rawRepresentation.count == 2 * ${CURVE}.coordinateByteCount else { - throw CryptoKitError.incorrectParameterSize + throw error(CryptoKitError.incorrectParameterSize) } self.rawRepresentation = Data(rawRepresentation) } - internal init(_ dataRepresentation: Data) throws { + internal init(_ dataRepresentation: Data) throws(CryptoKitMetaError) { guard dataRepresentation.count == 2 * ${CURVE}.coordinateByteCount else { - throw CryptoKitError.incorrectParameterSize + throw error(CryptoKitError.incorrectParameterSize) } self.rawRepresentation = dataRepresentation @@ -85,7 +89,7 @@ extension ${CURVE}.Signing { /// - Parameters: /// - derRepresentation: The DER-encoded representation of the /// signature. - public init(derRepresentation: D) throws { + public init(derRepresentation: D) throws(CryptoKitMetaError) { #if os(iOS) && (arch(arm) || arch(i386)) fatalError("Unsupported architecture") #else @@ -95,7 +99,7 @@ extension ${CURVE}.Signing { let coordinateByteCount = ${CURVE}.coordinateByteCount guard signature.r.count <= coordinateByteCount && signature.s.count <= coordinateByteCount else { - throw CryptoKitError.incorrectParameterSize + throw error(CryptoKitError.incorrectParameterSize) } // r and s must be padded out to the coordinate byte count. @@ -113,9 +117,15 @@ extension ${CURVE}.Signing { /// Invokes the given closure with a buffer pointer covering the raw /// bytes of the signature. +#if hasFeature(Embedded) + public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws(E) -> R) throws(E) -> R { + try self.rawRepresentation.withUnsafeBytes(body) + } +#else public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R { try self.rawRepresentation.withUnsafeBytes(body) } +#endif /// A Distinguished Encoding Rules (DER) encoded representation of a /// ${DISPLAY_CURVE} digital signature. @@ -149,8 +159,8 @@ extension ${CURVE}.Signing.PrivateKey: DigestSigner { /// - Returns: The signature corresponding to the digest. The signing /// algorithm employs randomization to generate a different signature on /// every call, even for the same data and key. - public func signature(for digest: D) throws -> ${CURVE}.Signing.ECDSASignature { - #if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API + public func signature(for digest: D) throws(CryptoKitMetaError) -> ${CURVE}.Signing.ECDSASignature { + #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION return try self.coreCryptoSignature(for: digest) #else return try self.openSSLSignature(for: digest) @@ -168,7 +178,7 @@ extension ${CURVE}.Signing.PrivateKey: Signer { /// - Returns: The signature corresponding to the data. The signing /// algorithm employs randomization to generate a different signature on /// every call, even for the same data and key. - public func signature(for data: D) throws -> ${CURVE}.Signing.ECDSASignature { + public func signature(for data: D) throws(CryptoKitMetaError) -> ${CURVE}.Signing.ECDSASignature { return try self.signature(for: ${HF}.hash(data: data)) } } @@ -183,7 +193,7 @@ extension ${CURVE}.Signing.PublicKey: DigestValidator { /// - Returns: A Boolean value that’s `true` if the signature is valid for /// the given digest; otherwise, `false`. public func isValidSignature(_ signature: ${CURVE}.Signing.ECDSASignature, for digest: D) -> Bool { - #if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API + #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION return self.coreCryptoIsValidSignature(signature, for: digest) #else return self.openSSLIsValidSignature(signature, for: digest) diff --git a/Sources/Crypto/Signatures/Ed25519.swift b/Sources/Crypto/Signatures/Ed25519.swift index a6b38b304..329ab19d4 100644 --- a/Sources/Crypto/Signatures/Ed25519.swift +++ b/Sources/Crypto/Signatures/Ed25519.swift @@ -14,7 +14,11 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else -import Foundation +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +public import SwiftSystem +#else +public import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) protocol DigestValidator { @@ -48,7 +52,7 @@ extension Curve25519.Signing.PublicKey: DataValidator { /// - Returns: A Boolean value that’s `true` when the signature is valid for /// the given data. public func isValidSignature(_ signature: S, for data: D) -> Bool { - #if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API + #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION return self.coreCryptoIsValidSignature(signature, for: data) #else return self.openSSLIsValidSignature(signature, for: data) @@ -69,8 +73,8 @@ extension Curve25519.Signing.PrivateKey: Signer { /// implementation of the algorithm employs randomization to generate a /// different signature on every call, even for the same data and key, to /// guard against side-channel attacks. - public func signature(for data: D) throws -> Data { - #if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API + public func signature(for data: D) throws(CryptoKitMetaError) -> Data { + #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION return try self.coreCryptoSignature(for: data) #else return try self.openSSLSignature(for: data) diff --git a/Sources/Crypto/Signatures/MLDSA.swift b/Sources/Crypto/Signatures/MLDSA.swift new file mode 100644 index 000000000..0a079ca45 --- /dev/null +++ b/Sources/Crypto/Signatures/MLDSA.swift @@ -0,0 +1,286 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2019-2020 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +@_exported import CryptoKit +#else +public import Foundation + +#if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +typealias MLDSAPublicKeyImpl = CoreCryptoMLDSAPublicKeyImpl +typealias MLDSAPrivateKeyImpl = CoreCryptoMLDSAPrivateKeyImpl +#else +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +typealias MLDSAPublicKeyImpl = OpenSSLMLDSAPublicKeyImpl +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +typealias MLDSAPrivateKeyImpl = OpenSSLMLDSAPrivateKeyImpl +#endif + + +/// The MLDSA65 Digital Signature Algorithm +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +public enum MLDSA65: Sendable {} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension MLDSA65 { + /// The public key for MLDSA65. + public struct PublicKey: Sendable { + var impl: MLDSAPublicKeyImpl + + /// Verifies a MLDSA65 signature. + /// - Parameters: + /// - signature: The MLDSA65 signature to verify. + /// - data: The signed data. + /// - Returns: `true` if the signature is valid, `false` otherwise. + public func isValidSignature(signature: S, for data: D) -> Bool { + self.impl.isValidSignature(signature: signature, for: data) + } + + /// Verifies a MLDSA65 signature, in a specific context. + /// - Parameters: + /// - signature: The MLDSA65 signature to verify. + /// - data: The signed data. + /// - context: Context for the signature. + /// - Returns: `true` if the signature is valid in the specified context, `false` otherwise. + public func isValidSignature(signature: S, for data: D, context: C) -> Bool { + self.impl.isValidSignature(signature: signature, for: data, context: context) + } + + /// Parses a public key from a serialized representation. + /// + /// - Parameter rawRepresentation: The public key, in the FIPS 204 standard serialization format. + /// - Returns: The deserialized public key. + public init(rawRepresentation: D) throws { + self.impl = try .init(rawRepresentation: rawRepresentation) + } + + /// A serialized representation of the public key. + /// + /// This property provides a representation of the public key in the FIPS 204 standard serialization format. + public var rawRepresentation: Data { + get { + self.impl.rawRepresentation + } + } + + fileprivate init(impl: MLDSAPublicKeyImpl) { + self.impl = impl + } + } + + /// The private key for MLDSA65. + public struct PrivateKey: Signer, Sendable { + var impl: MLDSAPrivateKeyImpl + + /// Generates a MLDSA65 signature. + /// - Parameters: + /// - data: The data to sign. + /// - Returns: The MLDSA65 signature. + /// This method throws if CryptoKit encounters an error producing the signature. + public func signature(for data: D) throws -> Data { + try self.impl.signature(for: data) + } + + /// Generates a MLDSA65 signature, with context. + /// - Parameters: + /// - data: The data to sign. + /// - context: Context for the signature. + /// - Returns: The MLDSA65 signature. + /// This method throws if CryptoKit encounters an error producing the signature. + public func signature(for data: D, context: C) throws -> Data { + try self.impl.signature(for: data, context: context) + } + + /// The associated public key. + public var publicKey: PublicKey { + get { + PublicKey(impl: self.impl.publicKey) + } + } + + /// Initializes a new random private key. + public init() throws { + self.impl = try .init() + } + + /// Initializes a private key from the seed representation. + /// + /// - Parameter seedRepresentation: The seed representation of the private key. This parameter needs to be 32 bytes long. + /// - Parameter publicKey: The public key associated with the secret key. + /// + /// This initializer implements the `ML-DSA.KeyGen_internal` algorithm (Algorithm 16) of FIPS 204. + /// + /// If a public key is provided, a consistency check is performed between it and the derived public key. + public init(seedRepresentation: D, publicKey: MLDSA65.PublicKey?) throws { + self.impl = try .init(seedRepresentation: seedRepresentation, publicKey: publicKey?.impl) + } + + /// The seed representation of the private key. + /// + /// The seed representation is 32 bytes long, and is the parameter + /// for the `ML-DSA.KeyGen_internal` algorithm (Algorithm 16) of FIPS 204. + public var seedRepresentation: Data { + get { + return self.impl.seedRepresentation + } + } + + /// Initializes a private key from an integrity-checked data representation. + /// + /// - Parameter integrityCheckedRepresentation: The integrity-checked data representation of the private key. + /// The parameter needs to be 64 bytes long, and contain the seed and a hash of the public key. + public init(integrityCheckedRepresentation: D) throws { + self.impl = try .init(integrityCheckedRepresentation: integrityCheckedRepresentation) + } + + /// The integrity-checked data representation of the private key. + /// + /// This representation is 64 bytes long, and contains the seed and a hash of the public key. + public var integrityCheckedRepresentation: Data { + get { + return self.impl.integrityCheckedRepresentation + } + } + } +} + + +/// The MLDSA87 Digital Signature Algorithm +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +public enum MLDSA87: Sendable {} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension MLDSA87 { + /// The public key for MLDSA87. + public struct PublicKey: Sendable { + var impl: MLDSAPublicKeyImpl + + /// Verifies a MLDSA87 signature. + /// - Parameters: + /// - signature: The MLDSA87 signature to verify. + /// - data: The signed data. + /// - Returns: `true` if the signature is valid, `false` otherwise. + public func isValidSignature(signature: S, for data: D) -> Bool { + self.impl.isValidSignature(signature: signature, for: data) + } + + /// Verifies a MLDSA87 signature, in a specific context. + /// - Parameters: + /// - signature: The MLDSA87 signature to verify. + /// - data: The signed data. + /// - context: Context for the signature. + /// - Returns: `true` if the signature is valid in the specified context, `false` otherwise. + public func isValidSignature(signature: S, for data: D, context: C) -> Bool { + self.impl.isValidSignature(signature: signature, for: data, context: context) + } + + /// Parses a public key from a serialized representation. + /// + /// - Parameter rawRepresentation: The public key, in the FIPS 204 standard serialization format. + /// - Returns: The deserialized public key. + public init(rawRepresentation: D) throws { + self.impl = try .init(rawRepresentation: rawRepresentation) + } + + /// A serialized representation of the public key. + /// + /// This property provides a representation of the public key in the FIPS 204 standard serialization format. + public var rawRepresentation: Data { + get { + self.impl.rawRepresentation + } + } + + fileprivate init(impl: MLDSAPublicKeyImpl) { + self.impl = impl + } + } + + /// The private key for MLDSA87. + public struct PrivateKey: Signer, Sendable { + var impl: MLDSAPrivateKeyImpl + + /// Generates a MLDSA87 signature. + /// - Parameters: + /// - data: The data to sign. + /// - Returns: The MLDSA87 signature. + /// This method throws if CryptoKit encounters an error producing the signature. + public func signature(for data: D) throws -> Data { + try self.impl.signature(for: data) + } + + /// Generates a MLDSA87 signature, with context. + /// - Parameters: + /// - data: The data to sign. + /// - context: Context for the signature. + /// - Returns: The MLDSA87 signature. + /// This method throws if CryptoKit encounters an error producing the signature. + public func signature(for data: D, context: C) throws -> Data { + try self.impl.signature(for: data, context: context) + } + + /// The associated public key. + public var publicKey: PublicKey { + get { + PublicKey(impl: self.impl.publicKey) + } + } + + /// Initializes a new random private key. + public init() throws { + self.impl = try .init() + } + + /// Initializes a private key from the seed representation. + /// + /// - Parameter seedRepresentation: The seed representation of the private key. This parameter needs to be 32 bytes long. + /// - Parameter publicKey: The public key associated with the secret key. + /// + /// This initializer implements the `ML-DSA.KeyGen_internal` algorithm (Algorithm 16) of FIPS 204. + /// + /// If a public key is provided, a consistency check is performed between it and the derived public key. + public init(seedRepresentation: D, publicKey: MLDSA87.PublicKey?) throws { + self.impl = try .init(seedRepresentation: seedRepresentation, publicKey: publicKey?.impl) + } + + /// The seed representation of the private key. + /// + /// The seed representation is 32 bytes long, and is the parameter + /// for the `ML-DSA.KeyGen_internal` algorithm (Algorithm 16) of FIPS 204. + public var seedRepresentation: Data { + get { + return self.impl.seedRepresentation + } + } + + /// Initializes a private key from an integrity-checked data representation. + /// + /// - Parameter integrityCheckedRepresentation: The integrity-checked data representation of the private key. + /// The parameter needs to be 64 bytes long, and contain the seed and a hash of the public key. + public init(integrityCheckedRepresentation: D) throws { + self.impl = try .init(integrityCheckedRepresentation: integrityCheckedRepresentation) + } + + /// The integrity-checked data representation of the private key. + /// + /// This representation is 64 bytes long, and contains the seed and a hash of the public key. + public var integrityCheckedRepresentation: Data { + get { + return self.impl.integrityCheckedRepresentation + } + } + } +} + + +#endif // Linux or !SwiftPM diff --git a/Sources/Crypto/Signatures/MLDSA.swift.gyb b/Sources/Crypto/Signatures/MLDSA.swift.gyb new file mode 100644 index 000000000..9481fc670 --- /dev/null +++ b/Sources/Crypto/Signatures/MLDSA.swift.gyb @@ -0,0 +1,163 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2019-2020 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +@_exported import CryptoKit +#else +public import Foundation + +#if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +typealias MLDSAPublicKeyImpl = CoreCryptoMLDSAPublicKeyImpl +typealias MLDSAPrivateKeyImpl = CoreCryptoMLDSAPrivateKeyImpl +#else +typealias MLDSAPublicKeyImpl = OpenSSLMLDSAPublicKeyImpl +typealias MLDSAPrivateKeyImpl = OpenSSLMLDSAPrivateKeyImpl +#endif + +%{ + MLDSA_VARIANTS = [{"name": "MLDSA65", "ccinfo": "ccmldsa65()!"}, {"name": "MLDSA87", "ccinfo": "ccmldsa87()!"}] +}% +% for MLDSA_VARIANT in MLDSA_VARIANTS: +%{ + NAME = MLDSA_VARIANT["name"] + INFO = MLDSA_VARIANT["ccinfo"] +}% + +/// The ${NAME} Digital Signature Algorithm +public enum ${NAME}: Sendable {} + +extension ${NAME} { + /// The public key for ${NAME}. + public struct PublicKey: Sendable { + var impl: MLDSAPublicKeyImpl<${NAME}> + + /// Verifies a ${NAME} signature. + /// - Parameters: + /// - signature: The ${NAME} signature to verify. + /// - data: The signed data. + /// - Returns: `true` if the signature is valid, `false` otherwise. + public func isValidSignature(signature: S, for data: D) -> Bool { + self.impl.isValidSignature(signature: signature, for: data) + } + + /// Verifies a ${NAME} signature, in a specific context. + /// - Parameters: + /// - signature: The ${NAME} signature to verify. + /// - data: The signed data. + /// - context: Context for the signature. + /// - Returns: `true` if the signature is valid in the specified context, `false` otherwise. + public func isValidSignature(signature: S, for data: D, context: C) -> Bool { + self.impl.isValidSignature(signature: signature, for: data, context: context) + } + + /// Parses a public key from a serialized representation. + /// + /// - Parameter rawRepresentation: The public key, in the FIPS 204 standard serialization format. + /// - Returns: The deserialized public key. + public init(rawRepresentation: D) throws { + self.impl = try .init(rawRepresentation: rawRepresentation) + } + + /// A serialized representation of the public key. + /// + /// This property provides a representation of the public key in the FIPS 204 standard serialization format. + public var rawRepresentation: Data { + get { + self.impl.rawRepresentation + } + } + + fileprivate init(impl: MLDSAPublicKeyImpl<${NAME}>) { + self.impl = impl + } + } + + /// The private key for ${NAME}. + public struct PrivateKey: Signer, Sendable { + var impl: MLDSAPrivateKeyImpl<${NAME}> + + /// Generates a ${NAME} signature. + /// - Parameters: + /// - data: The data to sign. + /// - Returns: The ${NAME} signature. + /// This method throws if CryptoKit encounters an error producing the signature. + public func signature(for data: D) throws -> Data { + try self.impl.signature(for: data) + } + + /// Generates a ${NAME} signature, with context. + /// - Parameters: + /// - data: The data to sign. + /// - context: Context for the signature. + /// - Returns: The ${NAME} signature. + /// This method throws if CryptoKit encounters an error producing the signature. + public func signature(for data: D, context: C) throws -> Data { + try self.impl.signature(for: data, context: context) + } + + /// The associated public key. + public var publicKey: PublicKey { + get { + PublicKey(impl: self.impl.publicKey) + } + } + + /// Initializes a new random private key. + public init() throws { + self.impl = try .init() + } + + /// Initializes a private key from the seed representation. + /// + /// - Parameter seedRepresentation: The seed representation of the private key. This parameter needs to be 32 bytes long. + /// - Parameter publicKey: The public key associated with the secret key. + /// + /// This initializer implements the `ML-DSA.KeyGen_internal` algorithm (Algorithm 16) of FIPS 204. + /// + /// If a public key is provided, a consistency check is performed between it and the derived public key. + public init(seedRepresentation: D, publicKey: ${NAME}.PublicKey?) throws { + self.impl = try .init(seedRepresentation: seedRepresentation, publicKey: publicKey?.impl) + } + + /// The seed representation of the private key. + /// + /// The seed representation is 32 bytes long, and is the parameter + /// for the `ML-DSA.KeyGen_internal` algorithm (Algorithm 16) of FIPS 204. + public var seedRepresentation: Data { + get { + return self.impl.seedRepresentation + } + } + + /// Initializes a private key from an integrity-checked data representation. + /// + /// - Parameter integrityCheckedRepresentation: The integrity-checked data representation of the private key. + /// The parameter needs to be 64 bytes long, and contain the seed and a hash of the public key. + public init(integrityCheckedRepresentation: D) throws { + self.impl = try .init(integrityCheckedRepresentation: integrityCheckedRepresentation) + } + + /// The integrity-checked data representation of the private key. + /// + /// This representation is 64 bytes long, and contains the seed and a hash of the public key. + public var integrityCheckedRepresentation: Data { + get { + return self.impl.integrityCheckedRepresentation + } + } + } +} + +% end + +#endif // Linux or !SwiftPM diff --git a/Sources/Crypto/Signatures/Signature.swift b/Sources/Crypto/Signatures/Signature.swift index b51f94347..c8fca65a7 100644 --- a/Sources/Crypto/Signatures/Signature.swift +++ b/Sources/Crypto/Signatures/Signature.swift @@ -14,22 +14,26 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) protocol SignatureVerification { - func verifySignature(signature: Data, data: Data) throws -> Bool + func verifySignature(signature: Data, data: Data) throws(CryptoKitMetaError) -> Bool } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) protocol DigestSigner { associatedtype Signature - func signature(for digest: D) throws -> Signature + func signature(for digest: D) throws(CryptoKitMetaError) -> Signature } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) protocol Signer { associatedtype Signature - func signature(for data: D) throws -> Signature + func signature(for data: D) throws(CryptoKitMetaError) -> Signature } #endif // Linux or !SwiftPM diff --git a/Sources/_CryptoExtras/Util/Optional+withUnsafeBytes.swift b/Sources/Crypto/Util/BoringSSL/Optional+withUnsafeBytes_boring.swift similarity index 100% rename from Sources/_CryptoExtras/Util/Optional+withUnsafeBytes.swift rename to Sources/Crypto/Util/BoringSSL/Optional+withUnsafeBytes_boring.swift diff --git a/Sources/Crypto/Util/PrettyBytes.swift b/Sources/Crypto/Util/PrettyBytes.swift index 8db832af7..695ebb31e 100644 --- a/Sources/Crypto/Util/PrettyBytes.swift +++ b/Sources/Crypto/Util/PrettyBytes.swift @@ -11,7 +11,11 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) enum ByteHexEncodingErrors: Error { @@ -20,9 +24,9 @@ enum ByteHexEncodingErrors: Error { } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -let charA = UInt8(UnicodeScalar("a").value) +let charA = UInt8(97 /* "a" */) @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -let char0 = UInt8(UnicodeScalar("0").value) +let char0 = UInt8(48 /* "0" */) @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) private func itoh(_ value: UInt8) -> UInt8 { @@ -41,6 +45,7 @@ private func htoi(_ value: UInt8) throws -> UInt8 { } } +#if !hasFeature(Embedded) @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension DataProtocol { var hexString: String { @@ -56,17 +61,19 @@ extension DataProtocol { } } - return String(bytes: hexChars, encoding: .utf8)! + return String(decoding: hexChars, as: UTF8.self) } } +#endif // !hasFeature(Embedded) @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -extension MutableDataProtocol { +extension RangeReplaceableCollection where Element == UInt8 { mutating func appendByte(_ byte: UInt64) { - withUnsafePointer(to: byte.littleEndian, { self.append(contentsOf: UnsafeRawBufferPointer(start: $0, count: 8)) }) + withUnsafeBytes(of: byte.littleEndian, { self.append(contentsOf: $0) }) } } +#if !CRYPTOKIT_NO_ACCESS_TO_FOUNDATION @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension Data { init(hexString: String) throws { @@ -107,3 +114,4 @@ extension Array where Element == UInt8 { } } +#endif diff --git a/Sources/Crypto/Util/SafeCompare.swift b/Sources/Crypto/Util/SafeCompare.swift index 29fe5ea98..51a726d5a 100644 --- a/Sources/Crypto/Util/SafeCompare.swift +++ b/Sources/Crypto/Util/SafeCompare.swift @@ -14,11 +14,15 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) internal func safeCompare(_ lhs: LHS, _ rhs: RHS) -> Bool { - #if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API + #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION return coreCryptoSafeCompare(lhs, rhs) #else return openSSLSafeCompare(lhs, rhs) diff --git a/Sources/Crypto/Util/SecureBytes.swift b/Sources/Crypto/Util/SecureBytes.swift index 71b6dfe16..94be737f5 100644 --- a/Sources/Crypto/Util/SecureBytes.swift +++ b/Sources/Crypto/Util/SecureBytes.swift @@ -14,22 +14,23 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -private let emptyStorage:SecureBytes.Backing = SecureBytes.Backing.createEmpty() +nonisolated(unsafe) private let emptyStorage:SecureBytes.Backing = SecureBytes.Backing.createEmpty() @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -struct SecureBytes { - @usableFromInline +struct SecureBytes: @unchecked Sendable { var backing: Backing - @inlinable init() { self = .init(count: 0) } - @usableFromInline init(count: Int) { if count == 0 { self.backing = emptyStorage @@ -43,7 +44,19 @@ struct SecureBytes { } /// Allows initializing a SecureBytes object with a closure that will initialize the memory. - @usableFromInline + #if hasFeature(Embedded) + init(unsafeUninitializedCapacity: Int, initializingWith callback: (inout UnsafeMutableRawBufferPointer, inout Int) throws(E) -> Void) throws(E) { + self.backing = Backing.create(capacity: unsafeUninitializedCapacity) + try self.backing._withVeryUnsafeMutableBytes { veryUnsafePointer throws(E) in + // As Array does, we want to truncate the initializing pointer to only have the requested size. + var veryUnsafePointer = UnsafeMutableRawBufferPointer(rebasing: veryUnsafePointer.prefix(unsafeUninitializedCapacity)) + var initializedCount = 0 + try callback(&veryUnsafePointer, &initializedCount) + + self.backing.count = initializedCount + } + } + #else init(unsafeUninitializedCapacity: Int, initializingWith callback: (inout UnsafeMutableRawBufferPointer, inout Int) throws -> Void) rethrows { self.backing = Backing.create(capacity: unsafeUninitializedCapacity) try self.backing._withVeryUnsafeMutableBytes { veryUnsafePointer in @@ -55,11 +68,11 @@ struct SecureBytes { self.backing.count = initializedCount } } + #endif } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension SecureBytes { - @inlinable mutating func append(_ data: C) where C.Element == UInt8 { let requiredCapacity = self.count + data.count let backingCapacity = self.backing.allocatedCapacity @@ -71,7 +84,6 @@ extension SecureBytes { self.backing._appendBytes(data) } - @usableFromInline mutating func reserveCapacity(_ n: Int) { let backingCapacity = self.backing.allocatedCapacity if backingCapacity >= n { @@ -95,32 +107,27 @@ extension SecureBytes: Equatable { // MARK: - Collection conformance @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension SecureBytes: Collection { - @usableFromInline @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) struct Index { - /* fileprivate but usableFromInline */ @usableFromInline var offset: Int + fileprivate var offset: Int - /*@inlinable*/ @usableFromInline internal init(offset: Int) { + internal init(offset: Int) { self.offset = offset } } - @inlinable var startIndex: Index { return Index(offset: 0) } - @inlinable var endIndex: Index { return Index(offset: self.count) } - @inlinable var count: Int { return self.backing.count } - @inlinable subscript(_ index: Index) -> UInt8 { get { return self.backing[offset: index.offset] @@ -130,7 +137,6 @@ extension SecureBytes: Collection { } } - @inlinable func index(after index: Index) -> Index { return index.advanced(by: 1) } @@ -139,7 +145,6 @@ extension SecureBytes: Collection { // MARK: - BidirectionalCollection conformance @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension SecureBytes: BidirectionalCollection { - @inlinable func index(before index: Index) -> Index { return index.advanced(by: -1) } @@ -156,7 +161,6 @@ extension SecureBytes: MutableCollection { } // MARK: - RangeReplaceableCollection conformance @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension SecureBytes: RangeReplaceableCollection { - @inlinable mutating func replaceSubrange(_ subrange: Range, with newElements: C) where C.Element == UInt8 { let requiredCapacity = self.backing.count - subrange.count + newElements.count let backingCapacity = self.backing.allocatedCapacity @@ -182,12 +186,11 @@ extension SecureBytes: RangeReplaceableCollection { } // The default implementation of this from RangeReplaceableCollection can't take advantage of `ContiguousBytes`, so we override it here - @inlinable - public mutating func append(contentsOf newElements: Elements) where Elements.Element == UInt8 { + mutating func append(contentsOf newElements: some Sequence) { let done:Void? = newElements.withContiguousStorageIfAvailable { replaceSubrange(endIndex..(_ body: (UnsafeRawBufferPointer) throws(E) -> T) throws(E) -> T { + return try self.backing.withUnsafeBytes(body) + } + #else func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> T) rethrows -> T { return try self.backing.withUnsafeBytes(body) } + #endif - @inlinable + #if hasFeature(Embedded) + mutating func withUnsafeMutableBytes(_ body: (UnsafeMutableRawBufferPointer) throws(E) -> T) throws(E) -> T { + if !isKnownUniquelyReferenced(&self.backing) { + self.backing = Backing.create(copying: self.backing) + } + + return try self.backing.withUnsafeMutableBytes(body) + } + #else mutating func withUnsafeMutableBytes(_ body: (UnsafeMutableRawBufferPointer) throws -> T) rethrows -> T { if !isKnownUniquelyReferenced(&self.backing) { self.backing = Backing.create(copying: self.backing) @@ -212,17 +228,22 @@ extension SecureBytes: ContiguousBytes { return try self.backing.withUnsafeMutableBytes(body) } + #endif - @inlinable + #if hasFeature(Embedded) + func withContiguousStorageIfAvailable(_ body: (UnsafeBufferPointer) throws(E) -> R) throws(E) -> R? { + return try self.backing.withContiguousStorageIfAvailable(body) + } + #else func withContiguousStorageIfAvailable(_ body: (UnsafeBufferPointer) throws -> R) rethrows -> R? { return try self.backing.withContiguousStorageIfAvailable(body) } + #endif } // MARK: - DataProtocol conformance @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension SecureBytes: DataProtocol { - @inlinable var regions: CollectionOfOne { return CollectionOfOne(self) } @@ -257,38 +278,31 @@ extension SecureBytes.Index: Strideable { // MARK: - Heap allocated backing storage. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension SecureBytes { - @usableFromInline +#if !hasFeature(Embedded) @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) internal struct BackingHeader { - @usableFromInline internal var count: Int - @usableFromInline internal var capacity: Int } - @usableFromInline @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) internal class Backing: ManagedBuffer { - @usableFromInline class func createEmpty() -> Backing { return Backing.create(minimumCapacity: 0, makingHeaderWith: { _ in BackingHeader(count: 0, capacity: 0) }) as! Backing } - @usableFromInline class func create(capacity: Int) -> Backing { let capacity = Int(UInt32(capacity).nextPowerOf2ClampedToMax()) return Backing.create(minimumCapacity: capacity, makingHeaderWith: { _ in BackingHeader(count: 0, capacity: capacity) }) as! Backing } - @usableFromInline class func create(copying original: Backing) -> Backing { return Backing.create(bytes: original) } - @inlinable - class func create(bytes: D) -> Backing { + final class func create(bytes: D) -> Backing { return bytes.withUnsafeBytes { bytesPtr in let backing = Backing.create(capacity: bytesPtr.count) backing._withVeryUnsafeMutableBytes { targetPtr in @@ -300,7 +314,6 @@ extension SecureBytes { } } - @usableFromInline class func create(randomBytes: Int) -> Backing { let backing = Backing.create(capacity: randomBytes) backing._withVeryUnsafeMutableBytes { targetPtr in @@ -320,7 +333,6 @@ extension SecureBytes { } } - @usableFromInline var count: Int { get { return self.header.count @@ -330,7 +342,6 @@ extension SecureBytes { } } - @usableFromInline subscript(offset offset: Int) -> UInt8 { get { // precondition(offset >= 0 && offset < self.count) @@ -342,11 +353,80 @@ extension SecureBytes { } } } +#else + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) + internal class Backing { + private var storage: UnsafeMutableRawBufferPointer + + var count: Int + var capacity: Int { + storage.count + } + + private init(storage: UnsafeMutableRawBufferPointer, count: Int) { + self.storage = storage + self.count = count + } + + class func createEmpty() -> Backing { + return Backing.create(capacity: 0) + } + + class func create(capacity: Int) -> Backing { + let capacity = Int(UInt32(capacity).nextPowerOf2ClampedToMax()) + let buffer = UnsafeMutableRawBufferPointer.allocate(byteCount: capacity, alignment: Int(CC_MAX_ALIGNMENT)) + return Backing.init(storage: buffer, count: 0) + } + + class func create(copying original: Backing) -> Backing { + let buffer = UnsafeMutableRawBufferPointer.allocate(byteCount: original.capacity, alignment: Int(CC_MAX_ALIGNMENT)) + buffer.copyBytes(from: original.storage) + return Backing.init(storage: buffer, count: original.count) + } + + final class func create(bytes: D) -> Backing { + return bytes.withUnsafeBytes { bytesPtr in + let backing = Backing.create(capacity: bytesPtr.count) + backing._withVeryUnsafeMutableBytes { targetPtr in + targetPtr.copyMemory(from: bytesPtr) + } + backing.count = bytesPtr.count + precondition(backing.count <= backing.capacity) + return backing + } + } + + class func create(randomBytes: Int) -> Backing { + let backing = Backing.create(capacity: randomBytes) + backing._withVeryUnsafeMutableBytes { targetPtr in + assert(targetPtr.count >= randomBytes) + targetPtr.initializeWithRandomBytes(count: randomBytes) + } + backing.count = randomBytes + return backing + } + + deinit { + // We always clear the whole capacity, even if we don't think we used it all. + memset_s(storage.baseAddress, storage.count, 0, storage.count) + } + + subscript(offset offset: Int) -> UInt8 { + get { + // precondition(offset >= 0 && offset < self.count) + return storage[offset] + } + set { + // precondition(offset >= 0 && offset < self.count) + storage[offset] = newValue + } + } + } +#endif } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension SecureBytes.Backing { - @usableFromInline var allocatedCapacity: Int { #if os(OpenBSD) return self.header.capacity @@ -384,7 +464,7 @@ extension SecureBytes.Backing { } /// Appends the bytes of a collection to this storage, crashing if there is not enough room. - /* private but inlinable */ func _appendBytes(_ bytes: C) where C.Element == UInt8 { + fileprivate func _appendBytes(_ bytes: C) where C.Element == UInt8 { let byteCount = bytes.count precondition(self.allocatedCapacity - self.count - byteCount >= 0, "Insufficient space for byte copying, must have reallocated!") @@ -399,7 +479,7 @@ extension SecureBytes.Backing { /// Appends the bytes of a slice of another backing buffer to this storage, crashing if there /// is not enough room. - /* private but inlinable */ func _appendBytes(_ backing: SecureBytes.Backing, inRange range: Range) { + fileprivate func _appendBytes(_ backing: SecureBytes.Backing, inRange range: Range) { precondition(range.lowerBound >= 0) precondition(range.upperBound <= backing.allocatedCapacity) precondition(self.allocatedCapacity - self.count - range.count >= 0, "Insufficient space for byte copying, must have reallocated!") @@ -419,8 +499,7 @@ extension SecureBytes.Backing { /// Moves the range of bytes identified by the slice by the delta, crashing if the move would /// place the bytes out of the storage. Note that this does not update the count: external code /// must ensure that that happens. - @usableFromInline - /* private but usableFromInline */ func _moveBytes(range: Range, by delta: Int) { + private func _moveBytes(range: Range, by delta: Int) { // We have to check that the range is within the delta, as is the new location. precondition(range.lowerBound >= 0) precondition(range.upperBound <= self.allocatedCapacity) @@ -437,8 +516,7 @@ extension SecureBytes.Backing { } // Copies some bytes into the buffer at the appropriate place. Does not update count: external code must do so. - @inlinable - /* private but inlinable */ func _copyBytes(_ bytes: C, at offset: Int) where C.Element == UInt8 { + private func _copyBytes(_ bytes: C, at offset: Int) where C.Element == UInt8 { precondition(offset >= 0) precondition(offset + bytes.count <= self.allocatedCapacity) @@ -453,14 +531,28 @@ extension SecureBytes.Backing { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension SecureBytes.Backing: ContiguousBytes { +#if hasFeature(Embedded) + func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws(E) -> T) throws(E) -> T { + let count = self.count + return try storage.withUnsafeBytes { elementsPtr throws(E) in + return try body(UnsafeRawBufferPointer(start: elementsPtr.baseAddress, count: count)) + } + } +#else func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> T) rethrows -> T { let count = self.count - return try self.withUnsafeMutablePointerToElements { elementsPtr in return try body(UnsafeRawBufferPointer(start: elementsPtr, count: count)) } } +#endif + #if hasFeature(Embedded) + + func withUnsafeMutableBytes(_ body: (UnsafeMutableRawBufferPointer) throws(E) -> T) throws(E) -> T { + return try body(storage) + } + #else func withUnsafeMutableBytes(_ body: (UnsafeMutableRawBufferPointer) throws -> T) rethrows -> T { let count = self.count @@ -468,17 +560,32 @@ extension SecureBytes.Backing: ContiguousBytes { return try body(UnsafeMutableRawBufferPointer(start: elementsPtr, count: count)) } } + #endif +#if hasFeature(Embedded) + /// Very unsafe in the sense that this points to uninitialized memory. Used only for implementations within this file. + func _withVeryUnsafeMutableBytes(_ body: (UnsafeMutableRawBufferPointer) throws(E) -> T) throws(E) -> T { + return try body(storage) + } +#else /// Very unsafe in the sense that this points to uninitialized memory. Used only for implementations within this file. - @inlinable - /* private but inlinable */ func _withVeryUnsafeMutableBytes(_ body: (UnsafeMutableRawBufferPointer) throws -> T) rethrows -> T { + func _withVeryUnsafeMutableBytes(_ body: (UnsafeMutableRawBufferPointer) throws -> T) rethrows -> T { let capacity = self.allocatedCapacity return try self.withUnsafeMutablePointerToElements { elementsPtr in return try body(UnsafeMutableRawBufferPointer(start: elementsPtr, count: capacity)) } } +#endif +#if hasFeature(Embedded) + func withContiguousStorageIfAvailable(_ body: (UnsafeBufferPointer) throws(E) -> R) throws(E) -> R? { + let count = self.count + return try storage.withUnsafeBytes { elementsPtr throws(E) -> R? in + return try body(UnsafeBufferPointer(start: elementsPtr.baseAddress?.assumingMemoryBound(to: UInt8.self), count: count)) + } + } +#else func withContiguousStorageIfAvailable(_ body: (UnsafeBufferPointer) throws -> R) rethrows -> R? { let count = self.count @@ -486,6 +593,7 @@ extension SecureBytes.Backing: ContiguousBytes { return try body(UnsafeBufferPointer(start: elementsPtr, count: count)) } } +#endif } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) @@ -528,6 +636,12 @@ extension Data { /// This is our best-effort attempt to expose the data in an auto-zeroing fashion. Any mutating function called on /// the constructed `Data` object will cause the bytes to be copied out: we can't avoid that. init(_ secureBytes: SecureBytes) { + #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION + self = secureBytes.withUnsafeBytes { + // We make a mutable copy of this pointer here because we know Data won't write through it. + return Data($0) + } + #else // We need to escape into unmanaged land here in order to keep the backing storage alive. let unmanagedBacking = Unmanaged.passRetained(secureBytes.backing) @@ -537,6 +651,7 @@ extension Data { // We make a mutable copy of this pointer here because we know Data won't write through it. return Data(bytesNoCopy: UnsafeMutableRawPointer(mutating: $0.baseAddress!), count: $0.count, deallocator: .custom { (_: UnsafeMutableRawPointer, _: Int) in unmanagedBacking.release() }) } + #endif } /// A custom initializer for Data that attempts to share the same storage as the current SecureBytes instance. @@ -548,7 +663,16 @@ extension Data { let base = secureByteSlice.base let baseOffset = secureByteSlice.startIndex.offset let endOffset = secureByteSlice.endIndex.offset + + #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION + self = base.withUnsafeBytes { + // Slice the base pointer down to just the range we want. + let slicedPointer = UnsafeRawBufferPointer(rebasing: $0[baseOffset..(hashFunction: H.Type) throws -> String { + #if false +#if !CRYPTOKIT_IN_SEP + if #available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, macCatalyst 19.0, visionOS 2.0, *) { + switch H.self { + case is SHA3_256.Type: return "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a" + case is SHA3_384.Type: return "0c63a75b845e4f7d01107d852e4c2485c51a50aaaa94fc61995e71bbee983a2ac3713831264adb47fb6bd1e058d5f004" + case is SHA3_512.Type: return "a69f73cca23a9ac5c8b567dc185a756e97c982164fe25859e0d1dcc1475c80a615b2123af1f5f94c11e3e9402c3ac558f500199d95b6d3e301758586281dcd26" + default: + break + } + } +#endif // !CRYPTOKIT_IN_SEP + #endif + switch H.self { - case is Insecure.SHA1.Type: return "da39a3ee5e6b4b0d3255bfef95601890afd80709" - case is SHA256.Type: return "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" - case is SHA384.Type: return "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b" - case is SHA512.Type: return "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e" + case is Insecure.SHA1.Type: return "da39a3ee5e6b4b0d3255bfef95601890afd80709" + case is SHA256.Type: return "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" + case is SHA384.Type: return "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b" + case is SHA512.Type: return "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e" default: XCTFail("Unhandled type: \(H.self)") throw TestError.unhandled @@ -38,6 +52,20 @@ func nullTestVectorForAlgorithm(hashFunction: H.Type) throws -> } func testVectorForAlgorithm(hashFunction: H.Type) throws -> String { + #if false +#if !CRYPTOKIT_IN_SEP + if #available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, macCatalyst 19.0, visionOS 2.0, *) { + switch H.self { + case is SHA3_256.Type: return "916f6061fe879741ca6469b43971dfdb28b1a32dc36cb3254e812be27aad1d18" + case is SHA3_384.Type: return "79407d3b5916b59c3e30b09822974791c313fb9ecc849e406f23592d04f625dc8c709b98b43b3852b337216179aa7fc7" + case is SHA3_512.Type: return "afebb2ef542e6579c50cad06d2e578f9f8dd6881d7dc824d26360feebf18a4fa73e3261122948efcfd492e74e82e2189ed0fb440d187f382270cb455f21dd185" + default: + break + } + } +#endif // !CRYPTOKIT_IN_SEP + #endif + switch H.self { case is Insecure.SHA1.Type: return "a49b2446a02c645bf419f995b67091253a04a259" case is SHA256.Type: return "cf5b16a778af8380036ce59e7b0492370b249b11e8f07a51afac45037afee9d1" @@ -89,6 +117,15 @@ class DigestsTests: XCTestCase { try orFail { try testHashFunction(hf: SHA256.self) } try orFail { try testHashFunction(hf: SHA384.self) } try orFail { try testHashFunction(hf: SHA512.self) } +#if !CRYPTOKIT_IN_SEP + #if false + if #available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, macCatalyst 19.0, visionOS 2.0, *) { + try orFail { try testHashFunction(hf: SHA3_256.self) } + try orFail { try testHashFunction(hf: SHA3_384.self) } + try orFail { try testHashFunction(hf: SHA3_512.self) } + } + #endif +#endif // !CRYPTOKIT_IN_SEP } func testHashFunctionImplementsCoW(hf: H.Type) throws { @@ -111,9 +148,17 @@ class DigestsTests: XCTestCase { try orFail { try testHashFunctionImplementsCoW(hf: SHA256.self) } try orFail { try testHashFunctionImplementsCoW(hf: SHA384.self) } try orFail { try testHashFunctionImplementsCoW(hf: SHA512.self) } +#if !CRYPTOKIT_IN_SEP + #if false + if #available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, macCatalyst 19.0, visionOS 2.0, *) { + try orFail { try testHashFunctionImplementsCoW(hf: SHA3_256.self) } + try orFail { try testHashFunctionImplementsCoW(hf: SHA3_384.self) } + try orFail { try testHashFunctionImplementsCoW(hf: SHA3_512.self) } + } + #endif +#endif // !CRYPTOKIT_IN_SEP } - @available(macOS 10.15, iOS 13.2, tvOS 13.2, watchOS 6.1, macCatalyst 13.2, visionOS 1.2, *) func testBlockSizes() { XCTAssertEqual(Insecure.MD5.blockByteCount, 64) XCTAssertEqual(Insecure.SHA1.blockByteCount, 64) @@ -121,5 +166,15 @@ class DigestsTests: XCTestCase { XCTAssertEqual(SHA384.blockByteCount, 128) XCTAssertEqual(SHA512.blockByteCount, 128) + +#if !CRYPTOKIT_IN_SEP + #if false + if #available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, macCatalyst 19.0, visionOS 2.0, *) { + XCTAssertEqual(SHA3_256.blockByteCount, 136) + XCTAssertEqual(SHA3_384.blockByteCount, 104) + XCTAssertEqual(SHA3_512.blockByteCount, 72) + } + #endif +#endif // !CRYPTOKIT_IN_SEP } } diff --git a/Tests/CryptoTests/Encodings/ECKeyEncodingsTests.swift b/Tests/CryptoTests/Encodings/ECKeyEncodingsTests.swift index 90b982fcc..4f0a14c54 100644 --- a/Tests/CryptoTests/Encodings/ECKeyEncodingsTests.swift +++ b/Tests/CryptoTests/Encodings/ECKeyEncodingsTests.swift @@ -80,11 +80,9 @@ class ECKeyEncodingsTests: XCTestCase { XCTAssertNoThrow(try P256.KeyAgreement.PublicKey(rawRepresentation: p256KeyKA_raw)) XCTAssertNoThrow(try P256.KeyAgreement.PublicKey(x963Representation: p256KeyKA_x963)) XCTAssertNoThrow(try P256.KeyAgreement.PublicKey(compressedRepresentation: p256KeyKA_compressed)) - XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(compressedRepresentation: p256KeyKA_x963)) { error in - XCTAssertTrue(error is CryptoKitError) - XCTAssertEqual(error as? CryptoKitError, .incorrectParameterSize) - } - + XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(compressedRepresentation: p256KeyKA_x963), + error: CryptoKitError.incorrectParameterSize) + let p384KeyKA = P384.KeyAgreement.PrivateKey().publicKey let p384KeyKA_raw = p384KeyKA.rawRepresentation let p384KeyKA_x963 = p384KeyKA.x963Representation @@ -92,11 +90,9 @@ class ECKeyEncodingsTests: XCTestCase { XCTAssertNoThrow(try P384.KeyAgreement.PublicKey(rawRepresentation: p384KeyKA_raw)) XCTAssertNoThrow(try P384.KeyAgreement.PublicKey(x963Representation: p384KeyKA_x963)) XCTAssertNoThrow(try P384.KeyAgreement.PublicKey(compressedRepresentation: p384KeyKA_compressed)) - XCTAssertThrowsError(try P384.KeyAgreement.PublicKey(compressedRepresentation: p384KeyKA_x963)) { error in - XCTAssertTrue(error is CryptoKitError) - XCTAssertEqual(error as? CryptoKitError, .incorrectParameterSize) - } - + XCTAssertThrowsError(try P384.KeyAgreement.PublicKey(compressedRepresentation: p384KeyKA_x963), + error: CryptoKitError.incorrectParameterSize) + let p521KeyKA = P521.KeyAgreement.PrivateKey().publicKey let p521KeyKA_raw = p521KeyKA.rawRepresentation let p521KeyKA_x963 = p521KeyKA.x963Representation @@ -104,11 +100,9 @@ class ECKeyEncodingsTests: XCTestCase { XCTAssertNoThrow(try P521.KeyAgreement.PublicKey(rawRepresentation: p521KeyKA_raw)) XCTAssertNoThrow(try P521.KeyAgreement.PublicKey(x963Representation: p521KeyKA_x963)) XCTAssertNoThrow(try P521.KeyAgreement.PublicKey(compressedRepresentation: p521KeyKA_compressed)) - XCTAssertThrowsError(try P521.KeyAgreement.PublicKey(compressedRepresentation: p521KeyKA_x963)) { error in - XCTAssertTrue(error is CryptoKitError) - XCTAssertEqual(error as? CryptoKitError, .incorrectParameterSize) - } - + XCTAssertThrowsError(try P521.KeyAgreement.PublicKey(compressedRepresentation: p521KeyKA_x963), + error: CryptoKitError.incorrectParameterSize) + // Curve25519 does not have an x963 representation. let x25519KeyKA = Curve25519.KeyAgreement.PrivateKey().publicKey let x25519KeyKA_raw = x25519KeyKA.rawRepresentation @@ -124,11 +118,9 @@ class ECKeyEncodingsTests: XCTestCase { XCTAssertNoThrow(try P256.Signing.PublicKey(rawRepresentation: p256KeyKA_raw)) XCTAssertNoThrow(try P256.Signing.PublicKey(x963Representation: p256KeyKA_x963)) XCTAssertNoThrow(try P256.KeyAgreement.PublicKey(compressedRepresentation: p256KeyKA_compressed)) - XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(compressedRepresentation: p256KeyKA_x963)) { error in - XCTAssertTrue(error is CryptoKitError) - XCTAssertEqual(error as? CryptoKitError, .incorrectParameterSize) - } - + XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(compressedRepresentation: p256KeyKA_x963), + error: CryptoKitError.incorrectParameterSize) + let p384KeyKA = P384.Signing.PrivateKey().publicKey let p384KeyKA_raw = p384KeyKA.rawRepresentation let p384KeyKA_x963 = p384KeyKA.x963Representation @@ -136,11 +128,9 @@ class ECKeyEncodingsTests: XCTestCase { XCTAssertNoThrow(try P384.Signing.PublicKey(rawRepresentation: p384KeyKA_raw)) XCTAssertNoThrow(try P384.Signing.PublicKey(x963Representation: p384KeyKA_x963)) XCTAssertNoThrow(try P384.KeyAgreement.PublicKey(compressedRepresentation: p384KeyKA_compressed)) - XCTAssertThrowsError(try P384.KeyAgreement.PublicKey(compressedRepresentation: p384KeyKA_x963)) { error in - XCTAssertTrue(error is CryptoKitError) - XCTAssertEqual(error as? CryptoKitError, .incorrectParameterSize) - } - + XCTAssertThrowsError(try P384.KeyAgreement.PublicKey(compressedRepresentation: p384KeyKA_x963), + error: CryptoKitError.incorrectParameterSize) + let p521KeyKA = P521.Signing.PrivateKey().publicKey let p521KeyKA_raw = p521KeyKA.rawRepresentation let p521KeyKA_x963 = p521KeyKA.x963Representation @@ -148,11 +138,9 @@ class ECKeyEncodingsTests: XCTestCase { XCTAssertNoThrow(try P521.Signing.PublicKey(rawRepresentation: p521KeyKA_raw)) XCTAssertNoThrow(try P521.Signing.PublicKey(x963Representation: p521KeyKA_x963)) XCTAssertNoThrow(try P521.KeyAgreement.PublicKey(compressedRepresentation: p521KeyKA_compressed)) - XCTAssertThrowsError(try P521.KeyAgreement.PublicKey(compressedRepresentation: p521KeyKA_x963)) { error in - XCTAssertTrue(error is CryptoKitError) - XCTAssertEqual(error as? CryptoKitError, .incorrectParameterSize) - } - + XCTAssertThrowsError(try P521.KeyAgreement.PublicKey(compressedRepresentation: p521KeyKA_x963), + error: CryptoKitError.incorrectParameterSize) + let x25519KeyKA = Curve25519.Signing.PrivateKey().publicKey let x25519KeyKA_raw = x25519KeyKA.rawRepresentation XCTAssertNoThrow(try Curve25519.Signing.PublicKey(rawRepresentation: x25519KeyKA_raw)) @@ -186,6 +174,23 @@ class ECKeyEncodingsTests: XCTestCase { XCTAssertNoThrow(try P521.Signing.PublicKey(compactRepresentation: p521KeyKA_compact)) } + func testPEMPrivateKeyImport() throws { + let pemKeyString = """ + -----BEGIN PRIVATE KEY----- + MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgNjSvGphHdpvWvUNB + RR7xtcT7lQwt/VvTNYP+qTeinIqhRANCAAQLlT9xVWd72j6QQOIyXFhgwASrh1G1 + lyaDq/mR7r2Xasd+X1xm5P364yPecJJeFtDFYrTCeFa+d8/MvWDZQ0q5 + -----END PRIVATE KEY----- + """ + XCTAssertNotNil(try P256.KeyAgreement.PrivateKey(pemRepresentation: pemKeyString)) + } + + func testDERPrivateKeyImport() throws { + let derKey = Data(base64urlEncoded: "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgzdwpYwaEoIXKGBU_QHIJBgR4krKcxUgZsXDaarhEGXuhRANCAAT4A-8-QanrFJDb_bQVAEQcWM7HWeZh-hA1a6YvZi0-jq7LqSZOSnwteb4yDqbQ_USNWDlz6793Tr1kKDYjaK6L")! + + XCTAssertNotNil(try P256.KeyAgreement.PrivateKey(derRepresentation: derKey)) + } + func testSimplePEMP256SPKI() throws { let pemPublicKey = """ -----BEGIN PUBLIC KEY----- @@ -200,51 +205,29 @@ class ECKeyEncodingsTests: XCTestCase { XCTAssertEqual(signingKey.rawRepresentation, keyAgreementKey.rawRepresentation) // Now the non-matching public keys. - XCTAssertThrowsError(try P384.Signing.PublicKey(pemRepresentation: pemPublicKey)) { error in - guard case .incorrectParameterSize = error as? CryptoKitError else { - XCTFail("Unexpected error: \(error)") - return - } - } - XCTAssertThrowsError(try P384.KeyAgreement.PublicKey(pemRepresentation: pemPublicKey)) { error in - guard case .incorrectParameterSize = error as? CryptoKitError else { - XCTFail("Unexpected error: \(error)") - return - } - } - XCTAssertThrowsError(try P521.Signing.PublicKey(pemRepresentation: pemPublicKey)) { error in - guard case .incorrectParameterSize = error as? CryptoKitError else { - XCTFail("Unexpected error: \(error)") - return - } - } - XCTAssertThrowsError(try P521.KeyAgreement.PublicKey(pemRepresentation: pemPublicKey)) { error in - guard case .incorrectParameterSize = error as? CryptoKitError else { - XCTFail("Unexpected error: \(error)") - return - } - } - + XCTAssertThrowsError(try P384.Signing.PublicKey(pemRepresentation: pemPublicKey), + error: CryptoKitError.incorrectParameterSize) + XCTAssertThrowsError(try P384.KeyAgreement.PublicKey(pemRepresentation: pemPublicKey), + error: CryptoKitError.incorrectParameterSize) + XCTAssertThrowsError(try P521.Signing.PublicKey(pemRepresentation: pemPublicKey), + error: CryptoKitError.incorrectParameterSize) + XCTAssertThrowsError(try P521.KeyAgreement.PublicKey(pemRepresentation: pemPublicKey), + error: CryptoKitError.incorrectParameterSize) + // Now the private keys, which all fail. - XCTAssertThrowsError(try P256.Signing.PrivateKey(pemRepresentation: pemPublicKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P256.KeyAgreement.PrivateKey(pemRepresentation: pemPublicKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P384.Signing.PrivateKey(pemRepresentation: pemPublicKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P384.KeyAgreement.PrivateKey(pemRepresentation: pemPublicKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P521.Signing.PrivateKey(pemRepresentation: pemPublicKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P521.KeyAgreement.PrivateKey(pemRepresentation: pemPublicKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - + XCTAssertThrowsError(try P256.Signing.PrivateKey(pemRepresentation: pemPublicKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P256.KeyAgreement.PrivateKey(pemRepresentation: pemPublicKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P384.Signing.PrivateKey(pemRepresentation: pemPublicKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P384.KeyAgreement.PrivateKey(pemRepresentation: pemPublicKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P521.Signing.PrivateKey(pemRepresentation: pemPublicKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P521.KeyAgreement.PrivateKey(pemRepresentation: pemPublicKey), + error: CryptoKitASN1Error.invalidPEMDocument) + // Validate we can reserialize. let firstReserialization = signingKey.pemRepresentation let secondReserialization = keyAgreementKey.pemRepresentation @@ -267,51 +250,29 @@ class ECKeyEncodingsTests: XCTestCase { XCTAssertEqual(signingKey.rawRepresentation, keyAgreementKey.rawRepresentation) // Now the non-matching public keys. - XCTAssertThrowsError(try P256.Signing.PublicKey(pemRepresentation: pemPublicKey)) { error in - guard case .incorrectParameterSize = error as? CryptoKitError else { - XCTFail("Unexpected error: \(error)") - return - } - } - XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(pemRepresentation: pemPublicKey)) { error in - guard case .incorrectParameterSize = error as? CryptoKitError else { - XCTFail("Unexpected error: \(error)") - return - } - } - XCTAssertThrowsError(try P521.Signing.PublicKey(pemRepresentation: pemPublicKey)) { error in - guard case .incorrectParameterSize = error as? CryptoKitError else { - XCTFail("Unexpected error: \(error)") - return - } - } - XCTAssertThrowsError(try P521.KeyAgreement.PublicKey(pemRepresentation: pemPublicKey)) { error in - guard case .incorrectParameterSize = error as? CryptoKitError else { - XCTFail("Unexpected error: \(error)") - return - } - } - + XCTAssertThrowsError(try P256.Signing.PublicKey(pemRepresentation: pemPublicKey), + error: CryptoKitError.incorrectParameterSize) + XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(pemRepresentation: pemPublicKey), + error: CryptoKitError.incorrectParameterSize) + XCTAssertThrowsError(try P521.Signing.PublicKey(pemRepresentation: pemPublicKey), + error: CryptoKitError.incorrectParameterSize) + XCTAssertThrowsError(try P521.KeyAgreement.PublicKey(pemRepresentation: pemPublicKey), + error: CryptoKitError.incorrectParameterSize) + // Now the private keys, which all fail. - XCTAssertThrowsError(try P256.Signing.PrivateKey(pemRepresentation: pemPublicKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P256.KeyAgreement.PrivateKey(pemRepresentation: pemPublicKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P384.Signing.PrivateKey(pemRepresentation: pemPublicKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P384.KeyAgreement.PrivateKey(pemRepresentation: pemPublicKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P521.Signing.PrivateKey(pemRepresentation: pemPublicKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P521.KeyAgreement.PrivateKey(pemRepresentation: pemPublicKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - + XCTAssertThrowsError(try P256.Signing.PrivateKey(pemRepresentation: pemPublicKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P256.KeyAgreement.PrivateKey(pemRepresentation: pemPublicKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P384.Signing.PrivateKey(pemRepresentation: pemPublicKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P384.KeyAgreement.PrivateKey(pemRepresentation: pemPublicKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P521.Signing.PrivateKey(pemRepresentation: pemPublicKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P521.KeyAgreement.PrivateKey(pemRepresentation: pemPublicKey), + error: CryptoKitASN1Error.invalidPEMDocument) + // Validate we can reserialize. let firstReserialization = signingKey.pemRepresentation let secondReserialization = keyAgreementKey.pemRepresentation @@ -335,51 +296,29 @@ class ECKeyEncodingsTests: XCTestCase { XCTAssertEqual(signingKey.rawRepresentation, keyAgreementKey.rawRepresentation) // Now the non-matching public keys. - XCTAssertThrowsError(try P256.Signing.PublicKey(pemRepresentation: pemPublicKey)) { error in - guard case .incorrectParameterSize = error as? CryptoKitError else { - XCTFail("Unexpected error: \(error)") - return - } - } - XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(pemRepresentation: pemPublicKey)) { error in - guard case .incorrectParameterSize = error as? CryptoKitError else { - XCTFail("Unexpected error: \(error)") - return - } - } - XCTAssertThrowsError(try P384.Signing.PublicKey(pemRepresentation: pemPublicKey)) { error in - guard case .incorrectParameterSize = error as? CryptoKitError else { - XCTFail("Unexpected error: \(error)") - return - } - } - XCTAssertThrowsError(try P384.KeyAgreement.PublicKey(pemRepresentation: pemPublicKey)) { error in - guard case .incorrectParameterSize = error as? CryptoKitError else { - XCTFail("Unexpected error: \(error)") - return - } - } - + XCTAssertThrowsError(try P256.Signing.PublicKey(pemRepresentation: pemPublicKey), + error: CryptoKitError.incorrectParameterSize) + XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(pemRepresentation: pemPublicKey), + error: CryptoKitError.incorrectParameterSize) + XCTAssertThrowsError(try P384.Signing.PublicKey(pemRepresentation: pemPublicKey), + error: CryptoKitError.incorrectParameterSize) + XCTAssertThrowsError(try P384.KeyAgreement.PublicKey(pemRepresentation: pemPublicKey), + error: CryptoKitError.incorrectParameterSize) + // Now the private keys, which all fail. - XCTAssertThrowsError(try P256.Signing.PrivateKey(pemRepresentation: pemPublicKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P256.KeyAgreement.PrivateKey(pemRepresentation: pemPublicKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P384.Signing.PrivateKey(pemRepresentation: pemPublicKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P384.KeyAgreement.PrivateKey(pemRepresentation: pemPublicKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P521.Signing.PrivateKey(pemRepresentation: pemPublicKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P521.KeyAgreement.PrivateKey(pemRepresentation: pemPublicKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - + XCTAssertThrowsError(try P256.Signing.PrivateKey(pemRepresentation: pemPublicKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P256.KeyAgreement.PrivateKey(pemRepresentation: pemPublicKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P384.Signing.PrivateKey(pemRepresentation: pemPublicKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P384.KeyAgreement.PrivateKey(pemRepresentation: pemPublicKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P521.Signing.PrivateKey(pemRepresentation: pemPublicKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P521.KeyAgreement.PrivateKey(pemRepresentation: pemPublicKey), + error: CryptoKitASN1Error.invalidPEMDocument) + // Validate we can reserialize. let firstReserialization = signingKey.pemRepresentation let secondReserialization = keyAgreementKey.pemRepresentation @@ -408,25 +347,19 @@ class ECKeyEncodingsTests: XCTestCase { XCTAssertThrowsError(try P521.KeyAgreement.PrivateKey(pemRepresentation: pemPrivateKey)) // Now the public keys, which all fail. - XCTAssertThrowsError(try P256.Signing.PublicKey(pemRepresentation: pemPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(pemRepresentation: pemPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P384.Signing.PublicKey(pemRepresentation: pemPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P384.KeyAgreement.PublicKey(pemRepresentation: pemPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P521.Signing.PublicKey(pemRepresentation: pemPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P521.KeyAgreement.PublicKey(pemRepresentation: pemPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - + XCTAssertThrowsError(try P256.Signing.PublicKey(pemRepresentation: pemPrivateKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(pemRepresentation: pemPrivateKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P384.Signing.PublicKey(pemRepresentation: pemPrivateKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P384.KeyAgreement.PublicKey(pemRepresentation: pemPrivateKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P521.Signing.PublicKey(pemRepresentation: pemPrivateKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P521.KeyAgreement.PublicKey(pemRepresentation: pemPrivateKey), + error: CryptoKitASN1Error.invalidPEMDocument) + // Validate we can reserialize. let firstReserialization = signingKey.pemRepresentation let secondReserialization = keyAgreementKey.pemRepresentation @@ -456,25 +389,19 @@ class ECKeyEncodingsTests: XCTestCase { XCTAssertThrowsError(try P521.KeyAgreement.PrivateKey(pemRepresentation: pemPrivateKey)) // Now the public keys, which all fail. - XCTAssertThrowsError(try P256.Signing.PublicKey(pemRepresentation: pemPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(pemRepresentation: pemPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P384.Signing.PublicKey(pemRepresentation: pemPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P384.KeyAgreement.PublicKey(pemRepresentation: pemPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P521.Signing.PublicKey(pemRepresentation: pemPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P521.KeyAgreement.PublicKey(pemRepresentation: pemPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - + XCTAssertThrowsError(try P256.Signing.PublicKey(pemRepresentation: pemPrivateKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(pemRepresentation: pemPrivateKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P384.Signing.PublicKey(pemRepresentation: pemPrivateKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P384.KeyAgreement.PublicKey(pemRepresentation: pemPrivateKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P521.Signing.PublicKey(pemRepresentation: pemPrivateKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P521.KeyAgreement.PublicKey(pemRepresentation: pemPrivateKey), + error: CryptoKitASN1Error.invalidPEMDocument) + // Validate we can reserialize. let firstReserialization = signingKey.pemRepresentation let secondReserialization = keyAgreementKey.pemRepresentation @@ -506,25 +433,19 @@ class ECKeyEncodingsTests: XCTestCase { XCTAssertThrowsError(try P384.KeyAgreement.PrivateKey(pemRepresentation: pemPrivateKey)) // Now the public keys, which all fail. - XCTAssertThrowsError(try P256.Signing.PublicKey(pemRepresentation: pemPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(pemRepresentation: pemPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P384.Signing.PublicKey(pemRepresentation: pemPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P384.KeyAgreement.PublicKey(pemRepresentation: pemPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P521.Signing.PublicKey(pemRepresentation: pemPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P521.KeyAgreement.PublicKey(pemRepresentation: pemPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - + XCTAssertThrowsError(try P256.Signing.PublicKey(pemRepresentation: pemPrivateKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(pemRepresentation: pemPrivateKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P384.Signing.PublicKey(pemRepresentation: pemPrivateKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P384.KeyAgreement.PublicKey(pemRepresentation: pemPrivateKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P521.Signing.PublicKey(pemRepresentation: pemPrivateKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P521.KeyAgreement.PublicKey(pemRepresentation: pemPrivateKey), + error: CryptoKitASN1Error.invalidPEMDocument) + // Validate we can reserialize. let firstReserialization = signingKey.pemRepresentation let secondReserialization = keyAgreementKey.pemRepresentation @@ -553,25 +474,19 @@ class ECKeyEncodingsTests: XCTestCase { XCTAssertThrowsError(try P521.KeyAgreement.PrivateKey(pemRepresentation: pemPrivateKey)) // Now the public keys, which all fail. - XCTAssertThrowsError(try P256.Signing.PublicKey(pemRepresentation: pemPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(pemRepresentation: pemPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P384.Signing.PublicKey(pemRepresentation: pemPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P384.KeyAgreement.PublicKey(pemRepresentation: pemPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P521.Signing.PublicKey(pemRepresentation: pemPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P521.KeyAgreement.PublicKey(pemRepresentation: pemPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - + XCTAssertThrowsError(try P256.Signing.PublicKey(pemRepresentation: pemPrivateKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(pemRepresentation: pemPrivateKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P384.Signing.PublicKey(pemRepresentation: pemPrivateKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P384.KeyAgreement.PublicKey(pemRepresentation: pemPrivateKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P521.Signing.PublicKey(pemRepresentation: pemPrivateKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P521.KeyAgreement.PublicKey(pemRepresentation: pemPrivateKey), + error: CryptoKitASN1Error.invalidPEMDocument) + // We can't reserialize the SEC1 keys, we don't emit them. } @@ -597,25 +512,19 @@ class ECKeyEncodingsTests: XCTestCase { XCTAssertThrowsError(try P521.KeyAgreement.PrivateKey(pemRepresentation: pemPrivateKey)) // Now the public keys, which all fail. - XCTAssertThrowsError(try P256.Signing.PublicKey(pemRepresentation: pemPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(pemRepresentation: pemPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P384.Signing.PublicKey(pemRepresentation: pemPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P384.KeyAgreement.PublicKey(pemRepresentation: pemPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P521.Signing.PublicKey(pemRepresentation: pemPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P521.KeyAgreement.PublicKey(pemRepresentation: pemPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - + XCTAssertThrowsError(try P256.Signing.PublicKey(pemRepresentation: pemPrivateKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(pemRepresentation: pemPrivateKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P384.Signing.PublicKey(pemRepresentation: pemPrivateKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P384.KeyAgreement.PublicKey(pemRepresentation: pemPrivateKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P521.Signing.PublicKey(pemRepresentation: pemPrivateKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P521.KeyAgreement.PublicKey(pemRepresentation: pemPrivateKey), + error: CryptoKitASN1Error.invalidPEMDocument) + // We can't reserialize the SEC1 keys, we don't emit them. } @@ -642,25 +551,19 @@ class ECKeyEncodingsTests: XCTestCase { XCTAssertThrowsError(try P384.KeyAgreement.PrivateKey(pemRepresentation: pemPrivateKey)) // Now the public keys, which all fail. - XCTAssertThrowsError(try P256.Signing.PublicKey(pemRepresentation: pemPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(pemRepresentation: pemPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P384.Signing.PublicKey(pemRepresentation: pemPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P384.KeyAgreement.PublicKey(pemRepresentation: pemPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P521.Signing.PublicKey(pemRepresentation: pemPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - XCTAssertThrowsError(try P521.KeyAgreement.PublicKey(pemRepresentation: pemPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .invalidPEMDocument) - } - + XCTAssertThrowsError(try P256.Signing.PublicKey(pemRepresentation: pemPrivateKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(pemRepresentation: pemPrivateKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P384.Signing.PublicKey(pemRepresentation: pemPrivateKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P384.KeyAgreement.PublicKey(pemRepresentation: pemPrivateKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P521.Signing.PublicKey(pemRepresentation: pemPrivateKey), + error: CryptoKitASN1Error.invalidPEMDocument) + XCTAssertThrowsError(try P521.KeyAgreement.PublicKey(pemRepresentation: pemPrivateKey), + error: CryptoKitASN1Error.invalidPEMDocument) + // We can't reserialize the SEC1 keys, we don't emit them. } @@ -674,51 +577,29 @@ class ECKeyEncodingsTests: XCTestCase { XCTAssertEqual(signingKey.rawRepresentation, keyAgreementKey.rawRepresentation) // Now the non-matching public keys. - XCTAssertThrowsError(try P384.Signing.PublicKey(derRepresentation: derPublicKey)) { error in - guard case .incorrectParameterSize = error as? CryptoKitError else { - XCTFail("Unexpected error: \(error)") - return - } - } - XCTAssertThrowsError(try P384.KeyAgreement.PublicKey(derRepresentation: derPublicKey)) { error in - guard case .incorrectParameterSize = error as? CryptoKitError else { - XCTFail("Unexpected error: \(error)") - return - } - } - XCTAssertThrowsError(try P521.Signing.PublicKey(derRepresentation: derPublicKey)) { error in - guard case .incorrectParameterSize = error as? CryptoKitError else { - XCTFail("Unexpected error: \(error)") - return - } - } - XCTAssertThrowsError(try P521.KeyAgreement.PublicKey(derRepresentation: derPublicKey)) { error in - guard case .incorrectParameterSize = error as? CryptoKitError else { - XCTFail("Unexpected error: \(error)") - return - } - } - + XCTAssertThrowsError(try P384.Signing.PublicKey(derRepresentation: derPublicKey), + error: CryptoKitError.incorrectParameterSize) + XCTAssertThrowsError(try P384.KeyAgreement.PublicKey(derRepresentation: derPublicKey), + error: CryptoKitError.incorrectParameterSize) + XCTAssertThrowsError(try P521.Signing.PublicKey(derRepresentation: derPublicKey), + error: CryptoKitError.incorrectParameterSize) + XCTAssertThrowsError(try P521.KeyAgreement.PublicKey(derRepresentation: derPublicKey), + error: CryptoKitError.incorrectParameterSize) + // Now the private keys, which all fail. - XCTAssertThrowsError(try P256.Signing.PrivateKey(derRepresentation: derPublicKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P256.KeyAgreement.PrivateKey(derRepresentation: derPublicKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P384.Signing.PrivateKey(derRepresentation: derPublicKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P384.KeyAgreement.PrivateKey(derRepresentation: derPublicKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P521.Signing.PrivateKey(derRepresentation: derPublicKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P521.KeyAgreement.PrivateKey(derRepresentation: derPublicKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - + XCTAssertThrowsError(try P256.Signing.PrivateKey(derRepresentation: derPublicKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P256.KeyAgreement.PrivateKey(derRepresentation: derPublicKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P384.Signing.PrivateKey(derRepresentation: derPublicKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P384.KeyAgreement.PrivateKey(derRepresentation: derPublicKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P521.Signing.PrivateKey(derRepresentation: derPublicKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P521.KeyAgreement.PrivateKey(derRepresentation: derPublicKey), + error: CryptoKitASN1Error.unexpectedFieldType) + // Validate we can reserialize. let firstReserialization = signingKey.derRepresentation let secondReserialization = keyAgreementKey.derRepresentation @@ -736,51 +617,29 @@ class ECKeyEncodingsTests: XCTestCase { XCTAssertEqual(signingKey.rawRepresentation, keyAgreementKey.rawRepresentation) // Now the non-matching public keys. - XCTAssertThrowsError(try P256.Signing.PublicKey(derRepresentation: derPublicKey)) { error in - guard case .incorrectParameterSize = error as? CryptoKitError else { - XCTFail("Unexpected error: \(error)") - return - } - } - XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(derRepresentation: derPublicKey)) { error in - guard case .incorrectParameterSize = error as? CryptoKitError else { - XCTFail("Unexpected error: \(error)") - return - } - } - XCTAssertThrowsError(try P521.Signing.PublicKey(derRepresentation: derPublicKey)) { error in - guard case .incorrectParameterSize = error as? CryptoKitError else { - XCTFail("Unexpected error: \(error)") - return - } - } - XCTAssertThrowsError(try P521.KeyAgreement.PublicKey(derRepresentation: derPublicKey)) { error in - guard case .incorrectParameterSize = error as? CryptoKitError else { - XCTFail("Unexpected error: \(error)") - return - } - } - + XCTAssertThrowsError(try P256.Signing.PublicKey(derRepresentation: derPublicKey), + error: CryptoKitError.incorrectParameterSize) + XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(derRepresentation: derPublicKey), + error: CryptoKitError.incorrectParameterSize) + XCTAssertThrowsError(try P521.Signing.PublicKey(derRepresentation: derPublicKey), + error: CryptoKitError.incorrectParameterSize) + XCTAssertThrowsError(try P521.KeyAgreement.PublicKey(derRepresentation: derPublicKey), + error: CryptoKitError.incorrectParameterSize) + // Now the private keys, which all fail. - XCTAssertThrowsError(try P256.Signing.PrivateKey(derRepresentation: derPublicKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P256.KeyAgreement.PrivateKey(derRepresentation: derPublicKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P384.Signing.PrivateKey(derRepresentation: derPublicKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P384.KeyAgreement.PrivateKey(derRepresentation: derPublicKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P521.Signing.PrivateKey(derRepresentation: derPublicKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P521.KeyAgreement.PrivateKey(derRepresentation: derPublicKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - + XCTAssertThrowsError(try P256.Signing.PrivateKey(derRepresentation: derPublicKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P256.KeyAgreement.PrivateKey(derRepresentation: derPublicKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P384.Signing.PrivateKey(derRepresentation: derPublicKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P384.KeyAgreement.PrivateKey(derRepresentation: derPublicKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P521.Signing.PrivateKey(derRepresentation: derPublicKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P521.KeyAgreement.PrivateKey(derRepresentation: derPublicKey), + error: CryptoKitASN1Error.unexpectedFieldType) + // Validate we can reserialize. let firstReserialization = signingKey.derRepresentation let secondReserialization = keyAgreementKey.derRepresentation @@ -798,51 +657,29 @@ class ECKeyEncodingsTests: XCTestCase { XCTAssertEqual(signingKey.rawRepresentation, keyAgreementKey.rawRepresentation) // Now the non-matching public keys. - XCTAssertThrowsError(try P256.Signing.PublicKey(derRepresentation: derPublicKey)) { error in - guard case .incorrectParameterSize = error as? CryptoKitError else { - XCTFail("Unexpected error: \(error)") - return - } - } - XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(derRepresentation: derPublicKey)) { error in - guard case .incorrectParameterSize = error as? CryptoKitError else { - XCTFail("Unexpected error: \(error)") - return - } - } - XCTAssertThrowsError(try P384.Signing.PublicKey(derRepresentation: derPublicKey)) { error in - guard case .incorrectParameterSize = error as? CryptoKitError else { - XCTFail("Unexpected error: \(error)") - return - } - } - XCTAssertThrowsError(try P384.KeyAgreement.PublicKey(derRepresentation: derPublicKey)) { error in - guard case .incorrectParameterSize = error as? CryptoKitError else { - XCTFail("Unexpected error: \(error)") - return - } - } - + XCTAssertThrowsError(try P256.Signing.PublicKey(derRepresentation: derPublicKey), + error: CryptoKitError.incorrectParameterSize) + XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(derRepresentation: derPublicKey), + error: CryptoKitError.incorrectParameterSize) + XCTAssertThrowsError(try P384.Signing.PublicKey(derRepresentation: derPublicKey), + error: CryptoKitError.incorrectParameterSize) + XCTAssertThrowsError(try P384.KeyAgreement.PublicKey(derRepresentation: derPublicKey), + error: CryptoKitError.incorrectParameterSize) + // Now the private keys, which all fail. - XCTAssertThrowsError(try P256.Signing.PrivateKey(derRepresentation: derPublicKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P256.KeyAgreement.PrivateKey(derRepresentation: derPublicKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P384.Signing.PrivateKey(derRepresentation: derPublicKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P384.KeyAgreement.PrivateKey(derRepresentation: derPublicKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P521.Signing.PrivateKey(derRepresentation: derPublicKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P521.KeyAgreement.PrivateKey(derRepresentation: derPublicKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - + XCTAssertThrowsError(try P256.Signing.PrivateKey(derRepresentation: derPublicKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P256.KeyAgreement.PrivateKey(derRepresentation: derPublicKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P384.Signing.PrivateKey(derRepresentation: derPublicKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P384.KeyAgreement.PrivateKey(derRepresentation: derPublicKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P521.Signing.PrivateKey(derRepresentation: derPublicKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P521.KeyAgreement.PrivateKey(derRepresentation: derPublicKey), + error: CryptoKitASN1Error.unexpectedFieldType) + // Validate we can reserialize. let firstReserialization = signingKey.derRepresentation let secondReserialization = keyAgreementKey.derRepresentation @@ -866,25 +703,19 @@ class ECKeyEncodingsTests: XCTestCase { XCTAssertThrowsError(try P521.KeyAgreement.PrivateKey(derRepresentation: derPrivateKey)) // Now the public keys, which all fail. - XCTAssertThrowsError(try P256.Signing.PublicKey(derRepresentation: derPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(derRepresentation: derPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P384.Signing.PublicKey(derRepresentation: derPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P384.KeyAgreement.PublicKey(derRepresentation: derPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P521.Signing.PublicKey(derRepresentation: derPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P521.KeyAgreement.PublicKey(derRepresentation: derPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - + XCTAssertThrowsError(try P256.Signing.PublicKey(derRepresentation: derPrivateKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(derRepresentation: derPrivateKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P384.Signing.PublicKey(derRepresentation: derPrivateKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P384.KeyAgreement.PublicKey(derRepresentation: derPrivateKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P521.Signing.PublicKey(derRepresentation: derPrivateKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P521.KeyAgreement.PublicKey(derRepresentation: derPrivateKey), + error: CryptoKitASN1Error.unexpectedFieldType) + // Validate we can reserialize. let firstReserialization = signingKey.derRepresentation let secondReserialization = keyAgreementKey.derRepresentation @@ -908,25 +739,19 @@ class ECKeyEncodingsTests: XCTestCase { XCTAssertThrowsError(try P521.KeyAgreement.PrivateKey(derRepresentation: derPrivateKey)) // Now the public keys, which all fail. - XCTAssertThrowsError(try P256.Signing.PublicKey(derRepresentation: derPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(derRepresentation: derPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P384.Signing.PublicKey(derRepresentation: derPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P384.KeyAgreement.PublicKey(derRepresentation: derPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P521.Signing.PublicKey(derRepresentation: derPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P521.KeyAgreement.PublicKey(derRepresentation: derPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - + XCTAssertThrowsError(try P256.Signing.PublicKey(derRepresentation: derPrivateKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(derRepresentation: derPrivateKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P384.Signing.PublicKey(derRepresentation: derPrivateKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P384.KeyAgreement.PublicKey(derRepresentation: derPrivateKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P521.Signing.PublicKey(derRepresentation: derPrivateKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P521.KeyAgreement.PublicKey(derRepresentation: derPrivateKey), + error: CryptoKitASN1Error.unexpectedFieldType) + // Validate we can reserialize. let firstReserialization = signingKey.derRepresentation let secondReserialization = keyAgreementKey.derRepresentation @@ -950,25 +775,19 @@ class ECKeyEncodingsTests: XCTestCase { XCTAssertThrowsError(try P384.KeyAgreement.PrivateKey(derRepresentation: derPrivateKey)) // Now the public keys, which all fail. - XCTAssertThrowsError(try P256.Signing.PublicKey(derRepresentation: derPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(derRepresentation: derPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P384.Signing.PublicKey(derRepresentation: derPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P384.KeyAgreement.PublicKey(derRepresentation: derPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P521.Signing.PublicKey(derRepresentation: derPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P521.KeyAgreement.PublicKey(derRepresentation: derPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - + XCTAssertThrowsError(try P256.Signing.PublicKey(derRepresentation: derPrivateKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(derRepresentation: derPrivateKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P384.Signing.PublicKey(derRepresentation: derPrivateKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P384.KeyAgreement.PublicKey(derRepresentation: derPrivateKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P521.Signing.PublicKey(derRepresentation: derPrivateKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P521.KeyAgreement.PublicKey(derRepresentation: derPrivateKey), + error: CryptoKitASN1Error.unexpectedFieldType) + // Validate we can reserialize. let firstReserialization = signingKey.derRepresentation let secondReserialization = keyAgreementKey.derRepresentation @@ -992,25 +811,19 @@ class ECKeyEncodingsTests: XCTestCase { XCTAssertThrowsError(try P521.KeyAgreement.PrivateKey(derRepresentation: derPrivateKey)) // Now the public keys, which all fail. - XCTAssertThrowsError(try P256.Signing.PublicKey(derRepresentation: derPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(derRepresentation: derPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P384.Signing.PublicKey(derRepresentation: derPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P384.KeyAgreement.PublicKey(derRepresentation: derPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P521.Signing.PublicKey(derRepresentation: derPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P521.KeyAgreement.PublicKey(derRepresentation: derPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - + XCTAssertThrowsError(try P256.Signing.PublicKey(derRepresentation: derPrivateKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(derRepresentation: derPrivateKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P384.Signing.PublicKey(derRepresentation: derPrivateKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P384.KeyAgreement.PublicKey(derRepresentation: derPrivateKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P521.Signing.PublicKey(derRepresentation: derPrivateKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P521.KeyAgreement.PublicKey(derRepresentation: derPrivateKey), + error: CryptoKitASN1Error.unexpectedFieldType) + // We can't reserialize the SEC1 keys, we don't emit them. } @@ -1030,25 +843,19 @@ class ECKeyEncodingsTests: XCTestCase { XCTAssertThrowsError(try P521.KeyAgreement.PrivateKey(derRepresentation: derPrivateKey)) // Now the public keys, which all fail. - XCTAssertThrowsError(try P256.Signing.PublicKey(derRepresentation: derPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(derRepresentation: derPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P384.Signing.PublicKey(derRepresentation: derPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P384.KeyAgreement.PublicKey(derRepresentation: derPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P521.Signing.PublicKey(derRepresentation: derPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P521.KeyAgreement.PublicKey(derRepresentation: derPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - + XCTAssertThrowsError(try P256.Signing.PublicKey(derRepresentation: derPrivateKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(derRepresentation: derPrivateKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P384.Signing.PublicKey(derRepresentation: derPrivateKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P384.KeyAgreement.PublicKey(derRepresentation: derPrivateKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P521.Signing.PublicKey(derRepresentation: derPrivateKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P521.KeyAgreement.PublicKey(derRepresentation: derPrivateKey), + error: CryptoKitASN1Error.unexpectedFieldType) + // We can't reserialize the SEC1 keys, we don't emit them. } @@ -1068,25 +875,19 @@ class ECKeyEncodingsTests: XCTestCase { XCTAssertThrowsError(try P384.KeyAgreement.PrivateKey(derRepresentation: derPrivateKey)) // Now the public keys, which all fail. - XCTAssertThrowsError(try P256.Signing.PublicKey(derRepresentation: derPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(derRepresentation: derPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P384.Signing.PublicKey(derRepresentation: derPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P384.KeyAgreement.PublicKey(derRepresentation: derPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P521.Signing.PublicKey(derRepresentation: derPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - XCTAssertThrowsError(try P521.KeyAgreement.PublicKey(derRepresentation: derPrivateKey)) { error in - XCTAssertEqual(error as? CryptoKitASN1Error, .unexpectedFieldType) - } - + XCTAssertThrowsError(try P256.Signing.PublicKey(derRepresentation: derPrivateKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P256.KeyAgreement.PublicKey(derRepresentation: derPrivateKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P384.Signing.PublicKey(derRepresentation: derPrivateKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P384.KeyAgreement.PublicKey(derRepresentation: derPrivateKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P521.Signing.PublicKey(derRepresentation: derPrivateKey), + error: CryptoKitASN1Error.unexpectedFieldType) + XCTAssertThrowsError(try P521.KeyAgreement.PublicKey(derRepresentation: derPrivateKey), + error: CryptoKitASN1Error.unexpectedFieldType) + // We can't reserialize the SEC1 keys, we don't emit them. } @@ -1124,10 +925,20 @@ class ECKeyEncodingsTests: XCTestCase { let publicKey = privateKey.publicKey try XCTAssertNoThrow(P256.KeyAgreement.PublicKey(x963Representation: publicKey.x963Representation)) - try XCTAssertThrowsError(P256.KeyAgreement.PublicKey(x963Representation: publicKey.compressedRepresentation)) { error in - XCTAssertTrue(error is CryptoKitError) - XCTAssertEqual(error as? CryptoKitError, .incorrectParameterSize) - } + try XCTAssertThrowsError(P256.KeyAgreement.PublicKey(x963Representation: publicKey.compressedRepresentation), + error: CryptoKitError.incorrectParameterSize) } } +fileprivate extension Data { + init?(base64urlEncoded input: String) { + var base64 = input + base64 = base64.replacingOccurrences(of: "-", with: "+") + base64 = base64.replacingOccurrences(of: "_", with: "/") + while base64.count % 4 != 0 { + base64 = base64.appending("=") + } + self.init(base64Encoded: base64) + } +} + #endif // CRYPTO_IN_SWIFTPM diff --git a/Tests/CryptoTests/HPKE/HPKETests-TestVectors.swift b/Tests/CryptoTests/HPKE/HPKETests-TestVectors.swift index 56e941416..0ce8fa259 100644 --- a/Tests/CryptoTests/HPKE/HPKETests-TestVectors.swift +++ b/Tests/CryptoTests/HPKE/HPKETests-TestVectors.swift @@ -18,13 +18,13 @@ import XCTest // Skip tests that require @testable imports of CryptoKit. #else #if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API -@testable import CryptoKit +@testable @_spi(HPKEAlgID) import CryptoKit #else -@testable import Crypto +@testable @_spi(HPKEAlgID) import Crypto #endif // Curve448 is not supported on our platforms -var unsupportedKEMs: [UInt16] = [0x0021] +let unsupportedKEMs: [UInt16] = [0x0021] struct HPKETestEncryption: Codable { let aad: String @@ -97,6 +97,9 @@ class HPKETestVectors: XCTestCase { XCTAssertNoThrow(try testWithKEM(tv, ciphersuite: ciphersuite, skR: P521.KeyAgreement.PrivateKey(rawRepresentation: skRBytes))) case .Curve25519_HKDF_SHA256: XCTAssertNoThrow(try testWithKEM(tv, ciphersuite: ciphersuite, skR: Curve25519.KeyAgreement.PrivateKey(rawRepresentation: skRBytes))) + case .XWingMLKEM768X25519: + // There are no test vectors for this implementation + break } } diff --git a/Tests/CryptoTests/HPKE/HPKETests.swift b/Tests/CryptoTests/HPKE/HPKETests.swift index cca6397ca..80fb0ac16 100644 --- a/Tests/CryptoTests/HPKE/HPKETests.swift +++ b/Tests/CryptoTests/HPKE/HPKETests.swift @@ -18,20 +18,28 @@ import XCTest // Skip tests that require @testable imports of CryptoKit. #else #if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +@testable @_spi(HPKEAlgID) import CryptoKit @testable import CryptoKit #else -@testable import Crypto +@testable @_spi(HPKEAlgID) import Crypto #endif class HPKETests: XCTestCase { func testCases() throws { - let ciphersuitesToTest = [HPKE.Ciphersuite.P256_SHA256_AES_GCM_256, .P384_SHA384_AES_GCM_256, .P521_SHA512_AES_GCM_256, .Curve25519_SHA256_ChachaPoly] - + var ciphersuitesToTest = [ + HPKE.Ciphersuite.P256_SHA256_AES_GCM_256, .P384_SHA384_AES_GCM_256, .P521_SHA512_AES_GCM_256, .Curve25519_SHA256_ChachaPoly + ] + if #available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, macCatalyst 19.0, *) { + ciphersuitesToTest.append(contentsOf: [ + .XWingMLKEM768X25519_SHA256_AES_GCM_256 + ]) + } + for ciphersuite in ciphersuitesToTest { try testCiphersuite(ciphersuite) } } - + func testMismatchedKEM() { let skR = P256.KeyAgreement.PrivateKey() XCTAssertThrowsError(try HPKE.Sender(recipientKey: skR.publicKey, ciphersuite: .P384_SHA384_AES_GCM_256, info: Data())) @@ -47,16 +55,29 @@ class HPKETests: XCTestCase { try testCiphersuite(ciphersuite, withKeys: P521.KeyAgreement.PrivateKey.self) case .Curve25519_HKDF_SHA256: try testCiphersuite(ciphersuite, withKeys: Curve25519.KeyAgreement.PrivateKey.self) + case .XWingMLKEM768X25519: + if #available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, macCatalyst 19.0, *) { + try testHPKECiphersuite(ciphersuite, withKeys: XWingMLKEM768X25519.PrivateKey.self) + } else { /* pass */ } + @unknown default: + fatalError() } - } - + + func testHPKECiphersuite(_ c: HPKE.Ciphersuite, withKeys: SK.Type) throws { + let skR = try SK.PublicKey.EphemeralPrivateKey() + let info = Data("Some Test Data".utf8) + var sender = try HPKE.Sender(recipientKey: skR.publicKey, ciphersuite: c, info: info) + var recipient = try HPKE.Recipient(privateKey: skR, ciphersuite: c, info: info, encapsulatedKey: sender.encapsulatedKey) + XCTAssertNoThrow(try testSenderRecipient(sender: &sender, recipient: &recipient)) + } + func testCiphersuite(_ c: HPKE.Ciphersuite, withKeys: SK.Type) throws { let skS = SK.PublicKey.EphemeralPrivateKey() let skR = SK.PublicKey.EphemeralPrivateKey() let info = Data("Some Test Data".utf8) - let psk = SymmetricKey(size: .bits256) + let psk = SymmetricKey(size: SymmetricKeySize.bits256) let pskID = Data(SHA256.hash(data: info)) // Testing base mode @@ -83,7 +104,7 @@ class HPKETests: XCTestCase { func testSenderRecipient(sender: inout HPKE.Sender, recipient: inout HPKE.Recipient) throws { let msg = Data("Some Other Data".utf8) let aad = Data("Some Authenticated Data".utf8) - XCTAssertEqual(sender.exporterSecret, recipient.exporterSecret) + XCTAssertEqual(try sender.exportSecret(context: Data("SampleContext".utf8), outputByteCount: 16), try recipient.exportSecret(context: Data("SampleContext".utf8), outputByteCount: 16)) for _ in 0...100 { let ct = try sender.seal(msg, authenticating: msg) @@ -103,6 +124,52 @@ class HPKETests: XCTestCase { XCTAssertThrowsError(try recipient.open(ct, authenticating: aad)) XCTAssertEqual(try recipient.open(ct, authenticating: aad2), msg) } + + func testHPKEIdentifiers() throws { + /* + HPKE.Ciphersuite.P256_SHA256_AES_GCM_256, .P384_SHA384_AES_GCM_256, .P521_SHA512_AES_GCM_256, .Curve25519_SHA256_ChachaPoly + */ + let cp256 = HPKE.Ciphersuite.P256_SHA256_AES_GCM_256 + XCTAssertEqual(cp256.kem.value, 0x0010) + XCTAssertEqual(cp256.kem.nEnc, 65) + XCTAssertEqual(cp256.kdf.value, 0x0001) + XCTAssertEqual(cp256.aead.value, 0x0002) + XCTAssertEqual(cp256.aead.keyByteCount, 32) + XCTAssertEqual(cp256.aead.nonceByteCount, 12) + XCTAssertEqual(cp256.aead.tagByteCount, 16) + + let cp384 = HPKE.Ciphersuite.P384_SHA384_AES_GCM_256 + XCTAssertEqual(cp384.kem.value, 0x0011) + XCTAssertEqual(cp384.kem.nEnc, 97) + XCTAssertEqual(cp384.kdf.value, 0x0002) + XCTAssertEqual(cp384.aead.value, 0x0002) + + let cp521 = HPKE.Ciphersuite.P521_SHA512_AES_GCM_256 + XCTAssertEqual(cp521.kem.value, 0x0012) + XCTAssertEqual(cp521.kem.nEnc, 133) + XCTAssertEqual(cp521.kdf.value, 0x0003) + XCTAssertEqual(cp521.aead.value, 0x0002) + + let cc25519 = HPKE.Ciphersuite.Curve25519_SHA256_ChachaPoly + XCTAssertEqual(cc25519.kem.value, 0x0020) + XCTAssertEqual(cc25519.kem.nEnc, 32) + XCTAssertEqual(cc25519.kdf.value, 0x0001) + XCTAssertEqual(cc25519.aead.value, 0x0003) + XCTAssertEqual(cc25519.aead.keyByteCount, 32) + XCTAssertEqual(cc25519.aead.nonceByteCount, 12) + XCTAssertEqual(cc25519.aead.tagByteCount, 16) + } + + func testHPKEKEMInterface() throws { + if #available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, macCatalyst 19.0, *) { + let c = HPKE.Ciphersuite.XWingMLKEM768X25519_SHA256_AES_GCM_256 + let skR = try XWingMLKEM768X25519.PrivateKey.generate() + let info = Data("Some Test Data".utf8) + var sender = try HPKE.Sender(recipientKey: skR.publicKey, ciphersuite: c, info: info) + var recipient = try HPKE.Recipient(privateKey: skR, ciphersuite: c, info: info, encapsulatedKey: sender.encapsulatedKey) + XCTAssertNoThrow(try testSenderRecipient(sender: &sender, recipient: &recipient)) + } + } } #endif // CRYPTO_IN_SWIFTPM diff --git a/Tests/CryptoTests/KEM/Boring/XWingTests_boring.swift b/Tests/CryptoTests/KEM/Boring/XWingTests_boring.swift new file mode 100644 index 000000000..07180137d --- /dev/null +++ b/Tests/CryptoTests/KEM/Boring/XWingTests_boring.swift @@ -0,0 +1,52 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2025 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +// Skip tests that require @testable imports of CryptoKit. +#else +#if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +@testable import CryptoKit +#else +@testable import Crypto +#endif + +extension XWingMLKEM768X25519.PrivateKey { + static func generateWithRng(ccrngState: SequenceDrbg) throws -> Self { + // We're going to generate a "random" seed. + var seed: [UInt8] = [] + seed.reserveCapacity(32) + + for i in 0..<32 { + seed.append(ccrngState.state[i % ccrngState.state.count]) + } + + return try Self(seedRepresentation: seed, publicKey: nil) + } +} + +extension XWingMLKEM768X25519.PublicKey { + func encapsulateWithRng(ccrngState: SequenceDrbg) throws -> KEM.EncapsulationResult { + // We're going to generate "random" entropy + var seed: [UInt8] = [] + seed.reserveCapacity(64) + + for i in 0..<64 { + seed.append(ccrngState.state[i % ccrngState.state.count]) + } + + return try self.impl.encapsulateWithOptionalEntropy(entropy: seed) + } +} + +#endif // CRYPTO_IN_SWIFTPM diff --git a/Tests/CryptoTests/KEM/MLKEM1024KAT.json b/Tests/CryptoTests/KEM/MLKEM1024KAT.json new file mode 100644 index 000000000..67050dc89 --- /dev/null +++ b/Tests/CryptoTests/KEM/MLKEM1024KAT.json @@ -0,0 +1,702 @@ +[ +{ + "rngSeed" : "061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1", + "pk" : "537911957C125148A87F41589CB222D0D19229E2CB55E1A044791E7CA61192A46460C3183D2BCD6DE08A5E7651603ACC349CA16CBA18ABB23A3E8C330D7421598A6278EC7EBFABCA0EF488B2290554753499C0452E453815309955B8150FA1A1E393386DC12FDB27B38C6745F2944016EC457F39B18D604A07A1ABE07BC844050FFA8A06FA154A49D88FAC775452D6A7C0E589BFB5C370C2C4B6201DDA80C9AB2076ECC08B44522FDA3326F033806DD2693F319739F40C4F42B24ACA7098FB8FF5F9AC20292D02B56AC746801ACCCC84863DEE32878497B69438BF991776286650482C8D9D9587BC6A55B85C4D7FA74D02656B421C9E23E03A48D4B74425C26E4A20DD9562A4DA0793F3A352CCC0F18217D868C7F5002ABE768B1FC73F05744E7CC28F10344062C10E08ECCCED3C1F7D392C01D979DD718D8398374665A16A9870585C39D5589A50E133389C9B9A276C024260D9FC7711C81B6337B57DA3C376D0CD74E14C73727B276656B9D8A4EB71896FF589D4B893E7110F3BB948ECE291DD86C0B7468A678C746980C12AA6B95E2B0CBE4331BB24A33A270153AA472C47312382CA365C5F35259D025746FC6595FE636C767510A69C1E8A176B7949958F2697399497A2FC7364A12C8198295239C826CB5082086077282ED628651FC04C639B438522A9DE309B14B086D6E923C551623BD72A733CB0DABC54A9416A99E72C9FDA1CB3FB9BA06B8ADB2422D68CADC553C98202A17656478AC044EF3456378ABCE9991E0141BA79094FA8F77A300805D2D32FFC62BF0CA4554C330C2BB7042DB35102F68B1A0062583865381C74DD913AF70B26CF0923D0C4CB971692222552A8F4B788B4AFD1341A9DF415CF203900F5CCF7F65988949A75580D049639853100854B21F4018003502BB1BA95F556A5D67C7EB52410EBA288A6D0635CA8A4F6D696D0A020C826938D34943C3808C79CC007768533216BC1B29DA6C812EFF3340BAA8D2E65344F09BD47894F5A3A4118715B3C5020679327F9189F7E10856B238BB9B0AB4CA85ABF4B21F5C76BCCD71850B22E045928276A0F2E951DB0707C6A116DC19113FA762DC5F20BD5D2AB5BE71744DC9CBDB51EA757963AAC56A90A0D8023BED1F5CAE8A64DA047279B353A096A835B0B2B023B6AA048989233079AEB467E522FA27A5822921E5C551B4F537536E46F3A6A97E72C3B063104E09A040598940D872F6D871F5EF9B4355073B54769E45454E6A0819599408621AB4413B35507B0DF578CE2D511D52058D5749DF38B29D6CC58870CAF92F69A75161406E71C5FF92451A77522B8B2967A2D58A49A81661AA65AC09B08C9FE45ABC3851F99C730C45003ACA2BF0F8424A19B7408A537D541C16F5682BFE3A7FAEA564F1298611A7F5F60922BA19DE73B1917F1853273555199A649318B50773345C997460856972ACB43FC81AB6321B1C33C2BB5098BD489D696A0F70679C1213873D08BDAD42844927216047205633212310EE9A06CB10016C805503C341A36D87E56072EABE23731E34AF7E2328F85CDB370CCAF00515B64C9C54BC837578447AACFAED5969AA351E7DA4EFA7B115C4C51F4A699779850295CA72D781AD41BC680532B89E710E2189EB3C50817BA255C7474C95CA9110CC43B8BA8E682C7FB7B0FDC265C0483A65CA4514EE4B832AAC5800C3B08E74F563951C1FBB210353EFA1AA866856BC1E034733B0485DAB1D020C6BF765FF60B3B801984A90C2FE970BF1DE97004A6CF44B4984AB58258B4AF71221CD17530A700C32959C9436344B5316F09CCCA7029A230D639DCB022D8BA79BA91CD6AB12AE1579C50C7BB10E30301A65CAE3101D40C7BA927BB553148D1647024D4A06C8166D0B0B81269B7D5F4B34FB022F69152F514004A7C685368552343BB60360FBB9945EDF446D345BDCAA7455C74BA0A551E184620FEF97688773D50B6433CA7A7AC5CB6B7F671A15376E5A6747A623FA7BC6630373F5B1B512690A661377870A60A7A189683F9B0CF0466E1F750762631C4AB09F505C42DD28633569472735442851E321616D4009810777B6BD46FA7224461A5CC27405DFBAC0D39B002CAB33433F2A86EB8CE91C134A6386F860A1994EB4B6875A46D195581D173854B53D2293DF3E9A822756CD8F212B325CA29B4F9F8CFBADF2E41869ABFBAD10738AD04CC752BC20C394746850E0C4847DB", + "sk" : "433A70EE6950F9882ACDD5A47820A6A8163708F04D457C779979B83FE117224701490830386637DA332E74B1AEDA0B2F81CA4F9BB2C2B02B0CFD680C11482F335ACF7B9139B5B88A34E3542C6861377545983343CD829414E47864212E78F855F52390379ACC3A62953131B63EE832ADB3BF4BF58E247349B5E097E55ABE497B15982373AE732E0439AC67D05C7F037C8A739B18140E144C851DC9611F4BCF04F3A2093C197BD63BB5E6190100545FF81DB7FCCDDD9A324B0BAC3C2C2382284058F08B961952C094019C10BE37A53D5AC794C010A9D0821F15027A1C419C3C71C9A1D28AED02597AB79B875394626BA39ADC090C3A90CF75871A65275EB1C5B03372E13A1A23D0CF9374111F80CC83A905622B83FC513971EC8419F0880C3067633671B09B5456AB6057936D19A4A2A267911B000A13956FBD493821DA072C04642B0C20DA6CC0D9D864A39365DFD64F10187825FA33250749CBC0C905D7B1FF3CAE2412BF86B81A817B86BAA30EDF7862E5F6BAC98726E56B3CEC60664CAA2A7DF670C5E207DFAC03824C89897CB490EAA76521222C86205169C91C329C4A184D78721AF836AD4DB0CA78464D4171473012B7D183BAFA627585C64BE3809D7E6004CBDC79A5460F0AD677CB716512407D3A619AD09543B739547472A706B317A509BE5D861FD66C7D0ED94CD5004795C18159E3A33D798711525F1635A68428172923249635AAD032B9E56664BDD48ED24AC75C6468D1903E471086C5F1567E831A0508C539632591AB577D324A82429725809950761D8434288C14034F1C06C1D0AAE09A71C740A55701C28FF84499F2BB18B6628CAAA3FE75AC4DE04C6F913900D86C88126252A17C4D303991DB0287120881BB88478AAA9AF9BC53D3729843858FDB4648059CAC82C1A10878BA39823B041BD0E258487B56CC8A3220C1A58BF66A172B5B9A0C632D674EAE885A015C4E37BA073680BEDE7534F3E34B6050C86B21C3C090941F23B7F6731E2BDA0E6EA4646771CEC572B98CA0A158919ADBEB84CE585FF9F25EBDDA6CB6F07A8F811232607E7217BB039BABD0D91934A8594059C9687723C04381BFD627A10517F5F4BFC77777AA2671AE124F2B7A5F4D5614029197E6586FA8C17E0AD90781BC7BB19A772D5A4EFE32CAC89B76C42A5EDE9BCC20C1898C08A5B0C07E478B1BBC226EFAD15F2AC737514B8C6149810779222416537ED00DAEAB177E903EAD6B4AC42370AF1B1F50EBAFAA1C6E647BBACCE72C7D0B88AEB0B06FC1A45457A9C187579BF184579CC351C43DFF942605AA5604FC85FC5583F6F1496FE61D70D6CDE2327FEE713D86F29B3AFCBB54E9A92A33A6C1EA6FFA309566B0686233C0F3B1C3144890E4F0829A6099C5749CDEC84328EC2CB64A7385A761D64B3A23C489343343B97723AE78C7D805458E1620F0292897691704CB76E3B0B281A83CF64490498CBCAF04802416B33C565171D772D3B9354037587629AE14A5C5031AC36671A0D0C91CC0B4CD69D8402E33B9BCC2BBAF6B971E303FA137BE232598A4999BC012574C81651B38B38396C1C365303AD25D49FC6B689951A1CC4C6007613065495F97910F9735D4EA4E442ACB2FABAECFE1ADEF0667BA422C954A05D1B6167A263E1275C6ADA8385965304B30324040542CF5A451BCAFC74788BE3B9B9FCC45D4790E2D7335C60A14F0A49D13053F2626A627CA19553CB336A2CB4A455D8EF3989491472BA0051EF7416E0BBF1A6108FA07C161548E7C62331AE5A2B4E4A108A51093D3150821A2FB547170A1B73C43C550C6557A4048A58A2CD77A244234B2235175A0897D5061B4613482DC136414048C11DB37EAE0A5DF87C19314B0E82397A0D338DC21538AF36149D93F8B1A11C53BB5DEF8B7A2CCA3362B7FE3A1408A2547E209058C673A7566C26123A6D8B692A5F33EBDCB2624B79D877BCE5FA14E42E83FAAD82E9900553A3C6045CA329FEA4A506558C491B6A616C6FD400B42136F44CB0D0257650819018D3C568EF6C60C6C409E70A829287108C1B6A4D32F76E5CC4D104B02438EF7A467912398EA9C7CBD9981589A341897687B516A13307D66C068C444B4B949A17412413315CCF49B99980034B5B8CFDEC4A60B9C1E7455AAFBF3A757346990CC32B0599BA217A6C5FC39537911957C125148A87F41589CB222D0D19229E2CB55E1A044791E7CA61192A46460C3183D2BCD6DE08A5E7651603ACC349CA16CBA18ABB23A3E8C330D7421598A6278EC7EBFABCA0EF488B2290554753499C0452E453815309955B8150FA1A1E393386DC12FDB27B38C6745F2944016EC457F39B18D604A07A1ABE07BC844050FFA8A06FA154A49D88FAC775452D6A7C0E589BFB5C370C2C4B6201DDA80C9AB2076ECC08B44522FDA3326F033806DD2693F319739F40C4F42B24ACA7098FB8FF5F9AC20292D02B56AC746801ACCCC84863DEE32878497B69438BF991776286650482C8D9D9587BC6A55B85C4D7FA74D02656B421C9E23E03A48D4B74425C26E4A20DD9562A4DA0793F3A352CCC0F18217D868C7F5002ABE768B1FC73F05744E7CC28F10344062C10E08ECCCED3C1F7D392C01D979DD718D8398374665A16A9870585C39D5589A50E133389C9B9A276C024260D9FC7711C81B6337B57DA3C376D0CD74E14C73727B276656B9D8A4EB71896FF589D4B893E7110F3BB948ECE291DD86C0B7468A678C746980C12AA6B95E2B0CBE4331BB24A33A270153AA472C47312382CA365C5F35259D025746FC6595FE636C767510A69C1E8A176B7949958F2697399497A2FC7364A12C8198295239C826CB5082086077282ED628651FC04C639B438522A9DE309B14B086D6E923C551623BD72A733CB0DABC54A9416A99E72C9FDA1CB3FB9BA06B8ADB2422D68CADC553C98202A17656478AC044EF3456378ABCE9991E0141BA79094FA8F77A300805D2D32FFC62BF0CA4554C330C2BB7042DB35102F68B1A0062583865381C74DD913AF70B26CF0923D0C4CB971692222552A8F4B788B4AFD1341A9DF415CF203900F5CCF7F65988949A75580D049639853100854B21F4018003502BB1BA95F556A5D67C7EB52410EBA288A6D0635CA8A4F6D696D0A020C826938D34943C3808C79CC007768533216BC1B29DA6C812EFF3340BAA8D2E65344F09BD47894F5A3A4118715B3C5020679327F9189F7E10856B238BB9B0AB4CA85ABF4B21F5C76BCCD71850B22E045928276A0F2E951DB0707C6A116DC19113FA762DC5F20BD5D2AB5BE71744DC9CBDB51EA757963AAC56A90A0D8023BED1F5CAE8A64DA047279B353A096A835B0B2B023B6AA048989233079AEB467E522FA27A5822921E5C551B4F537536E46F3A6A97E72C3B063104E09A040598940D872F6D871F5EF9B4355073B54769E45454E6A0819599408621AB4413B35507B0DF578CE2D511D52058D5749DF38B29D6CC58870CAF92F69A75161406E71C5FF92451A77522B8B2967A2D58A49A81661AA65AC09B08C9FE45ABC3851F99C730C45003ACA2BF0F8424A19B7408A537D541C16F5682BFE3A7FAEA564F1298611A7F5F60922BA19DE73B1917F1853273555199A649318B50773345C997460856972ACB43FC81AB6321B1C33C2BB5098BD489D696A0F70679C1213873D08BDAD42844927216047205633212310EE9A06CB10016C805503C341A36D87E56072EABE23731E34AF7E2328F85CDB370CCAF00515B64C9C54BC837578447AACFAED5969AA351E7DA4EFA7B115C4C51F4A699779850295CA72D781AD41BC680532B89E710E2189EB3C50817BA255C7474C95CA9110CC43B8BA8E682C7FB7B0FDC265C0483A65CA4514EE4B832AAC5800C3B08E74F563951C1FBB210353EFA1AA866856BC1E034733B0485DAB1D020C6BF765FF60B3B801984A90C2FE970BF1DE97004A6CF44B4984AB58258B4AF71221CD17530A700C32959C9436344B5316F09CCCA7029A230D639DCB022D8BA79BA91CD6AB12AE1579C50C7BB10E30301A65CAE3101D40C7BA927BB553148D1647024D4A06C8166D0B0B81269B7D5F4B34FB022F69152F514004A7C685368552343BB60360FBB9945EDF446D345BDCAA7455C74BA0A551E184620FEF97688773D50B6433CA7A7AC5CB6B7F671A15376E5A6747A623FA7BC6630373F5B1B512690A661377870A60A7A189683F9B0CF0466E1F750762631C4AB09F505C42DD28633569472735442851E321616D4009810777B6BD46FA7224461A5CC27405DFBAC0D39B002CAB33433F2A86EB8CE91C134A6386F860A1994EB4B6875A46D195581D173854B53D2293DF3E9A822756CD8F212B325CA29B4F9F8CFBADF2E41869ABFBAD10738AD04CC752BC20C394746850E0C4847DBEBBE41CD4DEA489DEDD00E76AE0BCF54AA8550202920EB64D5892AD02B13F2E5B505D7CFAD1B497499323C8686325E4792F267AAFA3F87CA60D01CB54F29202A", + "ek" : "3CA7A7838B26FF0E598F1D4CD6516FD8D28B7C3A61607204C7FDB39009D04911C11F9187DB0E6DC05DEDEA6462AA00FF67BB40285CAC7501FD5B7D9E2CFC8B9177A126B62567CFF1F665EE05705495017C5C40001F6A7ABC47D34F36D183B624E4BB75F92600F2EEA70A2052FFEA7919871EC27F960E9EED46BCF8713C396C6F2F3CBD0B1EB6CF136A97FF2435F1B310DB70206F52B268BB768407A27B31EDC8DE55EF53192DE1304D15E6C5523E5B1BB96D9F288DDB9ED65E8E32701D3858832D9D7CDE72E716565F5788035A087121F60BCDC72AA386A1BCDA978E15F4AA736BD2F884E0A66775D6E2CE78B73D109267C48080396E22B42D4DD0C2D8E75065F1EEAE8654FF9C259465FF4AB2C253F517B8DB481CD6C00D573D0B46CC7E4644DFE0E1E2F997B586B2CCCC75F52DEC788AC214F8013782206023EBE8F72289664EC637A6F988BEE8CBA25226AEABBF09179E41E7E6168E30819AF0A89A745671F3C5A10560DB93D5EDAF63AC7539A8616D84B37BF4245B09E5248D7E4042C4C0D5585504BB825E0ED05EC08F3F3B4365611299F8F5D2BE0B2E4538A2BD3938194D7F5C79FF8AF9622B336DBC31BCB7D60F6A190883F498B4DE4688B3F5475A200493D9C8218F85256E87CCB3013723C7A264A3AB764ACFC8DCFE2CE359A7BD53FF7F68A842751CFCBDD39EBB1C44F65739C071AF6C24220575296E85AE4458E0F676348A2D7CDB64378E75ABC74E86D346480949C6A6D3627611CB2CDF7714EC779BF08A47616760A49F30A1A712493F190D433E7828CAB45037CEF6C863C5A3CACD5C14BC2E36BB3296E187E1796D2738B32835620E142E1ADF096BF309CDC83A1545E414232B9905BBAB1FD23BAB0D93D4DF0AD8314809FEDF7A97992871F5BD238FD72FF52BAD31F934EE5435E0E32A2BE4519E2BA670BB443A0E227A3D44B400CC48A31475A98233930CAB930BF498CC30CCB0421DC412C3190A98A03D8ECE1816DEF4D358E3C3C1D4249264252D02DE48E2B2216A2B246A61EAC8DEC3F8A4BDC2A69085DFEC3AD5C80852B0960DA201828EF04AAE93E026DEB3C6704904801B4101AAE305013581294F1F34877376A18DB8EEC0F1BFE9B596BE86383244F999E298ACB04287ACE035D5B89B2F9DA1CBDB5779994E5733DCC4DE22AD2F3F9F1EF49E5DEB80EC9AC133DF3E0BB9BE7CD8DB478EB3111BB6D716849F4A48CA795BD049AC1C3939862BF9091697F054EA7DDDB4224579BC3E3D946E7D881669A290C23A4A222B3C90071333E404BC10842749F7D3051175CCC645146A991CF07AF05020A2FDF94F474DF6BFE24790047497257930FAFC7B9A56D1C06EC95859B9576ACF45C98CC8D7434C03C90B0117DA333388AA87DE75A5441EA63F27235BE4A7D25B1D1AFE291C857955E38AE39D3CF469B2FBBEB327AAE7C56E9057F5CC592B37D9D9D671F7C91CCFE0C282C3F285B6CF2FDD6FB110B898CDDCBD37787CE8E954B70890F0DAA90F4A5791360F4F1E68D64FA7A48A0FD2E38490482EFA90A869535D320C6B6575FE8E0E5518E9DE40D9F10BF35F499A30ADB975CFABBA568E28CA3AB81E21679E6768EE5C890F4C5E9349F02337EDFAFE4EFE1023E93CE32E84039BFCA516E86986649AEE3E475BE7B3644774DABBB6CA8B5C77B4CA1865D776A10043CDCBC612DF0F436A8252DEA172A9F2686B03FF96F9B2905240AFA24551916F8F82944F3FF7173F6EA487159EC83C290FAE1440CC54CE6F785BBC3CB3763FA98CF917D33BCA00F56D90491668A1EE89D76116F7F19EDCDF7160240B9882261387E190B116A95F2DDFD2D8E5B03DCB850B89584EE9FFECEDABAF7F15030E16679757D4A27E2014A04DD8FEEFFFCA2EC795FA9A6FD31A3F3A74E440DAE018E5F174141E200ADE656E3C9689BFFA04D3FEAFAAB95D7ED5D5E75461B236559826347DAF9E8DF8FA27904BAB7078433ED9BD4557C78468DA6B747E13D6E5C97D927A5B0915097316A6FE21EDA26D230CF19BA826485C93365814BF50FC8E4AF90392CB0BB79570216FD9543271B6205DC44416BBF41448240D283E367C4CAB21F090941D2E4033B7CF02A345AE9EE8550A4CF19775CFD440E70CE838552A31719D8789401D33F01F3EE558A992D71FD309CCBE9689C48B3667930FD8C7DDCA717E7C77DAC273D7F4CA77757ACA23FF2E558CEEF152075ADD70BAA763C29F", + "k" : "EA636CE31B73F40229572146B97E590F1605FDADD1C3781861530EFFCF2B1E18", +}, +{ + "rngSeed" : "D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC81ADDE6AEEB4A5A875C3BFCADFA958F", + "pk" : "938A454364CF10A4C719113A23B242BC013962F13421EC0686E32CCB80840749643EB4B5CC4182CEE2366717CF77F97DA296A185440113770B6F755BC596CBBCE021E94306B1E4AE437AB7DBC29527142A9223A8A7CB269391CAD8F70C6CF666118830485CCAEBBA1BDA242176559904713C6722C413D5C2B9C2669D58138ED5B23506A71C6182AF6939DD40C51D678639238C8C071384C1256EE6A307475BB72BC93976C8976BB89C736D8FB19580CACB1F335B97D16943C0706F78095408CDAD77A9FE967C4BCA738960B3A3C171680426528A21578B79B226BDA19A9BF132998A2149C463932D630B0F131E8096BE462080E6D17107704F3B0CC90C3908CD645268375056E6072425B51A46C27A48B9C0DB67B025A58EE37B44794430F3AE6CC74E1673C2B1D4B29DB5370F590EAF6165E5806376F6A7D4825C74038792683F38893464103D82426593F366F96B023008BE21956E6BE8A4BD612D4F85239D62AB6C39069AA210B47B37CA85394C19327E5303CC9C54A5C63AEB104DACF67A1C1C3142710DCF682EDAC82471BA98C81A552AD2541B7338B2A0CE41354CCAB879F549CFA58995EB8C64A8B30B6F384EC2E04DC1A11AE04C967F744024D70DA780516777A1B1715F22CB1EB3511F5C4C99CE577836489A0F813A99A622390B52E4757843C772F6E75F470305259833B3993919F3ACA66563F3EB7375F5883CFCA72398B049170EBF0997FF277E44501FB0E83D0C5CA6C701048180AC68D857E0DC5D24B1628433C737B8808C290839D42C6A322250E0C22B81B4C018260D288C47976BCB84BCD0856C40448CA40B723B8144837965AD46B521EC4B405C28589B8536621A10678A75233E2CD59BC6E03F49D93925C5BCC133BEA39A7E21907A19840C80225F1F154C270A4BF0206A16C241BF42CBD351055ADC8519D38FC9D3B976E2144909053C5843C36B7B247A6ECD04C9D792A6FAE968CBE11713592B287CC8B07B73C334BDBCB91D05C7AE4E86AA7547B4CC6403504ACAEF4C6E5B758F4E261C7624337000C187648325F36AC8854D4A8A1C2C732A0811B39439340E23C33AF0CE5090CE800070306834321B5AF9E4BE13B22EA6655DA11427F995A115DC86CDA737AA99078407B9F78B914E831A6BEC2C85F922F972BDDA971B66761045813A852A0FD990136840835F8B5A72C5C8E8A65CE8D3CE957B06698261160031597A29E3388A4F5A5F0B96B70481A2E5738D3A50189496C75A856643899947C955BE8871E808030A5757D6B46079454B54D51557CCA964379BCA5A8191698275DC51CB164F8E508FDAF480031A28AFB1C9CCC65DA9AC1CDEC625131C6630188FFFFBCB726133CA563DA640C76A6C24105502EA3C24B918C5B818121CC68E2F1B62112A41594A6359876B91D058FD66861B7633D73CC7226B8DEBEBCF90FCC390F761360554ACF013AD03911B49B641C73687F4A73F8C290A2890C02C56E2A6567FB03826353D87EA41369673E1F9B920B36203CC9AA464192D01B6D859307927A629A24B34132CBCECA487A0CB3C7442ABA47C4A077FBE7442C2A4221A200A93E726518830B11B690F0497AC0851A5B27EA20253065A9AE7E6567FC26500EDB11346955AEB2D9C6C228F1644F21B34E3694C05016284BCAF746AB6344A10EEC87CD0F76A611AB64EC86288C339294AA15233ABFB680036D2155FE77363530C3EE0C4B8B74A54E9A2453CA081D01F9626867632870B178D25B831FD133A2AC0596E688652C1772E2979305C5E2A10949BF35BDC08CECD6771B7F659B61960A45054998472163C21D31024C0C24972D5B145608C1044718F60894BF5875A453D4A7C4569C63A2B38C2DB6A4FB8DC9289610EF12754F37CB4DAD3B66E135D1F75759622CD7FA03C4BA81D71AC9938C9A97839A12D7A4622943C381A048EDB26C64926B3A807B644AEBC9110C54B06D4EA1CBF6462A55B31C7F5202CCA8B7C698D9559276A1A3963CC56DD26CE3C051167F299D80C3A8EE894F134567CEA1032C845D79CCD95313F04D6459D1BA72E00CC604365A9C5C5185005F17A0397A559A0B28F31B41A5E0948C81501E902B9CC253F6EBA88172BBB92024984FA99C5BAB08DC01504556AABE8C81BC99C56FC771DDC85D37B7C50182345E189267934564AA9DD80BCDC25B127F1244763644004E5EAF06B095B892BAE095E0BA7F9D2700A50", + "sk" : "1DF76D46867CD8C5B94B3666CCC8C368AB45C71ABC8DF2CF74FB3070095902282B41A698B405947354664DF4727AF16B549209329623A33889B41747D56594B842BE87F40AABB37BB457C935C5A2FD3801694433FBB545B35B23B6D17A8D9AAEF6D31FEFE99D8C7C2030989A285900D8FB78ED65C97428C25459195890406DC878B2A98993664FECC960237A2326530105F78BB0D04A00030E6EC0A258D803A00844753B8BCA802AD335648F348FA34905681A72A8E198206613DC285101499413267A5588BB4331120213BF3DCC0EFBD80B70FB08BBEB6067E617D380B804BB6A4E745A97CC8342C5CAB4208390147BF1B87C6C4430D8B443E45C101AE65FD9C43798A082ACA969B8171B8794C3E442096A139496B9A11E9821AFEA868107006E4A283F60A035485914E9901E843013D36C36B35318522CD69C1DF78ACAB468336FF89CA4A787363B51F7B62468D974506A245049C0EC7092E7C9368E18C313297A92A292926902D34B0890192B50CB3772A797EA6918D380B1752B8E1E0A36B41A2F865B73A8B3A36D68446ADA396AE000898035C40CB4BBC76ABE0240392372FA6BCA942C4112C86EAEB60A548326868B80AF6A8F9DC506BF9474641B7032994D641A3D1C45B8DF7C2FB3301003F6481F00622932309E860FCCA71F7FD6C38242CDA0A4A589E4BB791294A6AA9F85959E91B0B5424A61A974CE29D87C7C0C1B0D7AB804690E285952CD95CA150097A7C6ABA8C878A87B883C52B2D076762FD424FD76C074873FAFA03D0D98647E76B4FD994300850093C2529B3B599D33692935BA09E4156052916833BC0C13836110BC134C4AE465ACF1730A01E261F2D3B1156288F54573AA6CBA8D161E533B50C56A2EE0FA04676B83489B742D492AA6650FD658BAABE309A860967A726A6CAC46BDC8893215160F97C3DB16CDE48A684BA64FA34A7C9720935711AA4E3BB0FEA7B14F4C9A889B9A45024CDBC09F3A971854B5BA1F940712913284516614277A1DF04A6A583873B154F4E68151DC8ECB86B5F58842FD31491E4422DB7B7059268030C60F4EC3BC1B37B076D157C2C014DC52A9909505D99180B259CFD3204A22825BA2051E9DD4376E7502B305A208A98A2BFBA19AD9152D3853ACAB2C48551EE998C84649C2C8E7B9140BC67CF839C1A49389C0AEFB2120CCF6B7CBA4360921A0E31B7EEC4335926788AF441280B4ACCAD52AE014493D15CAA20246CD4434639303FB5603F282B8A6F0B1FE41098D28C73F0B74653CBE673340158492D6517C514218DFEA8BBB4ABA8F741C0820C076A23B170456F8D8598211CBE6A37C15E6C38C905B8ED8430DB09982EC4F6C882632383ADDA285A08BBCBE219947E96017C8BF3B790DCA66B868CA729DF23A8125BC103B5EEEA6CABC6472A07281DE58CFBBCB319A7AB27D3A5F5C268BB0AC6587E7774A2A437541A28C84A8C1B986B1A7204FB613CD0067EC26458155923248BF0C641FBB4C4219941414895F60712928FA7275F7A99ED20E6AA7A2E3637D1FABBE65DB9DCE36B1DF2656E0284D3C5B4C2D789802C97515071A8F7C31B5501F4FF492CEFC8C7F6B0937DA9E02DC6A99493BA7F7269A32B610127F89B6B94020BF58A20ECD7548009D63331B2F4908499B400357C30F1A67694DE351FF5CBB4EB553E4D523568542A0E241A6ECC8045CAF295BCB12C55861F7B5E5151E5F4CBA28D54859619DC04B96B6B3A2A2436D921BC4560A4C4DF68A34413733761B8ADB790FD95A6479351BBB7CBB17A528CA14F0C31EADB195C86397BEEC61AB8B8EF9032D1AE0C669FB1203F554D2575E25E45BCA0767B0821740EB7AA749161E485152B68D5A8C0C53DB6BA6472A34016FD9067D07E8745E66785949A4BE88573987AA91DA5FE01387B739415B0C5D03CAA04089812C85829DD43E9B310FF5887561C7AAF64B1368862050B157E0BCBFBB659934466A3B1611633619D7C2855553B4C3934C8F410E7A097A5B591A76582AEF355C57A076A00905B6474626E33AC9DCAA77E8A07BD9509F5BAF27BC54BFB8890AC4210F8BB45342350ACB61C34999371614D85C7CC49C92E54BBBC94389663053B74088984B1B2D6C335C000FFCD21C9A45A8D377638F954A5E132563F62347614F10D103D0A58408867FEC69C50F595C938A454364CF10A4C719113A23B242BC013962F13421EC0686E32CCB80840749643EB4B5CC4182CEE2366717CF77F97DA296A185440113770B6F755BC596CBBCE021E94306B1E4AE437AB7DBC29527142A9223A8A7CB269391CAD8F70C6CF666118830485CCAEBBA1BDA242176559904713C6722C413D5C2B9C2669D58138ED5B23506A71C6182AF6939DD40C51D678639238C8C071384C1256EE6A307475BB72BC93976C8976BB89C736D8FB19580CACB1F335B97D16943C0706F78095408CDAD77A9FE967C4BCA738960B3A3C171680426528A21578B79B226BDA19A9BF132998A2149C463932D630B0F131E8096BE462080E6D17107704F3B0CC90C3908CD645268375056E6072425B51A46C27A48B9C0DB67B025A58EE37B44794430F3AE6CC74E1673C2B1D4B29DB5370F590EAF6165E5806376F6A7D4825C74038792683F38893464103D82426593F366F96B023008BE21956E6BE8A4BD612D4F85239D62AB6C39069AA210B47B37CA85394C19327E5303CC9C54A5C63AEB104DACF67A1C1C3142710DCF682EDAC82471BA98C81A552AD2541B7338B2A0CE41354CCAB879F549CFA58995EB8C64A8B30B6F384EC2E04DC1A11AE04C967F744024D70DA780516777A1B1715F22CB1EB3511F5C4C99CE577836489A0F813A99A622390B52E4757843C772F6E75F470305259833B3993919F3ACA66563F3EB7375F5883CFCA72398B049170EBF0997FF277E44501FB0E83D0C5CA6C701048180AC68D857E0DC5D24B1628433C737B8808C290839D42C6A322250E0C22B81B4C018260D288C47976BCB84BCD0856C40448CA40B723B8144837965AD46B521EC4B405C28589B8536621A10678A75233E2CD59BC6E03F49D93925C5BCC133BEA39A7E21907A19840C80225F1F154C270A4BF0206A16C241BF42CBD351055ADC8519D38FC9D3B976E2144909053C5843C36B7B247A6ECD04C9D792A6FAE968CBE11713592B287CC8B07B73C334BDBCB91D05C7AE4E86AA7547B4CC6403504ACAEF4C6E5B758F4E261C7624337000C187648325F36AC8854D4A8A1C2C732A0811B39439340E23C33AF0CE5090CE800070306834321B5AF9E4BE13B22EA6655DA11427F995A115DC86CDA737AA99078407B9F78B914E831A6BEC2C85F922F972BDDA971B66761045813A852A0FD990136840835F8B5A72C5C8E8A65CE8D3CE957B06698261160031597A29E3388A4F5A5F0B96B70481A2E5738D3A50189496C75A856643899947C955BE8871E808030A5757D6B46079454B54D51557CCA964379BCA5A8191698275DC51CB164F8E508FDAF480031A28AFB1C9CCC65DA9AC1CDEC625131C6630188FFFFBCB726133CA563DA640C76A6C24105502EA3C24B918C5B818121CC68E2F1B62112A41594A6359876B91D058FD66861B7633D73CC7226B8DEBEBCF90FCC390F761360554ACF013AD03911B49B641C73687F4A73F8C290A2890C02C56E2A6567FB03826353D87EA41369673E1F9B920B36203CC9AA464192D01B6D859307927A629A24B34132CBCECA487A0CB3C7442ABA47C4A077FBE7442C2A4221A200A93E726518830B11B690F0497AC0851A5B27EA20253065A9AE7E6567FC26500EDB11346955AEB2D9C6C228F1644F21B34E3694C05016284BCAF746AB6344A10EEC87CD0F76A611AB64EC86288C339294AA15233ABFB680036D2155FE77363530C3EE0C4B8B74A54E9A2453CA081D01F9626867632870B178D25B831FD133A2AC0596E688652C1772E2979305C5E2A10949BF35BDC08CECD6771B7F659B61960A45054998472163C21D31024C0C24972D5B145608C1044718F60894BF5875A453D4A7C4569C63A2B38C2DB6A4FB8DC9289610EF12754F37CB4DAD3B66E135D1F75759622CD7FA03C4BA81D71AC9938C9A97839A12D7A4622943C381A048EDB26C64926B3A807B644AEBC9110C54B06D4EA1CBF6462A55B31C7F5202CCA8B7C698D9559276A1A3963CC56DD26CE3C051167F299D80C3A8EE894F134567CEA1032C845D79CCD95313F04D6459D1BA72E00CC604365A9C5C5185005F17A0397A559A0B28F31B41A5E0948C81501E902B9CC253F6EBA88172BBB92024984FA99C5BAB08DC01504556AABE8C81BC99C56FC771DDC85D37B7C50182345E189267934564AA9DD80BCDC25B127F1244763644004E5EAF06B095B892BAE095E0BA7F9D2700A50CFB6FC18D6419F5438A0573693F421D3793E5DDF3D846678552AADDC19265946588522D326E7F105F11C4E8D97E119E193AF42DC28409F4F7572ADA538B52C1F", + "ek" : "CE2FA3E89CD1D0C13C4770598D67155B43844190D8FA83651507B4EF68F68470F6E982E7F7834AD67A1AF8133798D3DD57369575226C94CEB69F60CE2D0C064FD47D8E4D8D18A1E3FEC68006E3D2B9D76C6543D9767DA121F52C086153AB91492D6BACECA444C015A094A278D9D2D3BD7F05C98D5CDFFD1F0266C464E492F4DAC81E05C567500EC9C22C16B61BE0A6ED436F2D3433AE7D7F9C21C2A7CE3FDEEF39419B9017A3987105E189D5FE81CBFF12741D631FB309E3B980821B968D664A1F8928C970E789C1969A62A3B7BA8B2980FF5E8D0BA9287CC95BD8C73D3ADEC8C028E41951F817B8FDEAFD0F1D91E2AF6B25149AA5B19BE5A34246C4E54C3D0A0FC03338CE2D7539C24FC4ED09DC94BDCF96C4CD2E11DF4EFA9728204682B441CED86AF33A8A9089DC94630772CDBA6ED8BA77F9BAA8CE32A22D286C3C5D5F16BCBF544666770CA3B57409B65E3FD75924599E9D26C05CAAF65EA675C79195F39F39B541D92B3BFC043BBEDC89E5C53D4770CE1109D50B45A1419B68C9D1C17A8421E1BC558FAD9CEA3D46F1ED6C5B46321E19F41BD0049C5EF8D7CBAD8E7B0EB3267F94873D0188E435EED75962FB1E4C2B1603F84EBA696D646C188031365C31B1C298B660C7F6BC0379E1F56EE5C04C139EE211A6507E946E4CA1D096C482494E74E154D37D4E71E8024A19CE81A0DDF041F6BE65E7D040F8DCDD3BB91345A72FB11A30E44F27F682CCF56E007359D6C4EBF55190133241A510E8116E2497391DEC14679A9FF1459D12523265330262210DEA3A9D72A2092535C6A96B8CE5D165598F1F3B2913819713D1FC8D5ED5A2A84751066F597E606940794DD7839E106150C49354EAE93D234D900F40574AC7D350270C9BA4FCC310D3195904CC8099CF7B01ADFC83B47633B75752FDE5B85AA9A993AD2FCCB344E173AFE9CD9FC5C86F968729DF19EC5E01F359CD4E9D6FB8200D66948888571D7359983A454E48B4A6EA0B25A1A970E0E688F9734E1783E09F9A7C389BA0C3F393FC8E5588F2DB00AE8E14DFF8021DB6CFBA71DB5EE0C77E90EA44604691AED76EDE157923DE9A7E8E2962FAFFE9D423AFC2D45B517D179B6CD8A6924E2044BA6AE78CB9C1219F65A2080145C6126286F89DD207D216F2D6A97F480F3E66990086E45A8E4D0948EA9FC3847B6B243FFC0D16CA2F8A384F7AE555857E5500E136F8C22201A9D338ABC99912717795F957BA945AAEF267C28EB1F5C6C83A58AA1F4CF8A4BEBB1264E2ACF06BB070511814A47A293DECDDE829A875F1ACC51F6C969E86C5D6AD660D03F7D09A91DCD16AAB62D03C58CFC190B55DAA9B38B6318CC8390B99D98F32FB13FCC808215E106D6C325DE5AFB1C254933C2F42977FD8CD9F07E737E44DF4C089C608BFFD3B816D9E24A7E944DB693B1FA4145FFFFED8804BC411E63396FC1E9A6924EF0070C9F8430140C403333CC509324438FAF9DCB4841A8ABADE35F34F0738F50734EBD5232CDB905061225AFDDB1ED41F00B83722225C657D7A89DC49A07A294053D4AC4838F79A74CD50D36046C6A731030E24C2D0936C5F92E3D8204D3C322C8313A6FB883A15379713D29885CF600B1051DF9D36148DC6998F3EFA9B54E59F659139C23DEFD6D03116C3B77A7A5B7219FA3E9C3A4FCD8242685CA26EBCA88F5B3B094AF8EDACDB74EA003DEBDFCB8DBAA3D17A3992E104D344092D36804AFEF0860EC5B686A63AFCAB4FD42DDDF7E12769464DD52D93C42103B2EA235FEC5979DECBEE9C1492291FB70280C7E37C33DFD4A3109D5EDB5D243635885962BF8A5E0A66E8D3593A560B5FA54F906F7CF856669FB081F45E498460AD05A5BB2367EE669400A28868168A6A3BA889C7F3E4069E29782879C130F6F344E2D4B804DFD7D7A31198188ED52A16C50EC392BE7DAEED5C2FA04B9B5D08CBC159B3BFF240970814B4F84DADD0DB9BC3BD6D08FD23A81DE7C8CFC503C23E48E61DD8E74043D6FBAC87ACFEF1F66DC156D1E690969A7D93A9CD629781ABD4C9226B34CAE477B547602191CFA1EB1FC4D669D38D1BA7D2F6D6AF4FDCF09F3E298CB8944669332F035CB0798A1C7F36663556F0C3A3879D4D55A10056077E29E8A44D8F612756D035E2F0B942F6AEF0FEC589714C9481CC3BD4B0D7CFB06637363F39D833466BDA93795E919CC86FE13E620CD372844E1688119751CE65D0D79D11F8", + "k" : "8BDB8B7DA6AF99A68647983D18EF82D0278BA1EDB9647E3BB15D30FEC2EE826C", +}, +{ + "rngSeed" : "64335BF29E5DE62842C941766BA129B0643B5E7121CA26CFC190EC7DC3543830557FDD5C03CF123A456D48EFEA43C868", + "pk" : "A1A341B578B4765C4649E6BFAF5C8B2AD80DE5200E4DD30DA0B693F5EBBFCFBA9F0AD2AD46576A7A06B65DE6BCDC432B6A753F3A6326A27073436483AEF170B8649E2CA022497329D071AF4C25968CB0521A118AEC41CBEAB013786A1C2984CB2C649DA0FC94FDD880FD3A05239B84AC053CA0F822E4C94EBFE1B6D6898DA03B02E455467AF6C89DB7225AD653A5AC0C8E165F3B9B68B01270EF0BA7CC56322D5C671805B7D333B899ABBAC120C010033F3064647E4A387649C272A32C2DCC2FD62793D8689CF59619F43C87FDEAAEBCD4C3F21483863563CE8442A7F581009410B3C506146390FCD44D0F918B2903940A321C66700CA4E205D4501ECEC23A4D17157CE4A0BAC562533273FB8071DDF960217696CCD98A59E6C39DAC5CD185A0793A9190E25A0460837D07D020D72B5C5BA9840B0940832FA3A483AEC99D0D629CFD67A1CE77766A23B2349947968C238D0126F6AB9422B97D6DEC5657A20A683544BA07971BC773A5DA90BF471EAF12310283944C723EB1E0600EEB2464BC71DE7233EBFB7BE64202EE21088222A48BA200F04B6BF6A1C7F6404295764E6FD857D747CD985B07F4D83F8B13A901CCBFF7B01E21B8789C05B635BCC14C8128C379BDD52029EFD660468A34512BB78DA224FFF9A223371E457333AD464C6FDBA4F6C5451B585583655182691F6EE817CF81CE6E7A5CC6B9CACEE275C473AE1C58AA38E43DE50796F22475FCA44270E3A46FB5B8BDDA74E3E05B88210F54F36E79FB05BECC76805B716154A6E2346B0F4CAC241748FDE93F325B4F82F3B681136AFF8056BC7304EF22652F1679C816032BC35DB68B64B2848351DA88DF89166707B194CB4759E6761032ACA4B7A54E8064F5755D36288FC5061072DA1EC35A8491396C9406446060347361BED860B028B57250F0187F45A204FBA678F587AE031AC38480CF4C3FFF90188D925BD4C7C6BD0B758698BCDE97CE3958697610CE05E4ABFCA60EAC13B666732E8262B36B7447C0C93F91362C519337052865927A9862D2C1ED186B411554275A24DC9738751A4BA243BCFE46109212B711AA453A35B09BA20AB405B6F0F3457321B24017261B49923225B3620678C4F474515396113880DF463138ABC3E820C65415C593D74C01E5136150B02F1CCC55A6C1E7E9B121588362D784C3E85658532331BB596682377C752E7C259608B629E74A5A470BAD77D3C0672B23831A217C1AC82B94A82437643807681CC1684098B86DE031440A79378A229BD902F2996F326A0DF16354778A4CD5375C756A34890CCF0C92BA07A61546387BF54C2CB0C8548D4780AA72B667C0A1FE400B30F194465CC97FF42511E75457D1A8A9712A6EA971D797BAA894B0348561DF068A3455A89AFC3684081DDFC0A90FD8ACBDC217C83398380267776051CF3491542534B1A74B409B69A8A142C1B437B5A8561FB064ECB591B7334AFC482AF678CFA4E11E970A48BDF822A0B45E1C591D07792884E4BD057A15EECC5CDF66C994CCA765DAAB1AF377A14B98BCD8918FE3546FA4438BA5322DA1BA75543BE245B12E228D07C1CF1091499A2C57DD42C9F6BA3240C053165CA3FD669B4C3944A7D003D016A0FCA826B5E615846C48873CB7F222CC12462023E38F14D98FA0486EAE480F81A7376EB6380A42A1A2A6123D8A4EFB102EE7B900CBE7A9238B59006ABDDF2AB25565815947B3BF6B14EED43BE91A5687B339E6BB6614387583C585F1456372AA68B17449C2A1C6269A05F8659DA97585F52421AB74B9D705BA13AC139F15BE9F41971E0A6E04BA167BE9B681D294C706D0477A22D64565E71979009A18C8086059F3964ED327288AAA0C8A2B2D976D5FBB50B842BCDF3C9D25656ED7224F3435C9BC9B59B17727B46A546EB8553DAB54ECC6842CBA94FB24592ED077FC56BD5DD2CD798715FE0C513377361D263C6348340A5018B0E9B43E112BB6BA60503CA954F2BB25FC585C021B57FB3D1ACC80A3B20FF4555EBFA223F90762E2008CE920A420B48CD8FA9606EC5834051D0904847466564294CDADDB25CAB5CC68008F96971B2711AE8D73B754CC8AB2BC13E07708E7B555AC681C0AF0961A19105BF62B93267B8C47C73526B8C2D08BB13867BE10211347656C0108AA3825234847519A52B6A4599CCAC59E10E945EB7BD579E0C98D12AA9905ED85271887A974AB8F04A783747CAAB69D", + "sk" : "9A29CA06E2CCB6A96AD265638A6A057BA846FD6777408CC21AA7C8A7B60AEFFC6D014B02E64968CAB39948E45C6E32676117373F201DC8A86368F54A54501B8D002D3EA36C1287A5504313F3E03FFBE64D28059B41247E76C24A8C05ABC21678110983CA0905434B5B2AC45ADC6C5D90D83B416B30351B780E8386D304CAAFC70F3A2A059E8094CEB83810D7599AF876537C4D367C21C0827CEF5C80F2B04F554C105C1A8C874389A5F8506D104C105213B64B00B1F194C1F793F6D340A7466896905E295B39D9FA9E6C314E879140BD0B1CC276632E70A56902346FCA21D2FC7B0004817B1288B3B34506CC1B15060D1B103025E2CE51E2868335685382B2CEA4B87DCC6590FAC80825CAFF465CEB9B1DFB51B52EC97C5077B55D528B32F4B2E344071E04B703F759BAC057916916AB758718509921D0C0E0D08BD2037E0643A18ED60F984A837B86C5EBB7B8068C1528100515CB808A019F9017113122A7ED16582C78CDB52AB7B6320E7EC0AFC194B651119F79F6C7FF32B003BA7E0160510D32AF80ECA6547C3999547749DCB7205C50BDC62F54CABB15F386648B1805DA6AD5C1A55265B57665BEBE46CDFBA6604352B5FD036D5A9426F70C014FAB63BC2AB7288653ED2680DD6081519B3BC56BA9704AB32BF3A59282257BB9071E270FAD6B705E48BED7A546CA6A80A3181F3875580965798E978F757B83FEE729774BA46AB32A61343E002B6379A5AD9EE25F37838C84F397B9B4039B447B50C834C1B99EEFF51CE6D5BDD8810ABE873E1A1C57E74C51BB0139D937390F10C118A568BC464A28028CF5A778BC1A717F9A672EC5CC2B635ADD077485DA497F68C51F017D3785BF0DBB6AD9EB3AB3A02776E9784A864A45DC0527B00D47D2A8C7794D43F059CFE88A2F43160C38292216B0DBA17DA92B56CE6B2711B0869E1204E21C2834C12A2D4557FB723CAADC01AF894AFE656956B35829E780BBA9C8AC28002245CD5D46112DC93DAC9A656FE40EF67BB544847BEBF73EAFFC85EC1514B9A248DA8760BBD1B65108ACFA364B4286C538AB466F34C383F008E0E611F379ABA066638B87854163065AFCAF1003A189A81CCFC873C84BB465601479D1AC21D9886E7614CDD3603415B8470766892028FF575A69F471B126AACB0136B5D91D1F532F85392E66E182A5ACC4BE796E42C16D1D56447264AA9F20505F1A447288CD2362BD99C19A7BBA93D1775586D769B3A2A1AEBC17F84B1C14C5A0D5908DDAB90C06BBB7B31C3B88625B96E9244D163585724FFE361E04127E5A981929D24A8E8B58BE5221A9D202B84B3C1E0CBA55349ABD356D787022BF01A04573CCDBE42D1687B29BE8C03CF3535EB952073A43319A2F0E52726906CDF7D06BE43319D43370B4131457AA2F968628B5C5A71B4B1804734C85EC5EFBBACBACD336CA048F8F3589E9561E3732A0EA5523168A8449A9B30A88CE124C25DC2749A3933382DCA4CFEA4DE519BC17F7605321C99B3B20FAA4ADF952231FB27A95A55C7238702A869D0B1CA018FA58CA21C6D494BC38DB4B34216BC770BBC1B63102A588DA22A6AE3723BB80B1C857AD06B88D1D0001B396BE411618DD421760A58E0898787C498118775CE407317F4BCBD3477CE35C565D83C1EE124ECAFB0EEB1B19A4E05EDA182B53920B4613C989523D93DBA735423DBD84B76491047DB0C6F50376DD5460A9C20C02643B63049DABCB3EC09C9A6AA264F3C02CF4FAAEAEA9158F74670C74C783D461E1C3AAB218403161508BE461DC2C09D4C77F6737509CC317A2703E3850CA06636105463A4EB16AFE797BE2C32763F0AD222401545462DDF41C71B65FB2499AD3D0A7C128556518BE54948A86B6BB5A811B76B4C35D35BC2D54C0C60C6A744C4944BC74303144B4891B841AC2B1E63777101465EACBE933087FA6541E502BA54522EB69842D3A706DCC617076AB90C16393853FEA190CAD088DA65953A412C8EEE83945CB3E10719F37188054C31518070603BC0AF5E483F6155D618700F74093AAF352FACC6A1AB0809DC101B64C9ADA665D1ACC9BF31C15BB3A2D163874B523951C7441BAC80823D29A909B9DB7B73D43020300E68BC66B1964A1031351B451650B63F0076ECC6FE8495857E6A93C9B667D924EB3A84CAAE9B401EC2FA3355DA1A341B578B4765C4649E6BFAF5C8B2AD80DE5200E4DD30DA0B693F5EBBFCFBA9F0AD2AD46576A7A06B65DE6BCDC432B6A753F3A6326A27073436483AEF170B8649E2CA022497329D071AF4C25968CB0521A118AEC41CBEAB013786A1C2984CB2C649DA0FC94FDD880FD3A05239B84AC053CA0F822E4C94EBFE1B6D6898DA03B02E455467AF6C89DB7225AD653A5AC0C8E165F3B9B68B01270EF0BA7CC56322D5C671805B7D333B899ABBAC120C010033F3064647E4A387649C272A32C2DCC2FD62793D8689CF59619F43C87FDEAAEBCD4C3F21483863563CE8442A7F581009410B3C506146390FCD44D0F918B2903940A321C66700CA4E205D4501ECEC23A4D17157CE4A0BAC562533273FB8071DDF960217696CCD98A59E6C39DAC5CD185A0793A9190E25A0460837D07D020D72B5C5BA9840B0940832FA3A483AEC99D0D629CFD67A1CE77766A23B2349947968C238D0126F6AB9422B97D6DEC5657A20A683544BA07971BC773A5DA90BF471EAF12310283944C723EB1E0600EEB2464BC71DE7233EBFB7BE64202EE21088222A48BA200F04B6BF6A1C7F6404295764E6FD857D747CD985B07F4D83F8B13A901CCBFF7B01E21B8789C05B635BCC14C8128C379BDD52029EFD660468A34512BB78DA224FFF9A223371E457333AD464C6FDBA4F6C5451B585583655182691F6EE817CF81CE6E7A5CC6B9CACEE275C473AE1C58AA38E43DE50796F22475FCA44270E3A46FB5B8BDDA74E3E05B88210F54F36E79FB05BECC76805B716154A6E2346B0F4CAC241748FDE93F325B4F82F3B681136AFF8056BC7304EF22652F1679C816032BC35DB68B64B2848351DA88DF89166707B194CB4759E6761032ACA4B7A54E8064F5755D36288FC5061072DA1EC35A8491396C9406446060347361BED860B028B57250F0187F45A204FBA678F587AE031AC38480CF4C3FFF90188D925BD4C7C6BD0B758698BCDE97CE3958697610CE05E4ABFCA60EAC13B666732E8262B36B7447C0C93F91362C519337052865927A9862D2C1ED186B411554275A24DC9738751A4BA243BCFE46109212B711AA453A35B09BA20AB405B6F0F3457321B24017261B49923225B3620678C4F474515396113880DF463138ABC3E820C65415C593D74C01E5136150B02F1CCC55A6C1E7E9B121588362D784C3E85658532331BB596682377C752E7C259608B629E74A5A470BAD77D3C0672B23831A217C1AC82B94A82437643807681CC1684098B86DE031440A79378A229BD902F2996F326A0DF16354778A4CD5375C756A34890CCF0C92BA07A61546387BF54C2CB0C8548D4780AA72B667C0A1FE400B30F194465CC97FF42511E75457D1A8A9712A6EA971D797BAA894B0348561DF068A3455A89AFC3684081DDFC0A90FD8ACBDC217C83398380267776051CF3491542534B1A74B409B69A8A142C1B437B5A8561FB064ECB591B7334AFC482AF678CFA4E11E970A48BDF822A0B45E1C591D07792884E4BD057A15EECC5CDF66C994CCA765DAAB1AF377A14B98BCD8918FE3546FA4438BA5322DA1BA75543BE245B12E228D07C1CF1091499A2C57DD42C9F6BA3240C053165CA3FD669B4C3944A7D003D016A0FCA826B5E615846C48873CB7F222CC12462023E38F14D98FA0486EAE480F81A7376EB6380A42A1A2A6123D8A4EFB102EE7B900CBE7A9238B59006ABDDF2AB25565815947B3BF6B14EED43BE91A5687B339E6BB6614387583C585F1456372AA68B17449C2A1C6269A05F8659DA97585F52421AB74B9D705BA13AC139F15BE9F41971E0A6E04BA167BE9B681D294C706D0477A22D64565E71979009A18C8086059F3964ED327288AAA0C8A2B2D976D5FBB50B842BCDF3C9D25656ED7224F3435C9BC9B59B17727B46A546EB8553DAB54ECC6842CBA94FB24592ED077FC56BD5DD2CD798715FE0C513377361D263C6348340A5018B0E9B43E112BB6BA60503CA954F2BB25FC585C021B57FB3D1ACC80A3B20FF4555EBFA223F90762E2008CE920A420B48CD8FA9606EC5834051D0904847466564294CDADDB25CAB5CC68008F96971B2711AE8D73B754CC8AB2BC13E07708E7B555AC681C0AF0961A19105BF62B93267B8C47C73526B8C2D08BB13867BE10211347656C0108AA3825234847519A52B6A4599CCAC59E10E945EB7BD579E0C98D12AA9905ED85271887A974AB8F04A783747CAAB69DCB74EB00A87EB1651271050E74552291B66A29053BEF5E49690D4EEC7B7BD352D5A45A4CED06403C5557E87113CB30EA3DC2F39481734DE9E18BCBFBECC6719F", + "ek" : "0D6F0975714A794C4E311147C5C82851C8DFB1790F780CEC27C761A9EABBB52BD3B908FB8BFE1AD40F4A1F24834DF0DCCB43FD1A9AF0367B5E71EC9A722361D5643DD594166B99ED7A64C13A8B8E938A015A96C7D910A49F7E65345B742C71011F2FFE81F795313E0E5C7795F1DF657FAECFD92C39EB0DDCD3DCF9A7530962D4743825A68CB7EE303F76B443B566234255BDD589A3E7B026FBE23A660E00DE6154034463C7C8D0D2867F0EF2ADF339C94E71D9B6D83254C722628546ABCD02AFB3B3718E2ECCD90DFF863679BC9F8F5EA7C7EAF0B5B7B6813B2339949E0F9656A2302B09B87ADF25FD328D99E5E0AEA3B4E0A2DA6A25102CC787DE081CD25F9B9620E146B402D4CC76C7B96316A2A217F87EDB7AF895DA47097D412DAEB1B3AE26EF7FFC47D2269423F8CE33EE206A9A1841064F54347507C57425CC8A7A6251D44AD21DB6E3B07BA51EE52172E8B35FA62F02F484830D243E99014889E92E7085404287E036B53C90398483DAE3A081554241107C5F3B2DD45E259658865461B58B21DA16F78DD6E892063B9330B3CC79D18275BE1E58F27B5F442DF7F52F1E86E79EFBF5B834A91002794364A7104E36CF5DAFC801FBEB714061B5EAC9EEBAAAFF6482BF0BAE5319595289254F3BD301633A999524DCD3A02B4E836CBDF21072F23CE414FC871A8199BC60B0F2D876B0BC18905A58E8D4B3871E2B9300F7BEF6DE500031CBA92025DADB96ED7315C73A5ABFDB72583F53A19B218255DE6B4E0757EE249A374B5BE20B4E0366C645EF68630ECA9A8B2907AD00DFBFD2A1839D790EC3C42FC687EB935B2E2B0CE438F22CD547A393D956AC224D4C530A51C4BB2FE0086FABFE31051EFB0274227C94EC111381793E228F0DF9A07846B09D2BF4C80918E46E90220A6F3C27D0560D66335F2FEDF717F6653BEDA1FF388C26CCDC3F43B33FB6BF0966C4CD30944DBBC2298DE357BA1FD3E6AD7135D5B09A30B558B99B187A3C5A44111D7F79B02A311A2F0D3F96DE2AB95077AC4D4F138595D1C4A4BC6BDB9C351E87DF7EA0A9A4138A238C2762149824B0B74AA96ABFFB29B84CB750866F93C012FCFDD4AB775050CCB1155109D400F48F186E0FB5FD505946949A9631892646E4CCCE2FFF69F3362AFFFFC0737FE9B2E482AB55830C16DF6347CABC23539E6AE43FC6CC6099098D6B6F3768774B8428E6845C7915BA0B01809B07014E7699A252C8EDD60E77875F3EB99D84B215D47F5B4D369C85B5237EFF62990568960AA9104CCFFE51815A0695C3535F88440641B41281511765AF6D4E314AD83FC624C381DD8C7DC661D79111621D123F5CA18115DFEF0504F860CB63FA8338F726CA2927C1073EFC3F554A57A188418717E990E997F843DEEC21B5C3797288C5B69EF9EEF670FB511A6006FD27E482823011EE7022BE4EDF5DB39F39EB9F39B9C7A716139978AFD57915997647ED7BFCD8D39A39B68A172C904ECE1577B477DE81DE4B614525F0471188056CD1AC7B32C91E5D3EB27C617119C4899344AC99CF061E582F48868B951F510317730023A910E3B4CBFF43DA5BDAC55DB3DC67AAB0DDF5E357374AFF817BA37C50800021BC659B6E2BFACF6AC0B468E95968812123DCF00266B38D9823171E2DF86B9B6A2B764F0CBC557E4C42CC6E496540F6B9618B9049ABF0D70ABDBB006354A0C50F2F77EA7E0901C8606E30378B5B0611E11EA47010F4FB04B1E6D66EC3D58BA17F907F08872C5A6560B300A4C7B2D4327801C23116AE082C128114D0635B4FEE926BC6C0D38F68E95C4718A8CB3FCCEF0553D3C4984AD6C5713A4E70E921FBB5B0AFE76EE74730B93E9286B0946632D8DA98F4E728E62D11518DDB66B971D473B3AF15D184EEBD0BF1DC0FCC3EA9DEE28947EA5AD9FBFD421F9E5EA463FCBD31742B187C89CC066E8837675E474327D65B5B74D61E336F47F9702CC7D018AA553D1DFF915D9D79084D8434FD75CC74864922C769A9D75194F60BD0758C3DA6927D2855E92FECA14D85C40F05C2A33E9EE957B61C6D57CEEBE946036BABFC825B282FA57E6EF9ED8021F8368DBDA5BAF4A01FA2A9D02B9D4F84C2A36C17914CED600C8BADA84C49B062FFF3BBD9D7352D3BA95516F6A8FB0FB64F8AC387FF7DBC5C52AB9BB57319E4B4502630F0DB183C7213B838EEA3B0DED94865DBF41A03927197AFBD6BAABD033C6F2A0041ACF6", + "k" : "7133AFF8FC9E3B14E476971D9651976A1B41A289B54FA6040DCC820C96D55500", +}, +{ + "rngSeed" : "225D5CE2CEAC61930A07503FB59F7C2F936A3E075481DA3CA299A80F8C5DF9223A073E7B90E02EBF98CA2227EBA38C1A", + "pk" : "C8016EEAE46E2610A5FD252102A480CAC2BC6E7860620259E41C64591584F1E6CE8E3312DC8862DD806CC2181A18BB91FB184DCF045B030807A5023C4B3779F14A162E0938743B78C71493BEDA7826022E78AC100E7892FC104D48E25CE92610C072A3E9E8208C93CC225C916A2941C13838EDA382F311A809C19B9CA60F188910A1A1BEDE4710B6B72127E48A5454A457C8037439572C558378CC784554171F6A0C78C676DB8BB8AA380357FCC1F61859B0EC72730C10F8C3932975C70E6329AAD34A56797A03C0297FB4AA6B97A63BE19F5CA6318D0B2C8B4C6D9EF808EBE364D0A41A82DC768BE47F44F300BC9B2E4CCA1050E21A9919A9B65A07A6C8BC1CA5622A441117A1749211571C462A40C94C3301081867B3A8957FF45C1C3F7C00097A35AF93438D74C78C061C2D645E7F6C3BE5FA6DA749085DD12461FC517E0C28BAF93418978772E4C723C071908915A1A5807050C57D2A3D56597B1E1BAE4B437632A2522F314B39FA6AB7A047E12B6502027E334B715B5B0B17BB76AE608ACC0250D91A859C8C448B27BF4C44B092350E260B65C20C82588C8C1EF25AFFAAAF150479E80801C82CBEA73A37DD1A7DF6D268A9B0C4FC753158C39EA4E90960C20460804329F58BD460A37357AE6515BCD505C7CDA55B2669017BEC3D51816E7001B0A64837F9E07EA26735E830092A648F828CB3093228B98A0C92656C1A14CB3A306929C6207751CEBE31AEA4C0372CD5C06CC637DD9B6894F00DCB3796D09CA87884412726A25BFA9BF6EB613E1A2A19A196E1E1634E1CA0347A9BCC96816923092961B69DC0C013C191F7BA4FB0B13CE5555E8C1B07D8568722155287264B5FA990E92603AED71DF778832EE3BF9A767FA9E650420A14F5AC227DF497EFAB89511302D231A521C5353BD425306A14B7D2A566AB3B32AACF353C2B04A148E4C93C3E470605067DC7590722C452245B3D750205D2C0AAD03B0E2EC535BC6CC3956132E329A980C8495D765ED1EB071C58680A11859C3CC0B1E986486A5B543949643B83452C307DF477685A4D0A70A7528A55A997BEA46780B26252AF157FE5D874CF5C420B5B1A324A932BA52291428A39672BB359ABC4B54BBFAC608A0135CC99A38E102DA3E088E4EC5C47984A636C7CB99A6B6304CB0350052618471F716BE06B899087AA38053111E35A95965C04A7C42BDA2319598819AA0AEB5C39181079F41982E05223C8E89ABBC32FC1487F3CB99A167BA694B0668A5525A88472439C89179147EF831022B45F6B8553C8150E32B5421F75291C830A8698A916406807F201141A0EA1CB28255A9ED709502EC7851A56A86CD3B7F05726ED6A6E50FC52706104E829B02F7B61A1856C9B44B8D1214768851AC190B46B61C053C371A333A95B7806EED16C033790C1563FB823204E26CE3AF87750CA639E605CD435024336751CA0BDAB99CE5B45CEFA04CAA29BA33B4998DA0AA832EC22551821BAC055961ACEFA077DE544BBB80211878C6109B512B6B4850B5A8D0BD9BEA6978A0F920C1FE8601E1123A98AA23CFA30090817EE849E654A0387A185171A43047758A578A02EBB557904106EB3096D3C1F92092F02891F1D3B0659F284188B7119C14896688EF2BCC8086C604FC140A8FA24C9595D020269B0355AD9A44CBD803B59010A1B85B12FC785EF0A0789C10B3A30925CF155AE8682859A8F8164CF62FC08DF577EAB2071DB87B029A16EC90303F5B97117761C5F20033110B1BDF7388895B30ACA862F22ADDE6930430821DCCB2B1BA4CB923652309B4F16600FC9FBCFAA8553CB45BBB53035CD28526EA8449844AC68B87AA61047B94244F126BFE2323AF5F30BBA9C1B96A426A1D84C2DA35FBC001E20A517D458B4291CB36394CD9A074E51D8A45CE623484A3AA7D575977242AED535D46B74D8645AED246692AC1B8B055D717CCBD59769FF9617BCC3AA7BB9366BA51A736B2CE79B971E0C204AC62FD09755B4E4B233E94A9CD3490F4049CE6CC96C7C0FA1254C4EB67748B337C41C473FAB4A944364531A6FE18652856797787C804CE1C59462B8D145CAE4B97232440BA99CC3A66C1E019B53FDB272D000C85AD63D686A907A31700FD4A29E5936A53A4F2D2486751851EDD1B70115ADAB07A29B15594566221B329076A5A116676D3534044965014DAA0D13DA178581619DC06DF40A02750BEB995480EEE9", + "sk" : "2CA62AC1F40BBEF551A3F75613606661A204EBC3A81A170AB0E80EAC65017BF3ADD2830B80EA56743A56BBB7B428951050844474BA8AAB61912D35433A679C6770B3F8174214510215268EB5B14411E982F752192C649B61E559BB189666D98254CA913EDCB22F93667970566DD06FCC06BD937BCA44BA015BC689278925FBF64F1AEB93EE4A7BCE8093AEB6862009C49F89CF31E74F91DA8A206AC4ED0C21F8EA9AE1BA7F3EC59DFB5B729E73172770AC90957740068B1FB41ED528C73E2C2E62223264DAB7F23B6A583C2E0E4BBCAF9878384376C23C38802C5753DA4688554A2E9843B0DCA303997451A0609BE12D73CA1687E2702DB3CFB703504FA7B3FB372A59831267A8B9EAAC60EC31932C776907D29BE988ABD0208789F457DEF7130D628B4E694760F9883E197475F43670402F992CBF22819AA27A12FD60470E0B2A59700C05287589C2A85FA723B5C95EC12488F7E503BF090C581B112F854383C02E9BC693748628DFB2AF873713E268C98FDB5EC890B55D8A7AF5B93F3E94BE8F5971C8C63590715D09D894E078C07FDA4414280B20386AD6C645DF5B21FE43B940610DDE4B30B2A40131627D68A47045696ECA108E93BA6A3600CA7BE14F54346E9699331D92BDE1786BDE2886027A62234155648B2A52E3673FE5653CCA7FFAC07ACC060371D67A581A529D0BBE89762DD1763DAEF0C09657698829348028C5F14359F4996437EBB092F64E7DEA7C87E003C874C0531200E8163A9891CBA6B0750051006914CF22D95088542FE58C4F6955256370825306122AA5A26963C66AE4CE268C180698A4123954467972E8C9AB44545D0224443AD83D3D7C48ED052EF59B1772D82DE3781D713197E6E739E187CB4AD8B8B9F4972ED232F9513B03D2BD0F84C2D5951F2F20B01E362BED051A1278BF2A185B95514814494F576B56418C9D4DE5C62B30CEEA03A1E86A7A7FAB18A5C4BC9ED43C8F46426A3A853D5127073125BF3510FF3065E81A726D934F3A279950A675F0C3C9BF0BC42A574BBE21BE72092ED5AC8323E44CBDC1CE8864031838A7C43B64E9DC28A657BFE11711D0F1C5D407212F5938A7F14E82D9353173BD4D94621AE29247A2328007078FA5029136290D48009AFC39720CA4A8B8CFC2233DD0042AB0625007B36474FA370A961B520575404154A1070560BC0BBBD9060DAA27D4D10A13DA8FA0B676B291544A6C1BB5582B08D761162BA103094DF56789F76C8CAE2B6637D58391F0CE022C9F77DA0888C5045586A0C18A2E1730B3003493DCC8BBABFB359A39796EE578F5CC67FDC9A817461AA5296C5D379A58AB6F7A911114F0BCC39771633A6776965816384E5CD27FF1401A8880B2774CC73E6303E00574E241573EDB2282A47C6F1C03B74A91FF3C10E4305FCB86BA613C747A591D9AEC4C90193F9617431AF4689C11310025B92247C805487DE6C82968938E67084A178511C70722B28934E64A6E4A5223105C3BB24A6192D9216B7232FF0764F7D48507B84D72AC2236D92C69716BB6FCBB06757249AB3D7BC5A751E104C9E5881FC4675B374AFB7735A56B9872164C847493A5DACE7A855674D90091809109C524289CCBC4143A2567A6CB587045EC2D33E93EE2C60C9EA6A1A40344613A49EF538A41753A41D8C203785D38207ABB3024584CAEDB404C8C0661D114405D256BC06164FC6CA2B8D71B1E481AD065462128327ADBA3D7572C3DC71A75791258A5CEA5C65A70E11B0EB93A9F027B3B91AAA58A8A50B6BC2F59049F915404087AE4280CF7F603D110C9EECCB045125DC22B4C1923C83AA84C779A6312888AE7E019B7814D61D1CB6635B69D6445A8D005B4FBA51B91604530088CB3436CF73F19E42EBE1ACBC013B2E8341E3986C4AE156950E1B9D799C450751953DA223FC11688862405691D9120CFE4EB283C99B3E39555C7F246C6E73119F7473E0709F979499C52630F140DABC690BEAA91186151E5865F7FC85AEAE9C27DC3C03C31715303CABA288F95C55BFDE806374902D0F50015221A3C3298DB60A2257648BF22CEFFF39AC0E92016D71FAFB8C9037246A99A0EAA4566A04B0E7B8C4DCF8ABEA7F72E214494D4176920858E9BA69487680499D27E2ED56D040045AC671A364848C0A4100FD4B44E1B1E8BB5914AB89DC8016EEAE46E2610A5FD252102A480CAC2BC6E7860620259E41C64591584F1E6CE8E3312DC8862DD806CC2181A18BB91FB184DCF045B030807A5023C4B3779F14A162E0938743B78C71493BEDA7826022E78AC100E7892FC104D48E25CE92610C072A3E9E8208C93CC225C916A2941C13838EDA382F311A809C19B9CA60F188910A1A1BEDE4710B6B72127E48A5454A457C8037439572C558378CC784554171F6A0C78C676DB8BB8AA380357FCC1F61859B0EC72730C10F8C3932975C70E6329AAD34A56797A03C0297FB4AA6B97A63BE19F5CA6318D0B2C8B4C6D9EF808EBE364D0A41A82DC768BE47F44F300BC9B2E4CCA1050E21A9919A9B65A07A6C8BC1CA5622A441117A1749211571C462A40C94C3301081867B3A8957FF45C1C3F7C00097A35AF93438D74C78C061C2D645E7F6C3BE5FA6DA749085DD12461FC517E0C28BAF93418978772E4C723C071908915A1A5807050C57D2A3D56597B1E1BAE4B437632A2522F314B39FA6AB7A047E12B6502027E334B715B5B0B17BB76AE608ACC0250D91A859C8C448B27BF4C44B092350E260B65C20C82588C8C1EF25AFFAAAF150479E80801C82CBEA73A37DD1A7DF6D268A9B0C4FC753158C39EA4E90960C20460804329F58BD460A37357AE6515BCD505C7CDA55B2669017BEC3D51816E7001B0A64837F9E07EA26735E830092A648F828CB3093228B98A0C92656C1A14CB3A306929C6207751CEBE31AEA4C0372CD5C06CC637DD9B6894F00DCB3796D09CA87884412726A25BFA9BF6EB613E1A2A19A196E1E1634E1CA0347A9BCC96816923092961B69DC0C013C191F7BA4FB0B13CE5555E8C1B07D8568722155287264B5FA990E92603AED71DF778832EE3BF9A767FA9E650420A14F5AC227DF497EFAB89511302D231A521C5353BD425306A14B7D2A566AB3B32AACF353C2B04A148E4C93C3E470605067DC7590722C452245B3D750205D2C0AAD03B0E2EC535BC6CC3956132E329A980C8495D765ED1EB071C58680A11859C3CC0B1E986486A5B543949643B83452C307DF477685A4D0A70A7528A55A997BEA46780B26252AF157FE5D874CF5C420B5B1A324A932BA52291428A39672BB359ABC4B54BBFAC608A0135CC99A38E102DA3E088E4EC5C47984A636C7CB99A6B6304CB0350052618471F716BE06B899087AA38053111E35A95965C04A7C42BDA2319598819AA0AEB5C39181079F41982E05223C8E89ABBC32FC1487F3CB99A167BA694B0668A5525A88472439C89179147EF831022B45F6B8553C8150E32B5421F75291C830A8698A916406807F201141A0EA1CB28255A9ED709502EC7851A56A86CD3B7F05726ED6A6E50FC52706104E829B02F7B61A1856C9B44B8D1214768851AC190B46B61C053C371A333A95B7806EED16C033790C1563FB823204E26CE3AF87750CA639E605CD435024336751CA0BDAB99CE5B45CEFA04CAA29BA33B4998DA0AA832EC22551821BAC055961ACEFA077DE544BBB80211878C6109B512B6B4850B5A8D0BD9BEA6978A0F920C1FE8601E1123A98AA23CFA30090817EE849E654A0387A185171A43047758A578A02EBB557904106EB3096D3C1F92092F02891F1D3B0659F284188B7119C14896688EF2BCC8086C604FC140A8FA24C9595D020269B0355AD9A44CBD803B59010A1B85B12FC785EF0A0789C10B3A30925CF155AE8682859A8F8164CF62FC08DF577EAB2071DB87B029A16EC90303F5B97117761C5F20033110B1BDF7388895B30ACA862F22ADDE6930430821DCCB2B1BA4CB923652309B4F16600FC9FBCFAA8553CB45BBB53035CD28526EA8449844AC68B87AA61047B94244F126BFE2323AF5F30BBA9C1B96A426A1D84C2DA35FBC001E20A517D458B4291CB36394CD9A074E51D8A45CE623484A3AA7D575977242AED535D46B74D8645AED246692AC1B8B055D717CCBD59769FF9617BCC3AA7BB9366BA51A736B2CE79B971E0C204AC62FD09755B4E4B233E94A9CD3490F4049CE6CC96C7C0FA1254C4EB67748B337C41C473FAB4A944364531A6FE18652856797787C804CE1C59462B8D145CAE4B97232440BA99CC3A66C1E019B53FDB272D000C85AD63D686A907A31700FD4A29E5936A53A4F2D2486751851EDD1B70115ADAB07A29B15594566221B329076A5A116676D3534044965014DAA0D13DA178581619DC06DF40A02750BEB995480EEE94ADA82049CBAC3E8C6830334021C22894085DBC8382FB43CBE318E8E6ADA99553E0351BDC8A2DAF0258645C383021DF33FE59B553A8270C1B7A4D0AF155999B8", + "ek" : "7822770450AEF97A430EBEC39C179983DB49B994F19E55E9B6DFC71CD291C6FB4E47AA5FF4644429377E4DAD4C09B731AC31881BD509EF0CD29771575916CF1C4DA94579D0351A8A4C111922006E79EF3726D781C2171B71431202785D0531923ADAC3E284DC901172F48D6D1511818D8B14EC1E71436D58655B76F6041B375992A235B3476F57DF3B37EB1FB23ECAE5726EE35CBD4BE6FD407655B5CD50FF0F2E7BE0CCFC21B2B56268F483FC6F532285651F9D76AD97126C6C8D1403FBD7A73C7797EE4DF60E3BC3E5C9C6E20193220B3D516123944649869A8E3E3593A2F7D236E28F7C876915429750CE23A2FE308BADDC6F8E84D6BA439B0D6871113EE5D142F3D9DF3731CBF5C24D8C39250E5E8B33532E28DB54AC3632F71140F1B96039CEE1DA915C0B48F05531F66DD819DE6F61773B6C09B6D4D30FEF538E0FBAC990B20965DF16E2B2B7A0C1AFD4B6506735356784D7B7C369603EF0919CBFD479A5387CF317063BD351C6562DA58B8D756E4E089FE15B92E3D24F49FCA714DCBA7BABC30E9596FD75680573A45D056689566D4590D0A08761A74BB2DA4D5C520C0AAC7BE67FC346EE5D22AFCE7ABFE0CBD16058982FE831C1E47F6DA04626C38440CF922E024FDB0871C8CB1A3271BA9836098DE8BD6516AB2CA1B7F1DB091BD3ACCF0B9D21D010C81D3F5CD68A007C3DD46743F178ACAC599ABB404126FB23D0E44399EEF146853A28511B074357C37C35995A95403508EB20E80B8040217112BA46D2CE377B638FA402CE604593481265D93066FC2A1193F644965382B337396E675835AE507944F956A3B6C6E8668D1BBF0FDA07C8586CDEFF4F37A3D3CD81DE1C99DADE6498DDAA8AEE4A228BA9A55E2BF16F33C2941911EA19832D757C1C4307AA88A0F505B3560597E28A72E95662C4C95D0770717B4BC7989B6D758BFE6FA92E0E494201DC593BB4BDB673CF2585C4C4B5A8B5E374C270F7022F539E7BCDF0C83CD7456A7CFF2471D769AA5EAB88CA99844216BA9CD832FDB8C12FC7A1FE3A6AE6845715729CE226A301E858AD4EAF114FF4E55E8FE1DE7FA32D2DEC8109C1B9DE79C38525C54F35109589EAEB64CC4103FB56AB7179F769D43B56D5BD3344CC28E4896F833DAFFCCA9AB30AD382230B211A0E61CEC0B290FDC39BFADD25865E82EE4F76C83D500FC7467776E3AAE76BD74EEDA28175D32E006A6E006C2216CC7E273343CCF7478623F9BC9676382965FE17B5F28321D39BE7ACDF2BB4BFE7D7CFD027B30460D01B9988C119EF0B0AF1A87D619E9642B62EE8C98A1DE88C717D43EB7B434A628142DD2D588BADDC96BD14D2760DA8062066E89C87AA3CDF2E4FEA1ABF8959CF9832DD530DD0820735AF4357D003466ED5A6076BB85FC11EE373D836D694ED8BB9444C86C7BB4261D1B8742F9BA3DE009C3EB46E4C26344020A559C44256B8E141C2D233C24F57394DC57D537368FFF3703339BBF7A4845629842F3E5ECBCD1B6BBF5F0043FFF7C5D0A16B3AD50BA51296194B946B63AAD33B0405A64D98492EC0F4D36006E99AD53ACB5755F0D940B2A174E6D88A778E3DF1B0233C3F5E20B6A93A75618B9BDE8391C21E4BA7BA116C505C0F7981D00566A28262D01AA51D4E9EBADA5F67A25F18880291751448D038B006331E35B6AAEA1223DAB87DB949C12553787FBBB0E98E298594290B55D6E45E4901DB0AAE6327CBFBB4901638362E6F8BA3D3FC673EC49911053D6FD296103C2B67EACB3738578B5CB927123EB7FAE5D978BB93A9491ED74FB0A9E9C342D312532299BBA2E61431A3802465708F6A491181FBFF2C1F3B35D92D83241C103DF76DC5BE06C6D9095EB9E67DE696DA8CA2EED3664BEF7474350C9607574B728147C727978927523068509261486834FACFCFEE6A6C6996339BA893E29D61FC35560D10A47A6F18B4EDF1B7AD8B95A367B1DB0AEC4A3B028F208FE172C866BF47F2749F94D8FC6D8CE08EA5BA3DF35EA6BE06321E7BD51C93659750F444204FFB870D31D0BA534FF5F8E00D1D9CE5D538D715112A6360305D2637C814D8DE75F40E9E542BF3ADD29029AA632B8CB01134039DEE78B83762F1254A2FAF19F360D4C335B252921C6CF0BEDB4D77D34B012B4C4542D8C5411C883284308923C7671D6FF87DF8F7B5AE44F63023B0465A6D9C36445BB3711D1E10FB47DC8B772B200E962D7836F07D81", + "k" : "ED1BF217D14064B516C69BEA719BB15E145F57B1047507E005FE9358F77E57A5", +}, +{ + "rngSeed" : "EDC76E7C1523E3862552133FEA4D2AB05C69FB54A9354F0846456A2A407E071DF4650EC0E0A5666A52CD09462DBC51F9", + "pk" : "2F7A733C9C0D0A05B6AE91776032105BFA99D149062746AC1FD2CA81DB9224518A39629A36D043E6A398444A055A2CC28AC785E22B9ADA469D2E3491174A4E16E11824D32C33326F7CC2B73D417A7151496FBB6805A79D5D974B12F3C0125B5D7BFC7C6F244B68E2C1CA8613E891322261B4789898A1F858F5991B2B1B177769ACA1453C57C43140548452F3053D3B55FD2C3062A0B11939A3C14A81C59432616A5700C775FE98C6FB88C1EB8277C469BE42F541DBB79808479E0CDB11856CB7C1CB6A5B865469BBA549D73CFE581BEE85494DEA28D6E96A5F04CD65E561EF66A2482C806E39257B9BA9581421708663BF0B45B4131EEF3384EB53B8733C4957937161C3CCACEA5CBF91429E87B8B2B6A0AA44CAB94BCD02D14CC3932C3EE58B483B1D11E5243FEA0D34912B8D45BDF48C1358DB3FC163AC081C23CA6C43919A649C33911C5802E2407E9FEA350C3B64F302C5489005EC87650DE428E60B790489A17E96B9E1FA91B33BCE5F4B8D8DFA1610B39FD2858C25B898C1386C6DC021BD3414BF213719867F8CDCCBB4D2BDF12207860A638BD41A05B9697A3BC901E9AD0075C080243CC0CBB3D389977C522230A42125B08D41839986A60ACAE28BDA183AACC32DD5CB149AF2BBFC60B0D5BA8AD89B1ACC0863CEB24FAEA37EF3F60168CC96D766642F07A116225873E651EF693F2BB97339ACBCBA301E975405661B2AA523168E06C86F9BCBB42B5F12D79C3C379AFCC37DC4995B11A4AFC3578A30A13FF57AB87F022FD5C3AC5DACC3462C7E7EDAB63B889C22E90D685733A1A79EC336C50C18A5FE4408C2C122E34A60EF56A78BC16B78C3C98ED689E0C9276697CDD8ABA667109CD911B77E6930C4F58CEF1240C1F7005A7A2B17390988924CB0604B4F897D19C5B0E4A557A6A23470BC71DB15BC99248D42D9BED4117652690124B1BEBB438473619C4919C6C0E4071CA990B9D005EB287B15126E5C3477A98669F0856242DC073BB2673C7C1B1485799C300A0648A83142B95A2377D7E2B1D994209184309934C914308B7371A307A3BFC825958A98A12524B847BA5B61E5A279EB9F7CAB5CE030C45FFCBCF919A6CE1059DD7C6AA077C2D2437408315DB32A800C2099A92AB682FAC6461896D583007B97AF2336B1E6D061643C62F0B5122D48A230225128C52863C9AA7837AB4F254F92863EFBB3B379F87E40071CB6C8B74AC79AF4EC11DA6C028F1CAF9545A7D0A984BF6AC8D4067A7FF29325DAACD3F9470D529F02B00183586011DA8A0295B678B18D7572CD4F081317B92C21803F613BB959170AD3A4CF465645D3E5A1DBF672013BB935BCCDCEA51393BCBE7C975D30A9823667BBB155BDCCD14AD3D8B453B30EC2B0CBD703485975CC571530B4CC521693A9965139FCA21A90D57397F34C46822EA0E0CA0F56668B8692127BC93322389046C63FD08FF82B67F9778964054B49AB0DABE24628E771627CCF34F46C6C820E9D890B15F396A291A98EB14A23575952ABBE46374C74B812AAC6B9CED932C078AD3F2A05C821B720305773D070B8C86D7686C53B81CE241586F5F752FB4A2774152638F04156A0B24B3061141878D5759D12F8BAD4E98AA5D41895B91E122074B31AAADC30A1DFF707C32AA0DBFB2FE0A519B4289942E99754034D65D7B9EB5C0087225048B5A293038969A944725A23475B0681CA2177C5BEE023BB7E0ABE99A630B5BABB5F8A67C8117FECF20C1187C338A97B72C1674AA302C3005037631CCFD51A5B10CE837911D8D8372B9760C0498B8AD8218F832FD8519476EA5673D6659B558895796E14CB5A55E7A3D0B91CF5A6228A3C93175A2CCB06C26BB00D5224A402F119A3A42356A37CFD82162C65953B798D9D96CF4353805DDCA537A9504B708D16424A3C6209C2D738E25C357256833DD14375A65E1E32868BC4C4E5E062FB636E27F4C746EAAC0F641330D235D909A128C890E531BE3E0CC307E632BAAB0EF7684CC687BAC9B966EFECB85ED1030A1B1E15B71BE5A263FC64C320B145CAB657A14C2749DCC9961952AD5489C6485F208933FFF0203F3C31EB6A389F072CC3573166B9349ADA4D7DC66BB12C18A7D96A86F93883F83822EC0094B24751388A51166DA6B24A0B526935817E1AD73B4403AA3B10B5D1822DAF198AA848A73C9F9A866B634F939C2179CE55EDFAA1D5D48CB3127F0FEA3ACC7B163D", + "sk" : "6360495AF613E1C6B526A64A23CB3052FA4FC0198A351AA70D982284B13CE66384EDB522DF0B38199BAA8265CA96DA7040A7204CD0162AB481517A76D9B94A20306B04D19F5AB43146F26C4F43C23094131B9CA58552AE1EDA8B9E623CFFC533E77AB7345790A507A3EDC589A0E01584A291E0A98389224AC057A2C7A49AA92C012E3068FCE416936ACE78967543053542FAA399A8B7D2F5C483D9B09058067DB414B319407DAC97A1045D78B6633D2B690A77510D996ABD44C972A37B37BAAE708086A4143926875E09AA15A206B3FDC69562D645BA213A13C74B245072A2480459672B33AB4F1D969157137D85F481828A7CB71AAABBF6B54874821B9B77E41CAF849874830A742C887FAE918EC657343AA11C8DBB6190D53749157E6277582C589AD1D9A33E740E25F00BF3DCAF2C03B1A6A64FFBC0A104FC37A2C34F7B8C56E06AB258B7C79ECAC3EEB9C2A87C02171ABA70B84C58D474F4841241DC10AE9645C1B71163AC3053A8B9E999309494763C50354E235F253B87AF35818166AAACF85ABEA0056B3CA078960DC54C599BB43508FB06E06C968964CCA2ACC72A17C25D47A6768C512836A7CCD3CF58B09A024B1AEA57BB26F2219EAA3F473A367EFC8BD1790F576978FF159F282A218DA906B506BE5C63C016A55D92C69999E4CF1E1730AF67881DDA242F505FF78C242D3A3730C088B83ABE4F39BB628A4EFCFA03B0ECB8FF98C288D1B8E12B2429263FFB0A638F9665704B1770C4BE9D999F8AD6AC080671CBA047378A60C259BF042839BA39A11F94354DFB8D3DA789A4790B2241718A2A267C7C8B5E1A2178002971306D08F360C6940043A25B4AB350AE385969FB28B64CAB121C10AE15CE4C51475CB4794CC18118B877D1E3723101BA4172C272C1CDD1E33F506212C5B421B0F631DD773BA590B894056051753FF73013DAA26C597A50D0023B2CA99AF7AA5F218971B5C8845C68801468471651765922C6C7586D88B65D017572D792B037D7684A86A517C453FD36CA5135B320092C36EBAB15DCB82A70C156E6657ED35DCCF34F94559B92D83F7D46277926C9D7422FDBCA5424D431D61648A848BD8E260179047120A72A0BD1A495EBBF154908EDF0363B86892F783E75369252E92A85097A2636C8F284A841396D4CB39F8B247CE1593FA502A6CA4014CB4036F94810656CB9335C24EE345B1CC15431359DCEE9526EC6A42D26280493B6090B0D500808BD29A321959F6101C18AF673921804A3501F5848022D0B1075B1ADB6F30F47786C9DD345CC33A12FA98DFA909EB724CE7E853B5F29A00F43319F92A14999526CC7966D3C25BC24924F5CA64DE9A2A5C69965F95FBF29875B201DD3D54A1ED97CB7039F8D3982764A4E964C45583183A15C0D8097C033DC144BB7CA7D4483900090859C2A25C9C2B1AAB964D7629BB420F3261E2E4C76AFBCAB41272155496C4CF9131D7195B9228EBB613DC7B42541CA05E39AC09E710FB972978F4395B883BC6A67593A7361E4179B7C95945513C28BD488F84146C5C8956C4B18A0DA5CE7A680D26A779EA5AB1A046CEE3191ACD2C655CAC8DBD9518528BE44E03C1BD758CFC30D9D163B06C0A60E5013F6E646D3461A3993B7608B9EDCC65304E92D0E59B193747325452AC403771A657B92FB8D4A57A424F13E323B37C46183B4014600B760BD44C5EB1099167354A5C31AD377A5041C6EA00BCBA66B18CD457A6571853DB6A90F408FFDBC35FE7BACF16A2BE625ABC9473F57C269F0029844976475F484B4090A53523F0766168F80A708AB37E0776C0A4B4FE02795073A19C01619EDFC36FFDCB12668851C43C2CE7765C050A46A025252904698D2427A634FF421C45D2018772BBBC3AA2EC49799B3E9733E4B0CB16973E51A1F43AB1596D64A92C61576592D6F3CB339F76FFFE186106A176F45525900A6B594B673271CE54499BF90A5C5489928CA879E93B3CFA7917999B472D1ABD7DA21333165B95C8B1F6736BB183FA14B9D1B26143E1807C7F71D66360B1AC2BE6DB555C1DC907B794DD6A07C505451BDA90D2E7A7112636FD7590F48E0C94CEAB150906945273CD375B82573AB5994C2AC447F5D53A3D9E04B4D694F5D81B54E29C125F461BA056E599674B5D15B0161802012217CB73419D431E03ABE2F7A733C9C0D0A05B6AE91776032105BFA99D149062746AC1FD2CA81DB9224518A39629A36D043E6A398444A055A2CC28AC785E22B9ADA469D2E3491174A4E16E11824D32C33326F7CC2B73D417A7151496FBB6805A79D5D974B12F3C0125B5D7BFC7C6F244B68E2C1CA8613E891322261B4789898A1F858F5991B2B1B177769ACA1453C57C43140548452F3053D3B55FD2C3062A0B11939A3C14A81C59432616A5700C775FE98C6FB88C1EB8277C469BE42F541DBB79808479E0CDB11856CB7C1CB6A5B865469BBA549D73CFE581BEE85494DEA28D6E96A5F04CD65E561EF66A2482C806E39257B9BA9581421708663BF0B45B4131EEF3384EB53B8733C4957937161C3CCACEA5CBF91429E87B8B2B6A0AA44CAB94BCD02D14CC3932C3EE58B483B1D11E5243FEA0D34912B8D45BDF48C1358DB3FC163AC081C23CA6C43919A649C33911C5802E2407E9FEA350C3B64F302C5489005EC87650DE428E60B790489A17E96B9E1FA91B33BCE5F4B8D8DFA1610B39FD2858C25B898C1386C6DC021BD3414BF213719867F8CDCCBB4D2BDF12207860A638BD41A05B9697A3BC901E9AD0075C080243CC0CBB3D389977C522230A42125B08D41839986A60ACAE28BDA183AACC32DD5CB149AF2BBFC60B0D5BA8AD89B1ACC0863CEB24FAEA37EF3F60168CC96D766642F07A116225873E651EF693F2BB97339ACBCBA301E975405661B2AA523168E06C86F9BCBB42B5F12D79C3C379AFCC37DC4995B11A4AFC3578A30A13FF57AB87F022FD5C3AC5DACC3462C7E7EDAB63B889C22E90D685733A1A79EC336C50C18A5FE4408C2C122E34A60EF56A78BC16B78C3C98ED689E0C9276697CDD8ABA667109CD911B77E6930C4F58CEF1240C1F7005A7A2B17390988924CB0604B4F897D19C5B0E4A557A6A23470BC71DB15BC99248D42D9BED4117652690124B1BEBB438473619C4919C6C0E4071CA990B9D005EB287B15126E5C3477A98669F0856242DC073BB2673C7C1B1485799C300A0648A83142B95A2377D7E2B1D994209184309934C914308B7371A307A3BFC825958A98A12524B847BA5B61E5A279EB9F7CAB5CE030C45FFCBCF919A6CE1059DD7C6AA077C2D2437408315DB32A800C2099A92AB682FAC6461896D583007B97AF2336B1E6D061643C62F0B5122D48A230225128C52863C9AA7837AB4F254F92863EFBB3B379F87E40071CB6C8B74AC79AF4EC11DA6C028F1CAF9545A7D0A984BF6AC8D4067A7FF29325DAACD3F9470D529F02B00183586011DA8A0295B678B18D7572CD4F081317B92C21803F613BB959170AD3A4CF465645D3E5A1DBF672013BB935BCCDCEA51393BCBE7C975D30A9823667BBB155BDCCD14AD3D8B453B30EC2B0CBD703485975CC571530B4CC521693A9965139FCA21A90D57397F34C46822EA0E0CA0F56668B8692127BC93322389046C63FD08FF82B67F9778964054B49AB0DABE24628E771627CCF34F46C6C820E9D890B15F396A291A98EB14A23575952ABBE46374C74B812AAC6B9CED932C078AD3F2A05C821B720305773D070B8C86D7686C53B81CE241586F5F752FB4A2774152638F04156A0B24B3061141878D5759D12F8BAD4E98AA5D41895B91E122074B31AAADC30A1DFF707C32AA0DBFB2FE0A519B4289942E99754034D65D7B9EB5C0087225048B5A293038969A944725A23475B0681CA2177C5BEE023BB7E0ABE99A630B5BABB5F8A67C8117FECF20C1187C338A97B72C1674AA302C3005037631CCFD51A5B10CE837911D8D8372B9760C0498B8AD8218F832FD8519476EA5673D6659B558895796E14CB5A55E7A3D0B91CF5A6228A3C93175A2CCB06C26BB00D5224A402F119A3A42356A37CFD82162C65953B798D9D96CF4353805DDCA537A9504B708D16424A3C6209C2D738E25C357256833DD14375A65E1E32868BC4C4E5E062FB636E27F4C746EAAC0F641330D235D909A128C890E531BE3E0CC307E632BAAB0EF7684CC687BAC9B966EFECB85ED1030A1B1E15B71BE5A263FC64C320B145CAB657A14C2749DCC9961952AD5489C6485F208933FFF0203F3C31EB6A389F072CC3573166B9349ADA4D7DC66BB12C18A7D96A86F93883F83822EC0094B24751388A51166DA6B24A0B526935817E1AD73B4403AA3B10B5D1822DAF198AA848A73C9F9A866B634F939C2179CE55EDFAA1D5D48CB3127F0FEA3ACC7B163DEDC529D14502BAB03D1B7FC370F2EDE22C7190BD47CC88028ADB3294029E264AB68C0EF1663E52E24C33090EA8F4F564D85DACA610FD7C2D5756D7D882408DED", + "ek" : "58520CFAC3F02AC1ABA6CD7EF6B2A56D570CC228A730D1FA7E07B4B7B589051D1DE17D10C0A81C0BE8849E8B92F3F5B98BA5BC4B6DEB0149FDAB5C13B26CE5D0C83DADF81A34D7F683E518090393AE06123B1A171935E5775421AAFA2C0025C882195E24883F2E64022B182169E754B03B664E43A5FB5D4C1731C54427C30178C52BF4BE272ABE26A45711F027E63137DBC4E113CEE769C72AB95BC317300B2B0AA7C83460A8295B51119B6EAB0A56AD701F31D03B1C8C5D92BC9159179AC1D87C09F1DFE63EB9E4EE151CB97CA8AE700F92D7EC12EC2D8D195F34260951C00D7C28FFC60941F7644F192DAD6913D8988F9DDCA99F045E6956759C0C7C14BC71BA0D2D403DB2C7FA1F3F97D10B1031D931DA8BDF10D84D9F2607EC762BC4474295600439A59D49E7AC6BC69EAEEF3E2D3968E3EF6B3C2EDC55D489361163E20F3FB37694ED5BA738357DFF6A27862329C0B9F1B971D1FC286034CB9EDBF7D2AFB6130079DBFCB4183C4271078FF121F64C916F450D41DE968ADCB7FBF3490D0AE72119B1ABB3C0817E10057BBDCA5C5DFFB1F16DAF6EB6B7EB61E8998346FCF8B61F45F17946F352EB396D5F2595A32FF8501195AFD2CCFB94F68EC72BA3958231A3E0EDB063465A38B3AC047C5F9373A74E89242D0BA3F558A8DF63B9C2EB539BDEEC643E18E7E2D4BEB4DC60C804BC774C462CEB72ACAEECD15FF95A1C89633B280419EC45F62E7795063441BF271C04D5E314892B20D185B296EC8D7DA7DC3F2C0F55AA110FF127D0CC0F6C3611A341BB8552F23E657B5B9BDEF439A90C36BA6243377D06530C483362A5005E5C12A4A91F77710CA2AD0DC5298029BEBBBF5939380BBA88C771B639BFC64198F65763AAFBEA0CB06FE1B415B9AA2BBC6D31D26F84E7536EBC0BC579985DBE6DA8F2314E0B3D017EAC671204E0212FDE7E0FC9BA8ADCCBCF65AA497FC2F595C04ED24DC72F79AED1E3785B2BD86A12FBF40B2B4F39E438D389433C27F57F0AFFAB7673B162715627038654514F6E18EDC0106FCC87E028E8D1A1F3A69BF1E13D433A3D0965F47075D7E5F75F603B6ED274E13454DC81535F0F46996ED5067BB0D5420BD9BFB9541321273BB30E6C911C5FE4AEFBE0338B9973E13A9764A3327699566474253290CD7F84C31A908B6A5C891F901E364B56464FEDA85A541D0A1C60B1394A5EBC58D1E9D4341B73080A1574657432600856A84D1F2D0C8F55E92035F8E3B833325E35D188CF1FB328B5783DB411471F4B0CF3F1573D1A4F2BA73A919A6D36DB2C7AFC5D6222A1FB86FE56487F0A568C8E2605735FF77EE2CEC59520A106B2B6F9948E0E3032585BAF971BCBC43649CECC312500826FAF94174DCFAA61B5D2E7FE4F72D37F63B2DFB47ABF7D981F14F9FD8C03BD97684AE0A12B7D56B75699FE8B6234415B26FC24B563AFA8D902DECC51D209A26889FB226BD1999E31D2D9948DB3922B1268943FE6425423E5F8DFB50ABD8C03678C74BDD67326168F5592A7407F0B5338AE045CC088B785761EF60F6E9CB591EA09BEC10CD7A06AAFCA7120E7F39D3CAF336819025415BA4B15BCB09CD8AD2B7796A039EEEDCFAB0F3D33CDEE6269403B3415592B55ECD5C5F5EA0AD78B9A3050B688F81A1947B3C4DF8DA300440106B120FC35FE954BA51847DE517D3B90C7A0A84B9B65C3F0E53998E013681CDA388887E7CC95C6D4832ACF53DC6C304233F623101765FCF4A8A87E48D129B2AB1DCA31951175D2C3B898069B9B76E824960165F4580BD8B42A3FEC0981E5705E04AE8EB817FC18A923EF0D7E6CC489AFA98F89CA13D4B52385A2FA69BE97B8C415AA8FA052C88A4011352C7CEA5D81B19A0B02715E2DCEA61D0736841F308294D742B4B87AE54299244F8BF20A5A5E633BFF615974EB433AE8F7AD207E1BEB4C477C0DC0EE120EF0DD0A3DDE77F6FB2BCA3ECCE4A172932C129EF44DE946981007FDDDC2D08895B9841EE3E87C5D8D750718CB6E436A3348A554E29806C31F34DF4B9A709F77287F601597DDA32CE2358BC42FCE9D55703EA36122A63B073AD84432C042F1094DDD3BBD456C0DE11F1CB31966D3E6C9C100F9586D65CFF61564F44303A4FC2BD841863D5E6ABC0E3DA64DC77FDC4FE5EAEA9DABAB83B1A0D874E8D3CDFC9C38C3A1301A6681A3245FC867D78FABA41DC3EBF7A876ADCA74E6C27387BF77EDDB43358A86", + "k" : "3E8B8748E809C1C8D0B1408A605A051F8C37F6FC33563DBAC04F750459D53A88", +}, +{ + "rngSeed" : "AA93649193C2C5985ACF8F9E6AC50C36AE16A2526D7C684F7A3BB4ABCD7B6FF790E82BADCE89BC7380D66251F97AAAAA", + "pk" : "69BC82661A9E822624D2A644E1767DE906658569BA68922AA5C18996C58B3325685BF3564518AFDBB99AA67ACABCA017283BCEC3CCA9075CBCEF02CBE57CCFC73581784BC6FC1B8B7623B9255C20F7430887C87A5F6873B8789DE3810EE4841447D826706BBE47D6C4BB13380A03A532D240ADBB8240847E6ED68EB5ABB3452584B949B8889BB77D2BC87A11C4580919931509E8FB931B50957FB00B972C8F17C8BE0E0565BD95B16799606B825E462059A701412AC2704CDBA91EA269271519421574F807206D8A65F8B67F44117B4C742E7BF4209668CB013975A9317EE847BB09DB3C44D8029E01C4FF4954D5AC7557941B4C12C60520785867CEF3F77214805C96D8497B508629713064CBB04D0B9ABE21AFABB10F33EB38B6B3BFB34908EBF048CCB239701944FE64792B8A909CBA14BBF50D03B858BF4A318B9860E58141B7F114B38616533C96C4EB25115724E6672EC20937FAB6164AA4A9818ACF072C90EA4A5BA34CC95270A330E2874D76A5E0FB085F1ABA5917A6E6C3A50AE59659D95703D0A1E9C76C0F0055605AC839F70F6868BF0727496F38C4FD042226FB261CE27BCFAB89DAA192044462CBA31297A660B191BF4440305C5235EC225018CC92480C19BCCB480D03D08C470AB20C88C7A1B2A9F37DD7B911CAE469DE0C7F6E08AA9D427A8EB90AF2649AA28CCF1BC19C0FD84842E5748F686278631659A5A874377347EA3894B035A5C139EC8CC0AA63A960535F8E3113F668BBFA9A67A82CCB03253461D3354EB81D0D112FD667A1F133C054730F28AB50F54C5416F65EF60B6CE8C86F6608456C819A7E10BA9232322E4BC73D8370874846643275622B3DA6DBCAF9FAC7001CCE6D34565CBC6F34A1BC9AE904C5229320A3755C4A439F035B5F8A099C70A6A57B5E3E15001BFC19710878C5DB0930B21F28603EA4087E0B30A2CBA02118FA644331A81312A22CA0721FF266620BC91FE318897B77D3C9B7F9986861879A3A9C349E16C72A9B2BD645915FB05A94BA4C57AA72E93C3DECC55597E664AE3A683274267F486452E089AAA8679234C2FDE99327A60A81E687CF4491DE4B90528492B6C46EEB7725D876A91987025AF06895279635E98183BB0EF7267C6449913ED09AE1BA77BBA0010B03B900863119011B1DD02AA969BA41B6B684FC3976C416342891CBD0588B5C6A480C04D7798820DA67C9142FC07A906F2517A9217398C9611B0749F5556821D93368014D9D01CF2976AF6BF492E2E59B66D3671E814E466388E2039037313AC690C3DC534BA77281613560B0FC9BC5A298C87B879835B386C6B0E1580830B689E7B005AE950D309C2E264556685C54C606AAB7C0318B2C66D4513A707B8B5800AD2ECC1567807F28122525B69B7E1CC0D1646EFCC1673A156429A205E4016887464C39A6543E722F0980B81F524203B45DEB45184D35351BE963D3906E7B0A98B49167A2E0BAC9C7A50DB62657C4CADF6985D753C33F90BB1A275BE17A7342859415F7855384975775CB557A2EB92801BCEB7F63CB97A40837AC159A37C2935157160D518BDE11C1FBE18C32923D3049B50B50C2AE0A325281C7A4BC32022AA7835630198103B25398D613631860B70A6536BBC66EF6FC9AB856771652689527C5F5DB1D1B4243E3F06460EBA75C363715378C99019D213732804B31E30CBE3E93C6F83A7EC239560ABBBD48D96684F17ED61C9DAFCB55CB168E2BA1778ECB0166E7664E9412F4EC7353092FDBA5CCA4585D173023F1856836619E57B0052B07141BA9507B042C5D5B89AB429B3F237F0D80C5D4126CB4C59D9D19BF0BFA9E3EB42894228D13A05125B36D1DAA647661905CB471B08405207469EBB35BA5375A40B923E6B0CDB3F1070BB6728A389CA4B89079467732EC3CD7A27D746850BD4908E401134B650419E639FBA07D88EB2BBB755B2A7AC2BC6947AB8907C80A3B5610A771782DAF790874563B65A1236BABA0B6FAC1E5F242919BB4519B637464565467456600882532457E1249E692BB82E16C7F21C370A29453A95600A069A54B0B62087F09EA7AB3DA48348257877864CB080F7A39603E284063DA75EC0B9219E515021BA46CA8C573B306E814245D45CEE5F55D0E5C7E36A31166634E7805A413A062A7B5A7AE75783F97C505DAA8F9113507A98A3E8CE6FF046DF83FD23815DE42EB44B586845B55B2D39AA000AD", + "sk" : "5999174084C2DBB511A7CC2500577F27809863DB3607C863F5E50901E2BE2B949EF9B55231B82703A200B1CC181E7119C0F9AB9839B795E763A5E7CA3A0216F6B080F0E7B52C8C196051B5DDD86779587B92BC10A16BA470BC115FE733C1847C689B06CDD2B3CC28A95D92BB479B05244549F5C3114951B872E1257B10ACF04BA20CBC2A045947AD631C41781D0704C6F469908DA6AF1250BD04772CC6C45145E8193B739DE340397F1CC431227474F2C15C634961B7AF3DC645C9278C8FFC304AC39D1933946981399C92094AECCAC243B81B698C2C4985E0191CA1126861D5A5F8EB61C023A5B38489D2168BC75A6F891202D734A28335ADD858B6A3DBA95C86899DB97921007777902DF820B4D63B1EF40BBF87A59FB20662001511A75C323EE3B2EAC47F51CA993F865BB80954138BB59BF2731C2B2498940129746C8C6297D2BB5AA8E75E3560CE91002FAE79543289C7F1D1B1850B8CEB2166104B2AA30028CDFC6A5623C1EBC2C8F8CC2F27345412D90A9A840085ECB68214A13444AA3AA7259F35B0C5CB9E80AA83ED21C714A1A51CEC15B91A578544294F565FA5C640EDD9BB94C52419209006E9439AD53CACF4946567B80D4A11F5B2CEF3740D20ABCC04E39AADA58CAE16185072B98C64B7FB756EB0022FD055545B679BB14829BF0606558A6EC5497EA824371EA95312E31A02036179945A599454F5210DCE7A3610055BD6DB8F40E37502073824EB699A3913348660F3D1454430951732ACDF3B4B64D57C9E69C6E6CAA65E029A9DE4C36942CBCAB150034510EADA835FF5AA0024B36DF8301EF2AAE086545A421E834C9DEA771575D0AD98A0562E3C56B38546AD04475A39C310572FAD7339DFFACD2C39888A898FF9703D71147C3C9C476B75911D8615F43C9138003D1EA59E86CC9160F340A03904C8774924CB8CE5F610EE7A979F320960343D22C0CB84F977EC08B7FA18C34A2836A2157271472100758281198CFC88CF2C4B4EC287C6C669553F0135BCA1129874B480D4621A4994D690922F67C6EF8B66C6602256AB917A9576638285E0586F3EF860D3891B66A8551A19A57AD7286C700BD7566938727B74401B9225732D5BA65929175480087F645632E93EA2C607B0BB900EFB9E71D57B84F63B2D6946BE5A66E77B032883B64C2734DCE12944225DD58C3D19476A4CB01416711A1A81BE7510C3D1183EB5D39391889D78206F3BC2775E174839A0162000921EF689A204565DF8CF155131C9E7C5569459C81B3F712A8B0DA79B1FCBC9A13C12D346B2E121177ADCCA95E4C6AB647784231172E4C4BDE45C7A4532930A2A0A60A663A5B7BF186A5346A2C0EC9F918147A1E66B7F6289A21C2A6DF8B04DB12E76027D89BB7C13BA9672D1C76F4057415160430985F5215B53C59AC76C6387E52281889D968592DC607744757B61F30AFB6C4E90CA6A580C475CBA12664A5552F17330696B12B3CA3EA72784D16D2DFC5ACC0B1665BBB1D8A09D8BFC6D81BA51F1117A109B43D2C97250FC9634001FE8018E2C9300E1E46C317C62574B1EE2C850B78383DA446DEB16AEB66A08A3348ADBA75693991B4C4172F8575AD7730039E3ACB9BC8BF238C20E51B9CBC9818554021D7465D007967D274D82C03AFB990F7502A87A60036BF5A204910E7FB3A514B8126AA96DE7926592108C0692AF748A839335837F0A9D3B20C97F3131906197C6A66AB88291A7C62D7D740F004D44E261C683827FE424B02802937D6AB4A798554574A0A6B5894BA8AFD11B782472950C2CC678C148A9F80CA305BE0B765A1542A1FE8690F4C865A09931904A3408E665D60633349B72C2353159220A12B5434EDA854D7983333C04A0864356C6A137892023A89A2ED1A263A100A7503C1EAC6AAEA6B12A434B9BA504C9D79C8AB4AAA20611CCE877A5F834D740108874BEBB82C23E65BB16CA769C60280B036E2B921EA4D30F59F68D189A595DD099A6DA6AFCCA07A6159099E05483B92D00076F22D0A1B94761E8B8399B4A82E204A011F141FA82768B2926D086A24EA0A71AEC9D8723AA77614CB0B0CE881742E0A7A2AFD0C288244BE4400BE81A90209C33AAD80B84E383F84A4C313ACAE89A6575A3AA726B65F0D75E5A7AB355F967D5B771C85993A0B6094EB35E05C409F3E47369BC82661A9E822624D2A644E1767DE906658569BA68922AA5C18996C58B3325685BF3564518AFDBB99AA67ACABCA017283BCEC3CCA9075CBCEF02CBE57CCFC73581784BC6FC1B8B7623B9255C20F7430887C87A5F6873B8789DE3810EE4841447D826706BBE47D6C4BB13380A03A532D240ADBB8240847E6ED68EB5ABB3452584B949B8889BB77D2BC87A11C4580919931509E8FB931B50957FB00B972C8F17C8BE0E0565BD95B16799606B825E462059A701412AC2704CDBA91EA269271519421574F807206D8A65F8B67F44117B4C742E7BF4209668CB013975A9317EE847BB09DB3C44D8029E01C4FF4954D5AC7557941B4C12C60520785867CEF3F77214805C96D8497B508629713064CBB04D0B9ABE21AFABB10F33EB38B6B3BFB34908EBF048CCB239701944FE64792B8A909CBA14BBF50D03B858BF4A318B9860E58141B7F114B38616533C96C4EB25115724E6672EC20937FAB6164AA4A9818ACF072C90EA4A5BA34CC95270A330E2874D76A5E0FB085F1ABA5917A6E6C3A50AE59659D95703D0A1E9C76C0F0055605AC839F70F6868BF0727496F38C4FD042226FB261CE27BCFAB89DAA192044462CBA31297A660B191BF4440305C5235EC225018CC92480C19BCCB480D03D08C470AB20C88C7A1B2A9F37DD7B911CAE469DE0C7F6E08AA9D427A8EB90AF2649AA28CCF1BC19C0FD84842E5748F686278631659A5A874377347EA3894B035A5C139EC8CC0AA63A960535F8E3113F668BBFA9A67A82CCB03253461D3354EB81D0D112FD667A1F133C054730F28AB50F54C5416F65EF60B6CE8C86F6608456C819A7E10BA9232322E4BC73D8370874846643275622B3DA6DBCAF9FAC7001CCE6D34565CBC6F34A1BC9AE904C5229320A3755C4A439F035B5F8A099C70A6A57B5E3E15001BFC19710878C5DB0930B21F28603EA4087E0B30A2CBA02118FA644331A81312A22CA0721FF266620BC91FE318897B77D3C9B7F9986861879A3A9C349E16C72A9B2BD645915FB05A94BA4C57AA72E93C3DECC55597E664AE3A683274267F486452E089AAA8679234C2FDE99327A60A81E687CF4491DE4B90528492B6C46EEB7725D876A91987025AF06895279635E98183BB0EF7267C6449913ED09AE1BA77BBA0010B03B900863119011B1DD02AA969BA41B6B684FC3976C416342891CBD0588B5C6A480C04D7798820DA67C9142FC07A906F2517A9217398C9611B0749F5556821D93368014D9D01CF2976AF6BF492E2E59B66D3671E814E466388E2039037313AC690C3DC534BA77281613560B0FC9BC5A298C87B879835B386C6B0E1580830B689E7B005AE950D309C2E264556685C54C606AAB7C0318B2C66D4513A707B8B5800AD2ECC1567807F28122525B69B7E1CC0D1646EFCC1673A156429A205E4016887464C39A6543E722F0980B81F524203B45DEB45184D35351BE963D3906E7B0A98B49167A2E0BAC9C7A50DB62657C4CADF6985D753C33F90BB1A275BE17A7342859415F7855384975775CB557A2EB92801BCEB7F63CB97A40837AC159A37C2935157160D518BDE11C1FBE18C32923D3049B50B50C2AE0A325281C7A4BC32022AA7835630198103B25398D613631860B70A6536BBC66EF6FC9AB856771652689527C5F5DB1D1B4243E3F06460EBA75C363715378C99019D213732804B31E30CBE3E93C6F83A7EC239560ABBBD48D96684F17ED61C9DAFCB55CB168E2BA1778ECB0166E7664E9412F4EC7353092FDBA5CCA4585D173023F1856836619E57B0052B07141BA9507B042C5D5B89AB429B3F237F0D80C5D4126CB4C59D9D19BF0BFA9E3EB42894228D13A05125B36D1DAA647661905CB471B08405207469EBB35BA5375A40B923E6B0CDB3F1070BB6728A389CA4B89079467732EC3CD7A27D746850BD4908E401134B650419E639FBA07D88EB2BBB755B2A7AC2BC6947AB8907C80A3B5610A771782DAF790874563B65A1236BABA0B6FAC1E5F242919BB4519B637464565467456600882532457E1249E692BB82E16C7F21C370A29453A95600A069A54B0B62087F09EA7AB3DA48348257877864CB080F7A39603E284063DA75EC0B9219E515021BA46CA8C573B306E814245D45CEE5F55D0E5C7E36A31166634E7805A413A062A7B5A7AE75783F97C505DAA8F9113507A98A3E8CE6FF046DF83FD23815DE42EB44B586845B55B2D39AA000AD80DB50DDB1AFF6498E12EAC2D5DCDD68BE66C7A569B0153AB4AEBA37A75DC9730DA1D147E7686E428AA1775BC2EB045D1ECBB17563AC966F708CF3882C47B5AD", + "ek" : "7B389D8510F58383423001ED83C4BF16CC08F990F0DA964637085F909E211AA019FC3D7B7B22CE6C9E54FB341A331B2B9EA6769A9B8FE1D229996E8A7FF7BE10A5CB0DA30121A2C8FEE3C1EE1DDA6BAA82099EFD1EDB948CE7EB9000602EAEE5EC89CDAFF12AF2FAA533B8023A2A41FFF10F323D51B1F13D0624B69356BCC7882C14B279B8AECB22F88BD3D0BF010D68375E77076AC2DE6C3725AECE1509CE6534765B5DFD931E994B017C0DF829B130166E30D2240FDE37BBE1F26E8C0F5E0588DBAAC8E7D59F6266396CEB3A11CC6AB0305531DAE07AC5AC12C609645AEC8E072E7A23C25996DB31A12D8FE314B9DDED04F46F579050EB82B7E85E72DF99719B334D61C3DA0B656E798415E3AB988AD8147E2F61401FD71746F0F204CFC9E0E3A8E2BA56D4A47B70724A822A54917AFBBB20E0C06FED3FC4E2F32BD17EA0AA90AE6EEB7661E25BB7AF29F7460F9E92CAF2EE9106DE8FFE07B612420FD7A5F7BF4032DB3BE614EFD2777BB16C97B6853CAAE1BF646B7778326907F8BA02F2BBA33FB382DBE9A3DD4F74C8D6309D3BEB457F369B7ABF8A554365C7146D74DFA728D0A91C4954580B1E4E735835CC5375DFB2FB9295166C66F28F4241855D57BDE7762F09B026FAF40944CCB232857539A2FE59E6D180D430DF010FF4067E1D10712422D7B6CC2F908C8D8CB4DB95C12EB3A4723A3272359EC8B9FC459CE108D10CF92ABA82D548F1C234DB9C9679F488DA80A936293CD8B9E45403899BDCA8F5260207E57CE3958847AB1577E234D871B4EA187A9C638AA800F326F400CCBF884AC44D0EACFB6E3BCB31D43C7860329C4A559A61B70112A0027954AD49D93E8A59E2ACE52514EBDAF593B6C1BF242A92B03A05F1780218091203CE5C59E5192ED001DCF80637AF843D37634B1479AF9ADFEC8FC60E2339EE0301E9783513470D7264BB22A97FF00428B004FE62FC602B795B4713082370172E19663F8F9E84658CBB54FE32DFB2BBDF822669BC7A870D1F06DC1CE463D03133D5F411BC951E05E50072FDA9A9B032BDBF29C2BDD5D4C93211C213A1401249D746334D4FFD11C3EEF02A2E8FB00257EF780BA4077B0EC7301F00AC8F68AAA7ECB7C98EC7DE26E3D3DD0279F1922756F4C6FE004F74D80EB596E4054E2CDB7A8D25CC83CD08130542FF638A0B5AB2FE4F2D106D6BBEAD8615C91DC9D5DD0FDF9AD1EDC95BE0ED3DD96434C2427B34AB58EAC7D4F96A2539CA23BB56F07AFAB7F10BF2D8A28FD27EAE3EAFABB94AC261403DE902B7D3EFD32002757CCB53CC1170B48B47FBCD01C874D3A7DA7133CBA5CBFADB7773D1E03BCE9A8D41B5AEF079E192F07072C813C53E9D60DD35456BA6912DDAC310CC01696093B13B640C181D7A89884AED04558440E20A93A6232C5D6248C5E0B34FA5C8A0AC570051BCCAF216BFBC69463308BB982C3A432DFE591DA521CE443F3D0E6652CA80B57DBBB2A43948708E010829C85D820FA906FC84F69C183C8A9188DA96A3582677C385464DEA89AC9B4D5E302A3C83C34C379A9A158CDAEED4F8FACBBE692CB2E79DC1A5BB1324682E513D23D89C5E84D3C5585B4524F0ED1ACACF5A55F8C33D27420DA515E26B2B7F45011D4257FAA05932ECA2603B5817F868E47C462EB160EBF69B09DBF8BABC8762023E3E6826B433B2AA3A3DC7CB3ACE66A97CDFA71426896564D16B66EFFEFDC85A4543FC92DA14301450A2629C86250AE067495F130842F9ED3DE194A7223C42A83FDF34D65335EF437E0DFA8D9C7B71159627CBDB25C07AFD3E66E665C90F902C3AC0FE1C3351AD97FC80EC5384F1DA8671ED3B8B438F179C1E5D640E4C7F92284A0A281E501CF4785CF8451AD9BB4CF80B05880CAA004EB185E5B656DD7F8244D2B0E8790B4821078A4AF2CECE3C820529FCFBC3AB1CB377F41F908B58D0F888F447E1782E28C86509DEE8B7A6C63381CA3DFE58F9600C093E98CB4D3C2B06CFC063C02FDBECEC899C55DC7AF72BDA0CAF017AF2C935ADFE029C453D4EC455BA94AA7352AF01BE3AA34ACF711D0AD587621D9097C54CD6631235495EA92012B1084953C5D8CDC3D330D00200CC9D5EC8EBDE37BB2D902C831F1F343953F48170A1C94834BB30A2DFB07C6F7ACEDEC4D54E65146733C99C7986A1C06C1C41A392D1E872C8CA33EB246F06B12CD9E4E155C7A3DFC844FD1AC7325716DD805D15351D07", + "k" : "663B6EFC200203BBC10FAF2C23011460FB59AFDD381EA7DC4FCACB49C798ED52", +}, +{ + "rngSeed" : "2E014DC7C2696B9F6D4AF555CBA4B931B34863FF60E2341D4FDFE472FEF2FE2C33E0813FC5CAFDE4E30277FE522A9049", + "pk" : "55F39E77F0722A726811358DC0F0B76AA90AAB8C2DFDD3A4F3E31CDD076947D2B503C73B8805B26D6780D75B86D5F3B50BA899BEF229BEEA7D18FA9016878F3AA8BA392A4B42EC4F92F42AD08CCBE58A18BBC7C8639C04016B9C663CA32EBC31FC82A138970C0CD238B6D1B2F2645FA407504183A125B1ABEB622245886B9DCCB9F2793147A63227236C9CDA173C0546739BCA51AB24CF3287CF935A8D870719A62B71728FC5E262662296F9984E485101860679CAAA02FA1209E7703E0A5678C496A401CC5C1B834AE8C02D2A61B8C40694C634C80290A2F5B4A63F865ED6689A54201589A3384ACC299C054D1CFA25BE6AB278530B93616EFA35CBD0AC8FD367923BD89CFA828F1E8A10A6D027EF2417422A491AC1BDD2702D688809B7455824AC902A70B06D54C92D73B2047567A25336FC74A6D8613D6AF0A51C0645ED30C19F3231C147AD98E0276654B9277B16E100A2BC1327ED41043B61900D48C1F51C70725133AE31190B90B43DA26335A323C13652A04A2E084827F190915548ACD4D96323B573AEB2633BE0B3061544CB6B80176337ADEB4C5EAB7C55BB612E9390419A7598DBA6A79523F5764EC7FCBCD31B85C41548E1DB0CF1AAC1DEA8031B0C3B9E629B6B9C06EF29628AFC979D303355FC4D1A480FCFD0BDD9C04168E772880A4A53D4182AD30B760C89B2787691B40EB56165F321691F3C4880B20A81D08834C9B2D7B2AEB0E537F5EBCAADA992AC0A3402E81E18AA1FD1391F00FBB333D46C7AE50373EBA628685D15CB1867B952ED05BCAA8A7EFCE7C825EC58054B2C84D5C69DC22C219CC71D5A92230B9F40F633029C30BC6B266B37BC5E994E14F96D4C568D83DB3491E38AE1B4A320D831CDD5A8E582A1E8A43153C347A3C91919BA60D18490BAF18AB8A530066A9C35CB7E05915D208294059B161B09A0B8B446C322C9BD6160D7413974A1B11D0B643364432A1A2BACB1C0D70C642B68811B39A69D44974B125655A64075B35CF9CC0D632493EC46307ABA8ABBC1033EAC4E7AD3329C246A08294F3CB141FAD16F10B6804F70597DD6AC34B2B40190C36E17325742A4E9386C08B69CF1E0124BDCC2CEA6CE77B310262A71FF7017FA1B70DECA96DEC183F2981975036117656955A5C4F1C674B09C1624C0C48AD2C2584968F511BA5D070EAD9C7889E79B1E123C488349A1F5216F351070BC459F3C8CC8314E16B97266D37675B809FE962914D924D0827CF9B41C9FA169612B70ADE609BEC43E04345E5B97C330D9216A5A7E42632F09E95469E9B3422041C3119DE5E845D6E02795806ABA9203DA928201905E2FA82C6C7229EF074A230A05401CC9E22076E1C372E742C8EEDA0FE7ABA76CE5BAFF468CFC93482A1AB5957CBCDB2295BA074038E539BE24986CB8297A536FD479B42C8973B7D03D71D74346625F96234B32323B17C3769564A1A82378DD5C4D23A551024C3468E50AD5B97CA5641272711FF4464D62B9619D130DE8491430B5CCDBC928B7E411FEF80FB942AB322323DA20CDC42B5D17A9406E3612B7970B648817E060030D338689665D3AA7CF2B97314F8237AFC890B10097D8F304A26B9664844784AC8D00932ED8B32438A28E5B078484B5324D976422324FD0F217314102EA587D6DE84B482992D9E6A6CDB3112599942FD76434390C060321D326BC702376D466683AD546B3BC2E47E4B891F3B7D584375DD3859ED58FE94255FE421BBFC7214E3ABE265A1465E58C1067BBBF214DB3A94C54876725FA0FDD048764921D5B6BA00C3382D5064BAF295B30029BF27A88F8F630D5558D595549B65201793229CA2647621648297A66E92917E409CCCDF5CB1378B906C3BA731355D57CAD41F6148F7A706F850E99E7610D2C78D45B9F699926A4E01527A1A49886BA5FD25CA21C325E21034246C45785127F4859C0A67CC7B76259410B2F408F4E1569C73C54A4DA92A40476402573A2973963406290549F4A41A2226131251C5D59D85E1D5123D527576F7C794842974D884E79927F7BF6B09B752CBBFC442934BA461429A3EA921ABA995EF12C21116CFE66B132402BDAF690ED95483AEC9785E6989E934E7858BD13498F4E994619EA9CD55A9504E40B4D0CCBE8F8CCA1F72DBF74CAA3975595623C12F22C120C022B59B2CF3748B17199C44CD37F8EA61BA5D8C1BBE50789CE915DF9FCE1B4CF3C5ACD7CE52DFD", + "sk" : "8146C57021044D4310992C0A37686E1B55240A076646E041ECA9976EE77981F4C4743788E5071B28011A2E26C2CA7C3DCDE694DD996855EA17DCB241DDEB8CEAA74EB6E90BC7E415028CC4F7280069626196B793E7208B6987516A4A95B4906274B9A154D669AD7A85D454CE905C090AABC30FB68F0A001BB7998772937EE88714FC854DD1CB7F544B7EA345A016841C6EB1BC070066C2134591944016EC8CC5443F57E72FD8020F90F332A0284314CA6B02F8596DB0A7244359D97A9A84C07F14939405718781606C80E272A0462FDB2C323C326383A010AB5BB55531A687233AF12812D88268A2B73FE0377512E6BFE1FC5F74948A338259654760DECB2616F3AB2D80428CD754E27746196B38C399A765B610F46B00F3B717A888B7E2111EB0986C8CDC84A546C420B6B37C882E96E96618B374975C0B8ECB50C6B9BC8D598AE6B46C023B82F3393817A19D09FBACF897251AA9389603321192BAF160C0C5489381634320BB2083D604F6DB178C8374B055271A124CDA7100D48847719704BEEA14F6D18EDCA69DB74B1E5CCC47CCEAA4609A7AC43BC32C8159CB4ABECB2800B1947245196BC4E3675540B6D5A29EB7E82DB5C3B7F2B70B12042727489170884ECF09B0537134A9AAC0CC79568E562695947AAC325BC104BB45E83956E857803C563E287A20F9063291B8D1809795A069DBAC2525E6CF0E1628CE07A335B110648551ED4471FA166AEDB5449F64CAD9EA5605BB2C51CAA38AFAC0190C515FF0BAC6D8712AFB250DC4BC96DCBBEAC20C4291097F31611A2A3DDA52C94008357901BA6B5A227D5CC744D4A4E3BB97EA0B7CC8B7829BD245E6039E23B9451011334928C6CC22A919E97558CC9A79B988D248186F3ACFE7C1AB71500C8671568A591C6306920C19B396923368118153458EA7411CF38CB60779CC9195CE98EA9C0C549889414DF119874CB44B332B8789599A713056BC0A6EDE61C05777262FB1C7DD03AED0B324DD903B7BE44FDBA05D192BB5426A86910108E3D257AAD1A99FB7408AEBC5A758C5728C7375D405C4BB461816BD7583AA2357C83A594D41449F7B7CBAF4D80B3948A8E92CAD59A3283F7C3233833AD8C866AAA1CD0B39359A0C60DA978046EC7039ECB3BBE752045BB15E8A0C745BAB19287E79D844DDAA9EB89A4512B249B637122BA646888A0B14A50473683E05449295F7729980043C03357EC35432585270780805683D04E6A6DC099F7EA4A72B482E090797392AA8168242A5890EC8E89B13EC202A3398A734C75FFCC37A088225E103AC41B52AF9412069BF0084C303FC0D205509A7211598D475F4437782FA3637D8C6A7150600061D4458811608AE7D290B1706516A9456C665CF86670F20F2A5F691CF36D1C90772B837747B737029D558CBFD418DF8E26E5369BC0FE35E4089C7EA67383EE02F51F5CCA36A2A2B867668521AE972486FF865D4E2BECA6C4B1E39CAC3C61CF131352F036C6292CCE7875CE6939544B58634CB62FE6B80C4A4447CBA420DCA993AE070D3C69D62DA3B956897DAF687C6E339F8B45760B40C0B9AB06773584584B83A8113BD765815537985D2CBFB784BB3FB50BE2B11E79B91129C29B7468638978A1CC8A81ED289CF209F41F85B4B018372C8799E9B7403E10A8A63035417719B3416961B94C47A0D81E51860ACA7832B23CC41A541529DF511A443E480E31020A1A5B5AC8A43B022B9B1581CFDAC0B8D0C082E392C473C922481B15122CF4E47474D6C73F94496D812283173B6361C31AE5251029BB45D21B8AAF3037FBA8B3F3744508B25CDCB35873321B6671D94C13148B115EA13B196DC9C3C5C7B37D5324ACA344597870F361CB4E5B9450B93FF8A69B8CA3C55BC76845A635584CD0C145B67CB047C0517CF60C8A1146D11274531EB46DA9943D8B777DF8344F28B8B12FBA249398FCC7710ED177C4AB34C0F229E4573C882D00A5A88CB41F4102D309B8A23858DA00AA9C935E4E157A7DA40885379ADE1489B4B75DEDC7612282DF1969B5E42A915B17CD084788CE92521D6A83A79047E7CAE21325D40D357BE0B3A47933A5949A4C9B42FF883A3D7130B01843D57717BCBCC09EE13C0B63311DF50425E7669540B3C3444A43B775473189D07C1724A114FFFE30BB1976004A66CCF811955F39E77F0722A726811358DC0F0B76AA90AAB8C2DFDD3A4F3E31CDD076947D2B503C73B8805B26D6780D75B86D5F3B50BA899BEF229BEEA7D18FA9016878F3AA8BA392A4B42EC4F92F42AD08CCBE58A18BBC7C8639C04016B9C663CA32EBC31FC82A138970C0CD238B6D1B2F2645FA407504183A125B1ABEB622245886B9DCCB9F2793147A63227236C9CDA173C0546739BCA51AB24CF3287CF935A8D870719A62B71728FC5E262662296F9984E485101860679CAAA02FA1209E7703E0A5678C496A401CC5C1B834AE8C02D2A61B8C40694C634C80290A2F5B4A63F865ED6689A54201589A3384ACC299C054D1CFA25BE6AB278530B93616EFA35CBD0AC8FD367923BD89CFA828F1E8A10A6D027EF2417422A491AC1BDD2702D688809B7455824AC902A70B06D54C92D73B2047567A25336FC74A6D8613D6AF0A51C0645ED30C19F3231C147AD98E0276654B9277B16E100A2BC1327ED41043B61900D48C1F51C70725133AE31190B90B43DA26335A323C13652A04A2E084827F190915548ACD4D96323B573AEB2633BE0B3061544CB6B80176337ADEB4C5EAB7C55BB612E9390419A7598DBA6A79523F5764EC7FCBCD31B85C41548E1DB0CF1AAC1DEA8031B0C3B9E629B6B9C06EF29628AFC979D303355FC4D1A480FCFD0BDD9C04168E772880A4A53D4182AD30B760C89B2787691B40EB56165F321691F3C4880B20A81D08834C9B2D7B2AEB0E537F5EBCAADA992AC0A3402E81E18AA1FD1391F00FBB333D46C7AE50373EBA628685D15CB1867B952ED05BCAA8A7EFCE7C825EC58054B2C84D5C69DC22C219CC71D5A92230B9F40F633029C30BC6B266B37BC5E994E14F96D4C568D83DB3491E38AE1B4A320D831CDD5A8E582A1E8A43153C347A3C91919BA60D18490BAF18AB8A530066A9C35CB7E05915D208294059B161B09A0B8B446C322C9BD6160D7413974A1B11D0B643364432A1A2BACB1C0D70C642B68811B39A69D44974B125655A64075B35CF9CC0D632493EC46307ABA8ABBC1033EAC4E7AD3329C246A08294F3CB141FAD16F10B6804F70597DD6AC34B2B40190C36E17325742A4E9386C08B69CF1E0124BDCC2CEA6CE77B310262A71FF7017FA1B70DECA96DEC183F2981975036117656955A5C4F1C674B09C1624C0C48AD2C2584968F511BA5D070EAD9C7889E79B1E123C488349A1F5216F351070BC459F3C8CC8314E16B97266D37675B809FE962914D924D0827CF9B41C9FA169612B70ADE609BEC43E04345E5B97C330D9216A5A7E42632F09E95469E9B3422041C3119DE5E845D6E02795806ABA9203DA928201905E2FA82C6C7229EF074A230A05401CC9E22076E1C372E742C8EEDA0FE7ABA76CE5BAFF468CFC93482A1AB5957CBCDB2295BA074038E539BE24986CB8297A536FD479B42C8973B7D03D71D74346625F96234B32323B17C3769564A1A82378DD5C4D23A551024C3468E50AD5B97CA5641272711FF4464D62B9619D130DE8491430B5CCDBC928B7E411FEF80FB942AB322323DA20CDC42B5D17A9406E3612B7970B648817E060030D338689665D3AA7CF2B97314F8237AFC890B10097D8F304A26B9664844784AC8D00932ED8B32438A28E5B078484B5324D976422324FD0F217314102EA587D6DE84B482992D9E6A6CDB3112599942FD76434390C060321D326BC702376D466683AD546B3BC2E47E4B891F3B7D584375DD3859ED58FE94255FE421BBFC7214E3ABE265A1465E58C1067BBBF214DB3A94C54876725FA0FDD048764921D5B6BA00C3382D5064BAF295B30029BF27A88F8F630D5558D595549B65201793229CA2647621648297A66E92917E409CCCDF5CB1378B906C3BA731355D57CAD41F6148F7A706F850E99E7610D2C78D45B9F699926A4E01527A1A49886BA5FD25CA21C325E21034246C45785127F4859C0A67CC7B76259410B2F408F4E1569C73C54A4DA92A40476402573A2973963406290549F4A41A2226131251C5D59D85E1D5123D527576F7C794842974D884E79927F7BF6B09B752CBBFC442934BA461429A3EA921ABA995EF12C21116CFE66B132402BDAF690ED95483AEC9785E6989E934E7858BD13498F4E994619EA9CD55A9504E40B4D0CCBE8F8CCA1F72DBF74CAA3975595623C12F22C120C022B59B2CF3748B17199C44CD37F8EA61BA5D8C1BBE50789CE915DF9FCE1B4CF3C5ACD7CE52DFDA0237F5F24FCA5A18F8F98C916C3E3304D2669330C1042829573E197597D7294729B5A50627688A4CB3E37CC0FEF22162DDBD848E5AA641731F8E60B4B79C93F", + "ek" : "5B965A85E06BE9C1A93CB91DF85890C111E9547BD8C2D7D2F87582FECE3AA0C2FFD8236C32DAA98811FE208E92A3001C21FB5026A53EB9B7C96D42A7EAF39AA4381CC3B1FEFF2110910858D8466DFDD749C73C561B7C738E4FF2AFF3E54FF66BC3DCF99931E23D969061D871A04B55BB8BA78512F386529EBF91C2A900F60C4D5373D2B5C8E16F3D64C5EA2DCED6ADD4E1DC99C3594A16323193D14F356B33D24B4428D6DF508623C1EA83E4E7E31098FB22C9090BE61E494DAC7094A7AC9D55F7B00788B519E20AF431C2F3A2C38CB0C0BAF1C5B5F11046FC1853000C229202EA21A8F09B3F9DC935F77990DB1469581F994B630953523C24A04E8E145A436C1ABE352A982E9469DF5D623E1526D98C06016570D836A27C4D710EE00989F21F193D982693B79DE5643E5E96448F32BA3605B4A1B9FEB80BDDCB09D9EF0E544EA405CAC01EB201B2C1A2EC8F0B1EE4185BE779D707628EC1D392AF4412EB442FB10988535623B0A5A0C8CF71F2CD404719F903BC593959892F3E00B3C76EDF3B8192AAF816B3208969F64C02B02B646946F774F6B8055DBA772F5A6D28DA016FF0331D696ACABB073ADE66E08E1B97F2CE2C044934B960C9A77280821B287E2EDC625D546F56E576F2726806034213035D4084707B1EBB6F5E4B2A47A6239C916374097E30BBC1ED8BC18788364561D6321D53BA66D891442FFB09766AEAE22CEA7F6AA135268509CCC173586FBADF226DEE8496CC4F31729848C3D25A4F20152AAAE57AC1E29A7CA927FA82484A12093A9E56D561269905C91937C8A988A709155ADAD65D148544D5B9828FEA5C51AB93D89F3230CEF9647E05C9B090F2DA511C8424574FEB286280DCC217F3D1E5376A114AB1FFCB35F38D81DF0C6897E4530507E4C84B6EE058E1D7206C81255777BDFC55D8D38C438E074ED90FA11032A730AE54CA700FE832BA58DC115775784461358C34D1A9FD931D7BE468B872FED9A2F3BA908CDFD7B7ABAD7499A0C6817F3FEDB81C64723B3B0CAE51D80D0D09C07F967B7B9D2A13D5FEA1DE580B1721A71BAB09261FF8C5C1D0E233F688AC8010B76CA2D71FEDF15A0C6EDA94B62EFE3FFA124F7DE31AE04C759CF3083064CAB8378598E72635A3A576A6E8BFD61016234CAC2BA6558F2B93312ED721957C47668D0E95C7C558518FE58D69185EAF772F2B63558108F5891E0955FA23B104207AE877115451F8AE6424E3A6CB84AE655B460068C7FE9EEA10B9BC65A1164185E1CC0E31692CD614E77EF2CBA5B590453966A6A4503190043637303E59EB89C8CF6C2B223FAD10B06766EF8B0CD22F22CF62182D76E08C37BA6643407E650756C688ACE0E50800F1D90B7717F7AD6737A668F2D5A2B2B516A08836D779BD7FA3CDFECE40D72DE3FD24603CCEC3B54077E95AC99EBCD27A2EFFD8CE63069040003AC7ED9E91E1405E33E853BDD0BBF9A328E081989CC39B836A9A85B75992F8DCD877A8218467D61C5EF36ED38F2EE04C29735C84C264462128A4193E60CDFFB588E27B0D2BD583BED2514919C3DC1B6983B831E00D681A5C0DFC04270AF024B9FE480DEE16A075CAC3FDEFD0874D28CDFB14BDA82D92102B29C993559AD52FF891A3BC8B3AFC7137AF4B0131DE3CE86BF1422D8A871A32EBC9B5DE2CDA761D6D02D65670EA8CD9A57E3CD0312C5E3711C8EE6147B84CE4150C7F33EBCF4713A706DA47232E156AA4B83C0A35955977E61B292C2411989410A0AD36DCF6F597FC2ED363071A17A2FF176F84BFD5DE80DB7F5B10EC0AEBCB02B6BDF70ADB0877CA163C6F79EFB4D13FABC8038CFA1A0F06571E47963BD5910EA08639A87DB0EBF729058EB5778400A620961C75F7E2CB12CE0EFDF8DDF7211966EDE6E49C6AC0239C6D87AC7F7A53CB9F206BBE6F74F6AB0FC6E815E8B2BA8B5DE750972F007777A3957A785F7F0A860E7CEE1CFA53B7AC96C2DCFDDCC77C1A2C6CEFD20E60FF2FEECDC42A482587422B8AA265573E055082617D381C85D52314B6C89E12D674C559A5F6748AFC1AEA6F63AA845084EFF2719EA6A46CABAA8C8267625497ADD27F15C67455B4770D8243811344360A76E9E84C29ED09C1610D08967FD1560B33399A1B2F9A633B6A7A95EEE6808E35F8F4D7A72C41724CAE9F3AAC9906A3D8AF1759BA303C765106017EB90011050599D09DE78A3D2562B5FB520DCA1C437390AE8E", + "k" : "189F81A485D6916CA8091FD9A28D683C70EA5558AC067ED814BD5496CC4EC454", +}, +{ + "rngSeed" : "AEFB28FDD34E0AB403A703B535296E3A545CA479C1D8148E2D501B3C8DD8B1034BD986F13F1A7B4671BE769359FD2AAB", + "pk" : "07F76C0D2245FE775FC5CB525824BF945B31BDBC0A86B88D8827AE7FC0A3DB8BB9F534A21792637765081C4669832BB66485133F61BC22C55F03B109882B9AD7E75FBF12519873A18D9472087A6FB375244B313F6A81B608D88B0F79147282C9C37084B00138E8BC8CB3BBBD2BF9C5F95766040617962651F0556756BB9121A6BF09A515C6836B650C44E9DB72CEF47E08079945B8CF19D8BB25641186A8C8999103898492A904C5A7F2BEFC1614B4482931989FF7FC83AB40781CE54FB51866706CB04EC2C1C8813E963C70B0F15567B41FFDDA8D02A94D00D1348911BE52163F5C44188B6214856763A409040E8480C0F263D966A99BA7C7D5724F225AB99327A962D1497E9B265BD819C2959B1CD7995D138B4D71804FB122730B6133713D68C95D861A3C567C803ADC403CC911186327E1726E2881BC9B4B1873091637C5532951C0C01A0999E7740FA77C1C1C847FEB3DCD387BA3974E1AD0310F889D05E3508F02443491261C367C94E074009103E8BCCF25520C4546C4BCCA7AAD34AAC89892524219BA9B715C470C72C6C67811764926335F722C03B85C509105D6F43F65EA9908D4C61F7947CF70C4ECC08DA31AAA6AC1887BD388720CB36E10521DD88D7B2A483FC5833F8694BE9892BBF8BB19B6CEB08A133F037371F287956821014B58C6EB9351946303A3B7FA920E32A471F26A18A0B939FF137927C2A79C27A991040FA0D29B5A89124DE37FCED8109FF634F6313551140A873A6B76245A2538AEBA7A234845CB4EF0C9707A4C56F8BAEE1329864591D09745FEC24B1B392F86C47C38A62B613A8E6DC022ECF58D7D81C0F1E11A27296290BA0CB5BC04516A50FD1361C248CE450B54698C28A59274204427C53C68B5F73C739A62F9D57FFBD17F18C06994F0CC58F0979646A7273B9F0D3493DB0A23DF085524845418695EDD526AF36AC6B0B4C3346A2F61317AC8E93CF54351E12A752183C7ADAC04C3A943C463599ADB1F4DD18A69D6A933A14447B73C2502374682C8209706CABBA3A2C27B2A108FFA23A6B9732F5BD14FF2EC25E9A384A8BC83855C043A372687972112050901F12B9C0BA8AE7676B1446CFB376B1DDB89AF260007ABB736B5B223044E73DAB7B3566C7E361C5EAA54978A6F3F72C31BF499C0854E272005EC603D3A50426B24A35721C0F1613D55E68E92682217401B9A21AF9296989E75588143495907CAE38C231C7521197258ECC60BF0409E4729CE5BD436749343A449A9450C5B2AF817DB83210F9738C0029BA26835C73C4A2B85255B42AF98703D1D47106E2B3BF3F6C90C1B0C88E40F13E18F4870AA42555C08E00AAD7760321C6FA8151768930CD7C12D1B6149FB679D35E981319B566108B56B98CF1EFB9ECB9A3EFBB6AC471C6F0F207569EB2022EA0FB0048207E96A7DC805D0D07DE1541531848D670817463BBED673B5071227665A157BDB5509EB09873A00B8C98C48A3C131E029576B76F49B7D0152BCEB0BB499AC6BECE46F54F16B5D7414C8BC27DFDC9948077C090304ACD20A4955B350F22253576780696AFF4998DAAB028632CE4B3A372FCA46B0BB33F23A52A93C31DCBBA882A925C9C6C0C4546AC152A0EAC489E9B27CE9C89AEAB652920690B6B9944FC6B807D896CCE9BF0A0908F05322E184BB7C5B2A4D7459EA75BC700424F884925A2A83CC95241E7701944CCD53271F8B1992AFAC3BD3F63AF3228E9B84A5D1A9483D5502DAC28F992531ECE7CCEC18B14BAC48F1F62039861E90CB8EC0681D059788ED147D1E10115AAAB25B6B41A66A5E1388557AD56EEEE6571EF418A5F0B797352CC013A1176C3B131B499008319C121185A976C5831BD3258B7BD7B3852AA12FB77E9DB085389C0A9E1033EB224835D4793C8603296C965BBC699F87B328DB504B335FE83010432A4EF2A0B0A4300E29309E3370660F9B21BBD79382970DBF4750B3E142D5F7C381030901E7C09218636FEB3062D43EC75A7FF9A640005C1F08669C50D6A41FA86790F2BB41E7CDB401C06C3C035FB812AE2013604422A7E3C1E6AA437AC4261F7834FA95BE9E71001B65BD2E0417164142F2BC80366A8E5E1ACE65108771B321DA81100397A117F00515B6A2C934599416CAD1D5091BD23708E45EB6F90A2FB5C47C8C77D6E395A6332A45F4178B0959466F648EC5C43422397D4E771F902DB7B8D876A028F1708E233D", + "sk" : "617C1296D2BB9802655166CB0C2074C206CE03FC18F252CA7F7A66D3E619ACD48697B3A5D9845F8CBA2FE98654B56CBA727786AE19C961E447C07AB7B9D30A64C85659429FDCA3A01823C30A8335014A2472898D963A3407980A63C6BDF5AA79BF2AA7DA370F03B593CA91C77F998AD93917711B7639E448A2036B86489489BC41A25404F77B0436B7810B38A3B729472B26BB47C70337D575ED265C22B86D46A8C7F1C668E56A66F3D65223F0BFE60B472A90A463881ED587313A45A675B9AAAA7A618DA1165D143EA764C0EABA20CE244F8E3ACB79C9BE141B73D8D00BB6DB5D27E30C2ED5189C31406F154560D7832CEA31D40533A45B1811216951099F59896D25E1C1E898BA033AA6107B703CC7CD357B0D60118FEC352B5DF527FC0245F7A44FDB649C01B1B9E410B8990C689758AA606C1BA559075E2C3068E865CD835ACEB37A78268E8EEC1E1C93A619ABC71C3305E6DB35B58791E8D00FEBCA9D3ED37B62A818D2A12A66D591420CB38896248A5792D2716C63C6949B804CE27768AC78A974E42BE1437CF170464610223F9812908C29FB748EA9E253D3D8242320B4B0125BB094C7A2F635EEA0AD60ABB710F85150D797502617FD4341FBD58835B48412309330D3859E1140BA2443F6970B96C154D5B9429FB1A41EE6A30E4C4B919642FBD288629C68301C363599738A5571DEB84358C571311737C01101E00C490D918260D7172EFBCBA6B8544D96A384101BE6F64E946012CFC91125236B8A54781C4AB58DAC60F737021C5B6E45B0B4FCBCCB224BC7CB1B551AC35FD99A5F9C0CBDFFD64D43FB3588F177489A02340B19FA12B2F3BA61F6D53A7A0CC1E186BFF1A49CF22C500537933364A7FE257A5519C133ABA7AB7648E2F7C6869B6531723CD03673AFA10EB8B30ADA830D53A4C7099695E8F4242454382E752B86FBC8BD361C058986D80699E60039437066DB9172A6D8B3274A6369402C12A885A5E5136AB8B10AB8C7D3361EACB7627F16CC411BC7E2B3403D6B5F53B31F6A6657C2464EACFB796AFB6A172A201026B3834BC70FECA013FA036B5611F6F81013EC66017A4B1EA043F52C02EF0B55F05B6F65783A4DD6641496988E3A84364352967CA26302168EA81405929A4C72C30AA14F83016692413399630B582078FA6574DCBB29F17C5B85E3134E8C2DB35C73B4683ABD8B7DDF666AC1501B56D855081054B3085144A57F74246464BBC226C8605F71BD620562C044B9A6E656E7640549147819E124AFE991FA28B049B388D150A313829144262234F46779264DDAE5725469755A3594CC42CF29469B8A35016D170323601131B72304378A66F41DC0E43792915F5F35B338822CA6C7C9E6273F6FF36FC022522732514BBABBACE610B9D952043C8D9AC98E89743FAF9B2DCDBBB10AEB07C636001060A165D41309B46FD7D32C5F05C138D33CD06C3F316117FF90831AA5B6E0E054D49761EF3B2C6771B0F6F7124E5B8CE0814104500E704C84202B02DEB0B78C17883CE72444850E608620C97290AF3572F2681460F08E1FDA10129806F6431317DAA1E091889B7573C9100D16CCA12B77A27706A34C5775BD494F13EB59002847D13163E777886501A497A7BAC4CA9166B1C2ED27249CF11F135876B4C50C2FEBBACE470505202A8FE10223B9374C6520AD4075DC30B0C4D06ED30877BEABB108A6659078B7BD56C9C3D6A83F1B4380019CDA1C5C6519145D515DD521449B717A98335EFEDB5E301A9D72467B4B458089D4242620697E27887D5B88B8259D0564CA792A3395649D4F458100E14F09400E8BBB77D64BAB25407C95BC792115BD88E767B3D7C7EAFCA87DBB27E7C1989E74817B723F348A0A4D3B2B3506CC150934F6F50BCB676B756B1B1A401822C853B986B00599C61A269DC8A1B54227963FC7A7608952E984B90E10A9A81172B2577C7FD9AD3CE4B319FA0611F46706EA596AF024831248EE19258C4B0D9928AAE5208C4F3621C7696ADB95A7CD91C39157CC4AB735CAD892768850493B4509564DDEF09EAF84C6F86638A1667DAD3B2076CB93FB538D02A5C36E28240C367BA19717FA695DBA621359F85C05E740BFC2BA1C146DFED60A88785179373EC49680999AA616E7753D3ABCEB4A2CED2A60C0B00BB3A90B2BE5CAC300B107F76C0D2245FE775FC5CB525824BF945B31BDBC0A86B88D8827AE7FC0A3DB8BB9F534A21792637765081C4669832BB66485133F61BC22C55F03B109882B9AD7E75FBF12519873A18D9472087A6FB375244B313F6A81B608D88B0F79147282C9C37084B00138E8BC8CB3BBBD2BF9C5F95766040617962651F0556756BB9121A6BF09A515C6836B650C44E9DB72CEF47E08079945B8CF19D8BB25641186A8C8999103898492A904C5A7F2BEFC1614B4482931989FF7FC83AB40781CE54FB51866706CB04EC2C1C8813E963C70B0F15567B41FFDDA8D02A94D00D1348911BE52163F5C44188B6214856763A409040E8480C0F263D966A99BA7C7D5724F225AB99327A962D1497E9B265BD819C2959B1CD7995D138B4D71804FB122730B6133713D68C95D861A3C567C803ADC403CC911186327E1726E2881BC9B4B1873091637C5532951C0C01A0999E7740FA77C1C1C847FEB3DCD387BA3974E1AD0310F889D05E3508F02443491261C367C94E074009103E8BCCF25520C4546C4BCCA7AAD34AAC89892524219BA9B715C470C72C6C67811764926335F722C03B85C509105D6F43F65EA9908D4C61F7947CF70C4ECC08DA31AAA6AC1887BD388720CB36E10521DD88D7B2A483FC5833F8694BE9892BBF8BB19B6CEB08A133F037371F287956821014B58C6EB9351946303A3B7FA920E32A471F26A18A0B939FF137927C2A79C27A991040FA0D29B5A89124DE37FCED8109FF634F6313551140A873A6B76245A2538AEBA7A234845CB4EF0C9707A4C56F8BAEE1329864591D09745FEC24B1B392F86C47C38A62B613A8E6DC022ECF58D7D81C0F1E11A27296290BA0CB5BC04516A50FD1361C248CE450B54698C28A59274204427C53C68B5F73C739A62F9D57FFBD17F18C06994F0CC58F0979646A7273B9F0D3493DB0A23DF085524845418695EDD526AF36AC6B0B4C3346A2F61317AC8E93CF54351E12A752183C7ADAC04C3A943C463599ADB1F4DD18A69D6A933A14447B73C2502374682C8209706CABBA3A2C27B2A108FFA23A6B9732F5BD14FF2EC25E9A384A8BC83855C043A372687972112050901F12B9C0BA8AE7676B1446CFB376B1DDB89AF260007ABB736B5B223044E73DAB7B3566C7E361C5EAA54978A6F3F72C31BF499C0854E272005EC603D3A50426B24A35721C0F1613D55E68E92682217401B9A21AF9296989E75588143495907CAE38C231C7521197258ECC60BF0409E4729CE5BD436749343A449A9450C5B2AF817DB83210F9738C0029BA26835C73C4A2B85255B42AF98703D1D47106E2B3BF3F6C90C1B0C88E40F13E18F4870AA42555C08E00AAD7760321C6FA8151768930CD7C12D1B6149FB679D35E981319B566108B56B98CF1EFB9ECB9A3EFBB6AC471C6F0F207569EB2022EA0FB0048207E96A7DC805D0D07DE1541531848D670817463BBED673B5071227665A157BDB5509EB09873A00B8C98C48A3C131E029576B76F49B7D0152BCEB0BB499AC6BECE46F54F16B5D7414C8BC27DFDC9948077C090304ACD20A4955B350F22253576780696AFF4998DAAB028632CE4B3A372FCA46B0BB33F23A52A93C31DCBBA882A925C9C6C0C4546AC152A0EAC489E9B27CE9C89AEAB652920690B6B9944FC6B807D896CCE9BF0A0908F05322E184BB7C5B2A4D7459EA75BC700424F884925A2A83CC95241E7701944CCD53271F8B1992AFAC3BD3F63AF3228E9B84A5D1A9483D5502DAC28F992531ECE7CCEC18B14BAC48F1F62039861E90CB8EC0681D059788ED147D1E10115AAAB25B6B41A66A5E1388557AD56EEEE6571EF418A5F0B797352CC013A1176C3B131B499008319C121185A976C5831BD3258B7BD7B3852AA12FB77E9DB085389C0A9E1033EB224835D4793C8603296C965BBC699F87B328DB504B335FE83010432A4EF2A0B0A4300E29309E3370660F9B21BBD79382970DBF4750B3E142D5F7C381030901E7C09218636FEB3062D43EC75A7FF9A640005C1F08669C50D6A41FA86790F2BB41E7CDB401C06C3C035FB812AE2013604422A7E3C1E6AA437AC4261F7834FA95BE9E71001B65BD2E0417164142F2BC80366A8E5E1ACE65108771B321DA81100397A117F00515B6A2C934599416CAD1D5091BD23708E45EB6F90A2FB5C47C8C77D6E395A6332A45F4178B0959466F648EC5C43422397D4E771F902DB7B8D876A028F1708E233DC266D76C52B2A849F00690FFB252699D5B3E9F66E0ABD3C1362C39CEDBC698500472C3D61E4CAE91B22D2F5A316794C723FBCF7546DB47A42A15F1450CA3282D", + "ek" : "DE8E8D0C9CDF3896636E6DA211C53E865C6491240D87128A896CA87D283BE6D8CC97278D6D26FA7AFE185635882226FD187CA3CA1863C951C985D54152B75A6A6AE6938DBF8DB3768AF8EEEDE5B6FD2C23FDA742F6909E48E9E4997CB0438E4B7B8AE56AF3324DC230BF167DEE380E635EB1E833AA2DC3CB68C5A826C3448EB170F4EE02D210CEB3E5C861CC45E5275D31FFB9E1D90A1D03A1A167677155E97B6DBCD642D46A30A1F5E45A75EF86F7FC0F184788325DA02E81E3F9AA65787A6B0CEA4C0EC3223F50E6DE76F78B5428D89E9E77C74E59B105071893460BB2548B7540460B078E2F76DE64D2926CD3A888DD1F28642D221573956D03C6CFE839F16D0DBDF282760CE8C1603D54E728BC76A4E8460BFD44ABFF73E9E0FCD292BCFFA8AE2C141AE23CA5F1E1F54EB0289EBB26A2F23C132361CFC742BE127584195E90A58A5A46145A4ED02953AFE8D08ABC5619CAD1874B8772CC44FA9958102F7205E3F8556AEF93D45BB7DABFF396ECD578E4049B75B85C95B785745C0BFACBE0225E8E79C1B018FA742515B8562C6636D55604483003CC5D72BFC62D7658CC6B0B63A568FB33BC6FD274A522F9AD643502337BF8717F87D353CB585F692C14C11E3DF2FFE964B2ACEF720BD533A7057C935DEB08618579B9C58877F1EFFF50BFDEF1DCDCD550FA06D3A634467F10FF23B0BB30FE30B1FA9455235EDC0F5276D3238DE1B8A86E94C2CF3D3B5BD2081D5E35DA039B525B99B46ABFEB4DAA76F37F8F354D597F741565C73FF221B04345C268107B3C3C88DC1E1B4D573A2C36C30C11043464CBED0FE14DA85F801078D74E08D1920BB6FBE583B42B2835C48C39974B32B02B2696954D0C825CE38B83D5F0EA888790F5A0173A7EB485D3B9977E2A8D04C9B80AA2B3A0F37CD0A01F04A66C5471D9EA3C8FF8D0985EDEA17F669975E563404A74E51D86B6852FB552EE8D6F6EFED6404FCC753747FCC1F07CF6630E9BF574383F229270105D0828B5BC55F3E8AB47D86C1BAC1E2D64A12877D28AE8322258AA89B80BEA11CB06378542A1BE10E764992D7926ED28E60F486F6DADD62C0BFD639EFE2EFF8F1E3F1BC6D1F2CAA2C1A4988BD162D926B9084607784FE71FBECFB538782D1FA51638D7268BADD790CE9AA763BA44719BF278D1D978A426AB53B6A4BED54E2BF7D879358D97B3F5C7574D3A5ACC65760BFC906D88E4CA15FE0F195230E3ADA233F819DD8F9EEDDB1E51D175FD13E2DA79DA2FA0B7F6BBC46FF689D73E073D2722A2217474B9ECF42A73C929F66B38F415B33C74167F26E410B9B085B323231B7B1F9748D0F2F149CBBD3836F793D1E31FB7AE99A93052A1B01B73AF1C57C8AB3B63BBE621FB7674B9B555F78AEEAD0D9681F40AAEBDD5B934A9F4E0C7D802638FA180BF19CCF00BE01852A7AE6930789D5A3438D36B7C0213DEB965C84681107681DA5E1F58C9BBA23A34788F34C69392B0A31D0257E83680C296EF5BC627EDBF1EC75A90189481C067B759037FFE9F59A2E721418C6BB221FF5116452DE246760FEB422C732663FD0CA95EB03693B908835C01BB77A9F17E6786C60BAF7391D55D6EAB443EBC8C8172AC25A483084CD43D8BAF154F4302E28D7FCB8C38D15F2FFB6402F31D15C2D4A711773841A2D4FFAA439EA130F8A191152348303EB2B6CA49628E688CA4FDC28CE254E7FB8BB3C9A747AAE2DC0EF203BDEDFEA30B5735C5163EE7C62E921F7A26D52726A99C5F4108AF7DF293A1FB044779A80243DAC93686EDED0239DCE03C8623D66AED7D1C5A5A27F8B0585070777883B90E134923A7239E4DBAB1AFD4C2AABF55261BFD3D6B5B6F28B32C626519E1695660DD27A97B6E578748ED76DA02F5509912C4FFB329C6FC25E372CF398D0C74B02CF2FA3F36536C0E243BA6449CB5B6F3D9B509014647F66CB8386BFE087C19554F22CA40E65438C5A54684C14BF7C7567D2D2904136FECDC7FE51A571A2FBA1314E2EE04DDA5DB5F505B24CF8B81FBF92ADE8B16E4345771119D864C38F3F59530DF52E3F4D47B08A2BB40EEB04E0D8041DF3B8F8D7EF0B1EE232F73854DE6B2EE84F0BD5B819BB7DDFB9F0A08052995A5EE675ED7A91B9620528B0BB0F7B602EFFA4BFCF42756BFBA104CFEC16D4D0A5D180A2C10359EA863B95DD4763F191A242555275537205C8A193F6DCFF2FEFD3AE90712227B006278717BE1", + "k" : "5E7680EA71006A3CD175700B9654589F535F60AA7FECA64474C1173380D249A2", +}, +{ + "rngSeed" : "CBE5161E8DE02DDA7DE204AEB0FBB4CA81344BA8C30FE357A4664E5D2988A03B64184D7DC69F8D367550E5FEA0876D41", + "pk" : "E4F12B6F27CC55032582857549F3BA0D6BAFEEE47CA2E2CEE04B023B066F53F75A5DFAA0ACA416ED16CABDB510564738AA08134346757F92585AC112C25A6E0723958B7B23BED41A126617B4DC30DE275BCE903A1C6C2A28C5C58C49A5F0C447FB0C86F5B6A6E9D271383588EC398FE6928F04B67EAD2633EE174564CB2115A55D8A53971E0C9FE2A209F9C8745467BB8D9944E6C1BBC8A54A5D28CF82E8815A3615DEC5695D00C0E72B2F7C483F72D36D2F091CD169311A283A42D608D0D66E020172A6A799A66C10AA9B93A9DC5CAEFC805CD77D567390BF017693DB8B33392BCF96011DC88287375BEE828341E5A515A97C019895C8E68D41C0675723AF42B6A50DA91D04C9880D21A5AF9929362411F5B36C75199211DA655F454539AA399EC276AF29011FC2B5E7F5534461220EC3AD3869178109A282E8A960B6119D0A4CE801D05150C636D20D70DBB092999BD2AB9597A0B1DE56086C27CA8F5C22B86995E5AAA9F6514323A31750EB794ADC1EA1247317F82EB443604FF254E99A895436060291AFCCAAA1FA26B20FBB9F48E462851513F7707A5C3461E3F4B3B4E72BA3089C53FB85B9C0576C06B2DC832FAFB929C3B34DE6974021378356FBC4E1282884D062B831B9ADAC1EECE03F5BE7C9C7E8B69B1A7A79304842231F0BA1107079416B388A074CCDDAE26B4D22693F95A8BBCB2F3445CCF74ABB702428FD3A04BEA9CE55B6C251C57B6FF10232A6A85832530835883336A10992CD30144B757AB6A6377389E36093E218BD09CCA1504400A7A473E248CCD40567637183CCBAB9BB2DDE7198ABF35DF8F8C836E1BFE061448B133898FA6CE3ABC79BEB4AC8D9997C12588C908AA1002B2570A64654C8BB3C1914583748B95D13F9619659AB4C8687F872030DF926EE04B6A74047B995625B1A9A929A7FAD134F989C7CAC25C42817BD9F45327725474A629DF0944F5FD3BF06057355F2843E8157115361CD627EE6D548230A89AD49BF1B156E50CBA74FC19A63EA2E01796B6EF4A37D4212897346DA865F5C36CC49A6954A8A868AE195BC4625300716D3B3692E683A10D9192E2AC5D096C465126730A9B72BB3A729A7CF39922674E39900DBBF91B2785E301AD8A3843F875361B5C4EE0953AE34A583B36D0F54CC194800BE6B0A6465479C51999D5029FF50117D5498E8C6A0C81BBDFC6C220B21A310993FD5E7691834732E358FAACA460FA26AD20044DBB7177C47736C412BC9011F09A0BA4D22AEFB485A524BBB8F74BDDCF78358C8ADDEC550B86895FC3141682C0C323210ED756864910C9446C7D9983CFA98CE9EDC644967CC93B7008E3C9166CCBFFAD008CCA6569AE913E7327C26032744758F2E82A70F8A399AC72657995EF2754E3184C263AB93CED1510BBA1D0838A13AA2CB9D7A25C236A37EC37FC5C0093BB47DACE9944D077F5C837D78C54E3FB1CB0E8A70C4A18B6E8B95F6B7BE2B79B802055AD4EA5FEBE770C39757AC42A09FEAC48B6174BEE79621BB3AF7D0A0094895CC8B6AACF722EEB76ABF6B6F0D66BDC545C68C845B22CB167F96A0448B0CF812C46793A28B55A600A1431374B570C93D6DD7B4F789101E578E29D96B2384A8E09115F9E1C8DD008D0047926C17285DD996690B4EE9957CDE5BA56451BC2DE46371738E65744FBBB558537B33581998DD0525EBB9C17D9777A701A676956A03BB4911070D83B603F5169F66838CB671627B899E9706BE9460CCBDA50135D504E2709AC31C48C4FA67EAA740BCBA4173EC25FD7766BCA198FE4122FE93BE5B646B1A475C74AC276BCA3904A7C119B057DD2BBADE1701FF249F484A4BEF04392122C416AAACD5726A273066FC510F394903B5F34860206D8C45A4CC340440179694223B8EB578C5BAC2CDD183507946E3D02C0E219AE33008E19822D77ACFE5C85BFEE7A0B6AA0EADA58AD1CA5BA1E12AC92063C326AC4140250BE091B2095F568AC7B483ACAFD7045A229954B8583A33376CA7B19A948A10C4A45A5B80D403C89773B7C2C67AD1358BF2900E8A793DEE71B91C978C389B4D8C824937E921A17914C6D1A4BDD6460A2C7CAC50CBB2F006CE9C98C7A3342F9ACFE11094B249870AFC3E15800701D606471A7A0DFCC073C277BB74706E5571F81CAE7331A7D1E36DFB437D7D52957526BDA146BFA3530DFC93063FECB103CE58C30ABB5BB70C6DBC92E5F3BF4060", + "sk" : "DE8539327C009F37124D009DC3D112BE749B80E86CE81A4EDCC802E757AEEEB0BCA029441DD2193C568063599DC8D87209775224A792FA020EAA02AAAEB0C444336D94D38A1A156DDD4014070C197E527D33BA3A40B496C8FB19F61353CA32AD986664CDE663862534A7351CEEA4779FEC825F8CA93AEA7F23883548989F23F77A25F99BA847B427D319145CC8E32656E83B6295F50A015263C75CA8778650624AB7409C0F45964A8CF466D2FC95417807A481A1D2062629B17DF583B254124342316153FB5D45F67BBA6024F6180252B6B54662CB2AD793704C51FDE4BCC758314DEC86E6751ECD6A0324AA123109C38D356B0DFC9676C087BD7C945871A33E46C0924B8E8E1B6777F530615A5E3A71C95CA532C8255E8EB6AFA1B0570BE3B80FD1974B170C3CF30559D998E0684F92FB1BD4FA79B5BB5AFF34443C0C1A5423C42833B9753B1F98E46A024CB1D3074B00F101802B105A89B95B306A7D546F1D357CCE202A71043AC2859265CB768A29CEA051810A08965C773546768C09A66AA76710ED954269070FC886A30EB42E33C4CD7CA650CFF5ABA39B7B0AD62311B92139805E89DCB14507C0DBAA6DED775BD1107FA1E1C5D2A61BA9D732DF58B8845B4965D001F78066261794311701330B238483BF61780F7A4082881AA316892F5CAB105B5519AD111BC7E32FA5F23F98202CCCF67D825826CFC50A6DB58C15E12A6D84C185B469B0F94022550EB72A4332D4377DC356A5B34135D1593117651A5C0F0C87580B392B8643386167119F4651B7A433D7104F9A216486AB6A6E0208ED6B75B93989797472391C3464054EAA91558E1B570BB2116EC964EEAABB650896BC296C93A090BBE1C79A320F4E94A2A27122FA8C422A0A4D318C62CC840EA2379CCDA0A4FC71C1FD7759133520B8BA0037F688F2A3057FAC7FC5E6B3D3B1652C2567B092B7ADD6A542C182C579A366D620C2F40E59A13983609DF8D2C6A7301E0566323F00132EC9A3CE800892304DDF74411D3932C27089DC987E8A3755FB010629887E0E518ACCA18110EBB53A48980091AB4C156185C8965ACC1D16D702EFC301FA88A20C5B4FDB24A25E0A6822C9CD9D6B7A095C2E14B027EE38319FC0827C5C393FB6C3EEE59CF315031E5BAEB6B08753C7AA0CC7CF8ABB926298C444352B50D12E7F2474AA065EB6C16B1B660F3A1A80DD36151C8B40BB265CBAFC87C526B89B860DE3513770110402734FC2A3568AAB6E751233F5DA9A7F846F5E4C7D318595F1989D557312D791261E642FC93B23E6378D61FA036CD11F0E3723E7790551D010CBA70ACF913ACBA674393B06DE7AA856953F10AB2EC7F182996695D4BBACC5457B904B7DF2FCC73BDB62C047B3C7377E5C41B247FA1F562C57D4A09C6B9710C7675E267263CD06781A5B63A58C36C94317509540A81063CF97AF65249EB6648290E10C627B1029FB593A05CB575C3F63F280D367CFFD0C9A8443836235B90201C5A8C53380B4B3C669936F965337ACC72C05AC5B441FD8DAB2BA5259E38C9B87C98BCD9646AA397961A160C7718808C414DDB05742189EC4730FEB020D92F84296DBB97A453F7F4B09C965A6652894E92350F097B184A1BCCB0728ED70C0DA600B3E3B1C6CF0790135A329B6B3C86C748AE6840EF581939C81CCEC3848F15821643E4A41CD9B48B1E0979A964C858DE00C67970BA281A4D70678D61A0B6E5B93CF7B5297C6219C1733670407D8272491D137BFCCAB4709984ABA8A3842415EC337E6EB5E22B4855AAB21BB394C470881BEC25F21238BCE98CAA9A44E06277870A74426BB927B46CB63F10D116BC94232C566406B79C1199CD16DBEDAAD1404AE4F98BA38B58D6F6B7B46FA21247B0D93D58B0081C5473AA14C7964D56496739214033C34528A8B51D0857AD3B18699CF7A025E84D91788D906E70C011CDB3B291019E2225696A2C61D0787FE445B6E36C64231288F3854E52AABD1295CBA072ADF5B756AA19C9B079084C204EA1BC7B65A34A2E8894FCBCA16B42DDF415B40B73D5BB36AD2714B233C899FD42040502A9AC208C031885791323A9B706A35CBB9F935DE1633D1B6B877D5C402E92E8D06117EA4A8FB709DE91320D5AA554D77A945B30C127031030858C066556C957FA8813BF9F4BEA15257905A4DE4F12B6F27CC55032582857549F3BA0D6BAFEEE47CA2E2CEE04B023B066F53F75A5DFAA0ACA416ED16CABDB510564738AA08134346757F92585AC112C25A6E0723958B7B23BED41A126617B4DC30DE275BCE903A1C6C2A28C5C58C49A5F0C447FB0C86F5B6A6E9D271383588EC398FE6928F04B67EAD2633EE174564CB2115A55D8A53971E0C9FE2A209F9C8745467BB8D9944E6C1BBC8A54A5D28CF82E8815A3615DEC5695D00C0E72B2F7C483F72D36D2F091CD169311A283A42D608D0D66E020172A6A799A66C10AA9B93A9DC5CAEFC805CD77D567390BF017693DB8B33392BCF96011DC88287375BEE828341E5A515A97C019895C8E68D41C0675723AF42B6A50DA91D04C9880D21A5AF9929362411F5B36C75199211DA655F454539AA399EC276AF29011FC2B5E7F5534461220EC3AD3869178109A282E8A960B6119D0A4CE801D05150C636D20D70DBB092999BD2AB9597A0B1DE56086C27CA8F5C22B86995E5AAA9F6514323A31750EB794ADC1EA1247317F82EB443604FF254E99A895436060291AFCCAAA1FA26B20FBB9F48E462851513F7707A5C3461E3F4B3B4E72BA3089C53FB85B9C0576C06B2DC832FAFB929C3B34DE6974021378356FBC4E1282884D062B831B9ADAC1EECE03F5BE7C9C7E8B69B1A7A79304842231F0BA1107079416B388A074CCDDAE26B4D22693F95A8BBCB2F3445CCF74ABB702428FD3A04BEA9CE55B6C251C57B6FF10232A6A85832530835883336A10992CD30144B757AB6A6377389E36093E218BD09CCA1504400A7A473E248CCD40567637183CCBAB9BB2DDE7198ABF35DF8F8C836E1BFE061448B133898FA6CE3ABC79BEB4AC8D9997C12588C908AA1002B2570A64654C8BB3C1914583748B95D13F9619659AB4C8687F872030DF926EE04B6A74047B995625B1A9A929A7FAD134F989C7CAC25C42817BD9F45327725474A629DF0944F5FD3BF06057355F2843E8157115361CD627EE6D548230A89AD49BF1B156E50CBA74FC19A63EA2E01796B6EF4A37D4212897346DA865F5C36CC49A6954A8A868AE195BC4625300716D3B3692E683A10D9192E2AC5D096C465126730A9B72BB3A729A7CF39922674E39900DBBF91B2785E301AD8A3843F875361B5C4EE0953AE34A583B36D0F54CC194800BE6B0A6465479C51999D5029FF50117D5498E8C6A0C81BBDFC6C220B21A310993FD5E7691834732E358FAACA460FA26AD20044DBB7177C47736C412BC9011F09A0BA4D22AEFB485A524BBB8F74BDDCF78358C8ADDEC550B86895FC3141682C0C323210ED756864910C9446C7D9983CFA98CE9EDC644967CC93B7008E3C9166CCBFFAD008CCA6569AE913E7327C26032744758F2E82A70F8A399AC72657995EF2754E3184C263AB93CED1510BBA1D0838A13AA2CB9D7A25C236A37EC37FC5C0093BB47DACE9944D077F5C837D78C54E3FB1CB0E8A70C4A18B6E8B95F6B7BE2B79B802055AD4EA5FEBE770C39757AC42A09FEAC48B6174BEE79621BB3AF7D0A0094895CC8B6AACF722EEB76ABF6B6F0D66BDC545C68C845B22CB167F96A0448B0CF812C46793A28B55A600A1431374B570C93D6DD7B4F789101E578E29D96B2384A8E09115F9E1C8DD008D0047926C17285DD996690B4EE9957CDE5BA56451BC2DE46371738E65744FBBB558537B33581998DD0525EBB9C17D9777A701A676956A03BB4911070D83B603F5169F66838CB671627B899E9706BE9460CCBDA50135D504E2709AC31C48C4FA67EAA740BCBA4173EC25FD7766BCA198FE4122FE93BE5B646B1A475C74AC276BCA3904A7C119B057DD2BBADE1701FF249F484A4BEF04392122C416AAACD5726A273066FC510F394903B5F34860206D8C45A4CC340440179694223B8EB578C5BAC2CDD183507946E3D02C0E219AE33008E19822D77ACFE5C85BFEE7A0B6AA0EADA58AD1CA5BA1E12AC92063C326AC4140250BE091B2095F568AC7B483ACAFD7045A229954B8583A33376CA7B19A948A10C4A45A5B80D403C89773B7C2C67AD1358BF2900E8A793DEE71B91C978C389B4D8C824937E921A17914C6D1A4BDD6460A2C7CAC50CBB2F006CE9C98C7A3342F9ACFE11094B249870AFC3E15800701D606471A7A0DFCC073C277BB74706E5571F81CAE7331A7D1E36DFB437D7D52957526BDA146BFA3530DFC93063FECB103CE58C30ABB5BB70C6DBC92E5F3BF40602BFA2721399623D76222E93D092C34792AA8308D8999AAC7E17433DA2166292B81B292427D57FEEB160F9347348632E1CD340960F6E6EA2422D194A0109AF1DF", + "ek" : "A270F1B557AD3B05906A883B9973FECA94C710E4CFE6FDDEFAACD532BB3AA0BC2906179F2053FF70D47D2D10D9D5472FEB39360815C296CEB47AC7B292A90FDCE0B7227CE73986A840F888CB7133930BBEF34C75A8FAD67EF626271D14977700EBAC2DC52D348EB5CE10F7329908ED9A4822AC484C2351C0C85E7EF0A426C1707C098F99DB1A644A0C1BD219D885041AA63C03618FDA13B9D056AEB4E1046C89AE5945C20D742B8DB30FA2158EF4A4567E1DD54D6E46941B5014471DCE4082226ACADBD37C9746D620283D6CC91189B009950AC2D28FBD4BA694727C09CDBC01C24AFE31A3D9DB3CA9889649055905D6B36E8121E64C95975D0836D5B67449527A5979605820F7B971A49E187B561513FB5D8589B9C852674EEA711A6028D278AA8FA480C9564FE5217C61A45898F10C339EA5514BE54CAD4D00D2411BBA7525D9103087D5AEFCF768779FBA7EA19C0F29B5FCC859B846811664C1DE9A96FE002F6A55E30A99C7EE61DF42D1D4C7C524FE8A90F50F8359FFD16620E9A97210B09F7847DD4BD1D5DE8887E0508F86BB97E94DD5997ABB737B8332FBF9D887DCABA54C964B1D16FCFE8B1233C4E62DD024A5754D0BFFD2ED3ED32C216D5A27BD487B417E197B95A2BF6BCA3F981FDBA04EC74C268D422AD075E77A3F3B16F5280F92547389D2D7457B4F3D2EC83F21E47090954BC79D4D224BCB7D6DFDBB84F1C25408695F1E1DAC1D36E166BC2A151C954A534CF0AF2F599E9E689CC446B200836F4F4DF1D2BD8E1548A62B40ED7DE55E63D0D91A4683B1C1A5C7C1B413351FFD61A5E3D94562F2430B25C531CE78E70493C377433894526F9EBA45200D2EF5339226F50A669414080F92D68420C51E66ACF5F6D108A39A69F08301B743236EDEE85405F9833F429438BD5256631F8F4F3C6E3BB2B6456E35D175B5AA084BA4F61A19F033185E563BB236DAEFAAAACEE25F08A1AC13F15F4A1C000651BA8DB8570C9AB5AA184F2FE6DA97B360E3CE5722AA1E2F1CCDBD8B1D6C7AF96DD5B1CD6F896D4BC9021DCE16ACB5CF6374D0109DE6961D040FA59331F04F11680C0C85F59349496410737CB96C4524609AF315A0DDD271E7649E1FD23F3B18764D17D6A894757D0FBF4F68C96AAC1A7D1F6348920826DD521EB695B3536FE40CA220375B179C7F3CB2925DAD2847DE06EE5BCD3EA3BAEF865634CE91BB8ABBBEB21652FA1A214E9EC574C22091F9AFC3D0394924AF25D1CC03D9BD6992ABF39DD264C47B65FD0EE085067E1EF9742C5DD3360E944586806B282A2979A821320DDF3FB406FBFA6435027A5B377955CD37855E9A58772F64A0B6F61FB0708A2424BBF8E02E0C8778F649295F01E06210949C0B0C595DE624BC005250E160346DF5F8231121961F593BD30401A6E8452D199848FD0A71E64B1586BE761C88EE4D470117189C3E33170555415326A426D8F171D4DB9A48914ECE99D3D6DE3BB4C6E94BD56018667F18947BAADF7CB48465E8A110BA9475EA7E4AE6F0E84B9B936234B04F3D2816C49FCAE9EFDDD16E310E43F1BC851202DBF59B0D5A56194DEC2930FA8412F9B04415DC51BC112B47CADEDD15A1DFD24099DAE0A0BC8AB35E9CFA3B2876353D2D09770AC12CE2CAE0D00B0787139BD4BF4D53F23227478BF35A124356C6DEFAAB9CBAA9E1F583E5F7DB1F35472BA70E46874C9ADE72122669D4DB509592FB97A94EF077A90BF36E78F734B42980DCA6F2076DAC8D6BF27B9C9683C7FB7F0A535765F99F67640086C360E23D15EF575966FB46D5E911696A59A80576F573FEB102EB77514FBE8622BB45E2E0552242FC1A006363933FE370825BF05906CB72F6D0FF56B04EA480F613962A83A813DABB6FB2CB32EC5F147D2A37E3F9606189FBBA291FE73A45E085412806535F4ED8DF25D6005E747A595444281DBE8B3FB94B17D4D1CF685E3E7069340DB3206B0EC8A5164D889DB9B2BB78B0AE8E7A071BB2352E967856E57E90C271F260A20434A36749C07A54A03441E492876988417DD7215CB6DC3C29E2397689A14084BE4F2CF72560E0BB955403C03EE52A78F13A623A1D27B3C82FF60BE6099616EF4A06A7AC9AA3195F962B187CC04EF68E8AE9031EC815F14F6CFB2E0CA57FBF541D662318AFE1142FE949BC7CD3D830ACF8D69F67BDF6BE09A88B87FBBDFD173F5A3D03409D88B9C944948CCC45AFD25601F045", + "k" : "0D27C4E8B72E5BC38DB816EF2076E46C7A20567546780AD0F242206600709D6D", +}, +{ + "rngSeed" : "B4663A7A9883386A2AE4CBD93787E247BF26087E3826D1B8DBEB679E49C0BB286E114F0E9F42F61F63DEC42B4F974846", + "pk" : "1E778910B9AFED44842D78417CD027F819699AF6B0AB475A18B7359817B50C306BBA0728C5A9088E667DCB7944AF6C10BA86300308165C1242CBE8708C8347C44AB77478304EFC0A9E5328F203B90108418FD1B5B7C3B085E74CF500729E27719C2596FEAA689A54CCB3A5A4A74ACF36C652FB97AD49190CC6F08382017DB7A910F816701957CDD8449CA075B9A3C18BD88469E3F51E0C967146413BDAA15C38284A726A8935B3987E774A182023CC0ACC18A80B8B6909B52B8726881380B204CF1C069415A99556476B0218EBB4217FF33A0593BE5F3CC47EF89C13397D68933721C5A6F1241B88F452654C249D35C1A8B16305469586435C1A6156F8520AD33938C8DBA429C118154020205B0235262F233C36A89B384D82BBC49B6D6074517A631C5ED285F56585B286462872503DA5C3DF9C91340071EEC625F8B29E4C416E93B46D37F95822EC35C2897417D7181DC9A7097AA74F3A02BF1420B1A568E1D7B1A743C0D07623E2296071912F7DB25D67D751FB3B9FFA671403F29D162B635F0C7AE693578D2A752984914EB9036BCA365A76861A05075B4B2A95077B6600A42E071D60E21618A689E3F7B5C9836B7451997EF80917F6351F814E2EF1786736A703012D3C9AB9DB50B5B9F08BCE69BA50A2C48F059DDE2181F725CF39F426B39028402ACAC36BC0797C918D30A4A6D4BDEA2927CD75364D167F34DB97260039BFCCB64B0003AB3532F77353FB6A0433A5A95570C2CCBC77F0E4BEC1584CB1A88735F27ACF58120D01265CD7236F18AF3C00B4363CC372FAB07EF3A87030B19B07AF020320F1F747E32A8BD1F32E78F1A62960A43327307D8C212D1044689805BE15C1C68682D0A8A24EA51267058DC4B15F36E12104EA83E425C248209A8D193911E2A2DFE3A47F485ABB226F02919F9BBA4014262FFE6B4607BBB511FB5FCC205134F8AAE2310245B9C9E73957A2B5B4CFE0916DC1BF6FF891C645B28E63BAB6C23E5077A8C3954FB5978AD8E07DAC5C5C1FC4759912524566785DF222D04435A6A24361178D917B53AF57438B46AEEAC546BB5207C186BD196BBB6277216D95AB6E545D78E04B82669D19093241B808AEDC5DB79A9E54762074A0AED86931497917969CA7F20942EEE719287C887B3508F23B919418278BE0236043ACB3E4ABAC940C44C3AEC3AB8C78BCABD84C1D373899369B515C2478C6085CED3B08F668224F950D3B82355468BFF0534CC7660045E96CA40067DE520091437309F7030F71A250C359F0C71C2F8819B62CB39646B19D63669F679FF9F48AC7A426E3FC1A1D358B675105F28586726304ADB8109E104715B6C330F053961207EB96148A866C12C9349FB6AAFD1B42F5F80A2D827094C3B4DEF6478212332D96359FB3450CFA6BEE8327EA707B8CC61799105358521C6199607D9B769B38AD15E4B638D12D16AA90AA49CD90B9047696ACF9C14CBEE59F82B46DE5BC644402400BAA2E839AC801C70A368A3611CB11A1484DADF30185112F52421196D1797A3085F5D429D286343953BA8DE676C381AEBF394D0453BF1610905F3B6AFDD5299A750F2333B3944067D9A9CC201922F9B5162CC41CBD35400A275717228050A97D05D0C1B303BAD3405F36A1218C5C089C98467AA37905B334EDB31F667A88C2129C1749784F49B83A329275E1B5FFF4798D4B1C5779A5D433CE716BCE5763572A29CBDDF5B40B464F3E163CD5B554C5612C20726F57244735E2616F45356237263D69A1E1E03CC4D9AD57C83B3075CFAEE45418282261D8BB531B685C766989C28AE9F991415907858308A1FA027156B6D3C8C0CF926553B570FD077B6FC419D8F4556655CE53F6802D406781B06463042304477BC8EA19757BB54F2CB54B9276FDD575D5A00C267B1222D4C25DE11860DC14A1F3453423CAEF02BFE8720472C194DD234038F8AA0D3118286B530247B88A83318FDA0A9C226CBCF22510F681DB3880C2208B70F67C124437DD32AB9120894AA287C7040E06F6CDD0121EDE209068238B57716DB488335564C316111CDD90741A197646874922EC355A26A7E5BA4AF5873F974B2626B40AFBBB5C59501FCECA0C9FC76FE9B8786AD1C5C76B071B6C054AAC0EB8E0535BF8A4249A9256E4C1E8EC673FB5BCAE20063A90B601E047E9BAC3BA827ACFBA4A7E9B040776BD6F351E548EE005D759DA86C9B2971F9D6D1CAB8D", + "sk" : "7592584BA97569A4CC9C918D9DEB2312E81719FB4286D67866E9A14FA947F220692CE29D0F68A97F851E5C938DB1587180ECAE36FCBDB8EB19D96302BF38A02E0128FA562BA7A9260C873460814FF3021D511482F4F731F9A152CA42C920285003025C5AA0C77698BB5B778C1F864D696C0DD4D634421224C7D14287D625B422062310AF94C005636C8F15A486E3EA3151B5230E337AAA59235BF7968D9C7B067B8D1BD6247316047D0568AEF514F725BEFEA696EF124F10F822D45773E780226730B8AA043F80229AE2200739392A3B42C0F3833DA3B18B38C243F0A72760A917581BC6D2784CD4B796E6812FBDE666FBDA9CE9522A32242A644032F144C4904031100C12AE7A3AA52AA3EEE02F27909736A8BF9F8992079C76157001C64B08428A5ACD67762D01C4009D4EE71C3C9047751D89B0F6020FFE848BF3013A5E4C5C3DB6457C55BFC8D62F6DB63FD4AB1B51A06B43F8B7EEA0AB5987BDA78278D711AD53A6B5FE58BA81C5931C9B1EDC74643115BBA84CA0621A9C3E49325F8B583715142732C4E0EA713F36C6FBC3C90A467757C798EDE3368015B95A62ADB0A62A12452ABDDA5E0B9A882EABC2F1150157E8AA950010EFE51F29B3C88F132A02E311FD75497BD21828F428CFB12BC361250B3A765E022D70BC3544B55DF119ADBB5C63399172CCC7BB6F392F04CC02F96AAB64E0B46744ABFE9ACC869487F929317AE1C103508556F688BE7C3407202A79E54F68683CD066C537366BFB918B3916A8B030B0CC1301E1E4B7098A47CBB46D417CAA00418E9020629DB0BC597B2A9008CFDE2BBCC777AC7BD55F2215502FCB3F803075037A56E70C8B4F3B44B9269824610BCCD15CA8A3C52357BD582C52EA217B22627ED9ECA00E390E7E890E626B75AF7BB9F5D8A05C293642C51B0D399D9D5250B19724D22B3F1010389BC38752A032622BC44FC4BA074B0B1EE753F6305931FC3CB7B0C88FBBA271F0722E73C83E8C49A120CD3130471A78C10DF4CF52952829E596BD651AB39C430C4C4904B55EBFB06F74640DFFA40D76C15E3779BB752CCB3D86AD225B8333208EC12C50B7E923A9F67B3E77AA55A8486CBA6EFAB46CE56A7ADB92739B264617CCBDF5F41D5797873A42B36F26A6FAD310DF949F9C670014403136522FD5530E03263401F3138847C363E400477BAFF7C38BA4631A19517BDB61B8CD3868A7C6BDE90A97D5722B9C5B17BF05C60822A705179D018A324E0CA09B54998CA8AC188B0037E4B563B479C4795562591CD3E06F64BB83057631B243CD981819A3655F68B506FD0CB52237C9B9166D07F46A44C22C037B7B07250CB5088A96473C9D225B79AA8C09245D8B9A71496AC9CE658D0CC329A1BB3FBD03C433E413F355515B2373D8158A40562501FC46C0E7A4E903293442A2D8BC0FB26A1475D2AD52CC1B99229C4DE5A78B7B07D84475B5E8651590916A4978DCF72148838140896E210A3C328486A315A9E15592B9945730CCCD1FD75ED55A74F4897E63B3A1D8B96D5021CBD0B8141176AF3AA4A69AE6C634419246BA662F5739E46991B09C631DB407E1A94EEAF717F92A977A448E67891BE2006DA0371AA0B0C581DB7A605080533B2427194DF500C4D4D17A24A6A98F96714556CBA48327BA2ABECA7C06FFD382133621CBE68D9C11B07FF458E584848473431B488ED6730AEB26093288058B653CFE453EE00C3D97D35E5061660F246FF10C75F6BA6B404A48D537A846C06D02B7242462B0C0A80CBFE9022D97852C290887D0766FF81CB9A08F0F06BF00D6996C962EBF4139739709BBCABE7E770F01FC720BF015E81517D1A7AC1FA69236D452F783C0DCB65CFDE091C0B8ABBDB8B83FD2134E7434452C21BFBC0D5FB81F631C2AFB1C0F65EA0172999C6888B2C39A8269FC383C06105A34194D8BB64D31BD56E86E5C3758293B7844FC5412A7B7D9CB9A614420BE1C079AE9830A494F356B99E9981E55B5CDF2FB227F2A8EABB86531A00E42F07C0E1A0B198BB198CA8252763B62872AC7C742BA04084DF82F542B067C23B72FCB51DFC9A4FA2958CE0C2EA4265C1654BB2090BA81273E83FAAB505871DDFA6C76062B3308AE5D8143E258793130431A16CE5E7B62BA9B90DC776E778280D0F2B8CDF7BC8750A96B219EDA180621707F1E778910B9AFED44842D78417CD027F819699AF6B0AB475A18B7359817B50C306BBA0728C5A9088E667DCB7944AF6C10BA86300308165C1242CBE8708C8347C44AB77478304EFC0A9E5328F203B90108418FD1B5B7C3B085E74CF500729E27719C2596FEAA689A54CCB3A5A4A74ACF36C652FB97AD49190CC6F08382017DB7A910F816701957CDD8449CA075B9A3C18BD88469E3F51E0C967146413BDAA15C38284A726A8935B3987E774A182023CC0ACC18A80B8B6909B52B8726881380B204CF1C069415A99556476B0218EBB4217FF33A0593BE5F3CC47EF89C13397D68933721C5A6F1241B88F452654C249D35C1A8B16305469586435C1A6156F8520AD33938C8DBA429C118154020205B0235262F233C36A89B384D82BBC49B6D6074517A631C5ED285F56585B286462872503DA5C3DF9C91340071EEC625F8B29E4C416E93B46D37F95822EC35C2897417D7181DC9A7097AA74F3A02BF1420B1A568E1D7B1A743C0D07623E2296071912F7DB25D67D751FB3B9FFA671403F29D162B635F0C7AE693578D2A752984914EB9036BCA365A76861A05075B4B2A95077B6600A42E071D60E21618A689E3F7B5C9836B7451997EF80917F6351F814E2EF1786736A703012D3C9AB9DB50B5B9F08BCE69BA50A2C48F059DDE2181F725CF39F426B39028402ACAC36BC0797C918D30A4A6D4BDEA2927CD75364D167F34DB97260039BFCCB64B0003AB3532F77353FB6A0433A5A95570C2CCBC77F0E4BEC1584CB1A88735F27ACF58120D01265CD7236F18AF3C00B4363CC372FAB07EF3A87030B19B07AF020320F1F747E32A8BD1F32E78F1A62960A43327307D8C212D1044689805BE15C1C68682D0A8A24EA51267058DC4B15F36E12104EA83E425C248209A8D193911E2A2DFE3A47F485ABB226F02919F9BBA4014262FFE6B4607BBB511FB5FCC205134F8AAE2310245B9C9E73957A2B5B4CFE0916DC1BF6FF891C645B28E63BAB6C23E5077A8C3954FB5978AD8E07DAC5C5C1FC4759912524566785DF222D04435A6A24361178D917B53AF57438B46AEEAC546BB5207C186BD196BBB6277216D95AB6E545D78E04B82669D19093241B808AEDC5DB79A9E54762074A0AED86931497917969CA7F20942EEE719287C887B3508F23B919418278BE0236043ACB3E4ABAC940C44C3AEC3AB8C78BCABD84C1D373899369B515C2478C6085CED3B08F668224F950D3B82355468BFF0534CC7660045E96CA40067DE520091437309F7030F71A250C359F0C71C2F8819B62CB39646B19D63669F679FF9F48AC7A426E3FC1A1D358B675105F28586726304ADB8109E104715B6C330F053961207EB96148A866C12C9349FB6AAFD1B42F5F80A2D827094C3B4DEF6478212332D96359FB3450CFA6BEE8327EA707B8CC61799105358521C6199607D9B769B38AD15E4B638D12D16AA90AA49CD90B9047696ACF9C14CBEE59F82B46DE5BC644402400BAA2E839AC801C70A368A3611CB11A1484DADF30185112F52421196D1797A3085F5D429D286343953BA8DE676C381AEBF394D0453BF1610905F3B6AFDD5299A750F2333B3944067D9A9CC201922F9B5162CC41CBD35400A275717228050A97D05D0C1B303BAD3405F36A1218C5C089C98467AA37905B334EDB31F667A88C2129C1749784F49B83A329275E1B5FFF4798D4B1C5779A5D433CE716BCE5763572A29CBDDF5B40B464F3E163CD5B554C5612C20726F57244735E2616F45356237263D69A1E1E03CC4D9AD57C83B3075CFAEE45418282261D8BB531B685C766989C28AE9F991415907858308A1FA027156B6D3C8C0CF926553B570FD077B6FC419D8F4556655CE53F6802D406781B06463042304477BC8EA19757BB54F2CB54B9276FDD575D5A00C267B1222D4C25DE11860DC14A1F3453423CAEF02BFE8720472C194DD234038F8AA0D3118286B530247B88A83318FDA0A9C226CBCF22510F681DB3880C2208B70F67C124437DD32AB9120894AA287C7040E06F6CDD0121EDE209068238B57716DB488335564C316111CDD90741A197646874922EC355A26A7E5BA4AF5873F974B2626B40AFBBB5C59501FCECA0C9FC76FE9B8786AD1C5C76B071B6C054AAC0EB8E0535BF8A4249A9256E4C1E8EC673FB5BCAE20063A90B601E047E9BAC3BA827ACFBA4A7E9B040776BD6F351E548EE005D759DA86C9B2971F9D6D1CAB8D517DD00566ABA5F53253D778CE06E380B14C9019095028F3944A31A1AA4816D505224FCA29659D6C7A880A5F20D5FE02DC4491F2F095DCF2DDECBF105014C5A8", + "ek" : "05F3D006A3784B295D47284391A7D60FB169AE23529654B979A9BFD3C25FD63E0FB2B82C0DECB45BAE9593058BB21411AF352470A56276DBFEE93FD044568BA792E2885CEAC8700EAA25218E5AA670FE93F0C7F28C19BC8790B543CBFEC7BE9FFF650E7DFD42C6464C21D31E1FA0C11DA0620C0F8DAE49D4C75C60A257A5BD5CCE77A23E9859F8940D8E9B3A7E73C943D533B3E1B1A423A9E88C1A46E9C7E28F5ED8A11C3D913700A0489016E425A0A26602E218889EDD5678B3A283EED69ECF84370A60CD1C1CA413F88A29682A8D1A6E794DC07D44615306950BE92805F8C02F6C8101C3351A074024ABF7F73658110388D7FA5B2AD95F0D68DD63EACD60650B6FCDC2B4D94E06C65F017AE7DCB0491246F2A36E3DC10C0C6344122B892EFEE5CD16BB944629506C29930F5099F8B2793B5714549057B7F10C387374C93F57428109EBF5814004FA9A34BA4D9E8FD32399D546C11C07B3896B840A00417150E976ECCA2E94F27BC1CC8610E33EF91350C493F17681EBAB4596AD173FFA3380A35FE3A301CDDECA9341A737A3385A511904A3A14908CE6E3D3C8D415AAE0EC5F8EDDA69673A48D9AD8D8C3012348253E265298D0F49BF4985028B957727CF86D70EB5D4DE6F5AC5037198A45286579312195902CCB495D4931C58F54EB1DC507924F55117C323838E847E844AA86CE1518A4224B2558D44FC5ECE031678ED477221E5D387445DDADE35C06EAEA63E7C5E308DE3C0710E2601EEE452379415D9CD35107674C8FC9C69123745B287C016B643A6F3821B3CC3B016C3A63C4CC1F77F904BD59CDFF3D8A079348FC57095CF4F9DB226D0CC9B0119A0E9B3EDD48967DBD2AC110D35ABB01C64B40250F18D8F4219ABA0C801E12392098FD367CA3BFE141E8DC85BA025C1B35451891227413EF6DE49729DD2A17349BE212245BFCE40FFA2E2501CA8631AF8DFACF997962EF1408670E620A7A0BF1EDD18DE50A14F80A20872AE1DCE05F231A58B312E0BC59A383A35951215799517677D24DDEA903B8FCBADFA835ED398E129EF573C11ADC64B79FA34488818C14BADE1EE34AC64F8E06B5F283E7C3BD9ACCCEE4BFF2C538C9B752F6E718FCD4F0BC86502C4CE1B70A6AC222B914FACCBDF0EE5A796B2A5774E6D54B8084AB465A31DFE33C79F8BBA6484C5C786DCD7F389A0341A93A790B7A3EAFB7F9D390726F4DB61945C70DBE93F968479D4F4E7D70780DE5BADDDF9C6748FF36B7B63A4C136C2EB20C46B35AFAF89D569E7E6B82BE19A7F5337ED0EB1688E1DEAFC202CFBA18494C54654AFF80C936EBA165255B40EA8AEB25BB61B247BD69495CE99D6F5FB8FD3463613040F73720F3B170A9AFBD4021AA3273B38201F6A3AE592241AF3C423B73412A98792ABB418FF8DFE540F5502DE98AE3CAD0335CC6C164EF6AF66C62AA528541B9988A78FED04383CEECF09FF68FC73D566BE0C45193395A8218DFBC8CDCED7914D0C2CF3E0D838607AF51BD798E935092C750155F623A125BDBC1D71B5A5C87908F9C79AA1F6060DA93BDE03E0E5C07D423EC7CB2BF3D354637D2882CD7598E8156BE200FA42B309C58FCDB0C3827FC7776C1C34F2634E34832925233A5A5C70D3E1A38BCC7317B67BE900CD6A2A4BFB8F5A47F819F47662C811F9E40A2657027479F7E3148910A2BFEEB809E6994AA32BCEDC5C5984812267AF1A953B8A7A2BA7A56575E1D0707A31B5630978968187DDB931DF3CC97BB351DDC7DCF2E8B9EBF2D8D0BA71E439DCA9061311A189532697FBEA421193828C15F90A2D6854B4E038B77F3B31C56DDB77ED19315941D47D92E4B8449B4BA8FE1D229E94B442220D2FA267956747A86D853CC079EBFBC28853F4A88FAFF6B33F65DCA01FCFD949288A1359A68181F5C24899EE51DDB51557706FBB17EA1244185F7DF021CFE153429F7FE29E9F6339C3F58E2F4056ABE5AA8686814225B84866CE2954DD0C2B7F3934E5DD6446D02D80510E88EBADB18B8FC0EB94022C0B4D0CFBC31DC7687E1F31DC317D354F9A6D24F24F0150FE56E480845247FAB121A5C4C718A7F029A03C67045997D3E1666EB0D2EFCC4A8C9F4B02030827119DF2DDEBEF8DA8E1501A226A0548D1CE09366E978C9589E3C98051D3BB9BC72405DE0652BF591F66C2E2133B2D7BECF2BEB9152C1BF1740CEC063AF2719116312FE5AEA22A9F9147338BA95C5FDF", + "k" : "4C12774C6B69CD110072F6D00466F2D8EFE5F412A2C735AD279E6CE7ABF79F9F", +}, +{ + "rngSeed" : "980D0BA7C8F8B23D0E948A6029FF2659810EA1360064663A8994D0333C8543EE5FF5D6D5C9ACF446E61DC464F792B9D3", + "pk" : "1CB3C6A7F721C4039B10482990923ABA0427E2DA5BDD30BD55133989A5B43BC371D2105415E76BA18786237C7151548B26005961FB2A9E737E39BBAF97F612CACC3EBBD216F9F57873F97C503A95A49A1A113B0C454526A082203B1A27E2FB170FF1B59B0657861567D5565555F11EA31523C42898D6EA1AE260CD98B9CD69F9AE4D19A81365154D24C008BC15D1482665C313C3721CB701C3A407373E1BCA5829CF45D484721357D5F83B5CB58B21987D9FB7B77224C03C017E183B31FB4C407AC23312ABA708E8BF7F905D68B4895A48CD7A70AF6AB9060D959F56A02D7E3672A90A6218FBBC6FB641163674BD736AF2764C72C5BC85651BE47350507AB81749BB2B6C744520B5B0A3B6633355C0991CE4E1A813615F2E8300366521040049B1054A7741B29AF1C300E2C86977AF90E820DCFCB8CD967C27102D49FB1683C63553289CC0C62DE0E26F7555392187009E0CC5896ACD8C3C9A4A7C637A107DA325CB7A694E9A1107E889CDC6310671BB6C5B51A35A0169FF7B5158BC6469A71A3E8740E9281F5869180C91CEC8E1169E2B377C8174669CA67418116C3CBD2AB61D8A874F9BB767DE8973D8425CD118BC9A320453DB9C64183248B22AF3F489AE69159A056AD113833C2A9FBC56B10D013E911210BDB8CBA68A0FF0F0729757BDCDF68B3FC7BE480481FF64C4C09825EE52B274E85E544091C3D36F40444D28878D7C19122957348E3C27FBE74685FC1A3C21126064242616BC4AAA5284F5588435140956CF37BC72DAF5A73FF6CE452CA689066FD6E118BCD4988660C7C8501C34DCBF1965C66FD95FDAC910B9E48093FCB200564B4CFB36C72C3096C5579F736059534D57B7168813439B722D5230B255532D838598D615C1B641A9D5807F33653A1BE96835F474D4F1955E3C5BB5C621497C3451003CA76275AF98B25A962765E5BF2FE754330A77837288810AA53BE9A2564451319405CC38B13401A7F7DC960B5B2096F45A94098A2FB39DCD654F846388CFB4B57B4B92ABB321A16A83B3E6953A0724AFB47902E581ACDC278957100548C735FA5C04A4147E826A77030284615B82FA60BD3619B57BBCA10872AFEA091FC6288EE434D8319F028125A0B5006CACACA8CA6EB95C7AD87C7E499A4AD81BBF79D144AB16AC9CB49743258CF0C83F2B006B1D0585EFA0AC7DC722ED6C12170831F0964CAE2B6D2F808AFDC6223D11B510B949E76A0A4C262748148CE17B38C55CC7EAC2BFDF468105BB89298C88C8806B124C7488D606B52B217C81A17EE5AE67CC27F6A3382D50705A9BBB1D3C59F68B8BA9A45ED1C97EA1EAAB76903D1F2A1C71A07420F47695D1B68D06C5DC85114AE83204FB4BF16C09385934105C9E2FD803D83542F4AACC3AF6B949A63E6D0B0C46CA8A6B4633926C0665BC09B69CA250945C14366D49705658F6CD76964E107497BB42290F4C1471A4AC29A60C3DFCB701770619CB45B0613068091A68B58C7B2A19CA9933CCEB112E234014816B7DB43BEEF660100A19377A4200A0806BE78D30169C4B747E8208780A14AA53987065936AC4F06B7A710870FCA3B1BACB04C2AF5E3005A9208B3A03929B864D0E1011CEC63B93220E96B480128C20B7675C9A87C1C8E2BAB4A7422FE9C16D367928117765458A3803AF02332D1BF654E782816B15A5BCC3BCF0213DCBE07C59A92D1B1BAF1F217061E197C71223C12746CFC0B0AEB99FEA7B29BB3A1300BC266F1692FD8641D6FC594B9894DFCB0C951B8351236087241F7CC3506CA74CCFB4C930FCA1BE940AF6606FFC76BB92B53768294C30370B29B795DE63CAEF451A18317384299168B77793E22FE0FC03E4C064CBB6979B38871EB11C5650587DBB31EEC0CF7CE128F535B0545BA98AF5AB4BC186EA1081AE15BEDEF5945410C800553D8A2211E8E16125D4A7CF25A91F13858E1CCCB8E56481A5A3BBC3468BB624F282069425C8B5462725A813BBE53C1CB11BBFA242C2A1619763448AF184958CC333C3AEFD35C4A4861C5CFB2EE1B0C39B0C73314AA3D191B6406CAA94D8280D8B01E1B73E56F5BDBBA80FB3923A4B608543AC827395CAD1B050530B5E908231C324132D782994753284927F3A379F71603036A172EF58018CFBB879F29A42A106BB32A384DB6E033401FA46045B035ED2B3F277EE6BC7B69EA2A0946112498DA4EE64A2BE6AB49596C4E61553E1164D", + "sk" : "25C969038AAA118900417B46198C2C1D718005994DFA10CE5EB8B998A524DBB1A4F3E0716D314458EC6DE9972DC3D988A064CB0B11CB82450F1055C9F333B2C82541F99167786B126C8427C515A8F9F506F878427E1A5E239547F1D6BD97674379B06813624A220A22F5C51E0DC0582AE30CAAE6CC39CC1350412C7DE154C3484602496BF84CB3DF4C031192BAD2390F9F60C7E84855CA118B00BCA814510C6A019D25E8687489CFC7C0240C822DE267359B877ADDDBA93EE7B99B8831EFCBC6C915639B7547204190F4D500701B239A161CC4858411542FE113372CC3B0E3B4417EE5117DF681CCAC2EFA3988921A151C8418E52CB49215B1E7C270812B876D37B092B882EF98A8075226AD76AB0BB9170F61C73D1CADDC201ED8A38B9E237A6C345FFFBACD6F86C47BFA56BB04B05185607FEA02A16A132730710C85A424A08CCAC9C8DCB662FE0650FDFB1AE1BA973E95079FB9717DE44348CB0930D1C8EF1202B4C7849C244436D7B477C2211758801C316AC9B5BE8A082661EA78E2B14E87DA8C78E81EF2285F00D116755C5CFF986B56B29032B390BB8453E8D970C7F90237757EC291CA8F71C9B691CDA16749A63246EE865AC503A5573962BE14A61C31A6BD3995E51684C1E59D2E803B5061B2CE633E7B692B5503818E349A61155B8820B790A692896317FB56366B63CFD7A4305F1082BDE4CAC8904D22F782FCD7C89F32CD98125F7ED96B0EF932CD077131424437744A5CB74F2DAC52932C6C25EC282CAA4E65FC9B38A43E21D3B95CC5BD67801A22D95280457B5A182F6D9C8FDD197CD12231F7889AF318AA0DBA8E3EC6056FD6687A476A971ABE6CB439C055B21C6933C5F58C9409CFDF29BA810B87CB971F1E314256DCAA7AD63A41A11B4C1C127A8065C24979B89C96D3A2A944D16D20E39C27CC2969BB132A688A0A419C726338F93593005453001B753AFCA27C84C25661A63628365CE3074C90448C92B20E1299B2A10403FC9FC8DAC9BD479802F8C3ADD3929B60B409F73E53FBAA328756A7B3CA8AB8A3341863CA5C625697B4E1760E63217275EA216A61951F88B9CE64839C461DE048B3AA4692E6095496482130EA3BE3569CBDAC7C6684C4C561043B4167795138C662B44EAA97A279A7EA1A9E94D83D008BA136C484FA27C05DB44066FCAA02F71A663512A71C7AE01742082C5FBC879A046373759965B0E565930506A8F6CD1035AED5E4A12B09A7ABD74D4135653C509444775190B3C822C567381A266D1A7D6E19A60A536F60A946A455C71BA2385FB099ADDBADA7691DE2C54D5EA88020DB4424605C69BA6AC2BB4181B363C688C24611737CEBB00F536A83C3B30F0A9D46946FF4814AA8559368D393D94264DA25B805B417158B6D0103CA9D1C5B62B1B5CFE969677A70EC1385C17A59A065809E52B99FB647E63B1F1DB0800DCB9952710A94361D60FB0F932B30ED8B6715D913D8AC16A095809DBAB0B0F64B6F5A7AC4AABB38414401C58B935586F000354BE345F9C45CB0908DF8E33063CC0997D122EC830E4C871166EA0499D6710E919FAA269B064374D463BCFD96B427B47755D689FB3320B3E4759AC13F738A72516638D8194C31802ABBFB68F4A6B107E05D81BA4D5D70CE6E140771F08FF7E966364703FE8A2F2EA8CBCC960EF834A711CC7C3BAA7485059D7315AE0B395BAA55652CF54FC817BB23819117B933B82BAFB146248310B494C506AD0AB37025965F550A2D821787671CDA3C9874E6781AD85934DA3393B566D58742BD8CC44043CA7A4268B757BA3E1B4975F112617707C7F603CC3569B82B100FD79A391673DED0A14CB11AF1556FC26A4A11291F4EF1816C52C292475807F58A2D461CA15B13ADC4A7E1A75E1B4BAC02F11C3AF98F57B5516DA77B49455CCFCA47BFA0C70E0935F53B14C3431724A35A8FD663FD2CA7107C8E4F0A14D30B98B5F03E1CB568331C0F14E7756AA4901313842447AD98874165F8372334869E89C82EB36429C13F442A3F6F92A9A3F75B931B97B5D4080442371BABB4509C5E1B997266805B777C1253FBA72A839F9D62002BC2075788CEC91269F0F1408E71031122B107E11486D096B1FAAB348C5AA46CC63EB38C4935915E037F4238B9BE3B59975C6A67FC807A732B0AC43671825CD0F74D1CB3C6A7F721C4039B10482990923ABA0427E2DA5BDD30BD55133989A5B43BC371D2105415E76BA18786237C7151548B26005961FB2A9E737E39BBAF97F612CACC3EBBD216F9F57873F97C503A95A49A1A113B0C454526A082203B1A27E2FB170FF1B59B0657861567D5565555F11EA31523C42898D6EA1AE260CD98B9CD69F9AE4D19A81365154D24C008BC15D1482665C313C3721CB701C3A407373E1BCA5829CF45D484721357D5F83B5CB58B21987D9FB7B77224C03C017E183B31FB4C407AC23312ABA708E8BF7F905D68B4895A48CD7A70AF6AB9060D959F56A02D7E3672A90A6218FBBC6FB641163674BD736AF2764C72C5BC85651BE47350507AB81749BB2B6C744520B5B0A3B6633355C0991CE4E1A813615F2E8300366521040049B1054A7741B29AF1C300E2C86977AF90E820DCFCB8CD967C27102D49FB1683C63553289CC0C62DE0E26F7555392187009E0CC5896ACD8C3C9A4A7C637A107DA325CB7A694E9A1107E889CDC6310671BB6C5B51A35A0169FF7B5158BC6469A71A3E8740E9281F5869180C91CEC8E1169E2B377C8174669CA67418116C3CBD2AB61D8A874F9BB767DE8973D8425CD118BC9A320453DB9C64183248B22AF3F489AE69159A056AD113833C2A9FBC56B10D013E911210BDB8CBA68A0FF0F0729757BDCDF68B3FC7BE480481FF64C4C09825EE52B274E85E544091C3D36F40444D28878D7C19122957348E3C27FBE74685FC1A3C21126064242616BC4AAA5284F5588435140956CF37BC72DAF5A73FF6CE452CA689066FD6E118BCD4988660C7C8501C34DCBF1965C66FD95FDAC910B9E48093FCB200564B4CFB36C72C3096C5579F736059534D57B7168813439B722D5230B255532D838598D615C1B641A9D5807F33653A1BE96835F474D4F1955E3C5BB5C621497C3451003CA76275AF98B25A962765E5BF2FE754330A77837288810AA53BE9A2564451319405CC38B13401A7F7DC960B5B2096F45A94098A2FB39DCD654F846388CFB4B57B4B92ABB321A16A83B3E6953A0724AFB47902E581ACDC278957100548C735FA5C04A4147E826A77030284615B82FA60BD3619B57BBCA10872AFEA091FC6288EE434D8319F028125A0B5006CACACA8CA6EB95C7AD87C7E499A4AD81BBF79D144AB16AC9CB49743258CF0C83F2B006B1D0585EFA0AC7DC722ED6C12170831F0964CAE2B6D2F808AFDC6223D11B510B949E76A0A4C262748148CE17B38C55CC7EAC2BFDF468105BB89298C88C8806B124C7488D606B52B217C81A17EE5AE67CC27F6A3382D50705A9BBB1D3C59F68B8BA9A45ED1C97EA1EAAB76903D1F2A1C71A07420F47695D1B68D06C5DC85114AE83204FB4BF16C09385934105C9E2FD803D83542F4AACC3AF6B949A63E6D0B0C46CA8A6B4633926C0665BC09B69CA250945C14366D49705658F6CD76964E107497BB42290F4C1471A4AC29A60C3DFCB701770619CB45B0613068091A68B58C7B2A19CA9933CCEB112E234014816B7DB43BEEF660100A19377A4200A0806BE78D30169C4B747E8208780A14AA53987065936AC4F06B7A710870FCA3B1BACB04C2AF5E3005A9208B3A03929B864D0E1011CEC63B93220E96B480128C20B7675C9A87C1C8E2BAB4A7422FE9C16D367928117765458A3803AF02332D1BF654E782816B15A5BCC3BCF0213DCBE07C59A92D1B1BAF1F217061E197C71223C12746CFC0B0AEB99FEA7B29BB3A1300BC266F1692FD8641D6FC594B9894DFCB0C951B8351236087241F7CC3506CA74CCFB4C930FCA1BE940AF6606FFC76BB92B53768294C30370B29B795DE63CAEF451A18317384299168B77793E22FE0FC03E4C064CBB6979B38871EB11C5650587DBB31EEC0CF7CE128F535B0545BA98AF5AB4BC186EA1081AE15BEDEF5945410C800553D8A2211E8E16125D4A7CF25A91F13858E1CCCB8E56481A5A3BBC3468BB624F282069425C8B5462725A813BBE53C1CB11BBFA242C2A1619763448AF184958CC333C3AEFD35C4A4861C5CFB2EE1B0C39B0C73314AA3D191B6406CAA94D8280D8B01E1B73E56F5BDBBA80FB3923A4B608543AC827395CAD1B050530B5E908231C324132D782994753284927F3A379F71603036A172EF58018CFBB879F29A42A106BB32A384DB6E033401FA46045B035ED2B3F277EE6BC7B69EA2A0946112498DA4EE64A2BE6AB49596C4E61553E1164DD2D4C9CFE0E22188F2BB5E538A054C904CDD0D6DD921AF93591F4A37E9EA2B5C6931E7324D5527DCD0EA7E2E6C2A82D4A80C3EDFB38752B36581F3035ED9A23E", + "ek" : "B29E987E4ED7AFEAD4237F7E8DC85D1240664C51E7662E96D37E1DB8922C8B2D9D9AE8E55E53684B22A394C1BD9BEC693E4EB20600C3E8C722893AD1F764BF1A9E36D98C42370879A4431FA05696EB9C5A609E10C9D716CAAFC9CF2A19B1B97B8FB896D1D60C5C9B6BC7E777F5F60E9C1C2412AB5645BEC7DB202D561307EDD06AC8202158A002BA97492C33334C20C977ECAC7D383BED1B24D1DF423F922DE2214BCA2E2DB32C5984E5BC303673E07FA82B92C0B85146562B805DA9C459B58C58914FC0B3B1BBFA23DC9F86E042FDE8D94D82EC63ED4AB1C505026CCADF252DBAA286145B068621196D2688133E6954283D97F2AA79772170643376E054E1461CAC32D466E8C4D3D3426E38F1E9345099F855CC9636F67A5235FC488248EBCD32144DA1093EA739C1A403993DAA54CD346B8EFC6BE9CB3E2C83BB92E8D10266D876B924B60DBCCDC27D0E8BDACFE1BE09DBEFD50F145C681BE596F1EF64035A2C4C696EA1458FC13692CC6117DB4C3531ED699CC3AC8CFB2428A58F944DD7E418BED37B6817136EC6B0EBE6064D6835A7BC5B7035AD268CDE71EC6CAC80F0D7E7DC40CE0F96C05ED753E374BAB62FB19421C03B17733C13F2B79308ACE8648B57D3B24781615F2ED3B7C1073B13DA98DC5DC165C313FCFAB4E8DDE59BB40E3A57CE5EB7E0FB816AF6AB563BD655613C579AB2D63F518ADE525108EFC9813EDD7F6065600AA722BDDAA06D3C15B993EF463001C014386C802E7A688EE7FCE581BCACBA3968FA645FC47AD5927C9C7383C64309ED425E545889A619634890286763617322487F78433D1359527F04A7B207C82B74694CA5B0946735F3516C52565A66A66D894A115264A31FE475F1D20C929608439B6FE119BFA90EE4B185F23001552202D00D8F8AFD3052ACEE57844024CF74574D2C14DBCD1F3B6886BE96E96EA675B1C43C7A6786E63816108FF2F491A2CF3A3DAF8069503BD646D50322079794E44C0E05CCED5ACE50E941D773FA0BF4086EE005CD9079E555B5D95CB2A6ED346B57652E3DDDC3F8B2C68974AFC8175A3D4F0252354CAB31166DDF0A958D8AF1AE025B5670C132783153A046CE429F27BEDDDEA3258AEF250F2407CC59AC49CA64CA1A091F42C1988AE36DED6FD601F515288F6CADE2F2E4D05A2A9AAC854A6514BE7F625264297AE921079D4BE2BEA8AB39500A4C2EB8DAEE87C08F423981BB7F0B3A1F0D398AFB2AFE950A03A65816874F0DF81BCC38F883BC419A68924FB6657E4344273225591FA2973A8BF54A728FB345BD0EC24E72B66489F8EBEFADE7AC88C30D7C6710182AB78C73D3ED9CE34210BA10ED28352CBA24D7DE9241F6879DED6D0238D91B3C20F31115E6605D079E4FCD27A80626A5D052DAE7D051133D300BE0BEB4EB4112202F60F9CB106D3AF75E98878B469C63EA6F6F18779429003C6FFE86E2A127008087D579913650B4D191E2F3D29823371C7C8154AF2A1861189DE419FC9334D3CB766226027786F94FD66A871CE21D4FAD4F7621F7A42F0B3DD8EE346828C4201197471B26CAC1CCFDF80B3B677600607DC4CFF9EDF223F4E4C95A71754E9DFB7BF828FA93BF9B939BC6728690BD017AFF6371D38CA88B1E6DEAB14727184C646445A461E83A07BB923DC7E8E4FE6788FDC52A7167CDF96F2D2D491EE55190D2BAC7131C5A68CA50DF34938C01481A1853025A2CA02E8861E10949F1AF16352D1D1647BAB2D8A2124804ED9CE1C7EA6F6D5F014E8D9C1983668A39D29BA1CED4E70585F02934D99D49D8DBA8E3123BA469039BB21C74B478205203EB30A8868F99F4FF7E5F8F16BDE2A0BEAD28B1D6784C41576F6A890029A387206B309B3195D1FEF8D38241933C7A2504976AB9AC5247FBC0D5661D9462383790563625C080C94503D13E33D8767EE9524D08425BC25F59937786EA0FFE28CFEBC55A5227FA2221317A8A00CC16E514A8398AB5249EEAC23F1DFAE4559BD77F5B5C32A453E846F7BC3B9E699A15884392231209025500C5123612C06729EBF2C31F09561814738490C6459E47D9100A423FEE8A33E683078EDA644BB3DBEA883A6FF6E0C965D2F68FC28362C93F38E23AC8567935BFA3F1CAE7B44271574E5243AC83255E258F19594BAFBBD92DC819CA78889616437F92495443B0A95E04E231371DD0ECA5596A527C569576CE3921682B2E59A6A8434F3F2182AB", + "k" : "5E3B04CDAA4D0510916C5C8162F90D7B2C7C2F0353A28EEB0966CDC0AC7F8C32", +}, +{ + "rngSeed" : "6C029462CA42ED520F10A579F52687101105E0B90C6E7BFA582A4C112B579D5AD0A0ABD38F72ABCFDCAAF5893A112BDC", + "pk" : "78D90B2D2B06C3C74E60306D7E0514FBE0111A930A10627E5B2B11077AC78BC32C46D1406EE73ACC41B518B2C1A8CBC93990B9C1D0964B1091B0871DFE594AEB6719400C71E96893A7524D082BB5B7B3711F586F9ECC4B65F66FDB2801495086969A6A49961D563391A24B1029A7A3C9E2399F605A37A4A05237570160976B658DA00B57CED318B4C7025CEB071C269EC9DB9D6A2944C973CC9B427D5573C2EB37C64E4624216C290C5645B36CBB3E82713DE383DAA5CB4029C6DFB14C43F4AEAA9C93843B784FDB63957B75F39088820694BD0706CA856864FA031B682031581673608DC9EA058DEA014AB79EAEF74928D4CB33308FCAD06ED303A1AB8B6CBBDAC332A24CE5474013C90C5B1B869BC9881323435A097D09E5910E39CAE5A1BC148AB7D8AA12C84634864930C24AC4F375731CFB65D5992916302640A524A4A52C9A2281534956F946473541852D0884E6461614F9A1DD95CC923C6298998B21C2415518443F86949E6C390F9463B69A63F2F9B328053C01872EA2EA8FC45185CA3BBE74B713528CB3525A60F7639F770824686C1B2AD719FBDA1D4C44C9DCD0B24F5277FB6720E686270B5349FD3B1215008C6B24C26AA943AE71146F063072F0C42EA114D3986ED1030260E88F2F2C34E7385491565168E1C18AD324FB13482F5B83B2F6020A6895F9D24B93805FD5556B4A048C2E3106EB02A53A774B169106A77BC166137E7DCC4B60569E77DBC6D5F9C276A011EF59BCCD08793B695EB3A5BD3C1B64CA3BBFECD1ADB5F97294D8909B31772929C693AC396D412549B1CF910AA3C60CA0250928EA4350B8C91DF7D31474EA07CFF56DBE417B16603C6AF97329D53163343E0AF3A84ED37CB91A349BF2AF7EE84D8EE504F2A73E9DC3301480BC6F144A631BC3C160348773CB0B6A3B57FA1286E2107E950EC6A682EDCAC892926966E28AB2A482BD5991F8C6C6F5E231B0826191A8C8D3C2701984980146BBD1B8A629B548CE578F5DF90B58305026ACA96EF20C77610A2DA79018B0047F5351858C2C99A035F2F339885521D09611A219895E987471A2C10EE576E07320B7F9B5D678221AA995AFE550C0F72F1B647F3EF429D3720802D7B53CEB917FECA63860337EA126FE41777B85980744025EF9418BB4C1983C8AF0109D2A0A0FF47C121DE1926FFB5B3D8BCAC797A0F5309C8629605A757A6AE91BEAA437CFE184BFD3B703052FFE8CB2D7E57B411719625A9F1E11473AA8A4814788C0280FD179596DB23D3003461314896D38A9E8FA75E93B65CC76CDCCF24A72B1294ACC47B3E7843B2A322E82C98F906BA369B7E8B588D2DC8056B70E8588C4EB80CE8300630D265A8F6A74306374DA0622EB125F51764C81C55B9966C27B562C5E930A30207F825B27711C3124FBB98D4A8351980A04041E99F7AF63AC015D667232162DB0E793EEBC70DEA04EBA186D2C14381AE886F7C6B934F587710AA095B206621CBE4CA1BBB8752B5489626AC72290315FE9A967EF6980F9486462B74E7938800B020519C5C0A684ADC1B82F0CCAA3988CB5A28264CCFCBA1E8119ADD64A58DA88BED5CB01F5B0410A3EE03C9105029EA789BF65BC9EC58B4B2B0C9AA9C7859A48CBF0C12CF9E78049528118D366D0345951D0AA9102B5C12B36C6022FA4C7B4554178A8800C1A968EC74569AF3815ACDC39BFE029807A8FFE1267A69073744A806161BB5AB59D5340B8218054A252560C188314C177C5F3300E86863EB97253E6778415B77F140D498AA104EB291B21BDC2C5693A39254CB01C8A3A9E8E14A965D107A6B98EB09A26C2851059A290B6E94EC10138289148086456047750A3F8AADB5B1693C9642A8BA89B89C6F45C18BA750656C151CB563BA7260CA09C780077B956E5275CF998C86748D2D332A9008F8625BC61939B18F0C063F171175338464C0D402915C6E54682FB6876C7338F654D1916655FB19E21F18E2C0629E0962457CB62BDF3C93CFBA8A551C752642016F72B5479615DA16C1622B21A105DA72413DF20B125C48B0A76001472780BE292A98500321C007B1A0273108BE097BA0E5972A2394861C5C9F8E0093DAC8AED47A6467570299A5501C6B2F281283D0013260901A08531E737BB6BAA0FC13895253AC4469519C483B591D28CB8A9A0ECD051937EB8D82BBA18673A17339DEE827BE4156633D8A2C376D41FA4E7BD70D4E199", + "sk" : "FC569914244BCA63C05D25BEB59702977903C59C046079C9410C873936B86945AE56F3C1F049A3BA4185AD5C49BCBBBE7FC89E561B2A940AAF66538EBF594EB0E5BD163824F8022F6B5183C0839B59361B96008F3BA83D1CC37CA7581121A0B552908E28245218730B3817A27E4099313484B6FA99A539295713ABE453AFBF8788FE6AB530E1CF3F430F4A855ABF3BC11DA69E10CB2D879075FA6198B1601DC8903C32A845D4DA3B726B6828AC84E3469DC9E66701C16B64957D36128856B82E1367AC00C274D9A366B6B38FA87364880299E86561BDB46269A951C273710616109AECCA78E5710C406B27EA403C05704C77B27DA95C45DA86D2C586F72A0BA1BC5493A389961B789CF5B35EF88DFC38CF6443B7C3190069A19BE5A7B11A7339F6CB445F88C90D1B350D5C3089BA13C4C70ED5514DEA34B61D7BA5ABF4C78024ABD21A9A84F4CD73F86B43F3744FFB572D918338688168CBAC7F979BBDB2C52910402F94C3FCAA29F4362147205DC5B5AF7D4CB920F21851392ED6A40E10F1013B380EE87A4FE70B864AE285BB5B1D01A448AED532DA26948F639258A4AF94B3270A984063C927929867E1FC9415815FC51C5158CB4AE9D8C81CDB30A98A82E6367E6340C6F5704A37E06523E736BBA1C4D98C524BF136A3A48B5786A9EC624DF5A992BC89C389861B03ABA410531340BAAE94C5A91410370F92573C3B28F2E2A47A2695A9626CF311B834597C0A09AB0EE2A588E26962189B7B50A99D5B7906C274A8130F3A30B56CDC85C1A8AB9853476A22A8C047B4F825032A742D601CA1BF319B8A1825BE3C38E93A686A50694E15164D9C603F537772F88ABC1258749A1ADDE38B55E0485F34BD20129A1F6180EB2382BF2B96120CB798FCBD98401A62A872B4B175F80CA9AA0B496EC12FCF713184400D43212DB7A55A522A1D718C43D61823F4E342E9396E6C2451C056CE3CCC93C7D9A45FF41461262E49C01DEF44A350E5CB7E40BFC2845989BCB8CD59600F1120647B45A585318B0BAB8A202AFB7348028B3FBA36A41AA7528DC9973FECA1C28A722525C29687398F607E02C9BE2B2491A0458E1AA6C10882BB4C0BB50985CBDBA386D0B53CEFCC6F316965E1F289148C64BE223853791A254B38A98160F0BC3AA63CB6D45263CD61048A831A5440413AC3C6F38670A83190D2BB32AC5A35908C41618CA017893B3EB2628265B857D5130C821AF61C895C274FAA2150034C0E80E2318917BF9AA15CF2665C1B3AB8B62A39282C738FFBBF7760845637861F46C3E5137F050A907E98BCF755A3BC0CA201522ACC9BC780D10D4C41C69EB400F9234C8C7907BCE0CB52B783C0FA82410A5B0F325753D985622BBAB7639B649C5B36696E2BD8B5C969165F66BA02B142E4380E77AC07D2A85C599B9449E48F4A6AA0FA30160C18180CA2056FD52A94FC2F2D26C0F5641C81CB854197AF4EAA389ACA0E5DC9BDBD4885DA4B9AE207983CF37BF8955CCFBB37E57B30E74BB6F798B4BA62273059B589E51F78B79FE927818EB12F0E73636321B51E456DC5F90281153C7687CC313723B1034DE828620D17AECEE6482242AFE899C45735209606B82A1C284FD7A0DD819F72AC71D30BAC8B54715E422E7C4511A073039587CA15251D8BD926CEB2B0864C159D348889BBADEFF732D0303951D1B491B98B43214D26BC7A3B121DCE077739109B5C00441917CBF3169577D63BC7CA18E4478F4FA8BF23164C8EC68E86ACC8D0E1AD1034A99EEA986699CDB6176C84294F711067EC7748BA83CC6DC51FB3E9576D7150977C76096A233B2233C68995333B82BAEB80C3F2480FBC93B414CD3DF6165E4969AEAB0B052492FAA0A613818B6F60086CFA21A1EA774AFBAB6857033C65BC38395B47F3514C624D27E3120A969D01B1A49AF814C7192AD1F97C2B398301EBBA4E76BE866C8DD17A46C7DB9D5149329CA53460D135E323C6488134E9E3CEDA48562AA78CEFD098FF75A93F3413384904CDC10278C798A77AA93F033EB4FA32F7698318D23C79B4AF83639BFFDC56AF742144E7B36C217F13244B152B88FA3192781594759B1E0D158CDA2A12C1FC85D093390F42413E00A4337C32092618908A24379444FBB5C7F702B2FEA3098AA125A89B82336A3789A3BEF7C403A5A2C56BDC0A78D90B2D2B06C3C74E60306D7E0514FBE0111A930A10627E5B2B11077AC78BC32C46D1406EE73ACC41B518B2C1A8CBC93990B9C1D0964B1091B0871DFE594AEB6719400C71E96893A7524D082BB5B7B3711F586F9ECC4B65F66FDB2801495086969A6A49961D563391A24B1029A7A3C9E2399F605A37A4A05237570160976B658DA00B57CED318B4C7025CEB071C269EC9DB9D6A2944C973CC9B427D5573C2EB37C64E4624216C290C5645B36CBB3E82713DE383DAA5CB4029C6DFB14C43F4AEAA9C93843B784FDB63957B75F39088820694BD0706CA856864FA031B682031581673608DC9EA058DEA014AB79EAEF74928D4CB33308FCAD06ED303A1AB8B6CBBDAC332A24CE5474013C90C5B1B869BC9881323435A097D09E5910E39CAE5A1BC148AB7D8AA12C84634864930C24AC4F375731CFB65D5992916302640A524A4A52C9A2281534956F946473541852D0884E6461614F9A1DD95CC923C6298998B21C2415518443F86949E6C390F9463B69A63F2F9B328053C01872EA2EA8FC45185CA3BBE74B713528CB3525A60F7639F770824686C1B2AD719FBDA1D4C44C9DCD0B24F5277FB6720E686270B5349FD3B1215008C6B24C26AA943AE71146F063072F0C42EA114D3986ED1030260E88F2F2C34E7385491565168E1C18AD324FB13482F5B83B2F6020A6895F9D24B93805FD5556B4A048C2E3106EB02A53A774B169106A77BC166137E7DCC4B60569E77DBC6D5F9C276A011EF59BCCD08793B695EB3A5BD3C1B64CA3BBFECD1ADB5F97294D8909B31772929C693AC396D412549B1CF910AA3C60CA0250928EA4350B8C91DF7D31474EA07CFF56DBE417B16603C6AF97329D53163343E0AF3A84ED37CB91A349BF2AF7EE84D8EE504F2A73E9DC3301480BC6F144A631BC3C160348773CB0B6A3B57FA1286E2107E950EC6A682EDCAC892926966E28AB2A482BD5991F8C6C6F5E231B0826191A8C8D3C2701984980146BBD1B8A629B548CE578F5DF90B58305026ACA96EF20C77610A2DA79018B0047F5351858C2C99A035F2F339885521D09611A219895E987471A2C10EE576E07320B7F9B5D678221AA995AFE550C0F72F1B647F3EF429D3720802D7B53CEB917FECA63860337EA126FE41777B85980744025EF9418BB4C1983C8AF0109D2A0A0FF47C121DE1926FFB5B3D8BCAC797A0F5309C8629605A757A6AE91BEAA437CFE184BFD3B703052FFE8CB2D7E57B411719625A9F1E11473AA8A4814788C0280FD179596DB23D3003461314896D38A9E8FA75E93B65CC76CDCCF24A72B1294ACC47B3E7843B2A322E82C98F906BA369B7E8B588D2DC8056B70E8588C4EB80CE8300630D265A8F6A74306374DA0622EB125F51764C81C55B9966C27B562C5E930A30207F825B27711C3124FBB98D4A8351980A04041E99F7AF63AC015D667232162DB0E793EEBC70DEA04EBA186D2C14381AE886F7C6B934F587710AA095B206621CBE4CA1BBB8752B5489626AC72290315FE9A967EF6980F9486462B74E7938800B020519C5C0A684ADC1B82F0CCAA3988CB5A28264CCFCBA1E8119ADD64A58DA88BED5CB01F5B0410A3EE03C9105029EA789BF65BC9EC58B4B2B0C9AA9C7859A48CBF0C12CF9E78049528118D366D0345951D0AA9102B5C12B36C6022FA4C7B4554178A8800C1A968EC74569AF3815ACDC39BFE029807A8FFE1267A69073744A806161BB5AB59D5340B8218054A252560C188314C177C5F3300E86863EB97253E6778415B77F140D498AA104EB291B21BDC2C5693A39254CB01C8A3A9E8E14A965D107A6B98EB09A26C2851059A290B6E94EC10138289148086456047750A3F8AADB5B1693C9642A8BA89B89C6F45C18BA750656C151CB563BA7260CA09C780077B956E5275CF998C86748D2D332A9008F8625BC61939B18F0C063F171175338464C0D402915C6E54682FB6876C7338F654D1916655FB19E21F18E2C0629E0962457CB62BDF3C93CFBA8A551C752642016F72B5479615DA16C1622B21A105DA72413DF20B125C48B0A76001472780BE292A98500321C007B1A0273108BE097BA0E5972A2394861C5C9F8E0093DAC8AED47A6467570299A5501C6B2F281283D0013260901A08531E737BB6BAA0FC13895253AC4469519C483B591D28CB8A9A0ECD051937EB8D82BBA18673A17339DEE827BE4156633D8A2C376D41FA4E7BD70D4E199AD2B1951F0DCE0B0AFD296D3F22BAFE4F13638EE2540CAF8A6BF7D0387265BF83390C2FAA8E2BBDAC1EDF5A5B6803BFD3C58DCB1ACE60333D03CDE2C71737F55", + "ek" : "B364C8D0D2FF1F2BDEA78E7DDBE2A0088C0E1076C492D4773BAB84E2CED6C0DEEBC2C47AD799D53D0BAE22A45B0C991AC6EE7363D77263D4812438343DE9EA2D707DA2488E0E8EBFB63BDBB9797FDD8165DB7C97187FD3458471F96ADA1A472154A6B4E73AB48F170B654E0596D6ABFDFC03A0BEF6E1FE25DB638BA14466D68F545725431AB0EC60179993B9616CE9AED6EAAEA63DEB37CCD3CD84ADE9845B0D4788D27FBF9A3F0BA640606807B1628445EEBF38EB49F290F27FBE110DFA7C032C7BC1B734E0EE27060E32092675FDBFAA29CDAA084E70A8CDE73123D5B4FCBCC40699CD78D207A47DC96945799D7D25ADC907B201F17DCE9487E6457EC5909814F3A8A4E81711DE450A629364CF763BFDCFD4AFBE0E0C2BC8AE8A4D4F078D3473BDE90F88F0B1396AE02FE8E6F8B464AD0A03AE5BC5522C9D1F546E0837E36AC21BC925B7769231BE6A2B80EB08A72C0A226BEC5B19C8E3C1F65DF11DF784DCA488C344BB8395F9E2CBAF1BC7E78CB1D695B14E77DA99C0414CE50BA1682CAA25FBC577A2ED6F6F84B974256FCE821DBECE989C88464B8B97E6C87DA235E25B7BE5E0957E26E6DA5FE2F1DB23687E18F58772B7A936E4AF1DD3E755ACEC6889FBB3E18D1A288F9AE388272750F72861D58351A90E04A587D069D0438F09E36FD822E79026A07F22B93FF43F3016867175FD894D4A6BC6DF00043644699B46F98D740B34D62B162D5E6F7C85E21C4907E3B020E5875844C27E802431F6268A9DE7420415645262221FC13D749181571324700376ADD64CFD5569C498F579927B1F482452849A7ABA91C32F774C68E2D848813F5978324CDCB6888F7FEA3B1B801DC2302147B615B2DC2FE4E6F6359C097AB795CC38A5DAE3479385C1DEEBAD33EF004BA6CB5AA0852CBD7D98F3A0A93246DD60A5A326D6C24201ABC6642E68AA206F5A4D4E81C31D330BD6BCF97EF7E28389A9565D6C798A49427F99ACF4A66001B1382521B3D7B5BB21C4A1EDD4EFE7BA7009D0C6DEB068DE11472A146CE2566E0470D93D8024FFC654627CFEFE870761C572201067AA789CC01398D11A79F4DAD4B8F997EC9C68DDAE822AEE3761D419691D0F3DFC656D9C05CC7594917C3277FB1F6C3AF32986D1B4592114502E7F80C9ED1116D597D4815EC7EE4E23F2F2475B9912FFF70A8E2943340987D4664C338C4C52AF0FBCD1AC49D69B2D795F7F319C4D1EAFF3E5288B0FE1C4FE71D494E9DEA886E7C57248C04594804FEEFDED86DD1E29A990240A5332E89BE978B07685CFACD6370A38BCB119915AF114FC315A7A664A288926630F754F830AD786FD5AB739829D845D276C6E8C4E392A0E2E9EC961BDE2F6D38FDE7BF5F7C79ADB2D02F69B7BAC0BE9E480BFC08AD09FF5B18CDB7F73005B1F3E94F87938D638E30769201A3E6B18E5AAA65F08D57A1722E72F8A41F804D4966126AC5FBA05FA105519CBDCE3D4E90367BA820349A61B345D35E4262AC15B172D6970E8FA4596F782B0C51CB01BAB002D63D944CF1D631F039FCA409656EB9B4F0AD5E55D7ECEC814C9E2F4B5BBCD5CF373EC3093321D2A8B29BCDBF521E186AFB7F384FEAFB35DA155876273752F470EB09AA42902C6DD942739BCB4D18144F0B68E1A23D383D4A187497D685FF18C7872B0F5AB2B07175EF531A020186CE683AF5B00E0A61783608780BDFBBA75AB7E2816EB0C0FE235D50F89634E551D3A747C620A2167595041B986E8AF8BF15AF6DBD0C8E8AD58CBF1C708B56E8D89294472691A65C80722E9FFFA15CADDB62B7306D957F6466E63855AE91351E576482BA2C4A2C8EE417712A52A59EA89E94A25C35E0A3E9D0A6EBEE1EDA9406F87FE105C3AF820618FB057638FF88F6FD59B8E687B2E60C947E26F4B5BCD7BC390B6A26FB4A6125E49071D8DC330BAE2A384203CAA2C466CF5E569F8DCE0A408DBDC403DD7290BAF206E15D182455C2C15B9013DC5B7C560EC4B318667B61E81DA3109CC9D733DE76008D0BB6FA4BA2FEBFC40787574F82B7E565420C3895F3ADFC80077B093608D94C52DD3864C0863FBFB32E6BAFEB2B659C83C5638BAAF23977F6D18EEC7043E0074BD1AC9A845D4BE996BF80E6C05082F1458D7EECE0075E8D492AA348479CB9BE12D6F3B904AF2B37B6988ACB91D97E9DB9419A03A12D17E3963E4247A1E7538071819A259A9E8A736EFED7B042A48D97615", + "k" : "22ECA566C6228E0D1B611D47C58BFF4CEC65582444FBA081304F2039C32D5C7B", +}, +{ + "rngSeed" : "DB00120937570D62331F4C3F19A10465231EFF46465CDEE336A0D46AA1E7493DF80F18617F9FFD0476CF7784A403EF4F", + "pk" : "81F27E76A1562BD2C206BA3087231983AA0BD65420E2B71B749605960C94319ABEB1E80AEBF274B27A9237740C07114614658C51D0C5118B9FE6D0064E9B47641AB189B2CE2086293DBA6054A1437D00719B5C11351A9901B0A15E4C7EFCFBBE9A3A7AC6AB157586C8D5B68B2D9B747B2461F2A2CC3179A70926423EA5AED845407846BB9C5C57534B66A6CB8B480C9A18453E047C58EF00CF652867B474C7B1B62FD7AA0D7B4C63D881B05F6A8D8549257D7B0B7153525D5B295E8BBBF3D36DA46A5D425601E9FA8EE7402535D553BB60547BBCCB7777B5E48373F2B38F3C566E7B98A85465590EE1C8CEF16E4515AC3B4C69F99CA7F3495254C345B0405FCF975BB5CC26A1FAA82FE109F8D670F17164F25878A9E8834B4271F75338DAC56CA7B4BB3B56AE95444AF369C20B582EDC204928037434C3C5F8C372FC9449A773261ECBAA4DDB929F148BB6BC471D2A72706A1F621CA295EB8B44A83A4B99C6F3BB04002B2D6ED42FA5418BDCA5A07F743754882E2EC966F44235FD3B48C1BA874D8765EE30156CBC0456E610C5B02C8FC3B6D305AA23A5528E77AEBF2BC3696A37C438A2A1259054C3537AB8798AB9C16C2B9BEC71A861A96AE2387955CB95FC4C984D2B936BE897CD05AC3524B845A2AED4BB981DC47120FC9E4C6476E7847EA69755886A5C85CB059AD0CF05B0AAC6609104E0449E36815EFB9C0B232C7E5B9B80E386A8AB12BE22A72E0A4EFB447B253C65F619C2C85A878A54457D272D2E9A32D2668D9A02089A434A1BCC4CDEC25F909640901AB4EA97128850335E63882F363EAE699599A1BAFEA68C9987882751B545795ED6428162993B17E7A7FBCCBD2115C9CDB83C9852912FC21BAF53082FA41AE41723A8E6A8E6A3C008DC8B8B6250C7C740AD2A3B92676960DB68318C3CF24B855B62B237B97DF54C561B72B0BCA0877925734D650C0824AB8081802F166D8A294FFE8328FDE34B02436EA27086B870009545A71D56CCFDA986D00CA3E6931B85A53CAB3AA85A2184E55718A9988E11AA2F024076BFB36C0D222685977EC39702E4EB7045229E5256890AD87D84DC8DE5C44F8E73C65970216C6312BC22920FAC8E24A6B251103BEAAC8B4A911A1BF62870A33AD9986D81161A3E44B0F5C9508BE97324A97107CB15B2A2B9F6F71B80FC7B59D199FF7B04652644F10156C2DBC33EE34CEA079E6B718FF4E2BA10858A2B33827F7019BACBB952CA83A8F38D69422431FA722BF31683E3AD6E1784EF9AB210391EE600C2D0C690D739AC5A581C4F5660576BC743D79552CC833222B43E45201888A3EC82194DC2307A07B8549C838BF4A70F9C4F8CF5868710CADB4636BF12A257A57C344061B9F83DBE9324195651020C2F02574A2DB4AA4EF527E5A66FD4758382F96E52D84472852A30B49EE7D60698F4B9B6E9003F475623E345E1DB767B143BD30BB5273636CA7926F434863CE41813767082873AB5365DCC72A251C035DA426FE6DB4AA1F34FFA45C9277327A7125C866546BBE22B9C09C054E133B3D8B3FBF18832248E5A3198C89794C5BA4E6486574DE79CD67626EF2953007431AD08895AE499CC17111F76C002322A6602B677A922FC450971FC90C0B8CE16DBA195FA80196569FE8B87FE060311867E6C6ABC87F2351F4B0DA1F837EB7830B9319498F36FF707C80926158B84A934400F63911B5650C6D205686F7BB7D415CA9DCCA9A94C5706945580F49EBA773067EAC6C989A8E1D84D2586C58E70793933367DA73EF0509E27A97F03C28A10086D782A3EF2251D08793748357F411200B5803F0C76C886B35BFEAA68544AA038374F868C474F0A6DF1061DE88886A1241F090AC4C7C17F6A429F5CA400E8DC98554C56363C8FCD728A1FAB7C0007C67915B7D793C0EC5514C8F6A394C8502EE3C63B73B26DA015C370826278AEA16AC479884AB77A2D3C0B147E93181167BC1980627B46B7D06509D7725CF1085850A53F442C226CFAA24C8721DB0C137C7A72B5898CD2137839202DB535CD8AE76E42219E49EAABE2FBBB643742ED91551CD54F1DE16F63C953FBC7B5849CCDA3167660FB28F2A6AD8327A6D6AB649EB22CCFCA574733CF01663FBADB3BE7C33A482C13E50027D76A134E114C54380C1E84255060944DD10321B29149922BE789EB0A8FB7721FE98A1E0BEE89476E7EFD6BA100E4D6C896905FC524E7F985", + "sk" : "7445654A55AD6ABA3D41506B872C53FBC83988EB1AA5D4CA645854AE700CDF3A1FBB448B51D83B20C3BF82BA45000357D3820A0CE20F011581D2A4C4F186522D568861554EFAFB1C843296C927A3C29A19BCF7037B497F6ED90706305BFB28B06818549E9B7700A387CE14420C74A5151555DDA18B216B0846C5A90CBC29BD623BDC8C74F2DBAFFF76A1A53CA1B9137FFC687C5304A3FAA42772C85719585C39FC923D7C253DFA471ED7260394134C058B8C768B04123F3C955BB8C94A26D4B6B44824CBCC79F305516672311DA2B15BE23A183C323F8841EC76882BD161844C2829DA23482A3AD106225CD444F4463072F096740AA4A72C88DBB9B393289D91B85B20DB1CC38096C0BC6DEE84A16068A80D759D0D861A6EEB11D82A2B1B6909280C32BA42733D259AD3BBCCD3E0BF13446B0BA77DF35085F6494934555514353825C33A0FF41BD00545F607096B524519DC3FFD73A65DC1B9BA4AC7D32818BA2B21E1A300DA3248B2FB913154BE448C76195BA9CEE404B0F8CE458540A678984D034E4067065116A4C8580DA808B3E0F07D74A2A6A6B391ECA57039BB3D5643A5545394057AC7222ABBECE46E06E4684830AADDD737BAF64FABD956712B57ADD25A462441E362796D0796CB4C10706017C42C4070D8A51492B7C0DB033E29761E593927111A9BAC35E8E9A12A6423D8726237526D95E10CB0A3BF8B2302882C55EB92A69173B3A6353FC34711B51CBA08C3642C449AC9BACD0B2906A2B5A8B53A1BC64B810023CF4FA7C73B3779AB468131569A60409831F32E2D87BCB455C15B705DE96948CD9652F30619881879F3D043A341A3239680A6B12645B750E42CB736245FC83330AD7408E8B56BB535B865A9BD79549FBF8AC3468B9E90158B0A92C53A08B774B2CAF4A124B8785F26589E65346B7F4469B807292108520A02C9E5DA14C1FCC21FD526AEAC3088D94666B54CB3BB00E3887F34B0670FBA3D167B1B9088651A377AA8098C1F87888655B0BEF1364E39973442C1B8FB4396E3079CD244C241149535AEE7767CE60267A6BC733DE942CBC81E0AB46F19370E5A82A09CD724043204CF6372AC5BA918FA2105C54640E3B9BFB0CA60600EC5091236A44D7FC5A183579FEBB401872066A95B22CACB9492F14955843A0460102319A1C49980405BC947283F95643D0B63B80D36B7EF29097BCB057926B2583745DE85192A65070A0143BE745E0651775B84480F7B0EE9727EA738B1C36B3890E19AA4431C46A7AB29F273660983E5EB05810327DA1BC0AC5020CCD34BBB4765CD632E3F1B727483B76A0262C0617B3A06439171ACE34B482674A967474C1BF77536BC6819BB77AD40B157267C6648C9C05259F06C20AD7B814048C926C52E2C14682B464A4C2740A37C3434B7055FB99EFB813DF8637BF8B4AB530731F77653EC2AC15A174769DBC5E435AE8B4668D009CFFEA1716F38037752A007C788BA80976A319B5455BBFC41119AA24E1E43A0ECF02C4FDBADFA60C187BCA996F7B039692A6A03439221AA85C145C1110E22D46AE25AC7E1F99C68B7AE69FB22ADAC7446961E543532B5C10DFA74388A031C310275CB29B4A6F290B97C9FE8F7052AC51B759A75A9E552FAF29F10114E43237F3E758506E53FA110488B11B3C1E339A7C8312F1335AF7A8A456B581BD61D0AF384D0796D531B6AF20B2B08725C341B5D38737FCB055BCA240EF239C0419598AD303344722DCF2C5DCE35BB393B89DD876F9DC97020724C6CC75892F996B470B609872A127A3D73BBA81BA14C7BC0049A9BCD5985CA4AD15D20267F6E56088E1512491AA7B51A6E3AAA6D34F870EEDB3DB6EB03FF44B3A674750967CA88A0A1CB110C9E9566CB20B42A696E86F3711AD407E3A01C269600CA9446A87BAF63789410975376A5BCB801303B30CD1DF625129B44E388672356132C10B6A6030C1678797D157C55B4741DD925DF96374B16B8FB464D4BB39ECCDC30124248ACA11A2521BB0AF5AA53C61F29663B6E103A6EE6940CE05E071242280858A06930BB5413AC75A3DF260E070752E1818E12C221A69554A774507E892BD18B88A4672BC2FCB07302A132648D49C08D65804D1DA7324FB00F53B44E6539B941839FFA36C435498809C3804685273324147AC41C259B86F5A09781F27E76A1562BD2C206BA3087231983AA0BD65420E2B71B749605960C94319ABEB1E80AEBF274B27A9237740C07114614658C51D0C5118B9FE6D0064E9B47641AB189B2CE2086293DBA6054A1437D00719B5C11351A9901B0A15E4C7EFCFBBE9A3A7AC6AB157586C8D5B68B2D9B747B2461F2A2CC3179A70926423EA5AED845407846BB9C5C57534B66A6CB8B480C9A18453E047C58EF00CF652867B474C7B1B62FD7AA0D7B4C63D881B05F6A8D8549257D7B0B7153525D5B295E8BBBF3D36DA46A5D425601E9FA8EE7402535D553BB60547BBCCB7777B5E48373F2B38F3C566E7B98A85465590EE1C8CEF16E4515AC3B4C69F99CA7F3495254C345B0405FCF975BB5CC26A1FAA82FE109F8D670F17164F25878A9E8834B4271F75338DAC56CA7B4BB3B56AE95444AF369C20B582EDC204928037434C3C5F8C372FC9449A773261ECBAA4DDB929F148BB6BC471D2A72706A1F621CA295EB8B44A83A4B99C6F3BB04002B2D6ED42FA5418BDCA5A07F743754882E2EC966F44235FD3B48C1BA874D8765EE30156CBC0456E610C5B02C8FC3B6D305AA23A5528E77AEBF2BC3696A37C438A2A1259054C3537AB8798AB9C16C2B9BEC71A861A96AE2387955CB95FC4C984D2B936BE897CD05AC3524B845A2AED4BB981DC47120FC9E4C6476E7847EA69755886A5C85CB059AD0CF05B0AAC6609104E0449E36815EFB9C0B232C7E5B9B80E386A8AB12BE22A72E0A4EFB447B253C65F619C2C85A878A54457D272D2E9A32D2668D9A02089A434A1BCC4CDEC25F909640901AB4EA97128850335E63882F363EAE699599A1BAFEA68C9987882751B545795ED6428162993B17E7A7FBCCBD2115C9CDB83C9852912FC21BAF53082FA41AE41723A8E6A8E6A3C008DC8B8B6250C7C740AD2A3B92676960DB68318C3CF24B855B62B237B97DF54C561B72B0BCA0877925734D650C0824AB8081802F166D8A294FFE8328FDE34B02436EA27086B870009545A71D56CCFDA986D00CA3E6931B85A53CAB3AA85A2184E55718A9988E11AA2F024076BFB36C0D222685977EC39702E4EB7045229E5256890AD87D84DC8DE5C44F8E73C65970216C6312BC22920FAC8E24A6B251103BEAAC8B4A911A1BF62870A33AD9986D81161A3E44B0F5C9508BE97324A97107CB15B2A2B9F6F71B80FC7B59D199FF7B04652644F10156C2DBC33EE34CEA079E6B718FF4E2BA10858A2B33827F7019BACBB952CA83A8F38D69422431FA722BF31683E3AD6E1784EF9AB210391EE600C2D0C690D739AC5A581C4F5660576BC743D79552CC833222B43E45201888A3EC82194DC2307A07B8549C838BF4A70F9C4F8CF5868710CADB4636BF12A257A57C344061B9F83DBE9324195651020C2F02574A2DB4AA4EF527E5A66FD4758382F96E52D84472852A30B49EE7D60698F4B9B6E9003F475623E345E1DB767B143BD30BB5273636CA7926F434863CE41813767082873AB5365DCC72A251C035DA426FE6DB4AA1F34FFA45C9277327A7125C866546BBE22B9C09C054E133B3D8B3FBF18832248E5A3198C89794C5BA4E6486574DE79CD67626EF2953007431AD08895AE499CC17111F76C002322A6602B677A922FC450971FC90C0B8CE16DBA195FA80196569FE8B87FE060311867E6C6ABC87F2351F4B0DA1F837EB7830B9319498F36FF707C80926158B84A934400F63911B5650C6D205686F7BB7D415CA9DCCA9A94C5706945580F49EBA773067EAC6C989A8E1D84D2586C58E70793933367DA73EF0509E27A97F03C28A10086D782A3EF2251D08793748357F411200B5803F0C76C886B35BFEAA68544AA038374F868C474F0A6DF1061DE88886A1241F090AC4C7C17F6A429F5CA400E8DC98554C56363C8FCD728A1FAB7C0007C67915B7D793C0EC5514C8F6A394C8502EE3C63B73B26DA015C370826278AEA16AC479884AB77A2D3C0B147E93181167BC1980627B46B7D06509D7725CF1085850A53F442C226CFAA24C8721DB0C137C7A72B5898CD2137839202DB535CD8AE76E42219E49EAABE2FBBB643742ED91551CD54F1DE16F63C953FBC7B5849CCDA3167660FB28F2A6AD8327A6D6AB649EB22CCFCA574733CF01663FBADB3BE7C33A482C13E50027D76A134E114C54380C1E84255060944DD10321B29149922BE789EB0A8FB7721FE98A1E0BEE89476E7EFD6BA100E4D6C896905FC524E7F98558672899468FC0A35E2A8C6FCBB35B2912E4AEFB8C396BB9738E3C16C95CCF75605F30457945F8B1560010C71B40717FEE3264A27EBAE2AC8ABC16267FB0F3AE", + "ek" : "F941C814C3AEA3AF7B4BC6F96D9C252542DBEF202E6012310CFC30FFAF548B09418BBAD2920D3AE280EBCAB51F418E0AFB61391338CD065C345FB5A8ED5BB71AD7CABAC571A7FBAC7355C3464F01CCE4BFE7CA2E8F1103BBD9E8697E52FE47733321F8F05C6517D5D03C7F05E42981C8419E09A47B145EA149FA03EFC9442FB180044D4EBD973E61FE21EDC289D650C824FF7FD641D8B33674C6FB8A64E16EE4D66C86AF6EA9C4B19A1B6CFDFCF850F9ADF5FBA24CFDA164560900D0ED42EB80C0D1BC335D620AE40F0BE06BEAE832DEE1ACECF29C29E6834E554FDC2E28AC8D8D45A7037CFA971002A3628070B159280D6684B557D13BCA4154F5657843AD4AE770FAE283586117DBFE210EADEBE906AA8F18E7287FEFBC56447DD3BC0D74E733560EA3AFBA54D1084306D28096BBA897391CFD26FF191592306821C1CF48FE5E1EEA078952446EA82A04265D1F09A2915714F5DB6F8BEA2650713293368DEB6F30388995FE1D910CC8316EE4A1D6110C9BCB8FB459FD8B65F98C60E831AF706292559D7FD73F20D021A9965824F1C2DB99DD67ACD8AEA6BB1A1F987D3F25A3556D354D45B5CC32C4297DE6281BF8979060782A0497B11F92336E58CB91AD6022799F592FB32AE35A8987FD682EF6F8BB8381C4DA2F7DE11AB079084C9736D9BFAC3B992BB75381F8D89CB3DD6DCF02388493434E8475D79BEFD4280294936B89B5731646A4A94E3C95E01AEEF6AC598826663CAC4A7D1AA967910F81F2F5E19AFC0543543164277FEEF977038B476A9D4EED48116BD76A4346ED11EE5F731BAD33C9D4BF6283A61451EE62A054D42BC4A3433A9D54C13F8C227CC4AFC8FB8A4E7244336F6AAA371B5C24DA3209DB5F33E2BCD26C5BF3E9F1AE4D9F9FCE5AFC7559C4800417CFEBE4909972583DAD60E2AE3C09487E67C50DE85FEA74B5B8407A34323927B1C2F3836D28B31131AB44DF1A7B93EF8C5497C1E7E5050471F2EF810035B80B8557CB0FB412B33AE3AD7B19111EB5E58D30531C4D76804D1FDD1072A8937717C1F897485CC595A12FDEBA0E30750A18FA8FF8B34AAEB08A9D990D6C8D8F437E96B78EE6E49EE370D0CAC4E5988A34AA7BF991B99515202C2731EB4D986F4CBBF15657261F6EBA212D5641A735573E72052178D3DB45B15B25440A5970458249A98AE0BCA6341D54C192E89098BA19053B7E08C4023B0FAD66852AB54300E1D1DE7BEB82CF10B4A83BF15EE5238A6387FEA428B5C2A5E2F175DCBF053085F4E724C1798DCF17B409A8F96BE754E636DDC912092FC4FB6D17EB0C1013369BB20DF51E7F55C62B3665E80CB3B036A55DE5CE104B5FC0A3EDD34C0178257DE697DB666405D56DD24F6844CD9A4DE2B6EAF8BDCD811ACFCF341FC68E564249A6FFB4D915AD93BBE2A4AF43F6753E3B009D98054FBDFF04A088FC97B4E50BFE40B72E76F5A0E4A33BA02CA008119E38B3A8895890258C3B195D31D7F53A9E82258F6061681DBECD002FC9CB7B5404C46279991EECEF0680664A7F82F2E80BE0A1BAE139F96468057E991D6F2CF7411CD97713BF469CFECBBD7310F61C5CCB19CB049A25E4D0B1AC56D94BFD9B6DE6E2B86802A19748ED72499B1CE487465D61521F43928781C32A22EC54389B58DEB0DB86D43B625F97860E0EEAF6F9F207A10FA2146A0DB5672D540DB44586B50C97F26E21D8EDBD3F98EFF6E4E99128373B7D6948B3DFACA9A7EBB1A0063895782226DF1547BF0231D60695B8FE2790A797868C457F58E489D5DD9F5F68A85E790726934867AC8BE007D7ECF14CE955419ACB181182738E872F9C80906C7FCC7B955A41205724FC9D9040524E926EA59D872DA57019729DA8BF0AEDA18A62035B927549162A791A1FD5FF04D29EAD56D8B67C22041B08B4F8585AF4574BF7A38B836C3E520825301B1E38CB5BAE2D0D41C9429D399703A55D61F7F763332073943E6F0C0A2112EA928C6183FF66FBD407E82522628B6EABB5B99F2EF3EFEC80B20CF423833F7C83C271C639A16DD01BB9BE9B603C692E515815030BFDEEE1359B7D56A9D08D1F8566CB434A5F09D37B0DC7556401BDC66CB854C7932F874FAF9DB5EE9E537C1DE3D8F30F1DC0225745673B1765D884D79D1B527CAB9886E8E20ACED261E1850FE5F3F4D36829940FCB153C6C64453BBD9C04EB0B59871416F0C9648FC84FEF8C92AEDDC8ADE758DE0F", + "k" : "BB6CD66BDDCA2310F511B277B0306B484DE28458F3EB37720B988288AA722162", +}, +{ + "rngSeed" : "BD26C0B9A33E3B9B4C5D7EA32D5BD1FC371015BE163C86F584E49BFD5362C8D8341161CD1308115B2A03B7E5EADDD418", + "pk" : "33651904E40D7B863A34774EE1E401A9A24A960045D4537E5124921355CCE831936F307C7CD807EB376CA1B640E7A76964C0195B6848B2CC9F832AC0C11C3C3C7290EE182C46BC1608C49E809B1C24A7C738845E9AE972D70C5ED346C46CCC73E0E251B1B57368B96DD71CBDA55366585011EE659A2F081A7288C873C8A98964131C078AADA0AD1662BB0D2B0A1555A3C84555C593231D167D378BA606257FD3958BC24B47E8380DC370C374A869413547D0703D28E4B5EC85CC0C897F14D5B03D6520937295183CCB1059821C2B866E755E24286634EC088522941516C592418A4FA872B2F911018843D7C877DA76C1822246CBDCC046695A1E93AFF063A577FC0EFF56B27A2BBB56F76DBA2B34B6A6765B78493F514661A4A83B58B42E4B96B471068682BB73F535E32C8FC7964A978B47BE9B23CDC2B33CE980F66A033F8154BF24B73147152F544939377BA2ECB5A288276C712F2317AC69292EEA9005A74A3FE336AACC4257E46395FA9A96A3FC9172B5229C393021E57265D017F6E7A5E92066B459199957CF4DC653AC222BF0B953C3C4CCD5F7463DE539C024BFCC9475CB3437C22502FE16B909F73B6E733C6DFC6D87CBA8A13220E823A46ED900C7649494006766A23CEC36AA46756D3A7124BFFB2AF34C586847162735CA2D1B259F5C1EB0912AFCF6846641984763266BC0ADD6D60FDF5B6FD87343A5D59C108CC663D8B700AB1DD5C0AB60FB66B764201722C9C2F5B2CE9A88162C3135D44CA9A735FC90B35058BBDE332063820F3085CAD54C4A8CD8708D43B871CA2B41D0CFBBC066AB45BAE33CBF2700C67A5A62CBF1CA19C2431B6C52AC476FC2EC4C00EA9C14CBCEE11B1232D523AAE8AF555958C3089C6C45B47BA58CF1F884E77893FD296CE80584A76ABBF2330AB058C2AF770E4468097CC20748A188B6620F128912126A899D7B0DF24B067A73C4329314C3F6B0B9B83FB450414CF0A2FFAC6FE2AAC17359B20288A14272A952642958058F04B24A69B93492BC0DAD67A7552B37F2417CF7E5B889E97B2D02980F7336F8E0198123C855DC1A40BBC5A93779C7C7BE7089A8440214B3542341E56499AC1F6EE61B981705258C5FF6E74637FA0E48556BD3542EE342891EA4B4DD5A4982B0471CE63D61B3ADCD1197DAE05627C5993B502BF3025F6CB8792F32264184B362909BE8BA74A1B6674E253F28B086189115129919821B867CC84341E3AB43B350A5C79D5AF47B4CD228856189454538D362049C710953F33678C28F3CD9812D731AA9F95004B94425C60CFF24186F644E749A6963B77760BA491744CCADB72E23653A3A08A1F7BBA316A9C83E3113CB49022DD2BE9A4A69C7DB6145377289C921EA0292F3E4AD84E99ED72696DBBC97A3644478761D6083AEAA59004A9694D545835549CA3357CD9D63007CDBABD6E1A0B661113CEB370FAC0DA48B893B3C8635619E79F4CA14431CD9A1BE2F34AAF3BC059DE3A3D9B630B5542F38A5A1712C67327C893BD64883B7701636B0576223C4868F2195716C3499A4295B0387715C9CA4FEB3B1BC08C6E09C1E809988E2F414F0B0CCE5515F43B50C2DBA028E9AC11E6368062C360370BB7F5655A3A75C2E7AA86BA9B892019DB150BC7DC881C5E3B24E414780512BFEFBCE95C914CF060A76FA4C34359C634A1A11C40AB7B56AF1D19E2732BA6F3CCEB93CB31E08C93F2A9A33841D667079F1715A56013C0E68386B639E414540CF2B13650CA9378234B94C24BCE9A9CEE8C2ADF4356F246DBEC0BD9B371DDD296EE623603EDBAF65E734504844AFF0438D163B27C34D52163D736BCB42B0A1A67067A6E84BC8F849531A631FC55046DA2B31E0B99B938D4F8B239384BC2ED54E46E17E9A8297C2A16775F77859BA69C759638FEA8FC2057B5105952B34058B329EE7B2B08A69B00962C31A5106A281890AD6257DAA8C6AD5854EEC7E8A203CDDB935AB5545E3E57EE5F78925B1531E5C4593A7AFEE319C5215645905B50CEC48961B2B6C1727B4794ED382C66C11B67804B18C3C0000868EE4E3CE4E9790B681161B2CAC3F8A1A419892608814AAD65880E683FA75CE66335831A7BBCC236DD6F2B8C63560FF1939B2B56B97E87049EB4C65F42D640C0D8FD5841E48BCBD1815EF0C62DA099F5478BB93198EF28D89EC6714B0F142ECE80C6A6050D3AA936C25BBED1DBCFC99F39B4805782B", + "sk" : "EB8809301A6603D8822F86B6B44286F1E1B83B121B3880C35731A1215722562A2F14D15364B7AA6AB35503331DC63BC435F31A23EA1A7DD060195AB2626245FE2853A88244B7522BF9FC39A76B188C7260C9C2829F7A6E1964CFC8C28F45889958731F742ABA74993C2A75BF4557C71FC5390067AC00A39FBB7049C657056B168A83899E94BBB38ADB1837B53A32E74B8EEA1A2CC198105CC32932BC5D4071B06B1A6CB7587DEAB9F7528309A64DC5D696EA00575BE8AE3788721B061E6F143DFB73BD9E2BB04CCA4074894B067A70270B7FC8762772890AB8D3B3A5545B9C48BE169C1FFF82473B250A25F15F0BD7B142C97A3400233C57B8F5DB3DB25817880A4490F04977A605CEF4C151593BF769100EEC456EE7831A526066E757F7844F660392F6F91372DBB0B8A3325A498BF7291B3EE048FCB61DB8CA6CF8FA0B98671894E95094B325B922103B564189937C1F032488D868405800264781A702878268A7C19B8C39899262C246A8B4CC91EB5AFBC8765D23A40B40C49DECBF917737F14765D0E7CA19879236551DDCE824C22676F754444A829434A01B264019D970CB44F1B8128483C549C329288C9A55991E12BCE3547F22D4088527A8D1322FCE360BCDE1309205B2547B32E917A39D4846E45C5D4D16AEC4435AD8695AD384236BD71336358294652418A33839608230270AE247780F16BA3FE7BA2DE37063B66402D360601BAA068833BDF2325F144AA6528DB92225360032E5199A8E61ADE5087DBB741E2903C245A1C95470C795BC0AC363806CC6BE3268CB51D333100A21F00917BB3479FED22F3D263763B406DDE76514E929F5C604DD7536BE6305D6035F31790C40AA6BB5F17EA2CCC9E07C6262878FFCA72D78F4208BF804B4C322B1287011A21DC54B81BFA22BC77AC1A0DB6DEA6C4CB7EC49D8858138F45D9D200A52D33D13B533CB6447910CC4CC21A0B9350220845C1C4B64B5C84BBBF7C7C3A4932000559E2B068D2CA9BF44B0F7EA760B225A37E78A84A5B14C5A2FB926AC622B8F86C7AC7734A82125B18F1575FB3968A4634D9633CA7B0A2D3E56580C34BC3B13741406BE06396E66E64126888055ABA9C8CA2ED2BC344A38A710DCB1E7D72D70A166DABC79CF79439F5340225378E7E062472584A477CD67C812733B5D57127D6CF9A6855B9A4479AF6870A6090CAED93A642BD91224F6B1D1F13B86582A5A7C227BF21B1D7547B2DC398FC88158E87571E826BAA55933459521401C432782E2112D1FD7ADEC475178AA2A3CE59C96DA6449B75DC5AA37201CCF404C5EFED99C7B266A97D46494F1316F0781ED830DA8484A2C5174403C0EFC2B1010D9559329C714771B7BC7023E9C89E3F0A601D439B8BC2D3EA1B01A991FAFB409CE994868BA5ECE31330118161CE9A6C08C5F4C65AF7334920B659B56D2C658CA4D9951C4C0B93F43A91D580B81087838AE28BA99C1B916103A91709B384840FA4A047EB94ABF2C96DE847D04E2198E363D248921A2537172735537878BB65B2B4ECA2D9A1C4270A8A00AC667E7F9192F7C46C244B6B7676086F18EED246BFC10855E9591DE3415142A8621F98170FBB55E608E10E38B6CE140A3835172387EA722339B1C6598E53D7FB694978BB5A3B5CADD1822374071AD6BB1A1569230C6042C9CB9E205104BC6827D3B9B1912A3F275CFD31A28B7291D4875C88954A36E078C9F72956E874426632A9B2B24132A1A45306A4D8CAEDA6A2C401713D4176C694378698A77284B7A9DD016CB332DA7138511923D9F3850DDD5C6EF5BA28C357BA766B960E351DF862DB600320F996943E10046891F27B2B243EA71506B755F27C032690713C42298A16096D28CBCE4051633974F02ADECEB95E1BC264C45944D752E23B000419C2B88108A0320B3C86204EDF5914F324B221BB9884499603137342B8D102B96117C88D6B589F9545B639CC18FC2C89D144107610FADA81B1E2344A5CABB357ACAE302BEBD71159BFC23906BC2BC781A76A68489A73DD5235738B06F8BD54A8771257513B6E1E74DFBF774B1E469E67086B84C1A6FFC274B73633903AEBB05911FC7B99151A8A6D0ABE8AA466473B2FF2155AE2568C23576F70648676BCC1A6A19E880267F139EDEB973A8A9A59AD2A8EDFB5CEA9A0BB39407F5153633651904E40D7B863A34774EE1E401A9A24A960045D4537E5124921355CCE831936F307C7CD807EB376CA1B640E7A76964C0195B6848B2CC9F832AC0C11C3C3C7290EE182C46BC1608C49E809B1C24A7C738845E9AE972D70C5ED346C46CCC73E0E251B1B57368B96DD71CBDA55366585011EE659A2F081A7288C873C8A98964131C078AADA0AD1662BB0D2B0A1555A3C84555C593231D167D378BA606257FD3958BC24B47E8380DC370C374A869413547D0703D28E4B5EC85CC0C897F14D5B03D6520937295183CCB1059821C2B866E755E24286634EC088522941516C592418A4FA872B2F911018843D7C877DA76C1822246CBDCC046695A1E93AFF063A577FC0EFF56B27A2BBB56F76DBA2B34B6A6765B78493F514661A4A83B58B42E4B96B471068682BB73F535E32C8FC7964A978B47BE9B23CDC2B33CE980F66A033F8154BF24B73147152F544939377BA2ECB5A288276C712F2317AC69292EEA9005A74A3FE336AACC4257E46395FA9A96A3FC9172B5229C393021E57265D017F6E7A5E92066B459199957CF4DC653AC222BF0B953C3C4CCD5F7463DE539C024BFCC9475CB3437C22502FE16B909F73B6E733C6DFC6D87CBA8A13220E823A46ED900C7649494006766A23CEC36AA46756D3A7124BFFB2AF34C586847162735CA2D1B259F5C1EB0912AFCF6846641984763266BC0ADD6D60FDF5B6FD87343A5D59C108CC663D8B700AB1DD5C0AB60FB66B764201722C9C2F5B2CE9A88162C3135D44CA9A735FC90B35058BBDE332063820F3085CAD54C4A8CD8708D43B871CA2B41D0CFBBC066AB45BAE33CBF2700C67A5A62CBF1CA19C2431B6C52AC476FC2EC4C00EA9C14CBCEE11B1232D523AAE8AF555958C3089C6C45B47BA58CF1F884E77893FD296CE80584A76ABBF2330AB058C2AF770E4468097CC20748A188B6620F128912126A899D7B0DF24B067A73C4329314C3F6B0B9B83FB450414CF0A2FFAC6FE2AAC17359B20288A14272A952642958058F04B24A69B93492BC0DAD67A7552B37F2417CF7E5B889E97B2D02980F7336F8E0198123C855DC1A40BBC5A93779C7C7BE7089A8440214B3542341E56499AC1F6EE61B981705258C5FF6E74637FA0E48556BD3542EE342891EA4B4DD5A4982B0471CE63D61B3ADCD1197DAE05627C5993B502BF3025F6CB8792F32264184B362909BE8BA74A1B6674E253F28B086189115129919821B867CC84341E3AB43B350A5C79D5AF47B4CD228856189454538D362049C710953F33678C28F3CD9812D731AA9F95004B94425C60CFF24186F644E749A6963B77760BA491744CCADB72E23653A3A08A1F7BBA316A9C83E3113CB49022DD2BE9A4A69C7DB6145377289C921EA0292F3E4AD84E99ED72696DBBC97A3644478761D6083AEAA59004A9694D545835549CA3357CD9D63007CDBABD6E1A0B661113CEB370FAC0DA48B893B3C8635619E79F4CA14431CD9A1BE2F34AAF3BC059DE3A3D9B630B5542F38A5A1712C67327C893BD64883B7701636B0576223C4868F2195716C3499A4295B0387715C9CA4FEB3B1BC08C6E09C1E809988E2F414F0B0CCE5515F43B50C2DBA028E9AC11E6368062C360370BB7F5655A3A75C2E7AA86BA9B892019DB150BC7DC881C5E3B24E414780512BFEFBCE95C914CF060A76FA4C34359C634A1A11C40AB7B56AF1D19E2732BA6F3CCEB93CB31E08C93F2A9A33841D667079F1715A56013C0E68386B639E414540CF2B13650CA9378234B94C24BCE9A9CEE8C2ADF4356F246DBEC0BD9B371DDD296EE623603EDBAF65E734504844AFF0438D163B27C34D52163D736BCB42B0A1A67067A6E84BC8F849531A631FC55046DA2B31E0B99B938D4F8B239384BC2ED54E46E17E9A8297C2A16775F77859BA69C759638FEA8FC2057B5105952B34058B329EE7B2B08A69B00962C31A5106A281890AD6257DAA8C6AD5854EEC7E8A203CDDB935AB5545E3E57EE5F78925B1531E5C4593A7AFEE319C5215645905B50CEC48961B2B6C1727B4794ED382C66C11B67804B18C3C0000868EE4E3CE4E9790B681161B2CAC3F8A1A419892608814AAD65880E683FA75CE66335831A7BBCC236DD6F2B8C63560FF1939B2B56B97E87049EB4C65F42D640C0D8FD5841E48BCBD1815EF0C62DA099F5478BB93198EF28D89EC6714B0F142ECE80C6A6050D3AA936C25BBED1DBCFC99F39B4805782B5BFB6D44C0E7348FBA37D50B05031C0489D4294BE6CFDC6F4146740E54FA5D690A8155459118346A84683DE346659727DA4B64A1050C5271E968BA9CFDF6029D", + "ek" : "9C36355B800FD768AAEBB3E0DB09999B43771A437AB0E2F88568A00A9A0F58473D1D5BD4BC1BF15731414D6093CFCB221F4B1D94C6766EE925341E9FBDCFB67A6425E2019B45911A98C6DD26AE1A12A20878539AFBBEF4DC645B98171FF8EBB050E009256688857C802DB2B21416E87FF7E6ACEAF6654D1DC64C8EF9A41AC15E129E8611589320472A133714FF283CD9C7A9D3D36E575110FE11D0DFE9CCB7526010CB4B680E08C3761F645EB759CEFC0E4A07523086448F1BE0EF2A70BC1310C31F058A42AE2882D1CB72CE80B76D0CAA0C89287CE2902BCB5F5F01564B8BB12BFA01C2C299FA1D1DD5DEE2EB0715E43418A41E9746F08A569AFF1C704CAA195D82D13708CE5D75793077320DA66B9E8F1196DBE5DBE6582B9FE99EB81021664C4F8B5DF74CEC1C9E7930BE106E1FFC810197C8F17B90B94E81214B4EE61308B88C9DE020FF5125E01B56EB601768335589BCFF7851A821CB95B38A4123A7C871436EBF3A0A6A08A257260D1DAABF7B85D40E35B821B6A7A71D000D54405B3B7E15825F942C6FC103EB7156D9E8839CB46C6D168B8ED97CC3C5EBF5FF1FE34A553FC00054F4359EFBD86BE6CD6D9EB8F3A32F17E323719B0797EEE43DAFA2AB8A80FDCFE68E7B478A472E6C36F661851510895089D65EE4FB1A72D2B136A04FFBD7AAEC639D377FCB76749C1B42DDBB60FE8BEA32B9D17B9D3557A229DEE0A229B45FBCC727485F61AC9B8F3FAD497172CFA8D9313AF079EC9D4504DDC0549D58F60FE175DE09354DA7667DB06B9BF0E6F2DB8D203629F4689FB3C5033DCC8FE1079F48FC89037F5092402E872C72B33A39BB1BDCE34F448FFDB504DFAE973C3035709D57DFE164EF098936AA97520C37DC0F1C276DFDD1D98B181392F064011B47B1CA2A9519E1D97AA963BC51D7371580CAB0FEBD4C1247B866ABCFB0FE0FD06BAA87FBB166190D7DB509C04075964D8050C304D33194E99BBC2040E64AD17354879053B02F687EEF3B67996370735E9350D1D792A758D5DB793D5763E006CA9861C0D27E5F1BD751DBB08933206BEF4FDEA149DE725D7B6AC05B80B58DB5A82ECB7E42853743EA9AA96C5CE6C9A5EE2E76225FB72B0824C465EB90F027C5EFDDCCB709BB39ABC601E476CE8D9D9B154435875B51A116B44EBF156190F7B17EC915350C411144A8E3A9B2A606E499A731862065CDEB5FC8F4BEAEA24E1C0B87A1F164558D58C8BAAAA24B887DD4B37A690E5454B14BE2BFCA36189019670638A699C257D5E04B1C1B6A2570BF61D6CAFF5CA8CD624C360E0523ED4BB33939CCE8F2678D1B5C7B28DCBA9D08313DE6715EDB734CE64471F21DF1A367EEFB1C0253FE9BA2E68DE94802199A7CD67C51620B578085E61D6F24FC032C57F46485B3E6F717B8C966530869711B51EC0C6B1D7E21177D67F52E9007D3B8E482D7B281E89A55E803DFFE605DCD6FA0D07A7420AB33DA22BF60EF4AB9CE00FE3FC50D463766C9C568C324B0009CD8C71F74533EF2AFE32819FCED6B09EBDCAD8D5E20F2C797C5DD16F60DE3BB682369AD621ABA7492BBB1F71A6E3657DB5DC952C69EB8404CC641647FAA8965A08F4FCD43275B98DC87252F54FC8B56E33B589440DA1E26E0D924504B828FCC43C24C3494D4DAB17A874841764A2455C3D4A5FF7EAA844FE61884D0D21343EAB880704BD3CD0AC918BDEF5157EA5F66F4CB5CB2466CCDD86B86D67D8B053AFD23605D48F71931B99BEC710D8A6266B32D6FBB4D3ED6D3BA9CD164B7A34F739EC089658F5F24D4A0DCC578B729ECBB798374231022A785A03956722DD2D6F6E3B0531D5C63B0AE79D8CDEFD2A618DE93D1199C1B2C6A0808D23984C8A8150F501B97FBE22478275957CE057BDF4E3C3596B00488C3F49D4CCBC09528A0AE06D0FACBA35D5E74A5D43F53F999BEEBA7356A3317F13AFA2E59DCE5C5B7F1B1D79C9230C406ABE03E9FA12A108C054C6BAAC618D72860B6367EED0750A70743533C6EC07C712CE60E69C7C8F3B7CEC2626B9954DECD7BD6891FC06CBEC6AD2EAA9C2983A0A3706F01A92F10C664E9832369F1E270BA52035D4E160081DE5BA5F8A21E045E586F1BC1F031EF92B8DC5E6CE28FEBBCB1E9EE69D227D42E98E96F0269B19344FB7016BAA9BF49B0B22B2D0030167F9E23F15CA7F70AF5E30B8B3CBE08C53381B306DEAB5B6FE9831DB77A3FC40DC0147E0AF3", + "k" : "C723ED3422696B27B38DD0C16183E1FF810E03222FA6E316EB0BA26C98CE7DB8", +}, +{ + "rngSeed" : "E2819EF86853BCA1B9DEE7EE1C1619988964F9A913E635AACF0D96CA6E0300D084329DABD8F149E24176D22757404260", + "pk" : "24E5249C820C83A86B66536C8FB371772408729447F8F2BD61FC63DB224D868B70C8E8AC6685C8E3BC2375049C25F941169291C38A0EB0F3CF027BC8324398FCCA99FEB47059E87DB1C2B723522D3F09CB8A19BF7B2B35DB5516A652B837FB94A6AC6701C479686AC758C381FA242D8E67B1E7F6B0CB04CEE5FCBE2BC5B266DCB55F1C72B091039596C4E4E50DB8741763C35365931BB37A3552BB3223938C6A876E54121FA489C502E14943AACEBE7A5E7747BDDF5C6E916095BEA36DFE8059CAC7ADC0DCB10A64BBC2812BBCEB001E22CD5438183F9B3249A27566098AF16782C6B503B987A6A5896C1BD82EF7D3C5C77B82CC797BD682849826981187A1530B4FC07173DDA9CCB8C5248583503A8B974E8B1CA39B1BEAE9AB516087A170BA4D12AD5E555F77F27C55C519226CC6B3246CA1328DB15648ED4394CC038245BB7D9EA48AF2350F0961283F195BD51304AF6653BD133E241729B5A62495C8C45583CD4C30BB1C538FA4F86AFE799026F86E1DE0024FF13ED5713A8806CB9EB6CEC9C94C4FC4ABB2569D9486507137733E681A5EEB479C8256CEAC1EF823B34995C65CF43BAFA250A874B743388CB6541D8346071F075B439620BCE761CBF1848953200543177E0154C9343B47BA3F5CA025FAD201BED145B7E8ABEC99A404621A11372C930713A013B0CF4B346EA6CB64620859D458D0E08B5D416BC86552C79B087F63539303C6FA96AEF18C6A61DC37E1E8436FAC43763C9ACB9B5955157CBDC15D356936CBC603F6ECA2E2A53163591B3D2257D67335CAF60B4223B8C0CB7C54454E3B4812E5760848EC0BABD9A0D7DA9E83719BB0D7395418C44D86BFEFF4C8A8548CEE6780A5388E36EB4F5667AC2182C213A577FA2C4616814EBDA8CE8A1C5851E0551D356471A8051D179DE078C9F12163B0234FD729C9B02C302997C13974B47AEC7573604D8278783BCA1A5F184F77047F3B1861B7E1C2DFEBA290E785D77CCC37E0AD03C199322C475191AAAF87300EA43F6A956B7D03B338B147CDFA14467B2850A73BA99C6B39D89EC6FA3052A9BFD0F6922F9B37AE6966C940370811AAD1572039BA3365D089016C21FCB64FE3D924F805336D49683ED262410594F8205BB2649082642314FC7065CBA9B8C4421F1BAC52F69EA8F96093F89342B879EEB785756587A4027680119D41BB559C758197D360342BC3845237AED01AEB8104490B9BCB4AC158F154B347A49219CA5A401F90D1C1F4F7BA521BB33AE0610767207F3C9FEB991E7CE444A42B33EE5A14710586523CC98AA53DE01801BF383E33EBC03900678750734311C349CAC283BA827FE39F976B3DE28610113291F61325B870384280C58AC9C48BB65C5D8A672C86B218E8A706D3B87F2341B95199956886EE0AB068D927DDD109AF491D23E991F4E8619E4AAE99053C4DB3514D380133105AD60885A9FA5FA80C144A3949CC8C33B591C776D5A7A6E9C8D12417B4C1661C867119F7006E6520462B63E1770AA6424DBEC6B9A0C2CDB8C8945D653E62C790D7857681B479FDA12C8894640AAB041A044D897C565CE882AEEB8CAF42630E10AFD12293FBEC9D7EF259BF881C92CC7706AC41626BBE1D17373E57B3A86A3BA62CB6084869B58C659371C110930B6C75626651971641A899645846F96081B00F6C29BCF8C646210676BF266467D90EB393B64A1593B4579ADB0B549E6648DA5C9E2EB3BDDBC78C468912DC674B126ACD4448BB40BAB46EBC8620288253156D8D39ADA1B639C6F69D34E9A25E6B6BF4241BC00B5968282BAB963820FAC7159001FA414DBE2B94A74158AB43C6A43519F9A34A716CC07908452E5A0A517138CF46220243BF2E27AE78835B73E0720222700861136B2A405A241E58F37F132C588A1102A5344B704619666900C73990C2145497565D09E984F2689E315AB204C59A360534A641228768A9F1581532EA9D7717B8D8069158605508A24AD1C71FEE5760605BC2D619B177985CE89CBAE0EA5EA335529A20225CF83744D807B886CCD5CBCBB8393D5BF144497A4C454A2AC7589B5315937345CC02372FDE21BEC80C0AC8912D28B3348DF2A88C35B7F384809F24665600583530226B50A6429217CA211946EA66451C9092E7C42B309A922465561B307F8912F29A1EE687B1D96D8C201BDD75A34E09D954A4267F21490C0EB74AE98FAD1B5A3B5D2B9F70E9", + "sk" : "DE2A5203A614274820AC186BEF852A92160817520323D112EA9240ED0BB381DB4B012A4282775C91055800516CD465812722C6696165D80188C1F7BCF2F99CF18124A2905B6E3A69185C0A20F61913402BC2622A5477BD455046A032823DA983660BD0AA51238DE42A86FA9654F61CE0EA1E8F865BCD9407B879CD54C8520ACB99B74ABC1A6A23B767AC7C9449613A4A4B5003B2000AA52C17CB6652CE133ABC641EAA34141FEAA745C06ED7A1273BE6A66EB6779232635C22B4030252AB30AE3C13291513438F2B19C4A10CC6F884D093223D2B12E460B49C191ADCFCBD4F82C67EA936F946391835B2752CCFEFE46230D84245EA8D8C799EEC979F98409F51A65CBFC62A8C3A889D33A72EA24C96C094257104701755949524D5D4ABBA117A098B16DA589C47E5415ED0920C4B2B5AE0BCE2616C5781A903953D2D768EF5C58431984F671A3B31953940A6B52F24658CE943FC360FE9B0C9F9308CAAF7A04E3779EF5CCF99A505B2B27D1C0B68F9F2254752820F6B721D55BE6A205B3C832213D8CC015A14F5895D8AD17A14501ECE031ADBE36362B1C475C7CB2129863838AE80CA94D67007E3B5668EA415E5AC3E66D1AADC76021C4A47C1EA8C41423571A553D041A07096CE6548511CF08E108893AC1C0AE3990559B21952E5CDAF1751052425F483C88A3356EA567C717C75DFB70EE49B0BE7F9CBF172AB7DD22172D40214BB7C9F22801C3645C8D075582965EB02CA9DC68DD6C3798D28162DE30DA699A29C216220E35F725A14B0708349E4C87F726755B68F632918DAA2C83836B8ED34A542DACED4A46351F337B16516B853BC2A44337710043A58A83BA5870AF51AF1252B83E69CA81539BB89AF01526DFE7162665B9347D441BDD77B2E4A3665565307E65FBDD341B0B154FEF5AA7EA530C93362A0A4766AD13307E90D1DCC2A2A37746E881D57A718E2964FA80080D9F28074121893C95AE850C61028A6E82CAA571A63B7D85C37290B61EC6EBEE839DA040FD1D5B359D9BCE5AB54462242EEE31892030F7402AAFDC1A2575000AD636337EC69537C4B61669547859875A2B94F13AA723182F9424E8A95051F10148F470F1D04C9C444641D4BA30CEB312BB89DCD04BE5B421FA5D7327748C7A37ACBDCD73589A94070635EA6198F014B4471106862EA794D2C8EBA828E95D81F3BD226247952DB967F72AA44311438D4D995B3C6CA6D6233705A311F095A6C9CA8CEC042087C8071D00ED4ACCED97053116A8928981E61C5B3BF8177E4D99B4A130999066729F2875DA7462B7827CA00980EB96D3ADA528778CABD214DC0969FFC38B795512BC385921496A27B1AC7A099989A22C173A06DDC4B81B2365A9C6A160CB36F70FA4EBCF22C77E477DA74A7BE867394E5168B744DC03A32FF21221F877421A4AEC9E9A2BCEC7E46C88C2EF550333787DFE664E767124C5B0F09F8874D085324FA2EEE6A127CB2A3C6936F649719171116BDC8A6DB265C387930BE3A1DAAC267B838640D44C8BA75537347735DE517582C9D8DA18666942DB6951A4A7A2EA8F09768D026734C0BDCF7983F877E29C42F659873114669974C9018E7392C4500A45BBA4F3C834275C84289C23FA13CA6E927C128ACCD480225C79247982B811B885062022EDA9B448061AA908664400ACC9B7F34284D98D526FB96336B408845D85C4BE2B0215B0B32547C5F4B7E43FB465A358F6B1297AFC22BF08B9307FA8E5A1361B03882A26798106526FC136CF93438B03601D48A145D58998F087D0C4386AFA0C834A91AD3121DE0C57DD7C117FD339DDE05BC09E0A157C9C638D8C1A1D10687FA3EEED68EEE7B3B2ADC8B970BC0A0820B14679462C1113221CDCC045906618DDA5CC340C448BA0038C0BBC36DE75C00FBCB11F55E6532504FB2AD08E59AA3C65702547D04A02C5DA62286A2053A75975C38C865D3BDDC9506FE7C7081345700DAA716DA27B789590360B5C6F5B9F964921B7680ED159899829052987536F4375A8C5CA9E322E05A3D11F58BEA4B1DE4191667E87508AC279F4757A54393130B04675C312314218AD0C98038488BD501104989055BBDE396CEC47790B462B13B00A625A732959157E5715B16F4AA25582B7728C427C5758D25191B5B42C33B5D096BA301075D7C515AD195AA24E5249C820C83A86B66536C8FB371772408729447F8F2BD61FC63DB224D868B70C8E8AC6685C8E3BC2375049C25F941169291C38A0EB0F3CF027BC8324398FCCA99FEB47059E87DB1C2B723522D3F09CB8A19BF7B2B35DB5516A652B837FB94A6AC6701C479686AC758C381FA242D8E67B1E7F6B0CB04CEE5FCBE2BC5B266DCB55F1C72B091039596C4E4E50DB8741763C35365931BB37A3552BB3223938C6A876E54121FA489C502E14943AACEBE7A5E7747BDDF5C6E916095BEA36DFE8059CAC7ADC0DCB10A64BBC2812BBCEB001E22CD5438183F9B3249A27566098AF16782C6B503B987A6A5896C1BD82EF7D3C5C77B82CC797BD682849826981187A1530B4FC07173DDA9CCB8C5248583503A8B974E8B1CA39B1BEAE9AB516087A170BA4D12AD5E555F77F27C55C519226CC6B3246CA1328DB15648ED4394CC038245BB7D9EA48AF2350F0961283F195BD51304AF6653BD133E241729B5A62495C8C45583CD4C30BB1C538FA4F86AFE799026F86E1DE0024FF13ED5713A8806CB9EB6CEC9C94C4FC4ABB2569D9486507137733E681A5EEB479C8256CEAC1EF823B34995C65CF43BAFA250A874B743388CB6541D8346071F075B439620BCE761CBF1848953200543177E0154C9343B47BA3F5CA025FAD201BED145B7E8ABEC99A404621A11372C930713A013B0CF4B346EA6CB64620859D458D0E08B5D416BC86552C79B087F63539303C6FA96AEF18C6A61DC37E1E8436FAC43763C9ACB9B5955157CBDC15D356936CBC603F6ECA2E2A53163591B3D2257D67335CAF60B4223B8C0CB7C54454E3B4812E5760848EC0BABD9A0D7DA9E83719BB0D7395418C44D86BFEFF4C8A8548CEE6780A5388E36EB4F5667AC2182C213A577FA2C4616814EBDA8CE8A1C5851E0551D356471A8051D179DE078C9F12163B0234FD729C9B02C302997C13974B47AEC7573604D8278783BCA1A5F184F77047F3B1861B7E1C2DFEBA290E785D77CCC37E0AD03C199322C475191AAAF87300EA43F6A956B7D03B338B147CDFA14467B2850A73BA99C6B39D89EC6FA3052A9BFD0F6922F9B37AE6966C940370811AAD1572039BA3365D089016C21FCB64FE3D924F805336D49683ED262410594F8205BB2649082642314FC7065CBA9B8C4421F1BAC52F69EA8F96093F89342B879EEB785756587A4027680119D41BB559C758197D360342BC3845237AED01AEB8104490B9BCB4AC158F154B347A49219CA5A401F90D1C1F4F7BA521BB33AE0610767207F3C9FEB991E7CE444A42B33EE5A14710586523CC98AA53DE01801BF383E33EBC03900678750734311C349CAC283BA827FE39F976B3DE28610113291F61325B870384280C58AC9C48BB65C5D8A672C86B218E8A706D3B87F2341B95199956886EE0AB068D927DDD109AF491D23E991F4E8619E4AAE99053C4DB3514D380133105AD60885A9FA5FA80C144A3949CC8C33B591C776D5A7A6E9C8D12417B4C1661C867119F7006E6520462B63E1770AA6424DBEC6B9A0C2CDB8C8945D653E62C790D7857681B479FDA12C8894640AAB041A044D897C565CE882AEEB8CAF42630E10AFD12293FBEC9D7EF259BF881C92CC7706AC41626BBE1D17373E57B3A86A3BA62CB6084869B58C659371C110930B6C75626651971641A899645846F96081B00F6C29BCF8C646210676BF266467D90EB393B64A1593B4579ADB0B549E6648DA5C9E2EB3BDDBC78C468912DC674B126ACD4448BB40BAB46EBC8620288253156D8D39ADA1B639C6F69D34E9A25E6B6BF4241BC00B5968282BAB963820FAC7159001FA414DBE2B94A74158AB43C6A43519F9A34A716CC07908452E5A0A517138CF46220243BF2E27AE78835B73E0720222700861136B2A405A241E58F37F132C588A1102A5344B704619666900C73990C2145497565D09E984F2689E315AB204C59A360534A641228768A9F1581532EA9D7717B8D8069158605508A24AD1C71FEE5760605BC2D619B177985CE89CBAE0EA5EA335529A20225CF83744D807B886CCD5CBCBB8393D5BF144497A4C454A2AC7589B5315937345CC02372FDE21BEC80C0AC8912D28B3348DF2A88C35B7F384809F24665600583530226B50A6429217CA211946EA66451C9092E7C42B309A922465561B307F8912F29A1EE687B1D96D8C201BDD75A34E09D954A4267F21490C0EB74AE98FAD1B5A3B5D2B9F70E922599B58AF4BF05A9815C270046161175CFDBC167293CFD50E9D74851EF1D1DF08AD5BF30D584AE9C8425AB3C8F1FB9960752721CB2C8310CD7BAC84808BB979", + "ek" : "E71E8D522D43E7C9A055BA279822FD757615C903EE07084D2CA44868EF6DE2D3085CEA368D6674AFCB3B0F027D64AD3AA06C34CFDAD50B27E3D0C3C90B502A7D4CACBE5B21C77AFA22CD7B044F685E23FFE0AC203FB0D898400CDBA1A0A378B391A61D8034F764C4CAE050BEC5D5CD6985956F7B1349F4186BEBA5200943CCC65FD761F630D2D8687467084E09BF50545967D5B239C331FF5400997EC7AA398BDFFC1BC69145E98A425266DC4F088D2A1FA244641D411C540EC1F012302D28F3FA7547A1C8554EDA40EFAA02FAFB785B0419F88C7F27F961BC436D61A53A0E54B79131027B3BE5751548D9028D57617C2A0DDC1759BE8BC3F1176525CB478134258303BA5561B368026A9A02180D1C2CB55CB71D25EEB678032D934ABE338BAC978D4F51236744078E26830F57146F670F58420C35159C20189AA3416F0C5AE9679255D584B85460C2BCD89E0576F0B22698F3EE64F96182CA42E4AB83D876EDC14F581093B971A6793AC4A13339FB87987AA3A7A13D1C4720669A8EE47D93B90DEC8CCEC1E56BFD2129F2946E969B3B634F822A09BF5DDDE17C9DF0575820C3E5F421DD545B94182F00497F8CE4A80BE5B7D1BBA2857008E0BFD6072CCDC5766D0C32FE875FA15D82EDABB74E01A8CE2FC78CEE4395C22BD2757CDF171DDE18F99F252F1C8FCB07DCCABC97296F2FBAB02E7C91570C60421459709554A0E9218FA475F8FA07A3F3B3D7F5EDF22D138FEA761E6D41B7EB3F106C027D5FF8880F8162C5F5138E4E95DBE33B02BCBADE6054A6A73721704C82CA1AA9477648ACA8B613577DBB6A29982DA3F6771B2175D0A34CE91699421035736648A1FFD108FDBA14D2EAA5669843D9AFF4B83607AEB0CDD02808A7FA4AE6CAA6C95C32F87450F48E302F339E94EE7053CD46859530C363A2475E46D61182EA7EBAE58367E4B3CCD53646A689E74B413F3562785BB34F41EFDB68A314A2C050927EBDF22DF993463B93C6ADF50FFFB336210152EE904F3E7C2261B255044CED5C35C8FCC9BCC8B27DD208ACD796F0136D0E900A87AF18D21C507A4D900E6C1CDCFA4E7670AF5974CA932445A0927C1E10629F6DEB706BB958ACC76F8DBB8890AF314471310446619947F552AC0A831A4101E1618EBAC30C053EB85962B22BA5CF22EAF09422A9171C5F9FCFE8E09DBC1E366C35B07F8F6E20E042A58C66F0E913A05B6CC502D6C995DD60E9993D0171EE100A7773F763F5B39E24414E582CC27879BE85C3986A916C1F78B378446EECBE45A6A22B57556ED7C67E4651AF21E040F08FDC604B3CBA268D998A490A7DA3CFE092D584CE1552A2F01F89B12DB851BAA92D9FDF8A443B3237D6F4F74DF6331AA4F14F980C6C3ECCEFC8D53C9A6B763653232ACF60C19389217B3E0A637D9237D2BD9180988661EA0A8D5071F87C9D5036743F2B84464785850B98736DF0FA64332C09D394F72ECD31282F34D93D4DEC3BB73F8DF93C06DF6BD95B4B816D7EBC13F8BB3A3F2239ED7DB8941CB3D8A51282916BD82E2CD32A6C2433CBB1C565D99FC6731DA067E9CC6D3A75229E07A2AE3D0E757C903A90FA7298D6CB03AB20C00037754025511C4CE09AFE383DBFA082D0B4AA125698428535631D26DEDC322873A2E28F45047027EBBDC0B1ED6ABF20F4424A3FA9A5F769EC12B69861CC6B874363BC216BCA819D88A40A172D1C88EADD181FFF105F9696422115E1806A47C7CC275F47DFCE059401E40CF2D6AC2899C03E830329520AA2ED1919953F306C84B71E6C82C066EB099F915288E8C55E84DAF30197791274D147002AE2F67F4A13C2C4A408F9D48834640E01014FDF51DE42F0859066CBABAC1CE9E43F3E25E6F515EF9441E0C78495DDCE1BD799A162B455A15607AFBC22F1DDEEA1A974ED521D4C255A86E9C3FCC9AF6DD363E02F496126150A3F1A663665E22B40A90EDE1ACE5CA1CCCB9E91FA650A4DDC132BB071B2004AA2D8542C24FBCBDA49ED53D90EE2616984FC2E953B5F200A790C852F2A7AF01A5569FD52933FEC5C35EA4D7B4BADFB9229DBBEE8F9CE1D5FE3B78473A11D3186D7821405B9F5B9F0BEBBA2EA68CF5985AFE6A662CD4FFF41D897866016B0C01C65AC239B5B49CC14774E7EA9D8B2DABA219BBA2519791163F0F42909E1F6BE936AC4BFE509685DE7782CAB71AC81325D55D5D6F7EF306C34EA42072C17DEF89E79577C35", + "k" : "08323560EAE4CFBEACA3734FD2928A94C78E515597D95B00F102168AC1998EAF", +}, +{ + "rngSeed" : "669C4EF8A051CE201DA65FC4BC34D398EC1F806276FC5D987AD71D93BC12DC8F107B58BE6E8422A0795C88CB9A0E7488", + "pk" : "6820166411ABE7DA1944FB933EB009DE46BA60E249664722776B37CCF770B187269CB240004AAF74C37EB027C62536AE847B8EC48A6B2A9AC68307802DB576B70226FA1B951DA9CFE094A0BF4B0B306C5E030BAAA25BAA591B289FA24148C7CA16A19E0A0039EDA555645BB65685A75A57028BB29456E4C16AB48C06D346BA9925DB4184ADF635E779522C2670DC5BC1AC86C662EB37975AA806A2B2E307904F6C6A0D094828AA1C07891CF098223EA78967E7AF701273A8A1859ADCCAC61BCD0C103F3C13ACA18689397BAB1DDCBDEE2AB113EC6932C68622C513B0D66C60244CD77441C7AA964B5331EC11A088A5034E064A1D95B4B389C15C51426FC9A135464416881858511FC894BC2A3B0B742366DBCA062F2C3EEC28BC3C38C809EAAB081C5DCA65BFCE171057AB8467EAAB50987732B9C85BDCAEE647342C3660950B9CA7C0BDFB3BAB69268FC8486397B540F0831EFB861AC11855DEA4A588C4935847A644A470F055A923162F1DBC2B699020880CB08B80621DE33A9F0AA83FA2B5541AA2CF41B98214A5FEE14785661A63603F0492163B47829C71A7AFB0B5EFE94E8E225EA2C0179539772A510A5AB5456BE4670A076EE1B25FF62687A96284166576E3E773ADF2C061258BF2D28B1BA00FD485B8151076EAC5BE6AB7CCD81312A9CA938F256B6FBC8AB6D3C3A1DA5C75E1806C5C4CD4202C0B20816E368BB2443684463ED43787A89236FEC32FC99891166462852750A8C1445AC407924470A56B1CC75C7A378A2E40C00FB35C0D4F65BD12F49911FB923BEC1B635BACA8428EC7D13B36079732838459C669F7F0C26281717AD45EEC972011C66D63A298B95566AFE11BAAC79A67DBADC882815D014549CC294B658A8C00A2422C0D23F6A0BE9BCA232C8374E616E749623E8A99B0F96A08C95897E88900851076B1B470732EC2462BC9C943255BC475DA70B44B134E0CAFE8F3CEF42972CC175E04FBBCBDF4CD151639155A0469651408C9292DE9383E63C08C8BCD96A69A3EBAAD9B2C1940A37F6C32B1D3B702D28ACB908CB2C7B88B89A7AD4C87CFA6C53987E4721D2302BFB53EF3E9BF7319219926BB7884111FE2C4A9AA4C4C1C0F8BE3BDA890C0342B56F826A6E971C33F900408292C5820C92B66BC8432CF735388DDC35EB004506D8A671547B7F324741F609E2121A0592644E7E0CFFCE7280F77C34D05B930B96EC9C79838DA4A78680DA3B07C1485081D14B9D880BF3EC61D852114D738580918C72A270D7034412305BA10D6A5629A931747611554602F529F32356D9E0331DE2232E65C695AF1B597CC816D001DDCA540A0FA3AE67313853B6A46606C1BD3B32D193BDCF2CDFC2C1F9006724365550632BAE19BB3D60804D0C80F17681EE020C6CF3CB7C19A22B1D4ACAA8ABB40F308EC2CC6616164E106A06F700BC62266CCD40D4A414DFC818EF3EA39540247C0853309D45FB99B84FC3BA114C240915A19E96B742A234CA1E0183E60C8ACB65ED2C8A7D239B408C33FC5E31AE83CAAAD17C24B99238B2A52181517A1202C87A17F22BCA93E758ED95A895A6A97C163CBA8A4C0D0B980E9871FA8F595A668ADF927C4538374C7E65FD052196A64CBAA23969A1C07145352B6829AA9E93993C640E0F62B5BB0228EE37400619EAB437434026DF078BEF452267841BCB72844E836AC95D25439567A76F69A3B2C6CFC1C4525F340B40C558007B4F76864E8367CBA7C71EDF2AA9EC56F25F606CDD66CEDD0937451B95422A509B12553A8CEBE7B95BD97B45564C98D20A9CE8C51ADD836D8C00AF538B0D0528507BC3924A731AC05A688A1680E050B770C3A8F49C654138BDE367F4269ABDC4215175799A6112BBC186B23745FB0CC3F2BCBB6BA1670B1834E99E10B2FE25003243284C59EE4202EE28A6EC2086510697240D60961398C77B3B046A23A55B89151673E1AD8A9DE959923974C540902716C973EA402B3576F5B664DA2A104812A6101996980D68BAEDC34F9856EFFB6C457C8332487349EA3B8BC67ACB7FC509C22A476C331AF75374C57B4C010675D490DA92C7C60AC69D89A25E0D67351AA5C9E9880BC1386B77019436ABF526B319CE44CC759B009B93F8B9C3059BC7C63AB483A749E1A761E90587F13945674E85B7C896280D15D2D20BCEA11DB480755602348B4616400FAEED3C143406EA9C1307E37E2642EE73C442A", + "sk" : "402525B257C035FBC56B1AACD731540E40999EB1A2CCE3487189184F088A4BC96D9DCC63AB435BB6E26F78A90CA281B436BA7B222CABBBA20B4CA3223B1210B5DA1C7FEC7E64D27B9D7ABD831417D8E384AA500A5A986442C767EED412E6499825CA2946BBB83E1A9D07F14429AA46BA598595DC4639DA5015C96535C90E99A1C36DD511DAAA713F741F3CE3CF8232CB5FF403F32C75467440092A4F7714524B9CCC3FCA9503C50CC8D676758AB660E2742930BBB061639549346B9A67D82617A33283061011844467BF12AD270AB2E047835CE36276051062F46F32E05C3AF197CF7244352C03F423305C6477A9B606301B606C693EA08196A2C8B639C21AA641646BD3C958F3B6DA0CA8234B17EAD33B9A855E2B0181DDE85AE8A33CE357273583CB06968F07F6B52DE50D6600973B5B60EC3702C5480D95820DC0AA611CF80891338B5187B74D7046906499BF7419F2DCC89F7808B5557915EC82DD90102800A26E1CA3503B8844416C688386C3A74FE6B11FCBB6293F9C65FA247C70A40D8779056663BF92AB39B2596A17710204B884765C5C90F6B61B660A32C8158CE1817F45C2D9C769BB203ACEA434817C6F788482135118623152C0F38FF33733013A3FE5898F741986A5D322F679A7C0A17040B4CFC0F65E0395BB7D5B698E676DB248880791274EA868D13009E289951D3B80D57385924A433A83A42D879208072A2A5B563B171C9B53C263C6B233A27E40F6B3205741373880498552AFE88132B80F3849C937FA91EBB3A0770C5027A7065B961365429A7685BD2DF71792BA893CEC50BF398493D0676E002EA5A9054F095D52870728FB9ED9536DA077273437689209B2B14407F9639BDD287BA9F77AF0F6C750580C7CEC0426035E89745E88F3B328C60FB31987D7FA0280D062D8AC2F57B5133AA1AF119151344B5F4589389AA11803DA3C1F08AEF60589AB2687E5EBCDCCCC9D3C38B80D078C3C4038D0870E0DA3ADB641A5F22198868A24D2A128981B4BEBAB984F9C39EDB9650D23823DC1AD7F2C39067B95844829BF24CA25B68325134F14D9A849DB47169304F3319F95DA79E119BE3F31AF93CC1F1A1BB6743379A6314477FA01E687B135256F72D5657561B98D215ED6BC1BF80239E3831C16317CEF9B7E2FF60C6D116BF8456C11C6A47006B75B27ADA9C6BAEDCAAA8775306319982372A39039BFD1315AA310C7859AA42C287DDA6CBBE0F24F288BA3F9D78B214B6065D35EB9374EC46C251E77608C53161232CF11480B92505BA69A7FBA20B5713BC616317E4C963FC938AF06558EC62B47BE7C967E652DC55C1EA38C1A9D90947D167D672C6D0C608B6B9535BFE20E2E2BB322155EC3E777341C3B5F4A5C79A93A376A023F263E71C215E19B2CAE2C11EC400A93439B0BD13F8CABA7366094635CBD1558448294704C5B209D7B7A6BA1AAE425AA03AB197AEA341D0166ECA608337C387644638EE00CC3FCA30F2A063B8847F637299320127D038343F001720BA4AAF339404A2494B1385F851EC06B07105869960332A8DA7F5A7065E8983261EB7B68191481062A22A800932A38E0280CE73C1B762A3F95058492C27C4022CB2F82C1781418CE217C06D5CA7F1AB2E99167705B3721719497B266DB68B6EA1356B4C642058B4F1AAB6C4093C3B2532181F9BDA310387A216B6339341239B8FBB9CB9D8A46554C1AA875B1ACB34BA50B2B6B11CD07AB0C695A66F025CAE448229655B177543B98478EBA7895882A6A7E20A5263370C7177370D1AE4B48B18583A49DC62228165C55368AE6AAB812F6321AEAC1EE5542BD35A9C291B6F8AC01DF1C10E5E10A00D61ACAF83B125407445A341AEAACE6F592FED5BFF105178C018F893116BAD4AAB410CE04071E312269BCB1725CF229BF57103FE90A99DBB8A0105E926C28AA87571D613290550EC96BC9E2213A088C98C3981727E8311AA595F221183A9657E0CCA6ED40962A30570A475E7C70281576013D725793E11A91B312E688A55365CE42AB08AC759897A8AF7C607622E56014DC825F647D1421A9099B14BCC4934CC4B389B333C14373FA593F0851291A1B3B4FA96EDBAA893E4814F887ADECF9560154876E1B861841A2AD37236DC2C647E608CEF8A3BCACAABA0A66ACFAAFE173CEF526C86D31416820166411ABE7DA1944FB933EB009DE46BA60E249664722776B37CCF770B187269CB240004AAF74C37EB027C62536AE847B8EC48A6B2A9AC68307802DB576B70226FA1B951DA9CFE094A0BF4B0B306C5E030BAAA25BAA591B289FA24148C7CA16A19E0A0039EDA555645BB65685A75A57028BB29456E4C16AB48C06D346BA9925DB4184ADF635E779522C2670DC5BC1AC86C662EB37975AA806A2B2E307904F6C6A0D094828AA1C07891CF098223EA78967E7AF701273A8A1859ADCCAC61BCD0C103F3C13ACA18689397BAB1DDCBDEE2AB113EC6932C68622C513B0D66C60244CD77441C7AA964B5331EC11A088A5034E064A1D95B4B389C15C51426FC9A135464416881858511FC894BC2A3B0B742366DBCA062F2C3EEC28BC3C38C809EAAB081C5DCA65BFCE171057AB8467EAAB50987732B9C85BDCAEE647342C3660950B9CA7C0BDFB3BAB69268FC8486397B540F0831EFB861AC11855DEA4A588C4935847A644A470F055A923162F1DBC2B699020880CB08B80621DE33A9F0AA83FA2B5541AA2CF41B98214A5FEE14785661A63603F0492163B47829C71A7AFB0B5EFE94E8E225EA2C0179539772A510A5AB5456BE4670A076EE1B25FF62687A96284166576E3E773ADF2C061258BF2D28B1BA00FD485B8151076EAC5BE6AB7CCD81312A9CA938F256B6FBC8AB6D3C3A1DA5C75E1806C5C4CD4202C0B20816E368BB2443684463ED43787A89236FEC32FC99891166462852750A8C1445AC407924470A56B1CC75C7A378A2E40C00FB35C0D4F65BD12F49911FB923BEC1B635BACA8428EC7D13B36079732838459C669F7F0C26281717AD45EEC972011C66D63A298B95566AFE11BAAC79A67DBADC882815D014549CC294B658A8C00A2422C0D23F6A0BE9BCA232C8374E616E749623E8A99B0F96A08C95897E88900851076B1B470732EC2462BC9C943255BC475DA70B44B134E0CAFE8F3CEF42972CC175E04FBBCBDF4CD151639155A0469651408C9292DE9383E63C08C8BCD96A69A3EBAAD9B2C1940A37F6C32B1D3B702D28ACB908CB2C7B88B89A7AD4C87CFA6C53987E4721D2302BFB53EF3E9BF7319219926BB7884111FE2C4A9AA4C4C1C0F8BE3BDA890C0342B56F826A6E971C33F900408292C5820C92B66BC8432CF735388DDC35EB004506D8A671547B7F324741F609E2121A0592644E7E0CFFCE7280F77C34D05B930B96EC9C79838DA4A78680DA3B07C1485081D14B9D880BF3EC61D852114D738580918C72A270D7034412305BA10D6A5629A931747611554602F529F32356D9E0331DE2232E65C695AF1B597CC816D001DDCA540A0FA3AE67313853B6A46606C1BD3B32D193BDCF2CDFC2C1F9006724365550632BAE19BB3D60804D0C80F17681EE020C6CF3CB7C19A22B1D4ACAA8ABB40F308EC2CC6616164E106A06F700BC62266CCD40D4A414DFC818EF3EA39540247C0853309D45FB99B84FC3BA114C240915A19E96B742A234CA1E0183E60C8ACB65ED2C8A7D239B408C33FC5E31AE83CAAAD17C24B99238B2A52181517A1202C87A17F22BCA93E758ED95A895A6A97C163CBA8A4C0D0B980E9871FA8F595A668ADF927C4538374C7E65FD052196A64CBAA23969A1C07145352B6829AA9E93993C640E0F62B5BB0228EE37400619EAB437434026DF078BEF452267841BCB72844E836AC95D25439567A76F69A3B2C6CFC1C4525F340B40C558007B4F76864E8367CBA7C71EDF2AA9EC56F25F606CDD66CEDD0937451B95422A509B12553A8CEBE7B95BD97B45564C98D20A9CE8C51ADD836D8C00AF538B0D0528507BC3924A731AC05A688A1680E050B770C3A8F49C654138BDE367F4269ABDC4215175799A6112BBC186B23745FB0CC3F2BCBB6BA1670B1834E99E10B2FE25003243284C59EE4202EE28A6EC2086510697240D60961398C77B3B046A23A55B89151673E1AD8A9DE959923974C540902716C973EA402B3576F5B664DA2A104812A6101996980D68BAEDC34F9856EFFB6C457C8332487349EA3B8BC67ACB7FC509C22A476C331AF75374C57B4C010675D490DA92C7C60AC69D89A25E0D67351AA5C9E9880BC1386B77019436ABF526B319CE44CC759B009B93F8B9C3059BC7C63AB483A749E1A761E90587F13945674E85B7C896280D15D2D20BCEA11DB480755602348B4616400FAEED3C143406EA9C1307E37E2642EE73C442A4F71DA07C289AFD5CAFBA73184B9723C238DA81E3AE109DACA1873AE1E34D84A48B1985FD7938595DAC8AB776701CA1E9FEF47350DFC45355FF1E83A08BFC3A9", + "ek" : "7E4464F2050BDCFC71C285821539BED82EFBD6DCC1071A8B8189B4A07AEC85A17BBC1643A1E08C985AC950F68401ED42024783AA0824CF034B76C76F84D9A810D60AF31471AA52D5E8B5A74D2F0791F71190A58609E87DB64BB127AEAF24B8D51AFE63273F66D1B76CECA9CF36B4DB1EBB386C1AF2E0BB20D2055AF6902E5FB009D1D57807008E793D7BB195316EFCD6F52E8773F2EAAA34F335B9CCC2AD71EC1C864F80053FA741AFB73C676A5B9204E1BD0F18E19B4FE115834296A94A45616447134E37A6287294984ADCD33ACE5453BEC6E6CFF057A8C25CE906008154C1F03313C147148EB948D78126A1D6DDD0212AC467ADFD8D128B3B809F11F39513F55A128CC80B06FD7FA013281F517BF069E4FD3B23B61493616EC012715C510B1CB9A9D8AF5213AA11B795793A58F0F450222C149067CD7F6E84FCE1523A8B73579AE64E96156EF86E721CA757714387826D2FB25E24213C8E2DC819ACC2ACA85B605DE09223AB4CDB3F14F0F9332DD840500974E866DD53B14B2520A8ED1297E0B9AC885103CC55658416C15908E59C948069BE2BB0B60160B70BE281BEEED94D87A0F1700713D0A7A8329DB3CEE0C3FC18A824C1171396163A0BF71E6D22461359121DCDC4EE24260AB70EEF42ACF10F022B86AAAB93F5415AA9E66B1B082805E3991A91460B83BFC6F50C13AA80C2BE96BB596F6A8EDE9AF267E2C0A0FC059F401EEDCC132802DF7E86D860233295236618784065DEFD34ED1C65459575CB70D72A0F035CD4B19E4EA4E8A493F9774418F27D50321F5028599D3BF56D7B61E3BFD82F0F9024CB33F7D7EB1D0BFFDED30E4B5D9C3188A3908279548DC733E3BB7783BBAD67958D3CB3D7E7611E12CFB3C4F5AB3652FBBCE544F569E733BA399C6F95CB1B816D5126152D1F271942F8ECB28D1B44122046A200621294871DC3B6FABE0330B864E51D85F2329BCD3B928E4A02F010CF18DCD79D17169E1804421F79B9E499694694824A424096CD04D71DFF711FA7CD6533DC674833754413DE84FBF4E7BCED2991A652A81B12296C70006320B6DC9CAB1135467E217C638D37C3255321897309F242C638637159BA8CFD4626A83CA67A4C5D5B777C508CDBC5D64E35C5A2D362838CBEF25C94E01927D305B44F0D1F6F28DB331361E083A10C39E1050025415D847B91398EA8CB4E8438C707145AFF85CD4E6D46B4724AC2ABECEA52330B87BE668A3B41CE81F9D321F57D571670B618FD9B21CF70D5098E6BE5CE3C30C8D4910888C5E96B1C87F4588C5AC9E753AB524199C23D072205932CC0944ACD26CD8C02F88F05F434FE6DC90B6C53CA89ED0FE4C1598EC4D2B09CF405CE7D1817ACEE6F65A5B77983E76C7A0474ED40845EF4252C1DC18CB56F25345E313FB304476BCA9B897E4734EEA78B62339B8C39ED50ACD31856DCCD0B447169A6B011532BFF9CE4AAB7EC8DB04768DBD9E0D9099E57A9DF8911EBE6EF78EC0ADD2A002134AD472F903136781EC6802BAF7705284EA599F87DA26D44C7E6C4C15CF246C4A79C9ABDC32E96DFB9A4062C392815C9016DE894BF233D4039AAAD1CBAEE5598799C1476251608720F3B4851ED8293076E659F45A130DF26D28AAD7D4AD765FED707F11FF3F32BFF0798EE06AC1099FA0E660E0A5935F0B4269FD2FDE2594DABDAA1463CBBB5D1FA0FDA84979A0265D98611807163168DD08CE5FFA2C2A0B4A90932C58A27F0A31B999FE631B78F4FEF5C26F42032B838B60C21D3915AB2C6C3CCE15EF759CB1B12967097F455C36A6541EE9F765D8021133E77379E304CF03C64711C7AF5D8513931A126AC26EF64C36D762EE6B93D14F2D600E798B48181FC5ADC083A0DDF36412D093649C143BBD787F296AB1ED0B59619F8400022C9FD8F92177193FA2D8AA7CBF2A2DF578592317782C834956252BB1E6DFA00DDEC55DFFE985AD5BBAD88B4B1E3819F27DBB2A0C24F6B0C52918B877B8CA98201A61FF725447BB3225BDBF7046CAAE2277F78FF6655B06B9497E90C756FED6EFAFB52196F5B4EDF7AC2E9D13D5549EB13D603264FEFEFEE9171A087769551178B6875B0BB1D2742FD83159DDAA327B369D628988F987E57397E12E208CB854983EED7DA3684CC3EFBF3D892C61974661DB2AB3666D595DAC5F0EB0301F2895B7A39AFEABEC04D69E4717C5EE909336E9BBD02E7AFC5B25590D9B17703DBBB", + "k" : "4264B153F18AB65459CEA51447657B8C8A7391B635CE7507E049B8A6FAF69DD2", +}, +{ + "rngSeed" : "9DEBCCFE818F6B5204DB4EA09C03EC9A19DCF1629C1527685B8A29776BB1DAAEC45F8ABF8F0ADC9A8C8BD6E2DF6D8048", + "pk" : "60045CEEA77D8303982AB9B039DC4C3FD0159D46C89E618304FB5D4CC53E9766138FBCB061B56DDBD61E33873A953590F628C122D049CF722737B54D4430C312342189B59364E14FDF8CB1EDC540C39612F8E2BF88710C26425C09DC7AFFA63F52FA01DB7794AA2C2ABCA69145E89C06D40189FA704DFC4B252811B939118F1B9928D0B0B6767A1685804F502A19254FF89A45D9539C9F968835013B69A362F634B269B911C4327520673049C00E0FC437448C2849089918EC93C2EA270BD0699C85898C0148F4A1095039A216A51143183F4D695AA456C32E8A35D351415120725EF995010409E1176806DA6B6E08CCFB3093914C87C107CD14E11F937A9F138B928EA5580494C6EB643AE33B5600F7726E2004F52CC39AB24D0CC9C3F9E57A0B821FDFE8404E6532BBE01609A61DEF2B4F452A1FBFF381692975E05121E2330C789055E5A4AD696678BBEB1A8D3247D2257BA246A2EF966C305A8F4FAC73A6FC08F71CA500AA9D00962CAAB7A2780CB94C209B1CD43151F3248DD344BC9898B7780950A10211D73AA0BA20D89B01B36623ED8AAE48845E1D7372F12B9A692B3D525263DFA12B3F312F91B5802D3B3380E58BE6A92A70E77CD6134103496DC3E9236FF17CB0EBB04A1783379BAA0A3C54CF1C5EB1B4AFCD9A7042C50D6405B1B610A9429AAFE61A5423055AF9F61D3617BE60BB59EE8019E72123069614E738A46703AF5BF25D31AC4F1357832B1232CBB9325E522E79571A1D226397E407E4B08B44082E71E984E463747A230BED934127E892FBA29B88857606983A60B9425008117CE17D20C82B6171165E940530254F2B0CB4E5C235DCE373FE1450EE6457DA59C331B17F8D4B5E0BAB25AAC789C04ACFFB957724783D00DD24EEC3375F97AD838AC0C261789CD3AFCD68B2D53C0C9BF944F094BF0875C0F08C161D3618C774304AB25563981974CA2E13B5BBDD210EC10BA39C64635C9025B9610B623C2F12A768E03163D75315C7097782B69C44B3A0C33A552228C6001C5CE194346A80824627B974D2C64FBA994D2C62F8BABAC47C51DC100C54789F737C61B9B3420469B11D110DAD9010C6C67EAD2329D3B4C665AC528041BFD028612C608F87F3AB74B6B68309317E1C0EE5662F8DCA46C26039E2DCB1FE8C42CFF0057D4BB3E4AB3BCE13C142E589592C0850E117CABB2CAC88431461A5E6743695E096099A8249E22F4033C15E9266CB00A9A36103AC473123E95D373B0DC92CBDF6B2B173B07A3771456D283C758AB963811E5168694CC20E64E8A677E05E3915C4D93C8531B75D430B3709753F899B1C45434BE196A3FBE5149DDA2AC0912AFAC619B4A45F3DF262F7D617322A9E8221A79F2319E6AC59034C80B3214953419A191B0E4A25247BFAA0DEFA001D5529B1CBB9E63AC03768404645BB8AC7CE25687BE70796BDF516B76039F7B689CE6C3F569A04C52875ECDC9FBC97447E0160E75A89215AA263091E7CB5534A97660CC8515ED61D9B624950C089D9AA647F787A8ED7C89216694A83C56CF278FA94340D790015B914D09BA91E10AC5B7BA95792BFE779966EBC07AC6916FE1AA4BCE56CBAF506563319C5A4C4344344B472226F59B7FBE7982C08AFE9A60A80C446B8B341EAC220FA8A664B6B1A0DF72684B67BF2032D75F5AAFFF7CC724ACF3F1051EC3CC4CE8768FA9AB51F960F3293A1FC527686570DA34404B5681967258799FA26F22179E18221F4BABC2B7C46601AB7CECA1A345027D44783E7D6C511615B108C4197BC0D9EE49C91621074A907AB292D4575ABAD75A19F10C2A493AF902252BBA57348DC33FDAB3217778429680B4F352B52445EB662101DD22DDD211F314577CB23BC47C7176942C5CBA072996C048408A5DD795907BB2E2F49ACD0E75A93CC4F7938136D7C26DA0691C08733E8138CAED6C8CB116B900869F9FBA9F5823B20626980EA86E6F487AF758830C787BB1BBD8DE024BE9765DD04B969DC21589312E709CD6780C9A38A8207FBBE74F220C3C33E2A127588B64E3170999D3A77C8F67EEC947CB69649DC64010A3119C9030E1FD0530CF5C3B73B631917719D0983AD0A06D2963741289A282A717D7487ACB30354FC74B005BA01101A1C8B52C130A00339BFF4F480A4E890030A709B28082D3C501B2AA2D14FBEF9E429F8CFB50E84C327BA02EDB7F6ABDDE459896EAC77B5D8C7D7CABE", + "sk" : "499333BCB7971E60C8A924AA6EBB2CCFF48B4D3B9FD4786741668C071AAB1C401D6E50928EE83D7997CD10151B1BB28BBDC8844681CBF736C4110CCA8F32C3CE345060080D9280B9D8D8B8621B690EAA77E6BB8ED23285EAAC41EE6B44D85A7253D70DC3180C5BC16FF3B7A4371616C98B50C3DC46BDB3207F880220B6BA60BB6DB6A3326137190FCA28777A519377CF8F08B333A721DDF9C8A91479A600087FC15A35430091357759DA0B009D86D312AA7C8ABED3D6BABC371612543EDB115C0273C999452F85D796D9EAA442C880EB098EC2A8B249D3378611B4A27A583CBBA276790E9A119ABC9CCA1BA7C57414C1D697303DEA1778B736DDBB9F521A44B76941538666A98140263419D3BB593CB23BD070008F396AA8532A92DBCFA7031D5C537FEB2594131204691605D7FC8E5C7C6AAEEACDFD169E62B476D3A65D611801DDB06988F38636F32600EBC192B8709B1C56070A68FED61866F00D0F2B16B0429A9EDB6E6850366CF3995EB5C926AB4C82506F50017A1A106E2CC32698FB77BDABBC60F35DD93A54FAAA10F4272C2EC98357F3C137628C855513173C4788C35AF8BCC723B97910343EAF4172AC586064DBAA43EA90CC36521A54AAD84B3CF906145ABABA3498CF2AD900C10B5C7BEB0FC11B8D358A90D34383FAA5032D535935FA4C639CC7E0094534623176B836D7C041D2B6C1689C3325C71DBEF0743863A4993C34623578428910959075C5129D7706A3537172CFE981E8AB8A29BB09A1681B6FB75BB60017BA998AF84863AA17C03CFAC56E18AAF714AC9854616F09BECF13427E996DFB084B1E62C5495C9EEEB1C0BC23C971077255520F17692601A9021662B770672A860C025BA9238CF8C73A8A467833BEA9462AE604387F11431AB5794907916AA15DE03AA6501C993BC684506B24D715557DDB7BA01C492407147905ABB8977902DA131CEBBFD9B3B5DBC7A03580726510393F2835A1DB389804A7AF54743C553F5C445B4D350D3679B8D300916BE22DCCC7A0AA009E22E98DC21003F7A8041813BF84A8592D7979AE34B299E9403FD8A073CBA7DEA6A44968944EB4BE70623163EB9E59DA4516612D3DF06E80D8326090B52EC78C3B883E70C06A77C70FD0426EF34150BA3195D05075A08C133F608DE4327712C825E05878BA74ACC9AC66A7573F6D245F2AB3C09E702B1B395BB28C1746ECA972B41FD9D28743B736AB39853066C5029B4CC37089B89179E3A822CD606BFBB74820D3885E3B08BBB0716A7C7D4B674F46EC36D6D89A4E331ADD040EF64CCA6C3B1E1BACB5A5D857A729BEEC7B5F4B068C3A685614619D6021170CE22F3F28A52517268AC6693C58B3F19798E4B186E2F0C471E33C4CA0338555CE3C37316A291CB89A3FDBD1B64FEA422C46C51E65844E5317E4DC47A9461704E16259701718600610D7273A09CD53B256D5C6701DD1CBBC3B452BF943729C3F35A2761360885CD65A0BD06965443E2762B4D5152F50A4C18171205BB192DE1619D9F3217A870EF1272EDD442F62C21257407427FA0D4E85BF4E27563FC2C569357E44F7239EDB9828C65DAE20870D5A48B4F807CBA20062EBA57F0613114C335969AD471178E6F3318103B038C2812C18BBD68903C00827179A710C23CE84670C08075B70513AA9D5C6B3C34A3E4C437CC6C14B63B4C3E1C27638151D8A2FE633520F1159C52C4C59536EEB22B6981B8D10C29469242F3A09A7A416C79D893FE2C5C3204895AB23B0B062160B58B99D501F2DBC3C75A594E0A605DCB6CE54832D2BD450BC4C53ABD892FECB0DB87319ADC0294345770197ACC8E1B8FBFA67E8A830834432FC93AA463541456059DA44BE22695B3EC0CAEC411835E409430076DE94426FF03AF3E97C5ED07DC0B9450CC1A37508D019BA1B08D89943A5661FDA1E84F09F2B8961D36243F36155F95C8A74E83B0FE61966F1008826566F5737BBDA0A3BC1B2E0852F50F96DF1C692BE536346FCA97D83C41EF6CC63AB22F4A159229217261A8760E648D2653D4FE13884624BAF9A57AF50802AD6C90359A10F3A9E83119834A001B74A09BACA15C80C2B1A391DC652236011885BC181F6A8B42E7B0581798348CBC987959462E3B2F8986E42F59D84BA35CB171F2E81BFA5079DD30B981973ADF67C645DD82D60045CEEA77D8303982AB9B039DC4C3FD0159D46C89E618304FB5D4CC53E9766138FBCB061B56DDBD61E33873A953590F628C122D049CF722737B54D4430C312342189B59364E14FDF8CB1EDC540C39612F8E2BF88710C26425C09DC7AFFA63F52FA01DB7794AA2C2ABCA69145E89C06D40189FA704DFC4B252811B939118F1B9928D0B0B6767A1685804F502A19254FF89A45D9539C9F968835013B69A362F634B269B911C4327520673049C00E0FC437448C2849089918EC93C2EA270BD0699C85898C0148F4A1095039A216A51143183F4D695AA456C32E8A35D351415120725EF995010409E1176806DA6B6E08CCFB3093914C87C107CD14E11F937A9F138B928EA5580494C6EB643AE33B5600F7726E2004F52CC39AB24D0CC9C3F9E57A0B821FDFE8404E6532BBE01609A61DEF2B4F452A1FBFF381692975E05121E2330C789055E5A4AD696678BBEB1A8D3247D2257BA246A2EF966C305A8F4FAC73A6FC08F71CA500AA9D00962CAAB7A2780CB94C209B1CD43151F3248DD344BC9898B7780950A10211D73AA0BA20D89B01B36623ED8AAE48845E1D7372F12B9A692B3D525263DFA12B3F312F91B5802D3B3380E58BE6A92A70E77CD6134103496DC3E9236FF17CB0EBB04A1783379BAA0A3C54CF1C5EB1B4AFCD9A7042C50D6405B1B610A9429AAFE61A5423055AF9F61D3617BE60BB59EE8019E72123069614E738A46703AF5BF25D31AC4F1357832B1232CBB9325E522E79571A1D226397E407E4B08B44082E71E984E463747A230BED934127E892FBA29B88857606983A60B9425008117CE17D20C82B6171165E940530254F2B0CB4E5C235DCE373FE1450EE6457DA59C331B17F8D4B5E0BAB25AAC789C04ACFFB957724783D00DD24EEC3375F97AD838AC0C261789CD3AFCD68B2D53C0C9BF944F094BF0875C0F08C161D3618C774304AB25563981974CA2E13B5BBDD210EC10BA39C64635C9025B9610B623C2F12A768E03163D75315C7097782B69C44B3A0C33A552228C6001C5CE194346A80824627B974D2C64FBA994D2C62F8BABAC47C51DC100C54789F737C61B9B3420469B11D110DAD9010C6C67EAD2329D3B4C665AC528041BFD028612C608F87F3AB74B6B68309317E1C0EE5662F8DCA46C26039E2DCB1FE8C42CFF0057D4BB3E4AB3BCE13C142E589592C0850E117CABB2CAC88431461A5E6743695E096099A8249E22F4033C15E9266CB00A9A36103AC473123E95D373B0DC92CBDF6B2B173B07A3771456D283C758AB963811E5168694CC20E64E8A677E05E3915C4D93C8531B75D430B3709753F899B1C45434BE196A3FBE5149DDA2AC0912AFAC619B4A45F3DF262F7D617322A9E8221A79F2319E6AC59034C80B3214953419A191B0E4A25247BFAA0DEFA001D5529B1CBB9E63AC03768404645BB8AC7CE25687BE70796BDF516B76039F7B689CE6C3F569A04C52875ECDC9FBC97447E0160E75A89215AA263091E7CB5534A97660CC8515ED61D9B624950C089D9AA647F787A8ED7C89216694A83C56CF278FA94340D790015B914D09BA91E10AC5B7BA95792BFE779966EBC07AC6916FE1AA4BCE56CBAF506563319C5A4C4344344B472226F59B7FBE7982C08AFE9A60A80C446B8B341EAC220FA8A664B6B1A0DF72684B67BF2032D75F5AAFFF7CC724ACF3F1051EC3CC4CE8768FA9AB51F960F3293A1FC527686570DA34404B5681967258799FA26F22179E18221F4BABC2B7C46601AB7CECA1A345027D44783E7D6C511615B108C4197BC0D9EE49C91621074A907AB292D4575ABAD75A19F10C2A493AF902252BBA57348DC33FDAB3217778429680B4F352B52445EB662101DD22DDD211F314577CB23BC47C7176942C5CBA072996C048408A5DD795907BB2E2F49ACD0E75A93CC4F7938136D7C26DA0691C08733E8138CAED6C8CB116B900869F9FBA9F5823B20626980EA86E6F487AF758830C787BB1BBD8DE024BE9765DD04B969DC21589312E709CD6780C9A38A8207FBBE74F220C3C33E2A127588B64E3170999D3A77C8F67EEC947CB69649DC64010A3119C9030E1FD0530CF5C3B73B631917719D0983AD0A06D2963741289A282A717D7487ACB30354FC74B005BA01101A1C8B52C130A00339BFF4F480A4E890030A709B28082D3C501B2AA2D14FBEF9E429F8CFB50E84C327BA02EDB7F6ABDDE459896EAC77B5D8C7D7CABE482C88CDC80345768E4CB54D17AEBF2947B07C716DDE8DA26E0B7114F85DFD2985C3A8B3732DB34F4CD985B65E078AFE6A735B53F4BC36D4762A3E45D1DBCB74", + "ek" : "97513E51F7CB1641082F178883503C0E69BCE416226EFA72B21BC0ACA249C400EAB727769B73A41960E7431E607932BCE78C5563A31046AC2E88F5ECEC8129969C632CDB62A2C1B15D40DF0D8AB92567D22E59E5A4278EF1D3D0CF6430C59D435487EC62BD50883960DBABEEBD8CE714D220A2BF6BC3231E3F6DB37D0F9037A89FC7298830A867F580843ECCD83274A3140AD57362D457606BBBA2C36F38F3CF1471164B00E85AF890F5D8C25392BFBDBD196EEBDACAD5D0DF82530966C26E7D89D4CAFCE1303FCBE6FA8B14351BD204CC215F603C50DC4CC6E288B1149F2825C4336D6CD14F0355FB806F54D0B5E4E728201770F7719469B819112E5DE472A3CC30CA0DA3F629469E98F7D09F8B1AA8845E497F30DC383843F42748BCF956C6ACC8815596559DF67C35F6E3299245CF4241369B0C777765A7544D7BCE3445551899345F23C4BB4F6F6A5AF85A8B70848A9F18B923F000F3AD6B340D9CBB78E032F377575E073EC74DFD20ACC55932358C3D5FDABD19B944D95A6391E1CDB4E654AB6E9F46B069DCA8876E0F0DAB8605A80B2C7D93D5D552C211AC7C07E29C07859D157DCDAC595E51F88880D20AD6867072FAAB0F87E4FBC0ED0F2129FF24414413E669C1AF118BB5E9AA0C95EA8B50745931F8A0ADFD1E062D6B7518E70E3EA57EC8315C4ABE4E221B4E842C721B3D2C9DB4DFF2286C5DF4D5C0723FC8F4F8845AABF1AA6DAA62DD933E2FA5900347DB6E93F16C748EA2092B0F686DD6AE7908BB7367426F7B3A89044EF1A691E655C1C7AA5B76E1FEF21BA44B293FA8AC816FF96C41F37ED79D9CD6A267ACEFB820EA63142F0CA36DCC542BBAD7C9100D008ABA3349194956EB064EA5D165D9A88CF68DFD194909D948CFB2D775300ED5F1A6AE9491F3561DC64D789469AFF36750DD04D6E2EDE4756A460E496DADCFC7BA0E2AAC4F5624E38DB79E5E9CDEBC412BF16B399C01199B81DE4A7AEF6B45359BEAE9C0C3DA436CDD73D0F253A4202257A4B232FD7DC4CE99BCBD2F34C2F2ACC14855253F2741677F648DB45BC7AA4DEC9E4144A90C52E854028C14287BCC8CA31F37CCEE6A47D5E4D1D2E184D46F9554C0DCEB7D431DB395C70B74C424131929D6280BC77AE26584F8C0AD9B6167BF9EF5EFB3C003C7C0D2F1D531AC53DBC6CBCD69E29C5B6F60997983048172100428EC30D06F67AED89F4D611CC8E16D4BD8B64A9D9F477E7496011AD3AA45578B49024C17DABF96ADB838FECB4487B190159253B5B733F4518AA56622344D6B835F0941D188F3F221606579F5161455155A2FDC1AB21CDF93AA40E7D21C6C2FEFDCF2D88C68D7F8C87F7071CC91117B2B9DFD728235DED24787CCCD35615DDAFC808FB555A6E99559A3965E286DEEFEEAAC9C3157714DAA245A7AA177E848394BDF75169BD4E2B0359609419787BA524B048E7B4604D56EF17CFCD31DE36D91802D342893C209B27FB7D51FAC1D6AEC2020BA302B21006B529747C331A5BAD4DD351F297B154D04E774212920A98C95027A7009C73F25B6FFF687ED75C0248A473F64F71A505158FF43D9DC05F2407727E4D09132C9CDBC3E7C1FA8363A910A1CFFE76748A26513DFA96128183007C4EEA40578E3E4E6775E6903FEE622BE831228719100B6F1F28E7CBB1076E2B97900918FE175197AE2791167F608324DCB9FD30818AA9A7F94724A36EDB9F53F61A55B8FF6C676F7673F77BE5178BD2D8672CFE0A319C2B4D530DF517730DA9B259AB9D22FFF654180E91C9508DCF1FA81DFA3B0E6E391A4C2227AC430FD1941A5C55DE51A765A620C331D5F9ED2021687A8076B80C11BCBD6EB66647895420F4D65F7A56C51D7F7D9A3BFAA5D708BAF96AA9E187143C18531A787DC6A6D938C492293D09902AD9646FD94F891F9187BB9844C244104A009D96D79EA2F11B89B4160E584E9D721C5B0045F833002BD979DD083FAA87F1BFFE81BC7907134B46FE754615B6D5AF1AC3D2AC202CBA2D7E970D00618D5EBBC1ECD665E59D3C73FC1BC07450AB54FECA500F9407F47CCB7F7BF6730B60CA8C31D2AE357CC05C8414249150A8F1BF0CBD68872BCDF7F58C60A9C3B95B2B53EFEA7E59B55E2F16FAA088F36B4D6024B283CC5C32795AD9CF19A29172793A6CD3E4488B195F944120F7A472DCC850943FBD6FC459E69760A5B9DBA3915D0D7C7E73925124DB145F5A97399AC56", + "k" : "D569FE0EBFC4032F317DAF570B2E33905DAB48FF281F36CEE782250823BE4904", +}, +{ + "rngSeed" : "8098AE7A92C10F707D405F7DEA02C2EFBEF44EFA132BA8AEFE81BD45E543ECEC74F10920AE48A40B0653D63532517F2A", + "pk" : "944633D5F98AF3845CA7C37F1BE75A52410DA5D2BF9D102305EACE09009E6EA21B6C543A25032612492B58247F13F01C6EBB27FD469DCFC83AC93071D3368FA128A4C71475AC1817A8B1744C9A2085E54EBB8455BEC286DEE50CBCE87EBB0BAFC32341E877ABA7A5AC10DC99B65687AA53CDF2585976A06BEF586E8993953D5A3CFAD8A7593349F9C31010E6BECD32CF6EC70F4EF88B1AB955A5D6AAC2A877323181668A2C731726236C4C1F77768ED06A7358744C91C690029C4C747603289874032FE6730D96392805E10B7A50A6B849985083CAF8D64C1FC257747613B9E6C85E455ACE3755CA9034089162D96346E3F0CDDE0A81F6A7727BABAB5F1401DC1832BC175E3576B36747101CCAC305D28AC5386EA92447F483408AEA6AB22C1027B99B9F14A1B6A67A24FCCFD5F52295DC11995B9503D76C7D0BA51ABAC76777B960C45CE8DCC24FF6031DA9A99174BE42A381654B5C9697B13188A38C278D94F801A2B94685ACB0935074C06272E0BA87B6214F717C01D9508D77535E444B5A2B461D02ACB855D7309B8AC6B7731BAB6626921160E1A35D0BF14DEEB922D770BE063198D5A72DE076216BB366A0889773BBCDEF5872934A894C7664F568AC7F1CB5BC72587767025A271DB13A0CE44697AA4C0DBA80A730C0C1C2146B36A50D23926DF520AB3460B18687921DE988C2A7C97DABACC5AA849068AD76F10B361B9A2D1436BD88C962EC724DC15A6583CA8A41704F3946DA465042B808F2513B65A5009DA5B44125308142478AD82AC64940164C24A599C96EB69EE5E4BEF1E45066E2CAB719B57FBCC03C1985472CAD16A2699E4939B2E2850C1B24E8049A41362B2B908E52E2A9F7808D06A6298E059BBE1C5A87A8610A06AF0262BC61390F90D962EC95BCC907C850721778A947677A226C0482B5704E7E0176F1E28E27150AD84093AE862682B4A74E8A7D330C4C4E144C3A39C3A3DA3C75873DBACA4880C2940CE30ED10C395805C0BC043CD2861B2E9C0DA1B59474F8C492024CECDC7676D4B8C4B3311096270D29057D05CBA6494B6AA07379B73BDFAC9A561A8FFDD3A43C5877D85749DB9C8379ABB29F7567FA1CC57B09C35E7B6FF3F735CC18473049BA2D5837EDD8176531B67E04A509BA811A9467C633B962E8392D065A03865658913F494501FE9C0A6A649DC8F3256B6274CB6235B0CB278132676D028A24E07595F56C4727A7B11830C1C9840C002DB53B6198444E5B63BE4C46BE9548BF4E1598EA6371686C63DA774270B82C95F0C9A12B5C8F9A591EC50971D897B3C1C4E0701DA5E26BE2760AC99B481151ABD2A20BA343BF46ECA8699487D14A9667565CA4E30EAE468AC5E6CAE54B4ADCD5ACD74812EBC3B4066021B0CC890099B911553B95C794643A97F99A512CE874F10A3C250A513C005A70605429F5943600CFB9E4B2C5E72C821149D9C2C554C43D9BDB271806AE8B58506571C061240B6E7967417542334773178424D46122C7212E0BA7B5BF4388E8F4A3F60CAEFF712C1E3773FE51B357584A917BC3E4FB950C442AE17ABEFFE262A4A6550576B6E8297BA723943AE3BF60971B9B86CF952C806FECBE937C7B15C91C9E438EBEE95E51D209E60105BC43BE345167AC92492BBA9549807361A06F525380F5F19F7D1BB926CB1C2FA726CF371174CAAD5034037D07AE2F305F4BA52F9415B0C624398B936333D68625F533D7DA20D62507768A73F579AE71B2193F52A214B30921DC121B6C94042B386F52A202794BAB835A9391CCBDBAB2DDD94B3B04ACF71A12DE67CD24D1A85E7330DD36BBB6B387ACB6BAD3A59C1D292FC24AA6045C8C34EA4771B8137537B644997EB45BC2EF2A1165B308D3C926A0D23D09E749A142493A99AB1C3A80A87C3003990956729EC1C6C60A47A16F495813CB75C995AEAA481875830F1E906FD6EB993A8B3365189D1B50627466161451A21EE45397971D8F56634D90CD0E136C9D82729F8A76C61298A1A240F611824173ABFB52AC1AA4BED85B4B18939988895075E888AC0C519EC75EBF693D3903560445414ED3BB3D262074981524E361EFE44945B14DACCC62E2C335EC40BB4453CAE2524229571ECEB64A25026B3E1CA249C127AACC08CDE4203EBBCB6FB427379097FD222B4E24CB9CD47381C6B780553DD196BFC6C356F031EEED6C85B57BE19AFC39DD1F929BBB2D627F5F19DB", + "sk" : "DC0009FA7C1C6BCC6A0164044607925524CCBA9A8C5986419805C924374838A2764FEA94D7DB8CDAE57360510AA9DA6B61134D767B14CC87A2AEE90A68C10CE92A41BF8144E97C73E2B730F15673165A5647CA4D536BACF780A3E33A224F67B58258B3718BC184534B8436C1162BCEA0B5C6599C00C262C34283B5BEF25A1620AB60410C9FF0B21CAC43CF0A68AB784A1110C183E06984596712560C087AAA05B67BE9D6BD9520A486750E18A14AC0796AB1E9C33629BD1375316BE248F06295FFC665D8D9BDB701C0447B33252360377611B04A30812B0E2D003CD1365F122104E71B8F52256976B6415CA0B1E2713214527515D37ECA3C466A9B11FEF107577CAEB5E17E33AA0C9C4A71C7BA9B4813B3413BA65887C4FBEA22E80251E3F727D2B7B0128555BE6965CF704F9409B57B939AA2612D1D7241ADB88EAB14926A3718A483BA06A604D72591BB0377D53A31B8810AD8F70A8A2757DDB44FF1B02F557B9B61EB5A33C481F4B25AE00B1389B93437B5CDE202BA6282912A095F19255C7B7BC136072EE3E7CA4C6800C415A2135871313BBDD47338CEAA715AB7450293A984E3805141B1185A84BD867202AB34B0213F917728176B5EDEE0A0904BC29AA74880C8618EE862C326C37152B325B5CBED5C679268AAD2C903CFB6A5691912FC0508E23A8E88957F89D79E93B91DA85742EDE6AC13F0AA15D76B9952C1F5058A3EF0B453691EE45943B7564ADCEC64D4A02389D3B2F255553E440203605A0F7A192BA417EA54AD6EB347AE52250C5A2BD59C46BF750D60372EAED87C8BF11C44E65FB8DB1017411776B161551A9D29212E98CC9C6C735FF8100267296DB77B2425B6319A3B6ED5998A6426125CFA78167C0A6EA6C6F8100F7A19628C325B4EF4B29BA97297258565DC5DA1042F80C7C634140A2CF93D2C19973506CB6B84C67E32C0A7D718B7D86265A76FE1417BDAA1C8D56A1748016C4B9AC886736A8FB3CFA2693D4A443309DCC003F227F1586498C0CEA3D6853E5C07C66AB02943CF9CC791FD2289AB7A1A13C7B3D3A0B990E32D747C2588EB54018C1D25E86CB4D84538DA8752248C04353CEA97C534801EB223C877682D2DC50284F932095BB2E55B031A144F8F646AAD45935B8C947B37B19B99092A0B636D0962D93053E147030187954614AE54CAA88EB3736C5745D2D5BDBC462389F97D72F128AB4B5BAB3A7AA9E1588452C240774CA5783F56B01824F007D1946D0414A1A722C32154598F3682F3E24AA5C80167956CCAFC84B6C343986729E7D03C87F418482B56963243FA67CEFDA9B221253753A004BCCC4D156817BCC9B8E7332128B38C6F6625CED3713C51A3EE137D37785A35D88B7A2B4DAAE5B356E07BF6EA7A67B5763B04A2944475A5323002B30A6680C9EB08B5954347824A2AE17A29C1A69523CA73BBC9403C35C3B2C74AFFCA1864E24556B90162D07A95E138EA80469D021E35A1770A1C3A5185258CC9659D10054F814ECFBB0937233C3F322E77D3821E9AB61033C24FEA260A4B8B3004592C50C68D41B72A67936598A177A6AEC3163BC3DC9872415E1F60AC07640B9180A20500BCED23ADD93752D586915A2C448301449E024967159E4F278C674B0313D00DD69CC819C354F5722537DC4DACF29F58B46579B917BA38B2807978F1569DF299246A6C23B1E92907F540CA9C27D2393B0481CC10E47D3246CDD599312AF942A38CB8FF936E3B64743A6B22A7E96925C863D82B963FB909EF439FF687544B53937C8110399C1DC37C66C987124AA56F9B8C8EC0501DC170252ABA325A5A70BC134A2E73C90ECB5CECD373820A34EB706BCDD25F95B3CC9C035A4F1659CA5252A5A21D895CABBA090C5115028A079BD81A3C948201B6F9981FB45E73600B2475578D08A8218A9D832CA974D992D13984664057FEA0771A0C125B16B9A2D33B72D2478250A4CB9A34A1B3CEDDBA53D1A4905332217875797AB6248C6B97052678317A99716376B851204CF24FE743782C88CA93B90DA03C3E54321ED9500AF39B9BF2F7856B13604013A7F502B4C60049B1A03E91292C40D487CC9673E8BB150CD84B11C83493DC0CA1D5568F532AF3E54C8166B5B180A6E253840012B7A5EB4F05D53F3BCC5C9414136A70057037C7B88266BAC70E4C01B0944633D5F98AF3845CA7C37F1BE75A52410DA5D2BF9D102305EACE09009E6EA21B6C543A25032612492B58247F13F01C6EBB27FD469DCFC83AC93071D3368FA128A4C71475AC1817A8B1744C9A2085E54EBB8455BEC286DEE50CBCE87EBB0BAFC32341E877ABA7A5AC10DC99B65687AA53CDF2585976A06BEF586E8993953D5A3CFAD8A7593349F9C31010E6BECD32CF6EC70F4EF88B1AB955A5D6AAC2A877323181668A2C731726236C4C1F77768ED06A7358744C91C690029C4C747603289874032FE6730D96392805E10B7A50A6B849985083CAF8D64C1FC257747613B9E6C85E455ACE3755CA9034089162D96346E3F0CDDE0A81F6A7727BABAB5F1401DC1832BC175E3576B36747101CCAC305D28AC5386EA92447F483408AEA6AB22C1027B99B9F14A1B6A67A24FCCFD5F52295DC11995B9503D76C7D0BA51ABAC76777B960C45CE8DCC24FF6031DA9A99174BE42A381654B5C9697B13188A38C278D94F801A2B94685ACB0935074C06272E0BA87B6214F717C01D9508D77535E444B5A2B461D02ACB855D7309B8AC6B7731BAB6626921160E1A35D0BF14DEEB922D770BE063198D5A72DE076216BB366A0889773BBCDEF5872934A894C7664F568AC7F1CB5BC72587767025A271DB13A0CE44697AA4C0DBA80A730C0C1C2146B36A50D23926DF520AB3460B18687921DE988C2A7C97DABACC5AA849068AD76F10B361B9A2D1436BD88C962EC724DC15A6583CA8A41704F3946DA465042B808F2513B65A5009DA5B44125308142478AD82AC64940164C24A599C96EB69EE5E4BEF1E45066E2CAB719B57FBCC03C1985472CAD16A2699E4939B2E2850C1B24E8049A41362B2B908E52E2A9F7808D06A6298E059BBE1C5A87A8610A06AF0262BC61390F90D962EC95BCC907C850721778A947677A226C0482B5704E7E0176F1E28E27150AD84093AE862682B4A74E8A7D330C4C4E144C3A39C3A3DA3C75873DBACA4880C2940CE30ED10C395805C0BC043CD2861B2E9C0DA1B59474F8C492024CECDC7676D4B8C4B3311096270D29057D05CBA6494B6AA07379B73BDFAC9A561A8FFDD3A43C5877D85749DB9C8379ABB29F7567FA1CC57B09C35E7B6FF3F735CC18473049BA2D5837EDD8176531B67E04A509BA811A9467C633B962E8392D065A03865658913F494501FE9C0A6A649DC8F3256B6274CB6235B0CB278132676D028A24E07595F56C4727A7B11830C1C9840C002DB53B6198444E5B63BE4C46BE9548BF4E1598EA6371686C63DA774270B82C95F0C9A12B5C8F9A591EC50971D897B3C1C4E0701DA5E26BE2760AC99B481151ABD2A20BA343BF46ECA8699487D14A9667565CA4E30EAE468AC5E6CAE54B4ADCD5ACD74812EBC3B4066021B0CC890099B911553B95C794643A97F99A512CE874F10A3C250A513C005A70605429F5943600CFB9E4B2C5E72C821149D9C2C554C43D9BDB271806AE8B58506571C061240B6E7967417542334773178424D46122C7212E0BA7B5BF4388E8F4A3F60CAEFF712C1E3773FE51B357584A917BC3E4FB950C442AE17ABEFFE262A4A6550576B6E8297BA723943AE3BF60971B9B86CF952C806FECBE937C7B15C91C9E438EBEE95E51D209E60105BC43BE345167AC92492BBA9549807361A06F525380F5F19F7D1BB926CB1C2FA726CF371174CAAD5034037D07AE2F305F4BA52F9415B0C624398B936333D68625F533D7DA20D62507768A73F579AE71B2193F52A214B30921DC121B6C94042B386F52A202794BAB835A9391CCBDBAB2DDD94B3B04ACF71A12DE67CD24D1A85E7330DD36BBB6B387ACB6BAD3A59C1D292FC24AA6045C8C34EA4771B8137537B644997EB45BC2EF2A1165B308D3C926A0D23D09E749A142493A99AB1C3A80A87C3003990956729EC1C6C60A47A16F495813CB75C995AEAA481875830F1E906FD6EB993A8B3365189D1B50627466161451A21EE45397971D8F56634D90CD0E136C9D82729F8A76C61298A1A240F611824173ABFB52AC1AA4BED85B4B18939988895075E888AC0C519EC75EBF693D3903560445414ED3BB3D262074981524E361EFE44945B14DACCC62E2C335EC40BB4453CAE2524229571ECEB64A25026B3E1CA249C127AACC08CDE4203EBBCB6FB427379097FD222B4E24CB9CD47381C6B780553DD196BFC6C356F031EEED6C85B57BE19AFC39DD1F929BBB2D627F5F19DBA8F24545F5C1F2244D7712DCE7596CE08146DAE6A7F474DAAB4056DA2D22C4AD11C11C1086F0365E9FBD525B3FCB4E4F169FB488BF0CBCB455EC098D49E903C9", + "ek" : "A6432DF3BAF8990CFC3A7E8FA9E6BAA7853110A822A5C7FED3C9AF97F6AF89970714994D52819FFCA6FEE7C2CD61FAE8546F449DA033EEF31D1EF8306C5AF0715D7B38BA8DE0A372182126174F76628EC9270C0A0BB534D418B2E96AD0ECC39A29B86B56241D60D047E8AE602AE705C132F2ECEFFE47D0864A5DC9ACC3083B44025B718CD7858E6216A9B8BB7A58B2C818E8874AE47A29E6C74963448E44C9561BD8561220AFB7EC68ED272433EC3E8562E64268311E3D8E03B199023EE585D32B82012E0E83BD1BF5377FFBF1F0EF66D8769CA4FAB9EA29EC48FF025091BE7247CECD20E07274065600636C28B246350F9EA16542F72F4889C2F43CDEE64929BA4391F5D181BE496F6132842DB4B99CEC05F0FABE705C98583CF16953FEEBF7698EDE10E5F637F309516FD398701C6225698B9BA55874A605A9B1E698FF87080CC958B3922608F35A9B2F43CACA6AD20D4E43E6343AA8DC8A3C2985958E189A6CF83E90F0799F4E4C9EC70B2BCBBEBD46F1D02B466C3DA4423E2CFC4897427E6DD5AC23662C1E4ACB89FDEAF5407A397D6A15CD4FB74E26A8BD3518FC17B6F5B770780FF8880E67683ED15D5BC9F82B8149336DC5BEF1285A0E87DBB2FD840E0B532DE0D309F40BA1B4FAC0FC19053FD75AA5F84D86979F94C5C885D1A747A50E3D1253CEC40EDC8931CB0E5943CE6899B0993D1B809A9FC1CD6501F81C11541EC9D8C78835A912D33D3EF60DADA310B7FF673ACD213EFAD11888C2D28223FB3A0A908413AF98152557302C2EEF35B612945D0644107C80A4ABA23F2005DF7D9E74B31785551821B1E19E4B92D6893FC4CEBFC0B0B325DE9487135D1F135D0D867A84B8E7A39E1314EFF5772DF2AA64A8C0C30B1DF06EA6BA73C9558CB3364512928B94EBDA84F95F23434F376FA4B09977A2C457D98A4E0005C851571B3B05CFF5669501B38E2E6C20708151FBBC2A38A883476472F0A422DC805C3E9CFD83D910D0BB379110A195C1DE77B25CF79AD7898A4DC5A3B41C975EF8F217C4DEC0F0F2012E8F4DABB64BA7B2B085E27E4A1569DF3AC55E23D09B89AC2AF2C67909BE87A430B31A69F07110AAAD25F0701FCFFAEA9FD98AA01EA58A9A295A843F299B1252E1FC1953C92802F60D8B8C11199CF38C00DDFF6BA453C864EC264BEFC6717007F77117450DA71581F2E7DF7A8F8669EA12621647374C32979288B635380811657DA4F5AB950A490E95A1DECA8FF4DD68C94971B105A7AC3517B42D87F29D0F66C58E0D76A201AF5F42F30216F15B99B80946255A54A58D781E7E4580080E9090049B8E0A02D306D3AC8A451E0E8BEC68338218F3607CD7781E9B6DA8B43E1544969E6E4E294FE46BEDE9226B0C43C7A1291DF9ABF5428E832298D8C4E62725A93E26F91A6ACC63F8CD387FF34338BBD718C36D547C3DDC3100E745E083C1054A22319217486C978025611ECA26C2D40CB84F3641AA20E20BE7EF87F2F8E354630B5B62A491CDED7CF90DFB76B703C67E217DDEC770E4E898D611858C1F623EA675A8E662EBDF8F7658ED68DA628BF2292E448121409E77210D0853056FC85C4D75AA19D46660F190763E786D8B8355E4FC83A6D48F446A974D5EA23A69B731F2CB6B94814559EE86A2FDD28C657DDED508AD76FBC0C20F592B6B2938894FCF318E1C8AC4CA568C2F69B15837F1EB90FF50F816BE7D1A8E53BB145693AE54E37938E17E0573BB60E1ECF8C6A21D6FB30C7B0F35B4205D487D8C2B897F08ADB835D3DCA93A0997B7033CEB6C6D0C2CE7FF0A6909F5267062B6707F89D24264C580751F43EBECFA2DF38FC32B6D4D7DB7A47A23C53E1AB270E2A2EFD9139F46EE8D4D0E0CE2B35890CCE01883A3F8A989171E042DEE8797AA9D71C26C99B7BD2591BCD129C6F29ABEEC2352D4E1AE48E709AD0B171876AFA10E5969700A287E4BE911D9C62917595B1E9051FC24239BCE1CCC39E501B44CC74DD881C7E1D74CEBE761C1EDCD6AA7214C5A1110E60DC27E97E7CEC5B47759B149B75DF24F6A1B7C605C9153FB0A358A3AC647393FA7CD2AB584C25A0730822EFF840CA1268F875C41363840DC71656455F15E2C01E3533E609105DCDB9EAA3FD411F2422EFE960711ECA89BEFECE486A58E51091BFEC5CADEAAEACBD4FB2E39DE3A4554243DF48C58C2EE7F6B4EC07562D2E0BCDDAAC02E61E00752FFA4244BFF1EE3F8AC09", + "k" : "858F06A2914F6B5F3C5151561631BCD02A9DBFF0AC018FE14BA0D5E14C244F27", +}, +{ + "rngSeed" : "D5F23808871544E9C1D6EACE2028362B48E225312F77663E9F78CAFEB512B908CD9E25875D61A16EC615F4B8FF826856", + "pk" : "6D3B096A7383933C0CB6615824885499F79DC06B5E874203C3349B2C3B27B1F1012E52BCE9968496C068B6E6C7244722621A1A44349314845B1D8831D9821ECA386EB8FC254587BE5DC529438485B3FAC44AF0613732509CF225F5C127A4056CD5E503EB742CF03154511969E7A743834708D71579E9CA4A4E281AEB177EF50CB0DB826DDD17873E63A182E3B001F659EA3CC73CFAA5D7D7B5E7E9CDAAE04C9944978DFB7ED34248D976190CDC0184930E25C6306312180A0B8758395D1FEBAE95B22E0945C5FE265595A9AE91616CF9F35B588B7A02F66D8D49800C50017C7272BBEBCFFB10A16A5C8560130D96FB0C241A286BA949620AB83539B83D862DDCE2507EC4B4BC4330C27517172B43BDF09A5E6A5FB684166800372663544859ACBE07424705809587A08DC50FAFABC1B2F9486CA6415266C502F7B998DCC947C7B5F5584CD34CC90A4C385F30A2CC051237C6A85D4A5571305A5182C970B9BC87268484F293464545F4C349E8B2BA3E5B4A5E7C42237C0E6E1B7722B04E3D02A27D0597D7169A49E340A778179A924A1D31C0C3D53BEDB46868A62AE17847F130AD1478B8428B09FD71B028F1933803318AF78103723AE7E1185801872F847753862F9F72323F980D6BA9744CB6C079341B02443B52E4BECCA891FFFBC6084AB40BD17AF7C6B2B21C09C170455C52C4C7093C44AABBB1A0C1D11B12070894F7649112F32A98D976C72291100A3BB4948F928771B063839A94A614227587D1A9BD25479BD8BD06E114894BCA10814F0C516E1BE41B81CCC6044A8F3654679DF531C7220982760AA39A4E982BA3247B009D405C0B50969C694858889B4058089631C57DD1C5FE12ACD5B27143D09A2D90C8ABD8930D16769AA44A3927967B2975A329BCE9599BFB170E02A7994FB90E0B1C7BC7DB753C065CACF820B80C6C1D585624C93FF14A26AFE6245AD8A6B2C082EC871DD1FB10C3ACCA1898520647B8EF8C0E45580C87F718EAF18ED4E97EA1516ACCA657BDFA16493115E6C90EB998CD31E6CA095066BC75057B2B71AC2A75711A7820984AE9306DEA825C80F26A1CA6C686189C93550D931A1F73FC3ED0341EA703C033BB463C6260097C54BD17996A82ABB0D32010CC53D81B7B7052B86ABB6302B57D6A34895D09840B3B6A50C9962DC248EDFCB328E94460D3C82819CBAB49A79F742A86E85577EC995A025FDE616FAD52C4F092BD89286297D8A8912294FAF7C959CA392CD40989C92B8229AD3EC91D352A6BB7D757D3709C5810B40157CC0FE006BFE843419B8A1D792D00C1505E0A63B39C7C2CA2C96F695426073EBD50283572BACE67C01BB7B27B09BE59E589BD60ACCA376A8630034CF87E9D49411648A1B05C329AF92CB29942CB2369381C3EF761A02F8C905F963F0B08514A7C1302B4BAC9F261FA37855B67250258C003E5BC9AD07035E667BCD6A537F35A0756BB2801A0ACA56576D72F3A8C0C2F371E5AA036AF3A987BB550AC06980BEA73B938CE91715A4B19620A08BE52695ABCB3C833ECA2824B60DE483810857ABA0A9292911C4167159B023989D061BA81C94DF979917C72C8EAAE518AB0E46AB8927B5B9DB690BAC6720667BAF711A73952B033ABAA59D5C4CCF676007044E26C2BB31B5AA2095F2DA9724570CB04174E9AC174216C1390A687C60B6C396AA48EF849D19234F36886205B0B28250E7803502565523D0CC0BFFB78EFE64DC758CF3C93BEF42103694B434C4819F82BBC42AB45AD827287A560EE43600B87443D8BC91AC5B15FAB2701F05577C32678E06790808D4A6965C30A0915AC8FC7950B274C428A43650003BEEE2726BD31A09DE14E892B54C2605269B8C22F146AFE669DC9C4775D200AA9534AF5612EA736B01543788B13C3FBA608AE90AAC0DA9335E6C115FBB1D67938B86849D5087A87F3437EA29D7B899144FC3E739A4C079628597C618B554468F56CC6745FF6500D3118C55A8171E42B67CA43CA32135672B22286F78D0485B363D63A2EC737D2AA98AE602D3C485814D2C195DB5D7BEA8B3AE5470FF7A1E8225F82D565414C6B59379CC5B26155F682F6098795C52E3E8ACFED87743737C1BEE0BA875A95E9509D89F3667D741CB3AAA989378A2425A0E5F218C02763DE4345A208C5BBE4949A506DCD5B01C5F8F4EC5F5BAE6946C95AD7FA4E1E5F80354B5112D882796092029150D5D621", + "sk" : "D0F6234EA63D21038094AC3082F06F5DC2081B5A6083B00A59E5490266A351259927ECC2855C144A83871475277F89311B71436CA835797A1250945A9CF23E041A7020E0CC3AD5C719C9707A6B823B3083351451FA94A7258986C05421E8C98D6E0140A8C171C1116A5A6939DFC95308E8495A47C2AAB4B4D30A663E005CA89273B3FA6BED9475BBFA3A6526673D2B4428F01A8041377DC04B9D21618EA05CD2988070C91E95F489B76225AC396DE3562BA513B3F23B9809F86EEDD7BF9A29A8CD856587EB558772BBE847C2E93497A226080DF9567E3A6B22C513B1523C5977B1A1D573336869EF2389B37C3867A5121FC92A097C9640BC996E2845514B04F1B315EB0C7CE4A0B0B219B9C0846CB46C5668796D83759DA3A28348F170C3042A86846B78AC7FA5E5C831C4BB953CCDF6821BFD674A8E775A17A4429A197C910B0163454EC3C286CF94CE7E9562F67797896927BCD1B07C1C1B62714A7261AE5D9180473120DA730C5E3B8CF1B8B9D9AA54D5392D5C695BD84BADF3E20CEDA5BB15C1A1C231878D35267BB49571A2216B067BA7515B3CC2661BC8742C3A8616436D117A53E6C96474FB67F0332A261884ADB452219B52F31545550B5520C48DA1ACCA388BC35AA120E05433EA1C31B35113F9EC2828E6BF63DBA38AFB0ED144015C3BCFBF221AF1954F5D95B02E3B3DF2EA8CFAF09F152987E3DB11AA112FB0270D69FC3BA8E26AC30556340BC630C60AF699171DC4914DAA5FBE81125941982A900A1155188A7A55962639408A2856F480FE22830305078C8785CB9591728A47B0043D0A987A498542F31A113EF0A2ED971A8FB2AEA9B334E5354B901393C5A140B05A72E54C21C4860DA23019EDAA2D0B8680E4379A7813B07DF36969E22AE2B4102132711A63171C8BB97F30A599552BB8B902CD9565BA1B0CAD788CE92B85B7A468B8348094BAC38980981797C80032376DA288DF3CAC31F202F3C3279882B4124761D1C02075303F6F1401BC4B361DC156A417028E56A2822BC941C7AACF26667B100F9BC003398866E9D104F9090C46E23C1D249CFE4619059B38A9012DB2D8833B9C96CD40945B83BE73B16FE8E53F5E69612F488C7D0753856071882741D533ADCC9AC1323513EF15BFAE06761385A651994085EC4820E75E7694C5B2423CD12A3B0D06A7194B87055B973803899B4492AE8C6E006636E3A21EA9D872B13C9364E208E99C2C74965215D6290EB96A802A1C836C2819772E21457596982D72E6491651070F1CC7E6861D5A7A01BCEABB0DAA0692321E9F49BFFD83A07CAA9A15453831898DF4505CF33899F4CC81BA7059D592690D784263074060155C4491130FB9159C09028EC559C4169FAF663AF83C8D82DB07AB08213B1B97607BA0DD50962966683B014BF381BE25DA2EE32057BB55562A6197B3D6555570AF1107AC025CC8FFCB3F4CA17EA33AB0CC792BC83B4674F0014E3808EA128F7E3CC01B4495A0B72846938D23A32ECA110E47B17C7DB043340A79F7D521407CB0DA754B59F267721C63D46C5C4FC58D88F75426A00914DBB3E98246D1B2573BF59CD65222E5939C34B25856625916C28C9CDB82C5643BD13C9B8A634235F1BADEE54AA3180C1C2BAE97828D8746AFFC737F5BDA768EE34BF9FC17618164F59B689F094AEF337AB0F56840DC569F20B313647B87C74154A4C6B79968B29627EB067D2918BED7A94D24163848830463A1088A60C49A7C3FE9579A58CA4277A8A75FA7C4A734C2917A98E540B5405A3699949FB66340B36C449B685A1B03896DF118A73213BB404CF6DAA413134AE2A5594DE4C98789B3F5E93FE9A51395D22F72211429252489673CD7668D8CD48B733A472A2736B82BA3DBAA0757B89DEBF5883909C82B7AB523E2AA6D0156DC2AC8C9F6352F038E4FF045F7A81A0F026881A3890425180E9742CDD0C6A7129A163338EC0AB2AC4B7D80145053AB101FF05F771568A724CEE02741A604C92B53485B617C8ED24EF14A2FC608C882C59D9BE5717E444FE347B0CAB7B07F4B5D405034C9BAACAE2C4E844046A95275738966EB87322479043ED7083CB2A60FEA71019BAF85D3866A5CC3A8B93F09260B5533819AA7B6CF0BCEC07181B6659F469533B3419F32129FB33B2E8166AA8D10ACB4F035D7E6226D3B096A7383933C0CB6615824885499F79DC06B5E874203C3349B2C3B27B1F1012E52BCE9968496C068B6E6C7244722621A1A44349314845B1D8831D9821ECA386EB8FC254587BE5DC529438485B3FAC44AF0613732509CF225F5C127A4056CD5E503EB742CF03154511969E7A743834708D71579E9CA4A4E281AEB177EF50CB0DB826DDD17873E63A182E3B001F659EA3CC73CFAA5D7D7B5E7E9CDAAE04C9944978DFB7ED34248D976190CDC0184930E25C6306312180A0B8758395D1FEBAE95B22E0945C5FE265595A9AE91616CF9F35B588B7A02F66D8D49800C50017C7272BBEBCFFB10A16A5C8560130D96FB0C241A286BA949620AB83539B83D862DDCE2507EC4B4BC4330C27517172B43BDF09A5E6A5FB684166800372663544859ACBE07424705809587A08DC50FAFABC1B2F9486CA6415266C502F7B998DCC947C7B5F5584CD34CC90A4C385F30A2CC051237C6A85D4A5571305A5182C970B9BC87268484F293464545F4C349E8B2BA3E5B4A5E7C42237C0E6E1B7722B04E3D02A27D0597D7169A49E340A778179A924A1D31C0C3D53BEDB46868A62AE17847F130AD1478B8428B09FD71B028F1933803318AF78103723AE7E1185801872F847753862F9F72323F980D6BA9744CB6C079341B02443B52E4BECCA891FFFBC6084AB40BD17AF7C6B2B21C09C170455C52C4C7093C44AABBB1A0C1D11B12070894F7649112F32A98D976C72291100A3BB4948F928771B063839A94A614227587D1A9BD25479BD8BD06E114894BCA10814F0C516E1BE41B81CCC6044A8F3654679DF531C7220982760AA39A4E982BA3247B009D405C0B50969C694858889B4058089631C57DD1C5FE12ACD5B27143D09A2D90C8ABD8930D16769AA44A3927967B2975A329BCE9599BFB170E02A7994FB90E0B1C7BC7DB753C065CACF820B80C6C1D585624C93FF14A26AFE6245AD8A6B2C082EC871DD1FB10C3ACCA1898520647B8EF8C0E45580C87F718EAF18ED4E97EA1516ACCA657BDFA16493115E6C90EB998CD31E6CA095066BC75057B2B71AC2A75711A7820984AE9306DEA825C80F26A1CA6C686189C93550D931A1F73FC3ED0341EA703C033BB463C6260097C54BD17996A82ABB0D32010CC53D81B7B7052B86ABB6302B57D6A34895D09840B3B6A50C9962DC248EDFCB328E94460D3C82819CBAB49A79F742A86E85577EC995A025FDE616FAD52C4F092BD89286297D8A8912294FAF7C959CA392CD40989C92B8229AD3EC91D352A6BB7D757D3709C5810B40157CC0FE006BFE843419B8A1D792D00C1505E0A63B39C7C2CA2C96F695426073EBD50283572BACE67C01BB7B27B09BE59E589BD60ACCA376A8630034CF87E9D49411648A1B05C329AF92CB29942CB2369381C3EF761A02F8C905F963F0B08514A7C1302B4BAC9F261FA37855B67250258C003E5BC9AD07035E667BCD6A537F35A0756BB2801A0ACA56576D72F3A8C0C2F371E5AA036AF3A987BB550AC06980BEA73B938CE91715A4B19620A08BE52695ABCB3C833ECA2824B60DE483810857ABA0A9292911C4167159B023989D061BA81C94DF979917C72C8EAAE518AB0E46AB8927B5B9DB690BAC6720667BAF711A73952B033ABAA59D5C4CCF676007044E26C2BB31B5AA2095F2DA9724570CB04174E9AC174216C1390A687C60B6C396AA48EF849D19234F36886205B0B28250E7803502565523D0CC0BFFB78EFE64DC758CF3C93BEF42103694B434C4819F82BBC42AB45AD827287A560EE43600B87443D8BC91AC5B15FAB2701F05577C32678E06790808D4A6965C30A0915AC8FC7950B274C428A43650003BEEE2726BD31A09DE14E892B54C2605269B8C22F146AFE669DC9C4775D200AA9534AF5612EA736B01543788B13C3FBA608AE90AAC0DA9335E6C115FBB1D67938B86849D5087A87F3437EA29D7B899144FC3E739A4C079628597C618B554468F56CC6745FF6500D3118C55A8171E42B67CA43CA32135672B22286F78D0485B363D63A2EC737D2AA98AE602D3C485814D2C195DB5D7BEA8B3AE5470FF7A1E8225F82D565414C6B59379CC5B26155F682F6098795C52E3E8ACFED87743737C1BEE0BA875A95E9509D89F3667D741CB3AAA989378A2425A0E5F218C02763DE4345A208C5BBE4949A506DCD5B01C5F8F4EC5F5BAE6946C95AD7FA4E1E5F80354B5112D882796092029150D5D6211C931F81FC67B2316F99DB7F55D799363828F7DE74B5E979FD7620C7449132D4284837F7EDF4788F32E757949CFA69DDEE079E2E00E439ECEDC8512097E2D2CE", + "ek" : "C6A8D5EDB5FDC4A9A5F45A5AD41F01E035474C0A7C629726C80A671716D02030AD5DEEA83CB07CC1FBF04E0F6A5C1B2A390558241BBCE3FE7D3B028552AA2B1D2590C421F8445948631E76F1A8F5BB06566D19F32DEE93A29721B21D99FDFF8CBB63A242635989AAD7C495521A12F1031669035F4E45F12A0D09E895D3FEE0220E9BC0C8D12D6411A7B57FC930BD2D9D7F2AEE4C409441A5706752E4D2DCFAF3C4213EE31BAD0AF11EF6D851F6C091B2C6C5F52504315AEC645B511BC6BFB65A0431E3A5B5F3743D4C5E634237CBB842005225FF94E5B6BE0C65A1293742F78C715C85726437A20583DBBB98EF4451F97A97A67E4F12E24EDB2D3B7F140C6E70DE6A793636A4A38D0128242BEFC433C90CC6F8E698BCEC1D4397309808B51F67AEF2997A8E7B059C25B1D375DB8217F3BF09F3CDEFC844CE41F8C90211A76BCA4759202BB33C933EB01C19A26D3FAE2587EC717FBE9C0D8E392F80BB5BD1039ADEB416F625956888A5844455C3CC7AEFA420660C586B81F53A9FF520916D0DABA6D03B8AF7C31A8E257EFB0CAAE2F246ED2AE4F31C3C295EADD85BCE26EFB07A4E3048D1C0A9DB04456762B55F7A4B2AF47407582EFBD7D240E3785E6DD7D1318ED77DCEA2470D0720EE17665185CB6648E0E41F81708E7B9CA72670223B469D20D1146F0D9438637F64E3E534315AFED54D1896EABD7D2E7B8901BDE34EAD417F2AC933B621A645151281D4278785FC891E67EF72E2BABE524CF3D489F2E99DEC29F017EB61EBF5E896417C96FEC9E202141FF52342F23581579C332574EBA9B0EBE56D9A59F8AA6985829630F446C05F7784485C4DC4348636F284B1C0B040E29B24C46A5CB77D6DC41368D405EF8881580D47D71B4A45721F0528289A8A371D81776872E2CD006984AF865EAE584B50EE8153DA83160DF5EC797DDC82D183DB6761FA085214A74B40C8728EC134410636A07AA518F8A9AF5914AAC9E1B290C1CDA4A6F13CF91610FF01E1ADAEF86E3E6B9C2A1656BCBB564BAA3678E17163A65EA5B6692728FEBF6A667334E987E65E76AC5B455C5C721D4275E3EC253EB79CE11BDDCE8F88DAD302D83E9614A44BDFC992EF062A7FA02760732F45F70BA33F6DC80F405DBFAED132210A60CC165447DB562799AD27E357D57BEFD9EE79A61E3FC43B6D141DB28781256BDB0454D47026E61CBE64F7248FB05E09FD81F1FAE3A83754FC1FD8266B00024471D4A3AD57CC7F000882B0A1974407467F1057C30E333CAD557B0096E0BD7CEA5786770ECC5A99723801B1D983A90E226AA8D4EE64CBE7F617A4149C871B1DE6E50820518159E8575154093D0CFCF0E2FE3440CC18D5E462192093FF5178D773B603D797098F2D59779D3B7D412A7EA7BD35B2E671A6B4DB074179BE838C3378E3C8F1459DA8EE07EA68EB3A790E1F1D1147AA044F399716E56BFC4C123CAF4BAFC0043E80F64D8FEC76072DC30B00FDEF0AE120EA230151CD50FC20A38808CB3AD147AB0761AB4554ABA9DEE33CA06486D1338306EF8881F47CE6DD4E569BBD8AB76F94FE8B61E4055E437A84E0CE77900CE0DEBD65692EBB581A867170A6E23B4BABB943DB72C903731F600CF9EF6B1A5AA565ABBF24589CDA6A8553CC803C6CA3EDCED396AF2C3489B44D2A075A98FDF77932F464C06508FE94749D2D63E8791B836A6189ADADDBC11833B488E21324535F7AFBF48C6BE2029FBAEE2B2C364B4682637D71EE139CCEA10B00721180EDA0AA49B7C4D507077FDFAD122AEA12F0355DE13C582D85A8754A9864B70B86DAC06ACD4276E51EB0DFD071544356D4ECCE888D0A4CDC905F20A0A8D1EAEED1C1380EB9D17FC667843508B811DF376822E001D65E3BC1BD746C2BCACE26E7DEA890D30508654D3B432BBA36A0D9916CF604673FC1B7D912899050C4BD7975529FE0BE210570BD491DBF4AF4CDBF9EB60F8EEFC19E85FDA87B52706D4F2ED11DDEE3F564B80B530FBF26F89614DEFC1C407690CC9C4291229743F477DCDEA8FEA9F1810D8965ACF2DDB258420810320EF2189A6C82F5D6234E65CE0451DE6F36DFBB8174AB9BD591FB57AE88852CFD5B9CE0B105DC8A779B72121947B5F27076DA0E222A6F1B28AD524E4542AFA51A6F8C8CA4A36286500DDEEAB801881452A1553CAE5C5E3E4A67B135DCC5B344659C987BBFDD2D40811F80629DD59792E2898455BEEE", + "k" : "503071C945ED4827A0022026DBA9CF39FED584A0625E0155EAFA4947E3417F4F", +}, +{ + "rngSeed" : "822CB47BE2266E182F34546924D753A5E3369011047E6950B00BC392F8FEC19EA87C26D8021D377DF86DC76C24C5F827", + "pk" : "CD22CA9CEA98BCD401164C349B35C8B36424F294B11EC7C7D0A3953FEC20DBB283EF99A3452496D9B86513E33633765C10B45C6612BFCF590F6036A711EB3DEAD00067649EEDD14491716CAED40A3DB26D7B00C6E8396858C3916397166D24370B033EE54C3D3B85B5382B1F3F1220325AA2F804BBA473CC70B15D443548491416BC1698A5A9C39DEA2BA59171F35569ED6946621C1B3647598BECBCBBC72A0781C77BAA5BA128B1B7053B2DE9C122B8790125C50E003A119964AA48392A96B01D7675AF541B46B4369B10C38A2C68EE5425C5F6293C2255A19A7CC2607774D342AF773A22C3943A9B411BD69A92E1C756993A1A392698A93D5F4772C374B549C15A0BD636BE908641A7B8ED758E3C341292598B82A7976F45AE4FB0BC2AF0352D92751A6A5E5015444D3B82CEF064D32C3BEF9B2292571092360E1806B5E5A892586029AB421ED247AFFF408F7FBC9B5CAB930A6896B1250AB1C58AC4231FD6D0BD9B990B649028E4C28E435093B36462E28940FD2723E7BC20E59914E1C812BB3AA912318F15472A64B75C12BA361B2843751611183870A6028496195CD5D219698A89DBCB2C1C06AB2BD5937C1CB5A2DA7774BC3FACFAA028829F3C3C9BD6C584EEC882CCF3AE1B00B1357692ED377F09712A30FBC73F17C0BC462A88E64DE262C24E7A7F7C784DBC5B615AD57E58484DB23363433A4680126C2EB5B9152C162E3277C0BC4DA9693B22DAAC51A1C6107242B7428AC3F21F2C3968810435F9AABF3C65B7DB7B37361218B49B9C76695B53C9A227963CCC1B60D447B3B7D15765BAB6B3B73585F26C2F0862C927B6F23624F360A4F6C537B09563ADF7A9616A4DBA03732C707FED845C35C660B5317EF652055843CBC28AC501DCB493EB5D6BD5C322EA2F2A8B61418B9788482F51B8135F4C1F1173895057AD3218387D527133890FA3A9425D73CE03E1879B85A5B120285B823501487D5C555ED2B7BFAC82762B9262D3D4B3B64736497899A768903750BFF4A82E6A0097F3C230DBA5BCB0AC95006852BF60480D039D1FCA9FB758B5562A384160ACD9C489A3B4BDBCD96989C57EB7A411EA3540ADA882AA567FBB340B518477839925577C780953BAFD0CBE2803626B89CF1C3B3056C4BD78C88818211FC836765FE813C7B18E5DC9725978CCD9EA8C7E1710DDEB883AD93E2CC987024B817C30908AB1BA7A658399DC931A4BA4FCA5A10398289E9718E906336B148C328C2930B843CD4CA0D4735B633618E8C1C327B29596C24BAB053867747883231F11005ED6987679544B51C45D42CC209B7061A91A0C82A92C943C85C149B79C1A190716C03F156D3C22AD27E7B8B87962C8C5421D3B01C7EB2220452B22D813D2180E7A38BE15B6976AEC7659D25B60D3C780FA75C3654D7F9B6DE0D33C8C28C97B6B95BC8C2CB517B497F73A98C41A64F312FFF48FCDA7B07E86A8136C05720A8740D866BC024CA1E22D43F6470C8A38A7301B3CE74585E6AB8B899B13EA39C163AE79E764E0B846FCD57029A73708091F053212C6F93F1173A854B26D7E49BFAE38046E43193B98460D171FB48283E736C7A1651DEEE6272387CF65AC876FEB4292BBBC9200981299C9BFF13690D6C2017BBD3E257700A111FEFA33072CCC8E952263E4867590C79B558187E3441A930964AA3EC0441E91E7AD198CB6E8959A35051DDD972A43A020D0F968EAA8696B9686DAB01B9F9B8095522A7B411D486444B16AC4FEE7B245F50BA1A26D81457B802BBA966AC8EB300CD92773CA26908A91A2E23B21B0116DFCAAA5F4A57514DC2AD736CC788904C29050389B80CAFB0D71B131B567551F6A2E16390C55234E5AD50080EA6268047618B333A49795B4233BD07530A89C275BDABC4EC99D84A812D9E20E2C27072196138386BA42CC4998314905E070ECAB69F2D12AA204A32AD28658DA3FAB69223521B81461312CF88700A49077914AF3C28A2F544D608209E24CCCFEB46AE13BB90E8B86A4BC85D5F41A9ADA7A957CA8763ACAD6713623EC20E2F199B1270966432BF2B8CACEC65776D8A63A471CB4A7C891A01BC92C8C28719C3FF9A8A7A350D9454729D2CE932982E94BBF30B298B3353CA6C459EE5017FCB724FF430A9348B9FB46ABC86374B245668AC71096501A7F3313823C5749E01D0E40444111BEBC0A6858891224B08CFC8E74C41084FD5C03C102480537", + "sk" : "2B8C2EA5542D9E3B90C417523F690109007C5AA97940102CE5EC7BC9BB471726B202D02E4F871062C281D2A095C4CAC14D6B9ADE99421D2599FB696942F6B74D349BC23A2099F687F1A3B1DB3781095615A341862246B29500CF6C3828085C8F72C303EBB9773DD90C37D1001BD70E1BA70AB99CC2440A6D8B841314E84C71718C1FF802897ABDE7694D49E416090527A600B2AB4578A378B0CD9B52308403CE5C5AD198BCC6DC0B3D5BBA010AB9D5C18CA3210111654B47FA504CC2B34EBAB1A9E328FB963B22491D5DCB13B5F46B3F43669101483E95AA0BFC83CBFBBC6656269D900138DBC252206FE781B007B3C2A26740643B0B9E6CBA3D83A3546B112BAA3113FC5CE4E94DCE8ABB1180564C6CCE9583A703DA022D20A14489426E6693BA2710AEA52761173F5F5379CA711DF6972E7264B3C8D2805FB08880A6420EAA1A060476E792562CD3CB8A768D2BA32402B2659330B7970A1AD3782D670486E4E73A6CF47938549A8246991D205F4A4BBB8F977DDB3C8F724110CED267CE681E1240AE0C9674C4E20E4D82194A1BB835E1B56166CAC3714E3B42A60092BD746665E253933D6786DFE6B95EB9A98F7C299FA9993D803755E40EF80AA7DE893948B5BD65366288A7000C6A5C3B7C5B00D7102EA95F490BCDA8D6AB38520C30E231A449A69BEC79CFB80DADA50739F83A85C624A1458C135875A803041F186FB6C50D2C0B657B59377BD2AECCB343B56A7A5DD2466FD902D5B5BD3CD3557FA31465FA8CF9CCABD05A24AD290988355EE1318789FC81E4D112CC797DC5E087C0CA19D5E8B85C57463F456868EB585A188A27E51858F8CC8C24A9A1B47B38934E07B92529C0722B98AE0C3BA8D7F329E19C0F6E8092ACC7C617FA145C37BB477501C1919B26B041AA6641362A480397C5E0441439545DEB6B5C47D01539337F523CA078C6543ED9984AAC812638A00FE930A07B56E6859A20F0CE54617EE6B8395867319930583309A67530AEDF8018B602536D33C98F81B7A7B6A252A00073443C9FF4BDFDD87B3513536D93C908188516749A28A92A410919A2C803196B1E4A533CF8133BF97C2F49FBBB1CD19E2F3838F3D05FC8E5C11CC602EBE5A2A5187FF2A74025A7AF16075FDF88374624305C191116C9BF59DCCF9FE89E86F007A6E3C0B0DBA7333BC4C9733214BB233E05C8A033AE93E85BFBDBAFE31260E8F7A5A1ABC9DA303FADC8697A264012900FD1B713F8DA7AC5CA8F2206BE63C31C5FE3C6F6188DEAA31D89502AAC2AC5052B982E3A75B385AD353C9C035C862CD5A6290076C959B11E6A4832793378B9828B0236E016BF6817511DD9A86022CCE5182F660013F8B2A036A993C90740A6A5AE2779724A60B872E5BF76C78A6D95997397BF1092B2827924DB015CAA204BF23710DA941E0D3A1A05458EE4386404AA5EC1CBB108925AC4703048A09F37814C78E63FC4B31F2341C559222A6DB43D50BC12D8C88962CB7E9149C009414C519721B63970953524009B8BE2BA1644C787EDFA0D9F9C0EAE722037F0546FC96CB333A062206436DC21F6806099BB5FA43879E2D433C9E1BE8B073076B1034D062AD0348E6213176960A90B7AB4DEA8ADB0BA41C73B2C4BE4C0A06200E3A975042346B52244EF5334C98189247092A19092E8833AD43096E4B47C50668356EC0BC5AC212E8A1972E40E7029561AD20E33BA29F97CBA0E3153B338A09841BB6EAB67FCE41A86265D6A2899D1B7BF4416AD1AC211F7969914930DA09844A2603989998542EA9EC24C0A5D8B01FEC38C33E84D51B93C360A4D98D439C593063A3747FB9C2EB16439AB7035490A99793939445CCD33C4AA2974AACB21873A7659A98BB67668AE47548AB98B336E2103323522DCEC9B59C80EF0E5C935B697C0AC85DA18766B39CC1E8C1319567B9560109C2C2F66A9AE528A889F500E8E11B9D548690750C54AC1785BF998BE78CC935BCCE9E8185EFA9F009791D4A687F131309A0C8D51105D2B650E295ABB3EC29F1B421063148638626019525C844974F12A9ADD84C72E324EA3698BDE2B33DE8770AA65674F43B861E28E53E54DF35040A4A91AC6CC4867635CCB91680D943A4782AF82D17C2FC8A3F5EB2AF0A1525A29AF94D2CF7C8631F95862FCE1A401E175DE0C3C184072444C10CD22CA9CEA98BCD401164C349B35C8B36424F294B11EC7C7D0A3953FEC20DBB283EF99A3452496D9B86513E33633765C10B45C6612BFCF590F6036A711EB3DEAD00067649EEDD14491716CAED40A3DB26D7B00C6E8396858C3916397166D24370B033EE54C3D3B85B5382B1F3F1220325AA2F804BBA473CC70B15D443548491416BC1698A5A9C39DEA2BA59171F35569ED6946621C1B3647598BECBCBBC72A0781C77BAA5BA128B1B7053B2DE9C122B8790125C50E003A119964AA48392A96B01D7675AF541B46B4369B10C38A2C68EE5425C5F6293C2255A19A7CC2607774D342AF773A22C3943A9B411BD69A92E1C756993A1A392698A93D5F4772C374B549C15A0BD636BE908641A7B8ED758E3C341292598B82A7976F45AE4FB0BC2AF0352D92751A6A5E5015444D3B82CEF064D32C3BEF9B2292571092360E1806B5E5A892586029AB421ED247AFFF408F7FBC9B5CAB930A6896B1250AB1C58AC4231FD6D0BD9B990B649028E4C28E435093B36462E28940FD2723E7BC20E59914E1C812BB3AA912318F15472A64B75C12BA361B2843751611183870A6028496195CD5D219698A89DBCB2C1C06AB2BD5937C1CB5A2DA7774BC3FACFAA028829F3C3C9BD6C584EEC882CCF3AE1B00B1357692ED377F09712A30FBC73F17C0BC462A88E64DE262C24E7A7F7C784DBC5B615AD57E58484DB23363433A4680126C2EB5B9152C162E3277C0BC4DA9693B22DAAC51A1C6107242B7428AC3F21F2C3968810435F9AABF3C65B7DB7B37361218B49B9C76695B53C9A227963CCC1B60D447B3B7D15765BAB6B3B73585F26C2F0862C927B6F23624F360A4F6C537B09563ADF7A9616A4DBA03732C707FED845C35C660B5317EF652055843CBC28AC501DCB493EB5D6BD5C322EA2F2A8B61418B9788482F51B8135F4C1F1173895057AD3218387D527133890FA3A9425D73CE03E1879B85A5B120285B823501487D5C555ED2B7BFAC82762B9262D3D4B3B64736497899A768903750BFF4A82E6A0097F3C230DBA5BCB0AC95006852BF60480D039D1FCA9FB758B5562A384160ACD9C489A3B4BDBCD96989C57EB7A411EA3540ADA882AA567FBB340B518477839925577C780953BAFD0CBE2803626B89CF1C3B3056C4BD78C88818211FC836765FE813C7B18E5DC9725978CCD9EA8C7E1710DDEB883AD93E2CC987024B817C30908AB1BA7A658399DC931A4BA4FCA5A10398289E9718E906336B148C328C2930B843CD4CA0D4735B633618E8C1C327B29596C24BAB053867747883231F11005ED6987679544B51C45D42CC209B7061A91A0C82A92C943C85C149B79C1A190716C03F156D3C22AD27E7B8B87962C8C5421D3B01C7EB2220452B22D813D2180E7A38BE15B6976AEC7659D25B60D3C780FA75C3654D7F9B6DE0D33C8C28C97B6B95BC8C2CB517B497F73A98C41A64F312FFF48FCDA7B07E86A8136C05720A8740D866BC024CA1E22D43F6470C8A38A7301B3CE74585E6AB8B899B13EA39C163AE79E764E0B846FCD57029A73708091F053212C6F93F1173A854B26D7E49BFAE38046E43193B98460D171FB48283E736C7A1651DEEE6272387CF65AC876FEB4292BBBC9200981299C9BFF13690D6C2017BBD3E257700A111FEFA33072CCC8E952263E4867590C79B558187E3441A930964AA3EC0441E91E7AD198CB6E8959A35051DDD972A43A020D0F968EAA8696B9686DAB01B9F9B8095522A7B411D486444B16AC4FEE7B245F50BA1A26D81457B802BBA966AC8EB300CD92773CA26908A91A2E23B21B0116DFCAAA5F4A57514DC2AD736CC788904C29050389B80CAFB0D71B131B567551F6A2E16390C55234E5AD50080EA6268047618B333A49795B4233BD07530A89C275BDABC4EC99D84A812D9E20E2C27072196138386BA42CC4998314905E070ECAB69F2D12AA204A32AD28658DA3FAB69223521B81461312CF88700A49077914AF3C28A2F544D608209E24CCCFEB46AE13BB90E8B86A4BC85D5F41A9ADA7A957CA8763ACAD6713623EC20E2F199B1270966432BF2B8CACEC65776D8A63A471CB4A7C891A01BC92C8C28719C3FF9A8A7A350D9454729D2CE932982E94BBF30B298B3353CA6C459EE5017FCB724FF430A9348B9FB46ABC86374B245668AC71096501A7F3313823C5749E01D0E40444111BEBC0A6858891224B08CFC8E74C41084FD5C03C102480537C11D5E63A349785E242CC58BF790539D3ADF4844176AFB3ADE1DB843A9E6AE9F11BFE66D2D15C33524F478F9A6BB3AF2A83357197C834D399A8625F761529BE9", + "ek" : "2965356F20539D2E7688EADCD7E1F953AA799C17F2F4FE9FD44A71BF304466035060020D6E8D3134B5625E5157DBE1319F2EA3B32391280D3A0DA18AE740142E803D562DE78225AB94226CA446AA43F6477E71C23490E05FB1E2029D77B5A75C7E69141EBA161217ABF9AA7F5A063DFC399EDED563F68E9C3894B9D4457AD38B2E4271CBADC4B0B90F30CE4E1256CA884257343BF66E84F6E65778214C1C62E8E191A10DCB5799F03AEC65E4DB08E22C06FFEEF6B9915153900E1F7CC943A424A6695FC4BB50F425C46D14F32D50FAAB5779E23E774586B0B1CF0AB0855134B06ED228B0FB928CA038F7565D0366F3639C5C73461D9B9461EFE3DFCA5FB2E71CF2D2124B2140004B4188FCB3885F55783EA84876117E1D8628E1D1BB2EE9C193B482E476B7FE35F6459FEEB53103E7F63B24697B557BCB980683DE0AFB5B0C817622A2E64AAE0BE9A2D13477C33E3DBEF768ABA0336C32722DBCE060186F2B27EEF23D664F36703889E9CF0FF125D59F7A21BF0E7A41DF8369A76AD2405C1CF2059EE5496F297F175F067B986E543E8CE0454FFF7627BB49AC444C2DA91A13517D5EA177933A7DB135171DEC1067FCB4276DDF89E25B13257490548726A07DB01D9B19EC55012041A4AE492E73745ABB0D699DF9A695BA7A132CB6A275B71408FFDC70EF586497E4EDEFF771F67926D613D6FC75B55544F26A8EFAB2B7690DD6B117B9EBD15157E3D95F9F731D14B4421EDDB10C9F8611B1CB29D08DD51259AE628EEC8F2DCD922F2171E46136E80B543A2035DDA0193830740A0630C6A8E5108BB68BDFB33F893F93335F1E8A7C7C9975D92BAFDD1DCCF51618CA6250C34B9459CD0E3ECD2BE41EBAA7EB0FC4F293894D1A643AA88AAB2AD0D63EEDA24CB238DE3F6044E70AA1DA2ADF7D5EC45301E55D321F5F1BCC08A9078A08718F415A58DB176E46DBEBDB5AA758D66D11105B1275F81107623353423274081800790DBD7B5DFB07638631FCF2CD217B08484210940B351921B36C4E88645E36528ABC87FEB495BCF169A8A2DD9D5E2F2794BBCAD463638E33891DBA72622E366ED8F631FC05F449B35776B8E1E90B67B086A4839C5CE06AE0FCBC117A89F04B7C0849E86994EFBA2937AC10176DF37F2399C3ACD57FA7B6E05DD4A792BB6EFBD840D823A41B60550DF402339E646528DD31245DF5026649C05BB0673CA76489753CF01B571E44129E9F223C643358CC97659BFBE6BD063A736AC437124E106B11C7DEC7FCD7BC5BC2C25A883BB34C523DAB911730654D0497E33AC02866B4173A1112721420BDE66DD7E7D3ACC4FFBECE77E0004D7F9B3C75427B43EB82FA514ED55F00C8A1B6D37525FE4CE6950FA4AA42A2D1E4734286439F177546A795E9E994C2C313ED24A78FC42A1187ADFA932AAC0BEED9489F04BC2898DB756A2EED9ED70232FB80DBE7CC15071D639530433C5EB6DE32F5DD96343B16C969C45BCAF63488F02DFD07F663409141B7C60CB7A803383BA029550574CAD2211297D575A8BE6C73582D8847297D511879765D35C7DF196ACA92E6F82FCF08B0DA36449D9A59DF45B91119CF0785F2DA35EE56A54A730BC49954B87B0FB5FA8F3F12C4DF5F60EFA2859A960701097925B07C67F34185FBB5ED9531B023AE4434B8BF299F8FEC0D90B503C77E744ACCD010BD84DA14A035665F98EB67BB61AF9FC1F49828B9B1622A4019F9CD24BBEB4C6C0179D3277DBC1E10E2AC0196CEBF6307D7C894858E93EF1FEEB239CD8E632F60FFDC95941BD360885A7A3AADE66E574D0DC0913F207A33742414035FF291192F629D4DCCFBA2C7DF05B6ED53521503CACD5F4C73B97CE4348DEDF5B98E9B302AA47F2C5CDD483E999F3DCFA835427194E628B3C520E934C63267066317C5782992589D0291A780F6992059560B67DCB6995509EBBB47BD909717F194DEEC9B9108F7E80F74C1200E903E321BC5AC9A6D238E99B10E9ED3ECA16A5C8C9C4041924E815BBC5A4C350C406FD224EEB0364D5347FA2B83A6ABF9F72CDFCFF750FB2D48872CD6008ECDB6D35B38CDC8117C108571A79984B3AA2315FEED7E720FF50612F84F2624778390F95E5785CF9CF88B7EE258629540037B5BA4EC4CDDBF0DFB037767DEE60E9660CCFFF18335364A4CD2F25B5DE429B516E2962FC497CFE942661850DBCF92F3ADA7AB5174C60EAA88C6B45911F08D8F", + "k" : "8071A662F45658A641A1A1682F0CC7798E4145F64CF9E19E6B1A452628877AF8", +}, +{ + "rngSeed" : "81401DB81138D6874E91B7C11D59596E4ACE543F5A3471B6FB00999221765FEC3CA057ABE20F03B2D59003375FD71FE8", + "pk" : "17A1C1CA6B5B6BDABFEBAC339A5C121792056C508FF99588D292CBCC1760F1ECCBF105281116A623C600E87B4231C2A94689133CA16B6D99796700B917262F4D776D10709A26123A5AF9AF5AC7455882CAA4D220437271AA5C9E30877A3CB263F9048A483A826774C806941939C44274287B629B2BCBA56F19E7AAB2B8C6A3F72BBDF5820C774C48A151C381A5A75C27337C60C406CC1AE36A3EEB25D91521918A780D75A69F94AA4005771A5C22ED4466811834FBB238E6351FB055A70C32994442297F273752DB6F03F445804C0CDB380F838C484C50250BB2C849E308D8F608ED942442E85BAE7CADF4C6C3A49CC1CC107FF32154E61A99DF1244F8F956C678AC4192ABA83B5485F284F1510B816C26D16922412738DB9796CF6023E558741C7CA293EB35FDD71F9175B838377FFF3050D447A35E208027881406446061686621FAB300755A15921BE9D24B721A50976884C76BA928405EA9E6B7B357BAA68674BF412F66F54A454C03FC2A64B1C1142BC56CC535911EFA578C5A097D8301836CC641E078BDF1245E5359A0D7CE3A87012D199880A3AB5D61753488782B9734C26947B6C925E4FA6CA38475905A9F45A88221DB62B762B4C884344CFC7D81E55FA34293DBF49E4E8BCE0BB95408B32BEC404A245C153042A3EBCBBD8598A3F9537E1403319A5CC6A006A37DB5A3FC4960DDC5381A1B0B85657D41D085309B47C9E21A0641700A14150A0B3E00823E76C6BAD867C6F3E6568EB840B9A9C4F4F45D35E733AE56377B9C2E008B66F9436B59320F3107AA43DC123BC2A89637637DD3A26AB0ABF355C0FEF642632523611A196E2402AC16C38562A0F8C65B6A0485DEE1492CE2494B7230422ABB2D705333D4C3F4E10B28D3C4B3266949CA4B95062E3D600CAACC77655236181208C0DC4487063CCC528961661DC0E474BDD88FACEB2EC448C1EA8A6F14206A33195E30FA4EFD463B7F438ECF4ACE66090BC268B532B251D783BB380380E12A79AC044BD72C0D9478018D98B6E4E36F234142347B919601521365665ED05111F39698C43F5B62C047F1BA861A91A1E29F6BF1B8BA376280DB89FEDA41195A9564D17C73F4305D73CC6A606530179029E192352A5AA9E58F4DF6C0C9D8846DA4518192BC360544F734340C9B072CF399806906784073F622AC18C766DE49A65DF56B6FF99A6E896245C7AA5585723D1C6981A0AD2FC09115B8B8321941961959A8E40B37C24A66125810223DCFBAA093510BF0B9C631E65021D64BAE6BBE847C7576826506F73493D19DA8D47F07898D179697AEC0A1DF3CAD227CBC83C33C6B72B450731D943041F79136D34C7F039558468C3DE1E3021E509A2D898EC1245FA9A966BA457E5894691899521362B7F2D607578B01F230365A84C7AE1BA12BA53C1E216933A34E53E75E252C52087C615FD5AD705743494B10042B033468AF0016274DF94F2E65048E9A4595A4B541B082BCD96E6D90A44AF778077007C069AC9673CB4A559820A2A9992C4500DA89F5ACC48A6BC9AC1922BE9C211F36C468986D0704121193AD5E2732D693C650D867234C9C261525325157FDF94D89EB2DA1949A627338C0D07B1CB9CB45D95B64B38A22B029BCB87C928C7C97984D760BB11B9666271AA914D3CBEFD723D40928EDE94AF17516EF7A72C1FA978584111F8B0903C544DD7C81D94A3B8502CC08B21CD89C8FAFB94D9EB57F9061A51E9AA6F3860CA3DA018DEC14D46981062B8FFD542747E7C83CF815989117AC14BA1654BE4A92B396B01FAB274A082609ED9C685F125FDC4611CC8C00167A8BE5F28F0867397DA186AE68A29701B4C1885235FAA006D45D30B990D13C479FA5B1B76CA2406A46A0C42F9C63CCCDD187F5E93B16F20BB86B5251B00842D28E58C86DBCA41AD708A62C28846D0C983DD60DC4F5B018017FB1276EAF839A2898A8CAEC69F11037498C5A621C05CDC5BFC9AC9DDE250A7C4C1531B813B3F84E70A43BAA43950A9CACF07C9DC6C8B8C4A660AEE6CA67159A00010A3414C87FD94AD197856D9940DDB47AD0D8700F635E58408A5AF8213FE4636FCC594EE677B3F205E3552202CA8087922402D24AC4F42FDF5C99BA1356F14CBFF297192A40B48ABB531912B8F853A07BD241B19AA1EFFA784E5746905449B1E7436A79A28E3F712507E5BC0D026037001723D3443145BD066CEBAAA3D000C9F0CA", + "sk" : "04A39F7840AD6E0C41084136F21609602A0A00CD8E0FE0158C1C3C27845AE6219ABCFC95E72814A9776655841E46491A9EE342591133569123D6A09A54A8A253A49AF9B27103D196873622EA93BD17DA439E88226A333DA9C525B856C7ED53593A002007235D84225FCA027493168F9748C4384004D873ABE1BBA69212C7FC4CA89EC745FFAC84B99C8707860EF798BC1E7C4F2F0344542054F3C46DC72A6F9D2B9303E6CF114040E136087B66AF5FB47EC6A55C11C02ACCA23F306A7221F3C81470714A472EA822BD387CB29DE9CE4BC96655D63E1811C93A740E148C994E149554B24EDFCC6B4878C55570971D95576ACB6943C6532CB2101B4468CF578A99348634836174792758C350651224A2D22647446F67A056180AB2AFA34BA27A76933C9F4F3447C0AC6B605B144A2C9F2C626E8F434B4F35CCF894327C53A7DAB9009D5A9A4E7BBF0E6A22D4F120B0C42AE4A7C0AB08774CF8A33E069D4860655CD4BFF1940A22314356E8525213C351688B1A725A673918078031EC37080956973266811DD8CA275C9A75FCBB7B9891C26A3E343B36BE5273EC946F42F70865BC48D6238AD42B616C11B708D3551D3B9DC61B653E06B1E6709BC115256687AF92941B2FDCB99948184B025239C89052765B3D63B476C3A4DF499564EC0749A03496040029DA776D686DCF9984AC9354C2C69F2C3C8D3D5774201B7AC0254A891871847ACCA5099F89733FBE2A4979DCBC26F5C38EFC5129E083F508441DC6C7EAE73B1E7958671767968B180A3B34343CCA94289FE0A8788B1CC8394C5710B9BA6FAC1CF3147DB32C9060A9CF2D056734031190B53AE17917E40907B61826527C277344C8BC475451414E00E3CFA6C15400CD5A6875C7B2820702706566A00460ACBE58128E4C869095160FD0DC303FF8CA68A8947E3110C626C707DA0344717297147AEE5C39838C0F73EA57F70308601BA55E977BBD7B681E0C4C1CAB818AA156EAB24F74C2B66FFC8959C3617F92941F1C0935D89702C71F4D76C44402AB92310904504AB5F9A002C321B411BEAD73A819E02D006D8AC368BB89231AF85A97BB6B0E23AC2CA869306E9239D808CB24312C48C4624C33537A8092F6E8C147900894F3838DB9B0FC9419DFFB6E78127E922042FE4A3C20E5C48E478BDA52A2BB0A85612024FF5C92801AB1EDA82DE8AA6442249ADE4B6BB9886015035D436A855CB495F6885F6D3084F498AFFDB17272E127BFC3BACD3831D06C20569B92FA9B90278707C995B2DB1B63A423A997E37A244C763394B9B28B3D3538C981DA0BE1556696A7330FA83882C1B7DA6668F1FA5841EA5A984B4F6F4869356682B9652A842859BF079238A83EE3D6B01610270488247C6B5E63CB1E4336773231B6DC6BBE6888345A0AB5CD27091442786F2313C16BAB398356F1899554C69C4FC09C9A720FDD8BB1DE03C80E5241D25559FD7568B321CBFFEC8F619403662A61C696AD90346BAC979A7E446E41D5582ACBB5E0F70AECC4330A550854E60EEB5290198825A1F01915BB094F10BC0BC29572430BF8CB8938A4C182698557CA49BA9B7494419640792C3FB31CCE70AA2ED24830B65EFB3218052C539F2539DCA01532513717C7BC552179957671275327FF44A79A49B92F343A533BAEE4E06CAFF23D7857CA540A78F886BE136B3506BB080EF563E8A3987C083B4B5CBEF410AB20213AF7807D3C52C58C852DD48C4060587CCF259F00F40816EA86EDD276D1135EEC70B990E5C11E97C470D97CE45A3A105A9DA1CA768166C86C41474BE92535F1BCF7539D09598E773AADF39A5B66EC79B360699E953BB0BABDE4F0C707B99CE6F5075217A054407072B084B7546BFA95CCEDF1666746BFE74C674FDBC80EDC35B4769F5FE08632ABA9B5398E79DC45AD014A8AB539C157B672EB74757C6632E6C922202590A27DD1C82527A36287E2AB7A327A264ABD300634226149513980B9DBCA957C1560A6C32A20328B6926C843B53C635719F635EDD90F3C5313EE1766563A7A9AB6B011462558B229FB913179A438F3B5B2F427ADFBEB90F73A2CEB190CC6DC713B83AFBD12A54B0C170CF973367B11DB2CB3E5D880C169041732A276B93056E4632DEB8606C276A0897116A0829482BBEEC870F18C247309759971C4E1702117A1C1CA6B5B6BDABFEBAC339A5C121792056C508FF99588D292CBCC1760F1ECCBF105281116A623C600E87B4231C2A94689133CA16B6D99796700B917262F4D776D10709A26123A5AF9AF5AC7455882CAA4D220437271AA5C9E30877A3CB263F9048A483A826774C806941939C44274287B629B2BCBA56F19E7AAB2B8C6A3F72BBDF5820C774C48A151C381A5A75C27337C60C406CC1AE36A3EEB25D91521918A780D75A69F94AA4005771A5C22ED4466811834FBB238E6351FB055A70C32994442297F273752DB6F03F445804C0CDB380F838C484C50250BB2C849E308D8F608ED942442E85BAE7CADF4C6C3A49CC1CC107FF32154E61A99DF1244F8F956C678AC4192ABA83B5485F284F1510B816C26D16922412738DB9796CF6023E558741C7CA293EB35FDD71F9175B838377FFF3050D447A35E208027881406446061686621FAB300755A15921BE9D24B721A50976884C76BA928405EA9E6B7B357BAA68674BF412F66F54A454C03FC2A64B1C1142BC56CC535911EFA578C5A097D8301836CC641E078BDF1245E5359A0D7CE3A87012D199880A3AB5D61753488782B9734C26947B6C925E4FA6CA38475905A9F45A88221DB62B762B4C884344CFC7D81E55FA34293DBF49E4E8BCE0BB95408B32BEC404A245C153042A3EBCBBD8598A3F9537E1403319A5CC6A006A37DB5A3FC4960DDC5381A1B0B85657D41D085309B47C9E21A0641700A14150A0B3E00823E76C6BAD867C6F3E6568EB840B9A9C4F4F45D35E733AE56377B9C2E008B66F9436B59320F3107AA43DC123BC2A89637637DD3A26AB0ABF355C0FEF642632523611A196E2402AC16C38562A0F8C65B6A0485DEE1492CE2494B7230422ABB2D705333D4C3F4E10B28D3C4B3266949CA4B95062E3D600CAACC77655236181208C0DC4487063CCC528961661DC0E474BDD88FACEB2EC448C1EA8A6F14206A33195E30FA4EFD463B7F438ECF4ACE66090BC268B532B251D783BB380380E12A79AC044BD72C0D9478018D98B6E4E36F234142347B919601521365665ED05111F39698C43F5B62C047F1BA861A91A1E29F6BF1B8BA376280DB89FEDA41195A9564D17C73F4305D73CC6A606530179029E192352A5AA9E58F4DF6C0C9D8846DA4518192BC360544F734340C9B072CF399806906784073F622AC18C766DE49A65DF56B6FF99A6E896245C7AA5585723D1C6981A0AD2FC09115B8B8321941961959A8E40B37C24A66125810223DCFBAA093510BF0B9C631E65021D64BAE6BBE847C7576826506F73493D19DA8D47F07898D179697AEC0A1DF3CAD227CBC83C33C6B72B450731D943041F79136D34C7F039558468C3DE1E3021E509A2D898EC1245FA9A966BA457E5894691899521362B7F2D607578B01F230365A84C7AE1BA12BA53C1E216933A34E53E75E252C52087C615FD5AD705743494B10042B033468AF0016274DF94F2E65048E9A4595A4B541B082BCD96E6D90A44AF778077007C069AC9673CB4A559820A2A9992C4500DA89F5ACC48A6BC9AC1922BE9C211F36C468986D0704121193AD5E2732D693C650D867234C9C261525325157FDF94D89EB2DA1949A627338C0D07B1CB9CB45D95B64B38A22B029BCB87C928C7C97984D760BB11B9666271AA914D3CBEFD723D40928EDE94AF17516EF7A72C1FA978584111F8B0903C544DD7C81D94A3B8502CC08B21CD89C8FAFB94D9EB57F9061A51E9AA6F3860CA3DA018DEC14D46981062B8FFD542747E7C83CF815989117AC14BA1654BE4A92B396B01FAB274A082609ED9C685F125FDC4611CC8C00167A8BE5F28F0867397DA186AE68A29701B4C1885235FAA006D45D30B990D13C479FA5B1B76CA2406A46A0C42F9C63CCCDD187F5E93B16F20BB86B5251B00842D28E58C86DBCA41AD708A62C28846D0C983DD60DC4F5B018017FB1276EAF839A2898A8CAEC69F11037498C5A621C05CDC5BFC9AC9DDE250A7C4C1531B813B3F84E70A43BAA43950A9CACF07C9DC6C8B8C4A660AEE6CA67159A00010A3414C87FD94AD197856D9940DDB47AD0D8700F635E58408A5AF8213FE4636FCC594EE677B3F205E3552202CA8087922402D24AC4F42FDF5C99BA1356F14CBFF297192A40B48ABB531912B8F853A07BD241B19AA1EFFA784E5746905449B1E7436A79A28E3F712507E5BC0D026037001723D3443145BD066CEBAAA3D000C9F0CA5955B9C5A4F2CA172535D5A32EF67D54F334BF726829082485A7B83D43B46B2310EFE801AE61866A7109F40ED932E67B0AE9E966D1EC5F917E4A9F31A27EE13D", + "ek" : "038CA10F4F27F069D1F0E87F445D5C5551FF84D793E7B0093A2AF18890DA01293B3B1B5DA6CE8E2B5780465338D90E24E3CB7BE037931E7EC7C1DB6FCD1FF257905E965C31604438545963F53B2DD8130EC636F9C857B467F4A0AEDD1D16DFE22DEE3A1E6EE9A91160809C4B5E471991BF65FEDB1102A09321F07C5AA20E146FD0266CE9292560258BA55F5561634D23BD9E816AB277FA800D37B256187090C8C38C785DD90B05315FCE6D61694CF17BA926C39FD4772DDC9732F22E47681ECCF1763B2047F508C0E7E035387EEA263982C876A3DE317793B150B6506C3EF881F91DFBB484173D8E05602D7F9F4BEDBAE026E30924149C08E62C37083E1AD293C12F8DA2818C5C8B3B5293683814476672D7B8F20A35A6114E6453C4E0E39322AE15B01A4A1DC7018F16DECAC6E80603B324E5C84F96763C939BA00FA26E33563FCD366535597186F5BDC259B3D869C00944F869AF5960758A082F57DDB40DCD08FBA4A177165BA4398E2E0CBE6F8940EA30464214D0717A72C6010856AA602FBE3739ABD76D41EFFF908AD10480AFCEEE2D576B4F4AC569E8C0B6112515C26A5B0D6B33A8AAEA05B9898CB553FC8EFF6D3FC1314604EDE289B50F6166DB998330C46AAD85680C74451FEC7515162D93A39D53F57916065251B5EDF1CB3AE1DB4AB040168EAB0550B400433D4EAA591806F17500DC223E74CE00FA1032EEDFDE3B91582B043E5EB6C747E1563715642C2CB87718D646A222D94E0418E066C6731F0B8B477EA55EA568C3932EC70D71D207A4F90F2E213CE37C772DB150514D3E602FE231272CAC0C44EC9D19226591775D67522793F0764DF230FE62A1AA0271A06B345492C4C1E401DE7B929920E519A04E48FCC7C617BEEE07A07DD5B9052BD79CAF348E4042BDEB91EC9D0CA7470B15F0FC61E19EE006A9D351F14D4D8FFD3C8B5802C7B095BA80C78D02F9BC51584E3BAD9D556A9A7BE7D90BC1E595B53A62379275DB2761F01DEE231BC9660F01FC219AF0BB1B5AA3B67DCA64AFFD3E3EBA22EC930EB2ADF35DDE68A388F79522AA07AEC88D72B8053B04733B62E582D4E829C3940C8801F085FDC9B6C163452052DEAACD5F26A1A62B6C15FB290C5D0325E527CD4BC64C05531A077CC70ED053E0476C987C1F10D5847264FA2A53A92522204D764A94CC93386A34302712BCD3D9269B6607DE91F7DA7836BB0B5E6BA5D999E36B85C4658F9FB203D7279C3F9AC6784D77F92C95805F8429929FD7A17D2B94F0E281B34608E5EE800A300F0049736D86F25478B56C16292516BB7D3407081D81FF23CE18808B01A0660A9B1186E399ED995D079A495CD7AE1CE5B5593280C1743DB4BD054A6406ACB7F10F1E43ABCD9E6E2C48B1F679E944700832CEC2E0281809DD27D04453FABB5527AFFB16388B3B0947F35220158EBE69FD5DC3B18D6863AEC5637DEE0DD9B0F4133EC32B37BEADD41919CDF62FFDE823E5A59F3156078CCED24E90C0ED7FD728FB2D63666154E71704E9692E4FD5729E52715C19DE4A9AEE25908D3A0C75EA70E0932950CB90D4A40D9203FF4879F9357FF7FDD6D8107E522C53411501BD75561F363D8A0F8F699D4006F566ECC97E936C589CD592765003EAA652996E6F3B46BF1DA1B723CD381259C1BB9BBE1D96C467A43FB6306CC92B861CCA483A07BF8B8DB0C1C6666A06D2B2AC54656D6116DD2AA91D54512479133FB397C6D1D358297C1EE198CBF889D312B70D7FCEE4E2F4DF2F718B0A1A7F64D5254D5101945C9E894A4DB96B57F75D24EF00E7F08FB97E538D13C1E2B3E3F60F64A7BF73DDC34CAA187E065E08CB74414B024B2615C1A88479C51CA5E5095EC7A94B060F5EE4414A07B678AC535DA8DBDDD19298AD6A2D707A8AC876F1D43ACB5D5762A87DF351D73E99753F897FB007130F855E675DD30F9436EBB3256B21FC9D76062E1992C13EAF1F45B13D4F5319549FFD148420AD0D97523C75AFFB76BC86D2E403D5C79B8CB00A73E8A4710FCD305463D7F9B3FE187D1EF561A1B1F473FE4DD281D503189577044082397DAED54E95550CA629D91426FF3D2B3B77CF056210EF736C055C1310FB38A27ABF9EC2361D8289BEB539F26D227F075A17ED2EE49A3316894D8E6D619FA4C9B84819381CF1C92423C0DE5D6B93475E7238734270CE9B9E21461DEF0510FD25A5C04F1413567961567CC004F074D1", + "k" : "4A6959602EE856DDB8365AFFA4E51BFD09CB1A40FB0C2EEA8FC64D232EC841B3", +}, +{ + "rngSeed" : "30B5DE5B73681EC08AAA03F6F2D2169525D25F4042A5E3695A20A52CA54927B85F8BB948FC21DF7DEFC3910B28674994", + "pk" : "9EA32A494182483627849169E2006E9306448025229ED2C14FF825A43976935A8A14B8448D6C4DB642A1726823A2053F4F75951B80B47056BDAE61AB68402D4AEA6EAD635F2262082D71C4FF5C78E6A6345A72505E23064DD773118AC985E49E4D88C64DD894322B0D2A712F0CCCBB506436C3F0BED765AD0B193EA520580BE4C12CD65F2406CBE1FC9281D37BED1988D7488F3925244454B82982C49FB522A2F83A7D131D1CC65CFC7179F8A043DA781959A815B5E45F6E0B37269C84237424FCABBF4DC16A722CB171984E48864EF70C0FE14C69EE385F15EB7191249BBE3A3888C50FCDE9302AC5AAC6105503589B3748938EAB5614D626C6A301599B623ADA44F432BB18E359C7B223414A34945786468628C6579F9B004185CB7590E22F94E83DE26C6A9B69702F704041DA3FFBC8CE5FC2367A3A97C4B997BB06A01B8964A8534E2F713C289A0DC8C072DFE4A42F305785A99C0DC898D3104E0DCC62C0E600253C218F0511FCD94BF78497B03A08EFEA8BF7FC0E45D3545DF2C6D708435414BC00E64C76A523BC0AC823FB56DA247DA4643FD9063748B23128C6CE4316BDCAD4BAFBCA77B8EA6C10E54AD063A1433333252311F68C676EBAC53ACA8FD70B9404C1CF3C979CA0C492198A2F92294EE5AB4A2ED15100F20E5EB948916CA7BAC7B28FDC904AB1911AFC19A454AF45E6A265A726340291BAC80CEE679E009C02254A6C6130227464B2FBF2A95661BED8B348AE9C759FA53A4B429C0B536FD6BC85D5C96233F90CA3057839A47B068855283487C90A8088E271A3E33F5AE5695D044C4D14AE8440BF03B318549600E39CB9D9D58EA2D2A5E3D08A11484801B8167D4C5AFC20C56BF970A230231DA8372EAB0F5266686B4A3DA0CCC6B57CC81AA29053142CF0F35CF0C83282893C25983CA06606CF255CC1B41ADD5947FF9322A4C23BEE47CC49656A8581AB5A99A3797798EA77A1DB18C39ACC97E6342B8770550212718856398878900D6CC9A5963A71432E5678A12CE86257B0B32EE751EB181FFF62AD98443F7D79CC4F85BBC67190A68504A24A3166C588AC7B40FED53318B8B452D1A738E59A2C82442FEB013F9B2429B6C603F71619F386118327EAF0C13EA30FD620222AF064C61AA8D9801D53192C61575E3448B265EA9987BCC84CA825943A4D51A9CBB5E76E4FE88CB6D92215F60B0941C46B89A746CC96C74CBA7B097BFCF27533A46FCD928F49D670F85179E6B598EC595CF39C3554EB5F93AB9707D4A559069D24A4005CF28BFEAB0BEAD80363AC608965141E252DE510562CCB5FDF94C30DA1247DDC4C80554D879B62D0B49EB3B21EBAD10A50794545577BE4EAB070D30365DC9C34EAAD1163B251B223E8BA45DCB77DCBAB0A07FA635D8B841179A354304E0D249DDE2319D85CB724245877A549CCD8230FAC8721D82E8A2182E5CB63285CA8A0D049CC7160D7116D5C1C0127A9AE5FC808EEE88E340A57A80964B21A353B08BD35DA0DC1D7020D6CBE43F49547686546391D94B9A2B2D63B23FB2FB8C30F7AC371B3A80AAE0470D93B610BA1681AF1BE2871A49419A23610843BF940804483DEA0AD8D609500D8AA2426CBF0CA5AA353668A7151BB54C7C4E4AE3354C598CBAC6E90949CF6B79A941C541C652351306F810494DC0AE743CEDBA7904D34C2E0B32B603606E33156BC750BBC477313219A97E184D695C701B2009AAB8806709B8D376B9CB6A24F3B6D0A4157398C740D08809328AED069A52FE77CD68B9DAC62CEBE3649CD1B139FA84F6A2333AB702A30414425F50E25E41BFE9A2E277869E17C035652237889C37E3C86CDE41C7585776D14682F3C0309A09C1ED43609B5B82E03508869A7F6B627C3710C58198EBE9100F433AC0DF22D03934C1EAA10AA98B88C879FEE60596A3AB29739B613AB741AD4518E6BA5EDEC190678B20E6544F469791C64629657B9B1C51EFF1616E29A1B3BC25A55CC9C481995BBE68ABBC383DCC02E4C8208CCFB57E052AE86017DFEBCBD2165810151538E7A9AF3A4C5364C02208428D2B98890923B7BB92D66A2907B5376906A61115C979D4B34670A91339008BB466928B30E807CBECB307BECD228657BAE78F5869C3463D1B73E09AA7F6274C7FD2A3A9CDB4160DA310254462EBA30DCDBB5C30542463266D790D0FD79C3C76F5DA348753312E4949FF2955212EDC46DFCF9E6C37A", + "sk" : "93AB695549515D75A2CAF8A97B8974E75407D5E56416D3A3010C304C99AA39D468BDAB9DAB3B87DB1C27A2B831EA3595D371039345C37A892328287CF39255619494927828D95A7139871EB99496755AB3B689969E907CEDB05A97C7976A31683F329FE0237798F9387D5BA11870CF6DD01668EA8D0A74C0AEA46E13697DCC9846B1A8A9F2BC5304378154BC7CF8EC2DF7F070FF06B085239589B1A7FFD13F9653A821767A36A8294FD59793ABBB833B09D6E09E71B9062DD3055CC9A04FA0B8E6D41AE10001C18A398ED85BF31218532271332C73CEA3862867081A8B2C610B1785412BE3F42EA64917D3CA6779AB6581809D5F0412F579019A35C6AB21A4F9142F9D2A4B0C731AB447A002C7029B490AD5C1372EB6483A205FEDDA376FF1B432430E1738B7AB9531BCD48B4DA54F4D3A96A00C718FC809303C50D1042B7E49457C9512E4F66E6B75415FA1BB6B23A1EDEC751C60AA619473B9C489D6C5C4935380DCB67FF7F59D03A33881B60818A12639386DB06C6EE6313F98BB8C1163B2C8526744B560F1D7C672250258288A78761C99A8AEE292A6B0B48B80D2495684891A28BF0C226DE929B8229289F3E290D21A450901659C404E0B9C25A55C7DC39BBE070203C85CB3E9708071F6CB9E9045CF460939F29C321583F8695AB709AE11721924282AFBF225CC54AD87C13C56733A21294BECA82D8472363A2308A41163C2D60B7C3B42FE1B74C93A6A5146418E58697D3344006AA576D6300728440FFA0A6166514539BCC908CD1B3BA889D9AE234316A8D7709A7156635412F0EB33451942DCDB77AA9B4E29D1AE41B586CA960660E08672ACCAFD847FF9289035E10E05F0C35D5B1A9278615105533C98CA6B1B930F207C5AC3380F2933E834B4E45983A92A1AF994BC51EA5EC3E38389D2559275CA3BCC4D7C50585CEA9FD145BF284262D458BADD032F294050E01422FBE34C0501815008205EC4A8D43006674788A8D3A64C57470C953ECFE789FB3224EFD84D4A40C921852056A8CDF43976648429729386E663397F475900655BE634AAB9344610FC6322A28D859B5214395172468A15570A171096C5401175FBCB0DB8CCCCC16E5E6B82F7732C2C47AE7D15738D650189B3702D859EE43BB0A0650FA0CC823761BEE4A40877727EED58815A64C38A94B7DE743688156A18368F7FA9A83064CDB972B762A97BA0BC61BD45650478661819BA109947A9327D1E54B1BEE845E6E54EFBB51C9F2CB38AE825286C4A1A872D4A0629AD00574D60569D6106063AC54380BA3CDA463D41736535B631A3245F6360860B4D75FA153743203EA0846CE423BAB1095BA148A18C2FF75222BFB295EE904CC83BCC89D44A82558753E096DA4964346470C920499FAA392A3C7258C5B17A770B50906C6518239D81301DE60BD5522E1168A16801683EA09AB8D083C0250EB1413123164F95A36A5C053E706327C49BA727F00A6000C35DB64C01F92F4A746CFC76C9D0B7810E559F9B12B0370075E42153C7F66BD5B79C94F4C80CB0226BE6924F1A29A707007D998AD9A1AA5EB7176879B2FF476918732D1A810D456168EF86467F1AAE56A673E40921D48440914568C3C98E33F5835952517D6CCFC0206C2CBBB79A43A428A4858BC5200B5735D7809DE666CE5E124169B7ACC44A3E6B1838D497873AA48B66893FCE45C252813AD2E3B68C1C27EA4237841108218B8D7BBB8733BA43C6F6B2C7818B74FBB41E238BA1F5C1C5DB2EF8BB80F2456F228592E952CADDF6BCAC9C362A031BDB4B7F422573CB772115F385B830CA6FA368AC3920E43B5AB283989B3C719E295867539047D4420F71A2EC046F031A43FF738CE87B67EC19C4F284CB1C1CB07938348F17332BEA4DFB4C4417D7A30275460E498784F50D6AF7920A78A69E070D2786036E3145E1D7A503F188E81B42A8FA8658E30A8701341BC9B7278601951B2CAAB4997DBCC7C8C15C00611CEBD801B2B3B3155433240C6A8481A9EAF0B34F6750BF6C974962210F69A4022471A4C72FCAAC2DFFC4C603B6B4FD6B4D7806C0C275585EEA28B8F010A1D48506B1516872B70C43B6576544B9A19644FC1D00A7BF9A59A51AFA318818819DD8B1498BC1FC913B55C573B39633343C2691F6A8AF8B65AD05559E1721DDAA391415979EA32A494182483627849169E2006E9306448025229ED2C14FF825A43976935A8A14B8448D6C4DB642A1726823A2053F4F75951B80B47056BDAE61AB68402D4AEA6EAD635F2262082D71C4FF5C78E6A6345A72505E23064DD773118AC985E49E4D88C64DD894322B0D2A712F0CCCBB506436C3F0BED765AD0B193EA520580BE4C12CD65F2406CBE1FC9281D37BED1988D7488F3925244454B82982C49FB522A2F83A7D131D1CC65CFC7179F8A043DA781959A815B5E45F6E0B37269C84237424FCABBF4DC16A722CB171984E48864EF70C0FE14C69EE385F15EB7191249BBE3A3888C50FCDE9302AC5AAC6105503589B3748938EAB5614D626C6A301599B623ADA44F432BB18E359C7B223414A34945786468628C6579F9B004185CB7590E22F94E83DE26C6A9B69702F704041DA3FFBC8CE5FC2367A3A97C4B997BB06A01B8964A8534E2F713C289A0DC8C072DFE4A42F305785A99C0DC898D3104E0DCC62C0E600253C218F0511FCD94BF78497B03A08EFEA8BF7FC0E45D3545DF2C6D708435414BC00E64C76A523BC0AC823FB56DA247DA4643FD9063748B23128C6CE4316BDCAD4BAFBCA77B8EA6C10E54AD063A1433333252311F68C676EBAC53ACA8FD70B9404C1CF3C979CA0C492198A2F92294EE5AB4A2ED15100F20E5EB948916CA7BAC7B28FDC904AB1911AFC19A454AF45E6A265A726340291BAC80CEE679E009C02254A6C6130227464B2FBF2A95661BED8B348AE9C759FA53A4B429C0B536FD6BC85D5C96233F90CA3057839A47B068855283487C90A8088E271A3E33F5AE5695D044C4D14AE8440BF03B318549600E39CB9D9D58EA2D2A5E3D08A11484801B8167D4C5AFC20C56BF970A230231DA8372EAB0F5266686B4A3DA0CCC6B57CC81AA29053142CF0F35CF0C83282893C25983CA06606CF255CC1B41ADD5947FF9322A4C23BEE47CC49656A8581AB5A99A3797798EA77A1DB18C39ACC97E6342B8770550212718856398878900D6CC9A5963A71432E5678A12CE86257B0B32EE751EB181FFF62AD98443F7D79CC4F85BBC67190A68504A24A3166C588AC7B40FED53318B8B452D1A738E59A2C82442FEB013F9B2429B6C603F71619F386118327EAF0C13EA30FD620222AF064C61AA8D9801D53192C61575E3448B265EA9987BCC84CA825943A4D51A9CBB5E76E4FE88CB6D92215F60B0941C46B89A746CC96C74CBA7B097BFCF27533A46FCD928F49D670F85179E6B598EC595CF39C3554EB5F93AB9707D4A559069D24A4005CF28BFEAB0BEAD80363AC608965141E252DE510562CCB5FDF94C30DA1247DDC4C80554D879B62D0B49EB3B21EBAD10A50794545577BE4EAB070D30365DC9C34EAAD1163B251B223E8BA45DCB77DCBAB0A07FA635D8B841179A354304E0D249DDE2319D85CB724245877A549CCD8230FAC8721D82E8A2182E5CB63285CA8A0D049CC7160D7116D5C1C0127A9AE5FC808EEE88E340A57A80964B21A353B08BD35DA0DC1D7020D6CBE43F49547686546391D94B9A2B2D63B23FB2FB8C30F7AC371B3A80AAE0470D93B610BA1681AF1BE2871A49419A23610843BF940804483DEA0AD8D609500D8AA2426CBF0CA5AA353668A7151BB54C7C4E4AE3354C598CBAC6E90949CF6B79A941C541C652351306F810494DC0AE743CEDBA7904D34C2E0B32B603606E33156BC750BBC477313219A97E184D695C701B2009AAB8806709B8D376B9CB6A24F3B6D0A4157398C740D08809328AED069A52FE77CD68B9DAC62CEBE3649CD1B139FA84F6A2333AB702A30414425F50E25E41BFE9A2E277869E17C035652237889C37E3C86CDE41C7585776D14682F3C0309A09C1ED43609B5B82E03508869A7F6B627C3710C58198EBE9100F433AC0DF22D03934C1EAA10AA98B88C879FEE60596A3AB29739B613AB741AD4518E6BA5EDEC190678B20E6544F469791C64629657B9B1C51EFF1616E29A1B3BC25A55CC9C481995BBE68ABBC383DCC02E4C8208CCFB57E052AE86017DFEBCBD2165810151538E7A9AF3A4C5364C02208428D2B98890923B7BB92D66A2907B5376906A61115C979D4B34670A91339008BB466928B30E807CBECB307BECD228657BAE78F5869C3463D1B73E09AA7F6274C7FD2A3A9CDB4160DA310254462EBA30DCDBB5C30542463266D790D0FD79C3C76F5DA348753312E4949FF2955212EDC46DFCF9E6C37A1F40ABF556C865CD096C702D21239DE7C22713D70626F1A3A4C4CFBDF3FACA62921BBFBFCC283E1D1DB36E99B9CC6CCFFFBFDB86DAB7B6C7CA02CDA227DA8632", + "ek" : "562075E0DF7240A1EC6F092D12DC309F1F3119616C4FCE9462A4244F4D70E8EB13899EEA1F8C499259DC4E2F688F5977EA42563DECFE096AC9D558A1C30D20D91D004A53DCD161A899CF7B6D5B95ABE3A6DF944BDC651BBBACA0CA416DDBE970B5E211E1C9B5CE8821DD3FF54A51123034B67DE47EF7869A8AA4094A3C7E4D13783A28D465E1CAE99F51990390C7F0A9BC15D69CA8B77B0CE06E522034821A0EAA01525F696E4670CC084788F9207F8910752BAABCC89EBEB5EA21A9CE1900AD1EE423D2E7647BDD88939121B7CB0CFC4B20A17EFA93ABFE7662D0C6947D64000CEFDC9BD3796536340E95C3DC403B203343C2545C7BAA3E770F69818AA6A872D9AE10E30F0589D198AB6A92AC6176A9223DFADAC71EC089BD05BBFB6553AF7E0E6D2C6F11E26E17CA2A62645D79C2E4184970A2536C0857B01105FB326CDB9DE92916BB4582CEFF9709CD90C650AB2731D5F37631E4B14592AACAE207ECAA83C0A8E18DA15F52DAE8763BEA347D490B6EA35781BF5F7D2BEA990C14EF90F70FC65950C1B6131DD75953B7AD94960D046735DA7C92BC3C3D767764544E1DF2CCB06732CA89A7666CD70D2368A70502CB4BB8551D8631A3EF23961936E404C7BA004FF81DF39DA8109B76FEE039BD7A6575C13F32DB2B859AE63CAAAAFD9B3A2DC48CF26E728C67E806C661BD17B44F0409EBCC319DEB8AEE8FC725251A7F2B49B6D616085CEB645AE2A28E134079351E710751C7669EAE64C097BA1EC8E882BBC62659549DC1048E6B1A3B47306154A85BBA7F614F4A2FA733DC746591892BAE463BF6406C1F4E6FA16C8B2ABC75373EC47BAACAED4916B5B654DA27A66479FDCCB0E8E1B4CCC4191FA1386C5842D526AD457612E04ACE1D0E07CAC00CACEF5E2A98A461AE88D0F95DEDE403D5B961087962665315BD0576BA1AA71698EE706E08913A12F8107BC17F7EDDF08C0F2F84301DF2DF038E5FE27D03BC7E888B8FDCF91C14C5AB51332C8904DDAA67F359AA49A174D44B165C2F3AFCD77E295FA6D47E833B8BB643D018D765D6F1D9504E2C2C49236E0C1CD9BD752A626127DF39C45459358A655311655C5F8561D52E4B6A245139D81C6657308A11D6EB09A300D21A3752F08CCB50B6E7C6E374E8A841F57EECF71E78A9A5D6EBE9C0AD8C86A221728921626AF3B2D357B92CCF6D7486BFA7424EE70E5C52770EED7A8773E1595303F5CEAD46D07AD233821B8A3CE3CA949AC97B1CAACCDE31170893FA42C0B282E0FF34D5C7BF523E27731EA7CB37D49856FC7E48A979B67005C2CA50C382ED5E27DCA859AEDDA8A12E124F8667A07605EA1126DCAC084EC0CDFFA6A3AE0CF917FAC2A99231F39BFDB71E23E25180FAB96FFFDBB4EB200861D5655481AE750A9C2920A3F3468A8B64EC128C5C5FB3DC64E1978DCF9A9AF1C26D9D64095997181384A0CA6BE2DC866F3B085888CBB954257D05784B26943F9A5983781A2BEFDDC2B1B7E16E9AD4CC09BC962BB69406F8481A66E2FA94C2D6E76B488875E437858242CE19BD07DA67EBCB0032B6D3BDBA513F8226AFCB4287D69C7586412A9BF57A5E3D6D512F69720DB3781B6374837A538B8433F621273CF3E91BB7802AE139CCC44B7356D71FB2DA28162991D2104B8B387246843AEC756416CF511DF950C36B31186F759EBAAFEB57D0EB9241ACC268A6ADB2E21D00B9A6C49F66A404D2A8906E658475CEC607F3D0C811CEC0432DBF400F5C46BAB36F72CC8DAE3695D1A24C704BCB2EB5AB39188544EE104A8A13D7AF56F99A309AE099CE3963DBF8621327862B1CF98FFBD539ED68CF22C4AEDA104442848C613A8C9F45620BA1889E968C2FA7611AAE61ECD0DDE244C9976A302F3A189D8105F1C81CB3665C875E7B732DD5D0D8D8945581CB360900703E06964ECE230A507C8D352888545BC96584E6C2B737D634BFDC6BFCFF4D2A70A729DD9F633D6CB94D08AD7287FEDAC363617C4D44249D1795A51F57C6BB530255301340C987FC0FAB85D59F82C8EE598C33CBCDEB0E51BA04FA423D644B6F3604589E61E934D38FC5C1F9CB41A4B1133937A111725269A29C1BECF18DC809B5283571DCCB4FB4BAD7D6A54EF1EE04346E88DE56E5DE9E9E1C91C746C71A2432AA67A9706C58E5DE97A6F9A2595813FD22B84952E364249A9215D5106D6AD150E9FCB7881AC338C0FC8095CC506D518896CC43FE", + "k" : "69DB36B6095A50F46A5C5D12C74A76134DB58A42AC23307B2683E8262666CDBC", +}, +{ + "rngSeed" : "E335DF8FC0D890588C3E305AC92C7160FF199E07C85760A828933750E3FED8C83B0DBE802234481ECF890A32D7A2884F", + "pk" : "A1F055F88CC36236016D4809E5D9096762571C15863924797872CDD77370917720776B8EA9B72189F237E9D710DA6906AE25331B9C82CA0CA257DC980CCAA23EE61CE1E681AE09AECF967C33505F83078BDA132D1AD623373252B72109F6E6B8F5481DBE89B6033558B90A70D3866930A3C78E024B268604C8B3BECA583B8B531A4A6C094591BF173107025BA079C3062A607E30647308987084341925531076BA04E03C8DCBF551B56885C383A5929A54C207B39E162348F7A7FB375F38896E7C1C6641B56557F52F4DA23320252AEB382082B8560CDB83C34614C40B8E4DC4CE54B4C009D9C3CD6884C11C616520AE0D220E2CD03A869147FFA894D5B02C75007BB09B51C8F59A53EAC1AF1A0195623217B578BF4C3BF59459FE3C9CA7B677155436336176A99653FE677D0D9BCB266B2E5484A72BF8A86F1B250B5666E40083BD24CF578C4F9386BCE2F034D2E9347835632A1AB39726C2F467A864F5863C0B498491111221BB2E83386DA51C764B8597E2B503A21EEEDAA6350683AA82659FA276D9B8AD3875A019EA6A00B31193C9284832C581555D7C478F81E259150C41E8C23047EB0599647CA403A7F19273A765C439535EFB20A6861A1B7FCBA48927412AF6C9364670E2E44C6C630A930B9437529F0AFA7534A08B7606A512FB737A50B6A08C637087314DA4BBD76C35A312C091FA3A863A3B8C7874501C8A9233212E592C828829800C9D174CCA70761BF8188FF5585FE1D59905373420120848F22CE8D4BB8EA253D3499E0AE59B526555A2245EB0FB0BA2A38CDA009A31F89BB46851A4277B808018E8F23148789B8EC69D8C622247E207D2E08491A3945A60AABDB7B5CBD260A348818C8493159199717BBE5305A5C785C4EEB26DAD73C76A04BB28B740D2A761C8C02096E0B6DD297485725EC59B107086BC40E71F61B90BA596CC905B564CD33D76E2B1624BC3A2E75440474DAA778B79F3819D237A41D08D9260226E63231B5494DA150093566F31CC3A53F581880512C25826A7981241F4C90EE3B3EDA1C277B5C157226342FB7E3622B0665109FB7342D13A96E3EAB49C53074B76B3A2AA26C899BD86C8A26159CA278C034E323475A0B12F447DF223AEF827597EB5422BF26CD48B6A40B40200898430CCBE1A6B8EE1635C761623A956B270DAC22E3A24FBBC8CB62710A197110491AAF8B89575D68B530530CB2380A5E65CDCC044B52A922B346E50005DA16B8C2189525950A109F74B225213C28113BC793857E9C384914809CAC7C8EC5667A34B007C7EEC63AE9EC21A46497B6B836CAC1C451B03814B7C47554A9E6039842418468FD5860ED6CB13311C638B86680BA1628CA09AFC406D944CB0AC11B928899CF333AB54BE5796A6E0DB7CB2B2C8C9B9AE6F300A3D508EEDD292C77C589C6682E2509B8D712C6B41669A5B5363FA06F6BBC0BD272ABF0C423E0C719BA90CFF3B0DC2C390E30B46B38281864B5D8BC2AB339C48BD9CC8FE70067358722CFABFF6BC907A457F84B1BCBD6C765ADA9B5C684D290C53614123A02660FFA22FFAF602111B7612862D2D204C65E82DC232798982652EA51A362743BEA629A8324F76B693124B2C3772111C627E9DB55C49FB7AE4204222D850311CA5D99213173416DF4BBE68B6B6FB514DD4B821BDA1B50F5587B7BB254A65A2D9E6A2C5BAA0E71B0BE88199096C516F84A20F38A9D32520A0064E955697008A9BCCB6524EE56825BCBB776092C99A040B85C2E6E1669F08932F63635F1C37E989A4F8B2190C335E31A03AA06A755022C895485780BC90A969C834091F2CC64960D399EE65359AC245201B948BC2827943A06165255B0492A7236E7B69B66847824D8873A24B6267ACADACF330F306652DC766DF9269EF911068B50DCB199996A294B8F935DF477F00B99882A5A5FA8147023737592A2D797358BDA228BD62440FB0C3811B73CA1C8FE4E1C070498B11BC816DA770BD895A96338FD9A6659FFB88DF51719BF3A4B208647063CF9EC985EC087FA643608E0AA23CE7749EE3C7983783992961A409729A1C6F416A0A0A5659E8320F95277CCDD31DE6FA3E41AC9DE3293E3AB36971842D6F8B2FFA9A26DE29B0C1A26815362A657A5571FC378425B23089BB94016AB2E180888226D1F7B448749280B978958198CBC626539ABAA520F4C1FFED3ECD10DCA6A4D6EDFA0952D6E2785CBDDB", + "sk" : "EA4C84806AB1066A1665A830346B85AB6B9494364F2D46661CD97115948228557CBF7A541F34899CEC8CF1A3C57C913D6EB713D3022B13C7C15EA35158B043B9829C0516C5BA44327CA81DE2313AEDD1A3E9A5C07AB07BFBAB2686B9A33010A85382094E1C9C400714839AC2A2422CA6E10A96F70C8EDB8FFAB42562E7598D501168D919A6475E619A87A4C0790131684F3C8320466E002D619AE828324C163CC32A56A55AFEA2BD51625186784DB007673F1314EFCCA127A90B53893901D4253AC3625BA543A4B875ED322B2C510A9522403FA08BDEE8814492112DA917C1548E93AC360BD651F311BA8D675EEBDA8E78B6A0E5D4C314D89100B58A4FE6AF99979BF58B8B2A88229A53C73BE55ECFE26C48DCB4ED005680505CAF570998341EFF71864EE44D030262F3BC1346E44795D24CBE346A9F7871FFC71FBE0C9F03C925FC9904ABC4A58BDA6EF7D408B21A145E544E7F28758223C1B2636EBE2647ABC39B076C8903426EDA5359C58B22BE15C1F2405CAF641029F6810789B5C150525DB917BB8B82EF217F1B726DBB3A1589445E4FA472DA00B3ED673B8A95104E9039E1248E14137FEE3A34C0DAA6B937AF71B75337694394A7C180191B1137A92CD71A588AB5969694956369EE85A139DC552151AB48068147047B0D0A8F8A0A3373C60732FC0790D488784A58E07B0180B1A5F322A5C7609BA0759DB31AC35431736564724A53CDEC4CAB8155229A7036524ACC08B8B9069B53E497195F656B581A037D8309EF072A2810A5762A05F759BEBB7A27DCC0AD3E4824CD2781A6A2431E8BADD79902E8E492E40A9253E758100A19C17246409444F3B4BFFD2442AE86C544061FDB5971A0E0A1BDEA4942A8C4AD11571EE9460A539B8F49327DB237E2C5B95B371B2259138F68252AA5CD95D3C2BCF410E9201E71641D62EC9C9896A86D643505C8B99A625A8D19C6C4E0A94B816B910156B7F125C14CAC14498C643C8635D8B49962019F0A885B4A91836BA9CB16142AD712FC5C99137A2AFE2195E27A006F9B6BE6D67FA9EB00C9741847C1BB228036330999120870562487FE8843A967B362E1659C8337BBA05108741340E38057F351A4605388874561F99DB1C696B23B45F96A48377A18ACFB4D7200B7CB65B6FD0672671259F9337579424CEB2315336919A84965FF1BB9CC92622ADB3B8A991768B72D07C93898D815E4F49E8CC0500E64BB37BAC3C4613B6D4BADC656530955B9F3984C7B1A97D09C75242C169E9886A8E543C58812F4829778FA9CB20706DC84A4B5226786950DB1337061B79CCB78C4F520B232DB36AA599C1E800956A28F2E0B05E3BA11E1432C89713A4BE993CFA552F1C11D0CB8B3FCF2525E30C2AAB210EA488871430BFB2528858053BA499DF337B8853959A10504C124569086CCCB069B97A1B782150542E184E210A24C0B5447487AD5A8C291C5C8A9B3B9B701C13D7114E337231959B7C18B2631FCAA40E841CE72B633279E57A38E2FF26EAED13AF3F061595B679CB0C886304D874392B31173C89889615BA9676320D917424B608B057974D18C1806BCAD1D955B48420F927C6715641E6E867F073968A23A5751A799B08B2E1D30C8894634968B6450C48B7A4BA3894628697960EFB753D2540B6B4432A6B59C92EC3398E9C0C476173843CE80C626DF72B18FF7424C923FB0DB28A8B1903BD19B963ACBE1FB6F3FB27180490E82C97592D41ABBE486128CB57999816A97C050EBBC4781A672D07ACD13415F036B26763365CA756A7C13DB0B1F46FA23F591BC5A5B527E72136368BB85BC52F0916F921B2FF3C96EE0759A00F230D8B141A8C532F037770422A95A495B3087013393694D496A0A4241E8D62547178E2EF3663E211FF7BB213BB69555B25E91CB7B34039B6995C8BB91A1E31937AF23B09410CF9F583A76E04948C7C3D341C75A30AA670707EF83793537392917A0C2195013B54C0A8B3E4686C10D25239A03C3ED28C916F40D3809068C542EB8E0A321BAB4AE0011273190BB1136D5852ABAF8BF82156F2EC402725503B8849DAAA9BF266490DA991A56A30FE3C089CEE7AC241BC1528A0129CB8EA22B1C90023C9D1CB4BB04268B60CFEEB8071E4B8D6B52798C3B960CD87BDC66AD467649D0A835B5153BF2EC57F12B93A1F055F88CC36236016D4809E5D9096762571C15863924797872CDD77370917720776B8EA9B72189F237E9D710DA6906AE25331B9C82CA0CA257DC980CCAA23EE61CE1E681AE09AECF967C33505F83078BDA132D1AD623373252B72109F6E6B8F5481DBE89B6033558B90A70D3866930A3C78E024B268604C8B3BECA583B8B531A4A6C094591BF173107025BA079C3062A607E30647308987084341925531076BA04E03C8DCBF551B56885C383A5929A54C207B39E162348F7A7FB375F38896E7C1C6641B56557F52F4DA23320252AEB382082B8560CDB83C34614C40B8E4DC4CE54B4C009D9C3CD6884C11C616520AE0D220E2CD03A869147FFA894D5B02C75007BB09B51C8F59A53EAC1AF1A0195623217B578BF4C3BF59459FE3C9CA7B677155436336176A99653FE677D0D9BCB266B2E5484A72BF8A86F1B250B5666E40083BD24CF578C4F9386BCE2F034D2E9347835632A1AB39726C2F467A864F5863C0B498491111221BB2E83386DA51C764B8597E2B503A21EEEDAA6350683AA82659FA276D9B8AD3875A019EA6A00B31193C9284832C581555D7C478F81E259150C41E8C23047EB0599647CA403A7F19273A765C439535EFB20A6861A1B7FCBA48927412AF6C9364670E2E44C6C630A930B9437529F0AFA7534A08B7606A512FB737A50B6A08C637087314DA4BBD76C35A312C091FA3A863A3B8C7874501C8A9233212E592C828829800C9D174CCA70761BF8188FF5585FE1D59905373420120848F22CE8D4BB8EA253D3499E0AE59B526555A2245EB0FB0BA2A38CDA009A31F89BB46851A4277B808018E8F23148789B8EC69D8C622247E207D2E08491A3945A60AABDB7B5CBD260A348818C8493159199717BBE5305A5C785C4EEB26DAD73C76A04BB28B740D2A761C8C02096E0B6DD297485725EC59B107086BC40E71F61B90BA596CC905B564CD33D76E2B1624BC3A2E75440474DAA778B79F3819D237A41D08D9260226E63231B5494DA150093566F31CC3A53F581880512C25826A7981241F4C90EE3B3EDA1C277B5C157226342FB7E3622B0665109FB7342D13A96E3EAB49C53074B76B3A2AA26C899BD86C8A26159CA278C034E323475A0B12F447DF223AEF827597EB5422BF26CD48B6A40B40200898430CCBE1A6B8EE1635C761623A956B270DAC22E3A24FBBC8CB62710A197110491AAF8B89575D68B530530CB2380A5E65CDCC044B52A922B346E50005DA16B8C2189525950A109F74B225213C28113BC793857E9C384914809CAC7C8EC5667A34B007C7EEC63AE9EC21A46497B6B836CAC1C451B03814B7C47554A9E6039842418468FD5860ED6CB13311C638B86680BA1628CA09AFC406D944CB0AC11B928899CF333AB54BE5796A6E0DB7CB2B2C8C9B9AE6F300A3D508EEDD292C77C589C6682E2509B8D712C6B41669A5B5363FA06F6BBC0BD272ABF0C423E0C719BA90CFF3B0DC2C390E30B46B38281864B5D8BC2AB339C48BD9CC8FE70067358722CFABFF6BC907A457F84B1BCBD6C765ADA9B5C684D290C53614123A02660FFA22FFAF602111B7612862D2D204C65E82DC232798982652EA51A362743BEA629A8324F76B693124B2C3772111C627E9DB55C49FB7AE4204222D850311CA5D99213173416DF4BBE68B6B6FB514DD4B821BDA1B50F5587B7BB254A65A2D9E6A2C5BAA0E71B0BE88199096C516F84A20F38A9D32520A0064E955697008A9BCCB6524EE56825BCBB776092C99A040B85C2E6E1669F08932F63635F1C37E989A4F8B2190C335E31A03AA06A755022C895485780BC90A969C834091F2CC64960D399EE65359AC245201B948BC2827943A06165255B0492A7236E7B69B66847824D8873A24B6267ACADACF330F306652DC766DF9269EF911068B50DCB199996A294B8F935DF477F00B99882A5A5FA8147023737592A2D797358BDA228BD62440FB0C3811B73CA1C8FE4E1C070498B11BC816DA770BD895A96338FD9A6659FFB88DF51719BF3A4B208647063CF9EC985EC087FA643608E0AA23CE7749EE3C7983783992961A409729A1C6F416A0A0A5659E8320F95277CCDD31DE6FA3E41AC9DE3293E3AB36971842D6F8B2FFA9A26DE29B0C1A26815362A657A5571FC378425B23089BB94016AB2E180888226D1F7B448749280B978958198CBC626539ABAA520F4C1FFED3ECD10DCA6A4D6EDFA0952D6E2785CBDDBD5D6B62E0449476F7C6F9EA3621237BCE0F97B11FE0E65776F1E92DA38362CB340B4E01E03F62E5F489C39C78D387BB33B526CEB6907734A5F788209AE3C2647", + "ek" : "A2A286C9E15510E39650C5EF87D06DD026100423756026BDCF8190CE1EEA86D4DAD5FBA1F3CB14EB56BD8F083856583290BCB3BA509412337228BB754648BE2982FBDE4623D983637035A518847CF2F1C2C8E8EF67BBCAB745137F9900461F2374463B0BFF4460D72C89803445DBABF9D90CA72EAE880FD0752B83552465F6788D4F92E107130265083CDCA0CA13CA06BC00D3058AB6D037D09301956199C0A7FD58434D507136C36BD4CAAC45A714361E8BBB587233313E986C5CBEF5B0D27E431A47315186078BB8B3C054C9F5335EFD1738DBD69134DF8D7A5DFFCEBB3B34E1AFAFF66DB85D1653CBFE761D4AE91964E07E4F3EE62EE6C6BF2FED49686D3CC54B35C1E9B6296E3F79BF01D433848A65BB63669B9C15A775BAD03FED7A1624FDDF406C6B059014FD8AEA14D43BCEE619FAF0499A15C56CA44864D862599CBB4CFC319CC7F3706E72EAD20E71414F80F48BBED1E20788616A70458CC0B378732069564EDA748FB2E6904C74C11781AF0532F44A95DBD9ED6A4630C289615229CD81B2215D872F27CD50B343651A2B8F00BB4554C34E190DCA0A3561471F1444BCF70707F08F834C9A08BCA79DC3CE8A1E7CE22F6B54EB3E91D2079C0A48EDB25427BA558786B3AB814F46E831B2C1347D24AB6044ADC1DF2C13E0B5764467A9DDB3B6517A9C6413B1A6C45B6CFDD0C7D2C762716D71D2966E8DB47652F9E8EDBE9B4931093734E1FE00FBA8864CAC9950D38E6507C99417026483CBD19AF6355DD667818A45DEA577D112ACE9087425DB3B6EEBE2F49DE5BE91DDD27E55189FF90E9289E2F64C44B98C3441B692FECDB587E9DE282FD2097514DEF8EC0100581041DA1ECB79ADEE998B4C3BEB6156D5D91F7C2A82D6E68FC2B1286C1A552BEB5FD364E1F14727F64FF19D488A6176C1167EEB3ACEDC18EB23F280ABC2F0C526CB458B5A115D51457C092ED33D60AC9DE48774B95143E5E5F567F7A75282EA545608EF9CD4F1E9BA9A5BCD9C1DEC3277702F1A9B80FE791A6EBB8C308111CB8C5E572857BB9D50A85676F65311E679F62372AF3671C6B067F36B8EDF0E7013B2CD9ACAAB753419BFE67D5357342A490B74AA95FB64F7AC60FC9F0ECE5F7DF56EE6BFF17A3A7BD1ADBABB2DD9B76BB044B3AF1B914CBBDDE90A564601E965927D2388C7A3C5001EBDE3DEE43A021E3A1C2960BA41B3A04DE9E3079488D000F3D1EC7D12195B74E9924A08A907FA2F10006F6AC7DCC45C9903AF4056A2E3960E592DE152812AD29EA54DC7B21B91A2BE8A5F9543CCDC15B08DF2E4608F614C2D91C61DFD93CC02B052D9EF9F12FC0124468E00DA6EA7B45DA935D6F05D35616B69CD5BD1317EE94C9315054E7D2B7E183E54AFAF8BCDAFC08479EDBDA56C15A5280C8FB5A55CA84FDCB82C319E0D963EF643B14219926B93297CCE0C14B15CD7D6ADBDBDD12602C9A7E0E3AFEC0613B27CB6DBD7F17F807C978080C9D346A6ED40F37DCD832051EA95C1DEFD65E8C9D210E58EA014A9AEE2BD06F9C4DB24CAB8FA649627AEF01A90E30686A0742EC56E2195F167AC8A4907DE4976F519A1374037EEDFCFCEA2E3CE13568A56EA38A5EDE1337E6FF826020FB18037BD681DD1EB769E4B8082FFB41ECFA5A0EE09E8BF6F3389FF2F60950F7F8FC96C7067215764A4A3C92B1D1911FB9EA9710F70488894279AAABB3AC6B2FD51C70CB4EC6E25425B9E6DF93512E8D9DD27546AA846DA9CE7E9658D6DDD2FAB0E834D5B09C3CD57BB9FACCDF5B96D4C8A244126FF969A46BC45F8E2F18EB62822263FE3A17C47F728ADF7ABC19FACFB96DFF8D5753881CCA527F9C93DD4BDFD0AB16A42120095110FF8AA4025C446EB091B5B8D084C592796B65CB079E8EE50959992C8C13A285DDDD8F3DB8DFE8AEB6E837AE08B5B57BBEE447A5938EF588E55517C7F54ABE92D13E6D903D48093DF0DF9E7044DA155042032B2831D9B03E18983D503D429C686BE03DFA8887EBE4DC886C351AFCB1B4FB043B8A5F53EFE21615C7F2C6E77BE358483B82664ED3AF6AFC6A0CD6146E4EC20BD20BFBC4ACB833F98AF31529ACE0B92C417E6FD761B9D3700A07032567442F603DBFA2421E5810E9B81920DCFB4A96BCA0FD1CE84DBB5EC9E73420FC122A71139EC61A2BBF9174647C2B67D51577F011C8DD140D27A2820F7690B058217B5E0A11404415CF5A257FD652F443CEF11DA", + "k" : "30B142FB52346D2955DD0901BDADC20F7F286C002C39C7ECCBCBB372A21BBE31", +}, +{ + "rngSeed" : "FBEA1BC2C379F4F8FDCB0DE260D31CDB064C9EA9B1D6DFBE91B3692ADD1D34DEC9C9FFAE7BF5E72ED2743BA3F9F2E43D", + "pk" : "ADA7C7F6A193F8174B99E5B0C249517AC47C4ABABDA18B523A665587579D884B7D98F778758C48D28C89C97441E7BA1DDCD020455C73A30377402C13C20BB8BCF9042066424A9081C9D44139E53F3AFB7D9A687C3510A2F4F22FD5AB37BB778267053055F38158C3762694AAA89596ED824A0A10490C49619960B79DB3174A227C7687AC0B4533197799969911A24BCF1E19A4D6224E2FEA4C4DA636483A09C39C0E63531E367B7B74C9734313BAD6056228D00D90F8806B6A06DFB45E4366867C2175D692C66CA91083B5AD8566BFB4816B40DA9971BB4855B44E13A04EAC687AF1A025863B8878827C1A06360E84C24E8940E404716E665E570A12B0532BC663001AE8CB94AA658A9394B60A6A1C8B008EC7BDF432002DD43F34FA04665278057CC5A0EC65B7315E831681E4D5CCC2F95588089122B18B4CB93DF740B2910CCB49142942B563D2027C8552BA5BB595EF35943DB0BC2C912D57F2CF166B2B9D219222A6A71BC55CCF7CB9C7C8C23398761AA58BD8A587013841A266000A375CC14018CEC577260AA9D962799D9900A991873B175194720F50A90310C4B8B5248C0F08A0B609440ECA877C708E1941A15AF6407D5873FC62492BEA381F431C8A727E5FA235B39434BDEB8E0918C4AB82A5D735B0F676AAC18463F8E65CF2B30EE3A97969DA994105D056D49E2245AC4FD1912A44B6F3647CB9C377DF2C7F0A99016725BDA1FB78670013FB25061E11C09FE1C92EC21A83DA9A2ED2C95636598F63C264C972A4365E6580440B0327D3638628E06CBB7BA024BB2481F64BBD39A5E79C46B43ABF0F405FEE38076A600468F033B9C52AFF5C3FFB6191AB8B37DBD8730EC63677E6B43AFC74331631FA0C5263268B17BB0A77F2699E839E66489A8744230AAC9C77AB765CC9094A8077C12C8E8DC6BCFE900E831C02CF01161C083B14677F01878655394F31296A33C612A18121CFBA2F7A1358AF8904B5E8C00028434EF812AC1A5D24BC2E09EAA5929C5E6E05683D292428324FE2A021E238B2717490F4731AEFF426AD085574C9A1F7CAB392D662FD25B4390A694946C6684C0A02D85DA187769632B6A829CFC24999A317436D4B47473BBF8FD73F9576C6424ACF65E88A4BB230AEEC1F5E08C7C05A1C84AA3AF9D44C25C81E4DB436285A4B1A572F950437E277294DE7C0EC087B8148607B30229BC97F7907076D9842F5A77FC5644177FC095E7245EAA7BA8F9C7840C99F852A109257B04BBB3679F80A617BA997F5B5B22C14D13807AB9BCE20CC271C9B2CB5DCBF67E4A0DF65A5ADBC0F8634670C4718FEB06880293D7C7184C52601C69C58F110CB1EF961AEAA95133483714B11B57B71CBB94E6A483444F65F293B7D349A02950079ECC18CE091AB09D647141065E037C2041C932CA092AC7B870E4A64CAF14069FC9845CACD62549356C38FAFBA2A7F7133C5F7C630721FCA36AD23767E4D86A2D1EC8C41DA18355A9375659C9B7C04539864B1098B8C862DCEBB94785370430498CECB064DC8AEE2E385FD775749F47C1F38B6D6D08A6C3A5B2E148204D50048A3C8E5F13E2E3059E6A3554A636ACCA6B634ACA6DA71977E33A74F0A56E78CB856B816B73681A3A96F5A4328A1911A7E063EEF31440FD21E5F281E9BE9954113ACBC3662529911CBD8221A7227E2D38E9BF798DE61627D67B8E8F62F2E10BF66F24187D2AD2EFA071F0B2210E53091E29BE859857E801348092C572B91B59102E325104C6C1A49C7654C2BB4DF431C12AB0F88E1132B63BF56C1616028994A304536564DBF18B54A16B50B9C75D3F347D8CAC3F3BC2DC9827155C507294014C8C92E4121386C936F3BAC661F4C4F8604A2B648053E88792F5CA9A48719BED781AD4A7BEBD8306B5401DCBA9A69A35128A7A89D22B97FFA5C2336CC5CC090A6CAC001DC560AA25F8F65093F0C2FA5540B51F56862380996A4C48D90A68F8956EF49019BA809B84496118235E02535A37B1DA0C95845F18342545ED12426A6E5BA1BCC7B348585669C003B02033EB024CDB70405F5C5E6077449D8C4E6E66D65A23B9BF51F40230BD241BAC33B708AE7B2147809BA2A14005038D0D197C790491FFA5C74626D2F6C5E0AB2C69BA55EBC83195044CD7C4C00D84BC716D02F8BCCCBB4F85D5E50C6EFEC71D667CC0338E6A6CA392E61BC1211681CE762516ADE8BDAD2F1ED78A9731A2634", + "sk" : "2A3A066CB7CE2FD3976CF377EB5500FBF9887C2375705C6FEAC85EB92CC4D423AD0DD37B4B1ABF98D72A57E3905B9531B3F9382A2817B464769BA133C3A550036ABD7A704EF0026E832B5A0D494362025DEBC90EB1A03807B35832AAA00A8C93BD72BD1908819EF7165358541659ACA85C2E640987D5CC3FC941B7777BA63E17987BFB81869A484FFA81A83293D87272EBE243416728A92632480112628463D880C8CB23193B7038B765CAFD629605B0A1645A2770635B47CB35D728A264A03C2D2C260D965A86EB9603B16C33A092D472C0857B632BE44A04A2424F4AB1F1EC6FA54200C1BBB4EF0A35A59BBCA8B889889332577835121195D38248D849087C996933403F74E56C9B3406DFCB416359CC9912CFF4F69B3E826071C5029671724C28212F0B85950B100412BC574A059ACA60A3F1C76EA45A6DC88CF4998C21805F9B17C3EA7793AF98224B017CE25BB16676A1146C933A587D98448D7FC188E6A510272770983B964091BDC09B10FF341064DA0CB347C8CA92C53EB83BAB85248E0859A4A933BE5078FEBA8A8CA12D8B634946C24861FA7A699069C2C72DDC840FF20C4795A680111222B3E52116E64134616F4B223E0FDAB1B7A514C667155A42847C4C726E2C7211E675ACE1412303390B6A2DBDFCCE2D435750C94799A82DF899227D344A81A5422AF0C05B4A605CE5B00A438FDBDB80B8F224051C7C934937FCC8889C6BAA43E89244E1BC5F9B136A2B6B956A349AAA3CDE7338E1782FAF951518F29D492842A936CCA4CB09E81CA78586558550A7E11452197C29F7625E680138B03039612048913AA4A8C8B383E8655900549A472DC552BA39B617BC82405830CB186B1C89327145E1CB07113DCD39110CB7B45DD9A92A4B28B6E8794CA070F1E398E603BA39B5A7EB7B289885039BE10BED6A08B296298766752EE392E5D693396B90E71147463A63AA6B69E1E3C1426C403BCCC11C58BEEC481BD1F5B5A26657CDC75CD93BA89F834594240295544420E09F5B0BC9E76458AD426FF6B6247534AAE1A04A6A5A67894638C88BB858C0C21AF8376500B33143C917148C3244C2BD176FB134154879314D111BC2193AE5B03FAB328DB03837A177C8CAA585CAA45BA51794A7954837CB671017CC6325196FD767D50A65CE798754754403A0AF6A1C25DE2B051E502DA59C20E80528CF0B6E509772114A0E7B43436877CB0F175F8D1B0A774C36AB09A9D13013CF20667100AC1A314F0BA661BA72BBFB86890A48929DAC8CA0E40604B17BC9434013F707A2E37099021E1C7C8564E7848BD21B45D13C020B3A2C09823194CBB46841675A92C888BD1191B3CD78B154F650732B12634C3B8473CF044471A8A54DE3A601A4545566E9076D0149C8E8760CF0AA1A820E7FB24CE428A49F572AC1028E7109BE2CCB41F5E02BB902697E537305CCB425B8CAD1D63FECD8A8E1852E1988419E7688E891BAD58155C72002F190AD27A55725398831310CB8B14B06516EE2906AE86874629B7073E8ACC95548065275A66560D7935174CC4DC8F4596D000D288C5CE8536666FB275E33CD68E004210985C7D146BFC1B2E1B9A1BA1048C6516A4E4384C48921F271A4207369963B75C3D15E859322715B8A59B116DEB2BD623ACD158A8375A2C403F15068F74BFBDBBEAB602357461B9BB1AC5D429929025AC2A3B1200376A953704888A2B304B3EA608FC10B1F05716EF9466A670407AE66BAA218557177193DF197F3D692536C02FF5816CBA620D23B0A866980D1820D2417722AD440534A0F15E65573CBB8A896BE183B83CF2B954139A27D4A4EAF267B0A2471182963BDE3503E7B7FA723AC20E97357F24D5B6CC01B8B8606AA6EE251578963593187109452B352AB1F90A8928999B87B1C054A3B8EA30C4F79907C831636C9071277412A1FDA2E5631A86E7124F0393E1892857458327136A136414CD0DB09E7A9948995831882B1F08AC2B9767536E41D19FB54CCFB3565A470E1350B9D3A81EC11043A3A6F445433DB604DDA35AF06AA636BB88426D0623FBCCB6F9C43EE1B32F822416335AC36C7200E60ADA28096BEC7CAFE37C3AFF80F0EC27DC4AC5390E0756E080FF198BC11EA96178B55B00A21F5C81EC67744A8B236100CBF5CD98204000F931898EAC7CC091389ADA7C7F6A193F8174B99E5B0C249517AC47C4ABABDA18B523A665587579D884B7D98F778758C48D28C89C97441E7BA1DDCD020455C73A30377402C13C20BB8BCF9042066424A9081C9D44139E53F3AFB7D9A687C3510A2F4F22FD5AB37BB778267053055F38158C3762694AAA89596ED824A0A10490C49619960B79DB3174A227C7687AC0B4533197799969911A24BCF1E19A4D6224E2FEA4C4DA636483A09C39C0E63531E367B7B74C9734313BAD6056228D00D90F8806B6A06DFB45E4366867C2175D692C66CA91083B5AD8566BFB4816B40DA9971BB4855B44E13A04EAC687AF1A025863B8878827C1A06360E84C24E8940E404716E665E570A12B0532BC663001AE8CB94AA658A9394B60A6A1C8B008EC7BDF432002DD43F34FA04665278057CC5A0EC65B7315E831681E4D5CCC2F95588089122B18B4CB93DF740B2910CCB49142942B563D2027C8552BA5BB595EF35943DB0BC2C912D57F2CF166B2B9D219222A6A71BC55CCF7CB9C7C8C23398761AA58BD8A587013841A266000A375CC14018CEC577260AA9D962799D9900A991873B175194720F50A90310C4B8B5248C0F08A0B609440ECA877C708E1941A15AF6407D5873FC62492BEA381F431C8A727E5FA235B39434BDEB8E0918C4AB82A5D735B0F676AAC18463F8E65CF2B30EE3A97969DA994105D056D49E2245AC4FD1912A44B6F3647CB9C377DF2C7F0A99016725BDA1FB78670013FB25061E11C09FE1C92EC21A83DA9A2ED2C95636598F63C264C972A4365E6580440B0327D3638628E06CBB7BA024BB2481F64BBD39A5E79C46B43ABF0F405FEE38076A600468F033B9C52AFF5C3FFB6191AB8B37DBD8730EC63677E6B43AFC74331631FA0C5263268B17BB0A77F2699E839E66489A8744230AAC9C77AB765CC9094A8077C12C8E8DC6BCFE900E831C02CF01161C083B14677F01878655394F31296A33C612A18121CFBA2F7A1358AF8904B5E8C00028434EF812AC1A5D24BC2E09EAA5929C5E6E05683D292428324FE2A021E238B2717490F4731AEFF426AD085574C9A1F7CAB392D662FD25B4390A694946C6684C0A02D85DA187769632B6A829CFC24999A317436D4B47473BBF8FD73F9576C6424ACF65E88A4BB230AEEC1F5E08C7C05A1C84AA3AF9D44C25C81E4DB436285A4B1A572F950437E277294DE7C0EC087B8148607B30229BC97F7907076D9842F5A77FC5644177FC095E7245EAA7BA8F9C7840C99F852A109257B04BBB3679F80A617BA997F5B5B22C14D13807AB9BCE20CC271C9B2CB5DCBF67E4A0DF65A5ADBC0F8634670C4718FEB06880293D7C7184C52601C69C58F110CB1EF961AEAA95133483714B11B57B71CBB94E6A483444F65F293B7D349A02950079ECC18CE091AB09D647141065E037C2041C932CA092AC7B870E4A64CAF14069FC9845CACD62549356C38FAFBA2A7F7133C5F7C630721FCA36AD23767E4D86A2D1EC8C41DA18355A9375659C9B7C04539864B1098B8C862DCEBB94785370430498CECB064DC8AEE2E385FD775749F47C1F38B6D6D08A6C3A5B2E148204D50048A3C8E5F13E2E3059E6A3554A636ACCA6B634ACA6DA71977E33A74F0A56E78CB856B816B73681A3A96F5A4328A1911A7E063EEF31440FD21E5F281E9BE9954113ACBC3662529911CBD8221A7227E2D38E9BF798DE61627D67B8E8F62F2E10BF66F24187D2AD2EFA071F0B2210E53091E29BE859857E801348092C572B91B59102E325104C6C1A49C7654C2BB4DF431C12AB0F88E1132B63BF56C1616028994A304536564DBF18B54A16B50B9C75D3F347D8CAC3F3BC2DC9827155C507294014C8C92E4121386C936F3BAC661F4C4F8604A2B648053E88792F5CA9A48719BED781AD4A7BEBD8306B5401DCBA9A69A35128A7A89D22B97FFA5C2336CC5CC090A6CAC001DC560AA25F8F65093F0C2FA5540B51F56862380996A4C48D90A68F8956EF49019BA809B84496118235E02535A37B1DA0C95845F18342545ED12426A6E5BA1BCC7B348585669C003B02033EB024CDB70405F5C5E6077449D8C4E6E66D65A23B9BF51F40230BD241BAC33B708AE7B2147809BA2A14005038D0D197C790491FFA5C74626D2F6C5E0AB2C69BA55EBC83195044CD7C4C00D84BC716D02F8BCCCBB4F85D5E50C6EFEC71D667CC0338E6A6CA392E61BC1211681CE762516ADE8BDAD2F1ED78A9731A2634269505D6CB8212B9DAD2FA70171035FD4107FF47C02696B3489650D5EF9C6F19870A300648D2B1F1A637374278BC62B5ABB56380CDE88EACFBADB3224795A125", + "ek" : "1488B951EB42DD4850462D3820F2AF1A1A0DDA9E4774E115B929212BAEB7BF3C0C37631D318C616A3E8E9E682A7CE7E1F2FA0A79855D13926D714BC61DC8DEE8F46131FD014555262D168C19CCBFD749E324F1A4A7F08442EC35C8A9EB3667047A15479F366A0F1E04DA555DC4534B05F983121E28F7096878C36ACC7B6DEAEAE1979F0423BDC02A12E16B2C27F80A53FD3B52DFA8FAA050C5CCD9F84C6EB76AA72A3D005D07E70D7C6FA634AE253F0A32104E144E7489AE72DBA88FBA21601B858B85BB212DD338124443FC33580D12565F0B8183E773B2A0261341511E43EFB60AB9D606DC94BEE8F046113DB8BF501D5A8B60C5644658C4CB638E8F8884F3DD39B80D8DCC7642B24F8F1EE4410988DA980E61A77D1F6F5AFFF9F2EEEAF6C6C3FEEC75232F9A9B147A7B8FA35F61C3728686C1D5C3198BD8C474D8E2C2A6192E1690561D97D3E7C47E3FA09EFA031EFBC509E460780D49354A59DE30F2D5B335EBF9072BE6C834D65C6CE96381B7631F24C8F19CB91C9A98C6F1069AF1E596253A4AC8478FA19C1FE8A2142E5FA101FFB9A618785159F63E1BB4E2BB21DD5F2C2AD0CD2A5EFD5F49FD855D7F0B00064D7C653E11CFFCFAB8218AFF595A7A0A9F556789E70E75ADCCF82FBC69821DEF3F2027299EF981C7A02D24F5F307E1CD93469C14467884FEDFD07246DFC290EA9CCD4F969AA5D9D5791990CBABD223832FDD332C226C59E26467E5DB98BE5D7491EA2243241545C914420B3FE980C3BB8CCA7107E1FF79F74FECC4407891C88CDCDEBDCDDF7931AF3518F3EE4BEB51F0FF579011BBD1338D0AE979D271A9C7CE4A230C3112E483F27E9EB6D8A52E44D26BA07B019B81B21E118C6C03FFB6702C8F22ABF1727D6A67C57390EF7C7EC21AF9C2C8C4822A705F56D2423E65D8F383E9CED71D80BC09588A4499EE871C3E6A7C6B37E88CE35B871254B518133EB952A82D29C3A65B9E9C3DFF20E95367765716E64540057F9BBE661B2B473376E7864BA4C142996DC247ECB7439DF0023CCD3E304C14FD5D9D923711912B18757B77D89F0464C5A4AC73DBB05DD0A7329B2638AE66DD92A593AF809C4202DA5007CD63B20A567B383AD24553C7EAD78EE21B39A99DCFC63BA78C78F841175B66B038AE613199D12D5B6877A3B68F26EACA8982150637BE6426B8F571AC2E71E5AA7935F3DBB93BDD80AABF7E00F4574677BE443E318A3A77E1C746EB7B011CCEE28D6DF133D91EAEFC86E6E452669E3D856F71BE282BF14F7B81D2A0A7B5BBE53D02976631ADB7B32FEE11B6FE4C7D2B483815D0026AEC3BE3CC170779FDF611C363C8409CA0FA561DC0A9791EBD9D4CA84EA9ECA8C693B3C9B46EF0A725C7D8BBADE0A70EB3EAFF8B442EAF38779F7AC7B3479643AA3AE008031E3C7202D07C498FF91A531C78B3419DCF168170DE084181A700B3E23DDF064E3C6D4BE8C87291BB447BC40300CF36A01D922B882F3D6452FD694A5D1A3ADA8D598F0DB9DC4E22E60E58006473CA396EEADA08BB9294781FC7FB3DBCEE84351844E13A619E98D762936C6C6D79484E204BF22F6EF3A3E46596D1961E51D0F1BBB3CCD7134943B7333182D1EDAF6C797EFC16D876BDFD2B0A7998D74B1B4D63C55FAACD912660104C5A4087F955A28FEF16A65E151B662836236492FBEE45D8DF0146AF632FBE92C194AFFE106CA406A69CE236C80214E3EB7C82AD2FC114960FE5E0B66A1D4B0CAFE5D3F3AB7775606005391238560DC57DA0102E40E122D1DFA594860D612E536EFF6C7F7E8C41440E03C7B68DA5D1985C88C2FFAD1B6AB0A9DF166B3C904A562127535DBFF5C7B4621A424774184564BAAF7297958F9C8866DC5987578B91179A6F1D541FCC7338779E4209F52494F14DD67F07253B3E73454E5C2F2F35893A56D5517CB556D69CABDDE0B9714EC67EB107A62D163C8BA3EBC99808929307703AAFE8AF309D42E39203BDE07F2CDAD840297ED0189AD561A272893B6EA7EC82738864C76254E1DCD19C55D69800BCE6C58E3A2EE34B98BEEC2403251522AE6968252C98E090977A41A45641804BEEB0E4DB2E824C7E1C7994881A62C27014403CACFE9EEB9669D358EF2D19981DF1701ED80D3A4DFB900DB98D5C41A189C8DA99A8D92237DAB7AF444E35E9107D79068429B0E3E5452376C13EFF14D754E374BC1B0D4D1FD04BEE1F085C5AC39C119BAD", + "k" : "DC3C8879A0F5FA36539DC12A36028A6465AFA12010646A0B3883617126B04DA0", +}, +{ + "rngSeed" : "7E87FB886BC3C7C9FC12569F465D2ECD12532E76CC27C65644C8D3DD603B0CB2D036C5974E675058F271D5C82AD7A813", + "pk" : "306C0E7E44A625F44880CB0D125BAC36B650F8430C647C68E1CA6306E39C61142C2A5924CD0C9CD5A085F4EB5DC4815711E4AA7E3A26E521CAC85C303E420A18A3393D996C1CB68DC9904588301385451788E57842305C064807421034AD845DF2BAAEAD84ACEE401FD912B191C89F51C436FF6BCF4B33B0B2120440E65777F4BFF5DBA7560148364046598ACF3D46B70F7960EB9A7C5FE893C87C6DC5741CD84B080B7A4D0A596EFFA363B6441848D849B72A7CB9F1597C99B7EB6697BDC3181DB25CE213C35725BCCA20C840066DBA39420763572F187758D05F6E43CBD41296F7C7A637CB49A57B00A2A9CFA7B2BD1745B5CB0255B1A68892431704F4BBF5C4844D0C1E9CA5BDEFAB042FE1AD30D4491427543CB39FD11717035690A77149E09A9173A433DDE8A29C40744CD4A7D2EBAE568A392981326FC8BDC2989869D6A56F6715CE65A51DC9A5E8F5C304AB6937F41964E80BCB259B9494BB713B6C882B94AF5528A6B1BEE6886F1DA41D5A10B8CBB188ACA7A820761E10B6797A8A5AAAF54B5F724C8FA9A41AD09BF9C9875DF8AD40781EC93748B428CB0527C9257AA83D412FF1755D835343AE05BE3211A447011944AA8952F2CA001153F10BACB18AC64619689EA6562F23C0FB5A33046C5DC5B7C37E2133D0987A44C207AE5ABCB38BA68E13505FA5A05BE45AF5887606704B7B4A4E18E5B78F518E8680A4C3A678B5513CDFA3B18DDB285A562F00F29CAD2C984F60C005F73D23E3CC617148D6A53177D10004981FB7E8A1CC362224E48D0CF69D28F213082B4425368C2757AC8493393E5495F35A41646225B3741E5DD1BD6E354681E8B47AE5C576B19D7C807FEB4ABC89EA94F2D150F946920A0A3D6BCC3D1799332304035515273C2C4E3764CA04E1653BDABDEA77819E0490416211BA7877AB8028F8416FA08918C7A7791CEB4A65B567838283CEA96997E3CE2564CFA0D41C43868BF6F6828DCC78F5C03AFC4422675B9FE926C5D2CC197046C38A30CD5CECC076BA9BDB3C57A4FC806E835EF6B52B44070E4689BAA7633458E0ACBAB3A781AA83158B31B1C949338B58AC034FF2C2C80D3BB54EF7C10C5281E0D5930F3817B9893032246F6AA82F7F6CB29A467395340C6B81347B2997F5514D90C95E7E84633813861C488EA27200EBE7CEE795B560973EFFE3A19C32950E821ED1140B454C8D5DA64453FCCFEE09565C7CAC7192952C360232861EABA924780895CA022737AB9139645BCC7B6EDC67050C5A90A4308C44764740279107F2799A455A8E4B2D384012D66956384B0CDFD108A1DB088FB34CF0824F82CCC7DA6A8824A90982A92ED3B46AEA02837F57AA0ADA783E8766887B538FBA4C33B157C2138E9A9155795399CC99613BF9B707519F001241AB2336E96981AEDBABD2F41F6673C4BF28929F777F2500CF0E382F8CA2182B9B8E4FC36BE4CCC4A1293AA477A76625429A68178733380CE950D5871BD7A0695254CD4367A1D8A94BAE95304F23622D07650A17341D401CC5133A772C8ABA82A63FEB19DB78AF7FD850C2104FD207579649B0B9EB38C9F2236F1669CC31A5A116474C9B66897C4F6D96CEF6428974748BC066338A510621D9690E4345C1A3756DEA7355148D45C89A16DA8867E164AB538E01E35489C792F79A53A967277054297FDB4365FC7F9BC15068B70B6702A8D0AA9968A005A5422C30596DFC9C635C189F9D2AC1F9481167558992B21AB4DBB54F88742167164FF964C64201DA9CABDCE9B458DC8CD7489684D4C8AC7951A2147B7358098975837083723EB85A4889547C3847D7317CC88A1C5EA19294358941467FC48BC6BB38486CA05715058171C7B2A178CFFC838DE1BA0A02C02D4049960D477D9F79A0B1B17BA9345AFAF641AAF80218D41A71B9063A5680579123992CC4EFC596DDBC0E1D2C66F035963F7B11C7D74C35158EBAF6BC16D6798A24CE928274E125CF3D51419BC6926E69AAF11562F541446DF6B77C625F9EC820587B68F1B50E590132D9C988B65C0A86B6C721384B9283CBEA128904F5A8DBB6B6A5FB2ADA47918AE3544C7978FBF9381F78468B0265290181B8F57EE043690023BC9DD4360FD13514C79CF9E3639B792AA1E70C763C52A43773FBE6732D262F9385716528200E37054237C04504A8169BAFF63F6FCBD8988928266537D344DD44533E2797AA03D8CB025E705A9F45", + "sk" : "09080DC7CB09012BB14EAA2B8D92A71C0078A792CA0607908C04B8B684A0AAE139231991812B5E763B2F191526268519469673713359936BBA126AB5E0B4B62D8A5FA0D76B365212D686AB74188878AACDC1B420D323AC67659DD2E8851317B0C132CA57BBA44671B7B9A78F6E6C73503125AB718BD386B2BFF1B6F026C2A2DA0F5A05578B8013A0B78FD628CFD7090C648C0AFD11A9FD768E56DCA02A6A87C7C523EA959348FA0DD38B5D380291C99A989589B6B784BEC0CABC181C33C45840700622A0E666F3DB15C32BC4636782FC688C8D5433BAB63C35D3CA26EB488660A4D141B33371413156322FC2A9BE424FB96712E7B6A324FC1559508910124C7EAA62B731147D1331A375B597494CAC741520A07082D6945EA92B7F326D3830814F62B20C84179071182DD707D4BC87010B406299C11A633210726C59184767F96720A918DE74178D397407950C62974B3ED703B8305E9892016D859FB1479046BC0A0E1766A985266B950D56E9B178244D9A5C969FAC3E1A41983DB574B3C9B50F2797C807B03DE8AB0E692FF913A79E1600A4DC8F4D537368784844A34797433C7FE2B8C5BA14AF06BB9AE4C5B301201A55A55B2A3BE308A0354456F0243882651D91F69CD5930A27A25874B45B7A556DBEB65BA5F68F684C643A81C0810143DE8C2352B0A92E86C72DB570C3AC0CEAC65BDB5912CB59683A88627086A06A00AE99922FAC3A47AFE5451B813C7FAB053C043069E70C0624A40B6629EF46BFDDC36F82173ABDA6A36642C4B3685EA23375A1906C9EB98E3E057889671D2D6BA894876816C79A6AD476363B27A2811FDD4BABA235077A037FB780C540132A046432F04AA041F25B44897C885C8AB8E070D5F07042C2A383A9886BCC40C7750E5CE85C5FE1B217151FFE2BA53BC9875AF281F927C8C88529F6395A75783098A9B3A89CB494A131D3118A51A868CE76B84CF3B2CEAC1AE145B070793ECE3916B86726CB52BB1B40A24BE7A9580A29F1EA9146AB5D787C2F3F777638FCCAEED72A74F0959CE5B0EDD45BDE14C4EDD0AA601B82FF6B4EDB9B77C833A8B0AA59252C812D25BB627B0F82E3186F4CA2ACE595CCA41AC2612E6C409011854B033360F179C397B06C82E43DAFC47B3F424D4D59051048C624E999FAB7BD73B18B13A9305064844BE040FC5C4A033B59C097299E6221E2C5CA3B9B05317376EE4B4E9963B172802030AB06E403B6940B5D8258572D16CE4C80A20EC0A796B06DF076B73E2B648534520DEC6EF0B57F61F4B9B5519C82D9931E863461D26D41F35C0A3509A1D684CC5047B9482955D0387808A26BACB2B3922AB780B7CE43256246073B6C5900F004A3830FC14770DEBB620B1569F6C98DB310ABDACA61DBD337A9773758AB92FB490A9FB95596D1087A696FEE494C0E5739A2AAA63A77CFDAAC6A37618CAB56A6C6CCBDACE66F7EABA24BE57CF1D1C1CBC42517604C17801865081F13F3C04C9118444578B95B6A55E51830F3C594B3662351B113D57C6F49640FF14468DBBAEC7A7EAD354506C0ADB923A0050BB3F89CC82B2CCEAEA4582F1998691BB1845A22CDFC721D6B088BFC52D6A8CA526625B6FC2267C277B9E86B88D9CCF81847C79A0075D36F9B7315273870D0239B8ADC9F9DBB05A1E44E7C4604AA3947EE2085DDA65651B6069E2C7D64F06986F527C02525E103B50363CFFB93C9735135EB1A0A1BB056842278BADBCCB43810C3727028FCB0F4CC5DFFBCB7D39590165A01AD4092CE6954F8C3BD28663D5E3C35142B0351538B2660020DD30D35C0BB5BD7276A8743C79C53A1F80146C16523080DB316382D2C9DDCE7857703BC3C939B4D5372185603FED280DD8B57FB6B7D80270049AA09BC6A206CCC47F935AD40602A89E9A633541F903A16545274D8A51A40150CDE7555A56BCC80261D9522ACDB3390F6A5719D57705EC8AA871BA41FBAC75254349B15BB6AF427BC1053A8A05E2D766A3B8243690B1352A59EA4F2C18E202CF69C205DB06A3915058FA01FA8E4A35E3C26BD5ABE05DB1240687616D873355B6485DC858F5441D9155AB5E6C9FA115F46815E6394C2C1CBA717CC0D8048561BAB198A9449D8D9CA47803C4777AB6E55443B3BA176A15A0167826EC662877A457E5B4E7401B9B30883BF67B1FFA09F306C0E7E44A625F44880CB0D125BAC36B650F8430C647C68E1CA6306E39C61142C2A5924CD0C9CD5A085F4EB5DC4815711E4AA7E3A26E521CAC85C303E420A18A3393D996C1CB68DC9904588301385451788E57842305C064807421034AD845DF2BAAEAD84ACEE401FD912B191C89F51C436FF6BCF4B33B0B2120440E65777F4BFF5DBA7560148364046598ACF3D46B70F7960EB9A7C5FE893C87C6DC5741CD84B080B7A4D0A596EFFA363B6441848D849B72A7CB9F1597C99B7EB6697BDC3181DB25CE213C35725BCCA20C840066DBA39420763572F187758D05F6E43CBD41296F7C7A637CB49A57B00A2A9CFA7B2BD1745B5CB0255B1A68892431704F4BBF5C4844D0C1E9CA5BDEFAB042FE1AD30D4491427543CB39FD11717035690A77149E09A9173A433DDE8A29C40744CD4A7D2EBAE568A392981326FC8BDC2989869D6A56F6715CE65A51DC9A5E8F5C304AB6937F41964E80BCB259B9494BB713B6C882B94AF5528A6B1BEE6886F1DA41D5A10B8CBB188ACA7A820761E10B6797A8A5AAAF54B5F724C8FA9A41AD09BF9C9875DF8AD40781EC93748B428CB0527C9257AA83D412FF1755D835343AE05BE3211A447011944AA8952F2CA001153F10BACB18AC64619689EA6562F23C0FB5A33046C5DC5B7C37E2133D0987A44C207AE5ABCB38BA68E13505FA5A05BE45AF5887606704B7B4A4E18E5B78F518E8680A4C3A678B5513CDFA3B18DDB285A562F00F29CAD2C984F60C005F73D23E3CC617148D6A53177D10004981FB7E8A1CC362224E48D0CF69D28F213082B4425368C2757AC8493393E5495F35A41646225B3741E5DD1BD6E354681E8B47AE5C576B19D7C807FEB4ABC89EA94F2D150F946920A0A3D6BCC3D1799332304035515273C2C4E3764CA04E1653BDABDEA77819E0490416211BA7877AB8028F8416FA08918C7A7791CEB4A65B567838283CEA96997E3CE2564CFA0D41C43868BF6F6828DCC78F5C03AFC4422675B9FE926C5D2CC197046C38A30CD5CECC076BA9BDB3C57A4FC806E835EF6B52B44070E4689BAA7633458E0ACBAB3A781AA83158B31B1C949338B58AC034FF2C2C80D3BB54EF7C10C5281E0D5930F3817B9893032246F6AA82F7F6CB29A467395340C6B81347B2997F5514D90C95E7E84633813861C488EA27200EBE7CEE795B560973EFFE3A19C32950E821ED1140B454C8D5DA64453FCCFEE09565C7CAC7192952C360232861EABA924780895CA022737AB9139645BCC7B6EDC67050C5A90A4308C44764740279107F2799A455A8E4B2D384012D66956384B0CDFD108A1DB088FB34CF0824F82CCC7DA6A8824A90982A92ED3B46AEA02837F57AA0ADA783E8766887B538FBA4C33B157C2138E9A9155795399CC99613BF9B707519F001241AB2336E96981AEDBABD2F41F6673C4BF28929F777F2500CF0E382F8CA2182B9B8E4FC36BE4CCC4A1293AA477A76625429A68178733380CE950D5871BD7A0695254CD4367A1D8A94BAE95304F23622D07650A17341D401CC5133A772C8ABA82A63FEB19DB78AF7FD850C2104FD207579649B0B9EB38C9F2236F1669CC31A5A116474C9B66897C4F6D96CEF6428974748BC066338A510621D9690E4345C1A3756DEA7355148D45C89A16DA8867E164AB538E01E35489C792F79A53A967277054297FDB4365FC7F9BC15068B70B6702A8D0AA9968A005A5422C30596DFC9C635C189F9D2AC1F9481167558992B21AB4DBB54F88742167164FF964C64201DA9CABDCE9B458DC8CD7489684D4C8AC7951A2147B7358098975837083723EB85A4889547C3847D7317CC88A1C5EA19294358941467FC48BC6BB38486CA05715058171C7B2A178CFFC838DE1BA0A02C02D4049960D477D9F79A0B1B17BA9345AFAF641AAF80218D41A71B9063A5680579123992CC4EFC596DDBC0E1D2C66F035963F7B11C7D74C35158EBAF6BC16D6798A24CE928274E125CF3D51419BC6926E69AAF11562F541446DF6B77C625F9EC820587B68F1B50E590132D9C988B65C0A86B6C721384B9283CBEA128904F5A8DBB6B6A5FB2ADA47918AE3544C7978FBF9381F78468B0265290181B8F57EE043690023BC9DD4360FD13514C79CF9E3639B792AA1E70C763C52A43773FBE6732D262F9385716528200E37054237C04504A8169BAFF63F6FCBD8988928266537D344DD44533E2797AA03D8CB025E705A9F453E8CA044ED0E215C83F03EB98B6DA9DA137FF2433B319D9CCBD0BF054135D63B0914D81173BFD7729D81603DEB601C93969B81C401E2B7B922B2873F8AA2D998", + "ek" : "304EB6156CFD11149F2E7146F6C15FE9AA7241A84A7340A0390690CB886ECAFE8A2989BD27FD7E7BEE1615454AC99028B96F469F6771AECAE1C4F307DA839309B0444D11458CC9A1FD68539B18A169A55A8112A706F2874C87F327074B856AEFC06D859A77DDFADC22142B86B9CAFB64D953687D92B9AA5EE286470AF409737C0DB828E0125F499F8A4726076FA75608DAFC242ACB69532620D03B6DE336346551E321739682F0AF317FA340ECAB1061AEAAFDE00C07281F879AE617A8EBDC08EB5C72C05384F1322792A084F3A02397FABDA9A7054D7427FCCC3D118CD51CC1002311020497AEBA07B0FD7918F50301C9EEC244585873BAAEE87FA55D609222897B9240830801F5DFEBA6044FF18292065638CF68B9E6D8FF18444E4C8573354CEF5EDD023DF1991241A65D50BAF6C0C771E43F7F789A82EFF0E1642F8C81F34C74F75A87B4FA38D0E9AA19ECE54173EC4448DFF27B42A158B0D8C3725056A6A7D98248685315A52416B03A129CF3D7CF178C8E8BE24B194A5FF4C61C45E013BEF385E7221AA19707B42D1A3ED96CC86831C4AB21C6A6437C05CB3AB0D176A9412CFA8DAFC59F0E6E29BEA76ADF0F66B08F96312EC2371CF590476A89C3ABA1C726993EDCF45CA98926053001C0F7D6B7F82821D964DC9AC92CC961972563975F2F392448420D63C6260DA34B46EE1FD44746E4E6929B7C5C1D500A3C00337B28B1A1AB532855F2F827293600CDE57302D168886B2ECDB4ABE8E1CC3CA274F26D12CED4D576AE1744B390D547A8F253BFD53C3D9F7C91B4F0CD0ED08456026D39F907F1E0CAA2A3FE1D9800FA371632D88DE9E43E2AC5BAB4B3A1D32FD2AAF0DBADAF243FB786E59DF05DFFFC22AB0744F343E4E6AF643D2FFE7D32092AD59C5406734AF3E86CF1109C350F569D8CA30C60F7688936BE65D678F8A60ABEE6DD8CC2F07CA946102A98E6865809625512618FDE21B69500EBA6E045AAE672C11BAB745BA645E07242F9AE69035916751105E87C398C3F31DD650140966476CB86B2C10A9D7313ACF38A6364C6635D69E251EB66C97CF74DCB1CFA26A6AE20CCC6BA98DB3C1079CCEEF482690376AF7A404551573B6C27778CC82DEAED0CDD64761E2218DFB5A07329C1B18524BE9E8713958C91F28BC6194D1CF20098B8DDE3945A97191EA8D3354EF583C00B362CE78CFD83DD5E7D8064EAB4D4906378784E716D5DD74A630C629A7ABCE8729C194A556585B32EA70BF49A24D8D78BDB32CA674C34DB3F927E60CDED70C36ABA64EFC17FF2B1634C043F5215768D7F99C5C16E8074EF3774B01333865DC2A078E0AA72D347C51AECEF8974BE986E10AD8A50D5D7678138E10FB514AAC8AB70F4304F72A275676658DD64A745A31B24D9E8BFC28D1AFA8ABF23FA4C4D1D0ABA9EE5505A3F5919B709752EEA3AA28DD2616C5837D83A105A1BE45CA2E62618A07D4113F33291D42FA3265B669598232D8FB44A7BF61B25905E1D91519A78D7D908A00C80D760CA0C963512C587E2F89A91C981EE104F9197BFE156577ACB79474791AF65A9069FED9960927F487ADD80D5C140C4DA30D982484B7DD0282C37E51434F7F80D22518C331F1486ABD4AE0CE66DE27D85D8CF816C1884B68A44203EA906F0D9B906E87431E380E69D2648BFFB96E7D0067CDCCAC2F04741229E4945891FF848417299A2BD846C9CBBFFC44A95DB43604BC5D78A13DC1A2640B536561A3BFC83FDAA95CE2FC28E392A424886A7BC4D41BCB09432FE0C4B1FE90DB9567FB65CE0D068C3AB2125563B8E6E31D8BCB12847891CE00567B2CEDEE673C9686476EB850D076D09AF79EB259910940755C343961FAEF2E84E8233091B157104A42E0FEB2ED1E5F8E872E357E496507E6B74293F05E1FB7D25D24514E2239AC0AA15B590EA78DFB68C9ECCAE38C6F80D17843CE57F787C9F461C5156B5BE68A5B3D269DA7F931A1D9B51A959D85505860E1D82C6F94D1D1C0187AE7AED071B2B9CCECB87D31517CB7DFC8F99FD678ED7C90886346A147CB98ABB1DAF34C79C0A3702841486C241D0851886665FE198E2C64DA2FC7DF12C67441AA22529B95DFDEB4D1C610C91EAFDAA622EEFC0048EB5DE240C09AAB9BEBEE4445F05E38703A3AFDE104C0D7A1391828F303FAD9BFF8B252493C1CFDADFCC34121EC2827E93BB9BF4C81CAC5EC20EF7BF8F4355C51A912662C95E", + "k" : "A5618AD614599C76332EC335B14E415FAAD77B219B11B5664504CD32C6FAC19F", +}, +{ + "rngSeed" : "AD1424E804F306C7FF513DA4C1E8D445AFCA7BC942FAC5C0B335733AAF70693712ECBDE26EA726EE0F9FD9D52A83B1A4", + "pk" : "FE3200F3E260B8BC589D0162AA2B1EABD229F9AB6F64E528E0F05B3C69B9C9F192964A3A6D2C96B8D525F0BBB32B848E5C244409904F1583C7D58209B91465B9E3A6F2A515ECF55A778119455BC57AF5AA885B64100ACBF9746787B9757A17C1416C4EE317B017348F5299661436C1FB5C8AEF032929FBA046A601804B7B4474461957C8EEDCC19C609253C23AE1428674B5BA69264EC1EA74F825198CA71C3AD929465B2769338A6359132027AAF46173415B31CA0624D7E6C258A91388742B0F71917DF814B75C38B06025FC9682876B597CD65CF21943CBCB4E77B1314C4B487AA46493FB7D5F734D0DA891BC51CC8FD0454A7C9BFED5747DAA43E2C95FEA422165E02819882A535A7E3127396120A242412BBF7384BC91372F640202EA9EA5830002654D40F346C1F2025DD648BEFB332BF9AE0809810445A2C91A6C51C68EA19B01CA287E3E967139F58EE66B4632346CF4240634095C59492FC3B919BE49C7F32B00DA0A9B95625131E24A3B03C0B44C0CBCAA7FDE1C7872645950818C69A62D864B251E54B10FB6820B9678026353FB3BC09FC90CC5842849252D2C6208DBC7754CD70904F15434A8840104B6A74814B555C69897B4B2D2A69407715F93AB337A7005007218B5536A89020332998A040599BC688F6497C520B73EBAA40B735F41D966CAA24E655848FA66A2B473437D14C4F80357E449643CFB34E1759676B0B2B3733BFA6B2324357931A72866E99430454FB1B65797A90E5257037744C0F06415FED93540A68FD2BC5AE74247940C21A061923C603C4A89309F8A7D1AE48A29370908D9137DB01EE84C3FB6D4BCDE28CA63C34CF1012BDB060D830C2AA6DA19ECC0C0A8FC0272E066A8D6225F3A2873A52992768FFEF0BD9B109CED760DFD2C3CE7D17CC95095F95BC84F448EC51331066AB0126505DF1273741220A869B518CB458B00B5E1E503F53C639BD2BF11D71C45E8866582C71C0663CCD19B0519330F36594F1385EF82199D76B4507318FDE59B6AE4185F3811F15B873BE902D80C44A9523351653365E369BE2939F6F17F753C776FC3421DC75BD0CCAE0FAB9BCC2A8175408950FA32E983CB736075040A857501B2E543B043B617C16001CEF203AE164EFFC243D4B1CBA2F225F361A7D65949CABC32B3B3A782BB18D03627CD2507F1D122A46C3E35F91315CCAAEA110709F648114220524B8FAE55C8E6CAA27A693C3A559496D30DB2458674392575ACCEA61C91CD3B9188B94654D15E7EEBB383E19D114BC0720B7552BA0D42D85863E984A220BC4632BBD7D1C33F925836E117B209351FFB01C8923EDBF4A54D500CE7DABDA45021601A5B19D9B0B736C8B1E30896B285A633C647658622B30A9B476A8FCC251E0971F8938063550CF39718C86B6849C7B55319B7A4E817B4447D265BC5189614247026C82C557BE5A4E1D302397865AF7277646B442874A5B0D5AE60429E4DC5AB30C132052030D747715DBA66C16316A7D10D180B6EA88A6E97601AE1131A2412B5E83039C75A1CDFD8C0764109D360094882725C627A8F9395CDFAA7BEA40263C8479B3A3E1D68CFA5688CFA19322B833E0EB863171A3F48B9910E5289611C4D51554574CB239934CF870550A0F7A4E78B1AC50B59AC5B1DE0F348F0315E627CC2E50707827B9F9C6B943010B46A2B752500526840A13D3123621462BF5486820594C40318B86731E1258DE6215D76D68B58083149A041394114CAF69198277A8A57082DA4A440F799F78064310660350B0AB34970E6D9C9E53A2A24B2C95135971DB128EEC54CC21378B6067D648C85C8BC21BB9551A0648825719D5FCC67717083E9D677ABC523340CC24DA5B489933AD7D1C1D12B7004BC1A875244A7B9810B29C77826AAC6DAA1753681E2B9CEFA4AA3A5C4CDD63A844166017F8AA79DB97115B86C447BB7E66B7964A19D410149FBC475EC1BAB8B06CF96BA0861062F89A621776507AE40849B82615F0B6D81AB82A92184CE9B8B07F69311FB295EB83CC5CC4545D89362C33C8DCC7453A70051F40A56691E212897746C17F5002D8C15BBB2B625EF267914D62759CC01DA4C8437EB3FACF336FA0BC0E83A9FF51C793DC44007A63432309460162257D191ED8872EAD9A8A66296A7E55D30D86DDEE023CCB84744BAB7DB9C015A60707CD7AA0EBE7B8CFB1D663D8B18C5BBF06DA994E7EFF9D64742E2", + "sk" : "A902027DFA84635138AB20CB6B0CB06DF848ADB138ED618D93B5857F11042D2C753E0765D3A1C6FEBC1FBEF347C58B4993F5BFE065A9464098BBCC2C61AA1AE338217592B657F60CDB39B740871103019D17504C4A572F2C5490AC61CBACD3148D23AD48BCBA53A7A331E3403C13934ED8A3A6F794C263BE9E1B4FE96A40E991798987A54AF53048AB9646DB8B06B9152136713668A4CA1CB3947469AC27C035BA69FDF43C2B4128EFB31AA7226902E41DE295CF22B6711CFC34A5276DC6AC9329D30269E637A4E92A80FB481E123C45E9BB04B1724E4065524612FF66A30633A4888BB8B5A15B8780A10EF8841C35C54B90B98F156DCDE86A0B78A8052399D0D4BB6D2822A450CDFB5C245F245274167388D25F278B2A3B13BC7CA108D2E09A2AF50F47E82BCD8C62813375D88C92F9005A1255A4EBC720146B97929925D9940797A95354D3CB64E0A399CB1ED1F1B395419C0332293FE37C6D676123394E40E3BE474CC211DC5240DC855F27CA87D7AF59B799860AC3427959516A4794EC9318D1826E8C529CA7BF0E4613A7E9299A416C4DAC9937733825F1223D369FE773782381C1374B9F0EB942D5EB446F07C3C4130B3DC057E4222EC6A5C365F2B8CA618CFE998446171B2CCB940EB49A47B1CD123196C04128E1B9C35F30B38287B831AB79191C488DE7B4F302BE30C84EE446B29E4476B41A4901D85CAB92767BCB88CBA8B91A23AA45E088F2C82BFFB330CDD9CC4AA6B46B032E36A885F61627357208A1B4031C858179305A52F57480483A6BF30654022FCE933DA873AF8C64A74B1B51F1B9532A6CAF0DCA3FB16B50CAD1189097B18526691CEC9E3D2B6D53D1687FE64B434A7084873593CA8F359365EAE00B1220099ADCCFA4C78B5F3056D5BC6E3AB96AAF917D4F1073C4A517F66447A4C15A26F96A9AC3C4FD624283757ABF435AEF7A6DE4FB6AABDAC65A99792E548E2C2C24FFF7259BBBCE3D588AE4725585517B5B68B712166171B9780A8C46B3D07B1864BA4A4B5C88E14666B09733C3CA7F1A185DC950E6854A086CB8642487A313A72F916200255A70D94A43CCCD9664975D50C2995C56EE142C53BBB1F596A9454B1BDEF4A11DD6A21746A3D499C6E3D7209B1004924B2B69C7C9E4286D871546BFC37481FABA482616512B3492C4778FD1977BD079ECC188C3172D3B6193B7032708981A71FB72495C6E6787C7012748C062CDFAE690B3AC483B985B2FEA1E16E51B4AD408E1F53290B48BF4A972A3676862853BA348B0F8D730FC577657545DA7500D989C657E787783008509D81BABD7227348C574474F574AA60E976B97814A5F7C886AF9C3941BB04EC3314ECC1DED62B39ED69636C07227DC11D9596103DC104D96B96CB085CD18AD7087743795B28BC6AD4AF3196DC7C7DA1907F6D7C7C862B4F9F1045C5B7C57907FC319AFF58A113807269D9A2DEAF4CA4EC501D6A35C1C23710D674F5B0AD0C5B14D3CA61145B4C8AAF363C7560A61923FB54B3DAAE6AB4F979DC78B971A105F5D5BB3D8F6201B82175A215D16C501726C8FBD903A2878152FC471A8B4236D6C10698284AD07A7F4B1784AA893669539A7CA8093D81C367B5F51996E3477148B626A35326010D9B7A52044D56355F7008375E2237B312C3A399F265304ED53382F766C21A6822C4864CEDC9BD8A26B3928BA0B206D7F446B95161B5CB4415696CB50739B8B7A484470C8D196A762F586C5604F3E0C7BB41669BC538436A413B2630D12D23B94486F3D8BAD351A5CB277933E6B1DB56B3850149E28A91091AACD9A87BEB84A457BF242E78C9D1AF9B0412C0B61867F6981CD6C6B8B6B928409F606C4FC1FF6F6453A73B209527BB2E25527E791F729414544C8AC4C7C51B9A64591102C36C5942365498CBE7F9379890A70CD8999610C06E7504A96B6A7F839617FE42E2D13972EF49AF07AC9F35444D89A7454E1AF46B239FBF2AAFB87405768760767A2F4721D7A57288A42BFECB512CE6A023A3221C74266990171D09AA61596787984584697BF80D79DFFE0674E416CC74B311A9CBE9FCC7D6B185A5D1322ABA71D6F11B673AA293E037464D214E9061EE19341B11199C88A78E4103B41F90E849664C08C30E3D9C011595199913DC231BDFCC98B0AE15F276054215B1FEB4C4EFE3200F3E260B8BC589D0162AA2B1EABD229F9AB6F64E528E0F05B3C69B9C9F192964A3A6D2C96B8D525F0BBB32B848E5C244409904F1583C7D58209B91465B9E3A6F2A515ECF55A778119455BC57AF5AA885B64100ACBF9746787B9757A17C1416C4EE317B017348F5299661436C1FB5C8AEF032929FBA046A601804B7B4474461957C8EEDCC19C609253C23AE1428674B5BA69264EC1EA74F825198CA71C3AD929465B2769338A6359132027AAF46173415B31CA0624D7E6C258A91388742B0F71917DF814B75C38B06025FC9682876B597CD65CF21943CBCB4E77B1314C4B487AA46493FB7D5F734D0DA891BC51CC8FD0454A7C9BFED5747DAA43E2C95FEA422165E02819882A535A7E3127396120A242412BBF7384BC91372F640202EA9EA5830002654D40F346C1F2025DD648BEFB332BF9AE0809810445A2C91A6C51C68EA19B01CA287E3E967139F58EE66B4632346CF4240634095C59492FC3B919BE49C7F32B00DA0A9B95625131E24A3B03C0B44C0CBCAA7FDE1C7872645950818C69A62D864B251E54B10FB6820B9678026353FB3BC09FC90CC5842849252D2C6208DBC7754CD70904F15434A8840104B6A74814B555C69897B4B2D2A69407715F93AB337A7005007218B5536A89020332998A040599BC688F6497C520B73EBAA40B735F41D966CAA24E655848FA66A2B473437D14C4F80357E449643CFB34E1759676B0B2B3733BFA6B2324357931A72866E99430454FB1B65797A90E5257037744C0F06415FED93540A68FD2BC5AE74247940C21A061923C603C4A89309F8A7D1AE48A29370908D9137DB01EE84C3FB6D4BCDE28CA63C34CF1012BDB060D830C2AA6DA19ECC0C0A8FC0272E066A8D6225F3A2873A52992768FFEF0BD9B109CED760DFD2C3CE7D17CC95095F95BC84F448EC51331066AB0126505DF1273741220A869B518CB458B00B5E1E503F53C639BD2BF11D71C45E8866582C71C0663CCD19B0519330F36594F1385EF82199D76B4507318FDE59B6AE4185F3811F15B873BE902D80C44A9523351653365E369BE2939F6F17F753C776FC3421DC75BD0CCAE0FAB9BCC2A8175408950FA32E983CB736075040A857501B2E543B043B617C16001CEF203AE164EFFC243D4B1CBA2F225F361A7D65949CABC32B3B3A782BB18D03627CD2507F1D122A46C3E35F91315CCAAEA110709F648114220524B8FAE55C8E6CAA27A693C3A559496D30DB2458674392575ACCEA61C91CD3B9188B94654D15E7EEBB383E19D114BC0720B7552BA0D42D85863E984A220BC4632BBD7D1C33F925836E117B209351FFB01C8923EDBF4A54D500CE7DABDA45021601A5B19D9B0B736C8B1E30896B285A633C647658622B30A9B476A8FCC251E0971F8938063550CF39718C86B6849C7B55319B7A4E817B4447D265BC5189614247026C82C557BE5A4E1D302397865AF7277646B442874A5B0D5AE60429E4DC5AB30C132052030D747715DBA66C16316A7D10D180B6EA88A6E97601AE1131A2412B5E83039C75A1CDFD8C0764109D360094882725C627A8F9395CDFAA7BEA40263C8479B3A3E1D68CFA5688CFA19322B833E0EB863171A3F48B9910E5289611C4D51554574CB239934CF870550A0F7A4E78B1AC50B59AC5B1DE0F348F0315E627CC2E50707827B9F9C6B943010B46A2B752500526840A13D3123621462BF5486820594C40318B86731E1258DE6215D76D68B58083149A041394114CAF69198277A8A57082DA4A440F799F78064310660350B0AB34970E6D9C9E53A2A24B2C95135971DB128EEC54CC21378B6067D648C85C8BC21BB9551A0648825719D5FCC67717083E9D677ABC523340CC24DA5B489933AD7D1C1D12B7004BC1A875244A7B9810B29C77826AAC6DAA1753681E2B9CEFA4AA3A5C4CDD63A844166017F8AA79DB97115B86C447BB7E66B7964A19D410149FBC475EC1BAB8B06CF96BA0861062F89A621776507AE40849B82615F0B6D81AB82A92184CE9B8B07F69311FB295EB83CC5CC4545D89362C33C8DCC7453A70051F40A56691E212897746C17F5002D8C15BBB2B625EF267914D62759CC01DA4C8437EB3FACF336FA0BC0E83A9FF51C793DC44007A63432309460162257D191ED8872EAD9A8A66296A7E55D30D86DDEE023CCB84744BAB7DB9C015A60707CD7AA0EBE7B8CFB1D663D8B18C5BBF06DA994E7EFF9D64742E2B4ECD70CF455E2195477C581FA72AF1AE232E7B5EFB374D9607FD958447B7C67E82AB6CD4250546E9D3AAC903D6CC326CC39AE0B04CFFE6C6B3FFBD29AB63DD7", + "ek" : "2D0D6D2ABE8BB9F639CE9325FC533ED60B2C17B87F3247A7AC1A844C528EAF087C602FEA85F267619AEBEB0DA73976FB54398F39D66E910E97384D198F453D5A7B3410777DF98681761703BB01B86316E3A3BE2A0BDB7A5D39019D0D1902BEB91F595EB9D194B92F135D66ED8379CCA11C5A9D79E8169653A3AFD85D230AF6DF64B3962C6488FBAC5F1C065944D8BB673903F7058459323E598BE6A7CD5062917325CC39950DEF9462381197E6A0DCE06F026F98EFC4DDEB8DB76FB5B47962747D5A3E5ADA14FAD39575EDBE62B0B2178F2285524A33BBF48155ECF2394A7F348404303DB8CF1B62609DCB22F01699B00B8B79B16275ADA23CEA5938A31BEEA9A14A1856573A5BA3EB5E2A6FD0564FE6F2BD7E7B9D0F837C2A1418CA71A6528C6856D3EB78A5CC73E6C5FD64AA5EDABFE31F812E52843342DEB6302099D92119A9DE4F385EE620E00004B51F25A24CEDE266ECF7D8F032FB9FA0B3C07DEEAD23311B6724DD4730600FE00E669629F8D1E14A0C8FDCF36F1393DC6E04FF6CA0D8D5B2CCCB4766F293D1C9C48D381ED560C2D9B5E9D25D2414C0E182AEBAF645F48F658F8061220E86B92FFDF9464E4ED3C6BF747BE8F8F343012FC14F1C8ECBA388AEEF65C200FDB0B45417A04311D8D431F9A134CBEE82B982060C64C6250C4822937A0768FC1925B496925AF9BD8E488EE6D41842011BEE1CF0B075D33554E3BD1560CCEAC0E3B609D24B656111F6FAE2DB2D8E47A66C040511AB32D8E781526FC683BA55D6F5FABBDA2172659BF71C23BA4012C1EEBE8C2094B0738A60D709ECB3EAFD719153BD8B6C15C106A0D96A0872858027E9AF1B7532BB942609C97540C67536F63A2401853181AB9DFFF80FC8D16954384CFE4F023209FB3EA920CCEC404C5CBEFF811B083F0070F352B8A0465C2CF33F3912AACCDF8F8F27FB14BBB46D1BE2416A52FFB27F377A4720F4E7FD61F6CD12F9C7DFB129772AE3947AFC9238156669095538EFB38A1F76FD7A621F1A572E1A708E5EB18E1818AB78FA8432168860720C7435B7C277989CDD3084A93B47A42D6D890A1B9C0830807D856480171B1E348788DCF9008A4D48C9A5AEF0D4974DA8D16183880FB3D0DA77F5AB28E936436D4CC54C4AA77E01EF1DF757A273D39C7F7D44D6E91C9F83E0B5D64239FEFC33AA02F354DBA68A47EA42B7C150E00EC60BA6416C70698B94930DCB2BF87EAFD1F6009D24C5764821534F8A499075B9299F904A2BF01AB550F49FEA96412B7E0747646579FF169BB7F509504DF64CF97BB794EB4CFCA4FFDD3773A1F38B881613DB32E8503EC3B63007DAD0B2976D6761DD944CD6550720800D33121F57878E3144F9D30FE79AFCA2551A0A7E50197744766BB5B87F8A2C746CD00C41C7AC3C0DE03EA4CA09E8311706957AE57450D6892C2B689C2C5A44D3CE00C0F3449F0BDEA20A2D4D7B58D5CB485E6579D251ED7D43841693F457E5D5961100E43DEDF8CCC2A299FC288711B0EC99DEE0DEBECDC1861BA61E730455E1419168656CE5C0D5EDD5E64314588329D1E91325581B5BC31FBD4106096193ACD9BBABEB95E54F496DA8B0B3DF662465838323C3C0005A44B0A2D574F6D9ACF82F04E80AE5551FF90E0BD7E834E8A05F8833F8D010302A0165DF8F04086B7585F6C3534CC46C379260507E27C3C104078126EC40E2BF1964265DD1DABA6107EA4DC9121A0AA16236B67F149036AA32F5C6C34CB67FABA51A83F21EC57FE3F1098511413948C0784150A29FB0D9607B04DE226ACCFF1A8C52F0AA4A08A75F089675FDA5B267EC5319ED33F5CB6DECCC36DEFE702FAA8CCB55EBC467E5425F72089EC3F88F5B8CE65312296F9D0E9388E03FB366047ABF3EBCBD1ED8F8511345271C7EFB9C6B3C38B2408A37CCA36F29293FD53B0757CB6DE48A28EA7F5E42DA715762BBAEAAA1A2143822C07E4D817B27121C89132C733EFF3D9D40AC0CF1BAC8DB5F8419B60C85474DA7756A7900FB84EDB7EA5017EC73AB5D2BDF5FDBBB18B96081CA78660C2AE3843207119762D7A03CD50A72400B47A7E3FAFE2333DA557116BD4DC575F8478B67620FED32E4453BBBC54CFFE36BAACDF4700B5F7E90E525C4E68187A5049754AF0CD9DA98E37358F7DD50FF539D47470662D5A9713B531090E6BBAB5ED9D882ED3752E2D4FC8AE8D3E506A8C980276966D3E108D1C2EC17C952D5BB", + "k" : "5A2911B8B370049B6A2716CE674BD4EF6E76DE33E5C0BC5928B236965FD2CC1E", +}, +{ + "rngSeed" : "7C33CA0E987226C8524DD56C811FA4D1CCF9995B1E4E4DD5B1481974E88CFABFBF6787775C2611CEFB27ED4403EA9B46", + "pk" : "FCC42E1ADA20B880B35F49A312180F66B866C4952D92F2BF38B08F6110850224909413938678C8F9585A0741B561A36B7680644947485B2462D984AE5EA115FD52202643014607067B9540457A3405E7127E841D004B86C094468A0743B82BC70569C3388338E0DBC6ABD1456CA3AFC4564EE9D361CA0A708E417AACA1AF12151D5FC93DB4B652EB990A0335C799A27B713172B6949BE937B570384F3627102DD2BD784C97D46C8A2FF2A1D2A0C438F0281CF29971E3C58DF77C33B83B5252CF0E72C4FB9448ACA6A3ABB06A22677C0206609598C544781598FA318BD58DA2625CCAF7AE759B774147380F0304163B0786A9203A1169D943B54B9B92F7BC7BE5FB17E87A37DFE73712C33FC0824AB448A9B2295A7364629956CAC2CB6ED54AC085BC3693FBCD9CF7B44D4B318E248AD737AA1B821FA985BF7F219828B1CABFE66DEB269A6BE49DC3F74AF594C820748FCA60961FB04F22AC2CD4787B5A41A91195B8588B3A74A1A188F95E50AB047CF42FD5B63FB88BA57DD24528F90C2F966A1CC91CE39BA848FBB2EC4576DF188350F587E59B0AC0848D71A93CFDA63E3EF93745C6516CBB69A5505B1F900AA4F91094306C84F640050393F1C751A05872AA7B027F678B1AA2CD5F97CA25806A53016EAE4412A7F23EBD8A7359E5A706A11415951AE2A45D60FC999B66A255CAB76EF85601B2974C462EC4202F83B2BA85190AEC7C6FD6263D72E19F7EF71B6FD37694EC1E56090290549D002C2DA8B18BEAB345F969BF1B23144486C299104DC7DC367265902469C45D7788C5D23941C6A1608A12586692EB759EB4835C537429EF287B6709B87DC22653D7A92CC314A295A6A6C939E33B3A87394CC40CB284B17987A088FFFC3F401C2B072CB72B467D59F930D82101AC725C79D54FBA036AAD5760A615CD5FA1A323A87FB63A4472228F124A3EF72A086AC74245CAC6B7784249D17C7A19A126B28C7530C1EBD6A806097DE35177A5070ABE84BBE3B99EE7149C57224357C8624D08CE6467B144E598701987FB460B21E53957F57CE98343A564C63FC466F7E04BBBDAA63CE79448364FF1D9C05257219D03B2D90C9C0C299026D3C0AA4845050092FC7424F1EA03716A456BB2B935A2BE5A5570B1EB467D54890493C4977300344887718BB54AA06BD890229359AE33395D7A7B08A71465297780F54CB0D2125EC1311D6BD31766470DC18810848706C0E79C8654C6C6CB35D4F62EE70541E92982BA570DBC289BE8E842A31B7E7158660744992D6506E1D1C8BB512F98015270376158228319CBB7A2411253A98CBBCA8A6D86C2710631E105C217B2AC05F813474727C1B089B3C8AB8779CE91619352D86B38C5A622C73D692814FD36800D5C009AF0BF0EB6734EEB382F70412C2469D10698071C772E62C6243CCA236C2676FB0258487430998AD99A1456D29D79977C810953B138642754C0BB993E8B9B7E3B3B7972359569C44BD6576FBFC212F78C0C33362011225D2596BFD2EC1A4B721A36259FB723C6413910219048596252225879BF301C20D305DD3BAFB2E62CCFB1C3D300B5460BA561F3C61930662F3641B763B2F5B5B2682546CBA9A15331B8AFCA63CF68B7A1FC2E49C5B4042A3A2B2148C427C9701727DCF3371BC7B13AA62878C8A358F391F02B1FD3D2AD663C4F71C36CBFE11581E1995D976CA37440DDF9C4DE2B48ED9C492730A977E017A7065CBCC811BFD155D1935122E12325732505C6C568FA67BF7968FF6836F765C242B5B9966C333EA1161A336164D72CC5767E40939590F07B537788C46265FAB1BC3078C470E98DC1B7A31CC53A83A0A7E95C4634754A069007341396371AB79F6343B601B50966C5999144CC46B6D06089A879871BD1BB9C2CBCEF84CB8FB4A031786BF778703B164F6787C5CD63AC781424F8550E1AC992A6C04BF7953787047B043632DE12698E80526C813E08F36DC1DB592F48968395817566886BB2C7D3FCADDF331273EC7ECBDBB3E5D70C823323FA8A1A15E1371534CD0462CD052685950BB6B6833600243E35C7047BB20832F09E1D854739C5B425BB32BF86029E1159D79BA70293BADAAA25385563CFB4BABDF4BBBE341058D3817E9A7941E69ADCC867559B822BF63D0034C15DE1A9371945BFACB1CACA4FAD8590F723014CF5355228D850D99C57F85C67295A4AFA0B9D8E1DA6065EE0E9E43B6D", + "sk" : "6FA78813F0808FB375E817A1AA133A3564C1BD632F43A517D7D0BC43386DF21A252C71C707C5295109A5F5B64D8D8B338B86CE24290A1857364F69750FF116FDF273CD6861FA085F0EE8333E32CAE0C4C202B6AF2BE601A62C1E78AC3330B96DFF58C2037652FE497BB9C6B544460F58D59BC63091C9DBBAD4225D4F4A2AD5936A6FA20B5EF52BE6D72B8B2C9C9AB23A4937CE834364068A6A9FEBA95C41B577BC8E70D58425466BEBB66167384D6ED37DAFD7741E05971B5509AA5C7969C908DC71670E47C45358170F12B9D2804149350663A8A9BB45454929813E7C7FEA462440AB4BEF1035277A24A9076D7D11256CE4CD024157C0F2A37111A5305459F220AA4C569D0636BA1DCBB918903EDFF43AADF5C8843A99A9031B35311522D0BA96D6514AB0BA44908749422782A66F29EA4CC916ADCE65978B6A8B1BE6B0BB930427E8AF9EF176A13593B4BB1AB1EB4E816725FA182655750A9D835A4C20470E6C646C6314C42559BB2762077B482CA069787836D8D94412D946330A66DC819B49D0A0E42393311826507AA0124C47B5D402758B40D88BAB51333F1AB1A61BD81CCC561471C239D4F2CC2AF811B93250E4624D8817539FC95E90FA7A7C344D82477D0D632283624D48103E40FC924F1C5D372560AF7B96BAB49A3DE15ABE1363E17CB9FC722E986B48ED03B0E727B126320969A56C94428BA31878C6803033689639C67E5950B55F35000F90505EE871C3BB27DF9C5253634865024201D50384671813AB1CD77AC1261B08FA9702575673D8B3B40A02530928757842979DF188B2C697406A4800E59888623365B6A3299710EB65ADDDF4B85F087A87515FE9C46332FB3E825B9B37A40D48AC1AF52886BA7742F2A528FFD046B4D72D85B49DA1FB956B11886562AFCE32C7DD3771C9C4432871762F00BD72EB5CAB4A0CB401605D18C9B66C20B492365A2520F391BE37B449866181903653C40312B9395E57496E94C5A913D5A0AA7B41DAA33E4C3BAD134569E1039A5FECBA93A3BE80221C7F5CAE6B1242CFBC6B15F33540CABA84755C2DAC7B3239B6AEFBCCC239AB170B9168E842E53308F9E737C2695A09513C1DC213E7FABC79950AA4063104120B1670B7ADE210BA6A22069441B9F1CEA4964B7621C6B842C409D1093B8ABF7A9C12A9972A7BBA867B07AF3451AF3CD6B61F58AF1D842EA8E4391DE05F41EC639B3C63A72C4E0AF51FF8D144D3654FBB2582C488241C2369DDA7BA047181535432FCBB15D58548A7E991922C5A32AC86A80725B0AAB1B3C37639E812CA9568F00B88D84B3DC4EC9580B1760301A38CE7A78850A2F7B0931C1C729481C90AA367882643A432155E472ECD1280D5C68CDA283304646DCFC13672AB9A72C039D1909650DB543DC15BF8B2A94E68858C41C17F2C718977BB0A10A34BB093FB318650CC8AF102C1EA138A73E392BD8100F66B287D2A0E5BDC6B63B92DB44AA2A42251E6276079C1A53E896764C201077C1E052995EA609B9948CD04E175A3218A25288009B44B9A72CBE37BAC0801821F5575A2C54BB367530CB1367D36978A8AC6ECBC718107318AC28C5F18426489536C22359004A478799FC50A21BAF28DD269C34C218395C2A06AB07559157142C46ECF7517DFA9192B0C08E8A2524B46C7543753708B726ECBBECECA5218849F6B0142B9D45AFDA4C9A68BA91F6264E4D6A4649AA66AA6165120C4F57B3CE81A3833978AEBF52FFB536F61B74A25107E8ED440504C546F1941AC762D42F0A10C890DCBB79B35D93BB85195C8C58D9B27A934FC7466631A5451939D61B009CC054A90C143636B3AA76FBADB37DDDC5AFC231CC68320940098FCEC220D26114FB88B3E10CDB3A98B5DF06D2259911D340D27798B27108B2959C5734432A5F45298D4C9BE20CE912C199CEB1F53C309047A3100C5400CEBBA5D6C6E4BA7AE707C38CDC7782254B280B1C8DCB85726579842674A7D6061185556CE3C841FCC4927264712645B6369C30FC388D6899480490E9F223E7435A3BA055B96179C4E625EEBE824CA0498A2646749D04340C28EDB1077CBCC871AB64A2C23B14FDC1A45B063ECD263AB49936D325CBDD7A80D171DE2E6156445655629BD64AC08963824ABC09014B497ED50AF28B1B62B6C9D35515A0393341DDC9FFCC42E1ADA20B880B35F49A312180F66B866C4952D92F2BF38B08F6110850224909413938678C8F9585A0741B561A36B7680644947485B2462D984AE5EA115FD52202643014607067B9540457A3405E7127E841D004B86C094468A0743B82BC70569C3388338E0DBC6ABD1456CA3AFC4564EE9D361CA0A708E417AACA1AF12151D5FC93DB4B652EB990A0335C799A27B713172B6949BE937B570384F3627102DD2BD784C97D46C8A2FF2A1D2A0C438F0281CF29971E3C58DF77C33B83B5252CF0E72C4FB9448ACA6A3ABB06A22677C0206609598C544781598FA318BD58DA2625CCAF7AE759B774147380F0304163B0786A9203A1169D943B54B9B92F7BC7BE5FB17E87A37DFE73712C33FC0824AB448A9B2295A7364629956CAC2CB6ED54AC085BC3693FBCD9CF7B44D4B318E248AD737AA1B821FA985BF7F219828B1CABFE66DEB269A6BE49DC3F74AF594C820748FCA60961FB04F22AC2CD4787B5A41A91195B8588B3A74A1A188F95E50AB047CF42FD5B63FB88BA57DD24528F90C2F966A1CC91CE39BA848FBB2EC4576DF188350F587E59B0AC0848D71A93CFDA63E3EF93745C6516CBB69A5505B1F900AA4F91094306C84F640050393F1C751A05872AA7B027F678B1AA2CD5F97CA25806A53016EAE4412A7F23EBD8A7359E5A706A11415951AE2A45D60FC999B66A255CAB76EF85601B2974C462EC4202F83B2BA85190AEC7C6FD6263D72E19F7EF71B6FD37694EC1E56090290549D002C2DA8B18BEAB345F969BF1B23144486C299104DC7DC367265902469C45D7788C5D23941C6A1608A12586692EB759EB4835C537429EF287B6709B87DC22653D7A92CC314A295A6A6C939E33B3A87394CC40CB284B17987A088FFFC3F401C2B072CB72B467D59F930D82101AC725C79D54FBA036AAD5760A615CD5FA1A323A87FB63A4472228F124A3EF72A086AC74245CAC6B7784249D17C7A19A126B28C7530C1EBD6A806097DE35177A5070ABE84BBE3B99EE7149C57224357C8624D08CE6467B144E598701987FB460B21E53957F57CE98343A564C63FC466F7E04BBBDAA63CE79448364FF1D9C05257219D03B2D90C9C0C299026D3C0AA4845050092FC7424F1EA03716A456BB2B935A2BE5A5570B1EB467D54890493C4977300344887718BB54AA06BD890229359AE33395D7A7B08A71465297780F54CB0D2125EC1311D6BD31766470DC18810848706C0E79C8654C6C6CB35D4F62EE70541E92982BA570DBC289BE8E842A31B7E7158660744992D6506E1D1C8BB512F98015270376158228319CBB7A2411253A98CBBCA8A6D86C2710631E105C217B2AC05F813474727C1B089B3C8AB8779CE91619352D86B38C5A622C73D692814FD36800D5C009AF0BF0EB6734EEB382F70412C2469D10698071C772E62C6243CCA236C2676FB0258487430998AD99A1456D29D79977C810953B138642754C0BB993E8B9B7E3B3B7972359569C44BD6576FBFC212F78C0C33362011225D2596BFD2EC1A4B721A36259FB723C6413910219048596252225879BF301C20D305DD3BAFB2E62CCFB1C3D300B5460BA561F3C61930662F3641B763B2F5B5B2682546CBA9A15331B8AFCA63CF68B7A1FC2E49C5B4042A3A2B2148C427C9701727DCF3371BC7B13AA62878C8A358F391F02B1FD3D2AD663C4F71C36CBFE11581E1995D976CA37440DDF9C4DE2B48ED9C492730A977E017A7065CBCC811BFD155D1935122E12325732505C6C568FA67BF7968FF6836F765C242B5B9966C333EA1161A336164D72CC5767E40939590F07B537788C46265FAB1BC3078C470E98DC1B7A31CC53A83A0A7E95C4634754A069007341396371AB79F6343B601B50966C5999144CC46B6D06089A879871BD1BB9C2CBCEF84CB8FB4A031786BF778703B164F6787C5CD63AC781424F8550E1AC992A6C04BF7953787047B043632DE12698E80526C813E08F36DC1DB592F48968395817566886BB2C7D3FCADDF331273EC7ECBDBB3E5D70C823323FA8A1A15E1371534CD0462CD052685950BB6B6833600243E35C7047BB20832F09E1D854739C5B425BB32BF86029E1159D79BA70293BADAAA25385563CFB4BABDF4BBBE341058D3817E9A7941E69ADCC867559B822BF63D0034C15DE1A9371945BFACB1CACA4FAD8590F723014CF5355228D850D99C57F85C67295A4AFA0B9D8E1DA6065EE0E9E43B6DA97AB878370142B7B2B346179050EFF0A4153943BE66D9CE47C6772362BA795BF7642088944D664CA7996BA944EFF7E4ABD0B900D3D1728D99A9F722F928FEDD", + "ek" : "7959ACAFD7335B868D0DB158329F775BEA8FDD79B4B5F8091A7D5AF40059F5521CFCA272C94E9C8279DB517B10BBF8D5CC945232B59621DE91DCF8DA130F8F4FFA039CEF6B8D0DCBEE96DF8C96772A546C2933E25B45813F795A6B8A43AAC03F519D6D9F09776C6D19367B1EA287CCFBA57FDDB76FEF7BD3FF027D37E80688DC353F6C9D1CE90D23B9FC1B6C95FFBB197ECBA5795B7E00317FDAEAD00B3C21582DC0ED91B3EA6BCFCCEB1A65DC49242772F13C23EB674EACD1CD00827229EEC6EB17848541AF285AFDB73251B866B1F655EB6E0D050FFE0E483718ADA1CB73EA53652DE8D33CB65202330A5A506F6EBB06A8F3BA31B12A1109D2D669CCC5416311CE248E77FDF7A96FDA174ACCF8A302129E709B46BD3A00BD73CFC2B62FD09367749C9FFCC0FC461B9AA3491D895DD3DBBCDDD5E10CD6B0CA6BFA6B4CF6FA3CB22F1E3FBD6B6706C08BE31D649A9D9E68812E1B78BB825305273A361966A496ED56FA72556C5F75ED798B887759E3F3FC7D33002C7EAF707E9534135959FED28A8871E701A6F78441AB2A24F920B714D2F421035C1F7A94E0BB9A1A5D28E9A0C1540FE4C6E69016014659E72DF5F0405C6A740E885C80ED71C0420F5787906929ECEE8AF0671201E3F7EE58B86456540882BFC522FBC01A6E9BC6E4C21DE8AD7D2C3CFEE685306ABC3BE613A1A99C0ABAB27993795170AC9AF72D5DE3FF71D685C71FA63D9C59DFDEAB770FE2BB2EB8578BBDEFD24A45A9E3E6E4103E33F7F28279569CF94FF995A0155C5DD09336C0A5C63C867F4DC61EB92BCBA9DC3E16D11C3EFD4318588DC126B1D7C1FD915CF2595D63EF98946C8CCBD4A64D52D4F76684DB14CEE650B84F286F64FCFD8D58CD10852BDDEC4C94D86D5BBAF1B9ADC27371FC093BD9E8FEFEF20D4D6C488567630637C085493C1CCF234ED8156AA8FF2EDCB9CE2187069AF8F13305739ED57E5F2442081F8ADB7C177CEFEF45D4A9E67A60926D59C56E9B15EEEF0EA504327D37AE2E13892F961B3E6076F5A73C29597351357DB78CD8E66EE1377FE60B6FF0D3A0D04A6395C3F2C6DB9ECE629B5CBA85BB77E750D5BF31EE35C73B9C46E78EAF8384001BD79B36B49B1FA2E22D4CE1BDDF5A49B471EEA41F43A4591E87AE02C2AB349425FAB83760B0F00B61B6571112D5B05075713E4926C0C5F74EC9503E5BAC4591A139CB3C737AC5A3ECD3ACA2DC4AABDFE737D9B855651B8302D80C3F36C57928BB8FB59B19EA061367924466C727CB17797BC518090D7F8862020D2113AC71544D91A42106C8D0A875DAD71A44851928AA804D0B738A27EE8ACD29CB8D5A0C7BE29053834AE02D92736B0232E1C7893BBCC62585ED049E62432563C728A57806D5C156373793FD4BB5D458FDE37E28562E8CA2C7984EF3F80D7010B85A166CE865085C9E793F276232DEA6457C49FA4A630B8ABA942DF16E18AD8BDF044D8C29E6398DE0A42692B3FAD2425F9FA2E53C4B87BA4261FB1655146F09DFBBB111B101C96980B6359BA7A4B26AC8C8736282FBD4D31A412139F3F0373C06730CEA53B1C5004106E431D89EA309B3CB67E1423121C5B5359D6775097ED690C3FC4E7B8C3088C3E3A73F5AA01F116F8A8B186B39057DE5FBF3324B517FA62A3E363F308B33C445239F93F9D3385390845848D5BFAFB721B3E33AEDA813BF9D4DD001E5FD9B5164DCBA7589EC1A86165298E8E32909E0ECE2780327F89730C292849ED6670239C44C6A4EFD4A8C02A4B0789DD9DD338A9C20CF16D5F537C787FD6995F22130C8412476ACAD2C8BC5A4C19F86C4C449DAE377E9044DCE869A1878DB06A2CF310BB4A8EAF2877D7086CBAD4B3CEA002EFE12A4D20EAB6759745D830E578516307314499CD87D99EEC97BC62B0285873B2E1356E2A9B4A05299C1F647BC8E2C87F2A3F1EF02CF206530E9F85C35C300ED3ED7675775E3BBB3489E3FBD5B82432764FB580E2E66DC645A57631300E2A254ABDB3FC8EF798BFABB72BAD40D8A52CEC8D0770E3BD7E6E68AE725F0AEA91B1CC1065ABE7671C66BBF4AE4C1B09E22D75DC0D07323DE62C201ED1B1D45B92E6C3392E387736BEDEE4B533C8C9044575C0D7DAEEDE9F3C94904CD4F40EEFF342F0897F39BEB4C5753305BA00A8EA3D781662FF2B5951D691922E5E369FC2AB156819CFDAE8149152BC790F4CFB6C44E5A48A9493E06A61FA3686E3A", + "k" : "09A3CD5EB91CD8A1746827419D8D190265F7D9C3EBF36A3C0B708C7142778778", +}, +{ + "rngSeed" : "54770EA1252EA2857D6635151194F5F520ADEA8A41E409FF498D40C271359858FE2B084D5B96BEE087B8E8F4DD4E00C5", + "pk" : "3E074AAA7AC9F7703A87B72BD0AA050574B63FD80EF56C882109C9EAB220E67041396A29D6977F9530C3628329A2E02A7850C77C73A4698145C837087F2241AE46A1B7B692FB5C81DE38846A5BAD7246B596A889EAF558D1D55BF1372057F1795B40076D53C0B81288FC9009757A9111EA26C3410D55217768378CDC94A3CB40AF38F67B1B473B15205C58D876077B2C8005BF870588DD6318AC154DBD9AAAA6D48D1DC05118739FCC7C12327A68F8B5369A846B6AAC56FD1043C5CA8675752C12549840D47B6563C703723D6B8791BDF14E0011C0605136A1521265C13874B9BA6064B85EA895180C634168774AA55E2DF34EBD8132BAC959DBA90FFA656E7C61677D3B801EF3604814AC36D31657BCB05BF20C893A4A2D50644902133B9B16E81C1ABB2B5521408F3799152BA14D51A6A7F4A231B5167B0273B22CFC606482CC6685BBE8E80F6AAB99D7F55B50E093AA55B568C45AA3E4A0766A9228192E5E91378AF608276308905826C6A24E7413AA98F57495DC2D5ED5BD6FB5C65F4B4ED7B9C4C7B504548B0306C892F547613516A9064417B1B96A95CBCE5B502BC770356DF5AD52B98ADF01BD66175AB3747910C814E7B070205B60978AAD90C43341AC6AEE03CECF7CB8CD2B4842C3401AE1A3B60207AF366FC7F78069E39FDDA0CA53402BA455AF5EBB21EF9A6D60501D6ECB1B5297312B280AB2023F2FCC42C2D66308F263B7D019AF68144247C2DD93A05DF57DAA5A03E896A182B480F1F607EA668AEA60B66964B2A3FB609FF547DA9A51AA6848CE2A686406C7FCDB058595A807A6692F833CBE3166FFFC73A2F30523C86DB1B98EE7F477D7F1A8C7110076774D6147BB56A79ACEB6804EB982A8D00356553A68EA8E91D8B86D676F394A776353BC830043CF209DEAD22480C08D5DF25E80FB734BD6558F1B9080B09FAB642808C458CDEB0D72E5B49305AA502321711131C7F848FD14811D718BE5C805C8B254C8C556981AC8C1DAB13CBC9E91708D99688E36599F3B7A23F7AB83F2A3B613B38287B2856AEC5B4EE90C33E85B8D88CDE3870759320B4C1C0D8D727C8E379F84DA0221B2CDFEF70270299BAB0B7F9DB8C69D7C9EA6D01DF6107E04440BDCF945AF329BC016892D8C01F071654AE3B19374946246027210CF9B1760AAFB5E4A935C2D0B7C70DB3721279E6FE43D712468FED532CAD432EC30A1372554C97C3769C380C709018393364CA97F9DC37A0D393511990AABF398474965DC45AC2A37AD60163145BC3B73E7A6C2032F7D2216BC19B26B4CC55BC68ED996411BB00715473F4E0636282C203770A3BBDB26CC58AA7B4C69DCC01EE3E53AE514169859B632937CD8C355C560CEF5C091F4080047929554C94D7115393FCCC11FE397F2854564533FE9E66614DA3AFE15BE92196268720F5FCA36878797A2B045DADB2491FB3CDCFB7253F18750774D4108BD6C7C6545B801E8E368A1087E0F33C22A359907C1C75BD59DB28268DA457699337356436786B16BF6A25FC55141BCA303FAF566039991C700A227C01E6543BC173C06B9A8026FE07E032C30F5D4C86A950A3A7B32E6C67E51771D78C08CB5382BD4FA8068969926D352F7E5820AB19878197C25172E95D6AB6A05ACBBE375AB955BC777977D2B926786C9143978113C490731438EA53C0DB27BADA4BE961B38138B4C684A12D4B08B6F03AB28F6A260B01AFD348B59684197002BC534836C8B735DF139FF98C84EE03A58E02D0E6125F1E09BF7D7A91840226362A667627AE5F580EE50B594FA64892A508FF8BF80851ABDC45486936E11E26BECA14334454D66C0128663C52A8700B525950425A4CE7824B25B9E45EC6BFFF8279D1503816AC76F498F8E18B2B626B285655AB40096CEEB229856457699B500B77F7AF5C2BC8C545C4292A387583FD74DCD20C4BED85BEC8C245C63608EA302D557199D9A70194A5E92ACB24264532B02BAA8F824052379395B3B4222536164823C379782837FF417B1583238721B8B6B4A5BE982ABFD35A90D07BADE5C03C4C3170257BC0E88B41B242B146027BAA2CC72474D00427B0C79CF294203DF379628799452D3952D2AC709F20DCFE33B001022917A4678966F1D9065CAD2BB9B6979817873E8D662D7BA8343D18729291C544C00FDEAC5EAD3C8DD2CF3E2EC7899253E7F980F9AB3230EB1A9A3688F94BD522EBE016E2980D72C", + "sk" : "93D973D0A7B385A29D218666FAD6525FA2788A053B455422C2526D556B1E79A17330C18063B054F0E238EBC1BA8CB874836989C4A7C75D364118585B7DB99469D52B043243AC867B25B2B8CB9A8F6699C3D8FBCAC40423FAD90A56775C57D02107DA9DC94731A2A298DA61CAFFD12FFC119F817CB01D4C98A2F48443D6B36782BE1C25ADF882702B225F439000CCC8C3C16129F0040FB4BB1A4993470F7C20D73AB393016847A1647A3C14EA88A7095658B0B9C61C8C726FDA255D641B83F03BD1C9C3CFC20709909B1F227C89D9C7F5D51FE9FA753EE729571A3E7939AF9CDC17A0373F86A4253DFB849F70C52C336D1F34A682661B6C21C73E9A92C50BB69363A9CB3C41D55C1DA8D69607E012F5193A79D581BF8760CDD742F63003E96C6A1305AEDFB36DE84A9E5B832EB5AC2FF204397D28C8EB64A756C27D8E7B0CFEE3BA9BA2989C2310633813C9828705266C2F8569163C91E33BAA49E6A4B6B92BEF81174D24BFF6C0CC6C020EB501126ED1507EE8CBC4A7281B34C82DA47BD06851C0E52E5AD9AC27F3BE552564B7792FDF847F3CBB5283CA8F04C4B6A5E0BBDCF3C77A02C29FB847A5643CE719B276A39DDEC8A361D73A4A54BDF1757CB6C65B0D62333C562A64317F713CA2C714A2DDB1BEC986583E8B07A5F24217223AAFC711CCEBB83E7921A41625853A045CA02CB8B597332B524DCA8E15B02804101E3CC2882546864D732094E2CBB06699027727509A4A22E28B7CBBA46A30B174594C7ABB7735A47A471A245050C0AA5C6ABF020E005441766BB4741C756C588E4BB7963EF2A889E40D542B65A38A888E0511D8053AEFC6401DB4C795B718B9019C96B39458C62DA35A383738649C065FD0812EE4A0B9B809725359CE754604C4E8462D7094BEB3CCD17148E4EBCE2A799DCA2C55174C98BCD9206A0C340F8C559F6C7745D7B305B672F263643362B2FB099FC5173B43C167CC25BD8FDB7DFB7B3252162AC665BED6BB0EDAC9822745A80A463329DB5853B091F304094DC949B797B127E11CE4860793757CDAA510CC5C04F0C7575567AD1457C54C3176861C77E7F86446D410E9B3A005678577787D32741595989D9FC92FBE5B0620A11AAF94BEEB68000877CBAF39BB6BCC2BAD72975BF94FF94A56419726630CBB32114BBB412C27779BC49632FACCBADC4C3BC1A61F5D2337754B5981382E6D406828C6ACE3F73ADBA6021AA15E52EB152B222B0BF593519703B3ECB38A39ADEEA3123A2167F1C102A19BB83A76B562090E7D24C9FDF53056F35CD367431B82A7CA210521D4C78F78AD54244E97149CB2D28BF96CC36756BC4474C0BFF06AAAF3985329AF217469612B225504AFE70C69CD4467B3F277DF5A2B74B14F407A649DC76361527C0059A8C3FCA243B0C2EEC7C615F7C8A15A5D4055A301ABBFD5A5BE42A8CB7F4B0700F4575FFB719965A56AC21DFDCC19D48A8302C29CFC340FDFC391E2838F878164CC7B58355473A9AB44098AC0C0F8CF2C0B3657709E48419C3AEC2509222CB658AA1F6709D0C4BF6A077197A8A89F433ED18987072A9BBEC9A19307C51F66CDED27A2D0538ED86989040308FCB42E8C8A9BD2C5845A914C18C5C2AA5CC2BC418CCD5328C139AF2D66B63190B99C5042E7B81372772610511FCAC1449E71A6DB9B35FC1B5871A627A63900594869B20A1483A055C8BCADF3468B4E9A7CFA6C4E3230C550889A48F0A5B5EBBE64CC06110C96987CCC2343BBA708791BD9B2D5D6B028B9425841646244745B38C644342781E886AE452E3F04098E9C0B1C37C30E08328B011E0F4838A64874B1985CA1834559A07711C035E29C0159286D9473551FF65251E2C26A227E75F1293B2B86C53650A33B2E4B77B0108050F8C8CFC965771BBB8A9CA0075E09A30E81B2A4BAB1E424587AB282CA7927BFE1BF3E18775CC36A6579A3FC338DB8E090707CA42CA12981DC7956763285014577E9AF843B7CCFC631BF706A1186C6973B532FB204FB0C0645E54B7581871DB60E5B4C375DD2BD43B35865B08856166F640AC7EFA516F24885FC9216FBABBCE3D66FE9466DB3907AB224244E759D1B89C041BAC289040D125AAC681CB048D908D38513EDA6A23248A01C5B2C1B6C6296A5C612B21AD0B433BC3296F9F40B42F02973D2A4740C823E074AAA7AC9F7703A87B72BD0AA050574B63FD80EF56C882109C9EAB220E67041396A29D6977F9530C3628329A2E02A7850C77C73A4698145C837087F2241AE46A1B7B692FB5C81DE38846A5BAD7246B596A889EAF558D1D55BF1372057F1795B40076D53C0B81288FC9009757A9111EA26C3410D55217768378CDC94A3CB40AF38F67B1B473B15205C58D876077B2C8005BF870588DD6318AC154DBD9AAAA6D48D1DC05118739FCC7C12327A68F8B5369A846B6AAC56FD1043C5CA8675752C12549840D47B6563C703723D6B8791BDF14E0011C0605136A1521265C13874B9BA6064B85EA895180C634168774AA55E2DF34EBD8132BAC959DBA90FFA656E7C61677D3B801EF3604814AC36D31657BCB05BF20C893A4A2D50644902133B9B16E81C1ABB2B5521408F3799152BA14D51A6A7F4A231B5167B0273B22CFC606482CC6685BBE8E80F6AAB99D7F55B50E093AA55B568C45AA3E4A0766A9228192E5E91378AF608276308905826C6A24E7413AA98F57495DC2D5ED5BD6FB5C65F4B4ED7B9C4C7B504548B0306C892F547613516A9064417B1B96A95CBCE5B502BC770356DF5AD52B98ADF01BD66175AB3747910C814E7B070205B60978AAD90C43341AC6AEE03CECF7CB8CD2B4842C3401AE1A3B60207AF366FC7F78069E39FDDA0CA53402BA455AF5EBB21EF9A6D60501D6ECB1B5297312B280AB2023F2FCC42C2D66308F263B7D019AF68144247C2DD93A05DF57DAA5A03E896A182B480F1F607EA668AEA60B66964B2A3FB609FF547DA9A51AA6848CE2A686406C7FCDB058595A807A6692F833CBE3166FFFC73A2F30523C86DB1B98EE7F477D7F1A8C7110076774D6147BB56A79ACEB6804EB982A8D00356553A68EA8E91D8B86D676F394A776353BC830043CF209DEAD22480C08D5DF25E80FB734BD6558F1B9080B09FAB642808C458CDEB0D72E5B49305AA502321711131C7F848FD14811D718BE5C805C8B254C8C556981AC8C1DAB13CBC9E91708D99688E36599F3B7A23F7AB83F2A3B613B38287B2856AEC5B4EE90C33E85B8D88CDE3870759320B4C1C0D8D727C8E379F84DA0221B2CDFEF70270299BAB0B7F9DB8C69D7C9EA6D01DF6107E04440BDCF945AF329BC016892D8C01F071654AE3B19374946246027210CF9B1760AAFB5E4A935C2D0B7C70DB3721279E6FE43D712468FED532CAD432EC30A1372554C97C3769C380C709018393364CA97F9DC37A0D393511990AABF398474965DC45AC2A37AD60163145BC3B73E7A6C2032F7D2216BC19B26B4CC55BC68ED996411BB00715473F4E0636282C203770A3BBDB26CC58AA7B4C69DCC01EE3E53AE514169859B632937CD8C355C560CEF5C091F4080047929554C94D7115393FCCC11FE397F2854564533FE9E66614DA3AFE15BE92196268720F5FCA36878797A2B045DADB2491FB3CDCFB7253F18750774D4108BD6C7C6545B801E8E368A1087E0F33C22A359907C1C75BD59DB28268DA457699337356436786B16BF6A25FC55141BCA303FAF566039991C700A227C01E6543BC173C06B9A8026FE07E032C30F5D4C86A950A3A7B32E6C67E51771D78C08CB5382BD4FA8068969926D352F7E5820AB19878197C25172E95D6AB6A05ACBBE375AB955BC777977D2B926786C9143978113C490731438EA53C0DB27BADA4BE961B38138B4C684A12D4B08B6F03AB28F6A260B01AFD348B59684197002BC534836C8B735DF139FF98C84EE03A58E02D0E6125F1E09BF7D7A91840226362A667627AE5F580EE50B594FA64892A508FF8BF80851ABDC45486936E11E26BECA14334454D66C0128663C52A8700B525950425A4CE7824B25B9E45EC6BFFF8279D1503816AC76F498F8E18B2B626B285655AB40096CEEB229856457699B500B77F7AF5C2BC8C545C4292A387583FD74DCD20C4BED85BEC8C245C63608EA302D557199D9A70194A5E92ACB24264532B02BAA8F824052379395B3B4222536164823C379782837FF417B1583238721B8B6B4A5BE982ABFD35A90D07BADE5C03C4C3170257BC0E88B41B242B146027BAA2CC72474D00427B0C79CF294203DF379628799452D3952D2AC709F20DCFE33B001022917A4678966F1D9065CAD2BB9B6979817873E8D662D7BA8343D18729291C544C00FDEAC5EAD3C8DD2CF3E2EC7899253E7F980F9AB3230EB1A9A3688F94BD522EBE016E2980D72C13035E253575FCAE389887037CDBFF8EA508FF9E5337E2FB607919747CC53DF855F35361778BC0A53EA94003FCC0252D8333C58152482AF1E9C9D2BDF12F377F", + "ek" : "855B0B440EEE65382F3FF97FD9E299950FCB846F5B3690CB0A9E47CEEC009FA1191E670EFCC15325950C5BCAD4E6FC6B92C0050328C96BC8DBEC63C658ECBE0DCFED89029CD72DF0835D0B24B83978058FAB383D5F2842C999C6F2C1A9B19AE52238FCFC776354A70B94812FE5555B0E40C6F9E3F98E116E83E8F5CAED9ECF31A21349DA8726CD143EB40EAC3B5084D42B0C90B2AC20C06A8D3A2B3DC6E25CE8B1C11E834C4246E6A2709DFA5028D1B6F134F4B123D852BFE9A13E226940A14A9185E00FB33CAC65F2D76AA690BCE81A52CD0A35C64A72BBE2F1E246FEB6CAA99B62B1BEFDFD727CA82DB3D9E0FA670397718B9E08D52B8B455DD1A2DCB4655470FF5142F4AF19BFBFD80B726D8F327B8278BABB966D539873D670E05BC8C6D616FA8CFF0792ED8775F694A25F9109B40897CD971698A658824035573A7220BE00F7145BF76EB78ABB334A96C175852E299A39739CA848D1BAA5C50BC9C367903B33B6906674CA4E4D3B9717BB1842D5B07C8BA73B934760450B933075205753E1BF610C0474457FC660D2F748452955A68E3E9ED518BB454AAC63E19C99434F7BEFE1C773321634AB227BA1249F5AE139C7B8A549D063CDB20166FA6DF53E55AA2B4F9A213C1CD9B02BAFDA7658BE9160C773778B137A0F37479878EA7561ED43D8A6768F3B3B90B45C3534B977A06FA30B9A1676E7B07B80C4D08CE64E17B7D1893AB6BD6ACBF348BD2F98DEC712A4F266308FAEF4B49A7A5A5434A133CA4DEA4B6C6197FCDD997BCE542FFB8A24705519C99C414079D7755CA5AA5BEB5E8FC75ACAC6CC7D52BC9B8A21DF933CEF7A156D5556C500E514788B04569530E370FF3E591B88B89F88E06C97D49AB2D37013C49C4101BE78F33D452ED11D5D4ED73C873A09840C1B7C65516B20D55893A5A9DFFD8DDA51664D9B98E9D2315317B65F39A42DC04A26F5D3D3C30FA708553C76D4E135717D4B37BC58DC982597C2B83C01136E93D5583EC0CEBA9C044C32562620351A3F4408714A1486C816A32A5BD09589AAD6D5E7D61911097132C8C5A9C54F380CDDDA4E81CF3E05EC5618BB1F082ABF52EEC290F8C88CCDBF681462326CB129CCE615E7FA795981FF982BE8FC70565E5188BA03D6F866A7A6F76E0CADF22CA96B0DDC6E4A2239EDA5983299EB8301961CE8FDCC58EFC17A48CDF2CFBFB83A8A8775007E5B981CF5C9BD7745CCFF28CF7646C78DBE7882E0BD11F9CAC0A34CDCF1D5582E90E48138EE69E0D31ADF223B3C328994E956DA2BE85FBBFAE8D30B14D2CA0EB30AB98EB361612FAB3F351FF8A4E578B3B4951116E56841B7D7F51263B26E194D57BE9FFC60A6936CC5C6DCE842B6E26BD345D2156BE83B47C7B64375DD1BC00BC9E5FD049425AE2496C51A9A0D2A687CEA1C83139056DC7763AC5414C600FBD7918C20D36E20EAA5CD029DF029FD6ACC4931DC6809A534D451B25838550B28A2B5781819839D83DABE84A75D0D3922E6A7BA3098BAA03348A2824A5165A432BE9614311243FB146F4E667F63A7F0C035F14EB4DECB236D6646654759B702C5C66733FB92FBB7EB40239D37911F29FB9D190436130612719FB930D35B2F71B5D970EFFF323AA99256082742794573E9A20CB7ECFA8CCE143832ADBFA4F38610832CD5D80DD8B38FD645265FCE721D549E3E27154AE22759410750C5959143351262558A1220169F400899AC9EE7748B57824CD0289FBF639544C34C965AD206ADAD537ACCBDEB90DDFF45723F626B84431313F7A2DD1BB7D199092D2D5BC7986947578D8D0FC708D2FCB2EFDD3FE19F6E46101A9264F6E64B7DCCEF67AE008D0DBFD00FCB8D61834835A2E092DF49E995442649F4A443C869FFC7A4159FB2B85D0085720AABA9A65D5A1731AE8C0C8DAF825A52896968E29142D797701463EA1DC34372A857BD10B7D604B3FD5E0F326CB37FE89056B7B71FD85FD8154D252611D1B8F239A9225E7B4C88E81405284ED7F740419B1DF5592CA5B8C1BB3B603A3A5AA95A6A5E6517DE5B4FCB615B7AAB580F0DC2C9FD879594BF4DDFA0AE507CB93FA143D188F37155ECC83E650F864997542271D11A9F3FBD1956868695F90FF9011E65B23D4D60D8FBAA1DFEBEEFE31B96340608C7F114A5D0E73615DCF9849D4CEFED6DFD2452C1C6BCB4AAC7A5C676527FFA6F2F2CC02196A1DA7CD2223C5BAA83DC7470B4AF6069", + "k" : "EB630A59947E0DF21E174D403744ECDB41F6EEFF7F83A62CE7412BA6099885C7", +}, +{ + "rngSeed" : "CD6CFE94E9C0A1CC4FFDCD2D7876504BE5F50F1D1CA5CF93482943465B268276056F2781F4DE805C138976CA72621387", + "pk" : "10489B6E431F18744974E86C075394189349B00B1FFD5CAC6072CC10217B0E3203E3F61E1D9281C2D208AF83A7F071BA78546E273271AC1CC01A320F35E845F10C59BB8C97E1627603E51A06E532EE716EB83519C80A4833C7AB45E6951137C0F731964ED2197B033E17BCB5237A1128179A85D24F730A6B31EA0E52075AE2198B48106AD0E1225701313AF1A7B675347BC0CA48D88C4FF054EDCB1092E87CCF070E10DC093BCC9BD400490250B7DCA3775B715F218448CAA01A8D8C8C6577CC9F21A7E3E6208B2C42215794954AAC57712A3845523C74960B57A97E0C310CF7B8798192EB9507FE65020F706BE129774F10794F2296ABD13587A78456B083A164BF23C801969A57591062D22BAB23B61E7DD5B31BD54520F4080A4C6C01C6603F4B4B1AABB99681BE0B9C671F496F8CBA2A571502E0DA35FFA9BD2C77A5E66809E4D54000B851B2226E23C1072253826F374842DA312FF0931B7A85E6186F5E6A31276A2D40A81FBE135E2C86C328B896F07C2269F983B313CD92578882A321F0031FCB9A9E7D618FD3D543E34ABCDDDB98D4C4585CBCB67789283C442F8C5CC914427FB1A53F3E35B78C2110BA956DEFA035084C53CC9B6FA7946E11840087E8194DB6607246C7B314CE7644B8E522CF494A6333DBCC23DA197CEA95C318797EF0A18C84BAFBE968DF375FD0C9981757AA8C878658722BFC2684E012AF3B30A067AC996315B0CFB13EC45220C9447AD4374C78484AC652921328214CA33466F6024ABB7A78CBB528C44A339638EEF09D3EE370D3A1746053629E7A37EB2600F2F73EB9D572030598042315B093C0082456FAB06CA2A4C9BBD4C651BB297B494FE7E38D5C8AA3C7CBB6F1189D4A2C02DE0ACDD0E2C7FFA22E83C63623A21DC137C00E07193BD28264EC0FEE2259FF2362EBD1C252103D93645E92E398F46935109BC0CB50C619424DB0461823D33FD8D271727554A4C86A5113A17DE7BD17B47CF04BCED6CABFA7E926993B57A6C0A693E251E3B90B7B17195FF037FD867B87109A8BE90403060CB34B32688C263EB00194391EF6C978DB4C83C8967A735895A70B6DCED06016B3737015696F1A1945110A44F022472C0FFBD049C0925AB1D68EF3F775308C2A95E99865C04B17B34D28A1254C433313C972A7F51A48696DB9D7AB71D4600C0563B36437FAC1BA6AB9AD6E89630357485DAC1485E2808DE8869AE59FC6A952890C69695424E3BB9F27AAC2199301DC6B36503699F2504AC5E35ADFE08048F9842DF3260ABC3D209A1311D65C048B58111BC7FBD6953D21B56364A51D9C2419072DECE82B9D93AEB99C3F0A5A6C3F276504C3697A7C19563ABD84068E8A39373C1375D848400C663C44E6C968C3C61FB375EED10BAA60CF6158AA7E39C99E609A8B0765E36A2FBCA515E4581A0207AC3FD5B3B7A95F193A08511109F335CD1DCCC09223129DA93AEAB93EBF397BB073BD6374634675B6386CAA33F71E04B1B420A2036979ACF22835FCC511186441E1F5858402AF78BA99673125CE9331B6686821AC739FE41467EC22736463AC4415DB238BDB9A32E1895E0445AEEF16B12E818F33A435AFA91F850549ED465FC026163F988582040274638EADA37DC162BB2D2839CA934BFA44ACAEC450AB4436EE78A5E658134BF80F914052BE1A605E69BA87005F4042A25569C29243157865C5BED6918DA360C4B824C7EBC8157870962737D150AC5583907C0C0F0603B1DCECA45E10467ECC3A4435355AF8254AAC26F411A37B2587F40CC023C1C497664DE5D705FBD0C103E36875B168C1C732AB364E1A4726C1D8207E1830D73721DFCB55557352A6508469EABCCCA2CA706C1DE5FAB0A7647D2CF7B05E117998173C5B3958D483491F128F01889FDF00D0B668A857479030F0C16BB753794719E4E142F0C5A1A52445DE8862CBE3377C383DEAE1817B8110E045321A16594FA7C1D1037FBCD2208158C625514F3464237D7C73B0DCC605FBA342CB6FBCBC71391577AC3781ADB39D4B1C2236A4C9579810D039C10FE556DD954D71E705C6FC9389F3BE0089697DD6703D8BB8FF08C88BF6773082A56378B52BFB30182C9AE1512AE1C2B9F99B4F3D0B20F8593BC530C585D737540972BCEA60E11441E07A9C6827031363990B383B6F42AFEBF55E5F20635BA731FA86C24D6908AED77E3A57B2138C0C83A5BC98EBD3A002C0A9C6", + "sk" : "5BC2B53498CBFBE8CAD9602F75187BD676B0B4995353374DF1C4AAC9D105B8172BADD17B6707B89CA23568F5BED5969479557CF8A0ABFA8B4913A7BAE3720FA73C705655CB39C48137D2B0878429FBF44A0297B1DC71496DE1C341290865D60B8BD34C761933B3F7CD78E42039A4377FAB7C8C82B9CFA6B0358B0783B766E3A598AFCA3AECC59D0EEC2D35A0A55210A94EB44377634A1C097635D851D022C5F15838BD299F6E1A2C7E8CB330515F595966BA717E0DA12A2DC84E16902E6B022A48C4CABD27993E5587CFB4575FDA0E67830078D01935E4B47861C893D3C59267404BB2238CA14534823A3E1C82A97047F1B32388C96F615C729FEB7500125E17881BFEB2B7425151914C5BD24B479EA33BBA133A56FB1BB155AC34AA2C15D77588AB13ED53432BD0BCEA28B79C9CBDE8E66D75E6AC227224299A3391A38BE9EC2154751729022E588B341A062F6794494B0B549B0832D011CA6D04C976D76111F85456AC9C21649106A8B58B359C943AA7722C0B737393F5C9040E0A9126DC8DED3703EE7298E1424C18C2492FA1573DE9B77EA9988EF88DB2A61221C8729F0B0C88773F8F9553CEBA7AE0D6C9AD7BA7919741FA140E0703C96034766B126A6F992BF13381366121D0205EF45A9515B5A05D8C6DCB293AE44469C8875C40813DB41A06E935C80FE24EA9E178EDEA641F48519D6A6E6B0547C4940AE1178B234BC06F07129A6C9287DABD64F151F0F2BE8BC9B988B71341C74164D430FC6BBCC4E23D36938E2A4A8EBB8B5A0D906E428089E48946B63BB2525954323421FCD76BB00245EC4761C5FB3EE5F255EBFA33F64584F6DC971189A07BB19479F99247C11B3318076C2C9C08457E35AA25973A31E1F0A82355916D5891F193B0C45BB1D496091D7A47A33A83A5F34EBDD9B8935601ABD60768FA5C2FF2BBF2457ABA1523A3007E09B90A400A0C8B23BEAE5B48D6E9C642D985376A09B8CA6DDFB493EE37A0F6551F9C9208229A36CFF883C09B5239A55680967648116010645450DA2175EC5E4A452C982AB3CED778A802644945678DC514DAA144EFC4B53A153D6737A6DC3515C4744E39C61F9FA8522F39384738C99FAA3A7CDB779B9A7B75A5603AC55BF13620B647692F40594E144C378A3B5041AC1C63034198976BF9492B7393DE8455C284B1D3B2B773C448539BB493A9A8F1FC39045917F40A8CF2A052008626423328417478856C1CB67C36A34507EBF38EEC630AE5A73F7998344CF7BE33268FD99492D895AAADF5164DF7429AF1816E516F2717A0F6D0858B3A0119AAA1CC041EB5172D465184FF312E23F766AD29746E78AFF74ABD65A2AF2A0CA0B65CBC1F1A9B8544446C28C010DA1DFFB708D842BC82014CCEEA6784A35D74510503E8A8AFB7985684253F000BB2C95524C0827401AE9B058BC65896CFE43B9ACB3A00A475614136930BCBF0AC993E61236C24123105A6A70058A8D49A11931875F48F69A074D1757876F598A4A665AE6278A8E27D1591849857C42FD2A75DD4096359C4CEE2A42620B62AB641DA1BBC1FF4ACDF2220FD0751CC8A3789C06500765C632A32BFE88D0F9BCBB9303EB1F6CAE94A45D5F537C7EB7205D81C65863216F571D3BABAC57A6520A30A76F4950628CD46B88AB8F4C88FB33DFDB13089D85BDC7550647B257DAC3C6484CF0E881B83F241B5D869B5076148607718E43EF56572A3ABA527595C25D541EE1477F50773CC433D573B8C1599295B01B321C7AAC1F001C65BAA0D63650FC8C45F7312D1A7700FA1BF92092768C406934A8BB3C94951F17FDE83804F2608D292999F53872B167D2C4C17CFACCC9FF37FF7542E6D097BFA414EDE2453F2328408F0580AEAA7E67116CD895594452458675D93C03177C31BCFB57CD173006548966BBB6CC628C446576E9EEB602810A04FB126B37C45A6E4041DF38330812FA517117400AE7F429AB1A610D9D09E9ED36CEE0401D09A0D847B3DD2F826EEE3C841B4526280225D106EEB183C816A6B8387277E588712279CEE18C34D3162878204D4506F659047A9E126DFC756D946892D991B4BD406C83CB013FA8A9E7758AAC12C0F0BB6C014A048D5457309A125AAB0759AAC0BDC347DBC7EB572386D71569198C6F0A6C213C44A14A22AB40A7F34D1AC821972710B8C10489B6E431F18744974E86C075394189349B00B1FFD5CAC6072CC10217B0E3203E3F61E1D9281C2D208AF83A7F071BA78546E273271AC1CC01A320F35E845F10C59BB8C97E1627603E51A06E532EE716EB83519C80A4833C7AB45E6951137C0F731964ED2197B033E17BCB5237A1128179A85D24F730A6B31EA0E52075AE2198B48106AD0E1225701313AF1A7B675347BC0CA48D88C4FF054EDCB1092E87CCF070E10DC093BCC9BD400490250B7DCA3775B715F218448CAA01A8D8C8C6577CC9F21A7E3E6208B2C42215794954AAC57712A3845523C74960B57A97E0C310CF7B8798192EB9507FE65020F706BE129774F10794F2296ABD13587A78456B083A164BF23C801969A57591062D22BAB23B61E7DD5B31BD54520F4080A4C6C01C6603F4B4B1AABB99681BE0B9C671F496F8CBA2A571502E0DA35FFA9BD2C77A5E66809E4D54000B851B2226E23C1072253826F374842DA312FF0931B7A85E6186F5E6A31276A2D40A81FBE135E2C86C328B896F07C2269F983B313CD92578882A321F0031FCB9A9E7D618FD3D543E34ABCDDDB98D4C4585CBCB67789283C442F8C5CC914427FB1A53F3E35B78C2110BA956DEFA035084C53CC9B6FA7946E11840087E8194DB6607246C7B314CE7644B8E522CF494A6333DBCC23DA197CEA95C318797EF0A18C84BAFBE968DF375FD0C9981757AA8C878658722BFC2684E012AF3B30A067AC996315B0CFB13EC45220C9447AD4374C78484AC652921328214CA33466F6024ABB7A78CBB528C44A339638EEF09D3EE370D3A1746053629E7A37EB2600F2F73EB9D572030598042315B093C0082456FAB06CA2A4C9BBD4C651BB297B494FE7E38D5C8AA3C7CBB6F1189D4A2C02DE0ACDD0E2C7FFA22E83C63623A21DC137C00E07193BD28264EC0FEE2259FF2362EBD1C252103D93645E92E398F46935109BC0CB50C619424DB0461823D33FD8D271727554A4C86A5113A17DE7BD17B47CF04BCED6CABFA7E926993B57A6C0A693E251E3B90B7B17195FF037FD867B87109A8BE90403060CB34B32688C263EB00194391EF6C978DB4C83C8967A735895A70B6DCED06016B3737015696F1A1945110A44F022472C0FFBD049C0925AB1D68EF3F775308C2A95E99865C04B17B34D28A1254C433313C972A7F51A48696DB9D7AB71D4600C0563B36437FAC1BA6AB9AD6E89630357485DAC1485E2808DE8869AE59FC6A952890C69695424E3BB9F27AAC2199301DC6B36503699F2504AC5E35ADFE08048F9842DF3260ABC3D209A1311D65C048B58111BC7FBD6953D21B56364A51D9C2419072DECE82B9D93AEB99C3F0A5A6C3F276504C3697A7C19563ABD84068E8A39373C1375D848400C663C44E6C968C3C61FB375EED10BAA60CF6158AA7E39C99E609A8B0765E36A2FBCA515E4581A0207AC3FD5B3B7A95F193A08511109F335CD1DCCC09223129DA93AEAB93EBF397BB073BD6374634675B6386CAA33F71E04B1B420A2036979ACF22835FCC511186441E1F5858402AF78BA99673125CE9331B6686821AC739FE41467EC22736463AC4415DB238BDB9A32E1895E0445AEEF16B12E818F33A435AFA91F850549ED465FC026163F988582040274638EADA37DC162BB2D2839CA934BFA44ACAEC450AB4436EE78A5E658134BF80F914052BE1A605E69BA87005F4042A25569C29243157865C5BED6918DA360C4B824C7EBC8157870962737D150AC5583907C0C0F0603B1DCECA45E10467ECC3A4435355AF8254AAC26F411A37B2587F40CC023C1C497664DE5D705FBD0C103E36875B168C1C732AB364E1A4726C1D8207E1830D73721DFCB55557352A6508469EABCCCA2CA706C1DE5FAB0A7647D2CF7B05E117998173C5B3958D483491F128F01889FDF00D0B668A857479030F0C16BB753794719E4E142F0C5A1A52445DE8862CBE3377C383DEAE1817B8110E045321A16594FA7C1D1037FBCD2208158C625514F3464237D7C73B0DCC605FBA342CB6FBCBC71391577AC3781ADB39D4B1C2236A4C9579810D039C10FE556DD954D71E705C6FC9389F3BE0089697DD6703D8BB8FF08C88BF6773082A56378B52BFB30182C9AE1512AE1C2B9F99B4F3D0B20F8593BC530C585D737540972BCEA60E11441E07A9C6827031363990B383B6F42AFEBF55E5F20635BA731FA86C24D6908AED77E3A57B2138C0C83A5BC98EBD3A002C0A9C60409F3DFEBC62EDA14A11B1C03D59D46382C2C2A579009C0355DA8A58440C49AB2638686DB9A0292ADC26E549C7152FF36D9A7293BF1380BF93F1498546EB93B", + "ek" : "29E0476841E1F0672F2CEAD8859E8FAB116B37E70DCF7A012B27E9E26DCAEC8C0A8686DC3BBD18069C284A5DC20725C3CD5C0CEB5E3814749F39E1945F8F5FA94B585B2DE80B2D4E64ABCFF14A1B1E78CF66481E8D6DF1E39A9B3F718762393F2BEC7E232E52CB4079FF7579D0EE7D54B3472F1A58E2397FDBDE23C326F8C17CF26FDC333C0F61D86FCD1DFE843AA6B84BCF3E8707BEF2923AEC023AF376B66FED7C9C38DC6D7CE60E0C6F49742969F78017612F26A4409A42FA5DC2FA7E75D14C8E57CB3E71315D6E604B9A906E5F5DC51DB3A98C19AFE4B771FE4FDD72E618B1717B5A38FC355CE9D1F13CF04E1C36E5D5F36B2076637033042BB48AD331C2844EB5B136882F124F0FC94FFBC531C01208D7F5E1E11C13CF1BC431BAF2EFCF77A4A5706B0B1DD885AB4416849E0EB9897A7D665100E86C0E8B66E37574EABFA9FDD223363B2431565DA85BDC8893992F1CBF4C1CEB1A2F1932B0A8CFEEF87A97B2315D8A7568EA467F276FB90856116AD6DB793C1C5325F1E51E971B27A26D875AF80BB510F6C6118AC9FA36A031373801610869C2FE846417295EF814BF22DD48E63F04CB45E9EDC53B9B63A90E7931BC5FA0AD5BFBA331551DD1AF5440DC49E647BE051457B904B6667E3FC05F4F04478D2C58C0344E86E50CAE51DC2AAB85E117E6034F03FCF75087A04F503F5316AD29133BDE2DB0FB73ECA4E99557B232A03DD08047A2C416272FC053FDDE6B9A23EA11A900E5656AF604FA3905ACBE855C6811677E286B61994EF63572A88E95131FE4BC7A192BA50CFB1E462B38AB204B7A653F539CB8DC33A5D167331C0567C46D5AF1954A2C96F9E16E4CD5203D8A3FC3A0EBB69077347EBB8BF90344DC9E0596AA79CC583B868FF0A2AB8328F3E3EC029CCBD79AAC6E15362DDF29B0FB54A6F7F3F14885639687AEB512E4B9E23DA79FC482C858525A0CE079DEB44F11F5FB977EDFA8638A4ECC66623AB515CFAA2ED07E9CE03C0876E905D73DC9E26EC48C35021EF8406C75327EF30E402D19C3DC72E2837C31AEABEF74A782E8C70DEA92E0A79471B35A285A9863146E649E15A25F5AD8500D2542315DB5106E9BC1B2C30AE3034078DEF3E64412F1B5783D30638EBFAA0E3ECDD05FD917446DE1C1CFAA3416272C0D1CBEE24274136DC7F2B8E70368D053FF9E71D652B16A650A48469A038FA8A9CACEEC91F93001042A0F9D629B7C582B66EEA49115FCB0A02CCB96866236E5144A83A77880B0EA3E01CBD3E6179C97F2D6C9D8C8FB1F58B34C9B07F4450B956128982ED68F9F7C293A67218FA4946FBD9CFB07EFDE025252C941B92A3A932881D630252857714374A19D7432F1AF56D463FE0A69790F1F5DA5DF446574639EB6190ABFBB0526CDDEAC4A45D823AD38BD3B052CD44728A11118B3D1C3BEC49C986969479EE6EFB4298E72634936AD2E8A074663DF58583A883DBCC529157DD45EE0167FB77FB25144E76898D8688DBEF28D42CD984B320C668BE72D0046B0DB485BFBE9B898B1187F26F22725918034F2E9672763AC8657093144393BA760879C177B3BB952548B9B9E59A492EAAFA5E69E5267D0043A1E931FD8DFC2502521C4B9A950C452FC70999E2D2FB26D9BB7DC45368AB5B831B166D2501FD8B4A0E630F81C8987A343190820D8461A541A07849A5B0452176214C3D0F331C5A869FCA8B6AD7A623775DED7BAA6AE137A33CAB9611FF5BF3B474D51A26F7999AD24BED5B2F4C414AA97D8B3032D79A01F4D38CF2857A4325B438D601B6F214C66C6D4790FF0C8FA8FB16C50A998F142960F38DCF7BDCEBC234857C5C654EC563B2E86538ACD1CCB64756A45A3AD8BA1EA04EEAF1659C9665FA284D3444139788A335B964EA7815FC722F210BE2971B13224F218E491028D2F14A98B475DE02598402B74B63D486A0EE8404C740EDC63F40612C301E3AA83DFA0F5F04819D3A4FA5C77F48F25D971486B5FE552AE9F5FD6330C3433B273AFCD6354FB9F04F6B36D418C59D7A31C5CE4CD355B6B8D79F6927276B33A7D857B31AC5289098661DED5FE3E66E30FBE6ED08CC30A391DF8C69DDD62FC79B4BD2351973EB62B9D5D7B9890309461D736CACB7E5BB1E91264354A154AEAED3192C150E6AB26C1A534893122D8896E9314E34CA9C1F70056C9AEB608AF510EB1207A5565D3EC2F95470E711926ED170CDB32F73235F95CFA", + "k" : "C2BAF01B955D02594A41D1C1A9B6B39E7B04A8523886F3793EAFF68BFF970559", +}, +{ + "rngSeed" : "265EB2DE7099E4BD5614E5DE7F0C2A05C78EF3E8E2DD4AE4CB70F3E5E59C8D1D88248303F07DE0C5508652DA66B47222", + "pk" : "0DC34B0FC991BEA47B02A8CAE2F81A10043EC8D655124B3ED56505296C5AA2227CE2AC04A0A31CA05575B2E55C01119D6588CFB529AA54E707155BB4F9A63966D9566BB65A95287591F715E6BC0D7FD1691129999552B1771B35A322C5145C7A40D79D6D9C3EADF941112C4F76D678CB0AAB59B9A30BBB340E078BC2899951691F9BF84189A87F2AF590F881027A489EA1BB89E3A8B65959AD503A5E051C5F398A654C708F9EA51BF75C6BFC25634145076A93AA6E6640E6B47158ECAEB621C606C065972C9F26A34736067161E6BD49FA2871631AEE5B518DDAB90F692929D5A7A6E76582E53DCD36ACECB6A76DD9455358BA95EB8A70D3786C01960B367E15536B456408E4FACCAAA139C8E9737AD6B8B0E380BBAC446C73B7B388B319DC2047FB7338072A0F225B506253AFA722C812419E9C739C90BEED97BA8F684111900E7D1762A5C0903C390786E1445B615A1E054EFB7B0B1DAAAB671A63CAE7B55C8B6F13F10D55707650EA8D864C7E5217B572643E6C7480411489C9AB18400483A657185990BAB58B6A734596A6123DFE5240B2F908FC8C3591490F89875E0AD3B06F6812EA973E6FB0A69886199B3B55B7D26A55501B43609B3D6A3981CAB946049C10B5737DACCFB2040E014A5F715B4C1F8B0406B3A3204602182450D10B019B388BFE31B5A5A9794B5863BCB34CF6F659B25CC95F0A42FA9305A0D647342845D5B28FF5C1727975BB48C5AD2C96B97DDC3BD4F0B40E9B6FE1138739F1A9CA3B969CF33CCB700FA9FBA93EF565A8AA180CC3711974BDA14AB85E3817EF4801C0C3B3F68403BC94CC7412AD044A220750B6CA963E3E052F310BB1474623F707157C8A7D67F95989492278CA5707EA6D106431FA5A3B88C39E3E360BC0288925932D44A2523B0980A221519CEAA65353A7483B7DE6028744A2869BBC869A58BED2327B3C6A4AA7447A9A09BBBAF322D5914DC9D5A1EF8AAC92B920524C6968289D7DA06DB2561EEEA26FB764168C185EC20CCF2B57A89F2887720809E94C377B313CD5EBB7F71037BBF01BF85B675432B891850316F6B938231793AA3AAB2972E979C7AA258735858434B6386CF0C5A9232F60A70624B4CBE9F10FC9E3A0D7605BCAA23AB49A222F66127A1A4B9F2BADA03C8DCF330E1DD90131852B71CBCFCEE91F528377D200433DC898C2118F7B6275F4E0B9A97028E759AE0C77477CFC26A1398CADE7671AB89344140F5C3662C736107205A2CEA71C3612C4EB063CAC777B9D6B61CC0419FCAB4908AC161674C6B4C58C53A5065C637D0A4C964E29729667AA949C39EA0797B6882951314354AC28D52C2096049DF866BD028B1AC3B47CD2E648EB322134522AB2993DB33491326A625E8739672551562B2829CA57AE6518DD4553146281FA57AA373412F22C2D0CD02B6141BA29F31612447DEEFBAF8F974AEA75140DB2B85DE409DB834C283440E377147B2B8204F09DA14028F1960FD7C6B29EC1BDAB0098EA22669D7123D36A52DCD634A447209BDCCEA731B47719745597955D3372CC533CC9B59712E770D7CBB63CF114CC02AC9933AB248617B9B284A8763A8856AFEA63C442BA7407905C6DB13DDE25A24062B7DB428958E2B72117652535C1C24226266BCC7E87A721181CED66CD9DD1C8D86A1C28D0C335B66EAF7422C1BBB3A7DBC7F2A81C7A477A35717A23B486F307C766F1291BE3AFE8408026352D28A826A7E57819390F3341BFB8E258640213BB06B8AED87EB78B216971060B590F16D05D83801404EBC63B7304A0880062B4C1E235655B43C2B6062C28D4064A1A861A9844544776E8EAADC0CA66B2CBBB691460382B586E77856B8085A1D6795F82BE8185C62ED79B2BB8A3EBF57150145892F99A27EC8D1701265CD16B5F5293955400A44192B0E47F399A0BBB9027F9D3AA1F5407465B8B28E2A87AB881BE300FB72047F61A53B1282C13B65EC31045B1E0B779580017E1776E46A5018598799296F49C1447370AF1227A7C000E327B40ED2965EBFC7A555803D4D34176E14BD6F9905C5C4E253062C1110DCE0C22E74779F07846A6806EAF340BEC965DCBCB1A2C40A5E6428D2BFB50CEAB3A64CBA6AED667EDAC0CBF03CCD8D8A56D73C70B122628F90E4C760EA21C485A0536F6F1632F900E1CB13208F442501C6CFD05027F5FAE41ABECE025084A5E4598A766114B13B17DD16A4C99F255", + "sk" : "55FB671A41C8A2850965768B1EA68A496A772291CA1BB79AAAA07B542678F391BD786579BE185F883CAC4350621FE531DDE9A3729493E1E71530A5261A4CC20B41847D815297BA8415954AC0307543C34DAE9B5007254C18414A01AC0FCC55707D906A73CA41A2167D64470B9CD6C082A27FDC62B7711B2C6D4AA9FA00C1348C7666B7A181BB0B84617A9F67BC9825C0E2011B4CC5B1C3F243501A56D27CBBE2F73897332F1BF57EDF885F7A462D801089E9D96D14B9A891A909DD8AA7205545FD319598D3CA93E13EB0219A3674554C45238890CD54BAC9BF3058BD0A6C7DE7C3CCC98AB53C99F1E0BCD0F975D51C0EB11113B1144C8F46BE95C11B6A7909AEA01E3CD013A274354118B351E95C043073F4A3C0F8FC5D50570540281DA1D0CD7401615EB29D4C15B8562690D96531E48003478B805E222043C0611C276940D58E41900C34862F0CF80DD072CE0F8CB6E948CFCEF439333BA87DC04031711DD7859855A4493D4462D5B08BFA825C0A01972C333EE1291DDE850A33EABBD83AC27DDA737A0ACA9692B197358D82438FA24C7721773A61A52CD2781640AB111B588FE4F7A8CEEC4136115D30E325E5160975DC915CAB6369C579F2240881A02276938845CA6C679942757263CD4216CD0C09D01696CBC83B84B430366C2A73207A586B8400F4A9B098BD53A222A51B31B3E1A5A215824F268790D620754C1A387001BC9A3605D94360F9B50BA29723D8088A0871A0B79BADC669CF18BB95EBCA4E53106160A71EECBD492757F2E98C27A47FBA13C7519399CBC2A2121A1AE5376594159AC23B856888A34026904A3734141BBE75904D9D727486E644D7D1C7EEB4B7697AC925DC9FEA40421482ADE07B35879342B71426C8E21CE9CA3081D62E615661D1168E102779352571D884C1104B760E29BED2BC4F5E01BEF7322D1ED2A8C0C882798781310197828792430530443481A253CED84B8B7AC4736452703298519D41BD59CB3C32A2271A592A0F754192A6672607A346FA3997B360F0A75B423397B2520CFCC44C0197C7C7A6443154AC6F3985C1256A0AEC9BF72B1D8DAC046C7376B6A424B5324BA04881AFD25D16387C43AA57ECBB9CAA055C6863339F420B09E1CC665982E73997E23179234250B5C047A9E5B656169734576FAE1B970C15A9BCABC1742792E2A9BAE6C29B391B6A91136E31ABCDC859CA9D3A7A807C36DB195C1731AD11DA6AFB304704475CE0C3A73B42BE27172C8F2824FFF7B933102D1311A310444A73CB2E71A9AA6B482C73317689235B49F44C7AF6A02D5AB3547234944BCE390756719CBFC6370B18AB828A6971F770182422A9F2EB2C8523605AB228026797FC1721AA942AE8087010A5BD2C2886EFF0A29FA99DAA8A91B8A1C6395544DCF07586EC99E592B995074FDA2A716D8A86FB1005A380878C07243D708B1BB15BC2E639CAC28011E461C34C17A47A0E5E07BED0B6761429B21C04689DF8A2AA22400253801F41196A02522AB49C1B724107012EE3C362CE351F774C8943832F27732014C8918B2C8E747BB0CB531A3019204A441786AC3DAD4532A508147A334FD772CCEC01A07C021E2B59238D7B57D24A8F4C90B1B7A7546144C9FFF2BD9B931EEEA30FB2677D5A3BB24FFB4C15C0A222F151B0FC3B2FB68C96140C22765E36D471BDA76BEAD7BAEAEA3E86296403A673B0C60389A66003DA689F42C73471C0025364F86A66826B9E03864781073614D90EEBFA1F266C4255823A37258F51C0839D2106A90171F1191035310ABCC8522D814310B488E51BC7AE20C8597CB2EF11645C9B921CA2424F3780D6C87A17A9AE9FD0A5B15C6D9085C6E580A1CEE699A624046595401A370912381A5A9731E3F3396070C2E2795690ABC0383A71EA4ABA69459123AAACEB99691A82C729D028BBD69EC903A60ACC9FAD24CEDC2C391C4007DD324CA46581558CBC0BD4A397A776DB07C41EDA6C24F436021B4B269B105D33AE94A55594E70232C15CEDE461C40742BB950447064D21220E41673F98B57FFB9A23FE096DFBB4417E024AD4121A824274C75C7D457794C9034364AA1681C79AD7F3C3E308CE35AB8704EC566EB786283A9ED8EACB14E24CA349A581598E26967B88BA5B3E4A1BCC9C13CC74330D6409E0E1057C125AAAA4BA0DC34B0FC991BEA47B02A8CAE2F81A10043EC8D655124B3ED56505296C5AA2227CE2AC04A0A31CA05575B2E55C01119D6588CFB529AA54E707155BB4F9A63966D9566BB65A95287591F715E6BC0D7FD1691129999552B1771B35A322C5145C7A40D79D6D9C3EADF941112C4F76D678CB0AAB59B9A30BBB340E078BC2899951691F9BF84189A87F2AF590F881027A489EA1BB89E3A8B65959AD503A5E051C5F398A654C708F9EA51BF75C6BFC25634145076A93AA6E6640E6B47158ECAEB621C606C065972C9F26A34736067161E6BD49FA2871631AEE5B518DDAB90F692929D5A7A6E76582E53DCD36ACECB6A76DD9455358BA95EB8A70D3786C01960B367E15536B456408E4FACCAAA139C8E9737AD6B8B0E380BBAC446C73B7B388B319DC2047FB7338072A0F225B506253AFA722C812419E9C739C90BEED97BA8F684111900E7D1762A5C0903C390786E1445B615A1E054EFB7B0B1DAAAB671A63CAE7B55C8B6F13F10D55707650EA8D864C7E5217B572643E6C7480411489C9AB18400483A657185990BAB58B6A734596A6123DFE5240B2F908FC8C3591490F89875E0AD3B06F6812EA973E6FB0A69886199B3B55B7D26A55501B43609B3D6A3981CAB946049C10B5737DACCFB2040E014A5F715B4C1F8B0406B3A3204602182450D10B019B388BFE31B5A5A9794B5863BCB34CF6F659B25CC95F0A42FA9305A0D647342845D5B28FF5C1727975BB48C5AD2C96B97DDC3BD4F0B40E9B6FE1138739F1A9CA3B969CF33CCB700FA9FBA93EF565A8AA180CC3711974BDA14AB85E3817EF4801C0C3B3F68403BC94CC7412AD044A220750B6CA963E3E052F310BB1474623F707157C8A7D67F95989492278CA5707EA6D106431FA5A3B88C39E3E360BC0288925932D44A2523B0980A221519CEAA65353A7483B7DE6028744A2869BBC869A58BED2327B3C6A4AA7447A9A09BBBAF322D5914DC9D5A1EF8AAC92B920524C6968289D7DA06DB2561EEEA26FB764168C185EC20CCF2B57A89F2887720809E94C377B313CD5EBB7F71037BBF01BF85B675432B891850316F6B938231793AA3AAB2972E979C7AA258735858434B6386CF0C5A9232F60A70624B4CBE9F10FC9E3A0D7605BCAA23AB49A222F66127A1A4B9F2BADA03C8DCF330E1DD90131852B71CBCFCEE91F528377D200433DC898C2118F7B6275F4E0B9A97028E759AE0C77477CFC26A1398CADE7671AB89344140F5C3662C736107205A2CEA71C3612C4EB063CAC777B9D6B61CC0419FCAB4908AC161674C6B4C58C53A5065C637D0A4C964E29729667AA949C39EA0797B6882951314354AC28D52C2096049DF866BD028B1AC3B47CD2E648EB322134522AB2993DB33491326A625E8739672551562B2829CA57AE6518DD4553146281FA57AA373412F22C2D0CD02B6141BA29F31612447DEEFBAF8F974AEA75140DB2B85DE409DB834C283440E377147B2B8204F09DA14028F1960FD7C6B29EC1BDAB0098EA22669D7123D36A52DCD634A447209BDCCEA731B47719745597955D3372CC533CC9B59712E770D7CBB63CF114CC02AC9933AB248617B9B284A8763A8856AFEA63C442BA7407905C6DB13DDE25A24062B7DB428958E2B72117652535C1C24226266BCC7E87A721181CED66CD9DD1C8D86A1C28D0C335B66EAF7422C1BBB3A7DBC7F2A81C7A477A35717A23B486F307C766F1291BE3AFE8408026352D28A826A7E57819390F3341BFB8E258640213BB06B8AED87EB78B216971060B590F16D05D83801404EBC63B7304A0880062B4C1E235655B43C2B6062C28D4064A1A861A9844544776E8EAADC0CA66B2CBBB691460382B586E77856B8085A1D6795F82BE8185C62ED79B2BB8A3EBF57150145892F99A27EC8D1701265CD16B5F5293955400A44192B0E47F399A0BBB9027F9D3AA1F5407465B8B28E2A87AB881BE300FB72047F61A53B1282C13B65EC31045B1E0B779580017E1776E46A5018598799296F49C1447370AF1227A7C000E327B40ED2965EBFC7A555803D4D34176E14BD6F9905C5C4E253062C1110DCE0C22E74779F07846A6806EAF340BEC965DCBCB1A2C40A5E6428D2BFB50CEAB3A64CBA6AED667EDAC0CBF03CCD8D8A56D73C70B122628F90E4C760EA21C485A0536F6F1632F900E1CB13208F442501C6CFD05027F5FAE41ABECE025084A5E4598A766114B13B17DD16A4C99F255A964F69C975BC276B67B828D04997C8CAAF20600DA330EC642633F9789858F733AFCC6703873BA41A425FF19559EE47D056D3B5B9E567E5CF24EA17010A5C3CA", + "ek" : "3479FD420CFB637B4D9A35968041E23AAF9547B8C2BC92226D83B82D9CB32E3E5DA58347D376B0C272FF258978F65FA40B60DBA12D99364CFA0E1A9FA7FCF9989F3201BA9913D98CC6A8437D62083BE444152FAB8DDA85C88AE3425584EA1E0B5C9EC3666DDC48601B0613D88DCD9C45196E0A0CCEB6140E2B4CC156A27351F62DFBC21DC24BF7AAF9F6FB1F8D9D038CF9B0A6651186D31A19F46931F39FA796696549F1A5191E648E7A78069BD60AAD81A0B560E133EF0152DBC45501DE66CCADEC5A5AEF360A0873BBC0231360B86F1D3898E7C496DBBFFC2F786B9186D3F0A208D75E05F26C38EB0FB9AE9F2132910044CB0CB4CD54CF0997044DF52D06AD1D578B4014D1D8E179298F0537A21D69817AC205CC3A22E5C5073884880B1E0C8F123D74FE9AE253756F620A5DD1760E8540D0C9070F91BEC833B38427E11BF5B901F5B923596C52FD104CFA02D0899D8F15170DCFD1B6F76075C3792F32054EE6A70587DC092A83DD4B20972966D213408282D79E246EC382CF873FAF7300E4F878F5ADD61D4D1E5A450D42DFAE7E2138C9635A772F59EDE9A5A5EFC677E9E35C031DA28CF4EEB24CE221FC053A32BB38C7AD0519C071CF7C70C4C7EEB8E9483E14383397CC51C3757479C9863A274015C0F1769068AFB0530D7F06D4A11B2D7F60D2E703E2413AE5B9574AD34C3F135D632367C1A1741FFC684E68B2C91DBBA3B22F36140D4A4A295C91D716AEAC7FF68FF71D5271F85C9791A6CBFC078A09FE200793AF3AD48F2C0BA885F2925572BB07B7CCA1905C0AE83AF517ED42DB3D486E3ECDADCCC712332468C9E15CCF2EEFD65E1E4E1615012BF9097FDAEB8B9B353705503337A563AF0848CC23D0D3999E84BEA98FABEA5F20BA32A0705EBEAF499BAC189F62AFE2FAABAC6BF98B02FF8E51383D01FE3F917C1A91682115FDA7AE152CC57AB64061A2735A509F20DA4404C9650E38EA20A1E76859D9D625DA92FB315D4E1BAC44D462F536B0B4968FBB465EA82D2D04B885B099DB45A60B64C7DE25BDFB1B37D5538A570BDE74AE10AD7DFC1B9528922B98157A82D179D984A062859A616D0256D2B83ED25CFC63F330005DAAE1DE981955E9E109BA764BA4E7F1FC875C8F2807096C0FE6A0A92A395FD75C8967CC5DB6264A66CE31826709A4A5D5C8DE16403A44B9A19EE68097C893266FEFA2B753F20BEA9892B4AFA0BD071AE0E977957408BD9C7A88A4B8D52FA2D767D92F77257DA981AD6DD7F87878BB08B3DFF397F103380232501FF4D072BF8216B84165F0DB89E3349208937FCF7C092C880734699E615D95B6ECABD7B343292580045DC17E7429C94878592701E1CEB8F40BAA1CEA824835444F25540F5FDA40E7AF9FED40680BAC5F09B52322286A5C40739091ED7246BF6821690C29FC52E02ADDACEF12FEB81002A6CFD03726AD6A088164AB5FF5B74F2C29573DAB0ABBE4C79DD9D75EA2F588F2F27A1FE9C00DFC4833E7B7F246C29046E1FF45EBDCBE318CD450F74941BAB468D2BFFC6FF42EF11B62C3361B935370B8566FD64AAAAA49B32E600964ED3C586C0E64C1EAFEBBB5ABAB9A466AA383D63DDC47D7C1262CC205BDBC56B4E0C5827AE2B7EB221BCF930B69088E0A85AC0272C7668D266526CB4AF7D24A701DBC58D63038FECC8E58F43DDD63713D8C378E2A4DE54254736A86970FC0E9DFA0D8A4D40C15241940065FF7114D88C48EA6185BEE7F54A8A3D2B59E8D6DAD978273FB0A088DC463CEA001428E11B26FBA47EAF97416642BDCCAEDB1F33A49E0124A33F798E34ABC82B56AD0894E651F9CE065DD6528C46C38CF5038EE9B800AC37E123A9DF842EE2AD6995BE99C2AE8313D797311B77A5A5AB4335B5A8C3FC296FC1B50587911FC7AB8EC9AA3B4FF485F3CF8EB10F386213B7F879B20472B5382858B04CD2966F4ECA95E3A4EB8422DE2DD561E94E98BA6B0519BAE71C7D03289FA86FEB6E57FE055F861AEAEDC049CC549CE850F02891A4B68A964EEED9270FACE4E9ECB7CBCDEC2149AB31A5F1B801EC6EC3A8B9F6A1EBF7E2C0A2CF3AE4BB95AB3078B426B37928A8E77CD94879A1E9E0B148F46A145264267D17AF85D0547379D6A6839F96CAB5E16A3429C6B5A85756DDF6F92E5912481BEC5E3D30EDF6150ED93E05AD4FE121D3CA70AD692FD520303CCF23B8F03B18F792A23D356E70F8F41237F6B989605", + "k" : "E20520CE76834A866D10E35FCC226796D8FBACB7397372B2E135F429F148A69B", +}, +{ + "rngSeed" : "806BBD111F27C2668318387BD0830F65EC21A51AF01985EF48D03D64E1958FF7EE5133A4EBF6DBF36329BCAAF65F40EA", + "pk" : "AD4330BDC85F4699CCCD373DE5D7266E5530A73A42D10C9B327A57715539EB99030873689F47BF6871A00C6CAA06E4B04A832C865B69293303CF838AC186B453D77088895DB36163B1074A8E045911FA92DB578CAD284642BCBB44F844C6663F3F4C98CC8ACFA1A96B6DF57F5BE10FC76477D306245670B2C796672331076F74480C2627A3A44421A01229509752A536E95BA97E85AEBB920B4B1B1BC55BCB95FC76ED43B9805236CDB62861FBA353F08409C91126661580123509C05208C8604389B2DD3B0F8FC94F432B41632C4AE1CA0BDAC54CEABBCB743362725B839DC18ADD4B7795A025261139539641AA43A9C185621D13C33C579189244C884C047BAB4187577C97639CA4ABC631EBA5E9B141E11B6AA8D562449C3CCD8757503A7AB358A24D2B36F2E1768FB24727801123354B6DC661F640883E0613C8886121B89336202EDDC464204B1DC16B9FCD3906BB9A6CF8D6A176A43AA1B13200D67AD0E21F2F73186164A6FAB968EA0427C82501C59C49488846489710D7976A5C812F78B5B7DF2AAA6437054B0A03180C4A886B7D653149E8497B18B18E98E72F9815BE90D252A4583F2DE88C0D7BB10CEA4D65AC1F59683DB4CA4969A9B57BA65E06908F7E9267ADC8C87E8B8D8D5651B234BC9EE1C65FE42A51368A041253E982100C25955BC39B70B36C67484F8DF88C2066CD2A5339C471B60A1B81ACC5922E274CEA4A071EB71E788241AD1B7C41DB1E972212E27C770E6720A7E67DE941A1CA952BDBBC591EF78019C67DD184259BC873F045607D1440BEE46F199A7D2274B4E40062C064368BF5C6D50046A198C89E1372950B7710B3B6376CAA9BC32882A6B0AA9B7FAE86CCCAD0574CD8B417047D30D41BFBA0119B909142363D307A006265A3961C9C604A7B65384A5DEB1C61F25F66FB3B7640B5C3E22B8ED488F08201A10C3B5A42B043965D4FBA6F31B90C5A8A1D8B29A01D500BE93225AB6ACF77960AFD2824F2283CE86288CB1A9B98C11B03DBBB0E0854731B22464331F6DC70E7E1771471236B5B26CE131649E77D46E7946B85593B2989BAB4CE5D09AB8D745A64D53401BC0CA4855E54B20CA4811AE5D9192DE398D9D65DD3A327499CC0CCAA9F9B2B547C5B53722B50B21C7BD2C3C7F67A15BE8371E9D4583FAABF2467A4D5365CF7D92B8DE8A55DE200B61185B89C83BDF817ADCB67FC775A5BB19F1AA453B491CF1BFA8D51D0CC499331DE7730877A2DB14778052CBA5D759E21A8CEA550724F52BF25C2A31D7B117A4377F7A461FF92882E11A4A8C137EE5A4B7AA67F712838737A96FAEA898141A1B5165761401ADBB650BBEA1698267D324A3CB1D9933BE8BC95D55AADC4A814F201EBF724FA024763563E2656B028053CBD16B32C20457349702702C4B453A277B318551C8B732378E3D7BC31A10B5ED975AB032FBFF647C6340C2D5C91F68C1ADDB447FFF01DFD4C0C9D925111948F001880B36588DF16CD1B9BBE85973CE513662267214660340262273FB45F97F65DA4E615DCA4A6AA06C5E9BA0FF727775C84608611827C98C8B7717DAA60004D2212DC28B4392A6E0333A77CB9400978B60A00A766F6264486C60AF452FE92452156961F2467D013072F1C4CFBE08EA7885A74D0649517178412A1AC63261981ADB7708DEDC89B64E67DC2A8B25D98CB1AD74289372E48FABE360495B4A7472F3C8B7F877280EBCC6019648EF960CA23A1C49B684F947460E96F0E941408FA026C127900D84665768DB52A8EC05696725B3DD82498226030B7189C9AE1C612E9A2C65C86C29426CAF686D5B00EA0557466A1B04F8485A457BB83DC68C4B1CB01E7831E476453F084434151FC0C9EA3B7081EE00B4665048BCB8FAB778EADF90C25F54D8F452381E252B2382D04028378E7CC7B3973CFB776249857CC611AF8F91DB8D5B9F5D90212B27D5FC9A794D53E3E002089A05A421A540B36AAC5C803C8F5CD71012F176CA57A7A439DB90BDC71AC65F0470D54188927BF3D2640E5A3A45D9021F876562FA7C6C2B37BE9261393861C5F0336A47AC373E6874EC53FC9F90D856807675858BA1291C7134C4B8432F9782CF6855AE9D49226055D9C4B2F23C0238F20B516D6600FA72D8A5C2D06E1613DBB7FCDF9817CC299EF2614B6085517CCA4006876DE51659C317C7C9D15B2DFA3CFD29DB64B6DEE0F6E53B6BCEE0AC31C086DB16D", + "sk" : "0054C46A1943AE410F1D4B32823272687175A7FC81C1307F51E384FDF6168983525C430F0BA34722230657C2CE28F47FE354791B624CA6462F5634BE583C822A55180DD8A7F00B21FC2B58D1A1746699CCD91ACDDE65280048302AF4141A56000675448F00B57DB19788678872ABCC7F727AF4E816F6A1B8BA7AB408AB03A28A28C0906D47B98B702B513D306212E96BE12647C9586808025B74E37A593A47E2B00F6D505E38586885BAA7FD6257D30C3BA38027F5D149A4D53AB5019386779423851F84C234931C341A216F84E503FB429183E8544018B78BC90C5DDA2923B68ED2F47014683B3BE50F17CC7CCB36B314B0528F8C7CBCA19D936300970772AF962ADE7C7EFC2602A9175FE0B11628702502A9A0143A0C7004AE1DFA2AEFC3986C74348485A846981121250D07B78818302C41C20292143A9B5C6E22F61DE390286E0C9C036B945FA5495A592AC3B2AAABACB11824614AB15114DCCF02DCAEF932361EA0621F860B1D399A22153140220497BC723A00791DF15B6AACBCBFD5B16EE74DAAF059E4B85E30E4BAE4C53E2A133466413459E0857FC8C136E072F1B75BE9A3B806335F5603A46C734EDFE0994408B355442DB7967682859D1A5B36F6A135F5100D259715E04C00236B3855FA25551334437198E2B317C1F54207A1B504475368D328B9D561BA33C9AC75231C127EC8C8B6807AA787B15C1BF756C923AEE186A680ACC4F1D6B3A70116016BCC3FB9A4D95B9F3596AD52895DE27ABBE0D42751804EC2F1818F5361EB68A9B0F8188E9647EC627D1751A8A5F37E6ED4A42E2540DC97272BB380195B75DF18AA8709738F6207BA65AFFD669E3D23AE7BF1B7569AA9411561857921E048000A44819466AE28C631CDD68416E596ABD9365642113B78901B1986F7B43F240300FD487689E63773C1555D1B4ECE69304389074BCC99F1C88BC3068DF61880D32C43B6326CFC11836D94AAC626CDBDC6ADDEF07086ECCBF6F44850242A5D15219FA5598D45097171598CF6803E7B1110A04265544FFF9612416446BC62CB3FE6718B2152292552BD05BE6A30874111538AF71B5FE08367F8A646B925E7D52CB4331DDAE40E66302DB02C87437C1CA03176EDEC873C883707EA0EDC41A45C386A5782BEEF1C2353A97EE5A198A6E572A467AAC63AACC528777D847AC835886A15415286B4E0B0C9089C6472C00B389353F0C6441D84BBD12BBA40931BD2BC84270177C5DB13DC7A2C913C4718A63D9470CF63AA35C705A37CDA0BECC0C024D1257590272D6A302F275595D18A679573F2BA283A162114F34BA8C06D21435474697EF301A0D8F50FAC4324D32448940792A2C174948CAB5F3710A030CD282BC97AE617BC67823BD33EFD32AF9861AE0B4A7D04B4B207D9CDD7244F23651424602D8EC1CCFD77A7B4317BF2504A06646AA19280A22B82A41157CEFB3D3A08431D889E7AFCCE2C771BC5C604F71310983433CD59BD43A4ADC2FC8776109BEB59039AA70E8C1B8C7DC5BFED08C4789337EFEC6692DB5CADA88F0E3998E8B30E9A8897DD85CFD051C62BD9A9E12B47AA4015DD156616682E1C299357D57A2FBB22C2139CB562971C6360A7B607D7E2001EE26BAF0B5957F73F8D94ACBF8B3C56A3B72B11054FEBCF21C95D9EE82B70739846F06EB9966E280A8B007313D3084CF984CC1F7B34D7243627EB70E558B096644FEEABA78541A06ABBAF2CD331D8749247C2220E722DEAFCC5A76A0998D7BD62C50623EC183E4544F647943655CB5330381BF608536C81755319854296E2F3B52209BA9DF6093536541FB654D0170C5901228A4C8F95914C1A2C87CF76A3CBF3C6A9FAC15716001A2B7E0E0A8C00F984B08358E1902238E36046AB8DA9EA35560313C476286E1ABF559B407BF2080684B11BF44573F642002D364C35183A8B107C3952AFA40CD68A22B666AF575344BE88A269E141FF171A6169A29A92A1B63CC1DDCC642808B6F22B65A8345ADA90A992D91A9114480DF287359B9B709814E425C1A397AD0714948EC339B96A229E5AC0FA985DF1A19ED1440D1FC78C1FA77920ABADC31C5256C52314CC970B72B0A6D84FBEB1B1F08657A636BE530A5A8129A8F8137C6FFB5E5F549197DC2FE05259841B681A6393A6A7781FD03FCF592EC3B458D3027FAD4330BDC85F4699CCCD373DE5D7266E5530A73A42D10C9B327A57715539EB99030873689F47BF6871A00C6CAA06E4B04A832C865B69293303CF838AC186B453D77088895DB36163B1074A8E045911FA92DB578CAD284642BCBB44F844C6663F3F4C98CC8ACFA1A96B6DF57F5BE10FC76477D306245670B2C796672331076F74480C2627A3A44421A01229509752A536E95BA97E85AEBB920B4B1B1BC55BCB95FC76ED43B9805236CDB62861FBA353F08409C91126661580123509C05208C8604389B2DD3B0F8FC94F432B41632C4AE1CA0BDAC54CEABBCB743362725B839DC18ADD4B7795A025261139539641AA43A9C185621D13C33C579189244C884C047BAB4187577C97639CA4ABC631EBA5E9B141E11B6AA8D562449C3CCD8757503A7AB358A24D2B36F2E1768FB24727801123354B6DC661F640883E0613C8886121B89336202EDDC464204B1DC16B9FCD3906BB9A6CF8D6A176A43AA1B13200D67AD0E21F2F73186164A6FAB968EA0427C82501C59C49488846489710D7976A5C812F78B5B7DF2AAA6437054B0A03180C4A886B7D653149E8497B18B18E98E72F9815BE90D252A4583F2DE88C0D7BB10CEA4D65AC1F59683DB4CA4969A9B57BA65E06908F7E9267ADC8C87E8B8D8D5651B234BC9EE1C65FE42A51368A041253E982100C25955BC39B70B36C67484F8DF88C2066CD2A5339C471B60A1B81ACC5922E274CEA4A071EB71E788241AD1B7C41DB1E972212E27C770E6720A7E67DE941A1CA952BDBBC591EF78019C67DD184259BC873F045607D1440BEE46F199A7D2274B4E40062C064368BF5C6D50046A198C89E1372950B7710B3B6376CAA9BC32882A6B0AA9B7FAE86CCCAD0574CD8B417047D30D41BFBA0119B909142363D307A006265A3961C9C604A7B65384A5DEB1C61F25F66FB3B7640B5C3E22B8ED488F08201A10C3B5A42B043965D4FBA6F31B90C5A8A1D8B29A01D500BE93225AB6ACF77960AFD2824F2283CE86288CB1A9B98C11B03DBBB0E0854731B22464331F6DC70E7E1771471236B5B26CE131649E77D46E7946B85593B2989BAB4CE5D09AB8D745A64D53401BC0CA4855E54B20CA4811AE5D9192DE398D9D65DD3A327499CC0CCAA9F9B2B547C5B53722B50B21C7BD2C3C7F67A15BE8371E9D4583FAABF2467A4D5365CF7D92B8DE8A55DE200B61185B89C83BDF817ADCB67FC775A5BB19F1AA453B491CF1BFA8D51D0CC499331DE7730877A2DB14778052CBA5D759E21A8CEA550724F52BF25C2A31D7B117A4377F7A461FF92882E11A4A8C137EE5A4B7AA67F712838737A96FAEA898141A1B5165761401ADBB650BBEA1698267D324A3CB1D9933BE8BC95D55AADC4A814F201EBF724FA024763563E2656B028053CBD16B32C20457349702702C4B453A277B318551C8B732378E3D7BC31A10B5ED975AB032FBFF647C6340C2D5C91F68C1ADDB447FFF01DFD4C0C9D925111948F001880B36588DF16CD1B9BBE85973CE513662267214660340262273FB45F97F65DA4E615DCA4A6AA06C5E9BA0FF727775C84608611827C98C8B7717DAA60004D2212DC28B4392A6E0333A77CB9400978B60A00A766F6264486C60AF452FE92452156961F2467D013072F1C4CFBE08EA7885A74D0649517178412A1AC63261981ADB7708DEDC89B64E67DC2A8B25D98CB1AD74289372E48FABE360495B4A7472F3C8B7F877280EBCC6019648EF960CA23A1C49B684F947460E96F0E941408FA026C127900D84665768DB52A8EC05696725B3DD82498226030B7189C9AE1C612E9A2C65C86C29426CAF686D5B00EA0557466A1B04F8485A457BB83DC68C4B1CB01E7831E476453F084434151FC0C9EA3B7081EE00B4665048BCB8FAB778EADF90C25F54D8F452381E252B2382D04028378E7CC7B3973CFB776249857CC611AF8F91DB8D5B9F5D90212B27D5FC9A794D53E3E002089A05A421A540B36AAC5C803C8F5CD71012F176CA57A7A439DB90BDC71AC65F0470D54188927BF3D2640E5A3A45D9021F876562FA7C6C2B37BE9261393861C5F0336A47AC373E6874EC53FC9F90D856807675858BA1291C7134C4B8432F9782CF6855AE9D49226055D9C4B2F23C0238F20B516D6600FA72D8A5C2D06E1613DBB7FCDF9817CC299EF2614B6085517CCA4006876DE51659C317C7C9D15B2DFA3CFD29DB64B6DEE0F6E53B6BCEE0AC31C086DB16D2A63040993F86BDA57D8006A152C436E383AE407C7D9BD7A715A2F9EFA507422A4CB53697A77FE6E39EF13C7460D657197BC1C7EA3DF65B85C8DEB43A058BF1D", + "ek" : "8B8C385D6B2728A73A50CD3F4BC3747C8E1C0BA45A5A5B08C172AA805981BBD6ABBE0C1C3E8126789F5AB5EB5A62E35F538FB3C7B3A6A593ED7D15EB8FBB62C633A1DCBFA5C6A7986FF9C246017962908C12893D11B504658BF47F2C04877DC84473558CEA4E0DD73532871E123EEA523A2E63E05A2DFD1549A1BFDCD3A6038DD888A157D61E27838C25C2A60196520BF9C6B32544417DD7F03F52920BA99166EDC5CF933E509DB02A9FC0852C90BC85A796CAFE6ADA75E01327A8F89D31A6DCCD8467777D931D916C4D768C55FDC9E6B9040E29DC0C8B4B9A42C9873D69B619F5B119310790344D3CD1C380E3287730C7E4BC652F9F2C52099E2B713E4B9BB14262006AC890965899E9E196511452A2362164ED1CFA9DE3F904BE49709EF4FE845F72AF08520B6E09062CECA821AA9636E2D0D9433324E896F8AE7C9E4D4504FF648A2DEEEFA690066035DA588DB07613C7AC236921E8203998C924E452B39B8F567732199CF45B37391AACF2661F6C9AE49F9BC692DAE0CFC4C220274E94AE04EA66A9E14A64448CD1DA6C174DE5F11779D667A3FB677233B2DE0A499E2F18D36E55EB5B9D35C07C8A0190E287A26C60B41AE78835F2FD6EAE4E0620CD892B78FEEF519EF48BCCAE14FD3C63A5C05389B5F500D93F2F34CD2081B83021D79B686A4B5A9BEDF9C3D1256540707ED5402BE3FBE6D63DD84E4DD81DA096B6C65BE692A1906DEC1F58501EB7C4694B0023275905835350B257488B3C1B442F1A041EC5AAD1D7C8ACC71555C03B34E3D52322719E5DB8DD5B31A7C5C4AA823E0C783E787DC12CA06594B0A55CFB851A79FB1CF7E9121C8318F5A4D3FAFDD50727F0ACA83C6D26BA0F7EDE2772F287DCC01B6CEFA2591FFA84770AC7510D98ABF5609EEA0B1E1D89D52998EA34CE1683AF08B5A9A3D621A7C2E59B8170722DFD2C60664FD986FEE50812DC9466A260C4E9AF80958AC19FFE7422CBFF8CBC8205950EB12F10732CCE72025BC789CE409809D4B8C74E9EE967C146C4A107B9ABC96C6DD3682DC0AF62AAC2D6859B7B939CF811111A3F3AD083604AA97812DE4E5A9ACFEF1AD78EC8A40713955594A5C687E8D0ABF107FB345A95E9A149F5FE605B878CD5A46917F6B90B6C09C96EB8BE4DECDF182C39CECE0AC21D1732EDBE07CAA299529E23E84A006EEDE5258CB76C8912C457059ABEA20B29589EB0E275E4AAD6548A4D6F0E30C8E9C62825D47C4AAD85FA738CFDAD70996AD6FAC1E5614EB49EA495DC42C1368533AD38602EFEA600EBB178D502928510457A5A702C00186FA5E6D32C37DB9B9A0BC6967D3BA59EC4F5517B6F52E3823A340998614A29C1BB9A84EB8EBE5E931E5FE9FA537F8E41B2E6A36773AE02BB368D116B90A709AE115585A367FF2631F741B17CEC62C022182350B301EC1A5AFE515F37C5BE9A6773D4955782E5D2296E36CDB624EF471CEB7E8A1BBCDE234C7A11D243A8466D0EE148712C6511550A29D178B39B6FF752141BDD0BA6D2243625F53860DEFC170B09B59F56FC1F6A925CD56E843BC8570195AA771BD8FD06795AD7B8B50F78C24C7979971E31A29346DF3A7341C2C80CC06BCB47CCBF0E1D2299E13EB12955274CC3F65B9D0689FA8FE63FCADBDDA4AF738CFC07879F8BCF621FF8A098AAF35CBE15960BF34FBC14EEAE46281F04B4324AC3EBF0DF5CB73CBCAA6B1D834DE830DD31DAE4F9F57639DADA5AB71D7AF73DA2902EE660806926A719A750DE4A41E6035BA0CCB6FF469E2D7FD57A26062DCC1595D4695AAA87AFEC656A65C903FE51345AC68BBBDFC173FBEB26D1C56426A55386F3A2390ED5BAC98D0E66D04B6DFD01F8C2E9F608F0F462278DB3AB7BCA78DAC47A6F127CEFB56F686D33222AE69EB910F7763F6798EF2FCA374F3C0551593491ED04C99CCC0C64DBABCCC063744B43EB408C7C709A51A9F0A7E1B76625D3EFEAD77557F73435BE4707E476214D4B9778466BEE1BBD89D0E1047C75065B11DFE67461C015B6774EFE11C3557BBD1F9D96B446359D0C89F51786F5BB98409EA08E1E2E5AF515337F7626A0ECEA3D24300370CE6A26393776B6196729D0279FFB25BEAE902B71B13E984AFD85E4C35147C063BB9035F2B9A2CC6953795D453DB01560125B052BC78FC755D6EA2CFD69E9B3F89BCBFD41C58081C20C53354C93D751DE59345561AD786C9BCAC180FD0C4BAF38B3", + "k" : "DB9B28E1248B9AC41121AF0D2C2BE93E201E9F3D258F0D2E323B8D3C712574C9", +}, +{ + "rngSeed" : "AD540A9CE816D6FB1661E5483C44F6FDD00C9E7BD1A8CEDA4B4C4D3697D4F78ED0A56954996CCB7DA96ECB8F5CB15809", + "pk" : "2BF6A6FCE45EB9D6A03F11858433994E304B2D379C43D4670BE6C9D65A61E50C34ED26C67E716933CC5D9EA22D14F86E5CC54967CCC82E3506EFB8CDF40C31F313135B597B3AA72FE83B01EC88A97E32464733107294270F82216E11688DF6CEFC2A9332243EB75059FCECAD20A681AAA17402FB36C6E091728AB92EFA891D141C251895F4C79FE2DB4B2253114BE24D22A38B9D14532FF80E384778C8B99A4303506D08303BAB91D6E05C68A0C0AFFB5DEA7344EF5AB21A559CDFBC3BE395834B4B8D8D9C4AF6A9CA37A34FBF05669F99AF8BDB3237C98F98802AD76A26EB353C6612674E8B4F93A190F293C80DA025DA00AEC20265CBA37B0DF43D78982E6FF49A9F464E7FF57680E7455F816F815C733BEC25E4227CA3257336005D0559B647585379542EEAA8282D8A90B7A885B0360C4C9428951820D189B873E246E4D793FA94C0211630F54510F7F06D116ACFA35C856F87913BF61CBDEB0554589DAE65A2E25341E4B93916AA4B738714526653E798C11F24563B2200319C60343869579B74F2BA9DDB03C6F3479A0EF3A5E5F80183D69034968E25892C28C272DC501466621BC091C0FCFA09A2B56C9F8CCA6CDA208A523EA6A40A4907C1F390780D4A04624466206594CCDB1B19D2B9CC407BD172428316692E09229FC963710165970471E1B554F322C1548A118F84169DD9731BC8C49D1B0130287024C391CA027065591FD9755FFC2A68D36B7DCDAC3A54E0CE67E432E35695A3987B1D4A1E5EA32934C1CBEFAC253DA2BA9714AB6A4A46A07950B6477C303067E0E673FC6CC800A26FCFB59A01E397F944335EEC26002889B08A26338947DCCA758EAC669929BB4C608F9861812E06AA61F5B8B56299EFE95109D57C42C066EAD511BD868C2B107522043DA8356F617C26F7082B078234B435C478D48A53D5A369F7907CE2BE8370C0BA7347707B7FFDB25E6BAB2FA85B5922E0BBA7269FB7A9799A158F9806BC3589268D8514134AAB1DC83D415A235EF49586133DE1BA59B8FA1EF5493CF9DACBEEE04F4B9A94B3DAAE423575682311BC70C49E65090A87137CB327419A2F2D5481D6B10044C6A551EB711BFA828A3CBF22E026D2345DCA2415B6D9B03E9479FAF589EA02A12D1C03939935E8B225D7C18534A2CEF060456BB58145337E81F7346E057BBB98A8C0A312F784351DCB11A1FCA7984A2443B409BA903C3024B8DA9A8B6AABCA90B74A34B532BF01C7C1C1C7CE05BF08C5C65164A01F64C86797317DC03B2D69C263390F9E411DF4F4508D7B03C7B473A7E195E8338CAE5B89B85465779029C0AC711653B1C7A24BB3B9BFF0C612887C12A39C2F5BB2920313CF3522396EB79065BB1E854A8956F7AC2143ABB4136B0682BD01275506A765175C4B7648A0DBB875E2864D52AAB697533512164BE2659C57151C4AF898D689A8619726406110FAA69F61320E75D3A05CC27FEBF609E52026C10C01C30118EE3693A7293F4F7CC4D9F84EC37C5F38890A6A58AFCE1855D4D0CE1F0A577790423115C59228B96BD62D68D90F4BFAC9F17A7597A492E5711B65D8626E568F0150A458201C6205A81FE74A591B547BE842765723B57503C3B352478B304C39B22B147BF6B5BC489C2DCCD44C9F206B7CF58FB3FAA3C8891524FAAA88479B0C4051DEB63EAB53822F84935566AB7978C1B9E5CC043767C109BB4663960A534A750CAE177AA33315584138138D52648AAA5CEFB09F5CD58D008D4C69A1C85A242DD63A997385B529A288758C427BA15B05642C230C8A0180938606C6E1465166F128A35CA3855657AC1B3677A0A15D094EC68CAAF90CC1958BA0DBC22169F3853F3B7D56F4BDE7BB2C1C71C8C4C95299D95873F89A17A4583BB9198E0279A45691A3107BA1294726A385ED95163F0BC3C609C01EE201C5900EB763518F212F14723314715E7BC84B75A611C481CDF858350DE0495D1C020228B004624900C300CD018166FB4DD217CDA3C792DA49A87A3BCAC52542F3B3243F689CE69C1946A134A97061C83134AC52C92D97A458B7B38DFB7F42476B6C5C272C71065E5159121484D4A541311C97FCA3488D13B1DE64610483CB3A9551CF4A3317D0C76766C777E526595539AD17BB6C184AFF73B6C4EACCD5A14ED1B1B836975DEEEB8909458146938505DBA5DAD77C1A3ACDAB128B36DC1E94A121C545E3515ED56687F8911EB5E172", + "sk" : "C5AA9D405BCC9AF610795279EF2403C6F92389332592D0ADF1B3A5172C795B483E1F600F2C79A7A683574076AE8941B68FD17793FCAA9CB60D39373DA09B827662835EA227AB05845853979910154DCA8BA44C1511172123EA658B519A53695E1315ACCD3C5855E03C1E40A50E10666BA253FF23B1377830CA1A485F656B24662DD3EAAD239553F3A50B2934225B2647658AA1A21828A413944A53135FF9516850A2B0A66B8D502A17322CA87B3C09866059942BD8EB4F44D646E5A80A38687DFF595E92B2250C2331DFD2495964BC03A2CA5066CEA671A5CB0BA079788366376F8078804E98C9493A9556D044E7D218DDB83597F9BB33369266711F0ED4514582B25F04AAF1D0247C5624EB5555D0B08C14D307B7084E41E1185465C193AB04D4295790E4451DC25491796D4B3C47B1051D021A91440B869A75848E9894C8D393C534C4B2AC1318A5CB482B53F9BA76203331E87569803B0FC2E96072F777F61B008941642FDC76E9744FAF9C6F06C381F5D54492EB6CCDE84F09101501C60DDDA80788C4619CD48DEFD9A9CA6576DC451101D37D422350B4357C49A90C291AA393263CFCF887C1363769C40C76530877DC9CEF88BC13F740A8612AB43599933B7A3A7495A03800B9DC66BE070D8096976C85962F3C75BAD40C71457E5EE929386C7F65869F3E3C067512B2256112FFE557881B873BD313A021851C581259C2CC1F3617B38CACBF4A5BF2346623F2B316E4C82CFC9C4AE2C08742709AF023B91CCDFA0B829FB047661C8DFAB33BC9BA334328A8F22419F2F8768039C098806937C05CEDF34A8D65930B07AD66CCA3CEBA2DE45694CB534F7EA881C2A2C8DF9C9F52163FEAF0CF199CB81F1C05D1EC3774C203961C2D14C307BCF4716F69B837B7C894843766700CFFA87A5B6B655FA304D8B2A8AA32637AF967814B7915E5283F1263ED03469768783FB757F4B8385F7995548C75B98C24FED4B2A3B28729924CCD618A21F9385C5B577642150534C31A15A854179E1A0398DF0C2C69A76816979F0834000378BB9F4AC43BD098AD6944B2CB028924B201B6CACDD87F25A67E676C738931ACB4C42594A4AE4354CB87008CB2F486DD50A16E0228DB6B547E48780E523B8841CFE8B636670CA397990550C540E2572349947D15CC46E186CC3197045D77B8DC85943C0ABDCDF1629F4A74092A65F579B33F5233ED47916F1475AA284675972C7611C1F35C41CBE6A8F1F18F3BBCA2F7D9380E2C9AC9126AC3287A09E80A041531D83B39591A9618232F990862D125A29B85A1DE31BC4380C0C4F56E8A93A7A332A86D114FAA06189F91B76CE79CACC88BBB2360599C0E9090226C82A57C5C1403745703F6B55CB9BFEE17C4DD382C17DA5585B823F9A037BAD4101F07A301E96953E02A32A31326B04E02A52928293AF67A6FB115444F4A4B58EA17AE716D61806094A301BED3015443ABB0389AFD98196611CB1E0C21C951517717835E7868C4BB8C958C630B0C78032367B5EB30100A15AD9949E8051C9BAB638E8C0E271CAB8A3A43998532469724979879DD46C40426CB49A29F987C9BEEB92C1A393D6132921B019791D776728617597B0F2738916C99A9D889619BDBAFF69050E6B0C906F3048B8811A8DA04AAB71A1EA85E2B07AB021C089DFA848800ABA0D8838DD8AF43D82ABB6C664E363BA30B0E383214801CC69191BBD7913CCECA3A45B52B9688957843BBF86112C70A64B0E2A1C3C89AC5D881848616CA3838C3647AE686568883550E93190EBA3B1A08080B46373FD05F8EC81A535650C5281843279073C0802CD33A7CACA35547C0740256F8B7CCB85C790AEC85525759C0B22B15D268C9755BF020BF6C913074C5A4118BB45B025372DBAED0F96329C245052C8E831C5966105ED6D098A4E4527768CC3CDB47EB343788C9B5AD2B4EF15B24D8193B5E9B6611E3BCFCE348869B07BBA361035B54484257D1D65B3D11226F31C299607674C783B81AAEFA6161656115BE771991615A7E5A7B4BECC21DFCB48738CBACD764D1B8B8B9080D6811CAF9927A4BC68DAB415628422B05530BA495101A9B336A896457837D6694BD568290E2259DCBC302ED2BAA96292536B9A0154771B0C791B7EC8C4EA2489062160F8691CAD483B020AFBB076E0EE7C54188B32BF6A6FCE45EB9D6A03F11858433994E304B2D379C43D4670BE6C9D65A61E50C34ED26C67E716933CC5D9EA22D14F86E5CC54967CCC82E3506EFB8CDF40C31F313135B597B3AA72FE83B01EC88A97E32464733107294270F82216E11688DF6CEFC2A9332243EB75059FCECAD20A681AAA17402FB36C6E091728AB92EFA891D141C251895F4C79FE2DB4B2253114BE24D22A38B9D14532FF80E384778C8B99A4303506D08303BAB91D6E05C68A0C0AFFB5DEA7344EF5AB21A559CDFBC3BE395834B4B8D8D9C4AF6A9CA37A34FBF05669F99AF8BDB3237C98F98802AD76A26EB353C6612674E8B4F93A190F293C80DA025DA00AEC20265CBA37B0DF43D78982E6FF49A9F464E7FF57680E7455F816F815C733BEC25E4227CA3257336005D0559B647585379542EEAA8282D8A90B7A885B0360C4C9428951820D189B873E246E4D793FA94C0211630F54510F7F06D116ACFA35C856F87913BF61CBDEB0554589DAE65A2E25341E4B93916AA4B738714526653E798C11F24563B2200319C60343869579B74F2BA9DDB03C6F3479A0EF3A5E5F80183D69034968E25892C28C272DC501466621BC091C0FCFA09A2B56C9F8CCA6CDA208A523EA6A40A4907C1F390780D4A04624466206594CCDB1B19D2B9CC407BD172428316692E09229FC963710165970471E1B554F322C1548A118F84169DD9731BC8C49D1B0130287024C391CA027065591FD9755FFC2A68D36B7DCDAC3A54E0CE67E432E35695A3987B1D4A1E5EA32934C1CBEFAC253DA2BA9714AB6A4A46A07950B6477C303067E0E673FC6CC800A26FCFB59A01E397F944335EEC26002889B08A26338947DCCA758EAC669929BB4C608F9861812E06AA61F5B8B56299EFE95109D57C42C066EAD511BD868C2B107522043DA8356F617C26F7082B078234B435C478D48A53D5A369F7907CE2BE8370C0BA7347707B7FFDB25E6BAB2FA85B5922E0BBA7269FB7A9799A158F9806BC3589268D8514134AAB1DC83D415A235EF49586133DE1BA59B8FA1EF5493CF9DACBEEE04F4B9A94B3DAAE423575682311BC70C49E65090A87137CB327419A2F2D5481D6B10044C6A551EB711BFA828A3CBF22E026D2345DCA2415B6D9B03E9479FAF589EA02A12D1C03939935E8B225D7C18534A2CEF060456BB58145337E81F7346E057BBB98A8C0A312F784351DCB11A1FCA7984A2443B409BA903C3024B8DA9A8B6AABCA90B74A34B532BF01C7C1C1C7CE05BF08C5C65164A01F64C86797317DC03B2D69C263390F9E411DF4F4508D7B03C7B473A7E195E8338CAE5B89B85465779029C0AC711653B1C7A24BB3B9BFF0C612887C12A39C2F5BB2920313CF3522396EB79065BB1E854A8956F7AC2143ABB4136B0682BD01275506A765175C4B7648A0DBB875E2864D52AAB697533512164BE2659C57151C4AF898D689A8619726406110FAA69F61320E75D3A05CC27FEBF609E52026C10C01C30118EE3693A7293F4F7CC4D9F84EC37C5F38890A6A58AFCE1855D4D0CE1F0A577790423115C59228B96BD62D68D90F4BFAC9F17A7597A492E5711B65D8626E568F0150A458201C6205A81FE74A591B547BE842765723B57503C3B352478B304C39B22B147BF6B5BC489C2DCCD44C9F206B7CF58FB3FAA3C8891524FAAA88479B0C4051DEB63EAB53822F84935566AB7978C1B9E5CC043767C109BB4663960A534A750CAE177AA33315584138138D52648AAA5CEFB09F5CD58D008D4C69A1C85A242DD63A997385B529A288758C427BA15B05642C230C8A0180938606C6E1465166F128A35CA3855657AC1B3677A0A15D094EC68CAAF90CC1958BA0DBC22169F3853F3B7D56F4BDE7BB2C1C71C8C4C95299D95873F89A17A4583BB9198E0279A45691A3107BA1294726A385ED95163F0BC3C609C01EE201C5900EB763518F212F14723314715E7BC84B75A611C481CDF858350DE0495D1C020228B004624900C300CD018166FB4DD217CDA3C792DA49A87A3BCAC52542F3B3243F689CE69C1946A134A97061C83134AC52C92D97A458B7B38DFB7F42476B6C5C272C71065E5159121484D4A541311C97FCA3488D13B1DE64610483CB3A9551CF4A3317D0C76766C777E526595539AD17BB6C184AFF73B6C4EACCD5A14ED1B1B836975DEEEB8909458146938505DBA5DAD77C1A3ACDAB128B36DC1E94A121C545E3515ED56687F8911EB5E1724016AC096BF081A60FD2726D6B275F550C50021D42608C49C93385828573F89F195927B10C3BE5F19FB055A71CF9610FDC0F03E23FD09EEB8C63B7BA3C0FE642", + "ek" : "BD4D7F20A30E19994749514FF1EB133CF3BD1A249E86A02B943F9D4AE4F344526421797FDA8C6D625E2FB38FE9AB1B39FAD8D34C48911A6B5D26D18D9732F933C77AFB78CDD300993044EFE59051586E3CF17381660EB6429DF6CBA34B776AEC35A760D8FB0548F6D71CF9C665052C92A3133CA8B5805732DDE899FAC0A28C39AAB469186FDE2DE8CE43FD7D2FC70CAD9B0567012EB63A89F4AD391181151FD3B60FF3D4BBEAA18BF9A176B461F78A3CC67C7F740F3095F7BFE087B151FF33C29C3E378E582E4433F7B0C093E6D3038DDBD0F9C48314A0B62020CEFCE1B021329931C5181DDDD7B5D2B9FA1B9D0CB3DCAF1EE9D69B41F801E1ED627FD6C117ABB7DEF957DBD8A346FFC8E662E917A645AA5994F79808B1C86182D84886A743BE27BC68B4A441DA0A3556ADC6A700D6A8A76329C3D4CFBB74CE68E0D1693A2AB0630DD65483B60E8803CA49AFE49D21540A1625B8792065AD31595FF6FD334415AD31E54A14E4371D799B8EF85A9B894B8DB81E39998F0F285E4B1738B2FD22D676BFA30757CA46ECE34C11A6BEACC3B8F63AD67F943339B5DA714C8E93029981D9D276EC3DB9E969880262A1A271D8BE5C9D5D2EF8212527D1FD2505F890A351E5EA1001E7B0D35394B8E02D6B4906452A585493FBCBEDCC90438F0A88506CAE092273BC6013F3FDAC99D1A4B418A5E19515CD7B8EAE06CCFDC8EF5BAB43B992CA9E18801DAF62717D6EF22776A26373A5C9750BF0B9CA7639A29DEA33F0E47D4D49EE17D31C30D61020841700CD88EE019898DFB1E22BB9BF9F1C771E08D224CFA27E2B67BD42AEFF4CA7DFCFAE960F4E2F7383C5B9EC40C6E2A4FDF1C80CB06D7F4655AEF72B759D6F559FC9124A24417D3D5B902F22F89F09CC087A8CC081DDD4669D92CDDAFBF2C390DEF8399BC2D7925BA2F9D75D6D0AE6EB7575220DC5A587C352C299CD54656D1EF4F46320232AD64560D8DDAC0885F2D0E36C323FAF426BB2F7F086420F280AC4255BC1F8700C9E5A365293DE79F71D87090CEE395DCD62981A5D5878837994D0C53443068A7D5F4293B13730E8ED5DBA55AE5BF51767A6A03D09F59F942DE5E1DA8686F2F7934566660BEBD1D0E6C48FD34F36A84C7EC1C9E9753B3BAF7A696942C633F1664F1CE4258E88EE76623D5A46023C045D31D1EAF08C11634F74C2CA29B7E6627356813C7582135877D48AA6B019A12FFEFE3F42444CC0959916B57893FAA401310639C1364B0875E8E5E62303A734AAEBBCAA4ACFB85671A7527F4CAA020022C6D222BE773004D2A0F70BB8018FA208B02EA46FED6033512F5ED78B15EC6F23944A49E35F8B4E22004B1E776BEDB212885B61D996A3AC6CF23F7BC95B4CB8449DC504EB96BFF784CE8B47C33A38E6DE88B52874C04268FAA707537DCB37628C838AA6FB1A5166A24B5B84BBC4DC3FDAAE372FB50BC71C30F33227182C505B7EBBD2A3FC574443DFB912908EA15DA4323153DB81E34A0B770945C3ABDB43CC2C1331A014FC3DB9011EE9C0EDE8A8EC4A0C5E8B18522CF6A903AB0BBF6BE60FE9C9EB4640EB30D4C19CD795351FC2D771B0BA4809D792A098D2554FE8D7646C0F929E40F8A9FC51F14991F44700603FEAB556C892DBDFBFB59785BEAD10BD75B07DFCACB24A57CB523ABF3C01702DFAE679E39B622B7B482B084EB4EDD9E3E5610E6E0B2451ACAEEDF260BE053B825F26CCE62E9746833F97243279E2113C4D4CC7A717C8AF3B36B193FCCCA22FABE89003AF5895B9D83224DFE29DA9C1B5B0C117ACCCC032FD07F2EA476CEB1919C37F2BC6EE6B2796EFF77FE4024516AD8001DFC4E077DA5158BBA0CB14A57E8F504D0135360A3F9B8A0A59B50911D586F10F8D8F9CD946EBA80B6836D5A751FB43823B74559EB2A0CF91250C7A3BDB0D1CF80D160BD14E6F161F5624F5B7C70725107C04CB029E2687DFF62D099175D334D3A24CEC8AE9389B432E337016960CF86F64BC14679DBDECE4D98B79329EA810115FEFACCB2EDC9B578508BB12CFD16DC10D6594B1EF74188DD51A3D8EEC206C91D2C55DD5E1723CA328D283B3B2FCC1EC76EE0D04C3883A3776606D9753A68732D1E947C284F0B93F35F7A9A4CB0C626E98497EE5500D38C52429C2CD58AEBE89EA7FE6D55A4D80A2EA2600C9CE70A616407A79C0C11249A611E7C388ADA2DA5C8C557818D19F41BAC3725FBD3AABCBE4B1", + "k" : "D18A28875081F119EE15A3F031F68EEA3B9E3FA7114B4FC6994B222C39260E36", +}, +{ + "rngSeed" : "288A5F2684D862A86D2790AFDDDDBAC6FDA934EE7D2E6DA1508BB550838609E8107312B28E00A6C01706374CCD3AEFA7", + "pk" : "26C68B1BA4659966CC95D79851F03E029A736C3B4809F9C366093967C53769B4796EE76B4F1277F1407B8C478FC1400DE6415C2A231727303C86110AF4B743AA85B73E38B41B819021B07D1ED5C6C171077E9C9B6A678D67B94958C66921E9CF0F573585BC3B47323F32979B91C411C9133B3B8B03199179C6F457F106BE4201BCF2D142A4814C5E166C17680FDB2A1296890A89C802120585951A9051FCCC4C42001346C9ADD97F93191C720466F95C5590B0CB8046A470CB50A3716A063135EA4A0219217B4D373EFAC8625EF44E5C0761BC0404F4AB87BD8ABB068C07DA5C832DE7530BE88532FBB5D8EB5C6023A5F0DB1AEE3A50D2864601A579E6DAB597D6CD29208C48F075D42C6B27AA3C3CD837E224BDEF354E20168C03172A16973224D50CC0AC7F60FC9B0AFC7F399C29A9509F9BC3ABE7298303DB253DC04A69BC873E874A43DC28FBA6339E4152E4399A3EF1055BD81099B33A5087B816CCC668A75BED05650D37966D058D6EBB2B3A819218036C2BA064EBAC797C671EAD151C121AB88F6C9395204E714310A8293C64BC9789864F93569CA043B856C8412AD985D8206B6E7485F1956D7E616104F720E76459BBB0C874E45479E67233137875C82DC6509CC124BC184A3DBEC02CBB08B989103FB59C378670BE58F0A96A694D71062E6AF424B6745FD9130BEAC38D297A5F1AC783EF064084B84AA06AC9C2680E8DB2487CF43BBE6B8574311A4BD99D733A1B6A751F68401938F4091D25837120664033770D476096E561A1B03E8CC878480A015225CDC1D0719BE196B4AA94074C290590988E9B4A4EBBB4B3E5477483CFA6860219237924641CF9A2A7A1219A8A87BDE9D08166F0C3081297EDA4737D082AC5617CC7C36D428B9DBB7237C122676CE932FD01AAC625B5DB503A8042C0112714EB43370B5B5BB0D53378A5B6F738C874DC7A7F1C15987C28112857A4BB4310788375D9AA0E60C59958C7F0DB809F688F7640805C334E9B1AAF78761D5107C12618B81BA12A1258C4B0123EEB570CCD9924084B7AE3473ECCB429AE0C7FC059926F25542911A8738B0186C404F2F107716B5D2E228F91306E3BDA12A9B281A598C52228330EF93962D085ADEB6BEB1076969844E1980295964F9F115840753C15674C86119909D111719182F880AD9EE9792BDC128A8C4DF1DA9B3CD43301037B192ABDC694099BAB87441113C77A7F7210764CFB463A96C4007108D4537F29D4859D305987930FD4D94C796CBD55452D10E9B8723A6165CCCA8DD39741E94418812291FACDCDB453529960D850A40745A022643CD1CB70EC330A6E190ED04963EE28CC774198914B5BFD7C43C6614007D49DDA88C1D8B42E05A388F4DB09FF1A394B01547155C79FF4933A28568E172133515EAFAB53B86A078A1A62B114B9977465342A61ADA1A20C236D3778250EBA35F8D36AC0D58C91198D4974610181BEA1CCA0724061976A7AAF161AFA1B111F0B0E5B835ACE9AC1FDA361048A9B0008096B41BF7C619AF3299C5ABB04499C272211931F7B6528C17D5F52405097AFE5E0C6ED2AA2CCA7915FCC2543B4C8268256CF49936A858F7401117B80B18B081E08B45A0E828BF830C13FDC55FB468D99E8107B93616DA437B90A5B52896330C53CF3E28BD3799F65F28BD5F0406638C18C8C9838C555A9B015DC99A61AC330FB11654831571FE667F208689D1C045517AF836ABAAE37184EC603D01A918733362942632644B9B3826ED0967E6DB05A6E3CA77CC1604174A2AAB6CE72FB1EAA31480E235BE79C1C25832CCEF512E6C65261F2C485CBCCF4062A81912ABDBBB3C98C5A6912388A236161E7B8283965536908C0145BDC170BEC33C5B2E437628B452AABA7F3EBC8FA730147469D63EB8294FC3CC9096781E58D0BA64D6DD6837812B530E9077A5C5648AA6CC024069150C5ACF26D3CFA2D658AB18B86B1EEAC4AE2422D41704B9982C8DB14BC53E0721123A209D67999C9035EA07F3485AC50E35F85379396C620DDF159C3A4CD57FAB15B53C8F2E6AEE06C6F2CA02F0D99543368AB70B9BC3F655830D7CB47962D7C3789DDC893AB0A1BA3E1170590249A594445135AAF71A902D9AEDD178D88D980345190D72B710BA08077FC868E86713BE6BB45652A26C73CA91089040322801B9C68DE70662248670F323F4233C1A3C0937DC86F0B6476D12F426868BE1B", + "sk" : "23F2A309696A69C78A5272B1318A02669321E5461DE8166EBCC0A85DF06F30782C29DBB0FE921B9C7C54EBA9771D7B52887B55850234DE9B296C925420567FD327842AF26D0EF1CC1EC393507C540F27184F297340651EC5A0151CF385BA7A8B82156CFAB21419633338708212364997BA39755864B368C333397BEF42609F4B09C68A096F086AB6530A3816C35D6170B4B28479E39F3A5C621F4198F8B8BA5CAB50194BC8490A227C473854F9AB021851EB1A405CB236F8937723D74F0963A67DD465FB172489C594CF91517C3C0DC20C6BEC78CA1E52373A57805C30A3B319AC204995846C0BF1286CDDB73F777522DDE85B43E078C74634408C5E14777F74F9696E1C0703D9A221F04592F4218988AD5CD0B434541BE033CD3A28B039C22C77AB9FC1E477E6BC223703610C4076AD3B583C9402CCD26841A55074DC27BA3981A9552578644895E8279C02C39CC8C22DA0B11F16CCFB3750CDF76C333AC9988A23F1BB33030718279582FDB578B37512EA084348BB52FBD63C365951D9428468310821210105E0600B5723416B62A72C92C7A26642E7C9C562BE22BC9B5B82A16A00069B104B6E359328D0C78AF04BB337415F5A14C5730681E3C323098F117A1FF85CBA1780CB8E51690D8A8565F9739D15391FD7B6AA2091A828A4BBAA45D80B568FC59C77375848CB44D6F5A76F260FBDF6223FF80B3F1229992A7E8421ACFB918D28324C94350DEC894B50E73E084026BE12733146BC4FF3B76061CDC27470052175179C2DD2BA84DB17501D41A16CC183C8D0C2318480EFD5632E630B6C2612F0C88A9240017BA431C5A8629107AF4CF08614F24E44808949E75C283AB36092266AE41B66D67AABC836C7364525EC4DB7AB972D46709FF08762618D7050A3C165B21C5611DE2ACA9DE5A6D826C6441B4894F59BDB93690757461579024FEB4531ABBE20D0410EF201E7F35AC3D304378971DF8855F992CAFAC0CA7D7C277907D071CCCAA84B3CB2203A72BB3D7F0C3E08321C7BB944A4A19FE794544C28181D92CDBE62BA9C270DF5D646E1B05ADCCAA2835AA8B40A8B1741B10CDA223783A788F36A3A8C00EED901C74B95B009A04FA169D8E0512E28266D3348774C7248D6C7122362661C5A1146103D401621434198963F26D3459C6572B029A3828BCCC1EA35BE549BAE2C1AA094374061492636989BC8528D2A7ED649C1062A10C372C7635A4D0155A12B82A3656A491E1041FE25522CE39DDBB144A0BA37DAC28608794C87743B8884B2FB2CB2DC1A37FDF34718813AB58B8F73C0742D2595802381748736458A846DDA95DF2740842411661853DE6A8C04D1CC31975A8B8B3F676C4636A606DBC0906D101CA6E290D364B4A83B1AE5F461C56100D5D48A93C5448C12C67DA30341664F2F2A35B58C25A3397462308170AB80A95780EA1A4E650C6CBD90755C0905026A42D4001612289E7A4A0170B9907D689141138DE4460D143744B5E4975F027D48186161458C5D05CBCCBA6EE3A0A88135B94D0AA28DB8B61131783D63224FCB4962D83DDC39C08FD0773642340D93125E83BB31838E786A2CE3A1A68A4084C214B9F304AD8E4A13E80BC168F8115B378FE5CC0A12468B3C24CCD2DCBAAAB7BB4848C731E68810B92342B77E6E207D5ABC7B93118D0384941460249A3C495B617C35AB97C912589C76313B3CBE21A3AE88D9B0E93A2A24D8449B6816C1045760E7AB5B37649A97938FD4317F3984CCD33A0C6388DEC97F4C0B685F536A30E5C06AF072F7BA2C129C05DF5C40C7AA3E633AA44566689008506BA90107817205916DF72B97EAF79AB0D5C97A483F4C9825F485679CEB0D15C981F1605A86C637FAD32BDFA800CEE7846F6CC52DF8475B170316815CEF36137C2378E9E27F8121B5B8123A1FE62589DB2108810CD360B108018F5D67BFE36AC51BA1C56485CD8A88918CF70141B39AD513846413342BE9A31F62691D221DF48C125B1829526290C71CA471868C6DF5A5B1A5CB14052A46F34E5D5B1E271251427BC4F7F3249C220341261D102B31979821DE60610F9323DA66061311AC2F2413EF97730B0A38E436958DAA13A4F015CF96CA59D93BB56C58E66AB56AD7CA707A44CC1901E5866C3A223831FAA00EBBAD437A0A9DFA83BD32218BF66027F82D26C68B1BA4659966CC95D79851F03E029A736C3B4809F9C366093967C53769B4796EE76B4F1277F1407B8C478FC1400DE6415C2A231727303C86110AF4B743AA85B73E38B41B819021B07D1ED5C6C171077E9C9B6A678D67B94958C66921E9CF0F573585BC3B47323F32979B91C411C9133B3B8B03199179C6F457F106BE4201BCF2D142A4814C5E166C17680FDB2A1296890A89C802120585951A9051FCCC4C42001346C9ADD97F93191C720466F95C5590B0CB8046A470CB50A3716A063135EA4A0219217B4D373EFAC8625EF44E5C0761BC0404F4AB87BD8ABB068C07DA5C832DE7530BE88532FBB5D8EB5C6023A5F0DB1AEE3A50D2864601A579E6DAB597D6CD29208C48F075D42C6B27AA3C3CD837E224BDEF354E20168C03172A16973224D50CC0AC7F60FC9B0AFC7F399C29A9509F9BC3ABE7298303DB253DC04A69BC873E874A43DC28FBA6339E4152E4399A3EF1055BD81099B33A5087B816CCC668A75BED05650D37966D058D6EBB2B3A819218036C2BA064EBAC797C671EAD151C121AB88F6C9395204E714310A8293C64BC9789864F93569CA043B856C8412AD985D8206B6E7485F1956D7E616104F720E76459BBB0C874E45479E67233137875C82DC6509CC124BC184A3DBEC02CBB08B989103FB59C378670BE58F0A96A694D71062E6AF424B6745FD9130BEAC38D297A5F1AC783EF064084B84AA06AC9C2680E8DB2487CF43BBE6B8574311A4BD99D733A1B6A751F68401938F4091D25837120664033770D476096E561A1B03E8CC878480A015225CDC1D0719BE196B4AA94074C290590988E9B4A4EBBB4B3E5477483CFA6860219237924641CF9A2A7A1219A8A87BDE9D08166F0C3081297EDA4737D082AC5617CC7C36D428B9DBB7237C122676CE932FD01AAC625B5DB503A8042C0112714EB43370B5B5BB0D53378A5B6F738C874DC7A7F1C15987C28112857A4BB4310788375D9AA0E60C59958C7F0DB809F688F7640805C334E9B1AAF78761D5107C12618B81BA12A1258C4B0123EEB570CCD9924084B7AE3473ECCB429AE0C7FC059926F25542911A8738B0186C404F2F107716B5D2E228F91306E3BDA12A9B281A598C52228330EF93962D085ADEB6BEB1076969844E1980295964F9F115840753C15674C86119909D111719182F880AD9EE9792BDC128A8C4DF1DA9B3CD43301037B192ABDC694099BAB87441113C77A7F7210764CFB463A96C4007108D4537F29D4859D305987930FD4D94C796CBD55452D10E9B8723A6165CCCA8DD39741E94418812291FACDCDB453529960D850A40745A022643CD1CB70EC330A6E190ED04963EE28CC774198914B5BFD7C43C6614007D49DDA88C1D8B42E05A388F4DB09FF1A394B01547155C79FF4933A28568E172133515EAFAB53B86A078A1A62B114B9977465342A61ADA1A20C236D3778250EBA35F8D36AC0D58C91198D4974610181BEA1CCA0724061976A7AAF161AFA1B111F0B0E5B835ACE9AC1FDA361048A9B0008096B41BF7C619AF3299C5ABB04499C272211931F7B6528C17D5F52405097AFE5E0C6ED2AA2CCA7915FCC2543B4C8268256CF49936A858F7401117B80B18B081E08B45A0E828BF830C13FDC55FB468D99E8107B93616DA437B90A5B52896330C53CF3E28BD3799F65F28BD5F0406638C18C8C9838C555A9B015DC99A61AC330FB11654831571FE667F208689D1C045517AF836ABAAE37184EC603D01A918733362942632644B9B3826ED0967E6DB05A6E3CA77CC1604174A2AAB6CE72FB1EAA31480E235BE79C1C25832CCEF512E6C65261F2C485CBCCF4062A81912ABDBBB3C98C5A6912388A236161E7B8283965536908C0145BDC170BEC33C5B2E437628B452AABA7F3EBC8FA730147469D63EB8294FC3CC9096781E58D0BA64D6DD6837812B530E9077A5C5648AA6CC024069150C5ACF26D3CFA2D658AB18B86B1EEAC4AE2422D41704B9982C8DB14BC53E0721123A209D67999C9035EA07F3485AC50E35F85379396C620DDF159C3A4CD57FAB15B53C8F2E6AEE06C6F2CA02F0D99543368AB70B9BC3F655830D7CB47962D7C3789DDC893AB0A1BA3E1170590249A594445135AAF71A902D9AEDD178D88D980345190D72B710BA08077FC868E86713BE6BB45652A26C73CA91089040322801B9C68DE70662248670F323F4233C1A3C0937DC86F0B6476D12F426868BE1BA08C74EB9F3D9296C268DCD23C66BF0250B222854A5C31830B7431CCD3ED53FD7613C090FBE4AFD54869CE826B72F3A5EC823D9A1C983A3D31B2387ED6B0C613", + "ek" : "D3626B6BF30120B6030DA1CF49734BF1D57039CDFCB8CA42555727F930E28DCE1FE720C8145AE5707459523BA2D20E3C8BE3C0BEF7F5F3E450CDB767FF26EAE2AC2E1EBE122C856BC185E5F5E83645D398894504F5EBA0433B42DCEE9334A1CF68EDB80AF9E60B80DD23601536124323F02998538858CE300B2B733ACFAB188BB7BDCB9E06CEDE64473DCC25498C38ABDCE64B2E1314930CBF31D0BF1461F39FE3FD41A67481A545517849731165E4D3B7A1344A40DED2720CDDA0E55100618D99DC9855EC5293F86F49C20C5D4E076AAD54B42438FDB271DEA9088444979BBB4915F92AE1F74D64B2FD817A6F8F20683D941579AD229E0DF87D1E9FBF0FD9890D7F27421B0FD167D19C350CBE56C0B3736FED28AC889ECAC8323A2D94D347274F41BF8C61EBB8F5F0A0F84B71FCB026A941E212BCBF46ACB8429AB8DF7CC659896FFD7A3775667B3FCC05FD1CB45A970D9049F06B51988B4A456CB14E23E13E25BBAA774F95893899008BB2025780522198842EFBD4EE935E03DDCB9DB1CB2B70FEC7F0C882DF205CBC2D308C7ED8FFC4755963E585BB436B6D52792E2208EB2DF64E96D2E8EECB83506FD6530F6486199B7ECE9683729F667DACF647964A5EFEAB8F9A8D579D8884BC878372BD13C41E48798058C4F48BB5F7A09BCC6A67D108BAB00B3BB45ACA878E9010BB528D932647393F957F07382F1D9D3CF4618297C186812E6C0F33149D0CAEF8AC82AE3DA0457B673C0837E62BE3387FF27FDD0C2FB0474E2B76DF2BD7FF78FFB751444F1ACE7AF4DEBDCF3FD28FCC812F50467095B0CD02B23F417BE886A072A34CA00E515F8F7941ED66269B8F4CB1178F550A72BB62C0A710CAB6A9BC5164E5658637DF9FD9C9E4400AEC9CD1D8133ED154AE8F5B47A018A4EBA4B23D72E7B8712609410EDD714ED8FBE05ACEE990E422BE7FF2A275D7F7F2C1A5C0EB4E3F545622419C27D6A234634F09A4BA09497B7B92447B86E0AD65183DA1C1E26D91A775DE6268F49175495D1CBAF5BF1D2711B2302E9ECA630611CCEB78CABF16C5B7AA856E706E8C2FEACFF086648ACE5CEDF332569C4E48161BD8D4122CD5CA6FCEE65B9BEA2FC3082825A9959446AE23F9EE664651738CE10C4A38D1BC45AB6E70B6FE6956EC272C181A3562C223739ED9CDFE05285994C24ECE7F4BB923113190C949D49EBA45D72243DDD501B500EF134613A4F656F878EE13635A790E62013F4A4118C8A219FBD4A78F2BF837757D28CCB85E04A763F015F76F4AE9EDD1477E2FB7425A066E93FB3E0F03D4D082C2F343F56D37A09191BB35F91347A774315F28C750CC07793827B3479FE0D8C29464D8D5E5E658A763FF661A42C4F1813E88AAD787D6E34358C62D659F09E32B196E6E1FE2A06FE5EBC2E0DE4B3ECEFFFEC150CE96FAD447482F1B9EF903D897677503A8B8F1EAB0B5C4ACEAB1FB83187A34916B0447C8989AA8DACF01F6600C77336B9DDDF261FCEF077FFA0DA2D78BD33BD2469CF912B4494BFF27326EA9B4120DA85D8571085A95470DE49C91F667DED1C71DB8616870240AFCF65DBCDEEEEBB30E91131E3B885E4FC376A5FAF20447073DFC4C7BF4E2A39AC94070CFFC75D4095CB5DB87EB306CD8B195F3DD7E579448E6A2A3754B4712F0F6B16B48EBD4890B8709621DC27DCFBFD07FF052EEF5B27930AB8BDCF2DFC51F50E723E0178D8433917B1A2CD9C874D0A3717E2CA5C104EB6F42128922E106D12B21B7E7F86BF0DD049E2850ABDECCC6E4FF6795C6E3DD207C81C5E9C9A2F4C96485AFD71097F7C7C6AB4D73EB5168E0C79E66D392484BD45222C580216F6FD0DF78A184FC16E44D8289814206C939C8D2249F510514D872FFAFAEDD325DCB699FE3CD667A17D802F74126A428F32EB913E9FDA7CD346665C5E366D3567C0938DC198D0B4AD72E2D3301AC101A39B0A6106F70DFC8ED2697C0D40E230DEE8771040313DC31653ED0187DEF0A9A08950686B7DFC9F357F468745546E6388336CEE338CEF543744B2D2941011947AA1AD03B35857F00CE7D5EAF6EA1182B651EEE7851C04AA5705647F683D1ED0EF69AC8D175323D39696AE98E802DCE49A438130487812F1B742FF5E0D0D41E85DA461DB17AE1A936F47837E0DF108721B6C3C554E0F8B3AF4DA33832630531AC2DB844674BC002CE167CA88703F912F9844AAD60ECAF6679AC1CAE5C44B2", + "k" : "69AE4F8DB88DF7BEAF9E94F33776592D1177BF64C9602E07361FC795F667A935", +}, +{ + "rngSeed" : "4635DC5BB92EF98CDB6220DF0DD717C7F8158375EAA2B78FC3F0B58E9C9653E92684CAD3461D9158A481DA3D14694C44", + "pk" : "AF6C50F1421CC8E1532BC6AFDFE7ACF2A43B34130FEA7CA5B1409AB0F10DFAA5A5F0E7B9A62006F1C53E82B5C7EA427009C990BF31A939EA2705630164445715BC5C80B3906739C46A4C4CF1024776037BCFB0716D1BA00110637FC177FA1768E73CAD8FA4777E13AAC74338513C516715B645E3BED722382950B132418FEE81639D448EABD55A94C66A34EAB68DDCAF1C756A4907BC3F5115AEAB5320F3B9BBE84E0D885FB784AF7FD8C1EACCB37642CF39C8A24C4903A7E80578AC7E9F2A95CD806CAA200E23873F751636CD606D819731CF1B812AFA2ED24381A52B4F5FBA658618A02E0418D6823E7F418294C81032936559A77F9C014D8A3B38DF8BB17B7A8C3B45B53AD60B0D9929A21A4AE3039366F894B1082DB5F3CF2F13381D53827B5A568FC5234E099D6B94BC1A013DDDE944B4EA13EB52BFA880716B1A10D8827A033878986155B7F2944A63A2CC32BBD61907125475BC09B0AB76222CB4C9F2E80A00F9B71BF9705E3576B5A96F6229BA1CE06FA1B2079CF66C59F30DFB88C1F9412B0B2AC059DCAB8782ABE57209188BB938D08BDA140A0EB08DE0DB3F8558C403C725A77AA1E0563A54A77F32AA30CB780F4E562716075763E9C5D470564EC12CDFAB424BA970C51201081193741A5E358CC7D63064A7183D99B28DDC5B0F10374EA9710193385B855A259130BC490041F76A9D661483AA668AACE51C616804B5E7C1BDB8762B73B39F17785AF94B355B0FED72083C2B71EFD1CD43C1A9704A93E0E5752E99A2EF115B6ECABC74CB03BC091038F5701659A0D4BC693805080D6A5C81A0273BE9149861C461C47CF496CFB22526D3FB8BA5A3396DD19A8477611B814B76D5C8191AC1C8190AC3B12065CA4CCC879D5F34BC4479A5C8D4693D8771B434C4B8E8B8AE921E01A131E9410ED11C505D226722E011F2073B0DB34D10C104AFC2656DD053E43A8DB7C00FE705B0BA520980DC71E834127C08077806CD8E82144D50448DD59A085776DAB69E42DB0E7E8CCFC010A140B50B50E09F233AACD3DA972AA40F1D1241D718B54B6009D3DAA090186CB167C1AB3979C8356397E598502422DA2935EDD9C8C44B90E8C50473119D26E99575C0C328307E2017B515F33D4D2821BF341480780B21D37FB6CC3049324EB12A42C9F7C9E086BD0F39A1949058F1D8C8F0739C23FB1DC542429933080AE732B750AF73B05DF6B46E0F27B678668F9450C193C861E7E38D65E5CB05A52F62B29D21B4B33D34771BCA88B3149ACEDA8553C5813BFA6F8A99C656601FD6F4CA7E54CF80E48FA144BD996BCF41E49AEC97734687A7D0DA2C71231DD841C8FEC9A8FB686A7CF81106B16735D6559424C1AE7A5A5F0515A8074BD879C1CBD6012A3B5A7079BBEB6229DE7676A876C02F1620D04905341C95CE512D20C4CA11F7C08684473A31313640760D24B4946C0268C108A8B96F699634414B070444480800C6C3D4BBDF339C47E9B1660B9EA039BCC6836A6FDA9489E76418047EB3E99D40AABBDBBA140221333CF1CF2BC121318AAB09022F95C31B12ABBE67469BC34CCB88C8A0A965902E47494C7A0BD573910A97377B764EA7443E73346EF9BAC0376711DB236F89A025D9B09931AA473AD04B351A00C5D3B969134F03C1745F672138F52BA47A542942C1078892CA3B9509F435D8521A373810B12393C8EAB18FE7B6F3F4AD7EA88B88B21DB46338ADAC939040674BE52E6C2948FD659935A86691F076C7F228BC5874FB8214ECE1947F68B057411C218B776A332F5AA351B4D92560A42346180EDB08BD57F5342773249FCB1F036955DA0269695A712ED852A35A3DE8662966C0B2C2038EA1AB7B4F9708C5849DBDC6A29E734CE8DB1F447109B755AF11976B73CB6C8594A5DE221C44B61B9D425280007EF4EC4CE3B34BEB733CC73A1A7F6857218476ADB0200D96658C8456576666B6D7C06DA03663191E649457D298B81B067789C285AF151FF4B97239C35AB8688A8D6B4469FCC7E42201D5D57BF3CB98C883C5C9C88F05555674E7A1BDD59E3F327B69A74F0D4A250AA89FE1359E5724CA02C38784A14690C62D891364B752ADA80402128C623D0839A0F09BD0E6A37B724070A4356641C538415F2A97701C5492D29A2F2823884496AF9DD06703D8AC2C17C4DDF5561590B63FF78C4995A31A18D861A91C43C5DEC3705C6112D81B81555F7A3B432F", + "sk" : "2702A72C612968570B25144125A96FC1E89D964A96CA260AE250C7AF8C825D857B795396E4EB439F131DC9F36CC190B8AD3A385747A83A976A0E3662834662CA8C7F68386486DA8663774F04066D3AF42713AA6C8280AA96293BD92217C4AA8CC26B5F3371290EAB1AA0D0CEE1382DE722162A23BC001690CC5AC2C49705711164508CA429E06FF1231EBF0B64550C359B93BE6690B9D7E2CBD6027DE95C34F03C3D2097CBE1150E4861B57B691E18100C333A3BDEC306A87121E51C7641687290553D7005A5241609B75239E43ABE459414FF1CCC41118417633D72522B7D1B3746F8A542106061D567CB4370F721540CCA09BCB9CF8C364FCA8322D2D56A6F1026A53A1593981CEE1B8D8776B3827B5161886AA4E91D6BC26A516A757A353F6C2020DB2B090A7327215238F5EB4C91594E555B8B0A3680BA6B9BC0589B5E91600DA829205395EE836DEDA787045438E657830CB0C6F82379795A72F698C0D7209C85438C92812938C65407058985184E48F9093F6439FA158749696C1144A336614459F2BC41C9A7A31A2B74AC216D202ECCE10F82488B4F32C010A23F35C918AC8C3EA7906219FC85F67730AD12450120091A4B8B53F5378F81B5B7B0BD85B486C6ACA5B5435F33F8C38DC255C9B42F1A191457497845F291FBCC239DE68C1F6875A445BABA0951238265D90B87F630530FF089967B50A1D722DDCC7BB1803E552463B62249B4454095A0903DA20077B045213B0DB8953340761A8591B042FC885DAA8A8C6A2985836C9109B827B804ED5C0E92B568B221618DF155C1535FBB128012CC27B7AA6A5A362BB3747712CC693BDABC919BCF2BE8AFE42A76D814A3362B5337853828639767BB7FBC4BCDA6988A7A933F68AA3B3CB7BADDC065EFA98DA09CB742BA3563E19E27ECCF6B68B94DD28FBB351220764BBD781AB884956A865BEC99C222E59295842EDA25C340A45275DAB51631B24BB86B70A2B831F171CE9222E350A70A1879ADC70D87888DB2B1C540C4666F7641EE36C30E733AE206B087084FA3BAB717D2C8761B78C20A31093BA5E923298AC59CFB768C527A3AA4D19D1F0262D6D4BEBC41699D152E092368FFAC3088D2488E6B177BF9045802579BA973B89A2404DB17DF25C546FAC731480D180A519A9309E28A98FE3B521C978DF1A94AED0A2AEAB5B971C995724189AFE7B3F90C5B1563A9187311ABE681D61834FFDC8A2142871CDB48096A25C0A315F12A627304206149312A4C647D1059A1F559E6AA3B4F22BA01AC09365718763A720D94506A39582E6400D93A19540690C94C9AFE1C5DF5B6716CCB4B80939698CAA521313A3B3AB17A06A8EBC3713944656A75BC95599A67744BBE79997B4153182372754A9D8238926B1CC239D5942E60C1B5D85FBF828409BBCB68E30E89180BF08083E94816DDA4AAA53267787880B9CB38E381585535C80AE47D226893889B5240DB1D82D926656541F3196BE9458A1A20A5B9B263BFC60670D6BAA7981672A4654FA87A37804486258403C9B0DC48054D312C52592DE43A41A3A7AEA934A72281807D26C10AEC91BBBBC8EA75B2B215083CFC94A12C61BE14CFCB2B688B097832FB016B0A60CC133C709B9D6C1734D4A100D3523F8F30C78F9647808B6CBA905CB4DA605A2B3FC3A433C916089304C868257BAB174861A8B57F6BBF6B79AB55A3044BE689A8E19F3D598F7453B3A71A06B29BCF3EB3819ED35D56B74A176CB9BC81B9AD94250E639C17F431B1C856B02C4D6579417D304F3C7B2A34579B6C09A866AC9D871ACFDEF3099368025F4109240372FEABC2D17A7E89031E67A74B68144EE1A871C8737FEEF4B9C663BCC9A42770CA4571A9B92C60AD14F53600DDA002509F109659F8B2A5A83AB6A1D8C3025C38EBE6346EA5CB11E66D560A9C656A61DE98407C130B1094C391A879AD70AE5DDC2ACCE2B42CCB378B9A9997D6042581230E6843E70634D25CA675E09947027591372E50FB42A28CC9C8E13693267305C89B7CA4CFCA931EB1E6137F6470432A55A08A183D1187BA7A8F78E6B960874001515EE15437BBB8157C382AF1641693B20E2DE25CDFB7C4BFD9A803517FAC4AC6BB960377F17ED89B216CC92EDA7B08A89505903659B94552ED2433D7D6668B226081691F4EA558F2B072AF6C50F1421CC8E1532BC6AFDFE7ACF2A43B34130FEA7CA5B1409AB0F10DFAA5A5F0E7B9A62006F1C53E82B5C7EA427009C990BF31A939EA2705630164445715BC5C80B3906739C46A4C4CF1024776037BCFB0716D1BA00110637FC177FA1768E73CAD8FA4777E13AAC74338513C516715B645E3BED722382950B132418FEE81639D448EABD55A94C66A34EAB68DDCAF1C756A4907BC3F5115AEAB5320F3B9BBE84E0D885FB784AF7FD8C1EACCB37642CF39C8A24C4903A7E80578AC7E9F2A95CD806CAA200E23873F751636CD606D819731CF1B812AFA2ED24381A52B4F5FBA658618A02E0418D6823E7F418294C81032936559A77F9C014D8A3B38DF8BB17B7A8C3B45B53AD60B0D9929A21A4AE3039366F894B1082DB5F3CF2F13381D53827B5A568FC5234E099D6B94BC1A013DDDE944B4EA13EB52BFA880716B1A10D8827A033878986155B7F2944A63A2CC32BBD61907125475BC09B0AB76222CB4C9F2E80A00F9B71BF9705E3576B5A96F6229BA1CE06FA1B2079CF66C59F30DFB88C1F9412B0B2AC059DCAB8782ABE57209188BB938D08BDA140A0EB08DE0DB3F8558C403C725A77AA1E0563A54A77F32AA30CB780F4E562716075763E9C5D470564EC12CDFAB424BA970C51201081193741A5E358CC7D63064A7183D99B28DDC5B0F10374EA9710193385B855A259130BC490041F76A9D661483AA668AACE51C616804B5E7C1BDB8762B73B39F17785AF94B355B0FED72083C2B71EFD1CD43C1A9704A93E0E5752E99A2EF115B6ECABC74CB03BC091038F5701659A0D4BC693805080D6A5C81A0273BE9149861C461C47CF496CFB22526D3FB8BA5A3396DD19A8477611B814B76D5C8191AC1C8190AC3B12065CA4CCC879D5F34BC4479A5C8D4693D8771B434C4B8E8B8AE921E01A131E9410ED11C505D226722E011F2073B0DB34D10C104AFC2656DD053E43A8DB7C00FE705B0BA520980DC71E834127C08077806CD8E82144D50448DD59A085776DAB69E42DB0E7E8CCFC010A140B50B50E09F233AACD3DA972AA40F1D1241D718B54B6009D3DAA090186CB167C1AB3979C8356397E598502422DA2935EDD9C8C44B90E8C50473119D26E99575C0C328307E2017B515F33D4D2821BF341480780B21D37FB6CC3049324EB12A42C9F7C9E086BD0F39A1949058F1D8C8F0739C23FB1DC542429933080AE732B750AF73B05DF6B46E0F27B678668F9450C193C861E7E38D65E5CB05A52F62B29D21B4B33D34771BCA88B3149ACEDA8553C5813BFA6F8A99C656601FD6F4CA7E54CF80E48FA144BD996BCF41E49AEC97734687A7D0DA2C71231DD841C8FEC9A8FB686A7CF81106B16735D6559424C1AE7A5A5F0515A8074BD879C1CBD6012A3B5A7079BBEB6229DE7676A876C02F1620D04905341C95CE512D20C4CA11F7C08684473A31313640760D24B4946C0268C108A8B96F699634414B070444480800C6C3D4BBDF339C47E9B1660B9EA039BCC6836A6FDA9489E76418047EB3E99D40AABBDBBA140221333CF1CF2BC121318AAB09022F95C31B12ABBE67469BC34CCB88C8A0A965902E47494C7A0BD573910A97377B764EA7443E73346EF9BAC0376711DB236F89A025D9B09931AA473AD04B351A00C5D3B969134F03C1745F672138F52BA47A542942C1078892CA3B9509F435D8521A373810B12393C8EAB18FE7B6F3F4AD7EA88B88B21DB46338ADAC939040674BE52E6C2948FD659935A86691F076C7F228BC5874FB8214ECE1947F68B057411C218B776A332F5AA351B4D92560A42346180EDB08BD57F5342773249FCB1F036955DA0269695A712ED852A35A3DE8662966C0B2C2038EA1AB7B4F9708C5849DBDC6A29E734CE8DB1F447109B755AF11976B73CB6C8594A5DE221C44B61B9D425280007EF4EC4CE3B34BEB733CC73A1A7F6857218476ADB0200D96658C8456576666B6D7C06DA03663191E649457D298B81B067789C285AF151FF4B97239C35AB8688A8D6B4469FCC7E42201D5D57BF3CB98C883C5C9C88F05555674E7A1BDD59E3F327B69A74F0D4A250AA89FE1359E5724CA02C38784A14690C62D891364B752ADA80402128C623D0839A0F09BD0E6A37B724070A4356641C538415F2A97701C5492D29A2F2823884496AF9DD06703D8AC2C17C4DDF5561590B63FF78C4995A31A18D861A91C43C5DEC3705C6112D81B81555F7A3B432F37E94DEF940045D3FD9DDEC0289680AE2F96D9D43F5D774A81B86AE7A4761AB2BB3EEAC4320F84D09CAD413A7D7C19C27668B2E0E1BBBA2D159B833DB6C0F50A", + "ek" : "F6581C38F9612A7F09363ABEF48D5CD274B19395C4C008B4257307C1D538343F9849E27128DD9DA7C6B92F4C46AF5E675351D3310AA3D1CE523E6B30F52AC1555F48AEC7B073D29100F7290F80DED69129770E62B9638B35019D00DE7D1D746FC5098A7A938AC595C1A7A3C50152FD662EF7F39B4EE0593A9DC04FB2F42D3A48A65B18BA9CF0DCD54873AEB92311B139BC6AAB5802B97F6B962C8797DE1BF4285B535BC06EBCF6E9B5DF830D0500347AC2886A3B4D8DE243F967507E94CC4C6540D93B884540588A374F5334C455766203192C56474201CC4B9F5C095CA2F750538F8151B96E5F06BA7A0EC894F9E97BD7D25EC83857A19568C3257A5F17C1533A471B71E8B832A1B71F5A287E0EAA4DC5C0AE136BDA4CB31D95431F6A5614A690C872D52537CCCD94142AB61718E30F6BB387C74C5FFB5EE00BE818DBAFA4A67B74CF4C0D3C9ECE309E98F61DE1A29D9E6699AE16068CEAD024A11EE86CB08BA324CB468D9D2016F62574304F85F85A3B582586D391988804AB6AD8AF38ECF15296B4865C86091142618B30F037DE5BB3306203681A660485FE5449481048B412CF96780D646C5656C7D9DC0F9722FD9E8F5EBB81974CCBB72BD66E69C0F5648EA73615A34740338552F804B2B856D0C59663504C3D82EFE3204586E942CB6179E34E723A52B856B3D730942C57949677FCDD56BE139E802D232E402B0FBC74EE55F7F15BFF5584369813544E179E6AA7B60090118A987D6DF2788AD35B78FDA6947052D6C907432774004D519A966A6FD741D56D86C66040EA0057E439423FE0726D8382CD34C4EDA3B5C520A6757188FBD9857187A4742155A1F44791A5B001CD599016B2E4D97BEC68A38A448023A32AF993AB5B623B63FB34485FE3A3FE4794FAA50E88BC4D1ED55ED784E1CCD1D900902E4B4D24761F531E81918A95AFEE8AA1031A0727C22701FAD67E9FB03E54A7572CEAF6C0CE1F36468056BE2A24752A4160C758C5B401CDFD40DD04766EA6428142796FCF844ED14452236E50563FD97C11DFB5386308E685D2887CA2A8939B621A7C1C44D20FF21050DCBA569386C9457A025C2830F639D279627BCFF5601FE39B986EFB636D57F3BAC3EB01CD643C2646695ADA693438F26E93EA21D7CCC7DE976F89E37DBEA211FCB800997D22F52B641517407E494F963A770FD8E7A5569BF88C0286FFF7C62B4C8E61F71D7E8558019F671BBA6C0A8758852C1310FF575A4A6C4E4AED1021F9F8EDCAE3007A9D925093E73E071BBF8E642CCE37EF6BB9D69A6A0EA0BE64DF4A450C332FA0F2E0049DB0F69A3F97BF70C6C57948FFC6AE8CFFD379EC8471D7B6B031D472BD03AB88A206010B3F9EBBE64B6FA210F3879CDA2B5FD6CBFD6736900E38FD5BCDD8D4D88C4EAAB41CCBBD332CE0C2BD83B57C86E9EF48CA707CA6AC80DE0BE2F4DD9EDCAC05D13D12030370563873EF5F56D25E02404039F063DC30B020E84A597D2429D3C527867D6F15AEA106E9384165F850B78C8B88FCFBC754A7BAB00544578F3AC5D16F5DC9E296E46B57820F6575B0B9C76685F2C1B29AB97D222196E3CA0146352D2E4371837BA52D76E4E915B9E17E0E9FF54066D56A447D26E210790D6CFCE69E1F1A766CC4A18F533C680018E35DA0450E5EE7966A5100ABEA6AB910600EB55BDDA10343090F995B96B4EEE34EA783D06C838F8452379BD4A65480250FAF7990BD34E03088E255548EA9AF938F745FE4578CACFD2697E7EB8732DE16F3812FED0BF94E259B8BC5EC133D62B87DF95B8D10B0BA6156D0D842C3562D3E98FD86070020BF2987A8E2DC104D5DAB6AE85A78808167D6C79B3E1B314DF6B7E4053162BE814CCD035612E7DEEB1C3CA992A8D1CA8724061FCBF403371EFCC2094E6FCFEE1FE59BA52EA47323ECC8B23A257088CCF9A4FA8A2830CC8FB1BA7F3410CA5CBA9FF1A65D51A41FFED675825C099BC78D3D7E82DE00CAD6108AB9A7869F304A87391342BC6A612CD8D5E6026735E984ECD3302780D7CC09D75B89DD9F0E6B544BDB4DEFCC317C0961FCF7763530B778FD81A5210DC26342FD7F6755C360FCBAE22F4793FF20004DBC828B362B3883FBE4929BF51EE9ECB50AFF78D4ECB4D83D588CA80B24E6E4479A8BD17311FCFD0EAA86E2FDAF70B3251C0622A35AC0FA64E814A471DB896456F3FA4EB2FCF873ACED8A1D40C1ACD69E430C71", + "k" : "DF4FCDADB283ABD4FB47B60FB7F2CBF8B415BAE7E2E0C4C41BA159A0EFAF6E28", +}, +{ + "rngSeed" : "5DA2C51B4ACF488C8BDED5E985CC4702E4A7BCB248B5AC18AABA529F7F9CBF30EFA776E99F76D5C1686E94F50FB57DAE", + "pk" : "822A87A132C0B9E3C13BB45E2EB5BB47535099E37019B3C7AC3B81C6225DCC65476FC12E7A81CC80C9A508E507F201632BE9C1BF27317FD97275CC3F481BC7C5C25A4B1462767A42CBA43B152C276FFC8DB55A96D418246E0BB7D5A15F0D883597E9579D675E816B8333097787C613CAC29427B11739E650CEA2CA8B198C0158CAEE9971894B67332BAF761CAF88C16BD11C9F1DCACE7B83A6BEC71F0ED9BC28F706C38B057231B7C330A4B99898037720CC88245F8982DAEA502AD30E315C2CA477A3F045084356CB81184ED90734E0CBC0D1553ADAF5A94C2A6D8A51566997C735BC45FC408241357DA2C38C8A0520FB5A33E1D5C06CC80C4E91314D08599763232517B501097E4BB09BF814A0CDBA619C701D249C933D143BBD92C163724B523BC05568A410952380177FF6084C6416BC22C637B7E1AD586324103677101A74835C4255B89EA1935EC8B8382611BD4DD91931C436F9A909AF4747DCE811A2ECB63F046B411A201D1B4F12442E73D7703E22896A904736308453B946F248A6BD11800797886AF555B0787D84DAAD7883C0E583A7B6530C7D0A8559906F0E423E9E6CB600B9917768777B7489DC173FC67551AD92A26B054DDF13C4F83B5805B9B7B9829513611E171B9EA358ABF9054DDF02629A397489DC213705A9B86735577493B86C326E857EB816663DC1417CDAC788900C8030803751BAE22292AF87CF8FDA4F2991418948C0B4F54C19163DC4B195B76CC5DEF67B5288BAD948CF214CC6A11C6E1AB1A5B9B1501BAA75CEC23530C091CADB8C9A02415E816EBE708422DBC2DB224B74BA1B83327C8B25BDA3CB7127F5C5B963CF3C9ABFA15C952BDBA2ACC01C9D377A89EAB6A96A65CFBA3D722B6618262EA78770D5FBC556789CE4D13BFE02065F033362124B84560F462C64443B88F3135F585A3B29E450C1DCBAA7B9181133C915522A90F56E595BA11EC3327E6A83C7F1BA59951C4684995EA64EDBB3451271A878E42BE7D763B27CC430AB6B068173B973141E0A72CDB185B263071D20A8F5A37DD08AB6EA7A2639E0CAC1790D5573053569ADDC1731A339488268873D89A1490B78EE404C2E8328004D44CB4521A68737F195634AB659B919A94E268131CA290E59756311B6273B5DFC2C3ADB21534609CB2FC553906A14D8C079F487091587943DF49A39D1B465952EFAE34D33FB9ADE56CB6CA9CFA8221458D9940D4BB5F044297C4160A2284032458BF909C31E47A27C7AABDC9815F1ECCCADC6288FDAA6C0316F2CDAC38CE89FB31CB81B673F26E5709E08C474CC41F213B0FDBC5563851BBEC682D9051A5D58148A72956721BB96224214D03E8B89021B98B9A0A87DBF15B491125BC07C6AB6353560D61814EA3CB2E72344104B06413F963091802413521441DA171E6B6B039391842141C87C991A4157B428E35CE499A805E2C0954457582B6A8F52C4E102BB33CB01D1BA883ED4CB126C2137A75AADCA26852223741C07B027A1883220CA9A65585A5E0C0847B9D0013F821BDAD0902504785E927016328C99CA1F3D2BAD906B3CEF04A3598B2992B2C587100533BCCCD15BA1AEF877C3A565CB352B7B856880108FB828B42D3612473970044C6C4A057F18EC13DEB2C398393C19383603C183B02A461BC9B8AC0969E04179E53C5A8F54A556F54218024041137448D08401FBA8E4BCC09CF3B91CC28ED9BB700CC74523C251AD3A7C21F43398F85C7941387612C0C76A43DB2A0A368101E88480AA1A5F1500B2A17B5704299D5639B477802FEF34BCFD548274D26C476C50FFF8851F29BA5AD66CAF066DDFEC2140DC97B83077A9E21BB4F87AA85A16A7107E3597A1BF4A5BDF008C14BBA230CC95E6071BF0E6A25607566C9008D715223C483DFD6737E25A2DEA490EB5606C6E32B8063128BCB6181166A93DA7626C4273157C47B5A2ADB1D88441E76EC9FB6EFBDA9FD084B496D5635794AA23A43A8C4650E05BCC2E415D775971922B1A446411F952B7E5540091A430882067C0F008211A705E4842789CCF653BB919E742B65339AAF4653E474C10583D9329CADC47A6EF20589572A2E6E4AD67D03ABDF7CE1DC9015BA94ED9C69220D63B423CB5DAF465D5E3A9D190A6C9D84FB28141F28990959250D48162C68B813460B04A78126E4B2C4514D83CDA2735E3D3F1889578B626B002CD859EA9BA6FC856A8030F6010C780", + "sk" : "B212C7B33A82755496CAA9B591E69054A2808962AA4B703FF72B8F7EE2206F4A7CB77262DD34C791E095CC059B1E00A474E5B60A3A8B2B77B0B6A34968F02A67133B5F93C96E94657C8995AEB2C6706A1361E7370A8072AD3713F56C6AA32C19E34278FD2C397E84905813B10FAC77595A624476C9BE5A06DEA927614C8964C9300F6CC7D0E974E334540B60C48868C8FD99829A0CA9743522CC88B6BBFA77B9432B9C373C07573C5477A339697EBD8C4C2E087FDE72BF826B001CC7B3D3F7B05484193FA38982F3CE0488182F59CEF992B82C6039218829E4E4B1C554A9AAAA301F4733C0540FC2C7ACD1A13D9FA0BB6DA18F1631C5FFCA65BD9519FA454CA76C1B8F5C8F41037499561ED02252E4E408AA352AF4155A9D940E5FB964A57117D250556CB9BA2C888CD877083B742428EA6B62F0208C862A39DC6F9D6671965610D69A54D10ABBC1238931777CEFA00461EC086B26CA2DEA34E88565A6A89BD1A138178298CACC938135AD58CC98FCD29851409A3E93CF0A270F4D8779B5F7AEFC2143E0E082E8E8B357B84AF630364538B19B55954EDCB3F250A2A53CBA04682065846C0323556F154B97B7973D267C1678A02D1B2F168977A142BCD492509B46A6BDA72255510EC952A50AA11907B42B62694F978539FCE0CC35079A4BD164FAC25C46737C22540803D4A04F54824AC381EAA5AD5CA51568A8C256762A1021A8C46142E0A99F16DB9CFF371317C602BB08B275269B312411AE849C2C29285CC98D1244A346497FF59C9143A3CC9481AB5AC82CCC86C2D38512BF901B97D83B518AA0812AA2C6E3C2F8DA9E8CD8154F299FC8BB52E9BA96A4AA264F8B828FE783CA4190AC42A56A97C0E6D88ED658B6993399E47127040A44AA539480131B485318FFE6A598570139C06AD4054B70B6991FA4B82E59018B7A206F5595E0A2456FC122EA8828FC3B75744650B2AC1A248133BAE700585784A1949CAF7C58BCA497B0D03569127C6FC88B407268CFBAAE78E779ACF25E9C9767BC691EB0969F69988D3AF98FFDA60B308A789B8C985235C9D694C6F0E1425CC1782A921B11444E54E7A94819021CC1899439A753A677913970F470854966357569924CC5AD3E2210B6654193A4B2F145782C9397C2C6BF8FC14535149289B904A1F628A45B2CB0E66BD955C3C153BAEED32A71673067F7262FC0BD6385C6CC00793528B9CF021B339C179A157087864F70D24CAB938BE046CF3E409E01FAA10E4601AE47B677B670B11BA1EDCACB5B292908588554A8B9F204AF840A2D2581AE916652DB5A71E36822A37B6FFDD3664B9AC253ACBA6187211866B25A46B62853878BA777A5156948E52E0040BC63F120644A8AE466591986ACF5C1C41B77B562A2504C0509B411A879997491C9C25CA38AA3D62250CA5267854E1EE9554E064B4A6181958C50B11708A348929579CCC09953191011FEFC0C6A2242ADC09ECDD29D1DE974A2D3497D904BAF5494D4F96EF5FA8E86E45FE4F0C79BF3861BE98B7177093E9312C0F77B88F23FA62BA2C6F93255131F23E9607F3BB54C8888ECCB2E01CC22BFF2384BAB57FC2C62A8D47F73051AF951C7EFD63C0F0A87D29460402814E85602997A765A3597D5A9099B99A37D2817E827B76EB4A2DA2622F516364C525C69586C8E5729E3309925FBB3F9E86717503D04682FC5D83888B96E00BAB9348C426CE55977A73C40EA2315F122E724A17252317AF5187C290A87E6675E78589170454DF4B800D2546F9A33A288256669C09EC63E49EB755CEC96A542B49ED0365D6130EF2051B9A0C42C675302453EE7EA854C1184B43609A0B25F30164269479E6F2BC7A76AA758DB9709204739CB3378DAC80F54C665EAB7DCC0BE9E8186349B9F2E2BCDD9E2AF7EF03CE65C62E2D798FE588242F990CAA7650B5BA55897615A85AD2F96906651BECADC7B53B38DD74962D7E6CC79D68F7B273452AAB4F692018BC60DC6161E36E8B523B3B349F6666F4583855998D1F41F9333194B567B9B3332D8E93FE30B8E19813BFA0ABAED64106D147495A6ABBB4909E7AA06970B2B20914C51A5C6F1D9894D911038600BF22268B58AC4D8B8BD07F24DEACB1737779CD5B328DFC251577846131392D8533E70D074FD50841698BFB584B620A100B09AB9AD6C60822A87A132C0B9E3C13BB45E2EB5BB47535099E37019B3C7AC3B81C6225DCC65476FC12E7A81CC80C9A508E507F201632BE9C1BF27317FD97275CC3F481BC7C5C25A4B1462767A42CBA43B152C276FFC8DB55A96D418246E0BB7D5A15F0D883597E9579D675E816B8333097787C613CAC29427B11739E650CEA2CA8B198C0158CAEE9971894B67332BAF761CAF88C16BD11C9F1DCACE7B83A6BEC71F0ED9BC28F706C38B057231B7C330A4B99898037720CC88245F8982DAEA502AD30E315C2CA477A3F045084356CB81184ED90734E0CBC0D1553ADAF5A94C2A6D8A51566997C735BC45FC408241357DA2C38C8A0520FB5A33E1D5C06CC80C4E91314D08599763232517B501097E4BB09BF814A0CDBA619C701D249C933D143BBD92C163724B523BC05568A410952380177FF6084C6416BC22C637B7E1AD586324103677101A74835C4255B89EA1935EC8B8382611BD4DD91931C436F9A909AF4747DCE811A2ECB63F046B411A201D1B4F12442E73D7703E22896A904736308453B946F248A6BD11800797886AF555B0787D84DAAD7883C0E583A7B6530C7D0A8559906F0E423E9E6CB600B9917768777B7489DC173FC67551AD92A26B054DDF13C4F83B5805B9B7B9829513611E171B9EA358ABF9054DDF02629A397489DC213705A9B86735577493B86C326E857EB816663DC1417CDAC788900C8030803751BAE22292AF87CF8FDA4F2991418948C0B4F54C19163DC4B195B76CC5DEF67B5288BAD948CF214CC6A11C6E1AB1A5B9B1501BAA75CEC23530C091CADB8C9A02415E816EBE708422DBC2DB224B74BA1B83327C8B25BDA3CB7127F5C5B963CF3C9ABFA15C952BDBA2ACC01C9D377A89EAB6A96A65CFBA3D722B6618262EA78770D5FBC556789CE4D13BFE02065F033362124B84560F462C64443B88F3135F585A3B29E450C1DCBAA7B9181133C915522A90F56E595BA11EC3327E6A83C7F1BA59951C4684995EA64EDBB3451271A878E42BE7D763B27CC430AB6B068173B973141E0A72CDB185B263071D20A8F5A37DD08AB6EA7A2639E0CAC1790D5573053569ADDC1731A339488268873D89A1490B78EE404C2E8328004D44CB4521A68737F195634AB659B919A94E268131CA290E59756311B6273B5DFC2C3ADB21534609CB2FC553906A14D8C079F487091587943DF49A39D1B465952EFAE34D33FB9ADE56CB6CA9CFA8221458D9940D4BB5F044297C4160A2284032458BF909C31E47A27C7AABDC9815F1ECCCADC6288FDAA6C0316F2CDAC38CE89FB31CB81B673F26E5709E08C474CC41F213B0FDBC5563851BBEC682D9051A5D58148A72956721BB96224214D03E8B89021B98B9A0A87DBF15B491125BC07C6AB6353560D61814EA3CB2E72344104B06413F963091802413521441DA171E6B6B039391842141C87C991A4157B428E35CE499A805E2C0954457582B6A8F52C4E102BB33CB01D1BA883ED4CB126C2137A75AADCA26852223741C07B027A1883220CA9A65585A5E0C0847B9D0013F821BDAD0902504785E927016328C99CA1F3D2BAD906B3CEF04A3598B2992B2C587100533BCCCD15BA1AEF877C3A565CB352B7B856880108FB828B42D3612473970044C6C4A057F18EC13DEB2C398393C19383603C183B02A461BC9B8AC0969E04179E53C5A8F54A556F54218024041137448D08401FBA8E4BCC09CF3B91CC28ED9BB700CC74523C251AD3A7C21F43398F85C7941387612C0C76A43DB2A0A368101E88480AA1A5F1500B2A17B5704299D5639B477802FEF34BCFD548274D26C476C50FFF8851F29BA5AD66CAF066DDFEC2140DC97B83077A9E21BB4F87AA85A16A7107E3597A1BF4A5BDF008C14BBA230CC95E6071BF0E6A25607566C9008D715223C483DFD6737E25A2DEA490EB5606C6E32B8063128BCB6181166A93DA7626C4273157C47B5A2ADB1D88441E76EC9FB6EFBDA9FD084B496D5635794AA23A43A8C4650E05BCC2E415D775971922B1A446411F952B7E5540091A430882067C0F008211A705E4842789CCF653BB919E742B65339AAF4653E474C10583D9329CADC47A6EF20589572A2E6E4AD67D03ABDF7CE1DC9015BA94ED9C69220D63B423CB5DAF465D5E3A9D190A6C9D84FB28141F28990959250D48162C68B813460B04A78126E4B2C4514D83CDA2735E3D3F1889578B626B002CD859EA9BA6FC856A8030F6010C780EE3FAD17B073DDED30B6531F854523002DB21673437AE275E8A4D702EF311619A8AC144DFDA421DE1A7ADDC92ADB79BBFA9657F3DC4B78A7335F29DB87B290D5", + "ek" : "506998F1B83A5D1CD078D9B77014E066305BECD4A89E60141CB3ED91BD73A3462D8A13034F799C139072AF2A9224EC4C99C28F9D418B6CB5FC5D9317DA45B78C6EF3AF5101BC8A41C696F1C0FB2A92EB46094A5BD3B935AB1165CBEA06D17076542AA44B6CC5892C41EC19079E48107CE742D7B8838247D6D33D9D96C110E443698298FDCAB4A1317B3EA77BFF1C4C9B6D9FBBBF959906645450807DB40D4702288DB8B4A277D9F90A59C0182927127D572297BE182CB4F73CF39E4DDBE19E597B7140856CD04F01EF48D8B9CC261EFA68BFF7C5AC62353185E2C9B8FBE4BF5F97ACB93623D753D8C5CD04953491A1ADDFCFB286DCB8DBA7DFE56AEA5F1AA1EACE64A0DAAE41146D46C5ABC66670983FDA68D4D81B2FA4673B204D7BBE95DF4B9E14BFE25999125A82D4A4F347E24B7AFF995E65ECB7C5DC71A8D1ECDE97833CBD9602B64567411E8CEB8BDE64A556E5A0ADC9BCE265419D13B7BD9F191BCFBBC26A64726777A79B2F75DE40E7E27E07674ADC50B688BBADD98626A0AB833B3C2A6C39DACF4DFB098FD95C73FB9A01C9C4209EC750F8F03B27FCC4A211ABFAC8FE47754498C646BC3E966745F1D6121470B4E72DBAAD75F96175C35C839DA4F2B1E443075B970ABE2D32C8EA5B5BED69D1E49AAFB8E678200ADF8E5F3988AC41836F8F0646A8C5382DBA923C431633BA8FA1A091F33614E982FBAE74F7E89ECEF37073B75CE0CC3E6F0A1AE85B8FEC03F2AF5095FFC5758FF6915A60551463750830191043EC2E9A390081530DFD758CC55D866570898B70B620753C50ECCB1CCE11A0056745BEFC39988723A14CA9418D0BC08521E2881E31C438E1473E7489CE3C0B30DA5B6474EB9B4712F21F76019628BB70799BF67F7F0C049B4FC4755358C6AC8EB4BB4C7C7FDA8DA2C5C2DD21780F561B68D294BB7A497418DDE8F3EF1067A6D1354CE1C459FDBE0D3A8F806330FB29C0CB53DFFF57A7E82EC6ADCFC555535FF0375F00FEF5551FAD797B967D2882702F86C07A5344EC0F3243DB57A76C82ED62B184D34B1FC0135E3F27D9F1476946CE7FCB7F69795AA5088CE75E4D77CD14D9712B873705D19790D6E947D9D9FD9E78CBB7E9751DA10E4265BA49FF26649284998EF3C156C10BF449F35A9A05992186C97CFEFF68F0C61FC72ED5A315D184F6C832819BE30F3BF542115CB1904F9A57CA1224BB5BFD49F6701B19EA40329719BD6A602DE80CD823C3EFF5F7356BEEA9C75C316E34BA61412A3491311006B4286D0BAC603804B98FDBDBA76AA29A068FDD8D4CECD644ED16B6F4E97B162A06142B46FBAE3CA8482452D32BCD7882EF67DF4818312807148F0FD935B587584317208A2F6FD220CFF63830D1595044333743ABC3EA25C1C2711FD4BD7B3E8557DE1746FCFF6AE3BA4B3FF8CEE6DC87001E4A3E089D668CB0CF10DA8BFDCE4EDF64DEDB2D204AFD82B934B747479577F0C299F127B41FD0F8C537CD9DF3D581076E65B15E05F6D4CAC6E590DB95C449A5B9D0B41F63387853205E5D089F0CB59A348AC6337BE59C31A0B44757111EB1A4B5FAFB21A864DCEABC40EB73D63F5717B9C41DA24067D4B54284B0113CA5C5D7C8312FE8592946A78F56C7964B7C5E3C9514A4696DC21236C2AC1755D896905DDF4F897967B6B136B0355480B185958AB3A9B7448D9239207FAC6DDE57D73187F78C621627DC2A736F04C20A77707BAF0F27DD64F297729A0D80BDBBF8CBC78CB0AAB14B3FE9F340ACB8F8786A91EC3FB43A32AF992DBBDFC190CA3DE2A91CF6B63685D455DBDEE4E6F9056844D3FFF2D0723B08984D593100F14475912A441EF52F93F80020A1A96CD8E218F67959CB48ABDD563C6AE0AFBE321DDF0B9D80CAB19D97F4616B524A0EA4571B0BFD75B6D7E680D91841BE538D22D2FCBA8F84DFD7D6E9E1C158FDEDC00A5F38F1D2196DA7448FDF38304D0D529744F8B240DFB99BEE18BEC1CA3842F35B9CB3D38A0381A0D28AD5B584948F59D4E6194182F82A4DDA19F6F26C1EC66B83EE710C95D5BC20D6D3ADC2B4D344345D4DF3559CCFEEDA2D3E04EF9B06CD1D7051166D44BBD1D16900CE30C78CCEA0FF63BBB37FD7ABC59C4C94FF586F60811240FFDA3CAF0972B12461594812795B76490095290FDC2B86F3E390F9883E374ADB88489C863A1AF76FB47D7E2E6FD6F98F635D1CDB256DEBF5C829A112216352731AD1", + "k" : "2E4358BB91340D7A483A3C4E5D1EC84C3AE583DEEBEC3E600CB8B9D7F2643F34", +}, +{ + "rngSeed" : "4D2239E84B052109A78DBAB6D80C51A86D38248105970476B74A0B78B9CFAB6283E30D5A406FAE1C7F54F8BAE1110EE4", + "pk" : "B9C82A0DB31FB3C6458EF4C21B5663EF7795F4C36AE77A85ED8304A4066C48741323EBC5E5F50D50A704DE206C4F6A5719B27B8FEC3D95E77F545A7F78C57A9432A329741159808D255232D4288032D658BC483D4AFC3D6BA94F8BF44B347A8FD4BB7E2E4000DB9909C3720920A410A46905D3A34083C3484BD2448F232ED825658A8B25D99C995BE0866A18C01274607AD6BC0154A4FDF70F42768A5CA86DF321327B89094383648A236D8F74BD3E3854B110AD8D1403E428A73D9A13CF29A6240C30CC53532D60152FF560D1E3C3205AC557FC76BBA0AF547C69E9819D1CA412088A8665863F64CC98F3853E2CE115C4C3080E002542714EFB10B8F51A59AB954885B313AF6000FB8C0B23BC59AE73948E8B30213C84230098469200C8D3AA1F68160963B4DEC95C20C8290783457C06B7ED61AB17077709591416A422E52A2AFA2C61EC4932DF188A4A0C056DC854ACBA8ACD5298A6CB2DE04C7C3BC7BC724157FA2B9D01C9BCB0624D79E52988A4B783E8A6D7C45115C548E0EB474368993D971E59E96D5C2A9341B40F461752DD73CBFF7543031CAF370130311C458684A80209565B754437926BB20840AAC329392CBC4F7022EEB03580696B239B2993C9927F649AA838C4E88726F9633B8630977E85350BB25C130161B6C0298C03BCB387C38B4853CE8258166175623107F3D4C5A4B266C9978154E710F11337F05986E921B20D1C02D0667B42D1A4F09231D7D8993263A2CEF7B3E5F153AA691A12B7AD28513EBA123945F0651B83CD36099047B997DDC5128325213875AB7AC39B6E969693C4746F19A159B19B7911ABF45A9215F5C9EBF60C46F254C27285E9491486773CA0F8848E23BC16D83155C302D0E42504762226701BB3A446316B9199860B824C1BB5BB2B4F535E74C493A80B3FAA5B635D65364FC241A2E1366F3A2AE40AD07E6621EF64428FFB6C86A1883AA20D04B610FFEA3B48E88E6073005E281E91D65CEA99079E1846CE89C2FFFC8CB38932C00783C9812D26F91937E6966DD2642BC1B494775F5ACB46DDB3BFE70C62E2018CDA8B16FF762EC3944909D034C27CCAFD2803E4F392FEDBA006D672021A8EEC76CD2C5B1F2BB65737A5369365C8FF6231B7866973201853D7538B27825592629C7812DDA74B795CCC56FA684E8244A4B204C0B2BCE93100A57C02DD13C5AF5718084042E9D809EEE01EF78166D5579FB0702DEB07B6708C7AE2757A004D2CE31921030059C36A014DF0178D59C7A7A7B1C3E04BFDCA8AD4697BC2A36B5A213900249CE02A678009A4C9F8589BC24810E611A942AD468A2AE2D8AF0B3B3A7D741FDAEBA89F3B6C1FD302DAE37F2D54BA53FB78E040991F4C468BC2B6F527CB985A9AE19797CF845C53803D13B267C8F31E4382791F0A7ED27A96AC609B40C8BEDFB1A11D8C244CC85F4B692607D72F3CD05B070B5E8F4B7E0BA56657434296CAAED3928F32D526CF0281A57960E5C55F6DEB1636494E3D618D1E4431FCE125ADF544B91904CEF045F1D088E159A6CFF792FF5182386A87277953B4C4BA3714C20BC50E04C2B2B628B147D07291E24E18A6906B5300393180ED011B2C458D7E2A1F4604816A94B83C93C5160B740E3640707A4FE8F265BA351F4FF2C7FB75BAF8980F136B2BA2E81CAC3B27C2653C89B65CE236A3C0C28759B12275C4CDDF5C14C7B69E951BB30459B150983FBC330DB7DC3220420DD5E928EF5905A78A0B0E214BF1252765646F6C657AAEC11FA775183C1CA3BB7261A2205E46D064239103203532556CA7FBF750D1F88ED6862ED02489BB30C976B4ABFC0123583837A8DB3F6A38BC5E9A44A990A471CB3E380B4508AC4162A4073F815507D33FFFEC823F9CCF17AA150A5BC7562A4E3F85995444C787D16901332989C15FDCE4B43A215DA66000525AB32F5B1D728846FEA3AD2C092E271208B6F833E51C701DA8854B867E0BD0234A3C9D98117C58AC1AC8B05F59F027B4A78E94771EE263792CB891E9D5ABF0706F70F149482948EB6248BD811210765F93B4CD49DAA19A17843E510409D6638DDA571F680F02B17182E1C7EAA542E990275BD080BCA0C793D3113D524598FC9DBC453A0560C556E7BFA3856570B570A1B43F82657458615BE5080C89C0BC7E99A67A91BB9B8CB821E426B843F7542C5CE12CA13B5B7F6C716E63411681FEF0FF85E8CD3FCDE5ABDBB9E4", + "sk" : "AB6656E1C10C6071C28B24C6461336D91C7B5FF6CB9C97AB265215951983F6530AB7DA57F0E4967321866AB70204396CAA7B9917C9C6E082B331D65FD1EB300DD481311B723C44408A1B1F9657B19BB73AC593A3B2A86A1DE53F2FD150ABE7620FA9B061340AC23AB1CCF45914170AC5553873873FD0175B79D500C2E92AD5FC71AB348522C5C82B81C89303ABDF684EB9F638A2C502A088795CAA954F9255EC8389D0097D768133A7340857534CCE37B7372388507C8DD9908D01A62077DCB583A5328238A097A572B800AC1E3A4B02080EDF616072229B74F4078D99018EB6191E09C5D498A32CD04E22398604479C85C61436606DC6CC4256611FB8D0C2A4F83FA160C1E7810E558526140C42C2C111141A3A24EA7400E44E3A472D1E913E341B50D88364AE301F4917AD1BC94CE43027A2435C6EA9B979CB30D86A856BC69928348B52B36915684CB5B02C23B00B8FD68831D593338B07AB0316BC3656E9B58B4FF4969FD461AD72AB05754399E39E2776A08DDBC25E4A8DB78A279575BFFAABA7B9143C337888E8F524C163C059F860187B2CF674B6FCB94B480A859A2B7AF7066BE0111C94510A919739757470B1A25FD9EB3143CC66C7A2A0C4F9AE57AB26D9481AAE956240785043C43BB130C25BC10BC9956A930C009B7A08839CB483C73E671C29F2609667B49E52C79D494596A668484B5659C90965E8222DB617CE6E18C94CB80AAD565206C930CAB57E8040CF6D2C1BD4219BDE58538BD71EEEB1CE8AC9BAB801AEFD84406D7233A0A21A68D48FCBB10892F71A7B98110CB780DB9B07B6E53339E3A0AE3921A0F85C4DC282C4874B7F5A56AE059EE327BBBF68AB3CA84E1E72B5955CC3CAA12B86E949025A7BAD520ACC7037E97A51BDE797636C5EBAECB671F68518756207327F8ACB9594971E7EA07030748A87D674604B2C53B6CDD6F16A0E4669BA37A20477B25EA47CE56AA81F100BC3D4392E224AF7984D59F0570E9B020A698409E8B119425756A678CF6C98CF814BE4E02BE4D1BFA9DAA20B91A934DA2B18A9CD294808F838BD21A93189859FD6B645F805B8C2CAA10904697189CA2A90BB8C9431C14372FBE552009067D6097B11246C4D8469D01C470509079183082E6C10784A5110B93F450A8860134514110079393F3BC45A2442B59DE6B37896BE3A54553FCBB72CB10755649341699BE44488BCE835CAEBAF9F8A017437615D6409B576B90F8021DB6BABE5C10C0FB159AB9060A0744837631046D04930EB853A1970BC34734BCB327721B39528C0DED4226207033AA18A3171B50F698035282000696C9BB14A6617AE7453B608893BAB7B385E87CCFB83929CB968746C5196AC7C46423F4B10AD3DDCCF8F9616DEF05642E22E15E15B5827B850249434D9088896CDC45B39582C3E2D7340650365C929546298BEB4FA024DA8B3886A8ED6699BD15BC645DCA53DC792458470395BB64CEA5BD9916A11F5920487CB60776F3FA1B7E6D16007A5322E92410377C874F98BDF32066A136D8221B95474A240247BEA21CF0A572CDD721AD9C98F6A248C33A20CCD3A6965133E6E47055B5893D8DB26C6B77754F441BFE7439B8A5269280769247ADF0665D161C88E756DE537BF5601B248E9632886C84B572AA542B53F25001586C60EAB6E1CBBA8B62582EFE41CA212874F402635815611F09AB9CA4CE29B6FC665478192452D667228F17D1500D0A18574527A3EA92BB208E037722684B2F14DB7D7CFD11616D9A528E0D54CE197B16282BB2A2A778B81999BD38FA2D86B071B7D47DB2C7B3B3AF53B4A8BF7051B38468E63B2728003E8489D33CAABF3BA196468ABF982452F7A261993BCD3941FDC59A60EE24D19F060D7E493C29CA5A7510918B918EEEBAB86DBA7EEC12F233C0B0ADAA65CC1ADA2D64976C0399DC8092D5C3EF0774101A01F6643CE8BA0280356CBEFB2C2856CB6021768564342287A9952B1C2DA5928520CBDF6D8A970C4AA776C60D7781107AC9DA66672DC0490CDE4B38DBC08422624E50B9B3B775C8806ADCEC9A5A2D94F56D488A8AB8F90B6930CDB8FAC4AC5B17B66C6B1167C981A55CBA0C8079D1668AE51F32A62D4513165B275097597E422FB3CCB4BFCBEBA52C0B028A01C94C4A192B9F1DC4F584328CBACB263B5C71C145BB9C82A0DB31FB3C6458EF4C21B5663EF7795F4C36AE77A85ED8304A4066C48741323EBC5E5F50D50A704DE206C4F6A5719B27B8FEC3D95E77F545A7F78C57A9432A329741159808D255232D4288032D658BC483D4AFC3D6BA94F8BF44B347A8FD4BB7E2E4000DB9909C3720920A410A46905D3A34083C3484BD2448F232ED825658A8B25D99C995BE0866A18C01274607AD6BC0154A4FDF70F42768A5CA86DF321327B89094383648A236D8F74BD3E3854B110AD8D1403E428A73D9A13CF29A6240C30CC53532D60152FF560D1E3C3205AC557FC76BBA0AF547C69E9819D1CA412088A8665863F64CC98F3853E2CE115C4C3080E002542714EFB10B8F51A59AB954885B313AF6000FB8C0B23BC59AE73948E8B30213C84230098469200C8D3AA1F68160963B4DEC95C20C8290783457C06B7ED61AB17077709591416A422E52A2AFA2C61EC4932DF188A4A0C056DC854ACBA8ACD5298A6CB2DE04C7C3BC7BC724157FA2B9D01C9BCB0624D79E52988A4B783E8A6D7C45115C548E0EB474368993D971E59E96D5C2A9341B40F461752DD73CBFF7543031CAF370130311C458684A80209565B754437926BB20840AAC329392CBC4F7022EEB03580696B239B2993C9927F649AA838C4E88726F9633B8630977E85350BB25C130161B6C0298C03BCB387C38B4853CE8258166175623107F3D4C5A4B266C9978154E710F11337F05986E921B20D1C02D0667B42D1A4F09231D7D8993263A2CEF7B3E5F153AA691A12B7AD28513EBA123945F0651B83CD36099047B997DDC5128325213875AB7AC39B6E969693C4746F19A159B19B7911ABF45A9215F5C9EBF60C46F254C27285E9491486773CA0F8848E23BC16D83155C302D0E42504762226701BB3A446316B9199860B824C1BB5BB2B4F535E74C493A80B3FAA5B635D65364FC241A2E1366F3A2AE40AD07E6621EF64428FFB6C86A1883AA20D04B610FFEA3B48E88E6073005E281E91D65CEA99079E1846CE89C2FFFC8CB38932C00783C9812D26F91937E6966DD2642BC1B494775F5ACB46DDB3BFE70C62E2018CDA8B16FF762EC3944909D034C27CCAFD2803E4F392FEDBA006D672021A8EEC76CD2C5B1F2BB65737A5369365C8FF6231B7866973201853D7538B27825592629C7812DDA74B795CCC56FA684E8244A4B204C0B2BCE93100A57C02DD13C5AF5718084042E9D809EEE01EF78166D5579FB0702DEB07B6708C7AE2757A004D2CE31921030059C36A014DF0178D59C7A7A7B1C3E04BFDCA8AD4697BC2A36B5A213900249CE02A678009A4C9F8589BC24810E611A942AD468A2AE2D8AF0B3B3A7D741FDAEBA89F3B6C1FD302DAE37F2D54BA53FB78E040991F4C468BC2B6F527CB985A9AE19797CF845C53803D13B267C8F31E4382791F0A7ED27A96AC609B40C8BEDFB1A11D8C244CC85F4B692607D72F3CD05B070B5E8F4B7E0BA56657434296CAAED3928F32D526CF0281A57960E5C55F6DEB1636494E3D618D1E4431FCE125ADF544B91904CEF045F1D088E159A6CFF792FF5182386A87277953B4C4BA3714C20BC50E04C2B2B628B147D07291E24E18A6906B5300393180ED011B2C458D7E2A1F4604816A94B83C93C5160B740E3640707A4FE8F265BA351F4FF2C7FB75BAF8980F136B2BA2E81CAC3B27C2653C89B65CE236A3C0C28759B12275C4CDDF5C14C7B69E951BB30459B150983FBC330DB7DC3220420DD5E928EF5905A78A0B0E214BF1252765646F6C657AAEC11FA775183C1CA3BB7261A2205E46D064239103203532556CA7FBF750D1F88ED6862ED02489BB30C976B4ABFC0123583837A8DB3F6A38BC5E9A44A990A471CB3E380B4508AC4162A4073F815507D33FFFEC823F9CCF17AA150A5BC7562A4E3F85995444C787D16901332989C15FDCE4B43A215DA66000525AB32F5B1D728846FEA3AD2C092E271208B6F833E51C701DA8854B867E0BD0234A3C9D98117C58AC1AC8B05F59F027B4A78E94771EE263792CB891E9D5ABF0706F70F149482948EB6248BD811210765F93B4CD49DAA19A17843E510409D6638DDA571F680F02B17182E1C7EAA542E990275BD080BCA0C793D3113D524598FC9DBC453A0560C556E7BFA3856570B570A1B43F82657458615BE5080C89C0BC7E99A67A91BB9B8CB821E426B843F7542C5CE12CA13B5B7F6C716E63411681FEF0FF85E8CD3FCDE5ABDBB9E471C37CFF80F992F3359DED64B566956ADFA3266CB05F171EB644711D3A2CB4B46EDA18027C6709111F1987E026A481D46003AEAF2FF23B675BC349C749F300C5", + "ek" : "9EE98F0817AF2FE460060EA02CE155C00B1BB14030313C1F126BB5F3ECFA5092C6CD92E06ABD47AF48877D1EF5B5448462AC412125D9DA782BFCC6890629DE061572BEA0F4B5840D288426B685B61041FDA65A19F2B1910262927659A915ECF97E41788B6BC3A7CBC28C145D68935234F466E32260294581592D076A59F48FEF88258CB712F1A93EE7BCE5B81286E9E86CBDB6AC89A906485056A072A251AE70EDD6C6B5E0BDC02ED6B6316F0C490D4D93C281B2BE14E426B286CA5A49CAB20CD5C2103778C05F027E5254D6377BF908BE045FE46EF7FB1BB71AD4053BD59E88EB2112D6861980EF9A5B8C5DFD715FDC2BDA0C9FBB53B9C90CF0A9A43DF4BAF94A30D8E105E1C2B765294A10B872F51AD09663DC6B7531E4B968CC11A573A3B192009831512B50557CED412E8194D42F3DB4CFF79E0D163A15C52EB97EDE001035F9F1D89DE82144192ACFC69487D8FB85ADCA3025C6D6B4888F2C8291BAD250E6978CDBD766B3A1A4746383F43A86A12FB43C71407D23F356348869BC684DC98057AC86D3897028E346FD236FB02DDCA4C1BD7B6425E8AE37814D39302E95C8A294406BDF36777B24878DD9B855BDC48E196364AB28697433AD5912C66B09AD1A1E821478FB1E8C8D5601E65790F803D1DFF0D4CDF050D5A35F23B4BEE769DEF126933CFE03365E8F960F0E5020BF3562671BE32B9BA46DA8540BBA99580C1D8F5F3F5E0C176B66293F0C84B6DB16E37EA8865CDE94812CD0F4A90C4EE1DBB0FA631484B772C85CF6CF2A74F8E686C23CA7622026A92D7897990F062CF8B94F44C47C9426BAEE86EBE46F0068ED34B0C4EFE32BCF866B04D5166DD9824BE1B18D570EC00E1158729DF688BCE202F5329E9EE83777A15CB68B2F971ED8606EE52257881B1955C4F549E1ADBEBBF7E0C28F304B87C1039302804469F1FCB9810D53FEFD4E0696143BDEE4E655660A2E266CB83D00621FEBA6F3459FF7FB5CE024DD0BD3709531D93F0071CB1D8B79D5C6969C5D932BCE94779AC30FA545AD43BB2CD07A4C339876A45DB60CF5AE6E161229A8D0B74B4857A6987B388E7629CA50FAD1C8839580503877359E2B20D14403DC286EBBBCC4FADFB41AF311D2C19426694228BC70FAFD0F78C94E4FD6665A0701B30D004F72B68FBBC6D6BDE4D60FEBA262C83DA4CD990DA38B40904310748241A4CEB4AC8B01E6EB5480F878BD1F489F9C34FE1D6F7B1FB41C2CF9BDCD2B16C9D06F0B49F757A6F538A85F03D4C6198587A9D1FBC567CB458FCA2242D78E4F7D0471D257612A3C4BB1D9F8961EE4B312CA8E1063E4E62D5BF623028F83A04A5582849A53FD22D68E1C5F770DD84AF4D82A28C16950E3C133BBEFB9236DD951AA04A6F2D0C9851F763F4B89868D3BF4AB073F288CF87527DF5BDDE3E319BC54E17001BF09A3F9CA75219A4419A9342FCE84F6D16CFBE9F5719A1BBCD2C6D2AAFE55D97B65C258D2EEEE937EF08174540C886EE486C4F580FEE3BAF61C747BA5F7EA20C6E507A9EF12240A1906B8E695612AC6C5F46F53BF6A03A86D53835968C072BCAFBF44C58BFC56C704C556629D6575BFA8D3611D4E0F3455DFD35959A66F92BDDE79F2039A53BBE05BE23A332D3834BD561D54DEF764C7E2FCBC2D24FB56EA2551E8A5ED13076A237A672D1F05B8E2F1BE1E572B0C8D985E03247A78C29344516945456FCE6F8C4E7F39EB378E22C78954CAD093B0FC6F126D8D4743BFC80216E3DDED1618BAF60E271706A78EE4695A4F962485142F1E0431523F8FF3E84AC96C945E24C1812E59B067C8A31F722B017D6D0D9395919283321988BF662C1C6BEB2D2DAEE135328F8ECE0B050F75E40A65F0071F5816EA35D8B3DC76DEE23869E45CB7D99A26D36900963F127B8850C2299E5F82A1390CE41C6FF1A2FF47A186C00E202F798AC1E09972597A7C79FC0E35F7ECA5ED640D3282F87E06B71D571502951AE02EA44056D6E8B838673EDB2A28A0D8EC679D453F71BEB552A402222D21E3417F8A5B5CBA8883E79E7A7B67B3BC1749442F627709E05A1AC688D330E7FF1BE9E133F0C4B7206EAD0CB49D58A490682BF8403861A446AA28DF493903C1F324775EA33AD128EACE5A725B74C1E0B7FEB0F1BB23A9EEE94517104E2E972142476A1A4ECAF6257F789570E007D1C844A7F74276A8C3BD3CEFD902E4E6A9ECF88C902B1361A271857F656330", + "k" : "092E825FA8C17967A942F47E2A7CCB50E357ADE14CD8BBFC1EFBD2218C1898EC", +}, +{ + "rngSeed" : "EE762F5C9021C36446706A88EF16312F4A12C725CD7AFFF1484337C91EDA8E89F7007F3705747D29907B3FB7500E5074", + "pk" : "35D29C0D6263D9020389240D058974E871AB8E433196680F50C7B88E6A3EC8764B4509C3764BB4DB404A8E932413930DADBB5C5D60A01539763428CDFFDCCA2CD0554633367AD245E069BFDB397B803C68C8543583581BFCC9BB1147A2063262774706DAB0A015E7C57E244B12406B0009024FC06181BC058B466EE12C3ECD1A983FE1BB030774DB831EF1BB26539245CAAB4D9954BB01901C6BB66534B95CDCC92A1AF075BE8A949829558CE625ACE38B1296A75058B9A3F90E74E04FF3880106869899E6844A6504B8A0CF99BA86C72CBA26564739D0221FA20FB412828180A14BC570503A033EB379790A457F9277A221B75720537205CD19969149AB9D2B87A19250B595186454C99B46AB8F03365200424B4EF8CAE2569AB4BC07B98ACD2E50B0426032F967354C70B6C1F1A1DF32406C296B0E9B8066904FA2184E0DD04AD5C27F9E952774BC82A923AE90888613144BBE376B38112A836B7D6B0606D25ABDCEC0B471A834FE20ADBC78A68CDC5619089AE4F09B32947EAEDA996ADBCF131621BDB99173063F98F1380A324F84626212F8ACCA34205299399E62B321030191379B8BF96CCB336498D2A8BF573F44596D0DB92792122026B61264693BE3A3A7160A9E60FC1FC0897E5F602483D6C81F382E3E237D6709B82056976CE23D66B013EA48CB56D78D12C68DC2CC6FDC7AA1142548E1940E3D889C71E990FBB19D4FA0BF892B5CB873CED68516E544BCC4BAC3734215201C617767757DD3CA2B0A5084002F175995ABB6A7B88892D07B4AC68B974CA83F13722F028BAD4AA9400F0B755FA3352C90673A44BE327845D1DC1CADA0996D57B62FAB1032CCB6EB947646FA25D06495A6577A17D707B11C3E8FE82325D21DC2997D0ADA9BF85B45D8E5431CE5AC571C253744108F91ABA0B2868C7096C92B2F53FC5A0D996CD8414CF230CAE4C58059177607040D871B8B1DA28837C7AB177369FD2C05FE300DA0D84E97497CF5F22A36B966B5872266202D207740D47C8B1FD118AB390CD5BA70BFD9A0BF8B59D14B165575A079D82BD0FB1CC015340A1C0A0C77C7F822CD2999C6F10B5AAB063181775B7F42B2FBC813B2FABBFD76C0A5D4942DF97C449CADAC303CCF4790685438257A0093461F581C981BC61229C94A130372AD920D2CFA5CBEC684F8986A7ECAA94275814CDC2D7FE403C933BC0038B18B28CC3EEC9CCAC49BD922C446267CD07B786DE316012330AE70BC49216FCF6B4C7DB2BBAB55153E21089D04C3FDE934955BA215D047398AC172C2B1A18C0597182E88A327D0F0968796AE0A03772ADBB406A210F2E004810513F09712836C45CC11A0D8C8433B813E0E8AA380CB166FA93961A2B6765287AECACE40CB4CAA064F6B547F0084BCBA7856898B221D362C9DE766C7D447BC10925330CA87A8379BA944323C638F33B164E13731B0B92A134EE9D454684387790361B31B53C245328BB19185F9774E2764FD429E11E2A4851B222C4A9E504531FD962FC23852BFA3B4632ABA9BE4595CF5083D64522AC93B41C7409ABA1B83EC51CB6A1C0BD0C24E35CBFFF95088D7B6EC890CB5559C44553DC44822692A243D032FF75C7C08914D847551151052C6846E2F556201205DC130BABD9483DC721D42F42CBABCACFF1AA93D05A2EE54BD399186BFD4978A7A76D5D24008FC55EC40A6BDC899EA0A69CA22ACDF8BBD14A5CFA2A06587728427865A3331C60E77B5782C37E79561CB622195656D8F9C0C8C2C560AC95CB0B986FFA0784EE17554CB2BD0D332645958BB68CDE65B13D274BA9A655BCC8072D6681CF556C7931000B94A9436602F0A5A6FBF770A2B323612BC47190C9A88D4588D97C099CA04B3B7377867A6E68869FDA2258083CDCAA41AAA798EA11BA7F6CC4838F2AAF9C5795F8137ADBC4C17B491A59255E61BA078A9B4179CBC89CC3C9946C65EFB9CA5AC5765F3570F673AC80C1D26B5AF8F031266C65B4EF41F7923AF49DC6EB3D0A0EAC745ACA402ED4B9B2DE754BC3B7A6B54C2159BAEE1F560DC502E4EE6B3A3D6B4C1AC1E06DCA9EDB6775F5696CF91ACBD9293BE7A82244234DE9869AFB1B2696300331AAE6C9332840145EB16B016F8714FC00020D429F75231F73B265272A936E404F0D57B79C6CA8C25CB7C8BB89284C4E7B0BA9EB33C0406A8C39EB0D5429FCAE286A9C56BE5839C10AD33E8A58374DFF41FEB", + "sk" : "6D02B73B69CADB317AE9C9B09A74634C1762B30C55E793C0FDD50574EB6156F152E7DABF92B1A4CF7A9AFE32CB5F95909F1C045BF9C7C76C137C6C4A4C170F82724C32921A2FFB7250EA6FEA48060CF88B69A0506E2BAC21912E4CA5806D15983428C4D7F32847B6A4BFB7218A4CC2B09A343DE3AE2FE392AD6A555C035ECD0A16C66339280219BB40BA2FF5432524CDB0CA32A6D1B8A9EA96893C3864494E3690647D8318A3520682CBC19632CFE2E28733DA34A9811F5E659CFE99B7894A88AA01C3979285813A149E196FF51206BA654215985C47F3BD24848E0C959A93EB20C3176C68188139B72929B83533EA0A70E44333D923512750CD9520F98BCAE6C16643C080FC836367AA4A39C88F66C0CE09428135673B0F09529D0BB1E9E4B14679CF41F433BCF533E7E4CB1DB4B5E800218F564FCE359056706F9F091F6B1A0420269948512748871EA2B7C7FAC91411C70A23418A336297CE670EBBA02520C3C1D13807BAD55100AB3D0A8B4E87FB5A5D21925A6892E93C3C10A66FC4974B282CCB9CB134AA0AAFA86A527F96B2DF98BA19DA2E536614D243A19DD1A095FA37E9008607C882B48A79B3403F76342CD4345E6F6C95327965C2F860C4367135124373FB54A4AA7284429455F1637F56B4443AB048E0C9B82289F7D2340C2547A3BC8E66343248B5114D27CBB0E19A6A6A82C84BBCB340113ED65460052C088C555C27847078319149048C5A9103DCA6770AAC9D5A75F84930D6F7CD5813590A22040FFA2B9B631EC897409259037FEA8547DBC92288414DD002A4C377E501800AA49B28E68A528A3312060D635CA584542A8452CCA7C0CC3EBC4E3F46A5A5CB1FA49718B1C71F95224F9CBBCC9376737CF827B25CACCB4B49CF4A0B0DE096E4D83F319582EDC68BA1177BF7EC2E2A41B0686BC6678B8355CCCB7B9A8519AA68B39067DD178DB2FA8AB33305EFB7592A29A8F49B9264251C1EF83D75518134DA35EC07CA4BEB10E102466DA0B74673B9FD7CB93F287AB4E321C9C4034CB26BE63567F7083CC86A15B67535B1C235C7AA4AB1EB5097947B5B282E15B888A8B010E8596FAAA410F6CA7FD358765ED97E5F8970ABD54E36938709F6410B779077CC0B01052B412822CE256F15352FE5314AA2B41BE3611EC14020B975077A444007296455818B90F6B85C50A3FC4506CC48C1AD436308154C5075755C6419ED7A267561841CC56B428608EE62047122AAA674BC9AF18F15C52BFCC981FED3622F302896D7BF238B9808152B4D8CA1EFCA092569595DEABE45F6B35C8C9B7293A321E96E9574726DFA93C79B162EEBB0E7A37CEA7127EF1179C728C22D98328B59B86BA4A85D11249EA08A3E594E7DF1210846C8F7683F5B856FF4FC8D63B129CB1C8EA72A168C71C56C166CDAC216E07097E9FC050F458E0CF6BFC5F55116E161938C8DF6643B6D5514ECD860A4372693E12C1FC8B1552800802CCB48D16F4FD89306D30AF791AECAE205A6235EB9343C6576034C38747A306DB6C2302E5569C19A75B2CC62D3895584361284801F368766F27A83CD376952D0374316AF68D06B3C242D7188ACBF8847F55B80750BAB52B2043DF10B47DCA1986131F2DB9C9B12BF4664A3DB6BC1859B59B468C0F34C1BC8D8C74243AA3F434F044A408AB988A5820CA9317D35B8344E45273F76259C813DDF991E0E02664A4C8353252C85CA8531B6196BD68767CB8010D92FCFB12ACC9C931D169B9CD247AA2C8C5FB6013CF65F0EBC432C38936DB3B6EC983F742A1CA6449011BBB70F5BC7755B58D4C011455AAC47C6831D6A3368905E6B700C987CC910B23D3E406E81E56F28D0A35AA331F7499C63A10B2EEA5DD24B4E7C173D9E694D6C6B7A6262B26C99163C337FF3FC9DC9586548665C1472935AAC3A8B653E07802B1F2A291929233E7C8D1932718CA63299BA4919D9936D65A2B78C733AD2C15F13CB4F45252B7004D9D9911BC5293C61983EB24F7B9C1808285D82CACD48801A721B15F43C0F4563C494A9A5491C30DFAA5ED5F89E08CC76DD7324D16B3FFCEA5393AAA525E90F7A4BC88AC07010A60E68F7BE39B20FAA28610DB77006A5577ACC2D33740B6ED66341A56DCB4AC5A3EAA431765D006CAF51766A00E07F84A6BB0222C251764D628B9CB38860C4D8CB35D29C0D6263D9020389240D058974E871AB8E433196680F50C7B88E6A3EC8764B4509C3764BB4DB404A8E932413930DADBB5C5D60A01539763428CDFFDCCA2CD0554633367AD245E069BFDB397B803C68C8543583581BFCC9BB1147A2063262774706DAB0A015E7C57E244B12406B0009024FC06181BC058B466EE12C3ECD1A983FE1BB030774DB831EF1BB26539245CAAB4D9954BB01901C6BB66534B95CDCC92A1AF075BE8A949829558CE625ACE38B1296A75058B9A3F90E74E04FF3880106869899E6844A6504B8A0CF99BA86C72CBA26564739D0221FA20FB412828180A14BC570503A033EB379790A457F9277A221B75720537205CD19969149AB9D2B87A19250B595186454C99B46AB8F03365200424B4EF8CAE2569AB4BC07B98ACD2E50B0426032F967354C70B6C1F1A1DF32406C296B0E9B8066904FA2184E0DD04AD5C27F9E952774BC82A923AE90888613144BBE376B38112A836B7D6B0606D25ABDCEC0B471A834FE20ADBC78A68CDC5619089AE4F09B32947EAEDA996ADBCF131621BDB99173063F98F1380A324F84626212F8ACCA34205299399E62B321030191379B8BF96CCB336498D2A8BF573F44596D0DB92792122026B61264693BE3A3A7160A9E60FC1FC0897E5F602483D6C81F382E3E237D6709B82056976CE23D66B013EA48CB56D78D12C68DC2CC6FDC7AA1142548E1940E3D889C71E990FBB19D4FA0BF892B5CB873CED68516E544BCC4BAC3734215201C617767757DD3CA2B0A5084002F175995ABB6A7B88892D07B4AC68B974CA83F13722F028BAD4AA9400F0B755FA3352C90673A44BE327845D1DC1CADA0996D57B62FAB1032CCB6EB947646FA25D06495A6577A17D707B11C3E8FE82325D21DC2997D0ADA9BF85B45D8E5431CE5AC571C253744108F91ABA0B2868C7096C92B2F53FC5A0D996CD8414CF230CAE4C58059177607040D871B8B1DA28837C7AB177369FD2C05FE300DA0D84E97497CF5F22A36B966B5872266202D207740D47C8B1FD118AB390CD5BA70BFD9A0BF8B59D14B165575A079D82BD0FB1CC015340A1C0A0C77C7F822CD2999C6F10B5AAB063181775B7F42B2FBC813B2FABBFD76C0A5D4942DF97C449CADAC303CCF4790685438257A0093461F581C981BC61229C94A130372AD920D2CFA5CBEC684F8986A7ECAA94275814CDC2D7FE403C933BC0038B18B28CC3EEC9CCAC49BD922C446267CD07B786DE316012330AE70BC49216FCF6B4C7DB2BBAB55153E21089D04C3FDE934955BA215D047398AC172C2B1A18C0597182E88A327D0F0968796AE0A03772ADBB406A210F2E004810513F09712836C45CC11A0D8C8433B813E0E8AA380CB166FA93961A2B6765287AECACE40CB4CAA064F6B547F0084BCBA7856898B221D362C9DE766C7D447BC10925330CA87A8379BA944323C638F33B164E13731B0B92A134EE9D454684387790361B31B53C245328BB19185F9774E2764FD429E11E2A4851B222C4A9E504531FD962FC23852BFA3B4632ABA9BE4595CF5083D64522AC93B41C7409ABA1B83EC51CB6A1C0BD0C24E35CBFFF95088D7B6EC890CB5559C44553DC44822692A243D032FF75C7C08914D847551151052C6846E2F556201205DC130BABD9483DC721D42F42CBABCACFF1AA93D05A2EE54BD399186BFD4978A7A76D5D24008FC55EC40A6BDC899EA0A69CA22ACDF8BBD14A5CFA2A06587728427865A3331C60E77B5782C37E79561CB622195656D8F9C0C8C2C560AC95CB0B986FFA0784EE17554CB2BD0D332645958BB68CDE65B13D274BA9A655BCC8072D6681CF556C7931000B94A9436602F0A5A6FBF770A2B323612BC47190C9A88D4588D97C099CA04B3B7377867A6E68869FDA2258083CDCAA41AAA798EA11BA7F6CC4838F2AAF9C5795F8137ADBC4C17B491A59255E61BA078A9B4179CBC89CC3C9946C65EFB9CA5AC5765F3570F673AC80C1D26B5AF8F031266C65B4EF41F7923AF49DC6EB3D0A0EAC745ACA402ED4B9B2DE754BC3B7A6B54C2159BAEE1F560DC502E4EE6B3A3D6B4C1AC1E06DCA9EDB6775F5696CF91ACBD9293BE7A82244234DE9869AFB1B2696300331AAE6C9332840145EB16B016F8714FC00020D429F75231F73B265272A936E404F0D57B79C6CA8C25CB7C8BB89284C4E7B0BA9EB33C0406A8C39EB0D5429FCAE286A9C56BE5839C10AD33E8A58374DFF41FEB6AF202D9AD3F2C7CA61993E238140CE8550A5F0C39147130A5313C8C02D68DE7BA2DE5DD570E201786CBFD5D27020B649B011455909AAF0AD6D92C1B4BB1F8DB", + "ek" : "87C274C8469449F89E832D19318320FC90BC1389355278D3AC49D2F0C9A81BB39F94D525093CE4486EDB81623F196DB3B63C86405252D1612176952B231D38D81E5A52044024E2C218ACF718053B72038DB8A4BDBB27E61B9C5DDF2E0E78514332AB2E3CE19212E1FA72C2C7FD137EE8456C3873C66CFB79E3CF528BF1F77808402F0B5A6563A7BE106C78A6745706BD7172C5555375145A04B041F914106D051FB9B921F9C6E3D5B3F79BA65A8D30976AC3A1D5FBB7E1F64519D2476FCE56499B71EE36E29E3975B96BF9E5DB9E305216AC28176371A89A36D121A004C11F98F25BE59FF15A15B5D9B7607830D457FD7D1B708DDCDC18CC623CFA56531F642F0EFD70F02DEA3BAC041A8093D3A90E562D06AA58FC35B7629CDF84D6F84698C054FC165B14DF1AA08E0CCFAEFAC4A5E2A2850587145A952A665DCD944BAB221F93C7363637D09C0374E098D2D9A31B8A65A6F7CEE7223B98E9EC9F88E8C1356E871744B108B3B54991BD0E08CA111EFB1766AE81D7D5E0941D3007C16249DDECE5FF8311B54B799EE71C5D0282BA9AC5EF5E59867F4C1383CB422756F5CD3410E72FD8A4398426288EF9E61B6B031DCA71D285E15E5ABA24388AE4C74B6761DABAD8044D5BACB8F32B85B8E758468AA65325518DCB09D37D5B089E80B8271723FF67A4F307726B9FF165CB7C635F130CD03DAB36D6ABC2E84EE7EE079D1A8FEC3D0C51BA3DCE954874CD3FE1E0CEFC10B31B7B3BCF96528AF509200291EBB8E2E62DE9B82C21D3EB979A83DB19782C8CFCF7094D8D90577E4E58859E70D1878465ADE810B7A9D33E5DA88ABA6274411EA9BFEA2E650C415BBC2F698F43CCF64E77BE8D1E3E918CF12F2F5BAF9CE9B08A849191199E65D23EC2006C2F85C5CD9AFBAA61C5EED1F1E799148C406A473D5C5BCAE92EF15929EAB943B5ACDEFA31E21309E3DAD1A9D96207F917B6E88457F7333471D9623D6C2DAD10F16D16C007474D16B0321AEAF6E11C5CDE935F9CB3DDE8CF5A789B88AAF816ED15660ABC53F82571C1C19C159D7AA76D95FF01E0841D3CBFE284414959E194CB11DBC818DF5E1C658D65DC6B4BA3FE227A2FFA5FEB1B8CE0AA1FD283D3166D811057DBAF2AE8DBEEDF07FC0FCBB60FA7EF7567D7BC2899B1F53FE7B237543C6110614DC7923575E8CB19D8FC77A4C7C5B5C89785DDA155FCB9865532CB84E2290343078AA434D5AEEDDD443355F39CDEE2C6676DBE12D43672D7FF770CD5C932CC8E62BE88C64008FBBBF15AA794F7F2F88D6372DF1D78DB13DAD53D55520F7EFC5D943F091486268909ABB16435939A67D058389657AC07832FC69FE45252F12E7A76F2D1E5577EE56F79F18BDB4ACC4A5F00181247AFF4AD46C71E869155FB0718BB8DCE91F1F31B26671E4A8D347A1B208891253F531B5120A725FA6494A7009F8E83BF188CE83AB874F2A2680BBAE43B49B8F1A843CA2BBC6E9D5D0DCCE15857102319A52AC1E88E230ADB57E1C41FA4D5F45DB289385AA0E783CC62CE021EAF532CD14367C89CE8A87AA4A824C45E19855839FCD83FD46E3A725924F8940390DAA10E93465DE7DB1FC1050A5E18B3B65E99C989F261E77222618C2BCE805C97623CCD913F283813D5C1D5B1C18B31C9A54FF09BBA4BFFAE36F547C295514D7E28EAA11ED2B88704FDB6D198395BBD1170552C43B3516DFA5DFB0B8B8BE809E3C15F89F13BBBA2E2EF4796EE31A0FF0F84CC544A5920C24F6B48EE5785D827556D0D8A18420CE7018827A3E6ABD1E8146484C791D1AA61ED6E867D929975B513521A8B40C3DB9987B512632F58C97EE3029702F23C8337EAF5C5539EC2FDA8086484D6949B0FD8CB24C0AB2801307A41232A9E8586A6784F55A596FEB31E5617064346B1EB877ADA9FD3B85E3E4AC5B37A0EA9CC1601D3DC7A1BE99F8C5130BFC4DBEE547490A7D1A4542AE4049A15D18B9E71AF14BA3C6BD130AE31744BF0B2E184BBB59C69ED0C07F6823F4C10C4FE8C9CD179BBE5C11778281F57721F0B0D1E83C5508A4860031CD45C774576063BCA90FFEB4FF1F382E0C646E6910D4E253E9102A43772414A3BEF5CC9B99AA1D54CA5E7F8E5F9ECD3852219828F1B54628A4FE67F40E0E3CB3707F36D6674656D2334BDAF29E6C597FF5F0696DDDFF16161A3F2B7C337DD4289082C8C53BF6E3EC9337C5425760698FDCA1F3599418D8774D03E27", + "k" : "18F1535AB497FC278E9CFE97F81765B82AA71B1BAEC87A468F79AAABEDF2362D", +}, +{ + "rngSeed" : "D882BA69AC8BBC88715F1C6387531F53273A5DAB87E66FAA8221A7F628D2BDEEE1CBC59C0E08D0ADD84520A3A70C1389", + "pk" : "349251EC123CE574A5DD6CA1D14A967E7177AAE64D9678571D6B0B0769935A1A2A8DBA53DB6C5B7067210426C64F53542929B31D565BD25A480D9065D79852B0F05002964772465C3FCA5F8307308055603039B1B56726EEA02A8CC19C5AF41309F145000D2AAED3038C17911677A2631242280C23E9816185C75E5DAB43B4B04C8777A35721605AAB1ADAB828F2640EC5B23173F6CF5D37ACE602CE5AF62108ECAA540BA46594181AC9869517502AA73DDEDC4131AB152B53501DD4AABD79556476063DA48C4978835F28500F810B77715257080D87247354302399485852314598FC6EB1F93FEEE6429EAC96D37C8422DAC30F473B56DB0DCD2C64F1C18F91950E7984A88B63979B424C6D4A36220019881B5AAAC715E426A6976A300FF171A29778C82A1520F42A2F0B10D26035613A1E0511720087BE146AC9F0CBA2C1929C0960BC16065748573D61EB195DE53AB9EC802D247B210B747C70C45AEBCF39229E4B938EFF354FB9F65CC6B52FF0163494744848885EE577048B506A95112ED45466252783A4016F30E29B1928ACBB448379723D51BC3B59A62DF46CA75F64BAE27AA2D9456C66E2997B48274F425004E6884E296E17912F7E387DB452681CB32E7217566897287FE9C38622325A8C6716E5A767A626D98836CB779983C31D1802B0E0BCA04BEBBFA9E2CC02429F987A31F73274CE5320E1B0CFF8154DA331BE8EE21CAE8C5037A1BAA4956B04833D4928A1C32147246002466716EA9C69F4032D33260C338CB13EA09E5E47957700C33BDA9B147A3F3F64B46C933B7F4689D2797E4AD24DF42C002A323AC0E781B7E8C8E679C949CA730826B3F6C28813AC24CE7CCB21136695C75B3D028FBF6BA94F5A06115C72BCB879D64CCA29309502836EDAB5C7B2A79A1E1204161369C5E8B63DC513D0AAC9FD366387F0AA2E736BC09B4DBA05414659A6937264BA982B419342E8C063EC64B28663CBF4D12AA5A6AE5AA9056AE71C4F5643CFF81CE6D7A8D29A250AC27BE274AFEF453DD176C462791C249A817329142C00BA332851E50A01660A47E35BBF3890C23BE173DEC1A1D57A4837975C14269707384855E897CB44C4BEF532A003409AEA41D2FC889F572AB20C0409831FFB0222CC7246438A95FE4A6E32412688B2CC8C1963E38526201AA9D2B0963533B2FA42AF59E61D53C4BAC2BCC09E44C5F9C4963525A7C015244000749E811873A391F71315D1FA60C806390FB3AA80295E77E80158C665EAD61283271A1997757E5C4DC6893AD71A63A1898FCDA02165DB76E252665153016C90BB9C8423CF8A1D371338FEB40A382C2C3F99840EA96F99246044F4A5FA5CBB8D7473110B4A5238255E5C3D43463B055BBE46211D2E05812DC46BCD539C56A15199CABE5019220DCCC1A828A5E0C37BF130A6DF762E395915654B5BCB5C3EAA7142E1706697B9914A287513E407ED376354697144B33260EB966316C05DCA8655A0436BF47967779D43CCA5EDCCB932C023351542857268A57A74C4EB08B7809C289C5543CC3730594B3EA33DE6E23A5600AE6A68CDE3614CB1A80BD7C2379C1834C349C55FA73859C5A3AD45886286973F1363A5A536A0B08FAF26A939179F873CAC62281260868569372DCC744185A55FECCB261FB0AF1EE7A50DBA2C49636E09687F4618667DB136BB291F4B4C129FC7635182720521ACF1D67C719A283C412BC9165D9F883DB9049B98381A4412B6599316CB39986A9C3F8C069AEDB9B5E13B82F3ABC0C1CB70DBF0B5D1D66EA003676197C1BE2C15BC6533A41804CE0C123FA55A87FA344D850AF4F5B12FC0AE3610593E1BCAA1868571B2A618DB9F1900C459376798341E4263C70CB94A9DB42A04067F7A5310C606BD7FF661EF3508E6B6B6373C7BA0C872B8019676263BF912673C59A4C51372A2DA860399222654518063C3E1F07CC6C93E91AC6B53F3C04516B76DA65124325C59D4360091923D1883977A52B328C0D508D0F039696DB843BC12C506B521AE34C9B9D145047293A6EB99686770DD587C92BC65AA3A4083B40E8FE2CF891C5152281744612B2598664E4368775572E4A03A9FF53E307CAF081CA897DCB43061A404C689D934653769AD59D68475A8B0E7277BB280AC77EA7B1A1B6111C1574C6358DD6A472C49C264965F8CD9FAB7D1FD2C5F4C3A4FFCD66E5B05A4879536AEE3074B69C3D4E6B1", + "sk" : "4F311376E73D8074BEBFA35FB9C25879F482AB77C1708A8974D609F4ACA60712BF80E6A4948042A333CB8ABBB1BC32960C75776194ADDDF09925B605EFE3CEA0421A9CFC63ACFA774858B9F8468C39E9038434517B103E117ABDA9531EC9DB871B0144DE3B3E6A99CC091A696EC218E6E099188872D3B2B2E4188C1935530A364EC7A1A98D9CBA4BB68D26CA98EB437D2A3378BCE40FCD3B4A8F7982485A1296364363DCBCD813A2D434BF3F68788C035980C0BE8F46A6EF54A198D64C0D149731A097CAC43D7D022167AA8657EA521197CDB3585B4EF64B1F6708082471820919E8B9392A5C2F56E56148D10F18525491647FB0140E7C66BD26E3631F3BB3F20C947A67194B9C5DE9793D55C2B800263E50929889D8AFC878B661C7CB2FB366B8F70F8EBBCF75822CAED8A6C83A3651557389C51E5431AB15095705300A88EBADCC417A4E955F2858B797B39B64F10F587119E24A01E2A17A638873B485B2C8D867969C39B30C01404905ED14AFF50484DA83A8BFDB23689900A7954695B6695186B590E5C3DD27AB6A619A2CD13B78C9CFC7C966D4D373485AB99E522A74372C51A4764EC0152A29ACB154826479567B1C6AA68BB2FCF471E035C0D7F22478FAB87E7C035102A8FBB5CDDEF910923748BC752D0C82CFDF8B7733F30E6752B037482BFCC8A38097C9A9D8745B0681AD79710A4049BE27C13680627516ABA8D308287A45F498C9065900CEF26280F17B8EA6216F60118EEA6243337FB2D7CCC156325C33116B057B92E24D662718235A7E7B69186B17232132B529E44D558039EFF0C2AA6B0B0BF8332C382E1B132C3F343A2BFB3F11A116563A7905617E639C6BED21051F5513C4793DD887B9EA26B90DD7076AA4AAD5614D53E87D91861CADDC1DAB846C6933A689EB2D1566814F31951546B820620FB60690A7734153E79E9BA9A054AAA9B908605B10384BBA08E2213E683C6D64E9A80D8235F02C39A6BB42DEF54865164C86C08AF24A614F3608B24A617BAB86E5196172C81F1A6A001CA4CF72C9BCD6F89B8DCC154DD761A3C02362092DB91B3DA7DCB723B59C3E029BE1F96E6933A5A7A8296DA3A043A32E9FB27573A62352A088AFA68BAEF5403F200D8D71743ED79EC3ACBF1C4811A0308F425A05714C5637560CB7B36DCC91008D715248FB3E2E52C38B9C67381C3E0BD8127C163E320504AB20588F02A0AB036E8CD121D762AF33980C0A7625C6129B83B6C8D7E304A4529AC33C204D79741C1A68CE356C4CA04A4F16406B462DB4038F78BCA2BAAB2926250CEC30A3CE827E56186DA8669FBD7A2199F53CF87CB2656349B6D2BA189079E7D2AFF8938A983275551A21E7E179E13CBCEA08885AF930509C68456A9E778BAA0E4649E2C830454C278A06849F088D130C176320B260381259D4458555A2D8715A93957470E538448A7B29958D7119C17F6A38F09A8B441C371114CF1CF390B56365D7C71FE9BBCB496401BC8B07D15C06A49C221828B6B7B56CC601BFD6D75FBF3AAB16EC9584B78078324CF9060C5304354BC99E9A69C090C6513E16B6AF982F2BFB4E0DDC4CB69AB1FEA10575A53358890FEB66162D29B4AF6023EFF84070E25BB84B0B5EF18F4BC554B8D661CB5A97A83B856D6437EB503DE82760CEDB83A5AC4B05261A02A621937231EEE26777D75A3863CDBC24954F74B43260A089823B8C659108BC86DD1BC36E9643B4F62C1489A880099622B27160A2C934F4B3369A9AFA7531EC39487EF2B8742B63CC5059A8F9317B06AA8401071D86791B09249510AEF7924C25A2458152165ED7C4403C0CCB5A8DB007221F930FF9162D66B4A1522B878D8B08624A0EF3B24C1CEC21928773C8FB99F4816A7955A2A2816949EB1DC1A794F7B61C1837398521BB07C0063B2B01571054AF509DC94A3EF1882B0928AEB4DCA18769B593D2B357E56BB3148EF7D4CFEF73068D0B48CB37C168168A46701E3B16B6E8D463FD47CA5F7B472878497EB9A60E629897108C30461BF6F09283A006B95CA010AA80C50072892A1D7F406799593112B81D61775D4C15A3EA54C4184B775A88CC3C427D9A36CD1E77948ED33BC0891B24DC7A08822CD2C94246758CC4E49F04A61D0D721E43E57B8C18337293C25E109E64F01E88BB0C08497D49083A9FE260349251EC123CE574A5DD6CA1D14A967E7177AAE64D9678571D6B0B0769935A1A2A8DBA53DB6C5B7067210426C64F53542929B31D565BD25A480D9065D79852B0F05002964772465C3FCA5F8307308055603039B1B56726EEA02A8CC19C5AF41309F145000D2AAED3038C17911677A2631242280C23E9816185C75E5DAB43B4B04C8777A35721605AAB1ADAB828F2640EC5B23173F6CF5D37ACE602CE5AF62108ECAA540BA46594181AC9869517502AA73DDEDC4131AB152B53501DD4AABD79556476063DA48C4978835F28500F810B77715257080D87247354302399485852314598FC6EB1F93FEEE6429EAC96D37C8422DAC30F473B56DB0DCD2C64F1C18F91950E7984A88B63979B424C6D4A36220019881B5AAAC715E426A6976A300FF171A29778C82A1520F42A2F0B10D26035613A1E0511720087BE146AC9F0CBA2C1929C0960BC16065748573D61EB195DE53AB9EC802D247B210B747C70C45AEBCF39229E4B938EFF354FB9F65CC6B52FF0163494744848885EE577048B506A95112ED45466252783A4016F30E29B1928ACBB448379723D51BC3B59A62DF46CA75F64BAE27AA2D9456C66E2997B48274F425004E6884E296E17912F7E387DB452681CB32E7217566897287FE9C38622325A8C6716E5A767A626D98836CB779983C31D1802B0E0BCA04BEBBFA9E2CC02429F987A31F73274CE5320E1B0CFF8154DA331BE8EE21CAE8C5037A1BAA4956B04833D4928A1C32147246002466716EA9C69F4032D33260C338CB13EA09E5E47957700C33BDA9B147A3F3F64B46C933B7F4689D2797E4AD24DF42C002A323AC0E781B7E8C8E679C949CA730826B3F6C28813AC24CE7CCB21136695C75B3D028FBF6BA94F5A06115C72BCB879D64CCA29309502836EDAB5C7B2A79A1E1204161369C5E8B63DC513D0AAC9FD366387F0AA2E736BC09B4DBA05414659A6937264BA982B419342E8C063EC64B28663CBF4D12AA5A6AE5AA9056AE71C4F5643CFF81CE6D7A8D29A250AC27BE274AFEF453DD176C462791C249A817329142C00BA332851E50A01660A47E35BBF3890C23BE173DEC1A1D57A4837975C14269707384855E897CB44C4BEF532A003409AEA41D2FC889F572AB20C0409831FFB0222CC7246438A95FE4A6E32412688B2CC8C1963E38526201AA9D2B0963533B2FA42AF59E61D53C4BAC2BCC09E44C5F9C4963525A7C015244000749E811873A391F71315D1FA60C806390FB3AA80295E77E80158C665EAD61283271A1997757E5C4DC6893AD71A63A1898FCDA02165DB76E252665153016C90BB9C8423CF8A1D371338FEB40A382C2C3F99840EA96F99246044F4A5FA5CBB8D7473110B4A5238255E5C3D43463B055BBE46211D2E05812DC46BCD539C56A15199CABE5019220DCCC1A828A5E0C37BF130A6DF762E395915654B5BCB5C3EAA7142E1706697B9914A287513E407ED376354697144B33260EB966316C05DCA8655A0436BF47967779D43CCA5EDCCB932C023351542857268A57A74C4EB08B7809C289C5543CC3730594B3EA33DE6E23A5600AE6A68CDE3614CB1A80BD7C2379C1834C349C55FA73859C5A3AD45886286973F1363A5A536A0B08FAF26A939179F873CAC62281260868569372DCC744185A55FECCB261FB0AF1EE7A50DBA2C49636E09687F4618667DB136BB291F4B4C129FC7635182720521ACF1D67C719A283C412BC9165D9F883DB9049B98381A4412B6599316CB39986A9C3F8C069AEDB9B5E13B82F3ABC0C1CB70DBF0B5D1D66EA003676197C1BE2C15BC6533A41804CE0C123FA55A87FA344D850AF4F5B12FC0AE3610593E1BCAA1868571B2A618DB9F1900C459376798341E4263C70CB94A9DB42A04067F7A5310C606BD7FF661EF3508E6B6B6373C7BA0C872B8019676263BF912673C59A4C51372A2DA860399222654518063C3E1F07CC6C93E91AC6B53F3C04516B76DA65124325C59D4360091923D1883977A52B328C0D508D0F039696DB843BC12C506B521AE34C9B9D145047293A6EB99686770DD587C92BC65AA3A4083B40E8FE2CF891C5152281744612B2598664E4368775572E4A03A9FF53E307CAF081CA897DCB43061A404C689D934653769AD59D68475A8B0E7277BB280AC77EA7B1A1B6111C1574C6358DD6A472C49C264965F8CD9FAB7D1FD2C5F4C3A4FFCD66E5B05A4879536AEE3074B69C3D4E6B1EBA48A8A50609E70BAAF4C552F680F0B02AFAB2DA76D8833A2CBC3B6F782B36AF25F42AAA0D647322BD837CB730AF6082D2FA2D17BD63B162B36839FCC2DF0C5", + "ek" : "59D997A1ABABF7639CC090E83B45719F8062EDC7741637A1FD0A6E81673B2CB7AD866EDCD10F437871998526056FC3641B2F7851381D34478098F56AB1C288B8549BEEA74B2B153FCAE0AFD2DB182087B95D7B43F02C2FBD7DF213E0065522ED69263ABF68561F05B30B869160946BD104F4C5105E072C19A3C7996CDC059FC9B67B9FEE98DBE333264B47C9AD783D2985F1B19BA1082F11DFFB0927C871802A790D64A3AF8B291D9F7A5D17BE35086B25844AAF1A751B2A4AEE85D607F10203D263F272B098A6960B1D43BBDAC38C581AF34F087703720B164D76221FF063BF96BDD577824E944678012B92F0076FC34A994C62A463E19B23A5BDE8023463D31DA46EC304667AE38D63374C83FDF9C5111D9B8EAD7CA67B39FE619CBF7B47981B987410B3ADFF1B2749F7FBC44B18A861AC6AAEBC96F8CBC7C212EB374A29DF0F761AB05FBBED3F8B716A0AEBC9AAE231884D1731097487E7391E6F30871B052805364E4D7B4D7EE2D8DF09A1AA52551AF10C5FFB04910CE18EAB2771F30EB5339AE32694AEDF0918EB178EFDC824C8D2E256E79D5F52DD7263867BB1BE09FC9CDB0AD86893A30B33EBCF1559A40832D648CB6C0EA5A1CFB6ABCF7B2F762841ED7791922093E66B013A4600155AE550313E86E279CFED2521EFD1BC8145BFBEFA2C76B2D583AACF1396830D1C0DD39371FFCF20C9CA73B8EC5E570F89A8770CA8812F6E84CF37FBB83BDC3384FA47805CF2052937768BF7E441732029FAA8635FCDB8279B830E17128A312D4370ECAC93EB964F51FD785DC43B7A158ECE04D137B73A6A207F6015210C7D6B1502B78735C6A3E2D30CB5A74FCF896EFFD16F48502F7633B6E762425D4D1D63CEFFFCCF9FC1EC21FA3BF6DE13835B74749ACEE95CD1D73364990C2A1A492901A1CB41AC9FE0C7F49D7A084F7211142EA5C16761D160D9A80E62A4197D50EA923696CE4D1F5042DCB37069663F0F4CB9201CC1C930F1E61190B85A46FE471E169866135D720363C5BA0C77B28839734DEB7A79189D70DC6206346ED494E6958E4ADB8EE6243830C8CA1E7689D819C29356894FED7A56DBB44EAB99EA823545537520F6BE96188DD6ADE2373BDDDC65DAFAC104386C675BA18BEF812FDB89C38C501E1D65822D9A68D1353F7D8BD984B3C2942790CE8EDBD60E1CF78F4C02901C1B696966950743C7E64FB66306CC595554BAF9C276E7828FE794400F15C25C340CE232AAFFD4D1BAD74A170CFB11A1ED70EC86157A1F66F4701F612D55F62B73FAFD242F5AF9475EBD54A10E007B022BF92347099860F1BE9851B12E56D92B91560805263722BE1B6A7C8350AD92DA8DFBBA63BC4383EF59BBBB89DF74F50E18CA5A25E8827920FB24AF1EFDC8FA8725B43025165E1FF1A482B6CA1B65AEF86D49A11BCBB7EFCBA03FB42284258C7DB37D1A41BAD9347D5E09141FFAE20F08D31F1D90B7CCECFF30831E27C8BF8926E86980AE3FD563EB8605A37BBBEEB6E48BDE6D35C57986807488C9DC21AE60243759D57600AF66C8530910B41C9237A024D92893EA2F1C956F54DDB5FEEC160C6D4B4390E99EF0BB36DEA668334F68ADCEEA600A8AE25DFCA53D7B4FE1FDB17470C1B305AC3E53F46C578C449EA23749317899C4B942B5EC101C31CD1647967FDB0C5895DEC01F9EC9A5292A5AC5893F1F2155441DE1F1C400A3397805E82482446FABAA40FF88E3432F46812A9661DA7810783E84404D278FDFA8BADC5BC4293CA43A011B27B4A331FCCB4099A1C65013D7E9DB5B46790FF123A8FE0F381E20F087342417B03CAC9CDF9DC89EA5B7F8E5A3D61AB21001E2137CC5BE3F4F2EAC27CD35DDDCE5C3E9B03F87BB1DDC69E1D87E18C8A7A1F532AE230D98AFFFEE96962EFD3F3805B7AB6DF574580D57929DB8103078E862955160FBBBB914DC24A515142B20334D7CD3C5C3C6EC2BE93CEDAAEFF9E7291841F9F5A0CF40E347E6249EBF6F8E11E7806713D97F9794BB76617E1187D9F6518A41E495B28B5EFF37FC656BAE3EFBC56017B2DC22A882F45DA063108F9DEE425052C848DF404F23950AEC8ACD16E6DB36945AFA0D5F3119213304DD5E322954FB9F74D5FC561A2F4F249504B214C0C65CF1E84FFE577A15A212DA878CE1885E974E17B356EBE97EA4F5B9F84D2E66BE7CD22353F842F562FB88892C29F1574803614FCF1E1F2D14E2522E522639F2", + "k" : "1A5261E1D29DB43572573A2BF84359BE8D0B18A6043640F92F9B14C0CD9B430D", +}, +{ + "rngSeed" : "6C3AFF39F5D097096D882F24717718C8A702382DC4AAFFD7629763FDA73C163CF084807BBB0C9F600CD31A7135F48AEC", + "pk" : "6A515110C076DCB486EAFAC9040AC0690B79F5278022F59BFC316494A782D92310489C9F93E61585B3BD292165F651A7017A994B2512F0A5BDC8E77E9BAB7E5CCCAA7BBC779D445E5F16B871989974D92D2C268BCE10764C0146A683AE56C47C4644057CE8B4739031879BCC287B194CB36FAB6916FF563248D04851C74A7FE87F4FEA546A565EEFD507457882CF288ED294783179577EE898BED18C97660BDB726867A2C9581CC13BDB263DBB414D695990CCB897FA31984734E3178E081856627B0A4BBC736A235B3E392B3996441198C41BF8CEF5EC64D2F5C4B628490736CBBC076D8EBAB4CD1AB4936935FA3AA40D941E85CB08774520BDE23F24739400BD45B1B056D8A09EBB49A3E4B7209037C94A47084604697185BAC8772122D1BCF22888F165546BB699B23B2262035135120CF677AA7F767CA049B869137999884E360518358852CBBCA3F90643764CB30FA16CC009766C43B89E599203D6344B1081E97C863190AB57D42812D603AB56068283CD30E92E3F7A8989715479CC3735F3CB1ED9120E8B8C720BA35AB1178B426C413C5E89EB5483BB0FBED13A2FD0783CE4BDB1ACA87D80000DD48CAACB57C74B802C6B133817AB099C84F1C22383E57A759AC6EAB76DF67876E3591F32595A56A027F2087B63DB7DC138CD820A84B09411DA2284AC78445850BA820C31B1CA97F3E680E24201FE67154B935A36292B18857007953A848C49D0236406E7A320243FEE64AC24B02952D0A02A57AC4FBA19CE373E3382CFF61160913CA55A091696D782F4134DB83958DED48E681546ECF2BE93C09A9BEA7B3FF420C84A9107F4A75A2A1C40BA0F9E6060E936218F0C0904BB29ADD2305CD59E29D2B10FE667F9EA49CFD149D1D8BD62E549E08BAA1CCC63B8CBC734A24017E4A099BC5A939828FFC8CAC5FB5D388AC8613216F21942675CB714E32CFE666357413773AB5F6A2C405179995EF42635CC7DB7238DD7C410BA529E7D7391556C5F604C38FA079A70FBC2E8B393306832FE2A8BCA891D880209B9719EB4D2732581408A3896735143462A45F5E4267084BDA97A9A5324A2E23A714C1322F4368BE3EA5219C10F56CB560A78786C2A51DB18C79F151F3743A7DE67C43A35C63D1B70E17AAF4E4C48E300A73F9C07BFA776EE8797F803CA148ABA782A2FAB110A7C4440C5791354B25C1107106BE979B2077D422A6D8EDBC04225AC63C3705394C9FD5389C11855057572FB303FFA365CC2854A3BF620CE5203B21BCF7AD9C675427CA1294C7B001E37A02BE18473D1B13D9C52B9D59BC267ECB1FDF3BB96C2B374E72E4BC0898441C47ADAC60C1955BD1A5096F371BFC709EF624078139FEB979C9EF48BC0BB9100D0A97198B466BC5821978C87DA85C4E4164BA61A010B5FD99435DD18129A6B379C3232F75C8789D486EE3B6C84E052B55066E81C409C182D4E84926A42ABAC49846FD7B6F7C305E234130026540A6571D2C241C2700ED4E073D0262BF196164C71A62B904938CAB91CF12FC8D527A091C20A86B163AACAF2F25D1814BF2D435DC7881B0F0219BCF40F90F894E74392FEA065FD1B69F2E959CD0A5850B002CFAA8E44D0867A16BA5B173711D77F355A71BDF7674299A91CC05F2C772A5280177F2551B6F4A986F3BF584A899E755464166C3220130E694616F76CC3722C999536B6D145DFA5A27AA591EE994332893FA87ACC2DF67113F8A9C438ABFA667022B92842C73B15047D6DB08E02930A6348A71472A5E04BCF856058E785C10D049AF83736B2F78F8FA0B16B0B7E897CB695EC20D37C35190A079A57CB41BA5A0F010F4CB94B585466C9A802F0855946361237A0840D43487BF65BD9F000F2480AFCFC03B3DBBA6FF053AAE4981FC619D82818251C0D00DDB269042902B4C28FE6578709374F2461B0FC1A00441B78582DB2A76DEE8729BE071EA3C9957F5A3E75934628081EB8339CA5CB5AE83677D4C31D7B12B0463B57BF7AAE0AF3901A9795085B8AED0564D3755588A0829615785F322ADD179EDF08204021B86BB3CF8F3528AD652437BA8B0C6901CDBB748EE8A2D854644CB694668B9CE322992DC43F2D8A7EE655BE3B257A0974AD0649104B6B4E9A16BB8CB79A42968CEB1CBBBDFC6C3921AE35F6B22AC3C2F858184475B4F2A12DB3158B3BBF2D64F07EE186FC57DE21C26BFCF6B645F83CBD47CEF72136AEB644", + "sk" : "68E429BE33972613C71269A6D8C28F37780F659BB7329478251BA1F0A71E5292986EF1054D57A4A1A98EEA60BDD2244908972F138761469962AF11078F880E900543195101E2238CC4065EE72A33CAB77529C891209116774A34AA531093B15A133B3BBF24CA44787294578312A9648D6B427CC630BE8420AC73AD795175563B471694658721CE97A74719587F6DBA69307600ECB86C16D14428D264080B7083145C1CCB143933B902D463AB1264C53360C5FC04CAD928D3F91EFD67795EE2A9273A41353529CB3B6D3F61B2D4759662F1B0AAB989B1D42C40E05F53E7251D56879E57C40DBAAEEEE626F87B4F4EFA07A7666049C5C6AF4446260A1C2641432DE89EB582BA6F8C84640723B7A6449F268A7E8B93AF9B8A98552BF2AA940E277859824C22FB0CE8D1B3D118813D1C9749A345C990818091A21EBB2027A1BCB7434097B83FBA702EEAB0A8A8C3719DF9821CE2C0C6A392CE5A48B56A73801ACCF9BC0F55C96AD21C3AD7793DD62AC413F9CB25A75065E68EDC63508B13B90B6BCDCC127816D5C1E3B246B1DB27E50528EBF6B946B93962469DE91A70EC36C848C8BAFA2B13199C146E224552E619295703ED8C441A41188A004073392C59E88B76E847A11B527C6479DAF28548A5540DDC811D7727E203B51699A0DC85820AA90E7A96378D99148553726D251F73AB290B206452FB15314A7005A50FEF5B6A3C69B5C91125A161699D0956BCA47394567EB0CC4145FCA15B2CA32A751946841829531ADB91B9EFD60BB2018A13D736E67AA86C12517B134CBF51A6831A80188B54B051063561B1419C4990B1AAEB52280A2CA421A84B1F1827E544C27B88C1DB7593FBF3A9146633DD41A2CD26BFEAB57C7B01C3A7B07B0EA196DB4C21259BADDD81981D9A917B4A7BBBD45FD2773539817B77C09E79797BF301077BDA0E6DE9829B01C6BEBA809130A1A9724E3CE39931B58C07344EC731A11402470828BE43B33601667E46C66A59979B8B1A15D9739A7DA6AA19BA6DEF480D0E2B2F859B6482D128EE6262A929CEC408974AF41B9E0C9C6A9B0C32ABBAE27A36DC373199F65A18D4B3E4153086F003C127C7926C9DC3510BA0F99280A5360F29447C9204E7472E10486C3C465DFE4855B1D8B8D557B99232531C0B43426521C8034518D32BD5981C149883E8B95AB150C051793384C9662AA795C93B25DD3957FD3382AA117A9D6B333035650918CC924732737AAFF69472B4F699A99288C5A24946138FB955385A8A75F2088C143057275C3E7C97615C7721E0A049B544864C358AA8C0A30BA788C2E71DE8261567084040F83F23E333A4D74C55D52ACD20BD7C56142C2152407864F62C3D482622D87394E246110E133315D151DCBAB02909CD0A10754681AF44C2445331912A4031DD800E07E4AA3B37AAAA827738048A5AFBAE9677452CAB2DECA0205CA5B3E6F577892555ED3872BC845F97A86788A9577996810F0277CEE3235574A6EC91CBD49CCA68C870E161A7C9CC4B4C2252BB4C2F7CDC0863959061D73EFD366A65C140A014CEE9042734A9B79D67BF7AB6CEAF5A2C1FEB9B283502F940CB7E49C199CC7A4F885BF4B041CF418EEBACABB41067042B3C9C42A72655947ED2233A778FBA0338BA0B6FF8C58858E48281799F94ACC6694148B07CB1A5F8AE6DE647251758A2A72F19A34C6176614DFB6294646C5B95C59D857320CB2233B9AEDE91A6837820EF74376BA533D06487939348CF70681053078466B900206AF71A76D18A4E5F063317ECBB394CCC7B5ACE6151B1FA662ABE652186B92B3F785E828C2B1AD967FEAB658439C73CE93ADC47382C63544FE5CEA89A5C2602ACED184CB45B18FD3108BDF70152421571B9A432D299EDA808F8E0794E482BF468CB7B9B349932492F43C57E216281E1506D9A1679A54E4FB1986E284E6CA5466BDC8B3386B47E5103C0C70D796B4D42E17E279A9A31E434D2625EFEB4ABAC6BCD3014BC1FFA5B6424674710059A74B6B4E4B32BB8B183C76D00A109909CC799430A2CE6ABEE67504F1A65F2D4C5A305639B0A1E31776797734DD535BF20545E37B33624865890114C01C874C7F78BD6D88ED73356EBE5B14DB386CF677FB9315F8FD9A32039651A28338A0834696613502CA86F4830DD34B806A467FC2A726A515110C076DCB486EAFAC9040AC0690B79F5278022F59BFC316494A782D92310489C9F93E61585B3BD292165F651A7017A994B2512F0A5BDC8E77E9BAB7E5CCCAA7BBC779D445E5F16B871989974D92D2C268BCE10764C0146A683AE56C47C4644057CE8B4739031879BCC287B194CB36FAB6916FF563248D04851C74A7FE87F4FEA546A565EEFD507457882CF288ED294783179577EE898BED18C97660BDB726867A2C9581CC13BDB263DBB414D695990CCB897FA31984734E3178E081856627B0A4BBC736A235B3E392B3996441198C41BF8CEF5EC64D2F5C4B628490736CBBC076D8EBAB4CD1AB4936935FA3AA40D941E85CB08774520BDE23F24739400BD45B1B056D8A09EBB49A3E4B7209037C94A47084604697185BAC8772122D1BCF22888F165546BB699B23B2262035135120CF677AA7F767CA049B869137999884E360518358852CBBCA3F90643764CB30FA16CC009766C43B89E599203D6344B1081E97C863190AB57D42812D603AB56068283CD30E92E3F7A8989715479CC3735F3CB1ED9120E8B8C720BA35AB1178B426C413C5E89EB5483BB0FBED13A2FD0783CE4BDB1ACA87D80000DD48CAACB57C74B802C6B133817AB099C84F1C22383E57A759AC6EAB76DF67876E3591F32595A56A027F2087B63DB7DC138CD820A84B09411DA2284AC78445850BA820C31B1CA97F3E680E24201FE67154B935A36292B18857007953A848C49D0236406E7A320243FEE64AC24B02952D0A02A57AC4FBA19CE373E3382CFF61160913CA55A091696D782F4134DB83958DED48E681546ECF2BE93C09A9BEA7B3FF420C84A9107F4A75A2A1C40BA0F9E6060E936218F0C0904BB29ADD2305CD59E29D2B10FE667F9EA49CFD149D1D8BD62E549E08BAA1CCC63B8CBC734A24017E4A099BC5A939828FFC8CAC5FB5D388AC8613216F21942675CB714E32CFE666357413773AB5F6A2C405179995EF42635CC7DB7238DD7C410BA529E7D7391556C5F604C38FA079A70FBC2E8B393306832FE2A8BCA891D880209B9719EB4D2732581408A3896735143462A45F5E4267084BDA97A9A5324A2E23A714C1322F4368BE3EA5219C10F56CB560A78786C2A51DB18C79F151F3743A7DE67C43A35C63D1B70E17AAF4E4C48E300A73F9C07BFA776EE8797F803CA148ABA782A2FAB110A7C4440C5791354B25C1107106BE979B2077D422A6D8EDBC04225AC63C3705394C9FD5389C11855057572FB303FFA365CC2854A3BF620CE5203B21BCF7AD9C675427CA1294C7B001E37A02BE18473D1B13D9C52B9D59BC267ECB1FDF3BB96C2B374E72E4BC0898441C47ADAC60C1955BD1A5096F371BFC709EF624078139FEB979C9EF48BC0BB9100D0A97198B466BC5821978C87DA85C4E4164BA61A010B5FD99435DD18129A6B379C3232F75C8789D486EE3B6C84E052B55066E81C409C182D4E84926A42ABAC49846FD7B6F7C305E234130026540A6571D2C241C2700ED4E073D0262BF196164C71A62B904938CAB91CF12FC8D527A091C20A86B163AACAF2F25D1814BF2D435DC7881B0F0219BCF40F90F894E74392FEA065FD1B69F2E959CD0A5850B002CFAA8E44D0867A16BA5B173711D77F355A71BDF7674299A91CC05F2C772A5280177F2551B6F4A986F3BF584A899E755464166C3220130E694616F76CC3722C999536B6D145DFA5A27AA591EE994332893FA87ACC2DF67113F8A9C438ABFA667022B92842C73B15047D6DB08E02930A6348A71472A5E04BCF856058E785C10D049AF83736B2F78F8FA0B16B0B7E897CB695EC20D37C35190A079A57CB41BA5A0F010F4CB94B585466C9A802F0855946361237A0840D43487BF65BD9F000F2480AFCFC03B3DBBA6FF053AAE4981FC619D82818251C0D00DDB269042902B4C28FE6578709374F2461B0FC1A00441B78582DB2A76DEE8729BE071EA3C9957F5A3E75934628081EB8339CA5CB5AE83677D4C31D7B12B0463B57BF7AAE0AF3901A9795085B8AED0564D3755588A0829615785F322ADD179EDF08204021B86BB3CF8F3528AD652437BA8B0C6901CDBB748EE8A2D854644CB694668B9CE322992DC43F2D8A7EE655BE3B257A0974AD0649104B6B4E9A16BB8CB79A42968CEB1CBBBDFC6C3921AE35F6B22AC3C2F858184475B4F2A12DB3158B3BBF2D64F07EE186FC57DE21C26BFCF6B645F83CBD47CEF72136AEB64469835F3A1F1D9511E257ABFEAD77D365076A5C423EBF1554CECC7B29C0A61B6723DA505EA48A79EB504EEADDF7D19D736F39A46C837F2A0C2BF3FB876ED8E6BF", + "ek" : "8305772A875C46705C3A28C3627BF817599154DB94E295FC3D1E07C6070E17120BCDE33D752CC750491D83D107C76F499547A4316DD76EB15EC8F114C3E9600DB70CD8A2B19757F76A1D6B25124DCAB8CB9B0CCE6836EFDCE1979B65FF7AB193FBF7DDB8A18996A9AF2032537A5DF35BB4C60C31620F14B7B33F32F359FA4865CFA245FF3057A1050EED631CD715482BED488B29C4A50DD7136E2722715A69D39359D18D101AF8D65140DAFDA1772BE2ED10823F51D59172218ADB2B1F9940E00ACC55E9307DE8FBEDA272142D6EDCA738EE267AE57A802CECC65E811708BBAA9F5B490749D4A8CDA13E70E0FF709155D1DE7BE576E4850EA48FBD46CF5F0768EB0453FE0C2BAC46DF0B70968916B424455A0F7CD80C3AA45302D0EB0F693570AFD217C6C2CBC43215668F7065B0F743EA42FB4D1931B13EA63931B41FF73DC43E5D108F82388671C03C770CF5C8C4F88C068A5AF80195E893A53077D51C0343B1CE4C471F91D0F63C5AFCA6049A6ABA79552037B3724487D5600D4EEAC136495642FC36D4009BD16C76EF4DCFEC190386AD44D63A0671881954DAD3F09E0CF429B064DE1E33142F2F1360B2B1AFF8890C3530EEAEC06667C142096EA26D4903BA1F6BD46C32F2A96B9A4FC609B2111743FB55A133FEF8B9433F62A45AC8E67497A6F5226CB16BB68028A8753339E2AE93A79456D597BA5DB2002A73F8C9D12BFCD7588AD2A73EA5FFEED61DD7F1D84D4FE9C7EF336C83BD34719300CC0B247C6C5222238F2EC4D7394B673FDB360763BA3972FAB0DD132B15DE485A7E01745B668A5020B15BB00291603A5E741DE23604C995A1649074935C952DF62222626F3BE728B09AA95B297E46576E16082C5B42911171FF50DE455F958E2B5E089E4E377FE13ED3BA236F34D3EB6A0DE0B6B994606B2AADC25CEB9C71086A33B645180A89A74D10992D0E0DC1E3A628FA4C0F8AB052053F00158B200C13B2E58D8C33782E4D7192E5BD40DE1CBA60F3F0DAE0CAEA9707E5E5C925B1C3901A561417F1C2835620439915CA59F0F7090BAB4A0F444F9AEFD6F045E64606955E84C54B1F0C4D80E3366A983389129D3DA99533DD50BF6D0DD33F11360CB09D97CF1073F81E812327B7195E541312C1399B1DC2D434B8C0A80F7C3C460B15C2251265DC961EE2C214338877159BEC7A4101C7D610F1BA1EE678A28E402BCD05BA7E09C5BD1AAE84F5FCDE12C88DD4BD20E337A2ED1F4C84F65B0C251110396347EBCBBB235522F7C635BDEC6323F7E1C5EAEF0A4D8DE7A9239A536E4306F702834B33DDAEDFD8CD1150F640B88CD2D37A0BB558FC635D9AF986398AF20A51B6046DD257899E565F656475AA3FE925391DC45326DB336038D36AB745B77ED56CC60FA726F8EC539A2C8C563D594CC67E6125857D9A3345737724315215259C0CF317D52B31AD0DCBAA37B7BEAA896A76E40FECC76C83DF2ECE95110813B63FBB556E89702745DA5BA58A24A880AC0EBB7812030F82DCB878151E34285266F00B772D176C25A7626B665DEBAD7FFB133364B448E85B126C409F1348ACD6C3EEF45CDD2E638236B8B0B76D6D889E3CEA160C3A443AFA6732CA7077D2BDC447405658DF7C37A5ABDAE0FB6C253656F2E197D8DFE0E455701DDE04864B61D0A0ACC66CEA4570EB5601D7C94867D974910A2849D17C8306BB3CC26A9AC8D7D024C46B861BA5D7F526E7F68553543C6ACA381652A25B153C83B7400709BB3A7C903DB870D626A71C597254410AC843F560A97050366A496072D5CA373600935BDB9A6C1326F6840D64B51BAFDBF3348AD1BEA30D2AA2A39AE41D1107602767BDDE02D52BE862EEDD0F7534B0A8583CBF3B8EA2103AAF89819B4C881D455C9FE6583A48DDDDC0ACC271FE71772538237B9E073EF546F308D7F41F5A3DF3D5E83AC29BEDDEA087384E6905A33BB6405F0A347E5214C8572669496B3654E1DBFCC9A9A9AB78B8DA422DD9E02ECC41FE5683BAF8260A4DF85C5EA47181E6AD4ED490FA965F7349E21DDF39AF802B0AE71509B3D64AED858221D50C3992AE4037BC97F89669FCCBA2F2ADE7509B47E902463AFBDB7A03C26FBEA0907048B682ACA5C4EAA0607931C9020A264DF741C8AE50BF5A159646678795111E29CFA3A646AB95AB83CF6912EB6D3D302452E998D7DAD24FAAFDDE90EE50650926AB1DFDFA6842E39895929AEA7AD6", + "k" : "F98906FC4156FF25D6334C8B7709BC7ACA74167FB069026D210B6A2E341B3B31", +}, +{ + "rngSeed" : "CF520B92A2E3677AFD003EC1EC6EF136A709D78F828C9C0DD4946EFBD451C5FAABFC83CA66F9D3D17EE4220553B7A69F", + "pk" : "81D55AB1318E2C501E7D462CEA98864E291C2C727E6EF2349332680FB06B09767A2CA72CFC078163C140DC7151D869A9C785AC62C6ADE5F7519E070A08269938C7796B54B482F027A0C63AC24A6A00F7A0E7C65843E1C1FD01BD11D24ECF3C8B90CB803626044D03A39FCCA7E918AE418512631898F417C9C9618055340A05F67B6F1CB7CC44117AF09922CC07E9522285D16C42A7B2F833B51E72CE1C28A3FF37AB697CBD90D96B3E460C56C1734F1B11280AC33F170B3447C07F99A68F9A6F1DAC6083368555782F800BC7F4409ABF76B0ECCB6DA8F0825CC0C696CB9119340F663317913A641FF369657207194B65FA6B1DBBBA94D22B512B56877120A6EDC10DAFCB2F727349E5831A3DC8A539C0A55A517E65982EBA97930020608094B93E481FCA819058537BB2C051CB2C3F0E5A97E8365A14491FBBC03F603977273A035855C414812ECE238D254BA7334CC5BCE7256716077766CC21C617A9C378FAC1786C1CADECD13948591198682CBCF0CB098C504DC4B16A8269D13A701731B29A71432205660005919721C994011CA3C0BA8C3178A6D80B2ABCC9F6E6B7880811894CC6E62C0134011AAFA69568A1B95BB43C815C1405B4351A7290B856C50E284ECA0CC384A4551F455B503488313A341AA25F80AA02C97B9D3267492C31652B7654621A59F1AA64AE4410A1099ED7F14AEB10485F794E61157C1563CA5515684DB66EB99B76836A2441139A0906B35553C9E3E317F5E2C08487697574464A9936AABA528FE2B0C0C6B058B791D94AAC3BAC180B0609AB36B27579864C5BC6D8288292387DC4931FC889A45FC8BAD636AE2BD493A5AB401311084FB57C6FD88C2F0C504D5C463738BA7C5A97237C1681D8AAD66307EF648748198F6EA0C8FD6BA7EC424052C8A9B070C571B136CFA86F199542B12CB2A77C6973494BD41A2F0B55CB0E4122D0958026B7C54BC42EDDC040CEA8470F738F9C9916C158A9CA6457D8D9A0649337A3EC7347475EEA8C34E8127636B3897C547C0479A1E22BB2F7606AFD97CABEE179467880DC02C7B6F892FF3A7A29844476FA9843943D68BA4DF2DB6B8368394B62CFCD257BEFF5B8B54150407C5529349769824AF105ADFABCC53F936A8A492825D6A9B1108F1EA258C9DCA2D739A600F68616B2094AD29207184607985E3BB784D7977C20DC0585233131F93FDFDC9EE151C6937C7BC7FA4AF43B3B1DC4774CE6273AB04736308E89E21EACFB81845678A0C220309A3C9FE3104F61680F334227670F95F2B84C137A964A0A3A57525A4B99B231A8F22830D5BC588C0C705189B2E8A19C4362CB50186B99B5A783031300A26300280F279987EC058425817327B481CBFC789F659530D9C5D9C8432959ADF71741C1F9353D9A84836A5A5487392D19B5073A72869BA4E454C14EA5A93751322B8592E8566236A86C6619648BE1782CD03749D9B9604209EC66804C64913A143887212E7ACB54D5D995D0CB17E3E27C6DAC70904235F5C9BB29D908D8098B11739B16706541F31B53E3A384E594A7A640629543943A1262558530C193D18079426708117197A90B1C45E8B394125AC46238D2E22FB8750D1C190824828280565093999608F4113ACC18370509201056D589041D748B2FC71DA15490882805D3D3C0FA0A837400B73D25688C698CC8D78D144A80ABA8372BF7C349B9C395BBB8ADFB885906402EAB1EA58B622FF45C4DC14C9D11708659596552B18A3C0A1AF2CD7B558F15F461F0501C409A120B4468F2C09282AB7B25F9B028746FBC9AB77AF4262691A64DC43D59139C21EAC58E58A491E26E10974E6CBBB82AF385C4F77E7312CCB5194902257D3C4A4FA1A9035A670B5DB47EE67C1B07747B889A6C481490462829B26184BE3C9B0D7A0F9F2BCB10C8176F03464772479E9B84DD28CE94199D31845DFF0614D02841F4FC92F9221CFF071551E82DC829C9CF991E42265F94F7B4DBE7B791C244E37C3CA4192F70C32CBE9366DB59A9DD8582D6E69D849151CB7C6AB82AB8E7854C7B4C15B1557443CC2B1284B7FC7B16E415007427B5A9909B99F21C47956C45E14022374440B70415B896659178D3C98BC4F3BBE904A470E4838849BCCCC2CEDA8B9BB1E2AF29169D5919145B3229FB8C9EE705CFF4D91FB9729C6CB52725321F208F2D0B39ED53EDABA2C350ECBA69A4EE1F3159930F65C8BAAC80B2E0", + "sk" : "4EE12CAA4BAA2439AB1E4CA28BBB4F3A85C606A636CDC0553D821EC2AAB20D0394A0E3AC09C96CCE60CBFD9A1351B3CCEAFB11CA7C87BC42A1A191506BA9B3B617A6AA7A705C26B7820068D930BFCC96C3728BB277B157CBA1C1F8F17C415A1BC9E9AE5F4771EB38CFB7231108212167D6074EA1CF2D5B4C04179740C31BA48750E206C8C584355FA9C57D6CC84D1C88BB2A43FDA99CFCB14DA5E285B7ECADE1761D4C711B7A83B738D7060BD820E03529C608937B4734F8237FF746B47B3460A40C9FFBB18B6B30437C4B55DF55544F74BF3FC5758DD2B4320974698AADB0431F5670580ED39C1E1645101B635A49998157221AE3087229BB0F9CA04D2766CF308500ECCF34C40730888FD9C1AE671415892A8044D780D27B3F3BA3751CB9C9BBE61174614D2F15339D0A066EB738A0B43B8E0AB0E422B64F50C125769BD812B1DE3672A1976402909D353042D8C4A535A1ACEE33245254B575E71C5713A3DD919A8A9446B9FCC80368BE2F67669BAB466B91486A94A940E007A761461401D0512788AA06111C8C3DA1B136D3074598CC7A9D9AAF0A390A6468AAB1FB56A71414139840DC7582B439AA78B9194CFC00B0C357E8840FC583380942B26174838D558C6C441F1E634AC590BF9C1344B8FA95ABA16C6C130D8137706C424092CA5CC2BAB74340AA6ED81535FC6A0AB7B59CF276F55583759B0B009B4D6E117410212DAE343EAAC5946C3B379B7169CD5B5A4E838A2B0A7810A05C2EA6BF10667B4CD7A2E71B321D2395FA48A02FA08497FB68C771B1EAE67D5C11224EB19AB241770FAB2FC1800074E697D27B0AD3035CDB09772B222945A9BD9B2CC20D4B488DF40E80776EABB475CDDAA0EFD3C05F1C792EE9C946E717984686BD43660EB334BF775CC5470462D03CDE3C9830AC8A66879EA04ABA173B0858425774FA9306590A8C273CDCF347202267B44C3C52063693ABBAFDF65F4A2949C18B0BBCD02812DA0EB7F6A753B0893C4771A13986C408A2B2F3CB2144B1B7F7B6799177E0A258415CC91D449009C17A265803A038A21EF2911778242B043E19F986AB2754C33C31C8100A15F8609FC05804730D0B2212768901D7E4AFD4451950CACC42E891AE845A53BC396ED0B6C1423584C6B575A535E949909CA7CD95D05E743C16C25B57FC0A973E7B026197C6EEC688A5C19596BCB9879B44D2B1358F35B5A31BC3D8E38F003BBCF82A540993C73F30123C66BD31F04964235477D5323F69C6A99399055C8347CBB443C9AC5FFA477E05229457111DD212928B337DD6A98F59A303097536C10D7064177E06830497A644AC404226B688D354237742FDC6639A979625558BA4509CAC106121D847932311E4C22340B056F0AB54A4A1B5BC186C864397D7984DEFEBC974B25B211849AD36A93EA21D5EB9926F7C6B96233F11822BFDD822FA211AC570196BD1ACA785463C56A7FBB602AAA3C8DEE8BFEE7C18FEC5AD0F844EBE66B17D71337F71BC7335A86002CE28E65E6A5101C7871E9F651F04C1C6EC45C47BB97B1E4253E4110FB0339FDB84A7CA40A6F7AC81FB43681ED56C1F51AB7812CBBBC3A512BA340C566A9D60CD1AC90D568033D0E1166D70C9E10583E61282794B8247F4C2B248A71D379302B82E9D275F07BAC252AC4D09633BE60002A2A7CC23F1B1448C1E1AE77FE9CB8677CC3A2E8A1F6F3BB786A8B3B585946DD909AE296DC6648F1695B66D51C056E741C4468A3DB6ACC1C340228AB88D83CB168982008D9FB07B177278C893472437A12F3B2099C80322610C96C9754CDB513626297DD9DC5C8B64BABBB2CD2B904A52D67A1D00C92462A291D6B509FA66DE596516774EDCCC48CE2C145E625158381814709F23D3427BB56B465531453185ED500341A317F97C48373A0778293BF989529EDC39CA931F23B341BBE18BB071C61E488E45E100091AB58F18A7F33335D11019A973899F173FEF0B43454A2D091274C4601029176900D03D068164B2F1279094C16D38B32C2973958C0CF5362D34983AB213A4CC235D3EA428BF289D08428E02C3B23DBBB89D35C7C571A1CF018DBD6B377DBB2F09FBB30C5C0244C8782AC46E98C4CF614C42F48B49CFD8114CCA11E1455A419C2BEDE2684ED140AEF81BFFF6C2B32911013432FDF751E5855320202481D55AB1318E2C501E7D462CEA98864E291C2C727E6EF2349332680FB06B09767A2CA72CFC078163C140DC7151D869A9C785AC62C6ADE5F7519E070A08269938C7796B54B482F027A0C63AC24A6A00F7A0E7C65843E1C1FD01BD11D24ECF3C8B90CB803626044D03A39FCCA7E918AE418512631898F417C9C9618055340A05F67B6F1CB7CC44117AF09922CC07E9522285D16C42A7B2F833B51E72CE1C28A3FF37AB697CBD90D96B3E460C56C1734F1B11280AC33F170B3447C07F99A68F9A6F1DAC6083368555782F800BC7F4409ABF76B0ECCB6DA8F0825CC0C696CB9119340F663317913A641FF369657207194B65FA6B1DBBBA94D22B512B56877120A6EDC10DAFCB2F727349E5831A3DC8A539C0A55A517E65982EBA97930020608094B93E481FCA819058537BB2C051CB2C3F0E5A97E8365A14491FBBC03F603977273A035855C414812ECE238D254BA7334CC5BCE7256716077766CC21C617A9C378FAC1786C1CADECD13948591198682CBCF0CB098C504DC4B16A8269D13A701731B29A71432205660005919721C994011CA3C0BA8C3178A6D80B2ABCC9F6E6B7880811894CC6E62C0134011AAFA69568A1B95BB43C815C1405B4351A7290B856C50E284ECA0CC384A4551F455B503488313A341AA25F80AA02C97B9D3267492C31652B7654621A59F1AA64AE4410A1099ED7F14AEB10485F794E61157C1563CA5515684DB66EB99B76836A2441139A0906B35553C9E3E317F5E2C08487697574464A9936AABA528FE2B0C0C6B058B791D94AAC3BAC180B0609AB36B27579864C5BC6D8288292387DC4931FC889A45FC8BAD636AE2BD493A5AB401311084FB57C6FD88C2F0C504D5C463738BA7C5A97237C1681D8AAD66307EF648748198F6EA0C8FD6BA7EC424052C8A9B070C571B136CFA86F199542B12CB2A77C6973494BD41A2F0B55CB0E4122D0958026B7C54BC42EDDC040CEA8470F738F9C9916C158A9CA6457D8D9A0649337A3EC7347475EEA8C34E8127636B3897C547C0479A1E22BB2F7606AFD97CABEE179467880DC02C7B6F892FF3A7A29844476FA9843943D68BA4DF2DB6B8368394B62CFCD257BEFF5B8B54150407C5529349769824AF105ADFABCC53F936A8A492825D6A9B1108F1EA258C9DCA2D739A600F68616B2094AD29207184607985E3BB784D7977C20DC0585233131F93FDFDC9EE151C6937C7BC7FA4AF43B3B1DC4774CE6273AB04736308E89E21EACFB81845678A0C220309A3C9FE3104F61680F334227670F95F2B84C137A964A0A3A57525A4B99B231A8F22830D5BC588C0C705189B2E8A19C4362CB50186B99B5A783031300A26300280F279987EC058425817327B481CBFC789F659530D9C5D9C8432959ADF71741C1F9353D9A84836A5A5487392D19B5073A72869BA4E454C14EA5A93751322B8592E8566236A86C6619648BE1782CD03749D9B9604209EC66804C64913A143887212E7ACB54D5D995D0CB17E3E27C6DAC70904235F5C9BB29D908D8098B11739B16706541F31B53E3A384E594A7A640629543943A1262558530C193D18079426708117197A90B1C45E8B394125AC46238D2E22FB8750D1C190824828280565093999608F4113ACC18370509201056D589041D748B2FC71DA15490882805D3D3C0FA0A837400B73D25688C698CC8D78D144A80ABA8372BF7C349B9C395BBB8ADFB885906402EAB1EA58B622FF45C4DC14C9D11708659596552B18A3C0A1AF2CD7B558F15F461F0501C409A120B4468F2C09282AB7B25F9B028746FBC9AB77AF4262691A64DC43D59139C21EAC58E58A491E26E10974E6CBBB82AF385C4F77E7312CCB5194902257D3C4A4FA1A9035A670B5DB47EE67C1B07747B889A6C481490462829B26184BE3C9B0D7A0F9F2BCB10C8176F03464772479E9B84DD28CE94199D31845DFF0614D02841F4FC92F9221CFF071551E82DC829C9CF991E42265F94F7B4DBE7B791C244E37C3CA4192F70C32CBE9366DB59A9DD8582D6E69D849151CB7C6AB82AB8E7854C7B4C15B1557443CC2B1284B7FC7B16E415007427B5A9909B99F21C47956C45E14022374440B70415B896659178D3C98BC4F3BBE904A470E4838849BCCCC2CEDA8B9BB1E2AF29169D5919145B3229FB8C9EE705CFF4D91FB9729C6CB52725321F208F2D0B39ED53EDABA2C350ECBA69A4EE1F3159930F65C8BAAC80B2E03649C5C2F1142A51EAFDC3EDBDCB3C5150C608D828B7E1B9C1ACE00F9A548FCE5532C666D12D7F321AA87F8A1F475B161BF3812EFA99269925F5F29B1E030B5D", + "ek" : "15FABB4F4A1302564D607B0975E3C5EEF21583FFF81D760725D568FA90586ECCCDF8008D19E43491A082D4C2B7E2F69E0DF171AD540D4A9341A70C290E3AE7723BC64F3689EAA0E07890094D3EFAB1F039D505920D53A0872090D5A3C9EF8471E3C7B2791924AFF94DA9C132219E660A6DF6DDA9251900E845155871B134F85E00A25635BBDB51C2B77A140A39D5EF6FC758E5C4FA0759DF4217172007561C57D40A7326EE74015F6FFE7F38FEE82BC7A8337CE478305FB57E6AD8F2518642844FA7320B24D82178070C7EF66D06DFA240ACB77CE2254282BB07DFE11A7D0EE25CE0E3108FBA4632C4EC819C2B83C3C8C160C5918A3882562244997CCFAECAEEF0ECA9402F3727CAAC0034371250061008F042A10855EF2AEBDBD68D12859EA7BCE5DF154F48D7B2667031A18A4768CA62AA018A9727C2D483FEE3832B4B6AED9010F79D78C26734C4D4544A167D9EBFE6F8C721D19A819C0C499342B7D165EB7D0CF55FCD0E286D0532878AC90783181ED5875CCB46938A6482CD8C102D12BC7C3F472E38DF320042CD8B46B7F4714A141A73D967DC91A11E1ED0688DE931FA9D3AEF62F02487CE765EFC381AE77EF49964EF163FD76A661BEAA2F4DE65A507ECF7F95CFDB77129233C00097B1DBCE3E0E33900AA963BBA07B20D3530DF96D190E4929B883C7D26F3DA2D4C7A216AC7A7DA4B25ADF9718FF6FBC08A0809531EEAC1FA2CC7B0B33FBAACFD2E2A5F4322B5C55A8530B97E194C6E50FDE410C6458A18E0F0059BC467004B0ABA510F1D8701FA8C8573FFF86DDBF788C15D493EA4FC7525157474EBB6DF134E4755A772939BC5944E7AFE0B944131AA5C10CE0F2E832EF0C54CD09EFE589DA2B45EA709DAFFDB5078FA38AA3F154A68C5A7F649C7117B574D80EC7877BC8395C0E87576385B4C6FA4601251A11F239FCDC03AE15AA71C0CD536748D08C18D448E765E69C1D95249F3357189890407A72BE4587CDC08955F96858AD2B07EA973AFAEE64731BB5404BB8C4E5495131C5B0693C255C49783E588A08C30510EFEEDEAF559658A0977D71C940616E11F71246BE9EDCEB7329A55840128DBE05488E877AC2879F453BEB709356944676FC6782F969DC8CFBF5A08342F10CCBCE0CDEF2C8DDD74CED695FCD735C0B2D87BC27730863BDC1416271A1BC8B51B8926625BD31257A83F7883DD6F87342B24AB532B7BF193E7C6CE8232FB13E37A43AFF1675BFAEEAFE7A4B71CD8324E751B666A89800259D0514F04FCFBE9040C1C48312AEE11C4AA3A2A36EFC7A601038D81FBA250B156DE3D428F01F947163B94574693AA367BD3473C0BFF41F613DCB777F82A6BB827394135916E6CB44D7FF5808B720408223446D38222D4C98413CC505CEBA8BF9B47B18C6C380F551A499AEE69614BBC9EDD133FF474BED6CEF8B29FEF18AAF851F90A1662E877C1B0B879F054C69BBDB8FB474841E1900A9FE3FEBA288CBAA1E618BC6F539EA23008A550EEB2AA3A09BD8C02B209FDCC78C60FB0A65995C36D3FC5F11DDA8A3239FE8BB2EA7906B3C29DE1817098332367076772E7652C41FC21DE9A5E9B33769A0C130C9FA2A8341DBEC56F82FAFBB7BF5C4E9348D354ED324BF56462E961BDFBD8CE0FC2FA07CE4CAB9412D09352B8ACB237B2837B632C34895D86E225F0E3BDD185FDCDB3BD79313B62546C37894CCF063EA4F9B9C847E2BAC8534126C3B335E6C199D21671191CD079B89E5E0B2ED18B0453FFE1C53AC3A7B051063012B748C44A92C51F2501CC786B5E122976D38ED1DCAE81B57F977F093284937C17A496C0EF493B42A49F41E54FBF707487D6018CA5C2A34E80764AD92A0CC90D4D8200AD2CB6270BC0DDD291BE38EC44679D1B977CB1636B23D726DEA7FF133A695DD63A62F9E5A51C6FABFC0F2F74B15D016C9A5D56AB83CEE016CAB23B87B91E9E4A8EF95F5EBBBFA2F673EE4424F0E4E3DE3283F5CD5A0665F05D2A8ACEA38F1588875F57C3D19A469D4A91E7F6BDC1EC894B4E9306F4381839DEBD4184A870334E06BAA01483DF5D928675921AC2D505F9A325F907C6D606FD486C2F0898E8EFDC1B7DEED56CEC4E6081E82F0034B15C60426E540BFC3C4F4D5FCDC44843128B4A649DD4AEE7F49692A071400255705DC89492F399DC20D5F2F1D5E85B2326CF41FAB4032CF9886CCA8DCFB566BE2662C761A2ADE05861C60F798902", + "k" : "421CC1B24056281B0DF8A188672C6B4A69D2595EBED77398735DEA15CCC9427D", +}, +{ + "rngSeed" : "197E5D562DE7E01BED4FC597DB28DC6EFDF0179F3A5BDA5F94CAA39D67BAE730540534D59A7A06C8448F628DA8B7859F", + "pk" : "D4F7656B2B7819120A7CB68A80B91F2783979E1A329574272A3B154B52843BF80F88D947C79A58AE555E819674DF71B13EA48741D103D345A8D4786EB43012FDDB0B01C3BAA6A0CF128B099972449ECB3DE50020B025C486B4B5B115C78D927FE5E06BF8E29068D0B3D963C3B46CB9D1BA3256FBA01F2185CB566556151ED2E1C993469190B75FA75259A5B1096D5A1647448013C21ECA67A3ABA096A4DC77F35C2447E81114F732148663A9439B1304B148B813F12C61654688D35318B8C0A8C33738A2F1BD2A1B6E8EA93EEC771EC8C0094D4C6A45BA61579C72C2A41FFD468A6C679FC3D6B15D5A549B1614BC8874304BB6F01B775511CE5BCC7C055441AC72C34CA164F461990A57BAAA98840439371C26134500377B39AD6D222FEB0B67DFF197C550541B63173E2B1B7031B30CC3772E97734AD3C5B6243B3269C48FE055A82C9F4D1C166C294B8077269304CECBC404EBF8BD82C041C911B09FD7C2CEE33FEE1BB754878D8143CC93B81C7E99323B5210E7A64C7A3B8D96C1594FF3BA50132484E663797246DC3238A1EB743C4A33C51C6587A224BEC9BEBCF5CEAF175DD37C3591AC7D82512E9EE7C4ACBA2CF5BB26D3A2188BE321114A7724C797A2BB26CBE43B3FA03A8BC16DD5A49A68544E9FEB51786C46794C9F5239B7584ACFF68A2F7561BB05E6B5505C249262B509A922E97C40B4736E8FC2AF4017ACCE951CDACB3385F060CC1C55A4F79A60DAAECC939036115D2F480F6F0315FED05387E99F9448B6155A51D66A6940519B361233B2B7B34C740F0CB64A7CF0BDC48677292B0D1ED5898CE928E9040308807CFC730BE0D8C614D322735C1AF2D2199CCCA1DD80A96CB60247125CAB18CE7A1C5E4F0C4B978581742C8550CC9C84B0632967654B968C01492557BA0630EC0CAF04A443D9B2F616A9CB4CA13DA38FD9D611A59BC697C20E8EAA0D2B96AA2DB111BBA3A05FB463BDF7A777CB91B1086ADCE17DED04BE8B92254EC5442A6852134B5FDE9B060FDA258C18740B79970DC981CDB883CBE3297FA33EA988B07F9A581BD086D53507CE07536012A211C6B4DE17B73A08153C3514DAF12185416A81C61FE255A3E04B33E3C5A6A0188F6E09855BA504F838CB8417C2F0E97BBF5B937FF53848031274489B5366ABECA2CAA7636CDBE83F15980C02F207577B5EFB947692FB40AE7B36DFA83B728478F0541511FA58AEB121C14056451654D0DC4421695864DB64BC271A79AC0BEFF724B6BB2290CB64087B72297A6C3881765CD909AAFBAE72C9448B232093694CE522C72D2475F281AB1B633432175E3F78715DE1082DF66F74A351903B115D74489A32BB7A873AACF195F8F043922272CFEC2798F52F65F4638302C62648199E7979F4740B30D38F7D794CAD179AC960C838DB4AD7038AB84955960B4822324C5D01C5985AC8F47138BAB522DB895AF2F9A983494F360B061BC5120F385166A5AE9AB844C278008E47B655570430451CB606C24840B7A0E51268CBA81998697A5653E33BBE47D43EDC3249C32964E87BC8CCDB6D603C0F7387306B043FDB343E8500AAF0104683DC9488B0AD3D04A1C2657F11A99D46B040D0950D0937A4927012F4A78EE2405EABCAC445845D7E88B54A8C57947B7EC0C12BF654059D93BA38BA2E50CA3FEE8194053B2C9F10CAE8C846710392733123B0EB0AD895216EFAC4931CC782E886FB2C87BED305CDCC690DABBEEDE21ADDF7468E4873919865B905B3149A4D686B7C96FCC014B578E1D36BC3B63449F467B09BC84A92B20B01BF70200E703A0ED084C860F40A336576274C7E5475835BCC8EC515050EB8215F397F6312C9B1DB1AC1DA29FF90A4ED58B8F8623D4B893E1FF94E3E48A0DDC5C221C0B34A798713897BBE16A4C298C5E9F44932B09806E554F76B76FDB8744CB38D00F24F5CCCC75DBCB3F81233C454CE3664A807D82C68255C422866CEC26EF6E428677B4DB8F712ABF50C1E11C9F014B9AD59077CF0475F925568300C49C08E4E17CB7A5581DDC17331EB3BD7BC04C933B646224D3386A3140CADD445B632268458F63942455CA1B164C9CCB2AE679DDB12524C34CF823B3626B224E466245CACBBCF57896B7ACC6F6B702CE9000371473C622303DB63B2744C7138363A832B2973BB3144BBA8001999EEF108E317890C4B63E857C6DE99266629D3267DB18FD97BAA47B2DA64FCD1", + "sk" : "04C78EB9C2CAFCF78072B8508905B42C5698B3C86D8F20BCDC31A3E0801A084B35913203A642CF671C434EE39477E83D7314BC81A5B0A5D010031A26DC55BDE54C5194525091314212063B7E852476364AA64155E6E9A52BDA41C17939E553C26378175FE3C4CFF13E3F20543A275D6263276D2262D1A9596B52996C4982817A4FDED3924416B65E9BCAA45C6A6956C3724C0EA4171757393B5AF903DE5694E8962F3A122104092924F25E1590419FE11CDEE60BB33B5BDE000F7D621811819C77E4584A89659CAA85E7197588498EE8C8A8397C1157C29A7C8B696653A941EC2579C1CA7368BC0BE8BF4442222390BCBB871AEC382DE3C5011368CD420ABD03FA8BCC35A99AA27A1412515710B3F5118EABCC9055A09B350644A490BF83DCAC4C2035C81895AD53545D5B59BFE5455AB9C7CACCB4418B5830838E0403A56619AF355AB2448A69F2B848FFB42A8F5407FCCB9C5164B7F306B109533DD8C690A5A9332F058A1978915244645EB127B6AB92A732BFA7F0B528ABA0BCAAB51D52A54F57CF75C54CE462BF7AB8414C9974B58272357BC204D13D198058CBE21781E7A83507A7E1220195EC34CC84125D18CB7610B3996035E755421B969AB6CCA1B79A8315B791D96207B6920AF2E26FE66CA583A943AA3914A930943A723447C1639C22A937D91240839824547EEFB69E8C5868F0FA6DF79570DC01041D763B13C08084B8CF0213A5EEABB0D7507A0F8837E9138CD99349D4B2ACD1F72749B804EEC23F88EA19B00B5FC06BB665886C105786B45610E9A431FF8A48DA00AD35369843096F542396EA143974791C1E830256EB7C291368BA95009E6B4AE821BA1839CEEE153ADC9B7FD5B6462D4938A9129898B9CE6BE51C9AE90B065232616712580A80C6E57D57B1C597B526CEC406A948ABFA1BBA5D1835EAE0755270B8FFD5CBDF772C5C68C4A7F66F972C1C49553E206B08ED95067BD615B12B35F3E84F6E7A8FD72180FD904AC46CA901B89A5FDC2DA3B472F0A547901755194543E7A399C4363C33CC305345B79EA06889E12E049319A0428142E6A77D4B7223C72D3DD0C8E3C315B2677B19FA8C1BA7107D10B31E719A2C90ABC3102EA5E074F9707FCACC8A10E42014C21D7AA74153DA8B80779EF71A86C9D10BBAFA7432C9072E3CB4DEF92B9264AF134917DD24A687A492F0D351D3E9C61A421D0614BAF259752DB556C8BB401DFC33D9B0869AF44C81210BC25AA2EC07AFB5EC862D390C6794A0668580EBD39A23F914FEBA865A33603D5794E6F4BC210BB82B7A3914C1B5812120ABA6A58EF7381BC89E49817F0607980C93458343A12E26666C664832DA7552B804AB349E0B56A174716E3EF1270669653EE63A73A09C66E12C7B343A7AC13CB5AC4C740057C947BC3145B037D756BB8BCBF46097DCE24C2801C0B364B8E02329F7FA183C1003FC715AE470B50F1561FB3168B421727E66940A717A350A69AAD45E506144FD528F07235FCDD0C5B7B659F8C0BF85BC53195C75C447442E533B12E08404DB99A7346524964E312C48736C99A651407A3661B3812F83DA22F2E455483C44AF351CCD50721828313586665E95804F9A4E7D3878CF134A9D815AB4FBAA711517119043A46963101390C20C552D4C5366A92693526ED0893AA097481F8658122C3DF8FB21A150C52F9367991BB31955035D286FBDB5040E58556B2A8B7C88011877890F9ABBE1292F9BC36CEA7463318C5047629ED9A31C39D65F92C18B02E5A7EB16C4AEB68D7A057623F25C0AC68B48AA3A06AA534830A790CB36840C8E1C4B653CDA1ACDC1A13777AABDF19F55B66488296F407366DBF03D3451B8C55284A9F15F8F16CF51BA93781550EDE5BF43BA4470E6BF1D4236C4C78F7710BD0DF79F98D55873AAB6E8E573D88B19655497812AAEA85CA6B95AC5E0E908D2150D68C110E24A48F0E7A581EB4FDA5B7C3D97A68E26C9F709126089753D2C072E88AB97796600B2732104ACF744471BC562BFE4A995E88C36A80C5479C0F1204FBC6B723A1B1D3F817341853A02D75C1497B18E242E9E037AEBBABF28BBB5C4B72F22EB02734BBF5A897E77F84D9E4209D3FA77EED12BDA34378A541E5E5C3258399386C49BE1A05B6C509724C68D42B5A9BE11BC08D154C9E07BFCA513256A52D4F7656B2B7819120A7CB68A80B91F2783979E1A329574272A3B154B52843BF80F88D947C79A58AE555E819674DF71B13EA48741D103D345A8D4786EB43012FDDB0B01C3BAA6A0CF128B099972449ECB3DE50020B025C486B4B5B115C78D927FE5E06BF8E29068D0B3D963C3B46CB9D1BA3256FBA01F2185CB566556151ED2E1C993469190B75FA75259A5B1096D5A1647448013C21ECA67A3ABA096A4DC77F35C2447E81114F732148663A9439B1304B148B813F12C61654688D35318B8C0A8C33738A2F1BD2A1B6E8EA93EEC771EC8C0094D4C6A45BA61579C72C2A41FFD468A6C679FC3D6B15D5A549B1614BC8874304BB6F01B775511CE5BCC7C055441AC72C34CA164F461990A57BAAA98840439371C26134500377B39AD6D222FEB0B67DFF197C550541B63173E2B1B7031B30CC3772E97734AD3C5B6243B3269C48FE055A82C9F4D1C166C294B8077269304CECBC404EBF8BD82C041C911B09FD7C2CEE33FEE1BB754878D8143CC93B81C7E99323B5210E7A64C7A3B8D96C1594FF3BA50132484E663797246DC3238A1EB743C4A33C51C6587A224BEC9BEBCF5CEAF175DD37C3591AC7D82512E9EE7C4ACBA2CF5BB26D3A2188BE321114A7724C797A2BB26CBE43B3FA03A8BC16DD5A49A68544E9FEB51786C46794C9F5239B7584ACFF68A2F7561BB05E6B5505C249262B509A922E97C40B4736E8FC2AF4017ACCE951CDACB3385F060CC1C55A4F79A60DAAECC939036115D2F480F6F0315FED05387E99F9448B6155A51D66A6940519B361233B2B7B34C740F0CB64A7CF0BDC48677292B0D1ED5898CE928E9040308807CFC730BE0D8C614D322735C1AF2D2199CCCA1DD80A96CB60247125CAB18CE7A1C5E4F0C4B978581742C8550CC9C84B0632967654B968C01492557BA0630EC0CAF04A443D9B2F616A9CB4CA13DA38FD9D611A59BC697C20E8EAA0D2B96AA2DB111BBA3A05FB463BDF7A777CB91B1086ADCE17DED04BE8B92254EC5442A6852134B5FDE9B060FDA258C18740B79970DC981CDB883CBE3297FA33EA988B07F9A581BD086D53507CE07536012A211C6B4DE17B73A08153C3514DAF12185416A81C61FE255A3E04B33E3C5A6A0188F6E09855BA504F838CB8417C2F0E97BBF5B937FF53848031274489B5366ABECA2CAA7636CDBE83F15980C02F207577B5EFB947692FB40AE7B36DFA83B728478F0541511FA58AEB121C14056451654D0DC4421695864DB64BC271A79AC0BEFF724B6BB2290CB64087B72297A6C3881765CD909AAFBAE72C9448B232093694CE522C72D2475F281AB1B633432175E3F78715DE1082DF66F74A351903B115D74489A32BB7A873AACF195F8F043922272CFEC2798F52F65F4638302C62648199E7979F4740B30D38F7D794CAD179AC960C838DB4AD7038AB84955960B4822324C5D01C5985AC8F47138BAB522DB895AF2F9A983494F360B061BC5120F385166A5AE9AB844C278008E47B655570430451CB606C24840B7A0E51268CBA81998697A5653E33BBE47D43EDC3249C32964E87BC8CCDB6D603C0F7387306B043FDB343E8500AAF0104683DC9488B0AD3D04A1C2657F11A99D46B040D0950D0937A4927012F4A78EE2405EABCAC445845D7E88B54A8C57947B7EC0C12BF654059D93BA38BA2E50CA3FEE8194053B2C9F10CAE8C846710392733123B0EB0AD895216EFAC4931CC782E886FB2C87BED305CDCC690DABBEEDE21ADDF7468E4873919865B905B3149A4D686B7C96FCC014B578E1D36BC3B63449F467B09BC84A92B20B01BF70200E703A0ED084C860F40A336576274C7E5475835BCC8EC515050EB8215F397F6312C9B1DB1AC1DA29FF90A4ED58B8F8623D4B893E1FF94E3E48A0DDC5C221C0B34A798713897BBE16A4C298C5E9F44932B09806E554F76B76FDB8744CB38D00F24F5CCCC75DBCB3F81233C454CE3664A807D82C68255C422866CEC26EF6E428677B4DB8F712ABF50C1E11C9F014B9AD59077CF0475F925568300C49C08E4E17CB7A5581DDC17331EB3BD7BC04C933B646224D3386A3140CADD445B632268458F63942455CA1B164C9CCB2AE679DDB12524C34CF823B3626B224E466245CACBBCF57896B7ACC6F6B702CE9000371473C622303DB63B2744C7138363A832B2973BB3144BBA8001999EEF108E317890C4B63E857C6DE99266629D3267DB18FD97BAA47B2DA64FCD1F651C0028E1E5653A53302082D4E89B76B6B6A939A2F2F5B6B7D5931FF3ED6C5173DBCD4922B8FA921DC24240B2173C2E65A839357F8E4A93F51E7DAED4C8C00", + "ek" : "259D0E7C3DAB0DBA33D4D1E9A3773199D5F6493D0659922EC36BD6482AB98C0F59A0D315865F63FF9DC501C9E78FA866A423A7D2CFF8AC875CEEAACD9259049DBF8F9D673578379E825F7D070EFD1DBC633C4C8F5DFA397D01F9545F025B0A300B8EA4B515E23AD9544749ED5A0328418B7BDF9F427F19CAD10903876D30AD0488968AD4E8A2AC7B93E6153970096E302B1AF011A2242429E85BB8B91C0B881AEF96BC732D5C9BA0B42A00278AFE87138B3E0DD496FF06770EC7D29CF3A9E4994F99F8C173616306DA84E7B2DF54769445EED4C3CE8B8DA56AEA56B8C1FE19C1D4D129AE975022F97B0E53B79578F8CDAB6D6383A29F42B43B7E387F63AA4A24709251273C51FE8CF394E1ADE440937CCE03144B02BA3222CF47566A4C77705D28FD6D2E7EBA05922E5005CCC4F4825F7F229100DB1C817AAA1093AF2C0EB39A8F66C49B6C5370A98B1A63BBB1FA20EBDF23D2F67879CC1CAB20B2E512822CB7E7569D18B7E77BEF7D402DF6832120FE1E6D585859D7BED6CF93F8051A03BD2D0B924F6D56798535A2EE86A270F2F92E96C86A208B0B4E62B901783DBAC6F027779DFC95ACCDDDB0C7C6344F10E173746D59AF27313BFF92DCCBA601AC3FD50448997370CA8697FBB6D90D73A55F086B114D7503B2BFF3537841E26FCE2DDEC2DFC5F3E174382806721334F4AF8EE4724EAB51DB97DA78A30E63BACF0673461A4E1BD7E8DA23E9148923DD49954BEE45568EB5DF4D9836737B0199EEBF768128328A8A017C874B73384092C1608D84F30A53F4C360B15331F3B30DD991B9F2AF31ADCC496E8E132D6850CCBE26BD072F3A01AB521E94BF0EE6F3C9C970C3729EF88353EB95FA5E433422F0D3D4B9E8DC96B1BC40921E83F097E5ED6CA865831EE3B8DE5278A70A44022431DD220454FEE412DD5C02DB70740C2D579607B807C376DA1998A228DFD783DD56B4FB50422B7291ED16B429AD1CFBA99D71BCE5C0E816A64F4581B418D3E15BE56DBE8C8E6D6F6181859706F273885C58A753E6F3AB3AE146E70BEE81B0B2EFD9ABD4B8643EF9C08CAAA965F298731301518D730D3338B7AD2974830F3A31AE86D882574AFFCD5F0E48A78C2DB5DFC22019165B2C126B480C4767008E95A32C0F5ED0753FD008FE2504EE4C52379C0F1E15C3A1E699F047E8373F51B5E3A02AE8764A2A9C92FAAC5084646ED1B06BA197CBF472F0625E7FDECC3F4AB0A6402D8EDCF496D2B3D4C9D768D9AB112487824DEF849DCA84763DE68E14372C70F60AADAE8F67092AD7BFCA355B6CA04994713DC1DA60FC77B609E306BAD882F13C136A2619CC6ABDB76CC12AA49B33EF38E0665A706F68997E4765BE8D97CCBEDE34A8F523F16DFE6D27B3B0ACC97FDA8A3C125EF1623E7D16DD0D4ACC5D898FC7B62DC7AD2AFA7318568F96AC3846F66802B61BA92E2B2A4C7EDB3A5C9A7B6F30FF3DAD4BC68B6EA13C9859BB375A4E022B56108EC4656A99A7951D743BB1FDA9E6177A6B467374B285931525C2AC897986C513533D20729804E030C3EDDEA28E9A815CD61876261DCF2C3D983BC78FEB20E37399B4C27EE0E4075D7C40279605F5578A4D8BC6B91FFB9680EFA88537411BE1D21E9A8EA3B79F4C02432F4CA99D500D7C422CE61B7A0024DAB5BB35510143AA3130BBCEBFB03F0E3DF271EACCC27FBC6DFBFD4CD08B9B7FEF47A36A558214082E179224C080AE90A6698F560CE2144E51E56F5B7FC717E8B0502748B3DB9A8531BC517F189F83EBBA47FEAF87186BBC0042A5490BBAACAF5D1CAE01009E295C16F9975560132027E114BC5D5C080C7D44E3BBB6DC033DA62D1573D70B0222E176BC94F5B7AF88F1A5BEBFDF778BCA03B53F041AEAFD89B2C5BC8E0FCA56349168F6608BD50F23C7C63292CC63560F43FB0FD2BF5872E8E860257072CC026E5EA6E52A821BB93300BBB77FDC610E6EA5C284B9CCEBC0746400111A5AA913509EFE3B7CDEDDF7C0EBEEFE923DD697922890FFCED08921F142F8941E631CCE35F0F3B404E6786BC3F5757C19721AFB6C860B6B29370A6B95700489F3068D4FA647FB44E464C642C1A9ACE9CECBFA0DD247AC31AE314985A46A76B152E2B20115E05668C9310478E71AFE87B87A2D902150B9A3DE0D349C127ACE8FADBF31A0B4BEAD318A8768A04D11B64D47346CCE29EF7B5B42A97E3E2FF7679DC1A23E1FB4E4B2AE6E2ED5", + "k" : "4FE4673AAECD4AF5DA869C6F35A2E82467E349F0BDC2D623D1E92144512B61FB", +}, +{ + "rngSeed" : "F170583CB451D8A45D105457C02C01A33A40350616ED8515BD49067142F61EFB00F07857E4FFF3FE11E7164C648C76ED", + "pk" : "2829B04A621A204A4E63A2308D728B28C16652FA939D455181FA1B7B44447D1ABC83E46F9D5C4133B104CBC1369812BBF9E83AE1E58F66F8B7C2E56D902CCA69DC841F31372B783BC6421723AB0B2BC21CEBC7CDAC0CC3C55A3A088C0D21A4271264945766740AF06FFA65275F9C00B44B1B3E6823D3C29C0A509BCAA2BE1486972DC178821C40A203849A3ABEF402408CEB1E543C3BEF193417BBC0C5679C13074063E83EFF63AF43464B3CE47E4B86953BF21583C2515F7B1025BC0E50454A08313E915882DBF556FE9B18AD27250030723DB50E5DFB2380D8B74874C78862A1BC9083E1A8438E546FF9CA64C4A53BD17C1558067206056A0F222C8A4A00B2A92631179B6AAC71FC711CB635B008F28CD69B51B5D7AA6839A1ACA1A0DA854FAA39925CF606AE20612FC9C7573C73393A033CC8417D427DB29BB6973546A967354FCA3C43223A657713E150262E5621053BCA46931248386114564CD4C0861D4CA648E789EFC4221F7A075DD8B119AB7BB3F467ABDC6CD3C808D1586199EA7BE6E75C03916DA4C012D8E81843F472C8504FF4239D3C0881E0E664F6E253BF2112BEB301F19774E6998D4E8B68332346898087F1B7460B664D5D10B1AE199BA661CC460685D56808D6E66F3A78B6F5382EE3EB945482A1419A0A509A8909E8AB02990166C84905C7533159A9DC447F11F649E367486E2191A6C48B61331FB6137051B1410467CC440C8D0F9C9369B8803CFB33DA7416DFC47DB6726440028B23807C0F68804915A09AB16C47287D4ECA5F19B98839030E9606815629B1E153A5CDB954F6E3281749040D91061DF4AFB67A5F8B19B30ABBBE9B4B98B39182C4E48D514C35B515CDFB5BC61553C7EF047B17AC2AB3D10FE7D86A78386A0589072FC58983058A6959915B12A80EC79035C660AFB04E9670CBA471125E7A16D9FABEA6ECBFE1D18904757B0BF6A459F0087DD193BE490B4BF87BCAF772547B863EAA703AE18B58926AEE14CCA8015AF2939A49E29D546B968DDB17EB62B9EAF9CE53949E7477C4E9893A40766A4A15CBC392C73B313A0EE3201431BF3D5555DCF73174F3299C2B88DFAB4430C08C94183C27D1035C78769B143563A942047035A6C2373A03C0BCFC3973DB4F8F25C002C46376D6A6FE103BC641608E98948D86BBE6E89D5405542587AA4821C30AC8756F07C593044570F536B4B07FB14B3236422D01789822AAA020E4ACD92126809B2D47F49049875C15472A37B4B033FCC260FCA04AB629474C9B82450AE6572D891A58629CAAC895BF2F52BABEB6974BE787397243B20A99F37B52EE77934ED2B6157AC3351B9C0F3405369885A54BC33B2C487200BA8A326B9D1674209924D3D50527517978EB040BF85CCC9569A6B3138F072084595825A994078A09BEE86ED1E75EE9E759B31C491D9292FD2ABBE3CBA62661AD9440BBD392CB7D303CFAB4BD6B0130AF1C3336E2768907AFF0633F18F9BBA3706434B3BCE7C75D6C40753B6BBEAF11C47773CFF33B5067890FD5B8548E66C33D25906A066BC421617A909196A3986D362D3B80095E1077A5A087238054F2D89E0FD9A0D570C5EE2AACD3ABC16111189AACB4D2E911ABB7AA5099BB4A269D760174C324094FE944A4DC55D7708395F6AED8654831F7C3ECD85BAF03C44390193634B16E1C91AEE33979666EDFB18D7713C547A90FF9514BA6469E0A6716FF4C0420427BF00B794775043E162E798871F710C87FF423D5580D873B7F624C96C7D63E23EA02B1C800914A5836FA73D7A748472B0B7AF3099EB933F4A440ECD48262D4C9DE4C044EE30CC51877352B53B0C1C14153C88B44931DF12EE8520CD07117A1266815B74A431652D33074921C1D6DD6C0104AAA3F1A84E2F7CB24461290FB321D706113B172A2C7BDEE921DCDC31640F9C749F4B27D024A7488728F605F8AE904571062CE9B36C009937F51722639782D56496FC056B06B8A4A6C3F402649E0C15EAFA83E85A40EDA43433C44B6D8F037487C9E1B66622C6798C94B9228C7A52BD18360E07AC4B057218469AC09B397477D7F5325CA47B901D0A5D0B6977194A12F71ABFBABB3D910A8CBC52CA0DCB4F9F52D36C22B71B8513070C1C6C9A33397C79E4680862196CC1C3BAEA5BD04C58AB295B5DA152A98A6AB3035B2C48478F30CDFF392B47DC011E8FC82E0914E5AD3C8EAF0F76A57327C62BC9D4D", + "sk" : "DF9A22DC6C97B1E41AB3D6B79D183B1ED95C6CB32277A25155D380318260933CB26E427FE1D6BE2E40BC02EBC9E85A3850B30689ACB277096D8D48CF9B3C6B699864FC4B085BA86FD2B92396DC384D03428CEAB2173380603B49BF2668AF38967B4145A427C04A5541357771256277F7956335DA5BBDA033FC7B3909321777E2991189A93B730FEEA54FD6445796726C52752A7D11235C8461C281C9BDC3651DC72B4BC86EFCD5CC62A18ECE4B6586B2B0BE374CE392214CD175117453D393842346ABF0A0527E791E484C08B5324BC0E489CE327EB536609C4A646330A3D1168401F9420ADA3F4B7104AF688BB2326908D023F990AD064B6FCB4AC12903290E93BEA142A092C72B9B77B56F27552115057E6A7E92822EA635C1419159C186690E67BEAC07785E0A585681C67CB73AAD460378691B07D653EC0308CD0C21058892D34C437A5BAB3BBC83F660B644507A5DC00AD5E01A231A7D426764B9561C974490C85911ED94330CE8AB4B6C0C72D67114096691D1476EB820AE01AC8DF78AA1FC10D2B898A8F600CC1878360961EC5018D7F63D79744B41DA21BCD086E55A83E1B07AABB47AFF6831E9BA51DCA086208531D1205E8124B66A40A5C0D7249A29A1A218BE0F6091CB8135F552B81C397A000AB923050D167940CEF362BA796B9BD7B7F1A197C8704AB51C63F362C368C77DD5563B82336EDB912984FB144E46CF21A11C490CA7E8C66CAE89772B2B96E8085ABEB82AA8E33DA4B56693F81592545DDF9176486350E86229B423072D586852328E7BB2065D5A7A8600AEC4911D07271D75924D412494CF77B868AA7B192A11A5D66EDA19A10EE8C051D456FE7846BC8C52A0923D76E7B4E5B27BB2E2A03F8C214E6636620B54B893A3C9BA9BB7E68546626F601C8591BB33537B71B9302A15B81D6FB7919202C45C0341E3E17B9CF39964A4A48CEB4B7D936FC007C486F40B4265A8CF677AB5E97D1381BF1D8267E4445AADE22C4FD536392A6219D3C9855B06DE9610F714A5EFF2158F4AC31A29B71E0A9DB207C2075109C0FA762B70BDACF391399113FD8429C48A6A3EDB5D465A45E357332A7A1FFC414325849D9325BE55586AA9535F85E20DDD2696A615139C037757514295173DC7C92A5274C1571C0893190C5513C990C5C1FCB67AEFAC3BE248C9111C752C94C180FBA60064AF53D35DED934D7C72856BBB9703FA43AD125E285626065869C10027E0C374A28732BB238B426905491C25E73907D293B40777782C3AC846675502958BBA239597FA230930B515996E5B3054581A94F0F848CE13AE14425AAF593B175635B6DB63131C14ABDC4BE6E984E62BBA9F95A9C3D986C71640FFD1A3585C20423068B52662929406945199FA67A87F289CB15B85E6B28099F3477B8166D0D398BA922C22A1319CC168B970C699706EB87891B1504F99F91919DA8300A49DD8D292390C41F9735BA65C19FBB83C80E08392F10B31C0C18708A9B1780E253404BCD5753EB75E269B980EC34040A4495C2146BA5A1EDF3A8F228BCC10206D2868AC73318A361318BE704518A71B0CF65EB91823B643392BBC02B0E0835832ADBBE34577119C75171460A891EFB51559282700A80E65797E6B367D444C024332A5BBFB2B8C9619E1498ADCA52E985A9D03B91F356718E15BB11AC4BB133C08BB82C2A9FA0FF8785E92902818D314BFF162BCF5393DC0B2739A7271D02606673EEC47CEC412484F9B1437C688B3F147F1792A463738649A0DF8D0480E0A1CDFE3107D48C5AC11C3D7DCC204B439EF3533DDC2098CB22746001AE103C8D99704E7974E27B710A57CBD9E7A4509EC96374B648E6C49D0B0B0B7354E3DCB206E5B47942A29C0C498C7A1C1D401AF425A604C729A8FEA21A77AAB00C67DB762B5A32CA0E73AA9F5E2319AE5CC419C964C418F19276BBEE6AF76AA4FD04278D4C28AEBD4CA01B6999A5C8068540A07C2823116A4E56468ABC468FB222F32326BF5C02EB313C4B4AB4D92F408A60047D6890DE1EC3994E23EC757C138CAA5E3CC14B9D60153565AF3C20581A24D2684C4D251AEA1B36E56042FDC7C922812AE69796CC4912C882C5D46B4A2AF9874D91C3982660C2DD6749EBB2484009BE255177C9AC65623C65E0A896B1979E9CCC093EA5113FB59D4CC6B2829B04A621A204A4E63A2308D728B28C16652FA939D455181FA1B7B44447D1ABC83E46F9D5C4133B104CBC1369812BBF9E83AE1E58F66F8B7C2E56D902CCA69DC841F31372B783BC6421723AB0B2BC21CEBC7CDAC0CC3C55A3A088C0D21A4271264945766740AF06FFA65275F9C00B44B1B3E6823D3C29C0A509BCAA2BE1486972DC178821C40A203849A3ABEF402408CEB1E543C3BEF193417BBC0C5679C13074063E83EFF63AF43464B3CE47E4B86953BF21583C2515F7B1025BC0E50454A08313E915882DBF556FE9B18AD27250030723DB50E5DFB2380D8B74874C78862A1BC9083E1A8438E546FF9CA64C4A53BD17C1558067206056A0F222C8A4A00B2A92631179B6AAC71FC711CB635B008F28CD69B51B5D7AA6839A1ACA1A0DA854FAA39925CF606AE20612FC9C7573C73393A033CC8417D427DB29BB6973546A967354FCA3C43223A657713E150262E5621053BCA46931248386114564CD4C0861D4CA648E789EFC4221F7A075DD8B119AB7BB3F467ABDC6CD3C808D1586199EA7BE6E75C03916DA4C012D8E81843F472C8504FF4239D3C0881E0E664F6E253BF2112BEB301F19774E6998D4E8B68332346898087F1B7460B664D5D10B1AE199BA661CC460685D56808D6E66F3A78B6F5382EE3EB945482A1419A0A509A8909E8AB02990166C84905C7533159A9DC447F11F649E367486E2191A6C48B61331FB6137051B1410467CC440C8D0F9C9369B8803CFB33DA7416DFC47DB6726440028B23807C0F68804915A09AB16C47287D4ECA5F19B98839030E9606815629B1E153A5CDB954F6E3281749040D91061DF4AFB67A5F8B19B30ABBBE9B4B98B39182C4E48D514C35B515CDFB5BC61553C7EF047B17AC2AB3D10FE7D86A78386A0589072FC58983058A6959915B12A80EC79035C660AFB04E9670CBA471125E7A16D9FABEA6ECBFE1D18904757B0BF6A459F0087DD193BE490B4BF87BCAF772547B863EAA703AE18B58926AEE14CCA8015AF2939A49E29D546B968DDB17EB62B9EAF9CE53949E7477C4E9893A40766A4A15CBC392C73B313A0EE3201431BF3D5555DCF73174F3299C2B88DFAB4430C08C94183C27D1035C78769B143563A942047035A6C2373A03C0BCFC3973DB4F8F25C002C46376D6A6FE103BC641608E98948D86BBE6E89D5405542587AA4821C30AC8756F07C593044570F536B4B07FB14B3236422D01789822AAA020E4ACD92126809B2D47F49049875C15472A37B4B033FCC260FCA04AB629474C9B82450AE6572D891A58629CAAC895BF2F52BABEB6974BE787397243B20A99F37B52EE77934ED2B6157AC3351B9C0F3405369885A54BC33B2C487200BA8A326B9D1674209924D3D50527517978EB040BF85CCC9569A6B3138F072084595825A994078A09BEE86ED1E75EE9E759B31C491D9292FD2ABBE3CBA62661AD9440BBD392CB7D303CFAB4BD6B0130AF1C3336E2768907AFF0633F18F9BBA3706434B3BCE7C75D6C40753B6BBEAF11C47773CFF33B5067890FD5B8548E66C33D25906A066BC421617A909196A3986D362D3B80095E1077A5A087238054F2D89E0FD9A0D570C5EE2AACD3ABC16111189AACB4D2E911ABB7AA5099BB4A269D760174C324094FE944A4DC55D7708395F6AED8654831F7C3ECD85BAF03C44390193634B16E1C91AEE33979666EDFB18D7713C547A90FF9514BA6469E0A6716FF4C0420427BF00B794775043E162E798871F710C87FF423D5580D873B7F624C96C7D63E23EA02B1C800914A5836FA73D7A748472B0B7AF3099EB933F4A440ECD48262D4C9DE4C044EE30CC51877352B53B0C1C14153C88B44931DF12EE8520CD07117A1266815B74A431652D33074921C1D6DD6C0104AAA3F1A84E2F7CB24461290FB321D706113B172A2C7BDEE921DCDC31640F9C749F4B27D024A7488728F605F8AE904571062CE9B36C009937F51722639782D56496FC056B06B8A4A6C3F402649E0C15EAFA83E85A40EDA43433C44B6D8F037487C9E1B66622C6798C94B9228C7A52BD18360E07AC4B057218469AC09B397477D7F5325CA47B901D0A5D0B6977194A12F71ABFBABB3D910A8CBC52CA0DCB4F9F52D36C22B71B8513070C1C6C9A33397C79E4680862196CC1C3BAEA5BD04C58AB295B5DA152A98A6AB3035B2C48478F30CDFF392B47DC011E8FC82E0914E5AD3C8EAF0F76A57327C62BC9D4D63A647D85D1D66436CDF42CA198A44B31AA9F9D28B0311FB858CB5ECF74EB7707E30DD3B9F9D66518A0525F030574C504AB3851B77857B70858C130CA20ECE35", + "ek" : "1BA560912A0CB2D4796E89153A7D9B5B1871693C9F1656974FD96DAE81EE2CEDFF0BF4091E95D0C6C90D23446D0985DF96884FA5E0FAE648C40CEF09F16F6C4EF23ADCAEDC888F8979A7D71358811B933010E866F2325816A47F0BDDD5A7D4CDD7DB3272E6A5F1D2811430BA810E866D9243A5E1486EE656D16BDB26FE3524B4EFA40411F68207277653AE5B5076563E2889186F9572EAEB11C7653E0993B0C8811D1AAC3E1C4E7BD2068BAC45FA032EC8B41C4833AFDACFAABE7F7BC82ADC2C48CBCADF17C84A10DC9ED99D5F94CF4A63BF29A4E28E831E6F21A851070D716CF9E275B95E895902C01900ED8EBE0D63851F2576B6F5B2B8E4CC3FDCDF4A90F5A9ACF0147D4F16F63CFBC9CA2A5256FA879F88B7886EA6DD8B2C81810E1332963205C43052A220F345BB33E2F01EB143F56EA095C0243C8D9A4B457035B4A58620B320BCCE24E8281C3136AA49783B93E69CB07F42B805605508C4219F0199363677E34DE084DE03218DE00EE820F15DF7E87039EEF1061008056082B3BAD9F1AAAD58ECDE0FAB64E07522A84BAC8B0E3DD64773CE594FC96F44EA910A9E96EEE15893E1380B87D55ABFEDD6276FECC6BBA718FAB766A38B90A5353E78DBBBF576624E5DE6E98E8C056781BC3A94808ADEF0B73FAB49C75E10D3164BB42311C0EBF85128BC1171273BB83EA4DFAA75C114FDACE5582DFF4FD64C938AFF1150F74D548EF81FE5610591185CD6B50542647CC5AB046B11BF44F9718DBAFBE47D9A99E886E1C81C9323E13750BC2B58F9C19E2A7AE1843A93051339696E89EDD0EBA042CFB7AC16AA99DA9B3E028562BDCB841E26C5C7B61E029A29B2202E734CDB1AD53F0BEF5688D0716E8514F58000AB43CDFAF44B4933C81FA665A901AF7327B6C311145318093E5B26EF49272B334B12B70B546DBF30FB185124D9E12FD97718AF2903640B36A8CDE49B65BF8C14C97F15500D40704BF635AE86B66C79260342E33805DB42DAF5509BE8ACDC6BCAAD94E1DDDA1661573FB8CF880ED3DD7A3FC47BCDE21CEF6CD37505362FBC5AB61CB77DFBBED1BCE553A919B16CA92AC018208735853094EED4013D576767313DCC1071C845D54055FA5E75FBC55C5ABFE62C12579A17450898700D554184153EF1F23B74D7A2A637E43F0667BD217FB529D8D4269101EEA206F53898FBD1C8D22B71318BB0650F789A74411C71B6E7E0318DF306F644438E4C0185F1250433FA6BC36ED0B25EA9A9E216DE7CA86D49649049C5A6625150E49BB8B4EF012343B52171690EA914FE110AECD5E24221B93534DE308EC390AAC82B2B75B9AF58EF0FE7442901F073E6C15FE0567BD0CE694AF1C1388AB944803899F5F79C8C980E3A7BD29AD7D6A3B04D02616F0CD5C710292C8CB5870C3F1915576FCA4DD0AD2C7FD1B3610EC136C04BFA5BD054A46D80B0574C3F70F0BCD55E0054744ABB0A253CE410D44AFAE4A35D652E183FEEB14D3A9D5AD3C6520D016145C20EA25155D790501115FEE28B2E5E9F5068483C9A84B74640622C790E5CE0959CC154108DE92B88FC7040FFE79B436727BE1F72F5CE3C0099A800F6845385320BFA52B1BF679994541B73A12C727C7484974717AFB294D5DA9ADF735C8C2CE4F8C99AB158A56E893FE4D00765356D026C9298F03AD5A34E1C7B47AD81F3C059D7AA8067FF9E2B0D61B615BB8EDC81C28B38A9C3F4D48C4778E415ECE0AA413A941D4D888709A81E49DBE55A1B7F042F45C60146B6B09DE58B62DCC26997B96D6490CDDC56347474EE101CB59B2CF20563C6824788119DC0F31C11AD95A5E1D25E1570FE4F874CBD2B7F5E0E3F86E1D6C4D8964A168E678208096D45E0B75E9F4DBB0A03E7BE9ED152B986375E6F4C79320A41062E2984A7D268BD6D7DF5790170C7965E9C51F6EB18DCE7239F5F5E894CEE16F96039E825434E53271319C9D24EE2EA5315B537FB55BC5394F37DCD9FDD73DF0BCE51F659AC619CDA503AA2C762DE2FF20261F746E3F882336484A67391F73C174FD7AF16E01E342EB26D2FECAC201A2D75EAF74ED6D089E11250571D93AB90E1CFB940AB9A51BCD4924C35A52A8E82A02C1939129E72BBA6F535AB8F045E0D1E0C43CCE7458D1D44C9B4E58BB16847BC7E2D6AC37167DF53FC2E601264CDFFDECCB0D92A2EA7380211498364761577C3F85C1FA4137B3C90C7A9ADB50F087B2B63B87A89", + "k" : "25BB8F318B6AEF150E5494FD679DF50532C397A3D640D1D2DBF4E0201B279FF3", +}, +{ + "rngSeed" : "44A6774B2CAC02DFF210FF861A090561A453DB311F47B6FEDB81811872D5D9489F5FC4103010139AE53FCAED209DC9BE", + "pk" : "68D31D58C83101C3626170B992C2AB3C181F3D58B554249AA9E73C9E691BE2C6C402755CE0737CA2E2524FF59D3397B417965ED4C547F8DC97252C58F4367379F4BC9DA75B64B4A40A329952623F0615117D28AF7CFBB994B8AD70B2540978242CA0609A082DFD70AA5910778FB1CFE537C5C1AA5612029D9B972AEC8235466098558C1BB4FA2B84E1CF9C16300035A57328B460B20FACEA43D5502958B968547B60A3C9255EA20FAEBA1F4E69CEF343A6F3793D4B0418EDEC073909B6786A38FA3337C61C8F7AF5A796F41A3731A4CA6096382423C941616452B6A5438977445FFFF43D54E7B787CB9BC6C95C36003D87B9BF08934996F7301618C5A2A9B6D5D802D57C02018B44B0D95C5AC1C46B910DC518277BE4C8960400B14C51EEC975976975825B2D574965C338C121A056E2B9C9CD88CE4111C0EFF01DB722734B296540AB44A40214646C32713C87BBA448D349CD5B160DB48411A77593886C81AC1B59D10B51E8338A4178082EE858FF3987E58CB7E2A58CF23C28CCFC6141270C5ED0B883D01092C3095F0ABAFA2C43EAA7181136BD6E2B0C332B3E78BA665C73304DF21D83CC3915F9C8073B7D6D907C13BC4A295432FB0A894958B98C9629D6A025E3368FA234399AD0AA5F8C8FB54B9AF1D3A18D1A7EC1B22E7F5056C0D97595A801885202FF8C9CE2315BA340924D1C5E2EFB2DE7C1A468B684C8F7A363EB98DD4CCE7DDAB73447A5D263B2CFC4129BE74174B50AE359C69F086153AB30038A13AE21AB5EF870C44490990806C4936EFF553CCD9AC01D90B1E3D54BBF943B19236B935CAFEFEAA1059823B1D928CB77CBDC0CCFF4024E79219852C0653ECACCC3D9292A18783C10CCE69732DFC4585C8A45138AB94EF2C84DE2AED22B98BEE16BEF556331E56EB43C3D92E55A7C1BBC0474251A70AC72D5CDB9B2A9EBB9BE53C0CFC037C1678A1351CBA5E91BCF7147002518B8C8933CCA1C34F9DA03D2B70E885059B259B499901B98345AEDB9075AA1686E36A85C6337F01B4EA2F2AB29939EBA618C68C5256EAB4E6C1A1BEB334F93E99BCF3CB31012B1252537F8D1A589430B46E487AD07CFC5C58A2865B0A92A621006248A46C837F095109A3DE16B24B2339A509284C9055778816E9656C743A8929CB622F3E34F0141C820D231501C920581BC259C8BE8B0928B58B6F1E2B34B628301230FB18C3904741A0F061CB613B560E972B406C44E154724F6AF887A345ACC63065481C4B468423742E742582386C00F2531C67835F3C679EBFA9AFF871F0B006C461B760FB3171B99C9CC74A5378C3AC78C87C847A65F4BCB5043A551C223418114D58BBBF6AAA4422AABD4D70E7D78A61FB1AF33882EB5BC886D154EE032B0CF300EFBEC2ACC811CCD2C6968E90F6D146DBEB0932A569896F96A91BA3298C57C5EBB4AA130A7730A996054B9C058057FDB41825A2323799BB0A51FC0018428061AB3F3C12A6479C3367810ACC4AA869867F5888A90A1AC51913292A194F1B3D8C976902221D3B0C607714F4FDC8196859C939B499E511F54E52D059A25449068C39081DD59624A6515E282935EA454CAE482CA990A378A3B41E0B0ADC6702A9533C0C479A4F6176BE1A9A081A357F5BB98F835ED13CA29EB969F3A7C759B43464155EA78067752534D1044BE2501C38387B31C662E6B9CFC4584E5DC43CEA0805E273D9E56B71FC924204C8AD82CCB315207AFE34EFEA97F72A21760CBB629D6391AC85FE28AC568B1B96AD8B888C9CCEEC93FC08825429614BE352C55AB218383CCADF0BAD13862778BCA36285D67381164F5853340C0B9516EE3916700F4C3B8326E497BA7966456B6144B87F70C89CBC07A3A553C60B80E01C0C7E9297EC70E5A3017E906CF24593F86D3B6D1DB26004B8EBD7047339468183C20DF37055637995522A8322B04618B123BB3B1CBF765BEB8CD17A302B88166FB84A9BF1728BFBC57853B7DE3F113257359F6B7835E9953DA123BFCF545E5E3541C8620F5F58872F1192B67424B5A9909D5324A342FC74CAF906C69FBE3B2384A2A9BAB153439241D6065E0F944EF67C4D6873635B3650BF4CC4A4B879CCA63B6873C8E681982E4A183557E0465BB0F60A8B9D97625065D4727731E173977A95E7BC2CE3494B58071C1B89B1866C85FF814AA4843F7AB5BEE6124C2166757943AFA3DF3D5F59581246CDDF8777C228D", + "sk" : "536B38508A50A06441226094DD386686E461226C3A3C121F4C906608F7A78CE66D7F574D479A7154C87E1E88278409968859356C7B6DCFC0A9CFC473E670BD377849619887AB701C3C4A1D2BC0B6A9633247CB47E8305D983B80A37462512B1E587AB1A80293D3EC1D9C785BE97B7960E96CB4BB2A70454D5C619022CC647E12B67F786C4F386F68C03CAEA65FC0C14D8D0809B5A181F3FBCC5446037A00BED867264F167C69152789E38399356E1EAB187490B8C8C3C5B8F226BFA41877374D41972C151B11168C5D971740A373967492804BC988AFC31E7CC195F71C8CB4A53C39D16666982685368194A70FDC0B7EA96729ECE4085C6C59AE12218F649E1552998D571C0A41503FB278C2195D16F79012251ED5EB281AE05F88650CB62017781B7CCD534A0646A4E2E2A4A8F6160B64CC3AEB4CD78C17F633068D299B286730B2DB36F2963AB421B0F3DACFD18A5A02AA807B47231001AC238C176BC01646541F465B832C448AD4F157093C8D26B0B1DA121D17C21C71C64BDFE4793095C38D930B7A26A85C87C5B87821C389BC4F3CCBF42424D994754073605C166731A48923CCA3A30BA4DF4C2EE7457D5FEAC30AB08B21B71ABD66C8173A84587A047454AFEEA38E6EE12936743195EB79B6548E73822960C7428A7B36C75B5F549B66F2B30AE3CBCC4F10CBF672817B9B45305C7CF290C4C8C60AA2D443B03A6418B8BB42309F2D912A6268260D35B5C2D72AB320617D114FF649308789A3AC88817498333F2C8E65F47A99755929B35AF1BB975CB804C7F71469F32027C33E705C12E6AB4227F2BF37EB2214B66A00C556CCBA44EE84654212495D96983EF16D9AF2B848919005700F01B58B3D5667F6220983E1CA9CB8CC1AB09B609224AFA0269F935D99D92535CB2758C24F08AA76DD1CB889320C187C48BF781A10CB3762E402F3E39CC151AD6B7C6C8C50B71E7682364314A64C6C8E799915D84F50B37403077D41C76062277B6A1354D298427C31B52446864AC075E4229B598A9BCAC0C03EE1934207CBEEBAA931C18870E7787F4718830A932375935759C98DD5074CDBC3A2CB6786EA21AC928B34D675ECC9AFFA0C8C0D341FE0588A8A6A398E994EDD03786A167982815D693C9B149600FE5B265A94697ECBB5A9632F3A158E0EAB8D06DC0BD176BB02172C68851237E7BD9592433CF97B33017C32BAC8C719926C4A8CD6788F494806E7821EDC0C798CF6424767AD4715CF2E02C806565B5829BB4D9980210566763999046075AD12612AE07D6C0394BE26CC1C375C757CA776F7852002B6E1FA8F44DB1E643753F1DAA627799EB8D320EDF134B5362A7079093F519DD20A9FB662CC47E373EE81A058E367F4124B8DFC7EAFE83E2ED7693E46BE701AA7A9E3BA45338AA4C9C26831A5B1F7C03227C97C515E8A1B154EA910D7265AEE1C3F16198905E9C3770AA5BA924FDDF0433EDB6DF1AC0D2E6282E018912DB1C056F613BFFC51EFA044D995BE8A83A5560A4CA3C554AC538A45060B42CBA3255332CF2529795AC109DB6715D87810E697D97A4C88FBA86760460AA493BC25B2CC6BB79E3B1391134EC2934165A77F44B81B1416799D027E488450E43C42792C7753A8AC4805C13CE7A654B4A1BD881503A8CB3ED462E40A42F71C280C175663A64657FB61A9D8CBC58452141366A1F34EDDEC4E8C40B59D82A9260A68727431D8F36A614A8FFA681774C60587153ACA0591D212BC5C3A22423267D4345DB36878FC771C0319178A6936569BB778CABAA0E211B2A14EFFF4A4649052C60A9DABDC37350BB1C931AB2CB3854AE4999FC0A9F5D92A117783F975CE6D1297D7621A48FC0A2AB584D754B036A831051BA25B7B5B9E1442FC3A7F17D2710E7AA3D86B85DDF2ABEDC30FF756B2262A1D2D1165574A13E51373382704BC062F5B2261ED5053608446B7DB9E12D0191E1A2D41A0ADB4015696C3266C79497253C6BC51C20999B890BB21C8FCC9A786142E57009505694B7155B386C39B5C1B84F0791D9583D58A904EB66F461B2621F2C024B4A6F0CC1B2A7BCA62F5378FA1334B7B6F06C61CF5362CD4E3CCCEA93988EB757032A844037AA0186DF5703EE8F7C649C9785A26197C2593AF38C8F56B849BD68E12C696825982B4F2919D9942EC240178848F68D31D58C83101C3626170B992C2AB3C181F3D58B554249AA9E73C9E691BE2C6C402755CE0737CA2E2524FF59D3397B417965ED4C547F8DC97252C58F4367379F4BC9DA75B64B4A40A329952623F0615117D28AF7CFBB994B8AD70B2540978242CA0609A082DFD70AA5910778FB1CFE537C5C1AA5612029D9B972AEC8235466098558C1BB4FA2B84E1CF9C16300035A57328B460B20FACEA43D5502958B968547B60A3C9255EA20FAEBA1F4E69CEF343A6F3793D4B0418EDEC073909B6786A38FA3337C61C8F7AF5A796F41A3731A4CA6096382423C941616452B6A5438977445FFFF43D54E7B787CB9BC6C95C36003D87B9BF08934996F7301618C5A2A9B6D5D802D57C02018B44B0D95C5AC1C46B910DC518277BE4C8960400B14C51EEC975976975825B2D574965C338C121A056E2B9C9CD88CE4111C0EFF01DB722734B296540AB44A40214646C32713C87BBA448D349CD5B160DB48411A77593886C81AC1B59D10B51E8338A4178082EE858FF3987E58CB7E2A58CF23C28CCFC6141270C5ED0B883D01092C3095F0ABAFA2C43EAA7181136BD6E2B0C332B3E78BA665C73304DF21D83CC3915F9C8073B7D6D907C13BC4A295432FB0A894958B98C9629D6A025E3368FA234399AD0AA5F8C8FB54B9AF1D3A18D1A7EC1B22E7F5056C0D97595A801885202FF8C9CE2315BA340924D1C5E2EFB2DE7C1A468B684C8F7A363EB98DD4CCE7DDAB73447A5D263B2CFC4129BE74174B50AE359C69F086153AB30038A13AE21AB5EF870C44490990806C4936EFF553CCD9AC01D90B1E3D54BBF943B19236B935CAFEFEAA1059823B1D928CB77CBDC0CCFF4024E79219852C0653ECACCC3D9292A18783C10CCE69732DFC4585C8A45138AB94EF2C84DE2AED22B98BEE16BEF556331E56EB43C3D92E55A7C1BBC0474251A70AC72D5CDB9B2A9EBB9BE53C0CFC037C1678A1351CBA5E91BCF7147002518B8C8933CCA1C34F9DA03D2B70E885059B259B499901B98345AEDB9075AA1686E36A85C6337F01B4EA2F2AB29939EBA618C68C5256EAB4E6C1A1BEB334F93E99BCF3CB31012B1252537F8D1A589430B46E487AD07CFC5C58A2865B0A92A621006248A46C837F095109A3DE16B24B2339A509284C9055778816E9656C743A8929CB622F3E34F0141C820D231501C920581BC259C8BE8B0928B58B6F1E2B34B628301230FB18C3904741A0F061CB613B560E972B406C44E154724F6AF887A345ACC63065481C4B468423742E742582386C00F2531C67835F3C679EBFA9AFF871F0B006C461B760FB3171B99C9CC74A5378C3AC78C87C847A65F4BCB5043A551C223418114D58BBBF6AAA4422AABD4D70E7D78A61FB1AF33882EB5BC886D154EE032B0CF300EFBEC2ACC811CCD2C6968E90F6D146DBEB0932A569896F96A91BA3298C57C5EBB4AA130A7730A996054B9C058057FDB41825A2323799BB0A51FC0018428061AB3F3C12A6479C3367810ACC4AA869867F5888A90A1AC51913292A194F1B3D8C976902221D3B0C607714F4FDC8196859C939B499E511F54E52D059A25449068C39081DD59624A6515E282935EA454CAE482CA990A378A3B41E0B0ADC6702A9533C0C479A4F6176BE1A9A081A357F5BB98F835ED13CA29EB969F3A7C759B43464155EA78067752534D1044BE2501C38387B31C662E6B9CFC4584E5DC43CEA0805E273D9E56B71FC924204C8AD82CCB315207AFE34EFEA97F72A21760CBB629D6391AC85FE28AC568B1B96AD8B888C9CCEEC93FC08825429614BE352C55AB218383CCADF0BAD13862778BCA36285D67381164F5853340C0B9516EE3916700F4C3B8326E497BA7966456B6144B87F70C89CBC07A3A553C60B80E01C0C7E9297EC70E5A3017E906CF24593F86D3B6D1DB26004B8EBD7047339468183C20DF37055637995522A8322B04618B123BB3B1CBF765BEB8CD17A302B88166FB84A9BF1728BFBC57853B7DE3F113257359F6B7835E9953DA123BFCF545E5E3541C8620F5F58872F1192B67424B5A9909D5324A342FC74CAF906C69FBE3B2384A2A9BAB153439241D6065E0F944EF67C4D6873635B3650BF4CC4A4B879CCA63B6873C8E681982E4A183557E0465BB0F60A8B9D97625065D4727731E173977A95E7BC2CE3494B58071C1B89B1866C85FF814AA4843F7AB5BEE6124C2166757943AFA3DF3D5F59581246CDDF8777C228D53729573CE2F4F51DA212385808EF436EECDB8FB9F3C8346800BEB4B9E537D1D05913FFC8D7FB91C97DC1E0BEA9DC9955FA28B3CC0B7415C192F81912D70516A", + "ek" : "FAEAC438A461360625E0DEE10A0E0E3D7B1206D1A66EFE2D6777E5107FDA572B9917298AA08416DEEEA532D82367A61CDD4CAB223AB6906261BD181EE18BF7D0FDF1619159A1486C5FEC016E8EC8295D266DCA7FCC7BC00E1E18F4ED8797B6BB08C0EBBCCDF3DE06CA9A6A4045946DFA38897EA1B60C148FB65EEED59F8597BF4690E5FA2CB0B6B40176877F507ED5C1D600BB75375F2F62D91BCB6AA6F1B329195ABDFCD34AD8942CF65723C72CB354EA3B88BB32818DDD59BA66D68E413BE1534D0C9AE16CA6A5FFFFE0AAFD7B1A9E02FEBC28D93DEF10C1E1B955D1FF703B5A6FD90E6793359CAEE1A904BFA2A184174182F8212C0DACB34E8562E2684D0A904143D32724214D8D0F45576AC17C9E88B51E78355B81484F06DF0631FFF8041911BE9E961032728968313807EC1852C4F5F06269D6ACA6249871E72D515FD11743E45A4370AB98BA271BF57ED9BF965DBCBCA092AF59C5A9ECAD3B102EEDE30EFF895CF959A4C0401393F272F2F8BD8059A7265267981B137AB9EFADF7FECEE5ADF96BA780BB79C7C339AEDF2E7E441C2794959035B0F6F1313F4A57B1ADC284D717DD08AA3E3AC32C8AE542D667D3697C5C566D17B151C3EB1677757FF623C2442458FD8D507A22643CA7F74E2B0512EAC6278D4739DC6D1A107D478D21CAB9AE9ACA1B92963DCD03269F8A8BFC0F51CE1C29584B6FB4445728762D71CAA2640415FF2A925ED4CE562FE9F6933FB11B93D884C541A54D7D3E1B3D94FCEAAA82B8DDF5BF8EFFADF57666E754F7E34EF98B44C8CCB89F871BD859624DCA7701AF0F40129385B259168DC2147B6A9F862D0B003825BB56B6F699BA3E272915017413FD60E635C9BD4B7B10C30BB73FAD841250C081CE1E53F205A204BAAF82CE60AC6C31C18DAD2B7FFC618F54C2DE4A063399A1347D0EB75EAF1322E5B351583AE1B360D1B3DCFA10758E7438C7931E852F446E9EF47D483C0048A08F8C3AD24EA47A0829DC110D6DA81E6B9458976C1F64A8795E1C71F534491834DFF1529DCADC6B2890721291AE4ED7D20C18AEF49C04A0985C1D6FAF0040D499F4C97CB8A179532E24684CCEF6619A8F99D80E8796BE6C503D852D4276B64E32490498A39D86A7A28E854F29CCFCE95D26C7F99D97F5451FE987A47ED03ED4B368FAD55D2C69DE7A20D2214158A0541144561D55257455A4776852053CB509949745BD4587B6E2D8EE04E9C53F07526C05C3A49076A37958A33D5571D6A760044A004EC130773FF880CFE42EC756A552885072417B6BBC2028BD3EAE750A08052D350AC1D8AEAD3DA599C8ADF03876962E857E69E675CE0FA9E43034D3814EDAF29F087BAECAE3DF8FBEE883CBB9815AEC42EEC927563F5A151B80188D3A4327E2D70C2C77A6370E13C8D365390B8BC57E228DDD23BA5A66519921B36E22BB7D91BABF50EC4C68CB05914A69C27B90CC30D80BD733B4BE7DD19226367EDDBA2E25A190ED68DD2B3168123173F7D38B729B6D7EEE4EF4033D03AC3DA3171FD152C604B45C73C9AD984E98CB6BFCC0CE84A3A2F251F62B8BB8063ACBE41D6715F32619B35F674F8438932A90B6BDE802DE85C99E2A0B485E171C17778C62F5DE7AC5D497AE1C975C1CB0498AB736CC98D132C62D80DE186CB9C3DE150266B3CCF4702BD1D6BD0AA5FEBD9C6B3596F66A06250F6A72607AD34E56BA9FD9A7598A40D09A730E05DD6EEDF8CE30270EEF73315FFE74DC8E7FC49AB15DB04A2F1B9CA3186139D56367391E4A7132E2F775F45BA568DA018512772A1D1D701DF489E0022077C3927DEB8CED211781666672FD9A69D1088D430DA68DC6A6E6CFEE77686A45428CC95F977FC81532F3341DEB7284282CC63F09AE25A8154173367D8AD6E8647637A738732C2F02A9CC44DB0F911351175ED0346C4E161989465F3E1ADE6EE1287FF3529F924B165528C932D26E158BE76E1BC6A20D67A30E364A249413A11FC0E6803045641DBE265155642AA7A84DC3A676155F9E58841EB8CD9D3132E7037D8BD2032B3CCB2BD33D36CD2E7472248261DA19E31602DC02FB3F28F25ADBD4F2D52386B48D40426295C92EC657EACDC29FC28540E15A4D684DC1EB7C986FEE47420F799CD9D793B125FCAB34484511E7B69FC86D84C2608835E6976FC6DE0F05EDA38DC523EB3672A96EBE818691D89116A978B39E3BF50999F0FCDF9B8C6A4974F4", + "k" : "8C88B0C9161417F5CF7E69F67BAC58B02BD65F8A1E11533BDE2492A81BD109A7", +}, +{ + "rngSeed" : "49E1855588B6235DF2A400C4A70AEDF8AB17B6E5E2891AA745F132FA2E7AB0C8117C1DF37C39F5D57624EB77C2B4A091", + "pk" : "B2C2247D98C617419ADCBB5027B320E54205EC3B9C37FB528BE1BCB29624F0851A9844B83C5788A2332C0148C6C982BE4BA98BE6D9A54623B8183A66DBB8456473ACE4F18829A56D1523497E1731C524BA3545652BE97AECE915EC25CB8C18364FF961DAD655E2D08E14293A77963E4154B5D52A6D424A3FF976B69FD6C073B7BD960CC397D7511F76AEE624240CF6430D612385A21A33838D181C3F77197E530463E952662E512A538B81E72913EB32357577319D29599EA2CA2E088C91681EBB295C5FB3C4F11643BE6686F62B259C737C4ED37B38901EB7A79D5FACC426438F6AE228338439D136AB68BA7ECB760A3B45C77F186C177C2F79F47F7CBC2A43DA4B94371E4FFC9F8D520A9C1749D5B63B01A2AF5B7A10EE47505598CEBA4CA724F22FC15626A5243895DB48CD2BBEE25C27B171C44FA09D9DAC21A11803CE0A6492B72D16803DC793CABAB535EAA44EAA14B2D81A4162C32E73CB38A7BC945D0C1D6E0022E2785093D66C29E31616BA7EA0F58DEF02339AD231C3806600BA8612080D6DFBB50353B0FCC98DCAB2C07473B34E05A556D777CB1982BBE521B1CBC58C680606F352B1560E7E4589B905B50C299AE8D3328A3729AC0420C3D23ECA06491C43BA8D72AF0CAB1A869002434476BD7527F27B751C9364670A3730C52D514454E03386C66406A4B4315C8201DB561E9B79C2CA4C60B25044E6BC1253465B4D0206FBF695470B4B7B8BC068D391F5D0B7E9D8028F1591ED916DA33157CDEA92FF46AD98D18E1CE6C4B2F75854733E913C5AD2D13E23BA51B7F8C2D3CB0EDEA793B55ACC3995C97D3C65C0981F12913C88B56F62623F41E85A84543D4E4520C884981A3531D200CCBAEC0BF1096FA7AC429A9B3BC1A2B38DE159C2139361DCA3EA805D97E67F61D10C0911674FE148B33572797ACE2138AB478A51057306F010661D569DDD9A4E55E73F67F25F0DB09D61F1951279CB79D814D1A21A4FF311BE441BBBA97D81935B31BB4DD558544BABB18175B893357504589FE79170199129E78874882AA89B87C20BB03591F321419A41C1A78F87016B4E551C6928A37FA7C60708AFC03C8B5B17001AA3088DCA6AC9AB93FE5665F1781E36D7813945471F6945198983815C2737713F9C53A8E717BED4D9A7A706AC41D339001C5D74548388A2439CB0142BB6BCF2E23442155ADEB4269CB39432D31455F0191A25822F35C889F2962FF081F1C1B5C55B9AF0B14A414B618C7366FEF512D94077470440FED7C2D101B5C9EC7B79BA17CDC14653B6C3179261A9401A0B20BFD201BBE243B8CD1322FC872C4BC29889586A8E302AC26B043B605C13C1300A68C95F269B2EF49402786819668E964C921F765ABF805477EA239D3B8B203C7DB303AFE5A8C70158874981C663F1B3F8A645991CBE42A2498BEB4579B314918C85A8388F31E628010BCA96858A09E49365725B31D0726C0379709529C38B47E15678AC9625B28A763B579AF908CC1CC45A5ECB23E5A6CED504B9E3101CC562BE9714BF4931CBAB020FA3E10456D23D2D01AF6DDA8DC6E09EC6ACA54A3253F5D905D4B34B66250F80324060B1609083028A63AED377A7CCA6A929DA786EB080DB750CF906C98EB9A105F288A36427519C0087E300705524AC343B2C448EAD7802404417CACB6CA5A398C7E9C2A7B2855FCA298AB1BD0FA9C23AF9C5079496DFB2996A3738D5EA37CCBC24F1744EB9F5C672D74968C872392480FBA91DAF0C60FE96B13828BBEFC6156F860CA304970DE5695553A631A10C799B29B2585652065F33C6B53179BAC6473B4DC2B277284181C7A2A9491EA422C5087358EF8835BF5711DF91B38AB90000D324E7B6CE841830BD952E18583EAB6B6A922427B2D094EA633CDA75C94BDAA1A3D928FD2376A876AC0306B1EE631FE38987E50421389CB224D4045E260A9D34508D1739F223765A3A8F2699A8919B30F80177D9E141D7D9630B46CF5DCC4FF85045E62A4F0F86BDBD6367C1471AC4B22210771EB636C2BBE564578266B8682817A9118D95ADE51031DEF42E0D9CB273C03E3F93AC97395D9F09BE36EB8B2C21A4C74796AE501758B222101634D1668656B02CD0026C9EDA07C0F3BB7D99B7FAC6A78793BCDDB2A18CD4262039723F41223D336451EB31911219750098125D62110DFCB20E30C6D5CF75212B294EADF4AC273ECB8BB5BEEA59108851B4", + "sk" : "548B6BF0069239D110A3699BEFEC0527E89DA2E3792653549FB865D1E9AB9AB9250EE00D913B83DF22ACD9B4B17A23CD1BBC9C0B46B5DF36C3D5A636CD9808E08B8AFFE75D42DBADDB9974E8417C8CF14FFBDB8E89FAC43330BAB32C9BD8005B0A1C4948C04C4D110A6248AD52018549360B4E7A950A29A911E43250127A5362787D67AD2D85243EA92CBFFCCE1AC4CF4F979B59E47F60CA1156096C0F93A219328619FC00D2912D1A23BADB2C5190D211E339BBC3317E1A22AFE452492B75B0138600848894F3B86EEFBCCADA8C55C73877F9D9AB985004C86C717B199A164C2E25D79F3230368216800DE11FAE5C2D8892C5F33456DCB2CDB62392BFD1B2E7658C979B87D287CA62D052E86A1AFBD367BC066DE99851331A00E9461ADFCBC6B770471AC76BEA98BD52824FAFC790B41AA977481FDCE18F91528939C202BCE50FC64667FDC6C06E339B2CE3ACED139739036A7141B1D3B293EE188D57354969485238669B74514D281A7A5BBAC250CA154FE898E7CB42EF6670891B32DD97494F75AC96C6BD10682C682786D270BDD73A204AA340CDD9BA00162FF1787B81D2982D9A5FE90038537B65C5BC68BCC22BCFFA87E1415B79FB35DBDBB6AF8673E56BAAB96104CDE80B3D59AE0563660F8B068D3049C23C0AFB59B36D537DABD8C4DD2063AFC12B19539A845B51FB4594CA58BF967A9B87A057F7352D40C0B8E79B71E86A34A79116A5E13EA1D4054A35A65D50A57B61BB8F203F8F221C5A79119F0B3DCC2974038865B54C9711CACD1A2B306188235F36A173E99FF982A966D4030A84220604717E8B7726136941D80D23420FF3C599B623276E510567B499DA25ABECB32A51165F4800B95FB66B6AC1693E52305F32BBB4D980D8A53D83D44F754B0798E6596981C0260300BCAB8D55574C92A09AC86B277383B062857D1E4919E094B0B835B7848176A8984EC639942AE9A541FA0549D62570BAC5EE458130B0BB46C30FF3C8C7B2D67CB21785B82A9367E59D38528C82694D25756890B789FF86B9A755493EEA0B6F640AFD8C26AD833BE6014EBADC04A6866F2250C73CF5121522BD4D6AB3D8366E04676734FC92699531F5F6C0E595BEFBC425F91C2C978842595668415C59582142ED11418FE2983128959DC425B61183D2BA458C477E4B9338228B3AD1A16316EC976522B9EB95596628A3AAD73953B2877A038887B96A991CA938AA2615751B22F9429A65A8EA4C637F63B313B48F29662950227B702C6811B75564E58D9FFC3609479EE75205171C7DB51776177A2A83C74E3F61CFDE821F4B60B433902542770FFBF45D668001F94C553673742C96B76EDA9750F154E61362D4A173C806CCAF48ABA8EBAFA9648CD1B3A17E135840800CEE9855E1F4623F9768197B2AC9F5525C534C8BD7728BBAC26BC18AA5E412FDB92ED262027DCA769D9851917510B9E1A66826CDA147705F703512767A4D9245A2660ADE559956F67B7A012DF0A99FBF911D73367C0E7372E7265FCE319EFB818F139B84A5F652F183C7F2F68C1C252BFD69A586A716DCE522AAB98D94587DCCFC99A4B813AD60A15C924C87A9B11516188C4787171C98FB11466C59B3C72017D9AC1D9E6522B52C1CCBE45EBE0AB6A0983E84E8BEC3001EBFB845A14A47C34C9A74234676A28B33D2AABE157F56C26895E7586658649687CD7442832A1C1F2401207B51C676B90C41295BD609882E40A170008BE7C3909318593857B602CA882A998AB0265F5E162C60AA090287A9E7A3627909743DE22272AB0214816311CB4548FBB5B093C29EE57170121337000208759F6E224C6992C593337D62D3011E02CCD41015497190E9BA5DF520B3FAB78D68C2B0C18B72C8F67AA9E056A26BA52E32AD7C717472766F5BE4ACDC60B48EE38BF361B1FF52B11DF42546E30A2E0C3F37456FDD190030921E301C555F73B68E5818F285714333B5E2818C5D460994985E81C09448F9A58BEA16B87A02E4BC5D7765AB4936AE83B035A8878CE47A659778CAD7248733772B52459744362A51B05DC4D17F0E6B72FD1119B1D24D378B6B50831759870D2A80B8DD5C67E13A30A9BAB1CDDB0D5007CE2D2C7F391A654CE2CE94A77A83035F7D059F4016098F21A9B4633A96D634C32419AA073BE74B792B080BE8B672B2C2247D98C617419ADCBB5027B320E54205EC3B9C37FB528BE1BCB29624F0851A9844B83C5788A2332C0148C6C982BE4BA98BE6D9A54623B8183A66DBB8456473ACE4F18829A56D1523497E1731C524BA3545652BE97AECE915EC25CB8C18364FF961DAD655E2D08E14293A77963E4154B5D52A6D424A3FF976B69FD6C073B7BD960CC397D7511F76AEE624240CF6430D612385A21A33838D181C3F77197E530463E952662E512A538B81E72913EB32357577319D29599EA2CA2E088C91681EBB295C5FB3C4F11643BE6686F62B259C737C4ED37B38901EB7A79D5FACC426438F6AE228338439D136AB68BA7ECB760A3B45C77F186C177C2F79F47F7CBC2A43DA4B94371E4FFC9F8D520A9C1749D5B63B01A2AF5B7A10EE47505598CEBA4CA724F22FC15626A5243895DB48CD2BBEE25C27B171C44FA09D9DAC21A11803CE0A6492B72D16803DC793CABAB535EAA44EAA14B2D81A4162C32E73CB38A7BC945D0C1D6E0022E2785093D66C29E31616BA7EA0F58DEF02339AD231C3806600BA8612080D6DFBB50353B0FCC98DCAB2C07473B34E05A556D777CB1982BBE521B1CBC58C680606F352B1560E7E4589B905B50C299AE8D3328A3729AC0420C3D23ECA06491C43BA8D72AF0CAB1A869002434476BD7527F27B751C9364670A3730C52D514454E03386C66406A4B4315C8201DB561E9B79C2CA4C60B25044E6BC1253465B4D0206FBF695470B4B7B8BC068D391F5D0B7E9D8028F1591ED916DA33157CDEA92FF46AD98D18E1CE6C4B2F75854733E913C5AD2D13E23BA51B7F8C2D3CB0EDEA793B55ACC3995C97D3C65C0981F12913C88B56F62623F41E85A84543D4E4520C884981A3531D200CCBAEC0BF1096FA7AC429A9B3BC1A2B38DE159C2139361DCA3EA805D97E67F61D10C0911674FE148B33572797ACE2138AB478A51057306F010661D569DDD9A4E55E73F67F25F0DB09D61F1951279CB79D814D1A21A4FF311BE441BBBA97D81935B31BB4DD558544BABB18175B893357504589FE79170199129E78874882AA89B87C20BB03591F321419A41C1A78F87016B4E551C6928A37FA7C60708AFC03C8B5B17001AA3088DCA6AC9AB93FE5665F1781E36D7813945471F6945198983815C2737713F9C53A8E717BED4D9A7A706AC41D339001C5D74548388A2439CB0142BB6BCF2E23442155ADEB4269CB39432D31455F0191A25822F35C889F2962FF081F1C1B5C55B9AF0B14A414B618C7366FEF512D94077470440FED7C2D101B5C9EC7B79BA17CDC14653B6C3179261A9401A0B20BFD201BBE243B8CD1322FC872C4BC29889586A8E302AC26B043B605C13C1300A68C95F269B2EF49402786819668E964C921F765ABF805477EA239D3B8B203C7DB303AFE5A8C70158874981C663F1B3F8A645991CBE42A2498BEB4579B314918C85A8388F31E628010BCA96858A09E49365725B31D0726C0379709529C38B47E15678AC9625B28A763B579AF908CC1CC45A5ECB23E5A6CED504B9E3101CC562BE9714BF4931CBAB020FA3E10456D23D2D01AF6DDA8DC6E09EC6ACA54A3253F5D905D4B34B66250F80324060B1609083028A63AED377A7CCA6A929DA786EB080DB750CF906C98EB9A105F288A36427519C0087E300705524AC343B2C448EAD7802404417CACB6CA5A398C7E9C2A7B2855FCA298AB1BD0FA9C23AF9C5079496DFB2996A3738D5EA37CCBC24F1744EB9F5C672D74968C872392480FBA91DAF0C60FE96B13828BBEFC6156F860CA304970DE5695553A631A10C799B29B2585652065F33C6B53179BAC6473B4DC2B277284181C7A2A9491EA422C5087358EF8835BF5711DF91B38AB90000D324E7B6CE841830BD952E18583EAB6B6A922427B2D094EA633CDA75C94BDAA1A3D928FD2376A876AC0306B1EE631FE38987E50421389CB224D4045E260A9D34508D1739F223765A3A8F2699A8919B30F80177D9E141D7D9630B46CF5DCC4FF85045E62A4F0F86BDBD6367C1471AC4B22210771EB636C2BBE564578266B8682817A9118D95ADE51031DEF42E0D9CB273C03E3F93AC97395D9F09BE36EB8B2C21A4C74796AE501758B222101634D1668656B02CD0026C9EDA07C0F3BB7D99B7FAC6A78793BCDDB2A18CD4262039723F41223D336451EB31911219750098125D62110DFCB20E30C6D5CF75212B294EADF4AC273ECB8BB5BEEA59108851B460166DFBA8564A4A16E7F53E467431528A6E2D8B62B614D427846B701FBFF5F497C65A12D87432F475509F11E0884FB51B5D970C1B6D2C87C70590CF41C16B4F", + "ek" : "905190F6D0998410B0E910E4D3FE1D1573292D6E3EC4C33553DD7B12296995C0CD143C514715A2146F884B48157468A6C081C868DE6DC7D726D25586F8A26A994A8D8163BC05D5B565A34373DB83F47C3E08B94EC5021241D56092825A74AB1916A63C380B1C36C851B71731E086547E53C30FD24899FC84FEA2E66BA2A80C5C79AC0FB880B12777ABB0C9DC844444B84A78335E95710EBD8944679A973C9426A56F193842500B301EF1985E52EE642AEF5004A41851B0D44353D3245FF06843AA8528776387C3AAB9E338DE59B8A96A5C5CF9ADAE0C9ECFFDC4441C60A38E7B56DB955812431B530FAA967C0B58F654DEF503A4838B37A40350FE79D44989F18EB9DE62398447EAFD314809067F0C2EDAE179714932C9BEF705BAABBEFC1D935AB263E292C3A5D37935C229838549D82E8F01AF7E585BD21F5B2D1C232EB54383BF1608C3E2281B3FB3C340FAC1AAC9649257757BE7161393B8D3652B98F1BB463052592F5141B66CD62CB7CBF5D9E73521C87F63F1914AF683EE6322AFA80BDC2A78492875F8A70903F1F232DE2505D8CB0E22512468E454BA8AE4E15189655B7E1A8EF5850A941355D7CA319EFDB942069BDD476FD1F9076382FE62818E84B7CFAE4F2753060E8CE1BD5208903DDF488DC6D688C57338090151C31C294E285879D7C588F23E79FADD3B37B2997E724567FA08CBDE8B6CAEF39541EC94A2E7368DAD65B916BB8CC553323B99292B945A64BD0B00348A29AE3F0D9964F54CE26ACB7699B88368D2DC87D477CE4823F09B6F9A077951764884696ADC9DF7C4E1E86602DBCC2CC423A48079FD871D643182BBBCA68E91D93E54CBD2456D2F5E42AD86970C854844C99B7F85860D91E34A96C9DFDE4ED8CEC20D3F45A3AA6485058E53A78CC5423CD4FE1E6788435FE74A4A82AB6263F70A1E2AACFC4864156F04F0F7203BC32DA76238CA1DE1E4D09A7C62038B2D5DA2A0922783FCB661238BC6140EA774C8DF848EC811A54B3709B81596CE075B2DA28125B0800079131E40932C359D3564A8637E03AF868960EE59FEF1CB0BF1EF21C0450C690C375E6CF1FB1013B00375DA8EDE6DD64E28CE47B9C7176873687F57B88B6FECA08517BDAC6C7D176F5C8080C858D089C6297EF97BB06530732FA487B13A27D708B96365031B63AB495622F31527BBAAA1318174941B6D3A0F8CFF2242BE0F1277BE374982914851558D0AA84CD03D16BB605E37B7E666287880C7E86949A4FF062B664A7FD74930E45B7FB8AD60EECC3C5D4FDA7D14ADAE2B23EB37D81E19B8D14EE1B0A2DE439CBDCB8C0D4AB227082C78571E605379B5023AC45D499BF62E6E73D6BEF4985E38E6EC50DB049465CAB67F76046119008255D58ADB00426AFA84365FAEBD1D683E070E6F62C2160FF65B5D22530FD8765089863042AA230CFD8D7E76C2FD18E6F889CEF483BA83C4AD4580E9A21300BEF6DE2B6E41A995D8B56CF3AF13F87A99AADDCD00FD7FDA34359C9EBA4CECB1D922AA71ED64939C2E3D4140A0910D51EE4D6E6664A9C1F2EFEB55833C8CC324971064F7C338B7C687F889B91A0BBA03A9604D7491B43CBF436FE70271D3978F2B390DE9EE241E0B21008DD0E8C08E15ABAB16C6AA7A60EB2190A26EF32B51FBFF6A8FC69C9232E8009F8A7DFE41AAD754AEF0281E24B867BE5C6B4E00440D4DE4FA86CEBFFC8F9B53BBBD30F90196B3C60A13776E544217CA5C0F561D2D27F8835BFDB39F000B24E87FBB5CFADB7700E8C928B82E00CD1856EE7F8D30334BE4E47CD4B08B7AA775B104901DC9E0E504E97E29E6DF32081E7AC4AD0E476D31053EFCBF5C9C8BED305ED90B1F9D94E5E2B8879D911973DCC936288869A97BD9BE0A001BA12A5640C5AF47AD539A1554520D8AE93FE2EA96573BC99063029EA4A13433D1339BFB435C0F00D1C768AA3FD47EC1DE805D3AADB84BBCD00D7F598A054967A00904B2086833615C0908818819B85920861C10C515B581FB34184579280627F3821C118836188FF9A898EB6012EAB167AB3F4DF33CEB55D79574D2B70FDDF57DA86EAC9C3CFBF64B94DD516AB0FF8E981BDE26D8B8F31CBC4E7B569E8FFB44DDFFF6089A04EC70B6508D890ECCF6BA91D397C345A58BFF6BD72B1D24F56C38B388B2E85625FA23394DFC86D84F2AED5D6F769210F18254710A2DA4853C675CB1D7D69E7C8A68C5D595921A9115", + "k" : "1B579CFAB672E7E210850F70DEADE8EA6596C9DD1B5771666B7CF527852620A4", +}, +{ + "rngSeed" : "DF0E41D2F6F86C1F79D31FD5878E7AB434FC0AF3A0D5F47D2AB3FEF31A42BD949B0E3629DF9F575BEFBB62E829E51DAE", + "pk" : "4E35C7F9AAB819E1981647B85F7B73AC0B8ED44A9EBE203998771AF684086E00A0BA098841E7979BAA20D82B450BC35B88884EB935788DBA47BC63247DE5CF5CDA3F069A02874598468C6651842E56464D9731CC027AA307DA811C8C163D62CD057863A8C2764F81C889D718D10267200C8C2E7877D7D853A73287D8B1AEF013C715F69083B29A589B8E2AFBC72A76587032936899244D435F1DF58A957091241728DBF57693F46ACCC214DCB89FA35AC97C77732D0768E11B15B6D5C915AC78D5AA17323BAFA8262F75B66D06F55EB015A5774A3854D09BD130473295A946771652176DC0479CB862CC7B93494DF1C815D754F86C290F44C1C828228D48A5573A574A2039DC9140EE8A55C6ABBA1986938A47B0E84859558399A42CA013450033C53B1E978D5A3ACE10A87761D51A19BC349FD19F555042E0E2806C1AA76436BC32831F0935C51384B6698A432FD4A014157B8A9858CBC216FA784E66BC09F02258A9DBBC402422CF652A3E430301678283D19889C7B61226951BFAB2814A7C7A2899F83670B1A396F4D260AA869FEB409B0AF63B0B2438FBC72BAF0753FB2C7473D577618109A9D2C2A8448A0E756B4402C7C0E280FD1160F20B9B384224FA2BA06ED2274852B15E1B35851AB6E8A5BCB646AB45A85744141970F6C5AF2720FEDB56ABDB65603588D73109630BAA73F773F260C63D81C9137100B1322D7C21181285B773B7C552A4000CDB2830E28DAA17CA1DB9BFA0226E2C1CA720E7565E80BC08F1C742E453FB2230138BC430335C2965386323B269922E5713957057311BA3394320096075B492B641369236134095D728341DB3AA13EC453EB4B9C986085E23453E878E42D20C9AF4376D092DA16C8A9AFA9834CCA64F16B2B1561A4068C0245C4B6E329FCB1C0A9B15660485672CE70F3F17B486586597E8AEBF9987AF18BB2CE3267722C549A8519527515F4129BA5C986327996C38BABD95CEDFC1305F4378FD2C8B6761A24334192D47596502C86080BB202946F34C08D7E201A3AC937844B181D739B9807EA3D6792CAC7A7A1B4BA7FCB2C5833CB0101291523208E7BCD486737B982C1136381BE16F75202757FBB86970194C4A32EED31B01CCC5A2F0534BDA8EE61B0F4A2023CA58B415E59A8D9BBFA9964CF765B31FB0C565174BC7B006855C9747A66747E18E954444DBAA8272A15CAE2B7749B08DF9811E8CDC01FA46A362052F50AA06EB2249287ABFDA0AADB2E719F1E1AFA3C29D7C855A6CA27AEA661F40210C1C629F611343240B3968238746A245ACE3994BF88B46893EFF1A3A6096166E0BB7341900E73BCC36BB92D3E539E456BED44B84CC00BD836081704AB2E4065559896657AB31C60C3564981453B58BC7E238FC5B778CFB4AABA57417009A789A13BB075B6D9541692B85AB52961FE887C29289923797D18AB8C9D35230624B004457F749497267A2EFD15FADA244C1D35C44109ADD503328D063B7E8C0FB8C66BCB42C8B1C1EAC421563C232E579431FD9CE4D572904577811E23AF28109B2E419515260E0E1BF4A969D18A4378147C0334A5886046833AB8D06C78041C6B848A43810208A5FA0A202EC2320F4ADB15BC299C6649C694F76311D8C0450CA829C3545ACE79A33E0942F133C35E1E6BE342C30FA9B8DEBE6820A3CAD5A2995414BB7F0744A22194435EA8E5A534DCB8C754BC75444093AF5D72490A3468BD06BFD1442870701896A4F1FC11FD5C8C50580CB06192CE7B90F81D920A3BCC52ED02FCF703428C22C8AE25FA56085F8033C972B47C61998DB005B019032D7A83660803CD39014BB3165C94B9DBA1C6E38ABBF6567CD513283174C42BF4605B3809C29DABF149A650BC906A4CB1E33A469BFF3820713040AA067701282CC1C6826008F8787CFD0796BCB568210E088F649349AD921B9349CD4998189B4B945D92BA6BBCC972155D26920E1A756BCE6441748C41C6C7373723A9C00434E485216D92DD6884F6113068FC2B798790F41BB3104A513F0E413CED19303F396E5F7C72612C4F4112F41518EA77C850F7B8E64D1B6DF73A40F87B2945B14B8275ABA42B455253B9D522263E4BDDD6C24222062AE68BFE5BA4193195ED026712E729D59C7A1F519A9C65C566A51504CB93355A33D83ACB62A268E02874C67C89530F914761B751F03F3D2307AC9EDE742F51BCE4342AFD3CB6CE2AB83FE", + "sk" : "C4BA61E90C3A8868850FF1C4662226AC4953DE3553F0701C404618BC69C0F57B527EE459F171BEBE70C730F1841BA702F182AED1AB25AE59CB9E793D7A22C4640BA87E78433B639BB061106C0581809675C702596AF67E382B564B514C4D091A13F35629BC71ACA95A502239BBAA7FA15310AE31B7E8B97AB3BA783A27C8B9ECA6B9B054911C756085002A329063067B06707A6D3A31C27C234FA36DAA420C5EC0ACA490C0FB66023C34064F09832D43B465DC8F84572130270599C10534294AC0458412C58273F49C39CB12D522317C980670692207B3AF7417BEF469234AC081B1884815972C7FBB3733E22D8A164C614AC8546C14CBF05A6BC47D6424C36D3B106FB245CA335A927538D227BE6AA1A4DCC33BD1C68851E18E2FF7CC7EA93104521DB15C7F11041676855E0BEC2B2F9B8E9F63920858B3DB1CBA7005C5E21C4EFFA94427D155EC0C1432CB2679C45802795E0FF13674F15BE6D60ED4326CA4F230D87A59BFB268F08362A6764AA2402E270172275191649BB3991200330A62594AACC81A8FE9E5004BD5AB8CA4BCE4E36860EAA9E49A2F77762D88F0935D6563296121764AA34CE64B41418BCF275B8E5BB2A25259669B3010B239F111B2F6584C3EE9BFE7608D12639E72EA38073C9C45107ABBAA5C673718EC2C4A77A19464209B8EFBA54AE482731BBB3AA036A67653FFDB0E8741C678B88D4AD4647F8B39DC61A879EBA65DB1B98281CA641C954915A916B15307808587EC3D7248668B1003A1612F9EA13E4CA7B660431A7A55199814BA1E757AB08056B7D9C13B0334661839C334449AFB77DE61AA7CAA28AD57ACB2BA0E02E76AD9218A29C6C638390823D6CA512139D3F8826B5C176DA373D7754CDCE78C614B98A59B4BC607382F103EAED7645CF791B3FA3374FC1FB16493658A7885735F7FC38FBD324FBDEB904F17B7A9FC7AF45013A0E8C1D3C4B9B7ECCE171731EF1C97693695FA775FF0452D457B8D7F17BF24638112391D1B4017DB07C3A037845722AA4FD72A0A079803102B0CF49B522302B37A46E482914AC51AF1F007AC91A84D6556A176AFFCD28553362C16471EAF569E666683AB71CBB0748B6BB026D6B736E68203A3103940315650C4201F31BD286643C635644A567B2D38B1C6746757E956C663CC2FFB1230E7C20E94AE939C8AD10B9BE3887B8FB7CA9ED360B2295F03725047CB8CB771ADB18B7F1C976CB436CCC0C675F99575CEA24675C358C3678B3DFB345100CAA3D11A4FE8A34737C4C11131B7E400AEFAB6380B4565326F1AB8510D4210E3335A5FF07473A46D9AC73974AA4C8A10AE5851ADDC7B4D3BD9823B71AA1C0A7F2B4746744BBDB9335D7B161F55276A1B63C3B5B4800D0344023093ACE786FD99C144655D6AF601E86336A5E16E6CAB8B772A39CBA32C68E84390A80D62701AF5D5822629A758B49CBA714507C7CDF2034CF65C4A0601BD1B07B4E1C1A70AE555D7368A568AA0E59B5494239D2E25A9EAA34BF8B29B2FA31EF8EB606E69602BA0A4024780D5C29CB6C63CEE9187249280EA56207B4628F8964579BB878EF25AEDB180931AA5E176AD53A890B3F705BF626861265BB9331D79F66B87E96A6724634DF6A35A82979A4A2B1C23BBE585A001A936D548599CB82C8E362442A6481AD29478EC2E389853FDCBA3853629630030C9091E8781A33287001A6ABDEDDCAF69856A832CBCDD3894F09690B581AC6F7951B7F3558A284C8298225BF74C6847C8D834AA4B118A37FCC87C44749031091AF154B6273BBFB4AC7A3B34BA6C5642A78A22B213428782EB81194297A88C1C04ECD35D6C548289285999B69AC46346127AA097EB2A08FC1BAE1A944AE83BFF25949E27AF6167B73938147BB97AD5380F599822F788508EB73563E82E73C9951D5C94428A056939B9C5AB272525A7088977135008B0C5181BFA27E336457375B1438914BC0189C00BB2F07C5EB5429EE6956943D4C5AA597CF1376FF7083DA68B7C1941529FF5509CA82E3A424DCBE4673AD16439EA874786544E7181BB755250025572C9BCD36C28338482E31449A3B6A917C9947876A702B8567327309B3812A3AA4BC8B979168BBB2DB72F533434808CBCED5BA7F567AC05082DB4B029512747D203C84ED6AAC81245522A4D30A887B8F44B4E35C7F9AAB819E1981647B85F7B73AC0B8ED44A9EBE203998771AF684086E00A0BA098841E7979BAA20D82B450BC35B88884EB935788DBA47BC63247DE5CF5CDA3F069A02874598468C6651842E56464D9731CC027AA307DA811C8C163D62CD057863A8C2764F81C889D718D10267200C8C2E7877D7D853A73287D8B1AEF013C715F69083B29A589B8E2AFBC72A76587032936899244D435F1DF58A957091241728DBF57693F46ACCC214DCB89FA35AC97C77732D0768E11B15B6D5C915AC78D5AA17323BAFA8262F75B66D06F55EB015A5774A3854D09BD130473295A946771652176DC0479CB862CC7B93494DF1C815D754F86C290F44C1C828228D48A5573A574A2039DC9140EE8A55C6ABBA1986938A47B0E84859558399A42CA013450033C53B1E978D5A3ACE10A87761D51A19BC349FD19F555042E0E2806C1AA76436BC32831F0935C51384B6698A432FD4A014157B8A9858CBC216FA784E66BC09F02258A9DBBC402422CF652A3E430301678283D19889C7B61226951BFAB2814A7C7A2899F83670B1A396F4D260AA869FEB409B0AF63B0B2438FBC72BAF0753FB2C7473D577618109A9D2C2A8448A0E756B4402C7C0E280FD1160F20B9B384224FA2BA06ED2274852B15E1B35851AB6E8A5BCB646AB45A85744141970F6C5AF2720FEDB56ABDB65603588D73109630BAA73F773F260C63D81C9137100B1322D7C21181285B773B7C552A4000CDB2830E28DAA17CA1DB9BFA0226E2C1CA720E7565E80BC08F1C742E453FB2230138BC430335C2965386323B269922E5713957057311BA3394320096075B492B641369236134095D728341DB3AA13EC453EB4B9C986085E23453E878E42D20C9AF4376D092DA16C8A9AFA9834CCA64F16B2B1561A4068C0245C4B6E329FCB1C0A9B15660485672CE70F3F17B486586597E8AEBF9987AF18BB2CE3267722C549A8519527515F4129BA5C986327996C38BABD95CEDFC1305F4378FD2C8B6761A24334192D47596502C86080BB202946F34C08D7E201A3AC937844B181D739B9807EA3D6792CAC7A7A1B4BA7FCB2C5833CB0101291523208E7BCD486737B982C1136381BE16F75202757FBB86970194C4A32EED31B01CCC5A2F0534BDA8EE61B0F4A2023CA58B415E59A8D9BBFA9964CF765B31FB0C565174BC7B006855C9747A66747E18E954444DBAA8272A15CAE2B7749B08DF9811E8CDC01FA46A362052F50AA06EB2249287ABFDA0AADB2E719F1E1AFA3C29D7C855A6CA27AEA661F40210C1C629F611343240B3968238746A245ACE3994BF88B46893EFF1A3A6096166E0BB7341900E73BCC36BB92D3E539E456BED44B84CC00BD836081704AB2E4065559896657AB31C60C3564981453B58BC7E238FC5B778CFB4AABA57417009A789A13BB075B6D9541692B85AB52961FE887C29289923797D18AB8C9D35230624B004457F749497267A2EFD15FADA244C1D35C44109ADD503328D063B7E8C0FB8C66BCB42C8B1C1EAC421563C232E579431FD9CE4D572904577811E23AF28109B2E419515260E0E1BF4A969D18A4378147C0334A5886046833AB8D06C78041C6B848A43810208A5FA0A202EC2320F4ADB15BC299C6649C694F76311D8C0450CA829C3545ACE79A33E0942F133C35E1E6BE342C30FA9B8DEBE6820A3CAD5A2995414BB7F0744A22194435EA8E5A534DCB8C754BC75444093AF5D72490A3468BD06BFD1442870701896A4F1FC11FD5C8C50580CB06192CE7B90F81D920A3BCC52ED02FCF703428C22C8AE25FA56085F8033C972B47C61998DB005B019032D7A83660803CD39014BB3165C94B9DBA1C6E38ABBF6567CD513283174C42BF4605B3809C29DABF149A650BC906A4CB1E33A469BFF3820713040AA067701282CC1C6826008F8787CFD0796BCB568210E088F649349AD921B9349CD4998189B4B945D92BA6BBCC972155D26920E1A756BCE6441748C41C6C7373723A9C00434E485216D92DD6884F6113068FC2B798790F41BB3104A513F0E413CED19303F396E5F7C72612C4F4112F41518EA77C850F7B8E64D1B6DF73A40F87B2945B14B8275ABA42B455253B9D522263E4BDDD6C24222062AE68BFE5BA4193195ED026712E729D59C7A1F519A9C65C566A51504CB93355A33D83ACB62A268E02874C67C89530F914761B751F03F3D2307AC9EDE742F51BCE4342AFD3CB6CE2AB83FEA96998E3F52B93DC875DBBD503BC67BEEEE7F1E46083868F96EDB9EC3601DAD0A49F3B482A66256D7F667585925CB7F58894E42660EF2573AE33655C231DFB0E", + "ek" : "14836A947DCF4988FDEBFD82C857509CD0E44A459DD626670CFD2B468441C0C44527695371CC006C4881874E8DB293BB926D44287CE393334C72C2F45B76CFD9319FA55318CECC6580EC63B1817A9C7B29111D71FECA0149D8093A9EF86A385E74C85C99E1F716210DEAC774261D47AF2AB393C292B519EC0D82C2909B21AB8AF16C1C63E9FCB1A3E19887573F661F99E600D5CD9A05E995CC1E23E3FC515019961F31BDA06A846DB06EE1644109380C8D7A5A44E00AFAC782C8E5B32BB6DDC3CF3629DDF1A106406343CDD03208E309A853C19556787708A39FD74A07722F89A7860E2E1D99F54D2FDCD2BA880B7B17C7ADE8081A26FB56AE73455084EAC95589957B97BE7483F4F301E440EA8AD9FDE250B73FA15C28AE1F6B71CF4EA3BBD4D899EA74EC3CAF5A308F267EA4D72CE3C882D4FDC89730DCF63DEF3E9394C63FDC8C9000E2EE6AFBB996B5C5ECB7F9DA8F04D99C1E75640C169A565D874EC5E5490F8EFBBC57C7CD47C2AE60F8FB051FBF9DE09F0B599E37EBA8BB39D47AA2FBD52A20DB20108355C88E594F11F6EA82B9DB471FEC94394DC131108B9B86B3B9BF864DFDD4D5C7F7A67A31766993DFB6FD06DB6A4E7FECE0D76F1A57E0EE596AF20475C935037669CC0D7EDA6412DAB31F77595F93DAFFA9C2C4C469742BECD3FBBB14ACFD7C33F4A24F9CBFE5C0524AEA92396F52369B1D5F725059C5ABDE9DC5961062EB564BB6EE644503F5F4ED2407893B04D7F50D6BC8903D68CEF6F1E757DC3B0CD0BA878F2B07FCF3BE51725DCC8255097729F60BF692E37270BA5D5992FAFBDCF7104B6EFDB66FEB117455803C1F9FA85159373CC0CA646DCFEFD7B1AAC9F39A4250B4D2FCBDD2DD7486C67A1C5D9B4B9AB02EE8B32EA0027A2617D0B7EBEE0F5800EAAFA478031E6CFC9C6782FBFEAFB5E453C82A25CBC51E9AB02EA0FC4C2C054DDD985C4295A1FB0C4D2DCB64105CE182584999411EE8C35B1A736CB9AB0A46F8A37AE2E6A642B78D3C64D898CE0812B624B59F82EF7FB1A7BF636D88F20EA9DBA5BDB1CF176FBB8A7522BB7D5DE172CA208439456982CB8BA91D69E0EB58E45AD12AE10B2A1B6998AC2222DB52038C6EAE91C6285ECE1CD247C6FFAD1934D7F9CBB175EFE043C7C470BE7DA3402CAB86467E38641E6E02A9AD99F21D4725C0C377F87EC20E3B9F0460FD743CA7F888A3B6A5D91376B53B234CF97548CF3C3FF8F8AC97D96A870E77685EB0AA63630DFA4E778126F1668886E58D34CB4F78D7D90E710D4A50F0599BF2DCDCAACCF84476DB0CF325E8ABB484628A849A9D73298A14652AED3105277F650E81E33F8D718F06A730C223E74D56142F60020291535D08B21EF4B85294472D99309213646FA7F460B948D24A7D9B7F91DA343ED047CC760CA8B0ED1EAF94E78B9FE0106D5CDAFE3F8D744E077F24D804616DC8DA6066C4993220F7F76DFDA38BFE9B2804D01FEEC2B8797A55428CEA61F0752EB21F76D7EA0D7BC39B6D5DA0E03ED4D00DD586195EC0E89369288243EDD33307F93A71B7E65ADC3A246FEC0F2A5E764471A56B7D71100C5E4C5B65D7AEEA2378A2A2B65C61EAD310A5804195AFC59C9B082FECEFC2C8E24C8C358E8EFCEBA661D2BD3A7E1176A2AF42A81D82C37019DD9FE7A816D37730B7950453AA37B6A3E421DEF7EFB3E5D4A5BE5602986343AF08A700C2ACD3DBA23DF15CF43870640F6ADF02235956DF499268FFBF2AA651FF0491AAB215422B4ECAA52C14D0266BE1A02BAF50BFB0F12DCE0212E9D440164EDC4D751AAD1875E421D99F397D3CCEADAA5C7E48554B7610BA6386D494D018675978B95BC365E359E7F882F751DD46BDCB196DAD2E5E4591D91108AE1F4406524E32D8B8DAFBB2B0911407F89219A27F61531E24B3A21442D292BFEDA13B31024E6459759C606F1CF6B004E12D200E6DA7188FAEC1E67B76ABF3238904EF4723053922D3573CFF9EDDAECAFDE3EEDF11329DF6794E086F75948C7F76AEE7B4CF2BAF0F8705EC1A5681E1F7799B21F964CF33C284A61612F37764A6533AF70111E71F3F306C2F92252F25C57A54BCABCD18757B42EF440D23D99E22850384F1D933E046753B7E38FEC366E61B5372A80865B8C4A4BB9E454792C17FDB25697B9A221BDBD745C4D8C6B9D28F2DE3E7E80026BEEC4728C9667F90A838B168603175F8D34FB2973675B0A14B369ADC4B", + "k" : "24F6699ADECED6D22F9D1BCE33645E7E7F6F0218B707634B975A5676351B6F45", +}, +{ + "rngSeed" : "D3C9EBBA6EB03CCB5C9B9D2C8D7F0CFBBF50841E24396CDDF0E56525B38918C2FBE6C34CC1B93F7BCD4F4D5777E1A488", + "pk" : "F39713C311077C359F42971B65463A8DE1AED9879ABD512CB55B6E44F5C690E0A3F60768A778CC9CAC5AD6B897379507E3CCB994956284A7715970B0E3F6189F0C66D99C667119B82D87A6507141CFDBA46FCBAFA8A2A1352139B1024DBC64388A3275F34180FFDACC380132EFF35EAF788364F3AAFDD6AF9C02CFA396592282CBFA110792F87B6182B2F36A0A895C0791276D789976CDF09D2C16A32AAC669647219086BD36F6BF631392510C0E0970007A88378B647B52FC20EE9148CD4575BB8B31B06449994098BDF77680A48AB51B8E5732545D6B87112884E35A2302F60358F651F8A71C0789018DBA79BF5298A9F6AD16BCBBECAC4F0CC9888CF55BBEB38264C885CE098FA80463F63806A544BFC194B77895A76B22B81B1098A8C3819E035268D22F4BA0339067AB3BB30E65506A86E74FDE52AFEE944DF4E4C745F9393AD59117DACF74A407C236B8B5A2AA11B1C9F86163DF31129E885EBF68040F822314C2BC4DD12751851864D743EA49B68A93212D392845AC46F95715796A488CB44072ECCECA89878F37B51D662D783900B6341A65D894771476FB942ED058B15150BDC67A3B7F4CAC93733F735B81F8DC4AA5EB1288D761B0B74238A5CD73C8BD2457BC195B785FD31804D654AAE06EAF5B08A365A472503809B416904162C17942FD27671989C553AB5137488F385B7B9519A69CB496444A7A2DB607ADEA5C3E128BCBA31F586C5603F953F4FBBB4381CADCB88D6AA7784562C6EF302ED398CC2113ABD257C9554818C8175DB54BAF20024978E167620B672B28BF24465D2CB4CFC6C08739FB9696BC84FDD76B136B39B85C7DEB4C10FF59337B4112E32BB25A665E9CF624BAA86AACB2A18EA3CB67462874117445F913558C32E5EB7E1329CFC2D99CA4D83007467B80D74D2EC9832A5785FC7293EB466D55CC8904874BCA5714C776579B253F86B17187B9C19D702AE65AAD9D7CC23AFB041E593BC41308572825A76B4DFD51A2BAFCAA10390A76E08458C384CD0089668955FCAB00082759DE9147BDF581AA4A81F8F82BBEA84D255B43E30B6728FB7A705C0AA96B794C7CA28730C6A1B1B2C1040FA24A98AC862ED74453C03A3D842CB0BC87409A09456C739EA08717D7A1061041C424D13BBEE299C1AB1BF328B42314263F186E5B198BD5B1712C04402BF849DF6473B8E78C4009C944D05277C68D6EBA8555EC48139560922A7A142632D4168DFBC6396D0046C53221D43B7BBE01BDFFCC672F214217679853D3C0939ACFA7B45AC81B145E5BC7D668A4466156FAA6A44AE2B9CD6CAA5D42CB1C2AC5AA847CC6501CE998B2896652E2C901483ACDFFA695CD1625B124A8A88490B12B72A5CBCB67A29AA955247FD17EF46606AB5B5FDA6AC39EDC0128E46310903B32435E2F02158F678462F2BB230246455B7D307B5BDB40375C6CC507987EF616816D3A97545BC0F6E44C025C961CCA33A828BEB6480494CB9049BB2E0C8734437CA0745B55174B67FCA6ABE743C7F9793219A19A88298211562E7AD85643B0B680C957EB6B740AC142276822900110F3998F2B043816C9216C416D64E482DC1053928722EFDA8C35BBA98C563EB4FB280791A9A330968CD29360860737D3CABEF87D158419CD8794D15771588CB049F393D3729FE3276590488E97F00E63B6CDB760C22FB853352C2EAAF7340B204D6BF8CD186CAB5F786E7F967A4D147686A690CA7308173843DBC0BB17FA4AB2788436F43009827946265E86E782B97B2B27B87EE2C0BA9FF23D6D620AC02124189BB008D54DA8F0118A081A70040B0C722A7B5A97194C5641078B22446D7CE9B66AB9332F2AB85D7320FC651EEBF8B93B838421AC6818F87673872582360BCB903AB70972E8E589465660E6E4B9295675416547C277827D667102C99297F9909548C52621846F5978A5D6971AC97C6DF5CF1A3A42717194F112093B73642CD757B541C6D5094931D97AFA952BA80024B5D76CAA088577F24B86208DA3448DCCE24769DCAC3AF496B4EC8E634294C7D323A85128D4E20DBE5B7BBAFA8FBCE12131F0663572A4C1A4885AC49CC607578042C0C68853B661B452662AE194512B208435A72EBAD23519E07F96F59EDFE2A5297C351BB38773478747732D9841B5C26091CE45559D7184E1CA01B7C388A8CB030A00F66B47988C2D7D195332662CFC7D90B279248DE101F77E30", + "sk" : "744900D5A1CC90D1BAF5C17965A200AD563BE74168E130481832184937172B780A1CB0249BC3AC8FE09D7892709C70BFD6496041BA834BB1C291D5A73368944D13561790A20603BF8B97929624C5F586CEECD1636B6CB09C99807CBB9BEFD3B2688A29A63120132B05B5420A0D984B9368338710B29A4C5A4102B25CE23414E3563272C2C91A33467AA665B40B7A18AC434BA8E1FBAE3A7CC2493B531C6B642759625009CAC7751496B18127D33D4733AF3FD461C1CB7531223945EB1BE69C8486A35BD49AB075FA6227465F97EA2EFE552DB4329BDF66259D091956A41A1D938940998C8E83329AE0A8309B521AF642B9466AA3A52A4572A00CD6ACB467BCD0A0551F4538FBF78DB2E0668F47AE9F65094D4A30814371E20350066BC797777D79135D9F104F773289C2C20C55D4BCFEA1A674F454C87AB9D809A1AB91A6E13747438A7EB7F814464426CDA6C10D9456A34C66DC37766B87CF01A4A38E45154BF96D5A5617A9E3A353A57706AB5911DC3F50A1C9CCECB4590BCF8C4765FAD91EF119B00C027CF5F30BCBA608FC4667843891934935C49C8A945553575C67A1E3C80DF48BDBA8778865AD972BAE7733C8C4D2787609D062B16AA61C25564955213A06E8D021D631BC032257D0618D1B0122491B8C9DF8251886A2EFEBA199A850CA41BDF7C0362293B80A25C247820571EB6D6D798DA2C207115500A1441977A3362A2C1366A15CF60A6086258D35A695690A53EE6737CC76A8EDD47795CA913DAA42D762996E4061F8353BE362752FDAB69A571FA02671432615834C8008284293C9C83CA3B1EEA330A91A7522AA876D37CF7DA439E2B31DB5C903B17B9449E397659BC7DD668F3E9CB2CD877C57FA3EE2FA9A3B3C9D22E5C02A48AE494142E5D56664CA0FFDD15BE6C4C2A063907E842B800912DDC9141AF93839B17F37F3725CE36B9A7631E6A002A7676DF2D7A72A740302FA5BA55A41FBA7953A5812CE30823195CF26B8611C401242BA90487CA730472F30BC8975D78741051D91701B7FD707B7846BA16874A8984446D017BBF2357526A4882359EDDA98570B44AA2B1D968C4A2DE84AC78330D2D2725F7A317C093F42809D3D26092936330EB51E93132C975096DF35506FBAA429C67AE6B75D24B9A510AC2BEE812CED4A732FD1198FEA3E135CA2A97657608B6944181D062B1DF05679D8D847E50A8668FC8238CAA884B31FDEB3ADF0F890A4956887417D00376543FB8588FB4433156CA8C7152EF466B9EB7534E9030980AE47D82C04F55D5764827FE036FE58C6AC9AAAE51C115ED619E5DB99F3F6143354903BCCAB9CB5448F9A8E76C3690C76732DB1757D9742AEC5334F79C0080A9C0F251B34F637F80253152B4C5D8124F302C3F6E15EA5D09758E42B99F15427ECC63976A0315644ED8BA516429A1AAC16AA2045FEF31A4A68C737F206FB26667A403C3AF01D82A191BEF752976C1962B53B0228513A3026A0BA7358162DD8885AA3DC31E45B72346A055026396B405ECE0579BAC0504082589023B4E0AA77B07366ECD188381AB2B9AB47287C44C14A36FD1095453B2B3B0A816AF1C62EBB2E023247E4983BC983B867460158EAAD4876551638BA5B528E0C74B9A081537B7BCE3E1540062B93FE447873523766F2CFBB4C46E3C3751057764568033942B89B7325E639C318F63AACD82139192C81E45F4484073A540DF8E459FBB9AFCBA59C167A1ECC71AAE7473C8D9CBFE41CC27DB6B72C804F64CC1A015018D212C9DBE320AAE4423596B4FD544C6BD16AF096AF352C18A8DC1D68FA29DF7A454D54B92BCB21A74CB107153B8386285C0479020C04AC0B59BA8392BC976C046995FF606F2ACA215ABABD04F031E52032F6C08E63149DEC0A590A4C49EF55533735224C341BAAB9B0FC36771790C0301638AD09882634871196B55E87A5E7B9348C8A83D9FA0B1BE81232864342262F57F063D38940947B48AE840DC42B27D52A01F4C624196C9198D081992934777653FB533E525CBEC4591844485EE6A457F4B31FF94927713C9392627A0E676231318F18E084CEE43501F0BBD708196DBA67644145E7561FC1FA2C5C4835C76A5264A25D96D47138E2CB3D75297345910C164FFB30CD4C26CD1189264A602A3397AA6AFBB27DDA27A6566E9769A5F39713C311077C359F42971B65463A8DE1AED9879ABD512CB55B6E44F5C690E0A3F60768A778CC9CAC5AD6B897379507E3CCB994956284A7715970B0E3F6189F0C66D99C667119B82D87A6507141CFDBA46FCBAFA8A2A1352139B1024DBC64388A3275F34180FFDACC380132EFF35EAF788364F3AAFDD6AF9C02CFA396592282CBFA110792F87B6182B2F36A0A895C0791276D789976CDF09D2C16A32AAC669647219086BD36F6BF631392510C0E0970007A88378B647B52FC20EE9148CD4575BB8B31B06449994098BDF77680A48AB51B8E5732545D6B87112884E35A2302F60358F651F8A71C0789018DBA79BF5298A9F6AD16BCBBECAC4F0CC9888CF55BBEB38264C885CE098FA80463F63806A544BFC194B77895A76B22B81B1098A8C3819E035268D22F4BA0339067AB3BB30E65506A86E74FDE52AFEE944DF4E4C745F9393AD59117DACF74A407C236B8B5A2AA11B1C9F86163DF31129E885EBF68040F822314C2BC4DD12751851864D743EA49B68A93212D392845AC46F95715796A488CB44072ECCECA89878F37B51D662D783900B6341A65D894771476FB942ED058B15150BDC67A3B7F4CAC93733F735B81F8DC4AA5EB1288D761B0B74238A5CD73C8BD2457BC195B785FD31804D654AAE06EAF5B08A365A472503809B416904162C17942FD27671989C553AB5137488F385B7B9519A69CB496444A7A2DB607ADEA5C3E128BCBA31F586C5603F953F4FBBB4381CADCB88D6AA7784562C6EF302ED398CC2113ABD257C9554818C8175DB54BAF20024978E167620B672B28BF24465D2CB4CFC6C08739FB9696BC84FDD76B136B39B85C7DEB4C10FF59337B4112E32BB25A665E9CF624BAA86AACB2A18EA3CB67462874117445F913558C32E5EB7E1329CFC2D99CA4D83007467B80D74D2EC9832A5785FC7293EB466D55CC8904874BCA5714C776579B253F86B17187B9C19D702AE65AAD9D7CC23AFB041E593BC41308572825A76B4DFD51A2BAFCAA10390A76E08458C384CD0089668955FCAB00082759DE9147BDF581AA4A81F8F82BBEA84D255B43E30B6728FB7A705C0AA96B794C7CA28730C6A1B1B2C1040FA24A98AC862ED74453C03A3D842CB0BC87409A09456C739EA08717D7A1061041C424D13BBEE299C1AB1BF328B42314263F186E5B198BD5B1712C04402BF849DF6473B8E78C4009C944D05277C68D6EBA8555EC48139560922A7A142632D4168DFBC6396D0046C53221D43B7BBE01BDFFCC672F214217679853D3C0939ACFA7B45AC81B145E5BC7D668A4466156FAA6A44AE2B9CD6CAA5D42CB1C2AC5AA847CC6501CE998B2896652E2C901483ACDFFA695CD1625B124A8A88490B12B72A5CBCB67A29AA955247FD17EF46606AB5B5FDA6AC39EDC0128E46310903B32435E2F02158F678462F2BB230246455B7D307B5BDB40375C6CC507987EF616816D3A97545BC0F6E44C025C961CCA33A828BEB6480494CB9049BB2E0C8734437CA0745B55174B67FCA6ABE743C7F9793219A19A88298211562E7AD85643B0B680C957EB6B740AC142276822900110F3998F2B043816C9216C416D64E482DC1053928722EFDA8C35BBA98C563EB4FB280791A9A330968CD29360860737D3CABEF87D158419CD8794D15771588CB049F393D3729FE3276590488E97F00E63B6CDB760C22FB853352C2EAAF7340B204D6BF8CD186CAB5F786E7F967A4D147686A690CA7308173843DBC0BB17FA4AB2788436F43009827946265E86E782B97B2B27B87EE2C0BA9FF23D6D620AC02124189BB008D54DA8F0118A081A70040B0C722A7B5A97194C5641078B22446D7CE9B66AB9332F2AB85D7320FC651EEBF8B93B838421AC6818F87673872582360BCB903AB70972E8E589465660E6E4B9295675416547C277827D667102C99297F9909548C52621846F5978A5D6971AC97C6DF5CF1A3A42717194F112093B73642CD757B541C6D5094931D97AFA952BA80024B5D76CAA088577F24B86208DA3448DCCE24769DCAC3AF496B4EC8E634294C7D323A85128D4E20DBE5B7BBAFA8FBCE12131F0663572A4C1A4885AC49CC607578042C0C68853B661B452662AE194512B208435A72EBAD23519E07F96F59EDFE2A5297C351BB38773478747732D9841B5C26091CE45559D7184E1CA01B7C388A8CB030A00F66B47988C2D7D195332662CFC7D90B279248DE101F77E30087881DDFF4095EFEBAEA305138BF83F0E3071F5494C3EA5BEC8F775128CE60A1D9667C03155106785069387CE7D25CB09C5516D52817201D6653F20E775B453", + "ek" : "0F5E54FB52879546BE30CF914C5FBD9FCE62BF191006B9ED506CEC1DF8163177D7368541CF7870F194624C8202763A50B12A85B82E3F639E85D08B2D908642A421D7D7F90CA7CABD7201A0244CB126B4BBE9287DE61D0A92FFA092C4CAF138C22504C89F0D33099074FB3F8F7DEC01AD44AB5E0DEA8956ABB33D3D8CD9B5F125E3F69A9F8C75A15A9A70EF059D7B7DE82AD31FD6480408F99F47FB22808C4E36AAB03BDE0FD6ED8DE3AAA3D415E5CB79A676232A5F4C8C7265435E6D1B85BEA1B56AE0482FF5AFFE97E6CB08B2A4CC515C6C87B4F209C1A6BB7076D8BC44F0A8850B5CDA9FFF7989949AE320E86EEC0D22713EFAA763F7BF0AC9ACBE9DF72ED19781651D2168C975C92A63DFF81EB5F9709BDC6A8982E2DA665583C209DF6B95E654D35D8E39541069D4B998603649C93B8FD09921E03DB97EA5172993D6F6360E646FD8FDA65D4A1183D52FA9E1C627EB3461F64E14D65C5D10B34CBFE637196D3EAA14BDA07D2A747565B5148AFB1F5B0C0B6CD8FAFC567F30DA26A8FF82874EA07C452D7DE06624950C46CCF0BB531743F1243486DC6AD0807EC07744B2C0490005BA9013CAB88D78DBA42A8DB961388595308B8641FECDEDC339CCB06861BB32AB37DFA07C9A1208B2AAB0871F0926A97D1A689F52014A51A0CE68978EEB2C04CB87DC97C7CEF7263C3C05A03F1017FEBDEF9DE89CAB71B92EC1B041AC808FB27D80784585E03BBD627966E9A1871B8CA8D0EF5EF1D0C305FB1B9B3852DDE07761130970D1D1F3BDAD9AA90D6513EADD6655DE67972D44A7185AC37B58E1BC7CFC399E84C6629A68DFA82D5180659C7711CFB3A767D3D0DC0FD840E69EFC91DAB4AB2EB763C1B947078C4C694ED5D6331E9031F43725CA5C1C969E831AC4A4069E7381CFB3DBAD7A9B987AA8CF0E9BAC18473F44E98FDCDFA96B8BD01C26FD0303B01ACB8BAFAC5DA40969CED88D2A516BB043F9FE41E28FF71328956D0634AF160C8F5CF6715A1B4C35746B0E297F72837BCBF5B9772F1EF9A12602E14DA5DCBA74AFFA54D5C61C699413A471D4E10A5DA3AA84DCBFA2CAA87A1C73C59335991FA442AA28FD7187D161F26B9BB05415D4C34E1161B89C4FFA36F185876D46408B1A50F2C93E82B6989CBC5743EC9861C55C88BCFB2CFF27F3807E2DB3EB8C3E077B764ACAA793ADDEC66EE14E4A8A513B7E2D03EC2A201E219386C85C56A1675C00C53D7C06BD250629ACC21312E3F57B6428CE544E486487FEEDC5DD20C95412B5BF8E4109BFFB1B6BE7CEA3A913E78BBA089D33CCD49E4697E66BEDC666E31FE5EC5B8F60CE04C1A39CCA1380656AAD0CAA0DD4C86A7F574B8DF0C0A087852427B8E4781BD276DA8D1CE9E25777B218BB3EEB25BB60817C961E9AC9C943019389C5885D272DEBA3249AC71B51965028B8D217EA94D70DE6E38D8F87F7F92423D29D7BF326DE9A8141BF73270E7D556B6A8928ED6BFD6A56D022B60B6EDE888B340EE93CABEEB1FB6145AF1FC82167533A99E862EF15A24C238D704499D52C3AFED52AD2C4AB88374908BBBDBD6458D31F89448C21D74ABB89B0C7B7115A63288413A5D232B5001477CF0353BF95FE2CB6ED4D5670F8298700927B00BFEC8DBC542F7D2DF40039A4E150236FA75664412523D8FC7DB1C3491215243483C05BC9A8232F90542B40CFA5B3EB1B6AEC6F6BD2269941D5C19A7877464A69D70BBDBB983C6DEFAA53C75B6617CFC6DF32524BA2E99604D37E840DC032E8046FDD012B786FAE603D8D923AEF21DE1504BE2B30781436043A98462FC91CA04B4B3F36F6A5E574D7BD71B8C0EEEDB8FF3FCBF059E4E9E0BBD02E1D8419594EE5FC0D767E9BC447E1908EC412B352CE84BFAB5618B4F5900B43ECD972CDD57DF9E771EE1C43D14E521B845F92873AFB1E573F64B79D4AD9D301D48DBED325444DBF1F2B3E54374FFC824B6A438379DD4487304597A9B21E2051A9E7973972450869855CD6E0C34162A182E2309AF3BCE7FD079E5EF778712CBC6E8609E1C7613EBA8701306E802AFFD5F3C6D5BAD1ABE505542DD6A06563F180FA15BD9E85328215FBEC525A9479D529223271459C827FA77D42B6EFAEA0349A74838841C5C39DE9F8192640C0EA211F37614A7504024077085766043B2A1075D6995D3185C17378FDAA93BED9AF470967819E941875FEB4509447007516053686729E04EDDB16B4", + "k" : "9BB8B9A1F1F93B94474E62003404B3EE57F35B10CBDE11A8C58B44BE42567BD6", +}, +{ + "rngSeed" : "6B3996E8BC6F52879F2B7BE012C44AD555707CB7E5FD8ABB3457A298336D6FDC9EB7853008FF13201D5969A315C7E493", + "pk" : "2D661F371B1F9A3C88556374AF9B603C8C1DB100AC3E600C042672BCD971857232FBE70E3C1280F5AC45D0E819A8495D2DA89EF5086B110773C7D1539EC94A44FC0CD6F4A39362731F527DE3F06F4A78B0DFBB94E4977A564C765CF8CA68658FBE27937A7B15A8671CFC8B3E779533D1B5C092826B3038B213550421004012A4CB3F12478EFB0C92BCBDCA4259B153584BD4B65A6B8D66F578F6F408BFE246DEB5304CE5487B7A95C6DB5605818E26D2CF5FA6ADABEA9E3A48B6F889305C016055DB7A02A34BA5E10573143DDB8659FBE25C7B621E3494AECEF037EFFB36B2819A1816788A6B410918745C2A423285C7E0021CB8C8793B60B4C9061A39F97FF1212F02D387D224B0EC258268A374B6E27AC9C4598FB78C387A7DAA439280D79A6218B3CEB0BFC2E685BAD8801D92B5B1A42F64C8890709C58C95BD8EBC43568C33362A53B5A12C052489BFD806CAD36DDA117B2180B68CFBB317D4BCDF745C50324E19DC7B17AB7F31649A57BCCE91FA720052AFB0B0BA5E8B57A5E4296B1C390DA9A4F76A869AF0B9389C0AC381AEAE0A779BA588FF415858B3300D71B99FC172DE950A95C3A61C9072B6F2A7CD9245DA690128B9C597C44903837B8A9443865C785FF6BC05854E1115B9E3D7A70C7C40216CA48B1C6497062D61FB8CB29C71E5800B8E752E70B9A8655BAA8408742A511EDE8409301620F3BBC2A27790DD7058841432CAE4CAE719740835571CE65027E74D85958DB506A8E9601C1F5BA5728A6E710A3D3D93748A7A640C460167482DCD6CCCFC238326171927C6A72EE7084EE97D3E7519744AB8DF651B9B2B69D4AC7CDBD9437849114E29550BA3321202906E9331BC7CCBF4571DA4C6AE1A0B2797BA4BCC75398E18505EB02DC760B00F687C76F2A35F707F609CA149B4BE233B3BA4739E19E4462D78950138CD1B210904B10A83356156A63631D4A6193C68E78642E7C5C0DAF403E8520CC2F7438AE950D4136AD32684F2881C50C1A508B0442BF6C92F030F82653578C79FB4EAAB1CB60DF4870D6966CA5BD8651400A5A6D424749C8CC6AA6FC90B6514A8274E633AAA74435542BD2EAA354D65A32591819B8233834ABF1391470085C9144B8239390F97624FDBC645D3662F8A7A2B7AE412F8525884081B3282390F8C35E2379AA5D234DFE9C0C94098ECFAB31DFC315413C62AA80FB8A9AD11D070D02CB192D18F3717C1375401C0713437B0868298205162A78F8B00FB46CA2CCC6DAD2717185B72793B2AA009419A6330EC508C8C325110C53FA0512A713C500631B36AC410C5A966EDF1656419740BAACA6719639987BF5E17444B4122650C87C884069FC52BA082837158B9BB85B2C961268284B5D8636B2ED3BD1781296DE78A1CCA44502A779B2BACB6F86D676355D4D527BD050CA8D33A12D059E6D697F986177E1B95424BA97CDA6B6AE0191BA70BCB75172C354541C7742556C5FBE591F33B9624452392412F3859953AC21C50D5A445A34D94D492AFBB01A84C844FD582802391F4F4A5D012A8A62079E254363FBA52C83A399BB3398F6807E6F03F74F68FC788187BE6BCAA5491FF666C98E43C3F860470380768F70B4987C6EA10411EA60FC7E8CBA0B1AFD72A52713A41A2172804ECB9FB60315E37C544555A8AAC8089081C6C2695AF8011BD991E1DDC87C841CBE0C0357E04489785222930A5D75B81CDE91E5804315BB30BC93294367A4623A0C4A0EC8DDC436C7992B157039879BACBCB590490C28AE7C9142267654291C06A75237B24B8895404CDF32A073C4922C202A087BCE07AA5708816818564C68237136C0A98119C2A6244A59051071414425B9230A6113CAB28B06A058E67B16B9B3287F001422C276C78AAF608820836C863A1555590BC802A70ABDA52E4C430C80992745945EBD343277C222836631C652DCC425E1FEC6F22383EB78C9B47967E865C6382231B4FF42B94F281C4E9A849477706C339A48AC2C69416D1E51914C751DFF0B74CC657A8D9B0D0E21CB2C3A72FA241338B11F529A0EA9CBB8BD310203B29775867F23B7A6ED35890F3014474B51A578110CB1E1D052D2CD03A19FA06F1750279476642752934201C0832B80B552C7A4B4EB1118E2466624588AC1D0148C1C0484352479EA604758012B5D49E885965BF6EC29407A0D9D3F1F08826007A5A3D32062D2A775728C35116642149C2D449", + "sk" : "74E23285E187F22C6A1F0B5258081CA00C59AD4A733B6C168C39AE4994C7CAC606422AB8AE07968A652C7CB130E3A1B5B65077AD348F2B213EF368C46C1B45ECF9C58FE49A86396285D554B157CCF2142864FC88DF377C2BF758A3488722DC9111B39A90C58D29D18B0373801D761FAAB0845E78BEF3C0B91509C7C9E44CF6A74BCEF19DE93538567564855981484BA0DC5A0553E921D302449663CCE9C3AA1FDC3DB0129999E011EA3172A1A3A504E2286550CB86156A23C74E0B2B2750648A15479AAD813C4A576FC8F70553A34287147580B6A62957A26306CEA1571963D4171DBB38448763B664752CE93A21D84101F79A66BB1E192B2C4EA0266D1C869226B0E110975BFC13E6E384C1883A76E5258C129185EC036A6063F182A35C3AB843523CA5C9B30B655EACD967847C86DE2C169C40866F8B798555497EA94CFA99591C1C563264B54D369F0297168339379310BE3354BAF9D1CA6D7A79A2D0517E39C0F6412BF64BC57059B05DB3888DD35E5AF70FCCD55E38E053B453AA43D0027F8CCFC0E15DA1C91E4A0B3B4BB776DF88AAC1308F444856F3E888AE4753888B017CB342E70C78318A7A3A8142BB28326CAA32809571D547C15B86437C655EBCD48BB2990493001EF4BBC7B4A02008396755B911E1782DDFFCAA92A34C39DC8E0B9A48A33A252D6C547CA341F92727B5B40E92565AC466AE58000799A534B8277591E99876B4925A9A046644056A625A7A51431AEC58C5D6B98EB4A0F40724E24477F6EBC52AB7859987871E623E93A0C081C9212E5B33E1C813C6A81980A5A670C1991DFC721EC62DD771CC9A30BB7EEB67BA71AE78C81CB802743B3589E661C4AF476BB5753458DB8C7D281575EAB3F9216307A02F95147EEDDB5FCC76C158701BF8A44D3890B65E6B43761A757221A70769B825B6CAC8FCABB1DC155AF64B86258F0ED5260522188FFB472CF64B82CB68CD41B986B560BD00B6CD99B805531076E25A2BD6204E264114602D6C1BCC5E9235C85575E66B391BBA0D4297C9CB5508DC5CB3200B092400AD59508D7FE14703D433F980A79A796F24B82C60741A8276257C5B5311D85CFE1B8733EBA10E305A3EA4AFFA5304F98A438325647A521F1B154A6547CBD8457545DAB60EA7966A03B40E7C28EC1A22C4757A3B3C7DBB191895DC419CF609ADF40C5FD86436506894A3932F1666EBD14A74C93D5E93511B5401FAC02FC7280D088057EAE2B3C457168B1B9E25FA81FFAA9D30C27DFB250DD5F287F281B12F1381657918EAAA067CCB07BC0A67BD4827368C7C0B4CB45D403159F9CD8DE5CAEA6B5521BA173160561C9270AB15C85351CD46E8C4A3810587702F3F0B6921367E4648B654FB53D9627F573B936C6BC050A34B7E3C7C379A4C744B80230C35B784BF9A4A3FBD8A892450B4739488912B2B822B3664C25327D051C0236E05487671461264E2643C0AA7CA89A9C85867C817B714507C2B955371583611E77C783B68796267259638D4001E0555A19644B70B8527D9D66A5A3036E348CBF21200E3E07717CC83D0866EC7356412705706F192DBDA8F43AB30D3F14D059190C1C95BEC240E0C3271C2B755942183379893FB6CB0C0075C7B67352A76BC2BF7390C39C3768127E9402FC7E2716431BF25CC8405E23BB5830F348B4D00FCC1FB44389100CFF58A3409174FCD39C5779C93336A053D04531942133FC92D66E3855043BFDEA0C0F7B7795B0941DB78A52D6708A83913CFCA678F67000D873060777ED6F0906976AD12946B70C9B5F9E4A95A8B1EB5B733D3D92921CAB8BB610B3EA33549E6371AE507AD34170FB09CA9D65C4360CE42EC63DB51B1705B19205B01688AAAA7C00AF97C93FAE66DCCF93D44A61AB5381326982FF2A73BC5B19E17B126C7A652F36154401A6D28006A383841F4D9998A06152D0B58C5E6457B601953536693918768CC1EC85B1494255858DA9253693293848BF8C14A6BD362A2B91137CBADFB82A4B1F80A3577869B50716983730A31AD1574A3F5A62AD6635AD11C4706AC6912248A6B55CBA70658DEB6336E7344F1535E195722486866475BCA60C8BA89CB591AFC603FF0CDDFDC55A705BEAA1B99AE725A400454F6874462713E12698A55A267A96092BE913B3472B0D9FBAECF20169790368F010B2D661F371B1F9A3C88556374AF9B603C8C1DB100AC3E600C042672BCD971857232FBE70E3C1280F5AC45D0E819A8495D2DA89EF5086B110773C7D1539EC94A44FC0CD6F4A39362731F527DE3F06F4A78B0DFBB94E4977A564C765CF8CA68658FBE27937A7B15A8671CFC8B3E779533D1B5C092826B3038B213550421004012A4CB3F12478EFB0C92BCBDCA4259B153584BD4B65A6B8D66F578F6F408BFE246DEB5304CE5487B7A95C6DB5605818E26D2CF5FA6ADABEA9E3A48B6F889305C016055DB7A02A34BA5E10573143DDB8659FBE25C7B621E3494AECEF037EFFB36B2819A1816788A6B410918745C2A423285C7E0021CB8C8793B60B4C9061A39F97FF1212F02D387D224B0EC258268A374B6E27AC9C4598FB78C387A7DAA439280D79A6218B3CEB0BFC2E685BAD8801D92B5B1A42F64C8890709C58C95BD8EBC43568C33362A53B5A12C052489BFD806CAD36DDA117B2180B68CFBB317D4BCDF745C50324E19DC7B17AB7F31649A57BCCE91FA720052AFB0B0BA5E8B57A5E4296B1C390DA9A4F76A869AF0B9389C0AC381AEAE0A779BA588FF415858B3300D71B99FC172DE950A95C3A61C9072B6F2A7CD9245DA690128B9C597C44903837B8A9443865C785FF6BC05854E1115B9E3D7A70C7C40216CA48B1C6497062D61FB8CB29C71E5800B8E752E70B9A8655BAA8408742A511EDE8409301620F3BBC2A27790DD7058841432CAE4CAE719740835571CE65027E74D85958DB506A8E9601C1F5BA5728A6E710A3D3D93748A7A640C460167482DCD6CCCFC238326171927C6A72EE7084EE97D3E7519744AB8DF651B9B2B69D4AC7CDBD9437849114E29550BA3321202906E9331BC7CCBF4571DA4C6AE1A0B2797BA4BCC75398E18505EB02DC760B00F687C76F2A35F707F609CA149B4BE233B3BA4739E19E4462D78950138CD1B210904B10A83356156A63631D4A6193C68E78642E7C5C0DAF403E8520CC2F7438AE950D4136AD32684F2881C50C1A508B0442BF6C92F030F82653578C79FB4EAAB1CB60DF4870D6966CA5BD8651400A5A6D424749C8CC6AA6FC90B6514A8274E633AAA74435542BD2EAA354D65A32591819B8233834ABF1391470085C9144B8239390F97624FDBC645D3662F8A7A2B7AE412F8525884081B3282390F8C35E2379AA5D234DFE9C0C94098ECFAB31DFC315413C62AA80FB8A9AD11D070D02CB192D18F3717C1375401C0713437B0868298205162A78F8B00FB46CA2CCC6DAD2717185B72793B2AA009419A6330EC508C8C325110C53FA0512A713C500631B36AC410C5A966EDF1656419740BAACA6719639987BF5E17444B4122650C87C884069FC52BA082837158B9BB85B2C961268284B5D8636B2ED3BD1781296DE78A1CCA44502A779B2BACB6F86D676355D4D527BD050CA8D33A12D059E6D697F986177E1B95424BA97CDA6B6AE0191BA70BCB75172C354541C7742556C5FBE591F33B9624452392412F3859953AC21C50D5A445A34D94D492AFBB01A84C844FD582802391F4F4A5D012A8A62079E254363FBA52C83A399BB3398F6807E6F03F74F68FC788187BE6BCAA5491FF666C98E43C3F860470380768F70B4987C6EA10411EA60FC7E8CBA0B1AFD72A52713A41A2172804ECB9FB60315E37C544555A8AAC8089081C6C2695AF8011BD991E1DDC87C841CBE0C0357E04489785222930A5D75B81CDE91E5804315BB30BC93294367A4623A0C4A0EC8DDC436C7992B157039879BACBCB590490C28AE7C9142267654291C06A75237B24B8895404CDF32A073C4922C202A087BCE07AA5708816818564C68237136C0A98119C2A6244A59051071414425B9230A6113CAB28B06A058E67B16B9B3287F001422C276C78AAF608820836C863A1555590BC802A70ABDA52E4C430C80992745945EBD343277C222836631C652DCC425E1FEC6F22383EB78C9B47967E865C6382231B4FF42B94F281C4E9A849477706C339A48AC2C69416D1E51914C751DFF0B74CC657A8D9B0D0E21CB2C3A72FA241338B11F529A0EA9CBB8BD310203B29775867F23B7A6ED35890F3014474B51A578110CB1E1D052D2CD03A19FA06F1750279476642752934201C0832B80B552C7A4B4EB1118E2466624588AC1D0148C1C0484352479EA604758012B5D49E885965BF6EC29407A0D9D3F1F08826007A5A3D32062D2A775728C35116642149C2D449367BF894B2BFFE5BE757D54623B972FDB9093B0F54568B4F6F2E688F86AB2EABB5B9E60227058AFD73501B1C4E45ADBBD41C7BE8D14BCB8E98AF77698FDF6B69", + "ek" : "E4B7E2A08006EBC9397192DC812DCA1235C197314BBFA533F438860EE71028CACF23C39AE636D6EC1C133DBFC2D10403D836393E8C4D3E8B4A86EDE6C72401ABAD66552E79E39908678EF31A029617A9401DFAAF46740B8C248C7A62F98A522EE5F3F80F0F6693150F22E5CC68DC2D9523727FC3C544FECCF509DB3A444D0EB6483E92CE19BFFED0E71A1841EC72C9CE837DAA83787B07970FE932F26B4ADC5E5382CE8838FCD56F3E85BC3B0F15878D5C6AC10A3545362C9AFD56B18E8764AC58B2B0FA9E5F395524EAD656C4E3F883F446454DAA0DFEEB92BE079A8A9D3987910FF585FCDEFFF5F31789FC93392FE8143DDF50266F31B76E8C14E6125D4598EBC67E978D87C6514C151C5AA6A38E93B3DC5BDCCD37EB2EC4D8130825C21D368CF36C09BED34BD5C89960CCE752BB9206142BF42618BAA4E2D838421BD2DB2C5D303740A49E3F0099C63B27AC95C55BD6725C49D5E439BA007C3A6E9EC0B47F5E184F085A55EFF37BD90BB01D461BBFB5D0A68633E97C89891836E87CD4C2779EFDA2BF267BCC168A787553FF49602F9C453C769AFFF2E45DAD2A648AC92A09CE32B586D3C84BB5BE5CF6EE3A1DFBFA376FF4CADBC0C9049BAD0B02436DF2283F6E31C7EA9D75397AED9C264933B1EF1F074F0D0D83EE12C489CE2F8643FD427D4E18817401DD78F08C28B1A60D83A6E1E63E1DBFE82ACC1189E17D8836161BE05F873631384EC09B68B4375C4613D0EBF6F50E3576964E45D222ACE18F6B83A178D11E72F4A4002095B1B1BA89D9B936A62E852013CDFFBEB005B8E43B1721DCA73EA5506D757BAB8C3A3F96D9378935002E8F95076C5C39A30FB03E8EA1CEAC179A70B2371ECD2DF5B09802D0B801C4F0544D05C850516669ED5D378F5A738530C02562F2ABE7BD0CF8433FE77A0587D8B95984F01109C44BD5BF7987A1B3548450C2E4F82714B94294B817E669A178905E8411F8B7398DA01B14BB6BED4F5E5DD64ECC4DC26B157A9857FB69ACE1AE42BEEB5B2AE449324227DB88534F554D4534BFCB06C75CC2BE0785175A2F7F75E423B09EE53C9947257404C47BCD1082005BC6F04C731CE6A74B65BCD3D59DCA5545F95FBD82DD66822A8BBF857C7B63A539A5F725DDFF215495DDCFE6A06BE3C3032946D87C6698A9E0E25157029526DEA66BC0F11D214F7CA13E7E5D40D1D8970140140E8EBC0B0B5AFD1CB779483F0F1839D0BFD919D5A153C9F296CF6D9B68A9D5CDAC1F2401729A5625F3AD86E93B2BEC3733B3BD459DF0C94D52689DBAAEBC51301E1E5D2DE9436BE6A5E7F9F5CE8DDC0FA03B3E667903C7BC0D21454F1A323E7F289F06123AE3220683D8D25265251B0568023F430CC541AE70FBB68D1BDFB33B2E6234135E9CFD94A4B71F8FCB219B750B0C8B8BD8E0B2C78133758649001B45F9D064EA3B0D096B5F86987C3F3082AAF4DDB61460A95CF7181ED7377A582F22B1B5FE69AE702500099DCEF7F99450B3BDBE8E38A1FE3E85EB8F64D3449264E491E388C9DAFDE9D3D1FBF6A417EC5F81EC51ADA7E7BD6F222BA128EAA7E01381AB2F81DB77C3B8398848F4E2405157DF6F98E4E1B21DCC093DBA4700584D50C7A90EA1BA7E51FA6D13660BC3C9F9FD508ECEDB184CD95D0236000DA50C94B2A786E736878FBA0F813982E7818D3C10EC752B140B12D4E64D004F32D1210E8E136B9D28B2343E26894323B504E9A532E2A1D2B9CD69D11BB5205668A02D5BD974EA0EF9D3B6AF85018230E4731A335CFE2530CD9F17761D9449D35F7CA1C56734CEAF283044563C00A78C1359CFCC8CDA8F4C34A688D22B83C796EB8B57E3D5D17CCF100382053E0E80DD725E6EE4A2C7EE3AEA3FFBDF2680BE54B8D9DDB1A315CD8F9C74743B2AE7EF5FC34E9C65257EF84280E70FA41321DADA91674F3C918B1499DB83A40F94FEDBD3845114B288147E57968720274BC402849DC00F82C3094E8D043B8F25AA80325F35F21F1B5FD76C14953DAEA437F8AFBDE0151B8CA3BD7468BAE82BB0389119EB81F9F08C2D76BF4EE28F80BAB1CC5C66B64CB9F55FFEC998738F489F97741B59D945A73CF4A6E607721F3AD695B483EF88CB3D1D88143B59D4EAE48D52DE980ABE4EA696C8930311380819A03A1E4BB368EB6E933355417E3FF44D358C688D884E0E324D63CEC7FC914572262819EDCAD1786D33513322DBF64DBEC8754E982EF9", + "k" : "4E4D3DA9ABE48E14623499660F9691FA42E9C9A153173E645CF670764702E738", +}, +{ + "rngSeed" : "730B65ECE22DE27D573CE3AEA7CB021C415DF210D228808D91D4F380070FFCB0778B683C71D4853DEB569C822765F2A3", + "pk" : "90C537FB848EA86C2BA929C7B97456AC4B5C5007B27631AADDE902AE1917DBA8CF2936427FA22504AA2BCA42BDACB21AC9A497EB1CB8A4B096E69294620386ABC48F389C7F14380B03B10C614C625427C8CB9962F3D75409D923A56717882169BDAB15E4426DFDB26072952255EAB0380A88277CCAC1D24939C98900D0BE4570B3DF596AEF0A1747B2B0106C31E9AA9164F7745DE23BD1CB222178BA13F7C806C0B02FF9898774646417BB2FC3153167C1EB707655C548B63CAAF3FB3F37771BE2FC972D03BDE5286586D406B00902DFA0897785481B95805AB79DAC44233AF99ED3F53BFD6CC36AF1CC79006289563456FB71B54C6E5E894F47D715BA062E010841A9E67ABDBACC31DC373EC88CE8EBA2F96381EDD02FD0B88B47888F5084AC264C755C62A663CA9E30BB2BB8C89DC2BA91BA652FB79008AD91090C0614D6C7C674139BA5D57D26DBA05E7C47E2107AAC4CC28405A7D0D415E2472F66C40D49E094ADD494C19175886474B5A6991E355738C66D9178C94BB4C05912BD9D709290A8B562A358814A14C50750D17054273C7587B7AD5E403F231964BB40014FA7121FDB74DC23875A148F0F021A8CEB3CBDE6842714CDF1008D85B0AF62E65CCDA27D9FC2A12E415801BB22A865B861AAB5CC3C9093C3164E6B436A3475E5359BB8C241B635C351EC3614F7A225D522F2A0B7B181A1F7A4CCC858014A2222BA5B19767154E27B2667E90AEA352AE7D3C68E07B7C4D0482EC38AA226AC4F2B63A8DA4BE57842A4A65B6E04C2166327BE09A30128BCC33C154031B94EE13AA5D60F7708347659B4D73BC500432BF2401861C183C732019576A672D0C10D5C18AFE4364E9CCF67D670B29283D0F0B9F91130A0437D7450ACB4D76AF99AA4EA287A6BFC73FBAA3207F58FCCC775A811A7E6A0B7A63BCD87F04F1EEA0D57AB7735315324282B4818B8D4346B0ECBCEA3AC9C0A7BBC17A955617570A511447A9B8475F7C602135F57255E2412CB6DDB0D22C30159B43B9DD58066D81D77F7A4E263603E193EBF671FA3283C69E71A4AC433297867DA2B2B7ECA19373A9B4D3897689031E58284EC8779FCC4CB742B8712B11A3D143B02645A99DB61BFB19C26A5902F7B3D77302A9AB059350925D8E1A994B586EA777697C389F9CB6E25817E07C5716DB9AB63F451DC89A852031BB3352E8BA53643C509ED8590694B6A07340AD0FB2F1788937A0C45CF9A441494AE447C44C6917F2D7B21BDC6B7D3853BD8E33BC7EA75E62535F95096A9D0930CBCC0A210C2F5B81090D20A5D7C0346BB43EBE6B77072859F13A6576C72C0553DA80A4CA8F03292D86A98246151960E4B15B758B28E2AD2271C9CA70F92061C8A560BE21A2D967C0AE1B0CA446A987BBFD888CE4CCB725B95050D03134F3441F853935255BCE8473E88397D5EB4CB8D6ACAA6BB8D5F5003A560B08C89AC890B77AA16304F5CC74822764D82823B317572C5BBEE018EEDAB6CD93CAA924279CA8932A8858079197D412B7283E084A7FB9DBEF26D4530C1B6136619B06FBAE495D207A3C326910A5C2AC9C7B919498BEF5482532535D2551FEE95154B2082A76C0D3B16CED88993697B344CF7BE4742A3180C69F6FB589AC17FBD03489B13A0AF951EC1D9776EFA82CFD0276E58C553B2046B4594C9621E0AEB160D7923BBFA53F7C9C2A4A077D51A6F38473FB6D7A2B2B99C5414C5E646734FC48C56C18D30997D8073AFCB822680B321C40696092A7A9F9072CD034523ACB15154354D697F27A312348601D0D1170BEB4759510330CB0ADEF4CF31CA82F7F15BC02310F22C92DCBBC059E34771725685955DD5490331E0BD99829692275598A77A310243A6225F392A9F83910AFDDC172D124CD295288A77AE051031F898B42D792DDFE8C0902944B68043BBA48A25C27323F07D4F6A8C6ECC33F13948AD12463E834D23514AF69954395A144D1A4DF8F526C0331247D16D05E185DDF04A94A92047BCC976BC17F6B7488DD390EAAC4B608390E9FAC6C2829EED0903D544B3FF08B2C27A779198387A8112E374CE4F5B0F5F898101159462929C5417BF373420811B4ECBC034EB41AEC0888A30976428E2A54463072F3C9B55341147C464DC88B55DAA1FA7920C22FB6C8225B2CCF47692713DED1C4A76A479BB111E56CF782A6CAFE938D47DE49BB47E732223B0BD1BEE7BF690D1857044EEF2AAEC", + "sk" : "3642BF33D87830EC6D87E3CA5E4432A0553FA502878F93281671B93E87CB76763518841148126CCDFB6E8723AEC1975CC8A3971E24A8A9149A9957620B0B211C4C3F942A21DAA5182C63049BAC82959429F2C1B4F4B1204CE35C7C683DB5127A89699E23588D194574E603557D811AF3104B7F23627DC046ECD6AA633A20054AC997625147A2CB6BFB62E44BC7ECA7A019D41FF5AC505870C0DC648E209111CCD5827C750EB676058C6A14267CCB865B3B40DA4E2476AFF41B9227E18274C96E32966F2EB611FCFB3880159E6F2C62A9565C8E6C3A84BB530A13895F841FF354B798299AD3B68CA32838EA6B3920B3B6F0415B7A750295D33EAE09022B8C17D7AC040DF6B298D7BFDAD78F868CB97D178D5C80B27B69CE03D37F3277661D9B9340F347BC7296D310041C996EFA841BDDD592FE4B480DA657D47BCB4D147C112243F15268340B14AE26742B813934C26BE8204AD984863EB44C50C510A5C5872CF334275C5BD2517C55772E9D5020E8093D5F21264929B1C7858B4F8745ED0B2C9BF9671D3C085E80804AD730B8E0865B82A6D6BB1595331A0A05567BD3AF6A641918019D9A89B08F227640182FB8C7ADC6278473B2B8AF4C4C9E6B8F8232215D265F433C7357FA8C91751F6CD08B678240C5DA1EBC38CE3F2735D3320713AC4301EA1FDC1990B8909CB718B6344C45A612633376BB9E003656AC347305C3AEC055689C696EB01FF62B3A4FD0272B10CD778572667702FA4C2B7CE5305C413D91596904B872A0B051A255AF18119D00E1A4654C05259CC16663674365708843C20DF18B95D212EFAB1DD9485DC4426782FAC42E258FA0CB8BC3896A507107720246B972C457750BB98AC03C9375820046FA7021AF606C9344599EF233DE25667592B423E456A659C0389B86B27A0EB4675693C029C489A4DAA1B5ECF37AFBF80B8FEA5CD9D37BEADC9FD812428EC68484B8853CC82F019C9A7419115E8AC0972836D42BB459611BA06B82A59592F5440134908F35D182C0A765F9F44B66B293F471222D648989B61B7EB8586E004E7BF789838500C2AA2DE031661D4B7C46737772F4A86DF60E050164A1A998E996042E22B7DB76C3A4575F99199C5851C75F901085B21F6F693B5839557F259194590E84DCBAD233BD9B670049D47B67D91616DB28DCE64EC552712129A2ABAC23B4922FB4CB6BB3E54F7DDB093C5811A638CC3330A1170C46DE338757F445DF01AA42E056E6D59DAF690D3B4961365A6927DB368A5633A4CA087FA74020B0B7884A0AFECB5BB3D124276B38EB8C19C7C8AFB616A854B444F7F0910ED6C3EEF93722C827E80297E7F411B90B41ED430258E091E5AB151D961AF1E51FAC9AA03172C147D69E84274B3EEB949C8588EDAC38B400C775849CF162932BDB6F80FABBA816BFCAF51BFE9174CFE0191084004486814E938153478728041FA06A78E1916D20465370E55AAB5C993EF543C360BD082C7298250678F979904B402DE70DC4F9403E805B71955039B539784B2E79173D870363D8B677AA5C823B8980062CA773BA71BFEBAFCA6399B40C8109F4848DB6CB154A4846CB9C638C4E8B10149DE52667A21D1AF419DE65C030CC7BC8586C45A615DC346EA4073F4EB131E0607740C73DED62C192A413E955146F86AB9386156B3CA110295CED41977B147EC9E73F934BA396A27B6D6C37D2460E4E15C0AF6A090CCA7947C0103489C7DD9A56DFE62F5C9692531087FB7B7A75206765F34316378673C52B6279B0DB8C8DD74049052AAFA5467AC9FB7686CBB904F24AFDEBAAA8A7928DE03C02E35C14E4102B560D8831C62C44154758582BD901ED9C963FC558ED076C107A87F0E49BB2E1585E809BA31788A925588A0C8FBAB37B3BD79268EB359982063775ABAF9622024AAA9730CFF8411C04401CB58A4EE90B83EA547B1FE8AE6C3A93531511298331FFC512EC195F982C39C9394BB0933BBBFB1B46FA0C2DBC120C8ACB03953E188A6EE6B2852E79642EA3261C8403B3497B99BA7B25FB99949300DBC9BDCBCBBD72CA935242AE35D27CD66003F22C4918AC412F3304EE92B740C86CB12362DF19353438569C16935EDC8AF7B6091CC97C59996CE174253E9B2612A54DD9399FB11A5D0FA3AF913BBC66E1874DC7527381B593966014FBA090C537FB848EA86C2BA929C7B97456AC4B5C5007B27631AADDE902AE1917DBA8CF2936427FA22504AA2BCA42BDACB21AC9A497EB1CB8A4B096E69294620386ABC48F389C7F14380B03B10C614C625427C8CB9962F3D75409D923A56717882169BDAB15E4426DFDB26072952255EAB0380A88277CCAC1D24939C98900D0BE4570B3DF596AEF0A1747B2B0106C31E9AA9164F7745DE23BD1CB222178BA13F7C806C0B02FF9898774646417BB2FC3153167C1EB707655C548B63CAAF3FB3F37771BE2FC972D03BDE5286586D406B00902DFA0897785481B95805AB79DAC44233AF99ED3F53BFD6CC36AF1CC79006289563456FB71B54C6E5E894F47D715BA062E010841A9E67ABDBACC31DC373EC88CE8EBA2F96381EDD02FD0B88B47888F5084AC264C755C62A663CA9E30BB2BB8C89DC2BA91BA652FB79008AD91090C0614D6C7C674139BA5D57D26DBA05E7C47E2107AAC4CC28405A7D0D415E2472F66C40D49E094ADD494C19175886474B5A6991E355738C66D9178C94BB4C05912BD9D709290A8B562A358814A14C50750D17054273C7587B7AD5E403F231964BB40014FA7121FDB74DC23875A148F0F021A8CEB3CBDE6842714CDF1008D85B0AF62E65CCDA27D9FC2A12E415801BB22A865B861AAB5CC3C9093C3164E6B436A3475E5359BB8C241B635C351EC3614F7A225D522F2A0B7B181A1F7A4CCC858014A2222BA5B19767154E27B2667E90AEA352AE7D3C68E07B7C4D0482EC38AA226AC4F2B63A8DA4BE57842A4A65B6E04C2166327BE09A30128BCC33C154031B94EE13AA5D60F7708347659B4D73BC500432BF2401861C183C732019576A672D0C10D5C18AFE4364E9CCF67D670B29283D0F0B9F91130A0437D7450ACB4D76AF99AA4EA287A6BFC73FBAA3207F58FCCC775A811A7E6A0B7A63BCD87F04F1EEA0D57AB7735315324282B4818B8D4346B0ECBCEA3AC9C0A7BBC17A955617570A511447A9B8475F7C602135F57255E2412CB6DDB0D22C30159B43B9DD58066D81D77F7A4E263603E193EBF671FA3283C69E71A4AC433297867DA2B2B7ECA19373A9B4D3897689031E58284EC8779FCC4CB742B8712B11A3D143B02645A99DB61BFB19C26A5902F7B3D77302A9AB059350925D8E1A994B586EA777697C389F9CB6E25817E07C5716DB9AB63F451DC89A852031BB3352E8BA53643C509ED8590694B6A07340AD0FB2F1788937A0C45CF9A441494AE447C44C6917F2D7B21BDC6B7D3853BD8E33BC7EA75E62535F95096A9D0930CBCC0A210C2F5B81090D20A5D7C0346BB43EBE6B77072859F13A6576C72C0553DA80A4CA8F03292D86A98246151960E4B15B758B28E2AD2271C9CA70F92061C8A560BE21A2D967C0AE1B0CA446A987BBFD888CE4CCB725B95050D03134F3441F853935255BCE8473E88397D5EB4CB8D6ACAA6BB8D5F5003A560B08C89AC890B77AA16304F5CC74822764D82823B317572C5BBEE018EEDAB6CD93CAA924279CA8932A8858079197D412B7283E084A7FB9DBEF26D4530C1B6136619B06FBAE495D207A3C326910A5C2AC9C7B919498BEF5482532535D2551FEE95154B2082A76C0D3B16CED88993697B344CF7BE4742A3180C69F6FB589AC17FBD03489B13A0AF951EC1D9776EFA82CFD0276E58C553B2046B4594C9621E0AEB160D7923BBFA53F7C9C2A4A077D51A6F38473FB6D7A2B2B99C5414C5E646734FC48C56C18D30997D8073AFCB822680B321C40696092A7A9F9072CD034523ACB15154354D697F27A312348601D0D1170BEB4759510330CB0ADEF4CF31CA82F7F15BC02310F22C92DCBBC059E34771725685955DD5490331E0BD99829692275598A77A310243A6225F392A9F83910AFDDC172D124CD295288A77AE051031F898B42D792DDFE8C0902944B68043BBA48A25C27323F07D4F6A8C6ECC33F13948AD12463E834D23514AF69954395A144D1A4DF8F526C0331247D16D05E185DDF04A94A92047BCC976BC17F6B7488DD390EAAC4B608390E9FAC6C2829EED0903D544B3FF08B2C27A779198387A8112E374CE4F5B0F5F898101159462929C5417BF373420811B4ECBC034EB41AEC0888A30976428E2A54463072F3C9B55341147C464DC88B55DAA1FA7920C22FB6C8225B2CCF47692713DED1C4A76A479BB111E56CF782A6CAFE938D47DE49BB47E732223B0BD1BEE7BF690D1857044EEF2AAECFCDA92E6BDB853F01617133D65B67C0D6CC83710C053A18263AA91DBDBEF7B8511C033D4A4BB231985CA7E851FC73EA4B2C29E131B7F442DB8A66A9E5B31934B", + "ek" : "A705D61B4D5B96083F3B5D6007240B65F6958AF492E332FFCC708CD0A9423683D64DC1E95A29F83BA59F864A3EAE88FCA0601166BB1BA3284A3B22B86985AE7C1173AFD0CF4F789A44F1D87A4A89F8DB177F1159A6EC27FF7F0014408730601955F03A531C463E07C84313C460F6F507C9F9C1F73A142DD229FEEC6C54CF926C3BC745048D51AE112A4C4A1BC3CE3A665BBB8D78ED7B8D4D4ACF45CCC079CE5FD77FC01DDA44617755D59E64F537D4C290165D413D347C31B3184D31A738B8570335099140015E08F77BFCACC33F3EF30A088DE749285DCDB157B0585CEE392534142304D88F7DE8DDEF75E247774821E50E1991645404472287400950FF1F6724621964F2B28CBA39D85F48098FC78C1160C60F0A3EE2D053032B8013ED6FAB323D21A582315EA55551F87D390E77666D6CD51EA542E53DD2ED6B69D48F0678CD36801E14EECC7504CCB0990E921F56D81C0B2E41765C6FFE793EF252FD452EE2CA9C51C70863720F478C3B5F50B7223E5500ABC1CDD1FFBCFE735F3A2A7C3C2D8CDE9EE2A71E2B6D492EC1ABA89C9637825AC3EE0F3D90FE051F66EAD7F898E5B0DE23C404833E3368C10EC0D636689B2C0C8E998646463DB411AF93C59633137E9C1023BDF3B3434B43465B551F22C1B5EAB6CB525EDEDD274451B021766C4A98B9C71DBC34E52056258960E5B6D72088329204D9031EE36BBC011F636DACBD9E8A995F8E53D1374AC86FD441D3AA3A6A804909EA63D9BD2F4ACB43D8F256B8AE297EE9C3DB8E6C42BF8E954271CBFA8F3803D8F893FC6F7E9BA27CB96AB99AE8E77F2F9912D66D398AA9116737DB9AC99436A1860F48739BEB4788884D63F5F6DC38469F3D2918E1B10E276518D8CCD52F09B9A00E0AEECB065CED407679D6FB1352B4AFCC1FDB56B973C584DEE576CE188D2E99553C3111DD2B8416AA3E09F9B6EFEE804AD87C653777ADCBBCD2854DB5A82B7CA4383C1581DCFDDD2A442071E153DEC2641BFA4195B7158CF07CD622D2446E6535C30F93FCDD507E7349BEAFB780E12A24415069C3729335BBD1680290F92347EC0C2EC320B1599E062A7D5032C8FD94E580D270ECF9DDB92670D6D5F07883C00E7C1A3F598C3091CDE7BADBB019F0B9F9E66AA5CCB5584BD3DA3B806E3BEDD0766BE1D716D5CE94485AFC1D3FFDF8C06C7316CA3D2CCE51703E007539913983910DFECB62694AB29CBA70C20D9933F42D368E3DE0E875B53EEE24DC28D222496CBBB229375E6FCC9616274E49690AD51B91223418818DB7979A08A2199564ADA8A0EF48E420B93C637BB4F72F9955A6EE15A22E990C0FC8406A20846CEB69FDB418A938533AD49A5CE5A233D687AA3E9FB8E9E4B686841592B881A26D2D267790D04A9D323E23917B935E3DF0DE8F32C1CAE9F9B89FECA9044A8988452074A4DCFA96D26C65EEBCC3C5E8898BD2610D23018D47C8E2F80CCAA80B54864A085D2BAC3AA934D6524EBF34E5D8D8C21741EAF9EAB1BCCDA92D91A46D3B0AA7901546967268A5DC978C7FBF5E4C733E77890AE93935481F0FC9027E8AF19A58CCD9E427A9D3CCF0F6746FD2045A29DDE966AFBE12CA8FB78A3A4566B879DE1D42E4024D6ED0F084B0FBF7800B099F8654B9D5A123ADFD1EE2F37165ECF4C7A6924427C0FAE9ACE4971CA218B44A417761D15003658E0E72B0E4509FA67DFF708E3447C551FDF1D2CC4782A6AEE3797B84ADFC366EE8FE7E07FC473CA29F1093E1F9A2F3EF52DBD608643C39F78253864E1FE6354A739607A900E83AA08C7F9264B4539E10BC61DA6DDB95FEF07B2EDDA980001E00250C789B4F85F424184ACCE57D8E504440E5FFAD141F8E81CF65F50172D312FBF42E1321FFEDA9110960FED52DD70F96DEC7874583E4C72E728A1353E486E64E83C3080E62FA66FEF0A37DFFFED7665BFF9812595900F8230237AB862F2C939C3CBECF43BA848A6765D986BA026BCF34238133B5ADA06B5E3E4C5DCDAB3D2C0D916F2D3E7A768E8B3D85E958F62B9E6CD20C0BC23EB5267E5D78DF2B35F3D1B8CAB8006B762FF9BDD0D6AC9E457580FC86F7BE15B5C474A9AE63EE1D4676556D9B806FD91AD5323A4568CF67185D4DE3705FA5631FEB8AB62EA8D279208137764C24D0A85092EA31006DE55711A9F92CD30C82B7995E213B848F20B234A7AC34E60C7EFC3DB331F4A96039E8C3C0C6267D85B46206B196", + "k" : "455FCA869B90B4FEF35A43490C37425BE66221D7E8845459163F728007EC6C9D", +}, +{ + "rngSeed" : "5522A5A891A9A9B5514F4556AFD8DF40B9CEC63A01492F0CB8A1DB073A285A963E4A9FF2376C88662F7D8D241F8ACF17", + "pk" : "12E4C27FD191AB43B4AA8A66C4326E681CBE1207BC2D5AAC1AC59EF0A8AAC0C8B91F7C23AC35ABF566C75AD3B01D6B1DFBC29DB4A334B44C10FC25808F9B8ACDB4A2BA67528FBA8EE942A895D5544857473459763E92174DC640BF284908023146FB553B1B8B1E99A7446C5320CA17EB6BC497A330DED7B1016A1C28D23964F24F2188B2D7EBB2BBE954C9D9271BAA7E429C02DAB991DFFA49410BA6AB20829EC41B03B8BA8756B5CFFC640E928B24361F0F007226F2B5315A8BDF8A10AA88581CE5A140588B69B531F5112610C5306FE41D4C018302DAC1DBF69863B6BF99D892072591A0168DECC69F89823999095F256C52C6336ACB063BD741551BB855678C4E8BF90191A38C2FC641957312EE758E73D88D8C8937B9C6912C59CA13854A4209924DB71FD8B547A076A340560155122298E91328A71773E1CF117920E5FAA8FBD847FDD027F734C06BEC0BF479B97CC11D626122D1049E96C7643A6B323AA93E10521460C7193D7C85A1A8969DD0B0835B64ADE28DF777A1C70646B8E55578BA9DA6D82A96B5BBCA1B2E9346775D24B987535882468B3E9263A1C74288695722142D9BA23FD747383832B2A3B6720B21CFB5F00A178C51A878992D666872685CB1F346C77B86A0174AC955B06DF96BA094101330958452074C57377F520BF0766881752D70C0A778415F9BD3B5D276100F00AD563735CCE0952354260C153C3BA227181A21B9F8166DC0AA42ACC241F6051624B88D1659A2A81F9CF92CE82C76DADC27BC3B018F953A5AF66EE21401C02A4E3B8B4188A36BE3818CCB82686CC21D50614F1F000721F8445323B4920B3D929C1362D91EF948371B531096186034D61F0401C09679C54C5A993CE85137F15F50466BACE29512E260F990764C31648D6649D23C800750A08F759FA84258515C4625B856EB368D917C36768A8A1471A376AB367AAB46295707E94080BCE47DD4633C2B50CE0B19BF47D4A68C3519DA21C205B0C9128606EF8A7405AC525A12B0C613C7AE96ACA34743CA9679BF078D5D016405F336F6088A9652204154648E4B3F6872929F02670C7962F4B08BDDA9BEB2A33A2BABCEF40CC4DE288460D0188FC29CA85B212EB40F7B158AA4A38710E0608EB150FA5252860058CCD822618961CF5C18A01BCB2EB92DDA84597FE9B345E06D14A597917A4748949CE5F29E60A7AB29740242166C5A651501010BBBC73926A7C4D0DC6AA415240E0C0769774055F9882AA4330DAC1D8500747BD5264BB7625C2AB58E7917CD122858135EC09A3F0128837669BB37911903854D57DA6957D70407C752A20951535503847B17C536A69AC09A84CA64633A4FB9C26221296190B27C03781729456F6653639FC036FE17C4B66B390B2204A1361555323DD307572B2CAF24148DFEA74EEF05880205C164DA71980974240B2167B3C3200745CE778A4CAB786A0CBB132188158C3111707058884358DB6EF3D04480D7BA058C7E52E4052C1898E2918D98590716A80BD9A3A4C3D53CD8111005709E708B04C6D18BB1577219A39D26A496582384F1126FE491A2DAB7B8ADB4A07563C687C4A6056455113C6FE9B7BD30CB7FBED2839A93A584C76AF5C1422DCA809CC623079AB65CB146A3011C38C1A6F3DB134B72583AB9331D418C7AB513D77B91A612053F217D406BABAF4170607A1979EA637F8875154561F69870FB1682A62052FA36A21BF94FB4F24EA54C1658D8BEA4E2813707981366A8D9655400DB440DB8C27AF57EBDAA8ED897C7594712E6881C81F5B79557834E53C9B537AB69942830FA60A0C8BC7518192E52396EE15D945B9F8DF019F8F32513817117834A9AF58FF761A1830798EDD48FB571BE338B43140C44D17B272DB6AEEBB0CAB160342B49CBE2B47A6A5006B5CAC09D763F168C6A5F329B7D1B87DDE69542A4437B8C426890B4A5487AB43A98EF94667EFC881A943B33B42C776B3F8AF853FD59C2D3031FBCF541247100D22219E67094BA89791186BC8B7B536FB6438ABA5275D234ADC5A9FF129FA7D1B5C5757483F02980FA40882AA0C72C0EF233B0C2931F1E15CB7D528B471C50903256E54A87F8C16F02B3BB904133BF60136D603BC57C503420A8B6701AEA4A3B4052334F75BF820C2ED9890BCB812B20D9031C269AF9598ACDEB8A52BFA7CB804627ACFA20285753264F3DF670DC445647C881E112B71095F10934", + "sk" : "58B513BC1A5F348C2E22A0A8C99BC5178A736854B211C6B4E191B497F288755843E306C1527C87AC5393C98C77669A29299C660BFC0D67453DE33CC838D2C0E2D561E54600F89951F7543A42E0891D846F347A0E2FD956E29072D7B1565BE798D3A295321CCA8209AA439B5374602DA08792D6C814FE3B0398A2743CD258A8E505BE98BE9C5C806C7007ABBBCEC5CAA7151363789B22D6210E519649C34C56AB5B7A8318944370C30D4C16B226490D738282E63881E0B163E11B4818083CFC7593B068EB7C8711AB06553164382A87A683267957485DF51DD5F5B0135BBD09E0BE01594B3A134761E3A7EFB567C4554B0D4B6DDABCC50C036144B1B88484A19AB8A94E168CFF620330647DEE43B673664A01407334883CBD6379A61A1C7B755D28C80921416EDEC02CA326C8FAE52B4495B991335D253387682716F283675AE96EF431B98A821DDA681F35C71F5DA09FFDFA471D915574F23391072C9D8B50B9E06BD91055395958BB911A399C8AE9EB2884154CB7D59AA36A4D05B5887A23962260A057257E7E815859F53C85059760857882AB38FD8CB7A2514D2745867FB348B4F1AB4E8C0F200261E68474DD45394CE01C1E4A07799CA7DBFB5B3C51C7C1500EDC768BC389499427955868C21BD3A94C3694D588700DA5641B242EDC152F1C1C90E3ECADCB04B8512342A76027C98A6AF96A0958F775ABD890FA586D81497013E062AF9AA7E7734017807D89076A102BC46924B854D32476B1B6AC2CC922F0AFEFC6C90C6814A1819E96B429991B1250817A9187755805956D28A7CCCB043469896D326DF5477699CA89081CB44CC492EBC6671F3108F0795CDE1422D3FA8DFFA15E3D6040300B462F57986B355D7FB12454BAC56D66ACA19240C70445C166CDA05A8D5A0763034387B50C32DF573E61C921CCA5B26EE3095B0739CB7CAB1756A097B4C5A24555BC4A84681772B1ECCA530A41C7DB1F2C49C2AACA0EE363CA9A29B1040A5C31C608C235543D36ABC90A36D8110BADF3B10AF267F6CB11EBC7C0224175D2D82A0DF8485A7A754319952DA50F48563937517FD4032935830B47F907A9489011B93A0E9A3D999B3D13416BE914A4D9A4196AE573D73A4BF1099DC3C19DCD2B6CAD5999A71A7E25717729495597997112F23F38D54808BB0B86C2558C83BC5A290B0DDB26A9493ABFAC76E9D25FBC888928417F5C2A1A1E34A355343A45C4309822CD83BC55362A7B8EE521FC816BFE22AFC047196F87B9EB9092700723D3611DC5A53E8F9108E5064A9183AAA252AE2024B33AD93AD1C96796603A8538C7F1A3AF202024CE12CB4025192744BAFA338F325C10E1544E18A92509639BB62C4372EBC39965CAB0D1317F91BF1B46A4523BBCA018526CD681A3082CDECCCE960C6D2E5B317E2568B2F4A25A8CBD1844B1DCFC32C0160F12F126F0CAA3E6E37D95DB68DEEBCCDE353D7CCC22E204BD8B016F9DC1BCA5C8439A4CCE98EBBFAE4111A8776B09BC325599CDAE20C354640FAEE43C07911E08348A17E75F483A3751237F1EB9A43A49702654A4A0F21C3D6B591D3B4ADD7C3320D8083C223E889080AB6B364118CDD1D42038182CE07BCD7ADB2DEB2531A2536D2126460227604740CF54BC513C918058CA527B48B0EC1C6D6CD4549B5C18D50A477A80CDE6E87EFAD1284A71869D46B47F54465B9669E1EC5ED18505BD8C49BEC69ABEE2A2C69C684DB270E5A7A69846738F2A2416148098174C038964C8149F56097CAF8840FCA26D4F47A68D333761DB2109372778F56AA0003F402B3237B079F3A8AC031A41EED50C218673B05A5757D29196A653A47B689AC25A2800C79CA20BBDB02EC6B430456435DF3B7D81089CC986BDB246193BD1A153796CA5F1099D2A8C23810CF8467517085EF79B7BDFA7BA0C1B180B8312FBA0999F87C8BDD518B5654075950CD27861AD55724766664D8A3468A8139201CFC9A48FCFD0839DC41B0D61798EE6180BF33335C78FAA7A6E1A31262521BA7FD79A5AB0854C6A2F14265E418212324817CBA46EE849713FBAC9BC11A8DE51376AC02C35F45E21F642732CC132745C5DD1CD1E45A31B5C9ABC56055A8510F5FA71EB56C89D7685CEB4AFE3255C734A59DCC2B5A9910DB6EBBEAF4B110BDA0270FB568C3C6A59130FE6390D12E4C27FD191AB43B4AA8A66C4326E681CBE1207BC2D5AAC1AC59EF0A8AAC0C8B91F7C23AC35ABF566C75AD3B01D6B1DFBC29DB4A334B44C10FC25808F9B8ACDB4A2BA67528FBA8EE942A895D5544857473459763E92174DC640BF284908023146FB553B1B8B1E99A7446C5320CA17EB6BC497A330DED7B1016A1C28D23964F24F2188B2D7EBB2BBE954C9D9271BAA7E429C02DAB991DFFA49410BA6AB20829EC41B03B8BA8756B5CFFC640E928B24361F0F007226F2B5315A8BDF8A10AA88581CE5A140588B69B531F5112610C5306FE41D4C018302DAC1DBF69863B6BF99D892072591A0168DECC69F89823999095F256C52C6336ACB063BD741551BB855678C4E8BF90191A38C2FC641957312EE758E73D88D8C8937B9C6912C59CA13854A4209924DB71FD8B547A076A340560155122298E91328A71773E1CF117920E5FAA8FBD847FDD027F734C06BEC0BF479B97CC11D626122D1049E96C7643A6B323AA93E10521460C7193D7C85A1A8969DD0B0835B64ADE28DF777A1C70646B8E55578BA9DA6D82A96B5BBCA1B2E9346775D24B987535882468B3E9263A1C74288695722142D9BA23FD747383832B2A3B6720B21CFB5F00A178C51A878992D666872685CB1F346C77B86A0174AC955B06DF96BA094101330958452074C57377F520BF0766881752D70C0A778415F9BD3B5D276100F00AD563735CCE0952354260C153C3BA227181A21B9F8166DC0AA42ACC241F6051624B88D1659A2A81F9CF92CE82C76DADC27BC3B018F953A5AF66EE21401C02A4E3B8B4188A36BE3818CCB82686CC21D50614F1F000721F8445323B4920B3D929C1362D91EF948371B531096186034D61F0401C09679C54C5A993CE85137F15F50466BACE29512E260F990764C31648D6649D23C800750A08F759FA84258515C4625B856EB368D917C36768A8A1471A376AB367AAB46295707E94080BCE47DD4633C2B50CE0B19BF47D4A68C3519DA21C205B0C9128606EF8A7405AC525A12B0C613C7AE96ACA34743CA9679BF078D5D016405F336F6088A9652204154648E4B3F6872929F02670C7962F4B08BDDA9BEB2A33A2BABCEF40CC4DE288460D0188FC29CA85B212EB40F7B158AA4A38710E0608EB150FA5252860058CCD822618961CF5C18A01BCB2EB92DDA84597FE9B345E06D14A597917A4748949CE5F29E60A7AB29740242166C5A651501010BBBC73926A7C4D0DC6AA415240E0C0769774055F9882AA4330DAC1D8500747BD5264BB7625C2AB58E7917CD122858135EC09A3F0128837669BB37911903854D57DA6957D70407C752A20951535503847B17C536A69AC09A84CA64633A4FB9C26221296190B27C03781729456F6653639FC036FE17C4B66B390B2204A1361555323DD307572B2CAF24148DFEA74EEF05880205C164DA71980974240B2167B3C3200745CE778A4CAB786A0CBB132188158C3111707058884358DB6EF3D04480D7BA058C7E52E4052C1898E2918D98590716A80BD9A3A4C3D53CD8111005709E708B04C6D18BB1577219A39D26A496582384F1126FE491A2DAB7B8ADB4A07563C687C4A6056455113C6FE9B7BD30CB7FBED2839A93A584C76AF5C1422DCA809CC623079AB65CB146A3011C38C1A6F3DB134B72583AB9331D418C7AB513D77B91A612053F217D406BABAF4170607A1979EA637F8875154561F69870FB1682A62052FA36A21BF94FB4F24EA54C1658D8BEA4E2813707981366A8D9655400DB440DB8C27AF57EBDAA8ED897C7594712E6881C81F5B79557834E53C9B537AB69942830FA60A0C8BC7518192E52396EE15D945B9F8DF019F8F32513817117834A9AF58FF761A1830798EDD48FB571BE338B43140C44D17B272DB6AEEBB0CAB160342B49CBE2B47A6A5006B5CAC09D763F168C6A5F329B7D1B87DDE69542A4437B8C426890B4A5487AB43A98EF94667EFC881A943B33B42C776B3F8AF853FD59C2D3031FBCF541247100D22219E67094BA89791186BC8B7B536FB6438ABA5275D234ADC5A9FF129FA7D1B5C5757483F02980FA40882AA0C72C0EF233B0C2931F1E15CB7D528B471C50903256E54A87F8C16F02B3BB904133BF60136D603BC57C503420A8B6701AEA4A3B4052334F75BF820C2ED9890BCB812B20D9031C269AF9598ACDEB8A52BFA7CB804627ACFA20285753264F3DF670DC445647C881E112B71095F109342B8799C6382723886F5B8371EE58A35FBB48022D9C107BA6FB6DC5FDBD4FF57375FD654BB12DA3469881ED591A82F58B4BFBAC587D045FDF3AA0348029DEB1A7", + "ek" : "09C86B5B52B46D8A3F8012D34D1CE03F3D0FBE19B23362927D651DD994036E4E43211BDA093F4F1A533B399E478C653BBBB01C6E023C65D2DC8BAA188E53F6E2E63E840E0560ABAFAB80739ADA54D49F9F7E541FF9E0780E247702F79885E201D3C149D9205B477BCF9AD463861B31FE5BE308685E6CB5A962067FED3C6D302E23E5924AA7260DF379E173FC437AEDBAD535E52720B3872DD2CDCA94F66CA7BEFD7D47F9B9748E16223380563C0FFEE5656704553F201CF1B06B9DC3C94233E34A6B48A4E816C10758BF686C7C93832E202833953ECAB1CCFDE104BBB01AABB9F74B8E178D41429EC5D48461DD0334B059B36BFF6D2C99C9848131BFADAD32E36F037DCC34131CCABFF8C487A94F380F8C466549F506A1D902CBA1EA4BF73120C5FCA2F501E713475A21E3CD9CEA4882BE4DD7EB1A60FC27E6EBA3CD9B60D3AF87DA33B6429F69665DAD74D07158DEF877258DB1187ADF7552AE0C0A25803D0F04B922E207F79426C6753FE6CB473270350DCC4AB0C0302E5B5BBAA59E9C60F722E7ED663266CDA3C5048005BC5E5B5D0B8B7A913A69DE90B95411C301FCFD740F972F1B06E919C1D056358DDC5C91DA9EF6D8A737ECCADC731A9DFC8D8F0394B9556F03C64B2C298A414C00FE5CB8B9C90916B288A2869B2737E6B5F3ECF358CB79A0A658E8EBB87774F6B3B5775AC08A8B96C6B02AED2E56911BD3B7B4E0EB7EC5604665D97CDC9005FAD903927E6414E5F2374A1AC00B1D907CACFBFF92617D1C1B1F82B2BA9723C0280CA8EF32F07DEC68D87C3D33B4D3B50870B7A65B61597478B648A144704DB21A505B1F0E970841501FA052DA05BDFCEBD9A4B08DB4A805BF36BFDF73C65A09A46B996450F4CC7FC8774AA52957E3FA0AB874CEA843F0E8ACC72435790682AD3BE925A0D5BB9CC12FA622F90CE3FBDD38EE13E2DD263747B295249382C662DC2B9EC5F61F3610990BB1F1ABE57FABA03666E7E2CBAD9C4163452797C2ADB75C16F7F7774890845ED0DD8461032DE95ED344810DD7463D9B0FBBB6224D90AC0EF5BCCF6E857D85BB27787AFB60DE134DDDCE91491FFBDC92F76214C91783317EBFFD00B58415D9326A03682172D0309290A93385885A1D4B4FDE7B6B26765C23F858079111AD9A7210569C830D3930E77E78D6FE79C609171780ACC167ECA362735B0ECBEC0C777EC90BA606889DC4FEE90E84E0158446102E29B3053C31552E76F505B31C2F3CD422497D61F8554F546F8A7FB7C9D129363989CA8E8607BA6EB0AB76159BA40CE7BFFFCD76B67B88B885008E8C5DBEC9F1D7B2DD3D223C4C4068ADB64116896A5FCE9E2D700D38A0BDDED8C2BAEF180FB164694CA9A657B093D5CEE30B993BF0242707F3F0FC9E367EA44D143A1A045AE4719652633744386E1A1F18BDAA1D3BFDC93CAF82BC7DBB43EE94D377E14C990DEDC614FC37C894022E508F0476BF95FC311E2E2C905FE1B17DCCAA7EA88F4CE92A0840B747F13442F9AB91BE6AAC4D8640ADD0DB369207237C9E0E9455CFED55D15FF1582AA3A6C8A2C258604C718C98785CFF961828CF5D8B7C6905EFAFD4FABE890254CC46E336EABD9778682822D1042371FCFC45657870D3E860706B0A414B0CC12E048F8D418FA8EC3D97F11FAFC309DB9058358D77D758471F2DBE247E4222BE0AEF975F55D3820F63E0C1F76C8CD47107D59463C2E8C5F3D9DB85634747B4CBB728921F33F1F5D4F8A4DF9BBAAA2451D1A98BE8209EFF5F099F168D673E15CEE6CD207552FD4C1D994716E0E7DED524918368E1CC4C8349C7EECBE52317F0511DB07C2943852E80303C197CCC08E5846F46974DF3939B2F6A6C1E3AEC3D74372336FBC9C1DF77C138B229D700307E66A0E1E5933121A8F34E323346C71490D1486F3F8FC2189FECA48452771E9BC15395863D2104343226129FFA1F3D7C5820F0C1434BF81C5CAD470CA508464960A111ACA2315AEA6A5E9B7A4EF738E0C0E9F40C198ABF9580BE58431B9CEA84BEEC8B9199EBAFF607E00CCEFC6C8E19407AFB94ACC135F59D824A32DBE6B79B783AC875449F3DF7970B20679803D58EC190C8E53EC46F7A7173DAA24E9658E6F1AB08BA1F8593C5CBA2A496A4582C28160BEDA9F2CABDE99A6167C7969BD011B2D70791A04BB0742804F6A5AD6627CB46D4E978973413C937C635D7A48125D1071D9D6A9C82D24085AE240FAD", + "k" : "BD7613936413892C7F466DBB1770FCA74AD4EBA18EFA8B337FB065D63540D466", +}, +{ + "rngSeed" : "1853E72329353B3F89AE6A1B1EF700DA8ED3C10D19F9E61EE9252E28EBB0E15802EE43083A12A0B7527088832605E3AB", + "pk" : "96F73135FA51010A83491B407571126D85002A60CCCCEB5393B459CB39B4DCF175B2134CF515C06B38CB0EA33D8C34A7283B99B6D0C9E90825159CBF4BC2A1C0F131580557F243184BBC7498B39266F669FC161150482DE480AB196BA61DC526F8A46A2AE3336A7ABCA9E2743FD654E965B3B33CA0B9CBC8C96095D78A971A7277496A8C123967E8C204765A864890B762D34E83570A8DEC5CD25333276555E7644EEB5CCF8004579C357481000AE9A930A7313468D3A8B6D5B4DA4A558A7C1318DA670DEC758C98C5048144843096C2B781D73A9F215C2CA0481EA5ACA259997C8479256841507717B7DD01CFE1755F8AC2BF1008C2C61B7BD13810787185CDF16A17C2CF00BAB7EAB737A641CC12EA6D8BC802E0661730628194C40A7865A3587CC2F5B0AC1D328307C55388970B96C4969A533E04B425E528C713D41821CA6CF1F5BC74E64859C49B914563AD193C626C6DC520143A755132260D5940C76E20A7F07987FA7C1A4D1283BD700C9759871F973FA6D94FD88015CFFB046555B36559420BCB98CE617169465770135B15612A9884586D0232D44606632C50A9D5BEB3697669C9940E1739508C360505248F501DBBBABF70E7CFFB24652B782DE5F4A310A7767826BC73886E60E51230068DCFDB2B3EF246F7701D65813E54D78DDBC34CC9BCA025914883364C60576A5E0C5A863A17A9872B818C070647170CC46F44880D4FF46D68C4694442433C823C0AB39656B715E0443E8EAB14A990C42A031EBEFA6CFD54C32FE4521E218396D53C5554C60B93CF2F1CBB0062C6101686E5738896621E44B32449C297D968B16C80AC7491279DAB0F84749842195AA3DABBADDC2457FC8B854752D33CB1A5499DD53725BF34BF34A68457E57E4B270FE0F07323275FB99B78AA90AF27480B6440217B01867A1B7A5A5885FBCB931C524395CB11A406A492C4251F9C09E14A45E2B86A98C72F1532664879A2D5557FE9DB6BCB2AB6197892E5686B2E1AB35A3434A77A65EBB6189AA00E19FBB045A03FB767866184C5C2E2B155F465BC7A135AB25CC5415B0A42AA17595A32E2A370317414913278C18837F346C3A54BE5722520315332B2B43ED4089B427CC8E24F10F17610E40882B4C724C48B6315AA6F0C64A4032E4BE75BB6B0702A2CB7A11CC6AA14BCCFE91AF25642513425CA475FD7E7C387214294A36FFF09BB1388A5322910B9906491BC923A2644259086BC5131E5D67794D91F65B24A0DA06CEEB63239456E6C3B1CF4FA04165879B5858BF60664AAEB45B3A238B1A926489A2D395473D3A5173FB37A51FCB5BA0C9CC3EB01DEBC383260B4F5033BEE258F66A504E64A74FAFCBD1A46076EA00A02246EAE52BA6591A8CED21B58971F289847C508768DBBA5AB1921C14982C9525AB4B64285723954D33C8A35396DB137C0DB48A39432DA0ABC3857C5369B236BC03EF562A8A5E4211986A385B8AB4D1745742411A9712256636E62976F99A72D75C654F8574737B6AD34C129A2EAC22FE166B2682840F7043D4339BF699B68D51ECC32974C161136272F9012219BAC6BFA8950C6016207DC6566D20B916974743290F0A52B8BE51C9F3C239E8B6842278417A05DC789BC43FA1EE0671A51BA3301246BA780AB71295CBD20ADA7A07E5593A3933604EF972A711349A0678A60D2AF2434B17EE940C067BD89496C90D4B9903B9D146A49C36138DABAA405499ECDC02F791562A5D446FB358702B2A5EAEC93B7F4756762B3C17B0E8D48CEB5D5244965168FD9C3E6495D1FD578BA2C168805897CD351202059B5A4B96687465741B077677583CA7411C4331583308DA00AB5045EC5943BEB2800B30978C31031675A84DBFCBE6D7B27B2DA65152C692FB8727A485B9641888B1B36A25491AC76045792278125B0A3735F3E759901507CA4A2AA12DCBCCF3C35C68873518A4FC778201F0B960C7B551F038C6201378EE101948629DAE0364E38AD079320D2CC35BFBC8AE7CC446526447D60B19A36519DAA8331A45F1E4308D564979A5179073130594CC5FC07A1FB6B5966277511544611E018F3F8B76567ADD2C94A0DA8502063C66C54C3A50644E43B81A93C7CF0409B505C77F5D06D34432BEC389A137B6FB9F18DA05426D03477FF0B8185327C37F449C8F6398680C78EF7D26C51BBA9665CF58B72CDFB115BCC2A0715B5B4F40DD01C7A0585BBAE73", + "sk" : "4CCB897E841627F45DBAA7B00B670C7BB17786A89A4284047A2527C9464307C2B1D4072F357A09DF72A768B752E8794218F94BF07A6D288507FAD04380B13E397C80CE956E3E96A604D668530B20759438A83B35219A6CF39A44D2CB697453265BA04784501BD310560E7CB693A06944CC2EC1FC1201E5A105B239D024A41AC50103335C170684C9F03727185858506BA29C8D8C19A150BCC6D8DACC1054BD7AB4C054D390FF8484861C8C4B823D3C3B11E31CB2E4DBBC7592CA95E983AEE58EF4B6CA6227A2D024BA7B383B3FA752D6C9BE8CC91E6905619EA17C0A1B24D2586E91E590BA51C1672442BC9C7AF0E6BECE484A3B96A4D76467BFE4B199D22646FB86C74864B39A60D8EC41E7B5ADC791C1FC563FF2E14CCB8228F1944CBF1AA2F4258D6FBC5EA7C46282D109B8A87CFDFC576D74263BE3C866311A2EBB1AD5628E14975EA8DA31B7622245330788C340E0B1094AD8C2A1A1BA14663D749013742235BBBB6045733E7E6519CD1C8593E1BAAD83A50003B73900BD69E6CDAEE53DB7A7684AFA3B4566375B693C1410AAB368015E12517CB04B3EB6B824767724EC7718A403E5E7178C01190C289811B716C79A846133243FF383EDE452F15B7912F0B763C08DE8D0A2C08B67B3B41F39B63BC7BB7601A0AC7FC03DD4A656DFC89179C34F05976BE42896FFB49759222F259895DD433ED73B4E77A715127A3876849E1B039CB8A71BA4F2CC640B93986974A46C15974B7EF3B3745C3893B5327848590AC2DC44B5E032591B2ACBB055F2D336ABC062A1EA11388432AB2A7E402A62A4AC1AC5503FFBCA57F2505A951C0EF2B2BFD36AC5E4A0AE116C189AAA95202CC280E08DFDE77952BC6566513878C4077BD45FDB87520478073501818D2271324820EA038F79059C871A1B19625FB60A9E7C806DBC444FA8261C1540C890D315B1BA2BC4857445A539AF555D6CE710AAC7B9DC15A149D1BB356B2321112C6C530A63A9AE1D1B59DACC92E9F919F990509E7A66DD41CDEDEB8252D692E3DAC47DB872EC36BC4513741E31A65376ABE99A6D82E6110E2A5ACF501E3B785088A4298639144560C6D07C3C39C9364CA56DAE571ABFB13BD805CFA19054E8403493F2CCE7121836D01A83561D734AAE163481EAF2CE8519BFBD6AAA1B29AD09F8705E8582ADE2774161A2F47B03B2C995EECB024622B287E84500369CE1A71C77483D1C30653A7657F953B0503192C97528B4D92856696D256BBA012BCFDBD8C3256C9969819268C40944A9015750CFC255411C196147470743609356E7CA800C2635615337B1383267BB339934C3F68DDA85BB582C7BD7131F6041BB21F14AA0B25DF46BCF1C6B42B1DB5B604C17EFD00F6B23C85A3C054C600F9C40C21D1810F6699BB8620146A4C2466CAB86B1659313290D9C182DA0555E417009B3AE20F6CF1FA128D86307CA75C0046C269DF20F0C98342F39AF8C00918F93550C668F9E6C4423F559350185494C5663AB81BCE72919521BAAA81680E19E38154C4E0809E64C184A9396E1DC813DE849D13A7D6922CB41B2346DAC86F06996F8A71D3FD09B44CA60233C9229750263E88C10264694AC305C7390E2B63D8076863865047C80088894916B54756278C6F9C0730F4ABACB129842D1610DB66892C52616F62CC3E26F93E22B736CA9F43C16D3826F5E324150416A8C554874D094493A135111AFA6D45CF1F58A7177B242FA9E9B185EEC54659C887005B702DB26A05CF53DCFAC6179342ABBB707EA449912D9021CDC5716BB469E00BAECF754CEA89B36EB6B1C130F5D439B4AD903F09752EFFA555F182FB1C578855A44D4F9048479AE4551B61D34048FF53D911A51C547999AF5AA76500FF4B8434F2043FB583E5FC5AF9C73584F5065F1E465A794490A1A296BC8BD43C647E4A3283B24C4BA3301B40C462DBC20F28BBB17C1A0706A5FA084268298899F0A0FA4D36C74952FBDCA323BB3ADDA17944CE5898B9027D876A457D066819AB43D32A9A04B2EE3378C23E6CBD25BB2B317767866406D374BCF327B1045CB96F656FAE8228295156CE26DC2770EF48322972668C5C746DEB4B57B37040E9AA732C79A238227723576EF822E95A6C80E6151F6523FE6DB352DDA9F7F613A3601B6D61719A21C3696E4C9F80500FC918D96F73135FA51010A83491B407571126D85002A60CCCCEB5393B459CB39B4DCF175B2134CF515C06B38CB0EA33D8C34A7283B99B6D0C9E90825159CBF4BC2A1C0F131580557F243184BBC7498B39266F669FC161150482DE480AB196BA61DC526F8A46A2AE3336A7ABCA9E2743FD654E965B3B33CA0B9CBC8C96095D78A971A7277496A8C123967E8C204765A864890B762D34E83570A8DEC5CD25333276555E7644EEB5CCF8004579C357481000AE9A930A7313468D3A8B6D5B4DA4A558A7C1318DA670DEC758C98C5048144843096C2B781D73A9F215C2CA0481EA5ACA259997C8479256841507717B7DD01CFE1755F8AC2BF1008C2C61B7BD13810787185CDF16A17C2CF00BAB7EAB737A641CC12EA6D8BC802E0661730628194C40A7865A3587CC2F5B0AC1D328307C55388970B96C4969A533E04B425E528C713D41821CA6CF1F5BC74E64859C49B914563AD193C626C6DC520143A755132260D5940C76E20A7F07987FA7C1A4D1283BD700C9759871F973FA6D94FD88015CFFB046555B36559420BCB98CE617169465770135B15612A9884586D0232D44606632C50A9D5BEB3697669C9940E1739508C360505248F501DBBBABF70E7CFFB24652B782DE5F4A310A7767826BC73886E60E51230068DCFDB2B3EF246F7701D65813E54D78DDBC34CC9BCA025914883364C60576A5E0C5A863A17A9872B818C070647170CC46F44880D4FF46D68C4694442433C823C0AB39656B715E0443E8EAB14A990C42A031EBEFA6CFD54C32FE4521E218396D53C5554C60B93CF2F1CBB0062C6101686E5738896621E44B32449C297D968B16C80AC7491279DAB0F84749842195AA3DABBADDC2457FC8B854752D33CB1A5499DD53725BF34BF34A68457E57E4B270FE0F07323275FB99B78AA90AF27480B6440217B01867A1B7A5A5885FBCB931C524395CB11A406A492C4251F9C09E14A45E2B86A98C72F1532664879A2D5557FE9DB6BCB2AB6197892E5686B2E1AB35A3434A77A65EBB6189AA00E19FBB045A03FB767866184C5C2E2B155F465BC7A135AB25CC5415B0A42AA17595A32E2A370317414913278C18837F346C3A54BE5722520315332B2B43ED4089B427CC8E24F10F17610E40882B4C724C48B6315AA6F0C64A4032E4BE75BB6B0702A2CB7A11CC6AA14BCCFE91AF25642513425CA475FD7E7C387214294A36FFF09BB1388A5322910B9906491BC923A2644259086BC5131E5D67794D91F65B24A0DA06CEEB63239456E6C3B1CF4FA04165879B5858BF60664AAEB45B3A238B1A926489A2D395473D3A5173FB37A51FCB5BA0C9CC3EB01DEBC383260B4F5033BEE258F66A504E64A74FAFCBD1A46076EA00A02246EAE52BA6591A8CED21B58971F289847C508768DBBA5AB1921C14982C9525AB4B64285723954D33C8A35396DB137C0DB48A39432DA0ABC3857C5369B236BC03EF562A8A5E4211986A385B8AB4D1745742411A9712256636E62976F99A72D75C654F8574737B6AD34C129A2EAC22FE166B2682840F7043D4339BF699B68D51ECC32974C161136272F9012219BAC6BFA8950C6016207DC6566D20B916974743290F0A52B8BE51C9F3C239E8B6842278417A05DC789BC43FA1EE0671A51BA3301246BA780AB71295CBD20ADA7A07E5593A3933604EF972A711349A0678A60D2AF2434B17EE940C067BD89496C90D4B9903B9D146A49C36138DABAA405499ECDC02F791562A5D446FB358702B2A5EAEC93B7F4756762B3C17B0E8D48CEB5D5244965168FD9C3E6495D1FD578BA2C168805897CD351202059B5A4B96687465741B077677583CA7411C4331583308DA00AB5045EC5943BEB2800B30978C31031675A84DBFCBE6D7B27B2DA65152C692FB8727A485B9641888B1B36A25491AC76045792278125B0A3735F3E759901507CA4A2AA12DCBCCF3C35C68873518A4FC778201F0B960C7B551F038C6201378EE101948629DAE0364E38AD079320D2CC35BFBC8AE7CC446526447D60B19A36519DAA8331A45F1E4308D564979A5179073130594CC5FC07A1FB6B5966277511544611E018F3F8B76567ADD2C94A0DA8502063C66C54C3A50644E43B81A93C7CF0409B505C77F5D06D34432BEC389A137B6FB9F18DA05426D03477FF0B8185327C37F449C8F6398680C78EF7D26C51BBA9665CF58B72CDFB115BCC2A0715B5B4F40DD01C7A0585BBAE739590CCA5E4B82099B66C7175C5F858851EACA730FD0C55EDF9AE451E07BD366D4C7E3A5FA1EC46B73F87AF48578132EB080AAA37D31F0C2A041C5948E59F44F9", + "ek" : "312A0170C8F103E9C7C3E5AE5E32BAA12E3E7AAA16D1BF40656F0A61D8B329BF88E9B58E94CCC5FB49A2ED8C3282F0BF95249B1FED0E42A0BAE41FD7166A184428AE07191B8100A90C1F3BD6EFC47571C18ED0FE23F1C41B49BF257D4FCAB1BA21C42B8A60596DAF01CC6D3E677C1C1D5FE07369D2B59C4B40FC2E134C7904EC0AF675AE427C737ABD68EDB16C2801BB3DBB011F5AC838A1047FB0C942B0E80F75D819B1B5461692D290702C7CFE68F3B09338A4FAF3909D26A3ED1F7991DEBEEF00F892E35D3C0F46CD11DA94788C50A71641C6C54BB8415FAECA8F3E16A1B7E28779971E587FEDEAC965B3FCFB49A696C8070397CD522C0A10B64D2E9583D33DB2FA8029384028AAAFE1CB23D0C293E795355C4838F2793C2E38DE7EE0919FB3BD7D4A130471749B7D5D3A9670EB2F72047EB7049A03B73D2E37FB1549C603557F6F120E3D33436EA94226C2F60AD088A125BD8F844DC1D814926E85F282630B67E71D580C2C3A2D8437C1A0F1B4DE465A0C776AEA8D2894E127360AC229695F700BCA00C2B448F1770DBFDFD18D65569E5D9FCD63E47354699DD0EA5704B3D9FD09D863DD59112E50A99CA0D3C34E16049688B65DA02DC14E688FD085F84C5ABC2EBC3823C07DFDEEC629D7B98A995CB780CA6C7B014FFAE0DBDB523312CA2FA0A93B75F97EF53FB9F35226A16925DC6D4E5685696978AB952EDD249B44E878C939A442AB9F7E2C3A463DCAB92F9982D47F3D8F0B7D54BD682BB8336397076F9065A052527D9FDF63CE41F080E46367D97C0E131E42EBBDAD0F9A4CD097423E7083CE1442481ED69134A6EEF1A809D8244BA33D9C09F8A6DC0AC49AB3B5E285F764D829972F97FA2727F897A8434369E14A46E53BD2C765F8774B04C490F7AC15638181914249786E9407DB3941ECE2C69DCF72424FA4BB274CA1E40D60FF4BDABBFCC08E3C77EE0EE4F7EABEB1B5B06A89F762285BAB6042AAC34FA44F41F02295BB9F8E3D5667758DEF57CF8BCCF9AA43D3401C9A88A16B12375E1F139CD1F84AF59AFCEF87FBCB5AEAC7DEA48E4D6CE17136EEE75822A4F8C9408DBDF0BD6B71A1E383E56FEC3855C6A0BF7E09C1D0180115E6BE66F1F71D8A33B468826E38D3B5849714B45746A2DBE81D51C6D07F2F42EF09E6A4A857AA4903FC45E8C5FE6B8EBB8BBD34E8F787B1BFED557168DAE415BEAA7E95E669336AC9ADB07572DF014E6A95221CE246B7D86522FCB75044563AD98F52B54CAB59DA3F2190BA554DB2ABE5F67825033D33DD8D7FAD1025729307BEDA55F8D3674286F4E7CF132A52E20CF7433A0DB04CF6E5F156B11566CC20160BD67FBE92BB2DA68B1D0A2D2DE9746D4116CCAF64EC9E00CCDB8AC2FD64B5708ABEC5010B5236E702AFAC19389B512CDADE0566C5B09B6D3C5C3654323821C8A421853A2BCE04E0D03F0FF909181F4D9798547DC98CA05A9B83133F3571A8E143A7DAE47243A94FA31F04FA6C48EDAFC05AC0F589A7979E51A648C2A99FC00A124BAAA72B19B391C1CFC7BD3686C39A83D9C58876FB71758CCCE5D3991DC597D3E77E81767E9BC0B288C8F7895CEE8E752C22DA1370A1CD8CA158179139AEF83E5BDFA3AB6960BDF6D027C218440DBDE3F163024C6BC586E4F356C0E8AA5FE929E1237062D0FE5FB8A0EC46A8EBA6911C9944903C2A21B4DF3A2AC32AE39AB78E625B958EEA15D9A69522021604A980396F2736C2AA5794EC178E744098FD6B30832F195E28A7F190079E7787341F6C5218F3C2E2E3E3ADC1519630C500DB4CE8C04711CD7088112778F66EC672099855DDC2A0CD6BFD4362CE6FD1B990CA9257071718AC1F05145753B13BA510A63E6DE47F0361E74445EDCD626C9DA4A41A1166EE2B1DA414EF363A3E6B9EB64A39305882ED4A6E7F4741B570A2F36295098F8654ACD77AE3C0251143A400877111E96B6CB33A7D344E564E2E2DC61619EC80DAE6BA7D79A404C3C3AD530057D2EB1953A6FAC4EC430F64ACEAD994263AD863FF29C990E13E5CB68BBE0825DFB604B93B6BB59E1BE02BCFBBD281CD6822B8BE7A312CAF90DB281AF1C0638695F17FFC3CEB92C5ADCDE74B034134D8BFA2A39A479CB2DF729ED5E4572239D577E56EF41253A640F732D17C266B67BA57297CE8BEC647925D1D7ACC3AE5EC28F7C9A3EBE32C23DDE0E342F0EE6DDBA1DD94364AF8A93DAAD47ED7307FC21E", + "k" : "F361A627E1E3E72888A6E67736292ECC6A2F74BBD9C60F24A95D204D6E2538BD", +}, +{ + "rngSeed" : "027C3D5847ED4470931141104F25B19AE76117CBB64B224EE424FFB782E9A0E988839E0BDED0DF666FE8E5FCBB5DBC09", + "pk" : "3B37800C878B5ADBBAEF794F4F24ABFEAA40EB1C5763FA55B7369E5BE8754BEBA6BE9319CC3A482A53BA93C417BC9A5A3030CB2A247177EB11B63A672E0039FE71735CA9CEA99168D1634DF2737B45324034492E1D3C74F10239564B23E39585734C86D98118DBC944DEC28869CA8BE7E17B39BCB0B0E34E257BC9BA42CC782078945094EB1336E516C62B00871D12C6019700B478B5DB43AC419B2C7A50442D9458BA4B853D5A29CA946D64B6A6E6CB3485439ABD4A9CF34B5921242DDF3611289A72EFAC4101B208CB7598894A9EF1EC38E34A58B2C071B3E6738138BBAF416F246072EAD83B354A0832B98B551B7210095FE9323E1F75BB99905E5BD961CD778D32C1BE94512A7893C062F6A66553152D1C820B8825C25938C0348A3D2206897AB903E6472193B5C2AA3F1BFB22BCE88BF3723EAA8292D5446546865218D5827A5BA0DA5354E2F6C81EB96CF0F28EFAE54935138273447A953AADF9757319E03A6AD19D7E613C2CDC7F5A3AA1891368399AB5C5337881C782BEC48F9161774686204027B6FD895ED1B800DB68C2D9D529156B0A8DB90F107964D8F5C860737DB2A3375DF20B7BBC7F1EA57AB6E2A2EB44B5F8E6980D5233A0791350F4AC23210A4BBAA928273294691B7C441EDAC04909472E8F6714E99BB7DE1076A121576EEB1D419122D4366023BB2FD66937ED940566AB07D7B480B330937C341106C3BC01F3C26EB7388CE7404222BCCD7CC42E8A56909239A2968F2DA3CEA3C6695CBC909EE481B4C619F1E7AE6750B4D8F691D70490134BA02CFC97327C9F14DB4BBFCA7B4589431E0B8FB8DC61658110DCB675DD1BB46DB49605C66534CA53D918AEE579557E82C733A3841A7338F9947D92D4379B3A2D47469166BBC20ECC4DE2F7C768A0BA4DD788CEBAC30ECCBDFA11CCBFF61328F92739E12160B83369D8466421374380A1A2C8BFD701A869B49D09644266D300493BADFF092390E894102028768A4592E96306130550291ECDAAB48C711E8A1822CD278B80357856A739174B3DA66795FA8375333554FC92298DD92B3C962BAD035424F418B9B626D32B5383005564B8CBAD0915A977B1C95710AE490BFD158A2C780E14C85EF92A02A2601C3538C1297772D1045BC4811E4E7893310413B4121201EBA6C4DB8658378FA3A6B9B919C9247C40EF39A7D564BF13A6C8EC575FC3B58F42426AE1A4944CD638BCF8336504577C65A7B75B06649802BF898FC3337EA3F783BD58BC85E33C51C91412C09D99C310AB9802DDEB4E977A640EB05A6E01984186B62F3237230B33CC4721D984382D003A4472496C163A0C23AA7527A7A98B45260794C109C3EF645FD352B778F06C6DE40AE1AAC577698EDC053E951931E88B75619A2E3A795D9D7A015FC39978BA6832DA41DFC1AA36D53351321107D33D00D934CE079F53C1AD114B622EF09FDB70888A861E8B9334610A9C2A5614325B9265219DADFB7EEC92B472C87C0F0181E73C580B9CA8564BC1E3B9B70528A30D0C54BBF48B3001C46B536C51E15C4D0844FE81BC035351D919212C699A455B7F0900121A77360F4AAF09443E9031BA9286C0EF18A72A0C6AFB2B380452379FC14DDE6A20CAE7C703B8C367BBBF4EA43DF773BD6A3A4C051CAEEB66A236244F7BF5A837731655A73BF6E7A3413459CBAC0DDE329E59FC9521FC2009E480D82711496A5871F33D0378223243137486504A209D9012574B10561FC04DEED84999BAA3A936A9B1234AC4C4AFE451042F828CF40C49E632C6153684448154A023684AF08CE13B204AC025991C5E44B63201073F22A50C935B9BC1C488AA8A704BC178AB0A752595CFE050B341A295F9B851B67A3C09010ECF297791C746BA9247DF2A1BE5A82CC8F904E1553B31D53710B0B0B7372B8E9C0B7C15636097316D46587E07753BA05E03F7CB3C6C78870A7AB21CA99DB30217245A29FCCC3ED80364EC661EA93194D472813A3CB0203B223B909C5774F2DCA50E8A9753E36C33D92C278A52122A72FE389F0F962CE5D3A1D9F5C07000919E4761A07282E016854579B1C2E7C608630C6B2A6A1BD96C71392B9EF15E04F7BCEE414CF5D9A6FF701C4D2586506248F4BB6BD4EA4A45FA79FD92AECDECBF20D7AD8534673832A0D6CA13C561A446AAA23539624487767E4A195DCE0E2BC6A3FD1A73E918F297AA031FCD8C14925529ED33B83AE8E7AB", + "sk" : "EA9B6CF63A18D0045A6AAC4003930BD833A2109BC026CAA6B9A38261ECB70F9992EE3A47BB4335EB80314E699734098178C25F924444714A9348B980AC7699111856623C9D9F2B4F7DA5CFD47970A149C3BB882F84146E7B8562A549AD16E447A7C154B2ECCB38020B44C6119CE9663D34A646D6C31CF296F5B65CCB055CADA93C272AC018902C1EC93C907BAC9B7790CF5B2C129738E573C5D84734AE095801863B654B740FC216EDD2064C230E6266454D064ADC932428E6944C2A7951268F4310209CDBA48262036921BBD35C71D8728E46B291F9E865873316D9C0525C702841C3ACF3252BB36020D18238D36B245C08AC1E8A28B75C5B29A810D3C6087ED058CEA97AADC75F28BC92BFF3614DC04C825716F79B363E971EC215974277C02277322C1471959CA699AAB4662ACC7FB62120896B14A3A25151280E7741BDEA18E32A72F0B267FFC7B2108094E1378B169093C007C0769213E28B9249ACC9B2ACB5F8E7972FFA629A5B40FBC9773E921354B31BAD947C45D079DA092B5C4B7C094573D1DA2D378C8708D98E55061B9281C2FEEBBCB62A99B0C6A05291345B731788E6879DE89D9756A8795839318249849BCF7E432D622A319E57C0A982A2E034BE75771F06917A3193564C3231590C74EAE7638449989F703C6A664736823E039A571431535AF0211A1931177A4761E022BD925F76913C522B128FA54EA1A04A1F2196508A2D65106950437F13D463F1652691AB919D62118CE743440B273217ACB03CCD67E16CF85265B67C8EE56A4CD757C860372EC1F01D7E61AACFC55F072423ABCCA70834B550A4BC8228BE40BC08E723B37FE945F66018B6F4808257607A9612F9577D6BD86FCB3C149EDCB7D8D28CB5FA63B72A41D42471A0F8B014F8315E1AB6A894B2DC70C71F782C00E52C3F1534D46C83B2D2BBF4B0258C919307E9470E8027E5B261BC36C33511299E1A990AC68B6A735C3CB39BAF03AF5B4206601A7A6C24011FD56A965190B0B675D33381E5320D03DBCDCF684F782CBC2B80791E00A0B27913001796ED9BAEAB103BDFE2CDDCCCB0395B441D72746B5C13470408530460B473466D6B8F69AC8518A3B26C9CA22D077A31A3640538CABBFC852D3159FC26730FC5AF89C5B5200A7636E56F74F99953886F80B77F6E22055D51048CB4122BD525710A4EC272628CB50CE549342C314E81253E0CB2BE1D779B82462085829BB2CCCE74290E2018BA51D1CD08F00FE0870254F4A73FC637D0F5C6D8F56CA376690265C4B7773BDBAA0B08880DA2D82E79C87402C38BD60A4C07E219AA30B3566B78DED73683FC1DBAC43D033559E81364F8A0CAE5096243F15B7BBC3BF7CC061FD2921B12A5FEAB37C8B402FF97718FAA1FFE69122A658804310D9BA4555977B2CB5A97E14AC626FC4770FCC8C325B4E03472F8E62AE7C37918A48F6ECB15C0A01AE920A84B4B7113A74BBD39BD3318C2361401F1C15FB95875FFC55BCE76C77C3563D302A2794B92DC800CF9F38C5809C29B4B7E0E38C340E458BB00B44D7A11594A87CA96BAB666277970B569E5C21F574563DA3DD139CCAFAA29F8A79578A7AFB0930BE8F8914A17415EBCAF14D13F5A4037A960C70884B43C066698CB4A004AA9E32A4B1150A98B708E185A5B4BA09E4678290D33C13C14137A2B61E19495587190D34A2ED82AA0F9861B04E51344E4CB0EB60BAD5010D635C4811006A130470459262D028FA6C383417AB81586AE5CDBA777071D687C99DC9AB4AD21692D70679E0C4DAE3B1243294146D6BC1BB4B8D6B6A3E8DA24A27C62961CCEF556359A9486DB3642102C0C129224B2C035792649923010152C1503E797635905DC442DB389ACF6C30219E3A25538AE1E696B74576FA7997177343914F45954728499B3CC26C768A3D476EBD7120B336BAEB4C65B72C8518357776C774CF48996D6AD205C092C9791E55C727BAC7E916A2BBCF994C5F9C4330976B1743894DC024DBA7997E33EFD944405844C01235D4308C09A75548B43555A8A6EA0D212F5DA6C8427862873149CB6C3CE7A07EA39AF30E7A7505CAF30762798E84BC7E965EF96C51899341567C1324B6B07A984CBE7AA6B56CD52702FB106B1CDDAA02D50362CD12737308E3E93A45C9C0A3420C4B71167D9587A4B2188B6CA993B37800C878B5ADBBAEF794F4F24ABFEAA40EB1C5763FA55B7369E5BE8754BEBA6BE9319CC3A482A53BA93C417BC9A5A3030CB2A247177EB11B63A672E0039FE71735CA9CEA99168D1634DF2737B45324034492E1D3C74F10239564B23E39585734C86D98118DBC944DEC28869CA8BE7E17B39BCB0B0E34E257BC9BA42CC782078945094EB1336E516C62B00871D12C6019700B478B5DB43AC419B2C7A50442D9458BA4B853D5A29CA946D64B6A6E6CB3485439ABD4A9CF34B5921242DDF3611289A72EFAC4101B208CB7598894A9EF1EC38E34A58B2C071B3E6738138BBAF416F246072EAD83B354A0832B98B551B7210095FE9323E1F75BB99905E5BD961CD778D32C1BE94512A7893C062F6A66553152D1C820B8825C25938C0348A3D2206897AB903E6472193B5C2AA3F1BFB22BCE88BF3723EAA8292D5446546865218D5827A5BA0DA5354E2F6C81EB96CF0F28EFAE54935138273447A953AADF9757319E03A6AD19D7E613C2CDC7F5A3AA1891368399AB5C5337881C782BEC48F9161774686204027B6FD895ED1B800DB68C2D9D529156B0A8DB90F107964D8F5C860737DB2A3375DF20B7BBC7F1EA57AB6E2A2EB44B5F8E6980D5233A0791350F4AC23210A4BBAA928273294691B7C441EDAC04909472E8F6714E99BB7DE1076A121576EEB1D419122D4366023BB2FD66937ED940566AB07D7B480B330937C341106C3BC01F3C26EB7388CE7404222BCCD7CC42E8A56909239A2968F2DA3CEA3C6695CBC909EE481B4C619F1E7AE6750B4D8F691D70490134BA02CFC97327C9F14DB4BBFCA7B4589431E0B8FB8DC61658110DCB675DD1BB46DB49605C66534CA53D918AEE579557E82C733A3841A7338F9947D92D4379B3A2D47469166BBC20ECC4DE2F7C768A0BA4DD788CEBAC30ECCBDFA11CCBFF61328F92739E12160B83369D8466421374380A1A2C8BFD701A869B49D09644266D300493BADFF092390E894102028768A4592E96306130550291ECDAAB48C711E8A1822CD278B80357856A739174B3DA66795FA8375333554FC92298DD92B3C962BAD035424F418B9B626D32B5383005564B8CBAD0915A977B1C95710AE490BFD158A2C780E14C85EF92A02A2601C3538C1297772D1045BC4811E4E7893310413B4121201EBA6C4DB8658378FA3A6B9B919C9247C40EF39A7D564BF13A6C8EC575FC3B58F42426AE1A4944CD638BCF8336504577C65A7B75B06649802BF898FC3337EA3F783BD58BC85E33C51C91412C09D99C310AB9802DDEB4E977A640EB05A6E01984186B62F3237230B33CC4721D984382D003A4472496C163A0C23AA7527A7A98B45260794C109C3EF645FD352B778F06C6DE40AE1AAC577698EDC053E951931E88B75619A2E3A795D9D7A015FC39978BA6832DA41DFC1AA36D53351321107D33D00D934CE079F53C1AD114B622EF09FDB70888A861E8B9334610A9C2A5614325B9265219DADFB7EEC92B472C87C0F0181E73C580B9CA8564BC1E3B9B70528A30D0C54BBF48B3001C46B536C51E15C4D0844FE81BC035351D919212C699A455B7F0900121A77360F4AAF09443E9031BA9286C0EF18A72A0C6AFB2B380452379FC14DDE6A20CAE7C703B8C367BBBF4EA43DF773BD6A3A4C051CAEEB66A236244F7BF5A837731655A73BF6E7A3413459CBAC0DDE329E59FC9521FC2009E480D82711496A5871F33D0378223243137486504A209D9012574B10561FC04DEED84999BAA3A936A9B1234AC4C4AFE451042F828CF40C49E632C6153684448154A023684AF08CE13B204AC025991C5E44B63201073F22A50C935B9BC1C488AA8A704BC178AB0A752595CFE050B341A295F9B851B67A3C09010ECF297791C746BA9247DF2A1BE5A82CC8F904E1553B31D53710B0B0B7372B8E9C0B7C15636097316D46587E07753BA05E03F7CB3C6C78870A7AB21CA99DB30217245A29FCCC3ED80364EC661EA93194D472813A3CB0203B223B909C5774F2DCA50E8A9753E36C33D92C278A52122A72FE389F0F962CE5D3A1D9F5C07000919E4761A07282E016854579B1C2E7C608630C6B2A6A1BD96C71392B9EF15E04F7BCEE414CF5D9A6FF701C4D2586506248F4BB6BD4EA4A45FA79FD92AECDECBF20D7AD8534673832A0D6CA13C561A446AAA23539624487767E4A195DCE0E2BC6A3FD1A73E918F297AA031FCD8C14925529ED33B83AE8E7AB9B3999082BE47443720BF6B573A95207D1EEE1B3BE613A1985B3D6F48DC648786CF04CA090E5805FE0FFEDD6BE0F254397155A7639C5AFBB30A7A75CFEBFF026", + "ek" : "DF624F03A9E2B0F6CD74A929DDDBE8778E66765435C257E9B29C0056E018448ADD704FEB7C6EA2255C2228B16BCF33385C1D7F57723B40FFF734BC173C0DCB466176E7CCD66FCA5D54FE44C8603168F66908C14A3AF730C765847D5B4470F0853253F39453287A5A81A948647F33E614EC091A736FBE47565D2277F0485A29B9C17A473142FC89FB381D748AA781A4407FCCBB0F24DE0D00927FF59782BBF056B070B067C86964883707D521B39AA85E3410D4E37FD49619DE28D68188A9966EA07D34768925EBCEE9C54FB75C78669DFC0EC14E1E2C83AF00B074263F561B0405A513E5CBB57CF8FE103AD20DD7E7D3034484266974EAE489D25DCE7EF813E8911DEA857717CEA2D382A34C96DE4A14A3FBAF7F6F74D3CC363FA378DBAC6DE99972E53966496131C52C9B655B95E507FFF74DC4C89AE390FC53AE050AFF4714C4FAB87D9E81273D756CADABC8AD2864D082545719F280DBCE272980D8FFB29A634E06ED5D7114B6B093DEDFE81497422E49CB57F9DB2905F38C553F63F8084EF11E944A4772A83D1F6CD89F69189C3087CD615990833308A4363F80931F7B1A011E0A2C57697590916A5D9E559D942297ED0D493A33C102409A3929FE3DD26F4B9938FAB80319CFD109392E2AEF2EB53D3944271813F7B8FEDAE786C8E159A194C3FB7E4230E0A5F240495290C69143C78772ED390DE875B584B1558722801EC11711785559E887EE3F47EB2C5DD609A11874107F8D8B75683083B67DBB7C79985C604C6B10E229DB91E49293AC74068DAB0EE69295FA195C16AB49B6EF1E646923297D44DF6A3CC2934EC99479F2E6B28CB2E88EE1CC4D79C26C7B44EB01F022314A05A8F384211C4FBFE20B99C99A302CAAD1150F879E059A7B47948007F2CFBA2FA5A65427E026B3A38DEDAD8F0DDCBEC4FCA3D51BCDA5C38A164FB543B6D4E363FC1B4794DA90CF9BA3E9C3A69B670EA86E1BE1A43D416EA880F53764CF24F73C5998DC3972DBD4E08A91BFB890CA8652633C247FB12DFC6C8B2B04ABAA3051479727D322F003EA1FD0DB0BC19D2D42FD938F7E84D01DE0F3A7DDB78C13FE9AE3AADC806789C9923307CAA2EF9AE66FD02DF60405B38DB55B0C512A7E8C85434DE1E6BD4592C7A67E480E32DE16A112E9AE12E5F1DC63A8D4524B23C99F677B521B78ABA2F597D19085A5560F08E089A9099C97D32056C01B8EE93344B44F084DF61E609358AB90264DAFFF05003DBE9E02FE0E5FDCB5F1D29F97177F6B6D64D94B28CDF1C21F9F0AD956D76EABDF30F29ABFB1A18D1A3DD771DDD16DB669B32858D37D55AB73B97CE93D9631C2CFACF1B4FEE1FB04B6DDB2A1DC8A82D598BAFA2894956003477732FE8FD32C19243EF76459D8054EA78DA57C1DFC343963469AD481579BAFE33AE1F7CF9EB1E58608AFA70D29E3A3D07B2F7A3C3CFBE5DADDC31B6480ADC2B9EFD7A2E17E0F542706AA6124E65472DD66FA172AB2C41C7F3CD7B2622C060110DA84E93ECD2D805C4C613962A079ECDB89F5F40FD27E9DD6B96F0BA8398122949A73D14F8AE0C2DF1577D8FB8EBFA692130ED0C8DDC5099F58922FB19579A1A7BC8CD5C61FA39A40B2B8A860B099DAD514B67100D0BD50C8CEAC7CEF07AB89C1683B2426A1843BB4D7AB161AA9DF62C99BCBA8298AD1BFD14F676A9CF6F3A1E39E501203CAF9FFBA4E5151137DA844F8F041164B6C9ED52615326E60B6B0F157D2DA93DC8525B52CB022382822B252F9DAA64989F3AFF99586989E0EB2D5F19109E0FAC62C48EC9BF511E85946583C6B29646BA5F280BE206532D5646B3874610AD2AA15B56A7AD49BC0633232CFB135D3F3797C83EE60DC373E9B1D12DA8B1F5E3B455A47F6F32035C6FBDC14A0546583A8D18AC99524B60AD4F7DBB42C8FD68104A77321E7416A548E6DFEF1B25384684CDD2563F8EC8708F8477C0D05E11012D84AEC940DE0EE5F4B6C52257D8AEE7D1853B247DE8360FEEA19F69B028AC18AEAF0090ABDA5E5F28AD197F622B5F3F4736816101E13DC1E5D8E0F09CB474E61683EC714D7FE10A86ADEDA7B0E9E45D98A30218ED9C07474C2592E53A5169E1DBE7F336A2B204257D9BE09C98DBD3F8DE846D380AE747DDB4F4D69ACBD59A98539202180124439CAB2E924792AE72B608571957691BBA87CB61FA73198028AD46383D3BFC9CF90C3BFBAA8F6D184B5C5AF4CE56EFCBF", + "k" : "0B2EE305C7D958CD08C2AE05E6B7230E28154A22BE0A8A183DF52607163224FB", +}, +{ + "rngSeed" : "450751D4401737459C6D93E6C5F2FBCC4A3AF7CD7250CCF404BBB817A67BAB7B4C9D0EF4570BFE25CF919DA331C31D88", + "pk" : "96886AEA374A0C4886E4185A5AD8CA7F1A7DF73C6AF1282397A6A9B94C95C8284A0D65C3E614CC73159FD71BBD699006D1B97DA241C470AA28113A24EEF9856ECBC3619BBDBC25BF1691A241414CC3A816433C6D9466037CCA4DCCE8851AA9A182FA9E7ECC47E42713E9F81189CB5B68B52389095544427321AC5BB12000371A1E1CD96B585223EAA02218543C6F32A777D79C3DE28D13DBA32818CE41D13E2EABBC3C1223EAE799057C43A2977ECFF4A5966A7E52D0554A8907CC39495FA80339160FCE96742FE5679CD4C4648910AE0715A9899530723BE9B551E404B88A1C272E72B1B3E56144A4974DF799EEB20170862305E647951645DE729DA99BB4FE579309D4ABEAC03EA4D029990B3FA8464F82E4472125BFB98837E275508D161DDE593B490461E6508276B344BB18B93CC3C965E084DF68A68AF14E6BF37B4DCA585D0621A4F32263ABAB1684CE0B1A5FEF971E8FE18928D38477572E55596E35AB6270880C2E6ABD0EE9080E75850155273AA38C0BF588E02006F5837C01063360773FF79376A72380D9E123B199B561007F1873A4DDB715ABC93D95C7A8549407EC94CD0B928B30E3CDB15804CAD99AB2202005675E68EC6F71F70082139B42E5BF02ABCD4A4988EE0A16415A095EC8B94D2431070A710D72A596E30ED4588FDE91670F3AB70F35A5F0870E86927D68F641FAA10F962941E0026908EA7D27084261D190CB62B4354A1C8F06AB864031341637929B1274A1C97BD62208E681F3A96333871C41916B03E668D7559FC0A67DECEB0D2F818F45D82A9E4A679D76436BCBC45F1C971E966A6CFBB4E1948F2E4B0620A28D633B78951812FA15C4696A7BB17A9DDEC0329E927AA1294E5B7974BBC7008A977E0E13500337CD62B281BF73920F02B19C357EB57B3C575265F1E73A16B455AF856826F29BE11049A7005D9AA401AFF512E8F8210F296FE64BA0EE77B1734BAE34000B85C609D8BCB39260690CA9B82E105746ACC35FC49BA6D1461A748206361EC179990C1B2EC71387B51C1C7ED344B816008C384EBA96432ED66FE4E7225C0047E2B2979BC359A891B258A2CD40BA3694086489088B42452682518EC4C1BF8B56B91519C8D02395E726AD48696D5A2809D7F3021539BBDB38BB11E823CBEA2E7273742C87776457A1804B89D524ACFCB39E19FA454753908813815349A872E131A5FC91C51579B3A50E9142955AC575A8A528FFB35A77A6347F119AE0FAB07701CD4166A0144963AD69268BACBFDCA7BB18305EFD006E44F812D063B0B7E8B1FD75B5B1662A49E26324F89415A51FBEA41B75485C53B661C97AB2B9E193D6F1067F518E8522A73447AA1BE8AF9CD722EB8653E1837279C5194EB21BC9127F1EBA895F9924A254C6B38CAA0907018197A771D531A506713D3434C23A3A2B996B7E11C83B97058AF811E974819DA2147A473686869F4D04BFCB9786A0F9723DC67E70E4AC0F565B85F4BB30EBCE82B21950838A2102805550C9FC1607AB93A7E42A0C9E79611FA7829BEB0254050EE730792E73975A7B38BB718AC65064ED7090471658657123E7823631E802142AA563771BC6975CE2722F0E012F555C3F021A7FEDF78F51020935D01A92362DFF154DAAFBC4AB6C8D32D2A11525A474757C690B21274B443B58458B83766DF851D95214DD04BC0AF73679249CDE1055E1977559D26B3BB60BB306503879B7FBF0B2EB2508AEF52049F43ADF6275D4DB027B6477D6479CFBBA91AE0ABF1DC8126FC962CE9921DA1B0005A09C30B6894EF6B3FF79A0C088BD2D6074988CA824AA18B887073A10C7F21982F802204C220756C0BDF59BA855A63A026125BD5C677DB08368B475B52C3559C3031EA56040B9590F859F6C2560F9170F5FA759068678B9E22888671CB0A693E825BAFBDA853C0B56B79A63AA198710B6246A4AA58B226086416D3ED82C412B282CF38C71348B40EAB105BA23B2F3720EBAA6F21C9F7B23C4E324C4C3A821DE7957C21183FB48C4C127732AB169F822C3003A803AABA857C6B92BB22D8C10251EE1A6838B18C650CD5B8304F886240E16C8CF4A74F14938A21A8F3E87BCA0351DACA3A8D5C014037CA5665A2589EB7EC6F29D18D891C0CAC822792B3408617166B55CB1182341A309F86F99F86B4E7C54E6C2BCD15B15B091274F185CBF5AA7A7A8CE437ADC43DE798498003691147635E787EE", + "sk" : "09E4C3AC7C3E706AC8EB1A3C09ECC4C26A683A3B0141298052E81871D820B931A79E4A3292550098C93BE9AC0D9539641825928D8398C1C5082550489E1AA671B936BFAC883E23CE83B24122A28B20B5908B4C5D65E4C8322BCAE55755892C8896D9AD6C4B78F1D616AA37C61F3B117CA77643FC65D74746B1110C6A0C6ABEC7131F79C62A5B90D6CA21139682165AC043D063B0D4644EDCBC9746C498A55D2CCC1121996CD82769C9F388E2C37E7EA3B5E4E76DA12C4121AB1AA40A5B8A045E5EF767BA1B2DA22847424049E73AC213F7333A9664B836ABB08650E1370D4E3693898A802896300BFA14ED3B62C8156F76F6C5573946754C95E238136F33709800C589C38E76D76D946581C554AA5D608D613B2756963A3CF512D823AFD6D4AFD428601A1C5C7DE8C58D3727B8BBCD7A704B2B33B161536AFFC498E5D6AE2D1C9A3F9823DBB32664D36242185C6DA03C11FB5E21905DD374641B569BA4D3096AC5833FAA0641D40DED086973A49413D8596EA97C76F4838C37824DB6C8B4310311501CFDE747B4130C916927FCE26777F7978F2A0A3C89C93439CA7E00121C5B2074F775ACFC4239B0458038C90D71B45F83899C7B20BD91B1C697A12EB958F1618A2B8C5BF1A8B1FC765C7346B53F2C8DD311CBB8985D93E9184DD73ECA6036B1A73ABB38505744001260C21F123FB950CC550563C2E5240AF922C5CAA5DFDA1AFA84B23AE8420960ACE7224954DC08001513ED63A4896C96F45824504341F8B8B84CB2979947A923E3883EEB3CE2F06FF38A7247504C8E1C6AD0B014836001E12705534847A676B2C824C04D71467A58CECFA97672069DF0376DB8C23D1400CE62F1A0C3A258B763A58077A1FA01510A8071DD939AC1183E3BF22F880B5102878B1317A67A874D8E211AEC3A3ADC921272E756EC16B4694C2E398798F2CA8D7A668AC51711329B30483828F41B2EFDB9823A957D601381D2E86AB2502680F1004D67887A890336B218B2940EB60262F6C1593B500F45D18D2F081B5A956EF5B1817250452D87128EF0126B98302EBC3DAC33780E260B61F30CB5C81BC6A54FCB362A64F804506C79922893E889BD6C22C16A9018B9A522749950BD5AC6129126DFB2409BD512F5106E3E757F749A5EFEF79A5949096B47686386159A47AE22456257093F27455C402574FFE725B59A7AFE89B036E34E6190928C70B15F525DAEB69C71A08F1F611DC84748CE219FA38B89B06A15F576885EA73A4F773932EA14823C404F2004C056BBF6463268A1A6192443DD06B92C8CB0D11BC9F0029D6B4C9B44304CEC028C6E46BA3248B7F2912A1854A1A90229402035F1519535E53777A494E5DA9CE02195D7646CA2993B38C409F6CB3C9BAA7F461BAC9A877CDA431E1B5244ADE7351274BC69353437F4CC9641111AB74E07A734B1F0BE390B3421A598AB91770587AF7F16CD043990D0D73AF2E861B0F216B53865D42C8E8E1BAA52735F684248F14B8020461D974C2F79BBAB12D0717CF08D72C9A9F8F1C60B4C01362CB4C16620B6AC5604661728781E1F51CBFB7CABC24243235C1DCC19394BCB115BC2A2E6443527F7C446A3AC04C58DE930B5F19A9BDBB34C61C3C79A2BA4760173CB55C5171908AEA5C1E6860CA1898F51174C7FF50D92E87D989A36DA409DB602AC0EB8BF13655EA8E9B46956B9B80A4E97918623469D081214971B4B32C34C5BD9BC5D299EEFF97629A0C8E935816E1532853952AE007A6E9224839169BFF49493C13A5842AAA5B32D9257C30BF36D53870BEF195DEE5819E185A5DB768E950986CA8092CA371863B442DB96B62877BBDA7179D5C009A9626C6C8537A114CCB571C714644BDC9449D070BD9B35078FD71E862AA59D57630B0B3F0B17361A05ABA7B906F3D66C2A1C52DA0135742C40501A15F4B269C66683038B4BCC9AA5FAE69EDBD765E8CC34C5B31F0F56008A04C137F9507096C1A173466A8B496E1C7165CB9631E0B039EA8BFD55374D674A9D2BA84DD29CD200600FF374FE128A8EE4AB3B824126EC3450367784D936EF927E4339CD05FC013D57341AC63530C8808FF734531C5E802161BAA0697BB9B8F2545E36A2155958AF41D4BC95E27A8ED5BC5A24386FB73CE97B628D972EEC7703575C598B7A95F36C89586474CD413396886AEA374A0C4886E4185A5AD8CA7F1A7DF73C6AF1282397A6A9B94C95C8284A0D65C3E614CC73159FD71BBD699006D1B97DA241C470AA28113A24EEF9856ECBC3619BBDBC25BF1691A241414CC3A816433C6D9466037CCA4DCCE8851AA9A182FA9E7ECC47E42713E9F81189CB5B68B52389095544427321AC5BB12000371A1E1CD96B585223EAA02218543C6F32A777D79C3DE28D13DBA32818CE41D13E2EABBC3C1223EAE799057C43A2977ECFF4A5966A7E52D0554A8907CC39495FA80339160FCE96742FE5679CD4C4648910AE0715A9899530723BE9B551E404B88A1C272E72B1B3E56144A4974DF799EEB20170862305E647951645DE729DA99BB4FE579309D4ABEAC03EA4D029990B3FA8464F82E4472125BFB98837E275508D161DDE593B490461E6508276B344BB18B93CC3C965E084DF68A68AF14E6BF37B4DCA585D0621A4F32263ABAB1684CE0B1A5FEF971E8FE18928D38477572E55596E35AB6270880C2E6ABD0EE9080E75850155273AA38C0BF588E02006F5837C01063360773FF79376A72380D9E123B199B561007F1873A4DDB715ABC93D95C7A8549407EC94CD0B928B30E3CDB15804CAD99AB2202005675E68EC6F71F70082139B42E5BF02ABCD4A4988EE0A16415A095EC8B94D2431070A710D72A596E30ED4588FDE91670F3AB70F35A5F0870E86927D68F641FAA10F962941E0026908EA7D27084261D190CB62B4354A1C8F06AB864031341637929B1274A1C97BD62208E681F3A96333871C41916B03E668D7559FC0A67DECEB0D2F818F45D82A9E4A679D76436BCBC45F1C971E966A6CFBB4E1948F2E4B0620A28D633B78951812FA15C4696A7BB17A9DDEC0329E927AA1294E5B7974BBC7008A977E0E13500337CD62B281BF73920F02B19C357EB57B3C575265F1E73A16B455AF856826F29BE11049A7005D9AA401AFF512E8F8210F296FE64BA0EE77B1734BAE34000B85C609D8BCB39260690CA9B82E105746ACC35FC49BA6D1461A748206361EC179990C1B2EC71387B51C1C7ED344B816008C384EBA96432ED66FE4E7225C0047E2B2979BC359A891B258A2CD40BA3694086489088B42452682518EC4C1BF8B56B91519C8D02395E726AD48696D5A2809D7F3021539BBDB38BB11E823CBEA2E7273742C87776457A1804B89D524ACFCB39E19FA454753908813815349A872E131A5FC91C51579B3A50E9142955AC575A8A528FFB35A77A6347F119AE0FAB07701CD4166A0144963AD69268BACBFDCA7BB18305EFD006E44F812D063B0B7E8B1FD75B5B1662A49E26324F89415A51FBEA41B75485C53B661C97AB2B9E193D6F1067F518E8522A73447AA1BE8AF9CD722EB8653E1837279C5194EB21BC9127F1EBA895F9924A254C6B38CAA0907018197A771D531A506713D3434C23A3A2B996B7E11C83B97058AF811E974819DA2147A473686869F4D04BFCB9786A0F9723DC67E70E4AC0F565B85F4BB30EBCE82B21950838A2102805550C9FC1607AB93A7E42A0C9E79611FA7829BEB0254050EE730792E73975A7B38BB718AC65064ED7090471658657123E7823631E802142AA563771BC6975CE2722F0E012F555C3F021A7FEDF78F51020935D01A92362DFF154DAAFBC4AB6C8D32D2A11525A474757C690B21274B443B58458B83766DF851D95214DD04BC0AF73679249CDE1055E1977559D26B3BB60BB306503879B7FBF0B2EB2508AEF52049F43ADF6275D4DB027B6477D6479CFBBA91AE0ABF1DC8126FC962CE9921DA1B0005A09C30B6894EF6B3FF79A0C088BD2D6074988CA824AA18B887073A10C7F21982F802204C220756C0BDF59BA855A63A026125BD5C677DB08368B475B52C3559C3031EA56040B9590F859F6C2560F9170F5FA759068678B9E22888671CB0A693E825BAFBDA853C0B56B79A63AA198710B6246A4AA58B226086416D3ED82C412B282CF38C71348B40EAB105BA23B2F3720EBAA6F21C9F7B23C4E324C4C3A821DE7957C21183FB48C4C127732AB169F822C3003A803AABA857C6B92BB22D8C10251EE1A6838B18C650CD5B8304F886240E16C8CF4A74F14938A21A8F3E87BCA0351DACA3A8D5C014037CA5665A2589EB7EC6F29D18D891C0CAC822792B3408617166B55CB1182341A309F86F99F86B4E7C54E6C2BCD15B15B091274F185CBF5AA7A7A8CE437ADC43DE798498003691147635E787EE4E145D000A02FC34E2891D2047F787AD49B9ADEDE43FC52FBA6803172487E1910D5EC1BE89D37BEB810DB438778BAC52CDC1FE8F5C27AD825639E12ED908FA31", + "ek" : "F6479577F56AE9E2B96A45C15FBA36085BC7FE0358664B2B11A95C775D3215F7226A4BF508C391459FDD01A3067E5FCC354619BF0785FB532510892DFA2CFDB81C8E7F29D3AD4B49D52436734210DB2887F6D8F90BE7138C526A612B30D3215B5F87397A1DAEE3D081D637B87A10BC872820E3E78A8E859E39C877494C4F946852370E47377FF6651A10F9685F04A3B5D4BAE873C5BC1AB226945093A9612037D692111FBCEE32693DEEA93DCD3E31AE2A94C8530A875D15079E8D8C2300D476A7FDE24845FDA257565B7C143BED3CE6441758B8236AAA9067C6441D406D4064517373C4A8FE6617DD59BE5CAE26DBD51798C4A4ACE8441B8DEB9AB36F8F02DF30731A7F24E8659BD396E282642BD190F7DA367C2F671B5440A640BBC1A5A8641414B1522EB4F789B05F8283DBF594955064B611C2EFD3C4725DEED0AA6859ADD9F2B8E8927D3B9645D8CABFE585660B0D83CA71C99BBAD88F9B772971C27FE84F4D8398228CBDF38B99B45BC511711D155C7296009DE4B1FAEE218AE0BBE06BCF7491AD2590CE4548A9A9DAF8CB932076B4F17C37EE9DACEF1F730ADA932B4AF9BC2BC496DB712753482ED9CF23D09FDCDD113F83BA71F8160CB05751A132A9C4E404D03366726FD5655CD2EC229D9409780D2581FC0B0EA24BD05DF5614FB96780D913A0837ACFC15F120FC5A35BE36C2267A09CF723860E900D9CA2BE5EC3F305B429FB1E7E86D961D250C0129EEF2D96F8FF4B357BDA4C5456AB357783440E5D05A900A9B224E0F8BAC7E0FB785AD3E07EBD1D61E614FF608D97B4BC5314A765093A13053FBDED7CA8CB249AD4C964C8D0992B1BB6956E8C72BC24534F4E61D63A5A1264F3F8E1568015D4A51A71240B9196C415D600AF3943707F95C9331F470176E339AB146D7D4AB535832A3214FE3A0FFE5E1E8F338B4FAE6048C7AACBF5525FFEB65371D484D363382C02CADCDEA04FC3EC1297D6E0E8C25D8068C87DCA82503EF9490177498F99658BBD144E44B8451C78BA861898706E1F6A8264A7C1F6B0C769C5A46539E1582C85DA603621CF25D9AF1CC4C8BBDC8F0BAC624E8DEBA91FA6216136EBD4CE346EDE8C96491BC09661C12AA0225C2506C98E091C03F5D6A08C91F5FC8A98AE6664ECF13D230B67086358B6093C2CC2E36B0CB7ECD2A86EBB55DB6E9288C8919DFBA5201CE031D85BC0EDF764C26D29A9FD9AE32858B5A4D43BABE34B27B2545B38A8B299F1DBA43703F9CA44F9A77D193FB9D74613291E4CAEF591E4B590E0F41E6EB875D29582987AE9CA733223B424A43F178FE1B2C85A13DFCAE33DBA35D559A589017715F964CFD8F6818B7923B7B4865584CF83D16612B1086D83048B13CEF588921C05EC8F6C6079AF31401E2B00370A434C5798620E7108E7B0BCDD3B615892498B0D9FD7E84A68145E9B03BB76B006B31735EDA6ACFE5DC2C278B687D8EC7C14177A432429B29B91FDEAF6504243181E9CEF11E46E2EDF9C92F0435D80A7C09B53A827B6088805C21EE3C7D098D00A77A3610D6CB483FD823F0D97CAE7064D0823A5D3FE8BA1F9C89266028ADC08F2A251671091CC49F6D692583FE01C6AB692D28D156B0F5AD3BA169E380D1B5C70DB0AA01FD3EE8400DB87DD1B78B847014973454E17888EAA761062EB3BCAD719863B2579B015C63EF81F6F2C0D01326301BFD49CB8CE67791CA0D2B4D91C8123F9339F27C8C8E0DA5EB70CD41AE676477B6AAAAD7854AFA8E7F0A61542F55ED96F425E30328932C3CFDF9FF54A70C533DBD1CAA44472432D3946BB7265F7904DC0CC44D0E2A55CA3C5086238B80F6EF1282746BDCD3A6733C9B8FF07B3AF481699082498DEE3640699AE05C9C7DB240777950EFF219CCF998E736C0877ECECD99BF721D109552C3FCEA265DCF6FE7809F9A33169D57DDDB8768F1D1CEE191014EB935E589D9FDB2658A0978E88A8CEBAFE57BDF8C77C41153FDD19F69E79723C16969D066A13337053381AC2515C3920F0F81D7B5702431B04D6AEA58E4C505BDE058E4BBD3C59A77D5945AC2063B03201376ED0FFA59FAFECDD817355576B94F5C5B2D63E19ECC07442F703375BBC0EFC1E916EA0F72515B6A96C2D56E03178C5C8FF74870044E3709A383E347F04CD588DA00EB7B3662242849F9471569201BFDEFB143BF8104B50F9F2D302648F7451CC2F0BC20E1A5D05065057E8852EA7F3", + "k" : "CBDED539A4CAC32594E3827546E35793C4FFEF863DC2F06A7F2E238DA033E3C0", +}, +{ + "rngSeed" : "5DE720F2D152BF4E1F96A61E7AE5F1BED6B8548E32638C2CCEC9F43B87D1BB43DFCF334F0582984D27E440D519AB662F", + "pk" : "BA96BFC11884B9304CC16B669550CC08A2828DC34E704534FCC057A45B25CA8AB600372CF6F60BFD530B1E67309D5004361ACACD392D104C9D3BF66075D5949AD75815BC9517F13208068AD5250595D76CAEBC3B188A268312353E232CBBEC0830C45B44E315B4E037F66722F2C8C58D37228A7B3C81A8914DE52757947EDDB3A99AD35BCF1BBE82D9249D228A15009BC2521162D28F91B70CE3C05C4F027CF638053776511FD4C24E660023720370042C6BDCBEE2CC853E1345268235E1E31D41106B1C359C8C4844274A42059724B1BA455E01AC4B800D79D4050C4260B862CA9E30A3CB876852997298609C19479B7EA35691EC5DE9A16B09382CAD755CD1A008C06B3A5D347B75A06825D4A8077CC6A61543A6E4C362E979A6824DCB494B7F510C1A3557664B8EA3D681702932BA284DEAEC19E83BB4EB0B4E916670C185B8EFFBCBA3252959714462809D54049561BAA71F13AE08D25FC587A01C853B32681CF1FC906FE00C2CC58971F8863B803D9752310A18303298AC6C188B46AC03E3A24486B6BAB54306FB1942B908635028238622198882989F712ED3A30EF5970528BB477EE6A670D031E5DAC2557655ACB2C10923441A77959923BD8FE07745988EFDF48BF794659BD34CD8941733F97D85178021E8B20B185E0CC47973173C15A681F4A0AB52C5C4C6F3A2364465D3C727928853A5A55998743E58695FEEEB9F06C2CFAA70679C00CC6EA329C16BB4943418D90017BEEB03852400B7E87D6EB8BE948303E31306A4116FEA8BA59D30AB6F0A5060C2AA89329306065290466508C17EAF7687C551100A18CDDE6600B9E467E3FA7B10DCBA2A722347349C2ED9443C401B6749225F38195C04838CE8B96AB66CC2D7235C8B0316EB7E1AB1CA956C5780FA491A7720B073BEEB48B98DC41A1B276020256AE6D85AA3CB2D60E6375B44AEB6E34503FB0A73426CF999AF33E89F1F2934C3438F47814D76413B87A264FFC67263E3CADBDA0366F13B82D9A789D55F05A30868C6A9B7BC7CA7E69184051D9F2ABFF4EBCF0E26290E69C0BAD83CE3BA19D71133A0D8B347E1ADEEBB8A8B915247689311E5378D256FFA867FBA904217339976B4AF06BC3E5A9093E8E45CD615CBACF65BF1B0899DA61790883EBEC896A095959AF55D0D7B39A9611E439A26CAF8C71CB05A57CA071C719A281625C2E4615CD4B74826323B163CF161BF6A0424EEB2381DF549B050BFB9628461210461A9A35863BC0103C8290244C6EA5BA381C421421C91C010645CA365549C7AA09520257634442B83E5806D2A274DF4B8888BCA68ACCBB5350743443D8DCB471E25AE4B748338A922B7E11F761B059BD5848EAA441C812951729D6E7013FA98340AE9A142B84B6A98C6577369053652B3B505D4D8607737B49FE06C5CE8B40EC680838A182E34296C317DF67826F4EA16F4547B4FB9CD0778B2E5C66E1E5382DB0C0C432770D82A1E20F59CE1EB1CBA29A1B9D8A5E2DCBA6B04022BB72923591E79DC4F0616B2D4637BE08558A212166A97588E128C08579859D1012088A7EF26355FB4B83849AA3AB06B886AA45B9A1824A74B05F090BAA7CF2969368E6A82750160CEB0107811543AD0BD25031A285C4186719D9A30270FE1C73AC8BB64D912DFF5BC324441DF18AE94D03C82B63CDC9085D073063DA296627A5CC754973CF296F11AAE6BC102E940740C853FDF2576C24B3816E60483448D9A28C3E1B295A4E6BB36283F4706290882B52F7BABE54B95772A174A4A0A3767C2F6AA992F5904350071ECE661D94C868DF7396C1A1588F80F78F82BABE28531D97617335CB098CC530C5234DBB4DB98269D60B271376A52621FA40A464BFC620CBC08B2AB0198E2BCF6912752B39CAFF4938B842B1519455BCA30C8B15F6E2942B1C6798B584D89382ABB26AF5BE574FE12838737091611ADF21507E6803A88570D19E34331F07766D39D57F80CEAABABB0AC5A29991A1189A6C9364B93A53E73C13D91C656DE3038302279DE8A0D45D46715D78A8C9AAA5414540D9CC6553CC910B24CC941769CA5B8C576AE8E559969720D8048291C9374913BA79EE9CC3CC217C5F1A590A7AD9BF27B365881366C2A529A85EF8B34D64792BF786964831DA9A38DBD81A573B74A8247B040F60404A038846BC2A3117BBD025B0F7A7DE41806DE885D79E49A5EEE5DB12A57B1A7DA55CCB00B5B", + "sk" : "0B57A478859C30104A9DAC5C9C4B15AD5A2C3DD362B50C7ECF4B4F5861B60C9774994752AE90556290193F02B53FC3CEFDC6864B9845185A1B99745CE6120F6DF5898E8682D2484FD809106C9A01283251569A67FD8692FE202995290B6C54CDE2166A8926A96864C2F1D209DA830832D05275101A8791A5FA7B42FDE06D7109002D580701EC45777A5CEF2A961306244F540CFA4120AA146269D8B9178C34B0F9086895CF4376C10176621138AD1216BB1E0A109C0CC4DA4167A5FBC7497A6663A5CC2853B347801E5401B2846B7CA0233CCC78B2B79C0DA56A1854696180552A05A3CBD024668E593A65143DE0A969ACBA37D3DA4E834375F564379978121AAB89F2E210934C5A5529CA121C015474AFC1B805103226899967C616C482462FB588BD8E90606E440046A3593F4BC1FDA596067532F340469BAC9E75226B328C491411B940E27D196C872D3630E5A396BB47B38A256F6B376508E1B6EF92C15915469D2B781A8C09BB5382BE765AF47035A57B0BC85120CF10200F98844C410D3C077E0BF7703AD090FE58A7763C77881761FE651F1B8CA7003A99D7F4B94560B0B501241F102E93476DCDD937331B6A415317DF973C2A33C98D835C19B78F548B314BC5933474132F89876C9204E2221A61F81D140083DF2ABA9A674B088156C99A71F14674B2DAA435A85C4CA2CDF4A2588858CDEDE20516181E3537B1BB0060B448A306C691E93AAE45240800B390E77163F25B8CA78A7868C0B738A671F3A78171A931FF164B5BFA058D481AAD6245757BC47E32038AC95508878070BB6061069E2A0A1369C45DAEAAA04B9766B21C354FE31635189C4516694FAA2C72FCC8D15C9162EBC7BBB98B07E52C296A4087EA7EB7A0AC1233AB108C3603670D3B15AC529157356139C4DC19C5AB85C31C9B3EF4911861419F821A8D6A2A191925BB76AB9F203A2E241873B264EE980267F150B9B9B836E88FBFBB79C5FC2E738BA031D8B51439834D96C75D6017F4D404A0F41D0781986E7C72A98A2702143264B153B93B05B08B414A221EAFA3A733B8CCAAC737CDC6497DD07B171525730978D01B0222A54450334777A2658CA37BBA60AFE909896F47217F45652C1B1670C54098B962E49493239B62B17365B391112110B3F3F3B6DF73008BB238FB029E46C06E488B28E0D599EED122D3350C74C168E79592DE7C31F443B848051C8B8BC159D301C323AC43F24C9E06456FD19B72A1C237E25F8113047AD20B686C2541850B42C9056C68C9A95C3413F61C8A713DEE849732930B71F0CD65930CDAA816FC20B8DB2AA130202418F94115E2B6549A01DA9183524607CFA78F787219A4C88EC0C3913882429FB16961B2A8F6B298B24B2503254D6500746352030119C5C0A153B7DC204227A641417669139ABB8083F0552CD2A24E3CAC82899773BB77BECF49AA6FAA95CC230C9DB01DCA7094D44269C4E9823CD17F5344BFFD2C999DBC011D466EAF987EB4074A0045997BD18DA0213D5805AFC7278459F31151C6C81A8B54A3A6562422A4123266D66BB47A1BA3089A583E517F92D3386407A4D9849FD6197581B43C3BF0AFFF21B14B925954459E0348AB52B5120E140069EA1F47C97D3CC9A865F56A00B1B68190BA331A1A72D06B22847AF0248A21424E8C08426E3C5F40CA61A1705FC36C3A228332C1626FF9478C3382059126C9AE101278FA968FF7C3ACC43B326B9D0F7BAF4F979BAF542BB6D04769A05139E358150210D8BC26ABB209A3E17E5B6C85A5D5861906C943C3A25BC41BAA292157BA5E1998ADDF38B6D01CC4BE39C91E8348B1B38FD8324CF413125AA0C6BFD2749FF43C8EDC33E4A68B0EE9C6D5CA31B6E3C2F5A261DCC804D90A3CDF09A17881A697F52A9EEB2D81F48EF191408FA915F6AC9601F19BD4442EA74C2D99505A25B36F83000236A73DE7D776B6E57F7BAA41257A261E008FA4F574F8F90CD9865670B280D2BA02BA647D2EB6C7E7B1B679F85C03597764A59E51CAA147C63A4D9AB99815CB716593FBC898BFA9CE15F68D938CA77BA537EF1215BF160553306279DC539CF2395C004374860E812B7035FA14A2AA711EEAC5E666AC51096C5210A3B744681944A5877B917F6CBB7C58123C6372D87B12555105CD773C86249FF866A24942A758AA18BA96BFC11884B9304CC16B669550CC08A2828DC34E704534FCC057A45B25CA8AB600372CF6F60BFD530B1E67309D5004361ACACD392D104C9D3BF66075D5949AD75815BC9517F13208068AD5250595D76CAEBC3B188A268312353E232CBBEC0830C45B44E315B4E037F66722F2C8C58D37228A7B3C81A8914DE52757947EDDB3A99AD35BCF1BBE82D9249D228A15009BC2521162D28F91B70CE3C05C4F027CF638053776511FD4C24E660023720370042C6BDCBEE2CC853E1345268235E1E31D41106B1C359C8C4844274A42059724B1BA455E01AC4B800D79D4050C4260B862CA9E30A3CB876852997298609C19479B7EA35691EC5DE9A16B09382CAD755CD1A008C06B3A5D347B75A06825D4A8077CC6A61543A6E4C362E979A6824DCB494B7F510C1A3557664B8EA3D681702932BA284DEAEC19E83BB4EB0B4E916670C185B8EFFBCBA3252959714462809D54049561BAA71F13AE08D25FC587A01C853B32681CF1FC906FE00C2CC58971F8863B803D9752310A18303298AC6C188B46AC03E3A24486B6BAB54306FB1942B908635028238622198882989F712ED3A30EF5970528BB477EE6A670D031E5DAC2557655ACB2C10923441A77959923BD8FE07745988EFDF48BF794659BD34CD8941733F97D85178021E8B20B185E0CC47973173C15A681F4A0AB52C5C4C6F3A2364465D3C727928853A5A55998743E58695FEEEB9F06C2CFAA70679C00CC6EA329C16BB4943418D90017BEEB03852400B7E87D6EB8BE948303E31306A4116FEA8BA59D30AB6F0A5060C2AA89329306065290466508C17EAF7687C551100A18CDDE6600B9E467E3FA7B10DCBA2A722347349C2ED9443C401B6749225F38195C04838CE8B96AB66CC2D7235C8B0316EB7E1AB1CA956C5780FA491A7720B073BEEB48B98DC41A1B276020256AE6D85AA3CB2D60E6375B44AEB6E34503FB0A73426CF999AF33E89F1F2934C3438F47814D76413B87A264FFC67263E3CADBDA0366F13B82D9A789D55F05A30868C6A9B7BC7CA7E69184051D9F2ABFF4EBCF0E26290E69C0BAD83CE3BA19D71133A0D8B347E1ADEEBB8A8B915247689311E5378D256FFA867FBA904217339976B4AF06BC3E5A9093E8E45CD615CBACF65BF1B0899DA61790883EBEC896A095959AF55D0D7B39A9611E439A26CAF8C71CB05A57CA071C719A281625C2E4615CD4B74826323B163CF161BF6A0424EEB2381DF549B050BFB9628461210461A9A35863BC0103C8290244C6EA5BA381C421421C91C010645CA365549C7AA09520257634442B83E5806D2A274DF4B8888BCA68ACCBB5350743443D8DCB471E25AE4B748338A922B7E11F761B059BD5848EAA441C812951729D6E7013FA98340AE9A142B84B6A98C6577369053652B3B505D4D8607737B49FE06C5CE8B40EC680838A182E34296C317DF67826F4EA16F4547B4FB9CD0778B2E5C66E1E5382DB0C0C432770D82A1E20F59CE1EB1CBA29A1B9D8A5E2DCBA6B04022BB72923591E79DC4F0616B2D4637BE08558A212166A97588E128C08579859D1012088A7EF26355FB4B83849AA3AB06B886AA45B9A1824A74B05F090BAA7CF2969368E6A82750160CEB0107811543AD0BD25031A285C4186719D9A30270FE1C73AC8BB64D912DFF5BC324441DF18AE94D03C82B63CDC9085D073063DA296627A5CC754973CF296F11AAE6BC102E940740C853FDF2576C24B3816E60483448D9A28C3E1B295A4E6BB36283F4706290882B52F7BABE54B95772A174A4A0A3767C2F6AA992F5904350071ECE661D94C868DF7396C1A1588F80F78F82BABE28531D97617335CB098CC530C5234DBB4DB98269D60B271376A52621FA40A464BFC620CBC08B2AB0198E2BCF6912752B39CAFF4938B842B1519455BCA30C8B15F6E2942B1C6798B584D89382ABB26AF5BE574FE12838737091611ADF21507E6803A88570D19E34331F07766D39D57F80CEAABABB0AC5A29991A1189A6C9364B93A53E73C13D91C656DE3038302279DE8A0D45D46715D78A8C9AAA5414540D9CC6553CC910B24CC941769CA5B8C576AE8E559969720D8048291C9374913BA79EE9CC3CC217C5F1A590A7AD9BF27B365881366C2A529A85EF8B34D64792BF786964831DA9A38DBD81A573B74A8247B040F60404A038846BC2A3117BBD025B0F7A7DE41806DE885D79E49A5EEE5DB12A57B1A7DA55CCB00B5B706781DA8DD5F11267492109EA905A77270A67315EEA1F5C223AA9378BFB811691FD1369E8228B3979984C15440EF268FD3629C186D6CFDE02B0F8A7908A7EE2", + "ek" : "91D1F7D958A939CFDA1B35C0157E8E02FEA8D7EA03D29FFBD2E3FD130954CFC0AC74E0FC9B48BE3CF3D65B79DB2E9274FA41E293E1EEB9F1542DCC2121805AA08E15075F7C6590FABE4C0489A0BC5114231AA47A6FBD251A78E572C96C88C99048E0D9C86A80B5095C01979E2AB1EB63FDB4F57B96BE8C921B3680B2E700B345F4638E140D8331184BD416810008E0BE89E6B88D5BBEAB4FB63951C1EFF5AB27FD8F49174A0C8A62B1D20038B8FDC35236F47C24DA94028C8137CA6A2FDF5EBE1AD1FA5B6BBD50531AEEAFE0C59007789E4B2EFDC2676BF07DBD6FC9A305C6485D9F68E2F8D0B733B6D7CDD9A180CA6048D67BCCAE82B8E8D9B1B7DF5F4FA0ABEDBB9901F70C92689F78B4FE184292F9AF6D6E1EAE1835F8C321E2BEEBE33995A90E110D6EB7E41E90B6DA9D6E10CE0ADBB8F08D79B7253B55023D69977230ED2D268EB61B13824274AF3D0A217215F2EB6A0EFB1785452271636BE7ECFA9702119DB9D08AFE24E38CED07F6AB2383D088A50A92375D24517CB7CE3D3F7C35B10632ACBE0F630984BC32F6F2876E1882567D6B0F2F6CC3A985140DA65A16B0619D17B7D2CABA7C42C7FC56BAF77F248CD96642030E2535CFAB6FFF25E11CBB88A6BD381E4FD807420D675D8C3348B700B09D63F3D7BE0D9154CE11A497FB115C7EBA1EC2F99F551F939287FAFC84FE0BC3190615BDF6905A5A3A2FD4928214F3A4FE6AEA3B8652C37216BBE597F9636FF5A572D3066E490106344CF50A610C8A58AA2F6AB0B2B470FEC3FF93C6BCA5BEBD23B531FD2FC4DFB4CC10A6C4C56FCEEC9909F553912692C8B4B70854F4B636179C6426DA3D22BC90623A1B89457C18353A8B6515FE3B28B2A9C479C41B550AB55FE73A214142F8422F2D6146615849682057A2B4E11646451865BF4F6DA0BC77F3F9E7015C89F763B935102922943391CE8865AC4197FAA86B5A3A6C5724B63CD264FD4C3DB7FCFB5FC7CEF19DC6865F9DAC367887B16C7779C819BAC9485FD923240D8AF8DDD91B01ABBFA6317FB2DEEED2613848EC69E52D7D807C9C0C85920CF90B1AC212D93C169C4D974D36952B46D79FB27E0CAA86DD62FBDF5445B2F1B31C81CF7A21880B1EFE15966EE94AB6ADFEEBA4C1763250AA19A8AC380B6553B9BAC78D6BB7B1126D1E6B2DEC3D13B27C99D72771D0706F8E61014251A4AD068F38D889A94F7F8849EBA7534BF3CE646AF3E981AE938594899D936911941669E82246CD6F2EE5D8F8FF1E0B9C098A16EAF1AE6D0830C25378C94F14560F16DBFF219685236F86AE497D584F57BD91A9CD312C1E360F3864167596C402CE1E9650D2BF0E8B5330550B3A44AA0F303CE256F66DA8EA483A3F964E698625B1649F1FA7B14FAE67C1DC8DC99DD1F84B474F0E592C95A7B5B99EE05BF411F3E2CA9E92A80C84D06A76E74BAC006307D1907629B8BCAA8AFF786E488AD10A4A5EB7EAB66772D81CD64BAE518B4FC272DE6C4D78933B4A212211782D55A7B948A480592965F5C61888CF099D5269810CE0B6560608CBD75B0441782ADF8B8524C35545205734AD60AAD92BE0CD3EF7858440CA6EF0D2BD56199BA1F387F2101E186DD1B5A794F8843AC3C969B3D3C148671B68890A24F4BE1A24D7375CD6E11F2CF368B63EBEACB2A3E12C6C36323FF270C5186CC2F6E5106ED337D8577317CBBA7A7E8E0101A4AC8AB5614F78852294E2E1D5D367606C3F71FE41C6281916E41E37866B0F64B5731E41E6C676C8B8C58077AA24C94253655AFF9192DA249729F358C39934DB89CC14D531B78AACFFEEC55FC8BDDF592F152B55F66C1C78F7E487C3D16190A4220B488BE165C116B333F02DFF0D96022632496BD683DAED2DEB8A648BC9228068287C9FD7502AEED382D287A17040D8AA7AAE60541B068FE1B9437097F60C3AC2596C69DE0F9ADF02C1D0C238885F55F9086FFB1FF071C5EDC7411FB1A3E0AC2E7B37DFAFE26F4613CDD0056F04DF9353B9F56ED313FE888AC2EBC5EC83F4E5846696321F177EF365B1E0C35CC9B2F354DE7C3FD7611D6A946AA5349A31D6E2E34D9C5292BDD0CB37932B15038DB43E45985FDB4524A4AD3601957E4081DE77B5405423AD7C4BC9BA103D9C8DE84A44D363A48D64366D32FA2D187E62D1ECD09C2B693230EB2FAD999D253C6F84D44AC3BCCF938F5142749BDBA1BF4BE6E7704383539DF1E41FB6F4870993", + "k" : "7F35B2131BD3FF866286682BD5EDB8C9A3DD0FDAD18F9A79EC743C8780A769D7", +}, +{ + "rngSeed" : "D71729DCBB27D7CB39E9E905025D3E55C8602EFBCC483C9B866EBF82326157833169243C14550AD728BD1470F39C642E", + "pk" : "2626CBB144988961CD4A5B3797911772787768B796A5157C180A1264C1BC6AD588139028F9F28B3D8866B8964A5253B79AE86064B5979A0B468F87CE0AE843F34765982114BF327FF08C801A3A99AF0C27C72CAC48614620D373B23C01D1EBBB3331C4F0AB6CF7A03804545427547ACC2A467E895D75486F23CC23C779A390026E41B56CFB04B1E22190894A3C1EE16F19017D7CD75151047618B49921C8990A580A03E1656F841E95101EACC1106F0CB94DC2789BB1A2B3591134B05E7D983736F83CDD985D160A9CAA210DE0813EE78B411C813FB3008742F793E337A699B3A1180C5A48E12D92B9709525858A70CED2D2C81EFA2401283FBCA4C4B4F1904E75AD66A894AA57CF240118C73643AF435F024013D6664543888F7F30327BC65E3631A4DA4B6629131EC5067EC5A8C354F94AA207B587F139FD3583B3CB51E6F7926B9A914C15928738A75C9B618B250FFDECC61061618A8038B3C65841AB3D5BF203C122723B087D4AE2604F5BB6C9013C4F38903F65248C9783DB79B98B9A827D528444C26C8FE408D785530D90123D30371CF46307E1C6A81097AB96280EE058D598207E666CA0DC213FA48892C3B7D5F49BDCC894F2A8659FE882201B4EACE22E1713C06D74156A6A04D84C0B29F6B53FB61773D19F5CF9394DC03BA90923D33055B5C089F43961CE810A27F0878F4A77E9D60A2A1842A0450AB7208D24CC865A6393A9820B62F96ABADCC0650B171B473DB3E91906720CF7EA3730435F639C1AE9FAC889D76BCA6602BA96B0EB98AA44136CC3A978B747ACBA054032D36509A7AE9DC30855B2B1699628601793062C5705C5B103344C3A77947992A2071C35F6393942DBA3B8545EB9A58DED8A5407A270B676061DEA1C5D490F25A05C0F82750AE6151DE2BF028A28657269789733F1E4C279203E2FB837E6AB1F30C04DAEDB3AC2809791E8CE988A4C1754C8FDFA8BE0FB8C94A240AE3B1E73ECCA729B4AB04044BE1B97972A1A27BB10BDE4240D49A568114B938BCC050B26145598905735BA2A3198E3A375B752D8F5A84004890E25916871A34469A8CDC8B1077482F785AC3E497574ACA642D74A3625CA37DAC98565AB6F4C95A289A434C9CE9FE61D129C073B5CB755306D47873FB186BCB86AC00BE265C320C70788BCA0F462FBCA6DB8805986425A6437304CE48D59588489561D37B60D1F171F03EA8AB817C93EA7C3AFC06447EB823E630ACB4213B50793457AA8F0B9B484D5830399BC2C98A7FA452FC30713FC85AD9A7707E8343E2ED113EC436625172CD4162CB7730E5F327E9566A01DF27D06B460D155C8717469A365ACD5EA80B935445A6610EFD3062CA954276C70A8085C42AA7F82628655F97A06C098AA7BA8A1783060FB819DE027DAE9256E8CCC9A72539985144830C23DDBB3A1860147BCC0EDB69A0BA03BF9626C1F35A611F686CB71801E130E0CF363B795BDD9C32E82978F53083262A703F85398D0587C2CCA06CE1C83FFD614D1A85D437784623814D804CC00778978E0CD3E2704D34563FC23494D84B6A4482401B009B601582BF48D7521676023439AE2C48E5B54BAE0C592B64D038883A1CA9A4A843C100A58D19270F8484DA82AC633C3550A1634D0A7CB8BACAA19D4500AF0AE14499EBAD63CA1D2AFEA753E762246A0834942643050B151CC9AAECB587808754E2AAC15D5B2C074667766181309B113211320603499D9B2A5ACA065D8C088B24482200C0EB26C3F7DE8751EF56850AC8097581852873B396B05EA4C12347309C7814DC89929EA6C3F09D9BFA92BBFDD0680591A69DD855269FB77E8184DDB4AA0D3B2A7013BA06D447598E95222774BADD3544B6C80C229392B0CAF13A94EB3BC920FDC0AD3AAAAB352554A15AD0ACA4D7038C208EBA4F4B181E8194E21575687E55B5AF0C2551ACD36824C73C950B1D9A8A76264ADC88E6E220396BB1AEB6AC835F2CB3167C7F4DB6BF0B6552DB314BB91584B86C0D7762041075A432583F8F357A77731EDC1A7EA932DFD40A8AC9C09D3A687DD530FF1AB95C4E56537DC6E82210C0D3C582049A180030ACFC3790FA1B437E91E1F67262E03CB59A87485658182D1A518822F678C266AD70FC1622C5B206AB7C61510F1C920DB37EE852276F1961E64614EC8167FDA7091988C176E893AB163E034A7E92D569882BADF4976BA648396EE00E3AF7F5BDB9A417E", + "sk" : "455C59BAC459203A7BEB868C8477CF5CE391D9842619ABC685EA791C1C905CDA7D92A4CB0560C022BCA55C78CA606904CE666B79366EB2A06FCD6525F6075F80A5C23E7621965292549775E9250E8F7B6F902A0F5AC93CA9FAB1C843B0F71652CCE35F8950CB88981B5E9C20B6C639D2486DBDF823641836E453B4F3B3732965B8B9F64EF7C0897225CD495C8D38406B3B380A70C0B499788CB22B5C6859C25590BDFFD578396372C47CAB57D22A02313B23966E2C2B6F84F49FE69B7BFF77474B0654BBC71AB6346001B2C11F446818C041646050CF6136E037CD4CB8A69206A7BBF2C6E3D0A92B68A1E7CABA00A6A70551ABDCACCB618B35A3E96026B6499735BBC8B9551938680978804B1735F2DAB7BCDBCC3C4CC15A73053DBC1A7AE967EC073863132DA8F742C343A0B48851EDA61F97D6018F7BBDBC674CF24B6290D6A7A9577745EBCA38859D5A7C7D1E54CC18983D9A9530910A10CA8AAE777336CC147C939622BB433AE125484D2518CA45C000D2004BA72ACCA4288D391103A9A9F3DB703584451932A02DC46EAE313F55305E5990CFB776605FD268B63306FADA7A4337C51B2C2B44665B93E2A2D6709C0B08A172DB7EA5410B2C252A86D2A08D1AA9126986E78A910B852A12278B1DF95BAEB41965D1CAF6798EF097A5F7D9BD13C83B7C87AA29E4069A376668F730E1D85F693742CAD56A122494F926944DB6C8270407EEB7B0E3E20A56161948BAA86E218DAD3703D19854E5E475223476D2DA9B1469531322A1C7592577D7035F144AB29A76F661803B125046E33EB230CFB194CE37A228CF251E1C7190D9C231BD5BCF65D03595B4601EF519B91232F745C8182C921D937BA8F6A75AD524AE1A84AEB61A1BD4647E7A3F43315445F7BD6DB427BF309FA6E715CC1354BB3A66052A7665E53C8218B4AFA57B91E9576DBB562EFCA278B04707D8760AB73799260EA88B10070C2ED6FA545BA8A43B306D326ABF7054488702A5882C19848AC8C2397E42972260CC1CBF6B66CBA994A0282784C05ACDD25CF4E99F6F91086E777D3B0449AEA69D85570AD3EC60923300869502F245845C43BFF69B83E1EC790AF2B610F7CF09C3456B81023DCAA497277FD44733FC836572B76744280AAD512A94582C0A6CAEF92C02B81C646583CE8223183BD4303A741F6C752B8604BE7B8B7A0903AE91836D39BBB1B9FB864A86636977B1CA742A99D949818B535DB3AE8AA4618BC702CC4A1766411AD6FB993008A0B8AB46A0BBBA563006B0FC82C5B1667FBA4774F176CBD667068C7A5CB0055F2229025B3C99B890C1CB6757C14E748358D90C040F44A6DAE0025FA820C5D037D48C31E11892EC496833D41E1CF226C19341FBAB7FCCCA4B111160122755F35C43CBB75063462E3DE16A4619139ED178F78686B3590009153C17D142E34175D1B4C1D2D476C0BA4F8F715F0EC862138BC70A7A919237C2344AB8A971146A013864AC6128315590C671B1E6C1FB329DF06052F782A06A4A1FD8A66EDA148D03F04ECF878A13E50D657167DB2C57700278FCD1813884657CABA453DBA396005F51949619342E83B601EB1B85DE358617663656AB006AAC29443C4AB0696C48824DB1351BF9DCAC02F32FB45105151C936C48642429758979B1089C0696E039E8B4CDCE179ED2B457E65B3F9D65AFBAA5885A377581A2814EE1B048B10209918FDA1B7E2FC4368A525626A601B621503AFB0D3F883B94D1A41089C89C8C1C81880FBDB312E72983A38471A8D797B5719799A8C8482C9A99B07240438C01361A156A1BEC17619A60535A745670DB06B8C33B83D17F9124076409BF9130595E1322137C3DEB17B6DA088FE160B8345624A5612330C2042B98B13C6C2C8191772CC37623353D4DD2A9E2A156A30A7AD2C3461F6548D9282115A1B115D81293BC155881BFB49C5D16DA815CE4AE5C871ABC62828535CD8C4A98FD0430711B50D468715368A15680A6E0A78D088660E0364A3F279265F1556C7A711493B666F5B20BE30890CBBEBBB429B5C84F3F6A7CF6085E9F411656C65771806C69DB98168B278F506CE4D385B95468B1E94F6B0B6DFBF77EA7C8B924C81449530161B61B1D0A3884A23C90069837A386CB06B4CAF3A5BD0608D7B33DEE6A25A9712DB231961D73CD6D3B572626CBB144988961CD4A5B3797911772787768B796A5157C180A1264C1BC6AD588139028F9F28B3D8866B8964A5253B79AE86064B5979A0B468F87CE0AE843F34765982114BF327FF08C801A3A99AF0C27C72CAC48614620D373B23C01D1EBBB3331C4F0AB6CF7A03804545427547ACC2A467E895D75486F23CC23C779A390026E41B56CFB04B1E22190894A3C1EE16F19017D7CD75151047618B49921C8990A580A03E1656F841E95101EACC1106F0CB94DC2789BB1A2B3591134B05E7D983736F83CDD985D160A9CAA210DE0813EE78B411C813FB3008742F793E337A699B3A1180C5A48E12D92B9709525858A70CED2D2C81EFA2401283FBCA4C4B4F1904E75AD66A894AA57CF240118C73643AF435F024013D6664543888F7F30327BC65E3631A4DA4B6629131EC5067EC5A8C354F94AA207B587F139FD3583B3CB51E6F7926B9A914C15928738A75C9B618B250FFDECC61061618A8038B3C65841AB3D5BF203C122723B087D4AE2604F5BB6C9013C4F38903F65248C9783DB79B98B9A827D528444C26C8FE408D785530D90123D30371CF46307E1C6A81097AB96280EE058D598207E666CA0DC213FA48892C3B7D5F49BDCC894F2A8659FE882201B4EACE22E1713C06D74156A6A04D84C0B29F6B53FB61773D19F5CF9394DC03BA90923D33055B5C089F43961CE810A27F0878F4A77E9D60A2A1842A0450AB7208D24CC865A6393A9820B62F96ABADCC0650B171B473DB3E91906720CF7EA3730435F639C1AE9FAC889D76BCA6602BA96B0EB98AA44136CC3A978B747ACBA054032D36509A7AE9DC30855B2B1699628601793062C5705C5B103344C3A77947992A2071C35F6393942DBA3B8545EB9A58DED8A5407A270B676061DEA1C5D490F25A05C0F82750AE6151DE2BF028A28657269789733F1E4C279203E2FB837E6AB1F30C04DAEDB3AC2809791E8CE988A4C1754C8FDFA8BE0FB8C94A240AE3B1E73ECCA729B4AB04044BE1B97972A1A27BB10BDE4240D49A568114B938BCC050B26145598905735BA2A3198E3A375B752D8F5A84004890E25916871A34469A8CDC8B1077482F785AC3E497574ACA642D74A3625CA37DAC98565AB6F4C95A289A434C9CE9FE61D129C073B5CB755306D47873FB186BCB86AC00BE265C320C70788BCA0F462FBCA6DB8805986425A6437304CE48D59588489561D37B60D1F171F03EA8AB817C93EA7C3AFC06447EB823E630ACB4213B50793457AA8F0B9B484D5830399BC2C98A7FA452FC30713FC85AD9A7707E8343E2ED113EC436625172CD4162CB7730E5F327E9566A01DF27D06B460D155C8717469A365ACD5EA80B935445A6610EFD3062CA954276C70A8085C42AA7F82628655F97A06C098AA7BA8A1783060FB819DE027DAE9256E8CCC9A72539985144830C23DDBB3A1860147BCC0EDB69A0BA03BF9626C1F35A611F686CB71801E130E0CF363B795BDD9C32E82978F53083262A703F85398D0587C2CCA06CE1C83FFD614D1A85D437784623814D804CC00778978E0CD3E2704D34563FC23494D84B6A4482401B009B601582BF48D7521676023439AE2C48E5B54BAE0C592B64D038883A1CA9A4A843C100A58D19270F8484DA82AC633C3550A1634D0A7CB8BACAA19D4500AF0AE14499EBAD63CA1D2AFEA753E762246A0834942643050B151CC9AAECB587808754E2AAC15D5B2C074667766181309B113211320603499D9B2A5ACA065D8C088B24482200C0EB26C3F7DE8751EF56850AC8097581852873B396B05EA4C12347309C7814DC89929EA6C3F09D9BFA92BBFDD0680591A69DD855269FB77E8184DDB4AA0D3B2A7013BA06D447598E95222774BADD3544B6C80C229392B0CAF13A94EB3BC920FDC0AD3AAAAB352554A15AD0ACA4D7038C208EBA4F4B181E8194E21575687E55B5AF0C2551ACD36824C73C950B1D9A8A76264ADC88E6E220396BB1AEB6AC835F2CB3167C7F4DB6BF0B6552DB314BB91584B86C0D7762041075A432583F8F357A77731EDC1A7EA932DFD40A8AC9C09D3A687DD530FF1AB95C4E56537DC6E82210C0D3C582049A180030ACFC3790FA1B437E91E1F67262E03CB59A87485658182D1A518822F678C266AD70FC1622C5B206AB7C61510F1C920DB37EE852276F1961E64614EC8167FDA7091988C176E893AB163E034A7E92D569882BADF4976BA648396EE00E3AF7F5BDB9A417E243A93C5DC84BB3AFE84C380645FAD6886C5614A8735A6F718ACC565905E3532AC8557EB61A3D4A2400D3A604092CC3B92032F4D3B563F3D4AA19387EEBF2A76", + "ek" : "80DCABAD12497D8A17F570067F99D72B9057F594082703D499372D3D776C9EA3E14966C0F568519F29B3498467F2AA56D00AF4F4BB33963E47EB2EF04C1DE8724E29AC8D7CC9AC8DC67C830F6E7F87E6C474969A2DF3B5312F822BF2725043F010D6B169F814D08E74A3FF42CDA856BE74E3531A6445643C852D2CA167F23D22CD51DA908F69942BFA88DE717171B15F2EC68952AD1E3AD90C629F669267B58E43FD97BAF873DF399FEF0F7C90416194C6A1ED5427218B049282B9DDDAAC83A74E354D89C6A79D06E7A4C2E7BB733F62A603E603579346FAD5BB3A2C3E95F0EA4BB5E39B97A87902CC29738001E2DC6E9C6C13CCBE578B7BC3B6068CE4104DB4E674B89106A27491B28CE8E99CC1804252B81690EDF61679A6D04903EED297D2A183E1E8F9E926E174808A301A4A8EA41536006F56A4EDB5D54097106CD8AA55CCA9681040DEE9709D50083408F3EF44B3713163B4D697C8339EEEDF3499953FB6AADBD0246DA59C56A66AA356D0C5B581D7A5A68C2113E6E7386527BBC8DB80015154E476D400C516AF2DC13920CA4D79B4B4D31045047BA691F84A5728699614FBE9D88213CCE73C8F23F19C23AF904B3F2A8FC146568776984F089C79DAF9091B2B4B8B80EC7CFD9F0F24AD71ABEBEA843D174CA08F71B563BF4F03FE3FD343FD4BF8EFBF3FB3459FEB6DBEE614274BB65BA97AF4BFBADD8D871D03569FA6C10662A459828FB9B172049C6819C3731700DDA9FB1E0E7216A3B9E220CE1758B87E1AE6A3C20CE1AEFCDA0346091E00C394EB8E7EE647C730D468800F647BD7FE0BE767368F27F07A9DCEBA29B4014D52DD4BBCD24946176D418920C136363E71F470912C2EF2DF68BF5A67A39294D7D09FB15A735210DAA65895D466CF6853641377B4511C9A9B4B11D9357C5BDB6CA1494413EA851F9577D8EA4153E82698EE56EEFDF9EF48FF05C12AF2D3C9E9C1DF114ECAF2130A43DA0AD4BB9615D4F5ED9E2C49DCE83DB1600B8704D84C60DC1E3D70481B85D55145435EAFA7B8900609BEDD60A815DFC6082414F9AFE9127EBFE03FB6E7C0D854803179C3D2381FF9314AC882979B3390AAB682910C5D02F18C5D39DEE90D99EFA762676B926B44FE5B4F4C5D14782D5526A49660524502D96251B772AC93D1619EA971004C493F9EFAA55D5D55E78FFA8A94B899663F1FAE861EA7023DB8581E548797226CCBD2512796AAA098E146E755B4C29C8C9AD1D67F9B417A14F3231720505CC9B9A7AE56346A3B7017F5BFC6C6DC0454016CE6572B3938D47F5C68455C9C68DA41A49469A5EA97D7C7D70C82ABBB666410F47F7BB727212951AF9629761154822426B80F7D4B54D0425FE0AD98733951745768AA5F806A46DED5CDAC713534C9278171AF15A398C60C1135A53166F805F64301A6434505C28C4F2FD7E1BF62F4B85C10EE2C50AE7AA6A7BC6F0CC83B2B0D02DCE0BDEB1F9766AAB4FE30CB13B985D91755DDB3B84D1D115121D540473A867F5C9AE483B3BEAACE9F127D81F9703F14D60A40CFC937DCE63AA95E3506AF2B75E89E1556267D7EC1A492A8F6E622E18035EF74B03248E64041638EDCAD1854B19F3AFEE92BC1644764A85211E4CF460C352F9EC6C6948EF6AE073C83DC2B6FEFBFDF2A87DD0BCC75860B642FF556233510F9D7E633F90A07119DFBDA9DCE45B894EAFB2B14E9A0438CB60E84301B05C5BB155639022A2C993736E22453BBAB7D1CC6CEBF3C23FCA4EF671B940F57DC6EC13C4E9D113CE3285339CCAD6143DB4D9714C6B2BE051390F7EF6AFDDC5444AA979A3A6557C26414D655A517823AED7F078FCE3191ADF922FD41F78F1566A069D53CEDDBDA2212FF42AECC67E4E6A83A04E0FAB64DD958437C8D07504A68202926500F91C40C7DA5EE2D05A5F5F7DDFD31B9A665F354030470C64E7B1486B1034D7F6308A019A4112EDD9B32EC5D38AB9BADF12B6595EEA88600B67A841D21F0441C13084C05C9823E2BB923B41D0DEFC4EF60E5AA4772A2E6FD31E3A1E62C857AAEFB648149649525CE1664F3F53C593A75DAE3CC6C37830C34C6BE5FE3A6EA667A14A6406FB9B929006F2772447AF4737A63325D9AA5B4C15C3A67DFCAB2F2BB8E4D5A5406BEE4655FA9D72E373FD13B722AA82B88C780883A0130F660A4EC45BD992CF079F4177953D2BC3EB36F25877F997EC777890A4ABD5E908C67CCB47BBF", + "k" : "83C8933AB992D4476A8831A2B087A04EBB9C431BC8441517C270B5837CBA8D16", +}, +{ + "rngSeed" : "A7C2C8EDB3601396BEB2DF0657EC82FD5780A2723581A9E03DEE1CDB018440439BB1142CAB0487C5D136E9AF46338AB7", + "pk" : "032C5F6A930C1F65420B0C2BBAB954AE55CA8282B1DA2A61F1B111DF231DF1151504E9031B7B28E793109ED49D46702D25B37F58FA812F68508FE2B9EFC319A1976064A648BF7A251A948B74CA3F1985C5F114033E1240BF3691238B507BF28956A52204459EAE072BBE10431A56AF24AC15F8B546A62C03740C16ECC8AFC58871537C485CA93617A324F72991273A0549B377AC040AA12A46D366462FF7B76A429BB781922F7A5397385421424A24B366651B72C5F8870C21835E0B2949F61EB3571CDCB780DB683C95E23B708889303A4B9F2B862B68A4E2614EB2D8169ECC1349D9B71B5206973487660B6E4CF544BAA688202B0E8DF9AE88D85115F9A183FC95265608661993839914D9926CBAC8993013C59E979AA8444A54972B99257542E4ADB869CF56DCB305455BFEC5BCF64137B72B2A6C9B0DCC6C386ED616D6A25259EA612E89C21A170B64E379458B0ABD725DC8F53A55E57604282DD474C4AB30C4218A32B4183F0DF24475D01FC9F8550B0AAE3990BD414561463A023445BD23C7C321DC80EFF509A6155CD6B2059FCA448CE05D1F0062F3C21849E38A7A90BFBF15B192265F11B5BEF91A6BCD0823E2E1B414750E057583401B3A5F140ED7BBCB87BBA4B1AAA1AA75A911DAC26298A7B9A1830A48332F139F7A4A12A528B9486197999B5717CB8552B38F7F759BECD04970EB64BB4826A5CB47BCFBA7CC46CA17039F1DA30DEA436DE4B6AB76F43C06D1A1DB65A9001A1E0F510D7B4755137BB4C08A710E9A9D7FD8CB32D64152C0B85F40B9CB433ED1D7BEA1821C6881309642053F993739E3BCD38951433B291EA26F0948CB2DBBACC3088D58D42DE008AB581B0B3A9341AC18C28B131FD4E49964D72D65658C684472550A06E68391F8D34BC09A2F25161745C74D68681C3B333EA58C412F68B44D066E33CB7ED17253FA655603DCA0DE7A13C7C0C78C9630F5C57AE925AC97A823102C423D0B7A3AF864C7A95885E574D570895540A3793B3CD0C73B5A21660B64577D6B146E888A113BC44D78C175AA7EE72760F3B62ED7C971AE62A3E8F08CA4AB7DAA43C51A18CB72158DE398326589241F07A9E78BBE0C4CBC5DC388B03A7C131C885FB63841445469C42501D198D114C31DA36418985CA5D95196FA12B59599F90750E4567A76A767547BAEA91C6580A628C3C052C3C8BEF8755238C2B31D52621EA5579B649F6328695AF62AA8D28402A554941B11BAF7B54FFAB7BD21918A0A6D6A368516B4A04354B6A922901FB8A0E9BC9F7713B977226BD8477D5C7088B8B90AFABB61D0B32DE98529AAEC904AEAB8D0240BCF114C5E3A2A44F0043B628F03FA04ADDAC64C918916A3031D6808104539275901C8D8CBF17741A6E185250C7EB9379DE46176D0B6CB02621F97C083B8FC1DABC9A0CAFA9585AA848606C9CBC58B96DA5A8F414BC9A6AB4D9811CD3B3B512925BB5B352CB67F76C810B3FC79113685E85595D4C62D41633FA092C31FD3102102960A0024D1F460BE791BDB0B19B6610604FA26D6423864E93493066F859B86B6C2693A899DBC36CF667AB5E4D8278371CC411ABBA846B780090C7023A09409CC4541B4D8784BA0F643AA62336551525B315D6FB7086AC604B2272333C071B23595CCABB5459B6307B59786731008B14EA142C89A066D5E5C502724BC384013B5544A99AA872D5B65E5100315F70091D9AAE9D1ABA29C18A5549D11AA195D7046AE51A864EB4D69192DA8248300F985FB5742A8F0623859B2A7AA600FA835A0AA647EFB62B9309BA89A9C4B7478A8A1086D6C955834223600B65A80342CDB6788F09B138456773AA8A2B175F477B800C2803867253B06B5C5296D8CA3A4C85496FD9B413383C0CBB95880545C168099926C175BB6008B1ABD69505B8C782C9EE06877523802A936830C9E58145C6591C66BC56ABE2804B1AC28394B9F0DB695B15C560BF48DED5C54A47244DAF089975065B8AABC77E4A6D1178ED5B503A4CA40C2584E878C5C15FB41307AC297DA94A3EA7E204B8A4156489DF3577D74186D5255156AAE92F77512D0B54D1C1559B8866AF41EC7DB75CF658625F784AB26089A076AE52103EE3053ACC22A21A2920C65C10ED64372380292293F494C2C663A87D7EAB6EF126A4EF50002924497E70154426F8B9801B09AE930907E6284E384A1C6554B2BC594591397810B18D01BD3777534", + "sk" : "62D210ECF64CDF77865B40C9B663C2D30A39BC7916C4D7BEB420C29DAC6E3A7A1FDCAC2C68A117966C2BF4E2AEC3A7895CD83F0E426CF826C8D679055773798B748253F34A873824B01153566499460BBF16B41502E97BD7A4CDEAE40AB2F4372C755BB0A624A220B774345D3EBB235E06AFBEA95669E75DCF78502F68439A485E72427345E17A845109D816C3BEE592AC82C7B27902E43B31B5460E37A43A16FBC98065125109C9AEF2C8F1CCBC99EA571781595FBB27B8F26F62C995AFE082E46CACA8929E5C48510F05B1C6A28BA5C0C652DC0FF6E20A5A3C8D19691F0A29BE46246EED49B66D2398378B1B3583656CFCC1F1CBA0422B2A5E474C5F7854724607CEE3955E108B93585C3794CEBAEB8F6E4C24B653988A84708E3BC9649394F422C25BD88EF774AA17F8BF9BF19AA64CBEB4D343EEDB0BFBCC8B07330334278AA7901F8B7810A1E49A3449BBAD23CD17721A52A03DAE0822A4333C6896A303C26356008AA03C9F9414B47C8137BEE6922FF9160CA84D9A0A11E444528004AD471598737699EAD095C4991F99257981A7668DD60D97EBAE26019073657409BCB8909C3247BC7973B79882009AEB701EB82BB6B568BFFA379FFCF235460143AB7A4624F797EA324E16C6757072BC0E5C95166ACB3F9B30FFDB46B5B720BCB55209D96F4DA40FAAF21E2B9B5014D049936469A63940704947E5670310178C65F9C7BA44A6A6EB5580A0174B43595933B19EAB8C4D978D29BB8E7FF4B37FA1BA4DD9AF62DAA5AD879836849B88678BD3549238E2674963770A657C1389B023B75E8A7262E8C97A94444FCCCC63F3E4C17DB97C6131B721561D28146521F3AFA60BB75B0491E9F22636017F7C2587E8E64A8CF4B2D0C5C2DD53322419038E239C7F60B10C66905917C2C7267303D565FA30169904159B7A2E348CB641782599787D7C63BE7A536890DCC858F7A43A7080BD3593F6DA1F4C5454E745CB4CE2AC2A5051E8052A3616B9DABCBAC6B5C43FC3C28FE0505AA823FD324D79F0C1908C2720B37CFFDB58C7E822A48B7052748A996043C31364AB3B9974560F63E00D7E06184AE0485CD649374632FFEB64ED749E1BDA052BA4C0A972C679DB187A345E8C055FEE4C28DF4537795ACA7A602A243B77499146F649226F73991BEB88544AC439E53C2F060952BC5FDC3648E8B850526837B2744D0E7323A97598E01690E04C63D92891C64B9B1C962541755CDD861390DAB893B3ADBCC04D52F0AE193B27FC948305E5787BC2C27EFA77C7B6823FA700EBA383C96A119D453036EA2966988ACB289A324A02272A75ACD3A4551562CA894BB63C6D38B6710F90537DD007B807BDC0071A88537624876D58ECCA89D27757C9ACDE480BCBC96CA3D338F014B6DA5251D9578DED5ABA69B7047F88A8C75860CB652C744571591369A69AC0118209A70B2A06790BAFF6C35F515811E45B9B94A9D9B4ADD0C898037C2988858EB15BAFE5A88439F67CFD537A3070A12F40394CD86AFFFA967A206A5AB72AFEDC52ACC6ADD22CA1E0B0816D729D68D67BF1B387EAF43461A5CD28EC6FB70CCEA4828A9DC6237F04681AB4CD3E9C69138B48459769E07A3F6CA684C299BF3CC95DF9656DF5968CE5BC91C87487A600236BC64CA9881797B626B0881903A899F945716FA32D955711F289328C66C518539DCF9B83F241347B11210E4A3DCEF1516BE12F9CE514C38200D8757220B30CA95B7682EB16F7A305F6580B4A764C23470BF159846E656F62DA82B8DB4828F7244608320F5860D02821DCB61415249779D4941A06BB88C64FB14B8FBA049960C2118CC9473F66AB577A953E283732C689506B4B4C95A4AC105AA418A144B2901180876AA4128424BAA807354E12631473B8E05C00D0D505CE454BD425A0A1443AAAF92FF2237BC0F7458EA72B6632A2B8B760E377CE48EA5A60E8C4DAEC0670102C4C747492F28F81069CD1D64345553F8CAC531F23B6556010F79B623AC6A8FBFBB68176C41D3609E73C65C1006DE04804A0F2222433A2D1834DC80828FB06C098565297B815889161A58C0D187454B61A1A2986AD7E07A6EDF27FB4626277892BD12051A0C263E6F94CFD388E1E32AC4DE308EDFB070EB60DCB5887FE7CA44BA4A39BA7BFB363C98B00B60A4C7781940BB69998032C5F6A930C1F65420B0C2BBAB954AE55CA8282B1DA2A61F1B111DF231DF1151504E9031B7B28E793109ED49D46702D25B37F58FA812F68508FE2B9EFC319A1976064A648BF7A251A948B74CA3F1985C5F114033E1240BF3691238B507BF28956A52204459EAE072BBE10431A56AF24AC15F8B546A62C03740C16ECC8AFC58871537C485CA93617A324F72991273A0549B377AC040AA12A46D366462FF7B76A429BB781922F7A5397385421424A24B366651B72C5F8870C21835E0B2949F61EB3571CDCB780DB683C95E23B708889303A4B9F2B862B68A4E2614EB2D8169ECC1349D9B71B5206973487660B6E4CF544BAA688202B0E8DF9AE88D85115F9A183FC95265608661993839914D9926CBAC8993013C59E979AA8444A54972B99257542E4ADB869CF56DCB305455BFEC5BCF64137B72B2A6C9B0DCC6C386ED616D6A25259EA612E89C21A170B64E379458B0ABD725DC8F53A55E57604282DD474C4AB30C4218A32B4183F0DF24475D01FC9F8550B0AAE3990BD414561463A023445BD23C7C321DC80EFF509A6155CD6B2059FCA448CE05D1F0062F3C21849E38A7A90BFBF15B192265F11B5BEF91A6BCD0823E2E1B414750E057583401B3A5F140ED7BBCB87BBA4B1AAA1AA75A911DAC26298A7B9A1830A48332F139F7A4A12A528B9486197999B5717CB8552B38F7F759BECD04970EB64BB4826A5CB47BCFBA7CC46CA17039F1DA30DEA436DE4B6AB76F43C06D1A1DB65A9001A1E0F510D7B4755137BB4C08A710E9A9D7FD8CB32D64152C0B85F40B9CB433ED1D7BEA1821C6881309642053F993739E3BCD38951433B291EA26F0948CB2DBBACC3088D58D42DE008AB581B0B3A9341AC18C28B131FD4E49964D72D65658C684472550A06E68391F8D34BC09A2F25161745C74D68681C3B333EA58C412F68B44D066E33CB7ED17253FA655603DCA0DE7A13C7C0C78C9630F5C57AE925AC97A823102C423D0B7A3AF864C7A95885E574D570895540A3793B3CD0C73B5A21660B64577D6B146E888A113BC44D78C175AA7EE72760F3B62ED7C971AE62A3E8F08CA4AB7DAA43C51A18CB72158DE398326589241F07A9E78BBE0C4CBC5DC388B03A7C131C885FB63841445469C42501D198D114C31DA36418985CA5D95196FA12B59599F90750E4567A76A767547BAEA91C6580A628C3C052C3C8BEF8755238C2B31D52621EA5579B649F6328695AF62AA8D28402A554941B11BAF7B54FFAB7BD21918A0A6D6A368516B4A04354B6A922901FB8A0E9BC9F7713B977226BD8477D5C7088B8B90AFABB61D0B32DE98529AAEC904AEAB8D0240BCF114C5E3A2A44F0043B628F03FA04ADDAC64C918916A3031D6808104539275901C8D8CBF17741A6E185250C7EB9379DE46176D0B6CB02621F97C083B8FC1DABC9A0CAFA9585AA848606C9CBC58B96DA5A8F414BC9A6AB4D9811CD3B3B512925BB5B352CB67F76C810B3FC79113685E85595D4C62D41633FA092C31FD3102102960A0024D1F460BE791BDB0B19B6610604FA26D6423864E93493066F859B86B6C2693A899DBC36CF667AB5E4D8278371CC411ABBA846B780090C7023A09409CC4541B4D8784BA0F643AA62336551525B315D6FB7086AC604B2272333C071B23595CCABB5459B6307B59786731008B14EA142C89A066D5E5C502724BC384013B5544A99AA872D5B65E5100315F70091D9AAE9D1ABA29C18A5549D11AA195D7046AE51A864EB4D69192DA8248300F985FB5742A8F0623859B2A7AA600FA835A0AA647EFB62B9309BA89A9C4B7478A8A1086D6C955834223600B65A80342CDB6788F09B138456773AA8A2B175F477B800C2803867253B06B5C5296D8CA3A4C85496FD9B413383C0CBB95880545C168099926C175BB6008B1ABD69505B8C782C9EE06877523802A936830C9E58145C6591C66BC56ABE2804B1AC28394B9F0DB695B15C560BF48DED5C54A47244DAF089975065B8AABC77E4A6D1178ED5B503A4CA40C2584E878C5C15FB41307AC297DA94A3EA7E204B8A4156489DF3577D74186D5255156AAE92F77512D0B54D1C1559B8866AF41EC7DB75CF658625F784AB26089A076AE52103EE3053ACC22A21A2920C65C10ED64372380292293F494C2C663A87D7EAB6EF126A4EF50002924497E70154426F8B9801B09AE930907E6284E384A1C6554B2BC594591397810B18D01BD3777534EC53D050D5A81C049EAB8F93E7768C39323DD805F12C6553C204D58CBC47D8E855BDB92F28D0393C0F7850C7F6C371BD4835D6DB61C138B0FAF22854466231D8", + "ek" : "F788047A497F4DE55C63673615847E3950248E3C56B92E384D1693996AA00968CC263A1B75150A5A8CA642295F5BA1487DD93FC9DD7AB8DC5C6A88B9107D9BA4B78542EA449EDF3FC60E29BBD04999BB9C2F8D5F2AC9FE8B024714392F46211CF6F51E4561A13A20BC3EFD5DF9F78B72F67C1B9B17DF428D5D43D7D677CBED843BA9716AEA5BC0A5313356D36A2BDCE95939113E526E9B4F115A68CA2884CCEA6CA634C2CF3BCD3215F425CE4F6F2CCF9628265BB3A5F1BDEAEBD5669814284487A90204478DDA40B31C7528B58E77D1C5A10A1C3CF5F77E543A5E6678BD40BE9928F9A6C44362B83853352232E6BCE87089E71E114C70CD855A548701306D7152B98DD5EDD7419E8279F9D73BE95F23293CD75015FFE92F54C047F63689D75476841B32AC68929D0C9A585EDE880C1F945BBDC2886087D31078B116D8B7326A82591D5DD993F977096FC51B7195BC3CD779615462F883A31108D246146D2C81B66586E8231BEF15B5373F6F1E90A914CD9BE3961D426D22DF2654224C8939385D2B73424DB9614D5DF5F105CA9B520F3F73F69AE3F34F6AA8CF5CF5AE981CE22484D12F1D80C6702CD44EB13B40BC321386658B2025BF2CEF9F06969B4474219DC5D28EDB5DA62146D693997A508DAB54E9364628A8E6788CE06D99B6F35088A5D578DFA3861BE97F4400C03102180773CF78A075B81CE63AE3FA84788D40776E3D5B5BC5477204392AB2EE685FFB26EBE83CB34B99AC571447370447A3E8081C53D103A756C60E7BF8AC37F29DB1649C37D0DFDD477A12DEB29E79D3468B75F93A488A0A1D81A0A4C0144CE7020FC60DE43CE24AF4B77ABD4C2F3013F023047836B241FB8AFB40B5E3D0C06FDE9A6A7CBF4503F7AE2CE48967516D604212709C266F6784A9059B6DDF3DBEBF7A3818DD686EC8224397AB2BC1E750A2AC1FCCFC56E5833A8D81A9636453E585C315631B8AC562057919AF3091F5E4B0E0730B9522B612C702758E94A7C4B53EDE2E75C3A06E67E4EA5BE73BA92FD6C9F2F8CE6B168701E878BF8C2B844535C9F783C41FFC63738A09F564D20AB2C7D3E0318CEC690D9D1962417B49B17F45149A4B82868E67825387FDA0A78758C65DDD5B6AD8951C38A2E0303113199A69F7FB5542585541B7C53009FCE40A2A983BF19B54866F15BCD3ABA6326E8027C6956A7E5B567075EFFF949021C9F8BEC194F6552CAD70FE30BBEE17D15B054F23208732F441D0FDC897E5BA6DBE5E43BFF0A5F39369E4530AECEE61BFBB53D7ECF23F9D073BD810A4E4B005517BFA8ADFC07982820277E32D035CA77F1867D3BD471B5C9D64E2208F2638F7B05822681E9F2BA86600BF5E242D680C3B1C2F98CEAEDD9759F99D273CAA600122CB232EB7F5E6364C383275E136F57B0C90A93D3B5069108EB494CAD0C43F9912186460E7898E64C66BE9A4A30F43081B865730E5D7A9DE9FE3C2A1D5ED40EFAEA6D17523B723940551563FB1A537B27DAB237F9F6ABFC2E22F7B9914234B1417D118B1688B5D251F527A2A16DA9850D141EDCC44B67648D95AF67BCB663B1F4760B8C1234D7454DB53C97F9795B6DD14BD543A3E2FB0C294FFB09753186650761AB9E49D570B73C282CDBF7145B08E002540E479C0BE008D2B8107A729085C60FD7ACC703AA405089BCAA39CB13E4D570A7F3309865A05A3975DAF537BFC7BD1E1F73ABF49EB6670168F7B95223A3C7CFCC590E0426A508991F90A6231F6AB395EE40276869EE7A1791D221B5349C8D5C81116BDB0A6E440E4C77E1CBE2E6FFAFFC416730CCCE7078C0E1B371752AFD3C6DB1CDDA0B852407FA72D262AAA183237DBB3DA4AD0737A0BD185C6CEF0FAB5B95FF35CE4310F963EF8DC5FEA159B034C2118935B0B3FADD805B90BBCAF6DE25322601CE00EE9CB1176543B9A89A63E897DF2336652D2E6B5FBA59B81354B1709B3FCC62A77BBF2824FE4A323E428650848CEF240A1F6056F295C0C202F0386F4434CCDA2EB8DE626FED906627EE2D2F68AA5C045C13E5199BB91610F715279947E0D6352B3E2DC7C7A39009B8CF51139D06AD77C89D020E67AB888F01BA8FA44FB8F0E41642069F21F7DAC20CE1E8A530575375E2760FC2B0B45397DF3B83BD1787D3CC5A0ED518D5D5E144E32E5B72B37CF8250BA2FC9CC0B30B8D6AC42BCCBF80FE9BAF785B55F8019CCDBC6E484F1CCC34DE7B0234C", + "k" : "3551120B66F62C655B60173AC4DA394CFB0661CF1035AF03D196C4EBA2763DA1", +}, +{ + "rngSeed" : "467F6158CB86B724039FF18C47950AE5C49170163C910FC9A9B30141F86E9C06EBCEC91497BCD156D95758C9F0C6EF91", + "pk" : "059A381BD53C19D170642535F7C56A2F6BBEA8B824A81339DA5945F7175D08C69784E67D5E079FEC9129EE799A1860BA58485ED631CABC19AD60934C192A27F9266BEF098CE2D847407826AFCB0AB43057008339C534B9E19C5A3542B40A3A88D41533B346754FC09FCE920ED73B2FD7048E540BC9AF49247122771FEC129BF133C3C3711A679353A9A0AD47C4094471AEE9619EB58A3831BC60257E07D09DEF864638498D3A731F24A814177801AE900B5FB6CF3374320A261D57C170DAB6A473C86036733E85F290C9AA4CF7B56011C61723839B1E7C629C7CB5F4E4BCD1D6C9FEC583D4B78670FA7A53F65B9FD0A91CC6620A5C1129339CE2A93A66618C1EC69E584A0E9C283993268FDB1C8EC25669439472D409447B6A04CFD699D167252C29AF53EB27F6C3950B456861B7AD273887BCB3B41E75BDF2962B604BA62852A92F7B192CCA7391ACCD0AD0BB65672E66317AB82BBA06766917455F7FEA8AF660CBF6E3103F7A60B9736BF897B3A53C9BE798AC0C493911B835B4514F3E095A49A474C0C907987867CD11AE24D22D20EA24BA028F02D1B295605270C00C732B1C19658AF0424F2B01B7C4B8896E6706ED564B87F21AFB1208F9F85E1B40244D622A5AA461C25B0319567B7CDAC03D9BCBCA028AB108837150A6426138B1073C348A1DE7ECA92ACBBC0A95AA88864D734BB90CC8B8DBDCB91C4C333AE46DFD8353C27438ABAB8A60572D19C5BACF6B35A50B86E80A7B9B44BC74F74B050C2D6965298D33150C63C7A15150FB66082C851637568C2E5A9952E7AD62436E8401A0545C6415A948ADF1449A51779005BB08BB75FD518C2DC02ED5C0B63DBB35A37612EC44B2A04A3D3C15414C0193EF5C09AAC62D1CB212BBC7BC7B380BC88A37AB103D872605BA7883CC0BC83A20B2CE28A31A3B0BEC216B7B1419BCA5425E255B25A86DDB5BA95900C108F036A9BA2E941A1966B225B03CB7335901E6D32613B54806C0C737984DA16284AB0B4594B0734FE5C6018C047D238FEA777538D49992992D1A012F4A65008554405E3C0BF8D386C2EAC5E07470D4D6015DE45B3F99CC1B9B6F8E459E9987B773D69E3783B520D1282B177EDD9C631BB4A76052C8EAA8AA1BD62269A2B2D7A6BA35B1670D27BE1EAB28D1571054A67E94AB3ADCCA05EC609B5171A1D4AC1B3A2876E33B7218C7B1A119812479C4974575208540A0831446A7BE7AE0150859AD521A0D891B7A6CB9CDE236B48868C30ED26391410548EB21756C3D9EFA564DF5780FF7B1B1F830BFBB70CE7181DF82ABCCC941F1D79B6DB3A012D5B7CE5B7EA9CA24B387CBFC34400D47200BA07D5F82C28991B289F56361F31330245F264149C9567FEB569F4E2C21CD9B80A10A1ACE3804B899410D912D42A9AB68B76C2B4197EC5ABA066453FCE1CF04D2A315961126CC04FB63361E137A258832679865CEA937CAB03534746918080B1B92CD099622EA137E4D6B0B30D18BA27582775398027BC54FA09D7A23655655C491F23181816D45437BE2892EB73958B56899F25B3E48874434F12A0052518F3CAF11215DF0BC3265D648935A68806A75617506FCE900DE0CB07F7686223B9990719AF5252AC61A6C44A7655F54585ABB4D26E2AE5192C2381009B4796C87097C2657095AE03B924653BFFAAAB6B9035D176FB34184E58227A64059F54B44FE62A68C7A0E798362DE1966DB1A982EC3AF25EC20F3824CAFDB53CB526F055BCABE72A9E807079046B57EEC2F681AC8EBCC0734A71EC65224E4A80244340EA1D339E44C7E2C5717208A034E9A6791888C9968987E710FDE215207EAB3F38AA49195190A885FE75074E17920EA64B6FA077336AAB211FBB757880DBE36247299BB8F65C132E48C54D47ECCC7AA124547C910831BD98B07BB1F435AB7C96A4CB9B46B36B6B667DA4EB7CB2A12F1BBFA88B98F3C6C3704BE3F000F65562D7D4C4977AC8C98AC44958C28F65280AE68466F6B7495650CDE4AAAC4C68E07767D09F44917B29DF63352DCD76C1E393E0D5067C76855A989B04547A625762C730624835A6636191C83D3836BF74593839A83847AFF3BCB3AB169F65000C6AAB1DF08994E161861498FA2E42D1203786300ADB060A9C2429BC7325ECA24279404AC3C934EBED4991502BD669309E7A76CF09507B31FBF659DEB7BB881F5358D70595C01FBC7AE7183540B7883122D67BA", + "sk" : "08D1B85A3B6262A96EB593935CF9AA02B2738496441BE27303DA5E8A5BADB4C23FD7C2873C28429C7778A3F41C430786DCC92E41D41AB97028FDD1A87914190B210A0A108C74C86597F280AE4195B39A00D7A35A210B80D15C1AA54945887634E7DB73DE2945355227B86970BDB0ABFB8BAAACA1BE8F4382E36C0C3BB972F68A5D7E089ED430C977D4836E3A18116584E1C860C99277C00B51E6480BD78004AD660BD0002FBC4B04EEC53DEF499DA022741D96BA4277A2DDF1AE2D309CC9CC3C76C28BAF0180B03B4D5751572C2253E5E033114A81580B960059B6CDA77A06D990D2FA285D7694036B3C714ACD7C80A6E7A28D8BA01075B65772E65843E679702879E4D77FA61A7018DA1D14B6664B0133506BAE1840A6F2EC8897EB72E22874CE275EC4A81DC1714343D31A0E99CBCD497DFE5376D8E3CAF40683F7491F1FB85EF9A43587E07D21196161B831B0020C643845FBB26101389FFC83C88DE29DEF6B550B683D374C26883C4807B51A23110EF6B8C16EC95E0DC03F7FB6A8EA09A83CC4A82FF4C7E407271ACC2FB3943A3B0A1571D1C060D80977770D0BC17ED94679381984DDD7460F782A8A596646A49C48E59B0890A99768740F1C66D58A7DD7F88F27DC4F41B28DB4BC240ACA187371110ED39871CCAAE2972653DB394312793458208A29CE6A676498A100A5199EC642853E4661247B0FCF60A218F424A6831EB2488300542F1F354863DB3E32878758D21FEA35B06C79787851A61DA1786BC45008085E87EAA72623CB41A28200ED0B4CB86E77F510F4507C6C321891D455842750E933967890AE10E91B0EB5B23789CE5DA58EE120B965D20765830F9C4079A64848708A51D1826CA3425E0EA31727107C2AD28D1E8B0A6559094CD5C000C271E70B98949359BE468307526F683A32DF61ABA0821EFDC289AA273A9166ABFB4ABDB6C0A66CD444F349C8C2015CCF5CB3F72A561CC37BFC210F8EE4B0B89873B67506766383D279A2F1D28077E91F6B4AC289D3BC3934766AF53D2F238EA8227E9E9226B4F7A8C47B8FC5874DD30C51A1D61235BBB5DDC7B22511A776359EE18842E5B8341CE045F6CC9EA6922A0BAC7DB004217C0C234B52C53A33C03C8B1990F29FB2816D7AACA9F633495ED0AEEEB112F180B2D740B550550D8FA56B9EE659420A3575AC40C3D2041E01BE4E58824B2BC85685A5BFC7289494175B81626C7B88530BD031C68CAE15A76C510310B161229CAC449BA38809BE3446734A84080473C80A58C3E1A56AE49B2EE802A896C3C051D92EE2BC7DD9478E5954AB98202A2403CE6BB3660E20C4DE2C54289963F2CBCB692349A8A7B6676413105923C6C30A557C958AE16C03D7817A963230692CA16CC8CDE66A8B0A01B0D63B58D76B7D76B078DB1351931F0C23673C275A9FA87FED1A758B9302D8E65567CA508452B3068A9F3ECCBF53F44CEAD8103C3B0D5DF16D605B7FF9296434692B2A8C079BE8659CF507E8D59663E6116AC03B43F54528427176A354420212F9208ABBF933679C9C302C39FBF777BDB21C197065FADA38B9797586E61327565E40113CF5980A32936B57AB0719A837D2A394372230D9F03A9AAC0C8CB6C5491C7EA371BB17740BC76B851D77488C3B4C21D9C510B49971E11874BA9C46E3AF7B555163339B3C739E4349291E931BB2C9CD86FC44F0E1911C08864CF3BB74B3484F0A7A347CA8FA335C58A2AC4687A33787C1B49B791C026C7D4B1ADCF13B4C7A51E705C1AE114E527690B2713234D089FC35B880027215784D27E50E6A513598EA7A47BBB574A31D872C3549D307850B80DFE04350B814A297340FEC56662C7131D99AE573800D0669BA2B8570119D69F30DE12535CF05ACD9E8B66215B6D2979EA7A64C25941C69C61400A62AF40412FBEB1870319B37BC75D9292E2E6A76659C87E22CBD01FAB946F1C855BCA6D3D052CE42659C8C98D53674C83800D1776279A494C44617C281631DC9A338545F14FC1B7B7B407944786F8C25F69AB5E50C5D4D6315505C5CF03BC23B454D2427501A13C813CC11CC76681B90264121AEA8594BF087B474D821EA102C7014A796429A05D38A1A4B8E6EF8504591BEE10A3A7FBA19C9D8122C4C66503462B3A14E99144257203F76CA484FEC606CA158A8E29D944760059A381BD53C19D170642535F7C56A2F6BBEA8B824A81339DA5945F7175D08C69784E67D5E079FEC9129EE799A1860BA58485ED631CABC19AD60934C192A27F9266BEF098CE2D847407826AFCB0AB43057008339C534B9E19C5A3542B40A3A88D41533B346754FC09FCE920ED73B2FD7048E540BC9AF49247122771FEC129BF133C3C3711A679353A9A0AD47C4094471AEE9619EB58A3831BC60257E07D09DEF864638498D3A731F24A814177801AE900B5FB6CF3374320A261D57C170DAB6A473C86036733E85F290C9AA4CF7B56011C61723839B1E7C629C7CB5F4E4BCD1D6C9FEC583D4B78670FA7A53F65B9FD0A91CC6620A5C1129339CE2A93A66618C1EC69E584A0E9C283993268FDB1C8EC25669439472D409447B6A04CFD699D167252C29AF53EB27F6C3950B456861B7AD273887BCB3B41E75BDF2962B604BA62852A92F7B192CCA7391ACCD0AD0BB65672E66317AB82BBA06766917455F7FEA8AF660CBF6E3103F7A60B9736BF897B3A53C9BE798AC0C493911B835B4514F3E095A49A474C0C907987867CD11AE24D22D20EA24BA028F02D1B295605270C00C732B1C19658AF0424F2B01B7C4B8896E6706ED564B87F21AFB1208F9F85E1B40244D622A5AA461C25B0319567B7CDAC03D9BCBCA028AB108837150A6426138B1073C348A1DE7ECA92ACBBC0A95AA88864D734BB90CC8B8DBDCB91C4C333AE46DFD8353C27438ABAB8A60572D19C5BACF6B35A50B86E80A7B9B44BC74F74B050C2D6965298D33150C63C7A15150FB66082C851637568C2E5A9952E7AD62436E8401A0545C6415A948ADF1449A51779005BB08BB75FD518C2DC02ED5C0B63DBB35A37612EC44B2A04A3D3C15414C0193EF5C09AAC62D1CB212BBC7BC7B380BC88A37AB103D872605BA7883CC0BC83A20B2CE28A31A3B0BEC216B7B1419BCA5425E255B25A86DDB5BA95900C108F036A9BA2E941A1966B225B03CB7335901E6D32613B54806C0C737984DA16284AB0B4594B0734FE5C6018C047D238FEA777538D49992992D1A012F4A65008554405E3C0BF8D386C2EAC5E07470D4D6015DE45B3F99CC1B9B6F8E459E9987B773D69E3783B520D1282B177EDD9C631BB4A76052C8EAA8AA1BD62269A2B2D7A6BA35B1670D27BE1EAB28D1571054A67E94AB3ADCCA05EC609B5171A1D4AC1B3A2876E33B7218C7B1A119812479C4974575208540A0831446A7BE7AE0150859AD521A0D891B7A6CB9CDE236B48868C30ED26391410548EB21756C3D9EFA564DF5780FF7B1B1F830BFBB70CE7181DF82ABCCC941F1D79B6DB3A012D5B7CE5B7EA9CA24B387CBFC34400D47200BA07D5F82C28991B289F56361F31330245F264149C9567FEB569F4E2C21CD9B80A10A1ACE3804B899410D912D42A9AB68B76C2B4197EC5ABA066453FCE1CF04D2A315961126CC04FB63361E137A258832679865CEA937CAB03534746918080B1B92CD099622EA137E4D6B0B30D18BA27582775398027BC54FA09D7A23655655C491F23181816D45437BE2892EB73958B56899F25B3E48874434F12A0052518F3CAF11215DF0BC3265D648935A68806A75617506FCE900DE0CB07F7686223B9990719AF5252AC61A6C44A7655F54585ABB4D26E2AE5192C2381009B4796C87097C2657095AE03B924653BFFAAAB6B9035D176FB34184E58227A64059F54B44FE62A68C7A0E798362DE1966DB1A982EC3AF25EC20F3824CAFDB53CB526F055BCABE72A9E807079046B57EEC2F681AC8EBCC0734A71EC65224E4A80244340EA1D339E44C7E2C5717208A034E9A6791888C9968987E710FDE215207EAB3F38AA49195190A885FE75074E17920EA64B6FA077336AAB211FBB757880DBE36247299BB8F65C132E48C54D47ECCC7AA124547C910831BD98B07BB1F435AB7C96A4CB9B46B36B6B667DA4EB7CB2A12F1BBFA88B98F3C6C3704BE3F000F65562D7D4C4977AC8C98AC44958C28F65280AE68466F6B7495650CDE4AAAC4C68E07767D09F44917B29DF63352DCD76C1E393E0D5067C76855A989B04547A625762C730624835A6636191C83D3836BF74593839A83847AFF3BCB3AB169F65000C6AAB1DF08994E161861498FA2E42D1203786300ADB060A9C2429BC7325ECA24279404AC3C934EBED4991502BD669309E7A76CF09507B31FBF659DEB7BB881F5358D70595C01FBC7AE7183540B7883122D67BAFBEEA6F8085943992ED8B051CF758A8B8166C1A1E5F818F0DEB30FA1FA061904C95DF27DB27FFD4A8FDF31C4474CBFE2F5EF99F760E97FCF569D8AB22C2855A5", + "ek" : "440FFE5047FCAED0B197853251FE77C80CB17A7903486C24A0679FBED4ABD2BA3A0F2206351A07CFF1FBE3FE72B94AEB4375827814B143095DD73F396073DDAA2BD3A8DA7EE4BEB3B156AD18A9D6549B51332AA3D53236ECBA7425D0AE2486E9A22EBC88E2085F2D70ACBFD881C8359F23BF4044EAF3E98481D176912F9714FB478D330557222CB2452AB1751A086168DBACDC48268E1202580ABFB4715943C0F1D0E3CEA1580740D12449A147BF5A3731582A9DBEA12158214AA9A069587896D95EB12CEEF6E441049DD7F97C209DD07117896E0A36FDD915AD7818F16F774A364F6B9A97DAE7A67C016ECC1DF11D7F0007D0FD19C8A383802B78FC6A7E4C29E6C04472ADFF7C116272BD0DBEE05480454F63946679D722F017DAC31074C1FC4CCC35A7F20DA31375263DEC6A8C4CACA0F8199E0B86A51842CA0053A2FB42FF5876B9C63C7AA4D912FF08B551149C04A5D2EEB44FD276BA771BD426FA1FE35898236E24EA44EC4E81F7E131D99A74F3208C3D7C1C6EA8A730BA5772F8990913556C41273B121CD8C215ECE9082886026CBE4247B9A14E7C21AE075A68150B60A467242DAA2EFDD8FD4FA961C61327F928EF8AB2408F9D4399365FD0D9F7441C2EFADC3AC0A2F4A00FF4B820BC4FE375B7263A809F411BA1C7B4B03957AFBDC9745E05D797359BFB5964CA2E1FB973751C785678566C88D9709B6E1592F609748AA15B41B5ABE2BFFA4CDE2FA899D4450B138AC5F36DC00AB632134977F1A5DD5BB49BE8F8493D5D7FF23934D562A5698700398297234F7F1F88C57247C213F19F4ECE74B78802CB9041A3BB45708849DF96D3FA2314AF4F3E5C265377F67B8465D568196185B726FD23339200B460AE40FF26B29D19BDE9DF6BA62C37BBD44EBA8CF55C179F4F057166E7483B12D988CCF3F561B0A127AC38EF9B9E949ED6776412684471B446588CE862B0563C038CC8F47B9337B8F31D6E76AAF5815323F6FE2AE1BAC3EAC978F817A558B2C80A0B3A785A4372B01EA8C8F04C00C74A83554D25732E7FB20BE1AD57249E61011C4C4CAD67BC54179432CC5B0B0F5D25014D8AC0566001126573AF3468A93ED2A9470AE6EC4C46EB454DE10CEF939FFF7DCB6E7A7AD98C8EC02E5F579E4F1477A37A8CF167FBB1D23DA9286F8AFC9575475E305F40B2E2D9E520DA6335AEE04D6D4D2805318BE4876E9504BAB52C216FA548413C9EE06CFDCB8A40ECBC32A8A1A8BC012CD4DFBD1DA3FA5D2B93CBDB4936F258A354BDDF2323731E2E3BC65E73B810745D293AE526C6F36377A13976AD3F3462A487102AAC791A3E9DC2DA621EC408261F09D1984B13CC020A55C64609D031D4A0671D12A70FC1DA5BA012EB6C8DF81365FF4023964BF2C9EC19A494EE6C1806ACF8FD741013874B94298D438B8B7BB504693827CE6E7489305BDFBA815DF6D5432863B1DF348B661B5448D7FA09CFF46AB2429BB03CC2A42AA62711E3B162E620C28B8402CA72C1BE1A72313672C75D3EE4CCEED6025D7A46CE9B3F7B663AC2B29F3254D627BBF59950F437FB836821BA282E9B3B4406469139288F4DE98DDAB26EE858441923A54E3B8696D2C72DE9371E3E5414778715050EF914261B815A6FE1D590137BB1E148E3BFAAC064CF727340157AB3C31FE0BDA72557C3AC0A1492BC5F95DE3B1BE8014ABF6B4D36E0E740CD32BDCB2E413DC2E8B1AECEE6DD5E2EC78E1A1719A0FB244393926CE1E7B20FCC9E824C536BFEB12DB0E5F1BE07FB21AC1BFB507EDC4104E85C3A723F93D0B945B2BB5BB0AD6B3588E1277B9BD48E280679D0A1518DE8A061210EEFA923CA9484F7E2DFF337A06F1568CB44413858E5764737831092574313D08FF377E1A51A094EED80BC9F22113821B174F2D93BFF919B231B677EC13C2E129F93FBEAA6E1933EF8D5E8A10DFE89C6D2FADCC26DA661373E4F26A4EEF814C8712C5A974E3D133A98E521C69E6D9C9F4E1B41A077629FA3D3A2BB35E0AD81F066307F74B6430D54B3C096ABCD6D58C5EAE820C09E0293FB6DE9363B472CC172CD94921CAA0F6EEE24CA39115B93C3848B893FDC0C03EFA463A731DDE63D7D6E06FB559F81A8EF82342E98325101121DE7656DCD85C4DFA6ECD1F8DFC7EFFE59D3763D81C36E64F4A44B31681620A9B8FAABC69B5F6EF3DCE4BA18EA93DA4F68BB4EC170D0BC85B4D50123ACC96E4BCD6BF260D0", + "k" : "AB618B75400EC21C94921C7861693091DEAEE59310A1E76D0E26A9C0A59B45E5", +}, +{ + "rngSeed" : "687C02DE1041ABAC7B2C1E6EC2A7C3375552ED5EDB10E3A8139C24CC76BDA44D719D8121A81D47A0B762B4E9EEB85235", + "pk" : "128A170837C0C51758A801316881C56D436839E5778E79553D97C6C48587BAC980E17632F7C7AF3DE5A9B15CA6D33626254A9E83009442289274A4C860F42C86D8060B2821C873AA5CBCCDE4540A8E5A6784AC15E6B30CC71A8DE57A83BC5924D0117BBFBACE8AD5CDFECA785EB224BAF8361EB64C81453FDEB54E4E86AB4A397ED6E84B9BA73A0C4B8B606318CCDACE61B70DF22C4518F463D8342BA6FAA846EB55284995F36A7467385BC8B77689807EF511122D12066E12619E37C8AD0872D5710083A2B9DC7107C955623CB209139034C9B3C6CFB7B3133502621662A61BB63B9C3A4586C2201516EE6C3F2D25026F932FC13C5426D64093CBC768985FB8F70B6871755F8811C60A4317A21ED8B5A7E51C1784B562C2A244065451E22935BA9C3CA6A63DC945CA37489E317ABBB02C9E87B6B7092B1B4049C603F087D3596169BAA2C6E3A778E61AC5F04962B61AFF07A70EA72800A0143E9C43F2972908A27E0F3B627BF14841693613711115BC19659C5B3DB6BC19AB7BE40C24D5887D93E6B7D31899771244C756790EE881FD605D1383409D608FC1A10D6F2511CE815361A66DB6244BFFE1B61A46A888A06F3260409239ABBB9C717D76AC4D658E728977C9F09BAE86105D796F0BFC4B87385EFCC791ABA5169C679DABE34E1EE44EA66AB3D58724C3E7099BD80A9D52CCA8BA95F9699C3AD8C90199A3B9613CF9652A79CBB93C8C949DFB0A6A7A1FC5E4A6032247B7885B3843A7AF4C7BD49068228875A002321530BC6B5076D0853BE448A8A85A8BE09B94E5D65D3BC2194A977396D71924BC5B420AA6283B7ED9AC822C27641C811777A8550168468892987E936488D71C9AF0A8732B6AC23ACC23C2BF8719BE59B23AA96110FF02AF63858B7405482D684848D83FBF3B317217BE6BB750CAE74DF77A8DFD32539E8964B764A100688301AC20A95306163CA391D33052E7488CF27D4DA5BE786CAF99E294BA1782D462C446613A15F97E9F5632C524CBC0430382E828560315E6BAC00B35C084740DBF159809849F8E104EAA28ABD5F6978F071D53279C4689C77C43C0B649B8AA042A9C8CA968F28C81C211F8BCA19269A9D79985478707489CAF7690B529B988471B12523405DB659014138D9A6133171C68961A327099477759261C523F9BA6A008D3C14B0A02295902637912BF1230A8B763AE397F805C2CFB4228776443645274F5C01515986CDBA31285F9C72FE7634C0B44A42150B1DC75D8CC512D503B3EF7487371B70D50B9650360F073936398356CC3419F1225A3946A61BB38B2E61F0EF85D1686A29E56192D8A26D42A22F274811DFA1C1C4CBFEC8323880523288805AC98000944B667346E173611FCDC3D474B0C30B0620F69B3D45321D9C91A130CB6842659A6A0904BA598AB706336417E17607E865328CCB035BD0646B023C3545C2B437463CFFA14DBD86EE12B8EC24375F5B4A3A0548EB9997030AC092A579BCB6A0A984C9F354312931C653242678E98502A519D15E64597FC224101CD9462ACE9BA56C421B692668976B3A170D88C4501147E6C68EDE8A29FD4951D32AC9DC06F700CBE9B536A476736B1EAB14E2493C5A94A07F6AB5A323EC3E9B9F639258275523FD32071739B585B5D8657AA502262700998F0C5BA71974C35573F14C13A70842149C077624737E5A06D52863D63F815D57ACB4F0142C9167D2784365ED78C9F6B235C7368F2B26DAD962E05F2279CEB44784901DBE87E413A04F462B4395B5E2264784C2BA356935DC1AB3C104B6BE09B08941A02512055A1D70ECDC281E09C78214A0E57F2CE035947229181B943C5380B7E6F804FBC815A1F3023E4AAB03FB4B0E2C459F58C348249ADC6B4A5474622C3262B11814ACFA872BB6C79B3614E3AD2A1516A0B0DEC98F863CAC0B061670CCD8D0C6F7EECCDAC933BAD47CECEDAC3A5231EF1C040AEF8BC53025E0DFBB3D5C6CB2AE96F11A05DCF8885AEE9756A13CA0C1280C4D331D50B850B6C00999360DC585E1D849114B13F3849B361F7083B5B3DB470796F5761F7641A89189C748B4F6B88822EC85B04228F04A669C495AF4C091B54A3835B379201D9C7273557F73C1E357588B68BAF3E2A5C88AB0E9E057CDAE06CE672C84B2A04503372C0F370D114AE10F97052FB3BA450D323FD3BB1B887FC4DA6DBFEF06BA5A2D5344FEEDE346D1F04AD60895AB5", + "sk" : "59985866133CAF531409205B859B9783CC2CFFB66F52973FF226822187C58234AE920A4CD64665E6E60AC668A793052EB07981FD99C6592090E2286F0C405308970DDF93857E1C8F202173AA886FB54C242EE64167E9188C797888D1CA74604EDF6A21F38A8787B5CA07B49A7C491C240050D8EB234D891A3E120165BC1BDB1800B7B32C254900F9E36E40CB55B4D2B366D99F1C86304F6A970941BEC4D48905B33FC44564FDCCACD60993352A215DAAB12A93417D51A3DB6C9AA1A0C9A7D7B4A2EA121CF483090BB855048CBB6C4051140744919E4BC651B5007E8F3893C6AB6D745334918A2407A75557EC6B2DB1CBD819509958C255776158F4AB1BE64E3E431EFE786C8C941AD91936F1E37EE396B8609B4E0781CE842C312B1CA70CA80690773455421D50F49401A16FBF47192CA7649E3989E0546A662A84E1904D82133DD2FB83CEB959F33C3E9D46B69A107EB133BE1297749386BA7CDBADEEC0508256B126F801138A17A0488CCCEA64A0238384BA53AEC7B342C247257C5FCEA471D6123C942B312B486438351AC4B5306C6699BD868087348DE8F22F7F714BA3B74BA9B9C63A9098E45C1E37F2A4DB9C5B9A8A9F662A2F3FB1BDCD48CAAF1B5F01574DB0712A34429A87690639FC148F984434BA7E35173F924A60DD70208D74443921AE4805B03C77BC48BB7B3B0964E9C743D02801B7A727025A79104C8EEDFB80DF6552F7038A373283D7A38B6CE430DD8B46CE067D0B699EE27B1690538541D28742A125BD2BC801A660410492707ABC70725661F16B9EA10E7FBA2DA2D256962887C2A12D282907220456CE8A82EC163A54C97F4B7A9392D004A64731CA6B883C94A836E0539DB41E36D9471CF13C0CF343AD250D05A26966898505A161A5910132D747FCA047B5489A32245868778A68041B6B7870B0730AFCA761E640059D200F7A8948294991E6954E48F41E5F039072337AA5F2B3EC4BC2F1F12EACE4BA397230861773EF628D3F13654352ADFCC7C1E91510E22A4D0AD799C94A889562145F1372AB85BAE981023458AD1BB9859A701AF2C2149803058F435B4BC18E8A62C68C355C8B8450DFDB345D47A2585382E13C7D2F9A8ADAFC4643F642D4A463ABB34C25341545816C169527641A63D85C0180D74A09B070B182BF0921AC8F59C5DC194EF8B93A0235CAD649B781C58037E6153128BCA0699D0B9494DB44407F5455CB013D1A9073DE80A128E04CECBC639C64898D022F3C0B514408C8035CBCA60C4EADE1BC5E9873EF1612890C0A253A6C34F0CF9F9CC8AFE65737523CB83A90DE44847102CE96956CDC988448F7134AC791FA44C0BF760E07B05482FA1443E72505E1B2E4E73F6BB775C3A1072BD62452D7994056101A63467DA7511572142DD703AEBB4BC4723988C334F4F71BAAAA8ECC764ABFA43273EBA82B46B53F2B0F59F88CD2D113E49B52FC740EA0A5026BE88739AAC300E2810379027CA3B5467413B3484578062AA6B01FA91186BAE66D3994CD41C191CAE212A546354C7BC22D169DEE7132A8C53FB6DBC4E81AB5CFF448F5E7ACD9C5BDEC7C61B14A8671E45305341A4B8416798138A475154000B1424B4C2579A630A0968DFB7595C92C42292C5798B6CE4693C7566877E2725DBB5871C51FDE7B2022F28674D11D5C86C0A1874099FC192AF6B4CDC50843131C232C59E6E48A21DC1B8926B40375B6EADC7F11A8713E08C0A15220001469DA3A84A8A802B2737E596BACAF674C29D72FB1D463286CC3916B064E076D53058A5F86118506CD99E8372996A8E32A36CEB31163694BBADA95E9C36F02851D379A3522F638F737723F2B840663A60D2A8E25D49DFA6670B997B361394E9DB653B269C352E5135ADC008BA82CBAE431F6440C8AD9774C181DC0C07B0E0A326758BC536CB94C0C4D3E5490B6F7158C93A1B93915CD70BBC78631D9D8A34BB2C383CA2E1A59859C51306A50B8DA12C41467C6A89CB6E4506D1DA5177B2B443C644777A74E96F65913589582A8C7ABD99876F48EFE540CFCA7A88BBBC7784C2815FA82D3F17645FA632017C4004A5846503C9BD629850438D964892D0208B67903DDFC5476E50967A665B4B90ABE8795C7A234B2759826F9B1AB846D5F763007FC93107B1EFDC7A2876488B19554D4D3A9F08B82128A170837C0C51758A801316881C56D436839E5778E79553D97C6C48587BAC980E17632F7C7AF3DE5A9B15CA6D33626254A9E83009442289274A4C860F42C86D8060B2821C873AA5CBCCDE4540A8E5A6784AC15E6B30CC71A8DE57A83BC5924D0117BBFBACE8AD5CDFECA785EB224BAF8361EB64C81453FDEB54E4E86AB4A397ED6E84B9BA73A0C4B8B606318CCDACE61B70DF22C4518F463D8342BA6FAA846EB55284995F36A7467385BC8B77689807EF511122D12066E12619E37C8AD0872D5710083A2B9DC7107C955623CB209139034C9B3C6CFB7B3133502621662A61BB63B9C3A4586C2201516EE6C3F2D25026F932FC13C5426D64093CBC768985FB8F70B6871755F8811C60A4317A21ED8B5A7E51C1784B562C2A244065451E22935BA9C3CA6A63DC945CA37489E317ABBB02C9E87B6B7092B1B4049C603F087D3596169BAA2C6E3A778E61AC5F04962B61AFF07A70EA72800A0143E9C43F2972908A27E0F3B627BF14841693613711115BC19659C5B3DB6BC19AB7BE40C24D5887D93E6B7D31899771244C756790EE881FD605D1383409D608FC1A10D6F2511CE815361A66DB6244BFFE1B61A46A888A06F3260409239ABBB9C717D76AC4D658E728977C9F09BAE86105D796F0BFC4B87385EFCC791ABA5169C679DABE34E1EE44EA66AB3D58724C3E7099BD80A9D52CCA8BA95F9699C3AD8C90199A3B9613CF9652A79CBB93C8C949DFB0A6A7A1FC5E4A6032247B7885B3843A7AF4C7BD49068228875A002321530BC6B5076D0853BE448A8A85A8BE09B94E5D65D3BC2194A977396D71924BC5B420AA6283B7ED9AC822C27641C811777A8550168468892987E936488D71C9AF0A8732B6AC23ACC23C2BF8719BE59B23AA96110FF02AF63858B7405482D684848D83FBF3B317217BE6BB750CAE74DF77A8DFD32539E8964B764A100688301AC20A95306163CA391D33052E7488CF27D4DA5BE786CAF99E294BA1782D462C446613A15F97E9F5632C524CBC0430382E828560315E6BAC00B35C084740DBF159809849F8E104EAA28ABD5F6978F071D53279C4689C77C43C0B649B8AA042A9C8CA968F28C81C211F8BCA19269A9D79985478707489CAF7690B529B988471B12523405DB659014138D9A6133171C68961A327099477759261C523F9BA6A008D3C14B0A02295902637912BF1230A8B763AE397F805C2CFB4228776443645274F5C01515986CDBA31285F9C72FE7634C0B44A42150B1DC75D8CC512D503B3EF7487371B70D50B9650360F073936398356CC3419F1225A3946A61BB38B2E61F0EF85D1686A29E56192D8A26D42A22F274811DFA1C1C4CBFEC8323880523288805AC98000944B667346E173611FCDC3D474B0C30B0620F69B3D45321D9C91A130CB6842659A6A0904BA598AB706336417E17607E865328CCB035BD0646B023C3545C2B437463CFFA14DBD86EE12B8EC24375F5B4A3A0548EB9997030AC092A579BCB6A0A984C9F354312931C653242678E98502A519D15E64597FC224101CD9462ACE9BA56C421B692668976B3A170D88C4501147E6C68EDE8A29FD4951D32AC9DC06F700CBE9B536A476736B1EAB14E2493C5A94A07F6AB5A323EC3E9B9F639258275523FD32071739B585B5D8657AA502262700998F0C5BA71974C35573F14C13A70842149C077624737E5A06D52863D63F815D57ACB4F0142C9167D2784365ED78C9F6B235C7368F2B26DAD962E05F2279CEB44784901DBE87E413A04F462B4395B5E2264784C2BA356935DC1AB3C104B6BE09B08941A02512055A1D70ECDC281E09C78214A0E57F2CE035947229181B943C5380B7E6F804FBC815A1F3023E4AAB03FB4B0E2C459F58C348249ADC6B4A5474622C3262B11814ACFA872BB6C79B3614E3AD2A1516A0B0DEC98F863CAC0B061670CCD8D0C6F7EECCDAC933BAD47CECEDAC3A5231EF1C040AEF8BC53025E0DFBB3D5C6CB2AE96F11A05DCF8885AEE9756A13CA0C1280C4D331D50B850B6C00999360DC585E1D849114B13F3849B361F7083B5B3DB470796F5761F7641A89189C748B4F6B88822EC85B04228F04A669C495AF4C091B54A3835B379201D9C7273557F73C1E357588B68BAF3E2A5C88AB0E9E057CDAE06CE672C84B2A04503372C0F370D114AE10F97052FB3BA450D323FD3BB1B887FC4DA6DBFEF06BA5A2D5344FEEDE346D1F04AD60895AB5AAA698C34E1B3B6EF69049A883160C66533C8A65249AA35006F003D4EB4350A4284FDCB2D2A697D75E985AA43FAE0DF266A8056C18CB0BBB52B4EC89D66C21E8", + "ek" : "ED053DA51045C3454608A46928D9A1BB28C5460D5297DE632C113025EF853FC1F21778044C8F044F254D0A924760E5D923D8F0FA9F8B0392848F281F7E8260FB1B120D453C31B6EB80C9BA119A839DA40288E3EBDD6785E73D23969362E02E8B5FE0FABA1720E9E5686E2B8E6DA3F20B3A3B6EC5F02A1784AF5D87DCB1BB06B1EA0C5C8B636B4A56D49B86B063AD1575C88A36522F47D18CDCC91BE5255A397100F1B0A37E2F6F8D2E9E56362500576D1AB1757D528F111B166E5F95AA4B247449846785DC4BA8FA110D61A17155309D2C1937F0951C32A19F49A9942736F358CE0B44D0B3BE49DA4A0FEEE7A141780E39D850A4DC8BA84187ACEA685611EEB4660CD8B4AFEDDED50A8D2892F8D12E4BE8860B546E17F595F1F37FCACD0B1FF8BE0C5CAC11D59C948C0545022BCC3C011203E02099B5BB63DDB3CE72BA99AC9DE56463C4489410611DD8DF8934B29ACD7D4BF2E90890A6F2DB501C81FC06F8EB6DAAE8EB548DA947D91EA7878E7C33AE14A00F378CC335C0B12FE32F96E561515FF8E788897E38B14A506A197D545DCE01A92F85FC5D7878BD56DEFDACCAC7B71C1C28F6E7AC3697D92CA7A6B4E5EB92354FD004DE23AF20F8C2901AF90ECD5AA53A2AC2D7A80BC309A28DAED5DA865361FA8A00452D50C6ACE6082BBCC7904B49E208A3354B2096C64B6B7C5A537F246F8D1BD930E4C142F96E48826336CDFD3600298BCFE938B9BD0DF02A926B2F39151B914EFA1C313581C754796685F245136F4605D9D9D3CD71D0314F1F398CB67E9E26579F34770FE03D25A53EC217E3B1A5EBAF0269425ABEC944BA8FA73BD956BBF8021326A7B0F8DEC776FA9587582E6449235B0DBA3E008909B0E484D5A3A783CE3F0ECBC4BA85B1C509E6EEEB36B11F31F6CE76BB2CE308271BDA5177867D55FF6A369587F457F98C1F946C2DA9D6F69BE27B912923F366D1316FCAB14101A188271323BC5E36448298ABD0FFDFA6D7CA87B4E5E0A4FC0A5CCA348E91237F26379E665BAE27F81D3BA3912487984454D4A9C019CE7A7025F4ED7079AC01E1B9AC7BE7A4322E20B67321E89FEEEC7575D53AD03E77D0F57F51BC1134B2968A148BA8EDAA46018AE4B74018E9051F284315A156102508AB1EC45D246B27A9EE952A92CAE4308E044E1646134EE37C90D6CEC03795725259EEE37CB2533EC15639AB976DB4A25804C331115B5A7921EBD63AD25D0BD70A7B61B8BC3DDBCBC04363A9F1C257D7302C33536AE2D27F72F4F4F5C1CD9200FEF076D48CB1D4E120EAC7576B40019CE5BF95CE0426DCD32A20E44AB26BD08021FE1027C89C0C6F03E70A9F769D99CF89E28F777550CB9B073737C4354C9454F651AA3CED8DCAA60F863F4F557CFEC9625EC4AD87BBDD570495F149CDD1701393851250CA85E6A246B1384598DE8621212EE5CDCF1951E3BCE393680458B99A64BF10A761EE7D2A28C6A96A55E8312EDF30FD4A5264495E81A09BDEAA6D7DBFE9F56D7F866D276B8AA3F9BDC002B5103B926175C8B8F75C5AB3DFC80B159D3E7ADBAE83CD4FCBF269F3B60967662B48736BCC1CA65226952C5D2478B3DD4F309B75C3B316D6C9C71B42D7C50E2AFB5E7742F044E88DEBBC1D93BC5C18CD4E2C970C3E1560C2B9490559CF20C1E2582263D002CB9F9EE671F56292A440DF5298B350852E87B2106BE2CCACFD86EC4EED3BBFDDEC383ECA4450C9FED0695E8A253EA3A96DFD6B8DB69E61C608603068027B9E1302591E1DCE7A811D45C4D37A3FBC9057C5FCAE905A558B1D0363BB86FB1753F020F9307CD353523CDC45E54573100EA53A23EAD513510361699E0281FA9AD6078E3A2EC0EC638833907C4A043E03CA093E0E8DBED09B8582E13A5D17007D35F2571038972CB138476BF1218E38CCE71C9AB11135786BEA974E8B7E2C55E2CFD55166937ABB0C9DBCA5E1495194515C66087ECB3665459E0CAB1BCB0B13103A1D559FF76FA7F8F1A651AA67AE5B635081192E263D14C1FB77C4D613DE9C4B1A0F0DA9D9C56119BFD6295F372BA6982871D2EFB65A7218830836789D6B7F9C81BA7574BA9932626D71F87B12197C58227228DA7ED066D1724979693AD114962989CCDEB798ACAF57C1C1CB442008E90FF3F43E33E2FC59E04C919B82EC343B9FC8F55F1C7E3FE40D92F3A1671C7BD9A22895893F2C5A67D3A4BA089215B6D13BE620457BDA4849", + "k" : "51B28DA977511A76C1867E7C201312ED86BD72410DA84AF32B16F275B3BD058D", +}, +{ + "rngSeed" : "4142237070C216BCBE245A39BD9220533C97651D84832B26727855AD994A0760C52B9319AD404693E4248B8C5FF324B3", + "pk" : "2CE082FEE023E6C49FE0381CF056AC1BDC95895271F4E245BDC98EE3A87F651191832B224B3C5528562F9498979C4485C3206EEE0A6F5CBA8FDAA70DEC105BEDC40E4C6B667D1739C8580F2D246371F415411C803AE0B52F0B5A6CDA5FC3340F1BFA10BB29ACCF402D6F06472C14CC52556E5A97B56C190EABE6817985CC346BAA02C76AFBB6B6DFE33F711C78896A529656B4ABE25516E448BCB41DBABC340EF4B483B750B0180F68EC0020271A0E9B9F466A4728C19BDAA426FB82294CA00261CC0C3349B75D397674644AE5CA363774ABE8A290240ABE4039A7E124CC894657C9025E1534B91B896EEFD3AF2D559DA9F8558FA7774708A7FD535580545BC68C9CC89CCDBCC78ED5203FFB653965E7B0920574B7907443B9931472CF19C17DD18AB87842C853462366646881592EC3F5CAB67B7E768472A08A43681120F491BCDE05A9805C6787B96ECCCB05D7D944FC858B5EC3828859234DA88D8D00542B104883E824E7B630267111E49B1BB5E4103EA9AC2B187E046B4CD109709FCA26AF813440F30318DBBC34598EE5DC2806794C4E0A8C6B9C2310C34636088DA92147D6B32A7BB447F50B898C5A3E5CB43D6E3C147AD085652AB9EDDA72F25B7BF250AC84D1288FC188BA645D88333B65B1150722334B5616429B608A0C93D0D946C15576C82093E0B263BB521D9FDA997A461F1EE47098861FEEB8B557B4656CBAC57DC61FA9510BC1C95726B561A1CA4000F28A5720C42EB932F1CA8FC9B647D3740117EBCA3D5587816BB48CFC1CB4E9CAEB7834E1814A7C478FA052640AF253371242DA9575C2A66BD01C5FCA4B958EA437E6474301069D0DDB254BC4603D3BA5B7415A96E5327743662CAA7E08F608BE974341B70DB77A850B2C11E3B4CC6525808238CB097611E77CC449F17C63DA122966394E79518FB6022EC470E8C5082A945C73B52F05C38E2DC3419AF4080E890A6E819BB1B301046057E548894F511989A40E854AAFB62ACE7E586793921E292CC8601181599977D9FA457AA2039B14488D5698A8F03DF1B56479F9109AD105B028219B3C90ADAC962369AC1F0043373BC243286C24F599DE3A28684524988198971C1F88419CA09B3E4F22B64A221DF8D32AFDB0572BA62C7387235EE2752903535C9C912AE30C9151A3B6C415D59A4969CC432D088196F22C518037044236EB441438ACB6BB61CA45C947AB98A53B44C48119135F776F2AA4A8413A1142CC4EED8C2948F8CA5DB39388DBCC15C12D13035763A57C523B99A1912D0FD29B952776EB03AEED697320C66C0F65B369E13C7EAB1E98B281E7B17CC2CB9CEAB725671BB5DF0933EB5C70A3D39E0EB5A55CC20AF912AF87CC23E10AB77A9C9755201EC393B523F51D5307B176F05FEA16A2DFCAC794F834F60A712F13AC8D5174D3A7627CE66FB862497CB95E36DA3F486C7432E5983C2CC8CC3A7582A6B22C5A7AB3BC5107C831AF145FBCF74EF9523BC7F0CA5EB97B34A3872B9870EEFA3FABF609475C46B1E736CFF313F046B6050C13392571F2D252959ACA2F8418F7489809EA51939A1E8192BEA5719262208109B37BAE2424EC3655ADE90A9CA235F69C8A3BE54793655A9E8C6E9C64354A842458067295F08B6AB3B938E6B188BC252D4569589282EB703F0CB237A67A779D8957C4602A9BD80F266303898ACC60439A975C8E9D8342F6F1A7D6C92F11606435878739D3BD27460FB5E735A73CBD1CB6C657D0A6074633DE38647035B54BD10986E4573E09820EF56FD8D71EE778822F72194237C0B5344CD8C888F12BB34FC86E6147161143365FD45960396BF45A8868176C7D0C440FBB71B8C6ACA11B6EF3E33484F9BC22D090011918C3525CD0F0724423BD1E1C2B46A66552926A3A6A0389410A3E5C41D66B07C1B41C645787E8503C613343CC73066BC85B028025C3BB6901E33E242A0061E001ECBB7AC690837B02282A457CCAE40DDE98934BF37DBAA00DAE287FA0A628C42A66A7E05A6645B244E909FCCB6ABF0075BCF0974B97099A7C67A2C71090C7BB016210D0AB69FF775DBC47206429B347E6749EEB3E23983759A583E08B1653CBB5AD4B677F9B9B365287C1B559C199C3945653A3BC7B0DA8B41914BE5B411268080396795F1B95AE14871397E14F8F3BC940F00D669886668C2DDDEBF98E5E270510DB63B9982EF818D1253D74A644FD56900607545EF8", + "sk" : "A1EA441AFC0440B20C72E1B094EC44783325BA58A537BB2BA389B1A8E111FA85AC48716072D2345D789B2A9A07519506CBA99AA60932F0A112282531A4123C99B8B4EBA967F8B82B9B81C3B913B05CF51DD862810031AA7928242CE7B0A9404BC0142746B151EB3B002D571C07893507B7487063A4D59453DCA293625CB45FC8464EDC0322D3C9EE8B8C002C227D97B36611CC60204AF3D88352D6BD6C07C87B1365C8C58D3A2468D2103BE03604065734780765E4B932D6B0BF3935AAC04849B0498A7087C7DADBCEBC167858C778E8A09138481EF7074AFC688829A45311D16077E5A9E38744C140159795A281206998943DB5315599391D39007C25481BD79C8C0FE55AA013397BE3AB85204792872577EA1B3393CFEE4C90B442640F864BF0605A70F608657782A36CB78BB37D91748E1BC2BB388880A3B9AD78235ECAD24B95F2C0F880A59775C90CA46819300DC0CB35EF0B6AAFAA2F9234BFD7F0BF41507FE0166F7A4698E992373B6867704C2E7AEA3344288D98B22F42888EE4DA9ECC411AA079253309A2A9483D2EE2906518661E64482BB9CEE4DC314034741FB7377728831664AD3A333105B261EE87B107720A5DA79BB234CDE3234364973237D825D98657709715B71A4D7B78952406B56265B6756611D9A2A4844924A78A0BBB3C25FFAB7F5B94C96A3A90569CC178F06C884934B547A116938458E5BAE601B49754B3E0E48C86F141DFC624ECC0823EB6215476911B4B9D13B93FCE12076573B995AC8984B5A0DC33826D3B87EF0A77C363BF3D5C23255021F8612F28EB501890666B4486A972A3522B07E1C13BEB539E731167BD535593796D68D6547C7913ABC73D8812143BBB2CC6A05908C1038152655DF28FBA4912C757C9671B8D01570A5DD91A5DBA81113A69D15395C25B474DD817D862AD78D24566D7989B3691FAF25B88137F3C683E9917152E9B7D7218083DF9A0E1FA702F184D745B7DCA658B07A42494D27C15FB44F7C1199EAB93DAA26FE3D5406C09AD407B6D28945493DB62A9924E755C29B7B1873F242F7C637D9EC2A222B9CEED63BC73543A5729B93D618C09738957C8368C50A58D01A7BA0BD06548B763A4B3891641E640C89AF573BE0382055A9539B471C661646047C10C52C4D8121BF32BC89532B763656CFB19BE72330D4E7CAB3053B900B162FF480DD5018C9202D0A41A4185FC554216065CA0CB01D5460F209DEBB40496EAC65AC73BA264041BFB43DB29B0038AC8C12164F9826C20AB8DC4248DD7717EC3D6C2BF974DA380A31323B1B38678ABF80A32F832E642C31FA69A163B4A3AF6250EA212E8033377D1C596A72795196DE2873BCC00C21E8B5D75619C31CBB1B1E339AACB204C919B43CC4982B3405D82BB0C97B2DB370230C2413418C91EAB62E30B57B304A91568A8DD29506E656C6785BF482807960BC962E43FA7D8CE04669044924F8C62660E5A0EB9C4885E739C58C22D7440583189C6C9E51AAD37328A1C605BC44136F34B3FA82E24764743A43983F91125415C2E5042BA6393D2159B8992C41781A06D6C5745C5CC3BF10785F19BA1133CBA89C2609A26A3524DAAC54D152B34D62399459CACE6D0CAA1D01E77841AB153387C64C5DBBC29BB88250221046E927F6E7A4D85C5299887CE3774A726096D37C61343AABDAB95720AC89BED9B7EC29A14568178C9A63EAE1268F9F29D9C4080CEF312609834BFF34BFA775B4B3078FBA0CFF3812C1D79674D13C9A0853F89A1BB9A87529D55548E303D51D8004F539F60D17E3D858037E90E04DC54A2F8BBA79A395EFC823E085C93EAAA069C4A27720C16047934E2CEE970BEC418A02CC91EE82A3999870FB190855E571C075445E2F53C8EB65F4A18844032B6991C098CCC069FF55A84D484E4261C7A379655AA1D2FA461AAF74DEEA4603838B9E8D908F9B7A3939C17B97CC9C330438855C77C284270E81528A745A7B97098B55E7A120791491C10615494B39934143B18311E83B13B6E92BC6D450B47B7589C1571A122370CC98793A13D1E008D57E955998C222A97814A1CAA5FE7C336CA331BC6266DCB85D3EBCADA0593C04BB91C3155E83B2E0A8A57B5532F799263B0B3111B1146FAC429EF4C870911399E8158915B7522477500941B2C560CD7A39000219F2CE082FEE023E6C49FE0381CF056AC1BDC95895271F4E245BDC98EE3A87F651191832B224B3C5528562F9498979C4485C3206EEE0A6F5CBA8FDAA70DEC105BEDC40E4C6B667D1739C8580F2D246371F415411C803AE0B52F0B5A6CDA5FC3340F1BFA10BB29ACCF402D6F06472C14CC52556E5A97B56C190EABE6817985CC346BAA02C76AFBB6B6DFE33F711C78896A529656B4ABE25516E448BCB41DBABC340EF4B483B750B0180F68EC0020271A0E9B9F466A4728C19BDAA426FB82294CA00261CC0C3349B75D397674644AE5CA363774ABE8A290240ABE4039A7E124CC894657C9025E1534B91B896EEFD3AF2D559DA9F8558FA7774708A7FD535580545BC68C9CC89CCDBCC78ED5203FFB653965E7B0920574B7907443B9931472CF19C17DD18AB87842C853462366646881592EC3F5CAB67B7E768472A08A43681120F491BCDE05A9805C6787B96ECCCB05D7D944FC858B5EC3828859234DA88D8D00542B104883E824E7B630267111E49B1BB5E4103EA9AC2B187E046B4CD109709FCA26AF813440F30318DBBC34598EE5DC2806794C4E0A8C6B9C2310C34636088DA92147D6B32A7BB447F50B898C5A3E5CB43D6E3C147AD085652AB9EDDA72F25B7BF250AC84D1288FC188BA645D88333B65B1150722334B5616429B608A0C93D0D946C15576C82093E0B263BB521D9FDA997A461F1EE47098861FEEB8B557B4656CBAC57DC61FA9510BC1C95726B561A1CA4000F28A5720C42EB932F1CA8FC9B647D3740117EBCA3D5587816BB48CFC1CB4E9CAEB7834E1814A7C478FA052640AF253371242DA9575C2A66BD01C5FCA4B958EA437E6474301069D0DDB254BC4603D3BA5B7415A96E5327743662CAA7E08F608BE974341B70DB77A850B2C11E3B4CC6525808238CB097611E77CC449F17C63DA122966394E79518FB6022EC470E8C5082A945C73B52F05C38E2DC3419AF4080E890A6E819BB1B301046057E548894F511989A40E854AAFB62ACE7E586793921E292CC8601181599977D9FA457AA2039B14488D5698A8F03DF1B56479F9109AD105B028219B3C90ADAC962369AC1F0043373BC243286C24F599DE3A28684524988198971C1F88419CA09B3E4F22B64A221DF8D32AFDB0572BA62C7387235EE2752903535C9C912AE30C9151A3B6C415D59A4969CC432D088196F22C518037044236EB441438ACB6BB61CA45C947AB98A53B44C48119135F776F2AA4A8413A1142CC4EED8C2948F8CA5DB39388DBCC15C12D13035763A57C523B99A1912D0FD29B952776EB03AEED697320C66C0F65B369E13C7EAB1E98B281E7B17CC2CB9CEAB725671BB5DF0933EB5C70A3D39E0EB5A55CC20AF912AF87CC23E10AB77A9C9755201EC393B523F51D5307B176F05FEA16A2DFCAC794F834F60A712F13AC8D5174D3A7627CE66FB862497CB95E36DA3F486C7432E5983C2CC8CC3A7582A6B22C5A7AB3BC5107C831AF145FBCF74EF9523BC7F0CA5EB97B34A3872B9870EEFA3FABF609475C46B1E736CFF313F046B6050C13392571F2D252959ACA2F8418F7489809EA51939A1E8192BEA5719262208109B37BAE2424EC3655ADE90A9CA235F69C8A3BE54793655A9E8C6E9C64354A842458067295F08B6AB3B938E6B188BC252D4569589282EB703F0CB237A67A779D8957C4602A9BD80F266303898ACC60439A975C8E9D8342F6F1A7D6C92F11606435878739D3BD27460FB5E735A73CBD1CB6C657D0A6074633DE38647035B54BD10986E4573E09820EF56FD8D71EE778822F72194237C0B5344CD8C888F12BB34FC86E6147161143365FD45960396BF45A8868176C7D0C440FBB71B8C6ACA11B6EF3E33484F9BC22D090011918C3525CD0F0724423BD1E1C2B46A66552926A3A6A0389410A3E5C41D66B07C1B41C645787E8503C613343CC73066BC85B028025C3BB6901E33E242A0061E001ECBB7AC690837B02282A457CCAE40DDE98934BF37DBAA00DAE287FA0A628C42A66A7E05A6645B244E909FCCB6ABF0075BCF0974B97099A7C67A2C71090C7BB016210D0AB69FF775DBC47206429B347E6749EEB3E23983759A583E08B1653CBB5AD4B677F9B9B365287C1B559C199C3945653A3BC7B0DA8B41914BE5B411268080396795F1B95AE14871397E14F8F3BC940F00D669886668C2DDDEBF98E5E270510DB63B9982EF818D1253D74A644FD56900607545EF85499CB370A74DBC96DE89DAA52E6AF0482648E3995FCE28F7B7C0DACA7B78F1A11FE1EBBD66174798908AEAA16D79212E61D5C30364864FC1E09F1B20F296C11", + "ek" : "248A67BE42C34526FF6B797DF945EDAAD6371C63119477FB05704A5D06B091398940D14609651AFE99D18FD029A9FFDFDAB61A426AC71E94B7D7531CFA48F53E5BBB4A6961D4D1A345FECE39376A6A2643C4713A36842CAAC30333E6FE5135E9EF188504D6BD6DE4AC80912C3FD87FDFEF145737D9479004505B75EA247DA93F326CCC02233F57BB14CF8BF6D50E44167F110611F8694E56DD2E843AF14FB90F28CC69370995341F02F18CB05A4F7C6FEC7F445E50FAB4F111787D72E7E1E9F822D4974421265AA9E6B927A82D4360CF916E5C30C622CCA7856355C259485D57DB94E53D5F6E4EB2C162FDD4B2F141189FE4216768622E45C09905A5F25F64EF12E804C8839F8D8BF6FD75A645990188D601CD9B1D8C7D3316B50540CB3F7CFD3AA0458D8197698EE74AC1E0EBF0A4B53636707349822E027B98FE58D0FC45BF074F7E25BD90F2F82EF6BB5DCE998B128BB32CF39654A6B07F1760CD5E4DC8A6BC650027FC7E37DFFA1F6371DB016945B5D2A52FD5DF7DE177696C2738508E15A7338E5640F07558FD25546EE3664EC730F83B3DE2683A7BD64EBB867AD743D8613906DD6743FC871B5EC7BE226A60A73D167E27C2A1117A0D032D656D96612F5EFB44AD8A060156316BD1609AC152DE1C9286BFBBBCF835D6068C947DE9B030781645FAFA87D11FD69064B18884A5CC2592F0F66702361DA2F2FBFB4E420E71EE341C0A6E50ABA4ED2DE435080FCA90C6298890FD9BA2A67F1206673F2FFD4F63E39F566785327CF94B92E538B186F65CD1C49C6FD906FAE93DA07886DB21D86BB593D19A098376B4A0AA53F2E0ECE39C4D5489017CA1B54C5E002BE7E15D91ECD75BFDE3711134214C5EE893C5EB904E189A14FEA9C2A7BB8C37B1C420A015D5930E14F4C23C4C7F6806A5D8462E3CC153A46D6C5E2DA039603E6FFA2E86A7E701C0471F6954D26A3480E26DC4E3BFD06A55FF58A68AEA9D26D9040E7F7EE213161456E15DD38DD94F70BDF5B897AB22B0F0A771D7F731553BAAE4E24D0F6EEEE65EDE7E97E14FAC7F6B15A3E58673994DB4DEAE103A4ABCFC754324F8BE5EA79B3E722CCF732240A12BD9CAFB8691EDD49FA0A2F467965D4DC6F8BCFD67367975623A1A76ABEC6C9514CEAE5DCC68108A4A9A5C060C29E88461E6B915548C9AE6ABD776CC70BEAA63CC54BB5A0634AE475474AD81FA2912CA417AD41A6DF96B3ACD5C3D15FEC2734453D309CF9E37E3936EAF3638D0280C5507DA7D44F346BD7FDCCF7B905D0DCEFAEE538EEF8BDF276266774B64A1A38C3A9ACB1D3399ACF975AE4530F5A90E77F8CE41781D68B6D4877CCAC6F254E2F0D92B2CB4B2568CD24C7F44DC7DA612A0A41C4EDB1AE6934F3AF145FB8D72E4CAB35442958737C58DCDC6E6AFD9C26F814681072D1BC592510B4E4EAC4059461504C23107B862441816DC0E5DB669F184EE0549B1E5440A3B291D99772325378AE5D03F0E45992D88250DFEF84DA3B1965047FBB2A1DEE8466844D1E3DE685DE3FB7488B27EF5C5475B60BADE2694E41C0B85B604C2327366BEDEF9734E8A7D6B5AB213FCF211A9DFAA16AFDBA99FBEAAA4F7B832A0CB39DD3C84DAB57F24C0F53EE1F0677894ECDFE4C03999FBB6886E28B7DA541DE5DEA8358D7C5F284B08CFE1486AF4A2CC07371E868C85B1DEBB75A2BCD2055249466DD5C683F01E673FDF613AA9C9D6F40F55A70FDAA872A30462BC3D68C8E0135FC1AC051C4782D1913584BA7E9CB9FF621175F5912453820DA0E83BD9B8761CD58FF16C471C8E1528DED415119B35B111E40529485F7B8AD278CAAE89D33E728302D0E87D296CC5FC7E1CE51B9AC3EEC0CBDEA31DC26D8F8C640DB283F77CAB0A3E862359F4ABAB841D4100016684CB5C61514631965007872F26E92347B07E7FD54D679B6F0ACFC93AAC7BC2FD031B17340267B19808575728483B3914022C8FC9735C1C885048D71E898FA55FB63AE85B4BCF50F2D18B0DF19C8CC4E485795FA872E506969F3EC92809E6D42C76ECA93465D0FC53869B5609258729B31EA41D855413E0E07E7D80BB045C4D431181FD51264A050AC18F5FD7F03A9964BE2CE16B06CC6C394BCCAB7B2F9FA0AE90A31DDC0621A1AAC1C7089B244EF8A1B909D6ED8DE118DD6ED4CD72EF936494722700A90FD83F0ABB2DCFE54391001A85FF8883F2BF91DE91CEF715965043832003B8", + "k" : "C94D7E80572295E39753E2290ADF3AA0169134B01CB359D9F5FAB620527E2A25", +}, +{ + "rngSeed" : "BD334D7B7EB14E00E68863F2E5551A095F8AF10681C28353FD19B9A7E70B8BFE266840860609008A567ABC66316C77CE", + "pk" : "4F240D6D4AC24AD53108968CE43555FD4BC4E3BA3DF7A1541E0764C6A387DE455A564203FAA38457376A3170360B5303BE69450ACC7FFDF638A90C7CF4031719EB27FAD55E4C901CB7DC5FB828AE50730609B80D5A92A89EF1963D836A16685881028759D06C55B9505E84B1AEDC5E07D5294A084C1201C0109699B3009B2C67603C055949F400AD487167C1CE048B49A98A8740ABBA9291618F7C395D77B0649CBEC1A2C0E2D25C86C70320E92BE7595E103013C4974B7A3B70D8100D61B89A1FF43C30F48C137511375BA781E74BCBF322BE908D09FAC8991B4213DB7A298C2C29455B3A5092EC8610C0325187434239A8B651F0A164240CA4E827F7BB7345848E01B50E34162A359C2EF8C8C9E6E9B7A18BC371A20D2F086865A83A2BA3545943068E173941E4875600183FB19BCF8242FB576F908A8D805CB0909054DE4CB6B84B179478A0BAE353D8B10ECD278A310466FC0A00C68784EF246F1F0847CCF72894549806C2C9650C9430B02FDD5CB0B3A9608BC85F02DC32933811D87322DC4993D3D13177B7440822C62FC7A31EA174159814C59BB209356C5DD20620B40D08169DF1A12D913105225CBACD9C6054F1499D6204CEE06206389B05057E579A9E294B43243AB92E136265470786B256F615CD3540C5CA675C4BF68F7DA4760105367AD3C6D71A2A4B209296DABA2768223AA30845D4CE7D67C2906156BBC4C24410176652765E294A9E22C58CB031BA06A11B5A8AE035A37DB36CE1771999061D722CC99DE03E96EC3216543EF74447DAD96BFBD386B3154B35E08DCCCC88791677053A0001DACD8EB6C34CAB6EEA355A10C517C45164E9EB4C714091BF129186A6B3BF33A86049671652CEADE8B55AD17472B49513A79F2B867BF3157D5DBC929974147903AC69A6618F67781A450637ECA5D0950948CA8F3D7C41983B8942B03D6A04842A09A4896BA3CD345E7D72A16BA3C63D95A1E85AC4FBF42EFB588B088749E2F66BD6F06D56BB80A818C2C56C5D1D1B5580863D1EF10AE2A97F5F83BE12491C7FD629D112823D728A2AEC939E163436259367473EA0B63ED37BAC19934DA906A21E5355A3A2277519C8F53C96B4F1A8704B8D79666C1224819590048F5B9A8B767FFDA0A20697CAA075AC25B5546AE32EB2959947B11FDD384AEA2692F7952266267AA559C8EF9168A04CC57FD8AE46674B75E785535A2B1C0C779A553F4CE5C1BF6094541363BBDA825FEC4B42035325A3A2B1A8135DCBCBF1122B8FA1A37E925440E95C2E4C0EE1F69318D04282C0BB5FC8616E99C9ACE80D27A79B64C843B08CB9FC7A27D20309726CB50735CB3450BE54D86860D7708B11A615DC662ECB229997004F9670E27898E78A4B3732B4AE5CC459F28E78741F9355A8EF9B394CAB001C912124A01D27232F060CA523D378A5D42E0022BEF2D2700D7C6C14DA09736679B2A0C33C035B3F0513BDB5B46FDBBF3A5B80D65C4BE918511BC8631E35AA5459793F858F364C96F2010D8849229ACC89E8A50360551AFC8C1D481A1C21EBB100079CF3D45AB4159371C49B16CCA69FDA67AED5881F300C5864C03A9391AB1080B92601F23A417A0563C0C14B16B0255C36529F74A103036466FA9290744ECA08CB16B94F30340C49581BECEA5B64088FA7498E02B439981CB4B4AC29EC4684152830ED82864CA833481323FD8A8F66CA34BD4ABCEF70C15C926FB8B6323C609EFEA710DCB6548C06BC13D6BBB41B40CAEA5745C68CC550873BB467F9DC6B3E720FF4649AAD171BC5527B0633CC2709932F0869A0702DA790A305761F9D146C1B24005F6C1C808B6DD5D97C647232E843CD61E39894902B76624B73739E3A1BBE4FB1B4B2348C836592A2D31DC9884394628EBAE00112643BCDA9A01F34A8BFA828333B32E8063ACC5344A4B36667691C55C50B2E3098BB4C7069846283B57FEE61089654A8BA06797C57C2E7E9BF1404077B80928F5A1BB6C6A753BB8A95BC46748C32E0E1C8F7AAC1E2573A47D104FF9567DAA2C0732C501BB9AC1315A211C11593FC1A38A69651347B6AA1250F3895A7844E1DE2AE45EC66214A8B41DA464BAA5FC50100C5073BDAF5B4A88C70450256B6D65413AB3ED302CCBEE864C578733D40A796981A8C3849F465CACAEC79898CCEAAC424FCD9B57B426CAF306D165D1E0BA6573A638FD7DF6B3F824F240E7E0EAEEE7D7A093875", + "sk" : "E8D7111942790185AB64776746D835F4F3B4B8458EECE8CF89E08B7AE974BB84C5A5325FAA7958F830BFC65A3F57B9BB311928D939B7BEC454B051B399103AA8F871F3D87D240693A2D10587371A40FAB0A52A3C13091710476A393A90A89B3CA8EC955F3B42287B23B2519CAC32A1B8EA6194752A3B1083930A0C415159DA51967BA96299065158F156D31189C797C150306C2903B1FA4639252ABA2E131B3EE74917EA269AA41CFBE05915688B9E73780D46BA63325601895AA054023CE760347BADA01916087A700963AEF293A40A0B3E4DE60258A0A687E367489A684A22B86E22AEF5E5976989B09F1931D3E753A6265AEB677C0FB3629329C28B2061BE210B3C156B46C5364DF8B74CC95B416341AE5080488B895E2C4E7005901F5397249A3FC1747BAF1C8105EB433227C959B6AC876629BCC911EB671689B2BB33D8B6A1CBAF90D81CE3F11200314DC0A53B41DAC824EA117E25852F2339A33934278CCA7DD0797C7B55AF75AE8F6A1C34F288C1124DAC01AD5399C1966049E8569EFAA305CAF9BBA4E92E15154D2B2521D0F245AA89788687817AFCAC195315BEFB50EB77BCFA487BE2547E98306FD9E92BAB57CC7935168018C570260C93D712E3058A843AA36E88123815A847411A3C4078E336B2BD26472BE6B8BEC382898B57E02048E531B335894CCFEB24EDE00F9A46A34DDC67F9F73BF5D98A87B50FCB115694E7B3DAA7067F287DC665A13BC58661B53137401403A211A3574A7A596679A021F8458C7BAABE9EFA18F3F82BDAC20C6CAB93BCDC2D31218DFE0C451724226961189B460958A9BD12D87446B7B8DBF65AC7D908FF1C9FB7E927EC1679DA95C4B43CC5A11937B3538446298CC7B55B178078025A229BE58A95A0727928BD3370901B180543D78233530186B3155A78162D3969BDD6B6A0204A25066303C495FDC9C9DF947959B79497A805A3122C71E96EFA728C6B92042B39B45291CC87895D4AB62A2437C9AA7754B54A48CB34C1070B08FE2CB2EDB974BA633CC6C5413980CA5173160CA43CF77320850A12E402A0C94881D3C50EB5F317628C4E0477BB4B1B962C15081B2662D65C4EE1099C001835DE716AC6A924D3702DD2C61ACC2487851A14EF06C36C6925F9E6714291765D8272BDAC11651CCF6848975D57323F599DE580CDFD892209C7888B7BBCF6B65C1C32B5A8E9885A29C16446369FC51E4155B9D5081D9C74C2EB2C545C07277F608616D800E3CA0FF95A655B7189C48412556A8FDEA48E0701B4D1D5175CF0088B70042B5678F91164EB42031067814DB0ADE6B26C606BBF8CF596947980793AC48F7ABEE21A854FE00551E98CE039734CA028C8D8A3169C9922DBC273580FD5BB03A85508E0141EEF13A37E80CE35531BA7B900599ACDD281CE729C4F2BC6B898B47622F5B559E7CBC86A26AD61A0EDAACD3AA638879296A5413DDDB78EDF347879C4C325EC69E2BCC7710B65B4821489AAB9AB7C8FF9E6B8BFEC9D5C61967B1C77F7823CDACA03A7FC04703740DBA421C30B8AC1894CE58845CE9A73B2321C65228EA0D64C68D3C7A6533837B6967AD3139A709ACD8517DDB693ECB75CE3DB51B7235B34C0B296038A140737BF77BA7AE91C9C49200D6262A2D357AC390C744BCA28C9CA4D32A2DD8B456715907B1B42E7381A605B16E4E2A021E383F4D051F859BE8E83B39A2BBDB9987A37423B689718C72365DD5B65D1601B48707955724EA106602B6B4C2223B142907195855D652C13CBF29340753911714F82BCAFBFF178D52BAE8B9447CEF9745A6B18F53BB697AC157516C3123C526073CD7AEB3550128B1243B95F178705ACCB7EFA2FDF9C5FF9DB4A6D1C171AA7B6222151375796B93C8F39B8262D56169F591A8B3964EA228DE76710698698F23A147E3206A8641F5C46B7573B1EB13B8432104FC7751E813C4004D25C2AF512C5A47BD4A50A37129D7B0B80AE551145356EC304751A8CA143A57C6C1830AB5717E3862B50F70B745B33210BB73B340154B6197F1423F9CCB88FECA121E24E79600DC0B047A36B1B76697FA06395CA8769763443695852923572566ABF8C5C7097F6425AE1C7E1185B1DB5AB75A9856217AE82C61C82265E18151F831B65A5B435DAE57A89B2AD55C3CC02F70FCDC55901069A2E773B4F240D6D4AC24AD53108968CE43555FD4BC4E3BA3DF7A1541E0764C6A387DE455A564203FAA38457376A3170360B5303BE69450ACC7FFDF638A90C7CF4031719EB27FAD55E4C901CB7DC5FB828AE50730609B80D5A92A89EF1963D836A16685881028759D06C55B9505E84B1AEDC5E07D5294A084C1201C0109699B3009B2C67603C055949F400AD487167C1CE048B49A98A8740ABBA9291618F7C395D77B0649CBEC1A2C0E2D25C86C70320E92BE7595E103013C4974B7A3B70D8100D61B89A1FF43C30F48C137511375BA781E74BCBF322BE908D09FAC8991B4213DB7A298C2C29455B3A5092EC8610C0325187434239A8B651F0A164240CA4E827F7BB7345848E01B50E34162A359C2EF8C8C9E6E9B7A18BC371A20D2F086865A83A2BA3545943068E173941E4875600183FB19BCF8242FB576F908A8D805CB0909054DE4CB6B84B179478A0BAE353D8B10ECD278A310466FC0A00C68784EF246F1F0847CCF72894549806C2C9650C9430B02FDD5CB0B3A9608BC85F02DC32933811D87322DC4993D3D13177B7440822C62FC7A31EA174159814C59BB209356C5DD20620B40D08169DF1A12D913105225CBACD9C6054F1499D6204CEE06206389B05057E579A9E294B43243AB92E136265470786B256F615CD3540C5CA675C4BF68F7DA4760105367AD3C6D71A2A4B209296DABA2768223AA30845D4CE7D67C2906156BBC4C24410176652765E294A9E22C58CB031BA06A11B5A8AE035A37DB36CE1771999061D722CC99DE03E96EC3216543EF74447DAD96BFBD386B3154B35E08DCCCC88791677053A0001DACD8EB6C34CAB6EEA355A10C517C45164E9EB4C714091BF129186A6B3BF33A86049671652CEADE8B55AD17472B49513A79F2B867BF3157D5DBC929974147903AC69A6618F67781A450637ECA5D0950948CA8F3D7C41983B8942B03D6A04842A09A4896BA3CD345E7D72A16BA3C63D95A1E85AC4FBF42EFB588B088749E2F66BD6F06D56BB80A818C2C56C5D1D1B5580863D1EF10AE2A97F5F83BE12491C7FD629D112823D728A2AEC939E163436259367473EA0B63ED37BAC19934DA906A21E5355A3A2277519C8F53C96B4F1A8704B8D79666C1224819590048F5B9A8B767FFDA0A20697CAA075AC25B5546AE32EB2959947B11FDD384AEA2692F7952266267AA559C8EF9168A04CC57FD8AE46674B75E785535A2B1C0C779A553F4CE5C1BF6094541363BBDA825FEC4B42035325A3A2B1A8135DCBCBF1122B8FA1A37E925440E95C2E4C0EE1F69318D04282C0BB5FC8616E99C9ACE80D27A79B64C843B08CB9FC7A27D20309726CB50735CB3450BE54D86860D7708B11A615DC662ECB229997004F9670E27898E78A4B3732B4AE5CC459F28E78741F9355A8EF9B394CAB001C912124A01D27232F060CA523D378A5D42E0022BEF2D2700D7C6C14DA09736679B2A0C33C035B3F0513BDB5B46FDBBF3A5B80D65C4BE918511BC8631E35AA5459793F858F364C96F2010D8849229ACC89E8A50360551AFC8C1D481A1C21EBB100079CF3D45AB4159371C49B16CCA69FDA67AED5881F300C5864C03A9391AB1080B92601F23A417A0563C0C14B16B0255C36529F74A103036466FA9290744ECA08CB16B94F30340C49581BECEA5B64088FA7498E02B439981CB4B4AC29EC4684152830ED82864CA833481323FD8A8F66CA34BD4ABCEF70C15C926FB8B6323C609EFEA710DCB6548C06BC13D6BBB41B40CAEA5745C68CC550873BB467F9DC6B3E720FF4649AAD171BC5527B0633CC2709932F0869A0702DA790A305761F9D146C1B24005F6C1C808B6DD5D97C647232E843CD61E39894902B76624B73739E3A1BBE4FB1B4B2348C836592A2D31DC9884394628EBAE00112643BCDA9A01F34A8BFA828333B32E8063ACC5344A4B36667691C55C50B2E3098BB4C7069846283B57FEE61089654A8BA06797C57C2E7E9BF1404077B80928F5A1BB6C6A753BB8A95BC46748C32E0E1C8F7AAC1E2573A47D104FF9567DAA2C0732C501BB9AC1315A211C11593FC1A38A69651347B6AA1250F3895A7844E1DE2AE45EC66214A8B41DA464BAA5FC50100C5073BDAF5B4A88C70450256B6D65413AB3ED302CCBEE864C578733D40A796981A8C3849F465CACAEC79898CCEAAC424FCD9B57B426CAF306D165D1E0BA6573A638FD7DF6B3F824F240E7E0EAEEE7D7A093875CFB4F6A03BB7707D37C80474F92C12748B37F448186584DF115EE97C195D45A8BAE49824E1A023A302CDF665AEC15B60F7F77AB2A0FFFD5246D07AE975A0614E", + "ek" : "7C59757FFF8EADC3DB69EF71B61BE191F34352DBE84E2C1E22E62435F10FF67A408A885F9188C0A0D8A7D4B8DCC071DDA8DF99DC079A5CC3C341323353C69C38B816CDCC3662B5F1FBA694D5A0135AF57449B35107BC24BE2C52D4B2A6F60D7B36E1C39079FF20BE86FFF93628526FAA2450F5A50A490273A048F64999506806CA0C2B6BC00625F1AD1E357E91C7CC08826BDD0E9F3329F6B99F84DCB3DE424377C9903D05289333AB4F107784037856994E806BC6498D4186A02A303DC680B8C24CF15B193957925D16F0AC012659D79FCADD7248CEF4B07F8174B7F87D9082D438DAE0E45C2E33E711C6A517DD7B05B4830FA8EBC712BB3DCD2D759587FF9AC3FEDC1F764F8E21720A8AD44425B827BB316A3CF2199A1CFDB7CF04590340B366A04352A82FD60E33FA38B2356E9BDF3890220D2BDEE2DB3CD5577588A163D1394EE5EF8411286178AE5690823AA240D2E006379443EE824907AEEF87598F6E671164117B80754E36FE0D8F5E6D3A251D53D86C320061AF84F7A2635DA7110A029075BA4D8FED91EC58FE52BB4E3D08D8C059FC307F52353E613A2737B813F15A0E3AF05D34EA1674EF4956E95EB65F17D5723DDDA9C1F3727875A9844166A0D930DBBF2B614EADD848CA8BBF2C4C20D7FB5B83F66BCBF725BDEC00990ADA92911D95E7D66E583EDAF2C9DEF0BAD86848B6E64AC10E987582DAA77F56198538642B00CB6B085B5F28E3492F88498501D6DDFA52EF32214B9061B7F8D50E064F4B854AE5A870C38FFFCCB69002FEC03AA265AC090388F51ABF06D50CCA879774E60EE8CE65A535AD5A8429FF965C820387527808335FFC549AFB07D54FD0FD14BC1309C4E48D8FDEA49D59FF78B3D3DF63527CFAAAA7093C86F59A61098E1F279085C584E3BD012E0CAB37248804313D11B8AD85E39DBC5B4B7D2107E1AFAFA1005A33576CD81316F6923AC0C7C316EA389B3C23DF105967E1F475C59B942DD46D625083F9E171CA15482D1A743A519C50AFBF0B114593268975B930372FD44E750B36E9C8EC1F54EA0821F9F8B3FC9E37486BEF60116EFF02A80A45277CE9019AEC1C1D22CAC33D017370F6D823DDA0E6F782582539AB51DCF5926CC2D2FFD37339077FB139D2CEC7376C358856CEF732089B74571584B812917C380E66A70BC6471A814EE95273E65B9DD742B01E3A5240C607A60DE5A055F00F6F5C4F7842F6AF9024C87B852FDA8C0326EDB7874739E8C32AD76C3F5E0FB3C3CE277EFF68DDAA492F29CE1DFD93A0F0B7E275294A6432E22D14BFCE9EC7FFC30C1CA00DFA23B5EEB85C88B35A3C2A0AE30AC16FC26B5041BC3BA444C377CBF7E2A4EDE477C18E75041BFA220C530FA197F145B55375479234CAB77AA02C40DA91102C5F026EA8183C7087B4BD308271BF5D706CE5DAF95BDF60CD7BC9CB572907C483D993347D0CBF4CF24DF5548F130F545B010B18215D290EA7561DEBC36B326870297AE15CB5E1831174C79CCBD1E9BB11972E7E93530CF6AED859492AC9BCCA973F6AEF41842A9A1AF3724D880A765D525C8B3B6CCCF82E58B4B69E579D39844EADF87B24A6BE0E4C27A4E5D987FCE293D74E006F5DD99CF1DFF15ED7779504779E313F12A2916FA793F10812CAB7144AC748ADE266BA721FB066955CDF77D48D983AFB028BFF2317A966FCEFCF978519224C19F5D74A8D4439F201D13FB776DCB0F32223082A21B9D01C9D9D4D8DB2EE971A8E8E4101ED45DAD7ABB24CC28703A312011FE9B320F7DF99C99D9A76331A1D666D6270ECB53B46FAA264CA17B983CE3A1A728AAA02B371ED6B77BE8494EA7E056D47F55A59FBFF40F3ADF5C89540D08CBF703655ACB61279C3A3C748961B62203E550EC4F94D00738E50A66C9C033B7D0385AE9F14FB14CC0E7FFD7F796E1088E08A6B736CAB8A15A62677DA00D2853D496D349A83C87F18BB62F1D4472E99921A07BACBC349E675C4F5E9F98B9D404AA52C8D254B5879E9181A1772E2D160DBA2DCAED55B9BC2179466BC947B237BED5441A33532EB0E70DCE44A3D5CC80345B6FD72216E3013BAD00D8E5CC62652F1A2A7B4A2755D88793D4D44D51DF0289EFD00FF3D74DD0E0CB0F94C71E8623C2CC1F2507C86E347A2FC8EE82658CAEA3B08641C680C3FFCA2A1E9ED131C478CF3AC3424FA67E73EFA72E5D54F8792B6FFF32752AA37B904A2DDE3DDF3FF3F99D6", + "k" : "118A0298A3A4FFA81D9D23D296EAF78D17478A45E2A296A212C1E282A1547275", +}, +{ + "rngSeed" : "A0264C58AB1F2CBCB212077FD378D340307ACCB31F1312137CF84E3D3135044D4EAE8BD38BC3E540A0C14D46458F6179", + "pk" : "14905EBE26C856FCCE2C623156E43EFD0433C19858C986436150968132591DB37EAFF112C1383238C0767316C0077A00A4714E49D694D802A510DC960C525BF601384B96B90141B846DCA14F34159DB490479205B30800137819406BC6E14786DC4079E0481D098CA4A3F15F593135CA64CD7C32C46B45B3BDEA0D7FD70DEE467020AB49D4360355146D7F00337A1CB452357BD01074234B464A134ABEBC14F7557597BB057C4972D2F012B59A0B83328E88D76BD257CA5ACA8912C2A9F90672903CBCA16B9746E135108638C388676CD189452325DAFB4DDFE435E13908B177A5FC883BC233679DF34E40A09FE384654E6A857E49C5F62AAA30E123ED71A4D79A65BAB40EB2BA7E1C497EA28C069CE9898F3789FB1B03CC07A5789569496A5A6B84966DC3B601577B07B01E2BD6AFC315CBE74B03CBB51BB68920362474819A02E5C60DB441A3E0A2A7299AB0913A92E3228986C18639AB0B952A01C77907E6A0B59625C01B1C406A4B339C10B0C8947FDAF5C14F6721BE5C11E3A62A7065A78B9B1176E64AD075150B67AAF70820B9A62848378C374A3AEAE6C63CF620D0927971C0188768991734754368BDEBCAC2D6B899E5ECC20922059641566B4996BE455E90BA9AECA1A40CE8CBD68A6AC0CC708458169C624EF80A25CCC7C931D938687CA4A12290711B1E72FB3793A760A5C29942896853E26DD1606FB48C22B53506B4413E8F5B3C20B446DFEB586532A09AD602E5C54D5E0C0149EC3526758F174BA49134C980AC109E711FF658B7CDF0178B8C861A71C700E90B1DDB9265E9BFBC07A253726FC9C54419BCC39932555024AF651A277302BF383CB67DD2A929037FB4109C69347876751F4F83955A4768FB94622390790796084215B6108C72E10217FC9134B7872AC6EA3D07B989BC70A23A826676718F31338C68A5B1F9ECBA4B18BC47D3161419530B67041B3864686224D0171DBD248A48527950F2C4C857AAC6F7A3394662AFD84F79D5854EA77C26E7C57FD8A3AAD0399CCBA0AE4780ECD2481AE065E3597CF1868C327C14BAF36D9711A3A8647D26EA52A4F9139BA835F380CE9CC599F6F11586F158F941520D143F75D00125A3806C56108DE46C5AD093872BA5F927BB2A4A88E668C40AF5B4FE9B17F80CA75AB58224BA1B485A9E1C3A6E82B814A1B23BB0D61AE14A9CA4E95D03746A564087F9C53A343AB7595572CF2542D7A9CC90060E6E99CB2D18880F082D3AC91FBE00C5AB141C6385895C626D9C143CCD94042A27509FF67C802098415A49BFE163CA01A20A45ADD4916AA512467DB549E7B0C898656CB4265DF3987998C8737F3C79BEDBA48B9C6B8967A9BFAA0B22E6858307977903001867282CD38A01798D3B71BED21459ED4C4CA6E185D55525BAA096C1897C55789B9E19A6B303AF32F493CEE717BAD70CEDD67C3DD89BED6926A0F20B1798BB46D173452A31D7543530311734422F3CC9561D5360B665AD87A19DA71A7270998B87D62D5E7B0A5CA969120B4C610848FDC6AFC0E631FB2ABC21096347221971A08B94B0CA4116C2F5A8188CD982F3E647ADA99EEADB3AC25310DEA91FA724CF3E1017C0C86C2A979791D30192BC3163ECAF73C819DCFC113535BB3A40B252C8BC269884CF7407FCDA465C2AAEB19681DDE0C99A3853A861AC81F77E1319AFC6F67B2FE52DBA6B38523147F4E589EE716172650C7CB44E0B760174691217093ED4421DD5A38F2CA2C41604C592366A89C4C70ADBA149AC63DE1B5E21E78788F33D9E135890E61D69529DD9F658B340848623B17447998BACBF1C315B1FC5BDF8FC357E89448FE7A40217205C64961CD643AC6BC3486C5EFC003011E80C4F4494CBA123C2AC45F7D9019CBC7018669921FA76DB3CB5436763B48A8046FA71D186B57C942F6529930D23737C49698C15404DE20F8F357D5DA523EE3A117FD8B69AB80335E388FCC661A0C8B583F94A8C7869E464A0544C84D160A828F1770D97BE7BC43CDFA8566791727B7884E99A5D9FC549369A4EC5195EF1285860CB263085740CD466BC24835AE33BDD1499CE941F8041571AB638BCF896201CBF0B7324EC22C6D3C00F60AC6E6F0317EFE14EFB13440330B50CF86227FCC7BEDAC20F9364E2593ADB7599B5142174D6B999C725F7D119814642F79DE48F28D8B47D06BFEC41FD06E2DA9AE905005AD241BA55AB42A993DF7551", + "sk" : "CD85BACC99669BB19F64F32796599FA909499EDB700670AE7EACC07C89B4659CB7C3BAB323F3761728C79EC67515102091B133E3536A2032093DF24531874108D1010194338B16475F531030E0073AD08E168976AF67243EAB3596B9975B2A216E8146A5192577975883C21646CC20C036577DD709EDDA6ABD44989E6A8E07C555474B3D14215777193308D56FCA4AA7E2378A94F80DAEB4788F4C87B6477193D7A5D0BB6C49407ADFA222E7D34CA19B046CB14A37DB2CBE781288584F5C386A2E9C4FAE79A106C28F27C49CA2401A0A375664E885070814F96C9048993300065037EC06E1E692A97835C129B06707CD501C6C5CF1646D82365942CAE5E104A5BB71FDF42518485C1602838929244A49B194C76CFE2BAD0E758701214CC6C938ADF0C8E4712E0CE148576961F3B613537A843AC07243926A92A324ADC52B65152C69613ACC6336341A72F7104AD72C540DE40C4BBB8611A03CE9271680AA77BB827D7BF629A44BCA141C0CDF912B8B372A32030AC9680A2B64CE93F726001D6BA184736D571CFC79282CCA13DD0AA3ADC14683CA9BCD89B72D7CC280963F2D37925D57693B947017D61B716626E45A5C6EB295BA0963F2A9086615697688383EE8775228AFCD760C2A90C85D18C3FE553EDC719926AB0CE6E40D690A53B34626C6E28925B469EAEAC11209C7B00A03F020CC25176FAD9A2AD2B38FD16B04758A5D379630F3C9CC2B0824EAA882FCA6B134011A0E3035B1F2CB19346303A17837C30B60F11FF8795593035C6D335496734C491552EBF4A38EA10AB203B13F325A4DF221B9DBB7EB01AB00097845C1335F6349CE50C15E64A02E644E058807C9B764BADC44C6F21745C80B6F4264B1A7CE8FA65657D75D5319807A9B5BC17B1D76CA64EC831E113C1B8E79B5A1FC0B32D21F839A64BC212722E1664B9AC5C39A3DD0D8961D53C6DD697A6C896B664A6C7C5A70DE5A0DF2745A64CAC12447B70B1AB16395B71DBB810D763FAF817D42149B99181F9B9835C8E947CCE200A5A5AA573B44544226B1607CF58968B3829DE360952A8307F7FCB157C4AFFC5009CA6628F0527042E235F5D1C1A91BC178F8288BFC37B2F53077CC0C7C414E59F57E78D5357F447871579B54421986116C6BC22BE84080422C9B983794AE70304D601E2CF0AE29F6172A5529E8A4A14A89B064A3B142C4C90E421B59A48471E4852C749B9DC4867C677E52E44363A5131EB5642C4415F5248AE4358A3FBC01BEB2568C8321B711BC3199814A2B9E9BE56E266B2639FA920DD204DC41518B19B8A9DC0B5BA3290B362E9D071DD61C041B4A809FB92F0CD2B25BF94F04701299AB530EE704DCB6CA69613439C4C288E7A0643CA3AC321D930A99586C85AE0597B2C56F9A870E7BB260DF51BA7A62BED6859D7159B56B211D282B7E1BF85D81B1258FC01E2B8B15E3829BAFB34AA81036D05531D288A0EFDA8106362DA9878B61A4B3AB6813F27AB65BDB48105686EA3594FAB5C2D83AA867055A233052A5D57C741086814B7E4CA39B688669D4688CFD92203C902DC1D9831D3652475328C99BCA41A7B0F54A7795F8C2A4F90F305626E4E31B983C9FCB0748AAA856630A67399B37A2F204186388DCDB740F8B8B00CA0E328958A821A9F5E9A26D39C60A37B2A513B79C37930A992F3710BA1F574471F2175D2A777112A4F5444D37DB793D87C1C1E8B4CB37BEF3D06F8785AB65D8BAC7C07CB4003FD4A9933C3117E347664D92A18F137980F8065CC031AEB8B1A98B24656031C3B57D36894964171D6F511058E21A63A2083FDC37EF1848379AB86B7C53EEDC941D16174553966415439F6944393660C6209E59981662387A1E827B768787B8B46B685B8BB3B72175A367AF89B5F3953F4A636F9BB89B8351866A335A7EA422F9E9C794A24372B40FD277A5BA2A2531A4703E60827F562ACF95A8193991C8F4417109C059E91C4FBC289233B080A0AA8A4B3E02B35CB59216A9C37509A91725910CF8B11D6E7B985BA5C0D85073A99B324D0583C7F8C73901847E41C4515048A7556A0CC206711550649926514C96E3535EF6194A37C1A3EAE023A8851DFD0BBF0EFBA981880C19FB9D4E6C2F80B4B8CB4031B8106AB6AB33B6A37B3F8B5D133244894AC86929B4373B30F6BB4395B11914905EBE26C856FCCE2C623156E43EFD0433C19858C986436150968132591DB37EAFF112C1383238C0767316C0077A00A4714E49D694D802A510DC960C525BF601384B96B90141B846DCA14F34159DB490479205B30800137819406BC6E14786DC4079E0481D098CA4A3F15F593135CA64CD7C32C46B45B3BDEA0D7FD70DEE467020AB49D4360355146D7F00337A1CB452357BD01074234B464A134ABEBC14F7557597BB057C4972D2F012B59A0B83328E88D76BD257CA5ACA8912C2A9F90672903CBCA16B9746E135108638C388676CD189452325DAFB4DDFE435E13908B177A5FC883BC233679DF34E40A09FE384654E6A857E49C5F62AAA30E123ED71A4D79A65BAB40EB2BA7E1C497EA28C069CE9898F3789FB1B03CC07A5789569496A5A6B84966DC3B601577B07B01E2BD6AFC315CBE74B03CBB51BB68920362474819A02E5C60DB441A3E0A2A7299AB0913A92E3228986C18639AB0B952A01C77907E6A0B59625C01B1C406A4B339C10B0C8947FDAF5C14F6721BE5C11E3A62A7065A78B9B1176E64AD075150B67AAF70820B9A62848378C374A3AEAE6C63CF620D0927971C0188768991734754368BDEBCAC2D6B899E5ECC20922059641566B4996BE455E90BA9AECA1A40CE8CBD68A6AC0CC708458169C624EF80A25CCC7C931D938687CA4A12290711B1E72FB3793A760A5C29942896853E26DD1606FB48C22B53506B4413E8F5B3C20B446DFEB586532A09AD602E5C54D5E0C0149EC3526758F174BA49134C980AC109E711FF658B7CDF0178B8C861A71C700E90B1DDB9265E9BFBC07A253726FC9C54419BCC39932555024AF651A277302BF383CB67DD2A929037FB4109C69347876751F4F83955A4768FB94622390790796084215B6108C72E10217FC9134B7872AC6EA3D07B989BC70A23A826676718F31338C68A5B1F9ECBA4B18BC47D3161419530B67041B3864686224D0171DBD248A48527950F2C4C857AAC6F7A3394662AFD84F79D5854EA77C26E7C57FD8A3AAD0399CCBA0AE4780ECD2481AE065E3597CF1868C327C14BAF36D9711A3A8647D26EA52A4F9139BA835F380CE9CC599F6F11586F158F941520D143F75D00125A3806C56108DE46C5AD093872BA5F927BB2A4A88E668C40AF5B4FE9B17F80CA75AB58224BA1B485A9E1C3A6E82B814A1B23BB0D61AE14A9CA4E95D03746A564087F9C53A343AB7595572CF2542D7A9CC90060E6E99CB2D18880F082D3AC91FBE00C5AB141C6385895C626D9C143CCD94042A27509FF67C802098415A49BFE163CA01A20A45ADD4916AA512467DB549E7B0C898656CB4265DF3987998C8737F3C79BEDBA48B9C6B8967A9BFAA0B22E6858307977903001867282CD38A01798D3B71BED21459ED4C4CA6E185D55525BAA096C1897C55789B9E19A6B303AF32F493CEE717BAD70CEDD67C3DD89BED6926A0F20B1798BB46D173452A31D7543530311734422F3CC9561D5360B665AD87A19DA71A7270998B87D62D5E7B0A5CA969120B4C610848FDC6AFC0E631FB2ABC21096347221971A08B94B0CA4116C2F5A8188CD982F3E647ADA99EEADB3AC25310DEA91FA724CF3E1017C0C86C2A979791D30192BC3163ECAF73C819DCFC113535BB3A40B252C8BC269884CF7407FCDA465C2AAEB19681DDE0C99A3853A861AC81F77E1319AFC6F67B2FE52DBA6B38523147F4E589EE716172650C7CB44E0B760174691217093ED4421DD5A38F2CA2C41604C592366A89C4C70ADBA149AC63DE1B5E21E78788F33D9E135890E61D69529DD9F658B340848623B17447998BACBF1C315B1FC5BDF8FC357E89448FE7A40217205C64961CD643AC6BC3486C5EFC003011E80C4F4494CBA123C2AC45F7D9019CBC7018669921FA76DB3CB5436763B48A8046FA71D186B57C942F6529930D23737C49698C15404DE20F8F357D5DA523EE3A117FD8B69AB80335E388FCC661A0C8B583F94A8C7869E464A0544C84D160A828F1770D97BE7BC43CDFA8566791727B7884E99A5D9FC549369A4EC5195EF1285860CB263085740CD466BC24835AE33BDD1499CE941F8041571AB638BCF896201CBF0B7324EC22C6D3C00F60AC6E6F0317EFE14EFB13440330B50CF86227FCC7BEDAC20F9364E2593ADB7599B5142174D6B999C725F7D119814642F79DE48F28D8B47D06BFEC41FD06E2DA9AE905005AD241BA55AB42A993DF755120179B32E6FAF885F946898D545245757425D719681B0B2BA24D49340F931CF8E39CC6C99EE6FD8653D15505A6C2A713D41B43FA521CFB214E8D1B38440F4640", + "ek" : "BFF8FA4E668A264D071578A6240D8D1CD320F6C4B829773B873717C880F2BCF10842D4DC0E916E340205A2E4E2C48F01F1F1120DA5A1AB8346FD44E7BF631ED72A358226BB01BFC9F100EF2E9FD315CE003108A57132A6F56AEEA20CCAD49D011F1C67FCB01CDAB70D8DF8B7DC8DE7FAF9F8B681A486954D33A8BBC709201F62CB770AF8BBD81D56D882020D8D9602D22C973D4B185D521FBD4F97E5D382194357106DF8786284307A4FEFCDA0BA516575D886D0969E051754456A59F18C159CDFB94D79D5BF685FAC3BDB1A8BC133A72F536A4936D81A46F263A98105A2B0F49E62FEA8FBD6EA6669F73EF34B4BD558C0A9E157404ED371BC192EBE5AF7CEFF4CED5C51B9173ECAE841E249A27D8371FD687BCDEC66A07640FF399794EA09715CDCB70E400BB4E33F98064CDFAF1D36B8B5C77787AF22FFCDA7A518442DE4453CB726C88B3A347F2325AB469A7EFC53F59803D9C2458AB403125E791578CCB84499B7729C5A3D1CBB5C78FAC14D42E97EB06CEA4349E33DFD927A970C5479B07EB8CE4ACE81B75AE31F151B54F75F2019582EA913BAE3B9F4AD49C52542E14C1FE07C865C015910FAF06BED6FA0AB7C8090877543D8320A0A64704B0D6DED1658B5F8C686295FF4C4033004D67A3472BCF2DD8DC7847B9D1ADA272A432E76325506A88276DA04A6752613F7E922B00BCC268D1F04705BAAC7ED66D8AD0AD5D538E63FC6212DAF5133213A795815A8D510771EA27F873CE6A61DC62F7D2AE08BD4C2A136787B4451512A0E36692F74891E7660429D2373F6689EA68C0C2A61479955FDFEB5A872E35D4A58028846B8F5109863B42EBB68BDC72CDB2449820840E70C5B27F031A3B12218B7C0C563BDF9A1F6E6734CF2A10833C5715D990B359DEF4E6CB8292B483E170B1B226DD6E6E3A5B4729DE65450EE7F73378D11BC49BC2713E21CDB2A9CBA56884BD4D5FC386186BCF31E07F9931B46825DC96C26E43307995471E4BEC98BA840060259BEEE564CAD290E9A7FB2377A4A49A641C052F624BADD634701BC2CDA7212C269E24BC11CD48FECC23AF85DA3AC7E8C9260B35324620F484321078E228D50385FAA299F142816EF3100951828CA870B36F9CD006BA468BEC6ADE876F71FCBD2A7939409E398941F5050EEF3D4373ABC4A688930EFDD4C1A59C8F85E0F356E79D4B580DC8EDB2B36BBC5AFC074251AE77F4E60D9A9D70718619EB19C08E81EE6FCC85F6E725445E82143F0E39B5944729378B8A0292F5FC51E1B5E142CBFC8A513D4D850D1B7D0D7D3C52088C26B7E5912B41F665A12C5BE6A51402A664B94F7E97A551E29F0E81299A7EA0A47CABBDBBBA70F462060167601A1EDF633F78B8CE84A14133C3FB742F331A9783FD327AA78949D74F3B8C7D589E0B6CFB400680D8108E1F383E79BF9F669B811612499C0E646D3AE53BE383467C5BC78DB6268F96889D4162540A6EA3E92D1005DE4A140602B7EDA13387A8C2814970B42B2218FCE418612E9CE659F9C4E98AAC2C6D705CED555ACF824D0727E1186AD68DC078743868BCA3E324C2EC14C5BA0402465B65E2520F372E743D552328A455BAEBCD97BD42FF44E3E1FAC5565A4AEFD3BC8162718B5AAF8BF0781AFCAA06172231846B32C2D19B9477D16DFAB9F8E9F73C8DACE2EFA7AD95AA7939F510CD1DF9D6627731DCA40050086E82DC6A1464306AFEF5331E54B09C468C909290F6980959878045E76DF422904F11F6AFC9BED207491975D28D5C2267683428360ACE050977469CA180BE1A58431FBF7074CE8D8D506E92FE8936810FEFEED2CA1220315B13743580B774DBE79DAF33BA81D5171691638DCC11DDBF30F52218E9FB992D50516C15AA3147BA2E55B154019A76465D09E23BB843904916683691E006A477551F6D80F7F9CAB3DB47CC2D77C266009EB4F9449C81B237F7C3524AA5642422FFF5514DB71442465E558899F65A706D0B3562CAC0B98D69F91F96A3FB87B4426A9F5CA9BF95F0FC3A4EA18E6A97BEB85BF7A004ABAAB994FB0A4300F4F4FCB74BCBCD4DA61A0320CA538196E49A468479AA0E0E675D5E44827EAE0886C7DA1C1662A9D0DBEA1D4C12E61A62D9B840C75C3E7AAB9DC9D64A03394F2626349891FCD3A49E4140110F3714936614E1B790CD196FC7C5028734E88CE04C424B8C3F7B28C9C6FEB1BD5D072D1F9A4BF6A8F680F192CB00742", + "k" : "19668347771C8781F7CC910E58FDC10548B76FDF6959BF834E9902E86EF513FB", +}, +{ + "rngSeed" : "99A9CDBFC674AB3FF2C64CDED7D697A6E27A767434A47AFF7C3FBF3C6A22D6043D27868955286A13EFE3DE36D22EC48E", + "pk" : "212BACC3413AE8C00A2B78CC3B0C7958E349211BC64F036A70AA16067882330A36AA4CB183497C0251B2B942964A922C25525EE9E3834504A085540B36971963E09106FC14125659BAE0C96E6663A479A381A915FDA7B8A404061C90B814C3146A549B517A3735760244EA8959EB2D98BC37E2F7309E09749C4C689F6B640D28A7A0B8524FB9BC0B544EB219683BE91E79BAA327B5C0D2F2713B78341C9682F6941327959F853195AA36B919E07C1D5723D6528269B360984857DF1636F2A80CF1383A775C230A9991F8602D074B5F0BB42C13CA1EAF4B3C7336A4FE61A8310C9C27F37454F9AF3FF0BBB2232689C63CE4B7CBB880886B36681414902BF77A2623AE5F0C359C038F82433413D2CFA88373BBD17BF1D5503774939E916C415C8B929B5C2303234501BA642B75EF2823E42B71647014044A9450A55CEDC0592DA6554CF74693429D2D526D34851FDA24A64450C785510111988982914FCBA3ADDBD0963C3BCE55F41B3CC71C0300BA32B02FAC76158D673AB1EC7A23B30AFD2A53D5ABA3C3C87E0FA54408864037511DC3EC113153681D28C45B2A25E7256B6FA90DF8B8BA8435B2F90727D4394EAF49981B397916C1642ABB68F5006FBB2BA6C2C53B6DC5795A261BA674778FFA7E9DAA65AC93366954710419C99FB21A46B029242158294107DFA28C53554AA3D79878B53506EA03846A9041664BAB6056F7211A337910F77A2F37B993324927D64AA0D5085840475039C04ACAF0CE5721B1F182B53E96928927961B8A04500118A453738C78B8A796CEEBD960473B2FD2C9C825593FF4A95F3F659EF00B251449A253332171BBCB051699B100501F84BBC64C4E7F9C7DB1190C4621664FB33C624910078155C1F2035D1755F7B10112E4521D58CB9C89575A3A2FA6CAAE5DBA470A9B4D3FDC9B7CA6AC28E0570CC92647D382D04A5091D8A1EF749067848CDA293A47D772372820F25245FF457580857EADC0BDA0A059ECF1A3ADFBC6D7E87184337E94231E8E3774C9854EF1C6B4C872BEA6F939845942FF2732AED903A23B72CBB5122C43C8ED303AE0D33A7A704001890F0B378039CA271205D052FB594C526E7C761AD6B0CF14BB251225C7FF42B4B5F651ED55143ECC05CDB21962157E28D7BE4FC4B5AEBB6CFCE5396FA51AF1BC85FDA50B00FA63ED800D60A5761DEA715258BCF597A434E48B23202D8A415831C0417C6C43A659036DF10772E796A2D70515939823575CB5C01D35155F7399BFE1B3CA9BFA47EBD69F5C8CC8879B87AE34A7DC32568817AA3F923DF22C92BE454E99D83023D3CAA2E80E0ECB8818414B0241A6315AB20B63C422B6BE8572B5E7F249FA3802FA647FEBC89C8CCC22583C144C191B91187257235D857B9BBA3B13DB06BE10A35D712C540E7BCC62373D76E5828BE049B6462D8DA931F24A6827D314F5C0AD266A3529FA9B47CB6EEC425B326AB0BFA032B6809D82C1CC3E2427787A413DAA7D3976AAF83AC08D87B34DA219A92A631784BCE31CC66693C75AA58C7C87A9E3A926B5229A4F008B85090F351694F66743DAE3A59A86299B43C20522CD82F96284623EE20B521794114D1459FDF70739558123F18FF8304730FBC63F198A2EB992E7115E07F509DC58B1E2A00C314714B5162334861EC20ACAC85664D14057D2788207C01A7AE383C93971D850102D60AC0D042C648C100ED660EF8A2CAD375AE1A21B11998264E86AE0561E19D971689183968A98BE064486B8ABC3634021F770E2581B4383AA3C938BF3ACA4AA2A337EC06647AA47428BC027339F2802B9F135820F3A8BEA06846BEAC4C1A2702C502E50D338FB80A590A564F48A6606A10B51E839A4034F2B906EA34B4D3C875F1FF6BB57797B076638E4B576FE8C5A490806BFD178B4569A69626001C8A5FA1582BF4BB7BD586296F9AE74724D7B6C9C38D25273E114FED525AB008B887B9E5871172CC393938902914A3ACE06A41CF92F6DA963E4217F6B1363F7273CBF4A342865A761371F24285113E74F7A770079157C0BA0700E6BB9CA99AE10B83299CA9445B8024E450CB6152FCEB79C0C433753C0B88B21C71BCB38C643AE5E16502FD14C0AA8939219005A15180446A166E74933F46F41A68675692E25816E7A227808764E20C98D33D6C3EF3801D21CB37D2872FE76749AEB09976580CCD4FEADCEA0B16F00970F92ACB21C560501728F", + "sk" : "6B3B1E9E6771D2B6946533C210A8BBFE297DF569CDFC56B501C54EC9E21DBAC3CA24335438A71C456842CE4653EC9B4ED5BA80EBE665B40597230213F58951104C7CA0F225EB535FAD8C5724189B49138C22F4478B19492403C2C41C452080A2625654BEAB411EE59F1F372EFFDC5DD282A5B4244A8D7A0ADE30386A13A353D1516CA38991948497A4CA83CB9F65F5AA1A6AC85DFA634253068B2B43A1AC8C41F156E0ACAF4F05505EDC57A1A6BB1A890C15D35967B86E84F16D2A1056916C8F90DB83B47275B28CA3EFA0BD4F18B9CAA5B480E80566CB3951D606887777C2C3BCC88640A6C1C826EA51B169C8BB11A7F51B084BF0246F93990E62AC6F012B89EB025B5962E9A6BF36564EE9B483895B2ECDD6699421ABE9CAB8820771E121719922315DE8677FA1214E332379CAA11133A5FFA13DBBA75C6491308ED201C23812DB0A8D006C9CA9E7606C532557C8555CB10D6194284B71275CA84EAAB50E50470FC9E8C2954B70ECD96DDE6937616618BA91B1FA858335605C162972495C4846B46B6831477DC5658751C0169A5BA0C733863555F62C5C1BC5C83BCABBDBF1438617412BEBBFB5705622C258A301CAA76A4561099C3AE34EA4E014F89431CFB957C6A930315B7A001955310CAAB03076440594F7A66C1385637B69135AD50DF1934A1BC754EEC983DCF351B306A14FBA9EA5B6A416FBA9B46A40C99B640048AED0E4CE74771704A3B3A7C90009C964E7B055F4753BF062349A368AEC2423BD6A278FDCB3D9F0C81EF551A0122A72175E76D5970FBAA44FF8399FEC7498E59DCD685A6B4038B3B5BF47DBBCE204AD99B8945BD3AFAA237AF16A81DB0C15A906364E1733427B28040539D32832CC5A7F0CEC282ED902DF9A0AF281CF14256DA8873317FA5F6E9149A2D6AB544C97697683032455591C75EB2A0BB4AA5EEC1C3499B64B78729B6CB7553F1653BD4181224CADCD62AB80F5AF7478B909A4AD9DC1CF97E608234B48B2D9B005A5CEB80CCAFAE85E431A258C77601DC3764823177E970AB5763B154447DE89CB2C6CB11EE51195F59977F983C1629DFC640026A8C36B909D4AAA9F9E0B642140A35D2A5FE503A07A800C62CB4BB7C6334C056500D14337DC984C7730FB37891BA737F2A65545B2943BC22A5099345732A1129BBE22E88B987AA1C8E33934323006EAC14F03A9970CAFD6EC587D15544ED9950D5A851C63898C3B2331192E0FC620937C30A5E8B56355319CCAC8094CA136C237941372B17AC5367AAC78269658F4B40D04B33E84961733A353BAA9D5F4B2DC69609CE6A00EE6AF8DD425D2B04BCA841411473070D7A1F4042A8167CDCD138634619BD78C5C37511B54B3857A897F17FA02DE663854196418B4B23ED80008B6AF534B28B1F0027DBB41EBCBB83C9CB0F0080D5E9C8E80A83D120A0D679C9B3EEC7D4F94C9046832D947A622F7509D41AE888107F5FC7539CC0053A1365CE005CAF627F8185CD1355D4AE65638C18510B93EEB87642CDC87FDB858C4A997BCE0963F6B3A1318C206635289AAAF73A33CC7D76977E3570AAA98C515436EA39CDE485342A4503D991AB2E374EF2CA8E221C71840B876100AEECABD475233A40122F2832193F40BF29AC1FE71C1EAE1767EA470F3E580089AC09BC1737FA3449B4B9911C114191614599A8B8E02060517C57EA13BAEC5AC77B34B7AE21C2C9646FB6B6F9A0A3787760509E3CD9AF200F8CAB9DAA5A4BD7A9C816B4FD7D3C0905A2347215F5EC01E40C605DED70EBF472B1CA4CB684272DCC75FC17A3A150C06AF61CA0573AC03473C395BB35B34BDB0D3297A5C4729A14345546124377896B11975C26118D79970C76128502D474B8828B3B01A9BBAD62728B8593A254734AD208F29722FAE409D7F178B4A0937E86542527201A7E4C14547B599408552952CC65128533C4207AB047287AF05E9BC5EF0B110E4CE977660CEC3ADF062A154C24CC86494BF5B2F3F1424F42A7308D0057F041C077528030182295A67C27422AF6180A2010E4CC478444B595CA065B8A50DE1C775174BBE870A874BEB8649D82C07A68341165C11ABAD1FB5B7BDF2BDA1511543108158471D94C3B59AD199C868BB67E210A724909B9452DED168587247977A70DA79B3750C39F319B44198A5DBF047CE618C212BACC3413AE8C00A2B78CC3B0C7958E349211BC64F036A70AA16067882330A36AA4CB183497C0251B2B942964A922C25525EE9E3834504A085540B36971963E09106FC14125659BAE0C96E6663A479A381A915FDA7B8A404061C90B814C3146A549B517A3735760244EA8959EB2D98BC37E2F7309E09749C4C689F6B640D28A7A0B8524FB9BC0B544EB219683BE91E79BAA327B5C0D2F2713B78341C9682F6941327959F853195AA36B919E07C1D5723D6528269B360984857DF1636F2A80CF1383A775C230A9991F8602D074B5F0BB42C13CA1EAF4B3C7336A4FE61A8310C9C27F37454F9AF3FF0BBB2232689C63CE4B7CBB880886B36681414902BF77A2623AE5F0C359C038F82433413D2CFA88373BBD17BF1D5503774939E916C415C8B929B5C2303234501BA642B75EF2823E42B71647014044A9450A55CEDC0592DA6554CF74693429D2D526D34851FDA24A64450C785510111988982914FCBA3ADDBD0963C3BCE55F41B3CC71C0300BA32B02FAC76158D673AB1EC7A23B30AFD2A53D5ABA3C3C87E0FA54408864037511DC3EC113153681D28C45B2A25E7256B6FA90DF8B8BA8435B2F90727D4394EAF49981B397916C1642ABB68F5006FBB2BA6C2C53B6DC5795A261BA674778FFA7E9DAA65AC93366954710419C99FB21A46B029242158294107DFA28C53554AA3D79878B53506EA03846A9041664BAB6056F7211A337910F77A2F37B993324927D64AA0D5085840475039C04ACAF0CE5721B1F182B53E96928927961B8A04500118A453738C78B8A796CEEBD960473B2FD2C9C825593FF4A95F3F659EF00B251449A253332171BBCB051699B100501F84BBC64C4E7F9C7DB1190C4621664FB33C624910078155C1F2035D1755F7B10112E4521D58CB9C89575A3A2FA6CAAE5DBA470A9B4D3FDC9B7CA6AC28E0570CC92647D382D04A5091D8A1EF749067848CDA293A47D772372820F25245FF457580857EADC0BDA0A059ECF1A3ADFBC6D7E87184337E94231E8E3774C9854EF1C6B4C872BEA6F939845942FF2732AED903A23B72CBB5122C43C8ED303AE0D33A7A704001890F0B378039CA271205D052FB594C526E7C761AD6B0CF14BB251225C7FF42B4B5F651ED55143ECC05CDB21962157E28D7BE4FC4B5AEBB6CFCE5396FA51AF1BC85FDA50B00FA63ED800D60A5761DEA715258BCF597A434E48B23202D8A415831C0417C6C43A659036DF10772E796A2D70515939823575CB5C01D35155F7399BFE1B3CA9BFA47EBD69F5C8CC8879B87AE34A7DC32568817AA3F923DF22C92BE454E99D83023D3CAA2E80E0ECB8818414B0241A6315AB20B63C422B6BE8572B5E7F249FA3802FA647FEBC89C8CCC22583C144C191B91187257235D857B9BBA3B13DB06BE10A35D712C540E7BCC62373D76E5828BE049B6462D8DA931F24A6827D314F5C0AD266A3529FA9B47CB6EEC425B326AB0BFA032B6809D82C1CC3E2427787A413DAA7D3976AAF83AC08D87B34DA219A92A631784BCE31CC66693C75AA58C7C87A9E3A926B5229A4F008B85090F351694F66743DAE3A59A86299B43C20522CD82F96284623EE20B521794114D1459FDF70739558123F18FF8304730FBC63F198A2EB992E7115E07F509DC58B1E2A00C314714B5162334861EC20ACAC85664D14057D2788207C01A7AE383C93971D850102D60AC0D042C648C100ED660EF8A2CAD375AE1A21B11998264E86AE0561E19D971689183968A98BE064486B8ABC3634021F770E2581B4383AA3C938BF3ACA4AA2A337EC06647AA47428BC027339F2802B9F135820F3A8BEA06846BEAC4C1A2702C502E50D338FB80A590A564F48A6606A10B51E839A4034F2B906EA34B4D3C875F1FF6BB57797B076638E4B576FE8C5A490806BFD178B4569A69626001C8A5FA1582BF4BB7BD586296F9AE74724D7B6C9C38D25273E114FED525AB008B887B9E5871172CC393938902914A3ACE06A41CF92F6DA963E4217F6B1363F7273CBF4A342865A761371F24285113E74F7A770079157C0BA0700E6BB9CA99AE10B83299CA9445B8024E450CB6152FCEB79C0C433753C0B88B21C71BCB38C643AE5E16502FD14C0AA8939219005A15180446A166E74933F46F41A68675692E25816E7A227808764E20C98D33D6C3EF3801D21CB37D2872FE76749AEB09976580CCD4FEADCEA0B16F00970F92ACB21C560501728FFD648A3B658CE84640D17AD1564189385FE895B25CD30D122A90DECAA0583B90D55EEB68870B6DF148654F14EB4B3AE9084B40F8B5CBC83FF4C419DBBACBD190", + "ek" : "F44DE37EB840C36680B0B8421FC57FF8F231D73540113749F7E85548757A3B9ED709001D2A85B2B45E261C6184F71CF53FCFF1491A02857D8CC2CF79E572207B98040ED9D177EF9D611B5BA34F7D065D8D7462B44ADE3D2F3A1AB59F19FDEAE02A1F2A103226D90412EB07C8076B75D3129CE077749155974947588EBBF99C5CCCA965C045E3EEDE74E0DF502FE5A94DAB14431516C1BEEE649CDBA7287F1C362F870C8B48AFA8E7BC5DDB37C800ACAFB4F8DB0E61B837A74715C59B0DE5D4EDE42AE8A676276909AFEA732FF977D927B475D2C3E1FB5422861D5EFC7F914DC42707A7B7FD6A9F30FE852197BDAC623EDF82792A3BCC1AE6F75B01DF2FE417F9495F3B0B3AF74C337A538F91D88D2B47B7CA47F6B58D1949884272EFF583ADBBC2266C85900558FD5ACE80E26EB95155BD1107B6B965B82A9E34777C3B9B0E811602114A03ED52E612390332A11228FB0881B41410D217306FC17E2EA1269CB0AABA8AC1EA09F7059E02E25FE793AC1D3B3BC9A717F25EBB62C2D0B8491BCDF12755435976DF37D9DCD60CB5FB8D1E390E34F30E4224576F2EA709805A2DED0DEC5810A11C170CD74E0930833F15AD212DD662B095D730A088CDC686C0CB345BDEBF33E68902D0BB61D99573BA4590A703F430AA1DB5900C5753DBFDDC5913077980B75A43ACCD9603207D3388840BAED8D4198AAE7445FC856A14E50CBB0920BE07F94A4EE0681A685029ECA8C4636E639B74DB8B4E8FD291E53379193A79509EA3C4B71022EF28D2CD391C5C1AF9DC37E7613ECB230693E42AF11718FBFC3D4AB4EF809A5F0FE50977F0E106D8045939941A9A364A11DCE8530D8E0E5016C917B6051E1F7854F27E93158F8A65D582B0AB347E133A36D7AC7FEFACB32D4B43DEA2EC5D1769FA95512988BC865A052695B027B25F8188CC661E003743392A9F0DCED4A96D25198387F63A38C73E6D7DCFAA2EED16F3003C432B167503D7BABC5706F94E6D7A87D5E87E29B1281E54BE22FE3477A72AF44E679E1EB15F475B7366EBFA96190E1BCF2FC5E08423ECE2F99FA63A657A950A1CB62AE9CBEB8626113AE45447B2F5DF805836E9E3C404347E0DEB909761BAE86AC5DBA26E5D6DBF3F49C4C0299F54903E81188F76A47D90A991E8D44A1185454EC0272997A8C4D14B10F770BF847518DAF8D1BBCB3AF31E94E4BEAA8FA0CDAFD12DC6CF42BA47FD426F14130352DC80EEE93C7CACB5422212C2FFBA3F4F29393E7715AC6A3EFAC8286266A8865969B8A92D1DF64530EA292EF1E1E9E76D19DE42F60B688155106FE2C928D57DCA5F4E889E9CA381DA24423B651C080940D6B2588DBFD4B3A4EC88A4460DF4ADD266257AD8E2B5F32A732FCA1E3FB63D98D8A913C059690A8CB5E0AE8C6F8CD797F8B15B8DF49E187F386351564F6361161F3D3AED0ED10A824CA5DF9152541D0A24B22B454C9A6A87E91052556886AA2DC942D10DCC30148E2D30FD452368BC6F02DA920EF49A583E38CBB1172232C71D3C1B167425A26A04C6D6B79806A676AD0E32E18F5F950B45788481AA9D560F8EBCA66C300E689FD8180DAD7ACE8BFA1A99A39386BEE22C89C1B85F66F18CB9B2F2946B90EE99E346C9DAAB9B6EFDA08B9127471B48BC42A2561D12523B8D4396AF3F84BAC2EB6196DF5F3EE02E15E2DC122A95553F35D52C3686630D4A145A956EC0BF06431AF9D0F8EE50F5C595DE7B639394C6D257C6841C44FF908962617FB6A4BD8B635B7FC02462B68DD583282628D3A201F4400F61C158B07A7163A32785F92A984A271295BDDE265B29631A1F0DBB38D9A97E90749B4343A3B8F29A9725179EFE347E9CFF39C32BC07AC7908977A4B9A092E4FEE21B51B2F9EE4FB8C8BDBE4B85F335A0F45F5E4C8537D009DA4464A7978089B4F134063AAE54932EAC1F5749481FDD2895E6E862B29B0D41995DE2129068DC9896BDFBD8363BAA2DC98270B23F9ED09EB5DE6CEF8B5B10F14BD5B69B1E5E2AA997991ED54452EB1BA76249D35560C1A8DB1D64599EA795F6D08CC2FF2B8787B6B84905837CB041E3AB24BF8B75FF129FAADD41532237ABF95D9516482B04EA7E5109C4B3709E63A0E12591E82C3ABC9CF541D2DC201D4CF0354B7D77C528452075EA0A12BB0FE4DA3186CD270D2D86200247116E1408E273120263679DBA1D519E4116BE9522182CC5971E0610D33F12F2FAED5F", + "k" : "07E841B1DABAE13F9960D434170D315F6D84B131DBD7834CE6D3B9E01066317C", +}, +{ + "rngSeed" : "C799D57B41F28C5C446DFC58A5AC6499C4BCF3C162AFD2B09A16549826EC2A6F689E44BAFC4ACC82F5D6AEC23F4A3993", + "pk" : "F81037775C727839696ADB115A704F10199031D9BA3D3433ECB50702068392AC97A2DB354CB311DC39AAF9719C4F5A7C0401282BA4697CA8C70EBC4E179893135179CBF02820D6BB7263708B2339F777C242F4C34155AC2452CC21904580B381A964C281D750C15C42D8477E7708C45C61BBEFC6928F191260409AC31A61400350E928A3B24C313A71020FD186F6E9AFAB17BB065132588C115C31CA8C630275B4BAAB7A98A778B97A680ADB4611E6471683352B6928B7F0378105383B5F981923E800FF11CE6B64904AD3835C270CAD0CB0A6E1B8879CBE152221E6E0994FEA9BFEB9CF4F582E4F429170295A8419C984283D79B882BB420876588AE6403F207B3798D89DDC1BC90D7C91D7D07AEEB2BC0E491269281CFE93129C5283A03630542A1312BA5C896B969AC0ABA14A289C0672B964A6CB1C4A11C3617AB30E4BEB8B8864285087A15C574C833166C759741F493438A535918C0AB0E46926D195802A5CCA3078FCF3770EA9644A69C730314F3D91B5E04150B670B23448008EE55F841C148A699387D919DCDC63A23966A43B2927FCAF47F2CB36935D65622214403256753EF3DCAF73D183C79384E7914BFE597363684355F25AC1042505361A04798E377791B5553C449927EFDB48606A272C029A2DA819A48749BD66A32091946A2A7A0649095DA1193C1650AEF47099456861519BC8701477BB5B01359C4772269735485B829835861496E437A063838A0419AE6877D0C493B5C3AA56777F3A727E0EE5825DC83AE9F4A51E612002748A5D1A21C1F870F5886B39A23E0CFA14B6151053580A8D8A306AF04A7418C88BB5C398C6CD8F6529EDFBCD601C049872C11381AB10C0267C0C8C2F614B16D92800DD0989FB2A23887CCF46401B864552105DC79BB0DEF57EB8B6974723A9164C2737ABBDB793BFBF00A860A185D3A81A2257CA91E09F547C6ACAF35AC5833FDD9A1F38A5B4F5E227B3FC692677766BB81F85E34DE5B200DD077573F0796175140FA9C920522D68040518C5AA8F84B1CCACBE5BE03E0A0789372C338A1B24B47A8BFB0941AAA8601A7937D5577FDAB4A6D3094AEE7C073A7632F417B63383BD035A351C3656B0A52C6E435D6D6699946585B6EA9E8568307C18C025A80E9074629DD70DAE6BBDBA296E0897C8EA895FC6B5B446D1000E4C880747798CD42C860C3BDA63607B69A6C4FB88082593C1D965AC6CC71125CC56A72B60D1297605787819749D43BE46431959AC29A01C3EBAAB30D9A18C1C7998D9E29415BA0CD72C0D933086DCC1C20C537A6F296D88F29B5D2A21FE314999CB6037D539081120D60206EEF1B1E1A498EB65268E94366CD8912D269B2D12A3F1B99572E6138BC29FA5520C8A6CB23F90859EA0A494C17FE7AC09BEB658F260CBF3A5CDF9933CA1659F2A0551B881055406CC6B72BAEACCBBC4B6964751AFE07754DA9A8B0B151F02972DF2BC1465929C0BE64E38E6C55ED237F182151D1A91E4253C42D05BADB82CF3457E01CB59A96730B5007AE0FC37A3A322115C8560F0A2A1395A88464728C18A16BB249C168ACCC3165305A6584939105B594AF244C2BB41405163E5BB50FDE104E7DC604A592B9E22649C0686BE9A8860794CEE458A73796ED877B18E034F2F50B8441609CF53280F9C095FD67749871245A4C2BC9CB008EA3E44F424DBD56A7C734B1A322DE366541C732FD5F74A0663A61F277301723579158ECD08BD014C5CFDB7610B61789D8B84DA23A58E571A72981CF63CC49C59CCF045ACBD3CBFED4571F6DAAAB9B23BF26091BC581CBE301674972EE4420E7E0740BED617A3C94C3CA3BE7125C7D6242185163398458311937ADAD8462B0CB3D5900994F5906121C20F6731AC81A32A864EC383BD8310BD64A30F3D575D936426E721228B93C0C482C1BE106F4CE41C5E0057116B30CBF44AA2A217B08B690FF891657188D3B6702FFA9D8ED7B62CF78F6831A13B410679E60FBF9A3221906B5885404A7326589681C1549B9459745455BAE21CA799796065925FF980AAA68C206B17AAD1CB9511201E53DCA34D439167D55924018E7E513FA919A4573B5500A91C8AB61F17CB5BCC282939172217365EF694C98A440B09C883CCCC114769B84CE736C5C9C52B050EA16A0E4B8C58465438B7AA11C2C98ECF4AEA6284CD00C4229CB6FE2F90DBBC05EB935C85F1CA2AFDE0D54307949544", + "sk" : "41B21693EAB370113852491E3791739EB8B3BA69A2C2542A85B4C536D840D4B90800A7A6062B7C98F920FDB11BA6B0262A647DEE2570F422CCE4B7673B51670BE0694083C23FFB380025279C849A91D147AC85A3EEE4C8ACE51C314B21382009845BBC56C9A967A5BF25D1BD75908CCD0A5B86F14106998B27A41A38C365130A420569975DA13BDA305553750BC5B9402BC38646857BB50A97D016749CF7394DC35BA1F69C17B080A6961203514EB2520189B846D9597D3E443B0168028943BBFE80B1D0E4A323F61324352AAE686B1AEB914DD33745DA83F9451EDDE1359A630A4C79B4E9AA7CBC464B1F3923E981654F80922EF604465740938A9484137077533F4F7C379312306C6A26BAD108CC16C59CB729FA6CA21FEB2365F12E3E32C75B95CF9201BCDDC2046F93893DB11E35103303478F6A661E4747C854696D6FA00B47F3B18E32469E3B9312225B1A877EDA5B2F17699EF4BBB5054961E2A7C445E70C1BCCBE6613A4F332B380FB21565C809FD593E7076C42B9B891DA4513742E45FC4E60934583F888F399B4A3A0054BDC3639B73F756B94EDB5401FA66211D2BF7C714F527C48854A73EAD8993FE1B3A851048AA638B2A5538848912F6672430273E82820044A6D6A6B4B80EA6A12AA1BECF8B647292A2D328877C10D64706DE00A677F0399E30B8842633E2246109A407465F096A1E4B9F14605387494E3F3CC7F200E4398B2C234575E022BCE0961B0A8686537CAD6054A81FC83B6167C7A855D54E662AA29358BC192A0925D00D15A4634453A494C96758AA687476A7B15075045684B51A82225A562C2D1C28B36CCCE25668CED9CCD0CC58522D36EBB6C0368F67104F6C8A240B976C59EF5B46C62323CFE74BB95A55C8EE3B934253DE101A11832CC91D685CDC1599DA17362763ABC4A63A0C13CBA2123B76B391D20592C8799BF86054203307D770BC87696457962DFB39FA988A954532671818F6D7438CCF3C044599486E6B781933A45692E1FC79FAD5A7D8FD8BDE635AC05C631ACE040F383B9E5AA69BF39243C711455F605DDAC05EE905AECB6C971BB85C1ECBCB695810A713FBEE75D71362E5B6777322528BC54A77B6A979ED7C48E9270ADA7824814957563585334998FD6AC4566BB22DA8CB18A425BDAB55D61A1B8427AB1B817E8853EF002CF00389DC36A8E739C601BE907D749B4165CA166E6A42253C897A6112D2994A0F492116181081356AB447787D3C8D399A807D48860668DFA2AA8890CA8A7128CD38CBFF5EB5E6FC5A46C903EFF075AB70A36B85958DB922CA9172F53B7202744CF11452BDEE486D44B3920636BD7962C3622633324A2BB5B82FD3225A0D83B9FFA6B433B19B49A11DB2A19A7A5587553A4832A4DD2412502A575660BBDC1D9A23FC6AC2E7047EE9941ED3B99E7951C81D6473B440416A18332914D97B7C6897BB248876AD757C74D83950951C0D14724D99CAF72D17462D006E4D0064D14057A2C1488C79FAF4CC08114C9EB2C6EA68220D64735CCF603BAA718BAE17D130457835019E7E943A43347F7B3253E750BCAF71DD0F0A63D91C7DEB97E270209A942A9512B635F5C704F830649909C7C1107986BCB7DF1A191366F80EC694C179BCD9029F62880C60061627078B2D3277421169E45AE35F9991730159B005F50CA257EF3B1194B46DAE425B9D67E1692C9F1C94DA299A19AEAB00F45C62449AF52C81633403E2BC77ED6750EB91C1735411A32A9BD458029D31C1673C86DB6EB6C739021BF1508EA97B902A14BBE298F676258D9260C9F7305D5D1248332069432941AD759F3488D3A2C927793ADD8AB08BCEB6524F8B6F5103C2AAC069D0C46F8C314D1C77A86A605DB2A773AEB8B44EC8D12477970167CE70AB3A449276A7540313927E61239E23C79BB260AACF4C7DE036CDD5A55A45A8A7B898FD8B209C6F643B4202B16187A87842B33F0574FD0A4198A7ECF7B46282B8344EBAAD63AB34A652C22521561F2C74A68C485F4CF22735CCD203A8265AD5EA173AE4B8FB0CB4CA979CE33557BB09010767ACC4B881F24FB94CCFA008A020E3CAB56CBA5C3C6C87D4BB6A2448A94C55BBA200681D88878563B05454CCC7171A42ABCC545649483418BFAA6C3B1E568B251962A75853B6634872529D31B32FA0C29F81037775C727839696ADB115A704F10199031D9BA3D3433ECB50702068392AC97A2DB354CB311DC39AAF9719C4F5A7C0401282BA4697CA8C70EBC4E179893135179CBF02820D6BB7263708B2339F777C242F4C34155AC2452CC21904580B381A964C281D750C15C42D8477E7708C45C61BBEFC6928F191260409AC31A61400350E928A3B24C313A71020FD186F6E9AFAB17BB065132588C115C31CA8C630275B4BAAB7A98A778B97A680ADB4611E6471683352B6928B7F0378105383B5F981923E800FF11CE6B64904AD3835C270CAD0CB0A6E1B8879CBE152221E6E0994FEA9BFEB9CF4F582E4F429170295A8419C984283D79B882BB420876588AE6403F207B3798D89DDC1BC90D7C91D7D07AEEB2BC0E491269281CFE93129C5283A03630542A1312BA5C896B969AC0ABA14A289C0672B964A6CB1C4A11C3617AB30E4BEB8B8864285087A15C574C833166C759741F493438A535918C0AB0E46926D195802A5CCA3078FCF3770EA9644A69C730314F3D91B5E04150B670B23448008EE55F841C148A699387D919DCDC63A23966A43B2927FCAF47F2CB36935D65622214403256753EF3DCAF73D183C79384E7914BFE597363684355F25AC1042505361A04798E377791B5553C449927EFDB48606A272C029A2DA819A48749BD66A32091946A2A7A0649095DA1193C1650AEF47099456861519BC8701477BB5B01359C4772269735485B829835861496E437A063838A0419AE6877D0C493B5C3AA56777F3A727E0EE5825DC83AE9F4A51E612002748A5D1A21C1F870F5886B39A23E0CFA14B6151053580A8D8A306AF04A7418C88BB5C398C6CD8F6529EDFBCD601C049872C11381AB10C0267C0C8C2F614B16D92800DD0989FB2A23887CCF46401B864552105DC79BB0DEF57EB8B6974723A9164C2737ABBDB793BFBF00A860A185D3A81A2257CA91E09F547C6ACAF35AC5833FDD9A1F38A5B4F5E227B3FC692677766BB81F85E34DE5B200DD077573F0796175140FA9C920522D68040518C5AA8F84B1CCACBE5BE03E0A0789372C338A1B24B47A8BFB0941AAA8601A7937D5577FDAB4A6D3094AEE7C073A7632F417B63383BD035A351C3656B0A52C6E435D6D6699946585B6EA9E8568307C18C025A80E9074629DD70DAE6BBDBA296E0897C8EA895FC6B5B446D1000E4C880747798CD42C860C3BDA63607B69A6C4FB88082593C1D965AC6CC71125CC56A72B60D1297605787819749D43BE46431959AC29A01C3EBAAB30D9A18C1C7998D9E29415BA0CD72C0D933086DCC1C20C537A6F296D88F29B5D2A21FE314999CB6037D539081120D60206EEF1B1E1A498EB65268E94366CD8912D269B2D12A3F1B99572E6138BC29FA5520C8A6CB23F90859EA0A494C17FE7AC09BEB658F260CBF3A5CDF9933CA1659F2A0551B881055406CC6B72BAEACCBBC4B6964751AFE07754DA9A8B0B151F02972DF2BC1465929C0BE64E38E6C55ED237F182151D1A91E4253C42D05BADB82CF3457E01CB59A96730B5007AE0FC37A3A322115C8560F0A2A1395A88464728C18A16BB249C168ACCC3165305A6584939105B594AF244C2BB41405163E5BB50FDE104E7DC604A592B9E22649C0686BE9A8860794CEE458A73796ED877B18E034F2F50B8441609CF53280F9C095FD67749871245A4C2BC9CB008EA3E44F424DBD56A7C734B1A322DE366541C732FD5F74A0663A61F277301723579158ECD08BD014C5CFDB7610B61789D8B84DA23A58E571A72981CF63CC49C59CCF045ACBD3CBFED4571F6DAAAB9B23BF26091BC581CBE301674972EE4420E7E0740BED617A3C94C3CA3BE7125C7D6242185163398458311937ADAD8462B0CB3D5900994F5906121C20F6731AC81A32A864EC383BD8310BD64A30F3D575D936426E721228B93C0C482C1BE106F4CE41C5E0057116B30CBF44AA2A217B08B690FF891657188D3B6702FFA9D8ED7B62CF78F6831A13B410679E60FBF9A3221906B5885404A7326589681C1549B9459745455BAE21CA799796065925FF980AAA68C206B17AAD1CB9511201E53DCA34D439167D55924018E7E513FA919A4573B5500A91C8AB61F17CB5BCC282939172217365EF694C98A440B09C883CCCC114769B84CE736C5C9C52B050EA16A0E4B8C58465438B7AA11C2C98ECF4AEA6284CD00C4229CB6FE2F90DBBC05EB935C85F1CA2AFDE0D54307949544B08A2EA8E2FF6FA677E3C2BA136C16DFFD11094AD7F4ED4C5E7C11E3898A284EAACC8BE341A319F425312EFF5DACB31E6E772EFADDE7250DB9F613C13B454565", + "ek" : "BA00E6B226762EDEA673E56E32E6F0E510D1C599E480036E42A723FD726D903D8731B76E02A21D63CB8DB4EE7B6B56D9CECFACEA4110C93896CFB5AB35461B425474E9079F55A95F4F40888118CF126AFC056105590F38245C9ED661CCFB2F04676052356442AC81CD638C3422B790A112C676308B4051BA615999E5A8E6E86FFDBDC9A32D3E8F0F3897FE37B6C7B6F116CC89E21207D3652FA6350570D6417C70CA54D6FCB043EA62F89EAA605AD005377DB3419EAB1FD57648BE29816892AE1E511F4F402C5A69BDE347253167CCD554663A1BE6C077EA954B4D1C293FE1E0673E909BAC2110899591EDA49CA883BD6C72E96F5D7F21FB7FDB40B01456B0703D365EC92B01BA3092D935053278A9A98C6AD4AF72B0190FF48E1B7CEABEA9344558CA22CA31D1C4E730733FB5F0EC5A748866638EF31C19CEDEB56C461BEB50550B30D0C5BF65075215599B8884F434C862F2189E4CCDAC87E13403A5AD847102981DC9809664BA2866F98ED297189B62EE5D8DE58D9400693A9513BC1F16C28210EC83C8A2E456F19839C445228110AC31A60D077E58C4B7E28B92E3693BDBE3D84740E671E6CD88F85AB0EB9C16DD1493D72F8367A1E523E316B44D9700E53F4E8AD0DD623F2AEAB2C189DEAFC69D9F425C09C9CCAC01F2A0C3596ADF5E4333A022AB1AB48105A9A4A5BDF2A4DC9F973DAE712496D7047EF799A739E0A2E8DBF471FF11E1D73F325309480073CB35EF6F20A4623DA9C18563738A98F4F3BD1E6B170FE2D3D3044E899BA4F2BFF5E9BBE43AB9E0E5B9DEC826526685F422EEA326DCF9C1123F2FAEE183A4F0AF5EFB091C94BB8B1B618EDE1CBBB11C81587E856148128F715D1D4004A68231966B0B5028B5264CF18D5A950EAF006FC55AF6B1222846BF1B39432DDDC0B5E1E6D11118002A03026705D1F35E4E708A2D2E224EE35DB02A4C1B8FCAA69E5607E40BB74919F644625F023D2675E20D201DDAC6A58EF5FF203FF06724DF5D0916241C952060D770A89868D2E25ACE6358044FD3C85D5DED056151D59E9C47F1162DCBEC8270F513AC4A192AC5A3140680D146B3360F6A73EF20FF73BBA29CE663A937B761ADF01A5A242D1CCC5D71EC1188E341F36B8A5BA7B273FC3E6D7AA07E33ADE6FD1D3CF000A4563DB992D7ABFF688F432D5775428F77331609C0F4569D92E3485E97AB775D03808CA22F532B61454BA46DBDB1AD12E26471EE756464DAEEBB70CF62B94E5E92DA9436EF6F78F59C736D8281CC0F42ED4DA2376DF0E9AB0FBDA6A67F302553DD3D5E2FCAAFFEB9D51F25454F03F271290B0A38AF5854D7DF0657B4F7A52FAA4652014DBFB54D42A5C4BDF364DF3D387DBB19953B380FC4CD82BE9633C5A346DC713EA7CADCD1B0453707E07ED6AB81578819CEFDCF315BB2B6C81734D4E34842DBBD790456EF4A4E38E083176B07A5D203F5D106473456392CD8BFEA4BC2FCFE2561774C44273922045CEB18F85E806F55695516344DB46FEC41292F4D5122BE597E3736B957CF2E14853F95813E5CAC812968C435026C79D101527AAAA02AFE1A35649CA6DC9A4B3AAB04321250F0D0086D6268556EE44920FBDC669BE7D73D340FF18065EEF60C61CFE1E74E5282350C9B212DFF8B87830417B18434F3E9FAF4369A61EFD7D606EF0B813C61C72B37C93DD29003FFBC256FD80E793C301411E1082602F0EFD6AD8CBD2DFB37F20EF9D51191CC7FEC4DE68D0AD91215BE08E2A04190A38CC8B1A016C823CC2059586854511DB39CB0621A4C9723EFAFF06A9D6DE34A441C12B2F57C9CA85269E9EEA6567C35D496DD0919564720D5D824AC8F4FA50A96F7CAE919B7A37E2A725BDCBDA760B315B33518421B1B084A85595EE855EF626A41D83EA32A18136E77614D1A5E964A3F43CD9E1911DCBCE495EA61277CDF5873310F87B33C7C9FD578285C9274C7FE48DAD0490E5050D7F0825A60962CEA39FBEA39E63333E89CFCC5B8B9EDE2BF9C892B5B3A6B0F0C6713EF865FF81A6BAC17095F87ADA849B355A984BF3F7CC82DA29D559F521597B5326F012571D4B8FB3A667C9E7B160CA80279D81C84CC02E01CBF86DD9697DFA539F39AD7CD59855E3453C38573C652852C821D309F8BA82F32BC200D2338E9DE00C5BEDF7BAA61E6C72726451F783AE78742AA375DDD5A4E37572EA29EDA6B4CEBCED65A94A867CBDF1380303F7C11", + "k" : "A3FA0CFB4C912EB4FCE6C83CB7172023C79D7C71EF4B6607A0506B6416BAC2EA", +}, +{ + "rngSeed" : "F7AE036A0176A9DE9A036A542DD2840033277C44AE936D10B768566216DE9D4395CD42B116873B69D9804BA6CCBC05D5", + "pk" : "5227748594CC5AC52DECBB390CB6A9B8F989C7048017F52231125D91C51EA6174EF4A37B7CB505B4A029F44079E14B957FFA2F8F325E7334BCFB5B023B4801F5F576333C54EF0440B4F7C8F6B3AFEC2524E31943FD6323D8F2300BA1B8095309E41C1EA6016DE8F6CE4AF647DB19467E492C1CC12B5B5426B8339EA122473D1B84C603BABBA7B32534587145B360474A8483BE8B06A6086BC5666A9B5AF8B4EDA929FB60606B85305C89CBD26A4BE8A6B4866808FC2120649A60A3DA2C64330A94DABBDC4CAB2B956B2A5B7DC9E7CBDAC88A71D5C06DF3B192C5CC5DC6B7D10B07846026A3F5CF0E5B2C5D1C80BDE5C3CA231AC908BDB7054190E77D54D40B9E7534DFF0B36EB92652449AA4305967E57C9E358F8114544E0A5B8FF2C490C4A3267A405E38653449B617F26C6A3A74033AC483C074D5D0029D882F3507A7936845A6AB4D33BB4DDA806759852488A06731222681326E9C6691077A35A7791734BC6B8E2511AB961BB1F17EE411AE86EBABF1B4968DA61FAF667B507450FFF1A3392425457BA4625086AB1A871C8386982A322B82B7CF198AD639060EECC1C2E40BED7462CE4C6792764509E5CB9CC28B5A71A26D52658C0B5B951180F903BAD708CA9BF7995E4595B8A009C614406C669468C1B4FA3740A9E91C64C03CE4A3ADECD19A716A82530A508970CF16FCA38AA10BAF9810A8C3334C7B4A29904B7F72BEA3E61505107E641C2BE03CCD6C0546D2698C110CAF2F194789C616ADA3103B5C7F015991D473837E9451C9CBC9DD02333636BBBC825DD0DA77A6731FBC3A831348CF1A3550166B72B4D0C59A5BB31DE1829CC77C235B73BBDBA937E5B45A456198B218B641BE8C05CCDFF9746BD64FD5A759A4886D3022CB63167AA3F37655A55E9ACB9671262AEEB99F6D5618212419B1A41B7C260213B86AD9C995294B9E96E77BA66A40F9B5243BB38E6B7A7311D7C29C9272F98308A5F68C58CB111E33964B797A151588EE515FC0F032B054C7DD35CE5C734B8887465B0B4BB58C491F9953B1133561977F0C25401E6B577CC1CBD555BB8BA7760FB972A6B2344D2222C0FA575717501B3191ECC598BC93BD145800D9924C06C36D0360AAB9678E93138D266572B305B7EA69A6AC8CA3ED647137090CEC1227169754B49324F029776AD3C6C3E33E14170265296C1A7056282074A64690450555945A87BA57B54EB3595DF82E81C1552F19C415C6CFDC0CB5FB32C3DB060DCC208B6BEAC782668EDDF9986E0A1BB5A0941A3745EE0B73CA0A5F98F5928BD7189AC6B20205555050846EDB51A75573E9011F2D7738BB8C58BCD16795805F03A42AFF1B854D3981002614B39B90C6F8BEF32BC0CDC085466C8F55C7935B96157A624665404468783478D4B121D6B6A026818DC04515D0B98F9A1634977D3521316839253B7A847224C3819802D6B84482988122A7C87D069A13315FBAF56C9047C03641B4B008070BD885F1E3252F16918CF03AF8634A8F7291E7B64DF4E14FEAB909C10C7FBED446BDF2557D8A96E2CC17CBEB91515A2FF0B78BF0A21ABCEA847DEB7311E2A782A567A6B1A57BF105A4513DE2C378B1C0186909838A01ABC000A829A9503D8C12F374C0D48A32C6F539A2AB28AD12BC49507E230C9A3881153113C1DDD446AB513608A567AEA199624C98845A3ADF90A5A89A3098091F207B46F28A5659F54C75A01347E18A11DB75F9247749C03C7CCC6B9ED722DA1B118D3C2760216C792B7F2F406397BC9A7F18343812A09E97A0F6C3C3B87179888A6D69B01B9D8C4B8CD215AF5B76F7249747ABA3537044F7991BC30854EB68C2F6F8B404257CFD6043A3A327D457651F0B600415A977D1CB30904BB853B4DC380BA4802B28F7C479FA7705B3A6CDF8A99CE2604AF2670AB6A751236E08321D61D92A27412FEBCA600FE30850F3C86C647746A65B1A9210ADF34003A39C16EA69A626C73929567F1B001923B4F0726337F90124B74E500007EE8938CEBB15E1F993E1EA0726D04A5E3B52579C625EF79EBF66485083ADE6B1BBD0C9A953092FA80755F1471FF7F063A2F0013F429F155609142A685039C0AA540B3E410654803C7F281CE44B9CAE5842F7347B29336B5125586D151117F3AFE13669BCD7991068BDC68676A7F30708906DB24033FC5822B8CBE33012F5E916C80EC7DFB3661E433431CCB796BA70C5A1EE85D63D", + "sk" : "79949CD3DA852B8381B94853CDC981B74971879B0555D5B51D5AC57707A8D340C2070C9395214D3A6C0AFAF0A675F45F4FC779A7443219471570D43BB73CAA4C9501F2A220FFA00B60695B049B8543CB0AA94884BE42276588C4A211908DC979A0292A9B3C891CD2C59E39BC11B725D66CCCCDCC9D35A03D390AD0656BAFD8F9A778222C8FA753F4D78BB1792E87542C8FB3B71043607D77672B1A6A7F7840EB953D3290CDBFB78AB1535AEC0544BB6A6398466EB1711F9CE01C42D2AEA9FC255D694BF4C02B7E1CB6763B274807B1802AAE3A3A95E57C78002493FAEA627BF5BACB17A3B1085BAEA7802958C9BDB398377629B8C8C03057497BD542EA4C6B28C2CF0CF316CD820C6CEC0E2BD121664C252B0B570826AD17490363232D731B4F16B68291C78C3BA252FF110BD756225CA82B38E2B65D9979BD2B7EA0B30D83461F6E09219AF2CE1309CD99A87DE718CD46E40C091603CB572E6DE993E0051F84B55DB3EA6C7A64B9C67BCE6C3C6A0BF02CECF39E93D149EA38B585D77BE9726E662860DAB465959588C9225303C8B4ED935DED42721196747F104F02C17CDF3520F2435CA0F963D9AB8754F13B22EA157D0C061CA65D8A363C8C4278512888EF6111618C18BE72103DE324CDE4CF16F26F6A8421AE61AA867B3854D54E0163811A3843A7984E815A26A135CA43D249D17C9D93F8A742037DB4D95B2FE33FA3DA0DB12B7247D665F7488BA34AC5FFB0CDD0E123E812B6854739BFA740792B0A5038037C59991AAB615F937CAF9B89E4B9742992C5534939E20353C8573D9EE399280984B446A851868775A7A0DA729D8C594A5F5518F0681E22069326B1146D1213FAB35B0C811D990B529F7C7F7D11645DA77CA0F081AD592291BA2A0E15A880832ED7F02FC70908366485A9562CC45888C1304AEEA26E9BA961BBB53C89F79265A962F2C72B39F9CB43118A22ABAA91E96FBEF1C42E6334AA258CEB739BB17A24AEC2A8F59B972CC7910647CB1CA86031EA4B80C97308697CC4F414F7575154D51CE8C9BC9309C92B113DA36A1915934A64CBB358151DC28186C7F71BEA603C73F1C5ABA4A6DA017F10B16053D77CC92751BDF8C59220B5EB574E1F51A374F337D663213D3756F9096B6B9421A692A4820943576AC2A10246207AAFDEB8ACF6DC32B9A6CAB2F1AE21DAB2A678A308E138298A1D947151B5743D8ECA936963271EA15D5195304D268D87BA70E1C1A9DED02EF5DA2E077CC8A576B433716C419808BB187C9FEC2371832A09360525B49D89C84F84D1C10F1A7514077D14515EA63918A76577F1957CB0CC393E7122C097B51039869765342AEAB8106398FFC009E0F403225B2DF37C3D71F93C78763ABB49BF23E7A1C3A1695986824A54AEDA43B3F7DBA478097CB9019390187A6D9B8D9B684AD169ACE6F1B0FDB9184FCB15B0E724FA17B986576B3F5986A5FC603B466D232094402B0571A82864367DFCD17A53C3C74AE4AC0455AF209B05371174312679EE5A8D1A3326B70246642631A479BBE51BB73581549F7957747B87030AC019B454522B31CFA9CFCB7518DEB670BFB4B62CC964109C6773B885691B199259412F49B00C5BA719DB7162819E20984373175170F7A16DE42EF8770E55A6BB6D98748F9A0E6DD1335E2669764BC2754C7223B8A23986B5C7D49D3EA4A5529422A98C7B4DE1205465B357A1C8FC188EB0C4797F847602CBA59A20A4A2842BC05A4DFAC46B1469BE6C434E6FEB017BE1CD206247B6742EDC1141F9B54FA00A8F757887A4D04D0FE892DB899354E73442265251B30CAA18496AA22806425F0DA193F4932BD057C8C7A06EBBC3CF373205DDDA04EFAB885D12396B09C1DF636DD5D5C721F103C93A18B5227AD0E3339D44B804B65A6C628F71FB5AB900A8AB9917C94A51540A7B2F9BADB405853E9823D30A80AB9613556555B4273486927427942E7A6CAA1A727DFC59089F540A2BEB9802C91F324668F78A9E4431C6255603C5F15642E60A0DD843F8FC610FE102716333121105BEDBBF161B77D0BBCBA13296967A68C14AA99A6765718BA3782B3835F7571177212E0763A5CCA4492B94AE59616F9B5839141AF31A774FC32FEDF0A3408C211050948C24A722A48CA6913B32305E7A5194B7E187BC255F3618532075355227748594CC5AC52DECBB390CB6A9B8F989C7048017F52231125D91C51EA6174EF4A37B7CB505B4A029F44079E14B957FFA2F8F325E7334BCFB5B023B4801F5F576333C54EF0440B4F7C8F6B3AFEC2524E31943FD6323D8F2300BA1B8095309E41C1EA6016DE8F6CE4AF647DB19467E492C1CC12B5B5426B8339EA122473D1B84C603BABBA7B32534587145B360474A8483BE8B06A6086BC5666A9B5AF8B4EDA929FB60606B85305C89CBD26A4BE8A6B4866808FC2120649A60A3DA2C64330A94DABBDC4CAB2B956B2A5B7DC9E7CBDAC88A71D5C06DF3B192C5CC5DC6B7D10B07846026A3F5CF0E5B2C5D1C80BDE5C3CA231AC908BDB7054190E77D54D40B9E7534DFF0B36EB92652449AA4305967E57C9E358F8114544E0A5B8FF2C490C4A3267A405E38653449B617F26C6A3A74033AC483C074D5D0029D882F3507A7936845A6AB4D33BB4DDA806759852488A06731222681326E9C6691077A35A7791734BC6B8E2511AB961BB1F17EE411AE86EBABF1B4968DA61FAF667B507450FFF1A3392425457BA4625086AB1A871C8386982A322B82B7CF198AD639060EECC1C2E40BED7462CE4C6792764509E5CB9CC28B5A71A26D52658C0B5B951180F903BAD708CA9BF7995E4595B8A009C614406C669468C1B4FA3740A9E91C64C03CE4A3ADECD19A716A82530A508970CF16FCA38AA10BAF9810A8C3334C7B4A29904B7F72BEA3E61505107E641C2BE03CCD6C0546D2698C110CAF2F194789C616ADA3103B5C7F015991D473837E9451C9CBC9DD02333636BBBC825DD0DA77A6731FBC3A831348CF1A3550166B72B4D0C59A5BB31DE1829CC77C235B73BBDBA937E5B45A456198B218B641BE8C05CCDFF9746BD64FD5A759A4886D3022CB63167AA3F37655A55E9ACB9671262AEEB99F6D5618212419B1A41B7C260213B86AD9C995294B9E96E77BA66A40F9B5243BB38E6B7A7311D7C29C9272F98308A5F68C58CB111E33964B797A151588EE515FC0F032B054C7DD35CE5C734B8887465B0B4BB58C491F9953B1133561977F0C25401E6B577CC1CBD555BB8BA7760FB972A6B2344D2222C0FA575717501B3191ECC598BC93BD145800D9924C06C36D0360AAB9678E93138D266572B305B7EA69A6AC8CA3ED647137090CEC1227169754B49324F029776AD3C6C3E33E14170265296C1A7056282074A64690450555945A87BA57B54EB3595DF82E81C1552F19C415C6CFDC0CB5FB32C3DB060DCC208B6BEAC782668EDDF9986E0A1BB5A0941A3745EE0B73CA0A5F98F5928BD7189AC6B20205555050846EDB51A75573E9011F2D7738BB8C58BCD16795805F03A42AFF1B854D3981002614B39B90C6F8BEF32BC0CDC085466C8F55C7935B96157A624665404468783478D4B121D6B6A026818DC04515D0B98F9A1634977D3521316839253B7A847224C3819802D6B84482988122A7C87D069A13315FBAF56C9047C03641B4B008070BD885F1E3252F16918CF03AF8634A8F7291E7B64DF4E14FEAB909C10C7FBED446BDF2557D8A96E2CC17CBEB91515A2FF0B78BF0A21ABCEA847DEB7311E2A782A567A6B1A57BF105A4513DE2C378B1C0186909838A01ABC000A829A9503D8C12F374C0D48A32C6F539A2AB28AD12BC49507E230C9A3881153113C1DDD446AB513608A567AEA199624C98845A3ADF90A5A89A3098091F207B46F28A5659F54C75A01347E18A11DB75F9247749C03C7CCC6B9ED722DA1B118D3C2760216C792B7F2F406397BC9A7F18343812A09E97A0F6C3C3B87179888A6D69B01B9D8C4B8CD215AF5B76F7249747ABA3537044F7991BC30854EB68C2F6F8B404257CFD6043A3A327D457651F0B600415A977D1CB30904BB853B4DC380BA4802B28F7C479FA7705B3A6CDF8A99CE2604AF2670AB6A751236E08321D61D92A27412FEBCA600FE30850F3C86C647746A65B1A9210ADF34003A39C16EA69A626C73929567F1B001923B4F0726337F90124B74E500007EE8938CEBB15E1F993E1EA0726D04A5E3B52579C625EF79EBF66485083ADE6B1BBD0C9A953092FA80755F1471FF7F063A2F0013F429F155609142A685039C0AA540B3E410654803C7F281CE44B9CAE5842F7347B29336B5125586D151117F3AFE13669BCD7991068BDC68676A7F30708906DB24033FC5822B8CBE33012F5E916C80EC7DFB3661E433431CCB796BA70C5A1EE85D63DC27BB236759E3A2AF7553C03894124A6BDD3E3C87DEF1F1BF3E01FAC4709AA9B2779ABA933159A5AA043E2FBE31B14D2E56F93E83763E19787607196101D3F26", + "ek" : "DC560AA4079523C73D03B704080048EC306FDF735356BF1F273EC2BC5CFF13C86637FF89394D69886E600281A59ABA47A661164C69464052DC9F4BC74F1AE38D644E0735CCF3CD0950CE2BDE812CBFFACECC82DB2314BD427093D8789958EA2D6270B19EED8AE8BCEF7DE3E0C69D7E8885E032EC6BB1149C3787796A52131B5AAD0C646B2A29F431FE8F023C0F5D23DA24E0C4E47E33EA0A0FEA8A00BFC6A634D8099898C23887F0465435A4D1A76B63D1EF3BBAECD07B48F68947DC7E3BF9C0FF9084384C481559E0EA971E364073035E9084D75B81D7ADF9A7FC04FDF8F9CF21187E981C45FFB4DCD5014EB60B31C8E96700A8EA9CFDD1D4D556F12A8AB8F20907C1D89FABD0B661691CC7BF2FFD98385F48B8CCDDC4FA1D71C6A433C9D738B8F4444E325815227408EBFAAEA04468F629FFD1B99792F7F5729E8EF29EF328F9C7AB1284A1BD1EBFDB360794C2ABE4DE3AB037A4208285491A35FBEE40D588DFCC939BBED4EE1368A459CF26F052D56F00D3782FCE7A00FBE6A6BDC8EE4CF46A44A1DD1E0E4CC6704C34DA1C5052B53032B8A3E8434EEBEC5F1298BDDED2830C6738B5C75E295DADEB4D1CC70783969E0C8F178F8F6F64FDFCD52007A72F038BEF1D8A8173473EDEBBFEC2FAA90146CC550B079A228D8DCD2B245152D6081C1A89F9133F57B0DDD9BCC6F073066FDB6643C2BE9566100A8EBAF052359875D73E77B763795D5A683F60CB6D4A7BD7B9EFB0DE0A6B63BEFEAC6FAEF5AABBAFB833AD4399715824D4C0FA300CE39B3B08B88BB2BD520E92ECBCCB10D11C274D9B34623BDC1019906AF21C3C43AD0DCC53519C25ECCE21E05A897C43EAA7C7A68B9D4AE04CAA7A072716AF8AC40E12F86D913EBF677D76ED25F430634EB8575436AAF49B1A4FB27EFA161D819A0FF26222AE1CFCE54FA9A806121E1A14B1DD73E899C6F4F5823D6A808C172A99B8D268E887C1B7059F0E707307845715E5F8E66C2F0CEB7043EFC89EC239D53BF7AB79857FB05B57EB5548461402F6C71944998969FDB4F9A6394A88ADA699F1C1CCFE8078D7B8A8680939102A2BA2160B0EEF8B6D956B3D13688E4622FA2281F74D9B3132482DA16C2FAAD6A8C158D556C6F770540B9A9F3FD336FF0DE30B2F4EBC9E749E9DF780EC29F8F10BB89D19E98F453D9F1F446D6E166927A416E50E3AFEE3A5937BBA93B4A8A4D065CDE5C5C48BCE4D5A672ABECF3810EF78D361BF4B03060EB150E1EE013B6E00F6A6DCCBD2287A865FC62C140B9FC24973E5750F53A5D15D2515DEAE258C3341B6CF1C084FCB3EEC04957BFD5B7F4A2709DC271E542FA84F2D463733EE09ABE2E1AB8BA1CC46A8F947FF8FAD41950F2090520D6924C7278AB09A402DBABF97112FBF6EDB997467FA9F789B6A298AC36D07BFE6B723C5D66B911D82AD4F332BD2A8E0CCCC6A621BCBE2BC604F39396F86418EE512083BEC961097F3092BFFD6FC2AB229A4E3790D675E0E8B9367DB1363160F52E37494C7E1CB245970099B86BD532A964B0E70FDEAD238C6069F8697F0FC9C1C8BB181EFC382059D1C65369D6462360B84522041D4B057460F403F23439406B0E45C2EBFBA0721389E76FC3E127DE2C1D653FE95205CCCAE5121D0E2FAF676B0C63719C17026A039119D1BC83DCBCF1CEC90FF0A9CA0730CB374C8777B731B81701CBDB0C6C4EDD2A713688E50A63A97395DFE31D80C3DE931AA035ED6D177EAD55C64FCE125A6021AA7BE942BB9F6EB05E2B764E6692DB22FBBD41C48A90F8DFBEF638C8CB8E21324A09EF07764ED84EEC3A50FBAD83ACDEDAD92434BB9FE462951EF5831822E6EB8596993960B5252BFFDF1BFC7AC25373130014A944EEC0F2CA265C9506BADAB86E01CF39F668704C368CF75C930AEA9CCD7CB8903E63638E86D5D7DA09E8E101F1251CB23A09F07B432425AD839351566C96CB8A32AE5B222FED25756D6A6F855320F69698515FF7C8D9D10BCFBF10E985CA3C354D0EE3ABE37ABFD9F2CFF3EED12C18A57AA29A41197044EB5FF2B2B4D024A14684472E0F4B8B838910A72B405D6396626B330D0414963FF5E8CF1F5493454A48527BF4005D6B028F007A1B612BE2F563ED684487266B780E77F09F37AB80F3D26FD326FDB28A9A2D270AAFB399B5A605208D16A97C2B2D35C268E5D2AC9307A95F5A2B828F5B8C609749180B13CA3F183CEACCB1F3C10C1F8", + "k" : "A0D9BB14F9D1AC77ECD2EC9399C8C53A640F28375ACE4FF34CA1EFCBF1E88834", +}, +{ + "rngSeed" : "D995D38F934B6E1A7CA77C9522E3D037676CC939B0C8BD4B84394B3DC91A791F09D2D97199258C9943DA955E7F7B26FC", + "pk" : "03A595BC577A703B4201253367762BDC7A8D14E60784E5BF04AC62F5CBA8327C781122427A83800C9B342792AD6E93BDCA2491720894DDE616A9A9674E771439B8704EA57D70E9095E05A03F3155C3007B1AE0467B7C7BCFD67A5DC679C8F6BA53B44C110560359C65EF6425F667B5EBF967497119FC3B0BD0600C93FA269F349BEC1397C4B23BD851A0824B80B664070622860AEB98F2B2C9349C8E0CC824F5B0386348A77857C277496CF10046DFD59765DC9D00B013C3002060737E668CB6440AAED4F3220F789826B579359A3338B91F6584B27DFA7324F61859370795568DE4CB39C4B1B015FB693F42C09E981C7C5658D1CAB448A947F3A0CAA999625131C9118258AB7635D78CAEB86AC5C100B30A57216F586901D1863E27262EBC2E3FFC09AC4B6AE45C968FA81AAC089A04E7393409799E853499888DCDB29690C12A7E512891421F111A2189CABC1D00A2FB9878C0057144BCCA25C9A3F1A2C3B92C61261A3557177628A252347355BEE55DCEC7BE730639FAC28E0536C0636BBADBE97674D83B6C209442B34E37D9A43D508E849B3C21369149A7270E56646D984EFFA143C87777083BC54270B146291D8B4CBAFC6AB7E72A871469ABF3018ECDBC0753B94BA98140E4956C80913EFFFB22AD687921560055F466B1744E9BC851E12648899B7665A18A71130C1E4A47C26CC8F1A4972512186FB89A740CBEBC6553AC3C088B01B21BD9C47CD5578CC58FC4697A0C756E7F860F91086AEFB4CD02D184D294ACF1F2872191851F585D96D3B98A755BDCE648E8D7AB5E8BBBE8BA0B752973FAB007E5390BCB6AB750F8AAB5C907042AB8F49ACDC47271D6B2A2EE148F13518243809FB5651F6DA4379225BD864597AA65343B21B8F8753AB2994D981961CEA24B7F780643B5674520B7FD11793B1A4FF110AAC7516C1861AD54296B917C72E281692797AF7A594E50C35D958436816036D13348F81851BC5332F6E1B55AA575AF0C0035432B10ABC89CA5CF19170D9537C413D1C7674992467323DED94C4C6B694558CD3ED45447BC5FD3979A68427916A9297904B02D48918D914AD9E88C99B5C28A6AC037248BE9D3054ADCB0F3746ACC2C0A6711CBB1401C6D08D07A947D3BC35EB7B477CE19068FCC744772A126F98789D349FB7C58D9C91CB1EC4830CA54E2E44DCD27B45C48AE07E84C045487B2252178075CDA577B26704803A94F9B07ACC6E815A75696FC927C1CAC2C5BE290855247A4546288A383C15B05714C1EEF845E9BD70EF5D3284D5800DF8AB0A6522372893618D6A28A922152B1ADC2E93F60813025D2B15667947788B93DDC34F05374C9997A0AB8B72023CE47A50C86BA00C86A37E33B7516437A23D37D6DAB5197A88E823A5129D656AF31B755A89C4DF21B520B3CBDA5581200C9695B497AC2B0F582A42BA28B537A7024D30C127907BCC1667547B79AE655B4143723DCA5EC494D851B3E3EB763F4809CB045CA69407627CB49AA59099B050C26151B4D89CC55E762C1E358F1679B7F30A8CDC531B80580BEB1B8495487D2D0AC3A9A240AC1ACC457B53F6AA6A580B79D9CB953240E9BF90E54644253DBC79B2B3028E26AC8641042F7715D97190E64CA4E13624530A882BC53B2C724F68511021641CE277D0AE32D329B9FF554502CE25A294A3829C770E9565512D52F08211B7FA583CA675491533D14813DDBB96BA4F05FD9B95CCA052B7CF098000882BE1C2AD9865E4B9B0834189F91D5444791A561EC7BAAE5C82B09893A900920D6BF6DF1391CF1A2506ACB25D79F6D441A17BC5EB4D133F5059AE52565014939AAF208882631A531582B486BBD72850A0724DD52A225C40FA2A33F312C16A426A3162993CB7370D23C300E2A5D2A70102E9AAEE23B715C11860386C4BE5080283A4727954F2C5197E6125BC2C28757A63D46C0B322299E5F483EDB10CAEF28C44CDCCA5A9BC9505199E7DA28286815757A63FF83C7149BC0152A674404B3C2C06949950F7B073F537728514B20C676C53176002A8C7AF2865EBCFA57F1226FADA60EEAE67FA5417EA4B863D82C3871C4269974BB76E3338328C00530122E38C138E42DF370CB51830980F9A6B4829AF71A7149A28379A251530306D0719D0D6794F89750CE06C27A913832A9595B9A9C1728BBDC4515CF1AFE1DCAC211A3135EEECAE628AAC9538EF2FA7DAC989EBF18207DEF", + "sk" : "01AC758391018442AFBF29AF226CAC76C6BCC2F256E0454802A968D79B90EBE3252FC57781952AFFF183EC0C7B11EC71A6868963335825C00CEDC8089D822E8470978D74C75806654ED5BF178AB7F1A658440B0D28996B4FD23CC4104F811882A1129FBFACBD29AB2F278CA869BA0722544F0D28C879F0B1655525169A723A09BF15CAB7D3A1CE835294AE77C3D55C7537478660CB696025CB0DB431FA42349EE5266D5C41D92C64544A6A79D9099623B513190946B24BB2707259EB40AD59510496BD4EAC68BA9C14058665A465578E2BCF28068F54B47C957A7A1D1004648B2332A113C85B0261F1474718C95B95553E083B50B69D455764C6718FC286348C187FB0F8CDBC8A7C37DB679FE41D853769ECC03063AA1DBB215F044A025CE98767E7A52FBCB44A9C67B5529E3F9B9953640E525471511336D993B6E741BD9E8CC942A1219FE23835384AC0F990F1646E487AAE445065CCFB1CEE5790342B4D9594687BD53B871B2EF34C619994093F368049A6A483C007BA115AF85C976FA28787805BDFC158F64B50DE04AB3B82BA026621AE262D25C4BEF55776FE7CCFB15524120171E806BD413300089490D233C00FD20783630E2BBC5A661A0700CD1181C0559ED5712E0949C720CF2B15B776240B7535B76A237E37A86B81F6B59D4418C3A00624166559E180E18ACB91157C715C0030640522EAA523D76F073A1279B570EB08B14BB697C93345C3DA33B6D65F5BA668C80477140C22A56700FEAABD73F90237C54754F377695B83A7D5BA8EA4CD9934CC83A3C7ABECB927E1CB1EC405B58A7C4A010D3DF2A9B48C213D0B63DFCB1533602D26614C08995C561A3BDB4933A6CA3DEFE340E52A20E3894E8BB95657E8AE363B928B3648EC266193D44C11BA2E47E2656D54C3A13558510C9A739C7F857B586F13A5EFCC403AD347EEC8623A3B41F8447301E1BB512766EB803FC1460D05880D8272C4B38A03894C2F41B1C4F08A416BF06B3595070E985768132BEC00C05F5CCFEFCA9A1851C9B4100110051C977729B7D3446EDB2EC1D02820D189FC6476B6ABA6E08021E5000FE8F20D8C48B75DAA6D8DE2C0456345CAE60309589BA9C289C6DC664328B5FFE10610A5B2AF41053E21C8B58C7872CA332A8B6D12E75F739A6BFDA88E85690CB35C5952C1A238D2B82BA0216A44A9C1D346188CCD3365B0F0E66007B606E04BA1D8C2C08CB6A901F491AE6C4442417A86DA9D7051812066A652CCC178C0BE52B304DFA4B6092B8D5E8486D4918321B6537F883661CB8EA4596C804C6534C40404F992841309F272CB61BA90D7A439DD204D9D7369523087FA2818DD56A712227D96F026F1FC1D4A3B272475BEB1C0A398189FD392B0112CCAEC4704B7983C10DA4B1735AD78CBAB8144B485F2B721193B1A9654EB734DFD2B42B50078DB163B67C192F014BECF74847BF47F19E5A70EB6B28A717CA908A944AC6575F43D048950016B69BFB86E21E012E15435CEFC11E5B6813AD37942BB646752B82EF9C76F99A77B0707A8338A7528C01981B2B19CC64BE2ADE4E384AEC67773912E0DC9C8C5D431C099ABC663BEC1F64050517ACFB8584323169C941D1DBA6C0BE940DF049E7BDAAE440614E9C389A5817E54700B1710A24467146D124A12B90FCD18A964A8CA0B8883AB26916EC339D39133981570966083DBEA8038716D6A574A03710477BC7776F7338C435C4FF27EA3B42C315700D327757B821117595026392E8526AE12C51B27752499CC02FACA268594BEDFD3637D78ABE703B4A47564F7D78F87726E6AB45E814493E8103AA0255C26CABDD1321205657878460AFC005BB952482D672F8F9C4196282D5558085857A83BD43CA75805557898D49A9AFA414D6D2AB315506CB2879FF7628982588B62F2A428E21516C47757E36A1CE0236D9A074CD2928C043066CA3A3358B6D8065D8AC8458CE374AC71C0F6C6415FAA870B760ADED1668FD09F00DD2650DC75B426228D23B579204843CC0A2C9170B1155D7E445F93788308B316B9FB2C3B3C6EE79026EBF611505BC91A476BAAF65BCCF86091010DD14B7456E2A2AE8B0CF7E655FF251515F6627E01B1279BB0ED640D266C4B9798647FB17C09CC183F2170E9D8709F537CB6E7911DDCAF969C438C55623B89B037708303A595BC577A703B4201253367762BDC7A8D14E60784E5BF04AC62F5CBA8327C781122427A83800C9B342792AD6E93BDCA2491720894DDE616A9A9674E771439B8704EA57D70E9095E05A03F3155C3007B1AE0467B7C7BCFD67A5DC679C8F6BA53B44C110560359C65EF6425F667B5EBF967497119FC3B0BD0600C93FA269F349BEC1397C4B23BD851A0824B80B664070622860AEB98F2B2C9349C8E0CC824F5B0386348A77857C277496CF10046DFD59765DC9D00B013C3002060737E668CB6440AAED4F3220F789826B579359A3338B91F6584B27DFA7324F61859370795568DE4CB39C4B1B015FB693F42C09E981C7C5658D1CAB448A947F3A0CAA999625131C9118258AB7635D78CAEB86AC5C100B30A57216F586901D1863E27262EBC2E3FFC09AC4B6AE45C968FA81AAC089A04E7393409799E853499888DCDB29690C12A7E512891421F111A2189CABC1D00A2FB9878C0057144BCCA25C9A3F1A2C3B92C61261A3557177628A252347355BEE55DCEC7BE730639FAC28E0536C0636BBADBE97674D83B6C209442B34E37D9A43D508E849B3C21369149A7270E56646D984EFFA143C87777083BC54270B146291D8B4CBAFC6AB7E72A871469ABF3018ECDBC0753B94BA98140E4956C80913EFFFB22AD687921560055F466B1744E9BC851E12648899B7665A18A71130C1E4A47C26CC8F1A4972512186FB89A740CBEBC6553AC3C088B01B21BD9C47CD5578CC58FC4697A0C756E7F860F91086AEFB4CD02D184D294ACF1F2872191851F585D96D3B98A755BDCE648E8D7AB5E8BBBE8BA0B752973FAB007E5390BCB6AB750F8AAB5C907042AB8F49ACDC47271D6B2A2EE148F13518243809FB5651F6DA4379225BD864597AA65343B21B8F8753AB2994D981961CEA24B7F780643B5674520B7FD11793B1A4FF110AAC7516C1861AD54296B917C72E281692797AF7A594E50C35D958436816036D13348F81851BC5332F6E1B55AA575AF0C0035432B10ABC89CA5CF19170D9537C413D1C7674992467323DED94C4C6B694558CD3ED45447BC5FD3979A68427916A9297904B02D48918D914AD9E88C99B5C28A6AC037248BE9D3054ADCB0F3746ACC2C0A6711CBB1401C6D08D07A947D3BC35EB7B477CE19068FCC744772A126F98789D349FB7C58D9C91CB1EC4830CA54E2E44DCD27B45C48AE07E84C045487B2252178075CDA577B26704803A94F9B07ACC6E815A75696FC927C1CAC2C5BE290855247A4546288A383C15B05714C1EEF845E9BD70EF5D3284D5800DF8AB0A6522372893618D6A28A922152B1ADC2E93F60813025D2B15667947788B93DDC34F05374C9997A0AB8B72023CE47A50C86BA00C86A37E33B7516437A23D37D6DAB5197A88E823A5129D656AF31B755A89C4DF21B520B3CBDA5581200C9695B497AC2B0F582A42BA28B537A7024D30C127907BCC1667547B79AE655B4143723DCA5EC494D851B3E3EB763F4809CB045CA69407627CB49AA59099B050C26151B4D89CC55E762C1E358F1679B7F30A8CDC531B80580BEB1B8495487D2D0AC3A9A240AC1ACC457B53F6AA6A580B79D9CB953240E9BF90E54644253DBC79B2B3028E26AC8641042F7715D97190E64CA4E13624530A882BC53B2C724F68511021641CE277D0AE32D329B9FF554502CE25A294A3829C770E9565512D52F08211B7FA583CA675491533D14813DDBB96BA4F05FD9B95CCA052B7CF098000882BE1C2AD9865E4B9B0834189F91D5444791A561EC7BAAE5C82B09893A900920D6BF6DF1391CF1A2506ACB25D79F6D441A17BC5EB4D133F5059AE52565014939AAF208882631A531582B486BBD72850A0724DD52A225C40FA2A33F312C16A426A3162993CB7370D23C300E2A5D2A70102E9AAEE23B715C11860386C4BE5080283A4727954F2C5197E6125BC2C28757A63D46C0B322299E5F483EDB10CAEF28C44CDCCA5A9BC9505199E7DA28286815757A63FF83C7149BC0152A674404B3C2C06949950F7B073F537728514B20C676C53176002A8C7AF2865EBCFA57F1226FADA60EEAE67FA5417EA4B863D82C3871C4269974BB76E3338328C00530122E38C138E42DF370CB51830980F9A6B4829AF71A7149A28379A251530306D0719D0D6794F89750CE06C27A913832A9595B9A9C1728BBDC4515CF1AFE1DCAC211A3135EEECAE628AAC9538EF2FA7DAC989EBF18207DEF1330F4828E22A13CA5031217A3D8E6F8ED708A7026E1A96D8EBC4FD2F54B505192CEDEF206325F68EBC282123EB0AB02874F8A3C6665B78346775351AD99CC3D", + "ek" : "B6974A23E2C10CCE5B1E68F683AF8E3438AD140BE48A9FF64BB5B0AEF4A30C7592A3D6D3F1514836977CBE465F9D7BE447B86233D320A3E754148E51F7BE2AAB6964EDF951CB80386CB89B3FE5D9943720094E623416F445282FDE26BA96BB2FC984E3FC37AEAF1742476CFF15534BA7D7234862853DA0CBEA26AD1FA8C2366D2D6A1DB2B638CCE163E16F343D344219C19840FF7AADA7A36B97804573BAC498DAED42C291D4F78AE31123048A5449FE0253DD0BBE5F1DB60F6E8D90C2A15F69651F7429E497D48D879CEA4198642B1D9EA97E8CC437F54819FB746ED79226385A85398120C39026A852C2CF12EF80EAC9175B0E6452F361472D4C3534DC4D481D838FAE717725832F016B70905441BD251E843AECC6F3D102619C9DDB95F79DBA91F18A6AABEF1669B5AB11BD739E5B1A70BFF00081A2B63FF23FA03AFAEFADFB9B6EB67D6F976372C1887A36E814EDD8168A0A79D21BFD28FA7380D8E803A64E3C6A2D3D2EB3EBA199B429A8D817AF598DD8673CAE7287825B2D706F233C42FF6CB582FB53C3B2ED3149F2C486AFF8EB8FCE870E16C519EDE532902FB56BFD3B7A00311EF10429B359711D828E29E2EBA27AF164A9EC1696A5093411D88EA8ADCDD51452EE916CC69D085EC1CC2B9E81A7FB6A9487F89C3C8B60247077F777AFCCE1FAA107270AAF9D836C5CFB02291BF2381F4491F690FE3DFD527E0C58AB2948FE5A1C50072C835F4FD5E29908B79C2AF4CD35013811428A7BB4078DF7BDCC5D885C9A8FA2D34F69B2D8216F462998D840A5E13476786683A8C08851AD6CA8DC4923F4F529E55A9AFEF6EE8CD21C412BBB08532682E32DCBAFD9C2028FA9E3023EA039B2E6CEAC7BA7E338C9C5BBE61448CF19DEDEC1F6763A389951C7378BF5FFC07DA601CB7DC24FA83355C3DEEB44627ECC757E6D4FE653E897C97133A567C9BA6E54BD6154F9DA845E16A54892E9C8E333071975C25B14E75E592F1A32C7B6EAE46FD7B6BE995C41FC71F429BAE7734F8345F190DDFEF872CE906F7CD05161037F5DA20A1FF66DE6D49EE3C2262720DFE5B8B37FD72D275A4BB8408760DBFEADD908134A9F847BAA9E3AFC0F0B9707209F3FA15040E817A4E768DFAB43FEEA3280F5F6A75E0889F54A608BA780FC109CE74A9EA4A1ED8CFC2AB9A27DED2E009A92D8A66A219A65536778EC6949CD43D4198FE3FDE72F5200DBA3D43767410F6C924CEEB9B134D51AD9CB508E41C0FDABEA03D155E1470C9F40D26485911ACC122634B5CDFED26E721BE0851336326ED869649460592FF53BF34BFA308133C71F7C80ACFAD97128CECA8A0222B23C477902FB5DEFCB55353A979A7ADC5D60B19EB4A91AD6F5D585F0B415E535CC03F017FC83AC9C5922A3178E024B9576DDF280779AD0F636039F78E6B47690A305C822035DE010C4120A5A2BAC437BF40B94CFB6542FDE3D52E29BFACC2F1B76210846A53DB895FF9277A4D9BC026AB76412786FF4A842BDCFA715E51F2ED9F5237D52C89CB642EF21039D351E39AF75894A893559ADF076ADA224747A988C7195586F63C85155B9350C857508D0E1054C282253AB4C2F9D23D5446D6450495FEE096324C42D3D3C04059A4312E0F8B2FEAC2EE40B0686FE3BF05C23F5E31C8DC02560F09BB89D87A2497C5EEE34AE8B570E2D82E0924ECC0A497A42B6E22D1B9F7766882C2D68B1AB28247234722A15D1ED12D3B09793B58B273D1F9128DBA5EDAB29033BB677A32842146E1CBA315C397CC04F1D8503FD23D878AF4FC1080F70DF6F251E3E5C722896E53ED7D09FD27D02D6D573ACBA879AFF71072CF90539704B03E5124D09D53C35B5ECF1293DE68D8F480C15FD17724A8B67C9FDC3D55109FD720A0FB6E5CA9C0CF729E08E9550626AFE1FC8A68E29D762F81F401901CD3BDF886458E205E1272BC4D09F395F6A1A915CCF1D16CBFDEE3696C3DEEEB7C98F2427EFDE352095C90D3F08DF8DDF30138E1E2531975357DBB1951867DC2BE0D895FECB88C5767A6C14343FD4E44BA57F7C0C0B752BD7BEC777B37B4960C90C0E1A9F02338A9EF5B66192668B226E4DD41035357449449206AAD424CC7BF335353859CF92868A4B8BCFD4ECFFE799DFD57010B80B6A748A791D47E967CC2B498EF6B650BA1B6A960B9D27BD58091E9C512CD0636FE8A4EC19D4EB179D46658714776DF294B20E88681DF131CFECC5", + "k" : "7C90825D8F5B9EF1383A13B9756429418F2060E8DC1A4A0E8F80094305F22E9E", +}, +{ + "rngSeed" : "5929F02A271725CB40200DE32D9D03D8BEA53B53AC83186C42C7F565CCB1CA508305D470850CF86E9B2C61A5B8CA1C93", + "pk" : "DE62C02CBC473601B03F5547F1B4A8078AA079C4CF39C56F88925A9383B9A0F57B58741760C58D2629C5D70074DF007E715A3F9344755BA908A4A310DE73150A79A9EE3957A730687F4B2E7DF025C1D699C254AF6642BFAB84809EA9A3B35410C7688B296A3DA82C6CF6790B48FA3F66F5B651912E7939AB76B0935F49C1E0A25422365974698C9532AD00120BD2AB10A8D1A78ECB392E6892624A3F96B2758A423246D67933EABE6BA2BC019A031431338AB546B3154A80945A9B31BB5F9C4071A4B0AC4B1B85B3A11AE1371DB39771259936A27EBEC742E7D6282F19C4B6EC1A70085EC6CC23186C8A29F4C3A1D3ADE8912E3E238F024CBD30E61B1FF2312C91A2EEF9CDAB68446BCB64AE505C32F0CA5D02547C3B2343962DF8D384BAC81D15FA3BD2A116B4D9ABA31041428AB688F950809C94404B5C35F303D9852A0F029E609126110B64E310C81D634117E3B3E1994EE2A2799600AA38966E00AA9450F24657A39B4901764C3A267F2018363950256A69D5B0240F368BFB238FC3ABAE22DC2F3FA6C9E7F055A8712CEC654ADC039C49AA1D303158E05B0EE4F1CCC0E07CAE74047B603671B9704E70646CDC0B1D1423BF3C4FCA6612360269A26B9731524A2117A2B686131708470AB6C1ECEC857465CFDCAA5B1506ABDCB6A5E379BB4E358462F802C2A81B26D0091A9A281A891C06737FDA60AFD65AB7C7BC4D97667220EA69896A46F20200B0333546713D9E685D8230487BC39B68B170105231839417FA92ACA1CC38246B3D0DA638AA28C907C823A1FC779B7626A1146645DB0582E23115C64CA6468BC21A480385B27FCC28C0E6B8430A270C5061012A619DA7138CA97DA7832807AA4F338A3983170B62145F36A35241D21C13C61A1044B5BBD2232F5C16F106AD476818F83920F650A87DD80C3213680CC1572B0625391A92DD423E53DCC0EF58CA376B18A46B8BA4506878F38C88D814BBA280575235B23107BAE8C1F443A5E9C1058C904A09366B50E7B531451F8416342267352FCC7FB21C05BAD69BAC0967778C0C2D48A60980AB5B7901B84B54F1A53B6BB09B37D48DEA04838193657CC7B47B436D4DD36CF9BB4BCC552700F98A88A850DC009B00BC41C9F552E5B346416024065634F4D768CF49BBA831758AF42E408668AA712F93F43658C48B80A72BFECC0258AC6FB10C51BA665E8F25537116AE53336A8F3A0D2101B705642C5891B4500AC61D023398B35A21E37EC6C9821EB46C348C594590941FA0CB5D88AD32C3165CBC3569E15960DAB8F53C16D02320B7C8394971C14C5633AC5023D572608C60A726D50B22DC3696E7C352FA6FAA0C8E73127ECE085562BB8A86AB6628149292A750588AA90D268F5FA618B559A4F8468218985DB9F4CDC1F65B4644CF585A1A8057431985058476CFDA6CA0DEDB2FD77917FDA88D799709C169C01E90C5528A9FFA144636334D8CB3A1CB27B81DF55C9205AA1CB43F04EC29BEB19539992846DB361DE4BEA0A7B045749609571639933E6C105221782033885385C5036153AB3EE68156F0ABCEBCC67C9163FD09CF2A50910C8A5E50EBBAECC030FF38B041C3513DA677F78B253D7C5D9BEC993F85AAB56A21502B1EE66922CE9995EB83376ED309B1F66C9E9B46436399364496A51851D48CA06E342FD40A6C64748D6DB5A9BF18893D65A9FC3B227401C9410888287100482438E604CBAC435ABE040598F5CB7F07AECC23B6B38A95F9CC8EBBCB4F5CFB17A8443F89EA8EB592456DA09FE9A36BB31A98E9E5372D4BC83F9A7509DA4AD87036581B27844B79A9753BAD9A476EF64661CA2A5E49797FE161159ACA36F017D947B66D87833383C9EB593313054E00867A81E0AA6B1A8493A082305A387F8C50024A9F682C69CA0AA180EB8DCDBAAC44F4A3FA830BB056352095C2B8B65EEF62775A470638C252F40C8137D05CAD7C9508C3C34A6B29E6C6431B34882A3526CED7143DA2BB9733C2EF816E28D3A1372B418CA595BA593B18789B7C6A411E27ACEC3B4246E8659A2330C628436D21722536858548A280588CADAB316411B5EDEBB50DDAAE15C32ECD74AF476B3D4D834C1047376001CECAC303F5C1BF7AFC7B63E8372C97A8FB68837064294527799A8874684A81F6145AD7EBAC7A5CBCCB696472CA98FD95B9BA4DB7D8729965AEB56B8EE101D0B32B6B80A772FA80E70598B17E84FA", + "sk" : "E747A3E56B5DA1EC0B2859BE85084ECFB60144B5AD600A4BD5F31EE866B72BD110F6111653124F695B75DBCA4A5AEA5C17C237D3E5748D842830FA2C87454960BB6652F5B0108332EF3024A2346E5C9AB71D4466330C2761F7CBFA29BFBB51931970B3A291179A1139A0E23E46B62DAC796EAAC32B4225C7BBA9638FC428D3D4B691E5263C3C586D8ABB56A313BDC69DFE323BFA237F27B046966C0748128EA32C9F0B34015E6C3BC8578DEE1465F63C92E2E197E4E2AB2A76A9A41BB57B97903808472255B2F98BB24FDB4E8657CA5ED0CDD176931C934B33BC08F97646F6E7AB9AC565B7C04F26D12C44228E36824838C84B2EFB0B5DB6126B1B54614521C55455ADA2002203B12954652C84B3ED26163B70C8CD5C76976075BF323D1F7984E2CCBA31FA26FBE82A61895504ABB81D660DA8943BF6C29F16B72E59965813CC218A8635380044D40BCBCB728D9C37C375A975E619524E4C10D7A73FD8C400694AC396B384699BAE098C07BA1483C834AEB3F1222D753758F3458FA2B579F3A156D0A27554A27B9192EA872AD9A83D137A1EF1F3445458761348AB6F40A0B8121F25F56FD9E7CB57318169768B46D71C7C41914DE73838FC4ADBEACF5F7778ADC5CEF5764F41B8B5B0E1AAAA594EAE08B84F1B2FA8CAA94EB46E2468B090832F9AFCB4B543A61A5B572DE2B79967C03D97CDFB5C0CDD5166DD121F8E1552780667377783C7E14F23AC2A4F2A3DE89735C9E095DAFBC72FA8351CF5203B7C9E96DB2F5926320D8ABA5A2750EC7668406319860101D86B92D4FB00F0FC75D8E3B344573D70449FA2FBA847D399EE982540BA92A8149C24C411D4A13154CA92AB5A8A2BE2942D45370A1A56E3AB715DCB7864B9956F2ACEEEC963D34CC3EA33CC9AE700B58C0953011ADBA08C115574A377A71BEC017C79C12CA7A9362C6E40391DBF3AC987362569DC34D20A07B03306CF7577CE94078EF122207BC05E55A0D1D6368EF85874BA21A0090825C720467A891E1106A4C229446086BC71937904B534780E40B07D36175C81C8287DAC48FD72C37946B98A9CA814401D1DCB5A243CAD5240543234C00CC146B9EBBCC0DC57F5F963255366E4424CC595A1F7F2B9A066792FE0835E97390C97A43A52C39676AF8BE2393CA82D64039E6AE6A6FFD5B582915B23DB1F307C1B18C90086263A9EA5A87D5470B1584C0FF272E6CC3E1C3B59B895B048DB369BCA70A3D22263483226262A7F15B96EB316DC62178A52AF1810A7FD357679121C78083ACB8CA1F0F6C3959C235ED901E32366354087162C3C86828C7B6B8688120EBAF50F55F111950BA79093A3C2029DEDA0A007B73241D30024D897BB66A0653386BDB344D10C90E43249D1FA0847F0CA918A414484656D4C0C246350BE4722B43343A2E310EC985476FB754C93256A8321D9369FC531495B263A440C1DB25B975D0A74D6B6CAE1686A63B64A1FE0C51433CE5B886C34D9A44AFC76133245B302A277403EBD46889E4B84585615D6482A4B0B5D528790E40538D4612646A690F0E7A451FCAFF648583FB7025EA2038540ACACD2B30429A550C980247188CEA490E5252FDD0481D0B9837CE69E03D4798CDBCB25867B9E794DDC945D96489625AA16AD4150A925AACD254A6AE309869A018191C9E6F9411A6B375BCC9CF81925C57B99BEB92921AB932AA87C3E68C500070F5568757B2B8E86035F717B88B3735AE662ADD2334184E6CBD2AB026B8A9D41F12EB322AFC154A0B21330C951A4BF5C54959A515896ADEEB73C42D94218D46219C01CE056BF78FB88902BA686B440C1026BFDA6455610A1FA008D44C28BF22796204850F0E124108816E39B3C55C7CCEE889EFFE88587B0A12A5C0B2A30152E98C612B61B95C0CA8FB3B203DC850FFC7F866275C7C851B67333F2C37A6B5B999B686FD6EC67BA67C9B0910E95F84A5E9A826E0617229206D94B98927C418CEA516604444978C24DAB19F0C63536076E9A0841873338767B3D935CB526C04C2AB5015FBAAEE2A523CCF7154353B5282C7D9AF78F55A73857AC5A70A03A584A8F1B0BB762F9C7265B40404888516016F6808BB3B3B7D0553E2877726EA63312F3AFD494B5C1B60FC4B6BB6C8A68FCD1A6CFBB9265A10FA4C4BB76B8B47D0BB34F99B612A595AAA91DDE62C02CBC473601B03F5547F1B4A8078AA079C4CF39C56F88925A9383B9A0F57B58741760C58D2629C5D70074DF007E715A3F9344755BA908A4A310DE73150A79A9EE3957A730687F4B2E7DF025C1D699C254AF6642BFAB84809EA9A3B35410C7688B296A3DA82C6CF6790B48FA3F66F5B651912E7939AB76B0935F49C1E0A25422365974698C9532AD00120BD2AB10A8D1A78ECB392E6892624A3F96B2758A423246D67933EABE6BA2BC019A031431338AB546B3154A80945A9B31BB5F9C4071A4B0AC4B1B85B3A11AE1371DB39771259936A27EBEC742E7D6282F19C4B6EC1A70085EC6CC23186C8A29F4C3A1D3ADE8912E3E238F024CBD30E61B1FF2312C91A2EEF9CDAB68446BCB64AE505C32F0CA5D02547C3B2343962DF8D384BAC81D15FA3BD2A116B4D9ABA31041428AB688F950809C94404B5C35F303D9852A0F029E609126110B64E310C81D634117E3B3E1994EE2A2799600AA38966E00AA9450F24657A39B4901764C3A267F2018363950256A69D5B0240F368BFB238FC3ABAE22DC2F3FA6C9E7F055A8712CEC654ADC039C49AA1D303158E05B0EE4F1CCC0E07CAE74047B603671B9704E70646CDC0B1D1423BF3C4FCA6612360269A26B9731524A2117A2B686131708470AB6C1ECEC857465CFDCAA5B1506ABDCB6A5E379BB4E358462F802C2A81B26D0091A9A281A891C06737FDA60AFD65AB7C7BC4D97667220EA69896A46F20200B0333546713D9E685D8230487BC39B68B170105231839417FA92ACA1CC38246B3D0DA638AA28C907C823A1FC779B7626A1146645DB0582E23115C64CA6468BC21A480385B27FCC28C0E6B8430A270C5061012A619DA7138CA97DA7832807AA4F338A3983170B62145F36A35241D21C13C61A1044B5BBD2232F5C16F106AD476818F83920F650A87DD80C3213680CC1572B0625391A92DD423E53DCC0EF58CA376B18A46B8BA4506878F38C88D814BBA280575235B23107BAE8C1F443A5E9C1058C904A09366B50E7B531451F8416342267352FCC7FB21C05BAD69BAC0967778C0C2D48A60980AB5B7901B84B54F1A53B6BB09B37D48DEA04838193657CC7B47B436D4DD36CF9BB4BCC552700F98A88A850DC009B00BC41C9F552E5B346416024065634F4D768CF49BBA831758AF42E408668AA712F93F43658C48B80A72BFECC0258AC6FB10C51BA665E8F25537116AE53336A8F3A0D2101B705642C5891B4500AC61D023398B35A21E37EC6C9821EB46C348C594590941FA0CB5D88AD32C3165CBC3569E15960DAB8F53C16D02320B7C8394971C14C5633AC5023D572608C60A726D50B22DC3696E7C352FA6FAA0C8E73127ECE085562BB8A86AB6628149292A750588AA90D268F5FA618B559A4F8468218985DB9F4CDC1F65B4644CF585A1A8057431985058476CFDA6CA0DEDB2FD77917FDA88D799709C169C01E90C5528A9FFA144636334D8CB3A1CB27B81DF55C9205AA1CB43F04EC29BEB19539992846DB361DE4BEA0A7B045749609571639933E6C105221782033885385C5036153AB3EE68156F0ABCEBCC67C9163FD09CF2A50910C8A5E50EBBAECC030FF38B041C3513DA677F78B253D7C5D9BEC993F85AAB56A21502B1EE66922CE9995EB83376ED309B1F66C9E9B46436399364496A51851D48CA06E342FD40A6C64748D6DB5A9BF18893D65A9FC3B227401C9410888287100482438E604CBAC435ABE040598F5CB7F07AECC23B6B38A95F9CC8EBBCB4F5CFB17A8443F89EA8EB592456DA09FE9A36BB31A98E9E5372D4BC83F9A7509DA4AD87036581B27844B79A9753BAD9A476EF64661CA2A5E49797FE161159ACA36F017D947B66D87833383C9EB593313054E00867A81E0AA6B1A8493A082305A387F8C50024A9F682C69CA0AA180EB8DCDBAAC44F4A3FA830BB056352095C2B8B65EEF62775A470638C252F40C8137D05CAD7C9508C3C34A6B29E6C6431B34882A3526CED7143DA2BB9733C2EF816E28D3A1372B418CA595BA593B18789B7C6A411E27ACEC3B4246E8659A2330C628436D21722536858548A280588CADAB316411B5EDEBB50DDAAE15C32ECD74AF476B3D4D834C1047376001CECAC303F5C1BF7AFC7B63E8372C97A8FB68837064294527799A8874684A81F6145AD7EBAC7A5CBCCB696472CA98FD95B9BA4DB7D8729965AEB56B8EE101D0B32B6B80A772FA80E70598B17E84FA2A35C723556EB2782C7CF77EE75F8928F8038EE66DB41346741FBD6AA1DAF2B47373D22CACE9F3A09FCC5E85067EE05C0E537AA0738F79101236B4E7D28F2889", + "ek" : "50FD74B5FEFC8A73A346F03076F52C49244DDAAC21923895BC427890D1A4CF9F6C49D3A317EA4590C9FA923F1D32CED7C5E96782D84010A0A150657EAF1E84EDB02699409C171F3DC57663BB39E44550A65E6479AA7CE2D4064DF84F8CE15173C530BA88400F49D2384539AE1A6EEE33FDAA1FD1009609252F0896150DA9ADAAE7CB5B107EB6149B516C34D5CC7C1217AC4DC3D09868EFE717AC151630E668D6B446A9CB1541BD2CC88EFEBA8A40736CC8047471887F9F07907D08D76081FF69C567ACCD8BB124FFD6E8887555BBD8F8B290B53FABA833108C301DDB001921A1505965CCE4C3BAEF76BCC02AE7818DF2BC2F55203A184F416F1E92057C83BBE7952AE42FCEBE854E41B6E2009149EC893DC6D59F1E1A3493416BCF9B40A5468F86B74FA338E0515ADB9666905A20C2E9BC3E1BF24B9F1FEB3C290D3D7149FF560D34F701E8EBF732A12ED2EB070407052B66583F5A99F56A980E9C125C8356D31E7CAC9B5B42EE800F812C8DC59DEE0AFED764BCC084BC6F6856F8CC0B27C80CE89BF64AF704686EE3CD8CFC921E461C1047FF9ABCE04A8667596BEED51D0E8DC24B1C26B0DA7964F79929454FCFD17DBDDF162E4DC01E419CD0B0BC351A9729A8BB17E0D61386721095CD1F7281A01BD75E9A08BE110A0EB6AF641B376B81D496591FC18980D6D0F2ACDB2B4C9A60E7E213065F3694AF475C112F326979F52EEF2429AAACB4F8BED542DD3D64A6BC36036AA5395DCB5E7C2600280A388001211E11EEB8AE56794B9E32515935881DA059D37BCB9847478970220675FBCBFDA75A960A1BB6ECDF37E6793D1E15E736047BC023C6A1FB3F3D12D312904CF1C742CF5CF7634126D2756D05E16AA78BA9297A1F61EC678FCD3321C2FDED3651B477582907895839E6C60844952BD1ABCD807E0D7A7A7B019DFB9C8FFF41A38C4CDFD77B2936DCA0C07241F43473532AA53FF3CFEF7851D77F6BFF165EE95F986F6A39FFBB1482107CEFD53398913E482212B1141132AB9A971EF036401AE0A99022D94035FC9C4B47F51262F0C5780DCA721F4EFBA436CEE672532E34BD9D04970F5F1BCDB17C9995847A2A8A0E65870EC7CBA972B5DF99F021BA436F547495D06EA603FCA33E8C3AA67A565EA73A06C78E0F60A525959E75C37BCDC37CD3282C2F0FFBAF383CE7C81833804ABBB22085A6EEC7B2449E59C353473262058E4BD488A1B7CB113A25994AC1E4A2A0D9564765AC28D09B9AA6403E18F41749498829C74C6ED795AA09CE3CBE0AF5A81B589DE84999E3517E2027C17BD40E14E3FA5D65890DD277FCE94E376B653E90CCE8B93A486FEEACC0937ED1800C1B6799EFFE8056F30ADD828575AAC81927848EB34BD74850ED75D3E22F3073E04A3392C04AB8102BCD98038C9A5FD8B3B19D869D074246EFCADDB93CB20E0DAC3243012B065AF04637EACEF70D51E985C3C0B05B55A615CDE8219CB484932C1646A43003F52019319D9707D92E63606B28AE7B4C8AA53D6C4BCF99D764C104CB6F85C56AD65B1AF005AF7D98E60FA84BC4DEADB7FE235B0BBFAA7608AD1DAEC68DE02618D8D4E91BE22AE7E8CA58468FCCF6E060CE6CFEE874135CCE004A11AC6ACE9C0E9E53CBB9A12C48C14EE60B2538CEDADF0B57DBF06857E8AB8FA5DADE276CF093A187518496D11D79A7E65D899504606A6A212999975FADA035CF3DB5D9FDD4A0D8D1F30444C3CBB6E59713D5572E4CB8D7B6957BD66F78AD7CE9C358F032429D0A133F3FC2CAA66FBB347CB4E389C81AEE51FFDAB003E444089B0B8ED3953F4224F83F79A72FFC188E2C4873BAB7A629BDD5FAF1121FC4CD834FA780CC5CABA8E967017913088CADC31165EA9F1F8E416A7EEC1D45FCD592B45EC9F62EF5D075C9F3F8C168C8F266F54D1D5433B5D4A72DFFCB8BCC1FC09B4FD6C9F43432D06157E55441859561C1349BBD94726D117E78E7D604C9CD2B202AD5A998C17E6CF368C5516CAF6D3082EA1485F1E49CC1A6C7D6436455E5EF0319FDB94F294E8AAD0B8C175A5E9A71258E1931FD80030B0AB3DEA0F2835E320F5B15F46508A9E87908305FA160355ED63A3A393F4E5C21E19C8EF18934706A788CAB48CD7C436C9A9CB7D665D8F9E54B7D7A0101A166CCCE849A3D3E3F90AB14D59D62B95EFE9FBEFB976B8B4CB9773799E4FC63F56EC3A9811E5D80A5C2CC411F445D946D0B24217991", + "k" : "3F994BE12CC8153502B06140E97E3D61AF29BC005A8D33278BE3144690C91883", +}, +{ + "rngSeed" : "905074033D7B75DEB2D06A2F29144EB377B452534C5710632989F02D45312D156557E96D4486020826DB200153BC4A8B", + "pk" : "D0C53790651F609447F0B18434E5B31F2B2A3D1233205C11E5841DACCC2017203BE9C26DB2EA7DE30A6671F79C1C424052A784E727C36A3B9DD1D71BA80A542DD42B17C85EEBD81406DC394EC556ACB00932FA9A8AE610646A973DE42F9FE29C92B35C04884BE2A5BD3F68B2083945F8EC525D651877D924482B024847938EAAC5690CB33F0A878927BDB4A84AD627092F046A2968437BF9A675D91E25E89A3F246B38461F002C3D78206539968D9B7A83745869EA8ACCB72AB1DAB78FF0183C2FFA338C819DCFC1178AD8B928C68ABC98209819AD705A3FC264BDE3047FD2065C3E1806A9318D75A39C6E4541DFB86433BBAABD12762F521C842A2381DC78FB312B1A6A318C5201BED68AE518BE985746B863CCEC279836D6810178C54902619301467BC986A735A9E93678B1F433BCB7AF36DA821DEC7546A4957E413D30A4B1D75BA216DA71AF7A7B17A932C224BFDA459681893EC103A4B56C10805A24543741ED0B1F5BF84DAA018F94C07434758D32D80A3D8C6B54774DA822451B12AA086782F9C0622C2B8AC9776639084A19A509124B5DE6D77A83BB6E123B8EB1019A2B203F87896F23018568DA081DF72E460A1D8A2815794966AAC55FA07CB7007AC3743A0F2ED5B6F377286A7C2AA4B9655237B3F1635DC25527357BC4714C3A47285C9AE3A5A84886C7302D22BA2D3C15580BE7B1627C81FA1B0942E85A3A075845E47DC0674F4EC2C1ED9CA031AC1CD934A01C022D26B6CE5C038FBD541DCD4AB4A9BC17C06842D7645935B57587559C11B99AF337BC629A45EC37A3A20B1FE905510971B6E0926126E815625C5D79F677EBFC69B1489809172F34E075C29A6E9FB4B536F892B16C7AA97623168823D5B1AFB439CD2603C9758904B942971D769826B169936AC108C6CAEDB98982098D5176C71CBCB11B22B96143433F6C083BF83F6005C5C8B93562E081C940903AE662A8F17FD0882FCB399161D2A2BD2B8D1AF0731B0303E3C9BEEC81C5473384B7A04C1C841F60E27ECA0977EAB4C750930A2BCB3983DAA99CD4C2E2414AB8F77857432036C1A9A65C493AFC62EF80758830417375C697A2A7FD0782AC011014733E51F088BF32B7135B5DB727B147936740E320C603365E280CBAB502B64412ABDC4D25FB9A96CCC96F166445F6A6C3A894A6C10AC7BC074FE7B5A1D2964EF0531E7BC445E0A402F45B0F29809A84795848812A1B935D220670C2CD0E3332ABC68F57B98F24CB9E68F8B1663B4C793AC4212177F11C594671550E44794F84705FA4835D918B317A1D5AA39E65026D3888AAF40CC247023B74CC4E00FB1C011C6A266560949C626E08263891608713C12E75A229C5BC114BADA81395B00A5B6E695096B2790E85C954028C5B288758C9AD634A3AE11B069790BFF9428B425AB70C5C46C2150346235814E7AF8576AF3071C6E6D4B56B61412D7A5CABE21CDBD0AA69E53D4D223D72E4C77AFB927958245CD57967428D9F6C81CC604FADB43DD56C8148664942E2085395B17A1C53646287FA14A9BB208AEDB1A7E6F73828F0AAA5918A69C211BD765CC0F93615A57609B5AA91C502B851C4A9B24335D282348BA33A802170524EE3351B6C780A3A9B46CF472FBAB34BE9F508C32A64BC37B6E6B30F37A7A9F200C34811C2B8553EC3EC091091BB08AB02CA7680867244FD3C991508902E84BB5E177F7251057C38784C0905CBE7041F12BDB77C07842228AB569FB69700F9B3A058DC5791B600DC48855FB1CB938B2E2599C1F3411628B64094AC20EB6C50F5F5CFDFCC10471346DE9429DD29953E7B139E2A46F04127D7225FD46723DFE19522A4A76389BFE6414450B885CB211AE680B59EF46177D50B0B3306820A9D57293AE6753E65097F8DE97C898C465B07B6E89459F446A59C04145F2C30DEE57368E0479468AE96BB2E8B0332BB7535104498FFABB2ABD65A6B8A2358D467EB8376A795AAB40108ED9B0967A710083ACB476C28A01B46E68A3D64B12DBB49146DF48F31E1531CFC3295E4CDA083AF7B3A17617286F60B5CA9D21858508F8F009878916473C85360E8CF6AE8360C80AAD7A10F6CB7A707063EA9B2AC097155E6961388F87327D084BAEA61D5BA26E1D5BD9CC25FFDD46A24D81C40532697B4CC8F58643D41AFB6D29B7C857837A1E385A9106E3BD9911C697C8709312DB4EE1D9B023E39FB4A92D9D95FF015", + "sk" : "C35B3D09514951DC232B3B261CC77A4B23B033A57012277498F66299F98B2E58A618CC8B68BA21D1F86CEE4B7221611B8D003010C870A4F8510198A7F486279A168AC82AA70744CDF8662CE35B65AC836895255089CA97E4B61C1A52B7B6CC24B434B25BE51814D09B4312A1150931D627685917B8535BC52AEC1EAE1338BCB6C087BC419D3A30F625812BD73FD3E3C798D61BE67B30D0D34E34434878F53102437DB096CDEFF6C79992337E1122902C803E58C56D0878C5E891FE47441F95390FAB44D716978A0C4AF218863BA783A8C7B5B9F74AE671684FA284E1399E3CA469ACF757F6DC3B6306A2B241005214554A7430DD97646FC26F4B45CEB8E13FE47BCD2A1B0EA558CAED29BE60BAA1803808E4702EB6F46D92D1C36C5AA89FE27346C56D17B52CA4394EA563022551922923B6C5D36477002D92A88041399F33A902A0292563182A48145BB3791E0EB45708A4132FB768850C83C9517D25B1954939C857311CC94A168756AEF272764CF63CCA0B1A95AC4BDE1C2C531769CE89419EDBAB9614C620583AEF725EEFDA51BC16B5193241B986073764C4503B7B497A9D77587443A52FF47803BB40432852A1E4F6A7F1FB0A46304DA84A85523BBA99E06B304583BAB0BAACDC98DB486439916BD3EB4FA6706C8F26682D728BE9A82FB96C6F82A1C7414C5FE645B833AB30B515A446E54E5389A972D6222AE14209D9634AF7BCE363A0DB3222378968EB589F9BC2A5032C37AF18A9DC72211B5858575147AECA713C216DD4C7486861A16D9A56305C81255403BE295DE819B8EFE70A19A1201E7740240AA2A081739946606F7786A6A745B6929E70F552B7A28F49990C82E114360B63CF739712DC647FE8A03B9A8EC5A2B4F8C3010CE71CA964A1A89C61729C3C18BCB8891BC2F880C93041A5FFB9600E184DF6A07BA52838123ACE34F01099D5507E7820ABE2BB4F9B67012A4419934D13DB839D36AA6DE939FEECAE90CC35955164D9D9C8A078909D4CB22016854C2729633B2F2899302F356521F0427CDC7907B4529155C871779149F606BA29AA0D9586EE05BAA1C78D12B9807CA995D38122C43B9671B16FD03436FA87143805C71C4656C29B8DA8B3293B44BE0A0BB873647F7AA92562E4706362110388C9F15962CB249953128A53E30998918AD5370FF32081F4053D13F741D036C36FA47E8A97B15C647272A52AD94620C4BA7ADED0259323067F8B5612FCBE0AABA35D6999339CBFF2502EA693B446F626FA05B5F3B90C7362A38D0A710A32A1E68614B1D63469182BABA57BED2A462E879B7A172BDE9CA930D85B393A797E339D4116C3BCA1CFCB16205AD5C0E68488A112C34C66B4D617B856AC8C66AAA98CA458EC4219A747930F3394C4623A7D402B557069AA524EECA0A6F65A82A2C95AA816723AA2CDFA841106B0336A613420994580B94B3261A15799CDE04CA3A758884BE34955725827C15432E194F624921C674ED10877CB5078D1B29A52694FAC72CC2AA435549CC34242906ED1CC12E523D6EA0CE55CB8A09C22CF580A76A8909D3C3CD749BBDAE9C05F117114F4B5AD58533D410F8B2010FB8C25FC1ACD38C69DBA50803A3066214914CF9A8AB056A47892197DC50783072764A69D8B988798AAAE3F1C1B2A268312BCAFFE253940311033C64D20C1AEB501029F873A6AEB1D249945A997819651BBC86B96CB0537E7E80C0E382DF932606BD58CA3D21C01332CC65C1C00B31C34588D1B10CC176B2FFBBBAF2FA95545E51F0D7445CC017C4D3178FD38C9D85123040A702003AF65B74904028753825C7F7C6843B3BFC8020535FB6888227F6BF329D5203EAF8B8A3890716E563578E795ED566D43B071858B1336165544EC566ACB361A8B8564796B8934C8CE253C409677C2D45691306301A58DA9BA2D05F0C847684E960590F1A5C60217C5AB905CC8A95E9BD26301802BA9257370B73E63D647F02CCA6D58907DA1759CD5C20F7A8762E56C1E09B95C1B99F2BCAB69931F03A707BAA0580A896C022A53C3C846E4D0551F5A2D6F6B4D22BA779B017FB36546430292D950C10EE42862C749BD95104F133252B15771DB7D3FF4A7CC310036903650041B40609D6A9C16E40BA12E6C390A388B95950B1DE92ACB71396E4A0FB7890BD7D123D710A5D0C53790651F609447F0B18434E5B31F2B2A3D1233205C11E5841DACCC2017203BE9C26DB2EA7DE30A6671F79C1C424052A784E727C36A3B9DD1D71BA80A542DD42B17C85EEBD81406DC394EC556ACB00932FA9A8AE610646A973DE42F9FE29C92B35C04884BE2A5BD3F68B2083945F8EC525D651877D924482B024847938EAAC5690CB33F0A878927BDB4A84AD627092F046A2968437BF9A675D91E25E89A3F246B38461F002C3D78206539968D9B7A83745869EA8ACCB72AB1DAB78FF0183C2FFA338C819DCFC1178AD8B928C68ABC98209819AD705A3FC264BDE3047FD2065C3E1806A9318D75A39C6E4541DFB86433BBAABD12762F521C842A2381DC78FB312B1A6A318C5201BED68AE518BE985746B863CCEC279836D6810178C54902619301467BC986A735A9E93678B1F433BCB7AF36DA821DEC7546A4957E413D30A4B1D75BA216DA71AF7A7B17A932C224BFDA459681893EC103A4B56C10805A24543741ED0B1F5BF84DAA018F94C07434758D32D80A3D8C6B54774DA822451B12AA086782F9C0622C2B8AC9776639084A19A509124B5DE6D77A83BB6E123B8EB1019A2B203F87896F23018568DA081DF72E460A1D8A2815794966AAC55FA07CB7007AC3743A0F2ED5B6F377286A7C2AA4B9655237B3F1635DC25527357BC4714C3A47285C9AE3A5A84886C7302D22BA2D3C15580BE7B1627C81FA1B0942E85A3A075845E47DC0674F4EC2C1ED9CA031AC1CD934A01C022D26B6CE5C038FBD541DCD4AB4A9BC17C06842D7645935B57587559C11B99AF337BC629A45EC37A3A20B1FE905510971B6E0926126E815625C5D79F677EBFC69B1489809172F34E075C29A6E9FB4B536F892B16C7AA97623168823D5B1AFB439CD2603C9758904B942971D769826B169936AC108C6CAEDB98982098D5176C71CBCB11B22B96143433F6C083BF83F6005C5C8B93562E081C940903AE662A8F17FD0882FCB399161D2A2BD2B8D1AF0731B0303E3C9BEEC81C5473384B7A04C1C841F60E27ECA0977EAB4C750930A2BCB3983DAA99CD4C2E2414AB8F77857432036C1A9A65C493AFC62EF80758830417375C697A2A7FD0782AC011014733E51F088BF32B7135B5DB727B147936740E320C603365E280CBAB502B64412ABDC4D25FB9A96CCC96F166445F6A6C3A894A6C10AC7BC074FE7B5A1D2964EF0531E7BC445E0A402F45B0F29809A84795848812A1B935D220670C2CD0E3332ABC68F57B98F24CB9E68F8B1663B4C793AC4212177F11C594671550E44794F84705FA4835D918B317A1D5AA39E65026D3888AAF40CC247023B74CC4E00FB1C011C6A266560949C626E08263891608713C12E75A229C5BC114BADA81395B00A5B6E695096B2790E85C954028C5B288758C9AD634A3AE11B069790BFF9428B425AB70C5C46C2150346235814E7AF8576AF3071C6E6D4B56B61412D7A5CABE21CDBD0AA69E53D4D223D72E4C77AFB927958245CD57967428D9F6C81CC604FADB43DD56C8148664942E2085395B17A1C53646287FA14A9BB208AEDB1A7E6F73828F0AAA5918A69C211BD765CC0F93615A57609B5AA91C502B851C4A9B24335D282348BA33A802170524EE3351B6C780A3A9B46CF472FBAB34BE9F508C32A64BC37B6E6B30F37A7A9F200C34811C2B8553EC3EC091091BB08AB02CA7680867244FD3C991508902E84BB5E177F7251057C38784C0905CBE7041F12BDB77C07842228AB569FB69700F9B3A058DC5791B600DC48855FB1CB938B2E2599C1F3411628B64094AC20EB6C50F5F5CFDFCC10471346DE9429DD29953E7B139E2A46F04127D7225FD46723DFE19522A4A76389BFE6414450B885CB211AE680B59EF46177D50B0B3306820A9D57293AE6753E65097F8DE97C898C465B07B6E89459F446A59C04145F2C30DEE57368E0479468AE96BB2E8B0332BB7535104498FFABB2ABD65A6B8A2358D467EB8376A795AAB40108ED9B0967A710083ACB476C28A01B46E68A3D64B12DBB49146DF48F31E1531CFC3295E4CDA083AF7B3A17617286F60B5CA9D21858508F8F009878916473C85360E8CF6AE8360C80AAD7A10F6CB7A707063EA9B2AC097155E6961388F87327D084BAEA61D5BA26E1D5BD9CC25FFDD46A24D81C40532697B4CC8F58643D41AFB6D29B7C857837A1E385A9106E3BD9911C697C8709312DB4EE1D9B023E39FB4A92D9D95FF01560D717EE34E223EAD8139DB400078CB308C3E1BCEB046CD9D53F1A2ABDF8F924C1B070E4E519D727F677E011716436BEE9DD0188FE38C00D0FF425AD794C07D1", + "ek" : "5DF9F654538A3D6E27962961C4BBBD337CB066DA44DE6B33FF225D3A8C4B4036CD6421702BB17617730EB27E14C59D423715968394B3426262BA92EDCE223D2DE16B4D2E6A70899CD2D4D82EB6D43A850F070BBA99968A32402C728D97498A6E0AC31EB260C7473698B8AA05E2EDF148C1C0DF0D11AFB38E5A1BAFAB0E6EF1AF8B5CC274478242C7104A15A45B4186852B090268ED16AF9286F5E492DAB6A128FE122D4A376EDB3F452DCCA4B091BBA20C89C0FF47E77937561C87E13E6A97A9F4916B7BF293265F8F9A0D10778DC53CDAD17F03EB39F3EBA209433F16868D55E1D8B58416821EE42F139B18E7D9CBCC6C7244CFA8DC3B1F9B0E1AC6AB3E773D32B7AB10BB2F768226406E8E017C3194DF3B9D5DA9CE9DF261027090CC8BA779239909420CC88D154730FB03F303DA0439C76865FBB003B812E844AC99F143ADA230DAB78167B65F285958CC2FB0C29DA276C9BE70F2214C8060892603A332C0A15227732D0CE24BC9086AE8CA78DBC389B9AA49AAFEA36DEE36B9B177024F4DF89C982800BDD0728591A5156A8240265FECEB687AAF4BD10879A8A4B5D9530125B1A934D73A4DAFA93B6CC8CE5156BC36404B569E95E75FD10D8714569F0DEE44FFE6FCD20DEE3C438300E991BA8D432A1043BCBBAFACCE9CC86156DDA84D201302FAA09E5593C58A17C14841B85B2C2472E39209A292D868A22FC2AF07BE5835C0C1F59EBAF6197B83CCB72ACD117E70D29E64220D2FE2C84139A625464EDABE0F70B3061E56D9DD81AA35D8950C3BA48E461BA54FF062403FAB39661A5F2F6A153D8F9E0568426B6AB4DEB1B0E60CF96371C37F2AEABCB4D56F9675B667FE13F0C6F721C9E1EB92B638E67FE47262F0A76144065E063BD6DEE2819901C5FAD83C9F64BD78D00C8A716285D92302476857551B3E0ECA89FA29F46A2A4F3FDF111F7D7C5D3F39CD59383F8A639F98DD260A784EFA2E0B7D40093C42372958CC93CB8A1DAE30162504F3BBAFA62EC4AB36D5A0141FA7A6643D52CC996CD7CD609C617F7FC63668867FD7C5ECFEFE8BB6C1136B74878137CEACE21A18B9C576B2860950F0A15EE0C4BB4A3A4874969F3D3BE90B09D1AE7A9F4E65F6EAAB12B186BED902D6AB691AEF235CD95D4317EA470A8D89EBA1126F577ADBB6FED9551BE5DFB31E61D78A7B75DE425EA75E54074856A1A41C4003F282D6C381EAD4A445E6687AFB6D6BD1475FB58169CB9BF4EBE3DF399572ABC1B3E2A031EF38608D98FE32EB552CD8F507DE2C924EA45ED59C3D0B7FD7D04FCAF03E1672EFD92D65DDE678EC8251415136A51AAA66E4FB73386E46ED4C741473A8CE592DA2D4B8A28DF50C0465D89EC545E77B648671CA534BC3CF763BD127815B9DE062D4927ECA887D181CCC45C9CFC5292E7A3D734962AA079104EB63B47F78335EE4C2344A094379157759535F9987E5A5A58DBB564CD3F375486DC16AA74F021BC870087526FB205A7D6FE796717314EB64AEB7D81892FE787F4AD8F61C4A18099DEF106A1221520A0954A4E9D810CD2A592FA055791F85FAD6D2B0EC4EDB0A0F786840B7D3CAE4BE27F3CD338DA4801A0B6DAD70E6F7784FE8DC0D0AA42B1D91D11B304170218CB7B0B51E640F759BE2D1DC56C0E8216F812BFDF48502418A2178958C594F60E36157E4C65BADE8822F0FAE4E04AC8BE01C642507AD60BFF7104746240772C26155BEDFE51DF3F6BB970B4E5FC23F4035EDE95F3A1B685631A710BA1CF03F23240357F710C78238F4919F85B33D4927C397FCE35BE9729A9591B1E50C73377BF5DAD54C0D6E83E16254CB62E91D596D9DB243A5F4DCBF65EF02FDA09ADFEA3FF8019EF4F3BD7983027F4B2BBE83E2016F5EDDCE96C2E6B4CFD3AA0D033EC99265C8DCDD7F649486821FBDD03C5861C5EEFB445938F9A9D9B23992FFD3636558452A33619F116A0B52B6E2F100D136780BD3C23DE63729FFA4A7CF883D3F1BA2D26D3B7FF3B1BFA8FE3FD695E26164448053279F7B1C7CEF7E4EBF062EFDBC0DF2C1A112D31F53B508A6ECA607C6C4EE5C74CB609B259DC5F06186CC84F014052DD34EA27293EF26FABE7D8246944C69ED505972352459DDFB76DE57947186544C13310C94C6C1B11BAFE007BCF254A000B2D197488AD8E696B61D0E20347DB0D1376AA249F09A03AEDB0234A8CF016AD866C29AF29A6A5E882CF99ADFA5087BEA", + "k" : "0581835700C989511CFB20C23D944002D3B26EB1F3749817D0A3DF79651A33F6", +}, +{ + "rngSeed" : "A3E2E511AFA7BB560446BDADF67D2EE2E16FFC7BAEAE7EFB8C5455068BBD4E91BF9BE9D98B280072FABA7712C75B26D4", + "pk" : "13665DBE0A4AA46BCC40862F1E3621F2596BA293466F7499D9954EB6A6251483B350072CE7A4910F008166E62476E383F0151FE706C23999B71DD2471AF759B99239EC05996A94B7A3943E37F10DBFFA1BA205B2ED836AEF025221CA53AC612D41339770D80B03F0220FD1580B786353C9BF15909242494253684C8E2B5A28216501E1B4F1820D6312CAC1BC02C122BC0ED71350A05457F4C40A29584E20B70A8739F1E733483B7E7F8AB62B664C9672229980536D747F3199A064CCBD66E7BE173641808A93231ACA8A7B54DBD0C593BA85DF11C54BC2894C6A797BC0557DF513734C74F3641A6D2C98FCD8C1ED356C2E199C28088EF495A54FC1019B736F2FB8895EEA391C67C895041F97805BFD2354BA1C3DD8E98467D302366A616D280BDB4747FB5A000BC5781BD8C1CF2B563DB206E6E512248319D2122F5EE77802D88466A61F5006239C5001975B00DD634377705274629F16A92F13B37049698B12C39BB1C3579D693970736FD72C8D8654943E5868C53A51324ABDC57B330ED30145E92AB82C91D975244288833FF3A2D9D92AA1F53D99B11D191C99E06434196318E04087D9AABD03D7AE1CD2887CB2197EC4B09F7699861193D8EB77DA9C9E33749E4A0C5BAB3BB64ADC4436B7A6D84B9463C4887E4642D490052093399B2CB52A73B5904920A601C327E2937AC439FCF3B78EE830B4ECB795376DD263A3CEC91C6A6B60E48001A0F739E217B5B3C4AB0A676131514BB62C9FA1801BC80B6C8C7AC70110B4860CBF221543F2AA61E0683BEE500F98BA4FA93C2865A28BA4820AECC3A6C7B56081869C701B1BF741152C0CA0A753A211C3562CA26A15395A630A4A92729ED9A3092D23BEA5433447139AC0518F75D11AF6113B8368CC72891A5DE08DD7689B2592256A8CCFA524A2344921A0E887627BCF7965A1875C1EA5C255C36978DA7C4F184A1CBAF24A2DF142EF80C07750B87269419721C48D8014F4EC8B4EE23D95AB1ED9F8B5EE9943669007D48AC1657454AFD466E8765C877A54466171B649188A7C205BC3073791B832B6A752625809919DB9258EF1B7A15D2C54C6C02F57FA65751438F4186A8B576D7C561D649A7A60D1928E013DF7D69F4DD7035485107A7062BF3CA84A93A5A0197EA00B7522DC769ED45596BC5E712954E1EB37FFD69D63EA2CE5E33DF8088545E3A738B864BB61B916D29E45EBB39D8A7A6FB3CB3901B9880AB0547107C9073B19258E4E290156F54AE3D44D19D8ABC5FB334AD757C7E24986A26A31D458EDD45C69B9B8D87B0622166E66C76AFC49A23E1C1ABBF357B7328781AA9A054B24AA2645D691639F141981C30A7203623D550C31E2BD4BB95B2E7B518B44512DFA6A5387AFD6C7CE162A434A6B9ED937CD79222134310A2420934B357E72E009EA8413A9148698240AEF2732836B5659566D21111331FA9BB0B762C948247CBA816E313109270EEBE826ED722322F9841F33A935209E0DF273F4E2237A59B27CF85FB3773998A295A37714BA074D1093B0F096B2EB5133BB273E50E17DE75B45300C0C862354344336FD028A4A631DA22B285D4435082667FFC21FA01B79625C019E71CD0AD86032FBAA79326630692B9D02BE55315543D83C0B84297945406C339699B1093E4B188511AEC19B3C9069BDB8799A2E077AF4308C401982E96819C7F17F6BCA98054688C30A75DACB90AD342ACAA9BA227A7F6784100428CDA9D6890396CC19CB90A81153BED281CBCB1036113250206B59208D8C75839B76AB8425211961967396C696F05D913598259334C742915DD183F32C5A4E957013868634459F038340AA7761ECB628FBBB435BA642E21C538B907D8710413AC10D7F0A7965B03CB8C36D39336543193D0D768BCEB00AF79069E7C85B09114E77E6063ACA18F27376BEB9AC4A0B976CE745FA7972E9FA74D0055EF490CF40E11E6CD785510BC4BC1231D88ABBC9B22FC1E2577608580E26635070702FEA437F8A13F6FB37343B488C1C0B2560027BDA77FC6A97222319B66A86528061F21019AA73674519420BFA26AC5616EFD714CD46B7B7751922175A1DCB22831609EB40B4D16107C8438F33E203CDBB85BE910B78A99D766499D4541B91567FD8C7A85D983080B91C9254CE3C2A9FEDDB8C8BA948F0986A90D02681341FAC1CD19451956432B83B79D115D32A3D4F86F902F2F6B0C95AD7F4BD49", + "sk" : "AD3CC5E966747302200DD35F1D80350983648610CE07452591948A1C6A9DEBDA418FD0AD79DA318004AEE89ACDD62C689F88A5A7621F7EF3B1F16C5BFD5C17438B98F029906C276EF1202D1F5504BEC6243F608438047E6625C825B902CE22141142145368298D0C33EF857A45C872AA73308ED112726847DEF20029C2730768ABD1C40A8DCA501FA61CCC737D8FA497091AB5EA532BC730BB9633BECDE90398A391B4E60F5A5A31A360529B1486530B98742780C78C2761C09E655334BE04B71D8B9B04A7B7DAA7AC4D2A98E2BA49A54C2E91016BE462418E632A4E023BC6E816240927C73703FDF0AE2912787626C55F4614C93731C9C679984738C96B5CF64C7F3919CD4D217F44E668E9FBAEE0530949F63AC68137C841AB926587B161C56D218E3500885B82BCE07668CA959093792507ECA4827A003D26CD02324E352388FC76197EC546D590B00F646DE107681AD32C708561546BCCAF0489495821F8D43A436C1E4D9CCD9BE2A5B46232DD37485328C3ADE9BB08E53947EB16AFBC6AC1B2B96B496F1AFB250277BDBB0B6186B61B88B81240292880D9CB9A43352546A5E9F600045153BA033C3148A5AA78AFA9B2B7C8B86E4DD70A0516A8A3E746E83CA8B919104015650DA3A6F7AB9868E1C8E33B039B9279E4680B5C2A382789049F953FC28764A0422F00E9CAC3EC794DE5ADE0B432D294A9C06941A814AB0F89BF88E719D081520B114C9C821F772A7A3B2A16EDBC2F140724E7DC1649281233507187E4B87EA13803BB8E23541E176C1CDBF38ED1A225FC932716974829A6B83F30B3F587804EB8720E102278D5C7A2668F1481C42ADC13788604D60C9ED1498BDDA86A9640BC0B8137F3D7BA17E0BBA28167FF1C5E3EB86B6EB5C018AC766E15193B8B4F65ACAA3A2C191D646F97F19B200BA588780AAFBB2F1C582DDF4105767CB93FA984C5B6CB73CB0301D9183513582AF59E04D9C5869CC99ED83677D5A0F4405D166A97CEBA0D6E0B8692CB6EBE130F77025A24264BF6851B2A52B41EF989B9F890CDCCC3867C3AE19C7238750BFA11AE52DC573E87554A40088E682F15F9BE503B05E2B53FC4411758854F5D691AC806CA00136A0702CA52803DCA8C935D98C87FE476F960A169401147B240C026745C894D7D91197BC7B2D7802568F61EEE554D3B852902934906521FA08B29B6C7C27C6867667168B796B5249BB442783970E7C443469C540AA9598834BBC4BF8EC97A18119B496A56C3FAC7E2627B76CCC51FD60EDF764F68EC032BDB7A1B5424BE15329A54C537810205C15CA2EA34A6462CB3647DC7A38590B120A8D141D821A20349631E7C4804F11AF9AB9AD4917A27BA99B9F2277F3A8AFC059BAB0072E93131A1936F87C8356E3859FD97A89E17AFFE170693309EB4E29A769AB2AB48659F635ACB4AC986F08F1B186BB6A70A50A6CD4C202A10BC2F1D24AB4338B2D9765CA263CE01295537DC56BCA315DB1C652E850DFAA522CEE677D2775F878037E5C17DA2E6C7FB296927C64CE9256F88851D31BA9658F5BD7AA0636CC2BAFB1C3494110E7FB8683BDCB3ACBAA7274351B14A81BAFB0A4E2208D3C204E84C00920C0C074109A81426416BB805465E429641BC9006B56C75BA1C75C5AC4113F95BCE7843344749E969BA2702ADF09032AF83396606903772547365CDF835A5BCF69D3C14505B5472475C97ACD88EC1CA4D52D0B1281086A5BB3BED1CB3986238385391A0E59523B5A16756AF4E15B58A07426B574EC080893294A60D1148DC418C1312673F89951EC94E1DB149365B33FF60CB2BC372763277EB97C5C8884CA7421F681B90B249275E631918AA57A7BA65B4D620CBB59131201C9A3C5E070AC76F7214E167853FE16C6058A9231A0F5CF69339C0463D290457FA47D0D949BD7362B5C0C2236826E4241353C2AE7833C31DBB03E7332DBF370A637A8885CAB1B9D1A864B98BEF6C81A27C93CC306A27B37BF794190A3CB6D55BC580D295AE6087D05775FC802198191AC5F400C25B39102A54820B5ED02146D5F19586A8C66126C87BD22B0E9C7857C3426B470768676BE8F7B826B1C1DC486C9EE64D79C33372E33AD4880F357196CA95637C80668040022885549D1A9801109A96398F1B8C6247F203DDC4350CF730892B53037B4A13665DBE0A4AA46BCC40862F1E3621F2596BA293466F7499D9954EB6A6251483B350072CE7A4910F008166E62476E383F0151FE706C23999B71DD2471AF759B99239EC05996A94B7A3943E37F10DBFFA1BA205B2ED836AEF025221CA53AC612D41339770D80B03F0220FD1580B786353C9BF15909242494253684C8E2B5A28216501E1B4F1820D6312CAC1BC02C122BC0ED71350A05457F4C40A29584E20B70A8739F1E733483B7E7F8AB62B664C9672229980536D747F3199A064CCBD66E7BE173641808A93231ACA8A7B54DBD0C593BA85DF11C54BC2894C6A797BC0557DF513734C74F3641A6D2C98FCD8C1ED356C2E199C28088EF495A54FC1019B736F2FB8895EEA391C67C895041F97805BFD2354BA1C3DD8E98467D302366A616D280BDB4747FB5A000BC5781BD8C1CF2B563DB206E6E512248319D2122F5EE77802D88466A61F5006239C5001975B00DD634377705274629F16A92F13B37049698B12C39BB1C3579D693970736FD72C8D8654943E5868C53A51324ABDC57B330ED30145E92AB82C91D975244288833FF3A2D9D92AA1F53D99B11D191C99E06434196318E04087D9AABD03D7AE1CD2887CB2197EC4B09F7699861193D8EB77DA9C9E33749E4A0C5BAB3BB64ADC4436B7A6D84B9463C4887E4642D490052093399B2CB52A73B5904920A601C327E2937AC439FCF3B78EE830B4ECB795376DD263A3CEC91C6A6B60E48001A0F739E217B5B3C4AB0A676131514BB62C9FA1801BC80B6C8C7AC70110B4860CBF221543F2AA61E0683BEE500F98BA4FA93C2865A28BA4820AECC3A6C7B56081869C701B1BF741152C0CA0A753A211C3562CA26A15395A630A4A92729ED9A3092D23BEA5433447139AC0518F75D11AF6113B8368CC72891A5DE08DD7689B2592256A8CCFA524A2344921A0E887627BCF7965A1875C1EA5C255C36978DA7C4F184A1CBAF24A2DF142EF80C07750B87269419721C48D8014F4EC8B4EE23D95AB1ED9F8B5EE9943669007D48AC1657454AFD466E8765C877A54466171B649188A7C205BC3073791B832B6A752625809919DB9258EF1B7A15D2C54C6C02F57FA65751438F4186A8B576D7C561D649A7A60D1928E013DF7D69F4DD7035485107A7062BF3CA84A93A5A0197EA00B7522DC769ED45596BC5E712954E1EB37FFD69D63EA2CE5E33DF8088545E3A738B864BB61B916D29E45EBB39D8A7A6FB3CB3901B9880AB0547107C9073B19258E4E290156F54AE3D44D19D8ABC5FB334AD757C7E24986A26A31D458EDD45C69B9B8D87B0622166E66C76AFC49A23E1C1ABBF357B7328781AA9A054B24AA2645D691639F141981C30A7203623D550C31E2BD4BB95B2E7B518B44512DFA6A5387AFD6C7CE162A434A6B9ED937CD79222134310A2420934B357E72E009EA8413A9148698240AEF2732836B5659566D21111331FA9BB0B762C948247CBA816E313109270EEBE826ED722322F9841F33A935209E0DF273F4E2237A59B27CF85FB3773998A295A37714BA074D1093B0F096B2EB5133BB273E50E17DE75B45300C0C862354344336FD028A4A631DA22B285D4435082667FFC21FA01B79625C019E71CD0AD86032FBAA79326630692B9D02BE55315543D83C0B84297945406C339699B1093E4B188511AEC19B3C9069BDB8799A2E077AF4308C401982E96819C7F17F6BCA98054688C30A75DACB90AD342ACAA9BA227A7F6784100428CDA9D6890396CC19CB90A81153BED281CBCB1036113250206B59208D8C75839B76AB8425211961967396C696F05D913598259334C742915DD183F32C5A4E957013868634459F038340AA7761ECB628FBBB435BA642E21C538B907D8710413AC10D7F0A7965B03CB8C36D39336543193D0D768BCEB00AF79069E7C85B09114E77E6063ACA18F27376BEB9AC4A0B976CE745FA7972E9FA74D0055EF490CF40E11E6CD785510BC4BC1231D88ABBC9B22FC1E2577608580E26635070702FEA437F8A13F6FB37343B488C1C0B2560027BDA77FC6A97222319B66A86528061F21019AA73674519420BFA26AC5616EFD714CD46B7B7751922175A1DCB22831609EB40B4D16107C8438F33E203CDBB85BE910B78A99D766499D4541B91567FD8C7A85D983080B91C9254CE3C2A9FEDDB8C8BA948F0986A90D02681341FAC1CD19451956432B83B79D115D32A3D4F86F902F2F6B0C95AD7F4BD49566DEBCFC9A4F48F6F60AD57731445A7861BB9C371E4EE4407B35DF5A730F36DD89CDCF4B8ECE9F441926532427F01E9DD71B86EA949A59B14189AAA249AAF77", + "ek" : "BF91D237F0D3B1A6E12BCF9A93A2FDC274B975A9E55434C2A9C7B91BE6203C0D408C2A37CEDB5F25FF390B337D9CA3D2C1F94331FF9BE97EC4A54480CD93913E7A822FD321D4E63A4032204E3BE72F0888663632C092649A41B53D357222E077FB5E19D239A013F68D60E6934676B85F2EBBF4229257C47D7C4E66FF947E93995689E54B962B9D111E802BE82BE72D1CD9868F83685B48E11AF8F8E16BD6905A94C0DF033C4EB7FCBDD545E78BE048F96E8720E37F30A7846269A1F859B20B16C8F9DAFCE3EB6748AD08155743602D9628D70880DA1021BE832B3231BD4B2505BB478E413677BDE5BB22A56E2E2D1DD2C2E7CD0127723750C4CAC86F71A2BD5EB471D87A7C986980447F5381DC3234409AE477FAE28409BF16E3B38831BEE43E3603AED3C2B60DBF64EDA488DC9241D09F18F035EAB3999DB1CCDCABF57E807DF93B3759EC213ED759E8F8C120940B64436151C7FF8496A7CA5B7D400A0115995B6B4A15992471806505389B77F023DAF4747A13FFF6D5DD056361F52DE5057E055E141AA6E5C6DB9B8138DEEF06A4740B944CD54B4F01E62B11A746B9A51D4CFD67B7A1CEDFCAC5922D73A4489442CBC240FC92EE4489100E5827F7DB7674CE925A5E4E72F55271FAF77C78FBCCBC825F89A4F54954991DE0B73D514C2A819E175EC3A361F766866CC6737F12CF89D6ED81FAE9ED91C9D9C0DA18D6464190A5338F5E64A2AB46C523A1F33030819EF9D2E1DAFA0DF62A6A8F70B6A74C689B5628F8533791D2B434A78F1707A3C9FB951ED8C4A6AB542FBB981F01AF59670F8B56AEC6648E2316D04AC7BCF933B3BF70D9374B3CC6EBFF01EE1418B61E0B3A87E5BDE90822E1AB9D5025CFC8B9FDB96BA8EBE3F86AEE7D570F0D5571C52A888621574EE0B6D70057A457121156EB36EE1DEE4CAFC267EB12307BC5933DC9928C15416C0FB53D4579AED033A3C5719C9EA6A8C92B14FB4C79421107E878D265D2A6BDF7C7439FF6687419313587EFD8A404BE4258A185BAE9D4D391F6320449068E5A368ED35FA8341C58BB965675B30430C7EAEE15EF48E950B2CC42B3BD0B1F043D2003552AC93D548DC3AA3AF9413F5348AF3142A2276A8A1FDBB6D8D8271B6693C45F5F14D09E4643FE7718F0A2AFA218EBFEDD7F8328D19E4AFBB204D40F615F7B9BE7654BE4702BA905E2874314BA8FAA2A2884A21D5BFD8A445B65E77E730311B8E15CB134B76F778C63F453A50F003BCA7B832B92A7C6DB0CBA306CFEE6C990B6ED935EBA110932FB71E06E583E2965CCEDB60A992FF563420ABCF86D2CCC95B6AE91EE1DB98E9AD8EC618B9026D8E7CEA0165236690979BDEB9AB712D844894329FE819E42CA1F635DAE72E822E0A62C77A90E7574693D08E6B8E57A360055E64D417A21E18332356B3B38ECA9929704CDDD6A9EEDF631F23263982FD80914A0A1387ECFB396D5487D041EA55AFC752EA4C9E69E18D0DDA04D36CB91A2586F2BB1F4A512B99675F524F70E022E83C42693715935B1CAEE5D27FE8E7DBDD3953D57AC915F43AEAC6B770AF992C65E98CBDBA9649BA64021CEBAA08B0F90E626F95A7FD77AF7714480BEAF9FDEF8BAC3A5D132639EB5B1444B8F0393A723D3939B1D243E73E7FCAC3652EC24CEB99BEF6C7522AAFEF06E42DB9559016BB548E2E57EB8899E8377095B911D5FECA7FD25F2604EF3F5331755F828D15DB7A91B2D3728A45C4C9AB39B4A845D05B7F58AD6988FDF065F5E5BC911D9D35BFAF9809561AE5B4CB465507F170CDD3795BB4B2CF3CEFADE52FF0663ADB384A3FB2F7026C799C65A562222A191EC412231F91149D4BA6434988E1298F739FD532458A6B93F1E27F81550CE2012405B35E40C50EF190FED251E725002C34F6A9CBC920446DFC265A4DAD0CD14F11CC5E8F242C8E5633EF0503D47A510E6CA6388B8D9B5C75AD2D01C7C96078FDF97250DD40DD2280821637BA2A236ECB92A64B8240132438263500D90DC1C5088D4F012500347906DFC3DE26FE314E62A2E5B2A59D6DC1BF4BE190912040164E29F9F659CB81552482E36EFEFFEA161A9F4A695F3CCE0A4A12454E36DA825567C943D112E73159E6FBCA78A2E51A80251A10D3685894D6EB5A46D726F6968BBD618EB39BC8F4241279E88D51F38F728807E2E4450914D120878E23D575DF84EF0960F79BC9AAF96984E529D0DD7968948E197CF67", + "k" : "930CFD59161C50B81F49B9279485ABC73A1CA7824521D160F621F52C633614CD", +}, +{ + "rngSeed" : "074AB1A37BA5A0403D8F68D26FB787BC2C90F5EF88F2A6D286C3E6B168ABD85D393D8225618608B8EEB301D26AF53BC0", + "pk" : "869A9E3773A7C7942E279471A233A05D77899C2A18F35AC98A3243FA6767F076976529B75B75B070A341DFC95BB85C4BFA1394081141FE1B1B31365E3C2302C8A0296B9769DE04024DA48C2D7A3E5B29AE58659384FBCB4BA2ACE58C4CECA5BAA5131BDD465797664276AA44E8331E2F1328AA6910F68A6A73210E575CCBBDC689199559F094BB62380F436A925A7305FDEBA6C53A9193069873E724CB1B67FB8820E75C27D175BD5F5B5DB020C91EDA2439383B579C14DA0173E1704A318A03DE6691ECBC600097B41A7A9A429CA1A4D8A34DFC6C85E034E8A17629181FE7C993AB018D135A73861405186763B0F70C80D09706C9AF971313E47BB917761A0E3A39F7B96702C288254675F6A07771768F3939B7BEC979CBBB8BCA011124F08347B7BC7C70833197B192FB26589098E48834E8FC8551A1C1FC52A1701323D98C4BBE7779B867B813A5A2A5040D8E8845D4A2B03EFBCDBBB3083831B1FFAAA9E21C7A3AD77053793B1F7B7475B021E2C1AE25F194856B1594228E938A29B832930D5BAD3667C854366F83B48CD3501768F086B68007EAD71B2F046F630196B8237967C940D4727D388800DFEBB3B152CF57B33068803C1D55C59FBA14E31C323E820265C8826EC3B6018C8F60445A11268DA9B44F8DCC512B860212F408D3BAAC60CC6CA42211D2CA3A41271F745BC46FA70A9A8A3999CA83E8635E7A4843EA3B861194BF00909E4250AD1DDB3006F86DAAD2B8FA720D969A7D87DC97AE214AB3769EAC0261076092250133726265EB7987BD4BC01EC004E71BB8F7B06AB339AC9C0849FCB23C4BF35B11955C52D30FA0EB56DC7CBFAC95704E51969EA45AB01C10E59C691DC3908C083263C3565766A34B216F55F8284F219DBC158CFF247E2296C86BA69C922161ED753FDC1471834270095A85A5FABB1DB91FE203113139526961BB40B41E8F913A36461ECE86B37FB809779005C4312727F68923187203D001A378C0073A240190A144962BFAA89B1C384083178A1B44461926A9ED135ABAE505C93177F263996DE9780FC573619B63F741091ED57657404644194A25B6CD1E5AAB45E9021D9A8839546A9913752621BD79730685397D93EC49D86910C46A28142928A054599BA18CC3964CC4DB8BB7A87543E8A53FA23A95BB5B6713478F4B0B5CA6248018A729469A3794A8ED04A315F3783E667C0CD2AC80C68A40C35D64C90E5E8A3135CA15CFEA69D4A1A2E9B562DAC51409C6485E026001EB1196A487606404B6519974B386ABFC9CF4A0305AAB4A627B6C22A994DFE46035447F0CC09D1BAC0397A68FD647B0B13630D1439E63FC8FCA2B01CBE66BFDB4315230B06A9797B34A57A5DB208061195813073C7A10AC95B8755AA79B2033BF90386115066F177EA1421AB0267672B91830A26C20B4A8AB9011668CC46B49A2D824067102C95DC842B4F423FEABBD774B4A4BE351BCD8CF2C486CA70A5EB502AB5FFB8D77C2BF00FB7887FB960C089210D673679A0C71428B5AE348FF293602833B6927ADD5B18F22ACC4CE01517C65C848680D59931175954ACE9689FB6881CE17073E113CBCD53547BACB3946067A1A46CF6B4969065C98C17304D53AB5804501711C153A1B13D7CB442221EE311466469BA1225CBB312708C7B5E0055E3B476264B2244FE9590A557F088C9D4FB47A3D598A998A1B5F821D19909220A229FF020BC11143CDFAAA90E00B71D6C8B7622F24584508AB4D036792135B750EB9AE091B4BAA96A27DFB1AEAF605122060E5268BC4E9C08D1BBCD451A22E44A2D6201C6DE52BAF940F14956AAC311B5C3782E64377C645B35D210E1AE043AD6142BF6C05AAB07D3915500B67989709B7477432B947239A9C7ABBE747B2238ADE292448836B87938E804A4029F24182941CAE500D85AA7AB9556CA98C7808D90558E771D8709446BB1069541DEC34B69834C857215822F773871C4401DA04C70503CEE82491B07E8597480B6BAE6245084A4B92F9B015A158295F237A6376118868486D9C1A8389BAED937B392AB840D4BF67E31DF2C073A4A8C691896B6D6B623B95670CF404DD499773A54210975D1EA72667439E0FD8C112F33470789F2899A64217400E4B51FC501362EC98A45620FF6BA180A211CE5C154BB62A1904CC13A64FB6F445B48EF88CCAD56919A0DEED94A2AB2D4B6442A71C288753F1DC41EF5389E39497", + "sk" : "A11CCBCF239BDF7642937B7D37C0B33DC0667F06B13D7A166870CB3C696C93E038B314276A135CBBC672F830585A46C31CD09C621BBAD1F4C611F3349104857A4B1117F47142D36FA8F73834260FDC337D7427AA0FD90B5646587330CBFA5A56F3F42D211226C6A627085B86CDD73C05838F46692BE0D15A7D59B9C2E803940708946293ADC5C338A29913C489EE1396DE0162588B6449452259A243D422A92DACAF5ED9A88921A37500CB0B1031467C494B3C207ACB6D4FB444CAFBC9DD364933A3488EE654B7FA866DAC82A53ACC8C15464A29CACEFA9432256934C7790E1B99C85C599E3C5C0ED11310DC2EA6D813B505A6FEB4626048BB6FF0CA8A1C418BB4512008A94D863A6F7B359DF211F061584F34043AA628AB80C46007257283A6B5052E8967A56E86230D9B58ACC6125406064F03B6B25A5F9A706AEF5812790566308CA35B19B3C6A7A2450A56B164BDD19278DE85A5769186E7C67EA9DCB7E2A8223774CA66290368F67EF6494D2BF5411F7114E7E930B7A99BEB84BC69494E7461127FDA4D6EDC4959C375B6D8B48121312000A6DDF510504A8454600F87523D71071E13A0B676FA681428C31D7CC0D2492BC7C94C7B423092113DBB1B123A3936C0D1846057B2970A37D1CAA6E53988BC0565842B143CF2207AF23167080257A339795141318562A0141D1F7B59F68169FD0A2D7C959AF209971860123E5B30464A740F5214ACEB6B322B4CDCBCBC28285AA2746090A8595D4371508735EB5423B94A54F6BB8AA2019B76BB76B25C1DDE42B56D13819123BE6ED3BC3D26B1DD515121A268D3D3381AD4432713868D7059A06609864671FD9A6A1777803E4B46D9BA6D45050FB2C80F88F450A3B655843872F727A68AAA66C758A8317A3E2AAA55BDE0A97DDA29A244615EA33469CC5FF82A6C2E0982935C9737943B45C77C3355900ED32785F59FCAD14B936C1708BAA6B5686B952B07683C1252C99D8A49272B053FAF69AC090A8C0E2A0F639544CA196C00975F77667BD54289445CB62367BD79A290683319DAF1BE3CC89A5D105069E221B875075E7162B12B3203630EBDACA13BD6768CD9AB4872A7FF54AC4BAA49C3680E372B9C7E25124F6A9C62C498ADFBBE9A90A79FCA19FA358367A2B5A24B821866402E43B93DBC3CCE1467245A42CAE42EB6217CB7470158A24FA225467CF0962B399741C4743EA2222F265A45E7A94AD800734A050635AEBA147023349854305C59276565E32DFADB17B3183722B1C44AF4C289430F6AB53B416CA239B409FD1584A7891CDB77B742A32E55875D9A20A92F877DDE6662A0C0513FBB0875973924C16DD283AD5CBB18DFCC37FBF28914713A04DC05146A7D5399ADBE57B60D6003A81A3F9F5559450483D4116DBAE0470E15BA3F6323ADAB47AF30252DA7BC45E38759BA99877A6421F04232B35CD3B372C0C30ED32C64B0D74FA70C7E6085048C76C2E7E9B1BDC8B033021F7600BE3135B785491CFE48932E30A89F34729C012588374FB1307C808228DBF704F9A8C0EB8A98765A8E4C1B0591C212D5AAC9F9593A1418AFB84BBB931349B1B1BDD8D10BCDB66E7E97299A4B1C23770F8FFC8A08A0391F826B5058240D345FFFB4AC4C03483B74626D049F7FA52693B18B5381CEC4B13DD1478C5912A33F009F0D533BFE57105755392EE76DF7DBAB0DB56FBD2733487B511804BD63EC767464C10FD22817D79AA7909471B14C1E0445722A240918C2CD829D3C6C4BA81C0B6493B9D0DC3910BA048D515F2E3116142C553FD230D110CD71B449F6216FFF68839D83096638348A42A5ECF0986C62BF9305068CEB799CA1B7B8826A8FDAA131D6B872E1AFDE468AFF285AA818C8CAF80B9EBB2730F770FD143D81C86819B223D4059EC5A39F18AB5386142464195263F02F9B577105658DDC80A1C7EC2D82BC8C657B00C3D986F8261B039738449C0DB616207676B9FFB36A986C3350B698289367CA28CB404CA0C1E436F0E91898941D72E7C1BEF2A9AEF3305FC4C73D7ACF83F5248766A95F9A5B97185ED14C7508D7C8F7CA571A534BF4B843145799233818E0A65E0A7065AE5678411A25D95610DCF91847513BFE14ABBD94300F322619FBCB0B03857EF1340DE5510156579A52ADA7601EEDA662B61B16677C2C81F998869A9E3773A7C7942E279471A233A05D77899C2A18F35AC98A3243FA6767F076976529B75B75B070A341DFC95BB85C4BFA1394081141FE1B1B31365E3C2302C8A0296B9769DE04024DA48C2D7A3E5B29AE58659384FBCB4BA2ACE58C4CECA5BAA5131BDD465797664276AA44E8331E2F1328AA6910F68A6A73210E575CCBBDC689199559F094BB62380F436A925A7305FDEBA6C53A9193069873E724CB1B67FB8820E75C27D175BD5F5B5DB020C91EDA2439383B579C14DA0173E1704A318A03DE6691ECBC600097B41A7A9A429CA1A4D8A34DFC6C85E034E8A17629181FE7C993AB018D135A73861405186763B0F70C80D09706C9AF971313E47BB917761A0E3A39F7B96702C288254675F6A07771768F3939B7BEC979CBBB8BCA011124F08347B7BC7C70833197B192FB26589098E48834E8FC8551A1C1FC52A1701323D98C4BBE7779B867B813A5A2A5040D8E8845D4A2B03EFBCDBBB3083831B1FFAAA9E21C7A3AD77053793B1F7B7475B021E2C1AE25F194856B1594228E938A29B832930D5BAD3667C854366F83B48CD3501768F086B68007EAD71B2F046F630196B8237967C940D4727D388800DFEBB3B152CF57B33068803C1D55C59FBA14E31C323E820265C8826EC3B6018C8F60445A11268DA9B44F8DCC512B860212F408D3BAAC60CC6CA42211D2CA3A41271F745BC46FA70A9A8A3999CA83E8635E7A4843EA3B861194BF00909E4250AD1DDB3006F86DAAD2B8FA720D969A7D87DC97AE214AB3769EAC0261076092250133726265EB7987BD4BC01EC004E71BB8F7B06AB339AC9C0849FCB23C4BF35B11955C52D30FA0EB56DC7CBFAC95704E51969EA45AB01C10E59C691DC3908C083263C3565766A34B216F55F8284F219DBC158CFF247E2296C86BA69C922161ED753FDC1471834270095A85A5FABB1DB91FE203113139526961BB40B41E8F913A36461ECE86B37FB809779005C4312727F68923187203D001A378C0073A240190A144962BFAA89B1C384083178A1B44461926A9ED135ABAE505C93177F263996DE9780FC573619B63F741091ED57657404644194A25B6CD1E5AAB45E9021D9A8839546A9913752621BD79730685397D93EC49D86910C46A28142928A054599BA18CC3964CC4DB8BB7A87543E8A53FA23A95BB5B6713478F4B0B5CA6248018A729469A3794A8ED04A315F3783E667C0CD2AC80C68A40C35D64C90E5E8A3135CA15CFEA69D4A1A2E9B562DAC51409C6485E026001EB1196A487606404B6519974B386ABFC9CF4A0305AAB4A627B6C22A994DFE46035447F0CC09D1BAC0397A68FD647B0B13630D1439E63FC8FCA2B01CBE66BFDB4315230B06A9797B34A57A5DB208061195813073C7A10AC95B8755AA79B2033BF90386115066F177EA1421AB0267672B91830A26C20B4A8AB9011668CC46B49A2D824067102C95DC842B4F423FEABBD774B4A4BE351BCD8CF2C486CA70A5EB502AB5FFB8D77C2BF00FB7887FB960C089210D673679A0C71428B5AE348FF293602833B6927ADD5B18F22ACC4CE01517C65C848680D59931175954ACE9689FB6881CE17073E113CBCD53547BACB3946067A1A46CF6B4969065C98C17304D53AB5804501711C153A1B13D7CB442221EE311466469BA1225CBB312708C7B5E0055E3B476264B2244FE9590A557F088C9D4FB47A3D598A998A1B5F821D19909220A229FF020BC11143CDFAAA90E00B71D6C8B7622F24584508AB4D036792135B750EB9AE091B4BAA96A27DFB1AEAF605122060E5268BC4E9C08D1BBCD451A22E44A2D6201C6DE52BAF940F14956AAC311B5C3782E64377C645B35D210E1AE043AD6142BF6C05AAB07D3915500B67989709B7477432B947239A9C7ABBE747B2238ADE292448836B87938E804A4029F24182941CAE500D85AA7AB9556CA98C7808D90558E771D8709446BB1069541DEC34B69834C857215822F773871C4401DA04C70503CEE82491B07E8597480B6BAE6245084A4B92F9B015A158295F237A6376118868486D9C1A8389BAED937B392AB840D4BF67E31DF2C073A4A8C691896B6D6B623B95670CF404DD499773A54210975D1EA72667439E0FD8C112F33470789F2899A64217400E4B51FC501362EC98A45620FF6BA180A211CE5C154BB62A1904CC13A64FB6F445B48EF88CCAD56919A0DEED94A2AB2D4B6442A71C288753F1DC41EF5389E394976AC9CB9123B99FCD75201ADA0FD5DAF1A51F1D069822D795F8E736ABB8D1FCD68AAE27E7D301495DAB212A61FD3F209A8068FCF9A61AD83463C00D2CAB426633", + "ek" : "893C4E06A21C900D00CDE03DAD18BDC5AD66CFF714301F242CEEA3F87C088EFF468B05B84CA0F7869E2F8D4B617DD0D2D028C154754711EC895E66D18C740A4D053D6FBA065993DB41272478EAE9F744C43C931CD69D2DE3A4B104032F11D4B86E9839E98C8F75A5971225E24507567CD4CDF10824EA4BAF517771D341C462CF2AC1B529BAD8A2F8E24B4490A96967CABC996F2582E987202FA2F0C3B83789C91691C8C60CE8EC5C21ECA669957FF83F2824891A23D6A3DFBE68E060A4B8E01D924680BC858198921BE9A22431B18637257D2C6751EA881E787E3D7060A8503D7A0BADBC221AE49B80C10E9CB81F1CE984308C41C02F5EEDF167A094D4AFAE3C3A72B2F9DFE04D472A6EEA54C34CE4C2075183B72A2BAEEF5AFB4C166DC8344020E822EB6BA51B28923884A4BA566D7521FC10F6F7085B37F101FC7E7101A6B08DAC3B447C33064BC688CB352DA756BE44C316F2D25BB3DCA39DFE75032302388FAC6041CAF6EEA40CAADF896D5F69B571BE0E5D657C7DA446E14EA0BD6461E96AF723B3229C9E06E71D33229A693DF0A146F0D99980E791B27BE8781AA37F39F1C22785DC7154F4A54A6DBC70BDA09B5BBF5F178290400C24F0801B243637F9584E56B4C134CD6FB5C64470F908658498D6EC07D9FBD85BCFC312111DAC0415E002E869090EAF8A648FDA190F49F966304C976CFADFBCFE3E11F2D722B8ACD0F58A28FB5E839353ECEAA40EAA42EF3141F080EEFAEEC6A45AB7236CD13CBBB78203341DC858BAD9C33BBB8AC06929A67D8EEC5924423AED767A067D3E483EEB52CE68EE377186B1717127C8A9A17EB9A288DDE37A4FBA805014D6232AF60DBC4BFB55B157BF6B3AA6E42684C605E511E561558DB10DE3426F761C5A14484B92CE7C1779A723923299A2AA69FCA3EE4CD43583C83E137D0092794AC6446403DE651E0C10327EBCA2698811C84AB36CA2CF2649DF797B2EE1C83D2FAA1F57248E63BD81B1B4B2BDC89EB78A21D113665AFF17E3F6CF90564BF26D701E308A23408D741ACF1D8230363081C402EA6785B6583ECC5E12B01245355F5BAAD31A5D14E94E86346559DD3E33DC5475740363149CD7F01BE367BBEF8EDB636D224D1F101B3B49F8428AB8AD2692826E37DEE710DDC9F8230D8A4BED344ECCF053AE1F481A3FA07411ABE25C9FDD8C2D21746634D00EF31C3CBA624672EAECC10495621B79F8A528754220D9DF60AE06A448EE8845EB1824EB8442D810C51D3BAD0F24E3D12B710B6BC6E9EFC8B1756317295116A9068655EA0114EFE6FCE4567615EB5E52D02FF420B6B6333465073BEB81FD896F946EE43856C5275C7AAC3DB46BF1151F2A041D9D2523AA51FFAB366A24F174E7A0937A13160D6A97D35D334E540E29111A5C5A96941422B5C2B7B39E9E5EB64FD4D1D9CC61EA5D10581036EC62EC52FA08D927F953B6400B4EE3E777E249A11D7E1756F7FC0359AD4A166A665668E01ADA7F599D4F24E58DCA04E8AD5F2FFB82262CAF5D278F4E32942E208865962456DF61B06170B0430162D5BB1A4DBCC7574B11076DC9F62740F6E561F84786222DFF584C09C3DA24D9C3934226C31B0DF206CAB1FA1D447E3C208AFA4BF975E30B08B3E749755075938CAB90DE92233568BE6F04C1E5FDFFA3B2188D81086FE2808371A2D65F5A1602FD262DF4679E8C18AA0F87B3A4A3E5F41E4DCAB919DD1B8806AD31CE3F3252BECB35D0F37136924EA0FB059C949778A390443DBE7183D0D346A3F3C607340BA81BD44F08BA4B5EE1661419BEDAEB5B80866343089C6B3073FE6A8D68C03735C1A7C86476AC0A029B54D19619E8D7FB20EE0C9CFCF4DFC8D96D9C827CC565976E2F9418227A96EC6DA39907C9AEA1D70857B034E9A6A0B5FD280DAC227B15B6D220874656164E4F9859D299527FB6ECE8F36D3160676F8ACF6D7FE0A3FD3296CD46A6AE324EF5E7EBE28AAA3FE1C364BE98A91B62467FEA27CD3AB5476FCAFB92B23C8CA46D0F37E15613D6DC13BFC40824B61F0638B60BF5633D5E46FCA59C569F737E1A249B0D9CC3059618B094AAA5962AA24D4A4BDF8E2B2C8B38667EC8B8AC7459B42A85BAB35DC9928FBC6D789DEEFECDA3FC3C9AA5C045950950751DC92CB8771626FE6CF9D4E8A3D531BB93A5A7865512E3111E76852AC328B306A0D66B80CEE02CF0567B4F42160BD9CC06F77129F9CDA873C4", + "k" : "31D741629A9AF7FD7FDA1E3586F6D7A2C3988EAD16188EEB75BDAE0691DD7646", +}, +{ + "rngSeed" : "CC0C86CC0ABF86FA21899BE1953913C00E7C46E6B5F730C4E88B3C034012763981D7F14459D3081638080378348856EA", + "pk" : "12B3141C2441F96A053EC568C7D2B7E1229FDB620D905119A05690CBC9564BC9CAD3A66E05F641302A38ADA62E07380BA315ACB5A3AF9F02ABA7811726A3AC94723D6E66428EC8576718C4DA712846D450CB428571B1786267487B353B37D984CADC2F51AA6FA58C48B011360C5B1989E104B99671CE2985A174AEBF31CB5F803D29D93133D2AC1C9851031B21E8DA4021B44B4064AD7415786022BDB27A187495908DDB6109489CA2A67DEA269493986565E33941C1012E5504F4E5ABE662235BCA3A144C149D970EF3815079E2BBFC26066A7C8DC5591871E83731139951A262F9F7A2630C0E0FE635CFF95B792A6B9D490F0ED14B125B652DE35CFF994EF341A15BF57978211CA4149FC389C60F915EDC45610B9C5883080E96D77267268A37B4338CCCA90490CAC44A61F2795F943A25147A8943DC545C0805E5D39B70139BEF006DF10C695CAB9CDDE3B7C3A2AFE823C709936D7C3818584ABCE96950C06B248B858859BC2231622426078E480074BFB011BAA6B11336206425211C71B48D134B7B0B1C960C9429829AC5191F8F8AAC1ED70BCFA4342A362C68A35591DB506F2B69BFF31033F5CA4654421F48AFDD736E25D810ADD97F750530C443618E674A6691229C3A17F3B19E9D3740AE4A6AA6B77254B27374B246381483E52624A473035FDA0EAC427CF0F7244B3B8FCF4C835DF23CC5B729BCB1285AC49529C1241977741AB15C2984343F5139E1219D65992FF75637FA3A486232C1069CB49269305057080B535D4A624BDBB78AC18407FA8B48CAEC62459B80CDAC45013403ADF41038FC0B97FBB3B9450E9953718CD82B4E951B3628C7C1FA39F5629DBD074548D156437253FFD92F7DE9B292B00D1812CAD1EA7C26A295E373BF80FA6F173B68E7149EC6A454DB833D00FC462472AC51A208341A39FA8BA8F7C8243987CAFC65A48EB30E729A033CD8929A746AB6EAABA19388E9246FF28355BCEC0249FAB0E00B722B91BDEE0B8FD80377509937F201880239CE9C9251A9D3B48D455884E98ACD948F0AEA095155B360620F29A279116BA08A5B5CCD6C86E0E57F4B33C5787C38B7F0B924D71D7C06C58F932D7C68422085C8E365C6787B8069D21F0FA5A414D44267B40A5F629B6CF82DE5588B7E828868C5B6AB9438AF030983C7C37C1032BE605936002558E161BA0BB2B1B4C6B1FB5FEC029EC389A375D563DDE64EAF7B95E4A05E2CB7B1A4809E4E98893FBB2D79AACF0E7A0718A322ED8296323681EA398981512D04F56AD2BC10667187B2ECAE2E9AA5E2922FDFF22EB9651C37C75F6CA87AED6213E0048E36984E2B9B6936D61318DA6B7DB7C8B1538754B997DD325052C21D22328F03D5774E711A51AC6D3C333F0A529C1568840BC92AD42603B4A361197B36681722D45B497CD94F73D90FD48570B445C4B166A02C5A3C5928BFF91545053166F0FCA5F7B2229232A301484DDB25854D522F546C477F43072814668A734786B6810770B227487A21ABAF17E79DFC365C3843363EC53AF3686CCE7429104740A327CE441BB8E3736AF22448016B8E69784D3A2C92E0F1787E818139E19E95E2A9DB2B62164221D9B77AB2CA91DC221BA5533322AA772459C6C5763F24A07C5B715197A20C7357CDBCC18840AA7AF18C4684E275CB3220010386095259C4FA71F94662133622A2945D8CC6572B2311A7FC0E1091CE19D8C5D7913ACC490E6C1751D5AA3E5C7218EBCABA43A8C0F6D78897C15A20A87A891BC2CA94779525499A2958A60B4878DB537D9B148C01B7C2A642FEDC0624E594CC318A0FCB52960526AF556198FA028604A9F0181BE16399EDB84B38405E33B43C13D83E54483418467A57F8A796B4032D37A744FA6200B0AAE04899C6865A66923EB173906B26C33231A90044C9C4D5215117CA1D50CBAE1120471C0462EB1247F07A2197680856428BA494DC721BDB3760C1A97D2E59735BEA6064650F55212117659380052550FA311599923DEC097CB28D601CC4A117269822A2BB589AD165A8587893BEC2B0E22030DD8736D387673A67151B249C49E7ABF96960F5394FB255BE8CD9927152211613C5242A45E87028745626DE709542338E131678B871955582014F1074E2F8BE14A634AE5C40DAD64B78352FEBCB21BD987D7632C16E03261C4771BED2BAC280F77DA45501C2EF4D97F2FAF650309211985BBEE4C3A85865", + "sk" : "160B1E369B620E7891965A391BB99D9933BDDD1B407A647DABA289F0F16509F41EB62576B3CCB404744D2B699891300B119CB1BCBB97C090AB4091C1D15454CDFB2E0E181EB677797041B47069680A929F85DA252B34B571467B564BA72256867ABA61D8B14561B7A6C6CC0BD73227A3F5C840D264CA45CBB4D6C529329F011B2235B83FB8158A3966643C5664E4A4028B784AA3F84C2D21A6ABCC5F0BBB5160326963929FB3296B3C65502A34C409CA9CE0FAC53661A77A6AB85339364F0A999D21147958B01276C31454C14410989186496A5AA529223CC1D460A729A5D5170FBCD3C742B267D5C6AAD2047154630CB8492556372E927C0FF48015B4121966C742730C223BA3AC0D9553E8F3043C84A19CC40657167A75603A2E467698D117E0E96BEB199EBEF57AD25B91BE9BBBC31499999068D4F56315C05CF69727F6C1B09038CE4E3BA307FCCE081669C7F666934A9FEEF44653466915360C9160A573781B0BE59F23D817922BB9453802518B52250B5BFB1631F16327EA30552CD26725D94717E098E9B40559D12DB67680F52AA19CE11EF22641D214B1D14689252027E68BAE8F3A0034189C2452A89A8011B0F228C2F4C6C575AE8AB49D9B951B7F534C5C0C02B94C2EB1C120FBC6CAB391AC02D71B3A61AEDC65211314129CE950F4E82530F297F1D6B8B9FB6F0C423DDFA842F5F6667109CAF5AC5DB25A26FF46A771BB1731B855E909604DC4426D1598BA26B94FAB7188CA788C1B473BB00F74232D7772C196E3BE42C20AD9991B1460661C85A90285952A5565B9290D50FC2821A84EB80680C4D204981851882565E20455E7F70015289032D1792EE5475C499C8BA701BC094CDE789B7647536CEB7471DB9E4FA51B1B0A97D2D94F73024E83077DAB62ACFA03289197CD5D802901E34230D47CD5B469D202AD64E98F612CC286A267D17596BCA1634094CA33E09B9FABB5CA170920804A3F58233ED2CA62362CDBA424114275C1EA0DF1183C33303EFA559BCA706FC77B164670058708B5A97C6F18ACBABC011D8FB230ED56265C5C013BDA6DEFD92E76C0AB04FB8B1E0758073325C8C60465678537BB5FF47923B39A800CF39EB5686B653C9423594FD7290745D566ABE2735DFB4E9F7454EECC53B6FB11BD407D37E49A3155CC3561CFBE8250DC207D3F942FCAF3CFE5223103D2475D0ACA6809CCCE5B8D70C7AEBD053F4C94BD2B66C9E1EB68B7B6989F6BABFF582F85D08B3926C0FEF7AD5EE61CFF982B690689996412504284E65BBE77123180F78EFBC01C41A8262EE26765D39E94400A1A27CE4B147EF5E25D314C69AA86353F9A3933B73EA131BD7EF12979B863BA331F1412386F87336A90718DA6C9265249CDE518C39BA4E6AB83AB53C2D2C846F43041C4855D93099939D0BBF88722D873BDCF5BBD73519D8EF50255C7A18CFB04187147EC706FCE576CE8F13928530B43262CAE618F09D434FBF29FB5380ADD29C3A7992613733FA730A17E059C67297598F44FE28B4C4FB04FF17BCC7F3C8E516B557BDA28FBF82971E8134E3082BD7497995BB2E09CB398254A12E0BDFAB5A1F3234853C3067903A64AC22E528963EECBCEDC58149DEAAE0965185B1C2588B40668103719152016E833A95184DA4B10958C78B2D4AE2CA07466700F62FC687FCA4779B500AA904A0D95C93464717B3C21E58B9E4C133D793CA5660348AB0198A81937A8E000225B8728477922813B9F79325F788BD8020F052801FC079F3D604B3EC830D29407AA9C2168A122434B751085804207B29062B343FB90426319998A98401232F3D0CA1B475D15650E7E9A42F498A7995C4BDCB893D09531832A4FD12C8874E4C3C65005D6C27A102725A8113D2EC9663A40255FD4CAB9328B2220737F13AACB4646B392811EB3CA72307F89919525107BE84A5CCEDC1BB9D313F7B99D619CBAFEECAB88A01BA78C688166A6710B12A4724B2C661351574D7B1BA6B9265948D5A572B2C74982BB6F8546B8684CFB6916C9C1093BA1C205F92AFE80CEEDB043A04B67468335D28A8EB2406C72690700E724D773B40F4875C30B056E904AB688888195655D020DDAAC5D1B20032A9B65501B51BA036BA2D48E5FD75B5C2A4D8B65766BB7A341247EE8121961E40CD192C6C126A3FE92488D467212B3141C2441F96A053EC568C7D2B7E1229FDB620D905119A05690CBC9564BC9CAD3A66E05F641302A38ADA62E07380BA315ACB5A3AF9F02ABA7811726A3AC94723D6E66428EC8576718C4DA712846D450CB428571B1786267487B353B37D984CADC2F51AA6FA58C48B011360C5B1989E104B99671CE2985A174AEBF31CB5F803D29D93133D2AC1C9851031B21E8DA4021B44B4064AD7415786022BDB27A187495908DDB6109489CA2A67DEA269493986565E33941C1012E5504F4E5ABE662235BCA3A144C149D970EF3815079E2BBFC26066A7C8DC5591871E83731139951A262F9F7A2630C0E0FE635CFF95B792A6B9D490F0ED14B125B652DE35CFF994EF341A15BF57978211CA4149FC389C60F915EDC45610B9C5883080E96D77267268A37B4338CCCA90490CAC44A61F2795F943A25147A8943DC545C0805E5D39B70139BEF006DF10C695CAB9CDDE3B7C3A2AFE823C709936D7C3818584ABCE96950C06B248B858859BC2231622426078E480074BFB011BAA6B11336206425211C71B48D134B7B0B1C960C9429829AC5191F8F8AAC1ED70BCFA4342A362C68A35591DB506F2B69BFF31033F5CA4654421F48AFDD736E25D810ADD97F750530C443618E674A6691229C3A17F3B19E9D3740AE4A6AA6B77254B27374B246381483E52624A473035FDA0EAC427CF0F7244B3B8FCF4C835DF23CC5B729BCB1285AC49529C1241977741AB15C2984343F5139E1219D65992FF75637FA3A486232C1069CB49269305057080B535D4A624BDBB78AC18407FA8B48CAEC62459B80CDAC45013403ADF41038FC0B97FBB3B9450E9953718CD82B4E951B3628C7C1FA39F5629DBD074548D156437253FFD92F7DE9B292B00D1812CAD1EA7C26A295E373BF80FA6F173B68E7149EC6A454DB833D00FC462472AC51A208341A39FA8BA8F7C8243987CAFC65A48EB30E729A033CD8929A746AB6EAABA19388E9246FF28355BCEC0249FAB0E00B722B91BDEE0B8FD80377509937F201880239CE9C9251A9D3B48D455884E98ACD948F0AEA095155B360620F29A279116BA08A5B5CCD6C86E0E57F4B33C5787C38B7F0B924D71D7C06C58F932D7C68422085C8E365C6787B8069D21F0FA5A414D44267B40A5F629B6CF82DE5588B7E828868C5B6AB9438AF030983C7C37C1032BE605936002558E161BA0BB2B1B4C6B1FB5FEC029EC389A375D563DDE64EAF7B95E4A05E2CB7B1A4809E4E98893FBB2D79AACF0E7A0718A322ED8296323681EA398981512D04F56AD2BC10667187B2ECAE2E9AA5E2922FDFF22EB9651C37C75F6CA87AED6213E0048E36984E2B9B6936D61318DA6B7DB7C8B1538754B997DD325052C21D22328F03D5774E711A51AC6D3C333F0A529C1568840BC92AD42603B4A361197B36681722D45B497CD94F73D90FD48570B445C4B166A02C5A3C5928BFF91545053166F0FCA5F7B2229232A301484DDB25854D522F546C477F43072814668A734786B6810770B227487A21ABAF17E79DFC365C3843363EC53AF3686CCE7429104740A327CE441BB8E3736AF22448016B8E69784D3A2C92E0F1787E818139E19E95E2A9DB2B62164221D9B77AB2CA91DC221BA5533322AA772459C6C5763F24A07C5B715197A20C7357CDBCC18840AA7AF18C4684E275CB3220010386095259C4FA71F94662133622A2945D8CC6572B2311A7FC0E1091CE19D8C5D7913ACC490E6C1751D5AA3E5C7218EBCABA43A8C0F6D78897C15A20A87A891BC2CA94779525499A2958A60B4878DB537D9B148C01B7C2A642FEDC0624E594CC318A0FCB52960526AF556198FA028604A9F0181BE16399EDB84B38405E33B43C13D83E54483418467A57F8A796B4032D37A744FA6200B0AAE04899C6865A66923EB173906B26C33231A90044C9C4D5215117CA1D50CBAE1120471C0462EB1247F07A2197680856428BA494DC721BDB3760C1A97D2E59735BEA6064650F55212117659380052550FA311599923DEC097CB28D601CC4A117269822A2BB589AD165A8587893BEC2B0E22030DD8736D387673A67151B249C49E7ABF96960F5394FB255BE8CD9927152211613C5242A45E87028745626DE709542338E131678B871955582014F1074E2F8BE14A634AE5C40DAD64B78352FEBCB21BD987D7632C16E03261C4771BED2BAC280F77DA45501C2EF4D97F2FAF650309211985BBEE4C3A85865A7EA65E4729DAAC39A47C305AD3084AF028E66F759E0E22469D0386C10BFC23AC30E299218D4A39C2EA3FC06439FC4C411E99BBC34B8F30D23845E91E71FEF3C", + "ek" : "086DC72B6ACA4CC83D26906586DD625A23D9539BD7A9BE0E7394E02DE3DB7F684F0D6E1D550E70BA405E6B8E1DC1B7C42E0197D873C9BD4B0F350F0E8B9D1F8C891925EE009E8F2D6E06AA9AC7E6E4F4AF2A76ED8DCD93CD2F688770807AEBA91A430E74735D06170EA35F1D9F7BC043043213990481982AF71960E23B9899D05B1E5A352F2341561040EAD9815781154EF90FE4EA57F943F961476176B4792C940B55C7C9717E8F7BB87F995D8710BBC54A4FFF0914E567FEEDD38307693FED49713CF33BF95C020BA106513067022B63151B1C2CCC4A0A53D198D2C9561A76FE4D27F3F5C7C84CDB9E706CA391C967C303C1E7C03FE669EF2058DDBB0FD9E0CEA62B343AA99A1636F6641CB0B78E44921A5399023506A563B21E05252D27AC8B30AC7B5A0181AD53E26D5FA954D070A68D950AE3E756B2199660FC42B8201C95A038496A27C7238B6D32CB6A4C90B4D87FA29630F578CE2388257E9E1059CB74FBF5E710BAC9F205B3599AFB7C490CB65603DDD990EC7B7760AC1C60AE78E0F24ED0C5780FE0644A3DFF4C7E7E43124531651AB9F0EA423BB0E89618C5118A230096BE65346D18370E17B34A0CF6770796A8A89BE8840133EC7737EE01B3A553410A20657089DFAF4023BB97553D734E2A1DA4C2567C504CCE57432CD78A1F71AECCC6E24FFD29A2B1DDDE118B142151FDC7C99B3F80F200C709571B5F4EA1F38FD4F90FEFA776DB22FD20F30E91EFF8DD4CF54EE99DAEED4E8C9014D62A948FEDEBC41976014DE703918C88A24E12A72FF07399EF73CEC6DA5E41B7217728C1CC788CCA994CB932AAEC0C564BD144979B425A9D43232AB418C139F28C3531D14D28928600716CD8D81B24498D14923713BBE73655FFCD1CC4EEC41E97DBE761C17BC1A890F950B2D147BB036E5C2095FD103CF7812BA2B12624B1095145EED3D48A8B5EABC7610D79C990A243FDADF6E1BEEE4D49EBFA0B1F5C78E8B3C6F78EDD3F966BCFB35A8C9032FB83E900851E7F89E0CF06AB856F5FB197769E2F4FAE421C6BE219B2B5E2140697786DC891962EB5EF77C2BEE010F34ED0BB3DF048E684C5039AE92CEEF55FFCCB0B327A4EF2E9F8A77B32128DD3834353A7B5E957995DE86337307C5D6078B873795246879F7988DC381FB17ED0012DC9B3188A1A54EEBA7209A14D9B44545CC8ABBCF81343138458B138DF39EEF4AD9900EE249D5DC54F4C2795D8E1D02439D8F6CD875DB30DF7CE5E61F36E752FCD64CADC3423598A2DC840B287F1F211AE7170B09079D684A7853FFB3FDCBD32628D9D3BD019222812DF53C9A53F0EDAB0903491837D84C2735DE272B198D80E92313611EDD64E9FE953170BE00987BECCC6E40F57A39A1BC8C77934E17FED8B4B390588E1EADE0D4433AD2E4BC30E5BF3DE9E559DCA65BEA23EA0B07FD10E254158CE8BB3FC6175D6F9D308F2F4D4A0D2A89A206D0FAF6CF1AA8520F910988CCA7BFD480765F21CF3380764EECC1E52F06F9B2E6C2655F31E6B86E12001C35A86A5F7A0448F0593191F8CB062D4393E259C0CEAE4D0CB8624ADA7B505CDEC0F1A73BECD50D3036E62ACB8BB4BEB6A587E56146F78D5D3B342E885539BA3C216356807CFF93E0EAED78884A1866227DDE724A572ABBC372FDC20B39AD4CE77D94078DB5D696E215E89237E97C7AB599349842199A62DFEB7394D09AFE0BCDB8F970FE267A1B6E1F0127635F7A2A6760B3A39B5EA6EA0E95F7053D42039C06925B193300F65DF93593CEE3CF60C26876B0411BC82E110BF460552F547F37884C683427F99D4CC691190C412D009F75BF207D4DEA896303C55DF40AC4715E6CE1C3111A15389BD6490E8B7B3C12EE25DE2BAD5835053C8C2190DAD8DF3910AF7E9ADFB217A8C913632D433E0C66B779AF3F8BA1276AB208402C8AEBA42EC6C548BB1AD9D9E98ED029E0DDAA8AA0FB13EF34EB0065C377EA8259389DC685A1972E09A7ED3112CBB169E363438B99048B34C2EDC1879B520CE3ADC6A9705B44861DBCC7A89988E332B394438BDBE49CA04C264D62CEF37BC333F1D4DFCAFF1650D82156654F8A50557AFEC93C75AC02548EDA9DEA93FEFDB7987917DCCE9D06D9CCF5FEDE9209AB5183C5EC9F65CAE1DAA3EA3258124FB10458559106E3A2B716B559595D3DB554EE6CE9A141AD3BC62FB8C42D0982A31955151F06E612994F0AE39B223B699E41A", + "k" : "7D9B9B33E973BA7CA087989D0B5BEBC55C60A3429AC6611898E3A48D0A3E6400", +}, +{ + "rngSeed" : "6D5A7CC326ECF3983C4E7683F45263A37F692F3BCD2D920E1FD9584350119E74F9A3F905F70D3E20318C1413DE2A0DEA", + "pk" : "5CD35CD8F09EC13054176C506D02A7258A84EB685D14C3352F0B0051757C30D4184AB6A37BB6058C4451E89106AD2C259BC6791DE49ED9DC0BF62BAB1201429035C8716B864552A26B0549B1832A2BB01CC8F8CB55630618A525F885CB6FB407F042610681428031399E5666D56A9656E1A530460AB4178C3E957D22244B1366750DA084F572399A33BB452C7C73F3CBE9A7028CF3849B475606EA2C96958DBEF17AA08B3F15C146EDB65DE9379F62C11226F9B4B85802694614EB229C8ED44198542685610F53885F5BBABDD95C5597F89D825B0F441B21AA476BA4970BE900A2F40CB742402C2093803F27CA37D06347615131B81FE6AC6AC9249459C92D92133870111AA5176C6BB828A4198C865A1730A84961F3914379BBFBEB46411C1705BC86F8A38A5F817F1B4C34E99784773051764B3F55D38571E98D744043287A19DDDBA7D4EAC3F0B98173D09F0CD10B22A0BC0417A056C66064C906B7559AB134B6C47BAA7932540070811D3AB8F5F265822873B4C78AF45514FFDB6D03D79C24A88531D4AE7230486977B612CB05B906CE19337CA1F0455718569E80C2C2C795B7A156E60C5C65FA19FDFB5E4FD96727947FD66ABD94774A5BC45FDA822146A12B67534AD93AABAE123AF9CBA2B2A376608CC6335AAA99F759DC964AEDD80E432C6F417A1A65C63F639B5312C35038FAA9C45051BA31C66912538FB51A85189D846B799D8C2FEDC439EC8685B547376BE49A83FB60281ACCD733001D729E4156BADFFB3B7DD8CB40411EE7A3970A168357A89DCB75535CE341B5B47403308BD87BBA01F5CEF30634C9D27D56DA4D4373234790ACBFB5051CA2A8519A42E610269B4B32C64770A5DB4CAA1CA6670C432BD74745FBBA2F22377C729446954A6E067454639C3771AEB626871E3558A0F141A37C2732B13B13532CD16462F7822BA2869A0B20717E3675A328625DA796E12C4403D380CDB54930DB78493994C0793FD67B0A91140758FB78D229051E696C8707CF5A1C40EF511123B7C6DE51BA4B792EDA810762CC114F716C66A79DD4F5B0865A1A2A1144DA80C4106B72AABB0A8F8036BDE19B204992DC600956AB076CCAB601F4250AC4B2CEF77C38D6B6EF8907FEEC307AB29502B269DBC063E337AD43958D893A36318C6C052549BD907313C2251744AD02C30F78D0B394635508951856D1160706CB042275BA20A4BB6A734F9856AEBA164AF669F43C5016F1305E8084389581BC146168C0914D1A65AE5188E19082D585AF435C183DF28179C6B2278491DDE450E7B1BF64075E0A9A8301454B5E111E39B0CCED002680E173C5DB96DE082C3C399E398210C974B6F47449DC9326C1A7A79F893F454834E6EC1BCF0A860D962A4E05A1F51825981B18DC4AB661ABCC98D4313CB40BAA402307895460139C75B6AA69E27C5E69273141487B849A42996A55788B3B42018DA0AB1C315D10308F05C54176D727A04B656CE6859F69471A186A4FF6B17B877070924758C83DC681292BFC7618F2B75413C79EB9B945D1B2AEF95A47CB21CC8982F405739C9064975B5AB875AE5DDAC05A65A43CEC4ED80ACFEB15AAE898B995E649F32B98613C77FB926879EC940BACBCA0696CF6C6749604A1A59979A623477BE871A2278D22134A95ECC1B116C48340C6C6981ADBE742EDE1426BB65B942302162B8164352F918679D53C06BEAB47F07C8A37AAB0A7449D45E01CFDF9422A783E06F645353CB56B8C57E28840E074629BD58B5646CF1C96003181B915A71CAA00A35FB4533DF22B2367C9BEF95ECC85359A236E23A425F9C975EF842EE20228C66673F1EA3BE278B0FD43AD4C004655532654598F34A257BC7C81DC0999266C8C2F40A4D9364F602BAC27145B5BE7C4FB0759288761CCC586B9039D6EE57858A21A05676EDB52C937F11C35FC091D3BAEFCCC15BB953BF5C50B95B449B8DB449810680FCC53169BC8403BC70A5B2E3DEA7AF89AA0FD662255197360B8C7325545B7F45F2DFCCE05D939EE5556F5C63CEF52CD68E8399EC25726A316269374EB94BC3884011C89890E828B5C726D149CC3446B8A12D76C35545EECC7AAAFF17030A0CF9C993E53A88CA000116C2B206F0187F725ACC696112B5C44976A22AB617A0C42A64D03B8CE88B7A8AA7CDBA28A197A5D3BDC64CF089F922345DAE5A7C6BD86D17444F21DD9B1A5C82B9FC906C4AD49E0", + "sk" : "41A174FE5AC24562AD78E74C8E65930E7CBACA489509D26EBD09A742548FD3B90406B2B8A218BDBBE4A5222C13DBE576D37C0D4DC20F3E416DBA4B784491AB7A534D28B90C7121589DBC55BB214AF6475853B74A4C048885A6CEB5184535A5CFFE6C3A1C43C305FAC42CA17CA7F64A24700C0048447154CF15D25636873D41C0B588190B2D0178F12940F5EABEC85A59F90179076ABFC3E734973B4074C721A3D41AB31465392841EC558580711AAFA93BC1382EFA153F5BAC2FAB8C17EB7872E9D3B7B6FA94C2EA20D964388BD5144C237771E1C6A7F991D37A55975078DDDBB76499B6B87C974BAB79EC5513D839CEC1926AC9C5A7E45861E0A226E6F2B00A95BD52A17EEED93F573C19724C593ED7749E542287A62AE01A4021737242424694637649771345408D2800B5A03872CF6C70CE848B8CA2C57F93543BF7A61434A48F536338051BDCB092DEA6690FF3B6EA892612AB5472C0CB9E7987C3756548937E47A2CFED69AD4444CF35242BBD1B7D65EC028F2116507BA09CA114E4CAB4BCB736EC5109822B0A590270D3268DE357BEBF98317090185DB82B6C28CD4D7838D8A2368C9A315661B3554B43A8CB4CF376BD771664B5EA2C50EB929EB768BB685812EC4853A33A49519AB98C1FF8D4CF37B2BF5B97C2E0921A0D769ABE68C7E19A87B50A6A56228F4FA4915B2192D1E4225A58B3D2F0CA23A05DEC8BB5FF613E636C95FBBCCBC5F86D49E447D0124631F52FE575652F782CC5E3A376BC868695868D17B254C797D8CBC543343804C7B5BFA731DF211F48B20D0930B19485531C678328AC647C2260F6062AF02CC2C1778833A62B4C40BBC095B285E282B641B75C5CBAFE41A0EBF88B3CF890B13B5B8B032177754763454EF79403B6922CB012013AD810CD6875759693B298A57D107B8B568778E6C493239719C73249545CCD0520805ACE114C0B7B936314A6AF1F37BD3876322AD855877448E5BA7162CB7C7457C8D2A47D128B1BC8603A60D06B044C7611239EA90C0CADC09A4E8C4CB0AB386DDB2AC14C2741BB7CCF6C0387E6966EC824691855CF748B680134535397EC427DF2149F27FB14FD814D47031DACC858C52A5B435B6D9B8C8F76A40EC0486D2C670B5E4878ADF7ADEAA9B752B0350775CE1B9B590A9695C3C05C2EE0A6F2064A363664DFF41668C3BFAC172E1BA87E3D3845D1119A36F52C394CC328D8AB23914609C058B8F72B4F8851048868216A9B13C7CC55177CE559553AD28EBDF2C927ACA49CA90142E2CAEF59C9D457387D81C55729177C665DE8D2AE21453F91B7663B2B1F4304BBE02499F690B95AE18976A00E3151C570C479A6D512AFECBE34A2A2F2B7CFCC03290A052F00A093956091C22729E57044DC066F892799B9E263DD957296865E09A2C15E300C4CD1B1D05067FA1483C6E765C551425EFC7D5B15517BD911178A2B9692A1FAE74EF4CB2785E561A51C498FFCC20F039E0CE74DC62C3A56303774449661F171487CC2CACC071BC3B2CC54BEE99332D655AB4E6B8B9A8351397A398C484AE22A29A4187C6F5690BC741C23E9C2AF0916F8F4BECD630D47010402850F3111930CDAA5FEA74E3748492E6B2C589AB4AF5A011BBC8CCF878BBA2708720408CC56BD83859E62AB95DAD5C17DA8301010933EC27D18F02318FCAA9FB5336BFB608CBA4D0B59CBDE5C8317D09443F7AA641886201B62CC3B233903BA98CCA9A40AB8345C1DD886BFDD87CF6EE2C50AF15BB0539AC2673D0EF08E58BB34E3A83198093380F11035E38A0CF532CD47A45ED7CB95BB9420AA62F779345B6C851F9B09DE8C79EE1A807160763B9A0B26E74EBB32AA2F429740319285161585A7BFB6F7294669CCE50A044AD055D2F747070AA6CDC5195B221DCEF05C43456DD2BC1C1784B397444E6EB397F35B5E4CB8AA04A7207633AC1526BDCB9591494554D03557CE60820325008B42ACAD262F8A062E1AD11716001D99E8B3A1CAAD0226878099947A2511F62A333B1B97F5B1654A35C73F0C69FD92531D32A33CB50BE57041AE870E15019A0F30C35ECC8F33EA39AE209D7F65C5937B5BE1A82192C8C335F35B36D6CBEDFC953EB140E191C819A0CA16FA8775D67192161A3EB1A508B0695D61971CB9B4CA61CCB459B8FC3748D7C9596A93A88B535A5CD35CD8F09EC13054176C506D02A7258A84EB685D14C3352F0B0051757C30D4184AB6A37BB6058C4451E89106AD2C259BC6791DE49ED9DC0BF62BAB1201429035C8716B864552A26B0549B1832A2BB01CC8F8CB55630618A525F885CB6FB407F042610681428031399E5666D56A9656E1A530460AB4178C3E957D22244B1366750DA084F572399A33BB452C7C73F3CBE9A7028CF3849B475606EA2C96958DBEF17AA08B3F15C146EDB65DE9379F62C11226F9B4B85802694614EB229C8ED44198542685610F53885F5BBABDD95C5597F89D825B0F441B21AA476BA4970BE900A2F40CB742402C2093803F27CA37D06347615131B81FE6AC6AC9249459C92D92133870111AA5176C6BB828A4198C865A1730A84961F3914379BBFBEB46411C1705BC86F8A38A5F817F1B4C34E99784773051764B3F55D38571E98D744043287A19DDDBA7D4EAC3F0B98173D09F0CD10B22A0BC0417A056C66064C906B7559AB134B6C47BAA7932540070811D3AB8F5F265822873B4C78AF45514FFDB6D03D79C24A88531D4AE7230486977B612CB05B906CE19337CA1F0455718569E80C2C2C795B7A156E60C5C65FA19FDFB5E4FD96727947FD66ABD94774A5BC45FDA822146A12B67534AD93AABAE123AF9CBA2B2A376608CC6335AAA99F759DC964AEDD80E432C6F417A1A65C63F639B5312C35038FAA9C45051BA31C66912538FB51A85189D846B799D8C2FEDC439EC8685B547376BE49A83FB60281ACCD733001D729E4156BADFFB3B7DD8CB40411EE7A3970A168357A89DCB75535CE341B5B47403308BD87BBA01F5CEF30634C9D27D56DA4D4373234790ACBFB5051CA2A8519A42E610269B4B32C64770A5DB4CAA1CA6670C432BD74745FBBA2F22377C729446954A6E067454639C3771AEB626871E3558A0F141A37C2732B13B13532CD16462F7822BA2869A0B20717E3675A328625DA796E12C4403D380CDB54930DB78493994C0793FD67B0A91140758FB78D229051E696C8707CF5A1C40EF511123B7C6DE51BA4B792EDA810762CC114F716C66A79DD4F5B0865A1A2A1144DA80C4106B72AABB0A8F8036BDE19B204992DC600956AB076CCAB601F4250AC4B2CEF77C38D6B6EF8907FEEC307AB29502B269DBC063E337AD43958D893A36318C6C052549BD907313C2251744AD02C30F78D0B394635508951856D1160706CB042275BA20A4BB6A734F9856AEBA164AF669F43C5016F1305E8084389581BC146168C0914D1A65AE5188E19082D585AF435C183DF28179C6B2278491DDE450E7B1BF64075E0A9A8301454B5E111E39B0CCED002680E173C5DB96DE082C3C399E398210C974B6F47449DC9326C1A7A79F893F454834E6EC1BCF0A860D962A4E05A1F51825981B18DC4AB661ABCC98D4313CB40BAA402307895460139C75B6AA69E27C5E69273141487B849A42996A55788B3B42018DA0AB1C315D10308F05C54176D727A04B656CE6859F69471A186A4FF6B17B877070924758C83DC681292BFC7618F2B75413C79EB9B945D1B2AEF95A47CB21CC8982F405739C9064975B5AB875AE5DDAC05A65A43CEC4ED80ACFEB15AAE898B995E649F32B98613C77FB926879EC940BACBCA0696CF6C6749604A1A59979A623477BE871A2278D22134A95ECC1B116C48340C6C6981ADBE742EDE1426BB65B942302162B8164352F918679D53C06BEAB47F07C8A37AAB0A7449D45E01CFDF9422A783E06F645353CB56B8C57E28840E074629BD58B5646CF1C96003181B915A71CAA00A35FB4533DF22B2367C9BEF95ECC85359A236E23A425F9C975EF842EE20228C66673F1EA3BE278B0FD43AD4C004655532654598F34A257BC7C81DC0999266C8C2F40A4D9364F602BAC27145B5BE7C4FB0759288761CCC586B9039D6EE57858A21A05676EDB52C937F11C35FC091D3BAEFCCC15BB953BF5C50B95B449B8DB449810680FCC53169BC8403BC70A5B2E3DEA7AF89AA0FD662255197360B8C7325545B7F45F2DFCCE05D939EE5556F5C63CEF52CD68E8399EC25726A316269374EB94BC3884011C89890E828B5C726D149CC3446B8A12D76C35545EECC7AAAFF17030A0CF9C993E53A88CA000116C2B206F0187F725ACC696112B5C44976A22AB617A0C42A64D03B8CE88B7A8AA7CDBA28A197A5D3BDC64CF089F922345DAE5A7C6BD86D17444F21DD9B1A5C82B9FC906C4AD49E021CEE8B1F3FE43508E7BB3B567D02568CC93C39C3CC347E2DAE6E0144714D80CA33923382F8863478882483037FB1282FF917EB6658A7154C6AD64B5858C629E", + "ek" : "317C4D6AA11A96709F96FF3E9C420325C1DB869BFD13B7D92A3895C3F014B76DFD7F29D7AA4B55901C21BB7BD17BA6E4E42699ECEC9DF41EA947226D38DFD8391DEBD0CF8B72422DD44360414D9D3C5BEB6A75FC587272B21DF1041F14F70923E3613B64D8F2E12634EC5490DAB74616BED492103CA560D8DBF6D68D0DA01178CD9837180423888FA13337C8B983B7B12880F1EBCCF36407FAE8944AF66CC5C097F94DF44653AA8A1B89278919E79CC47FAA9FFBA32BFA38FE240CCB7D4638FE8DBF65ADFEEE909AA02A855E8606AC1A4526C30A728709DE9351788260D3499B4A247C2C8D7951D465ED3087FD06ED6667FBEE28939D0487A9EBA845BEBE4B7C023239718206398C71DAA0D325462F73BF6D46AC3A35DC38B328345C1C56B9765F1CF45FFABBF5B5359B28592BE49056C895D4B8C61F8774600AF143B63F09D19C5C59B90EE696050DD436587B7D9C25053057DF7900E31826C107A51368942404191E36059B9C9067DD34B03F99FCA8D43FBBEB76F92102A93313F0BF800AA43094F98FB3680EE3395735AE630CBB96E82D1414E5162EB962D5A9B729345F3691CF9730FCBF619D7C04DEEB3D26A0DF42B2A45953ADDDE594DE3FA83003A51F15C9217B5D759FE7EE6D8501404A61A823020536BC557C09C7E6F0F104F3FD28E874F5F4CE4D4430339F75169BE82068E5B41ED8C6094707D6DEB681DB46DB337F5100F53793D2DE61F8EEA989C710C048AC9B444734ACEE665258AF69D9C754EA5A24D27274B0062BAB055417A8CA27B7DE876239BAEB84A0601A177CF27D34EFB3D1D064DE34E6ACBE6C1852A504ED6CCCBDB1438C242404CF45BD74A90CC28F7226A56F7FCD60DD09A7E23298EB1E71123585FCD647020D8F026F20953894CD6716D5C6F09285627E4AF13C719B6A2D08086A630F0A058D91F6FC70FDE9C1B6E39249F046F0F94242A21FF5602CFCAFD0C5EF4C4AA9674F52D36C30D70CB1DEEB5E21DB0AD484B01860AB629EFCB99A0116C86B274E1ADBF08A21989982F7C5732D5A70AEBB107F05DCCE166E4D4AE62C8DC1BC1BC941E582A887B55F23994F4B2014D9A308141449DCDC0C355D76087AE3AFB0CE314CB6CCA608E1696CBCFAD98AD3D279C6C3D932B414D20A646FBE94A22198C727BD0CE6B340ABA9106D3D135E57EE930D92E60D6634A86B75ABBC7B61FF93F0F0C797E2F78AC7CEB71B05D2208AE708E40647D4978C608717606B0AF9ECB6EC80C4636EB814A1CBC639BFA8DC5E24D1468EA8DC1425A09B8797CBD59ABD7282ED3C876AEC35D495408C4CA890608CE2F3015EE8C68D44725CDFC7A97316016F81CAB3DDFAF5ABC1F8F4A591E1B21EB8A0CF6343A07E879AB36E6AAE384916AB17B75E3F0DB745673A4056DBEA0EAC3D966F9FDC387B234DCC6FC0F6AC5238613D50132EE1A1DF23121F38C2ADB148D02E0C1B3B4B0BDD55408C6ECA340E0E0EAFE8D4FBF91AA5A8C994403B9F8FC014E5985609C541FB84CC74158341FB37E946F4ED9C4D5B3BEF9CFAB4056EFE1D1A1F584378F1152554CEE569C069EFF5B516EE5F5D01AAB7D87B09D78F873FB5E7E9C0C9171EC2E888E049F48320E59E205A1DE4BDC1AC5CF00F3002F2F821C36825AAD699CAD564D85E0D19921BA8810B4AA66BBD4008E3D5B9ED5A847EBE708A41E7C270943754D1222E88AB886E4D840927A7EBD43BF7412EB56CE30D96F405A5404BDDB228050CCAF0E37B44BB3EE637785533746C08FE4821B0F92F9D4D822A71E4D1C0485A6B5505AC80D58C8CCCD1C3954AEFF1737669E7283353B9156455CB32F3B4C593FC64934B75EC804CEBEC3065532B84FE797D81CD5FD6F2A15634CDCAFF3E9F99D6C5228CE21612706133BF03C133C0FA94BB660807B3E8D53D98CED85C01D2E7D7891FD27CB839C4BF52F510BCF0E4D55B797B4B25F76FC3EF56FBD38379B988BB0FDE50D85223A603E47CCEDDDB48B505A39A30B33DAEC6C639D16C8677F71E753980F9BA7FBFFC3B3622085F51F2206742EBDC2663D8639DBD8DFBF6113FDFDA16250D622C93D8A92863524048C7B4C80D7AEE2E2CFA33447AFD2A689F7E046D40BCECE03C772E16A72B107819A9F7831F5C1E169A3CC5C73F545B310A3A2DEC2336605E3F6BA0802B5D860AF24B51978551214EEBC709CE7E34664876AA688A68441BEA899049030F2BE319D9DE4F247A66", + "k" : "374B2E1DF3E799C38FE03BFFBDC3A6F7E89237B420B179A65027AB7EA75E9A0B", +}, +{ + "rngSeed" : "F68FC0314DEA88F66AFAA76E6C9B6804B13D4876924410D1F526FAC59A62E26C560B125B1D0F8B461F1FC2E351EFFB4F", + "pk" : "66834AA6B266F0964EFA45C0469249C3FC0FAEEB19D1508CB7C409B49A7E38299920C3433DA3929B2552D5E9A1F092383E3B4D3D8A16FFD199F7D933EAA506062697C29B1FBF10292A4758D26AB61F085C31A0A3B85A19E956860F93A3ECE8A0C22426B40BC8D0C1191754803D0204FF048C07F6C778FC685B2108B0327DBA9361B00C071C8223AEF0949DDB804075C3A0178F41BCA68B676EC8469E417547617C8B8EBB6E19E83AF1BA27E2DB7D08E11F25805F959285ADD216C25A029684160A880FD2DC5753709EA3D81A59A91357205CF126C24F8858A3757BE1C562C65166A0800047949C062BCA79E03836D05AA6A91A30856A367B087B455169A7C3591091E72C96B7432397B6A257723508661349265C4C475EE7251E4CC26D739B33190CBB07A993E5B72288A55D5792CDD2C9177C9541F0A70BF066135E06A3FF1700AF24247AA61E70F4727E6A9FDAD70C470B671CA31A21D236BCFC508A833714182198C4C41BD1AEE23B5ACC9720A3E955ADB119E9E06FB6C8A7BA5A37BEA21565F77F7F037F0AD71D6AD13301A547FE8458C8363FEB218A3ED5BF594C3BDC7A03003641DA15479304810B5A0C949417B9A8473F76AE6C13144D7B3673074703DA0389E82AD34165F0C258457367B5521128EC318DF886EAA203E259BCA111B68E13AE684B1F1B3781D8305193E094C20B1E91B473AC9992D1E77DB85023CD043B147681FC9C2C9C2C1237C27F1E459B953CA0711A318A4B76D924BAEBF599D9EB852DCA1DC5F80191B91281F8345D774A29053513F159164A705C954E53EA26B6927DC57A0FAE5A19BD33BD67339E8EB925576A2EABDA6B0A4743ABE05545E080D5495402EB0629859671E130CD048235F254FFF49A7D394F3B1C3DE06A7847473119E218CF0944609958300B93046869C026CD93E21925A30DA0389E24BA6F08D498748730E2B40D1C73452DE8B7570027579C11A7417F2BBC67122C9286D1219D7230EE5B0C42D724D1B1CD4B031500958DC7124177A25651781657904FD1267F2BB69D5C929F8967CF216924D63696627C917F82BD2813563CC443705B0A1B279EAB237326B4CE45504EC710AB95D01AD812559B2B8BE763C1E9C55449A1366FA2CDB6D0106856B080A16D7E3700B0771A422423C806C62614B047820AD6876D7740B35FD674D99605FC61638D863CE5CC6A55D62F83A4A68AAC10AC065657870B5C623970DB1A40773500757178F29D54548AEFE92EAC306FA8F926E5F84B15F339F4FC388A554B79D87325C81F9E9989C690920F018FD4440AFCA405B1B667E489568121178CB7A18EE2C38E10AD4F5A09DF64A76C0BADFD08627861144F8A449DF4089A08C48CF1B110B443D16386042B6F24730C921643A6F8B7AEDB9A7036339F1B156C1C4DE7F4A03ACB57B1CCA827146F4BBC30F17A32DED42949CA5340B0494CD29098260A87BC7B50440DED82BEFAA1A6C4C28BCEBCBB16990978EA92A3709B817996F51A6E080578F2D060B924C5D9B93098725EEA946CEB84A0A884C7FAD252BFDA7AAF374E5FF8703941A8483493A5143E0F9B6F5EF45F683C2EA2C4B5E8B92A46984064B97E28D339789A8654E27E38C84ED7E4CB204412A434BAC227197528C6C6E1625DAB98C25557E16CB5B8249EBC11CAADE0B5FB505527D45981864D4ABC8E1060CD9A7467465064C9B8CCE823B6BDB9C702A7A30415B4FC6979D2476B4511909C90559F70597375C050189FF2932852A51E74A21B32C834C734052C61137025C20708263E0AA71D87B20263BACE0C0C98A58CDFCA4889672E6B654C003A7E22465F97021AC7C11FC4D1C0525CCAB768C6DBD124C8C533F49BA88629C71FD1CB6EBC4AAF09AB6DB011348B2B0691BCF8EB1BEA9588B640CF3FE97E35E92440284CC9607D49A3891283AC96C32A2A223D1C372B509B1D9401BA6BB13EBD5CCB6C44BA12E392B4D165C4940A714359CE122F6B34BC1344AF802992C6FA2D85F1957045BDBDA400B526B21BCA1A0CE181531C8BC644799EE8477AF16FBBFC33879868135A5ADC748F88799D23476AAB0643E5DAB979F3658CB1CF19292AC6F30A486353275CAE5FB941B2D49A0D0349E65917B4F4CDDB9A976F322D8917B70278AB9CB16EF193CC33B312E1689170532F31B001350225180493D7966E2B216C709AC1BEA73F1C624A081620B7981C1C95AE0387AEA62F", + "sk" : "F1594ECE355ED8872280F422ECD4B02C1C9FD2716CE375A9C01B172B3C735E4908DC96C1A58945E70813250A95C1D48F6BF159AAA265DA841DEDF23D0BC71809C6BF16856A0D316F59955DBBE18A39175295D5899B4ABAEEB6A7B3F9267426B6190C1F3C7372A0235A644B1DCB577065A6A2E6CB130F8150A8633CA8F388FF6935C2F3584508C0DA3898E5A1BE423506E612982D80179C4CC950AA35DF21244BBA78E2B24176769C934A020554AEF4D43CAFF4203ED5351BF822695814CC0BA1860A27031C0C9DE66CA3675ECFBB3AEA48496A2179E6124E755656F1412B04F2AAD353C93CB068910C0C73362183063A233183DB280174C0648C3422361954BE811651380AD3975305BC6E09B9736E911D6C55083F63347E2584E6A26BF3200C7CB9C1D71522FA87C684AC208A81B3F01298AB315773CA10D8243F465055D8489D5CE385E7C6C0B5CC741DF52B7E62CAF73509CCB814E9644F6C35BB394A4094745BA69B6B8F933B715581FDA1ABB0F8AC9EC15DED803A28E057E4D87BD7B9C53AF6B943A00E3F694810E3878E3359AB109245B29A962AC32D1A066872A6874A4E3A7235C5157250086D00610E21372218859F807207E20911826B1533C851024054441014BBD618E65056576AA6404A1499C92683872EAFB152FB2A171FF02F4F895F3A4B3D9BDC22A9627C6095957F86B41395B98B947E4611AE496844BA3083EB9228CC0277CD21C050F181D79BCB90416D4D5C5932F5643766A3DD1295CC2805721B58A0596A371CC1EB69C986C2B230F4AB6905468CE77916C816DF1B7668E6AC5AE2429CF56A9FA6A7327892556C58AB5B24BE7A9BEFF69AC35BA63A11C6DD15772B501DFBBC6D1437CB2EE29C98779131A56A28258B8DD6237629276894AF0B46AF6ED66C2B7272FB3BA9B936027B330E2F20B0813A240D27C7AE10778B0A0776E17751F85F410C373A6376670007D8EB78A7213A5EBB8A89D02CC902A62CA15F15709FEF9CAF5A558168B90FAE5B5F3909259184C20A0C37A0196A37B2232C34A32704301CFB56066CA60AA65A6A459689BAB328114E731650CC690B7F50814DA97DD2495302FCB61EE375AFA57EB06247277AB8AB96355AB42C87714EC6020FB6F95F05A02E679ABECE5069356C70D2444020521EAEB6376AF0630EDCBB1B655CEE8A734D577353D95E3F93BB7D703A6399050E12C1E41340807CC91E274970F27D7EC86C0E7B632190A65E886B52E02827795A8E3BA1ACA22C80E59765461B128543AE34965922876F2C418A47CDB447168160C12BB03E94FAB4FF012845E15BC17985A38C7F3C6B6AC365ADC1E8744B15334079BF0B081D3E2A9572119501892537BB0BE05249661A5700BBB268F153603AAE0850CDED06A4D7B548550797459141BECA50DC609110B22FBD61A2CE84C4D437663BE27CEE1B8F234B4E58BCB3D8B63295A5891EC1A63A933420A33EED084626F83DCCB82002D844A593B693190F4291372DD6428C7B90BF9A97019B7B1F9BAE23C87F152B6E514554CF6B9703604CBB2C864C94A024D54B7F3A2709AC878A8C2A9EA74C03F9A027D0B4973B062A45340EEB1B08AA2236B021F9FC56757237CC9411CDE098AADC935E52832D3A3101268CA57B566C1804EE9831863B2FABBB9497833C2D9097805B3D125C96C2EB3BC2612DF211829FC842EE6CA3770852BEB38D48399A195CB91FAB32E0B6752836CEDF05345FEC5143B28A5CE2A2510548CA95666C579F36E477E67A6AE6275AD32813A4F3795A602D24D6372EE039E50844CC000BE6609CF388686CFB1F6E775951A6A2626095B190191702114AD08193D714ABC32849A5A33858B1F951B09FB115F2F8481610CCA8BB14A10B54E8E364C471AE4E57037C3BAAFD9BA275F1A4BAA82C585279EB01403B2669DFD6B1735C5B7D85C5EFB3A1AD8C0E8D40198EA4B4B7D1427C39660C04635CE59619B5824C80B84164641AC45257817C0CB038B3047C30EC460298C75B73A2F7F0B82B6A6583391F58BA057A6581BADA84B5978888E15E9462952349961093354DFA34C0C08972B7571FD99197B13AA8B19A7F6920E5D41F50613A5C2A6036B79C0037113F41A3146AB6D7235185F51526F9B564462AD4C70F8F30346CE7282635783B9850EB9065CE58A272193166834AA6B266F0964EFA45C0469249C3FC0FAEEB19D1508CB7C409B49A7E38299920C3433DA3929B2552D5E9A1F092383E3B4D3D8A16FFD199F7D933EAA506062697C29B1FBF10292A4758D26AB61F085C31A0A3B85A19E956860F93A3ECE8A0C22426B40BC8D0C1191754803D0204FF048C07F6C778FC685B2108B0327DBA9361B00C071C8223AEF0949DDB804075C3A0178F41BCA68B676EC8469E417547617C8B8EBB6E19E83AF1BA27E2DB7D08E11F25805F959285ADD216C25A029684160A880FD2DC5753709EA3D81A59A91357205CF126C24F8858A3757BE1C562C65166A0800047949C062BCA79E03836D05AA6A91A30856A367B087B455169A7C3591091E72C96B7432397B6A257723508661349265C4C475EE7251E4CC26D739B33190CBB07A993E5B72288A55D5792CDD2C9177C9541F0A70BF066135E06A3FF1700AF24247AA61E70F4727E6A9FDAD70C470B671CA31A21D236BCFC508A833714182198C4C41BD1AEE23B5ACC9720A3E955ADB119E9E06FB6C8A7BA5A37BEA21565F77F7F037F0AD71D6AD13301A547FE8458C8363FEB218A3ED5BF594C3BDC7A03003641DA15479304810B5A0C949417B9A8473F76AE6C13144D7B3673074703DA0389E82AD34165F0C258457367B5521128EC318DF886EAA203E259BCA111B68E13AE684B1F1B3781D8305193E094C20B1E91B473AC9992D1E77DB85023CD043B147681FC9C2C9C2C1237C27F1E459B953CA0711A318A4B76D924BAEBF599D9EB852DCA1DC5F80191B91281F8345D774A29053513F159164A705C954E53EA26B6927DC57A0FAE5A19BD33BD67339E8EB925576A2EABDA6B0A4743ABE05545E080D5495402EB0629859671E130CD048235F254FFF49A7D394F3B1C3DE06A7847473119E218CF0944609958300B93046869C026CD93E21925A30DA0389E24BA6F08D498748730E2B40D1C73452DE8B7570027579C11A7417F2BBC67122C9286D1219D7230EE5B0C42D724D1B1CD4B031500958DC7124177A25651781657904FD1267F2BB69D5C929F8967CF216924D63696627C917F82BD2813563CC443705B0A1B279EAB237326B4CE45504EC710AB95D01AD812559B2B8BE763C1E9C55449A1366FA2CDB6D0106856B080A16D7E3700B0771A422423C806C62614B047820AD6876D7740B35FD674D99605FC61638D863CE5CC6A55D62F83A4A68AAC10AC065657870B5C623970DB1A40773500757178F29D54548AEFE92EAC306FA8F926E5F84B15F339F4FC388A554B79D87325C81F9E9989C690920F018FD4440AFCA405B1B667E489568121178CB7A18EE2C38E10AD4F5A09DF64A76C0BADFD08627861144F8A449DF4089A08C48CF1B110B443D16386042B6F24730C921643A6F8B7AEDB9A7036339F1B156C1C4DE7F4A03ACB57B1CCA827146F4BBC30F17A32DED42949CA5340B0494CD29098260A87BC7B50440DED82BEFAA1A6C4C28BCEBCBB16990978EA92A3709B817996F51A6E080578F2D060B924C5D9B93098725EEA946CEB84A0A884C7FAD252BFDA7AAF374E5FF8703941A8483493A5143E0F9B6F5EF45F683C2EA2C4B5E8B92A46984064B97E28D339789A8654E27E38C84ED7E4CB204412A434BAC227197528C6C6E1625DAB98C25557E16CB5B8249EBC11CAADE0B5FB505527D45981864D4ABC8E1060CD9A7467465064C9B8CCE823B6BDB9C702A7A30415B4FC6979D2476B4511909C90559F70597375C050189FF2932852A51E74A21B32C834C734052C61137025C20708263E0AA71D87B20263BACE0C0C98A58CDFCA4889672E6B654C003A7E22465F97021AC7C11FC4D1C0525CCAB768C6DBD124C8C533F49BA88629C71FD1CB6EBC4AAF09AB6DB011348B2B0691BCF8EB1BEA9588B640CF3FE97E35E92440284CC9607D49A3891283AC96C32A2A223D1C372B509B1D9401BA6BB13EBD5CCB6C44BA12E392B4D165C4940A714359CE122F6B34BC1344AF802992C6FA2D85F1957045BDBDA400B526B21BCA1A0CE181531C8BC644799EE8477AF16FBBFC33879868135A5ADC748F88799D23476AAB0643E5DAB979F3658CB1CF19292AC6F30A486353275CAE5FB941B2D49A0D0349E65917B4F4CDDB9A976F322D8917B70278AB9CB16EF193CC33B312E1689170532F31B001350225180493D7966E2B216C709AC1BEA73F1C624A081620B7981C1C95AE0387AEA62FECE8E4C1277C5B64512A4B2BB7CC80044F98E2B654E5BF0F4EA520CAAAE1F2EF7B2DAF2EA1F1011C4BD04208E9E90B9C2BBE2D8B96A1565CD1163966F5337E4A", + "ek" : "1E4B0A6C9F5A55178AFA1CF63EA60482DF31EBAD2A9693FBCA2C01F99074C6B98DB9C7DD66BD76265A60B85272C2932DD7C7E454CC824228DF98D8D24D71179364701C6134F2DDDDF388A8B7881A6FC65457D9C213D1A465E6C0A823764C5915BE5A2B724426F4CB253EA9A071C52DF7EB71A82E9513A8B850DEE7251654CB06F8A2775168C5AC8884B83D038796DA7B38C258C567290EFAF5EB9EFFFDCC2DB503BB1B0B7C6907C9C6C44CD41721998205A45C9ACB23B8535BB5315959632BBC19C4AA6BFEE072D2CA8AE2D6D78219FD67B04DD61E1F93EC29E25D9E0AD0ECA4D901AD41F179D70933741ECAC736C82A403088406A3B65030011C8AE5DE7C797B302BFB08A4940568DD0D0C9CB9C0275C884A21F88E61CC1C389CB92C7A286E27A9BCD1D6285C8A16DD089F51418B923246967101F85365D0272EB5690F74AB1D84672B5574628CADC7E6D137D4521F0D483246182DBE70F6EBFF092CEC4FE819BD73E248B69F6A21872020EFFBD5C85CBF5B55C7E099BE45C4225A0AE22363F5529E61928AFFDF26362541E1B06584C4DB2BC42D028E51765BCCD7E0790C83786AC5910DF034D6A763C1385EAF168442FAB117DF53D101D3A58F6ACA6D872E356F90EF8D1CA89CB750BC2140696E57CF73AA5716130BFA33D60E5B15F89C2711DDC6BBC196E5EF91B8A2A87DF238ADDA917CCEE8040E2EA0C4D851C327CC0B4E4D8FDF8E827D00FD019AD47DB6AC246D41B0114B34A792047151BCF3F53641006ACB28C19D86AB44CD8FFF36DC8BEF13D6BEDD8D830BACE1BB236F571069F8831CB0C324DBC6B3BBD363B79F9BDDA60B11A023B5A393EDA010A2C4C11BBBC4519EDBE1C20245B23CEB8793A4B74274C6EEDFD3EF8A21E677EC2107764DCD3B231FA4C97558313B47B6E3D0D85D004C64ED28014B4BAC0DFFB8AC9D7616762AD3AE7069ABED07E760FEDB2E067A2764B90D698851F09365C4EA9FF9C251F84D5CC756CEF9E2216E3D21C6F3C826A4FE14B2C3DFDF71F5E5262DF0C419D89A4699AF0759FF89422EB71931B6A71E14171095C1E8BE0A097ADB47C48D81281D49CA4483D162E4E7BD13F5BFD9F6A9BEA48540C48B67C2B7E44F1535CE8E39AE201BBAF25C679CD8370541993AB8C2BF22CF921C07DA4676DB4A31A7C9B456A9994911628C534B648321EED45F3964A63F62BE91586DCC0A0FFDBFF79150B3B96AB48FA4B7FCF03AC9C4119ADA6C1E6A53AD7DD79DB60D698C39768CD6A9F214D430C580517AA4F12B8355C18DB4D54D9D89FA8F13CC6FD0DA3661EB9F47482B2D6DC87A8DB6099E27E252011A788BD51E3C3B912898EF9063B5FA42CCE0AC7AA8E4DEDC0B4B0DCCC8F255BD8ADB7478B538E30B219FA96B674EA4E34CFC0975F08F5A9C1DF9FA1729AA77C754218338EE4872560DBF5737A2351848D79D1D6C2EF76DF119433CCF0DA872034FEF091EA94FC106319ACB7F5149A4B01CE85FF3FCB9DAB957D0D3D6A6F2B99341EA2C7AAB0C9F7C86597AA1987D9D46C890F27441DBEFD2006AC2B1ED96C978F4EC1C7149EA44437CF13E37EAA29D042DFB14BF46682D40E2C8798C4ADA0CAEA019A19D4213867574294E24D75BA43B3887402B36E7A7870705E3AADAD203A1680D3C3E3AA4C3618FACAC8DBFF4ABADB93EA6B0B8B3410F5CEDDB42715944DF942448FC1FBC656D7D5A3154D6733D4885F9DECB16F7604D6E5BCCAD033FC82796B0AA169B3014DC4A1B57AF6368982163343B16F589596077A750A51C6C7DAE27F0124170CC71B8B557B6E5D49F2C02F2E81AA9E1605E0E4212B95E52C8F8315DCA96130E9A1EEFAA83F0DE9930B64F46AB320BB8251BD3FD6A4B337DEBFB4893F197E7372C228ECFDE1B5C3D329907BA816606C9AA68F176FC59369FE3534802DB9E8107F42FA875FAB56C7AE3F1FD88CF6AC49216793C9C78E02ED18DDB8D6EECEF662B184C2901988CA0DD90A851BEA833F60D786934CF292CC60E86769711DB8C1B0CC19BE7D2068ED42650E502222EEA640F8E70323923D70D8D089C29C1AC0127A20FF0D9DDDABB3114270CEA9B85524736E14D6AD9EEC6F3BEA9A2DF8380A171F58CF4FBCC144E3F0638B63208FAD24D257C2F18B8F447CD6D9F752C0F6FF849BC37532EBCC44A140A057835451222501471C9FF37660BD7090F00083DE238B628DF45844B09B6189D0DE12089AC5EBDD26", + "k" : "9965786550601E122C4FCE15197A0F9FEF8B6AD7588AA570A42BC5C7F295636A", +}, +{ + "rngSeed" : "A229218B0D51F58D915DF549901548FB0722F352C7470900E7E4D8399205764A319BBDDBD06C00E8C5932722EE5A404D", + "pk" : "14830BE3EA225E8161039550C3C320E6C57220E076224AA8FD48B4DB59A30F71B2A2FBBEB05B3885819B672C48393C5FE1865A4C113B736505C1199B807C5E7669B7D2499931D899B21B8C1D9CAA129761BFA3974C4A85677A0EA1A49C4EE022CF3048012A3B108B4380F10AD2C327A009717A64704A62CB31446C5C810A5A9928E1E4564F95B027AC251C464569344F0086106F7A4DFAC13EB194ABBD64A8E7DB2352CC07EF52195DE869BDA087CF838FB42862F6346754F1744DE8A414464ECAAA921BF76A4EE344E3055CE0FAC32C15BC9FF3019C7B9205737426CC29239721ECF65DDC241F33DAC59DBA06DB577514891F70D020F5B240B03493ABA381F6716A16646A8A8343EFC41394A90CFC896DC04C4FBA8AAD7CD66005E426A3113DD1A4BE4A661EAC59CC2742A229C6BAB9BA26CFA9194AB41674E89A410BC7E8A25BC410BF95738F8420C64DE5715AE624368322EC4A513647CA86A231E76B62E52753C939308F8460A7650A28D258B24C4662793E2AD4454B5756E1692C6E6822A8DBC070EA81F4A85D6A2A852C452235F63816A08D957CBAB030C33B5535C87C5E7851C55503898F21138B61558B38B04CE78527658082308117978BCA146F8F338C4B4B623177A0B1A51B5F134BA58C19B4DB69182807F3BCB29838A0729CC2D34200379CBA1F751B6764C27D471FCF7A0B3F9A404FD3BF98150150B540D79B1DF00038CE770424838F58E10AECC304F29A9103177752520AE3D967BA33AC2526C85D9A7AEE03845B911F9C0A516F10A06A018AF24319385A81C153653FA81808A6BD74680F684A52B8A72BA5288B6E75BCA97A0304F2C3D8E940DBA7239869BF68C951ED8884DD32CDB254755098CEF7ABAADEC1A47A7A0FA646B1AE78AF8C608EE7535BC43371BF1206C8680634174426E062AD9C28F4474A01B6785DF35DF57014C3E8858C2A2ED9D911CDA8303C318BBDB13370B07BAD82ACBAD0BF04C3AD2C491328A20790C39292629152DC0E6A29199251B5BDC956A2C4272A4B894A87359A11803A8B67E236837D25A274C97EEBB6A8A9E7CE73CCA9DC91A1129236730786DE0A22286B71AFEA28E01ABDF69CBF460BA2D7D69143895630F526C5F2C6FE9A289A3A058D84B64228389C94984644BCA5FA1F61004A3EDCB94557093345991BCB9BDEA45915A5BB95618F4D62CCE22717A67C60042856FE8AB437066AAA733567694DCBD301307B4EB02CCE11124BCDE6A79819B95EA621F1B11492315E60F774BC5B207F42C178708B28A18C9883561CD66DAF17BC0BC42E0050B2A8157354F7945828A488A941363B3393A1112C691E123C6B5699A5C945038B6B2DD6725E7E619BEBF1C34C7C32245461D32525C5F49A763944CB64581CEA3A178146DC759C29C995CA0793DF62CB2153859A32905E785E8E6BA2B834918F2C2DC5CAB10F8B95867467ADC87111D7BEAF69099400AA4E908FE0A299E8901EF5F9346FB07BA287235087A1AEF51BC8933823D22B8A02C1FFFA56EA5B1DFB143EC1426F32959A4103B9E343108C87AAD2FC0BFC7384C0101AFCB4740F01B57B483C0300BABA66543ADCA822B4381E99870727A75C491A1129AF47D768E4F59FDF05C6F491AAA5DC11B9AC7E20E541AAEA11B6EC8B27E94189DC1BE939CEBFDA109CD53F38FCBBEE7AAD3C65A3C51AA3970CCB31695BBFBA3E3B10CDD0D37D848309EBEB3ED8601CA2D1479F3AA0F2766D24B0B0FEB01D34BC5627EA8DCBD935A2303BD6AA6D01E7605D23217B98B2CE8564CE077032ABC35AA6AFA046254D9A63BE6C4BDEBB95E0020AB5FB89AA5B01238047A3C183188BCEC1158C0CF901636B3A459A223A73986AFB886787CF93A8AABCD9AF1E4CC585CAC6F6F424131A9E01FB49BFB38EA664AD31DC16B2DC3C701753A2870CF9C27114262167763902B58B2F03BD906AAD3B0101B7898E2663BD458B5C4BB7C5F49C28FFFB97BB4393BA3AADA4C023E25427DD5016B089591277B13DD0C26AE3CCB06C088FAC04B475477DDC1BE06620CF3754548A6B2A551AA1B97DF5FAA296C6A6ECD052CDA5903533C93445778755876136C193FB0E3C937BF71AB2968A25E8D1C9E49A9962BA0C78951F64882C826016F63B97E6F8BA0242A45D69276FE0CE06F14BE7535859C87A9875904870890C5A620D8632F30F55D3CAE33D1C6F5896E6B12354A75C7894D8905403", + "sk" : "6CB427A837B55537299E1A8836B9C79AFAB583679FCD65663B17A3008200D9035FDBD50B99449FF6D14D5E0611BF21C652743D60268C89E0C75C5B4445707215A31593349A86960219F0CC079A2E39E221060AA5DC19861197049E817F692CA55E328AB0C32EC8FC5CD25A83311BB49EC8929455330764885C70C9D988A5DFABCB1366AC382B18BC866E5B93B780736558A0AFC0580C4AF75F6B6C63F95A454F0BB106627A2294AF45F02D948C1075618B8FB01228401B1FDC2B65B02B52F40452B86A1B235298B535B7990AB75565F66568BE06AEA98A6A1E4744C1728914D00CDF16CF3D940ADA784E14EAA332026C2F3CB05A7793C4239D5628281356170B181AA3AC98AF93193CB6A9BB6A682EA5073E11C5FA7558C9F713B98A424FF86D84FCB5238B8258076529311D3B522189B0A440B4194BD15344A5044216A524862ACD43223B51682DF641FF3876521CC9372C19ECF117D505B6E1B26A33BAC9B81C13B2900F11D849A0843A44C3061CC111C34ACEDB3B98A49874F4642DDBAC92D969597A635D64109BA5D55A20968B65072BA0BB4349046DC3C25CBE154790D3353E580C3855A755215AECD7B9C800AAF9D12816135F80F010C07824483C838C8176BB58CAE99817F1D2A538D694470021E3D87989F4B31E19539F1B60211022A3A74DF892A08DB12B03E3051D4B3BA9144926C1431A87CFD0F5702A7A127CC09B92F2A1D474B013CC9443F137E0BB1AAB721AD975C13BF69D6C5A2725A2B2AC88B80D7B8079B811E978CAEB96A89F97781DD7C422461D6A309ADD83CF83D563D2BB3D381A1DD4147943F76010D292F6703136D127840C9C4B532B86D46587EB54EA613E542645D1156F5B965C772905F90B3F518821A1B18961D61ACD7C0D3FD09DF90B9A1BF993282B7DE33A1ED638CC9A162FDE471971D2A5E946B70BCCAF00FB76C02A520343B24F1173D4D27E2AC574E1C123E7D663BC054CC432BF1ECCB0AC775377C65BBB2291C9695B55A2265F87323A7B63980AA0F1485775B2369EC3A3EB5A0FD126860AD14DB7928A9618C684C7790610C118A0AAB2B3ADCEB88B278A3FCEAC58DFC80BD9F2C7A2D55B35B82F18363A3E577737788DFBE0C6D995B3DA953A9BDCB46B1754E0A187F872C2AF0B0BFC70327646CA6778928F1005767A091E727D6F287A684199EB36A21B5A42D0C9775B9A2CF6D2BA31AC7677D075C9B207107C79A863C4EF47AA71A0CE5A409D6DE8B9549366273967A760101A67C3AACA617D49960FD658BBEAA371C172113B017E1445FA2096428074857142B07782924909C7097412280D45930561A80CC47720234C94CD682AD3C18572E5BECB8413B1868F7F3941E7256B01280330620056431911A638828162EBA4C7DF9C4C5C537B9738643E72B04F4C280048A4CF37BECB58A83CC0913EC58026B59135D15FE8950832CA27C1459CCE071FEEBA54106B89CEF37BDBF9515F25BF9DE37363D61AB5E02FB867BB86FA1F95B3638E105310258548A7986AD04A33A9745A71C41E783A3B86BBAD123A4B9971CF6755E7EA7DF2A5481D9973C079AE7801747FF8B03043944CCB8B3CC1320168566070BAB7E05BD98823220B17D8084DC77AB9ED4331DF4495003162C009B24735C736DCAC1836B8603C7893CAC54B922E50E64310196B08696B42FB8871B0991AD80977AA3DE41A25D6C918F2BC0F76B940A0BA85AF62C54A5B260807C5E76A062277A6D2A87E42E68E7F66B3C60936C207A57195CD0F4342BE7557CCA765094CB7D8CB0B03B134CCA0578CA61619D67F44B9A0C0843DAED00FEFA300C8678EBE8642046C454A34202A617BFCE69127F07C6987CCF09B1ED7E7C7B6F311293B575517C8CC720F8E2643C616269F6BC4ABDA117FDC031B93588B888833F0C791EB2862ABB733DC5691B670D041B171788C39D5B62AAB751B5361DDC4BA7A0A6690D2205C7CB2CBF65FFCEB0830383CBD134BB35175760350F5F9A4B4F67390E671BDEC8E3A61AF35C79C4D7C72FEB112AEBCBC22C074AE77B172E5B5DBD3374ACB2F031BB18C174B02755D8A53A882459695305D772176273B5300D02D7ED2A272F9C7BABB545A6C1AA25172F11096AF5398C9D6C4590730FF05C74C81308AE5315BA24B17FC738A30718AD046D0627E4B81B214830BE3EA225E8161039550C3C320E6C57220E076224AA8FD48B4DB59A30F71B2A2FBBEB05B3885819B672C48393C5FE1865A4C113B736505C1199B807C5E7669B7D2499931D899B21B8C1D9CAA129761BFA3974C4A85677A0EA1A49C4EE022CF3048012A3B108B4380F10AD2C327A009717A64704A62CB31446C5C810A5A9928E1E4564F95B027AC251C464569344F0086106F7A4DFAC13EB194ABBD64A8E7DB2352CC07EF52195DE869BDA087CF838FB42862F6346754F1744DE8A414464ECAAA921BF76A4EE344E3055CE0FAC32C15BC9FF3019C7B9205737426CC29239721ECF65DDC241F33DAC59DBA06DB577514891F70D020F5B240B03493ABA381F6716A16646A8A8343EFC41394A90CFC896DC04C4FBA8AAD7CD66005E426A3113DD1A4BE4A661EAC59CC2742A229C6BAB9BA26CFA9194AB41674E89A410BC7E8A25BC410BF95738F8420C64DE5715AE624368322EC4A513647CA86A231E76B62E52753C939308F8460A7650A28D258B24C4662793E2AD4454B5756E1692C6E6822A8DBC070EA81F4A85D6A2A852C452235F63816A08D957CBAB030C33B5535C87C5E7851C55503898F21138B61558B38B04CE78527658082308117978BCA146F8F338C4B4B623177A0B1A51B5F134BA58C19B4DB69182807F3BCB29838A0729CC2D34200379CBA1F751B6764C27D471FCF7A0B3F9A404FD3BF98150150B540D79B1DF00038CE770424838F58E10AECC304F29A9103177752520AE3D967BA33AC2526C85D9A7AEE03845B911F9C0A516F10A06A018AF24319385A81C153653FA81808A6BD74680F684A52B8A72BA5288B6E75BCA97A0304F2C3D8E940DBA7239869BF68C951ED8884DD32CDB254755098CEF7ABAADEC1A47A7A0FA646B1AE78AF8C608EE7535BC43371BF1206C8680634174426E062AD9C28F4474A01B6785DF35DF57014C3E8858C2A2ED9D911CDA8303C318BBDB13370B07BAD82ACBAD0BF04C3AD2C491328A20790C39292629152DC0E6A29199251B5BDC956A2C4272A4B894A87359A11803A8B67E236837D25A274C97EEBB6A8A9E7CE73CCA9DC91A1129236730786DE0A22286B71AFEA28E01ABDF69CBF460BA2D7D69143895630F526C5F2C6FE9A289A3A058D84B64228389C94984644BCA5FA1F61004A3EDCB94557093345991BCB9BDEA45915A5BB95618F4D62CCE22717A67C60042856FE8AB437066AAA733567694DCBD301307B4EB02CCE11124BCDE6A79819B95EA621F1B11492315E60F774BC5B207F42C178708B28A18C9883561CD66DAF17BC0BC42E0050B2A8157354F7945828A488A941363B3393A1112C691E123C6B5699A5C945038B6B2DD6725E7E619BEBF1C34C7C32245461D32525C5F49A763944CB64581CEA3A178146DC759C29C995CA0793DF62CB2153859A32905E785E8E6BA2B834918F2C2DC5CAB10F8B95867467ADC87111D7BEAF69099400AA4E908FE0A299E8901EF5F9346FB07BA287235087A1AEF51BC8933823D22B8A02C1FFFA56EA5B1DFB143EC1426F32959A4103B9E343108C87AAD2FC0BFC7384C0101AFCB4740F01B57B483C0300BABA66543ADCA822B4381E99870727A75C491A1129AF47D768E4F59FDF05C6F491AAA5DC11B9AC7E20E541AAEA11B6EC8B27E94189DC1BE939CEBFDA109CD53F38FCBBEE7AAD3C65A3C51AA3970CCB31695BBFBA3E3B10CDD0D37D848309EBEB3ED8601CA2D1479F3AA0F2766D24B0B0FEB01D34BC5627EA8DCBD935A2303BD6AA6D01E7605D23217B98B2CE8564CE077032ABC35AA6AFA046254D9A63BE6C4BDEBB95E0020AB5FB89AA5B01238047A3C183188BCEC1158C0CF901636B3A459A223A73986AFB886787CF93A8AABCD9AF1E4CC585CAC6F6F424131A9E01FB49BFB38EA664AD31DC16B2DC3C701753A2870CF9C27114262167763902B58B2F03BD906AAD3B0101B7898E2663BD458B5C4BB7C5F49C28FFFB97BB4393BA3AADA4C023E25427DD5016B089591277B13DD0C26AE3CCB06C088FAC04B475477DDC1BE06620CF3754548A6B2A551AA1B97DF5FAA296C6A6ECD052CDA5903533C93445778755876136C193FB0E3C937BF71AB2968A25E8D1C9E49A9962BA0C78951F64882C826016F63B97E6F8BA0242A45D69276FE0CE06F14BE7535859C87A9875904870890C5A620D8632F30F55D3CAE33D1C6F5896E6B12354A75C7894D8905403EF5C4F316E67AB8B72581B6EB228A8F357B716164E0388D504A7F1AAFBB06D485C2478CDC8D59AB164856623D53B9E60CF0AA8214CB64E674140BFD6DE9FDFAF", + "ek" : "3FD8B430361341F0C4A480A774391533E0E5EE66AE781DF52ABDAF33B05CAE6A22685F629B0079F3BD7E23F9111516F7458893DEB950CD4650969ACE0042A7E538C3C739410B218F741E3372938C8425B347DA44726C2E638D5B58E6C1D75A6754A2F5AA243E6C5E721CFE76A82390F34D350AD6FAC1689124A7367CEB9CA3F076671CA09FC74DA25BFA697A9BF4FEC776725C3113D809A13CA10B8EAE633BDE5ED8761B00886CA9FFA0771A21305698A0FDD846FFA59619201666AD17CEE35C7B6866943F9D93EA4F8A77F703C35326B6465FF984332B098899400FF3B865BE83AC90AB7B3AC2968995567FF6DD898681E6A636AC20041801BB02302E904A67C548F1543F9729BFC947B61693B7495DBF353384612EBE70988EBF7DC26A0036BF120E8D797EC8C048F990678B6C4FFF3A0CD4429064022682D5F318EEB0AE23A737347C145A81AE791677A38A2418DECC7E10A14698FC6D52E2B928F5041E576AC257EA0C79E26B19C1D2BAF50847A71DC8AE94467BBCA087B4F8CFD95EC035DAF17E78ADEE4EDFF576ED446CBB163E28A115A940995C56D78FCEBF3F8850F2F93CB3E88C972BCDD09ED9D31E73B6BA1E432F2060FF9E0394D4A185475AD0A2A69E29DD313385A5570A5CDBD396D58826C6C8ACC65B28A552EE936AF4E5274682F8A2F82CED49E5A27A9B04EE552C084FA67B3A8C67CCC45A024E271707E37F1170935DB2575EDE73E4E554D38531C4F6DDD8BCA44626749DE43E50FB8204B71EB7087D1CB071E0ADAA94B63B420C4FA4AEDE2DD3CAA6083AF7A7E08A8AF6ECFE3DAE3DBA24A5415B7291C15C0E4B241546C9E54E28FEF515ED24560FB6E64035D69A82A5890B32E4EE6737CC6294AA524361D9071668AD41F098FC5B3F282489F0267598A4B6DFD797E1149A4A02943C7D7DD2BB137A5DD51F6B62D7400C2262B4A1E74978DEA6E399E7EA966C668579481670C610F5224BF5A1C72A18EDFEEF6CE879466D39C865273BB20B247F952ABF476091BADDB41CAB79242EC8CAC8B31D034ECBB8E77689FE7D7E5F706D3B306BC20B18B97E414006435EEE23F28CC939566E64F5C0EA1753E3B2A9B615C534FB712B30ED32F0D2F84352D8D64BBCC54B6428C218785F76B51A71DA8BAECC477477E474B48E0F3887A06216A5748B0FD97594448E3427C843F99CBECDAF4B5C6EDAEEF09EDBE53DD69E545755DD4F1D15D7C592DD98A51DCC75280D1594F686EE11BFE833AC6B3BABD14EB4F109C86C032C806681E24D5EC2BB0EB3655AF10D80B2FA67A9247E82DEC17B6958D8CD27B8ACE3A9415DFA57FE110E6BF61090271C4135823D2F63DAB96D76C1CBC07ED24DAA0117FBEBE83436EC7BB74E5CD4F9FE1DE293C163263ECD2ECFCB6BAEE6F6A6AE644EC7A2AD326EF45F04E707F490E7B0946F10139727168DDF9B9330A8B9739EA931812782E6D4E54BB0D7CFE010E7FEA37C5E272C0ACF920ED983769AB49032CA6022B27FFC52EE199448ABABEA45182B65CAFA1E679FF6F715670F1387BF5936EB0F3C76EEA39E197E95C00059BEF67564AC9176EC91EC73CE48FD8D4965EB25343504A409C6E36776F5689F8C66C572B6204227440AED59B77DF27304D9A2A4D6307212AB10B95BB593AAAC063227CEE74B2AC6E61626EBCEEA36A90A6AA0FBA071377BAD22ADF030D1A8A91C18B3930F2FC08E2FF675D32B8AF3F07B8AD01E600788824E149DAE45F7AF7C05D1FE6737EB5A6411744303B30BD82E9F8CC99544EE3D61D4DF75C1BCD278C7D0B34A5C99E0538F5C6E4FC31E7CF60B7E70B1BDDF9FFC600DB3850E0A25047DAA30BD8B801497ADF068FCFAD0617735D26E0A18C7F2E646E7F34D829E3D75D479A3A6B8E9AA00A8C1999AD8F791707BC781B417D87244DFBBBD106D0231A4EDDECCCDA2D1C65C070F6074DC55F05B7D34811F54A17C7C8147FCDAA2052224851C202B56F619366E3FF4EBEC7855E698255915F6B88F37E911CC6BBBA00F7DE1538324863B71AF678C76854BFF7CC363A5B3EA0EE1116CF9CE03D144AD5690EEA0E8ED6FE6C7F7DD1693EFF90808F97ECCA2BF85F80BBABE968E12E9B5295F8BCCDD32604083C625C41D7CFEB72C8744E8A491C62AF6262DC837897AE899E3B5BEB12E6E164051F12FEBFA7B353757BC282CCCF111FF23F27674FE1EA0BCA61247F186A95BAD0BABFD8A0C60013AC5DC", + "k" : "60869C2F0ABB92D6FE8F457692A0980393EB38B39A2382ADF572E7F0A4DAB0DA", +}, +{ + "rngSeed" : "6960F21C7350DCF41B4770C551DC8692D8BA2C0B6E162C589166FF22E7A1AC0F94C2F48504A5F7EB0DA094DF427BC98A", + "pk" : "70EC588F847CA3EA21787531444355E26000209110BE1B6994C3003332B95B6AA30F8A0D047CB6A2D9CFAE2977E08962B656255637405057C233388E018753FEC08442A6603878A6D4F8CBB2574B9DCA1C32DC0964E82606739DDEB92402619649BC143950B753993E48DA443B1BBC8C3A0E2EDAA2710A541EA6AE48022AE1F48AF844C2B32707733916C259AB588241EE58ACA3538A0BD79FBF3589EDA9AB08906D77778649F0A2B2A7898A651BAE7013F8B863112C4AE2830A43AC421434236151B2AA7A5B3BE77D4C85C89E3140F52804CA470AA2B929E8E8BF9B4278BE1657CE321572D2196C4BB158EA891E627861DBC811525CB5F07A3377BE081B4651EBA3C311BB1C0357BF7A7923A524F003B02EBC030400B4B1E1711EF633B8921C101BCABCE37655E8C651CC9458110E68566D0871659C3072C509538C5A6174063469A25C4134BAA4F136E71464179B004FD361CB2B19D955376D137284039A6820211AA578189765F15A47E4B52D4AF9447C4A8343F84EDFE7AE76901D871B0A0D72414C4B01F35A38FE35A268848E663263439B4DFB9B3435537F54BB1E2B132528FA5942DA8563554276D466E97A25CEA6C7841729CAC824DC3CCEFA91C7D0A377F45B10B8F8CF78D00657F90E114363644869612BCA78E402C8E2A6EE1910E07B72AD43B44EDAC06EC2CB3C448B506CB0A09746CCD84B3B993213B7A76DD681D6E7B7E9916276172D15538209B01BA5149BB0AAA55CBB04AC89674700544EC7079A8277A3DBC298034E08716849C0542DC42B7E32319B0B7EFB43CB57F951B4912AF0141965FA6E1701CC53D08C1887BB31FC93399823F1371712785CE6CB549B91099A2245DFD350C374943EE6826CD3C9BED72E7012028B938BD304BA0F5255CA664389335962F35BDF253E2B3933689070145462F245696E4B1D852BAB0C817193679229EC684979C8F17965F4411FC1382309C28E98C095F663B587E967EF6320A84A474ED415E64381FF341DAF491A9BD872A019A112A2CEEA76661015B54181B8C325977B50993A5C26A7D992CF519D64F0A013F517664268D415A9C7F178C047A684495464332FD89071DA200C2D70BA68C68425B815772B349CF4ACE5DC1437BBB21E3283D2623CB58680FB1084E50685B99224F8C91D167590D4B03FD9A62D54695345217FB08658F1F6C25D0652CBC8CDD858AC9AD44616A8BE03E06E14288C1AB27E4D3C15B156732D246EF8492EFD508B41E6438C1C899B339874792F2BFAA1B8E55DC2740B02D23E8DA9C0A1B91C61DB66C92CB8BB3C64CC68BF4AF341892441085A96F3AAA1A2217BF6C005A3938C2C61A15A701E090C84D93628E7CB6BB0E49C170079DF1C0E364A4AD3622033B762593586549C79B764710B2107BD0C0ACF106C7F7BA9ACCCCC6DDB15D2B68A9FE7A2E8820EE9ACBFDEF8C139BC8B5EF47FD18626285409A59479D517714637B9D75AABAE29CBF3418BD56154FAE5195372299942271B0C90F0BB7F0C2537DF6A433A2350127A24AA144D30B95FAAFB39F566651CC1BF205814027477C46B7FF1B66837C657AF9CB0E7F46A42B4A74A69C36E716E2E993AD3C574AAEC31A8FA5A950A8CE7823A7E032CB4930C95D8483AA102D1B20926A6A324B9062B29192431BCD61AA56488BE8B9491EA373FDD276BF986AC01E6A9683785D3384ACCE6297DA89657C005AC086687161BC21A18D6D325FEF6059FF711A60782263A5DD87552F3B6691708A60459A81321CAEBBA42FAAA5593982AD4E0956AA42BB03867664470C8459A511026C2B8791A37278FAA906B288DAC6A1B7AA9588AE9062A31823076864800B08396AA90AB0A48A9798A146A8E77B104125AB1F1B5448CAFBDC749FF085F06B02A2C25174F587F6C2583CB0384C521990B6C15CD926B40712BC503471D4B807F85B7BAA361138312F1C62D62431297A451957375607BCEB0009D09BA904A864BE363BD220CAB37D13A77DAA42454B867307ED7C2A956D41A62B996E0E78C34B4AC0E7AAFF8D8164B4A11F8AA4379FBBB34F14E9FE13A7F4AB0025586F130914C6183719A941B0338E1E11AA3F167A421BFA38C9142E02316D1BA4E64C60320C0A190CEC011304F0BC58AF38E492937BBD0AD3A5A904FB39CE365A13DC902166C864A972082FD9E2EA5548A3B6C7D885A3CA6AE2E12EFC2EA3EE4CA0B0B171EE93A198B42", + "sk" : "342C2896A97CD8D63C24504629C1555870AA71FA19B668A558E2BCEE667A6B61463DC46547419DC8C458B24B5F463CA8399337782B02DF7704E53BC2F2D49F2DDBAC73DC3C84728738A29E6F1A906229A05BFC4673C87A2D2B0894A67C549B6631A925C562258EDB258524152B7816A9310D99883F4A583DF4E582FF16ACD9846B04A957BC54665F86C237BCB092A505FB089A8F76B865C130C001529AB53FA3B61F45376561A781C6EC75D0810CCDF44DCB0055BC70BF98F9940B000212215040CC08B31B90A395ACF312A9FEA3ADFBFCA17D309EE84B25BAD086EF669986C4BBF1AA6F694BB74A760CD235650E5927184BA6E4E918A1FAC482109767D2289DC16277468BA17031772868EB6749175C9A2755C18D67A0F6658FB6B5A27374BA2914680D730372E725181A6292DB0D1C719501257B0F33A152DC077188673FBACE2AE568BC1A890FDA174EDB4A1C10B825B85A78B26563B9429FC7CAAA116BF5D808427C0BFF488EA615017CE73008E9CEA01747B73733E91CCDFB5C88611A94642B661D1A41A943BF065733FE2449EE68B4537CBC86871E1268CCA564B5E952188E90AAE25988F79BB706706AADE42ADD2C1B2951B84D040E097B85D78C3C5B10C595879784B71638B2C70C390AD308A311A337413A20857A216D31134E2429CEE72BE2268CC38AC8617B7D45D2651EFC06C3B1C1D0C44531F5523A707D0802251576AC2D6A91B463A68348A2673A2F74CC7C20A79B73BB1916637830C91E701BB200166D2A63A21B5B8E52C7ACDA296D80D6C897C86334D8424F44677E9246FFA32C5C1754B632692AF6BFFD05458D131C41275161CC50A51AB2570746048B455420053193B6F1C0AE02F83ECF364E50A6694285523C5372A84B6345F484D0B2C8156C05E9F3C6B661BF1CDC5573082313C5C05C648BE94B7B83B68AD93019B8469DC93A51E9F47A532A15D9140BB56878984877311A8C303B7C2CB9B62CB34C1F70CDDE82C9D9E76C5037C46E6196903B1A372860110A721FBBC844963F287909E2E093C4B89358160BD6CA892B95A910565FB67B640A803A4EB7C08109CBD235B773F91CF54842352B4A7677BC310563E5FA320FDAB95517C61952B5687379C6E229F4D296BEC53CFAF346D0050EA6465040FA11D5F04E997932B9201A117B3D552BB853161DE6F6AE5669AE9CFBB36C00BA54052E5A70071398B0F1858EE5E3A6740A7B93A453AF91550E7CAE362532D59490D70CCFC9997DA3519638302BE5C01CBDFCAC7B32A984049426ACC67F12283598588D68A46C1720445B6602E4B60DF0864AD3760892403B575E61120863F03D0D67551103D02A8386B1ABCBD2B6307B42A62103A6E970CC0A021E5FD54B659B6C0FB8641C6C74C12873F5348C3FDA18EE264AF681316AF0C55CC2BC91D767344C7046C0455B36B673591942A622FD122FD6505FFB4A3FE61B0B0BF1BF0C539EFDABA1ACA1BAA254A788F821502B06DB752F702C15227C4A60FC09BB28C3D2165C95171C20EA6E8526CACE1C239DA3705844C860C35D6DEA477AA1339813A9F2D755A21B143724621421ABF6D5AAE62C591BE72A8E817603D942A35C9E7A391BAB514E88C1B54D9830EF7C490644287594C834D898A50C2F6E18575454733D40CE0BF20033BABB661C84D9040A12E4881E9947BA4023B0EAA86F9984F4158D825BCDBD888E7AE6084E3B2F49498FCEA10F1DB637C82287E6F8CD553CAF40B7BB00236450243EB7349958286F380BC456B7208922A5D8887A075ACC0C29B231C51CF9839E1FAC91E3D0631B865BCEF168E71A4A53921C5CD9AA758175C8B94A2BE1AF094C5A5C518BA3C7AD0A0CC105126217F04A49C674B7FC3E6A9BAE73778C02320512D1AD3B7B2508590DD544B03D2C21D0549EB5A146D87C3897A5525DF8735079970AFC8B58F419BAB8B3B513844CD08164A2882518CEB79ABF6AE8CCE5618AFAA228DB659A6AE16B82E351ED4646F2A3CBE1AC1DC0B6A0838532A0B2AEAD760AC43A7EAA290D991A172E4A1FE1E860BDC50B51E58D18272A942A9045358FAF279A916663CDB431BF81CB30777CF105A032108769475F84C74B20668A991B53541A45061236C232CC85A56292EA7D470B00B4B128E45586E1531C02F364CEEB86E4B22FE6D4A049399C70EC588F847CA3EA21787531444355E26000209110BE1B6994C3003332B95B6AA30F8A0D047CB6A2D9CFAE2977E08962B656255637405057C233388E018753FEC08442A6603878A6D4F8CBB2574B9DCA1C32DC0964E82606739DDEB92402619649BC143950B753993E48DA443B1BBC8C3A0E2EDAA2710A541EA6AE48022AE1F48AF844C2B32707733916C259AB588241EE58ACA3538A0BD79FBF3589EDA9AB08906D77778649F0A2B2A7898A651BAE7013F8B863112C4AE2830A43AC421434236151B2AA7A5B3BE77D4C85C89E3140F52804CA470AA2B929E8E8BF9B4278BE1657CE321572D2196C4BB158EA891E627861DBC811525CB5F07A3377BE081B4651EBA3C311BB1C0357BF7A7923A524F003B02EBC030400B4B1E1711EF633B8921C101BCABCE37655E8C651CC9458110E68566D0871659C3072C509538C5A6174063469A25C4134BAA4F136E71464179B004FD361CB2B19D955376D137284039A6820211AA578189765F15A47E4B52D4AF9447C4A8343F84EDFE7AE76901D871B0A0D72414C4B01F35A38FE35A268848E663263439B4DFB9B3435537F54BB1E2B132528FA5942DA8563554276D466E97A25CEA6C7841729CAC824DC3CCEFA91C7D0A377F45B10B8F8CF78D00657F90E114363644869612BCA78E402C8E2A6EE1910E07B72AD43B44EDAC06EC2CB3C448B506CB0A09746CCD84B3B993213B7A76DD681D6E7B7E9916276172D15538209B01BA5149BB0AAA55CBB04AC89674700544EC7079A8277A3DBC298034E08716849C0542DC42B7E32319B0B7EFB43CB57F951B4912AF0141965FA6E1701CC53D08C1887BB31FC93399823F1371712785CE6CB549B91099A2245DFD350C374943EE6826CD3C9BED72E7012028B938BD304BA0F5255CA664389335962F35BDF253E2B3933689070145462F245696E4B1D852BAB0C817193679229EC684979C8F17965F4411FC1382309C28E98C095F663B587E967EF6320A84A474ED415E64381FF341DAF491A9BD872A019A112A2CEEA76661015B54181B8C325977B50993A5C26A7D992CF519D64F0A013F517664268D415A9C7F178C047A684495464332FD89071DA200C2D70BA68C68425B815772B349CF4ACE5DC1437BBB21E3283D2623CB58680FB1084E50685B99224F8C91D167590D4B03FD9A62D54695345217FB08658F1F6C25D0652CBC8CDD858AC9AD44616A8BE03E06E14288C1AB27E4D3C15B156732D246EF8492EFD508B41E6438C1C899B339874792F2BFAA1B8E55DC2740B02D23E8DA9C0A1B91C61DB66C92CB8BB3C64CC68BF4AF341892441085A96F3AAA1A2217BF6C005A3938C2C61A15A701E090C84D93628E7CB6BB0E49C170079DF1C0E364A4AD3622033B762593586549C79B764710B2107BD0C0ACF106C7F7BA9ACCCCC6DDB15D2B68A9FE7A2E8820EE9ACBFDEF8C139BC8B5EF47FD18626285409A59479D517714637B9D75AABAE29CBF3418BD56154FAE5195372299942271B0C90F0BB7F0C2537DF6A433A2350127A24AA144D30B95FAAFB39F566651CC1BF205814027477C46B7FF1B66837C657AF9CB0E7F46A42B4A74A69C36E716E2E993AD3C574AAEC31A8FA5A950A8CE7823A7E032CB4930C95D8483AA102D1B20926A6A324B9062B29192431BCD61AA56488BE8B9491EA373FDD276BF986AC01E6A9683785D3384ACCE6297DA89657C005AC086687161BC21A18D6D325FEF6059FF711A60782263A5DD87552F3B6691708A60459A81321CAEBBA42FAAA5593982AD4E0956AA42BB03867664470C8459A511026C2B8791A37278FAA906B288DAC6A1B7AA9588AE9062A31823076864800B08396AA90AB0A48A9798A146A8E77B104125AB1F1B5448CAFBDC749FF085F06B02A2C25174F587F6C2583CB0384C521990B6C15CD926B40712BC503471D4B807F85B7BAA361138312F1C62D62431297A451957375607BCEB0009D09BA904A864BE363BD220CAB37D13A77DAA42454B867307ED7C2A956D41A62B996E0E78C34B4AC0E7AAFF8D8164B4A11F8AA4379FBBB34F14E9FE13A7F4AB0025586F130914C6183719A941B0338E1E11AA3F167A421BFA38C9142E02316D1BA4E64C60320C0A190CEC011304F0BC58AF38E492937BBD0AD3A5A904FB39CE365A13DC902166C864A972082FD9E2EA5548A3B6C7D885A3CA6AE2E12EFC2EA3EE4CA0B0B171EE93A198B42191FC1297D126AE957EC70B3E5CC940F2649F5A8CEE53A1FEB5E68E08AEADDDC88E66590B5B102B223291CC78119BB94E799E37B95B7BEF0337E6A572284B9FB", + "ek" : "940BC5079C1381D7AB7C98FBB3B9001C91680E9B08EBA382C0CAEBD7FD01CE86CFA39555DB47F9042013C7CECE7FDBCE5C4454466615C9A0E413F5BBF161799CA913346F9B2D10E4A7CA3449741ABCB9B30D90508DD8B7F65719241BD6F7841536E91B64CA42A5AC0AA699C92B041816FFB09858D4D997729D78A48811CB28A096A7E901D8F6FD1550095A696D7DD53FC0108B59EFF7C72575DFC908F63F3CA6DA8BAC8A0E446FD828BF6FEE77B54D9F581F1BEFEB99EDD40ED5CCC0EA5823C93F1850B931E4473A48503105D8BCDD8AFC157933C0D1B64662E3E584EEC2CDFC46A64C20EDFDE418ED0AE6B935B678D4A7398C97C9471A422F3C2474D190414B226AB7F15861596407AD140C199DCD1F8C7768FE7C5ABD4413910B63CB57212BD74AE09C8F7EE277D516EF1282741E4C3251840AF24512B4CC1615E0CEE81FC526B2EE9FC7AA2AB375D0F6F8E8C4B04C627D119809C10CAF9653DAE58B2751FAF99F9A90A087E2539B568EC77EDCD008227B6A1061934B9C7415AC98F664DA4889C87D41820B2522F94113F4993F071C020DAF4DE1ECE55BDC524762FE80BF1C3B06FB69CB60697E90E44EED96B9B1DA8EEB60838D04222DD2DFB40D2073AE642B8ECDC563ADFB6411FE697CBC9594EE841987AB01C98685BAC6A2F40A1330C6CC3A60A47AA4DB605FEFFAA203E85A785421DDABD989A0AC20F8FF4F4B4666CCA7FDC29200767E1ADCD48792186C415675B26BB0423BB22F7CCB053AF44ED03726A14754475D981B1D76D0196B29E230FE2C32084BE4CC093DE49501986DF2AC5009521175ADCED5444DE867F4242905D4E215F7DF55E5A2EC2E86BEA8C2C11B643FDE24498920091877D00C4DED51AE8D575044B637DABBB04E7B8C3B784459759B68ADCF51B65548BA08C354F71B56CC0483CA1F66C2E35981A288378C780D28D8A06BB61C056D071985E044F06C77BF56345B1C0091A105B79960C2C195ABE82B33E496D6DBD67F3BA5E12851E112016B850FB6AD531C379C035B9EC94664D2108A6B07D05317B8ABA8928252D0F463CD7E79D8E6D3F7633CED5D97CF342BFC213F45CD97643243FC2456E4022AA7307ED22967344E46ED1951D063B1A776C9F210B19C64252E7A1BEB25589ADED1D17A3806D2B1A9588F3ADF5DE3DAC27CBE0C32D3B50A07DAEEBF3D87613219102BC0F39F26C6EF07456E499D70383C99741D31D306B5B35CD0E66D3E967349260081D0FBD7E25D1C7C0BF2CD056D6889322A16908FD15B6454CBC89F3D02448693E913C9607737C8F161BE2CB663B7E091BAF0938F90416F31960B8BDCF174B98434C6D6BF48AB06A54BEF3EB0B63594B5881BC0E87CAE6AAB0FA802BBA133D4E1D8E15ABC03FE39DB637C6AC0C0D68A03419B5BBAE32C78B45A348F099E62FAAC35C2E35C139CEC489DF74154B441DB7F863425995AAED5C6F2D61B1BBFF8CF844EFF02319853C69384637207B4542958DB7AF83B6D3AD4FCF14B209C94CF924CFA066087891FF238CC003958E878B8461B822F21DE990D1BCAC3BA82101CEB6DBC5FB0DED219C7ED5151673E3E3A79863F6DE0532808864EE62E1F1B5DE94442289E88535984697C46A00B76CA6D59C4A1CE9CED38AA64022FDD5F073BC931039ECE9430536D2DA86E812588F6C67E213E3CCCDAF7C7461075C08DE13FE2DEFC5951957C162520972C66104B2E7703D8F13D760C873F4C49BE5564609A729673FA0377296D61F440780B87BF107791CC1053C32DC34C40359BD1720933DFFCF8373D125122ECFE14B879A2C8A4493ED6A9BC3017C51B728391E0F471F53CB7AB96E5F52B280A2F23D0FD66EA5EC7AF73B3DF62A28C0C47EB63AC1A7B3DCAC662CCF53A59D5B14CCA8845C0585CF434239A5B36D5B851B57382596F5F43CE93C24495EFA1B438F6E88F190ADBA6840B4FFAFBF574B2C43D86E77B49FC95D840D72E4A24CEF61319C7C5D57524DBA01B20397BD551B162D54756B5D069DB21E0A4E41C29E7187BDF2CDFF996B9DF027C407FF6948653B4E98F10D56523E8811E0E72D0D94F52B4D933791AD0C5D6A884FB7D67B3024C77DC9BF51BD684F2EAAE3285D75E14CAEF1412AD420D023A25FC8DA93C5C09B316169AF366D8C14AD5FFEEC4CEC1980F866E23001DF70EE9577B7D31053302A0B7BE9E20EFFB0397684839F8405C685458D01454D59A4EDA88F3", + "k" : "D91936ED02B30EFDCAC64FFB7B065505661C842DAACC1F1B7CAA454564BA5B17", +}, +{ + "rngSeed" : "53DF46012CAD4A745B7A3C06E18CA95E0B839FD8161E3025749A0887549EB0ED6A44EEEA08BD6060D6509DBF7E9DC864", + "pk" : "D0947B8B21912D062783FB94B458013F34480BA83178C87D9CA4575AC9014AB22A7CB92B1BF41ECF098F735B3401E31BC02A43C447220DA64CE22B17408AC536135641100D1EA581A14818EAA4C77B229B31511E0A403229889FCBA0A2D4D3C845868816B79F56D6265D678C9138B716213FCFD7ACB2C68F4FAC7914D140CD2A7487B34146708115689407A9BFD24216F563A6FD220893C1C5E2C657031B43A29B19471B084485B7F739AF017459AE50423518460266CF449B524406B9A2B80A77093AFB1344BC1521E0220C5A113CC0C4A4321A77204521E3C758927C83398AA1F4BC43AC61487E7158AB4053FCE98A74B14632054D3D3AAF018CBAAD771326B7160247CC10A114434087FAF515C7A39B0705BC374B7AF73C5B60741E037BC69B10949DB1739AD74A240C2191B3201A020F43890CB16390D6C27C39D40AF0043B57E8A0F978627FE1B36C6C83FC97B49AE9268618B2C96A7A3612002B2673BC1AC762A37E07FC6EF3749009876399862D67B5B48571CAF8B326A4A80B4544C03BA811B3501518D5CAA107BE696CBDAAE79CAA0191F5678FBE14934609AEB501BDB0A525ADA654D77CB3042159686381E3677EDBAB5F7DD87FE1C4566DD7382F03C2ACBCCB14182B9A65AFC0AAC41F4C3095675A316159B0B7271F0284E160190DE000FE4076B6E3073D302A51C7A6F6486C52C97446B506DD7C76EBF08A5F8C70E6E8479735C2AE79A6D4A99444A347BA838C43A1ACE485A005A7531916C45181157C955817C488CCAB9AA4D55DD79A5E243504A74405A8A4AC01CB1B9F2917FDAB3B2909CA609739859383D631B65965AFFB4490D5B9BE84A2902CB34CC50B5C49CBCE43F8351A68B3476387BF87A16B9784A0E801E1EB39EE33B8B9CA82BEF596605B59F33035A05A012D8549F0B68C93B784C7A309DD71425D3175BA50107D28AA8DD42369BCC68A8AA074020B4B21C3D537CA25B82A50DC875AB76B35A982B0792FD84B60E7DB48FA0B80CDB90E1A95038842404A78C17D6C73E42951ECF2160DB816CB7323CFC0B8B0057E6E66A36A856EAA60735433BC1680636D137B8DA85F19334BD0EC9617D8B484986AF31BBAF7E81A050C5B4DD9356563BD2F874B6B82A6E8B088B2CA59EF3866FDD4217EFBC5DD66C72B66137AE65E7DC5C541C42A5C4CC1C1F1B678B7941D37AB5BD7292C665EA89B9679C5A6F8248F9FC61C2AF282EC048BEA74CCCEFC2077F370D3979B83E2A65D64BE85742BB9B66308FCAFC84038E72950E968B33FD98DA2750484F1138AACC0E5E8607E352804316B26111C5A242C09901339FCB7D304C749D9205F169D2663A03BBC82658A0CA3025EC4D0A1E445BE8FE3A72C672333188ABC3010B6A98EC0F01D698B87F195B2E398CA6F8038EF0739AF347B22076A58391C46573B0F782444464D9EA0645B4CC6F7136927C34E51FBA618B082F826B29FABB8BCE80BB0F05524348104EB4732E0AB4F4040E104B78AB9317B558330D4995168752EE23455EBA2CC4CB679687BE93860CCD1848BAC42616893E6E710645B354A657E4F064E2D3266F89BACB8585E6D927259723E7D321AADBCBF9638B1BCF917E3C203FD06145FEC0BE1059C4A52AD751986D0F0BBB46BCCCD365AD6B614DFB87DD7F97CCD731F4F9B280CD321D7D7679743833823AA5A05B1B3D0263858CB2EC27677DA6928B26D3459573E25B0CA4964D6798CF250860D055418761D7FF0189223A1D3EB6DDAB21572B58F0F5AB03A1BC047D7928C060844160E169B2CE072A89FCA5B384B81B89B24741674FF5223D4116ADA77797234AD3CBB1F6A78CC33E27B03EBB0D5A18427F625A4311A9599AE8723BACF392B7C915AA731C943F49C24F189055143502CB35318432C8B89BD2B9243F35C4B443AD48126207559A2314A77BC67C4D79A3E010FA1686761509E6774BC2DF86EEC6C5E3CD547F9A5457FB4A984590E57CCBBEF3B38E441235D90BB60A24A691425CD65BB43B5868D128E3428B446409804A25333A7AD1F5C6D712169F660798DE5A448AA393B5C496DB978934C6EB001112440784DB13825167A33206F76B05EAAAB0B89966150238748C492379B387EC863FDA621ADA4296FE16593358CA0AB83C15225DD26691DA0B00554C2398A2C44F171BFE63D48DB72EE6CF36F47DD054B8F7BEC5A4BBB6B0D62BCD24A3B8A6D32C53A51BFB7C57ECF", + "sk" : "E6D51F1FF8939A52842F092D10A9CD02FA1B7840147F3A5417DA6994E7663B536D253B627094B87D951583C61B8ED8A15295276DF7B080C71A6B2A4FB93B29512977F02C7F8DC36EEB2644F4DB64A60BA2083B984A010E0029616295835118CE0382144701CFE9D5A02BEA7FC8BA9EA074C15CBA8F2A77062270B9818AB99D856E3C4C104A66441ECA4D7FC74B148A37A5EB7103F021C955826048A1AB6A4C3619C1A2884FBF4495B1469E33671C845A40314CA87C4BC87E8C8BAB04A1B9B237413242A83CC41517C11D50B7124A730D7B54A68282E2CBBAEBA0896B2453568C22B3E779899A5E8850424FA2B68AF95381CC5ADE59B54D6A1BF2F1B16EE59375A314F811A716239085A77BC4E29506589A420A6C09C2206CC1AA97F2AAD03657EB967C1AB8BB73A87A4853035D77285C29C788885BF1108FAFB517E5BC1F13F89CD5CA97D70C12B5F64B88376466230439026D73A3AA9D11B03DB22E541C28E32C22A2976B23508717379DED0989E2345CB5F0C7D9C97A81BA09514B0D27598554189F7E8B6E977A5D3588C979AAC19EE60C4F64CE5CE73B437C0C1D11577D539AF94158B946918085C689DCB227D72240A843B2BC4979F5CFDC2791EEC3BD168593BA7B1EB06B829844B9861387AF68B466498C84E8AA31FA39488CC676F728ED106AA9E368459028FFF42AFF418320498FC283B8CE860FD1C02AD1C0A7D0D92D61B6AAD6D1B939AB0396983693353F23507335AC5FCE277DF06559DD3A6961CC43247CB0F9E7269C438AB4E14EBC0AC2907BB1289741B211CF40A15DED58B8D18C4948294B774C6EDB047114991981FB612C5A196354BB80A2BF6EFB713AEB72D5F434F9C46D14DC461507AE5BACC7C04789C1DCACE8904CAD02401ADA53489A04FA2140D1864C76FB91777BB9900B010D7A6F2D09868504823D83C5E881AA7B5B408F144E01F2A83DE212A7D3188C845539BC6B061C2F72B5C771F8B7377C678CE473DDB25B33518CFCB71A18455ACDB02CE73433961A98D840C6BF844014C7C89CCA5EA58A6291391FF6C0135E11911B6895557193DFB84A97E4B8F1EBAE016947A70B8B08E5C578591F0874C6A2B7B900A490D240AD36BC745C113778EC3777C3220CB19FB49634CB200FB1F67E5DECAFD84100544C86EE79C000169CD908A884344ED2F40862558819458D5F87C4F3714FE0925538F002A7D454C2F438A3C751A1FBB13F77C85C612E16C0CB979249518B82B85586DF793DB403CA55709E1E6030356048B458A492EC56E0B08C661C5BA04B805CC631B12A741216448E22A22DB406C04935F7C6CBA44C213968A5FB6CA9066C88F70900411A43E8651641197FCEF47470299C51473F158175E2E7857716BA80F501E156525CE0BD05CB3327673385095D144562DC4B006C89B0C6AAA2E21CCC79C0A7F3B0AAE77142A447454B65694C6A5EAF3A7761B860189846A8612B89FA5ED5715C8EB3042890C52326AF5EDB7DE3B578DCCC61283474BB8966B187ACEBB9BCE0A08031E66CEC0BC57FA368AF2574E7397A1177828D4326A66A8093415872537099D77EB83B9CBB516F40D235C0831B3FF663D3F3A9DB6C0CB5106C905CB55DB0721E45A7EBB676DEF137A585CCF493002055536C3AB49A17A68783290FC9366923654E310B17C2551816A9196497EE62ADE56B24A2B421CE48A583D46F3192BC09493ED47502B75580BE01CC94CB4893F32FD6266FDAF865F4F16571D18C8E1A301341113D5C6B59061CD3124683748F5C20426288C7BDF8CCD2D21ACBEC096101283534CD4974978B117BEB70BCB5FC557D5B7482C626A390A10F500E65F8AF72B3779068B24228C37907477017327026324FE3C607A86EF7FC453AF88C2DBA51114CC67F32BB46E58CB7995D4AC31F9B0C2048B05012189E73562FD2BAAC0CC4795E55B5058B9A747A5C34C63438F2767D32354F12A0BA546C76F38CB54CA632F321EB39AB0528942647415F91CD0738190ED20B1401AA0B1C4765674DF3E47755A12426A2A307760DD9D39C2F7728DEC213B2559CD2128181E74426595082DC0065A2AA132C72B798AEDDE6A7C2BC03CB0539EC61BBCCA78E510600FAAB6828AC6A60F58B6BC894D16712B34892FDDCBB695C36EB9C3169543C61969C22F95B6EA52BDB9B2ED0947B8B21912D062783FB94B458013F34480BA83178C87D9CA4575AC9014AB22A7CB92B1BF41ECF098F735B3401E31BC02A43C447220DA64CE22B17408AC536135641100D1EA581A14818EAA4C77B229B31511E0A403229889FCBA0A2D4D3C845868816B79F56D6265D678C9138B716213FCFD7ACB2C68F4FAC7914D140CD2A7487B34146708115689407A9BFD24216F563A6FD220893C1C5E2C657031B43A29B19471B084485B7F739AF017459AE50423518460266CF449B524406B9A2B80A77093AFB1344BC1521E0220C5A113CC0C4A4321A77204521E3C758927C83398AA1F4BC43AC61487E7158AB4053FCE98A74B14632054D3D3AAF018CBAAD771326B7160247CC10A114434087FAF515C7A39B0705BC374B7AF73C5B60741E037BC69B10949DB1739AD74A240C2191B3201A020F43890CB16390D6C27C39D40AF0043B57E8A0F978627FE1B36C6C83FC97B49AE9268618B2C96A7A3612002B2673BC1AC762A37E07FC6EF3749009876399862D67B5B48571CAF8B326A4A80B4544C03BA811B3501518D5CAA107BE696CBDAAE79CAA0191F5678FBE14934609AEB501BDB0A525ADA654D77CB3042159686381E3677EDBAB5F7DD87FE1C4566DD7382F03C2ACBCCB14182B9A65AFC0AAC41F4C3095675A316159B0B7271F0284E160190DE000FE4076B6E3073D302A51C7A6F6486C52C97446B506DD7C76EBF08A5F8C70E6E8479735C2AE79A6D4A99444A347BA838C43A1ACE485A005A7531916C45181157C955817C488CCAB9AA4D55DD79A5E243504A74405A8A4AC01CB1B9F2917FDAB3B2909CA609739859383D631B65965AFFB4490D5B9BE84A2902CB34CC50B5C49CBCE43F8351A68B3476387BF87A16B9784A0E801E1EB39EE33B8B9CA82BEF596605B59F33035A05A012D8549F0B68C93B784C7A309DD71425D3175BA50107D28AA8DD42369BCC68A8AA074020B4B21C3D537CA25B82A50DC875AB76B35A982B0792FD84B60E7DB48FA0B80CDB90E1A95038842404A78C17D6C73E42951ECF2160DB816CB7323CFC0B8B0057E6E66A36A856EAA60735433BC1680636D137B8DA85F19334BD0EC9617D8B484986AF31BBAF7E81A050C5B4DD9356563BD2F874B6B82A6E8B088B2CA59EF3866FDD4217EFBC5DD66C72B66137AE65E7DC5C541C42A5C4CC1C1F1B678B7941D37AB5BD7292C665EA89B9679C5A6F8248F9FC61C2AF282EC048BEA74CCCEFC2077F370D3979B83E2A65D64BE85742BB9B66308FCAFC84038E72950E968B33FD98DA2750484F1138AACC0E5E8607E352804316B26111C5A242C09901339FCB7D304C749D9205F169D2663A03BBC82658A0CA3025EC4D0A1E445BE8FE3A72C672333188ABC3010B6A98EC0F01D698B87F195B2E398CA6F8038EF0739AF347B22076A58391C46573B0F782444464D9EA0645B4CC6F7136927C34E51FBA618B082F826B29FABB8BCE80BB0F05524348104EB4732E0AB4F4040E104B78AB9317B558330D4995168752EE23455EBA2CC4CB679687BE93860CCD1848BAC42616893E6E710645B354A657E4F064E2D3266F89BACB8585E6D927259723E7D321AADBCBF9638B1BCF917E3C203FD06145FEC0BE1059C4A52AD751986D0F0BBB46BCCCD365AD6B614DFB87DD7F97CCD731F4F9B280CD321D7D7679743833823AA5A05B1B3D0263858CB2EC27677DA6928B26D3459573E25B0CA4964D6798CF250860D055418761D7FF0189223A1D3EB6DDAB21572B58F0F5AB03A1BC047D7928C060844160E169B2CE072A89FCA5B384B81B89B24741674FF5223D4116ADA77797234AD3CBB1F6A78CC33E27B03EBB0D5A18427F625A4311A9599AE8723BACF392B7C915AA731C943F49C24F189055143502CB35318432C8B89BD2B9243F35C4B443AD48126207559A2314A77BC67C4D79A3E010FA1686761509E6774BC2DF86EEC6C5E3CD547F9A5457FB4A984590E57CCBBEF3B38E441235D90BB60A24A691425CD65BB43B5868D128E3428B446409804A25333A7AD1F5C6D712169F660798DE5A448AA393B5C496DB978934C6EB001112440784DB13825167A33206F76B05EAAAB0B89966150238748C492379B387EC863FDA621ADA4296FE16593358CA0AB83C15225DD26691DA0B00554C2398A2C44F171BFE63D48DB72EE6CF36F47DD054B8F7BEC5A4BBB6B0D62BCD24A3B8A6D32C53A51BFB7C57ECF5FB124740E9315CEDB69EBBC969314E2B7469C2D2E2BDF2698AF4BD116F0D12D08A2455063246EB5761E908816E48990D670308B0D34D7823A325D49A1A4DC0D", + "ek" : "6E145C933CA8B4B34D9EFD7BFB95669B9E7A626F6F0FB3B5E2061C30BE9E28CCE40EDEC9CC1524FAD080C1DA0BBB26723F8B6604611287430126E7B273FD859F2D5A2985D6F4A08C9F08BB825FBA2B095104CB9194F8EF10C71F8EF1202B8D9AB9601B9995E0EE20F97F31CD4C6E7EC6710FFC176C2DF7DDB19855E9BB11C7824318F16B1FE978E7F1158D4538816FB8D57ABBB2CCA4EEC9C56B94978DDC74BB9F6BADBC9C43B6F5C313FC508929E4E823AAC7A446364F8E0866400BEEF4C5AD19039FB11FA2E4D08A953511B1E125EE2B755417A13FE55C27AC87FBBF7BB416D7B9A86EC4B33AE05B1A7D50BBD7AE34E75FECFA232BA2B62C310EA996AC3A0653DE2182FA408C63665E32E7B478F66B29C82E45E038FE1AB8169A2F8456B32C4DAF668B5EC0964D0ED914BE0CA664DDA47C207E6A1A0B1124D5DBFBAF4AB0D3BFC4BE1E91F2B741B39F47FE795038F323F0A9FE482E0BEB2DAAF8E520037D9A44C1E029DE0D3D1817EA65D1DCFD4863C94E679D889447FF5C92B089A72E5655A911DF3FE45644E4AAF01CAC9F48B8B7BB87AB3ECDB43808BCAC505654E3555DFA6C3DCD0472A43354E12F55F655D02AD100F2FF5345E6AEB771731AA07964379402E562B63CDA171DD58EA501C43E700D3DD5655DE77AC2056BC29CE80FADEC49E6C65DCDE1B3F75CA8327722BA6E05BA77904340DA9163D71E24FBFAD10B7332452C2DEE01981BF0B10FA8A33A95911138822A3EC99241819308B4A245FBA82AFA3594918CF421C7374C48691146FFBD86E5D298CB255B68122A3D3B45163CE7FC909A669ABC374CFAE3AE83706F2D9D035719543AEAC69936C53D2561BA9B11D514D461CEAFE15D67490E2756AD6A796351F4E041A76A852311F4F36F1E3E4FA08B9ACDD91A35CF7C110B5BECC872F7749F0C646B8CF2B031CB1EF3C7F6E9697587AA121FDA1F95F49902DF3154AC1030DDB04096812770E52309F9E8AD6829C82BAF887CDB9A62D0C67D2C6061A07E271267FF6A1083DBB75B5A2A5707AA80FE3CBB3A666C66547032333A0535748B5891308EF5E4DC08E89972F89F06BAD7AA25455F4D55A88613A4E41F9564434136EEB8AEBD638ED1D43DF338E36E06DB21BAF4ECCF5AA68B12D2398BB8887C8344FBB133A9DCE53CBBA5AEDBB196CE64F36A6ED73FC200AD6E5BA7376CF4927935830EA39BC726A0E993747AB28C335A4575AC6418312918A936A1A6BA3FD42F4BD44DB9A6B4D2C613D3EA5B8824B0F2A6C1DCE67E4B5D2809E855F4B9F427D36B4CCFEC72950BDBD4A99E7BD5F7F6B1B64E42E83CE0BD94D737A43BF291F5297B52F2BEF0FDA7B81B795E601C941B7D22FB00D22CA45AE835EB67E00C4D483DE9777A41EE076FE1BB6C0FAB5F072AC1ECFC3D4B18A7E0F8ECB1F684013B0841B705B2F129DC5D9B9325798948F3CDA81DCD8154C455ED8424353036DA0B5D8883D5C5EAFE74FEF62900CE6717F05BD2BF48D03395FCA768C7CC6332F78A3DD0A0BBDD6763692A9A4CB84006C40D2FBC3DC183F80133F7D09D15926E945B145B788FC546C3173C405BF89055B8E50E765D441A6C258C329E532FB8DA2D514C3D52E470C4AC987585578D9A43CE0F6E109AB68977D85C2FC7C2A525C0AC96BF0BE41659A09AB090B624C739EEE2E103F4D340F223EDB0DF8E4311530B0679C68535803557CE2F4945688FD8AA5FD7F55BDB12F9B058AE14ED7F9DC8528012F88DF5278A7636E75E1A14F897459775CE92538CDAC8C04E85182899C3629E3F20CACE3608711E66463945437F578E1EFAD85F7E00B5E101B00CA4315D84C2924D4FD3435F755A74A8BEBAA65EE14F3E26A9439EFCA9CF988C207B9B6A35213954993259CF82C6A4C7F912819C92EAB344F73088125E793ECDB3E1689A52B2CA73150D6E613B94D2CB4606B7A9D8D049921028178804A12D5F89045119E937921A042AD53C95E3C6EF29B8D1393713D8E6678234068FD533D843898F55D8503C3F9FD267F06601053686A5907A7C86A70141AEACF62F2B8EA87303420393FBC0F6CC47D2C53FD7A55F2008063B7DB5E96A854A36CC65B133BFB941C5772B7F57A9AAFBBDCE7437789FD26C4340C3BAA4A59F811B3EC0FD7B8DB94CE1F3D579491CABC37D979583E95B4CA4F1BCA502B98DACA2B0F1636EA112281656868F16D82271348DA8C8E7DD5C79EE7B7699A4D157", + "k" : "C84DC492DA38324D22D5151A86ED8D7C6F09E4624F21895AD2FB8F1AFDC66231", +}, +{ + "rngSeed" : "DEB963F8B1D8FBDF499D564BA8D2D47915BB402DA02F17031B37B4039A842AFB9B7E48F37200605992BD2429427A7A4E", + "pk" : "E3658E3C8607F9775EA3B57A481CA307A36B36780EFD410873F9067EF06A6F75B2F695620C9753F97B167DF14F4B59A66EE953AEA71ABE866FF3E34CAE61B53F5842A9AC3C811ABC36798059DB5A51BB1A003B5687DC73E279236E69477CD03C5143B6E22BBDE999379AD131215C9C46E37376402D434A58F4CA4C5249C537B15937C38282D2759A45243CE36D24EB234C5BB875B2594AC89E51564E43D2869EDC93CB2143D3F72C6D8672DF16A08CF94031612199C224E25BB223FB646AC5997B806ADC1BCBD49A7833409515C05238AA2C3445A290EB4E4CDA6FE1E61FEFD58084DB9ED675B608EA1BF660195C226A6B70CEF5A114EC584903AA427A34C4F75B7D0DBB4564C72C2B252EA9B99173659AB3639D3476332C74AEBE0B6656E3CC3F99206406718E5718E76BBC2DFB8B409780263851DB783979FC5EA3E4A18D6383762C6D5F782E7333876C10414DFB4548296D33947590534A01C399A3731DDD4C882012BD0B1448E066C528F28C52D3C34F1CA1E2DA234F571AE9921084179A9673091555B9D671AEB33A3C41C22ADFAA8CA800B92E9401FE31B35C311D7820284FC534C928BFD575881E5678FE81803ED08041475B0F4A36C7644441A067CB35A633A2AFE385CE1A1B5C4F9C4A1580003D1AACC548A4D5E7C94C6A4799CB843FD4C6E6209E1EB1A71BE32B501B004AD9C0D7A6B44C2970140A021416483DD835E7987B779041AAC46806A1A538152E3B716BEAB69A86E5291B431B1EB68105380DF09758871335BE0735B4A22DE2C4593DA03679622C2AF78F4D888FB178098486602B743D72F25A57B3533623B57CB905AB499835093B1C4B9D40D361FEC791CF82A17417981EC713514BA50B46608C1307B7939AD5F9B1AE47AC2F0C76162161CF0677AECA801504512433918AAB949C078D46399D873B0A6E9987E9AA71E52C5691232B8BC68C55508C9BEC555D17A6293525D297BE94559671C0209561C6BF7859C3469772C25E0863C16C9C4AA453862E52AB3CA942D887C959850CF4FB2AFA3420FE55660C22516BF8C940EBCB1DDAB9A36A341CC144A646321037C07231424E040AD92C706D254E56F48012601E0DE8402221711102BE85F54D3BC513481C1E2AE6C50A022D056967C6B032C99BA89070847BD5ACEB4669619C71F2B7581736726DC800A3148BD2871D8BF60708DA4CD13B8822209BC09CC2A88A43DEFABE6A24986D697FEF253AA91525B3A3CC9F102C9EA158C699745B03AF77D41D4DF72BE7FCB6B7130F308BBEEF6AC699388976A574EE1A74E84B48649BB32EC763227584EE24C0248B7F5096C72CA172D2B81982F676DFE44A896618C77393475521EB6A6FB8EC6E153C72D7F8C9067A765CC4149FC58777974F96411739168DEB8A6B0E905997563D7F13590AB30173BB23F7B7440FCB6DB8F910B12958E0B62FB6F84FA5AA931B118AB4F1AD6374A34721C053224B04CB07982988FA3A569AE9342953165B012F31728960F89D589613D07A2B16C71E0EC942A812A72CF90EC9B23118A59C6BF7C273C6163A8470B18C8C2EE76F4D2975E7D79DF7E80E759A52E6B689EBB7BBC7ABBF6609560081AAC3ABA2B43ABA545951427CC35DAC5CBAFC7D394BBD57A2854E84B5F0F3059A94B35F3B0F1AD3344CC2A40FB89A87E091C9C0125C0052E8B28CFFF0C3E0390967E1364A4BA8C0B77A7FE83A65B76255422BA7A128FD4B3C8EF85FCFC16F80BA5701C9A48CA230E455B02B28641B98A67A851F31621733C0A779170EBD690111F395E7461127481FD8E1057D35B6C20B1F68322E72E92A2363825566445544995DFC08CCC492F6E19072E398BAFC32EFF92C7E229F87D1327BB1884CD04849569C415860DF59646EC59ED052BADE3A0EA6BBB8E9D924E6C43AEA22CD4969528D50AF83B977D4F8681FA52AE6F5A60EC1CEDBAC91B14B70D46C5EA18551F288690C3AAD6428939426326C54A80B1C6281D51B3D47462F18C6C5931C60395A1E74826F6C258F5622F689C4B5470976A961934104B41100142854BBF75D40D09BFD9A0E64575A7546BEC19108770C19A7CB48208780E1C657863163022C910F071C59F239A23CC9F1697CF5177F88E7580DF8C925B2C405A3360D0A80A6EA1486136FAA9C48AA3801EE87B7CC5C638D67BE57548C03711F9B2B31AB319D45C578E5ACFA30DC426AC3B194230A4BB5EE07F4", + "sk" : "401208D8B00DD0515A1F7C23013C9A8D48062F281437A312E94C7A76055580B894CF66A7795C182D889A1A940EA044112A265DEE346D902758EF7B3500A02F8C009E3C803A9FE2A39E95539702250FE05DA8A85FDC2CCF54BC17B540947E280276A084DE678FECB73A5D1BC985718C09AB5BD87675736BCC8EB858CBC246FDC07F0A7B3DBD1656F04C7BFA3854B502A71DB111FE2C36A25910D37A5C357BA0667417550071FD0B0C4FFC094B37B67D262734EAA64794C5E0D66D0ED96A5D7C7F3865CA8579B89C2B7349B3134E43A677680414EB2D88587C73192A11E5088D673E65EB1E88FBCEFD8AA72B704521749A384588A6009B3E41CD839313ED00B5B4A14236835055A875ADA5674A1959E2746E3A38A1CBC7BC0CF6A2C9AB95C135287BAB8B7D12BD8DBC79D2E6B36F0542EC73BD66F6949EF00975F74EC8F31C0CCA8544C25A431C8E43A9C0C99545A18CA7C5F28D4E0173C4505C5C4BA94E1B87A3B4B0EEC5759BDBB221530FFDC9048517102E70745EB09079F376914B643ECB3FDDF0B68D384E2FB727BAC38148D897554CC8EEE5A986EC0C2081A2D583B73DB69BFF054133E18E0E7B52E9E9C5C0E088A99895BAA375F5B27255F1B64B38B96B91B08AFB5B36371802559F240AC4BC4234D8DA75B6839ECC822721A466E0F7A292723286F38646E396E7AA3DC9239C3D621FE70A2EB14C37139B878285435C682B9B5489903BBA677A963509C5BA412F8165BBA029084344445E21BFB1432F97B27B3377252DF129208C71C41A10955C79C6B6507B1067DDDB8E1331897854897B6BA01F79BA6F6273CBE540620C27D731A86719903FDB5534BBBD9A9275870103D9BBA74B694595188460B80490E0269DC678FBF0CAB0918C59958EC297BFF5E6572B3133660936689A393AC36F638883D5A95E1D78C6460C692040A9A28895FEC808CEAC9590AA8552382B31A489EF167429E63C7387B794552CDA972D4DD3AA41835BF29315BB095B95D4539B66008887AE15E66FE561534FBC973F4621C4F41AB9498D0EA667637C5E563ACCB2B0429D580CEE038326A8413271203B93607ACC70666C50E34C6186D03600043CCB4C7E18A1182AD39EB49C0BCD746832B1AD47BB9248402091872BA2B68D25C0B04064558F9453DE628C4C983C1EB202FA724A9F373C003DA76C37743A452D8F765D82C292468C28C16C9B26A2727DF96B26673B191B3162970A557CAA63827B5A2B631ABAA861763663D08B72B712AC53990A35B57F99B5B7D4CA3035A590DB287E1513193177F687157EE74AE10B73E6F24E8838C3DF29C6D8B78AC6B70AA1EA1B6467B6D4319DBE98771CA752C9986006A687D0812E9E46374563A15AB32C7B70B58A21C976816192D36F04634FA0B46FCF202B44E684008C624F0209DDD64497184524032982DC654FE22751846A2402C17503799E9A7D686326873A4593479B615C13F91CBC3ABC952BC4792CE04F7A272921D13E34B10A203C2C06D65DDA903287887C29CCCFFBD4059C5B1FC2C3B7786C0EA2E49AD792136635982103473657CA2E4B32881B6EBE8C4E7C63594D34B341F515689B7C671B4F40FBC7D8E1CA6CD4016A9200CBB58741FB21EC84030F6CBAA282B9FC4365196094DD39BC6447739999041EE1055B373689589DA7A6A23A007145AB208BF56EA51C3D68E2C3B4CC4F0DA518F9089D4EFB28C7F746F0B948A2955E26DB2B5ECB7C6DB2694DB5ADA7A7AA939109B1D0604C5A2B654A4674B636CB9A5F65712F404B4EDEE505093B1FD76B627B32C4C42910B1390FF03C30A5E79BE6241DFA39A2D9456C331C4404E7A159B8A89E10588E3446C7151D7BF31A6B930F09312B5D798DD71C45B2273F513C8279034483CA7010A9B3D597CFC7F699E649A99238B1283A935B199F57F6333C2A08C553A9BB8C38109319486A4A44D71A5317AD4ECAA9B4548B86A9560969690E8B02A38BBB628391EAFA6D2EEB4A783C661F14B9754A8C2FAAB853DBC10793A61CE2B1EB72C7E5B15789FB1885E7BCCC89C03350A047B811C54738FA91219744CE5166A4882412C6898FE9037B817099779968EABC1261831A6C0A5F308431D8904CB9D4A1BC8B79F0EA01395088A5377935C26906093A34E0BD61199A9B8A06511B2127340C9C0169961A08E3658E3C8607F9775EA3B57A481CA307A36B36780EFD410873F9067EF06A6F75B2F695620C9753F97B167DF14F4B59A66EE953AEA71ABE866FF3E34CAE61B53F5842A9AC3C811ABC36798059DB5A51BB1A003B5687DC73E279236E69477CD03C5143B6E22BBDE999379AD131215C9C46E37376402D434A58F4CA4C5249C537B15937C38282D2759A45243CE36D24EB234C5BB875B2594AC89E51564E43D2869EDC93CB2143D3F72C6D8672DF16A08CF94031612199C224E25BB223FB646AC5997B806ADC1BCBD49A7833409515C05238AA2C3445A290EB4E4CDA6FE1E61FEFD58084DB9ED675B608EA1BF660195C226A6B70CEF5A114EC584903AA427A34C4F75B7D0DBB4564C72C2B252EA9B99173659AB3639D3476332C74AEBE0B6656E3CC3F99206406718E5718E76BBC2DFB8B409780263851DB783979FC5EA3E4A18D6383762C6D5F782E7333876C10414DFB4548296D33947590534A01C399A3731DDD4C882012BD0B1448E066C528F28C52D3C34F1CA1E2DA234F571AE9921084179A9673091555B9D671AEB33A3C41C22ADFAA8CA800B92E9401FE31B35C311D7820284FC534C928BFD575881E5678FE81803ED08041475B0F4A36C7644441A067CB35A633A2AFE385CE1A1B5C4F9C4A1580003D1AACC548A4D5E7C94C6A4799CB843FD4C6E6209E1EB1A71BE32B501B004AD9C0D7A6B44C2970140A021416483DD835E7987B779041AAC46806A1A538152E3B716BEAB69A86E5291B431B1EB68105380DF09758871335BE0735B4A22DE2C4593DA03679622C2AF78F4D888FB178098486602B743D72F25A57B3533623B57CB905AB499835093B1C4B9D40D361FEC791CF82A17417981EC713514BA50B46608C1307B7939AD5F9B1AE47AC2F0C76162161CF0677AECA801504512433918AAB949C078D46399D873B0A6E9987E9AA71E52C5691232B8BC68C55508C9BEC555D17A6293525D297BE94559671C0209561C6BF7859C3469772C25E0863C16C9C4AA453862E52AB3CA942D887C959850CF4FB2AFA3420FE55660C22516BF8C940EBCB1DDAB9A36A341CC144A646321037C07231424E040AD92C706D254E56F48012601E0DE8402221711102BE85F54D3BC513481C1E2AE6C50A022D056967C6B032C99BA89070847BD5ACEB4669619C71F2B7581736726DC800A3148BD2871D8BF60708DA4CD13B8822209BC09CC2A88A43DEFABE6A24986D697FEF253AA91525B3A3CC9F102C9EA158C699745B03AF77D41D4DF72BE7FCB6B7130F308BBEEF6AC699388976A574EE1A74E84B48649BB32EC763227584EE24C0248B7F5096C72CA172D2B81982F676DFE44A896618C77393475521EB6A6FB8EC6E153C72D7F8C9067A765CC4149FC58777974F96411739168DEB8A6B0E905997563D7F13590AB30173BB23F7B7440FCB6DB8F910B12958E0B62FB6F84FA5AA931B118AB4F1AD6374A34721C053224B04CB07982988FA3A569AE9342953165B012F31728960F89D589613D07A2B16C71E0EC942A812A72CF90EC9B23118A59C6BF7C273C6163A8470B18C8C2EE76F4D2975E7D79DF7E80E759A52E6B689EBB7BBC7ABBF6609560081AAC3ABA2B43ABA545951427CC35DAC5CBAFC7D394BBD57A2854E84B5F0F3059A94B35F3B0F1AD3344CC2A40FB89A87E091C9C0125C0052E8B28CFFF0C3E0390967E1364A4BA8C0B77A7FE83A65B76255422BA7A128FD4B3C8EF85FCFC16F80BA5701C9A48CA230E455B02B28641B98A67A851F31621733C0A779170EBD690111F395E7461127481FD8E1057D35B6C20B1F68322E72E92A2363825566445544995DFC08CCC492F6E19072E398BAFC32EFF92C7E229F87D1327BB1884CD04849569C415860DF59646EC59ED052BADE3A0EA6BBB8E9D924E6C43AEA22CD4969528D50AF83B977D4F8681FA52AE6F5A60EC1CEDBAC91B14B70D46C5EA18551F288690C3AAD6428939426326C54A80B1C6281D51B3D47462F18C6C5931C60395A1E74826F6C258F5622F689C4B5470976A961934104B41100142854BBF75D40D09BFD9A0E64575A7546BEC19108770C19A7CB48208780E1C657863163022C910F071C59F239A23CC9F1697CF5177F88E7580DF8C925B2C405A3360D0A80A6EA1486136FAA9C48AA3801EE87B7CC5C638D67BE57548C03711F9B2B31AB319D45C578E5ACFA30DC426AC3B194230A4BB5EE07F4C5B86EFEDFE663032FD6EC053E7AE81EE85AE4B3F808156CD357C2B36DB2F7FADAD700CFD0BFC439237A0CDB3F7D6C76699AAD545D0ACD755F14F7CB3B30096C", + "ek" : "A3967F14C9398F4FFAD731740BFEE21B0AB283B5E2EFC253AD3511E62156E4D5C45ACBBF0CEEDE94B20A8E025CABA2803435A070988B2A91D9C0726097084BDD0AB278005D0651F650DA8A096C79E3ED5784572B503C484843E42309E2ED018148EC362A0F0992BDB0D1788621D389284C90CBE74F0886904687EA2B15E20EE0E620AB33BD3AFCBF887E8FE5E5C88621279AFF86FABA87F400222720BC6DB1CF5CC2808EDEF789B403AFFD161CFFD1CDEF604DF69CF78C2003121A49B1AA76E5CF61FD8870491D43C2554B183F49F939A80843344261E5D035D5137F44783507F67D5517B2B626A35C7007832FBCAB624BCA5FCB8D0DCF96E041472CEA9E9CA82E892EA427F56372938796E52EB34A07475C699DE178D03707B9A615C5FE9C5D2BE3F930BFA2AF903CAE53B913E8AD409B7EAB94E0D6D49C6004083624B359CC041690D0F90DB52115D122D6FDF38035CF2FEE8FE164C02F29EF5D127C4AFECACA41A21A05746EFCD687F4E2D5452BD40660A27C01BC5FA959BDEDF7B3810FE2B0DCC932B0BF6E3C848E1DC09341A401DEBEC903D097FD0E23B9F06C7CE2581DC974FFD968BA8BF2556213CA08D42C8014E0BA34ED68424CE142E3BD5399D8796B7AA9FE74808786E7FD101C74A69A654A467E627BFB158C330148D1603FB3788125CC0F823B8FC05024209251FBA145E19969A188DDC644FE21CE77C9FE9F86AC7DA2544E8BF1F84BE4760625C20BDB94F4B4476121D32236EAD1A4BEE72B4B6836628636D8E8B357D7D05BCD68E38730FC770093ED7B6DC2EB2E20CDC1B7840046D90EF535EA6E807644FA76B186C64EF5A6A6922BA67D60C6A025A4C1AD522959E4EDDE586779E575C4DA0FC40AA1F674F1B07D1A86C31FCE68DA4E2FAE056FBEE1F15C770170E33280A08F1ADEBE128640E8E80B8125ECCC2DE4BF2DD01F2442E41303974489B3D0DFF4616E0F829DC88EEF04FE7B3BBE8A033E7D60ADA54288CACEA6D949BA18EF831E7DB58E7C3D63DA4A7D15703C80AE6D3A0B539C24069D7D10A9C458B9FBB9F65ACDA0CE916253C88BFC48C806F6B3B803F00A3E95006288B430B0C04B2590737F5ADF34EF02ECCC2E15879F0C72AD5658EA379EECCE88DE380AE189FA09AB13F8914DCFD7D3BE908E60361B9815AF14208353F1A09B1096CFDB0EE1DBFEF26F1CBBD2AF16287CA9C899076AE8861B26863A170E606028F64B87CDABE25D4CF96F9FBF5A2F189C058DFC84834689697D4480422BA01E679B9594FEF6323B5142844FD44736A4C8C6EA9C6E8F582F72195E4CAF57CE8DCD8D223DBEACF6CBA7721C8A1915E5E1014F0B67EA3C78899710AFC4CB382AB506D9BBF896065FB088A99FE5478225D28C3C27CB80EFC9AE67E6CE5CC29DEF21A1A4AF86DBA427C171B990440A5153D91C0D8C2F10F9DF97E1BD6573C2492A08BF8B5D5E6A89362AEFDB3894D0501198D6AF334A9E14206EC4A11C214C6115DFB67E602CD192EBD372490EF5C14E4B08385DD9EA2ACC046338199996418E11A89FD4AC1A077C22906694DB9FDAF032A349B90AB6819EB44BF4509BB5CD45055F48970C65A45590408E334889618EA95D952377F0C405352DA6ADAA884BE8B9B552B3AA2E2389C0FE7CBB1044F73274DB86117A9D7DA711BC8E1CA13AC2EEF1398EA80953BF8B60FE79EEAC5EA677427A2D9F4EC08E835B9A0B33745F0A15AB01BC623320FC618D083BAB0A487FC27CA58524F6182E3183F2778191CFC0DCA06B4BFD95A03B88296D67DE96D8A1D2BA522D8BC2C5EE61E441FA19821D6BD1A9CB8C1E1B8704C95EEC9E3A0809C20C7A32AD6D821F29705CC85375A7441A82E0BD9BEEFDAC8EFD7AC50E090209C075430CB5618809E2B51C8E63DE0D2FD8BC6039E5D32D08D26E2EAFEB25780606B7681611BF455418C82EC34F6E7102BB75CCD66CED58556EACE1470EA1C7A84734879BF51525542A3ABD7FAACA1F243A00B41A55DEACCF0A4DC5F877CA5E1717F2EFC04B6447189FCC6F429DA2A1272BDCC6DE996AC44764D9895DBFCB6D3755155337D5744614AC2CA08C8AE6115A17468BFBBD9B3CA8024042F9FB51004817CDFCB4C4188865664E18B26B8167DCF225AE32EF84F7B6D93E59332914A25657350D727D1689891583D4D86838D4C206A9652E81D473DA42AFFD274B2383367003E58D471EB553F30ADF7566B4930A0E2E87", + "k" : "C4E167F92FC45240D1E7E5CCDD76650D8E3526852FE09DFD05C72B4E6525FB23", +}, +{ + "rngSeed" : "8E2995F1B3E43853B18916BB1212ACEB05898E2B177A87ABEB928AD7184E59695C56B2CCCF5DB80853C28A525E327D13", + "pk" : "BD8557528725705C2BD05331FBC20F5560259FA82D438392C7299463710357160F985555DBB2AE4438310E3879982B55F03018C17101C2556EC377B15FE6507488052CD2360B52B8CBC7856C8894CEA237E76214DA481EF0363C877294399CCA9E38C249392D61A2772FA4BFFD98165D24760BB90CE22614E892A9C7F350706427BA2257EA7A1304029A6EA715BDA9B2FD682C6AEC65F70018C26C3A41A30F53976AD8B83AFF7268F6D9B3124A15B94528024A179DD24B8C56CC8605914CA89815F943C1C568F255B757220AC606D06A1701457B057CA323DDB65EF076CDA0044CAC79455798B501463D38D24CB9C65FAAE94410F79995D917C49319E898AAD54C620291491F96362D4792BC3639B6551E5A8B7030E9870896CCF461B65FD82ED0F69DAD10BB60805C553A1A195336435303C1C8834C3A25C2832BF7B62E1B50C603951C12AB6B74EB72F4B15ABB5455D9F681A0D5A290C0BF0AE79B03973E3CA80D9ED283272592FD0A64938C26803441DDA5907BE52AAB1B9AE14B62F9DB044CC0C2F5F48F0B8348A6B26631433DFB00B180B721910B8FB533CFE4A8BE1D250D75A9CD492CA059FA115132AE5463577DE070C87944BC48695F3B4B04014E9DC29185446E4683AE2CF5B9B3AC399FB6C6541925075B7BCA7B7326861DC105B3B57AB55A8117EF69B33CF79665663D3355819DBBB235F9693D7C0062E5293C0A32D7342C18648500F8CB3AE925C530B6507418DA33A819E57897849BF3F36F6BD68287F7CF8B5281E9E5AF40BB5F76C63D4A14CFBDB8235C6A95415C4AA157568C34CA9F58B3991A756BF5AB9B658D9464AE207206D9D2049D9145B7CC59261860267806A23AA513F3C39CD7AEE8E71AE4B3A4A6CCC570F179148C2AA50BCDD612BD81F8206FD1334389B9A726208DB920944530CA839F316161B89A59350B2220A4B6C67CAAA2425D78DA2A3B454E396386C5500F7726AA38530B881640A6870D2E5100EC0C25D5A39BCA206EA5652B55A8A31CEBC84FA62F2AB6A57A2658240A0F14841E48340CF158BFC639149921632047ACE0CC2AEE5A3E0F647FC0C671F648C689002D98910F78B34E80C523F9073E4E4C9E6E102818E996D3A30886E7BCF18B69D2A16FBA1181610B6BD248035CB90D8D440F6D4729031B21A4E1237D710BDDC5040047745B231A22246E517A76D76A0EE7985EBC794FC5A51C17D9A9E9ACC471F89CBE260DF5C4676D870B8713BCA53A400CB9B4FA6C36DF97A023AC03B08C621E7329635C2E9828719203852970C2FD557348F5365CC917FD3CCF71D38D5D96336026C7D33B885526632860044237B4A6B09AD392414B068144AC67972B3CE7A25753F631EB1A03B4FA2E9F553302A22EB9C721E9F2BF74A06673FCCE5BDB77EB4B525D63906AB2C4E8518322D3065121A20546A8A4EB45F85881CE25721B0058C2334FFCF2946C7B9D6AC05806FA778B2041BAD1C1250883873A95E3D5B76A3480D8DA8B48683C5DB2757EAB9193750649E74440DC58A56B3CCC27B2A8177BC638B61E0136A215C8079666C77857018784F38BCDDA0C56639C03196B54CBC80B49B0ABA6F6A9DF352CD09C5CC6E05F62E835F7A125845BBA2FCAAE4BF61BC55AC98BD67763EC0214CC1B7CF91632960C9EC01E0F27A97F909D7FC2486D0CABFA146B72BAA14371041A5336C71305E6E68A43577BC1665C0D66C76A239095E13921C00C4AD11CDB69050F7857C3A1B70E2A2152EBCD0961A936F6146D6A58305086E934061AE32BAD1B894CC27949F280320401188775AA5078B1497315639288AA2F1F826B48465613A73C5301383B69181CF14AB3A05035A79DE39973EC5C1FC5869AF11320350C3C4208CC68DB8943A017215B72B3353B77003FB0D513BF677B81F66085E8205C17CDD6B603AC98310C9A967A7B99B8D3AF10B66821612333E50D72FAAABCF93612210572E6710E482702B17BED5ABB5E4A57BAF365C39B59DC7CBAD13601DE6B40F5370A49E5B48C9580A0C26195013E6B6889B99B7EE5D93FC8B795CC62A37CCC5E3DE2692AD66E903C74BCC45ED6F16A68AB17D8E5094680C428A242D2FA247985A0B7D7A300F70E844765DC30437D032F216A8D99DCC54DA34C0A4C25A8A120B3C32F45A3777467B1E639BCFF1BB9839B6B45C7895BCF62307460DF309EB4E61AA9CC8941418677001064AC161A607E24E1", + "sk" : "76A86ACE9756DFB462FCC13E1C01409B79A49C256D8A75A9A30712F5E913E38240F3520C11344F4329C3372ACE01C1979B75C641DC5F0FA2C2FF1A8055DC61DDE093315910E032CED42248EAD082E9B355A0BC17CF349B2659555D5844D94310633B9098F3AD6353A4FE71809EE99D05C5A055A68E83A35B614361D4AB7E4BF30A80CCA2EDCB692C25BB35C702854C55939B88E020A329CC35F6F702C94740A614390D6C89B2FA2C324681CE4B600D87B0ADC91AEE506B50F40640259927B120DF4A3A2A2C1411E1A198102B8EB03FC1569B83DAA50A7687E1F8B7E2E16B5D13BA38905CEB285A57513532ABA8A235C4F9566D1BDBC64BE56E4B088E76854868377665CC922CB0A401C14142308E8851ACF4EC8484177EACA16AB5164A37F8BD12F4B514EBA7FF555ED43415EEA7A4B7B4CCB0A08D507992ADE401AF6A60426972D5F8A19D72CC2409584C4473F4D8088E34B376504344C242C6C7163CE6CA351B3B40A2AE3B7C45A96AC3C30136C880BFCD4166014736E0D575D72C9C2B1278DB43126C952B393C47B45152B2C7C59253B9B8D97E19818A9B007FAE17765CB60C6722014C6562AA4723C5A33EF63821DD9464CA298B72C68E80213613953E89E2B0D3A4B18347030015CDC1A6716D8A534B5031A5367C70184D7DAA93533B46EF97A573FBA6B7C39C9971B1538CC1B708B921196E97C7A3658CA9EFD1670B1B7934502896E02E18FB0F01B7A8B9B81322951CA25714DA90BACA924C56132BC8A09B52192DE63726D30186146B8B2C233F08ACB46092B5CA654C14C92B69E1CA946812FD3B0FE56AC13739BD2FE99C3C62C46AD3B39B4214A3D8220E67A718A16901CA82D59C08BCC7CF2B6A3ABDF995EC7A38C06801B0A2CEB88937A3164424161403FB639FB2AD6947A7153CA7BA8290F099A7D6D8322448127ADBA4E26C5972AC4EBC95905E7148023BB74CC13684267123F57243368F0C141CE0B05F29A61866F99A15A2A85437CF651CA4ED718E5787A0872C536F86198F0125087BC898BBBB479C1DBFC23231DB78D47B61EDB37F3B03981AB15CB70181FC3B9A1366C9F98ACFBB3B6E1CAB49B4110EEE3CC87DD2AC8D8720F48633D0910C2EAB7EA1FB197D3431C7B1BECC201A21C02B2E4B5C9E85C5A9560B2105B99C7B7B121842A79179057B6642976EF5E650AEC633B0B2B3DD14CA2C0206746595113C7A241443A9A0521421B21BC7238CA77691C76BE86365CD20BE3D1C8AF7C559333B5F94A344C2891467A742BE4A457064AE4FE0355F2910A2252269C60A2DD723D5C242A055CE73B2C29DF12A629CA382E6789CC95F0AA44BB1E1710690056D507392C9C004FB9079D27A6695B762D80B6533A8114B6691845D7E92CCF189BDC4C32F06E986B2D82706F47819F807032BA5DCE871F355433CF05AE849037FB6455C0CABA5951D4DD77575832C4425CDFCC70536F741B1A4A1EC47B600D430DF473F2ADA9313F2AA9B972E7E68C2A2C84D7C9B17BDBC9AAA4468598412C9DC325E3B9D8C545B80E13767373ED61C9AD5C531F6C391F293AB7195237E3A2D77F2685C50B2A9E09AFC18C18678B97143BBD52823218A60A87B71F321429A5B7CE32A48D5B3A4578A9EAA45AA66E6444D534F4ED46ACEDC33325333BB986027D0CB05D93E659A6DD5A09F3F820DB8B1751AB32C46473B4284499B5165196871EAC3730C062BE3482AE8D969A8AB5CF3D1234859BEA98476942439E2180ADA967E4CB303F8D884FED11A4998AF1B2B1113A9878A9290F1E846D3EC68A21C8C4026CA25844ED1464074B84B3B51351DD5A7DE685BA338387EB6277E8018091CB7AFF0449540B896FA3A63C2BC9034A3D99990B0C34D91D464063C4D7EC08DCE0A493096149955B5E06773D790C618A881E91BA94D276E034497B433A65D393B3B764201583A3B57C9CFCA20E2526E4670725BC346B1330880D4A4AE348813956439721A3D1A5B7871622378CF73554E0D33905E8656968510E4B2274E69235FC63E0EF78745F99236C27D33E676A626C7A679588AC7998E2332B8E0A39CA33D5D099B087CC966A10C40F52A8CE89B905586A95C1C6C2521136516DB69AC7E439E000A97031B7378B99D2112AD69A5CE78C46CC2C6A9EFCC85FC3932A956AD313536F3A5B9810AC8BD8557528725705C2BD05331FBC20F5560259FA82D438392C7299463710357160F985555DBB2AE4438310E3879982B55F03018C17101C2556EC377B15FE6507488052CD2360B52B8CBC7856C8894CEA237E76214DA481EF0363C877294399CCA9E38C249392D61A2772FA4BFFD98165D24760BB90CE22614E892A9C7F350706427BA2257EA7A1304029A6EA715BDA9B2FD682C6AEC65F70018C26C3A41A30F53976AD8B83AFF7268F6D9B3124A15B94528024A179DD24B8C56CC8605914CA89815F943C1C568F255B757220AC606D06A1701457B057CA323DDB65EF076CDA0044CAC79455798B501463D38D24CB9C65FAAE94410F79995D917C49319E898AAD54C620291491F96362D4792BC3639B6551E5A8B7030E9870896CCF461B65FD82ED0F69DAD10BB60805C553A1A195336435303C1C8834C3A25C2832BF7B62E1B50C603951C12AB6B74EB72F4B15ABB5455D9F681A0D5A290C0BF0AE79B03973E3CA80D9ED283272592FD0A64938C26803441DDA5907BE52AAB1B9AE14B62F9DB044CC0C2F5F48F0B8348A6B26631433DFB00B180B721910B8FB533CFE4A8BE1D250D75A9CD492CA059FA115132AE5463577DE070C87944BC48695F3B4B04014E9DC29185446E4683AE2CF5B9B3AC399FB6C6541925075B7BCA7B7326861DC105B3B57AB55A8117EF69B33CF79665663D3355819DBBB235F9693D7C0062E5293C0A32D7342C18648500F8CB3AE925C530B6507418DA33A819E57897849BF3F36F6BD68287F7CF8B5281E9E5AF40BB5F76C63D4A14CFBDB8235C6A95415C4AA157568C34CA9F58B3991A756BF5AB9B658D9464AE207206D9D2049D9145B7CC59261860267806A23AA513F3C39CD7AEE8E71AE4B3A4A6CCC570F179148C2AA50BCDD612BD81F8206FD1334389B9A726208DB920944530CA839F316161B89A59350B2220A4B6C67CAAA2425D78DA2A3B454E396386C5500F7726AA38530B881640A6870D2E5100EC0C25D5A39BCA206EA5652B55A8A31CEBC84FA62F2AB6A57A2658240A0F14841E48340CF158BFC639149921632047ACE0CC2AEE5A3E0F647FC0C671F648C689002D98910F78B34E80C523F9073E4E4C9E6E102818E996D3A30886E7BCF18B69D2A16FBA1181610B6BD248035CB90D8D440F6D4729031B21A4E1237D710BDDC5040047745B231A22246E517A76D76A0EE7985EBC794FC5A51C17D9A9E9ACC471F89CBE260DF5C4676D870B8713BCA53A400CB9B4FA6C36DF97A023AC03B08C621E7329635C2E9828719203852970C2FD557348F5365CC917FD3CCF71D38D5D96336026C7D33B885526632860044237B4A6B09AD392414B068144AC67972B3CE7A25753F631EB1A03B4FA2E9F553302A22EB9C721E9F2BF74A06673FCCE5BDB77EB4B525D63906AB2C4E8518322D3065121A20546A8A4EB45F85881CE25721B0058C2334FFCF2946C7B9D6AC05806FA778B2041BAD1C1250883873A95E3D5B76A3480D8DA8B48683C5DB2757EAB9193750649E74440DC58A56B3CCC27B2A8177BC638B61E0136A215C8079666C77857018784F38BCDDA0C56639C03196B54CBC80B49B0ABA6F6A9DF352CD09C5CC6E05F62E835F7A125845BBA2FCAAE4BF61BC55AC98BD67763EC0214CC1B7CF91632960C9EC01E0F27A97F909D7FC2486D0CABFA146B72BAA14371041A5336C71305E6E68A43577BC1665C0D66C76A239095E13921C00C4AD11CDB69050F7857C3A1B70E2A2152EBCD0961A936F6146D6A58305086E934061AE32BAD1B894CC27949F280320401188775AA5078B1497315639288AA2F1F826B48465613A73C5301383B69181CF14AB3A05035A79DE39973EC5C1FC5869AF11320350C3C4208CC68DB8943A017215B72B3353B77003FB0D513BF677B81F66085E8205C17CDD6B603AC98310C9A967A7B99B8D3AF10B66821612333E50D72FAAABCF93612210572E6710E482702B17BED5ABB5E4A57BAF365C39B59DC7CBAD13601DE6B40F5370A49E5B48C9580A0C26195013E6B6889B99B7EE5D93FC8B795CC62A37CCC5E3DE2692AD66E903C74BCC45ED6F16A68AB17D8E5094680C428A242D2FA247985A0B7D7A300F70E844765DC30437D032F216A8D99DCC54DA34C0A4C25A8A120B3C32F45A3777467B1E639BCFF1BB9839B6B45C7895BCF62307460DF309EB4E61AA9CC8941418677001064AC161A607E24E15109D06641E916A660B3E7F849F08B9DCC32C47E4A7DF2D5D4A374D3E5718A452A96A70166E26D17A7319E8A5E12E38CA01A98D8A5813049A5BDD355A7D71347", + "ek" : "8D02ED2F5BE5FF56F209FC1200CB71A259EF17CD8D063AA82356ECD7AA62F0B8A08F88A537F2D00F2BDADE070BBF820E5E85AF9F2FDD012AF8BF082346EA8EF638A0A62EC0D98E695BDDC114395FE7BEEDC06CEF9D4896A8E9863B26160E351E45F8BB1BBA2EADCF31AC1DA04612C3D5431EDEDFA0D4F73BB618BC8EE6262A4506A3530FF474244412309138FCA6EB35C1616EAA429D376C0AFF0CD67765CBC91777550354647C0FE20F9C79E05E9D0AD32E88255D1020388EC81ECFCD55307C74B5FC77E14598531A7697B059D00CC9ACE8CB309DC24DDE7DE318A3A0A70B9BD067D461F1A134E90519C79952BF4E2A57322F879336D4065886865613467EB3272134AD34EBA639F677DC16B94F6C7CDDF9595DDE5F25639174723024DE17470B0F1E20F2B601D36249D589E690F929350A312A6B4C35538DB7603A9D3F25988CB03BA007BF15C3B9AB8D335728C76838F7863569B574E77DAE9B48276B6C6D042D29DE91C59E933CAD3C8CEA9EBBAB7DA4FC8B107F7153E37FC20A320FEB4AAB670ABDC594AF466005EB2CBEAE89B9C069D0F055A2414E7A058E332F1AB8DADD76786F5AE3F624DA50FF6164BB0E816F1C078A47916CA8C58AE2C45CC722CA2412D0632F0F8DC33329ABA08053781E956C05A751E9B7A533B4E72C7DCA299AD10157E75F03432BFD97C4A69DF69C22CEF208CFC1DA6FB3B31D76DFB4A0718941CC88A8AC39A1EE010EC4B898DC2B7AD57C153B8FFA6CF63F8CF9C759540D3200E095C2483BBCD14C0AE7C4E1E49B5A4102195BC4232C71CDB504FE9D0505CAFE4D7D230E7797EAD0C6487F034A87B27F19BCA8595145F48227BEE27514C83BEEC65E509A333FC38D3BB5CEB39A09BFA88FD10F8EB266C41A0D7F4718584494C9612AACA70618F17956F41CFF2D3FD917FCCD49489B51BC8B8654A96A8FE2FC66B88DDD4AC93DDABB76190DEA8BD18A41995F535A1DED2A2DF0C7D2D5827DD16C8D79C19EC393A0FC260CE9A1F09570A76B747C3C482B5494DC13F67F4FDA4F64D0800E60E0075CCAD02EA7B54184106E4A38B3325604EDA104551E321F56946FC8E8229F6A292240A92588064DAC295B6A4A11C7515586CCFB368BE33A47A101D7BAC3A10F9848D2C33395E89BB94023D6806A21BF9A0E69C4C104279F24804C5DACD0102D756A5FC6BA48E02B2C60CBB0F3845D58319D0FFB6A82BAE6AC36C60A67824429A97EF089FAB33C570542D5CE157A48912BF4E3F9718625A2E2AA61D24278A060CB7D4FAC4AD88AB917F336FB6CEECF5F52739A6D14D1184CCD812E81795591FD4843093A8C13FE8A8C2A79FF33FC29C7E8A35ACA3C5B6ABDFE053DEAA1B79286C2DEA97634E00508A80DA6038BFEBDB41C586E6A6BC81F3D3AA7D3671D69275A36CCE96C0B288101D1E92B7AAF2BB183CD5E29B334057E83E01A47DDF511F386996A015574FA37221E0086D5E1332C0CC2B107F8978A040BEBF37F7094CFA98DDC63530244F2668D10E1A57CCCA681E96B6B14BEDE10D0BBA599BEC06357D2210966D890182F1A1917ADA81CB27D0231DBC503C4A4C43956E12B542D919F3D4D14AA52FD81F20DCFDAB42E1C6D59ADC478EDFC90C77B4DD8B2A692E6825787E8184B3A3CB17930CBE6143BF3F960F13F60B1788DABD4A9F454296F0A8113D243BDE21EF915F47BEE9BB7A7D6B41909A10CF3019E770C49FD7CD914834140FF026B6B862BBBBBDB65669FCB0F0D8D5B7C2C97C2C394B53301975364CAFC6D0449C821B0254320D3DD59AF415911604E993F8B148EFA7F448A79920E30B7708E2A9067E8F77ECD33CA4A1D7FD39D0AEDB60890135240EDD134F963599EC646BA0CCF993178B01E364C8A6B15F15C2A926FD750C7584555014C57E0FC614A93527174FB5765EF100669A41F1CB67399D684318122A6818B4DB0A916A0C427F842999503F1DBC052511D9332E1527C58677013D85972730689643D350C1EA4E5B28D75630FD249A718124DFBB06D16878D12093EA1843F627C73452B7A30FEA32968FDB7B6CDA086F65B5DAD3F35F57246B0511E9EB49DF840633D687CD05A29F424CF526EDC0478C83BB0A76290612660C24DD43E65F9E2F93C9B3B943CF6E78E7211CC971A4B1530659EE8A1C73B890CF20C3D0E4BF5766582081B7B4C0D8C005C22A207B340E5ECB86A87CF933DEF852973B6D4F0ADD91049C0FC", + "k" : "1443A9095AC9097E84AB22DD99BD901693169F67F97C027E12922F0FA72B3EC2", +}, +{ + "rngSeed" : "9218943C51FD2DE47E509AAC67EFF176795102F37D7A2017E3AFD768FCDA7877AF38739B00FCDF227C2FD62EB635942C", + "pk" : "F7A1521DDB8CE3E91A2835A177988A4E856467F6CED236ADA9BCCE8ED885B19B862B952CC8A2269F35826A290A90C170B7F9195F816DD631B1CE66442469C42A420FAD3970EDEC539F11826A4A917AB105123B4C14087F7B2455202A5455159E828CACD84767E5B9C024F4AE6D37596CA7570FABBE591082DE627FE04A97F45409FE265054BBB57426B6CFE71825837B4BE360FF7B48AF3A7226525B77C450CDC4A483A17D77E723C8B1282BB40FB621731FB504277AB50F171BEC369818BC3EC22126F6A47CA2937F907890C7815A1E115143F62F58550A0459CE7E04695BC7737787A972321578222F5622449010287AB844E624699A1AB50BD872CB29BFD534B401E538C51C12DD8C467A14C24F5C9856234DA17AC5FA28870DFB70565AC954C440DB457214016E301736520B5E15538E92D1CB205776F849CC0B23211E6A67AD5C9FCEDA1577E625BD271587F939FB3ACEE14135613592A7364534C77C2A1564151C12E1C6A219B878180001E2C94053EBB1282C5288A707ED7B245F15054D87B901C939373244F776CA51B3B9D00628C9A8165993974BAC2C0B26715AB1A1B9706E8264A0D210A0E627AE60B59BA58A4ABBB61E93F0CF31230A624591E0D1A368390205D6526889640651B7CB71C26807B11913056629914FBB1BC2545B55B2610F992E73812E82B73D10A541A7C8621A4690B2C00149B5B952E91D992C52E8426448E5936DD41ED7725FF1C5BB54803690E7B642805B168829EE5696B5D51A13560A36409A1EA41F03CCBF6BB86A1B205BEC128EF81C2AF9701752FA54CB3784081B5DEC67BCEEA87A8864BAE5BCA2AEEAB4ECA30D460B4015870C0187B2519783FA030A3774277E018274775EA2BA027B8624C1DC569416A3117B57DC5B34A1056E4C9B1EA54B6E5F55BF1CD3C027CAC8F5F9B9E4C921D98692A007AC22C6B044F6AC9AE5ACC4AA3062A348EB2CAD9E77189131BF56ABA2D86612E01ACCC76B3222B01D30B079FF5250E0869545641213C175BCA181EB738FC7E80E989B43A0C4C7BA0B41404ABE955C3C01859DC17B35F48CC39E9C6FF84625923C1229E9B7C3C2CCFA760C8808B43225CE4FC96BF0C0AFFA26AA43341F7F14AA37BA5D48798C1661319B31325D04AFA0759C35153EC77B07D5D88050F5A1F55262860C94990460341C6EAA32055A480547BB0829D5C3398208018B4C098AC686F1B18870864E2CB0777A798C221A659A0E7E9C5C2936AFC4897A611C55086330EE1689F7817F44A6C127A53597576F37B35B4F74C535444ABF5342DCF256D04800B04361ADC83A207952FB81CAA20CC8DD07A6FE8864E562844882B405B5B4B65C948B237B385974A9D4963068C3E5B18C51D42A7A9211D4F274EE5208E530907DB49DB956B8E10977E2357223523A58B511FBF7993BBA3C38A95BC0B98062312A1C9449DDC4082601780EA65A6BFB1467A01D9E326CD10A8E202320D2A29E9B36AD09C44127820D6D024B3CE0C818234F55D7855B0B000462B198A669BF924BC81C99AE0B32A1C21F448AC6084C71A59A90FB43AAA73266E69A077D16A8D1443DE4C2B61C3CCC731437FF744B7A7CC3A02A948DA951D5763F078A991CB64CA7B049FA1B1EECB534509AAFE04437E5F84E974261957BA746705EAF4528B4BA3764816F45045D40E807C14C3577A25F75F69CCAA136CE627742E33DB588BDB5CC339EF916D7A9B108180A637586DA55085EDA466E3C7734F85E6A903EF0FC91CE793910231A8F46A7E084C595177A501B390EAA818C0A9FD37C9BE78160C7A398F0E80D8E58966140639656890CD08F7FE92FE316CB1E1517AE7741445A47C8EC3FF8F54F476146F1095F9973062BC17F6723542B0A48E12B7E4DBAB100F3BF6DBC219816A76A3109EBBA8C823CBBD9176061D072D57726CF12908747BBC267C59FA71F6C719CC7827B91919CA3793D03A73604E1C2C98CA2E99877B6C2B93C97965C06B2DFD71CBBCBC7C81CB56B36587A174E899306ACF88FD2689E345A78657C5C0B65B0F3F8206E405DAE4738A7061D54DB38BDB2AB87E8CB6DC93F2BA0C11B65712840B740AC90AC3404B69CBA2123CD335004D8E363EB08148A627B66B4142F66B18E460B59D05091640587212F4DD60B84E61F0DB00AC05B15E83A6E0ED3C2BD281161CC07676E12EF19A936D073D684C1491518BDBD426EB5A1463CEA8B67", + "sk" : "26C5B889FBCFB6F91CD0805FF87C89368C9CF82C43AA70C6F59B01E297BBBAF7B8C9332721C2BDCB0526788204E7674EB1E975E3E609C82A97988787B8BB8DAF49763BBC0FBA822A3DDA19509BAC10396261134D0402073DEB6B64EA8E0E98A55FA2CD37B14C1E27CFF4E64C52BACADC319D57246BFF7145ADB11D06CA87F2939478EB094A06361D65AECC8B148B653EE2C15DC618535903B26592C4C334245661830F15638CA13583E387D92C6CC21AB77EB3CC13969322C8521809346A873EE9D9B888B695F695BBA983645E22B1A6A30BC05BAF1CB49A51DC9EEB5C9C7077495E6800FDCA87D3A15AC0D8CC2F2BBFCA1626107B3C2A670039EC12AEC506E82040CF72BA510881A408595D22C88C9C8D0806A079FC6F7FC32996273A0496C61A22B9C87926AEF37097C947EB5875599401D1911B175A770D901A453CA20AF484E9735A27A7B4CD3B52A2409A567A369801818E22314AB369C1FB93A9F2A669F4028128BF3A929424D84BA8C0ADF7B111A45B1DC6430BAD947A4D19152709001C069E1B0B7C00A05C3C420478E05E49788E27D712AE99029037C2E3FB4172D0594D69CACEBC05C5D87A8BC91662071C3ED07D84F2BD477454E4FB37468151C0C346053A3ADDE76C9575386F63BF44AB4B23D3852E274CDA84712A28777D69CEA67463E563722C90A956057A922C72A5810B0E5895F09BAEFA947392725C4211898181ACF14815EB316855066145063B75260A4C281BA96538073971AC59BC5EA863161A7C0AECA766526B9C627D716521AAF55173FB8EB7308805B47C89A520404548A144589D15490477AC5EB56C62E441D728A808A2CA8DD74981D205C11813EA165E05B938CAD77BE34A0D1612CB2EC6C90E6283AED35065E74A4D9905713BCAB3A1105287162786CD7839537F186BC6717F1132054C482BA0765AB95CB2B4BC4E15704F5808108244BCC1490338AB97CC94A2A02814AD440D34BB7FFD753DD5535F6B7B1F35BB44656726229522E5890EE2F3AE36A468C3C7C21716411BB0C4FA11A3E2BAA334C149483A404E5220CEA6926AC56DD1FA856DB5AD60BB86F0A3CC731B8AC0C48CE98A90C6C20617C8C142697425A7B6017555C7012B63769D6D817E0A810ED84CB436A2CB9A2167C7A0BE998B9A42A43545697577209FD09A03D5C902E9082091D0C933665AE84068D3384066B197C71A07C4307FE9AA1FA17436C41550A0337CF70C68A9220DF0852AD92853F7FA25905B81C528BBEB8260BC10654589475B1883B77A672F7BBFE8B9BCF5F8B2C432994D975CF6CA8CDDC929088C2806FC49037B3C8052448B65812124C82CEC2601268F0E998BC41854DE6350F56B4C3D31ACD427910C8546921132E88A8D1F9C573388CFA3BC93F57C6345682387A69D4220B756F7546D5687DFC9586245B6BB08A9D68263E67C21135301AC1CA2C08A1523132C6CCA56B6C05C91D33C44BCCC515AB429D9A812693EB1F3380E69BE20FC81C76B57BC99498C52784EF3650BD296D6675C7CCB55B67A59CBC09D44D9499A6243140040F2E30D1FF3AA0CF66C6569CFA6D2CA8517A1D5C87FD0D0693EF20D8E21BA5A4A2BEBD77CF55698B1A09B2D05BBF7D973C5F5792B165C35BC17F873A9DD95A696929D0F3106BD685FE83871EC99772BA3C21AA523842138191527CFE7646717C65CDC2FA2A9AC97E818625455C2877346B378A4653AACBB1643F075762A9CEBA500F0283013269F1B970C9D01588A149C1D8823EB214E76DAB3966A622E815FFB22A39E2CB7898B4245A82E72557D51785F3888BEF9BB9F1FF3312AC32A0524115AD1897753325378AB94B50DD5172CAC3A453535AF258A05D57930C035A503F26AF358C537519FF53C0E602BB8266ABB0A1854524B5311D7488754B51C672FA0B3312E356A60C62202B1678C241438D22720963A0BA51BB4441BD3246ADB2511DCD132ABBB85C18ACE9185907DC3175CA0CC9681C52E91388AE5B4CB4ACC4183C588A43E08986E4CA45770A5A40913AD353549C9652D60D5400282040CE17AF243614EE4CF045B2C10B6845D8A7704D4173E5CC2B3A6439ACB9B2DF0901BC229C46945C2A81C7E7742FD96A71066118D618154AABB8E7C9C45B2436F132E3FD48FD5EC04F857B24737C4EA5C218F52C562345AF7A1521DDB8CE3E91A2835A177988A4E856467F6CED236ADA9BCCE8ED885B19B862B952CC8A2269F35826A290A90C170B7F9195F816DD631B1CE66442469C42A420FAD3970EDEC539F11826A4A917AB105123B4C14087F7B2455202A5455159E828CACD84767E5B9C024F4AE6D37596CA7570FABBE591082DE627FE04A97F45409FE265054BBB57426B6CFE71825837B4BE360FF7B48AF3A7226525B77C450CDC4A483A17D77E723C8B1282BB40FB621731FB504277AB50F171BEC369818BC3EC22126F6A47CA2937F907890C7815A1E115143F62F58550A0459CE7E04695BC7737787A972321578222F5622449010287AB844E624699A1AB50BD872CB29BFD534B401E538C51C12DD8C467A14C24F5C9856234DA17AC5FA28870DFB70565AC954C440DB457214016E301736520B5E15538E92D1CB205776F849CC0B23211E6A67AD5C9FCEDA1577E625BD271587F939FB3ACEE14135613592A7364534C77C2A1564151C12E1C6A219B878180001E2C94053EBB1282C5288A707ED7B245F15054D87B901C939373244F776CA51B3B9D00628C9A8165993974BAC2C0B26715AB1A1B9706E8264A0D210A0E627AE60B59BA58A4ABBB61E93F0CF31230A624591E0D1A368390205D6526889640651B7CB71C26807B11913056629914FBB1BC2545B55B2610F992E73812E82B73D10A541A7C8621A4690B2C00149B5B952E91D992C52E8426448E5936DD41ED7725FF1C5BB54803690E7B642805B168829EE5696B5D51A13560A36409A1EA41F03CCBF6BB86A1B205BEC128EF81C2AF9701752FA54CB3784081B5DEC67BCEEA87A8864BAE5BCA2AEEAB4ECA30D460B4015870C0187B2519783FA030A3774277E018274775EA2BA027B8624C1DC569416A3117B57DC5B34A1056E4C9B1EA54B6E5F55BF1CD3C027CAC8F5F9B9E4C921D98692A007AC22C6B044F6AC9AE5ACC4AA3062A348EB2CAD9E77189131BF56ABA2D86612E01ACCC76B3222B01D30B079FF5250E0869545641213C175BCA181EB738FC7E80E989B43A0C4C7BA0B41404ABE955C3C01859DC17B35F48CC39E9C6FF84625923C1229E9B7C3C2CCFA760C8808B43225CE4FC96BF0C0AFFA26AA43341F7F14AA37BA5D48798C1661319B31325D04AFA0759C35153EC77B07D5D88050F5A1F55262860C94990460341C6EAA32055A480547BB0829D5C3398208018B4C098AC686F1B18870864E2CB0777A798C221A659A0E7E9C5C2936AFC4897A611C55086330EE1689F7817F44A6C127A53597576F37B35B4F74C535444ABF5342DCF256D04800B04361ADC83A207952FB81CAA20CC8DD07A6FE8864E562844882B405B5B4B65C948B237B385974A9D4963068C3E5B18C51D42A7A9211D4F274EE5208E530907DB49DB956B8E10977E2357223523A58B511FBF7993BBA3C38A95BC0B98062312A1C9449DDC4082601780EA65A6BFB1467A01D9E326CD10A8E202320D2A29E9B36AD09C44127820D6D024B3CE0C818234F55D7855B0B000462B198A669BF924BC81C99AE0B32A1C21F448AC6084C71A59A90FB43AAA73266E69A077D16A8D1443DE4C2B61C3CCC731437FF744B7A7CC3A02A948DA951D5763F078A991CB64CA7B049FA1B1EECB534509AAFE04437E5F84E974261957BA746705EAF4528B4BA3764816F45045D40E807C14C3577A25F75F69CCAA136CE627742E33DB588BDB5CC339EF916D7A9B108180A637586DA55085EDA466E3C7734F85E6A903EF0FC91CE793910231A8F46A7E084C595177A501B390EAA818C0A9FD37C9BE78160C7A398F0E80D8E58966140639656890CD08F7FE92FE316CB1E1517AE7741445A47C8EC3FF8F54F476146F1095F9973062BC17F6723542B0A48E12B7E4DBAB100F3BF6DBC219816A76A3109EBBA8C823CBBD9176061D072D57726CF12908747BBC267C59FA71F6C719CC7827B91919CA3793D03A73604E1C2C98CA2E99877B6C2B93C97965C06B2DFD71CBBCBC7C81CB56B36587A174E899306ACF88FD2689E345A78657C5C0B65B0F3F8206E405DAE4738A7061D54DB38BDB2AB87E8CB6DC93F2BA0C11B65712840B740AC90AC3404B69CBA2123CD335004D8E363EB08148A627B66B4142F66B18E460B59D05091640587212F4DD60B84E61F0DB00AC05B15E83A6E0ED3C2BD281161CC07676E12EF19A936D073D684C1491518BDBD426EB5A1463CEA8B671C02B230ED109318CA7C1470F5A0AB154B74EE3990FF20CA8CCB835ADFDA4867CD2DD7A1BE89575BE8C14529BDE4D832CC005DEA955065C08B3185B215DA3A2D", + "ek" : "14DAEB74CB47B8DA7EC4FA8A3BABBF2FE450DB5D2812AE8BD1CFFDB861D31A5AD46D95C0C9917B6141456381501FA3E71B623E4E9D7F71B8CB9C7E219B821FA5BF57E93B80ED2AA65C48488A26D1CD8B2446289E59AE2683FB72CF05F25041880D8F22FE9813EA14B4D5B72E36BAFB4C25DA4E4F48E92136FCADA4601C7B731A68F68201FAB1ACC8C413986AED98BB5B83CE429FC15C5D78CCB659A12CCDCE5662747F08BA2961CEA3DA534F343F03D9639409D3B1FCA652FD2A42DB64527D4309625831E04B6C6568B71CA5BE949B0E803AACE2C6CAB33F10B347FD0D1B04E7A3C27F8D7795E45238DADE4565F8D15E268A51A6569AC60A204AB00D082F54DF7E732098A277D322BC4C26F7AE931597841D90DA35270B8C447E55D5A36096CDC5BC161D106F7A81166DABE054DF532B5121389404F7FAAF5C7E83AAC7D4FEB14A00E101020998324D41936248ABCCEFED27901F514CA675CA198DE07202DCC98D4101E90CACCEF8ECC18AEB98F9C2184DE7B2082ED131C55AC495F0A2A9F079C9B54B79CCDC0BB28B23AE837A4EFCB48910811BC98412AA61146F64E1F5968BD89D4FDACAB8D3AD2B6EE9E04C31C051200361CD23F6461FD05FEDC3BA9DE9D31BCB97CC63753D59241419B97CEC043FD80CEA21358EB8446BAD2426150CF7EA48676CB9413B5C5086C0988DAB6EF819AB487CEB11ECD6D15920BF72E40E2B71A0E257882EB3DD0B7590A37DDD66E074EEF7E9A77DC87C2642C3EE3E1D0EBFB378F2509EABD6AB86EB457E52BF55BDFC9996970942FCC6DF2DCEB37F94FC0046CBD2C43388CF949334E7DD54AA64BE6B85B491F23F2786C662F4B3A638FBD3AE1EF55582D19816904129117CC8062BE57927CFC7B87924F55575B49B18A8BF9B653D331A723A481D2946901191CEDE9445AAEBFD1583509AD61EBFA188308D3F6991F57936EEA53E9D9C4E35E37084A6FB0F5B60569569C3B3B085BB44E681316B9B552311D32F6BB04DFC89B21A10152D75DCD57B8C57D1254707A9A6A006D4E6DD7E3E1900A43EE9030144ED000F0B34BF6D17DA6D09853597CB774B268B91931D71008A5373AC8D38A491022D9D6FABCCA72D562742198D1BB34CF20B47044642A641156BA2E0FBEC384A950C85BC0A1330BB73593A759CFD5A7AFE72EC2EC246D6846A968BC1CA831D7322F8D8A480216F6C3D80306179D2C6948A9474B1938A3BB02F511744CD67A42991F157C16906D3008E46F4B1A552501BB69116BD1AD78847AA8A82C3175EECB06D2B64846B4F06A9886C30726EDC46BB9665D17048C4F1628AEECF8D2F81B957C32F2B28AA88515862198D88B1DCC1703008D2DF5F36E9DFA241C377A533C19D8F079E26CCFEFD85901C4625F511462BB166CE98F194474508CB8B9FE7E32C147662C028EB8FB8863A3240C2FBE4C4140438BD7731B3F744D4C7DAE088C1D66459B704C66759B179DDD26FD53C3F23B843CCFBF8613E7E4F2A1A8B9E09F074CCC7E9696B7434BBA61EBC9E54E173320DB7A785773492FA53AC24A00B2A097627A2339C45636487101A271237DFA586A049E04A4E9ABD941EEBC71C81EB5A8ECDE70FCB07CE2D702C139D9D3637B9D12EF574965CC0EB326B8F38F74687548DC91910340D39AAF820BFCF924D66304B7432C66AF1912F4C0B66111312B7FCF704FF88DE0093EE6552CEA65A0C199CD7EFEDAB72B75D4A1BAE8EF2DF16F31BF6BF5EEE9979FFAED24E8482592D0A90E9635B7203495E2A964BC6D2AB0418B503DC45C6A7B3349E0B6EB0F2973E4DEA8C01E2E021A450AEC44BD67CB9CF4E3055648458F2377DD5724CB1BB957A38BF1F5A0A8619F4CDAC97D3CA41290242F0A373661D5DF47E7B5C99AFD4CB0A69CE898E74AFC3684C2B403C5DB39646EF1F4731E95D1F61570279A2C62E145C1468FB5D1B143CB834C31796E6B2F428C73AEE8B3CF5E6FAC09E425FF33A442AF5A369F7ACE63790AB5A55D3BE3645577007C7E202804C61016A52583822DB36E49345EB15225B20FE3D35D0AA9BED65C309EE4C65D8A900FF64EBB8762A295A0E0ABB84727C1C93AC23D2CA9A422C8BF4A97DF1D060BCA345A0D1AA495F3232DDB840C8CF6722BD67C77CEBC5EB3007CC57128423DF3F60866ECDACA6E39FC9DD4B66B6AB49F412FAB6D888F81299BD4ABB61E28E57C3AAA5404F5405564F7D1CCAEB896893CBA6", + "k" : "DE32692B69E9F523C68C58A94A1146BD5D0161BE1F55B78BAB3E64859A96AC03", +}, +{ + "rngSeed" : "542E20078ADD5296050AF150360F057F6B9AB3BA835589DD56987DE805F900B906505B5390A0D86CBA28038992DFC59A", + "pk" : "6F161381CBB8FF776B4299A36C893AEA783B541B50B2C253C088683AAAB40ED421EB113ADD58B322FCCACBC9AA91B74FB0657E7A2706AD9C7C7F7813BE9008CB07980C310F47C764B4EA496AF60E8E6A534CB49852A2C17B4C7BF096C52C72264B7855B7A5552AA93D9AEB47F5AC34E340A094D411CB2CB962B90588A1B32DD68B662060FFA2AE2999525424114ECB4905A19A1284928ED8C42A2C5461520437F93D3CB76502201412A65983DCBE4C70B9F9320418421962005B39AC65703442002D52D18A83B08574895C0EEEF19BFEEBCFCC7C308F960090E9BE93A01C36044220858F671BBC04F1A7557897DF2A51ADF85A0F7B25F1480089855F1A150BD8207EDD0C63DB7B99497AA03EB33A8068067D43A24957A20FDB6E11942559087C3FF343A2F5503B33756D55C9B9F29F6FE83D80CC3CBE9A00E8A31D0B986D1EF7635CFC1CDE434F6C826BA5445A5933845D1CB8047A8E2F263E1A86B4F58433C5318E6B86942CA92CAE767E2CCA9111BBCD8B582A81AA5D22AA29DCC21F374A96E55302B837AAB8709202141324386FF7F9C7D2EA068B057CF6954E6A433A5502785BF43EC8854EE7982002C703A0D6C35EE79A316A1FE3148B0D933FCD450829746C70E26D5B7B4792C40EE5C51B80CBBA439C212F1C66CD619408D654AACC9C1DE097A9D03478351E9A377E08710263728C08A71AB3DB7F4A50774F0B99C8306F7D39C1AABC4B4BD64356476F85D6945A404DF00B2DA8988BC9F6B34579447DC3BDA9D1A686E2C8BA67666F179F77217DAA8CBE47A40B154C16A773627AB06C66B5C291B8616BD675C0351DB13938C0A22C874B33D7CC128113642AD1321E5520A636681AE188F962A793B072BADC69316B96FB591A99F53CE160C1C9E56384925AFCF5C2DD74069F89580B3C18BC15AB0C91578686CF801B25C56C3E37847BE52B5869C2B3F03B9B5B6AB0D2B5043E56BDDB1C793D2C0FE47544E61C12AC0771A48C8249B3649D77AD9A4BB5D20C3CCB0AC05B51A0D1E29CC791677693B2D96B83C0D599E46B238063C50C7C101F3B3BCBA18FC4DA9D71B23DC133148417C2F4369B0C92855E538245F44496413C741282F5D7B1482167D90536B89165226AAFD7E8AEE821B22F69B963A87E4BEA84D5CA3040464E7293B1BAB723DD393EE3606CA2940431502F56183CDAD305EA19CC3F3974236310D05220F233B383C5BC97EC1544A8528C1C74A6A48E9B9B31097477EFA632BAA4BC6A8ABD6CEAB5D774BF988B7D708926275227BE2C416DC90FCA4720437425AE9B4769443472E2B54AD8924935BC0F65A4740699F2051C1E53153CC354527450C8909366F696C8A323A300A28388BDBBEC532AFC1580FAA1F7821C5A6988D8386265BB9DC1043C5EC2A1C51A35EC910D80A1A4C41755FA669A89E05DE79B331BF13ECF88BFF92CA340D5B961F446ECA336AF53A95173CBDDEB643D4831C2F563950736FB912BBE370DAFF28CDDC319EBE86958FB1794A97001A14DF90B01B3AA0C6E952E79C7AF072905F552487BF255E1F61536DC93824C7709492BD133516AE71C1B057CBCE6A4A3D48B0744A5CEB1604E41A378E53A9AFBAC28C3CF97B1B03B31797C40654FC23666C34F77207639FAABCE69C1E98262AE22CA956BC043FB6748F54310379E975958584579FBA4BD50E04B739020DF78849ABA007A4A23DA8A18D449194073903D1A3EA4F43E0E76B299C233C5FC8534D831E69475AB6B611AB02DA3251FDFE6B92475041F7814BE839FC39BB06912799C553B4647A7073482980090C2C9A96B2866D6D8B65DB1172BC062F3490B708B239FCC8A39E8175924C930825916386B463B645B4832BCC399B69A812A992D09D260CFC964EEF5C883027A2D44743FD538D05B3417A26974BB639F494131803B10678C725A389AA6ABEAF83BC947C6A3D031487488C72B1700B76F25F42FFFF6595D87426B67258FB6B993508189E9B37F16C2EFE87E3DE705FF794B0A50CB7D8BBA4059AE2E3AB4297429A3122C3E0568A64B64A401ACA8BA2EDD807DC0C0656B60B027290D23BCAD4BA71DE7F9989CD85FF43A1FD519B7EB40352D85B940208F9F8596F1946DC2366736A345D9C7501511101E81928380591C19868128A921E56383D12F19446577783E0B1665396C56CC9046C4C7C08A569D8EDF0B76096E3C0643E13ACF3D522C782871A1F0B31CF8", + "sk" : "DCBB8186F46C07BB4D36203FB6C89A5A487A0D16C2AA674A1B7A4724176D0A3A3EFA4C42A258C7566B39EE2172B36B8102B900327B5C97876D2DF233951C6CE26366C264B4202508FB4B37FAB78977C76CB91707C32B41AE916708B108C2C303C5958C3F8A84C0B44ED504AF57E31BAA864871871583A98C4360A8B467AB78D16715860E4F112F4CE4A203E154E78C29AE4035F6A6B3DF33A0118B6A70D5AF8D9A95C65A6C223398BF541879351943515DB63A4C97F7255171CD45C34C803C02668C73397C4ADCC7874B2346AA6123BCF9050C22942FE7605606B745E6B375B35EF4B3BE364353428ABE7B29A9C93072E24B6AF7904D87224B4B877A204180DDD63281D7211C17B8DC2AB00B5C71CF086E79B99CF1F7834E85B7C8E403B5E09C15042F5248C665B6B85BF84168D0165AB990EECA036E822BF6499F47B6162261B29F44644C78200A09BFADA808A8DB934977956FE026AAF342CD768D8F68AB2ECCB64D67710995CA46EB10EE5B54D05925019510405606633538E45C91CF5C8D285A42EEC3CBA21509356CCA48633E40B26AE5689E51A618B8B2481B780F071451D6C641911183184748185AA629B316139BBB8B666B9D165A24280BCF695B0D7A539A7950B0F133727141618605C7D8311EC5C61D153BADB14117A502F353570C051A7975CF3E0031389AB13409A699AB4B8711C5B5188D71D4195FF54A3587B8A965280326AFCD609E7B133DA87AB115E63963541E512A6A4966C9BA569F43F68877E9C7659A7F75011E5C9757D6AC23782B9579032A2D83848F2966A5E007464C1F26510589269ACDF80D28640AAD02142D0C02368203C80CA9D6274A66083B194200DF05473A056B20449D68D5AF4AD617698C1126666276D38368AB87B104158E0C025DD5B7F8835E9757929C75814179943F05467EB6984BF4600BBC99CC7022FDF21A174BCF7D1504A69AC7693C175CC1BB3AA93DCC1C0599B73B1FE8CB3DAA93CFD63DBA315A5BD84D5E13B59CF15B86539037565B4E753BA075C9DFB049692525A015428F07B8AD5B3EC2BA89A4691615115B647CBDC9787D3F51109FC42A3C6005FFF13AC191883C2683C6F45143E298ECD57F63C9BEF9294D7A6A00A2737475D46E0927CC2A3C172F4A2FD960470BC4CA50DB3B6AD5902508BB7538B7F9A9A42922104403A0D22BAD7F36033C91B6ACDC03205CA685E144BF72278EFBCEA55C7FBEDB3798F0C2AC2969E4A9C742E6435400A9BEB5C2A7874D971A36A278AAC25113F382AAEB0877A2241FC3B089E929B806D72613007924C65C72611D243B00554A864367CE38A1842797CC5D4270F297647F1A4BD87236DE55C6F3D1343E26708A623B8A03C3D3043055457A574C9B7B6A013D501189828C99A33D3FC715BE7CC72E27CC8B0A397B95A79FC5B78BC5179BF1CE44F71A5D699BA34A271CA67409C115BC67B6A7790D384026246AC0D5FCC0D0F5B92AD2CDFE9C5B3DAB52F07590EA07CA292CBFD2C44321C4687C385760988C0532C3DC237A9EC0AC139783D5CAA0EBC76D0C25A8C1A0BF1E1CA106466548558290D2683BD69CA296711072C6DD5B95040A5B434B8193FB0C7B0496F9334CC86528CF04B77E3451AE590CBF2C0C55219EE1310989AA2FFE7B3BFAF09DEDE24A86B765FDB9045919C2C70965F581AB16A90AFBDABD46D21EDB9B3710C392F1F8115DD12377321016E96334491BF6B4A5F661797E92926551C006DC5A5DB6512DC91542F017BD1976068386435A52F6684A0BC257EBD0869F72A5A269A46E5AA608D1A551C8192A7349885B95B3CC38D2D134442C69EB0655D9792EE8D3518CD7841B0563198A9F5526B925D2A02A5B3E7EA358CBDBA5B1D22F9416915DFA2D9C399FCDDC1F70A99E0C534BCC35382F1B4B4283CFD4575A3EA10BA05C77F316ACD1A7459EB40A663978114425E0740676E483C9AC833F881523427335796405F3A0A52C8EADB3952F328A0F5BA2468A594FF00BD673922782B0210A3D97B546E4D3333A7104409625795016E9DC57A7E4815268A06273CFC0866126605110163D6DE117B551C986AC4613D24AAEEB0209DB97BB734DA4AB0C9DA2ADFE1A058B88B2E5311118279443DA1859B23A814B6A10125C7C2A7B2686465840CCEDD31980F00786191AD330C36F161381CBB8FF776B4299A36C893AEA783B541B50B2C253C088683AAAB40ED421EB113ADD58B322FCCACBC9AA91B74FB0657E7A2706AD9C7C7F7813BE9008CB07980C310F47C764B4EA496AF60E8E6A534CB49852A2C17B4C7BF096C52C72264B7855B7A5552AA93D9AEB47F5AC34E340A094D411CB2CB962B90588A1B32DD68B662060FFA2AE2999525424114ECB4905A19A1284928ED8C42A2C5461520437F93D3CB76502201412A65983DCBE4C70B9F9320418421962005B39AC65703442002D52D18A83B08574895C0EEEF19BFEEBCFCC7C308F960090E9BE93A01C36044220858F671BBC04F1A7557897DF2A51ADF85A0F7B25F1480089855F1A150BD8207EDD0C63DB7B99497AA03EB33A8068067D43A24957A20FDB6E11942559087C3FF343A2F5503B33756D55C9B9F29F6FE83D80CC3CBE9A00E8A31D0B986D1EF7635CFC1CDE434F6C826BA5445A5933845D1CB8047A8E2F263E1A86B4F58433C5318E6B86942CA92CAE767E2CCA9111BBCD8B582A81AA5D22AA29DCC21F374A96E55302B837AAB8709202141324386FF7F9C7D2EA068B057CF6954E6A433A5502785BF43EC8854EE7982002C703A0D6C35EE79A316A1FE3148B0D933FCD450829746C70E26D5B7B4792C40EE5C51B80CBBA439C212F1C66CD619408D654AACC9C1DE097A9D03478351E9A377E08710263728C08A71AB3DB7F4A50774F0B99C8306F7D39C1AABC4B4BD64356476F85D6945A404DF00B2DA8988BC9F6B34579447DC3BDA9D1A686E2C8BA67666F179F77217DAA8CBE47A40B154C16A773627AB06C66B5C291B8616BD675C0351DB13938C0A22C874B33D7CC128113642AD1321E5520A636681AE188F962A793B072BADC69316B96FB591A99F53CE160C1C9E56384925AFCF5C2DD74069F89580B3C18BC15AB0C91578686CF801B25C56C3E37847BE52B5869C2B3F03B9B5B6AB0D2B5043E56BDDB1C793D2C0FE47544E61C12AC0771A48C8249B3649D77AD9A4BB5D20C3CCB0AC05B51A0D1E29CC791677693B2D96B83C0D599E46B238063C50C7C101F3B3BCBA18FC4DA9D71B23DC133148417C2F4369B0C92855E538245F44496413C741282F5D7B1482167D90536B89165226AAFD7E8AEE821B22F69B963A87E4BEA84D5CA3040464E7293B1BAB723DD393EE3606CA2940431502F56183CDAD305EA19CC3F3974236310D05220F233B383C5BC97EC1544A8528C1C74A6A48E9B9B31097477EFA632BAA4BC6A8ABD6CEAB5D774BF988B7D708926275227BE2C416DC90FCA4720437425AE9B4769443472E2B54AD8924935BC0F65A4740699F2051C1E53153CC354527450C8909366F696C8A323A300A28388BDBBEC532AFC1580FAA1F7821C5A6988D8386265BB9DC1043C5EC2A1C51A35EC910D80A1A4C41755FA669A89E05DE79B331BF13ECF88BFF92CA340D5B961F446ECA336AF53A95173CBDDEB643D4831C2F563950736FB912BBE370DAFF28CDDC319EBE86958FB1794A97001A14DF90B01B3AA0C6E952E79C7AF072905F552487BF255E1F61536DC93824C7709492BD133516AE71C1B057CBCE6A4A3D48B0744A5CEB1604E41A378E53A9AFBAC28C3CF97B1B03B31797C40654FC23666C34F77207639FAABCE69C1E98262AE22CA956BC043FB6748F54310379E975958584579FBA4BD50E04B739020DF78849ABA007A4A23DA8A18D449194073903D1A3EA4F43E0E76B299C233C5FC8534D831E69475AB6B611AB02DA3251FDFE6B92475041F7814BE839FC39BB06912799C553B4647A7073482980090C2C9A96B2866D6D8B65DB1172BC062F3490B708B239FCC8A39E8175924C930825916386B463B645B4832BCC399B69A812A992D09D260CFC964EEF5C883027A2D44743FD538D05B3417A26974BB639F494131803B10678C725A389AA6ABEAF83BC947C6A3D031487488C72B1700B76F25F42FFFF6595D87426B67258FB6B993508189E9B37F16C2EFE87E3DE705FF794B0A50CB7D8BBA4059AE2E3AB4297429A3122C3E0568A64B64A401ACA8BA2EDD807DC0C0656B60B027290D23BCAD4BA71DE7F9989CD85FF43A1FD519B7EB40352D85B940208F9F8596F1946DC2366736A345D9C7501511101E81928380591C19868128A921E56383D12F19446577783E0B1665396C56CC9046C4C7C08A569D8EDF0B76096E3C0643E13ACF3D522C782871A1F0B31CF8E5A656D13CDB067DB3640ACD507A2FDC583369EE08E235663A202AF6720934C39508257A83CCFFBD0677795070695CD40D7B7F39A891D25E7E208BB9D65AF538", + "ek" : "53EF1139C22B9BFBACA492606D5932FC95EDC0465B12945DC95EA934DAC315758D559C9D83A9C4127ECA4D97B5BC46043CB0D605F3F6F407A28B52AEC914871FD200F25299D56F4587D75383D89D61CDDE8468D8BFE096D87E0356B80D57438D6D8A163B04170BAA42DCC45EBD2C2D423B8340083D7CF774FD4480F23F14C9D24C30C27D254BC37A0945C3AC48803F75A2AF1607C60C0D6064A64D7A3F774D8CBD51F5DB8709603B1AA212290B9D9BC63D766B64238F2DB525B399412806506D9A9F94C6A7A3DB444FABFB236CEC140F935C3ABBF03D9DC8A1FE877FF061B05D4F66666A6F7109DC70C1BD8E36DC00978CEEEA2F28F0D497DE3C626C74367D83F0579E0A9F2A5E0A3AF905EA644F0E17EFF7D5127B3FF1E7D9C04E07024F2F045EB658B8CCA2D494B6439B123BEF7B355AD7380E0B3FDB05F37212ACF52A7C62A1A194CAA29F18D0ECDD16DCBE1995B5B21BD899AC6A2B8BFF64DF63D076CE07B33B4EE61B5AB1B23158294F3419F76581D0DFBF01B1102D98A58D547AE63DEBA210E499CC81EA72688DD6DACA93CBAB033CD977772A006EE23B5463E339A32EAB5458F205922A3B37C573D1CDDF45557D576B7FE103E0BE01AD2FE0BAD903FD2CAB7D4D23337C74C829389AB36D98B5A8927489654CA61230EE7BD0C3F48CDAF49CE46616C8206FA14B23CCE3F440CD7B2DE0209C6E212C4F284B3E92CB9875FA9393380180045E16069559B7D18240A939DE6F1735FA7F4C29A9CA9D1D8ED93377CC98049BA43F2793F018ADC967450BE75977A8CA6FF588DBF90B3D2E130B351FD5EFA0D089E5B4EE025D98F004EEB9102A2868FA5B746A35B485D633432403F4DA5322DF9AFD53C798244FB44CFF9778A1FA6AE608CAC0123866C3DEF219FBA10B5909B9A69C23F774269F4815D95E79B252D8F2F8B7DD6E2E4DD3D7259ACA7A6D5546D0673A5431E623C675AE314CEF8D786E41A4A0B35D842F2A30068B7E4134205FF53C3B9E1E8128EE33317C584C2708746CC27406CCE5B53E57F466FF45C34ED40597A422BAC0F9100835B3A9827F656EF7226422B7C995F87DC00EBA1371B4675F5033B2E28E0A5647EB04C06D8F903259B51517A027D7E12B5BDEA548C9B0A0F2B9219DAC568D9A487A07644AF4E56E8DEC5267528C3F878E930F2CFCA01515E74F81168B39E22B832FEC893A26DBD17511D2E73DB6E56A2E3D4E2B0EC5CCE31941532BB2C2C3F10E12B7082C289BE8E18F8C9ED6C406B2811CB11BBA6E1E17831EDDFDDD9CD311DC7B81BB06F6C5B921D02AC06C85BE516649F7D7564B13CD9947A17A9754F2FD9056CDB4885D8ABF8F639D544F16EE6C64B20A4A335D8CCA10684B1F1B1C118787B5ECC9FDD2828ABDF116AE2B7EA5FEBC571F18465ACFA186CC4B4C2BAB128D7596CA72ACED7FC93BC0678A3914320FE81FE6702967FBC1A6337ED3F923BC42943C3BDE9EBE61611C3F8FB70A6B9109C2A218E606B94A9809B7CAC421AADC1E78397A315436BAA4751A6DCD37444F0673A624A155DCA20FB4DAB9F02ABBA5D752EF185BF0F0AEF020DD0271434D06A93857D551C8BDD0F5C0407A80A833ABCC76F6DDC96D6E8C35DF4B3E7366F077AF093B8EF38C90DD60406FA694E94419BD6678E74CBA9CDF1FE3262DC982E777EB9C6422524D5FF331B6FE8696A0BFAD84BA41F77BCF3AA77D8BA6B18B09709047747F365FAB71D90C8150BF6F65153B95007AC235E782154EE588AA3F24340022789BC61B962856BAC4D69B7077D98BCC485AD7B921DC0B81400F0777D4E89DAAA170C4BB62F202B9B94B8637B69A8FEA0DBC5BF338D55CDCE1377EF5DCB6E26E8D0C915C075D452DFBFE0655CAC0895DC2F42A45F715966430792C1E3BE8B29A0113C550C9FAAE2D84FC6C9A3186238AB4529BE3CECB3B9E7387EDA78C8A0B84D8DCF78C62014E95E523BC2AA6DF0F91E8805A89EA8E75AA2D3CA0646A28712F0B8CF3E88F5DB7EB2CFDD076079F73F9CCDEA0357684157E727011F6AEB804B0B3B41548F49D6184B64B0101EAA1CB2B0C76B7353490FB2086B0BA8F00679004D953A4C4587CAF7B4DDA7D9B91E17A536CA33593731594EDABB43029D721A288BD63EB9FA9C601B30C8ACE502E4C670DF8CAEF5CFC38F3AC447D4982F1810EEC225733D6CF66B47009BD7BFF22A61FF796DD05D663C51179030F8A5600125CCC9FE652", + "k" : "2AFDB00EC81050357494BFFBA137CB2C9665C29569D33615023BD21DAECFE86C", +}, +{ + "rngSeed" : "6A85A61DD08C0733FCBC158ABB49FE0B0D96A50DCCA140A2E9F5A254F1901985844613B1C656C0CB0112620591B88AD0", + "pk" : "81FB1C51F687AA1438A329B100805F99F016D9119D2D06C1A6978569E7C40CAB47CE5CACC4D35AADD89047A3BF7175CD8833540B8A028C27461D334B3F8680DAF57313D7713A35075CE971CAC3CFEAC02774C3589C21232D5A73D959705BE77C3CA0884F8A1C3A89A1059972F115257BC0CE9F13271FD73E7293BF944B82865986A5D56E6C9C825C83271F42908C0953FEA66DE4EBB820013FE9AA9522AB4ED66334DE641F8E66766BFC47A7A5156C182C0BB3628B81B59461B05E3A11D945B36A3923B12ABF8F698D1234593D0C784633CDAF09CF8F4148F6320B15C48AA81B1FC3E79FA4055599935E1076C8C1780B1910AF4AC9652249B0C64C94137132A12AB62DD265334CC46A3444437A74B076039F39BDCBE2016D8402081949C8E6066F09839CC0ADFB5215590AAB10C51BB03B68701B0692D1C5C47C58D214B139B83562728B3A771F25CB7638077C4B6B2F83B11DF2369EBE9B4E51F36BE72BB04E1B591852AEA0CC31D1A774768940D73801B8BA23F71C542C8C01559862AF4950B7E21F5D4ABC3A1104251574E5597076F971B46C370FB1858A1CBA35353D29A23DB9E756C57A115539824F5375080990B3835023F448A2314D08C6897DA5AE35325F9A6107AD4CA05D653BA78C5769E51B368C200543C2A2884A2D504A73827009D166218A981189B5556B38DF395AE007772C1222C3E2778C34774C87AE0931BD116C82AE33B3454808E07CC5C6D16C5108C155A451E046260067C6FB0181AE084588017FDBB7AE63E96321290BDB4B3867074E6E684B700B7D5B1074641C5702E287D257B8A54597667C1CCC702F735C30BBAA84BF405123602572962ED89C2D7A3817AC4879D1392F9199C003E63666F1CFC6F91CFC9386B18615BD36913F010270E8A4A9A99E772CBB994B4CA926BF8A04CC1C20C885D2683301CD8C7B381190B0E3DCA0D6C33FDD49465FD265781A16FBB546E9B6C6CE0462C604B9FFF09CC2D4608259284B8A83A877B9FB18415CD60C37B0B3D6A48C803A61B0A5C9675018F64A013062440F0C40C62055CCA7BB6CB9A293193485FC529922478E4C620A73144A57833D3B5B9BB222F2F4B452447CC06638FAC1B4404402449A3CD60BCB2FBCCDAEA42086682AD7F972008276E4E5449217088B485CE6757EB3410C62796D0E7A643A3C72C612AB165475F6E51456D498E858AFF563C1F7781035FCAB3C85CFA2F207D1E4703D3015E14689FA0C9B1F57984B678BAA10CACE44A2FB23BC1F317D5304552306183435C62012B2CCDAA9A744575F959B57B9CCC2C28E1A94959A812DA6F259D11479FBBC97F54A57A986BE61F49EC42124DA687221AA3EB3B2C0298249746B20CBA291F1633E784608D5897DA13A20EA377DF6B95198132A7FD526D065250F97525D809BF9CC7270C7B723CC95DC9C8DDF5113EC4C8B3CDCA07A7242034741A3CC684A998514FBCCC435A8A2D92675E6C3F252A7019A74818689574C6AD907080954557CC12E1D47CA23240B78C2301F39C78127180C268B76289132AAB01F457ADFA649A4324A08E0BB5345CC2EF90FE6E33588D6ADB499B04DAA642FC01F5777BEF8A7AF04179630619D13BA0991CB36E8C23F16BAAB09A72E7388C93385331F7B5BDF420F1E75C7AD28C54DF96DF3F1086FE4120843AF7C7878B4483956B022AE05112253B97E6A61780CCF4047589EA04000D57593622983E8187A6232DEEB59F5E147EF1628A9F692B8BCCEA069CEE6F49533B7301728A3FFC85D7DB98398CCB38523254F843DD79BB58B4796A1FC6D68095B8FAA7FF9381D01D61BD6694F2C225C46086031A86105661033948C29278E422B304DAC9817401AF89540A29A1CD6093C86A3878C226FCAE156B85038F4AC53579143F2F5854F825B0D45BB974B724368814A9487A60A6E41261470935A90EBCF45B53279C67D92330556E99606DC22A2419021896B2EB750B2479AAE7A706B1BBDD9514173F23DD3066161A0AF8A6A9EF6AA7EFCFB1306B9C421F63BE2E376F747731A233A45A8309BA8182D24CF6598C26D65C89DA9C9E9E6B9579A4817552A8D355EDE798E09781B387C9935333B15D92998A4C736D266DFC2AB61708FCAC7B821C01044492F7F4BB8F37B5026790F3A437CFA63AF88341B95A8899AD31B37491CE3E42FD9B3701A63D537569B75A6B4B362C14F1B4BA66AB7914C9900187F1057", + "sk" : "7C12448F6C47D923C2ABE1A0D6F5259B00B5B0F84304FA9192C5AE32FC6E7D0C6D2CD2162E121C4D202A01D0C471F7A959F3941FE56655F808C139B471827D24D97464993BB77B69A45B0380A666874804DE793A2AB31D749070BF174DDC8A113B50C8D11037DCEC6EA71A7A37E84E133551494A2CFA01BFBAC60EA3691B60312AE6707883C74FE70954565ABDABE07364DB5C76FA2AFDC234C63B39FBB597EEA25FAADC07D326BC06918B201630CBD166E935CF713373BEF1749F0A579B77C185A9855E444A353A0804065C3640114D29B25E96CA34E8912454A2C9D39F353103AC17B7D3742222E605B50043E06350E655BDA46760E6073B0710691072B52681A81557930FEA99F1C13AE618930466305CD56E7879C455F1C7F140BB37DCB56C807955A084A7866B3858A78372487A565DA243C7C328C355BB1E21D25C499BCF2DE82FB77349D712A365B395D3A1A82D43326D464CABCBA97D634FA0F54226029D576304AB06229BF59BE0A3BE83C4A927157DB10743B9CB4070896E79B17483B07D185AA097C790B1B8168FE0AA02F47965E11A1F63587CB512D65B2CF4080D8BE80608E0AEC5D98A77813492E57DB94C20B3B4A29912466C2B693B2464DC8248757B808931727A7270FEDC06D86339886A90EC5A0CD5A66462646F66A9BFA959A5C790AF13B777F31BB0D1952E1C0A241AA743B54BC2CD4A3583D735A0774A65A57A1DB99FDE48381B456B2D415BA066CE94C8CE2F144EFDC71465F3AA19BBC8AA2CAFC85A0FDB06A784A48FB617BF3B7847B91037CE732D10CB2CB92331C38003DC87647015146ADCCD2A3761283C221F90AB65816107D69D5B481269009F43FACAD5D52830F53DF74B172B41C1AA693E2BB9A2A1BBAC5A362A9C190F142B71ED621429B58E88B05851668BB0193DF370402A8C6DC19591D84090A879B0C297C2B352BC74BB6A91A598997CB8A7BB3AD9553B9EB114E4B44E30E2698E83A38134BE232995A66644E1A0C308B014E1DC5DFC71C580D61ACC478DB94052340C109339731610223E212CD7AC3E7BE983CB75B0A9145FC2A058EAC5288A584CA024258A596BDB2A64B42A471A2C40BEA222CAD46478007CF981AE7B179F1864A76D0B6D3CC3324735BC2C7474A7C9778777B01CC85C67FB68F5671A74479B691137A006D0D5531014AB4261DCC4C88C07FF298EB9209D3234637F1B8BB0BB506D582467247FE6286EA885612B0648AA593F5436873646406BD03E65A549E610A6502121C0C84AD16C7DA8026B2D47334553967F749CAD20421BE2C67DF13225D694A4F84FAF99C61953A5199A556B8B6E86AC9DFDD4223FD3ADB37623D5A6C8A292CA4A048A7A72B7CDE58F60E227EFCC5290F5C55E75274860813EA29496123ADF577D22DC57174A25188BA951970597359C32B24031F264FD8494121727C7B4940FF4CF12F4CE8AE074272A0CE870304AF5B274E44EB34C8AEF476190917B0194BB75A23BE748C15A69525AABA908BAAFE6F67B4140BCC9F8670B16A84EA855D67610EC1A6CEBC7CA15534BD740BDE1181660501094050FC8C58A48F4B87F98CDA881569D03BE5DB1A4418B86F93AA5F18A9E2873418D5BC9CB849AADBB04883914D413955FC072B26C17AF227E7E3BB41C666C8BA269E5D6C9D14A13B458CC7E7B37907003E4A089F2941F4ED3B3B7F7CAEC60BA21389570E014612088DB3309582254E7A4667CD3755F4B3E536AB68F36459EF04C1EB210E17259FF714AB8D1052A6C03351A829A02A0F9267E6F62912B188627D907D11A85237AC296E3629151516E495E69C9BF93677BB1582900D5C3EE554D9E491BC1972239C96D17937B094795E6780B84F7BAF953095E909C11A90C2D803A3D7A265A9894D9B76988F9B54DD033D4C2461000087987A1F81A2027A036138C42DFF0656E4338BB717B0DA922E677B1D6447565F5CDF202AC9E7232C2B962626729C1F6836862900A32688AC60716286EDE932085D23774512F610881B63B1E34B77B25E30C7472969B7B2F4FB03A4FC46217A0A562B27345EB8038B22160913BF658478D089A88EB9E07B559D268BE07EC3E9F9A752F7C110633821FCA2EE9DC3B94E9A190759C6C4CA9AAA5547C1C86D714CCBED6C41AB53D3379BBE7C189BD1860DF788FD4528281FB1C51F687AA1438A329B100805F99F016D9119D2D06C1A6978569E7C40CAB47CE5CACC4D35AADD89047A3BF7175CD8833540B8A028C27461D334B3F8680DAF57313D7713A35075CE971CAC3CFEAC02774C3589C21232D5A73D959705BE77C3CA0884F8A1C3A89A1059972F115257BC0CE9F13271FD73E7293BF944B82865986A5D56E6C9C825C83271F42908C0953FEA66DE4EBB820013FE9AA9522AB4ED66334DE641F8E66766BFC47A7A5156C182C0BB3628B81B59461B05E3A11D945B36A3923B12ABF8F698D1234593D0C784633CDAF09CF8F4148F6320B15C48AA81B1FC3E79FA4055599935E1076C8C1780B1910AF4AC9652249B0C64C94137132A12AB62DD265334CC46A3444437A74B076039F39BDCBE2016D8402081949C8E6066F09839CC0ADFB5215590AAB10C51BB03B68701B0692D1C5C47C58D214B139B83562728B3A771F25CB7638077C4B6B2F83B11DF2369EBE9B4E51F36BE72BB04E1B591852AEA0CC31D1A774768940D73801B8BA23F71C542C8C01559862AF4950B7E21F5D4ABC3A1104251574E5597076F971B46C370FB1858A1CBA35353D29A23DB9E756C57A115539824F5375080990B3835023F448A2314D08C6897DA5AE35325F9A6107AD4CA05D653BA78C5769E51B368C200543C2A2884A2D504A73827009D166218A981189B5556B38DF395AE007772C1222C3E2778C34774C87AE0931BD116C82AE33B3454808E07CC5C6D16C5108C155A451E046260067C6FB0181AE084588017FDBB7AE63E96321290BDB4B3867074E6E684B700B7D5B1074641C5702E287D257B8A54597667C1CCC702F735C30BBAA84BF405123602572962ED89C2D7A3817AC4879D1392F9199C003E63666F1CFC6F91CFC9386B18615BD36913F010270E8A4A9A99E772CBB994B4CA926BF8A04CC1C20C885D2683301CD8C7B381190B0E3DCA0D6C33FDD49465FD265781A16FBB546E9B6C6CE0462C604B9FFF09CC2D4608259284B8A83A877B9FB18415CD60C37B0B3D6A48C803A61B0A5C9675018F64A013062440F0C40C62055CCA7BB6CB9A293193485FC529922478E4C620A73144A57833D3B5B9BB222F2F4B452447CC06638FAC1B4404402449A3CD60BCB2FBCCDAEA42086682AD7F972008276E4E5449217088B485CE6757EB3410C62796D0E7A643A3C72C612AB165475F6E51456D498E858AFF563C1F7781035FCAB3C85CFA2F207D1E4703D3015E14689FA0C9B1F57984B678BAA10CACE44A2FB23BC1F317D5304552306183435C62012B2CCDAA9A744575F959B57B9CCC2C28E1A94959A812DA6F259D11479FBBC97F54A57A986BE61F49EC42124DA687221AA3EB3B2C0298249746B20CBA291F1633E784608D5897DA13A20EA377DF6B95198132A7FD526D065250F97525D809BF9CC7270C7B723CC95DC9C8DDF5113EC4C8B3CDCA07A7242034741A3CC684A998514FBCCC435A8A2D92675E6C3F252A7019A74818689574C6AD907080954557CC12E1D47CA23240B78C2301F39C78127180C268B76289132AAB01F457ADFA649A4324A08E0BB5345CC2EF90FE6E33588D6ADB499B04DAA642FC01F5777BEF8A7AF04179630619D13BA0991CB36E8C23F16BAAB09A72E7388C93385331F7B5BDF420F1E75C7AD28C54DF96DF3F1086FE4120843AF7C7878B4483956B022AE05112253B97E6A61780CCF4047589EA04000D57593622983E8187A6232DEEB59F5E147EF1628A9F692B8BCCEA069CEE6F49533B7301728A3FFC85D7DB98398CCB38523254F843DD79BB58B4796A1FC6D68095B8FAA7FF9381D01D61BD6694F2C225C46086031A86105661033948C29278E422B304DAC9817401AF89540A29A1CD6093C86A3878C226FCAE156B85038F4AC53579143F2F5854F825B0D45BB974B724368814A9487A60A6E41261470935A90EBCF45B53279C67D92330556E99606DC22A2419021896B2EB750B2479AAE7A706B1BBDD9514173F23DD3066161A0AF8A6A9EF6AA7EFCFB1306B9C421F63BE2E376F747731A233A45A8309BA8182D24CF6598C26D65C89DA9C9E9E6B9579A4817552A8D355EDE798E09781B387C9935333B15D92998A4C736D266DFC2AB61708FCAC7B821C01044492F7F4BB8F37B5026790F3A437CFA63AF88341B95A8899AD31B37491CE3E42FD9B3701A63D537569B75A6B4B362C14F1B4BA66AB7914C9900187F105744DF0B816BA22F5D471848886DD490D5C76169A14AF42C03B0B56A7E26AA7AC424D67704139CB68EDB8F14C5ECFFCE83828208EDF58C0F494FE3CA22CFDF58AE", + "ek" : "CD741F620097DFAC3A8CF88A80896AD2A3747874514A7AB7390A520DD455D55117798E2B7AAB4A7596FBE52B21A275346E8EBF1C4F53B04A2CA851F1C8051520AFA62A7D1B67D338711F48523F10CF43C9EEDD3E9BF33DD9E4491C625558B88FAF69D313EA09403D27FC90EE2DDD70F6FBCCA7A700BC9B417DE9541676B6F576D84A242616FDC8944243ECC676A3B65A52B8EAFBFECA0388550A403AF73C283DEAA47E646E17739910EDBC79E19D9DE58EDEF3B131D63AEEC010A1D07306BF1A8191C059F1F0D439D5D43AE16DD7139EDF7E52DA9693057D98453CE185C0B9102E2B53FA367B7DCE91F4BCDDA463749D93EBE9E0CD03A7961AF83D1F6ADF244150E6295F7465211DE3CE3FB4C4440517B4ABAD3A7B8F3DD1864CA09C211375C9F9D5ED4B1DDA5EEB98B3829732BEB4C27CB0B8FC45CCB8A898E84821ABECFF59DB8CF68C536CA90037F68C003F3E62B5AADD5D82E41CE4D7FF00663A229D1C49709ED89B1E73030CFC29F81D5AD8A2B89F1C3E1443C2D4B87EC839D033FDA4527E251DA0E832F796B24314484C6891EBD66D394E3E0B4383C252BE12AA41FE53B7FBEEF5BC074B74C8178C03D803B7F9D6F6842381F87260AA9BFF6979A20EFE4C3BE5922B298B1A479CEA2DDBB7BF4FEC39B91E1409EDAF4D9BDD02C6D9E5450A08C556C1AF08CC202BAB218AEDEC594C4A06DA6593158326DF94AE5CCC1A9BE103B93CC72FE2F8DE511E6F0184837A20FC75F25757A1AF4F94FB2974A4D8E4B5AA77DD9504C6B25F22B21F58666BCB10A998D9EAB22497594FB57C77E726FDD94C238821AE1B08BDF75FC35DB0A6E87155247D039FF24C8E4A263173C592EFBA0BC597257F183A1C4FC38D54D132F3FE9D3F66975D046AFA5784AD918FE8CAC4F5C633288EBF8095ACAEE5D0E8D51A779EA3E36052F76D5BF7E941F236D164A86830FD8FEF79C76771772B2B78A7AC43EC747344C336E11388CDF739B5DFFE31A5E962AE8C42C278203AC8E3CC197D6E15A3A398E4B4315001B36FF7EBEC38216499AEE52371B7E523A261F342A395F31DC38972FADC2EB8A4EB2A5F090CF41EC726481CB007CE4ED8458C19EEEA5A942CA07A47C07AA9EA8BE1736F5A1CAF30CD8BE8DC3EE8E23BF8F85F3BFA159491FDFE52B3E1919DAD28B006D0A39EE1E38BC9C70B2652D14245DC24C25763BC85B9A02204A46785B8D3D97F8BF7782423D757AA2C5E0779439578B25FDB25DF190D8AAF86DE09FA2D90FEB20520AA804A3A2B2286C563B66DAA8986285F321A581A0469CCB3E9DAE0A10A48438DA05411F62FE64F1D9962323A49EF2EEB1FDD22B4F739EC6AA120F6C0C477D180CDEEF3D117F2F187EDA39748C465C98FE1230988ED18A6D731AD3738376FBE8A919EA122700A1EAFD8BD7BEDE9E851AAB3AFF5F8BA8F44A192CC396A425907622ACCB167F8AC26443CA1E5821B581EB119AE34C36D4D7E46D598937DB56A48BDA37A35D5F3AC57BB5948FABB8999C553AB94938BC02346C228AA49D033711EC818EF950402EEE175F532C329F3E303B56D8F5386399CC54C3C1BCE2CE6344887D5B2213458E000F1E35189ECBDE3A0548FD5F7CC68B19464685F865F64A9780E425229BEB7EAB835BCD4A005652458729334292F183735377ED5AAF0FB36644136CB13A8A622AD4BB282373DC71AA2ECEAC498331C1981BD135156522373430F936E5A470087172B5C555263B33A6AAC0EC7C78DEE2FAC1945D1D650688323EFFAE53A984AEAAF885C92A70A74063F7F34A8B8D1B7E3CCFC0925BC811899FCA675A9B0FBD3D0358415BB36B20287DD6731EDFF25B4604880F95C4E7F4A7115989A56B1FE6E6937E64B65719C9B47D942E138A7F286A57F4E8715C5BF0986FC69913AEBBFFE9A1096C7DCA1387529500E34CA7BB9562A945920A3E68A0F729D6D293D34703A727B94B8CF331CD049123B4A48C0A93876777BAE2332FFEA00D5C526EA9E64B0BFE8A0A631B8B4C58EE2BBD04596788349BEBBFEE5726D747E8DAB8713D0BEB6304F2A5761551CCA4B21A683829868D22F5B6EDE15B51D967FB3E5A596A96C8919A2D84F1F242A218621D38941030553CACBC0194D2F0484630753A87C34BB36F16305C2E4A13D59C323398C2A492856DED4BACF4F48EF4C5F4550ABA8F03A57A779577522D0A75533AA8C4AE603FC42D398B480D54F38586AB63D1D1A", + "k" : "0A343FA0BA4A23875A9C1D902D3A0E85091EEE9CEADD2CAE4BB5005E9679EC08", +}, +{ + "rngSeed" : "7F4A56EDA151E7B097CFB8EF980440FFF707AFFBA91867C89522CED6C5FF3BD7F5F00BB49DDD615D9361A7E4EFA42851", + "pk" : "55A15B77118695A2BFE69365A4474CC5F1BD3BC30BECA40FA5AB05198B708D58110ABA64FA4A8E5F955BFD935530B95F16EA816074AC23F8435EB22E85B7621481444B699278082693F073D623C99764C759AA0D6D3211FEA1A61B048519E142EEF86EC20430812C26AA3812C42471CC8799B80915222111C96B09EA063518C42786569101F81EAFE3229FD85900DA5ABAC8A84A688BD58A03213AC8019929E089A24FF8C712A1751856722FC7AF3C57BBF95C77C38C85D3E481916C75FFA371D2A0C583B03D301538CF49C744F429D2C80E1AB13C5E126AB6D3CCD733177E469E6A30CBE0C3212215B66F57BEDBCA118BE24C4A3267A1E65C8F924588E9B10CE22157650E64314B7643136E87BC141C9A01DC7B746556A1EA01F5AA8D22671BE3177BCBEB605093A225E1A847C6AB78CA89C4D3A4A618932025AAB56646A974B088429E182308DBDA27FE6A0A7F5A6B36D681CBD94EC205A018319A89345CA5715EF79266D1F67DFF2A1867366D14BB60625B9883740F4B3627AC385FA728A51C162401D86C4F2385BB9661CA891562523A7A66111195BACEC69ABD4C35BA6959397664AB56A621A25B00C5AA2C0793487A8B1B5847A29844D6E8CAC42BA2AA3586CE117B010AAA324236855771CC999929F0B948C671B4A7CED082358FC94147F86FB01C3B1210BFDFE266D1F60A72BAAB460AA7CE7083D4B913635332CF559B121A26FA643FBB7553781847787C8D78E9662CB82941627BC863BC79799D4681830D3B41D156384F157E3AD27192B92E47C106AB6C1304A3B56723162E933CC28B220F45CBB9615CC90AA3483CBB9B510E7AECBD80B28BA3A51E1264B6C6023C30843462F33FAF090E43555635C674A80679FBC88270AB53CCC83B79673E296A1394DBA0BC2B421B02A0D4213890D0093C19384298B039B5B8F4F61A2CE286BF11B9A6C164BB5A269427999D707C3E62CE88D66FA283218EF393A4EC7A35E2A927B92866E5976E1B95122236C2800D2B4989E0759AB8BC1F37DA21288AB22FC4A13BF8068A9ABAC80C814D150885762275C638087B643B60B4673408869156D52CA257BA50FF1354F4164B4D29069A99C7805527C7674C2DBBCF26656D110823F082BC88405299E093195038F7562B11DAAEC75668B71244FA6769A18B2D4643930704199F0105082BA91FF44F7B6BB339F243B524979AC51FC92C6B75711193FA29F898141A6C444E2850F03353FC6CA27F0023B9C88F6C0B8AAFC9CB9981C460E2B17D594C7A60B6E3451C9675C923A7B1645C4D3FB28B1E42AE1F93090B86659E1A7D46183D26F380A2C046D9028E9906CBDF1AB605367BE6A5609E79CB8DC349C739B7D4F74007FA69B9B50C94223E214509B2E057272476B1653D90740B0C059B1D2845EA9A57CAD384A2C7CC2B926979F60FDE47BFA01A217CD3C43BC01AAE86642B84B79CE58296700427C78B7F32116823BA964379F1374E4B164EAC108234B12139D580EC4BC11BE3B62442445409204E1A9459AB3D7D33815E76589CA4009B27CA2E6CA470B61504569D0E70155D988B80988CDA1C9EC0DA673AC2497D6A2FE1CB8539F5262BBA5104A4CF7659A616755CBD6A1CFD42A9EE1C115158A66AF0BBCEB149DBA4AF4ED2A128A988D8AA5C97164BE56483E1816E52402B908B12429C505D0A3A4B2366A7BB38169497E7AC0E3CA8AD8F9636A54CB4B4D667D91752D6658A08416D552C3EBEE80A613C41DE4478611598BD05B34A66853B079481885225941BEB4B67218013A3772A60E55AAA25AD44575F45A3178D37AF2786A76E20A5A8719D84E693F693507AAB4CB43C55A64339359B8075A643B7A696C373144A743288C37FFE36C454A45444C2A48C3C7D0415C125D133670CA1709C7F80897751FC8D07F30BA0A3B10F7110B03863E5B040B7942C6A527008F7952B89CFF921280296955261CA76F50D1DC0A0D2B8B682D8459FEC291C27C1E281BBF5A17DFF0C0C75A3BB4C987F30B175C293931FC444728AB8590C6095C60542E6BBD2A39E324B96AF61328ECBC54DA1A44CA7A175C61A131610BAD5144B702380D45B5DF1622F3B2A4E640457AC830C8CC05EF95B4429B599983BAB346A47443575087E975A57AB91601EE65966B51838108117934A5F334979349E3FDB9B49CA49252A4214B6E298C3B12E5F6E85DDFA7EDC01A03B27468684972318831A", + "sk" : "A9A63209470B02C598D426B60572256C3A610EE70E65D20BFFAC56F5371D896255FB79AC3934B43C78CCB0CB8CA428C975E0BE2E901C85F92950AB2E2E30B75953656E87C5107B1AE0B0275C0AB1E0A9019B3681E0B909FFEBCB467447EA7C8A4328C7FD485F4A6C6AEB6C730F10CEB68C3A3974BB5C2A37F3C588E6E9058DD458F478B702467155D9A2B0D28B5D60BEBBEA16924C22EFA742F59C10FF235F3EA05C51A721AB75550207B3A6F36E34683E7CC5127210015F20082EF4AEA1C273AB2C1ADBB235BA590F027028313B9FCAF656E4747D0461422EFC565276577720223F8600F9C3739E185C98669CC75A282AB8A663285AFAB5B1B406818C19508F99C9F35A01144A36FB8A68F12516B7EB09EED336BB0440A013BF78C19CA0F11257DB7751E5B54033A74FB5AC24D07FE2A547A0F9882B83570ED29E2AE403EEF911C3827CCE4A3B926B4C5FC579486836CD9C78CB537369D270798AA6A5707A28A2B48A93302F4BA79C8882E23256A335BD7674612749383E8399C7715BF53945E57927C29B2D04481E43E8A91D58511D975BEF95A304F253F9027D2948431DA71B92C0319B9512B5CB7DC6908A9FAB80D0F25F18207FA0323C7951BA4272C053440D0B9A81FC84708643B1A2880C7272A9CC0034246430CD396D4D2134FC1477AA0261AD5595A384CF19A6C37BE499274B870CE21120033092E70A38175388645C86692C5E213A29C910323270C790376A19A3D11742376C797E55628ADB813AA4AC10D2659A42A3FD7AA13C9C67CCA92D0BF0A37FD093A3267892BCA285C93C45EC65D4E0A63C3BBA8F0051F35A939F0C11B0356C160B14921B4AFF79A127B35B5A27C431252ABDA5A570C48327FB7204D7BA38A79F34A15AE5A2750E27A3E62ACF8FD87329B78E426A1BF91901190A29FD820C7656969AE737044207C8137D8EAC5EDAA41B606B257A53AF4D0ACCA2266618F081D743CE9803C1EBF29AFE0C24AC83BF3EBCA2BDD35B98355260C31819D7C4CA9C5550972B34EA388EC62A04CB6D06F083B06C4850814B1B4B65E3931E2037C4D89BA1314CA2C47B7DD7A06F11150BC5188178584F825205B693CBCD51612C13385C98B57168B0C4F9A488A81D31A3429968310496A665446FA6A988B7647B95AB582193543906B274CC73925073C55532D7E9AF4066998EDC208AACC5A0E23431255F1CACBFB380335046CDAF416417B80FAB2BCC834BB9A377709069A330F654929C39A0AA95126CBF26FC320DC34FA8EB706234878B516BA9854D2265ACFE5CA3EE0CCF5A413B884A9757608453516A524565345B0290421003E71EF631266A021488303A56998505CB4020B1C38C859F33D914AB97A0BAE13F620A090F80382BE3A40EFA723BF42FA10AAB9651485F8C6D3A8621A863723BC4AE27627C18287D0BD01B8393819100CBCD28B4173C35B0D874DBBB4E7E3793F16785742C282E590B4B4960C8503152980DDE8B5CAB7186FCE546A8642E7A43A0E939C17B25C8F7CA3B15814EBC91CC213920BD35848D8B412C0269FBD59F74382A27206F2886B33FFC71CB896F225170CC730E07092031E60CAB064BE4E005AF92428B8BB522237413E72B18949CB06588DB32C5B53570A93796DED26A22EC8E27B9A042795901B97507789905C421B3E1260263AB704925C7D8CE3393CE04A19486559EEA554EC40361010B73544C590147256CB50E7D940E9DD859AC8647F418548270941A53BC4D126F050152AE557F15756562C0267D26C1DB4313E5EC6E0F76A2085A77AFF2C1EC5CC4D6299591BACE03B527F3FA71D9786DEC5C9C1547C9E1665D707B565BDC93F0A0C88AE3AA5A00975D136A64A375F05B9E4EFCB85775627619A04000B1CD518DC8854362819CA583C71F4C6CBE624D847A2651776672501A71E3717F249B5A7582583B18F006530FEB7D68855592026CF6F52F3640AB33032E7D609FB8D3CFCAF15D3ABB0691E478D528AF606014BAB3C15FF5CAC8C774142C9433D6BD192676CC4B7230B66BA55A50426C1A47EA6118B4913B46BA3F72255689416CC47CAEEB470F8372DD21AAF34687BBE5A66C402762B64B96A42A3BB47D14554C8DD4C31D4C7C1C8071050A41DF9A1377D6457C341F6F1538FC74247581640A505F85E151F1775885D7B655A15B77118695A2BFE69365A4474CC5F1BD3BC30BECA40FA5AB05198B708D58110ABA64FA4A8E5F955BFD935530B95F16EA816074AC23F8435EB22E85B7621481444B699278082693F073D623C99764C759AA0D6D3211FEA1A61B048519E142EEF86EC20430812C26AA3812C42471CC8799B80915222111C96B09EA063518C42786569101F81EAFE3229FD85900DA5ABAC8A84A688BD58A03213AC8019929E089A24FF8C712A1751856722FC7AF3C57BBF95C77C38C85D3E481916C75FFA371D2A0C583B03D301538CF49C744F429D2C80E1AB13C5E126AB6D3CCD733177E469E6A30CBE0C3212215B66F57BEDBCA118BE24C4A3267A1E65C8F924588E9B10CE22157650E64314B7643136E87BC141C9A01DC7B746556A1EA01F5AA8D22671BE3177BCBEB605093A225E1A847C6AB78CA89C4D3A4A618932025AAB56646A974B088429E182308DBDA27FE6A0A7F5A6B36D681CBD94EC205A018319A89345CA5715EF79266D1F67DFF2A1867366D14BB60625B9883740F4B3627AC385FA728A51C162401D86C4F2385BB9661CA891562523A7A66111195BACEC69ABD4C35BA6959397664AB56A621A25B00C5AA2C0793487A8B1B5847A29844D6E8CAC42BA2AA3586CE117B010AAA324236855771CC999929F0B948C671B4A7CED082358FC94147F86FB01C3B1210BFDFE266D1F60A72BAAB460AA7CE7083D4B913635332CF559B121A26FA643FBB7553781847787C8D78E9662CB82941627BC863BC79799D4681830D3B41D156384F157E3AD27192B92E47C106AB6C1304A3B56723162E933CC28B220F45CBB9615CC90AA3483CBB9B510E7AECBD80B28BA3A51E1264B6C6023C30843462F33FAF090E43555635C674A80679FBC88270AB53CCC83B79673E296A1394DBA0BC2B421B02A0D4213890D0093C19384298B039B5B8F4F61A2CE286BF11B9A6C164BB5A269427999D707C3E62CE88D66FA283218EF393A4EC7A35E2A927B92866E5976E1B95122236C2800D2B4989E0759AB8BC1F37DA21288AB22FC4A13BF8068A9ABAC80C814D150885762275C638087B643B60B4673408869156D52CA257BA50FF1354F4164B4D29069A99C7805527C7674C2DBBCF26656D110823F082BC88405299E093195038F7562B11DAAEC75668B71244FA6769A18B2D4643930704199F0105082BA91FF44F7B6BB339F243B524979AC51FC92C6B75711193FA29F898141A6C444E2850F03353FC6CA27F0023B9C88F6C0B8AAFC9CB9981C460E2B17D594C7A60B6E3451C9675C923A7B1645C4D3FB28B1E42AE1F93090B86659E1A7D46183D26F380A2C046D9028E9906CBDF1AB605367BE6A5609E79CB8DC349C739B7D4F74007FA69B9B50C94223E214509B2E057272476B1653D90740B0C059B1D2845EA9A57CAD384A2C7CC2B926979F60FDE47BFA01A217CD3C43BC01AAE86642B84B79CE58296700427C78B7F32116823BA964379F1374E4B164EAC108234B12139D580EC4BC11BE3B62442445409204E1A9459AB3D7D33815E76589CA4009B27CA2E6CA470B61504569D0E70155D988B80988CDA1C9EC0DA673AC2497D6A2FE1CB8539F5262BBA5104A4CF7659A616755CBD6A1CFD42A9EE1C115158A66AF0BBCEB149DBA4AF4ED2A128A988D8AA5C97164BE56483E1816E52402B908B12429C505D0A3A4B2366A7BB38169497E7AC0E3CA8AD8F9636A54CB4B4D667D91752D6658A08416D552C3EBEE80A613C41DE4478611598BD05B34A66853B079481885225941BEB4B67218013A3772A60E55AAA25AD44575F45A3178D37AF2786A76E20A5A8719D84E693F693507AAB4CB43C55A64339359B8075A643B7A696C373144A743288C37FFE36C454A45444C2A48C3C7D0415C125D133670CA1709C7F80897751FC8D07F30BA0A3B10F7110B03863E5B040B7942C6A527008F7952B89CFF921280296955261CA76F50D1DC0A0D2B8B682D8459FEC291C27C1E281BBF5A17DFF0C0C75A3BB4C987F30B175C293931FC444728AB8590C6095C60542E6BBD2A39E324B96AF61328ECBC54DA1A44CA7A175C61A131610BAD5144B702380D45B5DF1622F3B2A4E640457AC830C8CC05EF95B4429B599983BAB346A47443575087E975A57AB91601EE65966B51838108117934A5F334979349E3FDB9B49CA49252A4214B6E298C3B12E5F6E85DDFA7EDC01A03B27468684972318831AE360D6A628C3B1B5DC926153F22A88C7B953085255EDD2A72799BDA15E49DFFACE71AC90659FF2DD31B35C165D3929CFA5E94407A5A798C568E6098F631923EF", + "ek" : "24A56EDD7656BB6C103B934AB16764767BB70907FE5B1CFC1D76A200D25F4764B5940028CAA86B575C0EC28D3765375953D3E00DF79F012ABC87980C87C143FEC776C0E30CC38DEC460C3507F432E0F3ACC3B2C21423BF182880C52AE55652386D5339DA9A38A86EEE913594773D22FD2C7D312C921B241923317ACBE73D1E0B872BA29E383837D65DB77787F8BAD18678CBFCAAD31C785F804B50B239F4EDF186B6AC3CB1F3CEBD6C3EF2171E247276C2DBA5C94B453701A479C6B10FD13718790C309B127A4D5AEACB4417AA5BEBF3353D5BB3A67D75370273F46987FE467E3FD2BC4E9291DB8B7468FFF04E55439FFD26C2230204F47F0159F32B8002C656F8F910AE7F10E32ACA27460930FD3683E289B3878A710EFBB2D882A891B7DD791D645C30E49E56EA718814E1FF25F2A739D0749E1063BE661EBE9957DD3494477503776EC06582FFC90A49B0DD3C929ADB0B79D37FA0AA58CD98C359D0F41C7F9306AE395CFDFABE3CCC9C5EB22E81A1D18A2CC03836EEA4EB01141E05A7BBE879DDA683E625290BE3A1D5C0012DD29455FF1877F536A63D3D9A81A0FC78D688EE5BF6DD37C1A17378E9015014615D41B382A0903A3E5A2B304E2FA222CA20B89A894B142D592E961AD4701BE7FA2958F2A1A2F9FA35272725802A61697AFF101611FC905A39D55B77C51C07591891F8B7C07905B1616045EF0460FA7EA135DBBBEB3DDB8A776BDCC9A17BEB2C1AF3D69E2D08C78AF539F874AD318499C11C644A1933DAC24A20D401C564B03C373E85DFCA90E2BB00D34B2793290E60DDECFA0AEC09060D82B59CC42B810E35765437C3D3D855152365552520F35CCFF061489A8B211539F5C5190C26F01728BF34F19CBDE412B891021190773EE966699A7ED94DD83C5AD7FB7B22521B332EF67972A0E634940B150493B0DDB94E0198676D9813F610A989543ECBA234F84053B7089ABCB2B402F1EC1F94610F1F7CF5E4AD0F17A75E2C5C0C7E7B4FD87DFBFCA554FAC30C587DB22CF270C08348CC8F3B7DED6900D275A327C7B2EFBF0D33989C7A7525D839BE35211B099BE65676CBB69582D2E7F10B3C78FFDECE987B4E767C9EBB01E024CACCEE4D55BB2B9B6BE700DA88E527E5D7D1A7CFC98879093F24D752D0CB3646479B3E838F29713BEF1B49E00E378FF415C1188FFCC3DD579E23E15150BA9D9B66675F1ADC792E51850988CBB79E68CA0D0B023C9CFBD6F894769216C4119C7B096B78512A01060A0AE7CC6F35E2DB81C9462720F7CD05EDAF8305D4233A477B00E4729B3A41E263D7F2EB94553151285DC3DFA1D875791D0D1D6E5E04AE998D6859812CD6AFAADFE7B148ABE499BB4F5ED63CC288E442720678974D5BB83D2BADCB520F310A07289B493979CF4972A48F5E55C490927319856AB45B79EBBFF1DE13F2139E9BD75E0803E15791EF08BEC4C94AC546C031D6204E8F664719564F5DC81915189E0EC65471065F88593B7C2278ACD83C3BBDD919147A0D9D73083C7B5EA1D4288A038FAFCF67CEE60F97C4565D85B54C43C8BBB7C7AA4C63A9775170654F9C54A2DFDC3E360DD083CB6D849D5EDBA8B2FCBDCED129D0B39E28AD00179BD67119ED576236FBAC9A58006E35ACDF190217736FDE022CC372EA03F8C75F295C3B90ADB0DDE08C4BE869CF8B60C9C423028D60998CA8C61E122D8203B1E4643C544570EDAA4188A29C8D4EA09008FDB3E309C65B2BF6415940F038355A4B541739EC6B62E948B5F869707463ABE4472250C2D4AC506C8011EF672A10E51E858A3FD298E06CDD4BD622268B571C8076B0C52AC8EC20E40FD0A98A3A3EC1E20109D437EC411756D68FAB796A68727B8D3AF4FC9528911A0BD1E2AEA6D53A3B5917F6273D33B0B7EA7955DD3CD3CA913E81CE0C1D631DD1F5C6F9813F1C2F750CFD1EB1801C30486D8B6BE827C341904045BFA5C22A4A3887C26CBE20B02ED6350AF8707D26070BD6DAD4D11B4ABE9190880C581A1C41D5B5952FC95A36F15DF900117E88880DBF37347C9A40E50C19CCF17299951F9DE1D9874500D7DBD719D9AF1447EF5975C1621E929139297895F3F81981B4BDAEDF22ED327BD0FC7DBEEFD656C1D4C0C9717A3B628C000ED6838D83D892906593E5EA3B8A4F45A7EF136AA0AB8E0B85002E205C1AE8CDE54350F76A9600ECF88A7D1E3DDFC8DFCCF84392CD3FA6A8762188E236D6", + "k" : "0854978110DFB0A0EFBBCDA5DBA094E5D1C601956876A5FDE29ECF1CF92402EC", +}, +{ + "rngSeed" : "09FC004519BCF85B20D25D314A0DFC79E00CB6262A7DDDF9C52473641AFB8CFA0F5DD5F53558184CAAE9EC34B459E98E", + "pk" : "31596BD912527E2C965CE3344B4621190C106F5084836006296C37949ACA196C426F4783B65221B9C50827C85B7067A9872A6D9277828EA9385F9B512A8A3E897628D1AA36A5206B35FB219AE26269126B75590B2D1067419B27FA6852A3552D6CE48C9193C96A3131397166D47C53EEBBB68B949A5BC3C7D585027961AAB89B38F5295CE7C60D3D9009508769EE37A48DE0685B9228D998B883D871985108B49C908390CB68147E8BC561DF29CDE02B1ED5236ED77B23B3F32E687B859DD63439890D8735640F5C073BC05CDA79603CFB37FC5CCD28E98B4EB169271408A1CBA57D21AFB87C97E2044766B38280B6911B95725D5A77327764832603FE771AED89BAA1C8B2FF49B741081884C6326FA0693FE64551402301A0552F49035A262E9D047D8A2075FDF6636C726F8B6098FB2B8F01C89E87478DC1112C37F1B857FB13CEC53673E297B8AA9612D26A4CD0C6168C9DEA407133ACB939D06A7C660581A877F046B9B1138F6FA6156BE2A5BFB23D04954FE32B1272D73E39C79094864CC9E36E46E9C8F1DB330C17A0ECBB332E385769C4C0ACE7C0B0D49FB89503CBC13FF3A1B19F421B80855FCB947CB651CCC0A7B55B5100C09AAB9201C4FF8C56A2D90BAC255A3665A731D07B8AD829F7A7B556AC12ACBC1073A40B7C36059EDCCD97A50C493359C8BA390E3716921A69998B9B111C4DD283456F7B61CCF97C1DBC362E2760E2928227405E449C126D7526516298F6315302288043085808195EA587118D731543F09479A2ADB96884B3A620D4C86123818CF848B295EB0035211BF614B077871DB1D8C779D61E90257730E47BBA178AC5E28B8E47794517727E4049DC759ED5A69CF7C66DE05C0A5A00C366A87F7F2914E1E059BD1921EEF61DA9CC201F016F1CDABCA2D2CD99E1884C114100EC5FD0F415D6FC6222981D8E4582DD138D71A368BD5590645359CF767146F2CF5F7A58E0E1BECADCB1DA0C87FD385C4AD15E02836D866025D0D815AF61B564E803F0F0BDA9A1AD0A3B86DD9A79B29792A713C78F00C55668AA2A0962B4A9BE8BD9CB6966A054F0AC39182CA4D54FFFE197891B964933AA8D60A87AB0AF08C139A8E79B7A5773CF189CAA615F64B973EB273EDEFB27BE439DDFF2A1FDBA7F2CC3C65DFB0D0CB177B7AC49AD1B4DA0725A3F3A2741FB2C82347DAC329657C9BBAEAA948102295C1828B01C22AE45CB0E0B46A68837CA5C8639AB483EEC5B4DC9CAF028A7BEE18ACCC402EC6AA57A93A1C53A145E923194341BDE96296857890FA616D1BCA0CADBBBA3E4302E55286C58A283CA8D1626515E6A84881AA692C662A3567CC294A23059392887CE7A835F8B8030F5C1060518C71E0C5621812D54D50043B73182FA67DE92768C63C4A2C562AC151342FAB8FC9181BE82301404792A94258B98411ED093A9121699EA13FC822BB5A317B55C1167AC12BD8C3CCD9BC743A634ED6A0961E13AD91A779A242DD0B9B4B41A5DA11CBEA085032EE2382C4B8CE088524075CDFE7B7C06CB6F2AE128F4F7A6C5D58011B42B8CD39A8A0AAABA14A0EA8C9A72F322693410CAC54C3EE5487D726ACDE02F9CD0B027844EA1C018E2744571C3A2C36B4E0DA088F09AB939152E30696CFD3473A085BE3ECCB53EB406B66C95EF8B1CFCFA1DF8C8238B8C129ABC9176E0864415852CC8CE13970FE8A76ECFE246800997C56668AF974605E748E3054700D7B75FA182278309E41CBE5B4A17696C843FB4AD72471BAC747FAF30C99D2433665433EF29B64870AE8A3593845AC211CA4AF0E5AEB9B8AFA5B4419559502E834F993543353835596985E31529C1482D0FCB9C11A1C79A704DB1D531BD0774F91B6810B98766A83387387C0682584C94793FA771AB8B4216455F7A117C65E5A481E01B5BD8BD0A9263635815F3C13C7C6740D2D1778AB47D56C9A37ED4A660249B8A4A02CBD716F6A09A646456C4B54CAD68C86F8B998855379560692CFA68B5176309162A7A506B28E042C25850A7E6357EBCCE387146B94A09FA82AD2CDA8123477F926757D552929EA72E379A9BB997BAB0D1AEB5F02568E7715D959168129CD58048AB1299EEC754B9080E7337084DDC37C4695B75488EFFDC370EDB65655231EF1091D762B8EC53A3283B3F7BB5114429C788A2CBDCE1C0454466882448990D0C963C4DC08E6955A7AA5238A6347A0D168A1AB143347AB4", + "sk" : "E7831320D38DD5629CCD557808A8B263730777D379CAA64E1DA51CD8C2BAF8AB930118770CCA3DBC11825C867AF4421C87541C5A6788BB93B560948DC8555C8CAA6597441E1A6313AC5A8ECC6A0ACC25CDABB2C59B49352CC589F13269CA38094D2A2029B070E989B0A2D15332BA43657B23F278B1A253C4250B2210B0905B4737F678A83DA40CA296BAB3461B58C1274BA0CE79E5562723242AC1CD86839E32E4302E84B42BD118FC4415B71C92E149CDAAF06DD12837A5C03AA41B60178C1518130AC4C7017D78C5AFD922E83AC2BCC3C3D94B6D8DC8062CD54649339EC4B75C49704D2E5C86AAF48294D19E4D28C12FE45CC56898C630A252E09E6F718C36C71CF9B38D38A3A9731C4F6F02528107C745277841B29D7B93BBC4B5C860147777F79745EA2296274856915D06944582055B31741F291C66DF5C4A2F09351311A6D56A8572AA6240A42BE432A5E4D98CF229195EE0A72F6C67CB4A9C48A9932D36CF70164364988270503573E43E2B730D88F94D23315B6848549515104320C26E83206AD5C33AC98C922B6BC0C961EF2607AAB223A4FABD82DC7670FC999263991612440D93A2E3EAA8E65961D441A8548762C84754FC4880DA92AED2621876294D1C086EFBBB52CD252E2F14853F6A2B7D0BC9E1F104B9703A27779733049013DA1812257BB8DB3857075B665C8E7622CCFA10667DE3BA468808FBA7B6DDA902A1337AF7EC59E4AABEE16C8017674114DCC2A0571730C14A9D07485648228FF8528C155F6266B79B3C76A8BA2ED133401D6BC56394785089ABC368B9D05B4A1165912360BF87FB6EF6F79859F8187151A31437904398C997C30092CA21C43996805245904A0D90BA8658309BE2B4306266888F5564B631CB250569AEC1886059352BF770E1137F5287058BA78463523C59F14D1846B7E1764AAF2210A58990FED7528BAB242EE02949539469122DCFF23F921B3A0746B44F64A7AAF81F99954AD88B67567C120B191ABDE6C7D54AAB5CE7BC87960E2EE2618E24746F24C03B153DC988B0D3712C42D20E152533BCB914588A32FFBC2C44B4045F07AB79EA5627045F45B11D62D2A3BBF97E57E8C27439418BE800A667BCD35435B6770B8223ACE5284371F5B0D8930AA93B8A3889984B8065F408BAFD0C5D5DF30CD3E5911D9845C9F687980A1609198DDE43A52EE970867C0ADDBC2114D52D91073D6C95156F7C95A40A575EE07228B22BDABB0B16729B2266B13EC29BBC70486E13612270541102BAF04A96B24900AF60CDAAECAA1AF07459F554B53B7806A65465FA8ED5C2BF65D32410CAA887A90527B82A9697738CC71A1926478BD4CBD70067A50479058BBAEAC05698B1530A1774C0F45001EC718E05053DA12F24115ACDD76BFF98094F8BCB45960E635377077B6D92150221C87B60994BD7732E24C34B55AC1FE660450AF46B3397A0C1C577A30B2FE1C263544C025172164F7C5620B5658D34455757C920F229920729264A159B20658A75496C6BB48FA9090D88BE51F754988AB5CC774D526A1C27361CF3AB173326886EB0053B082EE9279C27A428D6F7CBF9FBCC15AC4988D13DCED43E0045167D33B0AAC4C11C383CCD1025BBE1C83BF5C43AB6836328959CE979C3914510027121A00061E12D1D831EFA030CDDF9ABA24754BF556A99F65109832EF12CA41ED9342309C24E7A09CFC93647C6CFBAE5CC262764AA64AB49132DA03A6E7424C56BA49BCAD27AFFDCA4B88584B74C0623224541B82419E563DB5B90AB40787F8425E4B38BBC573918224C4D73149BAB4DBBE350630229A612BACD4B081CA05EB95A62C50453695A65763461586C8DE2934D31093297EA1384D3C2F2F811BC75C960237693652387A13F69629A3FD625351927A9658BD4125C713177959AA82EF3771C03B5BD5805B7D56F00D86FECC7AA29A7637CF3BBEA377EE7B9B1F94836197A718B097F510C81594A0E11381F01584A87419F51F49C120B89514754DD85A6BE48AD947B81698001F0A256F8A92D09A1A049C0376D236A19F19BCF431A90F94B028475C11807D14C5562E5747F1B8DB5B072017023BAB895A07415DEB89CB3CB8A9115B63216BD69243186901AE32B24402B88BD18CD03B2216D24928EB82E385684BC143E0D5745892B0826F89F9FA8A931596BD912527E2C965CE3344B4621190C106F5084836006296C37949ACA196C426F4783B65221B9C50827C85B7067A9872A6D9277828EA9385F9B512A8A3E897628D1AA36A5206B35FB219AE26269126B75590B2D1067419B27FA6852A3552D6CE48C9193C96A3131397166D47C53EEBBB68B949A5BC3C7D585027961AAB89B38F5295CE7C60D3D9009508769EE37A48DE0685B9228D998B883D871985108B49C908390CB68147E8BC561DF29CDE02B1ED5236ED77B23B3F32E687B859DD63439890D8735640F5C073BC05CDA79603CFB37FC5CCD28E98B4EB169271408A1CBA57D21AFB87C97E2044766B38280B6911B95725D5A77327764832603FE771AED89BAA1C8B2FF49B741081884C6326FA0693FE64551402301A0552F49035A262E9D047D8A2075FDF6636C726F8B6098FB2B8F01C89E87478DC1112C37F1B857FB13CEC53673E297B8AA9612D26A4CD0C6168C9DEA407133ACB939D06A7C660581A877F046B9B1138F6FA6156BE2A5BFB23D04954FE32B1272D73E39C79094864CC9E36E46E9C8F1DB330C17A0ECBB332E385769C4C0ACE7C0B0D49FB89503CBC13FF3A1B19F421B80855FCB947CB651CCC0A7B55B5100C09AAB9201C4FF8C56A2D90BAC255A3665A731D07B8AD829F7A7B556AC12ACBC1073A40B7C36059EDCCD97A50C493359C8BA390E3716921A69998B9B111C4DD283456F7B61CCF97C1DBC362E2760E2928227405E449C126D7526516298F6315302288043085808195EA587118D731543F09479A2ADB96884B3A620D4C86123818CF848B295EB0035211BF614B077871DB1D8C779D61E90257730E47BBA178AC5E28B8E47794517727E4049DC759ED5A69CF7C66DE05C0A5A00C366A87F7F2914E1E059BD1921EEF61DA9CC201F016F1CDABCA2D2CD99E1884C114100EC5FD0F415D6FC6222981D8E4582DD138D71A368BD5590645359CF767146F2CF5F7A58E0E1BECADCB1DA0C87FD385C4AD15E02836D866025D0D815AF61B564E803F0F0BDA9A1AD0A3B86DD9A79B29792A713C78F00C55668AA2A0962B4A9BE8BD9CB6966A054F0AC39182CA4D54FFFE197891B964933AA8D60A87AB0AF08C139A8E79B7A5773CF189CAA615F64B973EB273EDEFB27BE439DDFF2A1FDBA7F2CC3C65DFB0D0CB177B7AC49AD1B4DA0725A3F3A2741FB2C82347DAC329657C9BBAEAA948102295C1828B01C22AE45CB0E0B46A68837CA5C8639AB483EEC5B4DC9CAF028A7BEE18ACCC402EC6AA57A93A1C53A145E923194341BDE96296857890FA616D1BCA0CADBBBA3E4302E55286C58A283CA8D1626515E6A84881AA692C662A3567CC294A23059392887CE7A835F8B8030F5C1060518C71E0C5621812D54D50043B73182FA67DE92768C63C4A2C562AC151342FAB8FC9181BE82301404792A94258B98411ED093A9121699EA13FC822BB5A317B55C1167AC12BD8C3CCD9BC743A634ED6A0961E13AD91A779A242DD0B9B4B41A5DA11CBEA085032EE2382C4B8CE088524075CDFE7B7C06CB6F2AE128F4F7A6C5D58011B42B8CD39A8A0AAABA14A0EA8C9A72F322693410CAC54C3EE5487D726ACDE02F9CD0B027844EA1C018E2744571C3A2C36B4E0DA088F09AB939152E30696CFD3473A085BE3ECCB53EB406B66C95EF8B1CFCFA1DF8C8238B8C129ABC9176E0864415852CC8CE13970FE8A76ECFE246800997C56668AF974605E748E3054700D7B75FA182278309E41CBE5B4A17696C843FB4AD72471BAC747FAF30C99D2433665433EF29B64870AE8A3593845AC211CA4AF0E5AEB9B8AFA5B4419559502E834F993543353835596985E31529C1482D0FCB9C11A1C79A704DB1D531BD0774F91B6810B98766A83387387C0682584C94793FA771AB8B4216455F7A117C65E5A481E01B5BD8BD0A9263635815F3C13C7C6740D2D1778AB47D56C9A37ED4A660249B8A4A02CBD716F6A09A646456C4B54CAD68C86F8B998855379560692CFA68B5176309162A7A506B28E042C25850A7E6357EBCCE387146B94A09FA82AD2CDA8123477F926757D552929EA72E379A9BB997BAB0D1AEB5F02568E7715D959168129CD58048AB1299EEC754B9080E7337084DDC37C4695B75488EFFDC370EDB65655231EF1091D762B8EC53A3283B3F7BB5114429C788A2CBDCE1C0454466882448990D0C963C4DC08E6955A7AA5238A6347A0D168A1AB143347AB4C4E4AD5295A60C2D41E0B7A7BC92148855EBEDB4F2B77DA0C706A1BAFD6429D54248FF45452BCE5777B08108E059234029D3309CBC2BCAAD8EBB37DCF27832F2", + "ek" : "1B7D8FA6DE3BBC80372559A4AEB4E9A9617CCDF777B5298FC7B841471C1E7C9EE4BB97BB259DC763573CAD7FA93476341A3DD10992DDA1CBEC139210D557BCDC3E90FDC7A95E5A6DBA0A828AB2E87FC7F65AB9B9524B3F17AA4A4CAB6A0648EF33009D785D34BA5F0E3C16F56D23CB3A236198C6FD2D25CF154D43D7863F2D6E7A96B3168EB38FCF1A8AB358A7EB706FE31F7A81148868AB8E4886A9A250888CC453F59D885CE0B78B6E561D2B8E63C1AE1BFBA0B07932DE38CC1EB60FBFF1171572C8D39DEDD283C217A05A339B7F871A4EB2228110E364937A7D1FF9CD95C09C6DE5C3BFDC62CE23E5C209C0974ABCBF308BC39C0B27BC4BEAF9DC063F13C232F6300FD3E4B8D971F8C01C3873ED4EE4AE97FFC65F9C0255E8696BF0D786B27F23D03C1945FCBD74935C7FDAEEF08F2C96B8F40B29FB3DDB99D2C25CE7EB4780934336D5882E1F7FD95E08272C924F00839DC795DEA09E53BD034DBF8A33EF6350F0678A05897BFD9EBE32A0C98D4EE21C8A7F67C48D3BC9D8E9444E6F9873CC11191B7F66FA0C8A23EF07BE29CC5AE49C4383F8202FBFE889DFF88E2E533FAB07B6CCEBCCAFB4D847FC5FDF6C621C4BA95A89E00C0B7081BD4F5939FF5BADA1CF8DEC6D76703BF308ECE1B42B811E76A77E5B3F044740E7B5D3941633EF06119A26111DC2D196030ED1EEF5F45CD148433B354772BD4D3414087DD569B588F28DE5EB9D3546D6EB0FDF660B76C09EDAA3AE34607CDECF5278302B33B45AE882CD0DBAD9865ED2876BAD5ABBA6956A82AA29E0AE5E74928A7F5CE403243690B7E9E418419101A2127EC15EE580E355C37D4F58579BF86CB4BCD7B281D79E74F10CCC798E9608CFD5A5271BF4D0303683056E3009D465DCFE47ECDE90061E39EF96FAD80947AB5A0284B8CAF0D0B76C41C8AD96AF79CBAC54FB1B24E74F862A344140C59802ABC7B299E3C6EFEE8320660FBF9B7DA5815727104460D3B561F316E6EFB60AA00DD5275C89C9C72E9283D8EC81FDCAB58C26041D2EF341C395B067452C7743979A7F92788E837588FC9708EB864D7B0D4F8FB084192445E037C2ECECE97CE2CC30E04DFC6A827C8503DFA54D411CDE830D607F69EC9AFDF53213A4C2CDA6B7FBC4BECD3C6E9F894B6AA247788379938423B61486432A96F3022D75E18491A67D2B09147F7D21A84477338FE171B6F92310D68A310A21C310994466AF38D22D252AFBD503B1BBF233FCABBFDC32AAEB00AA84C229BF51863E9B6E0A4A76F97EAE6B891C5DE9E8B0FE657FA56678368685888F475C20C63C36FCD7A624AFCB03DE1290AA45C94ED06E75C905074AA90D46D7F74DD8B407450724A19101370F01CFD50D35CDDA7057B9633DA33FED5D608E8D46A49C2D0712651FB74C1BEC04C3F82F3953DF88AE027A6CC3793C84D3DA8302B8BECC8244CA92A4C65817A2775EEE6030F7C10AD30B262B8B42DA2DB0CDEF4A5CF392B5AF71E4E43387C21E37B716F5E6EFB3AA2BDFF5339861CA7838FBA9B178D2D5ECB022E349951D9FFE59588FAE19ABC3D2F219FF44E9667D190CD5D4B6BCA59ACAE4E486A14DCE3BD592315247BE5D7739AEFFB6E95CC4A2AB40FFE5D7593A0C9D0D1B2642CEA198B15DFA83EA61C97226496F8D72DB9B6ED0E9C9D6BDFD2BBF7EA54C6C7D7C7592756A973A83B7413462D2AF7DAA2084F061EA62423E105567060C10333474D0F069CD1A97DF2069653AC129E29558119E232C0B260225F45850980126AAE5AAA90C9B53FFE534E17D95FB8E1CF0A236EFC4A2E6A18760CCC10DABE238380D3A266655A336F6B166AFA51598349F6ADB5D5263BF3E0CC566BC2B31D5E571C26712167F2E0278D40B920764269180A2F12DBB8C2D9C591EC2E9C95020D573AC4F7CF98B0CC3F121D8D14C6E23AA373EEADAF26B76FD07F1ABFCE0BE4F109683F7F05B0745ACAB3D6EF72CDE40849B48E159E6F2358B44243E19898B79CE19BAD1DC8CDD72D4FAF409F2A21EE30A394EACC17F25818C4444A44C5B7DD2DB2DA312543F30336B0066A5F57BC1FCA724155B852C0DCD25F8ADA7F5F5510D5064701A237305BC3BC4717D0824BDC29FFBD9E8B7C0FA1CECE7F113D24F9FD1CA6371693A961B9A49FF6329353C3C35045BE6F8AC415BE65FD064F16C2DFF7474BE29075715A33719AE5518D86F48562761907483B2822C516E02744655C79A82ED0A", + "k" : "5BE94E51D4ED8D91EF38881BC1B09188ABB08C8D1832F28FA85D897665092FDE", +}, +{ + "rngSeed" : "E3C41CCA6F04CFE7732FD54DE30CC5CAAC93E2F80E76AED7D24A962A3969C1B6A311459A3EC3E510E3E9B1E4291D4D7D", + "pk" : "D7E9BFEBE65E89997CE4E680CE385C8EEB2862175FBDC9B25DC7724F641CA14B1675E13465D634915593A228C35432B316D295DCFCAC909B9AAEBA2E93F6028BE9045610BA38C763C08308A1D6B9B8667B500C649B94CFA703432F8695377462EC6159313A184F7349BE26512759A112223AF1B12127F5566DA94C8BB19765849F9E849A4F235C9DF3783627B3E548242FE2CF506AC1FD09CD5067422789CA6BD3CEB0E516A2E88D0406ABE03B65B0F064D7600DDC227CA460CC784652FC1168E8EA53F825851A222EAB10BB9C8598E6930A2ABB627EC5640D4A3C6EEB225561AE19F20EB6D0536CEB93145C7616FCB46C04B2076B9D8A4013A4BC527848A8972B0B6577C50F63194E6357BB2084FAE54C592577D6C7A61B79475FE1C43E70980762132806A7D25482EC2A0E19778AEC2685AC19490C303CBEE96E2992B836305B58270553D07184507B12C06510437B5C78B3F5CB1B57627DA57611DD3361772A213E033DD5519666D18BCCB13B3F751901D601AE131FF3C061AF87839692967CB88199F1770AD0AE196388ED6B9746FC6E536443AFE04A3B92352ACC4EA04173D00AB9E3EB9C1CC137B2D6B14FE36DFF9591B5300853A349DC23799D8209E811965AC84090F34D36382020BA31531A0DC909B9ED725EF6120929228F48A94A5E04D03314993FC8B306572A4D5A7063110C051011C1B09EE2D09315196F09192C329565CC5A64405C3ACDC234ACBC0A78E81B3C9523C43A2FB961873EB207464A302D8349AB50167CA33CDE091BE57801B6E850DDA6C5BAF498CE1897B247BC7E1A84C6B141FB00286FE864A9F27DB6475ED24371CF0C19586750CF72AC1CAB46CE08860090A0C1322ABA42CD902B6C05F4C4BAB667B54B0D5A04332335731544675F80A2ADE66DBC075D7A9B4ED924417677B6E195B902842FBD4390597C28A1504E161175D259AE7C44333E742471B58756C0666900CB94D87F73043E940A5733F89AE3E8CF037B83A51B4768A19DD1A96729216C7E317BCBF60B3B07CD82784D964754A440CE297B40E3F8811834885AE76A9605A249958F02D9BF2EF0A195D3603261560593A636B15DDDC681AB9BB19AB7AE95D32EA474388D81585E49B463B47033F81964481F46C229F751A930F6A632E8ABA8981CCA880511164B8F09A8BD9AB8C07BC8A28636D0D32BED77B2CD032B18090928F01E192943E028AF329B4B812238A3362B5E2A61CD7B3691D06148703D692080A6C755C560490CD5B47606AC9CD9BDB927B6E3B26D9060921757A0F85A2F82B618BBA9008B7073F24A88FDFA922EACBD6631C32157B36150BE06D3CE2C4B64410543CCF280143C1DE73917B816C86B1A04204A8F3FD7CADBD20B41831C8229788ABA219BA59AF78388C2B9865EB3000089C6C05C850E91021A5328149CB2A1A27E075A3EC8630D8F515CB77903FB5531F6E05CE984296669B0BFE8AF8AE59438B834D4110BA0606EE426799C313233CA9487EA35071871420C6825889C07DA0F87F1188D75650E36AD21A265D4B44C01361C0653B55F409FF3C290D2C2C212319297D5AEF2BB87164B7535B7518CA14469FABEE91C81384025F6914C19018A0775598AD4BBADA98E06C87C9AF309C73903AE1B84FA9A3C3F668042883A8195CEA1FA5BDCA59C203178EEB18041AA2E9AF770D180BE044BAB1C8C36044A70E50281540501AD6B165C021E53B86A5F368728E2AEED1520A09A48C1EA0E9419B313D7C6A9E59F17121C8AD47410ABB73E008C1ECC16C32B4A46F39712648CD06196CEB8A076F5C7048A3AAD37393973B8679C55393137E6B6BA2DEA4D50F65E1EF12116598DE49260112055F4B0ACDA503395E242B990398943C18C01CDCA993B3C9A74E19AC6768581CCC9A0331C005CE873B241B3E5E497493AB134E18569E80A6D12A04616911F9072FAE6A30E529CEA1BBDBAECC7CC64A7D655A730335E8A22B4F4250E2C54976C69A161694ABA04456BC14E2BF8C13B1BA2A5AC1A6B557BB061805C903D1D1AA3367922FE0C51DBC35DA6CC8593B8B3CDF741220126EEA9CC5B9C0632F75C7AA3AAD60A46AFCA4A6D166F2B2AC858C2A572E4CDC2D65BCA199CD73367B83909FB324855C4899D920A32B3107EC56789D63C25036C35D30BE5D28D54D725F1EB3F924BB991CC4C5EC2E36585C0133B82099B8234CB459A9FD8ACA37C4249A3B020", + "sk" : "27CB06CADCA3F6235B6B59C5A5E7499E95130AB431FC7C4744D1AD414393F5ACBD04D15B23C8867DD88AE7CCCFF7A03122B44DE4A4BECCC2251744C517F116B413A18D614D5BC371DF9534EB76B5FCB13485E60304F02425E37A653C76E08072AE9527E449783CFA72FAE68C27E4ABCD59AB364B49E6045D764581A9738E3F6443229196478CA629B28DFA519400149A1433B716564DC0959956C87E67E8179B46B1B1B4B9B60A52641971FB91372E6550AF2C4E1BE88E534108C059217B4071493807E3986D182CBE451047FA4021E264CCDFD89C5458085832C7E157676A649E4533A91904AB61E875BA8180D8639C82522A211787B4A490FCD587D93A7CE8E08DD0094FDFF708BF23C35E1B904EA56CE14A9BC5272AB935A69E36CBB15AC1AEA1865B7710AA747570704627AA79A1075D8ADC4D008D45926B8B55DC12624B6E66F4CE3502150AA0BFC6125430550D595B6627F9AD22243A12AA70B5597708509F9DD09F5AD23A4A876FB251A46F013F05B1884AAB725FF1786A4892542C2C0B23150BD6CC3B25427F4B76365193D008A074715B06E713A4E71E3819776B078390B8042D312715B28F1D44A4D540ABFDB9A2B3B7660A7101B31030DABB52A05B7F81A488A5E306156A268FD7396D4394A43534D9C4BEB2F91686014EE0D7C103733FDA120B62BA668F0955DB0C596355091002B4AF9929384075D6575938468F95571397F8A2F227B57C8599EAC2586B72902C698800C78F4B1B99B7284AAC542FEE229F32A25312F85469F9BF8B81AAC6440D4DD26D38C001F2D625D21577D0CA557016405DE603B7F26DC7199B300B120A0C278A1475B266354BDB961F5A54A4E0CD70A05E23D7A59DEBB4134111906A9F6F5B66704026CF033B98C617FC528B104060B8673083490D6C238ED1C943A217533475B5E7C00C871C81292516763B3936D3B99C680695139E6534335BF499AA6ABBE10ACAA5A2A75F659BAAA1A743D228934A129BEB65158A04B52C999612C6A8E602AFD532139006F386AD51A618702769ECE33229187E0F647027420418D560329ABB658AAFF3A358C5577115F437F59C06D503B154F380C4512D66364C0CE20B5F0A7563626D9F2620F09208ADB71B3D91C94A10C4EC29AAF892B8D0991E7F699BDDDA9C2CD8B96DE4661674B400F780FB60921008CCDC911CE6E29A771CB308E86415F4B641D33BBE0746FCA69E2A00015F9932AF23772ABC68ABDC5DDAE66E84E3826E3CBA0A7234DF3868FBAA8B2AFC0CAC953BE2271CA2DA5CC674569DB62A2BC5C5447966A0553EB3A258DFA05AD763850C0AB1724A01F2E2B4A2F3640398BD0B8BBE8AF79ADC3CCDEBF775F2A545A7E8A8685CA73D4C5BF0D788D6A21FEF02C241B34F80752F8860249966ADA889927582C0F60642B042B95EDA965C8873FE8191967B3ACC13457E0708316096CB50B856C35A7C19AC64A85A03F9B81E9A756046B901DC9491947C077A05E5D9986CFC3DCBA09D02055CAE5A47A6969652B056035453C97571138561E28B3B0D0160DA428C9104810CA69C75D15CE66B126A27B96654C6E2A0A463D1CD4775458964BE2E5A3BEC582E38B64C8BB68776C15BC2919D5E99259A68C5C8E42C37B2B4A6B0351C18A09D2378F04403A04AAA7A6BA6589B63061B0EEB80442ADA851BCBB5AFA1BE84D688B3050647530FCAC5AF0F8B275F036AB0D354991265FD1190D7F5468FC3578E15723214ABA66B855B0B5BA2FB27C8B1B7DD37790A8C77120A6C18797B5A920450F87144872D83E8AFEC5A72DF7A61B50655F5081389225235389BF15444C90C1B332B5395796A185B1F9D816AC1B69FD1457E1CE4B1D7071E1956AE9282645B8458CBB8C3F5711E3064A4D05488104848A846AFF4C01445241DB51B81549AB00230621C8C699FB13C94679F7F51879BC2676973C7418B6D14D9963426819768631ABBA1DB070321A32C0EDC95B35C206272946FF134AFA2093EFC76B28927A948BC4F1931E1A2CBCCE18CE9C93C8B029B13291234E76B00452BB3F7860ED98CA0FA2A01A16735272B09C4C0A0B08904F5654911A937F9237818926C03CDB0A98B167B6434A96FE74796AC233716625927535581516EC3217382E61710991003E81F2E0B8D139821F3BC631EDCAE24CC4583A8ABD7E9BFEBE65E89997CE4E680CE385C8EEB2862175FBDC9B25DC7724F641CA14B1675E13465D634915593A228C35432B316D295DCFCAC909B9AAEBA2E93F6028BE9045610BA38C763C08308A1D6B9B8667B500C649B94CFA703432F8695377462EC6159313A184F7349BE26512759A112223AF1B12127F5566DA94C8BB19765849F9E849A4F235C9DF3783627B3E548242FE2CF506AC1FD09CD5067422789CA6BD3CEB0E516A2E88D0406ABE03B65B0F064D7600DDC227CA460CC784652FC1168E8EA53F825851A222EAB10BB9C8598E6930A2ABB627EC5640D4A3C6EEB225561AE19F20EB6D0536CEB93145C7616FCB46C04B2076B9D8A4013A4BC527848A8972B0B6577C50F63194E6357BB2084FAE54C592577D6C7A61B79475FE1C43E70980762132806A7D25482EC2A0E19778AEC2685AC19490C303CBEE96E2992B836305B58270553D07184507B12C06510437B5C78B3F5CB1B57627DA57611DD3361772A213E033DD5519666D18BCCB13B3F751901D601AE131FF3C061AF87839692967CB88199F1770AD0AE196388ED6B9746FC6E536443AFE04A3B92352ACC4EA04173D00AB9E3EB9C1CC137B2D6B14FE36DFF9591B5300853A349DC23799D8209E811965AC84090F34D36382020BA31531A0DC909B9ED725EF6120929228F48A94A5E04D03314993FC8B306572A4D5A7063110C051011C1B09EE2D09315196F09192C329565CC5A64405C3ACDC234ACBC0A78E81B3C9523C43A2FB961873EB207464A302D8349AB50167CA33CDE091BE57801B6E850DDA6C5BAF498CE1897B247BC7E1A84C6B141FB00286FE864A9F27DB6475ED24371CF0C19586750CF72AC1CAB46CE08860090A0C1322ABA42CD902B6C05F4C4BAB667B54B0D5A04332335731544675F80A2ADE66DBC075D7A9B4ED924417677B6E195B902842FBD4390597C28A1504E161175D259AE7C44333E742471B58756C0666900CB94D87F73043E940A5733F89AE3E8CF037B83A51B4768A19DD1A96729216C7E317BCBF60B3B07CD82784D964754A440CE297B40E3F8811834885AE76A9605A249958F02D9BF2EF0A195D3603261560593A636B15DDDC681AB9BB19AB7AE95D32EA474388D81585E49B463B47033F81964481F46C229F751A930F6A632E8ABA8981CCA880511164B8F09A8BD9AB8C07BC8A28636D0D32BED77B2CD032B18090928F01E192943E028AF329B4B812238A3362B5E2A61CD7B3691D06148703D692080A6C755C560490CD5B47606AC9CD9BDB927B6E3B26D9060921757A0F85A2F82B618BBA9008B7073F24A88FDFA922EACBD6631C32157B36150BE06D3CE2C4B64410543CCF280143C1DE73917B816C86B1A04204A8F3FD7CADBD20B41831C8229788ABA219BA59AF78388C2B9865EB3000089C6C05C850E91021A5328149CB2A1A27E075A3EC8630D8F515CB77903FB5531F6E05CE984296669B0BFE8AF8AE59438B834D4110BA0606EE426799C313233CA9487EA35071871420C6825889C07DA0F87F1188D75650E36AD21A265D4B44C01361C0653B55F409FF3C290D2C2C212319297D5AEF2BB87164B7535B7518CA14469FABEE91C81384025F6914C19018A0775598AD4BBADA98E06C87C9AF309C73903AE1B84FA9A3C3F668042883A8195CEA1FA5BDCA59C203178EEB18041AA2E9AF770D180BE044BAB1C8C36044A70E50281540501AD6B165C021E53B86A5F368728E2AEED1520A09A48C1EA0E9419B313D7C6A9E59F17121C8AD47410ABB73E008C1ECC16C32B4A46F39712648CD06196CEB8A076F5C7048A3AAD37393973B8679C55393137E6B6BA2DEA4D50F65E1EF12116598DE49260112055F4B0ACDA503395E242B990398943C18C01CDCA993B3C9A74E19AC6768581CCC9A0331C005CE873B241B3E5E497493AB134E18569E80A6D12A04616911F9072FAE6A30E529CEA1BBDBAECC7CC64A7D655A730335E8A22B4F4250E2C54976C69A161694ABA04456BC14E2BF8C13B1BA2A5AC1A6B557BB061805C903D1D1AA3367922FE0C51DBC35DA6CC8593B8B3CDF741220126EEA9CC5B9C0632F75C7AA3AAD60A46AFCA4A6D166F2B2AC858C2A572E4CDC2D65BCA199CD73367B83909FB324855C4899D920A32B3107EC56789D63C25036C35D30BE5D28D54D725F1EB3F924BB991CC4C5EC2E36585C0133B82099B8234CB459A9FD8ACA37C4249A3B02025A466C0B64A911E75243DB16841847A8AC72DD835486E96A168B2F9FEC46F307B129A56B51BE635054CAB9E84F2DEF59A3F8168E301EA2BE388C45B8CB022EC", + "ek" : "D47FD3F4EA5746AAD73C95733797CE57430B2B4A912A54A6C7EDB26426772DCEF337179C3E1CB7542A756A22A501AC06D55693E6247ABE8ADA0E1F06073C7D15D7197209F1ED1B272733A5BA7FB362B890AB72281D092EA5203252460E4176178CCAE08B322298B1D8B08ECECE853EB659653AC6517D22E9FF3D076056DBBA68E4719AB09099911EDC3B42AD1AB162A15F894887789A65B99D398A506FBB022D15E79EF43E4B3B9183B48E8F53092DAEFD5C24F7B865E479AD015A03A2346B845FAB9ADD9EDFF4061562D3A7FCAE0D4963335AB86B0BCFB1F9243139EBC842319012CF37C8E0F9AB0A0E71EC027015B75E404CD6F0CCFC496B55E27480DAF4ECD6CEE314C1BBB8AA69AF6ADC8B26B75B7972BE00C8C97A2DBC31E866E56FB03A02E296CD7C6977E9159BF480D11FE6629FBB585F2BCE9CE800A63C271F278A3EEDD2A1B61F244509418232926B76831F73F28ED69E7E87279CE1746CE60870BFEA0910B1AD6CCCEE52692101654191D8AA3A9F2788E7896DA8E941C50767D3481CBFC6B24486D8CCD1958093E4F52C6864223E4E4F1FE812ECF7F4F8F213E234D21CC9DEFBA500FB425F8FDBDE09B9E78B1045153D046890F7CE64ECBBF5937B10A088701363387CEDA6AE482DDEF056D5C969E3BE5D097B639D8D8BBCA445E226AEB13F1CBFEA8B15608A8D46B714E0451F1FD9EE0EC645E5D67BB39D9D76C69549DBD58BEE33EF5EDCD129E4197A9233794014D27F2C132962C5F3D3C12D66D9315AB03A9945BE02B1DB482B32A5966760824DED44B43CB529B642DF02A61EF26C29A63632DA89D22062241FA4F491C48D03F5835C1FDA1DE1776F197D33EEC5007303A98BFF58CE860B6A650DC39AFD2AF2817401307076C43E4BA5E9A6B4DE63F636B87F33C462D0790585C29583622967A159C847C4F565D3F3D48B25E270325E4B635904B7ABD0747DBA0749B9BA932801C1FB7723177478E770BF953CF90A166447B939782AD2D8D762D1C5762A0508A37944380B34F39B5B8EE9F0FF01624C2D7EA6CF360DDA5A4F01BE3EB5D0D64C300AC35389AD05840634EFCEE45D3CD38450F6B98266C022F016C7EECE49F1E7DF81C50F431003160F4BA5D461BF36DA861A62710849A64896B227D025FBE74370B3A70A2892433F4D686E3975C63C25C8D7202ED4D4DBE43F39D94EB31E2F2BD21A1A6ADE70AC758B74DDD0625F50D8A8111191FCB86AF8A7656F6E5D805EB6F921BCDA751EE954A27531C9013CFCBEA8AC5CBB83611387D90600C1CD0AA685A49AA0F1FC48D0977DB464A642F4B2BE360D76EA6969215BEE154E85C091F25E845E11E7C2738352FD40AFF4E06730803F28E2D609EDA03D727E9D92CD3D117FC841D9D576198BD7F70F2022EC0908C96CE40B0B242373A8E4F95EB75182DE5CEAAB5E4CE5E428267040447A1EE561675557CA7217A64151475D8ABD7EAEE377CC6D823E4E0B5E86C0B18C3C9ACFB3311F60234566C9023466A5830052BDBCF5878BA5F190042C6E646C5E9B122DECCE19F9895618C6EB7E5B88361BE6F0D14B6D730DF0D89D63A40B529CB6F316B1F942C1D49965D98F23CBE321060040EFD98EF91CD51AA0B18773DA77A4A8408640718541B3E6E2C7B0BEECF4C5201ACD11853CBF5E749750C9E3CE89A734F113D62E3D91A26C7A6669C0C195441DB1869C8C98018CB2A9A5ED18E1DD17EA2900A9CEB2E44CE83B3E7E89132823CC6DE0AC012E4EB198589FF1C2B327BE78CB90FA5CA455041DEA36DEB64FB181D8E4735AFEBD558CD0BDB80134B9BEC46A48E1DC5CFB81D39B0A787B00B3DCEA3D5D078E197EBC61F4BFBE89BF8483C68E2F42A381295E543267A1D0F0DEF45950924B85874A543555F8C49D852370CFA9352E5B687D1C1A36E17AB1441BEB554A1545605E54CD6296FFCB4120CBEF598ACBB77199E714860412804B17FC03602B6AA5C4BCF6C8E371991D170AE5BD8472E7B2A86F7277A573BBA4585EA4D9A4AB34EA7BB9753EB619871708F93A7260FAE3E7D1A5BE2A6E07F5FCB2C2756A788984288FBCF2AA0D9ABB8668B39E07319334BA2A83E143CE1A13F498E5633C250D7EB5C5F6089B4A2C579E246A5A456FF71903D4B1F8083E3CB3A5BD369DC5E0D77562BD71937AD2EB7C3B65DD6169C5B2D13A70C5ECE8590E5C7646B71AD69EC43D17ADF59469DBF8582EDD6A0B0BE012", + "k" : "EE19BC8069534D6CC1DE3AFF886CD087BFE06282FF2B16311F6B313BFB8EAE7E", +}, +{ + "rngSeed" : "373FDDE922CFC416ED96B444E445BDD0962E8989F6C50ADF9912A89937C57217D3600B06C95440448E3F601AE69CA5BE", + "pk" : "27C546B8F148CFC133AA807FD7C233C7B5A5C3F6B8DA210EF7DC5C1A834FD1559CB2439406895223991A4E682554C63AC3A117D840AA4848B1B3864EDAC960C656046E3BC6D3B681E1E6B49BB0259F1AA2A4329B2598B932E26C00FDAE2CF4686803CA7AF8BF0F1243E64544D51794583349F9854DAE778894438805793B085373D09A185CDA5489D74274EB7BFEE433B63A56E14B95941440924CAD32935440B46235A8576D11B8D65A2E8198B64B510FC1F942BD9B0F8E077FE33C559CD987615263E9B66C38C5683893C3E10965F18AA755E1BEA6D1789913CF2CB21B41B23C4EECAB25798AD13A26321C59E35B0517A78743C4469A4435970BBC2B9C15498B1F17CB0FCCB446F67C2F437415ABE98CDEB3346413539961B3DFC1C40E243296695F27152B7F7A32FF4B185EA437B275C6F617523ADA8F7D2A594E277B9318019ABC0051AA399642CC0A478AC7466E0729848A516C9E86BC8AD85BE985B395E3B28AD89F71E3B584D857BBC1915A47A2FDAAB586B7916D9A87A56235DB0C683B9BBD5F000E6A218E54464043EA1E882BB906C917CD4449FDD5ACADF5B017983C87B4A8B0FC9DED7A1E2E7BA359240009B06701B5CB29FA3B9250715EA31BD8784DD1D91D26764F32B9A49F934C8CF61B4D4A8F36F81D3EE33023959427D889E4A3C796D284A1FB0895184BA4351034A0280F34AF119004E9B06FB1E69050FA2DB039A9ABC6AB00484B9A2694980197B69B9730DA0B8455BF591B2EB4F9CEF37A06E7C107BD56C3F7AB10EBDBC60DE87BDC8C22F62C2E4DB973140C5FFF95631839264AABAC5DD4873E44B8B2F7106C083DFFF8B6403322F467A91E52CDD359293540A45134B97A39AEFB6252C9C928ADCB231EAC0D790422A9E3BDA366762E2514758BADB2A2114A9AC924553D42E05D3769350E4CA047D4219F1B6FA953B60CC67B07A71DDA85649AF0076EC5C55EF46E73AB06613A84B2422C1BF039564A6873A9385FB18C4AB92CA7A1B205E8AD57728CCAA10B13268CA519C2A0DA39BE15918BC724F7760E826AB9D47CC288918B60AA87E037A60809B230562CE18C1D76BC457107C8BF80574A2CBD0F945C59D4371AF14737983FC089A425D1AE74993451055EC21435A8114060BAA6D774BB6CA82EFEC1A40DF1877011163108A2B20190135900A98A337192088D8C66E9E774B02C6D55819DAFD9BF3CA886D39165D1C4CF29B1ABD6B185DEE9671EB941AC598E1B0240D92CA7BFA119CCA15A643AC29B30AFEDDBA1ACACCA8B83A123102FF20B1BB94CCC16FBAEFAEA4FBAA36F3D46B7F5706A7EF60E04125228900261271C9AB11B04971CA5315E6F3C9EAC795687DA91EEC532476BC66B2BA7A5650EEEE119EA13C91BD94B19C31FDBD80842D25DBFF62F928550B1F6183AB64443E6B0D9653C5379158AF74A6436CE3A1150EA31367AACC7558C201124573235A5997773064A621869707AC661A29238421C9CE88CC38E733C75539443613D8D81C60DA70E46035B343577A1660E08A67849558901D539ED84CADAECCE4DA36C4B9940E106011B872D1B9748CB08C2E3DB4880638767BB67C74311021B6C46698A21ABA391C65B9AAB238D93A4BA80BE911C3BA8319BC866CAC3E67FEE11B773EBBBB8639891809D555258DC9445FCD815AF355CE2CB38552C5BE069B6C7D0BA83F8495F1230F50BB57A8C4D82EA8912608CEF0CA6CFE408052B736D9C6FBCA2CA08E76300D150DBA48080421C5A6B13F74B8F705B4ECCF9C1A336A0E7A47263D30B5D1675DF4A2ABEC7522868BA4C6139A8D22C23608C40A8BB5E8C65661B94E008BA442B9DD9883E8953029D7C4E7B46206880B48214A84CEA0B34560F29054756F427D185241D946EFBDA04956A3972F974BE20BE202314D9C58DFA3543ACF894D65B6F22047032E408636440024452F6C2CBB5D698730907C3271774DA95B09421E499B17F670CAF8585E2330394302AAC52B0C1D2B2AD16656CB79257B143F555757B989C79A49730354E42299F28A166ECE2A03E1A6DEA08B01B9323D9958D9E320F3055C9500625B731BEF77C3F30FB2960974815243F7EDBA28B64A58BF5AFEBD76B53675DBFA62B05B89F85F945C00B3DE4F8AD2507121BAB1A86224A9DB9AFE8C26513219CCC9B19156268D159097AD048F7FC245FCB93EDCE592A8D415D4A38502632973ED98B6F97F986DBFF7E", + "sk" : "0BE83A886381009553EE02AA62B113EA829AE09B3CF11B62D21091F1115CF548388E71ABB52315CA69A4D1D601A192A4E7B494B1D3127630CEC313C15C9CBC91693375A1776B51A08B56B31F38783AF9C052B34B7C0CBAA4EAC4618ACA24DBC843322FBC666F07272A587C5C54B778AA446B349B88F2416557AA2BB9E3BC74979F3CD287645435D2AB30ABF0B6E094446E95536DFB0CBAFAA2E87706738B192EF721EDB12D6D9A3DC366214E9752A4E8B0AC3CA5A69944FF0AA86EEAAB62CA34B8FC7D74BC6EAEC56612267724A038A47982FD6AB6CC726EA0E096529476329843EBE484FB7263B4E97FC2F68EB89A65AB8750CE193D9F3176BD876B69F9A826A64DAC2186AF796EED9469AA79660C295121367906478940099E51BC36AB67A72558425E153821EC43A560558D59B136255F655C161D729D7C21CA29A70B7BFB1B5BA66C0922947DCA55D854863203064B52896E3A412A9A5AFEF93FDA7601ADC46FDC3A1D25660DF46437DEBCCBCFDC78A0D90234F0073B496D5B586A9F8B36988B33EC82C8782AB744B3355FC934544B656ED93EAA36734CB40217D680EA85476FA98D3A50C86B4A2589E85249B9A7AD01AA4AFA2DF396C5FDA43753501BB2B614ACB5BC715A113C382B6667457BC30E79E58B41B7511E011965820F2FD6C5280CAA7A35C13EBA57654501D6C326EDA25B7A96AD0236C663D70F9B46CC798CB2A4D335F6C68181C49D669946673741285626B078401928C466C1C51922C4A62553141A86E4082F661198B07539A47283AEA18C0CDA348375201473A8D3F211B1770AC0DAB8252468303B909D078524F10BC3D4958F7037F830B96C64C7F3A89586E3254AC823F8A4911A878C9394006429152B7260BCCC60D4604D1226A87CF434E39158DB5557C887207F1AA4BC9B3FBE8721DD4C96E294C2B581C78AB3997E740A86707888B6929DB848EE38BFB6411110D1B5DCA49DC4109F62762126D9A7D2E46400755513ECA554665556D3AD2C047F011076E4FAB77579C3F9F515500C7EC9747EE5B56F840994D2EB91D13C523CBCB506F011E250C23CE4243795B4E83A8F4F32308007610E23C64F38AAB3AA9AC0C303EDC77442A2A29BA6BFB46343E32C549D043371AB941C5982FEAA30334531F61877E1515449690DC4C6A94DE7CB3739C43A53A89F41AC39F0AB90622D41B48F69567C9BA5C128041426CC367AB02EC5C3B082936DED118A50C7933DE5A5FB51A07F04AE11012123857BCEF60E5E70A51E109382D17FB1D461A157C6B10B7EEE63AF1BF40626A61C2F94AF7C93041676705FEC9DB5670777A462DE3659A20CA8EC41060168C06FE925CF294CD2175E7591600492018ED70CDA9266A7772103FA43C48129A1235AB1348BC5B2960140A460531ACE8C01E6C136D69751F623C29BC0CAD760743CC04011782790115BCE926202575FDDB867DDEA380852B2420A7555994F91525D4A5AB5291983D87ABC22407325618B04A42F8F11B203A33353245F06432778C2B3E9F08E2F9234777B00493364EE48CD5C256F15D62E03A52E5D52A849D042A84239D64A08F86A7A20334C77E332D7F886620461F0C0A86292C15180903990A68CE02D4DDA33F8D34CF003A4AE80A160A27EDBBB300B693F01A151D1363CC247B41C66B3EAE25BDC76609D2BCC5F429540543D1DB01C801137A99B1DF325B88225BDF5D802C84771DF545F806A0FA8F85779F56319E25D262B37F952B7BC962911822AB4F98BD65C9720208F6B0953B1D62E51937997B480497CC656341B2FEA7B812C3DB311784C6A17790321C1CC5021543AD7D54946D71D57C2A517B1187054725E7040CC4506DE0208513366C014116FA4444BC06CF5E22E50A993DDF89F19AA14937443CE2676FA817EDE4928F81394CF82B9BF629F8D33B7EC0C6B3A35C6ADF0CE6480BD837655C2297833A8C150D45610A011B57224CE3B5B47E8B2895C95C24745D1E44B0CF26EEE771F906089C0C864DFF15DA9E6C53C62371DE9875030C534DAA8BE4719FB8A1DBDD2AA12617E4DD3B9E7C40906817398A42DBE3384FC4A4CADC098647BA4C0035774AA1D9FB85CD6D9695088271431818980AD32E4C493EA358F863853E2AE8BE6BA9C978FE45B379F90AADC4B59A4C92CFE8288A3073F31F21927C546B8F148CFC133AA807FD7C233C7B5A5C3F6B8DA210EF7DC5C1A834FD1559CB2439406895223991A4E682554C63AC3A117D840AA4848B1B3864EDAC960C656046E3BC6D3B681E1E6B49BB0259F1AA2A4329B2598B932E26C00FDAE2CF4686803CA7AF8BF0F1243E64544D51794583349F9854DAE778894438805793B085373D09A185CDA5489D74274EB7BFEE433B63A56E14B95941440924CAD32935440B46235A8576D11B8D65A2E8198B64B510FC1F942BD9B0F8E077FE33C559CD987615263E9B66C38C5683893C3E10965F18AA755E1BEA6D1789913CF2CB21B41B23C4EECAB25798AD13A26321C59E35B0517A78743C4469A4435970BBC2B9C15498B1F17CB0FCCB446F67C2F437415ABE98CDEB3346413539961B3DFC1C40E243296695F27152B7F7A32FF4B185EA437B275C6F617523ADA8F7D2A594E277B9318019ABC0051AA399642CC0A478AC7466E0729848A516C9E86BC8AD85BE985B395E3B28AD89F71E3B584D857BBC1915A47A2FDAAB586B7916D9A87A56235DB0C683B9BBD5F000E6A218E54464043EA1E882BB906C917CD4449FDD5ACADF5B017983C87B4A8B0FC9DED7A1E2E7BA359240009B06701B5CB29FA3B9250715EA31BD8784DD1D91D26764F32B9A49F934C8CF61B4D4A8F36F81D3EE33023959427D889E4A3C796D284A1FB0895184BA4351034A0280F34AF119004E9B06FB1E69050FA2DB039A9ABC6AB00484B9A2694980197B69B9730DA0B8455BF591B2EB4F9CEF37A06E7C107BD56C3F7AB10EBDBC60DE87BDC8C22F62C2E4DB973140C5FFF95631839264AABAC5DD4873E44B8B2F7106C083DFFF8B6403322F467A91E52CDD359293540A45134B97A39AEFB6252C9C928ADCB231EAC0D790422A9E3BDA366762E2514758BADB2A2114A9AC924553D42E05D3769350E4CA047D4219F1B6FA953B60CC67B07A71DDA85649AF0076EC5C55EF46E73AB06613A84B2422C1BF039564A6873A9385FB18C4AB92CA7A1B205E8AD57728CCAA10B13268CA519C2A0DA39BE15918BC724F7760E826AB9D47CC288918B60AA87E037A60809B230562CE18C1D76BC457107C8BF80574A2CBD0F945C59D4371AF14737983FC089A425D1AE74993451055EC21435A8114060BAA6D774BB6CA82EFEC1A40DF1877011163108A2B20190135900A98A337192088D8C66E9E774B02C6D55819DAFD9BF3CA886D39165D1C4CF29B1ABD6B185DEE9671EB941AC598E1B0240D92CA7BFA119CCA15A643AC29B30AFEDDBA1ACACCA8B83A123102FF20B1BB94CCC16FBAEFAEA4FBAA36F3D46B7F5706A7EF60E04125228900261271C9AB11B04971CA5315E6F3C9EAC795687DA91EEC532476BC66B2BA7A5650EEEE119EA13C91BD94B19C31FDBD80842D25DBFF62F928550B1F6183AB64443E6B0D9653C5379158AF74A6436CE3A1150EA31367AACC7558C201124573235A5997773064A621869707AC661A29238421C9CE88CC38E733C75539443613D8D81C60DA70E46035B343577A1660E08A67849558901D539ED84CADAECCE4DA36C4B9940E106011B872D1B9748CB08C2E3DB4880638767BB67C74311021B6C46698A21ABA391C65B9AAB238D93A4BA80BE911C3BA8319BC866CAC3E67FEE11B773EBBBB8639891809D555258DC9445FCD815AF355CE2CB38552C5BE069B6C7D0BA83F8495F1230F50BB57A8C4D82EA8912608CEF0CA6CFE408052B736D9C6FBCA2CA08E76300D150DBA48080421C5A6B13F74B8F705B4ECCF9C1A336A0E7A47263D30B5D1675DF4A2ABEC7522868BA4C6139A8D22C23608C40A8BB5E8C65661B94E008BA442B9DD9883E8953029D7C4E7B46206880B48214A84CEA0B34560F29054756F427D185241D946EFBDA04956A3972F974BE20BE202314D9C58DFA3543ACF894D65B6F22047032E408636440024452F6C2CBB5D698730907C3271774DA95B09421E499B17F670CAF8585E2330394302AAC52B0C1D2B2AD16656CB79257B143F555757B989C79A49730354E42299F28A166ECE2A03E1A6DEA08B01B9323D9958D9E320F3055C9500625B731BEF77C3F30FB2960974815243F7EDBA28B64A58BF5AFEBD76B53675DBFA62B05B89F85F945C00B3DE4F8AD2507121BAB1A86224A9DB9AFE8C26513219CCC9B19156268D159097AD048F7FC245FCB93EDCE592A8D415D4A38502632973ED98B6F97F986DBFF7E53AC28332EA3F161CF5DBC077E44F725B05FF0AC4ABF95F60C5713AEF1BFEF4DF0C083AE8CFF7A4BD779D4385E111ED4583FE00D30E651F171D7E8A90EEC0DB5", + "ek" : "C22FE5E86A82D518EB472964C0E4A3FEE0A5BD5EE73A94AE77E7C1CE1126E798502FC0A5BD4DC4996F9DAE96B82D3C54A758B808CE32E0EEFB829860E4C2417A93F74BEB4A22AE0439A258511A9825D987E646951645FDD8DDE0859BBD9755DF3E481D888D13109AD4723EBF1D7BC417256422CB7B3B7FE84F25D1BC412DD80FAC5B1157AA8D85A1F3BF89DBF2DE7681CF6E529FAA2E3227F98591B76742B2FA084DEFAFA6036DB5D10EA611F634CAFCBD99DD87C991E1E6B5ADA7FA7A9F4117194E54C2D3EE5BDEFDC30E4A862B3960D75979D1D044C29179AD89B31C961E69D25EB19E0827F938787BF0A18A9364AA82853979BD6662123A79C9F8739FA7113328C65F66F31FC2E26CC14B0F3DD0BEF5A675F1554022B26BE3499C883638061A245F6D2F6FE4BC7BE07E37AF038E5418DC4212D3EE677F31776C732BBFBA7771BFB6064C7BD6B7F61C04BAC8FF67AE23F0DF677848886930B3AB2424A14E80458230918F0903F45C2B7F07DAE35921E4D084485B211AA37673802235A9F9B3462A99B12438F25AC741CC7B3B9FF87A30D10A64F164054B8BE2FFC3225CA482CBECA286023E055061C27EDFDA265C2ADABF2F8D18C363EB71EF147CCAA5FFB8B1D90168DF83B4445D5BCD9079F9AD1413E04B16E3B5D75BD552B85307B7451ED7C48C3B3F601E7D4F0D1B2253B8CF01854A9965E72E28988E82BF8C09D5E677490FB5EE64EB339ECB3E254E979BDACFCE892D4B2831DDD1FB2FF81B45B25094012447D7719604D706E6664BF8F7E8CFB5975E35673B9688A84E70A75F3B58D91CB7096F071A650EDC1D9812DDCC868DCB98CE3C5B22FE9E2A4049168C65B3049CEE19FF5C9DBD6E5AF2BA81513524FDA54968B3D5C3054EF751C92524F209B6428567834C40251AF038A376A033F46AFE4ADE6B03FC464A9C00BBB68E9CB7F65DFB3EBC22B729D7D1880FFC5923AE148604D6FC5B55260D6037C7501B5F29210FCE609880B63BBC72C7D693E2D221F4D6F2C2F53C064F2A0B6581242F3D8096A28AC7B0EB582439174FA9FBA60E888501ED2DBB3594F18125104190658BE7A9031FEC3857A49F26A48C725F48E68846619C2BA31B6DAE8D3135C375DB998CE47B3A843B4C1EE5EF405D0465A889325C97E5E6C25F5ACF0A5E39643A1ABD400C375E57A8909A0F9EA9E86E85B69F44FBDB68CBE41601912A109F32072A1BD0718BC1BA1C839B2A114F99969057B6235C4743B0D5D7573B3EC048BC8603A1B822DF498DD1DDCA49B8DAFAE025354E3920F638A7239E8B70375D9DC9CD2D3B4B424E30AD668D9F486AF52D4DD165550760EF084ABEFF10244408891AD6C91FCF31B04A9C122C9A7AC205613A83616C12CD43F2115AD4E1F8E6820A410C2EE3AFFC019054FFF36FEB2F1A537C6FF27DFA4E568C7C4D78D483D61C4A0E204EF018849191896A579AE9CF966336D0898769DC0A5ABFFEFA939BBAF20529ADC9FD9326803695A33029926B23D5CE8A4B71DA47B73A9553DD7B17BBDB3570FDE3E699A848533D6D3072C688DD0C78BD3A83129709E9438812A1359E752C48D9ACAD29F761DA306548403585B55EC905B68D3BC81F35413AE8ED8C750591D38C43FE77B4C26B925CAEF0C2D7B7F4B09EC7AD0E076D7378F4E8F6A11033FC98233181172D31EC3692FC64CF992117770896CA6051EE392AA800E5815F9F32A9D18D932B1CBDC9E94FBB8297E71A242F2AE9114571DD36671CEE76FA40C4E238A8374C8AC834B026E2028137A07261E40FDCB90C24C6DB4931B7B5E6B671FFB2331B2C1796AFCAFF08E47D02160C82A3AFA5A06CA532234F7234A4C2DE482F47A1BEE39DEAC5932B69E5CBA2368D59F58EF8269CE65B854D33C2C388F1A6CD957DA5AE79DEDB585884CB4E53F654C2971E9D19BC46891AD1C16D890778A6FC71DCEC3E91BD531A5B5433AC6550CF9050FDCE71504F5930FC79DE0B5306818EC424C90159CC98B7D927837B232487E1A266185A4A5D15717C11FDF6C4130019BE0132D5955BA220416B6413E1987C6EF0B30C6C9643889F39EE780D73F00FB2CF1F2124E7A116E80CFE9EEEF59DA18BC7F3EFDD40994198C5D18BE64122520E924AD930787C2D1B6674C29C5377F641C8116D36A8D109AC4CC9EEC2F45EF9D6E2762021DB35F64B590658F53D96245B97C516EE54ACFBDA9B3E9208B693DEA95A2EBA175434", + "k" : "E48218A34F56B392B102637B6B7DDF98F3D65C10098003F67F4D266E375A54CA", +}, +{ + "rngSeed" : "16BEF67F7AC3A755C59C816478B75FCC16CE5844DB537791ACCD1EBD49D2824B105FD2E970F728C8F0CF16E439A9AE2F", + "pk" : "98C5377FA74B86746684A02B2CC8694852594B62CC0DEC3C240C49B1CBA8235B2B7220CCA57AA380CA7F6FF96688B70299A0A52E34805ADA0144632CEB704B0F08A3AD9C78DEA9A9F1F556BB830CB0345AB9F2503342AEE2944879AC0103CAA1CFB1932062A04CF473FF372D72D500574660435B756A99635A9626F9F085FAA880F8C332F674A76AB0196A3326B0E88AC19547B6E8A4CCE3A3A60A9590D524E61501A41262CC67A3CF036E08E947E11C33D34895A2D4B7ED348EA8329F8E8775453A65EC242DDC6B33E6374ACD4064CD8C765BB3079550C05E0054DC11B4032B33C4E9371630AFF59986B95B7C729402D61C7CA3BCCBADBA94ECB5151BC60330379E24EB3FC36358CB83C55F18789C37C541E93B3B781D42904ED910ABA5F6A4168336DC351AEE66761CD17617DB2962547D77FA238BC415A6F441C0F50FC2CC88DCC7049FC58C3BF3A3091458278087AB81569B607C66C6B6E4F677B4E0C3B4188DC3D3741ECB585CA68A72D0B18F18739E0194448A1DA0D436F2A71FD08218283C416A0A580588932FAB5903C289BCE9A1B53328C70BB943660CE98773AD14A51783486268C270808CDDF713160068CC8C8682BA11D4A21A3408B181625BCA33491522949FE6A3AE6A2F046619114A0318FC69A3D58BC048C45ED4AC3A610AD1987629B2BD66200BC0E7B083B1B26CCA00F576A2D2B8AD3C5212D956A5EE0985CC4023E9A99031F3A903934F2EC24E2CA46F06A26EFC2A19FD28236E9097420337DDD61BC2B7C15FE9949ACC7C279708A7365CA87B72B635AEA5D67541853530F66BE8DA1730815852CB3C62024BE50288C7AB08A3A2C442307667C8BDCBD940C0A6B91EE1657BE599F13722F1D21848D189B8B389741A5EC86560F1B862EB63669753558190516964C610696E9B24A955D07BF388CA0CC4BD0861B388E5A9F1C78014DA35CA594F9F1B766494B7AB4377EAE61BFD8CBB5E775A4E627E2DC80C17128BB5C314BE217033668C29198CE8BB27BEBC79B1B4C5FD81578EB32709AC6BADC3CFB7C414584BC3A38BA2CA1C9EECA55DB9BC295791BA22AB54F9D22CADBC83EFB58E243517ABD4A93A11BD083950EC71536BC49B39C53D17B8A301A17EC0B90188C800CF2400312B76FD85A26557022909866F5591EB8017440364868C459F9039FF053E6E829AC73B2AEB81C9DFA78703C7AF8EFC6EE88C929183351F752A47E608638C7016026A031C289B936E06F46889E827A1E0C99EC431C763AE80E72B8E8CB87C3B7B74159596A9CC5A6C67253738E6889F5259A0EC87555E975EE50C82CD44428182827FAA7B81A0ABCD009A05685813E3000F9623E1C4536443811C98148FAB9C8941163A57B8C7377D55A994D6CA310AD58012F51F94BCC9FAE366A0591ADB9A7A78E78478D1076D65C8F029867D69BE153CC7F7B7C3F7F6B5F1832BEA256F3F9B7F1165978ECA35728115A115500677C1BD232FDF7145ED07810EA4651985A3AD7B5EDB37BC21E33115D4C8C8B5094419780831C65B88A7D934BEF0B9A52CA4299ADB84A6D9053EB4999A92C92B353D9823896D3759C3DAA69879782785017747C102E7AFC0A330AE96BC2E7A4E6C4B5A637B2D85EBAFC4E6C4CC676F78E29E6EB5B8A4BB942A797D78CC708AD3CD2F04217F18BB3677318D3A917DB689599C009D3897D95B586E899E5855253CF54974EC4F6FE8BE5A4C6804C99DBCD7C3E7407FA99B90A5586E9F180AA559A81978ADBA7B770A4C601980AD940CCD42EB70010254848B8C4A2886A1D835ABCB9097253E2FB817425525CBD37C1B8B3A2EF47E8A15147A6A441BE37E7B2579E5F74641C4731CCBAEE47B1F5BD744A15284239179A70A70BB8217B1371F928B275E14C83554788687ACE377888321C87EB5403CF3C93CD4C9E302B63533591D96AF9AA5C47353C03171CAEE118BD868A6FE29575F5881C5A5BC7F67A2DD5457EFD71329473364D509B02914D543843CC3B36E213E27FACD6F0369F165ADCBB314F9C4C8930564B9F5AAF21C82860035E9F729DFD30584B8CD6735AAFFF819F9D244CF8BCF9EC15770903A3CFBBFAA385CB960692923B88364100FF67A2DCA71154700E0594DFD66AE557CCC6FF36519A2252ADBA29881B7DD1283D3B621B40ACDB3BC22FAE51C5A64488A3993AB8FDEFB1682784EDD39F0FD80883FA378CDE6EFF656F57119177C56A9", + "sk" : "974B92E8755220BA2F34234C9C59C29DE41C7B9967D54334AA259F05A73E43285E4A6AB005A36528153C5599B79FB680F2D82559B68BD3A46B159C3F2E28C960D6CBF8C103AA205FDD885BCBE2C48723B789766038678D15F72ECB96AFBD340D4A17AD153A8F31A1C6B0F8291F6B5A1A4979197BA6CAD90C26E25F6424CD1E856C0FB5AC336A01C7E5C472C575AE15A5264263D3F82C11A8111AD7A88D536884C664C4A52D4ADB85F1A3567F48CFE068C038F5C10813A99EC6C605920CD481A6D6E0BA5409A65C6168F3D5A34E3B1FFFD16BC5522D7861441300C550022EF3235C85F5A1FDB6B7C4742A42351E957666A66AA918D959A4F10D24533ABB63196F44426F19302B3C0651779C690CA0A108710F4A8FA001A25F6619A49768416886C5D34DC8EC3EB4A89824E04E67CBC87DCC392D64004B5386F40796C71C017E133CD7853F2955289D7A52D7388DFFA436AD1363C03902B15128285341217A0832F094BC37733826C13C0886E123A490741EE0859923EC825D26AA4A3BA5C094728F83956596A14F12B4B0958FE01BCA0CF557265A5B5F367917D3841E3C16B1DBA445038CB95542F7276F906136E7F76C32EA23D78183ACC4BBD4067E08E3379CA47C2F37A4AEB1B2C4E4023B8B241993BFCE492AB7FB26950B4AC8C5BB1F7BC209957D72A2A87D0B37E0D74C08268BD81822D4272F6048997E9449579B4F972BBBDF1A2083F49996725C68693EACD63D98F3BAE3FBA88DAC46EBA99ED324C5BA3523C5398DF6035DFDB82E48A49ACC15B823D51D812CAFA9EA7041BB1D6B848CC4C1CB0BC67EF6A7A6D9B013F3356F353B1DC5C5934FE483099300A800C82D7513D8286E64D5B87882C03CFB1C981B2613D5981F92026F46403286136FE40272841EAE68C34E56363226CFAF0C7FB4A64FD094A7CB3B1B8DFC7BAFC2552BF98EC7E8967B46C70E4C0EB649A8F0464612D08B69A72B5A89820F1C1FD8E19A55526F592A79DC1A475D16099EC133B21C973C90160D68CF4ED7282096265DF929B43B0B265982B4A78A72317CD603C09F70B622B14C31F52F68A6572D749B60B92BCF4A7F3C539DA10C8C3C3C4131EC88485225955B63FE8617703C499F9201BDB583D07CC0077347E28B0275A26CF2E600122B73D8B22BFE17CB4A48183211A4C7A83F8002004DEA91BC2863B6B9086DD7A8965795392CBC188739702CA7EE84C85C867FC45431A7579DAD1BCDF5162D876499B039571174C44D679A7475A156EA73C14113AA206223E90A63C8B450369A89FA59FB65AC7EC1CE8E830B84A9A330E63F7F494A32867F6A815546D100FEC9482771871376CCD5AA649293C57800792275349BABA6589327DD883053F59D13695C41EA73C8B832A5521BC234A73BF668C80C7665A9AA98C0560DA4A6E9CCB0CD7C77EF39670A731A53A85606911B900866A8D272ABF56F31DCA4D15C7AD19C8D4BB31D9E545C84687FB50757F54BA51D283DAFA480C2AACD8C0206877948E1B8215088AB3C0B019EB42956A00E00E875DD4594175CA709164FEA4A0B3F819E4DD57EF4D2016E799E5D645E8A47267BF714C88080D7329A8F075AF812B3C7ACBFA0DBB477B93B789B76CE445C58B9B977A681E6B22730E35A82851F40649A3231BD7FA1A19FF859AD1B007A30413087C0B98A31C9423753F3C2FEEC9EDCD1CD2FD7A930FC08E811CF49762D792513719B370B7C809DE37BBD53879B533FED6295E3318A03CC94C1F81CCB563AFBB72BF6643C9A80C333134C8734360DFB4F001B27F58B625CC50E20ACABF7E1165D0A22BD96AC403440EB802E5FDA4D0653491979B331F0CE326A8365281B18EC83BD33319BB7149C192EBE202C6E2C2AD69313C12BC1C0B56599B90BEF70A8E70B60B72570BB49C207524850E8A7B549BC07B660E5D26EA8D94A5D1A59A9C8AB17196000C97F48E2B3F060C8B2236F6CC60F6EE09D019CC631809C91DA3ECB2544CA4237F37A20C2A82397E3BE1F0CB7AF6C693B994C8B811537E9007CE088F0FA4C02203B9E08388B186E3BE11093E218C8C3763E9810C9760E26D6C90C6400C349CF22069B86DCA993F36A303436166BBAC8DB1CB9E2A37C155F0F678DAB52ABEECA048B1813D63B42B2A986AE296E3F027854393DCF47004942CE611B9A82A54098C5377FA74B86746684A02B2CC8694852594B62CC0DEC3C240C49B1CBA8235B2B7220CCA57AA380CA7F6FF96688B70299A0A52E34805ADA0144632CEB704B0F08A3AD9C78DEA9A9F1F556BB830CB0345AB9F2503342AEE2944879AC0103CAA1CFB1932062A04CF473FF372D72D500574660435B756A99635A9626F9F085FAA880F8C332F674A76AB0196A3326B0E88AC19547B6E8A4CCE3A3A60A9590D524E61501A41262CC67A3CF036E08E947E11C33D34895A2D4B7ED348EA8329F8E8775453A65EC242DDC6B33E6374ACD4064CD8C765BB3079550C05E0054DC11B4032B33C4E9371630AFF59986B95B7C729402D61C7CA3BCCBADBA94ECB5151BC60330379E24EB3FC36358CB83C55F18789C37C541E93B3B781D42904ED910ABA5F6A4168336DC351AEE66761CD17617DB2962547D77FA238BC415A6F441C0F50FC2CC88DCC7049FC58C3BF3A3091458278087AB81569B607C66C6B6E4F677B4E0C3B4188DC3D3741ECB585CA68A72D0B18F18739E0194448A1DA0D436F2A71FD08218283C416A0A580588932FAB5903C289BCE9A1B53328C70BB943660CE98773AD14A51783486268C270808CDDF713160068CC8C8682BA11D4A21A3408B181625BCA33491522949FE6A3AE6A2F046619114A0318FC69A3D58BC048C45ED4AC3A610AD1987629B2BD66200BC0E7B083B1B26CCA00F576A2D2B8AD3C5212D956A5EE0985CC4023E9A99031F3A903934F2EC24E2CA46F06A26EFC2A19FD28236E9097420337DDD61BC2B7C15FE9949ACC7C279708A7365CA87B72B635AEA5D67541853530F66BE8DA1730815852CB3C62024BE50288C7AB08A3A2C442307667C8BDCBD940C0A6B91EE1657BE599F13722F1D21848D189B8B389741A5EC86560F1B862EB63669753558190516964C610696E9B24A955D07BF388CA0CC4BD0861B388E5A9F1C78014DA35CA594F9F1B766494B7AB4377EAE61BFD8CBB5E775A4E627E2DC80C17128BB5C314BE217033668C29198CE8BB27BEBC79B1B4C5FD81578EB32709AC6BADC3CFB7C414584BC3A38BA2CA1C9EECA55DB9BC295791BA22AB54F9D22CADBC83EFB58E243517ABD4A93A11BD083950EC71536BC49B39C53D17B8A301A17EC0B90188C800CF2400312B76FD85A26557022909866F5591EB8017440364868C459F9039FF053E6E829AC73B2AEB81C9DFA78703C7AF8EFC6EE88C929183351F752A47E608638C7016026A031C289B936E06F46889E827A1E0C99EC431C763AE80E72B8E8CB87C3B7B74159596A9CC5A6C67253738E6889F5259A0EC87555E975EE50C82CD44428182827FAA7B81A0ABCD009A05685813E3000F9623E1C4536443811C98148FAB9C8941163A57B8C7377D55A994D6CA310AD58012F51F94BCC9FAE366A0591ADB9A7A78E78478D1076D65C8F029867D69BE153CC7F7B7C3F7F6B5F1832BEA256F3F9B7F1165978ECA35728115A115500677C1BD232FDF7145ED07810EA4651985A3AD7B5EDB37BC21E33115D4C8C8B5094419780831C65B88A7D934BEF0B9A52CA4299ADB84A6D9053EB4999A92C92B353D9823896D3759C3DAA69879782785017747C102E7AFC0A330AE96BC2E7A4E6C4B5A637B2D85EBAFC4E6C4CC676F78E29E6EB5B8A4BB942A797D78CC708AD3CD2F04217F18BB3677318D3A917DB689599C009D3897D95B586E899E5855253CF54974EC4F6FE8BE5A4C6804C99DBCD7C3E7407FA99B90A5586E9F180AA559A81978ADBA7B770A4C601980AD940CCD42EB70010254848B8C4A2886A1D835ABCB9097253E2FB817425525CBD37C1B8B3A2EF47E8A15147A6A441BE37E7B2579E5F74641C4731CCBAEE47B1F5BD744A15284239179A70A70BB8217B1371F928B275E14C83554788687ACE377888321C87EB5403CF3C93CD4C9E302B63533591D96AF9AA5C47353C03171CAEE118BD868A6FE29575F5881C5A5BC7F67A2DD5457EFD71329473364D509B02914D543843CC3B36E213E27FACD6F0369F165ADCBB314F9C4C8930564B9F5AAF21C82860035E9F729DFD30584B8CD6735AAFFF819F9D244CF8BCF9EC15770903A3CFBBFAA385CB960692923B88364100FF67A2DCA71154700E0594DFD66AE557CCC6FF36519A2252ADBA29881B7DD1283D3B621B40ACDB3BC22FAE51C5A64488A3993AB8FDEFB1682784EDD39F0FD80883FA378CDE6EFF656F57119177C56A90B6CAE64DE81B6F1395296905389DA76CA7C5435E1C4B2D93CC5C303D31BC053B46F84F01FEFC519E118AFFC4A7A1560F1F8ADD6DE72615229B997B2CAD6393C", + "ek" : "7A89DB3BFE12E8BC60AEDBBDDA2CC39811516C53FE273481A7BC46155175E923C380D1BC7FE9F0905236477D089BBCC3F03B587FFD9989EFC92CB1A16D8CDEFB461EE81BDEBADED397C0A41D29E7C84B2856B76B85C90C7683CE80C4142832E39EC6478B9D08A01C6353297EA639BC9E2D3A543E0B73A6ED297D2498561AF695856D10CBF257C365693DC23071DC95324B46459E8E7AFA60380657604956271DA674C65FF9410B3236F47DA47E7D043A98391BD7A4C0E9B93B4B6F9F7B15B98B23B1F67C7AC77C66D2A7F8F761531A332CC303A4415F61A448A677F33E98539168B3F281E8CE58F85D8DA0C46907752412BEEB3A2F20C6AB8FB9F336B25400CECAD103D5BD1BFFF9FD6B9135BDC910675AFA6BB6323D115B7904F4B6420849178C64A47E156FCC731E87F78324A72DDD2CF35AC9D2693E4ED4CFF04E74BA0E40F4785F126BD4673D8133D0A251F852811F0998712D77EBCB04314F92DAE5C9D9BDE93B98697FF33D82E0520D09F3CF9C2C413E9C5ED50B8672CEEF31A8138116A304A24D507F2AE26383874E6A92CF4891F65E774B480CC9985CCFCA7215A3ED3E9E0D6DA5B8F0DA476395592B422D67C28775CC2CDB507C843EBF28A6BC220A0A86B73D42F4E2D02EF9AB33854776842A68068EF527003794EBFE1D909E1A34664EDB98848CA528408341A74557487E254A88E3C125994AD0C29FB9D45E7E6DE2ED3B34D86542ECDA48A3EA886FED0F3AD555329E93F75E4A4BABD3A0D67D306BC0ED6DBA15FEFABA5B5AF18DC7F730B8689762315D3D593D5A6F8F915FB1B5EBE6CBF4E04B1C7F5119DD07522DA2649F8F2324B51830BCF29B481656FC196EF63383EDA33D816719ED9725AA24B26E66CAA74E5B9DE2183E3FE3DACE5F1F202999EE2A74684EEE646FB71FA8E0E83CC026DB4A5FC19EE5CC08DFA033A4F735514F57423FF5DC8BAF2FC371789F8E22713F8CA35885CB4CB02E56FF76C6A2F8E6AB4DF7E394A14C3642C9DF6C8BCDB02ECA97C0F8C5949083927CEA3981B0DAE31753FF54E1AF1892D21653604F4AC9EA779B5AAEE7C951703509B503ED682B2864E0DEB9B73B92D5185D35CF150B17C9BE7EEC7E2541F14B1055F4E4F42D6121EA534E676EF7B145D1B645C08F17907E0EAB4C2543E963F72AC20F15C6D732044149045B479766C68A6FA7BD3DBE154522C49A134938BE67FAE7A96B00338047FB067BE6741014C0F4E4DE93B66944E742F908F26E3ACF604445C79F62CE4153C2BF35EEE94E199F35B9EEC31F3A1FBFF946FEFAFC8A86D96960C72A44E8DFF8BFED67B31CB99E7D72D302A51B6702F511C9087B9BD8F71D12E6FF1CA55DB33F0AFC7F96C0EE8FB6942D27FE56C55A31C24AEB33B95C184821DAFF7A6EB5DA141AC69E94BD3E807C2FB77AE6A1D912B25AC39196A3870FC5A3956B9F1B3E7DC6095DAFCDD75B9222CEC5A1B44924FD0523C64B9F8A9B1CF75237C0CF84770F92370F1113EA38A87A92FFA8A027BA90357365187E9A0ECC0E58EEB0D798748B2B3B958A18A1463F967776F759515B9A7BD645FD6A658C2FCB2FD1D9DD4CE1FCFB9571BE57330144616184DBE4559CAEB8620CF517DEE54927C122CC8E7B8271B32F4B318A6A67A47F1AA756CCFE1B50CBFF8F4D5E04691DF1FC27F58215761443771F4FA004029D8A7870ABDED20DEC2E8F5AF5E4F757CFD8344990D6CA55721205403FB8EE80CF3D6416BEC112806A8A700A2C6EB2D0666CE59AD84F21DC561DA623E02662F438780C82E53CA595E511326110F425C6F0B68C4EF0E8600C3FCA0DD4228AD9BED941E4D99B8A4A4E07B6450365E9AAF30A23A640A96D5796AD2617C80613972796867B414734E7E5AAF6FE088E04A4CF11E95FCC5528A83A3854CB9A04E8B62F5680881AF92B12F7426AEBCC1EA819D5553699095A185E587004CB931AA22BAB3B01AF60EDD41F71B87A06B9B867057766BA6E768F964D01EA877D290AF6FBAD514798CC9F952AC50A3F27DD5E5AACAE5BDDDCDAFB79734936B4AFB64ADFF5662F168BAEF8F0A3BB05957BFDD2B8DEDEED5A78672ABFB8F25FA006CBAD8949135BABC075309663A4CA020A923371753D164A9B9E91C89BD4C7D318BC293C3DA3AFCD6D7407C9C29971D5D1B00021CD7E7E13D41DDFF85B711D8361B7D3FFE9BAF73C2D01BAA52DB3FBF34EE3670C43DADBA9F29E68DA0D585B", + "k" : "D1FE43861044B625AE701942E72755D146F88847C82F55B24C8088A41CBDD3BF", +}, +{ + "rngSeed" : "D0611F9AE5BE4DA5D7EADC9109944348E716CB3DAEE545721EEA8C892E7831CF2E54603146454CBFD92387739E9A78D8", + "pk" : "E5BC009432C97A66BEA57133DF41CD6D6095A69192226C8A1C6A0416DC13BCD39CEE2867E991102AB5C7EE37AB23D33E113B3E7766B7C652CD0FE03FDCF38653149139B532AC46B7E80229C2576C44834080B75D9F2490D79A23E6D6CBA707458C90C7BB758E3C7049D5868B32E2C50441B280BB1FE7528924181051A9B35C6AC779645E6554B5DEB21959754F3A47454837B9512820D04722A884B10E01B5ACEC05AECC2A778091BDAB81F0091ED67A7C7D062085866DF21734959206733257294A4C82A7295A739638141AA3821C764891FDBB64DBC6AEBB67A8C82CAF86F7248AFBBCE556055405ADA63AC9F6423DE12447D89746FEA494662A69A021733592A0FED82749E73D4C2C9D192C994A535F126700A6C4CEE988945353C9E9D2240828BB674BC98F22A298FB6750DA5EE76345EE1B2DFDA01862D2116E6607D3C251ADE46EF82974EBD2A14502684BE1CC3EEA46CF3C2B3C4C14178A79FB495A44275CFBDB5A23AC7B8A911D7EE2AC0672B997CCA5D4442A5D80BE02C149C0C333CAEA0090937DF91491F3E03CA3F8C85357001E4B0C1C9A73BE64ABBD7C68776179D4696FA138834325715E115584C368B720AC8EAA45AA4176E9860200CB56C41143985A6BAE63AA16733464ACB2CC948A949528BF6A91156A3A6BFB55BBE1980D499543720CFD435289C880AD10A4E990CFA2548F17BAB1FA31A45EEC41361198DAF50F22A271C7F1ACB7F70463B9B4C82B71228644B3421325B09DE2946B829B31E56B0C95727C762B5B5D078C1BB46FF2596B4DB6863987C69B26225BB9595D612A5A464D84B6BC775701FA5559D5C8CB55BB30E2E3BAD532125CE9C790774DAFACB19F4C9DEA8ABB25B26A6C6A51E27205B0D2031938A9F1700D353C2997E935461B121149A16F7A133AF9A103B34E2D3180516A5421243769EABC81952A407486E2111238D99BEE90554C32AA12E774DD9B17A5D98CD68029F1BC8671A9015591CFEE86BFB8712A5948B9455CAA51074DB3771F89E74695524FE030AECF998B6EEB301D865F67B9BF4718476026AB3161C77F677FE77A301F357CAEFAC5E579BBD0B34B51B8B58EB71C44C52DC669B9341670BB653CA363096D691680C95A0086601448C619050486B6C244EACAA0198F77D987C5083853B0B9B5531A716A10E7517484A36E38E465E4C855164B2091C8A23E5B2F220524285C739D8B519F55AB1D6C4505CA6A00F6CB6DE0A16E1355C1C8824EA571611B8A3925C4FC64A5DE44A2A1BB189D48AAFEFA13ACE52290A615B5B4339008181D428F3D33267CC135A2649EB113C023432132A0B93BF08203B40EF0E6465C1BA8A1FA517C37C3D363B80D25C70248C52010CD995A866C8004EBA1AE03E56E4783453E52609D6C84264C836857A24F2955FA955041A44C6157BD2E627124FB102EA2BF87B1AC628A393FE09968D707C0F27105B491E19C34DCCC207367AE309CC1A0F0CB0072781C63642823623B2239335A73DB76BD449B401CF5636114A22863B50EE32BD4804006F13DD66B44058B43BE960E9A3A5ADC3437298B05C7B314D3FB9D4C7020B64B6488F70A73811D934BC0A81677D1664BB497949B757B02E074E76C8A2E65410158973E30A2A9B6B034C0BAAA22CD62A421BC25C7BFDA61D0578C1436B808540CBB608CFCB78C8AF6A43188BC26F637AB479A1CE86242766D9DAACCD93C13D1885C7C994ACB657FAB0A75DE17037F637076F2099560799520182B8265F9EA8440BA9E07B084EFA2A6CB244D7DB1A39B10297EDA34BDC82BCB6A2EE871BF13C1CB8EE602C0B3818335895E754EBE75476EE1786D4CCB52C7164C33A76A3B3E2B57B170C34D37295D22E2351BE21A95B6495432A1A5E8489EDABE9B71A4459A4EA08B8DD65C4FBEB66A5058CFE7706D8E09381979B608230C7430879BBBC30A6150AF273CC4D52C5F1C43E723A036530EDDF0CBBFB6BA091B0861F1C751530CE52C947743A59595C15E529104A892E089B912975C7C598B1DE528983B5A66A7A66C459610F63E95A7B1198B4E42710D69EA7A8FC3880C0876DA82CE872952120A666AACCD5B1001B6B99877610071249DB481117CD69F6A252CCAF1A64B45C84C2004EEA971ADE4659E3508E7B623FD9658F1AC8789297A8DFB3DE7B385D927B522126A05AAF40635372F59AF9ED4E64CD55048057D8B30C04FE6C876B8A67009", + "sk" : "B3D43C1965522268CAC5210FF79934C1420C14030E9DA56E02E26AFDA97824904FDF2A107A37BAEF774CA7A87030B1662B97CF678BC3BCF7586D78285BC44A9BBC546A7B1F48491F30F2939C11516EE6CCED064D0647950E004CF966045B871093CB8A42B9C903C5802BACC2AAB484D35B319A0025C330208913220C2A8033B4152EB39B08FBBD468C754DFB47CDF790A300BE561C004047826A03A175C285B5CA718919A119FB80F1F43E6BB00EFBD44C1D67C853C118604CBF2B980CF312CAF81793558050FFA5BB3643CD86788C6F5734CF652ECA45301EA97283F6C52DA4ADCBA71ED4E1ACD3499188D555082AA43FAC55E8E45BAE0C023801133EDCB2A5665BFB7829620BA4E21C746AC2C1E46C4000D93AF973810A881C1640562426424647752F162D2E65BBA6020143AB7FC2486401A30F36E3A81040B4442382608A02C4031CDD6A9569229FEE9C87E668A77E9BCE352704B8220136F3439C37C05C917EEE0578CB2C689A907E2B2544D26444B1F0A11C0C34B2BB0806A072E39C6952E28A08515DFDDC80E19413A2A3AE74092D34C2CD71E770DEB1CDB1E15A497A0DEF06B14B6CAFD066713F44A77755A7909BB4E90301A995C280982249714A72773493F060F6175A51F61A340022E69125716661D235B5AC124DC381A15FB356DDDB3623C53FCEFB0865D18C0A4B1F028704D50313DD0BC80F674D563588EAB3712A5C4903F27C4A9A3440443C31C2BF51F21FA9E6417A5479C2B5BE1A242FF9AB5DA06124F7544172456115481E8441AEB7A8A01F218E286B9B52D5618CD0B05FC99A02A24420A359C3A7A09BECA408915D4FFBAAA4865F37670F8744548B5BB8CEB9BF1DEB799CA06483D521E44B63C9E485BB75C8E32C42247B5FDBC137856CBCE035CEC6E1323C9A04AA154585F8A9A6C08DCCC720A3690D6192CA6E63990A5A9C7EF519808C68819A66394829025543BD3A823F729B98175B5E2576BF557609F50212524691F7B6BBD91A877A0B297C7FACF50967059E2FB23CAEE12093AC230505A4D8D8963CC05277361C371B4A50CC638882B068883DE6D69EF590A33A384DEFF6B618F9199099734E7B9C951B8318030A9CC92496DB0E03E738E0A64D1D24AFE6274E5E58B364AB1626FB188A91B35EDA4156C483830C2F603138A660310CB39DFC490E510B88B5AC4AC9006E6888B33B992B8343C71085AD4311356CD5563E03C75517C99E9BB59188ABD8880559D0B8FA290274DC6FA70BC97FC552F4A76B901A212F0364C584717A39A6E66568BBE0A277F9BFFE8355072C75D6C4CFC7EC7BB644B8932B41D191A058F2CFDA77CB3E876D00AD4B3B80AA7E1B83B031A4E3F891FF747B17782F633324AFF6AFB58975CBCC0E14FBC9F90584C51B049E6170AF720CC36C9ACD7002ABA933B685B34C665E90A4219D6721A71B79402ACB2E53480865B62DC97432D800BE255E7565B5F7BA6CA39C6FA443CEB79308EC9C2527A799CC75535082BFB4A5246EF8026EF925DEC7164BDBA472DB7919B17458F83386764B84E83E51E20B41346D424C65B7949A9DB6AB79B091F3A980448C0D253C36E9808D586C6E55E669C40BB9633A156733C76AA709B4BC9A877717B5BC4B0CD91EF75C0272119370B8401C815C129836EF785FAFFB25EC787188F40990F986961C5E785B9E6627913F7B2163408A7F99329314305C0B330BFB0EE5759016B4232E06B627B84F6B51843E34425DEB2BB8E10566E91B37A3657C2CA240F57711420094134C9242936C4A76582686DB9001635723C63795451537831460D0B4140FC811CA977FA2EB7BAB8A597A162336790697EC94EE684DFDF649E327CF61A15F2A6262A3001C5A342ACE47B394626439B313F9E21382987ECFA533D09C6A489B2FF84C63C0F5B4C3F8895D2283CD59305CA7248C6B293AE1B4B3071E5CBA9058706A1EA9ADD7FCAFA2C50B86CA10E3A951A5FAB5A0015EF09901B36B4F4055087A5361ACE4A1D2ACBCDFF1048FE17BD84B6C4DC05BDF4C453D18C6250A8ECB69B3DA26CADDE7711C0520A59AC94EE57B77A6AA13DB76BFC40AF90161E3634459B3263AE233178796148B592271408FF06B5EC012F5C082E107510907BB36E330D5C9BDD1245242D724A6D438085A30705662EEF25FB465A9AA584EE5BC009432C97A66BEA57133DF41CD6D6095A69192226C8A1C6A0416DC13BCD39CEE2867E991102AB5C7EE37AB23D33E113B3E7766B7C652CD0FE03FDCF38653149139B532AC46B7E80229C2576C44834080B75D9F2490D79A23E6D6CBA707458C90C7BB758E3C7049D5868B32E2C50441B280BB1FE7528924181051A9B35C6AC779645E6554B5DEB21959754F3A47454837B9512820D04722A884B10E01B5ACEC05AECC2A778091BDAB81F0091ED67A7C7D062085866DF21734959206733257294A4C82A7295A739638141AA3821C764891FDBB64DBC6AEBB67A8C82CAF86F7248AFBBCE556055405ADA63AC9F6423DE12447D89746FEA494662A69A021733592A0FED82749E73D4C2C9D192C994A535F126700A6C4CEE988945353C9E9D2240828BB674BC98F22A298FB6750DA5EE76345EE1B2DFDA01862D2116E6607D3C251ADE46EF82974EBD2A14502684BE1CC3EEA46CF3C2B3C4C14178A79FB495A44275CFBDB5A23AC7B8A911D7EE2AC0672B997CCA5D4442A5D80BE02C149C0C333CAEA0090937DF91491F3E03CA3F8C85357001E4B0C1C9A73BE64ABBD7C68776179D4696FA138834325715E115584C368B720AC8EAA45AA4176E9860200CB56C41143985A6BAE63AA16733464ACB2CC948A949528BF6A91156A3A6BFB55BBE1980D499543720CFD435289C880AD10A4E990CFA2548F17BAB1FA31A45EEC41361198DAF50F22A271C7F1ACB7F70463B9B4C82B71228644B3421325B09DE2946B829B31E56B0C95727C762B5B5D078C1BB46FF2596B4DB6863987C69B26225BB9595D612A5A464D84B6BC775701FA5559D5C8CB55BB30E2E3BAD532125CE9C790774DAFACB19F4C9DEA8ABB25B26A6C6A51E27205B0D2031938A9F1700D353C2997E935461B121149A16F7A133AF9A103B34E2D3180516A5421243769EABC81952A407486E2111238D99BEE90554C32AA12E774DD9B17A5D98CD68029F1BC8671A9015591CFEE86BFB8712A5948B9455CAA51074DB3771F89E74695524FE030AECF998B6EEB301D865F67B9BF4718476026AB3161C77F677FE77A301F357CAEFAC5E579BBD0B34B51B8B58EB71C44C52DC669B9341670BB653CA363096D691680C95A0086601448C619050486B6C244EACAA0198F77D987C5083853B0B9B5531A716A10E7517484A36E38E465E4C855164B2091C8A23E5B2F220524285C739D8B519F55AB1D6C4505CA6A00F6CB6DE0A16E1355C1C8824EA571611B8A3925C4FC64A5DE44A2A1BB189D48AAFEFA13ACE52290A615B5B4339008181D428F3D33267CC135A2649EB113C023432132A0B93BF08203B40EF0E6465C1BA8A1FA517C37C3D363B80D25C70248C52010CD995A866C8004EBA1AE03E56E4783453E52609D6C84264C836857A24F2955FA955041A44C6157BD2E627124FB102EA2BF87B1AC628A393FE09968D707C0F27105B491E19C34DCCC207367AE309CC1A0F0CB0072781C63642823623B2239335A73DB76BD449B401CF5636114A22863B50EE32BD4804006F13DD66B44058B43BE960E9A3A5ADC3437298B05C7B314D3FB9D4C7020B64B6488F70A73811D934BC0A81677D1664BB497949B757B02E074E76C8A2E65410158973E30A2A9B6B034C0BAAA22CD62A421BC25C7BFDA61D0578C1436B808540CBB608CFCB78C8AF6A43188BC26F637AB479A1CE86242766D9DAACCD93C13D1885C7C994ACB657FAB0A75DE17037F637076F2099560799520182B8265F9EA8440BA9E07B084EFA2A6CB244D7DB1A39B10297EDA34BDC82BCB6A2EE871BF13C1CB8EE602C0B3818335895E754EBE75476EE1786D4CCB52C7164C33A76A3B3E2B57B170C34D37295D22E2351BE21A95B6495432A1A5E8489EDABE9B71A4459A4EA08B8DD65C4FBEB66A5058CFE7706D8E09381979B608230C7430879BBBC30A6150AF273CC4D52C5F1C43E723A036530EDDF0CBBFB6BA091B0861F1C751530CE52C947743A59595C15E529104A892E089B912975C7C598B1DE528983B5A66A7A66C459610F63E95A7B1198B4E42710D69EA7A8FC3880C0876DA82CE872952120A666AACCD5B1001B6B99877610071249DB481117CD69F6A252CCAF1A64B45C84C2004EEA971ADE4659E3508E7B623FD9658F1AC8789297A8DFB3DE7B385D927B522126A05AAF40635372F59AF9ED4E64CD55048057D8B30C04FE6C876B8A67009F33AA451C6AD54D556D60210A23DA8FB68662C39A1E08D893E1D1E784FB717021056461570B29E27126962068B2D07EB33DB448A2938785E6FB3E02675A6EC67", + "ek" : "1AC10A1B289DDAD129C9AD7D5A31F5736ABDEC6A0C5E01153856B1E91719D0561851EF843D82B3599B2AC4B5E6054AC0B3B7CDD2F70F51C1FE4C7CD78648D3E3CAEAE7D044A4DBD2E6D06E5B8AB383BFC37F46EA1313DA777B17E5097E6E2E105AAEACE468DFDCCC59C6B664DF74BBB7A95ECC5F694D58AC794287A90AAC40DE0A117AF929C160A24D3FC19B089837DF8A55A07BB2D4B31415BE52594C169C96EB14236F6325B8D197219BD82F885A1F77AA70C26A5309DF3CA1B3D14CF607974BD3978DCEB22DCB5014E1A2442516D1A77FEA7F30691C8D6B21A29721E89DCE7E8400B8DFDADB3402A05D6017C249E7404BE10CDA682BCD7C5D9788ACE64B824298F31DF9D736A470B200E316B640A4BC075543337F6F6A563E6430D874ABD7BF9622288791595E2C52EA9FE6B24B6E799A78739E15D27BCA89C0569D1D7CE2FFF022489BB6C43F41565EE4178C7ED1CAC5896F68150F2DC5E7D573C600E5410C46ED5007A5A88BEF9193AB85C33EB5B2B91EF9047B03105587D14AA1AE6D7AA6DCC1DF37E8613FA7ECAFD720DA729D324F70350FC3D3D9B43D8EB3DDAB720089D3A9B4319F74712D3FBFEEC3CEAF647A1CD0765FBFFB08779B9AC4647687D10DD690BE7EF21752AB634A4EF813B8BE125D6A94CB61F43CBF1A08A40BDDFA64BE9F3DC2833FD6C15DAEA885CE1661542927BF894210E5DDA01E6F60F08D88043F60D9B965FE479D13748E4C88BDF01E0AD9D71169E7A5C0BBFB6E51E890D16FD79330C7D423A1DD7C8F84B4C26C2DAE403B4443A9A34D06A3A0B082560F11B39D21FE67D4835887B9A0F41C7AF3F111CDAA7F71EDF11B7217DE2CF960ED8E465D65A10ED3FAD2F56A3C9DABF512A793A45E0813F9F9723B76A63B36F24EEA7183FB00BD44F7D20722474D5D3CDBCD8DA6863CCE4EFA0B33F5CB021DFAB621023419586B1905148368339A1BBDCA748DD13B03366D78ACADC4217DB2C44ECDCF0D856442E22DF8F4AA91D243BC15F0A2CED1D907483A332A8DDEAA8106A39722BCE8BF169DF4AF9E8179DF192261DC5F89A9EE8365EF008A0F31D5CC37DEBB220C2684295D8E192C0197AACD5F9405CFBF1DA020A1E1BA22422730B87DEA8567843C431B4C88D05830748F53A1AEEB1CEEF7EF80EBD0C2AB7139F6759FDD099134060094C751844E12D7546B2F418F2C5D359C0A86BD2A45BFF9319E218FB000C1D9CFC0D83FC0A416583FEABEB64417EFFEFFDC8116D4259E646DF9F7C834E36E71D20FA678EE672F3950FC30113CFBB837A72E77B48F7925EDB48BD8C253555F9485A050B6977383925A185EA047CEE8C233A5FAF3F6FAA9284B43BFC00E7C1C21F3B693E4DBC0889BB258CEBF4477919E7ECC67179BE8D80580065B151E0B90A96C9EB46BBD04C7CE6C1E4388D3CDFB471CADC8A2745A84D7D25A1CC17BA87CD24AFA03764CAD146B22615CEA73727EB1F58C5D9DEC7A9FAAEA90209DF035504D1E4E7635B4D1FDC916314F1D940E3DB472FC410308B4FE885548170B8F028669D6C5C5C303673CAC33CC14BEC23F9680476D7AC59568EDDEF4080E64349704B9307E0969C62247AD0DE0B8FE550CE25F53231483B9CCC6BEBA161AE44250F99AFC13434C86F6E5F7487F65EA76E002FAF728AAE3545E7F4346BDDCE321A829C3DD027DAD61366CFCB3082356832937D3EFD25C8A34C0AF587EDDBAFD5506E755F910482A110E57C82D3D71C918AB4C82A38EF8D751D9D16C7A60FE540980358A15335D1C8D19A6090389CC7CD2C34EE7072B4796F786883E1D01839F38739462952C135D8D99DB12476C1D7BF494943E715703EDCFD8A58A8A6C7BE433CE35DF3B82BC04629A535E4D81D055B516FA591592303411E4DB348C796AE82D899AA97B1586985CA2CA1E88F89E5C9A7B3112587431CF07EC24D4C955F1322D4BF60B2C9407E350774879F2705255EACAD36C2F16A0F0617A2477BDB080018BEB63C3EC4FC3FD474A4D8EC24FD2B548E3098DABCC22784195169375BEFE75C8381CA01BC541DEB98FAF90B38DA619855A24FD50DDCC0EFE92EF055324F4BFA38E7A29C95CEE8D2335631BF2C13D910092F7BB77CAF989EDB90D262EAE527F88488F3FCE07E07E3CE17C2D6F8DD28E388AE66C16D80DA8FC70D29EDF744E47682F0399A6BFC61384B9E5B0FE7F2CFB729CFAE9742C2AD7F9E0F0B418073C413192", + "k" : "C69E857DCE0291E374D121984E58A3B468A1F775846A606B71E743F879F52A69", +}, +{ + "rngSeed" : "FBC38D7614D7718E931EDB850D2C6F0C5EEA9EE889B3E25BD69AC255D5B91E885D93E808E66BF9C88C655DC594DA5792", + "pk" : "5E8CA56E95A1B844147C6011E93057B8D35B6D6052CA045CC1D8444C1B603FF211FC67653A03CF7D3930373206D4AC62090712BE287EB6404843C5C1208B0B993C028A445BE50550E2B5625E3124BC58B256EB0886E74EC7F0C4D082A143139222B80037B61649E1B4F3079C3F12CD9742486DE788AC1A987C158F5D20296742AF5953617A5608B5B965CE1CC261139655A09936F555AD8882F3D7B823C400FB7056ABD05BC4CC18636141A3F0C0688B5CC04455B768BE41096EB7676315F808953C8AA95656E4686C89078E36290FB0B01697C56E41A0BDB7C9C6C6AB8F50EAADAE889FB9E0A41D757EC6756BB6E690819B95BD02386398817E1C9AD7DB807A842E75017F5BC6B46FA6CD1580993C1238AA197931C9B55D333E953420DEC916DCB00B657B5C6FB538468A855E830F1AFB9EB356098E12226A7A0718919DFEE4CE6E275211804079BCA97F291355790AEFF36F7BAA99C79CA6A4FB1979331494407B33CC6FEF3663FA018E28D76E49EB1B5FA828FD7AA270F917E143A9A7938BD9A05D9E483A2D7725061A88588C3DF6935ED6C411A149C634D0376DECC87D2988954671C8E9249F517EA3D939AF8A71D505A628958C634221F11BA962AAAB9FC91565FB647973633A4946976B379199105EAA8E8721A12EF43325F08FE6E173BAC2243EF74F92074D7E96124D70B3327839806876A6D6B982219BBCE5499BC56DF2B45AF9CB67E3EB878D02B881A5CE9EC55B98808C48A2C963D8854F0172083C9BD2F55B15F6AC7AD7156AF33FED0A5B6B668D654B602CBC3E3F9B81B3EB3C476B5BAB8B6C886528AE4699E3768B51CC7F48EA9304D77CC8A708ED08321E97228ECB97AEC4BA224BAF4E684FCF62753985C8EA07C86F501433F40C21F6903CC8166A7332C0B6A8A9C121C41C35690413E98A1A0FC672FB1CAD48D74044811F5C7363D7B03FAFE2A6A3634D850CB4FB505547B72DAA710BABE7165B50BA090338F6001D8744041B5B3DB9DC2BEF60C5B73928889975F51548AB72B4B88A85CBE2457810115A9121F72A3D8DD6BD0C0B2476B2BB9E69A7E613A83D820670596353944A26A16115FCA33C505A4DBC5C1136AE3A981DA1D1A4B2C25CA0D5474916675EC8817A969E78812414053A4D0245D86119E1072C8DCA8C211B9BF3C91FEE350F2A0A392C4017C5705655F26657C5090206270140BB93718C37918B4CE79918A9356161B00F09A43AEA259FF94D0DBC95A6B83EDA5326397750C68CC6B498CE974235484AA453334E05C8232DBA3DD1A182BA4543B4A944A5220C46D56812E125C06BBA360BA7759CCA24A1CC02B13EE9FB75CE8459DF3C601DA31AD552C153F789905A105929A223E3101F32431F346BCEC3A128B0A3C3D4290D270B34E643E17BB5D53B6D248455502C71EDD01654D028525576E3422BDF69571E9C10CF3C3C30227C89E2CE0C62911E5014B78B0CDABAB060579EBF1A517414BBE5343BF33311C0AB1F659B3D30727184EC1AA8F1C3A3DB45FBE215ACA961FCD8CE98429D381995280CA0E5E78CDE55442518476E0B404A2668424719ABE71D64083FF8B63F285396F5989DD4AA9332426EECE567D8098951E141EC43747C17CD9B1805F9245E0819AE416C61F3C60818EA448D397211E8B97E755494F0403A133ABCD0882AB907E55A130528A5AC535ADE736081D1CABD62980355CF85F84559EA36D6D3855030C341BABCF65A20C9BB67ED4901F8B2617C7B9C8466976DA39C6780003B71A74F6A16339082E6A62458835D30F1B32041BF9ED21C65EC59DB3044DAE0654E743A5E65836A4B9C5D2C9C4DE859B1A6755AE7860FA6053DE71ACA0A61CDAA34EEA773867A7CE66654380219C7B756D117A81E1C1F81156C6D5CCCFBDB285C831317E5CFB8FC50B673600BB46469BB3C7C6072D87CC3B17BBB65B95E81875548B63E3024A24A329A4BB1404FF862EF10BCBE6A997C847650B5402B888E0D71C900D4A4A4CC429D717D3860A6615869F734244A0B25CD463371B189A243733469BB5DD97CB3E856CDF2AE64FCB519D9BE1A75AA8794542F51BD67878E9A1B8F6D70A650B05B6A609CA9F477579264B127230966A289295719158B63931A3C0CB764E4847C9AC8BB91598B905A650A0123C7C0FB939F7E3943A2F3BAFA20A221F37DC17933CF5E868B958E4E7CEA4CFD021EF0BA63FF7A7250D21513171D5E", + "sk" : "D246B3612B31D8212A89F347BC6411C7F73E78E23A18FA3972A98DCD857165C070DFBBC8F62197E22B40E2021D5BB1384862C61A6380E042B3714695C515C5A984ABFEDB949F91C0AE23C4EDA48A276C9CC9E6911FBB4B20620875127704EBCE55DB5300EA34A1C76DE6A09C7933A1740552762A2D1D0754192019792A068942574037B949830C2121639E630449B1BFCD02970EA8887F4BA1CF278D819B14F9B58BE74566846C742AE150A70380FD0AB9CE2557B2349890969AF0BBA2FA05335C28B2B125806C637FF4B70095F66E41C136AE3B400323CB04909C035B3C6AA4C5676590AB448C0E6AAD6F246A6C59938AC3A56AFA0E4E23844220741C93507C445A9EFC53C7E6298305C5DB623D6469C15A4BC597D1AF24A532AA935AACBA42DA1831B8FCC344088B090A1B08031BB2364E2923AFA448A6A7A56C45A90181527776A70858631FE304ACDBD37036C83F976991CE8AA99C2252B73C6E54CA894301832C129DFA45B59A023EE45229CB8B3E34805B4D4590E857BCBA451E9B6C009ABB9A92A19B61F2B814325860680934F30847B5895A430B843969B24CB6DD1C66900569088897821AA058C2C814F3B7A0B14893F96FB241029141C90F63954709187186538B36C4C44536503056D740536D8212236925DF8C7A5A19AB01C70A5100759FF5B46AA5C78A8833DC48288BB432B2E741D1746F0F81245982395C39AE716BB35EAB66551A1F3C59B873487097D8748A285FDD1A6FBB963E3DB4207159256F2121AD6216DF07628AC607C1FAA3E6B158C5B218CAE892CF457DFC29ACF2E24BC3672D57E014F4143D301A3E00E276F0066178BC08D66CB163157FA534C96D304E489B22ECE80509E8437E23B556217C42B64BE26A3F9A445DC830746B47C011BA941B118965F52F44D126E5087C81368B42F1B73195CECDE34238F2300D909937722F3D2C999DAAB1B395851DB4CDF4152FB699C7794977D819988020836A185F62A57E1ED656166CCF27F50482C517D7D09B65F0AF06651FB15052AA65813B3B1BD1C33BDAB745D9A2A2D7373E9D6B8445E9A35F17A8E47C79FD768BE8F37DBE19A686EC6887D510F8E2181692282557458678C6D8C90CF1208C8470798F4799B5C2C63E0C350B46091B1A40286C7AD955AC7935965D944BAF0BA45AD10512C698D4C6A117BA3132E06812D10D13708285948BBAAA728D2B74E612A5A1F3545FA937A11496ADD908C932849D577B2A7115B4B47E67E543FB36A809D6CC369A1CB3BA357E332B93276B3AF902433B81FE546AA47A322B4812D4955BAC7365F4E33E767068E5928119BAAA867740068351CF70B75E2998B6E77EE1D80409D6B2D97C9732861CD9ACC05B1A1FAFF8A944537EB56B06C3C520365BB405780D12016BAF661BCE454E6DA89507267AA0FCC880078728D12EC0E6B364C60E6D589E50B7371A66CAAD262B729A0D34B08F0798951BE0C7D6798AA99670D9106A186001B93BA137461C0D3B8DA691194F0A9FFBDA4418BC2E97076B8AE3A4FC700531C502FEBBBFC766131DD4B00546151BA804EF08998ED9346C596D804473C54AB8D6F64AE654890A54A3CEB9201A74816D086FA121034A6661A20295BDCA444B1C64C9B77E235CADB4C08D75B5C02F62401208578442BD44B2615D3869F8526FC6F71A08B4A1E2398B81E86FDF3B89A3453569A66E52D5BBBDD670F173529D30950AB1B9166821E8538EFFC1495FD0C268BAA07E5212FC41385BC0A902D85F5F2093601C77B43BB865559CAB77B4E6D89B5A7A0A6D069E5FF839A77603EE4AB29A331C6F9B64AA626755E61648992003A556C210345F33C2300C3504F33FC57C32EC196B1A9A353F04020BB16818136D32737DD4C92F7B4656A83580FF053AD4D6A13EA364431AB1F3D8AC1F510D3FA25D8C33084A10BA42A50943FA22EE420BC7D656492952E157A689C73CF8D45487293B0C8C4245B410848670D66CA54A3A3E016B36FC1227FFCB63B9310B8DD73BFA405B3DA64C69A64173C15000F88DCEC5007E58BB05A81672E02414612829CB7E25637A77C49D434A44F4874BB4F27B3584CF85B3C73E2B9E0BA2A92B977E9C194584B04C3E8C37D9B7404E77802C05B50B3ACCE5B46E54C7354087321B4822CAB148137459124CAA95197546F8B65E8CA56E95A1B844147C6011E93057B8D35B6D6052CA045CC1D8444C1B603FF211FC67653A03CF7D3930373206D4AC62090712BE287EB6404843C5C1208B0B993C028A445BE50550E2B5625E3124BC58B256EB0886E74EC7F0C4D082A143139222B80037B61649E1B4F3079C3F12CD9742486DE788AC1A987C158F5D20296742AF5953617A5608B5B965CE1CC261139655A09936F555AD8882F3D7B823C400FB7056ABD05BC4CC18636141A3F0C0688B5CC04455B768BE41096EB7676315F808953C8AA95656E4686C89078E36290FB0B01697C56E41A0BDB7C9C6C6AB8F50EAADAE889FB9E0A41D757EC6756BB6E690819B95BD02386398817E1C9AD7DB807A842E75017F5BC6B46FA6CD1580993C1238AA197931C9B55D333E953420DEC916DCB00B657B5C6FB538468A855E830F1AFB9EB356098E12226A7A0718919DFEE4CE6E275211804079BCA97F291355790AEFF36F7BAA99C79CA6A4FB1979331494407B33CC6FEF3663FA018E28D76E49EB1B5FA828FD7AA270F917E143A9A7938BD9A05D9E483A2D7725061A88588C3DF6935ED6C411A149C634D0376DECC87D2988954671C8E9249F517EA3D939AF8A71D505A628958C634221F11BA962AAAB9FC91565FB647973633A4946976B379199105EAA8E8721A12EF43325F08FE6E173BAC2243EF74F92074D7E96124D70B3327839806876A6D6B982219BBCE5499BC56DF2B45AF9CB67E3EB878D02B881A5CE9EC55B98808C48A2C963D8854F0172083C9BD2F55B15F6AC7AD7156AF33FED0A5B6B668D654B602CBC3E3F9B81B3EB3C476B5BAB8B6C886528AE4699E3768B51CC7F48EA9304D77CC8A708ED08321E97228ECB97AEC4BA224BAF4E684FCF62753985C8EA07C86F501433F40C21F6903CC8166A7332C0B6A8A9C121C41C35690413E98A1A0FC672FB1CAD48D74044811F5C7363D7B03FAFE2A6A3634D850CB4FB505547B72DAA710BABE7165B50BA090338F6001D8744041B5B3DB9DC2BEF60C5B73928889975F51548AB72B4B88A85CBE2457810115A9121F72A3D8DD6BD0C0B2476B2BB9E69A7E613A83D820670596353944A26A16115FCA33C505A4DBC5C1136AE3A981DA1D1A4B2C25CA0D5474916675EC8817A969E78812414053A4D0245D86119E1072C8DCA8C211B9BF3C91FEE350F2A0A392C4017C5705655F26657C5090206270140BB93718C37918B4CE79918A9356161B00F09A43AEA259FF94D0DBC95A6B83EDA5326397750C68CC6B498CE974235484AA453334E05C8232DBA3DD1A182BA4543B4A944A5220C46D56812E125C06BBA360BA7759CCA24A1CC02B13EE9FB75CE8459DF3C601DA31AD552C153F789905A105929A223E3101F32431F346BCEC3A128B0A3C3D4290D270B34E643E17BB5D53B6D248455502C71EDD01654D028525576E3422BDF69571E9C10CF3C3C30227C89E2CE0C62911E5014B78B0CDABAB060579EBF1A517414BBE5343BF33311C0AB1F659B3D30727184EC1AA8F1C3A3DB45FBE215ACA961FCD8CE98429D381995280CA0E5E78CDE55442518476E0B404A2668424719ABE71D64083FF8B63F285396F5989DD4AA9332426EECE567D8098951E141EC43747C17CD9B1805F9245E0819AE416C61F3C60818EA448D397211E8B97E755494F0403A133ABCD0882AB907E55A130528A5AC535ADE736081D1CABD62980355CF85F84559EA36D6D3855030C341BABCF65A20C9BB67ED4901F8B2617C7B9C8466976DA39C6780003B71A74F6A16339082E6A62458835D30F1B32041BF9ED21C65EC59DB3044DAE0654E743A5E65836A4B9C5D2C9C4DE859B1A6755AE7860FA6053DE71ACA0A61CDAA34EEA773867A7CE66654380219C7B756D117A81E1C1F81156C6D5CCCFBDB285C831317E5CFB8FC50B673600BB46469BB3C7C6072D87CC3B17BBB65B95E81875548B63E3024A24A329A4BB1404FF862EF10BCBE6A997C847650B5402B888E0D71C900D4A4A4CC429D717D3860A6615869F734244A0B25CD463371B189A243733469BB5DD97CB3E856CDF2AE64FCB519D9BE1A75AA8794542F51BD67878E9A1B8F6D70A650B05B6A609CA9F477579264B127230966A289295719158B63931A3C0CB764E4847C9AC8BB91598B905A650A0123C7C0FB939F7E3943A2F3BAFA20A221F37DC17933CF5E868B958E4E7CEA4CFD021EF0BA63FF7A7250D21513171D5ECBA1F135207BD2AB61BF7718DC6825848E742AD56F9F8099BD43905EBD9D6BA72DC85FEF74A61DA258EDFF86F377FF16F321689E7BA5052364D2448A333C7961", + "ek" : "2DEDCD83A118495C5D639F4924444E0361D210F7821506BD6194243799BEFE74A14E2F7963B67D29DB5633FD36063306E7EBBD15942F140C4F3D6C1DDB720FC94EF8426586C9098BD2D53A263D8469BB3DAF599C253A0C9440F6B04DFFAC9EDA8138A4E0DF622B64B458ED1583C7DD7B57014DA95FA516B6F6CD52EA021D348E829DBBBF594BC00459F4BF655D77A3EE1E5A01B94B010C2E77B2F7C2D2D30C83D3A5471C645F70EADB4709A7FA76B74AD2300CE2AAC6FF2738E40FEC0D85C2219F21B2E3CA024050588000D9201BC36A798C861A9FE3461EF1C0A63D6A11370D22DDCE2764BFF50BB833E218DB7C24783F8BCF59059283630BF981E83B34D71A1BB963E779D60D858A8F79F4ADA83DC35A7237D7985268FDCAF3C7B7D7E51318D039BA2FC386D2BE11454143353C1A5E388247471418F712A474DF178FCB9025802959DC22A1A8D31C773C29C52FF28076E51FEC87403C909BE667FBFA13D8B6D9476A5F623A4515098BEF6177EE85D69BAFC244A59768363D273C7BF2A5604F31F918704F83B9956DEEDCA1678BC7A14551F6BE32088591DFF5A31940EF8790D5864905126F093D00480E1DA39135840223F9361598D1A4F22C95B0BAF0905D6F6ADA351A09B371ACEAA2A9247BEDF3B23CD584015A58B974E0A0318A0CC607CCA54C153CD91821F3D9156968C2CF9509BDC535F78B7A5C3D2AF8AA20F33F3519698FAA18C9E1755C0989CC5C53025A6836EF38AD518C4C113FFC21BE582D22355DB6F717CACA7A91E1EFC2119ECF9B088188080B98D54AA531C28E7AC2CA17E20A56E7D3C4C9EA3941BA6DAF6942B2446DF245E16B915BA1371430CFC5812E404696F7E95BF634D3A3FAC72DA87FA2F21AC72DA9A0F96524538194538C1AA44CEE64B22641909CF268BC4B8C532F0C734933D2158947A38E931029F19C13669E7C714EC8EAC901D480F92EE6DE2A5D26E73D485FC02D010114238EFEE911483FF0E7BC792F83995F18B54C101545E83B414D880F03A8549770A6F7C0CB343CEEF56C5DFDD450AD7CC82AEDEDE0F28D8CF258138881165DC31CE19FFD211BAC844739670462D4D6C6F9AA811C42551E47AD7FE6ED2F76A48F926D518B76F96863190C13B08BE9B15BA6C2D85481A2A92815C0907C917079B403DC7A587D00CF1A3E436FD9E4024B3A465FC197903CBAE8A6ED014B9A961DC53319E08632B6EF5D5CF69566E4A2442A54B2051EAAB094CA7BB65A82E00649A484DAF57C52B06FBED437EE17529D08DB151EC5897C8CDD9A774A354855FC04F6E7C40456AA0B754E88C70AB1372F91074FB94EF198B20228A403F182309ED0BD0330E3B2B41562F69453A067A6E2C75697D108A94F7F07BBB50134A1F9D9BAC60866265603A5F1F58F0896CCB00722D1D075AFE3E1DA15983D8C0CE79C35BD8953933BFEF0402A722044B9263015E1EA1A9EF5AD2FFB78B076298E2B45BA0C2CADA9184DE434038F2178A89A66FA56B92AE78023CFA9231CC078A3EFA5C5F3D291D3543916064D6477FCE47DB5BA0641AA76C74802AD580BAA32A3282D5A23B6A87E47EE04D82C8901E38FFECA8FE780A8DBF90FC56BD24AB506CDFFA0E10DF91B5F9D3883DF94170CCE7A8B66379AE5AE0B688C59F25604BD4140FEAA0D9C06010AD19E825D6B800BFFD5851A01087546B5820E8F07E5E483E315266D5627618B3742AE97C5AC3D7079D2BCFC800EFE1BB41B96C435074A489445706BDB06AB6DB3C2E1FAEBF1831A1F13443D311D8B52F7D6C96A9C80968398760101810766D70CA360EE664C8BDA1D01955822219A0391B940BAC2D685D318660E3134C622E79EB74B0C606FF60D58A6CE3CE8526EAE5447EF1D58E4B450AEC501BAF98C5F17C6A087C1AAD074FD62D2D6A2D3776E9D63FDBD0993BDA30BC1F0838BFAAB857271502C54D65168127290F4D79AE3B8DDDD5A58A1B1F898A47B893DB2F33A263716C2C002CCEC26B51926DD5A4CDC7DD5E739066D84DD86FF0EB39C62494B46B4B270236602BF1E67219A0F3EE43749274B0CA7D915D489E55CA608D19D01AD5EF126992535CCFA251D9721805FAC7D346BD36C53A12F08F735E7A843D195EBD008D7080357EF34A7611DD8122B215BF6A3E5C3077B2E4420DFA328BFFAF880679AA1AB75DF170E82B400CBC78B77F5A6BDAF1B9EE280E481E8C703A0CB9684B3297E8D62F9FF", + "k" : "4A0B277E4107A45DFBE2743AE862917BA77C358FC334A07F5542864B12150FBE", +}, +{ + "rngSeed" : "1722219CB5DB47374EB0AF0232C856A57F026F1CB09E5A5799F4C333DD422FF6A0A67C4DA502FAAE727FB2D45DAFCF35", + "pk" : "DFFB649ACA864C32B4F082AB455C94E6FAC7AC1C6C46943E0D4B811E48A80F18A22130589937A1F4E4097DFB8C3342AAB55648486701EC3C36ED167DAC427C7DD54A6EF844468A481595B933701A2DB33235439D702967AC1B77F47391E6700596D52B534B6EF33357322CA6F1C6A6917B1D8D9CC7F83028437C125912B4E8D33DB0D00B6D475452F41A5088A9E5D169D1FAA564B220C3ABA1D6C27A5B87AEF7F4AFB75442C0565CB78C7B81144AA3C209F9A808D43132C75399293400EF70551B51292BA501FB613998011A35153046787183580E485BBF5B81BB9FC690ECD0CB7449615A0B0134F559B6E1062D9209CA62AA10279E2C7475E48837E70A2DDECC66D1BA5DAC35760A5A5DE0764136618B78516A0C711C3C4440C1F0117D617CD64B55482C952E7617176443C802C8046012E9B774D0312A68C49C85A44D430984EC510212316D43ECC3D6FBCF9736CD3E712D0D3011B645107A22B9D8F51E8DBC30EBA66E98624473880C3378B8BF933D6577CC31D0105E19565F848290059604F9B71B755E123B7401F204356120C769CCCC2B1660E03E688A75FB370CA4088B46D955CB24B7073C8540ECB2A537A66980332DF62196D8C6E5584B7BA8A4C8739EAC585A812AABB33A5F591B428E50C7291415012467D49B232989C34711009806249580A557048DD3DC0D2D6599CD556AC325A5C00B8820F0C9DFD3336BFA5F61D6BAA5E26B848B39CA02CC542C1DBE90AD8D355CEC4C9F3548868E9052618C86FB729998CB4CD610C8FBD86429621E34D11C4943402C2598B80AA98F395A85A180AD402587111DE30CBB41E0C5F6044219D6A243860FA8DA94F2FB878C8625B8E8243731AAF5B511FE7B3C34AC3FAFC68DF6D4BE563727F705AD41245FDE8048D184337E662AEB85135DF92D4C1A3B36F1C984079D50248F88523483CAC2DFE959162A79353708D09B399E6534AA88AA5BB3CF3EB59EEC6A5C8309C6980BB2E4681BC47B7DC2939FFD5439EC4473606166DA1053E9467C50854712490B583AC02A657C61812336B47A5E2912CBFB4A1ACC84991116B9CB1497F199AB41B98BB54343D188AE54A269C89C36A61BE71898006BB9EC531D6006325A47A13995492F41498790BDAE9A9E41C0CEF6FC78F8E027380CAE57C2372308A1B0C2321F8BA17867A1358C5C13095617C2B276AA3C0B36588A9C62683104DB5C94643C69C1330DB1FA9A66C107C62567F2898419008B9465355AF511AFC923415C545EA44F15E7B98DD09EC0D79DA5893125D6125ACA7ADF78A32F918AF2A41CC6377C04A627FBB28AD5BB65BCB16E3F32622F45B5600CC367348379894C65F494F79948E6E1941C10AFC4CC00ED871E529C8573B36DEBC7C80364B01EA874F345271517B6C399A6277B80BFC1A9996A3748A0BBBA5A24ABF84D6A714695202AB7779637F85774C27A51446E72FCB59EE684873BA60315A84988B5936674833A93F06B283C6CC1ECA1BBC36A02C8197480C24E17E2316EEB58B81A3F5A063B1DC4B20239818C8AA67FD96CF6AB52017979BD82431C862837A1B796D0744A27559E748DB8DA63676369795BA92D48BB11F9BFA5393C522403B6379B0D2C82BEB17EF29B37FBEBB387AA695D54C241D51FC3D5BC7F8316100021FD805D76A601862473AE3996B2840EC274BFC37BBF5119668DD0BB0E909FC2A28F3B3C469A9B279BC4810C040B70781F3D67C584A965A94AC1BC088CD2B61C54F301F5DBB82F110C20D51A6C882CFD3C2AD1E6311FE4041EB6CEFD7681E75A72D7B0CF39742394E33328374E5EE5B0FB3B0E2C709365780ED3191E56008280188BABA9C745FA5A8958C0EF28C1FB641E4EC13DD77404DCB031FF3B670A2092EDF848900818C7104B3E457D4189CAC8082B55C55573C2021FD32E4B331EB515092843C323B02228737B2C8915BEB2718D63B8020C2B3A957FA5029638846ABCDA5C3C0CB2AEF55D05C38CDC1755328735901BA53D685B939B168B9CC55AA0AE05FCB8815400A9DC36A58A1F4F90B3EDA3060A4490751413D9C1453EC8CB64DBB679FC69073C9E839C40E8BA4CAC38124C3697528404BCC6435C9C21A5B89CD05516686B4DF7DA8ED3BBBB9AFC428A842A90BC09666804988C7386B794B460105FC5035DC3018DD494D421AE46F978B305738D5F40FAA6DD68EE73DF57C41F89935528E64270C9759D496204", + "sk" : "FFA253D9738C7F3CC8D3D9645BFA7B3DFCC722170CCF43200ED962315C4A48882756588B0FF85656BC8329C33D81DAC016A5B048A25204396268EA3E16B63AFF88A6C0B0344FB1AFB0F530FF3B2858954EBBE8155C287B3C0244F3BA7AA05C1BA3C7BEC8861A15F621D420653A44354415A152B774E31CC0D3AB9B08486AE87A406F17B062B224B75C81D3F1BB1678AECEA90A9A950F86EC8FA357984E697D21C82B70A0933DD34E2782189FE64F94325BC3D068F9A56328F6CD0FC93E74462640998CACAAA7D4AA17496C4FA0414F55E2A5601B3651934CB566594027A9BA5A77B2729165A51CD457907A25786D4510A5E281C2DC3ED422A40BD23A36494D4825A32CAAAA244685734A543C8C65B6BCC11DB390C24C57E3821CA2A229052846FDF155A786CAE0C3474C58C4CF6A4FC3F0CB4040A699198FD4F9519FC9533724B9D5A5C76E8C5F38D28F034CCE980008645704AD2B5E2F985657047554B389CAC253E51A862EBA7491AA76517224D7D247EAF35FCE78B0CE3C8EF14C901D2122E364449967446437416E052B8FA6671A04A173559F46015FBDE16C11657C7F759242EC6950523BE14C8E402A1CBF973C91AC94E004C00BE513FFD90C179071C5B05FD20A3DB6727B90325592FA06B220104988916D558817A734394B1CA7C95F2DA093FF211AFA8ACA0C11BFFCDB243E986B34B72D66647D05173FFA621D0A191E6E69CF7DD33C252A8267D50B57BABE73CC84972665DB7343EDDC2926DBBC17F44E80E229BA494743B6201A0693F4081BC6124BC27067F0A566EE95B455F6CF414C6621536F14762FF8B1B36342ADAA6C381656BF2FBA2D96304F895B6B0BECA0E7FC02603671D2A916A2B571CF17B060994C0D296089E3804CD1B76DB57D9A23640BCCB4ADC34BA970B9FE131427538DC80C41B2891C0900B2C16A42018696490C4DD31329577542E0B56778281F05379CEBE49F7276AC28CC0082AB23FB983811DAA72C940B8AB912AAA41D3EC895D215BD4325268AC137ED7BB97FA09F5C7AAEEA47B822EC6761740809A9B58470AE5B970D6BFC37C3092250218BFE248E2358600170B8C0B3444527947AC515211B9B2D65328E13CB33E413847CBAD815412EF36C7E7A42A6F097B0193AF3BB0C6049BECB3051D60A10BA1C6CF4B9CD10583886172FB2527D85CA2714FAC6A7352EAD8050819BB08AB050B5525E2A093CE296A0DD7A0E79FACA7A209E08FCC4366AC22BF63393EB32285A5DFC2198C0F3AE7F389D4283AD23E86A2E7972E6E4B22FCB7C5CF54353500D680288BD004A5FD28A280C09ACD35DCD245051545B46598524AB218DF38044F52F038281B332B2D6610D7FCCB9F25173B48C8A2B18B3DDA8C3B0ABC4AAF28FF2B4A6ABD085B6D8722C9A02CCDB96A0DC90922691F96769E2D9800CF5818B23C2F9030C929C3F11995C68C504C91B753496CF7B3B00E46A78BABC61043780EBFB9F037668E3B5039663C8CC291DB5F5A4E3352DB5079387E5855D74B84045B1ECC7B0371A048F484C658502C344B6BEE19E370C78B203260F6732EA55A0479453B4684454588C90E49D0A192F2634004D326292011F1D53B0AE71BB8284379D925FC139B581F402A9280DDE30A9F5847FADA70582A7AF03C71D0A8A3147219F986C329BD60079F38F22E99DAC8CBF4BA67AD77B0819334135D00888F476985441DE439DF0B81673D3274DA42AA8851C34BA304B467441405559491662443D51E92F50A056D4FAC1ED2357F00503F5280DA63C055F923CDA36916BA51F35E13CB17476A879BF88B406DCE51CA85475B7447C0CD6C46EBB0722A8CF8D8250FBEC5BBCB5B9B644238168151AD9AD156C7E0DD1ABEDA37E8D511A34B447195A897568B0809A02B4207AA8EC12B2BA73D64BB97952328FA1C5C19801CDB237FFA23115A774592C5F644BC60FE3B5B96A1689A90CD1D6ABFA9A50BB430AE796364CD99D8E6261820282204A8DC81CCCC40B67B82067FBC38FAEEB068AB72ECF3A6AF5259092B06B2DEA6665B7901FFB6C2A243A3D2B4235552935C323AAB07769AAC9BA0A8C3813C536700CA8323ED662954ADC5BF811C4D09434D0046566363775F4965E626346B6BC1B50655DE01CC642B7F984C925B11B5442C827DC28A004C38EE59D74CC0DAC334BDFFB649ACA864C32B4F082AB455C94E6FAC7AC1C6C46943E0D4B811E48A80F18A22130589937A1F4E4097DFB8C3342AAB55648486701EC3C36ED167DAC427C7DD54A6EF844468A481595B933701A2DB33235439D702967AC1B77F47391E6700596D52B534B6EF33357322CA6F1C6A6917B1D8D9CC7F83028437C125912B4E8D33DB0D00B6D475452F41A5088A9E5D169D1FAA564B220C3ABA1D6C27A5B87AEF7F4AFB75442C0565CB78C7B81144AA3C209F9A808D43132C75399293400EF70551B51292BA501FB613998011A35153046787183580E485BBF5B81BB9FC690ECD0CB7449615A0B0134F559B6E1062D9209CA62AA10279E2C7475E48837E70A2DDECC66D1BA5DAC35760A5A5DE0764136618B78516A0C711C3C4440C1F0117D617CD64B55482C952E7617176443C802C8046012E9B774D0312A68C49C85A44D430984EC510212316D43ECC3D6FBCF9736CD3E712D0D3011B645107A22B9D8F51E8DBC30EBA66E98624473880C3378B8BF933D6577CC31D0105E19565F848290059604F9B71B755E123B7401F204356120C769CCCC2B1660E03E688A75FB370CA4088B46D955CB24B7073C8540ECB2A537A66980332DF62196D8C6E5584B7BA8A4C8739EAC585A812AABB33A5F591B428E50C7291415012467D49B232989C34711009806249580A557048DD3DC0D2D6599CD556AC325A5C00B8820F0C9DFD3336BFA5F61D6BAA5E26B848B39CA02CC542C1DBE90AD8D355CEC4C9F3548868E9052618C86FB729998CB4CD610C8FBD86429621E34D11C4943402C2598B80AA98F395A85A180AD402587111DE30CBB41E0C5F6044219D6A243860FA8DA94F2FB878C8625B8E8243731AAF5B511FE7B3C34AC3FAFC68DF6D4BE563727F705AD41245FDE8048D184337E662AEB85135DF92D4C1A3B36F1C984079D50248F88523483CAC2DFE959162A79353708D09B399E6534AA88AA5BB3CF3EB59EEC6A5C8309C6980BB2E4681BC47B7DC2939FFD5439EC4473606166DA1053E9467C50854712490B583AC02A657C61812336B47A5E2912CBFB4A1ACC84991116B9CB1497F199AB41B98BB54343D188AE54A269C89C36A61BE71898006BB9EC531D6006325A47A13995492F41498790BDAE9A9E41C0CEF6FC78F8E027380CAE57C2372308A1B0C2321F8BA17867A1358C5C13095617C2B276AA3C0B36588A9C62683104DB5C94643C69C1330DB1FA9A66C107C62567F2898419008B9465355AF511AFC923415C545EA44F15E7B98DD09EC0D79DA5893125D6125ACA7ADF78A32F918AF2A41CC6377C04A627FBB28AD5BB65BCB16E3F32622F45B5600CC367348379894C65F494F79948E6E1941C10AFC4CC00ED871E529C8573B36DEBC7C80364B01EA874F345271517B6C399A6277B80BFC1A9996A3748A0BBBA5A24ABF84D6A714695202AB7779637F85774C27A51446E72FCB59EE684873BA60315A84988B5936674833A93F06B283C6CC1ECA1BBC36A02C8197480C24E17E2316EEB58B81A3F5A063B1DC4B20239818C8AA67FD96CF6AB52017979BD82431C862837A1B796D0744A27559E748DB8DA63676369795BA92D48BB11F9BFA5393C522403B6379B0D2C82BEB17EF29B37FBEBB387AA695D54C241D51FC3D5BC7F8316100021FD805D76A601862473AE3996B2840EC274BFC37BBF5119668DD0BB0E909FC2A28F3B3C469A9B279BC4810C040B70781F3D67C584A965A94AC1BC088CD2B61C54F301F5DBB82F110C20D51A6C882CFD3C2AD1E6311FE4041EB6CEFD7681E75A72D7B0CF39742394E33328374E5EE5B0FB3B0E2C709365780ED3191E56008280188BABA9C745FA5A8958C0EF28C1FB641E4EC13DD77404DCB031FF3B670A2092EDF848900818C7104B3E457D4189CAC8082B55C55573C2021FD32E4B331EB515092843C323B02228737B2C8915BEB2718D63B8020C2B3A957FA5029638846ABCDA5C3C0CB2AEF55D05C38CDC1755328735901BA53D685B939B168B9CC55AA0AE05FCB8815400A9DC36A58A1F4F90B3EDA3060A4490751413D9C1453EC8CB64DBB679FC69073C9E839C40E8BA4CAC38124C3697528404BCC6435C9C21A5B89CD05516686B4DF7DA8ED3BBBB9AFC428A842A90BC09666804988C7386B794B460105FC5035DC3018DD494D421AE46F978B305738D5F40FAA6DD68EE73DF57C41F89935528E64270C9759D496204F118F77224920BF4FF7C69DB5EBE12EACDC6012D57E2CCB3D690DB251204DCE3F4626AFBAE65EA913CDB263C9615A5F66061CCC74B1AC83B5FBAB8FA1EB6799B", + "ek" : "6F592F93C25DA7252131C515F3AF8C01AEF860D8BB8FA5F69F07D39EFFEEC1920B2370909353BCE6757027DE55DB5C54B141889C429060F36DC8AFF8459708B776ADFE6539EA10C97D98FBB1B9D03C51FC340CA01F6CAD570736EBD59AB23924A7831A6AC285C8548919EDEF777F6BADD6CF8C9B0E666DEC3284B1DCB28473311AB3582EE5C9A0DBE3940E3224FAEC121229C00A73D90D6F579D8F187F25B74D17D8666FA55EC05CFDC5439F474D9C3825DAA7206C437F5AA402683FDFC1E761B5921F3D7A6A480562AA753CEF2C7C8AE33C88A4C4CEB5DF4946C6A09F163323709B5A5AF8DD7A2A497033687136A64FAF595B4D2CCB1539F160C52FACCC1A0BB0FED01012A6DF82256ED2E938976CD43A9911C307891BADDD943F2EE53BD8E0208DFEC97CEDC98BE6DBFC7E86C29181509AC6B3CB5B3F10295DB917F455836958E6E0224C0A66A8E3F3A2CE822DC5027B84F907B494DB9C3C2EC8958ABEADE7ADFBF0A3104825384B3C2495E0C2CA54A7C983B39791AABF736ACAD35507EBDE7A5002497850BB5ECA6F35933A05E1C0A504F3C6D19ECD75F053C942062FF7E881973ADDF20ECBFCF3FDEC1AA745C44E21EB1802BC5E8B6B61ED2B75F432130F7F886DEE9F30E428FB8FF5D1430845605F0E2274AF4FCE7E9D1CBAD6B2F4B60C95ED119F45C3564ABAD9417777AB84CB5D98B0519CCECACE8C284F0396E0F4B2D7E28CB9980BED0EAEDC582880669927B3A08D568D9BB4FA31D72FE8CEDFDA6CC715EECFB3831070CB39B65FEFD47EDBDF1532499E4D34DA6FE31BEEC101EBDC61B3B1492A7193F07AD5686E27E5643F9B6A42D6B127C9D882BB9B273B62AC366EF19FEAF5C1796D01C892A45F4C531437CF6DD5FB7197F1F321AE60792D4D58B2BF6F05D22C376A6D6BC3BB9E222EFCD6F5C9DFDDC7D3AF799CBE54925E6E8E71DDD32E55B196D4C6D7C299B7CD77FE90E002D80B7D19ACACAEA46A015B80008B277528623BC10CF69C9A8260E3B4E6BB44EA1E6CF511EC8C303858099BE33B31EDF381D4EDE53DFC4E8D5E0CA5CEB3BC5B8907CD0DC4A333D4213E40C4C576FC0DB07226CDB7C6D9092115BF4605304D81F86AFB0E431594E3FCCD7C673A4E7B30A5CF34311AD14A5633F3D7F06024402CF0D8F984F99EC3E39D2D68A0170BCD9C0F6D09BBF883D31648596DD5381B00B4DAACA7086C8BD20C06FD46B4F0E4D8CF0BE45DD11B2CC4495E8873C8676F690455359012028E505BF273F09D42B81F1E51706E9D0A112129A2BDC75661CBE9216046B59A99D9F10DDAD274487C3B9B69B00C4B324606A43232B0D03BD81ACDC7CE92CA7DA4B8A5D8A5BA4E4AB2F3C5740865394A9ED61F0696A92D6C6CEC19561ADBA60A9233C34B54C986CEC9574A6BA4145E05EFA0A7F8DCECDB87924DA70C67E563D5DB7BD4EABD64DC2DBBE327B35EF04F703F641B44AED746328FDD9DFB45E0F35FC02332D187185F03B4ABC3D6A3A51A47B73ABE00CFA6158F3F20D83C1D26FA0D0EF6F573B97A211F592F45053AD21D71FCF6BA541AE5E379B50079A2E9EA3BD286A3AB619E53E74715C9E913F7844E1F056302F6881D28BB75AFCA6D948A160C656150B8D10C6186534A9EE0140B1DA714515926DAD8587D77DDC13BBE4E1F3DB24D789A09A9C943117BA35F9D1BBB4E32A4DA5AE54610DA55B1D937009B08624D8E5AD1B8556B997DFF87A6EC540900E8A6BA92EE7FE8915E143591A49979CA10017545FF6DE30B71F54BFA941299D7D8A56A6DDFFD0FB455B445ADC4ECFE8298F5D5CC50E823A905D76AD19F6E3D0C4311B65A937ECDEFEF671811A2965AA7CA49B5884425DAA670DE95E5E2522B7873DE0DC2840E670DBA5BDD1ADC9374309D1B959C1A583ADCAE3F5B3E698A56E204AB96BE69870F4C8C4A9D4360706461ED559795FFCD9C098D12FAE175F228FA87F828A6FFCBD0613677753F31295DBE82F3A4C4127C655EC3BB6272C6290905174D2AB0F6ED10608691601E3CCACEFE789860D544C99DDBBA21F0B0F5536FED9C71C52F814DD54C02950D416A44A3D888213F1E36639878256B02B61D2D967CB28173849C3B5AE6D1FB7B6F0A7CD3FBF19BA788BDD62F2F76BFB1FF863CF2DFF53F2A8E76FA7AE90C8478B5280137F98E2D0A184472DBF9EC79ABA1342D40681A823DDC18B68FCFA2B4B3889186C92043F5B6EB7B9B41E69BE5", + "k" : "62542A64DFDFD20A0EFFD910F8C678028426832E2FE7E23710DB89CA90F3724F", +}, +{ + "rngSeed" : "AC139B78FD16CA0F26D6D7F9E15345C888D857B1910CF38D883339B37EAD2DCAC30F7CF10176F23FF34B4488EB79437C", + "pk" : "1E4205E8FA992213C49059A409AAA3AC72B85837CDDDE4C4AC42A9A35AC7FB80AD2D8C1EAE7019276B1F3F3A6761602A01D99D4D050C23892427D6267EFA092B587A5D2376012CB755627B9E63A2A04432260AA1ABB2698EBB6075620FF11B01E4D049DE698966FB49BDFAB73675586583C744B5BAFBE9692B6C6C1448899AB72A8821B52B4BC061910FCC70BEAEF424AFECA7D3737F4C7C6711B38DEA919E1A13C78160C1C652A81210C010C48908B13101B04334E6534AA0986EC01A86B30D41CBA67E573AB6B0CC1A2C973C0041BD26721B508A667BC28E010265B762A223128E092EB512BB9D6150AF6840581514470212D0E5C1F4696E45AB102A91A0848497E8A7A52EF20C85D7067E6A1F99E1C0DE84473B735BFB001E860C3194029D5A06484920BB0E371114AB2F3BD775248A9449D2C19DE5023876931DE00DFD609C95C98C133BCBEEB52C0F713A19176DC90B5143A6876AB45B7F717865D4B8F0B8A2E6A45F123B85C8FB584CD3C042676EAD069CF9C23682AAA05C1010E122473907547D79B0F8B61180014B1B3A56B88B3B4FD97EEBB21EAAB37883889A37676C61061D41B40B49DC5E68F64ED979BBD3DA4A7824B32FC0BAB9985A94251FCB740BD2B103F9C21C25BB055043C895531E68B17A3CF3190683969D6299C850B7D11A6B7A183B4B3A3DACCC41D3321F5C088035102AB68B2938975FF180890153135E284155F971CA624C19F15AE4A3023F20CDA6D404406C39CC26AC4DF1665A3C19107A99BB289176A09E4A7C197BA72D6131980264A907B605C1E1791305974D49B604C81A9C8501ECD0CDD32A5F94DC3F64481164323736435D1043B09FD1BA63AB6956E4216CE47F719BC10F0C2B2830C17886965188534205C3F8818369AA638D5902CEDC28B56C9723AA4EEE8485151A270D3C1D963404BC265B912C6E52099DF9EA72910674BBB8493F670620645FBA16C0E6C73FFA20A99D6378433C6C55AB20F0A40C74BA37DDDA39D2BA4D7F34C705A4117C618AD91408BA3BCCE9FA9900D2650FB109FE2221F0F6219C226B74E7968F5AA0B3E3575BE051446B1B76B8A7785A43C824C73688CE495681FE723D97B249E5A65A961ABD0D61527D4B18027B00DFA49F4D213253E80FF2A556C48ACE2B6A5122B42C2D15622E158E2613B23E62C6398838AA821CB05A4424817F0F9291F4CCBE6578941070B22B9C36BBE89ECAD318E4251451A80202A70E1B2274854809E770677AB76C9E9C5CF4E8621E4338A279169AB46A6E5344CA391B80EB12F9B8A582105380384F2FE845B7298E52803989211498B42537B8B1CD22A59085BC00941F190A66FE77A1A6745E8AF09762751C63656A26692BF1870DF08CB861ABBA73B50AC6B03F880844A2C6811A031EB412501C79201E686AE528C84B7606AAC09BC42265E77B56FDE93022A71374693F9FF5787FA0855C79321D147831CA28E7880DFE1C15C66BBCCDB93C0E7113A5EB9B97285AE8717BB87C1F071C284C0089FBB5A7B5121770950D255AABFCF54F1C18C8D9B2BC4AA253D5BA49BD2944A8C440D01343F0770F690743DD952F4F6692A60BC3360588F9575636748E3D321050C42C11D75B69D316CAB62C681AB48F1880A9D787449440D1F1CFA0386613C2B3D25494E7C17D3E4B1F5A5780A9F088F00A9D6A79C6B1BC0E1D501FDB398421A19E316489BF1105D9F79C74433C82B87A775CA358965E8B1248134A94179C20011121AFF04B95130F2EA20A0DEB2D3AD8A0F6086481D8297A10374602661CE031B99012BE53C70110B53D28966D8009CE6857F778006A304FB402769065C04D25B2F3AA1BAE18A692D7552BC9805897C9B65A930BA11C6F3487801284D85579A912664118075B7237E66183C66510202188DC8ABC1ABA9524E0450B7A29B4D6B5076769B7E419FA4A63521619D1F76CEFD0A7DE67C7F5491724D063A13BC27BD20E9D486FD5158D3B7C04A97B95BB06895206058F94050DD8C262EB70A73746CF279350125807C52AE8A29DB743099F259C9748318F391E524C9D8B46932157C94A8179E02897F33226EF1964F4CC92C7323DF35A7700DAA10170082F0664E4B8A221DA0B5DA84F43B79584194AA8C18724A6452760365C316C1F36212811A8E1936578653878B2372FE58505E7957A3E0E0F1AC0D822A80287D204EB6A446A74AFAE0CCD1859A2544AEDFD", + "sk" : "3724C5EBBC753F55535FC5AC0069C238D8B7C111BB7EEA08B59999349BB352CC5C18F9926BF676B53A15C759964F205A322A1C88E1B4266C2D6A311384216EE6E4625C15414B77849706292FD79753163975A4BE5B9410F3D261E1931C934380263740D2A2666D861010036251E7061F04A6E8F8ACAB2907EDB1CF01F906BB972B53F79DF07B3AE368411913976E73360B077771B16489E83818B6A176223097E2397432C9FB4BB013B2C8FBD2815298B0214B97CF8B740AA4BD89067CED36BE138A3D096BC51F606D3865418610083C71968FA41009530931DA393AEA3AD975423829233BDB9B0095C2421A3DB1D914E502C4ADE29C408C84257A2A1B2A100839600A659026E6362BE2ACC789A12832CE5D876533862C0D20844E903516448448C0A600B6C7CB812A3847037CFC0CFFBAA582B9028528B52580C956D4383D10155DD58BB84BBA99CBAE99055574B02AEA64828F4C28B8A0C19A4009D6E6C58C661BEA9A84F6E273B9C50D9A8048AB144F168912CA1C5EFBF87997BAC3834300960AA1598C15221A1A0DE795F9385FADCA44CB036972A8C37DCBB61C793D851214A701B3F23645A166BF1912A827934A32A58FBA6ABFB41A4ED2331CE0D08378417F42C176403A9CA5ECA30370CA2C523E7A294C7F9A7CF87B941EA47B19928FEA095AE42038217B3FA0B54CAECB60BA03A8A99745982835AFB01934E1BD4C432F3F3C041E96C08C8836E267A30B8883997749B56047D182758A683123A91F70E08B1B42121B666C27D4C902939CC90442C19079E53B87B834BAA609413AA3698D365E5BD71B247A7F0D42184B166CFFD532B0691563C7874E9392FB1C9C528387EF3648D72CC063546CF22B23B6E68C340A23895A6573F80F30E3CCBDE14F56AAB4FBA5505314605D5311EE89A7EB5CADC7523716885B4150BC07318902657AD101594C24C7328004A29CB8CAA4A3F48C1AAF7C289A063A6ED690F72625C6EBC7C10BC500B8A0F5E807655B1470A4802FA6C3D9FB0BEEE3386858328EF97E0B94518A455C5C6A3020A70A9468CD784A38BCE99492CBA4BE53624925C3F74C533AA681A8482FBBA5C15B026462956FB4269BFBD3591AE33823425EE57398DCFC1E7F3A53FDC6B031267E59F0C82BB4B7CECA3CEDB23CBD29AF7C797867493046B30E1264141535315C24A03F08C811716DA610726472039FC1CDF489595E072F717A67487B842A6C8B2CB33EE9420EC5428FFA6B85A7311014595F409BA93E8B10100AC45BDA836A522C01C78FA8B904BD422EF17A93D1767F31B02B7540AC4EBC3CC6025884AC9FB0EC996E537608695B84C350EFF27A15F2B83D76B1622789F55157BE7274B73378994A997D564B819552389918B781C19317CF85A72DFE66BF8C44B032210B9395AE35F9CE61D002A2E4A0D6F823698698A0D475E6D90BAF596B83D2628B5B345570680A13B56C27A9A2D7BE01EC655DA3C1C93886D15B6B6F28404C85B37B09701AEA3C50A146BE8BB93B10C65B96248A02BACEC816444C911A700F7ACC16497C536DA22BA6995F89985F59E0BB5A16984A005F2C64584FFA868DA78D33B44B1AFB5A25F85C083CCF6DB93A59720AADCCBF2598228BCC6DA0676FEC92109480548E421A618C0F0A519750D846D4818F5D1A625B877C64E9CCB639AA69186B70775BDD6612C7607AE6149F52D447A9B2946AF664B493805DE93E9A4846B734C0946822DF415C446455CD037FECE9302EEA5A856208C1A3BCA48C35E88CB329F2CDD6F56A1B89CB8AB972140093F2686A2CFA1EE17AC413BA6F3F83723BCBCD933947389476ECF71C676A3C327C9725048DCE400F791C9EAE184AA95C193E84040CDA88F1A497A2B90201C95248ABAAD0C8848D7280BE076EA7B4AD3BF083656948C952417AD3BDD28821C9C92E59F90B5582BFBEEB560469AACE0B1E7DD53D29F59F12B767355A0790780E19716B588C150603BF3680464F15AAB3809EF240B1759288EC719B64F7A184B890060AD066A41923F25AD87B55AE89A1222B4BDBDA1E07631D95C704F6866B1F9994F94681C21B41C3D7972CCC2B842759754CA826E433497B358C071F306A464D3B0F7950B5503304910529A6E476CCE974488443562CC11DD13F45AB1926859952B67FDF277AD3CB8965C1A31E4205E8FA992213C49059A409AAA3AC72B85837CDDDE4C4AC42A9A35AC7FB80AD2D8C1EAE7019276B1F3F3A6761602A01D99D4D050C23892427D6267EFA092B587A5D2376012CB755627B9E63A2A04432260AA1ABB2698EBB6075620FF11B01E4D049DE698966FB49BDFAB73675586583C744B5BAFBE9692B6C6C1448899AB72A8821B52B4BC061910FCC70BEAEF424AFECA7D3737F4C7C6711B38DEA919E1A13C78160C1C652A81210C010C48908B13101B04334E6534AA0986EC01A86B30D41CBA67E573AB6B0CC1A2C973C0041BD26721B508A667BC28E010265B762A223128E092EB512BB9D6150AF6840581514470212D0E5C1F4696E45AB102A91A0848497E8A7A52EF20C85D7067E6A1F99E1C0DE84473B735BFB001E860C3194029D5A06484920BB0E371114AB2F3BD775248A9449D2C19DE5023876931DE00DFD609C95C98C133BCBEEB52C0F713A19176DC90B5143A6876AB45B7F717865D4B8F0B8A2E6A45F123B85C8FB584CD3C042676EAD069CF9C23682AAA05C1010E122473907547D79B0F8B61180014B1B3A56B88B3B4FD97EEBB21EAAB37883889A37676C61061D41B40B49DC5E68F64ED979BBD3DA4A7824B32FC0BAB9985A94251FCB740BD2B103F9C21C25BB055043C895531E68B17A3CF3190683969D6299C850B7D11A6B7A183B4B3A3DACCC41D3321F5C088035102AB68B2938975FF180890153135E284155F971CA624C19F15AE4A3023F20CDA6D404406C39CC26AC4DF1665A3C19107A99BB289176A09E4A7C197BA72D6131980264A907B605C1E1791305974D49B604C81A9C8501ECD0CDD32A5F94DC3F64481164323736435D1043B09FD1BA63AB6956E4216CE47F719BC10F0C2B2830C17886965188534205C3F8818369AA638D5902CEDC28B56C9723AA4EEE8485151A270D3C1D963404BC265B912C6E52099DF9EA72910674BBB8493F670620645FBA16C0E6C73FFA20A99D6378433C6C55AB20F0A40C74BA37DDDA39D2BA4D7F34C705A4117C618AD91408BA3BCCE9FA9900D2650FB109FE2221F0F6219C226B74E7968F5AA0B3E3575BE051446B1B76B8A7785A43C824C73688CE495681FE723D97B249E5A65A961ABD0D61527D4B18027B00DFA49F4D213253E80FF2A556C48ACE2B6A5122B42C2D15622E158E2613B23E62C6398838AA821CB05A4424817F0F9291F4CCBE6578941070B22B9C36BBE89ECAD318E4251451A80202A70E1B2274854809E770677AB76C9E9C5CF4E8621E4338A279169AB46A6E5344CA391B80EB12F9B8A582105380384F2FE845B7298E52803989211498B42537B8B1CD22A59085BC00941F190A66FE77A1A6745E8AF09762751C63656A26692BF1870DF08CB861ABBA73B50AC6B03F880844A2C6811A031EB412501C79201E686AE528C84B7606AAC09BC42265E77B56FDE93022A71374693F9FF5787FA0855C79321D147831CA28E7880DFE1C15C66BBCCDB93C0E7113A5EB9B97285AE8717BB87C1F071C284C0089FBB5A7B5121770950D255AABFCF54F1C18C8D9B2BC4AA253D5BA49BD2944A8C440D01343F0770F690743DD952F4F6692A60BC3360588F9575636748E3D321050C42C11D75B69D316CAB62C681AB48F1880A9D787449440D1F1CFA0386613C2B3D25494E7C17D3E4B1F5A5780A9F088F00A9D6A79C6B1BC0E1D501FDB398421A19E316489BF1105D9F79C74433C82B87A775CA358965E8B1248134A94179C20011121AFF04B95130F2EA20A0DEB2D3AD8A0F6086481D8297A10374602661CE031B99012BE53C70110B53D28966D8009CE6857F778006A304FB402769065C04D25B2F3AA1BAE18A692D7552BC9805897C9B65A930BA11C6F3487801284D85579A912664118075B7237E66183C66510202188DC8ABC1ABA9524E0450B7A29B4D6B5076769B7E419FA4A63521619D1F76CEFD0A7DE67C7F5491724D063A13BC27BD20E9D486FD5158D3B7C04A97B95BB06895206058F94050DD8C262EB70A73746CF279350125807C52AE8A29DB743099F259C9748318F391E524C9D8B46932157C94A8179E02897F33226EF1964F4CC92C7323DF35A7700DAA10170082F0664E4B8A221DA0B5DA84F43B79584194AA8C18724A6452760365C316C1F36212811A8E1936578653878B2372FE58505E7957A3E0E0F1AC0D822A80287D204EB6A446A74AFAE0CCD1859A2544AEDFD8678B1F242830FB21F34F7BEB20A96EBBBD6181890CEE3BDCAB29697C5AEFD70D79909F31E8168AC129FEED8EFEB21F07C02F282CB90F63EF10EB2F4A9ACB886", + "ek" : "1176C1AD660015634F28FE85811C21F447137E41329D9540210720DFF535D7647749599C17FA643DE923B4AD67F722074886172351581E761C6F42BD9D91D7BADDF27A29AB163DFE183694F41B65EAA4D25C3F75BA90D7ADB54161C1A1564824E25C42F7B121861AE47668DF1E19E065B4F2D91401BCA1DF7A1A3D0C7A6B8C34CA44FBE43C14D6D38C0CC13B140C0988BACF579ADF11FC4866CD3437DC8CA536E8918CE8686F48FCEBD3BFA6D91E260D9154946EFE6D759672B42EFA5AA0EF0426C86403FB5E5E0E1D9CF8BA71ED4BD8804361EFE3DF769D15A2B1A6B5F9CFF9535BF47086980C3ABBDD746D0C551D7289DC973F731548A61F77C79DB299278B749ECF9C4700B3543DCC005E29A8DB41FFA49460C1FA5C7303583D193C1B88CDF85813D2BDB29A211FB63295F588121CD914D1E23C092B82AA21B6ABC895CE7045D15D0C6C3C10EC23ED207745029F84E18E01EA0D1FBA5913C3178DDCEF77EA7C98179BDD9A041FBD7CC251722049A2228559755F9D815B1F8FB3DFE76431072CF62E63C95273A949A6BBC21BE37E8FDE8D98DEE370AC9267031F165D8AE11A44F97A315315B7F8D18BF1CAC902BA11375E23958EF200B6774E08022507E42463B85A324F89632994D3732BDEEAAEA7FA9B6662A7B0B2FFD31B124970767AAAB7F85E77C6A9DCBB5587202DC91164E4E5DF7CC59A0BBCDC233A0BBABE0F3780A5EB72481A5ABADC8A88B73AD79652AC18B284BE8D9008F0701CAF384EBB6FD5B37183FBDECCE1B7F25C4D69568383B1347D24D6E2285BD4FC9ADD8939E6208CF0C73C3906AB254CC0DC4CE230734409FD0AFCB776127A69432972AD2CAC0D72D57B5A20F8FB23A1C2E9D70F1DA6FE80F1866C9F0BB257D00B4C87D24007EE63AE526BA90CD83B93232D9D62546176316D2D6FA3587D2475DEA80F6F31A2101844D18A0BF564024196263C1796F9DE4662DB6931DB6231AB716D0DAB00A778A0AFE2F4ACAA8FA43516C866686CCCDE2E151EE1A38C1813D48C22C7DD79EAF927C62A80586EF5A4C57499039793D24248B9905EAD18F2EC36BD710F0F732C35ADE8FEB13703904CB77397202B22F06BC473F418004832097E1D66DA03D1D4CD6D8EB8090952FEC65ADD552DD3ED9C33C617AA3AFF96C335A5416DAC39A2FD28AD5BF6B212743FD7864FCE04CFF7B64BB834E0DBB94E2585DC841F8A63AFFA6ECB0B685ADCC93C635FAD76E30FBF9E06B61F76FA98C32B19F9458CCCE70BD5EC02426128F6B638091CCBAFACF060197E5785DD33E345B64E100E6121F90895D0181987F61A18B3144C077447BAD4C6E60DC8D501FE819E624E9BBA34841230121B5323901695D462EFD13501753EED4D3ABAD711B52452ECEC93564053B444AF9F4F1A20DB5CA1D8742AF8363B42D04655A4E652F10D36A95CBFA08A50628DCAD20F352108C2E4010663D2CB9386CF65879B5FA5B63CCEA09B6E120B6758F7A1D2290F3D42D35D52894D142D36CFF50951624F6401A280C0DBB7FCC0A92F47A71FA629C8E7414194D7B126D4B74468567F4BD58CB57DD895BA5B69B40A95CA2DCE90F02F23D9AA420DD766FD2828AED6A33FAA677098AFA616A3A47931D14C1A94F6E2A6FEB6B64CD339C64B4911B80BA62643929DEA4B3A24CDCD02B4D99A52937729501052FD936329C26E14E96AE166EC772FDFB3729C420A31568F89044BBE72AAA870633AF0C35504174B0DB1E16917B3E5095B53D06D02C8A948254034A5ECBE6E85D8F9DBE54767AEC10BF4E39ED67F89A736379743ED7B13553A4756FADD5C35A2BC5A3907A08384F814F7F690F349047E458AA2C0BA0FB42FE7AA334D4BF5722711C2F81D992FB362C15C207294E328DE935C8D401BE7DC0FEE420D4BACC88D975A4BEFEC3CF031A9F7F63AD59B5BD55D686EEFB2B3EA83CC8F524A351456C2E962831485181FD2931C49D2AD0FC5306F57D30A3BADF91E9309476749618B6847D8449CB1D47487780FEC46F012EE14880076EA6D740386B7D281417533CF26E73397446792A0DDC6E88142F8A633BB8D6D28F7E2422168D2ACBF43EEFF10BA18B7A833E6BD186B0BF77BC3DF7E6EDE823E1EC06608F02FFCB0A44D2D968F4934C32C675C046F40576657FBE39FC8F92BDE3E89A6A5B408858521905F657962369808B075BA8FAC2E13BB22A21827200B38D2C9398C25ED91F15187AD", + "k" : "888B24038353205404D578A802A31D1A26421AA2345C3610FF5A242CA85B5CDC", +}, +{ + "rngSeed" : "CC7152849C98D5FED2813275D32069E44824ECB14EAEF425CE017448CD9A401C91C06D0F7EED6D22B7BBE8BA6C429EC3", + "pk" : "EAC2871F16B152D08E74E28A250999DB0A6DB7036711A24370401AB844CD39B124B8D42E8A15B2BDC85FE3B11C9CAA30EE666F260AB0F0E230A5901229B974446428A9E24680A884208A2DFD3899FF1A4920B798AB275D5A10B01503D000C23DB72CCBB3A91AB0186FA7850DE3055E4531439BFA9CDCE3AC888066D17469DCE07F76D0397BD46A59C29A4A776C8B7310021128DD248BEEC9296C7C5E95D13AAE21303127778B653131BABC17494F0AA63C18260130315BCCA7A8C8521E7B9C9544C1260BD201EF23974957A6A4D3658D96A7FD4CB7DAEBB11E5ACEC216042CAC64AF05C8A7DB570CEB09393C7A24F5AE305280B1C22B9D68B02A0C521DD6393C20CB3EB798DB457CCBD869748AA2CDC8336A58162E56528C3AC7A7BB41E2DB1A35257B6135247C7802024CA258F03DE2EA93E2F6C42E539617D27FC62510EA016DEAF787A2B3B930165FF1FC8E20413B90EBC827581B74988937A018F612AC4098514480212781C4EA128680448B58A5A296B35020C6668ACC7A39EC329F3C5EB00C44F43C9DDD612C0860031669C911E0B4D5D20F45EC1B6C5B6BE399C2BDE785757215BE7617AA6A57EB6B797C8C5CF774274B2463D0C85E1343554BA052FD9B36DA139E13E04FF18427B418282A5642429825D15636DA6C45834375D543714E80530DEAAE0B006488ECA46974642C8307AA5297D34619DC39863F276189A20B75673744FB934420A138506FB04B0EB2E22108C1923784523E767DC70CA546FB820DE07BB9663333E623889279BC596B2F559F5699C272C3040602A0EA98C878D2AF1D7AA697AA83F1DC10E54017E2E586B220804588473C4B9D05AAAE6FF9C038D00F953547EC748E62BA3426001C3F669941596C6184B353D3919E591DF898831EB11AAEDBC49B88C8187CC13EB79EB09C7E07545BE6041A9BD0A70519B17B5479AEF79D105B83D74C08C719843A94BD1F76BAF7E3BBD6795E05830184C53F42061F4B6B0321E2561B4C474865A0C825C96F9269E12742771C4C9B20B9380540772A24B43C2AB3051B88EC4760F794C17AAA55199E39EAAB54C53AEF32BFD339C824501972EB5ED299908FF0AB3DA01460F106919B450BF00678967E45C18531D112B481918FB7023EFA1617DA59FF391B84B03AC199A1AB31208B918777A2C8A9706CC8359D09E4A817386CE09757C44350D10C4EDF02625ED06DD3DB07514639F67828C5077F0EB722F39587830C506C4BBB4BDC60A1B256BB157ED4770E603211D508165EDCCDB2D6CF37F039578176032C2158EB3C9D48921CB387339267BB728ECCF97BF31309D08611B91271EC698D8920CA3BF334FD8765B0170608726A6220A3ECC14023F02AA4F31446B22DA93597E4A46D451CADA3965EF2148A832221C4D8A7D12157D9B3BC69FAC8626B2DD1C44AEA272CC2125DC79A4F90B56EA75144037A4F0060C33C5B6ECA4572142310CE956FD6F31D23C6C9F6235057362B884A014FB5867B2C1976127A5A287EE371B7430CAEC5D35B63789B31D176D2553F82C8407F585C32511E3F0CBA0BA60537780EDC6CA22D1422EC8C3357EB203EE68C8FA135B0AC2836E027FE3161769C6838E98CD449C14EF2B07AFC714CF02D91D387A27472217C9EA6BC5CD1249BBA38842CF1B28701A6074CCFB7316DCF345ACD84660D02381040CBE8109C5D423921B84771A1CBA981C5FB08C5DE08AE6CDB38FD5B9489357DF11565D48A7797A6AF82553225D73CEBB362ABB1CE335358C6776D9FBBA731883AE7CC517E0A0A3BB5B970E4CDA95A98ABA47D9E2397ABD7757218C5D7BC4CA59B70BE5AA4D7B62AFB54048FFB0C64919AFB746120B383958B715D110E5E6BA666940328AB4510FA25E9B43537E566EF760D2CC52B07E5BC089B8EA9E166C513BACBCCC332F36D6AFC379E1A838AC24EA35C1260726D029651088996631C55E846ADCF36C792C21011320B2287973A770D2636470C080B2893A09BCC8705306C5B364837B7CC89A9AD1FD9C1EDCCA9A0B4B81846C8E088B36FE361539060CC08C911C9058BBB0839183B0C59302171826DFC7B6FB1C623DBA3F0F9B30768346A7714481B741BD0BB7CA32ED73A00A6A1874D8B7369F695EFE75E00F03BE6CAC1476815AD889C69EC6BF7FB38CE9609C174B902B6047EAD37DA33285D1009B83C39FF67773CC46F7B4B2CEE35E8E95100C31DC59EB9", + "sk" : "081ACE51252462BB622ED578C65C864BE5210AD1CBE55B6288A8CC22D297EDB0AAF549BC240963F0C65368CBCCFEC732A7345F43D563315442AA97ACAEE1036C58A4FB752984AC6E85C4B744F5177CBA665EE2154B5C6C3C0455B4CC602D9C411186CCAF5C1A1EC51558FC5EB1713229EA213F261A249C225566C5D9333B9A579A907016406B709B8C97A0D2270AA0A11E72AC51E1A5192545C6515153E193EBAA7985BB23A47138BFDB6F96E47E8BDA4042CBCD993948FFB7CA2673C4A3773E9CE5A97C34C543EA24EED7537BA8A5604CA316AA38B0B04BEB922C9C62AF8E010A8EF9B22AC92FBB7A6035E0C842C3CAABF12C90B706CAC75F6868B26B8AB652476D520662FAA46ECC990A4DB166262C19521817B3A82DC3B8B671BA21DC4B06F3150209F890BE837882570BC7603C48026C44415ED938146C57B36C361B7C0B0E04BC81F532494A198AF962208E0785EC1601B57967BBA750D4A34BED69C1C4B2982B97A1FC49B4E7E970307087930B32A44CA7FA4C4BCF5A91E1B86A2D8C60E3019B7CF98F634ABA74C84911AC4B159636A4D49D63BC81FB2210FDB40BF3B2A467CB101C43C68473046CC4B6B741BEBD71B27A56AE4DE70288D74E6EABB2F9A1B334F4274E7369B7618B31316F5555288EA88310B97AD7B425D052B21FB42487331CDACCC4398BC0A67B4A28A77A2396327A95CC6CD98B54058428D9A9D7A45F83EA5E1BD26222C60CC3F77E0CC87449836940815279ECB65001C5BB4A599771848E10A64D8C4AC30B57C6638FB11BB1350B1D5FA34153804556266FC8D70A4B56067718C47899A134E36A1815A791600A14F43C9A2065FF786AAEC7A7C4571546BA339DBC41BD98C462A85E5B72CDD07C5AF9979F74C32B2D501F05A57D5D659958B78F26853500DD47F0CB8AE5C08DB6A6A97C1312AE3C20BB34C4C3A2A9177CBC1B152C2F9940937433B3414067093375FC6BDF44B8738B4AD95261E74371EA2CB2EDA13B57579CD2A939F7C9A9950A32AD07BAF63C02603A626D9C7EDC89817ED02BBB376DC2C523B9A84E45DC811D736789647C5C291AAA9A3D01511B9237A56E26130445A4486962EF8682F71412104B7FFEC39B11FC713A234AE3087181A2CE5A2A3E7BEC354E2921806B7C99C57C8F5BAB84A83DD75B16147AB62A39064B530462E40D38C4971C18BF39F469D34C12DCE7707AD61CEE073C6FC0CF6AE259CE16890C2528A499B98AC82712B8AEE7225B78EC01A19BBF5692366E737591733015616C38E30924044C2F551CFE2C90755362C34ABB53C59FDF8A50C1E392AF7A0A739A5626246E655991C41C9AFF111E2C21CDDD5242801561747306FDAC5B54CC4E76543E39900E491CB24FE353B45B38DE47CB3E05693C9525F88B4886E1514564231CAA5F33D776CDBA9D6CE8323F7C02FF9310C7227A37C172392A85F3C234F73C52ECF48A3385C310554C04481D28B59185B8CDCF80437B04087A7820E94B95E31189F2EB4A02E4CB13E683971B9D9D912D2C369488A1037B468CA88061B1A96BB8ACB2A21BC54B402CF84798008006CAEB9266B9783BA81482F02E19DA185AAC95E233659672479D02C0E1A418852230F28A3FAABAAE8C058A995CB843D98E048499F7250E1B40C532380917FB8156D0B5CE338FB6256E31752BA16AAD5B9C7E1017188DE86E509109586CBC59916993A5226C13332BEA339716A228CB2C6A90B485440A98D6CBA8C5592B692763F853F56C35948B0860E087A15A78A134C3585CB034F135A2B79D2FFC73DB89B65512253893CD2AA937EAA1AD24D0AAB311845BECAC9F15B7EC1B6A51AAC4AA45C337B44644499CD464CD6F717472A08CEDB8570C8714D088A2CC21C4EFDACF8CC59C2DE91764141ACB26851CC584484728FA1290A90338468AAF944C943BEB9D7295CC500054615AB770423F82F329E3D3B751C70589C693009D7C1634B5C43BA5B795AD3873ADA60669835A034D61439F3A897C021A057616F911087BB626EBB5A9E6D63E896371AE4192C93471B66AC0544131EC28074CC6A12B4364FE362C2FC68F359A7313AC5D744989BC33B1846A2B0DB449F84A273738C9F2D98E6BDA993DD514F17AA047E8B72E413BAE7495F0B58B38B71D85A8CFC1F183EAEA4CC281A5BA6A876D7233107B1BEAC2871F16B152D08E74E28A250999DB0A6DB7036711A24370401AB844CD39B124B8D42E8A15B2BDC85FE3B11C9CAA30EE666F260AB0F0E230A5901229B974446428A9E24680A884208A2DFD3899FF1A4920B798AB275D5A10B01503D000C23DB72CCBB3A91AB0186FA7850DE3055E4531439BFA9CDCE3AC888066D17469DCE07F76D0397BD46A59C29A4A776C8B7310021128DD248BEEC9296C7C5E95D13AAE21303127778B653131BABC17494F0AA63C18260130315BCCA7A8C8521E7B9C9544C1260BD201EF23974957A6A4D3658D96A7FD4CB7DAEBB11E5ACEC216042CAC64AF05C8A7DB570CEB09393C7A24F5AE305280B1C22B9D68B02A0C521DD6393C20CB3EB798DB457CCBD869748AA2CDC8336A58162E56528C3AC7A7BB41E2DB1A35257B6135247C7802024CA258F03DE2EA93E2F6C42E539617D27FC62510EA016DEAF787A2B3B930165FF1FC8E20413B90EBC827581B74988937A018F612AC4098514480212781C4EA128680448B58A5A296B35020C6668ACC7A39EC329F3C5EB00C44F43C9DDD612C0860031669C911E0B4D5D20F45EC1B6C5B6BE399C2BDE785757215BE7617AA6A57EB6B797C8C5CF774274B2463D0C85E1343554BA052FD9B36DA139E13E04FF18427B418282A5642429825D15636DA6C45834375D543714E80530DEAAE0B006488ECA46974642C8307AA5297D34619DC39863F276189A20B75673744FB934420A138506FB04B0EB2E22108C1923784523E767DC70CA546FB820DE07BB9663333E623889279BC596B2F559F5699C272C3040602A0EA98C878D2AF1D7AA697AA83F1DC10E54017E2E586B220804588473C4B9D05AAAE6FF9C038D00F953547EC748E62BA3426001C3F669941596C6184B353D3919E591DF898831EB11AAEDBC49B88C8187CC13EB79EB09C7E07545BE6041A9BD0A70519B17B5479AEF79D105B83D74C08C719843A94BD1F76BAF7E3BBD6795E05830184C53F42061F4B6B0321E2561B4C474865A0C825C96F9269E12742771C4C9B20B9380540772A24B43C2AB3051B88EC4760F794C17AAA55199E39EAAB54C53AEF32BFD339C824501972EB5ED299908FF0AB3DA01460F106919B450BF00678967E45C18531D112B481918FB7023EFA1617DA59FF391B84B03AC199A1AB31208B918777A2C8A9706CC8359D09E4A817386CE09757C44350D10C4EDF02625ED06DD3DB07514639F67828C5077F0EB722F39587830C506C4BBB4BDC60A1B256BB157ED4770E603211D508165EDCCDB2D6CF37F039578176032C2158EB3C9D48921CB387339267BB728ECCF97BF31309D08611B91271EC698D8920CA3BF334FD8765B0170608726A6220A3ECC14023F02AA4F31446B22DA93597E4A46D451CADA3965EF2148A832221C4D8A7D12157D9B3BC69FAC8626B2DD1C44AEA272CC2125DC79A4F90B56EA75144037A4F0060C33C5B6ECA4572142310CE956FD6F31D23C6C9F6235057362B884A014FB5867B2C1976127A5A287EE371B7430CAEC5D35B63789B31D176D2553F82C8407F585C32511E3F0CBA0BA60537780EDC6CA22D1422EC8C3357EB203EE68C8FA135B0AC2836E027FE3161769C6838E98CD449C14EF2B07AFC714CF02D91D387A27472217C9EA6BC5CD1249BBA38842CF1B28701A6074CCFB7316DCF345ACD84660D02381040CBE8109C5D423921B84771A1CBA981C5FB08C5DE08AE6CDB38FD5B9489357DF11565D48A7797A6AF82553225D73CEBB362ABB1CE335358C6776D9FBBA731883AE7CC517E0A0A3BB5B970E4CDA95A98ABA47D9E2397ABD7757218C5D7BC4CA59B70BE5AA4D7B62AFB54048FFB0C64919AFB746120B383958B715D110E5E6BA666940328AB4510FA25E9B43537E566EF760D2CC52B07E5BC089B8EA9E166C513BACBCCC332F36D6AFC379E1A838AC24EA35C1260726D029651088996631C55E846ADCF36C792C21011320B2287973A770D2636470C080B2893A09BCC8705306C5B364837B7CC89A9AD1FD9C1EDCCA9A0B4B81846C8E088B36FE361539060CC08C911C9058BBB0839183B0C59302171826DFC7B6FB1C623DBA3F0F9B30768346A7714481B741BD0BB7CA32ED73A00A6A1874D8B7369F695EFE75E00F03BE6CAC1476815AD889C69EC6BF7FB38CE9609C174B902B6047EAD37DA33285D1009B83C39FF67773CC46F7B4B2CEE35E8E95100C31DC59EB9D604833A540D9922A7DBA53D67A38DE1634CDDEE1B169B45BB9EB3646E55FC0D648E3FAE1AEA06E15778F3442223574E9C7823F36CD16C72618846331F95E91C", + "ek" : "0093458D90D462D225DB556E15B5BCB647D5996474C7588573AD64892162BC01D64A61C1CBE4834939B3292C578CC45AEBA5BB85AE755B2E1933AD23B9C62C4321C791E939D3B14B0C8B2175BDB38729C15E6E65569D3E9DE92D1A80C66BDE8C8860C675DA3A2CE73796097053800A3B2D18A5F9AABF2B9E95C3929DBAAC043B71AAF7BFEE85A419D843B66CBA1F3CA5D81DC31B0C23CC35704CDD4907768231441BAFDC8638CC89640870B314DA39C6B4841AE5D31B6B171C20C5C87809DE2C74041CDD1D9D13FBCA381E684DA4759BD13A0EF6B95FD3DFB06C35B34F6F1633E842BD79AFDECB47581980F9C7613E2B6957B4F30D8B8F9631DF8469945B1D4397971003CBD6A2993D8B014239FD44BF7FBE5AF14F4136547318E7B2054C51AE79E81AD9D17F03CDD85F62F78473095166599EDEB5FD4ED8C89FA10CCB4785BEBEAB32E8E6F91967592AF2383C17BC3D365C1119F93539C74F481403480E1AC9F872F638298348B1D343373EBDCEFDF5C67B2FD2BC1107FBB93570DF4A14E90428C9830785FD574073CAD0BED3CCF9EDC7F0F12D2722B7B9545148A4830A03F49E53704128FD320E118F4BF95C898C696E90721B03C42DFBC0DEABBE290740CBDB0B36A93CC9C32D8FCACD7E1A8B9146EC3AE7D5A82DEBC0B54EC3D14A185029A648C03DF448BBB53314612F839F070B98CAB21C0FD379358C7A8EEEA31032FD6D5CDBA4940069037EF9325C93C791492C9832F8BED56F23107764690808BA48D3482DB6738CC04EA5F1473E3FE8C15789E4E869B77354083264451888E20CFDC714FB9733B329FF6758FAAB511420BB46EBC89BABE78AD03EC4B2285B90B4A107931B5B13B78A5491AF7891ECDDBB7F7D2E13766F19EE5FAA0E8EBE04CC6BDFE23CED04502E37DE7A1305A883EB9DB3658E4FBDFB46EF19CA113F2B5DFC984D2F96875BC14A33A2F30BCF6139E1E3DDB902AB413DCC45B6D2B7EED2EB30DDDA8DA1D042CD6FDAF6F464F99CA793197B7474C810D870F4707741274787104A3E4711D7205CBEED008CFFA24033363D7F14BC2AB7BFA333BC9B30210DE85BDEA8973C252D5DC7FDEEC919CAFA6D2CFB55582D58D054566BAEB554A2465401A72DCF7CB79729E8E77167BB86084855D504652F690865A6F410A0B9D2000FBE30A41AA79D290FCFC57D7A149E18443691A4D316093D82ECBA958258725CA6F1CACFBB981A1B53AD660F6D57C41E177A0F4906E67CD892FE0A56FE04768FBA6E950E14FA0F8A79CE6671141805D37BBD0989CF267A7FB63D2F9A2E894F11808CDA15E379FC8B8EC3B1334CA7ACFFFF7D49842912D551230F595B4596FEC3957230623F8CBF4EAAB83BC39A9D20FA986BC758676ACCE607DDA9B38E5D0C2575F0B180BD075C3FF62A4578FBCF398B0B8E634118BB433C024D9B8A9832F48DB64D6F11A601C9CBA92C302D8A3300AD98B4624FA499FB1FF7FFB7C2C0FFFAC8ED31107F653A73F5E80BDD3F6F81B9A9600925D4E306E6772716606A63F49B22BACF8E7CC2E7F088506098865B84892144A84842296D790C3FD9EDFCD163DDDCAE617670C0C52667393DCA0681812166FA91408D5D2737D3EAD8588248F0822CE2AB8C868794B191FE0D499626C47B41D60D5BC87B06D19743BF8E4F77734C6EF5EE74D440CE68E0F21AEF39FDC69C9658DE6251767E15B83C5D0C674D14A30F3CE3866AD788BA7E414E5F971E765E26FE6EDBD9C95B01366F6F4EBDBC3ED7EC0060CDA1A3C1E564084C80E3BFB2FC0DFBE55488E0E00285D3BC093B343060AD4F4B0B4C3F8A34D633EC860721846A4CE871A50CDFA76A7C65E5A10F4703DE40583A1497672340F7356E3F6056CF7447D6C6F9324F4A84A0C5D8B1FC490785F7ADCBAAC15DD24157A41824DD543D23A7DD35C34DAC3E293F79474A834F9E717527999CCAF7A3F39B6B44B50402303EF5323B2FD78C40D8553C56B6947472AB1021D7BC3449F6B7679A9EB31863FA0348246B4639CCF94B636DCF164B5D1693EA8EA3692A012C932B728EA83BC398E19B0A89941CE2E0F6A76DAB5E82BD452DDD7231FF4AD98798209D94A704E7EFA612EF06550CB5C613E5F55D8D361B269F6D2D6A8EBA499AC8B6BB93F0DDC88D02D92AB9E4CFB1E946A1279DA2028BB3E0B45E74C22BA83E07BE1F0E6D7F4CAC0B71D20CFEDCC03BC30E88EE20424872B214C624706B", + "k" : "88752E6D8F051AC4E6A666EBE96B5AC6B73A99E7D3FE8D3AD2E4452B07EBCBC6", +}, +{ + "rngSeed" : "96D9A06F88FF2C2036FA8E914B89C765E4A510B468DEE40F914F78858C811857EFE9FD0E17C0048E7389E8D996B7E2B0", + "pk" : "F8CA36BDD81E5969C6E2F8A58829A9B7697B6B36983E896E82B40738740FA2E6B657616B0B4CC0B15C2292EB5B42550F812673194B944B830051E4206670BCE9734F53232B408A6CBE7542712352C453CAC39741B5B940151580482B4752D16F58A1C090B101CF985034299840A186A1061E59EAA300B66FEC19A3ABAC920A1A12E1E4070AA37893923067614F9E53C0D859917626C6D6658A0324419D0B0D16A647ED57C3CEE638400875CB0436671A0C9F472EEDE423125A95C86C60D2301C85660807F43F35208716905AB4153B6510C128E038920A3A13E957E2E209AFB46C7E0C9E92FABBB80063B93C0A963B1AA2D49F48174F86C761D923259EE04C65F4B85DC110CB04AD4E26C369682E213AC4114824A526B2E6A21705174110B538E3562BD93CB251962E71782D89E562482A51949707AC8337B78627D489B193600636FC44C44898B2DC7C87332F3DD9C7579A68E0C01211FC1957C43D781473FD3BB17CE14456E62D93C236BD9656F5EA8088339668658ED8CC1E909A026FB76F0EC747D5A570AB88AEB44750710C0D10AC86CAF73F8E2238B7E51DA8722317973BD544834FA31571F48744B6A7CAC95E1D3375949038588CB1D5D50476629432CA9E43076BD260B1A6A3472BE2CD780177C4750B4080C09C820BF9F1CE2DE695478BA26A216BA2B032CB7729770514F71700864AB0E3780CF94CB7E94C88DD673DD03B8690AC65B8E0C597FA8098111D36EA9FC4B166D9E6BD4935993DBC8F21ACB9F53A20EE118A721541425A31705A5D67A6196C91A96DEC2B2B48536E118AFBD5C8FE46455AEB282A7A6E73B734001B6D3A997FF1D50AC7D3C97EEB4338F13F8EAC05CB0B6F7F60908C0B1ED89682192A6CA384C7DED2170674C353D9AEB8696648CB83AC986DFF669E23F49C47E9208DF49187C1155BB1C876D1242098BB7951454E677C67042DCDE2AF77E8090935B5BADA59C4252C6889B16765A033D98452F25632710CA5553559D76358C162C70C1B5624ABC090B59960C65889351529BDAE24170751A45A566AD858444FF61CFEB7003B08605F3B2558577F0E12B31A447D377294E7E4060EC12A5ECBB9770BB8707240C1237B08C744E70057D0E68E2FCA1CCED27A1997389BDAADA271054F72B849329E9A2321AEB03A940C44239844E94181B627876838671BDB3E9B4061FEDC74741B4B5E9C4B421167BF420CC8077C5BF02721076C1C5462D7624F8350AF75C50EB7267A96359004166C84145E72B731D5A82D43469C98B00A0C2352B7806313C60C04DC5F5C8B39D50376A9461F2A8773FE06973E852A04025BA6592F632BCFC3EA0AE572A50023C684A4A7A0DB573AD1494458990938C624E5928C028EC48A9A26492420781071D13A85A332DBD8ABB8F318A31596A38C7EFEEC28BBC1AA38198AA66CA68D811CF5700D9E093E34F38D0CC74A989459AB0B200A8CAAF6D40AB5E5CD651C05FCF68E14A1AE602560186A10AA452328218E41C49B7E5154C67099EC790E88AB641AE03DD6ACB82C33A6D4034A775515C52859BFE354B2E881C7C577BD5663B19B124948739BE90ADDB36348912710CC12102553765C580512B22EA35141EA4FFE681045497FCA77AD2E35C1A5B31BAEC2A8279C783D28241C923040607D38463A9B615BE08AB87ACC5E31B84ED8376D75F31DDA47C869F82CE14022ACC6C70429BA854B58E942635A12209240BAE3137EC8A40E716655A0A82BD02003F20428D15806594435DE6C39B746298AA9A693577783C71154CB31B7B31283F46733D199AE627DDB7947C4F4AAF1172858A97EF6140F56477B80450536396399A14A984CAEA756B1B5C09ED1F43C4E1754F40AD0BFC8C5F153346E0113930A3C9AD215F11C4ECE2875C41516B0A8452E948F3F3CC45960BDD8B23F14EAC17927142EB4A72EF6C3585899EFC128F53B022015B2BBB9642B5675BE352B9D442194D54D5B40A17C236E8A275DC2358FB31471A3F521B444040D983E64976B50F71441982F29FC690C41A954512F82A3ABF85235847A28982009E3303239454CE0C7A2C3840CCE031AD37516E6A3BA59B79BA4478AFDEAA8EE8AC4731CCBB34125D0A7C6504A8D7E285171A464129B714D8521C69B8D952B4623AA8967F644C8C08BDEF96117198E56C12602501201E036804129D528D717640EA33C9FB4885D61FA43860DAFED4282B108", + "sk" : "18264C57AAB774EA1BA3555C788511BBC7BEC8D072C953579D7B8558425123A057F94BC5670C85B11B81963731FC611BF751973A1105C7138D9C8CA76A559D20D25C79B64B70A91224E8110F623DA7097668BB1EA2A17D8C085128225AF2506C3F52A1F57011F849CECD605340724AA418CA6A86204FA02B0EFB0102E4B2D6F34A2817643BA33561827B3EA92FE0270FBFE89C3F84438C4397EBE8A735A77CB8597AD73B95D170B329D491BA624660A01EDD634ACAF45303133127E11B4A3B95804620A7C6B1F84BBD916744D18487A5D9A54697716A965B7A9530DCB406FF8B276787AC9E846CD037A00852662A6B73E976807615BCA1C00C1554AD0282B544DAAB0533B1AE9C1E71061DC18A79486C7FF9F0771A8138F93983134C5CF123955E748CE224CE925883C3565910088FAC9393D423AD55BA3FAD9012FAA77957D88573A721F372B2E3FB977DE30F72116090CB1CF02B0C1EA68CD23CC593E715A6A53493759F16A26A5C5745787115AAA233EC305B65B846C775BF36A754C8D563E25AB9E7681D589632131B8596B36A4FEA7382938E121C38D4B2B218B90D4C602354A3BCE5B58C4841C8DAF61F8573B7B1E46F38E203BCF0A0D0981576A45215F2C7339A6FE91839D899B995B839B9B465AA942F994913B906698B9A31530B0D4F096DE5AA3E885C6AD9468E1E674FC9B2ACD26C4A20EA5363F32D745A0AF3F037ADAC5350F07C5CA17738A243A29564455290602884866913D62413CA628AEAF248885B7517033583E05CCD55AC272B8CF142BCDF0BCEA1A9C271E747C8507FA6BB89B1F0345300BDDDA4BF13B40DD323C860F237D8F2B14E03CF02E923990BB8BAF13FBFD355CC3CB46BBB41B2F265A403C58E440306C7CA5A11CF2265562898B2EC28B5C6D396A1C668FD95B02E3451621A2D7212793E0921324450D601A19C975D877C84A91AA4B1E381D4F9256C0428C32809857B1CCE8B7BA412A3F7D4B3135954177865677C45191294636241609C533D548DD5E8131BE776724068A59242C1263E55ABC515E4B3536C6CC836A140062E11DBB43EF9831A012B8C34714467906B78A5ED8A8E515258DDC6ABBB0A110B6451544B78D85CB0DD78894D9AC491A7A5F08114833BB9C7628DD4061610944FD3A92205D7BE722A8F2A51A07D75CA660107254C88653A79A8D79811543DBAA5205C290A4F615DF4A24E7A7012155006DB9715CCF712FD65876013A6C5F12C272C112DB75E0C2983478328066496C34BCD763703E012076F85564719A4B477B8FC93845D30BA64164B28FA025CCB077A457F029B367DDC001B8CBED771B391857666AB88672B4BB5E4B653A8035225708B897FEFD950F8D9614E310EF1B65942D53BA13611FAF259F0A02C1CC357C36870B8B747FE1C66A5097FF49607007C0F52A74017D798DAD417CB308BA8B0381F692081C51FDA5B21CC5A471F5321D2128F0867714B141A37D983F3121054934B320AA2B044AC971870E0B2A6D14227C785504D341E3DF90C586B5C66243B01B42F6686AFC0C8B6A2FAA636E39A0C550A7F61AC5AF769E2573CEA2A8DA6B8ADFB03B12C74B330B02042E8C2921239C45641ED1899376C7939C51C08A15E23493C9B8A6396C44BBAF4212B05CEA4668A2E851C56BA56ABD11410E21B7BF18347CB020C33429C15B6658248DC75224189CF5C53B920068C855B24F9809CFDF8C61BC9662E981D8DD896C8B99EE667CEF1A4CDB2F14DF05435EFECC3D974CABDA81DC18192BFB39CCD144787BB3A6051B06B1082F2B75EED10C4DA0132D27C4FDD854B305B02C66A04DC50407D7160F1D54929E91A6A008D0A28CFE109BE18774744250C69AA7EE7BC41944597311C87438441CB59B082A5348E312B30D66F936585F356C06D761ECB04B48339082F1542E3F3CD885AAD7056A02D075AA825A3B99848C2E2BA518AA4E6662198FA871F744BFF97351E613CF2E7505D2115BE9A7386680300C1A985B39E0EB3769F73576EEAA28ED8C0F3B76AB5ACB302877BCE254FCF3636B4F6C4E0089D59305D5F819BE4F380D669186A24214E9B2477334C25D23910907240CA8F7E1720DC8ABD38E2B88246BE2A55C72F6C1DB3840370836F93992893B98F42F9180778795830BA59F09650986E5197A4DD239F99E7B5F8CA36BDD81E5969C6E2F8A58829A9B7697B6B36983E896E82B40738740FA2E6B657616B0B4CC0B15C2292EB5B42550F812673194B944B830051E4206670BCE9734F53232B408A6CBE7542712352C453CAC39741B5B940151580482B4752D16F58A1C090B101CF985034299840A186A1061E59EAA300B66FEC19A3ABAC920A1A12E1E4070AA37893923067614F9E53C0D859917626C6D6658A0324419D0B0D16A647ED57C3CEE638400875CB0436671A0C9F472EEDE423125A95C86C60D2301C85660807F43F35208716905AB4153B6510C128E038920A3A13E957E2E209AFB46C7E0C9E92FABBB80063B93C0A963B1AA2D49F48174F86C761D923259EE04C65F4B85DC110CB04AD4E26C369682E213AC4114824A526B2E6A21705174110B538E3562BD93CB251962E71782D89E562482A51949707AC8337B78627D489B193600636FC44C44898B2DC7C87332F3DD9C7579A68E0C01211FC1957C43D781473FD3BB17CE14456E62D93C236BD9656F5EA8088339668658ED8CC1E909A026FB76F0EC747D5A570AB88AEB44750710C0D10AC86CAF73F8E2238B7E51DA8722317973BD544834FA31571F48744B6A7CAC95E1D3375949038588CB1D5D50476629432CA9E43076BD260B1A6A3472BE2CD780177C4750B4080C09C820BF9F1CE2DE695478BA26A216BA2B032CB7729770514F71700864AB0E3780CF94CB7E94C88DD673DD03B8690AC65B8E0C597FA8098111D36EA9FC4B166D9E6BD4935993DBC8F21ACB9F53A20EE118A721541425A31705A5D67A6196C91A96DEC2B2B48536E118AFBD5C8FE46455AEB282A7A6E73B734001B6D3A997FF1D50AC7D3C97EEB4338F13F8EAC05CB0B6F7F60908C0B1ED89682192A6CA384C7DED2170674C353D9AEB8696648CB83AC986DFF669E23F49C47E9208DF49187C1155BB1C876D1242098BB7951454E677C67042DCDE2AF77E8090935B5BADA59C4252C6889B16765A033D98452F25632710CA5553559D76358C162C70C1B5624ABC090B59960C65889351529BDAE24170751A45A566AD858444FF61CFEB7003B08605F3B2558577F0E12B31A447D377294E7E4060EC12A5ECBB9770BB8707240C1237B08C744E70057D0E68E2FCA1CCED27A1997389BDAADA271054F72B849329E9A2321AEB03A940C44239844E94181B627876838671BDB3E9B4061FEDC74741B4B5E9C4B421167BF420CC8077C5BF02721076C1C5462D7624F8350AF75C50EB7267A96359004166C84145E72B731D5A82D43469C98B00A0C2352B7806313C60C04DC5F5C8B39D50376A9461F2A8773FE06973E852A04025BA6592F632BCFC3EA0AE572A50023C684A4A7A0DB573AD1494458990938C624E5928C028EC48A9A26492420781071D13A85A332DBD8ABB8F318A31596A38C7EFEEC28BBC1AA38198AA66CA68D811CF5700D9E093E34F38D0CC74A989459AB0B200A8CAAF6D40AB5E5CD651C05FCF68E14A1AE602560186A10AA452328218E41C49B7E5154C67099EC790E88AB641AE03DD6ACB82C33A6D4034A775515C52859BFE354B2E881C7C577BD5663B19B124948739BE90ADDB36348912710CC12102553765C580512B22EA35141EA4FFE681045497FCA77AD2E35C1A5B31BAEC2A8279C783D28241C923040607D38463A9B615BE08AB87ACC5E31B84ED8376D75F31DDA47C869F82CE14022ACC6C70429BA854B58E942635A12209240BAE3137EC8A40E716655A0A82BD02003F20428D15806594435DE6C39B746298AA9A693577783C71154CB31B7B31283F46733D199AE627DDB7947C4F4AAF1172858A97EF6140F56477B80450536396399A14A984CAEA756B1B5C09ED1F43C4E1754F40AD0BFC8C5F153346E0113930A3C9AD215F11C4ECE2875C41516B0A8452E948F3F3CC45960BDD8B23F14EAC17927142EB4A72EF6C3585899EFC128F53B022015B2BBB9642B5675BE352B9D442194D54D5B40A17C236E8A275DC2358FB31471A3F521B444040D983E64976B50F71441982F29FC690C41A954512F82A3ABF85235847A28982009E3303239454CE0C7A2C3840CCE031AD37516E6A3BA59B79BA4478AFDEAA8EE8AC4731CCBB34125D0A7C6504A8D7E285171A464129B714D8521C69B8D952B4623AA8967F644C8C08BDEF96117198E56C12602501201E036804129D528D717640EA33C9FB4885D61FA43860DAFED4282B108CAC59B140DF7D3285C832994E7A4FF5491C786281FDBD6F43A4C3902D4EAC0D2BB02D701FD1350AAB462CB65DAC4B2F75928D378DFD7A0360DFF9185175538FE", + "ek" : "EEC5EFB3DDD44E3B4D36EF939C397B8043115904459879346679660A4204F52316AE2BC0E97B8A76208EBD1112A1FA1536272EC69854A301CFFEE93C4180F97AFE3D5FAFB9B70022CEABC16BB909F7A63AEE904BF83DC12F96F7A74C99AE01CB678F2C671564443A7173B9E861CB7C89C5F2F350E49E4D6F04D4A98D1DA0144E106987BC76970D4DFDF22FC6E7A3677A7BE3BFF718F5943162E86C702CA9A9FBF394E5F61A1C5FF3BCB309CFA9D8B122A72FC6854638E1976794C40E94C85AF9872CAB6248FA62DF65025A077E31EACA91A0426104CE985CD1214B0D7E7F0E9008C6DC50B06DF59EC12D3E326E3B7E8D1E93E6CC4D573D8DFB4F30494CB91885070D005F0037940422503E5B50AB073C42D9F66C5FE276203CF22C60994165DC595842E4967AE507F4DB21FA5CFEAC7DC66CB687C3431A53F215BD9B7CC558D97579131FD515CBDA512F56BA973ACA9589A57959FAB6FAE087208A5A87B0A11125D51F861F4012032624FEA95727CD7357B8E2A9FB1CF7CCB78CA0BC5B32B851CBF3355E21EF6F6F5B4AA464A2A4C1E4A63532DEC65E0A28D3F12EB1E43E347AD78E845E43FD5434D34131BB3D7836229EAD1D30C565BAEA137BF56A9D6A102C8FE069AF5F9DE97E69FE652425239406646461249DB5B6825C7CA091C3694DE8D4D022FA0F3B33D288A43289040F5AC34BCB939F07CCD7D9241725CF6CB9581B520FFF84464D227ACCE21048D7498CB1C164F8416B5DC9459D003D9C2B059D100BD3A66536AC5743999AF0EB2F7AD428D3B4367AC536EE445E905A7DE5C10E8F357E79E24C772C5DA95066D749C50B3C1B50EA60B5D25A15CD9212D7A5D2D807127D4BB9410D33D8FFB36B14561BEE53F6362BD44E642395A956002C8A2A0734AF08BD3CC22B915D2344F13350FBFB112A08C4D979A0563F9D99CBD7A8306314B98C0FA64739DF89DF066D6AD369F6394063673A6E14B12B6964433A238649D2F667B1BC3E9BD96E2735980520E49DA2CCE3678CC7F117C1ECAAFE51379DFE001B59988897E6DAD6EEB324BC8376AB6FF2FF60C5696E8EAF6F0974BFA10FD7131BCC803DBB1043F50A8D1472EBEDA2BEEA509586213F2C9094D0ED629DE03E0EB018AFA9F4A3F7DCD5052382541613B0E328BE416B9BCAD7CF9649FAA91A334F04AD20252963F4428B62FA4724D63568BC1E436EC1F623AD52E2998DAB1CE0842560A528ABB6422FC51D90C17A5919E754CE338ED3CC6377EED3987E58D9869D87D2C4107F3722181E4EA44932EB0B773B9E7558CA3086CC641F8BD32A55B3FDA432CE74A06D3787C0EBD010F54F88C6FB139F26FEA3E395E050A2F25405ED0FF6BAD8533E9DCC8F09875CAAB94465BBBDE05AA0038145B3D67EBCD2A72C1BA01F3E9318BF9D20A694E96EC696F52997BC615E7CDC6E69E0CD46C19D24C07C91174CB54DD05263B08016CDB4C60985723837FE6B5961D954F3AC77EAB9029816638717234D0D7E159337E8E9DCD247DAC841292C6B3D2995EB255D7754E82C3323341AC2292FEAFE1BA81B58624C718A7B22A4878E7A5B60E6E8AD01DCA281280BAE4C2AD669769F77FF5A3E4B77385B8229165DE68A67B39D2F8BA80BB1B9471C7D4712AC1FDD915E9A15142FCF578FBDBE2A176DEBE481D6E05ADBD6D752B76FCCCE23EC75B15C81E8BEF6F173B4BC1820691DF417C22B4C8FCECE7C8780B1C98A092603E1811954F37F8382E1578B03FF0B076E06F279EE9EE636EBFC4966D511AE845282D9C733041147B51315CF5ABAFB9B54EBFCE6E1CEE729522B4CB84C5AA4F942053A9DDBF8A53BFCB11D4BAA34887FBDE6AFC4DE58CDFFA15B72E9840F70B81BA781619A77B6E92980C24CF9BC443610A00A55D22D41CBAE66D99CB3FFB69C2CBD567D87036E4EA266F634CA14726D239BDDE2A87033C08D18B671D4FFD3C506A595CB707ABC98B1EEFB43B8555694F64240F3C5BA79638BD9414BB3660DF210FBB3CDC783D56B3FD3D2DE67AB5E277FEB1C941A581E7F4F90F926E9A9AEA1B15A40F6C86BEB86D5BA98E774828C0C74C98B91E5299E8ACFC3D32BBAD8E8C5D92908B183C7189B13FBA592E3F38CD7E4FD108A3FDE1EDB7F84665B87204D60C117E492367AF8BC481A132A5719BC598015D49A029F0169B73667430FD37A0B4E1C0806E65232042A55F81559FC7E0A5A40B75C8128D7B91345232B", + "k" : "741FE0C5BBB60112B8E3C27089E6A85CDE5E86887EA7C61B43D061FE62D2785D", +}, +{ + "rngSeed" : "D26CE360D399BF7B89DC364AA7AC06BB513EAB8F527383E93E30727EDC3F22C262AA0EC70257B39EDFF0630DCDC1B79A", + "pk" : "C19093BDF18070E37B3AB06ADE8B14DE2B34CA99763F575E8D75177C72522C6C4ECED8AD20AC6BFC4AA329E765F986579C373A3A333D6167C2C7440E8F4131EC305188C989140B63B65019F2949C81C36CBC45939C026A42A1554F2385A738A229534CC6552D5E76076087C9E5B260BAF8724973B9152B3941FCBE19227BB7987D74856D3636049715BEEC638DB8E3B1D4E3BA2A440B46445369B60E0AD3C9C07C3203E2716FFA51EB5005D1A797079089F6E14D86D988D7F960F0DCC553A83F7433BE60A463B04423A6977599B7C1F7730265807B3F7B2BB8A625E0B0A0F3F1171D6C4E7A9A6CB5803B4871501453AC19B576364C3BD7E01F1BF475A9E71D557171E4D33BD3D14823672F27E356C89395C1476E0FA065DD168478BB710394116DE27CC3B0617EF5B74AC718E8B8C152C052A4D57828824AF38807D91295A0DA9B49DCBDA052317F5576E52B51ECA732D8D260D08832918094DE65AB48D3351B1327568574DCC82E3E8A222044984649271B3B45861AB6F5250A770B59071309D118ADB32322739CAD7227AD2B3460D156C065713F29A05EC48BB21AC7261AA6A0F3F19D05F0AA577CC8CAD6A7FBD25826A3CC6EE225C1B183D8E124055414C54469E4E410828BCE94A5CD95E22C7CA3770EC5A023F0656447621006929174850C786FD6357F36188A4884CADC108485277890A0114B4C565747C4165196E3E90CFA659662D992C33BB2582970CEB60582A691D66174952841AC5A64E53B31566671054486EE20437E245E234176EBC696A55A53308ABF020B40B944CBF382155BA02FB9EC298AAC3C2B81278772C9E0C730AB13C6F374BA8C886300831ADCF9CCDCC566E2456BEF479F4ED08EF803CA8719C382DCC667A21897DB1F81B41521790EE233020F3301BC9910DCE2202BF4329F632542F820BCABBD2BF38962E6810BFAAA5377A83B10A62495029E99C4BECBA9F0B3A54F70788F97AE54F01781B8505C27C23B810EE9C7452952AF9339C4AB88AEDAAB3B9F951CECD828DAEA0888A3481AB39207A6851C0285226136EE392996C41B7D93221DF711D44531C8818BF3B71AA65AA0A3B5055634699B007A47210E9583928EA984C413598868BFBD021CFF817C426CAEB3A77C9067B04DD3CDAF2B840AF6A44E5A5EC3956B21697CDDCAA035C46159262524E55F9923A5C44C1C747A1E35889B20AC2ECF5883577C0722316D6A82A88B21C8334BA25A442101B6828B10B1D9280F13F867E10C88FF3CCE3AF457A4BA82CCC4C231CA991B79C66BE0C56666C80656845789B45F0606539149CB12B0917B297FA683031413D3E89D3E38544EC40CBF288320BC3B812311EF69125E641232322E3F1BA325B668174179E38868BD50233C78B0CD8721ACB23B0B065A13F36A2B8B8245095CC785C64997ADD4A33B45E9A602B10EDB318830A046D8F700B2E76094228A14A251E8F48403914CFDCB9E3AC0795F907CC592AE18D322EBB882A1473FF2FC666B7A829189A4910C60F8B1193D59515280BC5A9169CA6433C4E560DB8AC756944FD9EA1DD1A0C9F9F57A474C32B94730460046251AA7D27A9A3F2C617816386207449D8C18F04537084A3F464B737C1A49E59C9042876E0556B92139225FA3AADAD3B5F18752DD614C1FC200923C0E0B4804FC5B26F7C6CDCC684DA00289CE344518C7A480936E46EC4C01B36A7F2645074B26D0414FCFC46D2ADA8FBDF1C50C128EC5D2ABE11AC78205310AC8AEA724A117F00246046C4360662101B191228628383CD9047A28025CF8D6A47DC161AF353E9067AE4433803C48B3CDE24466D00AAF68BE2EB1A209E8B1F6264FB14873EDAC70F834C710ACC18FA4C6D16A627B03406FC7501EF71E62963E01869C80787AF2D96A4EF8C72D273A3318C2826B8BB513BB2F6739648666AF720FBB4B7785C853BC1AA4CCA2C9D5852706B7BDDE4C06C78C960265CE1887B5E13275F42377447751AC0BC811E26C2F65BB19E058D573A64959BC0D74727A4B5AE8BA23F2179FFDFC171563712EB028D9524AF43C6143277BBD537F1155B04C0006B66036161472A199764EF7283E044C62A7244593564B15436B435DA9E995FC803964F631F8332FC8887E49A87C5812860CF96747EC5891A9ADA1E769AF720E946C9727731449CC7179F73E867C8A63B210D73CA9F8D4EB44B5DA3B57DFED46BD22AB85B9BD915556", + "sk" : "6A45C4D6507CD4ABC9BE8CC42A75BB661007F8BB7C8A408E51FC9B63FB8575683E3AC77AA6862F808529819219D8639F0C261CA4A2C2021426B53C19EB7C6DCB554F39952C0F4940FABB4C03903C5BD2592FD4178A68601A8C4B4FE598B3B874DCE5581063351683A672612904B17BCA915FF161C26AA8A27B212A7650B0858736C1D7025A987C91171E4465702007B4BCA05FEF05186106B895C62C42F33AAF449EA0D4982C46276069A970E04E8C58CE53356F18A99C7E2A8B1A9714A64AACB42338A2E05F377B969C82958891A9C335CE1EA24865EA1440D99038D82035CAB7D011508A802DA9B51A00192344AB9A38A59A2B203B448639B89A80B2C2B3F6163562CB2A01F526BF812181AC466C55013C94190172C086A2CAFBA3152FF247B89120EFBB1E957A33615924C34C0260034A9163C3DA2B2AFA4302595C4170953864990A95146DBF30B379F343B2F236C03BB4851775DA2A50F9A40121F7107D184D410975ED743FDB674B179C396B33C808B1AF0E717EB95000B62526598879FB5B972B54668B62306CC2C196F81113B72F6E4B0433B44251121CB7B872C54656A8E211B30B57C17A29FBC91DE1A8943EB2A0EC7CB04B4B3D4D057C12181684519DA9DA271E8189C8A6171F9108740482DA39C8DA064F5D2745EA9585702601513A2C5C1322FC95A7EF15AD1C4353710080CCF396F2F006335480AC1932407B048E72C0AC24A106051E7737A1E11AB0905AB829404B5E37BCA2EC9F9BDCB370B68404875061F1035978A3C7F7962FE015AA4C019465CBF37C929848C335E9CEC829218E15902FE045E6D43C845B99A8878EF7A73238FA87CF0C58DCC3913DCB29238928D948C94BD54029D9651B25401E64A29DF9A04C15BDF047A3AE857D74A5A22B383069EC24BFDC3E0D85AA892C6E69651A07EB61CCB40EA1D0BF624A17C4B849FAE348F8A8C326F875DAD81227465688B264DE92A195635A690B3D6126989AF58CB6E205CB8253AE8472E2E9B2C8D711FEA534BA41C108F22CEF0829F1BB4372D7A76DC4901F07AA413395998734390C07BE80CA1DC6CF087B11FFB180F94B86C051B505752D27AC9FEFA29FC849C77201B90641906492B54CC595E1DC71738A678451AEB9D4A30BFB2776435EB3D990F8405623856ABC7980B0A4C65D40ABBA6278FA4C7B3ECBB718180FB3225B597ACFC7E43CAAE9413FE858359334499A921B3216A03403672B6B1920C6F39B8ECDBA69D87CA52542CB0898477587AAAC8369F6E39AC7609C437456290434B002B2C3F32B05C41C1F827ACCF461DC159FB7CAA9856438FC232A5B4545C25C66A8A25C1F240EAAAA263F22CF5FA86506B51FFF385AFFD91B6AD8BB599633264C3CE786670AE70266F898A48040639CCF334188774C90B08B99E1A07BE3244D7BA319146711FAA921B647C7227B6CAAA70152701562D81BD1D1CCEEC218EA967BDFF454FB176F6EC504D7285779C3866763CFF23CAD659803B41448BFE253E391A21C67B89911C06E7C78B6B2AC56F737AA027CB7F80FCBD0897F60781767980B89266E342E80C97BC2336BE308A7CE393A229836F765086A6709191878570C6919D825E6C2A8F3FB9B4689079CA814759A8234B5C49C19623ED637859B991335672E168B7A31B788667CB088C4DA1A64319824F2002BE6D942C3E4891B032CDD347361352FFD3022F68017184110507017243C68906425C883093CA944EA118B20A30E05F740FB86C96742CAB2C086C4309FC53760E77A8500FC6830AB9FAB96BE00A319615905325103113956E233728A8C8755789F0B0B5F6061B320F0C3217415EDA617D33758FDA34C0ACC07C4C46A7C457FFB2AB6962397E1349325A90DBEE0AAA5977047549F28873E034AA770064FCC40C069166061B5AD66277320E989712A30A8969882E275B160046BC80077DCA73B307D71979C55731741E916657A1A46104D511B7BC8378B833350BE93C3015B68A8C651B960238853A294853D1F60A32D016721C25A30542367426FE2A22B45945A4C61117DAC71CC04A9DDB9B86A5B4B25569A04A19D28778E6FD27CA9763DB9E4B40A773B1FD53DC0466CA2086A561969D842310E5BC14CFC22FD3A5B4A969800E036E47C9F07B3AAAA0181CD8CB43B11534E267751337BFECB7AC19093BDF18070E37B3AB06ADE8B14DE2B34CA99763F575E8D75177C72522C6C4ECED8AD20AC6BFC4AA329E765F986579C373A3A333D6167C2C7440E8F4131EC305188C989140B63B65019F2949C81C36CBC45939C026A42A1554F2385A738A229534CC6552D5E76076087C9E5B260BAF8724973B9152B3941FCBE19227BB7987D74856D3636049715BEEC638DB8E3B1D4E3BA2A440B46445369B60E0AD3C9C07C3203E2716FFA51EB5005D1A797079089F6E14D86D988D7F960F0DCC553A83F7433BE60A463B04423A6977599B7C1F7730265807B3F7B2BB8A625E0B0A0F3F1171D6C4E7A9A6CB5803B4871501453AC19B576364C3BD7E01F1BF475A9E71D557171E4D33BD3D14823672F27E356C89395C1476E0FA065DD168478BB710394116DE27CC3B0617EF5B74AC718E8B8C152C052A4D57828824AF38807D91295A0DA9B49DCBDA052317F5576E52B51ECA732D8D260D08832918094DE65AB48D3351B1327568574DCC82E3E8A222044984649271B3B45861AB6F5250A770B59071309D118ADB32322739CAD7227AD2B3460D156C065713F29A05EC48BB21AC7261AA6A0F3F19D05F0AA577CC8CAD6A7FBD25826A3CC6EE225C1B183D8E124055414C54469E4E410828BCE94A5CD95E22C7CA3770EC5A023F0656447621006929174850C786FD6357F36188A4884CADC108485277890A0114B4C565747C4165196E3E90CFA659662D992C33BB2582970CEB60582A691D66174952841AC5A64E53B31566671054486EE20437E245E234176EBC696A55A53308ABF020B40B944CBF382155BA02FB9EC298AAC3C2B81278772C9E0C730AB13C6F374BA8C886300831ADCF9CCDCC566E2456BEF479F4ED08EF803CA8719C382DCC667A21897DB1F81B41521790EE233020F3301BC9910DCE2202BF4329F632542F820BCABBD2BF38962E6810BFAAA5377A83B10A62495029E99C4BECBA9F0B3A54F70788F97AE54F01781B8505C27C23B810EE9C7452952AF9339C4AB88AEDAAB3B9F951CECD828DAEA0888A3481AB39207A6851C0285226136EE392996C41B7D93221DF711D44531C8818BF3B71AA65AA0A3B5055634699B007A47210E9583928EA984C413598868BFBD021CFF817C426CAEB3A77C9067B04DD3CDAF2B840AF6A44E5A5EC3956B21697CDDCAA035C46159262524E55F9923A5C44C1C747A1E35889B20AC2ECF5883577C0722316D6A82A88B21C8334BA25A442101B6828B10B1D9280F13F867E10C88FF3CCE3AF457A4BA82CCC4C231CA991B79C66BE0C56666C80656845789B45F0606539149CB12B0917B297FA683031413D3E89D3E38544EC40CBF288320BC3B812311EF69125E641232322E3F1BA325B668174179E38868BD50233C78B0CD8721ACB23B0B065A13F36A2B8B8245095CC785C64997ADD4A33B45E9A602B10EDB318830A046D8F700B2E76094228A14A251E8F48403914CFDCB9E3AC0795F907CC592AE18D322EBB882A1473FF2FC666B7A829189A4910C60F8B1193D59515280BC5A9169CA6433C4E560DB8AC756944FD9EA1DD1A0C9F9F57A474C32B94730460046251AA7D27A9A3F2C617816386207449D8C18F04537084A3F464B737C1A49E59C9042876E0556B92139225FA3AADAD3B5F18752DD614C1FC200923C0E0B4804FC5B26F7C6CDCC684DA00289CE344518C7A480936E46EC4C01B36A7F2645074B26D0414FCFC46D2ADA8FBDF1C50C128EC5D2ABE11AC78205310AC8AEA724A117F00246046C4360662101B191228628383CD9047A28025CF8D6A47DC161AF353E9067AE4433803C48B3CDE24466D00AAF68BE2EB1A209E8B1F6264FB14873EDAC70F834C710ACC18FA4C6D16A627B03406FC7501EF71E62963E01869C80787AF2D96A4EF8C72D273A3318C2826B8BB513BB2F6739648666AF720FBB4B7785C853BC1AA4CCA2C9D5852706B7BDDE4C06C78C960265CE1887B5E13275F42377447751AC0BC811E26C2F65BB19E058D573A64959BC0D74727A4B5AE8BA23F2179FFDFC171563712EB028D9524AF43C6143277BBD537F1155B04C0006B66036161472A199764EF7283E044C62A7244593564B15436B435DA9E995FC803964F631F8332FC8887E49A87C5812860CF96747EC5891A9ADA1E769AF720E946C9727731449CC7179F73E867C8A63B210D73CA9F8D4EB44B5DA3B57DFED46BD22AB85B9BD9155568513EAA3DE494E114C2700ED07FFC1C2F8EF741765E8A42579DA4946AE0A201C165FD0A50A39142F7C6FAA2BFD417ADFA4224858281696965772F448C7AE22D4", + "ek" : "BD79C4829717096247B83409AF90ECC259528AF5A816EF6E9D70D0A6BD3D4BE4E79C74D0A40C2EE63030A55ED943236E57C65E983ADE9B7F581BA8C9122A14E5369636EB6C12332E19D3774179DE40DA139FD38E6098FA81C55D2E326655362DF825182BE795BAA15550A4452229375AA3E6B95B416D9CA657016B531C3A421F4E839649B2A8A08727613E2A778743BC98A0717531D00EF6EFE7CD7BCFFC9D39908717E936587A798E770D711E3D0FD0E55906E4EA1F1587D19AB9EB3BD0148CD36B1322F8F00A6EE32EE9707E40F6443C72A05F29C38F3C8621B4379ECEBB97CB361930811417D62D49C2B312E161DB5067D1E464064179F7055606931FB38050DC4CEFE8175755AD56D16DD8F1FA313FDF080D55794E57DE6761A90F189FBF381C3DD30D1710A12987910602C216983FB4FFAADA11E5CFAAA309594564432DDC16BBA507EA8E52372E11015A51C3A6FF53FCF0695AF22E8303B01635AB3E974EEE0A0D5E3E295BA04D38674139966C6DD4F01FF40951876513B7A5F5883A915D3FD067643AB53F28C11938A223802D632F6B8B06C15803875DE8315581326D811C5EC591A763047A9E8CD801A4F801DD45B8895EF13E870238953E91B3A8A16248EE94EAFA41200B2ADF2C68B924192AA9579ADD52080756FA9B35B3B9FEF5B463EA4C1B24323A1D53C59CDBC9CE1A39FF9687BE75B95D7D19218667D67140562893F05844D204F8D3B8458BC6D2A61B77FA710AE01909D26B77382EB1ED9F2EDC5AF32E9179BCF688CA851FC0C69F1B7B851FCFB35F29573EFB1B13B22D422F1EDA8C1366A4F63762BED91EB2D5CDF62F6E668E662FDEC1B4D634806AABDA127BD1A756C0CF49A7E52D6A8454BC57C82F912C43B4753059F445036EC8C0185ADACE8160D2F7D4107C07197EE4A9A7AACC1B3AAA40304A66C752B1E41500F2237DFCBAF9FCE3D8D2EBD286F9B5ACB41889AC1BA559C5C6F83E3D701A2BF259B0D0475B54D7D51EFF59F6B60379683DB9E95BE0A08026BE4544CBA282F8F064877F26B42F76029D271020E4CC5E1DC13F0831C1AE9F100299ACB3348C2EFD402E1ACEA0BC2DFDAE8210F3FAEDF7376280A91B888EDEA1AD071CBF76C688E443CE67E4A26E9C0774FAAB19E881DC9AF79B59080BC6C32B89F256860ED122B91B2B000C72447E0EEA2A59CE9DFEA7C3D78C352B247E6B1BD3D7C9CC4E6164AB7D172CB195D0F48E80D419949EE8332A4F992EE24D7DD3412A33A8F09E7D42A5FA08659B62708A6B0DC7D00A46A4EEE612B8B7B9E35F10CBC1CCCE3A61B9BE71DE35E61A52217D6C5979D67479104F9AF4A231E2AB78BDA00624CA3036DA395118F85B8E5AAA3F9E06E7DC17AA9E85AF92FFD88AEFAECC54C3C4BD730EFEDAD1ED55717C900FE4E2BFB959310BD201A90C861721BA077EE62D800AAA5F241E659E0577CD3FDF24F4851C018F2AAA328AC9A3F5D5CA01D9A9A9222ED49CDFD98FFFA99FF6AC28FF184AB748FACC7F3566970276B93EE7687C0A87EF0469235A4312F56710BB0DE3915D075F494DF483D23B5AB5D6F3A2AABB336C214D295CA73B6EB4E25CB43A1F0C8C55BDEEF72BF9BF3621FDD8C30DA95C5D4617CC64B33136C80A23FABD1801BA69BB1314E523A2762DEB46010BAD939FD1C4EE76778178D079F5ED1AA15936B0F83DE8F41335493322BD83D35BF78FBE3015B00449C0475E52A5EB3B3A2BA01AFBC5FF51A8F5E0EC4DFBBFC3ADA17C02030BAFF05B9CAE65231E1A9BCC9212957F4555AEB0ABD280687938B61F048788AC5BE0C78B64488324D0D75290A692DC6B1584D19D869BAB13157E1C3AD5FCE21CD98BD7EB33A772A2FD47CD5BC3A8521F4A2C0779CCA0B17AC74A56439E13827A2C764CE9374577F72941F2E16268353A6C387DAB64644A0AD1B37F9C65197AB857AE0577CF4C1ECF3F80D00D8F250C6A6CF6A13EB23A70A3E1E1EAD08A88D31B836189F93B4E195FC5BAE6CC3681D8C93ECA7CAE45E9EB5F3CBCA923014A69B0851EC5EED932154C23F6A2D4823972532E74E9ADBCBCE4A5693AADC7A88EAC00BB68533F63718AEFC01F01EB109A0631F15058C990778BA8D5FE2841AE6F1808B73890970843D5ED6E683A546F8C129A400249425F7C61851897CE74228104A668AD9255CFD82FB5B58E50E9F235F8C36CE678CA59403701F679C46B1FEF0C07446EAB4C6271E588", + "k" : "33139AE7CFF82885E6F8162C070845EA821F180E0AB27F80C05C399507B5DC58", +}, +{ + "rngSeed" : "C5856298C3CB6AC9787A0F30938537AB2635B96F6D19CC9522063360E7A5C88E644929D2879180E3E5BCAD2422B7CFC3", + "pk" : "CC9A64734C470128056A7B5D374435C099752EDCA129091770D6AF831AC7805A7DD5657BCBBCC9D751B140283A2EC533C17BA38A392BB98421A4F0731390C30A8701C1396A4C17CECE6CBCE99949D0279119E8790722B0E2C748348A8A5A7C760826BBC0D395313B893A796B9D572C10432B2F5363B9682A89D1174F822BFE38B05DDC5B68BA3AD62497C3AB8EA6D13B11A6A69DDB1F1340B41F013952DA1EE1E759D2D5459A01CECE819E5DE09B8D707C7D59519369660306C4174505A51846D5476D41D00393979293C1325A1B6673F16C32550529B21121E95F99F503CEA88530E2C72B038AA641327181673E301DDE28B0BA76B2B88453D1812499681CDDF932370C864BC6205B6CB13684455FCC5E008BCDC16597ED661B3732A60E329DF82820AF51B1BA4647A7944C4DCC7A8F1BCE390C44A9A7221E0C0943CB4FF6F048E2362F89F4113FD3636B97919E41ACF042189E02A83B580E5D4A996FEC6D6B7B33D690825F366D89F8952898152B3671685A22D8898BD62C83C32A1E3076AEEAE845900AB2CFAB51EA76C3022B52DC702D05B17A76609C88E69D12D7694EDC3E91420737B17BB6844A1A28C0C756038A8C6C6A74906232B50D74CF532B5266D32D01034C56AA898D624727E5363E0BB300203E792B3AFD39B5376998142ACF52F6933A594C9A5872AB619A8A4317E86A91D419A78D47245B1780BEF14ABEDB77CCB97D550AC223E5001E0B64A61B8FA0526331B409505A512B4B6BA7E3B4B630A112920B431292DB5962B577AF8D546B7465673A8641AB5807443085A9F0849B914A31393C1DAB0FA30B3B1C1261BDC9A8CA69CC0F0432E91C1D42B6A8346CB6FD9CB49B189D125C8BE422A690DC90ED4A87C70CA8E35CAA16A35A3120B9716BAE021C861267AEA4244219C60FB1C788CE8264C0241156340DAA3B1AE7725C6552CDADD4C244079CCE22AA083A1A2C0810FC7AC55D77BB6EF934FB73A8E8F4CC299B28C42C5D26F36518BA4CD3B320EC3158B8B36108BB6D4F6427DC46653EC24927A833853B4B0AF5723D8A3C5F37C17B3476D86161C57579CD020167A70C1C310325C6707FC82270F0C73D552363E2343B371FC1448B2770BFAE474707305A9B32A6AA77C7FC7715CB35826BFA1696D67EC48CC0C9554691D186DD025EAD64A9E39657BE0292F39829EF696D3584B99C7367A00034395252F2443EF4692C163A5FF1863BE79273A93192D10B661B9051D57572D5CAA817338C52374DDB282D4722B1EFAC7339F1CE852867E4BA2A4D368CCFA58FDA097FC59244FAE273AA7C63F891BBBCE875624800DCA2B5D65B5A2D414A81C7525583C0160A006BE08A68776223AA97525A1E97B241F59C0DACB50EC89B90BBD58E8F27C9F19729782B2C06BBB91725C3B6CA991E75BDC7850A0107674FABAB38E28AC5B9B717CA7542EBB563D078E4C856447A0AC85C9240D77210E4CE850570AB693ACA497819B5210E2CC957FA9B4542070171C56A2C1253E006CF12162E9168673A08D82B90812C8CB989394CA862AEDB1AD9885598D39A42B3AC25BC914FC15EDA2501D7C8C51ACA0C257CB8B0C16DE89900B2B12A875116CFC967553829E59510A00998440B93D8371A0B294AAB2B4697196D397A9CCEDBCB2F5414DC8C764189CBF720834327A9557CB44A90286277C54AA424D080822814626B753CB281B9F2FCA8680C2E197BAB18643C9B0AACF8445618A45814389466F67A5C557AECCABCF083CBDFF5569E39CAE20584EF46BB56456386F3C7EF5A5C196C51646B69154393BC7A6A6D0869E06C3F8ABABBD7AA070F974E682398508A356C78C74BE8108B42C6B53744C3742F16C84E5BC6750546739ACBADA819A2AF9C5BBAE2CA34F6215DF82C10AC8A5873A2A8C04CED887730988C14F00A33821994503F9E3555F790715414095F05BC7D5C20DD9313ACF98B10DAA4053C90F3D2C0DCC676DBA1CC0EC92427D4BBF61425935314494C3E65B266F16411A1250667954388FC5B750270E00A8BDE873D3D58C627C6B31D8610597174366C8052F21E429C185BBC4C080122B4B25D00A982101B4B44C18BAE64B7AAD2A2BF646E39BB241DF17D8C5B42DB08CA0D6571097250072420DDEA731357154E861809FCC1CEB7AD01D843EA928DCAD3C1370B6B517F5473B94BD6351E282F01BF82A24C3EF05658B9E66735007B45F5B008A7BD", + "sk" : "1783C5F7F498D7D8C421436701176E6349C025970F41744B369852A6C2CFABC9096F48706A702D3AE62D6A2C79E068143F45AE3D472180C432D6AC6897633982806C87526EE2F837DEA521FDC3C3A473A6D7405C2CDCBD1D99142D097EC5AC782CB80909B9C47B7A173922CCEB52C926F4B5C904C5F342C460356C72751BAF271A496BA3DED912E6810B8F498E78B194A02643B855AAB4A6C7DF2938A0DA001C461B52829CDA688AEA4C21CCC478C04923406ACF8A7B72F5B52CB091CA66D769FDCB2D2CF220C3EAA73DB7888CB37EBE441D81D0B53BF41259433922A1C6DF57062C2A010BC3C190E7C19157207D1B607EE33469334B3EE4500BDA58A1785B2C247410573D6D703D822149A5AB5A4E811516B69D76F3A80FE8B84FB8AC7F3568CFD69521036541E975E5C09F63905E571531984921F9C159CC2964541B0B55860270AC7795F0C26A3B9FBA603C26601322BA61AC86722B7933EDD01C68A292C783A56D55C0254439E936AF5B9970241C73A9244A271A43CFF187BAE40EF9CC6D47F23F3B68CB4AC08180537B16DAAA329345F17102BFF856891AC52E25BAE2E95EC2EBB21B9330067091CD7B0A963588E9700B89FC4EA40AA6C4A2C8B63568663B8C2EC9AC281AC3D470098F559F49966E01A91631F263B834A19AE5B3D6D150509815684C300CD483C3FC475B324C8873BF5CB01609B58BF573CCE0034B19425EDCA86C598AA4DA9BC4AD2CC78545917DF6962BA4CA06B0BBDB322FE300984E16B982773A0C1A1BBA55A14F575150484F2BE11CCDF97846A33AA8580C22AA647B7089A73831651C506045A05E785C1D682A0AF364B4CB1FD704B1C306523D6A7394AB1ABC34719A0C97F49CBE6CE9519F8B03556CC9C72C613E513AAA68074130456F2AC4775218F7A1C35EE07F229A7D59994F6B909C381A0385C2A6D1BC8D7A60A1A113442DE3CD785B7679230CA6D49D17F2C7FCFB1FC2E7121E20B87CAC2817E26854C392DBE25B31753DB9C5923879777364530C4551C28A3A5D83C9631008571C2F889889E8C835ECA3CE30E81C03CAB74B3B5B198458F0F81CDFD6CE88E7CB79F704C0159B83345232541CF4BA04A1C2C2A929C3687996D25AB65FD9A93CC6590846A861C5B72CE4640B47673E5A883D44162F914A318A163B5C33C37A6330F34B28B22AA639978598C3C6AC93D811C60D0330AB500D41F950E51C9FDE115619F022F9E88F7892BA41330018DA306F42BCBC8CACECABCDB0E5085BB687FC14C55BA8630DF92C3A2B7867E951F3AB12F8BA2417A70F766C60CDDC85A012B60E368F7C75A6102684EFB14D21961F2231C0394520EA813EEA69465A8A8582E89BEB3AABB9B42FBEE8BBD4900CA52247A322837D58C9C7B0A9E5D246178862253C7BAF2081D7C02367956A7A68554DEBAC141C634048053D602645A88549B94C95D907AC1C02058C66FD5B894222331952C4E214AB1331A3B2A83DCBD8C747431565026FFB231E9835961919C659F734C665636196AAAE827BBE2C30F736384F74CEC5CCC3DE622879F6AFD1A0C472509F9460B07E524BDC65CF605A36EE35CD6267403CD91B8AD8376C670C3BE6B4EA42C3CD46B275B9394DB41E0B389642461D443BA0163B7D7530243B911A64A27560E3956F18744A673606089FD611C9B5D4B6E9A5C0927632B259056D95235ED5A0490435127405CB164D8B0540BAD0B706A431FE077D2E385E4B64BEB3A8527C1921D119C6676BB4E59937E0600C07F0925D665A9B643E034478DEF83188F4CAA30764394A3FB0C3B9F4C2243B0A53F8B2CCC5D96EBB0478201CBC7E165FEFB565EA149BED831DF5DC4DF16531460A28C6E708A7686F61101D327A88F998223C9ABCC7D22B5EF78765E075AE4AA41730C3D507837080C4955614E88826EF4A8DCFFAB0BDE615673150A7F36EBAC7BB4C793DBD9A11F2E765BBFCBAE5D2AD2239AB9A2548EA20C47458B3A998533DF6B3900997770153C73955D200656314B90BD49D6D95407302A67813A62AB3B63D61B9A3195EFFCC87D6CA43CFF278BCC65EE0BB06C3DA296A117B3CC86C78E29C33748C0D293E243C25897B200F3B2D7A5B96215822D310805A35A331615C59172709BAA171D947D1B12E2C2699FB460B8219992FA09D529069C40138F24CB4CC9A64734C470128056A7B5D374435C099752EDCA129091770D6AF831AC7805A7DD5657BCBBCC9D751B140283A2EC533C17BA38A392BB98421A4F0731390C30A8701C1396A4C17CECE6CBCE99949D0279119E8790722B0E2C748348A8A5A7C760826BBC0D395313B893A796B9D572C10432B2F5363B9682A89D1174F822BFE38B05DDC5B68BA3AD62497C3AB8EA6D13B11A6A69DDB1F1340B41F013952DA1EE1E759D2D5459A01CECE819E5DE09B8D707C7D59519369660306C4174505A51846D5476D41D00393979293C1325A1B6673F16C32550529B21121E95F99F503CEA88530E2C72B038AA641327181673E301DDE28B0BA76B2B88453D1812499681CDDF932370C864BC6205B6CB13684455FCC5E008BCDC16597ED661B3732A60E329DF82820AF51B1BA4647A7944C4DCC7A8F1BCE390C44A9A7221E0C0943CB4FF6F048E2362F89F4113FD3636B97919E41ACF042189E02A83B580E5D4A996FEC6D6B7B33D690825F366D89F8952898152B3671685A22D8898BD62C83C32A1E3076AEEAE845900AB2CFAB51EA76C3022B52DC702D05B17A76609C88E69D12D7694EDC3E91420737B17BB6844A1A28C0C756038A8C6C6A74906232B50D74CF532B5266D32D01034C56AA898D624727E5363E0BB300203E792B3AFD39B5376998142ACF52F6933A594C9A5872AB619A8A4317E86A91D419A78D47245B1780BEF14ABEDB77CCB97D550AC223E5001E0B64A61B8FA0526331B409505A512B4B6BA7E3B4B630A112920B431292DB5962B577AF8D546B7465673A8641AB5807443085A9F0849B914A31393C1DAB0FA30B3B1C1261BDC9A8CA69CC0F0432E91C1D42B6A8346CB6FD9CB49B189D125C8BE422A690DC90ED4A87C70CA8E35CAA16A35A3120B9716BAE021C861267AEA4244219C60FB1C788CE8264C0241156340DAA3B1AE7725C6552CDADD4C244079CCE22AA083A1A2C0810FC7AC55D77BB6EF934FB73A8E8F4CC299B28C42C5D26F36518BA4CD3B320EC3158B8B36108BB6D4F6427DC46653EC24927A833853B4B0AF5723D8A3C5F37C17B3476D86161C57579CD020167A70C1C310325C6707FC82270F0C73D552363E2343B371FC1448B2770BFAE474707305A9B32A6AA77C7FC7715CB35826BFA1696D67EC48CC0C9554691D186DD025EAD64A9E39657BE0292F39829EF696D3584B99C7367A00034395252F2443EF4692C163A5FF1863BE79273A93192D10B661B9051D57572D5CAA817338C52374DDB282D4722B1EFAC7339F1CE852867E4BA2A4D368CCFA58FDA097FC59244FAE273AA7C63F891BBBCE875624800DCA2B5D65B5A2D414A81C7525583C0160A006BE08A68776223AA97525A1E97B241F59C0DACB50EC89B90BBD58E8F27C9F19729782B2C06BBB91725C3B6CA991E75BDC7850A0107674FABAB38E28AC5B9B717CA7542EBB563D078E4C856447A0AC85C9240D77210E4CE850570AB693ACA497819B5210E2CC957FA9B4542070171C56A2C1253E006CF12162E9168673A08D82B90812C8CB989394CA862AEDB1AD9885598D39A42B3AC25BC914FC15EDA2501D7C8C51ACA0C257CB8B0C16DE89900B2B12A875116CFC967553829E59510A00998440B93D8371A0B294AAB2B4697196D397A9CCEDBCB2F5414DC8C764189CBF720834327A9557CB44A90286277C54AA424D080822814626B753CB281B9F2FCA8680C2E197BAB18643C9B0AACF8445618A45814389466F67A5C557AECCABCF083CBDFF5569E39CAE20584EF46BB56456386F3C7EF5A5C196C51646B69154393BC7A6A6D0869E06C3F8ABABBD7AA070F974E682398508A356C78C74BE8108B42C6B53744C3742F16C84E5BC6750546739ACBADA819A2AF9C5BBAE2CA34F6215DF82C10AC8A5873A2A8C04CED887730988C14F00A33821994503F9E3555F790715414095F05BC7D5C20DD9313ACF98B10DAA4053C90F3D2C0DCC676DBA1CC0EC92427D4BBF61425935314494C3E65B266F16411A1250667954388FC5B750270E00A8BDE873D3D58C627C6B31D8610597174366C8052F21E429C185BBC4C080122B4B25D00A982101B4B44C18BAE64B7AAD2A2BF646E39BB241DF17D8C5B42DB08CA0D6571097250072420DDEA731357154E861809FCC1CEB7AD01D843EA928DCAD3C1370B6B517F5473B94BD6351E282F01BF82A24C3EF05658B9E66735007B45F5B008A7BD627D8E894A4FD9228571ECB1041A11F23220B1B83A46D7EC32691EC9BDCEAC14171EBB1A64C173B3D4D997C12F734D2D57FA2127052887DCC6461FCC23B66FEC", + "ek" : "432FDA5246F7E53F85F65687C29ED529F292AF7860BE819554A2D85EB175E17879EFC714E2564B16BCC2B5434479C82702A198F816ED39C4FB6D0236B645726D0F1327DFDC1930C851A62FC4F2B4362A3B6C4E10CA7A18C70D2BEA1F0EC31790F7E567ECDF7E9014A1C908CF5C4CCB14A19AC9ECFD1618F1FB3AD789228331F16205BA134912FF9F3894F030DA4FB282EB488DB69C89DD8D0F414DF39FD6095362EB8918B035D4D47E0963D1C50E8ACCAD5AF2F22CFA13DE374BDA2EE0A0EFE3DCAD76A5ECB6D5723AD8CF885E2207F71DC0325C38F6C1FCAD1C8AC46D611F8D0FDF8E2D1996C28E2392EC1646EC7364A07A0431632B03511B506D5AA8FC98688CD7FDD27477271C6CB23C10DBF7D3D2B46F9EE5B5325AB37BF9B8CCCF1E3A8B63BE4834D9F097ED778C79D44CEFAB762936F9BBAEBC8C3050C5F57C6389B5FC8AFE4A1862838761D95CE1495EE1BF1E4A6A3FE40957510C31D3C4E6811865704FAA19FD2713F4D9B56E04D686D06574E5147DFD128F7DC22167666939B7F7CC33974199ABE11E198B36AF2946ED313C9DB823731D36EE66FD75788407095533904A09C65392FBE82FC4D5EA5A1A96C3409F1E9F4F80EAAFFFC51E853A6A03E322BD25D6A33766E6F71FF1DE9BD186ACDDB7630FC77D4B7BB926F16086F378F5A5F3755524111C50253B47F7B453D64BA0B149814A2564B7574DBA6C6185D403E2B23B99BCB04C0EF850DFF2FADB798D0778350445D538A53E60D86F8FF9B69E2D48E509A27167A177219118F69ECA6289B8E20E0A6556101EE16A557FC00C912A765CD2535B252DD9A15C0A002F8201E1746740AEEF63E14FEBF2AC2B98AF6036BA4CFA7F80F2FBE4340628A358146505BA3B74A1B7689F2D7533E88400E800E31152F933D2D2BF192E0F7B2ECC1DA9A863091B2490EA2969E0873B251D623720D27D25033FCD8F083AEC2991C88617214D78BA3BBB02C47D74508D37CD99022300774E8F55BEF8DCEAE7235FDD36AB04446B624E7C002473B6D7BDB88DFD1F7F1564C099F8BE3F2A75A3A20BDDE414505296044777AB76F48599987DE82EA7909BB9506119D128D01D507EAEF2214FAC5C0EC626AB4A6EAE23D9D9708528620E39DAE188D1E137D7A8CE7BB6E9C7AF8B1DB0749037887182532B542E6EAF28DB90153C7744E777BA07F1BABA354DD12EDC453A2DB9D38F4983095C441EC87D0B5BFE330A6158A1E3CD24280925152157F0C1D7602F9F78240A98E4AFE3231EECF1B95DE462CB637BBD4717DE7E7C4A62CEFB4FF3E846A0661EE7788147D491D982D9484BFA78BA26D0A547ADC6C9314762161418D702E8C1A337984C17B60380E3F007FC9432ABC86228B92BC07521EBAC2038BBE3FEC80B66D6A2520D7D6D124508F2FDEC7FCDD49CE9ABE3312341760873F86BD322070ADD56C6D0116155D03F781BE5DE76704C26D72E2D5C7FEB2F8A1238BDBF36D8A98729FA80FC7124242F00AD69B04ED6D9D144E480B032683CC766AD6F67A15AA3CF31A00132B142643CCA94D6E47E05CE850163D95D73F7E29B64BE3CFF67F4C1B8B0E50E2E57D3CDF49B297ED62940226F4475DDE776C82B8B1787A7E7C101146E8A01EE752B8C04B4AFABFBB12235BACB9B54758040DA21570A1A0D514CC838264CBEFDBEDF3743D2C6FB4A3430D8C3AC516D773F9695CDCBEC5951457C72685E4FD3929096A5482853AA7DA1A73A971FD1A26996A88F0BBD0026D4157AF17395477555096B6A837761EF96E43E6D996AD6D516A20E5345A55AA1C5939E05275A2016C7BE33A067818A619DAA3D9E87AE1F0D4DA5AF03AE7520F4AFAB1004CB25606AD2ACD653398E03A10BE88FE1691621E73B48ADBE746DCC72B9368B85B739D3F520F4FED7B871BAE663A0E0D4F2A634A147B221FFDB4592F3E839107D634F59597C3FC79D10484364A3C8C59881067F009988B4ADC3452DCDE5506CE910BB0F40F8894F0134B8BA1D41B6958116827BE61287C19FC3FC5A2942EDB35D281BE0A98D4A105B46AACB540F2828FB1126F3AF4E6C87F06E4DBBA6160302C692A3FD4B7F37A830067239F275FFD81C2D5735A9B0C32F9E2370D1EEEE12096E350B0AB923F00C217B11626990BC5817E21F794B0F0029A9FC78710BE8537E0E8F0AB307A2F37A544D5603898A2947894E91DF7A6C1DF28825FB87B907BE03C9C6A7B2DD2C283223", + "k" : "790FB3AFCDA7E067DF34B65938DF1FB21C0FF38AE0F72E4E4268CEE40820B350", +}, +{ + "rngSeed" : "A28EAD0A08E7228AEFF602B16A1E752278B8ED1E91DAC67994F5ADC372E1D82F95CC390CD97AB9212275E0566C833FD8", + "pk" : "60C06A2DB222A10A620D78B129042477537AEF90B5F0F20A58B6005ED0234F3168EE927D726733C3221035F21DC2A95471FC5AFF57381741C9DDDA97273909EC4C68D4B2A22019CC2D58B0F40860CF429C20757C91269979A17E5D01AEDFC21D3706369C3294617628BB97C2655656301772007414AED6A9113CA543F9B027B2AAF0F122D1747A800A49DA48239ECA99FD4443566348A3F8142C6CA511E769CEE83D0513444E7778018211F3A683CEDA1BA2881A37F92586A54806858058B37AAD546D48B4A5F3E6289C237A041814C0531B27045B8716C1AB1566AE22BB1EEA845340791E2899020C8AC1D6724A0B8B432222B204B0B2AC55D924B4AFA5083426C716CA2DE71C99687748B56342ED726694BA5E63E42911F66F8F8B3111261EC39BB3DBCB9ED5C729B401A23AA26015D31BDF8C8301F61ABE695066ECCDEE028B11322AA437C26A785899817893CB321E0B72E7A7131410772799500A116F612838D7601F66F29567E8A0F0B7477114281DF703CA76326B8ABA041457004156854C1B81092FFA869EB46807E6A1108CEB06F65453800B72EBB4613E2C363B6190EAE29735D48E537A717E335C9F7B456C923C42A31B8F4B4DBBA96F59362743D516A01400B8F1B3EA71954F85B0CCFA751D3428FECC2663D509C8B9A211C011313B5CC8E8930B223D08C95E5EEB47127A4BC5482B0E871A758893E9B64BDF4162332B8DA6D7B29152A914F5C748A404FD865DC1224E0B64CF782B7C866833DC8773B20C6EB28AC57CF5166895CEE2E78D41F97B5EEA14400C1D329363915094BD5650377924C15C86EC833B0EA0B3E476AA91398C108A6E99E7AB64990513E061CA52756CF29238564CF0CAB366F8753ABA1FD3E9AB70621A0CF161B398C413A39280A268C1D28172D6501D313ED15284D12250E6B75704D1950BDC5AF1959BC3E93156346DD3B47450F758D3E9796CBA90598224740B33B239B97C45C696323A05CB15EA44CA4FD98EE589A2F5AA1D1EE00A476533D5BAA58027AACEEC151C9C5EDA23B14367B8BF7571E7C75D197A55ED3A349DE636BF84AD6D446E2C3BA5657C683622B136384BE3B89C7EBA095A89697B4C8ED9215D1E5544F3D957E51A86EFC098FBF272A6140A17530EF6E703F272792371B7C5E36A83C61C7EC18E6BFA7752C095639420968B91AEE627C3EC575D74B49FE13F2A216C711508A4AB1FE84A20BFB019AAE1B8B3C8750EDCBC30CB47AB0B567720421359A0C8C08295CCB705222141B74B8361004D9C484061AEF8C19DE9F8C809B90050F3345D65531070CD36D5B2E50047B97B61CDEA5C3B896DC0A22F6AC2A2585295AE0993BE023A498CBABD6B37D56C2F8DB63804D0CA52A169F5D003EFE695B6EAA2C530773CC4347D4B9E0E46A822A980A9F4C8900070C67437576C572160AC7B297BDD074C9EEC3A368297F0A34772B8292D0B7A29FAACCF7BAFD2DCC6999B0766D106E04A76BC9118B7875C187B1F8CBB00B3C882F3BC6BC65B294443610C65B19AA72F90C7086EC18F228C36D63808B0AA253052C1A44A6842568D82B43A994B5B6C69555A449FFD0C3959870F3B679E4643842083B20A40401C51898E138A092BA393BBACA9FC6F37F28D88560A7992C5B95C228B3388A622A6F2839DA96B121DDA0C75C0B36EF162BD7981EC294BA7F91A97B34C69BCA54C2B7E91548FA7C396F3D783255A79B3FC579CB62EED83B430C45377857190D06E5A26576D92AF1B79941F922BB234A68B21309DB9AEDE9765C78C486DA51E400CB46CB586C33C46DB9BA99B983B94815FC5B52B7FEABE42B4253DF9CBCA4037819A47F8541BD5747CCB34CA74158318664B243C81B85484BF050ED3AA81FF37725F29B962F901F5F44B4768CD9DB394FC7370D0CA72E1607F83A0CD82793EC3A23D3510AE6EF3375C3265DD8268B3F31BCEFA83F8E5AA3D1077CC62A8ED858E6ED4639447AA3D705A1DFC4CBE7C4B74D67183A5875D24552AE74E546AB15376AC54F0582F3A92A1E1075CFB682A16B6A46BA93F31165F32654838C9E14B46476465CFE45BEC653D2C0A1CEF96CF01E123F1A3116C93B1D5E54730DCC5F9D618B53A7917A71ABBCC312CACB170C10E454C41869717AFD8AA4A86113CEB654D582AF443A0B6A74173F963D99C8D44E5520AE278370855C0E9E01DF9B37D13E35124E6C2590E9A231A219C07EF6C", + "sk" : "214A365E155F2468311A972EAE496D188B7D7CE281B8DC49D326C2935829652B1A8E936030CCBEE7989DCD407DC74A5DA47B7387674310C37DA58C0B9474A7DC5A5F97763211B6208FF9B7AD343B0C0B58B5C3B2E95210A2844C6B013D5C3610F71006E8C806BC61A90071BDDDAB9DD214CFC9F6501F6570305B5F03C38FCDD9516E73B76F5B6BF2B7665C70C31D763A1721628F73490402C8A18CA4C8F42C8A95B81E0219FC0C66DB22763707C44E555924FA385AA212D4C643E6F51234728B47C37E67F2BC559C92B5A6248E9CBB8F197DBF4221E8FB938A4881C22841076C2C2CA6B5798B5991623160148A8DE9C4C7667FC4AB2D30B8917304011015400644079BE43F60F07B8501957A53A0ACC69520871013ACA31FD4B3BC246F5E300D8E84340927A645532B251945A9CA024892B0BAB4769F6C27F497206D1598259AA0F2D649D560C082B12CB1D851D757CC38E1ABD7A6C38A947B36E95579DA29A25765F2D85D5E5016E0C91D25C6A7CAC3CB4D504BF7046B7B32646CBAB6A3EB8FC1EA63016C0CDD74CF63B8C86B790660C94110E4C6119736AF99A75FFC2F98C7CB0AC653CB90CF69978E0859C610362B24B14C309476C53B5DD058C4075C59C2C753AA76B7E04520F2250319D41C6C6183921409908B6DF6FC8E7D17296A9A0826101BE7450AB3BABEA3C520B6735EA8D545949988BAA98F7A2684F3B3C62E058B398A21A5F5073177798D1C44EE5C94FFC564357718B7FA59E68610AAF8294EEB0619502CDA583F0A744D8A03BE0A6C9D6F756070DBBA4EF85AD8711BD691B489A3A23332A6E766C79EAB5644E42378BA05B9AB0EB6D790AE65C2DBE3620C26783B8A11FF59850EA182E6258B5232833B4538EAB3306023B2EB01B2EA157571791D0D37C6D79C2CAF1601528B6FC1600ED3DB72E4414822051B469B8B0E962D94C1672E318796E0CD17FC5DF12BC1E7F6B91C5A3449C16EFFEA06999BC5344C19B5D36466D18F5DBC56D7065A924B4F128639EE5ACC2E37C02C5332E2919C1BE01E799C27E18BBFB7404C6299B2335B6B410C4CF28474EB6CA8A4859F0A4A587FF6B356FC1C330041C72765FBDB1D2BB779AC384C53F77124FAA473716047D2159A3326798B0D38C0C77C4568D6450A0AABC9780AA2B3252CD3DA838094A867AB89E12C342953A3A0AB33BF6B27D4A0758C248DD9F2B0864C08D1083E32031283D979AD81709FE2466E7B15C7CC4429BB4D96B2733AEC85EEFAC633F626EDD8CC64114572608408D614E3C0A1473C046FC5405F46BD229B30659505094A312C170A0C21B33628A220A281637B3909D418268BCBBD746DF44C5E94DC5AE6DB45312B05F7C99985B3423755C17F9ACBD7D831F5C3AED7F33284745F09E0CBD0F4B841FB84FBB6CD190072773388A334CFBD05A45468CDAA249AB02C4394C264C276BE8CA164873C5D4E035B043C86D8A09D0AAA3E7F983A9CD3108F56BA545847ED27C29A1A84BB11310E556821181C4CB79B4ABBAF3C123053F9C92CA15F6C326E2FE67F24A20AE584BDFE763DB45AC37CA8A2239394CC86BA1AD976B7CB41B5304CF6EB23A5B8456470237731882BAC17BA241CEE78B740AB91A3B13B716634CD55C4FAF9C80DA43B43E13E770A90A9743F151958A267A8A6622BC57AA51EC356CA98034F836F6716840FF98DD190A6BB509D000211AC802C80BC3B28EC20C7407CB898980EF125B0FA34A88812550477DD267D37495930CBA3F9E43F920A42DDB34EB7B72801FCAD3000AADDB473210436E5110EFCF52791C9593607BFC6A440A8043CCDD9965099A200C7A4AA93944BF7AC55132EFC367AAA358EAB042A6BFA125E19759F469EE054147C58ADC98991CF92693708C75534A13E125B9A0540E423AA29059103C7708EDB1CF626A95E2AC9E34B9694325E9C9546E7FC566A013128C2AE932690447A552C2BAB21D249CC6590A1FB05AD0CB90EDB8B7074BD7D172B1977581CC0840F1A69CC0ABFBA1091927BA9CF7821AAE3295CECA3C20C018C3590C4151C0FD13958890195E761FB0C5BF8D1CAA0B57087997E8495C430373362A71DCF670E0B1108ADA374DFC08B57A0AB687A7D5B8172318C0E4FE868FD68A7DA773DCA08A71A49A4CA1B45EE3B223B785F2E6B0DD195CE79A1CB36751B60C06A2DB222A10A620D78B129042477537AEF90B5F0F20A58B6005ED0234F3168EE927D726733C3221035F21DC2A95471FC5AFF57381741C9DDDA97273909EC4C68D4B2A22019CC2D58B0F40860CF429C20757C91269979A17E5D01AEDFC21D3706369C3294617628BB97C2655656301772007414AED6A9113CA543F9B027B2AAF0F122D1747A800A49DA48239ECA99FD4443566348A3F8142C6CA511E769CEE83D0513444E7778018211F3A683CEDA1BA2881A37F92586A54806858058B37AAD546D48B4A5F3E6289C237A041814C0531B27045B8716C1AB1566AE22BB1EEA845340791E2899020C8AC1D6724A0B8B432222B204B0B2AC55D924B4AFA5083426C716CA2DE71C99687748B56342ED726694BA5E63E42911F66F8F8B3111261EC39BB3DBCB9ED5C729B401A23AA26015D31BDF8C8301F61ABE695066ECCDEE028B11322AA437C26A785899817893CB321E0B72E7A7131410772799500A116F612838D7601F66F29567E8A0F0B7477114281DF703CA76326B8ABA041457004156854C1B81092FFA869EB46807E6A1108CEB06F65453800B72EBB4613E2C363B6190EAE29735D48E537A717E335C9F7B456C923C42A31B8F4B4DBBA96F59362743D516A01400B8F1B3EA71954F85B0CCFA751D3428FECC2663D509C8B9A211C011313B5CC8E8930B223D08C95E5EEB47127A4BC5482B0E871A758893E9B64BDF4162332B8DA6D7B29152A914F5C748A404FD865DC1224E0B64CF782B7C866833DC8773B20C6EB28AC57CF5166895CEE2E78D41F97B5EEA14400C1D329363915094BD5650377924C15C86EC833B0EA0B3E476AA91398C108A6E99E7AB64990513E061CA52756CF29238564CF0CAB366F8753ABA1FD3E9AB70621A0CF161B398C413A39280A268C1D28172D6501D313ED15284D12250E6B75704D1950BDC5AF1959BC3E93156346DD3B47450F758D3E9796CBA90598224740B33B239B97C45C696323A05CB15EA44CA4FD98EE589A2F5AA1D1EE00A476533D5BAA58027AACEEC151C9C5EDA23B14367B8BF7571E7C75D197A55ED3A349DE636BF84AD6D446E2C3BA5657C683622B136384BE3B89C7EBA095A89697B4C8ED9215D1E5544F3D957E51A86EFC098FBF272A6140A17530EF6E703F272792371B7C5E36A83C61C7EC18E6BFA7752C095639420968B91AEE627C3EC575D74B49FE13F2A216C711508A4AB1FE84A20BFB019AAE1B8B3C8750EDCBC30CB47AB0B567720421359A0C8C08295CCB705222141B74B8361004D9C484061AEF8C19DE9F8C809B90050F3345D65531070CD36D5B2E50047B97B61CDEA5C3B896DC0A22F6AC2A2585295AE0993BE023A498CBABD6B37D56C2F8DB63804D0CA52A169F5D003EFE695B6EAA2C530773CC4347D4B9E0E46A822A980A9F4C8900070C67437576C572160AC7B297BDD074C9EEC3A368297F0A34772B8292D0B7A29FAACCF7BAFD2DCC6999B0766D106E04A76BC9118B7875C187B1F8CBB00B3C882F3BC6BC65B294443610C65B19AA72F90C7086EC18F228C36D63808B0AA253052C1A44A6842568D82B43A994B5B6C69555A449FFD0C3959870F3B679E4643842083B20A40401C51898E138A092BA393BBACA9FC6F37F28D88560A7992C5B95C228B3388A622A6F2839DA96B121DDA0C75C0B36EF162BD7981EC294BA7F91A97B34C69BCA54C2B7E91548FA7C396F3D783255A79B3FC579CB62EED83B430C45377857190D06E5A26576D92AF1B79941F922BB234A68B21309DB9AEDE9765C78C486DA51E400CB46CB586C33C46DB9BA99B983B94815FC5B52B7FEABE42B4253DF9CBCA4037819A47F8541BD5747CCB34CA74158318664B243C81B85484BF050ED3AA81FF37725F29B962F901F5F44B4768CD9DB394FC7370D0CA72E1607F83A0CD82793EC3A23D3510AE6EF3375C3265DD8268B3F31BCEFA83F8E5AA3D1077CC62A8ED858E6ED4639447AA3D705A1DFC4CBE7C4B74D67183A5875D24552AE74E546AB15376AC54F0582F3A92A1E1075CFB682A16B6A46BA93F31165F32654838C9E14B46476465CFE45BEC653D2C0A1CEF96CF01E123F1A3116C93B1D5E54730DCC5F9D618B53A7917A71ABBCC312CACB170C10E454C41869717AFD8AA4A86113CEB654D582AF443A0B6A74173F963D99C8D44E5520AE278370855C0E9E01DF9B37D13E35124E6C2590E9A231A219C07EF6C49CEC726E5BC6C6280269FB608E754D097AE818B16B386BC895AF3BB9F5F2A440B472C6DA19B790E6C9591EE625B42CA0FC04FD9F69D72CE4EFDB3B9ED8D9C29", + "ek" : "F2AF45B761629F4E06E105B9570A51BCA203A11027B2753E59FE974EDEFB50FDFCEF08D6AA9827404E2903AEEA6A8FBBC3649CD189CCB6CFB6C8BFE47EE9CB1CD11D3750534B9F1F72BBC376CC9C36406DD4C4BE3615C9AD7BCDC1CB57CE023859F7A471CFDFDBBC673F469940B5956EE61160F9FB28E84459E80E9433554B771B382E2A41DD1AC88C64570A199B21AFFF78D419C4C75D3A775AFE34B34052E67402CFB25EEEA0AC1DB8D5EACE4FFA71EC8E29F2DF0A35DD60126AD0E1AC0173C9024E33B162ADD1D808FE06124BC217EFE3C7930A7B68B80E86E34B81AF66AC4FF964D1413FB0DDF4392B584A94EAC44100A362B824A9FE37B0950EE28A9FA95AFFA431629911FDFC68B36181D320D799F6211895413CBD5240910A98A55C4472E5C63EC07D92AA9E0503DC6E0D25FB50B2CAB9EC8BD534FCC1952BAEB14109612E661174686D532CF0C95B63D9A85289F8CF3197AB0C184D1792D07D230F836BDD8A1F1598F171F48C005C9DA40C62361BE282D7E49B19ADE3AC8DA70707E1D16F8F72C1364B0C3F9790317BEC11F89520D9826217509B0BFDBA62E853E8CC21DB6CB3D9AFAA01CF92FDC202F7B0AC6642112A05FE18C6BE74257927573343CF1BBF4BE44B03D118719BD3FB3D072B777445A137DE96C041023A04569B436EBDDD3CE6E4D000D59304BDDBDC0B51DAB58036C9DB9AED9BA5AE8493AE2125747629BF4B2E0AFAB6F3A4977FE751871035829FEF5A436590E62169FA28C347B6177F23AC76C385F2FE420CE5F19F04DA4C88636AD47CB72B457C4F857D0BCE9A2392D7A5282A9B3355B4D0CE1CEDCFCC2AA92D8E266C4EF6BDFFB4D0E7FEAF6BF6B1AA334AACC82390DCAB12F6D4471171DDD88979793B091DE17DC2F4078F5162077060E38BDCA16ED96C278C1F4408C7E7B98D3FA9A51DAEE007CD074484D17B0348691B6E30C3F1D9266680E0DB274080CB26A4A4392AC6B62571D907043A2AE7F53B4AF6C8CCB10570F9559C31217882154B29F163052FB34F894411ED7C4012BDF5D6BF6D7883EF2F194650060081912B9E5CF5EC05E4503319F86A092E95E4C62FAA37CCA0AE7C294E449C66486A930C4D02853CD18EB3626D74B65CD75737FEDF7FED2B4A07E61DCBCA71987D3A871757AABD8FEF1385AB25D16B8CE3591D0B9428453149FE85A1612D5DBFD01AD8AED0C7FCB300C8C47F2C0E6251DFC84F2FF813A1F7E6C411BB8196E4E060C9E89DEFC20230367B7A19A553B53665F76305BC7FEDF4F07D98DD6CC8168187E7EBBB5F366692710C6DC0A2EF5121F43A62D1969E65919207FA563820305A9EB3FC3441550A11A901734171E469B01E53EF7B770AFF187CF824134E55437124C316B04DFA52A9D52492E544399582E2CE671AB15F24B0773AC717207608A1C76CD396C672D710F8759FF3BF04B21203224A339F7A7BDDBCEAA6474C35365F09E1F3E5531E3C724327F3391EB30F96CD3DC31180FDBBDB64C48BE8AD914F00DE6D4F6BD582D5F65F2E196F216A5141A85CD5F0A4E356A9B73D2653F74BCA41E3F9EC5B87CF40F9BB14C934D793CA903DBDEA4282EE2C92DEA722C27973B1DEDAC1E8222B4C5950198FBB4F21A6B18526FBB3BD64EFDD694395D29CAE54C6D76804EC60C155E636C6AC82799DEF8E5160D43D2799DAFECCA0638C4BFE768A7A762231338812E64C2D0CBBC7E6F49E4823FB016BC5EFA794C2AAA5F1899D3EFD36BDF15FFDC86BCFC210B637476391DE260BE89D87962F60D8101B329892B6A5832108A1F2261A0AFA40EC6B71562536A308BEF6E67A4005660A79B5F2DBEA6E5895291DD4471676551F183F5B4D0204E762111C84B1884F874F7FAFCB0B51417ACC2EF1CC563E528B35C0E602308FCFE7918F612835D3B9F787B8E4E1D6CDAB937741389A50FE286221CB76002D1699576BDEB2727D4E451537C76F73DCDB073FCBDD1F9EF6601A3DDF1389A81A46742178FF0EBCE78C6CD9D423DAC5214D48D8FDD8ACF9F8BE57FADF8D365706321E7EDEF0FCB680AD7BAB0D86427FB213075A15071C027285307E949000E69834DD2391AD361B962C9F1F496B1C79AF1D3DB78ADDA1AE3E50782F6C91AD902DC1F4F0173CCC5793836A58589EAABB1FBA6BCF9C9CF649C21A27E1F7295EC1C3BBB20B1E8688629965B1FA70D31760323CA17BEF409BBA8B1AC97A69CFCB692D024D5B", + "k" : "4CC1F19D829CDF7338800896B11A9BB598EC817BDEA59101E0D7B561C1A51E39", +}, +{ + "rngSeed" : "92877D706DAF88EF3412EB143DB8CD91BC047A9A43B7ACDAA42523560DEE4C172697BE4332042FCAB91135839BF74AB2", + "pk" : "C75C9083566B23ACC2E981457FAB1306B04340969DD1081F074A2A33BB85B892750BD34336A68362E00302712410EB8FC8F37DA6530A408B17FDDB0FD602C2E40A7DC4C94EA843226CA79B167B180F3024A273C57F91CD69629C970617720497C4308E10F03A038544FFF13A3AFB83FB2291DBF177A003B0197037A3C9283DE78DC911BEACF30E6C4C6740300266C6AB69893AA9E112B67903DF849A4BD59BA106030B62B61BC293FEF997A8851D06C956631C266AD533791124A4E09BDB06C0FFA681CF2C6D43670E2A017B9A40C13E85BC1C24AD914003AA69439D401BA605D013A2BAA0E0B010363574B71242745E9D709A3FF3B0A2AC7F374684BCE9BCF0200DB5A09B5D0C92CDC7BBFB3C24A79A8A4A0A9A64376A0793C1252362AF170856046471B1A60EB33F23C59122D0AAEDA79CAEF27DF971AC8764986CFB2617FC3BB71355A56867C29795F46668F8166970B06C6CA91D8651CCDCBC23FC1B2F0A75C45FB3321151953315036D52322C9B6408152BBB595129F41A8B8570F02B8CCBA66DE5FC36D892457673A9A096C556C9AFD11B06E1CA9CC8B3A9E9765E38E711D039612C4BB296061771E42EFD68C9ACC8CA61012F295251CCB33252E8B0E6486C5A5BC28683347571B8F0A42AEC4873CD3549324AB728324030196035B29AD3043AB9008DA6B924BD376CFB103FCBAB9450B44C299B4E27165303786944009418CBC66FD9A570468DD85AB652D86402501D61F5272CD880056521F72A362170580675BDDD505840378D96334A704282934527F70A499AE99DB81516B1D1426D233DCF9855880022D72100E14858C0A226325338B33AB5ECC5A86E0AC4E8504E168C5E1A4788177878BD569D49DC60B1484F43134E2BD39EFB207430AA564AB7A88CD40ECC00A10E4B6C663B61A6054323429C0722B2E4464EC0D43374234B4884BB8DDC0A28852600369635531FF943194CF91937B43AFD418F8F964CF9C9CC66988407BCC7B5247A2372980035C8F8357BC3DB948C0C4B391AB47636024DCB79F094C62CCB64893C0C45C1BC88CB00BA85248253606735547D424797B0BB302C5EB9631AC98060BC47341E69379BBA5B5E44980970C699187F62731F2B1A4BB4C7A33F8A20758335BC8A3C4C4C0900B3C2CFE35356A58AAE233B066466B34C814A4CB6B9F916581B0361E78A2971BBFC014A7476AB2F7C291BA688D5F75153C4AD7BA4C664A8002058C9EB195A3CA7AB70638BB114C3618BAC3AB383DBF292705A478A35C31F06A1823B545366CB6900C59C036B063727504A55C2AC940606C7BCC74643644BDE915D83C395023C8FBD069F9EC50E1FDBC8EDB0387AD1074B11BFDF220EDD7486082A4842D6C737C6A1ED5B98BB78CD6DE1153480B3BF095B04A7CBCCC19102964E34693A6E492FAE134C9D726E49532236018DC517BD94232D717A408AF43FD5C837A21CCA33ECC2A3859EAF8A74B63C36FA70168F241E2FF52F7197A615D04357A7ACCA269E47848375BAB1F82AC686903D44786D540A496E29642F71061EE76054B5AA6AE67CFA01704B386A657A6773B8509CC1B4E16BBB92CB204B5BC6638CC5DD868DB40358DCC4C258915D1E93771A12AA7CA4B3BCD854EA2A111C09AFBC60CC91F5ABD63CA5CCD11EF2C1B06A38925EB9A4BB569D8C4B859AD278CEB006A3D44328636809A31C377C58957AA5408B488445BF1FC4CA378C733E410E3814C4300850FFFB052DF767743468C6A91D81DC3C4C34B4B5A06DFAB7CB6A741C91107758859F2E1C2D06881612E05CD7444ABF23C104B6A068988FB794306E90AA1AD2CCF76482F0FA7067467DC105C27EA7192D0C6FC50B4042934E81876E121C6C295A5432219345BAB9CA566F0DFB6B9D4728AB7187F311BA22D55B4047B9B3A17632925EC31BB2322257DFEA3D1C1B4331467904EB2BC1F7A4369AAB9912531A6835358B016889AC910A7C398C18A1636976E04C7227CC9FE13D61A848EEB60D56635064BA07359730A0C269ED6CB25CA2908F524AE3C9BC860A062192421CDBA741DCA98F98AE0D955C78D141FEDB59BEE95957E035D5B05155F5792E88CE43342F410AC92EAA68CD055FE28C4A217B9C2DA4BA64D4A6605565D41A00ACF377EAF80881D9A5305766747CB076149866504DB6B96EE4CC9D4BB977165F0B04D3C03C1F8150A265215387C7983D37463A3136A1B7C6", + "sk" : "C73842B1F8A1F7CB343C570BFA701270595100A58798D235BAD4AE8AC7376607675DE7CDDAB1432F5B04FA1045AF5A2644FC431C604A2C794D57B1CCE958707E508C0FF80ECD5C001439456B65091BB75DAE518B9DD5A28FC8C549E4450ED9B92A6C77C5849836F52BAD941438672E06786CF16233FBBCCB192B5C07A9A2ECEBA39571778B665DF2B0C359206CBB34B33E215D1F8900BFC1BF6DFC69490257E2A533430A79522957D1677A19526A44E4BDAC44358CD283E60376B8026A0D389912324B1F37AB4283156A913782D26D7696827FD55A2D636AFC42173F86B03622091E489D55F74DB20C846B0C27E7C1C0EA8729B97CA5FFE5296FE180AA2A5728F7BEFC320BBAF64C0E5555B1F35BF9203EE22478127122AEEB4A3D983FEE5219DAD3B4DB5197AD079BE2803491238BBFC003E2E22E2FF98F0E0B2389C83C7A30A870E63AB54A094B27ADBF301526D04449B1283B02254AA2074A902E67B978C1BA92AD014C7A15C2F678BF3D1342FE588E4D7B8B674B9B92699D8B312FE0A64C0DA1A7D93C16F4917A96F03E3BB21E400B3141B17F90D58A853445EFD63E607CBB05036ED720C783F187AA897CD5282D64FC119DA7882BD28DBC42CCD3C1982E1AC0B4AA1497DCA5F764217A068ACB73AF404A5C8DAA35268484666199D7761B1A802F5334BD1BB4B05C5501BF1C4A1B23A35E3341E7623F181546FD2C069F63554A67C0D85A479123680849A17EC1890AB616DE357F16D14B3A75326E13CCECC690EB66AF0216921043C31A2C8A44688B670A060006AFDDC6CD13898DD97214F405A24EA5990E06B55C278CC66115F8655D4D8381EB55A0655655966B3F2CA433D3C78FE3A0AA0E6196CE4B355425AE81434C27E47B73CB6E024065FE2BBABEE99CCB8459E1EC8BF6703032330D402B2155765097F650681135A60C6FA2AA74CC1490DD22525A7A65AB853579026750BB5FBC645AB3C796BC798DCCF927663C9CE82134B9536A9EF38D54FC421F964D4C20CA8D5B9A5795BF1BB1C3857954D91C27140528FEF1C366EB41D78BBDC773B58B81420FF36DDEB3349375BF1A3933C7A865E2E16CBFEC0CD93567B09B18C6D2C9DAE2500C7B19E42C62326A279CD75CD7ACA7E9B08C08A81087012F75E278A281C9C482C149473CF5F8965ACC8DB1B74A205103A89686BFCC65D40576DAB5C33960069DB6C390138647B5301448627FD1BDBF68ABC6979A03F47651A13C098386C6551A89FB9EA39696A8182D390388B12070D4E378B70C13A4F6AF1FB860B7F1A42BD1C8373839432609032224CFEB9EE0814E5CA4B57AF39F84D53A4F9A7A311421C9DC7E411C102C207A34C2161C7099E9CC39D5908DED696ABE32A97B8A297C28B868792305490A691291F5E73CA8163E5B9A17E8D417B2F14AEB017A2757653B6B92AAA73AFF638CB5412F1508B9C7AAC9439787F2883043660AAC7294AEF5694C3294C1471DFC49BE531611EC7863FC4C2F58C7141418B285B209F6738E45D09F5956B44D6106ED04B59164287EFBAA28A63CD80C59636896104261C10CA8C2C8603FBA2B53C531CF7A8DA7E3ABADA81507487C28B9BB07477E0241C958584E6047BA1119783D62C4CAC3C4563C628A5503236C7A997377AD53B9A4BA153645933856671AACCA85D55ADA82C39D82280DE07100E1CACE49A6DD09C22F2C1DA1077B9DD437D55B0D7B6978446A19AB106CE18529608C2ED283C9806689B0624DCF10C6A8665948250AF74182D9023895A577C5EB880359A046CA7A15297B3BC3AD227972BA80061570A7C10BB26CD87F05736A492405B4267FDAAAAB8062A5B10BB65AC597D8C5A5E123A0F242AE2470C1F0D8829DD73FBECB53076AA093B73E68E35A3BB649CE4621BBDB7C95BC0DCF997B83C0A65BE2015A5465FC1273B599C7074220786C306F4717FA50936BB22417A2247DEA1AEF76895522CFA8B20CBD9C344047984E9B67985307E8F64A15813CEC89B8B004C1D61A884B327BADAC95A14A2D2AF1A7A5B5CA6E3722D150CB4BE7A376372BEB7A99DC94654F652780411A43E619C0643D266A8B1AAB982080B1B9AA52E007B1EB6B76B3147B14785652B5CD11586F6904CE3A9554F745947FF27E87E2C6ACC205D7689D908068608053387600C6AA9BA285738B9372C75C9083566B23ACC2E981457FAB1306B04340969DD1081F074A2A33BB85B892750BD34336A68362E00302712410EB8FC8F37DA6530A408B17FDDB0FD602C2E40A7DC4C94EA843226CA79B167B180F3024A273C57F91CD69629C970617720497C4308E10F03A038544FFF13A3AFB83FB2291DBF177A003B0197037A3C9283DE78DC911BEACF30E6C4C6740300266C6AB69893AA9E112B67903DF849A4BD59BA106030B62B61BC293FEF997A8851D06C956631C266AD533791124A4E09BDB06C0FFA681CF2C6D43670E2A017B9A40C13E85BC1C24AD914003AA69439D401BA605D013A2BAA0E0B010363574B71242745E9D709A3FF3B0A2AC7F374684BCE9BCF0200DB5A09B5D0C92CDC7BBFB3C24A79A8A4A0A9A64376A0793C1252362AF170856046471B1A60EB33F23C59122D0AAEDA79CAEF27DF971AC8764986CFB2617FC3BB71355A56867C29795F46668F8166970B06C6CA91D8651CCDCBC23FC1B2F0A75C45FB3321151953315036D52322C9B6408152BBB595129F41A8B8570F02B8CCBA66DE5FC36D892457673A9A096C556C9AFD11B06E1CA9CC8B3A9E9765E38E711D039612C4BB296061771E42EFD68C9ACC8CA61012F295251CCB33252E8B0E6486C5A5BC28683347571B8F0A42AEC4873CD3549324AB728324030196035B29AD3043AB9008DA6B924BD376CFB103FCBAB9450B44C299B4E27165303786944009418CBC66FD9A570468DD85AB652D86402501D61F5272CD880056521F72A362170580675BDDD505840378D96334A704282934527F70A499AE99DB81516B1D1426D233DCF9855880022D72100E14858C0A226325338B33AB5ECC5A86E0AC4E8504E168C5E1A4788177878BD569D49DC60B1484F43134E2BD39EFB207430AA564AB7A88CD40ECC00A10E4B6C663B61A6054323429C0722B2E4464EC0D43374234B4884BB8DDC0A28852600369635531FF943194CF91937B43AFD418F8F964CF9C9CC66988407BCC7B5247A2372980035C8F8357BC3DB948C0C4B391AB47636024DCB79F094C62CCB64893C0C45C1BC88CB00BA85248253606735547D424797B0BB302C5EB9631AC98060BC47341E69379BBA5B5E44980970C699187F62731F2B1A4BB4C7A33F8A20758335BC8A3C4C4C0900B3C2CFE35356A58AAE233B066466B34C814A4CB6B9F916581B0361E78A2971BBFC014A7476AB2F7C291BA688D5F75153C4AD7BA4C664A8002058C9EB195A3CA7AB70638BB114C3618BAC3AB383DBF292705A478A35C31F06A1823B545366CB6900C59C036B063727504A55C2AC940606C7BCC74643644BDE915D83C395023C8FBD069F9EC50E1FDBC8EDB0387AD1074B11BFDF220EDD7486082A4842D6C737C6A1ED5B98BB78CD6DE1153480B3BF095B04A7CBCCC19102964E34693A6E492FAE134C9D726E49532236018DC517BD94232D717A408AF43FD5C837A21CCA33ECC2A3859EAF8A74B63C36FA70168F241E2FF52F7197A615D04357A7ACCA269E47848375BAB1F82AC686903D44786D540A496E29642F71061EE76054B5AA6AE67CFA01704B386A657A6773B8509CC1B4E16BBB92CB204B5BC6638CC5DD868DB40358DCC4C258915D1E93771A12AA7CA4B3BCD854EA2A111C09AFBC60CC91F5ABD63CA5CCD11EF2C1B06A38925EB9A4BB569D8C4B859AD278CEB006A3D44328636809A31C377C58957AA5408B488445BF1FC4CA378C733E410E3814C4300850FFFB052DF767743468C6A91D81DC3C4C34B4B5A06DFAB7CB6A741C91107758859F2E1C2D06881612E05CD7444ABF23C104B6A068988FB794306E90AA1AD2CCF76482F0FA7067467DC105C27EA7192D0C6FC50B4042934E81876E121C6C295A5432219345BAB9CA566F0DFB6B9D4728AB7187F311BA22D55B4047B9B3A17632925EC31BB2322257DFEA3D1C1B4331467904EB2BC1F7A4369AAB9912531A6835358B016889AC910A7C398C18A1636976E04C7227CC9FE13D61A848EEB60D56635064BA07359730A0C269ED6CB25CA2908F524AE3C9BC860A062192421CDBA741DCA98F98AE0D955C78D141FEDB59BEE95957E035D5B05155F5792E88CE43342F410AC92EAA68CD055FE28C4A217B9C2DA4BA64D4A6605565D41A00ACF377EAF80881D9A5305766747CB076149866504DB6B96EE4CC9D4BB977165F0B04D3C03C1F8150A265215387C7983D37463A3136A1B7C694B79D85075E5A897A948EDCEAFC78B87B7FBB43B11F82831299A9EE660B3D4056DDB63A495D1AFA553A815CF751D711478A39E8D1AACA992796B619C84565CD", + "ek" : "FC0133CDC43A4A239E7A8D2148603256A25717E554FECC471A64ACCE118AE118352FCDE9AD7F4D00C6D08900930E4D7B238C606B43B9BB10E91E0911DB3AC726DAD5961D71499BB997574E0F6C2449A6C7CB0E5E176988155BFC106CC39EE1D89F426F8B4A02C265BB599BCE1D7CF797086B3F8FFBF74F758DCE16523007B25906CBA95CCAC12E719D0E33E1A210E2C12CEA592B4527C6E88896D04FEC59E87CD96340D408B43D8A4002BEE5570FA93E47B03A4CC22BBCFB2FB4CFE19EE69A9E8532EE9037B95094B444938DB6AB83AF230B7A54E22AA2B427F6E663AA3D3D3A83AE2618E177352D7D1051B618494E0413FC918FDFD8194E15E582F46D95E3DB5631B66AFE56A4562D8DC8A976286B09DF94437D5C9264DFC4098883F3A6D164EB30AAAE9F4790C2937E47DF78E2B266A941923BFFCA39B2F0A97D01F07D77598987D090508AF20429F4BA62CC8FAC1955F331520E44B5AC973E220C02CDD3B9F146B2AAAB2A8F663768A0E9520CC791F3A79C8F8FFC5E60E3EAA634B8BD3A5AD0D731E415B0C31BD4F197F3E14E2F5B0A6E3EF0EA9DE3C02EC9E46837755D8D7CBEFB4363A3A288D45ECCF42CCB144362B99D5C27F874806B5461BB405089110A23314F8ABCD072B062C004961AC8E9E00C03014D8B8464923745DA9FC75F39A6D389D64CD9654F9FEDC26C86DBD3C7193B4C745B9C050C163FD6EE901191ACA45BD4593B0CF31C9E67DAC6655820096FCA8DF998CF2451AF77C42F3C27207D310B61B82A05D787524C19A40CB042F7DEE3D590DE1B771AE2E395D5FE9015C8E80E4BB6CB69D61166C8FBF72B043C339B3DA8DDD01DC6EA9A5947D3C6F2B21D700C5B1D9177F35013E3879F9C8C0FF99870A51578498A7F62CFEE81D08AD80037698DCF65788B4E8A3F65C00D82F6AD90488CE1FD4C72F4CF86240AAB6798717284CEC77B20EC1C9C534DBCC9B399B89722473792884D4563CCFCF27FEA7ECCEECB0163862256DFABED3DF45DB7EA07FA459DB67BA60D6BE6F7034EE8383E2CBB5B0D230489FCFF091CA763DC0697783C6AA25806023F40BC8FBD2AD9FE682421FF996015D11D3BF7AC8E2C36EDA7C31AAF311BCDB19B67AE2D9F05C56A4BFBA368F6CA3709B058A4D1712065B8DA7A1995A47795FAC499D6D52E4458E4A614D2A2F2D517E08A1955A6EC945EDA933D2BC88655D704D7BA085A1435B770B89FA3743A83B02CB4FE9A570C67A29EABB5096F5B255BD91536C0507F2C7FF5A1DBAE1FDA4CEC659BED09BC188C1E66D3C3FCC6AF209D28F92CBB55343CBE353C9A8F3A69A4065A00A15D4E289F5D3835004E1FA01FA1E3F2A6E45CEBF49EAF9EEFC1BBA47FBA78D292BB635207B39F2FF270E864BA783C4F40A92EE657C7311C4363A743B9CF9C5C86FC0A2F542B6A541CAC5D3D105C0E041B83F07B18E57AA4D0A35AA5EBA6DEEDB1C50E04280784CEA3E130AC1EA251A77D5577BB53D7F592883D73CDA0D506E0B2D01F609D9BE352E9432998ED682979A1F4690AC851F728B33612982596A00D58CA95007C46CEA9068A01395A1F4CFA2B8547FCD8CBF748DDAEB7A2C0BA632F5E526B6B0796E656AFAAE0C99B5B6F521E891488CB09DBE3FEA7A9155CE70E8FD3EE30C3906DC5CF9EB1E6657B7B2D1078DE419EDCEB8F388772B43282805532E0CA8D0CBDD5A57FDE115910F42C87E29517393425091112F1A4EC0DD2A81A923C8C5EA501C63017CA534F2F7B5B37286B73A055E92A583914509B4E766089CD7A0055929987F7E7B67F683E993CAD6A8BB2A0655862F373D059EBC01CE8FA678EF625E5C0D8363F72A17BC75EDD9FE1E8D51913199BD85CFA864D598C8EDB576879288842C110D30848AFA8C81E9310F3CB241BB3DED7660405B27E5269110DD0DBA455CD53283CAE87F4ABD9FAEF0D24558E861927FDEC261DA09FA8C4DDAA3CDADFBEE6428400D73EE1F8F31D2C110151F2509C0D00C701D42EC867534E3D1272B50A151A59E49771E3F55DEED6AB057456A5D2D1FC71AEEDC8F4A5618B6258655AF8BEC5EB2B3026275D286D00E8B9FB66104935DB8F749AB65B6F78C80E01CD98F148C97091ADD0887ECF3F91EC6FC81386F57E09A5645215B28DB064C0F7829935C806A60267383488690C6E1919B3C8AA125879FCE721917852810F6A48C98B6437F5F24CE77D084C7125EF5A901BFA46E612D46AC5", + "k" : "640970DDDF9C6A83339AD7690B3D45B242E52A890CF6D21B9F55ED7662B0CB17", +}, +{ + "rngSeed" : "BB4C0082CA4044B1FF60B036C9B0E0495D58667156786C530BC69D949A13BFAFF53798E456423D7A0E162A60039367D7", + "pk" : "5586A5B224AAA6428374DA6BBED37B0F67C3B5352A5EC2BC072247D20C7E83D83EC162A3DD00B44C070577EBB614C97B06E15D7A41CCB6A45FB2205BB57BA4DAC40A12AC5F6BB522ED863DAF67379D230BADF71844256CFC596D28957BAE0C050B9182668857951A38628B83E2082659317FFDFA0E279644FED9877D6775E131682B998ADB000ACE652F13FB0B9AA57B9022B792BC4BAE5AB5F07372BCF131AB93523FF42E5A328FE465520BC57D62F222E0A3623AD8B034F164B1800926CA8A850277D0054F34B941E6388349A87EB853375055CAA0305309A06FC2016BA8A3C9BB06BBE7581946755E6C726E9767330D639AD4CA467FF670414A65EACBA93D2B33AA628F9EB2949054C82E62774CC13F013998CF29465E8B83DCE66928B2C9E1F4CEBBB91E2D8B2278879073411358910EF23C66C3115AF8CA4ED0B595C8A49AE8EB955A86A2549132CD65A2F6A44EECE7B43A40629EF172B068AAB1C2126FE058AD02183DEA6994ABC7DAA71414666C57B4C40A17781AC4784E6AB2ECBB8FB2101FA1530A00032B5D1B51B57AC1537076FAA54B3B9BBFD9DCAC565209CC681B73D5A3C7138156B258321C05A494345C9AA72197C9D3A9552E437E891C437BA16C00C76F0A6252C8E4CEBED86398957088596CE28C5880DB1B90306958C12A45B5A14E1B05C161C5A3AA78099154A557A58E6C2C7758653E3209EDB90110E40E037732A7E44D7A60736437C7A3E872C82B20478083B2592EA7418B75B002F1DA834DF8624F665DF2677E0AE98C62636F603BC1D796935A11BD18FB851E8076C7E4C58B41ABC71481608281EE4C572B612C08B8CADCD6B7DC83130F161EDB26B1335662A5161478EB5D5A8C61FAA175F54166EA2741D27C0496292380E93F6B77577B494C463C9CE8960BCEC25F43F198F0552DA73819BD7131CEC101FE6448F7BA3FB03637B351AF9E284DA6677B53B71FFDE41EE41518B18C39813A82CA041F2466321BA9531AD4B576CB8825978B565580D5F000B9A56A943C2CEDEC578F728785487ABC0A8F2D28AF8AA3237022125FAB084CD19565816D15F8BC6936959EEA23F8279C74946A8BA37D2EEC75622C4F911C24839B78CBC8812FA55E19E10EDE4931F5D16BBA8AA44943BF9720395A8B1328648B887B28A98423E4322A69A752D1D2121D447C2F05BC91E52635D06BB1E05DAAB02F02B6BA9EA8944D9344EF68C23AF10144B93A40C456DA0857ACDCACEBF1782D63A0648497C91916A50B3D0688800B968F1E2200FCEB4538F7520BECB0FB86368ADA208C0602E1BA5D2CA85DA8D36AB8782A80436D69F65622279D8145AA5ED9671A28699AC9990D738C3B67BA500A731CDA82965A01B4C16144383BFBF3334D159C31831F94301D6A0320A4C7A340AAB3A18825516B819A285DBB82A28F164091516C2519B9B534AB8D116CF61303DFA4091FAB8669A417A9862F90491D251277D4B7B0523B7C4E345EBB090E5EE581F1933E7168567A857DFAF916F7747550409889BCBFB7E32840537ECB7C050B18552FE5AABB6794B27505F3B721C0B96B738C844F816160D3C4349C4463F12D248A6605B52BB9F8B370E958DB55B9EE0663454104C47781E8E0A6ECEB2A2632ACF0082C4E1806C0927A25E7BA8F1A395F1A352E72CCF72093A9587299E5BC23933395836BCC97832360A992B040A7B67D4E2CAA3D227F60D4C8AE293070B1878C63C8E106267A8AC7BCC850DABB5904769FC487B4F417388CE6755058470A3A7FAE41B56F009B01C74AF2C0A7D252B30302A7B3585864C84C8AA4AC42E82B1AB44215191284799C40D5AC80079D30625DD09562E555167391A370FB6841A98FF2B85713B75FF58B984EFAA29393540FCB20E3C1CDB1887BE3A30FD3861D62999F2C376704983F969197C9165F19B498BC169966269E3AF2300847C908A4738C8655F476238FBA9BDB05C3E4F1C3AADC7432960603C36F759C69E4BA048C76561AB4831B40341ED5C05C7B8A853169F2D75713C97A883419457193B9889724D3A108C1C3D083404D93A25A98BABFE33D36FCCF4F6623B9E378FC5C731B0A20DF7B5C28A0C86C065017D37A65D89E8E127ACB630F4304739F19BB2A596BF950C996805F73D79EC0AA09DBB0561C3A3BDB13009F672B9F2C907C468D916C305D530FE5910A3C029A722A9E1E6048EF23454BB64B1C9EB2D1C1FB4C57", + "sk" : "29450B5491A0266AA9FD363954B83FFB586F34256D0CCC6436225516953BD1982AEE4224545ABEA8D68E9DD24B0F354F83978D0DE0C5639ACD6BD0A3C27289D20C9D55E56013ACA5DBB7045D748077F4B9BC967DC2259CC79AA29A5A7CBE66B9484CA649042EEE3B440BDB3F6475A02F61A85B2B373B91338940A2872213913AB6088B319D2B509AB46CD19AA454480D9560C0828A24B695CBB166471BD01A3BD406BBA004E0C21F969675BF0884ACA29F247C29F95097927490B5B3B72C30B59DDA7D2B6A54693A1AD6AC033794CD0941BE1C38998B488091A860A69C5E82248B5941851D8553F2159782DC7C2767C09B93671EC2C90684A4D3B27B6A88BE09C50EDC55B9291656177803461B4F312A6F4ABC5ED1C97A6384356C549E070200245C6E39EAC4267A77207293FED95FEF2C29F3D93D2F1C6A609C07A3B8624BBC8DA5C2538C25AFFEFB815CC0675D88BA2C7629618A8E47B98433ACB57C0B8E6499C44C311288C34D8566BECBAC15AFC9A5A3D7C49FF25892A7A758B77E7540AC9E61AB0128CF301769DC65BD83542EE4B287849C75D53102AE750148D0839425A4B10243656397C16B05A9591817F117E6923D63584EB5E2C84A922D9F89B554579F9C526E6AB612A096A22760040A564649244AB8DA3F066A4F0CD6906D83CA49EBAE1FC49B00A5C36776C6F0911222602F7F2799FC3018828415D7C2AC0B88116DBA3D0E1C62DA01365E32BD111709FB7C07CF905E0510B9DA4A61D7254D9A9C92CFAB5002926954781AE86B0D88660C94E6591188C629A39E2D1748F2B44EB0961C7A480768E63D0560B65702C4D782193B7C9A89807729A3CA0C5C737E15506FE79912B05F25767FC53B772E952B6B900EF2B535BEAB49B69C0B958A42FD47B28DBA99777291994598A64586CB86C8A98A12CC20322D2CB1A8819CAF36BBCC387265B57819E496CCA38B5C0B0B6F86C3B2D722D4EB3DB4D97BF5AA2FE0A212F8F9B14E39495ABB305A40C0C7EA77C315A2EED52FC31A75FE224BF08749AB8B7A5858860DD304F95608988ABACF00BC0DAA7F03B57BFED80503B366ADA238312A155D398E26491ABF1C5B10D22F8EE568D6F8867256684B0500D02A77070B8D54CB3504500A1935577CFB46113277933155D089C456D28F28AAAF0661A4A60486C4F7BA710253F753AF6D75CD7B265F3365B2213878BCE6C9F806C9DF532CE2A5A656D072E67238E0C74978395552EB88A0B9B49B3205C41B3027D40B198184C67A8D5D3303D25987E9598DE984A2F2EB69DA7B843C6277CA144C2CAC1BABE34F119ABEB5D6C1F6780D54CB511B2795A9118B4695749682CCE3625CF7E85A00B82F59AB33184C2F6B6559084A1550675F72795E6AD74B22D57B903678EC4BC07DA10A04B0C0CEB92A5E224661C9688E2A141D0C73AF528826F65A330CA36A0B220BCC8021BCC1FCD408FDEA0B2D709BFD368FDF1992F3D2841256647D2077F2A39C5770A11EF945823C55616CB00DF3ADAE6478CAEC0EA05171AEB86EEC42BB56C53CE27262A5DB7E9ACA343C036D8A7CA15CE23AB90312C8322E541773ACE463A03801C3C44A7AA39723F2092A6C86C3F0C7B316865B50A13B84485EBA71BDB2420BF351E21BA1B1169BF9414CDFE1235CB6024371450D9849CE8997E716BDB151119399884069BF964337DAC8291C47ABE351C914626CED0654E7A2CD65690E3FC67B3BE0AF7350C0D09AB978DA207DB5CC82902D6F3705F8B672384C0743D81A0DE0871AC4A7FBC7BF1224A2F6E2B1CFD90F37E75F61A17F7FC9AD14B35AC0F79E6567A0208C0BF049A624566204301CD2582510F1C19DE245B25394C8EA1405F7AFD7A325BAC60C93F700F77B258BA5B7177958FC8664E5E42D1600BBA29B63B17046881A28DDE4742DD7B8EF476F50186AB287A9F6C17321760A2332AF65F136CD675B63695BBCC86081A10365AABFC9008DB28B0123534ACC645F290805D8B9BDF0636934B0B955555476B7604850CA5B3350D20B9269A3898FD45B161B165248830BD952B92A4C12721B67D724336C327A46753DEA31A5C440F86C941660BC4E72BA51313D82842FF1E0175AA3C682A973F0861905FA9954770F83265F7F009474F118B081A24F9492D7D7408DF21D000087B9E8CB88D5437C59835586A5B224AAA6428374DA6BBED37B0F67C3B5352A5EC2BC072247D20C7E83D83EC162A3DD00B44C070577EBB614C97B06E15D7A41CCB6A45FB2205BB57BA4DAC40A12AC5F6BB522ED863DAF67379D230BADF71844256CFC596D28957BAE0C050B9182668857951A38628B83E2082659317FFDFA0E279644FED9877D6775E131682B998ADB000ACE652F13FB0B9AA57B9022B792BC4BAE5AB5F07372BCF131AB93523FF42E5A328FE465520BC57D62F222E0A3623AD8B034F164B1800926CA8A850277D0054F34B941E6388349A87EB853375055CAA0305309A06FC2016BA8A3C9BB06BBE7581946755E6C726E9767330D639AD4CA467FF670414A65EACBA93D2B33AA628F9EB2949054C82E62774CC13F013998CF29465E8B83DCE66928B2C9E1F4CEBBB91E2D8B2278879073411358910EF23C66C3115AF8CA4ED0B595C8A49AE8EB955A86A2549132CD65A2F6A44EECE7B43A40629EF172B068AAB1C2126FE058AD02183DEA6994ABC7DAA71414666C57B4C40A17781AC4784E6AB2ECBB8FB2101FA1530A00032B5D1B51B57AC1537076FAA54B3B9BBFD9DCAC565209CC681B73D5A3C7138156B258321C05A494345C9AA72197C9D3A9552E437E891C437BA16C00C76F0A6252C8E4CEBED86398957088596CE28C5880DB1B90306958C12A45B5A14E1B05C161C5A3AA78099154A557A58E6C2C7758653E3209EDB90110E40E037732A7E44D7A60736437C7A3E872C82B20478083B2592EA7418B75B002F1DA834DF8624F665DF2677E0AE98C62636F603BC1D796935A11BD18FB851E8076C7E4C58B41ABC71481608281EE4C572B612C08B8CADCD6B7DC83130F161EDB26B1335662A5161478EB5D5A8C61FAA175F54166EA2741D27C0496292380E93F6B77577B494C463C9CE8960BCEC25F43F198F0552DA73819BD7131CEC101FE6448F7BA3FB03637B351AF9E284DA6677B53B71FFDE41EE41518B18C39813A82CA041F2466321BA9531AD4B576CB8825978B565580D5F000B9A56A943C2CEDEC578F728785487ABC0A8F2D28AF8AA3237022125FAB084CD19565816D15F8BC6936959EEA23F8279C74946A8BA37D2EEC75622C4F911C24839B78CBC8812FA55E19E10EDE4931F5D16BBA8AA44943BF9720395A8B1328648B887B28A98423E4322A69A752D1D2121D447C2F05BC91E52635D06BB1E05DAAB02F02B6BA9EA8944D9344EF68C23AF10144B93A40C456DA0857ACDCACEBF1782D63A0648497C91916A50B3D0688800B968F1E2200FCEB4538F7520BECB0FB86368ADA208C0602E1BA5D2CA85DA8D36AB8782A80436D69F65622279D8145AA5ED9671A28699AC9990D738C3B67BA500A731CDA82965A01B4C16144383BFBF3334D159C31831F94301D6A0320A4C7A340AAB3A18825516B819A285DBB82A28F164091516C2519B9B534AB8D116CF61303DFA4091FAB8669A417A9862F90491D251277D4B7B0523B7C4E345EBB090E5EE581F1933E7168567A857DFAF916F7747550409889BCBFB7E32840537ECB7C050B18552FE5AABB6794B27505F3B721C0B96B738C844F816160D3C4349C4463F12D248A6605B52BB9F8B370E958DB55B9EE0663454104C47781E8E0A6ECEB2A2632ACF0082C4E1806C0927A25E7BA8F1A395F1A352E72CCF72093A9587299E5BC23933395836BCC97832360A992B040A7B67D4E2CAA3D227F60D4C8AE293070B1878C63C8E106267A8AC7BCC850DABB5904769FC487B4F417388CE6755058470A3A7FAE41B56F009B01C74AF2C0A7D252B30302A7B3585864C84C8AA4AC42E82B1AB44215191284799C40D5AC80079D30625DD09562E555167391A370FB6841A98FF2B85713B75FF58B984EFAA29393540FCB20E3C1CDB1887BE3A30FD3861D62999F2C376704983F969197C9165F19B498BC169966269E3AF2300847C908A4738C8655F476238FBA9BDB05C3E4F1C3AADC7432960603C36F759C69E4BA048C76561AB4831B40341ED5C05C7B8A853169F2D75713C97A883419457193B9889724D3A108C1C3D083404D93A25A98BABFE33D36FCCF4F6623B9E378FC5C731B0A20DF7B5C28A0C86C065017D37A65D89E8E127ACB630F4304739F19BB2A596BF950C996805F73D79EC0AA09DBB0561C3A3BDB13009F672B9F2C907C468D916C305D530FE5910A3C029A722A9E1E6048EF23454BB64B1C9EB2D1C1FB4C57D68F592A778A0B3BEDD71C5D4F75C2E46B6088CA12A0A5E9596D5999259F13FFD3698490455837FE52948613EE5FC2284F00B130C72334B1D8E68C7B09B2DE2E", + "ek" : "B0B584E4081BBDF90B7E083C690C8986A5AB7AF52515539A6A6C9E82591B7C02048AE24E0BF77061B3D2BF6871D1C5026165F1B3BD6063646F0C9B3A33E5E9B305E3A1346D4F7B1DF79B3187EFCC35FE9654FAB3020B6123614F05011EA58800B949B48B98F85EFBC26B50BAF6C3AE3A2A0E3F879C37C9D2A894120651EE14A9E363AB8580876AB2D5A809C69511C142B4D206199336E373D4AA6AB983131BD43BDA88F256985FEDB41B2C73D96438A58361C73E4163F87D6AAE09146955C940E57A709E26FED0DD5A7BE3937396BF0D908E6104E6F311F307AC153F57A20A2CF85B73A5B3A24A66F27098F4CF785335C396619B0DE93596EB707E2FC7C89AE7B9F79D14CC6D4D16B83D79146C2D83A8047545D531E8BEDDA99E0563FAD7D0FAF4C4AA0533BDB9FFD02A61F0E69A0A85425048F66B36EBF2565D8DFDD57A54E47831BCBECE6ED9A8A8AAD6B3DAAEFC4804FE4F479F22105A36CF2599266DBCEE85C0F9833FD025D27CA409C54350B7F8CD60BE3225BBF2A8BB34396DF8637DA38A4E722AE96FBFA895FE34C8B9862EED0491C93FE6F7384B9E3A9E8D2C2FF08E6C62EB2227E4D73918142930ED22925E4B301BEB6173DBF7DA1315E648149235F488F578522FE79F8D26D532A492F37690D11F716ADAB2D9E3580D4707306260A6C704EF8E5331E1B98651CF6FE79CAEA27446E32191064116BBEC30FA8891EC552E10A3194BA869DC334E2122BA4806715D44933E86B0CD150ED4CC66D182E3E7CCDBE80B2C3DD8A3434795020F66C1BBAA87E3684A91EED0CB1D36A951CD69E66643E973B79DFB5BABA21592E4C803FE76AE62EDDE4D9ADEBC185FFE918C50FCAAA7AA5EFE4C831FF2324AB2AFDE204370801CFEDF5F18C3099307D8948AF040024E5E5830F625A3BB1AB66D779D5A09E06A01CA072206F77A32C0263640FAB370F57A4471143EE0793810144C30C3441AA5123666808DEFA9326A70EEEF19A6DB9EF50331B56532786F5FDF0FCE496EE27A31C4AA652308BA8AD6ED81FDE645CF9FBD43D9DF3B355548A15FA0DC0D3BF52DE47E6B72E4393BC137A298B1723098658AD7B40768D9C8C8E0026CD69EF320A5BEA1E4CB0F92E9EA089CE1D36CF8916F92FFA5F12AC48F8C83DDBDC61E6CF5D26EB102559610770E3DF888647E96147BBDDA17172D1CAC9250AF39E25280AB17E7B6DE5E524C40891615C65C6FEA8AFA1D7019A2126BA8E5A0AB8CA950B6597845A9FA60330B29BCF99F3B6A8A488E8FE74A017FEB1E561A8D40301716B58F6C9F0A8F37ECC18E57F542E00F4F06A048464BD57D23B5D16FC68AC4769C0A710261C78774BA48138F7B953298CA1C59EEF499663FD654C603E0DE979196D9FBB4ECCF71F54A373569EDB11D4730C125EA6CBD28D753A1F7C94B73BCFDD52269CCBBC5F3C87C5F0C3E1E05A14FAFBABB58C67AA99044D20E6651E2B54639ADA3E9CAA7CA2AC9E020DEEDFCA3D76B2FF7D1E07CAEAFBD2F73A9EA33F5A160F735323C891B42DB8E574BC85ACE8E8D45E51AF10451DA072C9A1DAD75851FDC540794146379EFFE39A07E7F825C215236A4CAE6726EF70B685D774466A523BF4203ABBE9C18994118AD0D9E024EF9B23A1572E67E0ACFCF3F33FFC79BEE4CF1EB49B686A1B662C90B2036F4EFE1630F669F7FA90082FEE979B6D4508EDA741C0650B2970DC1AF199933E08D93FFD2AE0D34FE98B6252AE4B028A42441082ED8126896C4211CE6160183B162426A0B3A126E46F78DD6E671B338E8708D349879F0183329B7855F17231E578B62419203065C4C665F80F3CBF81374053CEC0976F01F11CB24443F545573AF8499AA535204B413BE82BCAB457D51B358F22AEBC6406B817654422093BAE9587A37D12EFA8F345D34BFC5DDA41F51A7869F2F5F3D6095105FC0CB86DA1E2F87090563D34743A5FC187FBF29A78442B56E07AF35FAE152CD2AE124097EDB42AAE9E82994EDF59A8E1539F5E40978D0CDE4A52A56CA7D90CA1150105393E18C4210E7B9133E0C0FC568E7CC2277E8EDDA872DB3A5AFABA86A52EE8DCB4072968796DC7DD888ACF1D28203903BB8B9034621BB81CEE3D3468FDB6489D3087C3239F1F6258F9A29E4C3F6BAD0EB51F1750E97AE7FB4E64999E3A00C2CA945A6FF1882A260EDE6A17C52BAB6826B47B797BFEE8049970548E8180411A6892DE1E68B8A4C8E6AE2", + "k" : "554062F1F8BA9D665EC53EBDA5DE762E714F7C2F1E3B97850B2FE7DA68FD161E", +}, +{ + "rngSeed" : "121D90E70AF6204445D0DEB28AC0C108262719E9FD3476ACA74BBFDE89FAF04D8D5F89A624E8A75DB80431F0D10AD28F", + "pk" : "56180D96474D83A849634866A5CB0E6E00B8CB964067060DF339CB2EA05FBC6021057978FF3BAF47CCCA15D90147473E8BAB23693B6B70872B27B4A4C0730C5374A260E7CBBE9A094AB50E6FAB80C32875C2032A5EAA8F2347C313409CA19302A0437CDEA621DA1CA0082157EA362EF7907FDC5826F067AC4A4A1E4B997D240C7D3DF9AE6DB528159402D1943FAD6743E6E18B345CA2C0494D9BC956888AC85C021153B65388F04C456608E41361A6D3525A1143F610C21B2A9A7F5A2E1A461552904E341AB427028E567741D9906982E4B563D980B68871EEF012F2C3639A244CD300CD0030BCF4A2B1DB5101C1D66EE28BC3BC276B7E9922D0253904F30BB676777A36A897D35D381292915A82F9B2B7705380277916E16A137030198032B865C823E80A58C12AB39639488D65B0C80A391102CBCB4811911C60F618323C13A0E967BAC6561483026C32348502927F70CB2F780BB571F861CDD5394296436E37737A8AC6CBDC42A0F9B96941907BE3ABB5E7740E193D590C862130283F0711665A85FFF5158C968578781A7B766CEAD81633B6A2560B0A740752D83253A04C7F17B90B63860C19F38B78866EDBB79482D8AF6CB858C8A38FCF1C423F10CBBD9131ED87116B611A75BC109EE57EEACB6B2E1201E488C785B87F384C86587844A921701205979C1BA17DBC1519DC0908C656D7734A5A354E05606ACF7901F0C7590E3A324C30A905B2462DA7CFE478A4697601618BC74070A9E30707219C53B48C14C01A8FC745098A27B799868166C26F51A12A9A24C9FAA336F92692C141961BA4444DCBA2A370A63F533F87CA2B1B9537987B7B71043D5FD090300A7D4673A38CB781F833897E94955BBA19D428CB7F71710E98901B3597467795A84487BCC5A1180482FEA1205A0A854481719C12B11054AD3C85175A04C27011C29C387D0E571084F625A6F73CB5986945CCCAAAAC7D9EAA305C31535877CADF213D5BD25801438717DBB5051532F5F135F2F79FBD093864439507446B36F349CE4748FE614463917864EB90F3F36742F026ECF32E82F1CB90017099EC78380B5ACA2C7E82657557EB66C2FB633ACA3D99962EF8927A3F3C9D8DA538B89525310664DC2889410465E90B4D078C7DC8F030729555756C807FE228623A37A2B248BA55516CACA65256BBFFAA6CF6457DBA32336A71221659358F955416074AD0131DC4D186BCCA317D193A91D12900C477A00490CC464A119214DF01882576B41AD7B6F29B34DBB3B03A5C77B2D4162D985530C908B186B7E168C2AD69830302283CCA078F5816A9C79ADD9BBBCA9B3FEE02447DCA3CCB82BAC0CCC385538208E49742DA9616A28BB3C20568838DE02140EEE3A7E5A94A82563A90720C62BA2F32F05DDEA552F565B4E2597B17C3B8C24168D4484DEFF79A25B82EE1253049E619829508B01A7891A10DB5C5A532F4880C169A38C7A0C99715A2A696BF66B678A0349EF02C7002A5E5EC3DB2C3647B960FE9A343B540069A6C228E024719E269853535F5E841F78922DD85C3052188A2DB0B2A453B5119311747386352A437D0A0E2FA474AEC0BDF1090EC169CF473B9CD153C2131B2E7E001D3525957A487A38C726D710A6BF6A1F0027432C53A56A96C3A1A100EA69103FBCCA441A3F43002DD47714D397F7A3A02D0137A0DC060EA0669530161C67334B8965FABA455B81A6DCB37C8D2BA97C9496C3E3BC984C44A7B2611B51794EE2347CC489C07B4A89E8C5C620221B9C98C08EB5B245819A92CADEB684B82757E00039079E550A7C7A14BC856E0D347D28861921277BF18932183CB9C40CB07D67202A7838B500DF71B1EBAA87202A0943D982AEDF41260B38C67E25173DBC67BE8B33D10724B08611857C13870BFF8C0324ACB67F498B599DB59515CA863BB1016E87D07B747EFE8C903F50B3F7468053587555163E7F5165740204B78CCF2BB11DC32AD1CEA844073B7D4667FB55B93BDB4A708DB296F3BBBC511119DB4479737578859075C320E55B0A5185552CB9426A69B0BD11B4DFF716D5CC208E3FB46C3C4456CD63EF1D598BD675D55B1ADC177790DA6509DEA49AA958D2CE9A9E6ECB19FE96548A88F7B489433147DDE00139007B6BDCA9B3C6C0EFF0A1832C10A257599FA50200B167829BB34EE72551BBF3A650C7A34AE6ED516D401D89486D438A0515A537077561EC79E1A3963AB", + "sk" : "38D11A53967017A25D6522C539D05BB58667841B27C88C5F684597C79950739B4B3E15976BDB84DE829FAB2A74E888A65A336B5CF51E57C3C86E6CAA9D9A4E7EAA69F9B53A719031A0D078F2257522BC083184BFFC57790BA35CAC0333F26925E87696C7749CC1129BF1D411FBEA5049FA56231217FE9C073E59CD389C7B8FB0240F568DC815459AD132B932956288C3D93AA36D1627EBF1947C707A7F19C9D637B4D4A712E9B61444604EA1711CF08A91BA112087143B8893ABC4DB933FE973C65CB1C6512519B38E7385A1596407DD4850AAEA36F9D4CC75542E96578B7230BD775040D6C03EF4B5B79406063C75B863A51488D395C33262A62268C1D11D53B315820B5190A94C8792AA24F651964061ACA4212F452E7566B21418A9C7D84075F609E7456F069C105CB41ED9F638FA417E73F55F4C01BB553C085B3740A3BCCD2CB76FE56B1F1B4892B762C2AD3C6EAE082531B5B50E265CE5E104E8479087639368C091D2E2087A10B5D5F92CADBA3C1B540BBF7945D9D04982AC5BBAA342AC5817B3A982E98A5E99A249555205D827B5E3348B31DC34AF06B84DD52BC6D771ACDB3B77A41AAA951B7FA5261D56BAD24932531C35820943B0B2984AFBCA41506C4B3481F8817C285136C7185D8AA4A22F48920719B4D525BA81381142E8B178A0019313BEA431C7ECDC7AEC54662F591BE66B74D85070C68817BC01C50E248B347C6EB3A97A70DA43F51ACA3DF1CBE1316F93C50F4D02424578C6D274074E13ACCC57BBB8222D87DB597E6C880CD794A94597FAA10FB4F901208244C788AFAF18502E3B7FEC113510470D39DB48352A7331B24A3EE15F986364A0E42AAC36BD6A82B78B803571F632A0A49E6A871A9EC17DCCA396C1D57A49EC5B46A981F6BA316F181721B40F17266120C0BF64A9A1D9116E2F104A0728BDFD54570DA246C512C102D964C3C8432839900FF26910992309AA78AEDA610CDA4CF12AABD3DC7A96B1C26337C1E2FC858DB6BE45321DE76ACA80E417C7410283634B3E613D6594B8748917B60333A1268E6F943746377CA9C5AB428A0B6F37B844C25A8B0BC52E25CDECA953E089B9D787A738911CB6F209BC3B85C415B1D0A3630115AA496227A5D9BBE4A67FF05C2C8AB29090F52A9AD33A06DCBCFF047244E170A9FB9FA7298B06313B80D4B1CA0A61D1531EFFEC12C77405E188053FC0AA1A0329BF1139CFAAA86341004A4A11C461A5AB38036FD777AFEC0FC8965EF19144F0F81E40065FB23986DAE3569DBB5FEAA79B4C867BE5A536DC9379D0365B00E91DE1AB9A9701011CEC0721C2905EA049FC221F39A7A80AA11114E69E7BCB3822B3C61A46386C1994141918ECD7068370BA638770FD2831DC758496056D15A82C6E0196C152592A216749EB02D2099309573FB9298E6D1CBDA57898CA8788EFD280934B4B60E40584C365633BC7FD091DB45A644936BE33953D4675C2FBD270ECB82B3E550D2DF36EB5D11F7F6726D722861468CC2E830A11C419646C28E4C0BEDC9627A0CC83AB9B9D4E3B320CDB18C4165C3B32AE61A05AA0869778A51DF37B9C125045C6899724152C7BA7A6536B3D9E92AC2C63C29189813F55B5919861F38CB6D30845CE353DD0E199503785ED6B43AB60C0B6233B64265C7A794CA19838776A65EE97935CD4A63862299297C15B6A17BB91CF0AD393972B867FB11DC1E24EC7E205A42925AD337874B3263A7008E6487ED08C14A8B7A973F6A340F2AF81FA76691C6343577E8B83399EC1A356B78D1E92CCBFA54CB79A3110411EE82161578C6A07D5746734710EE8A65F69780C16BF600737BE4B48C7C977CDC2A3A6769301328F7AE7238F297F16A897CB3B768401544B974007C64BE131B45D454A24A21AF8440792631D78FB3AC527112DA6222AB0AE47490C8247C847B5AA9700C05F7ABF8F084CDF97C2BBC11414AAB6AE26A276145CAB441240808D1C3069847BA4A288A01822C9AAE799DC44328A749042AC06A39130C513235F2567A34B52858199FE59758328010CCB7D8DE311220335B4A555342633E5EA60B0B599E483787D2417790282011A0B34D13151A02581D939423C364A0A348F81412D07738299CC7BD12D41D1642D3B861C661338A3568A956EC7A4B5D855733626B5164C8C2EF2A56897A656180D96474D83A849634866A5CB0E6E00B8CB964067060DF339CB2EA05FBC6021057978FF3BAF47CCCA15D90147473E8BAB23693B6B70872B27B4A4C0730C5374A260E7CBBE9A094AB50E6FAB80C32875C2032A5EAA8F2347C313409CA19302A0437CDEA621DA1CA0082157EA362EF7907FDC5826F067AC4A4A1E4B997D240C7D3DF9AE6DB528159402D1943FAD6743E6E18B345CA2C0494D9BC956888AC85C021153B65388F04C456608E41361A6D3525A1143F610C21B2A9A7F5A2E1A461552904E341AB427028E567741D9906982E4B563D980B68871EEF012F2C3639A244CD300CD0030BCF4A2B1DB5101C1D66EE28BC3BC276B7E9922D0253904F30BB676777A36A897D35D381292915A82F9B2B7705380277916E16A137030198032B865C823E80A58C12AB39639488D65B0C80A391102CBCB4811911C60F618323C13A0E967BAC6561483026C32348502927F70CB2F780BB571F861CDD5394296436E37737A8AC6CBDC42A0F9B96941907BE3ABB5E7740E193D590C862130283F0711665A85FFF5158C968578781A7B766CEAD81633B6A2560B0A740752D83253A04C7F17B90B63860C19F38B78866EDBB79482D8AF6CB858C8A38FCF1C423F10CBBD9131ED87116B611A75BC109EE57EEACB6B2E1201E488C785B87F384C86587844A921701205979C1BA17DBC1519DC0908C656D7734A5A354E05606ACF7901F0C7590E3A324C30A905B2462DA7CFE478A4697601618BC74070A9E30707219C53B48C14C01A8FC745098A27B799868166C26F51A12A9A24C9FAA336F92692C141961BA4444DCBA2A370A63F533F87CA2B1B9537987B7B71043D5FD090300A7D4673A38CB781F833897E94955BBA19D428CB7F71710E98901B3597467795A84487BCC5A1180482FEA1205A0A854481719C12B11054AD3C85175A04C27011C29C387D0E571084F625A6F73CB5986945CCCAAAAC7D9EAA305C31535877CADF213D5BD25801438717DBB5051532F5F135F2F79FBD093864439507446B36F349CE4748FE614463917864EB90F3F36742F026ECF32E82F1CB90017099EC78380B5ACA2C7E82657557EB66C2FB633ACA3D99962EF8927A3F3C9D8DA538B89525310664DC2889410465E90B4D078C7DC8F030729555756C807FE228623A37A2B248BA55516CACA65256BBFFAA6CF6457DBA32336A71221659358F955416074AD0131DC4D186BCCA317D193A91D12900C477A00490CC464A119214DF01882576B41AD7B6F29B34DBB3B03A5C77B2D4162D985530C908B186B7E168C2AD69830302283CCA078F5816A9C79ADD9BBBCA9B3FEE02447DCA3CCB82BAC0CCC385538208E49742DA9616A28BB3C20568838DE02140EEE3A7E5A94A82563A90720C62BA2F32F05DDEA552F565B4E2597B17C3B8C24168D4484DEFF79A25B82EE1253049E619829508B01A7891A10DB5C5A532F4880C169A38C7A0C99715A2A696BF66B678A0349EF02C7002A5E5EC3DB2C3647B960FE9A343B540069A6C228E024719E269853535F5E841F78922DD85C3052188A2DB0B2A453B5119311747386352A437D0A0E2FA474AEC0BDF1090EC169CF473B9CD153C2131B2E7E001D3525957A487A38C726D710A6BF6A1F0027432C53A56A96C3A1A100EA69103FBCCA441A3F43002DD47714D397F7A3A02D0137A0DC060EA0669530161C67334B8965FABA455B81A6DCB37C8D2BA97C9496C3E3BC984C44A7B2611B51794EE2347CC489C07B4A89E8C5C620221B9C98C08EB5B245819A92CADEB684B82757E00039079E550A7C7A14BC856E0D347D28861921277BF18932183CB9C40CB07D67202A7838B500DF71B1EBAA87202A0943D982AEDF41260B38C67E25173DBC67BE8B33D10724B08611857C13870BFF8C0324ACB67F498B599DB59515CA863BB1016E87D07B747EFE8C903F50B3F7468053587555163E7F5165740204B78CCF2BB11DC32AD1CEA844073B7D4667FB55B93BDB4A708DB296F3BBBC511119DB4479737578859075C320E55B0A5185552CB9426A69B0BD11B4DFF716D5CC208E3FB46C3C4456CD63EF1D598BD675D55B1ADC177790DA6509DEA49AA958D2CE9A9E6ECB19FE96548A88F7B489433147DDE00139007B6BDCA9B3C6C0EFF0A1832C10A257599FA50200B167829BB34EE72551BBF3A650C7A34AE6ED516D401D89486D438A0515A537077561EC79E1A3963AB873D11D816550A4C1B14B584703531DD7CF0D97269125DBEF3D73E443D017F57229EF54E776C02586F3F46D723E7932215FB7E09C397D1552CDFE3457241FC30", + "ek" : "F86FA55E5727870103B48FFE34E1FDD7B76312174F91602D30BA6A6AE5635795E05EC7D923A4424F9BB66C3B8C87E47164CF23397167ADD60272ECC9528B681F7DF3871DBE7161812730470594FE341CD868F40C7C3A230389C1F37FAE4D30D47D9EB0FBB26FADDCDD1B3A5EC2C3CDB9FA83EEF0A8D0983A543436735AEDB9025D488EB67D4992F4005D9195C21543765F2C598FF3A1BA86A47EA49ADB3B2CF82FA76ED9882576215440C378DA885FA8BBF34A48D30E1DBF1B9E4A3074E37DE47727EB76D58151461AA6CC9CF1AA6E341EFA7E924D8F14BBA9ADD66C72CC3210EFE0DD10C1290A886709A2D8646CC794CFA13DDA5C6F399FE5669C299155D6229A8EC9D9D4257E643E1D1E1A9C4D3955DC2946749D6849251FCB69F389A651EC274C567E90D01BFBDDAAC9AAA6E115817030048AC481AFAA23BB7DC9BEBB644A7E58287C1F8196FC5E8DBF16123AE8A8B0BD9B5E09E82617B32B48E6BB64F4D794B7B9CBEDDE87736B6754EC799F9745D833C24C3624B761E225D69D973D9AAC93D47F05888A9384D824F49AA583A66C406A048598C6A3473B0CFC77CC42B212E8069CD41225006D9BD9A3667AE85A6E2CF368AC98970DCBF777A6280AA195C215ACD910F40AF85929FFF656575C31F5282DB3819E65FB17F720DEE66DC669C36FF01EC3924C9A925AA3F106EE155124D1BE87C2109E0D6265F14066AF447011B686AD89469420B5C7CDEB441A9A32E59BC39265F004AD602A647A8FFE47E437E7E0F0D7851EE3636E71E6A69832315C97BAAAD7E45C0FBCCC1086149F9211908E9DDC4EB8E23F23CF9ABA8DBD57F5A63D595E978E3F401EE96A067C9149436759D5348DA5B308680C60D5DA4A85B91227B1853AEA84F4819819DD1C2BBF3C039A1B415FFA341B445F0B096CA49EF4499A944D7FC1BE840290984613E8F8DBF7816A20401AAF92A236F8E4F58490E12CB73A88C88D0954C8A1306CA12C5BA273300274B7627F227FF0BA13ABCA04F611EF6C14350E5B0601281C0ED01DF40485EED659E2C6E8191EB15DE87A7265E86DDA57789C979B006B2A098167195501FC9FDBFDBC7B812EB558EACBBF37192071D3B0A41480C6E40538B3AD0B45FE64FAB8A058A59B3579AD62EB7945F39F071C5ACCE8ACB0D65138E1C10FF6BCD0992F53FD733FC5A15B6D40906CD785DC26327720F71719DA91F71150FF30FAFD8725780FE7568D575A5C52CA193A8A9674C3A8F5FBB288636BBD8DCD1649D9C67D1003B75D79D9D7A97ACE4B51E5D590FC05E2B98FAAB6474A96CBA189870E009C78B600C1448E9D69A71B4E836C84E3A92252409D7E0903F5043C22184001F224EC27309AC5561A6C4136AFCEF90D2F31350E0F74F6F7758B58644A320B8642CC7580D2A676079B1F29A19DB8343250D39FE0DE68DE26CE00DB65A3271EE96DF51A7CE35B907AA83B9470C04820F0930CCC1AFB35CC8AD1AFB75783F613371185BD78D3A889C5267129A029F176271526697D88B2ADD3E064490B593A96BB7769BE664716B190BE33AF7440A9702A8374EE3018D6FB2B767663AE6ADB52B13C7B0DB0CA76F040595E915BCA8300CF9D5860AF2F729CE8F5511BF7445AC10D8359DA6D2C29B5B1D3334740BC4A8EF953D198BDCD63CF63EEC96FEA38674696819C5EDF83FF5CE0AC16D71C1085337F8F06CACD72BCFFC13FD6A378C1D48F389F4C11E0BF15E39CC50FE5F22895AF589C10846454E042D0336829542CC8C07CF54D8E1D9F399041650ED64457234FE9CE1D22823460226DE0838FC002C9EA8EDC7F16AE9FDC50D55A47A811D2C8DD185B14A7639D76912BBFAA8562B327BB5C1C82D536C017E65639B6DBB4166E6F3AEF59A990DCB4C187D01ED33EECC25C390BCFBCF97A5D4FC9AC3571D0D10A4B5B31BC04266D97F22295E17D9263DE3F5AECB601C7C6D9A9A12D39B4E5E34D4C441E652092A0133BF43D0C6415A999F4F6AA4CF6EF20952B7EFA11246032F3C9E64C38964925DFBD339C4CF8C0E237907DD2B713C873A980DB560623986E5D77CF11173766F0DE5EACE2BA9D3906F429D295A2722832947F851B2E3A8668127FC437DC2E95A058FD30EE9F8677452A045EE3832796ABB94B7F2021F79BC1577FB561205EA02725B209987924474C23AB563F567C1A1E15D7B7FD96A462F6A2EA46769603DE569F2F24EDF3AE0FCC9AC55A7F7B94", + "k" : "873BB6833F3E9137800A8F5F7B4B32854C5839095B58D33786928F2190B375B1", +}, +{ + "rngSeed" : "B3AC6503206ACCC2A92CBC210D020A2654726911D11CE676AA04FEAA08AF1D20C654E4105883AE470EC3AB299075D420", + "pk" : "CBF017D8E336EFBB596130B73268680BE4885255AA6353A39F04740BE2C3910A9BA91700687088AECA7FD4A37FECA45BF29A27824BABB327C49F18539ED20C1755983E6B1E03F98F8610227362C9E12246D2176DDAF48DAC31955E59A7D69A8DFA582F8C66B14DB7259E6C4C63BB88C995A71FC44BF964B1650746FF672FC2716528741DD8174AA2326E21F025367A0F243AC63728BC6AB95DC22A9632E18CFF13CC6E38A1F4A0A542259D41DB0C1DC640E8735DFBACA58C3C7F18E39C74641D477099FF1AC96C924E366B16AE423DE8BC9610C855EB686E8D9301F2C08E96E3A2776523FFB93CFA3726C1D03D0C2C634F1CBAE6DBB4CB987BE8EB464190056CDC29A7651C79773B1686269C1646A65786F667986E7A552278713FE5C5A4F9C23633C467B8B63B408C4229CEA5F5A0664852729A7474695137C0961783656DF45277092226E232D5EB929C8BB57781CDED3B7D5266BF5C2CCFA992BB9D8B59746319E6B5803D00A84E2A99989C08BC9726783389FD506074606A0945C7E3E22500D58FE3A647213B19BEB6174C72833DEC8ECD036499E53B0A18A1D6E471712A1D64A903B1F3634CEAACE56A906A1336C9D9708768A6BCB9CFC036AC22607810457E8560561A38C5CD84C6CA021A98C15AADC47E874778A81423D669AB411A72AA4A661DEB2B8F4A06600BAAC967617BFC5DC8D12D44D9A7F80B46D9A40B91A66E3CFA0BFB5523C04922DB21C4120717B436C6DC81030D13B867E707B9A3891791C756800ADB41CC9A29260D98202472B733611037A98B454B6B5AF423DF236DC079941B160FF1C0B8ED1B14E787898DA354CF79CA4FE506D5742B58141DCF624964397274737E4ED1AACB76A92BBA8966AB24741163893587C94CBD4581BD0A110937946051C572F2232A149667794812039BA9E6525A298531E7479A161123DA95B83EE746DCFA1D880130AF080FD71480A4D51A48C48ABCB62D4C7B44B712BC0ECC4EB53A929A1167F3C49BE7B019002679123348AF5B7AB18A36F86A23B309154C5307B003966C8755047718B32649945C7865F123EE60198AF51DD591934EE02EF7EC218569129D03B76E9729DACC17E4407EEAA4820E238DEB307D819528B932BBDD74AC25C0476C037CD8200EE9231533676F3E1B11A6FA2511A3160F10B26F2CBA2966572450516BE1A39ED8BF651B961E58BE810BBE83957037F1671C128F91F302DFE1103D624B97B4C331DB624FB354178047AD4B909BA93211908E35014D896144356C250DF2248C5487EA11B329214B4C3B2342E64244D684BA914E020228E0D9B5B0283B5C96A22B510F31974843B21DF48878652721BFEA1B38054BA1B39EBD0A03746AB5D07BA3D80B5BE050AF1282BF1EF87629EA0E2F9A272BAC24B7D3B464C182A8032DC2ACC0B7BA3482C5CD7C0B5199522634F61D553534020671BACA3534193B2A9585F47394ACA1C8AFF24C05A7A8B0F59745E56E12321FA1A7B38DB38DE3485F017626EEA474E3E3C1A6BB5242F26DE2529E517928E547423B79CEC6452F14C17AC403C0A6E23D25D334AD07AABD8C60310082BB4A194D656B2E2B64FF3475FCC9226A526867CA7DD03C75351AB921EB35E445B144F4A7E743ACCA85372A03C4CAD754F1D788A1C919EFC198AEF95BAF7768DBC94F36D5A37DB440EE403B9B8A339BCC50C0469F51681FCBB294A042147F895D9121701071A6AE8B85B3CA4A7F197F06CC5ED4E40C5BD1BA18F76A8010857BB0C3F8C15EF8F89FCF22AFD560445C8576B8A46297F1CBF5896232040727EB40B78C97099A09EAE192803BCDB153B7C9918B8C66A3E8CCB0A928B2505B3034886B452BC9F7719246D62AD183A292A75F4D6715A42153B8F8656B2C397428803725BD66239587506E9AD5694EE0592918A14346CDB0A9117B7969345BB11BE07B82DC4361B580FABC4A91D919FC97251AD1A69938B507E066CFA6A251D98927F2BF2A9806163C07D1A96627265776105126E5CA5872C61E4BBA95220ED45124E76B334DF40FE0CC4F193BAF6CE69581313616C0A9DE56824F007D65692D0F675AAFE086B6E2621BFBA18CE1ADC4337553C81B92CA4A9A2C9712416A168A7A9FD06450589641E952A96B122B4C4BB63721D6E76201F96E7403A908819BB61864F9225185678741DA30F96E7973A83811B94C50BAE593D1DA6D3B306BF50669E590EEE2", + "sk" : "5CCA6A37C37871E04CFA962D1716088FA90F49D176BD5077881B53D6F20DA1027284E94A28058A0E249DA3C36C5AD6AF6056C4F8774AF6343B19A0CF5F3A4C594489A64305D3196E71E390528141A735544B9BA54CF64523C39797153AE1620087264A5BC804CB864C92781AC4756C4A216D6D041EE6369436DCABD1B3A33FBB2FAC37A994E2251AA9112C28ADE1761151947314134EF0567962819AD9E47F56E7724FFB8967DB192DBC50E0358D4ED578DB4B88F76578196799340A21686C747B4763B9302EB4D5648CC83F75587627661A269801FF10662AE713A03B7EF1DC1918493885E811163902C7A8C5CC51C639C5750C13ABC126431DD85D9706C945FB5D736224C5456D6DA493651B148DE081607116437A9C45E6614F76A5C6502B65A1BA5A31318893BBA3B68E3CDC3680560D22C2B33745A4ACB3A8AF56452B7201CB42A0301C9A41848315212F60BB7D6CF7C8647CC7ACF68B81959A8A6A91DFAAA41F3A679DD136D40046D7846F170BCBA2648E08185A6AB380236158442299897814913196BD649A8B735D114135AA466804FABCA21084C28844BF00CD18D6C8DD0B48A0F61139458F08F912DD28C4B4B6B012F6CEF761740D97CC81341C80190A0659380CA04934E3B4426C7A22255815646AFED165F68186DA0206AEC0B841828CD3130C59F3295AB80613E07A85B599BFA444364A569486075AB07815C74B4729A9281C6AFEF55FE7737F621128E18A355BB89C392817C348AECEC895DA19125AF968BD1B4968240A025B051C49650594110E96547C10A127148AC162BAF3625093C26577174586ECC30E4234B9B626C58328613B21BD4A8FBACA56AE9C9B943A7D2D79230E01CAA6C6135900B33EE8925CEBA22EE6B65FA09056E539E71B20C4815B448C70BA772302B9CD6E7546E756A85B41C409062348C334C6EC74C130A13A146757B8B566D33D7B0918ECEC6ACAC9C579E5CC7E3A33C5DA79D86A36B0E9B6CE1B22CDD696E1E793F6109DA565137E2B666631225143A9C8B95D8D3A21C467C1DD2C0CE774A45006ABEA578844E09F8B982F0EBB53435C0941BC7CD7D27E8336CDDD8332D62C32068623BF18944643634D814AF239A12E3AA0DAA027A8241297FBA5BDA40EB7630D1C2A4ACFB7529963AA1F80CEB901B7159020B910C252BAC2110A6DA65732AE359AE3D0032494885C6A44874735D843CF2AC6A5E5F5A625069C0A49A66C8270B8E5A00D91293F0664F64594D7493F5399A3EC6A2C4F4A31BD604B04449C1B215DFB227F43778D9FE33F52E9C687452926E46A508C8A2D7A448AF4539C05B4BF512B962017781C0E157686B748CB77B36A95C459CE5011DA0C88F58A518932B5F7EAAC67A27D89A60884D8A9F2729509DB5CB76CC6F6236DDD0911D9C41F526086F3A24E0E160192577B8AC91EBC0860F7AC884161C6B62B872F129CB8FB11D56CCFE8B9ADBEC54FFD23B02E471284DBCF508C6A1912213FF754F1DC195F97B0BD798D8AE8B44114C4DFCA0F76E479D39C4A19AC67445520EBFAC92CC300FC62A94541B345F10B0F79C519C576C2037998564EB1506E6B91C8F606CAC8F9B0D6927AB0E885B4704AC54CB14C67949F506000EC9E0685A9684B648A802CD8B5C8CD82860566B2D6E60E213429882AB51EFBCCBBF33F4F7A0CF57B6CCB8A27D95936A87814E6D80C4562C7A753C0A7E03B3685891E77338034713B7C8DA4D097281753E54828CE951C60279A729376E991AAC5101C6DE3AE87C4AD3F4C75DDD517978BCAA4E85DEB15C10FE701710067D25C2DA778B4018C500C7368E58C550AB5825FFAC4D58B87E745BF10D8118A787A5C5694BC099B38D89AC7F890D25497A8E521C8505E659506E0C65678279BC3DAA95A82C806F04219944C5EF308315C69BC753D50490002C22E8EB89A65C93AC116692370595492CB626A8B5B64C291F77F256583BFE2A2372CBE80AC5704A2BBF3F0BD0A4515CD131814C6AAFD39934ADBAB22EC3889572B423B643BD56CDD3BA2B8B20E98BC8AFCC33D78C9BB8E466047961B03D31F94B783EE80A7506504ED3A723094C460D07ADBC7B4CE258F9072C687E6346C850EDEFA4D3600CD616C6E8138CE6C3854A9452393A9266C2141B1D62D4111ADF9833E2F2BA9BE4289DB4317CAC169CBF017D8E336EFBB596130B73268680BE4885255AA6353A39F04740BE2C3910A9BA91700687088AECA7FD4A37FECA45BF29A27824BABB327C49F18539ED20C1755983E6B1E03F98F8610227362C9E12246D2176DDAF48DAC31955E59A7D69A8DFA582F8C66B14DB7259E6C4C63BB88C995A71FC44BF964B1650746FF672FC2716528741DD8174AA2326E21F025367A0F243AC63728BC6AB95DC22A9632E18CFF13CC6E38A1F4A0A542259D41DB0C1DC640E8735DFBACA58C3C7F18E39C74641D477099FF1AC96C924E366B16AE423DE8BC9610C855EB686E8D9301F2C08E96E3A2776523FFB93CFA3726C1D03D0C2C634F1CBAE6DBB4CB987BE8EB464190056CDC29A7651C79773B1686269C1646A65786F667986E7A552278713FE5C5A4F9C23633C467B8B63B408C4229CEA5F5A0664852729A7474695137C0961783656DF45277092226E232D5EB929C8BB57781CDED3B7D5266BF5C2CCFA992BB9D8B59746319E6B5803D00A84E2A99989C08BC9726783389FD506074606A0945C7E3E22500D58FE3A647213B19BEB6174C72833DEC8ECD036499E53B0A18A1D6E471712A1D64A903B1F3634CEAACE56A906A1336C9D9708768A6BCB9CFC036AC22607810457E8560561A38C5CD84C6CA021A98C15AADC47E874778A81423D669AB411A72AA4A661DEB2B8F4A06600BAAC967617BFC5DC8D12D44D9A7F80B46D9A40B91A66E3CFA0BFB5523C04922DB21C4120717B436C6DC81030D13B867E707B9A3891791C756800ADB41CC9A29260D98202472B733611037A98B454B6B5AF423DF236DC079941B160FF1C0B8ED1B14E787898DA354CF79CA4FE506D5742B58141DCF624964397274737E4ED1AACB76A92BBA8966AB24741163893587C94CBD4581BD0A110937946051C572F2232A149667794812039BA9E6525A298531E7479A161123DA95B83EE746DCFA1D880130AF080FD71480A4D51A48C48ABCB62D4C7B44B712BC0ECC4EB53A929A1167F3C49BE7B019002679123348AF5B7AB18A36F86A23B309154C5307B003966C8755047718B32649945C7865F123EE60198AF51DD591934EE02EF7EC218569129D03B76E9729DACC17E4407EEAA4820E238DEB307D819528B932BBDD74AC25C0476C037CD8200EE9231533676F3E1B11A6FA2511A3160F10B26F2CBA2966572450516BE1A39ED8BF651B961E58BE810BBE83957037F1671C128F91F302DFE1103D624B97B4C331DB624FB354178047AD4B909BA93211908E35014D896144356C250DF2248C5487EA11B329214B4C3B2342E64244D684BA914E020228E0D9B5B0283B5C96A22B510F31974843B21DF48878652721BFEA1B38054BA1B39EBD0A03746AB5D07BA3D80B5BE050AF1282BF1EF87629EA0E2F9A272BAC24B7D3B464C182A8032DC2ACC0B7BA3482C5CD7C0B5199522634F61D553534020671BACA3534193B2A9585F47394ACA1C8AFF24C05A7A8B0F59745E56E12321FA1A7B38DB38DE3485F017626EEA474E3E3C1A6BB5242F26DE2529E517928E547423B79CEC6452F14C17AC403C0A6E23D25D334AD07AABD8C60310082BB4A194D656B2E2B64FF3475FCC9226A526867CA7DD03C75351AB921EB35E445B144F4A7E743ACCA85372A03C4CAD754F1D788A1C919EFC198AEF95BAF7768DBC94F36D5A37DB440EE403B9B8A339BCC50C0469F51681FCBB294A042147F895D9121701071A6AE8B85B3CA4A7F197F06CC5ED4E40C5BD1BA18F76A8010857BB0C3F8C15EF8F89FCF22AFD560445C8576B8A46297F1CBF5896232040727EB40B78C97099A09EAE192803BCDB153B7C9918B8C66A3E8CCB0A928B2505B3034886B452BC9F7719246D62AD183A292A75F4D6715A42153B8F8656B2C397428803725BD66239587506E9AD5694EE0592918A14346CDB0A9117B7969345BB11BE07B82DC4361B580FABC4A91D919FC97251AD1A69938B507E066CFA6A251D98927F2BF2A9806163C07D1A96627265776105126E5CA5872C61E4BBA95220ED45124E76B334DF40FE0CC4F193BAF6CE69581313616C0A9DE56824F007D65692D0F675AAFE086B6E2621BFBA18CE1ADC4337553C81B92CA4A9A2C9712416A168A7A9FD06450589641E952A96B122B4C4BB63721D6E76201F96E7403A908819BB61864F9225185678741DA30F96E7973A83811B94C50BAE593D1DA6D3B306BF50669E590EEE255B703FE0B2AEBDD29F6CEB606F15213DA5F478ED4605A212F52358E2046D5B066BBD48DEEA2A0A14BCAA97E18D848E609339DC39BCECCE7077F2D7432DA536E", + "ek" : "B9096B52AC4FB1F7BE7B8F85A99EE7D27C4E4F16D8F1F30E047511881E0FE0572490AAD273177D20B0E36785D3C8A1A7D3832EAF4371946738B326787E236610AF248E9DD6746D36AB88D019B5A5C4B979315A24B08168D86B71F753D42880C057628D35478F14BD22ECE21BF7311B277C5E2973C3C2F60FC5DA920527691DFDF45598F5ABCD6A86A258AE2553A292409A79830B9743152CB0114D767234A0C56D87B3D6FDCD4F09919980CAA2594F3A84983DF43CC0A1F3C4FE3A7509937C313A6016715E805D432EF95B063CEEA1582E27A7E95B2400ACAB532A20CC169DEF94032AEB863CA00FFBC10C97D7BD3DD664575FE1F512207E6CBA75157DB23BE8F379815F2FF6D14E968F8E77B2AD868B27A4E763A135F30F4ED196EED9E35BCF3EF6DB02256B3566E809EB0EB07648C7E28AC3E33819B151D58FCA498B8627004AE71B12EC3E7DDB504FB71CC4D124256C0E7B80B7F11B1F96AC4214BDBD2FADFE843CF0DC4A69F5A6185D9EC777588C9E5589310D410FBE4B803FC4793EAF1B47FF608F87AFA63A8ADF32D53CF8BB3E96B769EC94C9C93EA23265914C7053BD8DCC6DA532BDC985C69A98A7B52353422A8842F9075C4B8C6B077C633C688FE9F344189B633693C0D86ABC1AA03AB7A3F8AAA4157FB1DE73D34690BE77BE936FE78ACCB65F44B9865282215E0EAC4FA45DF0CEE39A5CB5F229DC33767DD4F5B1F01383B87BC0629C90EA2A78FC17788A622CFC05429E734E4D6786B8425A4AB47715E73EDA21428A6C3E0ED7C93093C2CF4C7975CAF8FD1901440AEDAD40E1A40F186DA9CC68A239AE48502167AC0149DF3DF9D4943CC91B811166F67557899327164E1A4BD20B3F75F5BF16D1470014EA3195525B7B814441EDB30A55E0B2B80E72DDAAAA5DC7D90119C6F70F80282A69F0A1AB871881D298B9425B66BE17282AE5C99F0DCB60B36802929C6066A04C083484013331004D4301C8017FE4521F3A837B10589AE1B10370A145E799C5CDE771E6D004DFD0F649525A911492D3C5C84FC01A9400D281695735F867C1B3D6368C516117E4B5DEC572F75A6358BC5BC238D1862D2F64790E6135447EB24A6DB98BC16BA0EB4470E6229011F3CD3CAE65F76F200B49C603D9E90B4536059C39DBD653CE62CE69B6A3191E70955E1E6BCB9F23CE08CC7562A1854E1D3D47E2DF200FFD7CDB9CCD68CCEFC852758B58444B3ED612A59B6627665A155059E9EFF6FD12897756EFEC85F3B87BE2114BDB810AA4CBFB93EA807AFBC01748A4F6B29E08DA94CFAEFF232F264B311B5D44622DEA370477E23E418EF7D6A7F59E0D501D418CD268214685BA80B406D871844D956FA5F875EE5DA8AC545D2125CC9B69309F6A7807FBBE0A2D9779BD5C2D5201DF35E6E8BF5A8700E8AD8A6BAC590357A0E0CE38A789A1D2470312C90423E42B89EDAD9BA3D5CC234D518C5EC8B267CF12E5746A64576CFD476AE5A657732332EC7A28C4D8E11B889D4AA26774312A669FF61D75D4DAE075EA9DEEA42797D81F98C12A6ABD59C5A2484989123D29DD8AB231BD5E06B479E4D2DBCEF19111F47618980C204556DF58C5FCD0931FC9E43F61759DD9747267D3BD39E142EEEB198EC1DC9E0E63939945BFC23B02E5973B0B8716D9B3DD0A893A5BC29417833EF816D496DF7BDAE43E219A07CA10C5436A88B611C7C8270D36DB65FE15A576FFD6DFE0C0238DE9F206E24CE0BB119838C860B2A941D8A4388C26D2A0F67A048105F519CD2343C632F36722170423ABBADD7217E6B581220E78D112483DE50DC9AFDAFE203A333BF7D438E8523D71681B700FF09D05096A0B9646A7ACF7F1B9D19F8FA7B436F7253126636ECE1C297146C6F325EA196CF3161D67F716A65798BE429AB262F1EC479767ABA04DEEFCF40F646B9BA0CE46A1B83A8BCBCD1EFB72140D8A70DEDA4B520243012357FFABDA317480293E0ED735EE7AB0B90B6921C50F0848A1A043A6118DD488691071085BA9EC53D831AC46700DD95A159CB38B5C2676CB5966ABAD1733CC6E1E1E9F5EDDAC27EFF2FC06EF2C43DCD20BB4CA37E6589DFF5EA2389D4943065DBAE7F325258873A0709EB48869F9E47315BEA207C29A99D63540D6EB15E63B09DDB5B9DB85925C82AD06206039A01F408BBB0A7119AB483185CAC0C571933C9B4CE3EC5A4E98E2194CE19B1B03FF4D55DBF5CC5343E46B7F9E", + "k" : "F1094EC60EA6B7484BB065BCE08062451E115E7F240C2E490D762C6FD2E691B2", +}, +{ + "rngSeed" : "59EFF60B1EF6185DB34EE1E3B1DD2F159106CECEAA79BEB74923B4F5623D5BC52DBF5D2594A1F7C6C64D12CF144E9ED4", + "pk" : "8945CC28753A4F3771A68A9000944D726479E1A79D88675FA13795FC086D79F82EA5DC7E2DA5AC939A42728963BFC3659D50345694373B877B0504A864247ADDC746E98126CDC71D0E3B0C7F457C046AC8B8C1458EE70C82905FF5183D890845B21C66953C6402CBA2E329886AD51A92F7C673995FE255BF9462B2EDCC899125B1820125590024B6928FA0C79476CCC407312664B83C9C59A806989C3252683B139799561708732F57804A96C0B58C88CB4A83A1271A05A9A58A4C187B45CC893B9621E8C5543A02221EFA2617B0A42BCA1880959E70496CD1452D36191DEA226B49F76418B1A44079C2D6392C37A319CA007B65F57743598F2C40A68DCBB603F11CD32C368A0688343A25F6A348C0B260B1946ABBF15B3C9BA0AD1CB302B918E4285870C9444118598AD60DD6030C45F33239ABC79A04A05A2CB8E62128A3A9CCB61248F1021C7BA5751DC60D50919862332BDD0BC371E4037063879FB5BB22290328C9194AA83716316B7747A5130A984A249E2E124EA0EB67396A3197FB80BD672C6E6CAB6DE2CCA2E3AD70D5866FC878DAB1CD654729ECF9CEB733A1B81890CF51C2AC112A52B6A4122C27B86CCA81089AFA1361C4015ABE68C62D9A11BB10358459882F58461761A7ECD3B9B3B17E32A682A389C4328BBC4AAB01F44CA93F150E72678160243130555AC9E964C784C33943B5ECD07AA8097BE421B796305F05E196AE166559CA5C59A445BC98092BE1182F8000D5C39B7C074E016433235ACA94D7162B853E45367D42E1604B10702CEA82D9004259D130AD5117CA24C6ED411D5929C3F7A6BB35CBCB2CA6BF08C06D1A1CB63AA54D4164A838173B82B45523E00559994E8FF5A9CAB63C6FC3266998CA8BD5820E7B16F8F86CE149C355E49451C89624B4B1F2FA7F09C5A15BBBAEB6A641D561830BA25EA470C9D7C397499C9747994BB8818BEF9C1EF7802FD6963DBAFB6E6DC5A3CE1509510578B96983D08C53C9384E45E6A5BEA7C943D11C5C46CEF5D0566C4C1F99D00079B0641636BC31913034A134E7A4B0CB959EA4662BE55157FE89A7EAE1A976F30517BA7E019820984115E5EC2E7D00267240695F600B2EB4181ADCAD96C7605D5C750154A41124C6F23696845B9B5539AE30B1564BDB2B41C09FEB96B31B0796FED8503028AF11B02E68F342E3210845525A52268A1B0B4F7648600B455C5C824C49E2972371808BF572017331CC8BC0E11147BC10793E096144A4187B196ABDE288B134BC54C5B3B85312E7A9BB90135DCA9BC7396615AC979DE9800C26057AE3064090174437209EDE210CB2C733302C4AE9C1AC1462024D54006835AC3F23611D1BCFC945A58401C6A6DA42242983F4E712A5080BDD13633B1C98F32835F179A3D011AAA46B9B2FB810DEE9495CB4451FE0BA20F71992A445E0C16486D06382C8CC4051647739762257A00D80956475B4521493DF79A28319C2C1338C9CB3791980785C2A1EC4A11844B608A7C7C92B81015534A03904CD5A4777FD587AD8004B61EC40BC9AA7A4268EF445900522759CC5057BAA2A5729BCFB3A0666126A90D56B7527C32800960D9586E93579EED18189F0A762518125A4317649A3C1883C6ED8B047B5444667B4D53AB5D5B952B10CA1B8AA4CA5E438EE3C2E79C2132BCC257D8585ABB609FF870D25826A67075FC38C32CD1C6D78E56A4F18CB59C756979331F1786820BA297F4C26CE251C93686506B26805286CF5919AB660092E6C1825D746C8C9478B408ACA024376233AB8C287D709D02F7B8C6D80B4430917FE546BA774482B9B77C20BCCAD85355F562152A1593CF2BBB02014DF47B29D1CA5C1D300445CB4835B45BD59B92CAA1CADFAB9986869F5A7875967981F1267E615180BF7952A27AB3527A60B130D69E155FF88410B1A10A705B14DF248CCA801E3B7610BAAC9D92C75E4C759CF7C8F644B610A350A9A9B5B59EB798A1CBF42D02F211A27AAF05AB8E19BAA600F3BABCA5D82C9388466C5ABA81C32A7DABC9775E73A77432F9B96225DB1698A2C7A6C9B6949C59D7796758D24C41872802A63BC9723B17F703903C84E425383051ABB07E94A1F19A258A61C66B56F46CCCF68FA4AD62C528CC1BBA2D579913AB754268EADC4204B887BB764096783301FD30EF9D972ACACC01977D137525D619DF951B0F9A5008BD9CB4524C5AE7CEC747696489A8FC0EF65", + "sk" : "AE7ABEA38C394EC61B08F8B73A42AFE39C0510A45E50A3C3565941C54332E613C5687C6B7F1AC590C7A2472597E331A23F3122E0A12A8688A9DA651AEC131981AA6C623AABFF1B682DB2525543AFDB53B461853AABCB955435178D9939C2E262554978B998AACC07728F29A6EE7C54F34738DB084C81B6CEE4914B0706AE0CE056EED5C97851A0C861A91F42938678BA9383B4A8DC051472CD38D2C85DE9747D90CE0E46BB059688CD2CC90721187F56BBB695C43C61651BAC8763572D78A4014EA4106A9916FF378CAB1518801455683175AA75AF0619A6EEF774F25568DD35CBE312B80DB29AB007BA069182A0369D8025CA8FCA341DFB99CCB044B1ECAA19979957E2001AF126DF1159F13648BEC2A71AC53A8CDC957B731C09D84249EC7A53B3507327B1FE36BB79A7668DACC9F898698BF296BB078D612603336109DC29664635B9FCE33005C704EB3512DF2C4AB3E63387126146A56C00A04954516E386B554ECCC45A848C8AB79513E9A7E1E0692315714B292090B281678B70AF0847D3211B97F89CAD50AEEFF5660BA620302724EB2403D4C0A8DD015E7362077E0944DA2B5AFAF2BA08687C25E491192659E48363143600CA16441A678C7FB40A76C08760C102247606F5D128DC0A13A8A86F758725D4205F1A2393A7479AF603A2F173C841B27B51F90833363B87D8134A904DCBCA542F76CAEEDBB57F73522F227F72056390939C10D28B52A824ED621D861C8080660472F01A3D692B1802A7BCEB5CABC12DBDD649713227BF9A53F801420C0421CB48C3214755917AB076709231A27DCA46A2A603649BA1AED077960E5BA1D44BB3F2AC2C0536B8DEE5BE0B7C682851553D902939A775D564B38ADA0FABD429E105ABA00433527B3EA6F847EE7C1667590F96FB7C4F2083C2D540582BC79DFC3E881905B8C16B5BC0C5C5C46880822CEA340C95006D80B475D0485C1539880D5298FE1018F9302723D5B3E64515851364E8269A6BC824C562A29C801806289D82389945A4974D16865889BC05D42F57CA85A6499FF0E5534B9CB8041CC0D5F30EA82A04746B51D8242319D980D274102B997B70688F63014F2B473F14B344D9DCBB08C400355A53B923B7A5539B2C41CA08A31556C32C67303448B088A9AC95005C74385BAEA6A227CD535BE3B58E97ACA21CE97F89E6C634D175274B737C74A8FEECB38BB587777B27CA372EE6C44592AC2F54618E77EAA6F11342DE70AD66DA080FF75D557B5E052BC4E6E9614F0B23C2B9A13E540637444585A81A5E90B2C1178881CA41A5863C45F42564200E7F9B82222430E7B185FEA1A5337A2BEB4BCD059CAD0B2141FDE13060AC4C2BB4B87CCBADDBACB43EA9BCD15A32E02AB9446C7086F64653F45FCA9190B0037FB5ECA9ACB9C28B757F177A9EF74BB4AB8CC526D2B4074B99EF4B6B3FC85CBB343834F929496A043A037E7E3C1EB71323F5CB62A57B3B7CF64D639C2CAD92623ACA195A43B684058F342713EB661D78A59BA2B57FDD7A64D2643ADD5738DFA57E575A11BCB956D628C85D06051109740A706FB649203EA70AEEB4CC07E1CBDDC2645E2613B6E90D5A12B0B9A81CB94152B106CB4D25830AF5B76DD61D98BBB9A6D5CABFD13FDFB139A90286379C5AA772AF1C10812DA52B582437B6543665F522AA7AB8ECF57E584429CB74ABFF84B9281B8FE0FA540F542599529505E0BDD117A3550BB1FDC225A250A8781BA42D45A481E74DE5598F4153650A4C85A005901A149C47FCA69F1B8ED039884C74B39582CBEA46B31061627368BBCD0C4DE55A5930670274B6BB33A737C9B376144B81C16B9B23292F2D15CC8A3AADA3CB7475C3425F8334FBD474A71A83ED957954FAC29DB49983C8A82BF41FDB0188152C5D20C6A9AD9BBB8F88693636AE00C4A61EB2BE93F95A96441A9D7BCE5B291A56D92640C4A22B1251EBE36379954FA49605216756B7D07943A176706A20F01362B96501DED810CCC709F54AA8744911811C2CE4E6490D6BB5BFFAC3F067278755BC8D472689720AD0F98801B6255BB399EC38272BC50AED950291D47ED97CC0C9C1542944AFB7C313565C414E18934532AEA2430C2C4AA95F31AE44B42E713387BA046AEE62A3DD4416D0F4071AE6541EFC7F8170995E376C41B57B7192C712A9BE8945CC28753A4F3771A68A9000944D726479E1A79D88675FA13795FC086D79F82EA5DC7E2DA5AC939A42728963BFC3659D50345694373B877B0504A864247ADDC746E98126CDC71D0E3B0C7F457C046AC8B8C1458EE70C82905FF5183D890845B21C66953C6402CBA2E329886AD51A92F7C673995FE255BF9462B2EDCC899125B1820125590024B6928FA0C79476CCC407312664B83C9C59A806989C3252683B139799561708732F57804A96C0B58C88CB4A83A1271A05A9A58A4C187B45CC893B9621E8C5543A02221EFA2617B0A42BCA1880959E70496CD1452D36191DEA226B49F76418B1A44079C2D6392C37A319CA007B65F57743598F2C40A68DCBB603F11CD32C368A0688343A25F6A348C0B260B1946ABBF15B3C9BA0AD1CB302B918E4285870C9444118598AD60DD6030C45F33239ABC79A04A05A2CB8E62128A3A9CCB61248F1021C7BA5751DC60D50919862332BDD0BC371E4037063879FB5BB22290328C9194AA83716316B7747A5130A984A249E2E124EA0EB67396A3197FB80BD672C6E6CAB6DE2CCA2E3AD70D5866FC878DAB1CD654729ECF9CEB733A1B81890CF51C2AC112A52B6A4122C27B86CCA81089AFA1361C4015ABE68C62D9A11BB10358459882F58461761A7ECD3B9B3B17E32A682A389C4328BBC4AAB01F44CA93F150E72678160243130555AC9E964C784C33943B5ECD07AA8097BE421B796305F05E196AE166559CA5C59A445BC98092BE1182F8000D5C39B7C074E016433235ACA94D7162B853E45367D42E1604B10702CEA82D9004259D130AD5117CA24C6ED411D5929C3F7A6BB35CBCB2CA6BF08C06D1A1CB63AA54D4164A838173B82B45523E00559994E8FF5A9CAB63C6FC3266998CA8BD5820E7B16F8F86CE149C355E49451C89624B4B1F2FA7F09C5A15BBBAEB6A641D561830BA25EA470C9D7C397499C9747994BB8818BEF9C1EF7802FD6963DBAFB6E6DC5A3CE1509510578B96983D08C53C9384E45E6A5BEA7C943D11C5C46CEF5D0566C4C1F99D00079B0641636BC31913034A134E7A4B0CB959EA4662BE55157FE89A7EAE1A976F30517BA7E019820984115E5EC2E7D00267240695F600B2EB4181ADCAD96C7605D5C750154A41124C6F23696845B9B5539AE30B1564BDB2B41C09FEB96B31B0796FED8503028AF11B02E68F342E3210845525A52268A1B0B4F7648600B455C5C824C49E2972371808BF572017331CC8BC0E11147BC10793E096144A4187B196ABDE288B134BC54C5B3B85312E7A9BB90135DCA9BC7396615AC979DE9800C26057AE3064090174437209EDE210CB2C733302C4AE9C1AC1462024D54006835AC3F23611D1BCFC945A58401C6A6DA42242983F4E712A5080BDD13633B1C98F32835F179A3D011AAA46B9B2FB810DEE9495CB4451FE0BA20F71992A445E0C16486D06382C8CC4051647739762257A00D80956475B4521493DF79A28319C2C1338C9CB3791980785C2A1EC4A11844B608A7C7C92B81015534A03904CD5A4777FD587AD8004B61EC40BC9AA7A4268EF445900522759CC5057BAA2A5729BCFB3A0666126A90D56B7527C32800960D9586E93579EED18189F0A762518125A4317649A3C1883C6ED8B047B5444667B4D53AB5D5B952B10CA1B8AA4CA5E438EE3C2E79C2132BCC257D8585ABB609FF870D25826A67075FC38C32CD1C6D78E56A4F18CB59C756979331F1786820BA297F4C26CE251C93686506B26805286CF5919AB660092E6C1825D746C8C9478B408ACA024376233AB8C287D709D02F7B8C6D80B4430917FE546BA774482B9B77C20BCCAD85355F562152A1593CF2BBB02014DF47B29D1CA5C1D300445CB4835B45BD59B92CAA1CADFAB9986869F5A7875967981F1267E615180BF7952A27AB3527A60B130D69E155FF88410B1A10A705B14DF248CCA801E3B7610BAAC9D92C75E4C759CF7C8F644B610A350A9A9B5B59EB798A1CBF42D02F211A27AAF05AB8E19BAA600F3BABCA5D82C9388466C5ABA81C32A7DABC9775E73A77432F9B96225DB1698A2C7A6C9B6949C59D7796758D24C41872802A63BC9723B17F703903C84E425383051ABB07E94A1F19A258A61C66B56F46CCCF68FA4AD62C528CC1BBA2D579913AB754268EADC4204B887BB764096783301FD30EF9D972ACACC01977D137525D619DF951B0F9A5008BD9CB4524C5AE7CEC747696489A8FC0EF65C68E808974E356659CF3D88474AE8AF1480F2C4BF5F053B0A8C211D43921F7353E3A1BCD39C74C1B899FFA21A6FE100804A551199D32DB4A75E6314BFB58F70E", + "ek" : "E11A6B96902C2AF3AB2ECBC002EBB364A246108D12C4E513141A1101E8060759EE8E0CFCBF562A1CA69A370816DE9464F0BAB5EB51A69E981D9C274D50A7AFC737B0C0C4054A03AE3E0BA235DC9FA6F9B9930FDC67A9DBFC27B2A159621BEDBCB53EECB12594DBCEB9886634D49A0690857584A76491B0B9EF4842BF00C677A80693CBDD6AEB40FEC582590C474B3F8798623D88D37096E41FF06C6749B263DC558F7B93FC61F918CD2C7D76920251A6BF0EA8DF3BA213CCFA5B7ADAB65E400C5D0CE2D1EAE7EED5AC2DB93EE34FB4ECEB6C16614FE492BB89A52107D9A71EFFB37196DB3611B2674F367B41F5070EB21235AEA7FA049D1F78958BCC0B52151878DFED88A163F12132FA350C532D95FF608E454C3AF1487768F79EFBFBE799F2CDB276A9C0438B5115D6854B8A97D2CD98FBF61BCC35782CD6BA406EFD884130448DFE01767281C0024CCE9BAADFCD322C451A36E84CD7EB9C60D93C5D2D165A61311EC93146B95DB5CB432D2E3B747A3D7DBFBB47D3467ECBA224D53D021C8A45BDDCDA0948118D1E4D055963BCCBC710E4205D3B6DB092EFD9600797EFA17A1D6CA1ECB3BB6F8DD163CF4F7E70FBD32E0E1E0940F9FC0892B778C2FFAD997A8356E68C4EB94E44B494FBAB3BF062A033939422296285555A60EB6FD8E198ED06BD256D6A20739B30B79E59699EB6BA25A5FBB5A4FE7F14954EEF6516F0EA3F8E6817A252F2948E197D8AC1BFBFA84E31898AF6AA5E37F13012B85DE7EB80B6E8EF1233A693BE6B55C5901E7F6A3BE6F5BE0854A2A4720B1C75249C4EA6C8D8F63FCBCBAB85AB41BB4D588D0F2B1CB7CF0F07EBC4828129FED3F4B415C1B6165C13797C14129554A1BAB9B5FB4B990601CF52F016D019F55D2199D411E2284355ACB15341944C441763447570639FF6F207CDDA02192F7DBA2872F88E103D8DC3D3BC5A457F3CD7EEE3978CB6641D8A826A3A25788CC69676782505837EDE8830CD9D8A20A47AC719FE44F758A6670C500DAD31CF0291C7DAC6ABB91BBA9FE1AF9049B1AA667A69C2AA1545046F62A96EDB257489CC06AE91CF89D0A7BE2E5E622A96DF1A8193D4BA86451070B362073960C41628665F78A168A7A71D65465ED381602B1D72FAFC0BE69B4F934BD2210EAF130E462DB497F4042252D1A2BFE334B03FF5B6159E7D908C29F50B42749CDC1E32F6A59ACA3AC90C337EBDBA01F3CD803E34BC33C466935469FEFA28192CF0D6EDA7DB37083DBAB82CBBEAC6E9D7693D283E612C01190E95B3705FEAA3035DEAC2AAA432ED26AD31610601A18FF9EBC3B23D5C2AA74C017EEDA66DCEBA69B44EEC90FB5410C6356EFB8E7CC4C98D30625E7B59A94137D778F4DFB6471695DC5EFACCDFF068F90045797DC2D161B1F0825962C24BE995D0EBE8F675B49100F913DD9A0C869D27C20ABABDA276938F8EE5C5B408783774FECA5DCC8C96A31DDE71E48C8D09B1278DF41242FB17FC7F157C433B6F93C83AB73C2C7AFA9CD0B96E998A5FC2B9C9343DF1A8E8DB872375868B10E39EE9279E3D66FAE59376E4E5C12699511F8619E2130CFC7CECC46438EF67D81B6BD2379D012D3C472AA85A60322D5ED5F108AE3D4070F437EC4B12F94827E041766A7F45E6817358D9E40F43F6225AE93CF09FE03FBA7E9E6EC81EEED8A5EF2535D9E8B9ACBFE3F9C2F236977E3F178AF426EC144E175EEF46AC4A31EE6D0E00A7D6B2EEB5C103E14082FD84498EB43F07DBC2F14D739B201E63029CB19C03F839BC0F67322E8D0090CB95A5C3CEE0CEB2DF10CE43F9342AD7882AA77F66BDCAC4603C31E43C919D773A23CEA4546E0EC4B227A9C99950953ED131E3D7CCBE58E0EDBE1EF459DED5ECAC339ECEBB7933B763E0FEED074670C1F6FD286751BABA4E828341F792BA1EBD03E29677DEC7C7288121CB0793E985D0E9E2FFCAC543B06554EB72C978B7CE665011AD081CC557B843D29D31982F3E262D4BC571AB377A0E4823D852547B8A1D3CD1040C3F6FFDBB5A98A5400CE672D35D1CFBA6D4C68DA0B49FEA7FB5BF1BA70A748F45734C1162D50BDAD05703EB4E354AF4F9A8175D9039C364EAE928CDB425C9349B8B1709EF7EBCBEA194E7021FDBA6FC3A1D81EB2D044ABB0BCFFB7B5CBB79F5D6E2FD2EDB9940210DB97EBA61C92CA83DDFA2C93FDC488E01C0188083AACB2D1AC129325BF97D06AA5F4508BA825F49", + "k" : "DFEBF0ECA5110BF795D6EB8EE11E7DB8E5909913F757EACE5FF274DA7696C585", +}, +{ + "rngSeed" : "DDDCA9DC31BEA737D3F474E7560B37FACB2F53C803E768FFAADE7669FF94B1D4FBD17068CFFD5DFDD24AADADA4EF6B12", + "pk" : "FAB5CF19743430A247522566196826BE35C3BA55053ED8C8AC04211931A38D5A100C7097059BC058D551672542A8F1A7FFE81E0C43B1636572F4608DFADC72F9A786C4C2B2D27C576D29461AD56369B7300D3B0A7890CA3D8407A8A1A90F796558843202152A7131919D9417065360440AB8516909087B2F4EA408BABA0CD5C0AF2A85634E88693B8C121DC8121D462650F2B417A0C44A5018BC2A70E68A590B757B4C0AC70BCA25923049FDA10856F62CA42701AB9A75D9991FE3D99856138112BA4F52DA1166F410E3F15BAF7C3062563DBF0626F76C4CE98CCB1F238A8870201654A6E551A5DE9CC24FB36DFF2334F2F7BCF51B8B6F8C2D07B4892A657E58637011624076040C02EC59924916F5E49956534B0B7A746B16663F33CEF4440F2EB5BE9FE4034DB153D296A86D83BEE3B08AE5341223193A7FEBABC53956049BC1E14819391C5BE5E216377438B0FB56AD770335A97C8E574C015C66D99C59325A2EDAFC7A6B4BA77FB51050A2C400D754D71C0FAC84781AF78C03C094BD800FE25B7F7060BFB4252643D97CCC6002A1568D4AF181E992B1FFA8CC17BB835F0B2E6B72026478729275B002636CB49C9EDBF4373912961DA0B913E6CFC1959B80E711CEA276C10158DC43B6887042D8D58402CC54A671275FB49A7920C35651AA4D81AEBDC772112420DB0162B94648CCC519E369958CE40ADC90413D9802E621B6E8CCAC13D846151C19C6813259C5998F40710F3162D006C5D3A9B2D18861789AA7854831A0314EB74A03B84921ED73AE13DB7298288CCEC07EAEF97716D14A8A296BC3D0B95E4A78E1FA2467C6AC961A73CE63085CA1A4B101ADB7F2A4059A97A24BC2DFDB6115386DE5E95486A46E6697A17A88510C97A0602205E008088D269082B2C1790C02912A9F03383A94D2127CE1A0D7F558434A6300513A14E2C4F6B33D8A159A06D09983688F75265A84637F07846F0C47441BC6A6A8E48142B39B4891BB5C321C8BD307DCB6326DBB960B532D88F08F8A299D914824E46189378C635CF2088ED8382FBB4164D01C867C1F1C4973116C3629B3CDDCB40B1832A0F06B6D04EC8EDC46205DA3B28F50BD1730BBC04C5F927209A4369B878596A2E149767139E4A06493EA42034062AB1AB037728908C07F9BDC820495916C9114F7E95683C945C19354DC06C5B7888244EC179BF88ED4E68BD10483918BCEA652446B7333E71A403E97446564361B5253D0B225D4155682123725F61ED5D4655BDB7891C6572758977F0B4E8DE021E832CE6314C25E82392CBCA5C794CD20241B87EC87A85A017774BC3DA18E77E0B53A521B2EB0A7006B35EDF5B0A85B44D3D78DFBB476861997714330C9C5AE5E0027D7298A64B62F2523670C618051629C9577ABC2F456EB0CA33FC86E94D910D186144BE3A886230CF3566CC09C2CCC76719BC349CFB70C35B24EA6B4BF1C0394527A529641A2B45B60DA3A976D70012E48B5DF60A7D8382AB149760CB5579F0673F78A52C01C8EFD1A667D86635BF15035AC32805B56CC9A1CFF506CA38B3DF7A3B860985FED84B2B4F1C7F3A88122630F438C565660362A90887A9CB55090CC448C9088C6783AA890CB51CCC3C8CC7C097D59808F06675E1E826869ABBC0644A612D471D5C106214ABCC1115B106AB3405B1DE14C664A773E6E5667D8177ED736A967710EDDA390F0B105F9C5BA3A2A61912A2414397030022035C533DE16C634A799F2B72FC3112071E7AAEBD1636A3603971020E2F90FB8113387CA17171B39104595E5500B50C99C37ABA1FAD50FED567D5EECC00DB3AC14624675C76846B42327B9510DDB882B24BE90C9661F5C46EB5B1991D25920C78F35807EC55AC2827776A54AC4EE272B469AC65AABC6BA199DBE33724E5866E24A8058D5908E30BF54325745907752D324490B766F6672C4C8443FF7647DEC597276135A4789DBAB39355175BF3A63CA6A359A879D648C0B388270680781D3E732EFA5C85F1C020E4384875954B50403A4987CE54A6F24C83E541491B7D144012544B96B00B933C51704BCFC2B20ADA6C481AB32D555898174526A266F70B7939054A88256A59C95A0EC2501CBD45F0FF2AD418B82ECB514F7EBC3FC33647F5C43C5026FB547A33BF2642C9279DC39AC6012A770267D6C947324C6D45B65393421BF4BD7068ABB93AB3A36081A303CF37B90037749A046D478", + "sk" : "52309729384894D97DE3098B745A1F88166013EC7422B31ED4AB74E69C3B7B094DFE982A7DB3CDC5D4AAF9E468D0471EAA8C8AA3148CC3A49CB1EB4E4D420B497B73573A839814032F655F87245DC6ACAFB9602774500919361BEEB7B9FD4688FA8238C8C1116F51970394C39354A39212B9508815DFFA2E87416269C88DEF88A639CB1B3560BAE168BE823918AFD8AF8D42C3AD9B43CE33428B6B19D4038CD03169C06C773AD1295FE5C06AD97B17EC93CD639732FAA7B88029ED160652930595719E5C734420028D60C6180263C9C7DB51A2BC5D52B232D0279EF9E7761C1A4578B2B2C21778CA806DEEF18F9C8778F0B5204D661425C3023C451DE2F806C67436FD2B7E2EF208023ABB81F87666C117A78B696D65630B1334EF853934A39D9D959AC8990B674534257012796352B0A41308A1104F82A09DF85ACA25137D597A33C088F942C496998A367A08473A49ACB2BD38D27B7AB21FE80959F3BCBCD0488C5BD4C42928155CE5A91DA1B437539A33A34CA0CB1C4D179540816F0D063664B599FE195DDC777EA8836CF5C20F8AB34E3C8C6026E58E8B032C6B720324A882A5512D502880B3D2A3DF38CF5DA7C5FEF955524B451D5C7FF24C926D0382535C0ECFEA73B4E736A25957C74084448324FBE462FB0C656B074EE596ABFFAA67B692B770E734F56C53A97BC846030FA6AB726EE7097A49A64F098AA3C763942001C7999131220A47751EF3AC3CD729238C671F5FF51AAC89101B772CEA01144E469510502103E70A67B08DD968B21818934693037F653C845579E25C5BE3196E180447210C97A9A724863588D5F38D20A8C5123A6B2AA549D50A8B03DAB4536BC658C8B9D8C782B3E02321C90525E56D3EA8CDF91A7340C88C8D90426414469ADAC2268214433C23CC078A12C5BFD3AB079DB8AB6222CF6F47C005FB84775AC60A606E1B460879D19DDF619293113B80598E87658A025824888541C2246F93870271C767F7D099E70227B97091D0D4C72A1248E47C80B99B2D8072CFC0552BB82320A6AC00F04232C75050AFB90F4295C98CCC09414B402782A0ED168D31C2CF913288E57245C8AB998D99B16BA26313D05D50E15617FA0E3AA1A32FF2717AC486AD72BFA679A5A63A047983AF1B6544C8405A4513AF232B00907C935F3B452619B91BA35C6E6297D5F4ABB981A6654B425E612B431359C5B861189A6ECDB978AE3B9804740C7DB22013B39DA62099D397659D847E7C6A9121991DB5ABC317B8287F2C9F07D4BFD9C3780E29441865458DF968187763B9EAA8C3C99C22976D77760F31B5C369917249A78874F2C22671446D289F996BA38F5235152C366BDA9D50F66235484DF4F6B0B8F243776BB09A7958668B77F9E1A537428395457873D6BE96868EE474C83D969D43E0BFD6976E9A75C79094574595AEC7FA2DEA390202DCB289F7823A35CA79632343C96E916A097E7314EFC002799047C3A608B62829D2669FA6F0A95F594533D910CE6594E9A8186444BC6826541F3C834AF812A38A2D8A87C8128837F68C93DC49B664813511FC64CAFA56E324556B2803E56503DB153ECEC99D274C889227BFE8A6B4CEAA578AD37684984A6DE966B0F9CB8740C7C5232293030AEC6C4828C29152AC2FDFB29EE8C72172105365B465D1BCC2C2A07269895397842F2A839467E49A422657CFF06E2320CA5687C52DEA39470A8B2B84710EC05BB7BC10E7F3542D4A9E5E2A377CD15D8189A4522B107C866EBC4B7777E602FA4A46981339879534A92B679BE67DE762B2B0D07A3AE14434220D749C0D3A556295757C747A248A3B2E172A9F7EA35F646C2C2BC3615AA110FEE2CE88D24BA7D12F0FD24D209A6FC44995DDF957EBC80014C4C904947A5C7A58A503BE4D18A9450C10A4B90E93B780D17C7073623296C62A3FEAA30B0414E1C8566D65B95A7C98890B366913336130CB5ADCAE5F40518325CF2328680D9C3E430BBB2BF32754235A4777280C934D33C2BC571A637B965583678B8280779AD6A2AD9A65D849419DE930327B5B00EBBA96DC14093088038982409A1B9B19C8085A3BC9A21783B51AB266A996A512C4EBB550C0C871F58332839CCB02A6B1509A89F43A54D302C865463BB12F5D87C1F0989322C48FE1927AEA1029E748593995A858514BFAB5CF19743430A247522566196826BE35C3BA55053ED8C8AC04211931A38D5A100C7097059BC058D551672542A8F1A7FFE81E0C43B1636572F4608DFADC72F9A786C4C2B2D27C576D29461AD56369B7300D3B0A7890CA3D8407A8A1A90F796558843202152A7131919D9417065360440AB8516909087B2F4EA408BABA0CD5C0AF2A85634E88693B8C121DC8121D462650F2B417A0C44A5018BC2A70E68A590B757B4C0AC70BCA25923049FDA10856F62CA42701AB9A75D9991FE3D99856138112BA4F52DA1166F410E3F15BAF7C3062563DBF0626F76C4CE98CCB1F238A8870201654A6E551A5DE9CC24FB36DFF2334F2F7BCF51B8B6F8C2D07B4892A657E58637011624076040C02EC59924916F5E49956534B0B7A746B16663F33CEF4440F2EB5BE9FE4034DB153D296A86D83BEE3B08AE5341223193A7FEBABC53956049BC1E14819391C5BE5E216377438B0FB56AD770335A97C8E574C015C66D99C59325A2EDAFC7A6B4BA77FB51050A2C400D754D71C0FAC84781AF78C03C094BD800FE25B7F7060BFB4252643D97CCC6002A1568D4AF181E992B1FFA8CC17BB835F0B2E6B72026478729275B002636CB49C9EDBF4373912961DA0B913E6CFC1959B80E711CEA276C10158DC43B6887042D8D58402CC54A671275FB49A7920C35651AA4D81AEBDC772112420DB0162B94648CCC519E369958CE40ADC90413D9802E621B6E8CCAC13D846151C19C6813259C5998F40710F3162D006C5D3A9B2D18861789AA7854831A0314EB74A03B84921ED73AE13DB7298288CCEC07EAEF97716D14A8A296BC3D0B95E4A78E1FA2467C6AC961A73CE63085CA1A4B101ADB7F2A4059A97A24BC2DFDB6115386DE5E95486A46E6697A17A88510C97A0602205E008088D269082B2C1790C02912A9F03383A94D2127CE1A0D7F558434A6300513A14E2C4F6B33D8A159A06D09983688F75265A84637F07846F0C47441BC6A6A8E48142B39B4891BB5C321C8BD307DCB6326DBB960B532D88F08F8A299D914824E46189378C635CF2088ED8382FBB4164D01C867C1F1C4973116C3629B3CDDCB40B1832A0F06B6D04EC8EDC46205DA3B28F50BD1730BBC04C5F927209A4369B878596A2E149767139E4A06493EA42034062AB1AB037728908C07F9BDC820495916C9114F7E95683C945C19354DC06C5B7888244EC179BF88ED4E68BD10483918BCEA652446B7333E71A403E97446564361B5253D0B225D4155682123725F61ED5D4655BDB7891C6572758977F0B4E8DE021E832CE6314C25E82392CBCA5C794CD20241B87EC87A85A017774BC3DA18E77E0B53A521B2EB0A7006B35EDF5B0A85B44D3D78DFBB476861997714330C9C5AE5E0027D7298A64B62F2523670C618051629C9577ABC2F456EB0CA33FC86E94D910D186144BE3A886230CF3566CC09C2CCC76719BC349CFB70C35B24EA6B4BF1C0394527A529641A2B45B60DA3A976D70012E48B5DF60A7D8382AB149760CB5579F0673F78A52C01C8EFD1A667D86635BF15035AC32805B56CC9A1CFF506CA38B3DF7A3B860985FED84B2B4F1C7F3A88122630F438C565660362A90887A9CB55090CC448C9088C6783AA890CB51CCC3C8CC7C097D59808F06675E1E826869ABBC0644A612D471D5C106214ABCC1115B106AB3405B1DE14C664A773E6E5667D8177ED736A967710EDDA390F0B105F9C5BA3A2A61912A2414397030022035C533DE16C634A799F2B72FC3112071E7AAEBD1636A3603971020E2F90FB8113387CA17171B39104595E5500B50C99C37ABA1FAD50FED567D5EECC00DB3AC14624675C76846B42327B9510DDB882B24BE90C9661F5C46EB5B1991D25920C78F35807EC55AC2827776A54AC4EE272B469AC65AABC6BA199DBE33724E5866E24A8058D5908E30BF54325745907752D324490B766F6672C4C8443FF7647DEC597276135A4789DBAB39355175BF3A63CA6A359A879D648C0B388270680781D3E732EFA5C85F1C020E4384875954B50403A4987CE54A6F24C83E541491B7D144012544B96B00B933C51704BCFC2B20ADA6C481AB32D555898174526A266F70B7939054A88256A59C95A0EC2501CBD45F0FF2AD418B82ECB514F7EBC3FC33647F5C43C5026FB547A33BF2642C9279DC39AC6012A770267D6C947324C6D45B65393421BF4BD7068ABB93AB3A36081A303CF37B90037749A046D478B6481B87D7F462E656DB85D6046534AE44D82B1CB737A0194EAAC814C7B85493AFF7ECFE33EFE4042A44F2F801170616925BE8CCA1BD1812A7335DCD80F9CF14", + "ek" : "5B2B6CB2C301B60D6A04AC92E95B22E436AC9C94F3F78308941DB4B84A0BAA465B725863241D6B74DADD84106A83B93DA189047B7C7E636EF5435387AAB30A07E10FF33E108389CE1DEB9CE9D4897E08B5B11ED51765C2EA00C4526F9A1521081EBB4E92449C6E2A0A62880D2A323F31E8DE8446C5CBD37165AC9649E0F0A42A3ECF2D4BE17DDEF588B1D17FFC0AE286BE083D7A6C65A8152A37ADDCFB302ACC54C56883273C98EC958E1152CC9A5FCFEB4A919746AF9F5776289FA0DB8D4B95A73E5DA57B2EF75A7AEFE85E97A5A5B3ECA5DB2C2E67278E99A1C9F09CEA1AF4F4E91F74096D66728F4930F97086BC5744BA1D8CBC6B21FDE4FAEB2C4976D52A2FAA16DA6868DECA8B9486385AF1C68BF15EE46D1AFAC7FA151300C419633CCD869575FF79EFEFC0DD2AF7F726552FA03153BF6B307A58ED043F57373814A5129BC3E7A2D9A78013920DC90698045A3875882390170791CEF276EB5988691DDE82CAFAF5E71E4AF861DBB29A9AB5E8DDEAE4AB3DB97C0C76873CC6302A9C4C2439C4F0EF40B19592E88F0ECC2CCC64975A975BBE8398AEF5313EE2A7E99D47ED09ECD0EEEA60ABDCBE2EF596B64C6BC731A58C779C35B3FCC24A730D6D4C819E35F5E4F73E2986A0FF6B16C1EC2DF3F102859C1F3AEE28EB168B90FD3D323FF2AE7D9B0B556955641476914BE1F7B0A036B5E7C0092256050E61993FC4931EEE0002A054CDE7D0F5CADF7C3D4BD99EB1F0FA4E5862F91AC57E05253BD5D31F603B1345C346661EB52BA88ECA9F36F97E62A3DBA9C0E81D6CB26F68663E0F01B2FDEEB90351E4488A75B31696B5AB59A6DB6726D7CD7F5DF1790015528497948C0B197B05AB3205A1FC9EA4D8B9D8563B20C4056FEF6166CB11CD5794E759EA5AC31DB22518F739784E8D8C71640B8DBB410638627D3FAA9A8C2EB87BD3FB16B321F46AA10A81A6A8BB71DB3AD1BF493373DE6C1B6AABECBED666A57E66ACBBEBC439CCAA877982A878BA85E6FDBD6FEF2CE437F009B1DFE28609542F29441D7A067E6BCBB932712CCFF5C1EC980D2694669DC90E896484727A015E15D3DEE8D07F59643A101228C39FFE75F5CC52405C2914F1828D12A617C5C9FB3E2F8B871998E42DD03D7A23AEB4D8CEE6B890FABAB864800AAA6AD76F6B2E54A8E256BC30139E4AE740C41D1CB58AC5167A96F57657BCDB1C569BEFDF51037FFF7C8BE6BFB7B42350029EF5022630B6D25420E51FE82B88EB1E9FF4B7EBC2BFA1BF47231DD0D5BAB226CCA009CB9A14A9263CE19C4913846BE994A5830AB66D5ADA8889573E209251253334BB1345B4DCE7EE617F9E484F872203D43F4AB6D98F0B026913E591384957EE4AD5CD9C14849A953E4C157A5915BA01987BD94FEE100DB67EB8C5E7716AD58DCF8DDBA200AD6E462698555B452841383BD1BA686FAC217A6C29C02F95356387AAB9CEEDBD83E0B9DDB1D4088B0F335EE51270A232B56ABC8ED82667B3E1238CE1CED13FC4BCC988CB2E50D150308D356BCEF56E4957211D0DFDB74CD0B057CA7AEFC00E2EFA5018010D0578A505B220C3AD9147AB0F4BF85946BB50FCE493781BB739F4D933596DCAA47ADC7F22487C183A5BF95C7EC2EE2A815BF3EE92E1490BF18589219BDA3FF4B0A297F4680411F72213C0048BF7A90DDABB3A79B331B6F84001945A6871F6DCDC95CD171E6058DDFD95B533AC9F048F1EDFE401D0DD0A782910702C528FB5B32DB92180F26CA0F771E15298259BED012984E43C28A00EC49FCFFCBAB0DFCC8A2140F7DB25929B93CD3BE83E00A509BFA4880E1896A02AFCF4D9F4163FA99F83D973D2614590BEA7DDD1A1FAAB1661F7E2DB245044C500961F90E6BBA2543A30890C2A162030E9B8DA9F1133FA22C98994E056C98DC18EB066ED079F95EA20F58305BDA615E68B44DD8A7746738368CE9FD79E56721CE88A7D578D29908415315A55D652E00DC0FAF436CA49948E91B81195CC3B9FFB59414ABB01DCC1AA801B5926F00716A90D7A0DAD9FF3FF0D7A5763C825ED429D2B82DB9DC2B11C028CF5FEA3DC867409BD374F794B937A162DAA598B030364AC8124DC7DB89D8C6749E7CA082B9AB6C58B3738307C878997D8A2C00B898CC86FB24DE1E0F5B442C122C46823698246AB449707BA7A16BC7065396D00EFE313398F5F0A87FB05DEB912F27F03195F4D2046B247B5AB75895F78182D", + "k" : "4B31A7F645FFAEEF688BDED864F537ABB3645D69BD16AF7567F227C5CB26E7FC", +}, +{ + "rngSeed" : "2A6F7386B815366F572AEB6C79E272CC21B7095FE09575F18072C9D677DA23BC9C8A4BC393B7524604D299BEDD260C8B", + "pk" : "7665CD15516D767A980E05BA44D761FE17355C0AA302F3826DD25DA4CA4D044C299DAB608DA967C1E253BA77108DF51914A15541763F737A89FEF62BE1F7B4E1B8B77EB719A84377BE0081F7D71A6E881E15578603867855D87EC04B5F1F133368E43EC6282FE5EB16935A04EC9916CAA90031E40D98B0A8CED98979FA7742A20DCBE84C67223EB6925D7B1B12E07A47677B56E9916029204E91408635EBA66A6A844DE5CCFF6AA63FE15190030B8771101B456288B170BB117584C996C8515262C684A4718F8B369011865C756827D3038D62355F4C994A539815F4D6B6DC9455F4D7BA24501029170CF1AA3B0944574F6642C446A3F121CD08C7BB67E7239DA147E0E9C9B5C57B8F2182E00488341994F620C99978C818ABA5E4516EFE23690636CABF607C438CC288E944B3446B41A264B88C6E0371A08A1C02703C21A0BC5D73E6B95E7B5FB87C6CD43415AEB26F92ABAC0371B9A7A70EA51C88E12BBCDEF7C3CD3A4BCBFA3BB83606B25C85984021122400272A616FC4071DB20560654A7CA099A6D0754C43687D9657B1B816A04B8D4CB63D0E3765E228890E0907ACCB4734CC557FC96EF7FB6B463CC2FA5B73B7FC231F230028201483E66EFDD4570365865C08028F96609377703A2300F7E1B9F4939475541E0CDA2527B28ACA7374D1827206426637965870E9B86CBC115D9A04C0E73E8B7A866C277DA3C58E0D2094FA285E2D05AF7EF64F8EA6146EC4321395B7F30A6E52171BA28984B1E49726B48ED259638F6BACBFC5C2A4BAA3CC391F0BE917F7BA3A05DC911642A63DB03FCE58BC6FF92AF7616569D04415A26EFF8C271F9921DDD302787959F5397B70D7A388F7569E010CF26B67FB2C3A2A52714F5666B9726CB775C28A79A41531213E4766C9442FA06498F6D5A1816B7338F9AFB779A40F2670221BC5EF319786762FC78B1A25FC9DB8E362F11C9F374B04204940877BC209B25AE7F461C40A0193F66A95AB7DCC80AFED9402AB725DAB23C1ABEACAD633C461A26790865C21A960D338A7E485CB2B42A8B0963B8689C9D4287643B8685A341333DCBBD7637FA2671C1048638A547815F07B255AC115C8BC32B61A369128C60076C3464FDBE2C7C0BC5EF1E383DDD2AE8B0457410C19BA1C486B702A9048049E85CD1E7569EAC6B3BE8287EC9C195C3BB0B4F28952823832C55257D05EBD8A8BFF9C372095BE66359C9BA7384080A7ACD9567DB7905C50C36734CEC7519E8E57195247B48A65A1E34CB942D741D88B429D226A4097BEED271DCBC8A035606E056A89A8487197039ADDE30F78BB17148A4F0BC84BF1DC0D9057C97B028296B9260E601ED1A675BCA781C53BCBD6866B4AE108D059ADA7C6B8615195336C2DF2E71CE97528378B2FDC4B6501F2443FD4B6248429B67A4624769236E32C12E3116EF66AE2554F55C7BE15319E803B8CE0089D3C04B65EC8340C483B2AE4C2B8EC7DAA91B39270AB7EC04FEE436E1C008F61C46FA854363287573C50C63C3B1F94D52FEEBA13AEC5C926257592904B00CA8615469DF5539E8F4C627B11BE02E96D17189A80F37DA5D08DB81BAEB7C34B5C58AB3CCB25AF3C29CEC9364175B6BB4A04B5958079E18D5440BF24538598C1C548327980297EFE531D4C14A9360B8DCC173F6536B760B2A6FD59BAE262087989269C884A966C658017CE65D14519A2C61266B344F6648ABC0A657580130C6FA0F6565D8100F0532011945C3FA296DE184750AA931582A90E6BB9080971CDD6B470F68DB4E529ED61BF97F62BFAC5CB534C1570DB606CF0351E1866D7E199DC329D70316D7FD849D5C296D76A8DB20306BBAB609E7A9AC05C7896B150D6962D2466158F8697E532901E421D5EC00671344640623891A9221EA17EBCF6B290DC54359814A86658E2C0159C2374E1DC5F94DCB30CE01F3633129274585E304F0436396D66660F81C4CD273B94A3740F9C2FDD081BC309602A2CADD82AAD35A46684547D01C74C38547176113A697B49E6C98C1C017B25F817E19C2A0302D083DC5C74C4C38B6706E94C10D178369B375DF9C118130824FE99AC49F24A682AC23DE429F8C7A6D1A89C36F82F0A47379E7AAFADC744E1F20B9186C67784C3E6B823306896FCA303BAF61309CB498A216431862F00198C26AB6938487DACFAEEC6906AE45303EC7DBC2889A8EEFA511B82609B980DAD54EBB3E7091E9D", + "sk" : "EAD08FEB355828171B57C7A2C7328D0A736FC5B548308A22B8672C19C820192297E4762A8BEA6C048A33C0248676F2BF0B8393B34667DE1ABAEC665A886AC369320CE3188F66D6482CBB184CA6B189C70C531661E10784F4B5116BA5000D0B06714320D8B72EA88621093A0338E5B628F44194925219406517E36D14096B2CF5286F6981F8885EFC1CA4074B2D5FFB118EBA8F1E7AA83DC8AC1AA9BAD3B5CD257465BEDC943FDC9A88915AA573A2FF63BBC2E29ABE33CD919BCD725BB24486B847F2CDCDF36FDEEBC79C123151A02A7F4A42851C0C56E08CB5B6CD34309200E80E9344A229917DC5231E1608115F6120DCF177DA2BBFFCD8A389E0623C81BAF62A3033F99AC0027540C93D2071380D5AC60D894B85D18B20F21AAA5151657B34D5B125557832FDB09DD1C5BEDB2BCCE9D3C71E742923EA341B1657AC7908AE474CB7340D2F917513958EF6FC9BC4997A9A91662300A610868840C7B868AC0755E0A3C16A9B8F2343C2308E5E256EC7C60811822545EB20C3B8077AE771BD4313208584551CC2463691AB1AB4D5C112FE951BC0B9C02E867377DBCF41114D1553912400D065308456C1314641ADF2038A8625B6311C3B0F98AA1AE37CAF188F4448A6B5A78B746A0BCFBA1EA2016D34059A3DC34FEFD9261D5308B4E03C5677895822BC96441741865DDF787545B80C509259265976F187833959229CFAA95765A41837B210661A1E06137014B08039C88BE27B9D292AC3969BB9AC396FBCBCD3626F3EBC78FBD6462E673CFFC06D490B7DEE720E57130ACB1A1EDD9C4E64A2AAA2F92411D489C9EA00B68A7D30D347714059487B8F837C1BB5070260B2521642CEF747C602398902E33C6022AFF921A25E941955F81515A245F6D717D048A307020055E988D760B141E23A16F767260877B7551E9BC80828626829F94E20C4020A9A2688D1168CA5C3A9F752643A17237BA623B79F144A118F5CB41F466A27CCA78A208815538290B8AC4B086CF626932869B43E4B5477834606D9BF8E21295D6284D0CC72E64875CF526B8C380731880DD00C20FC2A31496274B94AA87AD54DE79AAC54995C951A1371DA09770B8446AA1E40B1CBCB57BA5F446FDF1260E9BCA676DC3DB9A24C5F99CC300B7B08C9ABF620BB03E75D0A5B872BC79CDE550F8B243940737CECC136918B61ADFA167553A005E0C2FA3190A895C2EF4A53FF90A75A879CB0E9855F2826AD7A9608579606904411B25AB46C6181203756A93C7A9BA7C2D3B862889FBD153A394791D3C481FB64AABAD314C7D637DC43BFF1A6BA7C031698F245C29294A533700145A904B17F9F30853090A0F68574B2B4A095033257D205A4E59AF580B362A5BE3C0311ABB22E665C9558F29EF456CB3ACA8D3A149A01118F7CE93D87BA57A814CB7E7C84DBC614FC2614EBE6892D6037DF49446D135A6CD05D224786D79AC87417626D831134B95D129A42BC4663EF09184C53C50DCC9D2DCA8EFC81254AA76A8E8370BB03CA7C30124D5C2247490C03488484CC110C9B1233E482899CA443F0A4B44A6FA073AC87E82688763AD72BCAE0DB87B1A5A629D27F8AA2B11793B47C82AF1486C97E41B7AA308E1A23AF4B68BE5C849625224AAA0CAFCFC3A21BA49E3BA168D16512A5968D5C0222696649D7674332F884F31259CF9B477D1445EAC17C4B11AFD2FBB6A68AAECE5A47AC5031E5457D32CC2A601B6B91257B64EA7C30B6B32EF7B949893A3AA14CA0D1A153B50BBA60398CC4090A9390F714541F34BB4C93A81F734809CC86B8FAB6BE5539C9F6A968EC207EB577B16116169565B86C21561936A467A435B88081E71925576350CC964F5B37FD73C421E7A076703FC308947CC5A3F2E21D328B8C23E32FC8F5C04FAA6D72395FC7C8B2D8FA72C6F35C9D81271AC34C0CA2685B5C5571F7B9B9245133C58B3BF155E6668315D0899BAC05DFB0B8661241F22772DD290BD963087CB94C9FA464788B8A87C637F327CCBD31A34328CB58B5C7F95AAF9F51AA5BBC284FB26B40CC438843A6AC41C82886A2236734DCD81584D8CE18184B90B22E62296ACE4191EFE679D4D52C12351E3D41BB2D815035D62380C45BF078025D4A12885AC092057B009D6C3105AC49641CDFE0C48BC41A6F14C0A5F31423EC378EA2098B48557665CD15516D767A980E05BA44D761FE17355C0AA302F3826DD25DA4CA4D044C299DAB608DA967C1E253BA77108DF51914A15541763F737A89FEF62BE1F7B4E1B8B77EB719A84377BE0081F7D71A6E881E15578603867855D87EC04B5F1F133368E43EC6282FE5EB16935A04EC9916CAA90031E40D98B0A8CED98979FA7742A20DCBE84C67223EB6925D7B1B12E07A47677B56E9916029204E91408635EBA66A6A844DE5CCFF6AA63FE15190030B8771101B456288B170BB117584C996C8515262C684A4718F8B369011865C756827D3038D62355F4C994A539815F4D6B6DC9455F4D7BA24501029170CF1AA3B0944574F6642C446A3F121CD08C7BB67E7239DA147E0E9C9B5C57B8F2182E00488341994F620C99978C818ABA5E4516EFE23690636CABF607C438CC288E944B3446B41A264B88C6E0371A08A1C02703C21A0BC5D73E6B95E7B5FB87C6CD43415AEB26F92ABAC0371B9A7A70EA51C88E12BBCDEF7C3CD3A4BCBFA3BB83606B25C85984021122400272A616FC4071DB20560654A7CA099A6D0754C43687D9657B1B816A04B8D4CB63D0E3765E228890E0907ACCB4734CC557FC96EF7FB6B463CC2FA5B73B7FC231F230028201483E66EFDD4570365865C08028F96609377703A2300F7E1B9F4939475541E0CDA2527B28ACA7374D1827206426637965870E9B86CBC115D9A04C0E73E8B7A866C277DA3C58E0D2094FA285E2D05AF7EF64F8EA6146EC4321395B7F30A6E52171BA28984B1E49726B48ED259638F6BACBFC5C2A4BAA3CC391F0BE917F7BA3A05DC911642A63DB03FCE58BC6FF92AF7616569D04415A26EFF8C271F9921DDD302787959F5397B70D7A388F7569E010CF26B67FB2C3A2A52714F5666B9726CB775C28A79A41531213E4766C9442FA06498F6D5A1816B7338F9AFB779A40F2670221BC5EF319786762FC78B1A25FC9DB8E362F11C9F374B04204940877BC209B25AE7F461C40A0193F66A95AB7DCC80AFED9402AB725DAB23C1ABEACAD633C461A26790865C21A960D338A7E485CB2B42A8B0963B8689C9D4287643B8685A341333DCBBD7637FA2671C1048638A547815F07B255AC115C8BC32B61A369128C60076C3464FDBE2C7C0BC5EF1E383DDD2AE8B0457410C19BA1C486B702A9048049E85CD1E7569EAC6B3BE8287EC9C195C3BB0B4F28952823832C55257D05EBD8A8BFF9C372095BE66359C9BA7384080A7ACD9567DB7905C50C36734CEC7519E8E57195247B48A65A1E34CB942D741D88B429D226A4097BEED271DCBC8A035606E056A89A8487197039ADDE30F78BB17148A4F0BC84BF1DC0D9057C97B028296B9260E601ED1A675BCA781C53BCBD6866B4AE108D059ADA7C6B8615195336C2DF2E71CE97528378B2FDC4B6501F2443FD4B6248429B67A4624769236E32C12E3116EF66AE2554F55C7BE15319E803B8CE0089D3C04B65EC8340C483B2AE4C2B8EC7DAA91B39270AB7EC04FEE436E1C008F61C46FA854363287573C50C63C3B1F94D52FEEBA13AEC5C926257592904B00CA8615469DF5539E8F4C627B11BE02E96D17189A80F37DA5D08DB81BAEB7C34B5C58AB3CCB25AF3C29CEC9364175B6BB4A04B5958079E18D5440BF24538598C1C548327980297EFE531D4C14A9360B8DCC173F6536B760B2A6FD59BAE262087989269C884A966C658017CE65D14519A2C61266B344F6648ABC0A657580130C6FA0F6565D8100F0532011945C3FA296DE184750AA931582A90E6BB9080971CDD6B470F68DB4E529ED61BF97F62BFAC5CB534C1570DB606CF0351E1866D7E199DC329D70316D7FD849D5C296D76A8DB20306BBAB609E7A9AC05C7896B150D6962D2466158F8697E532901E421D5EC00671344640623891A9221EA17EBCF6B290DC54359814A86658E2C0159C2374E1DC5F94DCB30CE01F3633129274585E304F0436396D66660F81C4CD273B94A3740F9C2FDD081BC309602A2CADD82AAD35A46684547D01C74C38547176113A697B49E6C98C1C017B25F817E19C2A0302D083DC5C74C4C38B6706E94C10D178369B375DF9C118130824FE99AC49F24A682AC23DE429F8C7A6D1A89C36F82F0A47379E7AAFADC744E1F20B9186C67784C3E6B823306896FCA303BAF61309CB498A216431862F00198C26AB6938487DACFAEEC6906AE45303EC7DBC2889A8EEFA511B82609B980DAD54EBB3E7091E9D42A9B1D5B6521A7A4527116AA7C38F6DDF99ACD4A7B9837317D99F83732BB7CAD375BC4FB24E98F1EAA01E50A588E96A2B26DAF9421437313FC7E4B520387050", + "ek" : "6679B55FE6904E4C0D51247214AC1B4405A65101096761AF59402DCE26603448254B4E264756187B2A9E22B25E1619A8CA3BDEBD65C53067A94E05F84F0D1717E6470AD3D746E5EE4CF2EFEA2E7EDE5B7D07FFC81A5AEF2C5F391648A1992A03E3904CA10F81351AEF03EC8A6CE513DE7A502279378492F740B39595E1BF30550E3926098524BAD36FFDD77FAD5C15A3233C09FB5049788D393AB2006766387E88DF20E66DFDD9AD71C616491E681DC1D211989DBF81E336CC5E0A3456F54E1BCA1139005E48A3128A26BCDD511B585A1CB584D4BF27A509BCFA61A4E635F4DC0D7D112C55CF9BEDC4ACB6B0CEC82284BC5061A143F330472DCBDBC92F772736FED65882B3B970891BD717843A37B2468CB099C7D6DD97E233FCE321DBF15FBFF9EA20FE2303BCEE1DF458E93328134EE15A56C44CB6AAF21E20F9C872866873D6BFCF97E36CC18C2A82322AF628BDE165CE8BB92AA65E31B999459CD3F0A3E490746A68891FD4A94B80B65464FCD786A5A1F5BA8325B17D1ED24249280EC102487BA5D37366F3701A187349C299FFE9798FFF340420A7FAB2693B2DD3820BCC1BCC7FC31B4DC22F27EE10BBF26D9C456FBAF38AC7500780ECFE67FC8DF68314F80ABCECA8EF1D5607B8B78577E5CA8CFD639A89B84116B26EB84FC5F5FA40165989F62F67BD1134A35B8CB2788FD5727305367963049FC73EA3249E9A587110759DFC569FA4186FDE9BE9FAF6B6A4042540F7CD56B50A8C4AE41CBCD4D3A9207F2E9BA3773CA4D99B497C79AE6000D1BB107223CCC1636B7ED427E7A2338C9742594E638EFC6124A7A8AA661BF0F3F4865EC95FA9B7BFD857FA0190334EE5FA8D9756B89AA233E6FF12762B11FCE6C56E30FF3F335DD1329E3438D9FA0F187E1B02CCFE7A61887848B1F0E50D425F79DB29ECE92513976E3E823D2CABCA84D6132390CE3EF2FE0C34C60FF8DF7FDB5669B8963FD2B397A035A27AB30DC84110F3DDE258934B8CDB70563782CBE588B832DE828510B3C797C7509B26C3BBA55DB7154C95D091311EC2F2A7751B821210E5B73C036AFF087EFD1473D7F71E9DABFE9A2F080949FA419C665E89968BA931D1A758303B3CC34E3377A3C274A3F523329EB9C343D890842F0F230C7F106159E626095591C4EEAF427E63CCA61157954CD89EDDBEACD7883352150D24357E3D64046A852FC03D860A506BA9D9D202437D30F5B8B06203CED45440A3C91C250BA5BA04A8A263D10574A24D88B9E356B787E12766DDF3F9BC420EE0D7A46B6AFF3F18B56787019F0FF71F4209B0ED53067B58125D01B49468BF082810974B128B4A6B7C380A307FE50372B7CAFE5BFC1A0C178B5D26CF199313EBCD88629C9426F9990A7B746781F0736BE9B4AF4298D88E0ECB7842BB5F86CFD2E1F7F3BFC039BBB207976E76388B148A26D43803C08A21D289A4E1D371946F52D98FE9E0FE1A6ED6A45491C06A8B6427A14F4D7B38C704375950BFB0CCAE45612F1C60F0CF89C3B63E8ED985AC7083BEFA6AF83A64789EB60907502D92B0683021051181F44A23F8770EFE01569942E35137E8091925E4215A20F0914E3D156D95D3D25789050ECADB559DB6DD08E5B6939EE4449151A4542CBB8C3BDC9B6E6F167F62699AD6437CA4C2DC43D787CA29918B03C797F398E0716310A8CEC1C5D02C099E7665E9651BB3451D4D720F39BB1BE6CC868740133FA8B2654B2FCAC3C1A4230AC9A39D25D2C28ED23A717B721E69079A142108AD45967CA4B5C2F340402ACFFE209CA450E9CE431BCF2D422E2347FEBEDD136DC3CDB468B2F01B43B45694ED2FEC3AB4F06A85EA74C752A3E12B64E218DE94029BE5D1969E5769CACE27B846B3DE945F641B81DB1AA8A840DC5FF688F834C0A0D2D03A6ABCE23FCCFD822E2AAE4E32CC49257558DA41636AFFEB566515067BE0A8DE900EBD2DCA315DEF2D115353E6EC36C4E2E8212917C5592C7BB6A8CA1D7B674F947BFF7E71389E276409E9E092B42D2B53D370CE6F4082E669EBB6BE25485440CA01772A83E2CBEECDB945F59F12D2421ABAC939814F40D76575BD47F5B1540F5CCAC85735566F4AE69E839CF98061842AB0B122931C43402C9524E1506C0887A3014639D3BDE1E70C1D0B6E273F8CE055CD40220EF330A080280F0A86C1224C3755EA58921C7857B870D68E0E9CD68A079417CFB786B1FF929E7F26CDC7", + "k" : "13984718966CA2568BE5CD0C2DB87EDD376AB96ECF6E3F46EE949A2642141709", +} +] diff --git a/Tests/CryptoTests/KEM/MLKEM1024_BSSLKAT.json b/Tests/CryptoTests/KEM/MLKEM1024_BSSLKAT.json new file mode 100644 index 000000000..f1cbd6061 --- /dev/null +++ b/Tests/CryptoTests/KEM/MLKEM1024_BSSLKAT.json @@ -0,0 +1,503 @@ +[ +{ + "dz" : "7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2d8626ed79d451140800e03b59b956f8210e556067407d13dc90fa9e8b872bfb8f", + "pk" : "537911957c125148a87f41589cb222d0d19229e2cb55e1a044791e7ca61192a46460c3183d2bcd6de08a5e7651603acc349ca16cba18abb23a3e8c330d7421598a6278ec7ebfabca0ef488b2290554753499c0452e453815309955b8150fa1a1e393386dc12fdb27b38c6745f2944016ec457f39b18d604a07a1abe07bc844050ffa8a06fa154a49d88fac775452d6a7c0e589bfb5c370c2c4b6201dda80c9ab2076ecc08b44522fda3326f033806dd2693f319739f40c4f42b24aca7098fb8ff5f9ac20292d02b56ac746801acccc84863dee32878497b69438bf991776286650482c8d9d9587bc6a55b85c4d7fa74d02656b421c9e23e03a48d4b74425c26e4a20dd9562a4da0793f3a352ccc0f18217d868c7f5002abe768b1fc73f05744e7cc28f10344062c10e08eccced3c1f7d392c01d979dd718d8398374665a16a9870585c39d5589a50e133389c9b9a276c024260d9fc7711c81b6337b57da3c376d0cd74e14c73727b276656b9d8a4eb71896ff589d4b893e7110f3bb948ece291dd86c0b7468a678c746980c12aa6b95e2b0cbe4331bb24a33a270153aa472c47312382ca365c5f35259d025746fc6595fe636c767510a69c1e8a176b7949958f2697399497a2fc7364a12c8198295239c826cb5082086077282ed628651fc04c639b438522a9de309b14b086d6e923c551623bd72a733cb0dabc54a9416a99e72c9fda1cb3fb9ba06b8adb2422d68cadc553c98202a17656478ac044ef3456378abce9991e0141ba79094fa8f77a300805d2d32ffc62bf0ca4554c330c2bb7042db35102f68b1a0062583865381c74dd913af70b26cf0923d0c4cb971692222552a8f4b788b4afd1341a9df415cf203900f5ccf7f65988949a75580d049639853100854b21f4018003502bb1ba95f556a5d67c7eb52410eba288a6d0635ca8a4f6d696d0a020c826938d34943c3808c79cc007768533216bc1b29da6c812eff3340baa8d2e65344f09bd47894f5a3a4118715b3c5020679327f9189f7e10856b238bb9b0ab4ca85abf4b21f5c76bccd71850b22e045928276a0f2e951db0707c6a116dc19113fa762dc5f20bd5d2ab5be71744dc9cbdb51ea757963aac56a90a0d8023bed1f5cae8a64da047279b353a096a835b0b2b023b6aa048989233079aeb467e522fa27a5822921e5c551b4f537536e46f3a6a97e72c3b063104e09a040598940d872f6d871f5ef9b4355073b54769e45454e6a0819599408621ab4413b35507b0df578ce2d511d52058d5749df38b29d6cc58870caf92f69a75161406e71c5ff92451a77522b8b2967a2d58a49a81661aa65ac09b08c9fe45abc3851f99c730c45003aca2bf0f8424a19b7408a537d541c16f5682bfe3a7faea564f1298611a7f5f60922ba19de73b1917f1853273555199a649318b50773345c997460856972acb43fc81ab6321b1c33c2bb5098bd489d696a0f70679c1213873d08bdad42844927216047205633212310ee9a06cb10016c805503c341a36d87e56072eabe23731e34af7e2328f85cdb370ccaf00515b64c9c54bc837578447aacfaed5969aa351e7da4efa7b115c4c51f4a699779850295ca72d781ad41bc680532b89e710e2189eb3c50817ba255c7474c95ca9110cc43b8ba8e682c7fb7b0fdc265c0483a65ca4514ee4b832aac5800c3b08e74f563951c1fbb210353efa1aa866856bc1e034733b0485dab1d020c6bf765ff60b3b801984a90c2fe970bf1de97004a6cf44b4984ab58258b4af71221cd17530a700c32959c9436344b5316f09ccca7029a230d639dcb022d8ba79ba91cd6ab12ae1579c50c7bb10e30301a65cae3101d40c7ba927bb553148d1647024d4a06c8166d0b0b81269b7d5f4b34fb022f69152f514004a7c685368552343bb60360fbb9945edf446d345bdcaa7455c74ba0a551e184620fef97688773d50b6433ca7a7ac5cb6b7f671a15376e5a6747a623fa7bc6630373f5b1b512690a661377870a60a7a189683f9b0cf0466e1f750762631c4ab09f505c42dd28633569472735442851e321616d4009810777b6bd46fa7224461a5cc27405dfbac0d39b002cab33433f2a86eb8ce91c134a6386f860a1994eb4b6875a46d195581d173854b53d2293df3e9a822756cd8f212b325ca29b4f9f8cfbadf2e41869abfbad10738ad04cc752bc20c394746850e0c4847db", + "sk" : "433a70ee6950f9882acdd5a47820a6a8163708f04d457c779979b83fe117224701490830386637da332e74b1aeda0b2f81ca4f9bb2c2b02b0cfd680c11482f335acf7b9139b5b88a34e3542c6861377545983343cd829414e47864212e78f855f52390379acc3a62953131b63ee832adb3bf4bf58e247349b5e097e55abe497b15982373ae732e0439ac67d05c7f037c8a739b18140e144c851dc9611f4bcf04f3a2093c197bd63bb5e6190100545ff81db7fccddd9a324b0bac3c2c2382284058f08b961952c094019c10be37a53d5ac794c010a9d0821f15027a1c419c3c71c9a1d28aed02597ab79b875394626ba39adc090c3a90cf75871a65275eb1c5b03372e13a1a23d0cf9374111f80cc83a905622b83fc513971ec8419f0880c3067633671b09b5456ab6057936d19a4a2a267911b000a13956fbd493821da072c04642b0c20da6cc0d9d864a39365dfd64f10187825fa33250749cbc0c905d7b1ff3cae2412bf86b81a817b86baa30edf7862e5f6bac98726e56b3cec60664caa2a7df670c5e207dfac03824c89897cb490eaa76521222c86205169c91c329c4a184d78721af836ad4db0ca78464d4171473012b7d183bafa627585c64be3809d7e6004cbdc79a5460f0ad677cb716512407d3a619ad09543b739547472a706b317a509be5d861fd66c7d0ed94cd5004795c18159e3a33d798711525f1635a68428172923249635aad032b9e56664bdd48ed24ac75c6468d1903e471086c5f1567e831a0508c539632591ab577d324a82429725809950761d8434288c14034f1c06c1d0aae09a71c740a55701c28ff84499f2bb18b6628caaa3fe75ac4de04c6f913900d86c88126252a17c4d303991db0287120881bb88478aaa9af9bc53d3729843858fdb4648059cac82c1a10878ba39823b041bd0e258487b56cc8a3220c1a58bf66a172b5b9a0c632d674eae885a015c4e37ba073680bede7534f3e34b6050c86b21c3c090941f23b7f6731e2bda0e6ea4646771cec572b98ca0a158919adbeb84ce585ff9f25ebdda6cb6f07a8f811232607e7217bb039babd0d91934a8594059c9687723c04381bfd627a10517f5f4bfc77777aa2671ae124f2b7a5f4d5614029197e6586fa8c17e0ad90781bc7bb19a772d5a4efe32cac89b76c42a5ede9bcc20c1898c08a5b0c07e478b1bbc226efad15f2ac737514b8c6149810779222416537ed00daeab177e903ead6b4ac42370af1b1f50ebafaa1c6e647bbacce72c7d0b88aeb0b06fc1a45457a9c187579bf184579cc351c43dff942605aa5604fc85fc5583f6f1496fe61d70d6cde2327fee713d86f29b3afcbb54e9a92a33a6c1ea6ffa309566b0686233c0f3b1c3144890e4f0829a6099c5749cdec84328ec2cb64a7385a761d64b3a23c489343343b97723ae78c7d805458e1620f0292897691704cb76e3b0b281a83cf64490498cbcaf04802416b33c565171d772d3b9354037587629ae14a5c5031ac36671a0d0c91cc0b4cd69d8402e33b9bcc2bbaf6b971e303fa137be232598a4999bc012574c81651b38b38396c1c365303ad25d49fc6b689951a1cc4c6007613065495f97910f9735d4ea4e442acb2fabaecfe1adef0667ba422c954a05d1b6167a263e1275c6ada8385965304b30324040542cf5a451bcafc74788be3b9b9fcc45d4790e2d7335c60a14f0a49d13053f2626a627ca19553cb336a2cb4a455d8ef3989491472ba0051ef7416e0bbf1a6108fa07c161548e7c62331ae5a2b4e4a108a51093d3150821a2fb547170a1b73c43c550c6557a4048a58a2cd77a244234b2235175a0897d5061b4613482dc136414048c11db37eae0a5df87c19314b0e82397a0d338dc21538af36149d93f8b1a11c53bb5def8b7a2cca3362b7fe3a1408a2547e209058c673a7566c26123a6d8b692a5f33ebdcb2624b79d877bce5fa14e42e83faad82e9900553a3c6045ca329fea4a506558c491b6a616c6fd400b42136f44cb0d0257650819018d3c568ef6c60c6c409e70a829287108c1b6a4d32f76e5cc4d104b02438ef7a467912398ea9c7cbd9981589a341897687b516a13307d66c068c444b4b949a17412413315ccf49b99980034b5b8cfdec4a60b9c1e7455aafbf3a757346990cc32b0599ba217a6c5fc39537911957c125148a87f41589cb222d0d19229e2cb55e1a044791e7ca61192a46460c3183d2bcd6de08a5e7651603acc349ca16cba18abb23a3e8c330d7421598a6278ec7ebfabca0ef488b2290554753499c0452e453815309955b8150fa1a1e393386dc12fdb27b38c6745f2944016ec457f39b18d604a07a1abe07bc844050ffa8a06fa154a49d88fac775452d6a7c0e589bfb5c370c2c4b6201dda80c9ab2076ecc08b44522fda3326f033806dd2693f319739f40c4f42b24aca7098fb8ff5f9ac20292d02b56ac746801acccc84863dee32878497b69438bf991776286650482c8d9d9587bc6a55b85c4d7fa74d02656b421c9e23e03a48d4b74425c26e4a20dd9562a4da0793f3a352ccc0f18217d868c7f5002abe768b1fc73f05744e7cc28f10344062c10e08eccced3c1f7d392c01d979dd718d8398374665a16a9870585c39d5589a50e133389c9b9a276c024260d9fc7711c81b6337b57da3c376d0cd74e14c73727b276656b9d8a4eb71896ff589d4b893e7110f3bb948ece291dd86c0b7468a678c746980c12aa6b95e2b0cbe4331bb24a33a270153aa472c47312382ca365c5f35259d025746fc6595fe636c767510a69c1e8a176b7949958f2697399497a2fc7364a12c8198295239c826cb5082086077282ed628651fc04c639b438522a9de309b14b086d6e923c551623bd72a733cb0dabc54a9416a99e72c9fda1cb3fb9ba06b8adb2422d68cadc553c98202a17656478ac044ef3456378abce9991e0141ba79094fa8f77a300805d2d32ffc62bf0ca4554c330c2bb7042db35102f68b1a0062583865381c74dd913af70b26cf0923d0c4cb971692222552a8f4b788b4afd1341a9df415cf203900f5ccf7f65988949a75580d049639853100854b21f4018003502bb1ba95f556a5d67c7eb52410eba288a6d0635ca8a4f6d696d0a020c826938d34943c3808c79cc007768533216bc1b29da6c812eff3340baa8d2e65344f09bd47894f5a3a4118715b3c5020679327f9189f7e10856b238bb9b0ab4ca85abf4b21f5c76bccd71850b22e045928276a0f2e951db0707c6a116dc19113fa762dc5f20bd5d2ab5be71744dc9cbdb51ea757963aac56a90a0d8023bed1f5cae8a64da047279b353a096a835b0b2b023b6aa048989233079aeb467e522fa27a5822921e5c551b4f537536e46f3a6a97e72c3b063104e09a040598940d872f6d871f5ef9b4355073b54769e45454e6a0819599408621ab4413b35507b0df578ce2d511d52058d5749df38b29d6cc58870caf92f69a75161406e71c5ff92451a77522b8b2967a2d58a49a81661aa65ac09b08c9fe45abc3851f99c730c45003aca2bf0f8424a19b7408a537d541c16f5682bfe3a7faea564f1298611a7f5f60922ba19de73b1917f1853273555199a649318b50773345c997460856972acb43fc81ab6321b1c33c2bb5098bd489d696a0f70679c1213873d08bdad42844927216047205633212310ee9a06cb10016c805503c341a36d87e56072eabe23731e34af7e2328f85cdb370ccaf00515b64c9c54bc837578447aacfaed5969aa351e7da4efa7b115c4c51f4a699779850295ca72d781ad41bc680532b89e710e2189eb3c50817ba255c7474c95ca9110cc43b8ba8e682c7fb7b0fdc265c0483a65ca4514ee4b832aac5800c3b08e74f563951c1fbb210353efa1aa866856bc1e034733b0485dab1d020c6bf765ff60b3b801984a90c2fe970bf1de97004a6cf44b4984ab58258b4af71221cd17530a700c32959c9436344b5316f09ccca7029a230d639dcb022d8ba79ba91cd6ab12ae1579c50c7bb10e30301a65cae3101d40c7ba927bb553148d1647024d4a06c8166d0b0b81269b7d5f4b34fb022f69152f514004a7c685368552343bb60360fbb9945edf446d345bdcaa7455c74ba0a551e184620fef97688773d50b6433ca7a7ac5cb6b7f671a15376e5a6747a623fa7bc6630373f5b1b512690a661377870a60a7a189683f9b0cf0466e1f750762631c4ab09f505c42dd28633569472735442851e321616d4009810777b6bd46fa7224461a5cc27405dfbac0d39b002cab33433f2a86eb8ce91c134a6386f860a1994eb4b6875a46d195581d173854b53d2293df3e9a822756cd8f212b325ca29b4f9f8cfbadf2e41869abfbad10738ad04cc752bc20c394746850e0c4847dbebbe41cd4dea489dedd00e76ae0bcf54aa8550202920eb64d5892ad02b13f2e58626ed79d451140800e03b59b956f8210e556067407d13dc90fa9e8b872bfb8f" +}, +{ + "dz" : "d60b93492a1d8c1c7ba6fc0b733137f3406cee8110a93f170e7a78658af326d9003271531cf27285b8721ed5cb46853043b346a66cba6cf765f1b0eaa40bf672", + "pk" : "938a454364cf10a4c719113a23b242bc013962f13421ec0686e32ccb80840749643eb4b5cc4182cee2366717cf77f97da296a185440113770b6f755bc596cbbce021e94306b1e4ae437ab7dbc29527142a9223a8a7cb269391cad8f70c6cf666118830485ccaebba1bda242176559904713c6722c413d5c2b9c2669d58138ed5b23506a71c6182af6939dd40c51d678639238c8c071384c1256ee6a307475bb72bc93976c8976bb89c736d8fb19580cacb1f335b97d16943c0706f78095408cdad77a9fe967c4bca738960b3a3c171680426528a21578b79b226bda19a9bf132998a2149c463932d630b0f131e8096be462080e6d17107704f3b0cc90c3908cd645268375056e6072425b51a46c27a48b9c0db67b025a58ee37b44794430f3ae6cc74e1673c2b1d4b29db5370f590eaf6165e5806376f6a7d4825c74038792683f38893464103d82426593f366f96b023008be21956e6be8a4bd612d4f85239d62ab6c39069aa210b47b37ca85394c19327e5303cc9c54a5c63aeb104dacf67a1c1c3142710dcf682edac82471ba98c81a552ad2541b7338b2a0ce41354ccab879f549cfa58995eb8c64a8b30b6f384ec2e04dc1a11ae04c967f744024d70da780516777a1b1715f22cb1eb3511f5c4c99ce577836489a0f813a99a622390b52e4757843c772f6e75f470305259833b3993919f3aca66563f3eb7375f5883cfca72398b049170ebf0997ff277e44501fb0e83d0c5ca6c701048180ac68d857e0dc5d24b1628433c737b8808c290839d42c6a322250e0c22b81b4c018260d288c47976bcb84bcd0856c40448ca40b723b8144837965ad46b521ec4b405c28589b8536621a10678a75233e2cd59bc6e03f49d93925c5bcc133bea39a7e21907a19840c80225f1f154c270a4bf0206a16c241bf42cbd351055adc8519d38fc9d3b976e2144909053c5843c36b7b247a6ecd04c9d792a6fae968cbe11713592b287cc8b07b73c334bdbcb91d05c7ae4e86aa7547b4cc6403504acaef4c6e5b758f4e261c7624337000c187648325f36ac8854d4a8a1c2c732a0811b39439340e23c33af0ce5090ce800070306834321b5af9e4be13b22ea6655da11427f995a115dc86cda737aa99078407b9f78b914e831a6bec2c85f922f972bdda971b66761045813a852a0fd990136840835f8b5a72c5c8e8a65ce8d3ce957b06698261160031597a29e3388a4f5a5f0b96b70481a2e5738d3a50189496c75a856643899947c955be8871e808030a5757d6b46079454b54d51557cca964379bca5a8191698275dc51cb164f8e508fdaf480031a28afb1c9ccc65da9ac1cdec625131c6630188ffffbcb726133ca563da640c76a6c24105502ea3c24b918c5b818121cc68e2f1b62112a41594a6359876b91d058fd66861b7633d73cc7226b8debebcf90fcc390f761360554acf013ad03911b49b641c73687f4a73f8c290a2890c02c56e2a6567fb03826353d87ea41369673e1f9b920b36203cc9aa464192d01b6d859307927a629a24b34132cbceca487a0cb3c7442aba47c4a077fbe7442c2a4221a200a93e726518830b11b690f0497ac0851a5b27ea20253065a9ae7e6567fc26500edb11346955aeb2d9c6c228f1644f21b34e3694c05016284bcaf746ab6344a10eec87cd0f76a611ab64ec86288c339294aa15233abfb680036d2155fe77363530c3ee0c4b8b74a54e9a2453ca081d01f9626867632870b178d25b831fd133a2ac0596e688652c1772e2979305c5e2a10949bf35bdc08cecd6771b7f659b61960a45054998472163c21d31024c0c24972d5b145608c1044718f60894bf5875a453d4a7c4569c63a2b38c2db6a4fb8dc9289610ef12754f37cb4dad3b66e135d1f75759622cd7fa03c4ba81d71ac9938c9a97839a12d7a4622943c381a048edb26c64926b3a807b644aebc9110c54b06d4ea1cbf6462a55b31c7f5202cca8b7c698d9559276a1a3963cc56dd26ce3c051167f299d80c3a8ee894f134567cea1032c845d79ccd95313f04d6459d1ba72e00cc604365a9c5c5185005f17a0397a559a0b28f31b41a5e0948c81501e902b9cc253f6eba88172bbb92024984fa99c5bab08dc01504556aabe8c81bc99c56fc771ddc85d37b7c50182345e189267934564aa9dd80bcdc25b127f1244763644004e5eaf06b095b892bae095e0ba7f9d2700a50", + "sk" : "1df76d46867cd8c5b94b3666ccc8c368ab45c71abc8df2cf74fb3070095902282b41a698b405947354664df4727af16b549209329623a33889b41747d56594b842be87f40aabb37bb457c935c5a2fd3801694433fbb545b35b23b6d17a8d9aaef6d31fefe99d8c7c2030989a285900d8fb78ed65c97428c25459195890406dc878b2a98993664fecc960237a2326530105f78bb0d04a00030e6ec0a258d803a00844753b8bca802ad335648f348fa34905681a72a8e198206613dc285101499413267a5588bb4331120213bf3dcc0efbd80b70fb08bbeb6067e617d380b804bb6a4e745a97cc8342c5cab4208390147bf1b87c6c4430d8b443e45c101ae65fd9c43798a082aca969b8171b8794c3e442096a139496b9a11e9821afea868107006e4a283f60a035485914e9901e843013d36c36b35318522cd69c1df78acab468336ff89ca4a787363b51f7b62468d974506a245049c0ec7092e7c9368e18c313297a92a292926902d34b0890192b50cb3772a797ea6918d380b1752b8e1e0a36b41a2f865b73a8b3a36d68446ada396ae000898035c40cb4bbc76abe0240392372fa6bca942c4112c86eaeb60a548326868b80af6a8f9dc506bf9474641b7032994d641a3d1c45b8df7c2fb3301003f6481f00622932309e860fcca71f7fd6c38242cda0a4a589e4bb791294a6aa9f85959e91b0b5424a61a974ce29d87c7c0c1b0d7ab804690e285952cd95ca150097a7c6aba8c878a87b883c52b2d076762fd424fd76c074873fafa03d0d98647e76b4fd994300850093c2529b3b599d33692935ba09e4156052916833bc0c13836110bc134c4ae465acf1730a01e261f2d3b1156288f54573aa6cba8d161e533b50c56a2ee0fa04676b83489b742d492aa6650fd658baabe309a860967a726a6cac46bdc8893215160f97c3db16cde48a684ba64fa34a7c9720935711aa4e3bb0fea7b14f4c9a889b9a45024cdbc09f3a971854b5ba1f940712913284516614277a1df04a6a583873b154f4e68151dc8ecb86b5f58842fd31491e4422db7b7059268030c60f4ec3bc1b37b076d157c2c014dc52a9909505d99180b259cfd3204a22825ba2051e9dd4376e7502b305a208a98a2bfba19ad9152d3853acab2c48551ee998c84649c2c8e7b9140bc67cf839c1a49389c0aefb2120ccf6b7cba4360921a0e31b7eec4335926788af441280b4accad52ae014493d15caa20246cd4434639303fb5603f282b8a6f0b1fe41098d28c73f0b74653cbe673340158492d6517c514218dfea8bbb4aba8f741c0820c076a23b170456f8d8598211cbe6a37c15e6c38c905b8ed8430db09982ec4f6c882632383adda285a08bbcbe219947e96017c8bf3b790dca66b868ca729df23a8125bc103b5eeea6cabc6472a07281de58cfbbcb319a7ab27d3a5f5c268bb0ac6587e7774a2a437541a28c84a8c1b986b1a7204fb613cd0067ec26458155923248bf0c641fbb4c4219941414895f60712928fa7275f7a99ed20e6aa7a2e3637d1fabbe65db9dce36b1df2656e0284d3c5b4c2d789802c97515071a8f7c31b5501f4ff492cefc8c7f6b0937da9e02dc6a99493ba7f7269a32b610127f89b6b94020bf58a20ecd7548009d63331b2f4908499b400357c30f1a67694de351ff5cbb4eb553e4d523568542a0e241a6ecc8045caf295bcb12c55861f7b5e5151e5f4cba28d54859619dc04b96b6b3a2a2436d921bc4560a4c4df68a34413733761b8adb790fd95a6479351bbb7cbb17a528ca14f0c31eadb195c86397beec61ab8b8ef9032d1ae0c669fb1203f554d2575e25e45bca0767b0821740eb7aa749161e485152b68d5a8c0c53db6ba6472a34016fd9067d07e8745e66785949a4be88573987aa91da5fe01387b739415b0c5d03caa04089812c85829dd43e9b310ff5887561c7aaf64b1368862050b157e0bcbfbb659934466a3b1611633619d7c2855553b4c3934c8f410e7a097a5b591a76582aef355c57a076a00905b6474626e33ac9dcaa77e8a07bd9509f5baf27bc54bfb8890ac4210f8bb45342350acb61c34999371614d85c7cc49c92e54bbbc94389663053b74088984b1b2d6c335c000ffcd21c9a45a8d377638f954a5e132563f62347614f10d103d0a58408867fec69c50f595c938a454364cf10a4c719113a23b242bc013962f13421ec0686e32ccb80840749643eb4b5cc4182cee2366717cf77f97da296a185440113770b6f755bc596cbbce021e94306b1e4ae437ab7dbc29527142a9223a8a7cb269391cad8f70c6cf666118830485ccaebba1bda242176559904713c6722c413d5c2b9c2669d58138ed5b23506a71c6182af6939dd40c51d678639238c8c071384c1256ee6a307475bb72bc93976c8976bb89c736d8fb19580cacb1f335b97d16943c0706f78095408cdad77a9fe967c4bca738960b3a3c171680426528a21578b79b226bda19a9bf132998a2149c463932d630b0f131e8096be462080e6d17107704f3b0cc90c3908cd645268375056e6072425b51a46c27a48b9c0db67b025a58ee37b44794430f3ae6cc74e1673c2b1d4b29db5370f590eaf6165e5806376f6a7d4825c74038792683f38893464103d82426593f366f96b023008be21956e6be8a4bd612d4f85239d62ab6c39069aa210b47b37ca85394c19327e5303cc9c54a5c63aeb104dacf67a1c1c3142710dcf682edac82471ba98c81a552ad2541b7338b2a0ce41354ccab879f549cfa58995eb8c64a8b30b6f384ec2e04dc1a11ae04c967f744024d70da780516777a1b1715f22cb1eb3511f5c4c99ce577836489a0f813a99a622390b52e4757843c772f6e75f470305259833b3993919f3aca66563f3eb7375f5883cfca72398b049170ebf0997ff277e44501fb0e83d0c5ca6c701048180ac68d857e0dc5d24b1628433c737b8808c290839d42c6a322250e0c22b81b4c018260d288c47976bcb84bcd0856c40448ca40b723b8144837965ad46b521ec4b405c28589b8536621a10678a75233e2cd59bc6e03f49d93925c5bcc133bea39a7e21907a19840c80225f1f154c270a4bf0206a16c241bf42cbd351055adc8519d38fc9d3b976e2144909053c5843c36b7b247a6ecd04c9d792a6fae968cbe11713592b287cc8b07b73c334bdbcb91d05c7ae4e86aa7547b4cc6403504acaef4c6e5b758f4e261c7624337000c187648325f36ac8854d4a8a1c2c732a0811b39439340e23c33af0ce5090ce800070306834321b5af9e4be13b22ea6655da11427f995a115dc86cda737aa99078407b9f78b914e831a6bec2c85f922f972bdda971b66761045813a852a0fd990136840835f8b5a72c5c8e8a65ce8d3ce957b06698261160031597a29e3388a4f5a5f0b96b70481a2e5738d3a50189496c75a856643899947c955be8871e808030a5757d6b46079454b54d51557cca964379bca5a8191698275dc51cb164f8e508fdaf480031a28afb1c9ccc65da9ac1cdec625131c6630188ffffbcb726133ca563da640c76a6c24105502ea3c24b918c5b818121cc68e2f1b62112a41594a6359876b91d058fd66861b7633d73cc7226b8debebcf90fcc390f761360554acf013ad03911b49b641c73687f4a73f8c290a2890c02c56e2a6567fb03826353d87ea41369673e1f9b920b36203cc9aa464192d01b6d859307927a629a24b34132cbceca487a0cb3c7442aba47c4a077fbe7442c2a4221a200a93e726518830b11b690f0497ac0851a5b27ea20253065a9ae7e6567fc26500edb11346955aeb2d9c6c228f1644f21b34e3694c05016284bcaf746ab6344a10eec87cd0f76a611ab64ec86288c339294aa15233abfb680036d2155fe77363530c3ee0c4b8b74a54e9a2453ca081d01f9626867632870b178d25b831fd133a2ac0596e688652c1772e2979305c5e2a10949bf35bdc08cecd6771b7f659b61960a45054998472163c21d31024c0c24972d5b145608c1044718f60894bf5875a453d4a7c4569c63a2b38c2db6a4fb8dc9289610ef12754f37cb4dad3b66e135d1f75759622cd7fa03c4ba81d71ac9938c9a97839a12d7a4622943c381a048edb26c64926b3a807b644aebc9110c54b06d4ea1cbf6462a55b31c7f5202cca8b7c698d9559276a1a3963cc56dd26ce3c051167f299d80c3a8ee894f134567cea1032c845d79ccd95313f04d6459d1ba72e00cc604365a9c5c5185005f17a0397a559a0b28f31b41a5e0948c81501e902b9cc253f6eba88172bbb92024984fa99c5bab08dc01504556aabe8c81bc99c56fc771ddc85d37b7c50182345e189267934564aa9dd80bcdc25b127f1244763644004e5eaf06b095b892bae095e0ba7f9d2700a50cfb6fc18d6419f5438a0573693f421d3793e5ddf3d846678552aaddc19265946003271531cf27285b8721ed5cb46853043b346a66cba6cf765f1b0eaa40bf672" +}, +{ + "dz" : "4b622de1350119c45a9f2e2ef3dc5df50a759d138cdfbd64c81cc7cc2f513345e82fcc97ca60ccb27bf6938c975658aeb8b4d37cffbde25d97e561f36c219ade", + "pk" : "a1a341b578b4765c4649e6bfaf5c8b2ad80de5200e4dd30da0b693f5ebbfcfba9f0ad2ad46576a7a06b65de6bcdc432b6a753f3a6326a27073436483aef170b8649e2ca022497329d071af4c25968cb0521a118aec41cbeab013786a1c2984cb2c649da0fc94fdd880fd3a05239b84ac053ca0f822e4c94ebfe1b6d6898da03b02e455467af6c89db7225ad653a5ac0c8e165f3b9b68b01270ef0ba7cc56322d5c671805b7d333b899abbac120c010033f3064647e4a387649c272a32c2dcc2fd62793d8689cf59619f43c87fdeaaebcd4c3f21483863563ce8442a7f581009410b3c506146390fcd44d0f918b2903940a321c66700ca4e205d4501ecec23a4d17157ce4a0bac562533273fb8071ddf960217696ccd98a59e6c39dac5cd185a0793a9190e25a0460837d07d020d72b5c5ba9840b0940832fa3a483aec99d0d629cfd67a1ce77766a23b2349947968c238d0126f6ab9422b97d6dec5657a20a683544ba07971bc773a5da90bf471eaf12310283944c723eb1e0600eeb2464bc71de7233ebfb7be64202ee21088222a48ba200f04b6bf6a1c7f6404295764e6fd857d747cd985b07f4d83f8b13a901ccbff7b01e21b8789c05b635bcc14c8128c379bdd52029efd660468a34512bb78da224fff9a223371e457333ad464c6fdba4f6c5451b585583655182691f6ee817cf81ce6e7a5cc6b9cacee275c473ae1c58aa38e43de50796f22475fca44270e3a46fb5b8bdda74e3e05b88210f54f36e79fb05becc76805b716154a6e2346b0f4cac241748fde93f325b4f82f3b681136aff8056bc7304ef22652f1679c816032bc35db68b64b2848351da88df89166707b194cb4759e6761032aca4b7a54e8064f5755d36288fc5061072da1ec35a8491396c9406446060347361bed860b028b57250f0187f45a204fba678f587ae031ac38480cf4c3fff90188d925bd4c7c6bd0b758698bcde97ce3958697610ce05e4abfca60eac13b666732e8262b36b7447c0c93f91362c519337052865927a9862d2c1ed186b411554275a24dc9738751a4ba243bcfe46109212b711aa453a35b09ba20ab405b6f0f3457321b24017261b49923225b3620678c4f474515396113880df463138abc3e820c65415c593d74c01e5136150b02f1ccc55a6c1e7e9b121588362d784c3e85658532331bb596682377c752e7c259608b629e74a5a470bad77d3c0672b23831a217c1ac82b94a82437643807681cc1684098b86de031440a79378a229bd902f2996f326a0df16354778a4cd5375c756a34890ccf0c92ba07a61546387bf54c2cb0c8548d4780aa72b667c0a1fe400b30f194465cc97ff42511e75457d1a8a9712a6ea971d797baa894b0348561df068a3455a89afc3684081ddfc0a90fd8acbdc217c83398380267776051cf3491542534b1a74b409b69a8a142c1b437b5a8561fb064ecb591b7334afc482af678cfa4e11e970a48bdf822a0b45e1c591d07792884e4bd057a15eecc5cdf66c994cca765daab1af377a14b98bcd8918fe3546fa4438ba5322da1ba75543be245b12e228d07c1cf1091499a2c57dd42c9f6ba3240c053165ca3fd669b4c3944a7d003d016a0fca826b5e615846c48873cb7f222cc12462023e38f14d98fa0486eae480f81a7376eb6380a42a1a2a6123d8a4efb102ee7b900cbe7a9238b59006abddf2ab25565815947b3bf6b14eed43be91a5687b339e6bb6614387583c585f1456372aa68b17449c2a1c6269a05f8659da97585f52421ab74b9d705ba13ac139f15be9f41971e0a6e04ba167be9b681d294c706d0477a22d64565e71979009a18c8086059f3964ed327288aaa0c8a2b2d976d5fbb50b842bcdf3c9d25656ed7224f3435c9bc9b59b17727b46a546eb8553dab54ecc6842cba94fb24592ed077fc56bd5dd2cd798715fe0c513377361d263c6348340a5018b0e9b43e112bb6ba60503ca954f2bb25fc585c021b57fb3d1acc80a3b20ff4555ebfa223f90762e2008ce920a420b48cd8fa9606ec5834051d0904847466564294cdaddb25cab5cc68008f96971b2711ae8d73b754cc8ab2bc13e07708e7b555ac681c0af0961a19105bf62b93267b8c47c73526b8c2d08bb13867be10211347656c0108aa3825234847519a52b6a4599ccac59e10e945eb7bd579e0c98d12aa9905ed85271887a974ab8f04a783747caab69d", + "sk" : "9a29ca06e2ccb6a96ad265638a6a057ba846fd6777408cc21aa7c8a7b60aeffc6d014b02e64968cab39948e45c6e32676117373f201dc8a86368f54a54501b8d002d3ea36c1287a5504313f3e03ffbe64d28059b41247e76c24a8c05abc21678110983ca0905434b5b2ac45adc6c5d90d83b416b30351b780e8386d304caafc70f3a2a059e8094ceb83810d7599af876537c4d367c21c0827cef5c80f2b04f554c105c1a8c874389a5f8506d104c105213b64b00b1f194c1f793f6d340a7466896905e295b39d9fa9e6c314e879140bd0b1cc276632e70a56902346fca21d2fc7b0004817b1288b3b34506cc1b15060d1b103025e2ce51e2868335685382b2cea4b87dcc6590fac80825caff465ceb9b1dfb51b52ec97c5077b55d528b32f4b2e344071e04b703f759bac057916916ab758718509921d0c0e0d08bd2037e0643a18ed60f984a837b86c5ebb7b8068c1528100515cb808a019f9017113122a7ed16582c78cdb52ab7b6320e7ec0afc194b651119f79f6c7ff32b003ba7e0160510d32af80eca6547c3999547749dcb7205c50bdc62f54cabb15f386648b1805da6ad5c1a55265b57665bebe46cdfba6604352b5fd036d5a9426f70c014fab63bc2ab7288653ed2680dd6081519b3bc56ba9704ab32bf3a59282257bb9071e270fad6b705e48bed7a546ca6a80a3181f3875580965798e978f757b83fee729774ba46ab32a61343e002b6379a5ad9ee25f37838c84f397b9b4039b447b50c834c1b99eeff51ce6d5bdd8810abe873e1a1c57e74c51bb0139d937390f10c118a568bc464a28028cf5a778bc1a717f9a672ec5cc2b635add077485da497f68c51f017d3785bf0dbb6ad9eb3ab3a02776e9784a864a45dc0527b00d47d2a8c7794d43f059cfe88a2f43160c38292216b0dba17da92b56ce6b2711b0869e1204e21c2834c12a2d4557fb723caadc01af894afe656956b35829e780bba9c8ac28002245cd5d46112dc93dac9a656fe40ef67bb544847bebf73eaffc85ec1514b9a248da8760bbd1b65108acfa364b4286c538ab466f34c383f008e0e611f379aba066638b87854163065afcaf1003a189a81ccfc873c84bb465601479d1ac21d9886e7614cdd3603415b8470766892028ff575a69f471b126aacb0136b5d91d1f532f85392e66e182a5acc4be796e42c16d1d56447264aa9f20505f1a447288cd2362bd99c19a7bba93d1775586d769b3a2a1aebc17f84b1c14c5a0d5908ddab90c06bbb7b31c3b88625b96e9244d163585724ffe361e04127e5a981929d24a8e8b58be5221a9d202b84b3c1e0cba55349abd356d787022bf01a04573ccdbe42d1687b29be8c03cf3535eb952073a43319a2f0e52726906cdf7d06be43319d43370b4131457aa2f968628b5c5a71b4b1804734c85ec5efbbacbacd336ca048f8f3589e9561e3732a0ea5523168a8449a9b30a88ce124c25dc2749a3933382dca4cfea4de519bc17f7605321c99b3b20faa4adf952231fb27a95a55c7238702a869d0b1ca018fa58ca21c6d494bc38db4b34216bc770bbc1b63102a588da22a6ae3723bb80b1c857ad06b88d1d0001b396be411618dd421760a58e0898787c498118775ce407317f4bcbd3477ce35c565d83c1ee124ecafb0eeb1b19a4e05eda182b53920b4613c989523d93dba735423dbd84b76491047db0c6f50376dd5460a9c20c02643b63049dabcb3ec09c9a6aa264f3c02cf4faaeaea9158f74670c74c783d461e1c3aab218403161508be461dc2c09d4c77f6737509cc317a2703e3850ca06636105463a4eb16afe797be2c32763f0ad222401545462ddf41c71b65fb2499ad3d0a7c128556518be54948a86b6bb5a811b76b4c35d35bc2d54c0c60c6a744c4944bc74303144b4891b841ac2b1e63777101465eacbe933087fa6541e502ba54522eb69842d3a706dcc617076ab90c16393853fea190cad088da65953a412c8eee83945cb3e10719f37188054c31518070603bc0af5e483f6155d618700f74093aaf352facc6a1ab0809dc101b64c9ada665d1acc9bf31c15bb3a2d163874b523951c7441bac80823d29a909b9db7b73d43020300e68bc66b1964a1031351b451650b63f0076ecc6fe8495857e6a93c9b667d924eb3a84caae9b401ec2fa3355da1a341b578b4765c4649e6bfaf5c8b2ad80de5200e4dd30da0b693f5ebbfcfba9f0ad2ad46576a7a06b65de6bcdc432b6a753f3a6326a27073436483aef170b8649e2ca022497329d071af4c25968cb0521a118aec41cbeab013786a1c2984cb2c649da0fc94fdd880fd3a05239b84ac053ca0f822e4c94ebfe1b6d6898da03b02e455467af6c89db7225ad653a5ac0c8e165f3b9b68b01270ef0ba7cc56322d5c671805b7d333b899abbac120c010033f3064647e4a387649c272a32c2dcc2fd62793d8689cf59619f43c87fdeaaebcd4c3f21483863563ce8442a7f581009410b3c506146390fcd44d0f918b2903940a321c66700ca4e205d4501ecec23a4d17157ce4a0bac562533273fb8071ddf960217696ccd98a59e6c39dac5cd185a0793a9190e25a0460837d07d020d72b5c5ba9840b0940832fa3a483aec99d0d629cfd67a1ce77766a23b2349947968c238d0126f6ab9422b97d6dec5657a20a683544ba07971bc773a5da90bf471eaf12310283944c723eb1e0600eeb2464bc71de7233ebfb7be64202ee21088222a48ba200f04b6bf6a1c7f6404295764e6fd857d747cd985b07f4d83f8b13a901ccbff7b01e21b8789c05b635bcc14c8128c379bdd52029efd660468a34512bb78da224fff9a223371e457333ad464c6fdba4f6c5451b585583655182691f6ee817cf81ce6e7a5cc6b9cacee275c473ae1c58aa38e43de50796f22475fca44270e3a46fb5b8bdda74e3e05b88210f54f36e79fb05becc76805b716154a6e2346b0f4cac241748fde93f325b4f82f3b681136aff8056bc7304ef22652f1679c816032bc35db68b64b2848351da88df89166707b194cb4759e6761032aca4b7a54e8064f5755d36288fc5061072da1ec35a8491396c9406446060347361bed860b028b57250f0187f45a204fba678f587ae031ac38480cf4c3fff90188d925bd4c7c6bd0b758698bcde97ce3958697610ce05e4abfca60eac13b666732e8262b36b7447c0c93f91362c519337052865927a9862d2c1ed186b411554275a24dc9738751a4ba243bcfe46109212b711aa453a35b09ba20ab405b6f0f3457321b24017261b49923225b3620678c4f474515396113880df463138abc3e820c65415c593d74c01e5136150b02f1ccc55a6c1e7e9b121588362d784c3e85658532331bb596682377c752e7c259608b629e74a5a470bad77d3c0672b23831a217c1ac82b94a82437643807681cc1684098b86de031440a79378a229bd902f2996f326a0df16354778a4cd5375c756a34890ccf0c92ba07a61546387bf54c2cb0c8548d4780aa72b667c0a1fe400b30f194465cc97ff42511e75457d1a8a9712a6ea971d797baa894b0348561df068a3455a89afc3684081ddfc0a90fd8acbdc217c83398380267776051cf3491542534b1a74b409b69a8a142c1b437b5a8561fb064ecb591b7334afc482af678cfa4e11e970a48bdf822a0b45e1c591d07792884e4bd057a15eecc5cdf66c994cca765daab1af377a14b98bcd8918fe3546fa4438ba5322da1ba75543be245b12e228d07c1cf1091499a2c57dd42c9f6ba3240c053165ca3fd669b4c3944a7d003d016a0fca826b5e615846c48873cb7f222cc12462023e38f14d98fa0486eae480f81a7376eb6380a42a1a2a6123d8a4efb102ee7b900cbe7a9238b59006abddf2ab25565815947b3bf6b14eed43be91a5687b339e6bb6614387583c585f1456372aa68b17449c2a1c6269a05f8659da97585f52421ab74b9d705ba13ac139f15be9f41971e0a6e04ba167be9b681d294c706d0477a22d64565e71979009a18c8086059f3964ed327288aaa0c8a2b2d976d5fbb50b842bcdf3c9d25656ed7224f3435c9bc9b59b17727b46a546eb8553dab54ecc6842cba94fb24592ed077fc56bd5dd2cd798715fe0c513377361d263c6348340a5018b0e9b43e112bb6ba60503ca954f2bb25fc585c021b57fb3d1acc80a3b20ff4555ebfa223f90762e2008ce920a420b48cd8fa9606ec5834051d0904847466564294cdaddb25cab5cc68008f96971b2711ae8d73b754cc8ab2bc13e07708e7b555ac681c0af0961a19105bf62b93267b8c47c73526b8c2d08bb13867be10211347656c0108aa3825234847519a52b6a4599ccac59e10e945eb7bd579e0c98d12aa9905ed85271887a974ab8f04a783747caab69dcb74eb00a87eb1651271050e74552291b66a29053bef5e49690d4eec7b7bd352e82fcc97ca60ccb27bf6938c975658aeb8b4d37cffbde25d97e561f36c219ade" +}, +{ + "dz" : "050d58f9f757edc1e8180e3808b806f5bbb3586db3470b069826d1bb9a4efc2cde950541fd53a8a47aaa8cdfe80d928262a5ef7f8129ec3ef92f78d7cc32ef60", + "pk" : "c8016eeae46e2610a5fd252102a480cac2bc6e7860620259e41c64591584f1e6ce8e3312dc8862dd806cc2181a18bb91fb184dcf045b030807a5023c4b3779f14a162e0938743b78c71493beda7826022e78ac100e7892fc104d48e25ce92610c072a3e9e8208c93cc225c916a2941c13838eda382f311a809c19b9ca60f188910a1a1bede4710b6b72127e48a5454a457c8037439572c558378cc784554171f6a0c78c676db8bb8aa380357fcc1f61859b0ec72730c10f8c3932975c70e6329aad34a56797a03c0297fb4aa6b97a63be19f5ca6318d0b2c8b4c6d9ef808ebe364d0a41a82dc768be47f44f300bc9b2e4cca1050e21a9919a9b65a07a6c8bc1ca5622a441117a1749211571c462a40c94c3301081867b3a8957ff45c1c3f7c00097a35af93438d74c78c061c2d645e7f6c3be5fa6da749085dd12461fc517e0c28baf93418978772e4c723c071908915a1a5807050c57d2a3d56597b1e1bae4b437632a2522f314b39fa6ab7a047e12b6502027e334b715b5b0b17bb76ae608acc0250d91a859c8c448b27bf4c44b092350e260b65c20c82588c8c1ef25affaaaf150479e80801c82cbea73a37dd1a7df6d268a9b0c4fc753158c39ea4e90960c20460804329f58bd460a37357ae6515bcd505c7cda55b2669017bec3d51816e7001b0a64837f9e07ea26735e830092a648f828cb3093228b98a0c92656c1a14cb3a306929c6207751cebe31aea4c0372cd5c06cc637dd9b6894f00dcb3796d09ca87884412726a25bfa9bf6eb613e1a2a19a196e1e1634e1ca0347a9bcc96816923092961b69dc0c013c191f7ba4fb0b13ce5555e8c1b07d8568722155287264b5fa990e92603aed71df778832ee3bf9a767fa9e650420a14f5ac227df497efab89511302d231a521c5353bd425306a14b7d2a566ab3b32aacf353c2b04a148e4c93c3e470605067dc7590722c452245b3d750205d2c0aad03b0e2ec535bc6cc3956132e329a980c8495d765ed1eb071c58680a11859c3cc0b1e986486a5b543949643b83452c307df477685a4d0a70a7528a55a997bea46780b26252af157fe5d874cf5c420b5b1a324a932ba52291428a39672bb359abc4b54bbfac608a0135cc99a38e102da3e088e4ec5c47984a636c7cb99a6b6304cb0350052618471f716be06b899087aa38053111e35a95965c04a7c42bda2319598819aa0aeb5c39181079f41982e05223c8e89abbc32fc1487f3cb99a167ba694b0668a5525a88472439c89179147ef831022b45f6b8553c8150e32b5421f75291c830a8698a916406807f201141a0ea1cb28255a9ed709502ec7851a56a86cd3b7f05726ed6a6e50fc52706104e829b02f7b61a1856c9b44b8d1214768851ac190b46b61c053c371a333a95b7806eed16c033790c1563fb823204e26ce3af87750ca639e605cd435024336751ca0bdab99ce5b45cefa04caa29ba33b4998da0aa832ec22551821bac055961acefa077de544bbb80211878c6109b512b6b4850b5a8d0bd9bea6978a0f920c1fe8601e1123a98aa23cfa30090817ee849e654a0387a185171a43047758a578a02ebb557904106eb3096d3c1f92092f02891f1d3b0659f284188b7119c14896688ef2bcc8086c604fc140a8fa24c9595d020269b0355ad9a44cbd803b59010a1b85b12fc785ef0a0789c10b3a30925cf155ae8682859a8f8164cf62fc08df577eab2071db87b029a16ec90303f5b97117761c5f20033110b1bdf7388895b30aca862f22adde6930430821dccb2b1ba4cb923652309b4f16600fc9fbcfaa8553cb45bbb53035cd28526ea8449844ac68b87aa61047b94244f126bfe2323af5f30bba9c1b96a426a1d84c2da35fbc001e20a517d458b4291cb36394cd9a074e51d8a45ce623484a3aa7d575977242aed535d46b74d8645aed246692ac1b8b055d717ccbd59769ff9617bcc3aa7bb9366ba51a736b2ce79b971e0c204ac62fd09755b4e4b233e94a9cd3490f4049ce6cc96c7c0fa1254c4eb67748b337c41c473fab4a944364531a6fe18652856797787c804ce1c59462b8d145cae4b97232440ba99cc3a66c1e019b53fdb272d000c85ad63d686a907a31700fd4a29e5936a53a4f2d2486751851edd1b70115adab07a29b15594566221b329076a5a116676d3534044965014daa0d13da178581619dc06df40a02750beb995480eee9", + "sk" : "2ca62ac1f40bbef551a3f75613606661a204ebc3a81a170ab0e80eac65017bf3add2830b80ea56743a56bbb7b428951050844474ba8aab61912d35433a679c6770b3f8174214510215268eb5b14411e982f752192c649b61e559bb189666d98254ca913edcb22f93667970566dd06fcc06bd937bca44ba015bc689278925fbf64f1aeb93ee4a7bce8093aeb6862009c49f89cf31e74f91da8a206ac4ed0c21f8ea9ae1ba7f3ec59dfb5b729e73172770ac90957740068b1fb41ed528c73e2c2e62223264dab7f23b6a583c2e0e4bbcaf9878384376c23c38802c5753da4688554a2e9843b0dca303997451a0609be12d73ca1687e2702db3cfb703504fa7b3fb372a59831267a8b9eaac60ec31932c776907d29be988abd0208789f457def7130d628b4e694760f9883e197475f43670402f992cbf22819aa27a12fd60470e0b2a59700c05287589c2a85fa723b5c95ec12488f7e503bf090c581b112f854383c02e9bc693748628dfb2af873713e268c98fdb5ec890b55d8a7af5b93f3e94be8f5971c8c63590715d09d894e078c07fda4414280b20386ad6c645df5b21fe43b940610dde4b30b2a40131627d68a47045696eca108e93ba6a3600ca7be14f54346e9699331d92bde1786bde2886027a62234155648b2a52e3673fe5653cca7ffac07acc060371d67a581a529d0bbe89762dd1763daef0c09657698829348028c5f14359f4996437ebb092f64e7dea7c87e003c874c0531200e8163a9891cba6b0750051006914cf22d95088542fe58c4f6955256370825306122aa5a26963c66ae4ce268c180698a4123954467972e8c9ab44545d0224443ad83d3d7c48ed052ef59b1772d82de3781d713197e6e739e187cb4ad8b8b9f4972ed232f9513b03d2bd0f84c2d5951f2f20b01e362bed051a1278bf2a185b95514814494f576b56418c9d4de5c62b30ceea03a1e86a7a7fab18a5c4bc9ed43c8f46426a3a853d5127073125bf3510ff3065e81a726d934f3a279950a675f0c3c9bf0bc42a574bbe21be72092ed5ac8323e44cbdc1ce8864031838a7c43b64e9dc28a657bfe11711d0f1c5d407212f5938a7f14e82d9353173bd4d94621ae29247a2328007078fa5029136290d48009afc39720ca4a8b8cfc2233dd0042ab0625007b36474fa370a961b520575404154a1070560bc0bbbd9060daa27d4d10a13da8fa0b676b291544a6c1bb5582b08d761162ba103094df56789f76c8cae2b6637d58391f0ce022c9f77da0888c5045586a0c18a2e1730b3003493dcc8bbabfb359a39796ee578f5cc67fdc9a817461aa5296c5d379a58ab6f7a911114f0bcc39771633a6776965816384e5cd27ff1401a8880b2774cc73e6303e00574e241573edb2282a47c6f1c03b74a91ff3c10e4305fcb86ba613c747a591d9aec4c90193f9617431af4689c11310025b92247c805487de6c82968938e67084a178511c70722b28934e64a6e4a5223105c3bb24a6192d9216b7232ff0764f7d48507b84d72ac2236d92c69716bb6fcbb06757249ab3d7bc5a751e104c9e5881fc4675b374afb7735a56b9872164c847493a5dace7a855674d90091809109c524289ccbc4143a2567a6cb587045ec2d33e93ee2c60c9ea6a1a40344613a49ef538a41753a41d8c203785d38207abb3024584caedb404c8c0661d114405d256bc06164fc6ca2b8d71b1e481ad065462128327adba3d7572c3dc71a75791258a5cea5c65a70e11b0eb93a9f027b3b91aaa58a8a50b6bc2f59049f915404087ae4280cf7f603d110c9eeccb045125dc22b4c1923c83aa84c779a6312888ae7e019b7814d61d1cb6635b69d6445a8d005b4fba51b91604530088cb3436cf73f19e42ebe1acbc013b2e8341e3986c4ae156950e1b9d799c450751953da223fc11688862405691d9120cfe4eb283c99b3e39555c7f246c6e73119f7473e0709f979499c52630f140dabc690beaa91186151e5865f7fc85aeae9c27dc3c03c31715303caba288f95c55bfde806374902d0f50015221a3c3298db60a2257648bf22cefff39ac0e92016d71fafb8c9037246a99a0eaa4566a04b0e7b8c4dcf8abea7f72e214494d4176920858e9ba69487680499d27e2ed56d040045ac671a364848c0a4100fd4b44e1b1e8bb5914ab89dc8016eeae46e2610a5fd252102a480cac2bc6e7860620259e41c64591584f1e6ce8e3312dc8862dd806cc2181a18bb91fb184dcf045b030807a5023c4b3779f14a162e0938743b78c71493beda7826022e78ac100e7892fc104d48e25ce92610c072a3e9e8208c93cc225c916a2941c13838eda382f311a809c19b9ca60f188910a1a1bede4710b6b72127e48a5454a457c8037439572c558378cc784554171f6a0c78c676db8bb8aa380357fcc1f61859b0ec72730c10f8c3932975c70e6329aad34a56797a03c0297fb4aa6b97a63be19f5ca6318d0b2c8b4c6d9ef808ebe364d0a41a82dc768be47f44f300bc9b2e4cca1050e21a9919a9b65a07a6c8bc1ca5622a441117a1749211571c462a40c94c3301081867b3a8957ff45c1c3f7c00097a35af93438d74c78c061c2d645e7f6c3be5fa6da749085dd12461fc517e0c28baf93418978772e4c723c071908915a1a5807050c57d2a3d56597b1e1bae4b437632a2522f314b39fa6ab7a047e12b6502027e334b715b5b0b17bb76ae608acc0250d91a859c8c448b27bf4c44b092350e260b65c20c82588c8c1ef25affaaaf150479e80801c82cbea73a37dd1a7df6d268a9b0c4fc753158c39ea4e90960c20460804329f58bd460a37357ae6515bcd505c7cda55b2669017bec3d51816e7001b0a64837f9e07ea26735e830092a648f828cb3093228b98a0c92656c1a14cb3a306929c6207751cebe31aea4c0372cd5c06cc637dd9b6894f00dcb3796d09ca87884412726a25bfa9bf6eb613e1a2a19a196e1e1634e1ca0347a9bcc96816923092961b69dc0c013c191f7ba4fb0b13ce5555e8c1b07d8568722155287264b5fa990e92603aed71df778832ee3bf9a767fa9e650420a14f5ac227df497efab89511302d231a521c5353bd425306a14b7d2a566ab3b32aacf353c2b04a148e4c93c3e470605067dc7590722c452245b3d750205d2c0aad03b0e2ec535bc6cc3956132e329a980c8495d765ed1eb071c58680a11859c3cc0b1e986486a5b543949643b83452c307df477685a4d0a70a7528a55a997bea46780b26252af157fe5d874cf5c420b5b1a324a932ba52291428a39672bb359abc4b54bbfac608a0135cc99a38e102da3e088e4ec5c47984a636c7cb99a6b6304cb0350052618471f716be06b899087aa38053111e35a95965c04a7c42bda2319598819aa0aeb5c39181079f41982e05223c8e89abbc32fc1487f3cb99a167ba694b0668a5525a88472439c89179147ef831022b45f6b8553c8150e32b5421f75291c830a8698a916406807f201141a0ea1cb28255a9ed709502ec7851a56a86cd3b7f05726ed6a6e50fc52706104e829b02f7b61a1856c9b44b8d1214768851ac190b46b61c053c371a333a95b7806eed16c033790c1563fb823204e26ce3af87750ca639e605cd435024336751ca0bdab99ce5b45cefa04caa29ba33b4998da0aa832ec22551821bac055961acefa077de544bbb80211878c6109b512b6b4850b5a8d0bd9bea6978a0f920c1fe8601e1123a98aa23cfa30090817ee849e654a0387a185171a43047758a578a02ebb557904106eb3096d3c1f92092f02891f1d3b0659f284188b7119c14896688ef2bcc8086c604fc140a8fa24c9595d020269b0355ad9a44cbd803b59010a1b85b12fc785ef0a0789c10b3a30925cf155ae8682859a8f8164cf62fc08df577eab2071db87b029a16ec90303f5b97117761c5f20033110b1bdf7388895b30aca862f22adde6930430821dccb2b1ba4cb923652309b4f16600fc9fbcfaa8553cb45bbb53035cd28526ea8449844ac68b87aa61047b94244f126bfe2323af5f30bba9c1b96a426a1d84c2da35fbc001e20a517d458b4291cb36394cd9a074e51d8a45ce623484a3aa7d575977242aed535d46b74d8645aed246692ac1b8b055d717ccbd59769ff9617bcc3aa7bb9366ba51a736b2ce79b971e0c204ac62fd09755b4e4b233e94a9cd3490f4049ce6cc96c7c0fa1254c4eb67748b337c41c473fab4a944364531a6fe18652856797787c804ce1c59462b8d145cae4b97232440ba99cc3a66c1e019b53fdb272d000c85ad63d686a907a31700fd4a29e5936a53a4f2d2486751851edd1b70115adab07a29b15594566221b329076a5a116676d3534044965014daa0d13da178581619dc06df40a02750beb995480eee94ada82049cbac3e8c6830334021c22894085dbc8382fb43cbe318e8e6ada9955de950541fd53a8a47aaa8cdfe80d928262a5ef7f8129ec3ef92f78d7cc32ef60" +}, +{ + "dz" : "66b79b844e0c2adad694e0478661ac46fe6b6001f6a71ff8e2f034b1fd8833d3be2d3c64d38269a1ee8660b9a2beaeb9f5ac022e8f0a357feebfd13b06813854", + "pk" : "2f7a733c9c0d0a05b6ae91776032105bfa99d149062746ac1fd2ca81db9224518a39629a36d043e6a398444a055a2cc28ac785e22b9ada469d2e3491174a4e16e11824d32c33326f7cc2b73d417a7151496fbb6805a79d5d974b12f3c0125b5d7bfc7c6f244b68e2c1ca8613e891322261b4789898a1f858f5991b2b1b177769aca1453c57c43140548452f3053d3b55fd2c3062a0b11939a3c14a81c59432616a5700c775fe98c6fb88c1eb8277c469be42f541dbb79808479e0cdb11856cb7c1cb6a5b865469bba549d73cfe581bee85494dea28d6e96a5f04cd65e561ef66a2482c806e39257b9ba9581421708663bf0b45b4131eef3384eb53b8733c4957937161c3ccacea5cbf91429e87b8b2b6a0aa44cab94bcd02d14cc3932c3ee58b483b1d11e5243fea0d34912b8d45bdf48c1358db3fc163ac081c23ca6c43919a649c33911c5802e2407e9fea350c3b64f302c5489005ec87650de428e60b790489a17e96b9e1fa91b33bce5f4b8d8dfa1610b39fd2858c25b898c1386c6dc021bd3414bf213719867f8cdccbb4d2bdf12207860a638bd41a05b9697a3bc901e9ad0075c080243cc0cbb3d389977c522230a42125b08d41839986a60acae28bda183aacc32dd5cb149af2bbfc60b0d5ba8ad89b1acc0863ceb24faea37ef3f60168cc96d766642f07a116225873e651ef693f2bb97339acbcba301e975405661b2aa523168e06c86f9bcbb42b5f12d79c3c379afcc37dc4995b11a4afc3578a30a13ff57ab87f022fd5c3ac5dacc3462c7e7edab63b889c22e90d685733a1a79ec336c50c18a5fe4408c2c122e34a60ef56a78bc16b78c3c98ed689e0c9276697cdd8aba667109cd911b77e6930c4f58cef1240c1f7005a7a2b17390988924cb0604b4f897d19c5b0e4a557a6a23470bc71db15bc99248d42d9bed4117652690124b1bebb438473619c4919c6c0e4071ca990b9d005eb287b15126e5c3477a98669f0856242dc073bb2673c7c1b1485799c300a0648a83142b95a2377d7e2b1d994209184309934c914308b7371a307a3bfc825958a98a12524b847ba5b61e5a279eb9f7cab5ce030c45ffcbcf919a6ce1059dd7c6aa077c2d2437408315db32a800c2099a92ab682fac6461896d583007b97af2336b1e6d061643c62f0b5122d48a230225128c52863c9aa7837ab4f254f92863efbb3b379f87e40071cb6c8b74ac79af4ec11da6c028f1caf9545a7d0a984bf6ac8d4067a7ff29325daacd3f9470d529f02b00183586011da8a0295b678b18d7572cd4f081317b92c21803f613bb959170ad3a4cf465645d3e5a1dbf672013bb935bccdcea51393bcbe7c975d30a9823667bbb155bdccd14ad3d8b453b30ec2b0cbd703485975cc571530b4cc521693a9965139fca21a90d57397f34c46822ea0e0ca0f56668b8692127bc93322389046c63fd08ff82b67f9778964054b49ab0dabe24628e771627ccf34f46c6c820e9d890b15f396a291a98eb14a23575952abbe46374c74b812aac6b9ced932c078ad3f2a05c821b720305773d070b8c86d7686c53b81ce241586f5f752fb4a2774152638f04156a0b24b3061141878d5759d12f8bad4e98aa5d41895b91e122074b31aaadc30a1dff707c32aa0dbfb2fe0a519b4289942e99754034d65d7b9eb5c0087225048b5a293038969a944725a23475b0681ca2177c5bee023bb7e0abe99a630b5babb5f8a67c8117fecf20c1187c338a97b72c1674aa302c3005037631ccfd51a5b10ce837911d8d8372b9760c0498b8ad8218f832fd8519476ea5673d6659b558895796e14cb5a55e7a3d0b91cf5a6228a3c93175a2ccb06c26bb00d5224a402f119a3a42356a37cfd82162c65953b798d9d96cf4353805ddca537a9504b708d16424a3c6209c2d738e25c357256833dd14375a65e1e32868bc4c4e5e062fb636e27f4c746eaac0f641330d235d909a128c890e531be3e0cc307e632baab0ef7684cc687bac9b966efecb85ed1030a1b1e15b71be5a263fc64c320b145cab657a14c2749dcc9961952ad5489c6485f208933fff0203f3c31eb6a389f072cc3573166b9349ada4d7dc66bb12c18a7d96a86f93883f83822ec0094b24751388a51166da6b24a0b526935817e1ad73b4403aa3b10b5d1822daf198aa848a73c9f9a866b634f939c2179ce55edfaa1d5d48cb3127f0fea3acc7b163d", + "sk" : "6360495af613e1c6b526a64a23cb3052fa4fc0198a351aa70d982284b13ce66384edb522df0b38199baa8265ca96da7040a7204cd0162ab481517a76d9b94a20306b04d19f5ab43146f26c4f43c23094131b9ca58552ae1eda8b9e623cffc533e77ab7345790a507a3edc589a0e01584a291e0a98389224ac057a2c7a49aa92c012e3068fce416936ace78967543053542faa399a8b7d2f5c483d9b09058067db414b319407dac97a1045d78b6633d2b690a77510d996abd44c972a37b37baae708086a4143926875e09aa15a206b3fdc69562d645ba213a13c74b245072a2480459672b33ab4f1d969157137d85f481828a7cb71aaabbf6b54874821b9b77e41caf849874830a742c887fae918ec657343aa11c8dbb6190d53749157e6277582c589ad1d9a33e740e25f00bf3dcaf2c03b1a6a64ffbc0a104fc37a2c34f7b8c56e06ab258b7c79ecac3eeb9c2a87c02171aba70b84c58d474f4841241dc10ae9645c1b71163ac3053a8b9e999309494763c50354e235f253b87af35818166aaacf85abea0056b3ca078960dc54c599bb43508fb06e06c968964cca2acc72a17c25d47a6768c512836a7ccd3cf58b09a024b1aea57bb26f2219eaa3f473a367efc8bd1790f576978ff159f282a218da906b506be5c63c016a55d92c69999e4cf1e1730af67881dda242f505ff78c242d3a3730c088b83abe4f39bb628a4efcfa03b0ecb8ff98c288d1b8e12b2429263ffb0a638f9665704b1770c4be9d999f8ad6ac080671cba047378a60c259bf042839ba39a11f94354dfb8d3da789a4790b2241718a2a267c7c8b5e1a2178002971306d08f360c6940043a25b4ab350ae385969fb28b64cab121c10ae15ce4c51475cb4794cc18118b877d1e3723101ba4172c272c1cdd1e33f506212c5b421b0f631dd773ba590b894056051753ff73013daa26c597a50d0023b2ca99af7aa5f218971b5c8845c68801468471651765922c6c7586d88b65d017572d792b037d7684a86a517c453fd36ca5135b320092c36ebab15dcb82a70c156e6657ed35dccf34f94559b92d83f7d46277926c9d7422fdbca5424d431d61648a848bd8e260179047120a72a0bd1a495ebbf154908edf0363b86892f783e75369252e92a85097a2636c8f284a841396d4cb39f8b247ce1593fa502a6ca4014cb4036f94810656cb9335c24ee345b1cc15431359dcee9526ec6a42d26280493b6090b0d500808bd29a321959f6101c18af673921804a3501f5848022d0b1075b1adb6f30f47786c9dd345cc33a12fa98dfa909eb724ce7e853b5f29a00f43319f92a14999526cc7966d3c25bc24924f5ca64de9a2a5c69965f95fbf29875b201dd3d54a1ed97cb7039f8d3982764a4e964c45583183a15c0d8097c033dc144bb7ca7d4483900090859c2a25c9c2b1aab964d7629bb420f3261e2e4c76afbcab41272155496c4cf9131d7195b9228ebb613dc7b42541ca05e39ac09e710fb972978f4395b883bc6a67593a7361e4179b7c95945513c28bd488f84146c5c8956c4b18a0da5ce7a680d26a779ea5ab1a046cee3191acd2c655cac8dbd9518528be44e03c1bd758cfc30d9d163b06c0a60e5013f6e646d3461a3993b7608b9edcc65304e92d0e59b193747325452ac403771a657b92fb8d4a57a424f13e323b37c46183b4014600b760bd44c5eb1099167354a5c31ad377a5041c6ea00bcba66b18cd457a6571853db6a90f408ffdbc35fe7bacf16a2be625abc9473f57c269f0029844976475f484b4090a53523f0766168f80a708ab37e0776c0a4b4fe02795073a19c01619edfc36ffdcb12668851c43c2ce7765c050a46a025252904698d2427a634ff421c45d2018772bbbc3aa2ec49799b3e9733e4b0cb16973e51a1f43ab1596d64a92c61576592d6f3cb339f76fffe186106a176f45525900a6b594b673271ce54499bf90a5c5489928ca879e93b3cfa7917999b472d1abd7da21333165b95c8b1f6736bb183fa14b9d1b26143e1807c7f71d66360b1ac2be6db555c1dc907b794dd6a07c505451bda90d2e7a7112636fd7590f48e0c94ceab150906945273cd375b82573ab5994c2ac447f5d53a3d9e04b4d694f5d81b54e29c125f461ba056e599674b5d15b0161802012217cb73419d431e03abe2f7a733c9c0d0a05b6ae91776032105bfa99d149062746ac1fd2ca81db9224518a39629a36d043e6a398444a055a2cc28ac785e22b9ada469d2e3491174a4e16e11824d32c33326f7cc2b73d417a7151496fbb6805a79d5d974b12f3c0125b5d7bfc7c6f244b68e2c1ca8613e891322261b4789898a1f858f5991b2b1b177769aca1453c57c43140548452f3053d3b55fd2c3062a0b11939a3c14a81c59432616a5700c775fe98c6fb88c1eb8277c469be42f541dbb79808479e0cdb11856cb7c1cb6a5b865469bba549d73cfe581bee85494dea28d6e96a5f04cd65e561ef66a2482c806e39257b9ba9581421708663bf0b45b4131eef3384eb53b8733c4957937161c3ccacea5cbf91429e87b8b2b6a0aa44cab94bcd02d14cc3932c3ee58b483b1d11e5243fea0d34912b8d45bdf48c1358db3fc163ac081c23ca6c43919a649c33911c5802e2407e9fea350c3b64f302c5489005ec87650de428e60b790489a17e96b9e1fa91b33bce5f4b8d8dfa1610b39fd2858c25b898c1386c6dc021bd3414bf213719867f8cdccbb4d2bdf12207860a638bd41a05b9697a3bc901e9ad0075c080243cc0cbb3d389977c522230a42125b08d41839986a60acae28bda183aacc32dd5cb149af2bbfc60b0d5ba8ad89b1acc0863ceb24faea37ef3f60168cc96d766642f07a116225873e651ef693f2bb97339acbcba301e975405661b2aa523168e06c86f9bcbb42b5f12d79c3c379afcc37dc4995b11a4afc3578a30a13ff57ab87f022fd5c3ac5dacc3462c7e7edab63b889c22e90d685733a1a79ec336c50c18a5fe4408c2c122e34a60ef56a78bc16b78c3c98ed689e0c9276697cdd8aba667109cd911b77e6930c4f58cef1240c1f7005a7a2b17390988924cb0604b4f897d19c5b0e4a557a6a23470bc71db15bc99248d42d9bed4117652690124b1bebb438473619c4919c6c0e4071ca990b9d005eb287b15126e5c3477a98669f0856242dc073bb2673c7c1b1485799c300a0648a83142b95a2377d7e2b1d994209184309934c914308b7371a307a3bfc825958a98a12524b847ba5b61e5a279eb9f7cab5ce030c45ffcbcf919a6ce1059dd7c6aa077c2d2437408315db32a800c2099a92ab682fac6461896d583007b97af2336b1e6d061643c62f0b5122d48a230225128c52863c9aa7837ab4f254f92863efbb3b379f87e40071cb6c8b74ac79af4ec11da6c028f1caf9545a7d0a984bf6ac8d4067a7ff29325daacd3f9470d529f02b00183586011da8a0295b678b18d7572cd4f081317b92c21803f613bb959170ad3a4cf465645d3e5a1dbf672013bb935bccdcea51393bcbe7c975d30a9823667bbb155bdccd14ad3d8b453b30ec2b0cbd703485975cc571530b4cc521693a9965139fca21a90d57397f34c46822ea0e0ca0f56668b8692127bc93322389046c63fd08ff82b67f9778964054b49ab0dabe24628e771627ccf34f46c6c820e9d890b15f396a291a98eb14a23575952abbe46374c74b812aac6b9ced932c078ad3f2a05c821b720305773d070b8c86d7686c53b81ce241586f5f752fb4a2774152638f04156a0b24b3061141878d5759d12f8bad4e98aa5d41895b91e122074b31aaadc30a1dff707c32aa0dbfb2fe0a519b4289942e99754034d65d7b9eb5c0087225048b5a293038969a944725a23475b0681ca2177c5bee023bb7e0abe99a630b5babb5f8a67c8117fecf20c1187c338a97b72c1674aa302c3005037631ccfd51a5b10ce837911d8d8372b9760c0498b8ad8218f832fd8519476ea5673d6659b558895796e14cb5a55e7a3d0b91cf5a6228a3c93175a2ccb06c26bb00d5224a402f119a3a42356a37cfd82162c65953b798d9d96cf4353805ddca537a9504b708d16424a3c6209c2d738e25c357256833dd14375a65e1e32868bc4c4e5e062fb636e27f4c746eaac0f641330d235d909a128c890e531be3e0cc307e632baab0ef7684cc687bac9b966efecb85ed1030a1b1e15b71be5a263fc64c320b145cab657a14c2749dcc9961952ad5489c6485f208933fff0203f3c31eb6a389f072cc3573166b9349ada4d7dc66bb12c18a7d96a86f93883f83822ec0094b24751388a51166da6b24a0b526935817e1ad73b4403aa3b10b5d1822daf198aa848a73c9f9a866b634f939c2179ce55edfaa1d5d48cb3127f0fea3acc7b163dedc529d14502bab03d1b7fc370f2ede22c7190bd47cc88028adb3294029e264abe2d3c64d38269a1ee8660b9a2beaeb9f5ac022e8f0a357feebfd13b06813854" +}, +{ + "dz" : "7ec408f52c9aa723d0c41d9987682a5f4ce6c9da7cd0215af60bbaf5484ab353a08ccf451b049fd51d7a9ad77ae14a81569df8c9bd3a8f1ebea86fdcfb823082", + "pk" : "69bc82661a9e822624d2a644e1767de906658569ba68922aa5c18996c58b3325685bf3564518afdbb99aa67acabca017283bcec3cca9075cbcef02cbe57ccfc73581784bc6fc1b8b7623b9255c20f7430887c87a5f6873b8789de3810ee4841447d826706bbe47d6c4bb13380a03a532d240adbb8240847e6ed68eb5abb3452584b949b8889bb77d2bc87a11c4580919931509e8fb931b50957fb00b972c8f17c8be0e0565bd95b16799606b825e462059a701412ac2704cdba91ea269271519421574f807206d8a65f8b67f44117b4c742e7bf4209668cb013975a9317ee847bb09db3c44d8029e01c4ff4954d5ac7557941b4c12c60520785867cef3f77214805c96d8497b508629713064cbb04d0b9abe21afabb10f33eb38b6b3bfb34908ebf048ccb239701944fe64792b8a909cba14bbf50d03b858bf4a318b9860e58141b7f114b38616533c96c4eb25115724e6672ec20937fab6164aa4a9818acf072c90ea4a5ba34cc95270a330e2874d76a5e0fb085f1aba5917a6e6c3a50ae59659d95703d0a1e9c76c0f0055605ac839f70f6868bf0727496f38c4fd042226fb261ce27bcfab89daa192044462cba31297a660b191bf4440305c5235ec225018cc92480c19bccb480d03d08c470ab20c88c7a1b2a9f37dd7b911cae469de0c7f6e08aa9d427a8eb90af2649aa28ccf1bc19c0fd84842e5748f686278631659a5a874377347ea3894b035a5c139ec8cc0aa63a960535f8e3113f668bbfa9a67a82ccb03253461d3354eb81d0d112fd667a1f133c054730f28ab50f54c5416f65ef60b6ce8c86f6608456c819a7e10ba9232322e4bc73d8370874846643275622b3da6dbcaf9fac7001cce6d34565cbc6f34a1bc9ae904c5229320a3755c4a439f035b5f8a099c70a6a57b5e3e15001bfc19710878c5db0930b21f28603ea4087e0b30a2cba02118fa644331a81312a22ca0721ff266620bc91fe318897b77d3c9b7f9986861879a3a9c349e16c72a9b2bd645915fb05a94ba4c57aa72e93c3decc55597e664ae3a683274267f486452e089aaa8679234c2fde99327a60a81e687cf4491de4b90528492b6c46eeb7725d876a91987025af06895279635e98183bb0ef7267c6449913ed09ae1ba77bba0010b03b900863119011b1dd02aa969ba41b6b684fc3976c416342891cbd0588b5c6a480c04d7798820da67c9142fc07a906f2517a9217398c9611b0749f5556821d93368014d9d01cf2976af6bf492e2e59b66d3671e814e466388e2039037313ac690c3dc534ba77281613560b0fc9bc5a298c87b879835b386c6b0e1580830b689e7b005ae950d309c2e264556685c54c606aab7c0318b2c66d4513a707b8b5800ad2ecc1567807f28122525b69b7e1cc0d1646efcc1673a156429a205e4016887464c39a6543e722f0980b81f524203b45deb45184d35351be963d3906e7b0a98b49167a2e0bac9c7a50db62657c4cadf6985d753c33f90bb1a275be17a7342859415f7855384975775cb557a2eb92801bceb7f63cb97a40837ac159a37c2935157160d518bde11c1fbe18c32923d3049b50b50c2ae0a325281c7a4bc32022aa7835630198103b25398d613631860b70a6536bbc66ef6fc9ab856771652689527c5f5db1d1b4243e3f06460eba75c363715378c99019d213732804b31e30cbe3e93c6f83a7ec239560abbbd48d96684f17ed61c9dafcb55cb168e2ba1778ecb0166e7664e9412f4ec7353092fdba5cca4585d173023f1856836619e57b0052b07141ba9507b042c5d5b89ab429b3f237f0d80c5d4126cb4c59d9d19bf0bfa9e3eb42894228d13a05125b36d1daa647661905cb471b08405207469ebb35ba5375a40b923e6b0cdb3f1070bb6728a389ca4b89079467732ec3cd7a27d746850bd4908e401134b650419e639fba07d88eb2bbb755b2a7ac2bc6947ab8907c80a3b5610a771782daf790874563b65a1236baba0b6fac1e5f242919bb4519b637464565467456600882532457e1249e692bb82e16c7f21c370a29453a95600a069a54b0b62087f09ea7ab3da48348257877864cb080f7a39603e284063da75ec0b9219e515021ba46ca8c573b306e814245d45cee5f55d0e5c7e36a31166634e7805a413a062a7b5a7ae75783f97c505daa8f9113507a98a3e8ce6ff046df83fd23815de42eb44b586845b55b2d39aa000ad", + "sk" : "5999174084c2dbb511a7cc2500577f27809863db3607c863f5e50901e2be2b949ef9b55231b82703a200b1cc181e7119c0f9ab9839b795e763a5e7ca3a0216f6b080f0e7b52c8c196051b5ddd86779587b92bc10a16ba470bc115fe733c1847c689b06cdd2b3cc28a95d92bb479b05244549f5c3114951b872e1257b10acf04ba20cbc2a045947ad631c41781d0704c6f469908da6af1250bd04772cc6c45145e8193b739de340397f1cc431227474f2c15c634961b7af3dc645c9278c8ffc304ac39d1933946981399c92094aeccac243b81b698c2c4985e0191ca1126861d5a5f8eb61c023a5b38489d2168bc75a6f891202d734a28335add858b6a3dba95c86899db97921007777902df820b4d63b1ef40bbf87a59fb20662001511a75c323ee3b2eac47f51ca993f865bb80954138bb59bf2731c2b2498940129746c8c6297d2bb5aa8e75e3560ce91002fae79543289c7f1d1b1850b8ceb2166104b2aa30028cdfc6a5623c1ebc2c8f8cc2f27345412d90a9a840085ecb68214a13444aa3aa7259f35b0c5cb9e80aa83ed21c714a1a51cec15b91a578544294f565fa5c640edd9bb94c52419209006e9439ad53cacf4946567b80d4a11f5b2cef3740d20abcc04e39aada58cae16185072b98c64b7fb756eb0022fd055545b679bb14829bf0606558a6ec5497ea824371ea95312e31a02036179945a599454f5210dce7a3610055bd6db8f40e37502073824eb699a3913348660f3d1454430951732acdf3b4b64d57c9e69c6e6caa65e029a9de4c36942cbcab150034510eada835ff5aa0024b36df8301ef2aae086545a421e834c9dea771575d0ad98a0562e3c56b38546ad04475a39c310572fad7339dffacd2c39888a898ff9703d71147c3c9c476b75911d8615f43c9138003d1ea59e86cc9160f340a03904c8774924cb8ce5f610ee7a979f320960343d22c0cb84f977ec08b7fa18c34a2836a2157271472100758281198cfc88cf2c4b4ec287c6c669553f0135bca1129874b480d4621a4994d690922f67c6ef8b66c6602256ab917a9576638285e0586f3ef860d3891b66a8551a19a57ad7286c700bd7566938727b74401b9225732d5ba65929175480087f645632e93ea2c607b0bb900efb9e71d57b84f63b2d6946be5a66e77b032883b64c2734dce12944225dd58c3d19476a4cb01416711a1a81be7510c3d1183eb5d39391889d78206f3bc2775e174839a0162000921ef689a204565df8cf155131c9e7c5569459c81b3f712a8b0da79b1fcbc9a13c12d346b2e121177adcca95e4c6ab647784231172e4c4bde45c7a4532930a2a0a60a663a5b7bf186a5346a2c0ec9f918147a1e66b7f6289a21c2a6df8b04db12e76027d89bb7c13ba9672d1c76f4057415160430985f5215b53c59ac76c6387e52281889d968592dc607744757b61f30afb6c4e90ca6a580c475cba12664a5552f17330696b12b3ca3ea72784d16d2dfc5acc0b1665bbb1d8a09d8bfc6d81ba51f1117a109b43d2c97250fc9634001fe8018e2c9300e1e46c317c62574b1ee2c850b78383da446deb16aeb66a08a3348adba75693991b4c4172f8575ad7730039e3acb9bc8bf238c20e51b9cbc9818554021d7465d007967d274d82c03afb990f7502a87a60036bf5a204910e7fb3a514b8126aa96de7926592108c0692af748a839335837f0a9d3b20c97f3131906197c6a66ab88291a7c62d7d740f004d44e261c683827fe424b02802937d6ab4a798554574a0a6b5894ba8afd11b782472950c2cc678c148a9f80ca305be0b765a1542a1fe8690f4c865a09931904a3408e665d60633349b72c2353159220a12b5434eda854d7983333c04a0864356c6a137892023a89a2ed1a263a100a7503c1eac6aaea6b12a434b9ba504c9d79c8ab4aaa20611cce877a5f834d740108874bebb82c23e65bb16ca769c60280b036e2b921ea4d30f59f68d189a595dd099a6da6afcca07a6159099e05483b92d00076f22d0a1b94761e8b8399b4a82e204a011f141fa82768b2926d086a24ea0a71aec9d8723aa77614cb0b0ce881742e0a7a2afd0c288244be4400be81a90209c33aad80b84e383f84a4c313acae89a6575a3aa726b65f0d75e5a7ab355f967d5b771c85993a0b6094eb35e05c409f3e47369bc82661a9e822624d2a644e1767de906658569ba68922aa5c18996c58b3325685bf3564518afdbb99aa67acabca017283bcec3cca9075cbcef02cbe57ccfc73581784bc6fc1b8b7623b9255c20f7430887c87a5f6873b8789de3810ee4841447d826706bbe47d6c4bb13380a03a532d240adbb8240847e6ed68eb5abb3452584b949b8889bb77d2bc87a11c4580919931509e8fb931b50957fb00b972c8f17c8be0e0565bd95b16799606b825e462059a701412ac2704cdba91ea269271519421574f807206d8a65f8b67f44117b4c742e7bf4209668cb013975a9317ee847bb09db3c44d8029e01c4ff4954d5ac7557941b4c12c60520785867cef3f77214805c96d8497b508629713064cbb04d0b9abe21afabb10f33eb38b6b3bfb34908ebf048ccb239701944fe64792b8a909cba14bbf50d03b858bf4a318b9860e58141b7f114b38616533c96c4eb25115724e6672ec20937fab6164aa4a9818acf072c90ea4a5ba34cc95270a330e2874d76a5e0fb085f1aba5917a6e6c3a50ae59659d95703d0a1e9c76c0f0055605ac839f70f6868bf0727496f38c4fd042226fb261ce27bcfab89daa192044462cba31297a660b191bf4440305c5235ec225018cc92480c19bccb480d03d08c470ab20c88c7a1b2a9f37dd7b911cae469de0c7f6e08aa9d427a8eb90af2649aa28ccf1bc19c0fd84842e5748f686278631659a5a874377347ea3894b035a5c139ec8cc0aa63a960535f8e3113f668bbfa9a67a82ccb03253461d3354eb81d0d112fd667a1f133c054730f28ab50f54c5416f65ef60b6ce8c86f6608456c819a7e10ba9232322e4bc73d8370874846643275622b3da6dbcaf9fac7001cce6d34565cbc6f34a1bc9ae904c5229320a3755c4a439f035b5f8a099c70a6a57b5e3e15001bfc19710878c5db0930b21f28603ea4087e0b30a2cba02118fa644331a81312a22ca0721ff266620bc91fe318897b77d3c9b7f9986861879a3a9c349e16c72a9b2bd645915fb05a94ba4c57aa72e93c3decc55597e664ae3a683274267f486452e089aaa8679234c2fde99327a60a81e687cf4491de4b90528492b6c46eeb7725d876a91987025af06895279635e98183bb0ef7267c6449913ed09ae1ba77bba0010b03b900863119011b1dd02aa969ba41b6b684fc3976c416342891cbd0588b5c6a480c04d7798820da67c9142fc07a906f2517a9217398c9611b0749f5556821d93368014d9d01cf2976af6bf492e2e59b66d3671e814e466388e2039037313ac690c3dc534ba77281613560b0fc9bc5a298c87b879835b386c6b0e1580830b689e7b005ae950d309c2e264556685c54c606aab7c0318b2c66d4513a707b8b5800ad2ecc1567807f28122525b69b7e1cc0d1646efcc1673a156429a205e4016887464c39a6543e722f0980b81f524203b45deb45184d35351be963d3906e7b0a98b49167a2e0bac9c7a50db62657c4cadf6985d753c33f90bb1a275be17a7342859415f7855384975775cb557a2eb92801bceb7f63cb97a40837ac159a37c2935157160d518bde11c1fbe18c32923d3049b50b50c2ae0a325281c7a4bc32022aa7835630198103b25398d613631860b70a6536bbc66ef6fc9ab856771652689527c5f5db1d1b4243e3f06460eba75c363715378c99019d213732804b31e30cbe3e93c6f83a7ec239560abbbd48d96684f17ed61c9dafcb55cb168e2ba1778ecb0166e7664e9412f4ec7353092fdba5cca4585d173023f1856836619e57b0052b07141ba9507b042c5d5b89ab429b3f237f0d80c5d4126cb4c59d9d19bf0bfa9e3eb42894228d13a05125b36d1daa647661905cb471b08405207469ebb35ba5375a40b923e6b0cdb3f1070bb6728a389ca4b89079467732ec3cd7a27d746850bd4908e401134b650419e639fba07d88eb2bbb755b2a7ac2bc6947ab8907c80a3b5610a771782daf790874563b65a1236baba0b6fac1e5f242919bb4519b637464565467456600882532457e1249e692bb82e16c7f21c370a29453a95600a069a54b0b62087f09ea7ab3da48348257877864cb080f7a39603e284063da75ec0b9219e515021ba46ca8c573b306e814245d45cee5f55d0e5c7e36a31166634e7805a413a062a7b5a7ae75783f97c505daa8f9113507a98a3e8ce6ff046df83fd23815de42eb44b586845b55b2d39aa000ad80db50ddb1aff6498e12eac2d5dcdd68be66c7a569b0153ab4aeba37a75dc973a08ccf451b049fd51d7a9ad77ae14a81569df8c9bd3a8f1ebea86fdcfb823082" +}, +{ + "dz" : "c121915bfef6abdfc177dae2f5a24218f9abda2559afc6741b08e0e61ab433eb84ef52db5eaa6df8ec3a0bc5ffa730db0dde8c5f38f266d5c680a78d264a7b96", + "pk" : "55f39e77f0722a726811358dc0f0b76aa90aab8c2dfdd3a4f3e31cdd076947d2b503c73b8805b26d6780d75b86d5f3b50ba899bef229beea7d18fa9016878f3aa8ba392a4b42ec4f92f42ad08ccbe58a18bbc7c8639c04016b9c663ca32ebc31fc82a138970c0cd238b6d1b2f2645fa407504183a125b1abeb622245886b9dccb9f2793147a63227236c9cda173c0546739bca51ab24cf3287cf935a8d870719a62b71728fc5e262662296f9984e485101860679caaa02fa1209e7703e0a5678c496a401cc5c1b834ae8c02d2a61b8c40694c634c80290a2f5b4a63f865ed6689a54201589a3384acc299c054d1cfa25be6ab278530b93616efa35cbd0ac8fd367923bd89cfa828f1e8a10a6d027ef2417422a491ac1bdd2702d688809b7455824ac902a70b06d54c92d73b2047567a25336fc74a6d8613d6af0a51c0645ed30c19f3231c147ad98e0276654b9277b16e100a2bc1327ed41043b61900d48c1f51c70725133ae31190b90b43da26335a323c13652a04a2e084827f190915548acd4d96323b573aeb2633be0b3061544cb6b80176337adeb4c5eab7c55bb612e9390419a7598dba6a79523f5764ec7fcbcd31b85c41548e1db0cf1aac1dea8031b0c3b9e629b6b9c06ef29628afc979d303355fc4d1a480fcfd0bdd9c04168e772880a4a53d4182ad30b760c89b2787691b40eb56165f321691f3c4880b20a81d08834c9b2d7b2aeb0e537f5ebcaada992ac0a3402e81e18aa1fd1391f00fbb333d46c7ae50373eba628685d15cb1867b952ed05bcaa8a7efce7c825ec58054b2c84d5c69dc22c219cc71d5a92230b9f40f633029c30bc6b266b37bc5e994e14f96d4c568d83db3491e38ae1b4a320d831cdd5a8e582a1e8a43153c347a3c91919ba60d18490baf18ab8a530066a9c35cb7e05915d208294059b161b09a0b8b446c322c9bd6160d7413974a1b11d0b643364432a1a2bacb1c0d70c642b68811b39a69d44974b125655a64075b35cf9cc0d632493ec46307aba8abbc1033eac4e7ad3329c246a08294f3cb141fad16f10b6804f70597dd6ac34b2b40190c36e17325742a4e9386c08b69cf1e0124bdcc2cea6ce77b310262a71ff7017fa1b70deca96dec183f2981975036117656955a5c4f1c674b09c1624c0c48ad2c2584968f511ba5d070ead9c7889e79b1e123c488349a1f5216f351070bc459f3c8cc8314e16b97266d37675b809fe962914d924d0827cf9b41c9fa169612b70ade609bec43e04345e5b97c330d9216a5a7e42632f09e95469e9b3422041c3119de5e845d6e02795806aba9203da928201905e2fa82c6c7229ef074a230a05401cc9e22076e1c372e742c8eeda0fe7aba76ce5baff468cfc93482a1ab5957cbcdb2295ba074038e539be24986cb8297a536fd479b42c8973b7d03d71d74346625f96234b32323b17c3769564a1a82378dd5c4d23a551024c3468e50ad5b97ca5641272711ff4464d62b9619d130de8491430b5ccdbc928b7e411fef80fb942ab322323da20cdc42b5d17a9406e3612b7970b648817e060030d338689665d3aa7cf2b97314f8237afc890b10097d8f304a26b9664844784ac8d00932ed8b32438a28e5b078484b5324d976422324fd0f217314102ea587d6de84b482992d9e6a6cdb3112599942fd76434390c060321d326bc702376d466683ad546b3bc2e47e4b891f3b7d584375dd3859ed58fe94255fe421bbfc7214e3abe265a1465e58c1067bbbf214db3a94c54876725fa0fdd048764921d5b6ba00c3382d5064baf295b30029bf27a88f8f630d5558d595549b65201793229ca2647621648297a66e92917e409cccdf5cb1378b906c3ba731355d57cad41f6148f7a706f850e99e7610d2c78d45b9f699926a4e01527a1a49886ba5fd25ca21c325e21034246c45785127f4859c0a67cc7b76259410b2f408f4e1569c73c54a4da92a40476402573a2973963406290549f4a41a2226131251c5d59d85e1d5123d527576f7c794842974d884e79927f7bf6b09b752cbbfc442934ba461429a3ea921aba995ef12c21116cfe66b132402bdaf690ed95483aec9785e6989e934e7858bd13498f4e994619ea9cd55a9504e40b4d0ccbe8f8cca1f72dbf74caa3975595623c12f22c120c022b59b2cf3748b17199c44cd37f8ea61ba5d8c1bbe50789ce915df9fce1b4cf3c5acd7ce52dfd", + "sk" : "8146c57021044d4310992c0a37686e1b55240a076646e041eca9976ee77981f4c4743788e5071b28011a2e26c2ca7c3dcde694dd996855ea17dcb241ddeb8ceaa74eb6e90bc7e415028cc4f7280069626196b793e7208b6987516a4a95b4906274b9a154d669ad7a85d454ce905c090aabc30fb68f0a001bb7998772937ee88714fc854dd1cb7f544b7ea345a016841c6eb1bc070066c2134591944016ec8cc5443f57e72fd8020f90f332a0284314ca6b02f8596db0a7244359d97a9a84c07f14939405718781606c80e272a0462fdb2c323c326383a010ab5bb55531a687233af12812d88268a2b73fe0377512e6bfe1fc5f74948a338259654760decb2616f3ab2d80428cd754e27746196b38c399a765b610f46b00f3b717a888b7e2111eb0986c8cdc84a546c420b6b37c882e96e96618b374975c0b8ecb50c6b9bc8d598ae6b46c023b82f3393817a19d09fbacf897251aa9389603321192baf160c0c5489381634320bb2083d604f6db178c8374b055271a124cda7100d48847719704beea14f6d18edca69db74b1e5ccc47cceaa4609a7ac43bc32c8159cb4abecb2800b1947245196bc4e3675540b6d5a29eb7e82db5c3b7f2b70b12042727489170884ecf09b0537134a9aac0cc79568e562695947aac325bc104bb45e83956e857803c563e287a20f9063291b8d1809795a069dbac2525e6cf0e1628ce07a335b110648551ed4471fa166aedb5449f64cad9ea5605bb2c51caa38afac0190c515ff0bac6d8712afb250dc4bc96dcbbeac20c4291097f31611a2a3dda52c94008357901ba6b5a227d5cc744d4a4e3bb97ea0b7cc8b7829bd245e6039e23b9451011334928c6cc22a919e97558cc9a79b988d248186f3acfe7c1ab71500c8671568a591c6306920c19b396923368118153458ea7411cf38cb60779cc9195ce98ea9c0c549889414df119874cb44b332b8789599a713056bc0a6ede61c05777262fb1c7dd03aed0b324dd903b7be44fdba05d192bb5426a86910108e3d257aad1a99fb7408aebc5a758c5728c7375d405c4bb461816bd7583aa2357c83a594d41449f7b7cbaf4d80b3948a8e92cad59a3283f7c3233833ad8c866aaa1cd0b39359a0c60da978046ec7039ecb3bbe752045bb15e8a0c745bab19287e79d844ddaa9eb89a4512b249b637122ba646888a0b14a50473683e05449295f7729980043c03357ec35432585270780805683d04e6a6dc099f7ea4a72b482e090797392aa8168242a5890ec8e89b13ec202a3398a734c75ffcc37a088225e103ac41b52af9412069bf0084c303fc0d205509a7211598d475f4437782fa3637d8c6a7150600061d4458811608ae7d290b1706516a9456c665cf86670f20f2a5f691cf36d1c90772b837747b737029d558cbfd418df8e26e5369bc0fe35e4089c7ea67383ee02f51f5cca36a2a2b867668521ae972486ff865d4e2beca6c4b1e39cac3c61cf131352f036c6292cce7875ce6939544b58634cb62fe6b80c4a4447cba420dca993ae070d3c69d62da3b956897daf687c6e339f8b45760b40c0b9ab06773584584b83a8113bd765815537985d2cbfb784bb3fb50be2b11e79b91129c29b7468638978a1cc8a81ed289cf209f41f85b4b018372c8799e9b7403e10a8a63035417719b3416961b94c47a0d81e51860aca7832b23cc41a541529df511a443e480e31020a1a5b5ac8a43b022b9b1581cfdac0b8d0c082e392c473c922481b15122cf4e47474d6c73f94496d812283173b6361c31ae5251029bb45d21b8aaf3037fba8b3f3744508b25cdcb35873321b6671d94c13148b115ea13b196dc9c3c5c7b37d5324aca344597870f361cb4e5b9450b93ff8a69b8ca3c55bc76845a635584cd0c145b67cb047c0517cf60c8a1146d11274531eb46da9943d8b777df8344f28b8b12fba249398fcc7710ed177c4ab34c0f229e4573c882d00a5a88cb41f4102d309b8a23858da00aa9c935e4e157a7da40885379ade1489b4b75dedc7612282df1969b5e42a915b17cd084788ce92521d6a83a79047e7cae21325d40d357be0b3a47933a5949a4c9b42ff883a3d7130b01843d57717bcbcc09ee13c0b63311df50425e7669540b3c3444a43b775473189d07c1724a114fffe30bb1976004a66ccf811955f39e77f0722a726811358dc0f0b76aa90aab8c2dfdd3a4f3e31cdd076947d2b503c73b8805b26d6780d75b86d5f3b50ba899bef229beea7d18fa9016878f3aa8ba392a4b42ec4f92f42ad08ccbe58a18bbc7c8639c04016b9c663ca32ebc31fc82a138970c0cd238b6d1b2f2645fa407504183a125b1abeb622245886b9dccb9f2793147a63227236c9cda173c0546739bca51ab24cf3287cf935a8d870719a62b71728fc5e262662296f9984e485101860679caaa02fa1209e7703e0a5678c496a401cc5c1b834ae8c02d2a61b8c40694c634c80290a2f5b4a63f865ed6689a54201589a3384acc299c054d1cfa25be6ab278530b93616efa35cbd0ac8fd367923bd89cfa828f1e8a10a6d027ef2417422a491ac1bdd2702d688809b7455824ac902a70b06d54c92d73b2047567a25336fc74a6d8613d6af0a51c0645ed30c19f3231c147ad98e0276654b9277b16e100a2bc1327ed41043b61900d48c1f51c70725133ae31190b90b43da26335a323c13652a04a2e084827f190915548acd4d96323b573aeb2633be0b3061544cb6b80176337adeb4c5eab7c55bb612e9390419a7598dba6a79523f5764ec7fcbcd31b85c41548e1db0cf1aac1dea8031b0c3b9e629b6b9c06ef29628afc979d303355fc4d1a480fcfd0bdd9c04168e772880a4a53d4182ad30b760c89b2787691b40eb56165f321691f3c4880b20a81d08834c9b2d7b2aeb0e537f5ebcaada992ac0a3402e81e18aa1fd1391f00fbb333d46c7ae50373eba628685d15cb1867b952ed05bcaa8a7efce7c825ec58054b2c84d5c69dc22c219cc71d5a92230b9f40f633029c30bc6b266b37bc5e994e14f96d4c568d83db3491e38ae1b4a320d831cdd5a8e582a1e8a43153c347a3c91919ba60d18490baf18ab8a530066a9c35cb7e05915d208294059b161b09a0b8b446c322c9bd6160d7413974a1b11d0b643364432a1a2bacb1c0d70c642b68811b39a69d44974b125655a64075b35cf9cc0d632493ec46307aba8abbc1033eac4e7ad3329c246a08294f3cb141fad16f10b6804f70597dd6ac34b2b40190c36e17325742a4e9386c08b69cf1e0124bdcc2cea6ce77b310262a71ff7017fa1b70deca96dec183f2981975036117656955a5c4f1c674b09c1624c0c48ad2c2584968f511ba5d070ead9c7889e79b1e123c488349a1f5216f351070bc459f3c8cc8314e16b97266d37675b809fe962914d924d0827cf9b41c9fa169612b70ade609bec43e04345e5b97c330d9216a5a7e42632f09e95469e9b3422041c3119de5e845d6e02795806aba9203da928201905e2fa82c6c7229ef074a230a05401cc9e22076e1c372e742c8eeda0fe7aba76ce5baff468cfc93482a1ab5957cbcdb2295ba074038e539be24986cb8297a536fd479b42c8973b7d03d71d74346625f96234b32323b17c3769564a1a82378dd5c4d23a551024c3468e50ad5b97ca5641272711ff4464d62b9619d130de8491430b5ccdbc928b7e411fef80fb942ab322323da20cdc42b5d17a9406e3612b7970b648817e060030d338689665d3aa7cf2b97314f8237afc890b10097d8f304a26b9664844784ac8d00932ed8b32438a28e5b078484b5324d976422324fd0f217314102ea587d6de84b482992d9e6a6cdb3112599942fd76434390c060321d326bc702376d466683ad546b3bc2e47e4b891f3b7d584375dd3859ed58fe94255fe421bbfc7214e3abe265a1465e58c1067bbbf214db3a94c54876725fa0fdd048764921d5b6ba00c3382d5064baf295b30029bf27a88f8f630d5558d595549b65201793229ca2647621648297a66e92917e409cccdf5cb1378b906c3ba731355d57cad41f6148f7a706f850e99e7610d2c78d45b9f699926a4e01527a1a49886ba5fd25ca21c325e21034246c45785127f4859c0a67cc7b76259410b2f408f4e1569c73c54a4da92a40476402573a2973963406290549f4a41a2226131251c5d59d85e1d5123d527576f7c794842974d884e79927f7bf6b09b752cbbfc442934ba461429a3ea921aba995ef12c21116cfe66b132402bdaf690ed95483aec9785e6989e934e7858bd13498f4e994619ea9cd55a9504e40b4d0ccbe8f8cca1f72dbf74caa3975595623c12f22c120c022b59b2cf3748b17199c44cd37f8ea61ba5d8c1bbe50789ce915df9fce1b4cf3c5acd7ce52dfda0237f5f24fca5a18f8f98c916c3e3304d2669330c1042829573e197597d729484ef52db5eaa6df8ec3a0bc5ffa730db0dde8c5f38f266d5c680a78d264a7b96" +}, +{ + "dz" : "d86634ecf96cc2603761e284c0e36734cedec64e7ff486469e38539c71141c5a99daf37400cfe59841afc412ec97f2929dc84a6f3c36f378ee84ce3e46cd1209", + "pk" : "07f76c0d2245fe775fc5cb525824bf945b31bdbc0a86b88d8827ae7fc0a3db8bb9f534a21792637765081c4669832bb66485133f61bc22c55f03b109882b9ad7e75fbf12519873a18d9472087a6fb375244b313f6a81b608d88b0f79147282c9c37084b00138e8bc8cb3bbbd2bf9c5f95766040617962651f0556756bb9121a6bf09a515c6836b650c44e9db72cef47e08079945b8cf19d8bb25641186a8c8999103898492a904c5a7f2befc1614b4482931989ff7fc83ab40781ce54fb51866706cb04ec2c1c8813e963c70b0f15567b41ffdda8d02a94d00d1348911be52163f5c44188b6214856763a409040e8480c0f263d966a99ba7c7d5724f225ab99327a962d1497e9b265bd819c2959b1cd7995d138b4d71804fb122730b6133713d68c95d861a3c567c803adc403cc911186327e1726e2881bc9b4b1873091637c5532951c0c01a0999e7740fa77c1c1c847feb3dcd387ba3974e1ad0310f889d05e3508f02443491261c367c94e074009103e8bccf25520c4546c4bcca7aad34aac89892524219ba9b715c470c72c6c67811764926335f722c03b85c509105d6f43f65ea9908d4c61f7947cf70c4ecc08da31aaa6ac1887bd388720cb36e10521dd88d7b2a483fc5833f8694be9892bbf8bb19b6ceb08a133f037371f287956821014b58c6eb9351946303a3b7fa920e32a471f26a18a0b939ff137927c2a79c27a991040fa0d29b5a89124de37fced8109ff634f6313551140a873a6b76245a2538aeba7a234845cb4ef0c9707a4c56f8baee1329864591d09745fec24b1b392f86c47c38a62b613a8e6dc022ecf58d7d81c0f1e11a27296290ba0cb5bc04516a50fd1361c248ce450b54698c28a59274204427c53c68b5f73c739a62f9d57ffbd17f18c06994f0cc58f0979646a7273b9f0d3493db0a23df085524845418695edd526af36ac6b0b4c3346a2f61317ac8e93cf54351e12a752183c7adac04c3a943c463599adb1f4dd18a69d6a933a14447b73c2502374682c8209706cabba3a2c27b2a108ffa23a6b9732f5bd14ff2ec25e9a384a8bc83855c043a372687972112050901f12b9c0ba8ae7676b1446cfb376b1ddb89af260007abb736b5b223044e73dab7b3566c7e361c5eaa54978a6f3f72c31bf499c0854e272005ec603d3a50426b24a35721c0f1613d55e68e92682217401b9a21af9296989e75588143495907cae38c231c7521197258ecc60bf0409e4729ce5bd436749343a449a9450c5b2af817db83210f9738c0029ba26835c73c4a2b85255b42af98703d1d47106e2b3bf3f6c90c1b0c88e40f13e18f4870aa42555c08e00aad7760321c6fa8151768930cd7c12d1b6149fb679d35e981319b566108b56b98cf1efb9ecb9a3efbb6ac471c6f0f207569eb2022ea0fb0048207e96a7dc805d0d07de1541531848d670817463bbed673b5071227665a157bdb5509eb09873a00b8c98c48a3c131e029576b76f49b7d0152bceb0bb499ac6bece46f54f16b5d7414c8bc27dfdc9948077c090304acd20a4955b350f22253576780696aff4998daab028632ce4b3a372fca46b0bb33f23a52a93c31dcbba882a925c9c6c0c4546ac152a0eac489e9b27ce9c89aeab652920690b6b9944fc6b807d896cce9bf0a0908f05322e184bb7c5b2a4d7459ea75bc700424f884925a2a83cc95241e7701944ccd53271f8b1992afac3bd3f63af3228e9b84a5d1a9483d5502dac28f992531ece7ccec18b14bac48f1f62039861e90cb8ec0681d059788ed147d1e10115aaab25b6b41a66a5e1388557ad56eeee6571ef418a5f0b797352cc013a1176c3b131b499008319c121185a976c5831bd3258b7bd7b3852aa12fb77e9db085389c0a9e1033eb224835d4793c8603296c965bbc699f87b328db504b335fe83010432a4ef2a0b0a4300e29309e3370660f9b21bbd79382970dbf4750b3e142d5f7c381030901e7c09218636feb3062d43ec75a7ff9a640005c1f08669c50d6a41fa86790f2bb41e7cdb401c06c3c035fb812ae2013604422a7e3c1e6aa437ac4261f7834fa95be9e71001b65bd2e0417164142f2bc80366a8e5e1ace65108771b321da81100397a117f00515b6a2c934599416cad1d5091bd23708e45eb6f90a2fb5c47c8c77d6e395a6332a45f4178b0959466f648ec5c43422397d4e771f902db7b8d876a028f1708e233d", + "sk" : "617c1296d2bb9802655166cb0c2074c206ce03fc18f252ca7f7a66d3e619acd48697b3a5d9845f8cba2fe98654b56cba727786ae19c961e447c07ab7b9d30a64c85659429fdca3a01823c30a8335014a2472898d963a3407980a63c6bdf5aa79bf2aa7da370f03b593ca91c77f998ad93917711b7639e448a2036b86489489bc41a25404f77b0436b7810b38a3b729472b26bb47c70337d575ed265c22b86d46a8c7f1c668e56a66f3d65223f0bfe60b472a90a463881ed587313a45a675b9aaaa7a618da1165d143ea764c0eaba20ce244f8e3acb79c9be141b73d8d00bb6db5d27e30c2ed5189c31406f154560d7832cea31d40533a45b1811216951099f59896d25e1c1e898ba033aa6107b703cc7cd357b0d60118fec352b5df527fc0245f7a44fdb649c01b1b9e410b8990c689758aa606c1ba559075e2c3068e865cd835aceb37a78268e8eec1e1c93a619abc71c3305e6db35b58791e8d00febca9d3ed37b62a818d2a12a66d591420cb38896248a5792d2716c63c6949b804ce27768ac78a974e42be1437cf170464610223f9812908c29fb748ea9e253d3d8242320b4b0125bb094c7a2f635eea0ad60abb710f85150d797502617fd4341fbd58835b48412309330d3859e1140ba2443f6970b96c154d5b9429fb1a41ee6a30e4c4b919642fbd288629c68301c363599738a5571deb84358c571311737c01101e00c490d918260d7172efbcba6b8544d96a384101be6f64e946012cfc91125236b8a54781c4ab58dac60f737021c5b6e45b0b4fcbccb224bc7cb1b551ac35fd99a5f9c0cbdffd64d43fb3588f177489a02340b19fa12b2f3ba61f6d53a7a0cc1e186bff1a49cf22c500537933364a7fe257a5519c133aba7ab7648e2f7c6869b6531723cd03673afa10eb8b30ada830d53a4c7099695e8f4242454382e752b86fbc8bd361c058986d80699e60039437066db9172a6d8b3274a6369402c12a885a5e5136ab8b10ab8c7d3361eacb7627f16cc411bc7e2b3403d6b5f53b31f6a6657c2464eacfb796afb6a172a201026b3834bc70feca013fa036b5611f6f81013ec66017a4b1ea043f52c02ef0b55f05b6f65783a4dd6641496988e3a84364352967ca26302168ea81405929a4c72c30aa14f83016692413399630b582078fa6574dcbb29f17c5b85e3134e8c2db35c73b4683abd8b7ddf666ac1501b56d855081054b3085144a57f74246464bbc226c8605f71bd620562c044b9a6e656e7640549147819e124afe991fa28b049b388d150a313829144262234f46779264ddae5725469755a3594cc42cf29469b8a35016d170323601131b72304378a66f41dc0e43792915f5f35b338822ca6c7c9e6273f6ff36fc022522732514bbabbace610b9d952043c8d9ac98e89743faf9b2dcdbbb10aeb07c636001060a165d41309b46fd7d32c5f05c138d33cd06c3f316117ff90831aa5b6e0e054d49761ef3b2c6771b0f6f7124e5b8ce0814104500e704c84202b02deb0b78c17883ce72444850e608620c97290af3572f2681460f08e1fda10129806f6431317daa1e091889b7573c9100d16cca12b77a27706a34c5775bd494f13eb59002847d13163e777886501a497a7bac4ca9166b1c2ed27249cf11f135876b4c50c2febbace470505202a8fe10223b9374c6520ad4075dc30b0c4d06ed30877beabb108a6659078b7bd56c9c3d6a83f1b4380019cda1c5c6519145d515dd521449b717a98335efedb5e301a9d72467b4b458089d4242620697e27887d5b88b8259d0564ca792a3395649d4f458100e14f09400e8bbb77d64bab25407c95bc792115bd88e767b3d7c7eafca87dbb27e7c1989e74817b723f348a0a4d3b2b3506cc150934f6f50bcb676b756b1b1a401822c853b986b00599c61a269dc8a1b54227963fc7a7608952e984b90e10a9a81172b2577c7fd9ad3ce4b319fa0611f46706ea596af024831248ee19258c4b0d9928aae5208c4f3621c7696adb95a7cd91c39157cc4ab735cad892768850493b4509564ddef09eaf84c6f86638a1667dad3b2076cb93fb538d02a5c36e28240c367ba19717fa695dba621359f85c05e740bfc2ba1c146dfed60a88785179373ec49680999aa616e7753d3abceb4a2ced2a60c0b00bb3a90b2be5cac300b107f76c0d2245fe775fc5cb525824bf945b31bdbc0a86b88d8827ae7fc0a3db8bb9f534a21792637765081c4669832bb66485133f61bc22c55f03b109882b9ad7e75fbf12519873a18d9472087a6fb375244b313f6a81b608d88b0f79147282c9c37084b00138e8bc8cb3bbbd2bf9c5f95766040617962651f0556756bb9121a6bf09a515c6836b650c44e9db72cef47e08079945b8cf19d8bb25641186a8c8999103898492a904c5a7f2befc1614b4482931989ff7fc83ab40781ce54fb51866706cb04ec2c1c8813e963c70b0f15567b41ffdda8d02a94d00d1348911be52163f5c44188b6214856763a409040e8480c0f263d966a99ba7c7d5724f225ab99327a962d1497e9b265bd819c2959b1cd7995d138b4d71804fb122730b6133713d68c95d861a3c567c803adc403cc911186327e1726e2881bc9b4b1873091637c5532951c0c01a0999e7740fa77c1c1c847feb3dcd387ba3974e1ad0310f889d05e3508f02443491261c367c94e074009103e8bccf25520c4546c4bcca7aad34aac89892524219ba9b715c470c72c6c67811764926335f722c03b85c509105d6f43f65ea9908d4c61f7947cf70c4ecc08da31aaa6ac1887bd388720cb36e10521dd88d7b2a483fc5833f8694be9892bbf8bb19b6ceb08a133f037371f287956821014b58c6eb9351946303a3b7fa920e32a471f26a18a0b939ff137927c2a79c27a991040fa0d29b5a89124de37fced8109ff634f6313551140a873a6b76245a2538aeba7a234845cb4ef0c9707a4c56f8baee1329864591d09745fec24b1b392f86c47c38a62b613a8e6dc022ecf58d7d81c0f1e11a27296290ba0cb5bc04516a50fd1361c248ce450b54698c28a59274204427c53c68b5f73c739a62f9d57ffbd17f18c06994f0cc58f0979646a7273b9f0d3493db0a23df085524845418695edd526af36ac6b0b4c3346a2f61317ac8e93cf54351e12a752183c7adac04c3a943c463599adb1f4dd18a69d6a933a14447b73c2502374682c8209706cabba3a2c27b2a108ffa23a6b9732f5bd14ff2ec25e9a384a8bc83855c043a372687972112050901f12b9c0ba8ae7676b1446cfb376b1ddb89af260007abb736b5b223044e73dab7b3566c7e361c5eaa54978a6f3f72c31bf499c0854e272005ec603d3a50426b24a35721c0f1613d55e68e92682217401b9a21af9296989e75588143495907cae38c231c7521197258ecc60bf0409e4729ce5bd436749343a449a9450c5b2af817db83210f9738c0029ba26835c73c4a2b85255b42af98703d1d47106e2b3bf3f6c90c1b0c88e40f13e18f4870aa42555c08e00aad7760321c6fa8151768930cd7c12d1b6149fb679d35e981319b566108b56b98cf1efb9ecb9a3efbb6ac471c6f0f207569eb2022ea0fb0048207e96a7dc805d0d07de1541531848d670817463bbed673b5071227665a157bdb5509eb09873a00b8c98c48a3c131e029576b76f49b7d0152bceb0bb499ac6bece46f54f16b5d7414c8bc27dfdc9948077c090304acd20a4955b350f22253576780696aff4998daab028632ce4b3a372fca46b0bb33f23a52a93c31dcbba882a925c9c6c0c4546ac152a0eac489e9b27ce9c89aeab652920690b6b9944fc6b807d896cce9bf0a0908f05322e184bb7c5b2a4d7459ea75bc700424f884925a2a83cc95241e7701944ccd53271f8b1992afac3bd3f63af3228e9b84a5d1a9483d5502dac28f992531ece7ccec18b14bac48f1f62039861e90cb8ec0681d059788ed147d1e10115aaab25b6b41a66a5e1388557ad56eeee6571ef418a5f0b797352cc013a1176c3b131b499008319c121185a976c5831bd3258b7bd7b3852aa12fb77e9db085389c0a9e1033eb224835d4793c8603296c965bbc699f87b328db504b335fe83010432a4ef2a0b0a4300e29309e3370660f9b21bbd79382970dbf4750b3e142d5f7c381030901e7c09218636feb3062d43ec75a7ff9a640005c1f08669c50d6a41fa86790f2bb41e7cdb401c06c3c035fb812ae2013604422a7e3c1e6aa437ac4261f7834fa95be9e71001b65bd2e0417164142f2bc80366a8e5e1ace65108771b321da81100397a117f00515b6a2c934599416cad1d5091bd23708e45eb6f90a2fb5c47c8c77d6e395a6332a45f4178b0959466f648ec5c43422397d4e771f902db7b8d876a028f1708e233dc266d76c52b2a849f00690ffb252699d5b3e9f66e0abd3c1362c39cedbc6985099daf37400cfe59841afc412ec97f2929dc84a6f3c36f378ee84ce3e46cd1209" +}, +{ + "dz" : "0610678ff4dc3128e1619f915dc192c220f8fad94da1943b90aaec401683a492da1804ddb5aa9b1c6a47a98f8505a49bae2affde5fe75e69e828e546a6771004", + "pk" : "e4f12b6f27cc55032582857549f3ba0d6bafeee47ca2e2cee04b023b066f53f75a5dfaa0aca416ed16cabdb510564738aa08134346757f92585ac112c25a6e0723958b7b23bed41a126617b4dc30de275bce903a1c6c2a28c5c58c49a5f0c447fb0c86f5b6a6e9d271383588ec398fe6928f04b67ead2633ee174564cb2115a55d8a53971e0c9fe2a209f9c8745467bb8d9944e6c1bbc8a54a5d28cf82e8815a3615dec5695d00c0e72b2f7c483f72d36d2f091cd169311a283a42d608d0d66e020172a6a799a66c10aa9b93a9dc5caefc805cd77d567390bf017693db8b33392bcf96011dc88287375bee828341e5a515a97c019895c8e68d41c0675723af42b6a50da91d04c9880d21a5af9929362411f5b36c75199211da655f454539aa399ec276af29011fc2b5e7f5534461220ec3ad3869178109a282e8a960b6119d0a4ce801d05150c636d20d70dbb092999bd2ab9597a0b1de56086c27ca8f5c22b86995e5aaa9f6514323a31750eb794adc1ea1247317f82eb443604ff254e99a895436060291afccaaa1fa26b20fbb9f48e462851513f7707a5c3461e3f4b3b4e72ba3089c53fb85b9c0576c06b2dc832fafb929c3b34de6974021378356fbc4e1282884d062b831b9adac1eece03f5be7c9c7e8b69b1a7a79304842231f0ba1107079416b388a074ccddae26b4d22693f95a8bbcb2f3445ccf74abb702428fd3a04bea9ce55b6c251c57b6ff10232a6a85832530835883336a10992cd30144b757ab6a6377389e36093e218bd09cca1504400a7a473e248ccd40567637183ccbab9bb2dde7198abf35df8f8c836e1bfe061448b133898fa6ce3abc79beb4ac8d9997c12588c908aa1002b2570a64654c8bb3c1914583748b95d13f9619659ab4c8687f872030df926ee04b6a74047b995625b1a9a929a7fad134f989c7cac25c42817bd9f45327725474a629df0944f5fd3bf06057355f2843e8157115361cd627ee6d548230a89ad49bf1b156e50cba74fc19a63ea2e01796b6ef4a37d4212897346da865f5c36cc49a6954a8a868ae195bc4625300716d3b3692e683a10d9192e2ac5d096c465126730a9b72bb3a729a7cf39922674e39900dbbf91b2785e301ad8a3843f875361b5c4ee0953ae34a583b36d0f54cc194800be6b0a6465479c51999d5029ff50117d5498e8c6a0c81bbdfc6c220b21a310993fd5e7691834732e358faaca460fa26ad20044dbb7177c47736c412bc9011f09a0ba4d22aefb485a524bbb8f74bddcf78358c8addec550b86895fc3141682c0c323210ed756864910c9446c7d9983cfa98ce9edc644967cc93b7008e3c9166ccbffad008cca6569ae913e7327c26032744758f2e82a70f8a399ac72657995ef2754e3184c263ab93ced1510bba1d0838a13aa2cb9d7a25c236a37ec37fc5c0093bb47dace9944d077f5c837d78c54e3fb1cb0e8a70c4a18b6e8b95f6b7be2b79b802055ad4ea5febe770c39757ac42a09feac48b6174bee79621bb3af7d0a0094895cc8b6aacf722eeb76abf6b6f0d66bdc545c68c845b22cb167f96a0448b0cf812c46793a28b55a600a1431374b570c93d6dd7b4f789101e578e29d96b2384a8e09115f9e1c8dd008d0047926c17285dd996690b4ee9957cde5ba56451bc2de46371738e65744fbbb558537b33581998dd0525ebb9c17d9777a701a676956a03bb4911070d83b603f5169f66838cb671627b899e9706be9460ccbda50135d504e2709ac31c48c4fa67eaa740bcba4173ec25fd7766bca198fe4122fe93be5b646b1a475c74ac276bca3904a7c119b057dd2bbade1701ff249f484a4bef04392122c416aaacd5726a273066fc510f394903b5f34860206d8c45a4cc340440179694223b8eb578c5bac2cdd183507946e3d02c0e219ae33008e19822d77acfe5c85bfee7a0b6aa0eada58ad1ca5ba1e12ac92063c326ac4140250be091b2095f568ac7b483acafd7045a229954b8583a33376ca7b19a948a10c4a45a5b80d403c89773b7c2c67ad1358bf2900e8a793dee71b91c978c389b4d8c824937e921a17914c6d1a4bdd6460a2c7cac50cbb2f006ce9c98c7a3342f9acfe11094b249870afc3e15800701d606471a7a0dfcc073c277bb74706e5571f81cae7331a7d1e36dfb437d7d52957526bda146bfa3530dfc93063fecb103ce58c30abb5bb70c6dbc92e5f3bf4060", + "sk" : "de8539327c009f37124d009dc3d112be749b80e86ce81a4edcc802e757aeeeb0bca029441dd2193c568063599dc8d87209775224a792fa020eaa02aaaeb0c444336d94d38a1a156ddd4014070c197e527d33ba3a40b496c8fb19f61353ca32ad986664cde663862534a7351ceea4779fec825f8ca93aea7f23883548989f23f77a25f99ba847b427d319145cc8e32656e83b6295f50a015263c75ca8778650624ab7409c0f45964a8cf466d2fc95417807a481a1d2062629b17df583b254124342316153fb5d45f67bba6024f6180252b6b54662cb2ad793704c51fde4bcc758314dec86e6751ecd6a0324aa123109c38d356b0dfc9676c087bd7c945871a33e46c0924b8e8e1b6777f530615a5e3a71c95ca532c8255e8eb6afa1b0570be3b80fd1974b170c3cf30559d998e0684f92fb1bd4fa79b5bb5aff34443c0c1a5423c42833b9753b1f98e46a024cb1d3074b00f101802b105a89b95b306a7d546f1d357cce202a71043ac2859265cb768a29cea051810a08965c773546768c09a66aa76710ed954269070fc886a30eb42e33c4cd7ca650cff5aba39b7b0ad62311b92139805e89dcb14507c0dbaa6ded775bd1107fa1e1c5d2a61ba9d732df58b8845b4965d001f78066261794311701330b238483bf61780f7a4082881aa316892f5cab105b5519ad111bc7e32fa5f23f98202cccf67d825826cfc50a6db58c15e12a6d84c185b469b0f94022550eb72a4332d4377dc356a5b34135d1593117651a5c0f0c87580b392b8643386167119f4651b7a433d7104f9a216486ab6a6e0208ed6b75b93989797472391c3464054eaa91558e1b570bb2116ec964eeaabb650896bc296c93a090bbe1c79a320f4e94a2a27122fa8c422a0a4d318c62cc840ea2379ccda0a4fc71c1fd7759133520b8ba0037f688f2a3057fac7fc5e6b3d3b1652c2567b092b7add6a542c182c579a366d620c2f40e59a13983609df8d2c6a7301e0566323f00132ec9a3ce800892304ddf74411d3932c27089dc987e8a3755fb010629887e0e518acca18110ebb53a48980091ab4c156185c8965acc1d16d702efc301fa88a20c5b4fdb24a25e0a6822c9cd9d6b7a095c2e14b027ee38319fc0827c5c393fb6c3eee59cf315031e5baeb6b08753c7aa0cc7cf8abb926298c444352b50d12e7f2474aa065eb6c16b1b660f3a1a80dd36151c8b40bb265cbafc87c526b89b860de3513770110402734fc2a3568aab6e751233f5da9a7f846f5e4c7d318595f1989d557312d791261e642fc93b23e6378d61fa036cd11f0e3723e7790551d010cba70acf913acba674393b06de7aa856953f10ab2ec7f182996695d4bbacc5457b904b7df2fcc73bdb62c047b3c7377e5c41b247fa1f562c57d4a09c6b9710c7675e267263cd06781a5b63a58c36c94317509540a81063cf97af65249eb6648290e10c627b1029fb593a05cb575c3f63f280d367cffd0c9a8443836235b90201c5a8c53380b4b3c669936f965337acc72c05ac5b441fd8dab2ba5259e38c9b87c98bcd9646aa397961a160c7718808c414ddb05742189ec4730feb020d92f84296dbb97a453f7f4b09c965a6652894e92350f097b184a1bccb0728ed70c0da600b3e3b1c6cf0790135a329b6b3c86c748ae6840ef581939c81ccec3848f15821643e4a41cd9b48b1e0979a964c858de00c67970ba281a4d70678d61a0b6e5b93cf7b5297c6219c1733670407d8272491d137bfccab4709984aba8a3842415ec337e6eb5e22b4855aab21bb394c470881bec25f21238bce98caa9a44e06277870a74426bb927b46cb63f10d116bc94232c566406b79c1199cd16dbedaad1404ae4f98ba38b58d6f6b7b46fa21247b0d93d58b0081c5473aa14c7964d56496739214033c34528a8b51d0857ad3b18699cf7a025e84d91788d906e70c011cdb3b291019e2225696a2c61d0787fe445b6e36c64231288f3854e52aabd1295cba072adf5b756aa19c9b079084c204ea1bc7b65a34a2e8894fcbca16b42ddf415b40b73d5bb36ad2714b233c899fd42040502a9ac208c031885791323a9b706a35cbb9f935de1633d1b6b877d5c402e92e8d06117ea4a8fb709de91320d5aa554d77a945b30c127031030858c066556c957fa8813bf9f4bea15257905a4de4f12b6f27cc55032582857549f3ba0d6bafeee47ca2e2cee04b023b066f53f75a5dfaa0aca416ed16cabdb510564738aa08134346757f92585ac112c25a6e0723958b7b23bed41a126617b4dc30de275bce903a1c6c2a28c5c58c49a5f0c447fb0c86f5b6a6e9d271383588ec398fe6928f04b67ead2633ee174564cb2115a55d8a53971e0c9fe2a209f9c8745467bb8d9944e6c1bbc8a54a5d28cf82e8815a3615dec5695d00c0e72b2f7c483f72d36d2f091cd169311a283a42d608d0d66e020172a6a799a66c10aa9b93a9dc5caefc805cd77d567390bf017693db8b33392bcf96011dc88287375bee828341e5a515a97c019895c8e68d41c0675723af42b6a50da91d04c9880d21a5af9929362411f5b36c75199211da655f454539aa399ec276af29011fc2b5e7f5534461220ec3ad3869178109a282e8a960b6119d0a4ce801d05150c636d20d70dbb092999bd2ab9597a0b1de56086c27ca8f5c22b86995e5aaa9f6514323a31750eb794adc1ea1247317f82eb443604ff254e99a895436060291afccaaa1fa26b20fbb9f48e462851513f7707a5c3461e3f4b3b4e72ba3089c53fb85b9c0576c06b2dc832fafb929c3b34de6974021378356fbc4e1282884d062b831b9adac1eece03f5be7c9c7e8b69b1a7a79304842231f0ba1107079416b388a074ccddae26b4d22693f95a8bbcb2f3445ccf74abb702428fd3a04bea9ce55b6c251c57b6ff10232a6a85832530835883336a10992cd30144b757ab6a6377389e36093e218bd09cca1504400a7a473e248ccd40567637183ccbab9bb2dde7198abf35df8f8c836e1bfe061448b133898fa6ce3abc79beb4ac8d9997c12588c908aa1002b2570a64654c8bb3c1914583748b95d13f9619659ab4c8687f872030df926ee04b6a74047b995625b1a9a929a7fad134f989c7cac25c42817bd9f45327725474a629df0944f5fd3bf06057355f2843e8157115361cd627ee6d548230a89ad49bf1b156e50cba74fc19a63ea2e01796b6ef4a37d4212897346da865f5c36cc49a6954a8a868ae195bc4625300716d3b3692e683a10d9192e2ac5d096c465126730a9b72bb3a729a7cf39922674e39900dbbf91b2785e301ad8a3843f875361b5c4ee0953ae34a583b36d0f54cc194800be6b0a6465479c51999d5029ff50117d5498e8c6a0c81bbdfc6c220b21a310993fd5e7691834732e358faaca460fa26ad20044dbb7177c47736c412bc9011f09a0ba4d22aefb485a524bbb8f74bddcf78358c8addec550b86895fc3141682c0c323210ed756864910c9446c7d9983cfa98ce9edc644967cc93b7008e3c9166ccbffad008cca6569ae913e7327c26032744758f2e82a70f8a399ac72657995ef2754e3184c263ab93ced1510bba1d0838a13aa2cb9d7a25c236a37ec37fc5c0093bb47dace9944d077f5c837d78c54e3fb1cb0e8a70c4a18b6e8b95f6b7be2b79b802055ad4ea5febe770c39757ac42a09feac48b6174bee79621bb3af7d0a0094895cc8b6aacf722eeb76abf6b6f0d66bdc545c68c845b22cb167f96a0448b0cf812c46793a28b55a600a1431374b570c93d6dd7b4f789101e578e29d96b2384a8e09115f9e1c8dd008d0047926c17285dd996690b4ee9957cde5ba56451bc2de46371738e65744fbbb558537b33581998dd0525ebb9c17d9777a701a676956a03bb4911070d83b603f5169f66838cb671627b899e9706be9460ccbda50135d504e2709ac31c48c4fa67eaa740bcba4173ec25fd7766bca198fe4122fe93be5b646b1a475c74ac276bca3904a7c119b057dd2bbade1701ff249f484a4bef04392122c416aaacd5726a273066fc510f394903b5f34860206d8c45a4cc340440179694223b8eb578c5bac2cdd183507946e3d02c0e219ae33008e19822d77acfe5c85bfee7a0b6aa0eada58ad1ca5ba1e12ac92063c326ac4140250be091b2095f568ac7b483acafd7045a229954b8583a33376ca7b19a948a10c4a45a5b80d403c89773b7c2c67ad1358bf2900e8a793dee71b91c978c389b4d8c824937e921a17914c6d1a4bdd6460a2c7cac50cbb2f006ce9c98c7a3342f9acfe11094b249870afc3e15800701d606471a7a0dfcc073c277bb74706e5571f81cae7331a7d1e36dfb437d7d52957526bda146bfa3530dfc93063fecb103ce58c30abb5bb70c6dbc92e5f3bf40602bfa2721399623d76222e93d092c34792aa8308d8999aac7e17433da2166292bda1804ddb5aa9b1c6a47a98f8505a49bae2affde5fe75e69e828e546a6771004" +}, +{ + "dz" : "d322d56d8ef067ba1f24c92492b9c56df3a6ef54a304adc1b69913766a1ce69756047447b810cc094d400ab204cf9ae71e3afa68b88586ecb6498c68ac0e51b9", + "pk" : "1e778910b9afed44842d78417cd027f819699af6b0ab475a18b7359817b50c306bba0728c5a9088e667dcb7944af6c10ba86300308165c1242cbe8708c8347c44ab77478304efc0a9e5328f203b90108418fd1b5b7c3b085e74cf500729e27719c2596feaa689a54ccb3a5a4a74acf36c652fb97ad49190cc6f08382017db7a910f816701957cdd8449ca075b9a3c18bd88469e3f51e0c967146413bdaa15c38284a726a8935b3987e774a182023cc0acc18a80b8b6909b52b8726881380b204cf1c069415a99556476b0218ebb4217ff33a0593be5f3cc47ef89c13397d68933721c5a6f1241b88f452654c249d35c1a8b16305469586435c1a6156f8520ad33938c8dba429c118154020205b0235262f233c36a89b384d82bbc49b6d6074517a631c5ed285f56585b286462872503da5c3df9c91340071eec625f8b29e4c416e93b46d37f95822ec35c2897417d7181dc9a7097aa74f3a02bf1420b1a568e1d7b1a743c0d07623e2296071912f7db25d67d751fb3b9ffa671403f29d162b635f0c7ae693578d2a752984914eb9036bca365a76861a05075b4b2a95077b6600a42e071d60e21618a689e3f7b5c9836b7451997ef80917f6351f814e2ef1786736a703012d3c9ab9db50b5b9f08bce69ba50a2c48f059dde2181f725cf39f426b39028402acac36bc0797c918d30a4a6d4bdea2927cd75364d167f34db97260039bfccb64b0003ab3532f77353fb6a0433a5a95570c2ccbc77f0e4bec1584cb1a88735f27acf58120d01265cd7236f18af3c00b4363cc372fab07ef3a87030b19b07af020320f1f747e32a8bd1f32e78f1a62960a43327307d8c212d1044689805be15c1c68682d0a8a24ea51267058dc4b15f36e12104ea83e425c248209a8d193911e2a2dfe3a47f485abb226f02919f9bba4014262ffe6b4607bbb511fb5fcc205134f8aae2310245b9c9e73957a2b5b4cfe0916dc1bf6ff891c645b28e63bab6c23e5077a8c3954fb5978ad8e07dac5c5c1fc4759912524566785df222d04435a6a24361178d917b53af57438b46aeeac546bb5207c186bd196bbb6277216d95ab6e545d78e04b82669d19093241b808aedc5db79a9e54762074a0aed86931497917969ca7f20942eee719287c887b3508f23b919418278be0236043acb3e4abac940c44c3aec3ab8c78bcabd84c1d373899369b515c2478c6085ced3b08f668224f950d3b82355468bff0534cc7660045e96ca40067de520091437309f7030f71a250c359f0c71c2f8819b62cb39646b19d63669f679ff9f48ac7a426e3fc1a1d358b675105f28586726304adb8109e104715b6c330f053961207eb96148a866c12c9349fb6aafd1b42f5f80a2d827094c3b4def6478212332d96359fb3450cfa6bee8327ea707b8cc61799105358521c6199607d9b769b38ad15e4b638d12d16aa90aa49cd90b9047696acf9c14cbee59f82b46de5bc644402400baa2e839ac801c70a368a3611cb11a1484dadf30185112f52421196d1797a3085f5d429d286343953ba8de676c381aebf394d0453bf1610905f3b6afdd5299a750f2333b3944067d9a9cc201922f9b5162cc41cbd35400a275717228050a97d05d0c1b303bad3405f36a1218c5c089c98467aa37905b334edb31f667a88c2129c1749784f49b83a329275e1b5fff4798d4b1c5779a5d433ce716bce5763572a29cbddf5b40b464f3e163cd5b554c5612c20726f57244735e2616f45356237263d69a1e1e03cc4d9ad57c83b3075cfaee45418282261d8bb531b685c766989c28ae9f991415907858308a1fa027156b6d3c8c0cf926553b570fd077b6fc419d8f4556655ce53f6802d406781b06463042304477bc8ea19757bb54f2cb54b9276fdd575d5a00c267b1222d4c25de11860dc14a1f3453423caef02bfe8720472c194dd234038f8aa0d3118286b530247b88a83318fda0a9c226cbcf22510f681db3880c2208b70f67c124437dd32ab9120894aa287c7040e06f6cdd0121ede209068238b57716db488335564c316111cdd90741a197646874922ec355a26a7e5ba4af5873f974b2626b40afbbb5c59501fceca0c9fc76fe9b8786ad1c5c76b071b6c054aac0eb8e0535bf8a4249a9256e4c1e8ec673fb5bcae20063a90b601e047e9bac3ba827acfba4a7e9b040776bd6f351e548ee005d759da86c9b2971f9d6d1cab8d", + "sk" : "7592584ba97569a4cc9c918d9deb2312e81719fb4286d67866e9a14fa947f220692ce29d0f68a97f851e5c938db1587180ecae36fcbdb8eb19d96302bf38a02e0128fa562ba7a9260c873460814ff3021d511482f4f731f9a152ca42c920285003025c5aa0c77698bb5b778c1f864d696c0dd4d634421224c7d14287d625b422062310af94c005636c8f15a486e3ea3151b5230e337aaa59235bf7968d9c7b067b8d1bd6247316047d0568aef514f725befea696ef124f10f822d45773e780226730b8aa043f80229ae2200739392a3b42c0f3833da3b18b38c243f0a72760a917581bc6d2784cd4b796e6812fbde666fbda9ce9522a32242a644032f144c4904031100c12ae7a3aa52aa3eee02f27909736a8bf9f8992079c76157001c64b08428a5acd67762d01c4009d4ee71c3c9047751d89b0f6020ffe848bf3013a5e4c5c3db6457c55bfc8d62f6db63fd4ab1b51a06b43f8b7eea0ab5987bda78278d711ad53a6b5fe58ba81c5931c9b1edc74643115bba84ca0621a9c3e49325f8b583715142732c4e0ea713f36c6fbc3c90a467757c798ede3368015b95a62adb0a62a12452abdda5e0b9a882eabc2f1150157e8aa950010efe51f29b3c88f132a02e311fd75497bd21828f428cfb12bc361250b3a765e022d70bc3544b55df119adbb5c63399172ccc7bb6f392f04cc02f96aab64e0b46744abfe9acc869487f929317ae1c103508556f688be7c3407202a79e54f68683cd066c537366bfb918b3916a8b030b0cc1301e1e4b7098a47cbb46d417caa00418e9020629db0bc597b2a9008cfde2bbcc777ac7bd55f2215502fcb3f803075037a56e70c8b4f3b44b9269824610bccd15ca8a3c52357bd582c52ea217b22627ed9eca00e390e7e890e626b75af7bb9f5d8a05c293642c51b0d399d9d5250b19724d22b3f1010389bc38752a032622bc44fc4ba074b0b1ee753f6305931fc3cb7b0c88fbba271f0722e73c83e8c49a120cd3130471a78c10df4cf52952829e596bd651ab39c430c4c4904b55ebfb06f74640dffa40d76c15e3779bb752ccb3d86ad225b8333208ec12c50b7e923a9f67b3e77aa55a8486cba6efab46ce56a7adb92739b264617ccbdf5f41d5797873a42b36f26a6fad310df949f9c670014403136522fd5530e03263401f3138847c363e400477baff7c38ba4631a19517bdb61b8cd3868a7c6bde90a97d5722b9c5b17bf05c60822a705179d018a324e0ca09b54998ca8ac188b0037e4b563b479c4795562591cd3e06f64bb83057631b243cd981819a3655f68b506fd0cb52237c9b9166d07f46a44c22c037b7b07250cb5088a96473c9d225b79aa8c09245d8b9a71496ac9ce658d0cc329a1bb3fbd03c433e413f355515b2373d8158a40562501fc46c0e7a4e903293442a2d8bc0fb26a1475d2ad52cc1b99229c4de5a78b7b07d84475b5e8651590916a4978dcf72148838140896e210a3c328486a315a9e15592b9945730cccd1fd75ed55a74f4897e63b3a1d8b96d5021cbd0b8141176af3aa4a69ae6c634419246ba662f5739e46991b09c631db407e1a94eeaf717f92a977a448e67891be2006da0371aa0b0c581db7a605080533b2427194df500c4d4d17a24a6a98f96714556cba48327ba2abeca7c06ffd382133621cbe68d9c11b07ff458e584848473431b488ed6730aeb26093288058b653cfe453ee00c3d97d35e5061660f246ff10c75f6ba6b404a48d537a846c06d02b7242462b0c0a80cbfe9022d97852c290887d0766ff81cb9a08f0f06bf00d6996c962ebf4139739709bbcabe7e770f01fc720bf015e81517d1a7ac1fa69236d452f783c0dcb65cfde091c0b8abbdb8b83fd2134e7434452c21bfbc0d5fb81f631c2afb1c0f65ea0172999c6888b2c39a8269fc383c06105a34194d8bb64d31bd56e86e5c3758293b7844fc5412a7b7d9cb9a614420be1c079ae9830a494f356b99e9981e55b5cdf2fb227f2a8eabb86531a00e42f07c0e1a0b198bb198ca8252763b62872ac7c742ba04084df82f542b067c23b72fcb51dfc9a4fa2958ce0c2ea4265c1654bb2090ba81273e83faab505871ddfa6c76062b3308ae5d8143e258793130431a16ce5e7b62ba9b90dc776e778280d0f2b8cdf7bc8750a96b219eda180621707f1e778910b9afed44842d78417cd027f819699af6b0ab475a18b7359817b50c306bba0728c5a9088e667dcb7944af6c10ba86300308165c1242cbe8708c8347c44ab77478304efc0a9e5328f203b90108418fd1b5b7c3b085e74cf500729e27719c2596feaa689a54ccb3a5a4a74acf36c652fb97ad49190cc6f08382017db7a910f816701957cdd8449ca075b9a3c18bd88469e3f51e0c967146413bdaa15c38284a726a8935b3987e774a182023cc0acc18a80b8b6909b52b8726881380b204cf1c069415a99556476b0218ebb4217ff33a0593be5f3cc47ef89c13397d68933721c5a6f1241b88f452654c249d35c1a8b16305469586435c1a6156f8520ad33938c8dba429c118154020205b0235262f233c36a89b384d82bbc49b6d6074517a631c5ed285f56585b286462872503da5c3df9c91340071eec625f8b29e4c416e93b46d37f95822ec35c2897417d7181dc9a7097aa74f3a02bf1420b1a568e1d7b1a743c0d07623e2296071912f7db25d67d751fb3b9ffa671403f29d162b635f0c7ae693578d2a752984914eb9036bca365a76861a05075b4b2a95077b6600a42e071d60e21618a689e3f7b5c9836b7451997ef80917f6351f814e2ef1786736a703012d3c9ab9db50b5b9f08bce69ba50a2c48f059dde2181f725cf39f426b39028402acac36bc0797c918d30a4a6d4bdea2927cd75364d167f34db97260039bfccb64b0003ab3532f77353fb6a0433a5a95570c2ccbc77f0e4bec1584cb1a88735f27acf58120d01265cd7236f18af3c00b4363cc372fab07ef3a87030b19b07af020320f1f747e32a8bd1f32e78f1a62960a43327307d8c212d1044689805be15c1c68682d0a8a24ea51267058dc4b15f36e12104ea83e425c248209a8d193911e2a2dfe3a47f485abb226f02919f9bba4014262ffe6b4607bbb511fb5fcc205134f8aae2310245b9c9e73957a2b5b4cfe0916dc1bf6ff891c645b28e63bab6c23e5077a8c3954fb5978ad8e07dac5c5c1fc4759912524566785df222d04435a6a24361178d917b53af57438b46aeeac546bb5207c186bd196bbb6277216d95ab6e545d78e04b82669d19093241b808aedc5db79a9e54762074a0aed86931497917969ca7f20942eee719287c887b3508f23b919418278be0236043acb3e4abac940c44c3aec3ab8c78bcabd84c1d373899369b515c2478c6085ced3b08f668224f950d3b82355468bff0534cc7660045e96ca40067de520091437309f7030f71a250c359f0c71c2f8819b62cb39646b19d63669f679ff9f48ac7a426e3fc1a1d358b675105f28586726304adb8109e104715b6c330f053961207eb96148a866c12c9349fb6aafd1b42f5f80a2d827094c3b4def6478212332d96359fb3450cfa6bee8327ea707b8cc61799105358521c6199607d9b769b38ad15e4b638d12d16aa90aa49cd90b9047696acf9c14cbee59f82b46de5bc644402400baa2e839ac801c70a368a3611cb11a1484dadf30185112f52421196d1797a3085f5d429d286343953ba8de676c381aebf394d0453bf1610905f3b6afdd5299a750f2333b3944067d9a9cc201922f9b5162cc41cbd35400a275717228050a97d05d0c1b303bad3405f36a1218c5c089c98467aa37905b334edb31f667a88c2129c1749784f49b83a329275e1b5fff4798d4b1c5779a5d433ce716bce5763572a29cbddf5b40b464f3e163cd5b554c5612c20726f57244735e2616f45356237263d69a1e1e03cc4d9ad57c83b3075cfaee45418282261d8bb531b685c766989c28ae9f991415907858308a1fa027156b6d3c8c0cf926553b570fd077b6fc419d8f4556655ce53f6802d406781b06463042304477bc8ea19757bb54f2cb54b9276fdd575d5a00c267b1222d4c25de11860dc14a1f3453423caef02bfe8720472c194dd234038f8aa0d3118286b530247b88a83318fda0a9c226cbcf22510f681db3880c2208b70f67c124437dd32ab9120894aa287c7040e06f6cdd0121ede209068238b57716db488335564c316111cdd90741a197646874922ec355a26a7e5ba4af5873f974b2626b40afbbb5c59501fceca0c9fc76fe9b8786ad1c5c76b071b6c054aac0eb8e0535bf8a4249a9256e4c1e8ec673fb5bcae20063a90b601e047e9bac3ba827acfba4a7e9b040776bd6f351e548ee005d759da86c9b2971f9d6d1cab8d517dd00566aba5f53253d778ce06e380b14c9019095028f3944a31a1aa4816d556047447b810cc094d400ab204cf9ae71e3afa68b88586ecb6498c68ac0e51b9" +}, +{ + "dz" : "2f1d8a3bebb34540324b9485fdf3d5be3b858f544abc3fc641b5728cafab03ba8d6c42e7270ee2b77b6045385f3d175984a0e260363166c73b0c70c971644363", + "pk" : "1cb3c6a7f721c4039b10482990923aba0427e2da5bdd30bd55133989a5b43bc371d2105415e76ba18786237c7151548b26005961fb2a9e737e39bbaf97f612cacc3ebbd216f9f57873f97c503a95a49a1a113b0c454526a082203b1a27e2fb170ff1b59b0657861567d5565555f11ea31523c42898d6ea1ae260cd98b9cd69f9ae4d19a81365154d24c008bc15d1482665c313c3721cb701c3a407373e1bca5829cf45d484721357d5f83b5cb58b21987d9fb7b77224c03c017e183b31fb4c407ac23312aba708e8bf7f905d68b4895a48cd7a70af6ab9060d959f56a02d7e3672a90a6218fbbc6fb641163674bd736af2764c72c5bc85651be47350507ab81749bb2b6c744520b5b0a3b6633355c0991ce4e1a813615f2e8300366521040049b1054a7741b29af1c300e2c86977af90e820dcfcb8cd967c27102d49fb1683c63553289cc0c62de0e26f7555392187009e0cc5896acd8c3c9a4a7c637a107da325cb7a694e9a1107e889cdc6310671bb6c5b51a35a0169ff7b5158bc6469a71a3e8740e9281f5869180c91cec8e1169e2b377c8174669ca67418116c3cbd2ab61d8a874f9bb767de8973d8425cd118bc9a320453db9c64183248b22af3f489ae69159a056ad113833c2a9fbc56b10d013e911210bdb8cba68a0ff0f0729757bdcdf68b3fc7be480481ff64c4c09825ee52b274e85e544091c3d36f40444d28878d7c19122957348e3c27fbe74685fc1a3c21126064242616bc4aaa5284f5588435140956cf37bc72daf5a73ff6ce452ca689066fd6e118bcd4988660c7c8501c34dcbf1965c66fd95fdac910b9e48093fcb200564b4cfb36c72c3096c5579f736059534d57b7168813439b722d5230b255532d838598d615c1b641a9d5807f33653a1be96835f474d4f1955e3c5bb5c621497c3451003ca76275af98b25a962765e5bf2fe754330a77837288810aa53be9a2564451319405cc38b13401a7f7dc960b5b2096f45a94098a2fb39dcd654f846388cfb4b57b4b92abb321a16a83b3e6953a0724afb47902e581acdc278957100548c735fa5c04a4147e826a77030284615b82fa60bd3619b57bbca10872afea091fc6288ee434d8319f028125a0b5006cacaca8ca6eb95c7ad87c7e499a4ad81bbf79d144ab16ac9cb49743258cf0c83f2b006b1d0585efa0ac7dc722ed6c12170831f0964cae2b6d2f808afdc6223d11b510b949e76a0a4c262748148ce17b38c55cc7eac2bfdf468105bb89298c88c8806b124c7488d606b52b217c81a17ee5ae67cc27f6a3382d50705a9bbb1d3c59f68b8ba9a45ed1c97ea1eaab76903d1f2a1c71a07420f47695d1b68d06c5dc85114ae83204fb4bf16c09385934105c9e2fd803d83542f4aacc3af6b949a63e6d0b0c46ca8a6b4633926c0665bc09b69ca250945c14366d49705658f6cd76964e107497bb42290f4c1471a4ac29a60c3dfcb701770619cb45b0613068091a68b58c7b2a19ca9933cceb112e234014816b7db43beef660100a19377a4200a0806be78d30169c4b747e8208780a14aa53987065936ac4f06b7a710870fca3b1bacb04c2af5e3005a9208b3a03929b864d0e1011cec63b93220e96b480128c20b7675c9a87c1c8e2bab4a7422fe9c16d367928117765458a3803af02332d1bf654e782816b15a5bcc3bcf0213dcbe07c59a92d1b1baf1f217061e197c71223c12746cfc0b0aeb99fea7b29bb3a1300bc266f1692fd8641d6fc594b9894dfcb0c951b8351236087241f7cc3506ca74ccfb4c930fca1be940af6606ffc76bb92b53768294c30370b29b795de63caef451a18317384299168b77793e22fe0fc03e4c064cbb6979b38871eb11c5650587dbb31eec0cf7ce128f535b0545ba98af5ab4bc186ea1081ae15bedef5945410c800553d8a2211e8e16125d4a7cf25a91f13858e1cccb8e56481a5a3bbc3468bb624f282069425c8b5462725a813bbe53c1cb11bbfa242c2a1619763448af184958cc333c3aefd35c4a4861c5cfb2ee1b0c39b0c73314aa3d191b6406caa94d8280d8b01e1b73e56f5bdbba80fb3923a4b608543ac827395cad1b050530b5e908231c324132d782994753284927f3a379f71603036a172ef58018cfbb879f29a42a106bb32a384db6e033401fa46045b035ed2b3f277ee6bc7b69ea2a0946112498da4ee64a2be6ab49596c4e61553e1164d", + "sk" : "25c969038aaa118900417b46198c2c1d718005994dfa10ce5eb8b998a524dbb1a4f3e0716d314458ec6de9972dc3d988a064cb0b11cb82450f1055c9f333b2c82541f99167786b126c8427c515a8f9f506f878427e1a5e239547f1d6bd97674379b06813624a220a22f5c51e0dc0582ae30caae6cc39cc1350412c7de154c3484602496bf84cb3df4c031192bad2390f9f60c7e84855ca118b00bca814510c6a019d25e8687489cfc7c0240c822de267359b877adddba93ee7b99b8831efcbc6c915639b7547204190f4d500701b239a161cc4858411542fe113372cc3b0e3b4417ee5117df681ccac2efa3988921a151c8418e52cb49215b1e7c270812b876d37b092b882ef98a8075226ad76ab0bb9170f61c73d1caddc201ed8a38b9e237a6c345fffbacd6f86c47bfa56bb04b05185607fea02a16a132730710c85a424a08ccac9c8dcb662fe0650fdfb1ae1ba973e95079fb9717de44348cb0930d1c8ef1202b4c7849c244436d7b477c2211758801c316ac9b5be8a082661ea78e2b14e87da8c78e81ef2285f00d116755c5cff986b56b29032b390bb8453e8d970c7f90237757ec291ca8f71c9b691cda16749a63246ee865ac503a5573962be14a61c31a6bd3995e51684c1e59d2e803b5061b2ce633e7b692b5503818e349a61155b8820b790a692896317fb56366b63cfd7a4305f1082bde4cac8904d22f782fcd7c89f32cd98125f7ed96b0ef932cd077131424437744a5cb74f2dac52932c6c25ec282caa4e65fc9b38a43e21d3b95cc5bd67801a22d95280457b5a182f6d9c8fdd197cd12231f7889af318aa0dba8e3ec6056fd6687a476a971abe6cb439c055b21c6933c5f58c9409cfdf29ba810b87cb971f1e314256dcaa7ad63a41a11b4c1c127a8065c24979b89c96d3a2a944d16d20e39c27cc2969bb132a688a0a419c726338f93593005453001b753afca27c84c25661a63628365ce3074c90448c92b20e1299b2a10403fc9fc8dac9bd479802f8c3add3929b60b409f73e53fbaa328756a7b3ca8ab8a3341863ca5c625697b4e1760e63217275ea216a61951f88b9ce64839c461de048b3aa4692e6095496482130ea3be3569cbdac7c6684c4c561043b4167795138c662b44eaa97a279a7ea1a9e94d83d008ba136c484fa27c05db44066fcaa02f71a663512a71c7ae01742082c5fbc879a046373759965b0e565930506a8f6cd1035aed5e4a12b09a7abd74d4135653c509444775190b3c822c567381a266d1a7d6e19a60a536f60a946a455c71ba2385fb099addbada7691de2c54d5ea88020db4424605c69ba6ac2bb4181b363c688c24611737cebb00f536a83c3b30f0a9d46946ff4814aa8559368d393d94264da25b805b417158b6d0103ca9d1c5b62b1b5cfe969677a70ec1385c17a59a065809e52b99fb647e63b1f1db0800dcb9952710a94361d60fb0f932b30ed8b6715d913d8ac16a095809dbab0b0f64b6f5a7ac4aabb38414401c58b935586f000354be345f9c45cb0908df8e33063cc0997d122ec830e4c871166ea0499d6710e919faa269b064374d463bcfd96b427b47755d689fb3320b3e4759ac13f738a72516638d8194c31802abbfb68f4a6b107e05d81ba4d5d70ce6e140771f08ff7e966364703fe8a2f2ea8cbcc960ef834a711cc7c3baa7485059d7315ae0b395baa55652cf54fc817bb23819117b933b82bafb146248310b494c506ad0ab37025965f550a2d821787671cda3c9874e6781ad85934da3393b566d58742bd8cc44043ca7a4268b757ba3e1b4975f112617707c7f603cc3569b82b100fd79a391673ded0a14cb11af1556fc26a4a11291f4ef1816c52c292475807f58a2d461ca15b13adc4a7e1a75e1b4bac02f11c3af98f57b5516da77b49455ccfca47bfa0c70e0935f53b14c3431724a35a8fd663fd2ca7107c8e4f0a14d30b98b5f03e1cb568331c0f14e7756aa4901313842447ad98874165f8372334869e89c82eb36429c13f442a3f6f92a9a3f75b931b97b5d4080442371babb4509c5e1b997266805b777c1253fba72a839f9d62002bc2075788cec91269f0f1408e71031122b107e11486d096b1faab348c5aa46cc63eb38c4935915e037f4238b9be3b59975c6a67fc807a732b0ac43671825cd0f74d1cb3c6a7f721c4039b10482990923aba0427e2da5bdd30bd55133989a5b43bc371d2105415e76ba18786237c7151548b26005961fb2a9e737e39bbaf97f612cacc3ebbd216f9f57873f97c503a95a49a1a113b0c454526a082203b1a27e2fb170ff1b59b0657861567d5565555f11ea31523c42898d6ea1ae260cd98b9cd69f9ae4d19a81365154d24c008bc15d1482665c313c3721cb701c3a407373e1bca5829cf45d484721357d5f83b5cb58b21987d9fb7b77224c03c017e183b31fb4c407ac23312aba708e8bf7f905d68b4895a48cd7a70af6ab9060d959f56a02d7e3672a90a6218fbbc6fb641163674bd736af2764c72c5bc85651be47350507ab81749bb2b6c744520b5b0a3b6633355c0991ce4e1a813615f2e8300366521040049b1054a7741b29af1c300e2c86977af90e820dcfcb8cd967c27102d49fb1683c63553289cc0c62de0e26f7555392187009e0cc5896acd8c3c9a4a7c637a107da325cb7a694e9a1107e889cdc6310671bb6c5b51a35a0169ff7b5158bc6469a71a3e8740e9281f5869180c91cec8e1169e2b377c8174669ca67418116c3cbd2ab61d8a874f9bb767de8973d8425cd118bc9a320453db9c64183248b22af3f489ae69159a056ad113833c2a9fbc56b10d013e911210bdb8cba68a0ff0f0729757bdcdf68b3fc7be480481ff64c4c09825ee52b274e85e544091c3d36f40444d28878d7c19122957348e3c27fbe74685fc1a3c21126064242616bc4aaa5284f5588435140956cf37bc72daf5a73ff6ce452ca689066fd6e118bcd4988660c7c8501c34dcbf1965c66fd95fdac910b9e48093fcb200564b4cfb36c72c3096c5579f736059534d57b7168813439b722d5230b255532d838598d615c1b641a9d5807f33653a1be96835f474d4f1955e3c5bb5c621497c3451003ca76275af98b25a962765e5bf2fe754330a77837288810aa53be9a2564451319405cc38b13401a7f7dc960b5b2096f45a94098a2fb39dcd654f846388cfb4b57b4b92abb321a16a83b3e6953a0724afb47902e581acdc278957100548c735fa5c04a4147e826a77030284615b82fa60bd3619b57bbca10872afea091fc6288ee434d8319f028125a0b5006cacaca8ca6eb95c7ad87c7e499a4ad81bbf79d144ab16ac9cb49743258cf0c83f2b006b1d0585efa0ac7dc722ed6c12170831f0964cae2b6d2f808afdc6223d11b510b949e76a0a4c262748148ce17b38c55cc7eac2bfdf468105bb89298c88c8806b124c7488d606b52b217c81a17ee5ae67cc27f6a3382d50705a9bbb1d3c59f68b8ba9a45ed1c97ea1eaab76903d1f2a1c71a07420f47695d1b68d06c5dc85114ae83204fb4bf16c09385934105c9e2fd803d83542f4aacc3af6b949a63e6d0b0c46ca8a6b4633926c0665bc09b69ca250945c14366d49705658f6cd76964e107497bb42290f4c1471a4ac29a60c3dfcb701770619cb45b0613068091a68b58c7b2a19ca9933cceb112e234014816b7db43beef660100a19377a4200a0806be78d30169c4b747e8208780a14aa53987065936ac4f06b7a710870fca3b1bacb04c2af5e3005a9208b3a03929b864d0e1011cec63b93220e96b480128c20b7675c9a87c1c8e2bab4a7422fe9c16d367928117765458a3803af02332d1bf654e782816b15a5bcc3bcf0213dcbe07c59a92d1b1baf1f217061e197c71223c12746cfc0b0aeb99fea7b29bb3a1300bc266f1692fd8641d6fc594b9894dfcb0c951b8351236087241f7cc3506ca74ccfb4c930fca1be940af6606ffc76bb92b53768294c30370b29b795de63caef451a18317384299168b77793e22fe0fc03e4c064cbb6979b38871eb11c5650587dbb31eec0cf7ce128f535b0545ba98af5ab4bc186ea1081ae15bedef5945410c800553d8a2211e8e16125d4a7cf25a91f13858e1cccb8e56481a5a3bbc3468bb624f282069425c8b5462725a813bbe53c1cb11bbfa242c2a1619763448af184958cc333c3aefd35c4a4861c5cfb2ee1b0c39b0c73314aa3d191b6406caa94d8280d8b01e1b73e56f5bdbba80fb3923a4b608543ac827395cad1b050530b5e908231c324132d782994753284927f3a379f71603036a172ef58018cfbb879f29a42a106bb32a384db6e033401fa46045b035ed2b3f277ee6bc7b69ea2a0946112498da4ee64a2be6ab49596c4e61553e1164dd2d4c9cfe0e22188f2bb5e538a054c904cdd0d6dd921af93591f4a37e9ea2b5c8d6c42e7270ee2b77b6045385f3d175984a0e260363166c73b0c70c971644363" +}, +{ + "dz" : "31beda3462627f601cbc56f3ddf4424e1529c04737ef0ef2af6d7401f653b8a1812083bfa3b670e3eaf9b443702fb6db16ac1197656bbd61a8e25ed523b8d1e5", + "pk" : "78d90b2d2b06c3c74e60306d7e0514fbe0111a930a10627e5b2b11077ac78bc32c46d1406ee73acc41b518b2c1a8cbc93990b9c1d0964b1091b0871dfe594aeb6719400c71e96893a7524d082bb5b7b3711f586f9ecc4b65f66fdb2801495086969a6a49961d563391a24b1029a7a3c9e2399f605a37a4a05237570160976b658da00b57ced318b4c7025ceb071c269ec9db9d6a2944c973cc9b427d5573c2eb37c64e4624216c290c5645b36cbb3e82713de383daa5cb4029c6dfb14c43f4aeaa9c93843b784fdb63957b75f39088820694bd0706ca856864fa031b682031581673608dc9ea058dea014ab79eaef74928d4cb33308fcad06ed303a1ab8b6cbbdac332a24ce5474013c90c5b1b869bc9881323435a097d09e5910e39cae5a1bc148ab7d8aa12c84634864930c24ac4f375731cfb65d5992916302640a524a4a52c9a2281534956f946473541852d0884e6461614f9a1dd95cc923c6298998b21c2415518443f86949e6c390f9463b69a63f2f9b328053c01872ea2ea8fc45185ca3bbe74b713528cb3525a60f7639f770824686c1b2ad719fbda1d4c44c9dcd0b24f5277fb6720e686270b5349fd3b1215008c6b24c26aa943ae71146f063072f0c42ea114d3986ed1030260e88f2f2c34e7385491565168e1c18ad324fb13482f5b83b2f6020a6895f9d24b93805fd5556b4a048c2e3106eb02a53a774b169106a77bc166137e7dcc4b60569e77dbc6d5f9c276a011ef59bccd08793b695eb3a5bd3c1b64ca3bbfecd1adb5f97294d8909b31772929c693ac396d412549b1cf910aa3c60ca0250928ea4350b8c91df7d31474ea07cff56dbe417b16603c6af97329d53163343e0af3a84ed37cb91a349bf2af7ee84d8ee504f2a73e9dc3301480bc6f144a631bc3c160348773cb0b6a3b57fa1286e2107e950ec6a682edcac892926966e28ab2a482bd5991f8c6c6f5e231b0826191a8c8d3c2701984980146bbd1b8a629b548ce578f5df90b58305026aca96ef20c77610a2da79018b0047f5351858c2c99a035f2f339885521d09611a219895e987471a2c10ee576e07320b7f9b5d678221aa995afe550c0f72f1b647f3ef429d3720802d7b53ceb917feca63860337ea126fe41777b85980744025ef9418bb4c1983c8af0109d2a0a0ff47c121de1926ffb5b3d8bcac797a0f5309c8629605a757a6ae91beaa437cfe184bfd3b703052ffe8cb2d7e57b411719625a9f1e11473aa8a4814788c0280fd179596db23d3003461314896d38a9e8fa75e93b65cc76cdccf24a72b1294acc47b3e7843b2a322e82c98f906ba369b7e8b588d2dc8056b70e8588c4eb80ce8300630d265a8f6a74306374da0622eb125f51764c81c55b9966c27b562c5e930a30207f825b27711c3124fbb98d4a8351980a04041e99f7af63ac015d667232162db0e793eebc70dea04eba186d2c14381ae886f7c6b934f587710aa095b206621cbe4ca1bbb8752b5489626ac72290315fe9a967ef6980f9486462b74e7938800b020519c5c0a684adc1b82f0ccaa3988cb5a28264ccfcba1e8119add64a58da88bed5cb01f5b0410a3ee03c9105029ea789bf65bc9ec58b4b2b0c9aa9c7859a48cbf0c12cf9e78049528118d366d0345951d0aa9102b5c12b36c6022fa4c7b4554178a8800c1a968ec74569af3815acdc39bfe029807a8ffe1267a69073744a806161bb5ab59d5340b8218054a252560c188314c177c5f3300e86863eb97253e6778415b77f140d498aa104eb291b21bdc2c5693a39254cb01c8a3a9e8e14a965d107a6b98eb09a26c2851059a290b6e94ec10138289148086456047750a3f8aadb5b1693c9642a8ba89b89c6f45c18ba750656c151cb563ba7260ca09c780077b956e5275cf998c86748d2d332a9008f8625bc61939b18f0c063f171175338464c0d402915c6e54682fb6876c7338f654d1916655fb19e21f18e2c0629e0962457cb62bdf3c93cfba8a551c752642016f72b5479615da16c1622b21a105da72413df20b125c48b0a76001472780be292a98500321c007b1a0273108be097ba0e5972a2394861c5c9f8e0093dac8aed47a6467570299a5501c6b2f281283d0013260901a08531e737bb6baa0fc13895253ac4469519c483b591d28cb8a9a0ecd051937eb8d82bba18673a17339dee827be4156633d8a2c376d41fa4e7bd70d4e199", + "sk" : "fc569914244bca63c05d25beb59702977903c59c046079c9410c873936b86945ae56f3c1f049a3ba4185ad5c49bcbbbe7fc89e561b2a940aaf66538ebf594eb0e5bd163824f8022f6b5183c0839b59361b96008f3ba83d1cc37ca7581121a0b552908e28245218730b3817a27e4099313484b6fa99a539295713abe453afbf8788fe6ab530e1cf3f430f4a855abf3bc11da69e10cb2d879075fa6198b1601dc8903c32a845d4da3b726b6828ac84e3469dc9e66701c16b64957d36128856b82e1367ac00c274d9a366b6b38fa87364880299e86561bdb46269a951c273710616109aecca78e5710c406b27ea403c05704c77b27da95c45da86d2c586f72a0ba1bc5493a389961b789cf5b35ef88dfc38cf6443b7c3190069a19be5a7b11a7339f6cb445f88c90d1b350d5c3089ba13c4c70ed5514dea34b61d7ba5abf4c78024abd21a9a84f4cd73f86b43f3744ffb572d918338688168cbac7f979bbdb2c52910402f94c3fcaa29f4362147205dc5b5af7d4cb920f21851392ed6a40e10f1013b380ee87a4fe70b864ae285bb5b1d01a448aed532da26948f639258a4af94b3270a984063c927929867e1fc9415815fc51c5158cb4ae9d8c81cdb30a98a82e6367e6340c6f5704a37e06523e736bba1c4d98c524bf136a3a48b5786a9ec624df5a992bc89c389861b03aba410531340baae94c5a91410370f92573c3b28f2e2a47a2695a9626cf311b834597c0a09ab0ee2a588e26962189b7b50a99d5b7906c274a8130f3a30b56cdc85c1a8ab9853476a22a8c047b4f825032a742d601ca1bf319b8a1825be3c38e93a686a50694e15164d9c603f537772f88abc1258749a1adde38b55e0485f34bd20129a1f6180eb2382bf2b96120cb798fcbd98401a62a872b4b175f80ca9aa0b496ec12fcf713184400d43212db7a55a522a1d718c43d61823f4e342e9396e6c2451c056ce3ccc93c7d9a45ff41461262e49c01def44a350e5cb7e40bfc2845989bcb8cd59600f1120647b45a585318b0bab8a202afb7348028b3fba36a41aa7528dc9973feca1c28a722525c29687398f607e02c9be2b2491a0458e1aa6c10882bb4c0bb50985cbdba386d0b53cefcc6f316965e1f289148c64be223853791a254b38a98160f0bc3aa63cb6d45263cd61048a831a5440413ac3c6f38670a83190d2bb32ac5a35908c41618ca017893b3eb2628265b857d5130c821af61c895c274faa2150034c0e80e2318917bf9aa15cf2665c1b3ab8b62a39282c738ffbbf7760845637861f46c3e5137f050a907e98bcf755a3bc0ca201522acc9bc780d10d4c41c69eb400f9234c8c7907bce0cb52b783c0fa82410a5b0f325753d985622bbab7639b649c5b36696e2bd8b5c969165f66ba02b142e4380e77ac07d2a85c599b9449e48f4a6aa0fa30160c18180ca2056fd52a94fc2f2d26c0f5641c81cb854197af4eaa389aca0e5dc9bdbd4885da4b9ae207983cf37bf8955ccfbb37e57b30e74bb6f798b4ba62273059b589e51f78b79fe927818eb12f0e73636321b51e456dc5f90281153c7687cc313723b1034de828620d17aecee6482242afe899c45735209606b82a1c284fd7a0dd819f72ac71d30bac8b54715e422e7c4511a073039587ca15251d8bd926ceb2b0864c159d348889bbadeff732d0303951d1b491b98b43214d26bc7a3b121dce077739109b5c00441917cbf3169577d63bc7ca18e4478f4fa8bf23164c8ec68e86acc8d0e1ad1034a99eea986699cdb6176c84294f711067ec7748ba83cc6dc51fb3e9576d7150977c76096a233b2233c68995333b82baeb80c3f2480fbc93b414cd3df6165e4969aeab0b052492faa0a613818b6f60086cfa21a1ea774afbab6857033c65bc38395b47f3514c624d27e3120a969d01b1a49af814c7192ad1f97c2b398301ebba4e76be866c8dd17a46c7db9d5149329ca53460d135e323c6488134e9e3ceda48562aa78cefd098ff75a93f3413384904cdc10278c798a77aa93f033eb4fa32f7698318d23c79b4af83639bffdc56af742144e7b36c217f13244b152b88fa3192781594759b1e0d158cda2a12c1fc85d093390f42413e00a4337c32092618908a24379444fbb5c7f702b2fea3098aa125a89b82336a3789a3bef7c403a5a2c56bdc0a78d90b2d2b06c3c74e60306d7e0514fbe0111a930a10627e5b2b11077ac78bc32c46d1406ee73acc41b518b2c1a8cbc93990b9c1d0964b1091b0871dfe594aeb6719400c71e96893a7524d082bb5b7b3711f586f9ecc4b65f66fdb2801495086969a6a49961d563391a24b1029a7a3c9e2399f605a37a4a05237570160976b658da00b57ced318b4c7025ceb071c269ec9db9d6a2944c973cc9b427d5573c2eb37c64e4624216c290c5645b36cbb3e82713de383daa5cb4029c6dfb14c43f4aeaa9c93843b784fdb63957b75f39088820694bd0706ca856864fa031b682031581673608dc9ea058dea014ab79eaef74928d4cb33308fcad06ed303a1ab8b6cbbdac332a24ce5474013c90c5b1b869bc9881323435a097d09e5910e39cae5a1bc148ab7d8aa12c84634864930c24ac4f375731cfb65d5992916302640a524a4a52c9a2281534956f946473541852d0884e6461614f9a1dd95cc923c6298998b21c2415518443f86949e6c390f9463b69a63f2f9b328053c01872ea2ea8fc45185ca3bbe74b713528cb3525a60f7639f770824686c1b2ad719fbda1d4c44c9dcd0b24f5277fb6720e686270b5349fd3b1215008c6b24c26aa943ae71146f063072f0c42ea114d3986ed1030260e88f2f2c34e7385491565168e1c18ad324fb13482f5b83b2f6020a6895f9d24b93805fd5556b4a048c2e3106eb02a53a774b169106a77bc166137e7dcc4b60569e77dbc6d5f9c276a011ef59bccd08793b695eb3a5bd3c1b64ca3bbfecd1adb5f97294d8909b31772929c693ac396d412549b1cf910aa3c60ca0250928ea4350b8c91df7d31474ea07cff56dbe417b16603c6af97329d53163343e0af3a84ed37cb91a349bf2af7ee84d8ee504f2a73e9dc3301480bc6f144a631bc3c160348773cb0b6a3b57fa1286e2107e950ec6a682edcac892926966e28ab2a482bd5991f8c6c6f5e231b0826191a8c8d3c2701984980146bbd1b8a629b548ce578f5df90b58305026aca96ef20c77610a2da79018b0047f5351858c2c99a035f2f339885521d09611a219895e987471a2c10ee576e07320b7f9b5d678221aa995afe550c0f72f1b647f3ef429d3720802d7b53ceb917feca63860337ea126fe41777b85980744025ef9418bb4c1983c8af0109d2a0a0ff47c121de1926ffb5b3d8bcac797a0f5309c8629605a757a6ae91beaa437cfe184bfd3b703052ffe8cb2d7e57b411719625a9f1e11473aa8a4814788c0280fd179596db23d3003461314896d38a9e8fa75e93b65cc76cdccf24a72b1294acc47b3e7843b2a322e82c98f906ba369b7e8b588d2dc8056b70e8588c4eb80ce8300630d265a8f6a74306374da0622eb125f51764c81c55b9966c27b562c5e930a30207f825b27711c3124fbb98d4a8351980a04041e99f7af63ac015d667232162db0e793eebc70dea04eba186d2c14381ae886f7c6b934f587710aa095b206621cbe4ca1bbb8752b5489626ac72290315fe9a967ef6980f9486462b74e7938800b020519c5c0a684adc1b82f0ccaa3988cb5a28264ccfcba1e8119add64a58da88bed5cb01f5b0410a3ee03c9105029ea789bf65bc9ec58b4b2b0c9aa9c7859a48cbf0c12cf9e78049528118d366d0345951d0aa9102b5c12b36c6022fa4c7b4554178a8800c1a968ec74569af3815acdc39bfe029807a8ffe1267a69073744a806161bb5ab59d5340b8218054a252560c188314c177c5f3300e86863eb97253e6778415b77f140d498aa104eb291b21bdc2c5693a39254cb01c8a3a9e8e14a965d107a6b98eb09a26c2851059a290b6e94ec10138289148086456047750a3f8aadb5b1693c9642a8ba89b89c6f45c18ba750656c151cb563ba7260ca09c780077b956e5275cf998c86748d2d332a9008f8625bc61939b18f0c063f171175338464c0d402915c6e54682fb6876c7338f654d1916655fb19e21f18e2c0629e0962457cb62bdf3c93cfba8a551c752642016f72b5479615da16c1622b21a105da72413df20b125c48b0a76001472780be292a98500321c007b1a0273108be097ba0e5972a2394861c5c9f8e0093dac8aed47a6467570299a5501c6b2f281283d0013260901a08531e737bb6baa0fc13895253ac4469519c483b591d28cb8a9a0ecd051937eb8d82bba18673a17339dee827be4156633d8a2c376d41fa4e7bd70d4e199ad2b1951f0dce0b0afd296d3f22bafe4f13638ee2540caf8a6bf7d0387265bf8812083bfa3b670e3eaf9b443702fb6db16ac1197656bbd61a8e25ed523b8d1e5" +}, +{ + "dz" : "cbdff028766d558af4466ef14043a1a9cf765f7748c63cc09dceb59ab39a4e4d8e9a30597e4b52ffa87a54b83c91d12a5e9c2cd90fcac2c11b3a348240411a4c", + "pk" : "81f27e76a1562bd2c206ba3087231983aa0bd65420e2b71b749605960c94319abeb1e80aebf274b27a9237740c07114614658c51d0c5118b9fe6d0064e9b47641ab189b2ce2086293dba6054a1437d00719b5c11351a9901b0a15e4c7efcfbbe9a3a7ac6ab157586c8d5b68b2d9b747b2461f2a2cc3179a70926423ea5aed845407846bb9c5c57534b66a6cb8b480c9a18453e047c58ef00cf652867b474c7b1b62fd7aa0d7b4c63d881b05f6a8d8549257d7b0b7153525d5b295e8bbbf3d36da46a5d425601e9fa8ee7402535d553bb60547bbccb7777b5e48373f2b38f3c566e7b98a85465590ee1c8cef16e4515ac3b4c69f99ca7f3495254c345b0405fcf975bb5cc26a1faa82fe109f8d670f17164f25878a9e8834b4271f75338dac56ca7b4bb3b56ae95444af369c20b582edc204928037434c3c5f8c372fc9449a773261ecbaa4ddb929f148bb6bc471d2a72706a1f621ca295eb8b44a83a4b99c6f3bb04002b2d6ed42fa5418bdca5a07f743754882e2ec966f44235fd3b48c1ba874d8765ee30156cbc0456e610c5b02c8fc3b6d305aa23a5528e77aebf2bc3696a37c438a2a1259054c3537ab8798ab9c16c2b9bec71a861a96ae2387955cb95fc4c984d2b936be897cd05ac3524b845a2aed4bb981dc47120fc9e4c6476e7847ea69755886a5c85cb059ad0cf05b0aac6609104e0449e36815efb9c0b232c7e5b9b80e386a8ab12be22a72e0a4efb447b253c65f619c2c85a878a54457d272d2e9a32d2668d9a02089a434a1bcc4cdec25f909640901ab4ea97128850335e63882f363eae699599a1bafea68c9987882751b545795ed6428162993b17e7a7fbccbd2115c9cdb83c9852912fc21baf53082fa41ae41723a8e6a8e6a3c008dc8b8b6250c7c740ad2a3b92676960db68318c3cf24b855b62b237b97df54c561b72b0bca0877925734d650c0824ab8081802f166d8a294ffe8328fde34b02436ea27086b870009545a71d56ccfda986d00ca3e6931b85a53cab3aa85a2184e55718a9988e11aa2f024076bfb36c0d222685977ec39702e4eb7045229e5256890ad87d84dc8de5c44f8e73c65970216c6312bc22920fac8e24a6b251103beaac8b4a911a1bf62870a33ad9986d81161a3e44b0f5c9508be97324a97107cb15b2a2b9f6f71b80fc7b59d199ff7b04652644f10156c2dbc33ee34cea079e6b718ff4e2ba10858a2b33827f7019bacbb952ca83a8f38d69422431fa722bf31683e3ad6e1784ef9ab210391ee600c2d0c690d739ac5a581c4f5660576bc743d79552cc833222b43e45201888a3ec82194dc2307a07b8549c838bf4a70f9c4f8cf5868710cadb4636bf12a257a57c344061b9f83dbe9324195651020c2f02574a2db4aa4ef527e5a66fd4758382f96e52d84472852a30b49ee7d60698f4b9b6e9003f475623e345e1db767b143bd30bb5273636ca7926f434863ce41813767082873ab5365dcc72a251c035da426fe6db4aa1f34ffa45c9277327a7125c866546bbe22b9c09c054e133b3d8b3fbf18832248e5a3198c89794c5ba4e6486574de79cd67626ef2953007431ad08895ae499cc17111f76c002322a6602b677a922fc450971fc90c0b8ce16dba195fa80196569fe8b87fe060311867e6c6abc87f2351f4b0da1f837eb7830b9319498f36ff707c80926158b84a934400f63911b5650c6d205686f7bb7d415ca9dcca9a94c5706945580f49eba773067eac6c989a8e1d84d2586c58e70793933367da73ef0509e27a97f03c28a10086d782a3ef2251d08793748357f411200b5803f0c76c886b35bfeaa68544aa038374f868c474f0a6df1061de88886a1241f090ac4c7c17f6a429f5ca400e8dc98554c56363c8fcd728a1fab7c0007c67915b7d793c0ec5514c8f6a394c8502ee3c63b73b26da015c370826278aea16ac479884ab77a2d3c0b147e93181167bc1980627b46b7d06509d7725cf1085850a53f442c226cfaa24c8721db0c137c7a72b5898cd2137839202db535cd8ae76e42219e49eaabe2fbbb643742ed91551cd54f1de16f63c953fbc7b5849ccda3167660fb28f2a6ad8327a6d6ab649eb22ccfca574733cf01663fbadb3be7c33a482c13e50027d76a134e114c54380c1e84255060944dd10321b29149922be789eb0a8fb7721fe98a1e0bee89476e7efd6ba100e4d6c896905fc524e7f985", + "sk" : "7445654a55ad6aba3d41506b872c53fbc83988eb1aa5d4ca645854ae700cdf3a1fbb448b51d83b20c3bf82ba45000357d3820a0ce20f011581d2a4c4f186522d568861554efafb1c843296c927a3c29a19bcf7037b497f6ed90706305bfb28b06818549e9b7700a387ce14420c74a5151555dda18b216b0846c5a90cbc29bd623bdc8c74f2dbafff76a1a53ca1b9137ffc687c5304a3faa42772c85719585c39fc923d7c253dfa471ed7260394134c058b8c768b04123f3c955bb8c94a26d4b6b44824cbcc79f305516672311da2b15be23a183c323f8841ec76882bd161844c2829da23482a3ad106225cd444f4463072f096740aa4a72c88dbb9b393289d91b85b20db1cc38096c0bc6dee84a16068a80d759d0d861a6eeb11d82a2b1b6909280c32ba42733d259ad3bbccd3e0bf13446b0ba77df35085f6494934555514353825c33a0ff41bd00545f607096b524519dc3ffd73a65dc1b9ba4ac7d32818ba2b21e1a300da3248b2fb913154be448c76195ba9cee404b0f8ce458540a678984d034e4067065116a4c8580da808b3e0f07d74a2a6a6b391eca57039bb3d5643a5545394057ac7222abbece46e06e4684830aaddd737baf64fabd956712b57add25a462441e362796d0796cb4c10706017c42c4070d8a51492b7c0db033e29761e593927111a9bac35e8e9a12a6423d8726237526d95e10cb0a3bf8b2302882c55eb92a69173b3a6353fc34711b51cba08c3642c449ac9bacd0b2906a2b5a8b53a1bc64b810023cf4fa7c73b3779ab468131569a60409831f32e2d87bcb455c15b705de96948cd9652f30619881879f3d043a341a3239680a6b12645b750e42cb736245fc83330ad7408e8b56bb535b865a9bd79549fbf8ac3468b9e90158b0a92c53a08b774b2caf4a124b8785f26589e65346b7f4469b807292108520a02c9e5da14c1fcc21fd526aeac3088d94666b54cb3bb00e3887f34b0670fba3d167b1b9088651a377aa8098c1f87888655b0bef1364e39973442c1b8fb4396e3079cd244c241149535aee7767ce60267a6bc733de942cbc81e0ab46f19370e5a82a09cd724043204cf6372ac5ba918fa2105c54640e3b9bfb0ca60600ec5091236a44d7fc5a183579febb401872066a95b22cacb9492f14955843a0460102319a1c49980405bc947283f95643d0b63b80d36b7ef29097bcb057926b2583745de85192a65070a0143be745e0651775b84480f7b0ee9727ea738b1c36b3890e19aa4431c46a7ab29f273660983e5eb05810327da1bc0ac5020ccd34bbb4765cd632e3f1b727483b76a0262c0617b3a06439171ace34b482674a967474c1bf77536bc6819bb77ad40b157267c6648c9c05259f06c20ad7b814048c926c52e2c14682b464a4c2740a37c3434b7055fb99efb813df8637bf8b4ab530731f77653ec2ac15a174769dbc5e435ae8b4668d009cffea1716f38037752a007c788ba80976a319b5455bbfc41119aa24e1e43a0ecf02c4fdbadfa60c187bca996f7b039692a6a03439221aa85c145c1110e22d46ae25ac7e1f99c68b7ae69fb22adac7446961e543532b5c10dfa74388a031c310275cb29b4a6f290b97c9fe8f7052ac51b759a75a9e552faf29f10114e43237f3e758506e53fa110488b11b3c1e339a7c8312f1335af7a8a456b581bd61d0af384d0796d531b6af20b2b08725c341b5d38737fcb055bca240ef239c0419598ad303344722dcf2c5dce35bb393b89dd876f9dc97020724c6cc75892f996b470b609872a127a3d73bba81ba14c7bc0049a9bcd5985ca4ad15d20267f6e56088e1512491aa7b51a6e3aaa6d34f870eedb3db6eb03ff44b3a674750967ca88a0a1cb110c9e9566cb20b42a696e86f3711ad407e3a01c269600ca9446a87baf63789410975376a5bcb801303b30cd1df625129b44e388672356132c10b6a6030c1678797d157c55b4741dd925df96374b16b8fb464d4bb39eccdc30124248aca11a2521bb0af5aa53c61f29663b6e103a6ee6940ce05e071242280858a06930bb5413ac75a3df260e070752e1818e12c221a69554a774507e892bd18b88a4672bc2fcb07302a132648d49c08d65804d1da7324fb00f53b44e6539b941839ffa36c435498809c3804685273324147ac41c259b86f5a09781f27e76a1562bd2c206ba3087231983aa0bd65420e2b71b749605960c94319abeb1e80aebf274b27a9237740c07114614658c51d0c5118b9fe6d0064e9b47641ab189b2ce2086293dba6054a1437d00719b5c11351a9901b0a15e4c7efcfbbe9a3a7ac6ab157586c8d5b68b2d9b747b2461f2a2cc3179a70926423ea5aed845407846bb9c5c57534b66a6cb8b480c9a18453e047c58ef00cf652867b474c7b1b62fd7aa0d7b4c63d881b05f6a8d8549257d7b0b7153525d5b295e8bbbf3d36da46a5d425601e9fa8ee7402535d553bb60547bbccb7777b5e48373f2b38f3c566e7b98a85465590ee1c8cef16e4515ac3b4c69f99ca7f3495254c345b0405fcf975bb5cc26a1faa82fe109f8d670f17164f25878a9e8834b4271f75338dac56ca7b4bb3b56ae95444af369c20b582edc204928037434c3c5f8c372fc9449a773261ecbaa4ddb929f148bb6bc471d2a72706a1f621ca295eb8b44a83a4b99c6f3bb04002b2d6ed42fa5418bdca5a07f743754882e2ec966f44235fd3b48c1ba874d8765ee30156cbc0456e610c5b02c8fc3b6d305aa23a5528e77aebf2bc3696a37c438a2a1259054c3537ab8798ab9c16c2b9bec71a861a96ae2387955cb95fc4c984d2b936be897cd05ac3524b845a2aed4bb981dc47120fc9e4c6476e7847ea69755886a5c85cb059ad0cf05b0aac6609104e0449e36815efb9c0b232c7e5b9b80e386a8ab12be22a72e0a4efb447b253c65f619c2c85a878a54457d272d2e9a32d2668d9a02089a434a1bcc4cdec25f909640901ab4ea97128850335e63882f363eae699599a1bafea68c9987882751b545795ed6428162993b17e7a7fbccbd2115c9cdb83c9852912fc21baf53082fa41ae41723a8e6a8e6a3c008dc8b8b6250c7c740ad2a3b92676960db68318c3cf24b855b62b237b97df54c561b72b0bca0877925734d650c0824ab8081802f166d8a294ffe8328fde34b02436ea27086b870009545a71d56ccfda986d00ca3e6931b85a53cab3aa85a2184e55718a9988e11aa2f024076bfb36c0d222685977ec39702e4eb7045229e5256890ad87d84dc8de5c44f8e73c65970216c6312bc22920fac8e24a6b251103beaac8b4a911a1bf62870a33ad9986d81161a3e44b0f5c9508be97324a97107cb15b2a2b9f6f71b80fc7b59d199ff7b04652644f10156c2dbc33ee34cea079e6b718ff4e2ba10858a2b33827f7019bacbb952ca83a8f38d69422431fa722bf31683e3ad6e1784ef9ab210391ee600c2d0c690d739ac5a581c4f5660576bc743d79552cc833222b43e45201888a3ec82194dc2307a07b8549c838bf4a70f9c4f8cf5868710cadb4636bf12a257a57c344061b9f83dbe9324195651020c2f02574a2db4aa4ef527e5a66fd4758382f96e52d84472852a30b49ee7d60698f4b9b6e9003f475623e345e1db767b143bd30bb5273636ca7926f434863ce41813767082873ab5365dcc72a251c035da426fe6db4aa1f34ffa45c9277327a7125c866546bbe22b9c09c054e133b3d8b3fbf18832248e5a3198c89794c5ba4e6486574de79cd67626ef2953007431ad08895ae499cc17111f76c002322a6602b677a922fc450971fc90c0b8ce16dba195fa80196569fe8b87fe060311867e6c6abc87f2351f4b0da1f837eb7830b9319498f36ff707c80926158b84a934400f63911b5650c6d205686f7bb7d415ca9dcca9a94c5706945580f49eba773067eac6c989a8e1d84d2586c58e70793933367da73ef0509e27a97f03c28a10086d782a3ef2251d08793748357f411200b5803f0c76c886b35bfeaa68544aa038374f868c474f0a6df1061de88886a1241f090ac4c7c17f6a429f5ca400e8dc98554c56363c8fcd728a1fab7c0007c67915b7d793c0ec5514c8f6a394c8502ee3c63b73b26da015c370826278aea16ac479884ab77a2d3c0b147e93181167bc1980627b46b7d06509d7725cf1085850a53f442c226cfaa24c8721db0c137c7a72b5898cd2137839202db535cd8ae76e42219e49eaabe2fbbb643742ed91551cd54f1de16f63c953fbc7b5849ccda3167660fb28f2a6ad8327a6d6ab649eb22ccfca574733cf01663fbadb3be7c33a482c13e50027d76a134e114c54380c1e84255060944dd10321b29149922be789eb0a8fb7721fe98a1e0bee89476e7efd6ba100e4d6c896905fc524e7f98558672899468fc0a35e2a8c6fcbb35b2912e4aefb8c396bb9738e3c16c95ccf758e9a30597e4b52ffa87a54b83c91d12a5e9c2cd90fcac2c11b3a348240411a4c" +}, +{ + "dz" : "4c04310bea66305c6ca8ba6b8f61ca96257a67663afc11761f13fb5c7b324b6b8aec87a9a79204cee2986867a2906eb851b734b8b22b91d6749b1a5f07c44e3b", + "pk" : "33651904e40d7b863a34774ee1e401a9a24a960045d4537e5124921355cce831936f307c7cd807eb376ca1b640e7a76964c0195b6848b2cc9f832ac0c11c3c3c7290ee182c46bc1608c49e809b1c24a7c738845e9ae972d70c5ed346c46ccc73e0e251b1b57368b96dd71cbda55366585011ee659a2f081a7288c873c8a98964131c078aada0ad1662bb0d2b0a1555a3c84555c593231d167d378ba606257fd3958bc24b47e8380dc370c374a869413547d0703d28e4b5ec85cc0c897f14d5b03d6520937295183ccb1059821c2b866e755e24286634ec088522941516c592418a4fa872b2f911018843d7c877da76c1822246cbdcc046695a1e93aff063a577fc0eff56b27a2bbb56f76dba2b34b6a6765b78493f514661a4a83b58b42e4b96b471068682bb73f535e32c8fc7964a978b47be9b23cdc2b33ce980f66a033f8154bf24b73147152f544939377ba2ecb5a288276c712f2317ac69292eea9005a74a3fe336aacc4257e46395fa9a96a3fc9172b5229c393021e57265d017f6e7a5e92066b459199957cf4dc653ac222bf0b953c3c4ccd5f7463de539c024bfcc9475cb3437c22502fe16b909f73b6e733c6dfc6d87cba8a13220e823a46ed900c7649494006766a23cec36aa46756d3a7124bffb2af34c586847162735ca2d1b259f5c1eb0912afcf6846641984763266bc0add6d60fdf5b6fd87343a5d59c108cc663d8b700ab1dd5c0ab60fb66b764201722c9c2f5b2ce9a88162c3135d44ca9a735fc90b35058bbde332063820f3085cad54c4a8cd8708d43b871ca2b41d0cfbbc066ab45bae33cbf2700c67a5a62cbf1ca19c2431b6c52ac476fc2ec4c00ea9c14cbcee11b1232d523aae8af555958c3089c6c45b47ba58cf1f884e77893fd296ce80584a76abbf2330ab058c2af770e4468097cc20748a188b6620f128912126a899d7b0df24b067a73c4329314c3f6b0b9b83fb450414cf0a2ffac6fe2aac17359b20288a14272a952642958058f04b24a69b93492bc0dad67a7552b37f2417cf7e5b889e97b2d02980f7336f8e0198123c855dc1a40bbc5a93779c7c7be7089a8440214b3542341e56499ac1f6ee61b981705258c5ff6e74637fa0e48556bd3542ee342891ea4b4dd5a4982b0471ce63d61b3adcd1197dae05627c5993b502bf3025f6cb8792f32264184b362909be8ba74a1b6674e253f28b086189115129919821b867cc84341e3ab43b350a5c79d5af47b4cd228856189454538d362049c710953f33678c28f3cd9812d731aa9f95004b94425c60cff24186f644e749a6963b77760ba491744ccadb72e23653a3a08a1f7bba316a9c83e3113cb49022dd2be9a4a69c7db6145377289c921ea0292f3e4ad84e99ed72696dbbc97a3644478761d6083aeaa59004a9694d545835549ca3357cd9d63007cdbabd6e1a0b661113ceb370fac0da48b893b3c8635619e79f4ca14431cd9a1be2f34aaf3bc059de3a3d9b630b5542f38a5a1712c67327c893bd64883b7701636b0576223c4868f2195716c3499a4295b0387715c9ca4feb3b1bc08c6e09c1e809988e2f414f0b0cce5515f43b50c2dba028e9ac11e6368062c360370bb7f5655a3a75c2e7aa86ba9b892019db150bc7dc881c5e3b24e414780512bfefbce95c914cf060a76fa4c34359c634a1a11c40ab7b56af1d19e2732ba6f3cceb93cb31e08c93f2a9a33841d667079f1715a56013c0e68386b639e414540cf2b13650ca9378234b94c24bce9a9cee8c2adf4356f246dbec0bd9b371ddd296ee623603edbaf65e734504844aff0438d163b27c34d52163d736bcb42b0a1a67067a6e84bc8f849531a631fc55046da2b31e0b99b938d4f8b239384bc2ed54e46e17e9a8297c2a16775f77859ba69c759638fea8fc2057b5105952b34058b329ee7b2b08a69b00962c31a5106a281890ad6257daa8c6ad5854eec7e8a203cddb935ab5545e3e57ee5f78925b1531e5c4593a7afee319c5215645905b50cec48961b2b6c1727b4794ed382c66c11b67804b18c3c0000868ee4e3ce4e9790b681161b2cac3f8a1a419892608814aad65880e683fa75ce66335831a7bbcc236dd6f2b8c63560ff1939b2b56b97e87049eb4c65f42d640c0d8fd5841e48bcbd1815ef0c62da099f5478bb93198ef28d89ec6714b0f142ece80c6a6050d3aa936c25bbed1dbcfc99f39b4805782b", + "sk" : "eb8809301a6603d8822f86b6b44286f1e1b83b121b3880c35731a1215722562a2f14d15364b7aa6ab35503331dc63bc435f31a23ea1a7dd060195ab2626245fe2853a88244b7522bf9fc39a76b188c7260c9c2829f7a6e1964cfc8c28f45889958731f742aba74993c2a75bf4557c71fc5390067ac00a39fbb7049c657056b168a83899e94bbb38adb1837b53a32e74b8eea1a2cc198105cc32932bc5d4071b06b1a6cb7587deab9f7528309a64dc5d696ea00575be8ae3788721b061e6f143dfb73bd9e2bb04cca4074894b067a70270b7fc8762772890ab8d3b3a5545b9c48be169c1fff82473b250a25f15f0bd7b142c97a3400233c57b8f5db3db25817880a4490f04977a605cef4c151593bf769100eec456ee7831a526066e757f7844f660392f6f91372dbb0b8a3325a498bf7291b3ee048fcb61db8ca6cf8fa0b98671894e95094b325b922103b564189937c1f032488d868405800264781a702878268a7c19b8c39899262c246a8b4cc91eb5afbc8765d23a40b40c49decbf917737f14765d0e7ca19879236551ddce824c22676f754444a829434a01b264019d970cb44f1b8128483c549c329288c9a55991e12bce3547f22d4088527a8d1322fce360bcde1309205b2547b32e917a39d4846e45c5d4d16aec4435ad8695ad384236bd71336358294652418a33839608230270ae247780f16ba3fe7ba2de37063b66402d360601baa068833bdf2325f144aa6528db92225360032e5199a8e61ade5087dbb741e2903c245a1c95470c795bc0ac363806cc6be3268cb51d333100a21f00917bb3479fed22f3d263763b406dde76514e929f5c604dd7536be6305d6035f31790c40aa6bb5f17ea2ccc9e07c6262878ffca72d78f4208bf804b4c322b1287011a21dc54b81bfa22bc77ac1a0db6dea6c4cb7ec49d8858138f45d9d200a52d33d13b533cb6447910cc4cc21a0b9350220845c1c4b64b5c84bbbf7c7c3a4932000559e2b068d2ca9bf44b0f7ea760b225a37e78a84a5b14c5a2fb926ac622b8f86c7ac7734a82125b18f1575fb3968a4634d9633ca7b0a2d3e56580c34bc3b13741406be06396e66e64126888055aba9c8ca2ed2bc344a38a710dcb1e7d72d70a166dabc79cf79439f5340225378e7e062472584a477cd67c812733b5d57127d6cf9a6855b9a4479af6870a6090caed93a642bd91224f6b1d1f13b86582a5a7c227bf21b1d7547b2dc398fc88158e87571e826baa55933459521401c432782e2112d1fd7adec475178aa2a3ce59c96da6449b75dc5aa37201ccf404c5efed99c7b266a97d46494f1316f0781ed830da8484a2c5174403c0efc2b1010d9559329c714771b7bc7023e9c89e3f0a601d439b8bc2d3ea1b01a991fafb409ce994868ba5ece31330118161ce9a6c08c5f4c65af7334920b659b56d2c658ca4d9951c4c0b93f43a91d580b81087838ae28ba99c1b916103a91709b384840fa4a047eb94abf2c96de847d04e2198e363d248921a2537172735537878bb65b2b4eca2d9a1c4270a8a00ac667e7f9192f7c46c244b6b7676086f18eed246bfc10855e9591de3415142a8621f98170fbb55e608e10e38b6ce140a3835172387ea722339b1c6598e53d7fb694978bb5a3b5cadd1822374071ad6bb1a1569230c6042c9cb9e205104bc6827d3b9b1912a3f275cfd31a28b7291d4875c88954a36e078c9f72956e874426632a9b2b24132a1a45306a4d8caeda6a2c401713d4176c694378698a77284b7a9dd016cb332da7138511923d9f3850ddd5c6ef5ba28c357ba766b960e351df862db600320f996943e10046891f27b2b243ea71506b755f27c032690713c42298a16096d28cbce4051633974f02adeceb95e1bc264c45944d752e23b000419c2b88108a0320b3c86204edf5914f324b221bb9884499603137342b8d102b96117c88d6b589f9545b639cc18fc2c89d144107610fada81b1e2344a5cabb357acae302bebd71159bfc23906bc2bc781a76a68489a73dd5235738b06f8bd54a8771257513b6e1e74dfbf774b1e469e67086b84c1a6ffc274b73633903aebb05911fc7b99151a8a6d0abe8aa466473b2ff2155ae2568c23576f70648676bcc1a6a19e880267f139edeb973a8a9a59ad2a8edfb5cea9a0bb39407f5153633651904e40d7b863a34774ee1e401a9a24a960045d4537e5124921355cce831936f307c7cd807eb376ca1b640e7a76964c0195b6848b2cc9f832ac0c11c3c3c7290ee182c46bc1608c49e809b1c24a7c738845e9ae972d70c5ed346c46ccc73e0e251b1b57368b96dd71cbda55366585011ee659a2f081a7288c873c8a98964131c078aada0ad1662bb0d2b0a1555a3c84555c593231d167d378ba606257fd3958bc24b47e8380dc370c374a869413547d0703d28e4b5ec85cc0c897f14d5b03d6520937295183ccb1059821c2b866e755e24286634ec088522941516c592418a4fa872b2f911018843d7c877da76c1822246cbdcc046695a1e93aff063a577fc0eff56b27a2bbb56f76dba2b34b6a6765b78493f514661a4a83b58b42e4b96b471068682bb73f535e32c8fc7964a978b47be9b23cdc2b33ce980f66a033f8154bf24b73147152f544939377ba2ecb5a288276c712f2317ac69292eea9005a74a3fe336aacc4257e46395fa9a96a3fc9172b5229c393021e57265d017f6e7a5e92066b459199957cf4dc653ac222bf0b953c3c4ccd5f7463de539c024bfcc9475cb3437c22502fe16b909f73b6e733c6dfc6d87cba8a13220e823a46ed900c7649494006766a23cec36aa46756d3a7124bffb2af34c586847162735ca2d1b259f5c1eb0912afcf6846641984763266bc0add6d60fdf5b6fd87343a5d59c108cc663d8b700ab1dd5c0ab60fb66b764201722c9c2f5b2ce9a88162c3135d44ca9a735fc90b35058bbde332063820f3085cad54c4a8cd8708d43b871ca2b41d0cfbbc066ab45bae33cbf2700c67a5a62cbf1ca19c2431b6c52ac476fc2ec4c00ea9c14cbcee11b1232d523aae8af555958c3089c6c45b47ba58cf1f884e77893fd296ce80584a76abbf2330ab058c2af770e4468097cc20748a188b6620f128912126a899d7b0df24b067a73c4329314c3f6b0b9b83fb450414cf0a2ffac6fe2aac17359b20288a14272a952642958058f04b24a69b93492bc0dad67a7552b37f2417cf7e5b889e97b2d02980f7336f8e0198123c855dc1a40bbc5a93779c7c7be7089a8440214b3542341e56499ac1f6ee61b981705258c5ff6e74637fa0e48556bd3542ee342891ea4b4dd5a4982b0471ce63d61b3adcd1197dae05627c5993b502bf3025f6cb8792f32264184b362909be8ba74a1b6674e253f28b086189115129919821b867cc84341e3ab43b350a5c79d5af47b4cd228856189454538d362049c710953f33678c28f3cd9812d731aa9f95004b94425c60cff24186f644e749a6963b77760ba491744ccadb72e23653a3a08a1f7bba316a9c83e3113cb49022dd2be9a4a69c7db6145377289c921ea0292f3e4ad84e99ed72696dbbc97a3644478761d6083aeaa59004a9694d545835549ca3357cd9d63007cdbabd6e1a0b661113ceb370fac0da48b893b3c8635619e79f4ca14431cd9a1be2f34aaf3bc059de3a3d9b630b5542f38a5a1712c67327c893bd64883b7701636b0576223c4868f2195716c3499a4295b0387715c9ca4feb3b1bc08c6e09c1e809988e2f414f0b0cce5515f43b50c2dba028e9ac11e6368062c360370bb7f5655a3a75c2e7aa86ba9b892019db150bc7dc881c5e3b24e414780512bfefbce95c914cf060a76fa4c34359c634a1a11c40ab7b56af1d19e2732ba6f3cceb93cb31e08c93f2a9a33841d667079f1715a56013c0e68386b639e414540cf2b13650ca9378234b94c24bce9a9cee8c2adf4356f246dbec0bd9b371ddd296ee623603edbaf65e734504844aff0438d163b27c34d52163d736bcb42b0a1a67067a6e84bc8f849531a631fc55046da2b31e0b99b938d4f8b239384bc2ed54e46e17e9a8297c2a16775f77859ba69c759638fea8fc2057b5105952b34058b329ee7b2b08a69b00962c31a5106a281890ad6257daa8c6ad5854eec7e8a203cddb935ab5545e3e57ee5f78925b1531e5c4593a7afee319c5215645905b50cec48961b2b6c1727b4794ed382c66c11b67804b18c3c0000868ee4e3ce4e9790b681161b2cac3f8a1a419892608814aad65880e683fa75ce66335831a7bbcc236dd6f2b8c63560ff1939b2b56b97e87049eb4c65f42d640c0d8fd5841e48bcbd1815ef0c62da099f5478bb93198ef28d89ec6714b0f142ece80c6a6050d3aa936c25bbed1dbcfc99f39b4805782b5bfb6d44c0e7348fba37d50b05031c0489d4294be6cfdc6f4146740e54fa5d698aec87a9a79204cee2986867a2906eb851b734b8b22b91d6749b1a5f07c44e3b" +}, +{ + "dz" : "38a0d5f41d7dc1896efd1b45b0485634cef149828751b96087a0a6dd81b4d58aa2acf359556df4a2abaeb9dcee945829beb71185b4d6bd18b76e5668f253383a", + "pk" : "24e5249c820c83a86b66536c8fb371772408729447f8f2bd61fc63db224d868b70c8e8ac6685c8e3bc2375049c25f941169291c38a0eb0f3cf027bc8324398fcca99feb47059e87db1c2b723522d3f09cb8a19bf7b2b35db5516a652b837fb94a6ac6701c479686ac758c381fa242d8e67b1e7f6b0cb04cee5fcbe2bc5b266dcb55f1c72b091039596c4e4e50db8741763c35365931bb37a3552bb3223938c6a876e54121fa489c502e14943aacebe7a5e7747bddf5c6e916095bea36dfe8059cac7adc0dcb10a64bbc2812bbceb001e22cd5438183f9b3249a27566098af16782c6b503b987a6a5896c1bd82ef7d3c5c77b82cc797bd682849826981187a1530b4fc07173dda9ccb8c5248583503a8b974e8b1ca39b1beae9ab516087a170ba4d12ad5e555f77f27c55c519226cc6b3246ca1328db15648ed4394cc038245bb7d9ea48af2350f0961283f195bd51304af6653bd133e241729b5a62495c8c45583cd4c30bb1c538fa4f86afe799026f86e1de0024ff13ed5713a8806cb9eb6cec9c94c4fc4abb2569d9486507137733e681a5eeb479c8256ceac1ef823b34995c65cf43bafa250a874b743388cb6541d8346071f075b439620bce761cbf1848953200543177e0154c9343b47ba3f5ca025fad201bed145b7e8abec99a404621a11372c930713a013b0cf4b346ea6cb64620859d458d0e08b5d416bc86552c79b087f63539303c6fa96aef18c6a61dc37e1e8436fac43763c9acb9b5955157cbdc15d356936cbc603f6eca2e2a53163591b3d2257d67335caf60b4223b8c0cb7c54454e3b4812e5760848ec0babd9a0d7da9e83719bb0d7395418c44d86bfeff4c8a8548cee6780a5388e36eb4f5667ac2182c213a577fa2c4616814ebda8ce8a1c5851e0551d356471a8051d179de078c9f12163b0234fd729c9b02c302997c13974b47aec7573604d8278783bca1a5f184f77047f3b1861b7e1c2dfeba290e785d77ccc37e0ad03c199322c475191aaaf87300ea43f6a956b7d03b338b147cdfa14467b2850a73ba99c6b39d89ec6fa3052a9bfd0f6922f9b37ae6966c940370811aad1572039ba3365d089016c21fcb64fe3d924f805336d49683ed262410594f8205bb2649082642314fc7065cba9b8c4421f1bac52f69ea8f96093f89342b879eeb785756587a4027680119d41bb559c758197d360342bc3845237aed01aeb8104490b9bcb4ac158f154b347a49219ca5a401f90d1c1f4f7ba521bb33ae0610767207f3c9feb991e7ce444a42b33ee5a14710586523cc98aa53de01801bf383e33ebc03900678750734311c349cac283ba827fe39f976b3de28610113291f61325b870384280c58ac9c48bb65c5d8a672c86b218e8a706d3b87f2341b95199956886ee0ab068d927ddd109af491d23e991f4e8619e4aae99053c4db3514d380133105ad60885a9fa5fa80c144a3949cc8c33b591c776d5a7a6e9c8d12417b4c1661c867119f7006e6520462b63e1770aa6424dbec6b9a0c2cdb8c8945d653e62c790d7857681b479fda12c8894640aab041a044d897c565ce882aeeb8caf42630e10afd12293fbec9d7ef259bf881c92cc7706ac41626bbe1d17373e57b3a86a3ba62cb6084869b58c659371c110930b6c75626651971641a899645846f96081b00f6c29bcf8c646210676bf266467d90eb393b64a1593b4579adb0b549e6648da5c9e2eb3bddbc78c468912dc674b126acd4448bb40bab46ebc8620288253156d8d39ada1b639c6f69d34e9a25e6b6bf4241bc00b5968282bab963820fac7159001fa414dbe2b94a74158ab43c6a43519f9a34a716cc07908452e5a0a517138cf46220243bf2e27ae78835b73e0720222700861136b2a405a241e58f37f132c588a1102a5344b704619666900c73990c2145497565d09e984f2689e315ab204c59a360534a641228768a9f1581532ea9d7717b8d8069158605508a24ad1c71fee5760605bc2d619b177985ce89cbae0ea5ea335529a20225cf83744d807b886ccd5cbcbb8393d5bf144497a4c454a2ac7589b5315937345cc02372fde21bec80c0ac8912d28b3348df2a88c35b7f384809f24665600583530226b50a6429217ca211946ea66451c9092e7c42b309a922465561b307f8912f29a1ee687b1d96d8c201bdd75a34e09d954a4267f21490c0eb74ae98fad1b5a3b5d2b9f70e9", + "sk" : "de2a5203a614274820ac186bef852a92160817520323d112ea9240ed0bb381db4b012a4282775c91055800516cd465812722c6696165d80188c1f7bcf2f99cf18124a2905b6e3a69185c0a20f61913402bc2622a5477bd455046a032823da983660bd0aa51238de42a86fa9654f61ce0ea1e8f865bcd9407b879cd54c8520acb99b74abc1a6a23b767ac7c9449613a4a4b5003b2000aa52c17cb6652ce133abc641eaa34141feaa745c06ed7a1273be6a66eb6779232635c22b4030252ab30ae3c13291513438f2b19c4a10cc6f884d093223d2b12e460b49c191adcfcbd4f82c67ea936f946391835b2752ccfefe46230d84245ea8d8c799eec979f98409f51a65cbfc62a8c3a889d33a72ea24c96c094257104701755949524d5d4abba117a098b16da589c47e5415ed0920c4b2b5ae0bce2616c5781a903953d2d768ef5c58431984f671a3b31953940a6b52f24658ce943fc360fe9b0c9f9308caaf7a04e3779ef5ccf99a505b2b27d1c0b68f9f2254752820f6b721d55be6a205b3c832213d8cc015a14f5895d8ad17a14501ece031adbe36362b1c475c7cb2129863838ae80ca94d67007e3b5668ea415e5ac3e66d1aadc76021c4a47c1ea8c41423571a553d041a07096ce6548511cf08e108893ac1c0ae3990559b21952e5cdaf1751052425f483c88a3356ea567c717c75dfb70ee49b0be7f9cbf172ab7dd22172d40214bb7c9f22801c3645c8d075582965eb02ca9dc68dd6c3798d28162de30da699a29c216220e35f725a14b0708349e4c87f726755b68f632918daa2c83836b8ed34a542daced4a46351f337b16516b853bc2a44337710043a58a83ba5870af51af1252b83e69ca81539bb89af01526dfe7162665b9347d441bdd77b2e4a3665565307e65fbdd341b0b154fef5aa7ea530c93362a0a4766ad13307e90d1dcc2a2a37746e881d57a718e2964fa80080d9f28074121893c95ae850c61028a6e82caa571a63b7d85c37290b61ec6ebee839da040fd1d5b359d9bce5ab54462242eee31892030f7402aafdc1a2575000ad636337ec69537c4b61669547859875a2b94f13aa723182f9424e8a95051f10148f470f1d04c9c444641d4ba30ceb312bb89dcd04be5b421fa5d7327748c7a37acbdcd73589a94070635ea6198f014b4471106862ea794d2c8eba828e95d81f3bd226247952db967f72aa44311438d4d995b3c6ca6d6233705a311f095a6c9ca8cec042087c8071d00ed4acced97053116a8928981e61c5b3bf8177e4d99b4a130999066729f2875da7462b7827ca00980eb96d3ada528778cabd214dc0969ffc38b795512bc385921496a27b1ac7a099989a22c173a06ddc4b81b2365a9c6a160cb36f70fa4ebcf22c77e477da74a7be867394e5168b744dc03a32ff21221f877421a4aec9e9a2bcec7e46c88c2ef550333787dfe664e767124c5b0f09f8874d085324fa2eee6a127cb2a3c6936f649719171116bdc8a6db265c387930be3a1daac267b838640d44c8ba75537347735de517582c9d8da18666942db6951a4a7a2ea8f09768d026734c0bdcf7983f877e29c42f659873114669974c9018e7392c4500a45bba4f3c834275c84289c23fa13ca6e927c128accd480225c79247982b811b885062022eda9b448061aa908664400acc9b7f34284d98d526fb96336b408845d85c4be2b0215b0b32547c5f4b7e43fb465a358f6b1297afc22bf08b9307fa8e5a1361b03882a26798106526fc136cf93438b03601d48a145d58998f087d0c4386afa0c834a91ad3121de0c57dd7c117fd339dde05bc09e0a157c9c638d8c1a1d10687fa3eeed68eee7b3b2adc8b970bc0a0820b14679462c1113221cdcc045906618dda5cc340c448ba0038c0bbc36de75c00fbcb11f55e6532504fb2ad08e59aa3c65702547d04a02c5da62286a2053a75975c38c865d3bddc9506fe7c7081345700daa716da27b789590360b5c6f5b9f964921b7680ed159899829052987536f4375a8c5ca9e322e05a3d11f58bea4b1de4191667e87508ac279f4757a54393130b04675c312314218ad0c98038488bd501104989055bbde396cec47790b462b13b00a625a732959157e5715b16f4aa25582b7728c427c5758d25191b5b42c33b5d096ba301075d7c515ad195aa24e5249c820c83a86b66536c8fb371772408729447f8f2bd61fc63db224d868b70c8e8ac6685c8e3bc2375049c25f941169291c38a0eb0f3cf027bc8324398fcca99feb47059e87db1c2b723522d3f09cb8a19bf7b2b35db5516a652b837fb94a6ac6701c479686ac758c381fa242d8e67b1e7f6b0cb04cee5fcbe2bc5b266dcb55f1c72b091039596c4e4e50db8741763c35365931bb37a3552bb3223938c6a876e54121fa489c502e14943aacebe7a5e7747bddf5c6e916095bea36dfe8059cac7adc0dcb10a64bbc2812bbceb001e22cd5438183f9b3249a27566098af16782c6b503b987a6a5896c1bd82ef7d3c5c77b82cc797bd682849826981187a1530b4fc07173dda9ccb8c5248583503a8b974e8b1ca39b1beae9ab516087a170ba4d12ad5e555f77f27c55c519226cc6b3246ca1328db15648ed4394cc038245bb7d9ea48af2350f0961283f195bd51304af6653bd133e241729b5a62495c8c45583cd4c30bb1c538fa4f86afe799026f86e1de0024ff13ed5713a8806cb9eb6cec9c94c4fc4abb2569d9486507137733e681a5eeb479c8256ceac1ef823b34995c65cf43bafa250a874b743388cb6541d8346071f075b439620bce761cbf1848953200543177e0154c9343b47ba3f5ca025fad201bed145b7e8abec99a404621a11372c930713a013b0cf4b346ea6cb64620859d458d0e08b5d416bc86552c79b087f63539303c6fa96aef18c6a61dc37e1e8436fac43763c9acb9b5955157cbdc15d356936cbc603f6eca2e2a53163591b3d2257d67335caf60b4223b8c0cb7c54454e3b4812e5760848ec0babd9a0d7da9e83719bb0d7395418c44d86bfeff4c8a8548cee6780a5388e36eb4f5667ac2182c213a577fa2c4616814ebda8ce8a1c5851e0551d356471a8051d179de078c9f12163b0234fd729c9b02c302997c13974b47aec7573604d8278783bca1a5f184f77047f3b1861b7e1c2dfeba290e785d77ccc37e0ad03c199322c475191aaaf87300ea43f6a956b7d03b338b147cdfa14467b2850a73ba99c6b39d89ec6fa3052a9bfd0f6922f9b37ae6966c940370811aad1572039ba3365d089016c21fcb64fe3d924f805336d49683ed262410594f8205bb2649082642314fc7065cba9b8c4421f1bac52f69ea8f96093f89342b879eeb785756587a4027680119d41bb559c758197d360342bc3845237aed01aeb8104490b9bcb4ac158f154b347a49219ca5a401f90d1c1f4f7ba521bb33ae0610767207f3c9feb991e7ce444a42b33ee5a14710586523cc98aa53de01801bf383e33ebc03900678750734311c349cac283ba827fe39f976b3de28610113291f61325b870384280c58ac9c48bb65c5d8a672c86b218e8a706d3b87f2341b95199956886ee0ab068d927ddd109af491d23e991f4e8619e4aae99053c4db3514d380133105ad60885a9fa5fa80c144a3949cc8c33b591c776d5a7a6e9c8d12417b4c1661c867119f7006e6520462b63e1770aa6424dbec6b9a0c2cdb8c8945d653e62c790d7857681b479fda12c8894640aab041a044d897c565ce882aeeb8caf42630e10afd12293fbec9d7ef259bf881c92cc7706ac41626bbe1d17373e57b3a86a3ba62cb6084869b58c659371c110930b6c75626651971641a899645846f96081b00f6c29bcf8c646210676bf266467d90eb393b64a1593b4579adb0b549e6648da5c9e2eb3bddbc78c468912dc674b126acd4448bb40bab46ebc8620288253156d8d39ada1b639c6f69d34e9a25e6b6bf4241bc00b5968282bab963820fac7159001fa414dbe2b94a74158ab43c6a43519f9a34a716cc07908452e5a0a517138cf46220243bf2e27ae78835b73e0720222700861136b2a405a241e58f37f132c588a1102a5344b704619666900c73990c2145497565d09e984f2689e315ab204c59a360534a641228768a9f1581532ea9d7717b8d8069158605508a24ad1c71fee5760605bc2d619b177985ce89cbae0ea5ea335529a20225cf83744d807b886ccd5cbcbb8393d5bf144497a4c454a2ac7589b5315937345cc02372fde21bec80c0ac8912d28b3348df2a88c35b7f384809f24665600583530226b50a6429217ca211946ea66451c9092e7c42b309a922465561b307f8912f29a1ee687b1d96d8c201bdd75a34e09d954a4267f21490c0eb74ae98fad1b5a3b5d2b9f70e922599b58af4bf05a9815c270046161175cfdbc167293cfd50e9d74851ef1d1dfa2acf359556df4a2abaeb9dcee945829beb71185b4d6bd18b76e5668f253383a" +}, +{ + "dz" : "97b5665676e59e3538ebadaa8cd50df1f9fda1502d9894c616a946078e56b621df05318b5f655efe36f1b678cf4b875108a18db2fa312261caf839f84bd956c5", + "pk" : "6820166411abe7da1944fb933eb009de46ba60e249664722776b37ccf770b187269cb240004aaf74c37eb027c62536ae847b8ec48a6b2a9ac68307802db576b70226fa1b951da9cfe094a0bf4b0b306c5e030baaa25baa591b289fa24148c7ca16a19e0a0039eda555645bb65685a75a57028bb29456e4c16ab48c06d346ba9925db4184adf635e779522c2670dc5bc1ac86c662eb37975aa806a2b2e307904f6c6a0d094828aa1c07891cf098223ea78967e7af701273a8a1859adccac61bcd0c103f3c13aca18689397bab1ddcbdee2ab113ec6932c68622c513b0d66c60244cd77441c7aa964b5331ec11a088a5034e064a1d95b4b389c15c51426fc9a135464416881858511fc894bc2a3b0b742366dbca062f2c3eec28bc3c38c809eaab081c5dca65bfce171057ab8467eaab50987732b9c85bdcaee647342c3660950b9ca7c0bdfb3bab69268fc8486397b540f0831efb861ac11855dea4a588c4935847a644a470f055a923162f1dbc2b699020880cb08b80621de33a9f0aa83fa2b5541aa2cf41b98214a5fee14785661a63603f0492163b47829c71a7afb0b5efe94e8e225ea2c0179539772a510a5ab5456be4670a076ee1b25ff62687a96284166576e3e773adf2c061258bf2d28b1ba00fd485b8151076eac5be6ab7ccd81312a9ca938f256b6fbc8ab6d3c3a1da5c75e1806c5c4cd4202c0b20816e368bb2443684463ed43787a89236fec32fc99891166462852750a8c1445ac407924470a56b1cc75c7a378a2e40c00fb35c0d4f65bd12f49911fb923bec1b635baca8428ec7d13b36079732838459c669f7f0c26281717ad45eec972011c66d63a298b95566afe11baac79a67dbadc882815d014549cc294b658a8c00a2422c0d23f6a0be9bca232c8374e616e749623e8a99b0f96a08c95897e88900851076b1b470732ec2462bc9c943255bc475da70b44b134e0cafe8f3cef42972cc175e04fbbcbdf4cd151639155a0469651408c9292de9383e63c08c8bcd96a69a3ebaad9b2c1940a37f6c32b1d3b702d28acb908cb2c7b88b89a7ad4c87cfa6c53987e4721d2302bfb53ef3e9bf7319219926bb7884111fe2c4a9aa4c4c1c0f8be3bda890c0342b56f826a6e971c33f900408292c5820c92b66bc8432cf735388ddc35eb004506d8a671547b7f324741f609e2121a0592644e7e0cffce7280f77c34d05b930b96ec9c79838da4a78680da3b07c1485081d14b9d880bf3ec61d852114d738580918c72a270d7034412305ba10d6a5629a931747611554602f529f32356d9e0331de2232e65c695af1b597cc816d001ddca540a0fa3ae67313853b6a46606c1bd3b32d193bdcf2cdfc2c1f9006724365550632bae19bb3d60804d0c80f17681ee020c6cf3cb7c19a22b1d4acaa8abb40f308ec2cc6616164e106a06f700bc62266ccd40d4a414dfc818ef3ea39540247c0853309d45fb99b84fc3ba114c240915a19e96b742a234ca1e0183e60c8acb65ed2c8a7d239b408c33fc5e31ae83caaad17c24b99238b2a52181517a1202c87a17f22bca93e758ed95a895a6a97c163cba8a4c0d0b980e9871fa8f595a668adf927c4538374c7e65fd052196a64cbaa23969a1c07145352b6829aa9e93993c640e0f62b5bb0228ee37400619eab437434026df078bef452267841bcb72844e836ac95d25439567a76f69a3b2c6cfc1c4525f340b40c558007b4f76864e8367cba7c71edf2aa9ec56f25f606cdd66cedd0937451b95422a509b12553a8cebe7b95bd97b45564c98d20a9ce8c51add836d8c00af538b0d0528507bc3924a731ac05a688a1680e050b770c3a8f49c654138bde367f4269abdc4215175799a6112bbc186b23745fb0cc3f2bcbb6ba1670b1834e99e10b2fe25003243284c59ee4202ee28a6ec2086510697240d60961398c77b3b046a23a55b89151673e1ad8a9de959923974c540902716c973ea402b3576f5b664da2a104812a6101996980d68baedc34f9856effb6c457c8332487349ea3b8bc67acb7fc509c22a476c331af75374c57b4c010675d490da92c7c60ac69d89a25e0d67351aa5c9e9880bc1386b77019436abf526b319ce44cc759b009b93f8b9c3059bc7c63ab483a749e1a761e90587f13945674e85b7c896280d15d2d20bcea11db480755602348b4616400faeed3c143406ea9c1307e37e2642ee73c442a", + "sk" : "402525b257c035fbc56b1aacd731540e40999eb1a2cce3487189184f088a4bc96d9dcc63ab435bb6e26f78a90ca281b436ba7b222cabbba20b4ca3223b1210b5da1c7fec7e64d27b9d7abd831417d8e384aa500a5a986442c767eed412e6499825ca2946bbb83e1a9d07f14429aa46ba598595dc4639da5015c96535c90e99a1c36dd511daaa713f741f3ce3cf8232cb5ff403f32c75467440092a4f7714524b9ccc3fca9503c50cc8d676758ab660e2742930bbb061639549346b9a67d82617a33283061011844467bf12ad270ab2e047835ce36276051062f46f32e05c3af197cf7244352c03f423305c6477a9b606301b606c693ea08196a2c8b639c21aa641646bd3c958f3b6da0ca8234b17ead33b9a855e2b0181dde85ae8a33ce357273583cb06968f07f6b52de50d6600973b5b60ec3702c5480d95820dc0aa611cf80891338b5187b74d7046906499bf7419f2dcc89f7808b5557915ec82dd90102800a26e1ca3503b8844416c688386c3a74fe6b11fcbb6293f9c65fa247c70a40d8779056663bf92ab39b2596a17710204b884765c5c90f6b61b660a32c8158ce1817f45c2d9c769bb203acea434817c6f788482135118623152c0f38ff33733013a3fe5898f741986a5d322f679a7c0a17040b4cfc0f65e0395bb7d5b698e676db248880791274ea868d13009e289951d3b80d57385924a433a83a42d879208072a2a5b563b171c9b53c263c6b233a27e40f6b3205741373880498552afe88132b80f3849c937fa91ebb3a0770c5027a7065b961365429a7685bd2df71792ba893cec50bf398493d0676e002ea5a9054f095d52870728fb9ed9536da077273437689209b2b14407f9639bdd287ba9f77af0f6c750580c7cec0426035e89745e88f3b328c60fb31987d7fa0280d062d8ac2f57b5133aa1af119151344b5f4589389aa11803da3c1f08aef60589ab2687e5ebcdcccc9d3c38b80d078c3c4038d0870e0da3adb641a5f22198868a24d2a128981b4bebab984f9c39edb9650d23823dc1ad7f2c39067b95844829bf24ca25b68325134f14d9a849db47169304f3319f95da79e119be3f31af93cc1f1a1bb6743379a6314477fa01e687b135256f72d5657561b98d215ed6bc1bf80239e3831c16317cef9b7e2ff60c6d116bf8456c11c6a47006b75b27ada9c6baedcaaa8775306319982372a39039bfd1315aa310c7859aa42c287dda6cbbe0f24f288ba3f9d78b214b6065d35eb9374ec46c251e77608c53161232cf11480b92505ba69a7fba20b5713bc616317e4c963fc938af06558ec62b47be7c967e652dc55c1ea38c1a9d90947d167d672c6d0c608b6b9535bfe20e2e2bb322155ec3e777341c3b5f4a5c79a93a376a023f263e71c215e19b2cae2c11ec400a93439b0bd13f8caba7366094635cbd1558448294704c5b209d7b7a6ba1aae425aa03ab197aea341d0166eca608337c387644638ee00cc3fca30f2a063b8847f637299320127d038343f001720ba4aaf339404a2494b1385f851ec06b07105869960332a8da7f5a7065e8983261eb7b68191481062a22a800932a38e0280ce73c1b762a3f95058492c27c4022cb2f82c1781418ce217c06d5ca7f1ab2e99167705b3721719497b266db68b6ea1356b4c642058b4f1aab6c4093c3b2532181f9bda310387a216b6339341239b8fbb9cb9d8a46554c1aa875b1acb34ba50b2b6b11cd07ab0c695a66f025cae448229655b177543b98478eba7895882a6a7e20a5263370c7177370d1ae4b48b18583a49dc62228165c55368ae6aab812f6321aeac1ee5542bd35a9c291b6f8ac01df1c10e5e10a00d61acaf83b125407445a341aeaace6f592fed5bff105178c018f893116bad4aab410ce04071e312269bcb1725cf229bf57103fe90a99dbb8a0105e926c28aa87571d613290550ec96bc9e2213a088c98c3981727e8311aa595f221183a9657e0cca6ed40962a30570a475e7c70281576013d725793e11a91b312e688a55365ce42ab08ac759897a8af7c607622e56014dc825f647d1421a9099b14bcc4934cc4b389b333c14373fa593f0851291a1b3b4fa96edbaa893e4814f887adecf9560154876e1b861841a2ad37236dc2c647e608cef8a3bcacaaba0a66acfaafe173cef526c86d31416820166411abe7da1944fb933eb009de46ba60e249664722776b37ccf770b187269cb240004aaf74c37eb027c62536ae847b8ec48a6b2a9ac68307802db576b70226fa1b951da9cfe094a0bf4b0b306c5e030baaa25baa591b289fa24148c7ca16a19e0a0039eda555645bb65685a75a57028bb29456e4c16ab48c06d346ba9925db4184adf635e779522c2670dc5bc1ac86c662eb37975aa806a2b2e307904f6c6a0d094828aa1c07891cf098223ea78967e7af701273a8a1859adccac61bcd0c103f3c13aca18689397bab1ddcbdee2ab113ec6932c68622c513b0d66c60244cd77441c7aa964b5331ec11a088a5034e064a1d95b4b389c15c51426fc9a135464416881858511fc894bc2a3b0b742366dbca062f2c3eec28bc3c38c809eaab081c5dca65bfce171057ab8467eaab50987732b9c85bdcaee647342c3660950b9ca7c0bdfb3bab69268fc8486397b540f0831efb861ac11855dea4a588c4935847a644a470f055a923162f1dbc2b699020880cb08b80621de33a9f0aa83fa2b5541aa2cf41b98214a5fee14785661a63603f0492163b47829c71a7afb0b5efe94e8e225ea2c0179539772a510a5ab5456be4670a076ee1b25ff62687a96284166576e3e773adf2c061258bf2d28b1ba00fd485b8151076eac5be6ab7ccd81312a9ca938f256b6fbc8ab6d3c3a1da5c75e1806c5c4cd4202c0b20816e368bb2443684463ed43787a89236fec32fc99891166462852750a8c1445ac407924470a56b1cc75c7a378a2e40c00fb35c0d4f65bd12f49911fb923bec1b635baca8428ec7d13b36079732838459c669f7f0c26281717ad45eec972011c66d63a298b95566afe11baac79a67dbadc882815d014549cc294b658a8c00a2422c0d23f6a0be9bca232c8374e616e749623e8a99b0f96a08c95897e88900851076b1b470732ec2462bc9c943255bc475da70b44b134e0cafe8f3cef42972cc175e04fbbcbdf4cd151639155a0469651408c9292de9383e63c08c8bcd96a69a3ebaad9b2c1940a37f6c32b1d3b702d28acb908cb2c7b88b89a7ad4c87cfa6c53987e4721d2302bfb53ef3e9bf7319219926bb7884111fe2c4a9aa4c4c1c0f8be3bda890c0342b56f826a6e971c33f900408292c5820c92b66bc8432cf735388ddc35eb004506d8a671547b7f324741f609e2121a0592644e7e0cffce7280f77c34d05b930b96ec9c79838da4a78680da3b07c1485081d14b9d880bf3ec61d852114d738580918c72a270d7034412305ba10d6a5629a931747611554602f529f32356d9e0331de2232e65c695af1b597cc816d001ddca540a0fa3ae67313853b6a46606c1bd3b32d193bdcf2cdfc2c1f9006724365550632bae19bb3d60804d0c80f17681ee020c6cf3cb7c19a22b1d4acaa8abb40f308ec2cc6616164e106a06f700bc62266ccd40d4a414dfc818ef3ea39540247c0853309d45fb99b84fc3ba114c240915a19e96b742a234ca1e0183e60c8acb65ed2c8a7d239b408c33fc5e31ae83caaad17c24b99238b2a52181517a1202c87a17f22bca93e758ed95a895a6a97c163cba8a4c0d0b980e9871fa8f595a668adf927c4538374c7e65fd052196a64cbaa23969a1c07145352b6829aa9e93993c640e0f62b5bb0228ee37400619eab437434026df078bef452267841bcb72844e836ac95d25439567a76f69a3b2c6cfc1c4525f340b40c558007b4f76864e8367cba7c71edf2aa9ec56f25f606cdd66cedd0937451b95422a509b12553a8cebe7b95bd97b45564c98d20a9ce8c51add836d8c00af538b0d0528507bc3924a731ac05a688a1680e050b770c3a8f49c654138bde367f4269abdc4215175799a6112bbc186b23745fb0cc3f2bcbb6ba1670b1834e99e10b2fe25003243284c59ee4202ee28a6ec2086510697240d60961398c77b3b046a23a55b89151673e1ad8a9de959923974c540902716c973ea402b3576f5b664da2a104812a6101996980d68baedc34f9856effb6c457c8332487349ea3b8bc67acb7fc509c22a476c331af75374c57b4c010675d490da92c7c60ac69d89a25e0d67351aa5c9e9880bc1386b77019436abf526b319ce44cc759b009b93f8b9c3059bc7c63ab483a749e1a761e90587f13945674e85b7c896280d15d2d20bcea11db480755602348b4616400faeed3c143406ea9c1307e37e2642ee73c442a4f71da07c289afd5cafba73184b9723c238da81e3ae109daca1873ae1e34d84adf05318b5f655efe36f1b678cf4b875108a18db2fa312261caf839f84bd956c5" +}, +{ + "dz" : "ef99224a03a85a46ef115474ec5b5d620da6795d6efcca4c9135d19958a9de62df7d92dda83e6b2ef4cce08c9134563063068a196d7b1a1a13623e48ae12528e", + "pk" : "60045ceea77d8303982ab9b039dc4c3fd0159d46c89e618304fb5d4cc53e9766138fbcb061b56ddbd61e33873a953590f628c122d049cf722737b54d4430c312342189b59364e14fdf8cb1edc540c39612f8e2bf88710c26425c09dc7affa63f52fa01db7794aa2c2abca69145e89c06d40189fa704dfc4b252811b939118f1b9928d0b0b6767a1685804f502a19254ff89a45d9539c9f968835013b69a362f634b269b911c4327520673049c00e0fc437448c2849089918ec93c2ea270bd0699c85898c0148f4a1095039a216a51143183f4d695aa456c32e8a35d351415120725ef995010409e1176806da6b6e08ccfb3093914c87c107cd14e11f937a9f138b928ea5580494c6eb643ae33b5600f7726e2004f52cc39ab24d0cc9c3f9e57a0b821fdfe8404e6532bbe01609a61def2b4f452a1fbff381692975e05121e2330c789055e5a4ad696678bbeb1a8d3247d2257ba246a2ef966c305a8f4fac73a6fc08f71ca500aa9d00962caab7a2780cb94c209b1cd43151f3248dd344bc9898b7780950a10211d73aa0ba20d89b01b36623ed8aae48845e1d7372f12b9a692b3d525263dfa12b3f312f91b5802d3b3380e58be6a92a70e77cd6134103496dc3e9236ff17cb0ebb04a1783379baa0a3c54cf1c5eb1b4afcd9a7042c50d6405b1b610a9429aafe61a5423055af9f61d3617be60bb59ee8019e72123069614e738a46703af5bf25d31ac4f1357832b1232cbb9325e522e79571a1d226397e407e4b08b44082e71e984e463747a230bed934127e892fba29b88857606983a60b9425008117ce17d20c82b6171165e940530254f2b0cb4e5c235dce373fe1450ee6457da59c331b17f8d4b5e0bab25aac789c04acffb957724783d00dd24eec3375f97ad838ac0c261789cd3afcd68b2d53c0c9bf944f094bf0875c0f08c161d3618c774304ab25563981974ca2e13b5bbdd210ec10ba39c64635c9025b9610b623c2f12a768e03163d75315c7097782b69c44b3a0c33a552228c6001c5ce194346a80824627b974d2c64fba994d2c62f8babac47c51dc100c54789f737c61b9b3420469b11d110dad9010c6c67ead2329d3b4c665ac528041bfd028612c608f87f3ab74b6b68309317e1c0ee5662f8dca46c26039e2dcb1fe8c42cff0057d4bb3e4ab3bce13c142e589592c0850e117cabb2cac88431461a5e6743695e096099a8249e22f4033c15e9266cb00a9a36103ac473123e95d373b0dc92cbdf6b2b173b07a3771456d283c758ab963811e5168694cc20e64e8a677e05e3915c4d93c8531b75d430b3709753f899b1c45434be196a3fbe5149dda2ac0912afac619b4a45f3df262f7d617322a9e8221a79f2319e6ac59034c80b3214953419a191b0e4a25247bfaa0defa001d5529b1cbb9e63ac03768404645bb8ac7ce25687be70796bdf516b76039f7b689ce6c3f569a04c52875ecdc9fbc97447e0160e75a89215aa263091e7cb5534a97660cc8515ed61d9b624950c089d9aa647f787a8ed7c89216694a83c56cf278fa94340d790015b914d09ba91e10ac5b7ba95792bfe779966ebc07ac6916fe1aa4bce56cbaf506563319c5a4c4344344b472226f59b7fbe7982c08afe9a60a80c446b8b341eac220fa8a664b6b1a0df72684b67bf2032d75f5aafff7cc724acf3f1051ec3cc4ce8768fa9ab51f960f3293a1fc527686570da34404b5681967258799fa26f22179e18221f4babc2b7c46601ab7ceca1a345027d44783e7d6c511615b108c4197bc0d9ee49c91621074a907ab292d4575abad75a19f10c2a493af902252bba57348dc33fdab3217778429680b4f352b52445eb662101dd22ddd211f314577cb23bc47c7176942c5cba072996c048408a5dd795907bb2e2f49acd0e75a93cc4f7938136d7c26da0691c08733e8138caed6c8cb116b900869f9fba9f5823b20626980ea86e6f487af758830c787bb1bbd8de024be9765dd04b969dc21589312e709cd6780c9a38a8207fbbe74f220c3c33e2a127588b64e3170999d3a77c8f67eec947cb69649dc64010a3119c9030e1fd0530cf5c3b73b631917719d0983ad0a06d2963741289a282a717d7487acb30354fc74b005ba01101a1c8b52c130a00339bff4f480a4e890030a709b28082d3c501b2aa2d14fbef9e429f8cfb50e84c327ba02edb7f6abdde459896eac77b5d8c7d7cabe", + "sk" : "499333bcb7971e60c8a924aa6ebb2ccff48b4d3b9fd4786741668c071aab1c401d6e50928ee83d7997cd10151b1bb28bbdc8844681cbf736c4110cca8f32c3ce345060080d9280b9d8d8b8621b690eaa77e6bb8ed23285eaac41ee6b44d85a7253d70dc3180c5bc16ff3b7a4371616c98b50c3dc46bdb3207f880220b6ba60bb6db6a3326137190fca28777a519377cf8f08b333a721ddf9c8a91479a600087fc15a35430091357759da0b009d86d312aa7c8abed3d6babc371612543edb115c0273c999452f85d796d9eaa442c880eb098ec2a8b249d3378611b4a27a583cbba276790e9a119abc9cca1ba7c57414c1d697303dea1778b736ddbb9f521a44b76941538666a98140263419d3bb593cb23bd070008f396aa8532a92dbcfa7031d5c537feb2594131204691605d7fc8e5c7c6aaeeacdfd169e62b476d3a65d611801ddb06988f38636f32600ebc192b8709b1c56070a68fed61866f00d0f2b16b0429a9edb6e6850366cf3995eb5c926ab4c82506f50017a1a106e2cc32698fb77bdabbc60f35dd93a54faaa10f4272c2ec98357f3c137628c855513173c4788c35af8bcc723b97910343eaf4172ac586064dbaa43ea90cc36521a54aad84b3cf906145ababa3498cf2ad900c10b5c7beb0fc11b8d358a90d34383faa5032d535935fa4c639cc7e0094534623176b836d7c041d2b6c1689c3325c71dbef0743863a4993c34623578428910959075c5129d7706a3537172cfe981e8ab8a29bb09a1681b6fb75bb60017ba998af84863aa17c03cfac56e18aaf714ac9854616f09becf13427e996dfb084b1e62c5495c9eeeb1c0bc23c971077255520f17692601a9021662b770672a860c025ba9238cf8c73a8a467833bea9462ae604387f11431ab5794907916aa15de03aa6501c993bc684506b24d715557ddb7ba01c492407147905abb8977902da131cebbfd9b3b5dbc7a03580726510393f2835a1db389804a7af54743c553f5c445b4d350d3679b8d300916be22dccc7a0aa009e22e98dc21003f7a8041813bf84a8592d7979ae34b299e9403fd8a073cba7dea6a44968944eb4be70623163eb9e59da4516612d3df06e80d8326090b52ec78c3b883e70c06a77c70fd0426ef34150ba3195d05075a08c133f608de4327712c825e05878ba74acc9ac66a7573f6d245f2ab3c09e702b1b395bb28c1746eca972b41fd9d28743b736ab39853066c5029b4cc37089b89179e3a822cd606bfbb74820d3885e3b08bbb0716a7c7d4b674f46ec36d6d89a4e331add040ef64cca6c3b1e1bacb5a5d857a729beec7b5f4b068c3a685614619d6021170ce22f3f28a52517268ac6693c58b3f19798e4b186e2f0c471e33c4ca0338555ce3c37316a291cb89a3fdbd1b64fea422c46c51e65844e5317e4dc47a9461704e16259701718600610d7273a09cd53b256d5c6701dd1cbbc3b452bf943729c3f35a2761360885cd65a0bd06965443e2762b4d5152f50a4c18171205bb192de1619d9f3217a870ef1272edd442f62c21257407427fa0d4e85bf4e27563fc2c569357e44f7239edb9828c65dae20870d5a48b4f807cba20062eba57f0613114c335969ad471178e6f3318103b038c2812c18bbd68903c00827179a710c23ce84670c08075b70513aa9d5c6b3c34a3e4c437cc6c14b63b4c3e1c27638151d8a2fe633520f1159c52c4c59536eeb22b6981b8d10c29469242f3a09a7a416c79d893fe2c5c3204895ab23b0b062160b58b99d501f2dbc3c75a594e0a605dcb6ce54832d2bd450bc4c53abd892fecb0db87319adc0294345770197acc8e1b8fbfa67e8a830834432fc93aa463541456059da44be22695b3ec0caec411835e409430076de94426ff03af3e97c5ed07dc0b9450cc1a37508d019ba1b08d89943a5661fda1e84f09f2b8961d36243f36155f95c8a74e83b0fe61966f1008826566f5737bbda0a3bc1b2e0852f50f96df1c692be536346fca97d83c41ef6cc63ab22f4a159229217261a8760e648d2653d4fe13884624baf9a57af50802ad6c90359a10f3a9e83119834a001b74a09baca15c80c2b1a391dc652236011885bc181f6a8b42e7b0581798348cbc987959462e3b2f8986e42f59d84ba35cb171f2e81bfa5079dd30b981973adf67c645dd82d60045ceea77d8303982ab9b039dc4c3fd0159d46c89e618304fb5d4cc53e9766138fbcb061b56ddbd61e33873a953590f628c122d049cf722737b54d4430c312342189b59364e14fdf8cb1edc540c39612f8e2bf88710c26425c09dc7affa63f52fa01db7794aa2c2abca69145e89c06d40189fa704dfc4b252811b939118f1b9928d0b0b6767a1685804f502a19254ff89a45d9539c9f968835013b69a362f634b269b911c4327520673049c00e0fc437448c2849089918ec93c2ea270bd0699c85898c0148f4a1095039a216a51143183f4d695aa456c32e8a35d351415120725ef995010409e1176806da6b6e08ccfb3093914c87c107cd14e11f937a9f138b928ea5580494c6eb643ae33b5600f7726e2004f52cc39ab24d0cc9c3f9e57a0b821fdfe8404e6532bbe01609a61def2b4f452a1fbff381692975e05121e2330c789055e5a4ad696678bbeb1a8d3247d2257ba246a2ef966c305a8f4fac73a6fc08f71ca500aa9d00962caab7a2780cb94c209b1cd43151f3248dd344bc9898b7780950a10211d73aa0ba20d89b01b36623ed8aae48845e1d7372f12b9a692b3d525263dfa12b3f312f91b5802d3b3380e58be6a92a70e77cd6134103496dc3e9236ff17cb0ebb04a1783379baa0a3c54cf1c5eb1b4afcd9a7042c50d6405b1b610a9429aafe61a5423055af9f61d3617be60bb59ee8019e72123069614e738a46703af5bf25d31ac4f1357832b1232cbb9325e522e79571a1d226397e407e4b08b44082e71e984e463747a230bed934127e892fba29b88857606983a60b9425008117ce17d20c82b6171165e940530254f2b0cb4e5c235dce373fe1450ee6457da59c331b17f8d4b5e0bab25aac789c04acffb957724783d00dd24eec3375f97ad838ac0c261789cd3afcd68b2d53c0c9bf944f094bf0875c0f08c161d3618c774304ab25563981974ca2e13b5bbdd210ec10ba39c64635c9025b9610b623c2f12a768e03163d75315c7097782b69c44b3a0c33a552228c6001c5ce194346a80824627b974d2c64fba994d2c62f8babac47c51dc100c54789f737c61b9b3420469b11d110dad9010c6c67ead2329d3b4c665ac528041bfd028612c608f87f3ab74b6b68309317e1c0ee5662f8dca46c26039e2dcb1fe8c42cff0057d4bb3e4ab3bce13c142e589592c0850e117cabb2cac88431461a5e6743695e096099a8249e22f4033c15e9266cb00a9a36103ac473123e95d373b0dc92cbdf6b2b173b07a3771456d283c758ab963811e5168694cc20e64e8a677e05e3915c4d93c8531b75d430b3709753f899b1c45434be196a3fbe5149dda2ac0912afac619b4a45f3df262f7d617322a9e8221a79f2319e6ac59034c80b3214953419a191b0e4a25247bfaa0defa001d5529b1cbb9e63ac03768404645bb8ac7ce25687be70796bdf516b76039f7b689ce6c3f569a04c52875ecdc9fbc97447e0160e75a89215aa263091e7cb5534a97660cc8515ed61d9b624950c089d9aa647f787a8ed7c89216694a83c56cf278fa94340d790015b914d09ba91e10ac5b7ba95792bfe779966ebc07ac6916fe1aa4bce56cbaf506563319c5a4c4344344b472226f59b7fbe7982c08afe9a60a80c446b8b341eac220fa8a664b6b1a0df72684b67bf2032d75f5aafff7cc724acf3f1051ec3cc4ce8768fa9ab51f960f3293a1fc527686570da34404b5681967258799fa26f22179e18221f4babc2b7c46601ab7ceca1a345027d44783e7d6c511615b108c4197bc0d9ee49c91621074a907ab292d4575abad75a19f10c2a493af902252bba57348dc33fdab3217778429680b4f352b52445eb662101dd22ddd211f314577cb23bc47c7176942c5cba072996c048408a5dd795907bb2e2f49acd0e75a93cc4f7938136d7c26da0691c08733e8138caed6c8cb116b900869f9fba9f5823b20626980ea86e6f487af758830c787bb1bbd8de024be9765dd04b969dc21589312e709cd6780c9a38a8207fbbe74f220c3c33e2a127588b64e3170999d3a77c8f67eec947cb69649dc64010a3119c9030e1fd0530cf5c3b73b631917719d0983ad0a06d2963741289a282a717d7487acb30354fc74b005ba01101a1c8b52c130a00339bff4f480a4e890030a709b28082d3c501b2aa2d14fbef9e429f8cfb50e84c327ba02edb7f6abdde459896eac77b5d8c7d7cabe482c88cdc80345768e4cb54d17aebf2947b07c716dde8da26e0b7114f85dfd29df7d92dda83e6b2ef4cce08c9134563063068a196d7b1a1a13623e48ae12528e" +}, +{ + "dz" : "b12f6fd965ea9c5b947db80fc60c83d5e232dca82e7263027c19bd62e5a6ff550f6aa3e88f7fa8a96067f8cdaeceeac90c2d0b5e277e56e9c405ec9420c30252", + "pk" : "944633d5f98af3845ca7c37f1be75a52410da5d2bf9d102305eace09009e6ea21b6c543a25032612492b58247f13f01c6ebb27fd469dcfc83ac93071d3368fa128a4c71475ac1817a8b1744c9a2085e54ebb8455bec286dee50cbce87ebb0bafc32341e877aba7a5ac10dc99b65687aa53cdf2585976a06bef586e8993953d5a3cfad8a7593349f9c31010e6becd32cf6ec70f4ef88b1ab955a5d6aac2a877323181668a2c731726236c4c1f77768ed06a7358744c91c690029c4c747603289874032fe6730d96392805e10b7a50a6b849985083caf8d64c1fc257747613b9e6c85e455ace3755ca9034089162d96346e3f0cdde0a81f6a7727babab5f1401dc1832bc175e3576b36747101ccac305d28ac5386ea92447f483408aea6ab22c1027b99b9f14a1b6a67a24fccfd5f52295dc11995b9503d76c7d0ba51abac76777b960c45ce8dcc24ff6031da9a99174be42a381654b5c9697b13188a38c278d94f801a2b94685acb0935074c06272e0ba87b6214f717c01d9508d77535e444b5a2b461d02acb855d7309b8ac6b7731bab6626921160e1a35d0bf14deeb922d770be063198d5a72de076216bb366a0889773bbcdef5872934a894c7664f568ac7f1cb5bc72587767025a271db13a0ce44697aa4c0dba80a730c0c1c2146b36a50d23926df520ab3460b18687921de988c2a7c97dabacc5aa849068ad76f10b361b9a2d1436bd88c962ec724dc15a6583ca8a41704f3946da465042b808f2513b65a5009da5b44125308142478ad82ac64940164c24a599c96eb69ee5e4bef1e45066e2cab719b57fbcc03c1985472cad16a2699e4939b2e2850c1b24e8049a41362b2b908e52e2a9f7808d06a6298e059bbe1c5a87a8610a06af0262bc61390f90d962ec95bcc907c850721778a947677a226c0482b5704e7e0176f1e28e27150ad84093ae862682b4a74e8a7d330c4c4e144c3a39c3a3da3c75873dbaca4880c2940ce30ed10c395805c0bc043cd2861b2e9c0da1b59474f8c492024cecdc7676d4b8c4b3311096270d29057d05cba6494b6aa07379b73bdfac9a561a8ffdd3a43c5877d85749db9c8379abb29f7567fa1cc57b09c35e7b6ff3f735cc18473049ba2d5837edd8176531b67e04a509ba811a9467c633b962e8392d065a03865658913f494501fe9c0a6a649dc8f3256b6274cb6235b0cb278132676d028a24e07595f56c4727a7b11830c1c9840c002db53b6198444e5b63be4c46be9548bf4e1598ea6371686c63da774270b82c95f0c9a12b5c8f9a591ec50971d897b3c1c4e0701da5e26be2760ac99b481151abd2a20ba343bf46eca8699487d14a9667565ca4e30eae468ac5e6cae54b4adcd5acd74812ebc3b4066021b0cc890099b911553b95c794643a97f99a512ce874f10a3c250a513c005a70605429f5943600cfb9e4b2c5e72c821149d9c2c554c43d9bdb271806ae8b58506571c061240b6e7967417542334773178424d46122c7212e0ba7b5bf4388e8f4a3f60caeff712c1e3773fe51b357584a917bc3e4fb950c442ae17abeffe262a4a6550576b6e8297ba723943ae3bf60971b9b86cf952c806fecbe937c7b15c91c9e438ebee95e51d209e60105bc43be345167ac92492bba9549807361a06f525380f5f19f7d1bb926cb1c2fa726cf371174caad5034037d07ae2f305f4ba52f9415b0c624398b936333d68625f533d7da20d62507768a73f579ae71b2193f52a214b30921dc121b6c94042b386f52a202794bab835a9391ccbdbab2ddd94b3b04acf71a12de67cd24d1a85e7330dd36bbb6b387acb6bad3a59c1d292fc24aa6045c8c34ea4771b8137537b644997eb45bc2ef2a1165b308d3c926a0d23d09e749a142493a99ab1c3a80a87c3003990956729ec1c6c60a47a16f495813cb75c995aeaa481875830f1e906fd6eb993a8b3365189d1b50627466161451a21ee45397971d8f56634d90cd0e136c9d82729f8a76c61298a1a240f611824173abfb52ac1aa4bed85b4b18939988895075e888ac0c519ec75ebf693d3903560445414ed3bb3d262074981524e361efe44945b14daccc62e2c335ec40bb4453cae2524229571eceb64a25026b3e1ca249c127aacc08cde4203ebbcb6fb427379097fd222b4e24cb9cd47381c6b780553dd196bfc6c356f031eeed6c85b57be19afc39dd1f929bbb2d627f5f19db", + "sk" : "dc0009fa7c1c6bcc6a0164044607925524ccba9a8c5986419805c924374838a2764fea94d7db8cdae57360510aa9da6b61134d767b14cc87a2aee90a68c10ce92a41bf8144e97c73e2b730f15673165a5647ca4d536bacf780a3e33a224f67b58258b3718bc184534b8436c1162bcea0b5c6599c00c262c34283b5bef25a1620ab60410c9ff0b21cac43cf0a68ab784a1110c183e06984596712560c087aaa05b67be9d6bd9520a486750e18a14ac0796ab1e9c33629bd1375316be248f06295ffc665d8d9bdb701c0447b33252360377611b04a30812b0e2d003cd1365f122104e71b8f52256976b6415ca0b1e2713214527515d37eca3c466a9b11fef107577caeb5e17e33aa0c9c4a71c7ba9b4813b3413ba65887c4fbea22e80251e3f727d2b7b0128555be6965cf704f9409b57b939aa2612d1d7241adb88eab14926a3718a483ba06a604d72591bb0377d53a31b8810ad8f70a8a2757ddb44ff1b02f557b9b61eb5a33c481f4b25ae00b1389b93437b5cde202ba6282912a095f19255c7b7bc136072ee3e7ca4c6800c415a2135871313bbdd47338ceaa715ab7450293a984e3805141b1185a84bd867202ab34b0213f917728176b5edee0a0904bc29aa74880c8618ee862c326c37152b325b5cbed5c679268aad2c903cfb6a5691912fc0508e23a8e88957f89d79e93b91da85742ede6ac13f0aa15d76b9952c1f5058a3ef0b453691ee45943b7564adcec64d4a02389d3b2f255553e440203605a0f7a192ba417ea54ad6eb347ae52250c5a2bd59c46bf750d60372eaed87c8bf11c44e65fb8db1017411776b161551a9d29212e98cc9c6c735ff8100267296db77b2425b6319a3b6ed5998a6426125cfa78167c0a6ea6c6f8100f7a19628c325b4ef4b29ba97297258565dc5da1042f80c7c634140a2cf93d2c19973506cb6b84c67e32c0a7d718b7d86265a76fe1417bdaa1c8d56a1748016c4b9ac886736a8fb3cfa2693d4a443309dcc003f227f1586498c0cea3d6853e5c07c66ab02943cf9cc791fd2289ab7a1a13c7b3d3a0b990e32d747c2588eb54018c1d25e86cb4d84538da8752248c04353cea97c534801eb223c877682d2dc50284f932095bb2e55b031a144f8f646aad45935b8c947b37b19b99092a0b636d0962d93053e147030187954614ae54caa88eb3736c5745d2d5bdbc462389f97d72f128ab4b5bab3a7aa9e1588452c240774ca5783f56b01824f007d1946d0414a1a722c32154598f3682f3e24aa5c80167956ccafc84b6c343986729e7d03c87f418482b56963243fa67cefda9b221253753a004bccc4d156817bcc9b8e7332128b38c6f6625ced3713c51a3ee137d37785a35d88b7a2b4daae5b356e07bf6ea7a67b5763b04a2944475a5323002b30a6680c9eb08b5954347824a2ae17a29c1a69523ca73bbc9403c35c3b2c74affca1864e24556b90162d07a95e138ea80469d021e35a1770a1c3a5185258cc9659d10054f814ecfbb0937233c3f322e77d3821e9ab61033c24fea260a4b8b3004592c50c68d41b72a67936598a177a6aec3163bc3dc9872415e1f60ac07640b9180a20500bced23add93752d586915a2c448301449e024967159e4f278c674b0313d00dd69cc819c354f5722537dc4dacf29f58b46579b917ba38b2807978f1569df299246a6c23b1e92907f540ca9c27d2393b0481cc10e47d3246cdd599312af942a38cb8ff936e3b64743a6b22a7e96925c863d82b963fb909ef439ff687544b53937c8110399c1dc37c66c987124aa56f9b8c8ec0501dc170252aba325a5a70bc134a2e73c90ecb5cecd373820a34eb706bcdd25f95b3cc9c035a4f1659ca5252a5a21d895cabba090c5115028a079bd81a3c948201b6f9981fb45e73600b2475578d08a8218a9d832ca974d992d13984664057fea0771a0c125b16b9a2d33b72d2478250a4cb9a34a1b3ceddba53d1a4905332217875797ab6248c6b97052678317a99716376b851204cf24fe743782c88ca93b90da03c3e54321ed9500af39b9bf2f7856b13604013a7f502b4c60049b1a03e91292c40d487cc9673e8bb150cd84b11c83493dc0ca1d5568f532af3e54c8166b5b180a6e253840012b7a5eb4f05d53f3bcc5c9414136a70057037c7b88266bac70e4c01b0944633d5f98af3845ca7c37f1be75a52410da5d2bf9d102305eace09009e6ea21b6c543a25032612492b58247f13f01c6ebb27fd469dcfc83ac93071d3368fa128a4c71475ac1817a8b1744c9a2085e54ebb8455bec286dee50cbce87ebb0bafc32341e877aba7a5ac10dc99b65687aa53cdf2585976a06bef586e8993953d5a3cfad8a7593349f9c31010e6becd32cf6ec70f4ef88b1ab955a5d6aac2a877323181668a2c731726236c4c1f77768ed06a7358744c91c690029c4c747603289874032fe6730d96392805e10b7a50a6b849985083caf8d64c1fc257747613b9e6c85e455ace3755ca9034089162d96346e3f0cdde0a81f6a7727babab5f1401dc1832bc175e3576b36747101ccac305d28ac5386ea92447f483408aea6ab22c1027b99b9f14a1b6a67a24fccfd5f52295dc11995b9503d76c7d0ba51abac76777b960c45ce8dcc24ff6031da9a99174be42a381654b5c9697b13188a38c278d94f801a2b94685acb0935074c06272e0ba87b6214f717c01d9508d77535e444b5a2b461d02acb855d7309b8ac6b7731bab6626921160e1a35d0bf14deeb922d770be063198d5a72de076216bb366a0889773bbcdef5872934a894c7664f568ac7f1cb5bc72587767025a271db13a0ce44697aa4c0dba80a730c0c1c2146b36a50d23926df520ab3460b18687921de988c2a7c97dabacc5aa849068ad76f10b361b9a2d1436bd88c962ec724dc15a6583ca8a41704f3946da465042b808f2513b65a5009da5b44125308142478ad82ac64940164c24a599c96eb69ee5e4bef1e45066e2cab719b57fbcc03c1985472cad16a2699e4939b2e2850c1b24e8049a41362b2b908e52e2a9f7808d06a6298e059bbe1c5a87a8610a06af0262bc61390f90d962ec95bcc907c850721778a947677a226c0482b5704e7e0176f1e28e27150ad84093ae862682b4a74e8a7d330c4c4e144c3a39c3a3da3c75873dbaca4880c2940ce30ed10c395805c0bc043cd2861b2e9c0da1b59474f8c492024cecdc7676d4b8c4b3311096270d29057d05cba6494b6aa07379b73bdfac9a561a8ffdd3a43c5877d85749db9c8379abb29f7567fa1cc57b09c35e7b6ff3f735cc18473049ba2d5837edd8176531b67e04a509ba811a9467c633b962e8392d065a03865658913f494501fe9c0a6a649dc8f3256b6274cb6235b0cb278132676d028a24e07595f56c4727a7b11830c1c9840c002db53b6198444e5b63be4c46be9548bf4e1598ea6371686c63da774270b82c95f0c9a12b5c8f9a591ec50971d897b3c1c4e0701da5e26be2760ac99b481151abd2a20ba343bf46eca8699487d14a9667565ca4e30eae468ac5e6cae54b4adcd5acd74812ebc3b4066021b0cc890099b911553b95c794643a97f99a512ce874f10a3c250a513c005a70605429f5943600cfb9e4b2c5e72c821149d9c2c554c43d9bdb271806ae8b58506571c061240b6e7967417542334773178424d46122c7212e0ba7b5bf4388e8f4a3f60caeff712c1e3773fe51b357584a917bc3e4fb950c442ae17abeffe262a4a6550576b6e8297ba723943ae3bf60971b9b86cf952c806fecbe937c7b15c91c9e438ebee95e51d209e60105bc43be345167ac92492bba9549807361a06f525380f5f19f7d1bb926cb1c2fa726cf371174caad5034037d07ae2f305f4ba52f9415b0c624398b936333d68625f533d7da20d62507768a73f579ae71b2193f52a214b30921dc121b6c94042b386f52a202794bab835a9391ccbdbab2ddd94b3b04acf71a12de67cd24d1a85e7330dd36bbb6b387acb6bad3a59c1d292fc24aa6045c8c34ea4771b8137537b644997eb45bc2ef2a1165b308d3c926a0d23d09e749a142493a99ab1c3a80a87c3003990956729ec1c6c60a47a16f495813cb75c995aeaa481875830f1e906fd6eb993a8b3365189d1b50627466161451a21ee45397971d8f56634d90cd0e136c9d82729f8a76c61298a1a240f611824173abfb52ac1aa4bed85b4b18939988895075e888ac0c519ec75ebf693d3903560445414ed3bb3d262074981524e361efe44945b14daccc62e2c335ec40bb4453cae2524229571eceb64a25026b3e1ca249c127aacc08cde4203ebbcb6fb427379097fd222b4e24cb9cd47381c6b780553dd196bfc6c356f031eeed6c85b57be19afc39dd1f929bbb2d627f5f19dba8f24545f5c1f2244d7712dce7596ce08146dae6a7f474daab4056da2d22c4ad0f6aa3e88f7fa8a96067f8cdaeceeac90c2d0b5e277e56e9c405ec9420c30252" +}, +{ + "dz" : "9f52af92ca165fdc38788f2b59ba02e01c8281ff7c1e60504688043a5fe814b04f3029e1be4e1c0258c3a22ff5b50b2674cc094ba7018da2a61569845c17d26f", + "pk" : "6d3b096a7383933c0cb6615824885499f79dc06b5e874203c3349b2c3b27b1f1012e52bce9968496c068b6e6c7244722621a1a44349314845b1d8831d9821eca386eb8fc254587be5dc529438485b3fac44af0613732509cf225f5c127a4056cd5e503eb742cf03154511969e7a743834708d71579e9ca4a4e281aeb177ef50cb0db826ddd17873e63a182e3b001f659ea3cc73cfaa5d7d7b5e7e9cdaae04c9944978dfb7ed34248d976190cdc0184930e25c6306312180a0b8758395d1febae95b22e0945c5fe265595a9ae91616cf9f35b588b7a02f66d8d49800c50017c7272bbebcffb10a16a5c8560130d96fb0c241a286ba949620ab83539b83d862ddce2507ec4b4bc4330c27517172b43bdf09a5e6a5fb684166800372663544859acbe07424705809587a08dc50fafabc1b2f9486ca6415266c502f7b998dcc947c7b5f5584cd34cc90a4c385f30a2cc051237c6a85d4a5571305a5182c970b9bc87268484f293464545f4c349e8b2ba3e5b4a5e7c42237c0e6e1b7722b04e3d02a27d0597d7169a49e340a778179a924a1d31c0c3d53bedb46868a62ae17847f130ad1478b8428b09fd71b028f1933803318af78103723ae7e1185801872f847753862f9f72323f980d6ba9744cb6c079341b02443b52e4becca891fffbc6084ab40bd17af7c6b2b21c09c170455c52c4c7093c44aabbb1a0c1d11b12070894f7649112f32a98d976c72291100a3bb4948f928771b063839a94a614227587d1a9bd25479bd8bd06e114894bca10814f0c516e1be41b81ccc6044a8f3654679df531c7220982760aa39a4e982ba3247b009d405c0b50969c694858889b4058089631c57dd1c5fe12acd5b27143d09a2d90c8abd8930d16769aa44a3927967b2975a329bce9599bfb170e02a7994fb90e0b1c7bc7db753c065cacf820b80c6c1d585624c93ff14a26afe6245ad8a6b2c082ec871dd1fb10c3acca1898520647b8ef8c0e45580c87f718eaf18ed4e97ea1516acca657bdfa16493115e6c90eb998cd31e6ca095066bc75057b2b71ac2a75711a7820984ae9306dea825c80f26a1ca6c686189c93550d931a1f73fc3ed0341ea703c033bb463c6260097c54bd17996a82abb0d32010cc53d81b7b7052b86abb6302b57d6a34895d09840b3b6a50c9962dc248edfcb328e94460d3c82819cbab49a79f742a86e85577ec995a025fde616fad52c4f092bd89286297d8a8912294faf7c959ca392cd40989c92b8229ad3ec91d352a6bb7d757d3709c5810b40157cc0fe006bfe843419b8a1d792d00c1505e0a63b39c7c2ca2c96f695426073ebd50283572bace67c01bb7b27b09be59e589bd60acca376a8630034cf87e9d49411648a1b05c329af92cb29942cb2369381c3ef761a02f8c905f963f0b08514a7c1302b4bac9f261fa37855b67250258c003e5bc9ad07035e667bcd6a537f35a0756bb2801a0aca56576d72f3a8c0c2f371e5aa036af3a987bb550ac06980bea73b938ce91715a4b19620a08be52695abcb3c833eca2824b60de483810857aba0a9292911c4167159b023989d061ba81c94df979917c72c8eaae518ab0e46ab8927b5b9db690bac6720667baf711a73952b033abaa59d5c4ccf676007044e26c2bb31b5aa2095f2da9724570cb04174e9ac174216c1390a687c60b6c396aa48ef849d19234f36886205b0b28250e7803502565523d0cc0bffb78efe64dc758cf3c93bef42103694b434c4819f82bbc42ab45ad827287a560ee43600b87443d8bc91ac5b15fab2701f05577c32678e06790808d4a6965c30a0915ac8fc7950b274c428a43650003beee2726bd31a09de14e892b54c2605269b8c22f146afe669dc9c4775d200aa9534af5612ea736b01543788b13c3fba608ae90aac0da9335e6c115fbb1d67938b86849d5087a87f3437ea29d7b899144fc3e739a4c079628597c618b554468f56cc6745ff6500d3118c55a8171e42b67ca43ca32135672b22286f78d0485b363d63a2ec737d2aa98ae602d3c485814d2c195db5d7bea8b3ae5470ff7a1e8225f82d565414c6b59379cc5b26155f682f6098795c52e3e8acfed87743737c1bee0ba875a95e9509d89f3667d741cb3aaa989378a2425a0e5f218c02763de4345a208c5bbe4949a506dcd5b01c5f8f4ec5f5bae6946c95ad7fa4e1e5f80354b5112d882796092029150d5d621", + "sk" : "d0f6234ea63d21038094ac3082f06f5dc2081b5a6083b00a59e5490266a351259927ecc2855c144a83871475277f89311b71436ca835797a1250945a9cf23e041a7020e0cc3ad5c719c9707a6b823b3083351451fa94a7258986c05421e8c98d6e0140a8c171c1116a5a6939dfc95308e8495a47c2aab4b4d30a663e005ca89273b3fa6bed9475bbfa3a6526673d2b4428f01a8041377dc04b9d21618ea05cd2988070c91e95f489b76225ac396de3562ba513b3f23b9809f86eedd7bf9a29a8cd856587eb558772bbe847c2e93497a226080df9567e3a6b22c513b1523c5977b1a1d573336869ef2389b37c3867a5121fc92a097c9640bc996e2845514b04f1b315eb0c7ce4a0b0b219b9c0846cb46c5668796d83759da3a28348f170c3042a86846b78ac7fa5e5c831c4bb953ccdf6821bfd674a8e775a17a4429a197c910b0163454ec3c286cf94ce7e9562f67797896927bcd1b07c1c1b62714a7261ae5d9180473120da730c5e3b8cf1b8b9d9aa54d5392d5c695bd84badf3e20ceda5bb15c1a1c231878d35267bb49571a2216b067ba7515b3cc2661bc8742c3a8616436d117a53e6c96474fb67f0332a261884adb452219b52f31545550b5520c48da1acca388bc35aa120e05433ea1c31b35113f9ec2828e6bf63dba38afb0ed144015c3bcfbf221af1954f5d95b02e3b3df2ea8cfaf09f152987e3db11aa112fb0270d69fc3ba8e26ac30556340bc630c60af699171dc4914daa5fbe81125941982a900a1155188a7a55962639408a2856f480fe22830305078c8785cb9591728a47b0043d0a987a498542f31a113ef0a2ed971a8fb2aea9b334e5354b901393c5a140b05a72e54c21c4860da23019edaa2d0b8680e4379a7813b07df36969e22ae2b4102132711a63171c8bb97f30a599552bb8b902cd9565ba1b0cad788ce92b85b7a468b8348094bac38980981797c80032376da288df3cac31f202f3c3279882b4124761d1c02075303f6f1401bc4b361dc156a417028e56a2822bc941c7aacf26667b100f9bc003398866e9d104f9090c46e23c1d249cfe4619059b38a9012db2d8833b9c96cd40945b83be73b16fe8e53f5e69612f488c7d0753856071882741d533adcc9ac1323513ef15bfae06761385a651994085ec4820e75e7694c5b2423cd12a3b0d06a7194b87055b973803899b4492ae8c6e006636e3a21ea9d872b13c9364e208e99c2c74965215d6290eb96a802a1c836c2819772e21457596982d72e6491651070f1cc7e6861d5a7a01bceabb0daa0692321e9f49bffd83a07caa9a15453831898df4505cf33899f4cc81ba7059d592690d784263074060155c4491130fb9159c09028ec559c4169faf663af83c8d82db07ab08213b1b97607ba0dd50962966683b014bf381be25da2ee32057bb55562a6197b3d6555570af1107ac025cc8ffcb3f4ca17ea33ab0cc792bc83b4674f0014e3808ea128f7e3cc01b4495a0b72846938d23a32eca110e47b17c7db043340a79f7d521407cb0da754b59f267721c63d46c5c4fc58d88f75426a00914dbb3e98246d1b2573bf59cd65222e5939c34b25856625916c28c9cdb82c5643bd13c9b8a634235f1badee54aa3180c1c2bae97828d8746affc737f5bda768ee34bf9fc17618164f59b689f094aef337ab0f56840dc569f20b313647b87c74154a4c6b79968b29627eb067d2918bed7a94d24163848830463a1088a60c49a7c3fe9579a58ca4277a8a75fa7c4a734c2917a98e540b5405a3699949fb66340b36c449b685a1b03896df118a73213bb404cf6daa413134ae2a5594de4c98789b3f5e93fe9a51395d22f72211429252489673cd7668d8cd48b733a472a2736b82ba3dbaa0757b89debf5883909c82b7ab523e2aa6d0156dc2ac8c9f6352f038e4ff045f7a81a0f026881a3890425180e9742cdd0c6a7129a163338ec0ab2ac4b7d80145053ab101ff05f771568a724cee02741a604c92b53485b617c8ed24ef14a2fc608c882c59d9be5717e444fe347b0cab7b07f4b5d405034c9baacae2c4e844046a95275738966eb87322479043ed7083cb2a60fea71019baf85d3866a5cc3a8b93f09260b5533819aa7b6cf0bcec07181b6659f469533b3419f32129fb33b2e8166aa8d10acb4f035d7e6226d3b096a7383933c0cb6615824885499f79dc06b5e874203c3349b2c3b27b1f1012e52bce9968496c068b6e6c7244722621a1a44349314845b1d8831d9821eca386eb8fc254587be5dc529438485b3fac44af0613732509cf225f5c127a4056cd5e503eb742cf03154511969e7a743834708d71579e9ca4a4e281aeb177ef50cb0db826ddd17873e63a182e3b001f659ea3cc73cfaa5d7d7b5e7e9cdaae04c9944978dfb7ed34248d976190cdc0184930e25c6306312180a0b8758395d1febae95b22e0945c5fe265595a9ae91616cf9f35b588b7a02f66d8d49800c50017c7272bbebcffb10a16a5c8560130d96fb0c241a286ba949620ab83539b83d862ddce2507ec4b4bc4330c27517172b43bdf09a5e6a5fb684166800372663544859acbe07424705809587a08dc50fafabc1b2f9486ca6415266c502f7b998dcc947c7b5f5584cd34cc90a4c385f30a2cc051237c6a85d4a5571305a5182c970b9bc87268484f293464545f4c349e8b2ba3e5b4a5e7c42237c0e6e1b7722b04e3d02a27d0597d7169a49e340a778179a924a1d31c0c3d53bedb46868a62ae17847f130ad1478b8428b09fd71b028f1933803318af78103723ae7e1185801872f847753862f9f72323f980d6ba9744cb6c079341b02443b52e4becca891fffbc6084ab40bd17af7c6b2b21c09c170455c52c4c7093c44aabbb1a0c1d11b12070894f7649112f32a98d976c72291100a3bb4948f928771b063839a94a614227587d1a9bd25479bd8bd06e114894bca10814f0c516e1be41b81ccc6044a8f3654679df531c7220982760aa39a4e982ba3247b009d405c0b50969c694858889b4058089631c57dd1c5fe12acd5b27143d09a2d90c8abd8930d16769aa44a3927967b2975a329bce9599bfb170e02a7994fb90e0b1c7bc7db753c065cacf820b80c6c1d585624c93ff14a26afe6245ad8a6b2c082ec871dd1fb10c3acca1898520647b8ef8c0e45580c87f718eaf18ed4e97ea1516acca657bdfa16493115e6c90eb998cd31e6ca095066bc75057b2b71ac2a75711a7820984ae9306dea825c80f26a1ca6c686189c93550d931a1f73fc3ed0341ea703c033bb463c6260097c54bd17996a82abb0d32010cc53d81b7b7052b86abb6302b57d6a34895d09840b3b6a50c9962dc248edfcb328e94460d3c82819cbab49a79f742a86e85577ec995a025fde616fad52c4f092bd89286297d8a8912294faf7c959ca392cd40989c92b8229ad3ec91d352a6bb7d757d3709c5810b40157cc0fe006bfe843419b8a1d792d00c1505e0a63b39c7c2ca2c96f695426073ebd50283572bace67c01bb7b27b09be59e589bd60acca376a8630034cf87e9d49411648a1b05c329af92cb29942cb2369381c3ef761a02f8c905f963f0b08514a7c1302b4bac9f261fa37855b67250258c003e5bc9ad07035e667bcd6a537f35a0756bb2801a0aca56576d72f3a8c0c2f371e5aa036af3a987bb550ac06980bea73b938ce91715a4b19620a08be52695abcb3c833eca2824b60de483810857aba0a9292911c4167159b023989d061ba81c94df979917c72c8eaae518ab0e46ab8927b5b9db690bac6720667baf711a73952b033abaa59d5c4ccf676007044e26c2bb31b5aa2095f2da9724570cb04174e9ac174216c1390a687c60b6c396aa48ef849d19234f36886205b0b28250e7803502565523d0cc0bffb78efe64dc758cf3c93bef42103694b434c4819f82bbc42ab45ad827287a560ee43600b87443d8bc91ac5b15fab2701f05577c32678e06790808d4a6965c30a0915ac8fc7950b274c428a43650003beee2726bd31a09de14e892b54c2605269b8c22f146afe669dc9c4775d200aa9534af5612ea736b01543788b13c3fba608ae90aac0da9335e6c115fbb1d67938b86849d5087a87f3437ea29d7b899144fc3e739a4c079628597c618b554468f56cc6745ff6500d3118c55a8171e42b67ca43ca32135672b22286f78d0485b363d63a2ec737d2aa98ae602d3c485814d2c195db5d7bea8b3ae5470ff7a1e8225f82d565414c6b59379cc5b26155f682f6098795c52e3e8acfed87743737c1bee0ba875a95e9509d89f3667d741cb3aaa989378a2425a0e5f218c02763de4345a208c5bbe4949a506dcd5b01c5f8f4ec5f5bae6946c95ad7fa4e1e5f80354b5112d882796092029150d5d6211c931f81fc67b2316f99db7f55d799363828f7de74b5e979fd7620c7449132d44f3029e1be4e1c0258c3a22ff5b50b2674cc094ba7018da2a61569845c17d26f" +}, +{ + "dz" : "851ea90fd3854cbf28fe39fb81f68e4b14345cf0d6eee7ec4ce772513df8410d1c0ec046899a777655233e4e1b5ca44e9afbdc67964bfd5d5e3dbb45e60d03cf", + "pk" : "cd22ca9cea98bcd401164c349b35c8b36424f294b11ec7c7d0a3953fec20dbb283ef99a3452496d9b86513e33633765c10b45c6612bfcf590f6036a711eb3dead00067649eedd14491716caed40a3db26d7b00c6e8396858c3916397166d24370b033ee54c3d3b85b5382b1f3f1220325aa2f804bba473cc70b15d443548491416bc1698a5a9c39dea2ba59171f35569ed6946621c1b3647598becbcbbc72a0781c77baa5ba128b1b7053b2de9c122b8790125c50e003a119964aa48392a96b01d7675af541b46b4369b10c38a2c68ee5425c5f6293c2255a19a7cc2607774d342af773a22c3943a9b411bd69a92e1c756993a1a392698a93d5f4772c374b549c15a0bd636be908641a7b8ed758e3c341292598b82a7976f45ae4fb0bc2af0352d92751a6a5e5015444d3b82cef064d32c3bef9b2292571092360e1806b5e5a892586029ab421ed247afff408f7fbc9b5cab930a6896b1250ab1c58ac4231fd6d0bd9b990b649028e4c28e435093b36462e28940fd2723e7bc20e59914e1c812bb3aa912318f15472a64b75c12ba361b2843751611183870a6028496195cd5d219698a89dbcb2c1c06ab2bd5937c1cb5a2da7774bc3facfaa028829f3c3c9bd6c584eec882ccf3ae1b00b1357692ed377f09712a30fbc73f17c0bc462a88e64de262c24e7a7f7c784dbc5b615ad57e58484db23363433a4680126c2eb5b9152c162e3277c0bc4da9693b22daac51a1c6107242b7428ac3f21f2c3968810435f9aabf3c65b7db7b37361218b49b9c76695b53c9a227963ccc1b60d447b3b7d15765bab6b3b73585f26c2f0862c927b6f23624f360a4f6c537b09563adf7a9616a4dba03732c707fed845c35c660b5317ef652055843cbc28ac501dcb493eb5d6bd5c322ea2f2a8b61418b9788482f51b8135f4c1f1173895057ad3218387d527133890fa3a9425d73ce03e1879b85a5b120285b823501487d5c555ed2b7bfac82762b9262d3d4b3b64736497899a768903750bff4a82e6a0097f3c230dba5bcb0ac95006852bf60480d039d1fca9fb758b5562a384160acd9c489a3b4bdbcd96989c57eb7a411ea3540ada882aa567fbb340b518477839925577c780953bafd0cbe2803626b89cf1c3b3056c4bd78c88818211fc836765fe813c7b18e5dc9725978ccd9ea8c7e1710ddeb883ad93e2cc987024b817c30908ab1ba7a658399dc931a4ba4fca5a10398289e9718e906336b148c328c2930b843cd4ca0d4735b633618e8c1c327b29596c24bab053867747883231f11005ed6987679544b51c45d42cc209b7061a91a0c82a92c943c85c149b79c1a190716c03f156d3c22ad27e7b8b87962c8c5421d3b01c7eb2220452b22d813d2180e7a38be15b6976aec7659d25b60d3c780fa75c3654d7f9b6de0d33c8c28c97b6b95bc8c2cb517b497f73a98c41a64f312fff48fcda7b07e86a8136c05720a8740d866bc024ca1e22d43f6470c8a38a7301b3ce74585e6ab8b899b13ea39c163ae79e764e0b846fcd57029a73708091f053212c6f93f1173a854b26d7e49bfae38046e43193b98460d171fb48283e736c7a1651deee6272387cf65ac876feb4292bbbc9200981299c9bff13690d6c2017bbd3e257700a111fefa33072ccc8e952263e4867590c79b558187e3441a930964aa3ec0441e91e7ad198cb6e8959a35051ddd972a43a020d0f968eaa8696b9686dab01b9f9b8095522a7b411d486444b16ac4fee7b245f50ba1a26d81457b802bba966ac8eb300cd92773ca26908a91a2e23b21b0116dfcaaa5f4a57514dc2ad736cc788904c29050389b80cafb0d71b131b567551f6a2e16390c55234e5ad50080ea6268047618b333a49795b4233bd07530a89c275bdabc4ec99d84a812d9e20e2c27072196138386ba42cc4998314905e070ecab69f2d12aa204a32ad28658da3fab69223521b81461312cf88700a49077914af3c28a2f544d608209e24cccfeb46ae13bb90e8b86a4bc85d5f41a9ada7a957ca8763acad6713623ec20e2f199b1270966432bf2b8cacec65776d8a63a471cb4a7c891a01bc92c8c28719c3ff9a8a7a350d9454729d2ce932982e94bbf30b298b3353ca6c459ee5017fcb724ff430a9348b9fb46abc86374b245668ac71096501a7f3313823c5749e01d0e40444111bebc0a6858891224b08cfc8e74c41084fd5c03c102480537", + "sk" : "2b8c2ea5542d9e3b90c417523f690109007c5aa97940102ce5ec7bc9bb471726b202d02e4f871062c281d2a095c4cac14d6b9ade99421d2599fb696942f6b74d349bc23a2099f687f1a3b1db3781095615a341862246b29500cf6c3828085c8f72c303ebb9773dd90c37d1001bd70e1ba70ab99cc2440a6d8b841314e84c71718c1ff802897abde7694d49e416090527a600b2ab4578a378b0cd9b52308403ce5c5ad198bcc6dc0b3d5bba010ab9d5c18ca3210111654b47fa504cc2b34ebab1a9e328fb963b22491d5dcb13b5f46b3f43669101483e95aa0bfc83cbfbbc6656269d900138dbc252206fe781b007b3c2a26740643b0b9e6cba3d83a3546b112baa3113fc5ce4e94dce8abb1180564c6cce9583a703da022d20a14489426e6693ba2710aea52761173f5f5379ca711df6972e7264b3c8d2805fb08880a6420eaa1a060476e792562cd3cb8a768d2ba32402b2659330b7970a1ad3782d670486e4e73a6cf47938549a8246991d205f4a4bbb8f977ddb3c8f724110ced267ce681e1240ae0c9674c4e20e4d82194a1bb835e1b56166cac3714e3b42a60092bd746665e253933d6786dfe6b95eb9a98f7c299fa9993d803755e40ef80aa7de893948b5bd65366288a7000c6a5c3b7c5b00d7102ea95f490bcda8d6ab38520c30e231a449a69bec79cfb80dada50739f83a85c624a1458c135875a803041f186fb6c50d2c0b657b59377bd2aeccb343b56a7a5dd2466fd902d5b5bd3cd3557fa31465fa8cf9ccabd05a24ad290988355ee1318789fc81e4d112cc797dc5e087c0ca19d5e8b85c57463f456868eb585a188a27e51858f8cc8c24a9a1b47b38934e07b92529c0722b98ae0c3ba8d7f329e19c0f6e8092acc7c617fa145c37bb477501c1919b26b041aa6641362a480397c5e0441439545deb6b5c47d01539337f523ca078c6543ed9984aac812638a00fe930a07b56e6859a20f0ce54617ee6b8395867319930583309a67530aedf8018b602536d33c98f81b7a7b6a252a00073443c9ff4bdfdd87b3513536d93c908188516749a28a92a410919a2c803196b1e4a533cf8133bf97c2f49fbbb1cd19e2f3838f3d05fc8e5c11cc602ebe5a2a5187ff2a74025a7af16075fdf88374624305c191116c9bf59dccf9fe89e86f007a6e3c0b0dba7333bc4c9733214bb233e05c8a033ae93e85bfbdbafe31260e8f7a5a1abc9da303fadc8697a264012900fd1b713f8da7ac5ca8f2206be63c31c5fe3c6f6188deaa31d89502aac2ac5052b982e3a75b385ad353c9c035c862cd5a6290076c959b11e6a4832793378b9828b0236e016bf6817511dd9a86022cce5182f660013f8b2a036a993c90740a6a5ae2779724a60b872e5bf76c78a6d95997397bf1092b2827924db015caa204bf23710da941e0d3a1a05458ee4386404aa5ec1cbb108925ac4703048a09f37814c78e63fc4b31f2341c559222a6db43d50bc12d8c88962cb7e9149c009414c519721b63970953524009b8be2ba1644c787edfa0d9f9c0eae722037f0546fc96cb333a062206436dc21f6806099bb5fa43879e2d433c9e1be8b073076b1034d062ad0348e6213176960a90b7ab4dea8adb0ba41c73b2c4be4c0a06200e3a975042346b52244ef5334c98189247092a19092e8833ad43096e4b47c50668356ec0bc5ac212e8a1972e40e7029561ad20e33ba29f97cba0e3153b338a09841bb6eab67fce41a86265d6a2899d1b7bf4416ad1ac211f7969914930da09844a2603989998542ea9ec24c0a5d8b01fec38c33e84d51b93c360a4d98d439c593063a3747fb9c2eb16439ab7035490a99793939445ccd33c4aa2974aacb21873a7659a98bb67668ae47548ab98b336e2103323522dcec9b59c80ef0e5c935b697c0ac85da18766b39cc1e8c1319567b9560109c2c2f66a9ae528a889f500e8e11b9d548690750c54ac1785bf998be78cc935bcce9e8185efa9f009791d4a687f131309a0c8d51105d2b650e295abb3ec29f1b421063148638626019525c844974f12a9add84c72e324ea3698bde2b33de8770aa65674f43b861e28e53e54df35040a4a91ac6cc4867635ccb91680d943a4782af82d17c2fc8a3f5eb2af0a1525a29af94d2cf7c8631f95862fce1a401e175de0c3c184072444c10cd22ca9cea98bcd401164c349b35c8b36424f294b11ec7c7d0a3953fec20dbb283ef99a3452496d9b86513e33633765c10b45c6612bfcf590f6036a711eb3dead00067649eedd14491716caed40a3db26d7b00c6e8396858c3916397166d24370b033ee54c3d3b85b5382b1f3f1220325aa2f804bba473cc70b15d443548491416bc1698a5a9c39dea2ba59171f35569ed6946621c1b3647598becbcbbc72a0781c77baa5ba128b1b7053b2de9c122b8790125c50e003a119964aa48392a96b01d7675af541b46b4369b10c38a2c68ee5425c5f6293c2255a19a7cc2607774d342af773a22c3943a9b411bd69a92e1c756993a1a392698a93d5f4772c374b549c15a0bd636be908641a7b8ed758e3c341292598b82a7976f45ae4fb0bc2af0352d92751a6a5e5015444d3b82cef064d32c3bef9b2292571092360e1806b5e5a892586029ab421ed247afff408f7fbc9b5cab930a6896b1250ab1c58ac4231fd6d0bd9b990b649028e4c28e435093b36462e28940fd2723e7bc20e59914e1c812bb3aa912318f15472a64b75c12ba361b2843751611183870a6028496195cd5d219698a89dbcb2c1c06ab2bd5937c1cb5a2da7774bc3facfaa028829f3c3c9bd6c584eec882ccf3ae1b00b1357692ed377f09712a30fbc73f17c0bc462a88e64de262c24e7a7f7c784dbc5b615ad57e58484db23363433a4680126c2eb5b9152c162e3277c0bc4da9693b22daac51a1c6107242b7428ac3f21f2c3968810435f9aabf3c65b7db7b37361218b49b9c76695b53c9a227963ccc1b60d447b3b7d15765bab6b3b73585f26c2f0862c927b6f23624f360a4f6c537b09563adf7a9616a4dba03732c707fed845c35c660b5317ef652055843cbc28ac501dcb493eb5d6bd5c322ea2f2a8b61418b9788482f51b8135f4c1f1173895057ad3218387d527133890fa3a9425d73ce03e1879b85a5b120285b823501487d5c555ed2b7bfac82762b9262d3d4b3b64736497899a768903750bff4a82e6a0097f3c230dba5bcb0ac95006852bf60480d039d1fca9fb758b5562a384160acd9c489a3b4bdbcd96989c57eb7a411ea3540ada882aa567fbb340b518477839925577c780953bafd0cbe2803626b89cf1c3b3056c4bd78c88818211fc836765fe813c7b18e5dc9725978ccd9ea8c7e1710ddeb883ad93e2cc987024b817c30908ab1ba7a658399dc931a4ba4fca5a10398289e9718e906336b148c328c2930b843cd4ca0d4735b633618e8c1c327b29596c24bab053867747883231f11005ed6987679544b51c45d42cc209b7061a91a0c82a92c943c85c149b79c1a190716c03f156d3c22ad27e7b8b87962c8c5421d3b01c7eb2220452b22d813d2180e7a38be15b6976aec7659d25b60d3c780fa75c3654d7f9b6de0d33c8c28c97b6b95bc8c2cb517b497f73a98c41a64f312fff48fcda7b07e86a8136c05720a8740d866bc024ca1e22d43f6470c8a38a7301b3ce74585e6ab8b899b13ea39c163ae79e764e0b846fcd57029a73708091f053212c6f93f1173a854b26d7e49bfae38046e43193b98460d171fb48283e736c7a1651deee6272387cf65ac876feb4292bbbc9200981299c9bff13690d6c2017bbd3e257700a111fefa33072ccc8e952263e4867590c79b558187e3441a930964aa3ec0441e91e7ad198cb6e8959a35051ddd972a43a020d0f968eaa8696b9686dab01b9f9b8095522a7b411d486444b16ac4fee7b245f50ba1a26d81457b802bba966ac8eb300cd92773ca26908a91a2e23b21b0116dfcaaa5f4a57514dc2ad736cc788904c29050389b80cafb0d71b131b567551f6a2e16390c55234e5ad50080ea6268047618b333a49795b4233bd07530a89c275bdabc4ec99d84a812d9e20e2c27072196138386ba42cc4998314905e070ecab69f2d12aa204a32ad28658da3fab69223521b81461312cf88700a49077914af3c28a2f544d608209e24cccfeb46ae13bb90e8b86a4bc85d5f41a9ada7a957ca8763acad6713623ec20e2f199b1270966432bf2b8cacec65776d8a63a471cb4a7c891a01bc92c8c28719c3ff9a8a7a350d9454729d2ce932982e94bbf30b298b3353ca6c459ee5017fcb724ff430a9348b9fb46abc86374b245668ac71096501a7f3313823c5749e01d0e40444111bebc0a6858891224b08cfc8e74c41084fd5c03c102480537c11d5e63a349785e242cc58bf790539d3adf4844176afb3ade1db843a9e6ae9f1c0ec046899a777655233e4e1b5ca44e9afbdc67964bfd5d5e3dbb45e60d03cf" +}, +{ + "dz" : "d304c9389cc973477f169788abcb9d511f843219d246a9b587822f422a70c2386590a2e5c7ed86cf2c5c2a898662bc9a81418720bbb632ef9cf0b845ed052d73", + "pk" : "17a1c1ca6b5b6bdabfebac339a5c121792056c508ff99588d292cbcc1760f1eccbf105281116a623c600e87b4231c2a94689133ca16b6d99796700b917262f4d776d10709a26123a5af9af5ac7455882caa4d220437271aa5c9e30877a3cb263f9048a483a826774c806941939c44274287b629b2bcba56f19e7aab2b8c6a3f72bbdf5820c774c48a151c381a5a75c27337c60c406cc1ae36a3eeb25d91521918a780d75a69f94aa4005771a5c22ed4466811834fbb238e6351fb055a70c32994442297f273752db6f03f445804c0cdb380f838c484c50250bb2c849e308d8f608ed942442e85bae7cadf4c6c3a49cc1cc107ff32154e61a99df1244f8f956c678ac4192aba83b5485f284f1510b816c26d16922412738db9796cf6023e558741c7ca293eb35fdd71f9175b838377fff3050d447a35e208027881406446061686621fab300755a15921be9d24b721a50976884c76ba928405ea9e6b7b357baa68674bf412f66f54a454c03fc2a64b1c1142bc56cc535911efa578c5a097d8301836cc641e078bdf1245e5359a0d7ce3a87012d199880a3ab5d61753488782b9734c26947b6c925e4fa6ca38475905a9f45a88221db62b762b4c884344cfc7d81e55fa34293dbf49e4e8bce0bb95408b32bec404a245c153042a3ebcbbd8598a3f9537e1403319a5cc6a006a37db5a3fc4960ddc5381a1b0b85657d41d085309b47c9e21a0641700a14150a0b3e00823e76c6bad867c6f3e6568eb840b9a9c4f4f45d35e733ae56377b9c2e008b66f9436b59320f3107aa43dc123bc2a89637637dd3a26ab0abf355c0fef642632523611a196e2402ac16c38562a0f8c65b6a0485dee1492ce2494b7230422abb2d705333d4c3f4e10b28d3c4b3266949ca4b95062e3d600caacc77655236181208c0dc4487063ccc528961661dc0e474bdd88faceb2ec448c1ea8a6f14206a33195e30fa4efd463b7f438ecf4ace66090bc268b532b251d783bb380380e12a79ac044bd72c0d9478018d98b6e4e36f234142347b919601521365665ed05111f39698c43f5b62c047f1ba861a91a1e29f6bf1b8ba376280db89feda41195a9564d17c73f4305d73cc6a606530179029e192352a5aa9e58f4df6c0c9d8846da4518192bc360544f734340c9b072cf399806906784073f622ac18c766de49a65df56b6ff99a6e896245c7aa5585723d1c6981a0ad2fc09115b8b8321941961959a8e40b37c24a66125810223dcfbaa093510bf0b9c631e65021d64bae6bbe847c7576826506f73493d19da8d47f07898d179697aec0a1df3cad227cbc83c33c6b72b450731d943041f79136d34c7f039558468c3de1e3021e509a2d898ec1245fa9a966ba457e5894691899521362b7f2d607578b01f230365a84c7ae1ba12ba53c1e216933a34e53e75e252c52087c615fd5ad705743494b10042b033468af0016274df94f2e65048e9a4595a4b541b082bcd96e6d90a44af778077007c069ac9673cb4a559820a2a9992c4500da89f5acc48a6bc9ac1922be9c211f36c468986d0704121193ad5e2732d693c650d867234c9c261525325157fdf94d89eb2da1949a627338c0d07b1cb9cb45d95b64b38a22b029bcb87c928c7c97984d760bb11b9666271aa914d3cbefd723d40928ede94af17516ef7a72c1fa978584111f8b0903c544dd7c81d94a3b8502cc08b21cd89c8fafb94d9eb57f9061a51e9aa6f3860ca3da018dec14d46981062b8ffd542747e7c83cf815989117ac14ba1654be4a92b396b01fab274a082609ed9c685f125fdc4611cc8c00167a8be5f28f0867397da186ae68a29701b4c1885235faa006d45d30b990d13c479fa5b1b76ca2406a46a0c42f9c63cccdd187f5e93b16f20bb86b5251b00842d28e58c86dbca41ad708a62c28846d0c983dd60dc4f5b018017fb1276eaf839a2898a8caec69f11037498c5a621c05cdc5bfc9ac9dde250a7c4c1531b813b3f84e70a43baa43950a9cacf07c9dc6c8b8c4a660aee6ca67159a00010a3414c87fd94ad197856d9940ddb47ad0d8700f635e58408a5af8213fe4636fcc594ee677b3f205e3552202ca8087922402d24ac4f42fdf5c99ba1356f14cbff297192a40b48abb531912b8f853a07bd241b19aa1effa784e5746905449b1e7436a79a28e3f712507e5bc0d026037001723d3443145bd066cebaaa3d000c9f0ca", + "sk" : "04a39f7840ad6e0c41084136f21609602a0a00cd8e0fe0158c1c3c27845ae6219abcfc95e72814a9776655841e46491a9ee342591133569123d6a09a54a8a253a49af9b27103d196873622ea93bd17da439e88226a333da9c525b856c7ed53593a002007235d84225fca027493168f9748c4384004d873abe1bba69212c7fc4ca89ec745ffac84b99c8707860ef798bc1e7c4f2f0344542054f3c46dc72a6f9d2b9303e6cf114040e136087b66af5fb47ec6a55c11c02acca23f306a7221f3c81470714a472ea822bd387cb29de9ce4bc96655d63e1811c93a740e148c994e149554b24edfcc6b4878c55570971d95576acb6943c6532cb2101b4468cf578a99348634836174792758c350651224a2d22647446f67a056180ab2afa34ba27a76933c9f4f3447c0ac6b605b144a2c9f2c626e8f434b4f35ccf894327c53a7dab9009d5a9a4e7bbf0e6a22d4f120b0c42ae4a7c0ab08774cf8a33e069d4860655cd4bff1940a22314356e8525213c351688b1a725a673918078031ec37080956973266811dd8ca275c9a75fcbb7b9891c26a3e343b36be5273ec946f42f70865bc48d6238ad42b616c11b708d3551d3b9dc61b653e06b1e6709bc115256687af92941b2fdcb99948184b025239c89052765b3d63b476c3a4df499564ec0749a03496040029da776d686dcf9984ac9354c2c69f2c3c8d3d5774201b7ac0254a891871847acca5099f89733fbe2a4979dcbc26f5c38efc5129e083f508441dc6c7eae73b1e7958671767968b180a3b34343cca94289fe0a8788b1cc8394c5710b9ba6fac1cf3147db32c9060a9cf2d056734031190b53ae17917e40907b61826527c277344c8bc475451414e00e3cfa6c15400cd5a6875c7b2820702706566a00460acbe58128e4c869095160fd0dc303ff8ca68a8947e3110c626c707da0344717297147aee5c39838c0f73ea57f70308601ba55e977bbd7b681e0c4c1cab818aa156eab24f74c2b66ffc8959c3617f92941f1c0935d89702c71f4d76c44402ab92310904504ab5f9a002c321b411bead73a819e02d006d8ac368bb89231af85a97bb6b0e23ac2ca869306e9239d808cb24312c48c4624c33537a8092f6e8c147900894f3838db9b0fc9419dffb6e78127e922042fe4a3c20e5c48e478bda52a2bb0a85612024ff5c92801ab1eda82de8aa6442249ade4b6bb9886015035d436a855cb495f6885f6d3084f498affdb17272e127bfc3bacd3831d06c20569b92fa9b90278707c995b2db1b63a423a997e37a244c763394b9b28b3d3538c981da0be1556696a7330fa83882c1b7da6668f1fa5841ea5a984b4f6f4869356682b9652a842859bf079238a83ee3d6b01610270488247c6b5e63cb1e4336773231b6dc6bbe6888345a0ab5cd27091442786f2313c16bab398356f1899554c69c4fc09c9a720fdd8bb1de03c80e5241d25559fd7568b321cbffec8f619403662a61c696ad90346bac979a7e446e41d5582acbb5e0f70aecc4330a550854e60eeb5290198825a1f01915bb094f10bc0bc29572430bf8cb8938a4c182698557ca49ba9b7494419640792c3fb31cce70aa2ed24830b65efb3218052c539f2539dca01532513717c7bc552179957671275327ff44a79a49b92f343a533baee4e06caff23d7857ca540a78f886be136b3506bb080ef563e8a3987c083b4b5cbef410ab20213af7807d3c52c58c852dd48c4060587ccf259f00f40816ea86edd276d1135eec70b990e5c11e97c470d97ce45a3a105a9da1ca768166c86c41474be92535f1bcf7539d09598e773aadf39a5b66ec79b360699e953bb0babde4f0c707b99ce6f5075217a054407072b084b7546bfa95ccedf1666746bfe74c674fdbc80edc35b4769f5fe08632aba9b5398e79dc45ad014a8ab539c157b672eb74757c6632e6c922202590a27dd1c82527a36287e2ab7a327a264abd300634226149513980b9dbca957c1560a6c32a20328b6926c843b53c635719f635edd90f3c5313ee1766563a7a9ab6b011462558b229fb913179a438f3b5b2f427adfbeb90f73a2ceb190cc6dc713b83afbd12a54b0c170cf973367b11db2cb3e5d880c169041732a276b93056e4632deb8606c276a0897116a0829482bbeec870f18c247309759971c4e1702117a1c1ca6b5b6bdabfebac339a5c121792056c508ff99588d292cbcc1760f1eccbf105281116a623c600e87b4231c2a94689133ca16b6d99796700b917262f4d776d10709a26123a5af9af5ac7455882caa4d220437271aa5c9e30877a3cb263f9048a483a826774c806941939c44274287b629b2bcba56f19e7aab2b8c6a3f72bbdf5820c774c48a151c381a5a75c27337c60c406cc1ae36a3eeb25d91521918a780d75a69f94aa4005771a5c22ed4466811834fbb238e6351fb055a70c32994442297f273752db6f03f445804c0cdb380f838c484c50250bb2c849e308d8f608ed942442e85bae7cadf4c6c3a49cc1cc107ff32154e61a99df1244f8f956c678ac4192aba83b5485f284f1510b816c26d16922412738db9796cf6023e558741c7ca293eb35fdd71f9175b838377fff3050d447a35e208027881406446061686621fab300755a15921be9d24b721a50976884c76ba928405ea9e6b7b357baa68674bf412f66f54a454c03fc2a64b1c1142bc56cc535911efa578c5a097d8301836cc641e078bdf1245e5359a0d7ce3a87012d199880a3ab5d61753488782b9734c26947b6c925e4fa6ca38475905a9f45a88221db62b762b4c884344cfc7d81e55fa34293dbf49e4e8bce0bb95408b32bec404a245c153042a3ebcbbd8598a3f9537e1403319a5cc6a006a37db5a3fc4960ddc5381a1b0b85657d41d085309b47c9e21a0641700a14150a0b3e00823e76c6bad867c6f3e6568eb840b9a9c4f4f45d35e733ae56377b9c2e008b66f9436b59320f3107aa43dc123bc2a89637637dd3a26ab0abf355c0fef642632523611a196e2402ac16c38562a0f8c65b6a0485dee1492ce2494b7230422abb2d705333d4c3f4e10b28d3c4b3266949ca4b95062e3d600caacc77655236181208c0dc4487063ccc528961661dc0e474bdd88faceb2ec448c1ea8a6f14206a33195e30fa4efd463b7f438ecf4ace66090bc268b532b251d783bb380380e12a79ac044bd72c0d9478018d98b6e4e36f234142347b919601521365665ed05111f39698c43f5b62c047f1ba861a91a1e29f6bf1b8ba376280db89feda41195a9564d17c73f4305d73cc6a606530179029e192352a5aa9e58f4df6c0c9d8846da4518192bc360544f734340c9b072cf399806906784073f622ac18c766de49a65df56b6ff99a6e896245c7aa5585723d1c6981a0ad2fc09115b8b8321941961959a8e40b37c24a66125810223dcfbaa093510bf0b9c631e65021d64bae6bbe847c7576826506f73493d19da8d47f07898d179697aec0a1df3cad227cbc83c33c6b72b450731d943041f79136d34c7f039558468c3de1e3021e509a2d898ec1245fa9a966ba457e5894691899521362b7f2d607578b01f230365a84c7ae1ba12ba53c1e216933a34e53e75e252c52087c615fd5ad705743494b10042b033468af0016274df94f2e65048e9a4595a4b541b082bcd96e6d90a44af778077007c069ac9673cb4a559820a2a9992c4500da89f5acc48a6bc9ac1922be9c211f36c468986d0704121193ad5e2732d693c650d867234c9c261525325157fdf94d89eb2da1949a627338c0d07b1cb9cb45d95b64b38a22b029bcb87c928c7c97984d760bb11b9666271aa914d3cbefd723d40928ede94af17516ef7a72c1fa978584111f8b0903c544dd7c81d94a3b8502cc08b21cd89c8fafb94d9eb57f9061a51e9aa6f3860ca3da018dec14d46981062b8ffd542747e7c83cf815989117ac14ba1654be4a92b396b01fab274a082609ed9c685f125fdc4611cc8c00167a8be5f28f0867397da186ae68a29701b4c1885235faa006d45d30b990d13c479fa5b1b76ca2406a46a0c42f9c63cccdd187f5e93b16f20bb86b5251b00842d28e58c86dbca41ad708a62c28846d0c983dd60dc4f5b018017fb1276eaf839a2898a8caec69f11037498c5a621c05cdc5bfc9ac9dde250a7c4c1531b813b3f84e70a43baa43950a9cacf07c9dc6c8b8c4a660aee6ca67159a00010a3414c87fd94ad197856d9940ddb47ad0d8700f635e58408a5af8213fe4636fcc594ee677b3f205e3552202ca8087922402d24ac4f42fdf5c99ba1356f14cbff297192a40b48abb531912b8f853a07bd241b19aa1effa784e5746905449b1e7436a79a28e3f712507e5bc0d026037001723d3443145bd066cebaaa3d000c9f0ca5955b9c5a4f2ca172535d5a32ef67d54f334bf726829082485a7b83d43b46b236590a2e5c7ed86cf2c5c2a898662bc9a81418720bbb632ef9cf0b845ed052d73" +}, +{ + "dz" : "89a6e3be304a3518fb82b18ca730f0b359cd6ba90664a493fb4f8edaf965b9c3b6591121e25d64010c25a18676033e1d7278ac5f2d0b43a31f3a4156ae710465", + "pk" : "9ea32a494182483627849169e2006e9306448025229ed2c14ff825a43976935a8a14b8448d6c4db642a1726823a2053f4f75951b80b47056bdae61ab68402d4aea6ead635f2262082d71c4ff5c78e6a6345a72505e23064dd773118ac985e49e4d88c64dd894322b0d2a712f0cccbb506436c3f0bed765ad0b193ea520580be4c12cd65f2406cbe1fc9281d37bed1988d7488f3925244454b82982c49fb522a2f83a7d131d1cc65cfc7179f8a043da781959a815b5e45f6e0b37269c84237424fcabbf4dc16a722cb171984e48864ef70c0fe14c69ee385f15eb7191249bbe3a3888c50fcde9302ac5aac6105503589b3748938eab5614d626c6a301599b623ada44f432bb18e359c7b223414a34945786468628c6579f9b004185cb7590e22f94e83de26c6a9b69702f704041da3ffbc8ce5fc2367a3a97c4b997bb06a01b8964a8534e2f713c289a0dc8c072dfe4a42f305785a99c0dc898d3104e0dcc62c0e600253c218f0511fcd94bf78497b03a08efea8bf7fc0e45d3545df2c6d708435414bc00e64c76a523bc0ac823fb56da247da4643fd9063748b23128c6ce4316bdcad4bafbca77b8ea6c10e54ad063a1433333252311f68c676ebac53aca8fd70b9404c1cf3c979ca0c492198a2f92294ee5ab4a2ed15100f20e5eb948916ca7bac7b28fdc904ab1911afc19a454af45e6a265a726340291bac80cee679e009c02254a6c6130227464b2fbf2a95661bed8b348ae9c759fa53a4b429c0b536fd6bc85d5c96233f90ca3057839a47b068855283487c90a8088e271a3e33f5ae5695d044c4d14ae8440bf03b318549600e39cb9d9d58ea2d2a5e3d08a11484801b8167d4c5afc20c56bf970a230231da8372eab0f5266686b4a3da0ccc6b57cc81aa29053142cf0f35cf0c83282893c25983ca06606cf255cc1b41add5947ff9322a4c23bee47cc49656a8581ab5a99a3797798ea77a1db18c39acc97e6342b8770550212718856398878900d6cc9a5963a71432e5678a12ce86257b0b32ee751eb181fff62ad98443f7d79cc4f85bbc67190a68504a24a3166c588ac7b40fed53318b8b452d1a738e59a2c82442feb013f9b2429b6c603f71619f386118327eaf0c13ea30fd620222af064c61aa8d9801d53192c61575e3448b265ea9987bcc84ca825943a4d51a9cbb5e76e4fe88cb6d92215f60b0941c46b89a746cc96c74cba7b097bfcf27533a46fcd928f49d670f85179e6b598ec595cf39c3554eb5f93ab9707d4a559069d24a4005cf28bfeab0bead80363ac608965141e252de510562ccb5fdf94c30da1247ddc4c80554d879b62d0b49eb3b21ebad10a50794545577be4eab070d30365dc9c34eaad1163b251b223e8ba45dcb77dcbab0a07fa635d8b841179a354304e0d249dde2319d85cb724245877a549ccd8230fac8721d82e8a2182e5cb63285ca8a0d049cc7160d7116d5c1c0127a9ae5fc808eee88e340a57a80964b21a353b08bd35da0dc1d7020d6cbe43f49547686546391d94b9a2b2d63b23fb2fb8c30f7ac371b3a80aae0470d93b610ba1681af1be2871a49419a23610843bf940804483dea0ad8d609500d8aa2426cbf0ca5aa353668a7151bb54c7c4e4ae3354c598cbac6e90949cf6b79a941c541c652351306f810494dc0ae743cedba7904d34c2e0b32b603606e33156bc750bbc477313219a97e184d695c701b2009aab8806709b8d376b9cb6a24f3b6d0a4157398c740d08809328aed069a52fe77cd68b9dac62cebe3649cd1b139fa84f6a2333ab702a30414425f50e25e41bfe9a2e277869e17c035652237889c37e3c86cde41c7585776d14682f3c0309a09c1ed43609b5b82e03508869a7f6b627c3710c58198ebe9100f433ac0df22d03934c1eaa10aa98b88c879fee60596a3ab29739b613ab741ad4518e6ba5edec190678b20e6544f469791c64629657b9b1c51eff1616e29a1b3bc25a55cc9c481995bbe68abbc383dcc02e4c8208ccfb57e052ae86017dfebcbd2165810151538e7a9af3a4c5364c02208428d2b98890923b7bb92d66a2907b5376906a61115c979d4b34670a91339008bb466928b30e807cbecb307becd228657bae78f5869c3463d1b73e09aa7f6274c7fd2a3a9cdb4160da310254462eba30dcdbb5c30542463266d790d0fd79c3c76f5da348753312e4949ff2955212edc46dfcf9e6c37a", + "sk" : "93ab695549515d75a2caf8a97b8974e75407d5e56416d3a3010c304c99aa39d468bdab9dab3b87db1c27a2b831ea3595d371039345c37a892328287cf39255619494927828d95a7139871eb99496755ab3b689969e907cedb05a97c7976a31683f329fe0237798f9387d5ba11870cf6dd01668ea8d0a74c0aea46e13697dcc9846b1a8a9f2bc5304378154bc7cf8ec2df7f070ff06b085239589b1a7ffd13f9653a821767a36a8294fd59793abbb833b09d6e09e71b9062dd3055cc9a04fa0b8e6d41ae10001c18a398ed85bf31218532271332c73cea3862867081a8b2c610b1785412be3f42ea64917d3ca6779ab6581809d5f0412f579019a35c6ab21a4f9142f9d2a4b0c731ab447a002c7029b490ad5c1372eb6483a205fedda376ff1b432430e1738b7ab9531bcd48b4da54f4d3a96a00c718fc809303c50d1042b7e49457c9512e4f66e6b75415fa1bb6b23a1edec751c60aa619473b9c489d6c5c4935380dcb67ff7f59d03a33881b60818a12639386db06c6ee6313f98bb8c1163b2c8526744b560f1d7c672250258288a78761c99a8aee292a6b0b48b80d2495684891a28bf0c226de929b8229289f3e290d21a450901659c404e0b9c25a55c7dc39bbe070203c85cb3e9708071f6cb9e9045cf460939f29c321583f8695ab709ae11721924282afbf225cc54ad87c13c56733a21294beca82d8472363a2308a41163c2d60b7c3b42fe1b74c93a6a5146418e58697d3344006aa576d6300728440ffa0a6166514539bcc908cd1b3ba889d9ae234316a8d7709a7156635412f0eb33451942dcdb77aa9b4e29d1ae41b586ca960660e08672accafd847ff9289035e10e05f0c35d5b1a9278615105533c98ca6b1b930f207c5ac3380f2933e834b4e45983a92a1af994bc51ea5ec3e38389d2559275ca3bcc4d7c50585cea9fd145bf284262d458badd032f294050e01422fbe34c0501815008205ec4a8d43006674788a8d3a64c57470c953ecfe789fb3224efd84d4a40c921852056a8cdf43976648429729386e663397f475900655be634aab9344610fc6322a28d859b5214395172468a15570a171096c5401175fbcb0db8ccccc16e5e6b82f7732c2c47ae7d15738d650189b3702d859ee43bb0a0650fa0cc823761bee4a40877727eed58815a64c38a94b7de743688156a18368f7fa9a83064cdb972b762a97ba0bc61bd45650478661819ba109947a9327d1e54b1bee845e6e54efbb51c9f2cb38ae825286c4a1a872d4a0629ad00574d60569d6106063ac54380ba3cda463d41736535b631a3245f6360860b4d75fa153743203ea0846ce423bab1095ba148a18c2ff75222bfb295ee904cc83bcc89d44a82558753e096da4964346470c920499faa392a3c7258c5b17a770b50906c6518239d81301de60bd5522e1168a16801683ea09ab8d083c0250eb1413123164f95a36a5c053e706327c49ba727f00a6000c35db64c01f92f4a746cfc76c9d0b7810e559f9b12b0370075e42153c7f66bd5b79c94f4c80cb0226be6924f1a29a707007d998ad9a1aa5eb7176879b2ff476918732d1a810d456168ef86467f1aae56a673e40921d48440914568c3c98e33f5835952517d6ccfc0206c2cbbb79a43a428a4858bc5200b5735d7809de666ce5e124169b7acc44a3e6b1838d497873aa48b66893fce45c252813ad2e3b68c1c27ea4237841108218b8d7bbb8733ba43c6f6b2c7818b74fbb41e238ba1f5c1c5db2ef8bb80f2456f228592e952caddf6bcac9c362a031bdb4b7f422573cb772115f385b830ca6fa368ac3920e43b5ab283989b3c719e295867539047d4420f71a2ec046f031a43ff738ce87b67ec19c4f284cb1c1cb07938348f17332bea4dfb4c4417d7a30275460e498784f50d6af7920a78a69e070d2786036e3145e1d7a503f188e81b42a8fa8658e30a8701341bc9b7278601951b2caab4997dbcc7c8c15c00611cebd801b2b3b3155433240c6a8481a9eaf0b34f6750bf6c974962210f69a4022471a4c72fcaac2dffc4c603b6b4fd6b4d7806c0c275585eea28b8f010a1d48506b1516872b70c43b6576544b9a19644fc1d00a7bf9a59a51afa318818819dd8b1498bc1fc913b55c573b39633343c2691f6a8af8b65ad05559e1721ddaa391415979ea32a494182483627849169e2006e9306448025229ed2c14ff825a43976935a8a14b8448d6c4db642a1726823a2053f4f75951b80b47056bdae61ab68402d4aea6ead635f2262082d71c4ff5c78e6a6345a72505e23064dd773118ac985e49e4d88c64dd894322b0d2a712f0cccbb506436c3f0bed765ad0b193ea520580be4c12cd65f2406cbe1fc9281d37bed1988d7488f3925244454b82982c49fb522a2f83a7d131d1cc65cfc7179f8a043da781959a815b5e45f6e0b37269c84237424fcabbf4dc16a722cb171984e48864ef70c0fe14c69ee385f15eb7191249bbe3a3888c50fcde9302ac5aac6105503589b3748938eab5614d626c6a301599b623ada44f432bb18e359c7b223414a34945786468628c6579f9b004185cb7590e22f94e83de26c6a9b69702f704041da3ffbc8ce5fc2367a3a97c4b997bb06a01b8964a8534e2f713c289a0dc8c072dfe4a42f305785a99c0dc898d3104e0dcc62c0e600253c218f0511fcd94bf78497b03a08efea8bf7fc0e45d3545df2c6d708435414bc00e64c76a523bc0ac823fb56da247da4643fd9063748b23128c6ce4316bdcad4bafbca77b8ea6c10e54ad063a1433333252311f68c676ebac53aca8fd70b9404c1cf3c979ca0c492198a2f92294ee5ab4a2ed15100f20e5eb948916ca7bac7b28fdc904ab1911afc19a454af45e6a265a726340291bac80cee679e009c02254a6c6130227464b2fbf2a95661bed8b348ae9c759fa53a4b429c0b536fd6bc85d5c96233f90ca3057839a47b068855283487c90a8088e271a3e33f5ae5695d044c4d14ae8440bf03b318549600e39cb9d9d58ea2d2a5e3d08a11484801b8167d4c5afc20c56bf970a230231da8372eab0f5266686b4a3da0ccc6b57cc81aa29053142cf0f35cf0c83282893c25983ca06606cf255cc1b41add5947ff9322a4c23bee47cc49656a8581ab5a99a3797798ea77a1db18c39acc97e6342b8770550212718856398878900d6cc9a5963a71432e5678a12ce86257b0b32ee751eb181fff62ad98443f7d79cc4f85bbc67190a68504a24a3166c588ac7b40fed53318b8b452d1a738e59a2c82442feb013f9b2429b6c603f71619f386118327eaf0c13ea30fd620222af064c61aa8d9801d53192c61575e3448b265ea9987bcc84ca825943a4d51a9cbb5e76e4fe88cb6d92215f60b0941c46b89a746cc96c74cba7b097bfcf27533a46fcd928f49d670f85179e6b598ec595cf39c3554eb5f93ab9707d4a559069d24a4005cf28bfeab0bead80363ac608965141e252de510562ccb5fdf94c30da1247ddc4c80554d879b62d0b49eb3b21ebad10a50794545577be4eab070d30365dc9c34eaad1163b251b223e8ba45dcb77dcbab0a07fa635d8b841179a354304e0d249dde2319d85cb724245877a549ccd8230fac8721d82e8a2182e5cb63285ca8a0d049cc7160d7116d5c1c0127a9ae5fc808eee88e340a57a80964b21a353b08bd35da0dc1d7020d6cbe43f49547686546391d94b9a2b2d63b23fb2fb8c30f7ac371b3a80aae0470d93b610ba1681af1be2871a49419a23610843bf940804483dea0ad8d609500d8aa2426cbf0ca5aa353668a7151bb54c7c4e4ae3354c598cbac6e90949cf6b79a941c541c652351306f810494dc0ae743cedba7904d34c2e0b32b603606e33156bc750bbc477313219a97e184d695c701b2009aab8806709b8d376b9cb6a24f3b6d0a4157398c740d08809328aed069a52fe77cd68b9dac62cebe3649cd1b139fa84f6a2333ab702a30414425f50e25e41bfe9a2e277869e17c035652237889c37e3c86cde41c7585776d14682f3c0309a09c1ed43609b5b82e03508869a7f6b627c3710c58198ebe9100f433ac0df22d03934c1eaa10aa98b88c879fee60596a3ab29739b613ab741ad4518e6ba5edec190678b20e6544f469791c64629657b9b1c51eff1616e29a1b3bc25a55cc9c481995bbe68abbc383dcc02e4c8208ccfb57e052ae86017dfebcbd2165810151538e7a9af3a4c5364c02208428d2b98890923b7bb92d66a2907b5376906a61115c979d4b34670a91339008bb466928b30e807cbecb307becd228657bae78f5869c3463d1b73e09aa7f6274c7fd2a3a9cdb4160da310254462eba30dcdbb5c30542463266d790d0fd79c3c76f5da348753312e4949ff2955212edc46dfcf9e6c37a1f40abf556c865cd096c702d21239de7c22713d70626f1a3a4c4cfbdf3faca62b6591121e25d64010c25a18676033e1d7278ac5f2d0b43a31f3a4156ae710465" +}, +{ + "dz" : "d569b935ce015c85f792f8f7fb0d83c4f53b492959361dd4f75fb764d656450176eae84d11c4528382828f7a689a0d5cff87b8ca0bba97feacb39b935a8788cb", + "pk" : "a1f055f88cc36236016d4809e5d9096762571c15863924797872cdd77370917720776b8ea9b72189f237e9d710da6906ae25331b9c82ca0ca257dc980ccaa23ee61ce1e681ae09aecf967c33505f83078bda132d1ad623373252b72109f6e6b8f5481dbe89b6033558b90a70d3866930a3c78e024b268604c8b3beca583b8b531a4a6c094591bf173107025ba079c3062a607e30647308987084341925531076ba04e03c8dcbf551b56885c383a5929a54c207b39e162348f7a7fb375f38896e7c1c6641b56557f52f4da23320252aeb382082b8560cdb83c34614c40b8e4dc4ce54b4c009d9c3cd6884c11c616520ae0d220e2cd03a869147ffa894d5b02c75007bb09b51c8f59a53eac1af1a0195623217b578bf4c3bf59459fe3c9ca7b677155436336176a99653fe677d0d9bcb266b2e5484a72bf8a86f1b250b5666e40083bd24cf578c4f9386bce2f034d2e9347835632a1ab39726c2f467a864f5863c0b498491111221bb2e83386da51c764b8597e2b503a21eeedaa6350683aa82659fa276d9b8ad3875a019ea6a00b31193c9284832c581555d7c478f81e259150c41e8c23047eb0599647ca403a7f19273a765c439535efb20a6861a1b7fcba48927412af6c9364670e2e44c6c630a930b9437529f0afa7534a08b7606a512fb737a50b6a08c637087314da4bbd76c35a312c091fa3a863a3b8c7874501c8a9233212e592c828829800c9d174cca70761bf8188ff5585fe1d59905373420120848f22ce8d4bb8ea253d3499e0ae59b526555a2245eb0fb0ba2a38cda009a31f89bb46851a4277b808018e8f23148789b8ec69d8c622247e207d2e08491a3945a60aabdb7b5cbd260a348818c8493159199717bbe5305a5c785c4eeb26dad73c76a04bb28b740d2a761c8c02096e0b6dd297485725ec59b107086bc40e71f61b90ba596cc905b564cd33d76e2b1624bc3a2e75440474daa778b79f3819d237a41d08d9260226e63231b5494da150093566f31cc3a53f581880512c25826a7981241f4c90ee3b3eda1c277b5c157226342fb7e3622b0665109fb7342d13a96e3eab49c53074b76b3a2aa26c899bd86c8a26159ca278c034e323475a0b12f447df223aef827597eb5422bf26cd48b6a40b40200898430ccbe1a6b8ee1635c761623a956b270dac22e3a24fbbc8cb62710a197110491aaf8b89575d68b530530cb2380a5e65cdcc044b52a922b346e50005da16b8c2189525950a109f74b225213c28113bc793857e9c384914809cac7c8ec5667a34b007c7eec63ae9ec21a46497b6b836cac1c451b03814b7c47554a9e6039842418468fd5860ed6cb13311c638b86680ba1628ca09afc406d944cb0ac11b928899cf333ab54be5796a6e0db7cb2b2c8c9b9ae6f300a3d508eedd292c77c589c6682e2509b8d712c6b41669a5b5363fa06f6bbc0bd272abf0c423e0c719ba90cff3b0dc2c390e30b46b38281864b5d8bc2ab339c48bd9cc8fe70067358722cfabff6bc907a457f84b1bcbd6c765ada9b5c684d290c53614123a02660ffa22ffaf602111b7612862d2d204c65e82dc232798982652ea51a362743bea629a8324f76b693124b2c3772111c627e9db55c49fb7ae4204222d850311ca5d99213173416df4bbe68b6b6fb514dd4b821bda1b50f5587b7bb254a65a2d9e6a2c5baa0e71b0be88199096c516f84a20f38a9d32520a0064e955697008a9bccb6524ee56825bcbb776092c99a040b85c2e6e1669f08932f63635f1c37e989a4f8b2190c335e31a03aa06a755022c895485780bc90a969c834091f2cc64960d399ee65359ac245201b948bc2827943a06165255b0492a7236e7b69b66847824d8873a24b6267acadacf330f306652dc766df9269ef911068b50dcb199996a294b8f935df477f00b99882a5a5fa8147023737592a2d797358bda228bd62440fb0c3811b73ca1c8fe4e1c070498b11bc816da770bd895a96338fd9a6659ffb88df51719bf3a4b208647063cf9ec985ec087fa643608e0aa23ce7749ee3c7983783992961a409729a1c6f416a0a0a5659e8320f95277ccdd31de6fa3e41ac9de3293e3ab36971842d6f8b2ffa9a26de29b0c1a26815362a657a5571fc378425b23089bb94016ab2e180888226d1f7b448749280b978958198cbc626539abaa520f4c1ffed3ecd10dca6a4d6edfa0952d6e2785cbddb", + "sk" : "ea4c84806ab1066a1665a830346b85ab6b9494364f2d46661cd97115948228557cbf7a541f34899cec8cf1a3c57c913d6eb713d3022b13c7c15ea35158b043b9829c0516c5ba44327ca81de2313aedd1a3e9a5c07ab07bfbab2686b9a33010a85382094e1c9c400714839ac2a2422ca6e10a96f70c8edb8ffab42562e7598d501168d919a6475e619a87a4c0790131684f3c8320466e002d619ae828324c163cc32a56a55afea2bd51625186784db007673f1314efcca127a90b53893901d4253ac3625ba543a4b875ed322b2c510a9522403fa08bdee8814492112da917c1548e93ac360bd651f311ba8d675eebda8e78b6a0e5d4c314d89100b58a4fe6af99979bf58b8b2a88229a53c73be55ecfe26c48dcb4ed005680505caf570998341eff71864ee44d030262f3bc1346e44795d24cbe346a9f7871ffc71fbe0c9f03c925fc9904abc4a58bda6ef7d408b21a145e544e7f28758223c1b2636ebe2647abc39b076c8903426eda5359c58b22be15c1f2405caf641029f6810789b5c150525db917bb8b82ef217f1b726dbb3a1589445e4fa472da00b3ed673b8a95104e9039e1248e14137fee3a34c0daa6b937af71b75337694394a7c180191b1137a92cd71a588ab5969694956369ee85a139dc552151ab48068147047b0d0a8f8a0a3373c60732fc0790d488784a58e07b0180b1a5f322a5c7609ba0759db31ac35431736564724a53cdec4cab8155229a7036524acc08b8b9069b53e497195f656b581a037d8309ef072a2810a5762a05f759bebb7a27dcc0ad3e4824cd2781a6a2431e8badd79902e8e492e40a9253e758100a19c17246409444f3b4bffd2442ae86c544061fdb5971a0e0a1bdea4942a8c4ad11571ee9460a539b8f49327db237e2c5b95b371b2259138f68252aa5cd95d3c2bcf410e9201e71641d62ec9c9896a86d643505c8b99a625a8d19c6c4e0a94b816b910156b7f125c14cac14498c643c8635d8b49962019f0a885b4a91836ba9cb16142ad712fc5c99137a2afe2195e27a006f9b6be6d67fa9eb00c9741847c1bb228036330999120870562487fe8843a967b362e1659c8337bba05108741340e38057f351a4605388874561f99db1c696b23b45f96a48377a18acfb4d7200b7cb65b6fd0672671259f9337579424ceb2315336919a84965ff1bb9cc92622adb3b8a991768b72d07c93898d815e4f49e8cc0500e64bb37bac3c4613b6d4badc656530955b9f3984c7b1a97d09c75242c169e9886a8e543c58812f4829778fa9cb20706dc84a4b5226786950db1337061b79ccb78c4f520b232db36aa599c1e800956a28f2e0b05e3ba11e1432c89713a4be993cfa552f1c11d0cb8b3fcf2525e30c2aab210ea488871430bfb2528858053ba499df337b8853959a10504c124569086cccb069b97a1b782150542e184e210a24c0b5447487ad5a8c291c5c8a9b3b9b701c13d7114e337231959b7c18b2631fcaa40e841ce72b633279e57a38e2ff26eaed13af3f061595b679cb0c886304d874392b31173c89889615ba9676320d917424b608b057974d18c1806bcad1d955b48420f927c6715641e6e867f073968a23a5751a799b08b2e1d30c8894634968b6450c48b7a4ba3894628697960efb753d2540b6b4432a6b59c92ec3398e9c0c476173843ce80c626df72b18ff7424c923fb0db28a8b1903bd19b963acbe1fb6f3fb27180490e82c97592d41abbe486128cb57999816a97c050ebbc4781a672d07acd13415f036b26763365ca756a7c13db0b1f46fa23f591bc5a5b527e72136368bb85bc52f0916f921b2ff3c96ee0759a00f230d8b141a8c532f037770422a95a495b3087013393694d496a0a4241e8d62547178e2ef3663e211ff7bb213bb69555b25e91cb7b34039b6995c8bb91a1e31937af23b09410cf9f583a76e04948c7c3d341c75a30aa670707ef83793537392917a0c2195013b54c0a8b3e4686c10d25239a03c3ed28c916f40d3809068c542eb8e0a321bab4ae0011273190bb1136d5852abaf8bf82156f2ec402725503b8849daaa9bf266490da991a56a30fe3c089cee7ac241bc1528a0129cb8ea22b1c90023c9d1cb4bb04268b60cfeeb8071e4b8d6b52798c3b960cd87bdc66ad467649d0a835b5153bf2ec57f12b93a1f055f88cc36236016d4809e5d9096762571c15863924797872cdd77370917720776b8ea9b72189f237e9d710da6906ae25331b9c82ca0ca257dc980ccaa23ee61ce1e681ae09aecf967c33505f83078bda132d1ad623373252b72109f6e6b8f5481dbe89b6033558b90a70d3866930a3c78e024b268604c8b3beca583b8b531a4a6c094591bf173107025ba079c3062a607e30647308987084341925531076ba04e03c8dcbf551b56885c383a5929a54c207b39e162348f7a7fb375f38896e7c1c6641b56557f52f4da23320252aeb382082b8560cdb83c34614c40b8e4dc4ce54b4c009d9c3cd6884c11c616520ae0d220e2cd03a869147ffa894d5b02c75007bb09b51c8f59a53eac1af1a0195623217b578bf4c3bf59459fe3c9ca7b677155436336176a99653fe677d0d9bcb266b2e5484a72bf8a86f1b250b5666e40083bd24cf578c4f9386bce2f034d2e9347835632a1ab39726c2f467a864f5863c0b498491111221bb2e83386da51c764b8597e2b503a21eeedaa6350683aa82659fa276d9b8ad3875a019ea6a00b31193c9284832c581555d7c478f81e259150c41e8c23047eb0599647ca403a7f19273a765c439535efb20a6861a1b7fcba48927412af6c9364670e2e44c6c630a930b9437529f0afa7534a08b7606a512fb737a50b6a08c637087314da4bbd76c35a312c091fa3a863a3b8c7874501c8a9233212e592c828829800c9d174cca70761bf8188ff5585fe1d59905373420120848f22ce8d4bb8ea253d3499e0ae59b526555a2245eb0fb0ba2a38cda009a31f89bb46851a4277b808018e8f23148789b8ec69d8c622247e207d2e08491a3945a60aabdb7b5cbd260a348818c8493159199717bbe5305a5c785c4eeb26dad73c76a04bb28b740d2a761c8c02096e0b6dd297485725ec59b107086bc40e71f61b90ba596cc905b564cd33d76e2b1624bc3a2e75440474daa778b79f3819d237a41d08d9260226e63231b5494da150093566f31cc3a53f581880512c25826a7981241f4c90ee3b3eda1c277b5c157226342fb7e3622b0665109fb7342d13a96e3eab49c53074b76b3a2aa26c899bd86c8a26159ca278c034e323475a0b12f447df223aef827597eb5422bf26cd48b6a40b40200898430ccbe1a6b8ee1635c761623a956b270dac22e3a24fbbc8cb62710a197110491aaf8b89575d68b530530cb2380a5e65cdcc044b52a922b346e50005da16b8c2189525950a109f74b225213c28113bc793857e9c384914809cac7c8ec5667a34b007c7eec63ae9ec21a46497b6b836cac1c451b03814b7c47554a9e6039842418468fd5860ed6cb13311c638b86680ba1628ca09afc406d944cb0ac11b928899cf333ab54be5796a6e0db7cb2b2c8c9b9ae6f300a3d508eedd292c77c589c6682e2509b8d712c6b41669a5b5363fa06f6bbc0bd272abf0c423e0c719ba90cff3b0dc2c390e30b46b38281864b5d8bc2ab339c48bd9cc8fe70067358722cfabff6bc907a457f84b1bcbd6c765ada9b5c684d290c53614123a02660ffa22ffaf602111b7612862d2d204c65e82dc232798982652ea51a362743bea629a8324f76b693124b2c3772111c627e9db55c49fb7ae4204222d850311ca5d99213173416df4bbe68b6b6fb514dd4b821bda1b50f5587b7bb254a65a2d9e6a2c5baa0e71b0be88199096c516f84a20f38a9d32520a0064e955697008a9bccb6524ee56825bcbb776092c99a040b85c2e6e1669f08932f63635f1c37e989a4f8b2190c335e31a03aa06a755022c895485780bc90a969c834091f2cc64960d399ee65359ac245201b948bc2827943a06165255b0492a7236e7b69b66847824d8873a24b6267acadacf330f306652dc766df9269ef911068b50dcb199996a294b8f935df477f00b99882a5a5fa8147023737592a2d797358bda228bd62440fb0c3811b73ca1c8fe4e1c070498b11bc816da770bd895a96338fd9a6659ffb88df51719bf3a4b208647063cf9ec985ec087fa643608e0aa23ce7749ee3c7983783992961a409729a1c6f416a0a0a5659e8320f95277ccdd31de6fa3e41ac9de3293e3ab36971842d6f8b2ffa9a26de29b0c1a26815362a657a5571fc378425b23089bb94016ab2e180888226d1f7b448749280b978958198cbc626539abaa520f4c1ffed3ecd10dca6a4d6edfa0952d6e2785cbddbd5d6b62e0449476f7c6f9ea3621237bce0f97b11fe0e65776f1e92da38362cb376eae84d11c4528382828f7a689a0d5cff87b8ca0bba97feacb39b935a8788cb" +}, +{ + "dz" : "5cbb141c2763425c274f7404fe530d9116e08c33f9f200a20b011cf563a28990fc9ebbe336dc464489861db8253606971bd0a9008a433ed17752d04023781552", + "pk" : "ada7c7f6a193f8174b99e5b0c249517ac47c4ababda18b523a665587579d884b7d98f778758c48d28c89c97441e7ba1ddcd020455c73a30377402c13c20bb8bcf9042066424a9081c9d44139e53f3afb7d9a687c3510a2f4f22fd5ab37bb778267053055f38158c3762694aaa89596ed824a0a10490c49619960b79db3174a227c7687ac0b4533197799969911a24bcf1e19a4d6224e2fea4c4da636483a09c39c0e63531e367b7b74c9734313bad6056228d00d90f8806b6a06dfb45e4366867c2175d692c66ca91083b5ad8566bfb4816b40da9971bb4855b44e13a04eac687af1a025863b8878827c1a06360e84c24e8940e404716e665e570a12b0532bc663001ae8cb94aa658a9394b60a6a1c8b008ec7bdf432002dd43f34fa04665278057cc5a0ec65b7315e831681e4d5ccc2f95588089122b18b4cb93df740b2910ccb49142942b563d2027c8552ba5bb595ef35943db0bc2c912d57f2cf166b2b9d219222a6a71bc55ccf7cb9c7c8c23398761aa58bd8a587013841a266000a375cc14018cec577260aa9d962799d9900a991873b175194720f50a90310c4b8b5248c0f08a0b609440eca877c708e1941a15af6407d5873fc62492bea381f431c8a727e5fa235b39434bdeb8e0918c4ab82a5d735b0f676aac18463f8e65cf2b30ee3a97969da994105d056d49e2245ac4fd1912a44b6f3647cb9c377df2c7f0a99016725bda1fb78670013fb25061e11c09fe1c92ec21a83da9a2ed2c95636598f63c264c972a4365e6580440b0327d3638628e06cbb7ba024bb2481f64bbd39a5e79c46b43abf0f405fee38076a600468f033b9c52aff5c3ffb6191ab8b37dbd8730ec63677e6b43afc74331631fa0c5263268b17bb0a77f2699e839e66489a8744230aac9c77ab765cc9094a8077c12c8e8dc6bcfe900e831c02cf01161c083b14677f01878655394f31296a33c612a18121cfba2f7a1358af8904b5e8c00028434ef812ac1a5d24bc2e09eaa5929c5e6e05683d292428324fe2a021e238b2717490f4731aeff426ad085574c9a1f7cab392d662fd25b4390a694946c6684c0a02d85da187769632b6a829cfc24999a317436d4b47473bbf8fd73f9576c6424acf65e88a4bb230aeec1f5e08c7c05a1c84aa3af9d44c25c81e4db436285a4b1a572f950437e277294de7c0ec087b8148607b30229bc97f7907076d9842f5a77fc5644177fc095e7245eaa7ba8f9c7840c99f852a109257b04bbb3679f80a617ba997f5b5b22c14d13807ab9bce20cc271c9b2cb5dcbf67e4a0df65a5adbc0f8634670c4718feb06880293d7c7184c52601c69c58f110cb1ef961aeaa95133483714b11b57b71cbb94e6a483444f65f293b7d349a02950079ecc18ce091ab09d647141065e037c2041c932ca092ac7b870e4a64caf14069fc9845cacd62549356c38fafba2a7f7133c5f7c630721fca36ad23767e4d86a2d1ec8c41da18355a9375659c9b7c04539864b1098b8c862dcebb94785370430498cecb064dc8aee2e385fd775749f47c1f38b6d6d08a6c3a5b2e148204d50048a3c8e5f13e2e3059e6a3554a636acca6b634aca6da71977e33a74f0a56e78cb856b816b73681a3a96f5a4328a1911a7e063eef31440fd21e5f281e9be9954113acbc3662529911cbd8221a7227e2d38e9bf798de61627d67b8e8f62f2e10bf66f24187d2ad2efa071f0b2210e53091e29be859857e801348092c572b91b59102e325104c6c1a49c7654c2bb4df431c12ab0f88e1132b63bf56c1616028994a304536564dbf18b54a16b50b9c75d3f347d8cac3f3bc2dc9827155c507294014c8c92e4121386c936f3bac661f4c4f8604a2b648053e88792f5ca9a48719bed781ad4a7bebd8306b5401dcba9a69a35128a7a89d22b97ffa5c2336cc5cc090a6cac001dc560aa25f8f65093f0c2fa5540b51f56862380996a4c48d90a68f8956ef49019ba809b84496118235e02535a37b1da0c95845f18342545ed12426a6e5ba1bcc7b348585669c003b02033eb024cdb70405f5c5e6077449d8c4e6e66d65a23b9bf51f40230bd241bac33b708ae7b2147809ba2a14005038d0d197c790491ffa5c74626d2f6c5e0ab2c69ba55ebc83195044cd7c4c00d84bc716d02f8bcccbb4f85d5e50c6efec71d667cc0338e6a6ca392e61bc1211681ce762516ade8bdad2f1ed78a9731a2634", + "sk" : "2a3a066cb7ce2fd3976cf377eb5500fbf9887c2375705c6feac85eb92cc4d423ad0dd37b4b1abf98d72a57e3905b9531b3f9382a2817b464769ba133c3a550036abd7a704ef0026e832b5a0d494362025debc90eb1a03807b35832aaa00a8c93bd72bd1908819ef7165358541659aca85c2e640987d5cc3fc941b7777ba63e17987bfb81869a484ffa81a83293d87272ebe243416728a92632480112628463d880c8cb23193b7038b765cafd629605b0a1645a2770635b47cb35d728a264a03c2d2c260d965a86eb9603b16c33a092d472c0857b632be44a04a2424f4ab1f1ec6fa54200c1bbb4ef0a35a59bbca8b889889332577835121195d38248d849087c996933403f74e56c9b3406dfcb416359cc9912cff4f69b3e826071c5029671724c28212f0b85950b100412bc574a059aca60a3f1c76ea45a6dc88cf4998c21805f9b17c3ea7793af98224b017ce25bb16676a1146c933a587d98448d7fc188e6a510272770983b964091bdc09b10ff341064da0cb347c8ca92c53eb83bab85248e0859a4a933be5078feba8a8ca12d8b634946c24861fa7a699069c2c72ddc840ff20c4795a680111222b3e52116e64134616f4b223e0fdab1b7a514c667155a42847c4c726e2c7211e675ace1412303390b6a2dbdfcce2d435750c94799a82df899227d344a81a5422af0c05b4a605ce5b00a438fdbdb80b8f224051c7c934937fcc8889c6baa43e89244e1bc5f9b136a2b6b956a349aaa3cde7338e1782faf951518f29d492842a936cca4cb09e81ca78586558550a7e11452197c29f7625e680138b03039612048913aa4a8c8b383e8655900549a472dc552ba39b617bc82405830cb186b1c89327145e1cb07113dcd39110cb7b45dd9a92a4b28b6e8794ca070f1e398e603ba39b5a7eb7b289885039be10bed6a08b296298766752ee392e5d693396b90e71147463a63aa6b69e1e3c1426c403bccc11c58beec481bd1f5b5a26657cdc75cd93ba89f834594240295544420e09f5b0bc9e76458ad426ff6b6247534aae1a04a6a5a67894638c88bb858c0c21af8376500b33143c917148c3244c2bd176fb134154879314d111bc2193ae5b03fab328db03837a177c8caa585caa45ba51794a7954837cb671017cc6325196fd767d50a65ce798754754403a0af6a1c25de2b051e502da59c20e80528cf0b6e509772114a0e7b43436877cb0f175f8d1b0a774c36ab09a9d13013cf20667100ac1a314f0ba661ba72bbfb86890a48929dac8ca0e40604b17bc9434013f707a2e37099021e1c7c8564e7848bd21b45d13c020b3a2c09823194cbb46841675a92c888bd1191b3cd78b154f650732b12634c3b8473cf044471a8a54de3a601a4545566e9076d0149c8e8760cf0aa1a820e7fb24ce428a49f572ac1028e7109be2ccb41f5e02bb902697e537305ccb425b8cad1d63fecd8a8e1852e1988419e7688e891bad58155c72002f190ad27a55725398831310cb8b14b06516ee2906ae86874629b7073e8acc95548065275a66560d7935174cc4dc8f4596d000d288c5ce8536666fb275e33cd68e004210985c7d146bfc1b2e1b9a1ba1048c6516a4e4384c48921f271a4207369963b75c3d15e859322715b8a59b116deb2bd623acd158a8375a2c403f15068f74bfbdbbeab602357461b9bb1ac5d429929025ac2a3b1200376a953704888a2b304b3ea608fc10b1f05716ef9466a670407ae66baa218557177193df197f3d692536c02ff5816cba620d23b0a866980d1820d2417722ad440534a0f15e65573cbb8a896be183b83cf2b954139a27d4a4eaf267b0a2471182963bde3503e7b7fa723ac20e97357f24d5b6cc01b8b8606aa6ee251578963593187109452b352ab1f90a8928999b87b1c054a3b8ea30c4f79907c831636c9071277412a1fda2e5631a86e7124f0393e1892857458327136a136414cd0db09e7a9948995831882b1f08ac2b9767536e41d19fb54ccfb3565a470e1350b9d3a81ec11043a3a6f445433db604dda35af06aa636bb88426d0623fbccb6f9c43ee1b32f822416335ac36c7200e60ada28096bec7cafe37c3aff80f0ec27dc4ac5390e0756e080ff198bc11ea96178b55b00a21f5c81ec67744a8b236100cbf5cd98204000f931898eac7cc091389ada7c7f6a193f8174b99e5b0c249517ac47c4ababda18b523a665587579d884b7d98f778758c48d28c89c97441e7ba1ddcd020455c73a30377402c13c20bb8bcf9042066424a9081c9d44139e53f3afb7d9a687c3510a2f4f22fd5ab37bb778267053055f38158c3762694aaa89596ed824a0a10490c49619960b79db3174a227c7687ac0b4533197799969911a24bcf1e19a4d6224e2fea4c4da636483a09c39c0e63531e367b7b74c9734313bad6056228d00d90f8806b6a06dfb45e4366867c2175d692c66ca91083b5ad8566bfb4816b40da9971bb4855b44e13a04eac687af1a025863b8878827c1a06360e84c24e8940e404716e665e570a12b0532bc663001ae8cb94aa658a9394b60a6a1c8b008ec7bdf432002dd43f34fa04665278057cc5a0ec65b7315e831681e4d5ccc2f95588089122b18b4cb93df740b2910ccb49142942b563d2027c8552ba5bb595ef35943db0bc2c912d57f2cf166b2b9d219222a6a71bc55ccf7cb9c7c8c23398761aa58bd8a587013841a266000a375cc14018cec577260aa9d962799d9900a991873b175194720f50a90310c4b8b5248c0f08a0b609440eca877c708e1941a15af6407d5873fc62492bea381f431c8a727e5fa235b39434bdeb8e0918c4ab82a5d735b0f676aac18463f8e65cf2b30ee3a97969da994105d056d49e2245ac4fd1912a44b6f3647cb9c377df2c7f0a99016725bda1fb78670013fb25061e11c09fe1c92ec21a83da9a2ed2c95636598f63c264c972a4365e6580440b0327d3638628e06cbb7ba024bb2481f64bbd39a5e79c46b43abf0f405fee38076a600468f033b9c52aff5c3ffb6191ab8b37dbd8730ec63677e6b43afc74331631fa0c5263268b17bb0a77f2699e839e66489a8744230aac9c77ab765cc9094a8077c12c8e8dc6bcfe900e831c02cf01161c083b14677f01878655394f31296a33c612a18121cfba2f7a1358af8904b5e8c00028434ef812ac1a5d24bc2e09eaa5929c5e6e05683d292428324fe2a021e238b2717490f4731aeff426ad085574c9a1f7cab392d662fd25b4390a694946c6684c0a02d85da187769632b6a829cfc24999a317436d4b47473bbf8fd73f9576c6424acf65e88a4bb230aeec1f5e08c7c05a1c84aa3af9d44c25c81e4db436285a4b1a572f950437e277294de7c0ec087b8148607b30229bc97f7907076d9842f5a77fc5644177fc095e7245eaa7ba8f9c7840c99f852a109257b04bbb3679f80a617ba997f5b5b22c14d13807ab9bce20cc271c9b2cb5dcbf67e4a0df65a5adbc0f8634670c4718feb06880293d7c7184c52601c69c58f110cb1ef961aeaa95133483714b11b57b71cbb94e6a483444f65f293b7d349a02950079ecc18ce091ab09d647141065e037c2041c932ca092ac7b870e4a64caf14069fc9845cacd62549356c38fafba2a7f7133c5f7c630721fca36ad23767e4d86a2d1ec8c41da18355a9375659c9b7c04539864b1098b8c862dcebb94785370430498cecb064dc8aee2e385fd775749f47c1f38b6d6d08a6c3a5b2e148204d50048a3c8e5f13e2e3059e6a3554a636acca6b634aca6da71977e33a74f0a56e78cb856b816b73681a3a96f5a4328a1911a7e063eef31440fd21e5f281e9be9954113acbc3662529911cbd8221a7227e2d38e9bf798de61627d67b8e8f62f2e10bf66f24187d2ad2efa071f0b2210e53091e29be859857e801348092c572b91b59102e325104c6c1a49c7654c2bb4df431c12ab0f88e1132b63bf56c1616028994a304536564dbf18b54a16b50b9c75d3f347d8cac3f3bc2dc9827155c507294014c8c92e4121386c936f3bac661f4c4f8604a2b648053e88792f5ca9a48719bed781ad4a7bebd8306b5401dcba9a69a35128a7a89d22b97ffa5c2336cc5cc090a6cac001dc560aa25f8f65093f0c2fa5540b51f56862380996a4c48d90a68f8956ef49019ba809b84496118235e02535a37b1da0c95845f18342545ed12426a6e5ba1bcc7b348585669c003b02033eb024cdb70405f5c5e6077449d8c4e6e66d65a23b9bf51f40230bd241bac33b708ae7b2147809ba2a14005038d0d197c790491ffa5c74626d2f6c5e0ab2c69ba55ebc83195044cd7c4c00d84bc716d02f8bcccbb4f85d5e50c6efec71d667cc0338e6a6ca392e61bc1211681ce762516ade8bdad2f1ed78a9731a2634269505d6cb8212b9dad2fa70171035fd4107ff47c02696b3489650d5ef9c6f19fc9ebbe336dc464489861db8253606971bd0a9008a433ed17752d04023781552" +}, +{ + "dz" : "293abb6d1c207927945417cf84883ef010823e11b487ed55239e466e83696d0cff8563038aad865a817cab9ce98846ba75be9363718ecf5fea538aea90b2a558", + "pk" : "306c0e7e44a625f44880cb0d125bac36b650f8430c647c68e1ca6306e39c61142c2a5924cd0c9cd5a085f4eb5dc4815711e4aa7e3a26e521cac85c303e420a18a3393d996c1cb68dc9904588301385451788e57842305c064807421034ad845df2baaead84acee401fd912b191c89f51c436ff6bcf4b33b0b2120440e65777f4bff5dba7560148364046598acf3d46b70f7960eb9a7c5fe893c87c6dc5741cd84b080b7a4d0a596effa363b6441848d849b72a7cb9f1597c99b7eb6697bdc3181db25ce213c35725bcca20c840066dba39420763572f187758d05f6e43cbd41296f7c7a637cb49a57b00a2a9cfa7b2bd1745b5cb0255b1a68892431704f4bbf5c4844d0c1e9ca5bdefab042fe1ad30d4491427543cb39fd11717035690a77149e09a9173a433dde8a29c40744cd4a7d2ebae568a392981326fc8bdc2989869d6a56f6715ce65a51dc9a5e8f5c304ab6937f41964e80bcb259b9494bb713b6c882b94af5528a6b1bee6886f1da41d5a10b8cbb188aca7a820761e10b6797a8a5aaaf54b5f724c8fa9a41ad09bf9c9875df8ad40781ec93748b428cb0527c9257aa83d412ff1755d835343ae05be3211a447011944aa8952f2ca001153f10bacb18ac64619689ea6562f23c0fb5a33046c5dc5b7c37e2133d0987a44c207ae5abcb38ba68e13505fa5a05be45af5887606704b7b4a4e18e5b78f518e8680a4c3a678b5513cdfa3b18ddb285a562f00f29cad2c984f60c005f73d23e3cc617148d6a53177d10004981fb7e8a1cc362224e48d0cf69d28f213082b4425368c2757ac8493393e5495f35a41646225b3741e5dd1bd6e354681e8b47ae5c576b19d7c807feb4abc89ea94f2d150f946920a0a3d6bcc3d1799332304035515273c2c4e3764ca04e1653bdabdea77819e0490416211ba7877ab8028f8416fa08918c7a7791ceb4a65b567838283cea96997e3ce2564cfa0d41c43868bf6f6828dcc78f5c03afc4422675b9fe926c5d2cc197046c38a30cd5cecc076ba9bdb3c57a4fc806e835ef6b52b44070e4689baa7633458e0acbab3a781aa83158b31b1c949338b58ac034ff2c2c80d3bb54ef7c10c5281e0d5930f3817b9893032246f6aa82f7f6cb29a467395340c6b81347b2997f5514d90c95e7e84633813861c488ea27200ebe7cee795b560973effe3a19c32950e821ed1140b454c8d5da64453fccfee09565c7cac7192952c360232861eaba924780895ca022737ab9139645bcc7b6edc67050c5a90a4308c44764740279107f2799a455a8e4b2d384012d66956384b0cdfd108a1db088fb34cf0824f82ccc7da6a8824a90982a92ed3b46aea02837f57aa0ada783e8766887b538fba4c33b157c2138e9a9155795399cc99613bf9b707519f001241ab2336e96981aedbabd2f41f6673c4bf28929f777f2500cf0e382f8ca2182b9b8e4fc36be4ccc4a1293aa477a76625429a68178733380ce950d5871bd7a0695254cd4367a1d8a94bae95304f23622d07650a17341d401cc5133a772c8aba82a63feb19db78af7fd850c2104fd207579649b0b9eb38c9f2236f1669cc31a5a116474c9b66897c4f6d96cef6428974748bc066338a510621d9690e4345c1a3756dea7355148d45c89a16da8867e164ab538e01e35489c792f79a53a967277054297fdb4365fc7f9bc15068b70b6702a8d0aa9968a005a5422c30596dfc9c635c189f9d2ac1f9481167558992b21ab4dbb54f88742167164ff964c64201da9cabdce9b458dc8cd7489684d4c8ac7951a2147b7358098975837083723eb85a4889547c3847d7317cc88a1c5ea19294358941467fc48bc6bb38486ca05715058171c7b2a178cffc838de1ba0a02c02d4049960d477d9f79a0b1b17ba9345afaf641aaf80218d41a71b9063a5680579123992cc4efc596ddbc0e1d2c66f035963f7b11c7d74c35158ebaf6bc16d6798a24ce928274e125cf3d51419bc6926e69aaf11562f541446df6b77c625f9ec820587b68f1b50e590132d9c988b65c0a86b6c721384b9283cbea128904f5a8dbb6b6a5fb2ada47918ae3544c7978fbf9381f78468b0265290181b8f57ee043690023bc9dd4360fd13514c79cf9e3639b792aa1e70c763c52a43773fbe6732d262f9385716528200e37054237c04504a8169baff63f6fcbd8988928266537d344dd44533e2797aa03d8cb025e705a9f45", + "sk" : "09080dc7cb09012bb14eaa2b8d92a71c0078a792ca0607908c04b8b684a0aae139231991812b5e763b2f191526268519469673713359936bba126ab5e0b4b62d8a5fa0d76b365212d686ab74188878aacdc1b420d323ac67659dd2e8851317b0c132ca57bba44671b7b9a78f6e6c73503125ab718bd386b2bff1b6f026c2a2da0f5a05578b8013a0b78fd628cfd7090c648c0afd11a9fd768e56dca02a6a87c7c523ea959348fa0dd38b5d380291c99a989589b6b784bec0cabc181c33c45840700622a0e666f3db15c32bc4636782fc688c8d5433bab63c35d3ca26eb488660a4d141b33371413156322fc2a9be424fb96712e7b6a324fc1559508910124c7eaa62b731147d1331a375b597494cac741520a07082d6945ea92b7f326d3830814f62b20c84179071182dd707d4bc87010b406299c11a633210726c59184767f96720a918de74178d397407950c62974b3ed703b8305e9892016d859fb1479046bc0a0e1766a985266b950d56e9b178244d9a5c969fac3e1a41983db574b3c9b50f2797c807b03de8ab0e692ff913a79e1600a4dc8f4d537368784844a34797433c7fe2b8c5ba14af06bb9ae4c5b301201a55a55b2a3be308a0354456f0243882651d91f69cd5930a27a25874b45b7a556dbeb65ba5f68f684c643a81c0810143de8c2352b0a92e86c72db570c3ac0ceac65bdb5912cb59683a88627086a06a00ae99922fac3a47afe5451b813c7fab053c043069e70c0624a40b6629ef46bfddc36f82173abda6a36642c4b3685ea23375a1906c9eb98e3e057889671d2d6ba894876816c79a6ad476363b27a2811fdd4baba235077a037fb780c540132a046432f04aa041f25b44897c885c8ab8e070d5f07042c2a383a9886bcc40c7750e5ce85c5fe1b217151ffe2ba53bc9875af281f927c8c88529f6395a75783098a9b3a89cb494a131d3118a51a868ce76b84cf3b2ceac1ae145b070793ece3916b86726cb52bb1b40a24be7a9580a29f1ea9146ab5d787c2f3f777638fccaeed72a74f0959ce5b0edd45bde14c4edd0aa601b82ff6b4edb9b77c833a8b0aa59252c812d25bb627b0f82e3186f4ca2ace595cca41ac2612e6c409011854b033360f179c397b06c82e43dafc47b3f424d4d59051048c624e999fab7bd73b18b13a9305064844be040fc5c4a033b59c097299e6221e2c5ca3b9b05317376ee4b4e9963b172802030ab06e403b6940b5d8258572d16ce4c80a20ec0a796b06df076b73e2b648534520dec6ef0b57f61f4b9b5519c82d9931e863461d26d41f35c0a3509a1d684cc5047b9482955d0387808a26bacb2b3922ab780b7ce43256246073b6c5900f004a3830fc14770debb620b1569f6c98db310abdaca61dbd337a9773758ab92fb490a9fb95596d1087a696fee494c0e5739a2aaa63a77cfdaac6a37618cab56a6c6ccbdace66f7eaba24be57cf1d1c1cbc42517604c17801865081f13f3c04c9118444578b95b6a55e51830f3c594b3662351b113d57c6f49640ff14468dbbaec7a7ead354506c0adb923a0050bb3f89cc82b2cceaea4582f1998691bb1845a22cdfc721d6b088bfc52d6a8ca526625b6fc2267c277b9e86b88d9ccf81847c79a0075d36f9b7315273870d0239b8adc9f9dbb05a1e44e7c4604aa3947ee2085dda65651b6069e2c7d64f06986f527c02525e103b50363cffb93c9735135eb1a0a1bb056842278badbccb43810c3727028fcb0f4cc5dffbcb7d39590165a01ad4092ce6954f8c3bd28663d5e3c35142b0351538b2660020dd30d35c0bb5bd7276a8743c79c53a1f80146c16523080db316382d2c9ddce7857703bc3c939b4d5372185603fed280dd8b57fb6b7d80270049aa09bc6a206ccc47f935ad40602a89e9a633541f903a16545274d8a51a40150cde7555a56bcc80261d9522acdb3390f6a5719d57705ec8aa871ba41fbac75254349b15bb6af427bc1053a8a05e2d766a3b8243690b1352a59ea4f2c18e202cf69c205db06a3915058fa01fa8e4a35e3c26bd5abe05db1240687616d873355b6485dc858f5441d9155ab5e6c9fa115f46815e6394c2c1cba717cc0d8048561bab198a9449d8d9ca47803c4777ab6e55443b3ba176a15a0167826ec662877a457e5b4e7401b9b30883bf67b1ffa09f306c0e7e44a625f44880cb0d125bac36b650f8430c647c68e1ca6306e39c61142c2a5924cd0c9cd5a085f4eb5dc4815711e4aa7e3a26e521cac85c303e420a18a3393d996c1cb68dc9904588301385451788e57842305c064807421034ad845df2baaead84acee401fd912b191c89f51c436ff6bcf4b33b0b2120440e65777f4bff5dba7560148364046598acf3d46b70f7960eb9a7c5fe893c87c6dc5741cd84b080b7a4d0a596effa363b6441848d849b72a7cb9f1597c99b7eb6697bdc3181db25ce213c35725bcca20c840066dba39420763572f187758d05f6e43cbd41296f7c7a637cb49a57b00a2a9cfa7b2bd1745b5cb0255b1a68892431704f4bbf5c4844d0c1e9ca5bdefab042fe1ad30d4491427543cb39fd11717035690a77149e09a9173a433dde8a29c40744cd4a7d2ebae568a392981326fc8bdc2989869d6a56f6715ce65a51dc9a5e8f5c304ab6937f41964e80bcb259b9494bb713b6c882b94af5528a6b1bee6886f1da41d5a10b8cbb188aca7a820761e10b6797a8a5aaaf54b5f724c8fa9a41ad09bf9c9875df8ad40781ec93748b428cb0527c9257aa83d412ff1755d835343ae05be3211a447011944aa8952f2ca001153f10bacb18ac64619689ea6562f23c0fb5a33046c5dc5b7c37e2133d0987a44c207ae5abcb38ba68e13505fa5a05be45af5887606704b7b4a4e18e5b78f518e8680a4c3a678b5513cdfa3b18ddb285a562f00f29cad2c984f60c005f73d23e3cc617148d6a53177d10004981fb7e8a1cc362224e48d0cf69d28f213082b4425368c2757ac8493393e5495f35a41646225b3741e5dd1bd6e354681e8b47ae5c576b19d7c807feb4abc89ea94f2d150f946920a0a3d6bcc3d1799332304035515273c2c4e3764ca04e1653bdabdea77819e0490416211ba7877ab8028f8416fa08918c7a7791ceb4a65b567838283cea96997e3ce2564cfa0d41c43868bf6f6828dcc78f5c03afc4422675b9fe926c5d2cc197046c38a30cd5cecc076ba9bdb3c57a4fc806e835ef6b52b44070e4689baa7633458e0acbab3a781aa83158b31b1c949338b58ac034ff2c2c80d3bb54ef7c10c5281e0d5930f3817b9893032246f6aa82f7f6cb29a467395340c6b81347b2997f5514d90c95e7e84633813861c488ea27200ebe7cee795b560973effe3a19c32950e821ed1140b454c8d5da64453fccfee09565c7cac7192952c360232861eaba924780895ca022737ab9139645bcc7b6edc67050c5a90a4308c44764740279107f2799a455a8e4b2d384012d66956384b0cdfd108a1db088fb34cf0824f82ccc7da6a8824a90982a92ed3b46aea02837f57aa0ada783e8766887b538fba4c33b157c2138e9a9155795399cc99613bf9b707519f001241ab2336e96981aedbabd2f41f6673c4bf28929f777f2500cf0e382f8ca2182b9b8e4fc36be4ccc4a1293aa477a76625429a68178733380ce950d5871bd7a0695254cd4367a1d8a94bae95304f23622d07650a17341d401cc5133a772c8aba82a63feb19db78af7fd850c2104fd207579649b0b9eb38c9f2236f1669cc31a5a116474c9b66897c4f6d96cef6428974748bc066338a510621d9690e4345c1a3756dea7355148d45c89a16da8867e164ab538e01e35489c792f79a53a967277054297fdb4365fc7f9bc15068b70b6702a8d0aa9968a005a5422c30596dfc9c635c189f9d2ac1f9481167558992b21ab4dbb54f88742167164ff964c64201da9cabdce9b458dc8cd7489684d4c8ac7951a2147b7358098975837083723eb85a4889547c3847d7317cc88a1c5ea19294358941467fc48bc6bb38486ca05715058171c7b2a178cffc838de1ba0a02c02d4049960d477d9f79a0b1b17ba9345afaf641aaf80218d41a71b9063a5680579123992cc4efc596ddbc0e1d2c66f035963f7b11c7d74c35158ebaf6bc16d6798a24ce928274e125cf3d51419bc6926e69aaf11562f541446df6b77c625f9ec820587b68f1b50e590132d9c988b65c0a86b6c721384b9283cbea128904f5a8dbb6b6a5fb2ada47918ae3544c7978fbf9381f78468b0265290181b8f57ee043690023bc9dd4360fd13514c79cf9e3639b792aa1e70c763c52a43773fbe6732d262f9385716528200e37054237c04504a8169baff63f6fcbd8988928266537d344dd44533e2797aa03d8cb025e705a9f453e8ca044ed0e215c83f03eb98b6da9da137ff2433b319d9ccbd0bf054135d63bff8563038aad865a817cab9ce98846ba75be9363718ecf5fea538aea90b2a558" +}, +{ + "dz" : "74d87c7556f2671f2d666854a4d6e073e69f35421e6e1a428cccea49c37f972ce1fb7456ac0aa1b97068f452cba64ebdc138bcf5d36b0a0fada2a3b374141eb9", + "pk" : "fe3200f3e260b8bc589d0162aa2b1eabd229f9ab6f64e528e0f05b3c69b9c9f192964a3a6d2c96b8d525f0bbb32b848e5c244409904f1583c7d58209b91465b9e3a6f2a515ecf55a778119455bc57af5aa885b64100acbf9746787b9757a17c1416c4ee317b017348f5299661436c1fb5c8aef032929fba046a601804b7b4474461957c8eedcc19c609253c23ae1428674b5ba69264ec1ea74f825198ca71c3ad929465b2769338a6359132027aaf46173415b31ca0624d7e6c258a91388742b0f71917df814b75c38b06025fc9682876b597cd65cf21943cbcb4e77b1314c4b487aa46493fb7d5f734d0da891bc51cc8fd0454a7c9bfed5747daa43e2c95fea422165e02819882a535a7e3127396120a242412bbf7384bc91372f640202ea9ea5830002654d40f346c1f2025dd648befb332bf9ae0809810445a2c91a6c51c68ea19b01ca287e3e967139f58ee66b4632346cf4240634095c59492fc3b919be49c7f32b00da0a9b95625131e24a3b03c0b44c0cbcaa7fde1c7872645950818c69a62d864b251e54b10fb6820b9678026353fb3bc09fc90cc5842849252d2c6208dbc7754cd70904f15434a8840104b6a74814b555c69897b4b2d2a69407715f93ab337a7005007218b5536a89020332998a040599bc688f6497c520b73ebaa40b735f41d966caa24e655848fa66a2b473437d14c4f80357e449643cfb34e1759676b0b2b3733bfa6b2324357931a72866e99430454fb1b65797a90e5257037744c0f06415fed93540a68fd2bc5ae74247940c21a061923c603c4a89309f8a7d1ae48a29370908d9137db01ee84c3fb6d4bcde28ca63c34cf1012bdb060d830c2aa6da19ecc0c0a8fc0272e066a8d6225f3a2873a52992768ffef0bd9b109ced760dfd2c3ce7d17cc95095f95bc84f448ec51331066ab0126505df1273741220a869b518cb458b00b5e1e503f53c639bd2bf11d71c45e8866582c71c0663ccd19b0519330f36594f1385ef82199d76b4507318fde59b6ae4185f3811f15b873be902d80c44a9523351653365e369be2939f6f17f753c776fc3421dc75bd0ccae0fab9bcc2a8175408950fa32e983cb736075040a857501b2e543b043b617c16001cef203ae164effc243d4b1cba2f225f361a7d65949cabc32b3b3a782bb18d03627cd2507f1d122a46c3e35f91315ccaaea110709f648114220524b8fae55c8e6caa27a693c3a559496d30db2458674392575accea61c91cd3b9188b94654d15e7eebb383e19d114bc0720b7552ba0d42d85863e984a220bc4632bbd7d1c33f925836e117b209351ffb01c8923edbf4a54d500ce7dabda45021601a5b19d9b0b736c8b1e30896b285a633c647658622b30a9b476a8fcc251e0971f8938063550cf39718c86b6849c7b55319b7a4e817b4447d265bc5189614247026c82c557be5a4e1d302397865af7277646b442874a5b0d5ae60429e4dc5ab30c132052030d747715dba66c16316a7d10d180b6ea88a6e97601ae1131a2412b5e83039c75a1cdfd8c0764109d360094882725c627a8f9395cdfaa7bea40263c8479b3a3e1d68cfa5688cfa19322b833e0eb863171a3f48b9910e5289611c4d51554574cb239934cf870550a0f7a4e78b1ac50b59ac5b1de0f348f0315e627cc2e50707827b9f9c6b943010b46a2b752500526840a13d3123621462bf5486820594c40318b86731e1258de6215d76d68b58083149a041394114caf69198277a8a57082da4a440f799f78064310660350b0ab34970e6d9c9e53a2a24b2c95135971db128eec54cc21378b6067d648c85c8bc21bb9551a0648825719d5fcc67717083e9d677abc523340cc24da5b489933ad7d1c1d12b7004bc1a875244a7b9810b29c77826aac6daa1753681e2b9cefa4aa3a5c4cdd63a844166017f8aa79db97115b86c447bb7e66b7964a19d410149fbc475ec1bab8b06cf96ba0861062f89a621776507ae40849b82615f0b6d81ab82a92184ce9b8b07f69311fb295eb83cc5cc4545d89362c33c8dcc7453a70051f40a56691e212897746c17f5002d8c15bbb2b625ef267914d62759cc01da4c8437eb3facf336fa0bc0e83a9ff51c793dc44007a63432309460162257d191ed8872ead9a8a66296a7e55d30d86ddee023ccb84744bab7db9c015a60707cd7aa0ebe7b8cfb1d663d8b18c5bbf06da994e7eff9d64742e2", + "sk" : "a902027dfa84635138ab20cb6b0cb06df848adb138ed618d93b5857f11042d2c753e0765d3a1c6febc1fbef347c58b4993f5bfe065a9464098bbcc2c61aa1ae338217592b657f60cdb39b740871103019d17504c4a572f2c5490ac61cbacd3148d23ad48bcba53a7a331e3403c13934ed8a3a6f794c263be9e1b4fe96a40e991798987a54af53048ab9646db8b06b9152136713668a4ca1cb3947469ac27c035ba69fdf43c2b4128efb31aa7226902e41de295cf22b6711cfc34a5276dc6ac9329d30269e637a4e92a80fb481e123c45e9bb04b1724e4065524612ff66a30633a4888bb8b5a15b8780a10ef8841c35c54b90b98f156dcde86a0b78a8052399d0d4bb6d2822a450cdfb5c245f245274167388d25f278b2a3b13bc7ca108d2e09a2af50f47e82bcd8c62813375d88c92f9005a1255a4ebc720146b97929925d9940797a95354d3cb64e0a399cb1ed1f1b395419c0332293fe37c6d676123394e40e3be474cc211dc5240dc855f27ca87d7af59b799860ac3427959516a4794ec9318d1826e8c529ca7bf0e4613a7e9299a416c4dac9937733825f1223d369fe773782381c1374b9f0eb942d5eb446f07c3c4130b3dc057e4222ec6a5c365f2b8ca618cfe998446171b2ccb940eb49a47b1cd123196c04128e1b9c35f30b38287b831ab79191c488de7b4f302be30c84ee446b29e4476b41a4901d85cab92767bcb88cba8b91a23aa45e088f2c82bffb330cdd9cc4aa6b46b032e36a885f61627357208a1b4031c858179305a52f57480483a6bf30654022fce933da873af8c64a74b1b51f1b9532a6caf0dca3fb16b50cad1189097b18526691cec9e3d2b6d53d1687fe64b434a7084873593ca8f359365eae00b1220099adccfa4c78b5f3056d5bc6e3ab96aaf917d4f1073c4a517f66447a4c15a26f96a9ac3c4fd624283757abf435aef7a6de4fb6aabdac65a99792e548e2c2c24fff7259bbbce3d588ae4725585517b5b68b712166171b9780a8c46b3d07b1864ba4a4b5c88e14666b09733c3ca7f1a185dc950e6854a086cb8642487a313a72f916200255a70d94a43cccd9664975d50c2995c56ee142c53bbb1f596a9454b1bdef4a11dd6a21746a3d499c6e3d7209b1004924b2b69c7c9e4286d871546bfc37481faba482616512b3492c4778fd1977bd079ecc188c3172d3b6193b7032708981a71fb72495c6e6787c7012748c062cdfae690b3ac483b985b2fea1e16e51b4ad408e1f53290b48bf4a972a3676862853ba348b0f8d730fc577657545da7500d989c657e787783008509d81babd7227348c574474f574aa60e976b97814a5f7c886af9c3941bb04ec3314ecc1ded62b39ed69636c07227dc11d9596103dc104d96b96cb085cd18ad7087743795b28bc6ad4af3196dc7c7da1907f6d7c7c862b4f9f1045c5b7c57907fc319aff58a113807269d9a2deaf4ca4ec501d6a35c1c23710d674f5b0ad0c5b14d3ca61145b4c8aaf363c7560a61923fb54b3daae6ab4f979dc78b971a105f5d5bb3d8f6201b82175a215d16c501726c8fbd903a2878152fc471a8b4236d6c10698284ad07a7f4b1784aa893669539a7ca8093d81c367b5f51996e3477148b626a35326010d9b7a52044d56355f7008375e2237b312c3a399f265304ed53382f766c21a6822c4864cedc9bd8a26b3928ba0b206d7f446b95161b5cb4415696cb50739b8b7a484470c8d196a762f586c5604f3e0c7bb41669bc538436a413b2630d12d23b94486f3d8bad351a5cb277933e6b1db56b3850149e28a91091aacd9a87beb84a457bf242e78c9d1af9b0412c0b61867f6981cd6c6b8b6b928409f606c4fc1ff6f6453a73b209527bb2e25527e791f729414544c8ac4c7c51b9a64591102c36c5942365498cbe7f9379890a70cd8999610c06e7504a96b6a7f839617fe42e2d13972ef49af07ac9f35444d89a7454e1af46b239fbf2aafb87405768760767a2f4721d7a57288a42bfecb512ce6a023a3221c74266990171d09aa61596787984584697bf80d79dffe0674e416cc74b311a9cbe9fcc7d6b185a5d1322aba71d6f11b673aa293e037464d214e9061ee19341b11199c88a78e4103b41f90e849664c08c30e3d9c011595199913dc231bdfcc98b0ae15f276054215b1feb4c4efe3200f3e260b8bc589d0162aa2b1eabd229f9ab6f64e528e0f05b3c69b9c9f192964a3a6d2c96b8d525f0bbb32b848e5c244409904f1583c7d58209b91465b9e3a6f2a515ecf55a778119455bc57af5aa885b64100acbf9746787b9757a17c1416c4ee317b017348f5299661436c1fb5c8aef032929fba046a601804b7b4474461957c8eedcc19c609253c23ae1428674b5ba69264ec1ea74f825198ca71c3ad929465b2769338a6359132027aaf46173415b31ca0624d7e6c258a91388742b0f71917df814b75c38b06025fc9682876b597cd65cf21943cbcb4e77b1314c4b487aa46493fb7d5f734d0da891bc51cc8fd0454a7c9bfed5747daa43e2c95fea422165e02819882a535a7e3127396120a242412bbf7384bc91372f640202ea9ea5830002654d40f346c1f2025dd648befb332bf9ae0809810445a2c91a6c51c68ea19b01ca287e3e967139f58ee66b4632346cf4240634095c59492fc3b919be49c7f32b00da0a9b95625131e24a3b03c0b44c0cbcaa7fde1c7872645950818c69a62d864b251e54b10fb6820b9678026353fb3bc09fc90cc5842849252d2c6208dbc7754cd70904f15434a8840104b6a74814b555c69897b4b2d2a69407715f93ab337a7005007218b5536a89020332998a040599bc688f6497c520b73ebaa40b735f41d966caa24e655848fa66a2b473437d14c4f80357e449643cfb34e1759676b0b2b3733bfa6b2324357931a72866e99430454fb1b65797a90e5257037744c0f06415fed93540a68fd2bc5ae74247940c21a061923c603c4a89309f8a7d1ae48a29370908d9137db01ee84c3fb6d4bcde28ca63c34cf1012bdb060d830c2aa6da19ecc0c0a8fc0272e066a8d6225f3a2873a52992768ffef0bd9b109ced760dfd2c3ce7d17cc95095f95bc84f448ec51331066ab0126505df1273741220a869b518cb458b00b5e1e503f53c639bd2bf11d71c45e8866582c71c0663ccd19b0519330f36594f1385ef82199d76b4507318fde59b6ae4185f3811f15b873be902d80c44a9523351653365e369be2939f6f17f753c776fc3421dc75bd0ccae0fab9bcc2a8175408950fa32e983cb736075040a857501b2e543b043b617c16001cef203ae164effc243d4b1cba2f225f361a7d65949cabc32b3b3a782bb18d03627cd2507f1d122a46c3e35f91315ccaaea110709f648114220524b8fae55c8e6caa27a693c3a559496d30db2458674392575accea61c91cd3b9188b94654d15e7eebb383e19d114bc0720b7552ba0d42d85863e984a220bc4632bbd7d1c33f925836e117b209351ffb01c8923edbf4a54d500ce7dabda45021601a5b19d9b0b736c8b1e30896b285a633c647658622b30a9b476a8fcc251e0971f8938063550cf39718c86b6849c7b55319b7a4e817b4447d265bc5189614247026c82c557be5a4e1d302397865af7277646b442874a5b0d5ae60429e4dc5ab30c132052030d747715dba66c16316a7d10d180b6ea88a6e97601ae1131a2412b5e83039c75a1cdfd8c0764109d360094882725c627a8f9395cdfaa7bea40263c8479b3a3e1d68cfa5688cfa19322b833e0eb863171a3f48b9910e5289611c4d51554574cb239934cf870550a0f7a4e78b1ac50b59ac5b1de0f348f0315e627cc2e50707827b9f9c6b943010b46a2b752500526840a13d3123621462bf5486820594c40318b86731e1258de6215d76d68b58083149a041394114caf69198277a8a57082da4a440f799f78064310660350b0ab34970e6d9c9e53a2a24b2c95135971db128eec54cc21378b6067d648c85c8bc21bb9551a0648825719d5fcc67717083e9d677abc523340cc24da5b489933ad7d1c1d12b7004bc1a875244a7b9810b29c77826aac6daa1753681e2b9cefa4aa3a5c4cdd63a844166017f8aa79db97115b86c447bb7e66b7964a19d410149fbc475ec1bab8b06cf96ba0861062f89a621776507ae40849b82615f0b6d81ab82a92184ce9b8b07f69311fb295eb83cc5cc4545d89362c33c8dcc7453a70051f40a56691e212897746c17f5002d8c15bbb2b625ef267914d62759cc01da4c8437eb3facf336fa0bc0e83a9ff51c793dc44007a63432309460162257d191ed8872ead9a8a66296a7e55d30d86ddee023ccb84744bab7db9c015a60707cd7aa0ebe7b8cfb1d663d8b18c5bbf06da994e7eff9d64742e2b4ecd70cf455e2195477c581fa72af1ae232e7b5efb374d9607fd958447b7c67e1fb7456ac0aa1b97068f452cba64ebdc138bcf5d36b0a0fada2a3b374141eb9" +}, +{ + "dz" : "013bab0212d04ecd54b478daf72748003a25e2cb060ba6cc50bf95c292b8206b9da0c5da5f195b80fbb99c2e8b06926074f3f604b3f6195b5a5b9737876bba72", + "pk" : "fcc42e1ada20b880b35f49a312180f66b866c4952d92f2bf38b08f6110850224909413938678c8f9585a0741b561a36b7680644947485b2462d984ae5ea115fd52202643014607067b9540457a3405e7127e841d004b86c094468a0743b82bc70569c3388338e0dbc6abd1456ca3afc4564ee9d361ca0a708e417aaca1af12151d5fc93db4b652eb990a0335c799a27b713172b6949be937b570384f3627102dd2bd784c97d46c8a2ff2a1d2a0c438f0281cf29971e3c58df77c33b83b5252cf0e72c4fb9448aca6a3abb06a22677c0206609598c544781598fa318bd58da2625ccaf7ae759b774147380f0304163b0786a9203a1169d943b54b9b92f7bc7be5fb17e87a37dfe73712c33fc0824ab448a9b2295a7364629956cac2cb6ed54ac085bc3693fbcd9cf7b44d4b318e248ad737aa1b821fa985bf7f219828b1cabfe66deb269a6be49dc3f74af594c820748fca60961fb04f22ac2cd4787b5a41a91195b8588b3a74a1a188f95e50ab047cf42fd5b63fb88ba57dd24528f90c2f966a1cc91ce39ba848fbb2ec4576df188350f587e59b0ac0848d71a93cfda63e3ef93745c6516cbb69a5505b1f900aa4f91094306c84f640050393f1c751a05872aa7b027f678b1aa2cd5f97ca25806a53016eae4412a7f23ebd8a7359e5a706a11415951ae2a45d60fc999b66a255cab76ef85601b2974c462ec4202f83b2ba85190aec7c6fd6263d72e19f7ef71b6fd37694ec1e56090290549d002c2da8b18beab345f969bf1b23144486c299104dc7dc367265902469c45d7788c5d23941c6a1608a12586692eb759eb4835c537429ef287b6709b87dc22653d7a92cc314a295a6a6c939e33b3a87394cc40cb284b17987a088fffc3f401c2b072cb72b467d59f930d82101ac725c79d54fba036aad5760a615cd5fa1a323a87fb63a4472228f124a3ef72a086ac74245cac6b7784249d17c7a19a126b28c7530c1ebd6a806097de35177a5070abe84bbe3b99ee7149c57224357c8624d08ce6467b144e598701987fb460b21e53957f57ce98343a564c63fc466f7e04bbbdaa63ce79448364ff1d9c05257219d03b2d90c9c0c299026d3c0aa4845050092fc7424f1ea03716a456bb2b935a2be5a5570b1eb467d54890493c4977300344887718bb54aa06bd890229359ae33395d7a7b08a71465297780f54cb0d2125ec1311d6bd31766470dc18810848706c0e79c8654c6c6cb35d4f62ee70541e92982ba570dbc289be8e842a31b7e7158660744992d6506e1d1c8bb512f98015270376158228319cbb7a2411253a98cbbca8a6d86c2710631e105c217b2ac05f813474727c1b089b3c8ab8779ce91619352d86b38c5a622c73d692814fd36800d5c009af0bf0eb6734eeb382f70412c2469d10698071c772e62c6243cca236c2676fb0258487430998ad99a1456d29d79977c810953b138642754c0bb993e8b9b7e3b3b7972359569c44bd6576fbfc212f78c0c33362011225d2596bfd2ec1a4b721a36259fb723c6413910219048596252225879bf301c20d305dd3bafb2e62ccfb1c3d300b5460ba561f3c61930662f3641b763b2f5b5b2682546cba9a15331b8afca63cf68b7a1fc2e49c5b4042a3a2b2148c427c9701727dcf3371bc7b13aa62878c8a358f391f02b1fd3d2ad663c4f71c36cbfe11581e1995d976ca37440ddf9c4de2b48ed9c492730a977e017a7065cbcc811bfd155d1935122e12325732505c6c568fa67bf7968ff6836f765c242b5b9966c333ea1161a336164d72cc5767e40939590f07b537788c46265fab1bc3078c470e98dc1b7a31cc53a83a0a7e95c4634754a069007341396371ab79f6343b601b50966c5999144cc46b6d06089a879871bd1bb9c2cbcef84cb8fb4a031786bf778703b164f6787c5cd63ac781424f8550e1ac992a6c04bf7953787047b043632de12698e80526c813e08f36dc1db592f48968395817566886bb2c7d3fcaddf331273ec7ecbdbb3e5d70c823323fa8a1a15e1371534cd0462cd052685950bb6b6833600243e35c7047bb20832f09e1d854739c5b425bb32bf86029e1159d79ba70293badaaa25385563cfb4babdf4bbbe341058d3817e9a7941e69adcc867559b822bf63d0034c15de1a9371945bfacb1caca4fad8590f723014cf5355228d850d99c57f85c67295a4afa0b9d8e1da6065ee0e9e43b6d", + "sk" : "6fa78813f0808fb375e817a1aa133a3564c1bd632f43a517d7d0bc43386df21a252c71c707c5295109a5f5b64d8d8b338b86ce24290a1857364f69750ff116fdf273cd6861fa085f0ee8333e32cae0c4c202b6af2be601a62c1e78ac3330b96dff58c2037652fe497bb9c6b544460f58d59bc63091c9dbbad4225d4f4a2ad5936a6fa20b5ef52be6d72b8b2c9c9ab23a4937ce834364068a6a9feba95c41b577bc8e70d58425466bebb66167384d6ed37dafd7741e05971b5509aa5c7969c908dc71670e47c45358170f12b9d2804149350663a8a9bb45454929813e7c7fea462440ab4bef1035277a24a9076d7d11256ce4cd024157c0f2a37111a5305459f220aa4c569d0636ba1dcbb918903edff43aadf5c8843a99a9031b35311522d0ba96d6514ab0ba44908749422782a66f29ea4cc916adce65978b6a8b1be6b0bb930427e8af9ef176a13593b4bb1ab1eb4e816725fa182655750a9d835a4c20470e6c646c6314c42559bb2762077b482ca069787836d8d94412d946330a66dc819b49d0a0e42393311826507aa0124c47b5d402758b40d88bab51333f1ab1a61bd81ccc561471c239d4f2cc2af811b93250e4624d8817539fc95e90fa7a7c344d82477d0d632283624d48103e40fc924f1c5d372560af7b96bab49a3de15abe1363e17cb9fc722e986b48ed03b0e727b126320969a56c94428ba31878c6803033689639c67e5950b55f35000f90505ee871c3bb27df9c5253634865024201d50384671813ab1cd77ac1261b08fa9702575673d8b3b40a02530928757842979df188b2c697406a4800e59888623365b6a3299710eb65adddf4b85f087a87515fe9c46332fb3e825b9b37a40d48ac1af52886ba7742f2a528ffd046b4d72d85b49da1fb956b11886562afce32c7dd3771c9c4432871762f00bd72eb5cab4a0cb401605d18c9b66c20b492365a2520f391be37b449866181903653c40312b9395e57496e94c5a913d5a0aa7b41daa33e4c3bad134569e1039a5fecba93a3be80221c7f5cae6b1242cfbc6b15f33540caba84755c2dac7b3239b6aefbccc239ab170b9168e842e53308f9e737c2695a09513c1dc213e7fabc79950aa4063104120b1670b7ade210ba6a22069441b9f1cea4964b7621c6b842c409d1093b8abf7a9c12a9972a7bba867b07af3451af3cd6b61f58af1d842ea8e4391de05f41ec639b3c63a72c4e0af51ff8d144d3654fbb2582c488241c2369dda7ba047181535432fcbb15d58548a7e991922c5a32ac86a80725b0aab1b3c37639e812ca9568f00b88d84b3dc4ec9580b1760301a38ce7a78850a2f7b0931c1c729481c90aa367882643a432155e472ecd1280d5c68cda283304646dcfc13672ab9a72c039d1909650db543dc15bf8b2a94e68858c41c17f2c718977bb0a10a34bb093fb318650cc8af102c1ea138a73e392bd8100f66b287d2a0e5bdc6b63b92db44aa2a42251e6276079c1a53e896764c201077c1e052995ea609b9948cd04e175a3218a25288009b44b9a72cbe37bac0801821f5575a2c54bb367530cb1367d36978a8ac6ecbc718107318ac28c5f18426489536c22359004a478799fc50a21baf28dd269c34c218395c2a06ab07559157142c46ecf7517dfa9192b0c08e8a2524b46c7543753708b726ecbbececa5218849f6b0142b9d45afda4c9a68ba91f6264e4d6a4649aa66aa6165120c4f57b3ce81a3833978aebf52ffb536f61b74a25107e8ed440504c546f1941ac762d42f0a10c890dcbb79b35d93bb85195c8c58d9b27a934fc7466631a5451939d61b009cc054a90c143636b3aa76fbadb37dddc5afc231cc68320940098fcec220d26114fb88b3e10cdb3a98b5df06d2259911d340d27798b27108b2959c5734432a5f45298d4c9be20ce912c199ceb1f53c309047a3100c5400cebba5d6c6e4ba7ae707c38cdc7782254b280b1c8dcb85726579842674a7d6061185556ce3c841fcc4927264712645b6369c30fc388d6899480490e9f223e7435a3ba055b96179c4e625eebe824ca0498a2646749d04340c28edb1077cbcc871ab64a2c23b14fdc1a45b063ecd263ab49936d325cbdd7a80d171de2e6156445655629bd64ac08963824abc09014b497ed50af28b1b62b6c9d35515a0393341ddc9ffcc42e1ada20b880b35f49a312180f66b866c4952d92f2bf38b08f6110850224909413938678c8f9585a0741b561a36b7680644947485b2462d984ae5ea115fd52202643014607067b9540457a3405e7127e841d004b86c094468a0743b82bc70569c3388338e0dbc6abd1456ca3afc4564ee9d361ca0a708e417aaca1af12151d5fc93db4b652eb990a0335c799a27b713172b6949be937b570384f3627102dd2bd784c97d46c8a2ff2a1d2a0c438f0281cf29971e3c58df77c33b83b5252cf0e72c4fb9448aca6a3abb06a22677c0206609598c544781598fa318bd58da2625ccaf7ae759b774147380f0304163b0786a9203a1169d943b54b9b92f7bc7be5fb17e87a37dfe73712c33fc0824ab448a9b2295a7364629956cac2cb6ed54ac085bc3693fbcd9cf7b44d4b318e248ad737aa1b821fa985bf7f219828b1cabfe66deb269a6be49dc3f74af594c820748fca60961fb04f22ac2cd4787b5a41a91195b8588b3a74a1a188f95e50ab047cf42fd5b63fb88ba57dd24528f90c2f966a1cc91ce39ba848fbb2ec4576df188350f587e59b0ac0848d71a93cfda63e3ef93745c6516cbb69a5505b1f900aa4f91094306c84f640050393f1c751a05872aa7b027f678b1aa2cd5f97ca25806a53016eae4412a7f23ebd8a7359e5a706a11415951ae2a45d60fc999b66a255cab76ef85601b2974c462ec4202f83b2ba85190aec7c6fd6263d72e19f7ef71b6fd37694ec1e56090290549d002c2da8b18beab345f969bf1b23144486c299104dc7dc367265902469c45d7788c5d23941c6a1608a12586692eb759eb4835c537429ef287b6709b87dc22653d7a92cc314a295a6a6c939e33b3a87394cc40cb284b17987a088fffc3f401c2b072cb72b467d59f930d82101ac725c79d54fba036aad5760a615cd5fa1a323a87fb63a4472228f124a3ef72a086ac74245cac6b7784249d17c7a19a126b28c7530c1ebd6a806097de35177a5070abe84bbe3b99ee7149c57224357c8624d08ce6467b144e598701987fb460b21e53957f57ce98343a564c63fc466f7e04bbbdaa63ce79448364ff1d9c05257219d03b2d90c9c0c299026d3c0aa4845050092fc7424f1ea03716a456bb2b935a2be5a5570b1eb467d54890493c4977300344887718bb54aa06bd890229359ae33395d7a7b08a71465297780f54cb0d2125ec1311d6bd31766470dc18810848706c0e79c8654c6c6cb35d4f62ee70541e92982ba570dbc289be8e842a31b7e7158660744992d6506e1d1c8bb512f98015270376158228319cbb7a2411253a98cbbca8a6d86c2710631e105c217b2ac05f813474727c1b089b3c8ab8779ce91619352d86b38c5a622c73d692814fd36800d5c009af0bf0eb6734eeb382f70412c2469d10698071c772e62c6243cca236c2676fb0258487430998ad99a1456d29d79977c810953b138642754c0bb993e8b9b7e3b3b7972359569c44bd6576fbfc212f78c0c33362011225d2596bfd2ec1a4b721a36259fb723c6413910219048596252225879bf301c20d305dd3bafb2e62ccfb1c3d300b5460ba561f3c61930662f3641b763b2f5b5b2682546cba9a15331b8afca63cf68b7a1fc2e49c5b4042a3a2b2148c427c9701727dcf3371bc7b13aa62878c8a358f391f02b1fd3d2ad663c4f71c36cbfe11581e1995d976ca37440ddf9c4de2b48ed9c492730a977e017a7065cbcc811bfd155d1935122e12325732505c6c568fa67bf7968ff6836f765c242b5b9966c333ea1161a336164d72cc5767e40939590f07b537788c46265fab1bc3078c470e98dc1b7a31cc53a83a0a7e95c4634754a069007341396371ab79f6343b601b50966c5999144cc46b6d06089a879871bd1bb9c2cbcef84cb8fb4a031786bf778703b164f6787c5cd63ac781424f8550e1ac992a6c04bf7953787047b043632de12698e80526c813e08f36dc1db592f48968395817566886bb2c7d3fcaddf331273ec7ecbdbb3e5d70c823323fa8a1a15e1371534cd0462cd052685950bb6b6833600243e35c7047bb20832f09e1d854739c5b425bb32bf86029e1159d79ba70293badaaa25385563cfb4babdf4bbbe341058d3817e9a7941e69adcc867559b822bf63d0034c15de1a9371945bfacb1caca4fad8590f723014cf5355228d850d99c57f85c67295a4afa0b9d8e1da6065ee0e9e43b6da97ab878370142b7b2b346179050eff0a4153943be66d9ce47c6772362ba795b9da0c5da5f195b80fbb99c2e8b06926074f3f604b3f6195b5a5b9737876bba72" +}, +{ + "dz" : "ccb073c4b90be0ad746e26fb093b60c70110bd1dcbcddb566a8cffb7b3caf80e71600a8982c350df524cde514431ded7aec23576530894bcbf0ec0bfef0bb64f", + "pk" : "3e074aaa7ac9f7703a87b72bd0aa050574b63fd80ef56c882109c9eab220e67041396a29d6977f9530c3628329a2e02a7850c77c73a4698145c837087f2241ae46a1b7b692fb5c81de38846a5bad7246b596a889eaf558d1d55bf1372057f1795b40076d53c0b81288fc9009757a9111ea26c3410d55217768378cdc94a3cb40af38f67b1b473b15205c58d876077b2c8005bf870588dd6318ac154dbd9aaaa6d48d1dc05118739fcc7c12327a68f8b5369a846b6aac56fd1043c5ca8675752c12549840d47b6563c703723d6b8791bdf14e0011c0605136a1521265c13874b9ba6064b85ea895180c634168774aa55e2df34ebd8132bac959dba90ffa656e7c61677d3b801ef3604814ac36d31657bcb05bf20c893a4a2d50644902133b9b16e81c1abb2b5521408f3799152ba14d51a6a7f4a231b5167b0273b22cfc606482cc6685bbe8e80f6aab99d7f55b50e093aa55b568c45aa3e4a0766a9228192e5e91378af608276308905826c6a24e7413aa98f57495dc2d5ed5bd6fb5c65f4b4ed7b9c4c7b504548b0306c892f547613516a9064417b1b96a95cbce5b502bc770356df5ad52b98adf01bd66175ab3747910c814e7b070205b60978aad90c43341ac6aee03cecf7cb8cd2b4842c3401ae1a3b60207af366fc7f78069e39fdda0ca53402ba455af5ebb21ef9a6d60501d6ecb1b5297312b280ab2023f2fcc42c2d66308f263b7d019af68144247c2dd93a05df57daa5a03e896a182b480f1f607ea668aea60b66964b2a3fb609ff547da9a51aa6848ce2a686406c7fcdb058595a807a6692f833cbe3166fffc73a2f30523c86db1b98ee7f477d7f1a8c7110076774d6147bb56a79aceb6804eb982a8d00356553a68ea8e91d8b86d676f394a776353bc830043cf209dead22480c08d5df25e80fb734bd6558f1b9080b09fab642808c458cdeb0d72e5b49305aa502321711131c7f848fd14811d718be5c805c8b254c8c556981ac8c1dab13cbc9e91708d99688e36599f3b7a23f7ab83f2a3b613b38287b2856aec5b4ee90c33e85b8d88cde3870759320b4c1c0d8d727c8e379f84da0221b2cdfef70270299bab0b7f9db8c69d7c9ea6d01df6107e04440bdcf945af329bc016892d8c01f071654ae3b19374946246027210cf9b1760aafb5e4a935c2d0b7c70db3721279e6fe43d712468fed532cad432ec30a1372554c97c3769c380c709018393364ca97f9dc37a0d393511990aabf398474965dc45ac2a37ad60163145bc3b73e7a6c2032f7d2216bc19b26b4cc55bc68ed996411bb00715473f4e0636282c203770a3bbdb26cc58aa7b4c69dcc01ee3e53ae514169859b632937cd8c355c560cef5c091f4080047929554c94d7115393fccc11fe397f2854564533fe9e66614da3afe15be92196268720f5fca36878797a2b045dadb2491fb3cdcfb7253f18750774d4108bd6c7c6545b801e8e368a1087e0f33c22a359907c1c75bd59db28268da457699337356436786b16bf6a25fc55141bca303faf566039991c700a227c01e6543bc173c06b9a8026fe07e032c30f5d4c86a950a3a7b32e6c67e51771d78c08cb5382bd4fa8068969926d352f7e5820ab19878197c25172e95d6ab6a05acbbe375ab955bc777977d2b926786c9143978113c490731438ea53c0db27bada4be961b38138b4c684a12d4b08b6f03ab28f6a260b01afd348b59684197002bc534836c8b735df139ff98c84ee03a58e02d0e6125f1e09bf7d7a91840226362a667627ae5f580ee50b594fa64892a508ff8bf80851abdc45486936e11e26beca14334454d66c0128663c52a8700b525950425a4ce7824b25b9e45ec6bfff8279d1503816ac76f498f8e18b2b626b285655ab40096ceeb229856457699b500b77f7af5c2bc8c545c4292a387583fd74dcd20c4bed85bec8c245c63608ea302d557199d9a70194a5e92acb24264532b02baa8f824052379395b3b4222536164823c379782837ff417b1583238721b8b6b4a5be982abfd35a90d07bade5c03c4c3170257bc0e88b41b242b146027baa2cc72474d00427b0c79cf294203df379628799452d3952d2ac709f20dcfe33b001022917a4678966f1d9065cad2bb9b6979817873e8d662d7ba8343d18729291c544c00fdeac5ead3c8dd2cf3e2ec7899253e7f980f9ab3230eb1a9a3688f94bd522ebe016e2980d72c", + "sk" : "93d973d0a7b385a29d218666fad6525fa2788a053b455422c2526d556b1e79a17330c18063b054f0e238ebc1ba8cb874836989c4a7c75d364118585b7db99469d52b043243ac867b25b2b8cb9a8f6699c3d8fbcac40423fad90a56775c57d02107da9dc94731a2a298da61caffd12ffc119f817cb01d4c98a2f48443d6b36782be1c25adf882702b225f439000ccc8c3c16129f0040fb4bb1a4993470f7c20d73ab393016847a1647a3c14ea88a7095658b0b9c61c8c726fda255d641b83f03bd1c9c3cfc20709909b1f227c89d9c7f5d51fe9fa753ee729571a3e7939af9cdc17a0373f86a4253dfb849f70c52c336d1f34a682661b6c21c73e9a92c50bb69363a9cb3c41d55c1da8d69607e012f5193a79d581bf8760cdd742f63003e96c6a1305aedfb36de84a9e5b832eb5ac2ff204397d28c8eb64a756c27d8e7b0cfee3ba9ba2989c2310633813c9828705266c2f8569163c91e33baa49e6a4b6b92bef81174d24bff6c0cc6c020eb501126ed1507ee8cbc4a7281b34c82da47bd06851c0e52e5ad9ac27f3be552564b7792fdf847f3cbb5283ca8f04c4b6a5e0bbdcf3c77a02c29fb847a5643ce719b276a39ddec8a361d73a4a54bdf1757cb6c65b0d62333c562a64317f713ca2c714a2ddb1bec986583e8b07a5f24217223aafc711ccebb83e7921a41625853a045ca02cb8b597332b524dca8e15b02804101e3cc2882546864d732094e2cbb06699027727509a4a22e28b7cbba46a30b174594c7abb7735a47a471a245050c0aa5c6abf020e005441766bb4741c756c588e4bb7963ef2a889e40d542b65a38a888e0511d8053aefc6401db4c795b718b9019c96b39458c62da35a383738649c065fd0812ee4a0b9b809725359ce754604c4e8462d7094beb3ccd17148e4ebce2a799dca2c55174c98bcd9206a0c340f8c559f6c7745d7b305b672f263643362b2fb099fc5173b43c167cc25bd8fdb7dfb7b3252162ac665bed6bb0edac9822745a80a463329db5853b091f304094dc949b797b127e11ce4860793757cdaa510cc5c04f0c7575567ad1457c54c3176861c77e7f86446d410e9b3a005678577787d32741595989d9fc92fbe5b0620a11aaf94beeb68000877cbaf39bb6bcc2bad72975bf94ff94a56419726630cbb32114bbb412c27779bc49632faccbadc4c3bc1a61f5d2337754b5981382e6d406828c6ace3f73adba6021aa15e52eb152b222b0bf593519703b3ecb38a39adeea3123a2167f1c102a19bb83a76b562090e7d24c9fdf53056f35cd367431b82a7ca210521d4c78f78ad54244e97149cb2d28bf96cc36756bc4474c0bff06aaaf3985329af217469612b225504afe70c69cd4467b3f277df5a2b74b14f407a649dc76361527c0059a8c3fca243b0c2eec7c615f7c8a15a5d4055a301abbfd5a5be42a8cb7f4b0700f4575ffb719965a56ac21dfdcc19d48a8302c29cfc340fdfc391e2838f878164cc7b58355473a9ab44098ac0c0f8cf2c0b3657709e48419c3aec2509222cb658aa1f6709d0c4bf6a077197a8a89f433ed18987072a9bbec9a19307c51f66cded27a2d0538ed86989040308fcb42e8c8a9bd2c5845a914c18c5c2aa5cc2bc418ccd5328c139af2d66b63190b99c5042e7b81372772610511fcac1449e71a6db9b35fc1b5871a627a63900594869b20a1483a055c8bcadf3468b4e9a7cfa6c4e3230c550889a48f0a5b5ebbe64cc06110c96987ccc2343bba708791bd9b2d5d6b028b9425841646244745b38c644342781e886ae452e3f04098e9c0b1c37c30e08328b011e0f4838a64874b1985ca1834559a07711c035e29c0159286d9473551ff65251e2c26a227e75f1293b2b86c53650a33b2e4b77b0108050f8c8cfc965771bbb8a9ca0075e09a30e81b2a4bab1e424587ab282ca7927bfe1bf3e18775cc36a6579a3fc338db8e090707ca42ca12981dc7956763285014577e9af843b7ccfc631bf706a1186c6973b532fb204fb0c0645e54b7581871db60e5b4c375dd2bd43b35865b08856166f640ac7efa516f24885fc9216fbabbce3d66fe9466db3907ab224244e759d1b89c041bac289040d125aac681cb048d908d38513eda6a23248a01c5b2c1b6c6296a5c612b21ad0b433bc3296f9f40b42f02973d2a4740c823e074aaa7ac9f7703a87b72bd0aa050574b63fd80ef56c882109c9eab220e67041396a29d6977f9530c3628329a2e02a7850c77c73a4698145c837087f2241ae46a1b7b692fb5c81de38846a5bad7246b596a889eaf558d1d55bf1372057f1795b40076d53c0b81288fc9009757a9111ea26c3410d55217768378cdc94a3cb40af38f67b1b473b15205c58d876077b2c8005bf870588dd6318ac154dbd9aaaa6d48d1dc05118739fcc7c12327a68f8b5369a846b6aac56fd1043c5ca8675752c12549840d47b6563c703723d6b8791bdf14e0011c0605136a1521265c13874b9ba6064b85ea895180c634168774aa55e2df34ebd8132bac959dba90ffa656e7c61677d3b801ef3604814ac36d31657bcb05bf20c893a4a2d50644902133b9b16e81c1abb2b5521408f3799152ba14d51a6a7f4a231b5167b0273b22cfc606482cc6685bbe8e80f6aab99d7f55b50e093aa55b568c45aa3e4a0766a9228192e5e91378af608276308905826c6a24e7413aa98f57495dc2d5ed5bd6fb5c65f4b4ed7b9c4c7b504548b0306c892f547613516a9064417b1b96a95cbce5b502bc770356df5ad52b98adf01bd66175ab3747910c814e7b070205b60978aad90c43341ac6aee03cecf7cb8cd2b4842c3401ae1a3b60207af366fc7f78069e39fdda0ca53402ba455af5ebb21ef9a6d60501d6ecb1b5297312b280ab2023f2fcc42c2d66308f263b7d019af68144247c2dd93a05df57daa5a03e896a182b480f1f607ea668aea60b66964b2a3fb609ff547da9a51aa6848ce2a686406c7fcdb058595a807a6692f833cbe3166fffc73a2f30523c86db1b98ee7f477d7f1a8c7110076774d6147bb56a79aceb6804eb982a8d00356553a68ea8e91d8b86d676f394a776353bc830043cf209dead22480c08d5df25e80fb734bd6558f1b9080b09fab642808c458cdeb0d72e5b49305aa502321711131c7f848fd14811d718be5c805c8b254c8c556981ac8c1dab13cbc9e91708d99688e36599f3b7a23f7ab83f2a3b613b38287b2856aec5b4ee90c33e85b8d88cde3870759320b4c1c0d8d727c8e379f84da0221b2cdfef70270299bab0b7f9db8c69d7c9ea6d01df6107e04440bdcf945af329bc016892d8c01f071654ae3b19374946246027210cf9b1760aafb5e4a935c2d0b7c70db3721279e6fe43d712468fed532cad432ec30a1372554c97c3769c380c709018393364ca97f9dc37a0d393511990aabf398474965dc45ac2a37ad60163145bc3b73e7a6c2032f7d2216bc19b26b4cc55bc68ed996411bb00715473f4e0636282c203770a3bbdb26cc58aa7b4c69dcc01ee3e53ae514169859b632937cd8c355c560cef5c091f4080047929554c94d7115393fccc11fe397f2854564533fe9e66614da3afe15be92196268720f5fca36878797a2b045dadb2491fb3cdcfb7253f18750774d4108bd6c7c6545b801e8e368a1087e0f33c22a359907c1c75bd59db28268da457699337356436786b16bf6a25fc55141bca303faf566039991c700a227c01e6543bc173c06b9a8026fe07e032c30f5d4c86a950a3a7b32e6c67e51771d78c08cb5382bd4fa8068969926d352f7e5820ab19878197c25172e95d6ab6a05acbbe375ab955bc777977d2b926786c9143978113c490731438ea53c0db27bada4be961b38138b4c684a12d4b08b6f03ab28f6a260b01afd348b59684197002bc534836c8b735df139ff98c84ee03a58e02d0e6125f1e09bf7d7a91840226362a667627ae5f580ee50b594fa64892a508ff8bf80851abdc45486936e11e26beca14334454d66c0128663c52a8700b525950425a4ce7824b25b9e45ec6bfff8279d1503816ac76f498f8e18b2b626b285655ab40096ceeb229856457699b500b77f7af5c2bc8c545c4292a387583fd74dcd20c4bed85bec8c245c63608ea302d557199d9a70194a5e92acb24264532b02baa8f824052379395b3b4222536164823c379782837ff417b1583238721b8b6b4a5be982abfd35a90d07bade5c03c4c3170257bc0e88b41b242b146027baa2cc72474d00427b0c79cf294203df379628799452d3952d2ac709f20dcfe33b001022917a4678966f1d9065cad2bb9b6979817873e8d662d7ba8343d18729291c544c00fdeac5ead3c8dd2cf3e2ec7899253e7f980f9ab3230eb1a9a3688f94bd522ebe016e2980d72c13035e253575fcae389887037cdbff8ea508ff9e5337e2fb607919747cc53df871600a8982c350df524cde514431ded7aec23576530894bcbf0ec0bfef0bb64f" +}, +{ + "dz" : "2e889f44e28901e9ac7ca6b2fffcb124c8979401b17064d7e1d51a7e3c3adbfa0e145e44aae52cfc609e6f47fd7a6f6af877190ff52256d0ac5b05b89c3f449f", + "pk" : "10489b6e431f18744974e86c075394189349b00b1ffd5cac6072cc10217b0e3203e3f61e1d9281c2d208af83a7f071ba78546e273271ac1cc01a320f35e845f10c59bb8c97e1627603e51a06e532ee716eb83519c80a4833c7ab45e6951137c0f731964ed2197b033e17bcb5237a1128179a85d24f730a6b31ea0e52075ae2198b48106ad0e1225701313af1a7b675347bc0ca48d88c4ff054edcb1092e87ccf070e10dc093bcc9bd400490250b7dca3775b715f218448caa01a8d8c8c6577cc9f21a7e3e6208b2c42215794954aac57712a3845523c74960b57a97e0c310cf7b8798192eb9507fe65020f706be129774f10794f2296abd13587a78456b083a164bf23c801969a57591062d22bab23b61e7dd5b31bd54520f4080a4c6c01c6603f4b4b1aabb99681be0b9c671f496f8cba2a571502e0da35ffa9bd2c77a5e66809e4d54000b851b2226e23c1072253826f374842da312ff0931b7a85e6186f5e6a31276a2d40a81fbe135e2c86c328b896f07c2269f983b313cd92578882a321f0031fcb9a9e7d618fd3d543e34abcdddb98d4c4585cbcb67789283c442f8c5cc914427fb1a53f3e35b78c2110ba956defa035084c53cc9b6fa7946e11840087e8194db6607246c7b314ce7644b8e522cf494a6333dbcc23da197cea95c318797ef0a18c84bafbe968df375fd0c9981757aa8c878658722bfc2684e012af3b30a067ac996315b0cfb13ec45220c9447ad4374c78484ac652921328214ca33466f6024abb7a78cbb528c44a339638eef09d3ee370d3a1746053629e7a37eb2600f2f73eb9d572030598042315b093c0082456fab06ca2a4c9bbd4c651bb297b494fe7e38d5c8aa3c7cbb6f1189d4a2c02de0acdd0e2c7ffa22e83c63623a21dc137c00e07193bd28264ec0fee2259ff2362ebd1c252103d93645e92e398f46935109bc0cb50c619424db0461823d33fd8d271727554a4c86a5113a17de7bd17b47cf04bced6cabfa7e926993b57a6c0a693e251e3b90b7b17195ff037fd867b87109a8be90403060cb34b32688c263eb00194391ef6c978db4c83c8967a735895a70b6dced06016b3737015696f1a1945110a44f022472c0ffbd049c0925ab1d68ef3f775308c2a95e99865c04b17b34d28a1254c433313c972a7f51a48696db9d7ab71d4600c0563b36437fac1ba6ab9ad6e89630357485dac1485e2808de8869ae59fc6a952890c69695424e3bb9f27aac2199301dc6b36503699f2504ac5e35adfe08048f9842df3260abc3d209a1311d65c048b58111bc7fbd6953d21b56364a51d9c2419072dece82b9d93aeb99c3f0a5a6c3f276504c3697a7c19563abd84068e8a39373c1375d848400c663c44e6c968c3c61fb375eed10baa60cf6158aa7e39c99e609a8b0765e36a2fbca515e4581a0207ac3fd5b3b7a95f193a08511109f335cd1dccc09223129da93aeab93ebf397bb073bd6374634675b6386caa33f71e04b1b420a2036979acf22835fcc511186441e1f5858402af78ba99673125ce9331b6686821ac739fe41467ec22736463ac4415db238bdb9a32e1895e0445aeef16b12e818f33a435afa91f850549ed465fc026163f988582040274638eada37dc162bb2d2839ca934bfa44acaec450ab4436ee78a5e658134bf80f914052be1a605e69ba87005f4042a25569c29243157865c5bed6918da360c4b824c7ebc8157870962737d150ac5583907c0c0f0603b1dceca45e10467ecc3a4435355af8254aac26f411a37b2587f40cc023c1c497664de5d705fbd0c103e36875b168c1c732ab364e1a4726c1d8207e1830d73721dfcb55557352a6508469eabccca2ca706c1de5fab0a7647d2cf7b05e117998173c5b3958d483491f128f01889fdf00d0b668a857479030f0c16bb753794719e4e142f0c5a1a52445de8862cbe3377c383deae1817b8110e045321a16594fa7c1d1037fbcd2208158c625514f3464237d7c73b0dcc605fba342cb6fbcbc71391577ac3781adb39d4b1c2236a4c9579810d039c10fe556dd954d71e705c6fc9389f3be0089697dd6703d8bb8ff08c88bf6773082a56378b52bfb30182c9ae1512ae1c2b9f99b4f3d0b20f8593bc530c585d737540972bcea60e11441e07a9c6827031363990b383b6f42afebf55e5f20635ba731fa86c24d6908aed77e3a57b2138c0c83a5bc98ebd3a002c0a9c6", + "sk" : "5bc2b53498cbfbe8cad9602f75187bd676b0b4995353374df1c4aac9d105b8172badd17b6707b89ca23568f5bed5969479557cf8a0abfa8b4913a7bae3720fa73c705655cb39c48137d2b0878429fbf44a0297b1dc71496de1c341290865d60b8bd34c761933b3f7cd78e42039a4377fab7c8c82b9cfa6b0358b0783b766e3a598afca3aecc59d0eec2d35a0a55210a94eb44377634a1c097635d851d022c5f15838bd299f6e1a2c7e8cb330515f595966ba717e0da12a2dc84e16902e6b022a48c4cabd27993e5587cfb4575fda0e67830078d01935e4b47861c893d3c59267404bb2238ca14534823a3e1c82a97047f1b32388c96f615c729feb7500125e17881bfeb2b7425151914c5bd24b479ea33bba133a56fb1bb155ac34aa2c15d77588ab13ed53432bd0bcea28b79c9cbde8e66d75e6ac227224299a3391a38be9ec2154751729022e588b341a062f6794494b0b549b0832d011ca6d04c976d76111f85456ac9c21649106a8b58b359c943aa7722c0b737393f5c9040e0a9126dc8ded3703ee7298e1424c18c2492fa1573de9b77ea9988ef88db2a61221c8729f0b0c88773f8f9553ceba7ae0d6c9ad7ba7919741fa140e0703c96034766b126a6f992bf13381366121d0205ef45a9515b5a05d8c6dcb293ae44469c8875c40813db41a06e935c80fe24ea9e178edea641f48519d6a6e6b0547c4940ae1178b234bc06f07129a6c9287dabd64f151f0f2be8bc9b988b71341c74164d430fc6bbcc4e23d36938e2a4a8ebb8b5a0d906e428089e48946b63bb2525954323421fcd76bb00245ec4761c5fb3ee5f255ebfa33f64584f6dc971189a07bb19479f99247c11b3318076c2c9c08457e35aa25973a31e1f0a82355916d5891f193b0c45bb1d496091d7a47a33a83a5f34ebdd9b8935601abd60768fa5c2ff2bbf2457aba1523a3007e09b90a400a0c8b23beae5b48d6e9c642d985376a09b8ca6ddfb493ee37a0f6551f9c9208229a36cff883c09b5239a55680967648116010645450da2175ec5e4a452c982ab3ced778a802644945678dc514daa144efc4b53a153d6737a6dc3515c4744e39c61f9fa8522f39384738c99faa3a7cdb779b9a7b75a5603ac55bf13620b647692f40594e144c378a3b5041ac1c63034198976bf9492b7393de8455c284b1d3b2b773c448539bb493a9a8f1fc39045917f40a8cf2a052008626423328417478856c1cb67c36a34507ebf38eec630ae5a73f7998344cf7be33268fd99492d895aaadf5164df7429af1816e516f2717a0f6d0858b3a0119aaa1cc041eb5172d465184ff312e23f766ad29746e78aff74abd65a2af2a0ca0b65cbc1f1a9b8544446c28c010da1dffb708d842bc82014cceea6784a35d74510503e8a8afb7985684253f000bb2c95524c0827401ae9b058bc65896cfe43b9acb3a00a475614136930bcbf0ac993e61236c24123105a6a70058a8d49a11931875f48f69a074d1757876f598a4a665ae6278a8e27d1591849857c42fd2a75dd4096359c4cee2a42620b62ab641da1bbc1ff4acdf2220fd0751cc8a3789c06500765c632a32bfe88d0f9bcbb9303eb1f6cae94a45d5f537c7eb7205d81c65863216f571d3babac57a6520a30a76f4950628cd46b88ab8f4c88fb33dfdb13089d85bdc7550647b257dac3c6484cf0e881b83f241b5d869b5076148607718e43ef56572a3aba527595c25d541ee1477f50773cc433d573b8c1599295b01b321c7aac1f001c65baa0d63650fc8c45f7312d1a7700fa1bf92092768c406934a8bb3c94951f17fde83804f2608d292999f53872b167d2c4c17cfaccc9ff37ff7542e6d097bfa414ede2453f2328408f0580aeaa7e67116cd895594452458675d93c03177c31bcfb57cd173006548966bbb6cc628c446576e9eeb602810a04fb126b37c45a6e4041df38330812fa517117400ae7f429ab1a610d9d09e9ed36cee0401d09a0d847b3dd2f826eee3c841b4526280225d106eeb183c816a6b8387277e588712279cee18c34d3162878204d4506f659047a9e126dfc756d946892d991b4bd406c83cb013fa8a9e7758aac12c0f0bb6c014a048d5457309a125aab0759aac0bdc347dbc7eb572386d71569198c6f0a6c213c44a14a22ab40a7f34d1ac821972710b8c10489b6e431f18744974e86c075394189349b00b1ffd5cac6072cc10217b0e3203e3f61e1d9281c2d208af83a7f071ba78546e273271ac1cc01a320f35e845f10c59bb8c97e1627603e51a06e532ee716eb83519c80a4833c7ab45e6951137c0f731964ed2197b033e17bcb5237a1128179a85d24f730a6b31ea0e52075ae2198b48106ad0e1225701313af1a7b675347bc0ca48d88c4ff054edcb1092e87ccf070e10dc093bcc9bd400490250b7dca3775b715f218448caa01a8d8c8c6577cc9f21a7e3e6208b2c42215794954aac57712a3845523c74960b57a97e0c310cf7b8798192eb9507fe65020f706be129774f10794f2296abd13587a78456b083a164bf23c801969a57591062d22bab23b61e7dd5b31bd54520f4080a4c6c01c6603f4b4b1aabb99681be0b9c671f496f8cba2a571502e0da35ffa9bd2c77a5e66809e4d54000b851b2226e23c1072253826f374842da312ff0931b7a85e6186f5e6a31276a2d40a81fbe135e2c86c328b896f07c2269f983b313cd92578882a321f0031fcb9a9e7d618fd3d543e34abcdddb98d4c4585cbcb67789283c442f8c5cc914427fb1a53f3e35b78c2110ba956defa035084c53cc9b6fa7946e11840087e8194db6607246c7b314ce7644b8e522cf494a6333dbcc23da197cea95c318797ef0a18c84bafbe968df375fd0c9981757aa8c878658722bfc2684e012af3b30a067ac996315b0cfb13ec45220c9447ad4374c78484ac652921328214ca33466f6024abb7a78cbb528c44a339638eef09d3ee370d3a1746053629e7a37eb2600f2f73eb9d572030598042315b093c0082456fab06ca2a4c9bbd4c651bb297b494fe7e38d5c8aa3c7cbb6f1189d4a2c02de0acdd0e2c7ffa22e83c63623a21dc137c00e07193bd28264ec0fee2259ff2362ebd1c252103d93645e92e398f46935109bc0cb50c619424db0461823d33fd8d271727554a4c86a5113a17de7bd17b47cf04bced6cabfa7e926993b57a6c0a693e251e3b90b7b17195ff037fd867b87109a8be90403060cb34b32688c263eb00194391ef6c978db4c83c8967a735895a70b6dced06016b3737015696f1a1945110a44f022472c0ffbd049c0925ab1d68ef3f775308c2a95e99865c04b17b34d28a1254c433313c972a7f51a48696db9d7ab71d4600c0563b36437fac1ba6ab9ad6e89630357485dac1485e2808de8869ae59fc6a952890c69695424e3bb9f27aac2199301dc6b36503699f2504ac5e35adfe08048f9842df3260abc3d209a1311d65c048b58111bc7fbd6953d21b56364a51d9c2419072dece82b9d93aeb99c3f0a5a6c3f276504c3697a7c19563abd84068e8a39373c1375d848400c663c44e6c968c3c61fb375eed10baa60cf6158aa7e39c99e609a8b0765e36a2fbca515e4581a0207ac3fd5b3b7a95f193a08511109f335cd1dccc09223129da93aeab93ebf397bb073bd6374634675b6386caa33f71e04b1b420a2036979acf22835fcc511186441e1f5858402af78ba99673125ce9331b6686821ac739fe41467ec22736463ac4415db238bdb9a32e1895e0445aeef16b12e818f33a435afa91f850549ed465fc026163f988582040274638eada37dc162bb2d2839ca934bfa44acaec450ab4436ee78a5e658134bf80f914052be1a605e69ba87005f4042a25569c29243157865c5bed6918da360c4b824c7ebc8157870962737d150ac5583907c0c0f0603b1dceca45e10467ecc3a4435355af8254aac26f411a37b2587f40cc023c1c497664de5d705fbd0c103e36875b168c1c732ab364e1a4726c1d8207e1830d73721dfcb55557352a6508469eabccca2ca706c1de5fab0a7647d2cf7b05e117998173c5b3958d483491f128f01889fdf00d0b668a857479030f0c16bb753794719e4e142f0c5a1a52445de8862cbe3377c383deae1817b8110e045321a16594fa7c1d1037fbcd2208158c625514f3464237d7c73b0dcc605fba342cb6fbcbc71391577ac3781adb39d4b1c2236a4c9579810d039c10fe556dd954d71e705c6fc9389f3be0089697dd6703d8bb8ff08c88bf6773082a56378b52bfb30182c9ae1512ae1c2b9f99b4f3d0b20f8593bc530c585d737540972bcea60e11441e07a9c6827031363990b383b6f42afebf55e5f20635ba731fa86c24d6908aed77e3a57b2138c0c83a5bc98ebd3a002c0a9c60409f3dfebc62eda14a11b1c03d59d46382c2c2a579009c0355da8a58440c49a0e145e44aae52cfc609e6f47fd7a6f6af877190ff52256d0ac5b05b89c3f449f" +}, +{ + "dz" : "174aaa36410566dc15a5e62874218d7abdde0b2c0f30d877bb80b1abd5f5a0a450a7a2354f7e5cefa6f4a4e9a1c411eb9364506e9e1204a8acb3cb77fbd2c4ed", + "pk" : "0dc34b0fc991bea47b02a8cae2f81a10043ec8d655124b3ed56505296c5aa2227ce2ac04a0a31ca05575b2e55c01119d6588cfb529aa54e707155bb4f9a63966d9566bb65a95287591f715e6bc0d7fd1691129999552b1771b35a322c5145c7a40d79d6d9c3eadf941112c4f76d678cb0aab59b9a30bbb340e078bc2899951691f9bf84189a87f2af590f881027a489ea1bb89e3a8b65959ad503a5e051c5f398a654c708f9ea51bf75c6bfc25634145076a93aa6e6640e6b47158ecaeb621c606c065972c9f26a34736067161e6bd49fa2871631aee5b518ddab90f692929d5a7a6e76582e53dcd36acecb6a76dd9455358ba95eb8a70d3786c01960b367e15536b456408e4faccaaa139c8e9737ad6b8b0e380bbac446c73b7b388b319dc2047fb7338072a0f225b506253afa722c812419e9c739c90beed97ba8f684111900e7d1762a5c0903c390786e1445b615a1e054efb7b0b1daaab671a63cae7b55c8b6f13f10d55707650ea8d864c7e5217b572643e6c7480411489c9ab18400483a657185990bab58b6a734596a6123dfe5240b2f908fc8c3591490f89875e0ad3b06f6812ea973e6fb0a69886199b3b55b7d26a55501b43609b3d6a3981cab946049c10b5737daccfb2040e014a5f715b4c1f8b0406b3a3204602182450d10b019b388bfe31b5a5a9794b5863bcb34cf6f659b25cc95f0a42fa9305a0d647342845d5b28ff5c1727975bb48c5ad2c96b97ddc3bd4f0b40e9b6fe1138739f1a9ca3b969cf33ccb700fa9fba93ef565a8aa180cc3711974bda14ab85e3817ef4801c0c3b3f68403bc94cc7412ad044a220750b6ca963e3e052f310bb1474623f707157c8a7d67f95989492278ca5707ea6d106431fa5a3b88c39e3e360bc0288925932d44a2523b0980a221519ceaa65353a7483b7de6028744a2869bbc869a58bed2327b3c6a4aa7447a9a09bbbaf322d5914dc9d5a1ef8aac92b920524c6968289d7da06db2561eeea26fb764168c185ec20ccf2b57a89f2887720809e94c377b313cd5ebb7f71037bbf01bf85b675432b891850316f6b938231793aa3aab2972e979c7aa258735858434b6386cf0c5a9232f60a70624b4cbe9f10fc9e3a0d7605bcaa23ab49a222f66127a1a4b9f2bada03c8dcf330e1dd90131852b71cbcfcee91f528377d200433dc898c2118f7b6275f4e0b9a97028e759ae0c77477cfc26a1398cade7671ab89344140f5c3662c736107205a2cea71c3612c4eb063cac777b9d6b61cc0419fcab4908ac161674c6b4c58c53a5065c637d0a4c964e29729667aa949c39ea0797b6882951314354ac28d52c2096049df866bd028b1ac3b47cd2e648eb322134522ab2993db33491326a625e8739672551562b2829ca57ae6518dd4553146281fa57aa373412f22c2d0cd02b6141ba29f31612447deefbaf8f974aea75140db2b85de409db834c283440e377147b2b8204f09da14028f1960fd7c6b29ec1bdab0098ea22669d7123d36a52dcd634a447209bdccea731b47719745597955d3372cc533cc9b59712e770d7cbb63cf114cc02ac9933ab248617b9b284a8763a8856afea63c442ba7407905c6db13dde25a24062b7db428958e2b72117652535c1c24226266bcc7e87a721181ced66cd9dd1c8d86a1c28d0c335b66eaf7422c1bbb3a7dbc7f2a81c7a477a35717a23b486f307c766f1291be3afe8408026352d28a826a7e57819390f3341bfb8e258640213bb06b8aed87eb78b216971060b590f16d05d83801404ebc63b7304a0880062b4c1e235655b43c2b6062c28d4064a1a861a9844544776e8eaadc0ca66b2cbbb691460382b586e77856b8085a1d6795f82be8185c62ed79b2bb8a3ebf57150145892f99a27ec8d1701265cd16b5f5293955400a44192b0e47f399a0bbb9027f9d3aa1f5407465b8b28e2a87ab881be300fb72047f61a53b1282c13b65ec31045b1e0b779580017e1776e46a5018598799296f49c1447370af1227a7c000e327b40ed2965ebfc7a555803d4d34176e14bd6f9905c5c4e253062c1110dce0c22e74779f07846a6806eaf340bec965dcbcb1a2c40a5e6428d2bfb50ceab3a64cba6aed667edac0cbf03ccd8d8a56d73c70b122628f90e4c760ea21c485a0536f6f1632f900e1cb13208f442501c6cfd05027f5fae41abece025084a5e4598a766114b13b17dd16a4c99f255", + "sk" : "55fb671a41c8a2850965768b1ea68a496a772291ca1bb79aaaa07b542678f391bd786579be185f883cac4350621fe531dde9a3729493e1e71530a5261a4cc20b41847d815297ba8415954ac0307543c34dae9b5007254c18414a01ac0fcc55707d906a73ca41a2167d64470b9cd6c082a27fdc62b7711b2c6d4aa9fa00c1348c7666b7a181bb0b84617a9f67bc9825c0e2011b4cc5b1c3f243501a56d27cbbe2f73897332f1bf57edf885f7a462d801089e9d96d14b9a891a909dd8aa7205545fd319598d3ca93e13eb0219a3674554c45238890cd54bac9bf3058bd0a6c7de7c3ccc98ab53c99f1e0bcd0f975d51c0eb11113b1144c8f46be95c11b6a7909aea01e3cd013a274354118b351e95c043073f4a3c0f8fc5d50570540281da1d0cd7401615eb29d4c15b8562690d96531e48003478b805e222043c0611c276940d58e41900c34862f0cf80dd072ce0f8cb6e948cfcef439333ba87dc04031711dd7859855a4493d4462d5b08bfa825c0a01972c333ee1291dde850a33eabbd83ac27dda737a0aca9692b197358d82438fa24c7721773a61a52cd2781640ab111b588fe4f7a8ceec4136115d30e325e5160975dc915cab6369c579f2240881a02276938845ca6c679942757263cd4216cd0c09d01696cbc83b84b430366c2a73207a586b8400f4a9b098bd53a222a51b31b3e1a5a215824f268790d620754c1a387001bc9a3605d94360f9b50ba29723d8088a0871a0b79badc669cf18bb95ebca4e53106160a71eecbd492757f2e98c27a47fba13c7519399cbc2a2121a1ae5376594159ac23b856888a34026904a3734141bbe75904d9d727486e644d7d1c7eeb4b7697ac925dc9fea40421482ade07b35879342b71426c8e21ce9ca3081d62e615661d1168e102779352571d884c1104b760e29bed2bc4f5e01bef7322d1ed2a8c0c882798781310197828792430530443481a253ced84b8b7ac4736452703298519d41bd59cb3c32a2271a592a0f754192a6672607a346fa3997b360f0a75b423397b2520cfcc44c0197c7c7a6443154ac6f3985c1256a0aec9bf72b1d8dac046c7376b6a424b5324ba04881afd25d16387c43aa57ecbb9caa055c6863339f420b09e1cc665982e73997e23179234250b5c047a9e5b656169734576fae1b970c15a9bcabc1742792e2a9bae6c29b391b6a91136e31abcdc859ca9d3a7a807c36db195c1731ad11da6afb304704475ce0c3a73b42be27172c8f2824fff7b933102d1311a310444a73cb2e71a9aa6b482c73317689235b49f44c7af6a02d5ab3547234944bce390756719cbfc6370b18ab828a6971f770182422a9f2eb2c8523605ab228026797fc1721aa942ae8087010a5bd2c2886eff0a29fa99daa8a91b8a1c6395544dcf07586ec99e592b995074fda2a716d8a86fb1005a380878c07243d708b1bb15bc2e639cac28011e461c34c17a47a0e5e07bed0b6761429b21c04689df8a2aa22400253801f41196a02522ab49c1b724107012ee3c362ce351f774c8943832f27732014c8918b2c8e747bb0cb531a3019204a441786ac3dad4532a508147a334fd772ccec01a07c021e2b59238d7b57d24a8f4c90b1b7a7546144c9fff2bd9b931eeea30fb2677d5a3bb24ffb4c15c0a222f151b0fc3b2fb68c96140c22765e36d471bda76bead7baeaea3e86296403a673b0c60389a66003da689f42c73471c0025364f86a66826b9e03864781073614d90eebfa1f266c4255823a37258f51c0839d2106a90171f1191035310abcc8522d814310b488e51bc7ae20c8597cb2ef11645c9b921ca2424f3780d6c87a17a9ae9fd0a5b15c6d9085c6e580a1cee699a624046595401a370912381a5a9731e3f3396070c2e2795690abc0383a71ea4aba69459123aaaceb99691a82c729d028bbd69ec903a60acc9fad24cedc2c391c4007dd324ca46581558cbc0bd4a397a776db07c41eda6c24f436021b4b269b105d33ae94a55594e70232c15cede461c40742bb950447064d21220e41673f98b57ffb9a23fe096dfbb4417e024ad4121a824274c75c7d457794c9034364aa1681c79ad7f3c3e308ce35ab8704ec566eb786283a9ed8eacb14e24ca349a581598e26967b88ba5b3e4a1bcc9c13cc74330d6409e0e1057c125aaaa4ba0dc34b0fc991bea47b02a8cae2f81a10043ec8d655124b3ed56505296c5aa2227ce2ac04a0a31ca05575b2e55c01119d6588cfb529aa54e707155bb4f9a63966d9566bb65a95287591f715e6bc0d7fd1691129999552b1771b35a322c5145c7a40d79d6d9c3eadf941112c4f76d678cb0aab59b9a30bbb340e078bc2899951691f9bf84189a87f2af590f881027a489ea1bb89e3a8b65959ad503a5e051c5f398a654c708f9ea51bf75c6bfc25634145076a93aa6e6640e6b47158ecaeb621c606c065972c9f26a34736067161e6bd49fa2871631aee5b518ddab90f692929d5a7a6e76582e53dcd36acecb6a76dd9455358ba95eb8a70d3786c01960b367e15536b456408e4faccaaa139c8e9737ad6b8b0e380bbac446c73b7b388b319dc2047fb7338072a0f225b506253afa722c812419e9c739c90beed97ba8f684111900e7d1762a5c0903c390786e1445b615a1e054efb7b0b1daaab671a63cae7b55c8b6f13f10d55707650ea8d864c7e5217b572643e6c7480411489c9ab18400483a657185990bab58b6a734596a6123dfe5240b2f908fc8c3591490f89875e0ad3b06f6812ea973e6fb0a69886199b3b55b7d26a55501b43609b3d6a3981cab946049c10b5737daccfb2040e014a5f715b4c1f8b0406b3a3204602182450d10b019b388bfe31b5a5a9794b5863bcb34cf6f659b25cc95f0a42fa9305a0d647342845d5b28ff5c1727975bb48c5ad2c96b97ddc3bd4f0b40e9b6fe1138739f1a9ca3b969cf33ccb700fa9fba93ef565a8aa180cc3711974bda14ab85e3817ef4801c0c3b3f68403bc94cc7412ad044a220750b6ca963e3e052f310bb1474623f707157c8a7d67f95989492278ca5707ea6d106431fa5a3b88c39e3e360bc0288925932d44a2523b0980a221519ceaa65353a7483b7de6028744a2869bbc869a58bed2327b3c6a4aa7447a9a09bbbaf322d5914dc9d5a1ef8aac92b920524c6968289d7da06db2561eeea26fb764168c185ec20ccf2b57a89f2887720809e94c377b313cd5ebb7f71037bbf01bf85b675432b891850316f6b938231793aa3aab2972e979c7aa258735858434b6386cf0c5a9232f60a70624b4cbe9f10fc9e3a0d7605bcaa23ab49a222f66127a1a4b9f2bada03c8dcf330e1dd90131852b71cbcfcee91f528377d200433dc898c2118f7b6275f4e0b9a97028e759ae0c77477cfc26a1398cade7671ab89344140f5c3662c736107205a2cea71c3612c4eb063cac777b9d6b61cc0419fcab4908ac161674c6b4c58c53a5065c637d0a4c964e29729667aa949c39ea0797b6882951314354ac28d52c2096049df866bd028b1ac3b47cd2e648eb322134522ab2993db33491326a625e8739672551562b2829ca57ae6518dd4553146281fa57aa373412f22c2d0cd02b6141ba29f31612447deefbaf8f974aea75140db2b85de409db834c283440e377147b2b8204f09da14028f1960fd7c6b29ec1bdab0098ea22669d7123d36a52dcd634a447209bdccea731b47719745597955d3372cc533cc9b59712e770d7cbb63cf114cc02ac9933ab248617b9b284a8763a8856afea63c442ba7407905c6db13dde25a24062b7db428958e2b72117652535c1c24226266bcc7e87a721181ced66cd9dd1c8d86a1c28d0c335b66eaf7422c1bbb3a7dbc7f2a81c7a477a35717a23b486f307c766f1291be3afe8408026352d28a826a7e57819390f3341bfb8e258640213bb06b8aed87eb78b216971060b590f16d05d83801404ebc63b7304a0880062b4c1e235655b43c2b6062c28d4064a1a861a9844544776e8eaadc0ca66b2cbbb691460382b586e77856b8085a1d6795f82be8185c62ed79b2bb8a3ebf57150145892f99a27ec8d1701265cd16b5f5293955400a44192b0e47f399a0bbb9027f9d3aa1f5407465b8b28e2a87ab881be300fb72047f61a53b1282c13b65ec31045b1e0b779580017e1776e46a5018598799296f49c1447370af1227a7c000e327b40ed2965ebfc7a555803d4d34176e14bd6f9905c5c4e253062c1110dce0c22e74779f07846a6806eaf340bec965dcbcb1a2c40a5e6428d2bfb50ceab3a64cba6aed667edac0cbf03ccd8d8a56d73c70b122628f90e4c760ea21c485a0536f6f1632f900e1cb13208f442501c6cfd05027f5fae41abece025084a5e4598a766114b13b17dd16a4c99f255a964f69c975bc276b67b828d04997c8caaf20600da330ec642633f9789858f7350a7a2354f7e5cefa6f4a4e9a1c411eb9364506e9e1204a8acb3cb77fbd2c4ed" +}, +{ + "dz" : "351fe4313e2da7fac83d509f3103caf7b4c64a4d458fefdf636785ac361a1390f072d9b5a99f9c7a0a011e4dc10f6b600d611f40bba75071e7bee61d23fd5eda", + "pk" : "ad4330bdc85f4699cccd373de5d7266e5530a73a42d10c9b327a57715539eb99030873689f47bf6871a00c6caa06e4b04a832c865b69293303cf838ac186b453d77088895db36163b1074a8e045911fa92db578cad284642bcbb44f844c6663f3f4c98cc8acfa1a96b6df57f5be10fc76477d306245670b2c796672331076f74480c2627a3a44421a01229509752a536e95ba97e85aebb920b4b1b1bc55bcb95fc76ed43b9805236cdb62861fba353f08409c91126661580123509c05208c8604389b2dd3b0f8fc94f432b41632c4ae1ca0bdac54ceabbcb743362725b839dc18add4b7795a025261139539641aa43a9c185621d13c33c579189244c884c047bab4187577c97639ca4abc631eba5e9b141e11b6aa8d562449c3ccd8757503a7ab358a24d2b36f2e1768fb24727801123354b6dc661f640883e0613c8886121b89336202eddc464204b1dc16b9fcd3906bb9a6cf8d6a176a43aa1b13200d67ad0e21f2f73186164a6fab968ea0427c82501c59c49488846489710d7976a5c812f78b5b7df2aaa6437054b0a03180c4a886b7d653149e8497b18b18e98e72f9815be90d252a4583f2de88c0d7bb10cea4d65ac1f59683db4ca4969a9b57ba65e06908f7e9267adc8c87e8b8d8d5651b234bc9ee1c65fe42a51368a041253e982100c25955bc39b70b36c67484f8df88c2066cd2a5339c471b60a1b81acc5922e274cea4a071eb71e788241ad1b7c41db1e972212e27c770e6720a7e67de941a1ca952bdbbc591ef78019c67dd184259bc873f045607d1440bee46f199a7d2274b4e40062c064368bf5c6d50046a198c89e1372950b7710b3b6376caa9bc32882a6b0aa9b7fae86cccad0574cd8b417047d30d41bfba0119b909142363d307a006265a3961c9c604a7b65384a5deb1c61f25f66fb3b7640b5c3e22b8ed488f08201a10c3b5a42b043965d4fba6f31b90c5a8a1d8b29a01d500be93225ab6acf77960afd2824f2283ce86288cb1a9b98c11b03dbbb0e0854731b22464331f6dc70e7e1771471236b5b26ce131649e77d46e7946b85593b2989bab4ce5d09ab8d745a64d53401bc0ca4855e54b20ca4811ae5d9192de398d9d65dd3a327499cc0ccaa9f9b2b547c5b53722b50b21c7bd2c3c7f67a15be8371e9d4583faabf2467a4d5365cf7d92b8de8a55de200b61185b89c83bdf817adcb67fc775a5bb19f1aa453b491cf1bfa8d51d0cc499331de7730877a2db14778052cba5d759e21a8cea550724f52bf25c2a31d7b117a4377f7a461ff92882e11a4a8c137ee5a4b7aa67f712838737a96faea898141a1b5165761401adbb650bbea1698267d324a3cb1d9933be8bc95d55aadc4a814f201ebf724fa024763563e2656b028053cbd16b32c20457349702702c4b453a277b318551c8b732378e3d7bc31a10b5ed975ab032fbff647c6340c2d5c91f68c1addb447fff01dfd4c0c9d925111948f001880b36588df16cd1b9bbe85973ce513662267214660340262273fb45f97f65da4e615dca4a6aa06c5e9ba0ff727775c84608611827c98c8b7717daa60004d2212dc28b4392a6e0333a77cb9400978b60a00a766f6264486c60af452fe92452156961f2467d013072f1c4cfbe08ea7885a74d0649517178412a1ac63261981adb7708dedc89b64e67dc2a8b25d98cb1ad74289372e48fabe360495b4a7472f3c8b7f877280ebcc6019648ef960ca23a1c49b684f947460e96f0e941408fa026c127900d84665768db52a8ec05696725b3dd82498226030b7189c9ae1c612e9a2c65c86c29426caf686d5b00ea0557466a1b04f8485a457bb83dc68c4b1cb01e7831e476453f084434151fc0c9ea3b7081ee00b4665048bcb8fab778eadf90c25f54d8f452381e252b2382d04028378e7cc7b3973cfb776249857cc611af8f91db8d5b9f5d90212b27d5fc9a794d53e3e002089a05a421a540b36aac5c803c8f5cd71012f176ca57a7a439db90bdc71ac65f0470d54188927bf3d2640e5a3a45d9021f876562fa7c6c2b37be9261393861c5f0336a47ac373e6874ec53fc9f90d856807675858ba1291c7134c4b8432f9782cf6855ae9d49226055d9c4b2f23c0238f20b516d6600fa72d8a5c2d06e1613dbb7fcdf9817cc299ef2614b6085517cca4006876de51659c317c7c9d15b2dfa3cfd29db64b6dee0f6e53b6bcee0ac31c086db16d", + "sk" : "0054c46a1943ae410f1d4b32823272687175a7fc81c1307f51e384fdf6168983525c430f0ba34722230657c2ce28f47fe354791b624ca6462f5634be583c822a55180dd8a7f00b21fc2b58d1a1746699ccd91acdde65280048302af4141a56000675448f00b57db19788678872abcc7f727af4e816f6a1b8ba7ab408ab03a28a28c0906d47b98b702b513d306212e96be12647c9586808025b74e37a593a47e2b00f6d505e38586885baa7fd6257d30c3ba38027f5d149a4d53ab5019386779423851f84c234931c341a216f84e503fb429183e8544018b78bc90c5dda2923b68ed2f47014683b3be50f17cc7ccb36b314b0528f8c7cbca19d936300970772af962ade7c7efc2602a9175fe0b11628702502a9a0143a0c7004ae1dfa2aefc3986c74348485a846981121250d07b78818302c41c20292143a9b5c6e22f61de390286e0c9c036b945fa5495a592ac3b2aaabacb11824614ab15114dccf02dcaef932361ea0621f860b1d399a22153140220497bc723a00791df15b6aacbcbfd5b16ee74daaf059e4b85e30e4bae4c53e2a133466413459e0857fc8c136e072f1b75be9a3b806335f5603a46c734edfe0994408b355442db7967682859d1a5b36f6a135f5100d259715e04c00236b3855fa25551334437198e2b317c1f54207a1b504475368d328b9d561ba33c9ac75231c127ec8c8b6807aa787b15c1bf756c923aee186a680acc4f1d6b3a70116016bcc3fb9a4d95b9f3596ad52895de27abbe0d42751804ec2f1818f5361eb68a9b0f8188e9647ec627d1751a8a5f37e6ed4a42e2540dc97272bb380195b75df18aa8709738f6207ba65affd669e3d23ae7bf1b7569aa9411561857921e048000a44819466ae28c631cdd68416e596abd9365642113b78901b1986f7b43f240300fd487689e63773c1555d1b4ece69304389074bcc99f1c88bc3068df61880d32c43b6326cfc11836d94aac626cdbdc6addef07086eccbf6f44850242a5d15219fa5598d45097171598cf6803e7b1110a04265544fff9612416446bc62cb3fe6718b2152292552bd05be6a30874111538af71b5fe08367f8a646b925e7d52cb4331ddae40e66302db02c87437c1ca03176edec873c883707ea0edc41a45c386a5782beef1c2353a97ee5a198a6e572a467aac63aacc528777d847ac835886a15415286b4e0b0c9089c6472c00b389353f0c6441d84bbd12bba40931bd2bc84270177c5db13dc7a2c913c4718a63d9470cf63aa35c705a37cda0becc0c024d1257590272d6a302f275595d18a679573f2ba283a162114f34ba8c06d21435474697ef301a0d8f50fac4324d32448940792a2c174948cab5f3710a030cd282bc97ae617bc67823bd33efd32af9861ae0b4a7d04b4b207d9cdd7244f23651424602d8ec1ccfd77a7b4317bf2504a06646aa19280a22b82a41157cefb3d3a08431d889e7afcce2c771bc5c604f71310983433cd59bd43a4adc2fc8776109beb59039aa70e8c1b8c7dc5bfed08c4789337efec6692db5cada88f0e3998e8b30e9a8897dd85cfd051c62bd9a9e12b47aa4015dd156616682e1c299357d57a2fbb22c2139cb562971c6360a7b607d7e2001ee26baf0b5957f73f8d94acbf8b3c56a3b72b11054febcf21c95d9ee82b70739846f06eb9966e280a8b007313d3084cf984cc1f7b34d7243627eb70e558b096644feeaba78541a06abbaf2cd331d8749247c2220e722deafcc5a76a0998d7bd62c50623ec183e4544f647943655cb5330381bf608536c81755319854296e2f3b52209ba9df6093536541fb654d0170c5901228a4c8f95914c1a2c87cf76a3cbf3c6a9fac15716001a2b7e0e0a8c00f984b08358e1902238e36046ab8da9ea35560313c476286e1abf559b407bf2080684b11bf44573f642002d364c35183a8b107c3952afa40cd68a22b666af575344be88a269e141ff171a6169a29a92a1b63cc1ddcc642808b6f22b65a8345ada90a992d91a9114480df287359b9b709814e425c1a397ad0714948ec339b96a229e5ac0fa985df1a19ed1440d1fc78c1fa77920abadc31c5256c52314cc970b72b0a6d84fbeb1b1f08657a636be530a5a8129a8f8137c6ffb5e5f549197dc2fe05259841b681a6393a6a7781fd03fcf592ec3b458d3027fad4330bdc85f4699cccd373de5d7266e5530a73a42d10c9b327a57715539eb99030873689f47bf6871a00c6caa06e4b04a832c865b69293303cf838ac186b453d77088895db36163b1074a8e045911fa92db578cad284642bcbb44f844c6663f3f4c98cc8acfa1a96b6df57f5be10fc76477d306245670b2c796672331076f74480c2627a3a44421a01229509752a536e95ba97e85aebb920b4b1b1bc55bcb95fc76ed43b9805236cdb62861fba353f08409c91126661580123509c05208c8604389b2dd3b0f8fc94f432b41632c4ae1ca0bdac54ceabbcb743362725b839dc18add4b7795a025261139539641aa43a9c185621d13c33c579189244c884c047bab4187577c97639ca4abc631eba5e9b141e11b6aa8d562449c3ccd8757503a7ab358a24d2b36f2e1768fb24727801123354b6dc661f640883e0613c8886121b89336202eddc464204b1dc16b9fcd3906bb9a6cf8d6a176a43aa1b13200d67ad0e21f2f73186164a6fab968ea0427c82501c59c49488846489710d7976a5c812f78b5b7df2aaa6437054b0a03180c4a886b7d653149e8497b18b18e98e72f9815be90d252a4583f2de88c0d7bb10cea4d65ac1f59683db4ca4969a9b57ba65e06908f7e9267adc8c87e8b8d8d5651b234bc9ee1c65fe42a51368a041253e982100c25955bc39b70b36c67484f8df88c2066cd2a5339c471b60a1b81acc5922e274cea4a071eb71e788241ad1b7c41db1e972212e27c770e6720a7e67de941a1ca952bdbbc591ef78019c67dd184259bc873f045607d1440bee46f199a7d2274b4e40062c064368bf5c6d50046a198c89e1372950b7710b3b6376caa9bc32882a6b0aa9b7fae86cccad0574cd8b417047d30d41bfba0119b909142363d307a006265a3961c9c604a7b65384a5deb1c61f25f66fb3b7640b5c3e22b8ed488f08201a10c3b5a42b043965d4fba6f31b90c5a8a1d8b29a01d500be93225ab6acf77960afd2824f2283ce86288cb1a9b98c11b03dbbb0e0854731b22464331f6dc70e7e1771471236b5b26ce131649e77d46e7946b85593b2989bab4ce5d09ab8d745a64d53401bc0ca4855e54b20ca4811ae5d9192de398d9d65dd3a327499cc0ccaa9f9b2b547c5b53722b50b21c7bd2c3c7f67a15be8371e9d4583faabf2467a4d5365cf7d92b8de8a55de200b61185b89c83bdf817adcb67fc775a5bb19f1aa453b491cf1bfa8d51d0cc499331de7730877a2db14778052cba5d759e21a8cea550724f52bf25c2a31d7b117a4377f7a461ff92882e11a4a8c137ee5a4b7aa67f712838737a96faea898141a1b5165761401adbb650bbea1698267d324a3cb1d9933be8bc95d55aadc4a814f201ebf724fa024763563e2656b028053cbd16b32c20457349702702c4b453a277b318551c8b732378e3d7bc31a10b5ed975ab032fbff647c6340c2d5c91f68c1addb447fff01dfd4c0c9d925111948f001880b36588df16cd1b9bbe85973ce513662267214660340262273fb45f97f65da4e615dca4a6aa06c5e9ba0ff727775c84608611827c98c8b7717daa60004d2212dc28b4392a6e0333a77cb9400978b60a00a766f6264486c60af452fe92452156961f2467d013072f1c4cfbe08ea7885a74d0649517178412a1ac63261981adb7708dedc89b64e67dc2a8b25d98cb1ad74289372e48fabe360495b4a7472f3c8b7f877280ebcc6019648ef960ca23a1c49b684f947460e96f0e941408fa026c127900d84665768db52a8ec05696725b3dd82498226030b7189c9ae1c612e9a2c65c86c29426caf686d5b00ea0557466a1b04f8485a457bb83dc68c4b1cb01e7831e476453f084434151fc0c9ea3b7081ee00b4665048bcb8fab778eadf90c25f54d8f452381e252b2382d04028378e7cc7b3973cfb776249857cc611af8f91db8d5b9f5d90212b27d5fc9a794d53e3e002089a05a421a540b36aac5c803c8f5cd71012f176ca57a7a439db90bdc71ac65f0470d54188927bf3d2640e5a3a45d9021f876562fa7c6c2b37be9261393861c5f0336a47ac373e6874ec53fc9f90d856807675858ba1291c7134c4b8432f9782cf6855ae9d49226055d9c4b2f23c0238f20b516d6600fa72d8a5c2d06e1613dbb7fcdf9817cc299ef2614b6085517cca4006876de51659c317c7c9d15b2dfa3cfd29db64b6dee0f6e53b6bcee0ac31c086db16d2a63040993f86bda57d8006a152c436e383ae407c7d9bd7a715a2f9efa507422f072d9b5a99f9c7a0a011e4dc10f6b600d611f40bba75071e7bee61d23fd5eda" +}, +{ + "dz" : "9bc5315580207c6c16dcf3a30c48daf278de12e8c27df6733e62f799068ad23d5a4d0a8a41c4f666854e9b13673071ceb2fd61def9a850c211e7c50071b1ddad", + "pk" : "2bf6a6fce45eb9d6a03f11858433994e304b2d379c43d4670be6c9d65a61e50c34ed26c67e716933cc5d9ea22d14f86e5cc54967ccc82e3506efb8cdf40c31f313135b597b3aa72fe83b01ec88a97e32464733107294270f82216e11688df6cefc2a9332243eb75059fcecad20a681aaa17402fb36c6e091728ab92efa891d141c251895f4c79fe2db4b2253114be24d22a38b9d14532ff80e384778c8b99a4303506d08303bab91d6e05c68a0c0affb5dea7344ef5ab21a559cdfbc3be395834b4b8d8d9c4af6a9ca37a34fbf05669f99af8bdb3237c98f98802ad76a26eb353c6612674e8b4f93a190f293c80da025da00aec20265cba37b0df43d78982e6ff49a9f464e7ff57680e7455f816f815c733bec25e4227ca3257336005d0559b647585379542eeaa8282d8a90b7a885b0360c4c9428951820d189b873e246e4d793fa94c0211630f54510f7f06d116acfa35c856f87913bf61cbdeb0554589dae65a2e25341e4b93916aa4b738714526653e798c11f24563b2200319c60343869579b74f2ba9ddb03c6f3479a0ef3a5e5f80183d69034968e25892c28c272dc501466621bc091c0fcfa09a2b56c9f8cca6cda208a523ea6a40a4907c1f390780d4a04624466206594ccdb1b19d2b9cc407bd172428316692e09229fc963710165970471e1b554f322c1548a118f84169dd9731bc8c49d1b0130287024c391ca027065591fd9755ffc2a68d36b7dcdac3a54e0ce67e432e35695a3987b1d4a1e5ea32934c1cbefac253da2ba9714ab6a4a46a07950b6477c303067e0e673fc6cc800a26fcfb59a01e397f944335eec26002889b08a26338947dcca758eac669929bb4c608f9861812e06aa61f5b8b56299efe95109d57c42c066ead511bd868c2b107522043da8356f617c26f7082b078234b435c478d48a53d5a369f7907ce2be8370c0ba7347707b7ffdb25e6bab2fa85b5922e0bba7269fb7a9799a158f9806bc3589268d8514134aab1dc83d415a235ef49586133de1ba59b8fa1ef5493cf9dacbeee04f4b9a94b3daae423575682311bc70c49e65090a87137cb327419a2f2d5481d6b10044c6a551eb711bfa828a3cbf22e026d2345dca2415b6d9b03e9479faf589ea02a12d1c03939935e8b225d7c18534a2cef060456bb58145337e81f7346e057bbb98a8c0a312f784351dcb11a1fca7984a2443b409ba903c3024b8da9a8b6aabca90b74a34b532bf01c7c1c1c7ce05bf08c5c65164a01f64c86797317dc03b2d69c263390f9e411df4f4508d7b03c7b473a7e195e8338cae5b89b85465779029c0ac711653b1c7a24bb3b9bff0c612887c12a39c2f5bb2920313cf3522396eb79065bb1e854a8956f7ac2143abb4136b0682bd01275506a765175c4b7648a0dbb875e2864d52aab697533512164be2659c57151c4af898d689a8619726406110faa69f61320e75d3a05cc27febf609e52026c10c01c30118ee3693a7293f4f7cc4d9f84ec37c5f38890a6a58afce1855d4d0ce1f0a577790423115c59228b96bd62d68d90f4bfac9f17a7597a492e5711b65d8626e568f0150a458201c6205a81fe74a591b547be842765723b57503c3b352478b304c39b22b147bf6b5bc489c2dccd44c9f206b7cf58fb3faa3c8891524faaa88479b0c4051deb63eab53822f84935566ab7978c1b9e5cc043767c109bb4663960a534a750cae177aa33315584138138d52648aaa5cefb09f5cd58d008d4c69a1c85a242dd63a997385b529a288758c427ba15b05642c230c8a0180938606c6e1465166f128a35ca3855657ac1b3677a0a15d094ec68caaf90cc1958ba0dbc22169f3853f3b7d56f4bde7bb2c1c71c8c4c95299d95873f89a17a4583bb9198e0279a45691a3107ba1294726a385ed95163f0bc3c609c01ee201c5900eb763518f212f14723314715e7bc84b75a611c481cdf858350de0495d1c020228b004624900c300cd018166fb4dd217cda3c792da49a87a3bcac52542f3b3243f689ce69c1946a134a97061c83134ac52c92d97a458b7b38dfb7f42476b6c5c272c71065e5159121484d4a541311c97fca3488d13b1de64610483cb3a9551cf4a3317d0c76766c777e526595539ad17bb6c184aff73b6c4eaccd5a14ed1b1b836975deeeb8909458146938505dba5dad77c1a3acdab128b36dc1e94a121c545e3515ed56687f8911eb5e172", + "sk" : "c5aa9d405bcc9af610795279ef2403c6f92389332592d0adf1b3a5172c795b483e1f600f2c79a7a683574076ae8941b68fd17793fcaa9cb60d39373da09b827662835ea227ab05845853979910154dca8ba44c1511172123ea658b519a53695e1315accd3c5855e03c1e40a50e10666ba253ff23b1377830ca1a485f656b24662dd3eaad239553f3a50b2934225b2647658aa1a21828a413944a53135ff9516850a2b0a66b8d502a17322ca87b3c09866059942bd8eb4f44d646e5a80a38687dff595e92b2250c2331dfd2495964bc03a2ca5066cea671a5cb0ba079788366376f8078804e98c9493a9556d044e7d218ddb83597f9bb33369266711f0ed4514582b25f04aaf1d0247c5624eb5555d0b08c14d307b7084e41e1185465c193ab04d4295790e4451dc25491796d4b3c47b1051d021a91440b869a75848e9894c8d393c534c4b2ac1318a5cb482b53f9ba76203331e87569803b0fc2e96072f777f61b008941642fdc76e9744faf9c6f06c381f5d54492eb6ccde84f09101501c60ddda80788c4619cd48defd9a9ca6576dc451101d37d422350b4357c49a90c291aa393263cfcf887c1363769c40c76530877dc9cef88bc13f740a8612ab43599933b7a3a7495a03800b9dc66be070d8096976c85962f3c75bad40c71457e5ee929386c7f65869f3e3c067512b2256112ffe557881b873bd313a021851c581259c2cc1f3617b38cacbf4a5bf2346623f2b316e4c82cfc9c4ae2c08742709af023b91ccdfa0b829fb047661c8dfab33bc9ba334328a8f22419f2f8768039c098806937c05cedf34a8d65930b07ad66cca3ceba2de45694cb534f7ea881c2a2c8df9c9f52163feaf0cf199cb81f1c05d1ec3774c203961c2d14c307bcf4716f69b837b7c894843766700cffa87a5b6b655fa304d8b2a8aa32637af967814b7915e5283f1263ed03469768783fb757f4b8385f7995548c75b98c24fed4b2a3b28729924ccd618a21f9385c5b577642150534c31a15a854179e1a0398df0c2c69a76816979f0834000378bb9f4ac43bd098ad6944b2cb028924b201b6cacdd87f25a67e676c738931acb4c42594a4ae4354cb87008cb2f486dd50a16e0228db6b547e48780e523b8841cfe8b636670ca397990550c540e2572349947d15cc46e186cc3197045d77b8dc85943c0abdcdf1629f4a74092a65f579b33f5233ed47916f1475aa284675972c7611c1f35c41cbe6a8f1f18f3bbca2f7d9380e2c9ac9126ac3287a09e80a041531d83b39591a9618232f990862d125a29b85a1de31bc4380c0c4f56e8a93a7a332a86d114faa06189f91b76ce79cacc88bbb2360599c0e9090226c82a57c5c1403745703f6b55cb9bfee17c4dd382c17da5585b823f9a037bad4101f07a301e96953e02a32a31326b04e02a52928293af67a6fb115444f4a4b58ea17ae716d61806094a301bed3015443abb0389afd98196611cb1e0c21c951517717835e7868c4bb8c958c630b0c78032367b5eb30100a15ad9949e8051c9bab638e8c0e271cab8a3a43998532469724979879dd46c40426cb49a29f987c9beeb92c1a393d6132921b019791d776728617597b0f2738916c99a9d889619bdbaff69050e6b0c906f3048b8811a8da04aab71a1ea85e2b07ab021c089dfa848800aba0d8838dd8af43d82abb6c664e363ba30b0e383214801cc69191bbd7913cceca3a45b52b9688957843bbf86112c70a64b0e2a1c3c89ac5d881848616ca3838c3647ae686568883550e93190eba3b1a08080b46373fd05f8ec81a535650c5281843279073c0802cd33a7caca35547c0740256f8b7ccb85c790aec85525759c0b22b15d268c9755bf020bf6c913074c5a4118bb45b025372dbaed0f96329c245052c8e831c5966105ed6d098a4e4527768cc3cdb47eb343788c9b5ad2b4ef15b24d8193b5e9b6611e3bcfce348869b07bba361035b54484257d1d65b3d11226f31c299607674c783b81aaefa6161656115be771991615a7e5a7b4becc21dfcb48738cbacd764d1b8b8b9080d6811caf9927a4bc68dab415628422b05530ba495101a9b336a896457837d6694bd568290e2259dcbc302ed2baa96292536b9a0154771b0c791b7ec8c4ea2489062160f8691cad483b020afbb076e0ee7c54188b32bf6a6fce45eb9d6a03f11858433994e304b2d379c43d4670be6c9d65a61e50c34ed26c67e716933cc5d9ea22d14f86e5cc54967ccc82e3506efb8cdf40c31f313135b597b3aa72fe83b01ec88a97e32464733107294270f82216e11688df6cefc2a9332243eb75059fcecad20a681aaa17402fb36c6e091728ab92efa891d141c251895f4c79fe2db4b2253114be24d22a38b9d14532ff80e384778c8b99a4303506d08303bab91d6e05c68a0c0affb5dea7344ef5ab21a559cdfbc3be395834b4b8d8d9c4af6a9ca37a34fbf05669f99af8bdb3237c98f98802ad76a26eb353c6612674e8b4f93a190f293c80da025da00aec20265cba37b0df43d78982e6ff49a9f464e7ff57680e7455f816f815c733bec25e4227ca3257336005d0559b647585379542eeaa8282d8a90b7a885b0360c4c9428951820d189b873e246e4d793fa94c0211630f54510f7f06d116acfa35c856f87913bf61cbdeb0554589dae65a2e25341e4b93916aa4b738714526653e798c11f24563b2200319c60343869579b74f2ba9ddb03c6f3479a0ef3a5e5f80183d69034968e25892c28c272dc501466621bc091c0fcfa09a2b56c9f8cca6cda208a523ea6a40a4907c1f390780d4a04624466206594ccdb1b19d2b9cc407bd172428316692e09229fc963710165970471e1b554f322c1548a118f84169dd9731bc8c49d1b0130287024c391ca027065591fd9755ffc2a68d36b7dcdac3a54e0ce67e432e35695a3987b1d4a1e5ea32934c1cbefac253da2ba9714ab6a4a46a07950b6477c303067e0e673fc6cc800a26fcfb59a01e397f944335eec26002889b08a26338947dcca758eac669929bb4c608f9861812e06aa61f5b8b56299efe95109d57c42c066ead511bd868c2b107522043da8356f617c26f7082b078234b435c478d48a53d5a369f7907ce2be8370c0ba7347707b7ffdb25e6bab2fa85b5922e0bba7269fb7a9799a158f9806bc3589268d8514134aab1dc83d415a235ef49586133de1ba59b8fa1ef5493cf9dacbeee04f4b9a94b3daae423575682311bc70c49e65090a87137cb327419a2f2d5481d6b10044c6a551eb711bfa828a3cbf22e026d2345dca2415b6d9b03e9479faf589ea02a12d1c03939935e8b225d7c18534a2cef060456bb58145337e81f7346e057bbb98a8c0a312f784351dcb11a1fca7984a2443b409ba903c3024b8da9a8b6aabca90b74a34b532bf01c7c1c1c7ce05bf08c5c65164a01f64c86797317dc03b2d69c263390f9e411df4f4508d7b03c7b473a7e195e8338cae5b89b85465779029c0ac711653b1c7a24bb3b9bff0c612887c12a39c2f5bb2920313cf3522396eb79065bb1e854a8956f7ac2143abb4136b0682bd01275506a765175c4b7648a0dbb875e2864d52aab697533512164be2659c57151c4af898d689a8619726406110faa69f61320e75d3a05cc27febf609e52026c10c01c30118ee3693a7293f4f7cc4d9f84ec37c5f38890a6a58afce1855d4d0ce1f0a577790423115c59228b96bd62d68d90f4bfac9f17a7597a492e5711b65d8626e568f0150a458201c6205a81fe74a591b547be842765723b57503c3b352478b304c39b22b147bf6b5bc489c2dccd44c9f206b7cf58fb3faa3c8891524faaa88479b0c4051deb63eab53822f84935566ab7978c1b9e5cc043767c109bb4663960a534a750cae177aa33315584138138d52648aaa5cefb09f5cd58d008d4c69a1c85a242dd63a997385b529a288758c427ba15b05642c230c8a0180938606c6e1465166f128a35ca3855657ac1b3677a0a15d094ec68caaf90cc1958ba0dbc22169f3853f3b7d56f4bde7bb2c1c71c8c4c95299d95873f89a17a4583bb9198e0279a45691a3107ba1294726a385ed95163f0bc3c609c01ee201c5900eb763518f212f14723314715e7bc84b75a611c481cdf858350de0495d1c020228b004624900c300cd018166fb4dd217cda3c792da49a87a3bcac52542f3b3243f689ce69c1946a134a97061c83134ac52c92d97a458b7b38dfb7f42476b6c5c272c71065e5159121484d4a541311c97fca3488d13b1de64610483cb3a9551cf4a3317d0c76766c777e526595539ad17bb6c184aff73b6c4eaccd5a14ed1b1b836975deeeb8909458146938505dba5dad77c1a3acdab128b36dc1e94a121c545e3515ed56687f8911eb5e1724016ac096bf081a60fd2726d6b275f550c50021d42608c49c93385828573f89f5a4d0a8a41c4f666854e9b13673071ceb2fd61def9a850c211e7c50071b1ddad" +}, +{ + "dz" : "d8b907b34d152ff8603b73051f772daa71eb902c47b7e2f070508269d757e02e36b817736cbc5f7b1dd6eef5fe6332fb1a598f3871e5470d440fd2ea631da28a", + "pk" : "26c68b1ba4659966cc95d79851f03e029a736c3b4809f9c366093967c53769b4796ee76b4f1277f1407b8c478fc1400de6415c2a231727303c86110af4b743aa85b73e38b41b819021b07d1ed5c6c171077e9c9b6a678d67b94958c66921e9cf0f573585bc3b47323f32979b91c411c9133b3b8b03199179c6f457f106be4201bcf2d142a4814c5e166c17680fdb2a1296890a89c802120585951a9051fccc4c42001346c9add97f93191c720466f95c5590b0cb8046a470cb50a3716a063135ea4a0219217b4d373efac8625ef44e5c0761bc0404f4ab87bd8abb068c07da5c832de7530be88532fbb5d8eb5c6023a5f0db1aee3a50d2864601a579e6dab597d6cd29208c48f075d42c6b27aa3c3cd837e224bdef354e20168c03172a16973224d50cc0ac7f60fc9b0afc7f399c29a9509f9bc3abe7298303db253dc04a69bc873e874a43dc28fba6339e4152e4399a3ef1055bd81099b33a5087b816ccc668a75bed05650d37966d058d6ebb2b3a819218036c2ba064ebac797c671ead151c121ab88f6c9395204e714310a8293c64bc9789864f93569ca043b856c8412ad985d8206b6e7485f1956d7e616104f720e76459bbb0c874e45479e67233137875c82dc6509cc124bc184a3dbec02cbb08b989103fb59c378670be58f0a96a694d71062e6af424b6745fd9130beac38d297a5f1ac783ef064084b84aa06ac9c2680e8db2487cf43bbe6b8574311a4bd99d733a1b6a751f68401938f4091d25837120664033770d476096e561a1b03e8cc878480a015225cdc1d0719be196b4aa94074c290590988e9b4a4ebbb4b3e5477483cfa6860219237924641cf9a2a7a1219a8a87bde9d08166f0c3081297eda4737d082ac5617cc7c36d428b9dbb7237c122676ce932fd01aac625b5db503a8042c0112714eb43370b5b5bb0d53378a5b6f738c874dc7a7f1c15987c28112857a4bb4310788375d9aa0e60c59958c7f0db809f688f7640805c334e9b1aaf78761d5107c12618b81ba12a1258c4b0123eeb570ccd9924084b7ae3473eccb429ae0c7fc059926f25542911a8738b0186c404f2f107716b5d2e228f91306e3bda12a9b281a598c52228330ef93962d085adeb6beb1076969844e1980295964f9f115840753c15674c86119909d111719182f880ad9ee9792bdc128a8c4df1da9b3cd43301037b192abdc694099bab87441113c77a7f7210764cfb463a96c4007108d4537f29d4859d305987930fd4d94c796cbd55452d10e9b8723a6165ccca8dd39741e94418812291facdcdb453529960d850a40745a022643cd1cb70ec330a6e190ed04963ee28cc774198914b5bfd7c43c6614007d49dda88c1d8b42e05a388f4db09ff1a394b01547155c79ff4933a28568e172133515eafab53b86a078a1a62b114b9977465342a61ada1a20c236d3778250eba35f8d36ac0d58c91198d4974610181bea1cca0724061976a7aaf161afa1b111f0b0e5b835ace9ac1fda361048a9b0008096b41bf7c619af3299c5abb04499c272211931f7b6528c17d5f52405097afe5e0c6ed2aa2cca7915fcc2543b4c8268256cf49936a858f7401117b80b18b081e08b45a0e828bf830c13fdc55fb468d99e8107b93616da437b90a5b52896330c53cf3e28bd3799f65f28bd5f0406638c18c8c9838c555a9b015dc99a61ac330fb11654831571fe667f208689d1c045517af836abaae37184ec603d01a918733362942632644b9b3826ed0967e6db05a6e3ca77cc1604174a2aab6ce72fb1eaa31480e235be79c1c25832ccef512e6c65261f2c485cbccf4062a81912abdbbb3c98c5a6912388a236161e7b8283965536908c0145bdc170bec33c5b2e437628b452aaba7f3ebc8fa730147469d63eb8294fc3cc9096781e58d0ba64d6dd6837812b530e9077a5c5648aa6cc024069150c5acf26d3cfa2d658ab18b86b1eeac4ae2422d41704b9982c8db14bc53e0721123a209d67999c9035ea07f3485ac50e35f85379396c620ddf159c3a4cd57fab15b53c8f2e6aee06c6f2ca02f0d99543368ab70b9bc3f655830d7cb47962d7c3789ddc893ab0a1ba3e1170590249a594445135aaf71a902d9aedd178d88d980345190d72b710ba08077fc868e86713be6bb45652a26c73ca91089040322801b9c68de70662248670f323f4233c1a3c0937dc86f0b6476d12f426868be1b", + "sk" : "23f2a309696a69c78a5272b1318a02669321e5461de8166ebcc0a85df06f30782c29dbb0fe921b9c7c54eba9771d7b52887b55850234de9b296c925420567fd327842af26d0ef1cc1ec393507c540f27184f297340651ec5a0151cf385ba7a8b82156cfab21419633338708212364997ba39755864b368c333397bef42609f4b09c68a096f086ab6530a3816c35d6170b4b28479e39f3a5c621f4198f8b8ba5cab50194bc8490a227c473854f9ab021851eb1a405cb236f8937723d74f0963a67dd465fb172489c594cf91517c3c0dc20c6bec78ca1e52373a57805c30a3b319ac204995846c0bf1286cddb73f777522dde85b43e078c74634408c5e14777f74f9696e1c0703d9a221f04592f4218988ad5cd0b434541be033cd3a28b039c22c77ab9fc1e477e6bc223703610c4076ad3b583c9402ccd26841a55074dc27ba3981a9552578644895e8279c02c39cc8c22da0b11f16ccfb3750cdf76c333ac9988a23f1bb33030718279582fdb578b37512ea084348bb52fbd63c365951d9428468310821210105e0600b5723416b62a72c92c7a26642e7c9c562be22bc9b5b82a16a00069b104b6e359328d0c78af04bb337415f5a14c5730681e3c323098f117a1ff85cba1780cb8e51690d8a8565f9739d15391fd7b6aa2091a828a4bbaa45d80b568fc59c77375848cb44d6f5a76f260fbdf6223ff80b3f1229992a7e8421acfb918d28324c94350dec894b50e73e084026be12733146bc4ff3b76061cdc27470052175179c2dd2ba84db17501d41a16cc183c8d0c2318480efd5632e630b6c2612f0c88a9240017ba431c5a8629107af4cf08614f24e44808949e75c283ab36092266ae41b66d67aabc836c7364525ec4db7ab972d46709ff08762618d7050a3c165b21c5611de2aca9de5a6d826c6441b4894f59bdb93690757461579024feb4531abbe20d0410ef201e7f35ac3d304378971df8855f992cafac0ca7d7c277907d071cccaa84b3cb2203a72bb3d7f0c3e08321c7bb944a4a19fe794544c28181d92cdbe62ba9c270df5d646e1b05adccaa2835aa8b40a8b1741b10cda223783a788f36a3a8c00eed901c74b95b009a04fa169d8e0512e28266d3348774c7248d6c7122362661c5a1146103d401621434198963f26d3459c6572b029a3828bccc1ea35be549bae2c1aa094374061492636989bc8528d2a7ed649c1062a10c372c7635a4d0155a12b82a3656a491e1041fe25522ce39ddbb144a0ba37dac28608794c87743b8884b2fb2cb2dc1a37fdf34718813ab58b8f73c0742d2595802381748736458a846dda95df2740842411661853de6a8c04d1cc31975a8b8b3f676c4636a606dbc0906d101ca6e290d364b4a83b1ae5f461c56100d5d48a93c5448c12c67da30341664f2f2a35b58c25a3397462308170ab80a95780ea1a4e650c6cbd90755c0905026a42d4001612289e7a4a0170b9907d689141138de4460d143744b5e4975f027d48186161458c5d05cbccba6ee3a0a88135b94d0aa28db8b61131783d63224fcb4962d83ddc39c08fd0773642340d93125e83bb31838e786a2ce3a1a68a4084c214b9f304ad8e4a13e80bc168f8115b378fe5cc0a12468b3c24ccd2dcbaaab7bb4848c731e68810b92342b77e6e207d5abc7b93118d0384941460249a3c495b617c35ab97c912589c76313b3cbe21a3ae88d9b0e93a2a24d8449b6816c1045760e7ab5b37649a97938fd4317f3984ccd33a0c6388dec97f4c0b685f536a30e5c06af072f7ba2c129c05df5c40c7aa3e633aa44566689008506ba90107817205916df72b97eaf79ab0d5c97a483f4c9825f485679ceb0d15c981f1605a86c637fad32bdfa800cee7846f6cc52df8475b170316815cef36137c2378e9e27f8121b5b8123a1fe62589db2108810cd360b108018f5d67bfe36ac51ba1c56485cd8a88918cf70141b39ad513846413342be9a31f62691d221df48c125b1829526290c71ca471868c6df5a5b1a5cb14052a46f34e5d5b1e271251427bc4f7f3249c220341261d102b31979821de60610f9323da66061311ac2f2413ef97730b0a38e436958daa13a4f015cf96ca59d93bb56c58e66ab56ad7ca707a44cc1901e5866c3a223831faa00ebbad437a0a9dfa83bd32218bf66027f82d26c68b1ba4659966cc95d79851f03e029a736c3b4809f9c366093967c53769b4796ee76b4f1277f1407b8c478fc1400de6415c2a231727303c86110af4b743aa85b73e38b41b819021b07d1ed5c6c171077e9c9b6a678d67b94958c66921e9cf0f573585bc3b47323f32979b91c411c9133b3b8b03199179c6f457f106be4201bcf2d142a4814c5e166c17680fdb2a1296890a89c802120585951a9051fccc4c42001346c9add97f93191c720466f95c5590b0cb8046a470cb50a3716a063135ea4a0219217b4d373efac8625ef44e5c0761bc0404f4ab87bd8abb068c07da5c832de7530be88532fbb5d8eb5c6023a5f0db1aee3a50d2864601a579e6dab597d6cd29208c48f075d42c6b27aa3c3cd837e224bdef354e20168c03172a16973224d50cc0ac7f60fc9b0afc7f399c29a9509f9bc3abe7298303db253dc04a69bc873e874a43dc28fba6339e4152e4399a3ef1055bd81099b33a5087b816ccc668a75bed05650d37966d058d6ebb2b3a819218036c2ba064ebac797c671ead151c121ab88f6c9395204e714310a8293c64bc9789864f93569ca043b856c8412ad985d8206b6e7485f1956d7e616104f720e76459bbb0c874e45479e67233137875c82dc6509cc124bc184a3dbec02cbb08b989103fb59c378670be58f0a96a694d71062e6af424b6745fd9130beac38d297a5f1ac783ef064084b84aa06ac9c2680e8db2487cf43bbe6b8574311a4bd99d733a1b6a751f68401938f4091d25837120664033770d476096e561a1b03e8cc878480a015225cdc1d0719be196b4aa94074c290590988e9b4a4ebbb4b3e5477483cfa6860219237924641cf9a2a7a1219a8a87bde9d08166f0c3081297eda4737d082ac5617cc7c36d428b9dbb7237c122676ce932fd01aac625b5db503a8042c0112714eb43370b5b5bb0d53378a5b6f738c874dc7a7f1c15987c28112857a4bb4310788375d9aa0e60c59958c7f0db809f688f7640805c334e9b1aaf78761d5107c12618b81ba12a1258c4b0123eeb570ccd9924084b7ae3473eccb429ae0c7fc059926f25542911a8738b0186c404f2f107716b5d2e228f91306e3bda12a9b281a598c52228330ef93962d085adeb6beb1076969844e1980295964f9f115840753c15674c86119909d111719182f880ad9ee9792bdc128a8c4df1da9b3cd43301037b192abdc694099bab87441113c77a7f7210764cfb463a96c4007108d4537f29d4859d305987930fd4d94c796cbd55452d10e9b8723a6165ccca8dd39741e94418812291facdcdb453529960d850a40745a022643cd1cb70ec330a6e190ed04963ee28cc774198914b5bfd7c43c6614007d49dda88c1d8b42e05a388f4db09ff1a394b01547155c79ff4933a28568e172133515eafab53b86a078a1a62b114b9977465342a61ada1a20c236d3778250eba35f8d36ac0d58c91198d4974610181bea1cca0724061976a7aaf161afa1b111f0b0e5b835ace9ac1fda361048a9b0008096b41bf7c619af3299c5abb04499c272211931f7b6528c17d5f52405097afe5e0c6ed2aa2cca7915fcc2543b4c8268256cf49936a858f7401117b80b18b081e08b45a0e828bf830c13fdc55fb468d99e8107b93616da437b90a5b52896330c53cf3e28bd3799f65f28bd5f0406638c18c8c9838c555a9b015dc99a61ac330fb11654831571fe667f208689d1c045517af836abaae37184ec603d01a918733362942632644b9b3826ed0967e6db05a6e3ca77cc1604174a2aab6ce72fb1eaa31480e235be79c1c25832ccef512e6c65261f2c485cbccf4062a81912abdbbb3c98c5a6912388a236161e7b8283965536908c0145bdc170bec33c5b2e437628b452aaba7f3ebc8fa730147469d63eb8294fc3cc9096781e58d0ba64d6dd6837812b530e9077a5c5648aa6cc024069150c5acf26d3cfa2d658ab18b86b1eeac4ae2422d41704b9982c8db14bc53e0721123a209d67999c9035ea07f3485ac50e35f85379396c620ddf159c3a4cd57fab15b53c8f2e6aee06c6f2ca02f0d99543368ab70b9bc3f655830d7cb47962d7c3789ddc893ab0a1ba3e1170590249a594445135aaf71a902d9aedd178d88d980345190d72b710ba08077fc868e86713be6bb45652a26c73ca91089040322801b9c68de70662248670f323f4233c1a3c0937dc86f0b6476d12f426868be1ba08c74eb9f3d9296c268dcd23c66bf0250b222854a5c31830b7431ccd3ed53fd36b817736cbc5f7b1dd6eef5fe6332fb1a598f3871e5470d440fd2ea631da28a" +}, +{ + "dz" : "684a29e4e5480a5f2533e1526b5fac8cdf5927f3d85087c71f928c59690eb56575d12195ec32a8686d0600e45d4a7f54219b0d7a3826d193a51b9156ecf2edd6", + "pk" : "af6c50f1421cc8e1532bc6afdfe7acf2a43b34130fea7ca5b1409ab0f10dfaa5a5f0e7b9a62006f1c53e82b5c7ea427009c990bf31a939ea2705630164445715bc5c80b3906739c46a4c4cf1024776037bcfb0716d1ba00110637fc177fa1768e73cad8fa4777e13aac74338513c516715b645e3bed722382950b132418fee81639d448eabd55a94c66a34eab68ddcaf1c756a4907bc3f5115aeab5320f3b9bbe84e0d885fb784af7fd8c1eaccb37642cf39c8a24c4903a7e80578ac7e9f2a95cd806caa200e23873f751636cd606d819731cf1b812afa2ed24381a52b4f5fba658618a02e0418d6823e7f418294c81032936559a77f9c014d8a3b38df8bb17b7a8c3b45b53ad60b0d9929a21a4ae3039366f894b1082db5f3cf2f13381d53827b5a568fc5234e099d6b94bc1a013ddde944b4ea13eb52bfa880716b1a10d8827a033878986155b7f2944a63a2cc32bbd61907125475bc09b0ab76222cb4c9f2e80a00f9b71bf9705e3576b5a96f6229ba1ce06fa1b2079cf66c59f30dfb88c1f9412b0b2ac059dcab8782abe57209188bb938d08bda140a0eb08de0db3f8558c403c725a77aa1e0563a54a77f32aa30cb780f4e562716075763e9c5d470564ec12cdfab424ba970c51201081193741a5e358cc7d63064a7183d99b28ddc5b0f10374ea9710193385b855a259130bc490041f76a9d661483aa668aace51c616804b5e7c1bdb8762b73b39f17785af94b355b0fed72083c2b71efd1cd43c1a9704a93e0e5752e99a2ef115b6ecabc74cb03bc091038f5701659a0d4bc693805080d6a5c81a0273be9149861c461c47cf496cfb22526d3fb8ba5a3396dd19a8477611b814b76d5c8191ac1c8190ac3b12065ca4ccc879d5f34bc4479a5c8d4693d8771b434c4b8e8b8ae921e01a131e9410ed11c505d226722e011f2073b0db34d10c104afc2656dd053e43a8db7c00fe705b0ba520980dc71e834127c08077806cd8e82144d50448dd59a085776dab69e42db0e7e8ccfc010a140b50b50e09f233aacd3da972aa40f1d1241d718b54b6009d3daa090186cb167c1ab3979c8356397e598502422da2935edd9c8c44b90e8c50473119d26e99575c0c328307e2017b515f33d4d2821bf341480780b21d37fb6cc3049324eb12a42c9f7c9e086bd0f39a1949058f1d8c8f0739c23fb1dc542429933080ae732b750af73b05df6b46e0f27b678668f9450c193c861e7e38d65e5cb05a52f62b29d21b4b33d34771bca88b3149aceda8553c5813bfa6f8a99c656601fd6f4ca7e54cf80e48fa144bd996bcf41e49aec97734687a7d0da2c71231dd841c8fec9a8fb686a7cf81106b16735d6559424c1ae7a5a5f0515a8074bd879c1cbd6012a3b5a7079bbeb6229de7676a876c02f1620d04905341c95ce512d20c4ca11f7c08684473a31313640760d24b4946c0268c108a8b96f699634414b070444480800c6c3d4bbdf339c47e9b1660b9ea039bcc6836a6fda9489e76418047eb3e99d40aabbdbba140221333cf1cf2bc121318aab09022f95c31b12abbe67469bc34ccb88c8a0a965902e47494c7a0bd573910a97377b764ea7443e73346ef9bac0376711db236f89a025d9b09931aa473ad04b351a00c5d3b969134f03c1745f672138f52ba47a542942c1078892ca3b9509f435d8521a373810b12393c8eab18fe7b6f3f4ad7ea88b88b21db46338adac939040674be52e6c2948fd659935a86691f076c7f228bc5874fb8214ece1947f68b057411c218b776a332f5aa351b4d92560a42346180edb08bd57f5342773249fcb1f036955da0269695a712ed852a35a3de8662966c0b2c2038ea1ab7b4f9708c5849dbdc6a29e734ce8db1f447109b755af11976b73cb6c8594a5de221c44b61b9d425280007ef4ec4ce3b34beb733cc73a1a7f6857218476adb0200d96658c8456576666b6d7c06da03663191e649457d298b81b067789c285af151ff4b97239c35ab8688a8d6b4469fcc7e42201d5d57bf3cb98c883c5c9c88f05555674e7a1bdd59e3f327b69a74f0d4a250aa89fe1359e5724ca02c38784a14690c62d891364b752ada80402128c623d0839a0f09bd0e6a37b724070a4356641c538415f2a97701c5492d29a2f2823884496af9dd06703d8ac2c17c4ddf5561590b63ff78c4995a31a18d861a91c43c5dec3705c6112d81b81555f7a3b432f", + "sk" : "2702a72c612968570b25144125a96fc1e89d964a96ca260ae250c7af8c825d857b795396e4eb439f131dc9f36cc190b8ad3a385747a83a976a0e3662834662ca8c7f68386486da8663774f04066d3af42713aa6c8280aa96293bd92217c4aa8cc26b5f3371290eab1aa0d0cee1382de722162a23bc001690cc5ac2c49705711164508ca429e06ff1231ebf0b64550c359b93be6690b9d7e2cbd6027de95c34f03c3d2097cbe1150e4861b57b691e18100c333a3bdec306a87121e51c7641687290553d7005a5241609b75239e43abe459414ff1ccc41118417633d72522b7d1b3746f8a542106061d567cb4370f721540cca09bcb9cf8c364fca8322d2d56a6f1026a53a1593981cee1b8d8776b3827b5161886aa4e91d6bc26a516a757a353f6c2020db2b090a7327215238f5eb4c91594e555b8b0a3680ba6b9bc0589b5e91600da829205395ee836deda787045438e657830cb0c6f82379795a72f698c0d7209c85438c92812938c65407058985184e48f9093f6439fa158749696c1144a336614459f2bc41c9a7a31a2b74ac216d202ecce10f82488b4f32c010a23f35c918ac8c3ea7906219fc85f67730ad12450120091a4b8b53f5378f81b5b7b0bd85b486c6aca5b5435f33f8c38dc255c9b42f1a191457497845f291fbcc239de68c1f6875a445baba0951238265d90b87f630530ff089967b50a1d722ddcc7bb1803e552463b62249b4454095a0903da20077b045213b0db8953340761a8591b042fc885daa8a8c6a2985836c9109b827b804ed5c0e92b568b221618df155c1535fbb128012cc27b7aa6a5a362bb3747712cc693bdabc919bcf2be8afe42a76d814a3362b5337853828639767bb7fbc4bcda6988a7a933f68aa3b3cb7baddc065efa98da09cb742ba3563e19e27eccf6b68b94dd28fbb351220764bbd781ab884956a865bec99c222e59295842eda25c340a45275dab51631b24bb86b70a2b831f171ce9222e350a70a1879adc70d87888db2b1c540c4666f7641ee36c30e733ae206b087084fa3bab717d2c8761b78c20a31093ba5e923298ac59cfb768c527a3aa4d19d1f0262d6d4bebc41699d152e092368ffac3088d2488e6b177bf9045802579ba973b89a2404db17df25c546fac731480d180a519a9309e28a98fe3b521c978df1a94aed0a2aeab5b971c995724189afe7b3f90c5b1563a9187311abe681d61834ffdc8a2142871cdb48096a25c0a315f12a627304206149312a4c647d1059a1f559e6aa3b4f22ba01ac09365718763a720d94506a39582e6400d93a19540690c94c9afe1c5df5b6716ccb4b80939698caa521313a3b3ab17a06a8ebc3713944656a75bc95599a67744bbe79997b4153182372754a9d8238926b1cc239d5942e60c1b5d85fbf828409bbcb68e30e89180bf08083e94816dda4aaa53267787880b9cb38e381585535c80ae47d226893889b5240db1d82d926656541f3196be9458a1a20a5b9b263bfc60670d6baa7981672a4654fa87a37804486258403c9b0dc48054d312c52592de43a41a3a7aea934a72281807d26c10aec91bbbbc8ea75b2b215083cfc94a12c61be14cfcb2b688b097832fb016b0a60cc133c709b9d6c1734d4a100d3523f8f30c78f9647808b6cba905cb4da605a2b3fc3a433c916089304c868257bab174861a8b57f6bbf6b79ab55a3044be689a8e19f3d598f7453b3a71a06b29bcf3eb3819ed35d56b74a176cb9bc81b9ad94250e639c17f431b1c856b02c4d6579417d304f3c7b2a34579b6c09a866ac9d871acfdef3099368025f4109240372feabc2d17a7e89031e67a74b68144ee1a871c8737feef4b9c663bcc9a42770ca4571a9b92c60ad14f53600dda002509f109659f8b2a5a83ab6a1d8c3025c38ebe6346ea5cb11e66d560a9c656a61de98407c130b1094c391a879ad70ae5ddc2acce2b42ccb378b9a9997d6042581230e6843e70634d25ca675e09947027591372e50fb42a28cc9c8e13693267305c89b7ca4cfca931eb1e6137f6470432a55a08a183d1187ba7a8f78e6b960874001515ee15437bbb8157c382af1641693b20e2de25cdfb7c4bfd9a803517fac4ac6bb960377f17ed89b216cc92eda7b08a89505903659b94552ed2433d7d6668b226081691f4ea558f2b072af6c50f1421cc8e1532bc6afdfe7acf2a43b34130fea7ca5b1409ab0f10dfaa5a5f0e7b9a62006f1c53e82b5c7ea427009c990bf31a939ea2705630164445715bc5c80b3906739c46a4c4cf1024776037bcfb0716d1ba00110637fc177fa1768e73cad8fa4777e13aac74338513c516715b645e3bed722382950b132418fee81639d448eabd55a94c66a34eab68ddcaf1c756a4907bc3f5115aeab5320f3b9bbe84e0d885fb784af7fd8c1eaccb37642cf39c8a24c4903a7e80578ac7e9f2a95cd806caa200e23873f751636cd606d819731cf1b812afa2ed24381a52b4f5fba658618a02e0418d6823e7f418294c81032936559a77f9c014d8a3b38df8bb17b7a8c3b45b53ad60b0d9929a21a4ae3039366f894b1082db5f3cf2f13381d53827b5a568fc5234e099d6b94bc1a013ddde944b4ea13eb52bfa880716b1a10d8827a033878986155b7f2944a63a2cc32bbd61907125475bc09b0ab76222cb4c9f2e80a00f9b71bf9705e3576b5a96f6229ba1ce06fa1b2079cf66c59f30dfb88c1f9412b0b2ac059dcab8782abe57209188bb938d08bda140a0eb08de0db3f8558c403c725a77aa1e0563a54a77f32aa30cb780f4e562716075763e9c5d470564ec12cdfab424ba970c51201081193741a5e358cc7d63064a7183d99b28ddc5b0f10374ea9710193385b855a259130bc490041f76a9d661483aa668aace51c616804b5e7c1bdb8762b73b39f17785af94b355b0fed72083c2b71efd1cd43c1a9704a93e0e5752e99a2ef115b6ecabc74cb03bc091038f5701659a0d4bc693805080d6a5c81a0273be9149861c461c47cf496cfb22526d3fb8ba5a3396dd19a8477611b814b76d5c8191ac1c8190ac3b12065ca4ccc879d5f34bc4479a5c8d4693d8771b434c4b8e8b8ae921e01a131e9410ed11c505d226722e011f2073b0db34d10c104afc2656dd053e43a8db7c00fe705b0ba520980dc71e834127c08077806cd8e82144d50448dd59a085776dab69e42db0e7e8ccfc010a140b50b50e09f233aacd3da972aa40f1d1241d718b54b6009d3daa090186cb167c1ab3979c8356397e598502422da2935edd9c8c44b90e8c50473119d26e99575c0c328307e2017b515f33d4d2821bf341480780b21d37fb6cc3049324eb12a42c9f7c9e086bd0f39a1949058f1d8c8f0739c23fb1dc542429933080ae732b750af73b05df6b46e0f27b678668f9450c193c861e7e38d65e5cb05a52f62b29d21b4b33d34771bca88b3149aceda8553c5813bfa6f8a99c656601fd6f4ca7e54cf80e48fa144bd996bcf41e49aec97734687a7d0da2c71231dd841c8fec9a8fb686a7cf81106b16735d6559424c1ae7a5a5f0515a8074bd879c1cbd6012a3b5a7079bbeb6229de7676a876c02f1620d04905341c95ce512d20c4ca11f7c08684473a31313640760d24b4946c0268c108a8b96f699634414b070444480800c6c3d4bbdf339c47e9b1660b9ea039bcc6836a6fda9489e76418047eb3e99d40aabbdbba140221333cf1cf2bc121318aab09022f95c31b12abbe67469bc34ccb88c8a0a965902e47494c7a0bd573910a97377b764ea7443e73346ef9bac0376711db236f89a025d9b09931aa473ad04b351a00c5d3b969134f03c1745f672138f52ba47a542942c1078892ca3b9509f435d8521a373810b12393c8eab18fe7b6f3f4ad7ea88b88b21db46338adac939040674be52e6c2948fd659935a86691f076c7f228bc5874fb8214ece1947f68b057411c218b776a332f5aa351b4d92560a42346180edb08bd57f5342773249fcb1f036955da0269695a712ed852a35a3de8662966c0b2c2038ea1ab7b4f9708c5849dbdc6a29e734ce8db1f447109b755af11976b73cb6c8594a5de221c44b61b9d425280007ef4ec4ce3b34beb733cc73a1a7f6857218476adb0200d96658c8456576666b6d7c06da03663191e649457d298b81b067789c285af151ff4b97239c35ab8688a8d6b4469fcc7e42201d5d57bf3cb98c883c5c9c88f05555674e7a1bdd59e3f327b69a74f0d4a250aa89fe1359e5724ca02c38784a14690c62d891364b752ada80402128c623d0839a0f09bd0e6a37b724070a4356641c538415f2a97701c5492d29a2f2823884496af9dd06703d8ac2c17c4ddf5561590b63ff78c4995a31a18d861a91c43c5dec3705c6112d81b81555f7a3b432f37e94def940045d3fd9ddec0289680ae2f96d9d43f5d774a81b86ae7a4761ab275d12195ec32a8686d0600e45d4a7f54219b0d7a3826d193a51b9156ecf2edd6" +}, +{ + "dz" : "d76b3573f596eb286ab5231feec7499686b13021be36cb126c7ebeb9d7030daf248c0a21ea0bb6d6f56f12300e8584d8e9a34e0e6f52227281151ae4c305fb8f", + "pk" : "822a87a132c0b9e3c13bb45e2eb5bb47535099e37019b3c7ac3b81c6225dcc65476fc12e7a81cc80c9a508e507f201632be9c1bf27317fd97275cc3f481bc7c5c25a4b1462767a42cba43b152c276ffc8db55a96d418246e0bb7d5a15f0d883597e9579d675e816b8333097787c613cac29427b11739e650cea2ca8b198c0158caee9971894b67332baf761caf88c16bd11c9f1dcace7b83a6bec71f0ed9bc28f706c38b057231b7c330a4b99898037720cc88245f8982daea502ad30e315c2ca477a3f045084356cb81184ed90734e0cbc0d1553adaf5a94c2a6d8a51566997c735bc45fc408241357da2c38c8a0520fb5a33e1d5c06cc80c4e91314d08599763232517b501097e4bb09bf814a0cdba619c701d249c933d143bbd92c163724b523bc05568a410952380177ff6084c6416bc22c637b7e1ad586324103677101a74835c4255b89ea1935ec8b8382611bd4dd91931c436f9a909af4747dce811a2ecb63f046b411a201d1b4f12442e73d7703e22896a904736308453b946f248a6bd11800797886af555b0787d84daad7883c0e583a7b6530c7d0a8559906f0e423e9e6cb600b9917768777b7489dc173fc67551ad92a26b054ddf13c4f83b5805b9b7b9829513611e171b9ea358abf9054ddf02629a397489dc213705a9b86735577493b86c326e857eb816663dc1417cdac788900c8030803751bae22292af87cf8fda4f2991418948c0b4f54c19163dc4b195b76cc5def67b5288bad948cf214cc6a11c6e1ab1a5b9b1501baa75cec23530c091cadb8c9a02415e816ebe708422dbc2db224b74ba1b83327c8b25bda3cb7127f5c5b963cf3c9abfa15c952bdba2acc01c9d377a89eab6a96a65cfba3d722b6618262ea78770d5fbc556789ce4d13bfe02065f033362124b84560f462c64443b88f3135f585a3b29e450c1dcbaa7b9181133c915522a90f56e595ba11ec3327e6a83c7f1ba59951c4684995ea64edbb3451271a878e42be7d763b27cc430ab6b068173b973141e0a72cdb185b263071d20a8f5a37dd08ab6ea7a2639e0cac1790d5573053569addc1731a339488268873d89a1490b78ee404c2e8328004d44cb4521a68737f195634ab659b919a94e268131ca290e59756311b6273b5dfc2c3adb21534609cb2fc553906a14d8c079f487091587943df49a39d1b465952efae34d33fb9ade56cb6ca9cfa8221458d9940d4bb5f044297c4160a2284032458bf909c31e47a27c7aabdc9815f1ecccadc6288fdaa6c0316f2cdac38ce89fb31cb81b673f26e5709e08c474cc41f213b0fdbc5563851bbec682d9051a5d58148a72956721bb96224214d03e8b89021b98b9a0a87dbf15b491125bc07c6ab6353560d61814ea3cb2e72344104b06413f963091802413521441da171e6b6b039391842141c87c991a4157b428e35ce499a805e2c0954457582b6a8f52c4e102bb33cb01d1ba883ed4cb126c2137a75aadca26852223741c07b027a1883220ca9a65585a5e0c0847b9d0013f821bdad0902504785e927016328c99ca1f3d2bad906b3cef04a3598b2992b2c587100533bcccd15ba1aef877c3a565cb352b7b856880108fb828b42d3612473970044c6c4a057f18ec13deb2c398393c19383603c183b02a461bc9b8ac0969e04179e53c5a8f54a556f54218024041137448d08401fba8e4bcc09cf3b91cc28ed9bb700cc74523c251ad3a7c21f43398f85c7941387612c0c76a43db2a0a368101e88480aa1a5f1500b2a17b5704299d5639b477802fef34bcfd548274d26c476c50fff8851f29ba5ad66caf066ddfec2140dc97b83077a9e21bb4f87aa85a16a7107e3597a1bf4a5bdf008c14bba230cc95e6071bf0e6a25607566c9008d715223c483dfd6737e25a2dea490eb5606c6e32b8063128bcb6181166a93da7626c4273157c47b5a2adb1d88441e76ec9fb6efbda9fd084b496d5635794aa23a43a8c4650e05bcc2e415d775971922b1a446411f952b7e5540091a430882067c0f008211a705e4842789ccf653bb919e742b65339aaf4653e474c10583d9329cadc47a6ef20589572a2e6e4ad67d03abdf7ce1dc9015ba94ed9c69220d63b423cb5daf465d5e3a9d190a6c9d84fb28141f28990959250d48162c68b813460b04a78126e4b2c4514d83cda2735e3d3f1889578b626b002cd859ea9ba6fc856a8030f6010c780", + "sk" : "b212c7b33a82755496caa9b591e69054a2808962aa4b703ff72b8f7ee2206f4a7cb77262dd34c791e095cc059b1e00a474e5b60a3a8b2b77b0b6a34968f02a67133b5f93c96e94657c8995aeb2c6706a1361e7370a8072ad3713f56c6aa32c19e34278fd2c397e84905813b10fac77595a624476c9be5a06dea927614c8964c9300f6cc7d0e974e334540b60c48868c8fd99829a0ca9743522cc88b6bbfa77b9432b9c373c07573c5477a339697ebd8c4c2e087fde72bf826b001cc7b3d3f7b05484193fa38982f3ce0488182f59cef992b82c6039218829e4e4b1c554a9aaaa301f4733c0540fc2c7acd1a13d9fa0bb6da18f1631c5ffca65bd9519fa454ca76c1b8f5c8f41037499561ed02252e4e408aa352af4155a9d940e5fb964a57117d250556cb9ba2c888cd877083b742428ea6b62f0208c862a39dc6f9d6671965610d69a54d10abbc1238931777cefa00461ec086b26ca2dea34e88565a6a89bd1a138178298cacc938135ad58cc98fcd29851409a3e93cf0a270f4d8779b5f7aefc2143e0e082e8e8b357b84af630364538b19b55954edcb3f250a2a53cba04682065846c0323556f154b97b7973d267c1678a02d1b2f168977a142bcd492509b46a6bda72255510ec952a50aa11907b42b62694f978539fce0cc35079a4bd164fac25c46737c22540803d4a04f54824ac381eaa5ad5ca51568a8c256762a1021a8c46142e0a99f16db9cff371317c602bb08b275269b312411ae849c2c29285cc98d1244a346497ff59c9143a3cc9481ab5ac82ccc86c2d38512bf901b97d83b518aa0812aa2c6e3c2f8da9e8cd8154f299fc8bb52e9ba96a4aa264f8b828fe783ca4190ac42a56a97c0e6d88ed658b6993399e47127040a44aa539480131b485318ffe6a598570139c06ad4054b70b6991fa4b82e59018b7a206f5595e0a2456fc122ea8828fc3b75744650b2ac1a248133bae700585784a1949caf7c58bca497b0d03569127c6fc88b407268cfbaae78e779acf25e9c9767bc691eb0969f69988d3af98ffda60b308a789b8c985235c9d694c6f0e1425cc1782a921b11444e54e7a94819021cc1899439a753a677913970f470854966357569924cc5ad3e2210b6654193a4b2f145782c9397c2c6bf8fc14535149289b904a1f628a45b2cb0e66bd955c3c153baeed32a71673067f7262fc0bd6385c6cc00793528b9cf021b339c179a157087864f70d24cab938be046cf3e409e01faa10e4601ae47b677b670b11ba1edcacb5b292908588554a8b9f204af840a2d2581ae916652db5a71e36822a37b6ffdd3664b9ac253acba6187211866b25a46b62853878ba777a5156948e52e0040bc63f120644a8ae466591986acf5c1c41b77b562a2504c0509b411a879997491c9c25ca38aa3d62250ca5267854e1ee9554e064b4a6181958c50b11708a348929579ccc09953191011fefc0c6a2242adc09ecdd29d1de974a2d3497d904baf5494d4f96ef5fa8e86e45fe4f0c79bf3861be98b7177093e9312c0f77b88f23fa62ba2c6f93255131f23e9607f3bb54c8888eccb2e01cc22bff2384bab57fc2c62a8d47f73051af951c7efd63c0f0a87d29460402814e85602997a765a3597d5a9099b99a37d2817e827b76eb4a2da2622f516364c525c69586c8e5729e3309925fbb3f9e86717503d04682fc5d83888b96e00bab9348c426ce55977a73c40ea2315f122e724a17252317af5187c290a87e6675e78589170454df4b800d2546f9a33a288256669c09ec63e49eb755cec96a542b49ed0365d6130ef2051b9a0c42c675302453ee7ea854c1184b43609a0b25f30164269479e6f2bc7a76aa758db9709204739cb3378dac80f54c665eab7dcc0be9e8186349b9f2e2bcdd9e2af7ef03ce65c62e2d798fe588242f990caa7650b5ba55897615a85ad2f96906651becadc7b53b38dd74962d7e6cc79d68f7b273452aab4f692018bc60dc6161e36e8b523b3b349f6666f4583855998d1f41f9333194b567b9b3332d8e93fe30b8e19813bfa0abaed64106d147495a6abbb4909e7aa06970b2b20914c51a5c6f1d9894d911038600bf22268b58ac4d8b8bd07f24deacb1737779cd5b328dfc251577846131392d8533e70d074fd50841698bfb584b620a100b09ab9ad6c60822a87a132c0b9e3c13bb45e2eb5bb47535099e37019b3c7ac3b81c6225dcc65476fc12e7a81cc80c9a508e507f201632be9c1bf27317fd97275cc3f481bc7c5c25a4b1462767a42cba43b152c276ffc8db55a96d418246e0bb7d5a15f0d883597e9579d675e816b8333097787c613cac29427b11739e650cea2ca8b198c0158caee9971894b67332baf761caf88c16bd11c9f1dcace7b83a6bec71f0ed9bc28f706c38b057231b7c330a4b99898037720cc88245f8982daea502ad30e315c2ca477a3f045084356cb81184ed90734e0cbc0d1553adaf5a94c2a6d8a51566997c735bc45fc408241357da2c38c8a0520fb5a33e1d5c06cc80c4e91314d08599763232517b501097e4bb09bf814a0cdba619c701d249c933d143bbd92c163724b523bc05568a410952380177ff6084c6416bc22c637b7e1ad586324103677101a74835c4255b89ea1935ec8b8382611bd4dd91931c436f9a909af4747dce811a2ecb63f046b411a201d1b4f12442e73d7703e22896a904736308453b946f248a6bd11800797886af555b0787d84daad7883c0e583a7b6530c7d0a8559906f0e423e9e6cb600b9917768777b7489dc173fc67551ad92a26b054ddf13c4f83b5805b9b7b9829513611e171b9ea358abf9054ddf02629a397489dc213705a9b86735577493b86c326e857eb816663dc1417cdac788900c8030803751bae22292af87cf8fda4f2991418948c0b4f54c19163dc4b195b76cc5def67b5288bad948cf214cc6a11c6e1ab1a5b9b1501baa75cec23530c091cadb8c9a02415e816ebe708422dbc2db224b74ba1b83327c8b25bda3cb7127f5c5b963cf3c9abfa15c952bdba2acc01c9d377a89eab6a96a65cfba3d722b6618262ea78770d5fbc556789ce4d13bfe02065f033362124b84560f462c64443b88f3135f585a3b29e450c1dcbaa7b9181133c915522a90f56e595ba11ec3327e6a83c7f1ba59951c4684995ea64edbb3451271a878e42be7d763b27cc430ab6b068173b973141e0a72cdb185b263071d20a8f5a37dd08ab6ea7a2639e0cac1790d5573053569addc1731a339488268873d89a1490b78ee404c2e8328004d44cb4521a68737f195634ab659b919a94e268131ca290e59756311b6273b5dfc2c3adb21534609cb2fc553906a14d8c079f487091587943df49a39d1b465952efae34d33fb9ade56cb6ca9cfa8221458d9940d4bb5f044297c4160a2284032458bf909c31e47a27c7aabdc9815f1ecccadc6288fdaa6c0316f2cdac38ce89fb31cb81b673f26e5709e08c474cc41f213b0fdbc5563851bbec682d9051a5d58148a72956721bb96224214d03e8b89021b98b9a0a87dbf15b491125bc07c6ab6353560d61814ea3cb2e72344104b06413f963091802413521441da171e6b6b039391842141c87c991a4157b428e35ce499a805e2c0954457582b6a8f52c4e102bb33cb01d1ba883ed4cb126c2137a75aadca26852223741c07b027a1883220ca9a65585a5e0c0847b9d0013f821bdad0902504785e927016328c99ca1f3d2bad906b3cef04a3598b2992b2c587100533bcccd15ba1aef877c3a565cb352b7b856880108fb828b42d3612473970044c6c4a057f18ec13deb2c398393c19383603c183b02a461bc9b8ac0969e04179e53c5a8f54a556f54218024041137448d08401fba8e4bcc09cf3b91cc28ed9bb700cc74523c251ad3a7c21f43398f85c7941387612c0c76a43db2a0a368101e88480aa1a5f1500b2a17b5704299d5639b477802fef34bcfd548274d26c476c50fff8851f29ba5ad66caf066ddfec2140dc97b83077a9e21bb4f87aa85a16a7107e3597a1bf4a5bdf008c14bba230cc95e6071bf0e6a25607566c9008d715223c483dfd6737e25a2dea490eb5606c6e32b8063128bcb6181166a93da7626c4273157c47b5a2adb1d88441e76ec9fb6efbda9fd084b496d5635794aa23a43a8c4650e05bcc2e415d775971922b1a446411f952b7e5540091a430882067c0f008211a705e4842789ccf653bb919e742b65339aaf4653e474c10583d9329cadc47a6ef20589572a2e6e4ad67d03abdf7ce1dc9015ba94ed9c69220d63b423cb5daf465d5e3a9d190a6c9d84fb28141f28990959250d48162c68b813460b04a78126e4b2c4514d83cda2735e3d3f1889578b626b002cd859ea9ba6fc856a8030f6010c780ee3fad17b073dded30b6531f854523002db21673437ae275e8a4d702ef311619248c0a21ea0bb6d6f56f12300e8584d8e9a34e0e6f52227281151ae4c305fb8f" +}, +{ + "dz" : "b87439fde81c9e39eebe7cf741c685785532c1dd23e8ef868b9ce7a541010f3d1646460817a0fce5836bdfe124a7448e7adf7b8ecc2652ac6d280e986682df71", + "pk" : "b9c82a0db31fb3c6458ef4c21b5663ef7795f4c36ae77a85ed8304a4066c48741323ebc5e5f50d50a704de206c4f6a5719b27b8fec3d95e77f545a7f78c57a9432a329741159808d255232d4288032d658bc483d4afc3d6ba94f8bf44b347a8fd4bb7e2e4000db9909c3720920a410a46905d3a34083c3484bd2448f232ed825658a8b25d99c995be0866a18c01274607ad6bc0154a4fdf70f42768a5ca86df321327b89094383648a236d8f74bd3e3854b110ad8d1403e428a73d9a13cf29a6240c30cc53532d60152ff560d1e3c3205ac557fc76bba0af547c69e9819d1ca412088a8665863f64cc98f3853e2ce115c4c3080e002542714efb10b8f51a59ab954885b313af6000fb8c0b23bc59ae73948e8b30213c84230098469200c8d3aa1f68160963b4dec95c20c8290783457c06b7ed61ab17077709591416a422e52a2afa2c61ec4932df188a4a0c056dc854acba8acd5298a6cb2de04c7c3bc7bc724157fa2b9d01c9bcb0624d79e52988a4b783e8a6d7c45115c548e0eb474368993d971e59e96d5c2a9341b40f461752dd73cbff7543031caf370130311c458684a80209565b754437926bb20840aac329392cbc4f7022eeb03580696b239b2993c9927f649aa838c4e88726f9633b8630977e85350bb25c130161b6c0298c03bcb387c38b4853ce8258166175623107f3d4c5a4b266c9978154e710f11337f05986e921b20d1c02d0667b42d1a4f09231d7d8993263a2cef7b3e5f153aa691a12b7ad28513eba123945f0651b83cd36099047b997ddc5128325213875ab7ac39b6e969693c4746f19a159b19b7911abf45a9215f5c9ebf60c46f254c27285e9491486773ca0f8848e23bc16d83155c302d0e42504762226701bb3a446316b9199860b824c1bb5bb2b4f535e74c493a80b3faa5b635d65364fc241a2e1366f3a2ae40ad07e6621ef64428ffb6c86a1883aa20d04b610ffea3b48e88e6073005e281e91d65cea99079e1846ce89c2fffc8cb38932c00783c9812d26f91937e6966dd2642bc1b494775f5acb46ddb3bfe70c62e2018cda8b16ff762ec3944909d034c27ccafd2803e4f392fedba006d672021a8eec76cd2c5b1f2bb65737a5369365c8ff6231b7866973201853d7538b27825592629c7812dda74b795ccc56fa684e8244a4b204c0b2bce93100a57c02dd13c5af5718084042e9d809eee01ef78166d5579fb0702deb07b6708c7ae2757a004d2ce31921030059c36a014df0178d59c7a7a7b1c3e04bfdca8ad4697bc2a36b5a213900249ce02a678009a4c9f8589bc24810e611a942ad468a2ae2d8af0b3b3a7d741fdaeba89f3b6c1fd302dae37f2d54ba53fb78e040991f4c468bc2b6f527cb985a9ae19797cf845c53803d13b267c8f31e4382791f0a7ed27a96ac609b40c8bedfb1a11d8c244cc85f4b692607d72f3cd05b070b5e8f4b7e0ba56657434296caaed3928f32d526cf0281a57960e5c55f6deb1636494e3d618d1e4431fce125adf544b91904cef045f1d088e159a6cff792ff5182386a87277953b4c4ba3714c20bc50e04c2b2b628b147d07291e24e18a6906b5300393180ed011b2c458d7e2a1f4604816a94b83c93c5160b740e3640707a4fe8f265ba351f4ff2c7fb75baf8980f136b2ba2e81cac3b27c2653c89b65ce236a3c0c28759b12275c4cddf5c14c7b69e951bb30459b150983fbc330db7dc3220420dd5e928ef5905a78a0b0e214bf1252765646f6c657aaec11fa775183c1ca3bb7261a2205e46d064239103203532556ca7fbf750d1f88ed6862ed02489bb30c976b4abfc0123583837a8db3f6a38bc5e9a44a990a471cb3e380b4508ac4162a4073f815507d33fffec823f9ccf17aa150a5bc7562a4e3f85995444c787d16901332989c15fdce4b43a215da66000525ab32f5b1d728846fea3ad2c092e271208b6f833e51c701da8854b867e0bd0234a3c9d98117c58ac1ac8b05f59f027b4a78e94771ee263792cb891e9d5abf0706f70f149482948eb6248bd811210765f93b4cd49daa19a17843e510409d6638dda571f680f02b17182e1c7eaa542e990275bd080bca0c793d3113d524598fc9dbc453a0560c556e7bfa3856570b570a1b43f82657458615be5080c89c0bc7e99a67a91bb9b8cb821e426b843f7542c5ce12ca13b5b7f6c716e63411681fef0ff85e8cd3fcde5abdbb9e4", + "sk" : "ab6656e1c10c6071c28b24c6461336d91c7b5ff6cb9c97ab265215951983f6530ab7da57f0e4967321866ab70204396caa7b9917c9c6e082b331d65fd1eb300dd481311b723c44408a1b1f9657b19bb73ac593a3b2a86a1de53f2fd150abe7620fa9b061340ac23ab1ccf45914170ac5553873873fd0175b79d500c2e92ad5fc71ab348522c5c82b81c89303abdf684eb9f638a2c502a088795caa954f9255ec8389d0097d768133a7340857534cce37b7372388507c8dd9908d01a62077dcb583a5328238a097a572b800ac1e3a4b02080edf616072229b74f4078d99018eb6191e09c5d498a32cd04e22398604479c85c61436606dc6cc4256611fb8d0c2a4f83fa160c1e7810e558526140c42c2c111141a3a24ea7400e44e3a472d1e913e341b50d88364ae301f4917ad1bc94ce43027a2435c6ea9b979cb30d86a856bc69928348b52b36915684cb5b02c23b00b8fd68831d593338b07ab0316bc3656e9b58b4ff4969fd461ad72ab05754399e39e2776a08ddbc25e4a8db78a279575bffaaba7b9143c337888e8f524c163c059f860187b2cf674b6fcb94b480a859a2b7af7066be0111c94510a919739757470b1a25fd9eb3143cc66c7a2a0c4f9ae57ab26d9481aae956240785043c43bb130c25bc10bc9956a930c009b7a08839cb483c73e671c29f2609667b49e52c79d494596a668484b5659c90965e8222db617ce6e18c94cb80aad565206c930cab57e8040cf6d2c1bd4219bde58538bd71eeeb1ce8ac9bab801aefd84406d7233a0a21a68d48fcbb10892f71a7b98110cb780db9b07b6e53339e3a0ae3921a0f85c4dc282c4874b7f5a56ae059ee327bbbf68ab3ca84e1e72b5955cc3caa12b86e949025a7bad520acc7037e97a51bde797636c5ebaecb671f68518756207327f8acb9594971e7ea07030748a87d674604b2c53b6cdd6f16a0e4669ba37a20477b25ea47ce56aa81f100bc3d4392e224af7984d59f0570e9b020a698409e8b119425756a678cf6c98cf814be4e02be4d1bfa9daa20b91a934da2b18a9cd294808f838bd21a93189859fd6b645f805b8c2caa10904697189ca2a90bb8c9431c14372fbe552009067d6097b11246c4d8469d01c470509079183082e6c10784a5110b93f450a8860134514110079393f3bc45a2442b59de6b37896be3a54553fcbb72cb10755649341699be44488bce835caebaf9f8a017437615d6409b576b90f8021db6babe5c10c0fb159ab9060a0744837631046d04930eb853a1970bc34734bcb327721b39528c0ded4226207033aa18a3171b50f698035282000696c9bb14a6617ae7453b608893bab7b385e87ccfb83929cb968746c5196ac7c46423f4b10ad3ddccf8f9616def05642e22e15e15b5827b850249434d9088896cdc45b39582c3e2d7340650365c929546298beb4fa024da8b3886a8ed6699bd15bc645dca53dc792458470395bb64cea5bd9916a11f5920487cb60776f3fa1b7e6d16007a5322e92410377c874f98bdf32066a136d8221b95474a240247bea21cf0a572cdd721ad9c98f6a248c33a20ccd3a6965133e6e47055b5893d8db26c6b77754f441bfe7439b8a5269280769247adf0665d161c88e756de537bf5601b248e9632886c84b572aa542b53f25001586c60eab6e1cbba8b62582efe41ca212874f402635815611f09ab9ca4ce29b6fc665478192452d667228f17d1500d0a18574527a3ea92bb208e037722684b2f14db7d7cfd11616d9a528e0d54ce197b16282bb2a2a778b81999bd38fa2d86b071b7d47db2c7b3b3af53b4a8bf7051b38468e63b2728003e8489d33caabf3ba196468abf982452f7a261993bcd3941fdc59a60ee24d19f060d7e493c29ca5a7510918b918eeebab86dba7eec12f233c0b0adaa65cc1ada2d64976c0399dc8092d5c3ef0774101a01f6643ce8ba0280356cbefb2c2856cb6021768564342287a9952b1c2da5928520cbdf6d8a970c4aa776c60d7781107ac9da66672dc0490cde4b38dbc08422624e50b9b3b775c8806adcec9a5a2d94f56d488a8ab8f90b6930cdb8fac4ac5b17b66c6b1167c981a55cba0c8079d1668ae51f32a62d4513165b275097597e422fb3ccb4bfcbeba52c0b028a01c94c4a192b9f1dc4f584328cbacb263b5c71c145bb9c82a0db31fb3c6458ef4c21b5663ef7795f4c36ae77a85ed8304a4066c48741323ebc5e5f50d50a704de206c4f6a5719b27b8fec3d95e77f545a7f78c57a9432a329741159808d255232d4288032d658bc483d4afc3d6ba94f8bf44b347a8fd4bb7e2e4000db9909c3720920a410a46905d3a34083c3484bd2448f232ed825658a8b25d99c995be0866a18c01274607ad6bc0154a4fdf70f42768a5ca86df321327b89094383648a236d8f74bd3e3854b110ad8d1403e428a73d9a13cf29a6240c30cc53532d60152ff560d1e3c3205ac557fc76bba0af547c69e9819d1ca412088a8665863f64cc98f3853e2ce115c4c3080e002542714efb10b8f51a59ab954885b313af6000fb8c0b23bc59ae73948e8b30213c84230098469200c8d3aa1f68160963b4dec95c20c8290783457c06b7ed61ab17077709591416a422e52a2afa2c61ec4932df188a4a0c056dc854acba8acd5298a6cb2de04c7c3bc7bc724157fa2b9d01c9bcb0624d79e52988a4b783e8a6d7c45115c548e0eb474368993d971e59e96d5c2a9341b40f461752dd73cbff7543031caf370130311c458684a80209565b754437926bb20840aac329392cbc4f7022eeb03580696b239b2993c9927f649aa838c4e88726f9633b8630977e85350bb25c130161b6c0298c03bcb387c38b4853ce8258166175623107f3d4c5a4b266c9978154e710f11337f05986e921b20d1c02d0667b42d1a4f09231d7d8993263a2cef7b3e5f153aa691a12b7ad28513eba123945f0651b83cd36099047b997ddc5128325213875ab7ac39b6e969693c4746f19a159b19b7911abf45a9215f5c9ebf60c46f254c27285e9491486773ca0f8848e23bc16d83155c302d0e42504762226701bb3a446316b9199860b824c1bb5bb2b4f535e74c493a80b3faa5b635d65364fc241a2e1366f3a2ae40ad07e6621ef64428ffb6c86a1883aa20d04b610ffea3b48e88e6073005e281e91d65cea99079e1846ce89c2fffc8cb38932c00783c9812d26f91937e6966dd2642bc1b494775f5acb46ddb3bfe70c62e2018cda8b16ff762ec3944909d034c27ccafd2803e4f392fedba006d672021a8eec76cd2c5b1f2bb65737a5369365c8ff6231b7866973201853d7538b27825592629c7812dda74b795ccc56fa684e8244a4b204c0b2bce93100a57c02dd13c5af5718084042e9d809eee01ef78166d5579fb0702deb07b6708c7ae2757a004d2ce31921030059c36a014df0178d59c7a7a7b1c3e04bfdca8ad4697bc2a36b5a213900249ce02a678009a4c9f8589bc24810e611a942ad468a2ae2d8af0b3b3a7d741fdaeba89f3b6c1fd302dae37f2d54ba53fb78e040991f4c468bc2b6f527cb985a9ae19797cf845c53803d13b267c8f31e4382791f0a7ed27a96ac609b40c8bedfb1a11d8c244cc85f4b692607d72f3cd05b070b5e8f4b7e0ba56657434296caaed3928f32d526cf0281a57960e5c55f6deb1636494e3d618d1e4431fce125adf544b91904cef045f1d088e159a6cff792ff5182386a87277953b4c4ba3714c20bc50e04c2b2b628b147d07291e24e18a6906b5300393180ed011b2c458d7e2a1f4604816a94b83c93c5160b740e3640707a4fe8f265ba351f4ff2c7fb75baf8980f136b2ba2e81cac3b27c2653c89b65ce236a3c0c28759b12275c4cddf5c14c7b69e951bb30459b150983fbc330db7dc3220420dd5e928ef5905a78a0b0e214bf1252765646f6c657aaec11fa775183c1ca3bb7261a2205e46d064239103203532556ca7fbf750d1f88ed6862ed02489bb30c976b4abfc0123583837a8db3f6a38bc5e9a44a990a471cb3e380b4508ac4162a4073f815507d33fffec823f9ccf17aa150a5bc7562a4e3f85995444c787d16901332989c15fdce4b43a215da66000525ab32f5b1d728846fea3ad2c092e271208b6f833e51c701da8854b867e0bd0234a3c9d98117c58ac1ac8b05f59f027b4a78e94771ee263792cb891e9d5abf0706f70f149482948eb6248bd811210765f93b4cd49daa19a17843e510409d6638dda571f680f02b17182e1c7eaa542e990275bd080bca0c793d3113d524598fc9dbc453a0560c556e7bfa3856570b570a1b43f82657458615be5080c89c0bc7e99a67a91bb9b8cb821e426b843f7542c5ce12ca13b5b7f6c716e63411681fef0ff85e8cd3fcde5abdbb9e471c37cff80f992f3359ded64b566956adfa3266cb05f171eb644711d3a2cb4b41646460817a0fce5836bdfe124a7448e7adf7b8ecc2652ac6d280e986682df71" +}, +{ + "dz" : "056661b38038da4fdd7426f32a81576c73ed84843b305168a374f934e27a4e1b79238a80dcfd7c992d84b2dffa67493e669243d4fa38c46b090bdf86bc548411", + "pk" : "35d29c0d6263d9020389240d058974e871ab8e433196680f50c7b88e6a3ec8764b4509c3764bb4db404a8e932413930dadbb5c5d60a01539763428cdffdcca2cd0554633367ad245e069bfdb397b803c68c8543583581bfcc9bb1147a2063262774706dab0a015e7c57e244b12406b0009024fc06181bc058b466ee12c3ecd1a983fe1bb030774db831ef1bb26539245caab4d9954bb01901c6bb66534b95cdcc92a1af075be8a949829558ce625ace38b1296a75058b9a3f90e74e04ff3880106869899e6844a6504b8a0cf99ba86c72cba26564739d0221fa20fb412828180a14bc570503a033eb379790a457f9277a221b75720537205cd19969149ab9d2b87a19250b595186454c99b46ab8f03365200424b4ef8cae2569ab4bc07b98acd2e50b0426032f967354c70b6c1f1a1df32406c296b0e9b8066904fa2184e0dd04ad5c27f9e952774bc82a923ae90888613144bbe376b38112a836b7d6b0606d25abdcec0b471a834fe20adbc78a68cdc5619089ae4f09b32947eaeda996adbcf131621bdb99173063f98f1380a324f84626212f8acca34205299399e62b321030191379b8bf96ccb336498d2a8bf573f44596d0db92792122026b61264693be3a3a7160a9e60fc1fc0897e5f602483d6c81f382e3e237d6709b82056976ce23d66b013ea48cb56d78d12c68dc2cc6fdc7aa1142548e1940e3d889c71e990fbb19d4fa0bf892b5cb873ced68516e544bcc4bac3734215201c617767757dd3ca2b0a5084002f175995abb6a7b88892d07b4ac68b974ca83f13722f028bad4aa9400f0b755fa3352c90673a44be327845d1dc1cada0996d57b62fab1032ccb6eb947646fa25d06495a6577a17d707b11c3e8fe82325d21dc2997d0ada9bf85b45d8e5431ce5ac571c253744108f91aba0b2868c7096c92b2f53fc5a0d996cd8414cf230cae4c58059177607040d871b8b1da28837c7ab177369fd2c05fe300da0d84e97497cf5f22a36b966b5872266202d207740d47c8b1fd118ab390cd5ba70bfd9a0bf8b59d14b165575a079d82bd0fb1cc015340a1c0a0c77c7f822cd2999c6f10b5aab063181775b7f42b2fbc813b2fabbfd76c0a5d4942df97c449cadac303ccf4790685438257a0093461f581c981bc61229c94a130372ad920d2cfa5cbec684f8986a7ecaa94275814cdc2d7fe403c933bc0038b18b28cc3eec9ccac49bd922c446267cd07b786de316012330ae70bc49216fcf6b4c7db2bbab55153e21089d04c3fde934955ba215d047398ac172c2b1a18c0597182e88a327d0f0968796ae0a03772adbb406a210f2e004810513f09712836c45cc11a0d8c8433b813e0e8aa380cb166fa93961a2b6765287aecace40cb4caa064f6b547f0084bcba7856898b221d362c9de766c7d447bc10925330ca87a8379ba944323c638f33b164e13731b0b92a134ee9d454684387790361b31b53c245328bb19185f9774e2764fd429e11e2a4851b222c4a9e504531fd962fc23852bfa3b4632aba9be4595cf5083d64522ac93b41c7409aba1b83ec51cb6a1c0bd0c24e35cbfff95088d7b6ec890cb5559c44553dc44822692a243d032ff75c7c08914d847551151052c6846e2f556201205dc130babd9483dc721d42f42cbabcacff1aa93d05a2ee54bd399186bfd4978a7a76d5d24008fc55ec40a6bdc899ea0a69ca22acdf8bbd14a5cfa2a06587728427865a3331c60e77b5782c37e79561cb622195656d8f9c0c8c2c560ac95cb0b986ffa0784ee17554cb2bd0d332645958bb68cde65b13d274ba9a655bcc8072d6681cf556c7931000b94a9436602f0a5a6fbf770a2b323612bc47190c9a88d4588d97c099ca04b3b7377867a6e68869fda2258083cdcaa41aaa798ea11ba7f6cc4838f2aaf9c5795f8137adbc4c17b491a59255e61ba078a9b4179cbc89cc3c9946c65efb9ca5ac5765f3570f673ac80c1d26b5af8f031266c65b4ef41f7923af49dc6eb3d0a0eac745aca402ed4b9b2de754bc3b7a6b54c2159baee1f560dc502e4ee6b3a3d6b4c1ac1e06dca9edb6775f5696cf91acbd9293be7a82244234de9869afb1b2696300331aae6c9332840145eb16b016f8714fc00020d429f75231f73b265272a936e404f0d57b79c6ca8c25cb7c8bb89284c4e7b0ba9eb33c0406a8c39eb0d5429fcae286a9c56be5839c10ad33e8a58374dff41feb", + "sk" : "6d02b73b69cadb317ae9c9b09a74634c1762b30c55e793c0fdd50574eb6156f152e7dabf92b1a4cf7a9afe32cb5f95909f1c045bf9c7c76c137c6c4a4c170f82724c32921a2ffb7250ea6fea48060cf88b69a0506e2bac21912e4ca5806d15983428c4d7f32847b6a4bfb7218a4cc2b09a343de3ae2fe392ad6a555c035ecd0a16c66339280219bb40ba2ff5432524cdb0ca32a6d1b8a9ea96893c3864494e3690647d8318a3520682cbc19632cfe2e28733da34a9811f5e659cfe99b7894a88aa01c3979285813a149e196ff51206ba654215985c47f3bd24848e0c959a93eb20c3176c68188139b72929b83533ea0a70e44333d923512750cd9520f98bcae6c16643c080fc836367aa4a39c88f66c0ce09428135673b0f09529d0bb1e9e4b14679cf41f433bcf533e7e4cb1db4b5e800218f564fce359056706f9f091f6b1a0420269948512748871ea2b7c7fac91411c70a23418a336297ce670ebba02520c3c1d13807bad55100ab3d0a8b4e87fb5a5d21925a6892e93c3c10a66fc4974b282ccb9cb134aa0aafa86a527f96b2df98ba19da2e536614d243a19dd1a095fa37e9008607c882b48a79b3403f76342cd4345e6f6c95327965c2f860c4367135124373fb54a4aa7284429455f1637f56b4443ab048e0c9b82289f7d2340c2547a3bc8e66343248b5114d27cbb0e19a6a6a82c84bbcb340113ed65460052c088c555c27847078319149048c5a9103dca6770aac9d5a75f84930d6f7cd5813590a22040ffa2b9b631ec897409259037fea8547dbc92288414dd002a4c377e501800aa49b28e68a528a3312060d635ca584542a8452cca7c0cc3ebc4e3f46a5a5cb1fa49718b1c71f95224f9cbbcc9376737cf827b25caccb4b49cf4a0b0de096e4d83f319582edc68ba1177bf7ec2e2a41b0686bc6678b8355cccb7b9a8519aa68b39067dd178db2fa8ab33305efb7592a29a8f49b9264251c1ef83d75518134da35ec07ca4beb10e102466da0b74673b9fd7cb93f287ab4e321c9c4034cb26be63567f7083cc86a15b67535b1c235c7aa4ab1eb5097947b5b282e15b888a8b010e8596faaa410f6ca7fd358765ed97e5f8970abd54e36938709f6410b779077cc0b01052b412822ce256f15352fe5314aa2b41be3611ec14020b975077a444007296455818b90f6b85c50a3fc4506cc48c1ad436308154c5075755c6419ed7a267561841cc56b428608ee62047122aaa674bc9af18f15c52bfcc981fed3622f302896d7bf238b9808152b4d8ca1efca092569595deabe45f6b35c8c9b7293a321e96e9574726dfa93c79b162eebb0e7a37cea7127ef1179c728c22d98328b59b86ba4a85d11249ea08a3e594e7df1210846c8f7683f5b856ff4fc8d63b129cb1c8ea72a168c71c56c166cdac216e07097e9fc050f458e0cf6bfc5f55116e161938c8df6643b6d5514ecd860a4372693e12c1fc8b1552800802ccb48d16f4fd89306d30af791aecae205a6235eb9343c6576034c38747a306db6c2302e5569c19a75b2cc62d3895584361284801f368766f27a83cd376952d0374316af68d06b3c242d7188acbf8847f55b80750bab52b2043df10b47dca1986131f2db9c9b12bf4664a3db6bc1859b59b468c0f34c1bc8d8c74243aa3f434f044a408ab988a5820ca9317d35b8344e45273f76259c813ddf991e0e02664a4c8353252c85ca8531b6196bd68767cb8010d92fcfb12acc9c931d169b9cd247aa2c8c5fb6013cf65f0ebc432c38936db3b6ec983f742a1ca6449011bbb70f5bc7755b58d4c011455aac47c6831d6a3368905e6b700c987cc910b23d3e406e81e56f28d0a35aa331f7499c63a10b2eea5dd24b4e7c173d9e694d6c6b7a6262b26c99163c337ff3fc9dc9586548665c1472935aac3a8b653e07802b1f2a291929233e7c8d1932718ca63299ba4919d9936d65a2b78c733ad2c15f13cb4f45252b7004d9d9911bc5293c61983eb24f7b9c1808285d82cacd48801a721b15f43c0f4563c494a9a5491c30dfaa5ed5f89e08cc76dd7324d16b3ffcea5393aaa525e90f7a4bc88ac07010a60e68f7be39b20faa28610db77006a5577acc2d33740b6ed66341a56dcb4ac5a3eaa431765d006caf51766a00e07f84a6bb0222c251764d628b9cb38860c4d8cb35d29c0d6263d9020389240d058974e871ab8e433196680f50c7b88e6a3ec8764b4509c3764bb4db404a8e932413930dadbb5c5d60a01539763428cdffdcca2cd0554633367ad245e069bfdb397b803c68c8543583581bfcc9bb1147a2063262774706dab0a015e7c57e244b12406b0009024fc06181bc058b466ee12c3ecd1a983fe1bb030774db831ef1bb26539245caab4d9954bb01901c6bb66534b95cdcc92a1af075be8a949829558ce625ace38b1296a75058b9a3f90e74e04ff3880106869899e6844a6504b8a0cf99ba86c72cba26564739d0221fa20fb412828180a14bc570503a033eb379790a457f9277a221b75720537205cd19969149ab9d2b87a19250b595186454c99b46ab8f03365200424b4ef8cae2569ab4bc07b98acd2e50b0426032f967354c70b6c1f1a1df32406c296b0e9b8066904fa2184e0dd04ad5c27f9e952774bc82a923ae90888613144bbe376b38112a836b7d6b0606d25abdcec0b471a834fe20adbc78a68cdc5619089ae4f09b32947eaeda996adbcf131621bdb99173063f98f1380a324f84626212f8acca34205299399e62b321030191379b8bf96ccb336498d2a8bf573f44596d0db92792122026b61264693be3a3a7160a9e60fc1fc0897e5f602483d6c81f382e3e237d6709b82056976ce23d66b013ea48cb56d78d12c68dc2cc6fdc7aa1142548e1940e3d889c71e990fbb19d4fa0bf892b5cb873ced68516e544bcc4bac3734215201c617767757dd3ca2b0a5084002f175995abb6a7b88892d07b4ac68b974ca83f13722f028bad4aa9400f0b755fa3352c90673a44be327845d1dc1cada0996d57b62fab1032ccb6eb947646fa25d06495a6577a17d707b11c3e8fe82325d21dc2997d0ada9bf85b45d8e5431ce5ac571c253744108f91aba0b2868c7096c92b2f53fc5a0d996cd8414cf230cae4c58059177607040d871b8b1da28837c7ab177369fd2c05fe300da0d84e97497cf5f22a36b966b5872266202d207740d47c8b1fd118ab390cd5ba70bfd9a0bf8b59d14b165575a079d82bd0fb1cc015340a1c0a0c77c7f822cd2999c6f10b5aab063181775b7f42b2fbc813b2fabbfd76c0a5d4942df97c449cadac303ccf4790685438257a0093461f581c981bc61229c94a130372ad920d2cfa5cbec684f8986a7ecaa94275814cdc2d7fe403c933bc0038b18b28cc3eec9ccac49bd922c446267cd07b786de316012330ae70bc49216fcf6b4c7db2bbab55153e21089d04c3fde934955ba215d047398ac172c2b1a18c0597182e88a327d0f0968796ae0a03772adbb406a210f2e004810513f09712836c45cc11a0d8c8433b813e0e8aa380cb166fa93961a2b6765287aecace40cb4caa064f6b547f0084bcba7856898b221d362c9de766c7d447bc10925330ca87a8379ba944323c638f33b164e13731b0b92a134ee9d454684387790361b31b53c245328bb19185f9774e2764fd429e11e2a4851b222c4a9e504531fd962fc23852bfa3b4632aba9be4595cf5083d64522ac93b41c7409aba1b83ec51cb6a1c0bd0c24e35cbfff95088d7b6ec890cb5559c44553dc44822692a243d032ff75c7c08914d847551151052c6846e2f556201205dc130babd9483dc721d42f42cbabcacff1aa93d05a2ee54bd399186bfd4978a7a76d5d24008fc55ec40a6bdc899ea0a69ca22acdf8bbd14a5cfa2a06587728427865a3331c60e77b5782c37e79561cb622195656d8f9c0c8c2c560ac95cb0b986ffa0784ee17554cb2bd0d332645958bb68cde65b13d274ba9a655bcc8072d6681cf556c7931000b94a9436602f0a5a6fbf770a2b323612bc47190c9a88d4588d97c099ca04b3b7377867a6e68869fda2258083cdcaa41aaa798ea11ba7f6cc4838f2aaf9c5795f8137adbc4c17b491a59255e61ba078a9b4179cbc89cc3c9946c65efb9ca5ac5765f3570f673ac80c1d26b5af8f031266c65b4ef41f7923af49dc6eb3d0a0eac745aca402ed4b9b2de754bc3b7a6b54c2159baee1f560dc502e4ee6b3a3d6b4c1ac1e06dca9edb6775f5696cf91acbd9293be7a82244234de9869afb1b2696300331aae6c9332840145eb16b016f8714fc00020d429f75231f73b265272a936e404f0d57b79c6ca8c25cb7c8bb89284c4e7b0ba9eb33c0406a8c39eb0d5429fcae286a9c56be5839c10ad33e8a58374dff41feb6af202d9ad3f2c7ca61993e238140ce8550a5f0c39147130a5313c8c02d68de779238a80dcfd7c992d84b2dffa67493e669243d4fa38c46b090bdf86bc548411" +}, +{ + "dz" : "a1b52d871612a1c611ae0944f9e71858f35d3bd14f20e96a931720668bdf0a6b1f135cf64b6403e103afae34da038613e2853bbfc36baafa3c6a95347193f37c", + "pk" : "349251ec123ce574a5dd6ca1d14a967e7177aae64d9678571d6b0b0769935a1a2a8dba53db6c5b7067210426c64f53542929b31d565bd25a480d9065d79852b0f05002964772465c3fca5f8307308055603039b1b56726eea02a8cc19c5af41309f145000d2aaed3038c17911677a2631242280c23e9816185c75e5dab43b4b04c8777a35721605aab1adab828f2640ec5b23173f6cf5d37ace602ce5af62108ecaa540ba46594181ac9869517502aa73ddedc4131ab152b53501dd4aabd79556476063da48c4978835f28500f810b77715257080d87247354302399485852314598fc6eb1f93feee6429eac96d37c8422dac30f473b56db0dcd2c64f1c18f91950e7984a88b63979b424c6d4a36220019881b5aaac715e426a6976a300ff171a29778c82a1520f42a2f0b10d26035613a1e0511720087be146ac9f0cba2c1929c0960bc16065748573d61eb195de53ab9ec802d247b210b747c70c45aebcf39229e4b938eff354fb9f65cc6b52ff0163494744848885ee577048b506a95112ed45466252783a4016f30e29b1928acbb448379723d51bc3b59a62df46ca75f64bae27aa2d9456c66e2997b48274f425004e6884e296e17912f7e387db452681cb32e7217566897287fe9c38622325a8c6716e5a767a626d98836cb779983c31d1802b0e0bca04bebbfa9e2cc02429f987a31f73274ce5320e1b0cff8154da331be8ee21cae8c5037a1baa4956b04833d4928a1c32147246002466716ea9c69f4032d33260c338cb13ea09e5e47957700c33bda9b147a3f3f64b46c933b7f4689d2797e4ad24df42c002a323ac0e781b7e8c8e679c949ca730826b3f6c28813ac24ce7ccb21136695c75b3d028fbf6ba94f5a06115c72bcb879d64cca29309502836edab5c7b2a79a1e1204161369c5e8b63dc513d0aac9fd366387f0aa2e736bc09b4dba05414659a6937264ba982b419342e8c063ec64b28663cbf4d12aa5a6ae5aa9056ae71c4f5643cff81ce6d7a8d29a250ac27be274afef453dd176c462791c249a817329142c00ba332851e50a01660a47e35bbf3890c23be173dec1a1d57a4837975c14269707384855e897cb44c4bef532a003409aea41d2fc889f572ab20c0409831ffb0222cc7246438a95fe4a6e32412688b2cc8c1963e38526201aa9d2b0963533b2fa42af59e61d53c4bac2bcc09e44c5f9c4963525a7c015244000749e811873a391f71315d1fa60c806390fb3aa80295e77e80158c665ead61283271a1997757e5c4dc6893ad71a63a1898fcda02165db76e252665153016c90bb9c8423cf8a1d371338feb40a382c2c3f99840ea96f99246044f4a5fa5cbb8d7473110b4a5238255e5c3d43463b055bbe46211d2e05812dc46bcd539c56a15199cabe5019220dccc1a828a5e0c37bf130a6df762e395915654b5bcb5c3eaa7142e1706697b9914a287513e407ed376354697144b33260eb966316c05dca8655a0436bf47967779d43cca5edccb932c023351542857268a57a74c4eb08b7809c289c5543cc3730594b3ea33de6e23a5600ae6a68cde3614cb1a80bd7c2379c1834c349c55fa73859c5a3ad45886286973f1363a5a536a0b08faf26a939179f873cac62281260868569372dcc744185a55feccb261fb0af1ee7a50dba2c49636e09687f4618667db136bb291f4b4c129fc7635182720521acf1d67c719a283c412bc9165d9f883db9049b98381a4412b6599316cb39986a9c3f8c069aedb9b5e13b82f3abc0c1cb70dbf0b5d1d66ea003676197c1be2c15bc6533a41804ce0c123fa55a87fa344d850af4f5b12fc0ae3610593e1bcaa1868571b2a618db9f1900c459376798341e4263c70cb94a9db42a04067f7a5310c606bd7ff661ef3508e6b6b6373c7ba0c872b8019676263bf912673c59a4c51372a2da860399222654518063c3e1f07cc6c93e91ac6b53f3c04516b76da65124325c59d4360091923d1883977a52b328c0d508d0f039696db843bc12c506b521ae34c9b9d145047293a6eb99686770dd587c92bc65aa3a4083b40e8fe2cf891c5152281744612b2598664e4368775572e4a03a9ff53e307caf081ca897dcb43061a404c689d934653769ad59d68475a8b0e7277bb280ac77ea7b1a1b6111c1574c6358dd6a472c49c264965f8cd9fab7d1fd2c5f4c3a4ffcd66e5b05a4879536aee3074b69c3d4e6b1", + "sk" : "4f311376e73d8074bebfa35fb9c25879f482ab77c1708a8974d609f4aca60712bf80e6a4948042a333cb8abbb1bc32960c75776194adddf09925b605efe3cea0421a9cfc63acfa774858b9f8468c39e9038434517b103e117abda9531ec9db871b0144de3b3e6a99cc091a696ec218e6e099188872d3b2b2e4188c1935530a364ec7a1a98d9cba4bb68d26ca98eb437d2a3378bce40fcd3b4a8f7982485a1296364363dcbcd813a2d434bf3f68788c035980c0be8f46a6ef54a198d64c0d149731a097cac43d7d022167aa8657ea521197cdb3585b4ef64b1f6708082471820919e8b9392a5c2f56e56148d10f18525491647fb0140e7c66bd26e3631f3bb3f20c947a67194b9c5de9793d55c2b800263e50929889d8afc878b661c7cb2fb366b8f70f8ebbcf75822caed8a6c83a3651557389c51e5431ab15095705300a88ebadcc417a4e955f2858b797b39b64f10f587119e24a01e2a17a638873b485b2c8d867969c39b30c01404905ed14aff50484da83a8bfdb23689900a7954695b6695186b590e5c3dd27ab6a619a2cd13b78c9cfc7c966d4d373485ab99e522a74372c51a4764ec0152a29acb154826479567b1c6aa68bb2fcf471e035c0d7f22478fab87e7c035102a8fbb5cddef910923748bc752d0c82cfdf8b7733f30e6752b037482bfcc8a38097c9a9d8745b0681ad79710a4049be27c13680627516aba8d308287a45f498c9065900cef26280f17b8ea6216f60118eea6243337fb2d7ccc156325c33116b057b92e24d662718235a7e7b69186b17232132b529e44d558039eff0c2aa6b0b0bf8332c382e1b132c3f343a2bfb3f11a116563a7905617e639c6bed21051f5513c4793dd887b9ea26b90dd7076aa4aad5614d53e87d91861caddc1dab846c6933a689eb2d1566814f31951546b820620fb60690a7734153e79e9ba9a054aaa9b908605b10384bba08e2213e683c6d64e9a80d8235f02c39a6bb42def54865164c86c08af24a614f3608b24a617bab86e5196172c81f1a6a001ca4cf72c9bcd6f89b8dcc154dd761a3c02362092db91b3da7dcb723b59c3e029be1f96e6933a5a7a8296da3a043a32e9fb27573a62352a088afa68baef5403f200d8d71743ed79ec3acbf1c4811a0308f425a05714c5637560cb7b36dcc91008d715248fb3e2e52c38b9c67381c3e0bd8127c163e320504ab20588f02a0ab036e8cd121d762af33980c0a7625c6129b83b6c8d7e304a4529ac33c204d79741c1a68ce356c4ca04a4f16406b462db4038f78bca2baab2926250cec30a3ce827e56186da8669fbd7a2199f53cf87cb2656349b6d2ba189079e7d2aff8938a983275551a21e7e179e13cbcea08885af930509c68456a9e778baa0e4649e2c830454c278a06849f088d130c176320b260381259d4458555a2d8715a93957470e538448a7b29958d7119c17f6a38f09a8b441c371114cf1cf390b56365d7c71fe9bbcb496401bc8b07d15c06a49c221828b6b7b56cc601bfd6d75fbf3aab16ec9584b78078324cf9060c5304354bc99e9a69c090c6513e16b6af982f2bfb4e0ddc4cb69ab1fea10575a53358890feb66162d29b4af6023eff84070e25bb84b0b5ef18f4bc554b8d661cb5a97a83b856d6437eb503de82760cedb83a5ac4b05261a02a621937231eee26777d75a3863cdbc24954f74b43260a089823b8c659108bc86dd1bc36e9643b4f62c1489a880099622b27160a2c934f4b3369a9afa7531ec39487ef2b8742b63cc5059a8f9317b06aa8401071d86791b09249510aef7924c25a2458152165ed7c4403c0ccb5a8db007221f930ff9162d66b4a1522b878d8b08624a0ef3b24c1cec21928773c8fb99f4816a7955a2a2816949eb1dc1a794f7b61c1837398521bb07c0063b2b01571054af509dc94a3ef1882b0928aeb4dca18769b593d2b357e56bb3148ef7d4cfef73068d0b48cb37c168168a46701e3b16b6e8d463fd47ca5f7b472878497eb9a60e629897108c30461bf6f09283a006b95ca010aa80c50072892a1d7f406799593112b81d61775d4c15a3ea54c4184b775a88cc3c427d9a36cd1e77948ed33bc0891b24dc7a08822cd2c94246758cc4e49f04a61d0d721e43e57b8c18337293c25e109e64f01e88bb0c08497d49083a9fe260349251ec123ce574a5dd6ca1d14a967e7177aae64d9678571d6b0b0769935a1a2a8dba53db6c5b7067210426c64f53542929b31d565bd25a480d9065d79852b0f05002964772465c3fca5f8307308055603039b1b56726eea02a8cc19c5af41309f145000d2aaed3038c17911677a2631242280c23e9816185c75e5dab43b4b04c8777a35721605aab1adab828f2640ec5b23173f6cf5d37ace602ce5af62108ecaa540ba46594181ac9869517502aa73ddedc4131ab152b53501dd4aabd79556476063da48c4978835f28500f810b77715257080d87247354302399485852314598fc6eb1f93feee6429eac96d37c8422dac30f473b56db0dcd2c64f1c18f91950e7984a88b63979b424c6d4a36220019881b5aaac715e426a6976a300ff171a29778c82a1520f42a2f0b10d26035613a1e0511720087be146ac9f0cba2c1929c0960bc16065748573d61eb195de53ab9ec802d247b210b747c70c45aebcf39229e4b938eff354fb9f65cc6b52ff0163494744848885ee577048b506a95112ed45466252783a4016f30e29b1928acbb448379723d51bc3b59a62df46ca75f64bae27aa2d9456c66e2997b48274f425004e6884e296e17912f7e387db452681cb32e7217566897287fe9c38622325a8c6716e5a767a626d98836cb779983c31d1802b0e0bca04bebbfa9e2cc02429f987a31f73274ce5320e1b0cff8154da331be8ee21cae8c5037a1baa4956b04833d4928a1c32147246002466716ea9c69f4032d33260c338cb13ea09e5e47957700c33bda9b147a3f3f64b46c933b7f4689d2797e4ad24df42c002a323ac0e781b7e8c8e679c949ca730826b3f6c28813ac24ce7ccb21136695c75b3d028fbf6ba94f5a06115c72bcb879d64cca29309502836edab5c7b2a79a1e1204161369c5e8b63dc513d0aac9fd366387f0aa2e736bc09b4dba05414659a6937264ba982b419342e8c063ec64b28663cbf4d12aa5a6ae5aa9056ae71c4f5643cff81ce6d7a8d29a250ac27be274afef453dd176c462791c249a817329142c00ba332851e50a01660a47e35bbf3890c23be173dec1a1d57a4837975c14269707384855e897cb44c4bef532a003409aea41d2fc889f572ab20c0409831ffb0222cc7246438a95fe4a6e32412688b2cc8c1963e38526201aa9d2b0963533b2fa42af59e61d53c4bac2bcc09e44c5f9c4963525a7c015244000749e811873a391f71315d1fa60c806390fb3aa80295e77e80158c665ead61283271a1997757e5c4dc6893ad71a63a1898fcda02165db76e252665153016c90bb9c8423cf8a1d371338feb40a382c2c3f99840ea96f99246044f4a5fa5cbb8d7473110b4a5238255e5c3d43463b055bbe46211d2e05812dc46bcd539c56a15199cabe5019220dccc1a828a5e0c37bf130a6df762e395915654b5bcb5c3eaa7142e1706697b9914a287513e407ed376354697144b33260eb966316c05dca8655a0436bf47967779d43cca5edccb932c023351542857268a57a74c4eb08b7809c289c5543cc3730594b3ea33de6e23a5600ae6a68cde3614cb1a80bd7c2379c1834c349c55fa73859c5a3ad45886286973f1363a5a536a0b08faf26a939179f873cac62281260868569372dcc744185a55feccb261fb0af1ee7a50dba2c49636e09687f4618667db136bb291f4b4c129fc7635182720521acf1d67c719a283c412bc9165d9f883db9049b98381a4412b6599316cb39986a9c3f8c069aedb9b5e13b82f3abc0c1cb70dbf0b5d1d66ea003676197c1be2c15bc6533a41804ce0c123fa55a87fa344d850af4f5b12fc0ae3610593e1bcaa1868571b2a618db9f1900c459376798341e4263c70cb94a9db42a04067f7a5310c606bd7ff661ef3508e6b6b6373c7ba0c872b8019676263bf912673c59a4c51372a2da860399222654518063c3e1f07cc6c93e91ac6b53f3c04516b76da65124325c59d4360091923d1883977a52b328c0d508d0f039696db843bc12c506b521ae34c9b9d145047293a6eb99686770dd587c92bc65aa3a4083b40e8fe2cf891c5152281744612b2598664e4368775572e4a03a9ff53e307caf081ca897dcb43061a404c689d934653769ad59d68475a8b0e7277bb280ac77ea7b1a1b6111c1574c6358dd6a472c49c264965f8cd9fab7d1fd2c5f4c3a4ffcd66e5b05a4879536aee3074b69c3d4e6b1eba48a8a50609e70baaf4c552f680f0b02afab2da76d8833a2cbc3b6f782b36a1f135cf64b6403e103afae34da038613e2853bbfc36baafa3c6a95347193f37c" +}, +{ + "dz" : "952b49c803d6d6fba69f4375adce8594847a00bcae2179da49af2aed0423250262d7033947ae42ca53522a65fbafe18d3bc3e0cb66164e9a094fe4b44d8977ed", + "pk" : "6a515110c076dcb486eafac9040ac0690b79f5278022f59bfc316494a782d92310489c9f93e61585b3bd292165f651a7017a994b2512f0a5bdc8e77e9bab7e5cccaa7bbc779d445e5f16b871989974d92d2c268bce10764c0146a683ae56c47c4644057ce8b4739031879bcc287b194cb36fab6916ff563248d04851c74a7fe87f4fea546a565eefd507457882cf288ed294783179577ee898bed18c97660bdb726867a2c9581cc13bdb263dbb414d695990ccb897fa31984734e3178e081856627b0a4bbc736a235b3e392b3996441198c41bf8cef5ec64d2f5c4b628490736cbbc076d8ebab4cd1ab4936935fa3aa40d941e85cb08774520bde23f24739400bd45b1b056d8a09ebb49a3e4b7209037c94a47084604697185bac8772122d1bcf22888f165546bb699b23b2262035135120cf677aa7f767ca049b869137999884e360518358852cbbca3f90643764cb30fa16cc009766c43b89e599203d6344b1081e97c863190ab57d42812d603ab56068283cd30e92e3f7a8989715479cc3735f3cb1ed9120e8b8c720ba35ab1178b426c413c5e89eb5483bb0fbed13a2fd0783ce4bdb1aca87d80000dd48caacb57c74b802c6b133817ab099c84f1c22383e57a759ac6eab76df67876e3591f32595a56a027f2087b63db7dc138cd820a84b09411da2284ac78445850ba820c31b1ca97f3e680e24201fe67154b935a36292b18857007953a848c49d0236406e7a320243fee64ac24b02952d0a02a57ac4fba19ce373e3382cff61160913ca55a091696d782f4134db83958ded48e681546ecf2be93c09a9bea7b3ff420c84a9107f4a75a2a1c40ba0f9e6060e936218f0c0904bb29add2305cd59e29d2b10fe667f9ea49cfd149d1d8bd62e549e08baa1ccc63b8cbc734a24017e4a099bc5a939828ffc8cac5fb5d388ac8613216f21942675cb714e32cfe666357413773ab5f6a2c405179995ef42635cc7db7238dd7c410ba529e7d7391556c5f604c38fa079a70fbc2e8b393306832fe2a8bca891d880209b9719eb4d2732581408a3896735143462a45f5e4267084bda97a9a5324a2e23a714c1322f4368be3ea5219c10f56cb560a78786c2a51db18c79f151f3743a7de67c43a35c63d1b70e17aaf4e4c48e300a73f9c07bfa776ee8797f803ca148aba782a2fab110a7c4440c5791354b25c1107106be979b2077d422a6d8edbc04225ac63c3705394c9fd5389c11855057572fb303ffa365cc2854a3bf620ce5203b21bcf7ad9c675427ca1294c7b001e37a02be18473d1b13d9c52b9d59bc267ecb1fdf3bb96c2b374e72e4bc0898441c47adac60c1955bd1a5096f371bfc709ef624078139feb979c9ef48bc0bb9100d0a97198b466bc5821978c87da85c4e4164ba61a010b5fd99435dd18129a6b379c3232f75c8789d486ee3b6c84e052b55066e81c409c182d4e84926a42abac49846fd7b6f7c305e234130026540a6571d2c241c2700ed4e073d0262bf196164c71a62b904938cab91cf12fc8d527a091c20a86b163aacaf2f25d1814bf2d435dc7881b0f0219bcf40f90f894e74392fea065fd1b69f2e959cd0a5850b002cfaa8e44d0867a16ba5b173711d77f355a71bdf7674299a91cc05f2c772a5280177f2551b6f4a986f3bf584a899e755464166c3220130e694616f76cc3722c999536b6d145dfa5a27aa591ee994332893fa87acc2df67113f8a9c438abfa667022b92842c73b15047d6db08e02930a6348a71472a5e04bcf856058e785c10d049af83736b2f78f8fa0b16b0b7e897cb695ec20d37c35190a079a57cb41ba5a0f010f4cb94b585466c9a802f0855946361237a0840d43487bf65bd9f000f2480afcfc03b3dbba6ff053aae4981fc619d82818251c0d00ddb269042902b4c28fe6578709374f2461b0fc1a00441b78582db2a76dee8729be071ea3c9957f5a3e75934628081eb8339ca5cb5ae83677d4c31d7b12b0463b57bf7aae0af3901a9795085b8aed0564d3755588a0829615785f322add179edf08204021b86bb3cf8f3528ad652437ba8b0c6901cdbb748ee8a2d854644cb694668b9ce322992dc43f2d8a7ee655be3b257a0974ad0649104b6b4e9a16bb8cb79a42968ceb1cbbbdfc6c3921ae35f6b22ac3c2f858184475b4f2a12db3158b3bbf2d64f07ee186fc57de21c26bfcf6b645f83cbd47cef72136aeb644", + "sk" : "68e429be33972613c71269a6d8c28f37780f659bb7329478251ba1f0a71e5292986ef1054d57a4a1a98eea60bdd2244908972f138761469962af11078f880e900543195101e2238cc4065ee72a33cab77529c891209116774a34aa531093b15a133b3bbf24ca44787294578312a9648d6b427cc630be8420ac73ad795175563b471694658721ce97a74719587f6dba69307600ecb86c16d14428d264080b7083145c1ccb143933b902d463ab1264c53360c5fc04cad928d3f91efd67795ee2a9273a41353529cb3b6d3f61b2d4759662f1b0aab989b1d42c40e05f53e7251d56879e57c40dbaaeeee626f87b4f4efa07a7666049c5c6af4446260a1c2641432de89eb582ba6f8c84640723b7a6449f268a7e8b93af9b8a98552bf2aa940e277859824c22fb0ce8d1b3d118813d1c9749a345c990818091a21ebb2027a1bcb7434097b83fba702eeab0a8a8c3719df9821ce2c0c6a392ce5a48b56a73801accf9bc0f55c96ad21c3ad7793dd62ac413f9cb25a75065e68edc63508b13b90b6bcdcc127816d5c1e3b246b1db27e50528ebf6b946b93962469de91a70ec36c848c8bafa2b13199c146e224552e619295703ed8c441a41188a004073392c59e88b76e847a11b527c6479daf28548a5540ddc811d7727e203b51699a0dc85820aa90e7a96378d99148553726d251f73ab290b206452fb15314a7005a50fef5b6a3c69b5c91125a161699d0956bca47394567eb0cc4145fca15b2ca32a751946841829531adb91b9efd60bb2018a13d736e67aa86c12517b134cbf51a6831a80188b54b051063561b1419c4990b1aaeb52280a2ca421a84b1f1827e544c27b88c1db7593fbf3a9146633dd41a2cd26bfeab57c7b01c3a7b07b0ea196db4c21259baddd81981d9a917b4a7bbbd45fd2773539817b77c09e79797bf301077bda0e6de9829b01c6beba809130a1a9724e3ce39931b58c07344ec731a11402470828be43b33601667e46c66a59979b8b1a15d9739a7da6aa19ba6def480d0e2b2f859b6482d128ee6262a929cec408974af41b9e0c9c6a9b0c32abbae27a36dc373199f65a18d4b3e4153086f003c127c7926c9dc3510ba0f99280a5360f29447c9204e7472e10486c3c465dfe4855b1d8b8d557b99232531c0b43426521c8034518d32bd5981c149883e8b95ab150c051793384c9662aa795c93b25dd3957fd3382aa117a9d6b333035650918cc924732737aaff69472b4f699a99288c5a24946138fb955385a8a75f2088c143057275c3e7c97615c7721e0a049b544864c358aa8c0a30ba788c2e71de8261567084040f83f23e333a4d74c55d52acd20bd7c56142c2152407864f62c3d482622d87394e246110e133315d151dcbab02909cd0a10754681af44c2445331912a4031dd800e07e4aa3b37aaaa827738048a5afbae9677452cab2deca0205ca5b3e6f577892555ed3872bc845f97a86788a9577996810f0277cee3235574a6ec91cbd49cca68c870e161a7c9cc4b4c2252bb4c2f7cdc0863959061d73efd366a65c140a014cee9042734a9b79d67bf7ab6ceaf5a2c1feb9b283502f940cb7e49c199cc7a4f885bf4b041cf418eebacabb41067042b3c9c42a72655947ed2233a778fba0338ba0b6ff8c58858e48281799f94acc6694148b07cb1a5f8ae6de647251758a2a72f19a34c6176614dfb6294646c5b95c59d857320cb2233b9aede91a6837820ef74376ba533d06487939348cf70681053078466b900206af71a76d18a4e5f063317ecbb394ccc7b5ace6151b1fa662abe652186b92b3f785e828c2b1ad967feab658439c73ce93adc47382c63544fe5cea89a5c2602aced184cb45b18fd3108bdf70152421571b9a432d299eda808f8e0794e482bf468cb7b9b349932492f43c57e216281e1506d9a1679a54e4fb1986e284e6ca5466bdc8b3386b47e5103c0c70d796b4d42e17e279a9a31e434d2625efeb4abac6bcd3014bc1ffa5b6424674710059a74b6b4e4b32bb8b183c76d00a109909cc799430a2ce6abee67504f1a65f2d4c5a305639b0a1e31776797734dd535bf20545e37b33624865890114c01c874c7f78bd6d88ed73356ebe5b14db386cf677fb9315f8fd9a32039651a28338a0834696613502ca86f4830dd34b806a467fc2a726a515110c076dcb486eafac9040ac0690b79f5278022f59bfc316494a782d92310489c9f93e61585b3bd292165f651a7017a994b2512f0a5bdc8e77e9bab7e5cccaa7bbc779d445e5f16b871989974d92d2c268bce10764c0146a683ae56c47c4644057ce8b4739031879bcc287b194cb36fab6916ff563248d04851c74a7fe87f4fea546a565eefd507457882cf288ed294783179577ee898bed18c97660bdb726867a2c9581cc13bdb263dbb414d695990ccb897fa31984734e3178e081856627b0a4bbc736a235b3e392b3996441198c41bf8cef5ec64d2f5c4b628490736cbbc076d8ebab4cd1ab4936935fa3aa40d941e85cb08774520bde23f24739400bd45b1b056d8a09ebb49a3e4b7209037c94a47084604697185bac8772122d1bcf22888f165546bb699b23b2262035135120cf677aa7f767ca049b869137999884e360518358852cbbca3f90643764cb30fa16cc009766c43b89e599203d6344b1081e97c863190ab57d42812d603ab56068283cd30e92e3f7a8989715479cc3735f3cb1ed9120e8b8c720ba35ab1178b426c413c5e89eb5483bb0fbed13a2fd0783ce4bdb1aca87d80000dd48caacb57c74b802c6b133817ab099c84f1c22383e57a759ac6eab76df67876e3591f32595a56a027f2087b63db7dc138cd820a84b09411da2284ac78445850ba820c31b1ca97f3e680e24201fe67154b935a36292b18857007953a848c49d0236406e7a320243fee64ac24b02952d0a02a57ac4fba19ce373e3382cff61160913ca55a091696d782f4134db83958ded48e681546ecf2be93c09a9bea7b3ff420c84a9107f4a75a2a1c40ba0f9e6060e936218f0c0904bb29add2305cd59e29d2b10fe667f9ea49cfd149d1d8bd62e549e08baa1ccc63b8cbc734a24017e4a099bc5a939828ffc8cac5fb5d388ac8613216f21942675cb714e32cfe666357413773ab5f6a2c405179995ef42635cc7db7238dd7c410ba529e7d7391556c5f604c38fa079a70fbc2e8b393306832fe2a8bca891d880209b9719eb4d2732581408a3896735143462a45f5e4267084bda97a9a5324a2e23a714c1322f4368be3ea5219c10f56cb560a78786c2a51db18c79f151f3743a7de67c43a35c63d1b70e17aaf4e4c48e300a73f9c07bfa776ee8797f803ca148aba782a2fab110a7c4440c5791354b25c1107106be979b2077d422a6d8edbc04225ac63c3705394c9fd5389c11855057572fb303ffa365cc2854a3bf620ce5203b21bcf7ad9c675427ca1294c7b001e37a02be18473d1b13d9c52b9d59bc267ecb1fdf3bb96c2b374e72e4bc0898441c47adac60c1955bd1a5096f371bfc709ef624078139feb979c9ef48bc0bb9100d0a97198b466bc5821978c87da85c4e4164ba61a010b5fd99435dd18129a6b379c3232f75c8789d486ee3b6c84e052b55066e81c409c182d4e84926a42abac49846fd7b6f7c305e234130026540a6571d2c241c2700ed4e073d0262bf196164c71a62b904938cab91cf12fc8d527a091c20a86b163aacaf2f25d1814bf2d435dc7881b0f0219bcf40f90f894e74392fea065fd1b69f2e959cd0a5850b002cfaa8e44d0867a16ba5b173711d77f355a71bdf7674299a91cc05f2c772a5280177f2551b6f4a986f3bf584a899e755464166c3220130e694616f76cc3722c999536b6d145dfa5a27aa591ee994332893fa87acc2df67113f8a9c438abfa667022b92842c73b15047d6db08e02930a6348a71472a5e04bcf856058e785c10d049af83736b2f78f8fa0b16b0b7e897cb695ec20d37c35190a079a57cb41ba5a0f010f4cb94b585466c9a802f0855946361237a0840d43487bf65bd9f000f2480afcfc03b3dbba6ff053aae4981fc619d82818251c0d00ddb269042902b4c28fe6578709374f2461b0fc1a00441b78582db2a76dee8729be071ea3c9957f5a3e75934628081eb8339ca5cb5ae83677d4c31d7b12b0463b57bf7aae0af3901a9795085b8aed0564d3755588a0829615785f322add179edf08204021b86bb3cf8f3528ad652437ba8b0c6901cdbb748ee8a2d854644cb694668b9ce322992dc43f2d8a7ee655be3b257a0974ad0649104b6b4e9a16bb8cb79a42968ceb1cbbbdfc6c3921ae35f6b22ac3c2f858184475b4f2a12db3158b3bbf2d64f07ee186fc57de21c26bfcf6b645f83cbd47cef72136aeb64469835f3a1f1d9511e257abfead77d365076a5c423ebf1554cecc7b29c0a61b6762d7033947ae42ca53522a65fbafe18d3bc3e0cb66164e9a094fe4b44d8977ed" +}, +{ + "dz" : "3c815e57e9233e975fa1630208aab206b71ae0db37a7a8789ac683d9f9b2d29801c8e376fdb140ee343106c093af7cb149b316ba79446ceb4e5e0cedb9b164f9", + "pk" : "81d55ab1318e2c501e7d462cea98864e291c2c727e6ef2349332680fb06b09767a2ca72cfc078163c140dc7151d869a9c785ac62c6ade5f7519e070a08269938c7796b54b482f027a0c63ac24a6a00f7a0e7c65843e1c1fd01bd11d24ecf3c8b90cb803626044d03a39fcca7e918ae418512631898f417c9c9618055340a05f67b6f1cb7cc44117af09922cc07e9522285d16c42a7b2f833b51e72ce1c28a3ff37ab697cbd90d96b3e460c56c1734f1b11280ac33f170b3447c07f99a68f9a6f1dac6083368555782f800bc7f4409abf76b0eccb6da8f0825cc0c696cb9119340f663317913a641ff369657207194b65fa6b1dbbba94d22b512b56877120a6edc10dafcb2f727349e5831a3dc8a539c0a55a517e65982eba97930020608094b93e481fca819058537bb2c051cb2c3f0e5a97e8365a14491fbbc03f603977273a035855c414812ece238d254ba7334cc5bce7256716077766cc21c617a9c378fac1786c1cadecd13948591198682cbcf0cb098c504dc4b16a8269d13a701731b29a71432205660005919721c994011ca3c0ba8c3178a6d80b2abcc9f6e6b7880811894cc6e62c0134011aafa69568a1b95bb43c815c1405b4351a7290b856c50e284eca0cc384a4551f455b503488313a341aa25f80aa02c97b9d3267492c31652b7654621a59f1aa64ae4410a1099ed7f14aeb10485f794e61157c1563ca5515684db66eb99b76836a2441139a0906b35553c9e3e317f5e2c08487697574464a9936aaba528fe2b0c0c6b058b791d94aac3bac180b0609ab36b27579864c5bc6d8288292387dc4931fc889a45fc8bad636ae2bd493a5ab401311084fb57c6fd88c2f0c504d5c463738ba7c5a97237c1681d8aad66307ef648748198f6ea0c8fd6ba7ec424052c8a9b070c571b136cfa86f199542b12cb2a77c6973494bd41a2f0b55cb0e4122d0958026b7c54bc42eddc040cea8470f738f9c9916c158a9ca6457d8d9a0649337a3ec7347475eea8c34e8127636b3897c547c0479a1e22bb2f7606afd97cabee179467880dc02c7b6f892ff3a7a29844476fa9843943d68ba4df2db6b8368394b62cfcd257beff5b8b54150407c5529349769824af105adfabcc53f936a8a492825d6a9b1108f1ea258c9dca2d739a600f68616b2094ad29207184607985e3bb784d7977c20dc0585233131f93fdfdc9ee151c6937c7bc7fa4af43b3b1dc4774ce6273ab04736308e89e21eacfb81845678a0c220309a3c9fe3104f61680f334227670f95f2b84c137a964a0a3a57525a4b99b231a8f22830d5bc588c0c705189b2e8a19c4362cb50186b99b5a783031300a26300280f279987ec058425817327b481cbfc789f659530d9c5d9c8432959adf71741c1f9353d9a84836a5a5487392d19b5073a72869ba4e454c14ea5a93751322b8592e8566236a86c6619648be1782cd03749d9b9604209ec66804c64913a143887212e7acb54d5d995d0cb17e3e27c6dac70904235f5c9bb29d908d8098b11739b16706541f31b53e3a384e594a7a640629543943a1262558530c193d18079426708117197a90b1c45e8b394125ac46238d2e22fb8750d1c190824828280565093999608f4113acc18370509201056d589041d748b2fc71da15490882805d3d3c0fa0a837400b73d25688c698cc8d78d144a80aba8372bf7c349b9c395bbb8adfb885906402eab1ea58b622ff45c4dc14c9d11708659596552b18a3c0a1af2cd7b558f15f461f0501c409a120b4468f2c09282ab7b25f9b028746fbc9ab77af4262691a64dc43d59139c21eac58e58a491e26e10974e6cbbb82af385c4f77e7312ccb5194902257d3c4a4fa1a9035a670b5db47ee67c1b07747b889a6c481490462829b26184be3c9b0d7a0f9f2bcb10c8176f03464772479e9b84dd28ce94199d31845dff0614d02841f4fc92f9221cff071551e82dc829c9cf991e42265f94f7b4dbe7b791c244e37c3ca4192f70c32cbe9366db59a9dd8582d6e69d849151cb7c6ab82ab8e7854c7b4c15b1557443cc2b1284b7fc7b16e415007427b5a9909b99f21c47956c45e14022374440b70415b896659178d3c98bc4f3bbe904a470e4838849bcccc2ceda8b9bb1e2af29169d5919145b3229fb8c9ee705cff4d91fb9729c6cb52725321f208f2d0b39ed53edaba2c350ecba69a4ee1f3159930f65c8baac80b2e0", + "sk" : "4ee12caa4baa2439ab1e4ca28bbb4f3a85c606a636cdc0553d821ec2aab20d0394a0e3ac09c96cce60cbfd9a1351b3cceafb11ca7c87bc42a1a191506ba9b3b617a6aa7a705c26b7820068d930bfcc96c3728bb277b157cba1c1f8f17c415a1bc9e9ae5f4771eb38cfb7231108212167d6074ea1cf2d5b4c04179740c31ba48750e206c8c584355fa9c57d6cc84d1c88bb2a43fda99cfcb14da5e285b7ecade1761d4c711b7a83b738d7060bd820e03529c608937b4734f8237ff746b47b3460a40c9ffbb18b6b30437c4b55df55544f74bf3fc5758dd2b4320974698aadb0431f5670580ed39c1e1645101b635a49998157221ae3087229bb0f9ca04d2766cf308500eccf34c40730888fd9c1ae671415892a8044d780d27b3f3ba3751cb9c9bbe61174614d2f15339d0a066eb738a0b43b8e0ab0e422b64f50c125769bd812b1de3672a1976402909d353042d8c4a535a1acee33245254b575e71c5713a3dd919a8a9446b9fcc80368be2f67669bab466b91486a94a940e007a761461401d0512788aa06111c8c3da1b136d3074598cc7a9d9aaf0a390a6468aab1fb56a71414139840dc7582b439aa78b9194cfc00b0c357e8840fc583380942b26174838d558c6c441f1e634ac590bf9c1344b8fa95aba16c6c130d8137706c424092ca5cc2bab74340aa6ed81535fc6a0ab7b59cf276f55583759b0b009b4d6e117410212dae343eaac5946c3b379b7169cd5b5a4e838a2b0a7810a05c2ea6bf10667b4cd7a2e71b321d2395fa48a02fa08497fb68c771b1eae67d5c11224eb19ab241770fab2fc1800074e697d27b0ad3035cdb09772b222945a9bd9b2cc20d4b488df40e80776eabb475cddaa0efd3c05f1c792ee9c946e717984686bd43660eb334bf775cc5470462d03cde3c9830ac8a66879ea04aba173b0858425774fa9306590a8c273cdcf347202267b44c3c52063693abbafdf65f4a2949c18b0bbcd02812da0eb7f6a753b0893c4771a13986c408a2b2f3cb2144b1b7f7b6799177e0a258415cc91d449009c17a265803a038a21ef2911778242b043e19f986ab2754c33c31c8100a15f8609fc05804730d0b2212768901d7e4afd4451950cacc42e891ae845a53bc396ed0b6c1423584c6b575a535e949909ca7cd95d05e743c16c25b57fc0a973e7b026197c6eec688a5c19596bcb9879b44d2b1358f35b5a31bc3d8e38f003bbcf82a540993c73f30123c66bd31f04964235477d5323f69c6a99399055c8347cbb443c9ac5ffa477e05229457111dd212928b337dd6a98f59a303097536c10d7064177e06830497a644ac404226b688d354237742fdc6639a979625558ba4509cac106121d847932311e4c22340b056f0ab54a4a1b5bc186c864397d7984defebc974b25b211849ad36a93ea21d5eb9926f7c6b96233f11822bfdd822fa211ac570196bd1aca785463c56a7fbb602aaa3c8dee8bfee7c18fec5ad0f844ebe66b17d71337f71bc7335a86002ce28e65e6a5101c7871e9f651f04c1c6ec45c47bb97b1e4253e4110fb0339fdb84a7ca40a6f7ac81fb43681ed56c1f51ab7812cbbbc3a512ba340c566a9d60cd1ac90d568033d0e1166d70c9e10583e61282794b8247f4c2b248a71d379302b82e9d275f07bac252ac4d09633be60002a2a7cc23f1b1448c1e1ae77fe9cb8677cc3a2e8a1f6f3bb786a8b3b585946dd909ae296dc6648f1695b66d51c056e741c4468a3db6acc1c340228ab88d83cb168982008d9fb07b177278c893472437a12f3b2099c80322610c96c9754cdb513626297dd9dc5c8b64babbb2cd2b904a52d67a1d00c92462a291d6b509fa66de596516774edccc48ce2c145e625158381814709f23d3427bb56b465531453185ed500341a317f97c48373a0778293bf989529edc39ca931f23b341bbe18bb071c61e488e45e100091ab58f18a7f33335d11019a973899f173fef0b43454a2d091274c4601029176900d03d068164b2f1279094c16d38b32c2973958c0cf5362d34983ab213a4cc235d3ea428bf289d08428e02c3b23dbbb89d35c7c571a1cf018dbd6b377dbb2f09fbb30c5c0244c8782ac46e98c4cf614c42f48b49cfd8114cca11e1455a419c2bede2684ed140aef81bfff6c2b32911013432fdf751e5855320202481d55ab1318e2c501e7d462cea98864e291c2c727e6ef2349332680fb06b09767a2ca72cfc078163c140dc7151d869a9c785ac62c6ade5f7519e070a08269938c7796b54b482f027a0c63ac24a6a00f7a0e7c65843e1c1fd01bd11d24ecf3c8b90cb803626044d03a39fcca7e918ae418512631898f417c9c9618055340a05f67b6f1cb7cc44117af09922cc07e9522285d16c42a7b2f833b51e72ce1c28a3ff37ab697cbd90d96b3e460c56c1734f1b11280ac33f170b3447c07f99a68f9a6f1dac6083368555782f800bc7f4409abf76b0eccb6da8f0825cc0c696cb9119340f663317913a641ff369657207194b65fa6b1dbbba94d22b512b56877120a6edc10dafcb2f727349e5831a3dc8a539c0a55a517e65982eba97930020608094b93e481fca819058537bb2c051cb2c3f0e5a97e8365a14491fbbc03f603977273a035855c414812ece238d254ba7334cc5bce7256716077766cc21c617a9c378fac1786c1cadecd13948591198682cbcf0cb098c504dc4b16a8269d13a701731b29a71432205660005919721c994011ca3c0ba8c3178a6d80b2abcc9f6e6b7880811894cc6e62c0134011aafa69568a1b95bb43c815c1405b4351a7290b856c50e284eca0cc384a4551f455b503488313a341aa25f80aa02c97b9d3267492c31652b7654621a59f1aa64ae4410a1099ed7f14aeb10485f794e61157c1563ca5515684db66eb99b76836a2441139a0906b35553c9e3e317f5e2c08487697574464a9936aaba528fe2b0c0c6b058b791d94aac3bac180b0609ab36b27579864c5bc6d8288292387dc4931fc889a45fc8bad636ae2bd493a5ab401311084fb57c6fd88c2f0c504d5c463738ba7c5a97237c1681d8aad66307ef648748198f6ea0c8fd6ba7ec424052c8a9b070c571b136cfa86f199542b12cb2a77c6973494bd41a2f0b55cb0e4122d0958026b7c54bc42eddc040cea8470f738f9c9916c158a9ca6457d8d9a0649337a3ec7347475eea8c34e8127636b3897c547c0479a1e22bb2f7606afd97cabee179467880dc02c7b6f892ff3a7a29844476fa9843943d68ba4df2db6b8368394b62cfcd257beff5b8b54150407c5529349769824af105adfabcc53f936a8a492825d6a9b1108f1ea258c9dca2d739a600f68616b2094ad29207184607985e3bb784d7977c20dc0585233131f93fdfdc9ee151c6937c7bc7fa4af43b3b1dc4774ce6273ab04736308e89e21eacfb81845678a0c220309a3c9fe3104f61680f334227670f95f2b84c137a964a0a3a57525a4b99b231a8f22830d5bc588c0c705189b2e8a19c4362cb50186b99b5a783031300a26300280f279987ec058425817327b481cbfc789f659530d9c5d9c8432959adf71741c1f9353d9a84836a5a5487392d19b5073a72869ba4e454c14ea5a93751322b8592e8566236a86c6619648be1782cd03749d9b9604209ec66804c64913a143887212e7acb54d5d995d0cb17e3e27c6dac70904235f5c9bb29d908d8098b11739b16706541f31b53e3a384e594a7a640629543943a1262558530c193d18079426708117197a90b1c45e8b394125ac46238d2e22fb8750d1c190824828280565093999608f4113acc18370509201056d589041d748b2fc71da15490882805d3d3c0fa0a837400b73d25688c698cc8d78d144a80aba8372bf7c349b9c395bbb8adfb885906402eab1ea58b622ff45c4dc14c9d11708659596552b18a3c0a1af2cd7b558f15f461f0501c409a120b4468f2c09282ab7b25f9b028746fbc9ab77af4262691a64dc43d59139c21eac58e58a491e26e10974e6cbbb82af385c4f77e7312ccb5194902257d3c4a4fa1a9035a670b5db47ee67c1b07747b889a6c481490462829b26184be3c9b0d7a0f9f2bcb10c8176f03464772479e9b84dd28ce94199d31845dff0614d02841f4fc92f9221cff071551e82dc829c9cf991e42265f94f7b4dbe7b791c244e37c3ca4192f70c32cbe9366db59a9dd8582d6e69d849151cb7c6ab82ab8e7854c7b4c15b1557443cc2b1284b7fc7b16e415007427b5a9909b99f21c47956c45e14022374440b70415b896659178d3c98bc4f3bbe904a470e4838849bcccc2ceda8b9bb1e2af29169d5919145b3229fb8c9ee705cff4d91fb9729c6cb52725321f208f2d0b39ed53edaba2c350ecba69a4ee1f3159930f65c8baac80b2e03649c5c2f1142a51eafdc3edbdcb3c5150c608d828b7e1b9c1ace00f9a548fce01c8e376fdb140ee343106c093af7cb149b316ba79446ceb4e5e0cedb9b164f9" +}, +{ + "dz" : "588760826dcfbd36d9abe6ae44a669bb3ebba6a218eab69e30f18a3bd536576e0e860576285483bb5fd36e2f944d32c4317bebc1e441470c1372046a790d79d4", + "pk" : "d4f7656b2b7819120a7cb68a80b91f2783979e1a329574272a3b154b52843bf80f88d947c79a58ae555e819674df71b13ea48741d103d345a8d4786eb43012fddb0b01c3baa6a0cf128b099972449ecb3de50020b025c486b4b5b115c78d927fe5e06bf8e29068d0b3d963c3b46cb9d1ba3256fba01f2185cb566556151ed2e1c993469190b75fa75259a5b1096d5a1647448013c21eca67a3aba096a4dc77f35c2447e81114f732148663a9439b1304b148b813f12c61654688d35318b8c0a8c33738a2f1bd2a1b6e8ea93eec771ec8c0094d4c6a45ba61579c72c2a41ffd468a6c679fc3d6b15d5a549b1614bc8874304bb6f01b775511ce5bcc7c055441ac72c34ca164f461990a57baaa98840439371c26134500377b39ad6d222feb0b67dff197c550541b63173e2b1b7031b30cc3772e97734ad3c5b6243b3269c48fe055a82c9f4d1c166c294b8077269304cecbc404ebf8bd82c041c911b09fd7c2cee33fee1bb754878d8143cc93b81c7e99323b5210e7a64c7a3b8d96c1594ff3ba50132484e663797246dc3238a1eb743c4a33c51c6587a224bec9bebcf5ceaf175dd37c3591ac7d82512e9ee7c4acba2cf5bb26d3a2188be321114a7724c797a2bb26cbe43b3fa03a8bc16dd5a49a68544e9feb51786c46794c9f5239b7584acff68a2f7561bb05e6b5505c249262b509a922e97c40b4736e8fc2af4017acce951cdacb3385f060cc1c55a4f79a60daaecc939036115d2f480f6f0315fed05387e99f9448b6155a51d66a6940519b361233b2b7b34c740f0cb64a7cf0bdc48677292b0d1ed5898ce928e9040308807cfc730be0d8c614d322735c1af2d2199ccca1dd80a96cb60247125cab18ce7a1c5e4f0c4b978581742c8550cc9c84b0632967654b968c01492557ba0630ec0caf04a443d9b2f616a9cb4ca13da38fd9d611a59bc697c20e8eaa0d2b96aa2db111bba3a05fb463bdf7a777cb91b1086adce17ded04be8b92254ec5442a6852134b5fde9b060fda258c18740b79970dc981cdb883cbe3297fa33ea988b07f9a581bd086d53507ce07536012a211c6b4de17b73a08153c3514daf12185416a81c61fe255a3e04b33e3c5a6a0188f6e09855ba504f838cb8417c2f0e97bbf5b937ff53848031274489b5366abeca2caa7636cdbe83f15980c02f207577b5efb947692fb40ae7b36dfa83b728478f0541511fa58aeb121c14056451654d0dc4421695864db64bc271a79ac0beff724b6bb2290cb64087b72297a6c3881765cd909aafbae72c9448b232093694ce522c72d2475f281ab1b633432175e3f78715de1082df66f74a351903b115d74489a32bb7a873aacf195f8f043922272cfec2798f52f65f4638302c62648199e7979f4740b30d38f7d794cad179ac960c838db4ad7038ab84955960b4822324c5d01c5985ac8f47138bab522db895af2f9a983494f360b061bc5120f385166a5ae9ab844c278008e47b655570430451cb606c24840b7a0e51268cba81998697a5653e33bbe47d43edc3249c32964e87bc8ccdb6d603c0f7387306b043fdb343e8500aaf0104683dc9488b0ad3d04a1c2657f11a99d46b040d0950d0937a4927012f4a78ee2405eabcac445845d7e88b54a8c57947b7ec0c12bf654059d93ba38ba2e50ca3fee8194053b2c9f10cae8c846710392733123b0eb0ad895216efac4931cc782e886fb2c87bed305cdcc690dabbeede21addf7468e4873919865b905b3149a4d686b7c96fcc014b578e1d36bc3b63449f467b09bc84a92b20b01bf70200e703a0ed084c860f40a336576274c7e5475835bcc8ec515050eb8215f397f6312c9b1db1ac1da29ff90a4ed58b8f8623d4b893e1ff94e3e48a0ddc5c221c0b34a798713897bbe16a4c298c5e9f44932b09806e554f76b76fdb8744cb38d00f24f5cccc75dbcb3f81233c454ce3664a807d82c68255c422866cec26ef6e428677b4db8f712abf50c1e11c9f014b9ad59077cf0475f925568300c49c08e4e17cb7a5581ddc17331eb3bd7bc04c933b646224d3386a3140cadd445b632268458f63942455ca1b164c9ccb2ae679ddb12524c34cf823b3626b224e466245cacbbcf57896b7acc6f6b702ce9000371473c622303db63b2744c7138363a832b2973bb3144bba8001999eef108e317890c4b63e857c6de99266629d3267db18fd97baa47b2da64fcd1", + "sk" : "04c78eb9c2cafcf78072b8508905b42c5698b3c86d8f20bcdc31a3e0801a084b35913203a642cf671c434ee39477e83d7314bc81a5b0a5d010031a26dc55bde54c5194525091314212063b7e852476364aa64155e6e9a52bda41c17939e553c26378175fe3c4cff13e3f20543a275d6263276d2262d1a9596b52996c4982817a4fded3924416b65e9bcaa45c6a6956c3724c0ea4171757393b5af903de5694e8962f3a122104092924f25e1590419fe11cdee60bb33b5bde000f7d621811819c77e4584a89659caa85e7197588498ee8c8a8397c1157c29a7c8b696653a941ec2579c1ca7368bc0be8bf4442222390bcbb871aec382de3c5011368cd420abd03fa8bcc35a99aa27a1412515710b3f5118eabcc9055a09b350644a490bf83dcac4c2035c81895ad53545d5b59bfe5455ab9c7caccb4418b5830838e0403a56619af355ab2448a69f2b848ffb42a8f5407fccb9c5164b7f306b109533dd8c690a5a9332f058a1978915244645eb127b6ab92a732bfa7f0b528aba0bcaab51d52a54f57cf75c54ce462bf7ab8414c9974b58272357bc204d13d198058cbe21781e7a83507a7e1220195ec34cc84125d18cb7610b3996035e755421b969ab6cca1b79a8315b791d96207b6920af2e26fe66ca583a943aa3914a930943a723447c1639c22a937d91240839824547eefb69e8c5868f0fa6df79570dc01041d763b13c08084b8cf0213a5eeabb0d7507a0f8837e9138cd99349d4b2acd1f72749b804eec23f88ea19b00b5fc06bb665886c105786b45610e9a431ff8a48da00ad35369843096f542396ea143974791c1e830256eb7c291368ba95009e6b4ae821ba1839ceee153adc9b7fd5b6462d4938a9129898b9ce6be51c9ae90b065232616712580a80c6e57d57b1c597b526cec406a948abfa1bba5d1835eae0755270b8ffd5cbdf772c5c68c4a7f66f972c1c49553e206b08ed95067bd615b12b35f3e84f6e7a8fd72180fd904ac46ca901b89a5fdc2da3b472f0a547901755194543e7a399c4363c33cc305345b79ea06889e12e049319a0428142e6a77d4b7223c72d3dd0c8e3c315b2677b19fa8c1ba7107d10b31e719a2c90abc3102ea5e074f9707fcacc8a10e42014c21d7aa74153da8b80779ef71a86c9d10bbafa7432c9072e3cb4def92b9264af134917dd24a687a492f0d351d3e9c61a421d0614baf259752db556c8bb401dfc33d9b0869af44c81210bc25aa2ec07afb5ec862d390c6794a0668580ebd39a23f914feba865a33603d5794e6f4bc210bb82b7a3914c1b5812120aba6a58ef7381bc89e49817f0607980c93458343a12e26666c664832da7552b804ab349e0b56a174716e3ef1270669653ee63a73a09c66e12c7b343a7ac13cb5ac4c740057c947bc3145b037d756bb8bcbf46097dce24c2801c0b364b8e02329f7fa183c1003fc715ae470b50f1561fb3168b421727e66940a717a350a69aad45e506144fd528f07235fcdd0c5b7b659f8c0bf85bc53195c75c447442e533b12e08404db99a7346524964e312c48736c99a651407a3661b3812f83da22f2e455483c44af351ccd50721828313586665e95804f9a4e7d3878cf134a9d815ab4fbaa711517119043a46963101390c20c552d4c5366a92693526ed0893aa097481f8658122c3df8fb21a150c52f9367991bb31955035d286fbdb5040e58556b2a8b7c88011877890f9abbe1292f9bc36cea7463318c5047629ed9a31c39d65f92c18b02e5a7eb16c4aeb68d7a057623f25c0ac68b48aa3a06aa534830a790cb36840c8e1c4b653cda1acdc1a13777aabdf19f55b66488296f407366dbf03d3451b8c55284a9f15f8f16cf51ba93781550ede5bf43ba4470e6bf1d4236c4c78f7710bd0df79f98d55873aab6e8e573d88b19655497812aaea85ca6b95ac5e0e908d2150d68c110e24a48f0e7a581eb4fda5b7c3d97a68e26c9f709126089753d2c072e88ab97796600b2732104acf744471bc562bfe4a995e88c36a80c5479c0f1204fbc6b723a1b1d3f817341853a02d75c1497b18e242e9e037aebbabf28bbb5c4b72f22eb02734bbf5a897e77f84d9e4209d3fa77eed12bda34378a541e5e5c3258399386c49be1a05b6c509724c68d42b5a9be11bc08d154c9e07bfca513256a52d4f7656b2b7819120a7cb68a80b91f2783979e1a329574272a3b154b52843bf80f88d947c79a58ae555e819674df71b13ea48741d103d345a8d4786eb43012fddb0b01c3baa6a0cf128b099972449ecb3de50020b025c486b4b5b115c78d927fe5e06bf8e29068d0b3d963c3b46cb9d1ba3256fba01f2185cb566556151ed2e1c993469190b75fa75259a5b1096d5a1647448013c21eca67a3aba096a4dc77f35c2447e81114f732148663a9439b1304b148b813f12c61654688d35318b8c0a8c33738a2f1bd2a1b6e8ea93eec771ec8c0094d4c6a45ba61579c72c2a41ffd468a6c679fc3d6b15d5a549b1614bc8874304bb6f01b775511ce5bcc7c055441ac72c34ca164f461990a57baaa98840439371c26134500377b39ad6d222feb0b67dff197c550541b63173e2b1b7031b30cc3772e97734ad3c5b6243b3269c48fe055a82c9f4d1c166c294b8077269304cecbc404ebf8bd82c041c911b09fd7c2cee33fee1bb754878d8143cc93b81c7e99323b5210e7a64c7a3b8d96c1594ff3ba50132484e663797246dc3238a1eb743c4a33c51c6587a224bec9bebcf5ceaf175dd37c3591ac7d82512e9ee7c4acba2cf5bb26d3a2188be321114a7724c797a2bb26cbe43b3fa03a8bc16dd5a49a68544e9feb51786c46794c9f5239b7584acff68a2f7561bb05e6b5505c249262b509a922e97c40b4736e8fc2af4017acce951cdacb3385f060cc1c55a4f79a60daaecc939036115d2f480f6f0315fed05387e99f9448b6155a51d66a6940519b361233b2b7b34c740f0cb64a7cf0bdc48677292b0d1ed5898ce928e9040308807cfc730be0d8c614d322735c1af2d2199ccca1dd80a96cb60247125cab18ce7a1c5e4f0c4b978581742c8550cc9c84b0632967654b968c01492557ba0630ec0caf04a443d9b2f616a9cb4ca13da38fd9d611a59bc697c20e8eaa0d2b96aa2db111bba3a05fb463bdf7a777cb91b1086adce17ded04be8b92254ec5442a6852134b5fde9b060fda258c18740b79970dc981cdb883cbe3297fa33ea988b07f9a581bd086d53507ce07536012a211c6b4de17b73a08153c3514daf12185416a81c61fe255a3e04b33e3c5a6a0188f6e09855ba504f838cb8417c2f0e97bbf5b937ff53848031274489b5366abeca2caa7636cdbe83f15980c02f207577b5efb947692fb40ae7b36dfa83b728478f0541511fa58aeb121c14056451654d0dc4421695864db64bc271a79ac0beff724b6bb2290cb64087b72297a6c3881765cd909aafbae72c9448b232093694ce522c72d2475f281ab1b633432175e3f78715de1082df66f74a351903b115d74489a32bb7a873aacf195f8f043922272cfec2798f52f65f4638302c62648199e7979f4740b30d38f7d794cad179ac960c838db4ad7038ab84955960b4822324c5d01c5985ac8f47138bab522db895af2f9a983494f360b061bc5120f385166a5ae9ab844c278008e47b655570430451cb606c24840b7a0e51268cba81998697a5653e33bbe47d43edc3249c32964e87bc8ccdb6d603c0f7387306b043fdb343e8500aaf0104683dc9488b0ad3d04a1c2657f11a99d46b040d0950d0937a4927012f4a78ee2405eabcac445845d7e88b54a8c57947b7ec0c12bf654059d93ba38ba2e50ca3fee8194053b2c9f10cae8c846710392733123b0eb0ad895216efac4931cc782e886fb2c87bed305cdcc690dabbeede21addf7468e4873919865b905b3149a4d686b7c96fcc014b578e1d36bc3b63449f467b09bc84a92b20b01bf70200e703a0ed084c860f40a336576274c7e5475835bcc8ec515050eb8215f397f6312c9b1db1ac1da29ff90a4ed58b8f8623d4b893e1ff94e3e48a0ddc5c221c0b34a798713897bbe16a4c298c5e9f44932b09806e554f76b76fdb8744cb38d00f24f5cccc75dbcb3f81233c454ce3664a807d82c68255c422866cec26ef6e428677b4db8f712abf50c1e11c9f014b9ad59077cf0475f925568300c49c08e4e17cb7a5581ddc17331eb3bd7bc04c933b646224d3386a3140cadd445b632268458f63942455ca1b164c9ccb2ae679ddb12524c34cf823b3626b224e466245cacbbcf57896b7acc6f6b702ce9000371473c622303db63b2744c7138363a832b2973bb3144bba8001999eef108e317890c4b63e857c6de99266629d3267db18fd97baa47b2da64fcd1f651c0028e1e5653a53302082d4e89b76b6b6a939a2f2f5b6b7d5931ff3ed6c50e860576285483bb5fd36e2f944d32c4317bebc1e441470c1372046a790d79d4" +}, +{ + "dz" : "47550e9edacb6ddce3d9ab81f6b61080dd4f2693854acb05e0ccc7a4fb6390fbf89d7d99d5c3e0d10d6ef9af054d842375f695abb28e3b8eb495100f04306e92", + "pk" : "2829b04a621a204a4e63a2308d728b28c16652fa939d455181fa1b7b44447d1abc83e46f9d5c4133b104cbc1369812bbf9e83ae1e58f66f8b7c2e56d902cca69dc841f31372b783bc6421723ab0b2bc21cebc7cdac0cc3c55a3a088c0d21a4271264945766740af06ffa65275f9c00b44b1b3e6823d3c29c0a509bcaa2be1486972dc178821c40a203849a3abef402408ceb1e543c3bef193417bbc0c5679c13074063e83eff63af43464b3ce47e4b86953bf21583c2515f7b1025bc0e50454a08313e915882dbf556fe9b18ad27250030723db50e5dfb2380d8b74874c78862a1bc9083e1a8438e546ff9ca64c4a53bd17c1558067206056a0f222c8a4a00b2a92631179b6aac71fc711cb635b008f28cd69b51b5d7aa6839a1aca1a0da854faa39925cf606ae20612fc9c7573c73393a033cc8417d427db29bb6973546a967354fca3c43223a657713e150262e5621053bca46931248386114564cd4c0861d4ca648e789efc4221f7a075dd8b119ab7bb3f467abdc6cd3c808d1586199ea7be6e75c03916da4c012d8e81843f472c8504ff4239d3c0881e0e664f6e253bf2112beb301f19774e6998d4e8b68332346898087f1b7460b664d5d10b1ae199ba661cc460685d56808d6e66f3a78b6f5382ee3eb945482a1419a0a509a8909e8ab02990166c84905c7533159a9dc447f11f649e367486e2191a6c48b61331fb6137051b1410467cc440c8d0f9c9369b8803cfb33da7416dfc47db6726440028b23807c0f68804915a09ab16c47287d4eca5f19b98839030e9606815629b1e153a5cdb954f6e3281749040d91061df4afb67a5f8b19b30abbbe9b4b98b39182c4e48d514c35b515cdfb5bc61553c7ef047b17ac2ab3d10fe7d86a78386a0589072fc58983058a6959915b12a80ec79035c660afb04e9670cba471125e7a16d9fabea6ecbfe1d18904757b0bf6a459f0087dd193be490b4bf87bcaf772547b863eaa703ae18b58926aee14cca8015af2939a49e29d546b968ddb17eb62b9eaf9ce53949e7477c4e9893a40766a4a15cbc392c73b313a0ee3201431bf3d5555dcf73174f3299c2b88dfab4430c08c94183c27d1035c78769b143563a942047035a6c2373a03c0bcfc3973db4f8f25c002c46376d6a6fe103bc641608e98948d86bbe6e89d5405542587aa4821c30ac8756f07c593044570f536b4b07fb14b3236422d01789822aaa020e4acd92126809b2d47f49049875c15472a37b4b033fcc260fca04ab629474c9b82450ae6572d891a58629caac895bf2f52babeb6974be787397243b20a99f37b52ee77934ed2b6157ac3351b9c0f3405369885a54bc33b2c487200ba8a326b9d1674209924d3d50527517978eb040bf85ccc9569a6b3138f072084595825a994078a09bee86ed1e75ee9e759b31c491d9292fd2abbe3cba62661ad9440bbd392cb7d303cfab4bd6b0130af1c3336e2768907aff0633f18f9bba3706434b3bce7c75d6c40753b6bbeaf11c47773cff33b5067890fd5b8548e66c33d25906a066bc421617a909196a3986d362d3b80095e1077a5a087238054f2d89e0fd9a0d570c5ee2aacd3abc16111189aacb4d2e911abb7aa5099bb4a269d760174c324094fe944a4dc55d7708395f6aed8654831f7c3ecd85baf03c44390193634b16e1c91aee33979666edfb18d7713c547a90ff9514ba6469e0a6716ff4c0420427bf00b794775043e162e798871f710c87ff423d5580d873b7f624c96c7d63e23ea02b1c800914a5836fa73d7a748472b0b7af3099eb933f4a440ecd48262d4c9de4c044ee30cc51877352b53b0c1c14153c88b44931df12ee8520cd07117a1266815b74a431652d33074921c1d6dd6c0104aaa3f1a84e2f7cb24461290fb321d706113b172a2c7bdee921dcdc31640f9c749f4b27d024a7488728f605f8ae904571062ce9b36c009937f51722639782d56496fc056b06b8a4a6c3f402649e0c15eafa83e85a40eda43433c44b6d8f037487c9e1b66622c6798c94b9228c7a52bd18360e07ac4b057218469ac09b397477d7f5325ca47b901d0a5d0b6977194a12f71abfbabb3d910a8cbc52ca0dcb4f9f52d36c22b71b8513070c1c6c9a33397c79e4680862196cc1c3baea5bd04c58ab295b5da152a98a6ab3035b2c48478f30cdff392b47dc011e8fc82e0914e5ad3c8eaf0f76a57327c62bc9d4d", + "sk" : "df9a22dc6c97b1e41ab3d6b79d183b1ed95c6cb32277a25155d380318260933cb26e427fe1d6be2e40bc02ebc9e85a3850b30689acb277096d8d48cf9b3c6b699864fc4b085ba86fd2b92396dc384d03428ceab2173380603b49bf2668af38967b4145a427c04a5541357771256277f7956335da5bbda033fc7b3909321777e2991189a93b730feea54fd6445796726c52752a7d11235c8461c281c9bdc3651dc72b4bc86efcd5cc62a18ece4b6586b2b0be374ce392214cd175117453d393842346abf0a0527e791e484c08b5324bc0e489ce327eb536609c4a646330a3d1168401f9420ada3f4b7104af688bb2326908d023f990ad064b6fcb4ac12903290e93bea142a092c72b9b77b56f27552115057e6a7e92822ea635c1419159c186690e67beac07785e0a585681c67cb73aad460378691b07d653ec0308cd0c21058892d34c437a5bab3bbc83f660b644507a5dc00ad5e01a231a7d426764b9561c974490c85911ed94330ce8ab4b6c0c72d67114096691d1476eb820ae01ac8df78aa1fc10d2b898a8f600cc1878360961ec5018d7f63d79744b41da21bcd086e55a83e1b07aabb47aff6831e9ba51dca086208531d1205e8124b66a40a5c0d7249a29a1a218be0f6091cb8135f552b81c397a000ab923050d167940cef362ba796b9bd7b7f1a197c8704ab51c63f362c368c77dd5563b82336edb912984fb144e46cf21a11c490ca7e8c66cae89772b2b96e8085abeb82aa8e33da4b56693f81592545ddf9176486350e86229b423072d586852328e7bb2065d5a7a8600aec4911d07271d75924d412494cf77b868aa7b192a11a5d66eda19a10ee8c051d456fe7846bc8c52a0923d76e7b4e5b27bb2e2a03f8c214e6636620b54b893a3c9ba9bb7e68546626f601c8591bb33537b71b9302a15b81d6fb7919202c45c0341e3e17b9cf39964a4a48ceb4b7d936fc007c486f40b4265a8cf677ab5e97d1381bf1d8267e4445aade22c4fd536392a6219d3c9855b06de9610f714a5eff2158f4ac31a29b71e0a9db207c2075109c0fa762b70bdacf391399113fd8429c48a6a3edb5d465a45e357332a7a1ffc414325849d9325be55586aa9535f85e20ddd2696a615139c037757514295173dc7c92a5274c1571c0893190c5513c990c5c1fcb67aefac3be248c9111c752c94c180fba60064af53d35ded934d7c72856bbb9703fa43ad125e285626065869c10027e0c374a28732bb238b426905491c25e73907d293b40777782c3ac846675502958bba239597fa230930b515996e5b3054581a94f0f848ce13ae14425aaf593b175635b6db63131c14abdc4be6e984e62bba9f95a9c3d986c71640ffd1a3585c20423068b52662929406945199fa67a87f289cb15b85e6b28099f3477b8166d0d398ba922c22a1319cc168b970c699706eb87891b1504f99f91919da8300a49dd8d292390c41f9735ba65c19fbb83c80e08392f10b31c0c18708a9b1780e253404bcd5753eb75e269b980ec34040a4495c2146ba5a1edf3a8f228bcc10206d2868ac73318a361318be704518a71b0cf65eb91823b643392bbc02b0e0835832adbbe34577119c75171460a891efb51559282700a80e65797e6b367d444c024332a5bbfb2b8c9619e1498adca52e985a9d03b91f356718e15bb11ac4bb133c08bb82c2a9fa0ff8785e92902818d314bff162bcf5393dc0b2739a7271d02606673eec47cec412484f9b1437c688b3f147f1792a463738649a0df8d0480e0a1cdfe3107d48c5ac11c3d7dcc204b439ef3533ddc2098cb22746001ae103c8d99704e7974e27b710a57cbd9e7a4509ec96374b648e6c49d0b0b0b7354e3dcb206e5b47942a29c0c498c7a1c1d401af425a604c729a8fea21a77aab00c67db762b5a32ca0e73aa9f5e2319ae5cc419c964c418f19276bbee6af76aa4fd04278d4c28aebd4ca01b6999a5c8068540a07c2823116a4e56468abc468fb222f32326bf5c02eb313c4b4ab4d92f408a60047d6890de1ec3994e23ec757c138caa5e3cc14b9d60153565af3c20581a24d2684c4d251aea1b36e56042fdc7c922812ae69796cc4912c882c5d46b4a2af9874d91c3982660c2dd6749ebb2484009be255177c9ac65623c65e0a896b1979e9ccc093ea5113fb59d4cc6b2829b04a621a204a4e63a2308d728b28c16652fa939d455181fa1b7b44447d1abc83e46f9d5c4133b104cbc1369812bbf9e83ae1e58f66f8b7c2e56d902cca69dc841f31372b783bc6421723ab0b2bc21cebc7cdac0cc3c55a3a088c0d21a4271264945766740af06ffa65275f9c00b44b1b3e6823d3c29c0a509bcaa2be1486972dc178821c40a203849a3abef402408ceb1e543c3bef193417bbc0c5679c13074063e83eff63af43464b3ce47e4b86953bf21583c2515f7b1025bc0e50454a08313e915882dbf556fe9b18ad27250030723db50e5dfb2380d8b74874c78862a1bc9083e1a8438e546ff9ca64c4a53bd17c1558067206056a0f222c8a4a00b2a92631179b6aac71fc711cb635b008f28cd69b51b5d7aa6839a1aca1a0da854faa39925cf606ae20612fc9c7573c73393a033cc8417d427db29bb6973546a967354fca3c43223a657713e150262e5621053bca46931248386114564cd4c0861d4ca648e789efc4221f7a075dd8b119ab7bb3f467abdc6cd3c808d1586199ea7be6e75c03916da4c012d8e81843f472c8504ff4239d3c0881e0e664f6e253bf2112beb301f19774e6998d4e8b68332346898087f1b7460b664d5d10b1ae199ba661cc460685d56808d6e66f3a78b6f5382ee3eb945482a1419a0a509a8909e8ab02990166c84905c7533159a9dc447f11f649e367486e2191a6c48b61331fb6137051b1410467cc440c8d0f9c9369b8803cfb33da7416dfc47db6726440028b23807c0f68804915a09ab16c47287d4eca5f19b98839030e9606815629b1e153a5cdb954f6e3281749040d91061df4afb67a5f8b19b30abbbe9b4b98b39182c4e48d514c35b515cdfb5bc61553c7ef047b17ac2ab3d10fe7d86a78386a0589072fc58983058a6959915b12a80ec79035c660afb04e9670cba471125e7a16d9fabea6ecbfe1d18904757b0bf6a459f0087dd193be490b4bf87bcaf772547b863eaa703ae18b58926aee14cca8015af2939a49e29d546b968ddb17eb62b9eaf9ce53949e7477c4e9893a40766a4a15cbc392c73b313a0ee3201431bf3d5555dcf73174f3299c2b88dfab4430c08c94183c27d1035c78769b143563a942047035a6c2373a03c0bcfc3973db4f8f25c002c46376d6a6fe103bc641608e98948d86bbe6e89d5405542587aa4821c30ac8756f07c593044570f536b4b07fb14b3236422d01789822aaa020e4acd92126809b2d47f49049875c15472a37b4b033fcc260fca04ab629474c9b82450ae6572d891a58629caac895bf2f52babeb6974be787397243b20a99f37b52ee77934ed2b6157ac3351b9c0f3405369885a54bc33b2c487200ba8a326b9d1674209924d3d50527517978eb040bf85ccc9569a6b3138f072084595825a994078a09bee86ed1e75ee9e759b31c491d9292fd2abbe3cba62661ad9440bbd392cb7d303cfab4bd6b0130af1c3336e2768907aff0633f18f9bba3706434b3bce7c75d6c40753b6bbeaf11c47773cff33b5067890fd5b8548e66c33d25906a066bc421617a909196a3986d362d3b80095e1077a5a087238054f2d89e0fd9a0d570c5ee2aacd3abc16111189aacb4d2e911abb7aa5099bb4a269d760174c324094fe944a4dc55d7708395f6aed8654831f7c3ecd85baf03c44390193634b16e1c91aee33979666edfb18d7713c547a90ff9514ba6469e0a6716ff4c0420427bf00b794775043e162e798871f710c87ff423d5580d873b7f624c96c7d63e23ea02b1c800914a5836fa73d7a748472b0b7af3099eb933f4a440ecd48262d4c9de4c044ee30cc51877352b53b0c1c14153c88b44931df12ee8520cd07117a1266815b74a431652d33074921c1d6dd6c0104aaa3f1a84e2f7cb24461290fb321d706113b172a2c7bdee921dcdc31640f9c749f4b27d024a7488728f605f8ae904571062ce9b36c009937f51722639782d56496fc056b06b8a4a6c3f402649e0c15eafa83e85a40eda43433c44b6d8f037487c9e1b66622c6798c94b9228c7a52bd18360e07ac4b057218469ac09b397477d7f5325ca47b901d0a5d0b6977194a12f71abfbabb3d910a8cbc52ca0dcb4f9f52d36c22b71b8513070c1c6c9a33397c79e4680862196cc1c3baea5bd04c58ab295b5da152a98a6ab3035b2c48478f30cdff392b47dc011e8fc82e0914e5ad3c8eaf0f76a57327c62bc9d4d63a647d85d1d66436cdf42ca198a44b31aa9f9d28b0311fb858cb5ecf74eb770f89d7d99d5c3e0d10d6ef9af054d842375f695abb28e3b8eb495100f04306e92" +}, +{ + "dz" : "610afb64be8cc1df288cfb016ee2f44c6c07113de7f6fee071fe0c3fe31c6215cd292e4c5f9e1a55e0489bceffb204d672a6215f4f3980a646d9f880817c52dd", + "pk" : "68d31d58c83101c3626170b992c2ab3c181f3d58b554249aa9e73c9e691be2c6c402755ce0737ca2e2524ff59d3397b417965ed4c547f8dc97252c58f4367379f4bc9da75b64b4a40a329952623f0615117d28af7cfbb994b8ad70b2540978242ca0609a082dfd70aa5910778fb1cfe537c5c1aa5612029d9b972aec8235466098558c1bb4fa2b84e1cf9c16300035a57328b460b20facea43d5502958b968547b60a3c9255ea20faeba1f4e69cef343a6f3793d4b0418edec073909b6786a38fa3337c61c8f7af5a796f41a3731a4ca6096382423c941616452b6a5438977445ffff43d54e7b787cb9bc6c95c36003d87b9bf08934996f7301618c5a2a9b6d5d802d57c02018b44b0d95c5ac1c46b910dc518277be4c8960400b14c51eec975976975825b2d574965c338c121a056e2b9c9cd88ce4111c0eff01db722734b296540ab44a40214646c32713c87bba448d349cd5b160db48411a77593886c81ac1b59d10b51e8338a4178082ee858ff3987e58cb7e2a58cf23c28ccfc6141270c5ed0b883d01092c3095f0abafa2c43eaa7181136bd6e2b0c332b3e78ba665c73304df21d83cc3915f9c8073b7d6d907c13bc4a295432fb0a894958b98c9629d6a025e3368fa234399ad0aa5f8c8fb54b9af1d3a18d1a7ec1b22e7f5056c0d97595a801885202ff8c9ce2315ba340924d1c5e2efb2de7c1a468b684c8f7a363eb98dd4cce7ddab73447a5d263b2cfc4129be74174b50ae359c69f086153ab30038a13ae21ab5ef870c44490990806c4936eff553ccd9ac01d90b1e3d54bbf943b19236b935cafefeaa1059823b1d928cb77cbdc0ccff4024e79219852c0653ecaccc3d9292a18783c10cce69732dfc4585c8a45138ab94ef2c84de2aed22b98bee16bef556331e56eb43c3d92e55a7c1bbc0474251a70ac72d5cdb9b2a9ebb9be53c0cfc037c1678a1351cba5e91bcf7147002518b8c8933cca1c34f9da03d2b70e885059b259b499901b98345aedb9075aa1686e36a85c6337f01b4ea2f2ab29939eba618c68c5256eab4e6c1a1beb334f93e99bcf3cb31012b1252537f8d1a589430b46e487ad07cfc5c58a2865b0a92a621006248a46c837f095109a3de16b24b2339a509284c9055778816e9656c743a8929cb622f3e34f0141c820d231501c920581bc259c8be8b0928b58b6f1e2b34b628301230fb18c3904741a0f061cb613b560e972b406c44e154724f6af887a345acc63065481c4b468423742e742582386c00f2531c67835f3c679ebfa9aff871f0b006c461b760fb3171b99c9cc74a5378c3ac78c87c847a65f4bcb5043a551c223418114d58bbbf6aaa4422aabd4d70e7d78a61fb1af33882eb5bc886d154ee032b0cf300efbec2acc811ccd2c6968e90f6d146dbeb0932a569896f96a91ba3298c57c5ebb4aa130a7730a996054b9c058057fdb41825a2323799bb0a51fc0018428061ab3f3c12a6479c3367810acc4aa869867f5888a90a1ac51913292a194f1b3d8c976902221d3b0c607714f4fdc8196859c939b499e511f54e52d059a25449068c39081dd59624a6515e282935ea454cae482ca990a378a3b41e0b0adc6702a9533c0c479a4f6176be1a9a081a357f5bb98f835ed13ca29eb969f3a7c759b43464155ea78067752534d1044be2501c38387b31c662e6b9cfc4584e5dc43cea0805e273d9e56b71fc924204c8ad82ccb315207afe34efea97f72a21760cbb629d6391ac85fe28ac568b1b96ad8b888c9cceec93fc08825429614be352c55ab218383ccadf0bad13862778bca36285d67381164f5853340c0b9516ee3916700f4c3b8326e497ba7966456b6144b87f70c89cbc07a3a553c60b80e01c0c7e9297ec70e5a3017e906cf24593f86d3b6d1db26004b8ebd7047339468183c20df37055637995522a8322b04618b123bb3b1cbf765beb8cd17a302b88166fb84a9bf1728bfbc57853b7de3f113257359f6b7835e9953da123bfcf545e5e3541c8620f5f58872f1192b67424b5a9909d5324a342fc74caf906c69fbe3b2384a2a9bab153439241d6065e0f944ef67c4d6873635b3650bf4cc4a4b879cca63b6873c8e681982e4a183557e0465bb0f60a8b9d97625065d4727731e173977a95e7bc2ce3494b58071c1b89b1866c85ff814aa4843f7ab5bee6124c2166757943afa3df3d5f59581246cddf8777c228d", + "sk" : "536b38508a50a06441226094dd386686e461226c3a3c121f4c906608f7a78ce66d7f574d479a7154c87e1e88278409968859356c7b6dcfc0a9cfc473e670bd377849619887ab701c3c4a1d2bc0b6a9633247cb47e8305d983b80a37462512b1e587ab1a80293d3ec1d9c785be97b7960e96cb4bb2a70454d5c619022cc647e12b67f786c4f386f68c03caea65fc0c14d8d0809b5a181f3fbcc5446037a00bed867264f167c69152789e38399356e1eab187490b8c8c3c5b8f226bfa41877374d41972c151b11168c5d971740a373967492804bc988afc31e7cc195f71c8cb4a53c39d16666982685368194a70fdc0b7ea96729ece4085c6c59ae12218f649e1552998d571c0a41503fb278c2195d16f79012251ed5eb281ae05f88650cb62017781b7ccd534a0646a4e2e2a4a8f6160b64cc3aeb4cd78c17f633068d299b286730b2db36f2963ab421b0f3dacfd18a5a02aa807b47231001ac238c176bc01646541f465b832c448ad4f157093c8d26b0b1da121d17c21c71c64bdfe4793095c38d930b7a26a85c87c5b87821c389bc4f3ccbf42424d994754073605c166731a48923cca3a30ba4df4c2ee7457d5feac30ab08b21b71abd66c8173a84587a047454afeea38e6ee12936743195eb79b6548e73822960c7428a7b36c75b5f549b66f2b30ae3cbcc4f10cbf672817b9b45305c7cf290c4c8c60aa2d443b03a6418b8bb42309f2d912a6268260d35b5c2d72ab320617d114ff649308789a3ac88817498333f2c8e65f47a99755929b35af1bb975cb804c7f71469f32027c33e705c12e6ab4227f2bf37eb2214b66a00c556ccba44ee84654212495d96983ef16d9af2b848919005700f01b58b3d5667f6220983e1ca9cb8cc1ab09b609224afa0269f935d99d92535cb2758c24f08aa76dd1cb889320c187c48bf781a10cb3762e402f3e39cc151ad6b7c6c8c50b71e7682364314a64c6c8e799915d84f50b37403077d41c76062277b6a1354d298427c31b52446864ac075e4229b598a9bcac0c03ee1934207cbeebaa931c18870e7787f4718830a932375935759c98dd5074cdbc3a2cb6786ea21ac928b34d675ecc9affa0c8c0d341fe0588a8a6a398e994edd03786a167982815d693c9b149600fe5b265a94697ecbb5a9632f3a158e0eab8d06dc0bd176bb02172c68851237e7bd9592433cf97b33017c32bac8c719926c4a8cd6788f494806e7821edc0c798cf6424767ad4715cf2e02c806565b5829bb4d9980210566763999046075ad12612ae07d6c0394be26cc1c375c757ca776f7852002b6e1fa8f44db1e643753f1daa627799eb8d320edf134b5362a7079093f519dd20a9fb662cc47e373ee81a058e367f4124b8dfc7eafe83e2ed7693e46be701aa7a9e3ba45338aa4c9c26831a5b1f7c03227c97c515e8a1b154ea910d7265aee1c3f16198905e9c3770aa5ba924fddf0433edb6df1ac0d2e6282e018912db1c056f613bffc51efa044d995be8a83a5560a4ca3c554ac538a45060b42cba3255332cf2529795ac109db6715d87810e697d97a4c88fba86760460aa493bc25b2cc6bb79e3b1391134ec2934165a77f44b81b1416799d027e488450e43c42792c7753a8ac4805c13ce7a654b4a1bd881503a8cb3ed462e40a42f71c280c175663a64657fb61a9d8cbc58452141366a1f34eddec4e8c40b59d82a9260a68727431d8f36a614a8ffa681774c60587153aca0591d212bc5c3a22423267d4345db36878fc771c0319178a6936569bb778cabaa0e211b2a14efff4a4649052c60a9dabdc37350bb1c931ab2cb3854ae4999fc0a9f5d92a117783f975ce6d1297d7621a48fc0a2ab584d754b036a831051ba25b7b5b9e1442fc3a7f17d2710e7aa3d86b85ddf2abedc30ff756b2262a1d2d1165574a13e51373382704bc062f5b2261ed5053608446b7db9e12d0191e1a2d41a0adb4015696c3266c79497253c6bc51c20999b890bb21c8fcc9a786142e57009505694b7155b386c39b5c1b84f0791d9583d58a904eb66f461b2621f2c024b4a6f0cc1b2a7bca62f5378fa1334b7b6f06c61cf5362cd4e3cccea93988eb757032a844037aa0186df5703ee8f7c649c9785a26197c2593af38c8f56b849bd68e12c696825982b4f2919d9942ec240178848f68d31d58c83101c3626170b992c2ab3c181f3d58b554249aa9e73c9e691be2c6c402755ce0737ca2e2524ff59d3397b417965ed4c547f8dc97252c58f4367379f4bc9da75b64b4a40a329952623f0615117d28af7cfbb994b8ad70b2540978242ca0609a082dfd70aa5910778fb1cfe537c5c1aa5612029d9b972aec8235466098558c1bb4fa2b84e1cf9c16300035a57328b460b20facea43d5502958b968547b60a3c9255ea20faeba1f4e69cef343a6f3793d4b0418edec073909b6786a38fa3337c61c8f7af5a796f41a3731a4ca6096382423c941616452b6a5438977445ffff43d54e7b787cb9bc6c95c36003d87b9bf08934996f7301618c5a2a9b6d5d802d57c02018b44b0d95c5ac1c46b910dc518277be4c8960400b14c51eec975976975825b2d574965c338c121a056e2b9c9cd88ce4111c0eff01db722734b296540ab44a40214646c32713c87bba448d349cd5b160db48411a77593886c81ac1b59d10b51e8338a4178082ee858ff3987e58cb7e2a58cf23c28ccfc6141270c5ed0b883d01092c3095f0abafa2c43eaa7181136bd6e2b0c332b3e78ba665c73304df21d83cc3915f9c8073b7d6d907c13bc4a295432fb0a894958b98c9629d6a025e3368fa234399ad0aa5f8c8fb54b9af1d3a18d1a7ec1b22e7f5056c0d97595a801885202ff8c9ce2315ba340924d1c5e2efb2de7c1a468b684c8f7a363eb98dd4cce7ddab73447a5d263b2cfc4129be74174b50ae359c69f086153ab30038a13ae21ab5ef870c44490990806c4936eff553ccd9ac01d90b1e3d54bbf943b19236b935cafefeaa1059823b1d928cb77cbdc0ccff4024e79219852c0653ecaccc3d9292a18783c10cce69732dfc4585c8a45138ab94ef2c84de2aed22b98bee16bef556331e56eb43c3d92e55a7c1bbc0474251a70ac72d5cdb9b2a9ebb9be53c0cfc037c1678a1351cba5e91bcf7147002518b8c8933cca1c34f9da03d2b70e885059b259b499901b98345aedb9075aa1686e36a85c6337f01b4ea2f2ab29939eba618c68c5256eab4e6c1a1beb334f93e99bcf3cb31012b1252537f8d1a589430b46e487ad07cfc5c58a2865b0a92a621006248a46c837f095109a3de16b24b2339a509284c9055778816e9656c743a8929cb622f3e34f0141c820d231501c920581bc259c8be8b0928b58b6f1e2b34b628301230fb18c3904741a0f061cb613b560e972b406c44e154724f6af887a345acc63065481c4b468423742e742582386c00f2531c67835f3c679ebfa9aff871f0b006c461b760fb3171b99c9cc74a5378c3ac78c87c847a65f4bcb5043a551c223418114d58bbbf6aaa4422aabd4d70e7d78a61fb1af33882eb5bc886d154ee032b0cf300efbec2acc811ccd2c6968e90f6d146dbeb0932a569896f96a91ba3298c57c5ebb4aa130a7730a996054b9c058057fdb41825a2323799bb0a51fc0018428061ab3f3c12a6479c3367810acc4aa869867f5888a90a1ac51913292a194f1b3d8c976902221d3b0c607714f4fdc8196859c939b499e511f54e52d059a25449068c39081dd59624a6515e282935ea454cae482ca990a378a3b41e0b0adc6702a9533c0c479a4f6176be1a9a081a357f5bb98f835ed13ca29eb969f3a7c759b43464155ea78067752534d1044be2501c38387b31c662e6b9cfc4584e5dc43cea0805e273d9e56b71fc924204c8ad82ccb315207afe34efea97f72a21760cbb629d6391ac85fe28ac568b1b96ad8b888c9cceec93fc08825429614be352c55ab218383ccadf0bad13862778bca36285d67381164f5853340c0b9516ee3916700f4c3b8326e497ba7966456b6144b87f70c89cbc07a3a553c60b80e01c0c7e9297ec70e5a3017e906cf24593f86d3b6d1db26004b8ebd7047339468183c20df37055637995522a8322b04618b123bb3b1cbf765beb8cd17a302b88166fb84a9bf1728bfbc57853b7de3f113257359f6b7835e9953da123bfcf545e5e3541c8620f5f58872f1192b67424b5a9909d5324a342fc74caf906c69fbe3b2384a2a9bab153439241d6065e0f944ef67c4d6873635b3650bf4cc4a4b879cca63b6873c8e681982e4a183557e0465bb0f60a8b9d97625065d4727731e173977a95e7bc2ce3494b58071c1b89b1866c85ff814aa4843f7ab5bee6124c2166757943afa3df3d5f59581246cddf8777c228d53729573ce2f4f51da212385808ef436eecdb8fb9f3c8346800beb4b9e537d1dcd292e4c5f9e1a55e0489bceffb204d672a6215f4f3980a646d9f880817c52dd" +}, +{ + "dz" : "e1953800acaa85ac02a906c72cb8e8d704e8d27820345f88f71e89c1f549afcc8c64c049c6dfc0f1476cffd520b055756162f7ec94243de6b14ac0b9e5fb366c", + "pk" : "b2c2247d98c617419adcbb5027b320e54205ec3b9c37fb528be1bcb29624f0851a9844b83c5788a2332c0148c6c982be4ba98be6d9a54623b8183a66dbb8456473ace4f18829a56d1523497e1731c524ba3545652be97aece915ec25cb8c18364ff961dad655e2d08e14293a77963e4154b5d52a6d424a3ff976b69fd6c073b7bd960cc397d7511f76aee624240cf6430d612385a21a33838d181c3f77197e530463e952662e512a538b81e72913eb32357577319d29599ea2ca2e088c91681ebb295c5fb3c4f11643be6686f62b259c737c4ed37b38901eb7a79d5facc426438f6ae228338439d136ab68ba7ecb760a3b45c77f186c177c2f79f47f7cbc2a43da4b94371e4ffc9f8d520a9c1749d5b63b01a2af5b7a10ee47505598ceba4ca724f22fc15626a5243895db48cd2bbee25c27b171c44fa09d9dac21a11803ce0a6492b72d16803dc793cabab535eaa44eaa14b2d81a4162c32e73cb38a7bc945d0c1d6e0022e2785093d66c29e31616ba7ea0f58def02339ad231c3806600ba8612080d6dfbb50353b0fcc98dcab2c07473b34e05a556d777cb1982bbe521b1cbc58c680606f352b1560e7e4589b905b50c299ae8d3328a3729ac0420c3d23eca06491c43ba8d72af0cab1a869002434476bd7527f27b751c9364670a3730c52d514454e03386c66406a4b4315c8201db561e9b79c2ca4c60b25044e6bc1253465b4d0206fbf695470b4b7b8bc068d391f5d0b7e9d8028f1591ed916da33157cdea92ff46ad98d18e1ce6c4b2f75854733e913c5ad2d13e23ba51b7f8c2d3cb0edea793b55acc3995c97d3c65c0981f12913c88b56f62623f41e85a84543d4e4520c884981a3531d200ccbaec0bf1096fa7ac429a9b3bc1a2b38de159c2139361dca3ea805d97e67f61d10c0911674fe148b33572797ace2138ab478a51057306f010661d569ddd9a4e55e73f67f25f0db09d61f1951279cb79d814d1a21a4ff311be441bbba97d81935b31bb4dd558544babb18175b893357504589fe79170199129e78874882aa89b87c20bb03591f321419a41c1a78f87016b4e551c6928a37fa7c60708afc03c8b5b17001aa3088dca6ac9ab93fe5665f1781e36d7813945471f6945198983815c2737713f9c53a8e717bed4d9a7a706ac41d339001c5d74548388a2439cb0142bb6bcf2e23442155adeb4269cb39432d31455f0191a25822f35c889f2962ff081f1c1b5c55b9af0b14a414b618c7366fef512d94077470440fed7c2d101b5c9ec7b79ba17cdc14653b6c3179261a9401a0b20bfd201bbe243b8cd1322fc872c4bc29889586a8e302ac26b043b605c13c1300a68c95f269b2ef49402786819668e964c921f765abf805477ea239d3b8b203c7db303afe5a8c70158874981c663f1b3f8a645991cbe42a2498beb4579b314918c85a8388f31e628010bca96858a09e49365725b31d0726c0379709529c38b47e15678ac9625b28a763b579af908cc1cc45a5ecb23e5a6ced504b9e3101cc562be9714bf4931cbab020fa3e10456d23d2d01af6dda8dc6e09ec6aca54a3253f5d905d4b34b66250f80324060b1609083028a63aed377a7cca6a929da786eb080db750cf906c98eb9a105f288a36427519c0087e300705524ac343b2c448ead7802404417cacb6ca5a398c7e9c2a7b2855fca298ab1bd0fa9c23af9c5079496dfb2996a3738d5ea37ccbc24f1744eb9f5c672d74968c872392480fba91daf0c60fe96b13828bbefc6156f860ca304970de5695553a631a10c799b29b2585652065f33c6b53179bac6473b4dc2b277284181c7a2a9491ea422c5087358ef8835bf5711df91b38ab90000d324e7b6ce841830bd952e18583eab6b6a922427b2d094ea633cda75c94bdaa1a3d928fd2376a876ac0306b1ee631fe38987e50421389cb224d4045e260a9d34508d1739f223765a3a8f2699a8919b30f80177d9e141d7d9630b46cf5dcc4ff85045e62a4f0f86bdbd6367c1471ac4b22210771eb636c2bbe564578266b8682817a9118d95ade51031def42e0d9cb273c03e3f93ac97395d9f09be36eb8b2c21a4c74796ae501758b222101634d1668656b02cd0026c9eda07c0f3bb7d99b7fac6a78793bcddb2a18cd4262039723f41223d336451eb31911219750098125d62110dfcb20e30c6d5cf75212b294eadf4ac273ecb8bb5beea59108851b4", + "sk" : "548b6bf0069239d110a3699befec0527e89da2e3792653549fb865d1e9ab9ab9250ee00d913b83df22acd9b4b17a23cd1bbc9c0b46b5df36c3d5a636cd9808e08b8affe75d42dbaddb9974e8417c8cf14ffbdb8e89fac43330bab32c9bd8005b0a1c4948c04c4d110a6248ad52018549360b4e7a950a29a911e43250127a5362787d67ad2d85243ea92cbffcce1ac4cf4f979b59e47f60ca1156096c0f93a219328619fc00d2912d1a23badb2c5190d211e339bbc3317e1a22afe452492b75b0138600848894f3b86eefbccada8c55c73877f9d9ab985004c86c717b199a164c2e25d79f3230368216800de11fae5c2d8892c5f33456dcb2cdb62392bfd1b2e7658c979b87d287ca62d052e86a1afbd367bc066de99851331a00e9461adfcbc6b770471ac76bea98bd52824fafc790b41aa977481fdce18f91528939c202bce50fc64667fdc6c06e339b2ce3aced139739036a7141b1d3b293ee188d57354969485238669b74514d281a7a5bbac250ca154fe898e7cb42ef6670891b32dd97494f75ac96c6bd10682c682786d270bdd73a204aa340cdd9ba00162ff1787b81d2982d9a5fe90038537b65c5bc68bcc22bcffa87e1415b79fb35dbdbb6af8673e56baab96104cde80b3d59ae0563660f8b068d3049c23c0afb59b36d537dabd8c4dd2063afc12b19539a845b51fb4594ca58bf967a9b87a057f7352d40c0b8e79b71e86a34a79116a5e13ea1d4054a35a65d50a57b61bb8f203f8f221c5a79119f0b3dcc2974038865b54c9711cacd1a2b306188235f36a173e99ff982a966d4030a84220604717e8b7726136941d80d23420ff3c599b623276e510567b499da25abecb32a51165f4800b95fb66b6ac1693e52305f32bbb4d980d8a53d83d44f754b0798e6596981c0260300bcab8d55574c92a09ac86b277383b062857d1e4919e094b0b835b7848176a8984ec639942ae9a541fa0549d62570bac5ee458130b0bb46c30ff3c8c7b2d67cb21785b82a9367e59d38528c82694d25756890b789ff86b9a755493eea0b6f640afd8c26ad833be6014ebadc04a6866f2250c73cf5121522bd4d6ab3d8366e04676734fc92699531f5f6c0e595befbc425f91c2c978842595668415c59582142ed11418fe2983128959dc425b61183d2ba458c477e4b9338228b3ad1a16316ec976522b9eb95596628a3aad73953b2877a038887b96a991ca938aa2615751b22f9429a65a8ea4c637f63b313b48f29662950227b702c6811b75564e58d9ffc3609479ee75205171c7db51776177a2a83c74e3f61cfde821f4b60b433902542770ffbf45d668001f94c553673742c96b76eda9750f154e61362d4a173c806ccaf48aba8ebafa9648cd1b3a17e135840800cee9855e1f4623f9768197b2ac9f5525c534c8bd7728bbac26bc18aa5e412fdb92ed262027dca769d9851917510b9e1a66826cda147705f703512767a4d9245a2660ade559956f67b7a012df0a99fbf911d73367c0e7372e7265fce319efb818f139b84a5f652f183c7f2f68c1c252bfd69a586a716dce522aab98d94587dccfc99a4b813ad60a15c924c87a9b11516188c4787171c98fb11466c59b3c72017d9ac1d9e6522b52c1ccbe45ebe0ab6a0983e84e8bec3001ebfb845a14a47c34c9a74234676a28b33d2aabe157f56c26895e7586658649687cd7442832a1c1f2401207b51c676b90c41295bd609882e40a170008be7c3909318593857b602ca882a998ab0265f5e162c60aa090287a9e7a3627909743de22272ab0214816311cb4548fbb5b093c29ee57170121337000208759f6e224c6992c593337d62d3011e02ccd41015497190e9ba5df520b3fab78d68c2b0c18b72c8f67aa9e056a26ba52e32ad7c717472766f5be4acdc60b48ee38bf361b1ff52b11df42546e30a2e0c3f37456fdd190030921e301c555f73b68e5818f285714333b5e2818c5d460994985e81c09448f9a58bea16b87a02e4bc5d7765ab4936ae83b035a8878ce47a659778cad7248733772b52459744362a51b05dc4d17f0e6b72fd1119b1d24d378b6b50831759870d2a80b8dd5c67e13a30a9bab1cddb0d5007ce2d2c7f391a654ce2ce94a77a83035f7d059f4016098f21a9b4633a96d634c32419aa073be74b792b080be8b672b2c2247d98c617419adcbb5027b320e54205ec3b9c37fb528be1bcb29624f0851a9844b83c5788a2332c0148c6c982be4ba98be6d9a54623b8183a66dbb8456473ace4f18829a56d1523497e1731c524ba3545652be97aece915ec25cb8c18364ff961dad655e2d08e14293a77963e4154b5d52a6d424a3ff976b69fd6c073b7bd960cc397d7511f76aee624240cf6430d612385a21a33838d181c3f77197e530463e952662e512a538b81e72913eb32357577319d29599ea2ca2e088c91681ebb295c5fb3c4f11643be6686f62b259c737c4ed37b38901eb7a79d5facc426438f6ae228338439d136ab68ba7ecb760a3b45c77f186c177c2f79f47f7cbc2a43da4b94371e4ffc9f8d520a9c1749d5b63b01a2af5b7a10ee47505598ceba4ca724f22fc15626a5243895db48cd2bbee25c27b171c44fa09d9dac21a11803ce0a6492b72d16803dc793cabab535eaa44eaa14b2d81a4162c32e73cb38a7bc945d0c1d6e0022e2785093d66c29e31616ba7ea0f58def02339ad231c3806600ba8612080d6dfbb50353b0fcc98dcab2c07473b34e05a556d777cb1982bbe521b1cbc58c680606f352b1560e7e4589b905b50c299ae8d3328a3729ac0420c3d23eca06491c43ba8d72af0cab1a869002434476bd7527f27b751c9364670a3730c52d514454e03386c66406a4b4315c8201db561e9b79c2ca4c60b25044e6bc1253465b4d0206fbf695470b4b7b8bc068d391f5d0b7e9d8028f1591ed916da33157cdea92ff46ad98d18e1ce6c4b2f75854733e913c5ad2d13e23ba51b7f8c2d3cb0edea793b55acc3995c97d3c65c0981f12913c88b56f62623f41e85a84543d4e4520c884981a3531d200ccbaec0bf1096fa7ac429a9b3bc1a2b38de159c2139361dca3ea805d97e67f61d10c0911674fe148b33572797ace2138ab478a51057306f010661d569ddd9a4e55e73f67f25f0db09d61f1951279cb79d814d1a21a4ff311be441bbba97d81935b31bb4dd558544babb18175b893357504589fe79170199129e78874882aa89b87c20bb03591f321419a41c1a78f87016b4e551c6928a37fa7c60708afc03c8b5b17001aa3088dca6ac9ab93fe5665f1781e36d7813945471f6945198983815c2737713f9c53a8e717bed4d9a7a706ac41d339001c5d74548388a2439cb0142bb6bcf2e23442155adeb4269cb39432d31455f0191a25822f35c889f2962ff081f1c1b5c55b9af0b14a414b618c7366fef512d94077470440fed7c2d101b5c9ec7b79ba17cdc14653b6c3179261a9401a0b20bfd201bbe243b8cd1322fc872c4bc29889586a8e302ac26b043b605c13c1300a68c95f269b2ef49402786819668e964c921f765abf805477ea239d3b8b203c7db303afe5a8c70158874981c663f1b3f8a645991cbe42a2498beb4579b314918c85a8388f31e628010bca96858a09e49365725b31d0726c0379709529c38b47e15678ac9625b28a763b579af908cc1cc45a5ecb23e5a6ced504b9e3101cc562be9714bf4931cbab020fa3e10456d23d2d01af6dda8dc6e09ec6aca54a3253f5d905d4b34b66250f80324060b1609083028a63aed377a7cca6a929da786eb080db750cf906c98eb9a105f288a36427519c0087e300705524ac343b2c448ead7802404417cacb6ca5a398c7e9c2a7b2855fca298ab1bd0fa9c23af9c5079496dfb2996a3738d5ea37ccbc24f1744eb9f5c672d74968c872392480fba91daf0c60fe96b13828bbefc6156f860ca304970de5695553a631a10c799b29b2585652065f33c6b53179bac6473b4dc2b277284181c7a2a9491ea422c5087358ef8835bf5711df91b38ab90000d324e7b6ce841830bd952e18583eab6b6a922427b2d094ea633cda75c94bdaa1a3d928fd2376a876ac0306b1ee631fe38987e50421389cb224d4045e260a9d34508d1739f223765a3a8f2699a8919b30f80177d9e141d7d9630b46cf5dcc4ff85045e62a4f0f86bdbd6367c1471ac4b22210771eb636c2bbe564578266b8682817a9118d95ade51031def42e0d9cb273c03e3f93ac97395d9f09be36eb8b2c21a4c74796ae501758b222101634d1668656b02cd0026c9eda07c0f3bb7d99b7fac6a78793bcddb2a18cd4262039723f41223d336451eb31911219750098125d62110dfcb20e30c6d5cf75212b294eadf4ac273ecb8bb5beea59108851b460166dfba8564a4a16e7f53e467431528a6e2d8b62b614d427846b701fbff5f48c64c049c6dfc0f1476cffd520b055756162f7ec94243de6b14ac0b9e5fb366c" +}, +{ + "dz" : "c719f9b2d16399b7326ce4eca30dabefe8fdaab18e9f6df888b0a134ef355570e40771856eb77e4633504899fcb86c6a3d433d0b8d60e26f07bd61f1d4ed69bd", + "pk" : "4e35c7f9aab819e1981647b85f7b73ac0b8ed44a9ebe203998771af684086e00a0ba098841e7979baa20d82b450bc35b88884eb935788dba47bc63247de5cf5cda3f069a02874598468c6651842e56464d9731cc027aa307da811c8c163d62cd057863a8c2764f81c889d718d10267200c8c2e7877d7d853a73287d8b1aef013c715f69083b29a589b8e2afbc72a76587032936899244d435f1df58a957091241728dbf57693f46accc214dcb89fa35ac97c77732d0768e11b15b6d5c915ac78d5aa17323bafa8262f75b66d06f55eb015a5774a3854d09bd130473295a946771652176dc0479cb862cc7b93494df1c815d754f86c290f44c1c828228d48a5573a574a2039dc9140ee8a55c6abba1986938a47b0e84859558399a42ca013450033c53b1e978d5a3ace10a87761d51a19bc349fd19f555042e0e2806c1aa76436bc32831f0935c51384b6698a432fd4a014157b8a9858cbc216fa784e66bc09f02258a9dbbc402422cf652a3e430301678283d19889c7b61226951bfab2814a7c7a2899f83670b1a396f4d260aa869feb409b0af63b0b2438fbc72baf0753fb2c7473d577618109a9d2c2a8448a0e756b4402c7c0e280fd1160f20b9b384224fa2ba06ed2274852b15e1b35851ab6e8a5bcb646ab45a85744141970f6c5af2720fedb56abdb65603588d73109630baa73f773f260c63d81c9137100b1322d7c21181285b773b7c552a4000cdb2830e28daa17ca1db9bfa0226e2c1ca720e7565e80bc08f1c742e453fb2230138bc430335c2965386323b269922e5713957057311ba3394320096075b492b641369236134095d728341db3aa13ec453eb4b9c986085e23453e878e42d20c9af4376d092da16c8a9afa9834cca64f16b2b1561a4068c0245c4b6e329fcb1c0a9b15660485672ce70f3f17b486586597e8aebf9987af18bb2ce3267722c549a8519527515f4129ba5c986327996c38babd95cedfc1305f4378fd2c8b6761a24334192d47596502c86080bb202946f34c08d7e201a3ac937844b181d739b9807ea3d6792cac7a7a1b4ba7fcb2c5833cb0101291523208e7bcd486737b982c1136381be16f75202757fbb86970194c4a32eed31b01ccc5a2f0534bda8ee61b0f4a2023ca58b415e59a8d9bbfa9964cf765b31fb0c565174bc7b006855c9747a66747e18e954444dbaa8272a15cae2b7749b08df9811e8cdc01fa46a362052f50aa06eb2249287abfda0aadb2e719f1e1afa3c29d7c855a6ca27aea661f40210c1c629f611343240b3968238746a245ace3994bf88b46893eff1a3a6096166e0bb7341900e73bcc36bb92d3e539e456bed44b84cc00bd836081704ab2e4065559896657ab31c60c3564981453b58bc7e238fc5b778cfb4aaba57417009a789a13bb075b6d9541692b85ab52961fe887c29289923797d18ab8c9d35230624b004457f749497267a2efd15fada244c1d35c44109add503328d063b7e8c0fb8c66bcb42c8b1c1eac421563c232e579431fd9ce4d572904577811e23af28109b2e419515260e0e1bf4a969d18a4378147c0334a5886046833ab8d06c78041c6b848a43810208a5fa0a202ec2320f4adb15bc299c6649c694f76311d8c0450ca829c3545ace79a33e0942f133c35e1e6be342c30fa9b8debe6820a3cad5a2995414bb7f0744a22194435ea8e5a534dcb8c754bc75444093af5d72490a3468bd06bfd1442870701896a4f1fc11fd5c8c50580cb06192ce7b90f81d920a3bcc52ed02fcf703428c22c8ae25fa56085f8033c972b47c61998db005b019032d7a83660803cd39014bb3165c94b9dba1c6e38abbf6567cd513283174c42bf4605b3809c29dabf149a650bc906a4cb1e33a469bff3820713040aa067701282cc1c6826008f8787cfd0796bcb568210e088f649349ad921b9349cd4998189b4b945d92ba6bbcc972155d26920e1a756bce6441748c41c6c7373723a9c00434e485216d92dd6884f6113068fc2b798790f41bb3104a513f0e413ced19303f396e5f7c72612c4f4112f41518ea77c850f7b8e64d1b6df73a40f87b2945b14b8275aba42b455253b9d522263e4bddd6c24222062ae68bfe5ba4193195ed026712e729d59c7a1f519a9c65c566a51504cb93355a33d83acb62a268e02874c67c89530f914761b751f03f3d2307ac9ede742f51bce4342afd3cb6ce2ab83fe", + "sk" : "c4ba61e90c3a8868850ff1c4662226ac4953de3553f0701c404618bc69c0f57b527ee459f171bebe70c730f1841ba702f182aed1ab25ae59cb9e793d7a22c4640ba87e78433b639bb061106c0581809675c702596af67e382b564b514c4d091a13f35629bc71aca95a502239bbaa7fa15310ae31b7e8b97ab3ba783a27c8b9eca6b9b054911c756085002a329063067b06707a6d3a31c27c234fa36daa420c5ec0aca490c0fb66023c34064f09832d43b465dc8f84572130270599c10534294ac0458412c58273f49c39cb12d522317c980670692207b3af7417bef469234ac081b1884815972c7fbb3733e22d8a164c614ac8546c14cbf05a6bc47d6424c36d3b106fb245ca335a927538d227be6aa1a4dcc33bd1c68851e18e2ff7cc7ea93104521db15c7f11041676855e0bec2b2f9b8e9f63920858b3db1cba7005c5e21c4effa94427d155ec0c1432cb2679c45802795e0ff13674f15be6d60ed4326ca4f230d87a59bfb268f08362a6764aa2402e270172275191649bb3991200330a62594aacc81a8fe9e5004bd5ab8ca4bce4e36860eaa9e49a2f77762d88f0935d6563296121764aa34ce64b41418bcf275b8e5bb2a25259669b3010b239f111b2f6584c3ee9bfe7608d12639e72ea38073c9c45107abbaa5c673718ec2c4a77a19464209b8efba54ae482731bbb3aa036a67653ffdb0e8741c678b88d4ad4647f8b39dc61a879eba65db1b98281ca641c954915a916b15307808587ec3d7248668b1003a1612f9ea13e4ca7b660431a7a55199814ba1e757ab08056b7d9c13b0334661839c334449afb77de61aa7caa28ad57acb2ba0e02e76ad9218a29c6c638390823d6ca512139d3f8826b5c176da373d7754cdce78c614b98a59b4bc607382f103eaed7645cf791b3fa3374fc1fb16493658a7885735f7fc38fbd324fbdeb904f17b7a9fc7af45013a0e8c1d3c4b9b7ecce171731ef1c97693695fa775ff0452d457b8d7f17bf24638112391d1b4017db07c3a037845722aa4fd72a0a079803102b0cf49b522302b37a46e482914ac51af1f007ac91a84d6556a176affcd28553362c16471eaf569e666683ab71cbb0748b6bb026d6b736e68203a3103940315650c4201f31bd286643c635644a567b2d38b1c6746757e956c663cc2ffb1230e7c20e94ae939c8ad10b9be3887b8fb7ca9ed360b2295f03725047cb8cb771adb18b7f1c976cb436ccc0c675f99575cea24675c358c3678b3dfb345100caa3d11a4fe8a34737c4c11131b7e400aefab6380b4565326f1ab8510d4210e3335a5ff07473a46d9ac73974aa4c8a10ae5851addc7b4d3bd9823b71aa1c0a7f2b4746744bbdb9335d7b161f55276a1b63c3b5b4800d0344023093ace786fd99c144655d6af601e86336a5e16e6cab8b772a39cba32c68e84390a80d62701af5d5822629a758b49cba714507c7cdf2034cf65c4a0601bd1b07b4e1c1a70ae555d7368a568aa0e59b5494239d2e25a9eaa34bf8b29b2fa31ef8eb606e69602ba0a4024780d5c29cb6c63cee9187249280ea56207b4628f8964579bb878ef25aedb180931aa5e176ad53a890b3f705bf626861265bb9331d79f66b87e96a6724634df6a35a82979a4a2b1c23bbe585a001a936d548599cb82c8e362442a6481ad29478ec2e389853fdcba3853629630030c9091e8781a33287001a6abdeddcaf69856a832cbcdd3894f09690b581ac6f7951b7f3558a284c8298225bf74c6847c8d834aa4b118a37fcc87c44749031091af154b6273bbfb4ac7a3b34ba6c5642a78a22b213428782eb81194297a88c1c04ecd35d6c548289285999b69ac46346127aa097eb2a08fc1bae1a944ae83bff25949e27af6167b73938147bb97ad5380f599822f788508eb73563e82e73c9951d5c94428a056939b9c5ab272525a7088977135008b0c5181bfa27e336457375b1438914bc0189c00bb2f07c5eb5429ee6956943d4c5aa597cf1376ff7083da68b7c1941529ff5509ca82e3a424dcbe4673ad16439ea874786544e7181bb755250025572c9bcd36c28338482e31449a3b6a917c9947876a702b8567327309b3812a3aa4bc8b979168bbb2db72f533434808cbced5ba7f567ac05082db4b029512747d203c84ed6aac81245522a4d30a887b8f44b4e35c7f9aab819e1981647b85f7b73ac0b8ed44a9ebe203998771af684086e00a0ba098841e7979baa20d82b450bc35b88884eb935788dba47bc63247de5cf5cda3f069a02874598468c6651842e56464d9731cc027aa307da811c8c163d62cd057863a8c2764f81c889d718d10267200c8c2e7877d7d853a73287d8b1aef013c715f69083b29a589b8e2afbc72a76587032936899244d435f1df58a957091241728dbf57693f46accc214dcb89fa35ac97c77732d0768e11b15b6d5c915ac78d5aa17323bafa8262f75b66d06f55eb015a5774a3854d09bd130473295a946771652176dc0479cb862cc7b93494df1c815d754f86c290f44c1c828228d48a5573a574a2039dc9140ee8a55c6abba1986938a47b0e84859558399a42ca013450033c53b1e978d5a3ace10a87761d51a19bc349fd19f555042e0e2806c1aa76436bc32831f0935c51384b6698a432fd4a014157b8a9858cbc216fa784e66bc09f02258a9dbbc402422cf652a3e430301678283d19889c7b61226951bfab2814a7c7a2899f83670b1a396f4d260aa869feb409b0af63b0b2438fbc72baf0753fb2c7473d577618109a9d2c2a8448a0e756b4402c7c0e280fd1160f20b9b384224fa2ba06ed2274852b15e1b35851ab6e8a5bcb646ab45a85744141970f6c5af2720fedb56abdb65603588d73109630baa73f773f260c63d81c9137100b1322d7c21181285b773b7c552a4000cdb2830e28daa17ca1db9bfa0226e2c1ca720e7565e80bc08f1c742e453fb2230138bc430335c2965386323b269922e5713957057311ba3394320096075b492b641369236134095d728341db3aa13ec453eb4b9c986085e23453e878e42d20c9af4376d092da16c8a9afa9834cca64f16b2b1561a4068c0245c4b6e329fcb1c0a9b15660485672ce70f3f17b486586597e8aebf9987af18bb2ce3267722c549a8519527515f4129ba5c986327996c38babd95cedfc1305f4378fd2c8b6761a24334192d47596502c86080bb202946f34c08d7e201a3ac937844b181d739b9807ea3d6792cac7a7a1b4ba7fcb2c5833cb0101291523208e7bcd486737b982c1136381be16f75202757fbb86970194c4a32eed31b01ccc5a2f0534bda8ee61b0f4a2023ca58b415e59a8d9bbfa9964cf765b31fb0c565174bc7b006855c9747a66747e18e954444dbaa8272a15cae2b7749b08df9811e8cdc01fa46a362052f50aa06eb2249287abfda0aadb2e719f1e1afa3c29d7c855a6ca27aea661f40210c1c629f611343240b3968238746a245ace3994bf88b46893eff1a3a6096166e0bb7341900e73bcc36bb92d3e539e456bed44b84cc00bd836081704ab2e4065559896657ab31c60c3564981453b58bc7e238fc5b778cfb4aaba57417009a789a13bb075b6d9541692b85ab52961fe887c29289923797d18ab8c9d35230624b004457f749497267a2efd15fada244c1d35c44109add503328d063b7e8c0fb8c66bcb42c8b1c1eac421563c232e579431fd9ce4d572904577811e23af28109b2e419515260e0e1bf4a969d18a4378147c0334a5886046833ab8d06c78041c6b848a43810208a5fa0a202ec2320f4adb15bc299c6649c694f76311d8c0450ca829c3545ace79a33e0942f133c35e1e6be342c30fa9b8debe6820a3cad5a2995414bb7f0744a22194435ea8e5a534dcb8c754bc75444093af5d72490a3468bd06bfd1442870701896a4f1fc11fd5c8c50580cb06192ce7b90f81d920a3bcc52ed02fcf703428c22c8ae25fa56085f8033c972b47c61998db005b019032d7a83660803cd39014bb3165c94b9dba1c6e38abbf6567cd513283174c42bf4605b3809c29dabf149a650bc906a4cb1e33a469bff3820713040aa067701282cc1c6826008f8787cfd0796bcb568210e088f649349ad921b9349cd4998189b4b945d92ba6bbcc972155d26920e1a756bce6441748c41c6c7373723a9c00434e485216d92dd6884f6113068fc2b798790f41bb3104a513f0e413ced19303f396e5f7c72612c4f4112f41518ea77c850f7b8e64d1b6df73a40f87b2945b14b8275aba42b455253b9d522263e4bddd6c24222062ae68bfe5ba4193195ed026712e729d59c7a1f519a9c65c566a51504cb93355a33d83acb62a268e02874c67c89530f914761b751f03f3d2307ac9ede742f51bce4342afd3cb6ce2ab83fea96998e3f52b93dc875dbbd503bc67beeee7f1e46083868f96edb9ec3601dad0e40771856eb77e4633504899fcb86c6a3d433d0b8d60e26f07bd61f1d4ed69bd" +}, +{ + "dz" : "e9acbb774be970206c3a738e243b420805a509fa59fa902044be2f0d013650d2ded5edaec5de3bf5b4d7c2f2e18e87f499c1968993eff196753db8045e2c8ba8", + "pk" : "f39713c311077c359f42971b65463a8de1aed9879abd512cb55b6e44f5c690e0a3f60768a778cc9cac5ad6b897379507e3ccb994956284a7715970b0e3f6189f0c66d99c667119b82d87a6507141cfdba46fcbafa8a2a1352139b1024dbc64388a3275f34180ffdacc380132eff35eaf788364f3aafdd6af9c02cfa396592282cbfa110792f87b6182b2f36a0a895c0791276d789976cdf09d2c16a32aac669647219086bd36f6bf631392510c0e0970007a88378b647b52fc20ee9148cd4575bb8b31b06449994098bdf77680a48ab51b8e5732545d6b87112884e35a2302f60358f651f8a71c0789018dba79bf5298a9f6ad16bcbbecac4f0cc9888cf55bbeb38264c885ce098fa80463f63806a544bfc194b77895a76b22b81b1098a8c3819e035268d22f4ba0339067ab3bb30e65506a86e74fde52afee944df4e4c745f9393ad59117dacf74a407c236b8b5a2aa11b1c9f86163df31129e885ebf68040f822314c2bc4dd12751851864d743ea49b68a93212d392845ac46f95715796a488cb44072ecceca89878f37b51d662d783900b6341a65d894771476fb942ed058b15150bdc67a3b7f4cac93733f735b81f8dc4aa5eb1288d761b0b74238a5cd73c8bd2457bc195b785fd31804d654aae06eaf5b08a365a472503809b416904162c17942fd27671989c553ab5137488f385b7b9519a69cb496444a7a2db607adea5c3e128bcba31f586c5603f953f4fbbb4381cadcb88d6aa7784562c6ef302ed398cc2113abd257c9554818c8175db54baf20024978e167620b672b28bf24465d2cb4cfc6c08739fb9696bc84fdd76b136b39b85c7deb4c10ff59337b4112e32bb25a665e9cf624baa86aacb2a18ea3cb67462874117445f913558c32e5eb7e1329cfc2d99ca4d83007467b80d74d2ec9832a5785fc7293eb466d55cc8904874bca5714c776579b253f86b17187b9c19d702ae65aad9d7cc23afb041e593bc41308572825a76b4dfd51a2bafcaa10390a76e08458c384cd0089668955fcab00082759de9147bdf581aa4a81f8f82bbea84d255b43e30b6728fb7a705c0aa96b794c7ca28730c6a1b1b2c1040fa24a98ac862ed74453c03a3d842cb0bc87409a09456c739ea08717d7a1061041c424d13bbee299c1ab1bf328b42314263f186e5b198bd5b1712c04402bf849df6473b8e78c4009c944d05277c68d6eba8555ec48139560922a7a142632d4168dfbc6396d0046c53221d43b7bbe01bdffcc672f214217679853d3c0939acfa7b45ac81b145e5bc7d668a4466156faa6a44ae2b9cd6caa5d42cb1c2ac5aa847cc6501ce998b2896652e2c901483acdffa695cd1625b124a8a88490b12b72a5cbcb67a29aa955247fd17ef46606ab5b5fda6ac39edc0128e46310903b32435e2f02158f678462f2bb230246455b7d307b5bdb40375c6cc507987ef616816d3a97545bc0f6e44c025c961cca33a828beb6480494cb9049bb2e0c8734437ca0745b55174b67fca6abe743c7f9793219a19a88298211562e7ad85643b0b680c957eb6b740ac142276822900110f3998f2b043816c9216c416d64e482dc1053928722efda8c35bba98c563eb4fb280791a9a330968cd29360860737d3cabef87d158419cd8794d15771588cb049f393d3729fe3276590488e97f00e63b6cdb760c22fb853352c2eaaf7340b204d6bf8cd186cab5f786e7f967a4d147686a690ca7308173843dbc0bb17fa4ab2788436f43009827946265e86e782b97b2b27b87ee2c0ba9ff23d6d620ac02124189bb008d54da8f0118a081a70040b0c722a7b5a97194c5641078b22446d7ce9b66ab9332f2ab85d7320fc651eebf8b93b838421ac6818f87673872582360bcb903ab70972e8e589465660e6e4b9295675416547c277827d667102c99297f9909548c52621846f5978a5d6971ac97c6df5cf1a3a42717194f112093b73642cd757b541c6d5094931d97afa952ba80024b5d76caa088577f24b86208da3448dcce24769dcac3af496b4ec8e634294c7d323a85128d4e20dbe5b7bbafa8fbce12131f0663572a4c1a4885ac49cc607578042c0c68853b661b452662ae194512b208435a72ebad23519e07f96f59edfe2a5297c351bb38773478747732d9841b5c26091ce45559d7184e1ca01b7c388a8cb030a00f66b47988c2d7d195332662cfc7d90b279248de101f77e30", + "sk" : "744900d5a1cc90d1baf5c17965a200ad563be74168e130481832184937172b780a1cb0249bc3ac8fe09d7892709c70bfd6496041ba834bb1c291d5a73368944d13561790a20603bf8b97929624c5f586ceecd1636b6cb09c99807cbb9befd3b2688a29a63120132b05b5420a0d984b9368338710b29a4c5a4102b25ce23414e3563272c2c91a33467aa665b40b7a18ac434ba8e1fbae3a7cc2493b531c6b642759625009cac7751496b18127d33d4733af3fd461c1cb7531223945eb1be69c8486a35bd49ab075fa6227465f97ea2efe552db4329bdf66259d091956a41a1d938940998c8e83329ae0a8309b521af642b9466aa3a52a4572a00cd6acb467bcd0a0551f4538fbf78db2e0668f47ae9f65094d4a30814371e20350066bc797777d79135d9f104f773289c2c20c55d4bcfea1a674f454c87ab9d809a1ab91a6e13747438a7eb7f814464426cda6c10d9456a34c66dc37766b87cf01a4a38e45154bf96d5a5617a9e3a353a57706ab5911dc3f50a1c9ccecb4590bcf8c4765fad91ef119b00c027cf5f30bcba608fc4667843891934935c49c8a945553575c67a1e3c80df48bdba8778865ad972bae7733c8c4d2787609d062b16aa61c25564955213a06e8d021d631bc032257d0618d1b0122491b8c9df8251886a2efeba199a850ca41bdf7c0362293b80a25c247820571eb6d6d798da2c207115500a1441977a3362a2c1366a15cf60a6086258d35a695690a53ee6737cc76a8edd47795ca913daa42d762996e4061f8353be362752fdab69a571fa02671432615834c8008284293c9c83ca3b1eea330a91a7522aa876d37cf7da439e2b31db5c903b17b9449e397659bc7dd668f3e9cb2cd877c57fa3ee2fa9a3b3c9d22e5c02a48ae494142e5d56664ca0ffdd15be6c4c2a063907e842b800912ddc9141af93839b17f37f3725ce36b9a7631e6a002a7676df2d7a72a740302fa5ba55a41fba7953a5812ce30823195cf26b8611c401242ba90487ca730472f30bc8975d78741051d91701b7fd707b7846ba16874a8984446d017bbf2357526a4882359edda98570b44aa2b1d968c4a2de84ac78330d2d2725f7a317c093f42809d3d26092936330eb51e93132c975096df35506fbaa429c67ae6b75d24b9a510ac2bee812ced4a732fd1198fea3e135ca2a97657608b6944181d062b1df05679d8d847e50a8668fc8238caa884b31fdeb3adf0f890a4956887417d00376543fb8588fb4433156ca8c7152ef466b9eb7534e9030980ae47d82c04f55d5764827fe036fe58c6ac9aaae51c115ed619e5db99f3f6143354903bccab9cb5448f9a8e76c3690c76732db1757d9742aec5334f79c0080a9c0f251b34f637f80253152b4c5d8124f302c3f6e15ea5d09758e42b99f15427ecc63976a0315644ed8ba516429a1aac16aa2045fef31a4a68c737f206fb26667a403c3af01d82a191bef752976c1962b53b0228513a3026a0ba7358162dd8885aa3dc31e45b72346a055026396b405ece0579bac0504082589023b4e0aa77b07366ecd188381ab2b9ab47287c44c14a36fd1095453b2b3b0a816af1c62ebb2e023247e4983bc983b867460158eaad4876551638ba5b528e0c74b9a081537b7bce3e1540062b93fe447873523766f2cfbb4c46e3c3751057764568033942b89b7325e639c318f63aacd82139192c81e45f4484073a540df8e459fbb9afcba59c167a1ecc71aae7473c8d9cbfe41cc27db6b72c804f64cc1a015018d212c9dbe320aae4423596b4fd544c6bd16af096af352c18a8dc1d68fa29df7a454d54b92bcb21a74cb107153b8386285c0479020c04ac0b59ba8392bc976c046995ff606f2aca215ababd04f031e52032f6c08e63149dec0a590a4c49ef55533735224c341baab9b0fc36771790c0301638ad09882634871196b55e87a5e7b9348c8a83d9fa0b1be81232864342262f57f063d38940947b48ae840dc42b27d52a01f4c624196c9198d081992934777653fb533e525cbec4591844485ee6a457f4b31ff94927713c9392627a0e676231318f18e084cee43501f0bbd708196dba67644145e7561fc1fa2c5c4835c76a5264a25d96d47138e2cb3d75297345910c164ffb30cd4c26cd1189264a602a3397aa6afbb27dda27a6566e9769a5f39713c311077c359f42971b65463a8de1aed9879abd512cb55b6e44f5c690e0a3f60768a778cc9cac5ad6b897379507e3ccb994956284a7715970b0e3f6189f0c66d99c667119b82d87a6507141cfdba46fcbafa8a2a1352139b1024dbc64388a3275f34180ffdacc380132eff35eaf788364f3aafdd6af9c02cfa396592282cbfa110792f87b6182b2f36a0a895c0791276d789976cdf09d2c16a32aac669647219086bd36f6bf631392510c0e0970007a88378b647b52fc20ee9148cd4575bb8b31b06449994098bdf77680a48ab51b8e5732545d6b87112884e35a2302f60358f651f8a71c0789018dba79bf5298a9f6ad16bcbbecac4f0cc9888cf55bbeb38264c885ce098fa80463f63806a544bfc194b77895a76b22b81b1098a8c3819e035268d22f4ba0339067ab3bb30e65506a86e74fde52afee944df4e4c745f9393ad59117dacf74a407c236b8b5a2aa11b1c9f86163df31129e885ebf68040f822314c2bc4dd12751851864d743ea49b68a93212d392845ac46f95715796a488cb44072ecceca89878f37b51d662d783900b6341a65d894771476fb942ed058b15150bdc67a3b7f4cac93733f735b81f8dc4aa5eb1288d761b0b74238a5cd73c8bd2457bc195b785fd31804d654aae06eaf5b08a365a472503809b416904162c17942fd27671989c553ab5137488f385b7b9519a69cb496444a7a2db607adea5c3e128bcba31f586c5603f953f4fbbb4381cadcb88d6aa7784562c6ef302ed398cc2113abd257c9554818c8175db54baf20024978e167620b672b28bf24465d2cb4cfc6c08739fb9696bc84fdd76b136b39b85c7deb4c10ff59337b4112e32bb25a665e9cf624baa86aacb2a18ea3cb67462874117445f913558c32e5eb7e1329cfc2d99ca4d83007467b80d74d2ec9832a5785fc7293eb466d55cc8904874bca5714c776579b253f86b17187b9c19d702ae65aad9d7cc23afb041e593bc41308572825a76b4dfd51a2bafcaa10390a76e08458c384cd0089668955fcab00082759de9147bdf581aa4a81f8f82bbea84d255b43e30b6728fb7a705c0aa96b794c7ca28730c6a1b1b2c1040fa24a98ac862ed74453c03a3d842cb0bc87409a09456c739ea08717d7a1061041c424d13bbee299c1ab1bf328b42314263f186e5b198bd5b1712c04402bf849df6473b8e78c4009c944d05277c68d6eba8555ec48139560922a7a142632d4168dfbc6396d0046c53221d43b7bbe01bdffcc672f214217679853d3c0939acfa7b45ac81b145e5bc7d668a4466156faa6a44ae2b9cd6caa5d42cb1c2ac5aa847cc6501ce998b2896652e2c901483acdffa695cd1625b124a8a88490b12b72a5cbcb67a29aa955247fd17ef46606ab5b5fda6ac39edc0128e46310903b32435e2f02158f678462f2bb230246455b7d307b5bdb40375c6cc507987ef616816d3a97545bc0f6e44c025c961cca33a828beb6480494cb9049bb2e0c8734437ca0745b55174b67fca6abe743c7f9793219a19a88298211562e7ad85643b0b680c957eb6b740ac142276822900110f3998f2b043816c9216c416d64e482dc1053928722efda8c35bba98c563eb4fb280791a9a330968cd29360860737d3cabef87d158419cd8794d15771588cb049f393d3729fe3276590488e97f00e63b6cdb760c22fb853352c2eaaf7340b204d6bf8cd186cab5f786e7f967a4d147686a690ca7308173843dbc0bb17fa4ab2788436f43009827946265e86e782b97b2b27b87ee2c0ba9ff23d6d620ac02124189bb008d54da8f0118a081a70040b0c722a7b5a97194c5641078b22446d7ce9b66ab9332f2ab85d7320fc651eebf8b93b838421ac6818f87673872582360bcb903ab70972e8e589465660e6e4b9295675416547c277827d667102c99297f9909548c52621846f5978a5d6971ac97c6df5cf1a3a42717194f112093b73642cd757b541c6d5094931d97afa952ba80024b5d76caa088577f24b86208da3448dcce24769dcac3af496b4ec8e634294c7d323a85128d4e20dbe5b7bbafa8fbce12131f0663572a4c1a4885ac49cc607578042c0c68853b661b452662ae194512b208435a72ebad23519e07f96f59edfe2a5297c351bb38773478747732d9841b5c26091ce45559d7184e1ca01b7c388a8cb030a00f66b47988c2d7d195332662cfc7d90b279248de101f77e30087881ddff4095efebaea305138bf83f0e3071f5494c3ea5bec8f775128ce60aded5edaec5de3bf5b4d7c2f2e18e87f499c1968993eff196753db8045e2c8ba8" +}, +{ + "dz" : "c1b3cbffad4b306f9af0cdd3028876486dbe858875c9b6497fe20172a986c82b1c96249919cedc2369d8d739ab125e0d2ccb82dfebcd90240a545cdfe07511f2", + "pk" : "2d661f371b1f9a3c88556374af9b603c8c1db100ac3e600c042672bcd971857232fbe70e3c1280f5ac45d0e819a8495d2da89ef5086b110773c7d1539ec94a44fc0cd6f4a39362731f527de3f06f4a78b0dfbb94e4977a564c765cf8ca68658fbe27937a7b15a8671cfc8b3e779533d1b5c092826b3038b213550421004012a4cb3f12478efb0c92bcbdca4259b153584bd4b65a6b8d66f578f6f408bfe246deb5304ce5487b7a95c6db5605818e26d2cf5fa6adabea9e3a48b6f889305c016055db7a02a34ba5e10573143ddb8659fbe25c7b621e3494aecef037effb36b2819a1816788a6b410918745c2a423285c7e0021cb8c8793b60b4c9061a39f97ff1212f02d387d224b0ec258268a374b6e27ac9c4598fb78c387a7daa439280d79a6218b3ceb0bfc2e685bad8801d92b5b1a42f64c8890709c58c95bd8ebc43568c33362a53b5a12c052489bfd806cad36dda117b2180b68cfbb317d4bcdf745c50324e19dc7b17ab7f31649a57bcce91fa720052afb0b0ba5e8b57a5e4296b1c390da9a4f76a869af0b9389c0ac381aeae0a779ba588ff415858b3300d71b99fc172de950a95c3a61c9072b6f2a7cd9245da690128b9c597c44903837b8a9443865c785ff6bc05854e1115b9e3d7a70c7c40216ca48b1c6497062d61fb8cb29c71e5800b8e752e70b9a8655baa8408742a511ede8409301620f3bbc2a27790dd7058841432cae4cae719740835571ce65027e74d85958db506a8e9601c1f5ba5728a6e710a3d3d93748a7a640c460167482dcd6cccfc238326171927c6a72ee7084ee97d3e7519744ab8df651b9b2b69d4ac7cdbd9437849114e29550ba3321202906e9331bc7ccbf4571da4c6ae1a0b2797ba4bcc75398e18505eb02dc760b00f687c76f2a35f707f609ca149b4be233b3ba4739e19e4462d78950138cd1b210904b10a83356156a63631d4a6193c68e78642e7c5c0daf403e8520cc2f7438ae950d4136ad32684f2881c50c1a508b0442bf6c92f030f82653578c79fb4eaab1cb60df4870d6966ca5bd8651400a5a6d424749c8cc6aa6fc90b6514a8274e633aaa74435542bd2eaa354d65a32591819b8233834abf1391470085c9144b8239390f97624fdbc645d3662f8a7a2b7ae412f8525884081b3282390f8c35e2379aa5d234dfe9c0c94098ecfab31dfc315413c62aa80fb8a9ad11d070d02cb192d18f3717c1375401c0713437b0868298205162a78f8b00fb46ca2ccc6dad2717185b72793b2aa009419a6330ec508c8c325110c53fa0512a713c500631b36ac410c5a966edf1656419740baaca6719639987bf5e17444b4122650c87c884069fc52ba082837158b9bb85b2c961268284b5d8636b2ed3bd1781296de78a1cca44502a779b2bacb6f86d676355d4d527bd050ca8d33a12d059e6d697f986177e1b95424ba97cda6b6ae0191ba70bcb75172c354541c7742556c5fbe591f33b9624452392412f3859953ac21c50d5a445a34d94d492afbb01a84c844fd582802391f4f4a5d012a8a62079e254363fba52c83a399bb3398f6807e6f03f74f68fc788187be6bcaa5491ff666c98e43c3f860470380768f70b4987c6ea10411ea60fc7e8cba0b1afd72a52713a41a2172804ecb9fb60315e37c544555a8aac8089081c6c2695af8011bd991e1ddc87c841cbe0c0357e04489785222930a5d75b81cde91e5804315bb30bc93294367a4623a0c4a0ec8ddc436c7992b157039879bacbcb590490c28ae7c9142267654291c06a75237b24b8895404cdf32a073c4922c202a087bce07aa5708816818564c68237136c0a98119c2a6244a59051071414425b9230a6113cab28b06a058e67b16b9b3287f001422c276c78aaf608820836c863a1555590bc802a70abda52e4c430c80992745945ebd343277c222836631c652dcc425e1fec6f22383eb78c9b47967e865c6382231b4ff42b94f281c4e9a849477706c339a48ac2c69416d1e51914c751dff0b74cc657a8d9b0d0e21cb2c3a72fa241338b11f529a0ea9cbb8bd310203b29775867f23b7a6ed35890f3014474b51a578110cb1e1d052d2cd03a19fa06f1750279476642752934201c0832b80b552c7a4b4eb1118e2466624588ac1d0148c1c0484352479ea604758012b5d49e885965bf6ec29407a0d9d3f1f08826007a5a3d32062d2a775728c35116642149c2d449", + "sk" : "74e23285e187f22c6a1f0b5258081ca00c59ad4a733b6c168c39ae4994c7cac606422ab8ae07968a652c7cb130e3a1b5b65077ad348f2b213ef368c46c1b45ecf9c58fe49a86396285d554b157ccf2142864fc88df377c2bf758a3488722dc9111b39a90c58d29d18b0373801d761faab0845e78bef3c0b91509c7c9e44cf6a74bcef19de93538567564855981484ba0dc5a0553e921d302449663cce9c3aa1fdc3db0129999e011ea3172a1a3a504e2286550cb86156a23c74e0b2b2750648a15479aad813c4a576fc8f70553a34287147580b6a62957a26306cea1571963d4171dbb38448763b664752ce93a21d84101f79a66bb1e192b2c4ea0266d1c869226b0e110975bfc13e6e384c1883a76e5258c129185ec036a6063f182a35c3ab843523ca5c9b30b655eacd967847c86de2c169c40866f8b798555497ea94cfa99591c1c563264b54d369f0297168339379310be3354baf9d1ca6d7a79a2d0517e39c0f6412bf64bc57059b05db3888dd35e5af70fccd55e38e053b453aa43d0027f8ccfc0e15da1c91e4a0b3b4bb776df88aac1308f444856f3e888ae4753888b017cb342e70c78318a7a3a8142bb28326caa32809571d547c15b86437c655ebcd48bb2990493001ef4bbc7b4a02008396755b911e1782ddffcaa92a34c39dc8e0b9a48a33a252d6c547ca341f92727b5b40e92565ac466ae58000799a534b8277591e99876b4925a9a046644056a625a7a51431aec58c5d6b98eb4a0f40724e24477f6ebc52ab7859987871e623e93a0c081c9212e5b33e1c813c6a81980a5a670c1991dfc721ec62dd771cc9a30bb7eeb67ba71ae78c81cb802743b3589e661c4af476bb5753458db8c7d281575eab3f9216307a02f95147eeddb5fcc76c158701bf8a44d3890b65e6b43761a757221a70769b825b6cac8fcabb1dc155af64b86258f0ed5260522188ffb472cf64b82cb68cd41b986b560bd00b6cd99b805531076e25a2bd6204e264114602d6c1bcc5e9235c85575e66b391bba0d4297c9cb5508dc5cb3200b092400ad59508d7fe14703d433f980a79a796f24b82c60741a8276257c5b5311d85cfe1b8733eba10e305a3ea4affa5304f98a438325647a521f1b154a6547cbd8457545dab60ea7966a03b40e7c28ec1a22c4757a3b3c7dbb191895dc419cf609adf40c5fd86436506894a3932f1666ebd14a74c93d5e93511b5401fac02fc7280d088057eae2b3c457168b1b9e25fa81ffaa9d30c27dfb250dd5f287f281b12f1381657918eaaa067ccb07bc0a67bd4827368c7c0b4cb45d403159f9cd8de5caea6b5521ba173160561c9270ab15c85351cd46e8c4a3810587702f3f0b6921367e4648b654fb53d9627f573b936c6bc050a34b7e3c7c379a4c744b80230c35b784bf9a4a3fbd8a892450b4739488912b2b822b3664c25327d051c0236e05487671461264e2643c0aa7ca89a9c85867c817b714507c2b955371583611e77c783b68796267259638d4001e0555a19644b70b8527d9d66a5a3036e348cbf21200e3e07717cc83d0866ec7356412705706f192dbda8f43ab30d3f14d059190c1c95bec240e0c3271c2b755942183379893fb6cb0c0075c7b67352a76bc2bf7390c39c3768127e9402fc7e2716431bf25cc8405e23bb5830f348b4d00fcc1fb44389100cff58a3409174fcd39c5779c93336a053d04531942133fc92d66e3855043bfdea0c0f7b7795b0941db78a52d6708a83913cfca678f67000d873060777ed6f0906976ad12946b70c9b5f9e4a95a8b1eb5b733d3d92921cab8bb610b3ea33549e6371ae507ad34170fb09ca9d65c4360ce42ec63db51b1705b19205b01688aaaa7c00af97c93fae66dccf93d44a61ab5381326982ff2a73bc5b19e17b126c7a652f36154401a6d28006a383841f4d9998a06152d0b58c5e6457b601953536693918768cc1ec85b1494255858da9253693293848bf8c14a6bd362a2b91137cbadfb82a4b1f80a3577869b50716983730a31ad1574a3f5a62ad6635ad11c4706ac6912248a6b55cba70658deb6336e7344f1535e195722486866475bca60c8ba89cb591afc603ff0cddfdc55a705beaa1b99ae725a400454f6874462713e12698a55a267a96092be913b3472b0d9fbaecf20169790368f010b2d661f371b1f9a3c88556374af9b603c8c1db100ac3e600c042672bcd971857232fbe70e3c1280f5ac45d0e819a8495d2da89ef5086b110773c7d1539ec94a44fc0cd6f4a39362731f527de3f06f4a78b0dfbb94e4977a564c765cf8ca68658fbe27937a7b15a8671cfc8b3e779533d1b5c092826b3038b213550421004012a4cb3f12478efb0c92bcbdca4259b153584bd4b65a6b8d66f578f6f408bfe246deb5304ce5487b7a95c6db5605818e26d2cf5fa6adabea9e3a48b6f889305c016055db7a02a34ba5e10573143ddb8659fbe25c7b621e3494aecef037effb36b2819a1816788a6b410918745c2a423285c7e0021cb8c8793b60b4c9061a39f97ff1212f02d387d224b0ec258268a374b6e27ac9c4598fb78c387a7daa439280d79a6218b3ceb0bfc2e685bad8801d92b5b1a42f64c8890709c58c95bd8ebc43568c33362a53b5a12c052489bfd806cad36dda117b2180b68cfbb317d4bcdf745c50324e19dc7b17ab7f31649a57bcce91fa720052afb0b0ba5e8b57a5e4296b1c390da9a4f76a869af0b9389c0ac381aeae0a779ba588ff415858b3300d71b99fc172de950a95c3a61c9072b6f2a7cd9245da690128b9c597c44903837b8a9443865c785ff6bc05854e1115b9e3d7a70c7c40216ca48b1c6497062d61fb8cb29c71e5800b8e752e70b9a8655baa8408742a511ede8409301620f3bbc2a27790dd7058841432cae4cae719740835571ce65027e74d85958db506a8e9601c1f5ba5728a6e710a3d3d93748a7a640c460167482dcd6cccfc238326171927c6a72ee7084ee97d3e7519744ab8df651b9b2b69d4ac7cdbd9437849114e29550ba3321202906e9331bc7ccbf4571da4c6ae1a0b2797ba4bcc75398e18505eb02dc760b00f687c76f2a35f707f609ca149b4be233b3ba4739e19e4462d78950138cd1b210904b10a83356156a63631d4a6193c68e78642e7c5c0daf403e8520cc2f7438ae950d4136ad32684f2881c50c1a508b0442bf6c92f030f82653578c79fb4eaab1cb60df4870d6966ca5bd8651400a5a6d424749c8cc6aa6fc90b6514a8274e633aaa74435542bd2eaa354d65a32591819b8233834abf1391470085c9144b8239390f97624fdbc645d3662f8a7a2b7ae412f8525884081b3282390f8c35e2379aa5d234dfe9c0c94098ecfab31dfc315413c62aa80fb8a9ad11d070d02cb192d18f3717c1375401c0713437b0868298205162a78f8b00fb46ca2ccc6dad2717185b72793b2aa009419a6330ec508c8c325110c53fa0512a713c500631b36ac410c5a966edf1656419740baaca6719639987bf5e17444b4122650c87c884069fc52ba082837158b9bb85b2c961268284b5d8636b2ed3bd1781296de78a1cca44502a779b2bacb6f86d676355d4d527bd050ca8d33a12d059e6d697f986177e1b95424ba97cda6b6ae0191ba70bcb75172c354541c7742556c5fbe591f33b9624452392412f3859953ac21c50d5a445a34d94d492afbb01a84c844fd582802391f4f4a5d012a8a62079e254363fba52c83a399bb3398f6807e6f03f74f68fc788187be6bcaa5491ff666c98e43c3f860470380768f70b4987c6ea10411ea60fc7e8cba0b1afd72a52713a41a2172804ecb9fb60315e37c544555a8aac8089081c6c2695af8011bd991e1ddc87c841cbe0c0357e04489785222930a5d75b81cde91e5804315bb30bc93294367a4623a0c4a0ec8ddc436c7992b157039879bacbcb590490c28ae7c9142267654291c06a75237b24b8895404cdf32a073c4922c202a087bce07aa5708816818564c68237136c0a98119c2a6244a59051071414425b9230a6113cab28b06a058e67b16b9b3287f001422c276c78aaf608820836c863a1555590bc802a70abda52e4c430c80992745945ebd343277c222836631c652dcc425e1fec6f22383eb78c9b47967e865c6382231b4ff42b94f281c4e9a849477706c339a48ac2c69416d1e51914c751dff0b74cc657a8d9b0d0e21cb2c3a72fa241338b11f529a0ea9cbb8bd310203b29775867f23b7a6ed35890f3014474b51a578110cb1e1d052d2cd03a19fa06f1750279476642752934201c0832b80b552c7a4b4eb1118e2466624588ac1d0148c1c0484352479ea604758012b5d49e885965bf6ec29407a0d9d3f1f08826007a5a3d32062d2a775728c35116642149c2d449367bf894b2bffe5be757d54623b972fdb9093b0f54568b4f6f2e688f86ab2eab1c96249919cedc2369d8d739ab125e0d2ccb82dfebcd90240a545cdfe07511f2" +}, +{ + "dz" : "ff7495b8575b5a98e4fd21fb4c3e58cbb60f14bef21aa74cf8802e3153f14807bdc370460375a778d1a31d01c42b66367ed8d9e8f84551002f552f0e52102b5d", + "pk" : "90c537fb848ea86c2ba929c7b97456ac4b5c5007b27631aadde902ae1917dba8cf2936427fa22504aa2bca42bdacb21ac9a497eb1cb8a4b096e69294620386abc48f389c7f14380b03b10c614c625427c8cb9962f3d75409d923a56717882169bdab15e4426dfdb26072952255eab0380a88277ccac1d24939c98900d0be4570b3df596aef0a1747b2b0106c31e9aa9164f7745de23bd1cb222178ba13f7c806c0b02ff9898774646417bb2fc3153167c1eb707655c548b63caaf3fb3f37771be2fc972d03bde5286586d406b00902dfa0897785481b95805ab79dac44233af99ed3f53bfd6cc36af1cc79006289563456fb71b54c6e5e894f47d715ba062e010841a9e67abdbacc31dc373ec88ce8eba2f96381edd02fd0b88b47888f5084ac264c755c62a663ca9e30bb2bb8c89dc2ba91ba652fb79008ad91090c0614d6c7c674139ba5d57d26dba05e7c47e2107aac4cc28405a7d0d415e2472f66c40d49e094add494c19175886474b5a6991e355738c66d9178c94bb4c05912bd9d709290a8b562a358814a14c50750d17054273c7587b7ad5e403f231964bb40014fa7121fdb74dc23875a148f0f021a8ceb3cbde6842714cdf1008d85b0af62e65ccda27d9fc2a12e415801bb22a865b861aab5cc3c9093c3164e6b436a3475e5359bb8c241b635c351ec3614f7a225d522f2a0b7b181a1f7a4ccc858014a2222ba5b19767154e27b2667e90aea352ae7d3c68e07b7c4d0482ec38aa226ac4f2b63a8da4be57842a4a65b6e04c2166327be09a30128bcc33c154031b94ee13aa5d60f7708347659b4d73bc500432bf2401861c183c732019576a672d0c10d5c18afe4364e9ccf67d670b29283d0f0b9f91130a0437d7450acb4d76af99aa4ea287a6bfc73fbaa3207f58fccc775a811a7e6a0b7a63bcd87f04f1eea0d57ab7735315324282b4818b8d4346b0ecbcea3ac9c0a7bbc17a955617570a511447a9b8475f7c602135f57255e2412cb6ddb0d22c30159b43b9dd58066d81d77f7a4e263603e193ebf671fa3283c69e71a4ac433297867da2b2b7eca19373a9b4d3897689031e58284ec8779fcc4cb742b8712b11a3d143b02645a99db61bfb19c26a5902f7b3d77302a9ab059350925d8e1a994b586ea777697c389f9cb6e25817e07c5716db9ab63f451dc89a852031bb3352e8ba53643c509ed8590694b6a07340ad0fb2f1788937a0c45cf9a441494ae447c44c6917f2d7b21bdc6b7d3853bd8e33bc7ea75e62535f95096a9d0930cbcc0a210c2f5b81090d20a5d7c0346bb43ebe6b77072859f13a6576c72c0553da80a4ca8f03292d86a98246151960e4b15b758b28e2ad2271c9ca70f92061c8a560be21a2d967c0ae1b0ca446a987bbfd888ce4ccb725b95050d03134f3441f853935255bce8473e88397d5eb4cb8d6acaa6bb8d5f5003a560b08c89ac890b77aa16304f5cc74822764d82823b317572c5bbee018eedab6cd93caa924279ca8932a8858079197d412b7283e084a7fb9dbef26d4530c1b6136619b06fbae495d207a3c326910a5c2ac9c7b919498bef5482532535d2551fee95154b2082a76c0d3b16ced88993697b344cf7be4742a3180c69f6fb589ac17fbd03489b13a0af951ec1d9776efa82cfd0276e58c553b2046b4594c9621e0aeb160d7923bbfa53f7c9c2a4a077d51a6f38473fb6d7a2b2b99c5414c5e646734fc48c56c18d30997d8073afcb822680b321c40696092a7a9f9072cd034523acb15154354d697f27a312348601d0d1170beb4759510330cb0adef4cf31ca82f7f15bc02310f22c92dcbbc059e34771725685955dd5490331e0bd99829692275598a77a310243a6225f392a9f83910afddc172d124cd295288a77ae051031f898b42d792ddfe8c0902944b68043bba48a25c27323f07d4f6a8c6ecc33f13948ad12463e834d23514af69954395a144d1a4df8f526c0331247d16d05e185ddf04a94a92047bcc976bc17f6b7488dd390eaac4b608390e9fac6c2829eed0903d544b3ff08b2c27a779198387a8112e374ce4f5b0f5f898101159462929c5417bf373420811b4ecbc034eb41aec0888a30976428e2a54463072f3c9b55341147c464dc88b55daa1fa7920c22fb6c8225b2ccf47692713ded1c4a76a479bb111e56cf782a6cafe938d47de49bb47e732223b0bd1bee7bf690d1857044eef2aaec", + "sk" : "3642bf33d87830ec6d87e3ca5e4432a0553fa502878f93281671b93e87cb76763518841148126ccdfb6e8723aec1975cc8a3971e24a8a9149a9957620b0b211c4c3f942a21daa5182c63049bac82959429f2c1b4f4b1204ce35c7c683db5127a89699e23588d194574e603557d811af3104b7f23627dc046ecd6aa633a20054ac997625147a2cb6bfb62e44bc7eca7a019d41ff5ac505870c0dc648e209111ccd5827c750eb676058c6a14267ccb865b3b40da4e2476aff41b9227e18274c96e32966f2eb611fcfb3880159e6f2c62a9565c8e6c3a84bb530a13895f841ff354b798299ad3b68ca32838ea6b3920b3b6f0415b7a750295d33eae09022b8c17d7ac040df6b298d7bfdad78f868cb97d178d5c80b27b69ce03d37f3277661d9b9340f347bc7296d310041c996efa841bddd592fe4b480da657d47bcb4d147c112243f15268340b14ae26742b813934c26be8204ad984863eb44c50c510a5c5872cf334275c5bd2517c55772e9d5020e8093d5f21264929b1c7858b4f8745ed0b2c9bf9671d3c085e80804ad730b8e0865b82a6d6bb1595331a0a05567bd3af6a641918019d9a89b08f227640182fb8c7adc6278473b2b8af4c4c9e6b8f8232215d265f433c7357fa8c91751f6cd08b678240c5da1ebc38ce3f2735d3320713ac4301ea1fdc1990b8909cb718b6344c45a612633376bb9e003656ac347305c3aec055689c696eb01ff62b3a4fd0272b10cd778572667702fa4c2b7ce5305c413d91596904b872a0b051a255af18119d00e1a4654c05259cc16663674365708843c20df18b95d212efab1dd9485dc4426782fac42e258fa0cb8bc3896a507107720246b972c457750bb98ac03c9375820046fa7021af606c9344599ef233de25667592b423e456a659c0389b86b27a0eb4675693c029c489a4daa1b5ecf37afbf80b8fea5cd9d37beadc9fd812428ec68484b8853cc82f019c9a7419115e8ac0972836d42bb459611ba06b82a59592f5440134908f35d182c0a765f9f44b66b293f471222d648989b61b7eb8586e004e7bf789838500c2aa2de031661d4b7c46737772f4a86df60e050164a1a998e996042e22b7db76c3a4575f99199c5851c75f901085b21f6f693b5839557f259194590e84dcbad233bd9b670049d47b67d91616db28dce64ec552712129a2abac23b4922fb4cb6bb3e54f7ddb093c5811a638cc3330a1170c46de338757f445df01aa42e056e6d59daf690d3b4961365a6927db368a5633a4ca087fa74020b0b7884a0afecb5bb3d124276b38eb8c19c7c8afb616a854b444f7f0910ed6c3eef93722c827e80297e7f411b90b41ed430258e091e5ab151d961af1e51fac9aa03172c147d69e84274b3eeb949c8588edac38b400c775849cf162932bdb6f80fabba816bfcaf51bfe9174cfe0191084004486814e938153478728041fa06a78e1916d20465370e55aab5c993ef543c360bd082c7298250678f979904b402de70dc4f9403e805b71955039b539784b2e79173d870363d8b677aa5c823b8980062ca773ba71bfebafca6399b40c8109f4848db6cb154a4846cb9c638c4e8b10149de52667a21d1af419de65c030cc7bc8586c45a615dc346ea4073f4eb131e0607740c73ded62c192a413e955146f86ab9386156b3ca110295ced41977b147ec9e73f934ba396a27b6d6c37d2460e4e15c0af6a090cca7947c0103489c7dd9a56dfe62f5c9692531087fb7b7a75206765f34316378673c52b6279b0db8c8dd74049052aafa5467ac9fb7686cbb904f24afdebaaa8a7928de03c02e35c14e4102b560d8831c62c44154758582bd901ed9c963fc558ed076c107a87f0e49bb2e1585e809ba31788a925588a0c8fbab37b3bd79268eb359982063775abaf9622024aaa9730cff8411c04401cb58a4ee90b83ea547b1fe8ae6c3a93531511298331ffc512ec195f982c39c9394bb0933bbbfb1b46fa0c2dbc120c8acb03953e188a6ee6b2852e79642ea3261c8403b3497b99ba7b25fb99949300dbc9bdcbcbbd72ca935242ae35d27cd66003f22c4918ac412f3304ee92b740c86cb12362df19353438569c16935edc8af7b6091cc97c59996ce174253e9b2612a54dd9399fb11a5d0fa3af913bbc66e1874dc7527381b593966014fba090c537fb848ea86c2ba929c7b97456ac4b5c5007b27631aadde902ae1917dba8cf2936427fa22504aa2bca42bdacb21ac9a497eb1cb8a4b096e69294620386abc48f389c7f14380b03b10c614c625427c8cb9962f3d75409d923a56717882169bdab15e4426dfdb26072952255eab0380a88277ccac1d24939c98900d0be4570b3df596aef0a1747b2b0106c31e9aa9164f7745de23bd1cb222178ba13f7c806c0b02ff9898774646417bb2fc3153167c1eb707655c548b63caaf3fb3f37771be2fc972d03bde5286586d406b00902dfa0897785481b95805ab79dac44233af99ed3f53bfd6cc36af1cc79006289563456fb71b54c6e5e894f47d715ba062e010841a9e67abdbacc31dc373ec88ce8eba2f96381edd02fd0b88b47888f5084ac264c755c62a663ca9e30bb2bb8c89dc2ba91ba652fb79008ad91090c0614d6c7c674139ba5d57d26dba05e7c47e2107aac4cc28405a7d0d415e2472f66c40d49e094add494c19175886474b5a6991e355738c66d9178c94bb4c05912bd9d709290a8b562a358814a14c50750d17054273c7587b7ad5e403f231964bb40014fa7121fdb74dc23875a148f0f021a8ceb3cbde6842714cdf1008d85b0af62e65ccda27d9fc2a12e415801bb22a865b861aab5cc3c9093c3164e6b436a3475e5359bb8c241b635c351ec3614f7a225d522f2a0b7b181a1f7a4ccc858014a2222ba5b19767154e27b2667e90aea352ae7d3c68e07b7c4d0482ec38aa226ac4f2b63a8da4be57842a4a65b6e04c2166327be09a30128bcc33c154031b94ee13aa5d60f7708347659b4d73bc500432bf2401861c183c732019576a672d0c10d5c18afe4364e9ccf67d670b29283d0f0b9f91130a0437d7450acb4d76af99aa4ea287a6bfc73fbaa3207f58fccc775a811a7e6a0b7a63bcd87f04f1eea0d57ab7735315324282b4818b8d4346b0ecbcea3ac9c0a7bbc17a955617570a511447a9b8475f7c602135f57255e2412cb6ddb0d22c30159b43b9dd58066d81d77f7a4e263603e193ebf671fa3283c69e71a4ac433297867da2b2b7eca19373a9b4d3897689031e58284ec8779fcc4cb742b8712b11a3d143b02645a99db61bfb19c26a5902f7b3d77302a9ab059350925d8e1a994b586ea777697c389f9cb6e25817e07c5716db9ab63f451dc89a852031bb3352e8ba53643c509ed8590694b6a07340ad0fb2f1788937a0c45cf9a441494ae447c44c6917f2d7b21bdc6b7d3853bd8e33bc7ea75e62535f95096a9d0930cbcc0a210c2f5b81090d20a5d7c0346bb43ebe6b77072859f13a6576c72c0553da80a4ca8f03292d86a98246151960e4b15b758b28e2ad2271c9ca70f92061c8a560be21a2d967c0ae1b0ca446a987bbfd888ce4ccb725b95050d03134f3441f853935255bce8473e88397d5eb4cb8d6acaa6bb8d5f5003a560b08c89ac890b77aa16304f5cc74822764d82823b317572c5bbee018eedab6cd93caa924279ca8932a8858079197d412b7283e084a7fb9dbef26d4530c1b6136619b06fbae495d207a3c326910a5c2ac9c7b919498bef5482532535d2551fee95154b2082a76c0d3b16ced88993697b344cf7be4742a3180c69f6fb589ac17fbd03489b13a0af951ec1d9776efa82cfd0276e58c553b2046b4594c9621e0aeb160d7923bbfa53f7c9c2a4a077d51a6f38473fb6d7a2b2b99c5414c5e646734fc48c56c18d30997d8073afcb822680b321c40696092a7a9f9072cd034523acb15154354d697f27a312348601d0d1170beb4759510330cb0adef4cf31ca82f7f15bc02310f22c92dcbbc059e34771725685955dd5490331e0bd99829692275598a77a310243a6225f392a9f83910afddc172d124cd295288a77ae051031f898b42d792ddfe8c0902944b68043bba48a25c27323f07d4f6a8c6ecc33f13948ad12463e834d23514af69954395a144d1a4df8f526c0331247d16d05e185ddf04a94a92047bcc976bc17f6b7488dd390eaac4b608390e9fac6c2829eed0903d544b3ff08b2c27a779198387a8112e374ce4f5b0f5f898101159462929c5417bf373420811b4ecbc034eb41aec0888a30976428e2a54463072f3c9b55341147c464dc88b55daa1fa7920c22fb6c8225b2ccf47692713ded1c4a76a479bb111e56cf782a6cafe938d47de49bb47e732223b0bd1bee7bf690d1857044eef2aaecfcda92e6bdb853f01617133d65b67c0d6cc83710c053a18263aa91dbdbef7b85bdc370460375a778d1a31d01c42b66367ed8d9e8f84551002f552f0e52102b5d" +}, +{ + "dz" : "bdc3fba1c32751139fc45bacffb3ea97f26573d804a5f27a459293d95190ed8efd5a08f656a6eb8cd20679930a31caa6a6331c4b133a6838c223ef9f769f6246", + "pk" : "12e4c27fd191ab43b4aa8a66c4326e681cbe1207bc2d5aac1ac59ef0a8aac0c8b91f7c23ac35abf566c75ad3b01d6b1dfbc29db4a334b44c10fc25808f9b8acdb4a2ba67528fba8ee942a895d5544857473459763e92174dc640bf284908023146fb553b1b8b1e99a7446c5320ca17eb6bc497a330ded7b1016a1c28d23964f24f2188b2d7ebb2bbe954c9d9271baa7e429c02dab991dffa49410ba6ab20829ec41b03b8ba8756b5cffc640e928b24361f0f007226f2b5315a8bdf8a10aa88581ce5a140588b69b531f5112610c5306fe41d4c018302dac1dbf69863b6bf99d892072591a0168decc69f89823999095f256c52c6336acb063bd741551bb855678c4e8bf90191a38c2fc641957312ee758e73d88d8c8937b9c6912c59ca13854a4209924db71fd8b547a076a340560155122298e91328a71773e1cf117920e5faa8fbd847fdd027f734c06bec0bf479b97cc11d626122d1049e96c7643a6b323aa93e10521460c7193d7c85a1a8969dd0b0835b64ade28df777a1c70646b8e55578ba9da6d82a96b5bbca1b2e9346775d24b987535882468b3e9263a1c74288695722142d9ba23fd747383832b2a3b6720b21cfb5f00a178c51a878992d666872685cb1f346c77b86a0174ac955b06df96ba094101330958452074c57377f520bf0766881752d70c0a778415f9bd3b5d276100f00ad563735cce0952354260c153c3ba227181a21b9f8166dc0aa42acc241f6051624b88d1659a2a81f9cf92ce82c76dadc27bc3b018f953a5af66ee21401c02a4e3b8b4188a36be3818ccb82686cc21d50614f1f000721f8445323b4920b3d929c1362d91ef948371b531096186034d61f0401c09679c54c5a993ce85137f15f50466bace29512e260f990764c31648d6649d23c800750a08f759fa84258515c4625b856eb368d917c36768a8a1471a376ab367aab46295707e94080bce47dd4633c2b50ce0b19bf47d4a68c3519da21c205b0c9128606ef8a7405ac525a12b0c613c7ae96aca34743ca9679bf078d5d016405f336f6088a9652204154648e4b3f6872929f02670c7962f4b08bdda9beb2a33a2babcef40cc4de288460d0188fc29ca85b212eb40f7b158aa4a38710e0608eb150fa5252860058ccd822618961cf5c18a01bcb2eb92dda84597fe9b345e06d14a597917a4748949ce5f29e60a7ab29740242166c5a651501010bbbc73926a7c4d0dc6aa415240e0c0769774055f9882aa4330dac1d8500747bd5264bb7625c2ab58e7917cd122858135ec09a3f0128837669bb37911903854d57da6957d70407c752a20951535503847b17c536a69ac09a84ca64633a4fb9c26221296190b27c03781729456f6653639fc036fe17c4b66b390b2204a1361555323dd307572b2caf24148dfea74eef05880205c164da71980974240b2167b3c3200745ce778a4cab786a0cbb132188158c3111707058884358db6ef3d04480d7ba058c7e52e4052c1898e2918d98590716a80bd9a3a4c3d53cd8111005709e708b04c6d18bb1577219a39d26a496582384f1126fe491a2dab7b8adb4a07563c687c4a6056455113c6fe9b7bd30cb7fbed2839a93a584c76af5c1422dca809cc623079ab65cb146a3011c38c1a6f3db134b72583ab9331d418c7ab513d77b91a612053f217d406babaf4170607a1979ea637f8875154561f69870fb1682a62052fa36a21bf94fb4f24ea54c1658d8bea4e2813707981366a8d9655400db440db8c27af57ebdaa8ed897c7594712e6881c81f5b79557834e53c9b537ab69942830fa60a0c8bc7518192e52396ee15d945b9f8df019f8f32513817117834a9af58ff761a1830798edd48fb571be338b43140c44d17b272db6aeebb0cab160342b49cbe2b47a6a5006b5cac09d763f168c6a5f329b7d1b87dde69542a4437b8c426890b4a5487ab43a98ef94667efc881a943b33b42c776b3f8af853fd59c2d3031fbcf541247100d22219e67094ba89791186bc8b7b536fb6438aba5275d234adc5a9ff129fa7d1b5c5757483f02980fa40882aa0c72c0ef233b0c2931f1e15cb7d528b471c50903256e54a87f8c16f02b3bb904133bf60136d603bc57c503420a8b6701aea4a3b4052334f75bf820c2ed9890bcb812b20d9031c269af9598acdeb8a52bfa7cb804627acfa20285753264f3df670dc445647c881e112b71095f10934", + "sk" : "58b513bc1a5f348c2e22a0a8c99bc5178a736854b211c6b4e191b497f288755843e306c1527c87ac5393c98c77669a29299c660bfc0d67453de33cc838d2c0e2d561e54600f89951f7543a42e0891d846f347a0e2fd956e29072d7b1565be798d3a295321cca8209aa439b5374602da08792d6c814fe3b0398a2743cd258a8e505be98be9c5c806c7007abbbcec5caa7151363789b22d6210e519649c34c56ab5b7a8318944370c30d4c16b226490d738282e63881e0b163e11b4818083cfc7593b068eb7c8711ab06553164382a87a683267957485df51dd5f5b0135bbd09e0be01594b3a134761e3a7efb567c4554b0d4b6ddabcc50c036144b1b88484a19ab8a94e168cff620330647dee43b673664a01407334883cbd6379a61a1c7b755d28c80921416edec02ca326c8fae52b4495b991335d253387682716f283675ae96ef431b98a821dda681f35c71f5da09ffdfa471d915574f23391072c9d8b50b9e06bd91055395958bb911a399c8ae9eb2884154cb7d59aa36a4d05b5887a23962260a057257e7e815859f53c85059760857882ab38fd8cb7a2514d2745867fb348b4f1ab4e8c0f200261e68474dd45394ce01c1e4a07799ca7dbfb5b3c51c7c1500edc768bc389499427955868c21bd3a94c3694d588700da5641b242edc152f1c1c90e3ecadcb04b8512342a76027c98a6af96a0958f775abd890fa586d81497013e062af9aa7e7734017807d89076a102bc46924b854d32476b1b6ac2cc922f0afefc6c90c6814a1819e96b429991b1250817a9187755805956d28a7cccb043469896d326df5477699ca89081cb44cc492ebc6671f3108f0795cde1422d3fa8dffa15e3d6040300b462f57986b355d7fb12454bac56d66aca19240c70445c166cda05a8d5a0763034387b50c32df573e61c921cca5b26ee3095b0739cb7cab1756a097b4c5a24555bc4a84681772b1ecca530a41c7db1f2c49c2aaca0ee363ca9a29b1040a5c31c608c235543d36abc90a36d8110badf3b10af267f6cb11ebc7c0224175d2d82a0df8485a7a754319952da50f48563937517fd4032935830b47f907a9489011b93a0e9a3d999b3d13416be914a4d9a4196ae573d73a4bf1099dc3c19dcd2b6cad5999a71a7e25717729495597997112f23f38d54808bb0b86c2558c83bc5a290b0ddb26a9493abfac76e9d25fbc888928417f5c2a1a1e34a355343a45c4309822cd83bc55362a7b8ee521fc816bfe22afc047196f87b9eb9092700723d3611dc5a53e8f9108e5064a9183aaa252ae2024b33ad93ad1c96796603a8538c7f1a3af202024ce12cb4025192744bafa338f325c10e1544e18a92509639bb62c4372ebc39965cab0d1317f91bf1b46a4523bbca018526cd681a3082cdeccce960c6d2e5b317e2568b2f4a25a8cbd1844b1dcfc32c0160f12f126f0caa3e6e37d95db68deebccde353d7ccc22e204bd8b016f9dc1bca5c8439a4cce98ebbfae4111a8776b09bc325599cdae20c354640faee43c07911e08348a17e75f483a3751237f1eb9a43a49702654a4a0f21c3d6b591d3b4add7c3320d8083c223e889080ab6b364118cdd1d42038182ce07bcd7adb2deb2531a2536d2126460227604740cf54bc513c918058ca527b48b0ec1c6d6cd4549b5c18d50a477a80cde6e87efad1284a71869d46b47f54465b9669e1ec5ed18505bd8c49bec69abee2a2c69c684db270e5a7a69846738f2a2416148098174c038964c8149f56097caf8840fca26d4f47a68d333761db2109372778f56aa0003f402b3237b079f3a8ac031a41eed50c218673b05a5757d29196a653a47b689ac25a2800c79ca20bbdb02ec6b430456435df3b7d81089cc986bdb246193bd1a153796ca5f1099d2a8c23810cf8467517085ef79b7bdfa7ba0c1b180b8312fba0999f87c8bdd518b5654075950cd27861ad55724766664d8a3468a8139201cfc9a48fcfd0839dc41b0d61798ee6180bf33335c78faa7a6e1a31262521ba7fd79a5ab0854c6a2f14265e418212324817cba46ee849713fbac9bc11a8de51376ac02c35f45e21f642732cc132745c5dd1cd1e45a31b5c9abc56055a8510f5fa71eb56c89d7685ceb4afe3255c734a59dcc2b5a9910db6ebbeaf4b110bda0270fb568c3c6a59130fe6390d12e4c27fd191ab43b4aa8a66c4326e681cbe1207bc2d5aac1ac59ef0a8aac0c8b91f7c23ac35abf566c75ad3b01d6b1dfbc29db4a334b44c10fc25808f9b8acdb4a2ba67528fba8ee942a895d5544857473459763e92174dc640bf284908023146fb553b1b8b1e99a7446c5320ca17eb6bc497a330ded7b1016a1c28d23964f24f2188b2d7ebb2bbe954c9d9271baa7e429c02dab991dffa49410ba6ab20829ec41b03b8ba8756b5cffc640e928b24361f0f007226f2b5315a8bdf8a10aa88581ce5a140588b69b531f5112610c5306fe41d4c018302dac1dbf69863b6bf99d892072591a0168decc69f89823999095f256c52c6336acb063bd741551bb855678c4e8bf90191a38c2fc641957312ee758e73d88d8c8937b9c6912c59ca13854a4209924db71fd8b547a076a340560155122298e91328a71773e1cf117920e5faa8fbd847fdd027f734c06bec0bf479b97cc11d626122d1049e96c7643a6b323aa93e10521460c7193d7c85a1a8969dd0b0835b64ade28df777a1c70646b8e55578ba9da6d82a96b5bbca1b2e9346775d24b987535882468b3e9263a1c74288695722142d9ba23fd747383832b2a3b6720b21cfb5f00a178c51a878992d666872685cb1f346c77b86a0174ac955b06df96ba094101330958452074c57377f520bf0766881752d70c0a778415f9bd3b5d276100f00ad563735cce0952354260c153c3ba227181a21b9f8166dc0aa42acc241f6051624b88d1659a2a81f9cf92ce82c76dadc27bc3b018f953a5af66ee21401c02a4e3b8b4188a36be3818ccb82686cc21d50614f1f000721f8445323b4920b3d929c1362d91ef948371b531096186034d61f0401c09679c54c5a993ce85137f15f50466bace29512e260f990764c31648d6649d23c800750a08f759fa84258515c4625b856eb368d917c36768a8a1471a376ab367aab46295707e94080bce47dd4633c2b50ce0b19bf47d4a68c3519da21c205b0c9128606ef8a7405ac525a12b0c613c7ae96aca34743ca9679bf078d5d016405f336f6088a9652204154648e4b3f6872929f02670c7962f4b08bdda9beb2a33a2babcef40cc4de288460d0188fc29ca85b212eb40f7b158aa4a38710e0608eb150fa5252860058ccd822618961cf5c18a01bcb2eb92dda84597fe9b345e06d14a597917a4748949ce5f29e60a7ab29740242166c5a651501010bbbc73926a7c4d0dc6aa415240e0c0769774055f9882aa4330dac1d8500747bd5264bb7625c2ab58e7917cd122858135ec09a3f0128837669bb37911903854d57da6957d70407c752a20951535503847b17c536a69ac09a84ca64633a4fb9c26221296190b27c03781729456f6653639fc036fe17c4b66b390b2204a1361555323dd307572b2caf24148dfea74eef05880205c164da71980974240b2167b3c3200745ce778a4cab786a0cbb132188158c3111707058884358db6ef3d04480d7ba058c7e52e4052c1898e2918d98590716a80bd9a3a4c3d53cd8111005709e708b04c6d18bb1577219a39d26a496582384f1126fe491a2dab7b8adb4a07563c687c4a6056455113c6fe9b7bd30cb7fbed2839a93a584c76af5c1422dca809cc623079ab65cb146a3011c38c1a6f3db134b72583ab9331d418c7ab513d77b91a612053f217d406babaf4170607a1979ea637f8875154561f69870fb1682a62052fa36a21bf94fb4f24ea54c1658d8bea4e2813707981366a8d9655400db440db8c27af57ebdaa8ed897c7594712e6881c81f5b79557834e53c9b537ab69942830fa60a0c8bc7518192e52396ee15d945b9f8df019f8f32513817117834a9af58ff761a1830798edd48fb571be338b43140c44d17b272db6aeebb0cab160342b49cbe2b47a6a5006b5cac09d763f168c6a5f329b7d1b87dde69542a4437b8c426890b4a5487ab43a98ef94667efc881a943b33b42c776b3f8af853fd59c2d3031fbcf541247100d22219e67094ba89791186bc8b7b536fb6438aba5275d234adc5a9ff129fa7d1b5c5757483f02980fa40882aa0c72c0ef233b0c2931f1e15cb7d528b471c50903256e54a87f8c16f02b3bb904133bf60136d603bc57c503420a8b6701aea4a3b4052334f75bf820c2ed9890bcb812b20d9031c269af9598acdeb8a52bfa7cb804627acfa20285753264f3df670dc445647c881e112b71095f109342b8799c6382723886f5b8371ee58a35fbb48022d9c107ba6fb6dc5fdbd4ff573fd5a08f656a6eb8cd20679930a31caa6a6331c4b133a6838c223ef9f769f6246" +}, +{ + "dz" : "447f6076a627bbc5ad7773fbfeb14b4ba9ac43a0f8b99fb6dcd5e452aa3c47ec20a7237801f470fcc2bd9fd7bea8322859b850f7882d362947432913dd068c01", + "pk" : "96f73135fa51010a83491b407571126d85002a60cccceb5393b459cb39b4dcf175b2134cf515c06b38cb0ea33d8c34a7283b99b6d0c9e90825159cbf4bc2a1c0f131580557f243184bbc7498b39266f669fc161150482de480ab196ba61dc526f8a46a2ae3336a7abca9e2743fd654e965b3b33ca0b9cbc8c96095d78a971a7277496a8c123967e8c204765a864890b762d34e83570a8dec5cd25333276555e7644eeb5ccf8004579c357481000ae9a930a7313468d3a8b6d5b4da4a558a7c1318da670dec758c98c5048144843096c2b781d73a9f215c2ca0481ea5aca259997c8479256841507717b7dd01cfe1755f8ac2bf1008c2c61b7bd13810787185cdf16a17c2cf00bab7eab737a641cc12ea6d8bc802e0661730628194c40a7865a3587cc2f5b0ac1d328307c55388970b96c4969a533e04b425e528c713d41821ca6cf1f5bc74e64859c49b914563ad193c626c6dc520143a755132260d5940c76e20a7f07987fa7c1a4d1283bd700c9759871f973fa6d94fd88015cffb046555b36559420bcb98ce617169465770135b15612a9884586d0232d44606632c50a9d5beb3697669c9940e1739508c360505248f501dbbbabf70e7cffb24652b782de5f4a310a7767826bc73886e60e51230068dcfdb2b3ef246f7701d65813e54d78ddbc34cc9bca025914883364c60576a5e0c5a863a17a9872b818c070647170cc46f44880d4ff46d68c4694442433c823c0ab39656b715e0443e8eab14a990c42a031ebefa6cfd54c32fe4521e218396d53c5554c60b93cf2f1cbb0062c6101686e5738896621e44b32449c297d968b16c80ac7491279dab0f84749842195aa3dabbaddc2457fc8b854752d33cb1a5499dd53725bf34bf34a68457e57e4b270fe0f07323275fb99b78aa90af27480b6440217b01867a1b7a5a5885fbcb931c524395cb11a406a492c4251f9c09e14a45e2b86a98c72f1532664879a2d5557fe9db6bcb2ab6197892e5686b2e1ab35a3434a77a65ebb6189aa00e19fbb045a03fb767866184c5c2e2b155f465bc7a135ab25cc5415b0a42aa17595a32e2a370317414913278c18837f346c3a54be5722520315332b2b43ed4089b427cc8e24f10f17610e40882b4c724c48b6315aa6f0c64a4032e4be75bb6b0702a2cb7a11cc6aa14bccfe91af25642513425ca475fd7e7c387214294a36fff09bb1388a5322910b9906491bc923a2644259086bc5131e5d67794d91f65b24a0da06ceeb63239456e6c3b1cf4fa04165879b5858bf60664aaeb45b3a238b1a926489a2d395473d3a5173fb37a51fcb5ba0c9cc3eb01debc383260b4f5033bee258f66a504e64a74fafcbd1a46076ea00a02246eae52ba6591a8ced21b58971f289847c508768dbba5ab1921c14982c9525ab4b64285723954d33c8a35396db137c0db48a39432da0abc3857c5369b236bc03ef562a8a5e4211986a385b8ab4d1745742411a9712256636e62976f99a72d75c654f8574737b6ad34c129a2eac22fe166b2682840f7043d4339bf699b68d51ecc32974c161136272f9012219bac6bfa8950c6016207dc6566d20b916974743290f0a52b8be51c9f3c239e8b6842278417a05dc789bc43fa1ee0671a51ba3301246ba780ab71295cbd20ada7a07e5593a3933604ef972a711349a0678a60d2af2434b17ee940c067bd89496c90d4b9903b9d146a49c36138dabaa405499ecdc02f791562a5d446fb358702b2a5eaec93b7f4756762b3c17b0e8d48ceb5d5244965168fd9c3e6495d1fd578ba2c168805897cd351202059b5a4b96687465741b077677583ca7411c4331583308da00ab5045ec5943beb2800b30978c31031675a84dbfcbe6d7b27b2da65152c692fb8727a485b9641888b1b36a25491ac76045792278125b0a3735f3e759901507ca4a2aa12dcbccf3c35c68873518a4fc778201f0b960c7b551f038c6201378ee101948629dae0364e38ad079320d2cc35bfbc8ae7cc446526447d60b19a36519daa8331a45f1e4308d564979a5179073130594cc5fc07a1fb6b5966277511544611e018f3f8b76567add2c94a0da8502063c66c54c3a50644e43b81a93c7cf0409b505c77f5d06d34432bec389a137b6fb9f18da05426d03477ff0b8185327c37f449c8f6398680c78ef7d26c51bba9665cf58b72cdfb115bcc2a0715b5b4f40dd01c7a0585bbae73", + "sk" : "4ccb897e841627f45dbaa7b00b670c7bb17786a89a4284047a2527c9464307c2b1d4072f357a09df72a768b752e8794218f94bf07a6d288507fad04380b13e397c80ce956e3e96a604d668530b20759438a83b35219a6cf39a44d2cb697453265ba04784501bd310560e7cb693a06944cc2ec1fc1201e5a105b239d024a41ac50103335c170684c9f03727185858506ba29c8d8c19a150bcc6d8dacc1054bd7ab4c054d390ff8484861c8c4b823d3c3b11e31cb2e4dbbc7592ca95e983aee58ef4b6ca6227a2d024ba7b383b3fa752d6c9be8cc91e6905619ea17c0a1b24d2586e91e590ba51c1672442bc9c7af0e6bece484a3b96a4d76467bfe4b199d22646fb86c74864b39a60d8ec41e7b5adc791c1fc563ff2e14ccb8228f1944cbf1aa2f4258d6fbc5ea7c46282d109b8a87cfdfc576d74263be3c866311a2ebb1ad5628e14975ea8da31b7622245330788c340e0b1094ad8c2a1a1ba14663d749013742235bbbb6045733e7e6519cd1c8593e1baad83a50003b73900bd69e6cdaee53db7a7684afa3b4566375b693c1410aab368015e12517cb04b3eb6b824767724ec7718a403e5e7178c01190c289811b716c79a846133243ff383ede452f15b7912f0b763c08de8d0a2c08b67b3b41f39b63bc7bb7601a0ac7fc03dd4a656dfc89179c34f05976be42896ffb49759222f259895dd433ed73b4e77a715127a3876849e1b039cb8a71ba4f2cc640b93986974a46c15974b7ef3b3745c3893b5327848590ac2dc44b5e032591b2acbb055f2d336abc062a1ea11388432ab2a7e402a62a4ac1ac5503ffbca57f2505a951c0ef2b2bfd36ac5e4a0ae116c189aaa95202cc280e08dfde77952bc6566513878c4077bd45fdb87520478073501818d2271324820ea038f79059c871a1b19625fb60a9e7c806dbc444fa8261c1540c890d315b1ba2bc4857445a539af555d6ce710aac7b9dc15a149d1bb356b2321112c6c530a63a9ae1d1b59dacc92e9f919f990509e7a66dd41cdedeb8252d692e3dac47db872ec36bc4513741e31a65376abe99a6d82e6110e2a5acf501e3b785088a4298639144560c6d07c3c39c9364ca56dae571abfb13bd805cfa19054e8403493f2cce7121836d01a83561d734aae163481eaf2ce8519bfbd6aaa1b29ad09f8705e8582ade2774161a2f47b03b2c995eecb024622b287e84500369ce1a71c77483d1c30653a7657f953b0503192c97528b4d92856696d256bba012bcfdbd8c3256c9969819268c40944a9015750cfc255411c196147470743609356e7ca800c2635615337b1383267bb339934c3f68dda85bb582c7bd7131f6041bb21f14aa0b25df46bcf1c6b42b1db5b604c17efd00f6b23c85a3c054c600f9c40c21d1810f6699bb8620146a4c2466cab86b1659313290d9c182da0555e417009b3ae20f6cf1fa128d86307ca75c0046c269df20f0c98342f39af8c00918f93550c668f9e6c4423f559350185494c5663ab81bce72919521baaa81680e19e38154c4e0809e64c184a9396e1dc813de849d13a7d6922cb41b2346dac86f06996f8a71d3fd09b44ca60233c9229750263e88c10264694ac305c7390e2b63d8076863865047c80088894916b54756278c6f9c0730f4abacb129842d1610db66892c52616f62cc3e26f93e22b736ca9f43c16d3826f5e324150416a8c554874d094493a135111afa6d45cf1f58a7177b242fa9e9b185eec54659c887005b702db26a05cf53dcfac6179342abbb707ea449912d9021cdc5716bb469e00baecf754cea89b36eb6b1c130f5d439b4ad903f09752effa555f182fb1c578855a44d4f9048479ae4551b61d34048ff53d911a51c547999af5aa76500ff4b8434f2043fb583e5fc5af9c73584f5065f1e465a794490a1a296bc8bd43c647e4a3283b24c4ba3301b40c462dbc20f28bbb17c1a0706a5fa084268298899f0a0fa4d36c74952fbdca323bb3adda17944ce5898b9027d876a457d066819ab43d32a9a04b2ee3378c23e6cbd25bb2b317767866406d374bcf327b1045cb96f656fae8228295156ce26dc2770ef48322972668c5c746deb4b57b37040e9aa732c79a238227723576ef822e95a6c80e6151f6523fe6db352dda9f7f613a3601b6d61719a21c3696e4c9f80500fc918d96f73135fa51010a83491b407571126d85002a60cccceb5393b459cb39b4dcf175b2134cf515c06b38cb0ea33d8c34a7283b99b6d0c9e90825159cbf4bc2a1c0f131580557f243184bbc7498b39266f669fc161150482de480ab196ba61dc526f8a46a2ae3336a7abca9e2743fd654e965b3b33ca0b9cbc8c96095d78a971a7277496a8c123967e8c204765a864890b762d34e83570a8dec5cd25333276555e7644eeb5ccf8004579c357481000ae9a930a7313468d3a8b6d5b4da4a558a7c1318da670dec758c98c5048144843096c2b781d73a9f215c2ca0481ea5aca259997c8479256841507717b7dd01cfe1755f8ac2bf1008c2c61b7bd13810787185cdf16a17c2cf00bab7eab737a641cc12ea6d8bc802e0661730628194c40a7865a3587cc2f5b0ac1d328307c55388970b96c4969a533e04b425e528c713d41821ca6cf1f5bc74e64859c49b914563ad193c626c6dc520143a755132260d5940c76e20a7f07987fa7c1a4d1283bd700c9759871f973fa6d94fd88015cffb046555b36559420bcb98ce617169465770135b15612a9884586d0232d44606632c50a9d5beb3697669c9940e1739508c360505248f501dbbbabf70e7cffb24652b782de5f4a310a7767826bc73886e60e51230068dcfdb2b3ef246f7701d65813e54d78ddbc34cc9bca025914883364c60576a5e0c5a863a17a9872b818c070647170cc46f44880d4ff46d68c4694442433c823c0ab39656b715e0443e8eab14a990c42a031ebefa6cfd54c32fe4521e218396d53c5554c60b93cf2f1cbb0062c6101686e5738896621e44b32449c297d968b16c80ac7491279dab0f84749842195aa3dabbaddc2457fc8b854752d33cb1a5499dd53725bf34bf34a68457e57e4b270fe0f07323275fb99b78aa90af27480b6440217b01867a1b7a5a5885fbcb931c524395cb11a406a492c4251f9c09e14a45e2b86a98c72f1532664879a2d5557fe9db6bcb2ab6197892e5686b2e1ab35a3434a77a65ebb6189aa00e19fbb045a03fb767866184c5c2e2b155f465bc7a135ab25cc5415b0a42aa17595a32e2a370317414913278c18837f346c3a54be5722520315332b2b43ed4089b427cc8e24f10f17610e40882b4c724c48b6315aa6f0c64a4032e4be75bb6b0702a2cb7a11cc6aa14bccfe91af25642513425ca475fd7e7c387214294a36fff09bb1388a5322910b9906491bc923a2644259086bc5131e5d67794d91f65b24a0da06ceeb63239456e6c3b1cf4fa04165879b5858bf60664aaeb45b3a238b1a926489a2d395473d3a5173fb37a51fcb5ba0c9cc3eb01debc383260b4f5033bee258f66a504e64a74fafcbd1a46076ea00a02246eae52ba6591a8ced21b58971f289847c508768dbba5ab1921c14982c9525ab4b64285723954d33c8a35396db137c0db48a39432da0abc3857c5369b236bc03ef562a8a5e4211986a385b8ab4d1745742411a9712256636e62976f99a72d75c654f8574737b6ad34c129a2eac22fe166b2682840f7043d4339bf699b68d51ecc32974c161136272f9012219bac6bfa8950c6016207dc6566d20b916974743290f0a52b8be51c9f3c239e8b6842278417a05dc789bc43fa1ee0671a51ba3301246ba780ab71295cbd20ada7a07e5593a3933604ef972a711349a0678a60d2af2434b17ee940c067bd89496c90d4b9903b9d146a49c36138dabaa405499ecdc02f791562a5d446fb358702b2a5eaec93b7f4756762b3c17b0e8d48ceb5d5244965168fd9c3e6495d1fd578ba2c168805897cd351202059b5a4b96687465741b077677583ca7411c4331583308da00ab5045ec5943beb2800b30978c31031675a84dbfcbe6d7b27b2da65152c692fb8727a485b9641888b1b36a25491ac76045792278125b0a3735f3e759901507ca4a2aa12dcbccf3c35c68873518a4fc778201f0b960c7b551f038c6201378ee101948629dae0364e38ad079320d2cc35bfbc8ae7cc446526447d60b19a36519daa8331a45f1e4308d564979a5179073130594cc5fc07a1fb6b5966277511544611e018f3f8b76567add2c94a0da8502063c66c54c3a50644e43b81a93c7cf0409b505c77f5d06d34432bec389a137b6fb9f18da05426d03477ff0b8185327c37f449c8f6398680c78ef7d26c51bba9665cf58b72cdfb115bcc2a0715b5b4f40dd01c7a0585bbae739590cca5e4b82099b66c7175c5f858851eaca730fd0c55edf9ae451e07bd366d20a7237801f470fcc2bd9fd7bea8322859b850f7882d362947432913dd068c01" +}, +{ + "dz" : "2d5df64d62cb07fe630310bb801c658dbf3d97993e68626745de39d37fbfc2b27b534537addaba4ecf14f02ab317d36cb9f0f50222ced7cf029dff8a0d3d2fd9", + "pk" : "3b37800c878b5adbbaef794f4f24abfeaa40eb1c5763fa55b7369e5be8754beba6be9319cc3a482a53ba93c417bc9a5a3030cb2a247177eb11b63a672e0039fe71735ca9cea99168d1634df2737b45324034492e1d3c74f10239564b23e39585734c86d98118dbc944dec28869ca8be7e17b39bcb0b0e34e257bc9ba42cc782078945094eb1336e516c62b00871d12c6019700b478b5db43ac419b2c7a50442d9458ba4b853d5a29ca946d64b6a6e6cb3485439abd4a9cf34b5921242ddf3611289a72efac4101b208cb7598894a9ef1ec38e34a58b2c071b3e6738138bbaf416f246072ead83b354a0832b98b551b7210095fe9323e1f75bb99905e5bd961cd778d32c1be94512a7893c062f6a66553152d1c820b8825c25938c0348a3d2206897ab903e6472193b5c2aa3f1bfb22bce88bf3723eaa8292d5446546865218d5827a5ba0da5354e2f6c81eb96cf0f28efae54935138273447a953aadf9757319e03a6ad19d7e613c2cdc7f5a3aa1891368399ab5c5337881c782bec48f9161774686204027b6fd895ed1b800db68c2d9d529156b0a8db90f107964d8f5c860737db2a3375df20b7bbc7f1ea57ab6e2a2eb44b5f8e6980d5233a0791350f4ac23210a4bbaa928273294691b7c441edac04909472e8f6714e99bb7de1076a121576eeb1d419122d4366023bb2fd66937ed940566ab07d7b480b330937c341106c3bc01f3c26eb7388ce7404222bccd7cc42e8a56909239a2968f2da3cea3c6695cbc909ee481b4c619f1e7ae6750b4d8f691d70490134ba02cfc97327c9f14db4bbfca7b4589431e0b8fb8dc61658110dcb675dd1bb46db49605c66534ca53d918aee579557e82c733a3841a7338f9947d92d4379b3a2d47469166bbc20ecc4de2f7c768a0ba4dd788cebac30eccbdfa11ccbff61328f92739e12160b83369d8466421374380a1a2c8bfd701a869b49d09644266d300493badff092390e894102028768a4592e96306130550291ecdaab48c711e8a1822cd278b80357856a739174b3da66795fa8375333554fc92298dd92b3c962bad035424f418b9b626d32b5383005564b8cbad0915a977b1c95710ae490bfd158a2c780e14c85ef92a02a2601c3538c1297772d1045bc4811e4e7893310413b4121201eba6c4db8658378fa3a6b9b919c9247c40ef39a7d564bf13a6c8ec575fc3b58f42426ae1a4944cd638bcf8336504577c65a7b75b06649802bf898fc3337ea3f783bd58bc85e33c51c91412c09d99c310ab9802ddeb4e977a640eb05a6e01984186b62f3237230b33cc4721d984382d003a4472496c163a0c23aa7527a7a98b45260794c109c3ef645fd352b778f06c6de40ae1aac577698edc053e951931e88b75619a2e3a795d9d7a015fc39978ba6832da41dfc1aa36d53351321107d33d00d934ce079f53c1ad114b622ef09fdb70888a861e8b9334610a9c2a5614325b9265219dadfb7eec92b472c87c0f0181e73c580b9ca8564bc1e3b9b70528a30d0c54bbf48b3001c46b536c51e15c4d0844fe81bc035351d919212c699a455b7f0900121a77360f4aaf09443e9031ba9286c0ef18a72a0c6afb2b380452379fc14dde6a20cae7c703b8c367bbbf4ea43df773bd6a3a4c051caeeb66a236244f7bf5a837731655a73bf6e7a3413459cbac0dde329e59fc9521fc2009e480d82711496a5871f33d0378223243137486504a209d9012574b10561fc04deed84999baa3a936a9b1234ac4c4afe451042f828cf40c49e632c6153684448154a023684af08ce13b204ac025991c5e44b63201073f22a50c935b9bc1c488aa8a704bc178ab0a752595cfe050b341a295f9b851b67a3c09010ecf297791c746ba9247df2a1be5a82cc8f904e1553b31d53710b0b0b7372b8e9c0b7c15636097316d46587e07753ba05e03f7cb3c6c78870a7ab21ca99db30217245a29fccc3ed80364ec661ea93194d472813a3cb0203b223b909c5774f2dca50e8a9753e36c33d92c278a52122a72fe389f0f962ce5d3a1d9f5c07000919e4761a07282e016854579b1c2e7c608630c6b2a6a1bd96c71392b9ef15e04f7bcee414cf5d9a6ff701c4d2586506248f4bb6bd4ea4a45fa79fd92aecdecbf20d7ad8534673832a0d6ca13c561a446aaa23539624487767e4a195dce0e2bc6a3fd1a73e918f297aa031fcd8c14925529ed33b83ae8e7ab", + "sk" : "ea9b6cf63a18d0045a6aac4003930bd833a2109bc026caa6b9a38261ecb70f9992ee3a47bb4335eb80314e699734098178c25f924444714a9348b980ac7699111856623c9d9f2b4f7da5cfd47970a149c3bb882f84146e7b8562a549ad16e447a7c154b2eccb38020b44c6119ce9663d34a646d6c31cf296f5b65ccb055cada93c272ac018902c1ec93c907bac9b7790cf5b2c129738e573c5d84734ae095801863b654b740fc216edd2064c230e6266454d064adc932428e6944c2a7951268f4310209cdba48262036921bbd35c71d8728e46b291f9e865873316d9c0525c702841c3acf3252bb36020d18238d36b245c08ac1e8a28b75c5b29a810d3c6087ed058cea97aadc75f28bc92bff3614dc04c825716f79b363e971ec215974277c02277322c1471959ca699aab4662acc7fb62120896b14a3a25151280e7741bdea18e32a72f0b267ffc7b2108094e1378b169093c007c0769213e28b9249acc9b2acb5f8e7972ffa629a5b40fbc9773e921354b31bad947c45d079da092b5c4b7c094573d1da2d378c8708d98e55061b9281c2feebbcb62a99b0c6a05291345b731788e6879de89d9756a8795839318249849bcf7e432d622a319e57c0a982a2e034be75771f06917a3193564c3231590c74eae7638449989f703c6a664736823e039a571431535af0211a1931177a4761e022bd925f76913c522b128fa54ea1a04a1f2196508a2d65106950437f13d463f1652691ab919d62118ce743440b273217acb03ccd67e16cf85265b67c8ee56a4cd757c860372ec1f01d7e61aacfc55f072423abcca70834b550a4bc8228be40bc08e723b37fe945f66018b6f4808257607a9612f9577d6bd86fcb3c149edcb7d8d28cb5fa63b72a41d42471a0f8b014f8315e1ab6a894b2dc70c71f782c00e52c3f1534d46c83b2d2bbf4b0258c919307e9470e8027e5b261bc36c33511299e1a990ac68b6a735c3cb39baf03af5b4206601a7a6c24011fd56a965190b0b675d33381e5320d03dbcdcf684f782cbc2b80791e00a0b27913001796ed9baeab103bdfe2cddcccb0395b441d72746b5c13470408530460b473466d6b8f69ac8518a3b26c9ca22d077a31a3640538cabbfc852d3159fc26730fc5af89c5b5200a7636e56f74f99953886f80b77f6e22055d51048cb4122bd525710a4ec272628cb50ce549342c314e81253e0cb2be1d779b82462085829bb2ccce74290e2018ba51d1cd08f00fe0870254f4a73fc637d0f5c6d8f56ca376690265c4b7773bdbaa0b08880da2d82e79c87402c38bd60a4c07e219aa30b3566b78ded73683fc1dbac43d033559e81364f8a0cae5096243f15b7bbc3bf7cc061fd2921b12a5feab37c8b402ff97718faa1ffe69122a658804310d9ba4555977b2cb5a97e14ac626fc4770fcc8c325b4e03472f8e62ae7c37918a48f6ecb15c0a01ae920a84b4b7113a74bbd39bd3318c2361401f1c15fb95875ffc55bce76c77c3563d302a2794b92dc800cf9f38c5809c29b4b7e0e38c340e458bb00b44d7a11594a87ca96bab666277970b569e5c21f574563da3dd139ccafaa29f8a79578a7afb0930be8f8914a17415ebcaf14d13f5a4037a960c70884b43c066698cb4a004aa9e32a4b1150a98b708e185a5b4ba09e4678290d33c13c14137a2b61e19495587190d34a2ed82aa0f9861b04e51344e4cb0eb60bad5010d635c4811006a130470459262d028fa6c383417ab81586ae5cdba777071d687c99dc9ab4ad21692d70679e0c4dae3b1243294146d6bc1bb4b8d6b6a3e8da24a27c62961ccef556359a9486db3642102c0c129224b2c035792649923010152c1503e797635905dc442db389acf6c30219e3a25538ae1e696b74576fa7997177343914f45954728499b3cc26c768a3d476ebd7120b336baeb4c65b72c8518357776c774cf48996d6ad205c092c9791e55c727bac7e916a2bbcf994c5f9c4330976b1743894dc024dba7997e33efd944405844c01235d4308c09a75548b43555a8a6ea0d212f5da6c8427862873149cb6c3ce7a07ea39af30e7a7505caf30762798e84bc7e965ef96c51899341567c1324b6b07a984cbe7aa6b56cd52702fb106b1cddaa02d50362cd12737308e3e93a45c9c0a3420c4b71167d9587a4b2188b6ca993b37800c878b5adbbaef794f4f24abfeaa40eb1c5763fa55b7369e5be8754beba6be9319cc3a482a53ba93c417bc9a5a3030cb2a247177eb11b63a672e0039fe71735ca9cea99168d1634df2737b45324034492e1d3c74f10239564b23e39585734c86d98118dbc944dec28869ca8be7e17b39bcb0b0e34e257bc9ba42cc782078945094eb1336e516c62b00871d12c6019700b478b5db43ac419b2c7a50442d9458ba4b853d5a29ca946d64b6a6e6cb3485439abd4a9cf34b5921242ddf3611289a72efac4101b208cb7598894a9ef1ec38e34a58b2c071b3e6738138bbaf416f246072ead83b354a0832b98b551b7210095fe9323e1f75bb99905e5bd961cd778d32c1be94512a7893c062f6a66553152d1c820b8825c25938c0348a3d2206897ab903e6472193b5c2aa3f1bfb22bce88bf3723eaa8292d5446546865218d5827a5ba0da5354e2f6c81eb96cf0f28efae54935138273447a953aadf9757319e03a6ad19d7e613c2cdc7f5a3aa1891368399ab5c5337881c782bec48f9161774686204027b6fd895ed1b800db68c2d9d529156b0a8db90f107964d8f5c860737db2a3375df20b7bbc7f1ea57ab6e2a2eb44b5f8e6980d5233a0791350f4ac23210a4bbaa928273294691b7c441edac04909472e8f6714e99bb7de1076a121576eeb1d419122d4366023bb2fd66937ed940566ab07d7b480b330937c341106c3bc01f3c26eb7388ce7404222bccd7cc42e8a56909239a2968f2da3cea3c6695cbc909ee481b4c619f1e7ae6750b4d8f691d70490134ba02cfc97327c9f14db4bbfca7b4589431e0b8fb8dc61658110dcb675dd1bb46db49605c66534ca53d918aee579557e82c733a3841a7338f9947d92d4379b3a2d47469166bbc20ecc4de2f7c768a0ba4dd788cebac30eccbdfa11ccbff61328f92739e12160b83369d8466421374380a1a2c8bfd701a869b49d09644266d300493badff092390e894102028768a4592e96306130550291ecdaab48c711e8a1822cd278b80357856a739174b3da66795fa8375333554fc92298dd92b3c962bad035424f418b9b626d32b5383005564b8cbad0915a977b1c95710ae490bfd158a2c780e14c85ef92a02a2601c3538c1297772d1045bc4811e4e7893310413b4121201eba6c4db8658378fa3a6b9b919c9247c40ef39a7d564bf13a6c8ec575fc3b58f42426ae1a4944cd638bcf8336504577c65a7b75b06649802bf898fc3337ea3f783bd58bc85e33c51c91412c09d99c310ab9802ddeb4e977a640eb05a6e01984186b62f3237230b33cc4721d984382d003a4472496c163a0c23aa7527a7a98b45260794c109c3ef645fd352b778f06c6de40ae1aac577698edc053e951931e88b75619a2e3a795d9d7a015fc39978ba6832da41dfc1aa36d53351321107d33d00d934ce079f53c1ad114b622ef09fdb70888a861e8b9334610a9c2a5614325b9265219dadfb7eec92b472c87c0f0181e73c580b9ca8564bc1e3b9b70528a30d0c54bbf48b3001c46b536c51e15c4d0844fe81bc035351d919212c699a455b7f0900121a77360f4aaf09443e9031ba9286c0ef18a72a0c6afb2b380452379fc14dde6a20cae7c703b8c367bbbf4ea43df773bd6a3a4c051caeeb66a236244f7bf5a837731655a73bf6e7a3413459cbac0dde329e59fc9521fc2009e480d82711496a5871f33d0378223243137486504a209d9012574b10561fc04deed84999baa3a936a9b1234ac4c4afe451042f828cf40c49e632c6153684448154a023684af08ce13b204ac025991c5e44b63201073f22a50c935b9bc1c488aa8a704bc178ab0a752595cfe050b341a295f9b851b67a3c09010ecf297791c746ba9247df2a1be5a82cc8f904e1553b31d53710b0b0b7372b8e9c0b7c15636097316d46587e07753ba05e03f7cb3c6c78870a7ab21ca99db30217245a29fccc3ed80364ec661ea93194d472813a3cb0203b223b909c5774f2dca50e8a9753e36c33d92c278a52122a72fe389f0f962ce5d3a1d9f5c07000919e4761a07282e016854579b1c2e7c608630c6b2a6a1bd96c71392b9ef15e04f7bcee414cf5d9a6ff701c4d2586506248f4bb6bd4ea4a45fa79fd92aecdecbf20d7ad8534673832a0d6ca13c561a446aaa23539624487767e4a195dce0e2bc6a3fd1a73e918f297aa031fcd8c14925529ed33b83ae8e7ab9b3999082be47443720bf6b573a95207d1eee1b3be613a1985b3d6f48dc648787b534537addaba4ecf14f02ab317d36cb9f0f50222ced7cf029dff8a0d3d2fd9" +}, +{ + "dz" : "25056d1b8113bb362dd979d98643d7a7ac9c4f95994c0ba060609b6d07002ff3f48a9254dd40b117941fa35a66bb50296327b725525deef70e128ca8045ec451", + "pk" : "96886aea374a0c4886e4185a5ad8ca7f1a7df73c6af1282397a6a9b94c95c8284a0d65c3e614cc73159fd71bbd699006d1b97da241c470aa28113a24eef9856ecbc3619bbdbc25bf1691a241414cc3a816433c6d9466037cca4dcce8851aa9a182fa9e7ecc47e42713e9f81189cb5b68b52389095544427321ac5bb12000371a1e1cd96b585223eaa02218543c6f32a777d79c3de28d13dba32818ce41d13e2eabbc3c1223eae799057c43a2977ecff4a5966a7e52d0554a8907cc39495fa80339160fce96742fe5679cd4c4648910ae0715a9899530723be9b551e404b88a1c272e72b1b3e56144a4974df799eeb20170862305e647951645de729da99bb4fe579309d4abeac03ea4d029990b3fa8464f82e4472125bfb98837e275508d161dde593b490461e6508276b344bb18b93cc3c965e084df68a68af14e6bf37b4dca585d0621a4f32263abab1684ce0b1a5fef971e8fe18928d38477572e55596e35ab6270880c2e6abd0ee9080e75850155273aa38c0bf588e02006f5837c01063360773ff79376a72380d9e123b199b561007f1873a4ddb715abc93d95c7a8549407ec94cd0b928b30e3cdb15804cad99ab2202005675e68ec6f71f70082139b42e5bf02abcd4a4988ee0a16415a095ec8b94d2431070a710d72a596e30ed4588fde91670f3ab70f35a5f0870e86927d68f641faa10f962941e0026908ea7d27084261d190cb62b4354a1c8f06ab864031341637929b1274a1c97bd62208e681f3a96333871c41916b03e668d7559fc0a67deceb0d2f818f45d82a9e4a679d76436bcbc45f1c971e966a6cfbb4e1948f2e4b0620a28d633b78951812fa15c4696a7bb17a9ddec0329e927aa1294e5b7974bbc7008a977e0e13500337cd62b281bf73920f02b19c357eb57b3c575265f1e73a16b455af856826f29be11049a7005d9aa401aff512e8f8210f296fe64ba0ee77b1734bae34000b85c609d8bcb39260690ca9b82e105746acc35fc49ba6d1461a748206361ec179990c1b2ec71387b51c1c7ed344b816008c384eba96432ed66fe4e7225c0047e2b2979bc359a891b258a2cd40ba3694086489088b42452682518ec4c1bf8b56b91519c8d02395e726ad48696d5a2809d7f3021539bbdb38bb11e823cbea2e7273742c87776457a1804b89d524acfcb39e19fa454753908813815349a872e131a5fc91c51579b3a50e9142955ac575a8a528ffb35a77a6347f119ae0fab07701cd4166a0144963ad69268bacbfdca7bb18305efd006e44f812d063b0b7e8b1fd75b5b1662a49e26324f89415a51fbea41b75485c53b661c97ab2b9e193d6f1067f518e8522a73447aa1be8af9cd722eb8653e1837279c5194eb21bc9127f1eba895f9924a254c6b38caa0907018197a771d531a506713d3434c23a3a2b996b7e11c83b97058af811e974819da2147a473686869f4d04bfcb9786a0f9723dc67e70e4ac0f565b85f4bb30ebce82b21950838a2102805550c9fc1607ab93a7e42a0c9e79611fa7829beb0254050ee730792e73975a7b38bb718ac65064ed7090471658657123e7823631e802142aa563771bc6975ce2722f0e012f555c3f021a7fedf78f51020935d01a92362dff154daafbc4ab6c8d32d2a11525a474757c690b21274b443b58458b83766df851d95214dd04bc0af73679249cde1055e1977559d26b3bb60bb306503879b7fbf0b2eb2508aef52049f43adf6275d4db027b6477d6479cfbba91ae0abf1dc8126fc962ce9921da1b0005a09c30b6894ef6b3ff79a0c088bd2d6074988ca824aa18b887073a10c7f21982f802204c220756c0bdf59ba855a63a026125bd5c677db08368b475b52c3559c3031ea56040b9590f859f6c2560f9170f5fa759068678b9e22888671cb0a693e825bafbda853c0b56b79a63aa198710b6246a4aa58b226086416d3ed82c412b282cf38c71348b40eab105ba23b2f3720ebaa6f21c9f7b23c4e324c4c3a821de7957c21183fb48c4c127732ab169f822c3003a803aaba857c6b92bb22d8c10251ee1a6838b18c650cd5b8304f886240e16c8cf4a74f14938a21a8f3e87bca0351daca3a8d5c014037ca5665a2589eb7ec6f29d18d891c0cac822792b3408617166b55cb1182341a309f86f99f86b4e7c54e6c2bcd15b15b091274f185cbf5aa7a7a8ce437adc43de798498003691147635e787ee", + "sk" : "09e4c3ac7c3e706ac8eb1a3c09ecc4c26a683a3b0141298052e81871d820b931a79e4a3292550098c93be9ac0d9539641825928d8398c1c5082550489e1aa671b936bfac883e23ce83b24122a28b20b5908b4c5d65e4c8322bcae55755892c8896d9ad6c4b78f1d616aa37c61f3b117ca77643fc65d74746b1110c6a0c6abec7131f79c62a5b90d6ca21139682165ac043d063b0d4644edcbc9746c498a55d2ccc1121996cd82769c9f388e2c37e7ea3b5e4e76da12c4121ab1aa40a5b8a045e5ef767ba1b2da22847424049e73ac213f7333a9664b836abb08650e1370d4e3693898a802896300bfa14ed3b62c8156f76f6c5573946754c95e238136f33709800c589c38e76d76d946581c554aa5d608d613b2756963a3cf512d823afd6d4afd428601a1c5c7de8c58d3727b8bbcd7a704b2b33b161536affc498e5d6ae2d1c9a3f9823dbb32664d36242185c6da03c11fb5e21905dd374641b569ba4d3096ac5833faa0641d40ded086973a49413d8596ea97c76f4838c37824db6c8b4310311501cfde747b4130c916927fce26777f7978f2a0a3c89c93439ca7e00121c5b2074f775acfc4239b0458038c90d71b45f83899c7b20bd91b1c697a12eb958f1618a2b8c5bf1a8b1fc765c7346b53f2c8dd311cbb8985d93e9184dd73eca6036b1a73abb38505744001260c21f123fb950cc550563c2e5240af922c5caa5dfda1afa84b23ae8420960ace7224954dc08001513ed63a4896c96f45824504341f8b8b84cb2979947a923e3883eeb3ce2f06ff38a7247504c8e1c6ad0b014836001e12705534847a676b2c824c04d71467a58cecfa97672069df0376db8c23d1400ce62f1a0c3a258b763a58077a1fa01510a8071dd939ac1183e3bf22f880b5102878b1317a67a874d8e211aec3a3adc921272e756ec16b4694c2e398798f2ca8d7a668ac51711329b30483828f41b2efdb9823a957d601381d2e86ab2502680f1004d67887a890336b218b2940eb60262f6c1593b500f45d18d2f081b5a956ef5b1817250452d87128ef0126b98302ebc3dac33780e260b61f30cb5c81bc6a54fcb362a64f804506c79922893e889bd6c22c16a9018b9a522749950bd5ac6129126dfb2409bd512f5106e3e757f749a5efef79a5949096b47686386159a47ae22456257093f27455c402574ffe725b59a7afe89b036e34e6190928c70b15f525daeb69c71a08f1f611dc84748ce219fa38b89b06a15f576885ea73a4f773932ea14823c404f2004c056bbf6463268a1a6192443dd06b92c8cb0d11bc9f0029d6b4c9b44304cec028c6e46ba3248b7f2912a1854a1a90229402035f1519535e53777a494e5da9ce02195d7646ca2993b38c409f6cb3c9baa7f461bac9a877cda431e1b5244ade7351274bc69353437f4cc9641111ab74e07a734b1f0be390b3421a598ab91770587af7f16cd043990d0d73af2e861b0f216b53865d42c8e8e1baa52735f684248f14b8020461d974c2f79bbab12d0717cf08d72c9a9f8f1c60b4c01362cb4c16620b6ac5604661728781e1f51cbfb7cabc24243235c1dcc19394bcb115bc2a2e6443527f7c446a3ac04c58de930b5f19a9bdbb34c61c3c79a2ba4760173cb55c5171908aea5c1e6860ca1898f51174c7ff50d92e87d989a36da409db602ac0eb8bf13655ea8e9b46956b9b80a4e97918623469d081214971b4b32c34c5bd9bc5d299eeff97629a0c8e935816e1532853952ae007a6e9224839169bff49493c13a5842aaa5b32d9257c30bf36d53870bef195dee5819e185a5db768e950986ca8092ca371863b442db96b62877bbda7179d5c009a9626c6c8537a114ccb571c714644bdc9449d070bd9b35078fd71e862aa59d57630b0b3f0b17361a05aba7b906f3d66c2a1c52da0135742c40501a15f4b269c66683038b4bcc9aa5fae69edbd765e8cc34c5b31f0f56008a04c137f9507096c1a173466a8b496e1c7165cb9631e0b039ea8bfd55374d674a9d2ba84dd29cd200600ff374fe128a8ee4ab3b824126ec3450367784d936ef927e4339cd05fc013d57341ac63530c8808ff734531c5e802161baa0697bb9b8f2545e36a2155958af41d4bc95e27a8ed5bc5a24386fb73ce97b628d972eec7703575c598b7a95f36c89586474cd413396886aea374a0c4886e4185a5ad8ca7f1a7df73c6af1282397a6a9b94c95c8284a0d65c3e614cc73159fd71bbd699006d1b97da241c470aa28113a24eef9856ecbc3619bbdbc25bf1691a241414cc3a816433c6d9466037cca4dcce8851aa9a182fa9e7ecc47e42713e9f81189cb5b68b52389095544427321ac5bb12000371a1e1cd96b585223eaa02218543c6f32a777d79c3de28d13dba32818ce41d13e2eabbc3c1223eae799057c43a2977ecff4a5966a7e52d0554a8907cc39495fa80339160fce96742fe5679cd4c4648910ae0715a9899530723be9b551e404b88a1c272e72b1b3e56144a4974df799eeb20170862305e647951645de729da99bb4fe579309d4abeac03ea4d029990b3fa8464f82e4472125bfb98837e275508d161dde593b490461e6508276b344bb18b93cc3c965e084df68a68af14e6bf37b4dca585d0621a4f32263abab1684ce0b1a5fef971e8fe18928d38477572e55596e35ab6270880c2e6abd0ee9080e75850155273aa38c0bf588e02006f5837c01063360773ff79376a72380d9e123b199b561007f1873a4ddb715abc93d95c7a8549407ec94cd0b928b30e3cdb15804cad99ab2202005675e68ec6f71f70082139b42e5bf02abcd4a4988ee0a16415a095ec8b94d2431070a710d72a596e30ed4588fde91670f3ab70f35a5f0870e86927d68f641faa10f962941e0026908ea7d27084261d190cb62b4354a1c8f06ab864031341637929b1274a1c97bd62208e681f3a96333871c41916b03e668d7559fc0a67deceb0d2f818f45d82a9e4a679d76436bcbc45f1c971e966a6cfbb4e1948f2e4b0620a28d633b78951812fa15c4696a7bb17a9ddec0329e927aa1294e5b7974bbc7008a977e0e13500337cd62b281bf73920f02b19c357eb57b3c575265f1e73a16b455af856826f29be11049a7005d9aa401aff512e8f8210f296fe64ba0ee77b1734bae34000b85c609d8bcb39260690ca9b82e105746acc35fc49ba6d1461a748206361ec179990c1b2ec71387b51c1c7ed344b816008c384eba96432ed66fe4e7225c0047e2b2979bc359a891b258a2cd40ba3694086489088b42452682518ec4c1bf8b56b91519c8d02395e726ad48696d5a2809d7f3021539bbdb38bb11e823cbea2e7273742c87776457a1804b89d524acfcb39e19fa454753908813815349a872e131a5fc91c51579b3a50e9142955ac575a8a528ffb35a77a6347f119ae0fab07701cd4166a0144963ad69268bacbfdca7bb18305efd006e44f812d063b0b7e8b1fd75b5b1662a49e26324f89415a51fbea41b75485c53b661c97ab2b9e193d6f1067f518e8522a73447aa1be8af9cd722eb8653e1837279c5194eb21bc9127f1eba895f9924a254c6b38caa0907018197a771d531a506713d3434c23a3a2b996b7e11c83b97058af811e974819da2147a473686869f4d04bfcb9786a0f9723dc67e70e4ac0f565b85f4bb30ebce82b21950838a2102805550c9fc1607ab93a7e42a0c9e79611fa7829beb0254050ee730792e73975a7b38bb718ac65064ed7090471658657123e7823631e802142aa563771bc6975ce2722f0e012f555c3f021a7fedf78f51020935d01a92362dff154daafbc4ab6c8d32d2a11525a474757c690b21274b443b58458b83766df851d95214dd04bc0af73679249cde1055e1977559d26b3bb60bb306503879b7fbf0b2eb2508aef52049f43adf6275d4db027b6477d6479cfbba91ae0abf1dc8126fc962ce9921da1b0005a09c30b6894ef6b3ff79a0c088bd2d6074988ca824aa18b887073a10c7f21982f802204c220756c0bdf59ba855a63a026125bd5c677db08368b475b52c3559c3031ea56040b9590f859f6c2560f9170f5fa759068678b9e22888671cb0a693e825bafbda853c0b56b79a63aa198710b6246a4aa58b226086416d3ed82c412b282cf38c71348b40eab105ba23b2f3720ebaa6f21c9f7b23c4e324c4c3a821de7957c21183fb48c4c127732ab169f822c3003a803aaba857c6b92bb22d8c10251ee1a6838b18c650cd5b8304f886240e16c8cf4a74f14938a21a8f3e87bca0351daca3a8d5c014037ca5665a2589eb7ec6f29d18d891c0cac822792b3408617166b55cb1182341a309f86f99f86b4e7c54e6c2bcd15b15b091274f185cbf5aa7a7a8ce437adc43de798498003691147635e787ee4e145d000a02fc34e2891d2047f787ad49b9adede43fc52fba6803172487e191f48a9254dd40b117941fa35a66bb50296327b725525deef70e128ca8045ec451" +}, +{ + "dz" : "e4d34e12982aeeb1d62fd488d9b9e28557ed3429292239fb4f76fa9098009acae6c45c7fc62329b13c8d29844405db8ff6860de474bf727ecd19e54e6e1a141b", + "pk" : "ba96bfc11884b9304cc16b669550cc08a2828dc34e704534fcc057a45b25ca8ab600372cf6f60bfd530b1e67309d5004361acacd392d104c9d3bf66075d5949ad75815bc9517f13208068ad5250595d76caebc3b188a268312353e232cbbec0830c45b44e315b4e037f66722f2c8c58d37228a7b3c81a8914de52757947eddb3a99ad35bcf1bbe82d9249d228a15009bc2521162d28f91b70ce3c05c4f027cf638053776511fd4c24e660023720370042c6bdcbee2cc853e1345268235e1e31d41106b1c359c8c4844274a42059724b1ba455e01ac4b800d79d4050c4260b862ca9e30a3cb876852997298609c19479b7ea35691ec5de9a16b09382cad755cd1a008c06b3a5d347b75a06825d4a8077cc6a61543a6e4c362e979a6824dcb494b7f510c1a3557664b8ea3d681702932ba284deaec19e83bb4eb0b4e916670c185b8effbcba3252959714462809d54049561baa71f13ae08d25fc587a01c853b32681cf1fc906fe00c2cc58971f8863b803d9752310a18303298ac6c188b46ac03e3a24486b6bab54306fb1942b908635028238622198882989f712ed3a30ef5970528bb477ee6a670d031e5dac2557655acb2c10923441a77959923bd8fe07745988efdf48bf794659bd34cd8941733f97d85178021e8b20b185e0cc47973173c15a681f4a0ab52c5c4c6f3a2364465d3c727928853a5a55998743e58695feeeb9f06c2cfaa70679c00cc6ea329c16bb4943418d90017beeb03852400b7e87d6eb8be948303e31306a4116fea8ba59d30ab6f0a5060c2aa89329306065290466508c17eaf7687c551100a18cdde6600b9e467e3fa7b10dcba2a722347349c2ed9443c401b6749225f38195c04838ce8b96ab66cc2d7235c8b0316eb7e1ab1ca956c5780fa491a7720b073beeb48b98dc41a1b276020256ae6d85aa3cb2d60e6375b44aeb6e34503fb0a73426cf999af33e89f1f2934c3438f47814d76413b87a264ffc67263e3cadbda0366f13b82d9a789d55f05a30868c6a9b7bc7ca7e69184051d9f2abff4ebcf0e26290e69c0bad83ce3ba19d71133a0d8b347e1adeebb8a8b915247689311e5378d256ffa867fba904217339976b4af06bc3e5a9093e8e45cd615cbacf65bf1b0899da61790883ebec896a095959af55d0d7b39a9611e439a26caf8c71cb05a57ca071c719a281625c2e4615cd4b74826323b163cf161bf6a0424eeb2381df549b050bfb9628461210461a9a35863bc0103c8290244c6ea5ba381c421421c91c010645ca365549c7aa09520257634442b83e5806d2a274df4b8888bca68accbb5350743443d8dcb471e25ae4b748338a922b7e11f761b059bd5848eaa441c812951729d6e7013fa98340ae9a142b84b6a98c6577369053652b3b505d4d8607737b49fe06c5ce8b40ec680838a182e34296c317df67826f4ea16f4547b4fb9cd0778b2e5c66e1e5382db0c0c432770d82a1e20f59ce1eb1cba29a1b9d8a5e2dcba6b04022bb72923591e79dc4f0616b2d4637be08558a212166a97588e128c08579859d1012088a7ef26355fb4b83849aa3ab06b886aa45b9a1824a74b05f090baa7cf2969368e6a82750160ceb0107811543ad0bd25031a285c4186719d9a30270fe1c73ac8bb64d912dff5bc324441df18ae94d03c82b63cdc9085d073063da296627a5cc754973cf296f11aae6bc102e940740c853fdf2576c24b3816e60483448d9a28c3e1b295a4e6bb36283f4706290882b52f7babe54b95772a174a4a0a3767c2f6aa992f5904350071ece661d94c868df7396c1a1588f80f78f82babe28531d97617335cb098cc530c5234dbb4db98269d60b271376a52621fa40a464bfc620cbc08b2ab0198e2bcf6912752b39caff4938b842b1519455bca30c8b15f6e2942b1c6798b584d89382abb26af5be574fe12838737091611adf21507e6803a88570d19e34331f07766d39d57f80ceaababb0ac5a29991a1189a6c9364b93a53e73c13d91c656de3038302279de8a0d45d46715d78a8c9aaa5414540d9cc6553cc910b24cc941769ca5b8c576ae8e559969720d8048291c9374913ba79ee9cc3cc217c5f1a590a7ad9bf27b365881366c2a529a85ef8b34d64792bf786964831da9a38dbd81a573b74a8247b040f60404a038846bc2a3117bbd025b0f7a7de41806de885d79e49a5eee5db12a57b1a7da55ccb00b5b", + "sk" : "0b57a478859c30104a9dac5c9c4b15ad5a2c3dd362b50c7ecf4b4f5861b60c9774994752ae90556290193f02b53fc3cefdc6864b9845185a1b99745ce6120f6df5898e8682d2484fd809106c9a01283251569a67fd8692fe202995290b6c54cde2166a8926a96864c2f1d209da830832d05275101a8791a5fa7b42fde06d7109002d580701ec45777a5cef2a961306244f540cfa4120aa146269d8b9178c34b0f9086895cf4376c10176621138ad1216bb1e0a109c0cc4da4167a5fbc7497a6663a5cc2853b347801e5401b2846b7ca0233ccc78b2b79c0da56a1854696180552a05a3cbd024668e593a65143de0a969acba37d3da4e834375f564379978121aab89f2e210934c5a5529ca121c015474afc1b805103226899967c616c482462fb588bd8e90606e440046a3593f4bc1fda596067532f340469bac9e75226b328c491411b940e27d196c872d3630e5a396bb47b38a256f6b376508e1b6ef92c15915469d2b781a8c09bb5382be765af47035a57b0bc85120cf10200f98844c410d3c077e0bf7703ad090fe58a7763c77881761fe651f1b8ca7003a99d7f4b94560b0b501241f102e93476dcdd937331b6a415317df973c2a33c98d835c19b78f548b314bc5933474132f89876c9204e2221a61f81d140083df2aba9a674b088156c99a71f14674b2daa435a85c4ca2cdf4a2588858cdede20516181e3537b1bb0060b448a306c691e93aae45240800b390e77163f25b8ca78a7868c0b738a671f3a78171a931ff164b5bfa058d481aad6245757bc47e32038ac95508878070bb6061069e2a0a1369c45daeaaa04b9766b21c354fe31635189c4516694faa2c72fcc8d15c9162ebc7bbb98b07e52c296a4087ea7eb7a0ac1233ab108c3603670d3b15ac529157356139c4dc19c5ab85c31c9b3ef4911861419f821a8d6a2a191925bb76ab9f203a2e241873b264ee980267f150b9b9b836e88fbfbb79c5fc2e738ba031d8b51439834d96c75d6017f4d404a0f41d0781986e7c72a98a2702143264b153b93b05b08b414a221eafa3a733b8ccaac737cdc6497dd07b171525730978d01b0222a54450334777a2658ca37bba60afe909896f47217f45652c1b1670c54098b962e49493239b62b17365b391112110b3f3f3b6df73008bb238fb029e46c06e488b28e0d599eed122d3350c74c168e79592de7c31f443b848051c8b8bc159d301c323ac43f24c9e06456fd19b72a1c237e25f8113047ad20b686c2541850b42c9056c68c9a95c3413f61c8a713dee849732930b71f0cd65930cdaa816fc20b8db2aa130202418f94115e2b6549a01da9183524607cfa78f787219a4c88ec0c3913882429fb16961b2a8f6b298b24b2503254d6500746352030119c5c0a153b7dc204227a641417669139abb8083f0552cd2a24e3cac82899773bb77becf49aa6faa95cc230c9db01dca7094d44269c4e9823cd17f5344bffd2c999dbc011d466eaf987eb4074a0045997bd18da0213d5805afc7278459f31151c6c81a8b54a3a6562422a4123266d66bb47a1ba3089a583e517f92d3386407a4d9849fd6197581b43c3bf0afff21b14b925954459e0348ab52b5120e140069ea1f47c97d3cc9a865f56a00b1b68190ba331a1a72d06b22847af0248a21424e8c08426e3c5f40ca61a1705fc36c3a228332c1626ff9478c3382059126c9ae101278fa968ff7c3acc43b326b9d0f7baf4f979baf542bb6d04769a05139e358150210d8bc26abb209a3e17e5b6c85a5d5861906c943c3a25bc41baa292157ba5e1998addf38b6d01cc4be39c91e8348b1b38fd8324cf413125aa0c6bfd2749ff43c8edc33e4a68b0ee9c6d5ca31b6e3c2f5a261dcc804d90a3cdf09a17881a697f52a9eeb2d81f48ef191408fa915f6ac9601f19bd4442ea74c2d99505a25b36f83000236a73de7d776b6e57f7baa41257a261e008fa4f574f8f90cd9865670b280d2ba02ba647d2eb6c7e7b1b679f85c03597764a59e51caa147c63a4d9ab99815cb716593fbc898bfa9ce15f68d938ca77ba537ef1215bf160553306279dc539cf2395c004374860e812b7035fa14a2aa711eeac5e666ac51096c5210a3b744681944a5877b917f6cbb7c58123c6372d87b12555105cd773c86249ff866a24942a758aa18ba96bfc11884b9304cc16b669550cc08a2828dc34e704534fcc057a45b25ca8ab600372cf6f60bfd530b1e67309d5004361acacd392d104c9d3bf66075d5949ad75815bc9517f13208068ad5250595d76caebc3b188a268312353e232cbbec0830c45b44e315b4e037f66722f2c8c58d37228a7b3c81a8914de52757947eddb3a99ad35bcf1bbe82d9249d228a15009bc2521162d28f91b70ce3c05c4f027cf638053776511fd4c24e660023720370042c6bdcbee2cc853e1345268235e1e31d41106b1c359c8c4844274a42059724b1ba455e01ac4b800d79d4050c4260b862ca9e30a3cb876852997298609c19479b7ea35691ec5de9a16b09382cad755cd1a008c06b3a5d347b75a06825d4a8077cc6a61543a6e4c362e979a6824dcb494b7f510c1a3557664b8ea3d681702932ba284deaec19e83bb4eb0b4e916670c185b8effbcba3252959714462809d54049561baa71f13ae08d25fc587a01c853b32681cf1fc906fe00c2cc58971f8863b803d9752310a18303298ac6c188b46ac03e3a24486b6bab54306fb1942b908635028238622198882989f712ed3a30ef5970528bb477ee6a670d031e5dac2557655acb2c10923441a77959923bd8fe07745988efdf48bf794659bd34cd8941733f97d85178021e8b20b185e0cc47973173c15a681f4a0ab52c5c4c6f3a2364465d3c727928853a5a55998743e58695feeeb9f06c2cfaa70679c00cc6ea329c16bb4943418d90017beeb03852400b7e87d6eb8be948303e31306a4116fea8ba59d30ab6f0a5060c2aa89329306065290466508c17eaf7687c551100a18cdde6600b9e467e3fa7b10dcba2a722347349c2ed9443c401b6749225f38195c04838ce8b96ab66cc2d7235c8b0316eb7e1ab1ca956c5780fa491a7720b073beeb48b98dc41a1b276020256ae6d85aa3cb2d60e6375b44aeb6e34503fb0a73426cf999af33e89f1f2934c3438f47814d76413b87a264ffc67263e3cadbda0366f13b82d9a789d55f05a30868c6a9b7bc7ca7e69184051d9f2abff4ebcf0e26290e69c0bad83ce3ba19d71133a0d8b347e1adeebb8a8b915247689311e5378d256ffa867fba904217339976b4af06bc3e5a9093e8e45cd615cbacf65bf1b0899da61790883ebec896a095959af55d0d7b39a9611e439a26caf8c71cb05a57ca071c719a281625c2e4615cd4b74826323b163cf161bf6a0424eeb2381df549b050bfb9628461210461a9a35863bc0103c8290244c6ea5ba381c421421c91c010645ca365549c7aa09520257634442b83e5806d2a274df4b8888bca68accbb5350743443d8dcb471e25ae4b748338a922b7e11f761b059bd5848eaa441c812951729d6e7013fa98340ae9a142b84b6a98c6577369053652b3b505d4d8607737b49fe06c5ce8b40ec680838a182e34296c317df67826f4ea16f4547b4fb9cd0778b2e5c66e1e5382db0c0c432770d82a1e20f59ce1eb1cba29a1b9d8a5e2dcba6b04022bb72923591e79dc4f0616b2d4637be08558a212166a97588e128c08579859d1012088a7ef26355fb4b83849aa3ab06b886aa45b9a1824a74b05f090baa7cf2969368e6a82750160ceb0107811543ad0bd25031a285c4186719d9a30270fe1c73ac8bb64d912dff5bc324441df18ae94d03c82b63cdc9085d073063da296627a5cc754973cf296f11aae6bc102e940740c853fdf2576c24b3816e60483448d9a28c3e1b295a4e6bb36283f4706290882b52f7babe54b95772a174a4a0a3767c2f6aa992f5904350071ece661d94c868df7396c1a1588f80f78f82babe28531d97617335cb098cc530c5234dbb4db98269d60b271376a52621fa40a464bfc620cbc08b2ab0198e2bcf6912752b39caff4938b842b1519455bca30c8b15f6e2942b1c6798b584d89382abb26af5be574fe12838737091611adf21507e6803a88570d19e34331f07766d39d57f80ceaababb0ac5a29991a1189a6c9364b93a53e73c13d91c656de3038302279de8a0d45d46715d78a8c9aaa5414540d9cc6553cc910b24cc941769ca5b8c576ae8e559969720d8048291c9374913ba79ee9cc3cc217c5f1a590a7ad9bf27b365881366c2a529a85ef8b34d64792bf786964831da9a38dbd81a573b74a8247b040f60404a038846bc2a3117bbd025b0f7a7de41806de885d79e49a5eee5db12a57b1a7da55ccb00b5b706781da8dd5f11267492109ea905a77270a67315eea1f5c223aa9378bfb8116e6c45c7fc62329b13c8d29844405db8ff6860de474bf727ecd19e54e6e1a141b" +}, +{ + "dz" : "cd6a99396eb3539ca663a51e42063a3a262cc1c5a5fce1566f0597b52ad9fa325a3407f591791a5db4578b5972093a95bec3b8e70c1d542c9b5c9789729f8922", + "pk" : "2626cbb144988961cd4a5b3797911772787768b796a5157c180a1264c1bc6ad588139028f9f28b3d8866b8964a5253b79ae86064b5979a0b468f87ce0ae843f34765982114bf327ff08c801a3a99af0c27c72cac48614620d373b23c01d1ebbb3331c4f0ab6cf7a03804545427547acc2a467e895d75486f23cc23c779a390026e41b56cfb04b1e22190894a3c1ee16f19017d7cd75151047618b49921c8990a580a03e1656f841e95101eacc1106f0cb94dc2789bb1a2b3591134b05e7d983736f83cdd985d160a9caa210de0813ee78b411c813fb3008742f793e337a699b3a1180c5a48e12d92b9709525858a70ced2d2c81efa2401283fbca4c4b4f1904e75ad66a894aa57cf240118c73643af435f024013d6664543888f7f30327bc65e3631a4da4b6629131ec5067ec5a8c354f94aa207b587f139fd3583b3cb51e6f7926b9a914c15928738a75c9b618b250ffdecc61061618a8038b3c65841ab3d5bf203c122723b087d4ae2604f5bb6c9013c4f38903f65248c9783db79b98b9a827d528444c26c8fe408d785530d90123d30371cf46307e1c6a81097ab96280ee058d598207e666ca0dc213fa48892c3b7d5f49bdcc894f2a8659fe882201b4eace22e1713c06d74156a6a04d84c0b29f6b53fb61773d19f5cf9394dc03ba90923d33055b5c089f43961ce810a27f0878f4a77e9d60a2a1842a0450ab7208d24cc865a6393a9820b62f96abadcc0650b171b473db3e91906720cf7ea3730435f639c1ae9fac889d76bca6602ba96b0eb98aa44136cc3a978b747acba054032d36509a7ae9dc30855b2b1699628601793062c5705c5b103344c3a77947992a2071c35f6393942dba3b8545eb9a58ded8a5407a270b676061dea1c5d490f25a05c0f82750ae6151de2bf028a28657269789733f1e4c279203e2fb837e6ab1f30c04daedb3ac2809791e8ce988a4c1754c8fdfa8be0fb8c94a240ae3b1e73ecca729b4ab04044be1b97972a1a27bb10bde4240d49a568114b938bcc050b26145598905735ba2a3198e3a375b752d8f5a84004890e25916871a34469a8cdc8b1077482f785ac3e497574aca642d74a3625ca37dac98565ab6f4c95a289a434c9ce9fe61d129c073b5cb755306d47873fb186bcb86ac00be265c320c70788bca0f462fbca6db8805986425a6437304ce48d59588489561d37b60d1f171f03ea8ab817c93ea7c3afc06447eb823e630acb4213b50793457aa8f0b9b484d5830399bc2c98a7fa452fc30713fc85ad9a7707e8343e2ed113ec436625172cd4162cb7730e5f327e9566a01df27d06b460d155c8717469a365acd5ea80b935445a6610efd3062ca954276c70a8085c42aa7f82628655f97a06c098aa7ba8a1783060fb819de027dae9256e8ccc9a72539985144830c23ddbb3a1860147bcc0edb69a0ba03bf9626c1f35a611f686cb71801e130e0cf363b795bdd9c32e82978f53083262a703f85398d0587c2cca06ce1c83ffd614d1a85d437784623814d804cc00778978e0cd3e2704d34563fc23494d84b6a4482401b009b601582bf48d7521676023439ae2c48e5b54bae0c592b64d038883a1ca9a4a843c100a58d19270f8484da82ac633c3550a1634d0a7cb8bacaa19d4500af0ae14499ebad63ca1d2afea753e762246a0834942643050b151cc9aaecb587808754e2aac15d5b2c074667766181309b113211320603499d9b2a5aca065d8c088b24482200c0eb26c3f7de8751ef56850ac8097581852873b396b05ea4c12347309c7814dc89929ea6c3f09d9bfa92bbfdd0680591a69dd855269fb77e8184ddb4aa0d3b2a7013ba06d447598e95222774badd3544b6c80c229392b0caf13a94eb3bc920fdc0ad3aaaab352554a15ad0aca4d7038c208eba4f4b181e8194e21575687e55b5af0c2551acd36824c73c950b1d9a8a76264adc88e6e220396bb1aeb6ac835f2cb3167c7f4db6bf0b6552db314bb91584b86c0d7762041075a432583f8f357a77731edc1a7ea932dfd40a8ac9c09d3a687dd530ff1ab95c4e56537dc6e82210c0d3c582049a180030acfc3790fa1b437e91e1f67262e03cb59a87485658182d1a518822f678c266ad70fc1622c5b206ab7c61510f1c920db37ee852276f1961e64614ec8167fda7091988c176e893ab163e034a7e92d569882badf4976ba648396ee00e3af7f5bdb9a417e", + "sk" : "455c59bac459203a7beb868c8477cf5ce391d9842619abc685ea791c1c905cda7d92a4cb0560c022bca55c78ca606904ce666b79366eb2a06fcd6525f6075f80a5c23e7621965292549775e9250e8f7b6f902a0f5ac93ca9fab1c843b0f71652cce35f8950cb88981b5e9c20b6c639d2486dbdf823641836e453b4f3b3732965b8b9f64ef7c0897225cd495c8d38406b3b380a70c0b499788cb22b5c6859c25590bdffd578396372c47cab57d22a02313b23966e2c2b6f84f49fe69b7bff77474b0654bbc71ab6346001b2c11f446818c041646050cf6136e037cd4cb8a69206a7bbf2c6e3d0a92b68a1e7caba00a6a70551abdcaccb618b35a3e96026b6499735bbc8b9551938680978804b1735f2dab7bcdbcc3c4cc15a73053dbc1a7ae967ec073863132da8f742c343a0b48851eda61f97d6018f7bbdbc674cf24b6290d6a7a9577745ebca38859d5a7c7d1e54cc18983d9a9530910a10ca8aae777336cc147c939622bb433ae125484d2518ca45c000d2004ba72acca4288d391103a9a9f3db703584451932a02dc46eae313f55305e5990cfb776605fd268b63306fada7a4337c51b2c2b44665b93e2a2d6709c0b08a172db7ea5410b2c252a86d2a08d1aa9126986e78a910b852a12278b1df95baeb41965d1caf6798ef097a5f7d9bd13c83b7c87aa29e4069a376668f730e1d85f693742cad56a122494f926944db6c8270407eeb7b0e3e20a56161948baa86e218dad3703d19854e5e475223476d2da9b1469531322a1c7592577d7035f144ab29a76f661803b125046e33eb230cfb194ce37a228cf251e1c7190d9c231bd5bcf65d03595b4601ef519b91232f745c8182c921d937ba8f6a75ad524ae1a84aeb61a1bd4647e7a3f43315445f7bd6db427bf309fa6e715cc1354bb3a66052a7665e53c8218b4afa57b91e9576dbb562efca278b04707d8760ab73799260ea88b10070c2ed6fa545ba8a43b306d326abf7054488702a5882c19848ac8c2397e42972260cc1cbf6b66cba994a0282784c05acdd25cf4e99f6f91086e777d3b0449aea69d85570ad3ec60923300869502f245845c43bff69b83e1ec790af2b610f7cf09c3456b81023dcaa497277fd44733fc836572b76744280aad512a94582c0a6caef92c02b81c646583ce8223183bd4303a741f6c752b8604be7b8b7a0903ae91836d39bbb1b9fb864a86636977b1ca742a99d949818b535db3ae8aa4618bc702cc4a1766411ad6fb993008a0b8ab46a0bbba563006b0fc82c5b1667fba4774f176cbd667068c7a5cb0055f2229025b3c99b890c1cb6757c14e748358d90c040f44a6dae0025fa820c5d037d48c31e11892ec496833d41e1cf226c19341fbab7fccca4b111160122755f35c43cbb75063462e3de16a4619139ed178f78686b3590009153c17d142e34175d1b4c1d2d476c0ba4f8f715f0ec862138bc70a7a919237c2344ab8a971146a013864ac6128315590c671b1e6c1fb329df06052f782a06a4a1fd8a66eda148d03f04ecf878a13e50d657167db2c57700278fcd1813884657caba453dba396005f51949619342e83b601eb1b85de358617663656ab006aac29443c4ab0696c48824db1351bf9dcac02f32fb45105151c936c48642429758979b1089c0696e039e8b4cdce179ed2b457e65b3f9d65afbaa5885a377581a2814ee1b048b10209918fda1b7e2fc4368a525626a601b621503afb0d3f883b94d1a41089c89c8c1c81880fbdb312e72983a38471a8d797b5719799a8c8482c9a99b07240438c01361a156a1bec17619a60535a745670db06b8c33b83d17f9124076409bf9130595e1322137c3deb17b6da088fe160b8345624a5612330c2042b98b13c6c2c8191772cc37623353d4dd2a9e2a156a30a7ad2c3461f6548d9282115a1b115d81293bc155881bfb49c5d16da815ce4ae5c871abc62828535cd8c4a98fd0430711b50d468715368a15680a6e0a78d088660e0364a3f279265f1556c7a711493b666f5b20be30890cbbebbb429b5c84f3f6a7cf6085e9f411656c65771806c69db98168b278f506ce4d385b95468b1e94f6b0b6dfbf77ea7c8b924c81449530161b61b1d0a3884a23c90069837a386cb06b4caf3a5bd0608d7b33dee6a25a9712db231961d73cd6d3b572626cbb144988961cd4a5b3797911772787768b796a5157c180a1264c1bc6ad588139028f9f28b3d8866b8964a5253b79ae86064b5979a0b468f87ce0ae843f34765982114bf327ff08c801a3a99af0c27c72cac48614620d373b23c01d1ebbb3331c4f0ab6cf7a03804545427547acc2a467e895d75486f23cc23c779a390026e41b56cfb04b1e22190894a3c1ee16f19017d7cd75151047618b49921c8990a580a03e1656f841e95101eacc1106f0cb94dc2789bb1a2b3591134b05e7d983736f83cdd985d160a9caa210de0813ee78b411c813fb3008742f793e337a699b3a1180c5a48e12d92b9709525858a70ced2d2c81efa2401283fbca4c4b4f1904e75ad66a894aa57cf240118c73643af435f024013d6664543888f7f30327bc65e3631a4da4b6629131ec5067ec5a8c354f94aa207b587f139fd3583b3cb51e6f7926b9a914c15928738a75c9b618b250ffdecc61061618a8038b3c65841ab3d5bf203c122723b087d4ae2604f5bb6c9013c4f38903f65248c9783db79b98b9a827d528444c26c8fe408d785530d90123d30371cf46307e1c6a81097ab96280ee058d598207e666ca0dc213fa48892c3b7d5f49bdcc894f2a8659fe882201b4eace22e1713c06d74156a6a04d84c0b29f6b53fb61773d19f5cf9394dc03ba90923d33055b5c089f43961ce810a27f0878f4a77e9d60a2a1842a0450ab7208d24cc865a6393a9820b62f96abadcc0650b171b473db3e91906720cf7ea3730435f639c1ae9fac889d76bca6602ba96b0eb98aa44136cc3a978b747acba054032d36509a7ae9dc30855b2b1699628601793062c5705c5b103344c3a77947992a2071c35f6393942dba3b8545eb9a58ded8a5407a270b676061dea1c5d490f25a05c0f82750ae6151de2bf028a28657269789733f1e4c279203e2fb837e6ab1f30c04daedb3ac2809791e8ce988a4c1754c8fdfa8be0fb8c94a240ae3b1e73ecca729b4ab04044be1b97972a1a27bb10bde4240d49a568114b938bcc050b26145598905735ba2a3198e3a375b752d8f5a84004890e25916871a34469a8cdc8b1077482f785ac3e497574aca642d74a3625ca37dac98565ab6f4c95a289a434c9ce9fe61d129c073b5cb755306d47873fb186bcb86ac00be265c320c70788bca0f462fbca6db8805986425a6437304ce48d59588489561d37b60d1f171f03ea8ab817c93ea7c3afc06447eb823e630acb4213b50793457aa8f0b9b484d5830399bc2c98a7fa452fc30713fc85ad9a7707e8343e2ed113ec436625172cd4162cb7730e5f327e9566a01df27d06b460d155c8717469a365acd5ea80b935445a6610efd3062ca954276c70a8085c42aa7f82628655f97a06c098aa7ba8a1783060fb819de027dae9256e8ccc9a72539985144830c23ddbb3a1860147bcc0edb69a0ba03bf9626c1f35a611f686cb71801e130e0cf363b795bdd9c32e82978f53083262a703f85398d0587c2cca06ce1c83ffd614d1a85d437784623814d804cc00778978e0cd3e2704d34563fc23494d84b6a4482401b009b601582bf48d7521676023439ae2c48e5b54bae0c592b64d038883a1ca9a4a843c100a58d19270f8484da82ac633c3550a1634d0a7cb8bacaa19d4500af0ae14499ebad63ca1d2afea753e762246a0834942643050b151cc9aaecb587808754e2aac15d5b2c074667766181309b113211320603499d9b2a5aca065d8c088b24482200c0eb26c3f7de8751ef56850ac8097581852873b396b05ea4c12347309c7814dc89929ea6c3f09d9bfa92bbfdd0680591a69dd855269fb77e8184ddb4aa0d3b2a7013ba06d447598e95222774badd3544b6c80c229392b0caf13a94eb3bc920fdc0ad3aaaab352554a15ad0aca4d7038c208eba4f4b181e8194e21575687e55b5af0c2551acd36824c73c950b1d9a8a76264adc88e6e220396bb1aeb6ac835f2cb3167c7f4db6bf0b6552db314bb91584b86c0d7762041075a432583f8f357a77731edc1a7ea932dfd40a8ac9c09d3a687dd530ff1ab95c4e56537dc6e82210c0d3c582049a180030acfc3790fa1b437e91e1f67262e03cb59a87485658182d1a518822f678c266ad70fc1622c5b206ab7c61510f1c920db37ee852276f1961e64614ec8167fda7091988c176e893ab163e034a7e92d569882badf4976ba648396ee00e3af7f5bdb9a417e243a93c5dc84bb3afe84c380645fad6886c5614a8735a6f718acc565905e35325a3407f591791a5db4578b5972093a95bec3b8e70c1d542c9b5c9789729f8922" +}, +{ + "dz" : "6c8c53ed6f65e6b2e324b84364e10de42d1c26a106d4d1c99eee79c78586fb55b9402bf02481ce4b27a52e87feb92c4399c7f2988d40e942e7496ad15ad2aa88", + "pk" : "032c5f6a930c1f65420b0c2bbab954ae55ca8282b1da2a61f1b111df231df1151504e9031b7b28e793109ed49d46702d25b37f58fa812f68508fe2b9efc319a1976064a648bf7a251a948b74ca3f1985c5f114033e1240bf3691238b507bf28956a52204459eae072bbe10431a56af24ac15f8b546a62c03740c16ecc8afc58871537c485ca93617a324f72991273a0549b377ac040aa12a46d366462ff7b76a429bb781922f7a5397385421424a24b366651b72c5f8870c21835e0b2949f61eb3571cdcb780db683c95e23b708889303a4b9f2b862b68a4e2614eb2d8169ecc1349d9b71b5206973487660b6e4cf544baa688202b0e8df9ae88d85115f9a183fc95265608661993839914d9926cbac8993013c59e979aa8444a54972b99257542e4adb869cf56dcb305455bfec5bcf64137b72b2a6c9b0dcc6c386ed616d6a25259ea612e89c21a170b64e379458b0abd725dc8f53a55e57604282dd474c4ab30c4218a32b4183f0df24475d01fc9f8550b0aae3990bd414561463a023445bd23c7c321dc80eff509a6155cd6b2059fca448ce05d1f0062f3c21849e38a7a90bfbf15b192265f11b5bef91a6bcd0823e2e1b414750e057583401b3a5f140ed7bbcb87bba4b1aaa1aa75a911dac26298a7b9a1830a48332f139f7a4a12a528b9486197999b5717cb8552b38f7f759becd04970eb64bb4826a5cb47bcfba7cc46ca17039f1da30dea436de4b6ab76f43c06d1a1db65a9001a1e0f510d7b4755137bb4c08a710e9a9d7fd8cb32d64152c0b85f40b9cb433ed1d7bea1821c6881309642053f993739e3bcd38951433b291ea26f0948cb2dbbacc3088d58d42de008ab581b0b3a9341ac18c28b131fd4e49964d72d65658c684472550a06e68391f8d34bc09a2f25161745c74d68681c3b333ea58c412f68b44d066e33cb7ed17253fa655603dca0de7a13c7c0c78c9630f5c57ae925ac97a823102c423d0b7a3af864c7a95885e574d570895540a3793b3cd0c73b5a21660b64577d6b146e888a113bc44d78c175aa7ee72760f3b62ed7c971ae62a3e8f08ca4ab7daa43c51a18cb72158de398326589241f07a9e78bbe0c4cbc5dc388b03a7c131c885fb63841445469c42501d198d114c31da36418985ca5d95196fa12b59599f90750e4567a76a767547baea91c6580a628c3c052c3c8bef8755238c2b31d52621ea5579b649f6328695af62aa8d28402a554941b11baf7b54ffab7bd21918a0a6d6a368516b4a04354b6a922901fb8a0e9bc9f7713b977226bd8477d5c7088b8b90afabb61d0b32de98529aaec904aeab8d0240bcf114c5e3a2a44f0043b628f03fa04addac64c918916a3031d6808104539275901c8d8cbf17741a6e185250c7eb9379de46176d0b6cb02621f97c083b8fc1dabc9a0cafa9585aa848606c9cbc58b96da5a8f414bc9a6ab4d9811cd3b3b512925bb5b352cb67f76c810b3fc79113685e85595d4c62d41633fa092c31fd3102102960a0024d1f460be791bdb0b19b6610604fa26d6423864e93493066f859b86b6c2693a899dbc36cf667ab5e4d8278371cc411abba846b780090c7023a09409cc4541b4d8784ba0f643aa62336551525b315d6fb7086ac604b2272333c071b23595ccabb5459b6307b59786731008b14ea142c89a066d5e5c502724bc384013b5544a99aa872d5b65e5100315f70091d9aae9d1aba29c18a5549d11aa195d7046ae51a864eb4d69192da8248300f985fb5742a8f0623859b2a7aa600fa835a0aa647efb62b9309ba89a9c4b7478a8a1086d6c955834223600b65a80342cdb6788f09b138456773aa8a2b175f477b800c2803867253b06b5c5296d8ca3a4c85496fd9b413383c0cbb95880545c168099926c175bb6008b1abd69505b8c782c9ee06877523802a936830c9e58145c6591c66bc56abe2804b1ac28394b9f0db695b15c560bf48ded5c54a47244daf089975065b8aabc77e4a6d1178ed5b503a4ca40c2584e878c5c15fb41307ac297da94a3ea7e204b8a4156489df3577d74186d5255156aae92f77512d0b54d1c1559b8866af41ec7db75cf658625f784ab26089a076ae52103ee3053acc22a21a2920c65c10ed64372380292293f494c2c663a87d7eab6ef126a4ef50002924497e70154426f8b9801b09ae930907e6284e384a1c6554b2bc594591397810b18d01bd3777534", + "sk" : "62d210ecf64cdf77865b40c9b663c2d30a39bc7916c4d7beb420c29dac6e3a7a1fdcac2c68a117966c2bf4e2aec3a7895cd83f0e426cf826c8d679055773798b748253f34a873824b01153566499460bbf16b41502e97bd7a4cdeae40ab2f4372c755bb0a624a220b774345d3ebb235e06afbea95669e75dcf78502f68439a485e72427345e17a845109d816c3bee592ac82c7b27902e43b31b5460e37a43a16fbc98065125109c9aef2c8f1ccbc99ea571781595fbb27b8f26f62c995afe082e46caca8929e5c48510f05b1c6a28ba5c0c652dc0ff6e20a5a3c8d19691f0a29be46246eed49b66d2398378b1b3583656cfcc1f1cba0422b2a5e474c5f7854724607cee3955e108b93585c3794cebaeb8f6e4c24b653988a84708e3bc9649394f422c25bd88ef774aa17f8bf9bf19aa64cbeb4d343eedb0bfbcc8b07330334278aa7901f8b7810a1e49a3449bbad23cd17721a52a03dae0822a4333c6896a303c26356008aa03c9f9414b47c8137bee6922ff9160ca84d9a0a11e444528004ad471598737699ead095c4991f99257981a7668dd60d97ebae26019073657409bcb8909c3247bc7973b79882009aeb701eb82bb6b568bffa379ffcf235460143ab7a4624f797ea324e16c6757072bc0e5c95166acb3f9b30ffdb46b5b720bcb55209d96f4da40faaf21e2b9b5014d049936469a63940704947e5670310178c65f9c7ba44a6a6eb5580a0174b43595933b19eab8c4d978d29bb8e7ff4b37fa1ba4dd9af62daa5ad879836849b88678bd3549238e2674963770a657c1389b023b75e8a7262e8c97a94444fcccc63f3e4c17db97c6131b721561d28146521f3afa60bb75b0491e9f22636017f7c2587e8e64a8cf4b2d0c5c2dd53322419038e239c7f60b10c66905917c2c7267303d565fa30169904159b7a2e348cb641782599787d7c63be7a536890dcc858f7a43a7080bd3593f6da1f4c5454e745cb4ce2ac2a5051e8052a3616b9dabcbac6b5c43fc3c28fe0505aa823fd324d79f0c1908c2720b37cffdb58c7e822a48b7052748a996043c31364ab3b9974560f63e00d7e06184ae0485cd649374632ffeb64ed749e1bda052ba4c0a972c679db187a345e8c055fee4c28df4537795aca7a602a243b77499146f649226f73991beb88544ac439e53c2f060952bc5fdc3648e8b850526837b2744d0e7323a97598e01690e04c63d92891c64b9b1c962541755cdd861390dab893b3adbcc04d52f0ae193b27fc948305e5787bc2c27efa77c7b6823fa700eba383c96a119d453036ea2966988acb289a324a02272a75acd3a4551562ca894bb63c6d38b6710f90537dd007b807bdc0071a88537624876d58ecca89d27757c9acde480bcbc96ca3d338f014b6da5251d9578ded5aba69b7047f88a8c75860cb652c744571591369a69ac0118209a70b2a06790baff6c35f515811e45b9b94a9d9b4add0c898037c2988858eb15bafe5a88439f67cfd537a3070a12f40394cd86afffa967a206a5ab72afedc52acc6add22ca1e0b0816d729d68d67bf1b387eaf43461a5cd28ec6fb70ccea4828a9dc6237f04681ab4cd3e9c69138b48459769e07a3f6ca684c299bf3cc95df9656df5968ce5bc91c87487a600236bc64ca9881797b626b0881903a899f945716fa32d955711f289328c66c518539dcf9b83f241347b11210e4a3dcef1516be12f9ce514c38200d8757220b30ca95b7682eb16f7a305f6580b4a764c23470bf159846e656f62da82b8db4828f7244608320f5860d02821dcb61415249779d4941a06bb88c64fb14b8fba049960c2118cc9473f66ab577a953e283732c689506b4b4c95a4ac105aa418a144b2901180876aa4128424baa807354e12631473b8e05c00d0d505ce454bd425a0a1443aaaf92ff2237bc0f7458ea72b6632a2b8b760e377ce48ea5a60e8c4daec0670102c4c747492f28f81069cd1d64345553f8cac531f23b6556010f79b623ac6a8fbfbb68176c41d3609e73c65c1006de04804a0f2222433a2d1834dc80828fb06c098565297b815889161a58c0d187454b61a1a2986ad7e07a6edf27fb4626277892bd12051a0c263e6f94cfd388e1e32ac4de308edfb070eb60dcb5887fe7ca44ba4a39ba7bfb363c98b00b60a4c7781940bb69998032c5f6a930c1f65420b0c2bbab954ae55ca8282b1da2a61f1b111df231df1151504e9031b7b28e793109ed49d46702d25b37f58fa812f68508fe2b9efc319a1976064a648bf7a251a948b74ca3f1985c5f114033e1240bf3691238b507bf28956a52204459eae072bbe10431a56af24ac15f8b546a62c03740c16ecc8afc58871537c485ca93617a324f72991273a0549b377ac040aa12a46d366462ff7b76a429bb781922f7a5397385421424a24b366651b72c5f8870c21835e0b2949f61eb3571cdcb780db683c95e23b708889303a4b9f2b862b68a4e2614eb2d8169ecc1349d9b71b5206973487660b6e4cf544baa688202b0e8df9ae88d85115f9a183fc95265608661993839914d9926cbac8993013c59e979aa8444a54972b99257542e4adb869cf56dcb305455bfec5bcf64137b72b2a6c9b0dcc6c386ed616d6a25259ea612e89c21a170b64e379458b0abd725dc8f53a55e57604282dd474c4ab30c4218a32b4183f0df24475d01fc9f8550b0aae3990bd414561463a023445bd23c7c321dc80eff509a6155cd6b2059fca448ce05d1f0062f3c21849e38a7a90bfbf15b192265f11b5bef91a6bcd0823e2e1b414750e057583401b3a5f140ed7bbcb87bba4b1aaa1aa75a911dac26298a7b9a1830a48332f139f7a4a12a528b9486197999b5717cb8552b38f7f759becd04970eb64bb4826a5cb47bcfba7cc46ca17039f1da30dea436de4b6ab76f43c06d1a1db65a9001a1e0f510d7b4755137bb4c08a710e9a9d7fd8cb32d64152c0b85f40b9cb433ed1d7bea1821c6881309642053f993739e3bcd38951433b291ea26f0948cb2dbbacc3088d58d42de008ab581b0b3a9341ac18c28b131fd4e49964d72d65658c684472550a06e68391f8d34bc09a2f25161745c74d68681c3b333ea58c412f68b44d066e33cb7ed17253fa655603dca0de7a13c7c0c78c9630f5c57ae925ac97a823102c423d0b7a3af864c7a95885e574d570895540a3793b3cd0c73b5a21660b64577d6b146e888a113bc44d78c175aa7ee72760f3b62ed7c971ae62a3e8f08ca4ab7daa43c51a18cb72158de398326589241f07a9e78bbe0c4cbc5dc388b03a7c131c885fb63841445469c42501d198d114c31da36418985ca5d95196fa12b59599f90750e4567a76a767547baea91c6580a628c3c052c3c8bef8755238c2b31d52621ea5579b649f6328695af62aa8d28402a554941b11baf7b54ffab7bd21918a0a6d6a368516b4a04354b6a922901fb8a0e9bc9f7713b977226bd8477d5c7088b8b90afabb61d0b32de98529aaec904aeab8d0240bcf114c5e3a2a44f0043b628f03fa04addac64c918916a3031d6808104539275901c8d8cbf17741a6e185250c7eb9379de46176d0b6cb02621f97c083b8fc1dabc9a0cafa9585aa848606c9cbc58b96da5a8f414bc9a6ab4d9811cd3b3b512925bb5b352cb67f76c810b3fc79113685e85595d4c62d41633fa092c31fd3102102960a0024d1f460be791bdb0b19b6610604fa26d6423864e93493066f859b86b6c2693a899dbc36cf667ab5e4d8278371cc411abba846b780090c7023a09409cc4541b4d8784ba0f643aa62336551525b315d6fb7086ac604b2272333c071b23595ccabb5459b6307b59786731008b14ea142c89a066d5e5c502724bc384013b5544a99aa872d5b65e5100315f70091d9aae9d1aba29c18a5549d11aa195d7046ae51a864eb4d69192da8248300f985fb5742a8f0623859b2a7aa600fa835a0aa647efb62b9309ba89a9c4b7478a8a1086d6c955834223600b65a80342cdb6788f09b138456773aa8a2b175f477b800c2803867253b06b5c5296d8ca3a4c85496fd9b413383c0cbb95880545c168099926c175bb6008b1abd69505b8c782c9ee06877523802a936830c9e58145c6591c66bc56abe2804b1ac28394b9f0db695b15c560bf48ded5c54a47244daf089975065b8aabc77e4a6d1178ed5b503a4ca40c2584e878c5c15fb41307ac297da94a3ea7e204b8a4156489df3577d74186d5255156aae92f77512d0b54d1c1559b8866af41ec7db75cf658625f784ab26089a076ae52103ee3053acc22a21a2920c65c10ed64372380292293f494c2c663a87d7eab6ef126a4ef50002924497e70154426f8b9801b09ae930907e6284e384a1c6554b2bc594591397810b18d01bd3777534ec53d050d5a81c049eab8f93e7768c39323dd805f12c6553c204d58cbc47d8e8b9402bf02481ce4b27a52e87feb92c4399c7f2988d40e942e7496ad15ad2aa88" +}, +{ + "dz" : "2107204cd995f1df14314d5381f8c5440f09a347502e161cffc0a2ec3dcfbc7324c3da70fe850e80aa818301d60c70f3038153866dcd5d179e22db59b8991bb4", + "pk" : "059a381bd53c19d170642535f7c56a2f6bbea8b824a81339da5945f7175d08c69784e67d5e079fec9129ee799a1860ba58485ed631cabc19ad60934c192a27f9266bef098ce2d847407826afcb0ab43057008339c534b9e19c5a3542b40a3a88d41533b346754fc09fce920ed73b2fd7048e540bc9af49247122771fec129bf133c3c3711a679353a9a0ad47c4094471aee9619eb58a3831bc60257e07d09def864638498d3a731f24a814177801ae900b5fb6cf3374320a261d57c170dab6a473c86036733e85f290c9aa4cf7b56011c61723839b1e7c629c7cb5f4e4bcd1d6c9fec583d4b78670fa7a53f65b9fd0a91cc6620a5c1129339ce2a93a66618c1ec69e584a0e9c283993268fdb1c8ec25669439472d409447b6a04cfd699d167252c29af53eb27f6c3950b456861b7ad273887bcb3b41e75bdf2962b604ba62852a92f7b192cca7391accd0ad0bb65672e66317ab82bba06766917455f7fea8af660cbf6e3103f7a60b9736bf897b3a53c9be798ac0c493911b835b4514f3e095a49a474c0c907987867cd11ae24d22d20ea24ba028f02d1b295605270c00c732b1c19658af0424f2b01b7c4b8896e6706ed564b87f21afb1208f9f85e1b40244d622a5aa461c25b0319567b7cdac03d9bcbca028ab108837150a6426138b1073c348a1de7eca92acbbc0a95aa88864d734bb90cc8b8dbdcb91c4c333ae46dfd8353c27438abab8a60572d19c5bacf6b35a50b86e80a7b9b44bc74f74b050c2d6965298d33150c63c7a15150fb66082c851637568c2e5a9952e7ad62436e8401a0545c6415a948adf1449a51779005bb08bb75fd518c2dc02ed5c0b63dbb35a37612ec44b2a04a3d3c15414c0193ef5c09aac62d1cb212bbc7bc7b380bc88a37ab103d872605ba7883cc0bc83a20b2ce28a31a3b0bec216b7b1419bca5425e255b25a86ddb5ba95900c108f036a9ba2e941a1966b225b03cb7335901e6d32613b54806c0c737984da16284ab0b4594b0734fe5c6018c047d238fea777538d49992992d1a012f4a65008554405e3c0bf8d386c2eac5e07470d4d6015de45b3f99cc1b9b6f8e459e9987b773d69e3783b520d1282b177edd9c631bb4a76052c8eaa8aa1bd62269a2b2d7a6ba35b1670d27be1eab28d1571054a67e94ab3adcca05ec609b5171a1d4ac1b3a2876e33b7218c7b1a119812479c4974575208540a0831446a7be7ae0150859ad521a0d891b7a6cb9cde236b48868c30ed26391410548eb21756c3d9efa564df5780ff7b1b1f830bfbb70ce7181df82abccc941f1d79b6db3a012d5b7ce5b7ea9ca24b387cbfc34400d47200ba07d5f82c28991b289f56361f31330245f264149c9567feb569f4e2c21cd9b80a10a1ace3804b899410d912d42a9ab68b76c2b4197ec5aba066453fce1cf04d2a315961126cc04fb63361e137a258832679865cea937cab03534746918080b1b92cd099622ea137e4d6b0b30d18ba27582775398027bc54fa09d7a23655655c491f23181816d45437be2892eb73958b56899f25b3e48874434f12a0052518f3caf11215df0bc3265d648935a68806a75617506fce900de0cb07f7686223b9990719af5252ac61a6c44a7655f54585abb4d26e2ae5192c2381009b4796c87097c2657095ae03b924653bffaaab6b9035d176fb34184e58227a64059f54b44fe62a68c7a0e798362de1966db1a982ec3af25ec20f3824cafdb53cb526f055bcabe72a9e807079046b57eec2f681ac8ebcc0734a71ec65224e4a80244340ea1d339e44c7e2c5717208a034e9a6791888c9968987e710fde215207eab3f38aa49195190a885fe75074e17920ea64b6fa077336aab211fbb757880dbe36247299bb8f65c132e48c54d47eccc7aa124547c910831bd98b07bb1f435ab7c96a4cb9b46b36b6b667da4eb7cb2a12f1bbfa88b98f3c6c3704be3f000f65562d7d4c4977ac8c98ac44958c28f65280ae68466f6b7495650cde4aaac4c68e07767d09f44917b29df63352dcd76c1e393e0d5067c76855a989b04547a625762c730624835a6636191c83d3836bf74593839a83847aff3bcb3ab169f65000c6aab1df08994e161861498fa2e42d1203786300adb060a9c2429bc7325eca24279404ac3c934ebed4991502bd669309e7a76cf09507b31fbf659deb7bb881f5358d70595c01fbc7ae7183540b7883122d67ba", + "sk" : "08d1b85a3b6262a96eb593935cf9aa02b2738496441be27303da5e8a5badb4c23fd7c2873c28429c7778a3f41c430786dcc92e41d41ab97028fdd1a87914190b210a0a108c74c86597f280ae4195b39a00d7a35a210b80d15c1aa54945887634e7db73de2945355227b86970bdb0abfb8baaaca1be8f4382e36c0c3bb972f68a5d7e089ed430c977d4836e3a18116584e1c860c99277c00b51e6480bd78004ad660bd0002fbc4b04eec53def499da022741d96ba4277a2ddf1ae2d309cc9cc3c76c28baf0180b03b4d5751572c2253e5e033114a81580b960059b6cda77a06d990d2fa285d7694036b3c714acd7c80a6e7a28d8ba01075b65772e65843e679702879e4d77fa61a7018da1d14b6664b0133506bae1840a6f2ec8897eb72e22874ce275ec4a81dc1714343d31a0e99cbcd497dfe5376d8e3caf40683f7491f1fb85ef9a43587e07d21196161b831b0020c643845fbb26101389ffc83c88de29def6b550b683d374c26883c4807b51a23110ef6b8c16ec95e0dc03f7fb6a8ea09a83cc4a82ff4c7e407271acc2fb3943a3b0a1571d1c060d80977770d0bc17ed94679381984ddd7460f782a8a596646a49c48e59b0890a99768740f1c66d58a7dd7f88f27dc4f41b28db4bc240aca187371110ed39871ccaae2972653db394312793458208a29ce6a676498a100a5199ec642853e4661247b0fcf60a218f424a6831eb2488300542f1f354863db3e32878758d21fea35b06c79787851a61da1786bc45008085e87eaa72623cb41a28200ed0b4cb86e77f510f4507c6c321891d455842750e933967890ae10e91b0eb5b23789ce5da58ee120b965d20765830f9c4079a64848708a51d1826ca3425e0ea31727107c2ad28d1e8b0a6559094cd5c000c271e70b98949359be468307526f683a32df61aba0821efdc289aa273a9166abfb4abdb6c0a66cd444f349c8c2015ccf5cb3f72a561cc37bfc210f8ee4b0b89873b67506766383d279a2f1d28077e91f6b4ac289d3bc3934766af53d2f238ea8227e9e9226b4f7a8c47b8fc5874dd30c51a1d61235bbb5ddc7b22511a776359ee18842e5b8341ce045f6cc9ea6922a0bac7db004217c0c234b52c53a33c03c8b1990f29fb2816d7aaca9f633495ed0aeeeb112f180b2d740b550550d8fa56b9ee659420a3575ac40c3d2041e01be4e58824b2bc85685a5bfc7289494175b81626c7b88530bd031c68cae15a76c510310b161229cac449ba38809be3446734a84080473c80a58c3e1a56ae49b2ee802a896c3c051d92ee2bc7dd9478e5954ab98202a2403ce6bb3660e20c4de2c54289963f2cbcb692349a8a7b6676413105923c6c30a557c958ae16c03d7817a963230692ca16cc8cde66a8b0a01b0d63b58d76b7d76b078db1351931f0c23673c275a9fa87fed1a758b9302d8e65567ca508452b3068a9f3eccbf53f44cead8103c3b0d5df16d605b7ff9296434692b2a8c079be8659cf507e8d59663e6116ac03b43f54528427176a354420212f9208abbf933679c9c302c39fbf777bdb21c197065fada38b9797586e61327565e40113cf5980a32936b57ab0719a837d2a394372230d9f03a9aac0c8cb6c5491c7ea371bb17740bc76b851d77488c3b4c21d9c510b49971e11874ba9c46e3af7b555163339b3c739e4349291e931bb2c9cd86fc44f0e1911c08864cf3bb74b3484f0a7a347ca8fa335c58a2ac4687a33787c1b49b791c026c7d4b1adcf13b4c7a51e705c1ae114e527690b2713234d089fc35b880027215784d27e50e6a513598ea7a47bbb574a31d872c3549d307850b80dfe04350b814a297340fec56662c7131d99ae573800d0669ba2b8570119d69f30de12535cf05acd9e8b66215b6d2979ea7a64c25941c69c61400a62af40412fbeb1870319b37bc75d9292e2e6a76659c87e22cbd01fab946f1c855bca6d3d052ce42659c8c98d53674c83800d1776279a494c44617c281631dc9a338545f14fc1b7b7b407944786f8c25f69ab5e50c5d4d6315505c5cf03bc23b454d2427501a13c813cc11cc76681b90264121aea8594bf087b474d821ea102c7014a796429a05d38a1a4b8e6ef8504591bee10a3a7fba19c9d8122c4c66503462b3a14e99144257203f76ca484fec606ca158a8e29d944760059a381bd53c19d170642535f7c56a2f6bbea8b824a81339da5945f7175d08c69784e67d5e079fec9129ee799a1860ba58485ed631cabc19ad60934c192a27f9266bef098ce2d847407826afcb0ab43057008339c534b9e19c5a3542b40a3a88d41533b346754fc09fce920ed73b2fd7048e540bc9af49247122771fec129bf133c3c3711a679353a9a0ad47c4094471aee9619eb58a3831bc60257e07d09def864638498d3a731f24a814177801ae900b5fb6cf3374320a261d57c170dab6a473c86036733e85f290c9aa4cf7b56011c61723839b1e7c629c7cb5f4e4bcd1d6c9fec583d4b78670fa7a53f65b9fd0a91cc6620a5c1129339ce2a93a66618c1ec69e584a0e9c283993268fdb1c8ec25669439472d409447b6a04cfd699d167252c29af53eb27f6c3950b456861b7ad273887bcb3b41e75bdf2962b604ba62852a92f7b192cca7391accd0ad0bb65672e66317ab82bba06766917455f7fea8af660cbf6e3103f7a60b9736bf897b3a53c9be798ac0c493911b835b4514f3e095a49a474c0c907987867cd11ae24d22d20ea24ba028f02d1b295605270c00c732b1c19658af0424f2b01b7c4b8896e6706ed564b87f21afb1208f9f85e1b40244d622a5aa461c25b0319567b7cdac03d9bcbca028ab108837150a6426138b1073c348a1de7eca92acbbc0a95aa88864d734bb90cc8b8dbdcb91c4c333ae46dfd8353c27438abab8a60572d19c5bacf6b35a50b86e80a7b9b44bc74f74b050c2d6965298d33150c63c7a15150fb66082c851637568c2e5a9952e7ad62436e8401a0545c6415a948adf1449a51779005bb08bb75fd518c2dc02ed5c0b63dbb35a37612ec44b2a04a3d3c15414c0193ef5c09aac62d1cb212bbc7bc7b380bc88a37ab103d872605ba7883cc0bc83a20b2ce28a31a3b0bec216b7b1419bca5425e255b25a86ddb5ba95900c108f036a9ba2e941a1966b225b03cb7335901e6d32613b54806c0c737984da16284ab0b4594b0734fe5c6018c047d238fea777538d49992992d1a012f4a65008554405e3c0bf8d386c2eac5e07470d4d6015de45b3f99cc1b9b6f8e459e9987b773d69e3783b520d1282b177edd9c631bb4a76052c8eaa8aa1bd62269a2b2d7a6ba35b1670d27be1eab28d1571054a67e94ab3adcca05ec609b5171a1d4ac1b3a2876e33b7218c7b1a119812479c4974575208540a0831446a7be7ae0150859ad521a0d891b7a6cb9cde236b48868c30ed26391410548eb21756c3d9efa564df5780ff7b1b1f830bfbb70ce7181df82abccc941f1d79b6db3a012d5b7ce5b7ea9ca24b387cbfc34400d47200ba07d5f82c28991b289f56361f31330245f264149c9567feb569f4e2c21cd9b80a10a1ace3804b899410d912d42a9ab68b76c2b4197ec5aba066453fce1cf04d2a315961126cc04fb63361e137a258832679865cea937cab03534746918080b1b92cd099622ea137e4d6b0b30d18ba27582775398027bc54fa09d7a23655655c491f23181816d45437be2892eb73958b56899f25b3e48874434f12a0052518f3caf11215df0bc3265d648935a68806a75617506fce900de0cb07f7686223b9990719af5252ac61a6c44a7655f54585abb4d26e2ae5192c2381009b4796c87097c2657095ae03b924653bffaaab6b9035d176fb34184e58227a64059f54b44fe62a68c7a0e798362de1966db1a982ec3af25ec20f3824cafdb53cb526f055bcabe72a9e807079046b57eec2f681ac8ebcc0734a71ec65224e4a80244340ea1d339e44c7e2c5717208a034e9a6791888c9968987e710fde215207eab3f38aa49195190a885fe75074e17920ea64b6fa077336aab211fbb757880dbe36247299bb8f65c132e48c54d47eccc7aa124547c910831bd98b07bb1f435ab7c96a4cb9b46b36b6b667da4eb7cb2a12f1bbfa88b98f3c6c3704be3f000f65562d7d4c4977ac8c98ac44958c28f65280ae68466f6b7495650cde4aaac4c68e07767d09f44917b29df63352dcd76c1e393e0d5067c76855a989b04547a625762c730624835a6636191c83d3836bf74593839a83847aff3bcb3ab169f65000c6aab1df08994e161861498fa2e42d1203786300adb060a9c2429bc7325eca24279404ac3c934ebed4991502bd669309e7a76cf09507b31fbf659deb7bb881f5358d70595c01fbc7ae7183540b7883122d67bafbeea6f8085943992ed8b051cf758a8b8166c1a1e5f818f0deb30fa1fa06190424c3da70fe850e80aa818301d60c70f3038153866dcd5d179e22db59b8991bb4" +}, +{ + "dz" : "63a925685a8ac5bbd918faa33ac397d1ffbcf99135d9da7c3d6ff7aa4c50af3d3afdb8a246a56ee71465591831c371f2eb87467b0559dedd776ba063ee6d2f93", + "pk" : "128a170837c0c51758a801316881c56d436839e5778e79553d97c6c48587bac980e17632f7c7af3de5a9b15ca6d33626254a9e83009442289274a4c860f42c86d8060b2821c873aa5cbccde4540a8e5a6784ac15e6b30cc71a8de57a83bc5924d0117bbfbace8ad5cdfeca785eb224baf8361eb64c81453fdeb54e4e86ab4a397ed6e84b9ba73a0c4b8b606318ccdace61b70df22c4518f463d8342ba6faa846eb55284995f36a7467385bc8b77689807ef511122d12066e12619e37c8ad0872d5710083a2b9dc7107c955623cb209139034c9b3c6cfb7b3133502621662a61bb63b9c3a4586c2201516ee6c3f2d25026f932fc13c5426d64093cbc768985fb8f70b6871755f8811c60a4317a21ed8b5a7e51c1784b562c2a244065451e22935ba9c3ca6a63dc945ca37489e317abbb02c9e87b6b7092b1b4049c603f087d3596169baa2c6e3a778e61ac5f04962b61aff07a70ea72800a0143e9c43f2972908a27e0f3b627bf14841693613711115bc19659c5b3db6bc19ab7be40c24d5887d93e6b7d31899771244c756790ee881fd605d1383409d608fc1a10d6f2511ce815361a66db6244bffe1b61a46a888a06f3260409239abbb9c717d76ac4d658e728977c9f09bae86105d796f0bfc4b87385efcc791aba5169c679dabe34e1ee44ea66ab3d58724c3e7099bd80a9d52cca8ba95f9699c3ad8c90199a3b9613cf9652a79cbb93c8c949dfb0a6a7a1fc5e4a6032247b7885b3843a7af4c7bd49068228875a002321530bc6b5076d0853be448a8a85a8be09b94e5d65d3bc2194a977396d71924bc5b420aa6283b7ed9ac822c27641c811777a8550168468892987e936488d71c9af0a8732b6ac23acc23c2bf8719be59b23aa96110ff02af63858b7405482d684848d83fbf3b317217be6bb750cae74df77a8dfd32539e8964b764a100688301ac20a95306163ca391d33052e7488cf27d4da5be786caf99e294ba1782d462c446613a15f97e9f5632c524cbc0430382e828560315e6bac00b35c084740dbf159809849f8e104eaa28abd5f6978f071d53279c4689c77c43c0b649b8aa042a9c8ca968f28c81c211f8bca19269a9d79985478707489caf7690b529b988471b12523405db659014138d9a6133171c68961a327099477759261c523f9ba6a008d3c14b0a02295902637912bf1230a8b763ae397f805c2cfb4228776443645274f5c01515986cdba31285f9c72fe7634c0b44a42150b1dc75d8cc512d503b3ef7487371b70d50b9650360f073936398356cc3419f1225a3946a61bb38b2e61f0ef85d1686a29e56192d8a26d42a22f274811dfa1c1c4cbfec8323880523288805ac98000944b667346e173611fcdc3d474b0c30b0620f69b3d45321d9c91a130cb6842659a6a0904ba598ab706336417e17607e865328ccb035bd0646b023c3545c2b437463cffa14dbd86ee12b8ec24375f5b4a3a0548eb9997030ac092a579bcb6a0a984c9f354312931c653242678e98502a519d15e64597fc224101cd9462ace9ba56c421b692668976b3a170d88c4501147e6c68ede8a29fd4951d32ac9dc06f700cbe9b536a476736b1eab14e2493c5a94a07f6ab5a323ec3e9b9f639258275523fd32071739b585b5d8657aa502262700998f0c5ba71974c35573f14c13a70842149c077624737e5a06d52863d63f815d57acb4f0142c9167d2784365ed78c9f6b235c7368f2b26dad962e05f2279ceb44784901dbe87e413a04f462b4395b5e2264784c2ba356935dc1ab3c104b6be09b08941a02512055a1d70ecdc281e09c78214a0e57f2ce035947229181b943c5380b7e6f804fbc815a1f3023e4aab03fb4b0e2c459f58c348249adc6b4a5474622c3262b11814acfa872bb6c79b3614e3ad2a1516a0b0dec98f863cac0b061670ccd8d0c6f7eeccdac933bad47cecedac3a5231ef1c040aef8bc53025e0dfbb3d5c6cb2ae96f11a05dcf8885aee9756a13ca0c1280c4d331d50b850b6c00999360dc585e1d849114b13f3849b361f7083b5b3db470796f5761f7641a89189c748b4f6b88822ec85b04228f04a669c495af4c091b54a3835b379201d9c7273557f73c1e357588b68baf3e2a5c88ab0e9e057cdae06ce672c84b2a04503372c0f370d114ae10f97052fb3ba450d323fd3bb1b887fc4da6dbfef06ba5a2d5344feede346d1f04ad60895ab5", + "sk" : "59985866133caf531409205b859b9783cc2cffb66f52973ff226822187c58234ae920a4cd64665e6e60ac668a793052eb07981fd99c6592090e2286f0c405308970ddf93857e1c8f202173aa886fb54c242ee64167e9188c797888d1ca74604edf6a21f38a8787b5ca07b49a7c491c240050d8eb234d891a3e120165bc1bdb1800b7b32c254900f9e36e40cb55b4d2b366d99f1c86304f6a970941bec4d48905b33fc44564fdccacd60993352a215daab12a93417d51a3db6c9aa1a0c9a7d7b4a2ea121cf483090bb855048cbb6c4051140744919e4bc651b5007e8f3893c6ab6d745334918a2407a75557ec6b2db1cbd819509958c255776158f4ab1be64e3e431efe786c8c941ad91936f1e37ee396b8609b4e0781ce842c312b1ca70ca80690773455421d50f49401a16fbf47192ca7649e3989e0546a662a84e1904d82133dd2fb83ceb959f33c3e9d46b69a107eb133be1297749386ba7cdbadeec0508256b126f801138a17a0488cccea64a0238384ba53aec7b342c247257c5fcea471d6123c942b312b486438351ac4b5306c6699bd868087348de8f22f7f714ba3b74ba9b9c63a9098e45c1e37f2a4db9c5b9a8a9f662a2f3fb1bdcd48caaf1b5f01574db0712a34429a87690639fc148f984434ba7e35173f924a60dd70208d74443921ae4805b03c77bc48bb7b3b0964e9c743d02801b7a727025a79104c8eedfb80df6552f7038a373283d7a38b6ce430dd8b46ce067d0b699ee27b1690538541d28742a125bd2bc801a660410492707abc70725661f16b9ea10e7fba2da2d256962887c2a12d282907220456ce8a82ec163a54c97f4b7a9392d004a64731ca6b883c94a836e0539db41e36d9471cf13c0cf343ad250d05a26966898505a161a5910132d747fca047b5489a32245868778a68041b6b7870b0730afca761e640059d200f7a8948294991e6954e48f41e5f039072337aa5f2b3ec4bc2f1f12eace4ba397230861773ef628d3f13654352adfcc7c1e91510e22a4d0ad799c94a889562145f1372ab85bae981023458ad1bb9859a701af2c2149803058f435b4bc18e8a62c68c355c8b8450dfdb345d47a2585382e13c7d2f9a8adafc4643f642d4a463abb34c25341545816c169527641a63d85c0180d74a09b070b182bf0921ac8f59c5dc194ef8b93a0235cad649b781c58037e6153128bca0699d0b9494db44407f5455cb013d1a9073de80a128e04cecbc639c64898d022f3c0b514408c8035cbca60c4eade1bc5e9873ef1612890c0a253a6c34f0cf9f9cc8afe65737523cb83a90de44847102ce96956cdc988448f7134ac791fa44c0bf760e07b05482fa1443e72505e1b2e4e73f6bb775c3a1072bd62452d7994056101a63467da7511572142dd703aebb4bc4723988c334f4f71baaaa8ecc764abfa43273eba82b46b53f2b0f59f88cd2d113e49b52fc740ea0a5026be88739aac300e2810379027ca3b5467413b3484578062aa6b01fa91186bae66d3994cd41c191cae212a546354c7bc22d169dee7132a8c53fb6dbc4e81ab5cff448f5e7acd9c5bdec7c61b14a8671e45305341a4b8416798138a475154000b1424b4c2579a630a0968dfb7595c92c42292c5798b6ce4693c7566877e2725dbb5871c51fde7b2022f28674d11d5c86c0a1874099fc192af6b4cdc50843131c232c59e6e48a21dc1b8926b40375b6eadc7f11a8713e08c0a15220001469da3a84a8a802b2737e596bacaf674c29d72fb1d463286cc3916b064e076d53058a5f86118506cd99e8372996a8e32a36ceb31163694bbada95e9c36f02851d379a3522f638f737723f2b840663a60d2a8e25d49dfa6670b997b361394e9db653b269c352e5135adc008ba82cbae431f6440c8ad9774c181dc0c07b0e0a326758bc536cb94c0c4d3e5490b6f7158c93a1b93915cd70bbc78631d9d8a34bb2c383ca2e1a59859c51306a50b8da12c41467c6a89cb6e4506d1da5177b2b443c644777a74e96f65913589582a8c7abd99876f48efe540cfca7a88bbbc7784c2815fa82d3f17645fa632017c4004a5846503c9bd629850438d964892d0208b67903ddfc5476e50967a665b4b90abe8795c7a234b2759826f9b1ab846d5f763007fc93107b1efdc7a2876488b19554d4d3a9f08b82128a170837c0c51758a801316881c56d436839e5778e79553d97c6c48587bac980e17632f7c7af3de5a9b15ca6d33626254a9e83009442289274a4c860f42c86d8060b2821c873aa5cbccde4540a8e5a6784ac15e6b30cc71a8de57a83bc5924d0117bbfbace8ad5cdfeca785eb224baf8361eb64c81453fdeb54e4e86ab4a397ed6e84b9ba73a0c4b8b606318ccdace61b70df22c4518f463d8342ba6faa846eb55284995f36a7467385bc8b77689807ef511122d12066e12619e37c8ad0872d5710083a2b9dc7107c955623cb209139034c9b3c6cfb7b3133502621662a61bb63b9c3a4586c2201516ee6c3f2d25026f932fc13c5426d64093cbc768985fb8f70b6871755f8811c60a4317a21ed8b5a7e51c1784b562c2a244065451e22935ba9c3ca6a63dc945ca37489e317abbb02c9e87b6b7092b1b4049c603f087d3596169baa2c6e3a778e61ac5f04962b61aff07a70ea72800a0143e9c43f2972908a27e0f3b627bf14841693613711115bc19659c5b3db6bc19ab7be40c24d5887d93e6b7d31899771244c756790ee881fd605d1383409d608fc1a10d6f2511ce815361a66db6244bffe1b61a46a888a06f3260409239abbb9c717d76ac4d658e728977c9f09bae86105d796f0bfc4b87385efcc791aba5169c679dabe34e1ee44ea66ab3d58724c3e7099bd80a9d52cca8ba95f9699c3ad8c90199a3b9613cf9652a79cbb93c8c949dfb0a6a7a1fc5e4a6032247b7885b3843a7af4c7bd49068228875a002321530bc6b5076d0853be448a8a85a8be09b94e5d65d3bc2194a977396d71924bc5b420aa6283b7ed9ac822c27641c811777a8550168468892987e936488d71c9af0a8732b6ac23acc23c2bf8719be59b23aa96110ff02af63858b7405482d684848d83fbf3b317217be6bb750cae74df77a8dfd32539e8964b764a100688301ac20a95306163ca391d33052e7488cf27d4da5be786caf99e294ba1782d462c446613a15f97e9f5632c524cbc0430382e828560315e6bac00b35c084740dbf159809849f8e104eaa28abd5f6978f071d53279c4689c77c43c0b649b8aa042a9c8ca968f28c81c211f8bca19269a9d79985478707489caf7690b529b988471b12523405db659014138d9a6133171c68961a327099477759261c523f9ba6a008d3c14b0a02295902637912bf1230a8b763ae397f805c2cfb4228776443645274f5c01515986cdba31285f9c72fe7634c0b44a42150b1dc75d8cc512d503b3ef7487371b70d50b9650360f073936398356cc3419f1225a3946a61bb38b2e61f0ef85d1686a29e56192d8a26d42a22f274811dfa1c1c4cbfec8323880523288805ac98000944b667346e173611fcdc3d474b0c30b0620f69b3d45321d9c91a130cb6842659a6a0904ba598ab706336417e17607e865328ccb035bd0646b023c3545c2b437463cffa14dbd86ee12b8ec24375f5b4a3a0548eb9997030ac092a579bcb6a0a984c9f354312931c653242678e98502a519d15e64597fc224101cd9462ace9ba56c421b692668976b3a170d88c4501147e6c68ede8a29fd4951d32ac9dc06f700cbe9b536a476736b1eab14e2493c5a94a07f6ab5a323ec3e9b9f639258275523fd32071739b585b5d8657aa502262700998f0c5ba71974c35573f14c13a70842149c077624737e5a06d52863d63f815d57acb4f0142c9167d2784365ed78c9f6b235c7368f2b26dad962e05f2279ceb44784901dbe87e413a04f462b4395b5e2264784c2ba356935dc1ab3c104b6be09b08941a02512055a1d70ecdc281e09c78214a0e57f2ce035947229181b943c5380b7e6f804fbc815a1f3023e4aab03fb4b0e2c459f58c348249adc6b4a5474622c3262b11814acfa872bb6c79b3614e3ad2a1516a0b0dec98f863cac0b061670ccd8d0c6f7eeccdac933bad47cecedac3a5231ef1c040aef8bc53025e0dfbb3d5c6cb2ae96f11a05dcf8885aee9756a13ca0c1280c4d331d50b850b6c00999360dc585e1d849114b13f3849b361f7083b5b3db470796f5761f7641a89189c748b4f6b88822ec85b04228f04a669c495af4c091b54a3835b379201d9c7273557f73c1e357588b68baf3e2a5c88ab0e9e057cdae06ce672c84b2a04503372c0f370d114ae10f97052fb3ba450d323fd3bb1b887fc4da6dbfef06ba5a2d5344feede346d1f04ad60895ab5aaa698c34e1b3b6ef69049a883160c66533c8a65249aa35006f003d4eb4350a43afdb8a246a56ee71465591831c371f2eb87467b0559dedd776ba063ee6d2f93" +}, +{ + "dz" : "6a1aee5e708c1b47f02bdacce4f56c860f74fc7cfec1ef3b58285b1c8ad7fec2230e05b7114ff0395cc6634db1eae8258072d09c09f291e92d6620b177dc50d7", + "pk" : "2ce082fee023e6c49fe0381cf056ac1bdc95895271f4e245bdc98ee3a87f651191832b224b3c5528562f9498979c4485c3206eee0a6f5cba8fdaa70dec105bedc40e4c6b667d1739c8580f2d246371f415411c803ae0b52f0b5a6cda5fc3340f1bfa10bb29accf402d6f06472c14cc52556e5a97b56c190eabe6817985cc346baa02c76afbb6b6dfe33f711c78896a529656b4abe25516e448bcb41dbabc340ef4b483b750b0180f68ec0020271a0e9b9f466a4728c19bdaa426fb82294ca00261cc0c3349b75d397674644ae5ca363774abe8a290240abe4039a7e124cc894657c9025e1534b91b896eefd3af2d559da9f8558fa7774708a7fd535580545bc68c9cc89ccdbcc78ed5203ffb653965e7b0920574b7907443b9931472cf19c17dd18ab87842c853462366646881592ec3f5cab67b7e768472a08a43681120f491bcde05a9805c6787b96ecccb05d7d944fc858b5ec3828859234da88d8d00542b104883e824e7b630267111e49b1bb5e4103ea9ac2b187e046b4cd109709fca26af813440f30318dbbc34598ee5dc2806794c4e0a8c6b9c2310c34636088da92147d6b32a7bb447f50b898c5a3e5cb43d6e3c147ad085652ab9edda72f25b7bf250ac84d1288fc188ba645d88333b65b1150722334b5616429b608a0c93d0d946c15576c82093e0b263bb521d9fda997a461f1ee47098861feeb8b557b4656cbac57dc61fa9510bc1c95726b561a1ca4000f28a5720c42eb932f1ca8fc9b647d3740117ebca3d5587816bb48cfc1cb4e9caeb7834e1814a7c478fa052640af253371242da9575c2a66bd01c5fca4b958ea437e6474301069d0ddb254bc4603d3ba5b7415a96e5327743662caa7e08f608be974341b70db77a850b2c11e3b4cc6525808238cb097611e77cc449f17c63da122966394e79518fb6022ec470e8c5082a945c73b52f05c38e2dc3419af4080e890a6e819bb1b301046057e548894f511989a40e854aafb62ace7e586793921e292cc8601181599977d9fa457aa2039b14488d5698a8f03df1b56479f9109ad105b028219b3c90adac962369ac1f0043373bc243286c24f599de3a28684524988198971c1f88419ca09b3e4f22b64a221df8d32afdb0572ba62c7387235ee2752903535c9c912ae30c9151a3b6c415d59a4969cc432d088196f22c518037044236eb441438acb6bb61ca45c947ab98a53b44c48119135f776f2aa4a8413a1142cc4eed8c2948f8ca5db39388dbcc15c12d13035763a57c523b99a1912d0fd29b952776eb03aeed697320c66c0f65b369e13c7eab1e98b281e7b17cc2cb9ceab725671bb5df0933eb5c70a3d39e0eb5a55cc20af912af87cc23e10ab77a9c9755201ec393b523f51d5307b176f05fea16a2dfcac794f834f60a712f13ac8d5174d3a7627ce66fb862497cb95e36da3f486c7432e5983c2cc8cc3a7582a6b22c5a7ab3bc5107c831af145fbcf74ef9523bc7f0ca5eb97b34a3872b9870eefa3fabf609475c46b1e736cff313f046b6050c13392571f2d252959aca2f8418f7489809ea51939a1e8192bea5719262208109b37bae2424ec3655ade90a9ca235f69c8a3be54793655a9e8c6e9c64354a842458067295f08b6ab3b938e6b188bc252d4569589282eb703f0cb237a67a779d8957c4602a9bd80f266303898acc60439a975c8e9d8342f6f1a7d6c92f11606435878739d3bd27460fb5e735a73cbd1cb6c657d0a6074633de38647035b54bd10986e4573e09820ef56fd8d71ee778822f72194237c0b5344cd8c888f12bb34fc86e6147161143365fd45960396bf45a8868176c7d0c440fbb71b8c6aca11b6ef3e33484f9bc22d090011918c3525cd0f0724423bd1e1c2b46a66552926a3a6a0389410a3e5c41d66b07c1b41c645787e8503c613343cc73066bc85b028025c3bb6901e33e242a0061e001ecbb7ac690837b02282a457ccae40dde98934bf37dbaa00dae287fa0a628c42a66a7e05a6645b244e909fccb6abf0075bcf0974b97099a7c67a2c71090c7bb016210d0ab69ff775dbc47206429b347e6749eeb3e23983759a583e08b1653cbb5ad4b677f9b9b365287c1b559c199c3945653a3bc7b0da8b41914be5b411268080396795f1b95ae14871397e14f8f3bc940f00d669886668c2dddebf98e5e270510db63b9982ef818d1253d74a644fd56900607545ef8", + "sk" : "a1ea441afc0440b20c72e1b094ec44783325ba58a537bb2ba389b1a8e111fa85ac48716072d2345d789b2a9a07519506cba99aa60932f0a112282531a4123c99b8b4eba967f8b82b9b81c3b913b05cf51dd862810031aa7928242ce7b0a9404bc0142746b151eb3b002d571c07893507b7487063a4d59453dca293625cb45fc8464edc0322d3c9ee8b8c002c227d97b36611cc60204af3d88352d6bd6c07c87b1365c8c58d3a2468d2103be03604065734780765e4b932d6b0bf3935aac04849b0498a7087c7dadbcebc167858c778e8a09138481ef7074afc688829a45311d16077e5a9e38744c140159795a281206998943db5315599391d39007c25481bd79c8c0fe55aa013397be3ab85204792872577ea1b3393cfee4c90b442640f864bf0605a70f608657782a36cb78bb37d91748e1bc2bb388880a3b9ad78235ecad24b95f2c0f880a59775c90ca46819300dc0cb35ef0b6aafaa2f9234bfd7f0bf41507fe0166f7a4698e992373b6867704c2e7aea3344288d98b22f42888ee4da9ecc411aa079253309a2a9483d2ee2906518661e64482bb9cee4dc314034741fb7377728831664ad3a333105b261ee87b107720a5da79bb234cde3234364973237d825d98657709715b71a4d7b78952406b56265b6756611d9a2a4844924a78a0bbb3c25ffab7f5b94c96a3a90569cc178f06c884934b547a116938458e5bae601b49754b3e0e48c86f141dfc624ecc0823eb6215476911b4b9d13b93fce12076573b995ac8984b5a0dc33826d3b87ef0a77c363bf3d5c23255021f8612f28eb501890666b4486a972a3522b07e1c13beb539e731167bd535593796d68d6547c7913abc73d8812143bbb2cc6a05908c1038152655df28fba4912c757c9671b8d01570a5dd91a5dba81113a69d15395c25b474dd817d862ad78d24566d7989b3691faf25b88137f3c683e9917152e9b7d7218083df9a0e1fa702f184d745b7dca658b07a42494d27c15fb44f7c1199eab93daa26fe3d5406c09ad407b6d28945493db62a9924e755c29b7b1873f242f7c637d9ec2a222b9ceed63bc73543a5729b93d618c09738957c8368c50a58d01a7ba0bd06548b763a4b3891641e640c89af573be0382055a9539b471c661646047c10c52c4d8121bf32bc89532b763656cfb19be72330d4e7cab3053b900b162ff480dd5018c9202d0a41a4185fc554216065ca0cb01d5460f209debb40496eac65ac73ba264041bfb43db29b0038ac8c12164f9826c20ab8dc4248dd7717ec3d6c2bf974da380a31323b1b38678abf80a32f832e642c31fa69a163b4a3af6250ea212e8033377d1c596a72795196de2873bcc00c21e8b5d75619c31cbb1b1e339aacb204c919b43cc4982b3405d82bb0c97b2db370230c2413418c91eab62e30b57b304a91568a8dd29506e656c6785bf482807960bc962e43fa7d8ce04669044924f8c62660e5a0eb9c4885e739c58c22d7440583189c6c9e51aad37328a1c605bc44136f34b3fa82e24764743a43983f91125415c2e5042ba6393d2159b8992c41781a06d6c5745c5cc3bf10785f19ba1133cba89c2609a26a3524daac54d152b34d62399459cace6d0caa1d01e77841ab153387c64c5dbbc29bb88250221046e927f6e7a4d85c5299887ce3774a726096d37c61343aabdab95720ac89bed9b7ec29a14568178c9a63eae1268f9f29d9c4080cef312609834bff34bfa775b4b3078fba0cff3812c1d79674d13c9a0853f89a1bb9a87529d55548e303d51d8004f539f60d17e3d858037e90e04dc54a2f8bba79a395efc823e085c93eaaa069c4a27720c16047934e2cee970bec418a02cc91ee82a3999870fb190855e571c075445e2f53c8eb65f4a18844032b6991c098ccc069ff55a84d484e4261c7a379655aa1d2fa461aaf74deea4603838b9e8d908f9b7a3939c17b97cc9c330438855c77c284270e81528a745a7b97098b55e7a120791491c10615494b39934143b18311e83b13b6e92bc6d450b47b7589c1571a122370cc98793a13d1e008d57e955998c222a97814a1caa5fe7c336ca331bc6266dcb85d3ebcada0593c04bb91c3155e83b2e0a8a57b5532f799263b0b3111b1146fac429ef4c870911399e8158915b7522477500941b2c560cd7a39000219f2ce082fee023e6c49fe0381cf056ac1bdc95895271f4e245bdc98ee3a87f651191832b224b3c5528562f9498979c4485c3206eee0a6f5cba8fdaa70dec105bedc40e4c6b667d1739c8580f2d246371f415411c803ae0b52f0b5a6cda5fc3340f1bfa10bb29accf402d6f06472c14cc52556e5a97b56c190eabe6817985cc346baa02c76afbb6b6dfe33f711c78896a529656b4abe25516e448bcb41dbabc340ef4b483b750b0180f68ec0020271a0e9b9f466a4728c19bdaa426fb82294ca00261cc0c3349b75d397674644ae5ca363774abe8a290240abe4039a7e124cc894657c9025e1534b91b896eefd3af2d559da9f8558fa7774708a7fd535580545bc68c9cc89ccdbcc78ed5203ffb653965e7b0920574b7907443b9931472cf19c17dd18ab87842c853462366646881592ec3f5cab67b7e768472a08a43681120f491bcde05a9805c6787b96ecccb05d7d944fc858b5ec3828859234da88d8d00542b104883e824e7b630267111e49b1bb5e4103ea9ac2b187e046b4cd109709fca26af813440f30318dbbc34598ee5dc2806794c4e0a8c6b9c2310c34636088da92147d6b32a7bb447f50b898c5a3e5cb43d6e3c147ad085652ab9edda72f25b7bf250ac84d1288fc188ba645d88333b65b1150722334b5616429b608a0c93d0d946c15576c82093e0b263bb521d9fda997a461f1ee47098861feeb8b557b4656cbac57dc61fa9510bc1c95726b561a1ca4000f28a5720c42eb932f1ca8fc9b647d3740117ebca3d5587816bb48cfc1cb4e9caeb7834e1814a7c478fa052640af253371242da9575c2a66bd01c5fca4b958ea437e6474301069d0ddb254bc4603d3ba5b7415a96e5327743662caa7e08f608be974341b70db77a850b2c11e3b4cc6525808238cb097611e77cc449f17c63da122966394e79518fb6022ec470e8c5082a945c73b52f05c38e2dc3419af4080e890a6e819bb1b301046057e548894f511989a40e854aafb62ace7e586793921e292cc8601181599977d9fa457aa2039b14488d5698a8f03df1b56479f9109ad105b028219b3c90adac962369ac1f0043373bc243286c24f599de3a28684524988198971c1f88419ca09b3e4f22b64a221df8d32afdb0572ba62c7387235ee2752903535c9c912ae30c9151a3b6c415d59a4969cc432d088196f22c518037044236eb441438acb6bb61ca45c947ab98a53b44c48119135f776f2aa4a8413a1142cc4eed8c2948f8ca5db39388dbcc15c12d13035763a57c523b99a1912d0fd29b952776eb03aeed697320c66c0f65b369e13c7eab1e98b281e7b17cc2cb9ceab725671bb5df0933eb5c70a3d39e0eb5a55cc20af912af87cc23e10ab77a9c9755201ec393b523f51d5307b176f05fea16a2dfcac794f834f60a712f13ac8d5174d3a7627ce66fb862497cb95e36da3f486c7432e5983c2cc8cc3a7582a6b22c5a7ab3bc5107c831af145fbcf74ef9523bc7f0ca5eb97b34a3872b9870eefa3fabf609475c46b1e736cff313f046b6050c13392571f2d252959aca2f8418f7489809ea51939a1e8192bea5719262208109b37bae2424ec3655ade90a9ca235f69c8a3be54793655a9e8c6e9c64354a842458067295f08b6ab3b938e6b188bc252d4569589282eb703f0cb237a67a779d8957c4602a9bd80f266303898acc60439a975c8e9d8342f6f1a7d6c92f11606435878739d3bd27460fb5e735a73cbd1cb6c657d0a6074633de38647035b54bd10986e4573e09820ef56fd8d71ee778822f72194237c0b5344cd8c888f12bb34fc86e6147161143365fd45960396bf45a8868176c7d0c440fbb71b8c6aca11b6ef3e33484f9bc22d090011918c3525cd0f0724423bd1e1c2b46a66552926a3a6a0389410a3e5c41d66b07c1b41c645787e8503c613343cc73066bc85b028025c3bb6901e33e242a0061e001ecbb7ac690837b02282a457ccae40dde98934bf37dbaa00dae287fa0a628c42a66a7e05a6645b244e909fccb6abf0075bcf0974b97099a7c67a2c71090c7bb016210d0ab69ff775dbc47206429b347e6749eeb3e23983759a583e08b1653cbb5ad4b677f9b9b365287c1b559c199c3945653a3bc7b0da8b41914be5b411268080396795f1b95ae14871397e14f8f3bc940f00d669886668c2dddebf98e5e270510db63b9982ef818d1253d74a644fd56900607545ef85499cb370a74dbc96de89daa52e6af0482648e3995fce28f7b7c0daca7b78f1a230e05b7114ff0395cc6634db1eae8258072d09c09f291e92d6620b177dc50d7" +}, +{ + "dz" : "6396b328b100e4c7f4bcae69875edea1a1982421558c608c13c592bf7b5d0fef1100ced48add211a5c937b8d6079d8e271af3f949edc61f70e60453aef20dea9", + "pk" : "4f240d6d4ac24ad53108968ce43555fd4bc4e3ba3df7a1541e0764c6a387de455a564203faa38457376a3170360b5303be69450acc7ffdf638a90c7cf4031719eb27fad55e4c901cb7dc5fb828ae50730609b80d5a92a89ef1963d836a16685881028759d06c55b9505e84b1aedc5e07d5294a084c1201c0109699b3009b2c67603c055949f400ad487167c1ce048b49a98a8740abba9291618f7c395d77b0649cbec1a2c0e2d25c86c70320e92be7595e103013c4974b7a3b70d8100d61b89a1ff43c30f48c137511375ba781e74bcbf322be908d09fac8991b4213db7a298c2c29455b3a5092ec8610c0325187434239a8b651f0a164240ca4e827f7bb7345848e01b50e34162a359c2ef8c8c9e6e9b7a18bc371a20d2f086865a83a2ba3545943068e173941e4875600183fb19bcf8242fb576f908a8d805cb0909054de4cb6b84b179478a0bae353d8b10ecd278a310466fc0a00c68784ef246f1f0847ccf72894549806c2c9650c9430b02fdd5cb0b3a9608bc85f02dc32933811d87322dc4993d3d13177b7440822c62fc7a31ea174159814c59bb209356c5dd20620b40d08169df1a12d913105225cbacd9c6054f1499d6204cee06206389b05057e579a9e294b43243ab92e136265470786b256f615cd3540c5ca675c4bf68f7da4760105367ad3c6d71a2a4b209296daba2768223aa30845d4ce7d67c2906156bbc4c24410176652765e294a9e22c58cb031ba06a11b5a8ae035a37db36ce1771999061d722cc99de03e96ec3216543ef74447dad96bfbd386b3154b35e08dcccc88791677053a0001dacd8eb6c34cab6eea355a10c517c45164e9eb4c714091bf129186a6b3bf33a86049671652ceade8b55ad17472b49513a79f2b867bf3157d5dbc929974147903ac69a6618f67781a450637eca5d0950948ca8f3d7c41983b8942b03d6a04842a09a4896ba3cd345e7d72a16ba3c63d95a1e85ac4fbf42efb588b088749e2f66bd6f06d56bb80a818c2c56c5d1d1b5580863d1ef10ae2a97f5f83be12491c7fd629d112823d728a2aec939e163436259367473ea0b63ed37bac19934da906a21e5355a3a2277519c8f53c96b4f1a8704b8d79666c1224819590048f5b9a8b767ffda0a20697caa075ac25b5546ae32eb2959947b11fdd384aea2692f7952266267aa559c8ef9168a04cc57fd8ae46674b75e785535a2b1c0c779a553f4ce5c1bf6094541363bbda825fec4b42035325a3a2b1a8135dcbcbf1122b8fa1a37e925440e95c2e4c0ee1f69318d04282c0bb5fc8616e99c9ace80d27a79b64c843b08cb9fc7a27d20309726cb50735cb3450be54d86860d7708b11a615dc662ecb229997004f9670e27898e78a4b3732b4ae5cc459f28e78741f9355a8ef9b394cab001c912124a01d27232f060ca523d378a5d42e0022bef2d2700d7c6c14da09736679b2a0c33c035b3f0513bdb5b46fdbbf3a5b80d65c4be918511bc8631e35aa5459793f858f364c96f2010d8849229acc89e8a50360551afc8c1d481a1c21ebb100079cf3d45ab4159371c49b16cca69fda67aed5881f300c5864c03a9391ab1080b92601f23a417a0563c0c14b16b0255c36529f74a103036466fa9290744eca08cb16b94f30340c49581becea5b64088fa7498e02b439981cb4b4ac29ec4684152830ed82864ca833481323fd8a8f66ca34bd4abcef70c15c926fb8b6323c609efea710dcb6548c06bc13d6bbb41b40caea5745c68cc550873bb467f9dc6b3e720ff4649aad171bc5527b0633cc2709932f0869a0702da790a305761f9d146c1b24005f6c1c808b6dd5d97c647232e843cd61e39894902b76624b73739e3a1bbe4fb1b4b2348c836592a2d31dc9884394628ebae00112643bcda9a01f34a8bfa828333b32e8063acc5344a4b36667691c55c50b2e3098bb4c7069846283b57fee61089654a8ba06797c57c2e7e9bf1404077b80928f5a1bb6c6a753bb8a95bc46748c32e0e1c8f7aac1e2573a47d104ff9567daa2c0732c501bb9ac1315a211c11593fc1a38a69651347b6aa1250f3895a7844e1de2ae45ec66214a8b41da464baa5fc50100c5073bdaf5b4a88c70450256b6d65413ab3ed302ccbee864c578733d40a796981a8c3849f465cacaec79898cceaac424fcd9b57b426caf306d165d1e0ba6573a638fd7df6b3f824f240e7e0eaeee7d7a093875", + "sk" : "e8d7111942790185ab64776746d835f4f3b4b8458eece8cf89e08b7ae974bb84c5a5325faa7958f830bfc65a3f57b9bb311928d939b7bec454b051b399103aa8f871f3d87d240693a2d10587371a40fab0a52a3c13091710476a393a90a89b3ca8ec955f3b42287b23b2519cac32a1b8ea6194752a3b1083930a0c415159da51967ba96299065158f156d31189c797c150306c2903b1fa4639252aba2e131b3ee74917ea269aa41cfbe05915688b9e73780d46ba63325601895aa054023ce760347bada01916087a700963aef293a40a0b3e4de60258a0a687e367489a684a22b86e22aef5e5976989b09f1931d3e753a6265aeb677c0fb3629329c28b2061be210b3c156b46c5364df8b74cc95b416341ae5080488b895e2c4e7005901f5397249a3fc1747baf1c8105eb433227c959b6ac876629bcc911eb671689b2bb33d8b6a1cbaf90d81ce3f11200314dc0a53b41dac824ea117e25852f2339a33934278cca7dd0797c7b55af75ae8f6a1c34f288c1124dac01ad5399c1966049e8569efaa305caf9bba4e92e15154d2b2521d0f245aa89788687817afcac195315befb50eb77bcfa487be2547e98306fd9e92bab57cc7935168018c570260c93d712e3058a843aa36e88123815a847411a3c4078e336b2bd26472be6b8bec382898b57e02048e531b335894ccfeb24ede00f9a46a34ddc67f9f73bf5d98a87b50fcb115694e7b3daa7067f287dc665a13bc58661b53137401403a211a3574a7a596679a021f8458c7baabe9efa18f3f82bdac20c6cab93bcdc2d31218dfe0c451724226961189b460958a9bd12d87446b7b8dbf65ac7d908ff1c9fb7e927ec1679da95c4b43cc5a11937b3538446298cc7b55b178078025a229be58a95a0727928bd3370901b180543d78233530186b3155a78162d3969bdd6b6a0204a25066303c495fdc9c9df947959b79497a805a3122c71e96efa728c6b92042b39b45291cc87895d4ab62a2437c9aa7754b54a48cb34c1070b08fe2cb2edb974ba633cc6c5413980ca5173160ca43cf77320850a12e402a0c94881d3c50eb5f317628c4e0477bb4b1b962c15081b2662d65c4ee1099c001835de716ac6a924d3702dd2c61acc2487851a14ef06c36c6925f9e6714291765d8272bdac11651ccf6848975d57323f599de580cdfd892209c7888b7bbcf6b65c1c32b5a8e9885a29c16446369fc51e4155b9d5081d9c74c2eb2c545c07277f608616d800e3ca0ff95a655b7189c48412556a8fdea48e0701b4d1d5175cf0088b70042b5678f91164eb42031067814db0ade6b26c606bbf8cf596947980793ac48f7abee21a854fe00551e98ce039734ca028c8d8a3169c9922dbc273580fd5bb03a85508e0141eef13a37e80ce35531ba7b900599acdd281ce729c4f2bc6b898b47622f5b559e7cbc86a26ad61a0edaacd3aa638879296a5413dddb78edf347879c4c325ec69e2bcc7710b65b4821489aab9ab7c8ff9e6b8bfec9d5c61967b1c77f7823cdaca03a7fc04703740dba421c30b8ac1894ce58845ce9a73b2321c65228ea0d64c68d3c7a6533837b6967ad3139a709acd8517ddb693ecb75ce3db51b7235b34c0b296038a140737bf77ba7ae91c9c49200d6262a2d357ac390c744bca28c9ca4d32a2dd8b456715907b1b42e7381a605b16e4e2a021e383f4d051f859be8e83b39a2bbdb9987a37423b689718c72365dd5b65d1601b48707955724ea106602b6b4c2223b142907195855d652c13cbf29340753911714f82bcafbff178d52bae8b9447cef9745a6b18f53bb697ac157516c3123c526073cd7aeb3550128b1243b95f178705accb7efa2fdf9c5ff9db4a6d1c171aa7b6222151375796b93c8f39b8262d56169f591a8b3964ea228de76710698698f23a147e3206a8641f5c46b7573b1eb13b8432104fc7751e813c4004d25c2af512c5a47bd4a50a37129d7b0b80ae551145356ec304751a8ca143a57c6c1830ab5717e3862b50f70b745b33210bb73b340154b6197f1423f9ccb88feca121e24e79600dc0b047a36b1b76697fa06395ca8769763443695852923572566abf8c5c7097f6425ae1c7e1185b1db5ab75a9856217ae82c61c82265e18151f831b65a5b435dae57a89b2ad55c3cc02f70fcdc55901069a2e773b4f240d6d4ac24ad53108968ce43555fd4bc4e3ba3df7a1541e0764c6a387de455a564203faa38457376a3170360b5303be69450acc7ffdf638a90c7cf4031719eb27fad55e4c901cb7dc5fb828ae50730609b80d5a92a89ef1963d836a16685881028759d06c55b9505e84b1aedc5e07d5294a084c1201c0109699b3009b2c67603c055949f400ad487167c1ce048b49a98a8740abba9291618f7c395d77b0649cbec1a2c0e2d25c86c70320e92be7595e103013c4974b7a3b70d8100d61b89a1ff43c30f48c137511375ba781e74bcbf322be908d09fac8991b4213db7a298c2c29455b3a5092ec8610c0325187434239a8b651f0a164240ca4e827f7bb7345848e01b50e34162a359c2ef8c8c9e6e9b7a18bc371a20d2f086865a83a2ba3545943068e173941e4875600183fb19bcf8242fb576f908a8d805cb0909054de4cb6b84b179478a0bae353d8b10ecd278a310466fc0a00c68784ef246f1f0847ccf72894549806c2c9650c9430b02fdd5cb0b3a9608bc85f02dc32933811d87322dc4993d3d13177b7440822c62fc7a31ea174159814c59bb209356c5dd20620b40d08169df1a12d913105225cbacd9c6054f1499d6204cee06206389b05057e579a9e294b43243ab92e136265470786b256f615cd3540c5ca675c4bf68f7da4760105367ad3c6d71a2a4b209296daba2768223aa30845d4ce7d67c2906156bbc4c24410176652765e294a9e22c58cb031ba06a11b5a8ae035a37db36ce1771999061d722cc99de03e96ec3216543ef74447dad96bfbd386b3154b35e08dcccc88791677053a0001dacd8eb6c34cab6eea355a10c517c45164e9eb4c714091bf129186a6b3bf33a86049671652ceade8b55ad17472b49513a79f2b867bf3157d5dbc929974147903ac69a6618f67781a450637eca5d0950948ca8f3d7c41983b8942b03d6a04842a09a4896ba3cd345e7d72a16ba3c63d95a1e85ac4fbf42efb588b088749e2f66bd6f06d56bb80a818c2c56c5d1d1b5580863d1ef10ae2a97f5f83be12491c7fd629d112823d728a2aec939e163436259367473ea0b63ed37bac19934da906a21e5355a3a2277519c8f53c96b4f1a8704b8d79666c1224819590048f5b9a8b767ffda0a20697caa075ac25b5546ae32eb2959947b11fdd384aea2692f7952266267aa559c8ef9168a04cc57fd8ae46674b75e785535a2b1c0c779a553f4ce5c1bf6094541363bbda825fec4b42035325a3a2b1a8135dcbcbf1122b8fa1a37e925440e95c2e4c0ee1f69318d04282c0bb5fc8616e99c9ace80d27a79b64c843b08cb9fc7a27d20309726cb50735cb3450be54d86860d7708b11a615dc662ecb229997004f9670e27898e78a4b3732b4ae5cc459f28e78741f9355a8ef9b394cab001c912124a01d27232f060ca523d378a5d42e0022bef2d2700d7c6c14da09736679b2a0c33c035b3f0513bdb5b46fdbbf3a5b80d65c4be918511bc8631e35aa5459793f858f364c96f2010d8849229acc89e8a50360551afc8c1d481a1c21ebb100079cf3d45ab4159371c49b16cca69fda67aed5881f300c5864c03a9391ab1080b92601f23a417a0563c0c14b16b0255c36529f74a103036466fa9290744eca08cb16b94f30340c49581becea5b64088fa7498e02b439981cb4b4ac29ec4684152830ed82864ca833481323fd8a8f66ca34bd4abcef70c15c926fb8b6323c609efea710dcb6548c06bc13d6bbb41b40caea5745c68cc550873bb467f9dc6b3e720ff4649aad171bc5527b0633cc2709932f0869a0702da790a305761f9d146c1b24005f6c1c808b6dd5d97c647232e843cd61e39894902b76624b73739e3a1bbe4fb1b4b2348c836592a2d31dc9884394628ebae00112643bcda9a01f34a8bfa828333b32e8063acc5344a4b36667691c55c50b2e3098bb4c7069846283b57fee61089654a8ba06797c57c2e7e9bf1404077b80928f5a1bb6c6a753bb8a95bc46748c32e0e1c8f7aac1e2573a47d104ff9567daa2c0732c501bb9ac1315a211c11593fc1a38a69651347b6aa1250f3895a7844e1de2ae45ec66214a8b41da464baa5fc50100c5073bdaf5b4a88c70450256b6d65413ab3ed302ccbee864c578733d40a796981a8c3849f465cacaec79898cceaac424fcd9b57b426caf306d165d1e0ba6573a638fd7df6b3f824f240e7e0eaeee7d7a093875cfb4f6a03bb7707d37c80474f92c12748b37f448186584df115ee97c195d45a81100ced48add211a5c937b8d6079d8e271af3f949edc61f70e60453aef20dea9" +}, +{ + "dz" : "a453bcacdd2b0d4646009e5ed451c3c45f08fb827ef733db3c517a9dc1af93e67a3cc8aa3239d4c52ce4c95afdeff6efbfacac10d294edc0e7cf4535059bfdba", + "pk" : "14905ebe26c856fcce2c623156e43efd0433c19858c986436150968132591db37eaff112c1383238c0767316c0077a00a4714e49d694d802a510dc960c525bf601384b96b90141b846dca14f34159db490479205b30800137819406bc6e14786dc4079e0481d098ca4a3f15f593135ca64cd7c32c46b45b3bdea0d7fd70dee467020ab49d4360355146d7f00337a1cb452357bd01074234b464a134abebc14f7557597bb057c4972d2f012b59a0b83328e88d76bd257ca5aca8912c2a9f90672903cbca16b9746e135108638c388676cd189452325dafb4ddfe435e13908b177a5fc883bc233679df34e40a09fe384654e6a857e49c5f62aaa30e123ed71a4d79a65bab40eb2ba7e1c497ea28c069ce9898f3789fb1b03cc07a5789569496a5a6b84966dc3b601577b07b01e2bd6afc315cbe74b03cbb51bb68920362474819a02e5c60db441a3e0a2a7299ab0913a92e3228986c18639ab0b952a01c77907e6a0b59625c01b1c406a4b339c10b0c8947fdaf5c14f6721be5c11e3a62a7065a78b9b1176e64ad075150b67aaf70820b9a62848378c374a3aeae6c63cf620d0927971c0188768991734754368bdebcac2d6b899e5ecc20922059641566b4996be455e90ba9aeca1a40ce8cbd68a6ac0cc708458169c624ef80a25ccc7c931d938687ca4a12290711b1e72fb3793a760a5c29942896853e26dd1606fb48c22b53506b4413e8f5b3c20b446dfeb586532a09ad602e5c54d5e0c0149ec3526758f174ba49134c980ac109e711ff658b7cdf0178b8c861a71c700e90b1ddb9265e9bfbc07a253726fc9c54419bcc39932555024af651a277302bf383cb67dd2a929037fb4109c69347876751f4f83955a4768fb94622390790796084215b6108c72e10217fc9134b7872ac6ea3d07b989bc70a23a826676718f31338c68a5b1f9ecba4b18bc47d3161419530b67041b3864686224d0171dbd248a48527950f2c4c857aac6f7a3394662afd84f79d5854ea77c26e7c57fd8a3aad0399ccba0ae4780ecd2481ae065e3597cf1868c327c14baf36d9711a3a8647d26ea52a4f9139ba835f380ce9cc599f6f11586f158f941520d143f75d00125a3806c56108de46c5ad093872ba5f927bb2a4a88e668c40af5b4fe9b17f80ca75ab58224ba1b485a9e1c3a6e82b814a1b23bb0d61ae14a9ca4e95d03746a564087f9c53a343ab7595572cf2542d7a9cc90060e6e99cb2d18880f082d3ac91fbe00c5ab141c6385895c626d9c143ccd94042a27509ff67c802098415a49bfe163ca01a20a45add4916aa512467db549e7b0c898656cb4265df3987998c8737f3c79bedba48b9c6b8967a9bfaa0b22e6858307977903001867282cd38a01798d3b71bed21459ed4c4ca6e185d55525baa096c1897c55789b9e19a6b303af32f493cee717bad70cedd67c3dd89bed6926a0f20b1798bb46d173452a31d7543530311734422f3cc9561d5360b665ad87a19da71a7270998b87d62d5e7b0a5ca969120b4c610848fdc6afc0e631fb2abc21096347221971a08b94b0ca4116c2f5a8188cd982f3e647ada99eeadb3ac25310dea91fa724cf3e1017c0c86c2a979791d30192bc3163ecaf73c819dcfc113535bb3a40b252c8bc269884cf7407fcda465c2aaeb19681dde0c99a3853a861ac81f77e1319afc6f67b2fe52dba6b38523147f4e589ee716172650c7cb44e0b760174691217093ed4421dd5a38f2ca2c41604c592366a89c4c70adba149ac63de1b5e21e78788f33d9e135890e61d69529dd9f658b340848623b17447998bacbf1c315b1fc5bdf8fc357e89448fe7a40217205c64961cd643ac6bc3486c5efc003011e80c4f4494cba123c2ac45f7d9019cbc7018669921fa76db3cb5436763b48a8046fa71d186b57c942f6529930d23737c49698c15404de20f8f357d5da523ee3a117fd8b69ab80335e388fcc661a0c8b583f94a8c7869e464a0544c84d160a828f1770d97be7bc43cdfa8566791727b7884e99a5d9fc549369a4ec5195ef1285860cb263085740cd466bc24835ae33bdd1499ce941f8041571ab638bcf896201cbf0b7324ec22c6d3c00f60ac6e6f0317efe14efb13440330b50cf86227fcc7bedac20f9364e2593adb7599b5142174d6b999c725f7d119814642f79de48f28d8b47d06bfec41fd06e2da9ae905005ad241ba55ab42a993df7551", + "sk" : "cd85bacc99669bb19f64f32796599fa909499edb700670ae7eacc07c89b4659cb7c3bab323f3761728c79ec67515102091b133e3536a2032093df24531874108d1010194338b16475f531030e0073ad08e168976af67243eab3596b9975b2a216e8146a5192577975883c21646cc20c036577dd709edda6abd44989e6a8e07c555474b3d14215777193308d56fca4aa7e2378a94f80daeb4788f4c87b6477193d7a5d0bb6c49407adfa222e7d34ca19b046cb14a37db2cbe781288584f5c386a2e9c4fae79a106c28f27c49ca2401a0a375664e885070814f96c9048993300065037ec06e1e692a97835c129b06707cd501c6c5cf1646d82365942cae5e104a5bb71fdf42518485c1602838929244a49b194c76cfe2bad0e758701214cc6c938adf0c8e4712e0ce148576961f3b613537a843ac07243926a92a324adc52b65152c69613acc6336341a72f7104ad72c540de40c4bbb8611a03ce9271680aa77bb827d7bf629a44bca141c0cdf912b8b372a32030ac9680a2b64ce93f726001d6ba184736d571cfc79282cca13dd0aa3adc14683ca9bcd89b72d7cc280963f2d37925d57693b947017d61b716626e45a5c6eb295ba0963f2a9086615697688383ee8775228afcd760c2a90c85d18c3fe553edc719926ab0ce6e40d690a53b34626c6e28925b469eaeac11209c7b00a03f020cc25176fad9a2ad2b38fd16b04758a5d379630f3c9cc2b0824eaa882fca6b134011a0e3035b1f2cb19346303a17837c30b60f11ff8795593035c6d335496734c491552ebf4a38ea10ab203b13f325a4df221b9dbb7eb01ab00097845c1335f6349ce50c15e64a02e644e058807c9b764badc44c6f21745c80b6f4264b1a7ce8fa65657d75d5319807a9b5bc17b1d76ca64ec831e113c1b8e79b5a1fc0b32d21f839a64bc212722e1664b9ac5c39a3dd0d8961d53c6dd697a6c896b664a6c7c5a70de5a0df2745a64cac12447b70b1ab16395b71dbb810d763faf817d42149b99181f9b9835c8e947cce200a5a5aa573b44544226b1607cf58968b3829de360952a8307f7fcb157c4affc5009ca6628f0527042e235f5d1c1a91bc178f8288bfc37b2f53077cc0c7c414e59f57e78d5357f447871579b54421986116c6bc22be84080422c9b983794ae70304d601e2cf0ae29f6172a5529e8a4a14a89b064a3b142c4c90e421b59a48471e4852c749b9dc4867c677e52e44363a5131eb5642c4415f5248ae4358a3fbc01beb2568c8321b711bc3199814a2b9e9be56e266b2639fa920dd204dc41518b19b8a9dc0b5ba3290b362e9d071dd61c041b4a809fb92f0cd2b25bf94f04701299ab530ee704dcb6ca69613439c4c288e7a0643ca3ac321d930a99586c85ae0597b2c56f9a870e7bb260df51ba7a62bed6859d7159b56b211d282b7e1bf85d81b1258fc01e2b8b15e3829bafb34aa81036d05531d288a0efda8106362da9878b61a4b3ab6813f27ab65bdb48105686ea3594fab5c2d83aa867055a233052a5d57c741086814b7e4ca39b688669d4688cfd92203c902dc1d9831d3652475328c99bca41a7b0f54a7795f8c2a4f90f305626e4e31b983c9fcb0748aaa856630a67399b37a2f204186388dcdb740f8b8b00ca0e328958a821a9f5e9a26d39c60a37b2a513b79c37930a992f3710ba1f574471f2175d2a777112a4f5444d37db793d87c1c1e8b4cb37bef3d06f8785ab65d8bac7c07cb4003fd4a9933c3117e347664d92a18f137980f8065cc031aeb8b1a98b24656031c3b57d36894964171d6f511058e21a63a2083fdc37ef1848379ab86b7c53eedc941d16174553966415439f6944393660c6209e59981662387a1e827b768787b8b46b685b8bb3b72175a367af89b5f3953f4a636f9bb89b8351866a335a7ea422f9e9c794a24372b40fd277a5ba2a2531a4703e60827f562acf95a8193991c8f4417109c059e91c4fbc289233b080a0aa8a4b3e02b35cb59216a9c37509a91725910cf8b11d6e7b985ba5c0d85073a99b324d0583c7f8c73901847e41c4515048a7556a0cc206711550649926514c96e3535ef6194a37c1a3eae023a8851dfd0bbf0efba981880c19fb9d4e6c2f80b4b8cb4031b8106ab6ab33b6a37b3f8b5d133244894ac86929b4373b30f6bb4395b11914905ebe26c856fcce2c623156e43efd0433c19858c986436150968132591db37eaff112c1383238c0767316c0077a00a4714e49d694d802a510dc960c525bf601384b96b90141b846dca14f34159db490479205b30800137819406bc6e14786dc4079e0481d098ca4a3f15f593135ca64cd7c32c46b45b3bdea0d7fd70dee467020ab49d4360355146d7f00337a1cb452357bd01074234b464a134abebc14f7557597bb057c4972d2f012b59a0b83328e88d76bd257ca5aca8912c2a9f90672903cbca16b9746e135108638c388676cd189452325dafb4ddfe435e13908b177a5fc883bc233679df34e40a09fe384654e6a857e49c5f62aaa30e123ed71a4d79a65bab40eb2ba7e1c497ea28c069ce9898f3789fb1b03cc07a5789569496a5a6b84966dc3b601577b07b01e2bd6afc315cbe74b03cbb51bb68920362474819a02e5c60db441a3e0a2a7299ab0913a92e3228986c18639ab0b952a01c77907e6a0b59625c01b1c406a4b339c10b0c8947fdaf5c14f6721be5c11e3a62a7065a78b9b1176e64ad075150b67aaf70820b9a62848378c374a3aeae6c63cf620d0927971c0188768991734754368bdebcac2d6b899e5ecc20922059641566b4996be455e90ba9aeca1a40ce8cbd68a6ac0cc708458169c624ef80a25ccc7c931d938687ca4a12290711b1e72fb3793a760a5c29942896853e26dd1606fb48c22b53506b4413e8f5b3c20b446dfeb586532a09ad602e5c54d5e0c0149ec3526758f174ba49134c980ac109e711ff658b7cdf0178b8c861a71c700e90b1ddb9265e9bfbc07a253726fc9c54419bcc39932555024af651a277302bf383cb67dd2a929037fb4109c69347876751f4f83955a4768fb94622390790796084215b6108c72e10217fc9134b7872ac6ea3d07b989bc70a23a826676718f31338c68a5b1f9ecba4b18bc47d3161419530b67041b3864686224d0171dbd248a48527950f2c4c857aac6f7a3394662afd84f79d5854ea77c26e7c57fd8a3aad0399ccba0ae4780ecd2481ae065e3597cf1868c327c14baf36d9711a3a8647d26ea52a4f9139ba835f380ce9cc599f6f11586f158f941520d143f75d00125a3806c56108de46c5ad093872ba5f927bb2a4a88e668c40af5b4fe9b17f80ca75ab58224ba1b485a9e1c3a6e82b814a1b23bb0d61ae14a9ca4e95d03746a564087f9c53a343ab7595572cf2542d7a9cc90060e6e99cb2d18880f082d3ac91fbe00c5ab141c6385895c626d9c143ccd94042a27509ff67c802098415a49bfe163ca01a20a45add4916aa512467db549e7b0c898656cb4265df3987998c8737f3c79bedba48b9c6b8967a9bfaa0b22e6858307977903001867282cd38a01798d3b71bed21459ed4c4ca6e185d55525baa096c1897c55789b9e19a6b303af32f493cee717bad70cedd67c3dd89bed6926a0f20b1798bb46d173452a31d7543530311734422f3cc9561d5360b665ad87a19da71a7270998b87d62d5e7b0a5ca969120b4c610848fdc6afc0e631fb2abc21096347221971a08b94b0ca4116c2f5a8188cd982f3e647ada99eeadb3ac25310dea91fa724cf3e1017c0c86c2a979791d30192bc3163ecaf73c819dcfc113535bb3a40b252c8bc269884cf7407fcda465c2aaeb19681dde0c99a3853a861ac81f77e1319afc6f67b2fe52dba6b38523147f4e589ee716172650c7cb44e0b760174691217093ed4421dd5a38f2ca2c41604c592366a89c4c70adba149ac63de1b5e21e78788f33d9e135890e61d69529dd9f658b340848623b17447998bacbf1c315b1fc5bdf8fc357e89448fe7a40217205c64961cd643ac6bc3486c5efc003011e80c4f4494cba123c2ac45f7d9019cbc7018669921fa76db3cb5436763b48a8046fa71d186b57c942f6529930d23737c49698c15404de20f8f357d5da523ee3a117fd8b69ab80335e388fcc661a0c8b583f94a8c7869e464a0544c84d160a828f1770d97be7bc43cdfa8566791727b7884e99a5d9fc549369a4ec5195ef1285860cb263085740cd466bc24835ae33bdd1499ce941f8041571ab638bcf896201cbf0b7324ec22c6d3c00f60ac6e6f0317efe14efb13440330b50cf86227fcc7bedac20f9364e2593adb7599b5142174d6b999c725f7d119814642f79de48f28d8b47d06bfec41fd06e2da9ae905005ad241ba55ab42a993df755120179b32e6faf885f946898d545245757425d719681b0b2ba24d49340f931cf87a3cc8aa3239d4c52ce4c95afdeff6efbfacac10d294edc0e7cf4535059bfdba" +}, +{ + "dz" : "47ca2b77c5b717f423222c2730ca5cb9c856bc951d01b2b2c80bd76ccb5539b78f1481d7cab000e33fa07de8dc9627a85e76fabb4428a3376e66300cf12a0787", + "pk" : "212bacc3413ae8c00a2b78cc3b0c7958e349211bc64f036a70aa16067882330a36aa4cb183497c0251b2b942964a922c25525ee9e3834504a085540b36971963e09106fc14125659bae0c96e6663a479a381a915fda7b8a404061c90b814c3146a549b517a3735760244ea8959eb2d98bc37e2f7309e09749c4c689f6b640d28a7a0b8524fb9bc0b544eb219683be91e79baa327b5c0d2f2713b78341c9682f6941327959f853195aa36b919e07c1d5723d6528269b360984857df1636f2a80cf1383a775c230a9991f8602d074b5f0bb42c13ca1eaf4b3c7336a4fe61a8310c9c27f37454f9af3ff0bbb2232689c63ce4b7cbb880886b36681414902bf77a2623ae5f0c359c038f82433413d2cfa88373bbd17bf1d5503774939e916c415c8b929b5c2303234501ba642b75ef2823e42b71647014044a9450a55cedc0592da6554cf74693429d2d526d34851fda24a64450c785510111988982914fcba3addbd0963c3bce55f41b3cc71c0300ba32b02fac76158d673ab1ec7a23b30afd2a53d5aba3c3c87e0fa54408864037511dc3ec113153681d28c45b2a25e7256b6fa90df8b8ba8435b2f90727d4394eaf49981b397916c1642abb68f5006fbb2ba6c2c53b6dc5795a261ba674778ffa7e9daa65ac93366954710419c99fb21a46b029242158294107dfa28c53554aa3d79878b53506ea03846a9041664bab6056f7211a337910f77a2f37b993324927d64aa0d5085840475039c04acaf0ce5721b1f182b53e96928927961b8a04500118a453738c78b8a796ceebd960473b2fd2c9c825593ff4a95f3f659ef00b251449a253332171bbcb051699b100501f84bbc64c4e7f9c7db1190c4621664fb33c624910078155c1f2035d1755f7b10112e4521d58cb9c89575a3a2fa6caae5dba470a9b4d3fdc9b7ca6ac28e0570cc92647d382d04a5091d8a1ef749067848cda293a47d772372820f25245ff457580857eadc0bda0a059ecf1a3adfbc6d7e87184337e94231e8e3774c9854ef1c6b4c872bea6f939845942ff2732aed903a23b72cbb5122c43c8ed303ae0d33a7a704001890f0b378039ca271205d052fb594c526e7c761ad6b0cf14bb251225c7ff42b4b5f651ed55143ecc05cdb21962157e28d7be4fc4b5aebb6cfce5396fa51af1bc85fda50b00fa63ed800d60a5761dea715258bcf597a434e48b23202d8a415831c0417c6c43a659036df10772e796a2d70515939823575cb5c01d35155f7399bfe1b3ca9bfa47ebd69f5c8cc8879b87ae34a7dc32568817aa3f923df22c92be454e99d83023d3caa2e80e0ecb8818414b0241a6315ab20b63c422b6be8572b5e7f249fa3802fa647febc89c8ccc22583c144c191b91187257235d857b9bba3b13db06be10a35d712c540e7bcc62373d76e5828be049b6462d8da931f24a6827d314f5c0ad266a3529fa9b47cb6eec425b326ab0bfa032b6809d82c1cc3e2427787a413daa7d3976aaf83ac08d87b34da219a92a631784bce31cc66693c75aa58c7c87a9e3a926b5229a4f008b85090f351694f66743dae3a59a86299b43c20522cd82f96284623ee20b521794114d1459fdf70739558123f18ff8304730fbc63f198a2eb992e7115e07f509dc58b1e2a00c314714b5162334861ec20acac85664d14057d2788207c01a7ae383c93971d850102d60ac0d042c648c100ed660ef8a2cad375ae1a21b11998264e86ae0561e19d971689183968a98be064486b8abc3634021f770e2581b4383aa3c938bf3aca4aa2a337ec06647aa47428bc027339f2802b9f135820f3a8bea06846beac4c1a2702c502e50d338fb80a590a564f48a6606a10b51e839a4034f2b906ea34b4d3c875f1ff6bb57797b076638e4b576fe8c5a490806bfd178b4569a69626001c8a5fa1582bf4bb7bd586296f9ae74724d7b6c9c38d25273e114fed525ab008b887b9e5871172cc393938902914a3ace06a41cf92f6da963e4217f6b1363f7273cbf4a342865a761371f24285113e74f7a770079157c0ba0700e6bb9ca99ae10b83299ca9445b8024e450cb6152fceb79c0c433753c0b88b21c71bcb38c643ae5e16502fd14c0aa8939219005a15180446a166e74933f46f41a68675692e25816e7a227808764e20c98d33d6c3ef3801d21cb37d2872fe76749aeb09976580ccd4feadcea0b16f00970f92acb21c560501728f", + "sk" : "6b3b1e9e6771d2b6946533c210a8bbfe297df569cdfc56b501c54ec9e21dbac3ca24335438a71c456842ce4653ec9b4ed5ba80ebe665b40597230213f58951104c7ca0f225eb535fad8c5724189b49138c22f4478b19492403c2c41c452080a2625654beab411ee59f1f372effdc5dd282a5b4244a8d7a0ade30386a13a353d1516ca38991948497a4ca83cb9f65f5aa1a6ac85dfa634253068b2b43a1ac8c41f156e0acaf4f05505edc57a1a6bb1a890c15d35967b86e84f16d2a1056916c8f90db83b47275b28ca3efa0bd4f18b9caa5b480e80566cb3951d606887777c2c3bcc88640a6c1c826ea51b169c8bb11a7f51b084bf0246f93990e62ac6f012b89eb025b5962e9a6bf36564ee9b483895b2ecdd6699421abe9cab8820771e121719922315de8677fa1214e332379caa11133a5ffa13dbba75c6491308ed201c23812db0a8d006c9ca9e7606c532557c8555cb10d6194284b71275ca84eaab50e50470fc9e8c2954b70ecd96dde6937616618ba91b1fa858335605c162972495c4846b46b6831477dc5658751c0169a5ba0c733863555f62c5c1bc5c83bcabbdbf1438617412bebbfb5705622c258a301caa76a4561099c3ae34ea4e014f89431cfb957c6a930315b7a001955310caab03076440594f7a66c1385637b69135ad50df1934a1bc754eec983dcf351b306a14fba9ea5b6a416fba9b46a40c99b640048aed0e4ce74771704a3b3a7c90009c964e7b055f4753bf062349a368aec2423bd6a278fdcb3d9f0c81ef551a0122a72175e76d5970fbaa44ff8399fec7498e59dcd685a6b4038b3b5bf47dbbce204ad99b8945bd3afaa237af16a81db0c15a906364e1733427b28040539d32832cc5a7f0cec282ed902df9a0af281cf14256da8873317fa5f6e9149a2d6ab544c97697683032455591c75eb2a0bb4aa5eec1c3499b64b78729b6cb7553f1653bd4181224cadcd62ab80f5af7478b909a4ad9dc1cf97e608234b48b2d9b005a5ceb80ccafae85e431a258c77601dc3764823177e970ab5763b154447de89cb2c6cb11ee51195f59977f983c1629dfc640026a8c36b909d4aaa9f9e0b642140a35d2a5fe503a07a800c62cb4bb7c6334c056500d14337dc984c7730fb37891ba737f2a65545b2943bc22a5099345732a1129bbe22e88b987aa1c8e33934323006eac14f03a9970cafd6ec587d15544ed9950d5a851c63898c3b2331192e0fc620937c30a5e8b56355319ccac8094ca136c237941372b17ac5367aac78269658f4b40d04b33e84961733a353baa9d5f4b2dc69609ce6a00ee6af8dd425d2b04bca841411473070d7a1f4042a8167cdcd138634619bd78c5c37511b54b3857a897f17fa02de663854196418b4b23ed80008b6af534b28b1f0027dbb41ebcbb83c9cb0f0080d5e9c8e80a83d120a0d679c9b3eec7d4f94c9046832d947a622f7509d41ae888107f5fc7539cc0053a1365ce005caf627f8185cd1355d4ae65638c18510b93eeb87642cdc87fdb858c4a997bce0963f6b3a1318c206635289aaaf73a33cc7d76977e3570aaa98c515436ea39cde485342a4503d991ab2e374ef2ca8e221c71840b876100aeecabd475233a40122f2832193f40bf29ac1fe71c1eae1767ea470f3e580089ac09bc1737fa3449b4b9911c114191614599a8b8e02060517c57ea13baec5ac77b34b7ae21c2c9646fb6b6f9a0a3787760509e3cd9af200f8cab9daa5a4bd7a9c816b4fd7d3c0905a2347215f5ec01e40c605ded70ebf472b1ca4cb684272dcc75fc17a3a150c06af61ca0573ac03473c395bb35b34bdb0d3297a5c4729a14345546124377896b11975c26118d79970c76128502d474b8828b3b01a9bbad62728b8593a254734ad208f29722fae409d7f178b4a0937e86542527201a7e4c14547b599408552952cc65128533c4207ab047287af05e9bc5ef0b110e4ce977660cec3adf062a154c24cc86494bf5b2f3f1424f42a7308d0057f041c077528030182295a67c27422af6180a2010e4cc478444b595ca065b8a50de1c775174bbe870a874beb8649d82c07a68341165c11abad1fb5b7bdf2bda1511543108158471d94c3b59ad199c868bb67e210a724909b9452ded168587247977a70da79b3750c39f319b44198a5dbf047ce618c212bacc3413ae8c00a2b78cc3b0c7958e349211bc64f036a70aa16067882330a36aa4cb183497c0251b2b942964a922c25525ee9e3834504a085540b36971963e09106fc14125659bae0c96e6663a479a381a915fda7b8a404061c90b814c3146a549b517a3735760244ea8959eb2d98bc37e2f7309e09749c4c689f6b640d28a7a0b8524fb9bc0b544eb219683be91e79baa327b5c0d2f2713b78341c9682f6941327959f853195aa36b919e07c1d5723d6528269b360984857df1636f2a80cf1383a775c230a9991f8602d074b5f0bb42c13ca1eaf4b3c7336a4fe61a8310c9c27f37454f9af3ff0bbb2232689c63ce4b7cbb880886b36681414902bf77a2623ae5f0c359c038f82433413d2cfa88373bbd17bf1d5503774939e916c415c8b929b5c2303234501ba642b75ef2823e42b71647014044a9450a55cedc0592da6554cf74693429d2d526d34851fda24a64450c785510111988982914fcba3addbd0963c3bce55f41b3cc71c0300ba32b02fac76158d673ab1ec7a23b30afd2a53d5aba3c3c87e0fa54408864037511dc3ec113153681d28c45b2a25e7256b6fa90df8b8ba8435b2f90727d4394eaf49981b397916c1642abb68f5006fbb2ba6c2c53b6dc5795a261ba674778ffa7e9daa65ac93366954710419c99fb21a46b029242158294107dfa28c53554aa3d79878b53506ea03846a9041664bab6056f7211a337910f77a2f37b993324927d64aa0d5085840475039c04acaf0ce5721b1f182b53e96928927961b8a04500118a453738c78b8a796ceebd960473b2fd2c9c825593ff4a95f3f659ef00b251449a253332171bbcb051699b100501f84bbc64c4e7f9c7db1190c4621664fb33c624910078155c1f2035d1755f7b10112e4521d58cb9c89575a3a2fa6caae5dba470a9b4d3fdc9b7ca6ac28e0570cc92647d382d04a5091d8a1ef749067848cda293a47d772372820f25245ff457580857eadc0bda0a059ecf1a3adfbc6d7e87184337e94231e8e3774c9854ef1c6b4c872bea6f939845942ff2732aed903a23b72cbb5122c43c8ed303ae0d33a7a704001890f0b378039ca271205d052fb594c526e7c761ad6b0cf14bb251225c7ff42b4b5f651ed55143ecc05cdb21962157e28d7be4fc4b5aebb6cfce5396fa51af1bc85fda50b00fa63ed800d60a5761dea715258bcf597a434e48b23202d8a415831c0417c6c43a659036df10772e796a2d70515939823575cb5c01d35155f7399bfe1b3ca9bfa47ebd69f5c8cc8879b87ae34a7dc32568817aa3f923df22c92be454e99d83023d3caa2e80e0ecb8818414b0241a6315ab20b63c422b6be8572b5e7f249fa3802fa647febc89c8ccc22583c144c191b91187257235d857b9bba3b13db06be10a35d712c540e7bcc62373d76e5828be049b6462d8da931f24a6827d314f5c0ad266a3529fa9b47cb6eec425b326ab0bfa032b6809d82c1cc3e2427787a413daa7d3976aaf83ac08d87b34da219a92a631784bce31cc66693c75aa58c7c87a9e3a926b5229a4f008b85090f351694f66743dae3a59a86299b43c20522cd82f96284623ee20b521794114d1459fdf70739558123f18ff8304730fbc63f198a2eb992e7115e07f509dc58b1e2a00c314714b5162334861ec20acac85664d14057d2788207c01a7ae383c93971d850102d60ac0d042c648c100ed660ef8a2cad375ae1a21b11998264e86ae0561e19d971689183968a98be064486b8abc3634021f770e2581b4383aa3c938bf3aca4aa2a337ec06647aa47428bc027339f2802b9f135820f3a8bea06846beac4c1a2702c502e50d338fb80a590a564f48a6606a10b51e839a4034f2b906ea34b4d3c875f1ff6bb57797b076638e4b576fe8c5a490806bfd178b4569a69626001c8a5fa1582bf4bb7bd586296f9ae74724d7b6c9c38d25273e114fed525ab008b887b9e5871172cc393938902914a3ace06a41cf92f6da963e4217f6b1363f7273cbf4a342865a761371f24285113e74f7a770079157c0ba0700e6bb9ca99ae10b83299ca9445b8024e450cb6152fceb79c0c433753c0b88b21c71bcb38c643ae5e16502fd14c0aa8939219005a15180446a166e74933f46f41a68675692e25816e7a227808764e20c98d33d6c3ef3801d21cb37d2872fe76749aeb09976580ccd4feadcea0b16f00970f92acb21c560501728ffd648a3b658ce84640d17ad1564189385fe895b25cd30d122a90decaa0583b908f1481d7cab000e33fa07de8dc9627a85e76fabb4428a3376e66300cf12a0787" +}, +{ + "dz" : "aaf6eb40e596a5e3e8218871e708b089240dcbe7fd3641f0e5e41e071ce49107e2f8d320ac3cb0c52efdc753282f092bc39baf4a18783a48ea031a191865eb78", + "pk" : "f81037775c727839696adb115a704f10199031d9ba3d3433ecb50702068392ac97a2db354cb311dc39aaf9719c4f5a7c0401282ba4697ca8c70ebc4e179893135179cbf02820d6bb7263708b2339f777c242f4c34155ac2452cc21904580b381a964c281d750c15c42d8477e7708c45c61bbefc6928f191260409ac31a61400350e928a3b24c313a71020fd186f6e9afab17bb065132588c115c31ca8c630275b4baab7a98a778b97a680adb4611e6471683352b6928b7f0378105383b5f981923e800ff11ce6b64904ad3835c270cad0cb0a6e1b8879cbe152221e6e0994fea9bfeb9cf4f582e4f429170295a8419c984283d79b882bb420876588ae6403f207b3798d89ddc1bc90d7c91d7d07aeeb2bc0e491269281cfe93129c5283a03630542a1312ba5c896b969ac0aba14a289c0672b964a6cb1c4a11c3617ab30e4beb8b8864285087a15c574c833166c759741f493438a535918c0ab0e46926d195802a5cca3078fcf3770ea9644a69c730314f3d91b5e04150b670b23448008ee55f841c148a699387d919dcdc63a23966a43b2927fcaf47f2cb36935d65622214403256753ef3dcaf73d183c79384e7914bfe597363684355f25ac1042505361a04798e377791b5553c449927efdb48606a272c029a2da819a48749bd66a32091946a2a7a0649095da1193c1650aef47099456861519bc8701477bb5b01359c4772269735485b829835861496e437a063838a0419ae6877d0c493b5c3aa56777f3a727e0ee5825dc83ae9f4a51e612002748a5d1a21c1f870f5886b39a23e0cfa14b6151053580a8d8a306af04a7418c88bb5c398c6cd8f6529edfbcd601c049872c11381ab10c0267c0c8c2f614b16d92800dd0989fb2a23887ccf46401b864552105dc79bb0def57eb8b6974723a9164c2737abbdb793bfbf00a860a185d3a81a2257ca91e09f547c6acaf35ac5833fdd9a1f38a5b4f5e227b3fc692677766bb81f85e34de5b200dd077573f0796175140fa9c920522d68040518c5aa8f84b1ccacbe5be03e0a0789372c338a1b24b47a8bfb0941aaa8601a7937d5577fdab4a6d3094aee7c073a7632f417b63383bd035a351c3656b0a52c6e435d6d6699946585b6ea9e8568307c18c025a80e9074629dd70dae6bbdba296e0897c8ea895fc6b5b446d1000e4c880747798cd42c860c3bda63607b69a6c4fb88082593c1d965ac6cc71125cc56a72b60d1297605787819749d43be46431959ac29a01c3ebaab30d9a18c1c7998d9e29415ba0cd72c0d933086dcc1c20c537a6f296d88f29b5d2a21fe314999cb6037d539081120d60206eef1b1e1a498eb65268e94366cd8912d269b2d12a3f1b99572e6138bc29fa5520c8a6cb23f90859ea0a494c17fe7ac09beb658f260cbf3a5cdf9933ca1659f2a0551b881055406cc6b72baeaccbbc4b6964751afe07754da9a8b0b151f02972df2bc1465929c0be64e38e6c55ed237f182151d1a91e4253c42d05badb82cf3457e01cb59a96730b5007ae0fc37a3a322115c8560f0a2a1395a88464728c18a16bb249c168accc3165305a6584939105b594af244c2bb41405163e5bb50fde104e7dc604a592b9e22649c0686be9a8860794cee458a73796ed877b18e034f2f50b8441609cf53280f9c095fd67749871245a4c2bc9cb008ea3e44f424dbd56a7c734b1a322de366541c732fd5f74a0663a61f277301723579158ecd08bd014c5cfdb7610b61789d8b84da23a58e571a72981cf63cc49c59ccf045acbd3cbfed4571f6daaab9b23bf26091bc581cbe301674972ee4420e7e0740bed617a3c94c3ca3be7125c7d6242185163398458311937adad8462b0cb3d5900994f5906121c20f6731ac81a32a864ec383bd8310bd64a30f3d575d936426e721228b93c0c482c1be106f4ce41c5e0057116b30cbf44aa2a217b08b690ff891657188d3b6702ffa9d8ed7b62cf78f6831a13b410679e60fbf9a3221906b5885404a7326589681c1549b9459745455bae21ca799796065925ff980aaa68c206b17aad1cb9511201e53dca34d439167d55924018e7e513fa919a4573b5500a91c8ab61f17cb5bcc282939172217365ef694c98a440b09c883cccc114769b84ce736c5c9c52b050ea16a0e4b8c58465438b7aa11c2c98ecf4aea6284cd00c4229cb6fe2f90dbbc05eb935c85f1ca2afde0d54307949544", + "sk" : "41b21693eab370113852491e3791739eb8b3ba69a2c2542a85b4c536d840d4b90800a7a6062b7c98f920fdb11ba6b0262a647dee2570f422cce4b7673b51670be0694083c23ffb380025279c849a91d147ac85a3eee4c8ace51c314b21382009845bbc56c9a967a5bf25d1bd75908ccd0a5b86f14106998b27a41a38c365130a420569975da13bda305553750bc5b9402bc38646857bb50a97d016749cf7394dc35ba1f69c17b080a6961203514eb2520189b846d9597d3e443b0168028943bbfe80b1d0e4a323f61324352aae686b1aeb914dd33745da83f9451edde1359a630a4c79b4e9aa7cbc464b1f3923e981654f80922ef604465740938a9484137077533f4f7c379312306c6a26bad108cc16c59cb729fa6ca21feb2365f12e3e32c75b95cf9201bcddc2046f93893db11e35103303478f6a661e4747c854696d6fa00b47f3b18e32469e3b9312225b1a877eda5b2f17699ef4bbb5054961e2a7c445e70c1bccbe6613a4f332b380fb21565c809fd593e7076c42b9b891da4513742e45fc4e60934583f888f399b4a3a0054bdc3639b73f756b94edb5401fa66211d2bf7c714f527c48854a73ead8993fe1b3a851048aa638b2a5538848912f6672430273e82820044a6d6a6b4b80ea6a12aa1becf8b647292a2d328877c10d64706de00a677f0399e30b8842633e2246109a407465f096a1e4b9f14605387494e3f3cc7f200e4398b2c234575e022bce0961b0a8686537cad6054a81fc83b6167c7a855d54e662aa29358bc192a0925d00d15a4634453a494c96758aa687476a7b15075045684b51a82225a562c2d1c28b36ccce25668ced9ccd0cc58522d36ebb6c0368f67104f6c8a240b976c59ef5b46c62323cfe74bb95a55c8ee3b934253de101a11832cc91d685cdc1599da17362763abc4a63a0c13cba2123b76b391d20592c8799bf86054203307d770bc87696457962dfb39fa988a954532671818f6d7438ccf3c044599486e6b781933a45692e1fc79fad5a7d8fd8bde635ac05c631ace040f383b9e5aa69bf39243c711455f605ddac05ee905aecb6c971bb85c1ecbcb695810a713fbee75d71362e5b6777322528bc54a77b6a979ed7c48e9270ada7824814957563585334998fd6ac4566bb22da8cb18a425bdab55d61a1b8427ab1b817e8853ef002cf00389dc36a8e739c601be907d749b4165ca166e6a42253c897a6112d2994a0f492116181081356ab447787d3c8d399a807d48860668dfa2aa8890ca8a7128cd38cbff5eb5e6fc5a46c903eff075ab70a36b85958db922ca9172f53b7202744cf11452bdee486d44b3920636bd7962c3622633324a2bb5b82fd3225a0d83b9ffa6b433b19b49a11db2a19a7a5587553a4832a4dd2412502a575660bbdc1d9a23fc6ac2e7047ee9941ed3b99e7951c81d6473b440416a18332914d97b7c6897bb248876ad757c74d83950951c0d14724d99caf72d17462d006e4d0064d14057a2c1488c79faf4cc08114c9eb2c6ea68220d64735ccf603baa718bae17d130457835019e7e943a43347f7b3253e750bcaf71dd0f0a63d91c7deb97e270209a942a9512b635f5c704f830649909c7c1107986bcb7df1a191366f80ec694c179bcd9029f62880c60061627078b2d3277421169e45ae35f9991730159b005f50ca257ef3b1194b46dae425b9d67e1692c9f1c94da299a19aeab00f45c62449af52c81633403e2bc77ed6750eb91c1735411a32a9bd458029d31c1673c86db6eb6c739021bf1508ea97b902a14bbe298f676258d9260c9f7305d5d1248332069432941ad759f3488d3a2c927793add8ab08bceb6524f8b6f5103c2aac069d0c46f8c314d1c77a86a605db2a773aeb8b44ec8d12477970167ce70ab3a449276a7540313927e61239e23c79bb260aacf4c7de036cdd5a55a45a8a7b898fd8b209c6f643b4202b16187a87842b33f0574fd0a4198a7ecf7b46282b8344ebaad63ab34a652c22521561f2c74a68c485f4cf22735ccd203a8265ad5ea173ae4b8fb0cb4ca979ce33557bb09010767acc4b881f24fb94ccfa008a020e3cab56cba5c3c6c87d4bb6a2448a94c55bba200681d88878563b05454ccc7171a42abcc545649483418bfaa6c3b1e568b251962a75853b6634872529d31b32fa0c29f81037775c727839696adb115a704f10199031d9ba3d3433ecb50702068392ac97a2db354cb311dc39aaf9719c4f5a7c0401282ba4697ca8c70ebc4e179893135179cbf02820d6bb7263708b2339f777c242f4c34155ac2452cc21904580b381a964c281d750c15c42d8477e7708c45c61bbefc6928f191260409ac31a61400350e928a3b24c313a71020fd186f6e9afab17bb065132588c115c31ca8c630275b4baab7a98a778b97a680adb4611e6471683352b6928b7f0378105383b5f981923e800ff11ce6b64904ad3835c270cad0cb0a6e1b8879cbe152221e6e0994fea9bfeb9cf4f582e4f429170295a8419c984283d79b882bb420876588ae6403f207b3798d89ddc1bc90d7c91d7d07aeeb2bc0e491269281cfe93129c5283a03630542a1312ba5c896b969ac0aba14a289c0672b964a6cb1c4a11c3617ab30e4beb8b8864285087a15c574c833166c759741f493438a535918c0ab0e46926d195802a5cca3078fcf3770ea9644a69c730314f3d91b5e04150b670b23448008ee55f841c148a699387d919dcdc63a23966a43b2927fcaf47f2cb36935d65622214403256753ef3dcaf73d183c79384e7914bfe597363684355f25ac1042505361a04798e377791b5553c449927efdb48606a272c029a2da819a48749bd66a32091946a2a7a0649095da1193c1650aef47099456861519bc8701477bb5b01359c4772269735485b829835861496e437a063838a0419ae6877d0c493b5c3aa56777f3a727e0ee5825dc83ae9f4a51e612002748a5d1a21c1f870f5886b39a23e0cfa14b6151053580a8d8a306af04a7418c88bb5c398c6cd8f6529edfbcd601c049872c11381ab10c0267c0c8c2f614b16d92800dd0989fb2a23887ccf46401b864552105dc79bb0def57eb8b6974723a9164c2737abbdb793bfbf00a860a185d3a81a2257ca91e09f547c6acaf35ac5833fdd9a1f38a5b4f5e227b3fc692677766bb81f85e34de5b200dd077573f0796175140fa9c920522d68040518c5aa8f84b1ccacbe5be03e0a0789372c338a1b24b47a8bfb0941aaa8601a7937d5577fdab4a6d3094aee7c073a7632f417b63383bd035a351c3656b0a52c6e435d6d6699946585b6ea9e8568307c18c025a80e9074629dd70dae6bbdba296e0897c8ea895fc6b5b446d1000e4c880747798cd42c860c3bda63607b69a6c4fb88082593c1d965ac6cc71125cc56a72b60d1297605787819749d43be46431959ac29a01c3ebaab30d9a18c1c7998d9e29415ba0cd72c0d933086dcc1c20c537a6f296d88f29b5d2a21fe314999cb6037d539081120d60206eef1b1e1a498eb65268e94366cd8912d269b2d12a3f1b99572e6138bc29fa5520c8a6cb23f90859ea0a494c17fe7ac09beb658f260cbf3a5cdf9933ca1659f2a0551b881055406cc6b72baeaccbbc4b6964751afe07754da9a8b0b151f02972df2bc1465929c0be64e38e6c55ed237f182151d1a91e4253c42d05badb82cf3457e01cb59a96730b5007ae0fc37a3a322115c8560f0a2a1395a88464728c18a16bb249c168accc3165305a6584939105b594af244c2bb41405163e5bb50fde104e7dc604a592b9e22649c0686be9a8860794cee458a73796ed877b18e034f2f50b8441609cf53280f9c095fd67749871245a4c2bc9cb008ea3e44f424dbd56a7c734b1a322de366541c732fd5f74a0663a61f277301723579158ecd08bd014c5cfdb7610b61789d8b84da23a58e571a72981cf63cc49c59ccf045acbd3cbfed4571f6daaab9b23bf26091bc581cbe301674972ee4420e7e0740bed617a3c94c3ca3be7125c7d6242185163398458311937adad8462b0cb3d5900994f5906121c20f6731ac81a32a864ec383bd8310bd64a30f3d575d936426e721228b93c0c482c1be106f4ce41c5e0057116b30cbf44aa2a217b08b690ff891657188d3b6702ffa9d8ed7b62cf78f6831a13b410679e60fbf9a3221906b5885404a7326589681c1549b9459745455bae21ca799796065925ff980aaa68c206b17aad1cb9511201e53dca34d439167d55924018e7e513fa919a4573b5500a91c8ab61f17cb5bcc282939172217365ef694c98a440b09c883cccc114769b84ce736c5c9c52b050ea16a0e4b8c58465438b7aa11c2c98ecf4aea6284cd00c4229cb6fe2f90dbbc05eb935c85f1ca2afde0d54307949544b08a2ea8e2ff6fa677e3c2ba136c16dffd11094ad7f4ed4c5e7c11e3898a284ee2f8d320ac3cb0c52efdc753282f092bc39baf4a18783a48ea031a191865eb78" +}, +{ + "dz" : "6500f32c93415cfdbc0bd31d78d5be95cb9060c8cfa2013955b56f8b6868b322393308641a9a4647f230201e1389624a296b55192a9819fcb19ab77c25f95445", + "pk" : "5227748594cc5ac52decbb390cb6a9b8f989c7048017f52231125d91c51ea6174ef4a37b7cb505b4a029f44079e14b957ffa2f8f325e7334bcfb5b023b4801f5f576333c54ef0440b4f7c8f6b3afec2524e31943fd6323d8f2300ba1b8095309e41c1ea6016de8f6ce4af647db19467e492c1cc12b5b5426b8339ea122473d1b84c603babba7b32534587145b360474a8483be8b06a6086bc5666a9b5af8b4eda929fb60606b85305c89cbd26a4be8a6b4866808fc2120649a60a3da2c64330a94dabbdc4cab2b956b2a5b7dc9e7cbdac88a71d5c06df3b192c5cc5dc6b7d10b07846026a3f5cf0e5b2c5d1c80bde5c3ca231ac908bdb7054190e77d54d40b9e7534dff0b36eb92652449aa4305967e57c9e358f8114544e0a5b8ff2c490c4a3267a405e38653449b617f26c6a3a74033ac483c074d5d0029d882f3507a7936845a6ab4d33bb4dda806759852488a06731222681326e9c6691077a35a7791734bc6b8e2511ab961bb1f17ee411ae86ebabf1b4968da61faf667b507450fff1a3392425457ba4625086ab1a871c8386982a322b82b7cf198ad639060eecc1c2e40bed7462ce4c6792764509e5cb9cc28b5a71a26d52658c0b5b951180f903bad708ca9bf7995e4595b8a009c614406c669468c1b4fa3740a9e91c64c03ce4a3adecd19a716a82530a508970cf16fca38aa10baf9810a8c3334c7b4a29904b7f72bea3e61505107e641c2be03ccd6c0546d2698c110caf2f194789c616ada3103b5c7f015991d473837e9451c9cbc9dd02333636bbbc825dd0da77a6731fbc3a831348cf1a3550166b72b4d0c59a5bb31de1829cc77c235b73bbdba937e5b45a456198b218b641be8c05ccdff9746bd64fd5a759a4886d3022cb63167aa3f37655a55e9acb9671262aeeb99f6d5618212419b1a41b7c260213b86ad9c995294b9e96e77ba66a40f9b5243bb38e6b7a7311d7c29c9272f98308a5f68c58cb111e33964b797a151588ee515fc0f032b054c7dd35ce5c734b8887465b0b4bb58c491f9953b1133561977f0c25401e6b577cc1cbd555bb8ba7760fb972a6b2344d2222c0fa575717501b3191ecc598bc93bd145800d9924c06c36d0360aab9678e93138d266572b305b7ea69a6ac8ca3ed647137090cec1227169754b49324f029776ad3c6c3e33e14170265296c1a7056282074a64690450555945a87ba57b54eb3595df82e81c1552f19c415c6cfdc0cb5fb32c3db060dcc208b6beac782668eddf9986e0a1bb5a0941a3745ee0b73ca0a5f98f5928bd7189ac6b20205555050846edb51a75573e9011f2d7738bb8c58bcd16795805f03a42aff1b854d3981002614b39b90c6f8bef32bc0cdc085466c8f55c7935b96157a624665404468783478d4b121d6b6a026818dc04515d0b98f9a1634977d3521316839253b7a847224c3819802d6b84482988122a7c87d069a13315fbaf56c9047c03641b4b008070bd885f1e3252f16918cf03af8634a8f7291e7b64df4e14feab909c10c7fbed446bdf2557d8a96e2cc17cbeb91515a2ff0b78bf0a21abcea847deb7311e2a782a567a6b1a57bf105a4513de2c378b1c0186909838a01abc000a829a9503d8c12f374c0d48a32c6f539a2ab28ad12bc49507e230c9a3881153113c1ddd446ab513608a567aea199624c98845a3adf90a5a89a3098091f207b46f28a5659f54c75a01347e18a11db75f9247749c03c7ccc6b9ed722da1b118d3c2760216c792b7f2f406397bc9a7f18343812a09e97a0f6c3c3b87179888a6d69b01b9d8c4b8cd215af5b76f7249747aba3537044f7991bc30854eb68c2f6f8b404257cfd6043a3a327d457651f0b600415a977d1cb30904bb853b4dc380ba4802b28f7c479fa7705b3a6cdf8a99ce2604af2670ab6a751236e08321d61d92a27412febca600fe30850f3c86c647746a65b1a9210adf34003a39c16ea69a626c73929567f1b001923b4f0726337f90124b74e500007ee8938cebb15e1f993e1ea0726d04a5e3b52579c625ef79ebf66485083ade6b1bbd0c9a953092fa80755f1471ff7f063a2f0013f429f155609142a685039c0aa540b3e410654803c7f281ce44b9cae5842f7347b29336b5125586d151117f3afe13669bcd7991068bdc68676a7f30708906db24033fc5822b8cbe33012f5e916c80ec7dfb3661e433431ccb796ba70c5a1ee85d63d", + "sk" : "79949cd3da852b8381b94853cdc981b74971879b0555d5b51d5ac57707a8d340c2070c9395214d3a6c0afaf0a675f45f4fc779a7443219471570d43bb73caa4c9501f2a220ffa00b60695b049b8543cb0aa94884be42276588c4a211908dc979a0292a9b3c891cd2c59e39bc11b725d66ccccdcc9d35a03d390ad0656bafd8f9a778222c8fa753f4d78bb1792e87542c8fb3b71043607d77672b1a6a7f7840eb953d3290cdbfb78ab1535aec0544bb6a6398466eb1711f9ce01c42d2aea9fc255d694bf4c02b7e1cb6763b274807b1802aae3a3a95e57c78002493faea627bf5bacb17a3b1085baea7802958c9bdb398377629b8c8c03057497bd542ea4c6b28c2cf0cf316cd820c6cec0e2bd121664c252b0b570826ad17490363232d731b4f16b68291c78c3ba252ff110bd756225ca82b38e2b65d9979bd2b7ea0b30d83461f6e09219af2ce1309cd99a87de718cd46e40c091603cb572e6de993e0051f84b55db3ea6c7a64b9c67bce6c3c6a0bf02cecf39e93d149ea38b585d77be9726e662860dab465959588c9225303c8b4ed935ded42721196747f104f02c17cdf3520f2435ca0f963d9ab8754f13b22ea157d0c061ca65d8a363c8c4278512888ef6111618c18be72103de324cde4cf16f26f6a8421ae61aa867b3854d54e0163811a3843a7984e815a26a135ca43d249d17c9d93f8a742037db4d95b2fe33fa3da0db12b7247d665f7488ba34ac5ffb0cdd0e123e812b6854739bfa740792b0a5038037c59991aab615f937caf9b89e4b9742992c5534939e20353c8573d9ee399280984b446a851868775a7a0da729d8c594a5f5518f0681e22069326b1146d1213fab35b0c811d990b529f7c7f7d11645da77ca0f081ad592291ba2a0e15a880832ed7f02fc70908366485a9562cc45888c1304aeea26e9ba961bbb53c89f79265a962f2c72b39f9cb43118a22abaa91e96fbef1c42e6334aa258ceb739bb17a24aec2a8f59b972cc7910647cb1ca86031ea4b80c97308697cc4f414f7575154d51ce8c9bc9309c92b113da36a1915934a64cbb358151dc28186c7f71bea603c73f1c5aba4a6da017f10b16053d77cc92751bdf8c59220b5eb574e1f51a374f337d663213d3756f9096b6b9421a692a4820943576ac2a10246207aafdeb8acf6dc32b9a6cab2f1ae21dab2a678a308e138298a1d947151b5743d8eca936963271ea15d5195304d268d87ba70e1c1a9ded02ef5da2e077cc8a576b433716c419808bb187c9fec2371832a09360525b49d89c84f84d1c10f1a7514077d14515ea63918a76577f1957cb0cc393e7122c097b51039869765342aeab8106398ffc009e0f403225b2df37c3d71f93c78763abb49bf23e7a1c3a1695986824a54aeda43b3f7dba478097cb9019390187a6d9b8d9b684ad169ace6f1b0fdb9184fcb15b0e724fa17b986576b3f5986a5fc603b466d232094402b0571a82864367dfcd17a53c3c74ae4ac0455af209b05371174312679ee5a8d1a3326b70246642631a479bbe51bb73581549f7957747b87030ac019b454522b31cfa9cfcb7518deb670bfb4b62cc964109c6773b885691b199259412f49b00c5ba719db7162819e20984373175170f7a16de42ef8770e55a6bb6d98748f9a0e6dd1335e2669764bc2754c7223b8a23986b5c7d49d3ea4a5529422a98c7b4de1205465b357a1c8fc188eb0c4797f847602cba59a20a4a2842bc05a4dfac46b1469be6c434e6feb017be1cd206247b6742edc1141f9b54fa00a8f757887a4d04d0fe892db899354e73442265251b30caa18496aa22806425f0da193f4932bd057c8c7a06ebbc3cf373205ddda04efab885d12396b09c1df636dd5d5c721f103c93a18b5227ad0e3339d44b804b65a6c628f71fb5ab900a8ab9917c94a51540a7b2f9badb405853e9823d30a80ab9613556555b4273486927427942e7a6caa1a727dfc59089f540a2beb9802c91f324668f78a9e4431c6255603c5f15642e60a0dd843f8fc610fe102716333121105bedbbf161b77d0bbcba13296967a68c14aa99a6765718ba3782b3835f7571177212e0763a5cca4492b94ae59616f9b5839141af31a774fc32fedf0a3408c211050948c24a722a48ca6913b32305e7a5194b7e187bc255f3618532075355227748594cc5ac52decbb390cb6a9b8f989c7048017f52231125d91c51ea6174ef4a37b7cb505b4a029f44079e14b957ffa2f8f325e7334bcfb5b023b4801f5f576333c54ef0440b4f7c8f6b3afec2524e31943fd6323d8f2300ba1b8095309e41c1ea6016de8f6ce4af647db19467e492c1cc12b5b5426b8339ea122473d1b84c603babba7b32534587145b360474a8483be8b06a6086bc5666a9b5af8b4eda929fb60606b85305c89cbd26a4be8a6b4866808fc2120649a60a3da2c64330a94dabbdc4cab2b956b2a5b7dc9e7cbdac88a71d5c06df3b192c5cc5dc6b7d10b07846026a3f5cf0e5b2c5d1c80bde5c3ca231ac908bdb7054190e77d54d40b9e7534dff0b36eb92652449aa4305967e57c9e358f8114544e0a5b8ff2c490c4a3267a405e38653449b617f26c6a3a74033ac483c074d5d0029d882f3507a7936845a6ab4d33bb4dda806759852488a06731222681326e9c6691077a35a7791734bc6b8e2511ab961bb1f17ee411ae86ebabf1b4968da61faf667b507450fff1a3392425457ba4625086ab1a871c8386982a322b82b7cf198ad639060eecc1c2e40bed7462ce4c6792764509e5cb9cc28b5a71a26d52658c0b5b951180f903bad708ca9bf7995e4595b8a009c614406c669468c1b4fa3740a9e91c64c03ce4a3adecd19a716a82530a508970cf16fca38aa10baf9810a8c3334c7b4a29904b7f72bea3e61505107e641c2be03ccd6c0546d2698c110caf2f194789c616ada3103b5c7f015991d473837e9451c9cbc9dd02333636bbbc825dd0da77a6731fbc3a831348cf1a3550166b72b4d0c59a5bb31de1829cc77c235b73bbdba937e5b45a456198b218b641be8c05ccdff9746bd64fd5a759a4886d3022cb63167aa3f37655a55e9acb9671262aeeb99f6d5618212419b1a41b7c260213b86ad9c995294b9e96e77ba66a40f9b5243bb38e6b7a7311d7c29c9272f98308a5f68c58cb111e33964b797a151588ee515fc0f032b054c7dd35ce5c734b8887465b0b4bb58c491f9953b1133561977f0c25401e6b577cc1cbd555bb8ba7760fb972a6b2344d2222c0fa575717501b3191ecc598bc93bd145800d9924c06c36d0360aab9678e93138d266572b305b7ea69a6ac8ca3ed647137090cec1227169754b49324f029776ad3c6c3e33e14170265296c1a7056282074a64690450555945a87ba57b54eb3595df82e81c1552f19c415c6cfdc0cb5fb32c3db060dcc208b6beac782668eddf9986e0a1bb5a0941a3745ee0b73ca0a5f98f5928bd7189ac6b20205555050846edb51a75573e9011f2d7738bb8c58bcd16795805f03a42aff1b854d3981002614b39b90c6f8bef32bc0cdc085466c8f55c7935b96157a624665404468783478d4b121d6b6a026818dc04515d0b98f9a1634977d3521316839253b7a847224c3819802d6b84482988122a7c87d069a13315fbaf56c9047c03641b4b008070bd885f1e3252f16918cf03af8634a8f7291e7b64df4e14feab909c10c7fbed446bdf2557d8a96e2cc17cbeb91515a2ff0b78bf0a21abcea847deb7311e2a782a567a6b1a57bf105a4513de2c378b1c0186909838a01abc000a829a9503d8c12f374c0d48a32c6f539a2ab28ad12bc49507e230c9a3881153113c1ddd446ab513608a567aea199624c98845a3adf90a5a89a3098091f207b46f28a5659f54c75a01347e18a11db75f9247749c03c7ccc6b9ed722da1b118d3c2760216c792b7f2f406397bc9a7f18343812a09e97a0f6c3c3b87179888a6d69b01b9d8c4b8cd215af5b76f7249747aba3537044f7991bc30854eb68c2f6f8b404257cfd6043a3a327d457651f0b600415a977d1cb30904bb853b4dc380ba4802b28f7c479fa7705b3a6cdf8a99ce2604af2670ab6a751236e08321d61d92a27412febca600fe30850f3c86c647746a65b1a9210adf34003a39c16ea69a626c73929567f1b001923b4f0726337f90124b74e500007ee8938cebb15e1f993e1ea0726d04a5e3b52579c625ef79ebf66485083ade6b1bbd0c9a953092fa80755f1471ff7f063a2f0013f429f155609142a685039c0aa540b3e410654803c7f281ce44b9cae5842f7347b29336b5125586d151117f3afe13669bcd7991068bdc68676a7f30708906db24033fc5822b8cbe33012f5e916c80ec7dfb3661e433431ccb796ba70c5a1ee85d63dc27bb236759e3a2af7553c03894124a6bdd3e3c87def1f1bf3e01fac4709aa9b393308641a9a4647f230201e1389624a296b55192a9819fcb19ab77c25f95445" +}, +{ + "dz" : "7643cef2d62cc5aaeecf754653ea62294cd2208e5bf3ddeea209e3dc45373d49eac9d531a532770837a854b4f5531f6e0c8d6c10183b30d3435498c2dd142951", + "pk" : "03a595bc577a703b4201253367762bdc7a8d14e60784e5bf04ac62f5cba8327c781122427a83800c9b342792ad6e93bdca2491720894dde616a9a9674e771439b8704ea57d70e9095e05a03f3155c3007b1ae0467b7c7bcfd67a5dc679c8f6ba53b44c110560359c65ef6425f667b5ebf967497119fc3b0bd0600c93fa269f349bec1397c4b23bd851a0824b80b664070622860aeb98f2b2c9349c8e0cc824f5b0386348a77857c277496cf10046dfd59765dc9d00b013c3002060737e668cb6440aaed4f3220f789826b579359a3338b91f6584b27dfa7324f61859370795568de4cb39c4b1b015fb693f42c09e981c7c5658d1cab448a947f3a0caa999625131c9118258ab7635d78caeb86ac5c100b30a57216f586901d1863e27262ebc2e3ffc09ac4b6ae45c968fa81aac089a04e7393409799e853499888dcdb29690c12a7e512891421f111a2189cabc1d00a2fb9878c0057144bcca25c9a3f1a2c3b92c61261a3557177628a252347355bee55dcec7be730639fac28e0536c0636bbadbe97674d83b6c209442b34e37d9a43d508e849b3c21369149a7270e56646d984effa143c87777083bc54270b146291d8b4cbafc6ab7e72a871469abf3018ecdbc0753b94ba98140e4956c80913efffb22ad687921560055f466b1744e9bc851e12648899b7665a18a71130c1e4a47c26cc8f1a4972512186fb89a740cbebc6553ac3c088b01b21bd9c47cd5578cc58fc4697a0c756e7f860f91086aefb4cd02d184d294acf1f2872191851f585d96d3b98a755bdce648e8d7ab5e8bbbe8ba0b752973fab007e5390bcb6ab750f8aab5c907042ab8f49acdc47271d6b2a2ee148f13518243809fb5651f6da4379225bd864597aa65343b21b8f8753ab2994d981961cea24b7f780643b5674520b7fd11793b1a4ff110aac7516c1861ad54296b917c72e281692797af7a594e50c35d958436816036d13348f81851bc5332f6e1b55aa575af0c0035432b10abc89ca5cf19170d9537c413d1c7674992467323ded94c4c6b694558cd3ed45447bc5fd3979a68427916a9297904b02d48918d914ad9e88c99b5c28a6ac037248be9d3054adcb0f3746acc2c0a6711cbb1401c6d08d07a947d3bc35eb7b477ce19068fcc744772a126f98789d349fb7c58d9c91cb1ec4830ca54e2e44dcd27b45c48ae07e84c045487b2252178075cda577b26704803a94f9b07acc6e815a75696fc927c1cac2c5be290855247a4546288a383c15b05714c1eef845e9bd70ef5d3284d5800df8ab0a6522372893618d6a28a922152b1adc2e93f60813025d2b15667947788b93ddc34f05374c9997a0ab8b72023ce47a50c86ba00c86a37e33b7516437a23d37d6dab5197a88e823a5129d656af31b755a89c4df21b520b3cbda5581200c9695b497ac2b0f582a42ba28b537a7024d30c127907bcc1667547b79ae655b4143723dca5ec494d851b3e3eb763f4809cb045ca69407627cb49aa59099b050c26151b4d89cc55e762c1e358f1679b7f30a8cdc531b80580beb1b8495487d2d0ac3a9a240ac1acc457b53f6aa6a580b79d9cb953240e9bf90e54644253dbc79b2b3028e26ac8641042f7715d97190e64ca4e13624530a882bc53b2c724f68511021641ce277d0ae32d329b9ff554502ce25a294a3829c770e9565512d52f08211b7fa583ca675491533d14813ddbb96ba4f05fd9b95cca052b7cf098000882be1c2ad9865e4b9b0834189f91d5444791a561ec7baae5c82b09893a900920d6bf6df1391cf1a2506acb25d79f6d441a17bc5eb4d133f5059ae52565014939aaf208882631a531582b486bbd72850a0724dd52a225c40fa2a33f312c16a426a3162993cb7370d23c300e2a5d2a70102e9aaee23b715c11860386c4be5080283a4727954f2c5197e6125bc2c28757a63d46c0b322299e5f483edb10caef28c44cdcca5a9bc9505199e7da28286815757a63ff83c7149bc0152a674404b3c2c06949950f7b073f537728514b20c676c53176002a8c7af2865ebcfa57f1226fada60eeae67fa5417ea4b863d82c3871c4269974bb76e3338328c00530122e38c138e42df370cb51830980f9a6b4829af71a7149a28379a251530306d0719d0d6794f89750ce06c27a913832a9595b9a9c1728bbdc4515cf1afe1dcac211a3135eeecae628aac9538ef2fa7dac989ebf18207def", + "sk" : "01ac758391018442afbf29af226cac76c6bcc2f256e0454802a968d79b90ebe3252fc57781952afff183ec0c7b11ec71a6868963335825c00cedc8089d822e8470978d74c75806654ed5bf178ab7f1a658440b0d28996b4fd23cc4104f811882a1129fbfacbd29ab2f278ca869ba0722544f0d28c879f0b1655525169a723a09bf15cab7d3a1ce835294ae77c3d55c7537478660cb696025cb0db431fa42349ee5266d5c41d92c64544a6a79d9099623b513190946b24bb2707259eb40ad59510496bd4eac68ba9c14058665a465578e2bcf28068f54b47c957a7a1d1004648b2332a113c85b0261f1474718c95b95553e083b50b69d455764c6718fc286348c187fb0f8cdbc8a7c37db679fe41d853769ecc03063aa1dbb215f044a025ce98767e7a52fbcb44a9c67b5529e3f9b9953640e525471511336d993b6e741bd9e8cc942a1219fe23835384ac0f990f1646e487aae445065ccfb1cee5790342b4d9594687bd53b871b2ef34c619994093f368049a6a483c007ba115af85c976fa28787805bdfc158f64b50de04ab3b82ba026621ae262d25c4bef55776fe7ccfb15524120171e806bd413300089490d233c00fd20783630e2bbc5a661a0700cd1181c0559ed5712e0949c720cf2b15b776240b7535b76a237e37a86b81f6b59d4418c3a00624166559e180e18acb91157c715c0030640522eaa523d76f073a1279b570eb08b14bb697c93345c3da33b6d65f5ba668c80477140c22a56700feaabd73f90237c54754f377695b83a7d5ba8ea4cd9934cc83a3c7abecb927e1cb1ec405b58a7c4a010d3df2a9b48c213d0b63dfcb1533602d26614c08995c561a3bdb4933a6ca3defe340e52a20e3894e8bb95657e8ae363b928b3648ec266193d44c11ba2e47e2656d54c3a13558510c9a739c7f857b586f13a5efcc403ad347eec8623a3b41f8447301e1bb512766eb803fc1460d05880d8272c4b38a03894c2f41b1c4f08a416bf06b3595070e985768132bec00c05f5ccfefca9a1851c9b4100110051c977729b7d3446edb2ec1d02820d189fc6476b6aba6e08021e5000fe8f20d8c48b75daa6d8de2c0456345cae60309589ba9c289c6dc664328b5ffe10610a5b2af41053e21c8b58c7872ca332a8b6d12e75f739a6bfda88e85690cb35c5952c1a238d2b82ba0216a44a9c1d346188ccd3365b0f0e66007b606e04ba1d8c2c08cb6a901f491ae6c4442417a86da9d7051812066a652ccc178c0be52b304dfa4b6092b8d5e8486d4918321b6537f883661cb8ea4596c804c6534c40404f992841309f272cb61ba90d7a439dd204d9d7369523087fa2818dd56a712227d96f026f1fc1d4a3b272475beb1c0a398189fd392b0112ccaec4704b7983c10da4b1735ad78cbab8144b485f2b721193b1a9654eb734dfd2b42b50078db163b67c192f014becf74847bf47f19e5a70eb6b28a717ca908a944ac6575f43d048950016b69bfb86e21e012e15435cefc11e5b6813ad37942bb646752b82ef9c76f99a77b0707a8338a7528c01981b2b19cc64be2ade4e384aec67773912e0dc9c8c5d431c099abc663bec1f64050517acfb8584323169c941d1dba6c0be940df049e7bdaae440614e9c389a5817e54700b1710a24467146d124a12b90fcd18a964a8ca0b8883ab26916ec339d39133981570966083dbea8038716d6a574a03710477bc7776f7338c435c4ff27ea3b42c315700d327757b821117595026392e8526ae12c51b27752499cc02faca268594bedfd3637d78abe703b4a47564f7d78f87726e6ab45e814493e8103aa0255c26cabdd1321205657878460afc005bb952482d672f8f9c4196282d5558085857a83bd43ca75805557898d49a9afa414d6d2ab315506cb2879ff7628982588b62f2a428e21516c47757e36a1ce0236d9a074cd2928c043066ca3a3358b6d8065d8ac8458ce374ac71c0f6c6415faa870b760aded1668fd09f00dd2650dc75b426228d23b579204843cc0a2c9170b1155d7e445f93788308b316b9fb2c3b3c6ee79026ebf611505bc91a476baaf65bccf86091010dd14b7456e2a2ae8b0cf7e655ff251515f6627e01b1279bb0ed640d266c4b9798647fb17c09cc183f2170e9d8709f537cb6e7911ddcaf969c438c55623b89b037708303a595bc577a703b4201253367762bdc7a8d14e60784e5bf04ac62f5cba8327c781122427a83800c9b342792ad6e93bdca2491720894dde616a9a9674e771439b8704ea57d70e9095e05a03f3155c3007b1ae0467b7c7bcfd67a5dc679c8f6ba53b44c110560359c65ef6425f667b5ebf967497119fc3b0bd0600c93fa269f349bec1397c4b23bd851a0824b80b664070622860aeb98f2b2c9349c8e0cc824f5b0386348a77857c277496cf10046dfd59765dc9d00b013c3002060737e668cb6440aaed4f3220f789826b579359a3338b91f6584b27dfa7324f61859370795568de4cb39c4b1b015fb693f42c09e981c7c5658d1cab448a947f3a0caa999625131c9118258ab7635d78caeb86ac5c100b30a57216f586901d1863e27262ebc2e3ffc09ac4b6ae45c968fa81aac089a04e7393409799e853499888dcdb29690c12a7e512891421f111a2189cabc1d00a2fb9878c0057144bcca25c9a3f1a2c3b92c61261a3557177628a252347355bee55dcec7be730639fac28e0536c0636bbadbe97674d83b6c209442b34e37d9a43d508e849b3c21369149a7270e56646d984effa143c87777083bc54270b146291d8b4cbafc6ab7e72a871469abf3018ecdbc0753b94ba98140e4956c80913efffb22ad687921560055f466b1744e9bc851e12648899b7665a18a71130c1e4a47c26cc8f1a4972512186fb89a740cbebc6553ac3c088b01b21bd9c47cd5578cc58fc4697a0c756e7f860f91086aefb4cd02d184d294acf1f2872191851f585d96d3b98a755bdce648e8d7ab5e8bbbe8ba0b752973fab007e5390bcb6ab750f8aab5c907042ab8f49acdc47271d6b2a2ee148f13518243809fb5651f6da4379225bd864597aa65343b21b8f8753ab2994d981961cea24b7f780643b5674520b7fd11793b1a4ff110aac7516c1861ad54296b917c72e281692797af7a594e50c35d958436816036d13348f81851bc5332f6e1b55aa575af0c0035432b10abc89ca5cf19170d9537c413d1c7674992467323ded94c4c6b694558cd3ed45447bc5fd3979a68427916a9297904b02d48918d914ad9e88c99b5c28a6ac037248be9d3054adcb0f3746acc2c0a6711cbb1401c6d08d07a947d3bc35eb7b477ce19068fcc744772a126f98789d349fb7c58d9c91cb1ec4830ca54e2e44dcd27b45c48ae07e84c045487b2252178075cda577b26704803a94f9b07acc6e815a75696fc927c1cac2c5be290855247a4546288a383c15b05714c1eef845e9bd70ef5d3284d5800df8ab0a6522372893618d6a28a922152b1adc2e93f60813025d2b15667947788b93ddc34f05374c9997a0ab8b72023ce47a50c86ba00c86a37e33b7516437a23d37d6dab5197a88e823a5129d656af31b755a89c4df21b520b3cbda5581200c9695b497ac2b0f582a42ba28b537a7024d30c127907bcc1667547b79ae655b4143723dca5ec494d851b3e3eb763f4809cb045ca69407627cb49aa59099b050c26151b4d89cc55e762c1e358f1679b7f30a8cdc531b80580beb1b8495487d2d0ac3a9a240ac1acc457b53f6aa6a580b79d9cb953240e9bf90e54644253dbc79b2b3028e26ac8641042f7715d97190e64ca4e13624530a882bc53b2c724f68511021641ce277d0ae32d329b9ff554502ce25a294a3829c770e9565512d52f08211b7fa583ca675491533d14813ddbb96ba4f05fd9b95cca052b7cf098000882be1c2ad9865e4b9b0834189f91d5444791a561ec7baae5c82b09893a900920d6bf6df1391cf1a2506acb25d79f6d441a17bc5eb4d133f5059ae52565014939aaf208882631a531582b486bbd72850a0724dd52a225c40fa2a33f312c16a426a3162993cb7370d23c300e2a5d2a70102e9aaee23b715c11860386c4be5080283a4727954f2c5197e6125bc2c28757a63d46c0b322299e5f483edb10caef28c44cdcca5a9bc9505199e7da28286815757a63ff83c7149bc0152a674404b3c2c06949950f7b073f537728514b20c676c53176002a8c7af2865ebcfa57f1226fada60eeae67fa5417ea4b863d82c3871c4269974bb76e3338328c00530122e38c138e42df370cb51830980f9a6b4829af71a7149a28379a251530306d0719d0d6794f89750ce06c27a913832a9595b9a9c1728bbdc4515cf1afe1dcac211a3135eeecae628aac9538ef2fa7dac989ebf18207def1330f4828e22a13ca5031217a3d8e6f8ed708a7026e1a96d8ebc4fd2f54b5051eac9d531a532770837a854b4f5531f6e0c8d6c10183b30d3435498c2dd142951" +}, +{ + "dz" : "f8ee95521060c03bb8dacc79f7eb7db640f545f315613a35d447a09e504cb4e13fc3d8392cb53f36ed647364a04e37278a0e0a45b720f4a75c580c9920eba98d", + "pk" : "de62c02cbc473601b03f5547f1b4a8078aa079c4cf39c56f88925a9383b9a0f57b58741760c58d2629c5d70074df007e715a3f9344755ba908a4a310de73150a79a9ee3957a730687f4b2e7df025c1d699c254af6642bfab84809ea9a3b35410c7688b296a3da82c6cf6790b48fa3f66f5b651912e7939ab76b0935f49c1e0a25422365974698c9532ad00120bd2ab10a8d1a78ecb392e6892624a3f96b2758a423246d67933eabe6ba2bc019a031431338ab546b3154a80945a9b31bb5f9c4071a4b0ac4b1b85b3a11ae1371db39771259936a27ebec742e7d6282f19c4b6ec1a70085ec6cc23186c8a29f4c3a1d3ade8912e3e238f024cbd30e61b1ff2312c91a2eef9cdab68446bcb64ae505c32f0ca5d02547c3b2343962df8d384bac81d15fa3bd2a116b4d9aba31041428ab688f950809c94404b5c35f303d9852a0f029e609126110b64e310c81d634117e3b3e1994ee2a2799600aa38966e00aa9450f24657a39b4901764c3a267f2018363950256a69d5b0240f368bfb238fc3abae22dc2f3fa6c9e7f055a8712cec654adc039c49aa1d303158e05b0ee4f1ccc0e07cae74047b603671b9704e70646cdc0b1d1423bf3c4fca6612360269a26b9731524a2117a2b686131708470ab6c1ecec857465cfdcaa5b1506abdcb6a5e379bb4e358462f802c2a81b26d0091a9a281a891c06737fda60afd65ab7c7bc4d97667220ea69896a46f20200b0333546713d9e685d8230487bc39b68b170105231839417fa92aca1cc38246b3d0da638aa28c907c823a1fc779b7626a1146645db0582e23115c64ca6468bc21a480385b27fcc28c0e6b8430a270c5061012a619da7138ca97da7832807aa4f338a3983170b62145f36a35241d21c13c61a1044b5bbd2232f5c16f106ad476818f83920f650a87dd80c3213680cc1572b0625391a92dd423e53dcc0ef58ca376b18a46b8ba4506878f38c88d814bba280575235b23107bae8c1f443a5e9c1058c904a09366b50e7b531451f8416342267352fcc7fb21c05bad69bac0967778c0c2d48a60980ab5b7901b84b54f1a53b6bb09b37d48dea04838193657cc7b47b436d4dd36cf9bb4bcc552700f98a88a850dc009b00bc41c9f552e5b346416024065634f4d768cf49bba831758af42e408668aa712f93f43658c48b80a72bfecc0258ac6fb10c51ba665e8f25537116ae53336a8f3a0d2101b705642c5891b4500ac61d023398b35a21e37ec6c9821eb46c348c594590941fa0cb5d88ad32c3165cbc3569e15960dab8f53c16d02320b7c8394971c14c5633ac5023d572608c60a726d50b22dc3696e7c352fa6faa0c8e73127ece085562bb8a86ab6628149292a750588aa90d268f5fa618b559a4f8468218985db9f4cdc1f65b4644cf585a1a8057431985058476cfda6ca0dedb2fd77917fda88d799709c169c01e90c5528a9ffa144636334d8cb3a1cb27b81df55c9205aa1cb43f04ec29beb19539992846db361de4bea0a7b045749609571639933e6c105221782033885385c5036153ab3ee68156f0abcebcc67c9163fd09cf2a50910c8a5e50ebbaecc030ff38b041c3513da677f78b253d7c5d9bec993f85aab56a21502b1ee66922ce9995eb83376ed309b1f66c9e9b46436399364496a51851d48ca06e342fd40a6c64748d6db5a9bf18893d65a9fc3b227401c9410888287100482438e604cbac435abe040598f5cb7f07aecc23b6b38a95f9cc8ebbcb4f5cfb17a8443f89ea8eb592456da09fe9a36bb31a98e9e5372d4bc83f9a7509da4ad87036581b27844b79a9753bad9a476ef64661ca2a5e49797fe161159aca36f017d947b66d87833383c9eb593313054e00867a81e0aa6b1a8493a082305a387f8c50024a9f682c69ca0aa180eb8dcdbaac44f4a3fa830bb056352095c2b8b65eef62775a470638c252f40c8137d05cad7c9508c3c34a6b29e6c6431b34882a3526ced7143da2bb9733c2ef816e28d3a1372b418ca595ba593b18789b7c6a411e27acec3b4246e8659a2330c628436d21722536858548a280588cadab316411b5edebb50ddaae15c32ecd74af476b3d4d834c1047376001cecac303f5c1bf7afc7b63e8372c97a8fb68837064294527799a8874684a81f6145ad7ebac7a5cbccb696472ca98fd95b9ba4db7d8729965aeb56b8ee101d0b32b6b80a772fa80e70598b17e84fa", + "sk" : "e747a3e56b5da1ec0b2859be85084ecfb60144b5ad600a4bd5f31ee866b72bd110f6111653124f695b75dbca4a5aea5c17c237d3e5748d842830fa2c87454960bb6652f5b0108332ef3024a2346e5c9ab71d4466330c2761f7cbfa29bfbb51931970b3a291179a1139a0e23e46b62dac796eaac32b4225c7bba9638fc428d3d4b691e5263c3c586d8abb56a313bdc69dfe323bfa237f27b046966c0748128ea32c9f0b34015e6c3bc8578dee1465f63c92e2e197e4e2ab2a76a9a41bb57b97903808472255b2f98bb24fdb4e8657ca5ed0cdd176931c934b33bc08f97646f6e7ab9ac565b7c04f26d12c44228e36824838c84b2efb0b5db6126b1b54614521c55455ada2002203b12954652c84b3ed26163b70c8cd5c76976075bf323d1f7984e2ccba31fa26fbe82a61895504abb81d660da8943bf6c29f16b72e59965813cc218a8635380044d40bcbcb728d9c37c375a975e619524e4c10d7a73fd8c400694ac396b384699bae098c07ba1483c834aeb3f1222d753758f3458fa2b579f3a156d0a27554a27b9192ea872ad9a83d137a1ef1f3445458761348ab6f40a0b8121f25f56fd9e7cb57318169768b46d71c7c41914de73838fc4adbeacf5f7778adc5cef5764f41b8b5b0e1aaaa594eae08b84f1b2fa8caa94eb46e2468b090832f9afcb4b543a61a5b572de2b79967c03d97cdfb5c0cdd5166dd121f8e1552780667377783c7e14f23ac2a4f2a3de89735c9e095dafbc72fa8351cf5203b7c9e96db2f5926320d8aba5a2750ec7668406319860101d86b92d4fb00f0fc75d8e3b344573d70449fa2fba847d399ee982540ba92a8149c24c411d4a13154ca92ab5a8a2be2942d45370a1a56e3ab715dcb7864b9956f2aceeec963d34cc3ea33cc9ae700b58c0953011adba08c115574a377a71bec017c79c12ca7a9362c6e40391dbf3ac987362569dc34d20a07b03306cf7577ce94078ef122207bc05e55a0d1d6368ef85874ba21a0090825c720467a891e1106a4c229446086bc71937904b534780e40b07d36175c81c8287dac48fd72c37946b98a9ca814401d1dcb5a243cad5240543234c00cc146b9ebbcc0dc57f5f963255366e4424cc595a1f7f2b9a066792fe0835e97390c97a43a52c39676af8be2393ca82d64039e6ae6a6ffd5b582915b23db1f307c1b18c90086263a9ea5a87d5470b1584c0ff272e6cc3e1c3b59b895b048db369bca70a3d22263483226262a7f15b96eb316dc62178a52af1810a7fd357679121c78083acb8ca1f0f6c3959c235ed901e32366354087162c3c86828c7b6b8688120ebaf50f55f111950ba79093a3c2029deda0a007b73241d30024d897bb66a0653386bdb344d10c90e43249d1fa0847f0ca918a414484656d4c0c246350be4722b43343a2e310ec985476fb754c93256a8321d9369fc531495b263a440c1db25b975d0a74d6b6cae1686a63b64a1fe0c51433ce5b886c34d9a44afc76133245b302a277403ebd46889e4b84585615d6482a4b0b5d528790e40538d4612646a690f0e7a451fcaff648583fb7025ea2038540acacd2b30429a550c980247188cea490e5252fdd0481d0b9837ce69e03d4798cdbcb25867b9e794ddc945d96489625aa16ad4150a925aacd254a6ae309869a018191c9e6f9411a6b375bcc9cf81925c57b99beb92921ab932aa87c3e68c500070f5568757b2b8e86035f717b88b3735ae662add2334184e6cbd2ab026b8a9d41f12eb322afc154a0b21330c951a4bf5c54959a515896adeeb73c42d94218d46219c01ce056bf78fb88902ba686b440c1026bfda6455610a1fa008d44c28bf22796204850f0e124108816e39b3c55c7ccee889effe88587b0a12a5c0b2a30152e98c612b61b95c0ca8fb3b203dc850ffc7f866275c7c851b67333f2c37a6b5b999b686fd6ec67ba67c9b0910e95f84a5e9a826e0617229206d94b98927c418cea516604444978c24dab19f0c63536076e9a0841873338767b3d935cb526c04c2ab5015fbaaee2a523ccf7154353b5282c7d9af78f55a73857ac5a70a03a584a8f1b0bb762f9c7265b40404888516016f6808bb3b3b7d0553e2877726ea63312f3afd494b5c1b60fc4b6bb6c8a68fcd1a6cfbb9265a10fa4c4bb76b8b47d0bb34f99b612a595aaa91dde62c02cbc473601b03f5547f1b4a8078aa079c4cf39c56f88925a9383b9a0f57b58741760c58d2629c5d70074df007e715a3f9344755ba908a4a310de73150a79a9ee3957a730687f4b2e7df025c1d699c254af6642bfab84809ea9a3b35410c7688b296a3da82c6cf6790b48fa3f66f5b651912e7939ab76b0935f49c1e0a25422365974698c9532ad00120bd2ab10a8d1a78ecb392e6892624a3f96b2758a423246d67933eabe6ba2bc019a031431338ab546b3154a80945a9b31bb5f9c4071a4b0ac4b1b85b3a11ae1371db39771259936a27ebec742e7d6282f19c4b6ec1a70085ec6cc23186c8a29f4c3a1d3ade8912e3e238f024cbd30e61b1ff2312c91a2eef9cdab68446bcb64ae505c32f0ca5d02547c3b2343962df8d384bac81d15fa3bd2a116b4d9aba31041428ab688f950809c94404b5c35f303d9852a0f029e609126110b64e310c81d634117e3b3e1994ee2a2799600aa38966e00aa9450f24657a39b4901764c3a267f2018363950256a69d5b0240f368bfb238fc3abae22dc2f3fa6c9e7f055a8712cec654adc039c49aa1d303158e05b0ee4f1ccc0e07cae74047b603671b9704e70646cdc0b1d1423bf3c4fca6612360269a26b9731524a2117a2b686131708470ab6c1ecec857465cfdcaa5b1506abdcb6a5e379bb4e358462f802c2a81b26d0091a9a281a891c06737fda60afd65ab7c7bc4d97667220ea69896a46f20200b0333546713d9e685d8230487bc39b68b170105231839417fa92aca1cc38246b3d0da638aa28c907c823a1fc779b7626a1146645db0582e23115c64ca6468bc21a480385b27fcc28c0e6b8430a270c5061012a619da7138ca97da7832807aa4f338a3983170b62145f36a35241d21c13c61a1044b5bbd2232f5c16f106ad476818f83920f650a87dd80c3213680cc1572b0625391a92dd423e53dcc0ef58ca376b18a46b8ba4506878f38c88d814bba280575235b23107bae8c1f443a5e9c1058c904a09366b50e7b531451f8416342267352fcc7fb21c05bad69bac0967778c0c2d48a60980ab5b7901b84b54f1a53b6bb09b37d48dea04838193657cc7b47b436d4dd36cf9bb4bcc552700f98a88a850dc009b00bc41c9f552e5b346416024065634f4d768cf49bba831758af42e408668aa712f93f43658c48b80a72bfecc0258ac6fb10c51ba665e8f25537116ae53336a8f3a0d2101b705642c5891b4500ac61d023398b35a21e37ec6c9821eb46c348c594590941fa0cb5d88ad32c3165cbc3569e15960dab8f53c16d02320b7c8394971c14c5633ac5023d572608c60a726d50b22dc3696e7c352fa6faa0c8e73127ece085562bb8a86ab6628149292a750588aa90d268f5fa618b559a4f8468218985db9f4cdc1f65b4644cf585a1a8057431985058476cfda6ca0dedb2fd77917fda88d799709c169c01e90c5528a9ffa144636334d8cb3a1cb27b81df55c9205aa1cb43f04ec29beb19539992846db361de4bea0a7b045749609571639933e6c105221782033885385c5036153ab3ee68156f0abcebcc67c9163fd09cf2a50910c8a5e50ebbaecc030ff38b041c3513da677f78b253d7c5d9bec993f85aab56a21502b1ee66922ce9995eb83376ed309b1f66c9e9b46436399364496a51851d48ca06e342fd40a6c64748d6db5a9bf18893d65a9fc3b227401c9410888287100482438e604cbac435abe040598f5cb7f07aecc23b6b38a95f9cc8ebbcb4f5cfb17a8443f89ea8eb592456da09fe9a36bb31a98e9e5372d4bc83f9a7509da4ad87036581b27844b79a9753bad9a476ef64661ca2a5e49797fe161159aca36f017d947b66d87833383c9eb593313054e00867a81e0aa6b1a8493a082305a387f8c50024a9f682c69ca0aa180eb8dcdbaac44f4a3fa830bb056352095c2b8b65eef62775a470638c252f40c8137d05cad7c9508c3c34a6b29e6c6431b34882a3526ced7143da2bb9733c2ef816e28d3a1372b418ca595ba593b18789b7c6a411e27acec3b4246e8659a2330c628436d21722536858548a280588cadab316411b5edebb50ddaae15c32ecd74af476b3d4d834c1047376001cecac303f5c1bf7afc7b63e8372c97a8fb68837064294527799a8874684a81f6145ad7ebac7a5cbccb696472ca98fd95b9ba4db7d8729965aeb56b8ee101d0b32b6b80a772fa80e70598b17e84fa2a35c723556eb2782c7cf77ee75f8928f8038ee66db41346741fbd6aa1daf2b43fc3d8392cb53f36ed647364a04e37278a0e0a45b720f4a75c580c9920eba98d" +}, +{ + "dz" : "b8bd0493a882e3a49b4e0f6256fb1fea0912562fd9ba26ec3d6c9cc12c8973abd7e4b5d8021c486b9c3114d7cbbeb7cd49eba8a61bc2bcae1f1bef30a1daf76d", + "pk" : "d0c53790651f609447f0b18434e5b31f2b2a3d1233205c11e5841daccc2017203be9c26db2ea7de30a6671f79c1c424052a784e727c36a3b9dd1d71ba80a542dd42b17c85eebd81406dc394ec556acb00932fa9a8ae610646a973de42f9fe29c92b35c04884be2a5bd3f68b2083945f8ec525d651877d924482b024847938eaac5690cb33f0a878927bdb4a84ad627092f046a2968437bf9a675d91e25e89a3f246b38461f002c3d78206539968d9b7a83745869ea8accb72ab1dab78ff0183c2ffa338c819dcfc1178ad8b928c68abc98209819ad705a3fc264bde3047fd2065c3e1806a9318d75a39c6e4541dfb86433bbaabd12762f521c842a2381dc78fb312b1a6a318c5201bed68ae518be985746b863ccec279836d6810178c54902619301467bc986a735a9e93678b1f433bcb7af36da821dec7546a4957e413d30a4b1d75ba216da71af7a7b17a932c224bfda459681893ec103a4b56c10805a24543741ed0b1f5bf84daa018f94c07434758d32d80a3d8c6b54774da822451b12aa086782f9c0622c2b8ac9776639084a19a509124b5de6d77a83bb6e123b8eb1019a2b203f87896f23018568da081df72e460a1d8a2815794966aac55fa07cb7007ac3743a0f2ed5b6f377286a7c2aa4b9655237b3f1635dc25527357bc4714c3a47285c9ae3a5a84886c7302d22ba2d3c15580be7b1627c81fa1b0942e85a3a075845e47dc0674f4ec2c1ed9ca031ac1cd934a01c022d26b6ce5c038fbd541dcd4ab4a9bc17c06842d7645935b57587559c11b99af337bc629a45ec37a3a20b1fe905510971b6e0926126e815625c5d79f677ebfc69b1489809172f34e075c29a6e9fb4b536f892b16c7aa97623168823d5b1afb439cd2603c9758904b942971d769826b169936ac108c6caedb98982098d5176c71cbcb11b22b96143433f6c083bf83f6005c5c8b93562e081c940903ae662a8f17fd0882fcb399161d2a2bd2b8d1af0731b0303e3c9beec81c5473384b7a04c1c841f60e27eca0977eab4c750930a2bcb3983daa99cd4c2e2414ab8f77857432036c1a9a65c493afc62ef80758830417375c697a2a7fd0782ac011014733e51f088bf32b7135b5db727b147936740e320c603365e280cbab502b64412abdc4d25fb9a96ccc96f166445f6a6c3a894a6c10ac7bc074fe7b5a1d2964ef0531e7bc445e0a402f45b0f29809a84795848812a1b935d220670c2cd0e3332abc68f57b98f24cb9e68f8b1663b4c793ac4212177f11c594671550e44794f84705fa4835d918b317a1d5aa39e65026d3888aaf40cc247023b74cc4e00fb1c011c6a266560949c626e08263891608713c12e75a229c5bc114bada81395b00a5b6e695096b2790e85c954028c5b288758c9ad634a3ae11b069790bff9428b425ab70c5c46c2150346235814e7af8576af3071c6e6d4b56b61412d7a5cabe21cdbd0aa69e53d4d223d72e4c77afb927958245cd57967428d9f6c81cc604fadb43dd56c8148664942e2085395b17a1c53646287fa14a9bb208aedb1a7e6f73828f0aaa5918a69c211bd765cc0f93615a57609b5aa91c502b851c4a9b24335d282348ba33a802170524ee3351b6c780a3a9b46cf472fbab34be9f508c32a64bc37b6e6b30f37a7a9f200c34811c2b8553ec3ec091091bb08ab02ca7680867244fd3c991508902e84bb5e177f7251057c38784c0905cbe7041f12bdb77c07842228ab569fb69700f9b3a058dc5791b600dc48855fb1cb938b2e2599c1f3411628b64094ac20eb6c50f5f5cfdfcc10471346de9429dd29953e7b139e2a46f04127d7225fd46723dfe19522a4a76389bfe6414450b885cb211ae680b59ef46177d50b0b3306820a9d57293ae6753e65097f8de97c898c465b07b6e89459f446a59c04145f2c30dee57368e0479468ae96bb2e8b0332bb7535104498ffabb2abd65a6b8a2358d467eb8376a795aab40108ed9b0967a710083acb476c28a01b46e68a3d64b12dbb49146df48f31e1531cfc3295e4cda083af7b3a17617286f60b5ca9d21858508f8f009878916473c85360e8cf6ae8360c80aad7a10f6cb7a707063ea9b2ac097155e6961388f87327d084baea61d5ba26e1d5bd9cc25ffdd46a24d81c40532697b4cc8f58643d41afb6d29b7c857837a1e385a9106e3bd9911c697c8709312db4ee1d9b023e39fb4a92d9d95ff015", + "sk" : "c35b3d09514951dc232b3b261cc77a4b23b033a57012277498f66299f98b2e58a618cc8b68ba21d1f86cee4b7221611b8d003010c870a4f8510198a7f486279a168ac82aa70744cdf8662ce35b65ac836895255089ca97e4b61c1a52b7b6cc24b434b25be51814d09b4312a1150931d627685917b8535bc52aec1eae1338bcb6c087bc419d3a30f625812bd73fd3e3c798d61be67b30d0d34e34434878f53102437db096cdeff6c79992337e1122902c803e58c56d0878c5e891fe47441f95390fab44d716978a0c4af218863ba783a8c7b5b9f74ae671684fa284e1399e3ca469acf757f6dc3b6306a2b241005214554a7430dd97646fc26f4b45ceb8e13fe47bcd2a1b0ea558caed29be60baa1803808e4702eb6f46d92d1c36c5aa89fe27346c56d17b52ca4394ea563022551922923b6c5d36477002d92a88041399f33a902a0292563182a48145bb3791e0eb45708a4132fb768850c83c9517d25b1954939c857311cc94a168756aef272764cf63cca0b1a95ac4bde1c2c531769ce89419edbab9614c620583aef725eefda51bc16b5193241b986073764c4503b7b497a9d77587443a52ff47803bb40432852a1e4f6a7f1fb0a46304da84a85523bba99e06b304583bab0baacdc98db486439916bd3eb4fa6706c8f26682d728be9a82fb96c6f82a1c7414c5fe645b833ab30b515a446e54e5389a972d6222ae14209d9634af7bce363a0db3222378968eb589f9bc2a5032c37af18a9dc72211b5858575147aeca713c216dd4c7486861a16d9a56305c81255403be295de819b8efe70a19a1201e7740240aa2a081739946606f7786a6a745b6929e70f552b7a28f49990c82e114360b63cf739712dc647fe8a03b9a8ec5a2b4f8c3010ce71ca964a1a89c61729c3c18bcb8891bc2f880c93041a5ffb9600e184df6a07ba52838123ace34f01099d5507e7820abe2bb4f9b67012a4419934d13db839d36aa6de939feecae90cc35955164d9d9c8a078909d4cb22016854c2729633b2f2899302f356521f0427cdc7907b4529155c871779149f606ba29aa0d9586ee05baa1c78d12b9807ca995d38122c43b9671b16fd03436fa87143805c71c4656c29b8da8b3293b44be0a0bb873647f7aa92562e4706362110388c9f15962cb249953128a53e30998918ad5370ff32081f4053d13f741d036c36fa47e8a97b15c647272a52ad94620c4ba7aded0259323067f8b5612fcbe0aaba35d6999339cbff2502ea693b446f626fa05b5f3b90c7362a38d0a710a32a1e68614b1d63469182baba57bed2a462e879b7a172bde9ca930d85b393a797e339d4116c3bca1cfcb16205ad5c0e68488a112c34c66b4d617b856ac8c66aaa98ca458ec4219a747930f3394c4623a7d402b557069aa524eeca0a6f65a82a2c95aa816723aa2cdfa841106b0336a613420994580b94b3261a15799cde04ca3a758884be34955725827c15432e194f624921c674ed10877cb5078d1b29a52694fac72cc2aa435549cc34242906ed1cc12e523d6ea0ce55cb8a09c22cf580a76a8909d3c3cd749bbdae9c05f117114f4b5ad58533d410f8b2010fb8c25fc1acd38c69dba50803a3066214914cf9a8ab056a47892197dc50783072764a69d8b988798aaae3f1c1b2a268312bcaffe253940311033c64d20c1aeb501029f873a6aeb1d249945a997819651bbc86b96cb0537e7e80c0e382df932606bd58ca3d21c01332cc65c1c00b31c34588d1b10cc176b2ffbbbaf2fa95545e51f0d7445cc017c4d3178fd38c9d85123040a702003af65b74904028753825c7f7c6843b3bfc8020535fb6888227f6bf329d5203eaf8b8a3890716e563578e795ed566d43b071858b1336165544ec566acb361a8b8564796b8934c8ce253c409677c2d45691306301a58da9ba2d05f0c847684e960590f1a5c60217c5ab905cc8a95e9bd26301802ba9257370b73e63d647f02cca6d58907da1759cd5c20f7a8762e56c1e09b95c1b99f2bcab69931f03a707baa0580a896c022a53c3c846e4d0551f5a2d6f6b4d22ba779b017fb36546430292d950c10ee42862c749bd95104f133252b15771db7d3ff4a7cc310036903650041b40609d6a9c16e40ba12e6c390a388b95950b1de92acb71396e4a0fb7890bd7d123d710a5d0c53790651f609447f0b18434e5b31f2b2a3d1233205c11e5841daccc2017203be9c26db2ea7de30a6671f79c1c424052a784e727c36a3b9dd1d71ba80a542dd42b17c85eebd81406dc394ec556acb00932fa9a8ae610646a973de42f9fe29c92b35c04884be2a5bd3f68b2083945f8ec525d651877d924482b024847938eaac5690cb33f0a878927bdb4a84ad627092f046a2968437bf9a675d91e25e89a3f246b38461f002c3d78206539968d9b7a83745869ea8accb72ab1dab78ff0183c2ffa338c819dcfc1178ad8b928c68abc98209819ad705a3fc264bde3047fd2065c3e1806a9318d75a39c6e4541dfb86433bbaabd12762f521c842a2381dc78fb312b1a6a318c5201bed68ae518be985746b863ccec279836d6810178c54902619301467bc986a735a9e93678b1f433bcb7af36da821dec7546a4957e413d30a4b1d75ba216da71af7a7b17a932c224bfda459681893ec103a4b56c10805a24543741ed0b1f5bf84daa018f94c07434758d32d80a3d8c6b54774da822451b12aa086782f9c0622c2b8ac9776639084a19a509124b5de6d77a83bb6e123b8eb1019a2b203f87896f23018568da081df72e460a1d8a2815794966aac55fa07cb7007ac3743a0f2ed5b6f377286a7c2aa4b9655237b3f1635dc25527357bc4714c3a47285c9ae3a5a84886c7302d22ba2d3c15580be7b1627c81fa1b0942e85a3a075845e47dc0674f4ec2c1ed9ca031ac1cd934a01c022d26b6ce5c038fbd541dcd4ab4a9bc17c06842d7645935b57587559c11b99af337bc629a45ec37a3a20b1fe905510971b6e0926126e815625c5d79f677ebfc69b1489809172f34e075c29a6e9fb4b536f892b16c7aa97623168823d5b1afb439cd2603c9758904b942971d769826b169936ac108c6caedb98982098d5176c71cbcb11b22b96143433f6c083bf83f6005c5c8b93562e081c940903ae662a8f17fd0882fcb399161d2a2bd2b8d1af0731b0303e3c9beec81c5473384b7a04c1c841f60e27eca0977eab4c750930a2bcb3983daa99cd4c2e2414ab8f77857432036c1a9a65c493afc62ef80758830417375c697a2a7fd0782ac011014733e51f088bf32b7135b5db727b147936740e320c603365e280cbab502b64412abdc4d25fb9a96ccc96f166445f6a6c3a894a6c10ac7bc074fe7b5a1d2964ef0531e7bc445e0a402f45b0f29809a84795848812a1b935d220670c2cd0e3332abc68f57b98f24cb9e68f8b1663b4c793ac4212177f11c594671550e44794f84705fa4835d918b317a1d5aa39e65026d3888aaf40cc247023b74cc4e00fb1c011c6a266560949c626e08263891608713c12e75a229c5bc114bada81395b00a5b6e695096b2790e85c954028c5b288758c9ad634a3ae11b069790bff9428b425ab70c5c46c2150346235814e7af8576af3071c6e6d4b56b61412d7a5cabe21cdbd0aa69e53d4d223d72e4c77afb927958245cd57967428d9f6c81cc604fadb43dd56c8148664942e2085395b17a1c53646287fa14a9bb208aedb1a7e6f73828f0aaa5918a69c211bd765cc0f93615a57609b5aa91c502b851c4a9b24335d282348ba33a802170524ee3351b6c780a3a9b46cf472fbab34be9f508c32a64bc37b6e6b30f37a7a9f200c34811c2b8553ec3ec091091bb08ab02ca7680867244fd3c991508902e84bb5e177f7251057c38784c0905cbe7041f12bdb77c07842228ab569fb69700f9b3a058dc5791b600dc48855fb1cb938b2e2599c1f3411628b64094ac20eb6c50f5f5cfdfcc10471346de9429dd29953e7b139e2a46f04127d7225fd46723dfe19522a4a76389bfe6414450b885cb211ae680b59ef46177d50b0b3306820a9d57293ae6753e65097f8de97c898c465b07b6e89459f446a59c04145f2c30dee57368e0479468ae96bb2e8b0332bb7535104498ffabb2abd65a6b8a2358d467eb8376a795aab40108ed9b0967a710083acb476c28a01b46e68a3d64b12dbb49146df48f31e1531cfc3295e4cda083af7b3a17617286f60b5ca9d21858508f8f009878916473c85360e8cf6ae8360c80aad7a10f6cb7a707063ea9b2ac097155e6961388f87327d084baea61d5ba26e1d5bd9cc25ffdd46a24d81c40532697b4cc8f58643d41afb6d29b7c857837a1e385a9106e3bd9911c697c8709312db4ee1d9b023e39fb4a92d9d95ff01560d717ee34e223ead8139db400078cb308c3e1bceb046cd9d53f1a2abdf8f924d7e4b5d8021c486b9c3114d7cbbeb7cd49eba8a61bc2bcae1f1bef30a1daf76d" +}, +{ + "dz" : "c0407e41ddf48d333978b89bcf2db01e4613425b456249e76a6f25b8a2827bf5b2dca81e3f5f748d23c9d356a2209f6b2d60247b2e45c9808de497f64f124643", + "pk" : "13665dbe0a4aa46bcc40862f1e3621f2596ba293466f7499d9954eb6a6251483b350072ce7a4910f008166e62476e383f0151fe706c23999b71dd2471af759b99239ec05996a94b7a3943e37f10dbffa1ba205b2ed836aef025221ca53ac612d41339770d80b03f0220fd1580b786353c9bf15909242494253684c8e2b5a28216501e1b4f1820d6312cac1bc02c122bc0ed71350a05457f4c40a29584e20b70a8739f1e733483b7e7f8ab62b664c9672229980536d747f3199a064ccbd66e7be173641808a93231aca8a7b54dbd0c593ba85df11c54bc2894c6a797bc0557df513734c74f3641a6d2c98fcd8c1ed356c2e199c28088ef495a54fc1019b736f2fb8895eea391c67c895041f97805bfd2354ba1c3dd8e98467d302366a616d280bdb4747fb5a000bc5781bd8c1cf2b563db206e6e512248319d2122f5ee77802d88466a61f5006239c5001975b00dd634377705274629f16a92f13b37049698b12c39bb1c3579d693970736fd72c8d8654943e5868c53a51324abdc57b330ed30145e92ab82c91d975244288833ff3a2d9d92aa1f53d99b11d191c99e06434196318e04087d9aabd03d7ae1cd2887cb2197ec4b09f7699861193d8eb77da9c9e33749e4a0c5bab3bb64adc4436b7a6d84b9463c4887e4642d490052093399b2cb52a73b5904920a601c327e2937ac439fcf3b78ee830b4ecb795376dd263a3cec91c6a6b60e48001a0f739e217b5b3c4ab0a676131514bb62c9fa1801bc80b6c8c7ac70110b4860cbf221543f2aa61e0683bee500f98ba4fa93c2865a28ba4820aecc3a6c7b56081869c701b1bf741152c0ca0a753a211c3562ca26a15395a630a4a92729ed9a3092d23bea5433447139ac0518f75d11af6113b8368cc72891a5de08dd7689b2592256a8ccfa524a2344921a0e887627bcf7965a1875c1ea5c255c36978da7c4f184a1cbaf24a2df142ef80c07750b87269419721c48d8014f4ec8b4ee23d95ab1ed9f8b5ee9943669007d48ac1657454afd466e8765c877a54466171b649188a7c205bc3073791b832b6a752625809919db9258ef1b7a15d2c54c6c02f57fa65751438f4186a8b576d7c561d649a7a60d1928e013df7d69f4dd7035485107a7062bf3ca84a93a5a0197ea00b7522dc769ed45596bc5e712954e1eb37ffd69d63ea2ce5e33df8088545e3a738b864bb61b916d29e45ebb39d8a7a6fb3cb3901b9880ab0547107c9073b19258e4e290156f54ae3d44d19d8abc5fb334ad757c7e24986a26a31d458edd45c69b9b8d87b0622166e66c76afc49a23e1c1abbf357b7328781aa9a054b24aa2645d691639f141981c30a7203623d550c31e2bd4bb95b2e7b518b44512dfa6a5387afd6c7ce162a434a6b9ed937cd79222134310a2420934b357e72e009ea8413a9148698240aef2732836b5659566d21111331fa9bb0b762c948247cba816e313109270eebe826ed722322f9841f33a935209e0df273f4e2237a59b27cf85fb3773998a295a37714ba074d1093b0f096b2eb5133bb273e50e17de75b45300c0c862354344336fd028a4a631da22b285d4435082667ffc21fa01b79625c019e71cd0ad86032fbaa79326630692b9d02be55315543d83c0b84297945406c339699b1093e4b188511aec19b3c9069bdb8799a2e077af4308c401982e96819c7f17f6bca98054688c30a75dacb90ad342acaa9ba227a7f6784100428cda9d6890396cc19cb90a81153bed281cbcb1036113250206b59208d8c75839b76ab8425211961967396c696f05d913598259334c742915dd183f32c5a4e957013868634459f038340aa7761ecb628fbbb435ba642e21c538b907d8710413ac10d7f0a7965b03cb8c36d39336543193d0d768bceb00af79069e7c85b09114e77e6063aca18f27376beb9ac4a0b976ce745fa7972e9fa74d0055ef490cf40e11e6cd785510bc4bc1231d88abbc9b22fc1e2577608580e26635070702fea437f8a13f6fb37343b488c1c0b2560027bda77fc6a97222319b66a86528061f21019aa73674519420bfa26ac5616efd714cd46b7b7751922175a1dcb22831609eb40b4d16107c8438f33e203cdbb85be910b78a99d766499d4541b91567fd8c7a85d983080b91c9254ce3c2a9feddb8c8ba948f0986a90d02681341fac1cd19451956432b83b79d115d32a3d4f86f902f2f6b0c95ad7f4bd49", + "sk" : "ad3cc5e966747302200dd35f1d80350983648610ce07452591948a1c6a9debda418fd0ad79da318004aee89acdd62c689f88a5a7621f7ef3b1f16c5bfd5c17438b98f029906c276ef1202d1f5504bec6243f608438047e6625c825b902ce22141142145368298d0c33ef857a45c872aa73308ed112726847def20029c2730768abd1c40a8dca501fa61ccc737d8fa497091ab5ea532bc730bb9633becde90398a391b4e60f5a5a31a360529b1486530b98742780c78c2761c09e655334be04b71d8b9b04a7b7daa7ac4d2a98e2ba49a54c2e91016be462418e632a4e023bc6e816240927c73703fdf0ae2912787626c55f4614c93731c9c679984738c96b5cf64c7f3919cd4d217f44e668e9fbaee0530949f63ac68137c841ab926587b161c56d218e3500885b82bce07668ca959093792507eca4827a003d26cd02324e352388fc76197ec546d590b00f646de107681ad32c708561546bccaf0489495821f8d43a436c1e4d9ccd9be2a5b46232dd37485328c3ade9bb08e53947eb16afbc6ac1b2b96b496f1afb250277bdbb0b6186b61b88b81240292880d9cb9a43352546a5e9f600045153ba033c3148a5aa78afa9b2b7c8b86e4dd70a0516a8a3e746e83ca8b919104015650da3a6f7ab9868e1c8e33b039b9279e4680b5c2a382789049f953fc28764a0422f00e9cac3ec794de5ade0b432d294a9c06941a814ab0f89bf88e719d081520b114c9c821f772a7a3b2a16edbc2f140724e7dc1649281233507187e4b87ea13803bb8e23541e176c1cdbf38ed1a225fc932716974829a6b83f30b3f587804eb8720e102278d5c7a2668f1481c42adc13788604d60c9ed1498bdda86a9640bc0b8137f3d7ba17e0bba28167ff1c5e3eb86b6eb5c018ac766e15193b8b4f65acaa3a2c191d646f97f19b200ba588780aafbb2f1c582ddf4105767cb93fa984c5b6cb73cb0301d9183513582af59e04d9c5869cc99ed83677d5a0f4405d166a97ceba0d6e0b8692cb6ebe130f77025a24264bf6851b2a52b41ef989b9f890cdccc3867c3ae19c7238750bfa11ae52dc573e87554a40088e682f15f9be503b05e2b53fc4411758854f5d691ac806ca00136a0702ca52803dca8c935d98c87fe476f960a169401147b240c026745c894d7d91197bc7b2d7802568f61eee554d3b852902934906521fa08b29b6c7c27c6867667168b796b5249bb442783970e7c443469c540aa9598834bbc4bf8ec97a18119b496a56c3fac7e2627b76ccc51fd60edf764f68ec032bdb7a1b5424be15329a54c537810205c15ca2ea34a6462cb3647dc7a38590b120a8d141d821a20349631e7c4804f11af9ab9ad4917a27ba99b9f2277f3a8afc059bab0072e93131a1936f87c8356e3859fd97a89e17affe170693309eb4e29a769ab2ab48659f635acb4ac986f08f1b186bb6a70a50a6cd4c202a10bc2f1d24ab4338b2d9765ca263ce01295537dc56bca315db1c652e850dfaa522cee677d2775f878037e5c17da2e6c7fb296927c64ce9256f88851d31ba9658f5bd7aa0636cc2bafb1c3494110e7fb8683bdcb3acbaa7274351b14a81bafb0a4e2208d3c204e84c00920c0c074109a81426416bb805465e429641bc9006b56c75ba1c75c5ac4113f95bce7843344749e969ba2702adf09032af83396606903772547365cdf835a5bcf69d3c14505b5472475c97acd88ec1ca4d52d0b1281086a5bb3bed1cb3986238385391a0e59523b5a16756af4e15b58a07426b574ec080893294a60d1148dc418c1312673f89951ec94e1db149365b33ff60cb2bc372763277eb97c5c8884ca7421f681b90b249275e631918aa57a7ba65b4d620cbb59131201c9a3c5e070ac76f7214e167853fe16c6058a9231a0f5cf69339c0463d290457fa47d0d949bd7362b5c0c2236826e4241353c2ae7833c31dbb03e7332dbf370a637a8885cab1b9d1a864b98bef6c81a27c93cc306a27b37bf794190a3cb6d55bc580d295ae6087d05775fc802198191ac5f400c25b39102a54820b5ed02146d5f19586a8c66126c87bd22b0e9c7857c3426b470768676be8f7b826b1c1dc486c9ee64d79c33372e33ad4880f357196ca95637c80668040022885549d1a9801109a96398f1b8c6247f203ddc4350cf730892b53037b4a13665dbe0a4aa46bcc40862f1e3621f2596ba293466f7499d9954eb6a6251483b350072ce7a4910f008166e62476e383f0151fe706c23999b71dd2471af759b99239ec05996a94b7a3943e37f10dbffa1ba205b2ed836aef025221ca53ac612d41339770d80b03f0220fd1580b786353c9bf15909242494253684c8e2b5a28216501e1b4f1820d6312cac1bc02c122bc0ed71350a05457f4c40a29584e20b70a8739f1e733483b7e7f8ab62b664c9672229980536d747f3199a064ccbd66e7be173641808a93231aca8a7b54dbd0c593ba85df11c54bc2894c6a797bc0557df513734c74f3641a6d2c98fcd8c1ed356c2e199c28088ef495a54fc1019b736f2fb8895eea391c67c895041f97805bfd2354ba1c3dd8e98467d302366a616d280bdb4747fb5a000bc5781bd8c1cf2b563db206e6e512248319d2122f5ee77802d88466a61f5006239c5001975b00dd634377705274629f16a92f13b37049698b12c39bb1c3579d693970736fd72c8d8654943e5868c53a51324abdc57b330ed30145e92ab82c91d975244288833ff3a2d9d92aa1f53d99b11d191c99e06434196318e04087d9aabd03d7ae1cd2887cb2197ec4b09f7699861193d8eb77da9c9e33749e4a0c5bab3bb64adc4436b7a6d84b9463c4887e4642d490052093399b2cb52a73b5904920a601c327e2937ac439fcf3b78ee830b4ecb795376dd263a3cec91c6a6b60e48001a0f739e217b5b3c4ab0a676131514bb62c9fa1801bc80b6c8c7ac70110b4860cbf221543f2aa61e0683bee500f98ba4fa93c2865a28ba4820aecc3a6c7b56081869c701b1bf741152c0ca0a753a211c3562ca26a15395a630a4a92729ed9a3092d23bea5433447139ac0518f75d11af6113b8368cc72891a5de08dd7689b2592256a8ccfa524a2344921a0e887627bcf7965a1875c1ea5c255c36978da7c4f184a1cbaf24a2df142ef80c07750b87269419721c48d8014f4ec8b4ee23d95ab1ed9f8b5ee9943669007d48ac1657454afd466e8765c877a54466171b649188a7c205bc3073791b832b6a752625809919db9258ef1b7a15d2c54c6c02f57fa65751438f4186a8b576d7c561d649a7a60d1928e013df7d69f4dd7035485107a7062bf3ca84a93a5a0197ea00b7522dc769ed45596bc5e712954e1eb37ffd69d63ea2ce5e33df8088545e3a738b864bb61b916d29e45ebb39d8a7a6fb3cb3901b9880ab0547107c9073b19258e4e290156f54ae3d44d19d8abc5fb334ad757c7e24986a26a31d458edd45c69b9b8d87b0622166e66c76afc49a23e1c1abbf357b7328781aa9a054b24aa2645d691639f141981c30a7203623d550c31e2bd4bb95b2e7b518b44512dfa6a5387afd6c7ce162a434a6b9ed937cd79222134310a2420934b357e72e009ea8413a9148698240aef2732836b5659566d21111331fa9bb0b762c948247cba816e313109270eebe826ed722322f9841f33a935209e0df273f4e2237a59b27cf85fb3773998a295a37714ba074d1093b0f096b2eb5133bb273e50e17de75b45300c0c862354344336fd028a4a631da22b285d4435082667ffc21fa01b79625c019e71cd0ad86032fbaa79326630692b9d02be55315543d83c0b84297945406c339699b1093e4b188511aec19b3c9069bdb8799a2e077af4308c401982e96819c7f17f6bca98054688c30a75dacb90ad342acaa9ba227a7f6784100428cda9d6890396cc19cb90a81153bed281cbcb1036113250206b59208d8c75839b76ab8425211961967396c696f05d913598259334c742915dd183f32c5a4e957013868634459f038340aa7761ecb628fbbb435ba642e21c538b907d8710413ac10d7f0a7965b03cb8c36d39336543193d0d768bceb00af79069e7c85b09114e77e6063aca18f27376beb9ac4a0b976ce745fa7972e9fa74d0055ef490cf40e11e6cd785510bc4bc1231d88abbc9b22fc1e2577608580e26635070702fea437f8a13f6fb37343b488c1c0b2560027bda77fc6a97222319b66a86528061f21019aa73674519420bfa26ac5616efd714cd46b7b7751922175a1dcb22831609eb40b4d16107c8438f33e203cdbb85be910b78a99d766499d4541b91567fd8c7a85d983080b91c9254ce3c2a9feddb8c8ba948f0986a90d02681341fac1cd19451956432b83b79d115d32a3d4f86f902f2f6b0c95ad7f4bd49566debcfc9a4f48f6f60ad57731445a7861bb9c371e4ee4407b35df5a730f36db2dca81e3f5f748d23c9d356a2209f6b2d60247b2e45c9808de497f64f124643" +}, +{ + "dz" : "334382d39164d1989696a2ff77b25a28af8bead9883b5365eb6fcca7c1781cc9aba5068af837be962f439f233593d193ce5e08f7d66efb3389885927b89d2523", + "pk" : "869a9e3773a7c7942e279471a233a05d77899c2a18f35ac98a3243fa6767f076976529b75b75b070a341dfc95bb85c4bfa1394081141fe1b1b31365e3c2302c8a0296b9769de04024da48c2d7a3e5b29ae58659384fbcb4ba2ace58c4ceca5baa5131bdd465797664276aa44e8331e2f1328aa6910f68a6a73210e575ccbbdc689199559f094bb62380f436a925a7305fdeba6c53a9193069873e724cb1b67fb8820e75c27d175bd5f5b5db020c91eda2439383b579c14da0173e1704a318a03de6691ecbc600097b41a7a9a429ca1a4d8a34dfc6c85e034e8a17629181fe7c993ab018d135a73861405186763b0f70c80d09706c9af971313e47bb917761a0e3a39f7b96702c288254675f6a07771768f3939b7bec979cbbb8bca011124f08347b7bc7c70833197b192fb26589098e48834e8fc8551a1c1fc52a1701323d98c4bbe7779b867b813a5a2a5040d8e8845d4a2b03efbcdbbb3083831b1ffaaa9e21c7a3ad77053793b1f7b7475b021e2c1ae25f194856b1594228e938a29b832930d5bad3667c854366f83b48cd3501768f086b68007ead71b2f046f630196b8237967c940d4727d388800dfebb3b152cf57b33068803c1d55c59fba14e31c323e820265c8826ec3b6018c8f60445a11268da9b44f8dcc512b860212f408d3baac60cc6ca42211d2ca3a41271f745bc46fa70a9a8a3999ca83e8635e7a4843ea3b861194bf00909e4250ad1ddb3006f86daad2b8fa720d969a7d87dc97ae214ab3769eac0261076092250133726265eb7987bd4bc01ec004e71bb8f7b06ab339ac9c0849fcb23c4bf35b11955c52d30fa0eb56dc7cbfac95704e51969ea45ab01c10e59c691dc3908c083263c3565766a34b216f55f8284f219dbc158cff247e2296c86ba69c922161ed753fdc1471834270095a85a5fabb1db91fe203113139526961bb40b41e8f913a36461ece86b37fb809779005c4312727f68923187203d001a378c0073a240190a144962bfaa89b1c384083178a1b44461926a9ed135abae505c93177f263996de9780fc573619b63f741091ed57657404644194a25b6cd1e5aab45e9021d9a8839546a9913752621bd79730685397d93ec49d86910c46a28142928a054599ba18cc3964cc4db8bb7a87543e8a53fa23a95bb5b6713478f4b0b5ca6248018a729469a3794a8ed04a315f3783e667c0cd2ac80c68a40c35d64c90e5e8a3135ca15cfea69d4a1a2e9b562dac51409c6485e026001eb1196a487606404b6519974b386abfc9cf4a0305aab4a627b6c22a994dfe46035447f0cc09d1bac0397a68fd647b0b13630d1439e63fc8fca2b01cbe66bfdb4315230b06a9797b34a57a5db208061195813073c7a10ac95b8755aa79b2033bf90386115066f177ea1421ab0267672b91830a26c20b4a8ab9011668cc46b49a2d824067102c95dc842b4f423feabbd774b4a4be351bcd8cf2c486ca70a5eb502ab5ffb8d77c2bf00fb7887fb960c089210d673679a0c71428b5ae348ff293602833b6927add5b18f22acc4ce01517c65c848680d59931175954ace9689fb6881ce17073e113cbcd53547bacb3946067a1a46cf6b4969065c98c17304d53ab5804501711c153a1b13d7cb442221ee311466469ba1225cbb312708c7b5e0055e3b476264b2244fe9590a557f088c9d4fb47a3d598a998a1b5f821d19909220a229ff020bc11143cdfaaa90e00b71d6c8b7622f24584508ab4d036792135b750eb9ae091b4baa96a27dfb1aeaf605122060e5268bc4e9c08d1bbcd451a22e44a2d6201c6de52baf940f14956aac311b5c3782e64377c645b35d210e1ae043ad6142bf6c05aab07d3915500b67989709b7477432b947239a9c7abbe747b2238ade292448836b87938e804a4029f24182941cae500d85aa7ab9556ca98c7808d90558e771d8709446bb1069541dec34b69834c857215822f773871c4401da04c70503cee82491b07e8597480b6bae6245084a4b92f9b015a158295f237a6376118868486d9c1a8389baed937b392ab840d4bf67e31df2c073a4a8c691896b6d6b623b95670cf404dd499773a54210975d1ea72667439e0fd8c112f33470789f2899a64217400e4b51fc501362ec98a45620ff6ba180a211ce5c154bb62a1904cc13a64fb6f445b48ef88ccad56919a0deed94a2ab2d4b6442a71c288753f1dc41ef5389e39497", + "sk" : "a11ccbcf239bdf7642937b7d37c0b33dc0667f06b13d7a166870cb3c696c93e038b314276a135cbbc672f830585a46c31cd09c621bbad1f4c611f3349104857a4b1117f47142d36fa8f73834260fdc337d7427aa0fd90b5646587330cbfa5a56f3f42d211226c6a627085b86cdd73c05838f46692be0d15a7d59b9c2e803940708946293adc5c338a29913c489ee1396de0162588b6449452259a243d422a92dacaf5ed9a88921a37500cb0b1031467c494b3c207acb6d4fb444cafbc9dd364933a3488ee654b7fa866dac82a53acc8c15464a29cacefa9432256934c7790e1b99c85c599e3c5c0ed11310dc2ea6d813b505a6feb4626048bb6ff0ca8a1c418bb4512008a94d863a6f7b359df211f061584f34043aa628ab80c46007257283a6b5052e8967a56e86230d9b58acc6125406064f03b6b25a5f9a706aef5812790566308ca35b19b3c6a7a2450a56b164bdd19278de85a5769186e7c67ea9dcb7e2a8223774ca66290368f67ef6494d2bf5411f7114e7e930b7a99beb84bc69494e7461127fda4d6edc4959c375b6d8b48121312000a6ddf510504a8454600f87523d71071e13a0b676fa681428c31d7cc0d2492bc7c94c7b423092113dbb1b123a3936c0d1846057b2970a37d1caa6e53988bc0565842b143cf2207af23167080257a339795141318562a0141d1f7b59f68169fd0a2d7c959af209971860123e5b30464a740f5214aceb6b322b4cdcbcbc28285aa2746090a8595d4371508735eb5423b94a54f6bb8aa2019b76bb76b25c1dde42b56d13819123be6ed3bc3d26b1dd515121a268d3d3381ad4432713868d7059a06609864671fd9a6a1777803e4b46d9ba6d45050fb2c80f88f450a3b655843872f727a68aaa66c758a8317a3e2aaa55bde0a97dda29a244615ea33469cc5ff82a6c2e0982935c9737943b45c77c3355900ed32785f59fcad14b936c1708baa6b5686b952b07683c1252c99d8a49272b053faf69ac090a8c0e2a0f639544ca196c00975f77667bd54289445cb62367bd79a290683319daf1be3cc89a5d105069e221b875075e7162b12b3203630ebdaca13bd6768cd9ab4872a7ff54ac4baa49c3680e372b9c7e25124f6a9c62c498adfbbe9a90a79fca19fa358367a2b5a24b821866402e43b93dbc3cce1467245a42cae42eb6217cb7470158a24fa225467cf0962b399741c4743ea2222f265a45e7a94ad800734a050635aeba147023349854305c59276565e32dfadb17b3183722b1c44af4c289430f6ab53b416ca239b409fd1584a7891cdb77b742a32e55875d9a20a92f877dde6662a0c0513fbb0875973924c16dd283ad5cbb18dfcc37fbf28914713a04dc05146a7d5399adbe57b60d6003a81a3f9f5559450483d4116dbae0470e15ba3f6323adab47af30252da7bc45e38759ba99877a6421f04232b35cd3b372c0c30ed32c64b0d74fa70c7e6085048c76c2e7e9b1bdc8b033021f7600be3135b785491cfe48932e30a89f34729c012588374fb1307c808228dbf704f9a8c0eb8a98765a8e4c1b0591c212d5aac9f9593a1418afb84bbb931349b1b1bdd8d10bcdb66e7e97299a4b1c23770f8ffc8a08a0391f826b5058240d345fffb4ac4c03483b74626d049f7fa52693b18b5381cec4b13dd1478c5912a33f009f0d533bfe57105755392ee76df7dbab0db56fbd2733487b511804bd63ec767464c10fd22817d79aa7909471b14c1e0445722a240918c2cd829d3c6c4ba81c0b6493b9d0dc3910ba048d515f2e3116142c553fd230d110cd71b449f6216fff68839d83096638348a42a5ecf0986c62bf9305068ceb799ca1b7b8826a8fdaa131d6b872e1afde468aff285aa818c8caf80b9ebb2730f770fd143d81c86819b223d4059ec5a39f18ab5386142464195263f02f9b577105658ddc80a1c7ec2d82bc8c657b00c3d986f8261b039738449c0db616207676b9ffb36a986c3350b698289367ca28cb404ca0c1e436f0e91898941d72e7c1bef2a9aef3305fc4c73d7acf83f5248766a95f9a5b97185ed14c7508d7c8f7ca571a534bf4b843145799233818e0a65e0a7065ae5678411a25d95610dcf91847513bfe14abbd94300f322619fbcb0b03857ef1340de5510156579a52ada7601eeda662b61b16677c2c81f998869a9e3773a7c7942e279471a233a05d77899c2a18f35ac98a3243fa6767f076976529b75b75b070a341dfc95bb85c4bfa1394081141fe1b1b31365e3c2302c8a0296b9769de04024da48c2d7a3e5b29ae58659384fbcb4ba2ace58c4ceca5baa5131bdd465797664276aa44e8331e2f1328aa6910f68a6a73210e575ccbbdc689199559f094bb62380f436a925a7305fdeba6c53a9193069873e724cb1b67fb8820e75c27d175bd5f5b5db020c91eda2439383b579c14da0173e1704a318a03de6691ecbc600097b41a7a9a429ca1a4d8a34dfc6c85e034e8a17629181fe7c993ab018d135a73861405186763b0f70c80d09706c9af971313e47bb917761a0e3a39f7b96702c288254675f6a07771768f3939b7bec979cbbb8bca011124f08347b7bc7c70833197b192fb26589098e48834e8fc8551a1c1fc52a1701323d98c4bbe7779b867b813a5a2a5040d8e8845d4a2b03efbcdbbb3083831b1ffaaa9e21c7a3ad77053793b1f7b7475b021e2c1ae25f194856b1594228e938a29b832930d5bad3667c854366f83b48cd3501768f086b68007ead71b2f046f630196b8237967c940d4727d388800dfebb3b152cf57b33068803c1d55c59fba14e31c323e820265c8826ec3b6018c8f60445a11268da9b44f8dcc512b860212f408d3baac60cc6ca42211d2ca3a41271f745bc46fa70a9a8a3999ca83e8635e7a4843ea3b861194bf00909e4250ad1ddb3006f86daad2b8fa720d969a7d87dc97ae214ab3769eac0261076092250133726265eb7987bd4bc01ec004e71bb8f7b06ab339ac9c0849fcb23c4bf35b11955c52d30fa0eb56dc7cbfac95704e51969ea45ab01c10e59c691dc3908c083263c3565766a34b216f55f8284f219dbc158cff247e2296c86ba69c922161ed753fdc1471834270095a85a5fabb1db91fe203113139526961bb40b41e8f913a36461ece86b37fb809779005c4312727f68923187203d001a378c0073a240190a144962bfaa89b1c384083178a1b44461926a9ed135abae505c93177f263996de9780fc573619b63f741091ed57657404644194a25b6cd1e5aab45e9021d9a8839546a9913752621bd79730685397d93ec49d86910c46a28142928a054599ba18cc3964cc4db8bb7a87543e8a53fa23a95bb5b6713478f4b0b5ca6248018a729469a3794a8ed04a315f3783e667c0cd2ac80c68a40c35d64c90e5e8a3135ca15cfea69d4a1a2e9b562dac51409c6485e026001eb1196a487606404b6519974b386abfc9cf4a0305aab4a627b6c22a994dfe46035447f0cc09d1bac0397a68fd647b0b13630d1439e63fc8fca2b01cbe66bfdb4315230b06a9797b34a57a5db208061195813073c7a10ac95b8755aa79b2033bf90386115066f177ea1421ab0267672b91830a26c20b4a8ab9011668cc46b49a2d824067102c95dc842b4f423feabbd774b4a4be351bcd8cf2c486ca70a5eb502ab5ffb8d77c2bf00fb7887fb960c089210d673679a0c71428b5ae348ff293602833b6927add5b18f22acc4ce01517c65c848680d59931175954ace9689fb6881ce17073e113cbcd53547bacb3946067a1a46cf6b4969065c98c17304d53ab5804501711c153a1b13d7cb442221ee311466469ba1225cbb312708c7b5e0055e3b476264b2244fe9590a557f088c9d4fb47a3d598a998a1b5f821d19909220a229ff020bc11143cdfaaa90e00b71d6c8b7622f24584508ab4d036792135b750eb9ae091b4baa96a27dfb1aeaf605122060e5268bc4e9c08d1bbcd451a22e44a2d6201c6de52baf940f14956aac311b5c3782e64377c645b35d210e1ae043ad6142bf6c05aab07d3915500b67989709b7477432b947239a9c7abbe747b2238ade292448836b87938e804a4029f24182941cae500d85aa7ab9556ca98c7808d90558e771d8709446bb1069541dec34b69834c857215822f773871c4401da04c70503cee82491b07e8597480b6bae6245084a4b92f9b015a158295f237a6376118868486d9c1a8389baed937b392ab840d4bf67e31df2c073a4a8c691896b6d6b623b95670cf404dd499773a54210975d1ea72667439e0fd8c112f33470789f2899a64217400e4b51fc501362ec98a45620ff6ba180a211ce5c154bb62a1904cc13a64fb6f445b48ef88ccad56919a0deed94a2ab2d4b6442a71c288753f1dc41ef5389e394976ac9cb9123b99fcd75201ada0fd5daf1a51f1d069822d795f8e736abb8d1fcd6aba5068af837be962f439f233593d193ce5e08f7d66efb3389885927b89d2523" +}, +{ + "dz" : "6995143e8eb8a6e93840f76eec844f67d2b5f75b1839a5040337e61f9806764a0f4dff8e56f68440836a072412a30d851ace2c7c6f02d60e7a8420001a63e6c6", + "pk" : "12b3141c2441f96a053ec568c7d2b7e1229fdb620d905119a05690cbc9564bc9cad3a66e05f641302a38ada62e07380ba315acb5a3af9f02aba7811726a3ac94723d6e66428ec8576718c4da712846d450cb428571b1786267487b353b37d984cadc2f51aa6fa58c48b011360c5b1989e104b99671ce2985a174aebf31cb5f803d29d93133d2ac1c9851031b21e8da4021b44b4064ad7415786022bdb27a187495908ddb6109489ca2a67dea269493986565e33941c1012e5504f4e5abe662235bca3a144c149d970ef3815079e2bbfc26066a7c8dc5591871e83731139951a262f9f7a2630c0e0fe635cff95b792a6b9d490f0ed14b125b652de35cff994ef341a15bf57978211ca4149fc389c60f915edc45610b9c5883080e96d77267268a37b4338ccca90490cac44a61f2795f943a25147a8943dc545c0805e5d39b70139bef006df10c695cab9cdde3b7c3a2afe823c709936d7c3818584abce96950c06b248b858859bc2231622426078e480074bfb011baa6b11336206425211c71b48d134b7b0b1c960c9429829ac5191f8f8aac1ed70bcfa4342a362c68a35591db506f2b69bff31033f5ca4654421f48afdd736e25d810add97f750530c443618e674a6691229c3a17f3b19e9d3740ae4a6aa6b77254b27374b246381483e52624a473035fda0eac427cf0f7244b3b8fcf4c835df23cc5b729bcb1285ac49529c1241977741ab15c2984343f5139e1219d65992ff75637fa3a486232c1069cb49269305057080b535d4a624bdbb78ac18407fa8b48caec62459b80cdac45013403adf41038fc0b97fbb3b9450e9953718cd82b4e951b3628c7c1fa39f5629dbd074548d156437253ffd92f7de9b292b00d1812cad1ea7c26a295e373bf80fa6f173b68e7149ec6a454db833d00fc462472ac51a208341a39fa8ba8f7c8243987cafc65a48eb30e729a033cd8929a746ab6eaaba19388e9246ff28355bcec0249fab0e00b722b91bdee0b8fd80377509937f201880239ce9c9251a9d3b48d455884e98acd948f0aea095155b360620f29a279116ba08a5b5ccd6c86e0e57f4b33c5787c38b7f0b924d71d7c06c58f932d7c68422085c8e365c6787b8069d21f0fa5a414d44267b40a5f629b6cf82de5588b7e828868c5b6ab9438af030983c7c37c1032be605936002558e161ba0bb2b1b4c6b1fb5fec029ec389a375d563dde64eaf7b95e4a05e2cb7b1a4809e4e98893fbb2d79aacf0e7a0718a322ed8296323681ea398981512d04f56ad2bc10667187b2ecae2e9aa5e2922fdff22eb9651c37c75f6ca87aed6213e0048e36984e2b9b6936d61318da6b7db7c8b1538754b997dd325052c21d22328f03d5774e711a51ac6d3c333f0a529c1568840bc92ad42603b4a361197b36681722d45b497cd94f73d90fd48570b445c4b166a02c5a3c5928bff91545053166f0fca5f7b2229232a301484ddb25854d522f546c477f43072814668a734786b6810770b227487a21abaf17e79dfc365c3843363ec53af3686cce7429104740a327ce441bb8e3736af22448016b8e69784d3a2c92e0f1787e818139e19e95e2a9db2b62164221d9b77ab2ca91dc221ba5533322aa772459c6c5763f24a07c5b715197a20c7357cdbcc18840aa7af18c4684e275cb3220010386095259c4fa71f94662133622a2945d8cc6572b2311a7fc0e1091ce19d8c5d7913acc490e6c1751d5aa3e5c7218ebcaba43a8c0f6d78897c15a20a87a891bc2ca94779525499a2958a60b4878db537d9b148c01b7c2a642fedc0624e594cc318a0fcb52960526af556198fa028604a9f0181be16399edb84b38405e33b43c13d83e54483418467a57f8a796b4032d37a744fa6200b0aae04899c6865a66923eb173906b26c33231a90044c9c4d5215117ca1d50cbae1120471c0462eb1247f07a2197680856428ba494dc721bdb3760c1a97d2e59735bea6064650f55212117659380052550fa311599923dec097cb28d601cc4a117269822a2bb589ad165a8587893bec2b0e22030dd8736d387673a67151b249c49e7abf96960f5394fb255be8cd9927152211613c5242a45e87028745626de709542338e131678b871955582014f1074e2f8be14a634ae5c40dad64b78352febcb21bd987d7632c16e03261c4771bed2bac280f77da45501c2ef4d97f2faf650309211985bbee4c3a85865", + "sk" : "160b1e369b620e7891965a391bb99d9933bddd1b407a647daba289f0f16509f41eb62576b3ccb404744d2b699891300b119cb1bcbb97c090ab4091c1d15454cdfb2e0e181eb677797041b47069680a929f85da252b34b571467b564ba72256867aba61d8b14561b7a6c6cc0bd73227a3f5c840d264ca45cbb4d6c529329f011b2235b83fb8158a3966643c5664e4a4028b784aa3f84c2d21a6abcc5f0bbb5160326963929fb3296b3c65502a34c409ca9ce0fac53661a77a6ab85339364f0a999d21147958b01276c31454c14410989186496a5aa529223cc1d460a729a5d5170fbcd3c742b267d5c6aad2047154630cb8492556372e927c0ff48015b4121966c742730c223ba3ac0d9553e8f3043c84a19cc40657167a75603a2e467698d117e0e96beb199ebef57ad25b91be9bbbc31499999068d4f56315c05cf69727f6c1b09038ce4e3ba307fcce081669c7f666934a9feef44653466915360c9160a573781b0be59f23d817922bb9453802518b52250b5bfb1631f16327ea30552cd26725d94717e098e9b40559d12db67680f52aa19ce11ef22641d214b1d14689252027e68bae8f3a0034189c2452a89a8011b0f228c2f4c6c575ae8ab49d9b951b7f534c5c0c02b94c2eb1c120fbc6cab391ac02d71b3a61aedc65211314129ce950f4e82530f297f1d6b8b9fb6f0c423ddfa842f5f6667109caf5ac5db25a26ff46a771bb1731b855e909604dc4426d1598ba26b94fab7188ca788c1b473bb00f74232d7772c196e3be42c20ad9991b1460661c85a90285952a5565b9290d50fc2821a84eb80680c4d204981851882565e20455e7f70015289032d1792ee5475c499c8ba701bc094cde789b7647536ceb7471db9e4fa51b1b0a97d2d94f73024e83077dab62acfa03289197cd5d802901e34230d47cd5b469d202ad64e98f612cc286a267d17596bca1634094ca33e09b9fabb5ca170920804a3f58233ed2ca62362cdba424114275c1ea0df1183c33303efa559bca706fc77b164670058708b5a97c6f18acbabc011d8fb230ed56265c5c013bda6defd92e76c0ab04fb8b1e0758073325c8c60465678537bb5ff47923b39a800cf39eb5686b653c9423594fd7290745d566abe2735dfb4e9f7454eecc53b6fb11bd407d37e49a3155cc3561cfbe8250dc207d3f942fcaf3cfe5223103d2475d0aca6809ccce5b8d70c7aebd053f4c94bd2b66c9e1eb68b7b6989f6babff582f85d08b3926c0fef7ad5ee61cff982b690689996412504284e65bbe77123180f78efbc01c41a8262ee26765d39e94400a1a27ce4b147ef5e25d314c69aa86353f9a3933b73ea131bd7ef12979b863ba331f1412386f87336a90718da6c9265249cde518c39ba4e6ab83ab53c2d2c846f43041c4855d93099939d0bbf88722d873bdcf5bbd73519d8ef50255c7a18cfb04187147ec706fce576ce8f13928530b43262cae618f09d434fbf29fb5380add29c3a7992613733fa730a17e059c67297598f44fe28b4c4fb04ff17bcc7f3c8e516b557bda28fbf82971e8134e3082bd7497995bb2e09cb398254a12e0bdfab5a1f3234853c3067903a64ac22e528963eecbcedc58149deaae0965185b1c2588b40668103719152016e833a95184da4b10958c78b2d4ae2ca07466700f62fc687fca4779b500aa904a0d95c93464717b3c21e58b9e4c133d793ca5660348ab0198a81937a8e000225b8728477922813b9f79325f788bd8020f052801fc079f3d604b3ec830d29407aa9c2168a122434b751085804207b29062b343fb90426319998a98401232f3d0ca1b475d15650e7e9a42f498a7995c4bdcb893d09531832a4fd12c8874e4c3c65005d6c27a102725a8113d2ec9663a40255fd4cab9328b2220737f13aacb4646b392811eb3ca72307f89919525107be84a5ccedc1bb9d313f7b99d619cbafeecab88a01ba78c688166a6710b12a4724b2c661351574d7b1ba6b9265948d5a572b2c74982bb6f8546b8684cfb6916c9c1093ba1c205f92afe80ceedb043a04b67468335d28a8eb2406c72690700e724d773b40f4875c30b056e904ab688888195655d020ddaac5d1b20032a9b65501b51ba036ba2d48e5fd75b5c2a4d8b65766bb7a341247ee8121961e40cd192c6c126a3fe92488d467212b3141c2441f96a053ec568c7d2b7e1229fdb620d905119a05690cbc9564bc9cad3a66e05f641302a38ada62e07380ba315acb5a3af9f02aba7811726a3ac94723d6e66428ec8576718c4da712846d450cb428571b1786267487b353b37d984cadc2f51aa6fa58c48b011360c5b1989e104b99671ce2985a174aebf31cb5f803d29d93133d2ac1c9851031b21e8da4021b44b4064ad7415786022bdb27a187495908ddb6109489ca2a67dea269493986565e33941c1012e5504f4e5abe662235bca3a144c149d970ef3815079e2bbfc26066a7c8dc5591871e83731139951a262f9f7a2630c0e0fe635cff95b792a6b9d490f0ed14b125b652de35cff994ef341a15bf57978211ca4149fc389c60f915edc45610b9c5883080e96d77267268a37b4338ccca90490cac44a61f2795f943a25147a8943dc545c0805e5d39b70139bef006df10c695cab9cdde3b7c3a2afe823c709936d7c3818584abce96950c06b248b858859bc2231622426078e480074bfb011baa6b11336206425211c71b48d134b7b0b1c960c9429829ac5191f8f8aac1ed70bcfa4342a362c68a35591db506f2b69bff31033f5ca4654421f48afdd736e25d810add97f750530c443618e674a6691229c3a17f3b19e9d3740ae4a6aa6b77254b27374b246381483e52624a473035fda0eac427cf0f7244b3b8fcf4c835df23cc5b729bcb1285ac49529c1241977741ab15c2984343f5139e1219d65992ff75637fa3a486232c1069cb49269305057080b535d4a624bdbb78ac18407fa8b48caec62459b80cdac45013403adf41038fc0b97fbb3b9450e9953718cd82b4e951b3628c7c1fa39f5629dbd074548d156437253ffd92f7de9b292b00d1812cad1ea7c26a295e373bf80fa6f173b68e7149ec6a454db833d00fc462472ac51a208341a39fa8ba8f7c8243987cafc65a48eb30e729a033cd8929a746ab6eaaba19388e9246ff28355bcec0249fab0e00b722b91bdee0b8fd80377509937f201880239ce9c9251a9d3b48d455884e98acd948f0aea095155b360620f29a279116ba08a5b5ccd6c86e0e57f4b33c5787c38b7f0b924d71d7c06c58f932d7c68422085c8e365c6787b8069d21f0fa5a414d44267b40a5f629b6cf82de5588b7e828868c5b6ab9438af030983c7c37c1032be605936002558e161ba0bb2b1b4c6b1fb5fec029ec389a375d563dde64eaf7b95e4a05e2cb7b1a4809e4e98893fbb2d79aacf0e7a0718a322ed8296323681ea398981512d04f56ad2bc10667187b2ecae2e9aa5e2922fdff22eb9651c37c75f6ca87aed6213e0048e36984e2b9b6936d61318da6b7db7c8b1538754b997dd325052c21d22328f03d5774e711a51ac6d3c333f0a529c1568840bc92ad42603b4a361197b36681722d45b497cd94f73d90fd48570b445c4b166a02c5a3c5928bff91545053166f0fca5f7b2229232a301484ddb25854d522f546c477f43072814668a734786b6810770b227487a21abaf17e79dfc365c3843363ec53af3686cce7429104740a327ce441bb8e3736af22448016b8e69784d3a2c92e0f1787e818139e19e95e2a9db2b62164221d9b77ab2ca91dc221ba5533322aa772459c6c5763f24a07c5b715197a20c7357cdbcc18840aa7af18c4684e275cb3220010386095259c4fa71f94662133622a2945d8cc6572b2311a7fc0e1091ce19d8c5d7913acc490e6c1751d5aa3e5c7218ebcaba43a8c0f6d78897c15a20a87a891bc2ca94779525499a2958a60b4878db537d9b148c01b7c2a642fedc0624e594cc318a0fcb52960526af556198fa028604a9f0181be16399edb84b38405e33b43c13d83e54483418467a57f8a796b4032d37a744fa6200b0aae04899c6865a66923eb173906b26c33231a90044c9c4d5215117ca1d50cbae1120471c0462eb1247f07a2197680856428ba494dc721bdb3760c1a97d2e59735bea6064650f55212117659380052550fa311599923dec097cb28d601cc4a117269822a2bb589ad165a8587893bec2b0e22030dd8736d387673a67151b249c49e7abf96960f5394fb255be8cd9927152211613c5242a45e87028745626de709542338e131678b871955582014f1074e2f8be14a634ae5c40dad64b78352febcb21bd987d7632c16e03261c4771bed2bac280f77da45501c2ef4d97f2faf650309211985bbee4c3a85865a7ea65e4729daac39a47c305ad3084af028e66f759e0e22469d0386c10bfc23a0f4dff8e56f68440836a072412a30d851ace2c7c6f02d60e7a8420001a63e6c6" +}, +{ + "dz" : "995eff7e0d195c6d0533f3dc194d47e60f9ad14696144cde694d60a95f3e96b4b28f7e7a15a005f92400ce33db073d49b53871594a88fc45e0f94207b5f0f2dc", + "pk" : "5cd35cd8f09ec13054176c506d02a7258a84eb685d14c3352f0b0051757c30d4184ab6a37bb6058c4451e89106ad2c259bc6791de49ed9dc0bf62bab1201429035c8716b864552a26b0549b1832a2bb01cc8f8cb55630618a525f885cb6fb407f042610681428031399e5666d56a9656e1a530460ab4178c3e957d22244b1366750da084f572399a33bb452c7c73f3cbe9a7028cf3849b475606ea2c96958dbef17aa08b3f15c146edb65de9379f62c11226f9b4b85802694614eb229c8ed44198542685610f53885f5bbabdd95c5597f89d825b0f441b21aa476ba4970be900a2f40cb742402c2093803f27ca37d06347615131b81fe6ac6ac9249459c92d92133870111aa5176c6bb828a4198c865a1730a84961f3914379bbfbeb46411c1705bc86f8a38a5f817f1b4c34e99784773051764b3f55d38571e98d744043287a19dddba7d4eac3f0b98173d09f0cd10b22a0bc0417a056c66064c906b7559ab134b6c47baa7932540070811d3ab8f5f265822873b4c78af45514ffdb6d03d79c24a88531d4ae7230486977b612cb05b906ce19337ca1f0455718569e80c2c2c795b7a156e60c5c65fa19fdfb5e4fd96727947fd66abd94774a5bc45fda822146a12b67534ad93aabae123af9cba2b2a376608cc6335aaa99f759dc964aedd80e432c6f417a1a65c63f639b5312c35038faa9c45051ba31c66912538fb51a85189d846b799d8c2fedc439ec8685b547376be49a83fb60281accd733001d729e4156badffb3b7dd8cb40411ee7a3970a168357a89dcb75535ce341b5b47403308bd87bba01f5cef30634c9d27d56da4d4373234790acbfb5051ca2a8519a42e610269b4b32c64770a5db4caa1ca6670c432bd74745fbba2f22377c729446954a6e067454639c3771aeb626871e3558a0f141a37c2732b13b13532cd16462f7822ba2869a0b20717e3675a328625da796e12c4403d380cdb54930db78493994c0793fd67b0a91140758fb78d229051e696c8707cf5a1c40ef511123b7c6de51ba4b792eda810762cc114f716c66a79dd4f5b0865a1a2a1144da80c4106b72aabb0a8f8036bde19b204992dc600956ab076ccab601f4250ac4b2cef77c38d6b6ef8907feec307ab29502b269dbc063e337ad43958d893a36318c6c052549bd907313c2251744ad02c30f78d0b394635508951856d1160706cb042275ba20a4bb6a734f9856aeba164af669f43c5016f1305e8084389581bc146168c0914d1a65ae5188e19082d585af435c183df28179c6b2278491dde450e7b1bf64075e0a9a8301454b5e111e39b0cced002680e173c5db96de082c3c399e398210c974b6f47449dc9326c1a7a79f893f454834e6ec1bcf0a860d962a4e05a1f51825981b18dc4ab661abcc98d4313cb40baa402307895460139c75b6aa69e27c5e69273141487b849a42996a55788b3b42018da0ab1c315d10308f05c54176d727a04b656ce6859f69471a186a4ff6b17b877070924758c83dc681292bfc7618f2b75413c79eb9b945d1b2aef95a47cb21cc8982f405739c9064975b5ab875ae5ddac05a65a43cec4ed80acfeb15aae898b995e649f32b98613c77fb926879ec940bacbca0696cf6c6749604a1a59979a623477be871a2278d22134a95ecc1b116c48340c6c6981adbe742ede1426bb65b942302162b8164352f918679d53c06beab47f07c8a37aab0a7449d45e01cfdf9422a783e06f645353cb56b8c57e28840e074629bd58b5646cf1c96003181b915a71caa00a35fb4533df22b2367c9bef95ecc85359a236e23a425f9c975ef842ee20228c66673f1ea3be278b0fd43ad4c004655532654598f34a257bc7c81dc0999266c8c2f40a4d9364f602bac27145b5be7c4fb0759288761ccc586b9039d6ee57858a21a05676edb52c937f11c35fc091d3baefccc15bb953bf5c50b95b449b8db449810680fcc53169bc8403bc70a5b2e3dea7af89aa0fd662255197360b8c7325545b7f45f2dfcce05d939ee5556f5c63cef52cd68e8399ec25726a316269374eb94bc3884011c89890e828b5c726d149cc3446b8a12d76c35545eecc7aaaff17030a0cf9c993e53a88ca000116c2b206f0187f725acc696112b5c44976a22ab617a0c42a64d03b8ce88b7a8aa7cdba28a197a5d3bdc64cf089f922345dae5a7c6bd86d17444f21dd9b1a5c82b9fc906c4ad49e0", + "sk" : "41a174fe5ac24562ad78e74c8e65930e7cbaca489509d26ebd09a742548fd3b90406b2b8a218bdbbe4a5222c13dbe576d37c0d4dc20f3e416dba4b784491ab7a534d28b90c7121589dbc55bb214af6475853b74a4c048885a6ceb5184535a5cffe6c3a1c43c305fac42ca17ca7f64a24700c0048447154cf15d25636873d41c0b588190b2d0178f12940f5eabec85a59f90179076abfc3e734973b4074c721a3d41ab31465392841ec558580711aafa93bc1382efa153f5bac2fab8c17eb7872e9d3b7b6fa94c2ea20d964388bd5144c237771e1c6a7f991d37a55975078dddbb76499b6b87c974bab79ec5513d839cec1926ac9c5a7e45861e0a226e6f2b00a95bd52a17eeed93f573c19724c593ed7749e542287a62ae01a4021737242424694637649771345408d2800b5a03872cf6c70ce848b8ca2c57f93543bf7a61434a48f536338051bdcb092dea6690ff3b6ea892612ab5472c0cb9e7987c3756548937e47a2cfed69ad4444cf35242bbd1b7d65ec028f2116507ba09ca114e4cab4bcb736ec5109822b0a590270d3268de357bebf98317090185db82b6c28cd4d7838d8a2368c9a315661b3554b43a8cb4cf376bd771664b5ea2c50eb929eb768bb685812ec4853a33a49519ab98c1ff8d4cf37b2bf5b97c2e0921a0d769abe68c7e19a87b50a6a56228f4fa4915b2192d1e4225a58b3d2f0ca23a05dec8bb5ff613e636c95fbbccbc5f86d49e447d0124631f52fe575652f782cc5e3a376bc868695868d17b254c797d8cbc543343804c7b5bfa731df211f48b20d0930b19485531c678328ac647c2260f6062af02cc2c1778833a62b4c40bbc095b285e282b641b75c5cbafe41a0ebf88b3cf890b13b5b8b032177754763454ef79403b6922cb012013ad810cd6875759693b298a57d107b8b568778e6c493239719c73249545ccd0520805ace114c0b7b936314a6af1f37bd3876322ad855877448e5ba7162cb7c7457c8d2a47d128b1bc8603a60d06b044c7611239ea90c0cadc09a4e8c4cb0ab386ddb2ac14c2741bb7ccf6c0387e6966ec824691855cf748b680134535397ec427df2149f27fb14fd814d47031dacc858c52a5b435b6d9b8c8f76a40ec0486d2c670b5e4878adf7adeaa9b752b0350775ce1b9b590a9695c3c05c2ee0a6f2064a363664dff41668c3bfac172e1ba87e3d3845d1119a36f52c394cc328d8ab23914609c058b8f72b4f8851048868216a9b13c7cc55177ce559553ad28ebdf2c927aca49ca90142e2caef59c9d457387d81c55729177c665de8d2ae21453f91b7663b2b1f4304bbe02499f690b95ae18976a00e3151c570c479a6d512afecbe34a2a2f2b7cfcc03290a052f00a093956091c22729e57044dc066f892799b9e263dd957296865e09a2c15e300c4cd1b1d05067fa1483c6e765c551425efc7d5b15517bd911178a2b9692a1fae74ef4cb2785e561a51c498ffcc20f039e0ce74dc62c3a56303774449661f171487cc2cacc071bc3b2cc54bee99332d655ab4e6b8b9a8351397a398c484ae22a29a4187c6f5690bc741c23e9c2af0916f8f4becd630d47010402850f3111930cdaa5fea74e3748492e6b2c589ab4af5a011bbc8ccf878bba2708720408cc56bd83859e62ab95dad5c17da8301010933ec27d18f02318fcaa9fb5336bfb608cba4d0b59cbde5c8317d09443f7aa641886201b62cc3b233903ba98cca9a40ab8345c1dd886bfdd87cf6ee2c50af15bb0539ac2673d0ef08e58bb34e3a83198093380f11035e38a0cf532cd47a45ed7cb95bb9420aa62f779345b6c851f9b09de8c79ee1a807160763b9a0b26e74ebb32aa2f429740319285161585a7bfb6f7294669cce50a044ad055d2f747070aa6cdc5195b221dcef05c43456dd2bc1c1784b397444e6eb397f35b5e4cb8aa04a7207633ac1526bdcb9591494554d03557ce60820325008b42acad262f8a062e1ad11716001d99e8b3a1caad0226878099947a2511f62a333b1b97f5b1654a35c73f0c69fd92531d32a33cb50be57041ae870e15019a0f30c35ecc8f33ea39ae209d7f65c5937b5be1a82192c8c335f35b36d6cbedfc953eb140e191c819a0ca16fa8775d67192161a3eb1a508b0695d61971cb9b4ca61ccb459b8fc3748d7c9596a93a88b535a5cd35cd8f09ec13054176c506d02a7258a84eb685d14c3352f0b0051757c30d4184ab6a37bb6058c4451e89106ad2c259bc6791de49ed9dc0bf62bab1201429035c8716b864552a26b0549b1832a2bb01cc8f8cb55630618a525f885cb6fb407f042610681428031399e5666d56a9656e1a530460ab4178c3e957d22244b1366750da084f572399a33bb452c7c73f3cbe9a7028cf3849b475606ea2c96958dbef17aa08b3f15c146edb65de9379f62c11226f9b4b85802694614eb229c8ed44198542685610f53885f5bbabdd95c5597f89d825b0f441b21aa476ba4970be900a2f40cb742402c2093803f27ca37d06347615131b81fe6ac6ac9249459c92d92133870111aa5176c6bb828a4198c865a1730a84961f3914379bbfbeb46411c1705bc86f8a38a5f817f1b4c34e99784773051764b3f55d38571e98d744043287a19dddba7d4eac3f0b98173d09f0cd10b22a0bc0417a056c66064c906b7559ab134b6c47baa7932540070811d3ab8f5f265822873b4c78af45514ffdb6d03d79c24a88531d4ae7230486977b612cb05b906ce19337ca1f0455718569e80c2c2c795b7a156e60c5c65fa19fdfb5e4fd96727947fd66abd94774a5bc45fda822146a12b67534ad93aabae123af9cba2b2a376608cc6335aaa99f759dc964aedd80e432c6f417a1a65c63f639b5312c35038faa9c45051ba31c66912538fb51a85189d846b799d8c2fedc439ec8685b547376be49a83fb60281accd733001d729e4156badffb3b7dd8cb40411ee7a3970a168357a89dcb75535ce341b5b47403308bd87bba01f5cef30634c9d27d56da4d4373234790acbfb5051ca2a8519a42e610269b4b32c64770a5db4caa1ca6670c432bd74745fbba2f22377c729446954a6e067454639c3771aeb626871e3558a0f141a37c2732b13b13532cd16462f7822ba2869a0b20717e3675a328625da796e12c4403d380cdb54930db78493994c0793fd67b0a91140758fb78d229051e696c8707cf5a1c40ef511123b7c6de51ba4b792eda810762cc114f716c66a79dd4f5b0865a1a2a1144da80c4106b72aabb0a8f8036bde19b204992dc600956ab076ccab601f4250ac4b2cef77c38d6b6ef8907feec307ab29502b269dbc063e337ad43958d893a36318c6c052549bd907313c2251744ad02c30f78d0b394635508951856d1160706cb042275ba20a4bb6a734f9856aeba164af669f43c5016f1305e8084389581bc146168c0914d1a65ae5188e19082d585af435c183df28179c6b2278491dde450e7b1bf64075e0a9a8301454b5e111e39b0cced002680e173c5db96de082c3c399e398210c974b6f47449dc9326c1a7a79f893f454834e6ec1bcf0a860d962a4e05a1f51825981b18dc4ab661abcc98d4313cb40baa402307895460139c75b6aa69e27c5e69273141487b849a42996a55788b3b42018da0ab1c315d10308f05c54176d727a04b656ce6859f69471a186a4ff6b17b877070924758c83dc681292bfc7618f2b75413c79eb9b945d1b2aef95a47cb21cc8982f405739c9064975b5ab875ae5ddac05a65a43cec4ed80acfeb15aae898b995e649f32b98613c77fb926879ec940bacbca0696cf6c6749604a1a59979a623477be871a2278d22134a95ecc1b116c48340c6c6981adbe742ede1426bb65b942302162b8164352f918679d53c06beab47f07c8a37aab0a7449d45e01cfdf9422a783e06f645353cb56b8c57e28840e074629bd58b5646cf1c96003181b915a71caa00a35fb4533df22b2367c9bef95ecc85359a236e23a425f9c975ef842ee20228c66673f1ea3be278b0fd43ad4c004655532654598f34a257bc7c81dc0999266c8c2f40a4d9364f602bac27145b5be7c4fb0759288761ccc586b9039d6ee57858a21a05676edb52c937f11c35fc091d3baefccc15bb953bf5c50b95b449b8db449810680fcc53169bc8403bc70a5b2e3dea7af89aa0fd662255197360b8c7325545b7f45f2dfcce05d939ee5556f5c63cef52cd68e8399ec25726a316269374eb94bc3884011c89890e828b5c726d149cc3446b8a12d76c35545eecc7aaaff17030a0cf9c993e53a88ca000116c2b206f0187f725acc696112b5c44976a22ab617a0c42a64d03b8ce88b7a8aa7cdba28a197a5d3bdc64cf089f922345dae5a7c6bd86d17444f21dd9b1a5c82b9fc906c4ad49e021cee8b1f3fe43508e7bb3b567d02568cc93c39c3cc347e2dae6e0144714d80cb28f7e7a15a005f92400ce33db073d49b53871594a88fc45e0f94207b5f0f2dc" +}, +{ + "dz" : "3e809ec8dd0fec0d911a4e3fac20f70fbb128c5de94dc7184ca7310ae9157a98d8128601c28b1def8d393a0db283229f7c7383152a814e7cefe8ef9d9768c473", + "pk" : "66834aa6b266f0964efa45c0469249c3fc0faeeb19d1508cb7c409b49a7e38299920c3433da3929b2552d5e9a1f092383e3b4d3d8a16ffd199f7d933eaa506062697c29b1fbf10292a4758d26ab61f085c31a0a3b85a19e956860f93a3ece8a0c22426b40bc8d0c1191754803d0204ff048c07f6c778fc685b2108b0327dba9361b00c071c8223aef0949ddb804075c3a0178f41bca68b676ec8469e417547617c8b8ebb6e19e83af1ba27e2db7d08e11f25805f959285add216c25a029684160a880fd2dc5753709ea3d81a59a91357205cf126c24f8858a3757be1c562c65166a0800047949c062bca79e03836d05aa6a91a30856a367b087b455169a7c3591091e72c96b7432397b6a257723508661349265c4c475ee7251e4cc26d739b33190cbb07a993e5b72288a55d5792cdd2c9177c9541f0a70bf066135e06a3ff1700af24247aa61e70f4727e6a9fdad70c470b671ca31a21d236bcfc508a833714182198c4c41bd1aee23b5acc9720a3e955adb119e9e06fb6c8a7ba5a37bea21565f77f7f037f0ad71d6ad13301a547fe8458c8363feb218a3ed5bf594c3bdc7a03003641da15479304810b5a0c949417b9a8473f76ae6c13144d7b3673074703da0389e82ad34165f0c258457367b5521128ec318df886eaa203e259bca111b68e13ae684b1f1b3781d8305193e094c20b1e91b473ac9992d1e77db85023cd043b147681fc9c2c9c2c1237c27f1e459b953ca0711a318a4b76d924baebf599d9eb852dca1dc5f80191b91281f8345d774a29053513f159164a705c954e53ea26b6927dc57a0fae5a19bd33bd67339e8eb925576a2eabda6b0a4743abe05545e080d5495402eb0629859671e130cd048235f254fff49a7d394f3b1c3de06a7847473119e218cf0944609958300b93046869c026cd93e21925a30da0389e24ba6f08d498748730e2b40d1c73452de8b7570027579c11a7417f2bbc67122c9286d1219d7230ee5b0c42d724d1b1cd4b031500958dc7124177a25651781657904fd1267f2bb69d5c929f8967cf216924d63696627c917f82bd2813563cc443705b0a1b279eab237326b4ce45504ec710ab95d01ad812559b2b8be763c1e9c55449a1366fa2cdb6d0106856b080a16d7e3700b0771a422423c806c62614b047820ad6876d7740b35fd674d99605fc61638d863ce5cc6a55d62f83a4a68aac10ac065657870b5c623970db1a40773500757178f29d54548aefe92eac306fa8f926e5f84b15f339f4fc388a554b79d87325c81f9e9989c690920f018fd4440afca405b1b667e489568121178cb7a18ee2c38e10ad4f5a09df64a76c0badfd08627861144f8a449df4089a08c48cf1b110b443d16386042b6f24730c921643a6f8b7aedb9a7036339f1b156c1c4de7f4a03acb57b1cca827146f4bbc30f17a32ded42949ca5340b0494cd29098260a87bc7b50440ded82befaa1a6c4c28bcebcbb16990978ea92a3709b817996f51a6e080578f2d060b924c5d9b93098725eea946ceb84a0a884c7fad252bfda7aaf374e5ff8703941a8483493a5143e0f9b6f5ef45f683c2ea2c4b5e8b92a46984064b97e28d339789a8654e27e38c84ed7e4cb204412a434bac227197528c6c6e1625dab98c25557e16cb5b8249ebc11caade0b5fb505527d45981864d4abc8e1060cd9a7467465064c9b8cce823b6bdb9c702a7a30415b4fc6979d2476b4511909c90559f70597375c050189ff2932852a51e74a21b32c834c734052c61137025c20708263e0aa71d87b20263bace0c0c98a58cdfca4889672e6b654c003a7e22465f97021ac7c11fc4d1c0525ccab768c6dbd124c8c533f49ba88629c71fd1cb6ebc4aaf09ab6db011348b2b0691bcf8eb1bea9588b640cf3fe97e35e92440284cc9607d49a3891283ac96c32a2a223d1c372b509b1d9401ba6bb13ebd5ccb6c44ba12e392b4d165c4940a714359ce122f6b34bc1344af802992c6fa2d85f1957045bdbda400b526b21bca1a0ce181531c8bc644799ee8477af16fbbfc33879868135a5adc748f88799d23476aab0643e5dab979f3658cb1cf19292ac6f30a486353275cae5fb941b2d49a0d0349e65917b4f4cddb9a976f322d8917b70278ab9cb16ef193cc33b312e1689170532f31b001350225180493d7966e2b216c709ac1bea73f1c624a081620b7981c1c95ae0387aea62f", + "sk" : "f1594ece355ed8872280f422ecd4b02c1c9fd2716ce375a9c01b172b3c735e4908dc96c1a58945e70813250a95c1d48f6bf159aaa265da841dedf23d0bc71809c6bf16856a0d316f59955dbbe18a39175295d5899b4abaeeb6a7b3f9267426b6190c1f3c7372a0235a644b1dcb577065a6a2e6cb130f8150a8633ca8f388ff6935c2f3584508c0da3898e5a1be423506e612982d80179c4cc950aa35df21244bba78e2b24176769c934a020554aef4d43caff4203ed5351bf822695814cc0ba1860a27031c0c9de66ca3675ecfbb3aea48496a2179e6124e755656f1412b04f2aad353c93cb068910c0c73362183063a233183db280174c0648c3422361954be811651380ad3975305bc6e09b9736e911d6c55083f63347e2584e6a26bf3200c7cb9c1d71522fa87c684ac208a81b3f01298ab315773ca10d8243f465055d8489d5ce385e7c6c0b5cc741df52b7e62caf73509ccb814e9644f6c35bb394a4094745ba69b6b8f933b715581fda1abb0f8ac9ec15ded803a28e057e4d87bd7b9c53af6b943a00e3f694810e3878e3359ab109245b29a962ac32d1a066872a6874a4e3a7235c5157250086d00610e21372218859f807207e20911826b1533c851024054441014bbd618e65056576aa6404a1499c92683872eafb152fb2a171ff02f4f895f3a4b3d9bdc22a9627c6095957f86b41395b98b947e4611ae496844ba3083eb9228cc0277cd21c050f181d79bcb90416d4d5c5932f5643766a3dd1295cc2805721b58a0596a371cc1eb69c986c2b230f4ab6905468ce77916c816df1b7668e6ac5ae2429cf56a9fa6a7327892556c58ab5b24be7a9beff69ac35ba63a11c6dd15772b501dfbbc6d1437cb2ee29c98779131a56a28258b8dd6237629276894af0b46af6ed66c2b7272fb3ba9b936027b330e2f20b0813a240d27c7ae10778b0a0776e17751f85f410c373a6376670007d8eb78a7213a5ebb8a89d02cc902a62ca15f15709fef9caf5a558168b90fae5b5f3909259184c20a0c37a0196a37b2232c34a32704301cfb56066ca60aa65a6a459689bab328114e731650cc690b7f50814da97dd2495302fcb61ee375afa57eb06247277ab8ab96355ab42c87714ec6020fb6f95f05a02e679abece5069356c70d2444020521eaeb6376af0630edcbb1b655cee8a734d577353d95e3f93bb7d703a6399050e12c1e41340807cc91e274970f27d7ec86c0e7b632190a65e886b52e02827795a8e3ba1aca22c80e59765461b128543ae34965922876f2c418a47cdb447168160c12bb03e94fab4ff012845e15bc17985a38c7f3c6b6ac365adc1e8744b15334079bf0b081d3e2a9572119501892537bb0be05249661a5700bbb268f153603aae0850cded06a4d7b548550797459141beca50dc609110b22fbd61a2ce84c4d437663be27cee1b8f234b4e58bcb3d8b63295a5891ec1a63a933420a33eed084626f83dccb82002d844a593b693190f4291372dd6428c7b90bf9a97019b7b1f9bae23c87f152b6e514554cf6b9703604cbb2c864c94a024d54b7f3a2709ac878a8c2a9ea74c03f9a027d0b4973b062a45340eeb1b08aa2236b021f9fc56757237cc9411cde098aadc935e52832d3a3101268ca57b566c1804ee9831863b2fabbb9497833c2d9097805b3d125c96c2eb3bc2612df211829fc842ee6ca3770852beb38d48399a195cb91fab32e0b6752836cedf05345fec5143b28a5ce2a2510548ca95666c579f36e477e67a6ae6275ad32813a4f3795a602d24d6372ee039e50844cc000be6609cf388686cfb1f6e775951a6a2626095b190191702114ad08193d714abc32849a5a33858b1f951b09fb115f2f8481610cca8bb14a10b54e8e364c471ae4e57037c3baafd9ba275f1a4baa82c585279eb01403b2669dfd6b1735c5b7d85c5efb3a1ad8c0e8d40198ea4b4b7d1427c39660c04635ce59619b5824c80b84164641ac45257817c0cb038b3047c30ec460298c75b73a2f7f0b82b6a6583391f58ba057a6581bada84b5978888e15e9462952349961093354dfa34c0c08972b7571fd99197b13aa8b19a7f6920e5d41f50613a5c2a6036b79c0037113f41a3146ab6d7235185f51526f9b564462ad4c70f8f30346ce7282635783b9850eb9065ce58a272193166834aa6b266f0964efa45c0469249c3fc0faeeb19d1508cb7c409b49a7e38299920c3433da3929b2552d5e9a1f092383e3b4d3d8a16ffd199f7d933eaa506062697c29b1fbf10292a4758d26ab61f085c31a0a3b85a19e956860f93a3ece8a0c22426b40bc8d0c1191754803d0204ff048c07f6c778fc685b2108b0327dba9361b00c071c8223aef0949ddb804075c3a0178f41bca68b676ec8469e417547617c8b8ebb6e19e83af1ba27e2db7d08e11f25805f959285add216c25a029684160a880fd2dc5753709ea3d81a59a91357205cf126c24f8858a3757be1c562c65166a0800047949c062bca79e03836d05aa6a91a30856a367b087b455169a7c3591091e72c96b7432397b6a257723508661349265c4c475ee7251e4cc26d739b33190cbb07a993e5b72288a55d5792cdd2c9177c9541f0a70bf066135e06a3ff1700af24247aa61e70f4727e6a9fdad70c470b671ca31a21d236bcfc508a833714182198c4c41bd1aee23b5acc9720a3e955adb119e9e06fb6c8a7ba5a37bea21565f77f7f037f0ad71d6ad13301a547fe8458c8363feb218a3ed5bf594c3bdc7a03003641da15479304810b5a0c949417b9a8473f76ae6c13144d7b3673074703da0389e82ad34165f0c258457367b5521128ec318df886eaa203e259bca111b68e13ae684b1f1b3781d8305193e094c20b1e91b473ac9992d1e77db85023cd043b147681fc9c2c9c2c1237c27f1e459b953ca0711a318a4b76d924baebf599d9eb852dca1dc5f80191b91281f8345d774a29053513f159164a705c954e53ea26b6927dc57a0fae5a19bd33bd67339e8eb925576a2eabda6b0a4743abe05545e080d5495402eb0629859671e130cd048235f254fff49a7d394f3b1c3de06a7847473119e218cf0944609958300b93046869c026cd93e21925a30da0389e24ba6f08d498748730e2b40d1c73452de8b7570027579c11a7417f2bbc67122c9286d1219d7230ee5b0c42d724d1b1cd4b031500958dc7124177a25651781657904fd1267f2bb69d5c929f8967cf216924d63696627c917f82bd2813563cc443705b0a1b279eab237326b4ce45504ec710ab95d01ad812559b2b8be763c1e9c55449a1366fa2cdb6d0106856b080a16d7e3700b0771a422423c806c62614b047820ad6876d7740b35fd674d99605fc61638d863ce5cc6a55d62f83a4a68aac10ac065657870b5c623970db1a40773500757178f29d54548aefe92eac306fa8f926e5f84b15f339f4fc388a554b79d87325c81f9e9989c690920f018fd4440afca405b1b667e489568121178cb7a18ee2c38e10ad4f5a09df64a76c0badfd08627861144f8a449df4089a08c48cf1b110b443d16386042b6f24730c921643a6f8b7aedb9a7036339f1b156c1c4de7f4a03acb57b1cca827146f4bbc30f17a32ded42949ca5340b0494cd29098260a87bc7b50440ded82befaa1a6c4c28bcebcbb16990978ea92a3709b817996f51a6e080578f2d060b924c5d9b93098725eea946ceb84a0a884c7fad252bfda7aaf374e5ff8703941a8483493a5143e0f9b6f5ef45f683c2ea2c4b5e8b92a46984064b97e28d339789a8654e27e38c84ed7e4cb204412a434bac227197528c6c6e1625dab98c25557e16cb5b8249ebc11caade0b5fb505527d45981864d4abc8e1060cd9a7467465064c9b8cce823b6bdb9c702a7a30415b4fc6979d2476b4511909c90559f70597375c050189ff2932852a51e74a21b32c834c734052c61137025c20708263e0aa71d87b20263bace0c0c98a58cdfca4889672e6b654c003a7e22465f97021ac7c11fc4d1c0525ccab768c6dbd124c8c533f49ba88629c71fd1cb6ebc4aaf09ab6db011348b2b0691bcf8eb1bea9588b640cf3fe97e35e92440284cc9607d49a3891283ac96c32a2a223d1c372b509b1d9401ba6bb13ebd5ccb6c44ba12e392b4d165c4940a714359ce122f6b34bc1344af802992c6fa2d85f1957045bdbda400b526b21bca1a0ce181531c8bc644799ee8477af16fbbfc33879868135a5adc748f88799d23476aab0643e5dab979f3658cb1cf19292ac6f30a486353275cae5fb941b2d49a0d0349e65917b4f4cddb9a976f322d8917b70278ab9cb16ef193cc33b312e1689170532f31b001350225180493d7966e2b216c709ac1bea73f1c624a081620b7981c1c95ae0387aea62fece8e4c1277c5b64512a4b2bb7cc80044f98e2b654e5bf0f4ea520caaae1f2efd8128601c28b1def8d393a0db283229f7c7383152a814e7cefe8ef9d9768c473" +}, +{ + "dz" : "dbf1c465fff3d9f783bd9ee61a573715e45691147b8904439b5ffaa64f94ff7bb6d75eac6c76ced1b0a025b40a55440712ad8424672e761e9bc400d63812006f", + "pk" : "14830be3ea225e8161039550c3c320e6c57220e076224aa8fd48b4db59a30f71b2a2fbbeb05b3885819b672c48393c5fe1865a4c113b736505c1199b807c5e7669b7d2499931d899b21b8c1d9caa129761bfa3974c4a85677a0ea1a49c4ee022cf3048012a3b108b4380f10ad2c327a009717a64704a62cb31446c5c810a5a9928e1e4564f95b027ac251c464569344f0086106f7a4dfac13eb194abbd64a8e7db2352cc07ef52195de869bda087cf838fb42862f6346754f1744de8a414464ecaaa921bf76a4ee344e3055ce0fac32c15bc9ff3019c7b9205737426cc29239721ecf65ddc241f33dac59dba06db577514891f70d020f5b240b03493aba381f6716a16646a8a8343efc41394a90cfc896dc04c4fba8aad7cd66005e426a3113dd1a4be4a661eac59cc2742a229c6bab9ba26cfa9194ab41674e89a410bc7e8a25bc410bf95738f8420c64de5715ae624368322ec4a513647ca86a231e76b62e52753c939308f8460a7650a28d258b24c4662793e2ad4454b5756e1692c6e6822a8dbc070ea81f4a85d6a2a852c452235f63816a08d957cbab030c33b5535c87c5e7851c55503898f21138b61558b38b04ce78527658082308117978bca146f8f338c4b4b623177a0b1a51b5f134ba58c19b4db69182807f3bcb29838a0729cc2d34200379cba1f751b6764c27d471fcf7a0b3f9a404fd3bf98150150b540d79b1df00038ce770424838f58e10aecc304f29a9103177752520ae3d967ba33ac2526c85d9a7aee03845b911f9c0a516f10a06a018af24319385a81c153653fa81808a6bd74680f684a52b8a72ba5288b6e75bca97a0304f2c3d8e940dba7239869bf68c951ed8884dd32cdb254755098cef7abaadec1a47a7a0fa646b1ae78af8c608ee7535bc43371bf1206c8680634174426e062ad9c28f4474a01b6785df35df57014c3e8858c2a2ed9d911cda8303c318bbdb13370b07bad82acbad0bf04c3ad2c491328a20790c39292629152dc0e6a29199251b5bdc956a2c4272a4b894a87359a11803a8b67e236837d25a274c97eebb6a8a9e7ce73cca9dc91a1129236730786de0a22286b71afea28e01abdf69cbf460ba2d7d69143895630f526c5f2c6fe9a289a3a058d84b64228389c94984644bca5fa1f61004a3edcb94557093345991bcb9bdea45915a5bb95618f4d62cce22717a67c60042856fe8ab437066aaa733567694dcbd301307b4eb02cce11124bcde6a79819b95ea621f1b11492315e60f774bc5b207f42c178708b28a18c9883561cd66daf17bc0bc42e0050b2a8157354f7945828a488a941363b3393a1112c691e123c6b5699a5c945038b6b2dd6725e7e619bebf1c34c7c32245461d32525c5f49a763944cb64581cea3a178146dc759c29c995ca0793df62cb2153859a32905e785e8e6ba2b834918f2c2dc5cab10f8b95867467adc87111d7beaf69099400aa4e908fe0a299e8901ef5f9346fb07ba287235087a1aef51bc8933823d22b8a02c1fffa56ea5b1dfb143ec1426f32959a4103b9e343108c87aad2fc0bfc7384c0101afcb4740f01b57b483c0300baba66543adca822b4381e99870727a75c491a1129af47d768e4f59fdf05c6f491aaa5dc11b9ac7e20e541aaea11b6ec8b27e94189dc1be939cebfda109cd53f38fcbbee7aad3c65a3c51aa3970ccb31695bbfba3e3b10cdd0d37d848309ebeb3ed8601ca2d1479f3aa0f2766d24b0b0feb01d34bc5627ea8dcbd935a2303bd6aa6d01e7605d23217b98b2ce8564ce077032abc35aa6afa046254d9a63be6c4bdebb95e0020ab5fb89aa5b01238047a3c183188bcec1158c0cf901636b3a459a223a73986afb886787cf93a8aabcd9af1e4cc585cac6f6f424131a9e01fb49bfb38ea664ad31dc16b2dc3c701753a2870cf9c27114262167763902b58b2f03bd906aad3b0101b7898e2663bd458b5c4bb7c5f49c28fffb97bb4393ba3aada4c023e25427dd5016b089591277b13dd0c26ae3ccb06c088fac04b475477ddc1be06620cf3754548a6b2a551aa1b97df5faa296c6a6ecd052cda5903533c93445778755876136c193fb0e3c937bf71ab2968a25e8d1c9e49a9962ba0c78951f64882c826016f63b97e6f8ba0242a45d69276fe0ce06f14be7535859c87a9875904870890c5a620d8632f30f55d3cae33d1c6f5896e6b12354a75c7894d8905403", + "sk" : "6cb427a837b55537299e1a8836b9c79afab583679fcd65663b17a3008200d9035fdbd50b99449ff6d14d5e0611bf21c652743d60268c89e0c75c5b4445707215a31593349a86960219f0cc079a2e39e221060aa5dc19861197049e817f692ca55e328ab0c32ec8fc5cd25a83311bb49ec8929455330764885c70c9d988a5dfabcb1366ac382b18bc866e5b93b780736558a0afc0580c4af75f6b6c63f95a454f0bb106627a2294af45f02d948c1075618b8fb01228401b1fdc2b65b02b52f40452b86a1b235298b535b7990ab75565f66568be06aea98a6a1e4744c1728914d00cdf16cf3d940ada784e14eaa332026c2f3cb05a7793c4239d5628281356170b181aa3ac98af93193cb6a9bb6a682ea5073e11c5fa7558c9f713b98a424ff86d84fcb5238b8258076529311d3b522189b0a440b4194bd15344a5044216a524862acd43223b51682df641ff3876521cc9372c19ecf117d505b6e1b26a33bac9b81c13b2900f11d849a0843a44c3061cc111c34acedb3b98a49874f4642ddbac92d969597a635d64109ba5d55a20968b65072ba0bb4349046dc3c25cbe154790d3353e580c3855a755215aecd7b9c800aaf9d12816135f80f010c07824483c838c8176bb58cae99817f1d2a538d694470021e3d87989f4b31e19539f1b60211022a3a74df892a08db12b03e3051d4b3ba9144926c1431a87cfd0f5702a7a127cc09b92f2a1d474b013cc9443f137e0bb1aab721ad975c13bf69d6c5a2725a2b2ac88b80d7b8079b811e978caeb96a89f97781dd7c422461d6a309add83cf83d563d2bb3d381a1dd4147943f76010d292f6703136d127840c9c4b532b86d46587eb54ea613e542645d1156f5b965c772905f90b3f518821a1b18961d61acd7c0d3fd09df90b9a1bf993282b7de33a1ed638cc9a162fde471971d2a5e946b70bccaf00fb76c02a520343b24f1173d4d27e2ac574e1c123e7d663bc054cc432bf1eccb0ac775377c65bbb2291c9695b55a2265f87323a7b63980aa0f1485775b2369ec3a3eb5a0fd126860ad14db7928a9618c684c7790610c118a0aab2b3adceb88b278a3fceac58dfc80bd9f2c7a2d55b35b82f18363a3e577737788dfbe0c6d995b3da953a9bdcb46b1754e0a187f872c2af0b0bfc70327646ca6778928f1005767a091e727d6f287a684199eb36a21b5a42d0c9775b9a2cf6d2ba31ac7677d075c9b207107c79a863c4ef47aa71a0ce5a409d6de8b9549366273967a760101a67c3aaca617d49960fd658bbeaa371c172113b017e1445fa2096428074857142b07782924909c7097412280d45930561a80cc47720234c94cd682ad3c18572e5becb8413b1868f7f3941e7256b01280330620056431911a638828162eba4c7df9c4c5c537b9738643e72b04f4c280048a4cf37becb58a83cc0913ec58026b59135d15fe8950832ca27c1459cce071feeba54106b89cef37bdbf9515f25bf9de37363d61ab5e02fb867bb86fa1f95b3638e105310258548a7986ad04a33a9745a71c41e783a3b86bbad123a4b9971cf6755e7ea7df2a5481d9973c079ae7801747ff8b03043944ccb8b3cc1320168566070bab7e05bd98823220b17d8084dc77ab9ed4331df4495003162c009b24735c736dcac1836b8603c7893cac54b922e50e64310196b08696b42fb8871b0991ad80977aa3de41a25d6c918f2bc0f76b940a0ba85af62c54a5b260807c5e76a062277a6d2a87e42e68e7f66b3c60936c207a57195cd0f4342be7557cca765094cb7d8cb0b03b134cca0578ca61619d67f44b9a0c0843daed00fefa300c8678ebe8642046c454a34202a617bfce69127f07c6987ccf09b1ed7e7c7b6f311293b575517c8cc720f8e2643c616269f6bc4abda117fdc031b93588b888833f0c791eb2862abb733dc5691b670d041b171788c39d5b62aab751b5361ddc4ba7a0a6690d2205c7cb2cbf65ffceb0830383cbd134bb35175760350f5f9a4b4f67390e671bdec8e3a61af35c79c4d7c72feb112aebcbc22c074ae77b172e5b5dbd3374acb2f031bb18c174b02755d8a53a882459695305d772176273b5300d02d7ed2a272f9c7babb545a6c1aa25172f11096af5398c9d6c4590730ff05c74c81308ae5315ba24b17fc738a30718ad046d0627e4b81b214830be3ea225e8161039550c3c320e6c57220e076224aa8fd48b4db59a30f71b2a2fbbeb05b3885819b672c48393c5fe1865a4c113b736505c1199b807c5e7669b7d2499931d899b21b8c1d9caa129761bfa3974c4a85677a0ea1a49c4ee022cf3048012a3b108b4380f10ad2c327a009717a64704a62cb31446c5c810a5a9928e1e4564f95b027ac251c464569344f0086106f7a4dfac13eb194abbd64a8e7db2352cc07ef52195de869bda087cf838fb42862f6346754f1744de8a414464ecaaa921bf76a4ee344e3055ce0fac32c15bc9ff3019c7b9205737426cc29239721ecf65ddc241f33dac59dba06db577514891f70d020f5b240b03493aba381f6716a16646a8a8343efc41394a90cfc896dc04c4fba8aad7cd66005e426a3113dd1a4be4a661eac59cc2742a229c6bab9ba26cfa9194ab41674e89a410bc7e8a25bc410bf95738f8420c64de5715ae624368322ec4a513647ca86a231e76b62e52753c939308f8460a7650a28d258b24c4662793e2ad4454b5756e1692c6e6822a8dbc070ea81f4a85d6a2a852c452235f63816a08d957cbab030c33b5535c87c5e7851c55503898f21138b61558b38b04ce78527658082308117978bca146f8f338c4b4b623177a0b1a51b5f134ba58c19b4db69182807f3bcb29838a0729cc2d34200379cba1f751b6764c27d471fcf7a0b3f9a404fd3bf98150150b540d79b1df00038ce770424838f58e10aecc304f29a9103177752520ae3d967ba33ac2526c85d9a7aee03845b911f9c0a516f10a06a018af24319385a81c153653fa81808a6bd74680f684a52b8a72ba5288b6e75bca97a0304f2c3d8e940dba7239869bf68c951ed8884dd32cdb254755098cef7abaadec1a47a7a0fa646b1ae78af8c608ee7535bc43371bf1206c8680634174426e062ad9c28f4474a01b6785df35df57014c3e8858c2a2ed9d911cda8303c318bbdb13370b07bad82acbad0bf04c3ad2c491328a20790c39292629152dc0e6a29199251b5bdc956a2c4272a4b894a87359a11803a8b67e236837d25a274c97eebb6a8a9e7ce73cca9dc91a1129236730786de0a22286b71afea28e01abdf69cbf460ba2d7d69143895630f526c5f2c6fe9a289a3a058d84b64228389c94984644bca5fa1f61004a3edcb94557093345991bcb9bdea45915a5bb95618f4d62cce22717a67c60042856fe8ab437066aaa733567694dcbd301307b4eb02cce11124bcde6a79819b95ea621f1b11492315e60f774bc5b207f42c178708b28a18c9883561cd66daf17bc0bc42e0050b2a8157354f7945828a488a941363b3393a1112c691e123c6b5699a5c945038b6b2dd6725e7e619bebf1c34c7c32245461d32525c5f49a763944cb64581cea3a178146dc759c29c995ca0793df62cb2153859a32905e785e8e6ba2b834918f2c2dc5cab10f8b95867467adc87111d7beaf69099400aa4e908fe0a299e8901ef5f9346fb07ba287235087a1aef51bc8933823d22b8a02c1fffa56ea5b1dfb143ec1426f32959a4103b9e343108c87aad2fc0bfc7384c0101afcb4740f01b57b483c0300baba66543adca822b4381e99870727a75c491a1129af47d768e4f59fdf05c6f491aaa5dc11b9ac7e20e541aaea11b6ec8b27e94189dc1be939cebfda109cd53f38fcbbee7aad3c65a3c51aa3970ccb31695bbfba3e3b10cdd0d37d848309ebeb3ed8601ca2d1479f3aa0f2766d24b0b0feb01d34bc5627ea8dcbd935a2303bd6aa6d01e7605d23217b98b2ce8564ce077032abc35aa6afa046254d9a63be6c4bdebb95e0020ab5fb89aa5b01238047a3c183188bcec1158c0cf901636b3a459a223a73986afb886787cf93a8aabcd9af1e4cc585cac6f6f424131a9e01fb49bfb38ea664ad31dc16b2dc3c701753a2870cf9c27114262167763902b58b2f03bd906aad3b0101b7898e2663bd458b5c4bb7c5f49c28fffb97bb4393ba3aada4c023e25427dd5016b089591277b13dd0c26ae3ccb06c088fac04b475477ddc1be06620cf3754548a6b2a551aa1b97df5faa296c6a6ecd052cda5903533c93445778755876136c193fb0e3c937bf71ab2968a25e8d1c9e49a9962ba0c78951f64882c826016f63b97e6f8ba0242a45d69276fe0ce06f14be7535859c87a9875904870890c5a620d8632f30f55d3cae33d1c6f5896e6b12354a75c7894d8905403ef5c4f316e67ab8b72581b6eb228a8f357b716164e0388d504a7f1aafbb06d48b6d75eac6c76ced1b0a025b40a55440712ad8424672e761e9bc400d63812006f" +}, +{ + "dz" : "1f7cfd2b70863154e8a69d1758532e86c20cfc763d67c758bd10a13b24e759b5273b38bddc18488024ec90e62a4110129a42a16d2a93c45439888e76008604c6", + "pk" : "70ec588f847ca3ea21787531444355e26000209110be1b6994c3003332b95b6aa30f8a0d047cb6a2d9cfae2977e08962b656255637405057c233388e018753fec08442a6603878a6d4f8cbb2574b9dca1c32dc0964e82606739ddeb92402619649bc143950b753993e48da443b1bbc8c3a0e2edaa2710a541ea6ae48022ae1f48af844c2b32707733916c259ab588241ee58aca3538a0bd79fbf3589eda9ab08906d77778649f0a2b2a7898a651bae7013f8b863112c4ae2830a43ac421434236151b2aa7a5b3be77d4c85c89e3140f52804ca470aa2b929e8e8bf9b4278be1657ce321572d2196c4bb158ea891e627861dbc811525cb5f07a3377be081b4651eba3c311bb1c0357bf7a7923a524f003b02ebc030400b4b1e1711ef633b8921c101bcabce37655e8c651cc9458110e68566d0871659c3072c509538c5a6174063469a25c4134baa4f136e71464179b004fd361cb2b19d955376d137284039a6820211aa578189765f15a47e4b52d4af9447c4a8343f84edfe7ae76901d871b0a0d72414c4b01f35a38fe35a268848e663263439b4dfb9b3435537f54bb1e2b132528fa5942da8563554276d466e97a25cea6c7841729cac824dc3ccefa91c7d0a377f45b10b8f8cf78d00657f90e114363644869612bca78e402c8e2a6ee1910e07b72ad43b44edac06ec2cb3c448b506cb0a09746ccd84b3b993213b7a76dd681d6e7b7e9916276172d15538209b01ba5149bb0aaa55cbb04ac89674700544ec7079a8277a3dbc298034e08716849c0542dc42b7e32319b0b7efb43cb57f951b4912af0141965fa6e1701cc53d08c1887bb31fc93399823f1371712785ce6cb549b91099a2245dfd350c374943ee6826cd3c9bed72e7012028b938bd304ba0f5255ca664389335962f35bdf253e2b3933689070145462f245696e4b1d852bab0c817193679229ec684979c8f17965f4411fc1382309c28e98c095f663b587e967ef6320a84a474ed415e64381ff341daf491a9bd872a019a112a2ceea76661015b54181b8c325977b50993a5c26a7d992cf519d64f0a013f517664268d415a9c7f178c047a684495464332fd89071da200c2d70ba68c68425b815772b349cf4ace5dc1437bbb21e3283d2623cb58680fb1084e50685b99224f8c91d167590d4b03fd9a62d54695345217fb08658f1f6c25d0652cbc8cdd858ac9ad44616a8be03e06e14288c1ab27e4d3c15b156732d246ef8492efd508b41e6438c1c899b339874792f2bfaa1b8e55dc2740b02d23e8da9c0a1b91c61db66c92cb8bb3c64cc68bf4af341892441085a96f3aaa1a2217bf6c005a3938c2c61a15a701e090c84d93628e7cb6bb0e49c170079df1c0e364a4ad3622033b762593586549c79b764710b2107bd0c0acf106c7f7ba9accccc6ddb15d2b68a9fe7a2e8820ee9acbfdef8c139bc8b5ef47fd18626285409a59479d517714637b9d75aabae29cbf3418bd56154fae5195372299942271b0c90f0bb7f0c2537df6a433a2350127a24aa144d30b95faafb39f566651cc1bf205814027477c46b7ff1b66837c657af9cb0e7f46a42b4a74a69c36e716e2e993ad3c574aaec31a8fa5a950a8ce7823a7e032cb4930c95d8483aa102d1b20926a6a324b9062b29192431bcd61aa56488be8b9491ea373fdd276bf986ac01e6a9683785d3384acce6297da89657c005ac086687161bc21a18d6d325fef6059ff711a60782263a5dd87552f3b6691708a60459a81321caebba42faaa5593982ad4e0956aa42bb03867664470c8459a511026c2b8791a37278faa906b288dac6a1b7aa9588ae9062a31823076864800b08396aa90ab0a48a9798a146a8e77b104125ab1f1b5448cafbdc749ff085f06b02a2c25174f587f6c2583cb0384c521990b6c15cd926b40712bc503471d4b807f85b7baa361138312f1c62d62431297a451957375607bceb0009d09ba904a864be363bd220cab37d13a77daa42454b867307ed7c2a956d41a62b996e0e78c34b4ac0e7aaff8d8164b4a11f8aa4379fbbb34f14e9fe13a7f4ab0025586f130914c6183719a941b0338e1e11aa3f167a421bfa38c9142e02316d1ba4e64c60320c0a190cec011304f0bc58af38e492937bbd0ad3a5a904fb39ce365a13dc902166c864a972082fd9e2ea5548a3b6c7d885a3ca6ae2e12efc2ea3ee4ca0b0b171ee93a198b42", + "sk" : "342c2896a97cd8d63c24504629c1555870aa71fa19b668a558e2bcee667a6b61463dc46547419dc8c458b24b5f463ca8399337782b02df7704e53bc2f2d49f2ddbac73dc3c84728738a29e6f1a906229a05bfc4673c87a2d2b0894a67c549b6631a925c562258edb258524152b7816a9310d99883f4a583df4e582ff16acd9846b04a957bc54665f86c237bcb092a505fb089a8f76b865c130c001529ab53fa3b61f45376561a781c6ec75d0810ccdf44dcb0055bc70bf98f9940b000212215040cc08b31b90a395acf312a9fea3adfbfca17d309ee84b25bad086ef669986c4bbf1aa6f694bb74a760cd235650e5927184ba6e4e918a1fac482109767d2289dc16277468ba17031772868eb6749175c9a2755c18d67a0f6658fb6b5a27374ba2914680d730372e725181a6292db0d1c719501257b0f33a152dc077188673fbace2ae568bc1a890fda174edb4a1c10b825b85a78b26563b9429fc7caaa116bf5d808427c0bff488ea615017ce73008e9cea01747b73733e91ccdfb5c88611a94642b661d1a41a943bf065733fe2449ee68b4537cbc86871e1268cca564b5e952188e90aae25988f79bb706706aade42add2c1b2951b84d040e097b85d78c3c5b10c595879784b71638b2c70c390ad308a311a337413a20857a216d31134e2429cee72be2268cc38ac8617b7d45d2651efc06c3b1c1d0c44531f5523a707d0802251576ac2d6a91b463a68348a2673a2f74cc7c20a79b73bb1916637830c91e701bb200166d2a63a21b5b8e52c7acda296d80d6c897c86334d8424f44677e9246ffa32c5c1754b632692af6bffd05458d131c41275161cc50a51ab2570746048b455420053193b6f1c0ae02f83ecf364e50a6694285523c5372a84b6345f484d0b2c8156c05e9f3c6b661bf1cdc5573082313c5c05c648be94b7b83b68ad93019b8469dc93a51e9f47a532a15d9140bb56878984877311a8c303b7c2cb9b62cb34c1f70cdde82c9d9e76c5037c46e6196903b1a372860110a721fbbc844963f287909e2e093c4b89358160bd6ca892b95a910565fb67b640a803a4eb7c08109cbd235b773f91cf54842352b4a7677bc310563e5fa320fdab95517c61952b5687379c6e229f4d296bec53cfaf346d0050ea6465040fa11d5f04e997932b9201a117b3d552bb853161de6f6ae5669ae9cfbb36c00ba54052e5a70071398b0f1858ee5e3a6740a7b93a453af91550e7cae362532d59490d70ccfc9997da3519638302be5c01cbdfcac7b32a984049426acc67f12283598588d68a46c1720445b6602e4b60df0864ad3760892403b575e61120863f03d0d67551103d02a8386b1abcbd2b6307b42a62103a6e970cc0a021e5fd54b659b6c0fb8641c6c74c12873f5348c3fda18ee264af681316af0c55cc2bc91d767344c7046c0455b36b673591942a622fd122fd6505ffb4a3fe61b0b0bf1bf0c539efdaba1aca1baa254a788f821502b06db752f702c15227c4a60fc09bb28c3d2165c95171c20ea6e8526cace1c239da3705844c860c35d6dea477aa1339813a9f2d755a21b143724621421abf6d5aae62c591be72a8e817603d942a35c9e7a391bab514e88c1b54d9830ef7c490644287594c834d898a50c2f6e18575454733d40ce0bf20033babb661c84d9040a12e4881e9947ba4023b0eaa86f9984f4158d825bcdbd888e7ae6084e3b2f49498fcea10f1db637c82287e6f8cd553caf40b7bb00236450243eb7349958286f380bc456b7208922a5d8887a075acc0c29b231c51cf9839e1fac91e3d0631b865bcef168e71a4a53921c5cd9aa758175c8b94a2be1af094c5a5c518ba3c7ad0a0cc105126217f04a49c674b7fc3e6a9bae73778c02320512d1ad3b7b2508590dd544b03d2c21d0549eb5a146d87c3897a5525df8735079970afc8b58f419bab8b3b513844cd08164a2882518ceb79abf6ae8cce5618afaa228db659a6ae16b82e351ed4646f2a3cbe1ac1dc0b6a0838532a0b2aead760ac43a7eaa290d991a172e4a1fe1e860bdc50b51e58d18272a942a9045358faf279a916663cdb431bf81cb30777cf105a032108769475f84c74b20668a991b53541a45061236c232cc85a56292ea7d470b00b4b128e45586e1531c02f364ceeb86e4b22fe6d4a049399c70ec588f847ca3ea21787531444355e26000209110be1b6994c3003332b95b6aa30f8a0d047cb6a2d9cfae2977e08962b656255637405057c233388e018753fec08442a6603878a6d4f8cbb2574b9dca1c32dc0964e82606739ddeb92402619649bc143950b753993e48da443b1bbc8c3a0e2edaa2710a541ea6ae48022ae1f48af844c2b32707733916c259ab588241ee58aca3538a0bd79fbf3589eda9ab08906d77778649f0a2b2a7898a651bae7013f8b863112c4ae2830a43ac421434236151b2aa7a5b3be77d4c85c89e3140f52804ca470aa2b929e8e8bf9b4278be1657ce321572d2196c4bb158ea891e627861dbc811525cb5f07a3377be081b4651eba3c311bb1c0357bf7a7923a524f003b02ebc030400b4b1e1711ef633b8921c101bcabce37655e8c651cc9458110e68566d0871659c3072c509538c5a6174063469a25c4134baa4f136e71464179b004fd361cb2b19d955376d137284039a6820211aa578189765f15a47e4b52d4af9447c4a8343f84edfe7ae76901d871b0a0d72414c4b01f35a38fe35a268848e663263439b4dfb9b3435537f54bb1e2b132528fa5942da8563554276d466e97a25cea6c7841729cac824dc3ccefa91c7d0a377f45b10b8f8cf78d00657f90e114363644869612bca78e402c8e2a6ee1910e07b72ad43b44edac06ec2cb3c448b506cb0a09746ccd84b3b993213b7a76dd681d6e7b7e9916276172d15538209b01ba5149bb0aaa55cbb04ac89674700544ec7079a8277a3dbc298034e08716849c0542dc42b7e32319b0b7efb43cb57f951b4912af0141965fa6e1701cc53d08c1887bb31fc93399823f1371712785ce6cb549b91099a2245dfd350c374943ee6826cd3c9bed72e7012028b938bd304ba0f5255ca664389335962f35bdf253e2b3933689070145462f245696e4b1d852bab0c817193679229ec684979c8f17965f4411fc1382309c28e98c095f663b587e967ef6320a84a474ed415e64381ff341daf491a9bd872a019a112a2ceea76661015b54181b8c325977b50993a5c26a7d992cf519d64f0a013f517664268d415a9c7f178c047a684495464332fd89071da200c2d70ba68c68425b815772b349cf4ace5dc1437bbb21e3283d2623cb58680fb1084e50685b99224f8c91d167590d4b03fd9a62d54695345217fb08658f1f6c25d0652cbc8cdd858ac9ad44616a8be03e06e14288c1ab27e4d3c15b156732d246ef8492efd508b41e6438c1c899b339874792f2bfaa1b8e55dc2740b02d23e8da9c0a1b91c61db66c92cb8bb3c64cc68bf4af341892441085a96f3aaa1a2217bf6c005a3938c2c61a15a701e090c84d93628e7cb6bb0e49c170079df1c0e364a4ad3622033b762593586549c79b764710b2107bd0c0acf106c7f7ba9accccc6ddb15d2b68a9fe7a2e8820ee9acbfdef8c139bc8b5ef47fd18626285409a59479d517714637b9d75aabae29cbf3418bd56154fae5195372299942271b0c90f0bb7f0c2537df6a433a2350127a24aa144d30b95faafb39f566651cc1bf205814027477c46b7ff1b66837c657af9cb0e7f46a42b4a74a69c36e716e2e993ad3c574aaec31a8fa5a950a8ce7823a7e032cb4930c95d8483aa102d1b20926a6a324b9062b29192431bcd61aa56488be8b9491ea373fdd276bf986ac01e6a9683785d3384acce6297da89657c005ac086687161bc21a18d6d325fef6059ff711a60782263a5dd87552f3b6691708a60459a81321caebba42faaa5593982ad4e0956aa42bb03867664470c8459a511026c2b8791a37278faa906b288dac6a1b7aa9588ae9062a31823076864800b08396aa90ab0a48a9798a146a8e77b104125ab1f1b5448cafbdc749ff085f06b02a2c25174f587f6c2583cb0384c521990b6c15cd926b40712bc503471d4b807f85b7baa361138312f1c62d62431297a451957375607bceb0009d09ba904a864be363bd220cab37d13a77daa42454b867307ed7c2a956d41a62b996e0e78c34b4ac0e7aaff8d8164b4a11f8aa4379fbbb34f14e9fe13a7f4ab0025586f130914c6183719a941b0338e1e11aa3f167a421bfa38c9142e02316d1ba4e64c60320c0a190cec011304f0bc58af38e492937bbd0ad3a5a904fb39ce365a13dc902166c864a972082fd9e2ea5548a3b6c7d885a3ca6ae2e12efc2ea3ee4ca0b0b171ee93a198b42191fc1297d126ae957ec70b3e5cc940f2649f5a8cee53a1feb5e68e08aeadddc273b38bddc18488024ec90e62a4110129a42a16d2a93c45439888e76008604c6" +}, +{ + "dz" : "3a19577908efd37697b8edc7fdaf47d1bd3ad01a1b77faf794bee5b9c3192a6fa3729672816f3eba84c9638a79676eeac0f22c8a48e0c5d50a26ff0844c66b99", + "pk" : "d0947b8b21912d062783fb94b458013f34480ba83178c87d9ca4575ac9014ab22a7cb92b1bf41ecf098f735b3401e31bc02a43c447220da64ce22b17408ac536135641100d1ea581a14818eaa4c77b229b31511e0a403229889fcba0a2d4d3c845868816b79f56d6265d678c9138b716213fcfd7acb2c68f4fac7914d140cd2a7487b34146708115689407a9bfd24216f563a6fd220893c1c5e2c657031b43a29b19471b084485b7f739af017459ae50423518460266cf449b524406b9a2b80a77093afb1344bc1521e0220c5a113cc0c4a4321a77204521e3c758927c83398aa1f4bc43ac61487e7158ab4053fce98a74b14632054d3d3aaf018cbaad771326b7160247cc10a114434087faf515c7a39b0705bc374b7af73c5b60741e037bc69b10949db1739ad74a240c2191b3201a020f43890cb16390d6c27c39d40af0043b57e8a0f978627fe1b36c6c83fc97b49ae9268618b2c96a7a3612002b2673bc1ac762a37e07fc6ef3749009876399862d67b5b48571caf8b326a4a80b4544c03ba811b3501518d5caa107be696cbdaae79caa0191f5678fbe14934609aeb501bdb0a525ada654d77cb3042159686381e3677edbab5f7dd87fe1c4566dd7382f03c2acbccb14182b9a65afc0aac41f4c3095675a316159b0b7271f0284e160190de000fe4076b6e3073d302a51c7a6f6486c52c97446b506dd7c76ebf08a5f8c70e6e8479735c2ae79a6d4a99444a347ba838c43a1ace485a005a7531916c45181157c955817c488ccab9aa4d55dd79a5e243504a74405a8a4ac01cb1b9f2917fdab3b2909ca609739859383d631b65965affb4490d5b9be84a2902cb34cc50b5c49cbce43f8351a68b3476387bf87a16b9784a0e801e1eb39ee33b8b9ca82bef596605b59f33035a05a012d8549f0b68c93b784c7a309dd71425d3175ba50107d28aa8dd42369bcc68a8aa074020b4b21c3d537ca25b82a50dc875ab76b35a982b0792fd84b60e7db48fa0b80cdb90e1a95038842404a78c17d6c73e42951ecf2160db816cb7323cfc0b8b0057e6e66a36a856eaa60735433bc1680636d137b8da85f19334bd0ec9617d8b484986af31bbaf7e81a050c5b4dd9356563bd2f874b6b82a6e8b088b2ca59ef3866fdd4217efbc5dd66c72b66137ae65e7dc5c541c42a5c4cc1c1f1b678b7941d37ab5bd7292c665ea89b9679c5a6f8248f9fc61c2af282ec048bea74cccefc2077f370d3979b83e2a65d64be85742bb9b66308fcafc84038e72950e968b33fd98da2750484f1138aacc0e5e8607e352804316b26111c5a242c09901339fcb7d304c749d9205f169d2663a03bbc82658a0ca3025ec4d0a1e445be8fe3a72c672333188abc3010b6a98ec0f01d698b87f195b2e398ca6f8038ef0739af347b22076a58391c46573b0f782444464d9ea0645b4cc6f7136927c34e51fba618b082f826b29fabb8bce80bb0f05524348104eb4732e0ab4f4040e104b78ab9317b558330d4995168752ee23455eba2cc4cb679687be93860ccd1848bac42616893e6e710645b354a657e4f064e2d3266f89bacb8585e6d927259723e7d321aadbcbf9638b1bcf917e3c203fd06145fec0be1059c4a52ad751986d0f0bbb46bcccd365ad6b614dfb87dd7f97ccd731f4f9b280cd321d7d7679743833823aa5a05b1b3d0263858cb2ec27677da6928b26d3459573e25b0ca4964d6798cf250860d055418761d7ff0189223a1d3eb6ddab21572b58f0f5ab03a1bc047d7928c060844160e169b2ce072a89fca5b384b81b89b24741674ff5223d4116ada77797234ad3cbb1f6a78cc33e27b03ebb0d5a18427f625a4311a9599ae8723bacf392b7c915aa731c943f49c24f189055143502cb35318432c8b89bd2b9243f35c4b443ad48126207559a2314a77bc67c4d79a3e010fa1686761509e6774bc2df86eec6c5e3cd547f9a5457fb4a984590e57ccbbef3b38e441235d90bb60a24a691425cd65bb43b5868d128e3428b446409804a25333a7ad1f5c6d712169f660798de5a448aa393b5c496db978934c6eb001112440784db13825167a33206f76b05eaaab0b89966150238748c492379b387ec863fda621ada4296fe16593358ca0ab83c15225dd26691da0b00554c2398a2c44f171bfe63d48db72ee6cf36f47dd054b8f7bec5a4bbb6b0d62bcd24a3b8a6d32c53a51bfb7c57ecf", + "sk" : "e6d51f1ff8939a52842f092d10a9cd02fa1b7840147f3a5417da6994e7663b536d253b627094b87d951583c61b8ed8a15295276df7b080c71a6b2a4fb93b29512977f02c7f8dc36eeb2644f4db64a60ba2083b984a010e0029616295835118ce0382144701cfe9d5a02bea7fc8ba9ea074c15cba8f2a77062270b9818ab99d856e3c4c104a66441eca4d7fc74b148a37a5eb7103f021c955826048a1ab6a4c3619c1a2884fbf4495b1469e33671c845a40314ca87c4bc87e8c8bab04a1b9b237413242a83cc41517c11d50b7124a730d7b54a68282e2cbbaeba0896b2453568c22b3e779899a5e8850424fa2b68af95381cc5ade59b54d6a1bf2f1b16ee59375a314f811a716239085a77bc4e29506589a420a6c09c2206cc1aa97f2aad03657eb967c1ab8bb73a87a4853035d77285c29c788885bf1108fafb517e5bc1f13f89cd5ca97d70c12b5f64b88376466230439026d73a3aa9d11b03db22e541c28e32c22a2976b23508717379ded0989e2345cb5f0c7d9c97a81ba09514b0d27598554189f7e8b6e977a5d3588c979aac19ee60c4f64ce5ce73b437c0c1d11577d539af94158b946918085c689dcb227d72240a843b2bc4979f5cfdc2791eec3bd168593ba7b1eb06b829844b9861387af68b466498c84e8aa31fa39488cc676f728ed106aa9e368459028fff42aff418320498fc283b8ce860fd1c02ad1c0a7d0d92d61b6aad6d1b939ab0396983693353f23507335ac5fce277df06559dd3a6961cc43247cb0f9e7269c438ab4e14ebc0ac2907bb1289741b211cf40a15ded58b8d18c4948294b774c6edb047114991981fb612c5a196354bb80a2bf6efb713aeb72d5f434f9c46d14dc461507ae5bacc7c04789c1dcace8904cad02401ada53489a04fa2140d1864c76fb91777bb9900b010d7a6f2d09868504823d83c5e881aa7b5b408f144e01f2a83de212a7d3188c845539bc6b061c2f72b5c771f8b7377c678ce473ddb25b33518cfcb71a18455acdb02ce73433961a98d840c6bf844014c7c89cca5ea58a6291391ff6c0135e11911b6895557193dfb84a97e4b8f1ebae016947a70b8b08e5c578591f0874c6a2b7b900a490d240ad36bc745c113778ec3777c3220cb19fb49634cb200fb1f67e5decafd84100544c86ee79c000169cd908a884344ed2f40862558819458d5f87c4f3714fe0925538f002a7d454c2f438a3c751a1fbb13f77c85c612e16c0cb979249518b82b85586df793db403ca55709e1e6030356048b458a492ec56e0b08c661c5ba04b805cc631b12a741216448e22a22db406c04935f7c6cba44c213968a5fb6ca9066c88f70900411a43e8651641197fcef47470299c51473f158175e2e7857716ba80f501e156525ce0bd05cb3327673385095d144562dc4b006c89b0c6aaa2e21ccc79c0a7f3b0aae77142a447454b65694c6a5eaf3a7761b860189846a8612b89fa5ed5715c8eb3042890c52326af5edb7de3b578dccc61283474bb8966b187acebb9bce0a08031e66cec0bc57fa368af2574e7397a1177828d4326a66a8093415872537099d77eb83b9cbb516f40d235c0831b3ff663d3f3a9db6c0cb5106c905cb55db0721e45a7ebb676def137a585ccf493002055536c3ab49a17a68783290fc9366923654e310b17c2551816a9196497ee62ade56b24a2b421ce48a583d46f3192bc09493ed47502b75580be01cc94cb4893f32fd6266fdaf865f4f16571d18c8e1a301341113d5c6b59061cd3124683748f5c20426288c7bdf8ccd2d21acbec096101283534cd4974978b117beb70bcb5fc557d5b7482c626a390a10f500e65f8af72b3779068b24228c37907477017327026324fe3c607a86ef7fc453af88c2dba51114cc67f32bb46e58cb7995d4ac31f9b0c2048b05012189e73562fd2baac0cc4795e55b5058b9a747a5c34c63438f2767d32354f12a0ba546c76f38cb54ca632f321eb39ab0528942647415f91cd0738190ed20b1401aa0b1c4765674df3e47755a12426a2a307760dd9d39c2f7728dec213b2559cd2128181e74426595082dc0065a2aa132c72b798aedde6a7c2bc03cb0539ec61bbcca78e510600faab6828ac6a60f58b6bc894d16712b34892fddcbb695c36eb9c3169543c61969c22f95b6ea52bdb9b2ed0947b8b21912d062783fb94b458013f34480ba83178c87d9ca4575ac9014ab22a7cb92b1bf41ecf098f735b3401e31bc02a43c447220da64ce22b17408ac536135641100d1ea581a14818eaa4c77b229b31511e0a403229889fcba0a2d4d3c845868816b79f56d6265d678c9138b716213fcfd7acb2c68f4fac7914d140cd2a7487b34146708115689407a9bfd24216f563a6fd220893c1c5e2c657031b43a29b19471b084485b7f739af017459ae50423518460266cf449b524406b9a2b80a77093afb1344bc1521e0220c5a113cc0c4a4321a77204521e3c758927c83398aa1f4bc43ac61487e7158ab4053fce98a74b14632054d3d3aaf018cbaad771326b7160247cc10a114434087faf515c7a39b0705bc374b7af73c5b60741e037bc69b10949db1739ad74a240c2191b3201a020f43890cb16390d6c27c39d40af0043b57e8a0f978627fe1b36c6c83fc97b49ae9268618b2c96a7a3612002b2673bc1ac762a37e07fc6ef3749009876399862d67b5b48571caf8b326a4a80b4544c03ba811b3501518d5caa107be696cbdaae79caa0191f5678fbe14934609aeb501bdb0a525ada654d77cb3042159686381e3677edbab5f7dd87fe1c4566dd7382f03c2acbccb14182b9a65afc0aac41f4c3095675a316159b0b7271f0284e160190de000fe4076b6e3073d302a51c7a6f6486c52c97446b506dd7c76ebf08a5f8c70e6e8479735c2ae79a6d4a99444a347ba838c43a1ace485a005a7531916c45181157c955817c488ccab9aa4d55dd79a5e243504a74405a8a4ac01cb1b9f2917fdab3b2909ca609739859383d631b65965affb4490d5b9be84a2902cb34cc50b5c49cbce43f8351a68b3476387bf87a16b9784a0e801e1eb39ee33b8b9ca82bef596605b59f33035a05a012d8549f0b68c93b784c7a309dd71425d3175ba50107d28aa8dd42369bcc68a8aa074020b4b21c3d537ca25b82a50dc875ab76b35a982b0792fd84b60e7db48fa0b80cdb90e1a95038842404a78c17d6c73e42951ecf2160db816cb7323cfc0b8b0057e6e66a36a856eaa60735433bc1680636d137b8da85f19334bd0ec9617d8b484986af31bbaf7e81a050c5b4dd9356563bd2f874b6b82a6e8b088b2ca59ef3866fdd4217efbc5dd66c72b66137ae65e7dc5c541c42a5c4cc1c1f1b678b7941d37ab5bd7292c665ea89b9679c5a6f8248f9fc61c2af282ec048bea74cccefc2077f370d3979b83e2a65d64be85742bb9b66308fcafc84038e72950e968b33fd98da2750484f1138aacc0e5e8607e352804316b26111c5a242c09901339fcb7d304c749d9205f169d2663a03bbc82658a0ca3025ec4d0a1e445be8fe3a72c672333188abc3010b6a98ec0f01d698b87f195b2e398ca6f8038ef0739af347b22076a58391c46573b0f782444464d9ea0645b4cc6f7136927c34e51fba618b082f826b29fabb8bce80bb0f05524348104eb4732e0ab4f4040e104b78ab9317b558330d4995168752ee23455eba2cc4cb679687be93860ccd1848bac42616893e6e710645b354a657e4f064e2d3266f89bacb8585e6d927259723e7d321aadbcbf9638b1bcf917e3c203fd06145fec0be1059c4a52ad751986d0f0bbb46bcccd365ad6b614dfb87dd7f97ccd731f4f9b280cd321d7d7679743833823aa5a05b1b3d0263858cb2ec27677da6928b26d3459573e25b0ca4964d6798cf250860d055418761d7ff0189223a1d3eb6ddab21572b58f0f5ab03a1bc047d7928c060844160e169b2ce072a89fca5b384b81b89b24741674ff5223d4116ada77797234ad3cbb1f6a78cc33e27b03ebb0d5a18427f625a4311a9599ae8723bacf392b7c915aa731c943f49c24f189055143502cb35318432c8b89bd2b9243f35c4b443ad48126207559a2314a77bc67c4d79a3e010fa1686761509e6774bc2df86eec6c5e3cd547f9a5457fb4a984590e57ccbbef3b38e441235d90bb60a24a691425cd65bb43b5868d128e3428b446409804a25333a7ad1f5c6d712169f660798de5a448aa393b5c496db978934c6eb001112440784db13825167a33206f76b05eaaab0b89966150238748c492379b387ec863fda621ada4296fe16593358ca0ab83c15225dd26691da0b00554c2398a2c44f171bfe63d48db72ee6cf36f47dd054b8f7bec5a4bbb6b0d62bcd24a3b8a6d32c53a51bfb7c57ecf5fb124740e9315cedb69ebbc969314e2b7469c2d2e2bdf2698af4bd116f0d12da3729672816f3eba84c9638a79676eeac0f22c8a48e0c5d50a26ff0844c66b99" +}, +{ + "dz" : "ae0f65e29f38804a6759f70f4d01e2aaff7fe1c91ebc4f892dd0de3ab2e68ea5e03ff73e02a217659f53d8c47556bf3d8c94040f630d63605e2d0f923579370c", + "pk" : "e3658e3c8607f9775ea3b57a481ca307a36b36780efd410873f9067ef06a6f75b2f695620c9753f97b167df14f4b59a66ee953aea71abe866ff3e34cae61b53f5842a9ac3c811abc36798059db5a51bb1a003b5687dc73e279236e69477cd03c5143b6e22bbde999379ad131215c9c46e37376402d434a58f4ca4c5249c537b15937c38282d2759a45243ce36d24eb234c5bb875b2594ac89e51564e43d2869edc93cb2143d3f72c6d8672df16a08cf94031612199c224e25bb223fb646ac5997b806adc1bcbd49a7833409515c05238aa2c3445a290eb4e4cda6fe1e61fefd58084db9ed675b608ea1bf660195c226a6b70cef5a114ec584903aa427a34c4f75b7d0dbb4564c72c2b252ea9b99173659ab3639d3476332c74aebe0b6656e3cc3f99206406718e5718e76bbc2dfb8b409780263851db783979fc5ea3e4a18d6383762c6d5f782e7333876c10414dfb4548296d33947590534a01c399a3731ddd4c882012bd0b1448e066c528f28c52d3c34f1ca1e2da234f571ae9921084179a9673091555b9d671aeb33a3c41c22adfaa8ca800b92e9401fe31b35c311d7820284fc534c928bfd575881e5678fe81803ed08041475b0f4a36c7644441a067cb35a633a2afe385ce1a1b5c4f9c4a1580003d1aacc548a4d5e7c94c6a4799cb843fd4c6e6209e1eb1a71be32b501b004ad9c0d7a6b44c2970140a021416483dd835e7987b779041aac46806a1a538152e3b716beab69a86e5291b431b1eb68105380df09758871335be0735b4a22de2c4593da03679622c2af78f4d888fb178098486602b743d72f25a57b3533623b57cb905ab499835093b1c4b9d40d361fec791cf82a17417981ec713514ba50b46608c1307b7939ad5f9b1ae47ac2f0c76162161cf0677aeca801504512433918aab949c078d46399d873b0a6e9987e9aa71e52c5691232b8bc68c55508c9bec555d17a6293525d297be94559671c0209561c6bf7859c3469772c25e0863c16c9c4aa453862e52ab3ca942d887c959850cf4fb2afa3420fe55660c22516bf8c940ebcb1ddab9a36a341cc144a646321037c07231424e040ad92c706d254e56f48012601e0de8402221711102be85f54d3bc513481c1e2ae6c50a022d056967c6b032c99ba89070847bd5aceb4669619c71f2b7581736726dc800a3148bd2871d8bf60708da4cd13b8822209bc09cc2a88a43defabe6a24986d697fef253aa91525b3a3cc9f102c9ea158c699745b03af77d41d4df72be7fcb6b7130f308bbeef6ac699388976a574ee1a74e84b48649bb32ec763227584ee24c0248b7f5096c72ca172d2b81982f676dfe44a896618c77393475521eb6a6fb8ec6e153c72d7f8c9067a765cc4149fc58777974f96411739168deb8a6b0e905997563d7f13590ab30173bb23f7b7440fcb6db8f910b12958e0b62fb6f84fa5aa931b118ab4f1ad6374a34721c053224b04cb07982988fa3a569ae9342953165b012f31728960f89d589613d07a2b16c71e0ec942a812a72cf90ec9b23118a59c6bf7c273c6163a8470b18c8c2ee76f4d2975e7d79df7e80e759a52e6b689ebb7bbc7abbf6609560081aac3aba2b43aba545951427cc35dac5cbafc7d394bbd57a2854e84b5f0f3059a94b35f3b0f1ad3344cc2a40fb89a87e091c9c0125c0052e8b28cfff0c3e0390967e1364a4ba8c0b77a7fe83a65b76255422ba7a128fd4b3c8ef85fcfc16f80ba5701c9a48ca230e455b02b28641b98a67a851f31621733c0a779170ebd690111f395e7461127481fd8e1057d35b6c20b1f68322e72e92a2363825566445544995dfc08ccc492f6e19072e398bafc32eff92c7e229f87d1327bb1884cd04849569c415860df59646ec59ed052bade3a0ea6bbb8e9d924e6c43aea22cd4969528d50af83b977d4f8681fa52ae6f5a60ec1cedbac91b14b70d46c5ea18551f288690c3aad6428939426326c54a80b1c6281d51b3d47462f18c6c5931c60395a1e74826f6c258f5622f689c4b5470976a961934104b41100142854bbf75d40d09bfd9a0e64575a7546bec19108770c19a7cb48208780e1c657863163022c910f071c59f239a23cc9f1697cf5177f88e7580df8c925b2c405a3360d0a80a6ea1486136faa9c48aa3801ee87b7cc5c638d67be57548c03711f9b2b31ab319d45c578e5acfa30dc426ac3b194230a4bb5ee07f4", + "sk" : "401208d8b00dd0515a1f7c23013c9a8d48062f281437a312e94c7a76055580b894cf66a7795c182d889a1a940ea044112a265dee346d902758ef7b3500a02f8c009e3c803a9fe2a39e95539702250fe05da8a85fdc2ccf54bc17b540947e280276a084de678fecb73a5d1bc985718c09ab5bd87675736bcc8eb858cbc246fdc07f0a7b3dbd1656f04c7bfa3854b502a71db111fe2c36a25910d37a5c357ba0667417550071fd0b0c4ffc094b37b67d262734eaa64794c5e0d66d0ed96a5d7c7f3865ca8579b89c2b7349b3134e43a677680414eb2d88587c73192a11e5088d673e65eb1e88fbcefd8aa72b704521749a384588a6009b3e41cd839313ed00b5b4a14236835055a875ada5674a1959e2746e3a38a1cbc7bc0cf6a2c9ab95c135287bab8b7d12bd8dbc79d2e6b36f0542ec73bd66f6949ef00975f74ec8f31c0cca8544c25a431c8e43a9c0c99545a18ca7c5f28d4e0173c4505c5c4ba94e1b87a3b4b0eec5759bdbb221530ffdc9048517102e70745eb09079f376914b643ecb3fddf0b68d384e2fb727bac38148d897554cc8eee5a986ec0c2081a2d583b73db69bff054133e18e0e7b52e9e9c5c0e088a99895baa375f5b27255f1b64b38b96b91b08afb5b36371802559f240ac4bc4234d8da75b6839ecc822721a466e0f7a292723286f38646e396e7aa3dc9239c3d621fe70a2eb14c37139b878285435c682b9b5489903bba677a963509c5ba412f8165bba029084344445e21bfb1432f97b27b3377252df129208c71c41a10955c79c6b6507b1067dddb8e1331897854897b6ba01f79ba6f6273cbe540620c27d731a86719903fdb5534bbbd9a9275870103d9bba74b694595188460b80490e0269dc678fbf0cab0918c59958ec297bff5e6572b3133660936689a393ac36f638883d5a95e1d78c6460c692040a9a28895fec808ceac9590aa8552382b31a489ef167429e63c7387b794552cda972d4dd3aa41835bf29315bb095b95d4539b66008887ae15e66fe561534fbc973f4621c4f41ab9498d0ea667637c5e563accb2b0429d580cee038326a8413271203b93607acc70666c50e34c6186d03600043ccb4c7e18a1182ad39eb49c0bcd746832b1ad47bb9248402091872ba2b68d25c0b04064558f9453de628c4c983c1eb202fa724a9f373c003da76c37743a452d8f765d82c292468c28c16c9b26a2727df96b26673b191b3162970a557caa63827b5a2b631abaa861763663d08b72b712ac53990a35b57f99b5b7d4ca3035a590db287e1513193177f687157ee74ae10b73e6f24e8838c3df29c6d8b78ac6b70aa1ea1b6467b6d4319dbe98771ca752c9986006a687d0812e9e46374563a15ab32c7b70b58a21c976816192d36f04634fa0b46fcf202b44e684008c624f0209ddd64497184524032982dc654fe22751846a2402c17503799e9a7d686326873a4593479b615c13f91cbc3abc952bc4792ce04f7a272921d13e34b10a203c2c06d65dda903287887c29cccffbd4059c5b1fc2c3b7786c0ea2e49ad792136635982103473657ca2e4b32881b6ebe8c4e7c63594d34b341f515689b7c671b4f40fbc7d8e1ca6cd4016a9200cbb58741fb21ec84030f6cbaa282b9fc4365196094dd39bc6447739999041ee1055b373689589da7a6a23a007145ab208bf56ea51c3d68e2c3b4cc4f0da518f9089d4efb28c7f746f0b948a2955e26db2b5ecb7c6db2694db5ada7a7aa939109b1d0604c5a2b654a4674b636cb9a5f65712f404b4edee505093b1fd76b627b32c4c42910b1390ff03c30a5e79be6241dfa39a2d9456c331c4404e7a159b8a89e10588e3446c7151d7bf31a6b930f09312b5d798dd71c45b2273f513c8279034483ca7010a9b3d597cfc7f699e649a99238b1283a935b199f57f6333c2a08c553a9bb8c38109319486a4a44d71a5317ad4ecaa9b4548b86a9560969690e8b02a38bbb628391eafa6d2eeb4a783c661f14b9754a8c2faab853dbc10793a61ce2b1eb72c7e5b15789fb1885e7bccc89c03350a047b811c54738fa91219744ce5166a4882412c6898fe9037b817099779968eabc1261831a6c0a5f308431d8904cb9d4a1bc8b79f0ea01395088a5377935c26906093a34e0bd61199a9b8a06511b2127340c9c0169961a08e3658e3c8607f9775ea3b57a481ca307a36b36780efd410873f9067ef06a6f75b2f695620c9753f97b167df14f4b59a66ee953aea71abe866ff3e34cae61b53f5842a9ac3c811abc36798059db5a51bb1a003b5687dc73e279236e69477cd03c5143b6e22bbde999379ad131215c9c46e37376402d434a58f4ca4c5249c537b15937c38282d2759a45243ce36d24eb234c5bb875b2594ac89e51564e43d2869edc93cb2143d3f72c6d8672df16a08cf94031612199c224e25bb223fb646ac5997b806adc1bcbd49a7833409515c05238aa2c3445a290eb4e4cda6fe1e61fefd58084db9ed675b608ea1bf660195c226a6b70cef5a114ec584903aa427a34c4f75b7d0dbb4564c72c2b252ea9b99173659ab3639d3476332c74aebe0b6656e3cc3f99206406718e5718e76bbc2dfb8b409780263851db783979fc5ea3e4a18d6383762c6d5f782e7333876c10414dfb4548296d33947590534a01c399a3731ddd4c882012bd0b1448e066c528f28c52d3c34f1ca1e2da234f571ae9921084179a9673091555b9d671aeb33a3c41c22adfaa8ca800b92e9401fe31b35c311d7820284fc534c928bfd575881e5678fe81803ed08041475b0f4a36c7644441a067cb35a633a2afe385ce1a1b5c4f9c4a1580003d1aacc548a4d5e7c94c6a4799cb843fd4c6e6209e1eb1a71be32b501b004ad9c0d7a6b44c2970140a021416483dd835e7987b779041aac46806a1a538152e3b716beab69a86e5291b431b1eb68105380df09758871335be0735b4a22de2c4593da03679622c2af78f4d888fb178098486602b743d72f25a57b3533623b57cb905ab499835093b1c4b9d40d361fec791cf82a17417981ec713514ba50b46608c1307b7939ad5f9b1ae47ac2f0c76162161cf0677aeca801504512433918aab949c078d46399d873b0a6e9987e9aa71e52c5691232b8bc68c55508c9bec555d17a6293525d297be94559671c0209561c6bf7859c3469772c25e0863c16c9c4aa453862e52ab3ca942d887c959850cf4fb2afa3420fe55660c22516bf8c940ebcb1ddab9a36a341cc144a646321037c07231424e040ad92c706d254e56f48012601e0de8402221711102be85f54d3bc513481c1e2ae6c50a022d056967c6b032c99ba89070847bd5aceb4669619c71f2b7581736726dc800a3148bd2871d8bf60708da4cd13b8822209bc09cc2a88a43defabe6a24986d697fef253aa91525b3a3cc9f102c9ea158c699745b03af77d41d4df72be7fcb6b7130f308bbeef6ac699388976a574ee1a74e84b48649bb32ec763227584ee24c0248b7f5096c72ca172d2b81982f676dfe44a896618c77393475521eb6a6fb8ec6e153c72d7f8c9067a765cc4149fc58777974f96411739168deb8a6b0e905997563d7f13590ab30173bb23f7b7440fcb6db8f910b12958e0b62fb6f84fa5aa931b118ab4f1ad6374a34721c053224b04cb07982988fa3a569ae9342953165b012f31728960f89d589613d07a2b16c71e0ec942a812a72cf90ec9b23118a59c6bf7c273c6163a8470b18c8c2ee76f4d2975e7d79df7e80e759a52e6b689ebb7bbc7abbf6609560081aac3aba2b43aba545951427cc35dac5cbafc7d394bbd57a2854e84b5f0f3059a94b35f3b0f1ad3344cc2a40fb89a87e091c9c0125c0052e8b28cfff0c3e0390967e1364a4ba8c0b77a7fe83a65b76255422ba7a128fd4b3c8ef85fcfc16f80ba5701c9a48ca230e455b02b28641b98a67a851f31621733c0a779170ebd690111f395e7461127481fd8e1057d35b6c20b1f68322e72e92a2363825566445544995dfc08ccc492f6e19072e398bafc32eff92c7e229f87d1327bb1884cd04849569c415860df59646ec59ed052bade3a0ea6bbb8e9d924e6c43aea22cd4969528d50af83b977d4f8681fa52ae6f5a60ec1cedbac91b14b70d46c5ea18551f288690c3aad6428939426326c54a80b1c6281d51b3d47462f18c6c5931c60395a1e74826f6c258f5622f689c4b5470976a961934104b41100142854bbf75d40d09bfd9a0e64575a7546bec19108770c19a7cb48208780e1c657863163022c910f071c59f239a23cc9f1697cf5177f88e7580df8c925b2c405a3360d0a80a6ea1486136faa9c48aa3801ee87b7cc5c638d67be57548c03711f9b2b31ab319d45c578e5acfa30dc426ac3b194230a4bb5ee07f4c5b86efedfe663032fd6ec053e7ae81ee85ae4b3f808156cd357c2b36db2f7fae03ff73e02a217659f53d8c47556bf3d8c94040f630d63605e2d0f923579370c" +}, +{ + "dz" : "6084a235f79dd093ef6d185b54e69df33dacee73a9bf2f379004421a10e3a79d9f684fb055ece19459eb464e91e126a7a6e3ed11ccee0046da234d964c985110", + "pk" : "bd8557528725705c2bd05331fbc20f5560259fa82d438392c7299463710357160f985555dbb2ae4438310e3879982b55f03018c17101c2556ec377b15fe6507488052cd2360b52b8cbc7856c8894cea237e76214da481ef0363c877294399cca9e38c249392d61a2772fa4bffd98165d24760bb90ce22614e892a9c7f350706427ba2257ea7a1304029a6ea715bda9b2fd682c6aec65f70018c26c3a41a30f53976ad8b83aff7268f6d9b3124a15b94528024a179dd24b8c56cc8605914ca89815f943c1c568f255b757220ac606d06a1701457b057ca323ddb65ef076cda0044cac79455798b501463d38d24cb9c65faae94410f79995d917c49319e898aad54c620291491f96362d4792bc3639b6551e5a8b7030e9870896ccf461b65fd82ed0f69dad10bb60805c553a1a195336435303c1c8834c3a25c2832bf7b62e1b50c603951c12ab6b74eb72f4b15abb5455d9f681a0d5a290c0bf0ae79b03973e3ca80d9ed283272592fd0a64938c26803441dda5907be52aab1b9ae14b62f9db044cc0c2f5f48f0b8348a6b26631433dfb00b180b721910b8fb533cfe4a8be1d250d75a9cd492ca059fa115132ae5463577de070c87944bc48695f3b4b04014e9dc29185446e4683ae2cf5b9b3ac399fb6c6541925075b7bca7b7326861dc105b3b57ab55a8117ef69b33cf79665663d3355819dbbb235f9693d7c0062e5293c0a32d7342c18648500f8cb3ae925c530b6507418da33a819e57897849bf3f36f6bd68287f7cf8b5281e9e5af40bb5f76c63d4a14cfbdb8235c6a95415c4aa157568c34ca9f58b3991a756bf5ab9b658d9464ae207206d9d2049d9145b7cc59261860267806a23aa513f3c39cd7aee8e71ae4b3a4a6ccc570f179148c2aa50bcdd612bd81f8206fd1334389b9a726208db920944530ca839f316161b89a59350b2220a4b6c67caaa2425d78da2a3b454e396386c5500f7726aa38530b881640a6870d2e5100ec0c25d5a39bca206ea5652b55a8a31cebc84fa62f2ab6a57a2658240a0f14841e48340cf158bfc639149921632047ace0cc2aee5a3e0f647fc0c671f648c689002d98910f78b34e80c523f9073e4e4c9e6e102818e996d3a30886e7bcf18b69d2a16fba1181610b6bd248035cb90d8d440f6d4729031b21a4e1237d710bddc5040047745b231a22246e517a76d76a0ee7985ebc794fc5a51c17d9a9e9acc471f89cbe260df5c4676d870b8713bca53a400cb9b4fa6c36df97a023ac03b08c621e7329635c2e9828719203852970c2fd557348f5365cc917fd3ccf71d38d5d96336026c7d33b885526632860044237b4a6b09ad392414b068144ac67972b3ce7a25753f631eb1a03b4fa2e9f553302a22eb9c721e9f2bf74a06673fcce5bdb77eb4b525d63906ab2c4e8518322d3065121a20546a8a4eb45f85881ce25721b0058c2334ffcf2946c7b9d6ac05806fa778b2041bad1c1250883873a95e3d5b76a3480d8da8b48683c5db2757eab9193750649e74440dc58a56b3ccc27b2a8177bc638b61e0136a215c8079666c77857018784f38bcdda0c56639c03196b54cbc80b49b0aba6f6a9df352cd09c5cc6e05f62e835f7a125845bba2fcaae4bf61bc55ac98bd67763ec0214cc1b7cf91632960c9ec01e0f27a97f909d7fc2486d0cabfa146b72baa14371041a5336c71305e6e68a43577bc1665c0d66c76a239095e13921c00c4ad11cdb69050f7857c3a1b70e2a2152ebcd0961a936f6146d6a58305086e934061ae32bad1b894cc27949f280320401188775aa5078b1497315639288aa2f1f826b48465613a73c5301383b69181cf14ab3a05035a79de39973ec5c1fc5869af11320350c3c4208cc68db8943a017215b72b3353b77003fb0d513bf677b81f66085e8205c17cdd6b603ac98310c9a967a7b99b8d3af10b66821612333e50d72faaabcf93612210572e6710e482702b17bed5abb5e4a57baf365c39b59dc7cbad13601de6b40f5370a49e5b48c9580a0c26195013e6b6889b99b7ee5d93fc8b795cc62a37ccc5e3de2692ad66e903c74bcc45ed6f16a68ab17d8e5094680c428a242d2fa247985a0b7d7a300f70e844765dc30437d032f216a8d99dcc54da34c0a4c25a8a120b3c32f45a3777467b1e639bcff1bb9839b6b45c7895bcf62307460df309eb4e61aa9cc8941418677001064ac161a607e24e1", + "sk" : "76a86ace9756dfb462fcc13e1c01409b79a49c256d8a75a9a30712f5e913e38240f3520c11344f4329c3372ace01c1979b75c641dc5f0fa2c2ff1a8055dc61dde093315910e032ced42248ead082e9b355a0bc17cf349b2659555d5844d94310633b9098f3ad6353a4fe71809ee99d05c5a055a68e83a35b614361d4ab7e4bf30a80cca2edcb692c25bb35c702854c55939b88e020a329cc35f6f702c94740a614390d6c89b2fa2c324681ce4b600d87b0adc91aee506b50f40640259927b120df4a3a2a2c1411e1a198102b8eb03fc1569b83daa50a7687e1f8b7e2e16b5d13ba38905ceb285a57513532aba8a235c4f9566d1bdbc64be56e4b088e76854868377665cc922cb0a401c14142308e8851acf4ec8484177eaca16ab5164a37f8bd12f4b514eba7ff555ed43415eea7a4b7b4ccb0a08d507992ade401af6a60426972d5f8a19d72cc2409584c4473f4d8088e34b376504344c242c6c7163ce6ca351b3b40a2ae3b7c45a96ac3c30136c880bfcd4166014736e0d575d72c9c2b1278db43126c952b393c47b45152b2c7c59253b9b8d97e19818a9b007fae17765cb60c6722014c6562aa4723c5a33ef63821dd9464ca298b72c68e80213613953e89e2b0d3a4b18347030015cdc1a6716d8a534b5031a5367c70184d7daa93533b46ef97a573fba6b7c39c9971b1538cc1b708b921196e97c7a3658ca9efd1670b1b7934502896e02e18fb0f01b7a8b9b81322951ca25714da90baca924c56132bc8a09b52192de63726d30186146b8b2c233f08acb46092b5ca654c14c92b69e1ca946812fd3b0fe56ac13739bd2fe99c3c62c46ad3b39b4214a3d8220e67a718a16901ca82d59c08bcc7cf2b6a3abdf995ec7a38c06801b0a2ceb88937a3164424161403fb639fb2ad6947a7153ca7ba8290f099a7d6d8322448127adba4e26c5972ac4ebc95905e7148023bb74cc13684267123f57243368f0c141ce0b05f29a61866f99a15a2a85437cf651ca4ed718e5787a0872c536f86198f0125087bc898bbbb479c1dbfc23231db78d47b61edb37f3b03981ab15cb70181fc3b9a1366c9f98acfbb3b6e1cab49b4110eee3cc87dd2ac8d8720f48633d0910c2eab7ea1fb197d3431c7b1becc201a21c02b2e4b5c9e85c5a9560b2105b99c7b7b121842a79179057b6642976ef5e650aec633b0b2b3dd14ca2c0206746595113c7a241443a9a0521421b21bc7238ca77691c76be86365cd20be3d1c8af7c559333b5f94a344c2891467a742be4a457064ae4fe0355f2910a2252269c60a2dd723d5c242a055ce73b2c29df12a629ca382e6789cc95f0aa44bb1e1710690056d507392c9c004fb9079d27a6695b762d80b6533a8114b6691845d7e92ccf189bdc4c32f06e986b2d82706f47819f807032ba5dce871f355433cf05ae849037fb6455c0caba5951d4dd77575832c4425cdfcc70536f741b1a4a1ec47b600d430df473f2ada9313f2aa9b972e7e68c2a2c84d7c9b17bdbc9aaa4468598412c9dc325e3b9d8c545b80e13767373ed61c9ad5c531f6c391f293ab7195237e3a2d77f2685c50b2a9e09afc18c18678b97143bbd52823218a60a87b71f321429a5b7ce32a48d5b3a4578a9eaa45aa66e6444d534f4ed46acedc33325333bb986027d0cb05d93e659a6dd5a09f3f820db8b1751ab32c46473b4284499b5165196871eac3730c062be3482ae8d969a8ab5cf3d1234859bea98476942439e2180ada967e4cb303f8d884fed11a4998af1b2b1113a9878a9290f1e846d3ec68a21c8c4026ca25844ed1464074b84b3b51351dd5a7de685ba338387eb6277e8018091cb7aff0449540b896fa3a63c2bc9034a3d99990b0c34d91d464063c4d7ec08dce0a493096149955b5e06773d790c618a881e91ba94d276e034497b433a65d393b3b764201583a3b57c9cfca20e2526e4670725bc346b1330880d4a4ae348813956439721a3d1a5b7871622378cf73554e0d33905e8656968510e4b2274e69235fc63e0ef78745f99236c27d33e676a626c7a679588ac7998e2332b8e0a39ca33d5d099b087cc966a10c40f52a8ce89b905586a95c1c6c2521136516db69ac7e439e000a97031b7378b99d2112ad69a5ce78c46cc2c6a9efcc85fc3932a956ad313536f3a5b9810ac8bd8557528725705c2bd05331fbc20f5560259fa82d438392c7299463710357160f985555dbb2ae4438310e3879982b55f03018c17101c2556ec377b15fe6507488052cd2360b52b8cbc7856c8894cea237e76214da481ef0363c877294399cca9e38c249392d61a2772fa4bffd98165d24760bb90ce22614e892a9c7f350706427ba2257ea7a1304029a6ea715bda9b2fd682c6aec65f70018c26c3a41a30f53976ad8b83aff7268f6d9b3124a15b94528024a179dd24b8c56cc8605914ca89815f943c1c568f255b757220ac606d06a1701457b057ca323ddb65ef076cda0044cac79455798b501463d38d24cb9c65faae94410f79995d917c49319e898aad54c620291491f96362d4792bc3639b6551e5a8b7030e9870896ccf461b65fd82ed0f69dad10bb60805c553a1a195336435303c1c8834c3a25c2832bf7b62e1b50c603951c12ab6b74eb72f4b15abb5455d9f681a0d5a290c0bf0ae79b03973e3ca80d9ed283272592fd0a64938c26803441dda5907be52aab1b9ae14b62f9db044cc0c2f5f48f0b8348a6b26631433dfb00b180b721910b8fb533cfe4a8be1d250d75a9cd492ca059fa115132ae5463577de070c87944bc48695f3b4b04014e9dc29185446e4683ae2cf5b9b3ac399fb6c6541925075b7bca7b7326861dc105b3b57ab55a8117ef69b33cf79665663d3355819dbbb235f9693d7c0062e5293c0a32d7342c18648500f8cb3ae925c530b6507418da33a819e57897849bf3f36f6bd68287f7cf8b5281e9e5af40bb5f76c63d4a14cfbdb8235c6a95415c4aa157568c34ca9f58b3991a756bf5ab9b658d9464ae207206d9d2049d9145b7cc59261860267806a23aa513f3c39cd7aee8e71ae4b3a4a6ccc570f179148c2aa50bcdd612bd81f8206fd1334389b9a726208db920944530ca839f316161b89a59350b2220a4b6c67caaa2425d78da2a3b454e396386c5500f7726aa38530b881640a6870d2e5100ec0c25d5a39bca206ea5652b55a8a31cebc84fa62f2ab6a57a2658240a0f14841e48340cf158bfc639149921632047ace0cc2aee5a3e0f647fc0c671f648c689002d98910f78b34e80c523f9073e4e4c9e6e102818e996d3a30886e7bcf18b69d2a16fba1181610b6bd248035cb90d8d440f6d4729031b21a4e1237d710bddc5040047745b231a22246e517a76d76a0ee7985ebc794fc5a51c17d9a9e9acc471f89cbe260df5c4676d870b8713bca53a400cb9b4fa6c36df97a023ac03b08c621e7329635c2e9828719203852970c2fd557348f5365cc917fd3ccf71d38d5d96336026c7d33b885526632860044237b4a6b09ad392414b068144ac67972b3ce7a25753f631eb1a03b4fa2e9f553302a22eb9c721e9f2bf74a06673fcce5bdb77eb4b525d63906ab2c4e8518322d3065121a20546a8a4eb45f85881ce25721b0058c2334ffcf2946c7b9d6ac05806fa778b2041bad1c1250883873a95e3d5b76a3480d8da8b48683c5db2757eab9193750649e74440dc58a56b3ccc27b2a8177bc638b61e0136a215c8079666c77857018784f38bcdda0c56639c03196b54cbc80b49b0aba6f6a9df352cd09c5cc6e05f62e835f7a125845bba2fcaae4bf61bc55ac98bd67763ec0214cc1b7cf91632960c9ec01e0f27a97f909d7fc2486d0cabfa146b72baa14371041a5336c71305e6e68a43577bc1665c0d66c76a239095e13921c00c4ad11cdb69050f7857c3a1b70e2a2152ebcd0961a936f6146d6a58305086e934061ae32bad1b894cc27949f280320401188775aa5078b1497315639288aa2f1f826b48465613a73c5301383b69181cf14ab3a05035a79de39973ec5c1fc5869af11320350c3c4208cc68db8943a017215b72b3353b77003fb0d513bf677b81f66085e8205c17cdd6b603ac98310c9a967a7b99b8d3af10b66821612333e50d72faaabcf93612210572e6710e482702b17bed5abb5e4a57baf365c39b59dc7cbad13601de6b40f5370a49e5b48c9580a0c26195013e6b6889b99b7ee5d93fc8b795cc62a37ccc5e3de2692ad66e903c74bcc45ed6f16a68ab17d8e5094680c428a242d2fa247985a0b7d7a300f70e844765dc30437d032f216a8d99dcc54da34c0a4c25a8a120b3c32f45a3777467b1e639bcff1bb9839b6b45c7895bcf62307460df309eb4e61aa9cc8941418677001064ac161a607e24e15109d06641e916a660b3e7f849f08b9dcc32c47e4a7df2d5d4a374d3e5718a459f684fb055ece19459eb464e91e126a7a6e3ed11ccee0046da234d964c985110" +}, +{ + "dz" : "acd1c0217fad5caa4235544dd9de153ab1880ccf4c76f16f236fae4e4bfda04cf03a8abb0a5010f400ae5722a75bdf5a2f6d5b546b34d73857cb1bfc7e587aa7", + "pk" : "f7a1521ddb8ce3e91a2835a177988a4e856467f6ced236ada9bcce8ed885b19b862b952cc8a2269f35826a290a90c170b7f9195f816dd631b1ce66442469c42a420fad3970edec539f11826a4a917ab105123b4c14087f7b2455202a5455159e828cacd84767e5b9c024f4ae6d37596ca7570fabbe591082de627fe04a97f45409fe265054bbb57426b6cfe71825837b4be360ff7b48af3a7226525b77c450cdc4a483a17d77e723c8b1282bb40fb621731fb504277ab50f171bec369818bc3ec22126f6a47ca2937f907890c7815a1e115143f62f58550a0459ce7e04695bc7737787a972321578222f5622449010287ab844e624699a1ab50bd872cb29bfd534b401e538c51c12dd8c467a14c24f5c9856234da17ac5fa28870dfb70565ac954c440db457214016e301736520b5e15538e92d1cb205776f849cc0b23211e6a67ad5c9fceda1577e625bd271587f939fb3acee14135613592a7364534c77c2a1564151c12e1c6a219b878180001e2c94053ebb1282c5288a707ed7b245f15054d87b901c939373244f776ca51b3b9d00628c9a8165993974bac2c0b26715ab1a1b9706e8264a0d210a0e627ae60b59ba58a4abbb61e93f0cf31230a624591e0d1a368390205d6526889640651b7cb71c26807b11913056629914fbb1bc2545b55b2610f992e73812e82b73d10a541a7c8621a4690b2c00149b5b952e91d992c52e8426448e5936dd41ed7725ff1c5bb54803690e7b642805b168829ee5696b5d51a13560a36409a1ea41f03ccbf6bb86a1b205bec128ef81c2af9701752fa54cb3784081b5dec67bceea87a8864bae5bca2aeeab4eca30d460b4015870c0187b2519783fa030a3774277e018274775ea2ba027b8624c1dc569416a3117b57dc5b34a1056e4c9b1ea54b6e5f55bf1cd3c027cac8f5f9b9e4c921d98692a007ac22c6b044f6ac9ae5acc4aa3062a348eb2cad9e77189131bf56aba2d86612e01accc76b3222b01d30b079ff5250e0869545641213c175bca181eb738fc7e80e989b43a0c4c7ba0b41404abe955c3c01859dc17b35f48cc39e9c6ff84625923c1229e9b7c3c2ccfa760c8808b43225ce4fc96bf0c0affa26aa43341f7f14aa37ba5d48798c1661319b31325d04afa0759c35153ec77b07d5d88050f5a1f55262860c94990460341c6eaa32055a480547bb0829d5c3398208018b4c098ac686f1b18870864e2cb0777a798c221a659a0e7e9c5c2936afc4897a611c55086330ee1689f7817f44a6c127a53597576f37b35b4f74c535444abf5342dcf256d04800b04361adc83a207952fb81caa20cc8dd07a6fe8864e562844882b405b5b4b65c948b237b385974a9d4963068c3e5b18c51d42a7a9211d4f274ee5208e530907db49db956b8e10977e2357223523a58b511fbf7993bba3c38a95bc0b98062312a1c9449ddc4082601780ea65a6bfb1467a01d9e326cd10a8e202320d2a29e9b36ad09c44127820d6d024b3ce0c818234f55d7855b0b000462b198a669bf924bc81c99ae0b32a1c21f448ac6084c71a59a90fb43aaa73266e69a077d16a8d1443de4c2b61c3ccc731437ff744b7a7cc3a02a948da951d5763f078a991cb64ca7b049fa1b1eecb534509aafe04437e5f84e974261957ba746705eaf4528b4ba3764816f45045d40e807c14c3577a25f75f69ccaa136ce627742e33db588bdb5cc339ef916d7a9b108180a637586da55085eda466e3c7734f85e6a903ef0fc91ce793910231a8f46a7e084c595177a501b390eaa818c0a9fd37c9be78160c7a398f0e80d8e58966140639656890cd08f7fe92fe316cb1e1517ae7741445a47c8ec3ff8f54f476146f1095f9973062bc17f6723542b0a48e12b7e4dbab100f3bf6dbc219816a76a3109ebba8c823cbbd9176061d072d57726cf12908747bbc267c59fa71f6c719cc7827b91919ca3793d03a73604e1c2c98ca2e99877b6c2b93c97965c06b2dfd71cbbcbc7c81cb56b36587a174e899306acf88fd2689e345a78657c5c0b65b0f3f8206e405dae4738a7061d54db38bdb2ab87e8cb6dc93f2ba0c11b65712840b740ac90ac3404b69cba2123cd335004d8e363eb08148a627b66b4142f66b18e460b59d05091640587212f4dd60b84e61f0db00ac05b15e83a6e0ed3c2bd281161cc07676e12ef19a936d073d684c1491518bdbd426eb5a1463cea8b67", + "sk" : "26c5b889fbcfb6f91cd0805ff87c89368c9cf82c43aa70c6f59b01e297bbbaf7b8c9332721c2bdcb0526788204e7674eb1e975e3e609c82a97988787b8bb8daf49763bbc0fba822a3dda19509bac10396261134d0402073deb6b64ea8e0e98a55fa2cd37b14c1e27cff4e64c52bacadc319d57246bff7145adb11d06ca87f2939478eb094a06361d65aecc8b148b653ee2c15dc618535903b26592c4c334245661830f15638ca13583e387d92c6cc21ab77eb3cc13969322c8521809346a873ee9d9b888b695f695bba983645e22b1a6a30bc05baf1cb49a51dc9eeb5c9c7077495e6800fdca87d3a15ac0d8cc2f2bbfca1626107b3c2a670039ec12aec506e82040cf72ba510881a408595d22c88c9c8d0806a079fc6f7fc32996273a0496c61a22b9c87926aef37097c947eb5875599401d1911b175a770d901a453ca20af484e9735a27a7b4cd3b52a2409a567a369801818e22314ab369c1fb93a9f2a669f4028128bf3a929424d84ba8c0adf7b111a45b1dc6430bad947a4d19152709001c069e1b0b7c00a05c3c420478e05e49788e27d712ae99029037c2e3fb4172d0594d69cacebc05c5d87a8bc91662071c3ed07d84f2bd477454e4fb37468151c0c346053a3adde76c9575386f63bf44ab4b23d3852e274cda84712a28777d69cea67463e563722c90a956057a922c72a5810b0e5895f09baefa947392725c4211898181acf14815eb316855066145063b75260a4c281ba96538073971ac59bc5ea863161a7c0aeca766526b9c627d716521aaf55173fb8eb7308805b47c89a520404548a144589d15490477ac5eb56c62e441d728a808a2ca8dd74981d205c11813ea165e05b938cad77be34a0d1612cb2ec6c90e6283aed35065e74a4d9905713bcab3a1105287162786cd7839537f186bc6717f1132054c482ba0765ab95cb2b4bc4e15704f5808108244bcc1490338ab97cc94a2a02814ad440d34bb7ffd753dd5535f6b7b1f35bb44656726229522e5890ee2f3ae36a468c3c7c21716411bb0c4fa11a3e2baa334c149483a404e5220cea6926ac56dd1fa856db5ad60bb86f0a3cc731b8ac0c48ce98a90c6c20617c8c142697425a7b6017555c7012b63769d6d817e0a810ed84cb436a2cb9a2167c7a0be998b9a42a43545697577209fd09a03d5c902e9082091d0c933665ae84068d3384066b197c71a07c4307fe9aa1fa17436c41550a0337cf70c68a9220df0852ad92853f7fa25905b81c528bbeb8260bc10654589475b1883b77a672f7bbfe8b9bcf5f8b2c432994d975cf6ca8cddc929088c2806fc49037b3c8052448b65812124c82cec2601268f0e998bc41854de6350f56b4c3d31acd427910c8546921132e88a8d1f9c573388cfa3bc93f57c6345682387a69d4220b756f7546d5687dfc9586245b6bb08a9d68263e67c21135301ac1ca2c08a1523132c6cca56b6c05c91d33c44bccc515ab429d9a812693eb1f3380e69be20fc81c76b57bc99498c52784ef3650bd296d6675c7ccb55b67a59cbc09d44d9499a6243140040f2e30d1ff3aa0cf66c6569cfa6d2ca8517a1d5c87fd0d0693ef20d8e21ba5a4a2bebd77cf55698b1a09b2d05bbf7d973c5f5792b165c35bc17f873a9dd95a696929d0f3106bd685fe83871ec99772ba3c21aa523842138191527cfe7646717c65cdc2fa2a9ac97e818625455c2877346b378a4653aacbb1643f075762a9ceba500f0283013269f1b970c9d01588a149c1d8823eb214e76dab3966a622e815ffb22a39e2cb7898b4245a82e72557d51785f3888bef9bb9f1ff3312ac32a0524115ad1897753325378ab94b50dd5172cac3a453535af258a05d57930c035a503f26af358c537519ff53c0e602bb8266abb0a1854524b5311d7488754b51c672fa0b3312e356a60c62202b1678c241438d22720963a0ba51bb4441bd3246adb2511dcd132abbb85c18ace9185907dc3175ca0cc9681c52e91388ae5b4cb4acc4183c588a43e08986e4ca45770a5a40913ad353549c9652d60d5400282040ce17af243614ee4cf045b2c10b6845d8a7704d4173e5cc2b3a6439acb9b2df0901bc229c46945c2a81c7e7742fd96a71066118d618154aabb8e7c9c45b2436f132e3fd48fd5ec04f857b24737c4ea5c218f52c562345af7a1521ddb8ce3e91a2835a177988a4e856467f6ced236ada9bcce8ed885b19b862b952cc8a2269f35826a290a90c170b7f9195f816dd631b1ce66442469c42a420fad3970edec539f11826a4a917ab105123b4c14087f7b2455202a5455159e828cacd84767e5b9c024f4ae6d37596ca7570fabbe591082de627fe04a97f45409fe265054bbb57426b6cfe71825837b4be360ff7b48af3a7226525b77c450cdc4a483a17d77e723c8b1282bb40fb621731fb504277ab50f171bec369818bc3ec22126f6a47ca2937f907890c7815a1e115143f62f58550a0459ce7e04695bc7737787a972321578222f5622449010287ab844e624699a1ab50bd872cb29bfd534b401e538c51c12dd8c467a14c24f5c9856234da17ac5fa28870dfb70565ac954c440db457214016e301736520b5e15538e92d1cb205776f849cc0b23211e6a67ad5c9fceda1577e625bd271587f939fb3acee14135613592a7364534c77c2a1564151c12e1c6a219b878180001e2c94053ebb1282c5288a707ed7b245f15054d87b901c939373244f776ca51b3b9d00628c9a8165993974bac2c0b26715ab1a1b9706e8264a0d210a0e627ae60b59ba58a4abbb61e93f0cf31230a624591e0d1a368390205d6526889640651b7cb71c26807b11913056629914fbb1bc2545b55b2610f992e73812e82b73d10a541a7c8621a4690b2c00149b5b952e91d992c52e8426448e5936dd41ed7725ff1c5bb54803690e7b642805b168829ee5696b5d51a13560a36409a1ea41f03ccbf6bb86a1b205bec128ef81c2af9701752fa54cb3784081b5dec67bceea87a8864bae5bca2aeeab4eca30d460b4015870c0187b2519783fa030a3774277e018274775ea2ba027b8624c1dc569416a3117b57dc5b34a1056e4c9b1ea54b6e5f55bf1cd3c027cac8f5f9b9e4c921d98692a007ac22c6b044f6ac9ae5acc4aa3062a348eb2cad9e77189131bf56aba2d86612e01accc76b3222b01d30b079ff5250e0869545641213c175bca181eb738fc7e80e989b43a0c4c7ba0b41404abe955c3c01859dc17b35f48cc39e9c6ff84625923c1229e9b7c3c2ccfa760c8808b43225ce4fc96bf0c0affa26aa43341f7f14aa37ba5d48798c1661319b31325d04afa0759c35153ec77b07d5d88050f5a1f55262860c94990460341c6eaa32055a480547bb0829d5c3398208018b4c098ac686f1b18870864e2cb0777a798c221a659a0e7e9c5c2936afc4897a611c55086330ee1689f7817f44a6c127a53597576f37b35b4f74c535444abf5342dcf256d04800b04361adc83a207952fb81caa20cc8dd07a6fe8864e562844882b405b5b4b65c948b237b385974a9d4963068c3e5b18c51d42a7a9211d4f274ee5208e530907db49db956b8e10977e2357223523a58b511fbf7993bba3c38a95bc0b98062312a1c9449ddc4082601780ea65a6bfb1467a01d9e326cd10a8e202320d2a29e9b36ad09c44127820d6d024b3ce0c818234f55d7855b0b000462b198a669bf924bc81c99ae0b32a1c21f448ac6084c71a59a90fb43aaa73266e69a077d16a8d1443de4c2b61c3ccc731437ff744b7a7cc3a02a948da951d5763f078a991cb64ca7b049fa1b1eecb534509aafe04437e5f84e974261957ba746705eaf4528b4ba3764816f45045d40e807c14c3577a25f75f69ccaa136ce627742e33db588bdb5cc339ef916d7a9b108180a637586da55085eda466e3c7734f85e6a903ef0fc91ce793910231a8f46a7e084c595177a501b390eaa818c0a9fd37c9be78160c7a398f0e80d8e58966140639656890cd08f7fe92fe316cb1e1517ae7741445a47c8ec3ff8f54f476146f1095f9973062bc17f6723542b0a48e12b7e4dbab100f3bf6dbc219816a76a3109ebba8c823cbbd9176061d072d57726cf12908747bbc267c59fa71f6c719cc7827b91919ca3793d03a73604e1c2c98ca2e99877b6c2b93c97965c06b2dfd71cbbcbc7c81cb56b36587a174e899306acf88fd2689e345a78657c5c0b65b0f3f8206e405dae4738a7061d54db38bdb2ab87e8cb6dc93f2ba0c11b65712840b740ac90ac3404b69cba2123cd335004d8e363eb08148a627b66b4142f66b18e460b59d05091640587212f4dd60b84e61f0db00ac05b15e83a6e0ed3c2bd281161cc07676e12ef19a936d073d684c1491518bdbd426eb5a1463cea8b671c02b230ed109318ca7c1470f5a0ab154b74ee3990ff20ca8ccb835adfda4867f03a8abb0a5010f400ae5722a75bdf5a2f6d5b546b34d73857cb1bfc7e587aa7" +}, +{ + "dz" : "241191401a63afa750f05662e354dddbc683c776ce3222beb83e3cf913d7ed7ca59b3bd23b49a95bc1fad20070fec930b6060bd827d742b077092e422268e15d", + "pk" : "6f161381cbb8ff776b4299a36c893aea783b541b50b2c253c088683aaab40ed421eb113add58b322fccacbc9aa91b74fb0657e7a2706ad9c7c7f7813be9008cb07980c310f47c764b4ea496af60e8e6a534cb49852a2c17b4c7bf096c52c72264b7855b7a5552aa93d9aeb47f5ac34e340a094d411cb2cb962b90588a1b32dd68b662060ffa2ae2999525424114ecb4905a19a1284928ed8c42a2c5461520437f93d3cb76502201412a65983dcbe4c70b9f9320418421962005b39ac65703442002d52d18a83b08574895c0eeef19bfeebcfcc7c308f960090e9be93a01c36044220858f671bbc04f1a7557897df2a51adf85a0f7b25f1480089855f1a150bd8207edd0c63db7b99497aa03eb33a8068067d43a24957a20fdb6e11942559087c3ff343a2f5503b33756d55c9b9f29f6fe83d80cc3cbe9a00e8a31d0b986d1ef7635cfc1cde434f6c826ba5445a5933845d1cb8047a8e2f263e1a86b4f58433c5318e6b86942ca92cae767e2cca9111bbcd8b582a81aa5d22aa29dcc21f374a96e55302b837aab8709202141324386ff7f9c7d2ea068b057cf6954e6a433a5502785bf43ec8854ee7982002c703a0d6c35ee79a316a1fe3148b0d933fcd450829746c70e26d5b7b4792c40ee5c51b80cbba439c212f1c66cd619408d654aacc9c1de097a9d03478351e9a377e08710263728c08a71ab3db7f4a50774f0b99c8306f7d39c1aabc4b4bd64356476f85d6945a404df00b2da8988bc9f6b34579447dc3bda9d1a686e2c8ba67666f179f77217daa8cbe47a40b154c16a773627ab06c66b5c291b8616bd675c0351db13938c0a22c874b33d7cc128113642ad1321e5520a636681ae188f962a793b072badc69316b96fb591a99f53ce160c1c9e56384925afcf5c2dd74069f89580b3c18bc15ab0c91578686cf801b25c56c3e37847be52b5869c2b3f03b9b5b6ab0d2b5043e56bddb1c793d2c0fe47544e61c12ac0771a48c8249b3649d77ad9a4bb5d20c3ccb0ac05b51a0d1e29cc791677693b2d96b83c0d599e46b238063c50c7c101f3b3bcba18fc4da9d71b23dc133148417c2f4369b0c92855e538245f44496413c741282f5d7b1482167d90536b89165226aafd7e8aee821b22f69b963a87e4bea84d5ca3040464e7293b1bab723dd393ee3606ca2940431502f56183cdad305ea19cc3f3974236310d05220f233b383c5bc97ec1544a8528c1c74a6a48e9b9b31097477efa632baa4bc6a8abd6ceab5d774bf988b7d708926275227be2c416dc90fca4720437425ae9b4769443472e2b54ad8924935bc0f65a4740699f2051c1e53153cc354527450c8909366f696c8a323a300a28388bdbbec532afc1580faa1f7821c5a6988d8386265bb9dc1043c5ec2a1c51a35ec910d80a1a4c41755fa669a89e05de79b331bf13ecf88bff92ca340d5b961f446eca336af53a95173cbddeb643d4831c2f563950736fb912bbe370daff28cddc319ebe86958fb1794a97001a14df90b01b3aa0c6e952e79c7af072905f552487bf255e1f61536dc93824c7709492bd133516ae71c1b057cbce6a4a3d48b0744a5ceb1604e41a378e53a9afbac28c3cf97b1b03b31797c40654fc23666c34f77207639faabce69c1e98262ae22ca956bc043fb6748f54310379e975958584579fba4bd50e04b739020df78849aba007a4a23da8a18d449194073903d1a3ea4f43e0e76b299c233c5fc8534d831e69475ab6b611ab02da3251fdfe6b92475041f7814be839fc39bb06912799c553b4647a7073482980090c2c9a96b2866d6d8b65db1172bc062f3490b708b239fcc8a39e8175924c930825916386b463b645b4832bcc399b69a812a992d09d260cfc964eef5c883027a2d44743fd538d05b3417a26974bb639f494131803b10678c725a389aa6abeaf83bc947c6a3d031487488c72b1700b76f25f42ffff6595d87426b67258fb6b993508189e9b37f16c2efe87e3de705ff794b0a50cb7d8bba4059ae2e3ab4297429a3122c3e0568a64b64a401aca8ba2edd807dc0c0656b60b027290d23bcad4ba71de7f9989cd85ff43a1fd519b7eb40352d85b940208f9f8596f1946dc2366736a345d9c7501511101e81928380591c19868128a921e56383d12f19446577783e0b1665396c56cc9046c4c7c08a569d8edf0b76096e3c0643e13acf3d522c782871a1f0b31cf8", + "sk" : "dcbb8186f46c07bb4d36203fb6c89a5a487a0d16c2aa674a1b7a4724176d0a3a3efa4c42a258c7566b39ee2172b36b8102b900327b5c97876d2df233951c6ce26366c264b4202508fb4b37fab78977c76cb91707c32b41ae916708b108c2c303c5958c3f8a84c0b44ed504af57e31baa864871871583a98c4360a8b467ab78d16715860e4f112f4ce4a203e154e78c29ae4035f6a6b3df33a0118b6a70d5af8d9a95c65a6c223398bf541879351943515db63a4c97f7255171cd45c34c803c02668c73397c4adcc7874b2346aa6123bcf9050c22942fe7605606b745e6b375b35ef4b3be364353428abe7b29a9c93072e24b6af7904d87224b4b877a204180ddd63281d7211c17b8dc2ab00b5c71cf086e79b99cf1f7834e85b7c8e403b5e09c15042f5248c665b6b85bf84168d0165ab990eeca036e822bf6499f47b6162261b29f44644c78200a09bfada808a8db934977956fe026aaf342cd768d8f68ab2eccb64d67710995ca46eb10ee5b54d05925019510405606633538e45c91cf5c8d285a42eec3cba21509356cca48633e40b26ae5689e51a618b8b2481b780f071451d6c641911183184748185aa629b316139bbb8b666b9d165a24280bcf695b0d7a539a7950b0f133727141618605c7d8311ec5c61d153badb14117a502f353570c051a7975cf3e0031389ab13409a699ab4b8711c5b5188d71d4195ff54a3587b8a965280326afcd609e7b133da87ab115e63963541e512a6a4966c9ba569f43f68877e9c7659a7f75011e5c9757d6ac23782b9579032a2d83848f2966a5e007464c1f26510589269acdf80d28640aad02142d0c02368203c80ca9d6274a66083b194200df05473a056b20449d68d5af4ad617698c1126666276d38368ab87b104158e0c025dd5b7f8835e9757929c75814179943f05467eb6984bf4600bbc99cc7022fdf21a174bcf7d1504a69ac7693c175cc1bb3aa93dcc1c0599b73b1fe8cb3daa93cfd63dba315a5bd84d5e13b59cf15b86539037565b4e753ba075c9dfb049692525a015428f07b8ad5b3ec2ba89a4691615115b647cbdc9787d3f51109fc42a3c6005fff13ac191883c2683c6f45143e298ecd57f63c9bef9294d7a6a00a2737475d46e0927cc2a3c172f4a2fd960470bc4ca50db3b6ad5902508bb7538b7f9a9a42922104403a0d22bad7f36033c91b6acdc03205ca685e144bf72278efbcea55c7fbedb3798f0c2ac2969e4a9c742e6435400a9beb5c2a7874d971a36a278aac25113f382aaeb0877a2241fc3b089e929b806d72613007924c65c72611d243b00554a864367ce38a1842797cc5d4270f297647f1a4bd87236de55c6f3d1343e26708a623b8a03c3d3043055457a574c9b7b6a013d501189828c99a33d3fc715be7cc72e27cc8b0a397b95a79fc5b78bc5179bf1ce44f71a5d699ba34a271ca67409c115bc67b6a7790d384026246ac0d5fcc0d0f5b92ad2cdfe9c5b3dab52f07590ea07ca292cbfd2c44321c4687c385760988c0532c3dc237a9ec0ac139783d5caa0ebc76d0c25a8c1a0bf1e1ca106466548558290d2683bd69ca296711072c6dd5b95040a5b434b8193fb0c7b0496f9334cc86528cf04b77e3451ae590cbf2c0c55219ee1310989aa2ffe7b3bfaf09dede24a86b765fdb9045919c2c70965f581ab16a90afbdabd46d21edb9b3710c392f1f8115dd12377321016e96334491bf6b4a5f661797e92926551c006dc5a5db6512dc91542f017bd1976068386435a52f6684a0bc257ebd0869f72a5a269a46e5aa608d1a551c8192a7349885b95b3cc38d2d134442c69eb0655d9792ee8d3518cd7841b0563198a9f5526b925d2a02a5b3e7ea358cbdba5b1d22f9416915dfa2d9c399fcddc1f70a99e0c534bcc35382f1b4b4283cfd4575a3ea10ba05c77f316acd1a7459eb40a663978114425e0740676e483c9ac833f881523427335796405f3a0a52c8eadb3952f328a0f5ba2468a594ff00bd673922782b0210a3d97b546e4d3333a7104409625795016e9dc57a7e4815268a06273cfc0866126605110163d6de117b551c986ac4613d24aaeeb0209db97bb734da4ab0c9da2adfe1a058b88b2e5311118279443da1859b23a814b6a10125c7c2a7b2686465840ccedd31980f00786191ad330c36f161381cbb8ff776b4299a36c893aea783b541b50b2c253c088683aaab40ed421eb113add58b322fccacbc9aa91b74fb0657e7a2706ad9c7c7f7813be9008cb07980c310f47c764b4ea496af60e8e6a534cb49852a2c17b4c7bf096c52c72264b7855b7a5552aa93d9aeb47f5ac34e340a094d411cb2cb962b90588a1b32dd68b662060ffa2ae2999525424114ecb4905a19a1284928ed8c42a2c5461520437f93d3cb76502201412a65983dcbe4c70b9f9320418421962005b39ac65703442002d52d18a83b08574895c0eeef19bfeebcfcc7c308f960090e9be93a01c36044220858f671bbc04f1a7557897df2a51adf85a0f7b25f1480089855f1a150bd8207edd0c63db7b99497aa03eb33a8068067d43a24957a20fdb6e11942559087c3ff343a2f5503b33756d55c9b9f29f6fe83d80cc3cbe9a00e8a31d0b986d1ef7635cfc1cde434f6c826ba5445a5933845d1cb8047a8e2f263e1a86b4f58433c5318e6b86942ca92cae767e2cca9111bbcd8b582a81aa5d22aa29dcc21f374a96e55302b837aab8709202141324386ff7f9c7d2ea068b057cf6954e6a433a5502785bf43ec8854ee7982002c703a0d6c35ee79a316a1fe3148b0d933fcd450829746c70e26d5b7b4792c40ee5c51b80cbba439c212f1c66cd619408d654aacc9c1de097a9d03478351e9a377e08710263728c08a71ab3db7f4a50774f0b99c8306f7d39c1aabc4b4bd64356476f85d6945a404df00b2da8988bc9f6b34579447dc3bda9d1a686e2c8ba67666f179f77217daa8cbe47a40b154c16a773627ab06c66b5c291b8616bd675c0351db13938c0a22c874b33d7cc128113642ad1321e5520a636681ae188f962a793b072badc69316b96fb591a99f53ce160c1c9e56384925afcf5c2dd74069f89580b3c18bc15ab0c91578686cf801b25c56c3e37847be52b5869c2b3f03b9b5b6ab0d2b5043e56bddb1c793d2c0fe47544e61c12ac0771a48c8249b3649d77ad9a4bb5d20c3ccb0ac05b51a0d1e29cc791677693b2d96b83c0d599e46b238063c50c7c101f3b3bcba18fc4da9d71b23dc133148417c2f4369b0c92855e538245f44496413c741282f5d7b1482167d90536b89165226aafd7e8aee821b22f69b963a87e4bea84d5ca3040464e7293b1bab723dd393ee3606ca2940431502f56183cdad305ea19cc3f3974236310d05220f233b383c5bc97ec1544a8528c1c74a6a48e9b9b31097477efa632baa4bc6a8abd6ceab5d774bf988b7d708926275227be2c416dc90fca4720437425ae9b4769443472e2b54ad8924935bc0f65a4740699f2051c1e53153cc354527450c8909366f696c8a323a300a28388bdbbec532afc1580faa1f7821c5a6988d8386265bb9dc1043c5ec2a1c51a35ec910d80a1a4c41755fa669a89e05de79b331bf13ecf88bff92ca340d5b961f446eca336af53a95173cbddeb643d4831c2f563950736fb912bbe370daff28cddc319ebe86958fb1794a97001a14df90b01b3aa0c6e952e79c7af072905f552487bf255e1f61536dc93824c7709492bd133516ae71c1b057cbce6a4a3d48b0744a5ceb1604e41a378e53a9afbac28c3cf97b1b03b31797c40654fc23666c34f77207639faabce69c1e98262ae22ca956bc043fb6748f54310379e975958584579fba4bd50e04b739020df78849aba007a4a23da8a18d449194073903d1a3ea4f43e0e76b299c233c5fc8534d831e69475ab6b611ab02da3251fdfe6b92475041f7814be839fc39bb06912799c553b4647a7073482980090c2c9a96b2866d6d8b65db1172bc062f3490b708b239fcc8a39e8175924c930825916386b463b645b4832bcc399b69a812a992d09d260cfc964eef5c883027a2d44743fd538d05b3417a26974bb639f494131803b10678c725a389aa6abeaf83bc947c6a3d031487488c72b1700b76f25f42ffff6595d87426b67258fb6b993508189e9b37f16c2efe87e3de705ff794b0a50cb7d8bba4059ae2e3ab4297429a3122c3e0568a64b64a401aca8ba2edd807dc0c0656b60b027290d23bcad4ba71de7f9989cd85ff43a1fd519b7eb40352d85b940208f9f8596f1946dc2366736a345d9c7501511101e81928380591c19868128a921e56383d12f19446577783e0b1665396c56cc9046c4c7c08a569d8edf0b76096e3c0643e13acf3d522c782871a1f0b31cf8e5a656d13cdb067db3640acd507a2fdc583369ee08e235663a202af6720934c3a59b3bd23b49a95bc1fad20070fec930b6060bd827d742b077092e422268e15d" +}, +{ + "dz" : "b9a6b0c05677e957d41a34ba03bd06f2a9092e31f63389397d7e70fde6409d18e99c0e7b82be89bc3c1eaee6680aa4efd394e40c2b3f30523c8117f7c26a8969", + "pk" : "81fb1c51f687aa1438a329b100805f99f016d9119d2d06c1a6978569e7c40cab47ce5cacc4d35aadd89047a3bf7175cd8833540b8a028c27461d334b3f8680daf57313d7713a35075ce971cac3cfeac02774c3589c21232d5a73d959705be77c3ca0884f8a1c3a89a1059972f115257bc0ce9f13271fd73e7293bf944b82865986a5d56e6c9c825c83271f42908c0953fea66de4ebb820013fe9aa9522ab4ed66334de641f8e66766bfc47a7a5156c182c0bb3628b81b59461b05e3a11d945b36a3923b12abf8f698d1234593d0c784633cdaf09cf8f4148f6320b15c48aa81b1fc3e79fa4055599935e1076c8c1780b1910af4ac9652249b0c64c94137132a12ab62dd265334cc46a3444437a74b076039f39bdcbe2016d8402081949c8e6066f09839cc0adfb5215590aab10c51bb03b68701b0692d1c5c47c58d214b139b83562728b3a771f25cb7638077c4b6b2f83b11df2369ebe9b4e51f36be72bb04e1b591852aea0cc31d1a774768940d73801b8ba23f71c542c8c01559862af4950b7e21f5d4abc3a1104251574e5597076f971b46c370fb1858a1cba35353d29a23db9e756c57a115539824f5375080990b3835023f448a2314d08c6897da5ae35325f9a6107ad4ca05d653ba78c5769e51b368c200543c2a2884a2d504a73827009d166218a981189b5556b38df395ae007772c1222c3e2778c34774c87ae0931bd116c82ae33b3454808e07cc5c6d16c5108c155a451e046260067c6fb0181ae084588017fdbb7ae63e96321290bdb4b3867074e6e684b700b7d5b1074641c5702e287d257b8a54597667c1ccc702f735c30bbaa84bf405123602572962ed89c2d7a3817ac4879d1392f9199c003e63666f1cfc6f91cfc9386b18615bd36913f010270e8a4a9a99e772cbb994b4ca926bf8a04cc1c20c885d2683301cd8c7b381190b0e3dca0d6c33fdd49465fd265781a16fbb546e9b6c6ce0462c604b9fff09cc2d4608259284b8a83a877b9fb18415cd60c37b0b3d6a48c803a61b0a5c9675018f64a013062440f0c40c62055cca7bb6cb9a293193485fc529922478e4c620a73144a57833d3b5b9bb222f2f4b452447cc06638fac1b4404402449a3cd60bcb2fbccdaea42086682ad7f972008276e4e5449217088b485ce6757eb3410c62796d0e7a643a3c72c612ab165475f6e51456d498e858aff563c1f7781035fcab3c85cfa2f207d1e4703d3015e14689fa0c9b1f57984b678baa10cace44a2fb23bc1f317d5304552306183435c62012b2ccdaa9a744575f959b57b9ccc2c28e1a94959a812da6f259d11479fbbc97f54a57a986be61f49ec42124da687221aa3eb3b2c0298249746b20cba291f1633e784608d5897da13a20ea377df6b95198132a7fd526d065250f97525d809bf9cc7270c7b723cc95dc9c8ddf5113ec4c8b3cdca07a7242034741a3cc684a998514fbccc435a8a2d92675e6c3f252a7019a74818689574c6ad907080954557cc12e1d47ca23240b78c2301f39c78127180c268b76289132aab01f457adfa649a4324a08e0bb5345cc2ef90fe6e33588d6adb499b04daa642fc01f5777bef8a7af04179630619d13ba0991cb36e8c23f16baab09a72e7388c93385331f7b5bdf420f1e75c7ad28c54df96df3f1086fe4120843af7c7878b4483956b022ae05112253b97e6a61780ccf4047589ea04000d57593622983e8187a6232deeb59f5e147ef1628a9f692b8bccea069cee6f49533b7301728a3ffc85d7db98398ccb38523254f843dd79bb58b4796a1fc6d68095b8faa7ff9381d01d61bd6694f2c225c46086031a86105661033948c29278e422b304dac9817401af89540a29a1cd6093c86a3878c226fcae156b85038f4ac53579143f2f5854f825b0d45bb974b724368814a9487a60a6e41261470935a90ebcf45b53279c67d92330556e99606dc22a2419021896b2eb750b2479aae7a706b1bbdd9514173f23dd3066161a0af8a6a9ef6aa7efcfb1306b9c421f63be2e376f747731a233a45a8309ba8182d24cf6598c26d65c89da9c9e9e6b9579a4817552a8d355ede798e09781b387c9935333b15d92998a4c736d266dfc2ab61708fcac7b821c01044492f7f4bb8f37b5026790f3a437cfa63af88341b95a8899ad31b37491ce3e42fd9b3701a63d537569b75a6b4b362c14f1b4ba66ab7914c9900187f1057", + "sk" : "7c12448f6c47d923c2abe1a0d6f5259b00b5b0f84304fa9192c5ae32fc6e7d0c6d2cd2162e121c4d202a01d0c471f7a959f3941fe56655f808c139b471827d24d97464993bb77b69a45b0380a666874804de793a2ab31d749070bf174ddc8a113b50c8d11037dcec6ea71a7a37e84e133551494a2cfa01bfbac60ea3691b60312ae6707883c74fe70954565abdabe07364db5c76fa2afdc234c63b39fbb597eea25faadc07d326bc06918b201630cbd166e935cf713373bef1749f0a579b77c185a9855e444a353a0804065c3640114d29b25e96ca34e8912454a2c9d39f353103ac17b7d3742222e605b50043e06350e655bda46760e6073b0710691072b52681a81557930fea99f1c13ae618930466305cd56e7879c455f1c7f140bb37dcb56c807955a084a7866b3858a78372487a565da243c7c328c355bb1e21d25c499bcf2de82fb77349d712a365b395d3a1a82d43326d464cabcba97d634fa0f54226029d576304ab06229bf59be0a3be83c4a927157db10743b9cb4070896e79b17483b07d185aa097c790b1b8168fe0aa02f47965e11a1f63587cb512d65b2cf4080d8be80608e0aec5d98a77813492e57db94c20b3b4a29912466c2b693b2464dc8248757b808931727a7270fedc06d86339886a90ec5a0cd5a66462646f66a9bfa959a5c790af13b777f31bb0d1952e1c0a241aa743b54bc2cd4a3583d735a0774a65a57a1db99fde48381b456b2d415ba066ce94c8ce2f144efdc71465f3aa19bbc8aa2cafc85a0fdb06a784a48fb617bf3b7847b91037ce732d10cb2cb92331c38003dc87647015146adccd2a3761283c221f90ab65816107d69d5b481269009f43facad5d52830f53df74b172b41c1aa693e2bb9a2a1bbac5a362a9c190f142b71ed621429b58e88b05851668bb0193df370402a8c6dc19591d84090a879b0c297c2b352bc74bb6a91a598997cb8a7bb3ad9553b9eb114e4b44e30e2698e83a38134be232995a66644e1a0c308b014e1dc5dfc71c580d61acc478db94052340c109339731610223e212cd7ac3e7be983cb75b0a9145fc2a058eac5288a584ca024258a596bdb2a64b42a471a2c40bea222cad46478007cf981ae7b179f1864a76d0b6d3cc3324735bc2c7474a7c9778777b01cc85c67fb68f5671a74479b691137a006d0d5531014ab4261dcc4c88c07ff298eb9209d3234637f1b8bb0bb506d582467247fe6286ea885612b0648aa593f5436873646406bd03e65a549e610a6502121c0c84ad16c7da8026b2d47334553967f749cad20421be2c67df13225d694a4f84faf99c61953a5199a556b8b6e86ac9dfdd4223fd3adb37623d5a6c8a292ca4a048a7a72b7cde58f60e227efcc5290f5c55e75274860813ea29496123adf577d22dc57174a25188ba951970597359c32b24031f264fd8494121727c7b4940ff4cf12f4ce8ae074272a0ce870304af5b274e44eb34c8aef476190917b0194bb75a23be748c15a69525aaba908baafe6f67b4140bcc9f8670b16a84ea855d67610ec1a6cebc7ca15534bd740bde1181660501094050fc8c58a48f4b87f98cda881569d03be5db1a4418b86f93aa5f18a9e2873418d5bc9cb849aadbb04883914d413955fc072b26c17af227e7e3bb41c666c8ba269e5d6c9d14a13b458cc7e7b37907003e4a089f2941f4ed3b3b7f7caec60ba21389570e014612088db3309582254e7a4667cd3755f4b3e536ab68f36459ef04c1eb210e17259ff714ab8d1052a6c03351a829a02a0f9267e6f62912b188627d907d11a85237ac296e3629151516e495e69c9bf93677bb1582900d5c3ee554d9e491bc1972239c96d17937b094795e6780b84f7baf953095e909c11a90c2d803a3d7a265a9894d9b76988f9b54dd033d4c2461000087987a1f81a2027a036138c42dff0656e4338bb717b0da922e677b1d6447565f5cdf202ac9e7232c2b962626729c1f6836862900a32688ac60716286ede932085d23774512f610881b63b1e34b77b25e30c7472969b7b2f4fb03a4fc46217a0a562b27345eb8038b22160913bf658478d089a88eb9e07b559d268be07ec3e9f9a752f7c110633821fca2ee9dc3b94e9a190759c6c4ca9aaa5547c1c86d714ccbed6c41ab53d3379bbe7c189bd1860df788fd4528281fb1c51f687aa1438a329b100805f99f016d9119d2d06c1a6978569e7c40cab47ce5cacc4d35aadd89047a3bf7175cd8833540b8a028c27461d334b3f8680daf57313d7713a35075ce971cac3cfeac02774c3589c21232d5a73d959705be77c3ca0884f8a1c3a89a1059972f115257bc0ce9f13271fd73e7293bf944b82865986a5d56e6c9c825c83271f42908c0953fea66de4ebb820013fe9aa9522ab4ed66334de641f8e66766bfc47a7a5156c182c0bb3628b81b59461b05e3a11d945b36a3923b12abf8f698d1234593d0c784633cdaf09cf8f4148f6320b15c48aa81b1fc3e79fa4055599935e1076c8c1780b1910af4ac9652249b0c64c94137132a12ab62dd265334cc46a3444437a74b076039f39bdcbe2016d8402081949c8e6066f09839cc0adfb5215590aab10c51bb03b68701b0692d1c5c47c58d214b139b83562728b3a771f25cb7638077c4b6b2f83b11df2369ebe9b4e51f36be72bb04e1b591852aea0cc31d1a774768940d73801b8ba23f71c542c8c01559862af4950b7e21f5d4abc3a1104251574e5597076f971b46c370fb1858a1cba35353d29a23db9e756c57a115539824f5375080990b3835023f448a2314d08c6897da5ae35325f9a6107ad4ca05d653ba78c5769e51b368c200543c2a2884a2d504a73827009d166218a981189b5556b38df395ae007772c1222c3e2778c34774c87ae0931bd116c82ae33b3454808e07cc5c6d16c5108c155a451e046260067c6fb0181ae084588017fdbb7ae63e96321290bdb4b3867074e6e684b700b7d5b1074641c5702e287d257b8a54597667c1ccc702f735c30bbaa84bf405123602572962ed89c2d7a3817ac4879d1392f9199c003e63666f1cfc6f91cfc9386b18615bd36913f010270e8a4a9a99e772cbb994b4ca926bf8a04cc1c20c885d2683301cd8c7b381190b0e3dca0d6c33fdd49465fd265781a16fbb546e9b6c6ce0462c604b9fff09cc2d4608259284b8a83a877b9fb18415cd60c37b0b3d6a48c803a61b0a5c9675018f64a013062440f0c40c62055cca7bb6cb9a293193485fc529922478e4c620a73144a57833d3b5b9bb222f2f4b452447cc06638fac1b4404402449a3cd60bcb2fbccdaea42086682ad7f972008276e4e5449217088b485ce6757eb3410c62796d0e7a643a3c72c612ab165475f6e51456d498e858aff563c1f7781035fcab3c85cfa2f207d1e4703d3015e14689fa0c9b1f57984b678baa10cace44a2fb23bc1f317d5304552306183435c62012b2ccdaa9a744575f959b57b9ccc2c28e1a94959a812da6f259d11479fbbc97f54a57a986be61f49ec42124da687221aa3eb3b2c0298249746b20cba291f1633e784608d5897da13a20ea377df6b95198132a7fd526d065250f97525d809bf9cc7270c7b723cc95dc9c8ddf5113ec4c8b3cdca07a7242034741a3cc684a998514fbccc435a8a2d92675e6c3f252a7019a74818689574c6ad907080954557cc12e1d47ca23240b78c2301f39c78127180c268b76289132aab01f457adfa649a4324a08e0bb5345cc2ef90fe6e33588d6adb499b04daa642fc01f5777bef8a7af04179630619d13ba0991cb36e8c23f16baab09a72e7388c93385331f7b5bdf420f1e75c7ad28c54df96df3f1086fe4120843af7c7878b4483956b022ae05112253b97e6a61780ccf4047589ea04000d57593622983e8187a6232deeb59f5e147ef1628a9f692b8bccea069cee6f49533b7301728a3ffc85d7db98398ccb38523254f843dd79bb58b4796a1fc6d68095b8faa7ff9381d01d61bd6694f2c225c46086031a86105661033948c29278e422b304dac9817401af89540a29a1cd6093c86a3878c226fcae156b85038f4ac53579143f2f5854f825b0d45bb974b724368814a9487a60a6e41261470935a90ebcf45b53279c67d92330556e99606dc22a2419021896b2eb750b2479aae7a706b1bbdd9514173f23dd3066161a0af8a6a9ef6aa7efcfb1306b9c421f63be2e376f747731a233a45a8309ba8182d24cf6598c26d65c89da9c9e9e6b9579a4817552a8d355ede798e09781b387c9935333b15d92998a4c736d266dfc2ab61708fcac7b821c01044492f7f4bb8f37b5026790f3a437cfa63af88341b95a8899ad31b37491ce3e42fd9b3701a63d537569b75a6b4b362c14f1b4ba66ab7914c9900187f105744df0b816ba22f5d471848886dd490d5c76169a14af42c03b0b56a7e26aa7ac4e99c0e7b82be89bc3c1eaee6680aa4efd394e40c2b3f30523c8117f7c26a8969" +}, +{ + "dz" : "28a96c71577ba00c94f99fe965bc595a26db2b3ca6ab5cf8e443cdd8462b17929c35d165453e5fcdc6f9df64526d9de698f2bd3e6bac6c7fdd86601b9ba5f4a5", + "pk" : "55a15b77118695a2bfe69365a4474cc5f1bd3bc30beca40fa5ab05198b708d58110aba64fa4a8e5f955bfd935530b95f16ea816074ac23f8435eb22e85b7621481444b699278082693f073d623c99764c759aa0d6d3211fea1a61b048519e142eef86ec20430812c26aa3812c42471cc8799b80915222111c96b09ea063518c42786569101f81eafe3229fd85900da5abac8a84a688bd58a03213ac8019929e089a24ff8c712a1751856722fc7af3c57bbf95c77c38c85d3e481916c75ffa371d2a0c583b03d301538cf49c744f429d2c80e1ab13c5e126ab6d3ccd733177e469e6a30cbe0c3212215b66f57bedbca118be24c4a3267a1e65c8f924588e9b10ce22157650e64314b7643136e87bc141c9a01dc7b746556a1ea01f5aa8d22671be3177bcbeb605093a225e1a847c6ab78ca89c4d3a4a618932025aab56646a974b088429e182308dbda27fe6a0a7f5a6b36d681cbd94ec205a018319a89345ca5715ef79266d1f67dff2a1867366d14bb60625b9883740f4b3627ac385fa728a51c162401d86c4f2385bb9661ca891562523a7a66111195bacec69abd4c35ba6959397664ab56a621a25b00c5aa2c0793487a8b1b5847a29844d6e8cac42ba2aa3586ce117b010aaa324236855771cc999929f0b948c671b4a7ced082358fc94147f86fb01c3b1210bfdfe266d1f60a72baab460aa7ce7083d4b913635332cf559b121a26fa643fbb7553781847787c8d78e9662cb82941627bc863bc79799d4681830d3b41d156384f157e3ad27192b92e47c106ab6c1304a3b56723162e933cc28b220f45cbb9615cc90aa3483cbb9b510e7aecbd80b28ba3a51e1264b6c6023c30843462f33faf090e43555635c674a80679fbc88270ab53ccc83b79673e296a1394dba0bc2b421b02a0d4213890d0093c19384298b039b5b8f4f61a2ce286bf11b9a6c164bb5a269427999d707c3e62ce88d66fa283218ef393a4ec7a35e2a927b92866e5976e1b95122236c2800d2b4989e0759ab8bc1f37da21288ab22fc4a13bf8068a9abac80c814d150885762275c638087b643b60b4673408869156d52ca257ba50ff1354f4164b4d29069a99c7805527c7674c2dbbcf26656d110823f082bc88405299e093195038f7562b11daaec75668b71244fa6769a18b2d4643930704199f0105082ba91ff44f7b6bb339f243b524979ac51fc92c6b75711193fa29f898141a6c444e2850f03353fc6ca27f0023b9c88f6c0b8aafc9cb9981c460e2b17d594c7a60b6e3451c9675c923a7b1645c4d3fb28b1e42ae1f93090b86659e1a7d46183d26f380a2c046d9028e9906cbdf1ab605367be6a5609e79cb8dc349c739b7d4f74007fa69b9b50c94223e214509b2e057272476b1653d90740b0c059b1d2845ea9a57cad384a2c7cc2b926979f60fde47bfa01a217cd3c43bc01aae86642b84b79ce58296700427c78b7f32116823ba964379f1374e4b164eac108234b12139d580ec4bc11be3b62442445409204e1a9459ab3d7d33815e76589ca4009b27ca2e6ca470b61504569d0e70155d988b80988cda1c9ec0da673ac2497d6a2fe1cb8539f5262bba5104a4cf7659a616755cbd6a1cfd42a9ee1c115158a66af0bbceb149dba4af4ed2a128a988d8aa5c97164be56483e1816e52402b908b12429c505d0a3a4b2366a7bb38169497e7ac0e3ca8ad8f9636a54cb4b4d667d91752d6658a08416d552c3ebee80a613c41de4478611598bd05b34a66853b079481885225941beb4b67218013a3772a60e55aaa25ad44575f45a3178d37af2786a76e20a5a8719d84e693f693507aab4cb43c55a64339359b8075a643b7a696c373144a743288c37ffe36c454a45444c2a48c3c7d0415c125d133670ca1709c7f80897751fc8d07f30ba0a3b10f7110b03863e5b040b7942c6a527008f7952b89cff921280296955261ca76f50d1dc0a0d2b8b682d8459fec291c27c1e281bbf5a17dff0c0c75a3bb4c987f30b175c293931fc444728ab8590c6095c60542e6bbd2a39e324b96af61328ecbc54da1a44ca7a175c61a131610bad5144b702380d45b5df1622f3b2a4e640457ac830c8cc05ef95b4429b599983bab346a47443575087e975a57ab91601ee65966b51838108117934a5f334979349e3fdb9b49ca49252a4214b6e298c3b12e5f6e85ddfa7edc01a03b27468684972318831a", + "sk" : "a9a63209470b02c598d426b60572256c3a610ee70e65d20bffac56f5371d896255fb79ac3934b43c78ccb0cb8ca428c975e0be2e901c85f92950ab2e2e30b75953656e87c5107b1ae0b0275c0ab1e0a9019b3681e0b909ffebcb467447ea7c8a4328c7fd485f4a6c6aeb6c730f10ceb68c3a3974bb5c2a37f3c588e6e9058dd458f478b702467155d9a2b0d28b5d60bebbea16924c22efa742f59c10ff235f3ea05c51a721ab75550207b3a6f36e34683e7cc5127210015f20082ef4aea1c273ab2c1adbb235ba590f027028313b9fcaf656e4747d0461422efc565276577720223f8600f9c3739e185c98669cc75a282ab8a663285afab5b1b406818c19508f99c9f35a01144a36fb8a68f12516b7eb09eed336bb0440a013bf78c19ca0f11257db7751e5b54033a74fb5ac24d07fe2a547a0f9882b83570ed29e2ae403eef911c3827cce4a3b926b4c5fc579486836cd9c78cb537369d270798aa6a5707a28a2b48a93302f4ba79c8882e23256a335bd7674612749383e8399c7715bf53945e57927c29b2d04481e43e8a91d58511d975bef95a304f253f9027d2948431da71b92c0319b9512b5cb7dc6908a9fab80d0f25f18207fa0323c7951ba4272c053440d0b9a81fc84708643b1a2880c7272a9cc0034246430cd396d4d2134fc1477aa0261ad5595a384cf19a6c37be499274b870ce21120033092e70a38175388645c86692c5e213a29c910323270c790376a19a3d11742376c797e55628adb813aa4ac10d2659a42a3fd7aa13c9c67cca92d0bf0a37fd093a3267892bca285c93c45ec65d4e0a63c3bba8f0051f35a939f0c11b0356c160b14921b4aff79a127b35b5a27c431252abda5a570c48327fb7204d7ba38a79f34a15ae5a2750e27a3e62acf8fd87329b78e426a1bf91901190a29fd820c7656969ae737044207c8137d8eac5edaa41b606b257a53af4d0acca2266618f081d743ce9803c1ebf29afe0c24ac83bf3ebca2bdd35b98355260c31819d7c4ca9c5550972b34ea388ec62a04cb6d06f083b06c4850814b1b4b65e3931e2037c4d89ba1314ca2c47b7dd7a06f11150bc5188178584f825205b693cbcd51612c13385c98b57168b0c4f9a488a81d31a3429968310496a665446fa6a988b7647b95ab582193543906b274cc73925073c55532d7e9af4066998edc208aacc5a0e23431255f1cacbfb380335046cdaf416417b80fab2bcc834bb9a377709069a330f654929c39a0aa95126cbf26fc320dc34fa8eb706234878b516ba9854d2265acfe5ca3ee0ccf5a413b884a9757608453516a524565345b0290421003e71ef631266a021488303a56998505cb4020b1c38c859f33d914ab97a0bae13f620a090f80382be3a40efa723bf42fa10aab9651485f8c6d3a8621a863723bc4ae27627c18287d0bd01b8393819100cbcd28b4173c35b0d874dbbb4e7e3793f16785742c282e590b4b4960c8503152980dde8b5cab7186fce546a8642e7a43a0e939c17b25c8f7ca3b15814ebc91cc213920bd35848d8b412c0269fbd59f74382a27206f2886b33ffc71cb896f225170cc730e07092031e60cab064be4e005af92428b8bb522237413e72b18949cb06588db32c5b53570a93796ded26a22ec8e27b9a042795901b97507789905c421b3e1260263ab704925c7d8ce3393ce04a19486559eea554ec40361010b73544c590147256cb50e7d940e9dd859ac8647f418548270941a53bc4d126f050152ae557f15756562c0267d26c1db4313e5ec6e0f76a2085a77aff2c1ec5cc4d6299591bace03b527f3fa71d9786dec5c9c1547c9e1665d707b565bdc93f0a0c88ae3aa5a00975d136a64a375f05b9e4efcb85775627619a04000b1cd518dc8854362819ca583c71f4c6cbe624d847a2651776672501a71e3717f249b5a7582583b18f006530feb7d68855592026cf6f52f3640ab33032e7d609fb8d3cfcaf15d3abb0691e478d528af606014bab3c15ff5cac8c774142c9433d6bd192676cc4b7230b66ba55a50426c1a47ea6118b4913b46ba3f72255689416cc47caeeb470f8372dd21aaf34687bbe5a66c402762b64b96a42a3bb47d14554c8dd4c31d4c7c1c8071050a41df9a1377d6457c341f6f1538fc74247581640a505f85e151f1775885d7b655a15b77118695a2bfe69365a4474cc5f1bd3bc30beca40fa5ab05198b708d58110aba64fa4a8e5f955bfd935530b95f16ea816074ac23f8435eb22e85b7621481444b699278082693f073d623c99764c759aa0d6d3211fea1a61b048519e142eef86ec20430812c26aa3812c42471cc8799b80915222111c96b09ea063518c42786569101f81eafe3229fd85900da5abac8a84a688bd58a03213ac8019929e089a24ff8c712a1751856722fc7af3c57bbf95c77c38c85d3e481916c75ffa371d2a0c583b03d301538cf49c744f429d2c80e1ab13c5e126ab6d3ccd733177e469e6a30cbe0c3212215b66f57bedbca118be24c4a3267a1e65c8f924588e9b10ce22157650e64314b7643136e87bc141c9a01dc7b746556a1ea01f5aa8d22671be3177bcbeb605093a225e1a847c6ab78ca89c4d3a4a618932025aab56646a974b088429e182308dbda27fe6a0a7f5a6b36d681cbd94ec205a018319a89345ca5715ef79266d1f67dff2a1867366d14bb60625b9883740f4b3627ac385fa728a51c162401d86c4f2385bb9661ca891562523a7a66111195bacec69abd4c35ba6959397664ab56a621a25b00c5aa2c0793487a8b1b5847a29844d6e8cac42ba2aa3586ce117b010aaa324236855771cc999929f0b948c671b4a7ced082358fc94147f86fb01c3b1210bfdfe266d1f60a72baab460aa7ce7083d4b913635332cf559b121a26fa643fbb7553781847787c8d78e9662cb82941627bc863bc79799d4681830d3b41d156384f157e3ad27192b92e47c106ab6c1304a3b56723162e933cc28b220f45cbb9615cc90aa3483cbb9b510e7aecbd80b28ba3a51e1264b6c6023c30843462f33faf090e43555635c674a80679fbc88270ab53ccc83b79673e296a1394dba0bc2b421b02a0d4213890d0093c19384298b039b5b8f4f61a2ce286bf11b9a6c164bb5a269427999d707c3e62ce88d66fa283218ef393a4ec7a35e2a927b92866e5976e1b95122236c2800d2b4989e0759ab8bc1f37da21288ab22fc4a13bf8068a9abac80c814d150885762275c638087b643b60b4673408869156d52ca257ba50ff1354f4164b4d29069a99c7805527c7674c2dbbcf26656d110823f082bc88405299e093195038f7562b11daaec75668b71244fa6769a18b2d4643930704199f0105082ba91ff44f7b6bb339f243b524979ac51fc92c6b75711193fa29f898141a6c444e2850f03353fc6ca27f0023b9c88f6c0b8aafc9cb9981c460e2b17d594c7a60b6e3451c9675c923a7b1645c4d3fb28b1e42ae1f93090b86659e1a7d46183d26f380a2c046d9028e9906cbdf1ab605367be6a5609e79cb8dc349c739b7d4f74007fa69b9b50c94223e214509b2e057272476b1653d90740b0c059b1d2845ea9a57cad384a2c7cc2b926979f60fde47bfa01a217cd3c43bc01aae86642b84b79ce58296700427c78b7f32116823ba964379f1374e4b164eac108234b12139d580ec4bc11be3b62442445409204e1a9459ab3d7d33815e76589ca4009b27ca2e6ca470b61504569d0e70155d988b80988cda1c9ec0da673ac2497d6a2fe1cb8539f5262bba5104a4cf7659a616755cbd6a1cfd42a9ee1c115158a66af0bbceb149dba4af4ed2a128a988d8aa5c97164be56483e1816e52402b908b12429c505d0a3a4b2366a7bb38169497e7ac0e3ca8ad8f9636a54cb4b4d667d91752d6658a08416d552c3ebee80a613c41de4478611598bd05b34a66853b079481885225941beb4b67218013a3772a60e55aaa25ad44575f45a3178d37af2786a76e20a5a8719d84e693f693507aab4cb43c55a64339359b8075a643b7a696c373144a743288c37ffe36c454a45444c2a48c3c7d0415c125d133670ca1709c7f80897751fc8d07f30ba0a3b10f7110b03863e5b040b7942c6a527008f7952b89cff921280296955261ca76f50d1dc0a0d2b8b682d8459fec291c27c1e281bbf5a17dff0c0c75a3bb4c987f30b175c293931fc444728ab8590c6095c60542e6bbd2a39e324b96af61328ecbc54da1a44ca7a175c61a131610bad5144b702380d45b5df1622f3b2a4e640457ac830c8cc05ef95b4429b599983bab346a47443575087e975a57ab91601ee65966b51838108117934a5f334979349e3fdb9b49ca49252a4214b6e298c3b12e5f6e85ddfa7edc01a03b27468684972318831ae360d6a628c3b1b5dc926153f22a88c7b953085255edd2a72799bda15e49dffa9c35d165453e5fcdc6f9df64526d9de698f2bd3e6bac6c7fdd86601b9ba5f4a5" +}, +{ + "dz" : "c08ba2ef8c3a0a043afad931652d7a19e6e8cb670f840de5f1fa03309b2ca9ec5fe6141a25f7ab9f875f79e0a82d6ea5cde5a017ab637d5fdb7c42646a1d71df", + "pk" : "31596bd912527e2c965ce3344b4621190c106f5084836006296c37949aca196c426f4783b65221b9c50827c85b7067a9872a6d9277828ea9385f9b512a8a3e897628d1aa36a5206b35fb219ae26269126b75590b2d1067419b27fa6852a3552d6ce48c9193c96a3131397166d47c53eebbb68b949a5bc3c7d585027961aab89b38f5295ce7c60d3d9009508769ee37a48de0685b9228d998b883d871985108b49c908390cb68147e8bc561df29cde02b1ed5236ed77b23b3f32e687b859dd63439890d8735640f5c073bc05cda79603cfb37fc5ccd28e98b4eb169271408a1cba57d21afb87c97e2044766b38280b6911b95725d5a77327764832603fe771aed89baa1c8b2ff49b741081884c6326fa0693fe64551402301a0552f49035a262e9d047d8a2075fdf6636c726f8b6098fb2b8f01c89e87478dc1112c37f1b857fb13cec53673e297b8aa9612d26a4cd0c6168c9dea407133acb939d06a7c660581a877f046b9b1138f6fa6156be2a5bfb23d04954fe32b1272d73e39c79094864cc9e36e46e9c8f1db330c17a0ecbb332e385769c4c0ace7c0b0d49fb89503cbc13ff3a1b19f421b80855fcb947cb651ccc0a7b55b5100c09aab9201c4ff8c56a2d90bac255a3665a731d07b8ad829f7a7b556ac12acbc1073a40b7c36059edccd97a50c493359c8ba390e3716921a69998b9b111c4dd283456f7b61ccf97c1dbc362e2760e2928227405e449c126d7526516298f6315302288043085808195ea587118d731543f09479a2adb96884b3a620d4c86123818cf848b295eb0035211bf614b077871db1d8c779d61e90257730e47bba178ac5e28b8e47794517727e4049dc759ed5a69cf7c66de05c0a5a00c366a87f7f2914e1e059bd1921eef61da9cc201f016f1cdabca2d2cd99e1884c114100ec5fd0f415d6fc6222981d8e4582dd138d71a368bd5590645359cf767146f2cf5f7a58e0e1becadcb1da0c87fd385c4ad15e02836d866025d0d815af61b564e803f0f0bda9a1ad0a3b86dd9a79b29792a713c78f00c55668aa2a0962b4a9be8bd9cb6966a054f0ac39182ca4d54fffe197891b964933aa8d60a87ab0af08c139a8e79b7a5773cf189caa615f64b973eb273edefb27be439ddff2a1fdba7f2cc3c65dfb0d0cb177b7ac49ad1b4da0725a3f3a2741fb2c82347dac329657c9bbaeaa948102295c1828b01c22ae45cb0e0b46a68837ca5c8639ab483eec5b4dc9caf028a7bee18accc402ec6aa57a93a1c53a145e923194341bde96296857890fa616d1bca0cadbbba3e4302e55286c58a283ca8d1626515e6a84881aa692c662a3567cc294a23059392887ce7a835f8b8030f5c1060518c71e0c5621812d54d50043b73182fa67de92768c63c4a2c562ac151342fab8fc9181be82301404792a94258b98411ed093a9121699ea13fc822bb5a317b55c1167ac12bd8c3ccd9bc743a634ed6a0961e13ad91a779a242dd0b9b4b41a5da11cbea085032ee2382c4b8ce088524075cdfe7b7c06cb6f2ae128f4f7a6c5d58011b42b8cd39a8a0aaaba14a0ea8c9a72f322693410cac54c3ee5487d726acde02f9cd0b027844ea1c018e2744571c3a2c36b4e0da088f09ab939152e30696cfd3473a085be3eccb53eb406b66c95ef8b1cfcfa1df8c8238b8c129abc9176e0864415852cc8ce13970fe8a76ecfe246800997c56668af974605e748e3054700d7b75fa182278309e41cbe5b4a17696c843fb4ad72471bac747faf30c99d2433665433ef29b64870ae8a3593845ac211ca4af0e5aeb9b8afa5b4419559502e834f993543353835596985e31529c1482d0fcb9c11a1c79a704db1d531bd0774f91b6810b98766a83387387c0682584c94793fa771ab8b4216455f7a117c65e5a481e01b5bd8bd0a9263635815f3c13c7c6740d2d1778ab47d56c9a37ed4a660249b8a4a02cbd716f6a09a646456c4b54cad68c86f8b998855379560692cfa68b5176309162a7a506b28e042c25850a7e6357ebcce387146b94a09fa82ad2cda8123477f926757d552929ea72e379a9bb997bab0d1aeb5f02568e7715d959168129cd58048ab1299eec754b9080e7337084ddc37c4695b75488effdc370edb65655231ef1091d762b8ec53a3283b3f7bb5114429c788a2cbdce1c0454466882448990d0c963c4dc08e6955a7aa5238a6347a0d168a1ab143347ab4", + "sk" : "e7831320d38dd5629ccd557808a8b263730777d379caa64e1da51cd8c2baf8ab930118770cca3dbc11825c867af4421c87541c5a6788bb93b560948dc8555c8caa6597441e1a6313ac5a8ecc6a0acc25cdabb2c59b49352cc589f13269ca38094d2a2029b070e989b0a2d15332ba43657b23f278b1a253c4250b2210b0905b4737f678a83da40ca296bab3461b58c1274ba0ce79e5562723242ac1cd86839e32e4302e84b42bd118fc4415b71c92e149cdaaf06dd12837a5c03aa41b60178c1518130ac4c7017d78c5afd922e83ac2bcc3c3d94b6d8dc8062cd54649339ec4b75c49704d2e5c86aaf48294d19e4d28c12fe45cc56898c630a252e09e6f718c36c71cf9b38d38a3a9731c4f6f02528107c745277841b29d7b93bbc4b5c860147777f79745ea2296274856915d06944582055b31741f291c66df5c4a2f09351311a6d56a8572aa6240a42be432a5e4d98cf229195ee0a72f6c67cb4a9c48a9932d36cf70164364988270503573e43e2b730d88f94d23315b6848549515104320c26e83206ad5c33ac98c922b6bc0c961ef2607aab223a4fabd82dc7670fc999263991612440d93a2e3eaa8e65961d441a8548762c84754fc4880da92aed2621876294d1c086efbbb52cd252e2f14853f6a2b7d0bc9e1f104b9703a27779733049013da1812257bb8db3857075b665c8e7622ccfa10667de3ba468808fba7b6dda902a1337af7ec59e4aabee16c8017674114dcc2a0571730c14a9d07485648228ff8528c155f6266b79b3c76a8ba2ed133401d6bc56394785089abc368b9d05b4a1165912360bf87fb6ef6f79859f8187151a31437904398c997c30092ca21c43996805245904a0d90ba8658309be2b4306266888f5564b631cb250569aec1886059352bf770e1137f5287058ba78463523c59f14d1846b7e1764aaf2210a58990fed7528bab242ee02949539469122dcff23f921b3a0746b44f64a7aaf81f99954ad88b67567c120b191abde6c7d54aab5ce7bc87960e2ee2618e24746f24c03b153dc988b0d3712c42d20e152533bcb914588a32ffbc2c44b4045f07ab79ea5627045f45b11d62d2a3bbf97e57e8c27439418be800a667bcd35435b6770b8223ace5284371f5b0d8930aa93b8a3889984b8065f408bafd0c5d5df30cd3e5911d9845c9f687980a1609198dde43a52ee970867c0addbc2114d52d91073d6c95156f7c95a40a575ee07228b22bdabb0b16729b2266b13ec29bbc70486e13612270541102baf04a96b24900af60cdaaecaa1af07459f554b53b7806a65465fa8ed5c2bf65d32410caa887a90527b82a9697738cc71a1926478bd4cbd70067a50479058bbaeac05698b1530a1774c0f45001ec718e05053da12f24115acdd76bff98094f8bcb45960e635377077b6d92150221c87b60994bd7732e24c34b55ac1fe660450af46b3397a0c1c577a30b2fe1c263544c025172164f7c5620b5658d34455757c920f229920729264a159b20658a75496c6bb48fa9090d88be51f754988ab5cc774d526a1c27361cf3ab173326886eb0053b082ee9279c27a428d6f7cbf9fbcc15ac4988d13dced43e0045167d33b0aac4c11c383ccd1025bbe1c83bf5c43ab6836328959ce979c3914510027121a00061e12d1d831efa030cddf9aba24754bf556a99f65109832ef12ca41ed9342309c24e7a09cfc93647c6cfbae5cc262764aa64ab49132da03a6e7424c56ba49bcad27affdca4b88584b74c0623224541b82419e563db5b90ab40787f8425e4b38bbc573918224c4d73149bab4dbbe350630229a612bacd4b081ca05eb95a62c50453695a65763461586c8de2934d31093297ea1384d3c2f2f811bc75c960237693652387a13f69629a3fd625351927a9658bd4125c713177959aa82ef3771c03b5bd5805b7d56f00d86fecc7aa29a7637cf3bbea377ee7b9b1f94836197a718b097f510c81594a0e11381f01584a87419f51f49c120b89514754dd85a6be48ad947b81698001f0a256f8a92d09a1a049c0376d236a19f19bcf431a90f94b028475c11807d14c5562e5747f1b8db5b072017023bab895a07415deb89cb3cb8a9115b63216bd69243186901ae32b24402b88bd18cd03b2216d24928eb82e385684bc143e0d5745892b0826f89f9fa8a931596bd912527e2c965ce3344b4621190c106f5084836006296c37949aca196c426f4783b65221b9c50827c85b7067a9872a6d9277828ea9385f9b512a8a3e897628d1aa36a5206b35fb219ae26269126b75590b2d1067419b27fa6852a3552d6ce48c9193c96a3131397166d47c53eebbb68b949a5bc3c7d585027961aab89b38f5295ce7c60d3d9009508769ee37a48de0685b9228d998b883d871985108b49c908390cb68147e8bc561df29cde02b1ed5236ed77b23b3f32e687b859dd63439890d8735640f5c073bc05cda79603cfb37fc5ccd28e98b4eb169271408a1cba57d21afb87c97e2044766b38280b6911b95725d5a77327764832603fe771aed89baa1c8b2ff49b741081884c6326fa0693fe64551402301a0552f49035a262e9d047d8a2075fdf6636c726f8b6098fb2b8f01c89e87478dc1112c37f1b857fb13cec53673e297b8aa9612d26a4cd0c6168c9dea407133acb939d06a7c660581a877f046b9b1138f6fa6156be2a5bfb23d04954fe32b1272d73e39c79094864cc9e36e46e9c8f1db330c17a0ecbb332e385769c4c0ace7c0b0d49fb89503cbc13ff3a1b19f421b80855fcb947cb651ccc0a7b55b5100c09aab9201c4ff8c56a2d90bac255a3665a731d07b8ad829f7a7b556ac12acbc1073a40b7c36059edccd97a50c493359c8ba390e3716921a69998b9b111c4dd283456f7b61ccf97c1dbc362e2760e2928227405e449c126d7526516298f6315302288043085808195ea587118d731543f09479a2adb96884b3a620d4c86123818cf848b295eb0035211bf614b077871db1d8c779d61e90257730e47bba178ac5e28b8e47794517727e4049dc759ed5a69cf7c66de05c0a5a00c366a87f7f2914e1e059bd1921eef61da9cc201f016f1cdabca2d2cd99e1884c114100ec5fd0f415d6fc6222981d8e4582dd138d71a368bd5590645359cf767146f2cf5f7a58e0e1becadcb1da0c87fd385c4ad15e02836d866025d0d815af61b564e803f0f0bda9a1ad0a3b86dd9a79b29792a713c78f00c55668aa2a0962b4a9be8bd9cb6966a054f0ac39182ca4d54fffe197891b964933aa8d60a87ab0af08c139a8e79b7a5773cf189caa615f64b973eb273edefb27be439ddff2a1fdba7f2cc3c65dfb0d0cb177b7ac49ad1b4da0725a3f3a2741fb2c82347dac329657c9bbaeaa948102295c1828b01c22ae45cb0e0b46a68837ca5c8639ab483eec5b4dc9caf028a7bee18accc402ec6aa57a93a1c53a145e923194341bde96296857890fa616d1bca0cadbbba3e4302e55286c58a283ca8d1626515e6a84881aa692c662a3567cc294a23059392887ce7a835f8b8030f5c1060518c71e0c5621812d54d50043b73182fa67de92768c63c4a2c562ac151342fab8fc9181be82301404792a94258b98411ed093a9121699ea13fc822bb5a317b55c1167ac12bd8c3ccd9bc743a634ed6a0961e13ad91a779a242dd0b9b4b41a5da11cbea085032ee2382c4b8ce088524075cdfe7b7c06cb6f2ae128f4f7a6c5d58011b42b8cd39a8a0aaaba14a0ea8c9a72f322693410cac54c3ee5487d726acde02f9cd0b027844ea1c018e2744571c3a2c36b4e0da088f09ab939152e30696cfd3473a085be3eccb53eb406b66c95ef8b1cfcfa1df8c8238b8c129abc9176e0864415852cc8ce13970fe8a76ecfe246800997c56668af974605e748e3054700d7b75fa182278309e41cbe5b4a17696c843fb4ad72471bac747faf30c99d2433665433ef29b64870ae8a3593845ac211ca4af0e5aeb9b8afa5b4419559502e834f993543353835596985e31529c1482d0fcb9c11a1c79a704db1d531bd0774f91b6810b98766a83387387c0682584c94793fa771ab8b4216455f7a117c65e5a481e01b5bd8bd0a9263635815f3c13c7c6740d2d1778ab47d56c9a37ed4a660249b8a4a02cbd716f6a09a646456c4b54cad68c86f8b998855379560692cfa68b5176309162a7a506b28e042c25850a7e6357ebcce387146b94a09fa82ad2cda8123477f926757d552929ea72e379a9bb997bab0d1aeb5f02568e7715d959168129cd58048ab1299eec754b9080e7337084ddc37c4695b75488effdc370edb65655231ef1091d762b8ec53a3283b3f7bb5114429c788a2cbdce1c0454466882448990d0c963c4dc08e6955a7aa5238a6347a0d168a1ab143347ab4c4e4ad5295a60c2d41e0b7a7bc92148855ebedb4f2b77da0c706a1bafd6429d55fe6141a25f7ab9f875f79e0a82d6ea5cde5a017ab637d5fdb7c42646a1d71df" +}, +{ + "dz" : "0e3b30e102d707538c2671060f603bb0b8a014103f132d63b09ece07e4a4c75b11eafeca9e810796c34e8cfce9d59342884456007b01ddd12edce6d10ed87e4c", + "pk" : "d7e9bfebe65e89997ce4e680ce385c8eeb2862175fbdc9b25dc7724f641ca14b1675e13465d634915593a228c35432b316d295dcfcac909b9aaeba2e93f6028be9045610ba38c763c08308a1d6b9b8667b500c649b94cfa703432f8695377462ec6159313a184f7349be26512759a112223af1b12127f5566da94c8bb19765849f9e849a4f235c9df3783627b3e548242fe2cf506ac1fd09cd5067422789ca6bd3ceb0e516a2e88d0406abe03b65b0f064d7600ddc227ca460cc784652fc1168e8ea53f825851a222eab10bb9c8598e6930a2abb627ec5640d4a3c6eeb225561ae19f20eb6d0536ceb93145c7616fcb46c04b2076b9d8a4013a4bc527848a8972b0b6577c50f63194e6357bb2084fae54c592577d6c7a61b79475fe1c43e70980762132806a7d25482ec2a0e19778aec2685ac19490c303cbee96e2992b836305b58270553d07184507b12c06510437b5c78b3f5cb1b57627da57611dd3361772a213e033dd5519666d18bccb13b3f751901d601ae131ff3c061af87839692967cb88199f1770ad0ae196388ed6b9746fc6e536443afe04a3b92352acc4ea04173d00ab9e3eb9c1cc137b2d6b14fe36dff9591b5300853a349dc23799d8209e811965ac84090f34d36382020ba31531a0dc909b9ed725ef6120929228f48a94a5e04d03314993fc8b306572a4d5a7063110c051011c1b09ee2d09315196f09192c329565cc5a64405c3acdc234acbc0a78e81b3c9523c43a2fb961873eb207464a302d8349ab50167ca33cde091be57801b6e850dda6c5baf498ce1897b247bc7e1a84c6b141fb00286fe864a9f27db6475ed24371cf0c19586750cf72ac1cab46ce08860090a0c1322aba42cd902b6c05f4c4bab667b54b0d5a04332335731544675f80a2ade66dbc075d7a9b4ed924417677b6e195b902842fbd4390597c28a1504e161175d259ae7c44333e742471b58756c0666900cb94d87f73043e940a5733f89ae3e8cf037b83a51b4768a19dd1a96729216c7e317bcbf60b3b07cd82784d964754a440ce297b40e3f8811834885ae76a9605a249958f02d9bf2ef0a195d3603261560593a636b15dddc681ab9bb19ab7ae95d32ea474388d81585e49b463b47033f81964481f46c229f751a930f6a632e8aba8981cca880511164b8f09a8bd9ab8c07bc8a28636d0d32bed77b2cd032b18090928f01e192943e028af329b4b812238a3362b5e2a61cd7b3691d06148703d692080a6c755c560490cd5b47606ac9cd9bdb927b6e3b26d9060921757a0f85a2f82b618bba9008b7073f24a88fdfa922eacbd6631c32157b36150be06d3ce2c4b64410543ccf280143c1de73917b816c86b1a04204a8f3fd7cadbd20b41831c8229788aba219ba59af78388c2b9865eb3000089c6c05c850e91021a5328149cb2a1a27e075a3ec8630d8f515cb77903fb5531f6e05ce984296669b0bfe8af8ae59438b834d4110ba0606ee426799c313233ca9487ea35071871420c6825889c07da0f87f1188d75650e36ad21a265d4b44c01361c0653b55f409ff3c290d2c2c212319297d5aef2bb87164b7535b7518ca14469fabee91c81384025f6914c19018a0775598ad4bbada98e06c87c9af309c73903ae1b84fa9a3c3f668042883a8195cea1fa5bdca59c203178eeb18041aa2e9af770d180be044bab1c8c36044a70e50281540501ad6b165c021e53b86a5f368728e2aeed1520a09a48c1ea0e9419b313d7c6a9e59f17121c8ad47410abb73e008c1ecc16c32b4a46f39712648cd06196ceb8a076f5c7048a3aad37393973b8679c55393137e6b6ba2dea4d50f65e1ef12116598de49260112055f4b0acda503395e242b990398943c18c01cdca993b3c9a74e19ac6768581ccc9a0331c005ce873b241b3e5e497493ab134e18569e80a6d12a04616911f9072fae6a30e529cea1bbdbaecc7cc64a7d655a730335e8a22b4f4250e2c54976c69a161694aba04456bc14e2bf8c13b1ba2a5ac1a6b557bb061805c903d1d1aa3367922fe0c51dbc35da6cc8593b8b3cdf741220126eea9cc5b9c0632f75c7aa3aad60a46afca4a6d166f2b2ac858c2a572e4cdc2d65bca199cd73367b83909fb324855c4899d920a32b3107ec56789d63c25036c35d30be5d28d54d725f1eb3f924bb991cc4c5ec2e36585c0133b82099b8234cb459a9fd8aca37c4249a3b020", + "sk" : "27cb06cadca3f6235b6b59c5a5e7499e95130ab431fc7c4744d1ad414393f5acbd04d15b23c8867dd88ae7cccff7a03122b44de4a4beccc2251744c517f116b413a18d614d5bc371df9534eb76b5fcb13485e60304f02425e37a653c76e08072ae9527e449783cfa72fae68c27e4abcd59ab364b49e6045d764581a9738e3f6443229196478ca629b28dfa519400149a1433b716564dc0959956c87e67e8179b46b1b1b4b9b60a52641971fb91372e6550af2c4e1be88e534108c059217b4071493807e3986d182cbe451047fa4021e264ccdfd89c5458085832c7e157676a649e4533a91904ab61e875ba8180d8639c82522a211787b4a490fcd587d93a7ce8e08dd0094fdff708bf23c35e1b904ea56ce14a9bc5272ab935a69e36cbb15ac1aea1865b7710aa747570704627aa79a1075d8adc4d008d45926b8b55dc12624b6e66f4ce3502150aa0bfc6125430550d595b6627f9ad22243a12aa70b5597708509f9dd09f5ad23a4a876fb251a46f013f05b1884aab725ff1786a4892542c2c0b23150bd6cc3b25427f4b76365193d008a074715b06e713a4e71e3819776b078390b8042d312715b28f1d44a4d540abfdb9a2b3b7660a7101b31030dabb52a05b7f81a488a5e306156a268fd7396d4394a43534d9c4beb2f91686014ee0d7c103733fda120b62ba668f0955db0c596355091002b4af9929384075d6575938468f95571397f8a2f227b57c8599eac2586b72902c698800c78f4b1b99b7284aac542fee229f32a25312f85469f9bf8b81aac6440d4dd26d38c001f2d625d21577d0ca557016405de603b7f26dc7199b300b120a0c278a1475b266354bdb961f5a54a4e0cd70a05e23d7a59debb4134111906a9f6f5b66704026cf033b98c617fc528b104060b8673083490d6c238ed1c943a217533475b5e7c00c871c81292516763b3936d3b99c680695139e6534335bf499aa6abbe10acaa5a2a75f659baaa1a743d228934a129beb65158a04b52c999612c6a8e602afd532139006f386ad51a618702769ece33229187e0f647027420418d560329abb658aaff3a358c5577115f437f59c06d503b154f380c4512d66364c0ce20b5f0a7563626d9f2620f09208adb71b3d91c94a10c4ec29aaf892b8d0991e7f699bddda9c2cd8b96de4661674b400f780fb60921008ccdc911ce6e29a771cb308e86415f4b641d33bbe0746fca69e2a00015f9932af23772abc68abdc5ddae66e84e3826e3cba0a7234df3868fbaa8b2afc0cac953be2271ca2da5cc674569db62a2bc5c5447966a0553eb3a258dfa05ad763850c0ab1724a01f2e2b4a2f3640398bd0b8bbe8af79adc3ccdebf775f2a545a7e8a8685ca73d4c5bf0d788d6a21fef02c241b34f80752f8860249966ada889927582c0f60642b042b95eda965c8873fe8191967b3acc13457e0708316096cb50b856c35a7c19ac64a85a03f9b81e9a756046b901dc9491947c077a05e5d9986cfc3dcba09d02055cae5a47a6969652b056035453c97571138561e28b3b0d0160da428c9104810ca69c75d15ce66b126a27b96654c6e2a0a463d1cd4775458964be2e5a3bec582e38b64c8bb68776c15bc2919d5e99259a68c5c8e42c37b2b4a6b0351c18a09d2378f04403a04aaa7a6ba6589b63061b0eeb80442ada851bcbb5afa1be84d688b3050647530fcac5af0f8b275f036ab0d354991265fd1190d7f5468fc3578e15723214aba66b855b0b5ba2fb27c8b1b7dd37790a8c77120a6c18797b5a920450f87144872d83e8afec5a72df7a61b50655f5081389225235389bf15444c90c1b332b5395796a185b1f9d816ac1b69fd1457e1ce4b1d7071e1956ae9282645b8458cbb8c3f5711e3064a4d05488104848a846aff4c01445241db51b81549ab00230621c8c699fb13c94679f7f51879bc2676973c7418b6d14d9963426819768631abba1db070321a32c0edc95b35c206272946ff134afa2093efc76b28927a948bc4f1931e1a2cbcce18ce9c93c8b029b13291234e76b00452bb3f7860ed98ca0fa2a01a16735272b09c4c0a0b08904f5654911a937f9237818926c03cdb0a98b167b6434a96fe74796ac233716625927535581516ec3217382e61710991003e81f2e0b8d139821f3bc631edcae24cc4583a8abd7e9bfebe65e89997ce4e680ce385c8eeb2862175fbdc9b25dc7724f641ca14b1675e13465d634915593a228c35432b316d295dcfcac909b9aaeba2e93f6028be9045610ba38c763c08308a1d6b9b8667b500c649b94cfa703432f8695377462ec6159313a184f7349be26512759a112223af1b12127f5566da94c8bb19765849f9e849a4f235c9df3783627b3e548242fe2cf506ac1fd09cd5067422789ca6bd3ceb0e516a2e88d0406abe03b65b0f064d7600ddc227ca460cc784652fc1168e8ea53f825851a222eab10bb9c8598e6930a2abb627ec5640d4a3c6eeb225561ae19f20eb6d0536ceb93145c7616fcb46c04b2076b9d8a4013a4bc527848a8972b0b6577c50f63194e6357bb2084fae54c592577d6c7a61b79475fe1c43e70980762132806a7d25482ec2a0e19778aec2685ac19490c303cbee96e2992b836305b58270553d07184507b12c06510437b5c78b3f5cb1b57627da57611dd3361772a213e033dd5519666d18bccb13b3f751901d601ae131ff3c061af87839692967cb88199f1770ad0ae196388ed6b9746fc6e536443afe04a3b92352acc4ea04173d00ab9e3eb9c1cc137b2d6b14fe36dff9591b5300853a349dc23799d8209e811965ac84090f34d36382020ba31531a0dc909b9ed725ef6120929228f48a94a5e04d03314993fc8b306572a4d5a7063110c051011c1b09ee2d09315196f09192c329565cc5a64405c3acdc234acbc0a78e81b3c9523c43a2fb961873eb207464a302d8349ab50167ca33cde091be57801b6e850dda6c5baf498ce1897b247bc7e1a84c6b141fb00286fe864a9f27db6475ed24371cf0c19586750cf72ac1cab46ce08860090a0c1322aba42cd902b6c05f4c4bab667b54b0d5a04332335731544675f80a2ade66dbc075d7a9b4ed924417677b6e195b902842fbd4390597c28a1504e161175d259ae7c44333e742471b58756c0666900cb94d87f73043e940a5733f89ae3e8cf037b83a51b4768a19dd1a96729216c7e317bcbf60b3b07cd82784d964754a440ce297b40e3f8811834885ae76a9605a249958f02d9bf2ef0a195d3603261560593a636b15dddc681ab9bb19ab7ae95d32ea474388d81585e49b463b47033f81964481f46c229f751a930f6a632e8aba8981cca880511164b8f09a8bd9ab8c07bc8a28636d0d32bed77b2cd032b18090928f01e192943e028af329b4b812238a3362b5e2a61cd7b3691d06148703d692080a6c755c560490cd5b47606ac9cd9bdb927b6e3b26d9060921757a0f85a2f82b618bba9008b7073f24a88fdfa922eacbd6631c32157b36150be06d3ce2c4b64410543ccf280143c1de73917b816c86b1a04204a8f3fd7cadbd20b41831c8229788aba219ba59af78388c2b9865eb3000089c6c05c850e91021a5328149cb2a1a27e075a3ec8630d8f515cb77903fb5531f6e05ce984296669b0bfe8af8ae59438b834d4110ba0606ee426799c313233ca9487ea35071871420c6825889c07da0f87f1188d75650e36ad21a265d4b44c01361c0653b55f409ff3c290d2c2c212319297d5aef2bb87164b7535b7518ca14469fabee91c81384025f6914c19018a0775598ad4bbada98e06c87c9af309c73903ae1b84fa9a3c3f668042883a8195cea1fa5bdca59c203178eeb18041aa2e9af770d180be044bab1c8c36044a70e50281540501ad6b165c021e53b86a5f368728e2aeed1520a09a48c1ea0e9419b313d7c6a9e59f17121c8ad47410abb73e008c1ecc16c32b4a46f39712648cd06196ceb8a076f5c7048a3aad37393973b8679c55393137e6b6ba2dea4d50f65e1ef12116598de49260112055f4b0acda503395e242b990398943c18c01cdca993b3c9a74e19ac6768581ccc9a0331c005ce873b241b3e5e497493ab134e18569e80a6d12a04616911f9072fae6a30e529cea1bbdbaecc7cc64a7d655a730335e8a22b4f4250e2c54976c69a161694aba04456bc14e2bf8c13b1ba2a5ac1a6b557bb061805c903d1d1aa3367922fe0c51dbc35da6cc8593b8b3cdf741220126eea9cc5b9c0632f75c7aa3aad60a46afca4a6d166f2b2ac858c2a572e4cdc2d65bca199cd73367b83909fb324855c4899d920a32b3107ec56789d63c25036c35d30be5d28d54d725f1eb3f924bb991cc4c5ec2e36585c0133b82099b8234cb459a9fd8aca37c4249a3b02025a466c0b64a911e75243db16841847a8ac72dd835486e96a168b2f9fec46f3011eafeca9e810796c34e8cfce9d59342884456007b01ddd12edce6d10ed87e4c" +}, +{ + "dz" : "2478f7d3de6041e7e5cd11c5e2ef483d1aa6218eb126444091535f6ae532fa7311136e2681df2ef881b51a092a9badbe72c9772c169808521c47149578621e28", + "pk" : "27c546b8f148cfc133aa807fd7c233c7b5a5c3f6b8da210ef7dc5c1a834fd1559cb2439406895223991a4e682554c63ac3a117d840aa4848b1b3864edac960c656046e3bc6d3b681e1e6b49bb0259f1aa2a4329b2598b932e26c00fdae2cf4686803ca7af8bf0f1243e64544d51794583349f9854dae778894438805793b085373d09a185cda5489d74274eb7bfee433b63a56e14b95941440924cad32935440b46235a8576d11b8d65a2e8198b64b510fc1f942bd9b0f8e077fe33c559cd987615263e9b66c38c5683893c3e10965f18aa755e1bea6d1789913cf2cb21b41b23c4eecab25798ad13a26321c59e35b0517a78743c4469a4435970bbc2b9c15498b1f17cb0fccb446f67c2f437415abe98cdeb3346413539961b3dfc1c40e243296695f27152b7f7a32ff4b185ea437b275c6f617523ada8f7d2a594e277b9318019abc0051aa399642cc0a478ac7466e0729848a516c9e86bc8ad85be985b395e3b28ad89f71e3b584d857bbc1915a47a2fdaab586b7916d9a87a56235db0c683b9bbd5f000e6a218e54464043ea1e882bb906c917cd4449fdd5acadf5b017983c87b4a8b0fc9ded7a1e2e7ba359240009b06701b5cb29fa3b9250715ea31bd8784dd1d91d26764f32b9a49f934c8cf61b4d4a8f36f81d3ee33023959427d889e4a3c796d284a1fb0895184ba4351034a0280f34af119004e9b06fb1e69050fa2db039a9abc6ab00484b9a2694980197b69b9730da0b8455bf591b2eb4f9cef37a06e7c107bd56c3f7ab10ebdbc60de87bdc8c22f62c2e4db973140c5fff95631839264aabac5dd4873e44b8b2f7106c083dfff8b6403322f467a91e52cdd359293540a45134b97a39aefb6252c9c928adcb231eac0d790422a9e3bda366762e2514758badb2a2114a9ac924553d42e05d3769350e4ca047d4219f1b6fa953b60cc67b07a71dda85649af0076ec5c55ef46e73ab06613a84b2422c1bf039564a6873a9385fb18c4ab92ca7a1b205e8ad57728ccaa10b13268ca519c2a0da39be15918bc724f7760e826ab9d47cc288918b60aa87e037a60809b230562ce18c1d76bc457107c8bf80574a2cbd0f945c59d4371af14737983fc089a425d1ae74993451055ec21435a8114060baa6d774bb6ca82efec1a40df1877011163108a2b20190135900a98a337192088d8c66e9e774b02c6d55819dafd9bf3ca886d39165d1c4cf29b1abd6b185dee9671eb941ac598e1b0240d92ca7bfa119cca15a643ac29b30afeddba1acacca8b83a123102ff20b1bb94ccc16fbaefaea4fbaa36f3d46b7f5706a7ef60e04125228900261271c9ab11b04971ca5315e6f3c9eac795687da91eec532476bc66b2ba7a5650eeee119ea13c91bd94b19c31fdbd80842d25dbff62f928550b1f6183ab64443e6b0d9653c5379158af74a6436ce3a1150ea31367aacc7558c201124573235a5997773064a621869707ac661a29238421c9ce88cc38e733c75539443613d8d81c60da70e46035b343577a1660e08a67849558901d539ed84cadaecce4da36c4b9940e106011b872d1b9748cb08c2e3db4880638767bb67c74311021b6c46698a21aba391c65b9aab238d93a4ba80be911c3ba8319bc866cac3e67fee11b773ebbbb8639891809d555258dc9445fcd815af355ce2cb38552c5be069b6c7d0ba83f8495f1230f50bb57a8c4d82ea8912608cef0ca6cfe408052b736d9c6fbca2ca08e76300d150dba48080421c5a6b13f74b8f705b4eccf9c1a336a0e7a47263d30b5d1675df4a2abec7522868ba4c6139a8d22c23608c40a8bb5e8c65661b94e008ba442b9dd9883e8953029d7c4e7b46206880b48214a84cea0b34560f29054756f427d185241d946efbda04956a3972f974be20be202314d9c58dfa3543acf894d65b6f22047032e408636440024452f6c2cbb5d698730907c3271774da95b09421e499b17f670caf8585e2330394302aac52b0c1d2b2ad16656cb79257b143f555757b989c79a49730354e42299f28a166ece2a03e1a6dea08b01b9323d9958d9e320f3055c9500625b731bef77c3f30fb2960974815243f7edba28b64a58bf5afebd76b53675dbfa62b05b89f85f945c00b3de4f8ad2507121bab1a86224a9db9afe8c26513219ccc9b19156268d159097ad048f7fc245fcb93edce592a8d415d4a38502632973ed98b6f97f986dbff7e", + "sk" : "0be83a886381009553ee02aa62b113ea829ae09b3cf11b62d21091f1115cf548388e71abb52315ca69a4d1d601a192a4e7b494b1d3127630cec313c15c9cbc91693375a1776b51a08b56b31f38783af9c052b34b7c0cbaa4eac4618aca24dbc843322fbc666f07272a587c5c54b778aa446b349b88f2416557aa2bb9e3bc74979f3cd287645435d2ab30abf0b6e094446e95536dfb0cbafaa2e87706738b192ef721edb12d6d9a3dc366214e9752a4e8b0ac3ca5a69944ff0aa86eeaab62ca34b8fc7d74bc6eaec56612267724a038a47982fd6ab6cc726ea0e096529476329843ebe484fb7263b4e97fc2f68eb89a65ab8750ce193d9f3176bd876b69f9a826a64dac2186af796eed9469aa79660c295121367906478940099e51bc36ab67a72558425e153821ec43a560558d59b136255f655c161d729d7c21ca29a70b7bfb1b5ba66c0922947dca55d854863203064b52896e3a412a9a5afef93fda7601adc46fdc3a1d25660df46437debccbcfdc78a0d90234f0073b496d5b586a9f8b36988b33ec82c8782ab744b3355fc934544b656ed93eaa36734cb40217d680ea85476fa98d3a50c86b4a2589e85249b9a7ad01aa4afa2df396c5fda43753501bb2b614acb5bc715a113c382b6667457bc30e79e58b41b7511e011965820f2fd6c5280caa7a35c13eba57654501d6c326eda25b7a96ad0236c663d70f9b46cc798cb2a4d335f6c68181c49d669946673741285626b078401928c466c1c51922c4a62553141a86e4082f661198b07539a47283aea18c0cda348375201473a8d3f211b1770ac0dab8252468303b909d078524f10bc3d4958f7037f830b96c64c7f3a89586e3254ac823f8a4911a878c9394006429152b7260bccc60d4604d1226a87cf434e39158db5557c887207f1aa4bc9b3fbe8721dd4c96e294c2b581c78ab3997e740a86707888b6929db848ee38bfb6411110d1b5dca49dc4109f62762126d9a7d2e46400755513eca554665556d3ad2c047f011076e4fab77579c3f9f515500c7ec9747ee5b56f840994d2eb91d13c523cbcb506f011e250c23ce4243795b4e83a8f4f32308007610e23c64f38aab3aa9ac0c303edc77442a2a29ba6bfb46343e32c549d043371ab941c5982feaa30334531f61877e1515449690dc4c6a94de7cb3739c43a53a89f41ac39f0ab90622d41b48f69567c9ba5c128041426cc367ab02ec5c3b082936ded118a50c7933de5a5fb51a07f04ae11012123857bcef60e5e70a51e109382d17fb1d461a157c6b10b7eee63af1bf40626a61c2f94af7c93041676705fec9db5670777a462de3659a20ca8ec41060168c06fe925cf294cd2175e7591600492018ed70cda9266a7772103fa43c48129a1235ab1348bc5b2960140a460531ace8c01e6c136d69751f623c29bc0cad760743cc04011782790115bce926202575fddb867ddea380852b2420a7555994f91525d4a5ab5291983d87abc22407325618b04a42f8f11b203a33353245f06432778c2b3e9f08e2f9234777b00493364ee48cd5c256f15d62e03a52e5d52a849d042a84239d64a08f86a7a20334c77e332d7f886620461f0c0a86292c15180903990a68ce02d4dda33f8d34cf003a4ae80a160a27edbbb300b693f01a151d1363cc247b41c66b3eae25bdc76609d2bcc5f429540543d1db01c801137a99b1df325b88225bdf5d802c84771df545f806a0fa8f85779f56319e25d262b37f952b7bc962911822ab4f98bd65c9720208f6b0953b1d62e51937997b480497cc656341b2fea7b812c3db311784c6a17790321c1cc5021543ad7d54946d71d57c2a517b1187054725e7040cc4506de0208513366c014116fa4444bc06cf5e22e50a993ddf89f19aa14937443ce2676fa817ede4928f81394cf82b9bf629f8d33b7ec0c6b3a35c6adf0ce6480bd837655c2297833a8c150d45610a011b57224ce3b5b47e8b2895c95c24745d1e44b0cf26eee771f906089c0c864dff15da9e6c53c62371de9875030c534daa8be4719fb8a1dbdd2aa12617e4dd3b9e7c40906817398a42dbe3384fc4a4cadc098647ba4c0035774aa1d9fb85cd6d9695088271431818980ad32e4c493ea358f863853e2ae8be6ba9c978fe45b379f90aadc4b59a4c92cfe8288a3073f31f21927c546b8f148cfc133aa807fd7c233c7b5a5c3f6b8da210ef7dc5c1a834fd1559cb2439406895223991a4e682554c63ac3a117d840aa4848b1b3864edac960c656046e3bc6d3b681e1e6b49bb0259f1aa2a4329b2598b932e26c00fdae2cf4686803ca7af8bf0f1243e64544d51794583349f9854dae778894438805793b085373d09a185cda5489d74274eb7bfee433b63a56e14b95941440924cad32935440b46235a8576d11b8d65a2e8198b64b510fc1f942bd9b0f8e077fe33c559cd987615263e9b66c38c5683893c3e10965f18aa755e1bea6d1789913cf2cb21b41b23c4eecab25798ad13a26321c59e35b0517a78743c4469a4435970bbc2b9c15498b1f17cb0fccb446f67c2f437415abe98cdeb3346413539961b3dfc1c40e243296695f27152b7f7a32ff4b185ea437b275c6f617523ada8f7d2a594e277b9318019abc0051aa399642cc0a478ac7466e0729848a516c9e86bc8ad85be985b395e3b28ad89f71e3b584d857bbc1915a47a2fdaab586b7916d9a87a56235db0c683b9bbd5f000e6a218e54464043ea1e882bb906c917cd4449fdd5acadf5b017983c87b4a8b0fc9ded7a1e2e7ba359240009b06701b5cb29fa3b9250715ea31bd8784dd1d91d26764f32b9a49f934c8cf61b4d4a8f36f81d3ee33023959427d889e4a3c796d284a1fb0895184ba4351034a0280f34af119004e9b06fb1e69050fa2db039a9abc6ab00484b9a2694980197b69b9730da0b8455bf591b2eb4f9cef37a06e7c107bd56c3f7ab10ebdbc60de87bdc8c22f62c2e4db973140c5fff95631839264aabac5dd4873e44b8b2f7106c083dfff8b6403322f467a91e52cdd359293540a45134b97a39aefb6252c9c928adcb231eac0d790422a9e3bda366762e2514758badb2a2114a9ac924553d42e05d3769350e4ca047d4219f1b6fa953b60cc67b07a71dda85649af0076ec5c55ef46e73ab06613a84b2422c1bf039564a6873a9385fb18c4ab92ca7a1b205e8ad57728ccaa10b13268ca519c2a0da39be15918bc724f7760e826ab9d47cc288918b60aa87e037a60809b230562ce18c1d76bc457107c8bf80574a2cbd0f945c59d4371af14737983fc089a425d1ae74993451055ec21435a8114060baa6d774bb6ca82efec1a40df1877011163108a2b20190135900a98a337192088d8c66e9e774b02c6d55819dafd9bf3ca886d39165d1c4cf29b1abd6b185dee9671eb941ac598e1b0240d92ca7bfa119cca15a643ac29b30afeddba1acacca8b83a123102ff20b1bb94ccc16fbaefaea4fbaa36f3d46b7f5706a7ef60e04125228900261271c9ab11b04971ca5315e6f3c9eac795687da91eec532476bc66b2ba7a5650eeee119ea13c91bd94b19c31fdbd80842d25dbff62f928550b1f6183ab64443e6b0d9653c5379158af74a6436ce3a1150ea31367aacc7558c201124573235a5997773064a621869707ac661a29238421c9ce88cc38e733c75539443613d8d81c60da70e46035b343577a1660e08a67849558901d539ed84cadaecce4da36c4b9940e106011b872d1b9748cb08c2e3db4880638767bb67c74311021b6c46698a21aba391c65b9aab238d93a4ba80be911c3ba8319bc866cac3e67fee11b773ebbbb8639891809d555258dc9445fcd815af355ce2cb38552c5be069b6c7d0ba83f8495f1230f50bb57a8c4d82ea8912608cef0ca6cfe408052b736d9c6fbca2ca08e76300d150dba48080421c5a6b13f74b8f705b4eccf9c1a336a0e7a47263d30b5d1675df4a2abec7522868ba4c6139a8d22c23608c40a8bb5e8c65661b94e008ba442b9dd9883e8953029d7c4e7b46206880b48214a84cea0b34560f29054756f427d185241d946efbda04956a3972f974be20be202314d9c58dfa3543acf894d65b6f22047032e408636440024452f6c2cbb5d698730907c3271774da95b09421e499b17f670caf8585e2330394302aac52b0c1d2b2ad16656cb79257b143f555757b989c79a49730354e42299f28a166ece2a03e1a6dea08b01b9323d9958d9e320f3055c9500625b731bef77c3f30fb2960974815243f7edba28b64a58bf5afebd76b53675dbfa62b05b89f85f945c00b3de4f8ad2507121bab1a86224a9db9afe8c26513219ccc9b19156268d159097ad048f7fc245fcb93edce592a8d415d4a38502632973ed98b6f97f986dbff7e53ac28332ea3f161cf5dbc077e44f725b05ff0ac4abf95f60c5713aef1bfef4d11136e2681df2ef881b51a092a9badbe72c9772c169808521c47149578621e28" +}, +{ + "dz" : "9d405d3ebdaf35fa8722de431b669722acaaea2fd10b814310b17f78b66147d16ceb14f7662be0c42779459f69a145c0e2ce9f0bd9a0cd1bf32ed5694cc9ae32", + "pk" : "98c5377fa74b86746684a02b2cc8694852594b62cc0dec3c240c49b1cba8235b2b7220cca57aa380ca7f6ff96688b70299a0a52e34805ada0144632ceb704b0f08a3ad9c78dea9a9f1f556bb830cb0345ab9f2503342aee2944879ac0103caa1cfb1932062a04cf473ff372d72d500574660435b756a99635a9626f9f085faa880f8c332f674a76ab0196a3326b0e88ac19547b6e8a4cce3a3a60a9590d524e61501a41262cc67a3cf036e08e947e11c33d34895a2d4b7ed348ea8329f8e8775453a65ec242ddc6b33e6374acd4064cd8c765bb3079550c05e0054dc11b4032b33c4e9371630aff59986b95b7c729402d61c7ca3bccbadba94ecb5151bc60330379e24eb3fc36358cb83c55f18789c37c541e93b3b781d42904ed910aba5f6a4168336dc351aee66761cd17617db2962547d77fa238bc415a6f441c0f50fc2cc88dcc7049fc58c3bf3a3091458278087ab81569b607c66c6b6e4f677b4e0c3b4188dc3d3741ecb585ca68a72d0b18f18739e0194448a1da0d436f2a71fd08218283c416a0a580588932fab5903c289bce9a1b53328c70bb943660ce98773ad14a51783486268c270808cddf713160068cc8c8682ba11d4a21a3408b181625bca33491522949fe6a3ae6a2f046619114a0318fc69a3d58bc048c45ed4ac3a610ad1987629b2bd66200bc0e7b083b1b26cca00f576a2d2b8ad3c5212d956a5ee0985cc4023e9a99031f3a903934f2ec24e2ca46f06a26efc2a19fd28236e9097420337ddd61bc2b7c15fe9949acc7c279708a7365ca87b72b635aea5d67541853530f66be8da1730815852cb3c62024be50288c7ab08a3a2c442307667c8bdcbd940c0a6b91ee1657be599f13722f1d21848d189b8b389741a5ec86560f1b862eb63669753558190516964c610696e9b24a955d07bf388ca0cc4bd0861b388e5a9f1c78014da35ca594f9f1b766494b7ab4377eae61bfd8cbb5e775a4e627e2dc80c17128bb5c314be217033668c29198ce8bb27bebc79b1b4c5fd81578eb32709ac6badc3cfb7c414584bc3a38ba2ca1c9eeca55db9bc295791ba22ab54f9d22cadbc83efb58e243517abd4a93a11bd083950ec71536bc49b39c53d17b8a301a17ec0b90188c800cf2400312b76fd85a26557022909866f5591eb8017440364868c459f9039ff053e6e829ac73b2aeb81c9dfa78703c7af8efc6ee88c929183351f752a47e608638c7016026a031c289b936e06f46889e827a1e0c99ec431c763ae80e72b8e8cb87c3b7b74159596a9cc5a6c67253738e6889f5259a0ec87555e975ee50c82cd44428182827faa7b81a0abcd009a05685813e3000f9623e1c4536443811c98148fab9c8941163a57b8c7377d55a994d6ca310ad58012f51f94bcc9fae366a0591adb9a7a78e78478d1076d65c8f029867d69be153cc7f7b7c3f7f6b5f1832bea256f3f9b7f1165978eca35728115a115500677c1bd232fdf7145ed07810ea4651985a3ad7b5edb37bc21e33115d4c8c8b5094419780831c65b88a7d934bef0b9a52ca4299adb84a6d9053eb4999a92c92b353d9823896d3759c3daa69879782785017747c102e7afc0a330ae96bc2e7a4e6c4b5a637b2d85ebafc4e6c4cc676f78e29e6eb5b8a4bb942a797d78cc708ad3cd2f04217f18bb3677318d3a917db689599c009d3897d95b586e899e5855253cf54974ec4f6fe8be5a4c6804c99dbcd7c3e7407fa99b90a5586e9f180aa559a81978adba7b770a4c601980ad940ccd42eb70010254848b8c4a2886a1d835abcb9097253e2fb817425525cbd37c1b8b3a2ef47e8a15147a6a441be37e7b2579e5f74641c4731ccbaee47b1f5bd744a15284239179a70a70bb8217b1371f928b275e14c83554788687ace377888321c87eb5403cf3c93cd4c9e302b63533591d96af9aa5c47353c03171caee118bd868a6fe29575f5881c5a5bc7f67a2dd5457efd71329473364d509b02914d543843cc3b36e213e27facd6f0369f165adcbb314f9c4c8930564b9f5aaf21c82860035e9f729dfd30584b8cd6735aafff819f9d244cf8bcf9ec15770903a3cfbbfaa385cb960692923b88364100ff67a2dca71154700e0594dfd66ae557ccc6ff36519a2252adba29881b7dd1283d3b621b40acdb3bc22fae51c5a64488a3993ab8fdefb1682784edd39f0fd80883fa378cde6eff656f57119177c56a9", + "sk" : "974b92e8755220ba2f34234c9c59c29de41c7b9967d54334aa259f05a73e43285e4a6ab005a36528153c5599b79fb680f2d82559b68bd3a46b159c3f2e28c960d6cbf8c103aa205fdd885bcbe2c48723b789766038678d15f72ecb96afbd340d4a17ad153a8f31a1c6b0f8291f6b5a1a4979197ba6cad90c26e25f6424cd1e856c0fb5ac336a01c7e5c472c575ae15a5264263d3f82c11a8111ad7a88d536884c664c4a52d4adb85f1a3567f48cfe068c038f5c10813a99ec6c605920cd481a6d6e0ba5409a65c6168f3d5a34e3b1fffd16bc5522d7861441300c550022ef3235c85f5a1fdb6b7c4742a42351e957666a66aa918d959a4f10d24533abb63196f44426f19302b3c0651779c690ca0a108710f4a8fa001a25f6619a49768416886c5d34dc8ec3eb4a89824e04e67cbc87dcc392d64004b5386f40796c71c017e133cd7853f2955289d7a52d7388dffa436ad1363c03902b15128285341217a0832f094bc37733826c13c0886e123a490741ee0859923ec825d26aa4a3ba5c094728f83956596a14f12b4b0958fe01bca0cf557265a5b5f367917d3841e3c16b1dba445038cb95542f7276f906136e7f76c32ea23d78183acc4bbd4067e08e3379ca47c2f37a4aeb1b2c4e4023b8b241993bfce492ab7fb26950b4ac8c5bb1f7bc209957d72a2a87d0b37e0d74c08268bd81822d4272f6048997e9449579b4f972bbbdf1a2083f49996725c68693eacd63d98f3bae3fba88dac46eba99ed324c5ba3523c5398df6035dfdb82e48a49acc15b823d51d812cafa9ea7041bb1d6b848cc4c1cb0bc67ef6a7a6d9b013f3356f353b1dc5c5934fe483099300a800c82d7513d8286e64d5b87882c03cfb1c981b2613d5981f92026f46403286136fe40272841eae68c34e56363226cfaf0c7fb4a64fd094a7cb3b1b8dfc7bafc2552bf98ec7e8967b46c70e4c0eb649a8f0464612d08b69a72b5a89820f1c1fd8e19a55526f592a79dc1a475d16099ec133b21c973c90160d68cf4ed7282096265df929b43b0b265982b4a78a72317cd603c09f70b622b14c31f52f68a6572d749b60b92bcf4a7f3c539da10c8c3c3c4131ec88485225955b63fe8617703c499f9201bdb583d07cc0077347e28b0275a26cf2e600122b73d8b22bfe17cb4a48183211a4c7a83f8002004dea91bc2863b6b9086dd7a8965795392cbc188739702ca7ee84c85c867fc45431a7579dad1bcdf5162d876499b039571174c44d679a7475a156ea73c14113aa206223e90a63c8b450369a89fa59fb65ac7ec1ce8e830b84a9a330e63f7f494a32867f6a815546d100fec9482771871376ccd5aa649293c57800792275349baba6589327dd883053f59d13695c41ea73c8b832a5521bc234a73bf668c80c7665a9aa98c0560da4a6e9ccb0cd7c77ef39670a731a53a85606911b900866a8d272abf56f31dca4d15c7ad19c8d4bb31d9e545c84687fb50757f54ba51d283dafa480c2aacd8c0206877948e1b8215088ab3c0b019eb42956a00e00e875dd4594175ca709164fea4a0b3f819e4dd57ef4d2016e799e5d645e8a47267bf714c88080d7329a8f075af812b3c7acbfa0dbb477b93b789b76ce445c58b9b977a681e6b22730e35a82851f40649a3231bd7fa1a19ff859ad1b007a30413087c0b98a31c9423753f3c2feec9edcd1cd2fd7a930fc08e811cf49762d792513719b370b7c809de37bbd53879b533fed6295e3318a03cc94c1f81ccb563afbb72bf6643c9a80c333134c8734360dfb4f001b27f58b625cc50e20acabf7e1165d0a22bd96ac403440eb802e5fda4d0653491979b331f0ce326a8365281b18ec83bd33319bb7149c192ebe202c6e2c2ad69313c12bc1c0b56599b90bef70a8e70b60b72570bb49c207524850e8a7b549bc07b660e5d26ea8d94a5d1a59a9c8ab17196000c97f48e2b3f060c8b2236f6cc60f6ee09d019cc631809c91da3ecb2544ca4237f37a20c2a82397e3be1f0cb7af6c693b994c8b811537e9007ce088f0fa4c02203b9e08388b186e3be11093e218c8c3763e9810c9760e26d6c90c6400c349cf22069b86dca993f36a303436166bbac8db1cb9e2a37c155f0f678dab52abeeca048b1813d63b42b2a986ae296e3f027854393dcf47004942ce611b9a82a54098c5377fa74b86746684a02b2cc8694852594b62cc0dec3c240c49b1cba8235b2b7220cca57aa380ca7f6ff96688b70299a0a52e34805ada0144632ceb704b0f08a3ad9c78dea9a9f1f556bb830cb0345ab9f2503342aee2944879ac0103caa1cfb1932062a04cf473ff372d72d500574660435b756a99635a9626f9f085faa880f8c332f674a76ab0196a3326b0e88ac19547b6e8a4cce3a3a60a9590d524e61501a41262cc67a3cf036e08e947e11c33d34895a2d4b7ed348ea8329f8e8775453a65ec242ddc6b33e6374acd4064cd8c765bb3079550c05e0054dc11b4032b33c4e9371630aff59986b95b7c729402d61c7ca3bccbadba94ecb5151bc60330379e24eb3fc36358cb83c55f18789c37c541e93b3b781d42904ed910aba5f6a4168336dc351aee66761cd17617db2962547d77fa238bc415a6f441c0f50fc2cc88dcc7049fc58c3bf3a3091458278087ab81569b607c66c6b6e4f677b4e0c3b4188dc3d3741ecb585ca68a72d0b18f18739e0194448a1da0d436f2a71fd08218283c416a0a580588932fab5903c289bce9a1b53328c70bb943660ce98773ad14a51783486268c270808cddf713160068cc8c8682ba11d4a21a3408b181625bca33491522949fe6a3ae6a2f046619114a0318fc69a3d58bc048c45ed4ac3a610ad1987629b2bd66200bc0e7b083b1b26cca00f576a2d2b8ad3c5212d956a5ee0985cc4023e9a99031f3a903934f2ec24e2ca46f06a26efc2a19fd28236e9097420337ddd61bc2b7c15fe9949acc7c279708a7365ca87b72b635aea5d67541853530f66be8da1730815852cb3c62024be50288c7ab08a3a2c442307667c8bdcbd940c0a6b91ee1657be599f13722f1d21848d189b8b389741a5ec86560f1b862eb63669753558190516964c610696e9b24a955d07bf388ca0cc4bd0861b388e5a9f1c78014da35ca594f9f1b766494b7ab4377eae61bfd8cbb5e775a4e627e2dc80c17128bb5c314be217033668c29198ce8bb27bebc79b1b4c5fd81578eb32709ac6badc3cfb7c414584bc3a38ba2ca1c9eeca55db9bc295791ba22ab54f9d22cadbc83efb58e243517abd4a93a11bd083950ec71536bc49b39c53d17b8a301a17ec0b90188c800cf2400312b76fd85a26557022909866f5591eb8017440364868c459f9039ff053e6e829ac73b2aeb81c9dfa78703c7af8efc6ee88c929183351f752a47e608638c7016026a031c289b936e06f46889e827a1e0c99ec431c763ae80e72b8e8cb87c3b7b74159596a9cc5a6c67253738e6889f5259a0ec87555e975ee50c82cd44428182827faa7b81a0abcd009a05685813e3000f9623e1c4536443811c98148fab9c8941163a57b8c7377d55a994d6ca310ad58012f51f94bcc9fae366a0591adb9a7a78e78478d1076d65c8f029867d69be153cc7f7b7c3f7f6b5f1832bea256f3f9b7f1165978eca35728115a115500677c1bd232fdf7145ed07810ea4651985a3ad7b5edb37bc21e33115d4c8c8b5094419780831c65b88a7d934bef0b9a52ca4299adb84a6d9053eb4999a92c92b353d9823896d3759c3daa69879782785017747c102e7afc0a330ae96bc2e7a4e6c4b5a637b2d85ebafc4e6c4cc676f78e29e6eb5b8a4bb942a797d78cc708ad3cd2f04217f18bb3677318d3a917db689599c009d3897d95b586e899e5855253cf54974ec4f6fe8be5a4c6804c99dbcd7c3e7407fa99b90a5586e9f180aa559a81978adba7b770a4c601980ad940ccd42eb70010254848b8c4a2886a1d835abcb9097253e2fb817425525cbd37c1b8b3a2ef47e8a15147a6a441be37e7b2579e5f74641c4731ccbaee47b1f5bd744a15284239179a70a70bb8217b1371f928b275e14c83554788687ace377888321c87eb5403cf3c93cd4c9e302b63533591d96af9aa5c47353c03171caee118bd868a6fe29575f5881c5a5bc7f67a2dd5457efd71329473364d509b02914d543843cc3b36e213e27facd6f0369f165adcbb314f9c4c8930564b9f5aaf21c82860035e9f729dfd30584b8cd6735aafff819f9d244cf8bcf9ec15770903a3cfbbfaa385cb960692923b88364100ff67a2dca71154700e0594dfd66ae557ccc6ff36519a2252adba29881b7dd1283d3b621b40acdb3bc22fae51c5a64488a3993ab8fdefb1682784edd39f0fd80883fa378cde6eff656f57119177c56a90b6cae64de81b6f1395296905389da76ca7c5435e1c4b2d93cc5c303d31bc0536ceb14f7662be0c42779459f69a145c0e2ce9f0bd9a0cd1bf32ed5694cc9ae32" +}, +{ + "dz" : "9a86490f0615f3edf789cb0654066e9ee339cc59f968281f3b89213f83c692edfaeb2ef44d2f608621e831187ce79b2d2f4a20f1568bbe76b0d3d5af36111714", + "pk" : "e5bc009432c97a66bea57133df41cd6d6095a69192226c8a1c6a0416dc13bcd39cee2867e991102ab5c7ee37ab23d33e113b3e7766b7c652cd0fe03fdcf38653149139b532ac46b7e80229c2576c44834080b75d9f2490d79a23e6d6cba707458c90c7bb758e3c7049d5868b32e2c50441b280bb1fe7528924181051a9b35c6ac779645e6554b5deb21959754f3a47454837b9512820d04722a884b10e01b5acec05aecc2a778091bdab81f0091ed67a7c7d062085866df21734959206733257294a4c82a7295a739638141aa3821c764891fdbb64dbc6aebb67a8c82caf86f7248afbbce556055405ada63ac9f6423de12447d89746fea494662a69a021733592a0fed82749e73d4c2c9d192c994a535f126700a6c4cee988945353c9e9d2240828bb674bc98f22a298fb6750da5ee76345ee1b2dfda01862d2116e6607d3c251ade46ef82974ebd2a14502684be1cc3eea46cf3c2b3c4c14178a79fb495a44275cfbdb5a23ac7b8a911d7ee2ac0672b997cca5d4442a5d80be02c149c0c333caea0090937df91491f3e03ca3f8c85357001e4b0c1c9a73be64abbd7c68776179d4696fa138834325715e115584c368b720ac8eaa45aa4176e9860200cb56c41143985a6bae63aa16733464acb2cc948a949528bf6a91156a3a6bfb55bbe1980d499543720cfd435289c880ad10a4e990cfa2548f17bab1fa31a45eec41361198daf50f22a271c7f1acb7f70463b9b4c82b71228644b3421325b09de2946b829b31e56b0c95727c762b5b5d078c1bb46ff2596b4db6863987c69b26225bb9595d612a5a464d84b6bc775701fa5559d5c8cb55bb30e2e3bad532125ce9c790774dafacb19f4c9dea8abb25b26a6c6a51e27205b0d2031938a9f1700d353c2997e935461b121149a16f7a133af9a103b34e2d3180516a5421243769eabc81952a407486e2111238d99bee90554c32aa12e774dd9b17a5d98cd68029f1bc8671a9015591cfee86bfb8712a5948b9455caa51074db3771f89e74695524fe030aecf998b6eeb301d865f67b9bf4718476026ab3161c77f677fe77a301f357caefac5e579bbd0b34b51b8b58eb71c44c52dc669b9341670bb653ca363096d691680c95a0086601448c619050486b6c244eacaa0198f77d987c5083853b0b9b5531a716a10e7517484a36e38e465e4c855164b2091c8a23e5b2f220524285c739d8b519f55ab1d6c4505ca6a00f6cb6de0a16e1355c1c8824ea571611b8a3925c4fc64a5de44a2a1bb189d48aafefa13ace52290a615b5b4339008181d428f3d33267cc135a2649eb113c023432132a0b93bf08203b40ef0e6465c1ba8a1fa517c37c3d363b80d25c70248c52010cd995a866c8004eba1ae03e56e4783453e52609d6c84264c836857a24f2955fa955041a44c6157bd2e627124fb102ea2bf87b1ac628a393fe09968d707c0f27105b491e19c34dccc207367ae309cc1a0f0cb0072781c63642823623b2239335a73db76bd449b401cf5636114a22863b50ee32bd4804006f13dd66b44058b43be960e9a3a5adc3437298b05c7b314d3fb9d4c7020b64b6488f70a73811d934bc0a81677d1664bb497949b757b02e074e76c8a2e65410158973e30a2a9b6b034c0baaa22cd62a421bc25c7bfda61d0578c1436b808540cbb608cfcb78c8af6a43188bc26f637ab479a1ce86242766d9daaccd93c13d1885c7c994acb657fab0a75de17037f637076f2099560799520182b8265f9ea8440ba9e07b084efa2a6cb244d7db1a39b10297eda34bdc82bcb6a2ee871bf13c1cb8ee602c0b3818335895e754ebe75476ee1786d4ccb52c7164c33a76a3b3e2b57b170c34d37295d22e2351be21a95b6495432a1a5e8489edabe9b71a4459a4ea08b8dd65c4fbeb66a5058cfe7706d8e09381979b608230c7430879bbbc30a6150af273cc4d52c5f1c43e723a036530eddf0cbbfb6ba091b0861f1c751530ce52c947743a59595c15e529104a892e089b912975c7c598b1de528983b5a66a7a66c459610f63e95a7b1198b4e42710d69ea7a8fc3880c0876da82ce872952120a666aaccd5b1001b6b99877610071249db481117cd69f6a252ccaf1a64b45c84c2004eea971ade4659e3508e7b623fd9658f1ac8789297a8dfb3de7b385d927b522126a05aaf40635372f59af9ed4e64cd55048057d8b30c04fe6c876b8a67009", + "sk" : "b3d43c1965522268cac5210ff79934c1420c14030e9da56e02e26afda97824904fdf2a107a37baef774ca7a87030b1662b97cf678bc3bcf7586d78285bc44a9bbc546a7b1f48491f30f2939c11516ee6cced064d0647950e004cf966045b871093cb8a42b9c903c5802bacc2aab484d35b319a0025c330208913220c2a8033b4152eb39b08fbbd468c754dfb47cdf790a300be561c004047826a03a175c285b5ca718919a119fb80f1f43e6bb00efbd44c1d67c853c118604cbf2b980cf312caf81793558050ffa5bb3643cd86788c6f5734cf652eca45301ea97283f6c52da4adcba71ed4e1acd3499188d555082aa43fac55e8e45bae0c023801133edcb2a5665bfb7829620ba4e21c746ac2c1e46c4000d93af973810a881c1640562426424647752f162d2e65bba6020143ab7fc2486401a30f36e3a81040b4442382608a02c4031cdd6a9569229fee9c87e668a77e9bce352704b8220136f3439c37c05c917eee0578cb2c689a907e2b2544d26444b1f0a11c0c34b2bb0806a072e39c6952e28a08515dfddc80e19413a2a3ae74092d34c2cd71e770deb1cdb1e15a497a0def06b14b6cafd066713f44a77755a7909bb4e90301a995c280982249714a72773493f060f6175a51f61a340022e69125716661d235b5ac124dc381a15fb356dddb3623c53fcefb0865d18c0a4b1f028704d50313dd0bc80f674d563588eab3712a5c4903f27c4a9a3440443c31c2bf51f21fa9e6417a5479c2b5be1a242ff9ab5da06124f7544172456115481e8441aeb7a8a01f218e286b9b52d5618cd0b05fc99a02a24420a359c3a7a09beca408915d4ffbaaa4865f37670f8744548b5bb8ceb9bf1deb799ca06483d521e44b63c9e485bb75c8e32c42247b5fdbc137856cbce035cec6e1323c9a04aa154585f8a9a6c08dccc720a3690d6192ca6e63990a5a9c7ef519808c68819a66394829025543bd3a823f729b98175b5e2576bf557609f50212524691f7b6bbd91a877a0b297c7facf50967059e2fb23caee12093ac230505a4d8d8963cc05277361c371b4a50cc638882b068883de6d69ef590a33a384deff6b618f9199099734e7b9c951b8318030a9cc92496db0e03e738e0a64d1d24afe6274e5e58b364ab1626fb188a91b35eda4156c483830c2f603138a660310cb39dfc490e510b88b5ac4ac9006e6888b33b992b8343c71085ad4311356cd5563e03c75517c99e9bb59188abd8880559d0b8fa290274dc6fa70bc97fc552f4a76b901a212f0364c584717a39a6e66568bbe0a277f9bffe8355072c75d6c4cfc7ec7bb644b8932b41d191a058f2cfda77cb3e876d00ad4b3b80aa7e1b83b031a4e3f891ff747b17782f633324aff6afb58975cbcc0e14fbc9f90584c51b049e6170af720cc36c9acd7002aba933b685b34c665e90a4219d6721a71b79402acb2e53480865b62dc97432d800be255e7565b5f7ba6ca39c6fa443ceb79308ec9c2527a799cc75535082bfb4a5246ef8026ef925dec7164bdba472db7919b17458f83386764b84e83e51e20b41346d424c65b7949a9db6ab79b091f3a980448c0d253c36e9808d586c6e55e669c40bb9633a156733c76aa709b4bc9a877717b5bc4b0cd91ef75c0272119370b8401c815c129836ef785faffb25ec787188f40990f986961c5e785b9e6627913f7b2163408a7f99329314305c0b330bfb0ee5759016b4232e06b627b84f6b51843e34425deb2bb8e10566e91b37a3657c2ca240f57711420094134c9242936c4a76582686db9001635723c63795451537831460d0b4140fc811ca977fa2eb7bab8a597a162336790697ec94ee684dfdf649e327cf61a15f2a6262a3001c5a342ace47b394626439b313f9e21382987ecfa533d09c6a489b2ff84c63c0f5b4c3f8895d2283cd59305ca7248c6b293ae1b4b3071e5cba9058706a1ea9add7fcafa2c50b86ca10e3a951a5fab5a0015ef09901b36b4f4055087a5361ace4a1d2acbcdff1048fe17bd84b6c4dc05bdf4c453d18c6250a8ecb69b3da26cadde7711c0520a59ac94ee57b77a6aa13db76bfc40af90161e3634459b3263ae233178796148b592271408ff06b5ec012f5c082e107510907bb36e330d5c9bdd1245242d724a6d438085a30705662eef25fb465a9aa584ee5bc009432c97a66bea57133df41cd6d6095a69192226c8a1c6a0416dc13bcd39cee2867e991102ab5c7ee37ab23d33e113b3e7766b7c652cd0fe03fdcf38653149139b532ac46b7e80229c2576c44834080b75d9f2490d79a23e6d6cba707458c90c7bb758e3c7049d5868b32e2c50441b280bb1fe7528924181051a9b35c6ac779645e6554b5deb21959754f3a47454837b9512820d04722a884b10e01b5acec05aecc2a778091bdab81f0091ed67a7c7d062085866df21734959206733257294a4c82a7295a739638141aa3821c764891fdbb64dbc6aebb67a8c82caf86f7248afbbce556055405ada63ac9f6423de12447d89746fea494662a69a021733592a0fed82749e73d4c2c9d192c994a535f126700a6c4cee988945353c9e9d2240828bb674bc98f22a298fb6750da5ee76345ee1b2dfda01862d2116e6607d3c251ade46ef82974ebd2a14502684be1cc3eea46cf3c2b3c4c14178a79fb495a44275cfbdb5a23ac7b8a911d7ee2ac0672b997cca5d4442a5d80be02c149c0c333caea0090937df91491f3e03ca3f8c85357001e4b0c1c9a73be64abbd7c68776179d4696fa138834325715e115584c368b720ac8eaa45aa4176e9860200cb56c41143985a6bae63aa16733464acb2cc948a949528bf6a91156a3a6bfb55bbe1980d499543720cfd435289c880ad10a4e990cfa2548f17bab1fa31a45eec41361198daf50f22a271c7f1acb7f70463b9b4c82b71228644b3421325b09de2946b829b31e56b0c95727c762b5b5d078c1bb46ff2596b4db6863987c69b26225bb9595d612a5a464d84b6bc775701fa5559d5c8cb55bb30e2e3bad532125ce9c790774dafacb19f4c9dea8abb25b26a6c6a51e27205b0d2031938a9f1700d353c2997e935461b121149a16f7a133af9a103b34e2d3180516a5421243769eabc81952a407486e2111238d99bee90554c32aa12e774dd9b17a5d98cd68029f1bc8671a9015591cfee86bfb8712a5948b9455caa51074db3771f89e74695524fe030aecf998b6eeb301d865f67b9bf4718476026ab3161c77f677fe77a301f357caefac5e579bbd0b34b51b8b58eb71c44c52dc669b9341670bb653ca363096d691680c95a0086601448c619050486b6c244eacaa0198f77d987c5083853b0b9b5531a716a10e7517484a36e38e465e4c855164b2091c8a23e5b2f220524285c739d8b519f55ab1d6c4505ca6a00f6cb6de0a16e1355c1c8824ea571611b8a3925c4fc64a5de44a2a1bb189d48aafefa13ace52290a615b5b4339008181d428f3d33267cc135a2649eb113c023432132a0b93bf08203b40ef0e6465c1ba8a1fa517c37c3d363b80d25c70248c52010cd995a866c8004eba1ae03e56e4783453e52609d6c84264c836857a24f2955fa955041a44c6157bd2e627124fb102ea2bf87b1ac628a393fe09968d707c0f27105b491e19c34dccc207367ae309cc1a0f0cb0072781c63642823623b2239335a73db76bd449b401cf5636114a22863b50ee32bd4804006f13dd66b44058b43be960e9a3a5adc3437298b05c7b314d3fb9d4c7020b64b6488f70a73811d934bc0a81677d1664bb497949b757b02e074e76c8a2e65410158973e30a2a9b6b034c0baaa22cd62a421bc25c7bfda61d0578c1436b808540cbb608cfcb78c8af6a43188bc26f637ab479a1ce86242766d9daaccd93c13d1885c7c994acb657fab0a75de17037f637076f2099560799520182b8265f9ea8440ba9e07b084efa2a6cb244d7db1a39b10297eda34bdc82bcb6a2ee871bf13c1cb8ee602c0b3818335895e754ebe75476ee1786d4ccb52c7164c33a76a3b3e2b57b170c34d37295d22e2351be21a95b6495432a1a5e8489edabe9b71a4459a4ea08b8dd65c4fbeb66a5058cfe7706d8e09381979b608230c7430879bbbc30a6150af273cc4d52c5f1c43e723a036530eddf0cbbfb6ba091b0861f1c751530ce52c947743a59595c15e529104a892e089b912975c7c598b1de528983b5a66a7a66c459610f63e95a7b1198b4e42710d69ea7a8fc3880c0876da82ce872952120a666aaccd5b1001b6b99877610071249db481117cd69f6a252ccaf1a64b45c84c2004eea971ade4659e3508e7b623fd9658f1ac8789297a8dfb3de7b385d927b522126a05aaf40635372f59af9ed4e64cd55048057d8b30c04fe6c876b8a67009f33aa451c6ad54d556d60210a23da8fb68662c39a1e08d893e1d1e784fb71702faeb2ef44d2f608621e831187ce79b2d2f4a20f1568bbe76b0d3d5af36111714" +}, +{ + "dz" : "6dfd9b575872560c7bdc2732c4a28dac4db04e535eb8e402c3dffd145c09ce47a2985c1c4d203778597947d710dec806e36b0cd949fe460ef141213bfc525e5b", + "pk" : "5e8ca56e95a1b844147c6011e93057b8d35b6d6052ca045cc1d8444c1b603ff211fc67653a03cf7d3930373206d4ac62090712be287eb6404843c5c1208b0b993c028a445be50550e2b5625e3124bc58b256eb0886e74ec7f0c4d082a143139222b80037b61649e1b4f3079c3f12cd9742486de788ac1a987c158f5d20296742af5953617a5608b5b965ce1cc261139655a09936f555ad8882f3d7b823c400fb7056abd05bc4cc18636141a3f0c0688b5cc04455b768be41096eb7676315f808953c8aa95656e4686c89078e36290fb0b01697c56e41a0bdb7c9c6c6ab8f50eaadae889fb9e0a41d757ec6756bb6e690819b95bd02386398817e1c9ad7db807a842e75017f5bc6b46fa6cd1580993c1238aa197931c9b55d333e953420dec916dcb00b657b5c6fb538468a855e830f1afb9eb356098e12226a7a0718919dfee4ce6e275211804079bca97f291355790aeff36f7baa99c79ca6a4fb1979331494407b33cc6fef3663fa018e28d76e49eb1b5fa828fd7aa270f917e143a9a7938bd9a05d9e483a2d7725061a88588c3df6935ed6c411a149c634d0376decc87d2988954671c8e9249f517ea3d939af8a71d505a628958c634221f11ba962aaab9fc91565fb647973633a4946976b379199105eaa8e8721a12ef43325f08fe6e173bac2243ef74f92074d7e96124d70b3327839806876a6d6b982219bbce5499bc56df2b45af9cb67e3eb878d02b881a5ce9ec55b98808c48a2c963d8854f0172083c9bd2f55b15f6ac7ad7156af33fed0a5b6b668d654b602cbc3e3f9b81b3eb3c476b5bab8b6c886528ae4699e3768b51cc7f48ea9304d77cc8a708ed08321e97228ecb97aec4ba224baf4e684fcf62753985c8ea07c86f501433f40c21f6903cc8166a7332c0b6a8a9c121c41c35690413e98a1a0fc672fb1cad48d74044811f5c7363d7b03fafe2a6a3634d850cb4fb505547b72daa710babe7165b50ba090338f6001d8744041b5b3db9dc2bef60c5b73928889975f51548ab72b4b88a85cbe2457810115a9121f72a3d8dd6bd0c0b2476b2bb9e69a7e613a83d820670596353944a26a16115fca33c505a4dbc5c1136ae3a981da1d1a4b2c25ca0d5474916675ec8817a969e78812414053a4d0245d86119e1072c8dca8c211b9bf3c91fee350f2a0a392c4017c5705655f26657c5090206270140bb93718c37918b4ce79918a9356161b00f09a43aea259ff94d0dbc95a6b83eda5326397750c68cc6b498ce974235484aa453334e05c8232dba3dd1a182ba4543b4a944a5220c46d56812e125c06bba360ba7759cca24a1cc02b13ee9fb75ce8459df3c601da31ad552c153f789905a105929a223e3101f32431f346bcec3a128b0a3c3d4290d270b34e643e17bb5d53b6d248455502c71edd01654d028525576e3422bdf69571e9c10cf3c3c30227c89e2ce0c62911e5014b78b0cdabab060579ebf1a517414bbe5343bf33311c0ab1f659b3d30727184ec1aa8f1c3a3db45fbe215aca961fcd8ce98429d381995280ca0e5e78cde55442518476e0b404a2668424719abe71d64083ff8b63f285396f5989dd4aa9332426eece567d8098951e141ec43747c17cd9b1805f9245e0819ae416c61f3c60818ea448d397211e8b97e755494f0403a133abcd0882ab907e55a130528a5ac535ade736081d1cabd62980355cf85f84559ea36d6d3855030c341babcf65a20c9bb67ed4901f8b2617c7b9c8466976da39c6780003b71a74f6a16339082e6a62458835d30f1b32041bf9ed21c65ec59db3044dae0654e743a5e65836a4b9c5d2c9c4de859b1a6755ae7860fa6053de71aca0a61cdaa34eea773867a7ce66654380219c7b756d117a81e1c1f81156c6d5cccfbdb285c831317e5cfb8fc50b673600bb46469bb3c7c6072d87cc3b17bbb65b95e81875548b63e3024a24a329a4bb1404ff862ef10bcbe6a997c847650b5402b888e0d71c900d4a4a4cc429d717d3860a6615869f734244a0b25cd463371b189a243733469bb5dd97cb3e856cdf2ae64fcb519d9be1a75aa8794542f51bd67878e9a1b8f6d70a650b05b6a609ca9f477579264b127230966a289295719158b63931a3c0cb764e4847c9ac8bb91598b905a650a0123c7c0fb939f7e3943a2f3bafa20a221f37dc17933cf5e868b958e4e7cea4cfd021ef0ba63ff7a7250d21513171d5e", + "sk" : "d246b3612b31d8212a89f347bc6411c7f73e78e23a18fa3972a98dcd857165c070dfbbc8f62197e22b40e2021d5bb1384862c61a6380e042b3714695c515c5a984abfedb949f91c0ae23c4eda48a276c9cc9e6911fbb4b20620875127704ebce55db5300ea34a1c76de6a09c7933a1740552762a2d1d0754192019792a068942574037b949830c2121639e630449b1bfcd02970ea8887f4ba1cf278d819b14f9b58be74566846c742ae150a70380fd0ab9ce2557b2349890969af0bba2fa05335c28b2b125806c637ff4b70095f66e41c136ae3b400323cb04909c035b3c6aa4c5676590ab448c0e6aad6f246a6c59938ac3a56afa0e4e23844220741c93507c445a9efc53c7e6298305c5db623d6469c15a4bc597d1af24a532aa935aacba42da1831b8fcc344088b090a1b08031bb2364e2923afa448a6a7a56c45a90181527776a70858631fe304acdbd37036c83f976991ce8aa99c2252b73c6e54ca894301832c129dfa45b59a023ee45229cb8b3e34805b4d4590e857bcba451e9b6c009abb9a92a19b61f2b814325860680934f30847b5895a430b843969b24cb6dd1c66900569088897821aa058c2c814f3b7a0b14893f96fb241029141c90f63954709187186538b36c4c44536503056d740536d8212236925df8c7a5a19ab01c70a5100759ff5b46aa5c78a8833dc48288bb432b2e741d1746f0f81245982395c39ae716bb35eab66551a1f3c59b873487097d8748a285fdd1a6fbb963e3db4207159256f2121ad6216df07628ac607c1faa3e6b158c5b218cae892cf457dfc29acf2e24bc3672d57e014f4143d301a3e00e276f0066178bc08d66cb163157fa534c96d304e489b22ece80509e8437e23b556217c42b64be26a3f9a445dc830746b47c011ba941b118965f52f44d126e5087c81368b42f1b73195cecde34238f2300d909937722f3d2c999daab1b395851db4cdf4152fb699c7794977d819988020836a185f62a57e1ed656166ccf27f50482c517d7d09b65f0af06651fb15052aa65813b3b1bd1c33bdab745d9a2a2d7373e9d6b8445e9a35f17a8e47c79fd768be8f37dbe19a686ec6887d510f8e2181692282557458678c6d8c90cf1208c8470798f4799b5c2c63e0c350b46091b1a40286c7ad955ac7935965d944baf0ba45ad10512c698d4c6a117ba3132e06812d10d13708285948bbaaa728d2b74e612a5a1f3545fa937a11496add908c932849d577b2a7115b4b47e67e543fb36a809d6cc369a1cb3ba357e332b93276b3af902433b81fe546aa47a322b4812d4955bac7365f4e33e767068e5928119baaa867740068351cf70b75e2998b6e77ee1d80409d6b2d97c9732861cd9acc05b1a1faff8a944537eb56b06c3c520365bb405780d12016baf661bce454e6da89507267aa0fcc880078728d12ec0e6b364c60e6d589e50b7371a66caad262b729a0d34b08f0798951be0c7d6798aa99670d9106a186001b93ba137461c0d3b8da691194f0a9ffbda4418bc2e97076b8ae3a4fc700531c502febbbfc766131dd4b00546151ba804ef08998ed9346c596d804473c54ab8d6f64ae654890a54a3ceb9201a74816d086fa121034a6661a20295bdca444b1c64c9b77e235cadb4c08d75b5c02f62401208578442bd44b2615d3869f8526fc6f71a08b4a1e2398b81e86fdf3b89a3453569a66e52d5bbbdd670f173529d30950ab1b9166821e8538effc1495fd0c268baa07e5212fc41385bc0a902d85f5f2093601c77b43bb865559cab77b4e6d89b5a7a0a6d069e5ff839a77603ee4ab29a331c6f9b64aa626755e61648992003a556c210345f33c2300c3504f33fc57c32ec196b1a9a353f04020bb16818136d32737dd4c92f7b4656a83580ff053ad4d6a13ea364431ab1f3d8ac1f510d3fa25d8c33084a10ba42a50943fa22ee420bc7d656492952e157a689c73cf8d45487293b0c8c4245b410848670d66ca54a3a3e016b36fc1227ffcb63b9310b8dd73bfa405b3da64c69a64173c15000f88dcec5007e58bb05a81672e02414612829cb7e25637a77c49d434a44f4874bb4f27b3584cf85b3c73e2b9e0ba2a92b977e9c194584b04c3e8c37d9b7404e77802c05b50b3acce5b46e54c7354087321b4822cab148137459124caa95197546f8b65e8ca56e95a1b844147c6011e93057b8d35b6d6052ca045cc1d8444c1b603ff211fc67653a03cf7d3930373206d4ac62090712be287eb6404843c5c1208b0b993c028a445be50550e2b5625e3124bc58b256eb0886e74ec7f0c4d082a143139222b80037b61649e1b4f3079c3f12cd9742486de788ac1a987c158f5d20296742af5953617a5608b5b965ce1cc261139655a09936f555ad8882f3d7b823c400fb7056abd05bc4cc18636141a3f0c0688b5cc04455b768be41096eb7676315f808953c8aa95656e4686c89078e36290fb0b01697c56e41a0bdb7c9c6c6ab8f50eaadae889fb9e0a41d757ec6756bb6e690819b95bd02386398817e1c9ad7db807a842e75017f5bc6b46fa6cd1580993c1238aa197931c9b55d333e953420dec916dcb00b657b5c6fb538468a855e830f1afb9eb356098e12226a7a0718919dfee4ce6e275211804079bca97f291355790aeff36f7baa99c79ca6a4fb1979331494407b33cc6fef3663fa018e28d76e49eb1b5fa828fd7aa270f917e143a9a7938bd9a05d9e483a2d7725061a88588c3df6935ed6c411a149c634d0376decc87d2988954671c8e9249f517ea3d939af8a71d505a628958c634221f11ba962aaab9fc91565fb647973633a4946976b379199105eaa8e8721a12ef43325f08fe6e173bac2243ef74f92074d7e96124d70b3327839806876a6d6b982219bbce5499bc56df2b45af9cb67e3eb878d02b881a5ce9ec55b98808c48a2c963d8854f0172083c9bd2f55b15f6ac7ad7156af33fed0a5b6b668d654b602cbc3e3f9b81b3eb3c476b5bab8b6c886528ae4699e3768b51cc7f48ea9304d77cc8a708ed08321e97228ecb97aec4ba224baf4e684fcf62753985c8ea07c86f501433f40c21f6903cc8166a7332c0b6a8a9c121c41c35690413e98a1a0fc672fb1cad48d74044811f5c7363d7b03fafe2a6a3634d850cb4fb505547b72daa710babe7165b50ba090338f6001d8744041b5b3db9dc2bef60c5b73928889975f51548ab72b4b88a85cbe2457810115a9121f72a3d8dd6bd0c0b2476b2bb9e69a7e613a83d820670596353944a26a16115fca33c505a4dbc5c1136ae3a981da1d1a4b2c25ca0d5474916675ec8817a969e78812414053a4d0245d86119e1072c8dca8c211b9bf3c91fee350f2a0a392c4017c5705655f26657c5090206270140bb93718c37918b4ce79918a9356161b00f09a43aea259ff94d0dbc95a6b83eda5326397750c68cc6b498ce974235484aa453334e05c8232dba3dd1a182ba4543b4a944a5220c46d56812e125c06bba360ba7759cca24a1cc02b13ee9fb75ce8459df3c601da31ad552c153f789905a105929a223e3101f32431f346bcec3a128b0a3c3d4290d270b34e643e17bb5d53b6d248455502c71edd01654d028525576e3422bdf69571e9c10cf3c3c30227c89e2ce0c62911e5014b78b0cdabab060579ebf1a517414bbe5343bf33311c0ab1f659b3d30727184ec1aa8f1c3a3db45fbe215aca961fcd8ce98429d381995280ca0e5e78cde55442518476e0b404a2668424719abe71d64083ff8b63f285396f5989dd4aa9332426eece567d8098951e141ec43747c17cd9b1805f9245e0819ae416c61f3c60818ea448d397211e8b97e755494f0403a133abcd0882ab907e55a130528a5ac535ade736081d1cabd62980355cf85f84559ea36d6d3855030c341babcf65a20c9bb67ed4901f8b2617c7b9c8466976da39c6780003b71a74f6a16339082e6a62458835d30f1b32041bf9ed21c65ec59db3044dae0654e743a5e65836a4b9c5d2c9c4de859b1a6755ae7860fa6053de71aca0a61cdaa34eea773867a7ce66654380219c7b756d117a81e1c1f81156c6d5cccfbdb285c831317e5cfb8fc50b673600bb46469bb3c7c6072d87cc3b17bbb65b95e81875548b63e3024a24a329a4bb1404ff862ef10bcbe6a997c847650b5402b888e0d71c900d4a4a4cc429d717d3860a6615869f734244a0b25cd463371b189a243733469bb5dd97cb3e856cdf2ae64fcb519d9be1a75aa8794542f51bd67878e9a1b8f6d70a650b05b6a609ca9f477579264b127230966a289295719158b63931a3c0cb764e4847c9ac8bb91598b905a650a0123c7c0fb939f7e3943a2f3bafa20a221f37dc17933cf5e868b958e4e7cea4cfd021ef0ba63ff7a7250d21513171d5ecba1f135207bd2ab61bf7718dc6825848e742ad56f9f8099bd43905ebd9d6ba7a2985c1c4d203778597947d710dec806e36b0cd949fe460ef141213bfc525e5b" +}, +{ + "dz" : "6fca9f4e384d8418075cc064c70730801bdb8249899d456a77130d5beeb3662cce7683f8a03d3cf04e46970ff7d6a12494ae12558346dfc8fd9370bf944a0102", + "pk" : "dffb649aca864c32b4f082ab455c94e6fac7ac1c6c46943e0d4b811e48a80f18a22130589937a1f4e4097dfb8c3342aab55648486701ec3c36ed167dac427c7dd54a6ef844468a481595b933701a2db33235439d702967ac1b77f47391e6700596d52b534b6ef33357322ca6f1c6a6917b1d8d9cc7f83028437c125912b4e8d33db0d00b6d475452f41a5088a9e5d169d1faa564b220c3aba1d6c27a5b87aef7f4afb75442c0565cb78c7b81144aa3c209f9a808d43132c75399293400ef70551b51292ba501fb613998011a35153046787183580e485bbf5b81bb9fc690ecd0cb7449615a0b0134f559b6e1062d9209ca62aa10279e2c7475e48837e70a2ddecc66d1ba5dac35760a5a5de0764136618b78516a0c711c3c4440c1f0117d617cd64b55482c952e7617176443c802c8046012e9b774d0312a68c49c85a44d430984ec510212316d43ecc3d6fbcf9736cd3e712d0d3011b645107a22b9d8f51e8dbc30eba66e98624473880c3378b8bf933d6577cc31d0105e19565f848290059604f9b71b755e123b7401f204356120c769cccc2b1660e03e688a75fb370ca4088b46d955cb24b7073c8540ecb2a537a66980332df62196d8c6e5584b7ba8a4c8739eac585a812aabb33a5f591b428e50c7291415012467d49b232989c34711009806249580a557048dd3dc0d2d6599cd556ac325a5c00b8820f0c9dfd3336bfa5f61d6baa5e26b848b39ca02cc542c1dbe90ad8d355cec4c9f3548868e9052618c86fb729998cb4cd610c8fbd86429621e34d11c4943402c2598b80aa98f395a85a180ad402587111de30cbb41e0c5f6044219d6a243860fa8da94f2fb878c8625b8e8243731aaf5b511fe7b3c34ac3fafc68df6d4be563727f705ad41245fde8048d184337e662aeb85135df92d4c1a3b36f1c984079d50248f88523483cac2dfe959162a79353708d09b399e6534aa88aa5bb3cf3eb59eec6a5c8309c6980bb2e4681bc47b7dc2939ffd5439ec4473606166da1053e9467c50854712490b583ac02a657c61812336b47a5e2912cbfb4a1acc84991116b9cb1497f199ab41b98bb54343d188ae54a269c89c36a61be71898006bb9ec531d6006325a47a13995492f41498790bdae9a9e41c0cef6fc78f8e027380cae57c2372308a1b0c2321f8ba17867a1358c5c13095617c2b276aa3c0b36588a9c62683104db5c94643c69c1330db1fa9a66c107c62567f2898419008b9465355af511afc923415c545ea44f15e7b98dd09ec0d79da5893125d6125aca7adf78a32f918af2a41cc6377c04a627fbb28ad5bb65bcb16e3f32622f45b5600cc367348379894c65f494f79948e6e1941c10afc4cc00ed871e529c8573b36debc7c80364b01ea874f345271517b6c399a6277b80bfc1a9996a3748a0bbba5a24abf84d6a714695202ab7779637f85774c27a51446e72fcb59ee684873ba60315a84988b5936674833a93f06b283c6cc1eca1bbc36a02c8197480c24e17e2316eeb58b81a3f5a063b1dc4b20239818c8aa67fd96cf6ab52017979bd82431c862837a1b796d0744a27559e748db8da63676369795ba92d48bb11f9bfa5393c522403b6379b0d2c82beb17ef29b37fbebb387aa695d54c241d51fc3d5bc7f8316100021fd805d76a601862473ae3996b2840ec274bfc37bbf5119668dd0bb0e909fc2a28f3b3c469a9b279bc4810c040b70781f3d67c584a965a94ac1bc088cd2b61c54f301f5dbb82f110c20d51a6c882cfd3c2ad1e6311fe4041eb6cefd7681e75a72d7b0cf39742394e33328374e5ee5b0fb3b0e2c709365780ed3191e56008280188baba9c745fa5a8958c0ef28c1fb641e4ec13dd77404dcb031ff3b670a2092edf848900818c7104b3e457d4189cac8082b55c55573c2021fd32e4b331eb515092843c323b02228737b2c8915beb2718d63b8020c2b3a957fa5029638846abcda5c3c0cb2aef55d05c38cdc1755328735901ba53d685b939b168b9cc55aa0ae05fcb8815400a9dc36a58a1f4f90b3eda3060a4490751413d9c1453ec8cb64dbb679fc69073c9e839c40e8ba4cac38124c3697528404bcc6435c9c21a5b89cd05516686b4df7da8ed3bbbb9afc428a842a90bc09666804988c7386b794b460105fc5035dc3018dd494d421ae46f978b305738d5f40faa6dd68ee73df57c41f89935528e64270c9759d496204", + "sk" : "ffa253d9738c7f3cc8d3d9645bfa7b3dfcc722170ccf43200ed962315c4a48882756588b0ff85656bc8329c33d81dac016a5b048a25204396268ea3e16b63aff88a6c0b0344fb1afb0f530ff3b2858954ebbe8155c287b3c0244f3ba7aa05c1ba3c7bec8861a15f621d420653a44354415a152b774e31cc0d3ab9b08486ae87a406f17b062b224b75c81d3f1bb1678aecea90a9a950f86ec8fa357984e697d21c82b70a0933dd34e2782189fe64f94325bc3d068f9a56328f6cd0fc93e74462640998cacaaa7d4aa17496c4fa0414f55e2a5601b3651934cb566594027a9ba5a77b2729165a51cd457907a25786d4510a5e281c2dc3ed422a40bd23a36494d4825a32caaaa244685734a543c8c65b6bcc11db390c24c57e3821ca2a229052846fdf155a786cae0c3474c58c4cf6a4fc3f0cb4040a699198fd4f9519fc9533724b9d5a5c76e8c5f38d28f034cce980008645704ad2b5e2f985657047554b389cac253e51a862eba7491aa76517224d7d247eaf35fce78b0ce3c8ef14c901d2122e364449967446437416e052b8fa6671a04a173559f46015fbde16c11657c7f759242ec6950523be14c8e402a1cbf973c91ac94e004c00be513ffd90c179071c5b05fd20a3db6727b90325592fa06b220104988916d558817a734394b1ca7c95f2da093ff211afa8aca0c11bffcdb243e986b34b72d66647d05173ffa621d0a191e6e69cf7dd33c252a8267d50b57babe73cc84972665db7343eddc2926dbbc17f44e80e229ba494743b6201a0693f4081bc6124bc27067f0a566ee95b455f6cf414c6621536f14762ff8b1b36342adaa6c381656bf2fba2d96304f895b6b0beca0e7fc02603671d2a916a2b571cf17b060994c0d296089e3804cd1b76db57d9a23640bccb4adc34ba970b9fe131427538dc80c41b2891c0900b2c16a42018696490c4dd31329577542e0b56778281f05379cebe49f7276ac28cc0082ab23fb983811daa72c940b8ab912aaa41d3ec895d215bd4325268ac137ed7bb97fa09f5c7aaeea47b822ec6761740809a9b58470ae5b970d6bfc37c3092250218bfe248e2358600170b8c0b3444527947ac515211b9b2d65328e13cb33e413847cbad815412ef36c7e7a42a6f097b0193af3bb0c6049becb3051d60a10ba1c6cf4b9cd10583886172fb2527d85ca2714fac6a7352ead8050819bb08ab050b5525e2a093ce296a0dd7a0e79faca7a209e08fcc4366ac22bf63393eb32285a5dfc2198c0f3ae7f389d4283ad23e86a2e7972e6e4b22fcb7c5cf54353500d680288bd004a5fd28a280c09acd35dcd245051545b46598524ab218df38044f52f038281b332b2d6610d7fccb9f25173b48c8a2b18b3dda8c3b0abc4aaf28ff2b4a6abd085b6d8722c9a02ccdb96a0dc90922691f96769e2d9800cf5818b23c2f9030c929c3f11995c68c504c91b753496cf7b3b00e46a78babc61043780ebfb9f037668e3b5039663c8cc291db5f5a4e3352db5079387e5855d74b84045b1ecc7b0371a048f484c658502c344b6bee19e370c78b203260f6732ea55a0479453b4684454588c90e49d0a192f2634004d326292011f1d53b0ae71bb8284379d925fc139b581f402a9280dde30a9f5847fada70582a7af03c71d0a8a3147219f986c329bd60079f38f22e99dac8cbf4ba67ad77b0819334135d00888f476985441de439df0b81673d3274da42aa8851c34ba304b467441405559491662443d51e92f50a056d4fac1ed2357f00503f5280da63c055f923cda36916ba51f35e13cb17476a879bf88b406dce51ca85475b7447c0cd6c46ebb0722a8cf8d8250fbec5bbcb5b9b644238168151ad9ad156c7e0dd1abeda37e8d511a34b447195a897568b0809a02b4207aa8ec12b2ba73d64bb97952328fa1c5c19801cdb237ffa23115a774592c5f644bc60fe3b5b96a1689a90cd1d6abfa9a50bb430ae796364cd99d8e6261820282204a8dc81cccc40b67b82067fbc38faeeb068ab72ecf3a6af5259092b06b2dea6665b7901ffb6c2a243a3d2b4235552935c323aab07769aac9ba0a8c3813c536700ca8323ed662954adc5bf811c4d09434d0046566363775f4965e626346b6bc1b50655de01cc642b7f984c925b11b5442c827dc28a004c38ee59d74cc0dac334bdffb649aca864c32b4f082ab455c94e6fac7ac1c6c46943e0d4b811e48a80f18a22130589937a1f4e4097dfb8c3342aab55648486701ec3c36ed167dac427c7dd54a6ef844468a481595b933701a2db33235439d702967ac1b77f47391e6700596d52b534b6ef33357322ca6f1c6a6917b1d8d9cc7f83028437c125912b4e8d33db0d00b6d475452f41a5088a9e5d169d1faa564b220c3aba1d6c27a5b87aef7f4afb75442c0565cb78c7b81144aa3c209f9a808d43132c75399293400ef70551b51292ba501fb613998011a35153046787183580e485bbf5b81bb9fc690ecd0cb7449615a0b0134f559b6e1062d9209ca62aa10279e2c7475e48837e70a2ddecc66d1ba5dac35760a5a5de0764136618b78516a0c711c3c4440c1f0117d617cd64b55482c952e7617176443c802c8046012e9b774d0312a68c49c85a44d430984ec510212316d43ecc3d6fbcf9736cd3e712d0d3011b645107a22b9d8f51e8dbc30eba66e98624473880c3378b8bf933d6577cc31d0105e19565f848290059604f9b71b755e123b7401f204356120c769cccc2b1660e03e688a75fb370ca4088b46d955cb24b7073c8540ecb2a537a66980332df62196d8c6e5584b7ba8a4c8739eac585a812aabb33a5f591b428e50c7291415012467d49b232989c34711009806249580a557048dd3dc0d2d6599cd556ac325a5c00b8820f0c9dfd3336bfa5f61d6baa5e26b848b39ca02cc542c1dbe90ad8d355cec4c9f3548868e9052618c86fb729998cb4cd610c8fbd86429621e34d11c4943402c2598b80aa98f395a85a180ad402587111de30cbb41e0c5f6044219d6a243860fa8da94f2fb878c8625b8e8243731aaf5b511fe7b3c34ac3fafc68df6d4be563727f705ad41245fde8048d184337e662aeb85135df92d4c1a3b36f1c984079d50248f88523483cac2dfe959162a79353708d09b399e6534aa88aa5bb3cf3eb59eec6a5c8309c6980bb2e4681bc47b7dc2939ffd5439ec4473606166da1053e9467c50854712490b583ac02a657c61812336b47a5e2912cbfb4a1acc84991116b9cb1497f199ab41b98bb54343d188ae54a269c89c36a61be71898006bb9ec531d6006325a47a13995492f41498790bdae9a9e41c0cef6fc78f8e027380cae57c2372308a1b0c2321f8ba17867a1358c5c13095617c2b276aa3c0b36588a9c62683104db5c94643c69c1330db1fa9a66c107c62567f2898419008b9465355af511afc923415c545ea44f15e7b98dd09ec0d79da5893125d6125aca7adf78a32f918af2a41cc6377c04a627fbb28ad5bb65bcb16e3f32622f45b5600cc367348379894c65f494f79948e6e1941c10afc4cc00ed871e529c8573b36debc7c80364b01ea874f345271517b6c399a6277b80bfc1a9996a3748a0bbba5a24abf84d6a714695202ab7779637f85774c27a51446e72fcb59ee684873ba60315a84988b5936674833a93f06b283c6cc1eca1bbc36a02c8197480c24e17e2316eeb58b81a3f5a063b1dc4b20239818c8aa67fd96cf6ab52017979bd82431c862837a1b796d0744a27559e748db8da63676369795ba92d48bb11f9bfa5393c522403b6379b0d2c82beb17ef29b37fbebb387aa695d54c241d51fc3d5bc7f8316100021fd805d76a601862473ae3996b2840ec274bfc37bbf5119668dd0bb0e909fc2a28f3b3c469a9b279bc4810c040b70781f3d67c584a965a94ac1bc088cd2b61c54f301f5dbb82f110c20d51a6c882cfd3c2ad1e6311fe4041eb6cefd7681e75a72d7b0cf39742394e33328374e5ee5b0fb3b0e2c709365780ed3191e56008280188baba9c745fa5a8958c0ef28c1fb641e4ec13dd77404dcb031ff3b670a2092edf848900818c7104b3e457d4189cac8082b55c55573c2021fd32e4b331eb515092843c323b02228737b2c8915beb2718d63b8020c2b3a957fa5029638846abcda5c3c0cb2aef55d05c38cdc1755328735901ba53d685b939b168b9cc55aa0ae05fcb8815400a9dc36a58a1f4f90b3eda3060a4490751413d9c1453ec8cb64dbb679fc69073c9e839c40e8ba4cac38124c3697528404bcc6435c9c21a5b89cd05516686b4df7da8ed3bbbb9afc428a842a90bc09666804988c7386b794b460105fc5035dc3018dd494d421ae46f978b305738d5f40faa6dd68ee73df57c41f89935528e64270c9759d496204f118f77224920bf4ff7c69db5ebe12eacdc6012d57e2ccb3d690db251204dce3ce7683f8a03d3cf04e46970ff7d6a12494ae12558346dfc8fd9370bf944a0102" +}, +{ + "dz" : "e58f71bf175c0550a67e00e0f7b3b7fc36bc2707bf0c93044a492626de36301a7f7054814869cf7625e45647bc1547aff288dbb90699b2ad84893f3b755d9722", + "pk" : "1e4205e8fa992213c49059a409aaa3ac72b85837cddde4c4ac42a9a35ac7fb80ad2d8c1eae7019276b1f3f3a6761602a01d99d4d050c23892427d6267efa092b587a5d2376012cb755627b9e63a2a04432260aa1abb2698ebb6075620ff11b01e4d049de698966fb49bdfab73675586583c744b5bafbe9692b6c6c1448899ab72a8821b52b4bc061910fcc70beaef424afeca7d3737f4c7c6711b38dea919e1a13c78160c1c652a81210c010c48908b13101b04334e6534aa0986ec01a86b30d41cba67e573ab6b0cc1a2c973c0041bd26721b508a667bc28e010265b762a223128e092eb512bb9d6150af6840581514470212d0e5c1f4696e45ab102a91a0848497e8a7a52ef20c85d7067e6a1f99e1c0de84473b735bfb001e860c3194029d5a06484920bb0e371114ab2f3bd775248a9449d2c19de5023876931de00dfd609c95c98c133bcbeeb52c0f713a19176dc90b5143a6876ab45b7f717865d4b8f0b8a2e6a45f123b85c8fb584cd3c042676ead069cf9c23682aaa05c1010e122473907547d79b0f8b61180014b1b3a56b88b3b4fd97eebb21eaab37883889a37676c61061d41b40b49dc5e68f64ed979bbd3da4a7824b32fc0bab9985a94251fcb740bd2b103f9c21c25bb055043c895531e68b17a3cf3190683969d6299c850b7d11a6b7a183b4b3a3daccc41d3321f5c088035102ab68b2938975ff180890153135e284155f971ca624c19f15ae4a3023f20cda6d404406c39cc26ac4df1665a3c19107a99bb289176a09e4a7c197ba72d6131980264a907b605c1e1791305974d49b604c81a9c8501ecd0cdd32a5f94dc3f64481164323736435d1043b09fd1ba63ab6956e4216ce47f719bc10f0c2b2830c17886965188534205c3f8818369aa638d5902cedc28b56c9723aa4eee8485151a270d3c1d963404bc265b912c6e52099df9ea72910674bbb8493f670620645fba16c0e6c73ffa20a99d6378433c6c55ab20f0a40c74ba37ddda39d2ba4d7f34c705a4117c618ad91408ba3bcce9fa9900d2650fb109fe2221f0f6219c226b74e7968f5aa0b3e3575be051446b1b76b8a7785a43c824c73688ce495681fe723d97b249e5a65a961abd0d61527d4b18027b00dfa49f4d213253e80ff2a556c48ace2b6a5122b42c2d15622e158e2613b23e62c6398838aa821cb05a4424817f0f9291f4ccbe6578941070b22b9c36bbe89ecad318e4251451a80202a70e1b2274854809e770677ab76c9e9c5cf4e8621e4338a279169ab46a6e5344ca391b80eb12f9b8a582105380384f2fe845b7298e52803989211498b42537b8b1cd22a59085bc00941f190a66fe77a1a6745e8af09762751c63656a26692bf1870df08cb861abba73b50ac6b03f880844a2c6811a031eb412501c79201e686ae528c84b7606aac09bc42265e77b56fde93022a71374693f9ff5787fa0855c79321d147831ca28e7880dfe1c15c66bbccdb93c0e7113a5eb9b97285ae8717bb87c1f071c284c0089fbb5a7b5121770950d255aabfcf54f1c18c8d9b2bc4aa253d5ba49bd2944a8c440d01343f0770f690743dd952f4f6692a60bc3360588f9575636748e3d321050c42c11d75b69d316cab62c681ab48f1880a9d787449440d1f1cfa0386613c2b3d25494e7c17d3e4b1f5a5780a9f088f00a9d6a79c6b1bc0e1d501fdb398421a19e316489bf1105d9f79c74433c82b87a775ca358965e8b1248134a94179c20011121aff04b95130f2ea20a0deb2d3ad8a0f6086481d8297a10374602661ce031b99012be53c70110b53d28966d8009ce6857f778006a304fb402769065c04d25b2f3aa1bae18a692d7552bc9805897c9b65a930ba11c6f3487801284d85579a912664118075b7237e66183c66510202188dc8abc1aba9524e0450b7a29b4d6b5076769b7e419fa4a63521619d1f76cefd0a7de67c7f5491724d063a13bc27bd20e9d486fd5158d3b7c04a97b95bb06895206058f94050dd8c262eb70a73746cf279350125807c52ae8a29db743099f259c9748318f391e524c9d8b46932157c94a8179e02897f33226ef1964f4cc92c7323df35a7700daa10170082f0664e4b8a221da0b5da84f43b79584194aa8c18724a6452760365c316c1f36212811a8e1936578653878b2372fe58505e7957a3e0e0f1ac0d822a80287d204eb6a446a74afae0ccd1859a2544aedfd", + "sk" : "3724c5ebbc753f55535fc5ac0069c238d8b7c111bb7eea08b59999349bb352cc5c18f9926bf676b53a15c759964f205a322a1c88e1b4266c2d6a311384216ee6e4625c15414b77849706292fd79753163975a4be5b9410f3d261e1931c934380263740d2a2666d861010036251e7061f04a6e8f8acab2907edb1cf01f906bb972b53f79df07b3ae368411913976e73360b077771b16489e83818b6a176223097e2397432c9fb4bb013b2c8fbd2815298b0214b97cf8b740aa4bd89067ced36be138a3d096bc51f606d3865418610083c71968fa41009530931da393aea3ad975423829233bdb9b0095c2421a3db1d914e502c4ade29c408c84257a2a1b2a100839600a659026e6362be2acc789a12832ce5d876533862c0d20844e903516448448c0a600b6c7cb812a3847037cfc0cffbaa582b9028528b52580c956d4383d10155dd58bb84bba99cbae99055574b02aea64828f4c28b8a0c19a4009d6e6c58c661bea9a84f6e273b9c50d9a8048ab144f168912ca1c5efbf87997bac3834300960aa1598c15221a1a0de795f9385fadca44cb036972a8c37dcbb61c793d851214a701b3f23645a166bf1912a827934a32a58fba6abfb41a4ed2331ce0d08378417f42c176403a9ca5eca30370ca2c523e7a294c7f9a7cf87b941ea47b19928fea095ae42038217b3fa0b54caecb60ba03a8a99745982835afb01934e1bd4c432f3f3c041e96c08c8836e267a30b8883997749b56047d182758a683123a91f70e08b1b42121b666c27d4c902939cc90442c19079e53b87b834baa609413aa3698d365e5bd71b247a7f0d42184b166cffd532b0691563c7874e9392fb1c9c528387ef3648d72cc063546cf22b23b6e68c340a23895a6573f80f30e3ccbde14f56aab4fba5505314605d5311ee89a7eb5cadc7523716885b4150bc07318902657ad101594c24c7328004a29cb8caa4a3f48c1aaf7c289a063a6ed690f72625c6ebc7c10bc500b8a0f5e807655b1470a4802fa6c3d9fb0beee3386858328ef97e0b94518a455c5c6a3020a70a9468cd784a38bce99492cba4be53624925c3f74c533aa681a8482fbba5c15b026462956fb4269bfbd3591ae33823425ee57398dcfc1e7f3a53fdc6b031267e59f0c82bb4b7ceca3cedb23cbd29af7c797867493046b30e1264141535315c24a03f08c811716da610726472039fc1cdf489595e072f717a67487b842a6c8b2cb33ee9420ec5428ffa6b85a7311014595f409ba93e8b10100ac45bda836a522c01c78fa8b904bd422ef17a93d1767f31b02b7540ac4ebc3cc6025884ac9fb0ec996e537608695b84c350eff27a15f2b83d76b1622789f55157be7274b73378994a997d564b819552389918b781c19317cf85a72dfe66bf8c44b032210b9395ae35f9ce61d002a2e4a0d6f823698698a0d475e6d90baf596b83d2628b5b345570680a13b56c27a9a2d7be01ec655da3c1c93886d15b6b6f28404c85b37b09701aea3c50a146be8bb93b10c65b96248a02bacec816444c911a700f7acc16497c536da22ba6995f89985f59e0bb5a16984a005f2c64584ffa868da78d33b44b1afb5a25f85c083ccf6db93a59720aadccbf2598228bcc6da0676fec92109480548e421a618c0f0a519750d846d4818f5d1a625b877c64e9ccb639aa69186b70775bdd6612c7607ae6149f52d447a9b2946af664b493805de93e9a4846b734c0946822df415c446455cd037fece9302eea5a856208c1a3bca48c35e88cb329f2cdd6f56a1b89cb8ab972140093f2686a2cfa1ee17ac413ba6f3f83723bcbcd933947389476ecf71c676a3c327c9725048dce400f791c9eae184aa95c193e84040cda88f1a497a2b90201c95248abaad0c8848d7280be076ea7b4ad3bf083656948c952417ad3bdd28821c9c92e59f90b5582bfbeeb560469aace0b1e7dd53d29f59f12b767355a0790780e19716b588c150603bf3680464f15aab3809ef240b1759288ec719b64f7a184b890060ad066a41923f25ad87b55ae89a1222b4bdbda1e07631d95c704f6866b1f9994f94681c21b41c3d7972ccc2b842759754ca826e433497b358c071f306a464d3b0f7950b5503304910529a6e476cce974488443562cc11dd13f45ab1926859952b67fdf277ad3cb8965c1a31e4205e8fa992213c49059a409aaa3ac72b85837cddde4c4ac42a9a35ac7fb80ad2d8c1eae7019276b1f3f3a6761602a01d99d4d050c23892427d6267efa092b587a5d2376012cb755627b9e63a2a04432260aa1abb2698ebb6075620ff11b01e4d049de698966fb49bdfab73675586583c744b5bafbe9692b6c6c1448899ab72a8821b52b4bc061910fcc70beaef424afeca7d3737f4c7c6711b38dea919e1a13c78160c1c652a81210c010c48908b13101b04334e6534aa0986ec01a86b30d41cba67e573ab6b0cc1a2c973c0041bd26721b508a667bc28e010265b762a223128e092eb512bb9d6150af6840581514470212d0e5c1f4696e45ab102a91a0848497e8a7a52ef20c85d7067e6a1f99e1c0de84473b735bfb001e860c3194029d5a06484920bb0e371114ab2f3bd775248a9449d2c19de5023876931de00dfd609c95c98c133bcbeeb52c0f713a19176dc90b5143a6876ab45b7f717865d4b8f0b8a2e6a45f123b85c8fb584cd3c042676ead069cf9c23682aaa05c1010e122473907547d79b0f8b61180014b1b3a56b88b3b4fd97eebb21eaab37883889a37676c61061d41b40b49dc5e68f64ed979bbd3da4a7824b32fc0bab9985a94251fcb740bd2b103f9c21c25bb055043c895531e68b17a3cf3190683969d6299c850b7d11a6b7a183b4b3a3daccc41d3321f5c088035102ab68b2938975ff180890153135e284155f971ca624c19f15ae4a3023f20cda6d404406c39cc26ac4df1665a3c19107a99bb289176a09e4a7c197ba72d6131980264a907b605c1e1791305974d49b604c81a9c8501ecd0cdd32a5f94dc3f64481164323736435d1043b09fd1ba63ab6956e4216ce47f719bc10f0c2b2830c17886965188534205c3f8818369aa638d5902cedc28b56c9723aa4eee8485151a270d3c1d963404bc265b912c6e52099df9ea72910674bbb8493f670620645fba16c0e6c73ffa20a99d6378433c6c55ab20f0a40c74ba37ddda39d2ba4d7f34c705a4117c618ad91408ba3bcce9fa9900d2650fb109fe2221f0f6219c226b74e7968f5aa0b3e3575be051446b1b76b8a7785a43c824c73688ce495681fe723d97b249e5a65a961abd0d61527d4b18027b00dfa49f4d213253e80ff2a556c48ace2b6a5122b42c2d15622e158e2613b23e62c6398838aa821cb05a4424817f0f9291f4ccbe6578941070b22b9c36bbe89ecad318e4251451a80202a70e1b2274854809e770677ab76c9e9c5cf4e8621e4338a279169ab46a6e5344ca391b80eb12f9b8a582105380384f2fe845b7298e52803989211498b42537b8b1cd22a59085bc00941f190a66fe77a1a6745e8af09762751c63656a26692bf1870df08cb861abba73b50ac6b03f880844a2c6811a031eb412501c79201e686ae528c84b7606aac09bc42265e77b56fde93022a71374693f9ff5787fa0855c79321d147831ca28e7880dfe1c15c66bbccdb93c0e7113a5eb9b97285ae8717bb87c1f071c284c0089fbb5a7b5121770950d255aabfcf54f1c18c8d9b2bc4aa253d5ba49bd2944a8c440d01343f0770f690743dd952f4f6692a60bc3360588f9575636748e3d321050c42c11d75b69d316cab62c681ab48f1880a9d787449440d1f1cfa0386613c2b3d25494e7c17d3e4b1f5a5780a9f088f00a9d6a79c6b1bc0e1d501fdb398421a19e316489bf1105d9f79c74433c82b87a775ca358965e8b1248134a94179c20011121aff04b95130f2ea20a0deb2d3ad8a0f6086481d8297a10374602661ce031b99012be53c70110b53d28966d8009ce6857f778006a304fb402769065c04d25b2f3aa1bae18a692d7552bc9805897c9b65a930ba11c6f3487801284d85579a912664118075b7237e66183c66510202188dc8abc1aba9524e0450b7a29b4d6b5076769b7e419fa4a63521619d1f76cefd0a7de67c7f5491724d063a13bc27bd20e9d486fd5158d3b7c04a97b95bb06895206058f94050dd8c262eb70a73746cf279350125807c52ae8a29db743099f259c9748318f391e524c9d8b46932157c94a8179e02897f33226ef1964f4cc92c7323df35a7700daa10170082f0664e4b8a221da0b5da84f43b79584194aa8c18724a6452760365c316c1f36212811a8e1936578653878b2372fe58505e7957a3e0e0f1ac0d822a80287d204eb6a446a74afae0ccd1859a2544aedfd8678b1f242830fb21f34f7beb20a96ebbbd6181890cee3bdcab29697c5aefd707f7054814869cf7625e45647bc1547aff288dbb90699b2ad84893f3b755d9722" +}, +{ + "dz" : "e3fc575ed51513e62aba655d24cd9c8f1c6c848aaffa946c49a53ac3ea59e474d82c2f1bf2e6aebde5660fa73356982e12999d8fdafbb3cb186341d0386dead0", + "pk" : "eac2871f16b152d08e74e28a250999db0a6db7036711a24370401ab844cd39b124b8d42e8a15b2bdc85fe3b11c9caa30ee666f260ab0f0e230a5901229b974446428a9e24680a884208a2dfd3899ff1a4920b798ab275d5a10b01503d000c23db72ccbb3a91ab0186fa7850de3055e4531439bfa9cdce3ac888066d17469dce07f76d0397bd46a59c29a4a776c8b7310021128dd248beec9296c7c5e95d13aae21303127778b653131babc17494f0aa63c18260130315bcca7a8c8521e7b9c9544c1260bd201ef23974957a6a4d3658d96a7fd4cb7daebb11e5acec216042cac64af05c8a7db570ceb09393c7a24f5ae305280b1c22b9d68b02a0c521dd6393c20cb3eb798db457ccbd869748aa2cdc8336a58162e56528c3ac7a7bb41e2db1a35257b6135247c7802024ca258f03de2ea93e2f6c42e539617d27fc62510ea016deaf787a2b3b930165ff1fc8e20413b90ebc827581b74988937a018f612ac4098514480212781c4ea128680448b58a5a296b35020c6668acc7a39ec329f3c5eb00c44f43c9ddd612c0860031669c911e0b4d5d20f45ec1b6c5b6be399c2bde785757215be7617aa6a57eb6b797c8c5cf774274b2463d0c85e1343554ba052fd9b36da139e13e04ff18427b418282a5642429825d15636da6c45834375d543714e80530deaae0b006488eca46974642c8307aa5297d34619dc39863f276189a20b75673744fb934420a138506fb04b0eb2e22108c1923784523e767dc70ca546fb820de07bb9663333e623889279bc596b2f559f5699c272c3040602a0ea98c878d2af1d7aa697aa83f1dc10e54017e2e586b220804588473c4b9d05aaae6ff9c038d00f953547ec748e62ba3426001c3f669941596c6184b353d3919e591df898831eb11aaedbc49b88c8187cc13eb79eb09c7e07545be6041a9bd0a70519b17b5479aef79d105b83d74c08c719843a94bd1f76baf7e3bbd6795e05830184c53f42061f4b6b0321e2561b4c474865a0c825c96f9269e12742771c4c9b20b9380540772a24b43c2ab3051b88ec4760f794c17aaa55199e39eaab54c53aef32bfd339c824501972eb5ed299908ff0ab3da01460f106919b450bf00678967e45c18531d112b481918fb7023efa1617da59ff391b84b03ac199a1ab31208b918777a2c8a9706cc8359d09e4a817386ce09757c44350d10c4edf02625ed06dd3db07514639f67828c5077f0eb722f39587830c506c4bbb4bdc60a1b256bb157ed4770e603211d508165edccdb2d6cf37f039578176032c2158eb3c9d48921cb387339267bb728eccf97bf31309d08611b91271ec698d8920ca3bf334fd8765b0170608726a6220a3ecc14023f02aa4f31446b22da93597e4a46d451cada3965ef2148a832221c4d8a7d12157d9b3bc69fac8626b2dd1c44aea272cc2125dc79a4f90b56ea75144037a4f0060c33c5b6eca4572142310ce956fd6f31d23c6c9f6235057362b884a014fb5867b2c1976127a5a287ee371b7430caec5d35b63789b31d176d2553f82c8407f585c32511e3f0cba0ba60537780edc6ca22d1422ec8c3357eb203ee68c8fa135b0ac2836e027fe3161769c6838e98cd449c14ef2b07afc714cf02d91d387a27472217c9ea6bc5cd1249bba38842cf1b28701a6074ccfb7316dcf345acd84660d02381040cbe8109c5d423921b84771a1cba981c5fb08c5de08ae6cdb38fd5b9489357df11565d48a7797a6af82553225d73cebb362abb1ce335358c6776d9fbba731883ae7cc517e0a0a3bb5b970e4cda95a98aba47d9e2397abd7757218c5d7bc4ca59b70be5aa4d7b62afb54048ffb0c64919afb746120b383958b715d110e5e6ba666940328ab4510fa25e9b43537e566ef760d2cc52b07e5bc089b8ea9e166c513bacbccc332f36d6afc379e1a838ac24ea35c1260726d029651088996631c55e846adcf36c792c21011320b2287973a770d2636470c080b2893a09bcc8705306c5b364837b7cc89a9ad1fd9c1edcca9a0b4b81846c8e088b36fe361539060cc08c911c9058bbb0839183b0c59302171826dfc7b6fb1c623dba3f0f9b30768346a7714481b741bd0bb7ca32ed73a00a6a1874d8b7369f695efe75e00f03be6cac1476815ad889c69ec6bf7fb38ce9609c174b902b6047ead37da33285d1009b83c39ff67773cc46f7b4b2cee35e8e95100c31dc59eb9", + "sk" : "081ace51252462bb622ed578c65c864be5210ad1cbe55b6288a8cc22d297edb0aaf549bc240963f0c65368cbccfec732a7345f43d563315442aa97acaee1036c58a4fb752984ac6e85c4b744f5177cba665ee2154b5c6c3c0455b4cc602d9c411186ccaf5c1a1ec51558fc5eb1713229ea213f261a249c225566c5d9333b9a579a907016406b709b8c97a0d2270aa0a11e72ac51e1a5192545c6515153e193ebaa7985bb23a47138bfdb6f96e47e8bda4042cbcd993948ffb7ca2673c4a3773e9ce5a97c34c543ea24eed7537ba8a5604ca316aa38b0b04beb922c9c62af8e010a8ef9b22ac92fbb7a6035e0c842c3caabf12c90b706cac75f6868b26b8ab652476d520662faa46ecc990a4db166262c19521817b3a82dc3b8b671ba21dc4b06f3150209f890be837882570bc7603c48026c44415ed938146c57b36c361b7c0b0e04bc81f532494a198af962208e0785ec1601b57967bba750d4a34bed69c1c4b2982b97a1fc49b4e7e970307087930b32a44ca7fa4c4bcf5a91e1b86a2d8c60e3019b7cf98f634aba74c84911ac4b159636a4d49d63bc81fb2210fdb40bf3b2a467cb101c43c68473046cc4b6b741bebd71b27a56ae4de70288d74e6eabb2f9a1b334f4274e7369b7618b31316f5555288ea88310b97ad7b425d052b21fb42487331cdaccc4398bc0a67b4a28a77a2396327a95cc6cd98b54058428d9a9d7a45f83ea5e1bd26222c60cc3f77e0cc87449836940815279ecb65001c5bb4a599771848e10a64d8c4ac30b57c6638fb11bb1350b1d5fa34153804556266fc8d70a4b56067718c47899a134e36a1815a791600a14f43c9a2065ff786aaec7a7c4571546ba339dbc41bd98c462a85e5b72cdd07c5af9979f74c32b2d501f05a57d5d659958b78f26853500dd47f0cb8ae5c08db6a6a97c1312ae3c20bb34c4c3a2a9177cbc1b152c2f9940937433b3414067093375fc6bdf44b8738b4ad95261e74371ea2cb2eda13b57579cd2a939f7c9a9950a32ad07baf63c02603a626d9c7edc89817ed02bbb376dc2c523b9a84e45dc811d736789647c5c291aaa9a3d01511b9237a56e26130445a4486962ef8682f71412104b7ffec39b11fc713a234ae3087181a2ce5a2a3e7bec354e2921806b7c99c57c8f5bab84a83dd75b16147ab62a39064b530462e40d38c4971c18bf39f469d34c12dce7707ad61cee073c6fc0cf6ae259ce16890c2528a499b98ac82712b8aee7225b78ec01a19bbf5692366e737591733015616c38e30924044c2f551cfe2c90755362c34abb53c59fdf8a50c1e392af7a0a739a5626246e655991c41c9aff111e2c21cddd5242801561747306fdac5b54cc4e76543e39900e491cb24fe353b45b38de47cb3e05693c9525f88b4886e1514564231caa5f33d776cdba9d6ce8323f7c02ff9310c7227a37c172392a85f3c234f73c52ecf48a3385c310554c04481d28b59185b8cdcf80437b04087a7820e94b95e31189f2eb4a02e4cb13e683971b9d9d912d2c369488a1037b468ca88061b1a96bb8acb2a21bc54b402cf84798008006caeb9266b9783ba81482f02e19da185aac95e233659672479d02c0e1a418852230f28a3faabaae8c058a995cb843d98e048499f7250e1b40c532380917fb8156d0b5ce338fb6256e31752ba16aad5b9c7e1017188de86e509109586cbc59916993a5226c13332bea339716a228cb2c6a90b485440a98d6cba8c5592b692763f853f56c35948b0860e087a15a78a134c3585cb034f135a2b79d2ffc73db89b65512253893cd2aa937eaa1ad24d0aab311845becac9f15b7ec1b6a51aac4aa45c337b44644499cd464cd6f717472a08cedb8570c8714d088a2cc21c4efdacf8cc59c2de91764141acb26851cc584484728fa1290a90338468aaf944c943beb9d7295cc500054615ab770423f82f329e3d3b751c70589c693009d7c1634b5c43ba5b795ad3873ada60669835a034d61439f3a897c021a057616f911087bb626ebb5a9e6d63e896371ae4192c93471b66ac0544131ec28074cc6a12b4364fe362c2fc68f359a7313ac5d744989bc33b1846a2b0db449f84a273738c9f2d98e6bda993dd514f17aa047e8b72e413bae7495f0b58b38b71d85a8cfc1f183eaea4cc281a5ba6a876d7233107b1beac2871f16b152d08e74e28a250999db0a6db7036711a24370401ab844cd39b124b8d42e8a15b2bdc85fe3b11c9caa30ee666f260ab0f0e230a5901229b974446428a9e24680a884208a2dfd3899ff1a4920b798ab275d5a10b01503d000c23db72ccbb3a91ab0186fa7850de3055e4531439bfa9cdce3ac888066d17469dce07f76d0397bd46a59c29a4a776c8b7310021128dd248beec9296c7c5e95d13aae21303127778b653131babc17494f0aa63c18260130315bcca7a8c8521e7b9c9544c1260bd201ef23974957a6a4d3658d96a7fd4cb7daebb11e5acec216042cac64af05c8a7db570ceb09393c7a24f5ae305280b1c22b9d68b02a0c521dd6393c20cb3eb798db457ccbd869748aa2cdc8336a58162e56528c3ac7a7bb41e2db1a35257b6135247c7802024ca258f03de2ea93e2f6c42e539617d27fc62510ea016deaf787a2b3b930165ff1fc8e20413b90ebc827581b74988937a018f612ac4098514480212781c4ea128680448b58a5a296b35020c6668acc7a39ec329f3c5eb00c44f43c9ddd612c0860031669c911e0b4d5d20f45ec1b6c5b6be399c2bde785757215be7617aa6a57eb6b797c8c5cf774274b2463d0c85e1343554ba052fd9b36da139e13e04ff18427b418282a5642429825d15636da6c45834375d543714e80530deaae0b006488eca46974642c8307aa5297d34619dc39863f276189a20b75673744fb934420a138506fb04b0eb2e22108c1923784523e767dc70ca546fb820de07bb9663333e623889279bc596b2f559f5699c272c3040602a0ea98c878d2af1d7aa697aa83f1dc10e54017e2e586b220804588473c4b9d05aaae6ff9c038d00f953547ec748e62ba3426001c3f669941596c6184b353d3919e591df898831eb11aaedbc49b88c8187cc13eb79eb09c7e07545be6041a9bd0a70519b17b5479aef79d105b83d74c08c719843a94bd1f76baf7e3bbd6795e05830184c53f42061f4b6b0321e2561b4c474865a0c825c96f9269e12742771c4c9b20b9380540772a24b43c2ab3051b88ec4760f794c17aaa55199e39eaab54c53aef32bfd339c824501972eb5ed299908ff0ab3da01460f106919b450bf00678967e45c18531d112b481918fb7023efa1617da59ff391b84b03ac199a1ab31208b918777a2c8a9706cc8359d09e4a817386ce09757c44350d10c4edf02625ed06dd3db07514639f67828c5077f0eb722f39587830c506c4bbb4bdc60a1b256bb157ed4770e603211d508165edccdb2d6cf37f039578176032c2158eb3c9d48921cb387339267bb728eccf97bf31309d08611b91271ec698d8920ca3bf334fd8765b0170608726a6220a3ecc14023f02aa4f31446b22da93597e4a46d451cada3965ef2148a832221c4d8a7d12157d9b3bc69fac8626b2dd1c44aea272cc2125dc79a4f90b56ea75144037a4f0060c33c5b6eca4572142310ce956fd6f31d23c6c9f6235057362b884a014fb5867b2c1976127a5a287ee371b7430caec5d35b63789b31d176d2553f82c8407f585c32511e3f0cba0ba60537780edc6ca22d1422ec8c3357eb203ee68c8fa135b0ac2836e027fe3161769c6838e98cd449c14ef2b07afc714cf02d91d387a27472217c9ea6bc5cd1249bba38842cf1b28701a6074ccfb7316dcf345acd84660d02381040cbe8109c5d423921b84771a1cba981c5fb08c5de08ae6cdb38fd5b9489357df11565d48a7797a6af82553225d73cebb362abb1ce335358c6776d9fbba731883ae7cc517e0a0a3bb5b970e4cda95a98aba47d9e2397abd7757218c5d7bc4ca59b70be5aa4d7b62afb54048ffb0c64919afb746120b383958b715d110e5e6ba666940328ab4510fa25e9b43537e566ef760d2cc52b07e5bc089b8ea9e166c513bacbccc332f36d6afc379e1a838ac24ea35c1260726d029651088996631c55e846adcf36c792c21011320b2287973a770d2636470c080b2893a09bcc8705306c5b364837b7cc89a9ad1fd9c1edcca9a0b4b81846c8e088b36fe361539060cc08c911c9058bbb0839183b0c59302171826dfc7b6fb1c623dba3f0f9b30768346a7714481b741bd0bb7ca32ed73a00a6a1874d8b7369f695efe75e00f03be6cac1476815ad889c69ec6bf7fb38ce9609c174b902b6047ead37da33285d1009b83c39ff67773cc46f7b4b2cee35e8e95100c31dc59eb9d604833a540d9922a7dba53d67a38de1634cddee1b169b45bb9eb3646e55fc0dd82c2f1bf2e6aebde5660fa73356982e12999d8fdafbb3cb186341d0386dead0" +}, +{ + "dz" : "470b4943f0fe7fd0d8ec5185aba0d1db09d112934e4fb4787e2bbc6b88466e7b8b2809fd40008be70a6b184981101724bc3d5ec5e1956b510b82fd5ad0668a5a", + "pk" : "f8ca36bdd81e5969c6e2f8a58829a9b7697b6b36983e896e82b40738740fa2e6b657616b0b4cc0b15c2292eb5b42550f812673194b944b830051e4206670bce9734f53232b408a6cbe7542712352c453cac39741b5b940151580482b4752d16f58a1c090b101cf985034299840a186a1061e59eaa300b66fec19a3abac920a1a12e1e4070aa37893923067614f9e53c0d859917626c6d6658a0324419d0b0d16a647ed57c3cee638400875cb0436671a0c9f472eede423125a95c86c60d2301c85660807f43f35208716905ab4153b6510c128e038920a3a13e957e2e209afb46c7e0c9e92fabbb80063b93c0a963b1aa2d49f48174f86c761d923259ee04c65f4b85dc110cb04ad4e26c369682e213ac4114824a526b2e6a21705174110b538e3562bd93cb251962e71782d89e562482a51949707ac8337b78627d489b193600636fc44c44898b2dc7c87332f3dd9c7579a68e0c01211fc1957c43d781473fd3bb17ce14456e62d93c236bd9656f5ea8088339668658ed8cc1e909a026fb76f0ec747d5a570ab88aeb44750710c0d10ac86caf73f8e2238b7e51da8722317973bd544834fa31571f48744b6a7cac95e1d3375949038588cb1d5d50476629432ca9e43076bd260b1a6a3472be2cd780177c4750b4080c09c820bf9f1ce2de695478ba26a216ba2b032cb7729770514f71700864ab0e3780cf94cb7e94c88dd673dd03b8690ac65b8e0c597fa8098111d36ea9fc4b166d9e6bd4935993dbc8f21acb9f53a20ee118a721541425a31705a5d67a6196c91a96dec2b2b48536e118afbd5c8fe46455aeb282a7a6e73b734001b6d3a997ff1d50ac7d3c97eeb4338f13f8eac05cb0b6f7f60908c0b1ed89682192a6ca384c7ded2170674c353d9aeb8696648cb83ac986dff669e23f49c47e9208df49187c1155bb1c876d1242098bb7951454e677c67042dcde2af77e8090935b5bada59c4252c6889b16765a033d98452f25632710ca5553559d76358c162c70c1b5624abc090b59960c65889351529bdae24170751a45a566ad858444ff61cfeb7003b08605f3b2558577f0e12b31a447d377294e7e4060ec12a5ecbb9770bb8707240c1237b08c744e70057d0e68e2fca1cced27a1997389bdaada271054f72b849329e9a2321aeb03a940c44239844e94181b627876838671bdb3e9b4061fedc74741b4b5e9c4b421167bf420cc8077c5bf02721076c1c5462d7624f8350af75c50eb7267a96359004166c84145e72b731d5a82d43469c98b00a0c2352b7806313c60c04dc5f5c8b39d50376a9461f2a8773fe06973e852a04025ba6592f632bcfc3ea0ae572a50023c684a4a7a0db573ad1494458990938c624e5928c028ec48a9a26492420781071d13a85a332dbd8abb8f318a31596a38c7efeec28bbc1aa38198aa66ca68d811cf5700d9e093e34f38d0cc74a989459ab0b200a8caaf6d40ab5e5cd651c05fcf68e14a1ae602560186a10aa452328218e41c49b7e5154c67099ec790e88ab641ae03dd6acb82c33a6d4034a775515c52859bfe354b2e881c7c577bd5663b19b124948739be90addb36348912710cc12102553765c580512b22ea35141ea4ffe681045497fca77ad2e35c1a5b31baec2a8279c783d28241c923040607d38463a9b615be08ab87acc5e31b84ed8376d75f31dda47c869f82ce14022acc6c70429ba854b58e942635a12209240bae3137ec8a40e716655a0a82bd02003f20428d15806594435de6c39b746298aa9a693577783c71154cb31b7b31283f46733d199ae627ddb7947c4f4aaf1172858a97ef6140f56477b80450536396399a14a984caea756b1b5c09ed1f43c4e1754f40ad0bfc8c5f153346e0113930a3c9ad215f11c4ece2875c41516b0a8452e948f3f3cc45960bdd8b23f14eac17927142eb4a72ef6c3585899efc128f53b022015b2bbb9642b5675be352b9d442194d54d5b40a17c236e8a275dc2358fb31471a3f521b444040d983e64976b50f71441982f29fc690c41a954512f82a3abf85235847a28982009e3303239454ce0c7a2c3840cce031ad37516e6a3ba59b79ba4478afdeaa8ee8ac4731ccbb34125d0a7c6504a8d7e285171a464129b714d8521c69b8d952b4623aa8967f644c8c08bdef96117198e56c12602501201e036804129d528d717640ea33c9fb4885d61fa43860dafed4282b108", + "sk" : "18264c57aab774ea1ba3555c788511bbc7bec8d072c953579d7b8558425123a057f94bc5670c85b11b81963731fc611bf751973a1105c7138d9c8ca76a559d20d25c79b64b70a91224e8110f623da7097668bb1ea2a17d8c085128225af2506c3f52a1f57011f849cecd605340724aa418ca6a86204fa02b0efb0102e4b2d6f34a2817643ba33561827b3ea92fe0270fbfe89c3f84438c4397ebe8a735a77cb8597ad73b95d170b329d491ba624660a01edd634acaf45303133127e11b4a3b95804620a7c6b1f84bbd916744d18487a5d9a54697716a965b7a9530dcb406ff8b276787ac9e846cd037a00852662a6b73e976807615bca1c00c1554ad0282b544daab0533b1ae9c1e71061dc18a79486c7ff9f0771a8138f93983134c5cf123955e748ce224ce925883c3565910088fac9393d423ad55ba3fad9012faa77957d88573a721f372b2e3fb977de30f72116090cb1cf02b0c1ea68cd23cc593e715a6a53493759f16a26a5c5745787115aaa233ec305b65b846c775bf36a754c8d563e25ab9e7681d589632131b8596b36a4fea7382938e121c38d4b2b218b90d4c602354a3bce5b58c4841c8daf61f8573b7b1e46f38e203bcf0a0d0981576a45215f2c7339a6fe91839d899b995b839b9b465aa942f994913b906698b9a31530b0d4f096de5aa3e885c6ad9468e1e674fc9b2acd26c4a20ea5363f32d745a0af3f037adac5350f07c5ca17738a243a29564455290602884866913d62413ca628aeaf248885b7517033583e05ccd55ac272b8cf142bcdf0bcea1a9c271e747c8507fa6bb89b1f0345300bddda4bf13b40dd323c860f237d8f2b14e03cf02e923990bb8baf13fbfd355cc3cb46bbb41b2f265a403c58e440306c7ca5a11cf2265562898b2ec28b5c6d396a1c668fd95b02e3451621a2d7212793e0921324450d601a19c975d877c84a91aa4b1e381d4f9256c0428c32809857b1cce8b7ba412a3f7d4b3135954177865677c45191294636241609c533d548dd5e8131be776724068a59242c1263e55abc515e4b3536c6cc836a140062e11dbb43ef9831a012b8c34714467906b78a5ed8a8e515258ddc6abbb0a110b6451544b78d85cb0dd78894d9ac491a7a5f08114833bb9c7628dd4061610944fd3a92205d7be722a8f2a51a07d75ca660107254c88653a79a8d79811543dbaa5205c290a4f615df4a24e7a7012155006db9715ccf712fd65876013a6c5f12c272c112db75e0c2983478328066496c34bcd763703e012076f85564719a4b477b8fc93845d30ba64164b28fa025ccb077a457f029b367ddc001b8cbed771b391857666ab88672b4bb5e4b653a8035225708b897fefd950f8d9614e310ef1b65942d53ba13611faf259f0a02c1cc357c36870b8b747fe1c66a5097ff49607007c0f52a74017d798dad417cb308ba8b0381f692081c51fda5b21cc5a471f5321d2128f0867714b141a37d983f3121054934b320aa2b044ac971870e0b2a6d14227c785504d341e3df90c586b5c66243b01b42f6686afc0c8b6a2faa636e39a0c550a7f61ac5af769e2573cea2a8da6b8adfb03b12c74b330b02042e8c2921239c45641ed1899376c7939c51c08a15e23493c9b8a6396c44bbaf4212b05cea4668a2e851c56ba56abd11410e21b7bf18347cb020c33429c15b6658248dc75224189cf5c53b920068c855b24f9809cfdf8c61bc9662e981d8dd896c8b99ee667cef1a4cdb2f14df05435efecc3d974cabda81dc18192bfb39ccd144787bb3a6051b06b1082f2b75eed10c4da0132d27c4fdd854b305b02c66a04dc50407d7160f1d54929e91a6a008d0a28cfe109be18774744250c69aa7ee7bc41944597311c87438441cb59b082a5348e312b30d66f936585f356c06d761ecb04b48339082f1542e3f3cd885aad7056a02d075aa825a3b99848c2e2ba518aa4e6662198fa871f744bff97351e613cf2e7505d2115be9a7386680300c1a985b39e0eb3769f73576eeaa28ed8c0f3b76ab5acb302877bce254fcf3636b4f6c4e0089d59305d5f819be4f380d669186a24214e9b2477334c25d23910907240ca8f7e1720dc8abd38e2b88246be2a55c72f6c1db3840370836f93992893b98f42f9180778795830ba59f09650986e5197a4dd239f99e7b5f8ca36bdd81e5969c6e2f8a58829a9b7697b6b36983e896e82b40738740fa2e6b657616b0b4cc0b15c2292eb5b42550f812673194b944b830051e4206670bce9734f53232b408a6cbe7542712352c453cac39741b5b940151580482b4752d16f58a1c090b101cf985034299840a186a1061e59eaa300b66fec19a3abac920a1a12e1e4070aa37893923067614f9e53c0d859917626c6d6658a0324419d0b0d16a647ed57c3cee638400875cb0436671a0c9f472eede423125a95c86c60d2301c85660807f43f35208716905ab4153b6510c128e038920a3a13e957e2e209afb46c7e0c9e92fabbb80063b93c0a963b1aa2d49f48174f86c761d923259ee04c65f4b85dc110cb04ad4e26c369682e213ac4114824a526b2e6a21705174110b538e3562bd93cb251962e71782d89e562482a51949707ac8337b78627d489b193600636fc44c44898b2dc7c87332f3dd9c7579a68e0c01211fc1957c43d781473fd3bb17ce14456e62d93c236bd9656f5ea8088339668658ed8cc1e909a026fb76f0ec747d5a570ab88aeb44750710c0d10ac86caf73f8e2238b7e51da8722317973bd544834fa31571f48744b6a7cac95e1d3375949038588cb1d5d50476629432ca9e43076bd260b1a6a3472be2cd780177c4750b4080c09c820bf9f1ce2de695478ba26a216ba2b032cb7729770514f71700864ab0e3780cf94cb7e94c88dd673dd03b8690ac65b8e0c597fa8098111d36ea9fc4b166d9e6bd4935993dbc8f21acb9f53a20ee118a721541425a31705a5d67a6196c91a96dec2b2b48536e118afbd5c8fe46455aeb282a7a6e73b734001b6d3a997ff1d50ac7d3c97eeb4338f13f8eac05cb0b6f7f60908c0b1ed89682192a6ca384c7ded2170674c353d9aeb8696648cb83ac986dff669e23f49c47e9208df49187c1155bb1c876d1242098bb7951454e677c67042dcde2af77e8090935b5bada59c4252c6889b16765a033d98452f25632710ca5553559d76358c162c70c1b5624abc090b59960c65889351529bdae24170751a45a566ad858444ff61cfeb7003b08605f3b2558577f0e12b31a447d377294e7e4060ec12a5ecbb9770bb8707240c1237b08c744e70057d0e68e2fca1cced27a1997389bdaada271054f72b849329e9a2321aeb03a940c44239844e94181b627876838671bdb3e9b4061fedc74741b4b5e9c4b421167bf420cc8077c5bf02721076c1c5462d7624f8350af75c50eb7267a96359004166c84145e72b731d5a82d43469c98b00a0c2352b7806313c60c04dc5f5c8b39d50376a9461f2a8773fe06973e852a04025ba6592f632bcfc3ea0ae572a50023c684a4a7a0db573ad1494458990938c624e5928c028ec48a9a26492420781071d13a85a332dbd8abb8f318a31596a38c7efeec28bbc1aa38198aa66ca68d811cf5700d9e093e34f38d0cc74a989459ab0b200a8caaf6d40ab5e5cd651c05fcf68e14a1ae602560186a10aa452328218e41c49b7e5154c67099ec790e88ab641ae03dd6acb82c33a6d4034a775515c52859bfe354b2e881c7c577bd5663b19b124948739be90addb36348912710cc12102553765c580512b22ea35141ea4ffe681045497fca77ad2e35c1a5b31baec2a8279c783d28241c923040607d38463a9b615be08ab87acc5e31b84ed8376d75f31dda47c869f82ce14022acc6c70429ba854b58e942635a12209240bae3137ec8a40e716655a0a82bd02003f20428d15806594435de6c39b746298aa9a693577783c71154cb31b7b31283f46733d199ae627ddb7947c4f4aaf1172858a97ef6140f56477b80450536396399a14a984caea756b1b5c09ed1f43c4e1754f40ad0bfc8c5f153346e0113930a3c9ad215f11c4ece2875c41516b0a8452e948f3f3cc45960bdd8b23f14eac17927142eb4a72ef6c3585899efc128f53b022015b2bbb9642b5675be352b9d442194d54d5b40a17c236e8a275dc2358fb31471a3f521b444040d983e64976b50f71441982f29fc690c41a954512f82a3abf85235847a28982009e3303239454ce0c7a2c3840cce031ad37516e6a3ba59b79ba4478afdeaa8ee8ac4731ccbb34125d0a7c6504a8d7e285171a464129b714d8521c69b8d952b4623aa8967f644c8c08bdef96117198e56c12602501201e036804129d528d717640ea33c9fb4885d61fa43860dafed4282b108cac59b140df7d3285c832994e7a4ff5491c786281fdbd6f43a4c3902d4eac0d28b2809fd40008be70a6b184981101724bc3d5ec5e1956b510b82fd5ad0668a5a" +}, +{ + "dz" : "6df4385db978d27b27d2aa5e452e4152b36f097503d9581ac3390105c5727e7dc95fa08ed106ce84660e8a4c90bd2b22634e40769aa0090a101c5dddad45edc5", + "pk" : "c19093bdf18070e37b3ab06ade8b14de2b34ca99763f575e8d75177c72522c6c4eced8ad20ac6bfc4aa329e765f986579c373a3a333d6167c2c7440e8f4131ec305188c989140b63b65019f2949c81c36cbc45939c026a42a1554f2385a738a229534cc6552d5e76076087c9e5b260baf8724973b9152b3941fcbe19227bb7987d74856d3636049715beec638db8e3b1d4e3ba2a440b46445369b60e0ad3c9c07c3203e2716ffa51eb5005d1a797079089f6e14d86d988d7f960f0dcc553a83f7433be60a463b04423a6977599b7c1f7730265807b3f7b2bb8a625e0b0a0f3f1171d6c4e7a9a6cb5803b4871501453ac19b576364c3bd7e01f1bf475a9e71d557171e4d33bd3d14823672f27e356c89395c1476e0fa065dd168478bb710394116de27cc3b0617ef5b74ac718e8b8c152c052a4d57828824af38807d91295a0da9b49dcbda052317f5576e52b51eca732d8d260d08832918094de65ab48d3351b1327568574dcc82e3e8a222044984649271b3b45861ab6f5250a770b59071309d118adb32322739cad7227ad2b3460d156c065713f29a05ec48bb21ac7261aa6a0f3f19d05f0aa577cc8cad6a7fbd25826a3cc6ee225c1b183d8e124055414c54469e4e410828bce94a5cd95e22c7ca3770ec5a023f0656447621006929174850c786fd6357f36188a4884cadc108485277890a0114b4c565747c4165196e3e90cfa659662d992c33bb2582970ceb60582a691d66174952841ac5a64e53b31566671054486ee20437e245e234176ebc696a55a53308abf020b40b944cbf382155ba02fb9ec298aac3c2b81278772c9e0c730ab13c6f374ba8c886300831adcf9ccdcc566e2456bef479f4ed08ef803ca8719c382dcc667a21897db1f81b41521790ee233020f3301bc9910dce2202bf4329f632542f820bcabbd2bf38962e6810bfaaa5377a83b10a62495029e99c4becba9f0b3a54f70788f97ae54f01781b8505c27c23b810ee9c7452952af9339c4ab88aedaab3b9f951cecd828daea0888a3481ab39207a6851c0285226136ee392996c41b7d93221df711d44531c8818bf3b71aa65aa0a3b5055634699b007a47210e9583928ea984c413598868bfbd021cff817c426caeb3a77c9067b04dd3cdaf2b840af6a44e5a5ec3956b21697cddcaa035c46159262524e55f9923a5c44c1c747a1e35889b20ac2ecf5883577c0722316d6a82a88b21c8334ba25a442101b6828b10b1d9280f13f867e10c88ff3cce3af457a4ba82ccc4c231ca991b79c66be0c56666c80656845789b45f0606539149cb12b0917b297fa683031413d3e89d3e38544ec40cbf288320bc3b812311ef69125e641232322e3f1ba325b668174179e38868bd50233c78b0cd8721acb23b0b065a13f36a2b8b8245095cc785c64997add4a33b45e9a602b10edb318830a046d8f700b2e76094228a14a251e8f48403914cfdcb9e3ac0795f907cc592ae18d322ebb882a1473ff2fc666b7a829189a4910c60f8b1193d59515280bc5a9169ca6433c4e560db8ac756944fd9ea1dd1a0c9f9f57a474c32b94730460046251aa7d27a9a3f2c617816386207449d8c18f04537084a3f464b737c1a49e59c9042876e0556b92139225fa3aadad3b5f18752dd614c1fc200923c0e0b4804fc5b26f7c6cdcc684da00289ce344518c7a480936e46ec4c01b36a7f2645074b26d0414fcfc46d2ada8fbdf1c50c128ec5d2abe11ac78205310ac8aea724a117f00246046c4360662101b191228628383cd9047a28025cf8d6a47dc161af353e9067ae4433803c48b3cde24466d00aaf68be2eb1a209e8b1f6264fb14873edac70f834c710acc18fa4c6d16a627b03406fc7501ef71e62963e01869c80787af2d96a4ef8c72d273a3318c2826b8bb513bb2f6739648666af720fbb4b7785c853bc1aa4cca2c9d5852706b7bdde4c06c78c960265ce1887b5e13275f42377447751ac0bc811e26c2f65bb19e058d573a64959bc0d74727a4b5ae8ba23f2179ffdfc171563712eb028d9524af43c6143277bbd537f1155b04c0006b66036161472a199764ef7283e044c62a7244593564b15436b435da9e995fc803964f631f8332fc8887e49a87c5812860cf96747ec5891a9ada1e769af720e946c9727731449cc7179f73e867c8a63b210d73ca9f8d4eb44b5da3b57dfed46bd22ab85b9bd915556", + "sk" : "6a45c4d6507cd4abc9be8cc42a75bb661007f8bb7c8a408e51fc9b63fb8575683e3ac77aa6862f808529819219d8639f0c261ca4a2c2021426b53c19eb7c6dcb554f39952c0f4940fabb4c03903c5bd2592fd4178a68601a8c4b4fe598b3b874dce5581063351683a672612904b17bca915ff161c26aa8a27b212a7650b0858736c1d7025a987c91171e4465702007b4bca05fef05186106b895c62c42f33aaf449ea0d4982c46276069a970e04e8c58ce53356f18a99c7e2a8b1a9714a64aacb42338a2e05f377b969c82958891a9c335ce1ea24865ea1440d99038d82035cab7d011508a802da9b51a00192344ab9a38a59a2b203b448639b89a80b2c2b3f6163562cb2a01f526bf812181ac466c55013c94190172c086a2cafba3152ff247b89120efbb1e957a33615924c34c0260034a9163c3da2b2afa4302595c4170953864990a95146dbf30b379f343b2f236c03bb4851775da2a50f9a40121f7107d184d410975ed743fdb674b179c396b33c808b1af0e717eb95000b62526598879fb5b972b54668b62306cc2c196f81113b72f6e4b0433b44251121cb7b872c54656a8e211b30b57c17a29fbc91de1a8943eb2a0ec7cb04b4b3d4d057c12181684519da9da271e8189c8a6171f9108740482da39c8da064f5d2745ea9585702601513a2c5c1322fc95a7ef15ad1c4353710080ccf396f2f006335480ac1932407b048e72c0ac24a106051e7737a1e11ab0905ab829404b5e37bca2ec9f9bdcb370b68404875061f1035978a3c7f7962fe015aa4c019465cbf37c929848c335e9cec829218e15902fe045e6d43c845b99a8878ef7a73238fa87cf0c58dcc3913dcb29238928d948c94bd54029d9651b25401e64a29df9a04c15bdf047a3ae857d74a5a22b383069ec24bfdc3e0d85aa892c6e69651a07eb61ccb40ea1d0bf624a17c4b849fae348f8a8c326f875dad81227465688b264de92a195635a690b3d6126989af58cb6e205cb8253ae8472e2e9b2c8d711fea534ba41c108f22cef0829f1bb4372d7a76dc4901f07aa413395998734390c07be80ca1dc6cf087b11ffb180f94b86c051b505752d27ac9fefa29fc849c77201b90641906492b54cc595e1dc71738a678451aeb9d4a30bfb2776435eb3d990f8405623856abc7980b0a4c65d40abba6278fa4c7b3ecbb718180fb3225b597acfc7e43caae9413fe858359334499a921b3216a03403672b6b1920c6f39b8ecdba69d87ca52542cb0898477587aaac8369f6e39ac7609c437456290434b002b2c3f32b05c41c1f827accf461dc159fb7caa9856438fc232a5b4545c25c66a8a25c1f240eaaaa263f22cf5fa86506b51fff385affd91b6ad8bb599633264c3ce786670ae70266f898a48040639ccf334188774c90b08b99e1a07be3244d7ba319146711faa921b647c7227b6caaa70152701562d81bd1d1cceec218ea967bdff454fb176f6ec504d7285779c3866763cff23cad659803b41448bfe253e391a21c67b89911c06e7c78b6b2ac56f737aa027cb7f80fcbd0897f60781767980b89266e342e80c97bc2336be308a7ce393a229836f765086a6709191878570c6919d825e6c2a8f3fb9b4689079ca814759a8234b5c49c19623ed637859b991335672e168b7a31b788667cb088c4da1a64319824f2002be6d942c3e4891b032cdd347361352ffd3022f68017184110507017243c68906425c883093ca944ea118b20a30e05f740fb86c96742cab2c086c4309fc53760e77a8500fc6830ab9fab96be00a319615905325103113956e233728a8c8755789f0b0b5f6061b320f0c3217415eda617d33758fda34c0acc07c4c46a7c457ffb2ab6962397e1349325a90dbee0aaa5977047549f28873e034aa770064fcc40c069166061b5ad66277320e989712a30a8969882e275b160046bc80077dca73b307d71979c55731741e916657a1a46104d511b7bc8378b833350be93c3015b68a8c651b960238853a294853d1f60a32d016721c25a30542367426fe2a22b45945a4c61117dac71cc04a9ddb9b86a5b4b25569a04a19d28778e6fd27ca9763db9e4b40a773b1fd53dc0466ca2086a561969d842310e5bc14cfc22fd3a5b4a969800e036e47c9f07b3aaaa0181cd8cb43b11534e267751337bfecb7ac19093bdf18070e37b3ab06ade8b14de2b34ca99763f575e8d75177c72522c6c4eced8ad20ac6bfc4aa329e765f986579c373a3a333d6167c2c7440e8f4131ec305188c989140b63b65019f2949c81c36cbc45939c026a42a1554f2385a738a229534cc6552d5e76076087c9e5b260baf8724973b9152b3941fcbe19227bb7987d74856d3636049715beec638db8e3b1d4e3ba2a440b46445369b60e0ad3c9c07c3203e2716ffa51eb5005d1a797079089f6e14d86d988d7f960f0dcc553a83f7433be60a463b04423a6977599b7c1f7730265807b3f7b2bb8a625e0b0a0f3f1171d6c4e7a9a6cb5803b4871501453ac19b576364c3bd7e01f1bf475a9e71d557171e4d33bd3d14823672f27e356c89395c1476e0fa065dd168478bb710394116de27cc3b0617ef5b74ac718e8b8c152c052a4d57828824af38807d91295a0da9b49dcbda052317f5576e52b51eca732d8d260d08832918094de65ab48d3351b1327568574dcc82e3e8a222044984649271b3b45861ab6f5250a770b59071309d118adb32322739cad7227ad2b3460d156c065713f29a05ec48bb21ac7261aa6a0f3f19d05f0aa577cc8cad6a7fbd25826a3cc6ee225c1b183d8e124055414c54469e4e410828bce94a5cd95e22c7ca3770ec5a023f0656447621006929174850c786fd6357f36188a4884cadc108485277890a0114b4c565747c4165196e3e90cfa659662d992c33bb2582970ceb60582a691d66174952841ac5a64e53b31566671054486ee20437e245e234176ebc696a55a53308abf020b40b944cbf382155ba02fb9ec298aac3c2b81278772c9e0c730ab13c6f374ba8c886300831adcf9ccdcc566e2456bef479f4ed08ef803ca8719c382dcc667a21897db1f81b41521790ee233020f3301bc9910dce2202bf4329f632542f820bcabbd2bf38962e6810bfaaa5377a83b10a62495029e99c4becba9f0b3a54f70788f97ae54f01781b8505c27c23b810ee9c7452952af9339c4ab88aedaab3b9f951cecd828daea0888a3481ab39207a6851c0285226136ee392996c41b7d93221df711d44531c8818bf3b71aa65aa0a3b5055634699b007a47210e9583928ea984c413598868bfbd021cff817c426caeb3a77c9067b04dd3cdaf2b840af6a44e5a5ec3956b21697cddcaa035c46159262524e55f9923a5c44c1c747a1e35889b20ac2ecf5883577c0722316d6a82a88b21c8334ba25a442101b6828b10b1d9280f13f867e10c88ff3cce3af457a4ba82ccc4c231ca991b79c66be0c56666c80656845789b45f0606539149cb12b0917b297fa683031413d3e89d3e38544ec40cbf288320bc3b812311ef69125e641232322e3f1ba325b668174179e38868bd50233c78b0cd8721acb23b0b065a13f36a2b8b8245095cc785c64997add4a33b45e9a602b10edb318830a046d8f700b2e76094228a14a251e8f48403914cfdcb9e3ac0795f907cc592ae18d322ebb882a1473ff2fc666b7a829189a4910c60f8b1193d59515280bc5a9169ca6433c4e560db8ac756944fd9ea1dd1a0c9f9f57a474c32b94730460046251aa7d27a9a3f2c617816386207449d8c18f04537084a3f464b737c1a49e59c9042876e0556b92139225fa3aadad3b5f18752dd614c1fc200923c0e0b4804fc5b26f7c6cdcc684da00289ce344518c7a480936e46ec4c01b36a7f2645074b26d0414fcfc46d2ada8fbdf1c50c128ec5d2abe11ac78205310ac8aea724a117f00246046c4360662101b191228628383cd9047a28025cf8d6a47dc161af353e9067ae4433803c48b3cde24466d00aaf68be2eb1a209e8b1f6264fb14873edac70f834c710acc18fa4c6d16a627b03406fc7501ef71e62963e01869c80787af2d96a4ef8c72d273a3318c2826b8bb513bb2f6739648666af720fbb4b7785c853bc1aa4cca2c9d5852706b7bdde4c06c78c960265ce1887b5e13275f42377447751ac0bc811e26c2f65bb19e058d573a64959bc0d74727a4b5ae8ba23f2179ffdfc171563712eb028d9524af43c6143277bbd537f1155b04c0006b66036161472a199764ef7283e044c62a7244593564b15436b435da9e995fc803964f631f8332fc8887e49a87c5812860cf96747ec5891a9ada1e769af720e946c9727731449cc7179f73e867c8a63b210d73ca9f8d4eb44b5da3b57dfed46bd22ab85b9bd9155568513eaa3de494e114c2700ed07ffc1c2f8ef741765e8a42579da4946ae0a201cc95fa08ed106ce84660e8a4c90bd2b22634e40769aa0090a101c5dddad45edc5" +}, +{ + "dz" : "dbacba825728444921b227cdba54446b3f6881b47be9cd02832f78b023b1bee0e15274a8e2bc08fe818b117ba28c5dfae74d54fcdf6f20052f79be333edc8dde", + "pk" : "cc9a64734c470128056a7b5d374435c099752edca129091770d6af831ac7805a7dd5657bcbbcc9d751b140283a2ec533c17ba38a392bb98421a4f0731390c30a8701c1396a4c17cece6cbce99949d0279119e8790722b0e2c748348a8a5a7c760826bbc0d395313b893a796b9d572c10432b2f5363b9682a89d1174f822bfe38b05ddc5b68ba3ad62497c3ab8ea6d13b11a6a69ddb1f1340b41f013952da1ee1e759d2d5459a01cece819e5de09b8d707c7d59519369660306c4174505a51846d5476d41d00393979293c1325a1b6673f16c32550529b21121e95f99f503cea88530e2c72b038aa641327181673e301dde28b0ba76b2b88453d1812499681cddf932370c864bc6205b6cb13684455fcc5e008bcdc16597ed661b3732a60e329df82820af51b1ba4647a7944c4dcc7a8f1bce390c44a9a7221e0c0943cb4ff6f048e2362f89f4113fd3636b97919e41acf042189e02a83b580e5d4a996fec6d6b7b33d690825f366d89f8952898152b3671685a22d8898bd62c83c32a1e3076aeeae845900ab2cfab51ea76c3022b52dc702d05b17a76609c88e69d12d7694edc3e91420737b17bb6844a1a28c0c756038a8c6c6a74906232b50d74cf532b5266d32d01034c56aa898d624727e5363e0bb300203e792b3afd39b5376998142acf52f6933a594c9a5872ab619a8a4317e86a91d419a78d47245b1780bef14abedb77ccb97d550ac223e5001e0b64a61b8fa0526331b409505a512b4b6ba7e3b4b630a112920b431292db5962b577af8d546b7465673a8641ab5807443085a9f0849b914a31393c1dab0fa30b3b1c1261bdc9a8ca69cc0f0432e91c1d42b6a8346cb6fd9cb49b189d125c8be422a690dc90ed4a87c70ca8e35caa16a35a3120b9716bae021c861267aea4244219c60fb1c788ce8264c0241156340daa3b1ae7725c6552cdadd4c244079cce22aa083a1a2c0810fc7ac55d77bb6ef934fb73a8e8f4cc299b28c42c5d26f36518ba4cd3b320ec3158b8b36108bb6d4f6427dc46653ec24927a833853b4b0af5723d8a3c5f37c17b3476d86161c57579cd020167a70c1c310325c6707fc82270f0c73d552363e2343b371fc1448b2770bfae474707305a9b32a6aa77c7fc7715cb35826bfa1696d67ec48cc0c9554691d186dd025ead64a9e39657be0292f39829ef696d3584b99c7367a00034395252f2443ef4692c163a5ff1863be79273a93192d10b661b9051d57572d5caa817338c52374ddb282d4722b1efac7339f1ce852867e4ba2a4d368ccfa58fda097fc59244fae273aa7c63f891bbbce875624800dca2b5d65b5a2d414a81c7525583c0160a006be08a68776223aa97525a1e97b241f59c0dacb50ec89b90bbd58e8f27c9f19729782b2c06bbb91725c3b6ca991e75bdc7850a0107674fabab38e28ac5b9b717ca7542ebb563d078e4c856447a0ac85c9240d77210e4ce850570ab693aca497819b5210e2cc957fa9b4542070171c56a2c1253e006cf12162e9168673a08d82b90812c8cb989394ca862aedb1ad9885598d39a42b3ac25bc914fc15eda2501d7c8c51aca0c257cb8b0c16de89900b2b12a875116cfc967553829e59510a00998440b93d8371a0b294aab2b4697196d397a9ccedbcb2f5414dc8c764189cbf720834327a9557cb44a90286277c54aa424d080822814626b753cb281b9f2fca8680c2e197bab18643c9b0aacf8445618a45814389466f67a5c557aeccabcf083cbdff5569e39cae20584ef46bb56456386f3c7ef5a5c196c51646b69154393bc7a6a6d0869e06c3f8ababbd7aa070f974e682398508a356c78c74be8108b42c6b53744c3742f16c84e5bc6750546739acbada819a2af9c5bbae2ca34f6215df82c10ac8a5873a2a8c04ced887730988c14f00a33821994503f9e3555f790715414095f05bc7d5c20dd9313acf98b10daa4053c90f3d2c0dcc676dba1cc0ec92427d4bbf61425935314494c3e65b266f16411a1250667954388fc5b750270e00a8bde873d3d58c627c6b31d8610597174366c8052f21e429c185bbc4c080122b4b25d00a982101b4b44c18bae64b7aad2a2bf646e39bb241df17d8c5b42db08ca0d6571097250072420ddea731357154e861809fcc1ceb7ad01d843ea928dcad3c1370b6b517f5473b94bd6351e282f01bf82a24c3ef05658b9e66735007b45f5b008a7bd", + "sk" : "1783c5f7f498d7d8c421436701176e6349c025970f41744b369852a6c2cfabc9096f48706a702d3ae62d6a2c79e068143f45ae3d472180c432d6ac6897633982806c87526ee2f837dea521fdc3c3a473a6d7405c2cdcbd1d99142d097ec5ac782cb80909b9c47b7a173922cceb52c926f4b5c904c5f342c460356c72751baf271a496ba3ded912e6810b8f498e78b194a02643b855aab4a6c7df2938a0da001c461b52829cda688aea4c21ccc478c04923406acf8a7b72f5b52cb091ca66d769fdcb2d2cf220c3eaa73db7888cb37ebe441d81d0b53bf41259433922a1c6df57062c2a010bc3c190e7c19157207d1b607ee33469334b3ee4500bda58a1785b2c247410573d6d703d822149a5ab5a4e811516b69d76f3a80fe8b84fb8ac7f3568cfd69521036541e975e5c09f63905e571531984921f9c159cc2964541b0b55860270ac7795f0c26a3b9fba603c26601322ba61ac86722b7933edd01c68a292c783a56d55c0254439e936af5b9970241c73a9244a271a43cff187bae40ef9cc6d47f23f3b68cb4ac08180537b16daaa329345f17102bff856891ac52e25bae2e95ec2ebb21b9330067091cd7b0a963588e9700b89fc4ea40aa6c4a2c8b63568663b8c2ec9ac281ac3d470098f559f49966e01a91631f263b834a19ae5b3d6d150509815684c300cd483c3fc475b324c8873bf5cb01609b58bf573cce0034b19425edca86c598aa4da9bc4ad2cc78545917df6962ba4ca06b0bbdb322fe300984e16b982773a0c1a1bba55a14f575150484f2be11ccdf97846a33aa8580c22aa647b7089a73831651c506045a05e785c1d682a0af364b4cb1fd704b1c306523d6a7394ab1abc34719a0c97f49cbe6ce9519f8b03556cc9c72c613e513aaa68074130456f2ac4775218f7a1c35ee07f229a7d59994f6b909c381a0385c2a6d1bc8d7a60a1a113442de3cd785b7679230ca6d49d17f2c7fcfb1fc2e7121e20b87cac2817e26854c392dbe25b31753db9c5923879777364530c4551c28a3a5d83c9631008571c2f889889e8c835eca3ce30e81c03cab74b3b5b198458f0f81cdfd6ce88e7cb79f704c0159b83345232541cf4ba04a1c2c2a929c3687996d25ab65fd9a93cc6590846a861c5b72ce4640b47673e5a883d44162f914a318a163b5c33c37a6330f34b28b22aa639978598c3c6ac93d811c60d0330ab500d41f950e51c9fde115619f022f9e88f7892ba41330018da306f42bcbc8cacecabcdb0e5085bb687fc14c55ba8630df92c3a2b7867e951f3ab12f8ba2417a70f766c60cddc85a012b60e368f7c75a6102684efb14d21961f2231c0394520ea813eea69465a8a8582e89beb3aabb9b42fbee8bbd4900ca52247a322837d58c9c7b0a9e5d246178862253c7baf2081d7c02367956a7a68554debac141c634048053d602645a88549b94c95d907ac1c02058c66fd5b894222331952c4e214ab1331a3b2a83dcbd8c747431565026ffb231e9835961919c659f734c665636196aaae827bbe2c30f736384f74cec5ccc3de622879f6afd1a0c472509f9460b07e524bdc65cf605a36ee35cd6267403cd91b8ad8376c670c3be6b4ea42c3cd46b275b9394db41e0b389642461d443ba0163b7d7530243b911a64a27560e3956f18744a673606089fd611c9b5d4b6e9a5c0927632b259056d95235ed5a0490435127405cb164d8b0540bad0b706a431fe077d2e385e4b64beb3a8527c1921d119c6676bb4e59937e0600c07f0925d665a9b643e034478def83188f4caa30764394a3fb0c3b9f4c2243b0a53f8b2ccc5d96ebb0478201cbc7e165fefb565ea149bed831df5dc4df16531460a28c6e708a7686f61101d327a88f998223c9abcc7d22b5ef78765e075ae4aa41730c3d507837080c4955614e88826ef4a8dcffab0bde615673150a7f36ebac7bb4c793dbd9a11f2e765bbfcbae5d2ad2239ab9a2548ea20c47458b3a998533df6b3900997770153c73955d200656314b90bd49d6d95407302a67813a62ab3b63d61b9a3195effcc87d6ca43cff278bcc65ee0bb06c3da296a117b3cc86c78e29c33748c0d293e243c25897b200f3b2d7a5b96215822d310805a35a331615c59172709baa171d947d1b12e2c2699fb460b8219992fa09d529069c40138f24cb4cc9a64734c470128056a7b5d374435c099752edca129091770d6af831ac7805a7dd5657bcbbcc9d751b140283a2ec533c17ba38a392bb98421a4f0731390c30a8701c1396a4c17cece6cbce99949d0279119e8790722b0e2c748348a8a5a7c760826bbc0d395313b893a796b9d572c10432b2f5363b9682a89d1174f822bfe38b05ddc5b68ba3ad62497c3ab8ea6d13b11a6a69ddb1f1340b41f013952da1ee1e759d2d5459a01cece819e5de09b8d707c7d59519369660306c4174505a51846d5476d41d00393979293c1325a1b6673f16c32550529b21121e95f99f503cea88530e2c72b038aa641327181673e301dde28b0ba76b2b88453d1812499681cddf932370c864bc6205b6cb13684455fcc5e008bcdc16597ed661b3732a60e329df82820af51b1ba4647a7944c4dcc7a8f1bce390c44a9a7221e0c0943cb4ff6f048e2362f89f4113fd3636b97919e41acf042189e02a83b580e5d4a996fec6d6b7b33d690825f366d89f8952898152b3671685a22d8898bd62c83c32a1e3076aeeae845900ab2cfab51ea76c3022b52dc702d05b17a76609c88e69d12d7694edc3e91420737b17bb6844a1a28c0c756038a8c6c6a74906232b50d74cf532b5266d32d01034c56aa898d624727e5363e0bb300203e792b3afd39b5376998142acf52f6933a594c9a5872ab619a8a4317e86a91d419a78d47245b1780bef14abedb77ccb97d550ac223e5001e0b64a61b8fa0526331b409505a512b4b6ba7e3b4b630a112920b431292db5962b577af8d546b7465673a8641ab5807443085a9f0849b914a31393c1dab0fa30b3b1c1261bdc9a8ca69cc0f0432e91c1d42b6a8346cb6fd9cb49b189d125c8be422a690dc90ed4a87c70ca8e35caa16a35a3120b9716bae021c861267aea4244219c60fb1c788ce8264c0241156340daa3b1ae7725c6552cdadd4c244079cce22aa083a1a2c0810fc7ac55d77bb6ef934fb73a8e8f4cc299b28c42c5d26f36518ba4cd3b320ec3158b8b36108bb6d4f6427dc46653ec24927a833853b4b0af5723d8a3c5f37c17b3476d86161c57579cd020167a70c1c310325c6707fc82270f0c73d552363e2343b371fc1448b2770bfae474707305a9b32a6aa77c7fc7715cb35826bfa1696d67ec48cc0c9554691d186dd025ead64a9e39657be0292f39829ef696d3584b99c7367a00034395252f2443ef4692c163a5ff1863be79273a93192d10b661b9051d57572d5caa817338c52374ddb282d4722b1efac7339f1ce852867e4ba2a4d368ccfa58fda097fc59244fae273aa7c63f891bbbce875624800dca2b5d65b5a2d414a81c7525583c0160a006be08a68776223aa97525a1e97b241f59c0dacb50ec89b90bbd58e8f27c9f19729782b2c06bbb91725c3b6ca991e75bdc7850a0107674fabab38e28ac5b9b717ca7542ebb563d078e4c856447a0ac85c9240d77210e4ce850570ab693aca497819b5210e2cc957fa9b4542070171c56a2c1253e006cf12162e9168673a08d82b90812c8cb989394ca862aedb1ad9885598d39a42b3ac25bc914fc15eda2501d7c8c51aca0c257cb8b0c16de89900b2b12a875116cfc967553829e59510a00998440b93d8371a0b294aab2b4697196d397a9ccedbcb2f5414dc8c764189cbf720834327a9557cb44a90286277c54aa424d080822814626b753cb281b9f2fca8680c2e197bab18643c9b0aacf8445618a45814389466f67a5c557aeccabcf083cbdff5569e39cae20584ef46bb56456386f3c7ef5a5c196c51646b69154393bc7a6a6d0869e06c3f8ababbd7aa070f974e682398508a356c78c74be8108b42c6b53744c3742f16c84e5bc6750546739acbada819a2af9c5bbae2ca34f6215df82c10ac8a5873a2a8c04ced887730988c14f00a33821994503f9e3555f790715414095f05bc7d5c20dd9313acf98b10daa4053c90f3d2c0dcc676dba1cc0ec92427d4bbf61425935314494c3e65b266f16411a1250667954388fc5b750270e00a8bde873d3d58c627c6b31d8610597174366c8052f21e429c185bbc4c080122b4b25d00a982101b4b44c18bae64b7aad2a2bf646e39bb241df17d8c5b42db08ca0d6571097250072420ddea731357154e861809fcc1ceb7ad01d843ea928dcad3c1370b6b517f5473b94bd6351e282f01bf82a24c3ef05658b9e66735007b45f5b008a7bd627d8e894a4fd9228571ecb1041a11f23220b1b83a46d7ec32691ec9bdceac14e15274a8e2bc08fe818b117ba28c5dfae74d54fcdf6f20052f79be333edc8dde" +}, +{ + "dz" : "690eb71fd7052b906eaec09937a8ed374e0b02afa27c2f14399932be5839fad281c38c2cb5cfafac81b96a810ab749b61806b6d54c9f8cf4bf1be0192423288f", + "pk" : "60c06a2db222a10a620d78b129042477537aef90b5f0f20a58b6005ed0234f3168ee927d726733c3221035f21dc2a95471fc5aff57381741c9ddda97273909ec4c68d4b2a22019cc2d58b0f40860cf429c20757c91269979a17e5d01aedfc21d3706369c3294617628bb97c2655656301772007414aed6a9113ca543f9b027b2aaf0f122d1747a800a49da48239eca99fd4443566348a3f8142c6ca511e769cee83d0513444e7778018211f3a683ceda1ba2881a37f92586a54806858058b37aad546d48b4a5f3e6289c237a041814c0531b27045b8716c1ab1566ae22bb1eea845340791e2899020c8ac1d6724a0b8b432222b204b0b2ac55d924b4afa5083426c716ca2de71c99687748b56342ed726694ba5e63e42911f66f8f8b3111261ec39bb3dbcb9ed5c729b401a23aa26015d31bdf8c8301f61abe695066eccdee028b11322aa437c26a785899817893cb321e0b72e7a7131410772799500a116f612838d7601f66f29567e8a0f0b7477114281df703ca76326b8aba041457004156854c1b81092ffa869eb46807e6a1108ceb06f65453800b72ebb4613e2c363b6190eae29735d48e537a717e335c9f7b456c923c42a31b8f4b4dbba96f59362743d516a01400b8f1b3ea71954f85b0ccfa751d3428fecc2663d509c8b9a211c011313b5cc8e8930b223d08c95e5eeb47127a4bc5482b0e871a758893e9b64bdf4162332b8da6d7b29152a914f5c748a404fd865dc1224e0b64cf782b7c866833dc8773b20c6eb28ac57cf5166895cee2e78d41f97b5eea14400c1d329363915094bd5650377924c15c86ec833b0ea0b3e476aa91398c108a6e99e7ab64990513e061ca52756cf29238564cf0cab366f8753aba1fd3e9ab70621a0cf161b398c413a39280a268c1d28172d6501d313ed15284d12250e6b75704d1950bdc5af1959bc3e93156346dd3b47450f758d3e9796cba90598224740b33b239b97c45c696323a05cb15ea44ca4fd98ee589a2f5aa1d1ee00a476533d5baa58027aaceec151c9c5eda23b14367b8bf7571e7c75d197a55ed3a349de636bf84ad6d446e2c3ba5657c683622b136384be3b89c7eba095a89697b4c8ed9215d1e5544f3d957e51a86efc098fbf272a6140a17530ef6e703f272792371b7c5e36a83c61c7ec18e6bfa7752c095639420968b91aee627c3ec575d74b49fe13f2a216c711508a4ab1fe84a20bfb019aae1b8b3c8750edcbc30cb47ab0b567720421359a0c8c08295ccb705222141b74b8361004d9c484061aef8c19de9f8c809b90050f3345d65531070cd36d5b2e50047b97b61cdea5c3b896dc0a22f6ac2a2585295ae0993be023a498cbabd6b37d56c2f8db63804d0ca52a169f5d003efe695b6eaa2c530773cc4347d4b9e0e46a822a980a9f4c8900070c67437576c572160ac7b297bdd074c9eec3a368297f0a34772b8292d0b7a29faaccf7bafd2dcc6999b0766d106e04a76bc9118b7875c187b1f8cbb00b3c882f3bc6bc65b294443610c65b19aa72f90c7086ec18f228c36d63808b0aa253052c1a44a6842568d82b43a994b5b6c69555a449ffd0c3959870f3b679e4643842083b20a40401c51898e138a092ba393bbaca9fc6f37f28d88560a7992c5b95c228b3388a622a6f2839da96b121dda0c75c0b36ef162bd7981ec294ba7f91a97b34c69bca54c2b7e91548fa7c396f3d783255a79b3fc579cb62eed83b430c45377857190d06e5a26576d92af1b79941f922bb234a68b21309db9aede9765c78c486da51e400cb46cb586c33c46db9ba99b983b94815fc5b52b7feabe42b4253df9cbca4037819a47f8541bd5747ccb34ca74158318664b243c81b85484bf050ed3aa81ff37725f29b962f901f5f44b4768cd9db394fc7370d0ca72e1607f83a0cd82793ec3a23d3510ae6ef3375c3265dd8268b3f31bcefa83f8e5aa3d1077cc62a8ed858e6ed4639447aa3d705a1dfc4cbe7c4b74d67183a5875d24552ae74e546ab15376ac54f0582f3a92a1e1075cfb682a16b6a46ba93f31165f32654838c9e14b46476465cfe45bec653d2c0a1cef96cf01e123f1a3116c93b1d5e54730dcc5f9d618b53a7917a71abbcc312cacb170c10e454c41869717afd8aa4a86113ceb654d582af443a0b6a74173f963d99c8d44e5520ae278370855c0e9e01df9b37d13e35124e6c2590e9a231a219c07ef6c", + "sk" : "214a365e155f2468311a972eae496d188b7d7ce281b8dc49d326c2935829652b1a8e936030ccbee7989dcd407dc74a5da47b7387674310c37da58c0b9474a7dc5a5f97763211b6208ff9b7ad343b0c0b58b5c3b2e95210a2844c6b013d5c3610f71006e8c806bc61a90071bdddab9dd214cfc9f6501f6570305b5f03c38fcdd9516e73b76f5b6bf2b7665c70c31d763a1721628f73490402c8a18ca4c8f42c8a95b81e0219fc0c66db22763707c44e555924fa385aa212d4c643e6f51234728b47c37e67f2bc559c92b5a6248e9cbb8f197dbf4221e8fb938a4881c22841076c2c2ca6b5798b5991623160148a8de9c4c7667fc4ab2d30b8917304011015400644079be43f60f07b8501957a53a0acc69520871013aca31fd4b3bc246f5e300d8e84340927a645532b251945a9ca024892b0bab4769f6c27f497206d1598259aa0f2d649d560c082b12cb1d851d757cc38e1abd7a6c38a947b36e95579da29a25765f2d85d5e5016e0c91d25c6a7cac3cb4d504bf7046b7b32646cbab6a3eb8fc1ea63016c0cdd74cf63b8c86b790660c94110e4c6119736af99a75ffc2f98c7cb0ac653cb90cf69978e0859c610362b24b14c309476c53b5dd058c4075c59c2c753aa76b7e04520f2250319d41c6c6183921409908b6df6fc8e7d17296a9a0826101be7450ab3babea3c520b6735ea8d545949988baa98f7a2684f3b3c62e058b398a21a5f5073177798d1c44ee5c94ffc564357718b7fa59e68610aaf8294eeb0619502cda583f0a744d8a03be0a6c9d6f756070dbba4ef85ad8711bd691b489a3a23332a6e766c79eab5644e42378ba05b9ab0eb6d790ae65c2dbe3620c26783b8a11ff59850ea182e6258b5232833b4538eab3306023b2eb01b2ea157571791d0d37c6d79c2caf1601528b6fc1600ed3db72e4414822051b469b8b0e962d94c1672e318796e0cd17fc5df12bc1e7f6b91c5a3449c16effea06999bc5344c19b5d36466d18f5dbc56d7065a924b4f128639ee5acc2e37c02c5332e2919c1be01e799c27e18bbfb7404c6299b2335b6b410c4cf28474eb6ca8a4859f0a4a587ff6b356fc1c330041c72765fbdb1d2bb779ac384c53f77124faa473716047d2159a3326798b0d38c0c77c4568d6450a0aabc9780aa2b3252cd3da838094a867ab89e12c342953a3a0ab33bf6b27d4a0758c248dd9f2b0864c08d1083e32031283d979ad81709fe2466e7b15c7cc4429bb4d96b2733aec85eefac633f626edd8cc64114572608408d614e3c0a1473c046fc5405f46bd229b30659505094a312c170a0c21b33628a220a281637b3909d418268bcbbd746df44c5e94dc5ae6db45312b05f7c99985b3423755c17f9acbd7d831f5c3aed7f33284745f09e0cbd0f4b841fb84fbb6cd190072773388a334cfbd05a45468cdaa249ab02c4394c264c276be8ca164873c5d4e035b043c86d8a09d0aaa3e7f983a9cd3108f56ba545847ed27c29a1a84bb11310e556821181c4cb79b4abbaf3c123053f9c92ca15f6c326e2fe67f24a20ae584bdfe763db45ac37ca8a2239394cc86ba1ad976b7cb41b5304cf6eb23a5b8456470237731882bac17ba241cee78b740ab91a3b13b716634cd55c4faf9c80da43b43e13e770a90a9743f151958a267a8a6622bc57aa51ec356ca98034f836f6716840ff98dd190a6bb509d000211ac802c80bc3b28ec20c7407cb898980ef125b0fa34a88812550477dd267d37495930cba3f9e43f920a42ddb34eb7b72801fcad3000aaddb473210436e5110efcf52791c9593607bfc6a440a8043ccdd9965099a200c7a4aa93944bf7ac55132efc367aaa358eab042a6bfa125e19759f469ee054147c58adc98991cf92693708c75534a13e125b9a0540e423aa29059103c7708edb1cf626a95e2ac9e34b9694325e9c9546e7fc566a013128c2ae932690447a552c2bab21d249cc6590a1fb05ad0cb90edb8b7074bd7d172b1977581cc0840f1a69cc0abfba1091927ba9cf7821aae3295ceca3c20c018c3590c4151c0fd13958890195e761fb0c5bf8d1caa0b57087997e8495c430373362a71dcf670e0b1108ada374dfc08b57a0ab687a7d5b8172318c0e4fe868fd68a7da773dca08a71a49a4ca1b45ee3b223b785f2e6b0dd195ce79a1cb36751b60c06a2db222a10a620d78b129042477537aef90b5f0f20a58b6005ed0234f3168ee927d726733c3221035f21dc2a95471fc5aff57381741c9ddda97273909ec4c68d4b2a22019cc2d58b0f40860cf429c20757c91269979a17e5d01aedfc21d3706369c3294617628bb97c2655656301772007414aed6a9113ca543f9b027b2aaf0f122d1747a800a49da48239eca99fd4443566348a3f8142c6ca511e769cee83d0513444e7778018211f3a683ceda1ba2881a37f92586a54806858058b37aad546d48b4a5f3e6289c237a041814c0531b27045b8716c1ab1566ae22bb1eea845340791e2899020c8ac1d6724a0b8b432222b204b0b2ac55d924b4afa5083426c716ca2de71c99687748b56342ed726694ba5e63e42911f66f8f8b3111261ec39bb3dbcb9ed5c729b401a23aa26015d31bdf8c8301f61abe695066eccdee028b11322aa437c26a785899817893cb321e0b72e7a7131410772799500a116f612838d7601f66f29567e8a0f0b7477114281df703ca76326b8aba041457004156854c1b81092ffa869eb46807e6a1108ceb06f65453800b72ebb4613e2c363b6190eae29735d48e537a717e335c9f7b456c923c42a31b8f4b4dbba96f59362743d516a01400b8f1b3ea71954f85b0ccfa751d3428fecc2663d509c8b9a211c011313b5cc8e8930b223d08c95e5eeb47127a4bc5482b0e871a758893e9b64bdf4162332b8da6d7b29152a914f5c748a404fd865dc1224e0b64cf782b7c866833dc8773b20c6eb28ac57cf5166895cee2e78d41f97b5eea14400c1d329363915094bd5650377924c15c86ec833b0ea0b3e476aa91398c108a6e99e7ab64990513e061ca52756cf29238564cf0cab366f8753aba1fd3e9ab70621a0cf161b398c413a39280a268c1d28172d6501d313ed15284d12250e6b75704d1950bdc5af1959bc3e93156346dd3b47450f758d3e9796cba90598224740b33b239b97c45c696323a05cb15ea44ca4fd98ee589a2f5aa1d1ee00a476533d5baa58027aaceec151c9c5eda23b14367b8bf7571e7c75d197a55ed3a349de636bf84ad6d446e2c3ba5657c683622b136384be3b89c7eba095a89697b4c8ed9215d1e5544f3d957e51a86efc098fbf272a6140a17530ef6e703f272792371b7c5e36a83c61c7ec18e6bfa7752c095639420968b91aee627c3ec575d74b49fe13f2a216c711508a4ab1fe84a20bfb019aae1b8b3c8750edcbc30cb47ab0b567720421359a0c8c08295ccb705222141b74b8361004d9c484061aef8c19de9f8c809b90050f3345d65531070cd36d5b2e50047b97b61cdea5c3b896dc0a22f6ac2a2585295ae0993be023a498cbabd6b37d56c2f8db63804d0ca52a169f5d003efe695b6eaa2c530773cc4347d4b9e0e46a822a980a9f4c8900070c67437576c572160ac7b297bdd074c9eec3a368297f0a34772b8292d0b7a29faaccf7bafd2dcc6999b0766d106e04a76bc9118b7875c187b1f8cbb00b3c882f3bc6bc65b294443610c65b19aa72f90c7086ec18f228c36d63808b0aa253052c1a44a6842568d82b43a994b5b6c69555a449ffd0c3959870f3b679e4643842083b20a40401c51898e138a092ba393bbaca9fc6f37f28d88560a7992c5b95c228b3388a622a6f2839da96b121dda0c75c0b36ef162bd7981ec294ba7f91a97b34c69bca54c2b7e91548fa7c396f3d783255a79b3fc579cb62eed83b430c45377857190d06e5a26576d92af1b79941f922bb234a68b21309db9aede9765c78c486da51e400cb46cb586c33c46db9ba99b983b94815fc5b52b7feabe42b4253df9cbca4037819a47f8541bd5747ccb34ca74158318664b243c81b85484bf050ed3aa81ff37725f29b962f901f5f44b4768cd9db394fc7370d0ca72e1607f83a0cd82793ec3a23d3510ae6ef3375c3265dd8268b3f31bcefa83f8e5aa3d1077cc62a8ed858e6ed4639447aa3d705a1dfc4cbe7c4b74d67183a5875d24552ae74e546ab15376ac54f0582f3a92a1e1075cfb682a16b6a46ba93f31165f32654838c9e14b46476465cfe45bec653d2c0a1cef96cf01e123f1a3116c93b1d5e54730dcc5f9d618b53a7917a71abbcc312cacb170c10e454c41869717afd8aa4a86113ceb654d582af443a0b6a74173f963d99c8d44e5520ae278370855c0e9e01df9b37d13e35124e6c2590e9a231a219c07ef6c49cec726e5bc6c6280269fb608e754d097ae818b16b386bc895af3bb9f5f2a4481c38c2cb5cfafac81b96a810ab749b61806b6d54c9f8cf4bf1be0192423288f" +}, +{ + "dz" : "32e0ea9089fa928482c0770da545af1bb871a03ce38604138b0d08ea2a10ca2bc06c5bef7b6508409daf847a64c8d30d0974fd3ba7476dc76c46b458a036d884", + "pk" : "c75c9083566b23acc2e981457fab1306b04340969dd1081f074a2a33bb85b892750bd34336a68362e00302712410eb8fc8f37da6530a408b17fddb0fd602c2e40a7dc4c94ea843226ca79b167b180f3024a273c57f91cd69629c970617720497c4308e10f03a038544fff13a3afb83fb2291dbf177a003b0197037a3c9283de78dc911beacf30e6c4c6740300266c6ab69893aa9e112b67903df849a4bd59ba106030b62b61bc293fef997a8851d06c956631c266ad533791124a4e09bdb06c0ffa681cf2c6d43670e2a017b9a40c13e85bc1c24ad914003aa69439d401ba605d013a2baa0e0b010363574b71242745e9d709a3ff3b0a2ac7f374684bce9bcf0200db5a09b5d0c92cdc7bbfb3c24a79a8a4a0a9a64376a0793c1252362af170856046471b1a60eb33f23c59122d0aaeda79caef27df971ac8764986cfb2617fc3bb71355a56867c29795f46668f8166970b06c6ca91d8651ccdcbc23fc1b2f0a75c45fb3321151953315036d52322c9b6408152bbb595129f41a8b8570f02b8ccba66de5fc36d892457673a9a096c556c9afd11b06e1ca9cc8b3a9e9765e38e711d039612c4bb296061771e42efd68c9acc8ca61012f295251ccb33252e8b0e6486c5a5bc28683347571b8f0a42aec4873cd3549324ab728324030196035b29ad3043ab9008da6b924bd376cfb103fcbab9450b44c299b4e27165303786944009418cbc66fd9a570468dd85ab652d86402501d61f5272cd880056521f72a362170580675bddd505840378d96334a704282934527f70a499ae99db81516b1d1426d233dcf9855880022d72100e14858c0a226325338b33ab5ecc5a86e0ac4e8504e168c5e1a4788177878bd569d49dc60b1484f43134e2bd39efb207430aa564ab7a88cd40ecc00a10e4b6c663b61a6054323429c0722b2e4464ec0d43374234b4884bb8ddc0a28852600369635531ff943194cf91937b43afd418f8f964cf9c9cc66988407bcc7b5247a2372980035c8f8357bc3db948c0c4b391ab47636024dcb79f094c62ccb64893c0c45c1bc88cb00ba85248253606735547d424797b0bb302c5eb9631ac98060bc47341e69379bba5b5e44980970c699187f62731f2b1a4bb4c7a33f8a20758335bc8a3c4c4c0900b3c2cfe35356a58aae233b066466b34c814a4cb6b9f916581b0361e78a2971bbfc014a7476ab2f7c291ba688d5f75153c4ad7ba4c664a8002058c9eb195a3ca7ab70638bb114c3618bac3ab383dbf292705a478a35c31f06a1823b545366cb6900c59c036b063727504a55c2ac940606c7bcc74643644bde915d83c395023c8fbd069f9ec50e1fdbc8edb0387ad1074b11bfdf220edd7486082a4842d6c737c6a1ed5b98bb78cd6de1153480b3bf095b04a7cbccc19102964e34693a6e492fae134c9d726e49532236018dc517bd94232d717a408af43fd5c837a21cca33ecc2a3859eaf8a74b63c36fa70168f241e2ff52f7197a615d04357a7acca269e47848375bab1f82ac686903d44786d540a496e29642f71061ee76054b5aa6ae67cfa01704b386a657a6773b8509cc1b4e16bbb92cb204b5bc6638cc5dd868db40358dcc4c258915d1e93771a12aa7ca4b3bcd854ea2a111c09afbc60cc91f5abd63ca5ccd11ef2c1b06a38925eb9a4bb569d8c4b859ad278ceb006a3d44328636809a31c377c58957aa5408b488445bf1fc4ca378c733e410e3814c4300850fffb052df767743468c6a91d81dc3c4c34b4b5a06dfab7cb6a741c91107758859f2e1c2d06881612e05cd7444abf23c104b6a068988fb794306e90aa1ad2ccf76482f0fa7067467dc105c27ea7192d0c6fc50b4042934e81876e121c6c295a5432219345bab9ca566f0dfb6b9d4728ab7187f311ba22d55b4047b9b3a17632925ec31bb2322257dfea3d1c1b4331467904eb2bc1f7a4369aab9912531a6835358b016889ac910a7c398c18a1636976e04c7227cc9fe13d61a848eeb60d56635064ba07359730a0c269ed6cb25ca2908f524ae3c9bc860a062192421cdba741dca98f98ae0d955c78d141fedb59bee95957e035d5b05155f5792e88ce43342f410ac92eaa68cd055fe28c4a217b9c2da4ba64d4a6605565d41a00acf377eaf80881d9a5305766747cb076149866504db6b96ee4cc9d4bb977165f0b04d3c03c1f8150a265215387c7983d37463a3136a1b7c6", + "sk" : "c73842b1f8a1f7cb343c570bfa701270595100a58798d235bad4ae8ac7376607675de7cddab1432f5b04fa1045af5a2644fc431c604a2c794d57b1cce958707e508c0ff80ecd5c001439456b65091bb75dae518b9dd5a28fc8c549e4450ed9b92a6c77c5849836f52bad941438672e06786cf16233fbbccb192b5c07a9a2eceba39571778b665df2b0c359206cbb34b33e215d1f8900bfc1bf6dfc69490257e2a533430a79522957d1677a19526a44e4bdac44358cd283e60376b8026a0d389912324b1f37ab4283156a913782d26d7696827fd55a2d636afc42173f86b03622091e489d55f74db20c846b0c27e7c1c0ea8729b97ca5ffe5296fe180aa2a5728f7befc320bbaf64c0e5555b1f35bf9203ee22478127122aeeb4a3d983fee5219dad3b4db5197ad079be2803491238bbfc003e2e22e2ff98f0e0b2389c83c7a30a870e63ab54a094b27adbf301526d04449b1283b02254aa2074a902e67b978c1ba92ad014c7a15c2f678bf3d1342fe588e4d7b8b674b9b92699d8b312fe0a64c0da1a7d93c16f4917a96f03e3bb21e400b3141b17f90d58a853445efd63e607cbb05036ed720c783f187aa897cd5282d64fc119da7882bd28dbc42ccd3c1982e1ac0b4aa1497dca5f764217a068acb73af404a5c8daa35268484666199d7761b1a802f5334bd1bb4b05c5501bf1c4a1b23a35e3341e7623f181546fd2c069f63554a67c0d85a479123680849a17ec1890ab616de357f16d14b3a75326e13ccecc690eb66af0216921043c31a2c8a44688b670a060006afddc6cd13898dd97214f405a24ea5990e06b55c278cc66115f8655d4d8381eb55a0655655966b3f2ca433d3c78fe3a0aa0e6196ce4b355425ae81434c27e47b73cb6e024065fe2bbabee99ccb8459e1ec8bf6703032330d402b2155765097f650681135a60c6fa2aa74cc1490dd22525a7a65ab853579026750bb5fbc645ab3c796bc798dccf927663c9ce82134b9536a9ef38d54fc421f964d4c20ca8d5b9a5795bf1bb1c3857954d91c27140528fef1c366eb41d78bbdc773b58b81420ff36ddeb3349375bf1a3933c7a865e2e16cbfec0cd93567b09b18c6d2c9dae2500c7b19e42c62326a279cd75cd7aca7e9b08c08a81087012f75e278a281c9c482c149473cf5f8965acc8db1b74a205103a89686bfcc65d40576dab5c33960069db6c390138647b5301448627fd1bdbf68abc6979a03f47651a13c098386c6551a89fb9ea39696a8182d390388b12070d4e378b70c13a4f6af1fb860b7f1a42bd1c8373839432609032224cfeb9ee0814e5ca4b57af39f84d53a4f9a7a311421c9dc7e411c102c207a34c2161c7099e9cc39d5908ded696abe32a97b8a297c28b868792305490a691291f5e73ca8163e5b9a17e8d417b2f14aeb017a2757653b6b92aaa73aff638cb5412f1508b9c7aac9439787f2883043660aac7294aef5694c3294c1471dfc49be531611ec7863fc4c2f58c7141418b285b209f6738e45d09f5956b44d6106ed04b59164287efbaa28a63cd80c59636896104261c10ca8c2c8603fba2b53c531cf7a8da7e3abada81507487c28b9bb07477e0241c958584e6047ba1119783d62c4cac3c4563c628a5503236c7a997377ad53b9a4ba153645933856671aacca85d55ada82c39d82280de07100e1cace49a6dd09c22f2c1da1077b9dd437d55b0d7b6978446a19ab106ce18529608c2ed283c9806689b0624dcf10c6a8665948250af74182d9023895a577c5eb880359a046ca7a15297b3bc3ad227972ba80061570a7c10bb26cd87f05736a492405b4267fdaaaab8062a5b10bb65ac597d8c5a5e123a0f242ae2470c1f0d8829dd73fbecb53076aa093b73e68e35a3bb649ce4621bbdb7c95bc0dcf997b83c0a65be2015a5465fc1273b599c7074220786c306f4717fa50936bb22417a2247dea1aef76895522cfa8b20cbd9c344047984e9b67985307e8f64a15813cec89b8b004c1d61a884b327badac95a14a2d2af1a7a5b5ca6e3722d150cb4be7a376372beb7a99dc94654f652780411a43e619c0643d266a8b1aab982080b1b9aa52e007b1eb6b76b3147b14785652b5cd11586f6904ce3a9554f745947ff27e87e2c6acc205d7689d908068608053387600c6aa9ba285738b9372c75c9083566b23acc2e981457fab1306b04340969dd1081f074a2a33bb85b892750bd34336a68362e00302712410eb8fc8f37da6530a408b17fddb0fd602c2e40a7dc4c94ea843226ca79b167b180f3024a273c57f91cd69629c970617720497c4308e10f03a038544fff13a3afb83fb2291dbf177a003b0197037a3c9283de78dc911beacf30e6c4c6740300266c6ab69893aa9e112b67903df849a4bd59ba106030b62b61bc293fef997a8851d06c956631c266ad533791124a4e09bdb06c0ffa681cf2c6d43670e2a017b9a40c13e85bc1c24ad914003aa69439d401ba605d013a2baa0e0b010363574b71242745e9d709a3ff3b0a2ac7f374684bce9bcf0200db5a09b5d0c92cdc7bbfb3c24a79a8a4a0a9a64376a0793c1252362af170856046471b1a60eb33f23c59122d0aaeda79caef27df971ac8764986cfb2617fc3bb71355a56867c29795f46668f8166970b06c6ca91d8651ccdcbc23fc1b2f0a75c45fb3321151953315036d52322c9b6408152bbb595129f41a8b8570f02b8ccba66de5fc36d892457673a9a096c556c9afd11b06e1ca9cc8b3a9e9765e38e711d039612c4bb296061771e42efd68c9acc8ca61012f295251ccb33252e8b0e6486c5a5bc28683347571b8f0a42aec4873cd3549324ab728324030196035b29ad3043ab9008da6b924bd376cfb103fcbab9450b44c299b4e27165303786944009418cbc66fd9a570468dd85ab652d86402501d61f5272cd880056521f72a362170580675bddd505840378d96334a704282934527f70a499ae99db81516b1d1426d233dcf9855880022d72100e14858c0a226325338b33ab5ecc5a86e0ac4e8504e168c5e1a4788177878bd569d49dc60b1484f43134e2bd39efb207430aa564ab7a88cd40ecc00a10e4b6c663b61a6054323429c0722b2e4464ec0d43374234b4884bb8ddc0a28852600369635531ff943194cf91937b43afd418f8f964cf9c9cc66988407bcc7b5247a2372980035c8f8357bc3db948c0c4b391ab47636024dcb79f094c62ccb64893c0c45c1bc88cb00ba85248253606735547d424797b0bb302c5eb9631ac98060bc47341e69379bba5b5e44980970c699187f62731f2b1a4bb4c7a33f8a20758335bc8a3c4c4c0900b3c2cfe35356a58aae233b066466b34c814a4cb6b9f916581b0361e78a2971bbfc014a7476ab2f7c291ba688d5f75153c4ad7ba4c664a8002058c9eb195a3ca7ab70638bb114c3618bac3ab383dbf292705a478a35c31f06a1823b545366cb6900c59c036b063727504a55c2ac940606c7bcc74643644bde915d83c395023c8fbd069f9ec50e1fdbc8edb0387ad1074b11bfdf220edd7486082a4842d6c737c6a1ed5b98bb78cd6de1153480b3bf095b04a7cbccc19102964e34693a6e492fae134c9d726e49532236018dc517bd94232d717a408af43fd5c837a21cca33ecc2a3859eaf8a74b63c36fa70168f241e2ff52f7197a615d04357a7acca269e47848375bab1f82ac686903d44786d540a496e29642f71061ee76054b5aa6ae67cfa01704b386a657a6773b8509cc1b4e16bbb92cb204b5bc6638cc5dd868db40358dcc4c258915d1e93771a12aa7ca4b3bcd854ea2a111c09afbc60cc91f5abd63ca5ccd11ef2c1b06a38925eb9a4bb569d8c4b859ad278ceb006a3d44328636809a31c377c58957aa5408b488445bf1fc4ca378c733e410e3814c4300850fffb052df767743468c6a91d81dc3c4c34b4b5a06dfab7cb6a741c91107758859f2e1c2d06881612e05cd7444abf23c104b6a068988fb794306e90aa1ad2ccf76482f0fa7067467dc105c27ea7192d0c6fc50b4042934e81876e121c6c295a5432219345bab9ca566f0dfb6b9d4728ab7187f311ba22d55b4047b9b3a17632925ec31bb2322257dfea3d1c1b4331467904eb2bc1f7a4369aab9912531a6835358b016889ac910a7c398c18a1636976e04c7227cc9fe13d61a848eeb60d56635064ba07359730a0c269ed6cb25ca2908f524ae3c9bc860a062192421cdba741dca98f98ae0d955c78d141fedb59bee95957e035d5b05155f5792e88ce43342f410ac92eaa68cd055fe28c4a217b9c2da4ba64d4a6605565d41a00acf377eaf80881d9a5305766747cb076149866504db6b96ee4cc9d4bb977165f0b04d3c03c1f8150a265215387c7983d37463a3136a1b7c694b79d85075e5a897a948edceafc78b87b7fbb43b11f82831299a9ee660b3d40c06c5bef7b6508409daf847a64c8d30d0974fd3ba7476dc76c46b458a036d884" +}, +{ + "dz" : "6fb2ec719f2a0dea152bf3f64b9d148f8ab8ba88f64e61f5db53e12d59f525574f797c007e4061f95c7d56cfc7ee5c49e849dde3fea8f25e7876df2a18515c34", + "pk" : "5586a5b224aaa6428374da6bbed37b0f67c3b5352a5ec2bc072247d20c7e83d83ec162a3dd00b44c070577ebb614c97b06e15d7a41ccb6a45fb2205bb57ba4dac40a12ac5f6bb522ed863daf67379d230badf71844256cfc596d28957bae0c050b9182668857951a38628b83e2082659317ffdfa0e279644fed9877d6775e131682b998adb000ace652f13fb0b9aa57b9022b792bc4bae5ab5f07372bcf131ab93523ff42e5a328fe465520bc57d62f222e0a3623ad8b034f164b1800926ca8a850277d0054f34b941e6388349a87eb853375055caa0305309a06fc2016ba8a3c9bb06bbe7581946755e6c726e9767330d639ad4ca467ff670414a65eacba93d2b33aa628f9eb2949054c82e62774cc13f013998cf29465e8b83dce66928b2c9e1f4cebbb91e2d8b2278879073411358910ef23c66c3115af8ca4ed0b595c8a49ae8eb955a86a2549132cd65a2f6a44eece7b43a40629ef172b068aab1c2126fe058ad02183dea6994abc7daa71414666c57b4c40a17781ac4784e6ab2ecbb8fb2101fa1530a00032b5d1b51b57ac1537076faa54b3b9bbfd9dcac565209cc681b73d5a3c7138156b258321c05a494345c9aa72197c9d3a9552e437e891c437ba16c00c76f0a6252c8e4cebed86398957088596ce28c5880db1b90306958c12a45b5a14e1b05c161c5a3aa78099154a557a58e6c2c7758653e3209edb90110e40e037732a7e44d7a60736437c7a3e872c82b20478083b2592ea7418b75b002f1da834df8624f665df2677e0ae98c62636f603bc1d796935a11bd18fb851e8076c7e4c58b41abc71481608281ee4c572b612c08b8cadcd6b7dc83130f161edb26b1335662a5161478eb5d5a8c61faa175f54166ea2741d27c0496292380e93f6b77577b494c463c9ce8960bcec25f43f198f0552da73819bd7131cec101fe6448f7ba3fb03637b351af9e284da6677b53b71ffde41ee41518b18c39813a82ca041f2466321ba9531ad4b576cb8825978b565580d5f000b9a56a943c2cedec578f728785487abc0a8f2d28af8aa3237022125fab084cd19565816d15f8bc6936959eea23f8279c74946a8ba37d2eec75622c4f911c24839b78cbc8812fa55e19e10ede4931f5d16bba8aa44943bf9720395a8b1328648b887b28a98423e4322a69a752d1d2121d447c2f05bc91e52635d06bb1e05daab02f02b6ba9ea8944d9344ef68c23af10144b93a40c456da0857acdcacebf1782d63a0648497c91916a50b3d0688800b968f1e2200fceb4538f7520becb0fb86368ada208c0602e1ba5d2ca85da8d36ab8782a80436d69f65622279d8145aa5ed9671a28699ac9990d738c3b67ba500a731cda82965a01b4c16144383bfbf3334d159c31831f94301d6a0320a4c7a340aab3a18825516b819a285dbb82a28f164091516c2519b9b534ab8d116cf61303dfa4091fab8669a417a9862f90491d251277d4b7b0523b7c4e345ebb090e5ee581f1933e7168567a857dfaf916f7747550409889bcbfb7e32840537ecb7c050b18552fe5aabb6794b27505f3b721c0b96b738c844f816160d3c4349c4463f12d248a6605b52bb9f8b370e958db55b9ee0663454104c47781e8e0a6eceb2a2632acf0082c4e1806c0927a25e7ba8f1a395f1a352e72ccf72093a9587299e5bc23933395836bcc97832360a992b040a7b67d4e2caa3d227f60d4c8ae293070b1878c63c8e106267a8ac7bcc850dabb5904769fc487b4f417388ce6755058470a3a7fae41b56f009b01c74af2c0a7d252b30302a7b3585864c84c8aa4ac42e82b1ab44215191284799c40d5ac80079d30625dd09562e555167391a370fb6841a98ff2b85713b75ff58b984efaa29393540fcb20e3c1cdb1887be3a30fd3861d62999f2c376704983f969197c9165f19b498bc169966269e3af2300847c908a4738c8655f476238fba9bdb05c3e4f1c3aadc7432960603c36f759c69e4ba048c76561ab4831b40341ed5c05c7b8a853169f2d75713c97a883419457193b9889724d3a108c1c3d083404d93a25a98babfe33d36fccf4f6623b9e378fc5c731b0a20df7b5c28a0c86c065017d37a65d89e8e127acb630f4304739f19bb2a596bf950c996805f73d79ec0aa09dbb0561c3a3bdb13009f672b9f2c907c468d916c305d530fe5910a3c029a722a9e1e6048ef23454bb64b1c9eb2d1c1fb4c57", + "sk" : "29450b5491a0266aa9fd363954b83ffb586f34256d0ccc6436225516953bd1982aee4224545abea8d68e9dd24b0f354f83978d0de0c5639acd6bd0a3c27289d20c9d55e56013aca5dbb7045d748077f4b9bc967dc2259cc79aa29a5a7cbe66b9484ca649042eee3b440bdb3f6475a02f61a85b2b373b91338940a2872213913ab6088b319d2b509ab46cd19aa454480d9560c0828a24b695cbb166471bd01a3bd406bba004e0c21f969675bf0884aca29f247c29f95097927490b5b3b72c30b59dda7d2b6a54693a1ad6ac033794cd0941be1c38998b488091a860a69c5e82248b5941851d8553f2159782dc7c2767c09b93671ec2c90684a4d3b27b6a88be09c50edc55b9291656177803461b4f312a6f4abc5ed1c97a6384356c549e070200245c6e39eac4267a77207293fed95fef2c29f3d93d2f1c6a609c07a3b8624bbc8da5c2538c25affefb815cc0675d88ba2c7629618a8e47b98433acb57c0b8e6499c44c311288c34d8566becbac15afc9a5a3d7c49ff25892a7a758b77e7540ac9e61ab0128cf301769dc65bd83542ee4b287849c75d53102ae750148d0839425a4b10243656397c16b05a9591817f117e6923d63584eb5e2c84a922d9f89b554579f9c526e6ab612a096a22760040a564649244ab8da3f066a4f0cd6906d83ca49ebae1fc49b00a5c36776c6f0911222602f7f2799fc3018828415d7c2ac0b88116dba3d0e1c62da01365e32bd111709fb7c07cf905e0510b9da4a61d7254d9a9c92cfab5002926954781ae86b0d88660c94e6591188c629a39e2d1748f2b44eb0961c7a480768e63d0560b65702c4d782193b7c9a89807729a3ca0c5c737e15506fe79912b05f25767fc53b772e952b6b900ef2b535beab49b69c0b958a42fd47b28dba99777291994598a64586cb86c8a98a12cc20322d2cb1a8819caf36bbcc387265b57819e496cca38b5c0b0b6f86c3b2d722d4eb3db4d97bf5aa2fe0a212f8f9b14e39495abb305a40c0c7ea77c315a2eed52fc31a75fe224bf08749ab8b7a5858860dd304f95608988abacf00bc0daa7f03b57bfed80503b366ada238312a155d398e26491abf1c5b10d22f8ee568d6f8867256684b0500d02a77070b8d54cb3504500a1935577cfb46113277933155d089c456d28f28aaaf0661a4a60486c4f7ba710253f753af6d75cd7b265f3365b2213878bce6c9f806c9df532ce2a5a656d072e67238e0c74978395552eb88a0b9b49b3205c41b3027d40b198184c67a8d5d3303d25987e9598de984a2f2eb69da7b843c6277ca144c2cac1babe34f119abeb5d6c1f6780d54cb511b2795a9118b4695749682cce3625cf7e85a00b82f59ab33184c2f6b6559084a1550675f72795e6ad74b22d57b903678ec4bc07da10a04b0c0ceb92a5e224661c9688e2a141d0c73af528826f65a330ca36a0b220bcc8021bcc1fcd408fdea0b2d709bfd368fdf1992f3d2841256647d2077f2a39c5770a11ef945823c55616cb00df3adae6478caec0ea05171aeb86eec42bb56c53ce27262a5db7e9aca343c036d8a7ca15ce23ab90312c8322e541773ace463a03801c3c44a7aa39723f2092a6c86c3f0c7b316865b50a13b84485eba71bdb2420bf351e21ba1b1169bf9414cdfe1235cb6024371450d9849ce8997e716bdb151119399884069bf964337dac8291c47abe351c914626ced0654e7a2cd65690e3fc67b3be0af7350c0d09ab978da207db5cc82902d6f3705f8b672384c0743d81a0de0871ac4a7fbc7bf1224a2f6e2b1cfd90f37e75f61a17f7fc9ad14b35ac0f79e6567a0208c0bf049a624566204301cd2582510f1c19de245b25394c8ea1405f7afd7a325bac60c93f700f77b258ba5b7177958fc8664e5e42d1600bba29b63b17046881a28dde4742dd7b8ef476f50186ab287a9f6c17321760a2332af65f136cd675b63695bbcc86081a10365aabfc9008db28b0123534acc645f290805d8b9bdf0636934b0b955555476b7604850ca5b3350d20b9269a3898fd45b161b165248830bd952b92a4c12721b67d724336c327a46753dea31a5c440f86c941660bc4e72ba51313d82842ff1e0175aa3c682a973f0861905fa9954770f83265f7f009474f118b081a24f9492d7d7408df21d000087b9e8cb88d5437c59835586a5b224aaa6428374da6bbed37b0f67c3b5352a5ec2bc072247d20c7e83d83ec162a3dd00b44c070577ebb614c97b06e15d7a41ccb6a45fb2205bb57ba4dac40a12ac5f6bb522ed863daf67379d230badf71844256cfc596d28957bae0c050b9182668857951a38628b83e2082659317ffdfa0e279644fed9877d6775e131682b998adb000ace652f13fb0b9aa57b9022b792bc4bae5ab5f07372bcf131ab93523ff42e5a328fe465520bc57d62f222e0a3623ad8b034f164b1800926ca8a850277d0054f34b941e6388349a87eb853375055caa0305309a06fc2016ba8a3c9bb06bbe7581946755e6c726e9767330d639ad4ca467ff670414a65eacba93d2b33aa628f9eb2949054c82e62774cc13f013998cf29465e8b83dce66928b2c9e1f4cebbb91e2d8b2278879073411358910ef23c66c3115af8ca4ed0b595c8a49ae8eb955a86a2549132cd65a2f6a44eece7b43a40629ef172b068aab1c2126fe058ad02183dea6994abc7daa71414666c57b4c40a17781ac4784e6ab2ecbb8fb2101fa1530a00032b5d1b51b57ac1537076faa54b3b9bbfd9dcac565209cc681b73d5a3c7138156b258321c05a494345c9aa72197c9d3a9552e437e891c437ba16c00c76f0a6252c8e4cebed86398957088596ce28c5880db1b90306958c12a45b5a14e1b05c161c5a3aa78099154a557a58e6c2c7758653e3209edb90110e40e037732a7e44d7a60736437c7a3e872c82b20478083b2592ea7418b75b002f1da834df8624f665df2677e0ae98c62636f603bc1d796935a11bd18fb851e8076c7e4c58b41abc71481608281ee4c572b612c08b8cadcd6b7dc83130f161edb26b1335662a5161478eb5d5a8c61faa175f54166ea2741d27c0496292380e93f6b77577b494c463c9ce8960bcec25f43f198f0552da73819bd7131cec101fe6448f7ba3fb03637b351af9e284da6677b53b71ffde41ee41518b18c39813a82ca041f2466321ba9531ad4b576cb8825978b565580d5f000b9a56a943c2cedec578f728785487abc0a8f2d28af8aa3237022125fab084cd19565816d15f8bc6936959eea23f8279c74946a8ba37d2eec75622c4f911c24839b78cbc8812fa55e19e10ede4931f5d16bba8aa44943bf9720395a8b1328648b887b28a98423e4322a69a752d1d2121d447c2f05bc91e52635d06bb1e05daab02f02b6ba9ea8944d9344ef68c23af10144b93a40c456da0857acdcacebf1782d63a0648497c91916a50b3d0688800b968f1e2200fceb4538f7520becb0fb86368ada208c0602e1ba5d2ca85da8d36ab8782a80436d69f65622279d8145aa5ed9671a28699ac9990d738c3b67ba500a731cda82965a01b4c16144383bfbf3334d159c31831f94301d6a0320a4c7a340aab3a18825516b819a285dbb82a28f164091516c2519b9b534ab8d116cf61303dfa4091fab8669a417a9862f90491d251277d4b7b0523b7c4e345ebb090e5ee581f1933e7168567a857dfaf916f7747550409889bcbfb7e32840537ecb7c050b18552fe5aabb6794b27505f3b721c0b96b738c844f816160d3c4349c4463f12d248a6605b52bb9f8b370e958db55b9ee0663454104c47781e8e0a6eceb2a2632acf0082c4e1806c0927a25e7ba8f1a395f1a352e72ccf72093a9587299e5bc23933395836bcc97832360a992b040a7b67d4e2caa3d227f60d4c8ae293070b1878c63c8e106267a8ac7bcc850dabb5904769fc487b4f417388ce6755058470a3a7fae41b56f009b01c74af2c0a7d252b30302a7b3585864c84c8aa4ac42e82b1ab44215191284799c40d5ac80079d30625dd09562e555167391a370fb6841a98ff2b85713b75ff58b984efaa29393540fcb20e3c1cdb1887be3a30fd3861d62999f2c376704983f969197c9165f19b498bc169966269e3af2300847c908a4738c8655f476238fba9bdb05c3e4f1c3aadc7432960603c36f759c69e4ba048c76561ab4831b40341ed5c05c7b8a853169f2d75713c97a883419457193b9889724d3a108c1c3d083404d93a25a98babfe33d36fccf4f6623b9e378fc5c731b0a20df7b5c28a0c86c065017d37a65d89e8e127acb630f4304739f19bb2a596bf950c996805f73d79ec0aa09dbb0561c3a3bdb13009f672b9f2c907c468d916c305d530fe5910a3c029a722a9e1e6048ef23454bb64b1c9eb2d1c1fb4c57d68f592a778a0b3bedd71c5d4f75c2e46b6088ca12a0a5e9596d5999259f13ff4f797c007e4061f95c7d56cfc7ee5c49e849dde3fea8f25e7876df2a18515c34" +}, +{ + "dz" : "527fb88c8bd9a4d6031dad15e63878abd2b559e7e08d61f69e8e78fca964ee6ae32d432b4f9f751bde0496c580a181ffed762aa35454a02d3f1f47ee0394c89c", + "pk" : "56180d96474d83a849634866a5cb0e6e00b8cb964067060df339cb2ea05fbc6021057978ff3baf47ccca15d90147473e8bab23693b6b70872b27b4a4c0730c5374a260e7cbbe9a094ab50e6fab80c32875c2032a5eaa8f2347c313409ca19302a0437cdea621da1ca0082157ea362ef7907fdc5826f067ac4a4a1e4b997d240c7d3df9ae6db528159402d1943fad6743e6e18b345ca2c0494d9bc956888ac85c021153b65388f04c456608e41361a6d3525a1143f610c21b2a9a7f5a2e1a461552904e341ab427028e567741d9906982e4b563d980b68871eef012f2c3639a244cd300cd0030bcf4a2b1db5101c1d66ee28bc3bc276b7e9922d0253904f30bb676777a36a897d35d381292915a82f9b2b7705380277916e16a137030198032b865c823e80a58c12ab39639488d65b0c80a391102cbcb4811911c60f618323c13a0e967bac6561483026c32348502927f70cb2f780bb571f861cdd5394296436e37737a8ac6cbdc42a0f9b96941907be3abb5e7740e193d590c862130283f0711665a85fff5158c968578781a7b766cead81633b6a2560b0a740752d83253a04c7f17b90b63860c19f38b78866edbb79482d8af6cb858c8a38fcf1c423f10cbbd9131ed87116b611a75bc109ee57eeacb6b2e1201e488c785b87f384c86587844a921701205979c1ba17dbc1519dc0908c656d7734a5a354e05606acf7901f0c7590e3a324c30a905b2462da7cfe478a4697601618bc74070a9e30707219c53b48c14c01a8fc745098a27b799868166c26f51a12a9a24c9faa336f92692c141961ba4444dcba2a370a63f533f87ca2b1b9537987b7b71043d5fd090300a7d4673a38cb781f833897e94955bba19d428cb7f71710e98901b3597467795a84487bcc5a1180482fea1205a0a854481719c12b11054ad3c85175a04c27011c29c387d0e571084f625a6f73cb5986945cccaaaac7d9eaa305c31535877cadf213d5bd25801438717dbb5051532f5f135f2f79fbd093864439507446b36f349ce4748fe614463917864eb90f3f36742f026ecf32e82f1cb90017099ec78380b5aca2c7e82657557eb66c2fb633aca3d99962ef8927a3f3c9d8da538b89525310664dc2889410465e90b4d078c7dc8f030729555756c807fe228623a37a2b248ba55516caca65256bbffaa6cf6457dba32336a71221659358f955416074ad0131dc4d186bcca317d193a91d12900c477a00490cc464a119214df01882576b41ad7b6f29b34dbb3b03a5c77b2d4162d985530c908b186b7e168c2ad69830302283cca078f5816a9c79add9bbbca9b3fee02447dca3ccb82bac0ccc385538208e49742da9616a28bb3c20568838de02140eee3a7e5a94a82563a90720c62ba2f32f05ddea552f565b4e2597b17c3b8c24168d4484deff79a25b82ee1253049e619829508b01a7891a10db5c5a532f4880c169a38c7a0c99715a2a696bf66b678a0349ef02c7002a5e5ec3db2c3647b960fe9a343b540069a6c228e024719e269853535f5e841f78922dd85c3052188a2db0b2a453b5119311747386352a437d0a0e2fa474aec0bdf1090ec169cf473b9cd153c2131b2e7e001d3525957a487a38c726d710a6bf6a1f0027432c53a56a96c3a1a100ea69103fbcca441a3f43002dd47714d397f7a3a02d0137a0dc060ea0669530161c67334b8965faba455b81a6dcb37c8d2ba97c9496c3e3bc984c44a7b2611b51794ee2347cc489c07b4a89e8c5c620221b9c98c08eb5b245819a92cadeb684b82757e00039079e550a7c7a14bc856e0d347d28861921277bf18932183cb9c40cb07d67202a7838b500df71b1ebaa87202a0943d982aedf41260b38c67e25173dbc67be8b33d10724b08611857c13870bff8c0324acb67f498b599db59515ca863bb1016e87d07b747efe8c903f50b3f7468053587555163e7f5165740204b78ccf2bb11dc32ad1cea844073b7d4667fb55b93bdb4a708db296f3bbbc511119db4479737578859075c320e55b0a5185552cb9426a69b0bd11b4dff716d5cc208e3fb46c3c4456cd63ef1d598bd675d55b1adc177790da6509dea49aa958d2ce9a9e6ecb19fe96548a88f7b489433147dde00139007b6bdca9b3c6c0eff0a1832c10a257599fa50200b167829bb34ee72551bbf3a650c7a34ae6ed516d401d89486d438a0515a537077561ec79e1a3963ab", + "sk" : "38d11a53967017a25d6522c539d05bb58667841b27c88c5f684597c79950739b4b3e15976bdb84de829fab2a74e888a65a336b5cf51e57c3c86e6caa9d9a4e7eaa69f9b53a719031a0d078f2257522bc083184bffc57790ba35cac0333f26925e87696c7749cc1129bf1d411fbea5049fa56231217fe9c073e59cd389c7b8fb0240f568dc815459ad132b932956288c3d93aa36d1627ebf1947c707a7f19c9d637b4d4a712e9b61444604ea1711cf08a91ba112087143b8893abc4db933fe973c65cb1c6512519b38e7385a1596407dd4850aaea36f9d4cc75542e96578b7230bd775040d6c03ef4b5b79406063c75b863a51488d395c33262a62268c1d11d53b315820b5190a94c8792aa24f651964061aca4212f452e7566b21418a9c7d84075f609e7456f069c105cb41ed9f638fa417e73f55f4c01bb553c085b3740a3bccd2cb76fe56b1f1b4892b762c2ad3c6eae082531b5b50e265ce5e104e8479087639368c091d2e2087a10b5d5f92cadba3c1b540bbf7945d9d04982ac5bbaa342ac5817b3a982e98a5e99a249555205d827b5e3348b31dc34af06b84dd52bc6d771acdb3b77a41aaa951b7fa5261d56bad24932531c35820943b0b2984afbca41506c4b3481f8817c285136c7185d8aa4a22f48920719b4d525ba81381142e8b178a0019313bea431c7ecdc7aec54662f591be66b74d85070c68817bc01c50e248b347c6eb3a97a70da43f51aca3df1cbe1316f93c50f4d02424578c6d274074e13accc57bbb8222d87db597e6c880cd794a94597faa10fb4f901208244c788afaf18502e3b7fec113510470d39db48352a7331b24a3ee15f986364a0e42aac36bd6a82b78b803571f632a0a49e6a871a9ec17dcca396c1d57a49ec5b46a981f6ba316f181721b40f17266120c0bf64a9a1d9116e2f104a0728bdfd54570da246c512c102d964c3c8432839900ff26910992309aa78aeda610cda4cf12aabd3dc7a96b1c26337c1e2fc858db6be45321de76aca80e417c7410283634b3e613d6594b8748917b60333a1268e6f943746377ca9c5ab428a0b6f37b844c25a8b0bc52e25cdeca953e089b9d787a738911cb6f209bc3b85c415b1d0a3630115aa496227a5d9bbe4a67ff05c2c8ab29090f52a9ad33a06dcbcff047244e170a9fb9fa7298b06313b80d4b1ca0a61d1531effec12c77405e188053fc0aa1a0329bf1139cfaaa86341004a4a11c461a5ab38036fd777afec0fc8965ef19144f0f81e40065fb23986dae3569dbb5feaa79b4c867be5a536dc9379d0365b00e91de1ab9a9701011cec0721c2905ea049fc221f39a7a80aa11114e69e7bcb3822b3c61a46386c1994141918ecd7068370ba638770fd2831dc758496056d15a82c6e0196c152592a216749eb02d2099309573fb9298e6d1cbda57898ca8788efd280934b4b60e40584c365633bc7fd091db45a644936be33953d4675c2fbd270ecb82b3e550d2df36eb5d11f7f6726d722861468cc2e830a11c419646c28e4c0bedc9627a0cc83ab9b9d4e3b320cdb18c4165c3b32ae61a05aa0869778a51df37b9c125045c6899724152c7ba7a6536b3d9e92ac2c63c29189813f55b5919861f38cb6d30845ce353dd0e199503785ed6b43ab60c0b6233b64265c7a794ca19838776a65ee97935cd4a63862299297c15b6a17bb91cf0ad393972b867fb11dc1e24ec7e205a42925ad337874b3263a7008e6487ed08c14a8b7a973f6a340f2af81fa76691c6343577e8b83399ec1a356b78d1e92ccbfa54cb79a3110411ee82161578c6a07d5746734710ee8a65f69780c16bf600737be4b48c7c977cdc2a3a6769301328f7ae7238f297f16a897cb3b768401544b974007c64be131b45d454a24a21af8440792631d78fb3ac527112da6222ab0ae47490c8247c847b5aa9700c05f7abf8f084cdf97c2bbc11414aab6ae26a276145cab441240808d1c3069847ba4a288a01822c9aae799dc44328a749042ac06a39130c513235f2567a34b52858199fe59758328010ccb7d8de311220335b4a555342633e5ea60b0b599e483787d2417790282011a0b34d13151a02581d939423c364a0a348f81412d07738299cc7bd12d41d1642d3b861c661338a3568a956ec7a4b5d855733626b5164c8c2ef2a56897a656180d96474d83a849634866a5cb0e6e00b8cb964067060df339cb2ea05fbc6021057978ff3baf47ccca15d90147473e8bab23693b6b70872b27b4a4c0730c5374a260e7cbbe9a094ab50e6fab80c32875c2032a5eaa8f2347c313409ca19302a0437cdea621da1ca0082157ea362ef7907fdc5826f067ac4a4a1e4b997d240c7d3df9ae6db528159402d1943fad6743e6e18b345ca2c0494d9bc956888ac85c021153b65388f04c456608e41361a6d3525a1143f610c21b2a9a7f5a2e1a461552904e341ab427028e567741d9906982e4b563d980b68871eef012f2c3639a244cd300cd0030bcf4a2b1db5101c1d66ee28bc3bc276b7e9922d0253904f30bb676777a36a897d35d381292915a82f9b2b7705380277916e16a137030198032b865c823e80a58c12ab39639488d65b0c80a391102cbcb4811911c60f618323c13a0e967bac6561483026c32348502927f70cb2f780bb571f861cdd5394296436e37737a8ac6cbdc42a0f9b96941907be3abb5e7740e193d590c862130283f0711665a85fff5158c968578781a7b766cead81633b6a2560b0a740752d83253a04c7f17b90b63860c19f38b78866edbb79482d8af6cb858c8a38fcf1c423f10cbbd9131ed87116b611a75bc109ee57eeacb6b2e1201e488c785b87f384c86587844a921701205979c1ba17dbc1519dc0908c656d7734a5a354e05606acf7901f0c7590e3a324c30a905b2462da7cfe478a4697601618bc74070a9e30707219c53b48c14c01a8fc745098a27b799868166c26f51a12a9a24c9faa336f92692c141961ba4444dcba2a370a63f533f87ca2b1b9537987b7b71043d5fd090300a7d4673a38cb781f833897e94955bba19d428cb7f71710e98901b3597467795a84487bcc5a1180482fea1205a0a854481719c12b11054ad3c85175a04c27011c29c387d0e571084f625a6f73cb5986945cccaaaac7d9eaa305c31535877cadf213d5bd25801438717dbb5051532f5f135f2f79fbd093864439507446b36f349ce4748fe614463917864eb90f3f36742f026ecf32e82f1cb90017099ec78380b5aca2c7e82657557eb66c2fb633aca3d99962ef8927a3f3c9d8da538b89525310664dc2889410465e90b4d078c7dc8f030729555756c807fe228623a37a2b248ba55516caca65256bbffaa6cf6457dba32336a71221659358f955416074ad0131dc4d186bcca317d193a91d12900c477a00490cc464a119214df01882576b41ad7b6f29b34dbb3b03a5c77b2d4162d985530c908b186b7e168c2ad69830302283cca078f5816a9c79add9bbbca9b3fee02447dca3ccb82bac0ccc385538208e49742da9616a28bb3c20568838de02140eee3a7e5a94a82563a90720c62ba2f32f05ddea552f565b4e2597b17c3b8c24168d4484deff79a25b82ee1253049e619829508b01a7891a10db5c5a532f4880c169a38c7a0c99715a2a696bf66b678a0349ef02c7002a5e5ec3db2c3647b960fe9a343b540069a6c228e024719e269853535f5e841f78922dd85c3052188a2db0b2a453b5119311747386352a437d0a0e2fa474aec0bdf1090ec169cf473b9cd153c2131b2e7e001d3525957a487a38c726d710a6bf6a1f0027432c53a56a96c3a1a100ea69103fbcca441a3f43002dd47714d397f7a3a02d0137a0dc060ea0669530161c67334b8965faba455b81a6dcb37c8d2ba97c9496c3e3bc984c44a7b2611b51794ee2347cc489c07b4a89e8c5c620221b9c98c08eb5b245819a92cadeb684b82757e00039079e550a7c7a14bc856e0d347d28861921277bf18932183cb9c40cb07d67202a7838b500df71b1ebaa87202a0943d982aedf41260b38c67e25173dbc67be8b33d10724b08611857c13870bff8c0324acb67f498b599db59515ca863bb1016e87d07b747efe8c903f50b3f7468053587555163e7f5165740204b78ccf2bb11dc32ad1cea844073b7d4667fb55b93bdb4a708db296f3bbbc511119db4479737578859075c320e55b0a5185552cb9426a69b0bd11b4dff716d5cc208e3fb46c3c4456cd63ef1d598bd675d55b1adc177790da6509dea49aa958d2ce9a9e6ecb19fe96548a88f7b489433147dde00139007b6bdca9b3c6c0eff0a1832c10a257599fa50200b167829bb34ee72551bbf3a650c7a34ae6ed516d401d89486d438a0515a537077561ec79e1a3963ab873d11d816550a4c1b14b584703531dd7cf0d97269125dbef3d73e443d017f57e32d432b4f9f751bde0496c580a181ffed762aa35454a02d3f1f47ee0394c89c" +}, +{ + "dz" : "ac6fcfaeeef795b6ef9e062f02bf42975fa01e7d91ba832f74e05269a72684d05aeda108ea4d6c6bc0fb958286850422bc357ca67b83c986048e0d0087fa11ec", + "pk" : "cbf017d8e336efbb596130b73268680be4885255aa6353a39f04740be2c3910a9ba91700687088aeca7fd4a37feca45bf29a27824babb327c49f18539ed20c1755983e6b1e03f98f8610227362c9e12246d2176ddaf48dac31955e59a7d69a8dfa582f8c66b14db7259e6c4c63bb88c995a71fc44bf964b1650746ff672fc2716528741dd8174aa2326e21f025367a0f243ac63728bc6ab95dc22a9632e18cff13cc6e38a1f4a0a542259d41db0c1dc640e8735dfbaca58c3c7f18e39c74641d477099ff1ac96c924e366b16ae423de8bc9610c855eb686e8d9301f2c08e96e3a2776523ffb93cfa3726c1d03d0c2c634f1cbae6dbb4cb987be8eb464190056cdc29a7651c79773b1686269c1646a65786f667986e7a552278713fe5c5a4f9c23633c467b8b63b408c4229cea5f5a0664852729a7474695137c0961783656df45277092226e232d5eb929c8bb57781cded3b7d5266bf5c2ccfa992bb9d8b59746319e6b5803d00a84e2a99989c08bc9726783389fd506074606a0945c7e3e22500d58fe3a647213b19beb6174c72833dec8ecd036499e53b0a18a1d6e471712a1d64a903b1f3634ceaace56a906a1336c9d9708768a6bcb9cfc036ac22607810457e8560561a38c5cd84c6ca021a98c15aadc47e874778a81423d669ab411a72aa4a661deb2b8f4a06600baac967617bfc5dc8d12d44d9a7f80b46d9a40b91a66e3cfa0bfb5523c04922db21c4120717b436c6dc81030d13b867e707b9a3891791c756800adb41cc9a29260d98202472b733611037a98b454b6b5af423df236dc079941b160ff1c0b8ed1b14e787898da354cf79ca4fe506d5742b58141dcf624964397274737e4ed1aacb76a92bba8966ab24741163893587c94cbd4581bd0a110937946051c572f2232a149667794812039ba9e6525a298531e7479a161123da95b83ee746dcfa1d880130af080fd71480a4d51a48c48abcb62d4c7b44b712bc0ecc4eb53a929a1167f3c49be7b019002679123348af5b7ab18a36f86a23b309154c5307b003966c8755047718b32649945c7865f123ee60198af51dd591934ee02ef7ec218569129d03b76e9729dacc17e4407eeaa4820e238deb307d819528b932bbdd74ac25c0476c037cd8200ee9231533676f3e1b11a6fa2511a3160f10b26f2cba2966572450516be1a39ed8bf651b961e58be810bbe83957037f1671c128f91f302dfe1103d624b97b4c331db624fb354178047ad4b909ba93211908e35014d896144356c250df2248c5487ea11b329214b4c3b2342e64244d684ba914e020228e0d9b5b0283b5c96a22b510f31974843b21df48878652721bfea1b38054ba1b39ebd0a03746ab5d07ba3d80b5be050af1282bf1ef87629ea0e2f9a272bac24b7d3b464c182a8032dc2acc0b7ba3482c5cd7c0b5199522634f61d553534020671baca3534193b2a9585f47394aca1c8aff24c05a7a8b0f59745e56e12321fa1a7b38db38de3485f017626eea474e3e3c1a6bb5242f26de2529e517928e547423b79cec6452f14c17ac403c0a6e23d25d334ad07aabd8c60310082bb4a194d656b2e2b64ff3475fcc9226a526867ca7dd03c75351ab921eb35e445b144f4a7e743acca85372a03c4cad754f1d788a1c919efc198aef95baf7768dbc94f36d5a37db440ee403b9b8a339bcc50c0469f51681fcbb294a042147f895d9121701071a6ae8b85b3ca4a7f197f06cc5ed4e40c5bd1ba18f76a8010857bb0c3f8c15ef8f89fcf22afd560445c8576b8a46297f1cbf5896232040727eb40b78c97099a09eae192803bcdb153b7c9918b8c66a3e8ccb0a928b2505b3034886b452bc9f7719246d62ad183a292a75f4d6715a42153b8f8656b2c397428803725bd66239587506e9ad5694ee0592918a14346cdb0a9117b7969345bb11be07b82dc4361b580fabc4a91d919fc97251ad1a69938b507e066cfa6a251d98927f2bf2a9806163c07d1a96627265776105126e5ca5872c61e4bba95220ed45124e76b334df40fe0cc4f193baf6ce69581313616c0a9de56824f007d65692d0f675aafe086b6e2621bfba18ce1adc4337553c81b92ca4a9a2c9712416a168a7a9fd06450589641e952a96b122b4c4bb63721d6e76201f96e7403a908819bb61864f9225185678741da30f96e7973a83811b94c50bae593d1da6d3b306bf50669e590eee2", + "sk" : "5cca6a37c37871e04cfa962d1716088fa90f49d176bd5077881b53d6f20da1027284e94a28058a0e249da3c36c5ad6af6056c4f8774af6343b19a0cf5f3a4c594489a64305d3196e71e390528141a735544b9ba54cf64523c39797153ae1620087264a5bc804cb864c92781ac4756c4a216d6d041ee6369436dcabd1b3a33fbb2fac37a994e2251aa9112c28ade1761151947314134ef0567962819ad9e47f56e7724ffb8967db192dbc50e0358d4ed578db4b88f76578196799340a21686c747b4763b9302eb4d5648cc83f75587627661a269801ff10662ae713a03b7ef1dc1918493885e811163902c7a8c5cc51c639c5750c13abc126431dd85d9706c945fb5d736224c5456d6da493651b148de081607116437a9c45e6614f76a5c6502b65a1ba5a31318893bba3b68e3cdc3680560d22c2b33745a4acb3a8af56452b7201cb42a0301c9a41848315212f60bb7d6cf7c8647cc7acf68b81959a8a6a91dfaaa41f3a679dd136d40046d7846f170bcba2648e08185a6ab380236158442299897814913196bd649a8b735d114135aa466804fabca21084c28844bf00cd18d6c8dd0b48a0f61139458f08f912dd28c4b4b6b012f6cef761740d97cc81341c80190a0659380ca04934e3b4426c7a22255815646afed165f68186da0206aec0b841828cd3130c59f3295ab80613e07a85b599bfa444364a569486075ab07815c74b4729a9281c6afef55fe7737f621128e18a355bb89c392817c348aecec895da19125af968bd1b4968240a025b051c49650594110e96547c10a127148ac162baf3625093c26577174586ecc30e4234b9b626c58328613b21bd4a8fbaca56ae9c9b943a7d2d79230e01caa6c6135900b33ee8925ceba22ee6b65fa09056e539e71b20c4815b448c70ba772302b9cd6e7546e756a85b41c409062348c334c6ec74c130a13a146757b8b566d33d7b0918ecec6acac9c579e5cc7e3a33c5da79d86a36b0e9b6ce1b22cdd696e1e793f6109da565137e2b666631225143a9c8b95d8d3a21c467c1dd2c0ce774a45006abea578844e09f8b982f0ebb53435c0941bc7cd7d27e8336cddd8332d62c32068623bf18944643634d814af239a12e3aa0daa027a8241297fba5bda40eb7630d1c2a4acfb7529963aa1f80ceb901b7159020b910c252bac2110a6da65732ae359ae3d0032494885c6a44874735d843cf2ac6a5e5f5a625069c0a49a66c8270b8e5a00d91293f0664f64594d7493f5399a3ec6a2c4f4a31bd604b04449c1b215dfb227f43778d9fe33f52e9c687452926e46a508c8a2d7a448af4539c05b4bf512b962017781c0e157686b748cb77b36a95c459ce5011da0c88f58a518932b5f7eaac67a27d89a60884d8a9f2729509db5cb76cc6f6236ddd0911d9c41f526086f3a24e0e160192577b8ac91ebc0860f7ac884161c6b62b872f129cb8fb11d56ccfe8b9adbec54ffd23b02e471284dbcf508c6a1912213ff754f1dc195f97b0bd798d8ae8b44114c4dfca0f76e479d39c4a19ac67445520ebfac92cc300fc62a94541b345f10b0f79c519c576c2037998564eb1506e6b91c8f606cac8f9b0d6927ab0e885b4704ac54cb14c67949f506000ec9e0685a9684b648a802cd8b5c8cd82860566b2d6e60e213429882ab51efbccbbf33f4f7a0cf57b6ccb8a27d95936a87814e6d80c4562c7a753c0a7e03b3685891e77338034713b7c8da4d097281753e54828ce951c60279a729376e991aac5101c6de3ae87c4ad3f4c75ddd517978bcaa4e85deb15c10fe701710067d25c2da778b4018c500c7368e58c550ab5825ffac4d58b87e745bf10d8118a787a5c5694bc099b38d89ac7f890d25497a8e521c8505e659506e0c65678279bc3daa95a82c806f04219944c5ef308315c69bc753d50490002c22e8eb89a65c93ac116692370595492cb626a8b5b64c291f77f256583bfe2a2372cbe80ac5704a2bbf3f0bd0a4515cd131814c6aafd39934adbab22ec3889572b423b643bd56cdd3ba2b8b20e98bc8afcc33d78c9bb8e466047961b03d31f94b783ee80a7506504ed3a723094c460d07adbc7b4ce258f9072c687e6346c850edefa4d3600cd616c6e8138ce6c3854a9452393a9266c2141b1d62d4111adf9833e2f2ba9be4289db4317cac169cbf017d8e336efbb596130b73268680be4885255aa6353a39f04740be2c3910a9ba91700687088aeca7fd4a37feca45bf29a27824babb327c49f18539ed20c1755983e6b1e03f98f8610227362c9e12246d2176ddaf48dac31955e59a7d69a8dfa582f8c66b14db7259e6c4c63bb88c995a71fc44bf964b1650746ff672fc2716528741dd8174aa2326e21f025367a0f243ac63728bc6ab95dc22a9632e18cff13cc6e38a1f4a0a542259d41db0c1dc640e8735dfbaca58c3c7f18e39c74641d477099ff1ac96c924e366b16ae423de8bc9610c855eb686e8d9301f2c08e96e3a2776523ffb93cfa3726c1d03d0c2c634f1cbae6dbb4cb987be8eb464190056cdc29a7651c79773b1686269c1646a65786f667986e7a552278713fe5c5a4f9c23633c467b8b63b408c4229cea5f5a0664852729a7474695137c0961783656df45277092226e232d5eb929c8bb57781cded3b7d5266bf5c2ccfa992bb9d8b59746319e6b5803d00a84e2a99989c08bc9726783389fd506074606a0945c7e3e22500d58fe3a647213b19beb6174c72833dec8ecd036499e53b0a18a1d6e471712a1d64a903b1f3634ceaace56a906a1336c9d9708768a6bcb9cfc036ac22607810457e8560561a38c5cd84c6ca021a98c15aadc47e874778a81423d669ab411a72aa4a661deb2b8f4a06600baac967617bfc5dc8d12d44d9a7f80b46d9a40b91a66e3cfa0bfb5523c04922db21c4120717b436c6dc81030d13b867e707b9a3891791c756800adb41cc9a29260d98202472b733611037a98b454b6b5af423df236dc079941b160ff1c0b8ed1b14e787898da354cf79ca4fe506d5742b58141dcf624964397274737e4ed1aacb76a92bba8966ab24741163893587c94cbd4581bd0a110937946051c572f2232a149667794812039ba9e6525a298531e7479a161123da95b83ee746dcfa1d880130af080fd71480a4d51a48c48abcb62d4c7b44b712bc0ecc4eb53a929a1167f3c49be7b019002679123348af5b7ab18a36f86a23b309154c5307b003966c8755047718b32649945c7865f123ee60198af51dd591934ee02ef7ec218569129d03b76e9729dacc17e4407eeaa4820e238deb307d819528b932bbdd74ac25c0476c037cd8200ee9231533676f3e1b11a6fa2511a3160f10b26f2cba2966572450516be1a39ed8bf651b961e58be810bbe83957037f1671c128f91f302dfe1103d624b97b4c331db624fb354178047ad4b909ba93211908e35014d896144356c250df2248c5487ea11b329214b4c3b2342e64244d684ba914e020228e0d9b5b0283b5c96a22b510f31974843b21df48878652721bfea1b38054ba1b39ebd0a03746ab5d07ba3d80b5be050af1282bf1ef87629ea0e2f9a272bac24b7d3b464c182a8032dc2acc0b7ba3482c5cd7c0b5199522634f61d553534020671baca3534193b2a9585f47394aca1c8aff24c05a7a8b0f59745e56e12321fa1a7b38db38de3485f017626eea474e3e3c1a6bb5242f26de2529e517928e547423b79cec6452f14c17ac403c0a6e23d25d334ad07aabd8c60310082bb4a194d656b2e2b64ff3475fcc9226a526867ca7dd03c75351ab921eb35e445b144f4a7e743acca85372a03c4cad754f1d788a1c919efc198aef95baf7768dbc94f36d5a37db440ee403b9b8a339bcc50c0469f51681fcbb294a042147f895d9121701071a6ae8b85b3ca4a7f197f06cc5ed4e40c5bd1ba18f76a8010857bb0c3f8c15ef8f89fcf22afd560445c8576b8a46297f1cbf5896232040727eb40b78c97099a09eae192803bcdb153b7c9918b8c66a3e8ccb0a928b2505b3034886b452bc9f7719246d62ad183a292a75f4d6715a42153b8f8656b2c397428803725bd66239587506e9ad5694ee0592918a14346cdb0a9117b7969345bb11be07b82dc4361b580fabc4a91d919fc97251ad1a69938b507e066cfa6a251d98927f2bf2a9806163c07d1a96627265776105126e5ca5872c61e4bba95220ed45124e76b334df40fe0cc4f193baf6ce69581313616c0a9de56824f007d65692d0f675aafe086b6e2621bfba18ce1adc4337553c81b92ca4a9a2c9712416a168a7a9fd06450589641e952a96b122b4c4bb63721d6e76201f96e7403a908819bb61864f9225185678741da30f96e7973a83811b94c50bae593d1da6d3b306bf50669e590eee255b703fe0b2aebdd29f6ceb606f15213da5f478ed4605a212f52358e2046d5b05aeda108ea4d6c6bc0fb958286850422bc357ca67b83c986048e0d0087fa11ec" +}, +{ + "dz" : "ba2fb9318d4dbe7488057c33e95e6f054583a2800c41bb83083c330a914a12cfe63f8ffda3565c2424c89b20974b748a65a5aba75133fcb3156dfb6626a83bab", + "pk" : "8945cc28753a4f3771a68a9000944d726479e1a79d88675fa13795fc086d79f82ea5dc7e2da5ac939a42728963bfc3659d50345694373b877b0504a864247addc746e98126cdc71d0e3b0c7f457c046ac8b8c1458ee70c82905ff5183d890845b21c66953c6402cba2e329886ad51a92f7c673995fe255bf9462b2edcc899125b1820125590024b6928fa0c79476ccc407312664b83c9c59a806989c3252683b139799561708732f57804a96c0b58c88cb4a83a1271a05a9a58a4c187b45cc893b9621e8c5543a02221efa2617b0a42bca1880959e70496cd1452d36191dea226b49f76418b1a44079c2d6392c37a319ca007b65f57743598f2c40a68dcbb603f11cd32c368a0688343a25f6a348c0b260b1946abbf15b3c9ba0ad1cb302b918e4285870c9444118598ad60dd6030c45f33239abc79a04a05a2cb8e62128a3a9ccb61248f1021c7ba5751dc60d50919862332bdd0bc371e4037063879fb5bb22290328c9194aa83716316b7747a5130a984a249e2e124ea0eb67396a3197fb80bd672c6e6cab6de2cca2e3ad70d5866fc878dab1cd654729ecf9ceb733a1b81890cf51c2ac112a52b6a4122c27b86cca81089afa1361c4015abe68c62d9a11bb10358459882f58461761a7ecd3b9b3b17e32a682a389c4328bbc4aab01f44ca93f150e72678160243130555ac9e964c784c33943b5ecd07aa8097be421b796305f05e196ae166559ca5c59a445bc98092be1182f8000d5c39b7c074e016433235aca94d7162b853e45367d42e1604b10702cea82d9004259d130ad5117ca24c6ed411d5929c3f7a6bb35cbcb2ca6bf08c06d1a1cb63aa54d4164a838173b82b45523e00559994e8ff5a9cab63c6fc3266998ca8bd5820e7b16f8f86ce149c355e49451c89624b4b1f2fa7f09c5a15bbbaeb6a641d561830ba25ea470c9d7c397499c9747994bb8818bef9c1ef7802fd6963dbafb6e6dc5a3ce1509510578b96983d08c53c9384e45e6a5bea7c943d11c5c46cef5d0566c4c1f99d00079b0641636bc31913034a134e7a4b0cb959ea4662be55157fe89a7eae1a976f30517ba7e019820984115e5ec2e7d00267240695f600b2eb4181adcad96c7605d5c750154a41124c6f23696845b9b5539ae30b1564bdb2b41c09feb96b31b0796fed8503028af11b02e68f342e3210845525a52268a1b0b4f7648600b455c5c824c49e2972371808bf572017331cc8bc0e11147bc10793e096144a4187b196abde288b134bc54c5b3b85312e7a9bb90135dca9bc7396615ac979de9800c26057ae3064090174437209ede210cb2c733302c4ae9c1ac1462024d54006835ac3f23611d1bcfc945a58401c6a6da42242983f4e712a5080bdd13633b1c98f32835f179a3d011aaa46b9b2fb810dee9495cb4451fe0ba20f71992a445e0c16486d06382c8cc4051647739762257a00d80956475b4521493df79a28319c2c1338c9cb3791980785c2a1ec4a11844b608a7c7c92b81015534a03904cd5a4777fd587ad8004b61ec40bc9aa7a4268ef445900522759cc5057baa2a5729bcfb3a0666126a90d56b7527c32800960d9586e93579eed18189f0a762518125a4317649a3c1883c6ed8b047b5444667b4d53ab5d5b952b10ca1b8aa4ca5e438ee3c2e79c2132bcc257d8585abb609ff870d25826a67075fc38c32cd1c6d78e56a4f18cb59c756979331f1786820ba297f4c26ce251c93686506b26805286cf5919ab660092e6c1825d746c8c9478b408aca024376233ab8c287d709d02f7b8c6d80b4430917fe546ba774482b9b77c20bccad85355f562152a1593cf2bbb02014df47b29d1ca5c1d300445cb4835b45bd59b92caa1cadfab9986869f5a7875967981f1267e615180bf7952a27ab3527a60b130d69e155ff88410b1a10a705b14df248cca801e3b7610baac9d92c75e4c759cf7c8f644b610a350a9a9b5b59eb798a1cbf42d02f211a27aaf05ab8e19baa600f3babca5d82c9388466c5aba81c32a7dabc9775e73a77432f9b96225db1698a2c7a6c9b6949c59d7796758d24c41872802a63bc9723b17f703903c84e425383051abb07e94a1f19a258a61c66b56f46cccf68fa4ad62c528cc1bba2d579913ab754268eadc4204b887bb764096783301fd30ef9d972acacc01977d137525d619df951b0f9a5008bd9cb4524c5ae7cec747696489a8fc0ef65", + "sk" : "ae7abea38c394ec61b08f8b73a42afe39c0510a45e50a3c3565941c54332e613c5687c6b7f1ac590c7a2472597e331a23f3122e0a12a8688a9da651aec131981aa6c623aabff1b682db2525543afdb53b461853aabcb955435178d9939c2e262554978b998aacc07728f29a6ee7c54f34738db084c81b6cee4914b0706ae0ce056eed5c97851a0c861a91f42938678ba9383b4a8dc051472cd38d2c85de9747d90ce0e46bb059688cd2cc90721187f56bbb695c43c61651bac8763572d78a4014ea4106a9916ff378cab1518801455683175aa75af0619a6eef774f25568dd35cbe312b80db29ab007ba069182a0369d8025ca8fca341dfb99ccb044b1ecaa19979957e2001af126df1159f13648bec2a71ac53a8cdc957b731c09d84249ec7a53b3507327b1fe36bb79a7668dacc9f898698bf296bb078d612603336109dc29664635b9fce33005c704eb3512df2c4ab3e63387126146a56c00a04954516e386b554eccc45a848c8ab79513e9a7e1e0692315714b292090b281678b70af0847d3211b97f89cad50aeeff5660ba620302724eb2403d4c0a8dd015e7362077e0944da2b5afaf2ba08687c25e491192659e48363143600ca16441a678c7fb40a76c08760c102247606f5d128dc0a13a8a86f758725d4205f1a2393a7479af603a2f173c841b27b51f90833363b87d8134a904dcbca542f76caeedbb57f73522f227f72056390939c10d28b52a824ed621d861c8080660472f01a3d692b1802a7bceb5cabc12dbdd649713227bf9a53f801420c0421cb48c3214755917ab076709231a27dca46a2a603649ba1aed077960e5ba1d44bb3f2ac2c0536b8dee5be0b7c682851553d902939a775d564b38ada0fabd429e105aba00433527b3ea6f847ee7c1667590f96fb7c4f2083c2d540582bc79dfc3e881905b8c16b5bc0c5c5c46880822cea340c95006d80b475d0485c1539880d5298fe1018f9302723d5b3e64515851364e8269a6bc824c562a29c801806289d82389945a4974d16865889bc05d42f57ca85a6499ff0e5534b9cb8041cc0d5f30ea82a04746b51d8242319d980d274102b997b70688f63014f2b473f14b344d9dcbb08c400355a53b923b7a5539b2c41ca08a31556c32c67303448b088a9ac95005c74385baea6a227cd535be3b58e97aca21ce97f89e6c634d175274b737c74a8feecb38bb587777b27ca372ee6c44592ac2f54618e77eaa6f11342de70ad66da080ff75d557b5e052bc4e6e9614f0b23c2b9a13e540637444585a81a5e90b2c1178881ca41a5863c45f42564200e7f9b82222430e7b185fea1a5337a2beb4bcd059cad0b2141fde13060ac4c2bb4b87ccbaddbacb43ea9bcd15a32e02ab9446c7086f64653f45fca9190b0037fb5eca9acb9c28b757f177a9ef74bb4ab8cc526d2b4074b99ef4b6b3fc85cbb343834f929496a043a037e7e3c1eb71323f5cb62a57b3b7cf64d639c2cad92623aca195a43b684058f342713eb661d78a59ba2b57fdd7a64d2643add5738dfa57e575a11bcb956d628c85d06051109740a706fb649203ea70aeeb4cc07e1cbddc2645e2613b6e90d5a12b0b9a81cb94152b106cb4d25830af5b76dd61d98bbb9a6d5cabfd13fdfb139a90286379c5aa772af1c10812da52b582437b6543665f522aa7ab8ecf57e584429cb74abff84b9281b8fe0fa540f542599529505e0bdd117a3550bb1fdc225a250a8781ba42d45a481e74de5598f4153650a4c85a005901a149c47fca69f1b8ed039884c74b39582cbea46b31061627368bbcd0c4de55a5930670274b6bb33a737c9b376144b81c16b9b23292f2d15cc8a3aada3cb7475c3425f8334fbd474a71a83ed957954fac29db49983c8a82bf41fdb0188152c5d20c6a9ad9bbb8f88693636ae00c4a61eb2be93f95a96441a9d7bce5b291a56d92640c4a22b1251ebe36379954fa49605216756b7d07943a176706a20f01362b96501ded810ccc709f54aa8744911811c2ce4e6490d6bb5bffac3f067278755bc8d472689720ad0f98801b6255bb399ec38272bc50aed950291d47ed97cc0c9c1542944afb7c313565c414e18934532aea2430c2c4aa95f31ae44b42e713387ba046aee62a3dd4416d0f4071ae6541efc7f8170995e376c41b57b7192c712a9be8945cc28753a4f3771a68a9000944d726479e1a79d88675fa13795fc086d79f82ea5dc7e2da5ac939a42728963bfc3659d50345694373b877b0504a864247addc746e98126cdc71d0e3b0c7f457c046ac8b8c1458ee70c82905ff5183d890845b21c66953c6402cba2e329886ad51a92f7c673995fe255bf9462b2edcc899125b1820125590024b6928fa0c79476ccc407312664b83c9c59a806989c3252683b139799561708732f57804a96c0b58c88cb4a83a1271a05a9a58a4c187b45cc893b9621e8c5543a02221efa2617b0a42bca1880959e70496cd1452d36191dea226b49f76418b1a44079c2d6392c37a319ca007b65f57743598f2c40a68dcbb603f11cd32c368a0688343a25f6a348c0b260b1946abbf15b3c9ba0ad1cb302b918e4285870c9444118598ad60dd6030c45f33239abc79a04a05a2cb8e62128a3a9ccb61248f1021c7ba5751dc60d50919862332bdd0bc371e4037063879fb5bb22290328c9194aa83716316b7747a5130a984a249e2e124ea0eb67396a3197fb80bd672c6e6cab6de2cca2e3ad70d5866fc878dab1cd654729ecf9ceb733a1b81890cf51c2ac112a52b6a4122c27b86cca81089afa1361c4015abe68c62d9a11bb10358459882f58461761a7ecd3b9b3b17e32a682a389c4328bbc4aab01f44ca93f150e72678160243130555ac9e964c784c33943b5ecd07aa8097be421b796305f05e196ae166559ca5c59a445bc98092be1182f8000d5c39b7c074e016433235aca94d7162b853e45367d42e1604b10702cea82d9004259d130ad5117ca24c6ed411d5929c3f7a6bb35cbcb2ca6bf08c06d1a1cb63aa54d4164a838173b82b45523e00559994e8ff5a9cab63c6fc3266998ca8bd5820e7b16f8f86ce149c355e49451c89624b4b1f2fa7f09c5a15bbbaeb6a641d561830ba25ea470c9d7c397499c9747994bb8818bef9c1ef7802fd6963dbafb6e6dc5a3ce1509510578b96983d08c53c9384e45e6a5bea7c943d11c5c46cef5d0566c4c1f99d00079b0641636bc31913034a134e7a4b0cb959ea4662be55157fe89a7eae1a976f30517ba7e019820984115e5ec2e7d00267240695f600b2eb4181adcad96c7605d5c750154a41124c6f23696845b9b5539ae30b1564bdb2b41c09feb96b31b0796fed8503028af11b02e68f342e3210845525a52268a1b0b4f7648600b455c5c824c49e2972371808bf572017331cc8bc0e11147bc10793e096144a4187b196abde288b134bc54c5b3b85312e7a9bb90135dca9bc7396615ac979de9800c26057ae3064090174437209ede210cb2c733302c4ae9c1ac1462024d54006835ac3f23611d1bcfc945a58401c6a6da42242983f4e712a5080bdd13633b1c98f32835f179a3d011aaa46b9b2fb810dee9495cb4451fe0ba20f71992a445e0c16486d06382c8cc4051647739762257a00d80956475b4521493df79a28319c2c1338c9cb3791980785c2a1ec4a11844b608a7c7c92b81015534a03904cd5a4777fd587ad8004b61ec40bc9aa7a4268ef445900522759cc5057baa2a5729bcfb3a0666126a90d56b7527c32800960d9586e93579eed18189f0a762518125a4317649a3c1883c6ed8b047b5444667b4d53ab5d5b952b10ca1b8aa4ca5e438ee3c2e79c2132bcc257d8585abb609ff870d25826a67075fc38c32cd1c6d78e56a4f18cb59c756979331f1786820ba297f4c26ce251c93686506b26805286cf5919ab660092e6c1825d746c8c9478b408aca024376233ab8c287d709d02f7b8c6d80b4430917fe546ba774482b9b77c20bccad85355f562152a1593cf2bbb02014df47b29d1ca5c1d300445cb4835b45bd59b92caa1cadfab9986869f5a7875967981f1267e615180bf7952a27ab3527a60b130d69e155ff88410b1a10a705b14df248cca801e3b7610baac9d92c75e4c759cf7c8f644b610a350a9a9b5b59eb798a1cbf42d02f211a27aaf05ab8e19baa600f3babca5d82c9388466c5aba81c32a7dabc9775e73a77432f9b96225db1698a2c7a6c9b6949c59d7796758d24c41872802a63bc9723b17f703903c84e425383051abb07e94a1f19a258a61c66b56f46cccf68fa4ad62c528cc1bba2d579913ab754268eadc4204b887bb764096783301fd30ef9d972acacc01977d137525d619df951b0f9a5008bd9cb4524c5ae7cec747696489a8fc0ef65c68e808974e356659cf3d88474ae8af1480f2c4bf5f053b0a8c211d43921f735e63f8ffda3565c2424c89b20974b748a65a5aba75133fcb3156dfb6626a83bab" +}, +{ + "dz" : "aa6dd1e5799cdf7af9c4fc632b3eb9d51d66e85c8e0a21ec98664fc51ab63c7dfda268813efab5204efa60f78bf81d320d01ac09ac06244f7afbd2d80fd356d9", + "pk" : "fab5cf19743430a247522566196826be35c3ba55053ed8c8ac04211931a38d5a100c7097059bc058d551672542a8f1a7ffe81e0c43b1636572f4608dfadc72f9a786c4c2b2d27c576d29461ad56369b7300d3b0a7890ca3d8407a8a1a90f796558843202152a7131919d9417065360440ab8516909087b2f4ea408baba0cd5c0af2a85634e88693b8c121dc8121d462650f2b417a0c44a5018bc2a70e68a590b757b4c0ac70bca25923049fda10856f62ca42701ab9a75d9991fe3d99856138112ba4f52da1166f410e3f15baf7c3062563dbf0626f76c4ce98ccb1f238a8870201654a6e551a5de9cc24fb36dff2334f2f7bcf51b8b6f8c2d07b4892a657e58637011624076040c02ec59924916f5e49956534b0b7a746b16663f33cef4440f2eb5be9fe4034db153d296a86d83bee3b08ae5341223193a7febabc53956049bc1e14819391c5be5e216377438b0fb56ad770335a97c8e574c015c66d99c59325a2edafc7a6b4ba77fb51050a2c400d754d71c0fac84781af78c03c094bd800fe25b7f7060bfb4252643d97ccc6002a1568d4af181e992b1ffa8cc17bb835f0b2e6b72026478729275b002636cb49c9edbf4373912961da0b913e6cfc1959b80e711cea276c10158dc43b6887042d8d58402cc54a671275fb49a7920c35651aa4d81aebdc772112420db0162b94648ccc519e369958ce40adc90413d9802e621b6e8ccac13d846151c19c6813259c5998f40710f3162d006c5d3a9b2d18861789aa7854831a0314eb74a03b84921ed73ae13db7298288ccec07eaef97716d14a8a296bc3d0b95e4a78e1fa2467c6ac961a73ce63085ca1a4b101adb7f2a4059a97a24bc2dfdb6115386de5e95486a46e6697a17a88510c97a0602205e008088d269082b2c1790c02912a9f03383a94d2127ce1a0d7f558434a6300513a14e2c4f6b33d8a159a06d09983688f75265a84637f07846f0c47441bc6a6a8e48142b39b4891bb5c321c8bd307dcb6326dbb960b532d88f08f8a299d914824e46189378c635cf2088ed8382fbb4164d01c867c1f1c4973116c3629b3cddcb40b1832a0f06b6d04ec8edc46205da3b28f50bd1730bbc04c5f927209a4369b878596a2e149767139e4a06493ea42034062ab1ab037728908c07f9bdc820495916c9114f7e95683c945c19354dc06c5b7888244ec179bf88ed4e68bd10483918bcea652446b7333e71a403e97446564361b5253d0b225d4155682123725f61ed5d4655bdb7891c6572758977f0b4e8de021e832ce6314c25e82392cbca5c794cd20241b87ec87a85a017774bc3da18e77e0b53a521b2eb0a7006b35edf5b0a85b44d3d78dfbb476861997714330c9c5ae5e0027d7298a64b62f2523670c618051629c9577abc2f456eb0ca33fc86e94d910d186144be3a886230cf3566cc09c2ccc76719bc349cfb70c35b24ea6b4bf1c0394527a529641a2b45b60da3a976d70012e48b5df60a7d8382ab149760cb5579f0673f78a52c01c8efd1a667d86635bf15035ac32805b56cc9a1cff506ca38b3df7a3b860985fed84b2b4f1c7f3a88122630f438c565660362a90887a9cb55090cc448c9088c6783aa890cb51ccc3c8cc7c097d59808f06675e1e826869abbc0644a612d471d5c106214abcc1115b106ab3405b1de14c664a773e6e5667d8177ed736a967710edda390f0b105f9c5ba3a2a61912a2414397030022035c533de16c634a799f2b72fc3112071e7aaebd1636a3603971020e2f90fb8113387ca17171b39104595e5500b50c99c37aba1fad50fed567d5eecc00db3ac14624675c76846b42327b9510ddb882b24be90c9661f5c46eb5b1991d25920c78f35807ec55ac2827776a54ac4ee272b469ac65aabc6ba199dbe33724e5866e24a8058d5908e30bf54325745907752d324490b766f6672c4c8443ff7647dec597276135a4789dbab39355175bf3a63ca6a359a879d648c0b388270680781d3e732efa5c85f1c020e4384875954b50403a4987ce54a6f24c83e541491b7d144012544b96b00b933c51704bcfc2b20ada6c481ab32d555898174526a266f70b7939054a88256a59c95a0ec2501cbd45f0ff2ad418b82ecb514f7ebc3fc33647f5c43c5026fb547a33bf2642c9279dc39ac6012a770267d6c947324c6d45b65393421bf4bd7068abb93ab3a36081a303cf37b90037749a046d478", + "sk" : "52309729384894d97de3098b745a1f88166013ec7422b31ed4ab74e69c3b7b094dfe982a7db3cdc5d4aaf9e468d0471eaa8c8aa3148cc3a49cb1eb4e4d420b497b73573a839814032f655f87245dc6acafb9602774500919361beeb7b9fd4688fa8238c8c1116f51970394c39354a39212b9508815dffa2e87416269c88def88a639cb1b3560bae168be823918afd8af8d42c3ad9b43ce33428b6b19d4038cd03169c06c773ad1295fe5c06ad97b17ec93cd639732faa7b88029ed160652930595719e5c734420028d60c6180263c9c7db51a2bc5d52b232d0279ef9e7761c1a4578b2b2c21778ca806deef18f9c8778f0b5204d661425c3023c451de2f806c67436fd2b7e2ef208023abb81f87666c117a78b696d65630b1334ef853934a39d9d959ac8990b674534257012796352b0a41308a1104f82a09df85aca25137d597a33c088f942c496998a367a08473a49acb2bd38d27b7ab21fe80959f3bcbcd0488c5bd4c42928155ce5a91da1b437539a33a34ca0cb1c4d179540816f0d063664b599fe195ddc777ea8836cf5c20f8ab34e3c8c6026e58e8b032c6b720324a882a5512d502880b3d2a3df38cf5da7c5fef955524b451d5c7ff24c926d0382535c0ecfea73b4e736a25957c74084448324fbe462fb0c656b074ee596abffaa67b692b770e734f56c53a97bc846030fa6ab726ee7097a49a64f098aa3c763942001c7999131220a47751ef3ac3cd729238c671f5ff51aac89101b772cea01144e469510502103e70a67b08dd968b21818934693037f653c845579e25c5be3196e180447210c97a9a724863588d5f38d20a8c5123a6b2aa549d50a8b03dab4536bc658c8b9d8c782b3e02321c90525e56d3ea8cdf91a7340c88c8d90426414469adac2268214433c23cc078a12c5bfd3ab079db8ab6222cf6f47c005fb84775ac60a606e1b460879d19ddf619293113b80598e87658a025824888541c2246f93870271c767f7d099e70227b97091d0d4c72a1248e47c80b99b2d8072cfc0552bb82320a6ac00f04232c75050afb90f4295c98ccc09414b402782a0ed168d31c2cf913288e57245c8ab998d99b16ba26313d05d50e15617fa0e3aa1a32ff2717ac486ad72bfa679a5a63a047983af1b6544c8405a4513af232b00907c935f3b452619b91ba35c6e6297d5f4abb981a6654b425e612b431359c5b861189a6ecdb978ae3b9804740c7db22013b39da62099d397659d847e7c6a9121991db5abc317b8287f2c9f07d4bfd9c3780e29441865458df968187763b9eaa8c3c99c22976d77760f31b5c369917249a78874f2c22671446d289f996ba38f5235152c366bda9d50f66235484df4f6b0b8f243776bb09a7958668b77f9e1a537428395457873d6be96868ee474c83d969d43e0bfd6976e9a75c79094574595aec7fa2dea390202dcb289f7823a35ca79632343c96e916a097e7314efc002799047c3a608b62829d2669fa6f0a95f594533d910ce6594e9a8186444bc6826541f3c834af812a38a2d8a87c8128837f68c93dc49b664813511fc64cafa56e324556b2803e56503db153ecec99d274c889227bfe8a6b4ceaa578ad37684984a6de966b0f9cb8740c7c5232293030aec6c4828c29152ac2fdfb29ee8c72172105365b465d1bcc2c2a07269895397842f2a839467e49a422657cff06e2320ca5687c52dea39470a8b2b84710ec05bb7bc10e7f3542d4a9e5e2a377cd15d8189a4522b107c866ebc4b7777e602fa4a46981339879534a92b679be67de762b2b0d07a3ae14434220d749c0d3a556295757c747a248a3b2e172a9f7ea35f646c2c2bc3615aa110fee2ce88d24ba7d12f0fd24d209a6fc44995ddf957ebc80014c4c904947a5c7a58a503be4d18a9450c10a4b90e93b780d17c7073623296c62a3feaa30b0414e1c8566d65b95a7c98890b366913336130cb5adcae5f40518325cf2328680d9c3e430bbb2bf32754235a4777280c934d33c2bc571a637b965583678b8280779ad6a2ad9a65d849419de930327b5b00ebba96dc14093088038982409a1b9b19c8085a3bc9a21783b51ab266a996a512c4ebb550c0c871f58332839ccb02a6b1509a89f43a54d302c865463bb12f5d87c1f0989322c48fe1927aea1029e748593995a858514bfab5cf19743430a247522566196826be35c3ba55053ed8c8ac04211931a38d5a100c7097059bc058d551672542a8f1a7ffe81e0c43b1636572f4608dfadc72f9a786c4c2b2d27c576d29461ad56369b7300d3b0a7890ca3d8407a8a1a90f796558843202152a7131919d9417065360440ab8516909087b2f4ea408baba0cd5c0af2a85634e88693b8c121dc8121d462650f2b417a0c44a5018bc2a70e68a590b757b4c0ac70bca25923049fda10856f62ca42701ab9a75d9991fe3d99856138112ba4f52da1166f410e3f15baf7c3062563dbf0626f76c4ce98ccb1f238a8870201654a6e551a5de9cc24fb36dff2334f2f7bcf51b8b6f8c2d07b4892a657e58637011624076040c02ec59924916f5e49956534b0b7a746b16663f33cef4440f2eb5be9fe4034db153d296a86d83bee3b08ae5341223193a7febabc53956049bc1e14819391c5be5e216377438b0fb56ad770335a97c8e574c015c66d99c59325a2edafc7a6b4ba77fb51050a2c400d754d71c0fac84781af78c03c094bd800fe25b7f7060bfb4252643d97ccc6002a1568d4af181e992b1ffa8cc17bb835f0b2e6b72026478729275b002636cb49c9edbf4373912961da0b913e6cfc1959b80e711cea276c10158dc43b6887042d8d58402cc54a671275fb49a7920c35651aa4d81aebdc772112420db0162b94648ccc519e369958ce40adc90413d9802e621b6e8ccac13d846151c19c6813259c5998f40710f3162d006c5d3a9b2d18861789aa7854831a0314eb74a03b84921ed73ae13db7298288ccec07eaef97716d14a8a296bc3d0b95e4a78e1fa2467c6ac961a73ce63085ca1a4b101adb7f2a4059a97a24bc2dfdb6115386de5e95486a46e6697a17a88510c97a0602205e008088d269082b2c1790c02912a9f03383a94d2127ce1a0d7f558434a6300513a14e2c4f6b33d8a159a06d09983688f75265a84637f07846f0c47441bc6a6a8e48142b39b4891bb5c321c8bd307dcb6326dbb960b532d88f08f8a299d914824e46189378c635cf2088ed8382fbb4164d01c867c1f1c4973116c3629b3cddcb40b1832a0f06b6d04ec8edc46205da3b28f50bd1730bbc04c5f927209a4369b878596a2e149767139e4a06493ea42034062ab1ab037728908c07f9bdc820495916c9114f7e95683c945c19354dc06c5b7888244ec179bf88ed4e68bd10483918bcea652446b7333e71a403e97446564361b5253d0b225d4155682123725f61ed5d4655bdb7891c6572758977f0b4e8de021e832ce6314c25e82392cbca5c794cd20241b87ec87a85a017774bc3da18e77e0b53a521b2eb0a7006b35edf5b0a85b44d3d78dfbb476861997714330c9c5ae5e0027d7298a64b62f2523670c618051629c9577abc2f456eb0ca33fc86e94d910d186144be3a886230cf3566cc09c2ccc76719bc349cfb70c35b24ea6b4bf1c0394527a529641a2b45b60da3a976d70012e48b5df60a7d8382ab149760cb5579f0673f78a52c01c8efd1a667d86635bf15035ac32805b56cc9a1cff506ca38b3df7a3b860985fed84b2b4f1c7f3a88122630f438c565660362a90887a9cb55090cc448c9088c6783aa890cb51ccc3c8cc7c097d59808f06675e1e826869abbc0644a612d471d5c106214abcc1115b106ab3405b1de14c664a773e6e5667d8177ed736a967710edda390f0b105f9c5ba3a2a61912a2414397030022035c533de16c634a799f2b72fc3112071e7aaebd1636a3603971020e2f90fb8113387ca17171b39104595e5500b50c99c37aba1fad50fed567d5eecc00db3ac14624675c76846b42327b9510ddb882b24be90c9661f5c46eb5b1991d25920c78f35807ec55ac2827776a54ac4ee272b469ac65aabc6ba199dbe33724e5866e24a8058d5908e30bf54325745907752d324490b766f6672c4c8443ff7647dec597276135a4789dbab39355175bf3a63ca6a359a879d648c0b388270680781d3e732efa5c85f1c020e4384875954b50403a4987ce54a6f24c83e541491b7d144012544b96b00b933c51704bcfc2b20ada6c481ab32d555898174526a266f70b7939054a88256a59c95a0ec2501cbd45f0ff2ad418b82ecb514f7ebc3fc33647f5c43c5026fb547a33bf2642c9279dc39ac6012a770267d6c947324c6d45b65393421bf4bd7068abb93ab3a36081a303cf37b90037749a046d478b6481b87d7f462e656db85d6046534ae44d82b1cb737a0194eaac814c7b85493fda268813efab5204efa60f78bf81d320d01ac09ac06244f7afbd2d80fd356d9" +}, +{ + "dz" : "195d6c86a3df4c21e3007d7f2768b43c74cb3060e0eca77f0a5d3271542b9a84ae77e0f9f21eabd8c0c6eea7767f4e10fde5c2d79b8400bf96b19014b457ec21", + "pk" : "7665cd15516d767a980e05ba44d761fe17355c0aa302f3826dd25da4ca4d044c299dab608da967c1e253ba77108df51914a15541763f737a89fef62be1f7b4e1b8b77eb719a84377be0081f7d71a6e881e15578603867855d87ec04b5f1f133368e43ec6282fe5eb16935a04ec9916caa90031e40d98b0a8ced98979fa7742a20dcbe84c67223eb6925d7b1b12e07a47677b56e9916029204e91408635eba66a6a844de5ccff6aa63fe15190030b8771101b456288b170bb117584c996c8515262c684a4718f8b369011865c756827d3038d62355f4c994a539815f4d6b6dc9455f4d7ba24501029170cf1aa3b0944574f6642c446a3f121cd08c7bb67e7239da147e0e9c9b5c57b8f2182e00488341994f620c99978c818aba5e4516efe23690636cabf607c438cc288e944b3446b41a264b88c6e0371a08a1c02703c21a0bc5d73e6b95e7b5fb87c6cd43415aeb26f92abac0371b9a7a70ea51c88e12bbcdef7c3cd3a4bcbfa3bb83606b25c85984021122400272a616fc4071db20560654a7ca099a6d0754c43687d9657b1b816a04b8d4cb63d0e3765e228890e0907accb4734cc557fc96ef7fb6b463cc2fa5b73b7fc231f230028201483e66efdd4570365865c08028f96609377703a2300f7e1b9f4939475541e0cda2527b28aca7374d1827206426637965870e9b86cbc115d9a04c0e73e8b7a866c277da3c58e0d2094fa285e2d05af7ef64f8ea6146ec4321395b7f30a6e52171ba28984b1e49726b48ed259638f6bacbfc5c2a4baa3cc391f0be917f7ba3a05dc911642a63db03fce58bc6ff92af7616569d04415a26eff8c271f9921ddd302787959f5397b70d7a388f7569e010cf26b67fb2c3a2a52714f5666b9726cb775c28a79a41531213e4766c9442fa06498f6d5a1816b7338f9afb779a40f2670221bc5ef319786762fc78b1a25fc9db8e362f11c9f374b04204940877bc209b25ae7f461c40a0193f66a95ab7dcc80afed9402ab725dab23c1abeacad633c461a26790865c21a960d338a7e485cb2b42a8b0963b8689c9d4287643b8685a341333dcbbd7637fa2671c1048638a547815f07b255ac115c8bc32b61a369128c60076c3464fdbe2c7c0bc5ef1e383ddd2ae8b0457410c19ba1c486b702a9048049e85cd1e7569eac6b3be8287ec9c195c3bb0b4f28952823832c55257d05ebd8a8bff9c372095be66359c9ba7384080a7acd9567db7905c50c36734cec7519e8e57195247b48a65a1e34cb942d741d88b429d226a4097beed271dcbc8a035606e056a89a8487197039adde30f78bb17148a4f0bc84bf1dc0d9057c97b028296b9260e601ed1a675bca781c53bcbd6866b4ae108d059ada7c6b8615195336c2df2e71ce97528378b2fdc4b6501f2443fd4b6248429b67a4624769236e32c12e3116ef66ae2554f55c7be15319e803b8ce0089d3c04b65ec8340c483b2ae4c2b8ec7daa91b39270ab7ec04fee436e1c008f61c46fa854363287573c50c63c3b1f94d52feeba13aec5c926257592904b00ca8615469df5539e8f4c627b11be02e96d17189a80f37da5d08db81baeb7c34b5c58ab3ccb25af3c29cec9364175b6bb4a04b5958079e18d5440bf24538598c1c548327980297efe531d4c14a9360b8dcc173f6536b760b2a6fd59bae262087989269c884a966c658017ce65d14519a2c61266b344f6648abc0a657580130c6fa0f6565d8100f0532011945c3fa296de184750aa931582a90e6bb9080971cdd6b470f68db4e529ed61bf97f62bfac5cb534c1570db606cf0351e1866d7e199dc329d70316d7fd849d5c296d76a8db20306bbab609e7a9ac05c7896b150d6962d2466158f8697e532901e421d5ec00671344640623891a9221ea17ebcf6b290dc54359814a86658e2c0159c2374e1dc5f94dcb30ce01f3633129274585e304f0436396d66660f81c4cd273b94a3740f9c2fdd081bc309602a2cadd82aad35a46684547d01c74c38547176113a697b49e6c98c1c017b25f817e19c2a0302d083dc5c74c4c38b6706e94c10d178369b375df9c118130824fe99ac49f24a682ac23de429f8c7a6d1a89c36f82f0a47379e7aafadc744e1f20b9186c67784c3e6b823306896fca303baf61309cb498a216431862f00198c26ab6938487dacfaeec6906ae45303ec7dbc2889a8eefa511b82609b980dad54ebb3e7091e9d", + "sk" : "ead08feb355828171b57c7a2c7328d0a736fc5b548308a22b8672c19c820192297e4762a8bea6c048a33c0248676f2bf0b8393b34667de1abaec665a886ac369320ce3188f66d6482cbb184ca6b189c70c531661e10784f4b5116ba5000d0b06714320d8b72ea88621093a0338e5b628f44194925219406517e36d14096b2cf5286f6981f8885efc1ca4074b2d5ffb118eba8f1e7aa83dc8ac1aa9bad3b5cd257465bedc943fdc9a88915aa573a2ff63bbc2e29abe33cd919bcd725bb24486b847f2cdcdf36fdeebc79c123151a02a7f4a42851c0c56e08cb5b6cd34309200e80e9344a229917dc5231e1608115f6120dcf177da2bbffcd8a389e0623c81baf62a3033f99ac0027540c93d2071380d5ac60d894b85d18b20f21aaa5151657b34d5b125557832fdb09dd1c5bedb2bcce9d3c71e742923ea341b1657ac7908ae474cb7340d2f917513958ef6fc9bc4997a9a91662300a610868840c7b868ac0755e0a3c16a9b8f2343c2308e5e256ec7c60811822545eb20c3b8077ae771bd4313208584551cc2463691ab1ab4d5c112fe951bc0b9c02e867377dbcf41114d1553912400d065308456c1314641adf2038a8625b6311c3b0f98aa1ae37caf188f4448a6b5a78b746a0bcfba1ea2016d34059a3dc34fefd9261d5308b4e03c5677895822bc96441741865ddf787545b80c509259265976f187833959229cfaa95765a41837b210661a1e06137014b08039c88be27b9d292ac3969bb9ac396fbcbcd3626f3ebc78fbd6462e673cffc06d490b7dee720e57130acb1a1edd9c4e64a2aaa2f92411d489c9ea00b68a7d30d347714059487b8f837c1bb5070260b2521642cef747c602398902e33c6022aff921a25e941955f81515a245f6d717d048a307020055e988d760b141e23a16f767260877b7551e9bc80828626829f94e20c4020a9a2688d1168ca5c3a9f752643a17237ba623b79f144a118f5cb41f466a27cca78a208815538290b8ac4b086cf626932869b43e4b5477834606d9bf8e21295d6284d0cc72e64875cf526b8c380731880dd00c20fc2a31496274b94aa87ad54de79aac54995c951a1371da09770b8446aa1e40b1cbcb57ba5f446fdf1260e9bca676dc3db9a24c5f99cc300b7b08c9abf620bb03e75d0a5b872bc79cde550f8b243940737cecc136918b61adfa167553a005e0c2fa3190a895c2ef4a53ff90a75a879cb0e9855f2826ad7a9608579606904411b25ab46c6181203756a93c7a9ba7c2d3b862889fbd153a394791d3c481fb64aabad314c7d637dc43bff1a6ba7c031698f245c29294a533700145a904b17f9f30853090a0f68574b2b4a095033257d205a4e59af580b362a5be3c0311abb22e665c9558f29ef456cb3aca8d3a149a01118f7ce93d87ba57a814cb7e7c84dbc614fc2614ebe6892d6037df49446d135a6cd05d224786d79ac87417626d831134b95d129a42bc4663ef09184c53c50dcc9d2dca8efc81254aa76a8e8370bb03ca7c30124d5c2247490c03488484cc110c9b1233e482899ca443f0a4b44a6fa073ac87e82688763ad72bcae0db87b1a5a629d27f8aa2b11793b47c82af1486c97e41b7aa308e1a23af4b68be5c849625224aaa0cafcfc3a21ba49e3ba168d16512a5968d5c0222696649d7674332f884f31259cf9b477d1445eac17c4b11afd2fbb6a68aaece5a47ac5031e5457d32cc2a601b6b91257b64ea7c30b6b32ef7b949893a3aa14ca0d1a153b50bba60398cc4090a9390f714541f34bb4c93a81f734809cc86b8fab6be5539c9f6a968ec207eb577b16116169565b86c21561936a467a435b88081e71925576350cc964f5b37fd73c421e7a076703fc308947cc5a3f2e21d328b8c23e32fc8f5c04faa6d72395fc7c8b2d8fa72c6f35c9d81271ac34c0ca2685b5c5571f7b9b9245133c58b3bf155e6668315d0899bac05dfb0b8661241f22772dd290bd963087cb94c9fa464788b8a87c637f327ccbd31a34328cb58b5c7f95aaf9f51aa5bbc284fb26b40cc438843a6ac41c82886a2236734dcd81584d8ce18184b90b22e62296ace4191efe679d4d52c12351e3d41bb2d815035d62380c45bf078025d4a12885ac092057b009d6c3105ac49641cdfe0c48bc41a6f14c0a5f31423ec378ea2098b48557665cd15516d767a980e05ba44d761fe17355c0aa302f3826dd25da4ca4d044c299dab608da967c1e253ba77108df51914a15541763f737a89fef62be1f7b4e1b8b77eb719a84377be0081f7d71a6e881e15578603867855d87ec04b5f1f133368e43ec6282fe5eb16935a04ec9916caa90031e40d98b0a8ced98979fa7742a20dcbe84c67223eb6925d7b1b12e07a47677b56e9916029204e91408635eba66a6a844de5ccff6aa63fe15190030b8771101b456288b170bb117584c996c8515262c684a4718f8b369011865c756827d3038d62355f4c994a539815f4d6b6dc9455f4d7ba24501029170cf1aa3b0944574f6642c446a3f121cd08c7bb67e7239da147e0e9c9b5c57b8f2182e00488341994f620c99978c818aba5e4516efe23690636cabf607c438cc288e944b3446b41a264b88c6e0371a08a1c02703c21a0bc5d73e6b95e7b5fb87c6cd43415aeb26f92abac0371b9a7a70ea51c88e12bbcdef7c3cd3a4bcbfa3bb83606b25c85984021122400272a616fc4071db20560654a7ca099a6d0754c43687d9657b1b816a04b8d4cb63d0e3765e228890e0907accb4734cc557fc96ef7fb6b463cc2fa5b73b7fc231f230028201483e66efdd4570365865c08028f96609377703a2300f7e1b9f4939475541e0cda2527b28aca7374d1827206426637965870e9b86cbc115d9a04c0e73e8b7a866c277da3c58e0d2094fa285e2d05af7ef64f8ea6146ec4321395b7f30a6e52171ba28984b1e49726b48ed259638f6bacbfc5c2a4baa3cc391f0be917f7ba3a05dc911642a63db03fce58bc6ff92af7616569d04415a26eff8c271f9921ddd302787959f5397b70d7a388f7569e010cf26b67fb2c3a2a52714f5666b9726cb775c28a79a41531213e4766c9442fa06498f6d5a1816b7338f9afb779a40f2670221bc5ef319786762fc78b1a25fc9db8e362f11c9f374b04204940877bc209b25ae7f461c40a0193f66a95ab7dcc80afed9402ab725dab23c1abeacad633c461a26790865c21a960d338a7e485cb2b42a8b0963b8689c9d4287643b8685a341333dcbbd7637fa2671c1048638a547815f07b255ac115c8bc32b61a369128c60076c3464fdbe2c7c0bc5ef1e383ddd2ae8b0457410c19ba1c486b702a9048049e85cd1e7569eac6b3be8287ec9c195c3bb0b4f28952823832c55257d05ebd8a8bff9c372095be66359c9ba7384080a7acd9567db7905c50c36734cec7519e8e57195247b48a65a1e34cb942d741d88b429d226a4097beed271dcbc8a035606e056a89a8487197039adde30f78bb17148a4f0bc84bf1dc0d9057c97b028296b9260e601ed1a675bca781c53bcbd6866b4ae108d059ada7c6b8615195336c2df2e71ce97528378b2fdc4b6501f2443fd4b6248429b67a4624769236e32c12e3116ef66ae2554f55c7be15319e803b8ce0089d3c04b65ec8340c483b2ae4c2b8ec7daa91b39270ab7ec04fee436e1c008f61c46fa854363287573c50c63c3b1f94d52feeba13aec5c926257592904b00ca8615469df5539e8f4c627b11be02e96d17189a80f37da5d08db81baeb7c34b5c58ab3ccb25af3c29cec9364175b6bb4a04b5958079e18d5440bf24538598c1c548327980297efe531d4c14a9360b8dcc173f6536b760b2a6fd59bae262087989269c884a966c658017ce65d14519a2c61266b344f6648abc0a657580130c6fa0f6565d8100f0532011945c3fa296de184750aa931582a90e6bb9080971cdd6b470f68db4e529ed61bf97f62bfac5cb534c1570db606cf0351e1866d7e199dc329d70316d7fd849d5c296d76a8db20306bbab609e7a9ac05c7896b150d6962d2466158f8697e532901e421d5ec00671344640623891a9221ea17ebcf6b290dc54359814a86658e2c0159c2374e1dc5f94dcb30ce01f3633129274585e304f0436396d66660f81c4cd273b94a3740f9c2fdd081bc309602a2cadd82aad35a46684547d01c74c38547176113a697b49e6c98c1c017b25f817e19c2a0302d083dc5c74c4c38b6706e94c10d178369b375df9c118130824fe99ac49f24a682ac23de429f8c7a6d1a89c36f82f0a47379e7aafadc744e1f20b9186c67784c3e6b823306896fca303baf61309cb498a216431862f00198c26ab6938487dacfaeec6906ae45303ec7dbc2889a8eefa511b82609b980dad54ebb3e7091e9d42a9b1d5b6521a7a4527116aa7c38f6ddf99acd4a7b9837317d99f83732bb7caae77e0f9f21eabd8c0c6eea7767f4e10fde5c2d79b8400bf96b19014b457ec21" +} +] + diff --git a/Tests/CryptoTests/KEM/MLKEM768KAT.json b/Tests/CryptoTests/KEM/MLKEM768KAT.json new file mode 100644 index 000000000..b65849f29 --- /dev/null +++ b/Tests/CryptoTests/KEM/MLKEM768KAT.json @@ -0,0 +1,703 @@ +[ +{ + "rngSeed" : "061550234D158C5EC95595FE04EF7A25767F2E24CC2BC479D09D86DC9ABCFDE7056A8C266F9EF97ED08541DBD2E1FFA1", + "pk" : "A8E651A1E685F22478A8954F007BC7711B930772C78F092E82878E3E937F367967532913A8D53DFDF4BFB1F8846746596705CF345142B972A3F16325C40C2952A37B25897E5EF35FBAEB73A4ACBEB6A0B89942CEB195531CFC0A07993954483E6CBC87C06AA74FF0CAC5207E535B260AA98D1198C07DA605C4D11020F6C9F7BB68BB3456C73A01B710BC99D17739A51716AA01660C8B628B2F5602BA65F07EA993336E896E83F2C5731BBF03460C5B6C8AFECB748EE391E98934A2C57D4D069F50D88B30D6966F38C37BC649B82634CE7722645CCD625063364646D6D699DB57B45EB67465E16DE4D406A818B9EAE1CA916A2594489708A43CEA88B02A4C03D09B44815C97101CAF5048BBCB247AE2366CDC254BA22129F45B3B0EB399CA91A303402830EC01DB7B2CA480CF350409B216094B7B0C3AE33CE10A9124E89651AB901EA253C8415BD7825F02BB229369AF972028F22875EA55AF16D3BC69F70C2EE8B75F28B47DD391F989ADE314729C331FA04C1917B278C3EB602868512821ADC825C64577CE1E63B1D9644A612948A3483C7F1B9A258000E30196944A403627609C76C7EA6B5DE01764D24379117B9EA29848DC555C454BCEAE1BA5CC72C74AB96B9C91B910D26B88B25639D4778AE26C7C6151A19C6CD7938454372465E4C5EC29245ACB3DB5379DE3DABFA629A7C04A8353A8530C95ACB732BB4BB81932BB2CA7A848CD366801444ABE23C83B366A87D6A3CF360924C002BAE90AF65C48060B3752F2BADF1AB2722072554A5059753594E6A702761FC97684C8C4A7540A6B07FBC9DE87C974AA8809D928C7F4CBBF8045AEA5BC667825FD05A521F1A4BF539210C7113BC37B3E58B0CBFC53C841CBB0371DE2E511B989CB7C70C023366D78F9C37EF047F8720BE1C759A8D96B93F65A94114FFAF60D9A81795E995C71152A4691A5A602A9E1F3599E37C768C7BC108994C0669F3ADC957D46B4B6256968E290D7892EA85464EE7A750F39C5E3152C2DFC56D8B0C924BA8A959A68096547F66423C838982A5794B9E1533771331A9A656C28828BEB9126A60E95E8C5D906832C7710705576B1FB9507269DDAF8C95CE9719B2CA8DD112BE10BCC9F4A37BD1B1EEEB33ECDA76AE9F69A5D4B2923A86957671D619335BE1C4C2C77CE87C41F98A8CC466460FA300AAF5B301F0A1D09C88E65DA4D8EE64F68C02189BBB3584BAFF716C85DB654048A004333489393A07427CD3E217E6A345F6C2C2B13C27B337271C0B27B2DBAA00D237600B5B594E8CF2DD625EA76CF0ED899122C9796B4B0187004258049A477CD11D68C49B9A0E7B00BCE8CAC7864CBB375140084744C93062694CA795C4F40E7ACC9C5A1884072D8C38DAFB501EE4184DD5A819EC24EC1651261F962B17A7215AA4A748C15836C389137678204838D7195A85B4F98A1B574C4CD7909CD1F833EFFD1485543229D3748D9B5CD6C17B9B3B84AEF8BCE13E683733659C79542D615782A71CDEEE792BAB51BDC4BBFE8308E663144EDE8491830AD98B4634F64ABA8B9C042272653920F380C1A17CA87CED7AAC41C82888793181A6F76E197B7B90EF90943BB3844912911D8551E5466C5767AB0BC61A1A3F736162EC098A900B12DD8FABBFB3FE8CB1DC4E8315F2AF0D32F0017AE136E19F028", + "sk" : "DA0AC7B660404E613AA1F980380CB36DBA18D23256C7267A00A67BA6C2A2B14C414239662F68BD446C8EFDF36656A0891A3CC623FC68B6572F7B29A6DE128014411EE41906D08071F94856E36A832B40338D743516659BD25879C007A52BC9586F79876AFAC6C9A30D8FAC243BD22425D6ADCE42AB7ED39014757A958BC8A74565F019234FF04B34893ED6D05501C37255239AAE2AC19F8C75AC5900DAE8300DBBA710DC2CAAE1BCA3A38C58342B286B8518F136AD15B9F7BCBB06A5607DB375DBE976457C26C6598257531B2CFB6EE7F51591840804C38388376C27148413DA9E92920BFD9A069E018BD272053DA8775C0B739F761DB2107CF35A434D69B07E5BCDB87434138B0CB556761BA522A5747B28747D80EB9D6CC673BEE5769377B996D36CEB0C0C7ED9A658533324869C18A1A36F31470F14C5AE49AB070507F8249CE404B49C0A8C3EE42FEA9631FA1A0D10D86B93F986E0E3A82E703B74E5AE6101242421A89AA07FE68588460BAA368786486A72E4F24D2DD76CFC03B694A5BA91A755A0B98F3BF93307C0AB64639AEA7A6498A3C3DDC571141ABCA4678CD2E2B857FB88F600CAA596B44BC422250B2819E0515F0472391853700B01EFF9453FD11876B7C759A07DD845CABA4555264A82765193FDF81B620A1E1F923FB24442CD1CBE94175003EC06CE77A3C64493C199987A300C95C53C0089B5D65C92EA971B2FFA93B52A461EA2AC8C199C2F4C2B704297CE3C3949E0735EA8A14AA59E8DEC0C878399FF70747AB244CE46B5F2230473323D25C66FE6B419B1F4A112E5214035256BC43FFD2B6B7B378769A6B47000BFB6357D45814BAEF3857D379E2FB8B5E5201AB26274BB1B70AD322CD0439B2DB109CFF0A2F8E600995571FFC38C590BC4C7615C69D0C98EF430F30861A77238FFC07061E475D6A30AD1B47FD039C3A447762DB2211DC31D0ACACFD55890A5824798F9AEAD7413DFE028B1012BE8B6CA1026666AC6BC9440A449B51AD8BBA7B0921DD4D8B4A578136D1A05DB38CC858437B25161D1C3C28EE07BBCF2B249110D22781DC3050D8CC0090096B38A850696F86E9E6BAB325271B2248675011968502881090497FAC0AF843C1AEA76DD81CF29C012C66227B7F06D9961309B0262F732C9A4D0BBD06727ABB8371FF2C11899A098375C460516B2CC88BCF628EDE37D8F3B3342E4490A85606EC03DA29B0256275382A3313DC041114801032C519F350C3E6ABAC3E33B93B4A19F7C5466E58CB1DC14B4A96C475729F971BDF173CDF354824D019427F95B3B4A4A4A958E476A6E6991CE6F06CB5DFCA7D4380C3D920B5711AC1FCBAF4B9AC800B976D1EC766A626CC1900B66B3A9DC62C5C144527A296BAF70433BF657C0437F87597BD7C8BBBE9ABC37050931A4A86982A2028A74454C9B810C88D1701C8CC98A1D4CA107A6B25E962FE4B6B03C95453260B807228637CC9EB12ACC0954959A52AE54D1977300ABA0BA2C14609BB28C11D5FAC5CAC88297603283E867A3648366C724D9354CD7A196DBD9802F7B88D3FA001F9C9773225462235E91352A20791FD8B87FE3377EC6A3940B1130A0BB04E7410A34E2580D071D6C56202086787A6590F84393A8E651A1E685F22478A8954F007BC7711B930772C78F092E82878E3E937F367967532913A8D53DFDF4BFB1F8846746596705CF345142B972A3F16325C40C2952A37B25897E5EF35FBAEB73A4ACBEB6A0B89942CEB195531CFC0A07993954483E6CBC87C06AA74FF0CAC5207E535B260AA98D1198C07DA605C4D11020F6C9F7BB68BB3456C73A01B710BC99D17739A51716AA01660C8B628B2F5602BA65F07EA993336E896E83F2C5731BBF03460C5B6C8AFECB748EE391E98934A2C57D4D069F50D88B30D6966F38C37BC649B82634CE7722645CCD625063364646D6D699DB57B45EB67465E16DE4D406A818B9EAE1CA916A2594489708A43CEA88B02A4C03D09B44815C97101CAF5048BBCB247AE2366CDC254BA22129F45B3B0EB399CA91A303402830EC01DB7B2CA480CF350409B216094B7B0C3AE33CE10A9124E89651AB901EA253C8415BD7825F02BB229369AF972028F22875EA55AF16D3BC69F70C2EE8B75F28B47DD391F989ADE314729C331FA04C1917B278C3EB602868512821ADC825C64577CE1E63B1D9644A612948A3483C7F1B9A258000E30196944A403627609C76C7EA6B5DE01764D24379117B9EA29848DC555C454BCEAE1BA5CC72C74AB96B9C91B910D26B88B25639D4778AE26C7C6151A19C6CD7938454372465E4C5EC29245ACB3DB5379DE3DABFA629A7C04A8353A8530C95ACB732BB4BB81932BB2CA7A848CD366801444ABE23C83B366A87D6A3CF360924C002BAE90AF65C48060B3752F2BADF1AB2722072554A5059753594E6A702761FC97684C8C4A7540A6B07FBC9DE87C974AA8809D928C7F4CBBF8045AEA5BC667825FD05A521F1A4BF539210C7113BC37B3E58B0CBFC53C841CBB0371DE2E511B989CB7C70C023366D78F9C37EF047F8720BE1C759A8D96B93F65A94114FFAF60D9A81795E995C71152A4691A5A602A9E1F3599E37C768C7BC108994C0669F3ADC957D46B4B6256968E290D7892EA85464EE7A750F39C5E3152C2DFC56D8B0C924BA8A959A68096547F66423C838982A5794B9E1533771331A9A656C28828BEB9126A60E95E8C5D906832C7710705576B1FB9507269DDAF8C95CE9719B2CA8DD112BE10BCC9F4A37BD1B1EEEB33ECDA76AE9F69A5D4B2923A86957671D619335BE1C4C2C77CE87C41F98A8CC466460FA300AAF5B301F0A1D09C88E65DA4D8EE64F68C02189BBB3584BAFF716C85DB654048A004333489393A07427CD3E217E6A345F6C2C2B13C27B337271C0B27B2DBAA00D237600B5B594E8CF2DD625EA76CF0ED899122C9796B4B0187004258049A477CD11D68C49B9A0E7B00BCE8CAC7864CBB375140084744C93062694CA795C4F40E7ACC9C5A1884072D8C38DAFB501EE4184DD5A819EC24EC1651261F962B17A7215AA4A748C15836C389137678204838D7195A85B4F98A1B574C4CD7909CD1F833EFFD1485543229D3748D9B5CD6C17B9B3B84AEF8BCE13E683733659C79542D615782A71CDEEE792BAB51BDC4BBFE8308E663144EDE8491830AD98B4634F64ABA8B9C042272653920F380C1A17CA87CED7AAC41C82888793181A6F76E197B7B90EF90943BB3844912911D8551E5466C5767AB0BC61A1A3F736162EC098A900B12DD8FABBFB3FE8CB1DC4E8315F2AF0D32F0017AE136E19F028F57262661358CDE8D3EBF990E5FD1D5B896C992CCFAADB5256B68BBF5943B132B505D7CFAD1B497499323C8686325E4792F267AAFA3F87CA60D01CB54F29202A", + "ek" : "3B835A5FA145387A0819C4DAA1E65FBE2BA5400AFCD640BBDDBBE3585F24BEDD51289694A4FE643CD5AF9C8EB277C3F1877A347A97EBEA8A037971C6B37993E433CFAF580EBA4B7FDA990D54BF4D60CAF9D1CAFC477FD956F8E6070B6AEEC6776EB814835407B5F705DB9472701D16E00655024A309B14DDBF36D222BB509647A5A049D5816F49AD9F2975DDB64C2DF05FFEB24C6A3F24A786DBF4F6D5666FC55FB73539679DC15B72FB4F6CE38FEB281D28C908D5195DB7008315978EF9D2C67DC4DBCC4962467A2D44F7235FA54EBD88BDEC32408B1F7AFF1B842064075651F03A3AFD2721ED1FE4FF1A8775C6B4D95764555412CFF2F8AA4404900F33585F0BD1B70955CFF80130DCC2403920E9744A3D0DA914405561ECB2BB32120B7ADBD2F4D8E9A07B4630480B8DF8C068934FFD9BC9B855A888EECA090F211905E074A078AB68917E7445A6C7C7E39403753CE19B6614B9D222AB99F263A681CEC6C037587EF051F0F7294E376528B31789A530342258241C99AE7D384BCD61012A32A977C638B09A3BC16A33AA47CF2D7F12D79D8AA50F63C8C53C439800B2ED9BBA9481EB181B4244ED067D62695D6A99DFD7BF8788C159CAAF94E9FDA92AC5A93F59A0DF7C0F9BBD417CB8CF45D1076006E08A9E585EE4D7394265582A87641F1653BE9EDF194401E6E4EE93C4AB054A1B6E81E3BF01FD26F2E9A6DB5BF6C0DBD21E14C2E1A5A4CFF0B267ED95427B0B049EFF7FBC093B054510578523AC7A32CC1F8EDFCF078A6C71E6E6788EDFDA7D7BADD375F7D911EFAFB9CB406E968BC5989418FB09729ED51C92C4AEAE10846384F4A091C405AD85773FE0ADE816EDDFD618BA0EA5DEB73CC43592E063015118025542871E7A60F844A6B2C3D630F9C6F85791E8D2BDF3578FF92628E8ACAF02B88D79797FB1AC30153201FCAD2234FBD4F2FC84FA7D2AB6FB2E4D9B55F11DD91A798726107C6842C3E7A1CA895035A8FE701058E3426E17BBF04C23E78FFB283E027E1C636B1CF9DED3F5909EBCB0FC63608E918C9EA9A7F7B6D3ECE727DAC128D31B7C0FFD9E43046AE6A53C25888D0E602B2302E255DCA8C58C10C010269152582C598FDDA0B8F43E311EA15BA96E0D9FF3936F5F18631FB9D03020E342647BE078C12A9475474B3DEE55ABC0E3DD804D73FD929B6AF94A67DD27C35B5FC2C9BCE500B8103B984423CEC746231A5B819ACDEA138816E70A95005EA92F7232B666E772C060F95E20612EB7DAD3297A342A7817C73E24318A0B761562D1CCB6B5D618CBE06F4B1E7B351B6B831FC83479EB34BF947B68B3A1B557AD866872656C9F59E7578061E84DBAE900AF3301BEF1EAA0C6424746302930BB685C8F3D9721521ED61BB648A4D5335C4EBF3061F8863941955242FEEEC86462828239F460F55CF9DE10BADA5627F9D3328362D6ADA08F70F0C65C5A155B2DA66156A6AAE555C0371328924928E046135DAAF48B86C1EA78B56F40AFB2794FB74B9627E2A43AABF3E17A84EE7AD30CF79EB20A72AC69", + "k" : "AC865F839FEF1BF3D528DD7504BED2F64B5502B0FA81D1C32763658E4AAC5037", +}, +{ + "rngSeed" : "D81C4D8D734FCBFBEADE3D3F8A039FAA2A2C9957E835AD55B22E75BF57BB556AC81ADDE6AEEB4A5A875C3BFCADFA958F", + "pk" : "93C140F6C47B7E53B96F72BB18447D277CC021C144A0F7A35E30B57386A78AC976376262320A5E7E1CB42E290DE684462CE1067E920EE86C32418B130A5A41A0E8268CFA7E0DB2B441CB927D7897C42B1D50F9B32868A35A2C04CFE91040E9A9208902F20C477E1B1EE5C290D2E5244EB1B4B7B4C6AD074533B58D9914A6AA8829F96789F5CB87607569983003F3A2461C33C81A3672AF5924C4BA37E6827FCCF86D8B4103FBE9C0F6226DD0A2145A6B7AEC76B186466F9C67BF169039259574456497140C8CF4AC05091973AC8C08D809465785A677A032AC09AD1D666E8C48462813CE5AC75F184B38251C30E362B0E2501D6800C8AD103C8B773780B6717CF15C401139ACD54B1598B2B7C79492A86631090268C70D875BC040CB2B75A386FA96B092B8CBC25C47F70AA76CD8B9AFC12B42B536E27C5578831A96DBBAB7138C3F247E955A6C08B4407D4708F1914BFA48AF4B28533F747B860B7076C028E245C9727B42F3248FB0408B3EF0C4918AB76AB96DACA81AFB1211AB3A0329BA1A5B069A68934C1CE84C2F72839311257FA19E72C62FB5686B61416CAF8B22D2B26A6DD01BB7387F88EB8606980A5E2259CBD56CA1EC051CFC66F96239991A2360D75DAFA1534C8A05AB9C95E2E586853714600A3455511B62D94525D8B1A965CE69F986731888D1ECCE536000E4863322A83E3C8475D9EBA5414A65B0561D24A7B09DCA6FFE23836058BEC0A85671641008C831233C7890783DAFE8C359A263E796869118C4E74002DC3B0EC5B1C4AC641BAFE30EB2BB743713BFED2C1E79C4A6F46593006ACB35F7031F194807B893AA7A9323162168D384D0E96F2F23368626A2E027891AC94F12F30A044B85F0322CE2B16517D36AA3F23B5F391BE394B54DDC28E5A9775372869A7B50B4898C072C0669D43C641A3CB5E8C170BA63BED6AD1008615201305E292E1C818E1EF64F3E0C52FBA67E7249C1EC4A140DC89CE0050647F1C19F5897C77B9059040B4B5B4282E0669CB4C658F48F67338413C92FC7412E444BC635DABC93C51B030784F21461DCA210CC6A54FDC25BBA09705BAA77C1826636B16644A5ADA51270D8317A787ABF53192D40DC765BFB45C7DCAE58481AF3A49FE762B90BAC1F6F69A5DE8045981C67906B9F692625FCB6A4DF2641688ABA61FA49A84B47C96661E4701E5826C1108069C4B9C6E480251C4B021D11CFDACA12BBF9C09A0234186668E389454AC4046F5B2468AA2FA9B117868574E729574EE57EA7495AF310627B85916D6B4C708374F9FB0C9C3AA4664C6651281D8EEB98132C1AF13A816CA5B869F50B50B291EFD466DEA090918630C6FC77247C458AA82568A41DD9D4708AF3BBCA5A5716447E8C2C24AD788A8632473FDC4A257196BD2B549091176FE654D3694E10A118F7B66D1CD5AF199B6E90B3BFFA88A92E36717FD4BBFCC78B0E08634BC080C86885C92C8EF67AA4933C7DF097891369BAC5FC5D0C36737AA60971310ADF02C257F76A7A7B3F7E132C2A71C52FF4AFFB6846391C0868241A3DF13408D419A78BCFFD49619B03A192C683900A244289C9F7B4564823900CEACFFD9A9371260D5E57A8271196F4759EEAD0CEAC318966E76F68DE95AB9DB2BA4FBF83C3B27092CD339CFE48D5CA0BA11591D04566F4ED24A5", + "sk" : "A2B315A16CC2CBA3500ACA6746967DFB808D170C0583B1AD737B50EE3408FD1C793739845FC18297341662CA3630C11F7BF77710C414CC925A3C4734CDAAB8F1F677B33694067B230ACB79B30262F74B923AFBB06AB880B75A609463B40D908115489F3942473DC8A555E2403B7C1DEC411B9818B627457A583305301CC34C4CB1DB2B12D6F10CEED4269FDC9A67402B89B71FB372A4EF593A17A56D329B10AE24C6B3E750704B0993CC64A71840399BCE5D7B182B561C9CB2B914673B6A5337393C1D77D497F426CDE194363B50683E1B2C8BD909621158FA8B0AA234A47AC702A95A96B37C9F2A233E69B9779CE793788A0C2EA25F9B5A9A8444AFD6B62F5AD6860C8AB1267A0E57ACAA53BB86C6428CD7139BA48954EC55BEE3F83AC5A47EBD328F053182D395CB7576CA56A639B3663E92F79AF13ABC20B251FD903524F9A16CC32B631C83B1E7CF5E04800E193F1595C563870EA1FC996F3828B2ABC626C59137511FF6F40122A25BC644B154267A0BC6C1067078C993B3D5D018F44C56363B9C5CC9B1CA6569CFF876578B5E86703D30C20D733553550B1A8E669F2999B62720B6DBF1100EA550FE6C3973B6A396B50A03235142D75603240F78055F082B1D2F490DADB8B3A0CB0EBAE99AB2179F2B38B274C51FEBFB57CC87291E34BBE5FCBA818A3F2DA4C3FC8950F51C1E806C5E6F4552F3E187D82A0CF92B7DA3F26AE04B8C86F7A91B545670B409DDE5863CC7B7E30B937B13ACCD1C68E808AE6827175BB8239904A88A15824BF6489D1044620844A6D92469A311942C21294BA5F26C18DD0A0E85FC85F241C2151815EF00B3BED322DE98A7F7092DF5A0A5D3D6B424B26B38E1931DAB2402342BC12463AA96A0A1C42DBF73BA15278A22448A4FB6012C214DEF53B0FA233DBD096CFB2045A255C75A9931D7E3284F9B95F648071F00343EE580193627FF1981E982264E63940287860FA763663CACFB61350E7A4B53F7702432347F22596C678585E3CFBBA07D782766C8399AC21B37A8B16A79E6A41FF606469947AF07C226F79145174BA4CCB4BF226CD5CAC54055B8A0815020135B94E6560CA89C7D837E737A73A0278F0E8B1B29806C19858B8337967D527D0DD6A25A5B0F2338B23AC6A4A0496FFA8672D17075CC9C3B20B24FDF9548567A85F707998A375BDD044038C09BB4FA1AF3F08A37FB6B17ECC29C756CE9085EDD76618B5C459BDC4E361199ADA77BD1F91086F443DAC6A9ECA4CE9403B4C5CB1EB6D74ED2F79CE9EC032174748C64416B676D11FB28E8CCBE1FD3AED6D0C168E92E3F7096403A3FDBFB28505087C6DB9F2E44233773B03E5166AE1669041212CCD58EE8580A2D6861A30B6814F6CB550A7D9314080413BEF5C847C94174E590B765869D0C9C6002AA377BF77D7F068316050E62E72A7BD083403240C1088F84287849112A03AC8DDBE907AB574C4BCB356E9834D4FAB5C28B200FE233A61599C14259464A24E3210A99C7C601A81D2AB07D65A9504BD68906285545241131100CD03B5DFB05B5B4BA29166C226ED4347C2CA99D327595F29CEFBC8636161C4B755F87851675D5553308C70EF0A8FEE3BE05A27F53075AC7D1710ED3177C133793C140F6C47B7E53B96F72BB18447D277CC021C144A0F7A35E30B57386A78AC976376262320A5E7E1CB42E290DE684462CE1067E920EE86C32418B130A5A41A0E8268CFA7E0DB2B441CB927D7897C42B1D50F9B32868A35A2C04CFE91040E9A9208902F20C477E1B1EE5C290D2E5244EB1B4B7B4C6AD074533B58D9914A6AA8829F96789F5CB87607569983003F3A2461C33C81A3672AF5924C4BA37E6827FCCF86D8B4103FBE9C0F6226DD0A2145A6B7AEC76B186466F9C67BF169039259574456497140C8CF4AC05091973AC8C08D809465785A677A032AC09AD1D666E8C48462813CE5AC75F184B38251C30E362B0E2501D6800C8AD103C8B773780B6717CF15C401139ACD54B1598B2B7C79492A86631090268C70D875BC040CB2B75A386FA96B092B8CBC25C47F70AA76CD8B9AFC12B42B536E27C5578831A96DBBAB7138C3F247E955A6C08B4407D4708F1914BFA48AF4B28533F747B860B7076C028E245C9727B42F3248FB0408B3EF0C4918AB76AB96DACA81AFB1211AB3A0329BA1A5B069A68934C1CE84C2F72839311257FA19E72C62FB5686B61416CAF8B22D2B26A6DD01BB7387F88EB8606980A5E2259CBD56CA1EC051CFC66F96239991A2360D75DAFA1534C8A05AB9C95E2E586853714600A3455511B62D94525D8B1A965CE69F986731888D1ECCE536000E4863322A83E3C8475D9EBA5414A65B0561D24A7B09DCA6FFE23836058BEC0A85671641008C831233C7890783DAFE8C359A263E796869118C4E74002DC3B0EC5B1C4AC641BAFE30EB2BB743713BFED2C1E79C4A6F46593006ACB35F7031F194807B893AA7A9323162168D384D0E96F2F23368626A2E027891AC94F12F30A044B85F0322CE2B16517D36AA3F23B5F391BE394B54DDC28E5A9775372869A7B50B4898C072C0669D43C641A3CB5E8C170BA63BED6AD1008615201305E292E1C818E1EF64F3E0C52FBA67E7249C1EC4A140DC89CE0050647F1C19F5897C77B9059040B4B5B4282E0669CB4C658F48F67338413C92FC7412E444BC635DABC93C51B030784F21461DCA210CC6A54FDC25BBA09705BAA77C1826636B16644A5ADA51270D8317A787ABF53192D40DC765BFB45C7DCAE58481AF3A49FE762B90BAC1F6F69A5DE8045981C67906B9F692625FCB6A4DF2641688ABA61FA49A84B47C96661E4701E5826C1108069C4B9C6E480251C4B021D11CFDACA12BBF9C09A0234186668E389454AC4046F5B2468AA2FA9B117868574E729574EE57EA7495AF310627B85916D6B4C708374F9FB0C9C3AA4664C6651281D8EEB98132C1AF13A816CA5B869F50B50B291EFD466DEA090918630C6FC77247C458AA82568A41DD9D4708AF3BBCA5A5716447E8C2C24AD788A8632473FDC4A257196BD2B549091176FE654D3694E10A118F7B66D1CD5AF199B6E90B3BFFA88A92E36717FD4BBFCC78B0E08634BC080C86885C92C8EF67AA4933C7DF097891369BAC5FC5D0C36737AA60971310ADF02C257F76A7A7B3F7E132C2A71C52FF4AFFB6846391C0868241A3DF13408D419A78BCFFD49619B03A192C683900A244289C9F7B4564823900CEACFFD9A9371260D5E57A8271196F4759EEAD0CEAC318966E76F68DE95AB9DB2BA4FBF83C3B27092CD339CFE48D5CA0BA11591D04566F4ED24A57B00751EB9B1253231213F8A14F06F0FE1B7A4FDB7D1CFE44C161E577E5E8F0A588522D326E7F105F11C4E8D97E119E193AF42DC28409F4F7572ADA538B52C1F", + "ek" : "4DDF4E2919943817AB3B4CB085DAEFE5FEC774D83D96C2CEE74149E25ADDD15F71F26C9312D6EEE0B9A9FA77B0BD202CD752F75A7DA575A2A66CD1C608F54E3C609FE096CB6C5B832EFF662048D8A789745A8316132F3B5B352164EA696537903A266623DD352A3FA8CDDE4A25D395019E5A418FF420259B1BB5A3BAC5A7DDA1E386B82E588A79F2B841B11758B36B89821380258C8ED66725E90D7AF07339BAD61710B1BE0A72A98B3E590DDAF48165CEFF918FD32384CF612EB713E856BC6178EEAA0C8AA6FF638AF2D6AA3391687BD7B3EB6EB92175C30239AC7CE026CDFB3D52AF168E3EEE005F8DBA5930588B4148987C8204DFFA60EC1AB449A09F9D39A60FFEF1AADC44BBDB2A6BB3B61B949C1BDB7C1C6386BB89789D09BD71E4F5CA72C7F4718106B275AE170555E7B9F32BFE75DD445BD3E86EB1B10449759EE2ECADD41262AFE50452FEA9C1371561F6946E8F797F2F6BF842B50DC72F386B4B41CD038085CCD61EBEE077300988B1756445D7982B9395AE02493B83B06486E7215ECFC3254E012BC058626BF2D5B2E0B341AD3780111F7D79DE7B5FCDAB1C93B1F6F9EEF16D305B833C65534D24F7F74EB00FFD18FE476983823BF9B9BCB7004C57BB884978E36B2F5B2ECF2D9C7BA4EDFE4BBD7AFB11D362717EA473F119E5ECC2DB580AE013C60AE6B74DDAF857F4F18842F337446BD5626ED3602651323777EE1E78B28F795C19F718014BC92E71177D6A4459FF1384CBA0F43D1F46D6EAC02C29FCCB959E14ABD3723C93D3505B5B444A7AB0470E2DDF85F1AD79F55F4D1FAB170D02754C1C28881C4A6A1406739A448DFE29F24C8FBA865C7B6D571802C81219945194E93A518CBF422CE47D8D8089A799E37E9B5A9CDA351F2CD40243C2EDD28B64333A5A1757830F8C32F32F4F9D0F7E6548B3DD2FB9C52BBCBC8176B29B9BC101DB66901772505A48F6C63E50BB3ED8331D27D8C0B5768A1646960AD4C0445629599D4B4E346F8B63F257D2DE7ABAE199890C3F2A55E3A62946A560F604139672FF9ED5D8DFBA8E619054E83BF2E86FEC1D3B3C4E5EC0FD9F2264442B4C25FCC30620D060D138B17FE7838E1C8D3D0A0E8AC64A57D98E9972962DDF943B6F8012D40D37002F3B9C9452DABB2633D387E83875A0113B24077AB8866FC6232F735C031978234D35EEC02E1BAA8089F04DB2502FB324F3BD715C08369CBDFEDFDD0792765006DAAF921494C70127CCE82479AB5E88BB02A1906279CBF69A26C01910D78B9FA11A4BED362FF454C129C228BE14CA49E3A3627AB2068C3CB779D47DA910E0B76E082F0C710CCE75CDB5DFE3A12045A7FED3F0AE171FF672C4A4EA307677B9B13F5C5E399E9DF1CEE855B325953F14AE4DAD7A9118903973FF96BB30DFBE744F2B3E54F241ACC441A89C1046C2CD6B485B22A76E8CDE39716383FFDED33526D1CDA24872331D7A7F2F273DE064216B7172F1C9006A864BF938213E16C21BB36BA3FBC09CA40C8081A7B2E164D9057F9065C8B4D6500512BE46", + "k" : "950492E940BFA86AC28183DE02EFC04017D1755106A854FBB2AC68174F705B41", +}, +{ + "rngSeed" : "64335BF29E5DE62842C941766BA129B0643B5E7121CA26CFC190EC7DC3543830557FDD5C03CF123A456D48EFEA43C868", + "pk" : "C02B820292C46C8A8A92975A2E27292CF893A7F54A84A67022845D66236DCA3C4844604B16879E849C7FE3475D03F82323D822AE2CB6763842A319114F5C77754613D5FBAEC05AA801A03AC1989A725337EA38A668EA65CDB36343EC3D690CCDFA47AB1FE473247BC488D98E1E33175920A0F2272A03982C8386485BC2C4245884F1D941750A1D27FA85F0067F5C377532304261AA908BFB950894CECC1BBFD197CED78A641366B9199A4BA190446E03AE51549BE7959C87A629ABF24CBB7A58D01CAD4949734F797AE300A78F45C70F668506977D7C85A0CF64C700A5B1F7879801BC3AC75584302C8BC81C0D7F6B237A9400681BACFC7192F9C653F8A9551F796CCFC262D3A438A551AD74C80AE9E3B5A7F12C5204AD44C21F488B7824A4B1EED79DA9B44E60D8B225490C062B924DA04F0EF0252304CCA34BB4FC70CE6B1800FB6C5DC771BF7BDA9E9DB2B6C6046A1672C6F6F01A0406B903411C271B20E139A69138ADFBF50C1134AE0899C166B1B1A5D818515B0DD94895A253059B167630F3A0DD3C64CF257CDF93596E54288C7A4580404BA8DA541ABB1B6AEC7E530C58A61A64D9B9BC32D870BC105EF7063B9A97519B871A60D7AAF8C193E948C267C9C815063D6A603EE8D2249B386D94395804A9AF8CD2184800C7CCFBAED98C4F9F95B70145B448387183F5CC8F4B5F35A949BC74706BD03DB7645C2D084624844A55A0A5ABB9244CB5B8736B835B512BCD912361FB660479B2C51B99734970808BA5C6DB0169756CFC986DBDA94915563C15A109AEB77C01A7CFF55C8430696D6E83AEA5D49292462D725C428B984D15E97ED4A76403094699E1336426B54281067E675788B3A4FCEBCA4431BFDC8A49C215BA11004A341516018419ABEAB2374184B0E2B7B7A54EFC678E812588960A0D009418E5289EDDCAC582D3C73DD93E1234518DA003648853C5B5A24B389E88300AEAE78C41E62E5EE303A56B548375757CD42E21A7C59FF29A133868D1D0784197573464292547161B3A8689DC0C7DE11139D407F0B5784D942278D49462965F21F72CB992ADD160620F6A82F70AA9A830190CE3C9FA8015071C2877483C2203BAB7228EE2F37BBB17C1A4BC499EC249FFBB42E4989905A878DC873E456A7D9DB946572936D8D81777D1B992C00DB12A35DF1348CE8C9D1A02898C7403D4107F45A6BEE864375B623D30E0C191F8AD835A3F3709362CC763D63C2B91649D722825402C9EC1B1C7AA02B154D69E39DA196E72A25928212FE0711BBB2FD2F9550A361A28D4295BF0C036D7B79BE9130232060206C919F8B864F03D6F02348ED2C8001A30124B40C6D61DC3E18BCB27C60BD1324D8386DA99C3E098CFB94B018031A4D6AA5788D27A75A67B630327ADD804ADC21642D58080956A03F03C8193AC302C92E949CEA31721813390382C814B2C5A6D34A1EB44B8B62AA77BF88B5067455FC0C7BE967C21BC281AD38EA6978D228A83A820C57B4039175C910A450E300101CAE45B0736A4DCBB0E6EB58491DA31DE3B65CBA0A7C80C7815F677EEA7CE5EC571BBF7C4516C65E4B2528E160959C815E1BBCAD0A29CE59573D749453D9B6B52A951DE9B889C79CB355C345631070B7C30F1934123C9EC68EBB324D254E5D246B14A0259E49B2CCEC72B8C494834", + "sk" : "C22702A2A8B54046661FE48E8C686EAC807794EB4A67454D68A12825C99C73B3620F1482EBA71C724CB8EDDA16D05A2D630A4B7D967D33F42B352A07538A8CCFEB481776BAF74073FEE48709F01229D087B9F16D36E907AB792BE2B86BACA7C58BF31B63AA556613168140AD1CB45A70F3AD8F88AC7F6B42179B62707BA00FE0776FF45F575436AD70BDAB0769E05587314BA7F1802B2CE6536152A5076A991ECCB79A908351F62E38C75BC3DB7B8702A104155B87129B2B3A6D3A157FBA573C1B96B2B8EBC5327267AA47847259BF46F54C315B26748A6F49EB3721E772032B6F0DD48A44755EEEA543624CB62C6965840CAF314C81A7D49C1A2AB46D047BA45244B8B292F72252844335DB158496302E1554086B4A2DF68A1AF1737F743B0BC4E07BE5FA2EDCDC4BA03CB61101327FDB6E99A2B1DE800462431A5E45870F5BB61E058B21EA5A4F86404F99459B4C8CC5D91AE4E630FF1C380B3919C2F22F06F633FC062451B462130117E5F20CAFC2760C434E404944FCC03D64D5AA8AD11EB2F727DC71917E6200F61B53AC7497EB198A417753482C3FE988C53883372D08AC11C5AE57A24B787A995F6ACF6E359BC7121032E4BDA65C618963B84785A86DA1236289BB2A6B6716F2054DD43C77020D8686B47CA1B7EC2AB36C07141FB86937141F45D92219C25ED9C13D14C7AD682640A5F88B5574A283AA3709F26D9AA739F55C776526321942CC8115A69E790AE357765C7A05AB35266DEC2DE96ACF5D126CA86763E18999E9513F5B5809130B7E2616392A3514638B39442A6E98C44A35005FA4A6B1488C9F181C4747A935626895F3C623DDB44E1D581A11465FFAC0A0A1F2A5F881456654490A1B1BF1E4485A94841519BABCCC2AB594B1C2532FC92982DB3994161B15194C265B679FBB768970F885F04AC06F62692C9576C81B8979F221E545B150C9A57F232DFBFA7D9EBC91F5ACA92A3CC39AE922F1257F1973979B46AD1C967BAA7002C36080A926467F277AC234C31C716CCB954B617694E7D228164A1BE2E13B7B855534FB50B88C937A191CE493CEB19561D59B1F198B81C78371A58C5CA4F38BC6981FAF61A9B60941978569162004ABFB82AB729D4358C207A915D55458C13250BA813A8A5396CFAB1157B4A266033050D31C1B74AFC55C645BF256F00392B432A99092A30ECC456BBA202BCA14E5C741830C931EC377FC163B5F16B81B3897FECB961C6A0D8D97461CFAA8F4C48069648E8B48864DD9923B9B1BDD44290AA66290C151024285C3732A2B717C55072D2168AE92F001A1C44B54DC24A0145781923138875D8F4A0C76E2A79FAB7D10A141C57CA9C8434C8CA18E9D0271AE62A391F28C53361C759914852859F1970CAA124A1FFB3797723429874F3088197AF94A9557CB66FB76FA84BBF5BC87552605FF00C67EF53C5E5C68C5800057F6A36B391386743BDE6B4800B4AA1C1984EAC8A728A729AD60A6321A22D6A9B27B56BBC7C65F7AE34304827E833AAA867766079074C8E020C32B87FC6564E5E4953DF85B24991AFF87B052847FE6371EFB03A326A96514DC6AC8F42106F59DF9B10D668111A1A9B08C7BACF2A42243504CCB9ABD737593AAB617C02B820292C46C8A8A92975A2E27292CF893A7F54A84A67022845D66236DCA3C4844604B16879E849C7FE3475D03F82323D822AE2CB6763842A319114F5C77754613D5FBAEC05AA801A03AC1989A725337EA38A668EA65CDB36343EC3D690CCDFA47AB1FE473247BC488D98E1E33175920A0F2272A03982C8386485BC2C4245884F1D941750A1D27FA85F0067F5C377532304261AA908BFB950894CECC1BBFD197CED78A641366B9199A4BA190446E03AE51549BE7959C87A629ABF24CBB7A58D01CAD4949734F797AE300A78F45C70F668506977D7C85A0CF64C700A5B1F7879801BC3AC75584302C8BC81C0D7F6B237A9400681BACFC7192F9C653F8A9551F796CCFC262D3A438A551AD74C80AE9E3B5A7F12C5204AD44C21F488B7824A4B1EED79DA9B44E60D8B225490C062B924DA04F0EF0252304CCA34BB4FC70CE6B1800FB6C5DC771BF7BDA9E9DB2B6C6046A1672C6F6F01A0406B903411C271B20E139A69138ADFBF50C1134AE0899C166B1B1A5D818515B0DD94895A253059B167630F3A0DD3C64CF257CDF93596E54288C7A4580404BA8DA541ABB1B6AEC7E530C58A61A64D9B9BC32D870BC105EF7063B9A97519B871A60D7AAF8C193E948C267C9C815063D6A603EE8D2249B386D94395804A9AF8CD2184800C7CCFBAED98C4F9F95B70145B448387183F5CC8F4B5F35A949BC74706BD03DB7645C2D084624844A55A0A5ABB9244CB5B8736B835B512BCD912361FB660479B2C51B99734970808BA5C6DB0169756CFC986DBDA94915563C15A109AEB77C01A7CFF55C8430696D6E83AEA5D49292462D725C428B984D15E97ED4A76403094699E1336426B54281067E675788B3A4FCEBCA4431BFDC8A49C215BA11004A341516018419ABEAB2374184B0E2B7B7A54EFC678E812588960A0D009418E5289EDDCAC582D3C73DD93E1234518DA003648853C5B5A24B389E88300AEAE78C41E62E5EE303A56B548375757CD42E21A7C59FF29A133868D1D0784197573464292547161B3A8689DC0C7DE11139D407F0B5784D942278D49462965F21F72CB992ADD160620F6A82F70AA9A830190CE3C9FA8015071C2877483C2203BAB7228EE2F37BBB17C1A4BC499EC249FFBB42E4989905A878DC873E456A7D9DB946572936D8D81777D1B992C00DB12A35DF1348CE8C9D1A02898C7403D4107F45A6BEE864375B623D30E0C191F8AD835A3F3709362CC763D63C2B91649D722825402C9EC1B1C7AA02B154D69E39DA196E72A25928212FE0711BBB2FD2F9550A361A28D4295BF0C036D7B79BE9130232060206C919F8B864F03D6F02348ED2C8001A30124B40C6D61DC3E18BCB27C60BD1324D8386DA99C3E098CFB94B018031A4D6AA5788D27A75A67B630327ADD804ADC21642D58080956A03F03C8193AC302C92E949CEA31721813390382C814B2C5A6D34A1EB44B8B62AA77BF88B5067455FC0C7BE967C21BC281AD38EA6978D228A83A820C57B4039175C910A450E300101CAE45B0736A4DCBB0E6EB58491DA31DE3B65CBA0A7C80C7815F677EEA7CE5EC571BBF7C4516C65E4B2528E160959C815E1BBCAD0A29CE59573D749453D9B6B52A951DE9B889C79CB355C345631070B7C30F1934123C9EC68EBB324D254E5D246B14A0259E49B2CCEC72B8C4948349BDA55B63CFFA9BF953993918B18CD6595EA6433B479E89B5CD3C9339E4468CBD5A45A4CED06403C5557E87113CB30EA3DC2F39481734DE9E18BCBFBECC6719F", + "ek" : "C1C4D5866B3FDDBF2DF4553FBFE2FBD28D11DF5132D6E4020087A52E9163B76FAA2284FE8B82D68F3170E54632C77D5F4ED42A7445731899E6793D85F166804448CB4B0316086F478B064A5219C0625B9647AFB07B666121C5A97D16E2AF0BA7A36772431F8BFFFD086D8332F2CCF175F70A969A822720E7FB1618F2A51DE2A25EE3CBFB2116BE734E8D4B8EEC549FC74160522E776B8EC1B70B8D4F69FD0392291DAFB0614914A7FDABF819AFDFDBE0888CE346CC9AFE966D1CD7687791B5FE13E5114F670E99020224F7BB653711370C9917260F1C8F9C74FE78FBF68822E806541987BFFE1486731E6B7841FA91CE973A4A358072F219EA3B070C4AE35143E6A388FB1D0B80FC95A1073184C8798F0E2D625597A459F38EAAB378B4FCC09A38B4B0AE32D417DA16BEC1D2E907B12B12BB30D9F95F849BF79522622CD4068F7FA206D0400DCA69A404D48AB4EC469FEDEF37ECA0B41BBD4CAE6E8DE1066394E944349230882553F65BB9B29B74A121EF7F1C681995EC829CABB890E226DEFBA9DE9297F9841D0067BC18A93131DA91745839F3F011A1EB96A2DF3F7859F675D91F97446DDDE2E96B073B3B016B526D9C4B5FE2C8EF986D12173C6BFBC4B528E7B90F232025F8AF4CFAA029A9E81EF1C2E012D6387BE2FBDED405902705DECCD073FCBC4D76B55A7A26B2BFC488BAFE2CF595678839E035F531D0BA365EE4D98D552476EE1071258DECA125B92C0A0481BDEE6D48F502F577978B1FC818D6CCC3B0504C1B3BB5EA34D6455EE65435C9A10204B9CF041B7FD015F4FAE346269B7D2E7D6F1FF6261C43C11509287F3F644B14CDDEEA5AC9F659867F47EAAD6FE36EA58B4AD2B2F7F47E99A3239D74050607E1BEC9AFAE1221D9D0E0F634AD69EB618DF4E67AEA439DAD2C3B63875B716513C885D1FB76D9994481397FEA2D5BC8A56364D4A84AD76B6987632DA997B32D11F088CB4244111CAB008122E63C7D4A50B18F8D46AF7CC627DD9C0367948FE4804C482A5632AF94B0D0AE3F0523E19E3B1A8EC7FDE1ED66E0A50D17C19526919CCC81D593B1F65EC869DEE8F256DAB08306B85CD3B4062DF725325502F3DFD0F1F19BE6FDDC9401B8C6594FE100F77771F763BE0C9726B8F2C138981F91F000ADB4089E170D35596789A43B7ABBFA62FAD121507592D64E04EE85C9C27322D8A67D381E558D6F9D7B75220C400AF4E1E154245035D4AAF8D874AF51D5A0153DC0EDAB33D9B14702E242EADB8D5781894DD509CCE0C7CDA6C5EA8FAF2841F1609A25B0699A349550703739CA2F4581066C80FA80AD0A62BE3E7F846C30D3967AF9333F8FC3A8D6F6E411EDA8EBDD0D7F7D0076F9933985D8F6B3F97F605FF65A50CAA2C795B2E4A71CE54B50BC6768249FBED1AE45B201E8D05AC8C110DB4069293379DD9FB297E6930554E80A1DB24E08DBBB03AECF3E308F4A6F0E9CF126BAE888D0BC3F30BC2590DF642BAB346CC220AC3101631A3607E3BEDC257CD8D403567C7DC07193BE40440F94E2B6E2CDA2", + "k" : "DF7FEFB0FE72980E153B5E99A966915BD4C2226B2490C655109A0723AB8AADE0", +}, +{ + "rngSeed" : "225D5CE2CEAC61930A07503FB59F7C2F936A3E075481DA3CA299A80F8C5DF9223A073E7B90E02EBF98CA2227EBA38C1A", + "pk" : "25C1215D624156828088B63DA622AFA9FC5476B3603474B24D8394B93AB494EA3EB0F33FF5D91A33D34A2F666235EA009E35544CF135EFF54E3575AFE2FB15B6B59A4DB843C25139ED345FA170003FDA60B240065F761570471C4914AEFB01C38FE36B3C7B80F77887A03B74BAFB64D3B922701A86B027651FDBC777BC4D90D387FC15B8C12443AF8636E35224C0430520BC984D71C56DF26E84B683C1DBA081B0A584B5793E725775482EC45B1DB7C84949644D405579659CC31DB130BD190D2247210C043BC8F227450AC206C13E8BAA896E471F7CAB2BDAB29220C051BA354DC404767E812765C66EC19ACBA3B993CAA2C0BC2367DD50846BB40D6587B51A76277F6865A5C69D885553DDFC200E970B9C0666C1854EFC932AF57A1F3BC0A805024EFCF978F77B1DD739604B8A87B44B522EA80E87CA2CBA7220E62C441A429D19B76425D51CD1E61E2A2950922637A1AB84FBF645A1F6413C288B731945D4029958D56DB90AA01B712C83B73AA88581522757D505B83E61AE06EB6F5270021C61B7DABCB0229878D85C8F352A9A4349BDECB2AB0C2AB4039940A887B665F8B9DD10992B3B0493DB6074FA85E1382A970953EBF113D4835E9F031D390836732B3EA6A89145183F72DBB095D7617A3ABDC28912972035F1CC30AED3101D91C9EB397680C8AE222AA61E515A9396CEFCC75C0CC255535A3F41212141C12558881E23798E1748BBB5464ADFB167A2C44388044754A87A5AD1CE752C38B504BC443A24FF73A6CEA4768E22681554B56DD59DA1C7B88DB126B7EC640C1BCAE8A20B5F864EA6385DBBA1C4DDD31775CA9F72EC6F137570FA9356DE55C5C2EC92048A0CD9680837F98763FB35D1431805A7420D2BB803CC37BDC90FA921BD4D18B4F33419CF03AD0E2360D92192D7D87DF71BAE83D2B538741914892C0D778CFDF429BE268A22F4043C29B62FF74FA770156D93127C3A7FE2C6C6C65470D1931F85A3AF1A963BD919CA3C437B43D368E6E7A199407258B8BDE88B4742192673499AC440B247D97225E7554482C6AA6567486074F15B19588C6D9DE4619D4C493BF73F2BDBC05343A581E95197B64DCD8826442565BF629D5CE4045218BB908701A5E53B2D0679720598FA1B08F286B60E5C377CA7AFAFB206ED4712D6D16A47B99360426619F97DB0059A15592353577765A8368D93928802704836C2279205446BBF7A2465042816D7907F143635B1434680156523B02CF1D8565CA5C7CEAA126A2753DC299C10E4968A4729991A0F5CE31C595629301C135B5810A712910A84CE1F2164C3ABA248CB89C591CA0D24A7681C0A140672BF01C7F5C967F3E41B9A925AF6EA75408A24684B725B446A30D0199F67AF94B958C4B979C2A841B28878B5DC5154B79C944C7156538E6A130379674BBA5438D64775FE1A87D3ACA677541BF82C27C6D18F3BB182BC7494DC91B23C35392F21AC49E69E3C70454BDB16B2394D00A549734A1AA4790B01508BE670841E09042E5A1A4A73C3B830AC5A35B826F36411639E20576A89197426005C08380C13A4A464892BC6992E236771E7B135AEE096E9F65738C531B8E63C3F4A922A79222CF8B8309A04C3C7464A69982A072FB895714EB8F4E6D0A4C447AC97280A7A7B63BD585C521A49BF9230588DDD7034", + "sk" : "EDDA9B4FA2880D5778280A51A25A02B4D08F44F83AFCC7CCC3692AF517738BF8AAFAF53EB33004364AABC42BB0A640B12266BC6EAC91D124867192C485209660D625C33AAE9F38535903CDB178BC2AE557E71ACEE8208169D80C74044490B3CE4C06B2B68B44B2C0B47D3C9178344F7A7A30DA49548656B011B74B5BD1B23A1B39F9F37DCBC91C697799748007F80B3D55F6CB81B926311636FF11CFBBAA31BB02689E9B3B983213C2B3CD8D4395BBD46DBD25B345CA920F9B3545F13D4B809DAA02608B4C5A1E041A98B3320B91802544AAA98A4916C7C49DA792F6A04A4D64AFA1294A8E71ABD47C4D96D9203C7610A10B762E91B386471C8EEC6EF94259B8440C369153AB6B9D6B52994271A865E20ED1136435CA490264A541207707881EBF74BE6259B913B38A2C54BE4EA88DE1DBB3EB59B91497A13304C54A23A3A1810674610255350967A612B55BC82A22AED447B09BBC6F92FB9427A4BAA183406EE6CA14E35808E33BD339A9C428213AABC6ECF473C38B62AA7C6CC8B30F9A559565D413C8F504CC000FAFC4420177C054EC19C9360C2E04504B8B7E7BD86B820B1996A815337043F65975401C76A863A2803B0C80A6062E827DAA973EFCA23502FACA371CAE8B42C4518B52070B91ED07A5BE9C9DD304386592988FB1162449AC12589115E7C14776977BB34AFF985C95F40265C20B4CD6216702C9AD91345CF120CE0C2961872BB6E42547412BD226AB8FBA97B8E074EB0746D61140E07A51176227C9559C4BEA306BE88E2B84515C528AF3BA34CC71C06E7CAC19B998B23C549DFA2E253A33AD23B905E1C55F96054C3C4D0EE68F4B447404B8A752F4A9CB6ACC624A7985141055733F47D4220EF164F6C7B6573BBDA39365890C0C0318827A701AC4670878FA11FF24B3C57B56ABF09ED2AC5BA554A8DD184FD09695CB2C798AD23B86F0690D6840C77C53F98491845C0C335B601B26582D9758A244603035139C98B9A723872D16694A4B5165A22FC281142251855998CD6EACAD79B8987F143B5A7A69FEDA51D66B1C0E453DAFA5209A225C1298A8F922CECB2C6EBC63C762F285FF667469D1371CC5AC957A495B55834C3B3A4EE9BF2A85C5B7062742A940A686BF0149542B6A350FD2144A849D6D71CCBF7336FA06AA4F7AAE89E586C4D093145B8265699F5EF000EEDC0CEDC96E3256072DDA4FE71789EF1C4734E3205AE617AED6A8848083FEF84C61128C00645E6B4319B950AE0322AD845A58BC4564D2BBCB9E08858AAAA8F547070EA54412EB5B608CB7883472D10ABF2CE4143E461C1DE11B5178CDD8924D93666AB8F44CECB954AC431AB89208D812CC29073E2DE706953C2028FB236C731DD838AF9D310C1538238743BB71FC3546A08FE4E35E965903F2FB7E1A9A2201F6A86F38B21F22906D659F4BB8A226ECB8A107B217EA41E542075D01CBA7CAAF1C97C014A97AB49666E0015EEAC597717B1E1E8773838958DFD1796FE1A7B62583F575B1C0E676A916799BFACEC28BA707974131F36BB2292CE4E99CC2046B689624E069AE46DB94FD66A5CA083851940BA26341BB891FDC860D53741F084B2D9E846EC2BB5EABAA69A8D96A8975A1D6F33835A53225C1215D624156828088B63DA622AFA9FC5476B3603474B24D8394B93AB494EA3EB0F33FF5D91A33D34A2F666235EA009E35544CF135EFF54E3575AFE2FB15B6B59A4DB843C25139ED345FA170003FDA60B240065F761570471C4914AEFB01C38FE36B3C7B80F77887A03B74BAFB64D3B922701A86B027651FDBC777BC4D90D387FC15B8C12443AF8636E35224C0430520BC984D71C56DF26E84B683C1DBA081B0A584B5793E725775482EC45B1DB7C84949644D405579659CC31DB130BD190D2247210C043BC8F227450AC206C13E8BAA896E471F7CAB2BDAB29220C051BA354DC404767E812765C66EC19ACBA3B993CAA2C0BC2367DD50846BB40D6587B51A76277F6865A5C69D885553DDFC200E970B9C0666C1854EFC932AF57A1F3BC0A805024EFCF978F77B1DD739604B8A87B44B522EA80E87CA2CBA7220E62C441A429D19B76425D51CD1E61E2A2950922637A1AB84FBF645A1F6413C288B731945D4029958D56DB90AA01B712C83B73AA88581522757D505B83E61AE06EB6F5270021C61B7DABCB0229878D85C8F352A9A4349BDECB2AB0C2AB4039940A887B665F8B9DD10992B3B0493DB6074FA85E1382A970953EBF113D4835E9F031D390836732B3EA6A89145183F72DBB095D7617A3ABDC28912972035F1CC30AED3101D91C9EB397680C8AE222AA61E515A9396CEFCC75C0CC255535A3F41212141C12558881E23798E1748BBB5464ADFB167A2C44388044754A87A5AD1CE752C38B504BC443A24FF73A6CEA4768E22681554B56DD59DA1C7B88DB126B7EC640C1BCAE8A20B5F864EA6385DBBA1C4DDD31775CA9F72EC6F137570FA9356DE55C5C2EC92048A0CD9680837F98763FB35D1431805A7420D2BB803CC37BDC90FA921BD4D18B4F33419CF03AD0E2360D92192D7D87DF71BAE83D2B538741914892C0D778CFDF429BE268A22F4043C29B62FF74FA770156D93127C3A7FE2C6C6C65470D1931F85A3AF1A963BD919CA3C437B43D368E6E7A199407258B8BDE88B4742192673499AC440B247D97225E7554482C6AA6567486074F15B19588C6D9DE4619D4C493BF73F2BDBC05343A581E95197B64DCD8826442565BF629D5CE4045218BB908701A5E53B2D0679720598FA1B08F286B60E5C377CA7AFAFB206ED4712D6D16A47B99360426619F97DB0059A15592353577765A8368D93928802704836C2279205446BBF7A2465042816D7907F143635B1434680156523B02CF1D8565CA5C7CEAA126A2753DC299C10E4968A4729991A0F5CE31C595629301C135B5810A712910A84CE1F2164C3ABA248CB89C591CA0D24A7681C0A140672BF01C7F5C967F3E41B9A925AF6EA75408A24684B725B446A30D0199F67AF94B958C4B979C2A841B28878B5DC5154B79C944C7156538E6A130379674BBA5438D64775FE1A87D3ACA677541BF82C27C6D18F3BB182BC7494DC91B23C35392F21AC49E69E3C70454BDB16B2394D00A549734A1AA4790B01508BE670841E09042E5A1A4A73C3B830AC5A35B826F36411639E20576A89197426005C08380C13A4A464892BC6992E236771E7B135AEE096E9F65738C531B8E63C3F4A922A79222CF8B8309A04C3C7464A69982A072FB895714EB8F4E6D0A4C447AC97280A7A7B63BD585C521A49BF9230588DDD7034647A81F0F1B3E3DACB6E73E900F7C078CDFAA7119A5EDE48C7685FDB7E0FE2F53E0351BDC8A2DAF0258645C383021DF33FE59B553A8270C1B7A4D0AF155999B8", + "ek" : "29B0DE2C9BDE97A5007F6020F6F2DAEE3A002257366CCDEEEB9A556552480A83D44927275E855C9D31FAB889D1E34A1EBD8A6BAAA72B6816A7616188CB9E99E923FA53782A423AEA1B7891ACF51A252E25214D16BCAA13F822CE23FE19E94DC9DF702399FEDDF63093C8585B3A74904297DD77BE8D5E159F51D2276B269A9B94E2018A54E113A9EEBBF5A7F032B92726CB02896466AEBD626C6443344243F05B0C1B0D68421CB7E71C42FA1C98916956E1C03146D0D586E54F19DDF8265173954DA650B84E2753F63E69E1549B0C548AE104336D7568EFBCD2CC5E6486A51CD4258089E7215634592D22DFF9D448D0061C78E1EA87F223129762712EDBBF03625EB4B1891C5151D4E8787138F739B53B8DF2FE759C38DC2AE8E5629529A178ECD352253A2EC2E4F58F0CDE489E5D1A790E8237F97B1EC4D7E5FF65F229BD2CEC4B59AE4EDB38E65EEA8D864B6DD645DB85528DC316D9E55721B25DAA68A5A84B1460F303E57EECCEF94DC3708165C80DA1AACD8E2A6A69E5A373E548B8F46AB41218F8497DD46F374150747F27685A79859DFC16FD794C9B27548DE83A76472C15BBFCD3B07FF6A5BFBD3299D9D5D13EF83C1B0DD9761CA575086FF29805C3E3FBEB98174155C1014FC9249215D7CD71BC4100E1A2DAB4ABA21B9C26C56C34594A66EFB3FCD0FB994EDD99ADD8CBC785C4FCCEF1FC165FA5449866F0B1A4F66B2E7FF67E7A7313F419681A38A03EA9173D02A21EEF667AE5A1C7EDF3E4C7DB3BCD94E2A56093B059EEC2D3974680A2F37CC1DF227BED2DAE85A1E6240409F2F0FD69A9A45F1624B69CF072277A55FD449F88BE3C588F9FE1FAC6B1A100AD649DD141AEAE3AB8DE5B5CF4491BC67F210929FD081EF2CD748D20FAEB0CF1C0D8DA611A245F985ADFDB6A07ED9951C0B735E36774F9BFACD3C85EEA16D5D6B471358EA61278C6C5E3FE3C3E91C8EA89B2C870025233CA9416559B44EA2A00E3659447C1E4F480B3DA8EC26FDB6BAAE47B3BC460D67B63205A51F17A790FF1BD1916B71B276038A7D79C7F903B427F3D53B56177D4AA508509EA4B6F0FF469349BF16AF4CD60E5903D377744614462450CA2BF6BD25AE8B1C427B3A3414407E4FAA1B8AE7D8469B41FCA5CCD29BEA917F71E01DF4C00275EAB5180E6EC9A455D341BD8CD90569DB8929A6299AC391CB502A35E76559B99CE4F2C8A7F7672CB73DBD481E0DF7767835A18C651C3D297D7D4E65A7627C9A7848748AB555238F8B62F61CDC426928698410E8059D3C4522125ACD575D06528C44912F31BE49AB5D298F71AC64EE3D96CDC6B7BBF834694EE815B3FA5F3E1CB760BFA263889672E2785F16252D3545F51EB1C9DF232E583A556C5EB7938FCA695A5117E97982AB815BAD059918BBBDE8BB27791C08A669D07227795248EDF99ADE24318735A1C977B7CECAC2E3B9425EDCE5344AD52BD3B94F5507E2131E98F3E5874313D6C1AB0F98556CC9A3B179022F1157D7B117C3E70E411DF1BFEB0BA6B7DF2343573757B1CF42A", + "k" : "DA723F95D43D70E67C858A10FB7C5540F91406AEAAE806ABC0EDF48D24FD947F", +}, +{ + "rngSeed" : "EDC76E7C1523E3862552133FEA4D2AB05C69FB54A9354F0846456A2A407E071DF4650EC0E0A5666A52CD09462DBC51F9", + "pk" : "711CB96F0CBB88A8C1C298C7837B2F2C3525F2313EE5CBA7F6DC77413CB58ED86F75D26B39729561C28B795073C1994F69256EB0BA9C934146C4421419475D005150897A17D310BC52F43D50E8CA5706A774D5079719754C6336D1142D2387BDC1732C03E2A3A04A9DDE91C46612B54CA6AB15921BC20AB4F2D21910629FF4E37516870D60AB8BAB08CE45DC89CA6712F17869E645B702141EF5D64F67F62156EA90EF1C502024858E91C89DE92056F3675C1A6EB2191E17300845CC3F7B52CF93C566FFA732C362A8E89C5B6F4A5A827B6259D26A31932E3141486ECC746027776A852FAAF0C3C436C690E3664FFACA01582022A99130BCC402BB7234A14DB7BAADDF7981D6557DFC44788C7506BE021359E1917837A3C3D5A598757E00F77B6B785436B6840A16151939774A10A7CB8089FDA55E6AE49F30512D691716F29C8A9FA94A8A113632A20C71138851EA6AB3F84E6E18B8531119E36CBBC6D0229A491F6B3B7E20866DDA8CCF802ABF47A769676550E2FC52CE438C48946EEB22756734BD4572C501DCC311B26FBC9C8ED2100A68E44435520848590375B59687C94A685B6490E236193C722B7B4ACB84CE9A69388D13A984F696B85122C3DC0A5C38C2992BA60A280C9C6783855093A9B886953194EEA273225C1A3E10B9DB18C548C05C392631DC47320F411A618C943B7A201C784885B62F7C56A6B698ABF1C76A039B3E6F95C466DBC31B4173778A9D5770B68B8A8195E886E8191E043B909723209553BB942A96EC4CBDA1382D02F71A6C009BDAC062C791C12F68A1F0506478D1869B782BC8B0181DE6AC62BC8DC844AAD6403A2B907F2D1A992BC44313F711FEE1BC70D326E7199FE411354DB2C4AB2526D09227BCB42CCE2650E341368FB493D6754715736F8151019DF22B07E5B5BCCB3D0D161FFBEB2E93731600C85B6CCC226C790ED5E7384E8C3555497C07EC074F2253713B1EF6927CE4C1A80DA11CB609C826718A5474230D62A40B0824675C95D0CB05B7C77B1DC4AA2872B8083BB79E201A0C847061E18BE1D2AB68B2BD55D24925DB5F4479BC12DCBC834B0254B891BF373CF5C4971BB0811182527C72C2EE6479217C70214106B416BDF0D818ACECB63FA6AF4D7031BB50312023ACF66986C71A25CD8A88D767844C312DD5198B965C3DF3E244FFD64610EB0CB3431F98889E72E864590191692B8857675AFD45B6CC31374888B40183720E1985D811098738B63A823BC7716F9CE94EC70738D7F5228199BB78B811EA912500C71E1CD93C955C0049519FFA8B523A7861B6B2A3DCE97D82449B00B8961877488B50542221BA79AAA0D33B3A47025ACBE47998952B08E27AC2FBCE08D6BDAC7B6990297504194BC0304871472CF3CB952D439646AA86C47986D160AFD7F401C70BB200E6182F91872812C551E17EA8438AE4236CDD743159802B034443E8D7BA0A249B312AC91981927440CB0BDC8E4615974BD2450161614068206BDAC3C2E69EEA0912F8A4CA1AF21AC4C033A6076E6D13039C97CA930599AA12B93D58C09D663DE14158B72BA0803A1B7917B71284802340422310BABF6572AEC23AE33A54A1F9C65DCB70821393B95178BA5ACBC0756DD8A02F8AFD156DC73958BAB2F2C0D24C2436F9F00B7267DA9F8B2678C14626EC", + "sk" : "9AA91962F6556D921B81C4946AAA26B62AC53197A49E1701EFF367D7AB00B27677CED51B9619541EC8A180DB9A7ED7342C31000063578851BBE9095816CC689B701A0CF7ACCCC64ABB1355807703A6A759A2D89EC01C9B8196573576C06395335BB39903187233A3C89811447E8346DC70AE390544145ABB14004E6E132A43E59364B249B3CBC13084C9A3487BAFD0BB66D9414F607E6CB33B35D990DDF40D87135C3ABC43A5B431B72AC9981B753A4B17EA48C3FFAB5917B387657BC537162631E76EF6EB68C670CAEABCC613B439A1F265D1229F8226C1A76447B535A81BB311B58B1236324C20762AFFE367155678AB01BAE2B3BBBE3519CCC6840CF305E432B5C92966F45809DDE31B7C30C2CCD77AAAA236ECDA9260C361E71C7292E10151D165BF6C9CC709A49182807543651A844FEE7703876921AF5537365C50F4CA07B2895725505DB00C6A3D240089F51C7DAB07DDE7A49217A90BB46462B4957AB22197844335B620E0226D1DF94FFB5983BBE8AA3197CEB6180EAD6561BCD7914841AF1B954DACB4C5FFA694A1A45064E2C3B0BAC1D265ABBCF2BA35B8B3B0F660D83680BE5C12DD2437A46A3367D6BD94D40FDAE51CE2AC800A0881B3B3A12995BAD39A2EE4CA5E07446943F19AA5DACC7B8C9042950AB5EA60A4E54DE2E8378589722BF711A1C92113471259B2070041287E51742AC79902E4CCEA25712943285FE5896427C8EEF2313277B91AE9CB55AC2EDC49B2D194A325F6836D29812660209802C457266CE3688DE79A40D5B6A4C2B606B56C0B2E13B262990CF23987E138742EDA24C0CB551AAB1024EB095E929BE557B17326B2DAAB78C981BD26A393A175385ACBABB1A87983C271175CADA26B2495705142E0C4FEE912D1E19D97F2CEEB1653B70C9003165D7D5A4A6E916BF0298DFFD94523762790F0108610C1BFF81A59EC4CC890A716A29F4AD24D75D53360C423D0C921E66B59D96347112C918FF680ED460C8D590DB11992CF86CAF3EA3BAEC9370456C6C354859C040FD1C126F736C92E50860694B29DEA4C1BF31061CA259E83035C01A27EC57ECA8ACA80C6C932261E1F44B6AF8A0C571A833A826D2C8B749832566230CAC47644EEDC9B288640E32B4DD75282764C152B87648F7BAEBA3A73C31C7E2984973E74A6A7236B3C364BDAF2A5FE64B4DA0B49437102A550CE04F220AD907E8853028A370D0B501D6FA849858339F63B8BEFF42FB5986135090BCE450455B561F5D2C1D0A846DAE4B2FEA86507AA38C2257ECA186CA21B87364643CCB668F7D880C164C398F9C46BF75A9A7C975E463BCC0B9B26C4291839C43136614F9C9133793FED561ADC63992BF968D4C373B8531E6AF04D58476B33585C1E9BA49539043E726340C4CCE9223519227CD66B5F3D05702B9600A2694D5B23C4042B603018CF25FCBE4CB86422420CEC820CEB589B42791C010CC4AA306FDB55452A49C66071C81AA3BAC6F014BE88602A6B4C49DB2A7A9A57E6C97BAE7BC483F5A54BE7970300BD2445758027311E4949CE43859426B23999A0568A55B2304A838546D3F4B6CF8303798837B229B3B1AA3B3EA60BF3A9AA5C8B79F5293556A45010B5A571DC246ED749711CB96F0CBB88A8C1C298C7837B2F2C3525F2313EE5CBA7F6DC77413CB58ED86F75D26B39729561C28B795073C1994F69256EB0BA9C934146C4421419475D005150897A17D310BC52F43D50E8CA5706A774D5079719754C6336D1142D2387BDC1732C03E2A3A04A9DDE91C46612B54CA6AB15921BC20AB4F2D21910629FF4E37516870D60AB8BAB08CE45DC89CA6712F17869E645B702141EF5D64F67F62156EA90EF1C502024858E91C89DE92056F3675C1A6EB2191E17300845CC3F7B52CF93C566FFA732C362A8E89C5B6F4A5A827B6259D26A31932E3141486ECC746027776A852FAAF0C3C436C690E3664FFACA01582022A99130BCC402BB7234A14DB7BAADDF7981D6557DFC44788C7506BE021359E1917837A3C3D5A598757E00F77B6B785436B6840A16151939774A10A7CB8089FDA55E6AE49F30512D691716F29C8A9FA94A8A113632A20C71138851EA6AB3F84E6E18B8531119E36CBBC6D0229A491F6B3B7E20866DDA8CCF802ABF47A769676550E2FC52CE438C48946EEB22756734BD4572C501DCC311B26FBC9C8ED2100A68E44435520848590375B59687C94A685B6490E236193C722B7B4ACB84CE9A69388D13A984F696B85122C3DC0A5C38C2992BA60A280C9C6783855093A9B886953194EEA273225C1A3E10B9DB18C548C05C392631DC47320F411A618C943B7A201C784885B62F7C56A6B698ABF1C76A039B3E6F95C466DBC31B4173778A9D5770B68B8A8195E886E8191E043B909723209553BB942A96EC4CBDA1382D02F71A6C009BDAC062C791C12F68A1F0506478D1869B782BC8B0181DE6AC62BC8DC844AAD6403A2B907F2D1A992BC44313F711FEE1BC70D326E7199FE411354DB2C4AB2526D09227BCB42CCE2650E341368FB493D6754715736F8151019DF22B07E5B5BCCB3D0D161FFBEB2E93731600C85B6CCC226C790ED5E7384E8C3555497C07EC074F2253713B1EF6927CE4C1A80DA11CB609C826718A5474230D62A40B0824675C95D0CB05B7C77B1DC4AA2872B8083BB79E201A0C847061E18BE1D2AB68B2BD55D24925DB5F4479BC12DCBC834B0254B891BF373CF5C4971BB0811182527C72C2EE6479217C70214106B416BDF0D818ACECB63FA6AF4D7031BB50312023ACF66986C71A25CD8A88D767844C312DD5198B965C3DF3E244FFD64610EB0CB3431F98889E72E864590191692B8857675AFD45B6CC31374888B40183720E1985D811098738B63A823BC7716F9CE94EC70738D7F5228199BB78B811EA912500C71E1CD93C955C0049519FFA8B523A7861B6B2A3DCE97D82449B00B8961877488B50542221BA79AAA0D33B3A47025ACBE47998952B08E27AC2FBCE08D6BDAC7B6990297504194BC0304871472CF3CB952D439646AA86C47986D160AFD7F401C70BB200E6182F91872812C551E17EA8438AE4236CDD743159802B034443E8D7BA0A249B312AC91981927440CB0BDC8E4615974BD2450161614068206BDAC3C2E69EEA0912F8A4CA1AF21AC4C033A6076E6D13039C97CA930599AA12B93D58C09D663DE14158B72BA0803A1B7917B71284802340422310BABF6572AEC23AE33A54A1F9C65DCB70821393B95178BA5ACBC0756DD8A02F8AFD156DC73958BAB2F2C0D24C2436F9F00B7267DA9F8B2678C14626EC811AEA11A24A4B09E428415F82EE836E930C3B77867AAFC5E6728149E3F2BD1BB68C0EF1663E52E24C33090EA8F4F564D85DACA610FD7C2D5756D7D882408DED", + "ek" : "EC226FB85243D7FDB2EF048473857615E30A387F9EAFA5DFDCB89DCA3D2DFB4D33CC89F82D59558A79F914B76512B54AA84F1AC29C75469555AFED3E6670E19711037E481472B0A9D2FC0342C733A7304B5F7BE858FAA862CF9C59C23657A45EF8C5F164F7FD233C6897229BE03EA8FF488896CDFC2E1A2DF2B7427A76B8DC43021B2ADD59101CCB4AA6E00775C2FDBFF75F21EE645D504BC93AEF4ABD59F2CB48B4B6BA32DB18C59A762217C461142E40F701DE7633D1414648036D588C2C3E37B82D796A5205D06901C5248121CBD3088B57AFE5C5BCFEB66F61554D88669D365A25F0AE4577D8ED8699169F4C2135F1900F3F6B0A0E8A77D950BA3127F71B106FD66E5B671546D98ABEFCDFF6D03AC4D90517228F4622A657B831C97075671D05960007F7F0C8EDFBC77E3CA9BF6A2F962BDA933404F40B41FFE9617D737A773FCB9CEDCD3BD174D5D2045940779439D13913B307EE9401E5871ED62E9FE62B59956A6245B4E5B3B99F57BD8ADBC46623C58FF063988A54993F2A207BE9A68356CF4ADFD96BF81BBBF4EA0754929E6B5C4220C8CBB3E36237ADFA68FC47F49D4E3B07D28714E1CA186307CB3030AA5466A2529E7F0BE48755D6C60FC2E33203FF597289E35C133709B3CB334D870F63F40784DD92063992920F048BA64E7795CA030E998B8F7859779AE7F62029692E39AAFB58229BA44F9ED299BB74F62584AC66DEA7039915AE6C15157389496F6A399C2652BDB2891A63C278E53CEB11234E4F7366488DC0393A559BCB735C823680FB853B77F3BA38A77BB0B0798A5D3ABDDDB146EC282EC40C9CBC9D87B1FA4F0E44F205EF7B2A258779557EEC0896B89F4D4AAFB471FF8ABE254325B9D55E5CFF2D32B3C1A02789BF9DD9C6BD5248C3E924937DB28CC15EA12E64B4990EBD2BA00A4A2D2853CA862691AD60925E6BD10998D6433C305B9B91646E1FE29E46DAA0B7A1CDA8E90DEA667C44BF6807764685B048FF8927A4978EBD299DE1FAC5673F511C020B67FDF42325C0F9D7255EC955E4EF16C1C7B91699C70625A360240D6716B28776423BD2EF3BF7DA39ABBB1A94260A2F7FD8623C9386EE6BC7FF3C434D9D44593FEE017C7D8A3DF59EAB1D96922F13A44D2574F6E9705B941CAB25C6031AAA407213E274B15DE90533AFEEFE1F450ACDE06B1E6EDB085DFBE1705C3D9DB0017AC77CCD56DB0248F5C55DBFEF1B43445835C1B2E71D8EB7483F75AEA1BC5B54B432DDFF16EB1F97F3149CA9452C703879D1A86654018CBB87443C54556EEC24333E144EA37619634A862279A6B534E44B05DD7C699E56471C6AB8131C3C27F84BBBB1814C5B5AAC76EC3B9524CC90CFF89BBD6B373F1E0AF39DF437F85D24FCE48C84A1EEB47F6053AC2E01EB1511853E0550B605D63E23E418003760EF59B628A72D4B68F16C0428C5F707C6AC55410ED41A15850B039DA9E9D63BD74D4C3E4DC8E27630992977F511F704DF40969DFBC4FE1ABC07BA2656C142CD67E88B9DB28880C850DD7484BBB9B027", + "k" : "CDB2ED847828F6C0273EDCC88AC4948B72B09A7A7E898B4E1FA411A2044F3FEA", +}, +{ + "rngSeed" : "AA93649193C2C5985ACF8F9E6AC50C36AE16A2526D7C684F7A3BB4ABCD7B6FF790E82BADCE89BC7380D66251F97AAAAA", + "pk" : "317771B7E77466880E15C76A39356CB459B78E6821E69B2F0F817B236A04A7CB834A743F830934043856E0DCC376730B3AFCA17AAB6AE2C59EBBD57F52D84CB107B6C5E536EDC31E57C3CD404A618700AA1DD87E43D92D4E601CA8D998C927451E9205429C643B251E8307553FC755DCC06D9003C35C310780B31ECDB05764E3C479913063978143FB9A462B011446394A287888A61F4F57B6C0548718FAACECFA6571381CE25C2D10C27386CC255086419275A3CA59BFCBEC4C63E5B487C41661520495E7B54B9641A1E16DDDBA5794A42D42E86B0007444CBA4DB161C6547C69A9CC18B2923B2A388710578043B77513173F6EB0190854BD6CD2612D1048E79435EB17680E99BB932C232B1AC298591D98A881696B3A46E117BC4A50565BA52E4704EB1C23C057894878434C61789EE8A594F94AC55748E2B111170C391B6B8403099928A2C60A42383CE5CEA5880701AA5B60E4C789C759C12703D946416ED316E48C62603920E2F640A347A2F305602F4138AA82B78CD08FA071BA1B9711A333A3D22244DAD09AAC8058592B1EDF9193291C8854B18003C6CFEA4A8728E7AB378905E3D04349FA5E4ED9BAA17B41B0A7189AB5CD0E352F174A51F3518BADFA7DF523BFCB64C43FAC3BC5B6532BF4CA91E245E1E61A815C865BC7CF3CF87891EB1234A49B624C0E1169C400CAC05359B6A15C9F3201B21F02C3FF0A4B94980757688AE0C48D0AC5C3FB650DDC38A8167C87C51CABD1698F8E3654380CBC8819599699615EF5495EFBA00A7A2C805C1D49552183B37BDB782F652682E02B7E26893FD97B8A7025AFFC7062E99557751A6A1DA7828D7A003D0C62C8D006FAC92589594FD729C17F38C5C83BACFE5BB8ADD8C1749A7550765F872C22E3E8BE9DB4C50A915FEC511C31900890192861366D9177612D731F1912CCEF5534248408C31605ED8960A612234CC23C94275A0B77302F0B82B4D121BAE15539C3111B9A21031314076199849302F4274FC54B284D95903CB543902AAA5CD39D034304EE86814C6119F7FBC17D35C68B151E9048434973AE06030CFF855291C71D58740EA00254ED926AB8835234490BAD7B51EAB118ACCB66F4A6A172C9A26717376E678771B44D9D452DC93988B9C9B5AF98907B17487BCA1397B8547AC8382F8A28A78A91B1B105F107200E839218A74D16000E90334FFC8709976B7FCDD4B742DC6BD2667BA6AC24DC510314F6B98DD711BD7A7169798874225627F2C7AAD1BF37E97A4771542E8C7898FA0D8BF4C0FD91BF598580DF6C0CE231A96368C8B8435F5507429006883FA88EE4E5791C2685F61C9247E72378478492EC90778C5FB8AA4A70E6CD48890BAFEB05798C13795C58B62B5BA8F7C522E78365089AE735A796825D9EA8C572A6544AEA86B2E08EA9748CF6B5717103A6D1C02F5D87A5E1AA94BEDA8691D454DE0B547E951AFE05061399804BFB32EB7B0857B8851810BA48E92518BA798DD54135A74419217A687620A0C665A050318E3672CD616F6D41618005CBA6EA47FAEC63DABA709ACC2489417FEA39B74CA2B13D4A60AB61BA89B2CDF0912757E08214B0671D8867CD2794FB30A8983B410F149BA2CA7134D00F83CCC8D1D4E2F1E83C9D8D4B95E33927F84741E362D80C3CE5833B7F2498D841F4C7E0", + "sk" : "7390B68A5071DE21628A6256426AADD676C604479578D418FF77B4280C2901A29085E9AD9CA81C7639BAE82274EE094FA38CAFAEF26FB27723C8C3C2B5276E28DCBD7131A5AFB0BB238249963216CD81118A881DCF9628332661E0EB07C55465403B81D31407CC5B20B2041F5455C3FE8061EDC7AE33E06982999E185106322564BBF9B03E309E1FA6BD61412F15091E9C523885B6134788A19D812A4CF4372FF35A24823A020C97CB59A9F5B698471483B04410107A2C2D8824D1BA5646A89E697738EBE6926C54874DD6A55BA2B89B64B1AEC95F918A65C9E92D8FCABD58E25FB7B07FD880AB48F6581B661D4EA3CFDA38875C9568A2162EC367BD78C2A7F7B3776511A8AE16981838BB3FC6006FAB2457F2964BFBC5ED5C67DA4987EC997D5EDA305B389CB9234B39E23CCB316FED518F35C757BF77B501B983130282F598039435A6B402B679B14F5C1C2C69E32B1AC9421C888B6D935911D4AAB56A4B39B3A2C6B8049F8584D74110FE63A1CBD633C63051953B9D12F36C5E3885DFFA5D45309DCF56BCEA5739A85441DDE06B9564A4D1E416459A809964C16D574A42ECCB18F51CCAE7B016ECCA4DF2365596CE27958D1227A72A4CA336C412BAA26AFB154809243B5A448A9FC38B39DC90D2177F142B1959FBC767146DC8D17A3857B84E987479759997EA85ADA8662035A939A30412A771B3893AB5184DC94106EF0790AB7617C57C8875D842010C08C142AC0F347709684302929D1D4371CFF2019ADC2C9A0A34B1F4A70DBBC3B18011348C7E725345A50197739A83A86C7AF54960C11C3B03093CC3A39A7E2C8FB7F84E1D452029692BC4A872946A23CFE834254845D46BCF040267A93602B74A6FA9580B134500EDB9BD2ACA5CF1959991C8716E28C2ECB026A398444B853408B371AE438D4459A3A6BB00FB63175005CF15125136C2B069B9560D213ACD3642C3B3C26620AF85850922D27FE8F8CFB7B79AFE08B9459A36281379C4169B73234C7649B8A0416EEE2449EF7A1ADCE07910673D2EC3BA18E74914110E2BB7A9343B74D5551A80DBCF61D52367F387259408BB7B87D466593CC9B872766CB7021E9C741C040B397D842A80C952C91070838833EFA83F36EC134BE6156DBBB63E720B07D2197A4B4719F8A7815B682813A55E369721B88AC78144B738177D7788C2970E8591AB378BB4F26998845A8238A51352D33ED9B5533797A7E3D801B63A3542B11642ECC9E3808DB74700CC622762A4132D8A4EE583CAC8898005760351D6B70F71B52DEA75C07A7D5970875E500AC13C14F1F2625D217EF13404A493526B115C6AF01540629E07795FA78195CE23809911475E9CA00CB3CAA0B5BFED575A6C33BB16351C60BB5BB050218F259811BC669CE68FE4FB1D6369CB7913013A16108D8204F0E09F351156713495E7A045175876F2836A4EF381B6A426AE55370FF4C8E740015687A8828C19426060581523BB184BAA9972D946AF2D2C34EAEA9869304B095106FD759B2040908D175F02CA0A87762AF4B57DAACB432AD5558A41AADD2C49222460515178740C8F552CBD99653FFB4953D3218F8EFA2FD6A1BF7AC7101CF320060C537E95381623872A2607A8447A317771B7E77466880E15C76A39356CB459B78E6821E69B2F0F817B236A04A7CB834A743F830934043856E0DCC376730B3AFCA17AAB6AE2C59EBBD57F52D84CB107B6C5E536EDC31E57C3CD404A618700AA1DD87E43D92D4E601CA8D998C927451E9205429C643B251E8307553FC755DCC06D9003C35C310780B31ECDB05764E3C479913063978143FB9A462B011446394A287888A61F4F57B6C0548718FAACECFA6571381CE25C2D10C27386CC255086419275A3CA59BFCBEC4C63E5B487C41661520495E7B54B9641A1E16DDDBA5794A42D42E86B0007444CBA4DB161C6547C69A9CC18B2923B2A388710578043B77513173F6EB0190854BD6CD2612D1048E79435EB17680E99BB932C232B1AC298591D98A881696B3A46E117BC4A50565BA52E4704EB1C23C057894878434C61789EE8A594F94AC55748E2B111170C391B6B8403099928A2C60A42383CE5CEA5880701AA5B60E4C789C759C12703D946416ED316E48C62603920E2F640A347A2F305602F4138AA82B78CD08FA071BA1B9711A333A3D22244DAD09AAC8058592B1EDF9193291C8854B18003C6CFEA4A8728E7AB378905E3D04349FA5E4ED9BAA17B41B0A7189AB5CD0E352F174A51F3518BADFA7DF523BFCB64C43FAC3BC5B6532BF4CA91E245E1E61A815C865BC7CF3CF87891EB1234A49B624C0E1169C400CAC05359B6A15C9F3201B21F02C3FF0A4B94980757688AE0C48D0AC5C3FB650DDC38A8167C87C51CABD1698F8E3654380CBC8819599699615EF5495EFBA00A7A2C805C1D49552183B37BDB782F652682E02B7E26893FD97B8A7025AFFC7062E99557751A6A1DA7828D7A003D0C62C8D006FAC92589594FD729C17F38C5C83BACFE5BB8ADD8C1749A7550765F872C22E3E8BE9DB4C50A915FEC511C31900890192861366D9177612D731F1912CCEF5534248408C31605ED8960A612234CC23C94275A0B77302F0B82B4D121BAE15539C3111B9A21031314076199849302F4274FC54B284D95903CB543902AAA5CD39D034304EE86814C6119F7FBC17D35C68B151E9048434973AE06030CFF855291C71D58740EA00254ED926AB8835234490BAD7B51EAB118ACCB66F4A6A172C9A26717376E678771B44D9D452DC93988B9C9B5AF98907B17487BCA1397B8547AC8382F8A28A78A91B1B105F107200E839218A74D16000E90334FFC8709976B7FCDD4B742DC6BD2667BA6AC24DC510314F6B98DD711BD7A7169798874225627F2C7AAD1BF37E97A4771542E8C7898FA0D8BF4C0FD91BF598580DF6C0CE231A96368C8B8435F5507429006883FA88EE4E5791C2685F61C9247E72378478492EC90778C5FB8AA4A70E6CD48890BAFEB05798C13795C58B62B5BA8F7C522E78365089AE735A796825D9EA8C572A6544AEA86B2E08EA9748CF6B5717103A6D1C02F5D87A5E1AA94BEDA8691D454DE0B547E951AFE05061399804BFB32EB7B0857B8851810BA48E92518BA798DD54135A74419217A687620A0C665A050318E3672CD616F6D41618005CBA6EA47FAEC63DABA709ACC2489417FEA39B74CA2B13D4A60AB61BA89B2CDF0912757E08214B0671D8867CD2794FB30A8983B410F149BA2CA7134D00F83CCC8D1D4E2F1E83C9D8D4B95E33927F84741E362D80C3CE5833B7F2498D841F4C7E076C64235D8BD63438F13DCD038F286B9F4242070A5BEC4D8990075008667AAD30DA1D147E7686E428AA1775BC2EB045D1ECBB17563AC966F708CF3882C47B5AD", + "ek" : "4BC2A658A3A12F2A50CDDDA741E297BB6492FDDFA051A1D56048390FF6E233BE5505C126F2D0C4C4F2C1596CC3A19FC29B788C7B2026578E969448EAC338767F2C4445C0ED4CC246A51B687236670B570057895A692041572B89BF38544C6728D10A84534D4D4FC8B9111B04391857A44B38922358AE366BE7263548E5E026632EA14AB473F7DEF61D4430908D3272AED38AFA868149A4B57DE951BD37427898C7BF93DE5F0E02617C4A2A4283680E617EF9CDCA25CE6ED0E3DEC34F63C79EB0D7CF2A850DFD6FEBC1658936F54E8F022DFE96340DBE07B424865CAFD4A04AECB1A7C7E97F4B1FBC4E6E2611EA5C31D4B5733AC4D1F21AFF37A20336651E329934C913F78587A92DEA9806DF08F33085E715B9A51017D9B8E15663A591082A46339EDDBA6664065557EBC23BB274F3924226C4B45A8423583E5684499E23EC5EE0DBE3F9ABBC6688E215657C422B9B9EE4F78D515FA04019FBE4AE3426749ED8F5BF0B2D26A302B414B3658BE1EB83709E1F6F9B09C9ADC337853F5A194D3AB94BD04B91D968F194828DACBEBA97272F2ADD5870A6E204115EC726E758E796CD9C5A03E6F9AAC77F3F334CB2EE19657E5D103CEEB2E09F33D7FA942CAE260D66D33206A4C86EE6248206ACB0EE326AFD509E34CC45F6C0035063903BF7F935D573E7FF482B0A29AD021AE825BAF753AA8E6BFA8B8BB018518A95B6F7E384B8FB7101C9BD3CCC71AE0E3FBC6D7D817CE218CC826B1835EDA8C62C03E2C7E652E96F0659239EED615167E253D3405E015BE7C0711DB2E4AB4191B4149A556F5D2232091A48A7DD4C47B2169D516E75DCE90298A7C9DE76AC929DAA9526732F710BFD072CDDE1FDBF29F224BE5F353AC99CEDA4F773994B5B28D9E04ED3E23811BFD503819B0154E8ACAE0CC9A0569C09D36CDA884150925809FD7BACCEC6BB19527DA4FB2AE9EB1D89B709E303A217E314EE10448A30F60AAFBD55B76B5FD868D56C795F6982479B91FF8BC2E0217E26F1BF2AEF68CFC6239D0A16C0CDC7B4F107FB3CDA7F4555A24B354757D48F28BB9FEA82814AD9F0569FCB460AE6A0EBC2361FF6C5FD25479439243D12BC8C884A34E5B5068FE38C8A6DE1206E321235E35B32BFF77C13677EED3C577172FDB4A5ABD3F8C1058E288D495ACD6DA11F20402C7C05A3385B33357CA779EB6975BCD42DA28946D72F942BCF2AEB665A2880CD0B82E0B7271BEE2A093C836E95987F37FC8F3D14E0A13317A4420BFA4A00BD43A66197B902BFCF839819D87926396096518E9568177E5C2E45D60F271C7EEA01047B17E5A1CA1462E3B9F57D4CFBC6831BBD00A07B618E1A5B4D05604F8B55CC289ACB9EF7CEDC8E6FF01F7780CF07E82D6E4E7BC906878C7B885F739B439FCF454B0890AE1F06C488CDBF8A5960C85196B1C2072D13878B1E264E22B8D99163F586CA6F6725587C310A7997BDC9E5C67ED10EC29351124E69A26CA66F61EB8EEDD5FCFEC2062177146EC3BEE711FE6E0DC0E90CDED4D63A96E2CEF254130FB824", + "k" : "CB144AA7AFE13183F7CBEB782776D1D678BB2C03D9544BCA6A96EFDC1AE5E03E", +}, +{ + "rngSeed" : "2E014DC7C2696B9F6D4AF555CBA4B931B34863FF60E2341D4FDFE472FEF2FE2C33E0813FC5CAFDE4E30277FE522A9049", + "pk" : "611425C6BB62E8F60764DB8466613486836FA07896314A6EA13A56E2F467483848C3451602E4C6CEB2CADF378D85654A63024C5E1AA3BA242136E5302881274C1316CB26004A549B19DB794FAC3F7C454FD8223F560636FA5ACB56F0611911954131AD94AC88272B6CF4C89FA0635A7A838C38C92E1D640955453EA44AB5A6A0868CB9C071E51705E24A1CB1C4C9D8C59082757FC5CF95B17FF0064C0C47B021B244DE30AEDA11251FB170EFB279154515B69CBA0400875C78C1844503D411521AD54C651A738BC32DA29CCFE992BBDD937827C6503735116AB5079DC04006FCA98A66ACB6519187FCA7CA935C090BB8D31B6062B34513F01E157976183A1873DB1C9E878A3EB37B650205EA5245FCB614887A8DEF4BB44B89CBD3C221E1A9B587A8C4A50633A9F386E6AA43E360649DA46AB688116E01AA75943CE061B362D74EA824870A94CDF84B38D809BEA8C994D2E10057B78EA6685FEE45548E6BB681A32F5346AD5467558FE6C345E6258175A84EDCB32B378AC3BB24E85739681234C0F1633C334DF7D853C9D00DBDE8A23D463289423536A44BFAB94F2C76C113FCB086E5C4CF40193220C40B509065CC3AE5C861212B898699CE1C224A04A77BF165B0BB057C30D9CCA16B4DC8128E7C197A4999372906CBF38386D66C27D1E36E8D504613C36D8F655D49750A72509F32F09580FA4518D9A34EB63BA76C063AF7CACF158607890380C034E2429E49125C3F543C77C3066C374A43D24A7EEA2608A12B845A4C42F7354699BB169BC720B175CE7C0D6E63843F543C0A84162E388FC21C313B3A5902430CAB0A61D3E3AEA195B13CEC41E38539F41C6E22D63F5D60825D7182ECB31DC8A0A82A952B765C0EB279B75D20BE877B8FB8FBC290F56EFCF5240779BD2C639A67476FAE730BE123236EA68E4AFA9D3200D0DB30B7A771BB97FC1667E94CFF70BD02F32D6B0B19548B61BFF4A43FA5CB73EA11483B23B1394AD5812C8875002BE49510656794033FB3150C7E13611126AFA639355DE9C04DE445EB5C7430287815771A937707E88B3C8F42587F30BAEF55AEB7A392C14A4DC858ABB9D537F8043C64100AEEE6A597315BCDB65528286E0FC7AD5A59A066725CC965C562ACB9D6330F28220BFB35B21CBB4321FBB556449C5E1108C46744E48C578937CC12C20DF49B79CE96AEA9B231892597B8A57683C495A9729BD7B969F34899116104ABB00EE4049CCBC7C37EA5868BA5C2F4A3934D6599CEEC340D6A488FC28D84BA371456CAF9C52DA9980904E253E54332505CB9322B1CE3C1904C739433D99FDB35461D4B3F949C8734904974C5CB7DD54531E86E7F9A69B8C78E137A77C0EB6B1FF468D0B2973819CA6A69B1E640AF8F3B35AF45183F5284425393472B3B7674503A86592947621DAC8352A64427D313D51716ED6CC78BD85412D97561C910F31923361485D138B80585CF2A59A04896B3BD8C7EC2923CCD290C962C343561226A076E7E13A0D51233B68062D0E02512AA96FD701ECB80B7F45B210311246BFB594C5059F25C1167094F966C7D88DA77BA3A71D186936F6007CB7CB4941C599103792EDC82E3708E4AA9706DA72CED51924D19BA561843C3A70F3F91B4FF04987CC4A914FC6AD33290975BC0B534D415EFBE43F7D4A4B917723A", + "sk" : "2D8BA8D5472D324746FD3A4A9F999726CC13871A6CE75130AEA07566332C05DC3B99C8626CD69917F025F6898A3112B7119C168BD86E27C6AF08B292AA37745F993146DAB93B159E9685CC09D750EBB58DDD2615236B298E8422DB54B971192D69857D3CB1C910C948544B6270A1C5854936DFA643710B631C245E8B00C42FE15552A293B6F20278D82588BB164EB3636465CB0BF931B77C087A475DC35414C896069321080DE41D58644F14143C5B75719184172EB2ADD8DCC059BB5DAC9A22060283B5C87CA05B068405A9E2E4C7CB88941D7162667733B95A76D2E3AB9803B547047C95EB86995B1ABFA050346788EF0C682405852BD9BD8F178E4ADAC309E8ACA30BA6AB1BC5F8CA8DCC96291A616D77D31A0504229E206704DB130E8B4480822833597D36DB65CFD130D4796A254C360DC2799D256EAE54B01A264AF8020C4422AA837A61DD2C983345BC158BC878987AC4F22E49B21D21D47F32625CA0386637668517531EE2F13A5D0665C8D41AD19B3FAA53793232974EC3193F2568C092595B009D40F3301F033F479192D016106BE49303A1616347853B107626E49CD14C46BE4660883B0B4D7725C0477887EB771E305EE2AA49BEB1C00D6C42B5C33FDFA225DB0640E973855D504FFA70B23C6C1869BA0DAB69AA2CB75A02D9ACD2F57F66C0983182A334E2796AFB96AB2293751ACE0F51219A994B2C5625F1EC7DE1891840D0C6F0B300AD5146B5B682D5A6406455A475A799C0CA7C2D89C8BB759FCCD178D278217D086DBCE5A5946A0D6811518DCCB37E898BE658321FE262DF3527FC5271E7B2B164099042900F2DD44491A72361BB0AEF38106CF5CE7DBA2316FCA7FF2843F4F00A7AD94726F04BCB552DC8B24D6A644444EBC10CBB5DAC08AFCEEBC9DBF7910E031C8BB5038BCCA34DD77FD8C7CEAACA6321715E639B5AE7573C0A0BA32668245A09AA278B86E2F2118C5BC6E9331063FAC6D43C63D21728BB691233337668E7400FB08C54F98894C45A3548B74A7B1490A4B6009A05A9919195C20D835746D092BC6D3C02D2613E51832049631D3DAC37D5951D50A2BBC5C35AC63A8D9C0318C2491ED5EC0FFCD0BAEA679150AB737003CCA56556063B2ABDF7286E887E92737F3651329235492C7221AAF0609C8B2F54A9C001F30D7314581BA821BA5B344463A88FC046D06A0EB422A524CCAC23F7BD722C487D955C81836F7B49329B81231D371C7D3994BC54874E85BBAF278899C544236B49C04C688AA6170DEA386D11B840634E75932B01716FB33459E63393F8DA1281136F217BBFE8C10A14FB675E1A5074C1551530139C57312B4C9B5F4CCA2219C4B35B63B1590EE6E3AD66D301B4609075737FF7A37ACA7193D489762E75ADA15CA43FA8BE146232E5029B3F2A7D94F551AB625B8F963C79BAB4123489317923EB54AD997B004AD53B3332B25CB27DD10A3576776EB1D77BFA10A9EDAAA42C385CD5C871A4CC37E29A3DA2E51683A78C09D63E64F6895930BB314080028473BC8C53AB6A2038DC1DC018C219108087C3B2BC2389E8609C0A8737F01C8DFEE13E2014A77F2722E0F60D71F162DDF0C521F434D51A49BEFB613FB28FE9001D35C250791B0C611425C6BB62E8F60764DB8466613486836FA07896314A6EA13A56E2F467483848C3451602E4C6CEB2CADF378D85654A63024C5E1AA3BA242136E5302881274C1316CB26004A549B19DB794FAC3F7C454FD8223F560636FA5ACB56F0611911954131AD94AC88272B6CF4C89FA0635A7A838C38C92E1D640955453EA44AB5A6A0868CB9C071E51705E24A1CB1C4C9D8C59082757FC5CF95B17FF0064C0C47B021B244DE30AEDA11251FB170EFB279154515B69CBA0400875C78C1844503D411521AD54C651A738BC32DA29CCFE992BBDD937827C6503735116AB5079DC04006FCA98A66ACB6519187FCA7CA935C090BB8D31B6062B34513F01E157976183A1873DB1C9E878A3EB37B650205EA5245FCB614887A8DEF4BB44B89CBD3C221E1A9B587A8C4A50633A9F386E6AA43E360649DA46AB688116E01AA75943CE061B362D74EA824870A94CDF84B38D809BEA8C994D2E10057B78EA6685FEE45548E6BB681A32F5346AD5467558FE6C345E6258175A84EDCB32B378AC3BB24E85739681234C0F1633C334DF7D853C9D00DBDE8A23D463289423536A44BFAB94F2C76C113FCB086E5C4CF40193220C40B509065CC3AE5C861212B898699CE1C224A04A77BF165B0BB057C30D9CCA16B4DC8128E7C197A4999372906CBF38386D66C27D1E36E8D504613C36D8F655D49750A72509F32F09580FA4518D9A34EB63BA76C063AF7CACF158607890380C034E2429E49125C3F543C77C3066C374A43D24A7EEA2608A12B845A4C42F7354699BB169BC720B175CE7C0D6E63843F543C0A84162E388FC21C313B3A5902430CAB0A61D3E3AEA195B13CEC41E38539F41C6E22D63F5D60825D7182ECB31DC8A0A82A952B765C0EB279B75D20BE877B8FB8FBC290F56EFCF5240779BD2C639A67476FAE730BE123236EA68E4AFA9D3200D0DB30B7A771BB97FC1667E94CFF70BD02F32D6B0B19548B61BFF4A43FA5CB73EA11483B23B1394AD5812C8875002BE49510656794033FB3150C7E13611126AFA639355DE9C04DE445EB5C7430287815771A937707E88B3C8F42587F30BAEF55AEB7A392C14A4DC858ABB9D537F8043C64100AEEE6A597315BCDB65528286E0FC7AD5A59A066725CC965C562ACB9D6330F28220BFB35B21CBB4321FBB556449C5E1108C46744E48C578937CC12C20DF49B79CE96AEA9B231892597B8A57683C495A9729BD7B969F34899116104ABB00EE4049CCBC7C37EA5868BA5C2F4A3934D6599CEEC340D6A488FC28D84BA371456CAF9C52DA9980904E253E54332505CB9322B1CE3C1904C739433D99FDB35461D4B3F949C8734904974C5CB7DD54531E86E7F9A69B8C78E137A77C0EB6B1FF468D0B2973819CA6A69B1E640AF8F3B35AF45183F5284425393472B3B7674503A86592947621DAC8352A64427D313D51716ED6CC78BD85412D97561C910F31923361485D138B80585CF2A59A04896B3BD8C7EC2923CCD290C962C343561226A076E7E13A0D51233B68062D0E02512AA96FD701ECB80B7F45B210311246BFB594C5059F25C1167094F966C7D88DA77BA3A71D186936F6007CB7CB4941C599103792EDC82E3708E4AA9706DA72CED51924D19BA561843C3A70F3F91B4FF04987CC4A914FC6AD33290975BC0B534D415EFBE43F7D4A4B917723AAE654E4412FD220548280B7A6ACE9F2F0BC7B059FC103060346E53BC3C3161D8729B5A50627688A4CB3E37CC0FEF22162DDBD848E5AA641731F8E60B4B79C93F", + "ek" : "691EA3D9D6C8A1539A2D4D1C59EE0BAF4ED0CDE1C75A6F42935CF34A1D2617E5E3308D22CE653977F9E0EB06F2061081985FB53C67058193D61D513AC28BD01E4992139F523D1D7D6718E8B5AD1724020F5EE696E420F2A0CF3E99E0E5E7BD48EA73E276229A34532B889202A0F221801C5E35C04F3D7DE4C0296F58C2E1AC4F58CEC1E63374462007D516650E5D00AD604921517A3C9E452EAD24CAC737F480B1C97DEE9BE8E7E9675F7535D5AD15B025B58265DCEABBA5BDAA77141EAA389A65F186B55492BF574A5D4CF12F5C9DDE805AACB9CE9FA9DA0C45ED7995192E4232419C203FA326FE6253FF12CC0092DA49E2E38F975F4C719723267738F30B56C2C822676B6523E68808AE7396F92682630FD6A55DFBB5E69297489CBCB254340C1CFAAB8369402CA05D40D2D5BF132D18E71C7B2A7AD1973EF1CFCBE3D495637612A6B262FE8A843023B575FFC7ED3F03273EABDBCCCF8022E3BEEEC5555FBB6EFE6E326241095121A95B93815DE96677448544C296FF21CFD9E8D7695CC79769F09DD7870C9ABF603D46D640258088781E4CB4C853FD3E8FE41D08F4871FEF56D33AF93E5B9CFF5ACF390F6C06BB422E113C997B5BBB279550A8F9FDCAD106169074B8FB2D9FFEF3ED755009509EBB719EFF7FF5F9440FE041BF4EDC563237A6C9EC4F4EA33BC8E6C3CF218A9698E2D2F46EB4301FC573DC0BFEC75E569D1F0A923A850C7765CE3A80BCB1DDBCCD2E2334BB9314CE88D4EA316B489B2E1EB5436CDE86CBBA72A57C32B53F22D2633C277CAE1FB17B3DB98E106592F29AA696D949718087BA2E7C38F9C86C27E342A8F49E1D1C070FE343C2147D76B274FED177B208A76D2DBC16653269052E9819EB88A4994EB3B69A9B09EA606A9246AE8AA92234FADE8FCA3ECCDEE3FF9780AD92C5E56309FA7E0D73D54828DD71313F1173FFBBBCAECA79073A7F64847C6C6C8B5E7E1770AF4B372039B12114F6B4D8047ABD2A4BB29E35399BCF910150264FA9265C185B97362B3AE370F3A4233F3544273105FAE8C27314C6800E17CF8A114B97E1A71B603E62ED2FA59EC7DD826C6B48671F6430EDA890EF45A49372103FFD06A3E69F315D0EE359F2A3B801496F48B78E507C7AEEA85CE9B242A427FB4B782524D8BC613CD6F41301ACCC5731F911684C7876A4B6C81BC5CBF4BA17014298125CCD956CBEDD8B1F6232499307720975E558D66F835505CE949671744F7BB4BEC7B16B81A14507674B341FE608FCCD915C4653B1C64BC75BCE8F8AA866EB2DD1BF874BC9A98B7E7230A6EC309DB65919A259663EE662B0F53DBB38862D1AD374B030C2C9C704BC8ABE364736FDF6EC7AEC72CFF1DBE4695054E54BC037EB58A776477536183CD334508771EB5832EBC2A7C4CD5F5ECBA7609BA7C3B92493DC7ED5C69E0A860BFFD70F62CE4F62391870083F7B38AA8F24285EF3106A784934EB6B935B1D3A82BA33EEB589B05F7CDACF25A2FD950B2E34EAF206BE9F3E64B18E2C42F9A018A00C2FC396E0534553B1", + "k" : "A556918101AF10D7FF4734664D5184C3602EA54028277287502D8732E649E942", +}, +{ + "rngSeed" : "AEFB28FDD34E0AB403A703B535296E3A545CA479C1D8148E2D501B3C8DD8B1034BD986F13F1A7B4671BE769359FD2AAB", + "pk" : "3790B3E85BB887D46EC144B4D8EC8BED82BDDDA538EEA77D818C7081B3BFCEC68D496035B71280B23985C6D9CB7580568286B405F937E99A8AC1FB28A927940C0A7CBD36290D130A1C23A42F3A437C6291DCE36E39E8CF2EA8B9613C1FE7571AC74BCAB99BC452B9C5829B586E5544E27432F06BA9C96869F5B1228A0A70FCF95212B0B2B84B45F29A49B6572483807543BAA6E4F8B7B40119A5D483FD20224932A3AF6869F00C8E9C6C5BF4C53DBE092D879BCD7843475A3110A559454A7375AC0418C37444A16A164ACC751F56B2AC97A1158C76BB9976D750CD23761265D16473429C3DA3B82EAC213876C20D639BF5951E94D939985ABD149B99C249445F4C9CD7421DDF21C536BC8FC2029E65D5C7DE083296D88BDCF04E38D26DAC500AD4457CECF8A795322F45997BCFEA18EBF807E84C659937CDE6D89FB490765EA9713B768CE05099E7386B4037B961A81EDD79ADD8FB9F8DDB71EE56C349B453D2A3BF22C56730BAC0CE19C4F961C008E03ED3928C7D068CB6512DBA564855289BDCBC2F2B179DC7631B9372872D05C4E373577861A67EAB16CBA898BEB2AB70C69447A156DF0B36EF9C451931B4B7212C8A850799563CAD55BC89FB3460F0C56AB434C5E9ABE9363F1992577698AF0058B54BB5B9A7B42E8D148D9DCCAB2D1A31D661018182CE207C036FF201A95B755E041F2E1623BEF565B01A27D870046018CF65C8324FDCA0DAD64883DA659826BF82721C3712700F435EA40C872B83935BF6CDCCB41FE29C81E2210477BABE0012CD635079D5932D42038C615A476FF35A523C7761D4560554C8AE0532E8D23A16912A804908411BAB5FB96B9802737DB82CA0D40C1A3B9913D81FC1330CEE7504E2A056A994C4DC70768BC216F66921D93B81973B46352796D37B4F9009312AA957A51692AE8A65D514AB5BF7B46E0964A8F827ADC51765384E8C35C900C4899FF30B1B53BE227A39FD8B3ACFEA46BED8832C38555252B38CC5CF750221E3490DDCB80D0D73422FF47623282D273645C316181A36BF787AC90EC326D758AE71E5863C66B914DB005655B1EBB057F8444E2689AD91A69150F71000AD7908897B4A3BA94C881C20271532A9653071CBD55669719B5C613ABF45B3335D734B718779D51CC5162A91E4F2622A94469E09A41E8A9DBB3667312BC8D5AB7839374F689B32AFA5A25DE333126A49555909CB27002B18333A6A0D255B905E417EB8460D8F7566B12C99D2900794F4C0B78451777A3789C834C785274B65881BF055DC1875C6392DBEA82811E49C34A3B2978468E10AB7FD91793B2856666A7C28473AFBB467E60BA603230C5EF681AF07C1779C6598A20E051254384467868C0B21AB7D89604153AA680611B767F19956A3B16229BC31FA3CA4315048B90F9F3252C23C02C92A6CFCA28C5AD6ADEB242C26023B8F76A914F888D39B59FDD1042502A68C0B416E6853E9CB5894253A129A1016108E44AA4257C2B547292642C3AB2C5ABF1B5967C8FCB377EB91FEF8C0D4DAA3F2E04A0F869FF4BCC458F4C118A4B59715C6F3DC25A304B2FC9877D1AAA3AF43A512A680F3E1BDAA90C816B95C339331F5FCCDC969363977A7B9695DD6B9BA34809BB613862A0561EC25CE0D2DC86F262DC0ED164C2AD357A709EDA919CDA2C4F880", + "sk" : "6DFC120E15395FFC3FEA71601C36939F3CCB68116ECB66A550A284C09BAFE6BC93EE929EFABC348B015AD58B34F589891D9A7E34630565751B15F42D93412F81F511AC6587CE0121D32A4760AC0B6C3779C6BB5B4C0A983B72397C544B15CC7AA38502D37132040889C575BB473B0FCA1BC1C50815496606BB99A7DDE8861FDA4799955B1D026535021A01840BC82CCBAC7B99F745747DCACBB0AB34036110CBA31B58C0BA3273349F2927FC0B32128B1B41C256067642ADEA66CD35482BEBC757D2005B8C5579C5844989551CBB7377D550B17CCFA6BAC2CE6012701988EA580435E0533BB5879CF5715EB75C69322B9015A4824B33F2647F0B23B4343940965027CA10A58A8A4BFE883C5FC90F62ECCB9EAA3DDDF68B0C1671BB249A52898FAF3397FE07D02AA723EFA27261A44D721ACC9C8B6556267F06E872E6888D03463C3F7133EECC26B01B96879C0B5438A1D218820C91782F6B19EC5BB96362C09D1C9329912C45618735424A05C64CDDC9C8B53C556F7B4302226440C6909339603DBB5A66A76E0A898C53C700270BB1C375C2C91C222B4C54B0C2848CE5208E18864CEC0CBD86507A1B87DF6929C80A6BB0E93D6EB085FDC1AD97A713E3BA1470C1C33DFBCD89A802ACB9C222052073230EA3179BB75CBF107525A938B49A552B8FDC21C262740A55724EF28BB4D63BDFE2AD28B3246B4452578646623BA78509A286C258E69480A835C2B9820CEDEC3767E12E1D7B324FA1A51558B31A914D9568BB22E72A1B55714488A699FA705A4AC58DAA09348022F0D65DF68B8841DC7FBA2506D7FB2E137B8E6A921788B5661657C677283D16C16961549368129397492B1A849005917F695B2305E529871B61811B6CD88A535692C48E058F9CB826BC53411248A15C39B2E7BA40000AA9D5134CF2471574AA201E12601662B7D393BE919979681ABF59136DBF44A1B66704D8A68B23EC2BC1F9525B986B8A640A2F754702CCB321205C9EE916F7342FA86C8F48D817F9F72208474D660B5F23186357F43681D93440AA562CA93D3353154A42A4790A8811439A84A19F8A087B8614C6825A4EEBE035B794CAA7FA1EA967B63928965AE044F9740BD4986FD3EB78F2D42C76132C89D960BF32197C432452B6B2E117B248E511B8FCB0FD850A57852E071B6567C37263D3B45BD439095BA0572584BB1990C0D287CC826F13468D87D91725586707F1C29C5A7FD4E67FAAF6558FBB8990463297D00A196407057316B331CC911911E7DA8A82CA1C77159C4D654B74FB89E5597CE0640CE97861F37B79B47291676103D6EC6822770BBB40CB7332B841E7243CB55A934C488555652189BAC26C508B438ED6799F2C108D4357096C63080AF57FFFD17731E41A217393C2198EEAD7ADC7099E1B0154A010816073882FBC2409A678F1DB0C6E5942298A5B2088A2ABD39B8CFA8B2A7C6057482268C29B88566C5E97042F8866F469B69AE16DB06C1657F91A66787E4A06597A6C0DD2300A914AC1CAD196D5564864C5A597DB2C62F4BCF64C4CAB3BB077D331337A6B0E39C03891A64A369B202C1B51330AE01798B3834EB87CC5BF234E7E14B5A419B68C114FB0989D2A67BBD0DA491D75113790B3E85BB887D46EC144B4D8EC8BED82BDDDA538EEA77D818C7081B3BFCEC68D496035B71280B23985C6D9CB7580568286B405F937E99A8AC1FB28A927940C0A7CBD36290D130A1C23A42F3A437C6291DCE36E39E8CF2EA8B9613C1FE7571AC74BCAB99BC452B9C5829B586E5544E27432F06BA9C96869F5B1228A0A70FCF95212B0B2B84B45F29A49B6572483807543BAA6E4F8B7B40119A5D483FD20224932A3AF6869F00C8E9C6C5BF4C53DBE092D879BCD7843475A3110A559454A7375AC0418C37444A16A164ACC751F56B2AC97A1158C76BB9976D750CD23761265D16473429C3DA3B82EAC213876C20D639BF5951E94D939985ABD149B99C249445F4C9CD7421DDF21C536BC8FC2029E65D5C7DE083296D88BDCF04E38D26DAC500AD4457CECF8A795322F45997BCFEA18EBF807E84C659937CDE6D89FB490765EA9713B768CE05099E7386B4037B961A81EDD79ADD8FB9F8DDB71EE56C349B453D2A3BF22C56730BAC0CE19C4F961C008E03ED3928C7D068CB6512DBA564855289BDCBC2F2B179DC7631B9372872D05C4E373577861A67EAB16CBA898BEB2AB70C69447A156DF0B36EF9C451931B4B7212C8A850799563CAD55BC89FB3460F0C56AB434C5E9ABE9363F1992577698AF0058B54BB5B9A7B42E8D148D9DCCAB2D1A31D661018182CE207C036FF201A95B755E041F2E1623BEF565B01A27D870046018CF65C8324FDCA0DAD64883DA659826BF82721C3712700F435EA40C872B83935BF6CDCCB41FE29C81E2210477BABE0012CD635079D5932D42038C615A476FF35A523C7761D4560554C8AE0532E8D23A16912A804908411BAB5FB96B9802737DB82CA0D40C1A3B9913D81FC1330CEE7504E2A056A994C4DC70768BC216F66921D93B81973B46352796D37B4F9009312AA957A51692AE8A65D514AB5BF7B46E0964A8F827ADC51765384E8C35C900C4899FF30B1B53BE227A39FD8B3ACFEA46BED8832C38555252B38CC5CF750221E3490DDCB80D0D73422FF47623282D273645C316181A36BF787AC90EC326D758AE71E5863C66B914DB005655B1EBB057F8444E2689AD91A69150F71000AD7908897B4A3BA94C881C20271532A9653071CBD55669719B5C613ABF45B3335D734B718779D51CC5162A91E4F2622A94469E09A41E8A9DBB3667312BC8D5AB7839374F689B32AFA5A25DE333126A49555909CB27002B18333A6A0D255B905E417EB8460D8F7566B12C99D2900794F4C0B78451777A3789C834C785274B65881BF055DC1875C6392DBEA82811E49C34A3B2978468E10AB7FD91793B2856666A7C28473AFBB467E60BA603230C5EF681AF07C1779C6598A20E051254384467868C0B21AB7D89604153AA680611B767F19956A3B16229BC31FA3CA4315048B90F9F3252C23C02C92A6CFCA28C5AD6ADEB242C26023B8F76A914F888D39B59FDD1042502A68C0B416E6853E9CB5894253A129A1016108E44AA4257C2B547292642C3AB2C5ABF1B5967C8FCB377EB91FEF8C0D4DAA3F2E04A0F869FF4BCC458F4C118A4B59715C6F3DC25A304B2FC9877D1AAA3AF43A512A680F3E1BDAA90C816B95C339331F5FCCDC969363977A7B9695DD6B9BA34809BB613862A0561EC25CE0D2DC86F262DC0ED164C2AD357A709EDA919CDA2C4F8806ECEA55C3D5C042D2DCA3A3925FAAA9112561827DCEB0754580814A84BE19B870472C3D61E4CAE91B22D2F5A316794C723FBCF7546DB47A42A15F1450CA3282D", + "ek" : "EAC38BFAE77380CDE32FAA8FCE7B91E1A3ED6E241F55CC7D365933E9DA5F19FB4017C125DDDFA91D5307C14BEB33B27A2AB9404EC043BD632FA2039440BEC428E1D8DFC2DF1494D3BF0F64E67A432F8ACF89CBA6133235742933A88C168F2A636715B704009E70A87388FFB2BE5B54D0CD71505946FCA984B1CFEBAE98C4C7CE66365BB4801C6C3791698D6E69A1BCF85836FE70D8ABFC4861A02CF8912A5872FF3C15F0CBECF4A8081B6CF067C68047A64AB164F9FB832E840791A4194B538FDBADD5B8E554CE278A13546149C15FD77804E3442B3F29AA411363B57521D1A1EB9194325C18CE3A4FA50628E6AA35686539542480570AE2008F1F1B06E85856CE8BC71156D6B64C9F230AD408CFE4617FB9ABC146D28DC8F9E4C820F5FBB4049A8F62C7E7CCE079379C111A8CEC54EC6B5C22A337413B6BEB631F058AA8A275E1EA1E33539FBC4BEB88E9730264C53F07AEFED14951880CE625731248D3A21E33C27F89FB8E8037740C1CB9469770733E94F36685A06F847AC356B76A2FEED0CE11A0F563AB9A4C25F3FF442C7A98472BDA95C90EEF92CB6A977B4D47B092DB4F49913D7388EADC1FFD3CC5C5922C649C941062A497E189C675892600A5300156AD62BEBE8EF04ACE299DACF6C67D93867B6913F54ADD880047AFFC671CEE86216DAC411E5736B8FB270F23302389E0E9C5281037C17A7851645B46A979817F3B481B5032BEDE4DC8D7B014DF029FBDA35391CDE1478059CF6508E4BB859B36A773E8A104851F318A414EE18DDF4B287BCD371DDAC86D3BF3CAA6339322CEA216167ED25E24442200EBCA879CEF98AD8BB44FE0A7E37043EE3B2E1B491A102ECEE28A6F809C15283CB08687F054B78B648A8B4F9053C2E7E517850A15637A691E98D50ACB52225BC8E19C24254C5BD781931DD93B69DD025A2B87676D0185FDD0CBF3F1810BDEAF3ED7E87AE41A49CB810E733635E71FF9F042E43A798D3D9618CF15063775A7A643213AC3079B5E25F329EA09578821245D42DE5B68B9E5D85DF94034D35F5BC26777E20CCAB18F9587B38BC89BD09EDE5BFF9BFA99EB290B8E32A2253E3FBBE41A6F9163F28A1A7AA3474C889E51B66D4A2B321BAFBE81B3FEB3CD6421EF316998C6F2F9A830A4AC042F93C2B0580A35AA5018200E6844AC4CD4A0056755AB1688C4825C5E6445035825C2A10DC9AC60BE4060017ECF05BEFE6BCA172690252C29938644EC5453BE8F2816EEB79854C74E4AF7485F0AACA8761ED3B0DAFF342DD0A6124319CDF00564C3D97A86D57B979027AFA3CF3811F1F5D86F8EAE7C6A0E59C1A06945934B6AAFB4D9B4BE1E7BCA484F16322F730C60135B11160B384FD3B3A74A25887943ABBF269EE12AA4B16450E41B07C2196EDA7E9C0FD3112D2F6464DFA0A07F9BFB60D14084087B7DBFC139EFC561BBD0F1E70D487E67D99835082B97997F0F05296B8FD47D14453291B60E0D91044265628B2DE0D66D6C9FB2AD1DDACABBCA85213CADFAC4D642B2FE2A369624E0DD719A13", + "k" : "A29FB4FB2E87F4B38B2894050474C1BBB174C0BF51716495274BAC0D07BA7B73", +}, +{ + "rngSeed" : "CBE5161E8DE02DDA7DE204AEB0FBB4CA81344BA8C30FE357A4664E5D2988A03B64184D7DC69F8D367550E5FEA0876D41", + "pk" : "35775144C098E6756148A30E8CE75A67137AD2455860252B764C15823C08358C45AC820BBDC3525543A66A22854BCB8DD8E1C920A10F67E9C8D8495865B3BF16C39AB0A86CC231A521F42316F7BBE4D019616C167E88A40B4532B1EA688222A48150C6E24859EDD0210EA54E4E80654B86ABAAEB52A022742FCCBB336921D5807D0769BB5674141FB791C6025EAD44C79CF8C1FE80987086CDA07546811471CEBC7EB7E8A5C554A6CC0062BC6C0B10900A8EE95239F844D26527423C30F4A1BE90E29424263663406DEBAB5025E11F00E09C24058F8077CC2313842A5AC74BBA5E26CB78C4F8557CD38DC67286D9D25B18F005FBFA852C5AC738F33C24E07B26D635A09A3E3D12C9EAF432A06C4CC88B15EE7C4258B279631A9756E5086145CC2ADCA624410D58DB0DEF549D2C13CAA2D80ED4A088531221E9881F16E39659C3425B31B4E5C0462DF53375870C2360B984A881ADE524777489B8A184304372464AC7099B6AFA24A9545B3AD02AC8B9C968D0B4B6E991CC0A83550DC70DFBBA36DE192BDB2A2239672F011BC2924622CA6C2C7C4C334EA05DB489CA290390E5A18BF18B564A037157006FB9131B35983A9BD285D66482863C0CC4270A32B13E1299328ACC2DC4E1812F1522A88177E813A0E6B52F11573873FC512BD004EB31CBE1446A3B3518AE2253ED3204C3E3C36439AB128C322A0160A5B40A27F3AE6121333400B050D60E9FCABCBC82CA7FB1B1399715A23417691542441923750ABEC3607B47B380835191D6F790A7D08F00AB209A6BA608CC9CBDFC6C8F4CC194BB22C630AE48899A058BAE66F3B0CB12A0D2E3209D995010644FAE989EB94CAE8128585933AD0F7282940606785C07E882031C08A20F4A194BE008AAE8AE5CE77C17505BB0854579712F7F5231D1C32301053E9AE2A1866B634949BCB4C6952FB78376FC91BBDAC8FDF096D1D987DB5C71E39371F894ADFF2A099CAB93D5353BA013AEF5C58796F906E7A434590181A793CA012A6610C912DACA06903B719E384C827AC62E2B2590F82F29D00BFEB50D66815FE13085395663F722399C187CC2784198B028E585B305E6126F6A003B05ABA2C0A87EEC6B186623DBB37DAD789F7E8BA7CE01A792366117C308601664D6B7CE64A03A03090F55C5B59E66545BC0C9A29A29D2EB89EEEA017026C2A4B88CCD12C96816AF697C5B5F1896D340A60729984857072234C71AA5C8FED44F05DC7DEFA39CF409B063E68BB28B3789344BCE267DB328542A5530222203D6D8858E51CAEB8C913163A97C0759A1D1C3562288DCD48D164004B08A1C9EB76F956BA5A562A84182CAA6417E237BBE4E09A5BACCA54A32C76773C84C14401A348108B2CD83377F6470019AF3591B7C65BB33833517CE53F7701C4B1B2DB8665CF5259B6052E73B41EE2641E9C998DF327F750C44DEC00AD7BC0EE69992DA9455C2B26E4C7605DDDBB3ED942542FA5C255B4F9D037A4264939C3A26F8A817D9C21AA958677193C13A3B1B76619A66B2A0B351601A1750FF9B78CD4506E1C19F04671FCE65C5C34A6E8141628DD696B3D5B962497ED3433BCD707537AC4715A7192687826FAC2FC0A60FCDE02F78E69DD3B996B937332AD2161DB433EF850B4C8A5BC8A48556A927CE345679D1595B8A12A0E85DC5DA", + "sk" : "5EDB8568E989D33924746212F1B7131E5A247C6B73D58A8FB30C75B7161461F7B7F5BA4B38B924484964E7666DBF6177AA2662B193704FB19E60376614BC92E811905A293CBA30A81B4401FD067F4185C3A0E72B5CB260AEA81924B85105A7403BD6C6EE09627C13AB53DBAD06999D276004E290B41720A70202C5F1F4585A68C56CEBA1D7B21E079552FC591C6C3BC8F49C089527288CE6BE22ECC28EA6BEE8DB35A8024A03F77E5D7C8C79A825ECC4C002566335E9355C0A91E5EC451CD81C14F355BA3B82E0A29365723FF30CCA66A845E849A96093CEA945C7D242461A94B5C9595555932CE43107E000C251F13FDBD699DFE6B5D2A3AA3B7662F988C39BF4573C59B38046317C65CA2CD9304448AFC62190BB32BEE74220B32B85953A5036065D230C2D28C80F0A164EEE4B72B599BE3A3961A8A70491D4AB680A46615450EEA25A2FDB2C7352B7CE36AB05DCC5A933404925854EA5330563B41D477A775679C1F8B3E69690913216E9C479434AB55AF2996F6B431D01A9F4D7904C80C666D1CAB7E90DA6F125E14320D46861BCC11D50D9B21B0196902A7E26B720DF911EA80716CC478CCE204DD796398D108D04EB31EE3027B8F0197BB89079E87D2ABC641D7030923052046504788BCEDD194C5807CCA3202BFD25BAE48493FF273CCCC55446B2BDE23547C45A36BF295B32E18122A008BAC4A83EA05260930061D6C1205498549567AD11CE95F105B6E18FA282BF33C5102E0C18F2F44837980D85B26273C450C5885233F101CB8CA85039AFD9E5C9CAD0239EC63EAB8063A3A76D7069B5767603D7F0921729910DD29C814A08FC67587DE5020057ADD33C04BDC40C82015AF9C7A41CE541A4C11832459679CBBD0626A670246104A33CB4D4769069253FC2379835BE32E61CE6F12593D453071CBD7DF3441D30B8540C4A515279DEF5C44A8C397BB018E4E377BD84B1C09917DF0058BB8916CAA26A9417B314A79C536576D97A5D0091787C24154A1AA9F2F39A70577E9D61803BE48E2BEA7C245CAB5073CEC1B1403775922260005F43706950A261B99E22302B1E63BB45438D9DA39C2EE780E9DB6E0B6495D0FB966C9352873A342A914EF189854832AB4DD42128527E9251565CCB21F6646654E6B78AA3466A0AC82337B90ED86DCE3B0B62BB376827A5A1B467C63114E597BC7DA7016561BE00970200F710EF523CA3988068BBBB9A1A8FC5A94D37B930AE0758BB3C1FE98C96F5A90C94AA649A4647135B9169E6B81F18A192B19015A50BD39159F1E8CCAA881E34F53AE469A51756C220BC827546B0B9632D2110B86C43CD1B04C35BC183D68C1837B3B08E0C2AD5920AB4093142738A5545A5FA97951D735AEC4A3E090175ABD999BB1B1CA1C7499E7C5D46242FD605CE6E18047AE23231C605B6A81B320261CFA0884BB87BCA9902BA3B71FBD98C0A97A53989637CD2078EA5CFAB93B33B1396028270974B50C4D6C8F4C8A0A610CA689C981926C9013CCB06AC855F229D5A832C3BFC8F78B1CCEE078B4E893783934115923F26D747312450AED0731D99375EF6B8291B39EC146D0A2218C9084F1575B11FB4894D372BBCA066A621A334086FB392AFFDF4384CF64735775144C098E6756148A30E8CE75A67137AD2455860252B764C15823C08358C45AC820BBDC3525543A66A22854BCB8DD8E1C920A10F67E9C8D8495865B3BF16C39AB0A86CC231A521F42316F7BBE4D019616C167E88A40B4532B1EA688222A48150C6E24859EDD0210EA54E4E80654B86ABAAEB52A022742FCCBB336921D5807D0769BB5674141FB791C6025EAD44C79CF8C1FE80987086CDA07546811471CEBC7EB7E8A5C554A6CC0062BC6C0B10900A8EE95239F844D26527423C30F4A1BE90E29424263663406DEBAB5025E11F00E09C24058F8077CC2313842A5AC74BBA5E26CB78C4F8557CD38DC67286D9D25B18F005FBFA852C5AC738F33C24E07B26D635A09A3E3D12C9EAF432A06C4CC88B15EE7C4258B279631A9756E5086145CC2ADCA624410D58DB0DEF549D2C13CAA2D80ED4A088531221E9881F16E39659C3425B31B4E5C0462DF53375870C2360B984A881ADE524777489B8A184304372464AC7099B6AFA24A9545B3AD02AC8B9C968D0B4B6E991CC0A83550DC70DFBBA36DE192BDB2A2239672F011BC2924622CA6C2C7C4C334EA05DB489CA290390E5A18BF18B564A037157006FB9131B35983A9BD285D66482863C0CC4270A32B13E1299328ACC2DC4E1812F1522A88177E813A0E6B52F11573873FC512BD004EB31CBE1446A3B3518AE2253ED3204C3E3C36439AB128C322A0160A5B40A27F3AE6121333400B050D60E9FCABCBC82CA7FB1B1399715A23417691542441923750ABEC3607B47B380835191D6F790A7D08F00AB209A6BA608CC9CBDFC6C8F4CC194BB22C630AE48899A058BAE66F3B0CB12A0D2E3209D995010644FAE989EB94CAE8128585933AD0F7282940606785C07E882031C08A20F4A194BE008AAE8AE5CE77C17505BB0854579712F7F5231D1C32301053E9AE2A1866B634949BCB4C6952FB78376FC91BBDAC8FDF096D1D987DB5C71E39371F894ADFF2A099CAB93D5353BA013AEF5C58796F906E7A434590181A793CA012A6610C912DACA06903B719E384C827AC62E2B2590F82F29D00BFEB50D66815FE13085395663F722399C187CC2784198B028E585B305E6126F6A003B05ABA2C0A87EEC6B186623DBB37DAD789F7E8BA7CE01A792366117C308601664D6B7CE64A03A03090F55C5B59E66545BC0C9A29A29D2EB89EEEA017026C2A4B88CCD12C96816AF697C5B5F1896D340A60729984857072234C71AA5C8FED44F05DC7DEFA39CF409B063E68BB28B3789344BCE267DB328542A5530222203D6D8858E51CAEB8C913163A97C0759A1D1C3562288DCD48D164004B08A1C9EB76F956BA5A562A84182CAA6417E237BBE4E09A5BACCA54A32C76773C84C14401A348108B2CD83377F6470019AF3591B7C65BB33833517CE53F7701C4B1B2DB8665CF5259B6052E73B41EE2641E9C998DF327F750C44DEC00AD7BC0EE69992DA9455C2B26E4C7605DDDBB3ED942542FA5C255B4F9D037A4264939C3A26F8A817D9C21AA958677193C13A3B1B76619A66B2A0B351601A1750FF9B78CD4506E1C19F04671FCE65C5C34A6E8141628DD696B3D5B962497ED3433BCD707537AC4715A7192687826FAC2FC0A60FCDE02F78E69DD3B996B937332AD2161DB433EF850B4C8A5BC8A48556A927CE345679D1595B8A12A0E85DC5DA576CB9D31E5146967756CF7356926F2E20FC7C1FDE9954CB2F593D96A80AB86081B292427D57FEEB160F9347348632E1CD340960F6E6EA2422D194A0109AF1DF", + "ek" : "CE63119902E4B8BB7F2E44B1EC350AA603E16BC7AD8A26F1AAC5427F926AC785918BE2754D0E70E604BB130D7F537FF25D43D8C0192F12243492C5B361523329D69AC6B7702A667539C2C6A7109DBB6E83F24B16181974639865B4746601E7F1F44F6182DDD7ADDF08C7390F9BD37AA745724736ADDE1BAC0A35600FD40DB05191728EF9182CF0C49ACD7D19A8912B669A3E287AC5095D315F751E0F1A8A74CA23FF9C1DD4BBC0C68264CDB6ED3B8840CC504F01FCE8B31229D377010534E26B01559104E7E16DD3147C2E32A2DE3F75482903A64722AFA2C35272AAE98F5CB178AB9F9D49459C2980E919A38473E17300DE549D73D3E5E4DC2C3E14C9EFDE0687DDD887945E1EA8D8D3BA455DF4DEC1359C1C46029079E7BDB0C83860666EBB48BF3527D3379B9D7C8C729AC26164ABBABD467E85160A91AC6B5F2DCD4ACE16A96996A3C6EDBBC99B3E5D40A6FCB78021E18316ADC4BD9457A71C45A0236C40108FE8E44980BB23A2170CBAE835028C3459C271E251B62496D0913D2B18C75EB3B3CAF943A29E0192CB3EAD70A0B0F718BAE51A4DCF549B68EBA0277B90AE5F5D286BE06B9D33EF49103C41B99E2CF4B221AAB73B8E953F698534F80FBFA7D1773E6C0E33B256EF06D63DA03E6450E88231EADC68113F22BFD24E7E9880C35C18B1489A389CFB704421765285863D0F2DE22FCFB137D52D75E27F75D7C12E419DF2FCA08EE8396316CD7B78B669443FBE95B2566BFD1F5E964FB35D8D3434FE8AF75129E997556F027610C3604CD59C056369BAF3B61FDD770C33E5BAE268F610AB643127CA85EB3633CA6C415E83CF343F97D1FA96FE9D7C608DE47793AFDB57FA25CEFE4DF26116B30AF8639DF69786B33872F3A03D104BE0A6BC6D376003DAD486246112010EBD55B3F0B34530D3E1586738ED5751A911AEB0F1F9070FF47B6218DAB2A0D539704BA055EDC3F3D70AF4483C06B4569487009EDD45F996177ACEDF80B9697DF8189F889F2B948DB5AB68B2305EA545B595794B9A7B84D62F54E324D15DAFAEDAD583AD6B90807BA230312CC7DE7E1A5F5A96548DD8D82E2B6C04845260F4A69738583A4C06CC2944DE4526199DD68ED54782DCDB47DB7A8BFAEA8C0988C4C82E5660E9F84D2A3C1E6F2ADE8D97BFFE4A12CDDE80FF8C4815621A833B3268C4959C71D88681B4129C1C97D59C0D4B24996572BE5D78E394378B5CC006A6C6A0F28E48111A3BD449FA42325C6F4949392C03614933A6CB00643C2CA2C603B18A6651E41F0A5A80DE382BDFD091505A90E69DC0EEDB42B4FEE52DEF862A5617697FF3082631E685A4EEDF6B1740F1B7962BEBCAC3573E40DA93840E4E73C1D1F1069B29EBDEE310C7B45FB882F0E90CCFC708A7A6D07773D7504ACEC05FB916A7D67CDAA7794D6CBCC429A7B4504A7B14A9B4EEF800903F967ABFB8FA965746C9038BC6985F055E81F574A6586FACDC6A4FDBE2B9D39B00BABC7EACBD4A0713D009F38A63A7E1BDDB6B7E34AC20961459E1ED30E22D6E2B9B60", + "k" : "B2885E444EAD28880FBA51E92565201A92D98027A347F3A5DD06E947136F6CAB", +}, +{ + "rngSeed" : "B4663A7A9883386A2AE4CBD93787E247BF26087E3826D1B8DBEB679E49C0BB286E114F0E9F42F61F63DEC42B4F974846", + "pk" : "023753735C1BBA67BBFD117911D0BE47B827ED9773E4D50D8D11A5B6481357473AE2A766156B9A4E74169A1B3CD0BCB90EEBC31F587D886ACCF3027C8F6620AEE70741C403E4A72D4BBA51AF5B1362180158FA5867D25168871D599B04819635BBF096C4980CC336267AC6B956BC861E0A9864766A18D4B8B9EA61A0573FE60A5CE58A87CFA2974CF17D4F599673137DBC662EEE9706AD9A85D780A911C209644980CEA134545375C031B8E1082B4C201EA83877DCD7158435AE34D52376816719070D76C0683E0C4422750A1959932E88562EBC932BB7AE688C09CB703C6E567E6D898B6E135F483290DA271D7EF16B15D12D4E0872CCB05130F52CDEF878EA83768AD44885E5A2DD6B2A94493CA519C14EFA09E9CC0739354CCCB3850CB0C4B504C2EABB1128F55BCCDC17C534B5E68B94526AA46888AE970372ECD49A7F03171872633E78997B51CA867852E638215BE32EB2FB832C42038624035DE54D7F4938AB78210C47BBBC931C336917C9D2A0D58454DED14FC7FCC6F5A97A6C3A5649689286F0CED68963CF24A05E9851FE1277FED36812E5984290701D5BBF138AB76F32B6043853415790A540878C3BB297B6BC7B000036007D8DCC7D32E6B7544C3225C2CA861052DD65C8F1D103103959ED0753E81258EC3770360AA924357315C18B33AA12CA06B24F1C59AAD1B4EBC58F3F75B77C1B07BCB9A23FB0019DE06109050B0CE30E8D6809C8A0CA70EB56E366033841AC39A6A198C5C105C85899E6403781C72AB30BF1D5917035B9FE50B081B6CC6103B72D423237189C583C702F7768FE43C182075A48828D041178E6A616340178ABA89BE3418C4E968F14B9396574B370F1C7D2858A1FD78B5351213B7C0A7E05382D0217457BA27A344546E197B22256B3F031C9E6B65FF377BE25B6953A4DBC9A6E9AEB3B08C01358E2BCACEC80033990F282B0BDA655951A2B0AB83EF4459AC56A76AF2B2D2669C0239496610A4274C9B3E5E998AC948B3E7427C8B380C1077480789B008054373A7FC65080F3772D1F6626E345BB417C9FBD97ADD68640DC12028258970CBA5DEAAAA32C7B022B0183C89B3E1BE25606B3109EF88C9F07180C110703153A247981B5B465318ABCD0A78AD1BCAA15B07EDB66BD77A14B23E84AFA6500BDF15B588009F05925A2FB430B0629BB4C2057F8A231760D9255746781C83CE932AFE10B8602A80FC1A98C694E80333790B59E67722A7BCC2FCD9B61A56A5A8EA6B85B5861B44B521CB0B6ADFA9C84F624AD499C0664AA97270D1A0209897569A64650C0A9B2CAC1879E671D9F0413BE9621B415641ED645FAD52E2CE49F5A3BBE49655649A62BAEB5634E50807F737DCEF63A7FE0C5D2F573B9BC5914B97F28691F49045EC87767EEF405C3B3C8C6089E03268A5F0C530F1682C4C022E3804ADE91C20A0793265A45BE711A607465709A24DEE763AC192D0D57626561C3A6092F7777C8DBA75516C39FB49C2353157AAFF0787BE318CE2C7385101E4D23C043742B9C5BA0D96419E192C20BD426DE458585E11AA4D5C8315BBFBA129A446C80B726060BE07458991E973A394F163E54383D14D420AE0B4746A4B891D092DB39B8E1C708768046CB0E3CA324D417302E861358385229492A291DA3D601A3F41D29A75BECB44D66", + "sk" : "1E981C27E35D12192FF6BA764B9715BBB53B6AFC9C3DB6524BF480BB240D905622D8015AFA41B9CC78A3F039269C9579D1BAC3F6041827E883B3A073F22758A8112A36B91E2E1330D5EA0D5F91A09B7A2463A1A2025425B28BA10D85033B9A8FC3CA7AE949A8B5EA5C6F5B706ED22E949A1D5BE2A573306B8E0C226634AE3B500A24B08C771456179BB24AD2C3024C5414FBCEA4455CD781BF0FB5439F67285644309A8B6454D76463E69F27870E9089463D9ABE0F450D72572FBDD678D6FAC98C7989F0990D897913D0D1CDC6A378CEFB0E202C4389626DBAB6646B00BE17377FC027C27F9694EF320B48CA51BA744D7C7C29555AC0C1C8CC134572893BBFBE45671225273DB5B54659A67E41B2DCC744AB120917D3C952D9C847B038B53C36A369631493681B43512968069E2C7C140550BAE5AAF35B64B9F9B8FD6C75E8063108E7237CC320AD32A8BF9A74987098E3E828F99BC54A5504CFBBCBD36CCAB973CE8E4690CA8A37805657AF89C6811B8C0045CA3FF373720CA1087259DA8A27DE2855F32C16E7D7AAA32C761D2241AAB42DB19353DE53A2BD125CDAE17468356D63256E22F6B2EEB95BC3B343DDB33164E297C32572C41459E5890777D8623E3A7DF541945128004CE4AB73E25763E1236D1A99E5408A6BC59FFC308F2C810B4C18AC29D72581F46573843F75F57986979E77B28355E7BAB59A9F71500689D0200589A2DA8149BEB260241BCBD147AF09CB545FF104A603C1E22CAE6476626631256E3720705287DC984FD4B3CF06583344011A4975CD490488DEC64653D01B0394B413814F17B207E1A9BB5CB1661BA5C7439244267859F1544E50B03911188BEE97A12B62052390CACBC9C83C713DAE170CF927C8B4FB94D1B0C9DA83088BC62E9E112BAC46AF692C77C57C0008E44C08B737944BAC8C15901F2564BA2056C03660E7C6BB25C1C6075112A20338B8B413EF9C7421530741CB0DF30C785A86AD78AA519ED65993578E65DB2CB31C138CA6820A05231DD56B17668490D9393911C8E567060D368AFD9BBF3D9369B6B2AA4393899111B72C8014F1D967D61286ADFBB16BECCAF0971FB8A2257BDAC12B60372A61768AC242DF6B575EF18DF59C174ACC51C26276DA960F34219B8F50728290C99AC8C6971C9032C34FE682A58DE45E4B2615BDD08BA6E11AF9030E1968443A3B08E2877D04DA6205A274565953AD6B7FE40565C0B680DAF685049BCCDE9BB6616B325BF11E7069729A6A42544A0E13E90DF4B5A42C2A340FC28960B7171B638173057519568A83FBA15E40BB467B7E33D9785AE34F9E705F2211137E473B88C978D9A49EB4CCA1B5D6B52D5B303A3A8151AB4654544FC791755EFC094222AD8BEB3057A24BF6F60BB6D876C5F7B8D7E6358CD1ACEC6254D97075BF02AF58338F1A787DD335A70FBA4C2AE3625A840EF18B53F8D8A2D051A2BE6BBA4FA6C40992ACF1326ABE29B852C7592E052045655A9ACB5228B4CFD8C54A43FA2F76BA3FC7B10C603C958174894CC0277F688020013C7352B4B282389D9C178AE1AF179C3D7CE495F82A773035B08E512EED8B309A5294B904C46012AD03BC6466D033A551C700624D0055421CC1CAFD8568023753735C1BBA67BBFD117911D0BE47B827ED9773E4D50D8D11A5B6481357473AE2A766156B9A4E74169A1B3CD0BCB90EEBC31F587D886ACCF3027C8F6620AEE70741C403E4A72D4BBA51AF5B1362180158FA5867D25168871D599B04819635BBF096C4980CC336267AC6B956BC861E0A9864766A18D4B8B9EA61A0573FE60A5CE58A87CFA2974CF17D4F599673137DBC662EEE9706AD9A85D780A911C209644980CEA134545375C031B8E1082B4C201EA83877DCD7158435AE34D52376816719070D76C0683E0C4422750A1959932E88562EBC932BB7AE688C09CB703C6E567E6D898B6E135F483290DA271D7EF16B15D12D4E0872CCB05130F52CDEF878EA83768AD44885E5A2DD6B2A94493CA519C14EFA09E9CC0739354CCCB3850CB0C4B504C2EABB1128F55BCCDC17C534B5E68B94526AA46888AE970372ECD49A7F03171872633E78997B51CA867852E638215BE32EB2FB832C42038624035DE54D7F4938AB78210C47BBBC931C336917C9D2A0D58454DED14FC7FCC6F5A97A6C3A5649689286F0CED68963CF24A05E9851FE1277FED36812E5984290701D5BBF138AB76F32B6043853415790A540878C3BB297B6BC7B000036007D8DCC7D32E6B7544C3225C2CA861052DD65C8F1D103103959ED0753E81258EC3770360AA924357315C18B33AA12CA06B24F1C59AAD1B4EBC58F3F75B77C1B07BCB9A23FB0019DE06109050B0CE30E8D6809C8A0CA70EB56E366033841AC39A6A198C5C105C85899E6403781C72AB30BF1D5917035B9FE50B081B6CC6103B72D423237189C583C702F7768FE43C182075A48828D041178E6A616340178ABA89BE3418C4E968F14B9396574B370F1C7D2858A1FD78B5351213B7C0A7E05382D0217457BA27A344546E197B22256B3F031C9E6B65FF377BE25B6953A4DBC9A6E9AEB3B08C01358E2BCACEC80033990F282B0BDA655951A2B0AB83EF4459AC56A76AF2B2D2669C0239496610A4274C9B3E5E998AC948B3E7427C8B380C1077480789B008054373A7FC65080F3772D1F6626E345BB417C9FBD97ADD68640DC12028258970CBA5DEAAAA32C7B022B0183C89B3E1BE25606B3109EF88C9F07180C110703153A247981B5B465318ABCD0A78AD1BCAA15B07EDB66BD77A14B23E84AFA6500BDF15B588009F05925A2FB430B0629BB4C2057F8A231760D9255746781C83CE932AFE10B8602A80FC1A98C694E80333790B59E67722A7BCC2FCD9B61A56A5A8EA6B85B5861B44B521CB0B6ADFA9C84F624AD499C0664AA97270D1A0209897569A64650C0A9B2CAC1879E671D9F0413BE9621B415641ED645FAD52E2CE49F5A3BBE49655649A62BAEB5634E50807F737DCEF63A7FE0C5D2F573B9BC5914B97F28691F49045EC87767EEF405C3B3C8C6089E03268A5F0C530F1682C4C022E3804ADE91C20A0793265A45BE711A607465709A24DEE763AC192D0D57626561C3A6092F7777C8DBA75516C39FB49C2353157AAFF0787BE318CE2C7385101E4D23C043742B9C5BA0D96419E192C20BD426DE458585E11AA4D5C8315BBFBA129A446C80B726060BE07458991E973A394F163E54383D14D420AE0B4746A4B891D092DB39B8E1C708768046CB0E3CA324D417302E861358385229492A291DA3D601A3F41D29A75BECB44D663E9976D61A687DF88A8ABCC6651446B81B7D136DF42BFA03473C84DFD64FDB3B05224FCA29659D6C7A880A5F20D5FE02DC4491F2F095DCF2DDECBF105014C5A8", + "ek" : "7D862943B2C8889CEB3E5059595C85D744F0D779854C7B58D016760F2B1B685BF5E42855F8D010067663B76216E38230051E61D114012F9A2DBBF8553C4459FFAC077CDEB18513F98B2BDE04CB506A05D8B7D381DD0B4EB8F79DE6633E28524E0807663AB251FB2DE80B55A5ABF5FB5A0212049ADF241CC9A548CED0CCB8E2F56071F7D03B132EE58EF91D9BD4CC42BCFB232A2E013F0C7D7281E03DBD2D4C60AAC79048875EA3E78EBE350D413B605E3C17BECA9D8F5F595F2C9A2AFD696CD538A8850D0CA2BBBB5896E086D462E70C60E88B85618B3406FBEEF1CFF2B469A09ED6FFD8199BE27A91E85D6B886B9F9E96EBB8570CEF4E85B0F5280A657DDBA5F93B7B2BA317C1E7AD671B8C951125FEBD083FCF2F6D4C219EF9633319705A9F153B9D4D42141F0F986B6FFD4925C5E72ED398363C4D4531A46DECA1861617697A256A3877361E0F57FC159AB1085F20715F723CDB0DCEF3F57E17C9381C15B5E1384FA134814CB8AB18D7621ADB738C3071D31AFD0433180C0DA14C7D750E08CA18D9BD48A368B7499EE98766824D66555287F1D8781AECBB54AECF9E3DD45E689D0637B5B0E120C9E9A7445387621D0684E32F1FE48894BE1FE37955E4C339B5E3161E88D094BD8A900BE6D39B49DBA53D2F7B5547473526293E4E323F21FA3F1F0E614CE6DF767323A43DBAFD8EEFA61DBDE64BC82872C7D99EF7BF054F95F9304F654BF2E893794217686DF4D8E709C336F57A470E639BD169E086775B39F0A16456A22D9C81A389EE32EE3532555C560CB5E52B6AEB4F003B004C826DFA22FC23058646FAD26487DB3BD27ED4C88F26C872AD2CA8698F91E5D5FE21017E851BB70E2DF0A568323BFAC845E7A24725D1F048D3B47787FEF5946177569AA51B2C9BC882902CEF9718A0B342A41E608C8A2918E4B2C645748A0AB1C1FC3A4876BFEF0161263B8C02567FCAB000691C00C1A267356CF0ED8C13AD1A3463D1F9340B2E1A545D023C2B5C8D2F34A0248C69661A26B8A13A30AD9368027BC671D689AF62EEFDA612B63F9B3FBA685EE032B03B7423C167273B846208AF51097A6E40519D0CFA146E494C7913824DC10DF894C37EEAC5B12A3B5C7D4D5F8C2F52D050D9A1C942E4A938D1FCADB071A04A857A2AF803485416B295BFF434774B396F889A34F6D451AAF9FF1ACA37AE5AEC5E6094924BFABDBC4986E099659B17630D766E0A60B66B4189108B95324A3FE809F10CCA9FAEFC600D367F307D12BB17183E0ED4B7A3D967236F0F8744823CEE6AF539008E0B8D9BD55A14F546403880C8D4AF026EA9368C92009D79B1E6832EBDD4725C07CCAF97DC86B10550A4CC3DE4AC62F515AA22E611F1817DC413F4E947AED8F4E216E64E28E9524F95ABB105EBFA1E523BA335461EB53D68FB781E532D07F43798E34A9520AFB1D7900D482063048B88839437C9D352EC9DC713538091DE84F35D54CB7F7AE0FF496B49204968675FC76AF4D490C2BB1F26F0933D08ADCDAADD93ADE6FB4DE5FCC549F357CBC4", + "k" : "134FF8AA07C647137A2B54E771A5B0837DF893056CC7AC178F6CF711EC82B364", +}, +{ + "rngSeed" : "980D0BA7C8F8B23D0E948A6029FF2659810EA1360064663A8994D0333C8543EE5FF5D6D5C9ACF446E61DC464F792B9D3", + "pk" : "87FCA4992854F318A4DD4188F7F334D83A3FE0D5709E89B4AC382E9873BAF2525AFB10A2785C5AD09C4B28B311B4579A79F06FBC91378109271383AB1EF7169385AA2E78B70D435BDB604494A246BE23B1F26874AC9165AB451355F59686A33FC6CB78464CBD98021AD69C1ED12511EF99428E3B3685380DC2B16C0AB5CF46425984702E70FCA396140A95E2C1BBEB245572049DF3A4192A420FA52BDA254FD55186AA960669F7AE2D69954ABA444FB9C6B6CBC42B5BA82E262957089C76F48BA7362D6865259C321083C464BDC992BDA9635CBC88EA89726A268A34D5CF1EB9AAD5347350F67D1FEA925F5677E393984818053EACACE1844FC52B43D408761C385CB5491645696339BA086BC733C547546E540EAD9B1A7942A0316CB635A856836075D3A87B84B1944A5587CB33C653E44B5BD764F6F8B06AA8688AFA0526188FBBA82707A326817087EA807E2AE51071D5BADC027DDF781483D906259C30EE410B69060E4F47222481CF9DBB2075F330E4CCA839B093668B82C02680C236167F3621921B863CAB9A42E420A050986D481CABB873B6C19FA34B7E21BC6C029598DAA77E30177357BA8B0E7696B692116A97AE2F535CB5208C93611EF5E952E76417FB974879337874F3C56D47A0D695797E1313E2FB7C3C6B2C32167F7FAA9F10D18D512865F6A453E3E37C5BFA100631863B4A5F4B6C957EECA3BEF28F62F98336C05770E001D8FC4F595921826CBAD9825A76048AEF2B4D97CB354784B4B6768377342685F87142AB06A67477B66A9457C48A2F779E0872CABED62D6E73278BAA3406922F8FF5465AF790E02310C9B8BF6E1B2987CA6521C55BBADB249ECC26AFB244029312960A55FA45B448397264AA03530B9B56643A0D7CB9A73589955631883ABA865C4D34FC5F5A6B8D596CB2C4DB2B740645EB0A29647089EA2BC8A92BAD95C15F52F5A2D24431D83AC4E701210C5B0BA3F31BD0086E47AB3F7984363BA00041C082D33064F1B27FF26958B85C46612C6556561A2E40600AE14FA70B4C1A81109FA6822C01D0C2786F0E17CF198009349704159866E557947B81928FEB459B2337F3DBCA2C82162107B5E34AA202B893C103BA5CF9B4580107C1F36B6FFB9AC34C2CEE189571DC7F411349AD112D20F35A740C216FF98175563599D3CF6224BA230C2B2F087525059F9AB5B80F63110719972156AA30148BFE4C907B214F683C56A38A146E1C21E688C44F40BCA8D4A87D3011BF64725360478359ACE455C5E395625C95CC84EA3F0D004B2E3A4A12180A1463A234C4912F00BE8324906B3805151841A1F4A5595621D66CA8B1863B6AE4869B4C93E2C6C94FA6AF25F37E992CBC7AD23F6A274BEC8B537F89B996439B762B2FACA39D1F743DB79451CBCBA86DE02A9D8567D8977D12066A1817BD9FC2B1BDA75B9D6C78A39BC851654008B266C45361DCE46FB2B02E4894C784F0B017428DB0BA8F1AE54F3E8050381A90BDB073C186AAA458A2E8C682B919741836397E3C59E0AB75DBDC48976A6A474969356A75E171BFB2CA76E968191D970CD9E43D2FB2843B2A5E9D24CF4B2CA947E01F0C129A763BA55B9B92260C21113C03C7002BC8C6A2C544AF711C18030CA984DC584E0B0627B3D23ABD9C4D9E5087BCAE2BFE6581EB7F9CBF532BA6", + "sk" : "6423BEC1793D33F81BDC6A591EE2BB7D7C9C29E43654600EEB353459A19199234CA950CA5E51B3C8B24C5A96C164086EA746C3B68582EE171C0A03CEBAC11B39EA6B1C5218025118BA696DA2DC9BA9A87D197931261273DE87BD360389016131E47B66B54216474CC8C68C6F8485201692A53D3CC06D6BB1A4CB19A69C435E42706B1068C8872412E1520F7A2EF7CB361DAC74F339059108277DE75EC66B76C7D432F84BC17E5C20F0A94764C66DD8738E61012960B9B2798B4C0DCB213C0672B5530818B82A6BB29277735451147FB4A4A1BAC36949227479B74C358C2B3CA852048AC6D52872DC63187BF87F47A2C3024B41AAE5CE52E56607B5541E67B9C528503013354038197A86A2CAE824B6D282B37C8332A2BCE5A30F2357022058779D5A2E266430B89B3FD752CB5CA26EE317C628061C33203787F2865342CB9012158C113E402640D5E900C6DB4DA9C1162FF9079B482A4EDA56B63A626572734C417952EC894B10AEC7822121A78150042AD321A70554AE6043A6F0FB12C411876CCB65BFABCAE28B75126189FD8A1CC5510A95D36FB2318E96441BA4DC09631166905579429BADFDBC6BD7C231C971837FF422327C5F769A1A89668DA2669EAAC1564AE75E7DF44B9586011B6CBF7ABA51CE68260B5505A99207438837A2C67B047896F9F64C1B2A54959061E92C8A73742962366C16B72EF3509B11748BB819ADBD0B400964BE48CB7ADDA5627EB578933A698EF8137E362308C32AF7E93EC744984AC31DBB34BB8603B48965AC93891DE258A9BF942C36EA4C8D7C23A3978EB5F176554BC809D5946828B0F4FA0C55744E702A715268B8DC684133738AB9CC9543A74164E9731854327D7361B636069AD00184B5B3ACE48900BC0A28411C123B4C79D1A22346A10BA3488732B2A9E194BEE742A36AB3C1CA9003A76E28439C6667C3D6A731873150DED546F132644AE4965ECC29A5C961F04612B194B0509B3157A80859C2A95C9AB2B5486B3FA8732BD4C18BD4B806148D64D22F38C7685C9934F7B990CC378106579F981C36D5C99A26DBA6DF2921C6385CA329127342CAE148974D2B2FACA90ADB629020104E4650ACF41C5D85036BCC30581F304A5DB46B269424282776B6CA06BB3119A009CE22811E7A004C58B28F6AE24EE8E7499B331749DB0AAA33710CC9737EF18DC1994218CA439A46367590086EFB839589380560C6CEBC4DB59CACE187700A80508E3C9FCCE960637CCBB4C8A5BF3A6D3DB865696A5A5E824F91B7CEC516415DB47D0B706B99A0CF5963875E89A08C5272DF90987A7C374DE99113B54BDC5063C462011E225F223A377C3A15EC81C376817AABB785AD0B5C2A0BC7E55525DBBB305396319ED108F7FC527BE906F6E20B975B9EACF7C6CD574DEBD4027BF367518A0062260D0879B343783ADCC44372667AAC541B454A84B8CB6FE1DB9589E43950761D82C512BA923819A4078CB620FB750464D10E0069516028B145628FF1F06927965935E5B23592959F9B39BC32BAE290A583C24422B5545B22846E42CC1E45BFEF5396CFEB544A865D7739CFA0891A01D1C2D36C6F341C24E677A8218640D12CCA27792DDF9A488AFA799E580AE6B08287FCA4992854F318A4DD4188F7F334D83A3FE0D5709E89B4AC382E9873BAF2525AFB10A2785C5AD09C4B28B311B4579A79F06FBC91378109271383AB1EF7169385AA2E78B70D435BDB604494A246BE23B1F26874AC9165AB451355F59686A33FC6CB78464CBD98021AD69C1ED12511EF99428E3B3685380DC2B16C0AB5CF46425984702E70FCA396140A95E2C1BBEB245572049DF3A4192A420FA52BDA254FD55186AA960669F7AE2D69954ABA444FB9C6B6CBC42B5BA82E262957089C76F48BA7362D6865259C321083C464BDC992BDA9635CBC88EA89726A268A34D5CF1EB9AAD5347350F67D1FEA925F5677E393984818053EACACE1844FC52B43D408761C385CB5491645696339BA086BC733C547546E540EAD9B1A7942A0316CB635A856836075D3A87B84B1944A5587CB33C653E44B5BD764F6F8B06AA8688AFA0526188FBBA82707A326817087EA807E2AE51071D5BADC027DDF781483D906259C30EE410B69060E4F47222481CF9DBB2075F330E4CCA839B093668B82C02680C236167F3621921B863CAB9A42E420A050986D481CABB873B6C19FA34B7E21BC6C029598DAA77E30177357BA8B0E7696B692116A97AE2F535CB5208C93611EF5E952E76417FB974879337874F3C56D47A0D695797E1313E2FB7C3C6B2C32167F7FAA9F10D18D512865F6A453E3E37C5BFA100631863B4A5F4B6C957EECA3BEF28F62F98336C05770E001D8FC4F595921826CBAD9825A76048AEF2B4D97CB354784B4B6768377342685F87142AB06A67477B66A9457C48A2F779E0872CABED62D6E73278BAA3406922F8FF5465AF790E02310C9B8BF6E1B2987CA6521C55BBADB249ECC26AFB244029312960A55FA45B448397264AA03530B9B56643A0D7CB9A73589955631883ABA865C4D34FC5F5A6B8D596CB2C4DB2B740645EB0A29647089EA2BC8A92BAD95C15F52F5A2D24431D83AC4E701210C5B0BA3F31BD0086E47AB3F7984363BA00041C082D33064F1B27FF26958B85C46612C6556561A2E40600AE14FA70B4C1A81109FA6822C01D0C2786F0E17CF198009349704159866E557947B81928FEB459B2337F3DBCA2C82162107B5E34AA202B893C103BA5CF9B4580107C1F36B6FFB9AC34C2CEE189571DC7F411349AD112D20F35A740C216FF98175563599D3CF6224BA230C2B2F087525059F9AB5B80F63110719972156AA30148BFE4C907B214F683C56A38A146E1C21E688C44F40BCA8D4A87D3011BF64725360478359ACE455C5E395625C95CC84EA3F0D004B2E3A4A12180A1463A234C4912F00BE8324906B3805151841A1F4A5595621D66CA8B1863B6AE4869B4C93E2C6C94FA6AF25F37E992CBC7AD23F6A274BEC8B537F89B996439B762B2FACA39D1F743DB79451CBCBA86DE02A9D8567D8977D12066A1817BD9FC2B1BDA75B9D6C78A39BC851654008B266C45361DCE46FB2B02E4894C784F0B017428DB0BA8F1AE54F3E8050381A90BDB073C186AAA458A2E8C682B919741836397E3C59E0AB75DBDC48976A6A474969356A75E171BFB2CA76E968191D970CD9E43D2FB2843B2A5E9D24CF4B2CA947E01F0C129A763BA55B9B92260C21113C03C7002BC8C6A2C544AF711C18030CA984DC584E0B0627B3D23ABD9C4D9E5087BCAE2BFE6581EB7F9CBF532BA6C0CFD4113C5EDD408ADCD03D38B12F0B6AC17525C618D6D151A761A9EEBC26356931E7324D5527DCD0EA7E2E6C2A82D4A80C3EDFB38752B36581F3035ED9A23E", + "ek" : "F050383550F34AB78390C0CBEB6559E70F8E84503FA3F68D4D4B24497581A4A2C99B9B8C4D43C435FA570A80AE46A4B0286F136B084A0D92D271D9A9D3B52C2DD06FD9348985324B6D79322FC74BE4DB116878F4C9BCBFF633EA455CC553A36B47F29ADAA83B6FFC54CC1102C56A91B794CF637DDE45848D1D82E759425ACD382E20832BEB6C7E7BC3B6E5B321ACF78E98C1336F2060FA32F3697BF5BD70BDE1B4162E85747D8CD619D5C37BE1F454C8C38F805DE39C949557A6EA77B40EF6B54426A2CF286D3D895576493E50E35C4C4468538AF1A93D528B20EEA2DA6E2F687FF28EAEC10858267E966A1D661ACE9D6884B21CC11C258F5A3F71FAAD6FB5DC9DB77965DEC5B9F7762DD500310904F0A9BBED15706904C63FFF5F7A7D7B76200B52430774C9080947D4AE51F1971D372E62AB0E52112A15C49A945A760791AB39800CB8BE95C2BF9AB406EDE2FC318B8E09A4E614722E6B8F90A6206548AD3ED05CFDB265A2EF828E134CE68B8077705B23414F8CE6C80149E09EB93C1F101FA5506E32B766C5FD01125F3135C358E797E40F9343ED593EB39E11270D237838C5F544F476AEA512DD8496B3AE98365F4929D82781D81223F89209A6F550D07E6E48EC0AF2C96F4E3DD73C0E823CF2782F79309BC876D0DDF6333E2D1FF96700B7708C62F7081649C989B6E7E2B495A888A73C0676765C1E8BA3B26EE6E9CB6A5115AC366EC516FCB9B9B884953B812AF91E930C5B70616BB0219FDC8F8ED9FA64A267F1F0BFCD86076A6A1E2EF06285D4A97C15A651DF8DF26D3A625FDE0D26B76D332525BE57A9979E7B17AE8CC1031953CBDC4754803FAA5BE2D9847C76C751DEF42AB8CEA9201A30B650C9BA2B2B92237B1776FB2F83C8601C9D279E1D5EBCD95EEB6CB66243902B9537BFCA6935C4A55C30371CA95A3CBC6E066B275A52BFC3983D13CB87A35A207C20D850EFFEBFD2B2D92298549DCB0703E8BB9CBB7C6E86CC6E97296A1257C9329ACB8FD77629F6454D3E4D6B8DB54458F697140B366CA1F7490D29E1C528A87D56E1AE447897E3606E065A8FFFB4DAD89936984921BC192DAD076C59677027D6A4B56F3E71758B5FFBF0FE779E599B1D2318BAB0FE9BB7991F9C949AF4496DB4EDFB9E599938B2F04B3BCED0B4107B15205CA76596A73955DD654D0F66654BB6249AFD66035EAC4B921234E96AE04757D11317641A91CBACB8151260230F6E71E5C399107B3C1D2C35337D3DF5B88E9786C57609C5CCBEEAF947BB7AEDE12B7F6D2A6A0244043C74E82C6BEBCF41E793DFEC17F092832EEDF80605CCA7321BA9805049044C2025DA5E494AA2665A15174D3CF11895B867CCDCA431F6870248DD843B801D63450F117E81FF0CC16B5607E8DECA659871ED2AF46F15560FA5EE98E963C8BF4281A68E395C756638CB821F95E0C71D83581B82897F099EB0A6F7767F82D4ED6A2275718C4EB8CC587B652EAAC0FA5EF969E69B4D4CF5B69D6E7987319597FA8381B757F7D1F3068894855D97F2F92FFD", + "k" : "B6F3C02117EAB40E4543CDE85F920953AC389256D09ACBE6C234EA40547428C7", +}, +{ + "rngSeed" : "6C029462CA42ED520F10A579F52687101105E0B90C6E7BFA582A4C112B579D5AD0A0ABD38F72ABCFDCAAF5893A112BDC", + "pk" : "0D40B119341D9E23062C693509304BAC635F93F91BD48B362989751078AB995408DDF6787CEB3F99C6802AECB703581DC6979C4D405DBC80A985F991F31924383428D4F5A2CAD4ACB5F95408A3406EC53425F175651952F5B76ACFE2A465B30C1D56CA0E53953DAC0EE2DA352A687441F45DAE26B37CE8008A99308639999D325BA89585656A6D59F51D10E46F93D099490C2385788C994238EA1155ED22C96A5C5035A3488BE1C29E345EBCF6B1B7288ABE95C29B272A7817704BD31589A42B22053226A43329183F6160105ED05E73203D172354FA176D3FD084CE690A8B6A4CEF4035A3E06BC6464E8C913B88A48C81E58DFB1267EC6C1462D93433193E50D1B2D3E3828E90B6A412C1C45668272307F4B8294F37B84857BDAAC6190706CA31380533C30643FC319C866534562036B37E825462C8442641C7817650333FB02ED6A2BCD6C1AD0689001098AF3657363AA1B689A20683044D15275D0FC3C9AA720C8C4C6212FA70095A2243232CDD0B0FBEAA1C8E7B45FFC2870EFA9BF56C8EE86659A618A0A96C42ACB48AE125AF911558F7CB20C9CABC4554C8FA6C70E297625286456EE625AFA756145C41373AB4FB59B2782B4A406115DE4966D07629CF8CC2283B4307E6A058DB3DEE6413AAD72F89A7C1AB4131D8EA9DF020B033B1473D92C4D89AA84F044E429A43B4E22FBB693A694BBA3E315E78475437387B78B33261D786288B20440C44138C84F5592BBE74C1C2AB01CCD1124394082319780B24C593149CF660946F75A930F0A8F93A50ED01B5276BA96AB6CE5F794E638697CECA94D80585CED04310612A3C6CAD80DCCAB1C1CBF5E08B2BD6B7DF8C4CDE4C4507A56CC97B456E10050BDB3ACD6A7E00C1742AA4710E1674C59A8240680D04B8829752332324490ED6139B550C7A832862B2C831D4093DB2B256F702850BBA03053FECAC41A61734229B2DBA3210EEA0C1E8D9A54C915F54B32344296EA64855DCA92AB81AACC9E73153617D8464852E8208904ACE7B84509B2266F9FAC55BF68378D98D3FBC0A468543A8944B9975637162A4D50C7FDEB479DAA8BA43938333B897A12C224ED1C790F967B2D9708C6B67640CA9DDCC1562613C2904C6F3856D13D904CD3094965ABF1ED32CE52B7DFE4429EE68A8A3AB03446376D6DA1DE56A7A7FD30688F513FADC5627619A99D191BD4C0EC8BC1933C00757AB3E1F5826677B5E9BEC2B151058BD9A6B5D2285122C23466312559C89A634ABC2A5A11324CEBBDA8D167880F6D59BC5FABCC23487EDA84F3543386E0B8D25422D5051816315532D2120EA4723809509BCD0C2EDC1C93C275ADE244D4F5B27F73B0941820DA0183CA2B7AF8480C90243AF6334B36AF00BDA4C1E5F50463B8C350923B4696B7EB733762D189C9EBA08C09050A4946388D736EE73C62F47CDFFE453776730E88531F07ABDD8699E8BDC9F05BB12F275C453866D46519CE2A592A1052C1E0C6B8F093F53A057D6D1BCF759ABEA90883EEA68C5344A0AE96CDAD42F0E756070DBB496535B9E7325C02BADAE5533140B0D9E013C75013FFDEBC855734AA9947F1CA4B879C35B32C862C933479D884B2C675D3E1BBD26391D7C429DB547041502307D975AEE26905F7FDEB44F418D3D1FB5B081A3B06F87691170917A1E9F3C2CDC", + "sk" : "C062BFEA197AD53BC1F0556D6DC8A863D46BCFF5BBDBE919D96C4099627710B0417C889ACA6964A75A336EB5AAAE40674EF3A3F3F96D9207CD0988CFE76838BAC93B4EC866FC4B6B1127BDEB5C9978AB3CBAA6999CB508358B92CB3A859754461BF25A471BCA16BA9259B40B3CC31BA8831EE9C95904B9303BE152827525DB350F9CA65183B63A02B289192A224B781A6B11CE7A40BCAB396FEAE20158536BA9D86568401AA68B42856427B9003053C15D7D36B9807960B94B5F3F366896C59298689EFB101C8AE162F4B4B53D4BAE816C01A56BCE8C1232548007EB887A93703B66EA609869C7155BA0E8E509AA7C29DBA60337D8364AB61DE403A45F49041E82671CA0CCCB5002EFBBAF65A7B452A0237F1979A4988C524570815017F794A7BAE806A651A732659A36938B86AB36F7536EB27C5D9B72CEE990131C1A6B31ACCE8FB5473CD0CC8FC2605B3C06F24866A36138E1148F50C9A530C24911D031A0F1A2201137EA201EB8C3B788F15D3C0B0FAD52BAE069818480132992512BD5B57DF93B288A6B9A18C3D1F337D733A6E1A7B7780B45F3813AA855C64B004EF55B89DA05A85B1C0638F56F6D6C87EBB947273277A9C5392E489AFAC0276DFCA66687709F69BC73F373C929C7CD37C01CD2437060CECBEB1D045671500743CA451F7D9871FE252CCC39C341860A25D47CA90B18ADC3AF22D849389022DDD3A6E887212D6C9FFEB47DA0131F76C9CAE0467C35968242118F0F41330CAB99A5412642EA0817EA08F0D49380A94952956346087012AC595D85A2339779C956ABB2B25FAD4512CA46527B54954FB81BBF79CCC0801279DB6D57D5C16DA1374AC841B5B441BE3944003C30A90C56EE10239E746AC6FB867A50808839639AF13F36D516B5056605236F57572844D657AC209135569455D2349ED67F3715902C4B5894229EAAB63D0BA964BBC6884C1B57346CAAE6F1BC953B62F73827EE67468644AC383128FF6A3E97EC0CA3689A50EC5AA40392BAD95E88E241666B18BC7092F01B9C7B3194BFA77937839EBFD2495FF29CB659A9374A8DBEB51306A21553995AB9ECB83637BB702365690812C3D18196EA0069EBBA9F952B6B468B0E9846F4F7AF8C17054189CF5C2200140AD0551697387842DC20A4EAB8A1F0380934EBA5C34113962C652E11C97A0144348C3218D371380C476CE987870472D72A38A2475539DCC545693D4A17AF010A8FF93873DC24051F7A69EE7C3297CA508C3229D9D215B95B369D4126862A03531BB1FD7092BBA391D5541EB962B403B50565253A1B91C63901269D18BC41003BC75C876A277ADBF709DEF9B54447641F01027174334D963813A678CF7507B5562D1028A63DF2411F6A6D5771C60B4A26F6BA1971943248607D9EC3B72DF5B98802CCDAFBA8A7B0661A662C87001C3646A888208CFD68996FDB37BF9906EE99A0D09693F30B1C924C919DE4B7AE0359B2B159D648BB4FE41D197C8D8444C530995CE8C3AAC17637F699AD24BC0153FC7572C759E741C1FB71982FC61921C4515FC260AFC58FCA4A92DC3B9426F717CC0B60C6535D1F34B4EF858BD12677EEC80451791191148A0FE00343D0AFF44250CBA46B9B6263594C940D40B119341D9E23062C693509304BAC635F93F91BD48B362989751078AB995408DDF6787CEB3F99C6802AECB703581DC6979C4D405DBC80A985F991F31924383428D4F5A2CAD4ACB5F95408A3406EC53425F175651952F5B76ACFE2A465B30C1D56CA0E53953DAC0EE2DA352A687441F45DAE26B37CE8008A99308639999D325BA89585656A6D59F51D10E46F93D099490C2385788C994238EA1155ED22C96A5C5035A3488BE1C29E345EBCF6B1B7288ABE95C29B272A7817704BD31589A42B22053226A43329183F6160105ED05E73203D172354FA176D3FD084CE690A8B6A4CEF4035A3E06BC6464E8C913B88A48C81E58DFB1267EC6C1462D93433193E50D1B2D3E3828E90B6A412C1C45668272307F4B8294F37B84857BDAAC6190706CA31380533C30643FC319C866534562036B37E825462C8442641C7817650333FB02ED6A2BCD6C1AD0689001098AF3657363AA1B689A20683044D15275D0FC3C9AA720C8C4C6212FA70095A2243232CDD0B0FBEAA1C8E7B45FFC2870EFA9BF56C8EE86659A618A0A96C42ACB48AE125AF911558F7CB20C9CABC4554C8FA6C70E297625286456EE625AFA756145C41373AB4FB59B2782B4A406115DE4966D07629CF8CC2283B4307E6A058DB3DEE6413AAD72F89A7C1AB4131D8EA9DF020B033B1473D92C4D89AA84F044E429A43B4E22FBB693A694BBA3E315E78475437387B78B33261D786288B20440C44138C84F5592BBE74C1C2AB01CCD1124394082319780B24C593149CF660946F75A930F0A8F93A50ED01B5276BA96AB6CE5F794E638697CECA94D80585CED04310612A3C6CAD80DCCAB1C1CBF5E08B2BD6B7DF8C4CDE4C4507A56CC97B456E10050BDB3ACD6A7E00C1742AA4710E1674C59A8240680D04B8829752332324490ED6139B550C7A832862B2C831D4093DB2B256F702850BBA03053FECAC41A61734229B2DBA3210EEA0C1E8D9A54C915F54B32344296EA64855DCA92AB81AACC9E73153617D8464852E8208904ACE7B84509B2266F9FAC55BF68378D98D3FBC0A468543A8944B9975637162A4D50C7FDEB479DAA8BA43938333B897A12C224ED1C790F967B2D9708C6B67640CA9DDCC1562613C2904C6F3856D13D904CD3094965ABF1ED32CE52B7DFE4429EE68A8A3AB03446376D6DA1DE56A7A7FD30688F513FADC5627619A99D191BD4C0EC8BC1933C00757AB3E1F5826677B5E9BEC2B151058BD9A6B5D2285122C23466312559C89A634ABC2A5A11324CEBBDA8D167880F6D59BC5FABCC23487EDA84F3543386E0B8D25422D5051816315532D2120EA4723809509BCD0C2EDC1C93C275ADE244D4F5B27F73B0941820DA0183CA2B7AF8480C90243AF6334B36AF00BDA4C1E5F50463B8C350923B4696B7EB733762D189C9EBA08C09050A4946388D736EE73C62F47CDFFE453776730E88531F07ABDD8699E8BDC9F05BB12F275C453866D46519CE2A592A1052C1E0C6B8F093F53A057D6D1BCF759ABEA90883EEA68C5344A0AE96CDAD42F0E756070DBB496535B9E7325C02BADAE5533140B0D9E013C75013FFDEBC855734AA9947F1CA4B879C35B32C862C933479D884B2C675D3E1BBD26391D7C429DB547041502307D975AEE26905F7FDEB44F418D3D1FB5B081A3B06F87691170917A1E9F3C2CDC71C5534BB819E61A9D8A257FF2EB29598AE92ECCFAD38ABBFC9BCCDE5FF95A1C3390C2FAA8E2BBDAC1EDF5A5B6803BFD3C58DCB1ACE60333D03CDE2C71737F55", + "ek" : "0DA324A8217E5C4295FC5BADEA6F435E09DA35AE9517A17C1B154981F512F1E8987F60B37696E1A04EFA777F8FB6CE4C3254998F6102104164415C137500AE8CE1E66AB3C0284E9ED2BEB5B14B9F341BAF62CAA46837B25F77F7FBA5142D6B2D36BB0EFC3E9CCECA334DEAE6D335819292B7131324BCB0D33BBBF11567943E89257FCD76C23C88A6B6D05A5FF2D6261C7C592C8F25F16C6674D6E79E7F1BA85935A6C6A50A088C32054221E516CC563387B5A44131977CB04AE0CA6792F168F1C74CA91F094FE2B9DA833A027EBA20F254218490772678C41E6C13F85E6A502776419200EA553E7723CDB3763A1154EE725CA06618C2F460C7DB17F2E08B0E1F2CE87C7BE76FFB028D68961A3A7CB2102B0416DF17A743B6DFE229372D1BB76F8C1AB6C54437A205ECAFD8C62D3F6A5C639CFF6C90C8EDF3DBFDCF8B3ED5F464A3468D7262136DDD6B2ADE2E773B11EFDA1F4A2EDD1E5240934A9A8806F546E0E7046D29A310CD33339E0A46584FB9AF66985BF75ACC0ED15EE438E7830D07C716FEB3A222B9D0EC75729255C2262EC050E3CC465E9359DE23A1DA0C7CA1DAD7DA0644A7A151CD3B41EB764686F895F6770D8AC7F565E4BB21D6A1E118B73E0A75E86C52BE741E70D8C1D8DFDE9668DAAB1EEF028D197F63233F45601125197B4617D291EAE5EAB767B19C078AF1FE58516A81A149408273B21425197A00BE70ABFA99C15DA8D196EA58D1CABAA8C33904A75EE0BB996966B0AE0A8C6B019CDBD7B347AE9830D07537D9923E1483E99A6FB94BC8B9BB89D79002769D2120D4113E54CB2E1D23B9F35791FFC1D52E9538669EFEE5FD253511B8765231A33117C5C9D9A70849051D0CB068D58629631B92E1FB93A12276EC004AEF3EE8767A1317C9A33366FC37DD3D0199E6E83D136B9DBF9A535980050074654CAE7F6B3DBAE78E4165FD2D66FA402CD23D41EA1DC1B60688F15950FF25B02BF498F789A1FEE0B9E9382CA4B4D7E341B9EDF859780231D3FD267860B57151BEE8AB823839DF4D4FE546F98DE403016C62233B6C13874A5D831E510DDA04D6915A6F5C0737638EB7FEF0A57EBDD8DFB320E6C0A2E6DBD4EDFDB46F5F3DBD8CB17ACDD2BCF288DF0D8C8487C75760CD886B08D0AAC5926CE87F5BED22889568377D8152FAA5D6C58C2199F326954F403F971590753E47ED433142F40B80A819D0C03A651B4A8B6DA1D10E349123F3EFC85842EF1522A791629D3239935B33828CAE06822812EBFBC938510B4AD67DAE01E5870F4E5F762AEB8477D55B4600694AA448EE069F7D984C42CFEE7256010189FA39A0B52497F223570765F6A8EA9268B0569D0465D57C8761595FDDAB3E735113CD4071A88280314268F24772B194337BC3F6463C88603845B9F410098FAAA44CE56B75278FC26996D1D283A964953C844C2341106C3BFC2042EA4356898C1EAAFFCD782DA98F707B96F5DA31F367801A695A7BF9B2836071CFFB9382117A2DAB749ECA00CD2DB47F5C0BAEBFB2A7C277852772DA715D", + "k" : "C63EAE2F374936FBB0EA76FB9D1570DF13EB3D4F502BDFC7C1EAE2B4173858E7", +}, +{ + "rngSeed" : "DB00120937570D62331F4C3F19A10465231EFF46465CDEE336A0D46AA1E7493DF80F18617F9FFD0476CF7784A403EF4F", + "pk" : "62032561926A6380B6D6D90AABC5617126AA509168ECA264AD67C5CCCC5320C138E4053B4376924E6CB250B3A61FEA8689804AC3179588A29196E05D0EFB6915B3526D945CFC183DAFC40D46537D907A292CD63B950659FFAA57E280ADE8C09DD80655FE45979B612A6C6B1E350BA0CF433552E80F58C79D91F5CBFF0717F3161F83B3C59FCC021BB5CB1922B0FA3C29984BBFC3363333F561DCB99395561590409FD7B56BB7DB88E4162A61F8A81CA6B55AF485D9B06645C42D1F706E9EF2B3D6E425285B4973202D46F150FDD4A6BAD34A455B274814AC5C4053D680BFB4816578342FAD152B798A1D592A3C88B45BDC275C45A862179557D437304151548A568159691282BC08F9280BDAF30559A3A177E6B8A62B101D8342C9D72452E05BBB1634CC1A7465E479F100B6F2952DAB8AC806C27A8C555EC20A995C25A9EA8C090261085BD65C137A630E787DA7A6B039C38573006C79BB5C20E39756E1A72E2C016F6CC997464546283D76543D9774345AC619F9200C308C25CEA332FF25533B7983DB495100F24A42E4A8DF11504C4B96C017871B5A594E9C0B241B01E066043D07A366E343A08AC561EC5A08168A1C61755D5C33BD693608F42E63706BAE5CC8C7F47AEA360093FC78045517BE49566F35728BD6A8230984A5E21133B63A9CB4A7FAB4BEFE053E37BC78900141EB21189CF2ABC0764B3CC507382C8DB2320EA49C988C5AAA7AE896D10702C2082A59C3A457F382F44A1F2CE5B3D29A5A08D047537163916C5F6B22995541B87E1904B62A3585429D938A1B37D419BFC533CB918A424B5A1F73A65A8605EDFCBD00678B6361399AC794F2CB0C9B26939B09BACEB79FFC55AAA528673CCC4A5B844AD0873B4D6A31465CC479C30273AA2EDD362625512012F83B42D52781C3BC947872C78378164CB0E077CF9AD87974C75CA527AED41A8B6993073D711C1873965448B14D307C5B218717B94CA27B354FF99DE1F581E9561EC3CC196D1815A7A60A8C9A94CF4354140CC5E3B98BFDEB9C95C7C87182B878BA20939A0280E2C453567215A15803C01F7F03BB0B90741DF964C4FA02F1007C466BA6B8F78BEC07956611420220499A013AD3E3A874C4AD961B02E4C27A9AE71D57377DBFFB556334797EC28C701C220129B856E747B90AAC0803B2CBC7B0BB428583B810EFE1727E0598CDE9681429616C7B3F8BD8B691841A7A5405AD288F77B652A49C38ECEB4088201B651A5C65BBC05E40A7A0F4151EB0962C34B10C1869A003CC4CF86D39036778B3CA32D0C500F7918CF027EF920B3718AB1C191618F294866B2FE77BAB8C84118CE55157714AD2D054102A4D38AB73D1F3967E98351631582545C5A60B3AAD50A7852C9D43B945668BB8B6781F56057EC058B2CFD6310506133E38B75FE3086D990D92CAB098F06CD376531BDB8308E5A4D2E323C87C36E7CCAAC87B00A7D4CFA3B3342D74A02D888D702CB44BC31201E41FE62C7511493C068A92717CC5513045BFA197D7F83DB35798354797CCA7891392AE9587245E92974920551D826101D44D9F73B3113746114AC94B8C8E291892BE9C8015A0114EE44E26879C02084B0192194B922284956A8FC2B26E9071847FB901FDB6603C3BF7BBF5297BEA11539FBE18868709FC57DC4D46D7D54159", + "sk" : "77996BE8A7AE3546A363E340C57039FBA8113ADACF805385EAD18C56B75320CC714072C4549A225C86BA31212146220EB217133A70C987E3819FF1B6364806D6750B9E293EA05013C1241E0760537D867640171741645F18D451670007AD4C971DD16DD3C55F8DDAC186F029796979ED9091CBAB1A46D093B1B89265B7A5BC81459DCC638EF08AA0BAB48FF95E48C725FE90C8694274AA6365EA4BBAC173A658BB3F2E646F9D4645A914B70CF92394586A3420C60FF2290217576C43518E1088B703CFBC3A3837794706188B5772C03685C43A33AE27410AED7825E2F2541CE67C07F15A71A5910422BE6EC94631B1B465443B7215C30146C7049076EE1418E932C2A4061C1F1044B7456ED355851C41214AC25723BA486CD575B608359D2A948D85895ECA59DAB3CFCBB6A366815DABE7323EC05CCB9042C994B18335077C67187F352AB30A06D1D40007A1636AF51602F936F7694A0DA510BADC59FA21B3AD033F9B03103F6655FEB646F217809D00A521F6227876263B8B7663610F0392BDB9A5089362828BDA10667A36AF12BB9FF090CDBBCC6B1CA0E8259422F376A342944B118F74960F3D322BC11B0010AC32C49584003B2C66198ACB0239D7A55F7ABA6FD5546EFEC7A27C39C658D15332AB36F2988754F86F51C642FA087BCC935219E2B35EC7AA4194BFCAE007E465CFFA530C6B9982DCF98924F924591B2542B34FD28057E189A0448841B121A39AE17EA5D7101971B26301C43FC84EDB0B8B0CB35D6E729955208F650610822918589C740667CB31B169AC104160647F50C77924FCC6CCF95AD81603AA8481CB4BCEADCB3A6761B87831274DD8C5B6A7674F0412EC341589C303D6833FD3D25FEE059C5EF269F7A910B3060FD60217C7A83A75C53115083FB68A9AE2DA8F906C13522331B329C6EDA84ECE980284D9BD405B5A8CCC821B8AA99D49969871448D3921CB2C8C8C3B4E34EC07FDD299C532BB291329A4555C257A842D93BADABC414778C76B7293E369597E7C092A3020AD72B5335A93CAC4CD74D51FD3410DA6CAAA98085D107BA0DC3070A1284BAD4398AE8B9ACF58992397C9F0F9B2DDCAC60BF539D0253D2D3377903A6963597298F97A82BC92F7160282E25387F57C4629A0A3482A563A0B1C776C18870B26E289B511BA601884864787CD922B84B7CDECECC21E07120A9C5F23E5AAEA649EFF523EC0B54FB5FACE103A1A30714F6429421DCC4C3066ABDCF33356C09109ECCEBD2A68ACBCBDF3B162FB9A7B3D1C3743AC47B5DCA488C561CAACA4B2FB1A86AB91D00A65E97B213125836BF4190549C300F1A010515F0CF3C5ACB2BD10A20851078DF28999C831C14CFACC45D5872AF85800431D350921E959A231C64103F332BDD55B3816C150B61DEFA324F7DBA659E0CA30B9BC6138ABC707BE19A476F857AB9226CBD26A31E9F6A06D72369B6B5E21A7BF76538DA8FA06FAD879AB62C292A44E448B8252278EEDF1BB283AC71B93B50D592BEF275749C4C154BB669DF436F081785988C42B99270C1435AF451030FB08EC871285A9720646ACC3CB015F63C87CC0BB74705188E145EFE133B657A9CF360F48DC1E2FB11163AB31C6613A51307641E25662032561926A6380B6D6D90AABC5617126AA509168ECA264AD67C5CCCC5320C138E4053B4376924E6CB250B3A61FEA8689804AC3179588A29196E05D0EFB6915B3526D945CFC183DAFC40D46537D907A292CD63B950659FFAA57E280ADE8C09DD80655FE45979B612A6C6B1E350BA0CF433552E80F58C79D91F5CBFF0717F3161F83B3C59FCC021BB5CB1922B0FA3C29984BBFC3363333F561DCB99395561590409FD7B56BB7DB88E4162A61F8A81CA6B55AF485D9B06645C42D1F706E9EF2B3D6E425285B4973202D46F150FDD4A6BAD34A455B274814AC5C4053D680BFB4816578342FAD152B798A1D592A3C88B45BDC275C45A862179557D437304151548A568159691282BC08F9280BDAF30559A3A177E6B8A62B101D8342C9D72452E05BBB1634CC1A7465E479F100B6F2952DAB8AC806C27A8C555EC20A995C25A9EA8C090261085BD65C137A630E787DA7A6B039C38573006C79BB5C20E39756E1A72E2C016F6CC997464546283D76543D9774345AC619F9200C308C25CEA332FF25533B7983DB495100F24A42E4A8DF11504C4B96C017871B5A594E9C0B241B01E066043D07A366E343A08AC561EC5A08168A1C61755D5C33BD693608F42E63706BAE5CC8C7F47AEA360093FC78045517BE49566F35728BD6A8230984A5E21133B63A9CB4A7FAB4BEFE053E37BC78900141EB21189CF2ABC0764B3CC507382C8DB2320EA49C988C5AAA7AE896D10702C2082A59C3A457F382F44A1F2CE5B3D29A5A08D047537163916C5F6B22995541B87E1904B62A3585429D938A1B37D419BFC533CB918A424B5A1F73A65A8605EDFCBD00678B6361399AC794F2CB0C9B26939B09BACEB79FFC55AAA528673CCC4A5B844AD0873B4D6A31465CC479C30273AA2EDD362625512012F83B42D52781C3BC947872C78378164CB0E077CF9AD87974C75CA527AED41A8B6993073D711C1873965448B14D307C5B218717B94CA27B354FF99DE1F581E9561EC3CC196D1815A7A60A8C9A94CF4354140CC5E3B98BFDEB9C95C7C87182B878BA20939A0280E2C453567215A15803C01F7F03BB0B90741DF964C4FA02F1007C466BA6B8F78BEC07956611420220499A013AD3E3A874C4AD961B02E4C27A9AE71D57377DBFFB556334797EC28C701C220129B856E747B90AAC0803B2CBC7B0BB428583B810EFE1727E0598CDE9681429616C7B3F8BD8B691841A7A5405AD288F77B652A49C38ECEB4088201B651A5C65BBC05E40A7A0F4151EB0962C34B10C1869A003CC4CF86D39036778B3CA32D0C500F7918CF027EF920B3718AB1C191618F294866B2FE77BAB8C84118CE55157714AD2D054102A4D38AB73D1F3967E98351631582545C5A60B3AAD50A7852C9D43B945668BB8B6781F56057EC058B2CFD6310506133E38B75FE3086D990D92CAB098F06CD376531BDB8308E5A4D2E323C87C36E7CCAAC87B00A7D4CFA3B3342D74A02D888D702CB44BC31201E41FE62C7511493C068A92717CC5513045BFA197D7F83DB35798354797CCA7891392AE9587245E92974920551D826101D44D9F73B3113746114AC94B8C8E291892BE9C8015A0114EE44E26879C02084B0192194B922284956A8FC2B26E9071847FB901FDB6603C3BF7BBF5297BEA11539FBE18868709FC57DC4D46D7D541594B53B4AEC0D9F86A6377C63FF80150E40FC5347714C07591DC71C6BEB8DAAAFC605F30457945F8B1560010C71B40717FEE3264A27EBAE2AC8ABC16267FB0F3AE", + "ek" : "3A0EA5059094E7376962226637B9E2A83624BDED0CD895F551E8B1FE96AD37D4B659D22A0C3983CEDEEDBB70E81B776786044403133594E5BD29EFAE5762B1CB4B37B0CBD8CA9615CC2876065CC394F50164848E9E6B55D58C5338CAF4BA08BB36E63997292284BF472541E23A606C726A0C00AC3BC9B819A2B7D4DBA61DC796100488F7DF241BE9989DEB055D91DC4718E6C91A8D763022266CBAB343E609B7BF3F6EBA7813A590198DE44CF0C2B15DA1B513BF4F38C18FEF6272A770EEDB49855A38F055CA085C90D6926C5341E9E7E3F2C15B9BB72218FF0EA181424879C07F97E4A52A77D0EE5D5012972676B5FDFAD83F6F8598E91920D23B7BC408BE366EF650B709B501114D2E0128DACFDBAA3851796D647491125A51B9AC35C91284ADAA9B70CA4B3C695FDF4892518D664F6B6DED497BD70517FAAF96192DFC2467919A90F7B7D4FB06636BF80E1637C2EC9CA2547FA967B4D70B30A393EE03C737DE10342EF88BB30B637BAF75E5BD1A2D74AC69E6DAB2911ED825775DF8A725313A32F49D323BD71B519C9FD0C92E3C36F8FABC3DA4346AC463A534182C766662679BA4590929541FB69D68FF1A326F223ADBA8F7C7DA38FBFC5B3641DEC42D34A81B198A7BCC42D7ED0158C0A9E7490B224D6B2B07C2B25F3DE8270E8E62D37AA092876E32851A6CD49D1D9127F2C9A632DCF58C004475A331FC5109FC922C9AC9116E17CBBA91ACEA894F97E57EF119B3C4F5B91CDF4961D3A847625978BEC8E98B0DF509FE7318F33FE970C74B20842058000007B545D3D6302279FE6EF68D7A6B2D55160E86587A551F7A627761103F63465EE926EC6CAB6CBF8F0710110747BCD16125C56C7E0A5A4D041619619D9D41C04698B720D8FDAB72F98962BC1C391FC4FF075316C781348298B04144262EBF3F20B01B16159D401E11D1D0E937630549ECE6370FB009F1F007D45C2C82E2CD68AE14D351ACC5752A8763CD5C8AC1EA1E839CCFF39B3991C174EAD63C5191F0C817DD50A517CE6887699A490BED276C851735B5AA83FA6ED8E784EC04C42862E6223553F02722F573404B3F4F05BEF5166DBB4528D49F0391B6CDEBE37A37BFFE7D2FF70DC497CCAC4C3A03BD3A3AC69A8B0CB38EC3441A0BD1E1A37E828E0FCCCB9CE107220A94C1170C68B9C5F2743FE6B8AFBA01FC7BA04D408EA2C197D87CECB128E958CA3A2BDEC7A3739DDFD58F9BABCC733FEACB50AD23D4CDACB76E9BD5521D6EAB6AB65ABD6CB3B16B40C6013AAEDC611DD3EC1910BBE5542FF8DFBAF3E266E7CE96D0D6F4D6AFBB7F97A2CFE478838E3110C6B23C645EA25647DBFEC37022479A128E17201087D2B607CDE58907AAF8C05942CD27A6E14D06F4D8CC4BAE2CAFBEC4A31A31C8A162DABFD1370DCCDF4CB53A264E94BF9CA6B4E91A83AAF9BC8212B9A72B5E48D1719AD4AF3D547071D724A1A7E1B4A0FE7F42E8C60C83410420E20A6999EBDC5DDB0D6E5114D9BB8A30D0F7354C4C873BC2A3C067466D582280D2CF7F4EA37287D473", + "k" : "981381612F375BBF07D737F326ED0EE585EFAA18D0A783F036D506DE425DCB91", +}, +{ + "rngSeed" : "BD26C0B9A33E3B9B4C5D7EA32D5BD1FC371015BE163C86F584E49BFD5362C8D8341161CD1308115B2A03B7E5EADDD418", + "pk" : "ED7C794EE05D9B58740D13CD78EA15867A5C3CB14051223EFCB36969430B45FB699C26CAA918C3D9041589A1BDE4484E95859A700C2510D6380C2A323E34526E22ADB44A862C417B34D172269B32430C6B8A68CC3DD2BEE2447555C82189E2562AA82DF2A40E33B91D65B60D0AD93B127294D71002DD16B35701670564B1C07436DC2A001C751765DC93DA79AFF6177E9795B00C5BCBF66175357174032A2A742B3587E35F055268551C57AF78090044BE4200302FB0B16A40B80E092A1933BF99878852342CC6574C6230A9460B08376C42C51A48ACA14D0E59294F3BCB464A74C0A296FB0182CEF42B25B58711C6CC939C9E02C8302E2499640737EA07540ED89B5335A05C552472172E8BDB2F40C49A5B0295CE99A0F567AF39169313C8B61BA77FD2143F97CC762C8B6BE4C13300A8B78DD06011C144A1D747E1C3825CC1674B825838953574E8B6A16B3DFA8A05355C8977006C649B58D9F0AC2D704F774817EEA95F6DA97AB5CA71C521A277D9618881563F47792D99BEBC73A74CEB5560070B75C3B8B2E2C9598195FEB08EBFB5CB1D86A87F93465355A796520D0C24744C7B852BAC418FD620D060118D135947D9B174CCA55444096ED97FD6442DDA02B4A3364732C6818C39A9D199B4CB5A4D3659C8C4851D39DB9301047370351C8DC417BC1B86FA50486E759B87C4CC69A8A9EC282909C40F0B7CA0896C01F7221639B18FC3145EAE4B4B8252B4AF720F1A22C1E5CB980CEA6B103082B31B0542EA8D64D8C9B119AEF3524CAD116689280A51CCC08C09A8C3313A82A581B55CAE6A394EFB5146AD9884344AB6904C7D5BCC75729A261239C76EBC83E2557F60D125A9578FE0B4AC8D57B08D729A8D86647708483407BA16344049F8B842496A64F84D5BF42540429ADE11B10F567EBA812AFF9179E263A2899B770F8B3166DA15BCE789DEE3CC7D1846F3204B26933D4803B74C3C3885748A417692F0F5AC2733804CD2A98F45547AF8CCD28542AB3062211A51F454B28559C28D0751C5C6C31045A8AA41C79CD1CCA536C3D6A779AFD9175A006B663620BCC92B4DDCC92B61B88BD422F1DC7962A70569DACBBFC7AC9CE90F8D16C3B6973AB3E96B6539A145128631C6993C776FCF488F4EE692772645DC2CC1541874C02ABA0564A46176005F6CCF2AB27893DC60D2D44CE1E5B6E317A38C032AD98BBBF79554EF2882FDB51115782AE862C9DC79A6A8293A39135460F96329548507D58C39A07AB9AA7FE913A7FBE4C466F693EE1006F6091346A4B75A2A506F6C787CAB948FB76F4398B2110781AE27644211476364ABE4CCC2F0AC6CC4E917DD391BD0B369BA862D5F396D8627285B0C5D9B3692EF8069EA601E6E493D841755CEA52194B32B5F787F15A6478DB7B6B41336000D2BDF3270F8F0AAADAB89325B6A3DDA4EA88021C8B61B6BA372186321F4F5575F2508625685DB168830063860965A71A27CE34A7E934B9444D411DA9A151B27B3ED738869100FF19099F0C2A8583B872C8A0745E455BF715B8F526CB4F378FDD931C8111D53A97379AB1D57684224780690B2C1B36BAB3B0762B8FB6AFCF39CDDA151607A6537B985C37989299414B4C9B1894C6051242482B42289AB24793E2D7AF2CA0CEDBC27D0595B94C698BFA000840BB2D63E1946", + "sk" : "ED1263888C6658D29766539E247CB2DED8BD4AEA61E1998C090C96C40C513CE38507B3C1C171131EF280496B0324907D31B2B1D1E53BA4E2B3795C6B756CB113BC64DBD0B4F47978C048892F3A5B64241C3BBBB9BC7C593A8865F4923097180352D9600636B8F639704CE868D0B5069FA99A395C30CDC4B4CE3807CAA07130CB5864610F7C5A6234930A8A519B3B6CCB63C7CB898565791B8A32C594FD826CD283CEC434930B0161E183065DD48CDB392F0404120DD86253906605284BD8D16970382C5288C598F3220504C4BF05189695C0F8055A08C062C4889DB96C1E960BB8EB9009F060CBD9818EEA119886FB84592093610371A09358F351704BE5B7BA18308021AFDAFA52AF2A4B42B7021459318B15AEA8D04D700766A00428D8D3AC383A3CFBD03E49A8BA99713C7191B61422769EF5594954A4D3F00A0359482DE59D0B9C18C787AAF8BAB676ACBC9CEA9CFCA41B43946B52B262DFA8302CE58F749260DCD65E81B7055B660D9341A67A352DE1084353252D15E02D2B8BCDDEDC11BDA1CC3AA46EE307A1FC29019182B9D817C1A3D922BCDBB2A8EB5FC2370B9D1A36CCF94A5AF3B52EF094CBFB63CA590E24E43AC2E983B7760A187714DAABB7A7D02F961C3452298B0E93614A8BAF42988721965B4A7B1EFC3B5B6E1968E927CE28E08BC12CBFB3D23EE095836AA5B2DC941FF1E0568942B8A6D6B997BA271C37B25D8B1147E6515FF788861B7E3B454D5E66B22CD059A34696B430890E8A9E0007CD62A1BB1BB0897AC835DC26ADE4528BDE16C8A00995FA9362C17981C794793B199EB348606F68862FB29C1FB154EC28314E65983343C3897499AFCAAE97752616C87076A00D54EB8BEE6B3BF5E5BE83BC3EEB874594147369775D02352936E51D801335E0A656CE9C12EFF64BA0941FA6A563274CA536C3BFE9C2662A39B4C3EB07482201C93C50C95B823788606E81791EF21B27BB4EECE135F1C961FC0095C0DC83B5226204104C7A919D5B3489E4F8144AB2C0045B72FFE77A509A6CBD8061DA15371C03A6D028CD88F13494E8699AEC9EC54291C2E16F787718B730C7CF436844D7BCE9302AAD448C01213C1D14844845601DBCB556CA85EECC54D426621D846D01E62796C011A231652904A8A9E7A73B5A87DEA3AFE747662BD696913CBFDBC1BC31893D89F4AF3ED249AD946B7C2A31C8F35A7B9C8FF01988A956634BB06329E176D2E6C38AA3C8AB27B9DEE0135962AA08A909CA8196E8E626F123BB3883B9D86C23883C9DC9910CB9E6805C5859A0E08A7AF64D610A332B30CF41871FE8DA13B503156F6C031EA4A5C33CB5EF9384C8047C58532CB7DA4C9275176536A5F4CA0CD6CCA9B399A938ECBF61EB3DCB1660B160698996B3FA21714715299927723F3609D11526336B6AD0C2CF91491927D07AA4E0C7234C9249803A3F43460AC19597B4C47C9C4E64DC174A8241A913AACEB8A431973D552416E3115301A969C351AC9B8C798D83CAD6C925B7D467B132071BB9AF4A3C2C6CF6358101A620F857F6C55A9FA077AE25455FF1249C562ADE011AC64B659D289616284259A2CFF5144558D1149671B350B18D0CC20F0E164D47A8382FD07D96232E39C0A6ED7C794EE05D9B58740D13CD78EA15867A5C3CB14051223EFCB36969430B45FB699C26CAA918C3D9041589A1BDE4484E95859A700C2510D6380C2A323E34526E22ADB44A862C417B34D172269B32430C6B8A68CC3DD2BEE2447555C82189E2562AA82DF2A40E33B91D65B60D0AD93B127294D71002DD16B35701670564B1C07436DC2A001C751765DC93DA79AFF6177E9795B00C5BCBF66175357174032A2A742B3587E35F055268551C57AF78090044BE4200302FB0B16A40B80E092A1933BF99878852342CC6574C6230A9460B08376C42C51A48ACA14D0E59294F3BCB464A74C0A296FB0182CEF42B25B58711C6CC939C9E02C8302E2499640737EA07540ED89B5335A05C552472172E8BDB2F40C49A5B0295CE99A0F567AF39169313C8B61BA77FD2143F97CC762C8B6BE4C13300A8B78DD06011C144A1D747E1C3825CC1674B825838953574E8B6A16B3DFA8A05355C8977006C649B58D9F0AC2D704F774817EEA95F6DA97AB5CA71C521A277D9618881563F47792D99BEBC73A74CEB5560070B75C3B8B2E2C9598195FEB08EBFB5CB1D86A87F93465355A796520D0C24744C7B852BAC418FD620D060118D135947D9B174CCA55444096ED97FD6442DDA02B4A3364732C6818C39A9D199B4CB5A4D3659C8C4851D39DB9301047370351C8DC417BC1B86FA50486E759B87C4CC69A8A9EC282909C40F0B7CA0896C01F7221639B18FC3145EAE4B4B8252B4AF720F1A22C1E5CB980CEA6B103082B31B0542EA8D64D8C9B119AEF3524CAD116689280A51CCC08C09A8C3313A82A581B55CAE6A394EFB5146AD9884344AB6904C7D5BCC75729A261239C76EBC83E2557F60D125A9578FE0B4AC8D57B08D729A8D86647708483407BA16344049F8B842496A64F84D5BF42540429ADE11B10F567EBA812AFF9179E263A2899B770F8B3166DA15BCE789DEE3CC7D1846F3204B26933D4803B74C3C3885748A417692F0F5AC2733804CD2A98F45547AF8CCD28542AB3062211A51F454B28559C28D0751C5C6C31045A8AA41C79CD1CCA536C3D6A779AFD9175A006B663620BCC92B4DDCC92B61B88BD422F1DC7962A70569DACBBFC7AC9CE90F8D16C3B6973AB3E96B6539A145128631C6993C776FCF488F4EE692772645DC2CC1541874C02ABA0564A46176005F6CCF2AB27893DC60D2D44CE1E5B6E317A38C032AD98BBBF79554EF2882FDB51115782AE862C9DC79A6A8293A39135460F96329548507D58C39A07AB9AA7FE913A7FBE4C466F693EE1006F6091346A4B75A2A506F6C787CAB948FB76F4398B2110781AE27644211476364ABE4CCC2F0AC6CC4E917DD391BD0B369BA862D5F396D8627285B0C5D9B3692EF8069EA601E6E493D841755CEA52194B32B5F787F15A6478DB7B6B41336000D2BDF3270F8F0AAADAB89325B6A3DDA4EA88021C8B61B6BA372186321F4F5575F2508625685DB168830063860965A71A27CE34A7E934B9444D411DA9A151B27B3ED738869100FF19099F0C2A8583B872C8A0745E455BF715B8F526CB4F378FDD931C8111D53A97379AB1D57684224780690B2C1B36BAB3B0762B8FB6AFCF39CDDA151607A6537B985C37989299414B4C9B1894C6051242482B42289AB24793E2D7AF2CA0CEDBC27D0595B94C698BFA000840BB2D63E1946C2D52D0C837EB40DAC0653A5E862D9FB8B832629CECE9EAEB6D5FEB48B6EF5DA0A8155459118346A84683DE346659727DA4B64A1050C5271E968BA9CFDF6029D", + "ek" : "14A40FC73F412E7D2867D2D69397E2FB51868CFFCDB66D03B06D199047C73BBBA1C4166C56BCABCA385A2A41911DCB074E1978B9637551ABD720BDDFF45E114FCC5041AE0C6BEB217B9B8B827F4278D6ED5A731E9F21F7D9C9BEF761FA9AAB31CE0E0868527359D1A09129397DB172A927BAF1C2D2E6FC8F2A7EF0C6953A84F432A7C2397495FF80BF571011F0F09800283CE49D4AE5B17BF85B48A38D4DD3454D236D7F2843EBBA2048E75D65527876EDC4ECEB4B81BD6F67DEE66F1DB7920AF2EA141401B1C2898FC0AF2DC773F24F8FE77CEA1A317190A9393DD81DC9472AB32B695BED3B973D39A31E4E5B9B8202009A4C15D66E52565FDD5AAFD8E0DC2D5CB61D1D8958F0409D932534803D8573CDD5AF2867674E301EB2CA077CA736CD62F5470381DBBBE28FAC09BC900006A4CB00BFC0544AAE4D8B47B7AA933FAD266F1F013732A3CCF0157CC6202CD5C485B9CD32B3150B97EE191A52A15D02970DB415EBE236FB51725199B05539E029E1C4B8B8D0EF21C538DFD5525022FB32ABEB857B39D44E061D2C3E67354D801A990456C1E0CF3E2DFB006E52FA43E0F20FD3B66E3CECC7B10A1B8BD496A6AE300D61057AF68751D52D760183682C8D86F5D26E389CA46BF14F23DAD0BBEA50FFA74580CC2C1C4EE172F4BA9C4B770ABBEC546B20887733E68B9936006C83A99E5BFEA5B3D8E700B7E76DDBD98754FB6C6395D2741F359ABF0536C8C71C5C858ED054BFCBA20AA6C4134F351EA8CDFF6DFB10734BEF4F2E99C91F1821330BB03D808995AE703DD3344816E975BCCA8736BE72AE53452916F548E012ABD3E44DF2F891830A2FC4802AE6E45234457BF6F7AF98065455CD3F02D508BFC2F645C734EDD42DF2C6E4D222F6E2CB9AD3294C7CB08FBE028DC6514FAAA9A8C0377E2DA05AD4DE842422FC34BD872C4170516E2AE219FBF36C48C9DD9292FD0E9529D3B7974553B4CB32505738D98EAC3732F8B9ABDE7145CD3D7C4D11E62996827DEBC21F139E7BCAD7EEBDACC70D3CD2E4494BAC436A19370E13123F0E43BFCD1F66B2D3BFBB450A1206072FA6A86E1695720936184DE4A95E39F044B642DFC04E8639363227476FDEEAA99236B3501F090C1B77DF3B5EF508320E286A9613FAA09C285F5CB27581C91040E15C70A6800018542AAEEA7CB378EF1BB0AC3CEED5ED1C7E2D1556168043C483FF9603F3B9722C8EC342BF8504A2FBD5C4CF2204F3C89EF306F818757375E3881124548A6973C54BEE69896738232FF95E3633AC302C89A17C6F3E83CE9A39B84364928B22BC06D7147E692E555F13847457D6C813A5876948D8757EBD9C0186EC1E1EAD54940358CD69033A2B767A7051FB20947B1283C60C3899785D86C22D57CD0DC342E92846169E08E11E67E5189CC5D271FF9D9082380B259E9C0F092E95900D4E0A029B2E2E70760854F9DC4E3C2710F863B4043699BC60333E0ED02BF2CAF432663F06BCCFC40E5D4E5AFB56771E66B8C59E7BADA693B786BA0D3A0429DAD4E3A28BA56F07", + "k" : "C046867CC483811179A765AC8373D73326B77F1C99C702732541C4EBE865D0F4", +}, +{ + "rngSeed" : "E2819EF86853BCA1B9DEE7EE1C1619988964F9A913E635AACF0D96CA6E0300D084329DABD8F149E24176D22757404260", + "pk" : "109BAB4BE52B48818412EB1353680F2A3C3BD9FA7E55CC79C38207FDABA1833452DCB03763672212953C53532E6051AB040208ACD348AF507616562D96C7C04DA93C8F21566DF563DEAB2F18C9359B0B5391E8B03B485E3DC1A7C981B2A30026B0F83B84C4505A5966F648383C9ABD16638A3E557AE4925FBF1C0125D91D97511175895082A78C1272792A50A5651239CB66B3F6C1376FE332260CC27ED5972C4B6ECEF6462D3B712627928CDA42CE150D3D96B7F032209CA92E9937517BF2B7C5F66E3B837EC347643A6A8A4D8C299DE167395C84C2AA8BF1A8A4D5DB29C2962701701EAD468368B40E87DA45DEE76FF4B287950889692A838BBA17B2B47C3140B7761CB389E447B2A540AE251D61808341DBB2B9AA5F04A69C6010431B28C17B980FD00499E274C9492840CC7A1E90215BE92759DB8B14EF41C059C546D4482343106ADB27A802C3C3F8759A8FA20141FA63C65081D40090EB1ABEBAC9C5708A9BA50656B4E7616151A4F1B0BD678AC18188450DDACE2B99B3F170AC2635A62AD88320D17A9A75CA2E1BB52576274EE12F1F3B0B1696A247C70A6CDA6264DC9E892CB08548C0C8824168F471E19078737169B4549B62B634A611AD53699A5550635FAA7CE4589938501834F8C4856CB2E991BAC84809B424CAFB5BA089F14338780178D71B1CB7B1ED12C036F727FC2A94E9A62ECAB6A95C8800AAA237CFB224AF5C8FCC939443176CA4BCA59CE54400DC7639E0630FA7CFC292604E6AB0BCDA993A78107D108783D19DDED13C2033297FF513FA75C4C6D65640206B43F33CAC26950533B4B053190CB23E45587509ACBCFC57ACFADB6160F5345A599CAED04EAA02937BD5A5620A5F24E6B194C52DA021233B13CF950C270F8262972031790BA4CDB4524BD92781898427B6A1ADC7A986F88DDF7B39BE1C7D9700C87D52AEA9140AEF5C6454328F666A8F476B772784C3B13494DAB57B06E320B2AA701ACACDCE41B8B3843E9913CCB3705DAB48CB9D85AB5B36BBFF148C5A4239B32190193112E1184D33B88ED1E6C3A9BA0CED62BB5E634B72187030BC8DFC1A3E80E28BFCD1828EC4A2E4888D68E4BAFA3BA8622A87314432801325FA66C142760272E594DE825560C7C19E881EF238BD9A38013F601885E02ACEC715B25730FB004009EBA9111C125BFB0D6B2C154945575743CD66D85906981B24C1B2029452879608A34BCE8E610501B6B12F32A1B3E99B76143CC1455485B3802778B7ED52210B976CD2BA26F1551C0FDA036FB33891AC77C9265C30DB5A513BACA1524B8499932D5633B127AB98D8C07CA1704FBC8404957251F11DBEB7000B363255F5AAE1261EA5B7C741445CC2852666C5437A4054F5D3A421799318098F5AAA5262B46187F60A09D98442499E30BC54C86838E256C24AE481B6BC33BF076B04BBC798F0615CCCBE8EB66DD3C97DA6A89394D4C7E07B8C4D5C70A01C9E7C43B8A37C3A09D728D9FC25D933028A504DCED76C2A3900CA67369CF5B822107A9DDB2A168419AC87B036064786F500E9E0A279294DF8A7C632484723BA28B38B52937B40E20984C46B23DD81BEDF629DA6A3512EC060FDE7B8B2DC987395AF460998230C20A9A08C1DFBF3824CF7A6FB4ED55ED1FF461D800B59A6FFD7287E1EE3FB94CB59C39450", + "sk" : "263BAE3C310CBD4B6423AC0195592363652D2C1B470A718073E18E08E412286A4DF32501E9926D27C43DE1135DF1281B65C6738AFB062D1A0823C01617DA701B97A11C26055972B875D29D42985737502ED0551C85F11E2E9B28157049248691D750A4759184AB00B02595460A91ACB77A6272D49273C35895AC796EB6406999B8D5B824617393FAC877749CA787456211FABFD8C1CE7775BA14C51BFB2CA962B6A3ACD7AD4084C90D000CEF83ABA7EC45910BBE37598422C8419585111055C99AF87E08D5656DC5678B488FA9C96D366B5E6C2A5C8D900F40BC69DB4A9FB9021723E043D42B089C68831A0525C14C8E9B192B14B83962B7662202CC753AAEE4D18E23846E4EC1CDD9434A77A47A69596D8B5B019C60568A63734384B83A9406F461B9F940A9E0D3ADD5D21EF67C8D8F8C83259952C3CC86C35403FD713EF26A9CD239381AD4370414506EDAA2DA027B2821AC9A8C4E5A661F06038FF4B209ACB4A71B916386A928A57183F9A5515B704AEEC9654B7C17798C57C07911A038BB9B7715C0EA69CB3C9BAF14A0BF881E6CA1905BD405E876234102C572DB0B7C705EFC93A49D82303DE400003897C3F9196C758701A5946C947B32709268A9A265841408F038E280A9B441366F983316CB5FC5109C29B2320B156794EC3233A523BCC5B1E0EC6F0158C4346AC04078C244375AE8C8AB9B57296450AA75D8231AE3CBEB21A17F29C8D8FC628FF315BDA563961A2014338D294743269C4876689EB938141D31001F932440B0A0AA079B6F3C82553C5350827A4A768C1FDB5E75253423D95043989CFEABA0EC544DA71AC75A62A3D4D5600914972198CC95BCB1E4D04C1F4621ACE5C02B1B0536B0350FC09B23EC125AF05E92CC08362B6E1C1142484B736FCC46F4233EE2C52C2F810BA3148D74681FD5B158068CAE9D701819A16917C81CF3F5A31AD1873930B59294C32D915791510EF0D8C8AC8A6CB4673493AA6BDA6A6244810BEBC286CC8020CB86CDA351CAF9E801D9589CF29B9CAD0025CE563B1AEBAC4362B176C8A6C4349FF62124C53902B2C10636C88D612133E872759631B31D4CA637BB1670377EC7B97444DAAEBCA78664188885C134FB04205A266895B7909E3271E141AD62090D5696A0221415E5A711A7AC0A9512A1C528767BB617BB79B9AA55B47CC2ACB573AFF4B4B5442BC573A8B9E937AD1205A4E6311834899CAF3824ECA782530186209C25D7E810C8F6C5B4559F436C7365642D28933A3A1234415B9728C061365C74B73CCD3E36222DB3747C289D13942A32CA6FB1D7A75D563097E91399A2B967C3737962CD1FA0629F2B774D25A2021B458524B3C2F8344EBBBD2B7A70F7AB1574158E89117F3F8962ABA45BB0CBC297EC3C2CC546096078894308310241B8ECCE3FB787219C9E0B7443D622330877BF8C4C9637C6B9AEDB75CB763356EB7772BA5664791D4F439E6A317B1066452D698DBD235FDB4BA5C37BA57EA8BE97849345F7B3E8D56485329933B9B49F92A1A67B67C15C72A3B0CF05F36BFB2567F70BA9139CB6729212BB6B48B71590513BAE6489B47C03220A72AF6094045293CA3623842DE85677C16AA910B9DE06924DD3986DF541109BAB4BE52B48818412EB1353680F2A3C3BD9FA7E55CC79C38207FDABA1833452DCB03763672212953C53532E6051AB040208ACD348AF507616562D96C7C04DA93C8F21566DF563DEAB2F18C9359B0B5391E8B03B485E3DC1A7C981B2A30026B0F83B84C4505A5966F648383C9ABD16638A3E557AE4925FBF1C0125D91D97511175895082A78C1272792A50A5651239CB66B3F6C1376FE332260CC27ED5972C4B6ECEF6462D3B712627928CDA42CE150D3D96B7F032209CA92E9937517BF2B7C5F66E3B837EC347643A6A8A4D8C299DE167395C84C2AA8BF1A8A4D5DB29C2962701701EAD468368B40E87DA45DEE76FF4B287950889692A838BBA17B2B47C3140B7761CB389E447B2A540AE251D61808341DBB2B9AA5F04A69C6010431B28C17B980FD00499E274C9492840CC7A1E90215BE92759DB8B14EF41C059C546D4482343106ADB27A802C3C3F8759A8FA20141FA63C65081D40090EB1ABEBAC9C5708A9BA50656B4E7616151A4F1B0BD678AC18188450DDACE2B99B3F170AC2635A62AD88320D17A9A75CA2E1BB52576274EE12F1F3B0B1696A247C70A6CDA6264DC9E892CB08548C0C8824168F471E19078737169B4549B62B634A611AD53699A5550635FAA7CE4589938501834F8C4856CB2E991BAC84809B424CAFB5BA089F14338780178D71B1CB7B1ED12C036F727FC2A94E9A62ECAB6A95C8800AAA237CFB224AF5C8FCC939443176CA4BCA59CE54400DC7639E0630FA7CFC292604E6AB0BCDA993A78107D108783D19DDED13C2033297FF513FA75C4C6D65640206B43F33CAC26950533B4B053190CB23E45587509ACBCFC57ACFADB6160F5345A599CAED04EAA02937BD5A5620A5F24E6B194C52DA021233B13CF950C270F8262972031790BA4CDB4524BD92781898427B6A1ADC7A986F88DDF7B39BE1C7D9700C87D52AEA9140AEF5C6454328F666A8F476B772784C3B13494DAB57B06E320B2AA701ACACDCE41B8B3843E9913CCB3705DAB48CB9D85AB5B36BBFF148C5A4239B32190193112E1184D33B88ED1E6C3A9BA0CED62BB5E634B72187030BC8DFC1A3E80E28BFCD1828EC4A2E4888D68E4BAFA3BA8622A87314432801325FA66C142760272E594DE825560C7C19E881EF238BD9A38013F601885E02ACEC715B25730FB004009EBA9111C125BFB0D6B2C154945575743CD66D85906981B24C1B2029452879608A34BCE8E610501B6B12F32A1B3E99B76143CC1455485B3802778B7ED52210B976CD2BA26F1551C0FDA036FB33891AC77C9265C30DB5A513BACA1524B8499932D5633B127AB98D8C07CA1704FBC8404957251F11DBEB7000B363255F5AAE1261EA5B7C741445CC2852666C5437A4054F5D3A421799318098F5AAA5262B46187F60A09D98442499E30BC54C86838E256C24AE481B6BC33BF076B04BBC798F0615CCCBE8EB66DD3C97DA6A89394D4C7E07B8C4D5C70A01C9E7C43B8A37C3A09D728D9FC25D933028A504DCED76C2A3900CA67369CF5B822107A9DDB2A168419AC87B036064786F500E9E0A279294DF8A7C632484723BA28B38B52937B40E20984C46B23DD81BEDF629DA6A3512EC060FDE7B8B2DC987395AF460998230C20A9A08C1DFBF3824CF7A6FB4ED55ED1FF461D800B59A6FFD7287E1EE3FB94CB59C394504FF02338C9BB711D263140C471409F3C42813F38424698563D9550F85A168F2D08AD5BF30D584AE9C8425AB3C8F1FB9960752721CB2C8310CD7BAC84808BB979", + "ek" : "1B5B224B9FF40526F09AF0B9759FFD2C8278B7529FA4F32D7128ED32327A98D3C2C2840F8945C4BDD4ADAE94618B4A701DAB37C64993A6926D74E305B5A44C6ACD9523C28AFAAF402E4ACD2F341143DB1783BEA42C7EBBE0DBC1CDA433A10C05ED5F9C54234768CC1119BC0F7E36B687D6D426BA1B7455A7D9DC23B1CB0B85960908F17EDE953D5213E365B70DE2963CA8B99D2E99CE96D4AC6D4143FE18542112E1CD4C9351784D5F535A3AA327527DEEFF0CA18536139049C88DD226CAB282D0D461FDE46DD51001E4AD165770AAD05A3DDC04E8FA4C363472F5D2D91E6BCCDDB5DB5434722C63756324F7DECC303B783778C5732B62A72E7072CF30779C4DE03F70BF854E9CC0BFA7EE2866949C17CEE19A7A1130DE4B4959B29508C649F7E53E00BEC29AF0D29990D2163D3765B4FA891FBBA56B36A2482D8F3B034F6603BBE0B1CE457397423CD7B126A964DD7B0CAD81FBC43196C4533011B7F0BADA8636C00E95C3EB199FF099127ACE98B2E743054E109C22E013ED0A200D13DD1DB603360C50CAF88FEDD993D84471A1674E1FB2077BF294F80818EDA8DE3C2BAEEA8993979F918F663B98550AF7FF983FC86E1FA6A2FA7C1CED5406530D77FEC3C23721E6B8637725B6FBF136F5E411C73B436AC613AE61CBAED9F9BB908F93D18FB8EA9996D51272267806B197F512126EEAFE23EF8FF4B7D655F68C8F1CC2047DE85DB4AECB5F06E13130D3A267A8E8B2401F72001D144860E8F0356142209645FAFE1E347735A5642C3819C03AA9DE9D80F9601BB77BA69C59D60B5246C447E3D357696956E219523E4E477346605D9D03C2C931C1F1384283DCEF065AF6F0ECA3804AFE01C2736A01EB72C0DFDC21981C4121CE02848E274F8F72548370AD744F12F2093C1CF03D2E12FFC88AF99E768B8041638174070E8D99B9EB3F883938B27EAF90BC061DCD803196417F58921B9C62D0E719904353C5F594F9B3012D877B26690C5E0D059BF5C3ACD557DEE8D29C4835C1E809FC1C9ABFC6AABE5C476D88D185751A638F6A45295DBBC10DE57A8BF1BD2100B7B0CB27E8CF5B314C8C58BA0C3FCED2FF6FB14E0F5CD2D59BDE24F677B1D49645BBD4693681CC0B64752445D3EF10A49D5F6501EA22476EEA6E1326939C9C4746271B35FD1586B726A593FEC4CB270C47CAC2F64929CBC05068016BA732F64B1E92869F7BE30CFB4B5A03039BC9226E9F0C534D433D53CD0894180C2349EF53F3E132D3A66AC6C5218941AADB91D51E974736915F09C0A67633AF1322558E246BBEA7D2A448B0A0517A8FF4BFB79A548968E4E850E09DFBC1CED133762F9708D42B8B793096E6E954D39020190746BC397F734035F311C7BD3F19F757CA577DB7E91647B20415ADA304D805E419E807CC69DE61D9375F5B1E9F1CEE9D283ABE55C151F07C29F19B69C8193A17C1E9A04BA3872DD5747A8D380C85BEBD1944BB023ADD48DFC71A924FE949B6FA1C0AB294865A6EEF41F24CA229FECD5B01FD2BCF75F05DA598E2B44D5E9D", + "k" : "6B7B7AB8C6DDA1F1B2DF2E096A4F6205241BB13F9B369A5DC43A1C265E63C1F3", +}, +{ + "rngSeed" : "669C4EF8A051CE201DA65FC4BC34D398EC1F806276FC5D987AD71D93BC12DC8F107B58BE6E8422A0795C88CB9A0E7488", + "pk" : "034626F03687751B2F1ABAC22B4C2B1AC19567F3324FCA5D82B147AF141A004514D831039A612ED69B621FFB4223109171E6351BB35177B85BB5063161273ABF861988A1803E647820BB53B282BC6D04CD3E075A4A1B6755B97251901A81C7911437C528951D007D9ED82368D4C833ECF2AA1A806CBAD08259470461F7774A922227E812689BCB59A3483C8346D130650E06383556C067F94D41DC1171941EFCC96E3FD769623861BEC9BBCCA4A5ED22C10A36A59EFB5D7153859DF348EF9C3A2745CEA329A73CB831441762820C7D996B88C1D453C775A16AB2C752E68BC55839D2E79544B87AF56019F02B794B166F6DD60E8EFB0B14F00D1AE800E37BBE5FF7C7D47A257ADCCD2949CDC3D9318A0CBAA34A14E080B968533AB1D9AB674C89774187D592B4C86461E84AC0E6808C96090ABE6B0CF69A2056A1C4287B1CF3DAB74F8CA66AE8421FA200FBAA4B11760AC7529B92DB75231958E20A3F55B8A3396A10FE957361A9BF41941B90583D8D97CADE8828B8A3A5EBC36730C19FA7346AA427C489F56C7CF3716928C9082B36D3F3B82FF1348EABA325BA8C49ACB2673570DC5548229BA93A5C210B586ECE088D6679C975B60E0106C0003625E42C1BAFC1AC1BE1C1779556A95AC68776CA01363961132FF75C2185339D79A426E6C0A0011A260ACB7CC0583E71623B251CB8EC1049DA730C2F9A26A61075AAC24AB1DA2732F708221A01B27C9DA1B520BEB7686843360A11A292568993C28BAFC7088C1767B87523E9450873F9C73912CAE517CA29C066631137FAA16D217CCC07F840E1013440DA2DDAEC6B7161B29742A2C941C7573BB0B57A58A25B00DB5012A3362774FB35CD80C6F0A095753688B156B510561CA47B436CD5576EE0323F2BB2967022FE391B9CAB3F41477787A96EC6667337FA4EA29B44B7C9610AB69706E820557AC7C9F9C55AB4A04FCB05ECC4157B943BBAFC0B0E42567F95B8B436838D363DA680A42EE01CD5353DD4276B4DC625D492AEC385BFEBE9767A2731FA8B3CE9271CD8D28042B66714D98D0BC0675A54B3EA3C322830A5616816C43260F6F21947E3499DFC4F9D76A7977CB467899B455A12D8628E93ACBFED99CD8B813D21A15024DA9EF46B1AE4F6333DC8933B52A5F100BDBDF2B23987270D550493D949E83A269AB42027B34A12A177F185AF5F76AC9F9B1CF9EA4EFF5529E0247D3ABC3CA08B3A1D081A8C75A1FFE4337711759D25B9CC673B0263177EA93B56667C15F82B483702973C6436D40953AAC60929A36A911AD25AC109A10841FB95E1EC05962C5694CC3CD7372260EA4863109254C26A44F62AF0957960634354F62C624C5723416F14966417681FEC883AE47544B753340F749B487A095F89784F15A6E7945DA56C9E0D2C358162213403609A1C938C98C68B70A0FADC5AA746AE4EA9868F19B9EBC3282FF592960B436A7A7301E4C7FA075FF50762B866C4A9F157AD25291347A9DBA5CAD62C35B28A3933F5269F33A0E6D403E5721A0D36BAE734481C43918F9B13ACEA8F6A13B1BB584938284C10E3806ED935D8E543FD5BBBAB0685F099C2ADF254F4906D6E05590DFB1544A32FF3BB766109561FF31C164792B6B0991FA93C14A74086A585353C3E620D3EC5B1DA6FF7959016B53093137C512DFC18", + "sk" : "4FD2BE0FF2BA62BA7DDEC6A73C032E9A15CD9DB841B4791620989C38508BD6733C15C206C84402E286BA0F2B274B94AD18A5CA003D7689AAB71EF8CBCE7B75CE844622FC9F57B974F8991A89032206F59023002C938C6D66622A7033442C190134D06F04339FA61390CEAAC12DEC5D0E5275456873107A8CC1EA6D5E5450AAB97B23A06E34C8A812CC29794897A20BBFE7790C3404C25DEA2FEA4C80F102AD1E750780DC79010811FE680BB1C8000EBC930FF8257F912140DB9E0A9C5C7410388384591F500BF0AABC4258272DEB2871BCBB85757E9AFB2699F45142EBB80BA8CE2FD095CCCC1952579A8A67BB57F78E2FEB4E484A96854A8D4D16BEA8C08D04F91F31779E0DF23222F5768775C026148CB1895B970CAB860BAC34AA6612E8A5B93C5AEFC78E408A0312FC027F7A509D6C12B55453E9CB2F4E5C4360A4AB1E350F8122A008F69CF2796F6B72A58E388921863AB2FB82AE627C60593A99A4BA7806572DCA7179476B16D5AA6ADC6CCC90AD700CB1304C2B299C1AAF09369CC2CE8A9C31CB799185C24AD16967FB1269D0DBA48EB0A258D4C37F9484C9CC8D214232F88B919DE59FFAF6C00029058EFC1E4FE55A8457B16D3C49017C88909C0EEF37973A6B2E55D19B8114B074D8C95A57C5D897C87F024B3BD8578C7921536B1B45C19484E220ED87BC647C57AAD958E01C74A433074A660DE8824060108B1C44CC45486F0AD2C00FB79A7D88A2EFF62887A3171D132E441CBADDF2BC1622045562A893300502779C3CF072DDF61187D42DA0ACC451E6B56BBA37B3DA8F1B105483955C7B169F89DB86E7FB04A493B69567BC5A8B8655C919F8A70D6EE1034C1478EFFAB227622029F5997B14696F4BC4415B6771D3701B461E76D686C93699C96165B00A593D69827BB39A256A1385D8B77B2222A5C920A6864BA5F413800C95F2EA9C303A064A173C764437EAF13444EC34192911400506158A0AB1C56399C012C30A7290CC0B0D330BAD27B8C0C80B7DAB5ED21C38459A436B5A5B2B0822726815180395DBE69A472672FCFA17CC331EC910096480AFFC8C667BCC7A2CA92E6FF80B1735A5959810DD3A5FE9938836D1B50D772A11C1B126FA498009B730139C3A1C9A22D12A55F1755F81AB7442399C8BB509775A24B3987E4432FB3A4A22FC7DA509578C34302AE845B818894C7A6283D71D42657544B558F74B7977D270BE722B9A51BBBDC236DEB8898C65A92457B260D3816F57030F510E4F885450DA20977451B2A731DED6287FCBA24B4C7F09E4A7532965774C0578EABC13D1B123542C1D1B6A710BB3B55038A28155528CAF974769557318C617306F72ACAD23C7C475B9A568C70E7552B65917217677FE625B15548BE7465B147C60F857A832D08CA770C83CA3B201EC1E8CA1BA25630997A69EE54921E7BA611EA1C0928C0C99D65D0C0A39F2E18F8FF9980044477899411410A48AC2C6C2893E83C19F7F1080EDD9058270374F0AAD2F794655F594B3CC15BBEC6DB0D647E45805318534C4DA9484EA4D55464DA7231BDFD31E9BB6C53E35A6F0764ED3443823F9991CA3AFF1CAA50EDB522C42112ADA999DCA8A8E678EA1A8417D77920F723061C87CB29A55034626F03687751B2F1ABAC22B4C2B1AC19567F3324FCA5D82B147AF141A004514D831039A612ED69B621FFB4223109171E6351BB35177B85BB5063161273ABF861988A1803E647820BB53B282BC6D04CD3E075A4A1B6755B97251901A81C7911437C528951D007D9ED82368D4C833ECF2AA1A806CBAD08259470461F7774A922227E812689BCB59A3483C8346D130650E06383556C067F94D41DC1171941EFCC96E3FD769623861BEC9BBCCA4A5ED22C10A36A59EFB5D7153859DF348EF9C3A2745CEA329A73CB831441762820C7D996B88C1D453C775A16AB2C752E68BC55839D2E79544B87AF56019F02B794B166F6DD60E8EFB0B14F00D1AE800E37BBE5FF7C7D47A257ADCCD2949CDC3D9318A0CBAA34A14E080B968533AB1D9AB674C89774187D592B4C86461E84AC0E6808C96090ABE6B0CF69A2056A1C4287B1CF3DAB74F8CA66AE8421FA200FBAA4B11760AC7529B92DB75231958E20A3F55B8A3396A10FE957361A9BF41941B90583D8D97CADE8828B8A3A5EBC36730C19FA7346AA427C489F56C7CF3716928C9082B36D3F3B82FF1348EABA325BA8C49ACB2673570DC5548229BA93A5C210B586ECE088D6679C975B60E0106C0003625E42C1BAFC1AC1BE1C1779556A95AC68776CA01363961132FF75C2185339D79A426E6C0A0011A260ACB7CC0583E71623B251CB8EC1049DA730C2F9A26A61075AAC24AB1DA2732F708221A01B27C9DA1B520BEB7686843360A11A292568993C28BAFC7088C1767B87523E9450873F9C73912CAE517CA29C066631137FAA16D217CCC07F840E1013440DA2DDAEC6B7161B29742A2C941C7573BB0B57A58A25B00DB5012A3362774FB35CD80C6F0A095753688B156B510561CA47B436CD5576EE0323F2BB2967022FE391B9CAB3F41477787A96EC6667337FA4EA29B44B7C9610AB69706E820557AC7C9F9C55AB4A04FCB05ECC4157B943BBAFC0B0E42567F95B8B436838D363DA680A42EE01CD5353DD4276B4DC625D492AEC385BFEBE9767A2731FA8B3CE9271CD8D28042B66714D98D0BC0675A54B3EA3C322830A5616816C43260F6F21947E3499DFC4F9D76A7977CB467899B455A12D8628E93ACBFED99CD8B813D21A15024DA9EF46B1AE4F6333DC8933B52A5F100BDBDF2B23987270D550493D949E83A269AB42027B34A12A177F185AF5F76AC9F9B1CF9EA4EFF5529E0247D3ABC3CA08B3A1D081A8C75A1FFE4337711759D25B9CC673B0263177EA93B56667C15F82B483702973C6436D40953AAC60929A36A911AD25AC109A10841FB95E1EC05962C5694CC3CD7372260EA4863109254C26A44F62AF0957960634354F62C624C5723416F14966417681FEC883AE47544B753340F749B487A095F89784F15A6E7945DA56C9E0D2C358162213403609A1C938C98C68B70A0FADC5AA746AE4EA9868F19B9EBC3282FF592960B436A7A7301E4C7FA075FF50762B866C4A9F157AD25291347A9DBA5CAD62C35B28A3933F5269F33A0E6D403E5721A0D36BAE734481C43918F9B13ACEA8F6A13B1BB584938284C10E3806ED935D8E543FD5BBBAB0685F099C2ADF254F4906D6E05590DFB1544A32FF3BB766109561FF31C164792B6B0991FA93C14A74086A585353C3E620D3EC5B1DA6FF7959016B53093137C512DFC18BBCCDBCE67CF49FEA044DF5C767996681DD2714937D31C822F3C58CC34785AA748B1985FD7938595DAC8AB776701CA1E9FEF47350DFC45355FF1E83A08BFC3A9", + "ek" : "83DD64079DDC0CBAB5376F1F823F9BA6FA59932EAD936DAEFF1C19BF9901CAA675E9B84DA8547ABBB6FFB008100DD7182047B90E194ED4B80910DDCF6871F74971B2DF6A1834EFDFE1FAD10A97FB6B3C02D1411B5EDDB5E27CE66E2C168F092D03764E74B849F3BBEADA5B7BDA4826D6420F0DA79DC7D7918496D25D8BA9868C5AAE6AA5DBCC4588E11FB6D0037BDE0E92BAF34C309F3C5770B5B8005D653E8237B1B7DE1BC52D45DEC924C15CCF83BDB0448814483705972D11A77E972B121AC42042A396099EF0399ECCF7119837BD9C6ACE208B24C77A8BE23ABB3BCDE93A96C6519AD5B59FAB5F9FDB7DB399A3F3DD743AB4A70A9CBBAB0A9D5073952A436B6FF3CD89E8F5AA7FB9420F161B02EC8BD88CF590135B9639BF6EE75AA2612052720089CB39E2993CACD8A69BFADFDE1D1848B47351CC15EE8F68733C292F652DBF81E7534AA21E5B9DBF6ADBB4B759F97A7E09FEA5C64DD03F9CAC6F4A7BC7AB9D09759839DC7206757F2992EDEABAC6642E31829AC297F60E126FEC5CBD4870F99825A977A2BDC62D64D0A452FFAA46F6FC479B9D9125A75727E0F7645D5719D50244FF117CFA73E5584ACF5632DE4A6E3D8F1CF88906A3D9123E8FCB8694DE9847F50B645E136E0BD4D9CF099F2DFBEB95E4E28F17191743E487DA0B6AFF053393A01D23DAB8FD0F8EF46B664F79AFBE7FD7631B1D736E8599409B5CC3C10FFEAE786E5E5CC63B40C5B0FA5CE9814C7B5C625038A15714AD507044C319B005318D6AD8E15C847958C45F15E92026357D8F012064F7D94DDEF0BA519BBB2C02B3F1404CAAF5E184F05659ACA0FE88706D3387B5AF803B97128609DED773C61A229DF8C43679EB00C537F0DADF1B86446D947EF7BA3AA7823691B882A395BC1637E0A7E15B3FF4CE82DFCA568049ECDFE61D3730E3CD57EB54434305A7BE93B0B4C7F3C2AC4CD01D8EE2B5403929631239CC5ECF5F6D66BF8728857C5EAB21E8FC67FDB4FD9B4A147490DE7AA04B0FC1AA052CCB82B9616EAF49B1CFE79B430A5D5235DDB59C49253EE57D5CA25CDCA0E102084B1862C41F96BBD7CEF5F3824556D477CA7D351DD67075164756AADFD39685DEA07DB3E94B95BE1A231EA85579D9D71A35A977DDAA7D9044F94F3AAB4B4399069009F0E3DEE371C00D6A03CD5110AE89F7637FE172FE8AC3A0BAC20421929DC566E0512355FDDCC63F876B6DAA5E0D7AB308B4595FEEEB62D018437E5053AE7BF79BC972B2DB522E174EFDA72B73E5CD5C88BDAB13144D75D8C62B0FBBE7E28EEBE172B63C9B5256131BA78130D951F73462973C692C181C5A6A5FF3A3B723E7DC57C0895B819AB8EDB7446FA60121D2887E10F1A00F82909D1494877FC41BA757C941322E5721BD8E2A0FAE6090F795C437D2298A7565176DA1ECC18CCB331034C2543D43A01766805E12466F4800971687A4139C892FA44A55F179A02797AB5E6C1150EF4F9BBD91F0B5FDD2399019261E5425C51B1689A28A924CEBA393C948CAB08AA1D3466334BF8DA5", + "k" : "C1138A812E1B95DFCBE1021A1EDCF12880765738B8C82D5F86CA93CBA78B50AD", +}, +{ + "rngSeed" : "9DEBCCFE818F6B5204DB4EA09C03EC9A19DCF1629C1527685B8A29776BB1DAAEC45F8ABF8F0ADC9A8C8BD6E2DF6D8048", + "pk" : "CD187009317A52773C57D435FAF794021BBC709B8E7D688A5DFC686C15931221A9016C3BB461A487982DED37041AD0C1D032714F7379E2FB9FAF5AA6D0F5469C7156800BA258FC5B25D0996B6735665A806A74B03D9819A5832A6685157E7285DF397E23B13A543A983A5B24264C971A73708DE1572852465732C94830719C197C7985C0A7C53525A1AE76D18E1E9112EB4B57C1222320A8156643CBC9535A27658A3709123CD61AF7798ADDD888053BB0DE254EFF530296F9AE75B2CA756539B61C62DECB0E9AE611678B5190503344229096C34990A61CE8B10ED3841D48D266CDC249ACC96B7D88010899C453467213D8BD23E1764E0237480C34D8396EF57C1AAF781C042471D04077EFF85338AB8CAEF22ED064BC38164070A00CC78B8074E7569A627B49E0416A705386601D3B8A6C10A4ADCBB190B4877422304FFC776B4A129D4098C603896A6020725986CFCF0083FFFA66EABAB82DB734F5D1B5766104E8A2B8B859B6CD166DEC691AE331B87E794A1C9B083C14B50B85B7E97148745C9F8975733D4262E247473CE53B85D01C6DE505A352BFC0C233A396C87F856981C83FB74542C9F3CEE1276F3096486EF23359C51AC553931B80C6BD245B2114C4A2D344AB53765C02C82B41412AFA1AD5BA6CCEE9BF09E375EDDC0CD55BB6C727BE26BBBC4E7392293C59455084B1542C87578C63511AE3E384E027BC07CA7401CB0096D1205F4CA86D3C73EE8273DE930799369133F83F4667A92E72BEE2655B17120DEE233433F9C68A50C57FDC8617AC1D03F0961D4A7BD17678D8729329A0BA0591CA84670557E15FC5EB4E8255007B8C4E48206F62062E1DD53BFC43AF02405D2E300D4858B1B9C9CEB531A910C0BDE877450A9AAA8878A2FA45089E184D1FEC1CF4E3909670BC11E78DA5D8CFEB86A4C087A1B73A6099C99836B3CC76366D35A9854B3B205F4B2B69666878614117163FEFDC32B6DB37FDEAB0A0197F79DB088C3A355877CDB1313A2F200E27E37E12B4BFBA04691F82B1C2E8B8172C11E466CD8D01286F2A3A4FE5A5F920476A9278B9D25E420B77D489386F9C167F2731654B19FE4886867B79EE10C18F679FAE87826A0B65B44A83DA5A35E0723BDA3467541228B80B35D5AB869B52B5DBA9B8B309360FF1022D67BC93747C392469C28B288CB73FCA74001E5BB47D5B0321E08FBF832D0A9B0DBDF566D3898E1F9ABA7E3C011A14C3E918589282C0F167BF14470D1F6C774E6742E40A1452C70CAFB941624C02AD201E6030BF3DC6A039E6465D6772D1C184C693BD16C3367F02730ED6BEB95940FF783CF9E307F38A7F4F37754F6C4ED26A1C70C90741AC89E56C989B0260F7E1178B5B975D54AA6F420E97A7B90C3C74200359D561BEAE98B1AF044BE40A2AD8491F42662E2F34BDE200C63CA48E7409727C8B2185138AE7859CE43558349A1F3E641DF0C14428C0C12D0A49ABB904CDF8AE5CF34D379024ED528E5D84A3D25920B7A94B61A8ABF9E557FF61C784501FC9E332F2B652F16A0A11148B8E594D1F377035E124D637659D4485D909543818814FE7A8A173BC8AAB7066D2C927C90660DC8D30364D60A31F1D94A9E5F586CD84C167E2577D3326E41A614382F4982426E93391380C4B03DB38D0F7BF0FF66D2D93C251D3347C64", + "sk" : "999942A0AB8086204428A2098A205A297265EF3B725DE17CE121512FBA2225B20C2FD0147CD903DBF08722201C4575784A5370556715F8EC09EABA14B38863C5402B9100407B35375098A55F568FF0B4324B43098DEBB5085558FDA00084584BBFE68D94280636809F8D408256913D32152710A132380243C74455B7F11532D3B88145CBD61745AA7683BD204C4E035D526A488465170FA86A099323FCE43B78B4A3B959A1B1EC25D4593181DC22BA883A9F080316C23D07D1490DAA68C8FA2F43533635439B5BAB445A6C1DF2A2C22AA84355556C80A9877AC9453469B02D998476D0CEDDDB9F3D05C7C6F99253AB62109376DD9B384B26786872030D95C23B3CB38238066978B55F2746124A98D90BCAF1C958E08B108F6714FE7658F6E0A67CB875522090856761D47189BDECB13C7746AAE24C12294DB2662A65D9241B513CF244223EC0AC4BE18935C788E04421DA1071611A3349843B7C760CE3568413756B7D838C3F3827E167B1DB27BF0546606BA6BB7FF11A2E7B86186946CD00D0FA143122729EFA29ADEF75C499F2C719E985E6014B110373AD2164EF7A85E78B7FE1DC25ED60027DE464F3C133338404BCD89F2680C639D956BE5A8CDC6254E670B5400139E0C136A132763F6C6664A6B9283B03EF18C809D94347187D91F97BEBD0BDE9134BF0414D219895CBBA75C9B262E6E62AD70926816BC02818C71D542AD6E3BC2E58796D7A90A4AC200C1B135940B4D0346366763C2672AC70C03B56A62AFE49A1EF043FE9657391B7274B6BA05E3184FDA8125B412C46F986212BA2948B6DB9130F54FC33F9574F7A82AEB209B6441886ED83816C173EC9826F8FB6C8E36237D6B32376344CF01311346B19EB502A6CC61811D6728AC3288FA5C576380EE2286839E4A8A01761FDE8A2FB49A3DAB98BCBFA9633A2BFEB116072C479DDD28891305BCA71AE8622CC89DC4733846CFA56CD2ECB4D60623B92797BF8D8B2DBD2B74804C7CEA19F40B67394C46B46906A44A5B669D95D4514A95F6327465BAECB8A439114070884338485468B36B103C4AF5CE9C1C9A09FEB2A2F9B7324E703B23DC63192422E5B2C38228C36A3CCCF39777D2015496972C6C618A296908CF6EB54169A479D5221679A7829E27C92C5550A4156D5631450753BEB34CD4BA8CA8949A7390A4A2E4ABCE4BA418525620B7C9064D82F8D080A68F058D847BF69833CFE025F0E090E185234B6F6A260C7391C97B57222606BD0B488D37AD71774636C9E1EA8A449958C1B944E76F48FC8401DEDA708BC039A81C497C2E028B52A714B40679563263305BB432B3E120BBC561B121A2026569951986C94000235E96A2FBB70ACB7A50A79C06947C02DB12609208C101BAB9E63D449C1C0A0FAA336D7B0C1BA9C84B6518863267EE61624669938CBE07EEC601AD3649675CA12CC307724DB6ED5A60766F423C47100B75C41DEB4BB78BCB19D4C486C098279D53CE0E6295086BA75525E22D3551450CFABC72C781008CFC5830D6C603311ABBD81934E874B1C4A55E4884CBFF57DC4BA0549724C7603258ED6B63456AF9BFA0BDCB3CA86B09EC25AAF41911400E8BBE409604BA8919CC59B8916C8C8745C2E8042CD187009317A52773C57D435FAF794021BBC709B8E7D688A5DFC686C15931221A9016C3BB461A487982DED37041AD0C1D032714F7379E2FB9FAF5AA6D0F5469C7156800BA258FC5B25D0996B6735665A806A74B03D9819A5832A6685157E7285DF397E23B13A543A983A5B24264C971A73708DE1572852465732C94830719C197C7985C0A7C53525A1AE76D18E1E9112EB4B57C1222320A8156643CBC9535A27658A3709123CD61AF7798ADDD888053BB0DE254EFF530296F9AE75B2CA756539B61C62DECB0E9AE611678B5190503344229096C34990A61CE8B10ED3841D48D266CDC249ACC96B7D88010899C453467213D8BD23E1764E0237480C34D8396EF57C1AAF781C042471D04077EFF85338AB8CAEF22ED064BC38164070A00CC78B8074E7569A627B49E0416A705386601D3B8A6C10A4ADCBB190B4877422304FFC776B4A129D4098C603896A6020725986CFCF0083FFFA66EABAB82DB734F5D1B5766104E8A2B8B859B6CD166DEC691AE331B87E794A1C9B083C14B50B85B7E97148745C9F8975733D4262E247473CE53B85D01C6DE505A352BFC0C233A396C87F856981C83FB74542C9F3CEE1276F3096486EF23359C51AC553931B80C6BD245B2114C4A2D344AB53765C02C82B41412AFA1AD5BA6CCEE9BF09E375EDDC0CD55BB6C727BE26BBBC4E7392293C59455084B1542C87578C63511AE3E384E027BC07CA7401CB0096D1205F4CA86D3C73EE8273DE930799369133F83F4667A92E72BEE2655B17120DEE233433F9C68A50C57FDC8617AC1D03F0961D4A7BD17678D8729329A0BA0591CA84670557E15FC5EB4E8255007B8C4E48206F62062E1DD53BFC43AF02405D2E300D4858B1B9C9CEB531A910C0BDE877450A9AAA8878A2FA45089E184D1FEC1CF4E3909670BC11E78DA5D8CFEB86A4C087A1B73A6099C99836B3CC76366D35A9854B3B205F4B2B69666878614117163FEFDC32B6DB37FDEAB0A0197F79DB088C3A355877CDB1313A2F200E27E37E12B4BFBA04691F82B1C2E8B8172C11E466CD8D01286F2A3A4FE5A5F920476A9278B9D25E420B77D489386F9C167F2731654B19FE4886867B79EE10C18F679FAE87826A0B65B44A83DA5A35E0723BDA3467541228B80B35D5AB869B52B5DBA9B8B309360FF1022D67BC93747C392469C28B288CB73FCA74001E5BB47D5B0321E08FBF832D0A9B0DBDF566D3898E1F9ABA7E3C011A14C3E918589282C0F167BF14470D1F6C774E6742E40A1452C70CAFB941624C02AD201E6030BF3DC6A039E6465D6772D1C184C693BD16C3367F02730ED6BEB95940FF783CF9E307F38A7F4F37754F6C4ED26A1C70C90741AC89E56C989B0260F7E1178B5B975D54AA6F420E97A7B90C3C74200359D561BEAE98B1AF044BE40A2AD8491F42662E2F34BDE200C63CA48E7409727C8B2185138AE7859CE43558349A1F3E641DF0C14428C0C12D0A49ABB904CDF8AE5CF34D379024ED528E5D84A3D25920B7A94B61A8ABF9E557FF61C784501FC9E332F2B652F16A0A11148B8E594D1F377035E124D637659D4485D909543818814FE7A8A173BC8AAB7066D2C927C90660DC8D30364D60A31F1D94A9E5F586CD84C167E2577D3326E41A614382F4982426E93391380C4B03DB38D0F7BF0FF66D2D93C251D3347C643EF3581D438AF7DEC621304E0091F797346CA18A41F39401E9D03200EF48BEB685C3A8B3732DB34F4CD985B65E078AFE6A735B53F4BC36D4762A3E45D1DBCB74", + "ek" : "4591D285B1828A2B7EF165B57F41D77713AB2C285BF91CD51BE6F15171F41E1230981B3BEE25E9117C20AB8700D8B13E39F439A9FA838824F73494F0CFE51583310F0E55A5F3D7A577C7BEEA2F45C4BBA64B2D706B3B421819802354F3716D5EF0C7E4437603C8A75D8FA9EE1E7981B9B21877EEE1171471F57729AD1E70C63DC6C66CF8418B0A50905C8AE0AFB65011DFB6D05A5ED28067FD20184BAB8181274FBF2438E83D5ADA4CED773AB477FDA902E0CC9C9730D63EED0AED2E0742CE2900D94304D8E99E4F8D29B0C3F8AC7DA2BD55269F1BBE895A03E610F155A13D0FC2F39E60F3AF9F374760FB434CD4D7D0CDA9890DBB595435AF92D736BE71C7256FB56D900E2C24DCD4B70F7BEDF3FDC6F324605222561C19C9049FB6F08FFE480144B429A6B89D9EFE0F32D3D0B96ADFE78808E42C802E0CBB713276A5A1373C6B9ADAD60BE37C4E410F4C21E809D46B43D27CCE5FAB50E4FB63B7216996B8AFDD2F00C1FD9F32727313764F7D81856D3D82E59ED888D09B6D3A7DEC6C9519BBE8887B4FC5A35832DF1EA5A00D9DA03C74D20A9D0AA7D2D433746A92114E964D0764E8BD7BA864BC432543BB897558C2C1007C89FF8EF1B50D9DA77DFA0232DF3A54EC8A5BDF640D72FF7C4D36DDB04883B1851B237ABA2B10575954759402648852395F5A982E8D6B960EE48194B8973F3D9DB46873673A2E3948E9E26D78D41C728122AAE50BFE83F349EEC7F8B4601F82565C0C6F4A5ED7612F79D9CDA16398B888BAF480F1AD2FEE892ABFEA8BE24AF7909F550720F1C8A169AF75BB5A5D890D670849D4EA1769F8567A13A3AB669394EC051ADAC2E3C5D918D034BA9491C031B430F613096BDE3EDFDE7DCE038FAE38D695047A33449FAC24BA6FC4527EF100A95DE9BCC912FCE07C936051B5E4CC97F0B450AE0B5ACFC27567256438C8D4BD718205D70BC71A14581BDC5D35883D8E400DEB05B32A9BEC3B07AAF15B2D355C52A0AC846A301BC6749BA41D2D8EA9564DE9FE3AA76EAA612BB5763ECB77D667A59DC3CB2F7094D4BC06CDF27B09814ADCDE42CD88642F1C2C3D36A32A5C51416EBA240E455D34ACBB545343CB311B02463A8ACADBD03CAA756F72D7E0961264B6048CF3752E0C299D88F8591638C2B89EB3A5D07AB0EA02988DADC22D414F177D3AA54566839A67FCA6C3D962B30573C7BD3BF47DDAA79052F4DCC91E20701CC3541C6DA60B0F9BC3BE21A930506B4B7C93ACFCA75D18D4FB924DEA3C21A11B0155233076409797E0E0D85D767C39CC5085B3B5AC0D64A4A1C94AAE05AEE1FA75649940585988204D9F43098ABB81B92FB1AF3A7CA99ED7E44A391A531BDD4E63D23C9225859B67454966E80A7E91595B49DFE7D27ADFBCA65009D8E87F221BFB9FAD63E866EB88C0771E69806EF7F0BBCD639F2153101B5042014AF549033AF07E71306527EA1203FA5488AD3DFDC71C9097FBA52D20D3B502294F85D875ED3FE16A32E22E163AEC97086913229256BB89FB1143D7F52876236B421774", + "k" : "F41985D361D5FDE4067B4A9C398CDAF61047C705605140A342231F831453D078", +}, +{ + "rngSeed" : "8098AE7A92C10F707D405F7DEA02C2EFBEF44EFA132BA8AEFE81BD45E543ECEC74F10920AE48A40B0653D63532517F2A", + "pk" : "D8B6C56DC931D12A8092102490881B4E2064C5A9588E257834C1AEA2668E69D907DB5158C3CC7321D83B9703CB74864C1057660B718C3412CC47BB92612643313C356B6B2CDEAC80EC5B657E78CB2FE9AD14C28747E45466847D71C49D1355AA845A5C0FB27160156D49A3AF1D8B975D694186B06A5B1111AC504DF3F91CE9A4B2E248697F9A972E7B0CD048C1B6F7581AF20AFAE4C1B9333F60E73A0DD1CEB2E19887CC712D0BBB5C24054553C3C7C972E87253D4C46C971826E8955AC0017CA6D6550335916D6A939F5C167BD68C09D85650E89B40A4686FF0BBD921AC3E43641B1600A84BAD0FEC9524F09FC920916A31B081E88A36803715B1476E57CE39EC27FBB04256CA64FD11225E474B06BCAC9657B31DE3A39F4CAB5B65BCD8896655EB924243972B0BC9B755B0C69B837030A07937652C8C14F71745572882D222BA1208327D3228F0778A215B8FE6F4A14A9B3A56ECC56F09C49CA31CDA853DB12A2FE5D395A00CCE6621833E61C2CEA5BD6F0BCC6EC6B479E334FA543229B619BE566E8C00A1DC7837C7B5651B8B6A94412CCDDB63B8213635A5745A54BB56198D325A59109C75D2B733C77738A1328BF1370ED99B7ED8F611E69C3ED82620CE95088A91C6C6D472294260A1C5455291188E010A9467C816938F9835C1A4FA01223494C885642E5C416C82223D614A108A1128E53D9B264D61D798C4CA9BF6ABC72FE779346A3208A77542272B591A6AE781996EF17961284666C85BA91B2DE5F0BF9AF10EB91C5793E48FDF367F46F586E05B2DD65B262506043DE419482071DBAA2568256A14825B8F094B796A527FD25B8071A4041A1BE279C2E3F543021364A147CFF6740BA448B7010B4DDBA6AA90265A95905F141A9374970A1A071799D813ECD77073B453CB2B6D83AC9CB8267A5861B9E2F23D345581A074657554781E4782D98333F1237DCAFA48087AA66DE4209A9A78700B09D44A0B5C929AE6612ACF6B5D8AD20404A161FDD3639E659BF88291D41711015432F0E7AC759A67E0324F94C1876314687AC377AE48A30B48BA9986714EF3064F087C953AC6F86430BBA9CEF9857B849315DC4379799092AF4C5531FC13F63B186939040DA2233BE05371D448FA748D76F98C3F638A6BF5864B9BC5FBE496D72966E3004409E420BC4353A5D55D0610843D0B8E6EE5BB5D6C4DD1462AE99A43DF586B398A15FF5B5FF58A4006987613F5CABA694DC0F736F6D47AF66673E8F308A6044338D23C817C0420E679EF621739E21A4A35140DD2928E79584F787671B118E9E71E1D9430B9A3210E11C266876A44C7082E7CA5F6DC4B8D931F5BFA302FC790BD424CC3643844418F6C090E2CF5BF60F08C489BB87315464D90006375C34A5297A238A117A8770CB9795776C11F8A54FF13ADB3FA77DF3757938C28D03A612324858A11A860235E0E15284E36035BFC0178DB841C679A47B93E3B09A9F735955D6BCE328A91F2FA64273917B7371FBF166C47E9683776AEC02251EDDC84032CB0A852594F4C7875792FA345A43A68A193C51492A39C306B02F22C60CE5A8468C3050CC3965E2982E32B938A31CAB1F36C1DA3CA723261BE3A864E2912199262C46741FDDCA501DF33D04A79F8E3017E6197AB24B062CD98486DCE2A7FFB22E5798643CF9BA5", + "sk" : "C0B38724691A735C3FD82033D0535C3758A5D4298DDCF542556B73EC6009C4640F5C26471849A2289C469A975839FA5D4B389E75F8423A4633EBD29D8D1A5C19E609F12240EDF33AE9C07CF93C18950CB1DBB07963D69DD1E2447DB0500255098CB88083A633C5181F75D53A7F0681900747C8EAB98D3AAC6FF35D2BB01C80A1CB4E5A654A852A07614DA10C5EC8071AC3D6394B3A13D47312F03229604C682F05245CEC41B3B55098090B6044A1A3C0AF26AB4A6BA21ECD50A08D8723D32563C36AA8C3BB01FA3798C42AAAAADB9D0AC8925342264DD4072DB982309C0460D7380F02CF5EC0AFE3FA13C7297337DC205C0A1F8B3109363765D44A29F1A7BD2B17C24C3130C26A8B872575970239EF12352EB15AAB0C9A96B5C51F47370AA5372BC97A22A4029EA0B9156622903354F5A1CB3D49693A198413380075174D2969A95831B1051AB40D1344D809CEC691717579A1B7EB52C9087D9244CF9AE6BDC32766B694708D1BA22FC76B042A6F9AD668971B4767E6A54A95290B699A04788EDEA5C914E3CB431337C0736EFE7244D139BBBBA28CE82B72AE92A23121B7560C9DB5B908BD12539890A172F4C68F381D1C7B562B1B5BD88046359C29DD933BA1EC1F47BC4C485C8DD599767822CA7C4CB300954821695EB5EB2F87FBA33D61284B187CA6726A1BE742286959E38456594763F5EA53B9A7959382C348C7449783B5C784522F44AA3C25BD21D48660F78F70A00E49E59BEAD90C4C8367C22981D8CA6B5C198CB5906B12C55915232AFC1A4B1CE5C4FF346F5F536FE68AB9D816C98DD6C5EE103D251874B4CB0554F38AD0712BA687634882856D453DAEF102D3835CD81B5791A50ED5934A0734A81FC78C6EA23AB2D96B679866458C21ED50ABCE98875167361A62991052BFC7123CD4F9B5E0E98C4266536573742C431D9D343BCB9A8BC1E2A927496A71D73AB6195CD7194D31BA631D025570725E6B37ABDD60A545D2CD2532B32A9548F1A319DF6184614405832954D89A61DCE3B5CBDB1FF691550117402C027DA07B2B5BC20B25CA36B0E70D45771E3561526950A8216A7F09DB88EE46578A107EC0A46F932751D77A167C4809C14CA056923D2F540692C9B8DE07CC05A55AA5ACA7607A5F5B071139620AD4309E2E3A2995A31059CB8F3D09B65F171BC3740DF13CC63E51BBC33B7922951073AC3E51013B39A0464EA67A9D5A76546227EA7974E1B61847036D94E13201644D585CC7B4C9AA301980EEBA05E9E21DCC5163F7802DD3557E0FD6AEFA1305E2F84BC42C8FC057A4ADB58D3545CA8D767AE622CF7BD3C3178B92C5E776695BA375FB841E12760656BEFCB915D6A51F2CAC896D7380A879A41001CE067A602A73CDCE00A4321AA880B7382407C3DA7A3702F28A098719E3822D6D8C12C88B460E691DDA17BC4F5B589F2B46FC773FEFA492E1112CFAC69392C80ABC1084E68903BE87B76364CAF5FC82039015BEF0C9FEE65311407F970B695C8759287898EA39BBA8F61FE9D48936B1935B2A2770D498FC2BB22DF5980904759BA64F05230378266C8114A7B3A1A5E33129EFB4A52FC163628C5C1A65A0441325B3F3B8BCBC7DEA5C42C7897AA8956473D54ED8B6C56DC931D12A8092102490881B4E2064C5A9588E257834C1AEA2668E69D907DB5158C3CC7321D83B9703CB74864C1057660B718C3412CC47BB92612643313C356B6B2CDEAC80EC5B657E78CB2FE9AD14C28747E45466847D71C49D1355AA845A5C0FB27160156D49A3AF1D8B975D694186B06A5B1111AC504DF3F91CE9A4B2E248697F9A972E7B0CD048C1B6F7581AF20AFAE4C1B9333F60E73A0DD1CEB2E19887CC712D0BBB5C24054553C3C7C972E87253D4C46C971826E8955AC0017CA6D6550335916D6A939F5C167BD68C09D85650E89B40A4686FF0BBD921AC3E43641B1600A84BAD0FEC9524F09FC920916A31B081E88A36803715B1476E57CE39EC27FBB04256CA64FD11225E474B06BCAC9657B31DE3A39F4CAB5B65BCD8896655EB924243972B0BC9B755B0C69B837030A07937652C8C14F71745572882D222BA1208327D3228F0778A215B8FE6F4A14A9B3A56ECC56F09C49CA31CDA853DB12A2FE5D395A00CCE6621833E61C2CEA5BD6F0BCC6EC6B479E334FA543229B619BE566E8C00A1DC7837C7B5651B8B6A94412CCDDB63B8213635A5745A54BB56198D325A59109C75D2B733C77738A1328BF1370ED99B7ED8F611E69C3ED82620CE95088A91C6C6D472294260A1C5455291188E010A9467C816938F9835C1A4FA01223494C885642E5C416C82223D614A108A1128E53D9B264D61D798C4CA9BF6ABC72FE779346A3208A77542272B591A6AE781996EF17961284666C85BA91B2DE5F0BF9AF10EB91C5793E48FDF367F46F586E05B2DD65B262506043DE419482071DBAA2568256A14825B8F094B796A527FD25B8071A4041A1BE279C2E3F543021364A147CFF6740BA448B7010B4DDBA6AA90265A95905F141A9374970A1A071799D813ECD77073B453CB2B6D83AC9CB8267A5861B9E2F23D345581A074657554781E4782D98333F1237DCAFA48087AA66DE4209A9A78700B09D44A0B5C929AE6612ACF6B5D8AD20404A161FDD3639E659BF88291D41711015432F0E7AC759A67E0324F94C1876314687AC377AE48A30B48BA9986714EF3064F087C953AC6F86430BBA9CEF9857B849315DC4379799092AF4C5531FC13F63B186939040DA2233BE05371D448FA748D76F98C3F638A6BF5864B9BC5FBE496D72966E3004409E420BC4353A5D55D0610843D0B8E6EE5BB5D6C4DD1462AE99A43DF586B398A15FF5B5FF58A4006987613F5CABA694DC0F736F6D47AF66673E8F308A6044338D23C817C0420E679EF621739E21A4A35140DD2928E79584F787671B118E9E71E1D9430B9A3210E11C266876A44C7082E7CA5F6DC4B8D931F5BFA302FC790BD424CC3643844418F6C090E2CF5BF60F08C489BB87315464D90006375C34A5297A238A117A8770CB9795776C11F8A54FF13ADB3FA77DF3757938C28D03A612324858A11A860235E0E15284E36035BFC0178DB841C679A47B93E3B09A9F735955D6BCE328A91F2FA64273917B7371FBF166C47E9683776AEC02251EDDC84032CB0A852594F4C7875792FA345A43A68A193C51492A39C306B02F22C60CE5A8468C3050CC3965E2982E32B938A31CAB1F36C1DA3CA723261BE3A864E2912199262C46741FDDCA501DF33D04A79F8E3017E6197AB24B062CD98486DCE2A7FFB22E5798643CF9BA5FA06BB0FF42F4D610A7B3DF7544D66B97A486967CD9B62BA0142EBB10B8EE4EE11C11C1086F0365E9FBD525B3FCB4E4F169FB488BF0CBCB455EC098D49E903C9", + "ek" : "6C588B2AEC219D23895BADB397FCBFC64C7CD0E384193FDC4C98079E5544433E19256DEC9CED963DDCECCC087FE659FDBC6C46B6CEF84E14DDCA32D82F41111F79A8D991273AAD00288199F3F324103DBD0B76F7DD4BE9FE556E3C2F8870FC1850A7BBC70CB60AB5CDA4E65396A88C9A771DC84919A09C627AC1CD014D78ADAB11E563AD83278AC9F4F5B3AFB0157C8E1865A65D522164C667C76F8610035C2CD3D9571C6B5D91B6F9A6A2CF7D99972FE7E46F3F9A299D5A0993F4F11F220EFDF87FFDFA1F148BBC547268C39ED64308D5F46DF504407F7070BF83956AC75CD8C760A05C12796CA06BA2EEA77C9A33841333F0DD6F1578AE85523DD373A9895CDEB0B70233BB039B84B7B89984E10B94180826B1F913C6DAADEB3D631DD681A1A2B49F39DEC0F43B4246F85F5A4AE39C21A0B3D06D3098A4D491F638D6FF594484F5E2851AD4504A144A1FDE7BDEE837F4E4E3BDDFB51D41C77B84C46517219E3685049E23639A44F34B2F42EA747349D447756C57E5C9FF647510A35722A1B8F7287204CA02175EED28656E408B1DFC873BB0B7DB29476E9202DC5C1DCF71E75D8F1B20D0A69F82070AB05E17774D51F52479A1008D8383920374C7FEC175DDB586376F45E92F8CFE76EC831EC86B08AAA12F7AD8425ABDE4871FF54C76EC8A71A140DF0F357E97DB7C5FC84FF876DBD3080980A39D1D90778429A74E1AFB01591ABA84741E6F3F91E65AB2BEDFDBAA81EC089BDE3868EDDB359D1A7A0726F90D0A0D3D036DE021E951B1041B22F18F67EC0E4A33C141C02D21630515C9E46980B83D88049AC620877A38A65EDB1AFBD14A4C4898F1A881C6C7479A36D5CFF47A5CAE44D6805C567CFA3696EC8AD00E4CBFF02E36A6774AB91B7B4386877EA80109B0B4D3E81EE77569006BBFBF1DF00B3A4A36D125E5F876768DAD7B363C1679F6266A91AFC3B44F2910CDF00990BD2483A87E6C71536BC109A27DF4793E92CB609CB4414B67A5DAE5EE212D7F913CF79B4870E2B86EEC039906D04D429786846BA68EC0ACC9B950968124792597792A36E6B011E94C1CCB10A6EEBB824369C562E1A830369120E2ADECB4B3C0C87CD1D26A26A7782CA292C2C6FCA0EDDE60D99E9ECF9BC39B372B52830AD56DBBA7D7A0378E97134BDA6A5C2C53D16C87384E88A60F7DC8A281E51B52B9951914123832DAC31452751274247E35E0C652FDDD3E79D92A7888250B45FF0A7D1DB1AED3B8070366033AC75540E8FAB3734753F3F1704189085F398E516D7D820A60B89D4BD4D9A12BC24CD1EA47696BECC616AA065F57D00932623D2AC14AEFB3B55B664709784BF09B42527A33E23CAE14AC1B4CCA43A684CFE7ED939D8943567940C891C0B6A72865D464222D92E2921B6B3BB681D74734BA509A4180E125D2EFE3C22F8560A55B4B62582FE7271A9590FD4A2AAF42F843AE1CDB84798B6041602D5CF4C84327B52B91023A0396C3E843EDAE52426B81C4184399EFDB6B9FD21E670918858F2F315E96733D65BE02106DB9", + "k" : "18AF750CFE84E390A2995C943BAFB4412D67BC8E3355DEA9BC4157B264301798", +}, +{ + "rngSeed" : "D5F23808871544E9C1D6EACE2028362B48E225312F77663E9F78CAFEB512B908CD9E25875D61A16EC615F4B8FF826856", + "pk" : "6F22424D97BFE0B7CFEBA385C55253559B0372FAC0C533055EE490BED57446B637FD0C07C173B2C61345185A0288F1AA074ACCAE383C75208FA03A6A175C3D19481E79EC833057A8D2C234AE9B01376C21BC75277738B17DEA03EAE594EA939E125C2592BCC95D3CB4F76A8D8383B318A48F7481B6B8419E8BB47CF1229C23C4800788CF91E465088A580762AC5D31616F114606C54EFA9C0490298CCC23200154342DC7709A5CA5CA3A94B7A2AD8EA734B6E20A2D15ACD47C6AEADA3EF3331FCAE173AF5191CA8B74BEE31F1B7506B595A3DEE0899381111680AB02090429B93EFB7B52A6884D401841A0D8193953A5A5F2417DF927E5934C109722CFE18D0FF93A3DF69D9CFA4D7F5801D3294771156E828924C65A18BC798006A1C8EEFC3B4176634690C061B902738024C0AB981C3506D11B8F307C8F1CBC25EC764FDAD76FB2117AFF430C5A5A468F2966BBB877D2B8335BA3BFCA985864F21A9912BEA56A007E7223C7249B2E45A37DB9C104438E76D16321289D4B07001241AA2F0A1A24D81C27A9ADC0C768E1B3C72FA08E33F77C90F4CBDD530949B2B67DA9A15F336B679937AA825989B9A450FA5F69304D37E585BC039A154257EE78907F689DFDB246D05C94C3057066D03A2F9825BE6A52C3376EFBEA3FDEBA68E13716D810B73662ADDA56BF30031B8F682C8AB08C4B0978BDF113B4432EC712BA306A63C327978224597C3B8155551997BB7E2881102D8B3EEF786BE65196BA84478C1C629F45A885DB1AA4CA443D8A3300316608E8C2F71C6C7516CA5EB453CF9184BED2888EC592DCD53FED23B5CEB98CB575C474B51E7FD64D73D54F37B51FE1D432B2150ECD5B0DADE606D83729586B2FDC60414A558C3C19122E47858675179C2229779B40CD882BFEB3059FFAA93552443FB70FCABB54A7015F8B6A0798B090FEC5AEF185CC95579AAE5CAA2B4923DDF65B2570C15B1B0464C086114975DBAAC5A564CDFE02CBCE8C68752000EE81A9EEAC55D4A81BE9B3C66AA3875761049565A46E305459FC7A47D75316B59A371CAB01DC3BFE9108003D5F868B39EA617CE3091E3AB646DB07CCC4A09367B352D1848B26E920100827C8D4C92F0C222D8482606233ADBABA3005B58FD3248E67CC75733FEB52A5ACF5A41AB71CE0AB7E8FCA8113261DD4B7297FFC9D37899AB40B0637C02FF1C73E81A02762FB264F51C849D387B9F7AEA345B5E2EC44F2E0866B9574BCB13EA0D0AEB7A78D6DC7B5B0C9838297C05409BF90D86B3C1B59B92C998A8ABF34FC490259289B431C5C5368ACD762DF8CA04E0235AE91BFD5332D67169AAC2586DECA4C8174386617AC98471366283F3D30A971C62F35322AC96A7B0C45779F6C17F1117A2F1B454E3557CE5733CF979156400C5A780A4DA91AB8D99C4F98B141920731F361EC30950BD0C5653C83DBA87658674C57473DAFAC42F293BEE44034B9489CCFD5141EE42CD91B3C3CBACBA092CFEF6BA4B0A716D8162521B29853522356943C697A10948A50F27008D8A303254327C4570AF822024F5B9AEA82A62100856B2140015418A9BA3E77325B911A582E92A8B8E123816405ED8382820C0CE5CA491C0692B2B542B6A67EC87BB6B0334C1833E12AA958FCC0747802853F8536C1E24A0EA6E13CE23C96726B5CC8", + "sk" : "D95B5C5667B797B1797A73806DF8906819743E0322070C80D97B77242040A2C6154CE152E2BACF89BA871DCB835AA873133A331DD3450BB51893CBC5B072459026552001C56E6A9EC0DA3ACE136B5EE150946406F032A475D8CD05C31C14897445EBBB24CBA8A9E9B9FC819D752A5F6830162C89C4E7E16DC3B12823739D44C063F55AAADCB03D02C3325649AFA5A63E26A23F16CB48091B388F503F9EB6751D44BCF61989FA953C10A5B8EA9CA81C56A04498509F380C1675B273415BC9285D0E765B0222927A979EA9A47B9103C0B73326A35945EC1CC870A693980CB73722B855690BCCCA1DF9290D15B6CC53DB8B99A89395994E3F39C13C81B9F3A313A6AC1407585AE1015EB2298DEFD84A5258A2E62AABE709C8243679DD85B82C08A82021206CF0424B7CAB4DF614AA21C81D931FC5F0BAB9F373FC4A98484BC6FD5606AF987BF57842CC4461014C4C737B6A52234153986AAFD737D4A834971B96A711693716CDD1639F822A43936B94B7421BDD660503F3034C0C2596E8155684ABC1E81C218151E2D44845D781E4A54F33FA8EAA0CAE0D96C3509C6E5A973272C0B7616A929A579D6D9B83CA8C6631B87F94457312D9C58F66B20C04297B881D11E9C97357A9B0E50572B3430722963869CA2A1688F623B5A3224D2AFB7BF6F4CA115198BEB213679C210067A32219CB9557042018467863C10A4B449BEA2B486A85EBC0BA8DA9A3CA50A632451A5754B7EB0B7067C2C939BC192BDB8315427146AB6FE7390AB60264B0875FD2603D09466ACB2694091340BC8C6DF3FB8EAEF1664B533C0E377BFD0BCA39F801F40A92989619C41756AF7B4CC7551C8779558AD4031A6459E6ABBD9FC68103FBB95182C9576135E154A619180B1A694E384212FA89963360791666968CD9AA5ED3BC0F72939C24CDA10A9F2A62AA4CBA9B9D677C5DF1282E47C29A790BDBDB664DDB30CB154D01DA8E87035D62A099A9E9A47F019D6A769579EABDDC851416FC9A2F144B2D2C3FECF889F19A2ACC434919A89D474AC628C03ED6050B3503C2CCB4612EEB831CEB76EC9798C2738429DC10386B36BE606622D2152DB389B200C219E4957BB6AC6F59739BB60DE382C88EBC442FC16E5B55CFDDA0C9B78A18B07A5E72EA3927070D7D15951F87B0E09BBC631BCA04FA0D5F4630FD04A16D24BBCF351C806C07C32AA05B19009B66181413C202536D52B8946FD8BBC65215749359A3687CCA6982C3AB0435DA4EDF454A69B23726C503CBA4CED872311799C4CE57C0E1FC48CFF587C4B552DA83B5472353C711C6F220BB72540CFA651352287E88D0624DF8248B17914F654A61AC0FC30856CAD09F5FB984A8E334B5333C3010C1BFF26FA7164058B2343FEC330F4C2E93B07C7E568D6F437C0A307131C70E0821637519B1673A3846829AE11CA2801B5A5EAB191CE686EBD2C2A8695F357BBCF18C95C51591B67ACA77521DE32B1426173A0E059686007508DA93CE9089BBD43479183D0705496D1709EF41424219054BE29EC816868A95146AC5106E261D6331A692306BF9013207D60A7F1519D0D7CCC03755EB5C31A2982A81339CEE7B810727471D447DF481B87DA70F7651B7EFF647A2ECA76F22424D97BFE0B7CFEBA385C55253559B0372FAC0C533055EE490BED57446B637FD0C07C173B2C61345185A0288F1AA074ACCAE383C75208FA03A6A175C3D19481E79EC833057A8D2C234AE9B01376C21BC75277738B17DEA03EAE594EA939E125C2592BCC95D3CB4F76A8D8383B318A48F7481B6B8419E8BB47CF1229C23C4800788CF91E465088A580762AC5D31616F114606C54EFA9C0490298CCC23200154342DC7709A5CA5CA3A94B7A2AD8EA734B6E20A2D15ACD47C6AEADA3EF3331FCAE173AF5191CA8B74BEE31F1B7506B595A3DEE0899381111680AB02090429B93EFB7B52A6884D401841A0D8193953A5A5F2417DF927E5934C109722CFE18D0FF93A3DF69D9CFA4D7F5801D3294771156E828924C65A18BC798006A1C8EEFC3B4176634690C061B902738024C0AB981C3506D11B8F307C8F1CBC25EC764FDAD76FB2117AFF430C5A5A468F2966BBB877D2B8335BA3BFCA985864F21A9912BEA56A007E7223C7249B2E45A37DB9C104438E76D16321289D4B07001241AA2F0A1A24D81C27A9ADC0C768E1B3C72FA08E33F77C90F4CBDD530949B2B67DA9A15F336B679937AA825989B9A450FA5F69304D37E585BC039A154257EE78907F689DFDB246D05C94C3057066D03A2F9825BE6A52C3376EFBEA3FDEBA68E13716D810B73662ADDA56BF30031B8F682C8AB08C4B0978BDF113B4432EC712BA306A63C327978224597C3B8155551997BB7E2881102D8B3EEF786BE65196BA84478C1C629F45A885DB1AA4CA443D8A3300316608E8C2F71C6C7516CA5EB453CF9184BED2888EC592DCD53FED23B5CEB98CB575C474B51E7FD64D73D54F37B51FE1D432B2150ECD5B0DADE606D83729586B2FDC60414A558C3C19122E47858675179C2229779B40CD882BFEB3059FFAA93552443FB70FCABB54A7015F8B6A0798B090FEC5AEF185CC95579AAE5CAA2B4923DDF65B2570C15B1B0464C086114975DBAAC5A564CDFE02CBCE8C68752000EE81A9EEAC55D4A81BE9B3C66AA3875761049565A46E305459FC7A47D75316B59A371CAB01DC3BFE9108003D5F868B39EA617CE3091E3AB646DB07CCC4A09367B352D1848B26E920100827C8D4C92F0C222D8482606233ADBABA3005B58FD3248E67CC75733FEB52A5ACF5A41AB71CE0AB7E8FCA8113261DD4B7297FFC9D37899AB40B0637C02FF1C73E81A02762FB264F51C849D387B9F7AEA345B5E2EC44F2E0866B9574BCB13EA0D0AEB7A78D6DC7B5B0C9838297C05409BF90D86B3C1B59B92C998A8ABF34FC490259289B431C5C5368ACD762DF8CA04E0235AE91BFD5332D67169AAC2586DECA4C8174386617AC98471366283F3D30A971C62F35322AC96A7B0C45779F6C17F1117A2F1B454E3557CE5733CF979156400C5A780A4DA91AB8D99C4F98B141920731F361EC30950BD0C5653C83DBA87658674C57473DAFAC42F293BEE44034B9489CCFD5141EE42CD91B3C3CBACBA092CFEF6BA4B0A716D8162521B29853522356943C697A10948A50F27008D8A303254327C4570AF822024F5B9AEA82A62100856B2140015418A9BA3E77325B911A582E92A8B8E123816405ED8382820C0CE5CA491C0692B2B542B6A67EC87BB6B0334C1833E12AA958FCC0747802853F8536C1E24A0EA6E13CE23C96726B5CC886538ECDF65B7A485B73A34A72193AF1EA3F884D820463601C7F843672BBEC7D284837F7EDF4788F32E757949CFA69DDEE079E2E00E439ECEDC8512097E2D2CE", + "ek" : "1B344D0262404A412EDF1F1BC5F6C31073A2DB242BBD399B28F4CEA32600E2D9441224B299144621D820B762CEE458197678F1148E9A86F2A0BE91306A7F9A04C264F8357BE3213B2BB230293A61EEC6EC5F7B59E0DB943B1A63003159C1D90D3DEA88D2D3BEED0E6D655571713A521651EA27F45C53ABC04B734B2AA19F69A274673EF95F40F23E24CD8B88589BA4B9EE1F59B7D5F514ACEDC11BAFD11EB9ADD9B8DF5E3A25AF3C6F2463E2512DEFCB27CA25E81E7521A674A263B099B168C138935839B6A42CB773C476E02515BDD76E3284BB582040A33E5BF2714E0CD85AC44D5B1B86D1EF11B31632FB9A6BB1CA2C5869B98D8C35D2D5A6AAE580A6DA4C7C77BFA7AB2A7AAFAE1FCF97DF4790F4EC2E4635AFA4348EDAFE41499B8E0E362D28704599091558873FF8F37A10701759005B8E9200D86D1D205B6BE4305D1756ABCCC81025119E14679A19E0B24D59A825DDE55B2F5CC1FCEF7B29DBD2AEE2CAC3645F3E5ACA48DBEE3723EAA1AEAF863904FF6F4101E706A13583E7241248FDDE5536F3C8AD29500E954C710A6FE73BDABE194A3A460CC5AA7E25D2740DB4A3582578E1533FBE0D6F1DC62D8023A67155CD4DEAD55DAB4A4CEC67EB2BDA50C95A92C6930B4D9AA642760277B83B2F923A5B0565E98D971E9563D60F20C157C3E2FA6D81E5045D4167C0FB85A965AD4A7A0DB69069871BE969B13C9B1418E6B639EAD2DE88A3653A90D8A75FA66E52D28E1C1B198FE6979A08D68386791F3B1E6F7417F24A154D42EFFF3DCE6256C1BCE6EA2A94E6A84D88E8D8E88D6C920392F8A6D42B41591815A12D70D79BA2BDF6785BD6100B00E3A61753CE8FFE4FDAD4EE43FD49502C55F1F933FF3FF35AAFF714F64CF0070159ABDE9F3C0C38332C9CC4EE6A86C49CC9F379C821DC17E46D4EBC96A1EA98C35F17EA89312AB3B02036C778D408D4CCF21FDE88016DAD8D3673075E72E19C7D91297A621F68A22CB596507E2429594E3AF916D38950923214F4817428DCBE0789FA49DF3AC3CADA196AFFB8BCDB43E62C619AE5E73CEFEAE74F0CA2ADD741F4696FD25D7D3FE9803DE41FD57EDE9ED4B821886BB3490A729AFB0B2512A1932F58FAC101D1995F7AAD7E68BC61C99CAFBD591726386900147F25826BE0DD93918FC5C6912878308BD5A2FBACD4EFF266A2AA3A000F5F886BD7FDBA5F3055950DAADEABB9FD3BCF091C5B617C8857E9175AF5B3DAFA80D605383685DEB7278438BF320B9EC1257A256FFBC6D82FEA27014A796E03F3268998AA4331F3E11B63F2B00C460FBD3ACD0DF59366429C7033B1EE4C2CD6B5E64F4855C5CF357BDB78971B442D30C6768158DB7141A216EAEA5B906CCD5FDA7408341DB992E84A6F10EB5E2F6CB2B5456FEAFEB96D5275862F782792200CF1BEA0A021F5E6694B1672DA7065D620BADFF937F5499BA4140EEC6A300819CD2D382CC47DBEB963AFE0D5536A3F5A92D7B7E2F052623CD390981847F0484E7475A3FF67F570250D95CC3C24CFB9B6E845B5584B42", + "k" : "5F96DB99E2D09B62784102412606AE7A0FB4A2E979B5D98091C3BF653875F73F", +}, +{ + "rngSeed" : "822CB47BE2266E182F34546924D753A5E3369011047E6950B00BC392F8FEC19EA87C26D8021D377DF86DC76C24C5F827", + "pk" : "010510677C6C12C76CF7149F35031C8DF3B243140F9716A571F62A5365A0830169B612ABF0075AB40132D51070AEC5566FE953382AC3A3705B8566064AF52B926B765BC039D6F86AB8B27CB93B809E670DA4457BFB8B6BE9AA54D9B2BC94EB0C3E15BA6CE2B08AD229A469312A5CAA04C8A4FCA7C76CF905C6FC4D32127D84981608810A4752B9F26BAA12665BDF30882D2A38200798DE4A5F1D3BBB571085AB091C03E896F25B8759E43795DC83C2069FCB2CAD05B166DEF78D18B920E0E59853C66BCB11795F604963AC3AF33B43F78252E06B39D11449012B0B35BC65C2562A66F7597302377EB13119FB4285D5613D618C2227A8A187B132B08BF5B154745451FA627E0587C24118573F3628E3DA59E96C6A66D26C2880C95EB1ABD96202B3673BD64A74D1B11396AA406D378183325C9D03B8294177D3D6439FA79A2A6457D9F81BA8134BC781C575413E40082C686AC2F59C3FB45A580D3A50ADD274ADD391A09CB6C559623C997DA498C1D002B0F9B5254C26266757849E7598C941333D580A11A1C197617B23D98B7DA60B6AF0521E287F8B0CB21522236395A60AF9CA4DC7120925A4BF497E2ED65BCCE78A33555EA459197BD5A499BC7C2B788872916AB3B961F25094CC96659DB67BFEAB52260456BB775F56E492564456C5D25F3D0C9BBE7118615AA37B21547255112E590EEC52928173292450ABF2E834F6207751B068200875D7303E3BF7141F28AEC8653A463A774DBC33772849385304B42C99D3E531B0376BEB153A56734887C1CBE59B55BC3CBB32DA63D908345B200CFDD6303F3999BC873DB53342AAE6CCC789B2A4C72C7D08A58FEB9C939A3214AA3B2BD27AB108AA89682E08729CBAF93A68613A8F56B7764C23CF085F6A970D8ABAC213F7314128AA64DA213D5A53D2475F7002A6C354C1181BACAED645FAE9C7509A0B10C8317F714D37F3791C03CE39C79AA0548F88A69DD6F87DD49A8E63307331E00C5C5B5FD7D9804F3C57028C2D3FE65D87BA7C07624FA35754421C4EEA618CDA1C5434B09ACD0754E04439240988EBFB5F6D6A43C0683A287B5686364FB9FC6A62551916046442004CAA42428DAC71EF5879BEBB09C5DC919076620B9701A2D8AF248672E2AC0107C62159511CDE45120AB84993FBBE65022DCAA6369508212D7A915183555181B1B9610DD147516F2496EAB20F727724D7178357F50E23691C29400BF461C389932E2E663FAF31AC53273058BA675CC0C3367C4872383F683A834B4A522B92276F70022153AAF4622F24F439A0D382FBF5059744C487013501D41FE9A99966506F2F5651B3AB0FD0A73C02634DAE9695E850C67B154455AA749922229090B621E259D1F193B524579690262F94C114D9C690E170E526A99F5149A2840129D22C740CB5B2A50AE7809388147B943A4263D50CE72A2FC2FB6EFC85C065502642F015D6B83AAF0880B715983BAC12FED75B1C973046C79F72436A420B790543349B917FC4C3B18DB80A1AD346389180FBB9BBA1A6A8A0F0A62E6C24D580A16580C682553134738D0CC1CE766C13BF74C82EF5C548F79DE19A0F2A9236100A7ADC1B2F1E1B1D0066B9352CCC40663D53B0AF0DF9CCD6353381E5030AC08C3920847F233164DF98AE8AB017EFB305FCC83FBD22EA59EE59BB", + "sk" : "9D897195E7139D5B6B8075AEB5D176B60BBBAD949D5890C707F460341C12A79AC5E18A9126C7C2D0D59456D1CA072034706BC5444519FBEA529B17B3306113F73C840AD3BC015862DE98CE93344A849094EA71A6D5B1742FD2A811D389CA465419CB8AEE9B2DC3961C4723A7BFFC96ACBC79DC4B17C99B4022655D7CCC0A645981B990AD8AB7B9FE6A69B511731C84A2DF77C2BD917F1220235E91AE5FE91E30573DD67A16CCECB18F4B9116958F812C7FBCCCA50ED732B3B946645B409B74BBF34C3769757C0AA0A04D690FC2C14DF10B334C089ADB54CF6B731377D433CAFBA345DBAF06366EDA0975AFF207E0D545A31AADA7F85369B62F7D1983997A542E899AA2651A0F3417B142BF1317AA9B766DE2135546FB2224D5AA298BB4A90B4AA92A11EDE75F441734283A2BACCC2F2B851A6C314E81EA510C7A31F85855FE55CE0656A88EE689339495D5C293F483BC67E49C86644D08D896681CB2D28278DCFBA73C2BC2E050C9E277BA7AAC072724B7C02C2FF0E24A48EC9D8B46298D14657FC74DABF368C6B0272FE3A5AD280130936A2DB57E5D971D18916EC39B9960C73E2BCB5697E9690900B9F25496127A58D50062CE88C0F3AC9DC60B9A9F82406E0B0F7C6898806807F6BB9E0945B7563136CABBCAAC04C6B0EC8EAA60C26FA604B073A0CA8A925AC99BCE9BCE26FC7AB69C9A1509C7AE8C97E006B5B8F3A99DB2850332986D65B17A67A1D2CC80D476CC3A90CD419920E302074925375987CB7D268FF1EB4ADB07CC4D133C381B47C40B42311A8F21881F50EA68343483ED6BBF34344D710C7E0F769ECA3388B84C62688B4CFEC37104F0717CDA20E21B871E267FD275826DA7AA92B372FAC774B1611B18E35DD6DB3E52A58C015A8BADB33C54A60AA4005D55EB16AF7547D217670A621908A9B25BDBAC84753495C244AF191F7D73AC08C94B7C1B522916790A245D6DE2B274250159F89BB47A1E7C0850CB97BC843A7A29E594A5428C2EBBCCA5A989993934B9A36ED1E7561663A8C9D400CCAA7D5CF4484CBBC80DC6B3AC20926B3A49941903C4EB41FB988F0D77A8D26C2C68A14A0162B926F4BD8A26C45E76C706F68BCD738626A2AFD235638F6741D229427AB4166920850DB4661D4019FD7BA362065ACED015BA3259EEAAA4ACD2CF8B1189E4E1C4A3D67982D942FF2734E3434A45E842E157103890C7D3510134466884BC16D7078430E2048FCB58FF0717A5E6987999A5400973809C30CBCCA50EFC4ED5C1A37F3A0EC71842D88B35D53C49B040BEA967A8466772E9E3486306A0CBDC449DB2099C349970E8462093B398B7BA10B505A76C4AEDAA4EA661AF1A712A560417CEE26C4B109D8BE72B88467752F5CEFCC752AB3C324D2684B1145F4E7715E9D98F0A1BCD3F1A567676A138213E202AAFBA10C15AC75B45E06A43987D9F6C07DE147E05F42693D12F9A8877A2CBC7F2E81FF9540AC09BC620527E919542FBE53379519F35C70A4E0CA6F0253CAACC2EC83749AEBA42BD4A0FB6902946DA8320EC2E7954BF2A184F94A31E58C505B1D1AB9C3A19AA8A3C1DA7274838C768E21978982F95C41998058C9B58B861B1090A5BC3277A1346F2108DB4C0399454010510677C6C12C76CF7149F35031C8DF3B243140F9716A571F62A5365A0830169B612ABF0075AB40132D51070AEC5566FE953382AC3A3705B8566064AF52B926B765BC039D6F86AB8B27CB93B809E670DA4457BFB8B6BE9AA54D9B2BC94EB0C3E15BA6CE2B08AD229A469312A5CAA04C8A4FCA7C76CF905C6FC4D32127D84981608810A4752B9F26BAA12665BDF30882D2A38200798DE4A5F1D3BBB571085AB091C03E896F25B8759E43795DC83C2069FCB2CAD05B166DEF78D18B920E0E59853C66BCB11795F604963AC3AF33B43F78252E06B39D11449012B0B35BC65C2562A66F7597302377EB13119FB4285D5613D618C2227A8A187B132B08BF5B154745451FA627E0587C24118573F3628E3DA59E96C6A66D26C2880C95EB1ABD96202B3673BD64A74D1B11396AA406D378183325C9D03B8294177D3D6439FA79A2A6457D9F81BA8134BC781C575413E40082C686AC2F59C3FB45A580D3A50ADD274ADD391A09CB6C559623C997DA498C1D002B0F9B5254C26266757849E7598C941333D580A11A1C197617B23D98B7DA60B6AF0521E287F8B0CB21522236395A60AF9CA4DC7120925A4BF497E2ED65BCCE78A33555EA459197BD5A499BC7C2B788872916AB3B961F25094CC96659DB67BFEAB52260456BB775F56E492564456C5D25F3D0C9BBE7118615AA37B21547255112E590EEC52928173292450ABF2E834F6207751B068200875D7303E3BF7141F28AEC8653A463A774DBC33772849385304B42C99D3E531B0376BEB153A56734887C1CBE59B55BC3CBB32DA63D908345B200CFDD6303F3999BC873DB53342AAE6CCC789B2A4C72C7D08A58FEB9C939A3214AA3B2BD27AB108AA89682E08729CBAF93A68613A8F56B7764C23CF085F6A970D8ABAC213F7314128AA64DA213D5A53D2475F7002A6C354C1181BACAED645FAE9C7509A0B10C8317F714D37F3791C03CE39C79AA0548F88A69DD6F87DD49A8E63307331E00C5C5B5FD7D9804F3C57028C2D3FE65D87BA7C07624FA35754421C4EEA618CDA1C5434B09ACD0754E04439240988EBFB5F6D6A43C0683A287B5686364FB9FC6A62551916046442004CAA42428DAC71EF5879BEBB09C5DC919076620B9701A2D8AF248672E2AC0107C62159511CDE45120AB84993FBBE65022DCAA6369508212D7A915183555181B1B9610DD147516F2496EAB20F727724D7178357F50E23691C29400BF461C389932E2E663FAF31AC53273058BA675CC0C3367C4872383F683A834B4A522B92276F70022153AAF4622F24F439A0D382FBF5059744C487013501D41FE9A99966506F2F5651B3AB0FD0A73C02634DAE9695E850C67B154455AA749922229090B621E259D1F193B524579690262F94C114D9C690E170E526A99F5149A2840129D22C740CB5B2A50AE7809388147B943A4263D50CE72A2FC2FB6EFC85C065502642F015D6B83AAF0880B715983BAC12FED75B1C973046C79F72436A420B790543349B917FC4C3B18DB80A1AD346389180FBB9BBA1A6A8A0F0A62E6C24D580A16580C682553134738D0CC1CE766C13BF74C82EF5C548F79DE19A0F2A9236100A7ADC1B2F1E1B1D0066B9352CCC40663D53B0AF0DF9CCD6353381E5030AC08C3920847F233164DF98AE8AB017EFB305FCC83FBD22EA59EE59BB27757389A4A68C898DAB92D0F63C3340DFBA51E00312A05E721932B95B11F6DA11BFE66D2D15C33524F478F9A6BB3AF2A83357197C834D399A8625F761529BE9", + "ek" : "1F83FB4C0594D09EAD297900D0AAB5E506B7EA0E42F26A1776151A34E921C7246841ECE9934F4F5A06D1CF0B7A49B5EE11B369407718D9E3124A0890CD64022374D897F256EFB0E6BA1F408553425F97C0886AA1EB3DD73E2BD4FEA798CDC3A0E3E88C43E43F2D3123DBB0BDB56FAA7307C054EE5781C78D1AAC6039459F53108BC31093418E928C7DB13DD0A767B8BCFD47CD3FCB3EF1D0232B747548F0EE658B6EF5E0ED465D81B206CC4381E7C7961B0EDE59A78137A922170490E81D12279B038E613AB4762AD2D844501812B7C2FA8AB5808455F7E7053931C53A2CF9DF7F9D6BB3C83C3F0B0DB45AEB1E939BF173EBD1280044D222C5469FF2D8B74CDC413B87BD06F6F8C2218AA90B5DAC46F90EFED75DA1E083CBD0B3395885AFE9F5A263A001AB47383D557BFBEE2E0DF0E7D94B7AF06E5117DBA9003A2C7C4CA1665DEB937D6E6CE076DBA0AC7D751D898E0DDD3E2691C94A863DDB7DCD0D4B5A74E30A706AB983E2F8391039CCFF7AAEDC35DB495F4752257D496E4F0006408DE4728D986401F5E4DD8F7FFD5770E2C33964653589EB87DE8D56CDD6FD3F8EA37DA2302E8EF68D2391F8E26C29A02405B55A4DFD5642EDCEBD3BB96C390D446665B88C9079B3C0D62B87E27A1FEFB4D98FB3B81C374F34D05EFE8AB0E4CF4F031E26C835236560F54F3E07972653A4FB668A1A72DA779F6B7E0B9C3ED0A8347BA7B21A7C124733FF496C37A0AB6D0BEE6F137E2298948FA702240460693D4906DFA620348F85119A8755B36A371EFB0362358C7C814A8393FC8924507AFDD44C8F1F97907A396584217CEBA90DC3C2DC02EFD30466FEBF74A745C9E18A4841420E14B473723996C3F5739DF7FE9FB93465C04F2001E210B7508724652843FF3FC87D4633223120F502E093AE94E3EC360BDE3453A26E314B493D6DB03C839D8BA0F1B2BE941612140C7317A9DCECB4D859E1C33F9708DA9A7AFE4C97EFE285CC3AA9768DF26622EDD2B2A56758B2AAA75ED42D658FCB43E7DE0C7A5DEC266E2836AA62B9E133F63DDA1D183FCA81307FB6244DF6F7173FE4B9770F59D90979AA0525FF4D7462CC53D13EF7853758B7FB6F0B82A8215645CCBAA00FAADBACFF2CDD62A7B73AFFD34C119C570570923800111318E5DF8ED1C77ED3C2E45503D11D34030791F2B01FEED86010A7901AAB62F12A207051BF7422D25E0EA8AF9F93E6D8122FA8E74A8DDE15E06B0495CD2D4AA9ED38C13DF7E402F16DFA4345C48ACFDB7655A4EB68711252222C3A60FC07C3B2C649DDC3501610A8803D6A70587040481EEBA2E3CB9777C15C498CC3E0F1CB79C0CB8E3DE2F09907851288D388E5D9BB59BE351202E342BB4507EEF034C25B7A58DFF4C7E336405450E7B462780C8FB355FFF53AC092AF70FE50084B1273D2731F2E981BC5723F6A047DE775CED14B385FABB4450A942A647407E1515EFF076574030604E5976BC4AAF989CF5FCBCAA51727E7647E5F9D3E826F18E0E39EFFEA0D9B0A48FC7A0DEB369FBD7D018CA2D7", + "k" : "C2F40ACA65F1986B39B13E6B6E56738284958707F59656B05AB78D8571C6588B", +}, +{ + "rngSeed" : "81401DB81138D6874E91B7C11D59596E4ACE543F5A3471B6FB00999221765FEC3CA057ABE20F03B2D59003375FD71FE8", + "pk" : "801C4C929171C164522AA3AC2361B8C80B8CD3E644F7D169F9A20380BC575968901ED7783B6969C57461DD879D4781BDA106A913C629BE512788D4C1F92A71F9F819AB7207D1A65499E061C5E0447360B4E70503BD58511E4C3333556B75F6A8945B8661D0572C764C82CA70EC870CCDE0CC5810B816C10A46491E091C75F8B24EB975867E179D38345BDEDC627A725B4D732B7B453D9B15710FE7AFBC55BEB26C77E9E8A58BFA764FA430F1901928FA4EA1EABE2EE827D44191708310B5E708DEA4C5242A8949F658B548A2AD1BADB9A6322C56697B513BC1C29872B56FE1E32D9271B44EA0B43BB896CA9A7358F45E1F1821FCB361C6EA91ABCA91CE95A75588402D1217D1E37A80B3C880AA83C31C5683783E3BC77BC231AFC0172BEB9957FD7228D8589BC171A2FE24757400CC7E9CAB13D90A2CC12B771725E0F2180ACC221FE5879A317FB93A10682044D6E22AC67C0722C1062EE70959333C08AAA16BD9CC1B624405F40B78411BAF7BCB4AF46B80AB021D7C8A02EC8D0417B759CB2DCE94409BE96F5B5ABD1E207A9B906C71C18C763414B2D48D77C19D8E617DC4E41C3328AE39C18AA9ACA985964597686C919584114C4B2429308E123FBE9A8FB86327054817BCA07DF8C7ADB4E2A941742395CB6EA24C6106EB95CC0868F8A6452EFC5AED297D933919B39A8DA93137925B87ADA9A5CBFC5A541C2395BBCA59F95AB2C4A5352831F0D143DAC60B418C2051390396326D49E27B7B6159C43B5DE3E40D05956DAB59088F417302588E38C1A21261C62ABC8891E44EC4C7395421AC09E1B448BC2349DC88C571C74E470474935EC58001BE48B854A13D9855B8C87131985C91484A695CE9931267C1D0D0B9CEB4BC7C4A11676C267958566D59431A630D4ECAA8BEB98BAFD22172A30E14C9ACDBA26922F0AAE067C9A0E9B658630873139B9555B63A73BF8C65319D9423D4A927ABE86A95B383A7C0C8C54170DCC70A535B1FD814CB6C87900EA94EED7B51CBA571DC7B5E6370BF4928BBB27B1F66D770E43CBBF3EC0C615521E2B8ADDDB42971A12DB3A208F6B690289B059913760471367B4154113C14606C046A9591AA744683C4024B857293EB0E02EC7C75270C571248C0AACFA7E47A35E72157877847DB1EFD73C0922CB211C4538D018C05382E9C97C3D98CB375F78D056196466519BAF3312559315796CE3504731E811432A83294D75D8365391FB348F0136A7FD90921FC3844F57D286845D6D663E855B50D884F511A2020B09048298DC4DA2BE4A8398D260CA4735D84F2B66B2405D48032CF3174FB36B325E723AF241D280863B4D2099FB429C0414433786D33F880D7A15D3FE019E75861C7836490CA2A5B0771ECF904F794C746B4244D99226899C847814967454D7A4AA0FA743E2D2838BC9461446B61D9B006B4240098F37021C7631131A84BD75D33374B9067AFF5E900C4D0490995875606A7BAF87B8F4960DC84A7EBA96F4055AB6043C9FAB61FBED883705893AA89899AB975284867F63035A392902A779C8DF9CC63A1B944943691B770A9646CC731A93F6CB3DC3B183B71429770032D08A778217F9B72BB16CA81F07C66D436396038372AEB8EDC031083D95399084751BB9F3D32490393B510796C16C630CD2D7E0666CAB62B5D904B", + "sk" : "F789391672B25E088E06AB6E0167CBFD56B01C01876CC67EA0CB13A4491472C4710F9CAFB5D1068C207FA9875879DCBF60E78BB6236F2F00BC77F81B98D74DA1F3354DE5007C0B5243D15DC87282F2B2C298A5324F35CD2E6327A7008C51D2815D833E17F09B91A047D15B25E0C9782D34BC474A973EBB1585A23BDC22811448299A0A6D42669B31951DA1F949E8573292089BF6B0B866F4CEA0BB110FA5435550C11C477622B6C859691BE5683198C198D2960F8932606DC3310F3193663ABF161BCC6E1521A3C527B946A8CD20BB9C4B0627E9778E521ED5EBB7D727C79B687214C1C55B9A5DA230598EC71DAD4AB1833911E991531F0A32ED2A773D05A9C166CD4CF4C625F3665BC80BF1D46F88560800EC2C04A92FAD947E406B8A14061642D879B6F14A4B2651D3E1C502322B256A7C0FE403038125C9F5412B5C0FB62BBC8EE41DCF071C5236C4D54621010A088970C956A5588696412D75B9E6F5A920481349634956A9A097CC8A0A5897A6FB60CC103AA1136131C5B30F4469A73C52D43578DF35914D5436818A16D3EB44EF9760922C354356279B793A05A93214AC499B454E4B66AC1C1188E0C8375D0221C8B80012F21305B57AB023B822BA5DE2D96F4BC0A2420CCC8AFB3D9A983A59A46D4A32C3EE764B0D696669EA5B458816BE782F3DB39DF35B6624A59F092782C886806D8503EA4C177E7385FED9C8D7416BBB9708CF8CC32A2B3E198B2C93BBBEBB7AAF53F811CE50CBF173A92580861AF698451C77FE1556D79A486DC75DBDFA3A09EB150F477C87857B0352418C4A66C57A0F73F60A16941CA247B4981C4AEBD24985062B1FBB2F85323F87F248A71657760C8766900A1F260F2F9B2A4BB1073746AC6B73998B6171597B9D7FC42B873271801B6DD111162F7B2FFB55B044E08983F6AE95F731D0C32FB8D3108D4A048255A42EE290D33031521B46579C864CC04652E59252A3BCF315577C31695D6C8E44517B5FF76A75ACC608B180A6D10842C4C92AA0AC13A5515D6C21EF25CDD3F81556F336F1DA4E7FB89B73C195DFD5C772B5ABF20223CE84C297B32E57A1467225314C37A27EB43F0DF947B8BAA3CD38B6C5CB2E5A99CC35B9637FDB1EA82C5FC3AB3C9DB9CC9491B6095C499A2377A698B5B77799B1D00412D0C258D48E86801BF267CB01F17D335BBF4406463ED9C6575B10BA16622C888517579D68129603B0BDFD8284351183B6114CE424557EEA2D2986BC238C85D2A1443AF19B8D7051E84AC6ECFA8339D22DEB23472A856B3056CD5B280C3F395F2B2370DF8752827602D64BC033B26B1970C9C8F020D41C15736190DB9A5BA1A87AFE9575E7918E502382D9F763BC3C5B7313C8539564DF19C1DEAB0FF7AC7D3C48981E5AB31691C0A52C4818611456481668BA8612F410B78C21A68505335B8F4519C7BAB53328A700763A6D95163F75DC2BA489CCF92CB2ED1B72F2D904A54C35AA0C8397BB06CD676B28CB6D1E44502550C9D259A05204272B93600B09244423A63B4C753B69529D2B3D16114A836273FC702F17FCC046D7205E47C0903541F519641981576409A35FDA1E3E76CCEB8109EF446338424AA13A741B38ACFEA91A1C4795925026801C4C929171C164522AA3AC2361B8C80B8CD3E644F7D169F9A20380BC575968901ED7783B6969C57461DD879D4781BDA106A913C629BE512788D4C1F92A71F9F819AB7207D1A65499E061C5E0447360B4E70503BD58511E4C3333556B75F6A8945B8661D0572C764C82CA70EC870CCDE0CC5810B816C10A46491E091C75F8B24EB975867E179D38345BDEDC627A725B4D732B7B453D9B15710FE7AFBC55BEB26C77E9E8A58BFA764FA430F1901928FA4EA1EABE2EE827D44191708310B5E708DEA4C5242A8949F658B548A2AD1BADB9A6322C56697B513BC1C29872B56FE1E32D9271B44EA0B43BB896CA9A7358F45E1F1821FCB361C6EA91ABCA91CE95A75588402D1217D1E37A80B3C880AA83C31C5683783E3BC77BC231AFC0172BEB9957FD7228D8589BC171A2FE24757400CC7E9CAB13D90A2CC12B771725E0F2180ACC221FE5879A317FB93A10682044D6E22AC67C0722C1062EE70959333C08AAA16BD9CC1B624405F40B78411BAF7BCB4AF46B80AB021D7C8A02EC8D0417B759CB2DCE94409BE96F5B5ABD1E207A9B906C71C18C763414B2D48D77C19D8E617DC4E41C3328AE39C18AA9ACA985964597686C919584114C4B2429308E123FBE9A8FB86327054817BCA07DF8C7ADB4E2A941742395CB6EA24C6106EB95CC0868F8A6452EFC5AED297D933919B39A8DA93137925B87ADA9A5CBFC5A541C2395BBCA59F95AB2C4A5352831F0D143DAC60B418C2051390396326D49E27B7B6159C43B5DE3E40D05956DAB59088F417302588E38C1A21261C62ABC8891E44EC4C7395421AC09E1B448BC2349DC88C571C74E470474935EC58001BE48B854A13D9855B8C87131985C91484A695CE9931267C1D0D0B9CEB4BC7C4A11676C267958566D59431A630D4ECAA8BEB98BAFD22172A30E14C9ACDBA26922F0AAE067C9A0E9B658630873139B9555B63A73BF8C65319D9423D4A927ABE86A95B383A7C0C8C54170DCC70A535B1FD814CB6C87900EA94EED7B51CBA571DC7B5E6370BF4928BBB27B1F66D770E43CBBF3EC0C615521E2B8ADDDB42971A12DB3A208F6B690289B059913760471367B4154113C14606C046A9591AA744683C4024B857293EB0E02EC7C75270C571248C0AACFA7E47A35E72157877847DB1EFD73C0922CB211C4538D018C05382E9C97C3D98CB375F78D056196466519BAF3312559315796CE3504731E811432A83294D75D8365391FB348F0136A7FD90921FC3844F57D286845D6D663E855B50D884F511A2020B09048298DC4DA2BE4A8398D260CA4735D84F2B66B2405D48032CF3174FB36B325E723AF241D280863B4D2099FB429C0414433786D33F880D7A15D3FE019E75861C7836490CA2A5B0771ECF904F794C746B4244D99226899C847814967454D7A4AA0FA743E2D2838BC9461446B61D9B006B4240098F37021C7631131A84BD75D33374B9067AFF5E900C4D0490995875606A7BAF87B8F4960DC84A7EBA96F4055AB6043C9FAB61FBED883705893AA89899AB975284867F63035A392902A779C8DF9CC63A1B944943691B770A9646CC731A93F6CB3DC3B183B71429770032D08A778217F9B72BB16CA81F07C66D436396038372AEB8EDC031083D95399084751BB9F3D32490393B510796C16C630CD2D7E0666CAB62B5D904BEFE6E93D8E755292FA875609F2F63BD194C87E6F04DB7C83D8BB1B9D868BB77910EFE801AE61866A7109F40ED932E67B0AE9E966D1EC5F917E4A9F31A27EE13D", + "ek" : "71C2FC6A3550872B3EE96379A2BBBB7DD471B7BD4AAAB2A93A75C69F67DC52E435FC35A7F0E3C200B115E3C939D241ACEB7CF653AB7A4C74B2AAD2CC3F18D0493672A54505F36AC96ABEB1B95DCC81F4B60415C14E709FB6D54E3AB3CE2502FB11504E39A8509C5DB55D1DA516D211339A50CC06E69463BC49868F735245D13961B795423F451BAE33D3841082B4D9871060B4DA635C5FD50C43AB761053B0A8509F2E7A8C567235CFD18CAA7E29DE8849AD389D0B1765AD53FEE869703E25A39B08EE31228E60FF1C4F76A6C6D8BFCAE56084B08CDBF6E7EFCD69F7E300DAA0FCC3BCFED4A6BC6C96F8BB61399B740BB2D2E14251114EE92666C0DE958FD5D126FDA46CB6504950E33A4524C027BEF33C568591690B5644166EC4D91DDB9FE2572529C0C125459BA00D54A0EACD045EEEA7BBFC91C103D86E02015526839C4FC5F5E72169BBD4CAB060C5960D636B7BB1D6864FF161635F73CAA42B74137F10A0020A33585BD5829A3228C4EA81A4B7EA71FA16AF61EB5C6836B538FB9F92765C53EE6521E6AA689000157AD71B93D413B2CEB3E7EE071FF1BDCBC257A2AA72B454E42424EF23C382895430B4A9FD85449A1C57156A7A6630B5B614EE7B8F2F6672FFB59DBE6789D1B6ED2629CCF3D8E7F91E1392CEA96E4C297B6B821BC6A093E0751B95BADD9CD8534F5D286DA963F703AB0B01D0C5588FBF4B7153DF1FF9FF7E1D4F27BA858D5BA2002F0010724C8D1C38BFDC5D3B74B9A73B3BBDB6E080B86B8984E190E9B06EA5904259E1437214B725DEF7D684674261646A6F21141D4D56815C666042DF3B9EBD8953A73EC18DA1276AFA021EFD97AFF71158211A73CCA7CE2CA678467D84F852BECB49212D6A29D1060AA923BEE894C28FAA69AFFD87DBCA87A17E21D8462D8920074F463F5379E8DA95CFE5C049DA8A1F72C50559E6ABC72B8D96D649C3FDB4F10FBD9990D403CAC54BB7E1490F6B1FA6F4889A87630138496EFFA230D59157AC3A73ABF21F2DD52F4E1424C272DA278AFE2B1668DC8C097DE6D0F7048E507E889878E493C77F67DDFE52A0D70844A55E01802D8A66432638DA7BADF99DE0ADFC66EFFB690FB2BAFB80FF776E1BE66D0CCA5327058E08FFD50A80C28C9AC7507156DADFF6BE3B33F04DB4F3DCDACFC246A14790F86F4F8A550C1C6D8806899EFD0EBC393F855EE5A62AC697DBF234C6D64DFDEBD3BF0094696E69625C064DA7AD3A369B230876DC8857D5E79ACD18906CACD5D542A53EAD70174F305A7FCCD288DF09AEA6F0FFC16C1E61EF6DFEB32C1B629F3848F8A1AB3F5E94BB44D2578B2F2DF5160568CC9F1BD45E0A2730730FA41C5A33A18F71F0EF08BA2E4B8C8F31A5A12D60FE137544ACAC58792DBACBB8B968EF402AB485B05FC8A51610F80A29AB6021F0E074739F207C3FBDBE07A07A6903AA31CD166D975879B5D93142A82F3F6AFB50AFAD64D880BCD1662EF141592A2BFE249BE4477757EEC5B56F021CFEB87634F05457E1D255A825C5FF956DF80D5F28BBC7", + "k" : "4707BEDD4EDDD05980E10B80E3C824B53571D0F61B9A59598AC5BF0AEBF2F3CD", +}, +{ + "rngSeed" : "30B5DE5B73681EC08AAA03F6F2D2169525D25F4042A5E3695A20A52CA54927B85F8BB948FC21DF7DEFC3910B28674994", + "pk" : "DAF0B0019241E200929C660CF7770E111043C8DC4AF1014F7CEBA48A445815408B2823666C6B40684616D823C86787A412C26E521AC8C16868D7EB5646909027820444B8BFF59AB46086631D5A0761A75A79D76468B74FD8C20CB9784929F2A78AD1882A094619325CDFD05DE5A30D622551C840AC79B0B5B7A513F702CF58333F8B0382CE055A4C138C80764B8F882CF14324015212034581B2876EFBC3AE9687CDD7F2ACB964CC18BA90005730D55673BD519BE3173D3E231166C7AC0193A4FD26085BCC6607D4A6F73367EFB5AC1A1A063FAC0207766DA41901B8A61EC7E45BCDB73584B5891EF112251A84E9C07AE7C16F52362CEF10AA3CD69927DB4175BA47E225A220DC2653A58DC9854210087ECC2486AB13408F92BF902635D2AC331EC1C95402BB55B73B5CF063D3885FD1874D5B03100A993EACA11E978393FF33A31B6A98F72479AD9B88D3D1395C2726ED285B793C489E09A8A7BC744B361EC87427C399290D092A1D58A5007AB2209044895941088A81B1B44175BA3E7B038ED17B1B0CD5BBDD1BBEA3F58812A51AE58216B1C18907F131A80897353A328435B927D377A45A6BE2310CB22076CC428371D4B772EBCEAD61C765C875312CC91E73B20BE811706CAA4B52B089EA1E43D7B61CF4B705C1B7B3739FB92C53268A685C03723B4BC316F679F4D8B87375A4188382E711B1911502E502A3F523BD5531B30298815717CE2211283CD675EF106AC5D4C37A6809D7E3BF3E3C40C6C5092C34198659849713C090DB27C78689C6D57DDC90C04BF1AF5CD56B11C013EE7126958ABA8BA7284ED58828F1384786379EB0BB2B8C50A504A3B0FB83EB5964ED6C20B908731CA5C13D980D9A1C0AF7C7527DA50262C65F7C2132355AACEBC1AE5FA7059E7310D6D95DA97871C50A17C0D1C68DCB6BD7A9A697B9BD9BF15A643748C83BC8B244058F0C93E7D1A99111AC6F046A5CD1713D977650935CA5925D6E10C84C7AC692527E27C8465EA46FCE97C64DC66EB1110188C7A3AFBC94C1423A845B3530E35540805C881B999A6B28EF185273E584B9ACAF26746829FC6B1C88AC03578F98E71B67F5101DE2233C841D2F303C52A500B3D1BBCA883FE49B5A233B270BDCA755658448666DFF384EFC9CB26A664106C49AA46C4237D9AE0EF37DF159A0C9E880D7247566113C12BC4451F4C6B4946CF76C7B57F737032741A3047934B09E697ACB2210B05B17047EA8A460E4CD9E7068B4202A8912812A04286208202DE04D0C91B9D62992DE76497DD0986917592E9902F33C4999916576ECA4BC8495FC7233EA94671A3588ADBA1355804F1C475EBD788D683967AAF9B07A3CC9EC4C2C91A61E0456C18DDA1A238132D2EABFF8002C0EA6AD88D3AE3F4769E298AAF954550FA3CF86944184DA2CC7303F1BE393B6580CDC1A0E55BC3BE7300166D570FC4B8644156CFD6C8975C29059C7A550D4B63D242B3E11B887A31BF764A911AC62801A6845D6589B0ACC55E4C80CB37A3784AB8C048ABE21204B152069FBA2D6B75CAD8AB3F133678889A99D346E3B49C0C41147DEAAC27BFB7C8AA3810E3B74BC0B205F02753A48457BD4B7B624A3FBA1443217A88C65C5F63A0793951666453692C56B790391A7C9297E5224771C7A441D5363741DCE698C33558C584F", + "sk" : "0FE71CED368F0F36B7B8F1BE4802AB897C8919617030A5381945883B69BA1B456A2704C52D3A24A3DC3E8C35C09655CFD6C2C0F14489A1DB0A991CBCFDA5B52D708FE30229C272ACDAA3B7577CAE68845776579ACE017B2C0112ADCC57CE39265EEB0C5B2585EF868B6BB56A74089FE2373294298809D820499342C7FC5343B85493F30E773668C790AA55234AE7A230FE2CABED5A55D4699B6E14155F5793300676533C230F529F8C762FF0520DDB9B78894C241181B69BB09E3F7645391367499C707CB4454353B8F6D86FEFD8A3383B00D35089D6A62BE348645D8C03D5E815810894B0E962E1C5303FA5580B8483B8556F55A62D49DA3257F63E03533C10B74190134F1CF3530C025BB0035896628927E8C3C926B27AC05265EC90DA933104232B0EACA457C9131F95069F40141DB8239C483CFCCC26A2F41F5B7533BCC26F4AE13EBD26986227BC4501A3F5D74D11DA48BF1336A8483678A4BE53154BCBB62D609733FA678FC2F946CA4C5DE03741AD6B5BECBA4A9688C455C81B4AA528C2515C9CD33C2D071C1CD96B5B483797E9616B43BBEE62088E5987ECEB1A7B3217A31C37494568B40B453147644FF6B199465266911342B3CC7026B62338413827B51AA16EA0066C0E4228D0887775B89C4858A46E018E5368CCDAC224BA600EC8329B0A75150B82B51FDC5EEDCACB9589C870B48F02338DD3BB99501A6C6580BA52DC4F98B66564736C3F9BA887EB0351B60DF54057245C8098DC440E76100D4A4D572A7F34F80D5742833F41A3BB9508359801ED187B2E94A97472C9DA7374D33AB4BD425C7592CD0EB155F1D90FF1A03867599FA4C693472233F2F8C5CF86C89BE5921E607566C226C515CC27447D7C6970EEE6851FF06238CA9B8B18058F77357590B6E88B5CDD2C1CA7E477B25A21B2A586BA231DFF318F972A1805B280DF4445545A8C874053F740B462725007748DEA3866DF03C1B68B4D3EAB9984837F0958A905EA14403A1F135C4EAE2299ACBC5986DC0CABE31DE5459188365BB20AA917894967B39D535B5A022C5F2D02CF6431AFFF02B9A52162622249871B537E10CB53AA14D301B0AB13216528893B08BDF9145BC56451FD251DD0A926357303860909A1E132FFB58288752EB9CB5629591247D3456113279CA92DCE372F877A42802C1DCDF175C2DC159A082C0727122618761D667B80A272244AC8B34B56004580627BA261749849C0A5986494BA851DCBB0BEC8A75B1355656A824A6F37BCE21CBEB1F5A36FB1639EE743FAE1CE0CEBB973D2A0E6AC024F434FAC8882715146A5D0CF3F3AC4A6374A672B3DCC122F2CCC37D4D8A60FE34613E2B5F828674C8216EAF0402F319E3FBCC1BC9620CA698B42821312289A2F511733611AC45B0D1354B7FC815AFBDC7AD8AB14F1E43F7FF73EB626944B97044021761D352468CB334E1ABEE2E7A7D07751A34B35C9F2492F258791763BE524A00E37A3CBD31C86371CFB71388FEA7E67A85C3914892D216AEC165EEDE03CD02233A5C97AF27C5EE0219C8FEA7364933FDA62A3702A05C207527D79A4AA44277E3AC03874C14588BC60F32B5CF60226D15377884C1B37272507915FE97BE0C4AA282560BA5B2DDAF0B0019241E200929C660CF7770E111043C8DC4AF1014F7CEBA48A445815408B2823666C6B40684616D823C86787A412C26E521AC8C16868D7EB5646909027820444B8BFF59AB46086631D5A0761A75A79D76468B74FD8C20CB9784929F2A78AD1882A094619325CDFD05DE5A30D622551C840AC79B0B5B7A513F702CF58333F8B0382CE055A4C138C80764B8F882CF14324015212034581B2876EFBC3AE9687CDD7F2ACB964CC18BA90005730D55673BD519BE3173D3E231166C7AC0193A4FD26085BCC6607D4A6F73367EFB5AC1A1A063FAC0207766DA41901B8A61EC7E45BCDB73584B5891EF112251A84E9C07AE7C16F52362CEF10AA3CD69927DB4175BA47E225A220DC2653A58DC9854210087ECC2486AB13408F92BF902635D2AC331EC1C95402BB55B73B5CF063D3885FD1874D5B03100A993EACA11E978393FF33A31B6A98F72479AD9B88D3D1395C2726ED285B793C489E09A8A7BC744B361EC87427C399290D092A1D58A5007AB2209044895941088A81B1B44175BA3E7B038ED17B1B0CD5BBDD1BBEA3F58812A51AE58216B1C18907F131A80897353A328435B927D377A45A6BE2310CB22076CC428371D4B772EBCEAD61C765C875312CC91E73B20BE811706CAA4B52B089EA1E43D7B61CF4B705C1B7B3739FB92C53268A685C03723B4BC316F679F4D8B87375A4188382E711B1911502E502A3F523BD5531B30298815717CE2211283CD675EF106AC5D4C37A6809D7E3BF3E3C40C6C5092C34198659849713C090DB27C78689C6D57DDC90C04BF1AF5CD56B11C013EE7126958ABA8BA7284ED58828F1384786379EB0BB2B8C50A504A3B0FB83EB5964ED6C20B908731CA5C13D980D9A1C0AF7C7527DA50262C65F7C2132355AACEBC1AE5FA7059E7310D6D95DA97871C50A17C0D1C68DCB6BD7A9A697B9BD9BF15A643748C83BC8B244058F0C93E7D1A99111AC6F046A5CD1713D977650935CA5925D6E10C84C7AC692527E27C8465EA46FCE97C64DC66EB1110188C7A3AFBC94C1423A845B3530E35540805C881B999A6B28EF185273E584B9ACAF26746829FC6B1C88AC03578F98E71B67F5101DE2233C841D2F303C52A500B3D1BBCA883FE49B5A233B270BDCA755658448666DFF384EFC9CB26A664106C49AA46C4237D9AE0EF37DF159A0C9E880D7247566113C12BC4451F4C6B4946CF76C7B57F737032741A3047934B09E697ACB2210B05B17047EA8A460E4CD9E7068B4202A8912812A04286208202DE04D0C91B9D62992DE76497DD0986917592E9902F33C4999916576ECA4BC8495FC7233EA94671A3588ADBA1355804F1C475EBD788D683967AAF9B07A3CC9EC4C2C91A61E0456C18DDA1A238132D2EABFF8002C0EA6AD88D3AE3F4769E298AAF954550FA3CF86944184DA2CC7303F1BE393B6580CDC1A0E55BC3BE7300166D570FC4B8644156CFD6C8975C29059C7A550D4B63D242B3E11B887A31BF764A911AC62801A6845D6589B0ACC55E4C80CB37A3784AB8C048ABE21204B152069FBA2D6B75CAD8AB3F133678889A99D346E3B49C0C41147DEAAC27BFB7C8AA3810E3B74BC0B205F02753A48457BD4B7B624A3FBA1443217A88C65C5F63A0793951666453692C56B790391A7C9297E5224771C7A441D5363741DCE698C33558C584F87ADA29BF78A689417B645FE127D124339422BE80A993E623D13BC59F3406A6F921BBFBFCC283E1D1DB36E99B9CC6CCFFFBFDB86DAB7B6C7CA02CDA227DA8632", + "ek" : "1D5B13BEABB5E443D96D46D2B9B7A6AD1B5E4925E2E72195896971F2786670A2D844D41A5622F4F924458A5094F6F65CF123A83C010FE38507E4C3D0DCAC1EF984FB33571FEB7E98F9129E16BBACEB73BE5310110F004220084406812792627255D6885D9AF33AA5F39536D66F1FB44E9DA9379DA13DBF8DD7F5CE99B8FB04CA575320C07D969BA8DB476223DAE3496E356E49875FB43D9BA34594DFE02B0BD3ACA239DDC5B81493F814FC948125793A4E5FEE1684D0867C73DAFC3DA0BE13C7267BCB89CCFA8A683098B5F49874F96AA4622C6BC40C0FA32E4556584E005107DBC3AADF3DFF4B938265630DE05BFEDDC0FD4351CF8D50D94AB532E466E55204DAEF3F0626E5F0A25FED440265613BAF154976AAEABE54DD854E4F247A73FED436DD91C80289207512C0A6EA5ED98D9F07812EBE45EB1E7130406FA07195E2A6B5D8980E9DDBFCC552BC9A502268ED1A5BBC3F0ACB66C84178F963DCC550C40076099171E911C4AC2DDD9A095ECC022C727CFFCB903BA4E7D0C8D2990C48720D7BCD744BD87798E81FA8F21D22076039845B7F7267A43D6D420CD0294F71D71E974EAF11D6BE4E74B5257F958E1C7A3C5E3274EED7A6836F04D5945420A1697A7F4CC7769FEB4DFA9F82E8B1633782A54BC79A5495FD4062445D763B611FD91B6CB6A3C52165F6E20D160078BF376B5DDCB726DC16A3B7378D3B6C6CB8A64F0FBF88563138A0330E315576AC8D4041495D0743C322A4E0E72AFE7E8451788A758C68BE59157E25017D84809492F0A2057C8D03ED1B714380328470B24AB21DF4E1D705412294E5D4F7B5BAF19BED51D2393F930348099ABB3D0F1F99686E656375150D5A1F17DAAADD5B0A1150660424F20F3E8D8B201E4CCA8D2FE11194DF6EBB8131E89FD0587B32831314D2308B059748CCA6A19F7431B4759C1862375111CC8B549D012BA669F174EA3B85BD3C35CB2C6E8CCB68E14443B34C56C03DDBE548A4072001AF35B13AED749FFA8B26734AE815802D9153DA02E68F9E1514700E9CF7C4B44378FBB739510ED5A76A9E3A6BFF0F85B282015101A2E7FC0B0020738AF1EBD22760E131F895AF21082F7A057EFC1CBF54C251E2979317ADC2FDC694D22F2CEB5680FD2AF1334082F3F2D18BC3A17E14582AE8E251E71DFD3A16F3604F74EBC3A0749BECAA8729452F30C3CB2DA0374B69A9004170B5A8B66524451BAB59B0451996BA3A66C05961B541707E207D7861D6EA3E5C4A1CDE57436FF8E1D9FC116D4B436FB9E1D91C664B3BCEFF6BA7EE6E14F121975B78712701866B0B30F71347EC372B4A0585433C1982B0C85BFB4F03F38E6EF8A7A73DD53DAF31FDCFCA94C22C66910A13F066D759C8B20D39F2EFB3AC3B3603F8A1094EAA42C93F8D53919C0D26B8FF960E7D8EB04F96AB60E718E467B0BBCB611321298662C2B24C1E84856A36032511FD1B10311847A9E31DD94203741FDD2953DC647383670DD00A2B646A6F680D6F45AA9D2CAF7AF19CA337D96BAE18B579420500C669EB5A", + "k" : "055FE45C081D14192B35983F8548C276CAAC48AB6980E527F14B97231F516EBE", +}, +{ + "rngSeed" : "E335DF8FC0D890588C3E305AC92C7160FF199E07C85760A828933750E3FED8C83B0DBE802234481ECF890A32D7A2884F", + "pk" : "670855BCFA888F30A50035208F5A75DE6A8E3799CC4AFAA7AEE007788547E7B79C7507BED6A8522BE18743C101463C9D0C28328A68B0D3EC380D04A20A31AB8CE6465E5AAB4E2332F30870C5024718B1412C13B7094228E6F3A1A32440EDBA8F5CA66D968961A3F28705B9778713CD96974E42A50EE9EB61EBA399CBCBCCFC8786F7963C15D61EF8D194CCF37DB2E16A31CB57BA79C9AA4A5DA2593EB56C29498AB66F370D7B76971F797F9CD38AC3262226A64F91E03A1119B8EEA00C103358572A1F4AB68F8EB4A5F889540913B23FF11768200694597D19218A2C30C3C25829467AC2D1B67F85D37522B22E7E44B950D152A8E087A3A35E3EB1C41FB15C7FC264C39272F01A0A2A91324A1CCBEC627FA1AC81EDB30CE0F84A727B36A4F9015A25AC67E3C76629C2347C2478D61B42BC413F6920F7B6774542BF25B92A7715745120AC1C4226E3B623860B4A42566829317E09D5868719A1E9BABFFBA9517AC95A7C020882939CCA54005F94791F37093EAB5F2D15C1E7A09B9EC7B3738A197977C3CA0BAF9F093271D00387841F2AB98C9CB16F19272D5E4B8D15E69DA97517CF833475336D8850B5C3C87E4EF2C526B95E75060DC52C0292EB69E3F04294C854BFAA0F0FD5432DAC0FBD03414B5A4A3B7C7CF36906FEE8BE6479C193B7336F4C870ACA768D3AC2D84234B330A1F160B105214D469C8C1529BF31B3AAC01A3EE1E231F389A27D4340B35A463AD002A7F8327DD5ABED8B4256E87129B1BE8AC475C32B97D11397DB247A019533ACB1A61C15B9AA4BC91D45AF064A608B1926C93ACB18B7C75D9798569A89A78463B51B5BBF038DAE3C5CD133690AE80C1AD4541267BC10C83343A12439D6844B931A1CC79A0B5090214CA721F61E633600E8F76DB52274C6C736E4C8B63089014A4012015522A9385F863507B1F1CC7C814CB47B00395724D601AD7BB27E4B0C43DEAB0664CC858D4A74576642EAB3C76C211A58274E14F615FFE70084D7B7C0189D4D97A927A8B008B85888C57A0F6A307234344A5960836CBF6F4473AD988429A4AE3BA697BF07429D17C059A65D9E35A845735BA0A58E989307376C1E61F33023221A6611CA0465BE5200363D49C53CD44B003307E5CC0C4F7B15E1545C72A7C3410BA1BEBC8F7314B3B9D295C676BFE6ABA9848554FDEC9192F808329C60A793754BD6256CD030DA12BCE0D0765E51548AAB0985AC86D1537BA49635641B3A26C05DEF260E94593B2E0558567C5DA09B2CB122655BC4CD3E985EEDA6C3F4322765E6A808CA387CC369DC11C9DFAB64D4A30584E5329C905DC480801DD57D9AC8AB4087967177CB3163CF3E934A951A3E248A54CB922B6CA6CE9B4CB8BD788023E6425E75AEDCC135CD3C59920C5ED0356FC0FB5A1EC0035B7C8271726DC8D63DBAB3C78326A26C5B0F9F952CDE7373AECA36CF6A438FB39C38A56124171593EA3BB076320BC8B5E74204777B7120BA97C3E803560605CF80C39324A0E3045D0F687E8F219A2CE70AAC209B86D869FEBC5B51398341827204AC584C6B3381471937E68EFBE5866A8569838251171647B4127514DB9B84482D5B9A89119761C7F6508A099961376D6AE3706F6CA1C7C031F430190D6231425B14C6544CABE8701F8E475892FE31B587AA42D334FD189BDF", + "sk" : "3937043D61A4126A8C1AE01AB274B31B8424ED88CD180029BE89CF1EA58B2A6325FFE8627B7BC4E3E8A4B3C60FC42573225946CA400235BB54494A386EEAAE44F7BB8896C4F040836110C4B5796985108D116A76E05C984CFB2A9170811E7CB4C41A12E3601B9FB24BBD3CC0132C22D814BB98F049A8C155E38C242C2156C8B058EAC343C77B11F550C52E9207A25213B40648FC70872ED8C050920C4C078A9B4576B60909BCE496289168114A24111B7D15F10C06D7B719AC4C4872756D760970132BF15B08972C78F4F1A5A6A15364C0ACA1C4721B3C82777878A861B751ABA6A1EB75172C952B017ED03C9007541110A935207B037AA7296E73B998597240B60115333E50BA0C6B837C4CF26A027470770358A537481675A7FB7CCCB901CE7836B75B010FD687691E96487BDA2664756FD6057FFB122F69B26E3FB3BA2625B9FD9C41F4887CD0124DF978BDC26B0C6F3B0F9416C38B2145361343C2F2B752C7A885586E4AC9955FF924D2365847C22E06C6556B7858F0D9318C037E03536CE9C5A16220967AC1C55E6C61F00A5902322C8B35BD190042425249F54A3229F90453B0942AA9A31F421463F514DC64024D5616E653C9E94BBAE8E82FA914863338C65413A33E520243F92F1C3A888EA8121BE984B4E4CFD08285E904C34465BC1477CEF53757B1025B10D45415FA2E57931ECAD301929437B837146FCA445211B5719A933714A1C29B1EB52A3BB36603C072B4EE0B4775D17B7AF9C6049825E2B654E1C4BDD8E56F531406CC5297D2BA2CBF19B8C43835D1C184EAA661D9B90A6E99854787C82D53B794D8624D2406E57693143736BB34284608C8B20A9D99695D8F87AE57C83D095A106E793FB7325B80EB26C8CC345EA2B17ED66E3D437631A018A2C8BB7CBC42761B95F2508F92732BFCF9343C4AC48A935FD9260AE0463BDFA69120EA90F3E9909B2541DA03516F922E1E58411D1492686529CB030E1C9846F63ABD6AE9A781853BCF31AF495ACF79A49767731EBA21A3403140A707C106425C5BFA2CA326247515B229EAC449B01227FB1B228C8637732D818C6579E4A5F0189A23793F8E39C1CAD40AA70A3C6DB8707AA76831DC26A446287D8A4E45EC1FF7EB00782596F7A7AEED5307E5C84039B4231CA6609912C6E4E71DAD93012A21800914997F99970489380E12BE57979CB6E49861C9605D02A14727A17E286B40712233141E2FD5B3834033E2B215EF44AA752201A65334AC223817E290D2C50338A2681D298061586AD704862770867B0493D0941C4925ACDA9B4185B64588E25F1015705A885FAAFB1518A70AB415CAB51A25E3139644F31F1BBC0AB9573BF63230AB125891D58143EA8BCB858C7521100FF581EC7A97B351BBCF5B4161F3141AE78986713D5BC15A57E07F2BBB8244B11D81A0804A18AE63104BF75C755F70AA758997233154BFA942A47277EF20B312A68E96201F227A908DD7BC02E19391F73825DC44CD258B707B6DA20CA56A2B32C0202308357E48945D79A38C0560271FF0AB2E8C1AF246940A797CEF018B62873474A38A595127C026699D625EBF0774334B0A953881FBC1B0F5C472F549818D44B63EA59541A826C49754926135670855BCFA888F30A50035208F5A75DE6A8E3799CC4AFAA7AEE007788547E7B79C7507BED6A8522BE18743C101463C9D0C28328A68B0D3EC380D04A20A31AB8CE6465E5AAB4E2332F30870C5024718B1412C13B7094228E6F3A1A32440EDBA8F5CA66D968961A3F28705B9778713CD96974E42A50EE9EB61EBA399CBCBCCFC8786F7963C15D61EF8D194CCF37DB2E16A31CB57BA79C9AA4A5DA2593EB56C29498AB66F370D7B76971F797F9CD38AC3262226A64F91E03A1119B8EEA00C103358572A1F4AB68F8EB4A5F889540913B23FF11768200694597D19218A2C30C3C25829467AC2D1B67F85D37522B22E7E44B950D152A8E087A3A35E3EB1C41FB15C7FC264C39272F01A0A2A91324A1CCBEC627FA1AC81EDB30CE0F84A727B36A4F9015A25AC67E3C76629C2347C2478D61B42BC413F6920F7B6774542BF25B92A7715745120AC1C4226E3B623860B4A42566829317E09D5868719A1E9BABFFBA9517AC95A7C020882939CCA54005F94791F37093EAB5F2D15C1E7A09B9EC7B3738A197977C3CA0BAF9F093271D00387841F2AB98C9CB16F19272D5E4B8D15E69DA97517CF833475336D8850B5C3C87E4EF2C526B95E75060DC52C0292EB69E3F04294C854BFAA0F0FD5432DAC0FBD03414B5A4A3B7C7CF36906FEE8BE6479C193B7336F4C870ACA768D3AC2D84234B330A1F160B105214D469C8C1529BF31B3AAC01A3EE1E231F389A27D4340B35A463AD002A7F8327DD5ABED8B4256E87129B1BE8AC475C32B97D11397DB247A019533ACB1A61C15B9AA4BC91D45AF064A608B1926C93ACB18B7C75D9798569A89A78463B51B5BBF038DAE3C5CD133690AE80C1AD4541267BC10C83343A12439D6844B931A1CC79A0B5090214CA721F61E633600E8F76DB52274C6C736E4C8B63089014A4012015522A9385F863507B1F1CC7C814CB47B00395724D601AD7BB27E4B0C43DEAB0664CC858D4A74576642EAB3C76C211A58274E14F615FFE70084D7B7C0189D4D97A927A8B008B85888C57A0F6A307234344A5960836CBF6F4473AD988429A4AE3BA697BF07429D17C059A65D9E35A845735BA0A58E989307376C1E61F33023221A6611CA0465BE5200363D49C53CD44B003307E5CC0C4F7B15E1545C72A7C3410BA1BEBC8F7314B3B9D295C676BFE6ABA9848554FDEC9192F808329C60A793754BD6256CD030DA12BCE0D0765E51548AAB0985AC86D1537BA49635641B3A26C05DEF260E94593B2E0558567C5DA09B2CB122655BC4CD3E985EEDA6C3F4322765E6A808CA387CC369DC11C9DFAB64D4A30584E5329C905DC480801DD57D9AC8AB4087967177CB3163CF3E934A951A3E248A54CB922B6CA6CE9B4CB8BD788023E6425E75AEDCC135CD3C59920C5ED0356FC0FB5A1EC0035B7C8271726DC8D63DBAB3C78326A26C5B0F9F952CDE7373AECA36CF6A438FB39C38A56124171593EA3BB076320BC8B5E74204777B7120BA97C3E803560605CF80C39324A0E3045D0F687E8F219A2CE70AAC209B86D869FEBC5B51398341827204AC584C6B3381471937E68EFBE5866A8569838251171647B4127514DB9B84482D5B9A89119761C7F6508A099961376D6AE3706F6CA1C7C031F430190D6231425B14C6544CABE8701F8E475892FE31B587AA42D334FD189BDF0C87BEDD5C16C32CC3867910F734BDCF09869C7604A59CE36660074F561E12DA40B4E01E03F62E5F489C39C78D387BB33B526CEB6907734A5F788209AE3C2647", + "ek" : "46CD71E9D2994B80E695C57A2F1D886F633DDFB5A4506412EC358B651692129AEA503DF123CE27E3A1742530B4DB8EF1931597865878B7F481E734D3AA67C50ED69FACA94B5B89B8C154C5E262E5A8595805670B0BC4D2271BC3276538BB96AB68442A0C4036B46A75581AB0CC284C0F4F86F5D996929F73193B6D6C6DF53C82ED3D68E170BFE48161FFC90525B780AC3273F7072B7CA18721C5CF30F2678F50EBB2F7731CBD442B075FACCB8F85420E9B2BD0219C25E0283F5E0E1135715B827949C76410DB00ECBD9D0100A09CD655663B7ABD3807620A9E6462FDC8B3659531F6F7C5B9836F32FAD78B8322BF0EB8D79623A19786BA8B218CCE91B43B8C27F393AAC96FC714DC4E2BECC1260AE7DC1C5AFC06F176E43ABB4FD523917183EDB1486E87B6C0F82690EBBBB15B9795212E5B50CE35B748377A398526C43748BF9C12F213B6733C5C0332FBDAE075AE57467EA1165F720CC25BA3FAD34209ECC47D94A514A1054321958F6CD4C66BC70C4B8AC4B4032A70DC0FF2722F9512FEA8E8BA99250E79ABDE254959B4A12061AC251EE12D1B1CA7776B23EB27B5E48446B1DB5452EBD0B8F558AE2A940DA836BDD48D9AA298832FDCE5F950BD37CC033EDB124FAC5C72E9EEA0C509EB7FD7AB412683614B496916B594A321E710DDE9B91DE7079828094B4770A867089C06DB5AF480BAED8E5375BB98ED9C8B8F035E228A2947D871704E2902630BEFDDDF3E3E231C00AE7756A4627EF4D80162ADE460ABF18DB743179EE08EEAC5D878D125723C5E0CB64F56382F52C0B8249DCF9A3F6A329F95673F5457BBC21F5B362F274334726443A296C305571589C1C46D6B742E5A37EAAA53341ABD4C28121C03C29D32E4CCB6092B3900BA2EB1CF97FA41491C58D8CE503BD585DBDC5D6639BE1A78FC6AACF7522A54351DBCF4A3BCEE0C03E800E0977081280B63AE7B85076E98632B0D2A0406A1A6C932D2EF51BD252C1F265CAD12CBF403B9693E7E66C1964E946DE9980D0B2F7BD77ACC4D15025DA67E932800B101CA90DA191A1F1CCAA7EEA5214532E8333B756F0F757F9FD0122ACC4ECEA1E53EDAFCD71B4AE51399F0157DD73610F2AF396EDA4893D4207163484072D52757E26C0DC1EB20813C9F517FD1AA98876AD1E752E4C51641C0423CFE6A697197C4EE7A9C4B50E9305DF898E06B4E8F7E5C8F788ED66695230E5735B0D6589BB9712904B166D9888E47282539CF0BE815131FCA85F1D22454413EE1C0CF9192087F355EDF94E72536D5541CBE895FA25652786E57F6DBB2EA39E91F6F596B9C1F1FDC9826F4D6306F682A0869BBB93308C2E9738D78A49F0228430BCDA63FAA6EBDC74F298F8842A65651B05DBF7CB16B218026A30212E53A863C0EEEE22D2CD435C6BA8F4568906E8D70F5157F4EE3B85FD8BB50984242560D1C0D8EDB48E85B6596ECC05FFE5A08DCC13929E52C9FF911DD6CB1519B46927A5F634273495C21985664D31617D4B204BC58842C122E712F8D341D105D1E0237D4A0C577", + "k" : "64CCDCAEA16C41EA70BDFC76AAFBCDCD57D9C3147D0AAA14E0BF8823D8864499", +}, +{ + "rngSeed" : "FBEA1BC2C379F4F8FDCB0DE260D31CDB064C9EA9B1D6DFBE91B3692ADD1D34DEC9C9FFAE7BF5E72ED2743BA3F9F2E43D", + "pk" : "7DC26DB4F73DD1859B06A852E89A4845A0943E5513E8A056DDCC2623034A4EF251E607268997B7E90471D5D0CFBA5639DA844F0C9A7227C8A22A83B9E805942B67019EBC45502C22D369ABBE52A9AA6CBEF78AB914337375D9C075854BC9A3484A0995A239121D918AA64B2AD76C6873790211162509CA2347366D8163803C3433D32068D0F8B64CF38C2370A3546083ED45716DBCA7CEEA50207736FA51C062A6A15AB8C124AB6B00334E03808C858AB4B20A368DF787CDE92169AA4100A2ADBB4699510753B80A63B492C51F43A81BE012FA13405CCBB0DCF1166EF55F450781244420A0AC9301D485AB561B9AB67F5805AFFF924C1F43A5B1628F60BACA631931BFC6C9BB04D0FB3727D7AB6BCD6CADFFE84CA57851EE201F8153AE6D64C0D2AAA432BAAA0539A17E731CF4360EE37C0E38E0CD77CA85E817A827173BD9C0AD253A44FB244F47F956146B4281109297B05A9320953C022024373D60701A68450CCA32883848C4CFF3C64F548CF7912FF61A11F06030C5EB29FBF8BDD2B16541FA85B8683493E8239E22C01383985ACA367D6CBA52C7808FF12B79976B794C70471BA5CC7908E4168D5C916605337F26199C34519236A855EF063423D7777631BDDF164B2375098A25C9FBE9A7F9344AC12AA0B65A1380946560123F82E033FE33638788C82E7ABF79B2C4DF9C6DA2F4301D70465A3C05E3A485A26A3B8D98674D91594F24761F1654580719260C4B409B2FCC418A24082A11140D043A6DEA028DEA1A51E9224FDDAAB5F3AA64564B3C336586DD8587442800EAD481C9D27EF08908B938945B7204557C38AEE2753709B68088684637BD39F1B78C6929C84873822CAA30B2584A02C93B085380524405CAA5D9147E6C837BF0CCB1AEA19DB39471D1A573FD893028479391680282922B11AB4D78B407F7D68EB89B615C32593F2207A4B017FD1CB922778CA806B305600546700D9ECC70CCF292CA7CA0CE6B6FC2A79731F6A9E8B83C9492381AD561F657192BB3867D3CC663BC5FFB48C997403B4814C915616D03CA71D0E8A93EF0ACAB8A55A61A6A58D22845E27D6C453B79391DBE02797D390E262A6BE41CB564152768A5B1F2B7306872BC9DD63327E22E518082AD337F0EB8494EA23E7C730F48E94D21CA9CA3F660D4F960A6285F1E586D04120A083B814EC4229717B23B73C0C14AA6BD45294601BCAA89429814AD6E8A6190289758354043EB6D81842A6F332524DA9E63DC7570865695C043C9EB9C5925BF4C4B15BEE14AA58A09C4D37C822BA891F2626A414D01A10F9FBCBDE5609BF4D982E23392A4CC16C461260BC518717584BFB96E6960B6D4B673F61663BE1B2BABE74D46494CA9576F3200AE3CA8A58DE308D8E99B65384CCC30AA1669898722B1A76C87DCC276474A74C2985E746194844C0E98F811DEC520BB54A1B4572B0C39AD04820F8EA878BAA9CAF03018D4A196C5363F55373EF5A98890C719B7A019D0EB023E319241081694E74BAFDA502529020A8B8F1590B73D1BC36CCBC8D4BB76C44361309977270231A51A7999E65B923B1200366EF381B8FCF8C4C5D3ADD0C465F7DB79F7563DCC67940312CA49981581A798AE477915F078F11023C50EFEF1ACF4F751801BFEAA5EF93FE27771A40A3D377F0F1B1655F6ED13320E", + "sk" : "E2903DED4136AE2736D2F6522417953C15774FD1BF9160B6553B0A6F8810E2208A9205833C5479562AC268B6618787C4859838020A1CF2D16D7F8CCE4F18872C20703522463AE5C2CDEB4952D579A9C2726783562364CF8D86CD1254C76CE667DF6155DDECA4572506240723EC8561D7C65FF953158EF4CB3BE6CE823C5501DB9E29D8C1FC23327B04067F755B87D984348ACB362B22CD416D754B82E52483D8CB422EBA4BA8E649FAF56F30586F09D4ACAC0C3007EC6CA1732EAE602A004B58368785325B06124156248B22D69806B6B2947A75CB16B824D35C7EC26A7A6722C4FB36A5AA538C16E4B6D366344D049B36E53A6980177F3989C301293D3450C8E2ABDBC186972990DD933F9CBA7BA31717BC3126D19A0FC3D090BA37C447DB6143B63383745C866371C426171B667096E46E0C2942D40B4AC2F08F48B136EF09C82EB5BDB13A514876274BB20C6B40A600D1CFA0A8B29DDBCFACA547D1680067786D6E50A64B70546AE3AF52451A08028976BA78B9275A2B011858E0CABFF149F7854ABD2B390D28A661C7A871467A2603C5CE29866839208B5386714618B6A2012FE2B4B9753C8D21BBE74C477F427E72181988D0A094C15A9C24A7EAB46BE919A71FD60879A67480178453F4AED9B63C11040D370322D43B4077E74D8F8966319042C9559B021CCCDB0874009D61E3A3970C14B34A180CDFE0A2F9D5BF60954CB79B5B69169598FC88A9B11EA1287A8CC88F877659577433A97C16AF3CA892D40CDBA7642FC24F258A0207DA5E818580694582B7B7982A7BBB5DE714E7425B7552AEB394037827A98E765D96310D5014A7E69B3DB3B6797BD60650E36E1EBB0342A77576F496A7255D936C5EAB1BA3D9FB57D72305272A5E567C621746720878CDAB13A9F5B0AFA5101A6F7B844AF1BBF660C584205BCECB22A74B79C5B4302F29BBC502B4A3C9854682C8B123A33D949D878B4AE609AC5386AB5896AE2B877338B3200E582F34FA450ADBB27480296B0BC6E0E73C2EC1B633F56D1B8A54EA65AB7CB62E5E4A2C4E82A957194321E1BB39413C3990B74B54CE213008979146C47301E3C8489B257BE7A50AE6D39A5CAC1DAFD41EF2A91B54756779E5A8E5AB79CE481EF9F80195BA808769A158E0B48B52669C01980338042D2A5E21362703827AD9433CFCE6191C7C737DEB92CA3053EAA80D9C9234F54715B31013CDD31AFA49A24993669ADB72CED3C7E3C02C76AAB8BA56A29686A115F4B36DEB2FE00BB42CBB6BA8A825D9888F6347A6E61A7892E06C8FF9B8FBF1270D02BEDDD4268FE4615F9994EF8B93C8615B6A63C9B4D752A46C51EBE9C4D97C160FA27F8CB62AA22344F14339875B6D0F920875C3B831186EE6F04C745756D57B875098A55FC1B060F353F606BB073690546769DC61600A671CAC18B563ACA5E6A8A887EB76BF88A33D814CE9F32DB7CB5CC3D16636493421FBC550AC90A4B99611B39CEF828DBF056C0F5043BE8B003E260610F27A59A2765D57A13D2281D6904526B93D7745B4F8B98085397688AB559D073F88716DFE5A39D09975DE107A3E6C68EE17B3B63A9B10EA6F4531BDB627BB07494F279052CBCA04722BCC0014BB3993219236397DC26DB4F73DD1859B06A852E89A4845A0943E5513E8A056DDCC2623034A4EF251E607268997B7E90471D5D0CFBA5639DA844F0C9A7227C8A22A83B9E805942B67019EBC45502C22D369ABBE52A9AA6CBEF78AB914337375D9C075854BC9A3484A0995A239121D918AA64B2AD76C6873790211162509CA2347366D8163803C3433D32068D0F8B64CF38C2370A3546083ED45716DBCA7CEEA50207736FA51C062A6A15AB8C124AB6B00334E03808C858AB4B20A368DF787CDE92169AA4100A2ADBB4699510753B80A63B492C51F43A81BE012FA13405CCBB0DCF1166EF55F450781244420A0AC9301D485AB561B9AB67F5805AFFF924C1F43A5B1628F60BACA631931BFC6C9BB04D0FB3727D7AB6BCD6CADFFE84CA57851EE201F8153AE6D64C0D2AAA432BAAA0539A17E731CF4360EE37C0E38E0CD77CA85E817A827173BD9C0AD253A44FB244F47F956146B4281109297B05A9320953C022024373D60701A68450CCA32883848C4CFF3C64F548CF7912FF61A11F06030C5EB29FBF8BDD2B16541FA85B8683493E8239E22C01383985ACA367D6CBA52C7808FF12B79976B794C70471BA5CC7908E4168D5C916605337F26199C34519236A855EF063423D7777631BDDF164B2375098A25C9FBE9A7F9344AC12AA0B65A1380946560123F82E033FE33638788C82E7ABF79B2C4DF9C6DA2F4301D70465A3C05E3A485A26A3B8D98674D91594F24761F1654580719260C4B409B2FCC418A24082A11140D043A6DEA028DEA1A51E9224FDDAAB5F3AA64564B3C336586DD8587442800EAD481C9D27EF08908B938945B7204557C38AEE2753709B68088684637BD39F1B78C6929C84873822CAA30B2584A02C93B085380524405CAA5D9147E6C837BF0CCB1AEA19DB39471D1A573FD893028479391680282922B11AB4D78B407F7D68EB89B615C32593F2207A4B017FD1CB922778CA806B305600546700D9ECC70CCF292CA7CA0CE6B6FC2A79731F6A9E8B83C9492381AD561F657192BB3867D3CC663BC5FFB48C997403B4814C915616D03CA71D0E8A93EF0ACAB8A55A61A6A58D22845E27D6C453B79391DBE02797D390E262A6BE41CB564152768A5B1F2B7306872BC9DD63327E22E518082AD337F0EB8494EA23E7C730F48E94D21CA9CA3F660D4F960A6285F1E586D04120A083B814EC4229717B23B73C0C14AA6BD45294601BCAA89429814AD6E8A6190289758354043EB6D81842A6F332524DA9E63DC7570865695C043C9EB9C5925BF4C4B15BEE14AA58A09C4D37C822BA891F2626A414D01A10F9FBCBDE5609BF4D982E23392A4CC16C461260BC518717584BFB96E6960B6D4B673F61663BE1B2BABE74D46494CA9576F3200AE3CA8A58DE308D8E99B65384CCC30AA1669898722B1A76C87DCC276474A74C2985E746194844C0E98F811DEC520BB54A1B4572B0C39AD04820F8EA878BAA9CAF03018D4A196C5363F55373EF5A98890C719B7A019D0EB023E319241081694E74BAFDA502529020A8B8F1590B73D1BC36CCBC8D4BB76C44361309977270231A51A7999E65B923B1200366EF381B8FCF8C4C5D3ADD0C465F7DB79F7563DCC67940312CA49981581A798AE477915F078F11023C50EFEF1ACF4F751801BFEAA5EF93FE27771A40A3D377F0F1B1655F6ED13320E9A9A59F83FC58D7194CCC92BD78A45F97F721A1EB554499D0E4D5B37AEFC23A8870A300648D2B1F1A637374278BC62B5ABB56380CDE88EACFBADB3224795A125", + "ek" : "7D2837C55E65D99D68679F9114A1C934FEAA475B645232F5ECAC6CDEFB0A85CDDE57B08BFA1EB3FC6AFBB04E36B5C81A047EBEB247DCF1950D5AFB3E9E9DBB9F526DFE4F5FDE8908704F5FE60F590EB9850FE8446AE0F822B9A5A6E919165FE27E0DE9AB89A18C603BDEA341BD8D3A4C6F4A14130DF7DBCF736385DC90E7870B653783B18D6D8A4B1A4C25DFF59BC41C8114CAC1A0FCC3EF7371738D6EEF97745A7CCDEAEE914CB703622C65497ECA9A6B2E624256F896E3954C7BC831995DAE5D8A73B903D75E27B5C8F1612C24E7FF5803248692177FFD3064387D7B1533EFE42512734EA73BC1A484D2DE75530FE74E44127856AF5DC5EB7254AE0CDE73DB94DDD308F7BB5E7A6368578E511677923F7ED51F31FD753ED50456A9B69EF689DE6DD4E04660B0564D5248A7808AAE663142FFC348BFA0ABA68C0ABAAB22ECA593AE6D07E97D09910ADEED8B4E7604DA358BBF292BE8C3DBD87105C862FE264CF81DE917B3AD1CE0AEE18C249FC9E1B9EF10ABB8B32B32FA0239425DB8AA80273675CF3B41C760DCD4E75100FEC31A6715EF5D5EFDA135B1AEA070BE894D459D629E99DB490580FA59766105FF5209679328E7B5588908838939A3D2AA7CB27CE1F3A0F2BDAFEE426956FA3F5B0629705F3069C2265F7C0F20693195E27A3D788E117D623BB42EB9265944DA2C67D5BB563087059F891E12AEF0B136201280A982CDDEA94815C7CAF743A506B9A91D710C5A29BA709615B6DCE3E389D14D97234A4679674FA8DFFEA8B9ED826FC8EADE416B782C9AC441FFFDB2030911EFFD599E1AF5C104F9BEF4D8A58E04043C312F7A1204B72CC337DDA31A6A7782C1B554A04ED8A92EB414E3E6DF2565A2F0DF3FD8D35186171FDF3A307EA7E4CBBE5F066A1C9C500D586D45C4F8F7F554B23F678303198D457E006D243083FD6B4290ED837DAE210C3BE8EEED1BFEEA741006A0A998BA13D76199407265DBC27891FABBF7FF04F4F2DD91AAAACED8656AD16486FCE36E690DE7A84F6784F544C75F2F27AA3E406396CEB5B78F61195F88385F3CCCE81440C5894860B07B2CDD322B4C8ADADD4034FC7ECC410E8A317A2B599F5D59B19E510B242333467550A8AFD99E30441D07B022560E1C036C4F761E508A7AC3ABCB40B55F90D14D20EE45862ABF090DBEF4F7C3912B2DCA97D5AF9BEA688EE03C0EF27150233139558295DD97C265C97A1F5B0DC1CAB2F0D0AAA036BD5E3CFA6D1BFE8E006307CFA97DCCDA312C204794A50D3EA1C59963877E41650B62E95480554F4FD750CA040A9B125338BEB8FD95039561D9C0855EBFCEEF7D52EF0AACA29D892D4FC36B72860082EB7D772D81ACAF5035B1D318E7C4EB25CB46FE7C0C7C97B61493F67BF41C7BE2750ABEB66F714539431BE10F1D0F5622E326D1AB54F42210BFA292B396609F38DA46969F12167C2B1B88B6601FCEED8D34622AB42735DC0C8DABA357AB79BC0076102E57D1F8279318ADF82139C32E7B0104D3EC20908C1A24D3FC7E6DF081DC1ABE7C24", + "k" : "612B3B1292509693D2CF5574412E78D9F51B1983BCB3CA85652895891975A5ED", +}, +{ + "rngSeed" : "7E87FB886BC3C7C9FC12569F465D2ECD12532E76CC27C65644C8D3DD603B0CB2D036C5974E675058F271D5C82AD7A813", + "pk" : "790847ED9A831C0CC2ACBAA793C41913A02DB8AC1C6BF056573BB75E2990A6FCB732C3461CCB174DAB8EA4C55781317E400AB4EF68138FF84C27FC0BC4C68E30EB664CC8BB32B617916C155D28A195FC39A1A0419AF64A59C99664F744A375113228BA3730752CE5A06701112D7328649A3755B45AD6BC4BC0859FEB014E185B2E18603EA0437B31432457B36D13A5AE96B03905BB2FD0D5377EB04F34A68C57448E7909CC660A31D9F9540AF17324E4B31BF04F465665B5538F7351687F238D6C423C9237B5CA35618F092CF7DA879D965B67B1CDB2467C9EF3862F260C04727594AA6286F4035F0B0EEEB4B141306CF7D9C4A6BB942B7A1E30B56AE958B16C3C1237603AE6F879DC9CA96A2439E26C0834369E8B041C6327254608AD3727CDF23B842A003B91D1AEE60193AE1497D5B75E2A370147F052A08B1F86179BAD52605DF44F6C99C75DF478017318C6BA017A1B4A8302888F495ACF796E0745ADB0292EA6B5526FE43F96E20D98FB756B2553A9493401D4A25B9BBAC13B62967A228BB6446B2067063619AF66383E6BC2B3D8CBB9E6969196BB45D665BCE49284C5B50F934774D500C90134535930AD2169488C4BA8AC0854F36E085318A293BD65EA8E033C754EA44191D9AC8033C031E066B2021C13FA11A15222CAB4829A5C47DF7418761620AAD92135169E0F008760BA30A289CD41F1325A4C90334978C5176CDC5496962443B118A641D6130BACA422D89FAC5C968ADB461AB43729B6C9B1349E71116C0226B55FC00323D6A74C03282F24997949207D72CE58FA4D87A7413C3BBAEAC91FB2131C418C11BA501701549EFB25CDF560239223C90E1A2F99897FAD594930848A1BA2494FA87BC03C57C7BC33463B77EF80B978724153A956779028B7A565C40144047747E124C7DB801D309333D3150493C3B3AB68C34C939243454D90C3C4079174A8171C77A0B0C9E54277B5BBC5033EB1EBA3CAC86039492B4E75A23C8C51C88177EDD639A55B56FC557B580B03935765CF586C95178C330319C70A8C15C95FC18A23DA11798CF6C54F68BFB766A61A9C9C461B766B4A00608575C4309A621B28D27122CBBCC76C30A30286483BA85A68524C0E21591B7347A0AC0931E121EB3BB8D0FB7D9EC577A5821487619E196400C2169A42A71C7665505BF333AC70267BB50380B947FFD54745E41DE5A30A27B78A62F43786AC88B2012DE563CDE100358065485A73505982A265A505ED85CADC02228FF90A03D088DA7410C6179558D52CA36BA1D87353985189A709A1C0A7A10CD8513C4AA26D27CF802027AA8C5BB99C12A51B7F16E10838500132CC24D79C805CF11A5BAC88C4BB0377EBCC4FE7C6FFB927EBE7234016BCC1765AE9E72E62D51F9CD91017F508AE207D181AB0C4DCC8D1C4742494876D118F40C84E2706914C65A161D184A5765AEC67C9DCFA4BF3418E114C6F3CC34E94A149FC84B041853AF9B213759CC5A181ABD5641285613875367842F1A2549C09EB9B1DBD851365D58E6335C91EE7ADE6C23135C1200CFC1DE3F5CF6FD13967150F01053B943C3389BC4670DA9857CCC32528920F781CBF16A9DDE2299DB9912E87321C02AAC45C4820BA2E808666EE521DC4BED006527DF29A124412A4A19AA26C09B490188CCBA53900A2545022", + "sk" : "EB9A0F50030024200B530580640112B904C9190BCC0F7B6C9B071086ABA50212517EB401A356CDBB8547B1E06CEB0695F002C9982518E6258FAAA84CB7B0885D1C9272BC8ACEF294C2AABA89696E4569CF3493CD69DB0C9629C6AF282A6828A0DBA65F1C2802AF72BBFCD102E9EC5395F0473D29B9BCD99D8C803AEDEA59AA5B11F798230917C5196B2EA9A950E3834E7F272B8C6760B07C8597025CF62B63922768D89955315C2F36907ECB89B97DB098D7348B9643BA56582915B9558FA519BB1530D7B8461831C996731CFD2B4D46643C0DE99C459B93279173A83B423A073367BA8E79904BB431760B969A4B7B98F10A0E5FD1AA75E52B59FB9AF4123AD65B645AEC03C7E2C35EAB02E201B92C266B98C5932EA3B6029345F1F8085C955FADF2C840CCA34CC801CE489415781CBFC598F1F39CA240257A0C173B6108482C9720F56AFCF250C2C704C514214FE0155289470EA5470CC1A4EB5C999BF8567D688D5A4A2A7CC1C3381C68BEC925AB312ACF037113FA8C5CC43A75F3BAF932672ECB3ED412B17B5520351918297525C5D352076CA04D2A3833D306A321B9A9B1564504B8E70AA8E9A91EF47001A42C66B33370DB2AB3E9B43F32E926E7AC189252AF3C9AC7BD420C35767E1B26B161823DA4FBCFA11232DEA1143718B6B9E6AAD183311F756C04C15E8DF99BAFC854E751417C1AA5FD64623DF434F2C70DBD8AB6D41395CDF4814BC99EBE5C1DD0777C7344C1504B7E2FF4B82D974E01600D1293C5EC2A4B34FC895E608AD7A32B2FA6CDEEB2B2867A8AEF27AAE73CA70A5670C3857501F5C4231448A4E7B4A9926C1FFB58B0AA73705C1EB1E70068D97DE17B19A1814C34D746570BB3D142A6B7C49D52D78F501A6BFE37ABDB1905A30077A21A1B0E5A14F6784DB89197121143B851CE1D975DB4F50AB75A8138E60A542CC41AAA6C55626D81535044D0A1865B4D6303C649B3545511440A320CF5260D0B85041F6C26F92A13F01C77BCA3357C26BD0DD00084A54EBEB7330F59683597BB733182A4EC7B15E8656DDA8BF0A8B38FC3632E00BCF5938706C55D94623DD9C11BB57036783593DF9B85BD9B9B2C430D94C73A53B65DA10A614D93C6DA7CBE899A096EF3C608F747CB782955D0402D9831B9889F6A7708FFA7CAF87A8DCB1A18B74C363037C890470D18805BEFE3A0BF058E64850D61614948F41A2F03446BC9C6D65750BA421E2BB8510F2A8789B20AE70C1331402A550480FAD8C011494D7CC25C573B4B23BA4C96F99ABC5A6D8EF2195284BA54678F15543243362C6AEAAEC2812E76382DFA36C2B1704DFB559A27D5B8F7469596A28C9E2B0D426AAD0C57B2407346A6BA267690CC8F30857D2858AA5B97E286017C494BCBF398ACE755FB5B0D041AAD180691C85994D331616E91A9BC4932122C35B55B8300264E5D3533F7518C59C4CC4CDC5C3894B48F247B1433666EFC9934F18234535E18BB43B5BA5D9B6979BB14BB8D407D0E15704AC6CD1BEA3466D41362A261E9E3C4CB73B625690F1BF755DB67AC556528700A78CA973391B34D448ABE2BC96447DC8F96239E6D06C41DCA9FE04272E438B7437C6E0BAB01797475ADF9CF716430DC2B4A9AD16E790847ED9A831C0CC2ACBAA793C41913A02DB8AC1C6BF056573BB75E2990A6FCB732C3461CCB174DAB8EA4C55781317E400AB4EF68138FF84C27FC0BC4C68E30EB664CC8BB32B617916C155D28A195FC39A1A0419AF64A59C99664F744A375113228BA3730752CE5A06701112D7328649A3755B45AD6BC4BC0859FEB014E185B2E18603EA0437B31432457B36D13A5AE96B03905BB2FD0D5377EB04F34A68C57448E7909CC660A31D9F9540AF17324E4B31BF04F465665B5538F7351687F238D6C423C9237B5CA35618F092CF7DA879D965B67B1CDB2467C9EF3862F260C04727594AA6286F4035F0B0EEEB4B141306CF7D9C4A6BB942B7A1E30B56AE958B16C3C1237603AE6F879DC9CA96A2439E26C0834369E8B041C6327254608AD3727CDF23B842A003B91D1AEE60193AE1497D5B75E2A370147F052A08B1F86179BAD52605DF44F6C99C75DF478017318C6BA017A1B4A8302888F495ACF796E0745ADB0292EA6B5526FE43F96E20D98FB756B2553A9493401D4A25B9BBAC13B62967A228BB6446B2067063619AF66383E6BC2B3D8CBB9E6969196BB45D665BCE49284C5B50F934774D500C90134535930AD2169488C4BA8AC0854F36E085318A293BD65EA8E033C754EA44191D9AC8033C031E066B2021C13FA11A15222CAB4829A5C47DF7418761620AAD92135169E0F008760BA30A289CD41F1325A4C90334978C5176CDC5496962443B118A641D6130BACA422D89FAC5C968ADB461AB43729B6C9B1349E71116C0226B55FC00323D6A74C03282F24997949207D72CE58FA4D87A7413C3BBAEAC91FB2131C418C11BA501701549EFB25CDF560239223C90E1A2F99897FAD594930848A1BA2494FA87BC03C57C7BC33463B77EF80B978724153A956779028B7A565C40144047747E124C7DB801D309333D3150493C3B3AB68C34C939243454D90C3C4079174A8171C77A0B0C9E54277B5BBC5033EB1EBA3CAC86039492B4E75A23C8C51C88177EDD639A55B56FC557B580B03935765CF586C95178C330319C70A8C15C95FC18A23DA11798CF6C54F68BFB766A61A9C9C461B766B4A00608575C4309A621B28D27122CBBCC76C30A30286483BA85A68524C0E21591B7347A0AC0931E121EB3BB8D0FB7D9EC577A5821487619E196400C2169A42A71C7665505BF333AC70267BB50380B947FFD54745E41DE5A30A27B78A62F43786AC88B2012DE563CDE100358065485A73505982A265A505ED85CADC02228FF90A03D088DA7410C6179558D52CA36BA1D87353985189A709A1C0A7A10CD8513C4AA26D27CF802027AA8C5BB99C12A51B7F16E10838500132CC24D79C805CF11A5BAC88C4BB0377EBCC4FE7C6FFB927EBE7234016BCC1765AE9E72E62D51F9CD91017F508AE207D181AB0C4DCC8D1C4742494876D118F40C84E2706914C65A161D184A5765AEC67C9DCFA4BF3418E114C6F3CC34E94A149FC84B041853AF9B213759CC5A181ABD5641285613875367842F1A2549C09EB9B1DBD851365D58E6335C91EE7ADE6C23135C1200CFC1DE3F5CF6FD13967150F01053B943C3389BC4670DA9857CCC32528920F781CBF16A9DDE2299DB9912E87321C02AAC45C4820BA2E808666EE521DC4BED006527DF29A124412A4A19AA26C09B490188CCBA53900A2545022BDA0815DD53B263AFCC1F71D2501128C41FB3606AF71C5E68F0752C6D3A479C50914D81173BFD7729D81603DEB601C93969B81C401E2B7B922B2873F8AA2D998", + "ek" : "60F3EBFADDA0D9E89F273395152DB252256FC2CDFFB1EAAA990FE1BDE92DF15DBAD01DDB9288A0410F69972232C31E57D3CC6DED6605BDDCEF19379066B04DA966E7EA08A74729D246664F873B64B5377B4157AABE2DC35A0B678A13F96029FCB7FFA113D8736DF756F88AE7A0ABBE533C8063A7A32F002F817BC13BA13A9F7A8065C7BB24BD18F635D7D9BAA24554B25F201906419E3DD50D65189403F96B46DD6CE227FA890078677F0B921FC301BC78B3F68FBBDE4C5C2A5252AEBF64701E927084D2D0C2C55E09CE6CFC5139C10DD3AEF09061246064D72E6C9872F8BECBB3CD4720B28FBFDC14CDCA0FDABAF52A20018F13C3CC1C4A75037B9A7FC2424FCF57D36E57AF1DCB0F03DB0A8A3C5603D3C74C3BD1BD28FC0C1F10B8D2A0437FA67095C8716F814ADD8DB1D97C4F83635DA242516E5625F9310B47FC64470971E61D13912B9DECF5F07444B632EAB2C7690F1646793F6FC44E5A8A910499208A90B3DCE7EDF35C2CE47CDB7CA774C415A421202A2E778A5BBA5B775740399A71C192AFAE610D0B0B40B350D7DC0948AD7E0FAC4457F4CC2CA6111F8047C5C2BD52C2D05B3B5BF57108BD180F2E6E4A2175B5CF17385AE46B567D1E94BC4394AF01917CD099CA67E1CE38EB6D24DF31B4E245B625B1E3A65B9261E59D72B943DC17F8E1D5547A9386F53AA8C86EBCA6C2665050D0F9E5FA98B911978D502BCDA4F4F343235615D6A8AE5F69ECFBF2D4FA9B14AEF585114AB98100B2CECA9A5C006D95E2F3E80E1F50D83264C2ED3B46E63EE82D69514CE633C31DA31BA09817483686EE787653C318A73ECEBCF254EDAEA9B30058B28624200074CBE31E019D16BF46A78FE23259630302900051696EA124442998CB9F1C16C6C3BB1C351391D11F2128F4D4E730801B33AF1B3AF16C44AAE6FB33691F273877C1F278344E6AF461774F8E0BA013D237EFACBB52DC1D00DDDEFCE6D7E9C5CA4C4C8A9E0FB7DAB6B708DD3C47E819E810F50810598934AB8A1B725451B386883AE4A349019FFB105A2A482F9E33F8F9EEC4F06A91EB88EF5A282E53AACBB963661C6D7FAE3336BE75D7947CBE62756B5FC9325FE23FD8AD5C94D74843148F87B58036F949B46A9CAB2DEFFDAFF207833A10BCAC74096B0A6D70131EE5B6EDC4093C78A12810C1118C40BC745850C298200A203CD0DCFEB20CFFE871D9634C44B61294C383D4BEC8156CE4A527DAC430C8AB608D8183F102FCC13A919D85451AA005C86277CCFD8E6D3E49B9CC907B6D870997CD2F82FB8A8659F88E47639A8BEFAEA40ED423FC0187EA0D531790E0B27FF7C4B0E085FF07F7807B998D0AB5D47D0CEF1D0EF3A9519C75B69FA56D6991A8725C3108775950C89BD8A9E5D59AFEB173E4298573548857F303193ABB66A67DD8C901E60891E6D91632212C95C7A7284139100EBF7AFDE5EA320D92E9296BA822A7101025E526F2928CA6469A403E50CB8AAFE693AC073D1B7E58D65C5F71718B6A1A27FEC18B375995F0F674282932AEE9E3D4B0A0D0", + "k" : "B3AF14238C3C3A9864B4D943CDB078774AF4E9E8875DC37DB4EB4F711FA764E6", +}, +{ + "rngSeed" : "AD1424E804F306C7FF513DA4C1E8D445AFCA7BC942FAC5C0B335733AAF70693712ECBDE26EA726EE0F9FD9D52A83B1A4", + "pk" : "39DABCBAA131E892A48FBB80F78961F9C440322B49EDB03F0E554328EAC7C0B3CEEF957A82370A8E8169CB24A81595CC89F95D70179834DA375D55A1D16A7A8FAC8E7DA64508C97F4F7A53066AC34D407B42A6BE091696351B3FB1F12C05E5429CB0A14208336E110AE4B89FC9B91EDD0037392948E7D3BEB78B880D3C6D933A73BF909593A0654EA18A5CEC051CD17C25ABB7020487579A98F62B49C2969E3DF7407F9BBF0B01237A0994CC7312B0992CBA7566CFC2818DB511D37B1F06781B3DAB99DB5268F527123A0366BF481FAAECA57E16B37E27758C8B83125049F3F38681BA5438A795021652B5F81C02876C0F404B44F06976E368AA2CB923081E3DD07781562AE4750BC5F3809226AE6F100FB8F67FAA433B66F8153D6A1B846C589B471EA6479BDB05C741DABF217A6177F2AE8224BD05B46DE5F1A42AE20A1E641238F541FD282DFF3821414890600A970811795C993C8BA5418A8732B6C8B8ABF738FC5CA7D32AA3F87884021968A93CC271A490DE61C5F8143BE65485C9F34F0D433E492BBC5E215CFA037428A51D5921404D89AA0BA6181F5294D706786A30508C5990AD24C7BB6A70D6017207D3C03100A222396C44752579859E07315CF9C397549708901748C6958CBFD41E9D2880E9773FF03808480BB38C36BDEFAA5F81F85700FAC88CA85829E03D9BB845227A0A799B156D0952D0C54BD5B010C565A381B55885D26CD9E9B82D21A31354C17D2BCD43D93946BB58ED2A57C13509E9537FE879714C64CDBC842E93326AAC0944CB3898335004D0FC9C81546086F29136227EFBC798032AAF0CBA0F3C6AAC788886E03C87245964C99C18E62C008D646621D127856C7559370F5FA26301321BDCF502D1D12305002B2AE42E61209892D7B3AFAA6CBFA9A38AC097CB26C4745A4EAE395A1B10BF80829D1B216B4DA59FCB4A2A57D4070AC2AB59A82B6AF3B0682B53F9928F7759CE20E1A09042948BA966CEE8BD176B2EC6880C063B3ED6D1160FB26714B3AE7B44A4CE6C759555C6E478C0A71A90B62A8CF8F282A4F7C21C31C5BECAC2595A766A977C886009E9414123E5723E101E667647BB9A2489B3ACD17A81FFB4512516893CEBA8838949E998043713BB41073013D487CBA107F31C84480A0CE4378732D9446970716365278F70719DA66DDD8283D62190530566904221B383441124B6F3D47103D64983898F8D83A4FEF6489B0C08A11B82D30CC4D9EB4FD0D99085C875DD4801E3902405F0B292B8487A72867E67200C9231FFDB43E2048CAAA203C7883218F9A1AF7A365A19B0D2FA595A087B2AFA1F16686DBD24A98B931A5999483D467D2D264B21BA527CA419B6523FC046BF7FA96BF0A277AF5094F3362DC863B8BC2192E5D78173D77139D6AD07E091E7EA507F2A7A9BF982AAC812F736C787C27B04E25D1CB74D5D01C3FE6AA2E7248921225632A5033FC6342495167405028D410BC42C8BDB498D9A5260693BA326E2230C6040F332454F3B2020280FFE6BB0B7021F4EA6BB4C06980B62A9B6C89A935AC206B13E091C3C6AE609417AB8C66B7BCE94986E92596EE64B08A53844B706F84731755CA02C7C49906CBBDCE97C64019A52F278C2F286EACD5A261F5B502251EC136EC0A3C697FC30E8B59807DFF5DCED3D6BEF9C96BF", + "sk" : "878A1795956EC490AAFE2190FE1A0018C9B51FCAA6B97C13DA28A8C09A7FD0434596FC21D4E65BFEE21EFDF30059AAA51BC63C7D646F14F1AA487540380155B4E51FDE096389C3A1B983373DF0669553334DA5AE1E9304619948CB85AD5BE4219683033E33BA0F01750FC62FFE5331B4E3756E46CBCA7B2FA45C26B8E6B8121719A6655F0952B9DF797717CA88BD79A769938AC2F68D4347BAA9DC2908757E19157953CC9522261118155DF98419DD88556D961EF9855E20C86C4511CC7642C50BB4A35AB30E133B3548055C0EC585D9E1A390226749A739EBC5CA7834AE6776CDB6E461B5B736B11806E59521F010543568AD18097E8654C4CB7C9366DB7990439B93A06E83391A62B90FA84A0B842500CC5BBA4505AB41F60E8414768FFC1CB9E1B8334869723185AA5B141B94A21D276D3B769237E44F8EE373A8591BA9F6CA2BC852056334E41B1B3348C7687C8688C02B6D3ACD484B4F2D9513BF181363A683547176CB1219FEF44433899D93863E22274D7E157EE0188BE6F53492655C801B4A29C7BDE7048D798CAF9C475665462732A51A080345FD0292B3B93B4C354A1F3C8B5680C9EF6BAD9249472D761D25740E92E1C29E17BD38E989442B60A178AC720B935FA41BAEA41D1124183784941F510763001F20004CAF2B4314CC6E3CFA7D3EDA5E78451F27C7C49FB8253A93500EA757F1BCB4E97778B3866F9709083FBA0CDF1031A0C667C5F65880D157BFE5986368AD80362DC1A596D31A488835B8E9B1A80EE55DDB146880A235CCB5C8DC64913A80C6C02C44E86BCD40E56737443C49D6BB4AC1501B264FC104A522784C5CC94C9E186BA7A22C329612985B6ECED06E373669B691C620C4C6EA170C05C28D022158AD3053C89CAE8B144C634CCDE032503DD03BEEB602E06165487AB4EB1292E484989F6135F50A08251BB5030088583187A57B10AAC08B61B0911CAA8685657BFAA40FF389310AB3B54EFA8DF4BACC32D112A2191A8068A390B1A8219A7954FB3CEF743C22ABB2C1820F86A7B3C8488788816493D300883B8370688B7D0560ECA63430AAAA3F4B44D7EA887D70431C266E09C7769992328BC7B2A53734729297130A59E56C3D57893DC3FA7FFCB0070F7267CBE1AC7F2C18061B26409819D9526EE5DABAA47092CE07C2DB567A72F80CE9A5284C70C6F6482701AC71C71454185099F62424C81B344FB83AB3475693D6797C5348C7985536550BFC1CABFB6806D1686139A8C920832EC675049F40A0CCCA236375153A79C4CCB7380ACA2E30038C8F2B745290BEF444A71B73839707B524D07A2D1C4F4B00782E9C91447700594B30ADFC7868EB546AC27FAD089F7046BA8715C41E292415D274C3F03C5F57B311110000FC614BC30960B26EDEF3961C258240E333A8494B5AA3152C39C728464D6915C8016106CD34213E1137FCA383D3B94D545BAB479CC11231BE67634BEB00272B59728F628555BAAF35E7BEA2C664F616945629CC381042152AB0062902B6D5B3204266A98701F376A278778CB4281E47A6A82C6C1B0F2221577909F9297616F356BE210F0F3265F6690EE5B1385FFA8F457A5EC860C01388480A09413181B9602909DE7A3DCCE34F39DABCBAA131E892A48FBB80F78961F9C440322B49EDB03F0E554328EAC7C0B3CEEF957A82370A8E8169CB24A81595CC89F95D70179834DA375D55A1D16A7A8FAC8E7DA64508C97F4F7A53066AC34D407B42A6BE091696351B3FB1F12C05E5429CB0A14208336E110AE4B89FC9B91EDD0037392948E7D3BEB78B880D3C6D933A73BF909593A0654EA18A5CEC051CD17C25ABB7020487579A98F62B49C2969E3DF7407F9BBF0B01237A0994CC7312B0992CBA7566CFC2818DB511D37B1F06781B3DAB99DB5268F527123A0366BF481FAAECA57E16B37E27758C8B83125049F3F38681BA5438A795021652B5F81C02876C0F404B44F06976E368AA2CB923081E3DD07781562AE4750BC5F3809226AE6F100FB8F67FAA433B66F8153D6A1B846C589B471EA6479BDB05C741DABF217A6177F2AE8224BD05B46DE5F1A42AE20A1E641238F541FD282DFF3821414890600A970811795C993C8BA5418A8732B6C8B8ABF738FC5CA7D32AA3F87884021968A93CC271A490DE61C5F8143BE65485C9F34F0D433E492BBC5E215CFA037428A51D5921404D89AA0BA6181F5294D706786A30508C5990AD24C7BB6A70D6017207D3C03100A222396C44752579859E07315CF9C397549708901748C6958CBFD41E9D2880E9773FF03808480BB38C36BDEFAA5F81F85700FAC88CA85829E03D9BB845227A0A799B156D0952D0C54BD5B010C565A381B55885D26CD9E9B82D21A31354C17D2BCD43D93946BB58ED2A57C13509E9537FE879714C64CDBC842E93326AAC0944CB3898335004D0FC9C81546086F29136227EFBC798032AAF0CBA0F3C6AAC788886E03C87245964C99C18E62C008D646621D127856C7559370F5FA26301321BDCF502D1D12305002B2AE42E61209892D7B3AFAA6CBFA9A38AC097CB26C4745A4EAE395A1B10BF80829D1B216B4DA59FCB4A2A57D4070AC2AB59A82B6AF3B0682B53F9928F7759CE20E1A09042948BA966CEE8BD176B2EC6880C063B3ED6D1160FB26714B3AE7B44A4CE6C759555C6E478C0A71A90B62A8CF8F282A4F7C21C31C5BECAC2595A766A977C886009E9414123E5723E101E667647BB9A2489B3ACD17A81FFB4512516893CEBA8838949E998043713BB41073013D487CBA107F31C84480A0CE4378732D9446970716365278F70719DA66DDD8283D62190530566904221B383441124B6F3D47103D64983898F8D83A4FEF6489B0C08A11B82D30CC4D9EB4FD0D99085C875DD4801E3902405F0B292B8487A72867E67200C9231FFDB43E2048CAAA203C7883218F9A1AF7A365A19B0D2FA595A087B2AFA1F16686DBD24A98B931A5999483D467D2D264B21BA527CA419B6523FC046BF7FA96BF0A277AF5094F3362DC863B8BC2192E5D78173D77139D6AD07E091E7EA507F2A7A9BF982AAC812F736C787C27B04E25D1CB74D5D01C3FE6AA2E7248921225632A5033FC6342495167405028D410BC42C8BDB498D9A5260693BA326E2230C6040F332454F3B2020280FFE6BB0B7021F4EA6BB4C06980B62A9B6C89A935AC206B13E091C3C6AE609417AB8C66B7BCE94986E92596EE64B08A53844B706F84731755CA02C7C49906CBBDCE97C64019A52F278C2F286EACD5A261F5B502251EC136EC0A3C697FC30E8B59807DFF5DCED3D6BEF9C96BFE3E96E658787BA3F6FFB47DE56322541A2C81F68E2825C74CB75AB01D4B719D6E82AB6CD4250546E9D3AAC903D6CC326CC39AE0B04CFFE6C6B3FFBD29AB63DD7", + "ek" : "C301422816ED0CFA179E52D057ACF7E7BEF3E33D2E72D234E6B16B6C0E97DC65F7581A277AF771EDF33A36081FF67EA21EC887AD9FDA49FA725756EB788D318341C94328DD8D8855F2CC0EE8DF0AC1A7583A2090C0E1BD5CC523A9190BDC40CCFC4FB2E40CED94507F3A0BB116D8C77BAE984014E0B2D3A42DCBC5375E667F0DBD6E15AE0C3E66549D3901399BE4A472BBF0D91E9CB55F36E4BED52A72F9458CA65602629E7C49DB3C7EA5B58277A89FD1E5B86A779A2ECA44D949A42347B347EADF01CA8FD30A77693CCDB50DE548B792EB700453389ABA181D935BE386CBCA29F2F11F11503D6528463C9FB1EAE47D4B879A734B8DA63D4A795AB0980971043A41377169D5475F593184B9402B03658BB3AA423BCE8FAD039E9F6DF76B4538FDC2B6A1B98912E3C784E44BCA8356AE4EF9E35A27E9FF81444E304A647F6033AA5345BFD4E3016F1CD3CE0AD784BADECD2609ACD1C69E395CBF61278C2E326D9F9714729BB6D9B9ECBD2A5FF945190892536A5EC795148066C23407842E93F56AF5FB44BED1D09055F7AEF53FDD9A994BCBD171E218500D1E26A7966369B600C0184DD97E4852D8F8A7CF78C250E53BF13BD040F6F66E603944F23869D503BF4059575D9C5EE3D9DF2E7479419895EAC45CEC7EC114826DD1F84CC4F7E47483D6B3F6D9E2665CA682A026AFD5BE6D36F06E49123A1A5AB963A231A1B3828037B52D87E13D4D80BED1074FE9A08F01276F1F24732782895AB30FBD4FEFD52F8942158462022C5736B16E8A596F20E62E6E60DCA4FADB89B50E7919B5293BCC03230E03C345583E72A18429375B5AB6047E606D154F7D4B50DB38DE701362AD6E8ABA261D06ED6E0A39CEA0C434411D6F32F9041185BA5E9D505CEA8A2664BDF72CA70E6374623EF65E294503A1F9795BD49CFC2A83E6039DC104E43D5A8B289201C3F2DE1CFFDB73B43BBF9773AE47AFA5646537FFBBC3AA38621ED9E39216C2955F1731A4903CDE44632F7B3E1144B308A3594B68BB76C8C6B58D248B12863E32B69600F2E451D07DCAE75E3D41F04828CD627B86A3037586EFE47E3D1F11684EB67B70A9B930C5D9B6EDAB6E0503E07CEEF05D6E671499B832B9A1534D809F2D8F6985995BFF0B684AECB3D8D3244CF27D223CA36A8B13B8D9B5CF3F3ED76A52E1767593A9410AD8CD2CB6D69282C467ADFC97FA596606EA96C8B060B30A68F352D45E7FCAF9BB3609624813E61A389B36C018D420BABFF42DE266720DF27AF7B474C5F2FD4E2B94E9B7230B2731478C32635519649446516A71BEF3ACD017694A4F2B2D1F98422F9C7B9F8D3AA5E2AD12BC35B739CB39CCDFE4BDDC81BCE75C28817EDCF20B7BB262EAB2C597E917F6BCDEFF07915E98E13AE2ADA7559A4F3500619B3F2B15E647BF52AF2090BB7D2FEC04FE9BDA66E0023804508A5F803621F89AEBFA7AFF0AC3F43E908308FC7522999C570E55C3FC5295C64CD3A59BAD0DFA652E67B5A4B734184AC4B2E65C5AFE18E77D8A114F2D1056875BF82E8111", + "k" : "94B940EF373F1256D521D24B069E44BE49314AF0D15755970BB2B4791AD1B562", +}, +{ + "rngSeed" : "7C33CA0E987226C8524DD56C811FA4D1CCF9995B1E4E4DD5B1481974E88CFABFBF6787775C2611CEFB27ED4403EA9B46", + "pk" : "185BB36D9C3BA85A46A5F605706979EBD66DA03C15F1B4C25B886FACA00B16E04F87B773D0B8724BB4947C615344F9466F78CAE8D049876C9F7143154ABC47110B0DEAC571BBE83577F577046830031A08B465B86E1C341C82660818CD2F8173C5C558975868F0281470F39E737B6CF964008E040382B290795254380B4850DB27DFF98838D9921EAA8146022937E36AF6B030B8919BFEA844D9D602CCB3547D5C07F612C12C3C179FFC30FE52C9273B5C0DD27934B5A41737817BE0739425736BB0CDD267BEACD0BD77085CD2794947051099C3848FE0AA2BCAA18F6A18AFB626FDF1B977F376EA74A9CBD638932600EFD84FC053650474C801B1A8ED941CC5444922915173EC1971698172F8A61730358C751D2D776D93C866C47802E2AC19C7C092ACEB53996C20375B47413A66C06541B4343C548B4DC5341EA92B2266D9C0F1665719F62A72650414940BF3A20A260A5953D578D5AA48A2B670AFF7512BF6937E49052C3AB8BA07016D06A9D643081DD52009B358AC13C3136CC65B0127E675BB55B8598940C054C8B797D37312A1AE48120934A559BA31042E160DDD13C744D7AC5DD614D198A33253B829016FAE7CA51D397330BA1AAC557A8FB56477224324924276AA52B7000F77DB547A604F6D7189EF83071293465012B6133A6E1209AF3009A867A46BF2868F8AB8A932784B76084998E37EAA4496C661A42E9802F5E1CA947C75BC4A572562733409757855031C9627152C02CD25A9B9725ADAE909175B27C53C6233E4480CD3A06954AFED889AE97A091DF86842483EDFCB5DF9A365929B6DA98917CA7B025490B416A7ABFDA408F07429244A9202A23D23EA8AE96BC8DDD747D1EB9B79A3CF3610BC4EB56F9DE38C3FB77DB2740504E85107F46896202684DB8103B1C488E9B731F0A2BCC40B563226D05946C9FCC1A4E287628BC4985189E05A5174709F00C43EDA4897429773140B30BCC090ADA25C91B8858F07068BC6C154030F048C1A7002AB58E157EE5B0E682877372426E193CBBDD3C63DEC0A725C90D29411986A249CB30ECD981A92519ECE4074F18AB92967220AC1C963503A295C570D7084C2917EC9B6A4663A931D6A505D11757AB2935FA708E9B6AD5FC1187F3717C6A4A818D57CF5395626C8A3917012FBA13315902391116FF5015051DC8D07EC0716356D20A184458B4089A37FA9A713AA35C8AD1635A7FB49E6BB44CDF4628A3B84B9869DD760262CC487F44A361B9C1106553338CC5DD71C45C37A3BDE98036F45231DEA2A83001D82203B27AA054CD1BFCD215F477A7E43D31D946971B0D3223868922699B0D810B6FBCC834104BC0BA2CC7A50BC198616468C212C9B9DAB2550282A9B88F8A1B6D006BA801544B62564DC05CAD68D7F6B143222A5BB28BC9CB57788D417FDB73BD0778FE0529A35190B0912623DF81A7387CEF7D201AA007A199735BC3AAEF9706C6DFA1B0256B872320459951111B90CAF3202CEB8C10A480ADDF08DAE881EECD0CEC08A2ADC61C20E8C15B60824653492E603BC3C203FC35CA536FB7C64084112C878741B83870620EDA2997F38AFF953217BEC592EEA7947E8BE23FB627251C13FDC9BB0B705491151B8197CB07EC66DD1D49DAB7F9D23AA8FFA435F2CC7A7A3A1CDDAB6E37AB7BE45FBBC8A", + "sk" : "4B11A51A0BAC67897EA9CC5D7D071855BC8BB375A18D838016FCC506BBBC7AF38473E4275EB5449B0A5B7145B49C700626F7B6E5A6907879C541A0C6F027B7403A5FC25B42DA3A7C9308A51E863EB346C178C469BB27022CEC566DF469340205FDD84F4F0A79842913A974A7F50C2AEAF35E37673C4AE52E5820C7EA843109E403BA5329A9818A856050EFF789D4B71ACDFC34761C39AE130FDADC300BC6B3295380D3C6944213100E43788204A41C75395142B5B5BCCE2EE71BA4B14FF09325C9D884BBF9199E132551A444E527BB98E6B12A8210C6FCA2A054BF8FE346C2DB0EE9E97390FA2699C60A1E9C4599CC37110460D27B8A5F741D58FCB62962A38143AEE0377D6D440662506200FD44BF71631C479080660A9C6286CA3BC0D5F9AA44E7CF23342BCF37A9D710C86AE39E4795C796805F0198B25D0B87E4F77E01B970E2858D26542E92EB356C276E7E95BC77019C4E90BAB92C139AE10EF59B44CF8CC7E9B5B59D710F4BF2B8A4A5C5881018D9F593FA5B4C745A3F12457171B735920250778045C0FA3E1378C4ACA8388245484A232D1BB020EA665E60DA9F28A10E9992022098286C918CBC40476E7C8BDE62CC27EBBFD4C10DC76982781CA59D630E086771DBAA1338814496A7AB32913C837264C527080C9B6D39C25E623B61FC180A29AA3271F84A1BC50B7E678143939AE5FC17D33BBF52D95E53B525FF8A8A408ACF61D887585B561C3A69B088388F88532C8482A20C445E40362D1C4A331211D8F999C3F2424379B560B5AB4E6B655FF16E0904136A27774AB93233217ECFA58501C1CE6FEB7E448CA9F3C76A52511A4A10008CECAD9742368B104521B1B4E5461BED4C1A78EC9265D23272C06BA6C492BBE9AF2704B9043510AB869AF5D9B63EBBB8C2D26051B9B452D5C1605A7C4D60CED3A930AEB63A865056E1F00E3FE450A2DA299D3C1583E52FF109CB2837C6B34ABF6B063AFE82C86B2049D7335BA4762F8B9C039F49C3554C9CCFA95E9105AAA0419D39BC695C873EA42313973724F02729383B90780C55EDE19EE06B631752C2C835B0C2F04666BBCBBDA79077A270BBD670EDF111F5D578CC1B4589E31C22BBAAD3C4044C1CB67707ACA78C6D7C3441FEE377720A6AB1C5B13F3530BC73020200983A962C1403A20D388B2BA71E777C28C3FA066EF0BDC5C94E0DF40188F06800CD3DDF1C34B139BBA633CC680079042B934DB02FF093BD38FC9779F694196B160DD35C0A51C9F56BC4768333B07C4736E5C41CE048582C69F066AE08BCC4BB3C58FAE435F6B53F8B533AF1309A5B91BF3301B4A315491EB60670B1CB7E60424451031D6786B1F13360C8119BE05955C37336F49BD4C2A7E7B15FAD1A6D2C52AF63870DAA148AB0F8476E7A09309B529450B7E75B95988A66F037574EA5B1F3EC3D2D8570A6C46320A30286196E363028923B8AF1128847DB9B42C618DAC72698044144D5C205D14331E91E70F55DA87A45AD049D7BEACFAF079B148A9DA5981E1B40C36837B9E344AFFB519F961C45A8270D6BB125F42BC5C5089D9C7324DE600184336210F57603CC229489A4E27B7FC25CC0861962FF738F06C03D4422BF12855ABF225B25B254873079185BB36D9C3BA85A46A5F605706979EBD66DA03C15F1B4C25B886FACA00B16E04F87B773D0B8724BB4947C615344F9466F78CAE8D049876C9F7143154ABC47110B0DEAC571BBE83577F577046830031A08B465B86E1C341C82660818CD2F8173C5C558975868F0281470F39E737B6CF964008E040382B290795254380B4850DB27DFF98838D9921EAA8146022937E36AF6B030B8919BFEA844D9D602CCB3547D5C07F612C12C3C179FFC30FE52C9273B5C0DD27934B5A41737817BE0739425736BB0CDD267BEACD0BD77085CD2794947051099C3848FE0AA2BCAA18F6A18AFB626FDF1B977F376EA74A9CBD638932600EFD84FC053650474C801B1A8ED941CC5444922915173EC1971698172F8A61730358C751D2D776D93C866C47802E2AC19C7C092ACEB53996C20375B47413A66C06541B4343C548B4DC5341EA92B2266D9C0F1665719F62A72650414940BF3A20A260A5953D578D5AA48A2B670AFF7512BF6937E49052C3AB8BA07016D06A9D643081DD52009B358AC13C3136CC65B0127E675BB55B8598940C054C8B797D37312A1AE48120934A559BA31042E160DDD13C744D7AC5DD614D198A33253B829016FAE7CA51D397330BA1AAC557A8FB56477224324924276AA52B7000F77DB547A604F6D7189EF83071293465012B6133A6E1209AF3009A867A46BF2868F8AB8A932784B76084998E37EAA4496C661A42E9802F5E1CA947C75BC4A572562733409757855031C9627152C02CD25A9B9725ADAE909175B27C53C6233E4480CD3A06954AFED889AE97A091DF86842483EDFCB5DF9A365929B6DA98917CA7B025490B416A7ABFDA408F07429244A9202A23D23EA8AE96BC8DDD747D1EB9B79A3CF3610BC4EB56F9DE38C3FB77DB2740504E85107F46896202684DB8103B1C488E9B731F0A2BCC40B563226D05946C9FCC1A4E287628BC4985189E05A5174709F00C43EDA4897429773140B30BCC090ADA25C91B8858F07068BC6C154030F048C1A7002AB58E157EE5B0E682877372426E193CBBDD3C63DEC0A725C90D29411986A249CB30ECD981A92519ECE4074F18AB92967220AC1C963503A295C570D7084C2917EC9B6A4663A931D6A505D11757AB2935FA708E9B6AD5FC1187F3717C6A4A818D57CF5395626C8A3917012FBA13315902391116FF5015051DC8D07EC0716356D20A184458B4089A37FA9A713AA35C8AD1635A7FB49E6BB44CDF4628A3B84B9869DD760262CC487F44A361B9C1106553338CC5DD71C45C37A3BDE98036F45231DEA2A83001D82203B27AA054CD1BFCD215F477A7E43D31D946971B0D3223868922699B0D810B6FBCC834104BC0BA2CC7A50BC198616468C212C9B9DAB2550282A9B88F8A1B6D006BA801544B62564DC05CAD68D7F6B143222A5BB28BC9CB57788D417FDB73BD0778FE0529A35190B0912623DF81A7387CEF7D201AA007A199735BC3AAEF9706C6DFA1B0256B872320459951111B90CAF3202CEB8C10A480ADDF08DAE881EECD0CEC08A2ADC61C20E8C15B60824653492E603BC3C203FC35CA536FB7C64084112C878741B83870620EDA2997F38AFF953217BEC592EEA7947E8BE23FB627251C13FDC9BB0B705491151B8197CB07EC66DD1D49DAB7F9D23AA8FFA435F2CC7A7A3A1CDDAB6E37AB7BE45FBBC8AEB3FDFCC0B171AA975028F96CD47FDBA421AC08E29A0044CEDC29FCE35EB8510F7642088944D664CA7996BA944EFF7E4ABD0B900D3D1728D99A9F722F928FEDD", + "ek" : "A2B5AD732CF51C9E1F38927B6C7CF7118B1ED665C7C0D8DCCD7B77F711D7E600F6094F42CE59A244F5559FF931D376EF6A52BE09420D889C4B0CF01187FD7B65449132AF06131D968388AE88FB7FFDCBF4C9FDF6D89E8F75624DB904E0895AF41028FC3287E654947649C83EFF9B5EBF96D74AD183929A2022DAA5714091A32CE72D6CF9677B4D41117F2D6EAE3A73DB86844962C0A372F1709313AD140189FB347CAFD0B7DD47B2ED42BA896E062CF774D35AAB6BE0EB8247CA8DFE50CA1D68E487AAA04E68F4179B46B8F5DB06FF6C85EBB3065BD1F492E9AF90669BC544FA3036DFA344DE8EBF6E6651175A4093F30304045C43FF27B49B93458580505CE07940373B48FF957718ECD0A7DB598774691DE56921251ED3E28B94A4A4C7E35D2B7561DD9F05068A4899F18DFAB99D975D2C1FDF410E20742D66E2390F8C2094A9DB9C861A4A1C2267517F27325549CF39084777FC2F3B2C64B3047C0D138B8BB687716AFDB29A0786F331E7DE07E522D2B0DB5129FC809E650C62B22C50EA0EAD22A34836E3E895738C09B63D960E7C42C01D8C7E3AF71208C4A5835FC97B36AC1713F112BCF1F7B6CF2712EFB9E6FA7DC2C0B01D6AF2D3CE2D7885F8F74B4C9DEE09F8BA69761E2791EE73F172B4E28C54B6FA1935684C155BFC9C5B86E4CCDFC4C4E897824F7EFBD6A98CEC0BDC142EA5308618B3BB21BE232F1B4AD8EF85EF6707921E1DE284637BB1F962229616CCA66DE4E51413D85CF7637DDC05C7132F761338B5F835A1FFA2AAC27D7FF923AA085EF6D62014883C8BE6B629BCB3456A28D8C58840C8CD55E759FE45C7498C0D3FBC86636685E44C9E1361E50DDF4A49FAF4B7CE2237888629B1C24BA3FFEB818AA1C8EDEF7FC362D7D5EF49AD2B7A96C13F63D8508BBCD96534C599D26D840F796B1724E47443738270D6168E1ED7347291411EBB38112176E3D1C68352A62AF7F5C678DE7D9BBAA3B39854F39BEF1F2155F4149A391EF8C723BF55998A24DDFE0FA457D6071F2528D25DB76F58DF6E9BD02B7F8DE4FB23205B33F1257FCA37876D0660DD8A96AA27CDEC214EE6025B8382989DCDC717D709024F0D046347AF27DE544B50FF8452C2209F811B52F27B084EFBC9752F5D7D3034898F796891F5503AE4AB216D1AEC9F00C35CF4236A14D30E192624AE3943E98033B37A5F9EDA3CFF52A720A86B00E1D89B044B389A2DC8232A537D73BB980E8B5BAE69E6A8FE6DAFCC546443072883A1ACDAAEDD37F380C5AE67FEEFBAB439E54D66385316EDBDC421B888670B1019BE81C1DEE4AC62F97E3DBDFE3CD12427D7DB143D7B4BA79ED37A59C91EE3ACA47EC990893E53D3C75107BD3084306F982F7A84568FB8C114E1858A87A7BB59626146940CDDF08FC364E4EB1FD298FF5124AB1B7A1E368FC55AB8B4E5538EED9F559A3EED1E4B9BC234D2A7D4035D94D16595C747A1A186F23A06C3636AE6676EA5D0D14B0C58A5C32086881C69D45E7E8BB1C7421B6BA4C08B2990A9F15608A953F837420049", + "k" : "CF6F6A9285CE38A1A3874BDFD3C424D3D6F6195EE3F1C4A741954FF451C546C7", +}, +{ + "rngSeed" : "54770EA1252EA2857D6635151194F5F520ADEA8A41E409FF498D40C271359858FE2B084D5B96BEE087B8E8F4DD4E00C5", + "pk" : "E80434A94334B45589B1866BCC69BAD27BA323A563F47BC34073496A468DEE6013330BC9A219452CAA35C1A522C45C498FD4AC5564627D564D3881C731A9856FF7619622ABA6F928BEB9B9373B1104E2CD2E6246BDD88268C1B512867AE4CCCA21140F0C046B5E5817FD64A2F93383C3A5ADD2F62784E2C8E80C150A1C8E1A8A47232787AD529333A07E0C512332799D9896A6071BB4E4FAB647440F82CC85630C629C2C2068037948B575A1693F81D2A045A9C5A5C2306E83B911EA1E86DB5763F13CA6B02CA8905B50FAADF5440BEC7B49913B371F0C5786FC585DEA2813FA9CED349D9FA32CB5030B5EFC274522CA4C6985B9DBBB245465A8849C4C78688392B0AB5BCA98B04C7BF988EA84292C8505FC7ACF90199EAB7C31C13252680C71C9C333E91A0ADBC1BD00D023C8D7A7C9068C3FA9B3CEC75234663A2B73572ECC71E53A8EB5889860A336F77BBCC1C854D0C3C61C65216373BF2603A0EE72AF8F747BFBD7401BCB9D599B6CDB02C210010D0425917B72891C33C97E9B39A677010D22A784003E1B917DFA3273246ACBB45A79C7848143F0B583781626BA02A94922490C7B3695A787D9AE22E5470D32CB68790D75B81C55D084A43C4399AA587E07829510220469AB5E6381517BC9059353B68160EBCB0EDF969E8C317442C4058423C3356B34035B9761744FEFC76145300908DA3C13F95EB3065F2CBB911437CD24F815197C0DD3F9C87E3B54432C50DE1C7549228C5F9C32EE8C19FC4CBB04514025645E0FD1468DFA274E59A50D62C560EB051EAC35BDD148EF75B0B05357619490CBF08B0B13767557C5FDB310DA985DFDB9C35580217067A8C68491BA64307A618D272363EA346629EA6885ACC17733A801166FD404CCA58B591B68B2C73A9E890A13BB173584D2B6DB351133E75D258995CE46A8F798A44DDB8526633949E5442435C7B3C083875760C00614665C4A2AB92C378863A3755DDF681905EC2044C331C4B976F6EA5335BAC739C2BE9CF141A9F3AB3F669C5FC49D74F79BA066A7D03B0C2036247C86305BD45194A00E33A1179CCB8D05B374DEB491BF5C1D6ADC4506803A8C65B18DD6621A5820CA93C339DAC2BBC098C22B4E1FCA3CABE58CEAB66DA6A35191A29AD82C74ABF1C823200BB197015E074D14F224FDF30A51BCCC015A152B8443892B7450734B34E77356231C6A8016AAC430DB0A8954C7A416B43D49120FDC4017CB61C3BFE70FBF24773412B6A91375F381658D57677FE571C3BBC800CC80AC597A8F2C5CD1F19567AB1F4C797A68E6133507AA90D1AE096148D313B48096AB96298C33C3828D645A28098C777CC10CE068C035A71F7A2A36306FBBC311D3D14214C042871388DC899CA2116BAAC1AA5CB261AF35A0E255B228498295F6B4AE171DFE21B5F66671AF532253DC724A893B933829A0C275C20407898911472A02EB484D4AD5B8D274C00BD9377F3C497E6845161868434C968BD847EE90C2ECF600867CC790B005061C8D5C49339DD3AE23920E65DA2A19D649AAD1B722552E07F51CCA7B87EFA315B6191B31279509D78B0E974860BA9F635283412038EFE3CCB2A0C643C68756149A03B50F6891B9FDAA099ED50D7A012C0175B9518C15649396D94CA1266979893E82811AF8C142323FC3D38B8B5E554F", + "sk" : "06E67B30992AC43A09B6572F7B4764EA9BBA93B05CC3577A8F762279C1C9991044B7C57FFEC6C73A8CAB976031B32C33430807913524A3E5CE0E1627DC11495AA31A0712302CD26E7D980BDDA08542D30FEF9A1CDEF2C302C61B39D119C09909B338529B89C4B52CBC5111C20A880B493B01902AC47FEAA041A72426B4625DA3A79704A239138ECA642F24D382DDE6A0C549676BCCBC63010EA8F17DBCA231E69AB7ACC5A9D9081090CB653871532FE48879842E7DC41BFB8820F22367189B31D1F201B7C50E25466FE4891115C2C8337A637E964C5D88C5E752C9A247047BFB2B0DF93A36D06D80C3230CB628ECB5997D999B1A70A5FDD8B9588678D1E892C330BAD5AABE0927029F173B6BEB512D59369739AC8F0B5FB1663A874426EB31CF1818199B984C6C01B70CB56C2317078C393E5A35CC749C7D06A29C08A3637854A3CAD724E8C93199DCCC115B5A02902F29B482C6F1560EA778ABC9C0BFCAB0F4468761E17C8D265B93BA7927A2868F78BCBE6374723646A82821A4925C548679ED3BC29FD6022EA952E7B8ACC220AEA82C66C75C1A9D4A2A7F793EBB969B877A85A3A1A886CB57C58B3D0E091C5D136DFDE61F1685626D73BFAB6B672E95628BE27071897D880007EF364982EA4547B195BFD79323874000D8179876A61B0589FE769E7193378C61149627ACEC65616D701F08F654F486628CBA1574E92EF7F96C44A0AD9057B2B175012DBA705A4735DB91CF96155146DC53EE32A8E7620D1F6C0D969007BA84B36FD2BBAD660882467B6675B77D838B95AA32C6FB04F109B1C8EAA181C4AFE3CC7E2E301C8C89CAB8E4587FB472DCE46F3980AA62A61526B79108D611C9C103EB05746D58AC6CFA58C4A474D2A54F96E8617453847CBB296038498121B867F9AAC8776FE153BF3F8895A5D02DF74C934E2309414597C176857955BC7BB3C5989157EA63BDDBA696CBE57FBFF0C71FF637A54117939708DB26732BA13B33783416D0CD3390A437E8CBF4C978989000ADA7C5405254B9E9094C5B9C3D211F03E205E6469C478CA212136C9EE79A427B00370B2138B0C11CB435F93C4CED3326C3B1BF9A2991F9C4C285AB09453A2CAE4797AEE106FD95949F2007B8A6177A18BCFA717106688C7C536D955B3DB2F730C832B19CF84B31462C6C4623527B7E454085AEDB59AEC591B69349B00668E170B2667358DAABA2D959250CB0486F0448768689B2C5450E8BA2FA3A77E9E9080DDA636FFA09081576FD2B0320E69CBF017D468309076884AEF925F6A9938E76B52B453EB8C563411977551057FF750F1C206236679C09F98B34026B42A2C778407014396F9CAB89940A3D66D76EE512B7F07375ECC039C4258A1C7A8FE521868A99C18CB78B17E78334E598A5260CA42163BA705295F28C36CB19A242216A56079826483698BAFEF6755ECBA3B7091EE2C3C6AFC9B9D2F42317A51E2A61BDC229A4B7051AFC6472062A440CC7B684E200AEA93232BA945D21007BCB58BCA99B269C5CB46B3915197278C27BECE1B9A4E6BA09BA38573987F30490F57C09E750C9FD87BE933A91B9C59717E3B5C6FB660EAC8556488D942B4BB00711B2C93E4232C1C7A08669776A3F607CE80434A94334B45589B1866BCC69BAD27BA323A563F47BC34073496A468DEE6013330BC9A219452CAA35C1A522C45C498FD4AC5564627D564D3881C731A9856FF7619622ABA6F928BEB9B9373B1104E2CD2E6246BDD88268C1B512867AE4CCCA21140F0C046B5E5817FD64A2F93383C3A5ADD2F62784E2C8E80C150A1C8E1A8A47232787AD529333A07E0C512332799D9896A6071BB4E4FAB647440F82CC85630C629C2C2068037948B575A1693F81D2A045A9C5A5C2306E83B911EA1E86DB5763F13CA6B02CA8905B50FAADF5440BEC7B49913B371F0C5786FC585DEA2813FA9CED349D9FA32CB5030B5EFC274522CA4C6985B9DBBB245465A8849C4C78688392B0AB5BCA98B04C7BF988EA84292C8505FC7ACF90199EAB7C31C13252680C71C9C333E91A0ADBC1BD00D023C8D7A7C9068C3FA9B3CEC75234663A2B73572ECC71E53A8EB5889860A336F77BBCC1C854D0C3C61C65216373BF2603A0EE72AF8F747BFBD7401BCB9D599B6CDB02C210010D0425917B72891C33C97E9B39A677010D22A784003E1B917DFA3273246ACBB45A79C7848143F0B583781626BA02A94922490C7B3695A787D9AE22E5470D32CB68790D75B81C55D084A43C4399AA587E07829510220469AB5E6381517BC9059353B68160EBCB0EDF969E8C317442C4058423C3356B34035B9761744FEFC76145300908DA3C13F95EB3065F2CBB911437CD24F815197C0DD3F9C87E3B54432C50DE1C7549228C5F9C32EE8C19FC4CBB04514025645E0FD1468DFA274E59A50D62C560EB051EAC35BDD148EF75B0B05357619490CBF08B0B13767557C5FDB310DA985DFDB9C35580217067A8C68491BA64307A618D272363EA346629EA6885ACC17733A801166FD404CCA58B591B68B2C73A9E890A13BB173584D2B6DB351133E75D258995CE46A8F798A44DDB8526633949E5442435C7B3C083875760C00614665C4A2AB92C378863A3755DDF681905EC2044C331C4B976F6EA5335BAC739C2BE9CF141A9F3AB3F669C5FC49D74F79BA066A7D03B0C2036247C86305BD45194A00E33A1179CCB8D05B374DEB491BF5C1D6ADC4506803A8C65B18DD6621A5820CA93C339DAC2BBC098C22B4E1FCA3CABE58CEAB66DA6A35191A29AD82C74ABF1C823200BB197015E074D14F224FDF30A51BCCC015A152B8443892B7450734B34E77356231C6A8016AAC430DB0A8954C7A416B43D49120FDC4017CB61C3BFE70FBF24773412B6A91375F381658D57677FE571C3BBC800CC80AC597A8F2C5CD1F19567AB1F4C797A68E6133507AA90D1AE096148D313B48096AB96298C33C3828D645A28098C777CC10CE068C035A71F7A2A36306FBBC311D3D14214C042871388DC899CA2116BAAC1AA5CB261AF35A0E255B228498295F6B4AE171DFE21B5F66671AF532253DC724A893B933829A0C275C20407898911472A02EB484D4AD5B8D274C00BD9377F3C497E6845161868434C968BD847EE90C2ECF600867CC790B005061C8D5C49339DD3AE23920E65DA2A19D649AAD1B722552E07F51CCA7B87EFA315B6191B31279509D78B0E974860BA9F635283412038EFE3CCB2A0C643C68756149A03B50F6891B9FDAA099ED50D7A012C0175B9518C15649396D94CA1266979893E82811AF8C142323FC3D38B8B5E554FD046D93317DC6D0FF28990721C3F94A93024CE01B01C0CA55D634C191C4280FA55F35361778BC0A53EA94003FCC0252D8333C58152482AF1E9C9D2BDF12F377F", + "ek" : "5FF60AF380B8A293B3A09E5C366F41345784288F351C3269B484D913F7BE4A0844801B1DC4674EC79D873196D22CD6F5A8B21AAC01C3BAE963F9884AB2315787FE971338B4A0D1AC3DBBD3E9771EF7193BA0A7D4BFE949DE1773DA60B5300D2AD26758F92F75C6DD9D32F005EE283C08801EED6683483FD5303165EEA46250617E54F8FB26E0D1D9DF887C42CF0961C0D4DC58CB3EAF50BA85D05A902474145B43AF2CDDFE70A41C081A4C2C53C5F81E4E4C36C92C05F7ECB950F6F586CBCC01C70D083F75C1C459632D25FB572F84E4FEAADB479385E4198160C95C8E958E9669F3A26BFCB6D42FDD945EF2B9D39C49462C2615F4AC6C16967B3AB153B3ABAA4FDC156F2EC0CADC58456EE3AFA9D1EEE4D6C29BC39B7EE8B4B5537138034ADDD32DDA2F0A65072D3E054583B7D62B51CB39B22EC68912BB2D084EE83109FA0EA2A76DB2A7B1B4EDA0809EA8085E36ABB6AF17FA6839AAA9C7A0165F5675AA52B838B4076C60091565F86F54C0C8791477EB9D024B6B8555A405B42037C6C3F0E4E61722C14FF3FF9DC677576466ACF889918723559E1A9A697355274942D034F78674DCF6A3A3867C55308F665DCCD117826321D5177C795DF22F6477C79F5F7364C625EF2F1D71B98C1FA18EE4FB000F1B6435D32FA708FA26405470C9725542ACD34CDA993FD9CC9352474D72F4E926803FC4BF08C1C062241E1506C01522165D68C6A37BFDCA429190A0183E7C1B88B1B7018B7EED1156F3E3B2B76F8AA1E8CB1D083B35AD1174D6C40BAD80CE57076963349437D358E2DAE6E563A647E76E0CDA46D4C72208BFAD1382DC47B253C40A9DF86FE0C3D6397A95A71715864502C5100463AB13E4CDEAA4E2AB203226DE072085315099D663B1A036F140BAC77B69CBE506565A8A69F582B06F74A1C0DF417642981D1BE2CE7EF48807BC1A1E3A73C04C8DF166CCCCF3E1F476153BCE1CC3D24B2D9440DE8753A544240B9C4BDE4453147A1EFAE6EE03369FB7F9F01386E5C99EA181731995557EB7A839910412468003E79287D6E84811D0B6DC84B6215EC128129C93F6893C3E63D98998616646AE1C68CB24F60783006BD948FAE0BF6A19F15349C0BE0DC5AF0B8B63AE36A28A99FE0BCE3B9D0FE721A8F1EBCE7030069F419D0CAF96FDC00C30BE2182BB24A7D85F87FEECB8B5DB35832C6A937EFCD487E5A15EC70CD3EB1507908CB2BBC1A1B10656BD54B6E19599D85D91D2156BCAF8A0440493979CD2D3EF9413BCB28BA9E017F89FF8FDDE65431C0C42318EE913FB7E178600BFD4F1A773AAE47D67EE151DBED14A5E8EA3E62939C4491E626DB97B20E3BE1F7FCF9ECD30E46810AF6A6DA86909F49E0397131656E904944814BA8462CFCCB852D7336E2DF19479C97CFB6775E7D1E1DBEA076810BCB9B65C22E94CFE74AD0842D8091CBB064A392668573F2FB98E4B123FD784E07F511070CC36CFE67DD2145F348F35CF602AD4E3970AB82B26EB04EC4FAFE550EC509B4F33A152F502DF2B195126C80ACE4A7269", + "k" : "3D508295E6ABC043E3874A60D0B21D501768973AB9F56BCFDA18021A3A00D629", +}, +{ + "rngSeed" : "CD6CFE94E9C0A1CC4FFDCD2D7876504BE5F50F1D1CA5CF93482943465B268276056F2781F4DE805C138976CA72621387", + "pk" : "70D99D171745EDCA3A65045BF6E0625AA4955FD125D332AD33F9A3CEB2313AD50C97614D038547F22A135A33C06C61545B9A26B46C41D1830B83D0257FCBA82B36510199224855BD1A837A369A2C823391B1F84E54959A06938513681D97F34EEAA7BC42EB13574B29FB785C457786AC69CA22F644A1D53278D4C2E0F325A1209A0CA40FC32B92E906650B484E7D92CEE99A078F5090D2FB60F84B47DD44224228443D36219A081F9956CD7983AB223BCC094A0C65414CC2ABA8564977B147088EF41ABA589653E535847450C762517DFA462037C2C1457EF3D1909D0B79D66AC6ED9803CA88A7295C4A3AE53CC77C235CD8922B36BA8B837F375755326A960BEAB71AA1B33A8B64D6076F0889424B1875ED6316ED420DB7E02D731B2B3065C7E80115FC1406C125B651C2B4CED28AE9C67CC505BAE5B747E5722F4729602BD1AAF25BA333C29CA011CE36F55494204B0F70895938C9C4658044740521097D696C8EFC045709369F88C1CD46BB763B957DB8F48ABF1A07F431845C94BEB7A3A68D42AF6C2C3095F829DE51B37C134F977461AA2818073682DEF71A65291904F0C214B727FCC7B522C2A33F7A2E07A65926FA5661172103B390FDE2814B21273B318D029A112FD389D0324506D280BE8C49BB923412F4C430CA82F58CA8B7122907B986FE912C323B1758901007067153DB7B16168F791610DF534AEC8050A58296F58B7549F0665E13918C784DA2D00DA79559EE006566050482B2A13BAA4884AA83351753CD7A48E6385292A990CA559C8D630A7DD4947E428198B06242179C369741FC067DEC411765C58364D32BA655350530A4AAD934A1D14B76F55A19AB7F2DC60720124A2B69CA703030B2320DCBD459CADB6662FA0AEAE170F880797E2BB0A2F24E8DD1442549BA4510153640BA7F093ACAF41F67F55E4269260CE2AA28261D4DD4ACBC2A4A134751261991E7B36183387893C5900E8A611894C76C26217A390F86E5068A947457DB75E7214B8B05A3C87251CC2101D7E6115C908D2721AAB224B038C1B9C348A3C04C081496928DA726C0D140D363A427B93427F16841C97447698CD0F360529725EC86113594045E143659CC1A0667832F40AA7E059D0B1389048A75429886095B3EC5A646EA12A09424338C6AB729A27E595AC7784169C6E7C7BC208B07A44CEE5940F85896A7285845A2A262DA092D1B0295821975754898BAB492530E44A410F35563A1E45775613192DC45DF526CC19B6EED8186E6F706E233542A4450FA6C89BF993AF5699DC0E46965417433D5B1882340A1294D4B229D42061BADE4683F8557DAB0603FAB1BCD956B29BA8A2AF60093654F09E70F07EB3398F7BED1354A7982416AC40860538C36722CE1B37322C4A888C2359080704490B613C9A5F7318566A37139563C40D58C055B827145BD659C8FC6B7908A071FCDF0B17E4351CF3BCD9E8CB9361985C70C49BAD71F860B36AE120F62C06F3B34AA4942985D149DB7B13E1412CC1FF59DAE21CF50017883A0AAC754AE6CACBE87A46919C05752877840556AF8D56FCD848F982B415D333FD8640794918EAD0121D12309BF622D9C97551F294C3822644834B38FA844A035CB5458AA7240F750287F95FEB1696D88988EB0648C3CC0FA9D4277FD9AF8C579271F4C77", + "sk" : "101AB759F6AFCD596D4445B4E3A1907B3955F81641CBD1AAEF79B22EC38AF5A081A570B67DABB410AA3C78925C82384B5931908D147926230522DA5CFED372E9EB2B94900625E74CAF1098144572A3D9BA32D875C9184989C823A3F23DA4144938B88836E9C708E52967B8413F206758F578B340B2936B798775B7AAA09EFD567834E52AFBB17BFF8B11FA0435E6F55AC73219E79254E166CBD8DCB95F0874F26925DFCB93F9461B2A48925026651B0CAE117483D65B3F57B90639A39B16B1535647079F12A0D897C51CF60291A165FB884680071656C407C9E09B31977042A2AB6783A9B448AE7D924243DBADC5B00C00303C9A12308BBAA51F024884126E01346665F67344D2698ADC13159A316E4175DC532C75D40D6CE54916DA9AE3F763EFC74DC9A904D7D8941FA34E493A74E0F9032E44A84481916530573D4B372FC6790B3C357A6B6B075B87E6B1A82928037DA41F265C7A493ABAE425C11B6514A96C6E3949520EA4B9A7A18C76C53016A0CE644237CAD882D79C60739A4D2651A4E900463A224F1769A40D04CD1C2796CE2860844AC6FBC87B00379446A637F868B73BE31C57F41830D3628BABB45BD5B9712B33BF5637E897C6BAE6CFC6717DD87AC5DA5620CA04CAE154BF58F61024873F4CA93738A444801CB5B61ACBC6098B36747BF6926E78B08939116AC1604E5F61570DCA65832BA04C8C64DA99838BE418B61805B1382CC899559A62B73230CF126A701A56AEA6795E6EE95C2169CE82CA352A5C411D89881A3A992704143A06D01BA15F9F59083BB70C69FA5B7EB72036DA024A3707BEE499FA4057A52C36272579209215F21890216C0F0DC83B5DD38867604A6175C417962A8A8513DD5AAC8E0A806BF24A855C89252C392F6ACAD0404F9445B0B781BD26E15F4CF4A7D815BDEF3936001219955797C90191C7C794987C3D1D80B07C04B14EA5A6AD49BD4EC27720E68A8E855A042A8B223821DAD9B53C00912EC92249EA15AF46091714759D04B4734A5C60D979735741C9ACAA7B62B413C439A3BC7A6510C9C5900AF2177BC5104C0C079C67A03A12F923EAD47E1BA85753F822C7334E25A02A1B155E0B4C22AF82B353DB202627B2E4949A3C874C7207C0D96480C33C9070723B9CA1A2111321FE22170544C255D3246CFAA6960264AC042168922153970A6DF7A465690A7348C1EC77B997BBA243EC7508C88B730407BAC2A9B6040B83BA7E034A7388E78B010BA662D15EADE2495AE63568A12349C57BAAEBA16A32C363245F599475F7E141D1D2462076ABE3071FA2566C85197BC79B24876461F9A0082F4701EEB619CB5C4B1C169715729FE2E27D85890DEF829473D33F47BC7216030063466F2A8C9FD5E14E87374001B256A6B98D3C53094811108C1CB6101A6BB18A8BCC7BBB7B4278D030C7F04368D655C848D1A22D8A79FA787613B653CD0106723C9E8F81439083A7F022B9C98B6DC7D39C2C7B5B61F4C8DC06728741A641A9684808B20FF84A9B2A569784705EA2758C0176517AB47C22B408AB16EC20B849F1CBADD7CA82332107D41F7E6A6135365F86098FD9A66847E03641BAC2F1C933BAF967E94265D40847976B68C49730D245B5723B9F70D99D171745EDCA3A65045BF6E0625AA4955FD125D332AD33F9A3CEB2313AD50C97614D038547F22A135A33C06C61545B9A26B46C41D1830B83D0257FCBA82B36510199224855BD1A837A369A2C823391B1F84E54959A06938513681D97F34EEAA7BC42EB13574B29FB785C457786AC69CA22F644A1D53278D4C2E0F325A1209A0CA40FC32B92E906650B484E7D92CEE99A078F5090D2FB60F84B47DD44224228443D36219A081F9956CD7983AB223BCC094A0C65414CC2ABA8564977B147088EF41ABA589653E535847450C762517DFA462037C2C1457EF3D1909D0B79D66AC6ED9803CA88A7295C4A3AE53CC77C235CD8922B36BA8B837F375755326A960BEAB71AA1B33A8B64D6076F0889424B1875ED6316ED420DB7E02D731B2B3065C7E80115FC1406C125B651C2B4CED28AE9C67CC505BAE5B747E5722F4729602BD1AAF25BA333C29CA011CE36F55494204B0F70895938C9C4658044740521097D696C8EFC045709369F88C1CD46BB763B957DB8F48ABF1A07F431845C94BEB7A3A68D42AF6C2C3095F829DE51B37C134F977461AA2818073682DEF71A65291904F0C214B727FCC7B522C2A33F7A2E07A65926FA5661172103B390FDE2814B21273B318D029A112FD389D0324506D280BE8C49BB923412F4C430CA82F58CA8B7122907B986FE912C323B1758901007067153DB7B16168F791610DF534AEC8050A58296F58B7549F0665E13918C784DA2D00DA79559EE006566050482B2A13BAA4884AA83351753CD7A48E6385292A990CA559C8D630A7DD4947E428198B06242179C369741FC067DEC411765C58364D32BA655350530A4AAD934A1D14B76F55A19AB7F2DC60720124A2B69CA703030B2320DCBD459CADB6662FA0AEAE170F880797E2BB0A2F24E8DD1442549BA4510153640BA7F093ACAF41F67F55E4269260CE2AA28261D4DD4ACBC2A4A134751261991E7B36183387893C5900E8A611894C76C26217A390F86E5068A947457DB75E7214B8B05A3C87251CC2101D7E6115C908D2721AAB224B038C1B9C348A3C04C081496928DA726C0D140D363A427B93427F16841C97447698CD0F360529725EC86113594045E143659CC1A0667832F40AA7E059D0B1389048A75429886095B3EC5A646EA12A09424338C6AB729A27E595AC7784169C6E7C7BC208B07A44CEE5940F85896A7285845A2A262DA092D1B0295821975754898BAB492530E44A410F35563A1E45775613192DC45DF526CC19B6EED8186E6F706E233542A4450FA6C89BF993AF5699DC0E46965417433D5B1882340A1294D4B229D42061BADE4683F8557DAB0603FAB1BCD956B29BA8A2AF60093654F09E70F07EB3398F7BED1354A7982416AC40860538C36722CE1B37322C4A888C2359080704490B613C9A5F7318566A37139563C40D58C055B827145BD659C8FC6B7908A071FCDF0B17E4351CF3BCD9E8CB9361985C70C49BAD71F860B36AE120F62C06F3B34AA4942985D149DB7B13E1412CC1FF59DAE21CF50017883A0AAC754AE6CACBE87A46919C05752877840556AF8D56FCD848F982B415D333FD8640794918EAD0121D12309BF622D9C97551F294C3822644834B38FA844A035CB5458AA7240F750287F95FEB1696D88988EB0648C3CC0FA9D4277FD9AF8C579271F4C7721B12640BF755E94BA06204982458A9BE11E1DA542ECE4F3D284886800FC8E8EB2638686DB9A0292ADC26E549C7152FF36D9A7293BF1380BF93F1498546EB93B", + "ek" : "E304EAF2AAC98C93BF4D2162D81CE806540A0A9202E2F221AFD566514F216726D46D792DC8A187983438465D991EBF4B5FAE2948C02A6D125117A9492448FBD55C5A24A512031E779F5C30B8BE8A31D34CDE914044B256B93776C34778ED072074003475788734AF961507B8718C422485B85882637E91C0EC86102BA9CE05DF7D141C957DAB1978B237940ECACE7F92F947CCDEE34FB8373571A6EA73066B5BF8ED3327BD56AA9AC6CC4B6595AF67FFEAA6F974048A594E164796A040D54D25B65FD24524FBDA05806C9C62C0F1CC9567206CF8BD6E365CCAA8937B90D0E6054BC0A98025AB0FFE6D7EC571183AA99D1947857551C93C281C1C6FF6FE5BA5B13FA78D0615372916F7B351CA1377B7FD3E481B9C305EEA1C57044E5280CE806EC68CC387E040A50BFAB4466E227347FDD79F59D2528F139F8B3567D8420E89B24D29D2DAFA42C2663C7172949012C46481DCAC7E5C6FAFC6E85572BBB9AD8A655DEEB0F5F584A01A08998A7013A3CB6BB979F06D228A848BFAE9C47C95E8F86159B098F1BB4A337FF7EEAF8D6573D6CC397952CB0A5AC3082A8F95777D47F71044B4B5F481225FD8013006D4C455743753AEDC548CA9515850FE20079CCC5C4CED2F7285C195535C2361834CB5410329836C0A084DEB0DE49A1D7540B43742CEE6D33933D8A0D2315246E92BC9A06A16A0BF8D9E8265AEAF73C050745DB85EA20B40E05F0BA015B3EEDB2A5ED657694C02AA71A51C463151F9D995C1623DEB442BB927E0A01C05FD56F086DC36634E373EEDE0E4C7854BCCE297CE41B2AC08C57762CA9DBCC2F9676B996F17E9235059BEEA4C0CCFDE9E1B3582FA70658B447ED476239629729BD271C76FC54756C207AE96B19D0EC0E6AFCD8516FA03C8496CC325418E1E0E3E34A877B218F397CD6DE5B62F695A78273718A40C128A7D6BF9C4DDF338E24C5B2C4E7CEBBBE3DD7381947BD79B17500ED045B76CBFEE3A5A438F7E4F8B5EB5B761DD5E3F11338296BA3E3E29D8DF72BEDBA4AC175378E979A277B37DF32EE3A4FFA4CC397C8F2D74263C8B0E09D920533F3422CC756F2D1EBE602CA92645E264412F60F2D8BE0AA0A96D383EF5D936B236D6D5284F4F57FFB263904FD257CDF1387D580E595F3A9D2E916A126911AABD1888987980DD69BD77FBEAC52E902731C9629EA99FB4FCFFE6164901899248BD3DF941DC10ACE6BF667024D5941A115715B041FB641635B02505D375EC1E3319673C8486FA1F3A004CB411D7F7392CA57EC4AD00763BFC768FF1FB090E4D956D44F6EAB9E41709A5023DF2E38D38A414E69FD363E6087B4EE8229AFC670636993C01F096C8FA8086FBEB758CFA88D9D40A5CBDBBAD8F332D0CBD5829DC3EAF1563CFB06480CB55D1BC7FF1DD48C2630BCA65915DA4B179B42A2014FF9A7579B96F8AD0446CA271386093F4B1E184C3DF80942F8973C4A093E445844B3698FC16EEFD6B8F8610BC22AE062CD3F377628C644053A90DDA36CC3851BE23D0FCC944F9BAC9CBE87C6FE288", + "k" : "397C5804061C9555C5286DBF513F4D07814C0425905974353B415E22A72812B5", +}, +{ + "rngSeed" : "265EB2DE7099E4BD5614E5DE7F0C2A05C78EF3E8E2DD4AE4CB70F3E5E59C8D1D88248303F07DE0C5508652DA66B47222", + "pk" : "E770043BE600F7A60B3B370BFA6A30C846C475127924071E3120879E2A158433A2A3A7791C204912DA8576BC2722EB9E38139C198915986B58A9671FB054A81443553AD74563F587B226A9117C133DDC10DC0655A7D52D493B7B3DB9584C49B4D1F41C06665A3D07383057AD70B69F85B6CB2682238120B830681794E042D910467A24091D81322A08AA1D83B0861113756615A119503AF837EBA16768046B7E64AB5940AAD4DA6E3165AD036959C39BC69070BD7F074776089AFF76B33DCBB17BCBBE65B526C795B65943821D5B52AC1044CCA52E3403A02604A1B4D9CC84E4B72B2C136DE898A12451D8C74C280A67CABBA42DFCBEA68455C5F45BD3EC03BBCB3F72604DF70737A01683369C8A57091742C60F089A673DA350DB8BA39C2A1108AA6A4E2A6F24B13D95F004801B240B50067DD34B60991DB2A42DE3DCB2C24034D0CACD24C890CAC7A134BB183C92B5D66C7000A5A3F80898754827C9A7CC01A1550A9CB4F4F18D5959BE0EF84C35B54468C55A15D274F996CB74449D1E5B2F88BCB6D00912A9305879BB156BBCA9843610AF2C5193363177D2B5867240D207819498A98209C109273DD44A4F2A06549335A63AFB2660D212592C417B426268485A7E8693F865C0A7960E073153D5E578A74B34E9C3A57EB20FC825BA59E56359A627F358A4D7127BE7D571C991078D9630E1262402A731B14B9F0EE4A3FA4494BDE9AAF2D4603AF1178B8B49A649056FE314CAA92DF6D816FBA591FC4961CF0509D0DBB02EA7321EF75AEB20813E33A9717478BE58B49FCA3130EA2B54E62FD3243F4E240E54C08D26C5020A9512D2536C486772E725267BBA974F3A451BD50F29C55C7189012473AE1E5A7EF35C0B479679F1A71FAFB41CA6D16B39F100201BCF2515075A1C9F881A7AE4F4733B149E7C29973588C161616E9918062236332CC67F26A65FC72C78564312C429CD1F3854EB98C0CE91BE6D9A24AED0AC65BC5D805490E1D8C86963C8ADEB8755E0BCDFA473EE23037673773C46911CE0BAF8C81BCD8047A9D19175F6BC31C2997C62C502B934D7651FC51562625538E24B235C4C38CDB82FCEA4ABAA963B3D67B3679B51A21CBD77228338A95B4D641B5EB26644A58A59ABB0A8C0AFC8894792B3C6EDEC9CCF7C29C620B9CA262C634621D225228F1503609B548F0418648CAB5B9609E7486D57E5824C538037D32319427A3B077703A7368270C9B752217EB04B912A3843F4AFA829B38174BBDD1CADC8C74697544F6229068344441EE2863150716339716EA6A8245A3C3C142B986B7462FA2417A413AB718CEB196F15F887A465C8F901C55DB4718EA58C71926EA344C49635149014297275BAECC90AD1C95C75281EB885264F11123AD8CD7CF1968E885220F0964F25510539BE63263A4EB6169F7319F0086FECF996D2E852F139B500DC1FEC8824430505A7702360D81823269FF4B2622B54B7F917BB44714660051C31D9B39494A64A86C15C516437C4A437F41C0FD5922DDA52818336D93A8C750203FD859B06E127D8E33B52C34411E4199CB01CBD70B8EF0180B045119129AEB04398841BC8261444C963C3FC11C8DD4C78DC5A8CD902687E36ACA5F2667ABCCDF2093E5ECB1A4F09769A8251104731EE68587D0A470E2EE6AB99D3AF13F31776", + "sk" : "B6A8BE5C6C9E94C1B41A52CB1165B3E857604EA413DC11813442A518BBB3E1D84724109F9B1288F5F34D06C3AA30D913954C5C053486B60B254F3250E9AA656DD71553679F5F112D8E8C7F11E6B19072AB3784284DCB2988CC10D673A423A0C202F03CDCC74A43422A2FD3B934B67BCEB074A349B8524786F6C126D72A384C0A84FCB8304AF2C3D65994E5095274D2715D057B920AB40219AB156CBAF7C314FAD57122505ED15A61DBE66CD83BBACDC9B3D3A1AFB0D607D6E01A3E227D3109A1EA14696D84BEB84C0CD02B2964762A36F153A8B82733872B0BA6103437A191A59439FC3E2EC899BA841DE42BACAE534BB3100854283175548AB055CEDB836B49FA5841CA698571C4794C7648C65D5FBA44B3C57D925AAE29CCA857301F61B6940BBC28B634BBEFCB51037C301674297170469CD7CCF39A828D2110F8F3B9CEC915C6423163D90B2DBBC644864A6F8761E83371E2C3724617B7CCC893561337BFE7832CC4A0636AB871F07FE9B93B7169029BEBB7AFBB02AB249AC3597E0AD052B233A454F6628C52C6727A4267447BF11064B61A1BA6A4B7EDA764DE23B0BEC1B954D3C5882432E1BA6EF1B94EB1464086EC2A5AE0167EB8B5EA2B40C01953F223544E49BB5C441174537CF8953C74D318A5B4B6190881CDBA5B1305B6A3E2528C4C8825107FE323CE9E979F5D33AA20712B6CCB5CDB449989922B8E571A71CC458537BBD8E9A696D644C713BD25607D4C26A39BBCC11D58A4154C1161BB1E771986A4D923DC9936806498CEE91C3FFA819BAA73D1103B868772340A1B1AB664CEAA82D60B328E2963259C039E12798ADB66E62B827FABBD32D7B29E615AD76CB5690550AF975C2EDC1AA8849566CC8BD2639F009453D1FBA689BA14D5C68D55EC1D90074DE4B47A84944714A9C11D55B271727C64E566762459F7E381763981776665C3D908110A74B7977678E011C36058DE9606EA225084331C0F2479DE36C333C26122BA9FCE2B360628B5B8919838829C2CE55B12A6B80A3A5EF01998549A1A26223A96916DDB8A0258B5AC936B74D496B8BD249412176B697182054B744301C2A3B10B2FCBCC11CCC89FF5B40F079817C186893BB044559AB646626F683191A03FD6F41506CCC6F49627C09A821CA427E8122FF91234D5D92318863AEBE86466F108E9A51A37822A990BBBA5E01292543E756B64A2191FE855844185A673C584A2C0897E1B73EAD8CE548833C03447DC32BFE6F0CF615469CA61C376A3365FA6CB79C6129636C48AD68DFE2C1553F01DDE270D1830096A03072095BFA24282F1D100C2673ACA13C1ACCA01F158AA3A593D0B78458B75C8F34BA4F9391AFE255DCC715ECED306545A6A683191EE731CAB1177532882D301A482677FB4C38D6B69201F0920162641F7F701290969D5C63EAF13A133563E95AC5E88A42F4D128B9C69B5C3F16B76A6731FCCBE6F58547799BAC3C9A6F3CC9A13AB0CD26A50BAE9774ACBB86CE8944FA01B16840A8B220D7886197F671E64A41886C80AF2F66E899155B125181118697DB62A4A4A0DA162240E0218739CB439406219C679F9857DBFDC73D96A0F7A3181EEB3B38D8B31B7DA8E65F30995F778EC5B4026A28EE770043BE600F7A60B3B370BFA6A30C846C475127924071E3120879E2A158433A2A3A7791C204912DA8576BC2722EB9E38139C198915986B58A9671FB054A81443553AD74563F587B226A9117C133DDC10DC0655A7D52D493B7B3DB9584C49B4D1F41C06665A3D07383057AD70B69F85B6CB2682238120B830681794E042D910467A24091D81322A08AA1D83B0861113756615A119503AF837EBA16768046B7E64AB5940AAD4DA6E3165AD036959C39BC69070BD7F074776089AFF76B33DCBB17BCBBE65B526C795B65943821D5B52AC1044CCA52E3403A02604A1B4D9CC84E4B72B2C136DE898A12451D8C74C280A67CABBA42DFCBEA68455C5F45BD3EC03BBCB3F72604DF70737A01683369C8A57091742C60F089A673DA350DB8BA39C2A1108AA6A4E2A6F24B13D95F004801B240B50067DD34B60991DB2A42DE3DCB2C24034D0CACD24C890CAC7A134BB183C92B5D66C7000A5A3F80898754827C9A7CC01A1550A9CB4F4F18D5959BE0EF84C35B54468C55A15D274F996CB74449D1E5B2F88BCB6D00912A9305879BB156BBCA9843610AF2C5193363177D2B5867240D207819498A98209C109273DD44A4F2A06549335A63AFB2660D212592C417B426268485A7E8693F865C0A7960E073153D5E578A74B34E9C3A57EB20FC825BA59E56359A627F358A4D7127BE7D571C991078D9630E1262402A731B14B9F0EE4A3FA4494BDE9AAF2D4603AF1178B8B49A649056FE314CAA92DF6D816FBA591FC4961CF0509D0DBB02EA7321EF75AEB20813E33A9717478BE58B49FCA3130EA2B54E62FD3243F4E240E54C08D26C5020A9512D2536C486772E725267BBA974F3A451BD50F29C55C7189012473AE1E5A7EF35C0B479679F1A71FAFB41CA6D16B39F100201BCF2515075A1C9F881A7AE4F4733B149E7C29973588C161616E9918062236332CC67F26A65FC72C78564312C429CD1F3854EB98C0CE91BE6D9A24AED0AC65BC5D805490E1D8C86963C8ADEB8755E0BCDFA473EE23037673773C46911CE0BAF8C81BCD8047A9D19175F6BC31C2997C62C502B934D7651FC51562625538E24B235C4C38CDB82FCEA4ABAA963B3D67B3679B51A21CBD77228338A95B4D641B5EB26644A58A59ABB0A8C0AFC8894792B3C6EDEC9CCF7C29C620B9CA262C634621D225228F1503609B548F0418648CAB5B9609E7486D57E5824C538037D32319427A3B077703A7368270C9B752217EB04B912A3843F4AFA829B38174BBDD1CADC8C74697544F6229068344441EE2863150716339716EA6A8245A3C3C142B986B7462FA2417A413AB718CEB196F15F887A465C8F901C55DB4718EA58C71926EA344C49635149014297275BAECC90AD1C95C75281EB885264F11123AD8CD7CF1968E885220F0964F25510539BE63263A4EB6169F7319F0086FECF996D2E852F139B500DC1FEC8824430505A7702360D81823269FF4B2622B54B7F917BB44714660051C31D9B39494A64A86C15C516437C4A437F41C0FD5922DDA52818336D93A8C750203FD859B06E127D8E33B52C34411E4199CB01CBD70B8EF0180B045119129AEB04398841BC8261444C963C3FC11C8DD4C78DC5A8CD902687E36ACA5F2667ABCCDF2093E5ECB1A4F09769A8251104731EE68587D0A470E2EE6AB99D3AF13F3177695D9E5B9151D87FED52E287992ACB897A07B10ADA1DD83409A5CCDDABF9D7CFA3AFCC6703873BA41A425FF19559EE47D056D3B5B9E567E5CF24EA17010A5C3CA", + "ek" : "926151A30AF8152E47EB6FA3A09A074AEC41045049B7ACDC9C23117809646FA7056E44FE86283B47B57137E55CEAAF170C410B0E42D02C9EBF32759173F2FDF9385438B936932CE6C17865635D0B8B012FD1D510A662E899B5CE157AC252A73C82A2DF79E19160464E84D89482C0FB0A16C7A2B39E858E52CA1B84268413C66C130A1297D8DFA076CBA800B54CE5C5FE90760F05CA4BE199D5771CB85316146E68C6C995599D25521C68B82B7B2BDF008C5B10C6ECEB5A6E657F4B6D598C4ED41613D9927126079B7E780E2971CE8E5A7399815A2CE66E34F458D39409D3D19738332E3213A0C9C267D0723B55647F8AF2D6DE141A670012B50B2E548923790B238CAB35E08BC67B2F4D5AEBFD2994B693884FF7FB7BB4B9C1BB78B05C03B48D25202A36C1AE78B0C5C6A82DE4E3EC4E54C6C87B62873CF0CB6644D02239ABD6CD618B5999B1376D5046501936CB12FB066E10F53DD5EB3278F11CCBC7951A11668169802017C53CA02BE83A1C6F28A786B1B02A56BA42D4657D9F2D0987972B9CD929D90EC070A46E9F5B007E1D61B8E5452785A0AF1D53B88175C0B69BDC9C1BECD95504187272A8B00D9DE5621FA6F770FD5E267FC0F0B8F4AB4BB17AA4D61DC276FECD5E7EEC31A144CB59FFA2E7B0B85A3E1F64A242558C9AEF6A47C429814E282081CC4B00D0A8AC3E3359B0F16BB029F062D843D13277ECF58D633CDA64424643E4EA9C57A5113277BE86D70A4D9EDB9971A576D1E87F40D40CD7A6C421D0D9050C62C6E554921D5040A8C7C977D5902CF5281E3CBC0FD7C8B882FF56F15312A9D54092DD710D0052C0967576C4911E04A05513903AA284B8F89AF35221822BBE6EF9F56DBDF71BCA6E644E64D9B7ED6FE108BB09DF17EBA1B7F49521D5640365061D0F3E5A9EC55207088B63EF65CDE265676294EE4F45EFEEDC9CA66CEEC409EAC2BB055B4E149275782B9ED186774BD92FF4EDE21A6AD1577AC90BA4149A667BDDE5B4F82596D6C0698B29BE06B72DF3649BF892C1DC63ED92D3D8BA8624264584EF413C0CE599922300F63F3E5C2053D8FFA606DDE0446354795E8EBBC613A2EE52697F4A2AFA05C5E057D1F872D00119CF4377F0BD36FB6E3ED6A588346B553D2EED8AE0FB7036FC56B503CDDF8E19A96F8753E4E0295CD77913FE0E3FA8B928A69A84D23AEBCACD01E017FCC67ACB13790664AD112CC0B552B7168D43B00CBE296F8BAC4122B473D15D152694B451D9F726FF550E23CB573ECD7ECE8406E63BCC78697A343205D52E7208686397CA51D8749D1C642070719FBE40220DC40A694D02B0390033C1210E4A16D2EE757E723657CE05036A7199B200B4116EDA5A1969BAAF2FA96AAAC6292D50404DF5D04F5AB9785D8B6B834A121682F6C339491377214E71F3DDF6083975ED5EACF3CC6D476C5FD6A8F45ED112BE886962C2B68D447621ACEB3C77C3F002662D9FC6939B8858C3EBC84D3A9876602D7FA6034220676F8D936889B1D6D048E45CE3B90C6BD0D6272E2DD0B231A08D", + "k" : "16577B70172B04CF9A9FC760E113B6AFA2AC0A3D95C8D29B1F4CFD2A039E0CF1", +}, +{ + "rngSeed" : "806BBD111F27C2668318387BD0830F65EC21A51AF01985EF48D03D64E1958FF7EE5133A4EBF6DBF36329BCAAF65F40EA", + "pk" : "13568B12232135A5896094834CF450D789BA498787368B4E15F1B087A704E8E327D631290177ADD97C0A0D84820CE367DC515FC362AAA98AA7911A867A3789F69A5B68BBBABF3AABD037B5160A3F3D8277EC47898FF3BA5DDBBCA6980B5AD47C59236EB33B2A9C84B212E93D9E70AAE78A4F9F6BAE592AC2B5F96EEE627971D27389905B215869D9F4B706C379AA802B5A99ABF754CA9316872F033ECBD5B34F72C610C14037540A2C86AC7EAB0C3AF84729C48610615C9956751759660B3C7BAB57146F7B1088501FE14B2F59141B1BC6302D88A35FE27E0CFA18C1A22A9EB517CA6060F25408D4299A7F46C458B3BC38C4794BDA8F9079043854179DB0071AF69C9F074A83438874C882CD18B69B0B2009497B6FE94A9264470BE8256B49B6C353374AD49C04B1276FD484338796E4389A523598F3776291512E25FBB5FE98591320C1BB47C6EF3B4BD1D62B6997B5561BAE038854CEEB41B2925C1F1A81A702B57B2815F62AA9EB2625FF3512CF9595073CA623DA43F32C21D63297A491B28DD8B1361BBC91B40B34A65F1A2B7DB86B0B3BD21B26CA5795B795E355B45D1623B3A9731218174B50966D6937ED057FB10B631A51B7D42072A0845BE8553E19901FB0EBA35F5142C75857F642918BF24544355C4041102D8B197B429FE548433EAC36C42077ED787F8E631EDB856D4398A26D536911EBBD9F9C22769C756F858D180B6B51797FE9EC0833C908D9AB2730D937B76A0FEBB68FD84372C96C3C05197093E26D01219C15F898B2C7AC75D11485A2A413A065BE744E0908B6340155A244838DDB14B74C578FCA2D7E6C4E15E68421A568E7E39A4A04231926768AC4A061D67550A8512E780198738BF3E2420CF75680D1CAC07798C01CA06102CB2AE5C9B99B62A7349FC8A2C558989B68E3789C2C7074B476D18212846C8A8D562166829A36587EAFC95A362874E812AA951A6995F5A94D370AFC9B64777A7E58CB54B62A95476CCD323073D6E466E6AB909B4B4CD840AFF393C9391902F4C05BEA833D254207CFE938669CBEE478C57FF4424004003D151FE5E90413924BF1378419E08DBC46911E2AB2B7F45DCDE5C549F679691632C3D9BAE26B9FDB85C7BC3301A3900386873345974BDC007F869155DF79CFC6F06C39D8BC9A99675382358BA25836A15CC222AE78E4A85A19C5DA9912E48128FB37A7F386C0FC86AFCD2869E292CA9B521E6EF9B12908CA5D800AE1A7A3A7070766E2802A947C7EDB3452A377D9C1BCDB152D37DB41CE7C74C36B32C59131B1B85F9B68A3B66773EE4A2B81F12509C33CDAAB4CAA563E9BFB3CD9C4C72354C1E88423F94169E18BAB1A9798CB99031FF852E79229630C8F35459BF40C425AF7CB0843498A3CC7FDA53D932A07382018DE07808AAC2B4D60A1E242BEFFB89489BA69A6A26446180103C11F7B22361F651777B997B76CA8F5A25B97291058620EE5479E92AABB218444AEE52E5C8294D578C709158F655A8930FC197F765FB3790BD62A5FE11B57F273775DA27FC1B5128663C623F5175513B753543BD71AA045E77E4BD42B7E7BAA5AB2C4D3C41F4DB84AF265ACECD4906FAB897B5ABF5AF66B4C4A0B4E783B417C6FADD71D34EA294CCF8B8C8012EDB8BADB3437B191165CD639BCDE9EB71378E71FB55129", + "sk" : "9D4548BBB50474E5909A3B1B9FE69C379117A840ACE316A8FE3A0F68CC2488C4737F5469F025BDD6378875B173EA5B34119481B7A23388D20937EB5D85A566C8695106645EC3CB1BDC1400C1F3220669B2CC09AB752205EF2BC16961278EEB863D2C58DF1C77FBC01D6F298B89049326314323A49B99C7064E8AA44F148616AABBAF76800101406AB7A34402A8DA606AA9E2560DEB8F00A14072E204FEBC3D2A48AFB18608D03AA8C0A1CE1D591EE79676447A1657E19897F20B0B19A513DAA2CA415AD65A2E77066606890C5DE69E45367A668619E7E4A38CE656FC3702E5185142F65A6BA43D892B6F086AC0E6BBCBE0E04869EB48921936EAD6C91FF3AF5311B10F2622C1B137A5BB82B63247D6FB12200901E93ACF5E3466FF8160D7677A0F9825D2CA85DABABC27B24F3E52AA957B7371685E5FB56F1EDB91D66C8EC23287846119ECA062D9050CEC162A8A6332CB4087D9270C7F022773C6664FD74B85EAB209D15E6FA2145297232394138BC54CF4C6CD2841A65EF48CAD8384A957B42885236821A3D152B631F01F1574B28990045DA08EEA352BDFA8BC79FB621C504DBED81B0577AEAC881026322C0F295216019BB3A11569B74E91D019A6DA89CACA94879C801B331C115896054750FA6111207C0AB1D2BA8B328912BBCCC2494A300356041C7CE28043880B56DB58C78DA121B41AB4D2127711C5088ED232B7B536BF00B542B15800ACCC5B3677802807F0B23878258D18071C1691AE63054D3AEB129798BAD2F11B64238D7E83CEC2717C023B5E7EE404555393541191AFD8B7A79A88C36A2F711C3C2B79C64C405A84F2722643458F4C6CCE4CB2556963926C42303C85D87861F4055673B7405C5B6760BB52909290168C50E7F599B798B2F6EA119F3A387D59025954C2571B095D6C761D2932D5A79761F25E52C8A64C765B2220A3DDC38039D7658B1CBDB770574F0464875B7E5C9585ABF8B4B9CA9391C1A6EF647063046DDD857F7811C075250621228B80787879651F5843C175EB86883A73CDF97EDC6C6B79CC917CB710744B44A9D455CEC7A0C81919B600C755B8506003A86ED3276840AFD59344091A8430D4705DDAB1DD849B96D7238EA9BF63696F709532FD49B0833840E373336C8119A1E229E4881B23868CE260B3B3378FEAAC8730E69642CC068B4A6B16A0C83E4A484DE007B6EB2464836242F7279A754A73E3A8CF378EEA351FA7393A3BAABCBE08B23AE9887B973B6C653B1BD06A5CF89326D223C365791888B7010795F0C056428425B0F647230C669128B9E0865152AAB666561D43BA060DECC51A4AA7A0E20502167B69F31D2E6B8B6C63135D91AE1B899AFCA84CA89BCFD49A725184A6BE2289142248439AA568D9C18F492123301792A1CE41FC15C0739D88D05C5AE4508DB9936717049DF17384B261E8E1910A70CD56208689954A50A41711F9BB170ABFED596FE077053603694FF7BBA7F41789801DF0E64119E962594716C585A30B13C44CF97D9BBA5D577285827537688976933569CEE793F24733656B97AD6475024CAC8902760FBA36ADA22B9086187AC68DFD26ADE8E66DC8773F4EB764D322732450675FA715CB02095B326BD0970713568B12232135A5896094834CF450D789BA498787368B4E15F1B087A704E8E327D631290177ADD97C0A0D84820CE367DC515FC362AAA98AA7911A867A3789F69A5B68BBBABF3AABD037B5160A3F3D8277EC47898FF3BA5DDBBCA6980B5AD47C59236EB33B2A9C84B212E93D9E70AAE78A4F9F6BAE592AC2B5F96EEE627971D27389905B215869D9F4B706C379AA802B5A99ABF754CA9316872F033ECBD5B34F72C610C14037540A2C86AC7EAB0C3AF84729C48610615C9956751759660B3C7BAB57146F7B1088501FE14B2F59141B1BC6302D88A35FE27E0CFA18C1A22A9EB517CA6060F25408D4299A7F46C458B3BC38C4794BDA8F9079043854179DB0071AF69C9F074A83438874C882CD18B69B0B2009497B6FE94A9264470BE8256B49B6C353374AD49C04B1276FD484338796E4389A523598F3776291512E25FBB5FE98591320C1BB47C6EF3B4BD1D62B6997B5561BAE038854CEEB41B2925C1F1A81A702B57B2815F62AA9EB2625FF3512CF9595073CA623DA43F32C21D63297A491B28DD8B1361BBC91B40B34A65F1A2B7DB86B0B3BD21B26CA5795B795E355B45D1623B3A9731218174B50966D6937ED057FB10B631A51B7D42072A0845BE8553E19901FB0EBA35F5142C75857F642918BF24544355C4041102D8B197B429FE548433EAC36C42077ED787F8E631EDB856D4398A26D536911EBBD9F9C22769C756F858D180B6B51797FE9EC0833C908D9AB2730D937B76A0FEBB68FD84372C96C3C05197093E26D01219C15F898B2C7AC75D11485A2A413A065BE744E0908B6340155A244838DDB14B74C578FCA2D7E6C4E15E68421A568E7E39A4A04231926768AC4A061D67550A8512E780198738BF3E2420CF75680D1CAC07798C01CA06102CB2AE5C9B99B62A7349FC8A2C558989B68E3789C2C7074B476D18212846C8A8D562166829A36587EAFC95A362874E812AA951A6995F5A94D370AFC9B64777A7E58CB54B62A95476CCD323073D6E466E6AB909B4B4CD840AFF393C9391902F4C05BEA833D254207CFE938669CBEE478C57FF4424004003D151FE5E90413924BF1378419E08DBC46911E2AB2B7F45DCDE5C549F679691632C3D9BAE26B9FDB85C7BC3301A3900386873345974BDC007F869155DF79CFC6F06C39D8BC9A99675382358BA25836A15CC222AE78E4A85A19C5DA9912E48128FB37A7F386C0FC86AFCD2869E292CA9B521E6EF9B12908CA5D800AE1A7A3A7070766E2802A947C7EDB3452A377D9C1BCDB152D37DB41CE7C74C36B32C59131B1B85F9B68A3B66773EE4A2B81F12509C33CDAAB4CAA563E9BFB3CD9C4C72354C1E88423F94169E18BAB1A9798CB99031FF852E79229630C8F35459BF40C425AF7CB0843498A3CC7FDA53D932A07382018DE07808AAC2B4D60A1E242BEFFB89489BA69A6A26446180103C11F7B22361F651777B997B76CA8F5A25B97291058620EE5479E92AABB218444AEE52E5C8294D578C709158F655A8930FC197F765FB3790BD62A5FE11B57F273775DA27FC1B5128663C623F5175513B753543BD71AA045E77E4BD42B7E7BAA5AB2C4D3C41F4DB84AF265ACECD4906FAB897B5ABF5AF66B4C4A0B4E783B417C6FADD71D34EA294CCF8B8C8012EDB8BADB3437B191165CD639BCDE9EB71378E71FB551293A7ACFC3D283541D985E0ABD85EBA5315A17D6C4A7E4F248673DA60C341C29FEA4CB53697A77FE6E39EF13C7460D657197BC1C7EA3DF65B85C8DEB43A058BF1D", + "ek" : "384DC8E3565B4341CB56D4EE7EDC8F425070CB54A31D655CEB7892BB05034EF8C76A46BCC7F2743B59E5E6CDADB82B796F2453358DCC0B4BD99D0DB5B0551715C3AFC69559290F43E45CD8C66F8CABD3EAC91BDDB1901DDAAF707C274C5FC8AA79CC1EB870770992A989C29CCA670364FC3C0302ADC876F055CD8F604EAAE006E6BC7328A92B5C9C76C2C708375578A01017CAA6A88C4809704939EBF38E02B6907059BAD2125C908F1409101DA2D498F4BF1111DADF4DE751848F2CEA4E7A91ADBCFC581932F51E64768B6A6B455C363B0465BD4EB5226FD07F5A9C7A0B4A74305ADA2C7C2AAB1FF4751E2332C39104635A7E388F84CD4B8265EF7E34BEACD0ED48F7D07E9CD6E1416926FEF49E3DF65DCEC09F54D7B77DE52612402265BCFFD355932ACDDD63352E030762345AFA67C0C2A98DDCD1E8066DA10204E765DC14F74EE2A6A24B230A1911537694A05BC0DDBEC18308D128CCDC00B5C62E6003F309978A6E58C64D2298ED13D47601710EB6FCCF6C1AD10A3C54EBDCEF9AE752BCE2D79DF33741D66199529E9BE864C18EE8A4F0F1BEB688E521BD92DE2A372C41B926A26329EB6E9B063F4822CC74366D65EC767C8D72DCA2C572C89EF24ADB035D4A94B57F6BB408307BB6167A748FA8CE581293205FFF0C56E1D7ECBB15566DE1FC60FEB9ADA74AE089711DB791CF7C53661C79925CAEEF0FDDB05578CD1F6C21FF73707EABB124F4E3D90BCAE6CF520C5CBF02FA2305FD71A034BDE9EE3DCDD944550D42F92FA64388D92E4416E2B7B6270384090E25973A48BE8607AEA4CB0BF9AF079EE8DE59C0744D2D697210AC4F187E5695834D15833DC48AE26EE22753EBC8519D092E3102EBC47C6519D50D9F1D9EF78A2E0C61A22892C43A5311CEDDC1CE2A96B35CB71338911237C8DC5633807E80379235F70A71AC854651B20EBF9590A89160AE364B4B880A0B0E10A3E4CD8131CF9FAD449F6B1944E4173836BDC7B6DA049584B9860A35EF7D8433F9946E7F8A6A80F5F1CA337E6D90911D08B5C68EF990DE89CB16CB3A4E0FCF537D9E0DA6EF462774B8CC9D6175707D13507BDD1701E154FFAED925B8EB53363BA835F6F3784F18722E86A12C6E615871D7AA1B448C01FC3D9D5A66165317B6905AD9D30E8D207737735BA7B947E39CECD7F56B6314FD8A775891CBE13F5C89DF0B02DD03EC0A393C4D84A65C349BA747C5448C106EA75A7FDDBC8B3421D104F799CC4D3F8109F8E39382417E69510E926EF6F8BEE239ECA3D6FC957C87800B4E309492E5E699ABF663563E1B9B8E67FF9FC8D1666129F93C4668CAD37225649B6CA6A168A51E6213BD83B40828C075796B6F1B348829DF94BE04F284EAAE4C18B2E50A9BB0E421D36C59ADC2DD9E1A8D1B5C9AE0053F74B5DD7DD3F3C333B92110E5B937D65296CC1D56DEC577968DE5D37A00CAC34C78CA532706741CEA0BA8F16823B2D75CCAA2F9ADFA0398B97AA94DCA9092B4153BAC1446E5E7D6B293BEFDA317D466578ED14CFBF19ADFB3723186", + "k" : "800ACE8E945EDB4103387E71514047E98324DEFD800E2A8C53FAB29CDDA13050", +}, +{ + "rngSeed" : "AD540A9CE816D6FB1661E5483C44F6FDD00C9E7BD1A8CEDA4B4C4D3697D4F78ED0A56954996CCB7DA96ECB8F5CB15809", + "pk" : "B30C011788CB97CB439789A67D476D3DD265CAE63CBE43CB63AA124B93071D6812BC662F346481F974A73B16A505C48B9608359A3C035135258029A18B0217461830785379D3355FF3968D3C63A46685902425660B232B11B93997E60AE0A5BB95A27D553081F393040B1C30EC87535FFC6FE528B1E9866CD1E69520E376E0071087748691DCC057B95CD4C60707D8B976D6A67AF4869D960D5466A9F3251DDE92CFE8A0B03EA2C43BF03FABC9C9B5D97EA2F558B2BC0EC1908335CA4F2607CB04380A830B245F8B43FD06098269BF9CE33FC07C1E68A05F63560D70544EEA4C0BC528859A5B09683B8B3D3C6842E6458061B7DDC4B23EC6AE83D557E5C4B1848445FE253B35E52102517CD38030E6EA28A5E1A24BD09AC6B83C5DC658D11589900A7BB09A963480A2D76225AE55BC54108FB233785174B375A184EBA110E05762E7F26139DCA4CB197620156C06E47E5B74A0970BC6E18B1E1C919A6C0B10E7470D5CE09E2719194DA0440AC3AACD86BF724AA841A83DCF64C8E1F7704397A4CD57BBABC9A0CF940E97E8921211006044228632382EF48FB5D3B65219A5A6983AD0E48EE39081F2BA1103BC9C6314090A31AA34213C0C319EEAD96B865CBC98327570B965BF00CB9BAC18C640273D342CEDD11D72E2078399C458068439A8A27E388D3F4BB285B63992B5A4354122AC298222E39D31CB886C4958F28C5C2F37384632B4DB216B43CA6246051FD704B5969C07DBD525AC6A479E730F8B11C5D41111AC65764FD71A4F43BE55C563CEE5C26C69CDAA485D850C2126F2BB16F5766FE86BCE17535198CE99C2A66918AF96641B2EC74BE2B61752076A2DB330984CCD7021CE360A0C488143648389F492BA20AC566CF401383A496991497208B760D36DA6896BB3587788597191C3347539BE92B78CC6A2B0D8EB4188320CEB8AA6EE1018E9F78F4F8097AE7527EC947CB1B27DC8A86EE200020127531273983BF66746A7B731464A6B1524B18744A8C606648B2FB1A4339D5A15D7F6A5EA3A1C08122B773AB09564792FBA2E28719A603C3ED0850F2D5045DE3BB93DDA7A84E692C25537EF695787FB0889107395F87C6B836E138BBA9F4A711DAA421A396F556C26E3778F4D364D5B1844118B367D78AF37836FD7A9637F1714CD9A3E52155B0047468B5420CD5C6BB64138BA16863E18B4368542800B378537B5CF303CD2B191CCF783719142FFAC1AD0585B1938281CEB5C86587C43B28C49D9111982BA7AC567E1FB64D8E3C450730305CC2E4E12CC698A728977CF1C9B373F051C17F1935177AE90AA8856A5A24D18A08AA942B4250A6447C35289CF0B334AF45647E21B5A2153A8A05A38AC4C728A3350A15502CBA347A876CC4BD12034935BB3DC14435930D912AAC8A787DB3CA33521637C5159B015920100B416D22C18D6A0A52612C7D75C15741B6954AE752C4D31FBAF1B483B6B6862E6A983D5465E3B7B80E1654FACA5C669E77295F86263D344031B5EA7AB99E714C0A821042BD9512677AB9E89309F41CF47944DA1801521402F211A6076490AE393818EA2056954B24A624E6E54ACB7D5BBB32C14B339730AF6A72647A66F761BBB78012A76540763CB29DCB9B8C27A3C1E43769C31AF3EF54F7C8062D713CAB3803437E759A01EE76FBA1A5B", + "sk" : "B141B7D0D3C420B8548EBA8E71F2A751882023A2938A0628FEA97EACC45BD2FA0E89F485E57355E9C58B57746519E2538060924D9032508A508A8A36382254B5880E77248C6734C7F841C309830CE19898233116C0482888C03378B5946EB53E4A59B190B62DBBA173D4297405F9CD189C76FBAB0786FAC8A0E90EB3E8AD689726B1F8B321175094260775E143CFEA2C22A5AAEC749E7C7002CFE8AB16345ADAE43B6CA04BDC21632F799C77DA62755184C51B3535830277D83ED07574FF8A478C06A7DC817AFEF2684C00784865116FB8755CF13D19750E01AA165132C2844C1D27409D975BB2B0C97FFC7222DB3B13D47C8A5EE20DD147307BDC65B3AB91BD6481E17686D2F1534C0C73FB633260930A92C25ADEBC2BBD1299185439D0811EA303551E0879D825CCB08B7E307BA37B843854215EBCCA1EBA3237D95080C317979DA65172146645A543BA045F13851781028669C9B4CCC217D5BA8585A1495D652DD89B402C87043E285D3B0C72EAC388960367A428BD3E7A903FFBBD83614DF2B33180843375F1C9AF398975FACA439B0A15B2BCF804C340176400D1B80E399597372B53380DF0C61AC2F0A1757616825C8A3F90CF227CA44FC88E8608162232B1B5B882017843A6B61AF95193B6375951CA70ADE7A525633C75333450CBB38338A493099990080D99A788426047426CC89146B4AFE079FEC981884A4BB1A27931074A88BC9BC1271C40F2A8B6A1BC0CA4A24D71024BC7ACC077B97CC47531D21DE9F94FA8DBC522F78F698C77078788F6D90F67A661095B942CC5A349076E79EA90139CBF9C2216CA4C704F9992FB7A213C0B97D2BC5FC3491A6CD3BC599C9EB4D1469C3A3EFC14B7C6020C4A85481CD86D8C2B2F51410AB1CCCD55458BAD9422BAE77C1D544CC52C94D0D22D2E9783165548BAF519BD05B4909626DA8991FB48CB82B0C3A25B34F3C57A537039DBA031857B40023B6AB8BAA64B5234DC5403BDF3AA647CA09BEC6F32148E99DB47C7D141EDC70C804B722559CAA7214184BA97BA9802A7604604E90510295B21204B22955402EA572A12122205ADE2D1524E57B85ACACEB767086EE1218FD51F4799BE7364137B364DD2F832E8731605C9C69F4848B3237B51AC791D4A5A3ECAA5EDD29DE90412CA62C5556A6389EC98948735E162745F383C9C59A99764583D19C72255454B568B908A0E0828B7DD235DBF2268416C1BE640289606609F0122C0B492169954CF201A7D654E21541EEBE5448B0175D9B10314397A6632865CFCC055E566B476BE03773781B35842B6583105200E1CAD7475BF95355268AA1CFB1C7C16A68D2C38B92B6841C0B545C5E972DD7794110B5D34CBAFC9678E66D100AB1C6A1E0B5C262148F730762086BB7FD017AEA3069EF76C71C110DB4C80CB2C4FDC8C779486223920731906CB4553A00A400A3878AFA709079354A7F3E3795AE77698668FAB278688F3B21558306EE6844801B625B017203AB715D110FD636F4FA3C2C3C56ED43879468C9CCA379D3CC77197908C54875B0AB7B35EC8B774B5AD15D3CA75291B1CEB201A959B57215657606DBC9B8F1C124EB8A57C6146B1931C019A0A94EA266F441B6520B199161877B30C011788CB97CB439789A67D476D3DD265CAE63CBE43CB63AA124B93071D6812BC662F346481F974A73B16A505C48B9608359A3C035135258029A18B0217461830785379D3355FF3968D3C63A46685902425660B232B11B93997E60AE0A5BB95A27D553081F393040B1C30EC87535FFC6FE528B1E9866CD1E69520E376E0071087748691DCC057B95CD4C60707D8B976D6A67AF4869D960D5466A9F3251DDE92CFE8A0B03EA2C43BF03FABC9C9B5D97EA2F558B2BC0EC1908335CA4F2607CB04380A830B245F8B43FD06098269BF9CE33FC07C1E68A05F63560D70544EEA4C0BC528859A5B09683B8B3D3C6842E6458061B7DDC4B23EC6AE83D557E5C4B1848445FE253B35E52102517CD38030E6EA28A5E1A24BD09AC6B83C5DC658D11589900A7BB09A963480A2D76225AE55BC54108FB233785174B375A184EBA110E05762E7F26139DCA4CB197620156C06E47E5B74A0970BC6E18B1E1C919A6C0B10E7470D5CE09E2719194DA0440AC3AACD86BF724AA841A83DCF64C8E1F7704397A4CD57BBABC9A0CF940E97E8921211006044228632382EF48FB5D3B65219A5A6983AD0E48EE39081F2BA1103BC9C6314090A31AA34213C0C319EEAD96B865CBC98327570B965BF00CB9BAC18C640273D342CEDD11D72E2078399C458068439A8A27E388D3F4BB285B63992B5A4354122AC298222E39D31CB886C4958F28C5C2F37384632B4DB216B43CA6246051FD704B5969C07DBD525AC6A479E730F8B11C5D41111AC65764FD71A4F43BE55C563CEE5C26C69CDAA485D850C2126F2BB16F5766FE86BCE17535198CE99C2A66918AF96641B2EC74BE2B61752076A2DB330984CCD7021CE360A0C488143648389F492BA20AC566CF401383A496991497208B760D36DA6896BB3587788597191C3347539BE92B78CC6A2B0D8EB4188320CEB8AA6EE1018E9F78F4F8097AE7527EC947CB1B27DC8A86EE200020127531273983BF66746A7B731464A6B1524B18744A8C606648B2FB1A4339D5A15D7F6A5EA3A1C08122B773AB09564792FBA2E28719A603C3ED0850F2D5045DE3BB93DDA7A84E692C25537EF695787FB0889107395F87C6B836E138BBA9F4A711DAA421A396F556C26E3778F4D364D5B1844118B367D78AF37836FD7A9637F1714CD9A3E52155B0047468B5420CD5C6BB64138BA16863E18B4368542800B378537B5CF303CD2B191CCF783719142FFAC1AD0585B1938281CEB5C86587C43B28C49D9111982BA7AC567E1FB64D8E3C450730305CC2E4E12CC698A728977CF1C9B373F051C17F1935177AE90AA8856A5A24D18A08AA942B4250A6447C35289CF0B334AF45647E21B5A2153A8A05A38AC4C728A3350A15502CBA347A876CC4BD12034935BB3DC14435930D912AAC8A787DB3CA33521637C5159B015920100B416D22C18D6A0A52612C7D75C15741B6954AE752C4D31FBAF1B483B6B6862E6A983D5465E3B7B80E1654FACA5C669E77295F86263D344031B5EA7AB99E714C0A821042BD9512677AB9E89309F41CF47944DA1801521402F211A6076490AE393818EA2056954B24A624E6E54ACB7D5BBB32C14B339730AF6A72647A66F761BBB78012A76540763CB29DCB9B8C27A3C1E43769C31AF3EF54F7C8062D713CAB3803437E759A01EE76FBA1A5B21916DFE025B78FC6D4DD1D1541B51CD3EECCA90AE52177431B33C708FAF17B5195927B10C3BE5F19FB055A71CF9610FDC0F03E23FD09EEB8C63B7BA3C0FE642", + "ek" : "3A6003C5A8F40554A2F6B0C1ED3C5BA71C55D519AA725B7155375787AA6BD8C678ED3690CD1D98A31F5DB575A49ED42A3A88BA0F8E1145717F8DCA3ED89CB46386AA93D062C1379B300A68CFE35B189D8930958939ABE0A97C5103883E78DD43F27378EE8057E31FF0B4AAA4B5A095D9150636192A0D1195B37253602F3C7606BB4D3D0B5F12CFC1B976B3A40C225CDFF6C3CC2CE6D8BB69E129ADB0A87720928796088793A7727D8FEABCA62352C4C0589FD8511E0EE205C1065C6A1BF8356E6FFE7DE39B003FAC98D2784B4652AD5D9BC2523EFB019D18C60997B5CC8D30D5CC83038196B958AAD5F3E483EC5FE8CE76A64982ADF6A262393B7DCA21151B72C09C8AB8DB9F1347A9D3F8E0E675ABE1D611C2BBB74C1AE8AE092085A4AF9D7859297D548A4EF61BF33F3599386D1DEB3E3AC10CED905A2A0A5F7AC4BB0419D477E1441D01696491CD56FB5CF5DD14D7B60AA9C70C2ECABBBDF3507931BA260101A358415109EDC44E51E7959A93D67AB59F5BDBB0A8501DB406F1DE26D8A58837012B6EFF5D31E46CECBD2FD23B4FD5A7F94EB9B6567C90C1326B7802A2C1D3DEEB3D12873662DA35AE0C90064E74630FE23217307EC07307C5CAFD698BFECB999E8419024BB2E72599D34FEA54232AA60135522D637ACC073B907B9586CDF985E2A85DBC371A2BD32CF7A095224D9228F50EC8F555C4D5CA3920D94CCEA742A28BFF374403AA44E6E5FCB0BA5D417E74657FFFB5D530F5C5E58224A9AEC01C913BE1F2CF3E6B15B2E33EE319C2A5997830E39FCA54A88D2246A02AB63911471E94CBDF7B90FAA1799F73E5AE47DC1989AC901B5AA62EAA12125C0A50B1603B277BF337261F581DED5A86A6ACAE3A27BA42214744172C058391E0AB85FEEC9EA5BE57F6A9DAD3E40FED6ADB11608326556925FF304AF0E599BA0DD766207688565621EC0AF3E020C72046C16BE1C40339070A4CAB3325BE80B731A58245161E3031B6A5D5BFBFF493F033B234AAA8E094D94E6DCEC52D35A8D7C4C308583B6CA9A080CE8147A93E0DD78897796DB56A0036ACA6681414136F06D8B32E34BD4C44C13B0177E0100C6558D0A22E58A1AB50545416501F311B313C1B7E484F716316B974DB1652C0F057D40F310B06800ECAAF0273F1263185F6D7F4F5262C61A171BEA2B4E848DB73E86AD4155CC2241E824CF28506298535E9B83EAE9F14B1F3A1D8749DE8AD3FDD057FC7805AA1AC0B552C4B5F8A31F713F6B9E9A8BD4B24F43230F772665829055418DBD6F64F4159D9FDDAFF441F2266CFCCDEA9BCB2042F579F2ACAC21811CFD3EA7D63E426BF82B3134C5C6D9A5B8B5AA0AFFB6C5BB4CC50CF15D6D100D7911C1826B639B91B2E4BE39B282DD9F582BC5844B73A1EC9EEBAC74470208C45FCFE88BAF53915BE1417BC134ACB915DDD3A9FDCEF8DF11C24500751C0E77A3810F8CD84D2FF06996A3423E8AA892103F39D294EA7D0F910DE7C73176FD70EB527500ED8E6F2771B0F813CB765C6D91791FD83E669CE33568B", + "k" : "E08749828B2041CA70C1960205987D9AFF49D374A4FF167CA00757D860DC2D23", +}, +{ + "rngSeed" : "288A5F2684D862A86D2790AFDDDDBAC6FDA934EE7D2E6DA1508BB550838609E8107312B28E00A6C01706374CCD3AEFA7", + "pk" : "D23B1A80B6C91017009CFA4925F3CCA1B97D1A820B204A4AD5F4BB2147307A5350D0244CA20102B8F800C924BDB5667A5866303ED52E27C932A1D84C637C707537409FCB7515F195E557920FF79A3001354CEA327F274EDCBB99E66ACDA0AAC52DC503717A3B24786AFCA70DD84C7C4ED1C1B3AC454C832CAA687BEF8A96BF6C1182F5C663C1ADA4784654393D4C83219C149E31FB0EC1E9AFC4297968C80209594AA567C65000A883B32E3FB82D9EEB4E9AF65CA4FC0CC1EC794EB2B7EDE1A5556474F3B023C45B5D8712109A2281F4527A4BBC8262C9BEDD0758116643BC6A85F836825541767595C0B54516A330137F0724A1B232CF0A399E0478F732C543F81B9D05C7F5B086C64291B2D94CF02462DF7C0F43EB06319265AE25656B462F1445CA5299166731B114E8458A0A0361B135E6002315B65B337304404A907F3C1D41EC9220055939E11F263186C3751F96D750F3A8588EE14F40B09178368EF03A9526A5444BE096C3DA8A7441638F64B4FD201E31B34F2C456EC89890F53C9A25B559B47856053227E3B36C16297949C6B11159A79A4344F0759C7071A738EB0F80C25EC2F0A2EFE614C7766C9DD68FB488C4E514769D9B6BE2D59E9C9CBA6B5B1DBC9B0D8E5C7078663794FB4EB8C7060BC1B61286CB173AB6A80952424423746BC91BC953B67908BB34226EB382BD54BCBBF5C60E467652728186C357B3FBA85F6B8553C79C730BA51AB90D06EA9EDD407B89E0C0A4276EA3698EE5E6A8348A2F9F571C2B7B93F5EAB702F1ACC3480BBB223E68361FD89A57D1716FC8C99FF43734FC58969D35077F5BB422B859B271B085F41394F28B416565D2F90848216ADE3CAB7C205EF2F47D8B50B9152A9BA6032322E737089A1E5152387E3437D2190CB9E394BBB6857A1B1EAD7A3D7118B0AB8367BA1CC09F910518420A46A18271408121DB5DCB0670ED789D537BA3639C530A720ED9F40C023C75B1A8261B6C0192B14843252CB8D713C8736B34DAACFA235C9A51468DBAA6F2E4507711344B5A722AE46A70E683C42A9056ECAC5D143F9929006BB168FF2AC983CA8B1D99CFC1C8CD919B282EB921EAFAB2A778B227968F77EC885077CEB7BB5FA13884B6A4BAC782B31F250569E0671396B780E810E4A34416166C18C4204AC4124C1020064A257C32369C892420510811F28872D59CF8DB48F2A1510A5895A09C008BE695699A4845210777146B56093D36960D6C36860CEC578DE3688BF338A28118A67833F5C4C7D93B8867D93EA7AA99A3743434D236D786CD8E617791BC5452C88E70F1189D5004E17146F3C69C60682C11E78B06B2C0815BB889A17A15EB1D985B601E6C04604CCE34B13D82A328F61C2DDDAAA25FD9AE0DC83962C0887E392A25C8657D61CC2FFC980D4CC4C9557E7DEC446828B03E8BC9A1355DC32B1C06D504CF613235B6B9B1B04C0ED550545BC37E7000A2366786DA49D637CEB5C4273041706597236BE0A7213CB0394282AA998411E1236AB964A7998055A183DCC4CE765B8756760FFF965D2B7C5ADC272EF1D3B214B4AC9B543E0F24876E773EDC54C105892CD882848FCB039E5223D0C68FA204CFDB793C5EE56659932CAB213CD4EB18FA4B045103A1E865B0C567574E523BE27974B08ADEC6D539F37479C61FE8D8C4", + "sk" : "5E74B833C0808F44300017C6B2773FF7569CCC971250623710E01C79F2457F572DC1A8C9E23BBABF0B16DE993A063931936A4D6F4A22E1961949BA5DF2E3AA07693ED37B2B9D98668019123162BE5A1C2907E35D0ECB258CB034E4489FF1616D5F6B83A7877E0CDC5ED4677D84924381B1AAC175377B4B953863B296C601140281D9D5889F649D3A4C8C2AD662BCE81753B85D26EB058B7536AB98AFBD4A969AD26DB781BB40D980AFE249AE56AEA88B59F1B28DD3F99EA3E6B8DFF2BC91544F7173595FAC70C0D50EDEC867B90188F165C8B1725A00A45406E18D242B2F63F7736F68C13C5B9606E700F9D3CC64EC0A94872ADB04437CFB7ED2623EADEB11DA382785C74D96C96647E482E8AB1C9AF58CBCAC5D4741CAD8E6A80028219AF15BAABAC6D2E884599C2B83A1307A03AD2D4791BCFC767DD36B810CA63A7587486749835514FCF4C0B7D3B06D950CB1B26B69B8ABE466029FA2B66966501F6C812BB24834C3B72BCA0A98913816737384D29A3E70327F86BCF85AA92D393A5D516B2AA49694E32845C559CEB89F6351B825BAA599011EFE9558DA35A05B4537D01C6CE8B88EAF796B36A35C9EF41DDEF86EF4BC695424BB63FA5CB4533ABF2497D39057651B22A9806B20A9A4DD6075CDBA87C04051219A8C7FBC564CA84F1D51BAAC7BBBB8BB2118990E5138726FE0C4EC51AA44780D5E66169FF17312D214E4D908E8461B2C004557F75EE749889FE23612875F02046EA6A6604C6C74DC746BB7C08AD8FC324BE971359CA32E17864987712225257AF3114BE35A3483BCFC1135C0EC9A34B67CE5E20290B13D5E8A601E55633C154A83D65E1EA03D8DA88BF5875429690F848BB314B664C851A266A880F68C8B69C184C773CBD73A3E32556207F432EA9126E6E778D76638607C341AB42B61D59D4BE986E686474878A4D43C0877599689B35247061F98229384250E78408B76230A5485486CE70B076447BF96263C0058BB455CB4901D4C99A00EB316D4EC3540E6CD269B3093C6123D855FFF761E2E394E4204366E7A132425978A0561A4E2347DF685C5B6B7D291CB3E0970DDBA9BF9166A91F5CFEC7C751BC793A574181421C07E854103B4C5943CB3F89372E23CB98F75BAE819C71DE64A98B145794A6B006300F851C5581A30293542EE4482FA8987DD0A00BAB3A9881A292618724D8C164281BCA6A903CAF5C52B31B3F341A5F3626D30443190422ABD129F2E677682352C4C9427139A2B77A362043CC1AF5737AF761A62F27161018D76F8137DF25C1872A25CB81243ACA20FA738FBA24D708C7F2D610422481F3AD74061C22141B7A448EC8BF7670ED198C0EA72456567108CF56991D47069E6A6639C2DCA8C95086C8D3A5CC49E294400BCC2FCC39C5B673AD1E6248204969AF47A4B036FE7478EA16349A4B49B857469D115BE01C2662AFC5880D5924BA498E353597157B559343848F2CCF4EC17951943B39CAC83BB52C5665FFD1618BCD6446929CFDA114CA3C554C6B9821B6B85084873A3B20E5DD8486AA7B591B1B6F7B83B585C9112884756386A35A04F60B74289E206F2994D8C56185B1698C0583717368F7CA58E7635090AA262CFF0B93AF222DAC695D23B1A80B6C91017009CFA4925F3CCA1B97D1A820B204A4AD5F4BB2147307A5350D0244CA20102B8F800C924BDB5667A5866303ED52E27C932A1D84C637C707537409FCB7515F195E557920FF79A3001354CEA327F274EDCBB99E66ACDA0AAC52DC503717A3B24786AFCA70DD84C7C4ED1C1B3AC454C832CAA687BEF8A96BF6C1182F5C663C1ADA4784654393D4C83219C149E31FB0EC1E9AFC4297968C80209594AA567C65000A883B32E3FB82D9EEB4E9AF65CA4FC0CC1EC794EB2B7EDE1A5556474F3B023C45B5D8712109A2281F4527A4BBC8262C9BEDD0758116643BC6A85F836825541767595C0B54516A330137F0724A1B232CF0A399E0478F732C543F81B9D05C7F5B086C64291B2D94CF02462DF7C0F43EB06319265AE25656B462F1445CA5299166731B114E8458A0A0361B135E6002315B65B337304404A907F3C1D41EC9220055939E11F263186C3751F96D750F3A8588EE14F40B09178368EF03A9526A5444BE096C3DA8A7441638F64B4FD201E31B34F2C456EC89890F53C9A25B559B47856053227E3B36C16297949C6B11159A79A4344F0759C7071A738EB0F80C25EC2F0A2EFE614C7766C9DD68FB488C4E514769D9B6BE2D59E9C9CBA6B5B1DBC9B0D8E5C7078663794FB4EB8C7060BC1B61286CB173AB6A80952424423746BC91BC953B67908BB34226EB382BD54BCBBF5C60E467652728186C357B3FBA85F6B8553C79C730BA51AB90D06EA9EDD407B89E0C0A4276EA3698EE5E6A8348A2F9F571C2B7B93F5EAB702F1ACC3480BBB223E68361FD89A57D1716FC8C99FF43734FC58969D35077F5BB422B859B271B085F41394F28B416565D2F90848216ADE3CAB7C205EF2F47D8B50B9152A9BA6032322E737089A1E5152387E3437D2190CB9E394BBB6857A1B1EAD7A3D7118B0AB8367BA1CC09F910518420A46A18271408121DB5DCB0670ED789D537BA3639C530A720ED9F40C023C75B1A8261B6C0192B14843252CB8D713C8736B34DAACFA235C9A51468DBAA6F2E4507711344B5A722AE46A70E683C42A9056ECAC5D143F9929006BB168FF2AC983CA8B1D99CFC1C8CD919B282EB921EAFAB2A778B227968F77EC885077CEB7BB5FA13884B6A4BAC782B31F250569E0671396B780E810E4A34416166C18C4204AC4124C1020064A257C32369C892420510811F28872D59CF8DB48F2A1510A5895A09C008BE695699A4845210777146B56093D36960D6C36860CEC578DE3688BF338A28118A67833F5C4C7D93B8867D93EA7AA99A3743434D236D786CD8E617791BC5452C88E70F1189D5004E17146F3C69C60682C11E78B06B2C0815BB889A17A15EB1D985B601E6C04604CCE34B13D82A328F61C2DDDAAA25FD9AE0DC83962C0887E392A25C8657D61CC2FFC980D4CC4C9557E7DEC446828B03E8BC9A1355DC32B1C06D504CF613235B6B9B1B04C0ED550545BC37E7000A2366786DA49D637CEB5C4273041706597236BE0A7213CB0394282AA998411E1236AB964A7998055A183DCC4CE765B8756760FFF965D2B7C5ADC272EF1D3B214B4AC9B543E0F24876E773EDC54C105892CD882848FCB039E5223D0C68FA204CFDB793C5EE56659932CAB213CD4EB18FA4B045103A1E865B0C567574E523BE27974B08ADEC6D539F37479C61FE8D8C48F62011FBD5A1C10713D42A00A79AE7672E5E321872971F24FF71ED754178D637613C090FBE4AFD54869CE826B72F3A5EC823D9A1C983A3D31B2387ED6B0C613", + "ek" : "0A10E4F4A72C5249081148823CC0BD97017D1DE3B48DDD29A1BD70DDCA589224D8BC1373C7EFB89BBEAAEA01CEFF0B3AA016AC3F889F81235C76BB3246DCC06BAC1D1C1ED3BC07D840D1AAB23F3DD9CFEF6447B7D042C76E7DCBA7AC4B5CA9CE26574A3F7CB42F47FD1BF3CD31AFAA8B709857CE4860686DA50859DF5821AE4B05196277C0FFE794C9ABD213AC7748A5F43C3A885F2AE1F6380A0820B5A891A05BDED8AE4A02CCA1CA50613D368FE674205453E2D182007F04E86F267A9B7B534EEAE52F328E1F62E96B346E59533C690BAC451D00D3646C2DDF2591372949808B56C78FBD858762DD66B531EDB0CEEA72460E16963AAC410C041106B9E6A5063EFB7F913F3C2C61F9F369D44B0AB0F90EDA15FE2DF333456EAC5B10B302DB67E6E0CBAB7B831FD935CF896F77D6AD89B4B16DB7805B761D82B5B7ED7ED5F118DC562ED9A982703C2E86FA2C3B4D4A91BC2D029905874D288A535A2C7A5F4D866CEB89C4E6E73E86FB66759414C6388E2682A694AF2A6F84304034AD698C999A81F88FD82307F6C4FAC23E6500F978501FEC8E8D094DCC832F7064FE8D40487D2257D6229F19651653D5AD46A8966DF7F9B355FEDDF524057D4EBD3042B8D5C62AD2DA5FFB267270E396261E5B95CCFADF9E1811AECF3FCA4F4745D48B570572802A5AAC2441F90D0DF184D7E01A281CE6B6B01A702B1B46EF15E149DECF201E550105992FC273AE84DE9F9CC1A3EA7C9BC4B79FD04E64B22A5BE875C994EECF700649891770D6F1A803B28491F9551352C6E52938214DB6E00F9BE408057A6F5E5E2912F7D50A2D4E81A204566C1577F3639D9188AC051D2D24BDE90E45D84A5A620AB0A77446FACB829BF66ADBF2A66FF0BC9FFFB8E7ACFBCD46BFC5720295C3563096D6312CB5E2A4A93EF0BE5C0175B5B419FEA6EAC058A9768B00C1E557C72D6E519B9D54ED306C223D2C0721D4B622A625073A2C0505F863DB99FE66C7F13F94A30F32EFD3B999937264A2B21222BB178476D787F8D734798C743B794A69C62E56C65172AA1AF82E62B8D52B8FE5E0768C5B5B504231E4A736DE812E302CD74EC4D14D3FA7225F61E6E517809416EE1717879F006D13FC1A2B7BE38D0CE4A097B1BB37B0FEB0D2E0530B6363F4F908ADD8E9F111C4A96BB5324334A59CB8B4DC9EA9DEEBEE95589A108DB703B96FB5417F6897EC10547A0DF04AB68660489CE0880EB2562DC76559B8F73205EDAF7A3261FDB4352F1D44C281FCF51FC23EC389D42180D719C95048509A11D91A71A9A8CA3DBD82A7D4002602DA91E5E6C9BEF477473CF0F2C3274FE9FE16FA60B26FECE6A51D5EE37AF389A238420A8309F182910ADBE545987678E367EC958E15356E5B5DBED57E79FB169FB5C47C4C5A4B751EEDEA7E6AE938002A8C30BDBCC6B8B0F85039F7AA6203A3C7FE00A0DDFED5D041C0C2393E708B529F4244AEC8162B50D331F6FAC3701B5E2FB9940522DBDEFAF26414299BBCE0B228B43D69FDE6444FDAF641BFF0A9C5DE7EBDAB5BBD", + "k" : "77D71A64F7DA296CAC814C8F5C7D28A14BA941926586779884CB693A61537734", +}, +{ + "rngSeed" : "4635DC5BB92EF98CDB6220DF0DD717C7F8158375EAA2B78FC3F0B58E9C9653E92684CAD3461D9158A481DA3D14694C44", + "pk" : "4F27944614C35D121BF2390402BC93797055936A2D49699CDEEC2F29413403AA1024D802D97C54AA316707C26A0B432821F63CD89A87F769597CEC8356C2C399D3A34115CCA89B9DF6A55E4556A3B2150B51907CE67B860F697A65B199B370691FDCB31CF7937D1524BEF41A0732CFDF464175C95D9092176CE52814D3A9231114CC31718755CCD3A7B3FE69B4290175DC440CD38C69FAECB190CA684FB1001B5308FB4C1FF6A55B4BE8814D602EC59C2DEED654C93A45D55A3E020800E98AA786C76FCF33CEA3A7BDBFFA5037A171044B1B74D6094D1A3B606009B4FB0F060B6DD1D29AE67AB90C90C25DB895C9515FE0A17BDD69C6773518A532AE8AC731E32155500204DAE2C9284CC16F61B5A9E48334859357506E2C391D1BD38865EA489E492D8B847A6A50BA074320FA32074D89894324A705DBA4E1847A5059645C77063809CBF3CB0555B6BE4069C77B10A6C6F67AE1E7C09D603E87A34ACD3B814D7B4798DC05ACBA65220289772ABDBD89403E698F3556511E152BC0F77509DC36803B57D08129951AC44ECC49F43B7CFE8436BAA8B5376999F6442293352E76AC592B95804217817AD5A75A76CAA72172DF9C69DA4C170E937A69D93F12C7B533D4BCE41B34D0CC8A1C969947DB2C21A960D975AC029280ECBB527654A42385576286915D4B8F3FD163F0CB280736BEE89786FA277C8487B0820416985855A95A10647059CF34C08915985C32321B5B8B45A468CD4253C662847EEA36FB238098F059630CAC83AA70CC9596CC1A0406E993B737C236E78CFBEA1191D60FC6428FE7090997F1AB41C13E0C57A256A813BC559AD1E6AD10DC3CF43A64DAE2955F03B46A09AC6EE30326D95D6CA8B80E61AAB77579C017A1906279AC09766BD8A1B40B24D8BC4DEEFAAB47F9C14A8441EB413DBD718E5122AE7BEB94F526A31BDA25D893A544670D994530D3C6CA29879085870F6D54192B1A7FD63193C7423BE4867D2C134683BA25F9240E0FA2A96B47C5AC05B541C2980F51557989B3EBA42DAD002412F462ACF75B141C5FC320BDAFD3C11BE291EAFC04D6B5A1D4117C7703C313EAA30477253E938764364B25D859ACA263962C5D6D898ADA856B70E151DFA41289213ACDA6CDB5241BC7067BEE5CB467C34D2B0A6DED6AA746290EE2E40B7BE1294C583AAF415DD03213A3CB2E41F10731823E749ACBC53767C12B93D8F32257A54C6A71B2041A167D685F0BF789B94B277F1B60AF22C09B639AC72CA25B1C69B855BED6377126999C5708789091CEDCE768B253CCAE981715C8922DC9562EA8A0BA102B02585281B15C7E44339CF630529C1B076106EE2B5C7BE0181CE43D397A398C8547DA703E2AB47BC15284F4C6A50DCB904EC9C1F60A1AEEF38435997871E8501D4832BBB2A3354C70D9579F237427135329CDA32573089687D9A9130375BF66AC321113A25A08AA75CB667635455A93EAE7A0A6703A2DC0A85637681ECB097F1B16B2B331210B6288B13F5752BB6C731ADAB30CA051A817099095022892D923F571B8D879C8DDF0AB03145A32298DC6B644B25640D808006E3113ACCC6A0C1CCB05EC273E6B6559E287539C72D754BA9BC48C915ACEBB656E3CB7713E9BFC0BB6F311485EBAA078B78A737D81D38D368C220EB0E982FB0BD8A7ED97", + "sk" : "C2BCC42EFA0BAF63BAE062A1B1322114519CC504048FF26EE73B208D659518A286DC411C3097293D79BFE04790F8B87C1DCA42059C447CA5A382733C27550B41A367E19175E084C49B9BC5B8D1ACE0EB4EF2B220F187929171A10D5A9A46C8B89CCBA3B2435720780F6851B01CB06EF5127100C4CA44C6188AA3AF8E875B85317F47797D6D699E6D619441B26FEE871863392FF455413EA78D53852D5B19361CE82432410ADC6BA90793CD3330444B82A06DA38A131A1CA91756848CA59E200C86001C21D19A7B5A40692A979BD351FF140276F176C9F189E3499D067CB054F9A5725236ABBA148CF05A539675331352834CA583B8029C764EBE829CBEB934BA76BF3E75A1A2B0A65B879CB0B881DDA38487558ADEC31029783BA7CCC94AC879690049452724C3073106790748D57102236F4E9CC4159A14A042CC4C6986ED5C4027B28053D673F42811B4E54FD62507115B990849A9C3EA6153B405B6C73F27F6755DB5C489761DA376CA05031E027B6A34B12117AB8CDD1965CB958E6E0A7A8F9B8A780B0D06625AE7B8B5D2E97510C3C8A3B010B46506DB23AD99F509D3342DF563C2CCD951A7F0446D582CCC872AAC034A27A90822506AF8ACC35F321BCED03F1DBBA19507C17688965B59176563088CD44DFCBCA8A60BAFF382B15F812768C41D3AA6227C760E78FBC5E8191B01E697104164D8C1BDD2133AA222886263A573CB3D18743EBAF7ABC486C5AD24CDD770250FF860ACF05A88CB464088CF23C82F9A191833A780EF44BBF5A06CF1442FCFFA547FFB354C8476C0B8135C6ABFF733C30F38A3FF331A836492BA26C668B679DA54463B68573D566DE97A2B4A53CF9621A6A5A7493FF190B5C9A7EA63019FD1C3A4DBC395D0B254C80F7B5668E6074FB0BCCBAB9811010B1C42D55982928D604AC9F3B5C0A3888CBCE54CF0E1AE0C9914FB5474EC29492CD1BEF2537C4E3837FFABB058993C3FD11253E87E15E84451269B6A48911EF15E4F82606A475CACF420ED6796AC04AF07633B6EA63AF927C611B07DD932BD0CE852C4B785F7348FE2906EAFC76C3DF8706735813FF796AE51837C198E2EECCBD0A64B45254209882351740FB6414363976DDBE5C302A29DCD832270732E2C6ABEA1969E8B17CE2B1807AAF2485E6B07E3A7419B5019B8172A3EA0B7907A70589A88CDE16D1B043D7985860F623B95645CA1921AC8109870758016A5BDF37ACAA273C18B6944D0911A0D255B4F9580E3B50383F93BB7871F3FC2B280F2871B1C17B2C74B9368773AB747EC2B87209910CFA859243B7A75288C163BA025FB667025433B12C471E7C9642C4AB105413E0641D7E961B3FA462EC797D6A9CEC7AB1EF6A64B5D5869C4E6C3EC884AFB87B2A8711A46014DAD830FCC195DCC5B966252C5A350561B0359EFD07DF9A4B4BFC39AE6441CD70B57A4718D55A0BFD8F979C0D01E31787AFBB1A8C2A87E5A7B70D8976AE4814950D00E998927039111EDA21993C17FB107034FAA658617568350A48DC4BB3B124B032B35EDE2BA312162B57067AB245533177DAE67894349327663C329C2A752002326B18CC60B1CD1098968D18168BBBCAB459F4A4C18F63A7DD0E9CA68F43A6592484F27944614C35D121BF2390402BC93797055936A2D49699CDEEC2F29413403AA1024D802D97C54AA316707C26A0B432821F63CD89A87F769597CEC8356C2C399D3A34115CCA89B9DF6A55E4556A3B2150B51907CE67B860F697A65B199B370691FDCB31CF7937D1524BEF41A0732CFDF464175C95D9092176CE52814D3A9231114CC31718755CCD3A7B3FE69B4290175DC440CD38C69FAECB190CA684FB1001B5308FB4C1FF6A55B4BE8814D602EC59C2DEED654C93A45D55A3E020800E98AA786C76FCF33CEA3A7BDBFFA5037A171044B1B74D6094D1A3B606009B4FB0F060B6DD1D29AE67AB90C90C25DB895C9515FE0A17BDD69C6773518A532AE8AC731E32155500204DAE2C9284CC16F61B5A9E48334859357506E2C391D1BD38865EA489E492D8B847A6A50BA074320FA32074D89894324A705DBA4E1847A5059645C77063809CBF3CB0555B6BE4069C77B10A6C6F67AE1E7C09D603E87A34ACD3B814D7B4798DC05ACBA65220289772ABDBD89403E698F3556511E152BC0F77509DC36803B57D08129951AC44ECC49F43B7CFE8436BAA8B5376999F6442293352E76AC592B95804217817AD5A75A76CAA72172DF9C69DA4C170E937A69D93F12C7B533D4BCE41B34D0CC8A1C969947DB2C21A960D975AC029280ECBB527654A42385576286915D4B8F3FD163F0CB280736BEE89786FA277C8487B0820416985855A95A10647059CF34C08915985C32321B5B8B45A468CD4253C662847EEA36FB238098F059630CAC83AA70CC9596CC1A0406E993B737C236E78CFBEA1191D60FC6428FE7090997F1AB41C13E0C57A256A813BC559AD1E6AD10DC3CF43A64DAE2955F03B46A09AC6EE30326D95D6CA8B80E61AAB77579C017A1906279AC09766BD8A1B40B24D8BC4DEEFAAB47F9C14A8441EB413DBD718E5122AE7BEB94F526A31BDA25D893A544670D994530D3C6CA29879085870F6D54192B1A7FD63193C7423BE4867D2C134683BA25F9240E0FA2A96B47C5AC05B541C2980F51557989B3EBA42DAD002412F462ACF75B141C5FC320BDAFD3C11BE291EAFC04D6B5A1D4117C7703C313EAA30477253E938764364B25D859ACA263962C5D6D898ADA856B70E151DFA41289213ACDA6CDB5241BC7067BEE5CB467C34D2B0A6DED6AA746290EE2E40B7BE1294C583AAF415DD03213A3CB2E41F10731823E749ACBC53767C12B93D8F32257A54C6A71B2041A167D685F0BF789B94B277F1B60AF22C09B639AC72CA25B1C69B855BED6377126999C5708789091CEDCE768B253CCAE981715C8922DC9562EA8A0BA102B02585281B15C7E44339CF630529C1B076106EE2B5C7BE0181CE43D397A398C8547DA703E2AB47BC15284F4C6A50DCB904EC9C1F60A1AEEF38435997871E8501D4832BBB2A3354C70D9579F237427135329CDA32573089687D9A9130375BF66AC321113A25A08AA75CB667635455A93EAE7A0A6703A2DC0A85637681ECB097F1B16B2B331210B6288B13F5752BB6C731ADAB30CA051A817099095022892D923F571B8D879C8DDF0AB03145A32298DC6B644B25640D808006E3113ACCC6A0C1CCB05EC273E6B6559E287539C72D754BA9BC48C915ACEBB656E3CB7713E9BFC0BB6F311485EBAA078B78A737D81D38D368C220EB0E982FB0BD8A7ED97ED3D1DD05854A6542B24090A680B9AA9D6C65EF31CF1F4F5708AFFAFEB2E3989BB3EEAC4320F84D09CAD413A7D7C19C27668B2E0E1BBBA2D159B833DB6C0F50A", + "ek" : "B4D9DFE6717CFF99AFE645E90F9E9A497833488B2340C1473CEB6C39B944D7CDB748A3E961BDD632D923769AEA3B177CF25A36F86F94E80332B720F0F58A134AD8C6F7B31AD0388697864A3D91F43BDC9FA163FE572AECFBAA28D8CEAAA0E92F17EABAEBE9D3E117A1BC3C454C3D66E35F7B76BAF327D29FBBE8D35142A1E4360A70D0DE8D46977A688B6B488720AFEB05F846AAAFE9FC66AEA186961F63264A8A1AE0D721D49385699354B745F46669F89A20B493A836774115736184732B3D0E4374558622EA186D28E822C98DBA24F2FA6D233112A89C73994938C362D830AA95113D0989DC4CFDB8D50F0C872D248DCD60212C6C650DDB1679E9419ACB2D2FFB8540F578F55A0D03474E3F76FDBBE15AF07E3A5251574F6707B2DE3A433C0C8A7B04BA67391D27534AC945DC014E9F655068B5C14BEA32EFEC6E6BA1789B1F5C37DCA456E52B66AE3A9323671954774CAA1697C87DCE1D2425326B7185EB986FEB59EAE87AA2F902E958C6F3C4CC4AF8ECCB7290ECC824DB1A695C3DD643BC0D7C51B416ACC184C00C486BB33759BE1FE9750CFF4282A111723A16E6ADAE00EA34ECDE4B197E8CC1C370635ED2F1E36AFA30E76D3C4450EF839C48C016230CB1CDC3B2CD9E64D2E19B50DF9633F65DB9088177E385502B8A782955CBD6B2E56185E0B3734AA0281734A61C5359D6C4B938424C55A467712FFB555AB782BACC5FD418910A13F28AF859AE406BD7FD90490961C12F64927DEC576077D4DCDF933C8F6150D8F4F1316C6E28C1F3A0784587621F3D05B6E7EE6877C56CFC97A93C337616C6A940F8D0455FAD51FC1233425433EC89055BA451FE31BC51A41F6A4EE8C7AAD6F365CCE7C373C53BC674111A74FE2C3C187F6615CE07E7B2FD45A148D95F7649AD52AB94BCED68B16FA4DF9F9906C498BE510D7D9D74D33370E893E0BF2F516EA981F06EBF20988EC059BC58835711AD20D8F1F4E47FEA65D7F37A5D813DABE1A2C97E1B316D6825BFCD07B592A4834AA204148ACCDA22CE8758335CB3C73DB9A51261508EEF5B5A2FAE5A6A6EC0721313C6EE85D3C29191158D8A3D73D4A475171639A531DD8822682EA4C2375EDDBD6DF395066E33A16DD5D2CD81F9557268603F2B831FCFE92AF431A7780AD0FF9500129AD7959C4975422A1476DFED8A280A24B1158F9FA44DEDD77B9A3B883C53CEFD56B9EE8BF3A8A3D4D48FDA159FA7EB0ABC9F69448A8FAF53C15EC5F1BD9C6C9ECCBF65EDE2DB9032B22E0A60461A86F3707A3A829968FA59DC21078891C654E8A8FE4D0EFA640EE179429E5C0396178C094FDB18B6A4495A518AB6DB016629FEB51ED10929C4EF3F3710F3170AF26A41E197AA709575C0D1A8180F8E81AA6790663A7B2623518734CC9C1D939B2971D011B1DE2AD96EB4E87379ABCC43334E4B4A4BF8F76CAD70BA00465241EE09B6EAF3B93AE18A31FE50F2A05B8B57B76C43E3AEC7310E17F385506F771BB7C67CD97F606A2A9DB409B3CC3FEBF2CB0D762490F9AEEB8C9B7B0586", + "k" : "A154DB38FA0190042B01911AC8EC66A01F704F397E8E134E70CDF4B773A32484", +}, +{ + "rngSeed" : "5DA2C51B4ACF488C8BDED5E985CC4702E4A7BCB248B5AC18AABA529F7F9CBF30EFA776E99F76D5C1686E94F50FB57DAE", + "pk" : "39B95D90D51E8CECB49DC41A37E866C8FA1BF723C3E3815B1F388F63D791FE0CB8507020E19125BF0BA753FA89C19180A7505E15AB6C44E32F70499DF5CB106F85BCC5DC4F20D9660C17307DE05BC1EB6BDCEBC52727CA3544772CC56A08B30C0C54A847B28387808A1747A23F6460054C582B4CA1E09691C64615A6BA3F89A05A18ECCEA06B550241047C1807F3323DEC674F17056D71B7BEA906463EFAA0FA50B051723E0CD66CC7587DF4B58D49FB029FDA6E2E507D637CA7D489971D897B09148A6A2B47D3B4BC3A4AC0715B3ABDE096BFD8622CA24141683771CCAD1094595B20C8AF004D54873B0D42977886314FC889E5804474005527170C49882CA89648D24BA29CD30A7C2868F287345F4926F1141531D3A53CF68C8662247D47348CB1A102613AB236B67BB9A7CCE47E794096C0A93D54F743CDA16EA09C8D87C43E4A1B2CD9B0B5EA711F30B39812CA44DA20B02CB4C8FE12343896AE6EB838AC648ACB8BC8E887AC69602E7D81263315373029B2D6713705935A43177B9F9888115202ECB1A60E433D8DE2BB42D235135224C7F795D342466B4C5BB8BC93931116479171800B717C033A304BC619D2A79A687E005D6215FB1E76AB67D8B46C72857A46D753674A7EF3962C90F2B62F51458204B71D95734533875819A495360ECC12B66005330593456C516EAD7B3C942688A822BF0D92BF849BAB6068480A0B0B4B8C3A451007DC2A733DE7B51D835E5B7900AC836FBDF13A9EE82B34CCACDF6B8F4CD0594C80473040B633B7CEAA091259A21C5C881602C146E4444E1E48800A189239241813C13B724A02E6E7A70834493F794AE7991BBF1B60D4C0084C213471EB3598079ADF95004942176F297AD3D55B5CFAC5A3B385679CA6AF26217AD8309547A0738328BC1A519712BA545CA739E8C253A65394817AA6874E432A95E5F35AA045CCA1FC1C7BF467424A8D498274646C05C15B176C8A69F90A0A524B6E4B6053979499E7526AC66830D28B28CA2C6DC4061B1546A4E8D7348416C8A8FCBC0779C51CE855DFC54D94D74BEE674BBC383ADB248C07EB8889B0B44937356906A61B1074362754440856BB26B2FA906EBBB94CCC943FB39C00292843ED501F5F673762E3AFBD7179E41835208700FEF233793C0850C5B48499AFED371E56E5A92A4109662247B72338DB4769F9849F9516266ACB133AF5666B18131ED347454250CB04528C91B8334C2F5B3401CFB28E45824E73C1B6854B330C47C443D931B9E5B139F31B25D4458AC53A32025D49BB5D1A89B73BF930C74C233BBA7AFE30239A41587985726FA09D0A7A2AB19559ED380D9EEC34B5FA83B73813A763BEAB0A1F7DF5B87962709F255256A36800B94062D3AF90990B2A43251AD9B0E400BBAA4A306520443ECC8CF45613A8FC1C61E6312CFA02D23C1547A69CFE43660D987A0210CF60965FCA77C850503416C7C18A37BC10CA47F517ABFCDC018FFB538F474404917DD65C8A680A667B1762B5958E43547FCA1AA0DA8907D7D3A25B430724477EB2844E54F35AE8F27598D568D413914BF66B70E37DDBFB7DF01C08E1310932BA90AC2287187B022DC659C83B9F554871AE4AAEBA7AC76F1254F174493D31EDA27DEF0331DE8E68F7B1568C4C8919E4DE7A5005CE152FEF9C8C88EC9E", + "sk" : "9CA01438CCAF5AD79F0D253C6D29707C603905B40D1D3B93B269BE9072BA04020672EC15EC059D3FA9598EDCA4F4DB3164557B1737A0DE750EF5C31572D80C5D82AB52184238C439862492403B1CC06C7EFC7B94B41BB1718C6523DB1E6F63533DB04E4E91C405527A4EA866210731A687CE09D10E5E0945CEF0807665BDFD797802092F0B6837D61550A1D481782045C99B7DF6E2B9AC95BB44284F472B5CE1636B1B3662D732A82D76517B57BA46FC9BEE14511BE585CF0A6549584A361B7009A733C9595F01DC6290471E3D656371CB6D63C9BB25A8C5CAF03A84F6684AF3C7DAA48B2850BE6C4270412572F0C1AE74613752E6BF6D53C927F110F41922492780AD486DE631565E99886A077C209B025A6561BA503599897444642DB4750728E09D3EA6498D236153A743744217DF5400876690E393B0F3E2A481C31B52D605CFFA140651CEB93C1189AAA372E906A14B684BAB42C82B2071133CC31892048C1AD57AB99A00680E03287516141C281D2E1978B44C84595A59E13647F11623EE2B822A36B4F41B8A153A3DCF6B6DAA97B9240B25813343561750AB7ABF17816D76616879E09668B9C277D1CDBAD74A5E429074C07A3394CE72A99AF63010BE35611D296348A163CC2B412EBA4873988AC341566D1C2E60191DC9603C62F058391392494976E073760C0A9FE058564D0334A14A4D8E9B41C2E7226842AEE7DC263F35B47619C99CE66F6A546BE0E716F8A61830C23F37F152607032D34A6AE3501A00818BCA04CB9B7145673917B9252F449A7463565662513F92A5AD5BD4BDC6D63C7D7866019C0454956B92595EFCE15C900B6D60DB94ECE8C2F4BC7FD52240CDA936A5EA069980837C32C777F60B2A5BBC41A540C0394A3ED53BF34B37D8E7627979CD52FBA35B144DF35CC975209F232A0D24000C826CB54D365D74182631A326BA0674B86B1AF79A169BA6361D30737840BCC5F3798A9C5439541F6E036ABEFAA66A44A5D017855B48BAB216170DB6489D74A7ACD5339E43BA3B6BB6D1411ADD611735B9083C75B5111B903965A4B56B4B27585E9670B0FA2C5EE631B6DB0ACD324710ECE9A429C83B76BC417A087B08D989A44B3D9CD1217D835A12C62A437A34DD1568E25C6DB41C4C98D0BB7CF7B12BE2152C361C1A881B409730C4A9B82498245A8141A903C88CC7AEF187628C226FA3BA83D2453CA397290A0CB7EAD61047BC4D4F36CD6D70200A1A4139505E3A86885BD61CEA052BCDD52A1CF33FF2411F4B9C91BCCB7142C6657DB694031649BFB8800885BB076A0EAB3921E53B40C1B075677124B0187969DB8384244F63C6936AAC3F6770B9EDE5C7129A8E55D46AD5D8636C80082C47611B5C3AD3B814DB17157DF41585E68F5EF027E9537D3375CF7DF44BC807A7E88B8B9B083452A35A6A5844EAF3C4AFDB3789806D658276C4A18361AABFE743C67B2C626F1CBB2A8CCCEE295E6DC7A4E695B205D4980151A89E404A2A1940B58854A7E12E0D221FCA36592044492094619EBC7783DC1A12D8A6BDB95F697514F214A7707949C5E6CA4AB227800554D77639B9D2862BFC27BB686C701B0839402A33A60E0C253E32393E6A1C45003140D2B7CD56F34A39B95D90D51E8CECB49DC41A37E866C8FA1BF723C3E3815B1F388F63D791FE0CB8507020E19125BF0BA753FA89C19180A7505E15AB6C44E32F70499DF5CB106F85BCC5DC4F20D9660C17307DE05BC1EB6BDCEBC52727CA3544772CC56A08B30C0C54A847B28387808A1747A23F6460054C582B4CA1E09691C64615A6BA3F89A05A18ECCEA06B550241047C1807F3323DEC674F17056D71B7BEA906463EFAA0FA50B051723E0CD66CC7587DF4B58D49FB029FDA6E2E507D637CA7D489971D897B09148A6A2B47D3B4BC3A4AC0715B3ABDE096BFD8622CA24141683771CCAD1094595B20C8AF004D54873B0D42977886314FC889E5804474005527170C49882CA89648D24BA29CD30A7C2868F287345F4926F1141531D3A53CF68C8662247D47348CB1A102613AB236B67BB9A7CCE47E794096C0A93D54F743CDA16EA09C8D87C43E4A1B2CD9B0B5EA711F30B39812CA44DA20B02CB4C8FE12343896AE6EB838AC648ACB8BC8E887AC69602E7D81263315373029B2D6713705935A43177B9F9888115202ECB1A60E433D8DE2BB42D235135224C7F795D342466B4C5BB8BC93931116479171800B717C033A304BC619D2A79A687E005D6215FB1E76AB67D8B46C72857A46D753674A7EF3962C90F2B62F51458204B71D95734533875819A495360ECC12B66005330593456C516EAD7B3C942688A822BF0D92BF849BAB6068480A0B0B4B8C3A451007DC2A733DE7B51D835E5B7900AC836FBDF13A9EE82B34CCACDF6B8F4CD0594C80473040B633B7CEAA091259A21C5C881602C146E4444E1E48800A189239241813C13B724A02E6E7A70834493F794AE7991BBF1B60D4C0084C213471EB3598079ADF95004942176F297AD3D55B5CFAC5A3B385679CA6AF26217AD8309547A0738328BC1A519712BA545CA739E8C253A65394817AA6874E432A95E5F35AA045CCA1FC1C7BF467424A8D498274646C05C15B176C8A69F90A0A524B6E4B6053979499E7526AC66830D28B28CA2C6DC4061B1546A4E8D7348416C8A8FCBC0779C51CE855DFC54D94D74BEE674BBC383ADB248C07EB8889B0B44937356906A61B1074362754440856BB26B2FA906EBBB94CCC943FB39C00292843ED501F5F673762E3AFBD7179E41835208700FEF233793C0850C5B48499AFED371E56E5A92A4109662247B72338DB4769F9849F9516266ACB133AF5666B18131ED347454250CB04528C91B8334C2F5B3401CFB28E45824E73C1B6854B330C47C443D931B9E5B139F31B25D4458AC53A32025D49BB5D1A89B73BF930C74C233BBA7AFE30239A41587985726FA09D0A7A2AB19559ED380D9EEC34B5FA83B73813A763BEAB0A1F7DF5B87962709F255256A36800B94062D3AF90990B2A43251AD9B0E400BBAA4A306520443ECC8CF45613A8FC1C61E6312CFA02D23C1547A69CFE43660D987A0210CF60965FCA77C850503416C7C18A37BC10CA47F517ABFCDC018FFB538F474404917DD65C8A680A667B1762B5958E43547FCA1AA0DA8907D7D3A25B430724477EB2844E54F35AE8F27598D568D413914BF66B70E37DDBFB7DF01C08E1310932BA90AC2287187B022DC659C83B9F554871AE4AAEBA7AC76F1254F174493D31EDA27DEF0331DE8E68F7B1568C4C8919E4DE7A5005CE152FEF9C8C88EC9E6FE12A1E2D742DCAF56C585651ED6EDCE4F410ACA0FC83275B5ACB19DAEB149DA8AC144DFDA421DE1A7ADDC92ADB79BBFA9657F3DC4B78A7335F29DB87B290D5", + "ek" : "0B6F15E0690315C8C7B9CF7E507665C347609B6BF6CEB7B2B7C9D4BCF1BC02242746DF267070CCE79C7C9F1A921269B0912C50C2207E3636B8F40EC2C32029FF2A0FF96203846B984ABF9D3590D72BCBC7D911D546829291415D1A5F7B5DE169F4A0011E0239BB1F7DAD590F9856188EF0B6BD391985C0C857B8509E237FA3720C7CAD331D2065EE1FFE71D32EFCAB2915B47C85A9194F422E0C898F3BBB2F8472E440504367D836CFC2F6CB516B8D61EB44CB1A99DB6782FEC4C7575E13DAE7517C2C253978C5FB8014CB4DFF895105E4D4F3FEED8CEF9590FC3560C5EE9F83C7BEDA7B6815045E96CE3AFA03777B0EBAC3EC006E426F37B543C58C31BB59703532C0D04521823526F66BD5E2C8188ED7562E4942FFE5CBE0F3BDFA213E71C549AD0DFF7E17305F863E5271EE41E0912EB552F6A7B48481D8173C6F38600685D4E0280A2C13D24E33538D1C351C8B8EB5D1AC2B832605DE0D38E91D2BA85EF78FD4713E885AB94BCF5647EC6A6FAE79CFC69BED91CEB0D5035A91FF4D7BFB34F0E8EDBB30ABF21CCCC19537A6931A70D002D333C0DDCB8473EAF283E4BD43A86C30000E700A75F29AB299DF9DE0E2254D2B8D503CB6E3AEDF44062ACD7422FBF8B887E4361AFAF73B46633498E9724C67AF31053B704F6D6DD8A9EA549A52535FD86D973767F2C73D25BE904A96CB21A4B239D43D792601ABE6996E92D1AC249344EACFBF71D7EB038A543C5862C60DB4F2859F496B26B0629BC66FDD3F08926E13E970B2A8120F6B3A35F261382C254A94E5CCB58F2B7D2E835AB81A199CFE524FCD3E5F6AEE7C20F690A5C23F2277226C4952A81852227A6315FEAB0940BA151589861337B185DCEC34B25C367C5A5E85C41B344DF1E31F1AC8CCA93DE00AF354EB840F95972E9213F24784E81DF070DE4A8184CD1BD9D148964AF2FBC54924558BB87D753B43BF04DF8FC0C6C65EC53248612DA19D93B1A921DA2CAA6E7C51EEBB6C504D013739EB84570E6344158BFCD84819FF99D7F5B7A1129B08B2C913B53EA4B522A3867945D53949271D3F90B4EA818C6FDA67C57701A77C5D40DA2B72DE83F59F9A51027A85EC04EC2D965D2087A8D89F78ADF005991E5FF4C31335B3D6CF51FAA5395AFB729A30CC880E68C5AC526A196001A054573429ABDD1B76592A8DF258C165B66E054F35AFD41BD15FBE1D8CE749C10D7A9FC978BE9F910AEACC320B151224B873784D35D4D6F652F30F65BFF73181048C1530A69FE36F04429FA021879A3B45052179E84B81FB0F9993EB3861BE0C5506655ED8E864FC1B0D77316569E2021B4D5F7D210051FB8A1A38DB5086A8CBE7C06A1DB3E54BD2AB6C82F19EEE448C72EBA65721CAA0475657A50E83F383ABD0FA5289C555BAEEB213CBBF5849152B29B9DD4C2F57BB31A14CA927CD619DC8535CD4EEA11AF8ACFBC846872C63DA5BC62EEBFA94FAE7701EA080B4DA5EC95C61989D8CBE7964B91A0A325D13DE633B3C0B5A4F031B86B5B14870109AB78CEE850D6E653B58A596", + "k" : "9CF6E4888CAD0B6744FCBDB010CFB2A31CC7B6184641E11C4731124F18C3B8F8", +}, +{ + "rngSeed" : "4D2239E84B052109A78DBAB6D80C51A86D38248105970476B74A0B78B9CFAB6283E30D5A406FAE1C7F54F8BAE1110EE4", + "pk" : "E1696955C4BC38DC838761A183D31E38BC21FD2B955D9002AC69AD96C03822FB4283C4216E93B96D86BBF81888B68B1E67741D4FC8AF15D4642A7B65D7B408EC711055826BF634557C8A7CE4A32384592F3C5881AA530213C2435141505A8C0918186C1508AB11101B09397D82B31C85AB64F4BB38947726D2C717362858A0A3656487B0DEAA38C8109E5FD061496A695581347D52AA7ED71C20D8A613BC54E8A49A92EBCEAB993B0FA81DE448C156550AAE181A537C38638C6320ABAA08C50B7B54211DBC8124A487EFF2B545CA3DB8A07BE7674B51A95EFD08C4421CBF2AEB8CD92383851A044985AA9A062BF5267382DB45519BBD747852ED1A590CA3A89602A6C65CC06C856E22484244FA15B928B13B91736B1680E18CB1F76A7209B76754076DB872295EC76E246B1F58F80FE0610372938393288C85B2B2F2107FC39C7D805678E68A38E3E57C30ECB650DC15468674CC54AA8AAA424B5060A03BAE4D74C8A43C951E6B53B2C8B1502459868A1B03A5C1395C1B10551C28A6756D251E1916C24BA33792D74EB88A5C84078F60C612BEB4A7D94BCA27E3377E53442284C395ECC235309D1281C53964BD34A067F225829E5CBFAED47DA9E393895AA82A67AB5B44A92D8423BCB59265E73B84F549927427E9295ACC8694D77020D0E4342D3C784B121250140DB1C3BD38806351416C8F86B4ABFC7A14911BC865BAAF867F54E92F935B044B60BD5343C5FC9B2D1DC68735BAA31CE155E37C1ED0C85162D2AE3492C44C29343B50351C64747F9765B6F9306BBB3E543334C987C9A1C2A5783A576CE94B8F10BC3539CD55F30B0CCA01A5985EB5993D35B8CBB136BD769B13F0C5C2D40B34335A52BD34AB04F9CF3F6C313B6C5B9EF879C10C1E1B249CBA2580F7DA8BB06C003DB8718F318979E358292B881F9CCF984C525B61A34F6681197A7834913230627B56388EA26CCE0569680C968B31AAA97710C9B2CC019771A57F8B5739554E45048D59610BA990B2E1967648D3C87410AFF7981A57E2BCCE971B912C2BF633BB8EA55314F3327D3B4FCDE33AA1E235E6EB603CAA19BA83C98EEA4196C78A80E8B5680227CAF06EBB22042E9A5C63974650FBCB1531404C6862710215012671093911D67027D491A916539A1B84B3C966B89ED3B1E9980769267827731ECE44826A3A0BFCF037D9FBB9BAB4B85AD668FD1573C0E9B227FB5AD32C948037384145188B17620EB91CF6A6318F331CAE3800164CCD138C8C75A3071A7C0166F5156D74171B5B854C0783F9905B88950C23CA8835E530C4037260500BE9F00510B5357FD1B80B09AA06B7126ECC8BDB709E3E698761F756AD0624280778C0CA140C426F91C76F81B96CEF425403C95BC00852359B638A8A75B3FCBEA47990E002B346D5A9481083C4336D02191326F6AB5C5777F622CD4819BD1187CC6099CB7968474ED93C0B830BB301314551970B86A25DA05DCE97AB5DB744C78536712C752D02206C8585285268C5842491F92636682B223B6BDDD39C6070BFD74AAE3F8AB1FBC357136028AA3542F006CFBE429001377D2112C5AE3805244B865EA863257AA671D0B146D04B89B233F70768A373043A59B9060B0943F56865E6A91BCDC54402574A0F1C143DD36948D781D2F3C44E2F08B52E339B6E1CB3", + "sk" : "7079B0361596D968AEAAC085C8F649EF02A20B947EFA34800067938FF753BC0AA132D1A51944634BA6308E64848B60CF01AC01A7A13C5AC5763F2A07DA294D955B5044F2B46E2B6F51D501C3949E32A64BF7AB5B6435986A1719812BCDBA766380A0601C807DDB1A0C532017C0540B56E82C63DA8276E665D0C4418101AF9E07092A48422C960F7A818CB266141CE16F76DBA6973B5DA07449A2B5CD3E20650D753C044787A6154257785AA738418254281298C272273EE880099772C5A8D0491EBA4930280F75664D6156928967C2F855053B63ACA1141B8FB3C8E7720C0BD8C17D18A2C3A73902D6711C5AC31110A4008D920EF9C6CF918D0B457CC2373229516F2F0A9C70B91FD640C2959A3D95634736910C840B173FC4565912A332914BC4C6251483691ED7ABA7906693EB54F36794BB0777E5B45F32756EA6889D6FB75C84845D99A5458B024257A6210C657555AB7CDB802351E1016213636C3B37AF4B57AEA9CDC5A336FE2B987FA5994C991C5B59AEDA80A5DC1639A5DBC994E330F710752AF651B11A2BE27C57413704C0685973C67F969098383B341747AD8849B0D86715A2A296F0321F2E9C72B69431D4253970F25D653CCC2BF72D617BB861AC66781576A6F7AA70953D6D3C40DD659A373A1D7BE285ACE7C2E7C754D42C780AC5A8E9F7BEAC93610B9C56C64B28703B63A1684A88D76576743B650178C79B209D28A616D79AD68092B5B0CAB578C4AF895AAA20455000A07A9CB4BD57C04DC5AD159488B70A289F229E87552BBB9AA1F24AAB37099D0DB07E9CE14F500773D7326103405F5A516E0240647F556001D6CF77924C2EB3C546A25AA10A80BBB20D09FAAA6115020E988A85093F2E15447B536B6C610776403AFAB7037B795A7FC93EAB9639F400A383454E10A591AC0CA3AB344CA0892A022532BD79AE558710451175134801106C615E47AC6B333B1FF430A1D2A0B8230AFCA93D65E83049F01D00AD5E795902B8EC7DC496268584CC90BB8C88148BC5082B74E48B1FC2116D9033BD342B53215AEEEA5788447C0C50B567B88888841B9D8C9E9488BA2A4A23A3F913E00631AC784F13C858E5B49B920B428CD24CD1ECAFE553ACD95982AF5B8B8B00BCB1074F6AE52EA7EB34CB4482D4679EFC337EAB910D78210B94F7B5EF150814C01459C0154D67493FA276DBAB403950A609B23D1FD37F23E6C40BE57C2B9BAC82D9923AE3CAE126BE2C0C54EB88C9E0307402971543B58B67D21760590C818B4C71855FE90080696644E074BF2A45237F037565E800E071ABD930ABBE6B6E4FCB8774AAC945898EE8B74911726E316568068A1C545CA5E75C02C2B2872D478605341EE5B8B914690D9B0938940540A595744CD8BAE7483D39D1511344AE19BC99FE5B5180F22C032B6BBE67BD507C6A9A22C2E19A8EA2CBC5436A8B307A9E69D237076A0FA8D52DF9852205C4592461C252542C95E2847651011E1233834508A8B7B3D09C833E8837150BA67405BA5D651075E39590D74EAD502157253A703C2D460CC21EF173E197200AA85E497C9E6989996CF2C29320BEC0B671133BCE293268FA9B4EE48C31C9957DD2319385301C2BA97338C99E33D828119174E1696955C4BC38DC838761A183D31E38BC21FD2B955D9002AC69AD96C03822FB4283C4216E93B96D86BBF81888B68B1E67741D4FC8AF15D4642A7B65D7B408EC711055826BF634557C8A7CE4A32384592F3C5881AA530213C2435141505A8C0918186C1508AB11101B09397D82B31C85AB64F4BB38947726D2C717362858A0A3656487B0DEAA38C8109E5FD061496A695581347D52AA7ED71C20D8A613BC54E8A49A92EBCEAB993B0FA81DE448C156550AAE181A537C38638C6320ABAA08C50B7B54211DBC8124A487EFF2B545CA3DB8A07BE7674B51A95EFD08C4421CBF2AEB8CD92383851A044985AA9A062BF5267382DB45519BBD747852ED1A590CA3A89602A6C65CC06C856E22484244FA15B928B13B91736B1680E18CB1F76A7209B76754076DB872295EC76E246B1F58F80FE0610372938393288C85B2B2F2107FC39C7D805678E68A38E3E57C30ECB650DC15468674CC54AA8AAA424B5060A03BAE4D74C8A43C951E6B53B2C8B1502459868A1B03A5C1395C1B10551C28A6756D251E1916C24BA33792D74EB88A5C84078F60C612BEB4A7D94BCA27E3377E53442284C395ECC235309D1281C53964BD34A067F225829E5CBFAED47DA9E393895AA82A67AB5B44A92D8423BCB59265E73B84F549927427E9295ACC8694D77020D0E4342D3C784B121250140DB1C3BD38806351416C8F86B4ABFC7A14911BC865BAAF867F54E92F935B044B60BD5343C5FC9B2D1DC68735BAA31CE155E37C1ED0C85162D2AE3492C44C29343B50351C64747F9765B6F9306BBB3E543334C987C9A1C2A5783A576CE94B8F10BC3539CD55F30B0CCA01A5985EB5993D35B8CBB136BD769B13F0C5C2D40B34335A52BD34AB04F9CF3F6C313B6C5B9EF879C10C1E1B249CBA2580F7DA8BB06C003DB8718F318979E358292B881F9CCF984C525B61A34F6681197A7834913230627B56388EA26CCE0569680C968B31AAA97710C9B2CC019771A57F8B5739554E45048D59610BA990B2E1967648D3C87410AFF7981A57E2BCCE971B912C2BF633BB8EA55314F3327D3B4FCDE33AA1E235E6EB603CAA19BA83C98EEA4196C78A80E8B5680227CAF06EBB22042E9A5C63974650FBCB1531404C6862710215012671093911D67027D491A916539A1B84B3C966B89ED3B1E9980769267827731ECE44826A3A0BFCF037D9FBB9BAB4B85AD668FD1573C0E9B227FB5AD32C948037384145188B17620EB91CF6A6318F331CAE3800164CCD138C8C75A3071A7C0166F5156D74171B5B854C0783F9905B88950C23CA8835E530C4037260500BE9F00510B5357FD1B80B09AA06B7126ECC8BDB709E3E698761F756AD0624280778C0CA140C426F91C76F81B96CEF425403C95BC00852359B638A8A75B3FCBEA47990E002B346D5A9481083C4336D02191326F6AB5C5777F622CD4819BD1187CC6099CB7968474ED93C0B830BB301314551970B86A25DA05DCE97AB5DB744C78536712C752D02206C8585285268C5842491F92636682B223B6BDDD39C6070BFD74AAE3F8AB1FBC357136028AA3542F006CFBE429001377D2112C5AE3805244B865EA863257AA671D0B146D04B89B233F70768A373043A59B9060B0943F56865E6A91BCDC54402574A0F1C143DD36948D781D2F3C44E2F08B52E339B6E1CB330C784BB2CA3538979B24246C2644907484719C531EA39F13C5A34046F8E5CC36EDA18027C6709111F1987E026A481D46003AEAF2FF23B675BC349C749F300C5", + "ek" : "DCFC105552E6FA456892E8C6AA3C450D15F7AC08275F8822E104A60D0435E4DA137F448D908C23DA5F61295BAD5AA7627B22B923D9ED10013EA8FAA0C76E7DCD660A4879B685D83F43578A26B181A0B18F8573C3B9A019BEC5981D15C57822F18EE3AD3C6A876778F02C583C59490DC2CDFC740F0FCE1C4B4A6A59566104D432ABF7180455CDE7DB37C0DEC8D86E761785CD1B9C95C93BAB8921957759E13A94E5BC8A1D598CF94BF1F8585662B94B6BE46460FF90D6BEF640BD5AE3A8633F7FBAFF2F92E6D8C5C29583C494ED0ABDBAA9F732F398A433B07982C54C339AE340B5265FB5FE9550C663FEE3314FAA822EBC71D750E8B572D3E3B639B896DBF9CDFC00BCC7E0E230A7350ED893149B393F0A9EDC49533A7D4AE7296C9BACF6978704C4D120F9DCF8586530AEF694B9015FDEFD85746FB0E350B3D5BF04B8D91A0571E452705A75B7FE86D5A5EC6462A1AE105E06F9EAFB834A2F944E7AE87814DE5B337159BB12E48EB1603C576B1E32302F32B2BEFEBF5F5FAAB77312430B768A71736AEF50718042C65AA39B036FD73D0FF0E61F606A6B41C91133DAE4447A27DA434D289F4DA3F2D3449AEAE0A6106DC0CD9880EEF87B5BCF6023E5578BA7C108C224E2788B46FEBFBE631913F47E0D4D8E191AB9E9609A9221FFBF87ECDFB3B970AD627DA0ADA8219EFB62ACA70060A6C8955251D524A11E6FFD077D3FBB7B0FA1B390D8F48C7823B220AA018C3540BB4F6828767EBD626E782A75456894BAF611B6C6AD97140EF8736A661DB3F3C47EA292BA1901DC4E2A4B6EEA60BFE95FC196E2986F0D1207AE806B4FC941CC2CBAFBBF68A242C7464E60F8BDF937378A7AFDBC6321A10BDBC1FFB2BD5B8444ADD4F64D77C33BD21E11078894EEEBBBEA9C07BC4E4EC36545A54B6CA02BB1482DF3AE788227275D10B506999E81B176213818841C0CDBD896843B8AABFF95635D22C6E6E289422A90F37A668A159DA387356E4AEE0D5EDFB4036A3E390FA24EA935854F2EADFDD9DE81D37A2B892F00CBAA7F14D09B27CAEBE30B5D6D10B47F2551F95D0FEB9ABC4C8AD6124926744B2CFCEFC34AC63E4D4F40932F7B9A435AAC27B016116DE7988C3B74B983B41EE344081411AC236E74E0D7675FC868B50A25FFE1A4F40E5F5A0F0FB2ED6AA31F1B63194AAE2735D44B4CDD05F05C751AE40D19FC725D659F80A15797E2FF2FF2BF1A84E753663B8286224BCD4564BE75B7D7EB7269F3CC416838EB4EFAB7583B055F6CF4D24710A0CFAA7E941164407500DB02B3AF261E9797EAA9C08383DCF8ED97E92AA0856C382E79CA645B21FFB9F68B3C91DC526A8862809AB5C40B95359DF2D74956E1647BC7BFE2997AA93B7A667FDDCEAB101B01F04EC7B37FD81EAF12CF468EE1465368BB9C6EBCBB6F6CED1BD9E2E1F44B634E38D022161A5F62C3848AB0D35A1E986FD07313A986729B8B85EA4EDA84CA70DF450A0812ABFFF29D578C0339572A1A2CBA4B9820FDD281EBBF1041CD3912229DCFE20275DB7B36D890B8", + "k" : "A883ECBCFC3A4D96F16C96944BAF92155E7D04B572E998CC78AD8DBE46382268", +}, +{ + "rngSeed" : "EE762F5C9021C36446706A88EF16312F4A12C725CD7AFFF1484337C91EDA8E89F7007F3705747D29907B3FB7500E5074", + "pk" : "00264FBCF666ABBA49136B6E6CA0AC8636BB20D305BCA62BDEF6301AA51899D7341147B72C210AFEE6A3294A4AC8685B1B6003EAFB7E94D91FD958B5C3944129198BF02A2E9491491A2BAD9375CD9F184AAB285E91C877884B101511775CB31F2A2A3E7337406D7662C8D8C83C1933F0E27B8B2B39B1AA8897440EA5142F22B218C77C664092996E39237F577139014DA6DA6870D848CF98B006C9633FF138323261E1D042EA645E60813C11F9489714C197607E568C8045F0244FF40FB86634DD469033456604F19255645898181CDB830C1A82C4EB1373BA820515B6A44596342AC8B912C217603CC92B8A2B52CAA29972BC95AB334A93307D7B9AEE013B22118EABB947B1A23150481FA1E7B9146B9EF5FABE9DEBC682003EED2534D9614D90466C80A73FAB8B94D187A383463E7F6A380D1B34AE5473F58167E97794767A20BCE5B6D5DCA88B35695E0A2BAEE03ABD55BA0FE768A8254D40836233FAB358842675508302A337840167DEE53EB3CCB531A7637DD1B9DAC9A00432268002165F72A5AAD8CCC7131CCDB1C986A7B29BD89311099FA3E9460553900E51560364BF9AF461F1487CD9F0ADEFF5079B07240870C310AC4702E113F68433981242C153C49C43CD93493B52395B5DB073EC936F3518B7F6954426B9757476CC1BD0C4FF870A2124A8F8DAA3299AC21178235C260A018C169D083CF40842BB6A0F2D407861106B4E752091DACBB85677FABCBE180ABDC6235D0E8C34737A5934F431AFA670D000166F6C5E4516174A205F4BB6182BB24A54907BE5360CB81B5333A937C4E40FF2579B0039C0BA3374664859E376A8515B390BB46ACFB54BBD4AA6DAAB1DFDD44C712B311798C71E162F36F562017821CC96227CC431FFBC3634ACC704937187B8200D9BCBB0C25DF359C386E740195662AE24CBB24B181A23A2B4CB5E3A767701D3A80F7BB82133BE97DAA38A706C7E2949CE86587246BD5FABC774956019C2247F5748F0988087159D42B8C6B1AAA398879C77E32B0A5494926588DC537FE1F05A10741FD8814F191CBDC50CB2A0BA1EC053A789396208415C77C18D283510F410A722A187CFC552F63159648317ED696695413EC894AB80F4C106D73933E312996B23F073BDB9625727D8C0FF1818D9F78B91C4A6C33075F9A91B772138CBF6861937C53ACA7B535BAACD2BCEEC96223BA7747B4A7D50C36D3CB0297967CC447C3BFFBBB723455E421CCFD791C48F8BA558692E2CE278DD351E28D35EC1039F16D8281BC0867D529FFA6544B1663A14B6843FD85FEEA2B00E3C8B2131BBAAB0B2161493CAAB5464501FF6E30074A372DC6A905B9A1A66B637365B48AF4B55E45AC4236781B71B130718941F06C17D84786BF1A033B60DA7C6B0D4D385F3F323DBEA84C0BB8FA720569D1959473B1AF84459C0EC4EF133C0688323FE8503069BC15CBB391BA7041E665F652880EE367C97F34E7230009FC401D7A34B536529EF544233761BD2A01A9DA338A215492252906F979290202E5C666BB31A74FEB13B05CBBB341076674C02567C80531C5573FC6428B8CEDDF3AE84B8BB7018A3FFB02906770C4528C73360A867C2701158927EB5A9FAC60A2F401AFFC4C65198B4A5E1439001D5882496FA682185D21AA4EF95AC3EB5E675C7A4A4426F93", + "sk" : "06F99E63362CF6DCCC11A8854B1407FF12142D91A19D0395F3923ABFF155CB4807AA932E218232DFE932AAFA673150BC9E7155794565AAF7375F7195F0C1C35279A51D613C6BC32CDE086F61725C28324E9E392D1D3A91B0661F1524592F6772D4E012402C18EA162A3CC36B8F565152DCABE80691EA3B84D9EAB83DFC429036676D1109D9E258343B418F840A1C53B47211B55F490202C4659126BCC5F4CE23F2906630026CEC8418526EFCC02B0FEB7728A53A3298232AD37A424B4F980827E24CA9CEF26115A100BD224B4A304914C83629049F7E836B8AA539EFF61A60FA8154EA97C31259B3C629DC891C027C8E5441B5F164759B13980EE0A5BAA71DEB08C99E6340419B0F6EC82EE2536231E2634F9307781097F8BA2A22DB4412C5BCDF764F0B58BFE176163E1B5667CCC45B39C77B3673ED4C70786A33B5AAAFB5D5C12D4077BAA3223E2614A7E917C7462F220545FBE9275B1A62A882797E5A96CEFBADB309995C9B26747AB33E543B36080C29A4BAFE68AE41911AA763A8D90162A1959DFCB7890A394ED40A5340F0B8A89434BAEB9414BA460178B2C5DB503A28BC8F2A42CAACA2FBD6C77D758F30E14BB1075FFDF535FFFC76D02AC264787E45340B1DFBBBC4513FF15ABD2337B6D4543492160575F44BA1C793C3054BFE767A827875322CA753E200C717C47DB1AD47F12AD103C28E9380BE2868C8B32F7102C26B977760E67D98109921425611B9878E215494910730956BDC7A015506C45F919071042E921607560560237BBA0C3190C759295AD059B7C99ECB62222A54563BA730A7D3A4DDE375C9F931CD16C4344552FF984FD6AA9EDE0602A840BFCB705E078CC375437D3927455AAB6EA3872499B0795DF7BFD436CDA3368BBBDB990D6AC9D3F637BE663E7590055E00558D0177F7C63E7FA292097303D68A34F240A17C7C0B80C5A69004C195D915DCC880ACC9CAB1DB842C14722EA534B865488C41824017CEFBAA5C1127AEC9E535112764E713CE403C64A6A27662A254836327D5924846DCB646B79DE5AC0BDEAB9223F36F5C124E595165753656B0110241F6B805B0B30B1B698190B5D4F1CE112C93B4F6A190106C7BE120D2DAB2995578FE9C08DB3BB36C99C2C3F2001C6A269F563EDD088F3B50A39D508A67C75889012CC090217B321E99E95F4F310F8DB2CACBB853297601895A3430405F828827CF151A83480B4276CB73996FD5D7B357A52573912ADE3394C48B7709D50CB8F2381CF50EB0E14BDF5740836138E539A7FA6A4A94339CDE3BB71EC34EBAE4BF4763CE93D6041F62BD61C81868F81E8B88124E667CC83C0B226157560647996A2581837B75EB59D5A934BDE44CB1E664DE41184AC480323CA59F624662B17BCBC20424C565385958C99246D2383A9E2000F9B817FC57B7F32513D96CCBB6140510E11E224702893BB891350404F376B0B04A674B2161BC3C68E8901348A9A9D7742AA3A210319DAC25A7EA909F2E877728914CBC2332BED4876F5453AEB3365879A0A24244C6172A8D267CDF9C10787740A5852E66E3663A879A35208A07959B9C5997E57A779E8679563CAF551A597697473776519F87B0D7E03C1A686D705C55D1B1AB00264FBCF666ABBA49136B6E6CA0AC8636BB20D305BCA62BDEF6301AA51899D7341147B72C210AFEE6A3294A4AC8685B1B6003EAFB7E94D91FD958B5C3944129198BF02A2E9491491A2BAD9375CD9F184AAB285E91C877884B101511775CB31F2A2A3E7337406D7662C8D8C83C1933F0E27B8B2B39B1AA8897440EA5142F22B218C77C664092996E39237F577139014DA6DA6870D848CF98B006C9633FF138323261E1D042EA645E60813C11F9489714C197607E568C8045F0244FF40FB86634DD469033456604F19255645898181CDB830C1A82C4EB1373BA820515B6A44596342AC8B912C217603CC92B8A2B52CAA29972BC95AB334A93307D7B9AEE013B22118EABB947B1A23150481FA1E7B9146B9EF5FABE9DEBC682003EED2534D9614D90466C80A73FAB8B94D187A383463E7F6A380D1B34AE5473F58167E97794767A20BCE5B6D5DCA88B35695E0A2BAEE03ABD55BA0FE768A8254D40836233FAB358842675508302A337840167DEE53EB3CCB531A7637DD1B9DAC9A00432268002165F72A5AAD8CCC7131CCDB1C986A7B29BD89311099FA3E9460553900E51560364BF9AF461F1487CD9F0ADEFF5079B07240870C310AC4702E113F68433981242C153C49C43CD93493B52395B5DB073EC936F3518B7F6954426B9757476CC1BD0C4FF870A2124A8F8DAA3299AC21178235C260A018C169D083CF40842BB6A0F2D407861106B4E752091DACBB85677FABCBE180ABDC6235D0E8C34737A5934F431AFA670D000166F6C5E4516174A205F4BB6182BB24A54907BE5360CB81B5333A937C4E40FF2579B0039C0BA3374664859E376A8515B390BB46ACFB54BBD4AA6DAAB1DFDD44C712B311798C71E162F36F562017821CC96227CC431FFBC3634ACC704937187B8200D9BCBB0C25DF359C386E740195662AE24CBB24B181A23A2B4CB5E3A767701D3A80F7BB82133BE97DAA38A706C7E2949CE86587246BD5FABC774956019C2247F5748F0988087159D42B8C6B1AAA398879C77E32B0A5494926588DC537FE1F05A10741FD8814F191CBDC50CB2A0BA1EC053A789396208415C77C18D283510F410A722A187CFC552F63159648317ED696695413EC894AB80F4C106D73933E312996B23F073BDB9625727D8C0FF1818D9F78B91C4A6C33075F9A91B772138CBF6861937C53ACA7B535BAACD2BCEEC96223BA7747B4A7D50C36D3CB0297967CC447C3BFFBBB723455E421CCFD791C48F8BA558692E2CE278DD351E28D35EC1039F16D8281BC0867D529FFA6544B1663A14B6843FD85FEEA2B00E3C8B2131BBAAB0B2161493CAAB5464501FF6E30074A372DC6A905B9A1A66B637365B48AF4B55E45AC4236781B71B130718941F06C17D84786BF1A033B60DA7C6B0D4D385F3F323DBEA84C0BB8FA720569D1959473B1AF84459C0EC4EF133C0688323FE8503069BC15CBB391BA7041E665F652880EE367C97F34E7230009FC401D7A34B536529EF544233761BD2A01A9DA338A215492252906F979290202E5C666BB31A74FEB13B05CBBB341076674C02567C80531C5573FC6428B8CEDDF3AE84B8BB7018A3FFB02906770C4528C73360A867C2701158927EB5A9FAC60A2F401AFFC4C65198B4A5E1439001D5882496FA682185D21AA4EF95AC3EB5E675C7A4A4426F93B30FE432C2E9744430805AEF6B75CF3011FF387E323558212B9D71ED71F044F7BA2DE5DD570E201786CBFD5D27020B649B011455909AAF0AD6D92C1B4BB1F8DB", + "ek" : "12ED5C2C38AAEF145D4F144659100ADE04A6E6DB985E51C84E2F85E5241A937AF150ECD876308049CE2C2573F81558B1C2A5BD9B5D468D0A5C6F9A6FAD7F61C3F8D613BEDC3B1341DB72A4AFAAB4550EE8E9CECDCE5118126BD284E0BBCEEF9523264DBAE3B8E14859F619D6967CA6C76ACB5C6322570DCB79C0EBE96C871DE264C5553877A17176333AC31703B52334ACCDC54830176CE4534D31CAECDE7362F32F1DD7EAF312340BC50CF7FA30F4594E0EDFD225D06139078E0E60AD1F6C52D450149CFC50604938C67D86FAC3C8757663879D86D6530489C8BB5EA72FF7E561D5555C316F21DE5CD8CD41BDF5DC96D85180A653B6930A9A37596D7BD202755238D56BA7EAE727F5EB3C9C96F0D0B0F5F812A97B2C6F54A287164FC9D8213D5D5E4C7410E9A927210CEB1241592F9C06B93615732CF9064FA40AA6E78C031E358759EA8BF5E09DCFBE30C3DD94986A71F4176599E3A23CDEC2A1615D6A16A80D576B96EDF5A9056AFB7516E64B91084D60F2DDDBA1FAFF53C6C078E40CEB5E17E3B5265A1C34B6A280AC75D8DA08895F8F36809D2BAA0F03336C632560048101642DFDF7EFC9BB05216574286475B3EB754C9EE7DA4D79465BC09AE3A986337A0AC6331EC36DF15DCD6B600B34CD0E49ED9EE5869FB190CCDE999FC4BE2B9BF9E3993907F15CEAFC420C13F68AEA39484C87546D084ED7DBF9D1D97B73E399E223097476A138EDF4C2DAE0B571743F35B8BFC137124E0C76D01143EA215B5BB9B01AA76A15A73FE48001D75F069C728532620592F92B0BDC2915D0D28B939444E4326FDD3030A63BC7B57A022B72312FC4D96F3F417D28E3B73A1492413282D6DB967258219B66B9E82847EA018952A1755954668F6F2951F25AFCA652AAE2EABC100E4F513ADE8F499B04BE054BC88D665C19CAD768DBAD77CD3A39E957E564A1BB28FD80FD7C535886FBD54BC6C113DBA460D98BCB7ADF8BC5125836EA43D6697169CAE7E6BB8104D5BD135B3CC835D572FBC5AFF6A5D2288EEB79D3B9399D2DD17BB03D7F67F04394653BA4646EE48FE401EA2F896B436026FD17095EE3F9D6FDF58E6570B6A628FDAA9AF130370C1EF0393DEB7074EE84B486F77E341BB9C9F73D47B972BAB42565DD0D9AE29E68677B434FFBB98361A8A8ED361C309B4B3810B3C3679075CEB702DB09F97479FC07A70C4A8EA859A7B4577BC70BBC405EA0088F8F9408836A2B51F408895C8FA47FBCFE743B800F26889225B04D0F77F07F7531821DDFBB0B02E3DA893DAF967A6E2BF1F73289FDB7F9D125E2A23F3433AE8C19AC9226D50C9CBF0FB80CBC5B32FA8CF888B2654FA019C90EB7FB6D8490C8F8B132747980EFDCE5096D8933E93526FC684CA192DD498F5064A61D7B0A6D90B652FB09ABF5DA270C19FAD49FD9DA0317C453CFCCFE34CCE4678888582C3211FAFA13EF2FC6719C44EF365C29F9B8BD8D6AC9F570B442BB5A396C3615C41DC3C7EBCE6D0069F08F492300B09027228A751A45DC2351049ED2DD5DBB56E8", + "k" : "0C9BC34B6253A77B1B5FED3ADFFED0C6093752F1CC5E0E1C9B15F8E3F39B7CA1", +}, +{ + "rngSeed" : "D882BA69AC8BBC88715F1C6387531F53273A5DAB87E66FAA8221A7F628D2BDEEE1CBC59C0E08D0ADD84520A3A70C1389", + "pk" : "869719CE20C5ABACCD8889286F2A77B388A58EBB7C53E79619762AE5111B6F352192288128A83202005ADCF0B15C0640F2B84D2ED58EE806BD4FA22AD26C5C8EB9A035768951A579F8FACD48428E508ABECD418617FA5901FBBDACB6B539C148AF327823009E86FA49B96C42D8EC5ACCECC423FC979C475FC9C63696C21D206301E9D54AD1088BE167AF34C57FACC25D4BB49BA5677842E27C1FA666B0659C66DC412DE949980CA6A707A0C21976822579A0FB1D697892FC87251354A17F630271CB3B10F5C578777A990361B467C1374897675748F763619E065104A31999A765815CA7A22103F3631879B790A862450C69AF8D29C0F9A48E8DDA82F2C03C0E12B62484C4EE35002848B030E41DCF1084B1F70D405677A059774E322C7B72265E32810E761D82956CC0194257F31157928B786B6FB6011A130620D2F51678D27DE0965465D445E6777660865DF9E73BC6858FA8155BF5CB4BF9C23527340C32211009144FE456950694B656A2A30C55647D17CFA1856981867AEB82AF63F1525C31CF643B32EA822B2F389AD4255838A2BC2FF850CBBCA834C87F9FBA1C05BA251ACAAD9AD99075920653D29D94C399CC4A2E4C7A871E176A275B7AC0A4401D36B35113595D51B92CCB8618F3CA40B4900774A784644973477DD492C66D09BA9B074C3D0347DAFA08DBE43A9B890F62A5B9CAA996F9E362B9A2103942CB91915CE8E390AF54A2578227A9389E922B9C382907853BA05EB13E7F03C079301DB2135D95C934DA5784CB05B9726A1C1E28B01F5C5EDBA7A340053EA51C32D0930653F46170025204C0ADF94C2075631C55790895495F23EA104A60B88C8B627DB4256B6892D1B7886F959A18AC238AEA494E45AAEFD72056F362E7F34EC5E20E9C9AAF2EFA8683970E310390A620264EC1AC3AF515C24409EF4A4B99D0725DE1506C706303E2848E2904F8C4824260162E5392B5B0595D699357B190E237CE1E3692ED95B7710488AD285C04DB243EEA475520605CB98B98A1CC893A7F1D7492F038795DA03F63A91EC925A914B3C1FD9A3B5A74BEA6B6770A5B1400348F7002555BA8C9C95B88CD829EB179472245228C21AFA2D39238C76CDE000898B718884AC8108C06E81C02F264BB6C9C5C13081C09D431AAE78A26D62FBD041F32FBC012D0C83FB9450448CFCDD8CF881036AC096396E311E923478C5A346CF5C930D01C84B04400B38759A18D3BA40E46C8AF5F133258F353AAACBFA68B0BFE206BF7FA65B192A4798A0FAA68B2574725DFB69FF108B7C155CF77426EF8A776F0455BCEA85FFB91A74F7203BDC2A9D0096FE7AB57EBB4CF1DEA1CA0C5C4F9E264D2D5A0FB64658BB3B1CCC93EA5814407B6C865BC2B2FA14311CA50016B782716841BF89474C10E182AA51C0416580769312419D1219261A548EF0AAD81159E4BE73BDA9C8903B7A4955456A3A8B405A27C18968901D54F8A0CA16E41AA1D0C128EDC33B069A1C1E4B22438BEB74A996C8B30C1717F07092C46402B1D9B710C46540AB32F38381C95B7445704461C0589CB427606057C78F911FC72BA38D1B664767DF30901B148B1D609601BEC3E40E41136EA9EDAC60F1F097C49906F105C99C4B069D5325BAF3E6882DFDA254850BA1AE5CA738086B4BB3C91DF05C11C1ACB67A98D", + "sk" : "93B888D05AA46698878F187BE0DA6290127B2CACCA5FE508C40A523AA56B923B5325FB7BFE0B3CBFF11FEFB8C9ACF6B1ADD2A41D265BE89BAA96989AFE97A5A749484D27B8761B6E9CBB2A957676743CC79B22A74BF92AC693BB54A31C4F269E5D00C470630F7C491A708B40BC7160415576DB195FE78B3C33140882723387D4AF2D120B0FD015B41B5984A8C217E818300831F1556C5489139F216A4FFA5799246E9151790B98C2B907B8CD917F8D981E7DBB760A725A30E34D997774C657CD4D2648E974510511583F15C5F0100872B91D0C1C89C307AB4DC31CDE68C364A20712559A7C7C58D6CC0C8FEB1645D85436A8188D7C171DA14451685591380BC0A5417870645E4C633A2A430F23941C80C92694B8CEA6674E97A032C89516397D42E44855B4AB29F484D4E33097754D0FCC672F452BE0B3A2B752C2E2A87275AA89E65CA0EFD096EC158F591557C7FB1B6E696EF2BA704006B7F6E811F2385DBA947FB10C404B79B90E620A842A569DCA77F1039B62403787CB36BDC8984C352C48635B552361C77B82EB67ABE8EA1DB025302A98B9B075A5569243A8725493F07CD025494B5C01CCE508D594CD36F473B8416A9E7A8DE0A99879C109161AB3ADB78D01E1B2BA2809B7266575086CBB2622A4E708733BCAF322420A65873C624DBF1C20A07821A0EC02611A36F4501485A6399A91B888AC547C50120E5070E597A9A6A67F06A2039CD6CCF7246ADC0576A3F4457CB9A4C4B46CCD846A77F416961072CFE64A32920851AB1A20555122942B7C3CAD5B137F6885B39D66CFC4F5C7C6E63D2D45C8E184467EE336945AACA71442B1508BD9687F40A4B70DB764BBF90510526EF1842151C56DA153A100FC92EFCA3539AC6EFAC23FCD60665263CF435AB34336B08D2023EB147EAA00C5271459B026638B9C18D2D04E3B429BA38053DFFA2B1930A7453146E798323DC5C5FDA63AB285810DD734B9988691C8445098A2ED96CF2324067FC45D12F118B2726104404C2174097147CC6363C684215A12B4B34B161231331C56FAB25F0418F5E55FCD8BC258349524004A7534B99051113EFCB310D61556788E187C1F410B6563530D8AA4BD07690234D504B4A9795D8141D56049D8E1C019932D46219124596A64E20658F010724547E8AA25D55C042A8A58DE53B10C9C26740812CE6952F765BFE6153E1B43582F5B7AF3AB3881EC42B4F80163F89648C622AB625DA6B730F47244D2391E32C2BB19DA532C726F30772CD90B64F481CAD12C86C6166BC6F38FB0F92975B9AA31B8ACDBD5BF5E746891A7087849497FEB4FA63C28A4836784AC8A6E631055260EBC0B33C5140FD3ECB5D82156F16AAB8349411D1192FE578E3D359E22705439317B7DF77D08D38E7ABC8B146307BDA7A7E00B8E0D51836B1CCD35611835755A72A6BCC069165164A1181920AF68434BD639FE0764FE07D0B6871CCC617B5958C26763113C9062BE342DC5E44FAB720A30A44A10AA0458379C9D8719606A564DF808E63581820606BA242AE664C4FEF748AD311AC4156F597C39F17C93F88A74418B734E0CAF607C4F9D72877C925C0F25410F551C2B3860FC26CAE2F3A319815A239BC4FD627DED7181869719CE20C5ABACCD8889286F2A77B388A58EBB7C53E79619762AE5111B6F352192288128A83202005ADCF0B15C0640F2B84D2ED58EE806BD4FA22AD26C5C8EB9A035768951A579F8FACD48428E508ABECD418617FA5901FBBDACB6B539C148AF327823009E86FA49B96C42D8EC5ACCECC423FC979C475FC9C63696C21D206301E9D54AD1088BE167AF34C57FACC25D4BB49BA5677842E27C1FA666B0659C66DC412DE949980CA6A707A0C21976822579A0FB1D697892FC87251354A17F630271CB3B10F5C578777A990361B467C1374897675748F763619E065104A31999A765815CA7A22103F3631879B790A862450C69AF8D29C0F9A48E8DDA82F2C03C0E12B62484C4EE35002848B030E41DCF1084B1F70D405677A059774E322C7B72265E32810E761D82956CC0194257F31157928B786B6FB6011A130620D2F51678D27DE0965465D445E6777660865DF9E73BC6858FA8155BF5CB4BF9C23527340C32211009144FE456950694B656A2A30C55647D17CFA1856981867AEB82AF63F1525C31CF643B32EA822B2F389AD4255838A2BC2FF850CBBCA834C87F9FBA1C05BA251ACAAD9AD99075920653D29D94C399CC4A2E4C7A871E176A275B7AC0A4401D36B35113595D51B92CCB8618F3CA40B4900774A784644973477DD492C66D09BA9B074C3D0347DAFA08DBE43A9B890F62A5B9CAA996F9E362B9A2103942CB91915CE8E390AF54A2578227A9389E922B9C382907853BA05EB13E7F03C079301DB2135D95C934DA5784CB05B9726A1C1E28B01F5C5EDBA7A340053EA51C32D0930653F46170025204C0ADF94C2075631C55790895495F23EA104A60B88C8B627DB4256B6892D1B7886F959A18AC238AEA494E45AAEFD72056F362E7F34EC5E20E9C9AAF2EFA8683970E310390A620264EC1AC3AF515C24409EF4A4B99D0725DE1506C706303E2848E2904F8C4824260162E5392B5B0595D699357B190E237CE1E3692ED95B7710488AD285C04DB243EEA475520605CB98B98A1CC893A7F1D7492F038795DA03F63A91EC925A914B3C1FD9A3B5A74BEA6B6770A5B1400348F7002555BA8C9C95B88CD829EB179472245228C21AFA2D39238C76CDE000898B718884AC8108C06E81C02F264BB6C9C5C13081C09D431AAE78A26D62FBD041F32FBC012D0C83FB9450448CFCDD8CF881036AC096396E311E923478C5A346CF5C930D01C84B04400B38759A18D3BA40E46C8AF5F133258F353AAACBFA68B0BFE206BF7FA65B192A4798A0FAA68B2574725DFB69FF108B7C155CF77426EF8A776F0455BCEA85FFB91A74F7203BDC2A9D0096FE7AB57EBB4CF1DEA1CA0C5C4F9E264D2D5A0FB64658BB3B1CCC93EA5814407B6C865BC2B2FA14311CA50016B782716841BF89474C10E182AA51C0416580769312419D1219261A548EF0AAD81159E4BE73BDA9C8903B7A4955456A3A8B405A27C18968901D54F8A0CA16E41AA1D0C128EDC33B069A1C1E4B22438BEB74A996C8B30C1717F07092C46402B1D9B710C46540AB32F38381C95B7445704461C0589CB427606057C78F911FC72BA38D1B664767DF30901B148B1D609601BEC3E40E41136EA9EDAC60F1F097C49906F105C99C4B069D5325BAF3E6882DFDA254850BA1AE5CA738086B4BB3C91DF05C11C1ACB67A98DAB02B962B6350A9E1314BAAA272B6B13DB3D1EDC9F09D3ADDF07F6826A3556BFF25F42AAA0D647322BD837CB730AF6082D2FA2D17BD63B162B36839FCC2DF0C5", + "ek" : "5345DAB543EF9FD480BDEE57238FFEEA5DCDCA70AE206E62BCC316262626A7F7BF7F8AB9D5AD11193EE81DC4D8CBB573BC1C87EE5C93B6CE23CE6044DF19ED3C859012A75E5A0FF210EE38B4BFFC87E257194EEA35D7524A562EDFB581522A00AA9825E454BE4904E6E63FB963CC9143700F03C65BABBA23BB9A266A53C42DF791E5457EFF635CF2BD10004C3FB1A0A00644FCECF05D2AC7FC854F828C11EB13AF098BB866AB9E4277047311C88A04660E632412016BE0BFA0457462459F0C52BE5A44B58D50A14DFDCEE286B5F9F72E07264EB99D91E63CB49E65CADC6FFDAE649786F97D002F2A1AA12B8E17E54EB595FA68D325EECA78B70986303363762BC068AB7A61CAABAC8F2471FD0FC5BA1F352561757AD3D6A1ABAE835EC29E4C06FF647AA71EC443CFB6FB01D3FE45AF27AD9557871A8971E462F936110D3C3E4DBB6C00537C87C2A91953D5F2D2977C0C227DFD0E216874455CE301D3CBAFCB7CC7B7BB089E31F39C828B4706BE3F8DF0F3E9BBEAA7D61CF13493104680596899B91FBDD314B7BC09872FBE688C26C39A46D8E8EE5EAE2CCE34AB67C3C12EEC761B068225D4EFEA73060E3DA3DAF7DD44BC383C2B8A70C161FC64A64E4629C746BED92CE164CCA2725C6B641AF32C42DDA3021E7D01DFDF27CF00728C1D1DBC3D790C4459555737E57AA1A7EA258F009D60D5515AB7E225C14197DE45DC2CAA1A5405C43D277A21427204609EB3C75987F99F63117DB43A77F3D1E93B5D53664E453481012323765C53854D547C1C83B93071AA56277309401B0E0BECD5A19FC7DC4FD22FA3B2A3B8612F8346D43A849210291FA501EAC01740984AE05799043384EB8EAE891D124F68DD0435A8BC4A448F6657351826B0433DCBCDFDEAE17C68189A34E56C49C871D3A3C5643DEF6B392A6D864920EA7ECAEA79677F0ADA410AC7BFF64896BAC259BB038B5EAAB119567DE1BB1B742F8E5644731A50F2175F527EFA09ACDA906A140D3B0797D35DA8E9E1455FA59F07B023BDEC9FA005F33BE1E4548E93B35B4E0D3BADE0EF7E914364A4B20AF6CA381FAD3DF1A6DC3231AECA2691B4FDE36859887ABA76DF801D923EFED6F37F7B43C299C5E17F76E9577FB2C7714547A6656C4FFB3EE4743F44D29E77A9CE7EB162F3B43DD060FF45846CE812E66F821810DEB2348BF016BDAF1DD590E5D6394E03D898B0C264904C62F37A59294DFBC8808EED87D6FDAED701913FD6FBC9E429FB93EDB480AD288831DC0BFF8F1A3A697ACF9A00B54148AB89E271DD332DC512FF7634CBA599BF00F0A1AEC5D34421B7E97C99195D1766E05999BCE580F0CC624A86B2F59ABED148D0C0FFDC83E7EEB74D6B9DAB8440C85C94B447D02AAE20DA934A19B9700A3D7E31CA73F61960D8575B814FFBFE4C0E910AF38BB059B1F748008435AF722E220F05A758953C25370BCC27B37F4AB71A60A078BFEF1B46FA4B671CEF2C0E727A592E4386BC2270D796468AD0213F2C12619C57ED74EA820E087CA5FF14C6E5E3C4C26179", + "k" : "9E84021296AC831F4B9D8E299E08BB2F95C5946409E210F86C8571EF0B238701", +}, +{ + "rngSeed" : "6C3AFF39F5D097096D882F24717718C8A702382DC4AAFFD7629763FDA73C163CF084807BBB0C9F600CD31A7135F48AEC", + "pk" : "FE04B19E38680E8B5F005167B4CCBD4BC2A87C3A98D2B2AF18738B8B44B1FF480AD69183C828BD372A4A3CE12CE72867A886733F3BADE4144AB55B63BE2902AEF88AB4E129551540E8390357631233ECCF23A0668886B39942C23F902265A84A08B07D11B85C096512C09AC3C82023F23AAF48578BCA4B50426713C7E5270980C78C6643EF615C2B6AB57B98111A321E30D8A38B5A376F9A2C793BA196E293FDE201BA7261E222080D951B4F249A47DA98C2AA4B87E165DE574EFDA9577DC815C847AD269210970975D8322645246CFCFB46A194A9B3CB2B91A20FD9107948D8777D0A14D6187C922A5BEED80600991F3040643480286A580E932032A37B8C82833535F721EDF44E97397E14931CF7F49201D80B75D650F204BD37416C643BA725D2B3B4F368B033589E01CDC10CCFE264A6EFE01ECD3B8E92478BFD7C1ABBA973459346798007990A9EDF57B081C73D699B7A758A6013106597AB803870C24E4C2E0D649DEA9BC0E0FBC742571B7B6BCCA714881DB2597C3A45CF0794022B58985A61D582AA59B17E9C567E4B4268976943982705F389566F53C49526AB6C210F4E694544D307D2C8612D1CCC23658127E8B071E58136734082616ED011397BB781896953C73B5127B28437F38C27D663B05745D3FA37E9C2A07DBA767F0859E7A30E9D48CCE5F37632E817060CA46633C9B4F6735C3BCBB9185ABF39BA9AD600718C6FB84B7C7B867B5E5C51C0B0CDB03CC83B49568A4A02AD831FC93157A4E5010BA81C0B6BB34AFB908A77B2E8D106F752C39AC1A00A9467D58484BD273733947A619439576A98B4360811C97E73431901978D295148BB991433AC72B4CC3E5CAC2A8F68AC9D9A3F5D53889343AF7E6B02316831B7208939A88E613C0EC5D07861099488B08DEAEB2CD295B6977C7C9B2630CDAA5B0A93AB7D98728B3CCEC979B869D506B9C679ECB673B7D83DF908AA58603275A36291CA60FB717B74406EC852B802EACF4EC3C2533315240624B5B7A8EC960EBEB04D970CB815FB059C458D02254FE8564F154A8C240086FD98AB6A4A4510FAB5205A99AB873F3EC29B603A660061B8EB803B6E71740EF174DB09BD6C3447197765A0907D31FB1635435601B0A8337972263857F301AE5CF56A23DCCFA392020BC84E79AA6A37450389A616F6E626E001592F7A71FD00AD82F3AC9D1979E83955BCD1248E7C9F5245A22BD26479CACA02F70303B8C978187F102BB949B7A709E94FC2069489601C2752222DA41090578EDFC1083E0A8BC9110B0E64623E320F0BC56C4F2B2BEF38452AC7C2E17C5A72166A48D55CE5D3ABCA1A98D6EACF734249E8820E29721931FAAEBC3ABC1A7453B5B01B52A27284995DF4F07A3827BD9567CC31B2BB08825046226E059B52BF8B0F864793926B461574B73198B6B4A128F19607BF1205380127E6597EA4B099EBA13B38FA376177CF8D090881A20164D804320469B15988759025F5089D7B98675D554CE4714C124C1C30775CFF79229B1B99E4206CBF28BAB4017077D4721C263542EA1742AC45CC500D327A3DA9C46309BA09742305B25390C50ABAE20B6E8C8B3AE0208AADE68D9E2004BD0C26D21C8096CB97A1A2AB02548AB8F1BE5FDEA37E49857C092EBD421EABEAF7D76BEEA2FEB7CFF7D2376A329549", + "sk" : "7DB7CB1612BD434144E3E8C45DBCBD0983A000DA3AD94150800C6BA82929366027B9F3213CB2AEA2E094ED979A179B95629B885A77B3006D6735F6ADE15589F06397EE572A11C9A23E206168D10736E0A073B28240518FEBC2A88135B290231C78E5AFE50A21BBA9256280861EF75F0E97336F1B735AC69B0F652BB6D3B46D6520964671A8309DF2A2997B36A4430C7F1AF27443B869DAB0973793A39014614F96B4B0F554737B77481C0D16288183B71DC9794F713098EDF87BC947A96F542E2A6C11670401DD475E3214BE00C0054C687FD3774263BC9FD3CBB85050A02D53C1CEA22C6DA3585F743D14984C64046217555F45D9AA7B4944D14CBD3DD69BB520C150453BCF91387A1CA4BF4353B15A9792EA89DEF5CD09A6658ED57AF3CB2D2B1464AF2BC28E016379569D7C352CE2D2C350F8C494807A8D239C2B0654BCF2CB866BB35DA6289F5505F0059E4351A44810920CC6AC87C224BE4902F2F002936C4DC13554FF7588C13A1AB7A12B23C273E7FA5E94B152BECCC94E0A74D3580414C60DD2E4806A056235152ACBD21E7042A3C3429436A52BDFE45BE4247A0D24CBAA1821543BB6D860889933897B85397C94764DC2B1AA94555FF42412377BC6902FDEF97295569C8CF1585AD8AB64C124AF41A534EA4B2E5B6D76E33DCC5CADD7E376DEC13652115E9733C1AEC91DC9446FAE1702A7420B45F32C719473033925D7996915F40FD1F13D11807811F1C991B0137524ACEF597686B61C146526564CA162935307CB6FE15606DC660A550C848EA8171C392F5A916738DB2D90534A4332C303601D14B98CF5E7CDA3009BF50809D194000B10B63C7C718D8299497228932758629B5529610BF56C7A33464B206888228A257EB8A8C149B8A0846DF20C84722CA98A458C09CA598D752F8273326F27600C179F1A8CB1E8F14072DBC9866058A0F448A1556531E010582B4672CB9FF873865EAC6096F9A4FA0225F4855FF15C7A31968EA1447CABA5C295F70D5C7990057751DD91365C4C57B601CF45547153B2258A897BFA5B3D23C00D0BE449CE5172FC513141CAA315B397D6D77EAA67C6570A60A3B16F90F1087DA1196B363CA47B830B4902C23C97B1AC33D464B5293959F1A007E51374B3F016F7BCCE7417695DC015AD84B37E07AABBB0630C467206D2471509968F88914FE6BBBA9742878632EE6655418535B4E45B5595C90B4BA088541E51A32F4CB920879268F56861DC40BC9F661E8F611288FAA6F0C911BDF631DE2BC9D53369F2B116A26AB2BFF14981FB817A9B4D8AB928FA19A3E1B03F4B89CD459A64521300F5E5AE6ED8125F2544BB039A4F09483A799EBABB8839C4111F45A013276FF79A3AE9E5001CE451A0AAA5E84B185F8747BA35C58A253618A8593D155ADFD05A5F755DBEE456FFC3883FF715BB42AE09531FD6D88ECBB21D3138223326B8E9362E5382BE38E7035701C2F0D72C678B47A79A891487BB3C9C7D6B823231DA391B2B3C6751BB66B7A7E326526F3221A3A936FF82A09C07CF33763B3072B93A2426F2508B2B734E184B6F00488F378373209552A4701C43A746E207342E463C4E11BD5AB1B5F2E2B8691057D6162DD66A1BC97CCFAC8537FE04B19E38680E8B5F005167B4CCBD4BC2A87C3A98D2B2AF18738B8B44B1FF480AD69183C828BD372A4A3CE12CE72867A886733F3BADE4144AB55B63BE2902AEF88AB4E129551540E8390357631233ECCF23A0668886B39942C23F902265A84A08B07D11B85C096512C09AC3C82023F23AAF48578BCA4B50426713C7E5270980C78C6643EF615C2B6AB57B98111A321E30D8A38B5A376F9A2C793BA196E293FDE201BA7261E222080D951B4F249A47DA98C2AA4B87E165DE574EFDA9577DC815C847AD269210970975D8322645246CFCFB46A194A9B3CB2B91A20FD9107948D8777D0A14D6187C922A5BEED80600991F3040643480286A580E932032A37B8C82833535F721EDF44E97397E14931CF7F49201D80B75D650F204BD37416C643BA725D2B3B4F368B033589E01CDC10CCFE264A6EFE01ECD3B8E92478BFD7C1ABBA973459346798007990A9EDF57B081C73D699B7A758A6013106597AB803870C24E4C2E0D649DEA9BC0E0FBC742571B7B6BCCA714881DB2597C3A45CF0794022B58985A61D582AA59B17E9C567E4B4268976943982705F389566F53C49526AB6C210F4E694544D307D2C8612D1CCC23658127E8B071E58136734082616ED011397BB781896953C73B5127B28437F38C27D663B05745D3FA37E9C2A07DBA767F0859E7A30E9D48CCE5F37632E817060CA46633C9B4F6735C3BCBB9185ABF39BA9AD600718C6FB84B7C7B867B5E5C51C0B0CDB03CC83B49568A4A02AD831FC93157A4E5010BA81C0B6BB34AFB908A77B2E8D106F752C39AC1A00A9467D58484BD273733947A619439576A98B4360811C97E73431901978D295148BB991433AC72B4CC3E5CAC2A8F68AC9D9A3F5D53889343AF7E6B02316831B7208939A88E613C0EC5D07861099488B08DEAEB2CD295B6977C7C9B2630CDAA5B0A93AB7D98728B3CCEC979B869D506B9C679ECB673B7D83DF908AA58603275A36291CA60FB717B74406EC852B802EACF4EC3C2533315240624B5B7A8EC960EBEB04D970CB815FB059C458D02254FE8564F154A8C240086FD98AB6A4A4510FAB5205A99AB873F3EC29B603A660061B8EB803B6E71740EF174DB09BD6C3447197765A0907D31FB1635435601B0A8337972263857F301AE5CF56A23DCCFA392020BC84E79AA6A37450389A616F6E626E001592F7A71FD00AD82F3AC9D1979E83955BCD1248E7C9F5245A22BD26479CACA02F70303B8C978187F102BB949B7A709E94FC2069489601C2752222DA41090578EDFC1083E0A8BC9110B0E64623E320F0BC56C4F2B2BEF38452AC7C2E17C5A72166A48D55CE5D3ABCA1A98D6EACF734249E8820E29721931FAAEBC3ABC1A7453B5B01B52A27284995DF4F07A3827BD9567CC31B2BB08825046226E059B52BF8B0F864793926B461574B73198B6B4A128F19607BF1205380127E6597EA4B099EBA13B38FA376177CF8D090881A20164D804320469B15988759025F5089D7B98675D554CE4714C124C1C30775CFF79229B1B99E4206CBF28BAB4017077D4721C263542EA1742AC45CC500D327A3DA9C46309BA09742305B25390C50ABAE20B6E8C8B3AE0208AADE68D9E2004BD0C26D21C8096CB97A1A2AB02548AB8F1BE5FDEA37E49857C092EBD421EABEAF7D76BEEA2FEB7CFF7D2376A329549C153354B0187E658306A0C860B1FE6ED14686CA77D37B7C82D66FF62149406B723DA505EA48A79EB504EEADDF7D19D736F39A46C837F2A0C2BF3FB876ED8E6BF", + "ek" : "73C3BF0999D0BE554AF531370AB02D2A51425A319074772F413D9787BD2F9CA0E74BF4DE638AC2BB3CEE5FD07B47BFEF103CA04FBC531105C672DE4DC4DEB4A456F87AEBC48CDA9A03C582B50DCC44D7044182FCF8322EB55474BFFCA921292CD76C01C2E2F527018F530E6E5F8C6C1DF111D3B533C0733B27B2037DB68FA8079FCB416A83DFC9EE9FDC371B1D118D110DBE6CE2A6A327A9204D14BA166000C61C116BAAE50F17AE3C198A7C579115742E2A0C9BA081118F4B4E499CE570259922016F0CEED26988754331B1B04222F0834B84055AB6159BC2661EC3BA2CC88AE7664C08699B46B9BED9D9A939200801E7658A6C3A1B67D8F2A0A31D7821ABDDF081F84BF493065635F9D55208EDBBEC8AA31B4ECAD004C941C23A2D8A8D783BD6224584FEB9E4275C7033F67F24F10B76F5DD0E10E941F10CEAB29A88829839E5685A08840C82C71EE625DCD6C1C673C452C4D4C73853999192944B0A7D684EC54ADA503C4F4A9738E3C6A7B14B3B0A38028537AB82D05DFB919A06D585BFA863FEEBAEE5AB21E35DFEAB895F141368AF2806A3DC54C477AA19C577315C7DD098873C5DC422EE19B689EA80485CC6A30115D8DF5869E5D99D9396D9C4299F4577C9ECC885C7F9F23C8E85A0B0F0D53C73A252AB23DD593507FAC743532DD9FFBAC65366630C559C45CFEA48E6E7912CC16534B99C6A19786DF558A29D56A2A34772FC0834E4BD53249CD966E92B953EDD6C61CC6A1E33F68A5E77E33A603B70960254057170B74D55B4B850D15201D18F049F3CEBFC8E0FDF4093CA9396AA55E5B7DAC09BEB77C81F2A24E31C0D691A56D6DB01315796C933C45882210BF7A7C950ABDD1BCF282AE1565D087469DF2F624A3CA929440CA1ED3C7209CD74AD7A1927D86C038C940F1A93EF031D5DCE7DDE74552A9FC2F563976FBCFCB667F34D9A2FC7B1550DCF2254F1B3A36C0A679E8BC76137852D45C61AC38AA5C68AF92B17929C37C98525E68BA195BE2682534725FF9CA21EBE2BB33CC121ACAE3ADAA8DDB45F03EA9D9C4A8AD2F582A30D30DB1A05B7D9F5039BD6B2CF4B84EA253CFEC5602E7AD1CE50F1B946D51E3DF9CC0EA7CEF9049D8F02419D2167A141FB440260F65A6750AA591BF4F48CD07B7EF23B53BAC9E344675C91145E5935443785CCE6042383BBDB55C4D31433B81E4614E92D3171E8861F066C3A0A7B82F949C0DA26240E6491C0244049E70264026811A3C1007B34DAE96CF33B8AECAF6D151E55C7B0C9754DAA5D3BCD031A9691D2C6EAC462DCAA92EB80EF5CF5391555506210D3ED7EC912F8C3E18587E2C30BFA88E650F2F672D1C8726361E2CC639C1D83E2FD9E9DF262CBE3277F6218ADBC8404550A81FAF25F916028F4CD1B5CEB03BBDFCBE49DB711F0942105F67552C4D81EC09404D4A6D3843FD6CBC044BE7A1EF29618FD8338BD30D4C227E917A8B40A2C31DF8A407C6976128F089375186EB44B6DF676D64DB4C8A42FB86EC5DBA41D1DA1957B8622F1722BF35F246637A0262E77", + "k" : "205AB77BB526431C3E6CABD5B5552C19E5E05144F1DEA03D03E284DFE17432E9", +}, +{ + "rngSeed" : "CF520B92A2E3677AFD003EC1EC6EF136A709D78F828C9C0DD4946EFBD451C5FAABFC83CA66F9D3D17EE4220553B7A69F", + "pk" : "57C8B4DD8AB3B7E3203F2358221C9CC0F2A671AC1846E59B3D5C95576806B571C64746BD4BD541D4C55128B9A7D5208960A2B74A900A426013F6B48FE7FA1ADCBA5EC1E44594D3850C1A90E2A6BB341210039B48224B97EFC62583F5882C71505A96284CC7CBE9873215697BA688546D3A6F97729B22251F479AB3F92CB08FCC3A9D962A661C6150EC6DFDC7560986BF808B4504EA2D44D595A8C34F4A564147CB798FDB6836CB448CA857D5D08242E233E3826797A4191E53CEE0B375D395CEFAD91A395527ED094DAFF389A198C9D3B28B9E42B002FAB4AEF17B3089885E8017C047C35152A0E2709CCCD7BF4D4A081D3160EBBC3D7A3BA977E221FEA55E01823F2F61BFBEB9388D04103FA0C3330770C5EA5A882B26D14C4266B27722F29863B60C9F6984A5F0C2EE8B6F27385933994D8F9973728C5BE6898012E4766D842CD1D7B360E415286C965B0B5277A5A1C5F731DD085DF0F9579A31B5920227F238C389A723F8C31EA1C45AFCFB6A62E555B0B2B766E78889DBC7A8A174FEC48E328B4411338B26074002261E3C19C575B42F5A09A268B223AEA813706900E785C3A05A98A5708D083C5E6243872AD78F3B456173267D61D57B2F330D01F7BE8CAC65B1CA46D8492F39C83338D92F3EA9A3CC7B502B115D5A7700E5885F264C384AA36FF52BA08FFA3EEE17531915BAABB5C9C04033AA091C36A0C5E99AAF0FA446A945A6FA281750BCBCF8E6666C799A43780B4024B97A6A0B14D9722856838D00890B9A982EBA53F8254072F07EC00748A61CA18B0B516076382A9A52EB19AD329BBB81534DA023CB03E00CB65046615C2D41E24D6E8CA6DA872D46A1181133662735C6E382A615707E3D8AA89D49801F7908262C9BA7F1A49CD3C1CE9A5344F5B3DF38BF82121CC9D4284DA0C662D8B74CA9470051524AD108A2756BAD834A1B1B2F5C01B29D640AD11C70643C0553721504CA90EDD32CB4C693FD451564A1CA80F447378423888B3A2D30022997281AACCB939B0BF2F5643B036596983768758AC6B97DA4843E9D8183633A65E35CC669592BA3A73E0213489FF186CBC66B8FC49FD2916322B30A6F2CC89E42715A8722C672C246822938B32CA6C47F05C21F9DA66FB457206E7B58DDA0A7F28B93CE24CD182B068CB951C5B29CFE1C30EB226A81BC06629133FA0A590DE985E680550DC370108A7519A0B9DA5B06170BC8A647C408477333E63972A7452CAC811EF60CCE2B8AF8CC43B848CDDDD7168B01AB9D138270604671D0CE57D94481EB1361D9A7F1C5906A11CB80F6454A2C358AD27086A5214DBA5C5F69B003D9856831A8C13B9C28C7087EFB8CD7247853B1A9C50B70D5E086A4E48EC77C8C6F4A83A11421BA4B0871692477A6B38F68C004F4BEB011A137813AC02CCFE7B73271262FFF16227DA310AFF06A8D23938444436DA66D7EC6144AB44EDD1322B27179901C3C1703279FC86163F804136A13CC925E47901514DA5F7C68A23B23347D2B78ECB07AB4D81420662633B8A07D686AEA3BB8EDB04DA7D2616EFB147049C45E2A0DEB0C85260862D4D25B47932B54487D6396C7F94193E40483C928460EB6B9B4349E1E4C0BD180111A72246C4BC20377A7059FAFFAEB0F304A1A64398249B1E8626FD1AA24AE11F67A7F23FDCAEB349484", + "sk" : "4284A3F8FB141BDC3C3EB0ABE19B14E1C87CD6B667AAA115C1E4004A122459887FD63B38BAC7421B0C3F4B19CB8AA591E6BB8D54039156627B305638E718C92682C05B56A9005338623A54D1FA92FD8B6630D4C1E0E50CABBBC3D054BA0F03443BC87273602234441CCDBB601D30263F260C567A096FC18FD719BB7E4C6D7113A7E4398D30F793AFC45F484865AEA22BA9119346374438A29C3B068223A4474F8A3C6FD4AC8C009226A346BCB72D61273AE1F65AC87060CFB129D7172BC452A3E8809F6763B0641CB9E1611699CC158C5043B8D4C995CBC438F549A4454BB147CB0AE27B726C1CBC906F4920B91DDC8531FB2AC06274519096C23975404253C6BBC00A816E5A0A20D86ABA4380CFAB92C5DD125156B7642E8552582114BEB7B38A8B1050A42A2123470BB736B68011B809549C4550459B21AC656A301C0EF8723503B29B0D2370B2F4728CFB7EE17A1952A2354216155BB9072BF307F294BDC5760724DC75CCC315EC9BBF60E78CF11C27943289A0519D75B8AABEB895866C061FD02682E5C210A552E8278F8F296F7397A8DA315A83D523BED7B99137078F1010D73C3B53321F0E5B0EBB44252404811CA113F7475F7A9B3CB9229E2E2B13B4F8ABF5FA62AED176FBA02361F24B9FB88D82147B2A299CF084CBB6C812FB2A1BD9B89A2C56A766350123355D3BDA9774527FE9EB9AF2C31B25A66B5DEA238F27281516BAC6E02EC69C8E5C9A9A9A180BBFB7A189B66043BC379CDB58F7C1CEEC0A3EA4E931E854047C95565BF3BDC15098FEE54B992AAC09109197E82BDD28AE36B2C60E259788B53E8EEA988D93BFAE472499181176627E3D823AF9E23870F771FAD75B9938647FF39788A24B6C4A4FFB82399138387C9037B851CE74DC41182323AE935A0798126048C32AAC4D7C7390691427CA53CA52EB65FE85AC44983F80FA7923419ABDF8B14C834611D5908D742E373A7DBA8BA8E3D35EFD6C8FDC1C12E0F7C272A350FBD275D2EB1E0D836A4254C672251C06DC560F7A7EC7C80B8FA59475479F32A258294957D5D979A83CB6FC3C1CE6819F84E45C1E311B0E873F250283EC486323219A97373F5278A52AEA7B88D1C7A43974E0402E58A55E6FC91B08381078F0285F898F4282AC8E5950D09343C7827DF67A74BA1275E070C15EF44FFEB681C42B35C2C1B9C9D82CF07705FDEC10E5F244759699BA6C5A2CA59B76E5AD5B09187A7BC3049389A94B2E25FC295310B30A9B3FB22AB3D9F893D9D696579648A77BCAA6B4213B23C65D4C303BC50AA0493C76C9387D186F85B0CEA44488F0917612244C844450A81ACB15E25AEE3213E5BB647FD46B974BB45CFA21D6E1CC3AF7799B32CAACCA0C80BC61A3F3991D367515276190E061B2CA956655514090B0667673E898A13E9C8573077641ACA677C81EAF09CFE2DC78D0484AF1557ADFC9B32809AA5C6038020166B891920BC577F0064ED0B3112B727F800B22E9EC89BC691C883133A2B43A61C539701062E8512B9D1227E8EAAB2985705418A8DE6029832C2BC7EAC2D5C0AB4AEB9E92324B83424B2A12C04B58681748AAFC566D919862DB6A516934AD61ABBB17024665BA258F7299D7786BA6960A04F79B57C8B4DD8AB3B7E3203F2358221C9CC0F2A671AC1846E59B3D5C95576806B571C64746BD4BD541D4C55128B9A7D5208960A2B74A900A426013F6B48FE7FA1ADCBA5EC1E44594D3850C1A90E2A6BB341210039B48224B97EFC62583F5882C71505A96284CC7CBE9873215697BA688546D3A6F97729B22251F479AB3F92CB08FCC3A9D962A661C6150EC6DFDC7560986BF808B4504EA2D44D595A8C34F4A564147CB798FDB6836CB448CA857D5D08242E233E3826797A4191E53CEE0B375D395CEFAD91A395527ED094DAFF389A198C9D3B28B9E42B002FAB4AEF17B3089885E8017C047C35152A0E2709CCCD7BF4D4A081D3160EBBC3D7A3BA977E221FEA55E01823F2F61BFBEB9388D04103FA0C3330770C5EA5A882B26D14C4266B27722F29863B60C9F6984A5F0C2EE8B6F27385933994D8F9973728C5BE6898012E4766D842CD1D7B360E415286C965B0B5277A5A1C5F731DD085DF0F9579A31B5920227F238C389A723F8C31EA1C45AFCFB6A62E555B0B2B766E78889DBC7A8A174FEC48E328B4411338B26074002261E3C19C575B42F5A09A268B223AEA813706900E785C3A05A98A5708D083C5E6243872AD78F3B456173267D61D57B2F330D01F7BE8CAC65B1CA46D8492F39C83338D92F3EA9A3CC7B502B115D5A7700E5885F264C384AA36FF52BA08FFA3EEE17531915BAABB5C9C04033AA091C36A0C5E99AAF0FA446A945A6FA281750BCBCF8E6666C799A43780B4024B97A6A0B14D9722856838D00890B9A982EBA53F8254072F07EC00748A61CA18B0B516076382A9A52EB19AD329BBB81534DA023CB03E00CB65046615C2D41E24D6E8CA6DA872D46A1181133662735C6E382A615707E3D8AA89D49801F7908262C9BA7F1A49CD3C1CE9A5344F5B3DF38BF82121CC9D4284DA0C662D8B74CA9470051524AD108A2756BAD834A1B1B2F5C01B29D640AD11C70643C0553721504CA90EDD32CB4C693FD451564A1CA80F447378423888B3A2D30022997281AACCB939B0BF2F5643B036596983768758AC6B97DA4843E9D8183633A65E35CC669592BA3A73E0213489FF186CBC66B8FC49FD2916322B30A6F2CC89E42715A8722C672C246822938B32CA6C47F05C21F9DA66FB457206E7B58DDA0A7F28B93CE24CD182B068CB951C5B29CFE1C30EB226A81BC06629133FA0A590DE985E680550DC370108A7519A0B9DA5B06170BC8A647C408477333E63972A7452CAC811EF60CCE2B8AF8CC43B848CDDDD7168B01AB9D138270604671D0CE57D94481EB1361D9A7F1C5906A11CB80F6454A2C358AD27086A5214DBA5C5F69B003D9856831A8C13B9C28C7087EFB8CD7247853B1A9C50B70D5E086A4E48EC77C8C6F4A83A11421BA4B0871692477A6B38F68C004F4BEB011A137813AC02CCFE7B73271262FFF16227DA310AFF06A8D23938444436DA66D7EC6144AB44EDD1322B27179901C3C1703279FC86163F804136A13CC925E47901514DA5F7C68A23B23347D2B78ECB07AB4D81420662633B8A07D686AEA3BB8EDB04DA7D2616EFB147049C45E2A0DEB0C85260862D4D25B47932B54487D6396C7F94193E40483C928460EB6B9B4349E1E4C0BD180111A72246C4BC20377A7059FAFFAEB0F304A1A64398249B1E8626FD1AA24AE11F67A7F23FDCAEB3494842AB47CA9355ECE6CC643C3274C46EFBD6E927B8B4D11AE8F80B5345B487A5C715532C666D12D7F321AA87F8A1F475B161BF3812EFA99269925F5F29B1E030B5D", + "ek" : "CF541E943E2D9237B69C7BC6DC90C6AB5FD851EEEF1D8CFFFDD98AB92C3432C801E0FE5670FEF33585ECFD36D020B0738A2D3F628365E7E2EEA77A45D75ACAA9FD5D4AAC60FE0556B0103920ED65F83674F1A6266D938E797B0FA7271BCCD935F02E76DA06309327B76A8869E916FDA6DA7A1C2C8F9A889F9BBE679830C2A398C95E0052AEF2D21B47E14697EA6A12CD33B4DCFE2597C854017E1E19EA8DB8C899E563A2C6B02D0DFF29900EBC4A19301C3938CB7B1B05280CC38644984B85BE3D05F6A1E1293E7BCA4EBDC63740566691F7AF5F87B30094813131A024C14CCE9FD7867A31292DA173DEC5DA6B05432B78C775ED7FE5E83D371942B65FAFDA2296D321B180B2DFAEB8EF0E282DC161E22F21EE661C0E9C99764753DCB7CB2E81770D3E1CBAE6E9A0700F600E1008675B3D5B96E19034133447B29B2FEBF40867B6B72951AD6D6D2BC4C2784E57085ED6D0619544222BD8D3EEE634DFFE508872F06A564EB7316B29DDBC6D337A66276EC4B4BC0220A79A3813984BD905C7E2E5D3A2BF93C3DC658CD68D556DC9A5C723747C713B02B231D8EC4BFAC4C87C989BCDF29F6C9D0B681D88D28D5D2E2B6C660AEC54B5C408361B8BE10F619448A948A3C41900A4462ABBF8D38C2F7F93853A51DB086ECED4FDD7DD0AB71ED4CAB2EF37C2BDE8DB95B6422EEBCAB486E47131C7CDDCF46DBDA1D7C9F9B4406C1CEC7C3B9B9C7F0939AC854A33D7E4BFC6C6AF2581D9BCA1D8841ACAF39A4131715BED61D1227D5BE72D026E803C1C3F83A2942D465E839784168E3674E0B6444CFFFD961B471EB9448B6632411BEB5A04667E5B6E3CEC88E2379A68863A072A634B116863E9E0643850BB5C79A9EDDAC7E127179EF1CBBA118C834DEDC54733928F836066DC57240D5FEB41980EC9F5D44E8373F5F3F2B40A155A281A41416FB67C97F222C97D84DF931AB5A876A23465EEEF8FBD4A2E28C21017EA8BADAE4BBE88E3269971F94C1168B2F2F50B60A222B8F13EE351110A38F1BB67E0C5FB8950F8DE9C36A32A4F93C9F3051D3F07132FC380716ABB0D8E0034ADCFE50D603F64A70C486AB3791EEE23965D43A1897A80F8EE00B8E2397162E7CDA6B3E9A322002B1F938C67800989A81FB6E6CA354A4702E66E01006C7F2496134CC00968BBF49A28CF035E6400D3E1B9738816152A36D6AC132FE854E821086BBD2448B516005C7722F9B5B650AE87E875293681E15F4FAFCF0213908DCF8244547580084F8A32AF20536B35107E4DA9D7F5B4831360AB7D9934834CD2A8DF2DA3E66FC4CA8651D09950E012E13E408C1AA1810AF7D3E7654C002B0C6C166CBCECC901CD04F04A7E6883024D5536D53CC56B5230BF4EAE0506DCBE4CC06E379F21833C32B910C4FC450F4F178DA5C66DE423816DB92481989B8EB4DACC7EA8CD1F2D8BE3E1F4D2A74CD925EF75FCAA92C0CF94FE0F455A7A4ADEDDE180AC491F0C91CB900E4740214D7623B718BFEAB889BAFEF8DAD483480E607D573639B76F57941983CAB44CBF", + "k" : "8D03129D33F2583F6ED23CE132669E9D64BB6CDB5D19AE8C514C17C9687640EC", +}, +{ + "rngSeed" : "197E5D562DE7E01BED4FC597DB28DC6EFDF0179F3A5BDA5F94CAA39D67BAE730540534D59A7A06C8448F628DA8B7859F", + "pk" : "F784B4D0A3B69A60403F5B9C4AA3808D7B832AB9939B2A5CD15BB36BA710F13C934F0B5DC5F125B4C4604D330608C0C608F14795F690D21AB54BB9A0ED443601F821B3C153DDA33F6B102193A2343BBAC83B938E521676EA2A20BAD2B515C13BDBA9C7EFA9B8B460A8CFD6A54841BB306819B2BA7ADC5B93951653C6D116C86C302E067B358631259012F1D230B892C393652FE9D778E755BB1D8BCB840C51EB93371C2CB377DA1F0A33C13AA4AEC4C9B79F492EBE34906B6777ABA1470787BCE5ECC92F494377555685E32B6D52AFD230464469ADDA074D5A159A54E3493A3364D7443D81449006F0B88669B8F507493DFB67B1F012037438437982C868362C172556989272C8B338B8A56AC0AF290C3BE991C5B552B77A370C026B1C7B4044499036DFF32C06BB4B1B73B66D2644D0709F59050FBDC62B36E7977A7278FDB26798D264241914391C71AE928D5C7C7800FCA963F4A5ECD9AD5B1590BC941909E142BE1C382D7A38B123CC23AA02C9273B5F377D97637091DB6455447574BB0F26A250C63A6AEDF6CE4EF9CC1C86424B226B06DA65158114FDF2BCA1C457F68248FEA0BA9576BDFC380E45781BEF85BFC87ACE9F6B5C6F5805BC3403B9E9A86503396B109D2CA2916E16BC4C7A9C47270B77DB678A724BB9E461E2F3ADCAD69AB78A60CBC52134A7557AFA452EB758D4C357AF310247F2B61DB9C2EDBB126D7284F38829861870BB494FC65B8B16D97CC5C9150D4C4318EC698CC5704F8011B19037232B1E337911565382450A4AFDB8C8E07A7B4127A7D6D630C74098B528AA9CEA5249A6A424536A6003787B7723027BC8DFD07B9519337D5125B8BB631502701AE2BB9C352A3407CB3903A617303A5C29CDCE23C4ED747EB56BAE79084AD705041AD27CC7441DD8D51AC4F5BE1C594019143F41C56CF9B1773EE0CF9F116036AA65896420F82406C1B36009E12433E60993B691BF9295BA6621BEC9060C82BD3D8C75D2014CB774A3EB8C8C7E698069437155DA058AA4A6831C6CD0B47FB425C4F85C5481282107D4B5C61756DD3235BA61A95608404C11546A28C0191C5BF8473135A98C582608BF7C4A1387BCD92B449F888C6B9990A59725EA9C896FC58288C5905BD8AD06A80AC952106D42B298377A0DA30DB7F68DF4119EDF5B45D472C3B11C85CA1439D2EA0F074899C3155A51F26AF1F52265553E2136AE3A69B529767549F146ECC6592A4448918A892AF6A895A27A64480546DB66C42B8A9DD029FCB2BFC14189974531C37405812295E0E85C2C44620BBAC2B5376463A0490F628BA67C7BB7257BCA690CE4FBAE57B717423ABE164A43ECE7B30FC768779C5A82D3265B7A0D012383B1D8A6967A33969A5D368BBF5CA6137959093C9B321539236278043112C8EC819E1D9B532F5C7AD7506AB9C31CF2F4B95F978CF642B67B2995C8F56C272775023A438845CA46A6858B32201CA14F1BC19761452A0A6A2B6AE4BDE620CD8685A89BD02F64EB51D7BB5D29E71F009A79BD060273EBC51A48BFB575AFEBB57215AA0FDBDC0D0AD91120D3799C8843D50068363B5C47B09572623D7AD8071EA1424799C1EAA7165343AF0E808AFCB39F5CC8A7F5E14BD573052725185DBCC71968200BD272D97F676C08E4A6053F4E0A7071D7ABE99607E757", + "sk" : "72A953D60437F6C7A3855582B211C7D6D97DF18C8C53A787117758A3246DDAF89668D5C71E999418E9515A9C95926688BEBC25E0F003496BC0804A66FF68CE3FD1820C5320ED9992A92B8227D5042C72C1C1839D74B790DDD371D477B29230A66526A81A0962A52B5B501075F50086F041924E6889F5F6A6A7C15826A70E3C7268B4F224DEC35A73DA9DB8500DEF40ADA4D7B210513ACC63C753CAB007981BFB876171EA867197AC97716BCB830462E59167616528E840CDD703AB4516B1E307FD5703DA82BDECB0047EC49355A60CE27598D739CF9A493C9C388613B05CDB302AA7D82C0C934B95D602FBC810133A7D5C15639F52CA0BB93B06392CD8223E31A3AF2AA19CF5406F5953705C3A1E649346BA530B2E34618F520382569D8755563802CA6A76164DA8227D904D2E86CF653123C725C0D0B6C799A35A5C517237D405C8D945119A1C573A4B00AC224CC19115C301B8A73CD9FA72FE8366D596A3EB781AAB80895704B8F298571EB3A10FD7B6BCF590BDC4461B6C1522DCBAEE713BFBEACE03B4CE5A8C3D0BB6A3D7E410D0E5640BE91E43A134412313CB170A1EC771C73B91AF1C5A20A2B097F2BE408155D0E3905F1B043F8B888954384ADB7916154F0683619DDCC74086A6981A18F9A51D38E44DD4B7690B37A0694C434F9869140A5F4764C968598462D7289146044118022651C6FF259AAF878C584524EB4ABB65424C0D3649A76C3B2A9168FFD4C44C074D94632D615BB6A8E2A318C6144C949C27F2A7B9F914CF97025677AE31329F5FE484909689873C2987F6BFEA1B4F04FB2AA7880C8E4065CED03EB5FC49DF2BBD38A3AA2295C541C47FACA59145EB864623BAAD417975FB4B5B2B3F7629505393BF590B7B21579E3F7477BE32B2B7A2819FF856395A700353B6EEE92DADD46703CA3BE7B033770744B6216A6AA06FF38CA6F3C21BCA7AC726E7A665B45C46E4B5E0EA5CEF6728F1BB25A2503645B063BE0244A4BB9BBF1562EE76C7C859984C878C2F299E2BB0438E11578301A39C3288D5A4657C88901789438D35A29D0446AF5782D5263CBF13C831B32C4D052F55746F6D555BFFB74EA5D71B136B732F0041BDEA87C3A81C4AF28DB20C3B7D92BD355B340D234FD7A78D0B7057E44C509FD139F7BC84D3A6161295C0438509014C875B2B6B9DA55E222183CC0AB15C8C1751725FF90C5A75608B96C5C18A43A315FA5D5411C5717660B5200FA01459F02171647394CACCB11426C7F535545931550C6A7B7ACB725525AE17EC946C062AD845105072BE4EA32B12B67AA73CCEEF80C8F9D534EC9650131A138745010F96804C8267691824C336C41E2A9169B1AD7DE971F59329E3B6548267C1AE1642C649B8CA704E7DBA94D6A343CE998611745307501C2C90C5EE9795E2EC58BC825F81979BF9821C4A0B00BA2415E6BA54C36778959540E2B9797F925ADC7CB54AB54F5A58C3210CB677AA8BE0D6CD8D354666B70F30E7718FC107A9C3289C0407886678C4DA7ACEC224BB85BE78C23443C24BE09072E03A8CE92AA8323303C09266801A6444FB6267853DF12BB0E4D54E9AF982168C7941E785D1FB9701DB1E46DA1359C53F6C9370E7700E7DBC3E120B4EF784B4D0A3B69A60403F5B9C4AA3808D7B832AB9939B2A5CD15BB36BA710F13C934F0B5DC5F125B4C4604D330608C0C608F14795F690D21AB54BB9A0ED443601F821B3C153DDA33F6B102193A2343BBAC83B938E521676EA2A20BAD2B515C13BDBA9C7EFA9B8B460A8CFD6A54841BB306819B2BA7ADC5B93951653C6D116C86C302E067B358631259012F1D230B892C393652FE9D778E755BB1D8BCB840C51EB93371C2CB377DA1F0A33C13AA4AEC4C9B79F492EBE34906B6777ABA1470787BCE5ECC92F494377555685E32B6D52AFD230464469ADDA074D5A159A54E3493A3364D7443D81449006F0B88669B8F507493DFB67B1F012037438437982C868362C172556989272C8B338B8A56AC0AF290C3BE991C5B552B77A370C026B1C7B4044499036DFF32C06BB4B1B73B66D2644D0709F59050FBDC62B36E7977A7278FDB26798D264241914391C71AE928D5C7C7800FCA963F4A5ECD9AD5B1590BC941909E142BE1C382D7A38B123CC23AA02C9273B5F377D97637091DB6455447574BB0F26A250C63A6AEDF6CE4EF9CC1C86424B226B06DA65158114FDF2BCA1C457F68248FEA0BA9576BDFC380E45781BEF85BFC87ACE9F6B5C6F5805BC3403B9E9A86503396B109D2CA2916E16BC4C7A9C47270B77DB678A724BB9E461E2F3ADCAD69AB78A60CBC52134A7557AFA452EB758D4C357AF310247F2B61DB9C2EDBB126D7284F38829861870BB494FC65B8B16D97CC5C9150D4C4318EC698CC5704F8011B19037232B1E337911565382450A4AFDB8C8E07A7B4127A7D6D630C74098B528AA9CEA5249A6A424536A6003787B7723027BC8DFD07B9519337D5125B8BB631502701AE2BB9C352A3407CB3903A617303A5C29CDCE23C4ED747EB56BAE79084AD705041AD27CC7441DD8D51AC4F5BE1C594019143F41C56CF9B1773EE0CF9F116036AA65896420F82406C1B36009E12433E60993B691BF9295BA6621BEC9060C82BD3D8C75D2014CB774A3EB8C8C7E698069437155DA058AA4A6831C6CD0B47FB425C4F85C5481282107D4B5C61756DD3235BA61A95608404C11546A28C0191C5BF8473135A98C582608BF7C4A1387BCD92B449F888C6B9990A59725EA9C896FC58288C5905BD8AD06A80AC952106D42B298377A0DA30DB7F68DF4119EDF5B45D472C3B11C85CA1439D2EA0F074899C3155A51F26AF1F52265553E2136AE3A69B529767549F146ECC6592A4448918A892AF6A895A27A64480546DB66C42B8A9DD029FCB2BFC14189974531C37405812295E0E85C2C44620BBAC2B5376463A0490F628BA67C7BB7257BCA690CE4FBAE57B717423ABE164A43ECE7B30FC768779C5A82D3265B7A0D012383B1D8A6967A33969A5D368BBF5CA6137959093C9B321539236278043112C8EC819E1D9B532F5C7AD7506AB9C31CF2F4B95F978CF642B67B2995C8F56C272775023A438845CA46A6858B32201CA14F1BC19761452A0A6A2B6AE4BDE620CD8685A89BD02F64EB51D7BB5D29E71F009A79BD060273EBC51A48BFB575AFEBB57215AA0FDBDC0D0AD91120D3799C8843D50068363B5C47B09572623D7AD8071EA1424799C1EAA7165343AF0E808AFCB39F5CC8A7F5E14BD573052725185DBCC71968200BD272D97F676C08E4A6053F4E0A7071D7ABE99607E7573AB27768CE397A94BB7D29F5DAD97D54054915EB66BE41023E5D7052A10ED1E6173DBCD4922B8FA921DC24240B2173C2E65A839357F8E4A93F51E7DAED4C8C00", + "ek" : "496CA817C2ED4FBF60EA84AFA038E16A1BAEEDEB56340C4A5F9885E307E8C74DE03672F8A8C93D9F8051FF4CA35C064E9E595B8CDAADB1307E60920DA9B60757BF6D1AD045DD1C1F99D3C10A2A7FE521C0C1787037ADD79092334538591EFD9D474DC3CDF0813939CC0240B52C598677CD79EF30F23F6C284A0817B73C5C01C7BD20FBB0B87053BE22D74D2D88D209E69AD25AA14BAF83DEB996A7769F5D3ED5365A5269364ACEE8413DA273C42784537DF41EDF915AEE22EEE3A984A78E18390A45AA30B4B8513D37E113B12D292CF9D5BAD4998F4EF8607EC4C524B454563841F00DF32D02C8D0E6E4C3553A2694E07FE507C2E5157614513750B3746A3AD07218C6A523449993293E856D14D1EEB91EF677ADABC92802E6DC5ADFC0F297B591AABA29802F312613E035A220C6857F09E4B1D04EB4163FD30EC06612FBF6C90DBBB4EA4D4E23E2AB49101315BB322BF68E4FAECC4D0E4097E78DCB1215F5189BADF36357FF5E0CA2DA0870F4389298338D0E704F254BEDF9BC4D3379F5668E8B6406F1A849FD47016E83FA00D4464BDA552066DA2B478A9D91E5F1180F64DDB32E5681F79DEEA7DFC925C651E1CF6B9E57F9B8F91663D665AA209E58AF3393417F3264EAF9799BD1A275B73D5B5FF05CAE8023093A338A43B68F745A53A8FF3C51ADFA1D4AB3B8C6C07C35CB23AAB7BCD44C0348AC20B9465562C30D1806A89063ECC0224E74218307377CA3C6CB2EDE61C6AF707F6774320715A8485D497818A8C3F0A50BD5FF242D99ADA817412D58504BFA8808484F1ADD22FF709F07E28AF8C180C59A4FC843F5FE68D76C207D3FEDE1FF54E6E1D15705D4180C0A9A52DD8F6CC97DA931362AF87634DA7761CC383358A81F88B1701A266DBE2BA89B8CBD9CABC0926700C3184C43D7C271262619EA237373410D4B29644EE436D83A2DEA045041751C118212081B3D6D4D41BC4D08B8A5F436D2D5AB609B5E14B6A2524EEC778AE508EF07DF1AEE6BC02A4EE8D5827170FC73D24C198D0DDB43443B3A796286A39485931E885621865F2A280DF8A575724ECC52F846806C9AFD82B92D4B6B1CB0B0771CFCF980F1E547CA3645C1CC4D68CBE49E38AEA51D07C6D0CD215D95380B8750288D30634BD1B97529FA812A471506F31856595C7416119595A5A5BC864B6C737A94DED9F1CE652A34CD7EB5F152AAEA35B3F2F841FC1D1825786C8D7403FCB82F4DCA20FA6769E77563527711407955A599EF7878D312B7173B0501EAE53006D1B8C6DA96EF1F095D5E36961C3E4CA5F6E7CA81FE6A1956F525E01CFC9665803B447F44638AD1409F2F71C24C139E210EF337015E4729B5E0C268CA5949A1D3037F565F7FE811BA15BF7998C22F9130C20D7D26A2E77B9541D0091D65C40457AC0D98C7A8A7AFE3AC7B2AB1520E36C1BEBD2625DB438A43908D7B4B72E5C1C72DAD61CE8E45985100E0F79F2134C73A294C605E7D251F073C8B4FA023F9AB5BE72980A2B5A0E49AFCA02EA4765653B92C41C17F475C85FB2194", + "k" : "740023C48A43D31C31ABC6D0DD6A85B49F645AC924DECB7A86DF4C6458D0B5D4", +}, +{ + "rngSeed" : "F170583CB451D8A45D105457C02C01A33A40350616ED8515BD49067142F61EFB00F07857E4FFF3FE11E7164C648C76ED", + "pk" : "8645BFE5DCA2202CA92A9B07A6B33B49872FF21B1CD901020E4AC369FCA24C00593BE105483A24076CAFFF8220780C9BCC9150B3A65571FB426EC47A82974BB2A6BA13A13551D737E1CA2CFB50103E14269263CAA5B15B16066CA63B867A250318FB7335BABE4FD81A2EF56CE7B5BEB88C65C2BC6C5A75149898A3D8A552CBFA6AF1A463A19A071CB64280DA48F3684D99E0B4ADC7B48D039358F201A7BAA1FFA4AE95FBB0D45776BF76523CD504A379377B740D26069E933748710A63781A23765A6659EB4718DAC557A8553FD5BE04230166782860A3012290B068542DAB126A9F921ABA2B61AFD6958052BAA7B24AC50CBF1F613ABF761D3315692C49184CF3995CEA8F161C86768714AFD1185161B6DA86C73A6B228B953DDE1713108029D7A729811B85AA906F67978239C6B6F9F4A72656B9536B23691B27B3B2316176357C07B671EB562C41621C7552265914C500A21299B17DD258E2A04352B506138187611C19E7D8860741B110C57372A3BE2BE7A3B5A6C688390F06A5CDBAEB6DECE153CE5181C8080E4F879FC063A68739032481C2CEA4611291362165A63EF3C0F436230409C8E5E57C01651471694BB67729919920C6852BD78766A5F5C1B5DB45C84AC14C764549B54D8B2404523B0C00052C5D3538CBC00BFD96B8034206714A645D447DC83844EE82C069F63B59587F53C3CB0047CFE63B4F6EF41513AC5194B91EAB2A5EF4D7BC55E1762E9162F2FA009A9C437D2C93308CA411E8AD7F9C2A642636D5E89F93F5BDEDEB78062032DB389BB6FC77BE489506A98022E83C9AA9B7BF65C561E1A8A95871E4AB1875535981466286175EED087E61EA034C9488FE953106AACB251C7FA044BAFE474C2EB602CDB091687558C02778F4B562692349F9B132FB3A921F75A4EE6C33440AB76FA420BFB339E2F8C225BB85538CC4388522F9628AADE183C1532BAA778FAF937035639A5367CC64C4C036FC25A61B4F85470402E85EBB245A43C92F2CFB0CA69879A0FCCBFF31A35F2B46C986C66386308FAC63978534E5ECCD137561A6B110D82A2328A90636B55B8D67337626115448CA7EDA95A6D2740E33C6CBA56A9F34A95A7BC8F304702E25315F81182E54B2656913939083C052664A9844535301FCB730DFC9C5571BA72F279A0412B98CF64C069B89ACDA010494498F92838E32C711F1712D8B34303B3D594681305B20D2F8AD43FB6598113415460A0326BBCA4C1D658A1462ACA2A619ABCC5A61A99921CA82882E1569C3902769E208C61124E741630FEA09EC58065B889890A667D25BAD039C4846A77D17ACB5E726B5717B00E0B3918FC767205028CC4B67CB29B49196B4DC288A3ABCB112BBA52F0CAE6EF09CFBD74D939B73EE610F0AFA6D8B345D3EE95749CB4373CA3F52F69ECD767893135E7DC4BA6D069C053B79FEA0C69B5C1258609046C761C77322A9D4626DE19DF5543165958A447432D5237F399BB1B9A8923CA45521B21CC4B17D36E724F5A09772A7B8609C9C86140B03E8A10C54ADC91204C686049A643DB89B0C375A359C943D5961A803C6AD28512839F42326F53B22DC20455C843AD64753498E10145AF06270A81213046196D2192D0AE3924F4DBFFA093A9EB51025B31D268A74F44B849A4C408426071FE5E18C3EC8B5C4", + "sk" : "32F2C581D0B288CB18C0512172098F6E200CF9E1ABA837175DA86A45D4B6BD985728F5BF966B284EB96E059A8B4A99C0406046D117640CA029FF7864516CC6D49BA33B640C313569944B07A10B3820C49DDF965187D6794F491734531700571C788243CDF2C620B676657BC6CD9743242B6688D22BAAA432F9015F69A179C01652D6F1C3721B4A35841BCF620552E4100BEB54F494586C73CC5727C7DC023976D20BCC248BF6DA8B6E36878F51177CE3326E9989C95C5219C017F59806DEFC68F466213C131811CA618DF02DF0EA6FA759B095E259243C897A132ACED9661C3C04584BBC4BB218CCC118A91072CB32691432540F73403AF7C09E520537592965483F25394E51A57F2403CC6AC6471CA8633A3C00A049669A3061F82770B7A7CBE4638A8C98B686C499940A004E9C3A7E9C1D41A5081943579620003F738E2D9489D5B24967B6BE64D3984E4C2B69394F99F7062CAA8F9BE60C6FC6C801E77FC2D9B2286674DF0C20414832D4193A024B26448BC33C30405C134D78948C34FBBF5A442636B87BFD3051BED47F86B2083A4198C8B224D1F8C0B0F5769ED72A18027FE4A85D9EBAA57CD20F696193645C9B1E6251B695061A711EB95270F541A730842F56D24981881B5BB071BD15AF02E8641D1A3D0C093D680A7B4283C4D9751ED3C9B5B86C001DA05BF5970F42B86071AA81E4D534BE3B4C92B2B14821A54D9817212CC1364525BFE9CBF9978429C7C1B3A3615AEC75D4651EC85469F3442AE17B929BF8AABDF0539C2B783C30875F29B68CA5AB28579F3D7722126598801368EA9648017A77C7608E1E54C5ED0BC0EC48B1AF037B23665C1E675DE79312637482A9655A5E72C155581B79BC9B8125C5F32248274128A993A6543172A6570C4FFA6E5968239174C6CA9A72A8A793C5FC61362C424B525FE2C23F94AA4D4BD610F1A55E330A6A9B6056AA7605B6623F8962A996E806DE090ADB40CB34CB8D2C024B00940BBDD025BE366D12BB0B78C6B88F4A28F01731DBC7C1026A2C68DA6A5BBBBD1E6A898F36A19610ABB9CB6F04B3881D85BF9300142EC300FFE20B1F33763B816D6DBAC076373A21501495EAAB2FF3B3D0044D03658590A4C73F5486DD055745511BB4D176C5B7CC66FB0FA500B5CF14700640B2679C80DA38762AF61A4442687AF30D5FDC2308C9AF02753AA8A93B294B6E541490AF4C7CFBF60415D9BE34F6B7F73C4B6BB4842B5C608CF90FD8C1BEBA947FD9FBA4EB0513E8D35C8995473AC200051C6063A3022FD6A8DB9C0377F62639982556F8676464C86D856E6A599D031C35A294014A5B30B4AA5BFE779C14B50D4F6A3BEC6318D6312F028B6BBB237F203B4737A9CFDDF252F9B90964C01CB736A832CC337E078C6B66B9733C4F8401B8181926F2C73BFEEA63CF3B843E017F60E35E062219B2E76C9C830AA187BC8A863B58A8AEDC9A9E443C93520B109709089F4B40C8F7966DF7AF854B4718B91D3061A6AA153D7D336DEEAC9CCF0072D6540970741167281EAB315FA2857915144F73F9B508542492706E1D285CA9C58EEA9C3118EBC21C8374C6374CFE7C846E9815007B602AE23E43F68B82811498D2BF5A357C62275609022877E48A8645BFE5DCA2202CA92A9B07A6B33B49872FF21B1CD901020E4AC369FCA24C00593BE105483A24076CAFFF8220780C9BCC9150B3A65571FB426EC47A82974BB2A6BA13A13551D737E1CA2CFB50103E14269263CAA5B15B16066CA63B867A250318FB7335BABE4FD81A2EF56CE7B5BEB88C65C2BC6C5A75149898A3D8A552CBFA6AF1A463A19A071CB64280DA48F3684D99E0B4ADC7B48D039358F201A7BAA1FFA4AE95FBB0D45776BF76523CD504A379377B740D26069E933748710A63781A23765A6659EB4718DAC557A8553FD5BE04230166782860A3012290B068542DAB126A9F921ABA2B61AFD6958052BAA7B24AC50CBF1F613ABF761D3315692C49184CF3995CEA8F161C86768714AFD1185161B6DA86C73A6B228B953DDE1713108029D7A729811B85AA906F67978239C6B6F9F4A72656B9536B23691B27B3B2316176357C07B671EB562C41621C7552265914C500A21299B17DD258E2A04352B506138187611C19E7D8860741B110C57372A3BE2BE7A3B5A6C688390F06A5CDBAEB6DECE153CE5181C8080E4F879FC063A68739032481C2CEA4611291362165A63EF3C0F436230409C8E5E57C01651471694BB67729919920C6852BD78766A5F5C1B5DB45C84AC14C764549B54D8B2404523B0C00052C5D3538CBC00BFD96B8034206714A645D447DC83844EE82C069F63B59587F53C3CB0047CFE63B4F6EF41513AC5194B91EAB2A5EF4D7BC55E1762E9162F2FA009A9C437D2C93308CA411E8AD7F9C2A642636D5E89F93F5BDEDEB78062032DB389BB6FC77BE489506A98022E83C9AA9B7BF65C561E1A8A95871E4AB1875535981466286175EED087E61EA034C9488FE953106AACB251C7FA044BAFE474C2EB602CDB091687558C02778F4B562692349F9B132FB3A921F75A4EE6C33440AB76FA420BFB339E2F8C225BB85538CC4388522F9628AADE183C1532BAA778FAF937035639A5367CC64C4C036FC25A61B4F85470402E85EBB245A43C92F2CFB0CA69879A0FCCBFF31A35F2B46C986C66386308FAC63978534E5ECCD137561A6B110D82A2328A90636B55B8D67337626115448CA7EDA95A6D2740E33C6CBA56A9F34A95A7BC8F304702E25315F81182E54B2656913939083C052664A9844535301FCB730DFC9C5571BA72F279A0412B98CF64C069B89ACDA010494498F92838E32C711F1712D8B34303B3D594681305B20D2F8AD43FB6598113415460A0326BBCA4C1D658A1462ACA2A619ABCC5A61A99921CA82882E1569C3902769E208C61124E741630FEA09EC58065B889890A667D25BAD039C4846A77D17ACB5E726B5717B00E0B3918FC767205028CC4B67CB29B49196B4DC288A3ABCB112BBA52F0CAE6EF09CFBD74D939B73EE610F0AFA6D8B345D3EE95749CB4373CA3F52F69ECD767893135E7DC4BA6D069C053B79FEA0C69B5C1258609046C761C77322A9D4626DE19DF5543165958A447432D5237F399BB1B9A8923CA45521B21CC4B17D36E724F5A09772A7B8609C9C86140B03E8A10C54ADC91204C686049A643DB89B0C375A359C943D5961A803C6AD28512839F42326F53B22DC20455C843AD64753498E10145AF06270A81213046196D2192D0AE3924F4DBFFA093A9EB51025B31D268A74F44B849A4C408426071FE5E18C3EC8B5C44C20AA5A85B2E43C56E051698C75BFC27BB9B1722501A6502D1C0DAC0AA7F1B07E30DD3B9F9D66518A0525F030574C504AB3851B77857B70858C130CA20ECE35", + "ek" : "739C8768D235CF306EDDB4A8AA605C36C916C7BC8376D09B5C9CBFDD57F1339FC2222F0B06AE68F8B110287A3BC2105689F34226D0EEE4F2AE1E7198F52CBF7F5AE0CE73339C7A9E6B37F38A349B1BFF277F80D68224888D9D6202A15375EFA9E465FB3FE94337C04F054A51BACC9839A42465718261629657F553A9DBE5641AE8292F0B72FCDBBC118CE0D4D36F588C30D8062714550A27EBE19D31A3A2C3CCB48A3268AAA6791076CAE8C60E96DD2343E2CA0D4449A016DACACD8DDCCBEBBE1AB565BF9839204B3120A5DC8A608E9EF884B3CABFF1E8BFE2269C58DFBCFB1FEB18DE8E9A166210F8966F45CA7428838F5B7F5DF5E8FBE60143FE7234F404D32DF36904B5BCA92715E67DACF3F98620C624BBE0D467DAE5323AF5F30EB310E08E743AD222BE49A93E4986CDDA0E8DE39CCB678E1255E63D64F3FCDE39427F77FD2CD7B7385A6C382F7B91684782B491698AEE64E066A3D6C333740B649CB550F76B3AAD90FD60FD392D8A1E81078B43E39CE506EB517528465228340EA059B874DDF0B796D3F2F74BC8B6588970EFE66C2F6ED3287EA85140158F30536CA94F7764846ED2383FC8EF65C0C0DBF22B6633255A2E608ED2C26A9BC3ABE281B626BDD40D2E3A6463F69801176097730E14B0137E3FBC8258040E96D5ABAB7D8A1907F5CCF10ECFF434D8A3348C6AA2CBDB90CECCDC26ABB21904A695E817BF0DB1A2866D90F509DF53B918C0555E5C43F05D24814002E694BF39EA8B00DD80FF47393595CFD2EDC1F5962C3AF20FE2A17510D6F81806BB1CB4242E312540845871FFD41D1EFA08650609F222B6E74F2ECF9B8C72C6416AD6D574A9F553D6B709F09539447512F8BC150F7EA6BF9D83C15360873970A5704B6E22D88008C37AC1F0FE6F8F798BACA116D3227543D893111BAD65B2249A852932A1D8515DADB4CB026D8F3FDB58D59E13581BC17318B3F0472748FBAA228AA90C2BE4C8AE4A863A7E5077DF5B789B51C538928F1E31BB33F457C748BE9FA339A0CD647C428089FDB095950FF2BDEF0A16903AA74390383B680F4D8EEF7C34A8F57F4381C0480DA575439D27A630063C6D3D1E976E99D59D32E3906DB5AF333D7C20A0BB485B455F0E16D33156E6A193F068B9C8C15F67B81069C181FF6DB32924E645EB7A3907174F86EE866F245588585FA093BE4E1D14E3BC80F5DACC9C078395AF0829C25FE5636580921956117A0F9F7C1EDF84E075034B391F60A7432FA9FF9CD70BF6AEAF96201BE382E0A89577663655C7F3D9ED4A27077593F6DF05F92751012771B7BAAE6CF59ABA0D3A608332092B90D64CCA9406970CF371C62220F7FC9C26DE157D2B7352D803C70EEB518E3EB822F8C5C187CF78A2796EED7E8604686C6143A6FE714D775A07512AA3FDECF1B51A0E37D235FA40BFC82EB99239E7C1EBDA85060B6969808107ADFBEF980E83695E648DFC623DD62F6E2D957A11F800F13C2E3FA5920499D68F25493261CE252DA4F1B7573F4A29F34E2E9D18276EDDE2E04505C0EE", + "k" : "CAA02CFF46172C371F55430318DC41DCC181E8F70ADB86889205D7EE329350DF", +}, +{ + "rngSeed" : "44A6774B2CAC02DFF210FF861A090561A453DB311F47B6FEDB81811872D5D9489F5FC4103010139AE53FCAED209DC9BE", + "pk" : "38724D9A8308AC6B70D1C87BFEB07775D56703980C9A563040D1BA17297B1F253AFC339DDC11A42CBB051BA2722854CBF45BB80CECAA81AB63CE32ACFE953F9AC8648B95BE8668822060BAFBC10B59E72944185A57F790351A20DE6679328169B954465F8CC028558328F3BAECA98E42404299719D205CB17C745A7784B97C09130E26376778A9330C99ED84288EC3955DF4076D0C9F5847AF05BC58352C1364F34B0213A3CD05B2D79108AF038E457A30BB5626B1DC404605678AC675201C537A8A6AD67A8E3E0B17A0E8632CA1714DD341831B2790591C1F39C530288DC8448527FA542D64192E407F2304747CA7CAD98986C59622B2E63E076420916635A538871ABA5469F36A5536356D176265191FC150A4DC7349F07C932C053EF4B6BD245448BA8173CA0896E51092E06537D2157B0C1624D3A29EB0D055D48A038C858E53C1045C392D6F59408DF2BB19B35A87737EF90B9FDCC380AF6A1EA122838C673E39F502A08908AC33276B4297C712B3C7541C7806C71DC76E9291C89CFAC3A56C9C94852EC4A47BF6642349B95F69C43005FBC927113288CAA2CDD6175B2A627149027E3688B436C336B51C8539CEC3C5537DE5CA6955543F984C73005181E916317262BD638E249CC928E048A20045907B79C441CFEBF0B9106C8847B8088B4C41FE6B7356D7947AE9A9549305C9278E6E3A39060854B88B65CF9A20266218864C94377A475C0822D454AD8FB42C50A13F1BE65DCE1728388A8D4A81B372A1486A86B0E6D1ABD445559DD3B827B834E2AB3744C0C5ABC51BCB7551CC888DE7F590EF780D7CC94225830732F47B6AB4777261944CBB3E6D943EAB827DA40A7B00D8960DB1810D028529449DDE0C00EACBAA321C14249B7113BA43968B79070B9117DBAB36B44F05022BF25A9EC77C7A396415C7F24CE5E364B09A16308472E1D49CE92A41D3B868E4664E93279467745B9E04C39BD67CF0226D198110E6235A3A35AF970A73A3472027E1C7368C867D23CBC1895790F2478F807B756516ACC4C7DAE3A350F26A0353930F4C23C3D982FB90176BC70E0E6B739FB67AADA24D10F2AC30685C2D7606FD6BCE5DF369A0D176FE32B0E0E8CBF583B0E2019167640FA63C23D7223259441152B0C79D9B2012725B6EAC08BA8438CB90309123ABE5980B6CE6889D6B7D1C756AA7A90181A1422F5A6F803B1E772891A61CA657175F7B815CB3549D3EE613DEB001C7BA200730B2771B5743D80EE48683D94015AC7221671A3A711468F8B3BE5ECBC1AF824DFBBACF87972874E847B399280EB649304A3687F43DFD769E13A4964892B5E635C0A2216273331DA5C5B18EC0B406AB1163D4179AF5AAC5FC8273296E2433C8FD993F9340C5D365070CB72715188B52CC0426146C54A3687F6A57F36B0B1DD639C505BEF4C71FADC68D62009BC6B27B3817660DF31FAAD06E86B91AAD252B80461200168290848F963010511763F8614F202A3A05680831B8BDE86A18DD79248D46C144730BC7B4757AC95F34BA2CF0436BDA09CF5A9285E7C924F3B514695300C33CC6D92C280FF81E72B549694AA7AEDB46AFD394A2D5826E657897FC53285905406430C2B7786E64BA44225985F95146947535AAE744A3B3707467701A8BBD99B938F2FC7737F22BCB9F146983A07F", + "sk" : "F8108802536A5E0B192CD8A761C1163C02BF2C457BF4162799884650185CD6E7A978C74516E85541B212B90321A0014615A973226B927046CC24E709E988562964213A874ED5007D8C483336D80B2338313606C716A25D7FC8617A506899187ED9A73D835997DE71904FF82FC4C59B12275677B90FB6C079CA872866483EBE326E33F369006B4341BCCC759B6565816C8BFB3D00E11BFD7B2DE14B9BDF163BBA82852EE76037795DF78B9A2182C883652E17621055397C6B7848B3A8365467669ECB1AB81A8747FA449F22AAD5DB231873BC4C40A45EA265FE45C9F8F43DCDE1AB1573BF0716139549490ACC91AFFC45AA816809D53879678D90132FF321B2C2F32892EA9E4A112258F8236623A701A453FCBA1D26C3AEB37C50B72625887B5CD9EAC2CAE774783ABEBDABA500EB9445739EEE33114852A841447FA19CC360E31C95012227AA11E35412C2B5716D7602CD07A5B48B35DFEA154E6780F8573203D367BC9627F414879251738E3B8CB2E3C09956C798144FD6C9249B214CF25AB84AB0C7D0B03728B7847C485663470C41D59B76FC48F959199305D05117CEA0E04C0C2C056AE740FD21C0CAD76E70F55ED7A62BFD440A2B5601242837CC6205196971A5993DEE6B51F399AE1BA47334985CA1E26245897CE954A7F393105E75CFA25302F17B45E04059803BAE94251D9F51530012BA052CC8948463E48367DCCC5842354E7FD7596122B56B6604FEC0C58DB228A2170CD64A2BE9757D8BE35C1A0975CC1267D789C774883DE06BBD6572129B57A5E185195CF06BD70352574C68A4B71D2EF5580B57166C3746EC058302BA3DA6F916F1BA4B572A82E289593DD57277C0C570C22D1CDAB6AAE39B16A68F5684A5E367C713E649AE802776F6C3488B494CBAB596F73B1908CEB7C05C46304F4E26A54B388B61AA3C663A316314405049C67ACCB2A7AB62140915A09488627B3C3683C3AA198400FB6A53396F978B71189B7C4FB1CA005A79727C5E6D129AF7220705222617807460948B33197EA35A091CE9AB5A2B9437F961B70C432B360BE118A4B589C66AF374F58668E7515B029A14A272AE4AF399552796A4EA3A8D37C265B42E38C2C586792D6BE661C9C4753D373004DA166F69368F976BF1016550013388B562B43A00F801B2A77212237B5CF53C647714218B94343C0B06D3FCBE446514289A3BBAB9A3678284AE46242D1B56BB0845B30817C669CBDDA709576B91072AA38AE0A6CFE444C09239D189CAC861667CD6449C0BA8A773C7106C6B8BB40B100B39A562823D33A180DA2BEC923D1E707D59D7A8E397C68029B93428BCA352495966A79C299E531B9B59B437E86398B72157FA43391299770B7AB37C71B387401B5ED5CE81B88A26A7A9DC023635C932C26199B5C437536AB194074D1CB24F65285AF6B03F6A9A7174A380AD03C6826BA5FB32C6E93C2FE011A0146717E8265B31659A806975BD589F7630461BD1B6C51A0A2CB6AD3F825C919533C24C807A9C6E3C780D0E333105B43044D7931920621874395F794483820AFB55483E34ABF3F0440F3253FC702E71E34270D38E4875CB9A6090DBBC53352128C18A948EE821E49BC9C690563A92728B610A38724D9A8308AC6B70D1C87BFEB07775D56703980C9A563040D1BA17297B1F253AFC339DDC11A42CBB051BA2722854CBF45BB80CECAA81AB63CE32ACFE953F9AC8648B95BE8668822060BAFBC10B59E72944185A57F790351A20DE6679328169B954465F8CC028558328F3BAECA98E42404299719D205CB17C745A7784B97C09130E26376778A9330C99ED84288EC3955DF4076D0C9F5847AF05BC58352C1364F34B0213A3CD05B2D79108AF038E457A30BB5626B1DC404605678AC675201C537A8A6AD67A8E3E0B17A0E8632CA1714DD341831B2790591C1F39C530288DC8448527FA542D64192E407F2304747CA7CAD98986C59622B2E63E076420916635A538871ABA5469F36A5536356D176265191FC150A4DC7349F07C932C053EF4B6BD245448BA8173CA0896E51092E06537D2157B0C1624D3A29EB0D055D48A038C858E53C1045C392D6F59408DF2BB19B35A87737EF90B9FDCC380AF6A1EA122838C673E39F502A08908AC33276B4297C712B3C7541C7806C71DC76E9291C89CFAC3A56C9C94852EC4A47BF6642349B95F69C43005FBC927113288CAA2CDD6175B2A627149027E3688B436C336B51C8539CEC3C5537DE5CA6955543F984C73005181E916317262BD638E249CC928E048A20045907B79C441CFEBF0B9106C8847B8088B4C41FE6B7356D7947AE9A9549305C9278E6E3A39060854B88B65CF9A20266218864C94377A475C0822D454AD8FB42C50A13F1BE65DCE1728388A8D4A81B372A1486A86B0E6D1ABD445559DD3B827B834E2AB3744C0C5ABC51BCB7551CC888DE7F590EF780D7CC94225830732F47B6AB4777261944CBB3E6D943EAB827DA40A7B00D8960DB1810D028529449DDE0C00EACBAA321C14249B7113BA43968B79070B9117DBAB36B44F05022BF25A9EC77C7A396415C7F24CE5E364B09A16308472E1D49CE92A41D3B868E4664E93279467745B9E04C39BD67CF0226D198110E6235A3A35AF970A73A3472027E1C7368C867D23CBC1895790F2478F807B756516ACC4C7DAE3A350F26A0353930F4C23C3D982FB90176BC70E0E6B739FB67AADA24D10F2AC30685C2D7606FD6BCE5DF369A0D176FE32B0E0E8CBF583B0E2019167640FA63C23D7223259441152B0C79D9B2012725B6EAC08BA8438CB90309123ABE5980B6CE6889D6B7D1C756AA7A90181A1422F5A6F803B1E772891A61CA657175F7B815CB3549D3EE613DEB001C7BA200730B2771B5743D80EE48683D94015AC7221671A3A711468F8B3BE5ECBC1AF824DFBBACF87972874E847B399280EB649304A3687F43DFD769E13A4964892B5E635C0A2216273331DA5C5B18EC0B406AB1163D4179AF5AAC5FC8273296E2433C8FD993F9340C5D365070CB72715188B52CC0426146C54A3687F6A57F36B0B1DD639C505BEF4C71FADC68D62009BC6B27B3817660DF31FAAD06E86B91AAD252B80461200168290848F963010511763F8614F202A3A05680831B8BDE86A18DD79248D46C144730BC7B4757AC95F34BA2CF0436BDA09CF5A9285E7C924F3B514695300C33CC6D92C280FF81E72B549694AA7AEDB46AFD394A2D5826E657897FC53285905406430C2B7786E64BA44225985F95146947535AAE744A3B3707467701A8BBD99B938F2FC7737F22BCB9F146983A07F72C30933B8E50425FEFBF58D711F58CBF9FD8EBD2835A1B55469A2A1B993EACE05913FFC8D7FB91C97DC1E0BEA9DC9955FA28B3CC0B7415C192F81912D70516A", + "ek" : "E6B773DBD57AB1AB31E0C9743D6323388663F2DE816BFDC93E5BACD436EE1F68F5746A66D0923B850A3D950076A14EAACA189D30ABD0FB87E256DB53C3CFC92444B38C773C772AA17BD3469415A53ACE1465E95D1E6B57D22BE906B1BB47DC8B38EB661B12189C3D24F80B50571C2FB1FD8C1AD886B406D6F548FA2CFC94F156FD4B76916A30E3C3BD2C0299D375DC7641CF9BAB77A9914BC09A87DDBE821FAEA8E61CDCBCFFEA4D74910EA163B8044DD1189DBF7D74E4F0B6610696BDC530B9F76F4A21E5E7BEFCF0B09E3476B8F24E7BF39CCFE560C773A5E875413EDFA45064FEE9C2E2C47FFF6C3EB19AD397DFA0CF804FD70046544415641836732585C999757ED26ED2056A4DB5E7429A2AB250AEC46FEC85A2910302ACFF8133F26379D0D71C82C57511B743CA2B8AD93EAEF480FF6BD49D16B0AF39B961100CED445AFF1A9FCFD0B4490463B291E612A836029F4BE74E81029617903778164F39A1ACA6295DDF9C5C8F66378DA7C155189EFDA8A0EBD07C9C3373B50FCDF4307C5DB639D997E57F84E04630B106DEFC6089BA6DAAF063F341659C4C12AD36D64BEC0A99E2547A1F43E8DF9E77FC586A38093C4E64135122CA58E3988A01DBED9AA97A4D3D20222FBC2540D39868FFBD911411DADDA852B507D0B855D0A4C304B7694FE58EF8EE5B84B1E9797BF5BC7049386895F1FC204F805ACEBE6D58F47139322CCA69C6C130D91276FAF1B4D6E91E541A7B81525764B9840CCD862C158E23D3B3D8CF48A2BBAB1448513E04EFE3791BFF404E6B2B99EC9E1387A782F64ECB468FDE8086B0CB70EE4D155D47990C667FBC88E84C5D8A15558B31F636FB2BD829465D730571980E7CDB508F1C653C49B031B9A2C6207F72B990A00D4B018CDBB181E80F20F8B48B1B41702B2A33D087FB1E965D28FB852C8B09F7568B4330734E4BFAED87F7D5191F054F1EC62862443A306EC292DA477439000CE20475D8C29C40045AD8B1275CA9644F3F5134483AB005864C8E0D26B19A68EE7532D9A83BE4775A2D7E9CD2C0CE3648AFE6A1869931DD2A28032F5CAADEA7F4F19729F9F62AD29015BFC97A7536A3FDB08F58376382CF1EF3AC405929F4F4D8D0B09DD18EC7909C8B1A6CE35C7992D8C2DA4D0902B55539607DB90082614BB6E7EA9DB38EDACC04629C43D1AA0CB8ED2CD676D50AA95E586588C2722CE25CDE439DA416E9308AAD50EBC900F5459B88115EC053E2288D6F5B3FCED19E6F4085F14B8F0B4C0A2433945664EFD2B967F5A9E149BFBAE2DC736134AFAE13E627F984FEC4695DD18C32F1CC5BAECC4CC66491143F95F7D2DF5C5D61F3BBF577AD1429D259CEE638B270947F7856807228EBE288382C45A42F43EEF4F316E87DD843DB7DC5CB929840F9B4167BE0C4FAC426E45C8CB0C64089E7BB367363D57D115A7E335A9D617A0032E128A425622FD11A8CA8F3911E273566A0D1F295B4F1F1FFAAC16A656F3EF38CCBD281DC07F63B701E9CC191F60EC19FEE06FEE0764ABB9E36AC5E63EA3B9E", + "k" : "0EB234288C73E4AAE83464B298017780E9448B1801FA2CA9401C269C3E08EAE5", +}, +{ + "rngSeed" : "49E1855588B6235DF2A400C4A70AEDF8AB17B6E5E2891AA745F132FA2E7AB0C8117C1DF37C39F5D57624EB77C2B4A091", + "pk" : "BE19BE36C8CCDA4C9852A442D4259905628087C232F28871B05512DCD2B769179AD09A9313252DCA243D73B387B279A1CA1151FDA2781AB7757D2CA5C64052C8440BDD93ACB5152203987BD5A693453957504242B3F8667D3C800E9A969372A13FD014715A0BFF3A24C8F31A69C329A1C30EF37CA29903CE0943982413B0BA694ED53CB416F125151C8F036709AA2174EC365A56D608A2B54EC71183E2B4258E71ADC09C81FE05065BE2BD972979EEF093CDA03BBB82B6EE4180731C18FA997195D4917476427D7C07D99B663C4B50A9CBCCB3C364DF354685273B8B42B9E118A427C765B08036350A330BE79B3EF4171B953FAEE56F719483717854B29AA3385545D3C9CD71B0A070AA2734F8327C095AFF6B342584A570371EE7CA3F6A2A2BBDA60C4E3AA264078B6C9BB206781F229B9A5CC2BBA0C8933D01B469B4C687F5A1749513BFA3401CF1443EC0558C89C58CB795E3686640F6350420BED4B839EBC8106FF7043107C590C0BFB753C0AA2305E4920D1F639C3ED400A2836D3B638051B58EA9580390AB57DD7138421709759B89AAB4279C5A9768CABFC44CA6A2F1CF5C039E2B0563A9048931F1565D164C13AB60E4C92AC843451CB75662CA03C47A652445B7EF0B8E622187387059A614CB08796D34758133050161743677594D51D02F290B3CD7F23D4CBA1A64377BAA36082249AD896990D79AA040A7858F1B3DFCB43ADF040F1B245D216B2E23420E0B9613E9DB6C7535063D05079C739F70759F7DE0291537AAF5D6B3F4B6291C147855EA9A79ECB0AD80714520971011365DCA81AB5BC0D9D70ADE36A125AB2295858B79370FE21932504B9D583C787BF28762241A279663BAA450172651F126BB20B85349B6344AD404E3093369569148A2A8CB7B7E08E68FDA3408349B4761A171B0C2C85B37227CFA3D7C16A3950298C100955402919D14A71E7B231D60AC11E81A46515CF2F25FDE507C0DF59B352187AF7059F3620026C84469610D0098895A3330F7638082D5B5A925AFCA637A1D160ECD2C83FC522A3BF40591FA5ECFBAA0A3B1859FC58B1D157C18B71D540B6AA398179BD65DC00866275CB0473964FFE5A8C638BF57304D32E24007B3C61429881CCB1A0403566BF3C46D8A19E852AAC6F58D4AE32F45CC7B0F5181F18675920680C2C0BA8ED283FDF20C383BC08CCB7D46EB85204126BE034374769CAF39AE633924BC8BA6B7B89DAF72AC4A86BF86008C02FA0FB18A5DE6F8952EDA2526FB1D994B4165149ED11B578359A7B9D0BDD7257A2D00B676268A38528FE34140EB408ED5B916C0C43D79AC29B0946702341CD7C20EE23C16A6B2CFD1F9107872B8965952A9A45E0E435C56695C819B71B9A6B6796553271C029D06CDB0308112A89AB4B714566A4B18D03C18D223FB6427C7B3144E64874C26A8CA418CD6F14E4CEC2A0402698AA1AF6EF63264806E4B42AD3DEA298A404C1EC260935166418068EDB71ABEC21040F9B3EFF4389358B7CCE70461EC8C0AE8873A45504E8688E266787421343699089FC31F84EC95A9F2264EB3CEDA71261CA791D052A43808BA1F4706717A10FC4AC21B625FD324CD86AB8B3DC254DA31BAC0F9106028258ADCA5F754B309A6C7DD30E11B8701EF37E8715F03C0D8A32E9FA39D37E7637BA00940", + "sk" : "257C04EC995FB9757415BAC737300B03C991BC8A5C4BE86CB0458F66A551CEA67FDE748C88113C07F09E2EA03EFC14328381B21220741C12C1CDF9A81D3A28E9B7B4BCC88D0F38A700DAB5BEEC59D6073AD85697D14728603B1190A81151061F3159293CB2096C093D72F33B1957CCCF7085AB031F0E404B1C1BBD06831A9574B90DB6025FCA778D68151EDC4BFCC11292F240D9E6226739036CF000DCD1B275D12316E605C72A2FCCC55887220EC958412493C8AA4759DD0848EA0271C55BBBBD178642331E8C910A932A5A8D0A3479153A480C9B0AC58B10334C6B186B38526546EB31A0186E622520B2B60DCD00345222948CC833170427A301A26E920CCC6A71B979B7F8A02F86E983F1EB1B2ACA4202100260A94B847CCEDD8101E1B16041F96D72B8CEC772C08BF5A75C5190F78B123E943E1693169EB726771A7C2826351B5A05A803134C24B72DEB2A6F282B94689EE47BB47102926849821981322A03915086670896152A022036351A046BBB6D178BC7605F92254CB8AB2E24544650DA4E29FC0AE9ABBF0B2296D6BC7E99B4C1F9D50FE7FC7A130432BF98B28E142CB1924EFE5324BDD2887A9A7B6A1C18DCE15B5B127F17B5739B5C5E33E63FB2494FE403CBF9C2059618AB6FEA5B1D78C4D0438FE94C447A4A2E42D974A44890DB571DDFC288528B683A363A93A56EB6C9B1DA246F64F0B0D3D6C38B4975F6AC2ADB2C62A9D208812C0365F3A2AA39AC575595FDDAAE5EF5C7F7FA49D8B209784AA25C7166C92759F58421EB203A1E8291604C84D24565DC68CA7B183F78FB5A6869115BC7B7B1B33BF4E4AFDAC9AF6DC0604070300F7273223AAB0FD85401B923D6C6180C815853994AC22BC45E5B7961A176811780AF4B0BD84A490A0A3CE1062204C535C9932BE4137A7B6A1FF75579E72B75ECCB806B67419119721FD03E59713920949E8F6B5BB278B7DFD40F1125ACE9336B5BD5B46F5952D4FA0B780A875B87BBB8BA2096D940555C69E45602975B1324875E891C6C326539052C811FFC4417BC61205B430B522A1A7B4DF509A4E2C9BB5A595333F29B986C113F57A9E0D91AF791C8096C0330CB59C27B3B29C15B13128B86336CB0C270DBD80D451B08CFE35876594AC4011B621792458042E8906DEBA57AB57B9565344E2AF27D87A68108A8487A817AB5C779683CB81B7BB258E598047505EE98C7D666766110256EAC0694B3565B07124786966CA81F1EA5A8BE616544D54F03C5BEC6D81B392A723BB1176D94C75B47CD8A00AAA7836E1774824289803DF38C0F6C74B4C42660D1B27E5036C647BF4089B3BE19A76DD8CA518307CA92B3303253DBD9765BD26635F3BCA865C215723C20358F2B4C487B008A7F0221359889DBAC532DEB2B38EC8F35A4A6AF306597F09E1F84B808140DC31A36B1DB11B13C23EDC79AE5F1861DBC4EBA427A62B153F721A543224CAF3C54E15467057CBDA9B1AE41FAC0CA7658A542A87060A960D57F839712AA497F0EE03A9122315409279CC89FC6F5AFAF72497F99CA8F3A18DA1B7221321C87713BD484612204783117AA4F2219A9019C251C8F92D8BDB946B42068207AC04E0EA116A9D2CEBB25391415630DB5300BF51BBE19BE36C8CCDA4C9852A442D4259905628087C232F28871B05512DCD2B769179AD09A9313252DCA243D73B387B279A1CA1151FDA2781AB7757D2CA5C64052C8440BDD93ACB5152203987BD5A693453957504242B3F8667D3C800E9A969372A13FD014715A0BFF3A24C8F31A69C329A1C30EF37CA29903CE0943982413B0BA694ED53CB416F125151C8F036709AA2174EC365A56D608A2B54EC71183E2B4258E71ADC09C81FE05065BE2BD972979EEF093CDA03BBB82B6EE4180731C18FA997195D4917476427D7C07D99B663C4B50A9CBCCB3C364DF354685273B8B42B9E118A427C765B08036350A330BE79B3EF4171B953FAEE56F719483717854B29AA3385545D3C9CD71B0A070AA2734F8327C095AFF6B342584A570371EE7CA3F6A2A2BBDA60C4E3AA264078B6C9BB206781F229B9A5CC2BBA0C8933D01B469B4C687F5A1749513BFA3401CF1443EC0558C89C58CB795E3686640F6350420BED4B839EBC8106FF7043107C590C0BFB753C0AA2305E4920D1F639C3ED400A2836D3B638051B58EA9580390AB57DD7138421709759B89AAB4279C5A9768CABFC44CA6A2F1CF5C039E2B0563A9048931F1565D164C13AB60E4C92AC843451CB75662CA03C47A652445B7EF0B8E622187387059A614CB08796D34758133050161743677594D51D02F290B3CD7F23D4CBA1A64377BAA36082249AD896990D79AA040A7858F1B3DFCB43ADF040F1B245D216B2E23420E0B9613E9DB6C7535063D05079C739F70759F7DE0291537AAF5D6B3F4B6291C147855EA9A79ECB0AD80714520971011365DCA81AB5BC0D9D70ADE36A125AB2295858B79370FE21932504B9D583C787BF28762241A279663BAA450172651F126BB20B85349B6344AD404E3093369569148A2A8CB7B7E08E68FDA3408349B4761A171B0C2C85B37227CFA3D7C16A3950298C100955402919D14A71E7B231D60AC11E81A46515CF2F25FDE507C0DF59B352187AF7059F3620026C84469610D0098895A3330F7638082D5B5A925AFCA637A1D160ECD2C83FC522A3BF40591FA5ECFBAA0A3B1859FC58B1D157C18B71D540B6AA398179BD65DC00866275CB0473964FFE5A8C638BF57304D32E24007B3C61429881CCB1A0403566BF3C46D8A19E852AAC6F58D4AE32F45CC7B0F5181F18675920680C2C0BA8ED283FDF20C383BC08CCB7D46EB85204126BE034374769CAF39AE633924BC8BA6B7B89DAF72AC4A86BF86008C02FA0FB18A5DE6F8952EDA2526FB1D994B4165149ED11B578359A7B9D0BDD7257A2D00B676268A38528FE34140EB408ED5B916C0C43D79AC29B0946702341CD7C20EE23C16A6B2CFD1F9107872B8965952A9A45E0E435C56695C819B71B9A6B6796553271C029D06CDB0308112A89AB4B714566A4B18D03C18D223FB6427C7B3144E64874C26A8CA418CD6F14E4CEC2A0402698AA1AF6EF63264806E4B42AD3DEA298A404C1EC260935166418068EDB71ABEC21040F9B3EFF4389358B7CCE70461EC8C0AE8873A45504E8688E266787421343699089FC31F84EC95A9F2264EB3CEDA71261CA791D052A43808BA1F4706717A10FC4AC21B625FD324CD86AB8B3DC254DA31BAC0F9106028258ADCA5F754B309A6C7DD30E11B8701EF37E8715F03C0D8A32E9FA39D37E7637BA00940BCE58A5D05A4840F835B8CE39703F77BB31F20B9EE4FD3795C2E326244208B2897C65A12D87432F475509F11E0884FB51B5D970C1B6D2C87C70590CF41C16B4F", + "ek" : "3CE41ADEF24C782CCF087A126284418B4EF6270888451FC9428F41E7464C2DA402B833F38EF190C3E49F3C57137107C3F0BF42DF184E090E32166B083CFC84DDF8DBDE85E06267713333127676D30361BE67155676D44906BE280ABC4E572832BCAE420BC51EE58AEBFD8F2CF813FB8E0EA9C6DAE33D72D82A7CA0AEB26763FC38C3BE9316F1C86994449ABD92FAC723EB83F276F62A980279A88416BFCAE0E6F2DC52F129131899370AE0087D78FF3A1A9213BA4CD2F2D9B1D986DCF09C8649149B225F64FC11F069F2D0D6E1BCF445D52A980C1E9FD24A2B1A6A0D88158FAF0D6F0EE69F824DCEF02A6D5ED96153E87F7D0314900D44D84FB8D2AFD90A38BF451B6B45CBBB406617348EBBA80184A7D4CA38E10193F6DB2197E9DA82E7939BFB75D01D162B70740A90EC90448CF78BC0787568AB00CC74BF32EC0CBADF13EC01D4B241A08A97F4DADAD28ED123A0FFF483F30A967C910BD00C2DA85C2D0AAA2701D01B1B8164EAF2E798826D48CCD436AD19DC3242CAEDF26447381BE5E68B2BE3049F782DA1FA6C8542A3BFB1B295DA3C9C4C9ED1F603557B30B4FB9378B7AD46695025E16B49AA72F98E34ECF023590F4E6479C30FF2BBB1D6FF4ED53FCCC2F4F34169D749A148A98270DF4B9C2A105B402B824ABACFEAFDA873A1D00E0DCE0E634C9BC5AE6715E78AC81E9D5B3EF0F612A5C9181BD73F1EC08684A2EED292F843361444A5800E37E659BC29F7E1EC8D4F1EFB474BF233EEB4E97C3712610AE202F12506EFDB951C0DAABC07D6BE255FECF474F89D044488BEE86F572CC4EDCC2D77B485870A7540D5A72BEE091F9776428EA752357EC7E4F575AEF6652C59AE48A2DAA91875929AB8544DCA27F12B886906414011CD7E7ABFA5ACE167AF6CE4923E33DEA2F3CFFA6DCA785A1BB811856A0F7723DF273EA405595BB0C7CBD0B87D255809D7CB2467759C82693D35CDF1756B3E7A284CAE3A8CF8C7CC148B0547D400AEFDCE82CDD353D763EBE91DA2C572C4145C48208E2A341BFECA351D56696EB54F10019BE83E35A238CCEA29DAB54BBF6DF555A41BD0BFF035460A89488F9A339D461F1F3CD6D6F8EA776752503005679B9FA2D10AA163BC369C8F5A3D21450E0599047FCD1CD19AB247A9B8DB541369630CE2F3478176F26D1C050F3CC5C43FA5F26D375F3C6AE0F9637949A66ACBA69AC31A499A59916D74182A93F6073E12E99B61FC9FF52FE502EC01F5ED1DBC6E77E4F1D18A707BF6590DDA4BFB9E3968AA4998DBBFF71BB68F475BD129713BE8C31B0A503AACC8619DB1076A13B692A3488AB9030AD36C5C5CBBC645190262D40B95BAE7A5B4F65065D3154A3369E2F5462FDCAFD655A7A6EE2ACD5535952718E7ED9BC8CB5256A5E2734F16A047A1D96F24DC5048927526625302911350CC7F0EA3D3F89D7AED862241627DCBBF4342B4E6CD8307C534F04AFE40D78A202AB6DEBB1708670E648A2129E451921B24A15506B2822F8FCADDC4C4DE65964859178F8F38D5DB638A7F0D5AF201", + "k" : "50DEFC93E0D5F8A1F8DCB3488BBE2060CB4B60513537E3DC464AD0674900BBDF", +}, +{ + "rngSeed" : "DF0E41D2F6F86C1F79D31FD5878E7AB434FC0AF3A0D5F47D2AB3FEF31A42BD949B0E3629DF9F575BEFBB62E829E51DAE", + "pk" : "8AFA99DB2599004DA53EA126E94C903605AEE44B3D56ABAB69438320C91918ABBB1EA2B6953753E475BC33C159C590BED80760731565279C640D361DE46AAE78D0A837912C66C5A347C0946F6943866750C6AC1EEE713CB8636E543B2F8A08857D53834233603391417A23C88B6003246A0C8FF39EDFC7AB8759207DCB7C1D923AD891C31EF564E5F53C0447A25728C934303BEC26875C44A26AA36E0324CA6423855BF2CA04E27CB8F42329A3A0E28A7285658FE1748A58C538DDB710C6D7839B573B30A5C4486A448DC0BAB7C07B86279058578D4A56C781752E8AB270914534C51923A6D0C226967313695987314975DC7C7A101578F326D02A086513B2608A8B58EA5A63F2C6A1CBBDC847C312F5A2309C1749C349101A42757073224B0ACA598A6A72CB308A010C327AFAC94798F8B4C6A1279389C12D1C3015B02E37A95705D3B2B8277C2C141BC8148C94244EC5C50E65790FD6E0842185A5F2AC1E72A21D4D652A63001C650B6C8D06CD758923D42479CBA96D7EB396803C77BE54C831063707A35067B87B2876A1A0844D11E1A895DB70D596871FD1434798771B487AED562EE1D041C06505786205166812FA718424708A207CB4A6C25EE78B8B85E869BB82A89F647A813B97DC1ABFB22B430D37ADCB43B7BB1616DAE73B0D606940E5AF7D139F73B48B4618BFD5C22274D3A27C20195794344EAC73B9A09DE5CC4E59A2853A412EED7062DAD16B0E1AAEEF83221D34B3225868DA033822248E5E40A692C20AE4CB112B9C4F9E373D6DC3393F385B5F65C7F14B66D7D0B31DD7902AF39812D76D5CE73EBFA4C392B069BE694BBFCC7B9C0825D158B431898C9CC9080D632196378049A5A02B43CF83D37E4A731505F23009661070038917A93C452004A8023B1DA44B4E5CC53ADCAEA033C8759A3BB4BB52761191D76C95599A9DC2A2292BF37AA3803278726B660233E9B476748A31F9FB9F2D93B59B9CAB33356782A976E05B083716262278349FB14B806A7CD3E52C1A6A6F603468C4B420CD544BFA916D157A21D15C1945B31F7C6285C30529DDF735350C92C546CA776CB44360CD62F05620F8B23B94A0A720270F122B0F22316050B7CF6623CC0658A9146861785C03FC4E0833C3565CA4EBC951F5145E2E434555D45C3819CCC4C2546673C18D70AF49F0AEACEB83041556D52754C10B1D66B9C0519985E9B0AED559074743C8796881E5A189A4707B8923097669B2D9A162DCDA33C3B825E004AA20B1749EB198299476BF45A519D341E9B507B1E411BD5382A6A84B6DC9C1BB437E98546074076EA76654CA6519F7A71D1F39C5328B16A5B182BED6B57AE058C3201554D612628274BFF57755022B7E653DBB461958CA3EEFA117B57299245A9917158F2409384A7B234AB390152B01D1383AAD99747258C61BD24F7B12A0332C6D7B5ACE324B4E1DD9B3F8574B17382BF387155F0ABAF4FC8830B7774275821E91A939DA83C9C189EC08774C739FFF041D40D512B171C2D0EC7E404349BF5A64A876AAAF72C9C16A004578842BFBB6FF221DEBDB6FFC8A6DE429CA0D7AA50071BC8D68C23C379364E56E4AC247A99523F8D90B3DE4B049B526F8961621B98DC534B9A756AA9C4A1B2B4C7726E701BA03D885A39D59A76D92BBA31013F2A4714EA384", + "sk" : "8B814F850315F33901F955A7DCD2971BB73D44DB90B874804457124002BA681347B4DC33910BA22A903F480859275523598A1FF7CB818F8CBA2ED0668EDC45F1997F3E76628767B63890C35D334F209B62A208700820C7A41689A4C81208B05573361DD30642BAEA86F25BBC87D1157F05368582AAC0958E87FC84C431BB2EDA3C479A9CF0984A90E668427046F2946E50A43E3889AAB5D649B5A17242AA6D6350A1B72B971A748CD2A0A6CABABD4F77B6FE905EF270BF222C1B5C2683165B9C87458F849405ACA37DC8E99699128EBC6317274993D74C77CEE907E536B1A1871D1F8A3505670CDAB00080DB31CD0BA9269C84D9EA565D194E22D3C11573685B166F02245EFDE45F04CA2D851AAACF47C711A536AA1855B7693161F27E51EB52CBC1B6322537868386715B16C4802D2FB43E9EE7C28C51A5FBBC1FDDF670E02CC3E24BCF75389651268E4C78949E284FE9A2A0FD3428875C7D4BA669E1F7116EAC952640B9966626A867348022709CB54B05704C136B5538AC7C6E018107A27B1040211562CB1183714A2C9A634A8BD547965FA04FB62441CF7601393293F669420DD0A04D18AF0C0249A3B57E0905758B7073DB3C80E2634366285A86D6AA7FA8561FD4A6ED745AA04872FA7BA732C514BF045445CC4455ACCC40E499F71A2D3A8AC73BE9404F3736908745B1C40985E4920EDBAA2BB8933053124C4C300F7302FA634E6C6830B3671FEA4965D58AA5C653682E88BA5AB34361409F4C1656F1772643F71134BA1B1471192DE503F97868E43A4D4E9A2BB2EC38ECFA1835F24B3FF1B850FB5F4DE32F196377503C25CA0989703B72D72494A2217276C9A15B600BD4DC76585774B2512DA602553807AEFFC5C6E8F0187BF5613D35857E7B4A1A4B805946224B4A8989C0BD4FD445CF64910194AE3AC96CD0E22144B9AC51FAB7EF671B6AF68D7F5C2A3B48B82FB2CB49722CB5B668AD021240871307B185B6426451588626850080D68A917B2FC3720DFB33C365934EF37BB5E7359A6008AD72D255B4E921C6B1926B917CC00C03A286B8489A53B5A7429E1CBFC42507F33BBB5CE082B58CC550E03A41B9CCA243506DE21F3946019DC87683B35CACA42FE8272861B4633044773E5C399F8C6423922D05C528AF950B6F6B0445D98C5243C932451303222E8A8A55039B34C2BC643582871236553F96B80C9041400682F05C6795B64160006359270C4526BACA74B515B224AB234A6B127C4612ACBF82BD540226927675F5423CCE59034F4596276647C6C8C3D53B54014B6596FCCEB0C29609B50E1D599BC728A41DB0C3E2A6C41EBC956FEC70D2B58866C3C2665AB98B153052D917EBD9BA3ED037F62C8299A02F575742D7102FDACCCE7759763AD2147DF656AD878CEB1B7AD5B4CD3EE0A2320727A1051D74F84477AB5C2463CCE42295F656978B470708A4A26F21949635A957E12BBCC9C8C83753CCD6781474B067099425C705D78631E69632DC5909DEAC940398B8A6918E2F69587A5992B354B54B7931D0B4C0EEF60C61B46170699035EA014778A28D8A224196BEFFE96C06303E5F8BA659D0229DF3B5FF445CC7019E8B54B4F4346C7107B651D0277D8A195C59AE8AFA99DB2599004DA53EA126E94C903605AEE44B3D56ABAB69438320C91918ABBB1EA2B6953753E475BC33C159C590BED80760731565279C640D361DE46AAE78D0A837912C66C5A347C0946F6943866750C6AC1EEE713CB8636E543B2F8A08857D53834233603391417A23C88B6003246A0C8FF39EDFC7AB8759207DCB7C1D923AD891C31EF564E5F53C0447A25728C934303BEC26875C44A26AA36E0324CA6423855BF2CA04E27CB8F42329A3A0E28A7285658FE1748A58C538DDB710C6D7839B573B30A5C4486A448DC0BAB7C07B86279058578D4A56C781752E8AB270914534C51923A6D0C226967313695987314975DC7C7A101578F326D02A086513B2608A8B58EA5A63F2C6A1CBBDC847C312F5A2309C1749C349101A42757073224B0ACA598A6A72CB308A010C327AFAC94798F8B4C6A1279389C12D1C3015B02E37A95705D3B2B8277C2C141BC8148C94244EC5C50E65790FD6E0842185A5F2AC1E72A21D4D652A63001C650B6C8D06CD758923D42479CBA96D7EB396803C77BE54C831063707A35067B87B2876A1A0844D11E1A895DB70D596871FD1434798771B487AED562EE1D041C06505786205166812FA718424708A207CB4A6C25EE78B8B85E869BB82A89F647A813B97DC1ABFB22B430D37ADCB43B7BB1616DAE73B0D606940E5AF7D139F73B48B4618BFD5C22274D3A27C20195794344EAC73B9A09DE5CC4E59A2853A412EED7062DAD16B0E1AAEEF83221D34B3225868DA033822248E5E40A692C20AE4CB112B9C4F9E373D6DC3393F385B5F65C7F14B66D7D0B31DD7902AF39812D76D5CE73EBFA4C392B069BE694BBFCC7B9C0825D158B431898C9CC9080D632196378049A5A02B43CF83D37E4A731505F23009661070038917A93C452004A8023B1DA44B4E5CC53ADCAEA033C8759A3BB4BB52761191D76C95599A9DC2A2292BF37AA3803278726B660233E9B476748A31F9FB9F2D93B59B9CAB33356782A976E05B083716262278349FB14B806A7CD3E52C1A6A6F603468C4B420CD544BFA916D157A21D15C1945B31F7C6285C30529DDF735350C92C546CA776CB44360CD62F05620F8B23B94A0A720270F122B0F22316050B7CF6623CC0658A9146861785C03FC4E0833C3565CA4EBC951F5145E2E434555D45C3819CCC4C2546673C18D70AF49F0AEACEB83041556D52754C10B1D66B9C0519985E9B0AED559074743C8796881E5A189A4707B8923097669B2D9A162DCDA33C3B825E004AA20B1749EB198299476BF45A519D341E9B507B1E411BD5382A6A84B6DC9C1BB437E98546074076EA76654CA6519F7A71D1F39C5328B16A5B182BED6B57AE058C3201554D612628274BFF57755022B7E653DBB461958CA3EEFA117B57299245A9917158F2409384A7B234AB390152B01D1383AAD99747258C61BD24F7B12A0332C6D7B5ACE324B4E1DD9B3F8574B17382BF387155F0ABAF4FC8830B7774275821E91A939DA83C9C189EC08774C739FFF041D40D512B171C2D0EC7E404349BF5A64A876AAAF72C9C16A004578842BFBB6FF221DEBDB6FFC8A6DE429CA0D7AA50071BC8D68C23C379364E56E4AC247A99523F8D90B3DE4B049B526F8961621B98DC534B9A756AA9C4A1B2B4C7726E701BA03D885A39D59A76D92BBA31013F2A4714EA3840293675AAEFA1219F8794D114BBB004463F9C631729734CB430F26F38886537EA49F3B482A66256D7F667585925CB7F58894E42660EF2573AE33655C231DFB0E", + "ek" : "29CB1911C9C782BDD00E8DB30B63F3E2A04229327F5B80B31E453882BBDF496EF8B50648165A10AE41AB7B03493981E281A8F52A72AFDA056451A4CF655DA3600A64D7A71D807CC24B3A625ABABF15483F295BAD250CE603440F2D5F7870081BECE985CE966008CBED7E6B63EBB405B5AB43BB35B84626B414BF6D757F6D2661B81B0A948F02FC76F1639361E633E201675523E1D5EB6ED0CF76994AE4E5C4C9C56006C4AE3E8702A8FE1B8AF48A0F67ED8915E25FF82F72CCE6777FF3B0CA7B94C6FDE023CE5978E67E89CFA94ED697A3515F7F612BA7E7F6D14D854912C5E6E29840E7E3315DB5FA79367AE4ACE2A0ED3216701665857899F2E5FFE579768BDC71A8ABF8C2432B18A359B465FA2E6229C67692E368322ADE393E8385E4E5D6CA5A8B5A920516B871823B67759E531F37B4273883F35CC8CC6D91EDBE50549B166CA45547DE464332C7B5FE940743174E72D93EDF6A7010674E8D64205572643F71EB5D25A1C97C71DA1D4241A98A8223657D5442C7E721B4CBE93C98558E4E1A49FC2A797CA51AC396E0065A04E178590C4D7C774FF6120CE45C362AB3CB38887AE3C3C23E15661163A17982CEB6D50EFFC856908D3E1A34ABCF394B91376C84D09574D24C1E7B2F103B38D12FB3B3D3D9A864EEAF993A2D63B2C954ECD0D8110421E8C4497EAD5600F0577F3B617DE48FE1B932786A9E91E23AF77A8B50A48B488703C9D0833C8AE1645ACBD58FA42E2A2DFC4DCD739F0B1A766BF609FEDD9BA4E49E14648BE9A0CB3B7BAC2713093E13158116BCA7E3D48389158EE385979C5BE2623BC4596738F5CAE76B5021B3400CA53735FBE203FC3D6C74C5CF058FE67A88C99BFAEA4A33F4F9AA0CC9749E210FB25DFF18FB20FE79AA52ED3CF7C22686D24E98C9F0E1B7C4D9D472F7842098557C2C4A67B3C82B8E50EE79DB00ECEAA261BF6CCB7C329E638B8F5ED04C38C1D4D6B597686936356E16F3FA384FC47A7A0309C1D37F1BDF079CA7B401BFB4CF6EDD9EFD82A47F7AF2A653447EFC7298545617FE5DC735C232C0C2F5B9D27C0502799B329FC86496644DEA07617F015E04632B36F1B044E1E0C56780D0C870D9240D68FB9ADCDEE7C25116E820458FDB17D67443C2BE5EB5F2DA517434AA78A5DF2F1B3D229FDD86FFB1D81EA10736529974033B9F84279C4DAD7B8A5CA0D3FC48E1FC9591EE94AA790E08085F37341E3CA6DB4DB5B511BB47D04EECB4209C64BBAF6C0C095DAA8EB36CC61021E9E417B92211C019F596F7A9180609A53F492862920860A7327430C964FC9FE77E9A73C412D2A4D3B68AFFFCF73564C480913FCA663ADE6ECC0C0DCDB066471F4B51C86773473EA6CDFEC5F0B5D18AD2AD00BD569DD28AB8BCB8DCF12AEF1761F98452FF3A6952C28AA88EFC3BA77B5EB1A2909AF4C0E995EDA70BF59C88304BB06CD86658E4A6F7DCE885FAD0B19EF4FA6B1352DEC37CCAE5B1550EB001C22B32CF14F0F752EA357C1CF26A342B58A9485EE744155EF3F1102397FA5B8312993315", + "k" : "69B1A0E2DB6683B09A1EE39158005EC02E9C0B0ABDFAFE7710BDFC4E4DD5DBBF", +}, +{ + "rngSeed" : "D3C9EBBA6EB03CCB5C9B9D2C8D7F0CFBBF50841E24396CDDF0E56525B38918C2FBE6C34CC1B93F7BCD4F4D5777E1A488", + "pk" : "A7C9CCF796828B704EFBB194D5D895CEC082F5DCCB78B59A61090EADA66093C84267079597C9881DFB2CA8FA4CEE6682C4375EEE25A08BC0766EDA05BEDB2CABF734C4243987012A44E86CC013B7E555BD15D45306479A78EA7D4FD7723D3B074860914E24395B264D35E57867F0229912C6AD0238587355B44C155BF7B5E5C872AFEB136BBC32B1A950B3122F3A5B71D8C140940B1EE62A5543F3B61719896499721F5466F7B57B119568C960A3796BBF2C8877CF8A762D6A8852619ABCFB85EC7C6E79652311490B03F61BB18A23FA100FEE70A0FC693163B28EBD6505773324404341E6C79B0562207EC1077CBB64053A4447866EFB1894A6A544DAF283474C6E0E99323F962B5CF4667640AF8351059AB42E0925431D864339258752A3B08AD52F985520A1247AF44366F3377D5875589EA9A8E38455A3BB5FFC29083664CDA47988F4F0C59622454A7109A6722A77703B0A69A4DB2AC154D53A6BD60603E9BE794B0B1B0B88DA57A64802AC771134B1A4776D07703DB8746E610331EC3AD3926891C05B4B738D3564B79B59287174696D119717D3650AAB049B401466467EC352102CE597F6E867726543067ACF511975828799F920BF139C176FEA838144797E79441AF218D9C2C0F15A350EF82D588B45B86A2C58464239C121ED2A7650D2841EB21DD6547BD32C0E4D654A3823C4051609ED49220C2651DEB6B0E55A00D261CAEBFA9C17D82D5F23A111C391D06C0441102C2745875D6905AE21412C2C14AE51C5609C5872828CA8D09239B82ABD602005CC66DDEAB736DB3CC0E946D6232177E6C012A8672BD62D0A4253DBB5A908C42341503B76D428A0C38F7E978D4FD2532D075C08D9CB3A440018B323DC3AC28BF8875E412745962E512C0E0E81B4919A813766BB020C831CE0C3EEA5A496E57E8D598D3BB34733B6358CDA44B1960E8890CE525578D100257ED8A916A02FA2D8B59478966835C0603A8F48715AB2544D0FC487A7EBA7A96A6E3918B9C9CAC54C841C2899CEA0312B40F9BD93EB7D392A4CB889144C224A23244067A9712ED9CF52A15EDC35895C7C121822468716704E3617CCD59AEFF5120524495D44AE3019ADF7D25BD7871B2A98A17AB6C68C789174A28A4863AD69362FC5982AA68B3C0CF35FD2D63D064556E55B6DF0D636DC5CA56A928F19C61816349C6339C59FEBB2B8675807A6A9181A91620A684DBA5C4C596A821B66014851966547D60690F7A805BCCC4BF9620C188495795C3DAD55C8E7529FEDC92EE3192A68BB9250420F6FF04F939C82C8442350D40F9D518C10C53ED5C3539E373D0F955D3D451E7873A22AF2AA87C08105C044613334E6B585AA864795E0A6AF988AFFB2B2EAE653BE5C76383B66F5205E1DF2B557B66B0F9B7063D3039510AD13A9B5AE6BBAE433808DB7275271917D75524EB2203202C1F0B4C9AFB402F5798214C28667D28727F89B95D3294CF38C129A792B16161E6B9ECA60C18ED802C72225D585C7F59059DFD74944F764035C073119395478651F88352C204F89222BFFF7C8BEDCBB6BE1728EF74E54435B40B22276F1199EF34673EBC70047956A543F3D8569F334A5FB22B4C2BC34AA9A4B27A11795A730EB96003ED4662F2F0344DA2B88E634672FE48E40EC83F4AE731342E77CDF4A3A", + "sk" : "05E74AE857AC16003FD911741A1323A9621DE488789EB612908928E0435AAC49CE2097CD03EBCE2C8C0AA232B19BC64E81D38750395AF4499DE139BE5D8A4152B66A56067CD9A372C667AC143151676399B516377DABA3BCF2A846074786F934C8C091921353779B91C1A201CC293A83E11BAC68C3E68350A90C13D65628F379C1E181A8A9783B897102BE367CD21629D198C39686C02339CB92278AD1D17CE563797E9B4215CA88A37A9379AC6CCC523CD94049225B900CE145950CCE099700672300BA71B22B7A1A01D30AE26975FC53795D2B49A1620A80D0076CA983C0B8B87E96399FD6869AEA85D35159D5A9872242515D230AE0965D5ED31CCA22A35B33C5810AC4737481B2448F324B7C208387AC045C0B7C9B25A678526857C34A7748C443CED32BD4B7A2155AB7D67297C67080F507AE2309B66800728D661472692AC22063F3886E111A5176387FA410422BF571C79A4D8B764ABBBB56EF845CEEC23C8381671009C1E983465E090ECAC84D3E7B567CA59E5AF8477EA89DBA3784308C680033C3EE65B670AA43FC6932DD9692DBC8839BD94C89E85E20B2B9FF015EF85A2C9DD7208DB5815E73A4ED469D38A967BA42B2CED1C959E400AAA10957010A23FB7E086B82B1E1309B64977A77B9F6BC15C92149E3587C9BC5435D4A50A62C90DFBBC339B3467795BD3E125BCC6CC83B797D4D7A6E8701953A57CEC99B8C7939697BCC488F0B6601DC2F31EBCA4B15059F12962E153A164076A9F6AE88CB737B8AC4F5ECA0FA8B3BC9D03F7B578C8DE160DAEA49A0211C7B007A37CAC38EE02D07AA48E355CBFC43A540D9096DBC5504949239CC0B82D94755C4CA182852D56B9B9819C42B6C22F3246CD4A879662CC901E4904EF791FB34C7423A23876204618276E45CC8893B15F5277B67C391177889D8868A8C14949B684467094A9E2566BDC58B00B339E3B91FB54B63E1F43DC57A7F107CC988CC1D65E456B85325FEC11DB5A7C947FB1D82631FECFA57DFF3A1DE5BA8BD0A5C2004CDDF442699C4ACAB590730C8AEBD853A51A8CCD68839F1AC397AC4A9B6F54316537BDB99879596BBD2F517B296906345A2517318B4146D4AFBB7E1C1BF377337C6B84D3363B49A7A8937CB58DB3524A2525F2F2984598797B835A41961B99BAB237077A5B6DACDB161C86B19469E4B99C5B552C63C3F3FE3140770C369C49E6F696F11639D625647B3FB9A38A0CBFBC01231C2206975C0C7B931597881AF2CC267DA7F5A320EB4408DF9E39D15A7558429390048331C2109D2C46AB7D16B0412C1BA8B6B1F9B58A47C3D54564E70440EEB43C80ABC8D67792324287B3DB329329267F53549B6A72D94D9BBB2A02B7C985AE8F4A5C39218CDA99F6D461BD27723BB20AF88446EA65A7B85C074CEE48FEEB881DDF9773C5C6740A178E1707C50788478D3500F6AAC22B0BE3ED5AD240A9A336378AF185DC1519C0948CBBA81790DA7929ECB464406CF618CC019A84868745591496CA38AC57DC5010BA815B24507ACE51EDEE75DCBA3877179C4CEC474101395D9F831241C2547487636D39F1C6082041BA679B7A1B1D5BD0B295EB137AB4B210D0149B4FB0C8DF5515CA6D7A67393A9F5B57AA7C9CCF796828B704EFBB194D5D895CEC082F5DCCB78B59A61090EADA66093C84267079597C9881DFB2CA8FA4CEE6682C4375EEE25A08BC0766EDA05BEDB2CABF734C4243987012A44E86CC013B7E555BD15D45306479A78EA7D4FD7723D3B074860914E24395B264D35E57867F0229912C6AD0238587355B44C155BF7B5E5C872AFEB136BBC32B1A950B3122F3A5B71D8C140940B1EE62A5543F3B61719896499721F5466F7B57B119568C960A3796BBF2C8877CF8A762D6A8852619ABCFB85EC7C6E79652311490B03F61BB18A23FA100FEE70A0FC693163B28EBD6505773324404341E6C79B0562207EC1077CBB64053A4447866EFB1894A6A544DAF283474C6E0E99323F962B5CF4667640AF8351059AB42E0925431D864339258752A3B08AD52F985520A1247AF44366F3377D5875589EA9A8E38455A3BB5FFC29083664CDA47988F4F0C59622454A7109A6722A77703B0A69A4DB2AC154D53A6BD60603E9BE794B0B1B0B88DA57A64802AC771134B1A4776D07703DB8746E610331EC3AD3926891C05B4B738D3564B79B59287174696D119717D3650AAB049B401466467EC352102CE597F6E867726543067ACF511975828799F920BF139C176FEA838144797E79441AF218D9C2C0F15A350EF82D588B45B86A2C58464239C121ED2A7650D2841EB21DD6547BD32C0E4D654A3823C4051609ED49220C2651DEB6B0E55A00D261CAEBFA9C17D82D5F23A111C391D06C0441102C2745875D6905AE21412C2C14AE51C5609C5872828CA8D09239B82ABD602005CC66DDEAB736DB3CC0E946D6232177E6C012A8672BD62D0A4253DBB5A908C42341503B76D428A0C38F7E978D4FD2532D075C08D9CB3A440018B323DC3AC28BF8875E412745962E512C0E0E81B4919A813766BB020C831CE0C3EEA5A496E57E8D598D3BB34733B6358CDA44B1960E8890CE525578D100257ED8A916A02FA2D8B59478966835C0603A8F48715AB2544D0FC487A7EBA7A96A6E3918B9C9CAC54C841C2899CEA0312B40F9BD93EB7D392A4CB889144C224A23244067A9712ED9CF52A15EDC35895C7C121822468716704E3617CCD59AEFF5120524495D44AE3019ADF7D25BD7871B2A98A17AB6C68C789174A28A4863AD69362FC5982AA68B3C0CF35FD2D63D064556E55B6DF0D636DC5CA56A928F19C61816349C6339C59FEBB2B8675807A6A9181A91620A684DBA5C4C596A821B66014851966547D60690F7A805BCCC4BF9620C188495795C3DAD55C8E7529FEDC92EE3192A68BB9250420F6FF04F939C82C8442350D40F9D518C10C53ED5C3539E373D0F955D3D451E7873A22AF2AA87C08105C044613334E6B585AA864795E0A6AF988AFFB2B2EAE653BE5C76383B66F5205E1DF2B557B66B0F9B7063D3039510AD13A9B5AE6BBAE433808DB7275271917D75524EB2203202C1F0B4C9AFB402F5798214C28667D28727F89B95D3294CF38C129A792B16161E6B9ECA60C18ED802C72225D585C7F59059DFD74944F764035C073119395478651F88352C204F89222BFFF7C8BEDCBB6BE1728EF74E54435B40B22276F1199EF34673EBC70047956A543F3D8569F334A5FB22B4C2BC34AA9A4B27A11795A730EB96003ED4662F2F0344DA2B88E634672FE48E40EC83F4AE731342E77CDF4A3ACADBC64E263F1AFDCDDF2AD63F2FCD19799A0A8F43EC867477E249ED5FE716F81D9667C03155106785069387CE7D25CB09C5516D52817201D6653F20E775B453", + "ek" : "8CD652611D0066785977B4C0CC4C97B5F22E809D93A892BAA0F2AB5F7D7BA9B6C43252C06CEA74AA317D1A519290A80D5D55FE51201532C3CB46E5763A2969A7CF054967F94148142E0C086E801F468F2D6BFE6A3D880AE32350E31960EF5B2C160FAD29D346DD32A0566242BA0BF01D2CD792DD73F78C2E813A450F98B6A5085D97255A0B5F6E62C1D9C5DCBE3071ADFD79BE32E957F98C5943E8F73C267450922CD91391CC59A16CB0665917B892EEF1B21DC9C05BFEEA7CD0E7C823D90981BAB5E1B7A3B35847AC3FD695FB941DDF6AE75088221CCC63BCE29FB4320FC4E9E9F6C3E110D5B33DE97FE30177E92899961754C1B58819CBB7F394151CDB34537EF88DCB3659FFF1B3089284C90DB797AB973808AF32D4BD0D34A9A8D344914FD8F0F8E95F4D5A46D689BBC53D3392FCFCB4375E61AB13411B7FB702528BFD5A4C9B9EFB3A2B8C08665801ADCA988B335B2DBB8A734DC07ABAE2767499B1CE09458EFD6E209CF54346A56ACB4242396E7C7096853D881D0C8F382C3427F81E6F20F5B2AE434400C90CBE451567A3503518BA40B0B3BD29B6B2CF837349ECB6F55E455AC5B15DD71A8814A987E7476B8BC3F90686A1C91E459A3BB82B08E03E3F5E941B81778DB7E5DA70653DAFCD08D2A3866474EAA4F2F25521580B336B33857F8D77057251B0DBE9023BF502C1A2CC4524986D5E82D9323BA2172332A1DC2E62B73F7BCCD93CB265D0AAD0C46CBEE7574F51347A477656C2D746C53281FB3D80F6033F700C04B1953F317EAAD3DF3289CA5A9B08DEB6BC63A0AB72D9CAE7C8E8E1B76936C95945F073E3E4559A9B8E2F3541ED90176623B6E127DDFD2BB057589C2593E0D1D86BECAF587BD70A2038BB49EA8143A9E8AEB4365687F484193D1207E25F982C2DE798E30448A7B1C209C760C2C742CFF67813D6B74E94AB918E12485781567EDFB1E9019939B67E875210A169C44BECF701092CD662917454CEF5EF0AC55BF44F7A20F3BBF0A40E8BB7D5FED06DC4B67C11D9419B6DA58317ED078318F9142A7F13D6AC69F0FE87D6FB08C710A4653572FEEAB77ECC8D2A5427E293E9ACF085F786BFDE6997AEF749E8B8ED55C59E7CE7D6421DA929BE23D0BA2BF8D378444C6338F7DA5D717D8096EBEA8C437DD2D923C12C9CE1552EA6D6774350B8011059F79B807262F3E96439D80E327F2F9E1402CD8E20BFDEB27715EB82E722CE372E97846E4C0C9176809A4D10A7C06755DC5DFFDFA01AAC5C157693953B03ECE4249B6BFEC9ACDD396595576F71C0A465D8A57C5A3EBD8207C68C70AAA183B9AE86C57E22870141C5165AE739B4DEE0CFB7EC7A9C98DEA3B5B83071D990BD3CEFF0C6CB129B6C6DD69CE897E43FA94A7AE240A0507D65F14F2F48AB03A34C40301A18CFF0A47F7C8D38B9A50FF1E908E96EF0BD81A66BF59769E409C48B8FDA25044B61569486EF335FAB079AFEFE14E8A0D846069B2924A8A0127552B85B6F4074A99EC23CF86C2325A522F01115310784721DF7753F665450D0D4", + "k" : "0360ECB6FC467A4F6B318317254DAF5DD70F647736A4D3BC5ED034BF28C30B45", +}, +{ + "rngSeed" : "6B3996E8BC6F52879F2B7BE012C44AD555707CB7E5FD8ABB3457A298336D6FDC9EB7853008FF13201D5969A315C7E493", + "pk" : "B854A0DAEBC2831A4F20695579B52D3369AF228842776A03C4D3284D763D1F663000930377DC86AB14486673A349D8073FF6BA44496C64467D5F531F5203A074AC7CE9090E59F1C308D2C755910AF132AB81B50AD6D6C2C6716190696AE6A51433F61185A43CB1D23708D8286D066B61A6B7F9E13F8248C232D8315F40053FBA0D7FFBB4CE60410899200A8A5E51BC1D8392CD56F41FBAE85F35B110933A931084444036AAB790CC09B84B7A235F34763B9AB5C9B53620F627778C661C4C45B36EBB3A4565795656227FDC280B327EE2F96C16E7BBBDE89E9090318787B2ABBA7727A393CDC04DC38205E3C86ED5D5291A1149EE204B24661AB2CA16C1C0A35D3CCA0D7C57F4E01985242C3B43869D9914312678710B039BE4C2B775CCA014B1D936CA8432A4614C4E67B69620FB49CBC787599C4BFFDC3A2C786BA876864E7A5BE33AB200BC2D087C3E6CC642F4A96771BA212778046B5823085C4068B209C54A5BD4153E4D986ED3512D09D40C37C1A2E57495E0A594F4430FDB1C88C4FB677B007D8804CA114C0991B90B5140761D59325502A1F0476E961A0C2B2CA78A82C8B5581D98DA26DE717F84C140FED0A00221BA71C34821374AD7C565EC20CEFC949E98D1819702A4D38597C1DB9239B9167DFC8651498927BB0E170C151E881577F58963593D3AE00870B8BB9FA3B77C468E8BD365DDE088F24C2577C5AAE2F24AEE1552E4482352674D1D96B90880336ED44F6BF007B5EB67C52A10910A9A3FC82AB8D50AEE17B667A27B4D014161F1A60C3084A25524693364AC1876CAB0C93C01A153B03486E75C3A01728F625F9A7A6A99E78EA9B77B01490AB49C6DAD9CA584229A8A890EFFE47CE0692AAFB17A3DB2B855A01666514E8A800A47C0CBFB4872C8C8A4D4BC52C8DB43D3F7360D568F4F905ADA2565A494901F229ED51BAD9106BBA6DC4FA7AC59A3A5A64D033BE1E47C36C2CC9DA10A2BD200B681C2CAAC5CB1EB03F36455241367D30019AAC00AFE312C5323CBB4575E271C01F09C6EAC03CE1F02BCC4186768493F6CF97671E7A02DB6047557306BB8CE086382BBAB8312460663DC1BFD01B2411B3C49835690627F133935C27308BE6B5D09844F477523521C2B1BB1C92B6B3C46C20CF97217683A3F2E46B0151511C7C9C4BF8620D4706FFAEC98E524360986386A7B5C20C312C5B6237BD17271BC6C146124D190205F468DFB00BAE08318350C1AA5910A07A67BF13A99A52A39B2B04FA56143C0C1290C5C412CE1647BA8242C851C8BEA960C9C4879B83037886AE77B10E8126DD3B633A33A662076CEA326765D6262619B8D0C8C3217435450070DBBD67404F5255B6557267178ED99CD4257768E728F3069BC29F8484A127D84098FF4325946371384463C4FF489CD8B6EEED0C5E3E92B1B988C41A31DF71047CF78AB1EF9ADAC2A1BA3121672505EC77B0620617598F84D1FC7B00FDC65E7AB72274C86A424746DC74F53142BE6423545D02D581933BB92058563279E522AD8507F4326699BF4831970775640887E875E1CF29A09843210A23976941AF397A3C6C5605AF133BA94126132311224388F340448A1252C5BC0197B4699AAB73A4237D40204A46103BD605BC698111DDC3D6BC04804722C35600B001C554180D16628713BDEA10CDF", + "sk" : "B6F76178BBAB01B89443C00292AC914D658044F13FBBD19CD4C0A385141C6A91208665BC45C04AD73185E6E3A0CD102A8CD20547C2335EBB3BD7E9AD50294B07D9A45E617473814CCD41078FB58D2DAC1F872C6CB96C73D1AA4356A917C94704A36B9EF791C6C021CF9ED2270685C645A76141F6373B8AB6AB18963B580AE0134D8B175382847811A590080A3DEA2B863E06A0990C93839906E2F942B864BEE7410BBB17BC1DB6373EC99B45754EC78531C205919C27A4F2445B8A777683819709C1C9A3660CCAD39941E496AA791FF8D2671B74580DF965D0126DC5C034B8B01F31179C1C4746D3820955206B447174ECA321A5C22AE852B631E12025B5675385731BA9234AE36CD90C3E16FB5EA2494012B96498F02EDC23CD0DB74970961FE430129AF1B94AD5B1BD95931AECB365FC257C7C1D1668164EDC9D2B869A4CC95D54759182C6086785246794A6A0F81431D75FC7189416A9B1EFA3832C187FEA912474A8A4CAA5C9D08B2386240A3D26755111A3A3E830266473B6E02286C10E23BA34EC08C1F643A8F2B74519631706690FBEB5BE8BD581175412C1B83DA81700EC92BD03B9516A779205C78F726126D67AC2A4C528663ACD985296D187C7F6E231A95707D0F9854A4C051A12179678ADBF8285B5E58251D08F2DA015BCF219EDF39F6BE56E53B95BE3165114616175A5AB44607612FC40EF814C9BA52B6C060C0F11ADC8234D865282C3DC5E106753CF221AB2996AB9887ED5334BC7B83D6BB413E1FA9C074903F3C94C685C660AB00A6BE85C384478CB42BDE6715C9A3BB77B7ACAB909CE428B955476C85F153263874CA3A7429C6A79A0834C15237DC5FC7A7620897876A3C0970E1B7B789A13482A38C5455A187995960806304CE34B72E676FA589F9823C949981B6EEB887BF7C09EE147645602A640598BD29AC48C94DAF0771F46ACACAABB4BBB73E841B4BE5CCC886987B56CC6E25A7260B3364EC4A897AC22816048756A530AD269759929BCB4CE03435784B25F6F87CA320060D2A1B3B800986CEA76229B1D5FBA58AFA9AC3514289A9B7F63D80F2B48893B376018A0BAEDEC2715B01D61C8CFFB63B839C4129C8B97ACD904A23A0CC5A38245802EF5ECA812870A5717C667CA9BAC328F08305621305E5D40980CB7A3F8BB01EC4469B7E17CB4657944A739448A461DE11E3BEA1D7141A6B7DACF8F41A8F9C6437A9C26AD5B2DFFB4974BB7762C76715A9694D5D012E2254EA717369766C22CD9938EC0A4B5A88E7C45B03027926984081414CF7B3A15D46895C362A0A2928C1215601F665D675ABFEA867957F68178E6621871BD7AC1010ABC494517804E68BE80151C0AA332102822B0674915208AFAA21EFB3BA32B0AADC9778869BBAB9AD2CF934A690F40917593667CC2AD0CAB53C387957EE24960149B07A109465C5DE3EB576D99481FEC4CA5E8A0DE36756F951896322D29C5ADFD124C867A5286B59F0C2A0C632C6778A098D39C1E6029285A821C06958671651804E75DE2D2414EAA19D0A18003C12F74D50655041AADDC6F5DAA6DCA8B46367C63BEC73CE1E181CC166EFE3BAA2B986BFF325187369982978CDFEC651946A4995A20B48B035DBB5EB854A0DAEBC2831A4F20695579B52D3369AF228842776A03C4D3284D763D1F663000930377DC86AB14486673A349D8073FF6BA44496C64467D5F531F5203A074AC7CE9090E59F1C308D2C755910AF132AB81B50AD6D6C2C6716190696AE6A51433F61185A43CB1D23708D8286D066B61A6B7F9E13F8248C232D8315F40053FBA0D7FFBB4CE60410899200A8A5E51BC1D8392CD56F41FBAE85F35B110933A931084444036AAB790CC09B84B7A235F34763B9AB5C9B53620F627778C661C4C45B36EBB3A4565795656227FDC280B327EE2F96C16E7BBBDE89E9090318787B2ABBA7727A393CDC04DC38205E3C86ED5D5291A1149EE204B24661AB2CA16C1C0A35D3CCA0D7C57F4E01985242C3B43869D9914312678710B039BE4C2B775CCA014B1D936CA8432A4614C4E67B69620FB49CBC787599C4BFFDC3A2C786BA876864E7A5BE33AB200BC2D087C3E6CC642F4A96771BA212778046B5823085C4068B209C54A5BD4153E4D986ED3512D09D40C37C1A2E57495E0A594F4430FDB1C88C4FB677B007D8804CA114C0991B90B5140761D59325502A1F0476E961A0C2B2CA78A82C8B5581D98DA26DE717F84C140FED0A00221BA71C34821374AD7C565EC20CEFC949E98D1819702A4D38597C1DB9239B9167DFC8651498927BB0E170C151E881577F58963593D3AE00870B8BB9FA3B77C468E8BD365DDE088F24C2577C5AAE2F24AEE1552E4482352674D1D96B90880336ED44F6BF007B5EB67C52A10910A9A3FC82AB8D50AEE17B667A27B4D014161F1A60C3084A25524693364AC1876CAB0C93C01A153B03486E75C3A01728F625F9A7A6A99E78EA9B77B01490AB49C6DAD9CA584229A8A890EFFE47CE0692AAFB17A3DB2B855A01666514E8A800A47C0CBFB4872C8C8A4D4BC52C8DB43D3F7360D568F4F905ADA2565A494901F229ED51BAD9106BBA6DC4FA7AC59A3A5A64D033BE1E47C36C2CC9DA10A2BD200B681C2CAAC5CB1EB03F36455241367D30019AAC00AFE312C5323CBB4575E271C01F09C6EAC03CE1F02BCC4186768493F6CF97671E7A02DB6047557306BB8CE086382BBAB8312460663DC1BFD01B2411B3C49835690627F133935C27308BE6B5D09844F477523521C2B1BB1C92B6B3C46C20CF97217683A3F2E46B0151511C7C9C4BF8620D4706FFAEC98E524360986386A7B5C20C312C5B6237BD17271BC6C146124D190205F468DFB00BAE08318350C1AA5910A07A67BF13A99A52A39B2B04FA56143C0C1290C5C412CE1647BA8242C851C8BEA960C9C4879B83037886AE77B10E8126DD3B633A33A662076CEA326765D6262619B8D0C8C3217435450070DBBD67404F5255B6557267178ED99CD4257768E728F3069BC29F8484A127D84098FF4325946371384463C4FF489CD8B6EEED0C5E3E92B1B988C41A31DF71047CF78AB1EF9ADAC2A1BA3121672505EC77B0620617598F84D1FC7B00FDC65E7AB72274C86A424746DC74F53142BE6423545D02D581933BB92058563279E522AD8507F4326699BF4831970775640887E875E1CF29A09843210A23976941AF397A3C6C5605AF133BA94126132311224388F340448A1252C5BC0197B4699AAB73A4237D40204A46103BD605BC698111DDC3D6BC04804722C35600B001C554180D16628713BDEA10CDF5CA1708C7C6E354B69720B4B4A0C358FE9A6AD3FEBE78BB2A71691658ACAE21AB5B9E60227058AFD73501B1C4E45ADBBD41C7BE8D14BCB8E98AF77698FDF6B69", + "ek" : "55DBD68FDA3206688516D698772A5C8B161CD9005767CE25D7E5330679E87A2798C72CAB713DB8FA2360C6D3C3E4A34CA20EA29A8EE75F8D7DAA3A3331CE40C5F5E6C21B3EB5B34F9BCC6A19421F55C3F8941F33575CA3FB145A6C9F3A47536E1B2E17CF352C4C784C665A156E48E62BD03D62F32B906845620F84C2DB619DA19DCE0A3AF9D4169CAECA44FF9629DAE0A2F4C98611D61C01BD302243C111491BCC9F7E0F3E69D3E1449B1018518617351C3335EC322D2CB971A6633831BEB60FCD121747B37BECD34EE81E108EDB6875EBCE0C7EC6D4AC957587F2B57E0C6F693715B7F63301F1EDB2298175330E44475F6CAC87C64CC1A021F0972FA1512A264F214610EED32035510CFCC3C7555EA0F79047253C665B0BFF8611077D0FD845D387468D14B31319C89C9DD64817440C7F4F4F34EC0A34B4EA220AC678C652B6C58D1435DE69C309FB9A3A79859E25EDDF36743D99C18FD0A1A294770888AE0B65C0DFC9A42CBAEE4EB9CC2F74E0971046F8C459C81DBCA59097BD247B51640718DDB19CA0075F96C727486880000263A294C9BB561F6EABBBDC80B341E137C986A4FCD7DE34FA8A8D33E40A54F0278B81B9E441477F6F47D4EF8B711A7873ED9A419DBD3B90862A82346E5AAF7CFA793387A1419CD488419E59D980BA44A56A5979559773B0698F9107725B0A6970C363650998415EDF05F82659526F4183BA93CEBDA2A058EC3E540913D7DDF60B23448DDAEB7DB248E87AF5EC701E0AC872E1ACFD05570E51318161A1B68DFE176C0992EFF1CF834B5A1163104B3E5EF124B591A01D997E0CC20E20879DEBCD9419C79FB67DCA8143534511A002F693F7745E1350E358FD7177CF7810F3004D589FF8CDC2D13B2DD0A74011C2A17BC626D53ABA4129921F4876328BB30CE147FB42F0C6B092B4087617D19B0C3D03F98C70C2DB5666E0B33D2129B61A47FFB766B0D249E32B3C95E5DE203EA1E22287EE5C53E3834552F037FD75A16A8F80AD86230C1600DA55ABAFC4334921F6323A991C1D0D438FC7B991F5093152D244859B7DC1E52653C866E876CD5F1289EBC0BEC80363A3A7CE09C7EF7CBFBEC389D4721DA56A5E39F5CD7C231F0DA157C79E2F2CB970FDB273CE2CBE7306E79AF4AD182163584DF48F2E6C856271177E9CBC47033CC5F5307880A981A928E512D17C59F11382369624EE6773F9DC44F8E0737850D4CC341BE9AE4BAB7CF7D54AE6E9AEF0045E56A34444F0E15B28745A809840F853AE3186E2C84ABED57532C6C9B92C5285E333EACB253E7C98570EF0AFCE1098DC81DAC38154C73B9C3A431F152534047406D8CC7F1E58221DDC0750C9F27835B59A63E00097128892B8756A6D52818D3B8F0E3EFA3EA99D836A8CBF0144E101340DB14977A46C501CB0F0DD3944F38E6C55232FB2B35ABE7C5B69F6B68FEB675D008DA8DD2E9AFCD89DCB54C0269596736B62B515FB745471E8B04E2EC4DF545BAC008EB210F64C4C2FF572E2C5A9657C0EF319EF885E023849320316547E5D", + "k" : "9BD6BCC6CB530617CB4D8107BCEDAC5524B1A39B5B5ED74C124BCB47A0E115C5", +}, +{ + "rngSeed" : "730B65ECE22DE27D573CE3AEA7CB021C415DF210D228808D91D4F380070FFCB0778B683C71D4853DEB569C822765F2A3", + "pk" : "ADD1CB33481D37E546D75B5398198A82126A7D306A26C7124518075EE6701D1CA69D16A867115582F22A7C382BAB3ACB5DE50C34C13A5378B2B1415B5538987A77681597ABAB9A0B5BFC7BBD19550064489BE9B897A54FD12C7229F0AF5313429FC85F1936B5A325AEA955021A969AE289657BA4CE7393477AFAB3EC0B6E46BB7A8570B2DD4372D51537CEB3023E477A36BC2B784444D0F71C3165395AE71F98921ED160BE83E0572487691A43128352B3D82B223C67B33D8277B05C6C071418799583E2B87C9C2A81BB2A7658D67E637B99D5770E04B592BD5961F0C726D0058B31086AB1D23F4D200BBE6B418FD53A0131AAA5FC0380F70F1C90CD1DD5BFB3839CFF013375F49919214E756856042BB10E1252A0108C1DC39A1F69BBC230A4E9C93A87A87899FAAA210A781C91BDFEC9A59080AE642AADFBE20F9EC600A2B297C3394A751354B6E8AC65EA45D3B66C57328249034738EA2541476AB0F2717940930C8551314851BE98351D96ACF6232E1960B97D930E3F424EFDF706C2DA2F652796CAF344B86AB388F412853A5643A7932409B476D3C81C2A301E968DAE28742D18232EFA09B81177DC9AB33D7B2ED5E711C157BBB123506FE35C5132BD04EA87E173A7D8AB5B2E35A7EEB58AB3F549DD30228DC5197F778359B4B9B9B989B697839FBC013426016110BBE721C1C89C1D463248887491F0814C4BFCBFE7445144B88CB4EC535BB85A3016891B009DD4EA020E3799D56A710FF097B79384556C5D7D717436BC9626CC15EA509FED2BBB74C2636E8CB4E0435283C7159D8C9EB6E11E5BF977A80994278161671346B368372AB5612C85AD48DB8A82067ACAAA39BC0B1F49083E71E8727ADCA1F3C7CFACF907A71C3C73E6737BC51795C9761B5C36C87B46141400DD43874C4500606C616D90BD9D588905FAB9B538C23A07B9FBA6C0699259B6B81ACA207138884886205955250E3E7B5D4D549A8B73C0FF41B88C305B7EFA4178695ABAECB97BA46DAFE090A81C038FF373B13582665665B2058835B629F2925ED99082858152433BC3BBE90937C763D835638C3225E0C3485F9555D3E1556FFCCB1B059DFF8667AC445B474A17F360A2DBD895048B29FCC003F3C46768668B88BC0053BC3821A95D5D49CF1510894F1739C91174310B0AB2CB7836B41BC44AAD9681C0067192D4A46C2FD60E2323B6FCDAA15A6581B4571B4CCC09FAE5B24D8B11F67AA629E79652388CE04B9CEEB5029E80341AB6ABBFE38B2584B55108A21AC64D61636DDB2094CBA91C2B606CF3D2BA09D4863EE900DECC2D594A042B5A63C822631533A14B6CCCAA0775EA3210E3EBB22137A749B22C1EB129C872578FECA153B312EFE6238583793852485FC53952E4A513E64B8AC7B60241944D704246551D3372AB9E60BD8411729CAB31EB908C5348C34DB74F3CA60384E93C91479A52B321F8544DC13620F26C9FD324784A294197D9935551CCFBCB93F9F2BA8FDA993A3598A5D37C36469024129C8F3A081C9B3A680A02EC450B0A805DA455C5F696BF46681BA9F80F6B469AF9B1C09FB2BDF618242F449CD017308DD80A9FA7A3A6AA25BECB6F07B241F0F72B345664751B83B46A276EC74AA2569B79DE21A5198E7F0C3BC2AA84E7F5C79F4CDEA5B473BA2D344BF994FD32", + "sk" : "48F2003D718AE6848E47937D58E68162209B6C88892C931B4CC4B1CE0A0E762020495C60E89CC854F72444D21DEF3A5B96A004E2D9AC9B110AA8844DD02A4D8508B0AD3C480E37196E343EBC01C12CC2CE6616CBC395A8C7E02B19D25041165832584742A07FD3207DD3687C91D17E111A945985805FEC8836231B7546263D96302473ABFBE36FDA05345950C7DEA6AFFC45C87A3272E780A3EE920EACBA1FA17500AB04A091FB355D906430CB4BFE66697A09CB08F992A3CB9B2F31624726B13223122C5694D9E0757B65B46682694C82B862AABF3811AD14DB6A31B602030498993B8EB5364F3C9213E66C81744B018DC895FDFCB81A77672E71B320E3A2DF75403D57C229E745310A7CF780291FE169DA8290ED96A2056995FC7C59CF6CC162BB10678736A4F56AF0430E6C22419A6C3535B22FCB837BC2214A1D83A6AE7414D6521149498B0E0841E7775F1E783B376C1AC39067DB769AF6E691C59683114C7420FBA6723BB3AE5A137224BA7E816B5463902D21223064C8A8CB10F49ABB765281EC372C647B862F11095B25A41705B9B327456A7859C7033691353EEBA926EF880500F34FAC746D9E59BEF7B50457ACBC33369F3F85AF047BBD75A40CF62BA1ECC27CD5A6437BD28C37EA3739A784F068CD4CC68F0CC6B01E4933003C950985042B1609E0A748C9F87CE5099356EC846F9B40F6C13A6187CAB40B47D04CAE05D43C53956FF4553F62761068E9938F21A24734305098CAF7C9022A8B52CDB54860419A532CB9750C3E439A742D9031076B99FB8A934C2C8A42430A8E65CCA75286518CC08A6925C2E3B9FC854D8343B36D652F37C339B951B0F7D774B4DA5171A96CF6981F1848703DC93F2ED6BFDA065B7EC4056632A56A549353C12C0953757B2077E65C93C00673E88CCEC700B6D2307A0609AE9035177FC41C97FC32D1B8BFE7266AB8EB2B9BDB9EC6692F7D6678633B030CC19905BC46960BA25AC8B9DA762165485A7C07744D1B8FCC080993D0BF86496262F268F19B7DD7D7BDDD4C947E1146F2196CEDA5BB53137FB107560C4CCEDB96351945BB8AB5092C9975DB266E621C53C519CAF639C80225248E6804D78108789B2238644F33136E853C26E1477827D3797D7C75A09044BC77B9EA05BAD41A1DA87A460E17779A5233A080377294A1BA3A99B4DB42CD42893B937C369983811C14305CBFA0E57C3E4B19F0A77C4A2A6998525ECE48CF45635C5672429B67630E603D1CEB5A22E429AFF58C2CE61E79F6780D59575CA3309D559CBE6572E0671AF2259A39063F628BBCDB74345AF9CAF02AAEB0A381E39A5BF08107811B243D130C482B0C74A47738D9A6C5D30538E64CC513160D9A8351B9CE82521AE1CC03C8A48F72252EF1B2A15E6785E639246CB8C196F9949EC094FF6639C8E216B90BC3C2099BB3093AE5242F252807BDB162B3232F3E7383145655FFB71CA43456F1A5137E7977EF214ECBC6113F198D7712178DA090620A9D343025AC11595AB6B6844262822B128B8826FADC7B3F218D37941825733F43BA4CD99B63D26812772980679C3B14462B762AC8C3E8942A0B1D4AC1838A2795113C365A535D483658C4531A0EC63C010A2C7EC159ADD1CB33481D37E546D75B5398198A82126A7D306A26C7124518075EE6701D1CA69D16A867115582F22A7C382BAB3ACB5DE50C34C13A5378B2B1415B5538987A77681597ABAB9A0B5BFC7BBD19550064489BE9B897A54FD12C7229F0AF5313429FC85F1936B5A325AEA955021A969AE289657BA4CE7393477AFAB3EC0B6E46BB7A8570B2DD4372D51537CEB3023E477A36BC2B784444D0F71C3165395AE71F98921ED160BE83E0572487691A43128352B3D82B223C67B33D8277B05C6C071418799583E2B87C9C2A81BB2A7658D67E637B99D5770E04B592BD5961F0C726D0058B31086AB1D23F4D200BBE6B418FD53A0131AAA5FC0380F70F1C90CD1DD5BFB3839CFF013375F49919214E756856042BB10E1252A0108C1DC39A1F69BBC230A4E9C93A87A87899FAAA210A781C91BDFEC9A59080AE642AADFBE20F9EC600A2B297C3394A751354B6E8AC65EA45D3B66C57328249034738EA2541476AB0F2717940930C8551314851BE98351D96ACF6232E1960B97D930E3F424EFDF706C2DA2F652796CAF344B86AB388F412853A5643A7932409B476D3C81C2A301E968DAE28742D18232EFA09B81177DC9AB33D7B2ED5E711C157BBB123506FE35C5132BD04EA87E173A7D8AB5B2E35A7EEB58AB3F549DD30228DC5197F778359B4B9B9B989B697839FBC013426016110BBE721C1C89C1D463248887491F0814C4BFCBFE7445144B88CB4EC535BB85A3016891B009DD4EA020E3799D56A710FF097B79384556C5D7D717436BC9626CC15EA509FED2BBB74C2636E8CB4E0435283C7159D8C9EB6E11E5BF977A80994278161671346B368372AB5612C85AD48DB8A82067ACAAA39BC0B1F49083E71E8727ADCA1F3C7CFACF907A71C3C73E6737BC51795C9761B5C36C87B46141400DD43874C4500606C616D90BD9D588905FAB9B538C23A07B9FBA6C0699259B6B81ACA207138884886205955250E3E7B5D4D549A8B73C0FF41B88C305B7EFA4178695ABAECB97BA46DAFE090A81C038FF373B13582665665B2058835B629F2925ED99082858152433BC3BBE90937C763D835638C3225E0C3485F9555D3E1556FFCCB1B059DFF8667AC445B474A17F360A2DBD895048B29FCC003F3C46768668B88BC0053BC3821A95D5D49CF1510894F1739C91174310B0AB2CB7836B41BC44AAD9681C0067192D4A46C2FD60E2323B6FCDAA15A6581B4571B4CCC09FAE5B24D8B11F67AA629E79652388CE04B9CEEB5029E80341AB6ABBFE38B2584B55108A21AC64D61636DDB2094CBA91C2B606CF3D2BA09D4863EE900DECC2D594A042B5A63C822631533A14B6CCCAA0775EA3210E3EBB22137A749B22C1EB129C872578FECA153B312EFE6238583793852485FC53952E4A513E64B8AC7B60241944D704246551D3372AB9E60BD8411729CAB31EB908C5348C34DB74F3CA60384E93C91479A52B321F8544DC13620F26C9FD324784A294197D9935551CCFBCB93F9F2BA8FDA993A3598A5D37C36469024129C8F3A081C9B3A680A02EC450B0A805DA455C5F696BF46681BA9F80F6B469AF9B1C09FB2BDF618242F449CD017308DD80A9FA7A3A6AA25BECB6F07B241F0F72B345664751B83B46A276EC74AA2569B79DE21A5198E7F0C3BC2AA84E7F5C79F4CDEA5B473BA2D344BF994FD3204F0066489947B572F76E1DFC2E24297B210ED0AAF228788A0B349D11689E06411C033D4A4BB231985CA7E851FC73EA4B2C29E131B7F442DB8A66A9E5B31934B", + "ek" : "FC7E5D1930F261B71397AEB780673E400D25DFF47ABFCADE759E19052C2E9EAB1151964D1472DEA9CD288635E7767A4FE833075C7E25630C6C58BFD1CEECE2A1BF3C6A19F7701AAF9B48ED02F41CB15F7D9760F9A99CE5170DAB864FD61026662C41C9816B1C6DE747A62606D09703248CA5EDAFBA594A8508C3C4B75C8634655B657C39C5960D603B4B66704E1B13315AC04B88B8AD165ECA7A7C73C834044F24A03EFD2868D744B7AA94877010ED6B5701AF022D6B9CF1B2791EA9A8FD329A0E58F8EB3AE19C75AEBBCAA7E3719006693E84ACAB20E1FBA4C6C8CFD38EBB5DE4E72A193FC8B506A7D08807379BEEB5B92ABA619AF357D449F4CA349626F65585396A44D96016C25F9FBDFB9214A2F115D7C0F2BAA2372672AF2602C7FA6BCFA4B79B325599840CBBC2DF303A38D6F3AA49898A4B21CA5DD450F09E82F66F1DDCC741AA57E7B4794D544B4F279BABC6D5318C81029CEBE41B81272B35579F31DC023BF9B09B16CA56E49BFD6AC7A7CA0FF0A5C215D4A89A1BE9DE9AA044C8F3497800E305CC1EC29DEEE2AE4FACEB949E8C665627CD9822CDA744B82FB36F5A4B31BF53F98B3127D7F399E9626559F6DCA219F960C535A2A859EF7D44A1C953F5FA4CB2C94A86B282A253C00C22BDBD09814D05D6A0ACAA97380BA31408D40ADABDC678A2DBE2651733380946EB1FFA29A31478322BECA6DA441B8F6EA6977B7530BB18C37DCB72A33464D1A0F2C3CE4D4B0B937A18A190D6A0B40F6FC8E8457DAD8D3C6267B3B6F4E9FE257EA44AE28AAE1DA0C23D9B6935BB62AEB4B9A07C7EFEA21AF8808CDDAC668B0FEC53F0C7532A8AB0508ABBE93C81D78317B34EACABED33E2A97DA1B4B90F9E1E30F4990C6F38E1D368C47B76178984ABC248857A2734A1A053864B2DF19271FB3D532ABBD22654AA35BF5B05863D52D57F819350A3778B5D59108F0AA457F2790ED3A6E102B81D04A4DBD4BAEBCC30FE1CE261324D35FBD5EDE44AD5FB46572D857F93500B003E240D47078B0823E817EF0B06D9757B7A6F5FA9FD347FAFD76F40401CCA6B4250DFF128E1458D6E9A03F004171C7361BABD01C8FF12E891AF588C742EA80786EDCFEFE8B6834960623031EBB3EFC1FC714583203F8ABA5300261F468459E4BE3762D3630DD00A8EF99D56AF9D0CF01C2CFBC52E13A9D1A573979EB153A9D99454A7CBD3DD4FF89B7F7E12C457FD84FDF54C4E125FDE584026E3DA5B8A1581EA5A8D9C3CACDA8C6B1F081BCAA5E1406F1656D53DD1C3C982BD39D18011D5545797885C307A45AAE6374439161DA9B047D679FB72C2D83172FA441042982E9F0239FA9C68AC8FDF34264004F9F87182C2B382EC359F10614591562D1144032C2CEDD7A6E815215FEB377F45F69B2E03C3DFFF643ED0744D11CF8431B3E5693A35D043FD9EC73AA4C70A3B097C1C0C9F73E527116E10CB9262105D987AAE38308FFD3ABF502FFFF671ECB9947E687A4FCD89A46CF0039CF4D0506CB74C8B8CF299529DCCC474C3FFCDA3D4816446C7", + "k" : "6C185A0270BC69A71673A00E5C394A951ABC4482257C4D43DA1B8090DAA2A7FE", +}, +{ + "rngSeed" : "5522A5A891A9A9B5514F4556AFD8DF40B9CEC63A01492F0CB8A1DB073A285A963E4A9FF2376C88662F7D8D241F8ACF17", + "pk" : "A7A8102DF0C61577A7CD4B9A04B17AC55708D8C6746289529337B9E267737D5345F4E768E0D6656CF23593A84EB0EC290C8BA078EB9F8D1CC8EA18280981CAD0F46DD29C474FDC57CB5BC93E318537CA343BD03EA6A7A466B021B3DB77021A8E20B94907EA294F47BAAD599D51D74219E38F883B36CB323A317520997988342A7452C3AFF4522EBEE30211444FE78854F9F853CD189BE04CC1C800607CB4ACCCB650AE546323E7993BF2A203487BECF8328A2979DFC5C3BDFC1B47533A9A629E5FBA5A2234BCE8EB37D686A75BC33EEB945D80D92C218548EFF794AD6C0D825B57F6F12F0EF6B8201BC0D1FB0354F051EC1A217A9A0F0C77B1D6F76C1F25B01FF356FA390079D3800F1468D745A0DC852AC140307E700F97D557EB42164844B0B6D5A37BF1BC41DB5ABA156359E9B4AD5649189409BE58B8AD5AC89E348099AB9FFE81C71D54853EBA7B42167D478693C39837F76182E0C894E0F5CCF19643FBDBC5278B500D1B07F1E62EE797930C0CC4A41832AD093B28460C8700678BDA847EDC6BAFA64CA182016F75366AF8C330D201C7AC4327B2326D8B57997734BF909B0FA1C619155AAB7BC5F4026079926D04619186C4334F48BDFAECA777E91D0B0B7FC4B180E5E19F0162C5D3146B5AC5AC820781209C455D195F17D541D6916F56838F7BE838AC0293CDB63F28529DF3FC7D54475062B90D3034C2583B00C942102F82B9553C1120891B77D61B8C86BA21B4A78F772C4049869B56442D33C642A5C0AD167747807D5F6105CCC21AF8E06C85031A2A73ADA9D59453017F131B55C1E0176EE29B021B7933606C5425078B7B49CFA99F24B21818E78A0E856747E4A7888A3D1313624AF81C75ECA6C3C43238BB078B94C2A9C57F0C4C66EC5B59AB93B73A1000630AAA28A79415320BCC8A96195934C9F14D5DC41CB70C1104A63F5FA29953495ABF71B9359563F16C7BD6BC319ED7898FD00CB580902F2196B45311962CC17A9A9F002A916D9BBC1A452BD3E6A48CA05E50AB35BD828CFE66B483E96CA1D917001B46374C41C2D079FDD8257BC339A6E13A7FA2C0948056F6553803D10FC9F1C87725230BA3713903193F200A9851A78B61534B5A949D140C9B457EC66769C6544D79F0850C4CC8E4B78EAE0B260DFC9CF0848E4E09CF52047D62BB8E7E6231F4BA49859B1DEDBCA0D8832BD23789C6FBC40D61485E5A951DE68639E07E624A72395B9E25B603ACB330A37B998B7A9AB3F973003C15624C6ABCE84050FC0166924A397708C12308C578105C1457DE7CB41DD609C0C3333BE5B9C3B93E2776AA0AB3A4054C98789A4BF419BCB6EB914C2179BAE02B462B1126A3A28840B9E7170618C20E8527993623CD0C776E54F8B4EB237B4F8C075FA2175F11BE86E2BDF3B9B9DFF89B7534134620116E0AC025F6707B00B5C743AAE144241B935BA61827909B591B44CB6F36107EF81A214C6AA5B9B3E1F441C774CB7102310C4031E0E4A213A8C1F1593906A0424D657CDA7C10C1354B0D5A83D2CB9D0407073FA77ABE480854C953EEDC6CB06C75695665B92873552CC053A9BBA0C99AAF970753299DB3528276B56FEB8A5BBF373D13C20C2F22AE07E9542206B296F3B101D07A3BD1517D9EB8DB21E1F18E6DA63ACFCE1E0DC597CEF3ABFC7D0AEA99DA", + "sk" : "3E3A14084387AE125D7F5A0E51841407D61F85D7574B1ABEA52B6315D07A404372C827AADD3ABA668BAB52D5943C59BC500B78BD77CCC7DA7A3A6C8B613B9CF761BDD73A222BD11B246431D989A9B5D7B68F8C2364C8BB9380CAEE16BBAFEC6E4EE157655528DFD8399B3912B303481607620C941CF3A314CB7013A2526229C4BCABF7642596C4100023140A4AC869A30C2A20501AB4838581F42783A18B83F5165907985363D766EDC0606594188427A979D171C4A52152FA4ECF0C4D4BFB10306B98EC4A409E2BAF598124ABB31E34BAC176A29FE7316056ACCC59F38A268BA03B39BB48E0A763E340DCA4C3F1D8580CE304F696144EFB3DB5975157260DCD26194B476C5C6552F9A39B4C556028493F0BBA23C96AC03D03CE54A4680E8075CFE70B01BBCFF4E3026FA3185F059D401552DD966E70032F7D198A17B8620BA30A39CB1AA3F84EC2D82D154CA88F392C28574CD8DC1025E832751769560569E9BB0CF3F7A4126800142753F7E4950908BFE86B468D095F422C1DFAEB3B196A1C62CC8B0BEB47FCF6A456150B780B5648EC05387CC81D485318F1BCA87BC6CFD30AE2202E342345159154C8B561F92565EE2C20D7E1C385A7A1D99CBA75A3121E410D3145284C826C408455A068625D35B69FF944CB880601483B81F08DDF8CA0B8931480878B25E7C73A6795222B593BF517F0C25F6B862F970BC2A652ADA653838C942A68098AA6931A9A858CD4251C19B07F69B208CA1C479777907FB752D24CA06C96B394232F0E1982F4D0B9C6C245DA5275F75246F4D58472457AE842C6FA886DC2305B1E2654F1A999664C2E7819571BE87BD2F8216BCA5486615776E30A3BBCABC3B094D90C9FD24A083D03CCC29590647C533B278A28EB667BC71E2CD62CBEAA74821456278003B9FBC18CF23F2837C8326031BC8AB260A92524E9812D307004CA9F6D709A83B77D3B15B417B1CC7DE93737C02E22D0AC4486157D0A8236612F0E25985847185007C41A5846DBEA0987794EB2743C87020063277CD366B2C5105421C453257A63683A719A57BACF373B8CD90BB10542FC979C92267E04E0612CBC9FAFD485933B42B15404002C8CA8930D295359FF299D5AA3A5B82ACF26722542819389891509D24AC2D34D7E10AECAC27EDF022D499357D4D8548220148A082A504BAF876414FAEA7DDB11639A073E87C3A273713305FA19604B33F6C362DC792A0007AA577A0F3740A246AB4226297A0E66C073564B954039DEA916EFD14B4A32AFB361B80292C6B35244EC1B9FBFECA496B35C1BD5AD7E313575DAC43478816868B094C1756BAB5503723D39DC2EC6BCBA3103B6107544F9BCC74E25355597B69425AE77F04C0FA9A17B1351C0854964261E60284507F0B2A89B4A76CB9481C986198C3FE8514C76465DE4EB364BDBC43EC1A1054462643A0D1FF57D957685D0E70213505449119628E86C02F23E1315829CCCC9F60A733B8414161673C66A0F33371CA0B10DF9FAA4F142C4B4300B79B0C18CE8CF76811E459C98B56871345A57844AB6A3749A3E14C18C463E5596836E8C436296A84FDA143E69517B8176FEF3C52606170194AEF5B429057B9EDC7C48F1DCA18605BEE3E26AA7A8102DF0C61577A7CD4B9A04B17AC55708D8C6746289529337B9E267737D5345F4E768E0D6656CF23593A84EB0EC290C8BA078EB9F8D1CC8EA18280981CAD0F46DD29C474FDC57CB5BC93E318537CA343BD03EA6A7A466B021B3DB77021A8E20B94907EA294F47BAAD599D51D74219E38F883B36CB323A317520997988342A7452C3AFF4522EBEE30211444FE78854F9F853CD189BE04CC1C800607CB4ACCCB650AE546323E7993BF2A203487BECF8328A2979DFC5C3BDFC1B47533A9A629E5FBA5A2234BCE8EB37D686A75BC33EEB945D80D92C218548EFF794AD6C0D825B57F6F12F0EF6B8201BC0D1FB0354F051EC1A217A9A0F0C77B1D6F76C1F25B01FF356FA390079D3800F1468D745A0DC852AC140307E700F97D557EB42164844B0B6D5A37BF1BC41DB5ABA156359E9B4AD5649189409BE58B8AD5AC89E348099AB9FFE81C71D54853EBA7B42167D478693C39837F76182E0C894E0F5CCF19643FBDBC5278B500D1B07F1E62EE797930C0CC4A41832AD093B28460C8700678BDA847EDC6BAFA64CA182016F75366AF8C330D201C7AC4327B2326D8B57997734BF909B0FA1C619155AAB7BC5F4026079926D04619186C4334F48BDFAECA777E91D0B0B7FC4B180E5E19F0162C5D3146B5AC5AC820781209C455D195F17D541D6916F56838F7BE838AC0293CDB63F28529DF3FC7D54475062B90D3034C2583B00C942102F82B9553C1120891B77D61B8C86BA21B4A78F772C4049869B56442D33C642A5C0AD167747807D5F6105CCC21AF8E06C85031A2A73ADA9D59453017F131B55C1E0176EE29B021B7933606C5425078B7B49CFA99F24B21818E78A0E856747E4A7888A3D1313624AF81C75ECA6C3C43238BB078B94C2A9C57F0C4C66EC5B59AB93B73A1000630AAA28A79415320BCC8A96195934C9F14D5DC41CB70C1104A63F5FA29953495ABF71B9359563F16C7BD6BC319ED7898FD00CB580902F2196B45311962CC17A9A9F002A916D9BBC1A452BD3E6A48CA05E50AB35BD828CFE66B483E96CA1D917001B46374C41C2D079FDD8257BC339A6E13A7FA2C0948056F6553803D10FC9F1C87725230BA3713903193F200A9851A78B61534B5A949D140C9B457EC66769C6544D79F0850C4CC8E4B78EAE0B260DFC9CF0848E4E09CF52047D62BB8E7E6231F4BA49859B1DEDBCA0D8832BD23789C6FBC40D61485E5A951DE68639E07E624A72395B9E25B603ACB330A37B998B7A9AB3F973003C15624C6ABCE84050FC0166924A397708C12308C578105C1457DE7CB41DD609C0C3333BE5B9C3B93E2776AA0AB3A4054C98789A4BF419BCB6EB914C2179BAE02B462B1126A3A28840B9E7170618C20E8527993623CD0C776E54F8B4EB237B4F8C075FA2175F11BE86E2BDF3B9B9DFF89B7534134620116E0AC025F6707B00B5C743AAE144241B935BA61827909B591B44CB6F36107EF81A214C6AA5B9B3E1F441C774CB7102310C4031E0E4A213A8C1F1593906A0424D657CDA7C10C1354B0D5A83D2CB9D0407073FA77ABE480854C953EEDC6CB06C75695665B92873552CC053A9BBA0C99AAF970753299DB3528276B56FEB8A5BBF373D13C20C2F22AE07E9542206B296F3B101D07A3BD1517D9EB8DB21E1F18E6DA63ACFCE1E0DC597CEF3ABFC7D0AEA99DA67CE6C8ABCF3EC4D93505D3BE02C039E5A12538E5E59ADB5A5D709B9B342938D75FD654BB12DA3469881ED591A82F58B4BFBAC587D045FDF3AA0348029DEB1A7", + "ek" : "7F17BBB4CC25E300CBB40CC61439E3B10569716C3E393530A357FA4D1DA08C821253B646A55499C29DC3ECE08C69D8FFEBE6C243782E5EBA521FCCC51D56485C45A46B1FBFC899A11F507F0F28E6BB28D716121BE625FB96543C9270BD15701DB0D7F6B9B0FCA323A091605D8C35370C6D3E442ADA70F3E453EAB57A57C5CB5BB6FE857C829541C194338015C8613153F5638EBDCFE53F8313FC626C1B7E94918B1B32D2A8FEF69738A73DFD3F2947AAFA60C48325EC1D16C0950B809125CC73E2658C819CE54FEA02CA2018C76D7B040B7E8A8AF86286B4FA49FCB4FD83D189B55254DCE4BDBEA5EF90E4712D2A9858A83D3329751BDD6AE8B76CABB530E22D25303499481864A5148E896E48A0417857F543663339EF935A3EF935DCDB41D0ADA683BB52A56EC09756AA9E768F2B6B945C3E7836FB3CF13273EF8651856F3FB4AEA5CDC48C57FE33E6F20BC41A11F9B6183B77474F65C48D2957EE2704AA1DBA59702BFDEBE471AF39B0220132C5FBB0A072C7BC935789AC2DA03E092024F90AFAE5E1D382910E7433521DE5513A155FD8934F4DC5AABEE8FFA366CE8B4BDDA8ECB317DDB18E517717C0AFF2F535E5454A34EAEB41FE11A3BEB76C50DC0C758F6939EBB4224D054470C7EEDC82881EF4D5CFB3729BB0779349A40DA9878D6FA1AEE8FC5736339B32D23C1566ADBB285C1D9D8C7B9BED90410F57435746D2AAE4B35587A7D455A35CAFD298FE50BD3DEEF52EFEA1E8647FE0BCF2456BFBDFB911BA94075BFA215F8DDE201ABCF042077402316D72B74405DEF1D7EC07D6D11CC692A42ABEF4C24ECB2097915A1A33A001D087338F657BEF07E34E29FA1CA750D7CE2F4B517BB6416855A31A8F20932B4350C6DADE96371E4CA108BCD690CC8D3B032DC1A67F1541224766B9D638A878CAFB5293E8978962856FB771BB951787200800264021E79B28A1F2D3E2E7C2372411F07DEBBE5A71B18673D7D362143A4E3952B825934B22ECAE90F6E4FAFFB337E861E5895EBF1FE0CE0C0FB395DF06722C66058B423D7CAF773BC154E7D2FBD68F4D9A29F70A5981DD1A5A5EAF2379302731FDD01C51B2CC01919C0FE4C3672713A84EEED423E99D1E901DD744494CB7A69D0ACC7AC4C4CCC5C96DCADCE5435FDC38384904586D52930C4325DDDC25F014D5E5589DA5B9625415BF397B9E2E5879813C72BCA45901F1EE6598D2849FBA7EABEDCA7F0FDD07ED7CA735836F65A677E5DA4C08166734C3EC069D423728B83DDD5DF07853D622872B804E1D80A8EFBF69AD3634CC2BD7C943C8DA9B4E00A978D7B3E93693C07B8F7EFD4A345B4CBFAE3790D0B191BC076408F5ED6DF300C1A15455DCF04D6EC84F754D7CD9B4EEB6E234CD464011AAC19D61554C351BD9A91E1A6114CAD7B98680E2BD7BA413030320AD1A42941DCDEEBDE90A035837DBDCA83BBB4704D8907AD54B19B3771B1A148FA615452CDE97E172381297AFE5045FEF904984FC058350186AC6ABA659F28FA6ED718EDBA7CD77CB008B21B21BB9", + "k" : "C2C956AF2F65289CC7F27D72A1856C19A46F1A6C19F3EA31B3BF16AA141462A6", +}, +{ + "rngSeed" : "1853E72329353B3F89AE6A1B1EF700DA8ED3C10D19F9E61EE9252E28EBB0E15802EE43083A12A0B7527088832605E3AB", + "pk" : "E078C4A3954F40A2697092BBE4460F27C4CE6886628382606F395B55D1A29939A2F754A0B82968D3C865F30066C5E21E3E2839416570F5B54F24D347E2E10169571A3935307A4918B5D68DDFEA58A90382E70012911729238A4919A7531242228995215FCC96CE8C1970FAA902F79C7A7207A93613DE0066C384786F5913B24040E6B4B48B6B679E5538F953540C25C18402BE1C58762FE8BCEE6A1E58D93B21165F95895AFEFBA1F735B11FB7BBFCB40D3D54BA24CA7EF507973AAB9017B66A3E271F980462752137D9AB0D1937226129BF48F68B700021B2FABE81573E49FC17819BBE46858B5C58B4CA7C83A57398A667B09C681B990B648E96CE79B72104B13E97611EE8528C9F64C376EB04925BA46D3C8AB859304CE17B9435309726045DE17D8A7CAE32AA9C80E1AA4058CFF89010DFE22DAF0A002A905F945ACCD2F9225739AFF1863006B46F9ECBA5243BC48ED1184BB9A57AE26C8CDA147CACBB4A031112279DBE727FA6C467EAD943269AB1E3C9657C19BA0B648C9D4A48C6163A0A79954C0C7EC63529CB8A65C851C39840BB1A7C584104016F16B43DA179189343C3276BFEB5839D6622E684B421526D69517AD57B67494BCA6DB58CF6C95266170DDD9455A6867DE052ADC8909790659FA0DC0A1D011487B16A1E08BC82B22AA9444F123632EC889719E754993AC8319A72EE83A988A2C77D28ACD4BB5EBC486C33B0AF1D67A84A349480FBB2B0B252E8749401D8488DF52356A75BA2883090DCB757451C9956888B43806431BF9ED956E34806BAFC15FCB1CF2B45729EEA12A6580C6D1C366A76187FC20FAE7657F560973838ABAA510FAD13C59C5BAF4773188859809D1BCDBA937845759C9AF40DD2F14BD7DC48028A77FF4165F2204FB3B0B9F585061616CA4FC405A0C8533C344334E511053A548EE86998E9094863B8BDC02AAF6BBC916481AC9337ACBAC10D90794EC239268AA376157B1955379D30C2CB4927A8077CBA969AC398BC8521450EFCC7E1CC617E69A66FD16B771A2497D14E35A61919DC129844379A314821C333A2F4443651A4CFF234A3DCABAD32610F5B54D138065D8A5A81FC5068C5060AF125265CBC42C580F47B9FBDA72A893329999958B026C5661BA116346CCD86633E0A603B48C8ACAB78662162A9F11C4349C5235A5AC46546B16B25E355B4408456F7339122B67BB48334836214E431955E979244C8C7864BA189EB24C818C15417CAC84682F719C9BDD8479BE5C643D937605383C6A9514118498D5B4E81D5B74A063FB53CC19A20A9CFA26E479339B988C40918C192435DB1A3B2A7C6046376B97ACA7A9BBB30335A0E8FD237F8833E89E41A1C67B8AA9B0D539486B1855B9FBB53B5103AB2D19606165ACAA588B9D14A4E6A7823800D8A9334FF7456E75AABB81408B791C9C6BC3B5829C1AB241E8D310BB7B15A5B24123A2C691EF1B5DD80640A7B94892AA1AD7300797A3DE52A66C794426230640B303E71F0B93654708BD81F706B0F71757C08FCC591525BB6C9A57777BF1BDA0D81B4922A56586D21B04DAA2684E14EE8C0CD542824205B2BAC3C1232F2BD37109D621A25CF570573465A706583DA17C39FF3AD13826B6D5988158A1602A361D7A2F86A9219450FF713E184C0F6EA4146B79B03E5EE3454A79F", + "sk" : "1FE26897D8A471A69851D6BC3E69088DA81DD3534AB410B3A3F55C8CF805341651896A61C919668C97B2DB572D15B2799236545A4675D37C1AE6D96A8F640CDAC13C66C98E849ABAEF549AB109085F0190BB5315AAD870867630E41133087888231A08BE1BAFFBC0A74CFB84F24CA020C401D79A6E615604FB1BC80B2410A0E9B251AC2714011702717F6FFB2E1A7A3DDAB5ACF7D3211091471FA02F0838CC14D281850465A6A51E2CB6A5AA8A9560461AB67338B30C43EB49BD5221C26D366B21DB0E6F4194EDD60AD499052B192C2202B6C7962E6541A8E124410BF0B4CE9964DFB153576960B1AC01966552F8230CB3FB267F57650C783F6765C4C396A864D1762DF70FF2F67165A6BAE7E8B6C20A63A3668B7FD76160DC0CEFD968CEABC3827CB2FC191DF6E1472F27015C65A222B0A007A33993AC3270EC3AAFE4C869EA2985088269323829BC0304D0C21569A3A14095939224A40C9922F77BC59734B58385BE242CC8329FD9A4117E38A72019301BF8C55082186B84724D541529C79D8DC1A54B2CC3B3512BAC4127F683B5FB1CCF6D10539EAB9C8AB4B875733A903ACAE2B725854934B4B28F09E966E8E987077076BA508432F02F17322CDED648B206020F94171D8B82B413B7CB3573197C83C50B1387EB6CAED48C26E33D8CAC079FA55AD0C83FB7C045D640482C805B5845BA5A3767098C7058E43542F19E74D9758A025B008440B07A19A9FA9B24B8A4550A8A925BAC6F60476CA877A459B60E285FEB8A86458029CC31C3643A1949208491EC529E566D9E2B1118086CAC7252740098FCD318F2B319A89AB1EA4657F06A5034EA2E4E2A9DB6F06304FC27D6002F6DDCB487777D18B7C8994CBB1305A516383667C29A8144BE189697E36B068B2B6E2556794E53526388BA53E10ACC0373926898FBF1136420C50C01D063B7BA87233B312792B031AC0D8668AFB43EF651495663263CCB99E03540015C0A9EB7B88BC888877A766F15C0F28B947AAB9D74C212F80C78A6BCCC9EC78C97BB5242E25790305B9C222373536C481137FFE5B9903196C85C4EA7620B854170AEF2173E69AF57EC93AA20168BB679140A4BB668719D8773A1C7BCA0415E645006BDF7967FFB55717199DCA172F70976A9F1CE41DB56E088676377ACECC04F7BE426A57C71EFA95FEA2366562B61945A56E7502782C41E7EF46BC4427ACAAB204A8A8BD78C05471301CA4134D727BB025411E9836D14B2C7117B4E135401348697C0C66A8AC13476D67791247D97D34657514FC5829DEDE57C05A6404D8044DC2AA84A26BAFE9BCE4C1AAA8DE6A43C007CC1F203D814CA06F0A4643C2B5A650E2061C1A5B7CB30684DCDAB80EF3C03EB2A6A52B0C531305486A03C95AA0473A3CD7FA9861C8A9FEFF0C15E66094639AE7DB30863A35730DB258BC69B7CBB915918CE42B873C944A7907B7BC014357AE981861C36A1600050E019711360A4E227F5FA7CD54742E111028372057E982E4BE277A2728B4E381333902EEA825B943128B897C74C109475B3A70312C1830C7CCAD8A6F60020149A2A4B843D19DAAF10D426A074711B35CBBDA9797AB756DE92BEDB7BB19BA174F7AB74AAF115CDAAAB7D09C8E078C4A3954F40A2697092BBE4460F27C4CE6886628382606F395B55D1A29939A2F754A0B82968D3C865F30066C5E21E3E2839416570F5B54F24D347E2E10169571A3935307A4918B5D68DDFEA58A90382E70012911729238A4919A7531242228995215FCC96CE8C1970FAA902F79C7A7207A93613DE0066C384786F5913B24040E6B4B48B6B679E5538F953540C25C18402BE1C58762FE8BCEE6A1E58D93B21165F95895AFEFBA1F735B11FB7BBFCB40D3D54BA24CA7EF507973AAB9017B66A3E271F980462752137D9AB0D1937226129BF48F68B700021B2FABE81573E49FC17819BBE46858B5C58B4CA7C83A57398A667B09C681B990B648E96CE79B72104B13E97611EE8528C9F64C376EB04925BA46D3C8AB859304CE17B9435309726045DE17D8A7CAE32AA9C80E1AA4058CFF89010DFE22DAF0A002A905F945ACCD2F9225739AFF1863006B46F9ECBA5243BC48ED1184BB9A57AE26C8CDA147CACBB4A031112279DBE727FA6C467EAD943269AB1E3C9657C19BA0B648C9D4A48C6163A0A79954C0C7EC63529CB8A65C851C39840BB1A7C584104016F16B43DA179189343C3276BFEB5839D6622E684B421526D69517AD57B67494BCA6DB58CF6C95266170DDD9455A6867DE052ADC8909790659FA0DC0A1D011487B16A1E08BC82B22AA9444F123632EC889719E754993AC8319A72EE83A988A2C77D28ACD4BB5EBC486C33B0AF1D67A84A349480FBB2B0B252E8749401D8488DF52356A75BA2883090DCB757451C9956888B43806431BF9ED956E34806BAFC15FCB1CF2B45729EEA12A6580C6D1C366A76187FC20FAE7657F560973838ABAA510FAD13C59C5BAF4773188859809D1BCDBA937845759C9AF40DD2F14BD7DC48028A77FF4165F2204FB3B0B9F585061616CA4FC405A0C8533C344334E511053A548EE86998E9094863B8BDC02AAF6BBC916481AC9337ACBAC10D90794EC239268AA376157B1955379D30C2CB4927A8077CBA969AC398BC8521450EFCC7E1CC617E69A66FD16B771A2497D14E35A61919DC129844379A314821C333A2F4443651A4CFF234A3DCABAD32610F5B54D138065D8A5A81FC5068C5060AF125265CBC42C580F47B9FBDA72A893329999958B026C5661BA116346CCD86633E0A603B48C8ACAB78662162A9F11C4349C5235A5AC46546B16B25E355B4408456F7339122B67BB48334836214E431955E979244C8C7864BA189EB24C818C15417CAC84682F719C9BDD8479BE5C643D937605383C6A9514118498D5B4E81D5B74A063FB53CC19A20A9CFA26E479339B988C40918C192435DB1A3B2A7C6046376B97ACA7A9BBB30335A0E8FD237F8833E89E41A1C67B8AA9B0D539486B1855B9FBB53B5103AB2D19606165ACAA588B9D14A4E6A7823800D8A9334FF7456E75AABB81408B791C9C6BC3B5829C1AB241E8D310BB7B15A5B24123A2C691EF1B5DD80640A7B94892AA1AD7300797A3DE52A66C794426230640B303E71F0B93654708BD81F706B0F71757C08FCC591525BB6C9A57777BF1BDA0D81B4922A56586D21B04DAA2684E14EE8C0CD542824205B2BAC3C1232F2BD37109D621A25CF570573465A706583DA17C39FF3AD13826B6D5988158A1602A361D7A2F86A9219450FF713E184C0F6EA4146B79B03E5EE3454A79F7FE853DA745A27A1462668BB66C4348B7F4BF25C70527B360B2FD104CDA48FE54C7E3A5FA1EC46B73F87AF48578132EB080AAA37D31F0C2A041C5948E59F44F9", + "ek" : "C342ECA1B981B3990F50060881CA2D4F2FCBC72827C8E2569FA74EC97C7677CACA04FD355470E0EAAC0F2206C2AA6C467263932545E6D2D2DB1256739F02123B97EDE0384F51F058499F18F57FAFDCCDE93D83EB39C24938D06F2BFBD881ED7CB32B793B57A7CD1706B26131329D688CAB467A1A9F836662D23D45F5B69D85CEAD92071D9D42118B8DDDEA86FC65982334772DBCF6B9B6BAA92F73772819EFAA3B0282622778D3B264CF26C4D5DEE427474CB1A8C786B3DBA9B860673B66A73217C8CBA88256DF8B48A0D824A1E0F57168AEB518519AFB81E48BD3191873D97DA3F9CEBB3315D4949EC904D8E7E719E9F5F4087DB5EC7A29998EB36918900269FA67917B53EF0448AEC3B8318290E9DD99EBDB579FA481819C219BCEB77F01051A7D5AD613ACAD24B9AE4234C7521852F652971508BAB711788AD23C5AC4192D14CFD94D48F0ACF5789F3161361EC7D1F8DC84E0D070216A3F53EB7A7B34FB41694D80349799D376E9D9BEF44E217BDAB23DB654DD18073F8D1862D667EF7C4B59280D32921BB8ADD29229343DBD613435A0176F987668F6A529F4E33BC2CB109CDD50048EECAAB2FEE34A5BC7E90DA221D209F879395CD31EECDC6EB6FC955B099C915733FB4BECB9CE59F178E7D588F9E3E091A682CB1472134795D4C3ABF068A0FAF086A9209F116CA74CF3E28BD9805EB2B0EBD3084D07593F1131579D6F15E3B193663585DAF484E383D48D84C661AE20B59D439C2F896EDF33BBD679DFC37532354552D228538DA04799551840B7C4C15850584ABF5827462E54D0E3D2CCE16759C1DC78C692C2D6FA83042FFE9CFC9ABD2C6FF9FEF9D88ACC5ACD53690AC8373BE1A1BA5AD3961305F3934AA56CACE54E34DAF3E30A9F4B47E9DD1E4B459F33B40F53C602E2CBDDD833B558BFFDABC9D3E673C82533A146B06E26B87410D27466EDC9FC15D33D629106B5F8229EF4877F6AEE6E6305529B11E008F28FB365BA884CA6EA25B94183B1C6BACBE5A1277A91731706A1F7E6CC32C8E1776145409580CF9F6C4A57D2EA697971F110D220B533172D1F0F4CC9F60D5B7216C1F90A5782A4BC133EF559834653771256548499519F66B30A3D89481F44C7BFF0DE90154E55C91D79B6FF82D8855E41023E791544F76FB7EABDFD56224F0657F7A320953DE58D598270AD6F9F7D5CB0E8C37E07AA6F02F5A099458CB5CD4BE915A8C6F49490E8B3220A9AEC7812961FF0171571CAB2C8000ACA1F1979AE5881B092C12C4FE8F535AAD7E88FDDD77921F90587AA05D5F3DF8D3590FF32EFD564462975615DEA23754A7C21BBAA7475CED37FD440A746CAA6F3B6E8690633ED0D05E65F4357B55795DAD148367EB7F4064557DA02815F6DB3AE758938A37E81B257BBD4F6F1C3DE50B4354238B35AC5908098AA043873D7B2BF3016038B7797FD657AF931C7E871009AC77659D9B93C41B2AD995658E09B81D7317B6D6F809F18D0652CB867149820C736A9F36CFB3A6C745B739E5725F250A3D1917C78256B7DA3", + "k" : "B61BDF2CEA456F465117EF9EA0330B454267FE6A00042CCDE93A38C1551B82CB", +}, +{ + "rngSeed" : "027C3D5847ED4470931141104F25B19AE76117CBB64B224EE424FFB782E9A0E988839E0BDED0DF666FE8E5FCBB5DBC09", + "pk" : "A4163313F3CF10A65AFBE14A738352FD20B1931827758905DC32C20CF8ADF6C081009CA396F270B23A5F26117862A13CB00B65F5A2850E8252053255B8232626B5BDCFE44E95C0B7B5B09802165B5310122A434C5456136CB3A77C3C7C23FC61271550CF15122FEA612600AA722C8646A6760EE18AD6028850FA36B82156C09429FA188DB2EC3DC229A78F92112B4357D3681AEB19779F1785195B65469C6D3AF60FF063562817C4587225A10C8E9FD56C4353711F287469B87CB533B99DF46BFBCA625C4601AA86459B27778C7200F6A12AC8E8BC078231A37C87400A7429C476DDF7516FA4B7E27841ABACCEB3C24E92158EB168CD3DFC48ADE061B2C02C33B2A33B59AC45A77A439371F3683AEB6A18B107BC34E7785E4146B3F668D9565CB32A23BEA6AF6DAAAE79B39A8F725E61F1355C6965D0BA0CF8DA22ACE189CFD0652213501B3B5F791061CA929E2FD057F357BFAA4047C28577D2105BE1616044A6383FF9A087F4754926338E486CC3E76511C7946A02893D058F7100C98BF0AF514A47A7630E6E2564B5459D3B52BAC6884FC32C7961A34DF387AB85C07965786D6BB731AF75742147304A5CAC936797BA658FDB88C1939C78565914DDB0334FA291FA3182E31A36D6C159AC637A0D3A37098569A009911F54B13EFC46E403BA4BF0BF59499CAC06C848754903A7B8A1B7549A13B2DE5A2CB106A21A3A58D1D71BA30700D74243B1030258294EE022037FF9C7E752CF0FC60F582B6310D4637309CCAA3940E6617B72C0B0217924FEBB6F971A56A979212A452796A217909547598330557A9309161FBF7C59004D7B3A88A2C3066534153D99AC87DC5918401B860C1B4D5E763440389290D2B656C97CB9784B201A90553ACCEACA0F22B17852F391DED7094225053F88B6578678F178067AC944F1FB6C2E99ABD946953A49B059BABEAE527408F520844323D9496E51E88F0899857A07B8BF8586AC7A8D13579CA934161D10C08E3B400F084CBE9C6F21E29523C41BAC2187B7470F752B55ADDC6250C08338BAC7FD0879620023899041576191B502C736115E65977DE34C740C75A5C5F54AE4FA07A2943A7F5A3B8018461445C3CE938579680B68FAB41EA2BB26E40EEB13AC84FC3A38B78DD66186558426CF59A1DD4958427BBCBBC13037C577B0E0551238A67F596CD0A2627965216BF733FE88718D64725FFA4B6E73077A37A4585159C887B2A2F5077D1B457C06102CDAB7A0E5752263CACF7914DDF836B0E1A95AC4B941388BF7C5BD62F616726100F448001E1C6E4100BBB922B265942BCF37966A5B61BA4957DD02C484413084985D5B22B37964B5F66C11B27C25AF757F08CB8BA3B3115A6839483454239BB9D0A1B6B1BCBBA5060C3AE47FD0476107919281A508E0606B4AB51AE12B0866C21CA994817B87244AE55222C0807B02581856936EC0CA25E08C7E604E1F1379914702A9E209D7796CA44879A363CCE71A0D9850C8AE8596E9B7157A71052602CDBF1C2BA113341FB8B612F114A82C6BB106C703603EDDF80ED634BE616884B9F2BB271240AB48126A40CF7C0958E0C5BB4F73185CB41DCA542888720F8F930A66A66BB9C79ACDA38A22249F5240A5DB0067A23151A6F02ABAC2477574D9B5D49ED6C25FC46576CA327D614492EEBB", + "sk" : "6206AD862474F8463A601909E145BB7B68C12772311F5474C295A7BCB93EE331A5A891CCE2A69AF9E0820FC9AB484A6CA985090035970A587E860126801A87342CB627E769FB9BADF4C075AA78CBB127AB20F34D22CC4299ABAFAE49812A5190B95182EB635E844A5111490D754C0674C7A39D8B3323CB1BFD04A0430893B013555D253AA2739AB64808EE6C6B59572F40E3C1E42224C3B20648513172A7895A52B633F63292C04F3E61B25D064ED4834F854C932A897B7F093CC4AC98A22366B184480BA746968523C91A8A0E0980AA8A1D1DD3401966B27B7838BA246EA90432CD723793271CFBB4719E60912DF891D7E4A9A63781E8B1BAFB40431866AD153BC067D871ED8BB096152BFC1B731153711BB40876E835033861CF981B4DE14C24F2542F84C94EA39CD757AC011C8FC5785A9021626F476DF9CB687894582348C0CE00AF7CD3BB01685F5CD73304011E1B989B1A509660301217130302705C4FB868C1123E0CD633514B4648A347557A9147F44CE88BCF8DB4C8E18C826D34AC25C7B5582B3D1D552F2AE28174D0A84B5605D909A6051258D11A941378377F457700E2C8B3901EC33710D179639AE04D661AAA9B3CAAE38972DD5075D7CA40FF783BF79C1FF4E4BA037C16E3839B76B88EDE1779D025841072CB21520F18ECB6E0C9BFDC0379FFA6C074A12C9482AE39B3B51C1C7D02B72D3B844E4D80A8CA3663DC7016E49B0FD686CE826205E463BC164B59BAB5CB2BA3B973F7750E61A8697BB1368BCC98AA3D670B7943D7AE89E64F006783E8B67D0142BFDBE4A335A564357202D57566A8D97AE750BD61021CFC9B4FCFAA38F7B6CB55CA53F16B0EDFB36FFC1BC4C347C9DEB19E75873F2B41613B98C73D346E0AE0AEDC0A5154342AFA6A1872A73E1EF77F5D34B49F369C4529587C391FE885B0C50CA38F7227ADC980DF096254374553672992F84E7FC55712A1234FDA91C4EB8172128E5C012D75E4CCB0B440AFD1787F3A26E0230FE8A35A5C76515E4C4C6B335E60A0B417CC43109C45E6BA639A84377C204ADFFC0736144D43A005BD35434737C301EC15564B00FF6B8F8B83BF2D99B72A71419B83A39BC3A637276125E9037DD4741F515A41E71DFB75C94E29339A235107F3564E939828CA499986230312CAF91045FD6363C9DBB7A822027FBA5607DC12B4F19257E1C8832B95B537583FA6642593122EB2C0A25334DA883160B9CDAF4776FF14CBE2AA7D28BC271CA7985C1B1F9324042272C1590B737B5963B8894D58670E535775E7C3BEA20628B3292A43407CDE31B0718678BE28B05C11811E1B0016C456D63163549522EA65673E188A27A39783119D70106E9F35B437AA65CC685AE0A200A3B225516B9FD0F4687F3485CEC27A7BE012766AB18783CC77274C6487BD0AC369CA29A05AA0CD5FF8AC68E7B582392800FCC4ADA35E2974BB1DA5254EF6AF37E487100B4500F82F5C76A14542C9198AC57D699F26005C37B94E7FAA5EBD5C62F562351B58BDCFC15199849B33A1BE9AFB67CDFCB4A201A29C3B61274349F82916C9DBB38A206D81DC5036C51F70293DD51562CEE893FC80B7E0ABCD5A625470436AF7CB7C3CB76309490DF6254297F2BDA4163313F3CF10A65AFBE14A738352FD20B1931827758905DC32C20CF8ADF6C081009CA396F270B23A5F26117862A13CB00B65F5A2850E8252053255B8232626B5BDCFE44E95C0B7B5B09802165B5310122A434C5456136CB3A77C3C7C23FC61271550CF15122FEA612600AA722C8646A6760EE18AD6028850FA36B82156C09429FA188DB2EC3DC229A78F92112B4357D3681AEB19779F1785195B65469C6D3AF60FF063562817C4587225A10C8E9FD56C4353711F287469B87CB533B99DF46BFBCA625C4601AA86459B27778C7200F6A12AC8E8BC078231A37C87400A7429C476DDF7516FA4B7E27841ABACCEB3C24E92158EB168CD3DFC48ADE061B2C02C33B2A33B59AC45A77A439371F3683AEB6A18B107BC34E7785E4146B3F668D9565CB32A23BEA6AF6DAAAE79B39A8F725E61F1355C6965D0BA0CF8DA22ACE189CFD0652213501B3B5F791061CA929E2FD057F357BFAA4047C28577D2105BE1616044A6383FF9A087F4754926338E486CC3E76511C7946A02893D058F7100C98BF0AF514A47A7630E6E2564B5459D3B52BAC6884FC32C7961A34DF387AB85C07965786D6BB731AF75742147304A5CAC936797BA658FDB88C1939C78565914DDB0334FA291FA3182E31A36D6C159AC637A0D3A37098569A009911F54B13EFC46E403BA4BF0BF59499CAC06C848754903A7B8A1B7549A13B2DE5A2CB106A21A3A58D1D71BA30700D74243B1030258294EE022037FF9C7E752CF0FC60F582B6310D4637309CCAA3940E6617B72C0B0217924FEBB6F971A56A979212A452796A217909547598330557A9309161FBF7C59004D7B3A88A2C3066534153D99AC87DC5918401B860C1B4D5E763440389290D2B656C97CB9784B201A90553ACCEACA0F22B17852F391DED7094225053F88B6578678F178067AC944F1FB6C2E99ABD946953A49B059BABEAE527408F520844323D9496E51E88F0899857A07B8BF8586AC7A8D13579CA934161D10C08E3B400F084CBE9C6F21E29523C41BAC2187B7470F752B55ADDC6250C08338BAC7FD0879620023899041576191B502C736115E65977DE34C740C75A5C5F54AE4FA07A2943A7F5A3B8018461445C3CE938579680B68FAB41EA2BB26E40EEB13AC84FC3A38B78DD66186558426CF59A1DD4958427BBCBBC13037C577B0E0551238A67F596CD0A2627965216BF733FE88718D64725FFA4B6E73077A37A4585159C887B2A2F5077D1B457C06102CDAB7A0E5752263CACF7914DDF836B0E1A95AC4B941388BF7C5BD62F616726100F448001E1C6E4100BBB922B265942BCF37966A5B61BA4957DD02C484413084985D5B22B37964B5F66C11B27C25AF757F08CB8BA3B3115A6839483454239BB9D0A1B6B1BCBBA5060C3AE47FD0476107919281A508E0606B4AB51AE12B0866C21CA994817B87244AE55222C0807B02581856936EC0CA25E08C7E604E1F1379914702A9E209D7796CA44879A363CCE71A0D9850C8AE8596E9B7157A71052602CDBF1C2BA113341FB8B612F114A82C6BB106C703603EDDF80ED634BE616884B9F2BB271240AB48126A40CF7C0958E0C5BB4F73185CB41DCA542888720F8F930A66A66BB9C79ACDA38A22249F5240A5DB0067A23151A6F02ABAC2477574D9B5D49ED6C25FC46576CA327D614492EEBB65297F711F12A5FF123E6DE59D1F16878E93A31612015FB961BC572F3E999CEA6CF04CA090E5805FE0FFEDD6BE0F254397155A7639C5AFBB30A7A75CFEBFF026", + "ek" : "E5F9E9920BC2A1D195D80A9497198327FB9349B30EDA5A3A9590F931DF6451A08C8C15E1DDAE600FC2252FDFB606118962B17B713F372600F23EF82CD7F0A38A29C29463D8D6AD3EFD58786E5CABD48C27308FD2AA262C0EF1E74A1794FB6E2F3306376F82C623A14BFD1151AE6518CE5DEA225DB536B47891E4C8F8C998FA4D72EAB47C67B8477A5199519491884770D333797A08ED84D08A7A4B80FA6F856D7322D77E6D8AACEF46E7556D684DE22C9AA0544B62FB8F1B2D568F44D7B6D3503A75489358FF11A7D7E50FAF08E70336EE4D485BE40750833E28C96B62B77851510A7BBF58EDB497109FF46F013F4BCB71AD03E697AC8EC55103C5A068F16434792ED92F4C6E646F3A59FFF7AE8A20DD4DCCC0C3C3CD5F5977DCDF0D4DF3BF5BBD553BEF66AC7EE9C9FCAEA92BABEDC36EE4F632C7D54C892909C7193D9E0912735F3D75720F9231270A0DF19B20EA60246BD820B9284B868ACFD5B5CC056A8FBFABCCB695838B0522466223938DA8216E8EFB3F0CE341B1B66391E4A6A0F97F727DE05DEA4F70E6C93CD0F087DB6F1B652884B5F49BDA1A70952972F25D57C6180AD322655D884E0DB2253812397E88A310F425DECD1C99F13EFE03B7970A59B9F1C9A4BB4D9A7C590CEF34D4646E140E49BF18DA70A334F864F560C0162EF1F2ABA800267E547EA16FA20A6E91D0240645FB27F9CF1A3AAB0EBF2A7A5D8A1A8E3E8D694E58228DB9127C6100B2C018537163982A26E561B18AE0FB290B0F1F0AAF2EC1C0F21B8A40AF77C8EC55994D622AC7DE66FDA4493F7DF4DE53DDC33012FA68497F5F4896BEFF086D12502BF0F84081DA09B736DFACB33F74D529308E0BE0D00AB6B607AEAF211392B2F976682613E3F63B20DB3BBABE6E90629720D160437E7E2F9296D5AFD66209ACD4EFD44AB02867F77BC630148F595A1D3A8EBBDA24723CF695F951130B3EE073BD64437620FF3E8749BE113E44E42B7D85FDFDF61504F37BC1045E98951BBC79F59D91D7E8C60378BB57A48FE2CB802A08D79F7096DD37642D9BADC99C92F5C3C028573F4F25C6CC3F2DFBB3F231BC5463E755F28F8D61795A84E11090886A188713170413BBF516B455C946802FFE5064F39B575B4EFDA32E6CD7C8F2A011BCB3D13570C549D817CECE42747DC9193D4CE3A4158C4AE31392F749B266B68D35214C35577FE537B98B0AE0BB4128E310E9D0EE8808187EC652F173C3E3A36C1B108B5DA8C9E0239983989633964CC9ADDF9DCC6ACC5B1ECCAD4E15367CFC6FCEF7DE944C1F5BF6C85C9DDFC106F87F00BD48A56BEA13C6BFB33D753380A4486CEEC2066BCE0909E42870A64CB03687CCFC2BAA55B0F10B76B62B51F43EC0369436750B538D62A8EB861054B926595742179A1513ECE3D77D0FA18757E609BCAD0B0F4B3F7347A15B9D9403FD281653B52368BCA37106B8AF12111C45798DDC949555E40C1FD92AC0C44B89F1E8EF0FC6949F4FA2C71CC6C70B43EE823065D8ED196F17524080464160F54B8C0065ABE258A592", + "k" : "87C599A09960FD75A776BC54CE0F6A0AF2FE1BCC270DFE6463621BB092483E1F", +}, +{ + "rngSeed" : "450751D4401737459C6D93E6C5F2FBCC4A3AF7CD7250CCF404BBB817A67BAB7B4C9D0EF4570BFE25CF919DA331C31D88", + "pk" : "25B2CE04E31B6F647ABDE39D7B1CB988C37F2AB219C67839064481C2539F7C947A5187A850F61BA075A002E4621EBC290855C9E75818E3A99DA9E50522976372EA0E6E201F8CF3C49E4A86C503C38AB764B2F45BFD1718F6B5C0D2E66181045BE2A2A8A1E10BECB8A6BAE9569F42654187A9D9B24C8214ABF933063526804D0998B89C884B1055A56CAE82557455F3A47C677E8E262FE9569ACA0C5B1C0CBBF768302099A4CF3960F9D432A0865031E2B65DDAA43E00AAE05AA39152256061021669B8F2BA6BB31045E7E539830095216A846AA39D5B16BF69E152AA227C61287137E2B29D3931C6211510EA33325B2ECD20A1BBAB9D30A7AD9BF83E3058520606641DD23B092831D29022542513070C8626A42386C8177C7BC1FFE5754EF5B3A2C41F91F1463B7B068816B058DA287B4AC2AD82191D061630337D296A08A02030174A219C143224B4B1AA1324FEB23E7D52CCDC757929342EBCC02C9A080AAFF12763894928A16C1F7830D7DCB2EBD77837D97011001D83F3512F9578EFAC3CE1C0A17DA13B375C44AC8C32E616AEF48339C19A4F379C216FEB9672C20D78262FA99887F92324BF667502517CD42B340B51AC0D0C71C2CA5D357554EED04C1206BAEE66707B10BF52A424FC7567CA023B605A0E160ABA5BE5AFF753983B19938205188FB87A867B6CEA58112A3323C2EC23A92A1C16B48F8CC7BC55C5B18A33B67580CD9383275E7B53D053AED3F41F1A74859F3536A3C07832D4B64D6A9BD591C4A1901C46490EFD73C9AAEC1466528BFDA0AF55FB7A28F4AF2C332DE8024F87567E1EF87DBF3061AD29490C658B8367B0B911BA3C3C91E48189C8BB1CF3A229146CB537958BC1B427ADD62348BA0B54718753ACB2EC3A0783C58C8B6B1023580A3417CC08745FEB9B3F19397FDA09002CB019BE30A8D3781C936847D5C7C5A8E9A7B5D8C18BC5877ED4A8D787A7B11A0464440DA596A4250308398AA9CD482E0F685703058987B63E21C530B3B5367654BC30B86FE6F0645E328714FBCC0F666BB8EB28D7279339F622CB89B813C72DCF5944ECF68E4CE422744ABE30261ED3E127118CBDC1D224E538B48D441359D673470978BD4B5913B6CF557760389B3F6991344D4B622C7A332239A50626CE553A6E0677BDEEA96A3EFA72931B6921A23BE5CBBA9F51166BE80A542B5F341866F78225D50A608E95BDBAF02A599B7A2441537F5124B0D5150A19A7DE9AC2DE2460B80884512C970E7C700AA259982BBDA59773C415844B272DC45807F9D641C9443717C61BF9FA9201568868655E0F791910B5077CB77A93E40B85211F9953014D953FD3F8780189840AF9AE60DA1FC6C48D19D88DFC689A8421C28F569BFC5184ED6A66A50202BCB51425202B6428187F0C7A92D2AD1E7A35D3BC7F7D7664CFE9765D217F766A3C068149964B7C9BDB328A7821A9646AD53A8BDED2912C3C714EC81190C966C703A5B9B6BC74C89E2E0635D614624C5371EFC4099C00576D05AA5552B862455FD14641E1E80F4B468CFCA6CC37E032079617C6CC3C7CC68BC8FBB3329C9E28C1CAA811CD6B8BCDE9AB6DDFCC98F9534F3D7AAFF2A508B3237070C39E22B43A424B2AF4EA59C9920D24D6CDA3885CAD8CBC7A2E3B82554FEFDE1A383C558139F9E1808C824829AB0E", + "sk" : "A8A66E47B025073A79D8E2817C64306DFB4DA1390D93060BE758AC111030FC2C3BF6147C63981CE6399F31E5941F65B96C13C9B09A0EE6A08C9171AB262A400A926A628B8CCB307F9BDC7EAA06424C071BC7105637E90421EB1C8DB616CEB2972AE38CAE319C3B181686A9ADBEA05305B258A2A2A965630BEB687FB2F47B9A4A770D1370781B2526CA326261CDEE50CA3EE802A9D5B8E1944B67FB4DB24753756B9EB4289E81F1CDB1684C00C58C9977892EB7CA78B205678A352D3A7592E3970A124C9AEC88B521BC26A368DB678A45682D4208B9E1B099C5CB30506371C8A44B2113931E1BC1FD88A43C91B650C312C733C913835F7118B898A27B7A4A75F927A03FD914CE627D9E156B8153584F12B753E62A7148BB83F83F474985701C6D051110CF270DA672A5CC72C85F560AA7B91D99539224159466387DE5D39F9254B46735A0C30AC40F2B1A180A8EE30BACBD09CB45D52A4BB8336C269A78746F6A337F44604DE7B76690D23E71FA307C315C377555DCE8B26A945BAF1225DF553F518AA453B823FB618DAEE2AA5CF0A60414AF7CF39AEFA3A2FA2944D139869FFA51DC115E2FFAA1ABC7438B776A7B2A869D03B05AA0238903008372A3975C36D8D6067CAA75152A0305B6614C3815A589A332A860A0D1C6EBE2AD2D68B7BFA1687242960F8B8DDFAB9B3E851D4D814C94371B4C9B26C3838EADF70DAA5ABB4952B01A44CF5426B28B4C8C2F66BCA49A21E5763501708AC050B1F8D81B4BD0C0A0E5C171372C877C31882005D65580DA2B33165B87EEBCA160C50EE970B8E1567C9AE1132B65A6BD414117EB4D2A458520A55876F17941F38045B117CE004C299208220C16D10C70124529AC8A10980CB481D069BF0319BD990E34B31CCFE87D3252BF51C2687B234246943B248104BAA9BA21015FFC92877D550F5E0148C36BCA544C1B1F613AFED6AAD1132A91AA823B1ACCCCC3BD43B94C47B902CEEA431ABC8EE15AA32C1B3DA6A605B0B5B8CA905C7492A9BF137F2805133275BD3CD98CD5453943058A668456E9A334302C5872307AE5DB01DE5B4808D477EED39EFC00335F31116653CEE8F81B6F147D4DD9CCCB080C2DBBA75B5310C0348FF8AC88E09895422C371358B248509DF2D46089A5514F919FF271CB44BB70FB61BB2ED88F6D111DD8B38E155103955836BE3812BB255DA8DB97DA862C5A2491892251280C6C9DC779124C08947251F3574D3A5998F8AC8C68881927733FA59816C6AAA629D7893A3313A327A9E2401FFA5C8436F289E167CE68F4A4D232C84C23133D4B7F9B43B7E7AC8060D9BDA7D11AA648ADD452423D91A0C7B3702DA16BFED820C0F1420A842A04759F4DD336B1858D0AF93B81548F2C8CC8EF064BC554B1CC6CCE84968F8BF991649B59F5AB51A6E56375716E1D3074C5849E28F961D75B6F33275819342467E69498A713CAEC4E78F9B6C1CA774B026703167270E14B4209A9B5353CF6949EAF5C947B458038AB9761F6BCBA06785852B78B050D83D70B5C845CCE62CCA1D8723B472907D6C8482224F10318219C42EE848425787640636A7EEB651E2A2BB5207928A68F65A6318743BF7B43C223549590463AC38ACFED84AEA13A9025B2CE04E31B6F647ABDE39D7B1CB988C37F2AB219C67839064481C2539F7C947A5187A850F61BA075A002E4621EBC290855C9E75818E3A99DA9E50522976372EA0E6E201F8CF3C49E4A86C503C38AB764B2F45BFD1718F6B5C0D2E66181045BE2A2A8A1E10BECB8A6BAE9569F42654187A9D9B24C8214ABF933063526804D0998B89C884B1055A56CAE82557455F3A47C677E8E262FE9569ACA0C5B1C0CBBF768302099A4CF3960F9D432A0865031E2B65DDAA43E00AAE05AA39152256061021669B8F2BA6BB31045E7E539830095216A846AA39D5B16BF69E152AA227C61287137E2B29D3931C6211510EA33325B2ECD20A1BBAB9D30A7AD9BF83E3058520606641DD23B092831D29022542513070C8626A42386C8177C7BC1FFE5754EF5B3A2C41F91F1463B7B068816B058DA287B4AC2AD82191D061630337D296A08A02030174A219C143224B4B1AA1324FEB23E7D52CCDC757929342EBCC02C9A080AAFF12763894928A16C1F7830D7DCB2EBD77837D97011001D83F3512F9578EFAC3CE1C0A17DA13B375C44AC8C32E616AEF48339C19A4F379C216FEB9672C20D78262FA99887F92324BF667502517CD42B340B51AC0D0C71C2CA5D357554EED04C1206BAEE66707B10BF52A424FC7567CA023B605A0E160ABA5BE5AFF753983B19938205188FB87A867B6CEA58112A3323C2EC23A92A1C16B48F8CC7BC55C5B18A33B67580CD9383275E7B53D053AED3F41F1A74859F3536A3C07832D4B64D6A9BD591C4A1901C46490EFD73C9AAEC1466528BFDA0AF55FB7A28F4AF2C332DE8024F87567E1EF87DBF3061AD29490C658B8367B0B911BA3C3C91E48189C8BB1CF3A229146CB537958BC1B427ADD62348BA0B54718753ACB2EC3A0783C58C8B6B1023580A3417CC08745FEB9B3F19397FDA09002CB019BE30A8D3781C936847D5C7C5A8E9A7B5D8C18BC5877ED4A8D787A7B11A0464440DA596A4250308398AA9CD482E0F685703058987B63E21C530B3B5367654BC30B86FE6F0645E328714FBCC0F666BB8EB28D7279339F622CB89B813C72DCF5944ECF68E4CE422744ABE30261ED3E127118CBDC1D224E538B48D441359D673470978BD4B5913B6CF557760389B3F6991344D4B622C7A332239A50626CE553A6E0677BDEEA96A3EFA72931B6921A23BE5CBBA9F51166BE80A542B5F341866F78225D50A608E95BDBAF02A599B7A2441537F5124B0D5150A19A7DE9AC2DE2460B80884512C970E7C700AA259982BBDA59773C415844B272DC45807F9D641C9443717C61BF9FA9201568868655E0F791910B5077CB77A93E40B85211F9953014D953FD3F8780189840AF9AE60DA1FC6C48D19D88DFC689A8421C28F569BFC5184ED6A66A50202BCB51425202B6428187F0C7A92D2AD1E7A35D3BC7F7D7664CFE9765D217F766A3C068149964B7C9BDB328A7821A9646AD53A8BDED2912C3C714EC81190C966C703A5B9B6BC74C89E2E0635D614624C5371EFC4099C00576D05AA5552B862455FD14641E1E80F4B468CFCA6CC37E032079617C6CC3C7CC68BC8FBB3329C9E28C1CAA811CD6B8BCDE9AB6DDFCC98F9534F3D7AAFF2A508B3237070C39E22B43A424B2AF4EA59C9920D24D6CDA3885CAD8CBC7A2E3B82554FEFDE1A383C558139F9E1808C824829AB0E51634CB33A2BC3FC22FF47B58D7879D703BDD661AD3C290A6D812485EF0CE8FF0D5EC1BE89D37BEB810DB438778BAC52CDC1FE8F5C27AD825639E12ED908FA31", + "ek" : "E42CDB748CF9B9624854F1CAB8C97ADA403BAD6C8F2A8EBFA180C77FCAF780DA81B5AFC442A44C4B456A6D23EE1D8B32736241FA9D6A3F8D4494AEC1A371D8BF692303494FBA2B5F1ADBAAE5F2D221EE40ED27D3DBCAADC7EE3AF872614DDD37E52F89F477A8CE579BF89FC1CC8D7F49DA6FDD231DE8512A24DC7BC840D2C306E35F7E2D5C54413BC1B702BACE4A081D0FB2CFBA77B824C1E9442E754EBBB142055586B493E53D87730294E132F413802007082808A7BA2257292335EDBFFF67152E866CF2D0943C72FCB1C8D0C41F0642F48831EB758B252FDFCE957F9FF4EDD7CB045574EE3A538155B2F54FDFD367A43C011EE603FC121C52E114625547B348AE18E4A869635DD78240BD8272C2779CC82150D3666A42199F8400CBB921C117584F98DDE53873E398A4FB3614EC87E0879271CC01CC0AB38867589B75A7640034EE2D5DDACB6E3564D2C5B2311C873182C83128DAFA49ECBE47110508235B5746603C3E92525219FF6E2AFA2764406C6CE1E237C0A77D239AD8CE4E1560D26FCA83B6A40A22FCFFBFD5EC8CFAD4E5265D730E0EA9C08B713E6D3F4C8BB0D5CD3D5C582768D2EC8AC458BE14BA37DE342FC4B9A04B98FD6AFBAFD550CCAFAD249D8942E60A9C2A8C8693F032F66D5B56E875D63117D43D1C54F082AFF83718EBAA9155C8BED789878FD733CDD7051568038E0F5F4BAEACFC743B51BA896F4CEABD07D8561E8BA7134704C30AAD68C8E63968F8C13F700CFE2266C69E89AFEB07242A1CE92107D4E3EC5EB7721074D40047E5D8334AE741C36D6949D8379B0B2E126DE742EF64D4C5BA6850A90D27124028343C8118CF60C8EDFAD7AF7F3070EB6FA93F4D4BA2DAB96A9A9F6CD0C9944EAD065A5678604DF783F46473761997049091FE171AA146D3BC8D610CD1977BE7B0B7EE5EF0CD69A97B7BAF7712834EEABD91C3010AAF57D5EAAE23574A4BF946491C9D8A77E88EB71F21642FA367A2F6387BBF3D25A08273F8FAFB6462931AAEA3C67790E257AECFA70C1DC8247D9C6C811BBDA24DF84930B62FBD8C514B60AB6425296CFECF7DC1F5A0E5C64CD686CB8EEF990BDEB34361ABBB0CABF822859FEF97ACFD71A0425567154DAA8A02EBEBCC20CE4D61E58E8D9CE6BD1B2CE6EA95034C9F4D21191F4AB6F7B839841D3B50712C3CB4359B42D47800308BE291555BD557CF1D9082E1136B3F0CB083597CB1193C0D31E8C1BE23B9471D949A25904FCEB636F82822E7D16E8606B9CA364020DC548E19352C27B4B716DA72B56006A4E6AE98D077A25B01D6773A6FFBD0D0624050FBA75286345E501AAED4223DA2C6E6371287D689E3D273677E0BB8F0FE9E7FB23DC6349BB22C02F9AB1D0DC8AE3503EDB9BB8899B062713B64E1F4FD3DDF3982B4D18B1847837AB1AC58E91714256F71FBD27B74DE756A04454AE2E2DB5A12CDAD7F1506665C749B72177377BCB3CC9F25C2956E6373282828D01B87FC8078BAA44FA86147001D13BE9500C6C00BD50AE9F82CC27B747550A05B4146D1", + "k" : "BA80F2DCED001398613F494B2D4813A33F6BA143FFB602A0B152DBE643BCE56F", +}, +{ + "rngSeed" : "5DE720F2D152BF4E1F96A61E7AE5F1BED6B8548E32638C2CCEC9F43B87D1BB43DFCF334F0582984D27E440D519AB662F", + "pk" : "D9F945A651693BCBB0C7A385928129F004263FA16BEF92AE400780966A8AE8750E574947CF6A607FA4B3D252C77CD9925FF3A89E762378EBABE4C413AF52CF969068D86ACB44683222F93BC50BC8F7058DEF77A3241173222359D25C3A87C817461210C6E4C30D4A428BEA8B2D459C4D9C71594C597FB9C3BD17598AFA098329BDD15B1C23222F0F39189FA06319BBAC7D6866ED7953A2C933B3479235790942D6146A818EDFD64227E78BB47168709BC5E490291234929206A3FA1C2EC9359888641D61897927F0440929294439095DB0244A05C20F9678B69CA13268622D174A915A210B8908328B162454C1C0C3C36B8ACFE4BA2C38E0279AC15898F393F01468EB23A8DB1567EDE8B493608D3194B2F2F82E91E739479C35A59267A1C84FCC5A1AC12289B3E5845D0C8E9969BBA50211EE716774EA03514C3B7359892BD4B8D9DB4FD006AF53961687E5B0D0FB9E16FCB3764B1B0271B9803019048048CAB04E60119C8A140B401CC8C5F5770863B066429E71C8AC3751536DD3CBF4E775C7778C15920849D4B1C1B6CA9AC63D3DE47CDA549ED009B4EE7759FDD66EB5555B199022846671B1A819AA732A23E6BBD27605B1FB22B1AA71408B2E55BB651C1A676E13A8E9CBA2B65B246B6683AB20820FF40EAB949EB219851A7C2E1BC1A4CB7B06CF526BFF6B1ECB4B5AE4D05DFEC33DE9504D2EAA4538DC9B9BB39B051AB7D2239AE0B98A34F55474871CF9059E9BF463DDA3895E32C27A534737677E40527313EC993144841BC756E9222D756C3C22E56CEAF336E107C3AEEC9B1DC71131271392B4A4436A14292AA0E24957534856E30CCFF827CB3FDB31AAA086298C59AB71278885308803591513870867A018E61D2705B48210240739ADE4C7100210BBBCB524966A9123AAC92CD711F5DA3B5B614EEFDBC39BB36CDDF47ECB196840AC84A6C721F1FA2F031C022844A64C4433F414A707992200B857ADA964D17C6CEEF31186C248ADBC83CA2A528738AC567C4C8AFBAF8BA57B3F42700DFB8C563B5E494C6679E69ACAE47A9BB14C79396BFA2593D63224E29CABDD0991101496A0380AC19B759CB0220517ADED8371CE74667DC827C1141A233709FC47BD5EA6664C0B6C2182AA9A088DF3C92BB5E6047C7B03BD9C4347DB41EFECB80FBBAC90662C0D56B8F91B3F3B7B3417D592994771EC3695E94CC3AC73747F279984B7350ED9B9400201ED35B785F0629225AF64B05BB5B6016EA50A8689C9CEAAA234748400DB67EF9514E7BA63C683B4F5F6B35869586F0058BA7B9C4BAC500A0034BCE3B2BDA7C5FD5C8AD37C6466A9B877278B7773AC79809222F80EEF341236053AD1D0C95862796A9702FD977E820420D611C66163C5CD6C5FDABAB7EC96A51BB24328617E375367EE616ECDB46089C6604909D055033D53D828C7F8CD6DE0823022BABCF521AAA67959C1881161620E397B0A25682CBC805A96A84BB84A9A99ACFB6012E2ECC2E5BC1518036E40DBC3347CABA399178CA912EB8367C86070833137D1BCA5B5B3186AD23C2E76A4CC467D092102BA081494BC7F963A9A6AE575D2C57A38371BE5B164ADF29F392014D11522535B0173126BFB82721E153E74049C1E170144484DDDC2716B4C487AA0398EE9CCD2804DF58FAB8E2D32AC05BF22A8", + "sk" : "A3854BBDF04E2F617B377BA9D5C1652F27B377BC73F4828FD485AFB4C2A7EF05A02B1A1F06A707D68799BA1094F1208E52C9C44EC15580C6599CB244CD2617714C7EA5B07648F91D2230BF35A6910371289DBB7A6329436C4BA502C83633B64F99CC16F6C641FF62254C65511584CBE208A080495762EAB49D57253063A50FB45F61544D6AD39A4A0003C4E05D193A59EFA80949E1400643962E896C0C9A0C2AF30E586C0821388292768538137195009D907853AAB7459925498CCA238419977C36BBFD326ACB9832AFD3B46D934255A10A0AA0932A7ABFF1402DA645C0D2CBA5D03ABC21E0C09F9CA9F28032207A707B21619F7521B9A228386C29A89C53C38B8BD2DB9FA4FBABD79421551B6F4E1C489C0A3692E695C73B6F04BBB2BE72516EBB523AD794E9101B4CC6B7B16C5F7C2A8E41AABCDDDB3F070A5DE22A52B80165B3C6872F279FF87BA6EEA982BB741A768640D70797724841699C45AB10A522B74C53E55A8A8968AFD6BA69BB39EB4489E47343F807424EBB8B4AC8097F43B2BAB8CC37990CA185A19C9C6B28DBBDB7822517670CA050BA28D724176A7A3E887BB47BC4DD648B41CBC6B52656405CA5F4E7CB06E64477B2806FA3B52AFB3533034CF4772E4A383563AA5A057A6738338F92D9070EC94AB05489E278BC6688A98C2AB7A18AB86397631751C47DF75BA27A801497517845B99C0B692AFB31C95A78F96267CBEC760743CF92140F1ED46F1CD5840D13CE1DF028238C941C6044511592D2520188E86690707092EABBE9505CFBA46B710B642FF2A87FE7A3D5431773378E5EFB378E627058000B4921AB6E6368677492B2EB2EE219CE2E6633286B73863451CA01CBCFA570B806B5D2D5A2FC237C44D0A84C0AC097B8B299446C63A47F2C93A87C95C4B02A3D160BCE70125C9073CA35F663E0EC64A189565460B8DA009778A8324DE7211D072522476418A6C33C17046177359F9BBE5FE72D2CA483BAB4BCC05440FCFA67C17C326331B65A04ACF68C1AE870208F41C66057C3483C8B2870A3308BB90A5CA085EA8C15891A39A0AC3B09297C99320568504B4284A035BE76380E368018394A66BE5B2F45DC3DDBE6179AD60860123D55B28D270BA24CC0A49AA5A30BCA256D7148EF466B468C06CCC8C2CE439E75953C07013999AB77532B13C9E477905997FFA42F6B28C90F9471FF6B2477E7B311B34C89277803747257791A7325CEE25246F656CBF57391037A3E90D74729B16B1A5175ECA2871EBC7E4994B3759089E215933144909991550CD812F8F29658852EC11B3B604AA07E47C5DB88C98143467AB358DB51B5372124AF9C983E542E74BA6F273943A646065E603F11395D92CA09F1771ADC29C6BC202A9AC159EF356D3934A3A9C073AD459E1DE4BB1D81BA30143302013D7043776DB346D2239DCC81305386628A2C1B364CCC606804604669ADA153CE5A7E6367838A6CBC8971CA750342170509E4124C09846314185387EC47A501A0C5243ADB14C39C1105938292F09AA117A5BFB4649F8705696097466F25B32C4A382C877D82D31ABDD6B364B936F617B532B29C837A375846BC44635C8D55A5E5DBB44315090602830AD70B50A1CFB92723D9F945A651693BCBB0C7A385928129F004263FA16BEF92AE400780966A8AE8750E574947CF6A607FA4B3D252C77CD9925FF3A89E762378EBABE4C413AF52CF969068D86ACB44683222F93BC50BC8F7058DEF77A3241173222359D25C3A87C817461210C6E4C30D4A428BEA8B2D459C4D9C71594C597FB9C3BD17598AFA098329BDD15B1C23222F0F39189FA06319BBAC7D6866ED7953A2C933B3479235790942D6146A818EDFD64227E78BB47168709BC5E490291234929206A3FA1C2EC9359888641D61897927F0440929294439095DB0244A05C20F9678B69CA13268622D174A915A210B8908328B162454C1C0C3C36B8ACFE4BA2C38E0279AC15898F393F01468EB23A8DB1567EDE8B493608D3194B2F2F82E91E739479C35A59267A1C84FCC5A1AC12289B3E5845D0C8E9969BBA50211EE716774EA03514C3B7359892BD4B8D9DB4FD006AF53961687E5B0D0FB9E16FCB3764B1B0271B9803019048048CAB04E60119C8A140B401CC8C5F5770863B066429E71C8AC3751536DD3CBF4E775C7778C15920849D4B1C1B6CA9AC63D3DE47CDA549ED009B4EE7759FDD66EB5555B199022846671B1A819AA732A23E6BBD27605B1FB22B1AA71408B2E55BB651C1A676E13A8E9CBA2B65B246B6683AB20820FF40EAB949EB219851A7C2E1BC1A4CB7B06CF526BFF6B1ECB4B5AE4D05DFEC33DE9504D2EAA4538DC9B9BB39B051AB7D2239AE0B98A34F55474871CF9059E9BF463DDA3895E32C27A534737677E40527313EC993144841BC756E9222D756C3C22E56CEAF336E107C3AEEC9B1DC71131271392B4A4436A14292AA0E24957534856E30CCFF827CB3FDB31AAA086298C59AB71278885308803591513870867A018E61D2705B48210240739ADE4C7100210BBBCB524966A9123AAC92CD711F5DA3B5B614EEFDBC39BB36CDDF47ECB196840AC84A6C721F1FA2F031C022844A64C4433F414A707992200B857ADA964D17C6CEEF31186C248ADBC83CA2A528738AC567C4C8AFBAF8BA57B3F42700DFB8C563B5E494C6679E69ACAE47A9BB14C79396BFA2593D63224E29CABDD0991101496A0380AC19B759CB0220517ADED8371CE74667DC827C1141A233709FC47BD5EA6664C0B6C2182AA9A088DF3C92BB5E6047C7B03BD9C4347DB41EFECB80FBBAC90662C0D56B8F91B3F3B7B3417D592994771EC3695E94CC3AC73747F279984B7350ED9B9400201ED35B785F0629225AF64B05BB5B6016EA50A8689C9CEAAA234748400DB67EF9514E7BA63C683B4F5F6B35869586F0058BA7B9C4BAC500A0034BCE3B2BDA7C5FD5C8AD37C6466A9B877278B7773AC79809222F80EEF341236053AD1D0C95862796A9702FD977E820420D611C66163C5CD6C5FDABAB7EC96A51BB24328617E375367EE616ECDB46089C6604909D055033D53D828C7F8CD6DE0823022BABCF521AAA67959C1881161620E397B0A25682CBC805A96A84BB84A9A99ACFB6012E2ECC2E5BC1518036E40DBC3347CABA399178CA912EB8367C86070833137D1BCA5B5B3186AD23C2E76A4CC467D092102BA081494BC7F963A9A6AE575D2C57A38371BE5B164ADF29F392014D11522535B0173126BFB82721E153E74049C1E170144484DDDC2716B4C487AA0398EE9CCD2804DF58FAB8E2D32AC05BF22A845CCCC2997B502ED631257065214AB9AFED11F00CA5C18C92C4D6B917165FD1C91FD1369E8228B3979984C15440EF268FD3629C186D6CFDE02B0F8A7908A7EE2", + "ek" : "9B7E6CFD7BD26B2400FB4AA9DB8ABD2C725A1961D5CC5348D976083086B256C909A7C5E028F103697A5C9B3E2CDB50907A60068A0B30F305016A399399C3F2B118F42D18BF9AC98F8B5DFCCC2EAABAFA9ABCBDBB2E33E2D1CA1D253A1E32F0809DAD0C916A48C3A18264D2562C0365FF1BEEDD2783D67C7EC297BE3FBB572CDE89AC3DDCA5EE3A5424E4DFA359600330B94A3D22D599A60FA01A26823F823488AA7FBCA36A73AD72714653F0F1A12B8AC74193B2E4E88F630EF9527CE2F01C21ECBC98580AB1B73596EBF1C1AD2A9B4DC27B8C4C4F4D0BA93FCAC5CA3C38A02951539DAE47A6A1B4789F49ED9E777FA3231B0B1C9EDF3A141FEC02DB4E781E00795611CA233C67EBD2F110786083E3919273A89548367793D10B4BD43752A87DA5A4636339A5C5FA159915CFFE0F41A4F490CD850924B3BDE32FA3C3BA7E246A051AAE7734B7921724AF6FB41066B88805B91A533B0FA4550CEEE7290E45DABEEC8C1F5C12817DD2E10EFD638EC262850F4A9CC7CE47730720545B4F50F1B2789DFD5D471C86D7AB0C231BD40E47660DD8B0412A52B5C28CD953C608C3988A6B8168FD3C29485555DD11C297A603B91975EC738776EE8C0B0E17710867D8D9DD8822C61C83283422B3350E8BF1A10FD7F4D1D670BE94D9E623B15EEC9A4A44BEAA2444ADF3C564CDF4867951CA92074D0C2BF1F66665642C3128FA82691A652F3C695926B7E3C0A0C9824938B97BC74D890C913E1802927D523436AC49C65A87F80947B7AD2D0A54FD2866D2FDEFFC666755FA8D19E5DB28722A27AD78F4EEA93014B76415AD9FD7ABC7C2F993E0047A50BAE6E93C78F9F6DC2F0339D1100CD1CC70415740A9C9CB0CD21C836554037BEA7256F474AEE3866EBF6140769F0EE104DC6ECF5506F95F67ADA1A3B1B13FE5E9392FB8F965ABE2FEBC312C182C081A0E2670C4F3E51D9E019BE49DE6ADFBDEF80851048CF44A89DB5A554DAA9B48CDE853B0E67C38BDD069CE7892FB7037870054C0B90D91C4D06A435F7CF4282D2DDF7DD84EDDE265BA60A3E8A00A322541B9B927B36E0B2AE9680AA3F429D7CFD20C5E3677E1953045FFEA83085688C58A753AFBF624B422A45438D589B3A1EC7DB32BD736E07782779C76F32BCCB53F15D4C997E9B37BE1631EAAE2AA5C6AFFC2AD2DFBDAB4A95AB58999091B086AF8A4F6E7C0D702A3C4AF14349BD478BB906FD0C21760CA2C972B904C528E2E10178EBC72EA788187469E5A61A7D480F0C7ABBFC2FF492280ADC9041F0B7ECB40AA5AB9861DB89EF274A6BEE523813488FDDFD6C202E66D4A8142798A0AAC23EA3B9CF940EC4E1B1EEE6D7671298E6F2D028DEA128ECACD9137C2CC1C8B779FE302EF5FBFB9237DF497BCE46FD14AA4B3F8DE540791C2F13B2EC01D99EE754037AA7A5186C854DC1DF8DEEF9B104C6AD689E4E2FD9E383B6E0CF1EA51C8963110A7CE3E54B677C1F172309568193B0A6521A2FB458436C925596985F490A23791E1ACCBBE74076FD0BD019F942EBCD1EA6F9B", + "k" : "DC1DBEB960DF951444FFF4AA9A0CE6FFF36472DC912D69EEA71BF8BAE94BCFCD", +}, +{ + "rngSeed" : "D71729DCBB27D7CB39E9E905025D3E55C8602EFBCC483C9B866EBF82326157833169243C14550AD728BD1470F39C642E", + "pk" : "698035EDA89CFF189F730A05DABB3254297561072317010327D4222DE388A7E95D8D0076665061705209D59984540471FC61032904B13DAC27D520A2B7CB653A68A46623316557500CF4BB6F71AC9B5CA17D45331FF06507D5732829AF25417DEFE7ACA7364D99041448328F57D94F1AF2572F7468DA3B9F2E432064144F0396C1A8D95CE9951530A3B33B092D67590B307944095C50C30762435B76A5DCB3AF494A5B112FEE2567664A376F3B30C32172059631318821DE71AD62B0227D9A91530A5EF2E6C2ECF925FB95302598B722A991E989A1FD198836FB340FE44849CA144545A5A14B46F464078529BB6DAC09D148949E91CB0D7912F8701D84AA48DDACBC1AAB0A4EB63F9BA41465F03F1BF4B4285CAB3E315ACD8A3F79C465D1D31FB50670423B278F042442E2B5797483F5A2BD21E83248E3039626006D7124A324281545B8C4356396F413A1FA67577C5D15C638B7D23199AA5343473DD5B45B66F41D451358F74B82A3C18627A60C08513D34E14E3F2A4B13D7332FD8014FF817077B7EE2DB80A9C00EB1DA79C2193201996036D214EE7B238D82AFC2E3A226159AC05240E6683AD00A55A006190A279E116626B4F70FE345594D21A8D54B9017A76D6E2A61B9585BD5E378875CA26AC071D6B1546EE99D716CB8587B7A4E184C8119CB3150611389A8CA0BCD1AB6A7107942769CCE08C00174A19305D438A7A475F2A29B28D230A016479F8AA8DA24273C15094D3C0E10A8A0F0D3344169B81CA508E6CB662A4BA28C8693B9A27BD46A35ACBC27A6B7CF30292064B4AEF36BB29909AF11D8924EE59AF80B5871C2BDF0C53830A360688AB31A94CDA3B12C0F61CE341BC0566CA6AD1CAE54989AA3083707EA74680AC1FCB254FE3866BC9C7FC33189D3F4299A8A0A985BA3FBD51FBAA45D26AA352EAA710826AAB8F600FF8A9554C842657A3CD2D6588F42063E9C08E9955AB7F3CA032B440C7889595A3454025853BA4070F1CD09DC26392B2657C526052373EAC80C920C58C3A24827456BE174842ED722487C64373B2457836F13C4065DD7B555F3914567CD87426E1196BB03C08C7A77C77D586F18E9603F45B1B9675BC62A4E71F215C3D7071729B0A8E9069F35AB73E55948F9C3E766C4F150394716B198721676495416E54841908CF60148A7104A4DF00F21A10FCF508AE9438BA162291E5245AFCA757CA88ED577057F543921F670B262A0022A4EA4044318A4B1AF8A99CDAC8E1E550B732157E8EA9194970F786665C817299A7914B4C0B3394A57ADB179BD3067897421A09410A34C658DAABE6250047BF15B76F826BD371F0C504A2CF9106ECA67816A4865B60A87D48EF4753F90132663FB26A5FA08C59394B6770AB13081AA200C79A6802EE826396CC9B3EA9CBFB482D601952752758CB7CD18605A9336735EA2322BC82B7BCA773BE27F17BB8726A8CFA9070B9AA6A77CDC0B64081CBFBAB45C4314F855A953231C6FB6149BAB90707B87239C2F7C7103BB9B2532180BC1F16670D90B7B77C6028C4D4BF92195EA54BEE1150C25CC363C57F812A0754C9BF66470AD820E12133EBF44810B7318D2A79E5EB98C17C40B0EE10179F1B5B6870F26D27EBFB588F3A0D02E10A041AB4E3B97C35070F0DA64F7E0E7076AE69B2AB51A956CFD04F8", + "sk" : "F1CBC95BF8705EE2AEA2832134F8B633A20A3F3B6A82A2CC688728DE320944CA5E74B42744E4B2BFD860AD6920F671C4ACE706CE8903E0EB9F434364D1C09AA3F81303B195E704375ADC01242907F12173077384493049A136821CA239C7889FEE120AA015813F987611101BBBA9115A026C3766264374AC28B0C9C422B844889DF150CAF94409FBE61F08DAA4DC4B6BC3E0C866F82145FB813DC88BEE809177B13C2DB2CE1C3B8E8C93C8CB86AEFF1383ADF0AFAF5600BFDB178FCB56C899569BD497AE05186F19CD9E6BABA7CAC85F6317792BC6DA6C6222DA77B100595E84A2C9A9B9D9B131C9A0514E9C8C59C3B1A12637FFF8353D468239358834D11BB0FB0CF6F37A461132F8BB5559B26EB03C0E36872399CA6E5B18A05AEB934516A484116CCD72BF780379D82C396AD39EBA5B48DDA856E0C82F7B9C4CCC36B20054CF5D1B2F0EA00333527C6E6977A775AA2D58B180609CE57346F9E8A2B686B7D85CB4C58A2BB938B26DBBC6CCD685A6E309838C9FE2E335B74462C2F7C521490EA527AF3DBC91034C74E3E94A69E42FFC290920D64F4D662FF436345C06C242749AB140121AE330F254478D851D5F34048C2AB65C8460E8020499C33B4CB9851985817C62282DD49DA96064FB2881E18697696960D9A52F409A2E3136368C0C5146AC3ED3B4AA580C143BA22EA9255397203E95C4416161447698BDD6DC462FA5CBFCE3933A3CC26B2CCD5295C3E3B30429493244F63B811640F2111E86B54146D59B2E761C793B4920939C88A0CD12C882EF8192FAC7BF2AF22C08580BB4E20226AB02428731B72A81CDFB654EF9286B73713ECB2C90341E78A8B0D6699F59230B298A658648109B003840A2424ACA7D30D7C15D3704FB88C6F66592A04AB803E83EEEB4294B2BB5C6F957B65A6AA8C88A88F5337411404AC7CC76857AEB3AC07EF32D8BF0402CD135969669E2743CE7F8060CB06BE964991E797923BB291CAC6E78A8C55C65A85D402E2184491E474814086824836405629F0E68CD2F86691DF301F00BA2ED971FDA2222E1322101130FF1F1A2D870280DAC8CB98A29F93870047915146AA8A486AFC16CB4D01458EDD0B4D5B027FE2A6C4A884EE93A495A5C15AF938E5B37AAFE655EC6220C0D88557801890E6805C80A3B5E0C395548A19F404A4A6286E041A95506BE194A7AB1D7AC21F52932BB3B5F5393E5D5173D2C7C8653B9433344AF489F7102199523BB401CC75D80C8CE1162A69627E3A743B3201534C9BC21243961F7011731C1A3E01FA3847CC08BA7D1970E2E70B3F0C4349E707B40BB9C4B5519B8642334A97574529FDE05927B25B8C13BAE1E456B87D90087551D0C2918A3658E9A9B7DFC105AD9F0CC7A180BD0D0AA5042702AFA02FE67801137A1FABA5813F2BBCEC3B05B1ACA701385E159031FE9043199B07AE02682A0861812749294BDD42B6D09330248FB52FEE84E98B68B49830508197A06CAADB913295095108F2AB2B4854FDBC44742C673D0F55626E726D0BA68AB3508B7304D767B7F868676DDB33C917BA37B5B0C8A831756383235B81E872114278C2FFB29668DF706B38153BF7B39A388B9CFB38066177B0695A511B0C9E6C709CF0CAD698035EDA89CFF189F730A05DABB3254297561072317010327D4222DE388A7E95D8D0076665061705209D59984540471FC61032904B13DAC27D520A2B7CB653A68A46623316557500CF4BB6F71AC9B5CA17D45331FF06507D5732829AF25417DEFE7ACA7364D99041448328F57D94F1AF2572F7468DA3B9F2E432064144F0396C1A8D95CE9951530A3B33B092D67590B307944095C50C30762435B76A5DCB3AF494A5B112FEE2567664A376F3B30C32172059631318821DE71AD62B0227D9A91530A5EF2E6C2ECF925FB95302598B722A991E989A1FD198836FB340FE44849CA144545A5A14B46F464078529BB6DAC09D148949E91CB0D7912F8701D84AA48DDACBC1AAB0A4EB63F9BA41465F03F1BF4B4285CAB3E315ACD8A3F79C465D1D31FB50670423B278F042442E2B5797483F5A2BD21E83248E3039626006D7124A324281545B8C4356396F413A1FA67577C5D15C638B7D23199AA5343473DD5B45B66F41D451358F74B82A3C18627A60C08513D34E14E3F2A4B13D7332FD8014FF817077B7EE2DB80A9C00EB1DA79C2193201996036D214EE7B238D82AFC2E3A226159AC05240E6683AD00A55A006190A279E116626B4F70FE345594D21A8D54B9017A76D6E2A61B9585BD5E378875CA26AC071D6B1546EE99D716CB8587B7A4E184C8119CB3150611389A8CA0BCD1AB6A7107942769CCE08C00174A19305D438A7A475F2A29B28D230A016479F8AA8DA24273C15094D3C0E10A8A0F0D3344169B81CA508E6CB662A4BA28C8693B9A27BD46A35ACBC27A6B7CF30292064B4AEF36BB29909AF11D8924EE59AF80B5871C2BDF0C53830A360688AB31A94CDA3B12C0F61CE341BC0566CA6AD1CAE54989AA3083707EA74680AC1FCB254FE3866BC9C7FC33189D3F4299A8A0A985BA3FBD51FBAA45D26AA352EAA710826AAB8F600FF8A9554C842657A3CD2D6588F42063E9C08E9955AB7F3CA032B440C7889595A3454025853BA4070F1CD09DC26392B2657C526052373EAC80C920C58C3A24827456BE174842ED722487C64373B2457836F13C4065DD7B555F3914567CD87426E1196BB03C08C7A77C77D586F18E9603F45B1B9675BC62A4E71F215C3D7071729B0A8E9069F35AB73E55948F9C3E766C4F150394716B198721676495416E54841908CF60148A7104A4DF00F21A10FCF508AE9438BA162291E5245AFCA757CA88ED577057F543921F670B262A0022A4EA4044318A4B1AF8A99CDAC8E1E550B732157E8EA9194970F786665C817299A7914B4C0B3394A57ADB179BD3067897421A09410A34C658DAABE6250047BF15B76F826BD371F0C504A2CF9106ECA67816A4865B60A87D48EF4753F90132663FB26A5FA08C59394B6770AB13081AA200C79A6802EE826396CC9B3EA9CBFB482D601952752758CB7CD18605A9336735EA2322BC82B7BCA773BE27F17BB8726A8CFA9070B9AA6A77CDC0B64081CBFBAB45C4314F855A953231C6FB6149BAB90707B87239C2F7C7103BB9B2532180BC1F16670D90B7B77C6028C4D4BF92195EA54BEE1150C25CC363C57F812A0754C9BF66470AD820E12133EBF44810B7318D2A79E5EB98C17C40B0EE10179F1B5B6870F26D27EBFB588F3A0D02E10A041AB4E3B97C35070F0DA64F7E0E7076AE69B2AB51A956CFD04F889560D4E598328F6302A9762BDA2B0F29FA8EE34FE48DC4847810FC6F44CC198AC8557EB61A3D4A2400D3A604092CC3B92032F4D3B563F3D4AA19387EEBF2A76", + "ek" : "0CF4BFD66B29C894675E2AF42095E8D55F124DDAEB9E7A9B757753AFA1A98D1F32F7361F5BCCC8BDC3E91C891B16F73F3DB06622D7F05CD1ADBAE043210CE6938EC172D071FC4575CFAA7305623B17D5B0FA4CC020386D5091145D12916714E0107834215FACA9F03CD001FB2C1645681964B7A1EF888E8FB4D4FD7A88CEB1F01538028B1CE42933FB0D067BBB57B89CB9D97AB44646FA228A32D3F0077FC6DEF83BC0FD38ED2087FCD1E69765AD4ACED3017C26304270109B721872E0DB4E408826651C03CC1B20D4951B1FDDB57297E9DF6BF130D05BC9AE90BD5D5E63F27B0D999DFAC4699011D532901B530339B9CC522A18A229557CE70A97C0F6A2189E261B5C4E68DA2AB282BE3E4521AED63D0AEF969A7C43D7F17EA06912C79B589F7F811BA26B04AD3CAC52A2264641C60C6F5C3B4E9D9FE8FC60C30C7F950492C0C1DB9280F9D384A5A05B8BFC9C734A1D3F6B37AF3044F4994D4545A2A2400C83EAF2174B33E32E5A677BF87987613921EAA31DA8A478C619F969C9F2AAA7E9309BE4C330DF8AFA99C2EB905A5C8E9B2F54F51BE050D109A5341E549EF0BDEEA58091E7F8FF5E3A7CE0961A11FAD2BD4521D0B3180935C2F9260BC67F4D7179CF205513775BE9BD6F92E0E418E04C1239B51B0DC8774DC7210B2F88694F706FF4521A9E431DC511E787A37C8BC51FB2231B1FC7CD490104224662641D54B27BAF58BE201EF73821E5C5C03D199A4AA4CD1CB613EAF7257B64D0B4795E4A3222AD68984C5D40FC7B6D9271F5725DEF0487C34209E7DC73DD334F3D59553B3581D87244E44AC685723C24F7555181190C43128CE159BE80E2F003CE2B9A297706A42BA9FEB283516C606F50ED20D7CC040BE88A9C6BB96D57522598F0206F1CD327AE834A360C4BF262DAC6395CBB9231868589ECBAFF2AEE04C6F2748011D3E7C7213E31E3F4D05A622052999EDBC1E790D2C274F3A7C06EAE389BB2A721B9EC258E878C6D08F96AC12552EA6D5207129FFA332C1934E33A6280C85A657518CA3EEDC31B36D97B9540ECB744BFB9C26583561276B9B055D5F7DC8C0AFEE7608EEC42DB0DEB0E7419BDBFBA15086189C4D22216F6C5E6440144D437357EDB3FEBAD8C23A65C06600696C83E98D2E0C44E20107E6DB0147F27129057785EE4FBDCF1D65CDFBEC3879FA038329FDBB4B5EEACA470F401A982E7D774540794F744F2FA201410B99BA1FED5145E3AAF00DE2A0613608087DEDF893EC6FF13770426774B841A00ACC08B8CD96AA88A0D2F9CE4372CCF82B0693409C326D2C1E6DC1E7AC051A8969BE481DA73D50F0A8CB799EF2188B3081821DCAA402810F9FC709FD024118D3EC4C19B1409BD7EB6E4DE9964633DBF119C73FEC887B5B57DDFCFBFB609332F7BA82B8BBF54764652C889C1ED3CC4BD9ED31E100BD60EA21134DD5E7866AE311AEACEE74B466211756F67ADDF72D4903924BF00652458405C0C607FACEC04E81F62CD26441E8D75C009B7DA47169E0D7C5150331B85480F7ECE2BF793DE", + "k" : "F158063AFCE0D8D7AAA0077A98A9CC5839D7DFA5E82CC272B81E14FCFC8EB0AB", +}, +{ + "rngSeed" : "A7C2C8EDB3601396BEB2DF0657EC82FD5780A2723581A9E03DEE1CDB018440439BB1142CAB0487C5D136E9AF46338AB7", + "pk" : "4981B339E1A1368287FC699E4D50BAB5BA45320968FB7CBFB358C92E2564944571591211B510A5B044663FFC7DEAC3546A8AA060537BF36229BACB4C5D918726B5AE7DFAA45F153F329140106A80B3C54EAF273384DC8E47F58E68621F3BE905ACE09A76EC9839AC471F9404C196587CC95D90166A247029AAE0802AE3CF6983355B330BC9C6A4748A6130AA510CA1AFDB876AD0D7B2653C3C88079E14D7898EE482F34651B7A238F3F07BDB4989740861D358384A4863C39B8912259BD78653386801D2450CABB6BB7FC287C74B2CB24C5688B66F7952C289EAA5051B938FC833F343C273652E4A1A6EE6C35C8C8131EBB63C82D38046B41343FC0FC660168931C899088C92DB171F75B1F691577E09CE56435AB060C8FC084068133CB67CBB0FD36A73D8A21200623EF324256B99B0F60841BA9CDA515F62A978881318FDA87C95664E4A5755C72026369813DC90C8D6C18F48D61C10E49A7E9449F95492F0E4AE14F6969B654FD39BBAC79C7E0B507559D5137D2179B59B21DC60679CF1B455B94208D87514C008898A95747CA9B530164743A6F9F1878F7BADFF6A4B2023CA367944F288A399C52648F834C28014B0F921EF04127FF4AC656196C034C0DB9A7E8CA64109B904B2427FC601732C12241CC32589790E3BB71D924C184EDB521D3B090A90CE0B296365EC6911341AD4D8CC7C136C87469F1FF101FAF3488F89B52E98B920A659375125B48C403B4BA3175BBC6CC5A2CCC206DCCA0440D54C6DAC74CE4674E46444DFB4B5070926074C089C28C5CB11CD4C9C715AF34AAC79644CF2AD471213889C5E7BA92D114150233C673E505376F21DBC999997F43FF9C3B0F8F1B3DEC09A4CA3AC581B9192984E43999F0D34AAF32218B02C8AA2F21C579457F204BD18191811E7BD6E4AACCA5AA7C6F41FDD192BCD24760A2243034021B192575BF811E1344A25E1629B019564C39B09C88EF9B1CE6761066030BAB14AC202BB6A8D858C3FD316C4FA81D21904AE691F6FE7931DBC93AFC09F18F3B278E4C453AB5081372C093A9A38EA1622379F56397EC6C47CB7067FEF7225C952C262792DDA68135E45C3C6CBAD23593FFDE806FECAC55D682FB23839B37186D4A40B83641D9214B7E0490E305807745534DE18B9D4BC5EEA755CC117B68B7A30F76A9458708249F02DFD59691F0B720F257F1F96CFCC3573C5696EA33017AF14A843B81EA58821DB21B73A9B80CA187685DAC1F8735EA219CD01C6688F5BCAF4611FB3B58AD65B8D7C8BA4AB950BCAD9B23D5B2D0B718397E111FEB25F1739CCDBDC5C41D943E977AFF5209134722DD3D54B923B511661127B284AE9BA0C27F05AACB20181602D9BFB32C3E255E7F48735BAB94E515529A9591D51BE015A009A9094591C7E07A13C57E636B6E11CF4835A8180895A6581507805A1C7A39AB05633798AEBCAAE89E37D8D75B4F34C73C2184FFB567069F0B3911943C2060F34F10F835C8233A34B5618501AA36EBF678DAE07AF9A567AC7143567C92A89A94A0A4ABDE383706CCC3826A83DFAB8AE7165C6C6555BC77A43B5B3B2B590C56CE25E792796283737C6F5B300A0CF06E0060E1634A434793383860D84A76807C2983C57522FE3F988486BC386CB335AB55689D6B449B7A38DBCE911F512E4F148AA1567", + "sk" : "61D034B4827C4405B4CE0226038C1E98F42CB587123EC8A44454C38D4407D5FBAD7068C373EC34F303A6C4272990957C5803536618BF07418A9397CA03A81EB4490762DA41AA5731A8B795E077CA1DA336279132D785B9816819F58CAD7804BBAFA32FC501A5F68981C48B4E06A7088C2784E917B0645CC28116904EEBC3417C525CC312A3102DB9D97CEE85827A1775751CA137E117A217A6FCB4546D946CED119C6B1C45A2282415E9C11D6CB18D22616BE6917A38878281BADE6241410A42047C156D0C6FC5DC8060D9046FA658727B8E4E045548A5909A9C7139391E058722C7969B0B48C737B3A092082BFF215E98D8AE1B09B50C25176B2764BD414D84C57EC41A4B8C04C82EB22A2E52AD200A6E127968C844C8887C014AC99BA8F54067621601121DE01C8F5B923FE089584AE181FE8CC353F12390C565332A7BD8953F97E75B2DEB83FE53B3AAEB9F4A02ADA9401FB339C9BBF09BC6B826D9D0A1CA5A563A8213B8858E91050994472DD9F1C81C831D8096B72F360A65E194C5B758B37528808B9B48A65C9A04B34CCABEA12CAC24599F2C366646581366B71AC7724F01D833A5E76126617BF7630886E44DEDE81BBBB44DE625BD89E41AE0E28BF897202439C346A438B1A8B518698AF80418548664AE3699EFB8271E7C2EE995731D7309BEDB87C2572A6B805F46654A92D188CE661B9E197203113446CC5FABE73A35B97CB417297988CD02CB8B3E0498130341DFF42A85281F667ABCEBF576FA266F44B2368C926385CBBDE21621094C492607CF58227C2A12A8ED79C6A726A7CAD81B7E9A50D78417619AB575A3C54BC77F5A80206967029AB92DB447B0914168D8B37BE0438037E2BB3EEB95221A8DB95B07FB252044760832513BB0A7032E493ED529267C278DCE0B8D954B4FF0BB62785C6D24328ADDF3608C50C0B9EB5E3BC685FE198BE984735764BEA637B4F8A149BCF356D8A57D21B426B736CC8E9B396AC1577F41291F433CBFA04697180F623A6564C8C1F9723896437FE216715A30820DB78F7F0A78AD2AC034F701EC129C95DC49D8EB3B7A585AA00046876A7456278BC4A617CF9B8F06E89AF742C14DE2A7516C65C83BC53C3335DF6C00C0B344F79635F232420EC893D9E29A36986DEFA37403354624607E343B82660B3597EBA841B250A15574B009716B4812D5B175B88929D3539E3FA97B3A16644FE6BAC74C67DB2832A9E8807EB9745ED0AFC0025EE199B39EE3954A112BA484B3528838A4605EC659A046B1722DA037F9E2B007C895217927D9AA8514AC263A08CDE86720CDC012FCC84F7A089CA7C51F4ED71D7C1379FD34C713CB65CE3410214385DD6C91CA1B74A3B24BCD45B5CA097A02359A70008ADB82921F7A79B30A8689053F0340453E6B9979C8C522F606EB4C72A30970C09562D9FB00899C2127311AB57653B5833035AAB95C61C50680592DB86718BC6A5393A96C07907748BE2A9C2C2324CB1247876B9C3A53FC2340E32ABE72B39EE59E284A62DAC56964C721C3D305125A22A94B2B981A5F16F7CEB6A72007C92EE110362DDA1DEEB28D26C5A5DDB58B4B665F1AABC8A90628ABB65E5769194EE98F61EBC4835775EFC50CD5136A4981B339E1A1368287FC699E4D50BAB5BA45320968FB7CBFB358C92E2564944571591211B510A5B044663FFC7DEAC3546A8AA060537BF36229BACB4C5D918726B5AE7DFAA45F153F329140106A80B3C54EAF273384DC8E47F58E68621F3BE905ACE09A76EC9839AC471F9404C196587CC95D90166A247029AAE0802AE3CF6983355B330BC9C6A4748A6130AA510CA1AFDB876AD0D7B2653C3C88079E14D7898EE482F34651B7A238F3F07BDB4989740861D358384A4863C39B8912259BD78653386801D2450CABB6BB7FC287C74B2CB24C5688B66F7952C289EAA5051B938FC833F343C273652E4A1A6EE6C35C8C8131EBB63C82D38046B41343FC0FC660168931C899088C92DB171F75B1F691577E09CE56435AB060C8FC084068133CB67CBB0FD36A73D8A21200623EF324256B99B0F60841BA9CDA515F62A978881318FDA87C95664E4A5755C72026369813DC90C8D6C18F48D61C10E49A7E9449F95492F0E4AE14F6969B654FD39BBAC79C7E0B507559D5137D2179B59B21DC60679CF1B455B94208D87514C008898A95747CA9B530164743A6F9F1878F7BADFF6A4B2023CA367944F288A399C52648F834C28014B0F921EF04127FF4AC656196C034C0DB9A7E8CA64109B904B2427FC601732C12241CC32589790E3BB71D924C184EDB521D3B090A90CE0B296365EC6911341AD4D8CC7C136C87469F1FF101FAF3488F89B52E98B920A659375125B48C403B4BA3175BBC6CC5A2CCC206DCCA0440D54C6DAC74CE4674E46444DFB4B5070926074C089C28C5CB11CD4C9C715AF34AAC79644CF2AD471213889C5E7BA92D114150233C673E505376F21DBC999997F43FF9C3B0F8F1B3DEC09A4CA3AC581B9192984E43999F0D34AAF32218B02C8AA2F21C579457F204BD18191811E7BD6E4AACCA5AA7C6F41FDD192BCD24760A2243034021B192575BF811E1344A25E1629B019564C39B09C88EF9B1CE6761066030BAB14AC202BB6A8D858C3FD316C4FA81D21904AE691F6FE7931DBC93AFC09F18F3B278E4C453AB5081372C093A9A38EA1622379F56397EC6C47CB7067FEF7225C952C262792DDA68135E45C3C6CBAD23593FFDE806FECAC55D682FB23839B37186D4A40B83641D9214B7E0490E305807745534DE18B9D4BC5EEA755CC117B68B7A30F76A9458708249F02DFD59691F0B720F257F1F96CFCC3573C5696EA33017AF14A843B81EA58821DB21B73A9B80CA187685DAC1F8735EA219CD01C6688F5BCAF4611FB3B58AD65B8D7C8BA4AB950BCAD9B23D5B2D0B718397E111FEB25F1739CCDBDC5C41D943E977AFF5209134722DD3D54B923B511661127B284AE9BA0C27F05AACB20181602D9BFB32C3E255E7F48735BAB94E515529A9591D51BE015A009A9094591C7E07A13C57E636B6E11CF4835A8180895A6581507805A1C7A39AB05633798AEBCAAE89E37D8D75B4F34C73C2184FFB567069F0B3911943C2060F34F10F835C8233A34B5618501AA36EBF678DAE07AF9A567AC7143567C92A89A94A0A4ABDE383706CCC3826A83DFAB8AE7165C6C6555BC77A43B5B3B2B590C56CE25E792796283737C6F5B300A0CF06E0060E1634A434793383860D84A76807C2983C57522FE3F988486BC386CB335AB55689D6B449B7A38DBCE911F512E4F148AA1567878025DEEED7DAB8E62D43C3D2096E4682692537C70EBAB9E1561CBA88B05EC055BDB92F28D0393C0F7850C7F6C371BD4835D6DB61C138B0FAF22854466231D8", + "ek" : "A8CA3445F317E7A423C7E145DB1F6CE6C0CC59EE59BDDBCACB826D16CA9FDCBE043E740718F0E4D87A201492189BD34F69E65BE31F6B40E39FF3C2EE1E8CFD2BF97FC8D1136B2A1F952400963A5EE5C61AAC43465D6B0A0AE6B57690FA664F12BAF3115B85005D0AF9D05C4524BCD31D8695FCD50AC520D134B404E1DA38DD9496D72CB6AB745389E3E4733A694FE4E5B9CC5F05873062D0F85EE4FA6C5C895C2A9E2D3E20B2F094318B8DF747F5C4575AC5B1FE6F135F9993F569C8AB14E47DAECAD2D95B50119526AD9BA02B9ED9702F9F47DF67B40CC0C366ACF492E10DC716E079D0EEF1A576A4219EBAD3F108331D194B01FAA6F70318C0A2441AC52F165D4B6B08453A9517C5614E7EF8C4DD0299F94DB656F05318868A9A03FAF631D65DD48446509E09C1F9C6094663E488901379A465981C32A467037D628A6E6508E25CE850AB287C1E20D3B7F2811B167B076B019C0966238D82B7B49AED07B93EEB4F28A3EF5F958A0434F46E2FDE6DDEFA63BB0E169A8A8A0AF3E42068006E9111829B1008CFAB15FABCB7A2BA7F83E3EB8382FABC7C74901D379522C08D2261C136A8855014CA41D67BE67DCEA7BA5476E92C76BC32759B08BA566DE99148A9E5059A9252930296E22BC02D30933AED345D74BAFB718FA694B87DF63A209591461D837E81492DE838B72602C920A3A586B8ABBC0EC5D4E78D2A99BE8250E71F4F4AC4EC091E911030FFA584B4496DE8C63550BBD10A427A8445076B6204D04CC4AC552B83214CAF6436827421FF366B61E30D8EC32197288216464A98D1107D51480CF05ADCE9A0A84CC44B1966163B6C4ED5ACBC5AB1EE1D535CCF9A4A11E928429C556F016B28E62694AEE99B4DEA20CD5C87B46172D7F673290C4536213D0E76540E42B1D37E50394E1BCA9DD812923CF4ED11DB9E424D315DBA76D74F3D1E2DDF5D0ADD60B2BB858818E582C3D49A22F92CADC12AEDE90D8D281848B9176CAC8CFD9BC4D1CA46A71E2D522FBB5BC1C8C1899A43524C4A2D33264DF61A25DF39FD39A75CF830E2EECCFA0E3B9FF47A1BB7993A0222165446C3DBD5ED662CF98B695CA2BC78C026FCC57497392B5FAEB22F214CC8064B2169D09B7E4BE1C3CD31F9B7C1621C0BDDA72A3E56EAB2729337E084583BC00F1E5130FCC05D61C3F05DEFC90B689F967E5E6B971D22109C03B5C84E2DA71C5B79D68A6AFB5EF91993FC4563ED7084074F709B73418C27FA2F521F7C999CA170F030AF3D0BC1FB3198BFF68B0F0826AB8C9FA1D238E2A0A9119E126938E85C7BEB36975D69F9DE074A88F4330C59AF29D1698D08FAD75366471831579E1BCFB46E5CD3689DFC272331CFAA01D57705CD4D955E254A6C1861DC8B6A9C501201580CEDA6C5A07B2E0AE47079F96D9FAE710A5A910F3C9528918FD9CE9BF4227BBC9614EB0E7331CAF4E26DBE2276AFEB26D0092F458360E74ACD2C24ABBE23F99C09DA436E3CC352E9E4D79D471FFAB57362E3FA64EBE72FC6AEBD717E7ACA406A6F579CEFE8226567", + "k" : "6984DA44C2CC82096A6777F7E5BC30643826FEE44ABF9E48CBC8B9011600548C", +}, +{ + "rngSeed" : "467F6158CB86B724039FF18C47950AE5C49170163C910FC9A9B30141F86E9C06EBCEC91497BCD156D95758C9F0C6EF91", + "pk" : "5B19B76208B41EB99B73D2B00D7884AC289C5B4632F8362ED9F238E07A34FD7B3ACFC5973070C83E03B9B45C65F8EB64A08B88592B6676DB235096694073143EF758FC84C9D3097266B66C9C34A6C5F876779936E345C3A07614E2795E65C0793EF3A22CB65BD06BBD90B391EB425223C2C395674D9841109B6929D353437DD49C7CD50D781CAB5850363865689DC8BCF81A80C4269A05060965B80A56081C186A2F4BB00E2E942863FB8E507230C29215C98A78E37201C263783F703B17928F36656B99F9CFE31917F05C25F57063D728A4E2BC652E4193E52877B7310F7260A1985985C26CAAD60C9E6F01B54BE183A7C2AE986AB2A85B33788674DCD42566B406BE251837266EBC6261C3B62FFF702F10298119D414B580BB4077791B7096A7471595D8659614C878D8097E7437503A7C7E058A3DD295D34ACE86B9302B901100ADB0E6140CBF44161AB33B9AAC34A0DC6F1FABA14D259C546C672EBB7F528A010D5585C21C00C4B19980C6490D76083A77B8AAEBCAF7917A81B55A6F2A6BE7941393D0A9EBD2C549417F38682DEF039B4944CBC6FC629BB3A3ADE353EA2005115A665087C00A4B771EF0490748B370D8B4C4EC37CDD352562A11479597D8035C00824F48805000778A81D6A31A0BB8B6201CBD3149EF96428C79569C5CBA273A9BB4A77EEF98BFA54BA8267BC42C643C29577B2BEA5802ECC038AB70FDB1B23D9272B7EC30CFE1791126A185C40A77C57EC3088822C808ED8B1866068035590460D6A9A00C50DB70B19B765E7CA8229E1A66F4FB52D752B515EBA35F64097EE85399D78AD4C2CFF7935CCD269731CA2B3B3217A22203E3B9438CF0B396FC99B6113CBB883C16869BB114BB1ADCC06863738541ACC61458EC9AC98DF381825CA80AD954562AB931D1BF47A1C45A5C1C72D90CC2D3B4CF6135B8B5454EC4967523AB82E9AABEFC89780722B5AA12E47344BFBC8C3426802C77C02195255E71555D9045BAC868C7D45C06B6474BBA2F40FCBC480112176A83CE361DACF2B386CBCD270456E7563A873C55D752151B76B3FE3C3233C5199011AEAD401B88B9C36EFC295FE03DEE6015B1CA00C5BB06DFD2C2848125AF903C298C5F74FC4B9937412AC70AACF07FB99488C797287C04335821CBD6475E91D66A7D89C2F67285321442C4E7CE61D0212CC16D74C211ED2A7BD829044FF82491D1CB1746430603A0091110F626804E0B32EDB0CC827C8BA7C36F87CBC67CEC250F65AD2FC621363BB715557848C5A01B256524271BE7B6956B72BE644AA0DD33925F64BDD3481615246E95294196D6AF1AA5AEF6880CE2A609715B50FA7737BE749CEAD7C84977747924BC25792509CA7A931C3FFEE7341547913EE695F8144AFE83430BD5C96CE61F57610F78D6C64C3C33B468B6F3CAC46F29B60F0705AE1A05E5C63D21A62F5DC7208D25A7F0C09D8F77A7A7A03D51D2061FB13D9AE97386FB6DA4CB6FEA0923937536511BA8FF00BA753897D16B76058A15B5C706121CC792076EBC2AC1EE492A36E65D12D23F6488245E998457D4337A2C62C731AFA43085A94892BD30393B1C9FCFB380F9815EA491968D6514B8707551443FCDD5926991599DA552ACB4A19B6342D309B5027CB88909FFC8C83B1778D8AA46C9D07AA2594A7BFD47CB7AE1", + "sk" : "FA9ABDC750B445E2973D9C85B0599A6310583B93C146A61256592258E79664F8A22558CDF55C2CA0240D5B1425B6D6177956AFEDC12885E12714982872CA17EEF52085DC965DE960B29972F5828D3410506E34BC54BB2DDA3C6A54B5AAA89466CD44AFE56388C21B0FD19B744020CF83779359097C3E3086A904376B56814A454935BB53289C1CC4D08198FA6797149C74DA0D21F99177093DE6DCB8B5579A9641CEAEDC74AB8C3E91F2804BFCB94EAC1245B53E27BB5907219BBC6B7F61AB3A35A11C3CDA544DAC262B4289A4A930283B56D5779EE14C62F3A89308F1120E3B34EF87087E0C0ED6B55280031927682870E09DB8800467FC82602B95D1F16D680562A2B866380A411546475D1A529DB537C1F2B3E3F393C1919D6FB97877297CF2AB346273478AFA7EE1044BF4D3353374051E0A4ED2364587E0694920A6CD6ABEF9F68D00B16C7B2A53D64BBB0645098BA1A9745A15323B2BEBD956942090EF2381F8FB747F5964B4EA9A57B22659635DCE7C55FF10B7D1C3A76687334542315A05A0931A9A5DA734F6B647DE025E05E480B5A27FDE1116FE03630FDC074F542AB358341BA08FCB79B48CF4273B46C54219C16BC7943887CF451B1FE224BCFF9121098A75B2D9B35E71BA2BD94F106800DAC689D6002DF6AB6528876C39A74D63DC41490077CB94CB243947205841F8B698CC214BC9B2442AB418D7F4A7BEC2A793FC6975268A4CB66F304BC7CC142A81F057501C75BAF9B3A5F94935B3991C228AA52266EC289CA3333D35DBAF59AAB37D659423BC9953656317F48F025076240B15FD145E86DB6EA8758B9B265CCAB860CF5268AA627C02AB245F466923B91DB6A240D1731642229F22946BE1EC538A86B7DF1A1F4801791DDC487C6ACD7FBCBF9F457EEDC81CF0A03CA0C15E4524748FF08B7BA020E1C6A4E8E573A6D9C996842F8122BD876C4F6B193F22A68AF9111F302B895D2624F992AAFF265C996171889661897856B963C92061C4C1DB767ECC725056B473753AD6B9046AFC82C60A8D7000CCB18B7A3831933EEB9EB02C76E379A5B326C72B0647ADDC393A6676E6B948BC465578E9B4CCD670BB31A39C5B1AA52C6737433E930B0C2DB239FF2A55D8EB649B4AA69B56987E0273D8829DB39AC057F89194186DCE30B1B20B17F5592C5737CD12EC38BBD228DBF7863CECCFFE9587BD485090E45D84C298F811AF1925B37A4ACE9C751451E326ECE073C1503F54984E910BA12FC79F502391784B1BB3B41211E654655868A8D2B5AA4920B9FB2EE7605BD7E8A3AA668F9721212A860DD762113EFC1E1BA93A4A10CAE185BDF9C80C06EA30757B12768B29A4A3950D9175E15873F104413F22AD79362643599F7D6960F3D662D24255814C2FD7B445D35651EC7C0F873A2A2C255AAAC51C41118E4CBCB6F91745150C51CB7A5D5987341C807CF8969C523913B8659DC5120C6D90782D463ACC647F16976F641C54FF50BFF3DC1194C56C3C71B6BB296F65FC99D20B92662A19A0D8748A90932D498B7E315BE3388F87B73CA99611035224FAD81792E8C7A3A23DBDF0A44EF9C0EC0C4EA68804D9C9078FC08CCB733287862E01F8712F30388FEB2ABBD0810CF2485B19B76208B41EB99B73D2B00D7884AC289C5B4632F8362ED9F238E07A34FD7B3ACFC5973070C83E03B9B45C65F8EB64A08B88592B6676DB235096694073143EF758FC84C9D3097266B66C9C34A6C5F876779936E345C3A07614E2795E65C0793EF3A22CB65BD06BBD90B391EB425223C2C395674D9841109B6929D353437DD49C7CD50D781CAB5850363865689DC8BCF81A80C4269A05060965B80A56081C186A2F4BB00E2E942863FB8E507230C29215C98A78E37201C263783F703B17928F36656B99F9CFE31917F05C25F57063D728A4E2BC652E4193E52877B7310F7260A1985985C26CAAD60C9E6F01B54BE183A7C2AE986AB2A85B33788674DCD42566B406BE251837266EBC6261C3B62FFF702F10298119D414B580BB4077791B7096A7471595D8659614C878D8097E7437503A7C7E058A3DD295D34ACE86B9302B901100ADB0E6140CBF44161AB33B9AAC34A0DC6F1FABA14D259C546C672EBB7F528A010D5585C21C00C4B19980C6490D76083A77B8AAEBCAF7917A81B55A6F2A6BE7941393D0A9EBD2C549417F38682DEF039B4944CBC6FC629BB3A3ADE353EA2005115A665087C00A4B771EF0490748B370D8B4C4EC37CDD352562A11479597D8035C00824F48805000778A81D6A31A0BB8B6201CBD3149EF96428C79569C5CBA273A9BB4A77EEF98BFA54BA8267BC42C643C29577B2BEA5802ECC038AB70FDB1B23D9272B7EC30CFE1791126A185C40A77C57EC3088822C808ED8B1866068035590460D6A9A00C50DB70B19B765E7CA8229E1A66F4FB52D752B515EBA35F64097EE85399D78AD4C2CFF7935CCD269731CA2B3B3217A22203E3B9438CF0B396FC99B6113CBB883C16869BB114BB1ADCC06863738541ACC61458EC9AC98DF381825CA80AD954562AB931D1BF47A1C45A5C1C72D90CC2D3B4CF6135B8B5454EC4967523AB82E9AABEFC89780722B5AA12E47344BFBC8C3426802C77C02195255E71555D9045BAC868C7D45C06B6474BBA2F40FCBC480112176A83CE361DACF2B386CBCD270456E7563A873C55D752151B76B3FE3C3233C5199011AEAD401B88B9C36EFC295FE03DEE6015B1CA00C5BB06DFD2C2848125AF903C298C5F74FC4B9937412AC70AACF07FB99488C797287C04335821CBD6475E91D66A7D89C2F67285321442C4E7CE61D0212CC16D74C211ED2A7BD829044FF82491D1CB1746430603A0091110F626804E0B32EDB0CC827C8BA7C36F87CBC67CEC250F65AD2FC621363BB715557848C5A01B256524271BE7B6956B72BE644AA0DD33925F64BDD3481615246E95294196D6AF1AA5AEF6880CE2A609715B50FA7737BE749CEAD7C84977747924BC25792509CA7A931C3FFEE7341547913EE695F8144AFE83430BD5C96CE61F57610F78D6C64C3C33B468B6F3CAC46F29B60F0705AE1A05E5C63D21A62F5DC7208D25A7F0C09D8F77A7A7A03D51D2061FB13D9AE97386FB6DA4CB6FEA0923937536511BA8FF00BA753897D16B76058A15B5C706121CC792076EBC2AC1EE492A36E65D12D23F6488245E998457D4337A2C62C731AFA43085A94892BD30393B1C9FCFB380F9815EA491968D6514B8707551443FCDD5926991599DA552ACB4A19B6342D309B5027CB88909FFC8C83B1778D8AA46C9D07AA2594A7BFD47CB7AE17D30385F988DC748B843B7B7F569E58CCC9215503E1BC2F28F5019FC72FE6D33C95DF27DB27FFD4A8FDF31C4474CBFE2F5EF99F760E97FCF569D8AB22C2855A5", + "ek" : "411C98F832BD70435035AAFCD3146C70D8A959607ADBC8C9559897590B0A2310F3E0F9B5DF02B00DE84F08A02EB115B4E982509EBCAF0CF301E1C1D3C3DA5718DA979E79E93E82AA2E1B089A40CBC4DAD46515946F1E607CFBAD0D11598EF09C8BBFB3C58889EAFB42E85D40A2068881459AF4BFAF40D2EF3ECE7DD11AE6A0DD7442DD440BA3682AC1911A14AE6E55F0D730786EB4E24F2E822EB2EE5373814B0AF2D92C7446F25D93BB10978B0757DA8D0D75D17706F49062BC857617F3305FE12EC387276936C288EAE1544F851A31DA8435BD47102715D055C8F7E9E867D82EFB4F92CC090DA32C455B13A41D3B7E46655C962284950EED860DF2E0B949E9C85D5FEE16FBAA68D196267F8A254D711A48E701839E0EE37DD2A62E70BD24F4B8EED4476CFFD9339AB6EFCD7AF35E9B4F77E1C00B5AD5B308BAE4DEE12B8C0B9392FA1A3379EAEE60834BFEE91A98EF29D2517F7B0460BCE5ABFB6E9A7F771F5C85CE539BFE7104CCE55DDC080CCCE704F7FE3C5DA34EFA3FD91337195D9E8B0EA9EE5CAA51DCDD2A9CC42FE1068BA9435C17D9E804ED03052277A3F1F032D3D58892E2D2E06180D2B4B1F67480015C2D06F46DE1B495F8E617C1FB1FE542579CF412E2D3FD7E2F24E1A074B09B6F39C656A46598526F068F6113879DB3EF33405367BC3A99BDD140264BA95EDC27E2EBF1B2F87B16A48116EE5614569F868EC5C7E168F5AB5EC2D8DC6F755CEDE0CA2D93823925A8FFFE0E3E17912BBB758A8622A7214FF7106036AB39E148FEC17BF932A4ED9CB9968FB2A84A23F2D5236829517BF1F015832885BD35E3A524CC0255D0AEA3A9406E4912BDF40A7A3D006E785B738712BF32E824D0498ADA951D6E3231E7400C5D912E4FB965722D8D7C874498A819A3E6747C35DCA415B5F357728D0455306FEBA289EE18044BFD2F649A0615AAC41C7D644F484B669F72EB57EBD6FB1ECFAC01F9357864AE15EE5DF26B0DDE11F5F3E5375D67C7C96A47341A87F2130BF87D556CC6D82C3F9D1F4FBECCEDE113BB43FCBE30CD06376824964B69A0399AC7BCCC5D4FBC176FB9A1A9E4F727BCF1EBAB023EDA45AD1057BC420228C2F2F6A3F06D500A1E5C5106AC0470591B5D0BC0C244C3A265F326E0C9E0ADFC82C87A41313BF2A901902067ABE216D5D55FAF415CFF72522DD0912C05C0BA21CE9D27FBAD8BF081852E6755CCA7AFBDC6BA4072E10147285B4136E0E42938B36EB81B979306DC83A350514512CB79D67DD9412B279A114CF5B830650B4515E63D873E2D71896B962402AFACFE91CEACCDE6FAEB2EA55796663ACF33B18352575CA74675D36B8BBECF59F17531624071CE8C3A0AC4A5FD13EB22F1E8DE9467CDB7789C7EF8AA90DB0781A215DDB776F52ACE5AD5867934D328B016432F56E074CAE8DD1D3915A7EC975ADD6661EC669C9D4BFFA38E7277C91DA48909A7443C48B9DCD3AFF27F09CC26273F7B6D07857B6DDCE40C5C832E0BBF077B39993F8B3607C0CF0F97D1D53571BC31048767F917", + "k" : "14462386472C53274937889EA50EF763F9C3A4438B910268E69FC6015AE6C8B9", +}, +{ + "rngSeed" : "687C02DE1041ABAC7B2C1E6EC2A7C3375552ED5EDB10E3A8139C24CC76BDA44D719D8121A81D47A0B762B4E9EEB85235", + "pk" : "3610631D29C37A90908CF2C89D075928CCB3B9558A5453315ACABB5A228D0ABBB99D63B0294B68594A0A648367FE044E14347073562AEB475C17196A3DA38896F2168996CA917A0423614431963B10B5A0D3B228AECA3B26363026D1A5A952B5333CADF79A59B93B5BA484BBE4618B41756A101429CBA6407B44A2B001108EB30E92D60C093B4ABEFB63438C481DFBAF08442D607088EBEAC83A950623E057C99CB0F9E31639CACC82852F4CF9BCC83228151B91CDB0423F610552B0C170203C7F2B345443BD7D274AB14CB67B328D914366EA9A220CF46333A41FEB5193DED4A5D94C6E0A43BDD6B2A52C3C4C718591F11B32AD64930A638EA9F217E64A9E31526313133C02B5B0CAB821544543FE24AEFCE70927D9248AEC2937385C79CB85DF91256E176EAF3A239B370D4EF56A90DCA3935507A6A86D84B021312BC718662ABD432C08BB4DCA3614F357321B191A8522AC109A643A5A9A63419BE6845E5F5837B6188DE0C779FA01430B219470A20DA019688802BA8440C60D8727394114DB10343FBAB0993AC5D967B658B1551A6570F7D9B283445CC278298B4740884BA72B338C45249AB74C84A1435A84C42533A0BFBDD0509D7A3BD0B0635F538CE72645650931DBBC6E2850CD2585214F5CC12F2A2D9C2820D6C0550BE79D5276747E2C04BF976705227C842B872E294AFF495E06502819C6C92DE3622EA968B07C0646DC0301C009FCD5BF7F19A357693E032CC46B4777A1714D41A59BF07721A2490BE2E3CC7E4A04FE48A8DB361A5CC1390D921325875F80629C2ABC4D468A40D9C22911B9BDFC6BA986B9BB7226227DC63D75351FA4613DE3654475C5668D651F9F03A386179CAD00100B35343F48B7E36A79DBF979CDC734D5855B90128FEE10C9BF40ACFB67332CC8C9ECC4A3A9A98BD30C708E7A630A0909DC8BA2B1721E42250B83623A1289960E7288758525D4088525EC25511BCA906930602B5EE1D127C23205E681C9DB3474AA774733100838B2461E45CBD603C3A74122B679CDB9992063E089D5ACBF74B03469A3CE7993C6B978313A7A735E75BB94976B3539B4298CC47AF58425C24310667B1315BAA5937741E35309F1C70CB8C60E06AE1793502A316A276B2E21087305F453D8E99D08730E174159DB09324E4CBAA067CB1E766E455A34159465BF1138A285CC386502D698538AC63DE2F496B120BE468A952B02C5DCFAC5A997023B5B3D98691572103E158672EAA0A4E4F44FB6920FFD874F52748A630AA41D188ECE499AAB324E916079B3BC2427B35896B26B0D2564B2A875881A074706713D326306FC66EFAA1B8D4CADC7C85B7AC211C4F61F68A124465397385B2AC7A09686935CDE06638F156E6E4670F963CA82950D3207889446BE69E2A0D7CABFB16141868A6187B5BE7977C354FB27A8C9CB8197565480244BF296692A02701580A2B4AC4772B13A27C869123AC3B6CB6699698C11261F657FFB6C8D78102E0C60C004C0796F319330435A29ABAF33DBBB1C566AEA10349981409AC31C18AA48631A1F0657116821A2A36C2403870A3787A1E3F36349B3373AE729A859AF3163C078C38EF38C464AC5BA1FA8150D9093F97C17106C99C632BC42A5CA0595508BFA7485B23BDE8D12AD7BFC9C10C68374B70A4A46655B5A67D1", + "sk" : "26424F439191E67B1755D6893EE31789B8C6985191C9C21C1EC7CB8C990F82AC49B7996B1EF48046F8B3093A36C27CBA5C35B7CD733678C10AC06A5108609E47DA30A048312F1543B8761714114D37A3C70EE09813E79F37E6402D584F51673F70C5331B89A52E61A51D363A8AD8081DF227DD621B20469DED708BB64374E2678424787C57940617980DEF632A61EBA801C1A079517302F3B02DB4B136D588E2A41FCA2729B541C9BEF00940270E257C47103449BBD47EDA9BC7A9B508D42076FE7734FA5454228958D7CC932EBAA0F8D12123E7CCFDDB039A2A66D6D7A0140C6CE16B9FC0B6A0A3B7A0B50A06D8D397C9020F1DD1B5F4216565DC84E8911102E54B60E88ABCE7714AD29668F79B7F2A7B09E7C8A92480F30B072EC14E96E77E63342841167AFE3421C37C2FF3F25CCAD60C652C9831C5519390BF0EE9B2F108104D77145CA4B5245B66DB6607AFC0141324328D746787ECAD7F5A0FFEB50DDDE16EE1AB87440389FA0B9C44B75FD26C726773BB8049A77784860558107E069D3D0521C6015093787AC6F263D356130B9A39E5093F62D7B2F8E5411E61A18D44155FBB4D2BA7B09072CF6FE666109AB5FC078EB026490720C82B4990A28406A450268414AD4FF1791B370722258BF103507FB9A09B09BB4373465CE5A1EA263BAE6B723036AF268700D496724A42539CC9B7F7357CC7B6B33E11937A884DBD30888508BDC442379EB8B3682341B3B4B760A879FC229397E05879B003A06ACDF3C5530A7B90013873F47139C2D96E1D7B67427467E64CBA2965766603CA30E13F2E357E3E6945CDA2906416370CD699B3DA77889B63BE284AD538269929914092B805AAC7E9A04D0275C71DF020FFA6002C1703ED674DC5633367BC086CE15E4E61A93DE94023B823D1FA29BC6250B92A8A04533987A6BC510BBE84BA7FA1699B077C3A05992DDD52A19AA238B466C2801B3FE9F72335E15EC2342EBEBC7694BA68E276719371B933DBBA3FA07262870EA9521E95650444845B41258F6CA77915345C0AF3718EA09F6AD604C9A4971E618B59551F5EF54E57AA138E52CC03313398C0AE03BB4EE5D36799618955789E80A78BD896AAE9E87F2BC0A6B730A02BF82AF19C541CA93449B127F883AF13713BF5229238B19A216478A4880A7D9B6009719209F69519E5774CF48C8AA20B96E4B0F10A94027819204532A54C48026A5CDD5841E6C8A736CBC99F9CAF46B8A90648A854F9C6AE37048C6671C5E8A1B2731019351631829C205959A4B4AE87A4C3234C63E653CB75C92237C4721C66AD05871B22D69F3435BAAAF311491394CB1238B899973EF79F9C371F045B4145BC20DDB71D53FB50B25C46E674778FE9069197A9861337EDAB3DE55CC28BCCA65B2A5FBE1A2A67197BDA012ECAD40BC86593A06C833C82AAD0B714428296248A8E49304CD3955081EBB2E717B36DEAA928C3C09CE1BCAB3114627A7886F64D69B206CB7AA8F978C13E84A6C6453EFB1328684859EC20A9FF7A560D436977294DAF2ABC08B78CE10A22D5FCCBBDB192D57534BA04C5DFBA389C3BBBA4F5191EE9AC7A344CD519CD39100012DA9AFBA0BF9A2373AC534ADA885CC71322E5B4A4B84C473610631D29C37A90908CF2C89D075928CCB3B9558A5453315ACABB5A228D0ABBB99D63B0294B68594A0A648367FE044E14347073562AEB475C17196A3DA38896F2168996CA917A0423614431963B10B5A0D3B228AECA3B26363026D1A5A952B5333CADF79A59B93B5BA484BBE4618B41756A101429CBA6407B44A2B001108EB30E92D60C093B4ABEFB63438C481DFBAF08442D607088EBEAC83A950623E057C99CB0F9E31639CACC82852F4CF9BCC83228151B91CDB0423F610552B0C170203C7F2B345443BD7D274AB14CB67B328D914366EA9A220CF46333A41FEB5193DED4A5D94C6E0A43BDD6B2A52C3C4C718591F11B32AD64930A638EA9F217E64A9E31526313133C02B5B0CAB821544543FE24AEFCE70927D9248AEC2937385C79CB85DF91256E176EAF3A239B370D4EF56A90DCA3935507A6A86D84B021312BC718662ABD432C08BB4DCA3614F357321B191A8522AC109A643A5A9A63419BE6845E5F5837B6188DE0C779FA01430B219470A20DA019688802BA8440C60D8727394114DB10343FBAB0993AC5D967B658B1551A6570F7D9B283445CC278298B4740884BA72B338C45249AB74C84A1435A84C42533A0BFBDD0509D7A3BD0B0635F538CE72645650931DBBC6E2850CD2585214F5CC12F2A2D9C2820D6C0550BE79D5276747E2C04BF976705227C842B872E294AFF495E06502819C6C92DE3622EA968B07C0646DC0301C009FCD5BF7F19A357693E032CC46B4777A1714D41A59BF07721A2490BE2E3CC7E4A04FE48A8DB361A5CC1390D921325875F80629C2ABC4D468A40D9C22911B9BDFC6BA986B9BB7226227DC63D75351FA4613DE3654475C5668D651F9F03A386179CAD00100B35343F48B7E36A79DBF979CDC734D5855B90128FEE10C9BF40ACFB67332CC8C9ECC4A3A9A98BD30C708E7A630A0909DC8BA2B1721E42250B83623A1289960E7288758525D4088525EC25511BCA906930602B5EE1D127C23205E681C9DB3474AA774733100838B2461E45CBD603C3A74122B679CDB9992063E089D5ACBF74B03469A3CE7993C6B978313A7A735E75BB94976B3539B4298CC47AF58425C24310667B1315BAA5937741E35309F1C70CB8C60E06AE1793502A316A276B2E21087305F453D8E99D08730E174159DB09324E4CBAA067CB1E766E455A34159465BF1138A285CC386502D698538AC63DE2F496B120BE468A952B02C5DCFAC5A997023B5B3D98691572103E158672EAA0A4E4F44FB6920FFD874F52748A630AA41D188ECE499AAB324E916079B3BC2427B35896B26B0D2564B2A875881A074706713D326306FC66EFAA1B8D4CADC7C85B7AC211C4F61F68A124465397385B2AC7A09686935CDE06638F156E6E4670F963CA82950D3207889446BE69E2A0D7CABFB16141868A6187B5BE7977C354FB27A8C9CB8197565480244BF296692A02701580A2B4AC4772B13A27C869123AC3B6CB6699698C11261F657FFB6C8D78102E0C60C004C0796F319330435A29ABAF33DBBB1C566AEA10349981409AC31C18AA48631A1F0657116821A2A36C2403870A3787A1E3F36349B3373AE729A859AF3163C078C38EF38C464AC5BA1FA8150D9093F97C17106C99C632BC42A5CA0595508BFA7485B23BDE8D12AD7BFC9C10C68374B70A4A46655B5A67D10697D2F9E047E603B8845C9ECB168576F9D8BC7F3C831B6EC15C5FA4F744315D284FDCB2D2A697D75E985AA43FAE0DF266A8056C18CB0BBB52B4EC89D66C21E8", + "ek" : "B61C2821A08A362208601DEA0F6739ED54366AF8AA7AD4F7DDF266ADB17BE3D9AB8B8AB0664327FD5137B7B776494C5664569FED57927156FBC5173C20DCA563F66F4F6B74FBFCD45F696424263795F7E50785C552CC77F167470C8311858829FBD16AF7687664AB9F7164162F51971CC7242E14990CF8572D3401AD07555FA139F247461B5145FBA542EA6EC885C46A43BF69DF6D4F80F7EFC333A0D473246BDDC4C83A78A3FD3BFEDF8E6B4F0C307EA75610690FE4856AC8164B437B43772DE384AA6CBA0E7523C61E90F8019B1004E86008D6E634C451829FCF28C24FAC836636043737FE7C56F214F8D1C5D4A164E6F7E470540E64CEC8209E5018FF9224971DE73AECDEF8E44345BC0EA7ED600FD3F1F8224E4A6507C33E00E861B95A00EF237137C3C2D5780870B574351453F5A496ED3E50AF490D352595DC8D4706977E5D5BC4B7F81F9C1A9620F6C5DAE41D1EBA770CEC0176073C5D7FB0BE0D3A3D6BECDFC2E5D426FDDEAABB33E9DD03AA4068983425ECD813AB85D8FB475179AAF2AE3C8B887FA9031D6D514C7C6127B8FC1DF3A52830F8970A09CB531CC43BDBB920BA27D29D337A6B1BE51A60BB5484A41ABFFA644073EF0011128A8BC1A972477A2A68CA915D138D4C7898573ECA2A17EF95E34A4A775E86899A37658A40495E17069E9312A58C516597DFF033147F9735A4429AD9459DF0A33E9078233CBE37E7BA40E364D9117EEA05449537A724CD54237788DDD97F59346E539A220212AFA1330C0CF25C1DA70655EA4DF5BC07C2A724EBA99E6708A444F19B97894FF9E7E2B9739B3B53AD6CDE4349BB0375B3F7771F93ECB932157A1CFE8A24A7C38BB3E74BC01A368D238803130AAC7D015246E674E0F50C0A4F26C598C2FF7108CFFA7EF8A88131DD3DECB7FFF25BF1F10D702BB95072B84421732F4B5A80B8C4EC899859AECE984A0573033C4F4A9FA9E8EBF26C47170908986094109566F8C9763728DAACD2C3551CA6BE308DA93808B27AC769A0B2F56FECA40D351FED0965D07F2C6CFBB0EEB6A2B5114D2A34015D107F7A798E23D217E1892220147249BE5CE4C1570D0757A0CFA39E332E662C57E8F1EA9E95286007B67E1E3A607B918A1F3BB6936542B7D4AC3D5545955C10B61E082DCBF417EFD5F22388A21A7E851FBA42037A0FAD543DB113A9FF695B5C885F2DA1014CE7155F990BBAC0CFCB905527CB45CE92400CF43367761383D59544009AB075D22ABE9FCFE29BE3C38DF921FC3AEE64DF318EFCA007C9A7D594513D3498D4BF5862A26373F6D3F9AB24F594A301D79157BFF8F5041117E0509279CE24161AD99CEA01262F744F33EAC393270F2B0CB6414CE07D2C1CA3244F35A2CCBF82E660DF487D6AAA6B6DA4770A874D818CBB171D43C9E0B335183926561D750DB4196C45775236632C9D59976E9A8A40CAF1DE880CD1A1CA51B10D414D187E9F3223DAA580232A2886A6D9EE3CDC120FAD9BEBD485406C33E4727848A70BD5BA5B57D50A660977B54610D1FE2DF8E53E", + "k" : "89ED0C2DA94D4CAA7508E53782AFA8B7CBC7E2D88B05D08220D906AA0D1F0512", +}, +{ + "rngSeed" : "4142237070C216BCBE245A39BD9220533C97651D84832B26727855AD994A0760C52B9319AD404693E4248B8C5FF324B3", + "pk" : "00E7A56E91A766C72C04AB283D25787224A588EB4FE0C6B54D889D127A471A72C65F06375D1A545AD9B058A654324B5615138B2EC4A375989B3F1B60FD30BDDAA2307205A103B29BE6CB75F3567705A0C05EB845D493CAF795554AB25FD03B379A6284988763698B1BBB4B3C1A54B9C2038E9EF30A3870A11604288B32336E15939FD181525909949C6CDF7737CDB382B1DCCC0C49317213683B349F8DA22DB0B45E359B2F8E70916A0C0142FB264CB6BCEB80AFA3A36912D635D7B4CBF33A4A36E4C6714C551D70A18B967539B7A604C5182EE7673CE91D07736F5B97B407879E77050BCC089A14332138D92AB3E09B497B834DF573DEA32829B471BD5A73E61361EC699EE60320CCDC0E6FC983D3238A8D5ABC3412BF48D67DD2E1B0C2692A4E705DE666AAAAFA9ECA476A1B155D52459B563B6EF1549C51F83BEE2963A93729D4746A01A21DC667B120D38D79A45A112067205C3EDD378C7F65C940719F79389436A5595010678E1558CE163AD95593A751C737D4936ED9C7CFD41EFFB1ABEDC07564FA5238EA2D2908793E2A9A33E08B67AC3133402D42344F6D1C804536263661A557739CD8C29682549FFF416C069A39CD48229E47066E02612988BF780256E25009EC5B1EF829BD39BC0654A0C8C3C113CF421F06965713849A83CAC9F6415482D82074FBCBA804B4C5F2B1FBD941C7EC8C4C691DEE981392BB0736D43ADB3CA548829A55BB9537396D7BB11922A9167EF01CB1AACDAF17902F671A6CF5487BB643E0A1CDFA3522860326D374BA8009833BB08EB09A2B3CAB0D3193A6561C17D60B1CACB24CD3C26C455C040CF9AB0A7292BBDCAB2D5B783D65BEE7A666EBAA2764E98B7DF61BD5BA546BD307AD7469E4EA85B6031224D9B1315720CCF95273C35767C43A3B27A31773C5B35C7E4AA0316C53CDB2FB1A60AB77C4A76F2AF78BC2D6479B909EEB9C26FF97A47C468DBE7C439D232A914766FCF8772E7BA92B3182E362735C237BCFFC3E940CBC5E6042DF923EAEC04D96E31CC3187F66735FF1E62FB5460895B22145787484E529A1D654A2D72CB9D81B4D283BB15682E8F9BF1037CC95E29CC3716FD89810E1BB95DA871A2562645E0C60A27CB508C2885C19BEFC686DB2E7A78AA66B934AA0D42C856CD361EE93294759549929B59ADC1EBEC3686E70C4A15C8D56DC23AD080945D4734B76B0A64B73DE7B5D810AB8DAF48542A4C13B8A14AEF05C788448ACAA51263CB31BE69A91888AC66075C0E59EAD1B29D6439E94253D20F965D9F0ACA53A28B4903BD40A1310F0123AD221A45961527589E7048FAA407028601E397A96B39728BF55437D335F1E14063D3902E923863BC90572891117516FBA340263D6A0AAA0743E959DA8F21EF9FB38431B36B1328A15696E97AA78EA97936F8B38BB1556D2625F5AC31E1B8CB3BAEB1BE7F808B6329A440045EEA532624354DFB71DC321109D0058F24BA4729C375CCC0440948FD345561715654F60B378B477A208CB83F3AFED2534C5AB6EFC0A5761D46B6CC0A6ADA55D1C92C7558BAD4091772F65BEDAF335BA37AF34582E0BFBBC6609BDD3568001734520F45D9F4772D1D21D5080B9A7A2B2E72A0B6E030F1418BEB28A229C8F63411446B83FDE11B3D946C9BDABBA08D495AEE50911CC66291FD0", + "sk" : "1023C0608301AB03CAE768B68FB495C496B583B72006F0AAA985800DF2B6BA238CF37748DFB231FFF957AB744CD8C5710B301340426D66507F48A23DF19878D9CB0DDFC06E1674C03124CDC4C1C70ACB645EA55B22403190D813F287A5C245B4E7A31D11988D218988FAEBC195366760303FF99433CF07B68FB4BF6B8A507E902B0A07BD2F048F0393BB9F5B40CA588208FAA73789A0107CA9C4D12239CACA11500F3DE39995D11911B9386E8BB22CC908E9906BBB247C96A0BF6EC14BB0E33113AA4CED8531BECA2D415066CBD299A9DC920A935B1BB599C0C14A695253FBBC8AD7344122E8948F5B10E46138B28740348AA888EA0C18D53B875232C34BB0D44197352505231BBF5DD356B8955856A4C3BB4615DAB0A07724065F4AB0ACE46FC684A3DBBC9AC0E776E6D628AF8A2794829567A95D2AC0699E3A87A46086781965DF032586290D2EDC5C57A7332A286BCF39B8AF181424884863123D1145031AD069E0A56F9212C76378871848B121489773A623C69C139A33363BD032A40B4FA15637C01916C132754BEA335771810303418F75A35D591F212A603DCB2F3FE9CE261ACC082B4E38477CA9348DBF6BB981128BE73C189147B21949666CCA3DB8E433FE66CA43206356884431266B9D1A92B1899217AA636D3C7D7FB11A2E9CA61ABB586D20AC1E46198DA618CC71BD52B922DE064FF5211A2B53C51F206E025505D3273F3F682E1A873CF41433B77608739B55D457364C04315DD8B304604C2FA52734FB25BA6C69F9030008A310EA76B450281168A3201B9892E5B7926CF53C3E3A591979874248A361C5C1F601D0580351CD51A78392BC4134C708DC822AC8B9C032A80875B30EB69F9A636B2AB13C6A35CCF4D704CE40AED8FC2A3F47B50599B024F73444A09DF092775F5A77113225B87CC295E336EB8668CA6B3DC1D7B5AF00A75730C8C3A45F05F9A22C66143965466F5B7CCA564B6AFA4A3BA0A57DD5B7035651725010AC088727C5B7B5B91F173589E7B94463F70BF9813C28B405EE53C10E1943CB61CE66527D7C0529CC67B181EC6B4077AB764AA9455052495C9DADF033CE50C51A3893AA250F6E47711E96AECC69A13AA60B1E837C1AD98B5AD2931A9084C6C364B4A33DE1A02D01D9155B527F036B35D5EC3D13B5BF49E8BE9B0234F49400FB512E22A705E0B6212908B77F715B3813BBBE29539CB63F78075F0F3CC60821B4D24B5674E29AF16647FE917452B85A1C887286A89AFC31955FE8AFA67AAC2AB30295D8564EA94C720268ED866AD36C8BD634B2B6E6977EA1781A592E532B3F292B8FCBB10235246F8C320D6DAAB3A7FC26B63251DD98A12550166B513A8D66435789BD979436DBD263B18C15660693E6EB99268A3D80EA6C995234D7E08B7712B295543B0B3B9856C72CD2268F7F66A0C67C96A2A1BDDEB26A4CCBAF9D7499A7A48A65982C8059851B79C735897109479108ACC7E668BB16C8A530A7BF4F473841E17C191CBBF867B36059505446CB30C26FF5970FD21A4043854D96D9575EA25415C263028A2A4F35C824001EBA5062E23098FC4556399241B8E48933E28C67068D34155507E23CCF4877BD170F38203FEA3B9E2A289602301A00E7A56E91A766C72C04AB283D25787224A588EB4FE0C6B54D889D127A471A72C65F06375D1A545AD9B058A654324B5615138B2EC4A375989B3F1B60FD30BDDAA2307205A103B29BE6CB75F3567705A0C05EB845D493CAF795554AB25FD03B379A6284988763698B1BBB4B3C1A54B9C2038E9EF30A3870A11604288B32336E15939FD181525909949C6CDF7737CDB382B1DCCC0C49317213683B349F8DA22DB0B45E359B2F8E70916A0C0142FB264CB6BCEB80AFA3A36912D635D7B4CBF33A4A36E4C6714C551D70A18B967539B7A604C5182EE7673CE91D07736F5B97B407879E77050BCC089A14332138D92AB3E09B497B834DF573DEA32829B471BD5A73E61361EC699EE60320CCDC0E6FC983D3238A8D5ABC3412BF48D67DD2E1B0C2692A4E705DE666AAAAFA9ECA476A1B155D52459B563B6EF1549C51F83BEE2963A93729D4746A01A21DC667B120D38D79A45A112067205C3EDD378C7F65C940719F79389436A5595010678E1558CE163AD95593A751C737D4936ED9C7CFD41EFFB1ABEDC07564FA5238EA2D2908793E2A9A33E08B67AC3133402D42344F6D1C804536263661A557739CD8C29682549FFF416C069A39CD48229E47066E02612988BF780256E25009EC5B1EF829BD39BC0654A0C8C3C113CF421F06965713849A83CAC9F6415482D82074FBCBA804B4C5F2B1FBD941C7EC8C4C691DEE981392BB0736D43ADB3CA548829A55BB9537396D7BB11922A9167EF01CB1AACDAF17902F671A6CF5487BB643E0A1CDFA3522860326D374BA8009833BB08EB09A2B3CAB0D3193A6561C17D60B1CACB24CD3C26C455C040CF9AB0A7292BBDCAB2D5B783D65BEE7A666EBAA2764E98B7DF61BD5BA546BD307AD7469E4EA85B6031224D9B1315720CCF95273C35767C43A3B27A31773C5B35C7E4AA0316C53CDB2FB1A60AB77C4A76F2AF78BC2D6479B909EEB9C26FF97A47C468DBE7C439D232A914766FCF8772E7BA92B3182E362735C237BCFFC3E940CBC5E6042DF923EAEC04D96E31CC3187F66735FF1E62FB5460895B22145787484E529A1D654A2D72CB9D81B4D283BB15682E8F9BF1037CC95E29CC3716FD89810E1BB95DA871A2562645E0C60A27CB508C2885C19BEFC686DB2E7A78AA66B934AA0D42C856CD361EE93294759549929B59ADC1EBEC3686E70C4A15C8D56DC23AD080945D4734B76B0A64B73DE7B5D810AB8DAF48542A4C13B8A14AEF05C788448ACAA51263CB31BE69A91888AC66075C0E59EAD1B29D6439E94253D20F965D9F0ACA53A28B4903BD40A1310F0123AD221A45961527589E7048FAA407028601E397A96B39728BF55437D335F1E14063D3902E923863BC90572891117516FBA340263D6A0AAA0743E959DA8F21EF9FB38431B36B1328A15696E97AA78EA97936F8B38BB1556D2625F5AC31E1B8CB3BAEB1BE7F808B6329A440045EEA532624354DFB71DC321109D0058F24BA4729C375CCC0440948FD345561715654F60B378B477A208CB83F3AFED2534C5AB6EFC0A5761D46B6CC0A6ADA55D1C92C7558BAD4091772F65BEDAF335BA37AF34582E0BFBBC6609BDD3568001734520F45D9F4772D1D21D5080B9A7A2B2E72A0B6E030F1418BEB28A229C8F63411446B83FDE11B3D946C9BDABBA08D495AEE50911CC66291FD0D49E426AE85EAA6C911C4DCA80CABA6E28E5F645A54D8C016DE51A2B98241A2911FE1EBBD66174798908AEAA16D79212E61D5C30364864FC1E09F1B20F296C11", + "ek" : "D7E90FE7B013CD1C5E8CAFD97B9F7ED1F45113E8EE7A7A494D8B77F5101353F9BED5518DB3FC23F7E5CAE4024A93B5D31FC646C09F20846E952746A1B5308BFCCD68CCEBF2B8C9C3597B4B2092D3906363EC4DAED1AE7A0DB782A57323A3C0BB3F560DC990A64DE715EA6F00A597292C69F60A75A3E9E144EE5C535904371768F3DB719454A8F753C0500CCAB8846D180498AE74BCEBE6E7D46F4EABE1D35B74BF9E0FEE07AF596E318DE78C74305DDBDD14BB15D964DF3ADA6673216C71A616759B55C52FF9A1B4B53D151C780F97581415C3FE90917F1EFA46DAE8696583B3663C095CB523649E383EE33E45543DEC99B02A42689ED22FC332125BCF1EDE08619BA8F5ECD6B41021B56B45D59387640DDB6BDC0632B2FF9F98F0B514A458D2C569C5EA1F6512CCF83B88829BB61D3BCE9D88C84CD699B13C765B41EE6A9176FA98323B68B1C1C553932C9A429517ABD362A961B3B4B80F8257F79A35C56BD52D8072A0EF9CE6D57C9F7016EBA2882822748A737664DBEF14C0A181F154D0644B52135C117B69AB5559ACA66EC67656541A5295880EFC67BF870169C00E316DF642A423FBED4AD26C3109D7D232C25790B1949FB69D1C262593B430202BBD2AC457E4896E4034486672A995661C1895E8F72592D24F6ED1610E8EBE74DB7D8CA8AB8CDCC85835BBF82732E841DFE4605A07C7520BA81678E33807A7DCE439FE49025CA224F3B9FA459D740DA83212EF313D0AFF1A97F06A4082C1ED258C2DB10A43313958BFC0DCA087398EF7C81472FCF2AB1FB63ED8C250B3A930E8BEF5F20036CFEA87DE76891A8546469CEB2BD2827ED17677A8079B46F9225E709EC67600767A082B535B20560596F1653901DBB51EAD21F6449FF0688ABD2F210448648FBC28D8678BFB837120B9F0E78A022F9BFA9FF72B219900A60FADD7C96C9CE1A62D72CBBC72856CDB46448C91630BB6BCC7871E9D526C4C426783EB4B93096F7BDEEB71FC77970BCB9B55219988EB4BE24B80FDDF365D05F12C0A6341C63164AE3B9907AD379D327715ECB956E2ACD75CA3EE89470E88D6C33E9A89FDA43BD29CB13DA7578A52E5DDA02039C185DE9298F794C26A01536A350EE2F01FD1FF3E03324E69EBFE6B5E4B56CBF60972740736537C0E273813490584AF25CBA8CA9CC07E43B225EA8CDC6C65C8C7B44EF6865F33B3525B175BAEAAE37797D716B96F60F7382EB1ADF34362C0B2DAAC279D660BAFD2EDE7AA376A1065EDB40FDCA47327BEA21F912706C3890F7A39AA6943CB8246E61CC067183E7D650DF95596DC7CB3422A06CB8ED52D16965600F23008247FB36AC0D7CD2398C279AF5C00F9F49FF07D71E54010602B246A95B89CD8A9560796E13D927A6B13CC6CCD0ADE5FC7ED6D2646050536A8C449393D9F9ADA03992E646F30D1EDFCD1D75FF74BF8FB12A607227F8F86455C68DA20051CD68968E3F6306B11400122826D28EF9602C70C83F0F3E252DC7A3678074AC4A3C059C46513F23C865A7246124CC16D8568BD76D7", + "k" : "2A8608EAEC1B8E6758CA31C42C5015C045D5FF951D78C56599947AB572C0F6CE", +}, +{ + "rngSeed" : "BD334D7B7EB14E00E68863F2E5551A095F8AF10681C28353FD19B9A7E70B8BFE266840860609008A567ABC66316C77CE", + "pk" : "2450C193211551409A9FF92089C54B048B6A80127C7742BA34333BEC498E28D729D6085FC7F5B6E5C4212A0ACA0772AF8F83200D422B49A80DFA17CF56D8277B792D7B4675DBA3A7502674F595A45FE93008ACAD026410DE336FA41AC0C725BF601280BF7B4D7DFB63789175B7748DC54846F3A8B28D055C69E2424704BD84F61C896A40447BCD42B96834C8429CA79DC4A4BE300C7DEE38A253E35819A43D833046F6437622094D003A3B9914BC6946BB4F4CBA41246CA027CF2E599A54A23E8CCA88086A6BF8AA92305185A8B232A0F45903224BA2D3276715640451BF49C350FBE5B2D95A5F55223A1A794BDE26012BB48CCB4384B3027855331E96BA09C7E757BC71AE9AB2A1ADF51FF01BBFD4C77A40DC3E24DA767D8B456979913AE97FA9446413084A45FB7827A082ECA1094A9437154B2C8EDB48D7BB893AE3213B5A95F86BC9E146657AE653F1C9BF54F87830AA968B96B747B9AED4007AB4030ED652652DAA9612D00F36BC2DD1299C8F2C84FB56045AB45279735AA1F57ECC470D7E66696A8B7A65BCCF23B63EA1D595363466A4D24540E21BDE05733154180D1A80652B166CC05AF5A7CDB2158471D52FA5006A8EA25C98167F4574A8A47A00B7C031E667A7DAF41B32C714AE1855EA9BBD0A1AA18BF64071C44F3783B30CE8301F20CBDC5C194D6131712386BB135AF9B55C680790B5147F55A6CDB94075D0F0C289F42AA638623C16BE446289D099777717B89922476D8C5511997419D8B5A44AC8C4A9589C5B39C03B045AC31A6E9967FA22C21F5BAE213065867945EC746F776B0DAAA96D85B61864FA94E76474BEEC06815B556FAA81ACE15C552558C0575C44E26CC4F919D3E26FE1374D2AFCBB3DE23A9BE5B366C1A174D8B78CA462705BA70B358D57A751180C781B28075435B2528104AC0BBFE5912F8FDA282F93B7E3292A64B83494563741789C98EB7E84D69C7CC2CB1703AB94AA71D7491C69B52949818245ACC6EF07C11FCB68C336738FD762269B7AC562AA7401965F2C5B2909404B32CBC86671043AC334E283AB194BDAABC390B0B2E275BDF0CC2651D11207A53DB1A2166B7526633CB779D88DA83357B51C962F567D03917F0F2B5C3C3B9BA75699EFB4A8A5736D98A56B1510CD6F233C2C05909A3BA6203C11ED72A0091785ACD729DD609704E51DAFD4342275564615B258691B59266A0EE3A8B261C6E9E9894B681806E97FBE3B25B4B133D804A0286A909752220C11C8644417F34597DB43AC66159956A11541CB4348C23196095BE01023E7B267C1E51FB0C11D9B787A519B3CA3F0AE08C79ED3F256A63B488E38040195983DA72F9CFC03A9C5A7C428898291A9BFF3CEA8089A343B73E616C5E02227553511722B04A1604D5AC718ED753E8ADC001FA47665B76F944C10DCE0635E9C98DD91B9E6790DA2B09CE323AB41CC7C29839784E6BA907979CE815F982585297B5170DC7AFEB94524563510257D99131981128C7953AD87CA696D58250AAB373FFA3476AAC3F650BCF58AA6BBE85168B7C4012B3359A2B6BED702524B8498D3AAA04C7915211E1E013E1961B0E2E32B90E01E0B372446931A0FE6255B412581E2B5C0D60D3B7208A63449B4216546209BAB2AD3767F9793D0BE98CD2899DA27F7D980122D0BDF593022E2", + "sk" : "D77060C9FC07DC7287876347EEF702737A25A8B192146A5BFDB637F936B280098224A38CE6311116518028CC005089BCCE93C7C4F65451B893EB1872D5470342D3627E90110022B78CA23D5EB97FFD9A16BE398271444D6B17C4C5CBC680FB9F65C844C86C40B291A3CC5A85096B3F150AC9CF1540D1A29AB0D30874DB91D17894D234C6BB376B3683273D198C73CAC396D942C7CC2C63B19204C15792071EA41383DC864D2619BDDDD11431D0B7299AA720516FCADA90AAC7148FEA3D63A14E95D01FB51C03D74BB49AABBF70AB50EF225795340086A0B95A9CB15349501F4C059B26ABF18161151C21BCF30D325C1F1D348B58B3BB0DA69DA24C18D6C75DF0F6B0E63414AE9739E9EACEEA4B00F0D33775121E78742F9C6AB1AEF5AA83B14D8BE365270583C0C90847724E39978095C297799774AE05CBD4794882349C68F5A2A2F23877E395C5E14286C9774AA159703312EF63AF3FB2978E22A5C1C0152B4139429783EA5BC90016701F1868C2CAC0ACF4649886B773E5C29DFB7BC142615F93216D2C3EC9EB90E772359614C57CA97C75B593CED123F6A8BF76854D856C65D5069BA084C75F10290D104F5C9AC498200190B72F004897A8D83B0DB3274148443F1B14108615A3FA02668BB9BAF1086503351FF1301E65085F65CBA909BCC42B32FD5578522BAEA9F515E48B040A259FAE266127BB6A8E338965051943C63EA536B5DB2C3B6C8998D4287922D5657DA1269E8071939B28AEF119B0EB66A87378064162B1151E852CB00F927D6DEC61BCE0631A93C1B51379546453C63626F2A792D20C36AFF9A3182C6E7B5833DA416F29772B70216732C376A4F59176617C885816BBE72C38A1230F484F1FE4671FDC1224E1BDD8D795C2E0917692517C4441CD4CC3BCD71765212B2E4986C881B2B0E8A0405BA2F7676A41F4AA152003CC185BE7CC22C9F402B878BF9D44CD32CA21CF92A720E35F81007345D3BF40B821F48B4B2D693EEED8CD292B636E7360F79237720625E966B9A5D99A7A452D2BC7066163A00647AACA62044938AC6B6598E9EB003175C2A29C46228C7B6464815E9A271A690E771601E252B251F411E6EA91F2F55EA0150A7A5405F536849AF80E0840C322C5B339470196B16CBF24484F407DC84819373109A9676298CA273D82BBE4E24946E0617E33897F170BACF4B7A312245FFB780F4C5100109F8C4B629AC1042CB7A946293F740A3589E069987AAAC2D996F5C9886D7125CB772A6D93761851076931180D87AE808A908D3C3C1203BA85739C6095B4FBEC78066BA9DA4433DC4928F4D73E03108FD8F531CD6AC47C088A64562E607C7BDE3867691206BA9C058432466EB54A9414C3A3127208A512AB5973B5D118C51468FA70BEF827649BE94D0D97ACF60B693D73B062249806275A5D475AFBD943E96A512F45CE54343BB6F353A9B1540F420CF4F01BB3611A09925E430237712A8C2B91BEAF7623CEDC6988990EF8006BC0DA49C57B5EB718409C8A06F81BA501090EA67519C261574B118EBBE1765A145309677AE4FC9ED499934E24500056372A25271F40BEF480218D978D6457AAC1F9761BB63679396490242558B2B6C617050FD902523A8C2450C193211551409A9FF92089C54B048B6A80127C7742BA34333BEC498E28D729D6085FC7F5B6E5C4212A0ACA0772AF8F83200D422B49A80DFA17CF56D8277B792D7B4675DBA3A7502674F595A45FE93008ACAD026410DE336FA41AC0C725BF601280BF7B4D7DFB63789175B7748DC54846F3A8B28D055C69E2424704BD84F61C896A40447BCD42B96834C8429CA79DC4A4BE300C7DEE38A253E35819A43D833046F6437622094D003A3B9914BC6946BB4F4CBA41246CA027CF2E599A54A23E8CCA88086A6BF8AA92305185A8B232A0F45903224BA2D3276715640451BF49C350FBE5B2D95A5F55223A1A794BDE26012BB48CCB4384B3027855331E96BA09C7E757BC71AE9AB2A1ADF51FF01BBFD4C77A40DC3E24DA767D8B456979913AE97FA9446413084A45FB7827A082ECA1094A9437154B2C8EDB48D7BB893AE3213B5A95F86BC9E146657AE653F1C9BF54F87830AA968B96B747B9AED4007AB4030ED652652DAA9612D00F36BC2DD1299C8F2C84FB56045AB45279735AA1F57ECC470D7E66696A8B7A65BCCF23B63EA1D595363466A4D24540E21BDE05733154180D1A80652B166CC05AF5A7CDB2158471D52FA5006A8EA25C98167F4574A8A47A00B7C031E667A7DAF41B32C714AE1855EA9BBD0A1AA18BF64071C44F3783B30CE8301F20CBDC5C194D6131712386BB135AF9B55C680790B5147F55A6CDB94075D0F0C289F42AA638623C16BE446289D099777717B89922476D8C5511997419D8B5A44AC8C4A9589C5B39C03B045AC31A6E9967FA22C21F5BAE213065867945EC746F776B0DAAA96D85B61864FA94E76474BEEC06815B556FAA81ACE15C552558C0575C44E26CC4F919D3E26FE1374D2AFCBB3DE23A9BE5B366C1A174D8B78CA462705BA70B358D57A751180C781B28075435B2528104AC0BBFE5912F8FDA282F93B7E3292A64B83494563741789C98EB7E84D69C7CC2CB1703AB94AA71D7491C69B52949818245ACC6EF07C11FCB68C336738FD762269B7AC562AA7401965F2C5B2909404B32CBC86671043AC334E283AB194BDAABC390B0B2E275BDF0CC2651D11207A53DB1A2166B7526633CB779D88DA83357B51C962F567D03917F0F2B5C3C3B9BA75699EFB4A8A5736D98A56B1510CD6F233C2C05909A3BA6203C11ED72A0091785ACD729DD609704E51DAFD4342275564615B258691B59266A0EE3A8B261C6E9E9894B681806E97FBE3B25B4B133D804A0286A909752220C11C8644417F34597DB43AC66159956A11541CB4348C23196095BE01023E7B267C1E51FB0C11D9B787A519B3CA3F0AE08C79ED3F256A63B488E38040195983DA72F9CFC03A9C5A7C428898291A9BFF3CEA8089A343B73E616C5E02227553511722B04A1604D5AC718ED753E8ADC001FA47665B76F944C10DCE0635E9C98DD91B9E6790DA2B09CE323AB41CC7C29839784E6BA907979CE815F982585297B5170DC7AFEB94524563510257D99131981128C7953AD87CA696D58250AAB373FFA3476AAC3F650BCF58AA6BBE85168B7C4012B3359A2B6BED702524B8498D3AAA04C7915211E1E013E1961B0E2E32B90E01E0B372446931A0FE6255B412581E2B5C0D60D3B7208A63449B4216546209BAB2AD3767F9793D0BE98CD2899DA27F7D980122D0BDF593022E2903D69DA169D8F3F65EEC290ACF30078FE51BCBD1AEAF412DFE2D31C7B10157CBAE49824E1A023A302CDF665AEC15B60F7F77AB2A0FFFD5246D07AE975A0614E", + "ek" : "027E1F6C6B020D9842E28055FD523F98EB0984B1337060FD68D92E65465CB184BA29747BB084B23C9750AE905B4AEA7C1EC93385B7704C2756337EFD94CA3C0A63E62B5C46956466CE699EF1C8E513299D2C517B934CA669F31E1449B543A73D74E808CE2F5F67555A8CCEA87DADA4851CED621FEB0DC5820C404812738E3025BF4F75FB002E8B01013D2BAA2E7520C28D44238EF2A244A6E41D9E141F488651B6168DEE9EBE1FD2A6025748E9E0067150254B1AAB95EE992F8E2633F61D1353FDD089EF6B66B5C73DE05DA544D239070722ABDAC7A3B040E04727DFDF747711C39CBA5F869ED17440495F81A4836FD79D64DFC14525CC05FE61066AA9AD9B68EFAABA1F01E125832452A78AD9E1EC1EA0CDDF84CF15CDE73F6699BF8D4626C3E4C63FD0406768F6231658726A955CC7844985891A85F5488C1B37849ECB29F3198A1E4BC316C94538ED981592D5D16ABD0DB13F0BAC28941C852AE1E76C66212F3887D689C3113697E870B4DD41B40C05661A820D60C52BFC09F36D2E997EA6B9BF1E0716E6FCDE4B7E3602E95332F49E4922F8DDDF03A273F930A234EB064115720591DB920A2140EF953335FB838E20B98B9CC5683CDFF3250212315437A3B8F86920C9B5A48A0F01D3CB02BAEC112872B987A0AB36E9390E80FA794903AB9007F4DB12518E3513EB7823EB83D4B955AABDF37D13D8D30580E68DA80D5F3623B61CB490757180CC643DAA9542221713BD552A125A2FF7F4103F078477B6ECE92AE46228E4E3C854A2E863773E53F8297C6DC52C38E7EE878A22D821D1D1E8E4BE53CDA8ED5E7A567A54DCFAFFA077B5AA62BAB4A5C2630D68DD5931F60FBFF09B0586FE09B94D45E85B45FDF1077D27639F9637B080AFB32D9984721341CDFA7D551EAD4BC00A685063929B879ACE59EE2DFD9AE332F8643BF3FC263C07B931A92761BD172DED54563229DCA54457FDD4E295972A9492788FB23A1EDBE3DBF9180199D6B9FD93CF41BE2A2D14FE7F562FA5509B125F2BBA3AE53940C42FCA9720F9A7F52538231CFE053D508F18515CB431F42224502F8734BAD6531E1BDB0C876909E3E60A554A72BCFFA205158AD852AC0C4E5BD93F4F9E01E8AFA7C1C6967A76DBA2E8BD0C59BB394333505F29BC9DF3F17AB2DC177A195685842DBB1AB8AAF508822C32B4CCB9CEF67305E9C82779CCE2D90BA86F834CDBD3B1B94677441BE99D85C6F5E0CA93F76132D45289E5E8F8B964830F013F74C13C495446223CB090AE98E09D8A4AB94625573E4C513771D19AB02F09F90C36F32C603E580A809E2EF84A72FF1170F0D3A815B333E4976330E8A301A6494E04533F08AE1279AF3E09F3E36D5591BE1819A4E142193A6501538B3C172E37C5A2C2065E035FE3B8BEAEDA9BE8C02AD16ED069150353D03179D4CAC5D28879158DCCF1579988E080BD3B5E7816F6FD0A09653D994A9AAA64761066D2936E4DCC042574DADE294AF205E312B470EBD6B00C9EBFDD48BC8E68C1BDCB32A876170BA0606C9D20C501", + "k" : "B547361846E889D87C5CC8E45FB7C54A7C3C4CCD5E01101B734C8A3ECBA73F93", +}, +{ + "rngSeed" : "A0264C58AB1F2CBCB212077FD378D340307ACCB31F1312137CF84E3D3135044D4EAE8BD38BC3E540A0C14D46458F6179", + "pk" : "352071C0A607E459C907FA29619CCFDB5147F56C208E20B3DCB82FA2304E40C46AAEB47C5BFCA8A9079ECAB4471D4BCF914C8BA459433CCB950772038F6892062535603B536DA65DFD5C33430069A7F33A08092BD9C9617DF3A5778B1D15A8A91C8B99BF5B0D4596A3F8A79D3B6994E823C20F102CB2353273471E2675633D9AB2C7668F02E7A68B2534489B169EAA92A8D78E4E182647F71758FC7F49A17FB400C1DE30CC76664BD10B7C55885AF696478FEB919F3C24FDCC98991177B52CA647070CEF77AB47C891B06575E5A0814311A75BBC9837A1C564246C163017696294533999B6700A1402552063A621205BC28823E539AD1C1795E0A23B6B47737AE839617548A514631319A78D99350EB77DFBA97F7208D04EA980546A9E6642395C5177BB7B433DD47351B85E569091EAA30CE450C1B786C0272B91F9763478AC5410BC1F78175EDEF0021E8C0B4F074BCE255AC2238A5D67B84B08A12984696E1AC7AD1131CF64BC64C5B0A1CCC94E3BBA85271975C63F8D314D9F1A2D17835F873846C6858F9F285428478B2EFC10BD7B49FFA006A6537684B0093A633D9CF9BF6BF97017690B4CE511B1898971B2978B6A1371E8AA70D970F8600BDD0109C84521E663845805235DD5849B192C12B49B43F824D9A16DBA939609E166A8B05E4811B970915DFB527D803672C7A418293937A0C508272A5186203BE64B4B1B33578D48BE3E23913E73A385A8ADA0FCC4CEBB1070CA3006EA16F7DA6EEBF8B9E6637DEE942CBE43395C8A7806F2C23D1C146D6359D268303A1229E5D513C79B2095892D553038B6A3431948195BAC491A879C4DEC39CB1B97374A65D5F066F6C66045A25B9B5889999889DB34B1F42B4151126DD7431389A8331B9C123AAB61C2122285530566EA23BDA21CDEDAC78CCAA9CA1566EA1817F4791DA6754379F9B0F8ACB217085FA380910ED3CE4A52CABBE52D75472A63C88DDFB423C1BA6C1DEB6ED3172CBC7244FB71300721AA13037EDE787FFD546E60890131D8ADD25551D72881BE0C8647AA10EB5CBB5F73C891868D4641BF8A692BCF0A5867091F4313BC976C989D1C184AEA07EED11E36C215008B56A55AB5062BB41F7C5895837093671FBF7C4EC63505D15CA7EFA5C6E45A5F5A757A4FDA02F9F13C7926BA7C990E6DFC8B20CA1A2A9490A33210C14ACCDE09764153BC9D4A2A68B7A80D9A91D3D47789C2A79BB212BC92812F8660F23A833D78A3F056AC030BCAD487431A6357B8A1C13B512DEEC79CEEBC37C6099B720445390277DAB65346EA323D33C76E30483D51B9D01B5FDD55BB7D116B2DCCA951292F3065B1628B1DBB86BD0CF5CE6A66BA1AB3717829019CEACED283C6B748B26425588DDCC47BC89CEB267AC7C03172B960160A6317D44FC5287C5E462911A8C995BB92EA1C81FED5BAADABB569F9CF7C1CAC71926F3E4A1A7411295A623C41240EA4E9011660227A785D989AB00A2C3091B02BD65A5B244246FFB97E23213F57B86AA21669541A60ED7014F1831839E41539DC8634D0125D61100EA4438AF59434A25A1EC0BC99AA0EDEB19D67EBCCDD22CE5FF925AE364AF7868AD6308A602033E0221AB609560144ABEC5A4792B8894337C866EC1A5DF4076739FED133A74636EC9D904E88876B678088D8C70F3C70", + "sk" : "D98CAB94A33C2A631D4BB8A0E314B78E68824F7B2156D3C481C32F35C82CDC5B2F0F41C2AE64295C246661DC0052209CA274B3AAD8221AC955B0F30344F775B759ADB1031BC5FC34E6EAB6A8A10F7C576E848B2C78A31AA0F951ED8B917277153D4842317474693C5643EA6A9D49A8E5A9BAF7C61F967C8679647E8C25CE3FF5A766F34B5E481DBF93550BD36595C51C51CC1C50DC278DA95325F483209119942A604D3724328A28F18A6559EBC23A2CCC7D647ECFD866B17B2F2F63B31E1886C309211E7238D2C2510568262A48291A9A7A1D5C38AA61C0ACFBC20E8C347C59C6CAC9BC402788DA55BAF1A7C3C0093E4707699976BDCA93646607322368ADDD9420DF669079322EDFD59BF09397C4E2392062B455D25044382E26510197106F681663A2616D7EC46EFD75646952875BF708B2A20B9B7A688F256B078A140F170E3187B4FFBC2D742756C1AC1B07A29916F8347C6643131AC72C8C0840CA7F6C866F20D32DC53A448F193B4B81583DA61837873B4239B9E690486C240315C387B6E5763CA226D86A028CAA07F4C9963AF99850F69401200F69C74A0024A4D9A7A54BB978E23C0F13474E978740422C606E7C5576702C25020415D263D9EA362F9556D64129EE182D22B76A8AE4892BFAA97B68709BF905379102A435500835871D192B48D64B5B31A5647C3634489CC2F33C6CA400371152D8148C0EA4ACB95B96F3E2919CCC251E6BC458AC635470437165C2BD4A9EFCE81471D652DEB6AA06359123B532A4C7C1A0AB0ABBD193042C4A2D82B69DF83045BB933EB43D1199A818F85CA0239EBEFBB9294657DBE33DEA89A844EB54F624C39732201DB37AC46838BCA17E0AA3B01448412BCB8EC98B26FD78CEE583948A37BF2CE996EE852FE1D1A744F2098CA5B0720409FA592DDE17432D424BA40A5362596393932C8CA7022435A763A367AFB41818E12B88548392F9973619B41430CC48339A241CAB26C68855B07CA4163169497E31831AAA57C3EBF384F3926B28374FC4CB2AE37173DAE034EC61C48E804AC0A347D721C670357A7E78198D3B3EAB02C168D26E3EF04D1468BD7BA4BE00013266FB8FE3BB98A138B63A45167494C17B89C6A6E939D75584E755BBE8048FA2443C57F07F1F178965047E2A59C6815A5B92B6691C9C9DCB6250BB73725586B57C8239ECCCCC2FD418289A0406671D68E79E4118304637C9468B7312805599960C19A824582B5182DCA37DBC63D5D33559A79BEB56C60108C5655789BEE1C42B75B73B9B336140B202B61EA32324134B8DBD064BD3293650C5B8E8F87793080E509CC7BEAB0EAC8679CA5A723CFC119BC1A18E7631910A2F50601FA280084B98AA81C38907F0A685B3ACDD630A3532ADA83648BF858084D087C60B1AC73C76FF4477D9B01375A7CEA52280B404564DD69C46E3A2125729463CA7FD724C35738094E627E5F1610A9A00EF7294F4549470B993D0447DFE34B8AC264C547A0B7A134D19AC2BFF750CF2E4C80F32679375CDF0906346D64A56EC7648C4B7A20613C9B74301B12D40D1AC64F8318708820006D06E088811860A1CDB300187C694335170F6539DF45834B93EDFD4275E939FA5F828B6E471A5E09B352071C0A607E459C907FA29619CCFDB5147F56C208E20B3DCB82FA2304E40C46AAEB47C5BFCA8A9079ECAB4471D4BCF914C8BA459433CCB950772038F6892062535603B536DA65DFD5C33430069A7F33A08092BD9C9617DF3A5778B1D15A8A91C8B99BF5B0D4596A3F8A79D3B6994E823C20F102CB2353273471E2675633D9AB2C7668F02E7A68B2534489B169EAA92A8D78E4E182647F71758FC7F49A17FB400C1DE30CC76664BD10B7C55885AF696478FEB919F3C24FDCC98991177B52CA647070CEF77AB47C891B06575E5A0814311A75BBC9837A1C564246C163017696294533999B6700A1402552063A621205BC28823E539AD1C1795E0A23B6B47737AE839617548A514631319A78D99350EB77DFBA97F7208D04EA980546A9E6642395C5177BB7B433DD47351B85E569091EAA30CE450C1B786C0272B91F9763478AC5410BC1F78175EDEF0021E8C0B4F074BCE255AC2238A5D67B84B08A12984696E1AC7AD1131CF64BC64C5B0A1CCC94E3BBA85271975C63F8D314D9F1A2D17835F873846C6858F9F285428478B2EFC10BD7B49FFA006A6537684B0093A633D9CF9BF6BF97017690B4CE511B1898971B2978B6A1371E8AA70D970F8600BDD0109C84521E663845805235DD5849B192C12B49B43F824D9A16DBA939609E166A8B05E4811B970915DFB527D803672C7A418293937A0C508272A5186203BE64B4B1B33578D48BE3E23913E73A385A8ADA0FCC4CEBB1070CA3006EA16F7DA6EEBF8B9E6637DEE942CBE43395C8A7806F2C23D1C146D6359D268303A1229E5D513C79B2095892D553038B6A3431948195BAC491A879C4DEC39CB1B97374A65D5F066F6C66045A25B9B5889999889DB34B1F42B4151126DD7431389A8331B9C123AAB61C2122285530566EA23BDA21CDEDAC78CCAA9CA1566EA1817F4791DA6754379F9B0F8ACB217085FA380910ED3CE4A52CABBE52D75472A63C88DDFB423C1BA6C1DEB6ED3172CBC7244FB71300721AA13037EDE787FFD546E60890131D8ADD25551D72881BE0C8647AA10EB5CBB5F73C891868D4641BF8A692BCF0A5867091F4313BC976C989D1C184AEA07EED11E36C215008B56A55AB5062BB41F7C5895837093671FBF7C4EC63505D15CA7EFA5C6E45A5F5A757A4FDA02F9F13C7926BA7C990E6DFC8B20CA1A2A9490A33210C14ACCDE09764153BC9D4A2A68B7A80D9A91D3D47789C2A79BB212BC92812F8660F23A833D78A3F056AC030BCAD487431A6357B8A1C13B512DEEC79CEEBC37C6099B720445390277DAB65346EA323D33C76E30483D51B9D01B5FDD55BB7D116B2DCCA951292F3065B1628B1DBB86BD0CF5CE6A66BA1AB3717829019CEACED283C6B748B26425588DDCC47BC89CEB267AC7C03172B960160A6317D44FC5287C5E462911A8C995BB92EA1C81FED5BAADABB569F9CF7C1CAC71926F3E4A1A7411295A623C41240EA4E9011660227A785D989AB00A2C3091B02BD65A5B244246FFB97E23213F57B86AA21669541A60ED7014F1831839E41539DC8634D0125D61100EA4438AF59434A25A1EC0BC99AA0EDEB19D67EBCCDD22CE5FF925AE364AF7868AD6308A602033E0221AB609560144ABEC5A4792B8894337C866EC1A5DF4076739FED133A74636EC9D904E88876B678088D8C70F3C7008CFF1967030A528E748B708B0FB783577F249C04EA5536D2DA034FD0D15FBACE39CC6C99EE6FD8653D15505A6C2A713D41B43FA521CFB214E8D1B38440F4640", + "ek" : "168F34C52DE86331EABA699C046CC0E118BFA3D171E301494EE1DCDE107D5C4104DDD471388DB3AAAD6F6645183FFC95BDE59582ED0918422F2805681F8782892F48EDACA599CD1F1F3766D7120375807414D544F165DFC2CB1BB9E2307E528574478D9D4469A188F50B1EBDD26242582B87E9C90E84640F4325781A2868BF964FB5A7E40421CB32A9BF6D1B1A4470B0EF1547AD536F09742ADCFCA8247A9D1820F25E872DAB86310A69324E8724E119279269FC6B5577EB8D1C128ED796D40867DF1B01A5C38BF419F8F0D1B2559A1B5268F3E37C488927F332F0E318B60CFCDD9FF31CE7953A1AA631805C1AE2A51D53F279E7F6DBFA647A9BA7FBE0BED3F23742C6D2AC22A23D201ACDE0732F55D88E7E2E5F15F5D114D03CE9693D3C24EA31C38E52ECBB61F4E71250504BECBECCF5A5B79473F5EE5A6583D9A286895247ACD5947D183F7ABB5E2BF48E74985B79FAA0ABE2BA4AB467C514C7B224B4C5A2B8974F6AE62DACE276C077C2E2B68FCD1E3161CCFB855003911487099131A40FDE44879D16D514C29C7C48EE7A62AAAFC8BE168023B05175F4DB7FBB1A9964B5DA65545E4ADFA4B7A478C920DFB8E8FEFE3CDFC48296CAB025FB0EAC3BF5A8DEFE5F88BE96D0E90B35E7E8CFB4B8E305C63EC7CBF3AF4B5D9FFBC7D5EFD54A2A5E5E7BF9E203AB3C7E556D2EF60122EA0A2297453317D19316D047DB4E507029A1187518CF10FCE742FCECB85AFF457869C3C9755573CAD3EC4864FED37ABB58AA921ABBD62A7AEDA1FCBB47C7EA75420FA78FDFB5648CD33DFE995486C213766A80DB5037735BD653C2A779A94867CB41CB8FF19CA03CB6115A0C92359F98C508C10017B4D4A10B7B5C0ABCE2C8F1FD74C2D3E83B6B14B295715927EA91CA60FC8976B38036DA4F5EDF91AB8AAF56A2F5FD2F66A9F2DBBD83868685139928B35FA45D77F53E638BFBBF60322C2FDEC164F330D1103697A2E7A25322B6365F3C5030867C4654BAAD682F808C94D9177DFDA5865CF6C8270872D0E48F4DA89574BE9C892C608492AE45C29DEB0896CA1E9952737428C7EC25478E5D2C43705826A6C163E3E8B48D807E9DD848F2C90263BCF4DD09F2FBA6132900873A0EAAC466F8F89D3DDC2D1D520D5F4EA0A6703A6844B411C6EBD88C1D5CBCCD4E66AEE96229D80B81A2412A04666031BF7CAA9A3BE97EC772E46C2A74A6F004C407AC07674708B296EC998B37D595B605D364B41291352EBBB2CBF4361E4817B703D800263A2644FE53DFA6141F35BC3CEB99A3871B2C4FEFA695BF5CE5B438753D4CAC7DEF78233109668F810756FEECD93EABFC555A60489111A0AD031E8C40637BB6303C8C909D94BB285DF7065FF9976EE58D6540973B47295BB6EBC7BC5DBAE9DA41FE3C19E7F22AAE6C4A63B808C7C602A9609472256DAE7542687DE46270A614638651ABA97D1517CF7E9D50534CED83177697D5F6645B9831B30E79A134F7C17F962C6C3358B5509F9FAC7B7F4903579BC3A78EE03863208684B56EF6F9CEF13F", + "k" : "FAF2CD84EBC467D4A29FEA1FFC4D62B2396CEFAFA7660018D3E77783528C8ABD", +}, +{ + "rngSeed" : "99A9CDBFC674AB3FF2C64CDED7D697A6E27A767434A47AFF7C3FBF3C6A22D6043D27868955286A13EFE3DE36D22EC48E", + "pk" : "4A5058D467B5FF439FB0C2916AB09BD306661B18626746C8F4DB817E3C4DD2C71041929DD7C5918A760F50715C6528C2D2E7C9B97C51E9009281849CFE4410B616CE03455C73580FE16634FDA087387023E427902180C5E8276B797ABCC47028CAC91BC751C9EC4A9C39D682CB38B38882103839947B920ED453A766C04DF7BA58F9714C6C370B98172A71FB7D254285E609551F31444E90C2B1D595472825FB9CCA49D55C237A67377808EBCC1BB4848A75527EC467A7F94B8C4F8B1A16F789F3CA15F4F332FD0160FF6C4985B08B9996BD08892D5A836D50566BDDC6ADC6EBC7D3C95068C08682D54E70666F5F62B238F69BF86A3A48421BCD8B762625C06F03CD8E013561ABBB2F01B1C314A6A61500AA02B9A54682325340BA328761140781885FEBEC3A4090A5989B914A494D07E9793B703ED4B45AF78C42F3BCB46CB4C7FC5352802BA0EAB35B9F66C34C39259AE52D1B75B910A82FBB464D37F6BEFCAA811ABC6485F41D38C8A4D1592EC69B5CE90C7CD10C0082C0B72DFB2E5A16B4C7AB6E65F58FBEB6C442FBAA2B4345B3A3326BCCCA3B5104730520383178589C4B4C751796C31AA061346620BA90D30B340C541F7CAD17F86E05C91E4C21162F618B52117DDB572E1B90C0E19235A82A3E51B59C3B280CE3FA739BB70E4AF9233831269FF87F3114596F317F28DC11B8B53D578A8CA85B290D31ABB115B76C0A8748124FDB822F989C241B801C8B982FC733921D45853CF63880107704BAA331B725A416471032A9289673F3ECAD22050D9C5C9E2706A341553D168BCBAD1A41A3C554260112336430FA16CA8FB98CF5D92ACAFA8FB427C460A27AA08358B36C5AB849CA2725B72C939FE0601D1E2ABCC4434BD0AC835751315856922ED53CDC7B49468CACA339AEDFEB25EC2B97D43BA409693FBA524AE4ECAEE5B84B567432270644D6AA618669734E10C8B05A0D697B81D6C83C9F844CDC8AC755403044B14C288131E8C0C21C2361B206597782313D40BAD1D56DBE159735491F7B800D6B14CA69D92BF2130BADD1858B2CC4A408C33EE56FDFD719ABB2A431132E15B89D83498B6BB5AEB0D7404E94CCEB2A29FC392A2E466469E53DA9C371E0155A774A298D515D70EC5E31AA070BE92C3D6290F285A6034A97E389277EB393C5100F066C588AA33E66028976493BF41481B2EBA07A720937BC02B5324D63B9487A1789A6BACA91512C1A3A0A70B348C1596CCE7997ED395B971442EBB3B0E2DBBF5608012030A172B259AC705AF9634AD585916CD63EE1248CA143A20001A20CCA0496734C2C52A59BB40F76411578E2C60F2364E8763EC1E5641C80A9D6235D4FF9CA73F4C4D6DB9BCF3383D7D9A025AC76DB1CA49710AA281C222A4BB81B1027D80C38C8365A39988A029A93B5DCB2B0F410FD1B63A54297C65B7DE3F3A948F10988B507955AAAA2D3C699DC83EF348E3781C8723B9BD1C6637B94B6CD416427592C71311A16D449D15C0FB2753B338586F7260CDF255CA65CBC8C54101731A45544312099A66405B01EAB124F116CAB0003BDE314B25690520A9A2131154271C89B97539035652C03B462F2635DB501F9AB6983017F22B3391A67397066C86032A31080D329647A7C4F5AB89A47393636FF0671A4B06948C9F87FB580358D467FD3", + "sk" : "9483B4FD275ACC8CB660713BA7A57BB442AA743537E9E4B3DD73C5D3239CB876CDADD5A1DCD364327A7F8CDA092D6841879B0FC7B64E81216C9ACB87A4150A3FE7BAB7058A6C6464FBB9AC71954E65647083F42ACDB15829426C53C55A7984074DAB019220B5F570211DB614357CA0D3DA2B648B2AF10C0CD6008AC31AC8D995AF6C44531D1125CB710A6BC4A573F04558A97EED49071F748310A9C844C63B491997109CA079613D96C2910B365EB343B3E405B749F33CB6A3502ED634C50196D364352AA06F5A149CEBDC2E59D5B27C828292332157E98893494FDE7BC51996562F13081F2BA89EC4B416C4732946B4AA26C5E5600A8B9B18278C51821CA36E153AB0A763DBD397693800A62A1E3682C9F71154AEB6772CB3368B6465400C7B4B200E571390165CBF56452072E38B797BA0465238F9E80652A0BA700951FED03FAE6C91787C8B2C752A02A4AE52A16B4D1B057931174890656B53984CEB20B1B90D6FB10103C97F5DD7A0EE83CB2B34C85825766EDB64E2135F897A6AC1B144FFD8225A9887D546C0D9F1B3D851003E810FA2193C856C7944315869349C93DC84616134C3901D1F137358984341069546DA01864A16CA44025E78CB36744DB7B3045425243526524F064F8B46C862A7660ACC557D71574F227EA5D83EBF2C52DB172B4FB7A70BAA0DF43A776A326CD2DC4367B89843A79205F34365F3B206798550C5624E241F03B41D56776C88636611FB1BE2656FDC1C4E1EA84B0BD1B7C804BD53795DB335531C896EB72558E6805599CA66AC7A77E4D9A1FF20349DCC76F78CAE6C59B93A8165788216A7A611E2233BB4346AA01B47E5B458C970A0CAC589F0CC8435B25D74A12D25F10DFB51536B465F085CB170757F8181C7B7C32176109A1A8BB3A59A4D545365960267746349CAAAA182136E17F4A32BB040FD3038DADA40C8443694789654DB794F185CB7054C6BC50F9A24AC2EDB5F34EB6A5B410561C0B12E803B998BADA9E346785CB2C8E251989354540ACBBBFC8517ABB5071055CE7AC646E0197B89390516B9E56BB174D2B28D3AADCD0A51BF098F3325642E9B753015AF338A8D309000C2313949B2B30314B924E5050BB278C2C4CD96520FD8009C8944569187A69A749B651039CA5443C30B7755782D1D5A289C4BAEC0F0B0E8153F3986A969E113CBA21B41A06F8184B586FA312606419375387EB08980B86F97B382811400E82260D3CB5C74FA5E57B15C06AA2D8B250F92EA0BA222BE524459A589A7AB46AC01A5564975CAB66002C20745824C313D6167EF2C5A0266419B291401F6CD5B2497CC4CB7A7FB8C67A8761541CB281665F6DA184DA0CA520395CD492C86A3AE8AA91BA3D24D52322CEFDB38BE7A6CEA16209CBC69E796A2C43B1581A015C2E37DCDE072CC4012187276E81B54C20C6F95A6100093CBD9BCAC7B75A904EAA9EC31338203C40CF28425EA9C5403AC6CBA4CB8051CC2C5BA3F592100AA4188E2696211846BB68C4E39CEBF26464B19812C98C0472A76E0A44B2631C01201546AC9982EB8334AC30A4BE25342D48666CA41CB63423B9BAF290499C27321B5705E8A70474B2BA392A34C17E1A4AAC49DA90CAB751B0E5F50984A5058D467B5FF439FB0C2916AB09BD306661B18626746C8F4DB817E3C4DD2C71041929DD7C5918A760F50715C6528C2D2E7C9B97C51E9009281849CFE4410B616CE03455C73580FE16634FDA087387023E427902180C5E8276B797ABCC47028CAC91BC751C9EC4A9C39D682CB38B38882103839947B920ED453A766C04DF7BA58F9714C6C370B98172A71FB7D254285E609551F31444E90C2B1D595472825FB9CCA49D55C237A67377808EBCC1BB4848A75527EC467A7F94B8C4F8B1A16F789F3CA15F4F332FD0160FF6C4985B08B9996BD08892D5A836D50566BDDC6ADC6EBC7D3C95068C08682D54E70666F5F62B238F69BF86A3A48421BCD8B762625C06F03CD8E013561ABBB2F01B1C314A6A61500AA02B9A54682325340BA328761140781885FEBEC3A4090A5989B914A494D07E9793B703ED4B45AF78C42F3BCB46CB4C7FC5352802BA0EAB35B9F66C34C39259AE52D1B75B910A82FBB464D37F6BEFCAA811ABC6485F41D38C8A4D1592EC69B5CE90C7CD10C0082C0B72DFB2E5A16B4C7AB6E65F58FBEB6C442FBAA2B4345B3A3326BCCCA3B5104730520383178589C4B4C751796C31AA061346620BA90D30B340C541F7CAD17F86E05C91E4C21162F618B52117DDB572E1B90C0E19235A82A3E51B59C3B280CE3FA739BB70E4AF9233831269FF87F3114596F317F28DC11B8B53D578A8CA85B290D31ABB115B76C0A8748124FDB822F989C241B801C8B982FC733921D45853CF63880107704BAA331B725A416471032A9289673F3ECAD22050D9C5C9E2706A341553D168BCBAD1A41A3C554260112336430FA16CA8FB98CF5D92ACAFA8FB427C460A27AA08358B36C5AB849CA2725B72C939FE0601D1E2ABCC4434BD0AC835751315856922ED53CDC7B49468CACA339AEDFEB25EC2B97D43BA409693FBA524AE4ECAEE5B84B567432270644D6AA618669734E10C8B05A0D697B81D6C83C9F844CDC8AC755403044B14C288131E8C0C21C2361B206597782313D40BAD1D56DBE159735491F7B800D6B14CA69D92BF2130BADD1858B2CC4A408C33EE56FDFD719ABB2A431132E15B89D83498B6BB5AEB0D7404E94CCEB2A29FC392A2E466469E53DA9C371E0155A774A298D515D70EC5E31AA070BE92C3D6290F285A6034A97E389277EB393C5100F066C588AA33E66028976493BF41481B2EBA07A720937BC02B5324D63B9487A1789A6BACA91512C1A3A0A70B348C1596CCE7997ED395B971442EBB3B0E2DBBF5608012030A172B259AC705AF9634AD585916CD63EE1248CA143A20001A20CCA0496734C2C52A59BB40F76411578E2C60F2364E8763EC1E5641C80A9D6235D4FF9CA73F4C4D6DB9BCF3383D7D9A025AC76DB1CA49710AA281C222A4BB81B1027D80C38C8365A39988A029A93B5DCB2B0F410FD1B63A54297C65B7DE3F3A948F10988B507955AAAA2D3C699DC83EF348E3781C8723B9BD1C6637B94B6CD416427592C71311A16D449D15C0FB2753B338586F7260CDF255CA65CBC8C54101731A45544312099A66405B01EAB124F116CAB0003BDE314B25690520A9A2131154271C89B97539035652C03B462F2635DB501F9AB6983017F22B3391A67397066C86032A31080D329647A7C4F5AB89A47393636FF0671A4B06948C9F87FB580358D467FD3B5ED4C3FB678A44D92486CF091333C7F035541614729496D5DD45CE580F0D263D55EEB68870B6DF148654F14EB4B3AE9084B40F8B5CBC83FF4C419DBBACBD190", + "ek" : "F89BDCD620FB98524C2DC298B6E334885AB6AB63BFE23913CED9D66E36534DBF4D29DB82EFD0FA23F54EE3AC9F839E121AEA66432ADB8D656ACF709B5EA120E6D52CBA74D8B6E4BF9A579B0E955CD6B1039BE0C0570B3EB4A7F1AFC80F08514F46E4DADF0C18923A2C76A2A060CBB8B3D1D99ADEF1F6C13B88007E1374796E54F9B9203775C181093A07873FEDDDE342D28028F64561ECF8A04F2FFAA4E7F8D56B2B065A46D9EF023793B47C5791764372C6FCD4CABCCB490D6587E1275A3BDC4DE7684CE1527E7A3FD439E9204BB325D172F0DBCF0F81215D5BA76DAEAD64B6ED00AF082159D948A23D8355E472069A5019241AB726253D6DFE6B2E0BE0C02CDB033B67393403665D1873D8AC3E0A02026AC4C81BBE96FCAEB8AE588A5D69A41BD8667B66A18D24896C85E4C6504B06D628FFB84B646A299F660F5EAEB8C2FE96776E82D832202DE52E62FCE2C9E0622C3A5F7A7E6665C916DC1FB3E48A059509466DF179B4AD21FDE4C5ECD34CC6332694535C5DC08E0569CA3532D6C5B53872159C3E123BE9286E054BFA6001DF850790E824C83F0614E2AD6FC3D6187B1DE6E195F24A516A672B796000A2A6C184093BF5C71AD6398863EEF18C78137DB392C0700A502A7F05C3AFD869B86F5CA1F2E16A8E3FE7B02EBEEAAA833A49D7DFEB80A71EA0E60E3B97BCE94762FEE37041D65E585CCA7D2199DF6D2B4DF2880E2C7FCA948DF8011F361D9AAC87BA03C05B9B44BF16AC9A097E994E85A4A616AAE40DD2AA67959EC862E18FEC80FA4E447C328FF2C23B82DFA33557431C09C82BDAF3E5A4D7BE224C0C13946865608C9E75ECB4614402421894B5249A386B24B2AF1C824D93C5B16AD25C56EA7D13891F20E39E8327D672FBCD824E3A3170ECF4BA375045DA6066B3AA159191B172BEA1A4AF42F254829BD21BA6989E80FCFA30AF0800D512753B8B9B4F1E8ED8246EEC6B5821D6704BF95CC114BB5BF99D9B84EC1135064FF906446AA59A9A8E73B698D57E1271C04525BCE398344DF4BF6938208736FE67ACAD1DBC5F554F3991EE9D98771CA215D34C38746F60C0F4D47CDC7645EFC422AD020F02D9E0D70E4D24345CA44F030DEDDC7E348565516CD7148E8F1A72330A232DD05E566EAAD131A3E063490B71648A808FE32E693536CC965A6FFCF7C3F949CD143E7B250B4B6C5A08F72C969AD34CA5BB414D6B09902E1CC54DBA39CEBB6910908C502786287FA9C5E1D29FA86022913DF2DD36207C7A03846A884042437EA10F40D65ACEFCACF588AF1FE5E1490D8E492509C5381EE223642A5C1C79C39E7E600DC838E4BAA9D31DA12A35BB1F7CDA43FB2FC7C0CA07057CAE76DC20D72270427E8B73A2AA05306A043F035CE685B8FD0A44BC3600EC137811AD6F78FF624514571D5600EB0971D7E1F7857C0E44E4E87920B5791FCDF8C071B6D5D4B9B643E77F029CC95AEB5E2C2A36700EA5D63EA2DD67CC47A047906ADBFD9BE0D8EF278CD550E0C8E4D3A0337F04EF0A5C2CBEDF547897E1715BF277", + "k" : "A76A210AF553C9A9380D3241BC797684800AFCE10707D50BAC06256AF813498D", +}, +{ + "rngSeed" : "C799D57B41F28C5C446DFC58A5AC6499C4BCF3C162AFD2B09A16549826EC2A6F689E44BAFC4ACC82F5D6AEC23F4A3993", + "pk" : "D0A4700800708A0CBAA0E3347235004460C8F86188AE66AF363BA5CEE88B03A341F5255C329A7D119BCAC87C46BD77A1B5966A3FB22A45D89C712909FA8C69967B1FA8878D89B8541B8A1EE6858932E0793C045DEFFA62250C0D0072A46328992BA7AC4FD72B48512C7448CEDC902D9D69CA55626A09D1A700A92CFB1A6BD89291632C74AF580E3B4AA932C8C6714337B1D72A3002C6B68B1FC981CD0686502189712F0C5327E1050EF71549ABA312A59E9A342C9E76A96DE6907CF235B6E3B5E36A9072AC95D856AA7014699FF48BCB7B298E5168CFFA740E0A5BB1F65DF9CABBD715096CE738BD39BAD530A05EB58EFA8B9E3DD426F1781A06179736570611C89A6F99B3C0AA5F4AB2737592082FF73DAFD7671BCB60A87C5ADF3445CA3381A279C6A4FB1724373827494E294CA5D83574E0877E4A31634ABB106B81AFD515402290318CA8A2511CB129AA52228BA4A64444B761C184A3A29B221E11CC1335E4B87C457710FA4FDEE790614249FA060B0417CFAF9BC4FE88632A76766FC8C5FF424849CB91D4351EC621C2335A2D7813C01CC893C646986F7C2246B2BB05149EBDA38F00ACB65CB8BF53314561893EB0F1053B237915711B7577B18AA963315A3B024629689A52BDFC81E298C059380920AA5BC39759F2F56D2811C89C59ACDE3A5496F1A8CCE9BF5266B363A40CC1B6C78FBAA4241340DD4563A5603413CB73BA1893BDBCB3FF93BB7F1132940998427769D19047BC051506B5B990074E8D1BBE2D988699B526726A91513988627C2301B44F206696353CAB38F68CA111270CCC6CAB887AC3B8BEDACC12513CA349228B0D842BC193299AD1812B69C63C2B8233C20121D50793906C4014453E19A62DA12C76F03667031F2BCB59A074CDD2417BA3789E7AF38AC71335736890DAC04F77E0B10529381E930C8C0031F88838EFA47772A7B2541963B0C7B063472CCDF6228349CB5619C943067AD86019CD964C64767C838407EB32A4ED9C40581B63E0379D00ADB275F6578F065894E8A47796489B994AB9471235455FE1F819F3CC2B378648AC625107805EC8946F1599A8329981A7775523F7C8EF7426D8A31D1D5CC98820186FC7B55076B14D2C7C1533CC3217354BB24661C162AA0895CDC4AAEFA666686A0F12D1791ADB7392B78D31D6BEC44068C4F31CD60A768AC0B056C24864C03387715DC48BC86E1B51A649CE4945708951065F946E17C06F364590E4D16520FA2B47B230F1511FD02AAE79BB8FA72791806B0D3E211DE92455459066B410BFD4D437F0ACBBFB02BFC5E93DC7904B649A6F9A7AB09E2679E13040C8E9754032CC3FEB8C2BDC21D8F7AA56EA31370169EBCACE98D54362EC24B6B6C63732B882984E58839A7F825B17871820EA9DD0DC8C5E7A15403888E80150CF5A12C5E26040708791D2074DF71945D67F221B6D2BBC1B65D37559A7C248516CB4CCC19CC15F93BA6D6085BDD95568CAB1069CF13138B83173EA7C58EBBEA7516C6AE25BF5E07DDF29A0DCD64B455AA6E050C1D5663245318833CB95702BCAB1A11FDA773A73454E1055104F917B75D650DFE1C59E807314A096DE713E35837BA4F2A5F3991F6AC18302647FE01A05C055AC9D19FE27027CAD17633DC0F4693C1F79CF69756E79C9FAE7C954A0CAF2C6B326", + "sk" : "FB2ABF16F6CDB674757180738286B5CBC25EE9EB1229F3781A8678CCD0C5D4219D49352913BCC4A404503D7282CC215AE337AE96C60FEFC6A77E5C600962024E25328AC211D6D6C325746EC168777BB4489B04CD869522D44A62D1BB81DEA56E8EF8384AC64FAD710EFDD327410C6B7D184FBC639E2F6C72D64B44BD303C06779BE8C2B2CFFBCB8ABC582A2766EFD9503745773CA2C4F92769CFA2B4E9052D06D1ADAB40137A2419891BC9098898935650197A0E3DBA7F6EC54AA9B521624C48D265A667AA4269A12BEA0ABFC0E705FE422621848A6A87265F687DE0669F56C63968569C1D807826EBAAC30173586312F1EC53B0B52EBDE2AA82F32FFE592FB90363CB3A281F49CF9E16B9BA4390072C5A796C4E4AC95CE2E14070014034A4A92F8C1FE4733C645B5DBEC38129A4021D5C1AFB9005C1756E37F431D89177142891827519D2874C9D1273967B176A311F041270CB3BC8D0779C3E40BF824102374A55FE5B2598D20D8D30249B59479946936FDC6B0E17A39D4684BD914479110E68C780F8468E3155BE5ACB0930FBBEAEAA79BD655592A28622CC0553A3123F2A9FE15B78C89501B0943731E71D2AB05FCE4129B6324D66991114974DD7E79DDAFA46879286D8D5BA285526F8767AAF45184E860E8E23BA7458AABFEB021EC68B19253A19204C7FBC81CA904CEE1A2B7C38982C97A01E2330292168198101E0F30C1A429B3D243EEA7114DE5849E50249AC66BC24E482461895A9D28F4F181E5B036E7299832A14BB02435D9E087F7340432A632BDD84AADA7A657402BC91B3B0A1075E39D66741E18855826FEF247B6E1496E3866F9A2226C4D2A198C050AE706F007D1A4317B45AEC0A1E7A2E359B695DC7523050C564B717E2B1005F570235129D913AB2E5FA99CFECA4B4262D48F0486E6B3C47A61946114C69150B068B92A8853C26A9C4C1016E67CC90CEF8CDEE024785E58586CAA9F990B48546BEC008956A1744DD9473F4A150445B8C46A1C4B171712C1B94A9743FBA6B389B8852175B0B1D093D8D7C10FB079DBE65771A8120C1930F769B8FDBEC6F857025C4C44771842D8D42ADE8DC3712D9A9256167DCA6C1CAF1A95301CB6401AFAC63A7D0915059B6A7E45C0567C951A3096BF5CB44114091D497352FD2BE702990608991FEAA7302511E838C9A346CCC267CAAA9C5221EF60B317B6C3A18A07DDC737E6221D28667C70CAA3CD24533175AEB0A99BCF7CF60AAB105385906FB1167CC26923A2F3C390FC2D150D3760D77B8954A61065814B6D134887B570FFA944F2D1299B6E6BAE557CDB041B2B084792215CFBE30302F39573E6456F486B8DFC22B95F96B78098FFD343126671219244DF0C4443F46473818C78F185DCD4765ECCCAF4B67276F697D21108EBC16632BE86FA48278D467021A1520AE6B0668FC7471C9262EB716CD307C98A1C205A83BE5279B0143806D3AA443CC7E1A255D2DF178E7E298D938C97DF6260A278052B763E1BBC2F85B1389B78ABADB449CE848B0EB8A5B44B2E881AC3E6BC66A2CBB9C998A0F3A2439816809B97D066B87DA226907D581D981481FA8833D9AAA2EB6B5458288872C5974D9CF06CB6DA269471E51CD2945B1D0A4700800708A0CBAA0E3347235004460C8F86188AE66AF363BA5CEE88B03A341F5255C329A7D119BCAC87C46BD77A1B5966A3FB22A45D89C712909FA8C69967B1FA8878D89B8541B8A1EE6858932E0793C045DEFFA62250C0D0072A46328992BA7AC4FD72B48512C7448CEDC902D9D69CA55626A09D1A700A92CFB1A6BD89291632C74AF580E3B4AA932C8C6714337B1D72A3002C6B68B1FC981CD0686502189712F0C5327E1050EF71549ABA312A59E9A342C9E76A96DE6907CF235B6E3B5E36A9072AC95D856AA7014699FF48BCB7B298E5168CFFA740E0A5BB1F65DF9CABBD715096CE738BD39BAD530A05EB58EFA8B9E3DD426F1781A06179736570611C89A6F99B3C0AA5F4AB2737592082FF73DAFD7671BCB60A87C5ADF3445CA3381A279C6A4FB1724373827494E294CA5D83574E0877E4A31634ABB106B81AFD515402290318CA8A2511CB129AA52228BA4A64444B761C184A3A29B221E11CC1335E4B87C457710FA4FDEE790614249FA060B0417CFAF9BC4FE88632A76766FC8C5FF424849CB91D4351EC621C2335A2D7813C01CC893C646986F7C2246B2BB05149EBDA38F00ACB65CB8BF53314561893EB0F1053B237915711B7577B18AA963315A3B024629689A52BDFC81E298C059380920AA5BC39759F2F56D2811C89C59ACDE3A5496F1A8CCE9BF5266B363A40CC1B6C78FBAA4241340DD4563A5603413CB73BA1893BDBCB3FF93BB7F1132940998427769D19047BC051506B5B990074E8D1BBE2D988699B526726A91513988627C2301B44F206696353CAB38F68CA111270CCC6CAB887AC3B8BEDACC12513CA349228B0D842BC193299AD1812B69C63C2B8233C20121D50793906C4014453E19A62DA12C76F03667031F2BCB59A074CDD2417BA3789E7AF38AC71335736890DAC04F77E0B10529381E930C8C0031F88838EFA47772A7B2541963B0C7B063472CCDF6228349CB5619C943067AD86019CD964C64767C838407EB32A4ED9C40581B63E0379D00ADB275F6578F065894E8A47796489B994AB9471235455FE1F819F3CC2B378648AC625107805EC8946F1599A8329981A7775523F7C8EF7426D8A31D1D5CC98820186FC7B55076B14D2C7C1533CC3217354BB24661C162AA0895CDC4AAEFA666686A0F12D1791ADB7392B78D31D6BEC44068C4F31CD60A768AC0B056C24864C03387715DC48BC86E1B51A649CE4945708951065F946E17C06F364590E4D16520FA2B47B230F1511FD02AAE79BB8FA72791806B0D3E211DE92455459066B410BFD4D437F0ACBBFB02BFC5E93DC7904B649A6F9A7AB09E2679E13040C8E9754032CC3FEB8C2BDC21D8F7AA56EA31370169EBCACE98D54362EC24B6B6C63732B882984E58839A7F825B17871820EA9DD0DC8C5E7A15403888E80150CF5A12C5E26040708791D2074DF71945D67F221B6D2BBC1B65D37559A7C248516CB4CCC19CC15F93BA6D6085BDD95568CAB1069CF13138B83173EA7C58EBBEA7516C6AE25BF5E07DDF29A0DCD64B455AA6E050C1D5663245318833CB95702BCAB1A11FDA773A73454E1055104F917B75D650DFE1C59E807314A096DE713E35837BA4F2A5F3991F6AC18302647FE01A05C055AC9D19FE27027CAD17633DC0F4693C1F79CF69756E79C9FAE7C954A0CAF2C6B326E9037042553968FF3007CDB135E368ECF440E4187E554AF9D0FF272911CED339AACC8BE341A319F425312EFF5DACB31E6E772EFADDE7250DB9F613C13B454565", + "ek" : "DCC7F9E9254D3811CE1DE92D35BC449878C06B80F252F1A188AD737E9EEBF5A3EEB48098CD9050FD225F85E0A05C47E5FC22D8793E9DA4638FE45142D0FC6AEA210792312DEDA7E09241DE11671C32A443F9EFBF169C7B3556139BB662A80BF0B02E922042F798BF16F6A8EB2B7ADF7A908C4AE8E3B12971585272881A48C05FA3104D500011B7E241169BAE2A7938AA642744F57F35C0035747AD5283AB49AA973C6199C0CB4421ECEEBB173278243056839B43F6A1EA80EC8513EFFA2174C267A8EA637959725D44FDA49E86AEEF67C3B27198078BEB56CD1F408662300AE629D79BD19DA6266CAD2A3253225E7296BC6D8E49EC6FA9230B040F894E37FC219ED9ECB14993ECCD2E559F51087A0079E5346EF23D7586395D151FE11D72D8A6F5BA6CF141F90C1AC264122AB98050519031637B866A01639480CD205C087027AB1C9BCA02D872412518D41C0BAC1FA3DAFE2219B4F8B6CA8E187DF54B2646BB22D4A0581265F370A12CA47E347F3CCF4972C23ECC88A7BADE86196034CB53AEAA49B088E328E897E23353F967DA6EBECB98EED39CBDB2E4C4BD8D7146B1213D08E22F584BEAF845424940B8848C12B31140078DE48799BCD0BE3B37DE8CA577777461EE9A593C28D6A8F5887403C70EF86998C044C4E5F8630EF8E2FFAE1653A63AD27B74931DF933F112DAF192E0478EFF00F5F6D840A90DF27C574F2853589FB499AFDE93F0D36655182B61E35B62B0A36B3541267C2E11C6BBA708B92365F32AEF7FF77C42F3AAC4398CC3C07655A7D7EB6F3A6D7D19B0EA82E81902D3A15299D44B1FDAF13AE10F316B3E07A7D5BBCA4E423D0F7F95EC13A511470C4A90067DEC2682245B38C4F8894262C6B572CD499F2B03E6BCC08AACC88651EBEDD6F820D2223037179326C4C678D42945007250AAEA9378FDC5FDF77F343D23E890FE74CF67EF438AF1CFA9BFD273A0A53402E2FDCFBB0861150226C33EB9A2374DCAAC163A4169F7734B195855FD2FB8B75E04793EAA1116B41E69CA5EC9AA27EDB83D29C0BBD57B4CAFF2B268115F4813C6D2913A5F28AA813A0178D210A6E1367E4148E6D95811C2730FD811A1032D110E69C68D4FE9243759FE4CBE0BC29D6566BC456988C3CAD1E6D61A64DB97F477302AA4C017ACDD12E5DFE951B0AA162ED8986DA4E447E2C2CF9B175D6A8042D37A38FF3F9BA8575E62E899909E7F5FFD36CBA9C89F32F8A4D1945904BE0F120FF803F9A2B2D7C655F1BDF23A6479DD4687A63A6BBD351F47EE0E6019EE4FB3C8652078158286990683BF480CBDA6F0E70F5F0143786C734F07EA9685A276DE861AAC79E924C8AD5619D9E27AB2CB4E50593C2941DB40C4E7AA72972E5E7ADA11AF0D47F99F5E6532900203B841EFA0A6BE71DD6F878A905ACFB8E252F0EE725F1AA99356CCF60B3D6116E71512B107C4EFC5E1BF99BEB8BB65CCDB80C0F8C7EC2DBD5CB986578F5067850315D82709986A1BF3C05A296C2DD56086D34FBC21E8BC687A8D0E935A68C49984391D153056", + "k" : "EDB312341D92D2F17A4A2C590D4CB03AB95435CFED0B0916914B661DA1CFAF67", +}, +{ + "rngSeed" : "F7AE036A0176A9DE9A036A542DD2840033277C44AE936D10B768566216DE9D4395CD42B116873B69D9804BA6CCBC05D5", + "pk" : "60E29047D95726801982A9349AA17EDBE89D04A6CE4CC52B24D989327C855ACBC39E6B9880A0783166AF6D03043BD34EB427B4A8B32676A874B0C18DA60759A5248ED4508ABFD90723CB161E38058D4CC3B162C75261380C119C712639E50494BF195B0E6A9D4B22803278832D52A6CBFB542F451C777396EA0BA5C9D186C0786180A4A032D12BBA793E2E29328C91A40DE06B9B754A189C2A01404F2DC7011B036C969B1455F7A6C05B249E83009B52CA5EC643B92C0E4EC9469E3ABDFC2B8DBF5638450AA498C345F126782A5C29AC7673A8DB84B0F87086DA21728067F3193EED391376317450A3ACC5EA0322B189F56ACCB246BDB6CCAF7252C89BE8BD846AA9D07995BF2C2C5BE82385D77E566C90FD797BD9B2A5DBA704D60341B1530CF3F60F231066A06590F6E3C90F1B6BCF5CB316B482C2817462BA2CD3EA4A5F0744DB5128B6D07851E15266280414B6710FBBB7DA113C8EAA45974C62BDB7B335315E5D093D11E5176F019DDDBA19B379399C7C88A9911E17D16FC5194B2A1998D219C4A5FB5531EA6E6AD37052A57FB5560EA39719C378B69C902ACBD3324F9C29DA73145B409A5F79C8629B4853F65D03ECA0A8718DFB7295AE3483EEE45BDB265638C0511864A0E471A34D839419CCBE42303FD2C51232246E0A6B81D9AB00C50A7FA656893693A8E6E245FA7B119A14336C9A0F57108ECF87A9C249C01D3A214BD42649E092E2C3C8C89A2E4D980B0BBA5340330717A01F5B3ABD426CCF6BFC3E5BF8969AF7278B0C428CC39A36DA6A7C0B8BD666A1D07BCD2845718B755D76FA61D3CA51B3B77486708606975FC377B6EE0596A6F37474B91549F6899A3C4E46A5309F035133AAB371EB5599809BF32034A73C8D4C0240A306176C6B09135719CE9478D3F8136C189B715C6B4CE6612BDC973F40238994B763065D08308597CA22A3F4A43681CB500A680A476E1110005C6C6ACFBC13C91ABF636A7EBA2A1F1280BF41293F3031A8ABF8AF4FAA1D617A380E925861185A2BC37A806CB8BCF92354A26340481AA0E6230758A667020145057F8FC55B49B530AD5BA6F490C9A73B8FBDE960A8D123C648155418B373B1189E10C9F91A4BB15592DA329F61682F70E03143846B09C09DA648454901AB938928280628D4A57A636397E5CA0F57DAB388C65FD6E7BB5A9A0F3F95892973C990F393174BB8AA669BF28322F80A65320BC69B6460BE565265E7B8AF86587AD9B43F1C3E5A582773045BAB8CC6E03329AB1A4E05B33AFCF8009DCC67986831D0A60662B427FF5A7B9991017930524BF678C7D461E1BC95FD441A7693C3B842460EE186B3F973B35BAD2FC258972C2C309490163109CD6C87A81A2D30BAC5C6766E7D151DA391A83A2A5E96904CF9F268706B23E8758F514072B43A6D7891A92E57AD6A9B82246A7F3459CB9CBB5E157A957B27C8192407E9820A906CBCAD6794E16BAE2B0664811400CA22941E576FA6FA1083571BA17884D5073C83B7A7A1CA53A90AC098EB7DD1627C2EC28D61F86FDBA69308E27FA50515CDB19445405A3E6C720651AC5199A1085C8EF1995D8DB0A43ECABB5229353316780F12258867C65BF257AF667DA224C271B02F52B8BCF4805BC2031FD9D999B3C825FFF0F4C8CF37E52C6007BB4A2B63952A0C223185", + "sk" : "218284084CC5E95BB4C8A7648D77BD0FA0B91235AF9D447D8BF062D322BC4CD25EF1532433193509D4839BAA0F4FB63143E64BB1D35408ECCC80DA5CCD6123344182AD9734602221C02B6CEC762EB6416BE03562497768D22146DFD3B04281A0542B4CE1070FEB56A0B21165BA91B3B06A0DCA42B15F556A5A6793DE72C4548969F5F8102B49BB8CB47C8890AFC022BA481837C301A619C69731743B971302957207196A56B1F071CB330A7D26327A55B296C8422B87456024C9363798A5FC94B5E026A4A3BE75765B2827852908303E6AB4764C33569C657C864A39AB991B61A45DE4C3D37811FEA6BCBB6708CB27B83178C03571566D090647330CF9B91FA3D9B49FCB0090B226E38322603249005D3CCB00D0A65843FC3149A407B672B88AA3C6331CCA33CA7A33136BA5BB4520917A9BCB673F22852240B7A577C3A78E2B0C36E32BFFE4CE17EA5DBD016FD00745DDF48775E9274ADBB45CB4946BD05B4EE0A38285CDC8760FDB871F629524D3E89438C5AFA2AC2B5258C3923430CEB99993C9B95FAB5AC7563E6E1068406860AC10BCAEA63C609531BA80A637D395485111DB501F78A98AC1C0241EAB362EF092EC2C4306ECCD5274A729B7909002831CD65FCA5CBDC9440E95EB2B588C1430903078A625C9B67A4C5955C8EA25175BA7244B57290787CCAB76FFB6262679B4B4130426D31D6DC754009573AEE9443C4A9AF619637BE8C52E9486415565A6A3C3DEE9A5C9F31D6EE716E0DB5C219B01287A8A046BB038939BAF2939A2A608674212B5743F6FF99C2A3496CBE21414C646D51399E7048EE398238BEB8F0B33806EE33655573074ABADFDB22DF14952937CACC143C885AA0C7E144E172C1B4690CC6144304475BC02A3CDD84126E3FBBC0D5B6BCC875F89BB4883B7C841D6588A3A5B68A79613D4BB04486A2C10CE76378E07B19824D83BA89A649BB3936E6A060E84B8AF0C91E1E6CF9E3B03C00320ECC5B493C88E93F9419C1AA71F27BA194C3022634AD0441F3F36280F6C2E4CBC68AA05A681AA4F16E978B0582E09FBCAC4B849800616FF820B5764961E299F462A55A3083477FA15827937C7746E01C22CB1A878DBA2AB1D1B5856AAB05F3960E4CBC9754351C691C646A29BDBCBAE01B670A7284C5A608B8609026A28AD2DA69E1D5707770A6C5252917AFA476D68AD7C5CA1E9B839AA887E2BC92520552523FAC50F29559A803CA9DA4FCAA58C1CE05E1D987B05D71CCD4A0EB184A9486819A745010CA92937A16C177C97743CB7FE680617279A0BF40F23A5456AE0346F38A5B346358CF76CF2549528815A272008D748A7A5FB3B9454CFEF492B52D350B5710A3F5595E1D6473D2134070733BCE526128579D7A80EAD61611912644EC5171BA940398301FFB282A0150ACF047C25892333514CE4595089C0702D7300A76470FF191B8B8634E56C7CB720AD8429ADDA29294E1A1A92E06BE1E4C4B2A37AF7A36515D58873972C1B40336132C0D29C0088989BB4C29BA0CBA4B878C8C096C6FCC868EFCA2D03540F9317ADB81B808AA3BD1A118D0AD70ABA98792B830C7379012DF373820C7E70A7805D357733D543EB657334096FD616C6D1097AB106CCAA3B1460E29047D95726801982A9349AA17EDBE89D04A6CE4CC52B24D989327C855ACBC39E6B9880A0783166AF6D03043BD34EB427B4A8B32676A874B0C18DA60759A5248ED4508ABFD90723CB161E38058D4CC3B162C75261380C119C712639E50494BF195B0E6A9D4B22803278832D52A6CBFB542F451C777396EA0BA5C9D186C0786180A4A032D12BBA793E2E29328C91A40DE06B9B754A189C2A01404F2DC7011B036C969B1455F7A6C05B249E83009B52CA5EC643B92C0E4EC9469E3ABDFC2B8DBF5638450AA498C345F126782A5C29AC7673A8DB84B0F87086DA21728067F3193EED391376317450A3ACC5EA0322B189F56ACCB246BDB6CCAF7252C89BE8BD846AA9D07995BF2C2C5BE82385D77E566C90FD797BD9B2A5DBA704D60341B1530CF3F60F231066A06590F6E3C90F1B6BCF5CB316B482C2817462BA2CD3EA4A5F0744DB5128B6D07851E15266280414B6710FBBB7DA113C8EAA45974C62BDB7B335315E5D093D11E5176F019DDDBA19B379399C7C88A9911E17D16FC5194B2A1998D219C4A5FB5531EA6E6AD37052A57FB5560EA39719C378B69C902ACBD3324F9C29DA73145B409A5F79C8629B4853F65D03ECA0A8718DFB7295AE3483EEE45BDB265638C0511864A0E471A34D839419CCBE42303FD2C51232246E0A6B81D9AB00C50A7FA656893693A8E6E245FA7B119A14336C9A0F57108ECF87A9C249C01D3A214BD42649E092E2C3C8C89A2E4D980B0BBA5340330717A01F5B3ABD426CCF6BFC3E5BF8969AF7278B0C428CC39A36DA6A7C0B8BD666A1D07BCD2845718B755D76FA61D3CA51B3B77486708606975FC377B6EE0596A6F37474B91549F6899A3C4E46A5309F035133AAB371EB5599809BF32034A73C8D4C0240A306176C6B09135719CE9478D3F8136C189B715C6B4CE6612BDC973F40238994B763065D08308597CA22A3F4A43681CB500A680A476E1110005C6C6ACFBC13C91ABF636A7EBA2A1F1280BF41293F3031A8ABF8AF4FAA1D617A380E925861185A2BC37A806CB8BCF92354A26340481AA0E6230758A667020145057F8FC55B49B530AD5BA6F490C9A73B8FBDE960A8D123C648155418B373B1189E10C9F91A4BB15592DA329F61682F70E03143846B09C09DA648454901AB938928280628D4A57A636397E5CA0F57DAB388C65FD6E7BB5A9A0F3F95892973C990F393174BB8AA669BF28322F80A65320BC69B6460BE565265E7B8AF86587AD9B43F1C3E5A582773045BAB8CC6E03329AB1A4E05B33AFCF8009DCC67986831D0A60662B427FF5A7B9991017930524BF678C7D461E1BC95FD441A7693C3B842460EE186B3F973B35BAD2FC258972C2C309490163109CD6C87A81A2D30BAC5C6766E7D151DA391A83A2A5E96904CF9F268706B23E8758F514072B43A6D7891A92E57AD6A9B82246A7F3459CB9CBB5E157A957B27C8192407E9820A906CBCAD6794E16BAE2B0664811400CA22941E576FA6FA1083571BA17884D5073C83B7A7A1CA53A90AC098EB7DD1627C2EC28D61F86FDBA69308E27FA50515CDB19445405A3E6C720651AC5199A1085C8EF1995D8DB0A43ECABB5229353316780F12258867C65BF257AF667DA224C271B02F52B8BCF4805BC2031FD9D999B3C825FFF0F4C8CF37E52C6007BB4A2B63952A0C223185806AEA6700E293F433A97E4B2C8485E6B4AC19AD493C4C16A10A2A884D58F5EE2779ABA933159A5AA043E2FBE31B14D2E56F93E83763E19787607196101D3F26", + "ek" : "C4E8F8DDAC9B74A7800293F05ED5395D0EDE351201F1B8DD207722D42D41A595C8845D2F6F7CFB9A06368366F68C7DB5354A09CCCA35D0A3403570452EB66FAC2B4C6D0335FF3271F3B3946D49A5C16FD6F0E0512EF9884201E8456B0BE22D24BE11E02AD81E7480B8BA79A1C083DD6E67B3B6BF94645767035961F00C1245EA021DF8CE1B4D630EE66B08B85CBA137D58AB2F9BCB0D1F9D026023642CCDA658762CD22135B5782E24EDEA149F4B2E311762774F5F195B2A236596547C1C4BB0F79B196464DE6074D11BD23E44271B1F913A169A2A624B2F8CAD3C515628E52409DB2A134DAA96CACBBB9F10E4709911177C03987C99C8D1B3CCE1FEC962CF9194A1C0F387A384F55867ECA9FB0865F53F0E9CA2649C34A2AFF6A03399438D9D3F4899A10A85268C539E93741CFCD30D35F9EEE2455A8CB1CA3AE9FA73BC5871D3B66FA6DC6AA7B290FCD3B641AED63FCF5A623140FA00ED2510EBFF86FEFEA04FE2D0B64FE98FFA5D86B4F90A17AC491AAF66076D053B81DFB712FD0BFFB5C2015F8D4EFBAC08A6A92BAD03F2114F8C98309A17AB235B8ED07D949837A740BBC88F5C88B6A88936301C780FE2BF0BF40A1E0127AC1C97346C1AB21D7C4DCCAFA14C00ADE830E15F7006C0F90A668A77AD26A1CB0E75FA61D99EA719EB6E7202AC51742A60F440D617127587A0CC5D71DEBC4E2523DDCB5B84D0E77FFBBA5920C91968769898963220BD2AFC8BEDC388644B0148FED22ABCD8FF358DE2A41E48A7197E1ECAE22F3086AA9094E34D3490ED6B9E185A24D549F5991DE3668C770324E100003031F7951E9A599A32C621EB6628D0E51C1724B09DF56841063678AA11C1FCFD84B54B2AFB294F6A2FB9D49724D6B015C15ED636655AAFFD5CCF56D506CB3A2022CB2DECEADF594C1E30D0B9912B819F261E1E5F2CCBE4FD72D35D7DA6CA55A2CA740CB64124ED02591CF4BC7EC4DD982E2998947A6E3E5F62E3846C794D95BDF6CBCD9DE4A841B27F523D1E23EFBB3AA5AE1FA23F53CC864D3E3C43BDDE18F3E26A56820885602BAA70BE96D0F498AD5ADD003BDB506E7F39CE1EBE2A0714E0AD0B015F7B1A9F5C46520E5644172788EA99B818C65D0DEF06A2B32BA32573EC0F4EB0938250F6A90413D12081F8E7913F502DCAD792801911C29AC578D26BBF0507151BBC1A55E9E660737F6FF13939412062536CF343F622428E638546BE9B8DD1B2AADE422DEAAF9814429909A3029D1D4B84455652D32B61266D0EA750597FFAC452CFA87A179E5809041E22C2456920C5F74477F61B7CF3FBAF79613444DBFCE5FB73BC0CF7734C887AA6D8094508E012C2779922C92582F0C50ABF560D5067FF472804DE3E1B6C73C809516355CD731D164AD25F1D50C1EF60FE140A0F9C3BCBDDAD0BD54676FB61345819AC74262C88FF6617C791BF9547BD8CD352CE835FE138AA348D97B6D0D44F6BAC01DB82FF04249719098AEC5A211DA7B1859BB7B523A7E4C3731AFCDEF8C5DDC1BD4A67D9A9C52C6FDCB1F37464CE", + "k" : "1F33DA6314A9270CC6289AFFE54EF97CDED193A0F140519C0C3C4C7F6B4DF4B8", +}, +{ + "rngSeed" : "D995D38F934B6E1A7CA77C9522E3D037676CC939B0C8BD4B84394B3DC91A791F09D2D97199258C9943DA955E7F7B26FC", + "pk" : "7EAC95CB2439A4D5171062A42523CC5EC7CAA414654394003942AEEB720D4320C10D609DE9C397D0790C585398FE0C42374AC2D220BDC6F507FE62CC592BCAB77BB0A5F4CE73A380BA3640B4E491343AB7A33310E7F04C130A70F75B75E6ACA5306837E9AC03C84B01C3FA4F5032069F492CFEAC1585054A9FC4271DA3636639AEF3A065F2857A32D590E416866E71AB92D2AC27CCA217756B528776A6319014867816D00837E476AFC08D5DA82293D37042709567052370B553CC925043957EAA3C34D2810A28163E9F4807B492301A4AAA232B1834DB5932D20D8866A37FA312CA9CB129116634E95D551764487C384CF00B35682927808A28660D92E51610C68EDC994C76A95549C79C162487D445293F0758A43B525B04477C2C50A47A963531B727964828C5B567FB538432C92A8C5A0BE6136B9B05C2E68353D5787A0A455DBA373CE60F40C4B48BE8723FF760ECE23D135887BE491157B6B4DC8591B5046735C5588CB405057B96DE0097F158C67223C5A854BE20238126F1203DC59BA6D5BEE4D7AA52F1A92441CB23340820D9AFE134097BC8512BBA1D2097201D6B7952641369649EECB884A4C35848314D2618C283BA9B343922B7CC18BEA9CD1A4A3597C146D433692D15C55172847B9CBDDA7A049EE455E5E43F6B18A80E60CA48822B1061835431644EE1B307D581ADD3B21DF3367350BDE75B1366505B0C88302EB1C6B164290E29204FB005F81567571552A6E22638A0018BDC94E768A9ECC7CC20E50EBC8BC9774C7CAEA9A1FBE1CC6C925F3FE70FE2F523FA9017B714B7BA820968B3898C1410B7E46FC54226C2C15056EA0EE2C071635B70FEA288B88C9CB43A1FAAD97671E763D04B173426224CF217B2937246CA012EDC14C529A2E2D47BF3B15B96804590E5241254A3B1E6A29378522CA0B2598491509127869A1A73DC2F334386C3BC7542F5BAB81C89E938071892709F3744ED560C77D43D6DDC2537C544A4F64B19D55917165001BB74D93A1437835442C83B989BBC22CA67E6F96FD44787B8865F759419A409B78F209DC87A89E3EC883441C3EA39627C2524C4F88625594C2B0B5798386866A2C9D45C2D50D438D61C571564040893BA00A7752EB28FBF6B737088103C2A0FDFC87D99B978D2521949683B7DCC98B644504C297905D2417649C0A60AB70B5C674783739FAC213F1AC5C5D69F7FE32C5995073E846D12DA57CF17A73FB70FE8E7013D681DFB393A4B40922A654473C40B50249362E4AECD22515F256250365660177BF345A2CBD0884933B45D7AC67EF3871969BCF94570ADC7BBC2CC948F82B7731A8BF0F980A3C373D30A4E85E1482686AE98501810C28108670078830254B7CCFCA27BB0C57C56490E1A5B593816923D722D7C433534980293A1CE65219E0245A2FA049D9FB10FB54917AD82019A51212F0086AFA520F34799A0361A083211A415A42B36237D40A5138C5ECFD7C70F5B084A05156DF817071B709E745EB3E0252BE9B1D89247B6917C72BB9E3EE78DCFB819EF5308F2AA4375578C72D02C348B16FDE51F80602D0FE50DA8BB5BE6598FDA0BB8BB1987DE7BC575832BAF123948215B833821AFB7087A65014511A50E800CF6714AB446E189261A2A3DBAC768C1E9E232985C430516BD8E18C79AEF56CDB5", + "sk" : "8D3542BFA71C67EB9C7A824D7179882305AD248622B6DABEBF2C435436BB86777A43380BFE26126B1089399CC3816A435621643D354D7B4989646381B6393851822276641698A597CB173F0888A3DB31529A41492A5201608A30CEA5114FF52686E874A676C8C9A6A5B8429451C294842904F5D4327F6A3BC30B7EBF35BE21ACA79126B8C3827F7DBA4474E308FD9B2F4A80982D93B4C6BCB05956B5295A59A6703E8B6C4E254606FCB353CE2C2649AB07F8E8275B8536E204847F774E5B7A94DAFB15A2C5571D107EE771941BEC00519C1B2EE464B12B0CB4C002320C0997E5C516F402960B33363C57851A72989A5570420DA7DC1D5EA5C885796BB43A9030F105E58546510129C4506B89A62F03337890D89A40EA2AD1E62BA420A321180108A8A1ABAA124C5613C4CB680ED621149315C734209530185EA709D6538EBD8C2ECCC6C58A1755DF1090881B1CA516155B3458800735F98282B1B1AF72697C6DE29BE547CDE7F64CA29B6070CAB2F9246E068C99777987C86885EF65340E868196B040007784464CB9B7F30A8410B1BF363436E657B1BC2C62D5C14A8AC3D6B636F7714B641560A0E88EB5982F36C3CE94C14A7FB979BA5110A633A2B70517C0EB0E79512844B50ED0C1B41E68BC3F1224C4CB03CDA780A5105E2CE01A4921193DD86AB7F41997F893A5947464E32B2092C48FDB1D84C71A74F087E25596CB21056349B15FC73B838BC679F49AB5041FA9D53049070DE760B5F574B2D9AB48D5328CB799AE5EFA0C17855AD57001F2CAB922C4788FA6BE39B1B9656A11BE63C57CBCA770E5217F54B5D61990C3409D0E1306667B228A27425605B9B5802B6B795FF5A5A423138C098B4758553C14CA7A198C9960E806B2A51EE39A0FC9C7136A876187963B02E6C6E4365A33EB1DD938AD6D2510F3C873ECA835C9176B4FF5921EF52DD1F671A85368CA35B878347E42B3A3E42B731FD4051F37AD84F5A1B16C72512AA959E8B0C7107A5454AB96B585099B1DB79745311A80CEB070C69B1FEC37598FB63F32AC282611A5C37337A0C44C960C35800018E2E1C040978260B50CB51217A22104634118D4287E88045229998A7CEAC32F532C48358ED48929D7133D67BA96087586BBB37107F5423DC56F84D390FF281FFB8344139CAAFBCB140D065912678F8EE44CC3C78C681CBE530637DE1CAB0D0112DC023163031F7CD70B4D7AC2BD43678989412B0804ADD344F6541E007A46FBD79DBFD4156892A2D18A05C34C028F46ADE763103A079D03A3945EA614D8CCC84FFABCFD300ACF38C319B32D92BB18A3870219307C0394546DE89E738A9F7D88C767825823B2BC0C368990681D183A1D3078B3BD43CF2F47727FA8BC6A4607928090F57C74539AC06413567C4C968C9CA8C5DA0632799526B3B9DF7C6271AA4906371B46C0B134A7C1D5709D8548485BB2103EAA27BD515D409CC07DB2530A569C1D617A218AA215B7A2BFB0999E791F35D07D1B5B12CFE53DEE8A8EDC91725B138B1FC7001955991DD32BB9196CF41ACFDC773899AA1ECAB0854203B421406EEB85820E2116AA746466C49837A69D8E18AF5D82C3A0FA0777F9800A187F327CA08E0C1E29E13DFD0AB97EAC95CB2439A4D5171062A42523CC5EC7CAA414654394003942AEEB720D4320C10D609DE9C397D0790C585398FE0C42374AC2D220BDC6F507FE62CC592BCAB77BB0A5F4CE73A380BA3640B4E491343AB7A33310E7F04C130A70F75B75E6ACA5306837E9AC03C84B01C3FA4F5032069F492CFEAC1585054A9FC4271DA3636639AEF3A065F2857A32D590E416866E71AB92D2AC27CCA217756B528776A6319014867816D00837E476AFC08D5DA82293D37042709567052370B553CC925043957EAA3C34D2810A28163E9F4807B492301A4AAA232B1834DB5932D20D8866A37FA312CA9CB129116634E95D551764487C384CF00B35682927808A28660D92E51610C68EDC994C76A95549C79C162487D445293F0758A43B525B04477C2C50A47A963531B727964828C5B567FB538432C92A8C5A0BE6136B9B05C2E68353D5787A0A455DBA373CE60F40C4B48BE8723FF760ECE23D135887BE491157B6B4DC8591B5046735C5588CB405057B96DE0097F158C67223C5A854BE20238126F1203DC59BA6D5BEE4D7AA52F1A92441CB23340820D9AFE134097BC8512BBA1D2097201D6B7952641369649EECB884A4C35848314D2618C283BA9B343922B7CC18BEA9CD1A4A3597C146D433692D15C55172847B9CBDDA7A049EE455E5E43F6B18A80E60CA48822B1061835431644EE1B307D581ADD3B21DF3367350BDE75B1366505B0C88302EB1C6B164290E29204FB005F81567571552A6E22638A0018BDC94E768A9ECC7CC20E50EBC8BC9774C7CAEA9A1FBE1CC6C925F3FE70FE2F523FA9017B714B7BA820968B3898C1410B7E46FC54226C2C15056EA0EE2C071635B70FEA288B88C9CB43A1FAAD97671E763D04B173426224CF217B2937246CA012EDC14C529A2E2D47BF3B15B96804590E5241254A3B1E6A29378522CA0B2598491509127869A1A73DC2F334386C3BC7542F5BAB81C89E938071892709F3744ED560C77D43D6DDC2537C544A4F64B19D55917165001BB74D93A1437835442C83B989BBC22CA67E6F96FD44787B8865F759419A409B78F209DC87A89E3EC883441C3EA39627C2524C4F88625594C2B0B5798386866A2C9D45C2D50D438D61C571564040893BA00A7752EB28FBF6B737088103C2A0FDFC87D99B978D2521949683B7DCC98B644504C297905D2417649C0A60AB70B5C674783739FAC213F1AC5C5D69F7FE32C5995073E846D12DA57CF17A73FB70FE8E7013D681DFB393A4B40922A654473C40B50249362E4AECD22515F256250365660177BF345A2CBD0884933B45D7AC67EF3871969BCF94570ADC7BBC2CC948F82B7731A8BF0F980A3C373D30A4E85E1482686AE98501810C28108670078830254B7CCFCA27BB0C57C56490E1A5B593816923D722D7C433534980293A1CE65219E0245A2FA049D9FB10FB54917AD82019A51212F0086AFA520F34799A0361A083211A415A42B36237D40A5138C5ECFD7C70F5B084A05156DF817071B709E745EB3E0252BE9B1D89247B6917C72BB9E3EE78DCFB819EF5308F2AA4375578C72D02C348B16FDE51F80602D0FE50DA8BB5BE6598FDA0BB8BB1987DE7BC575832BAF123948215B833821AFB7087A65014511A50E800CF6714AB446E189261A2A3DBAC768C1E9E232985C430516BD8E18C79AEF56CDB533DF23B37987C6B557E4C0F8FA9E466312F19E7E90CD0A67ABE6A145CBCA9D4492CEDEF206325F68EBC282123EB0AB02874F8A3C6665B78346775351AD99CC3D", + "ek" : "E1E238F829D1836C5322197FF717BE0E2703E6EDE95A678B5620073DABC5020C099634A94ED54FB201F1AE81D96EA4BB4AF5EE9AFFB784E98872CF819A3059499DA0F3FE0DBB3E94C7B66936A223EE621820DE600FF8BC32EC3D4B3DCADB3812EE668629EC11FC4D5D0581C6C2D97D9CF4FED706ED50BEFF21523BAD737CE6BC6E024C6AAE4405CB08263F83A70029784285B79F0A970E3A11EABF0E2EC2714F8D384308EE09E3C404A790CF1A021FE28BDCC367BBCA3E21F361FD38A5388C7BECDDE981673F9606DDA8EB1EAC0E6D1127D0FEE465A292A3845DE9B2C1F8C0DD657223CE4540D411FC167DA99442FF77CC913E7786030D4DF888C004717CEF6D4008D53E05DD204121B38F3F3AF7D121B7E354C40D5D7FF3167961E6A5FA120C98605C42203596B7793017E4930918809EDC73EECCA48532BE2CCC8C8AB3B4B8BAAB563EF2024AC7324EE1A86B91331646228704DCBA63FA642A947669D222179578429A7ACF1D2F5379E578937526B58EF25821F0F487EE070D5F6B8B9E4AD89AA07A6CDB9881809979811405794A72637AD678493F31A882625D79D3F0EEF197B7EB7E0F30E2B2566E60D91FB68C08F4C17AC10B8E3397E75305838A8286E112A4F2AC74080E836CF1F629D6E41A38C659BCE2B02DC3A0DBAC774FB076F0C44CAECA05151740DE4F04F501D3958019B9F144EFB0BD8C7AAF867A71534B782EE415F4A954ADEA7827139C5A561A5A1AEFBD5F8BF6BF194DEFB16D25A737F43B629BE1D87CFBF4650B0575E73E7D270F2E682F43B067778F49C65D285E8946AA3398DE36A1A0899CDB3520D9AD5C8C5BCC29BBF3DE2C7BD756E41176A68589135C7994031943CD0CBEA2BCE5029CCC67EA0A4CEC4A2A92C982DFDD67E828CC6B220358D56DADF6B96B13F01F6F8CA955C53ED97E0061895EF07017C262922A1B1D4D7204F72286C86DDF2127732487028E9FB2664F53C08CE10E55E4370FE84CB19C818A6A5D435C667E991EC2F20A269CCCD667DF64FEEE489FF37646C2F07C591B6B23DAD5CA358479BDE0410CC93727680B07F002D95A98992204DC922D87364F125950A3E043A5206CBB2227AA0E0BBC1056056A1CD710391502E2F6FBAF6341E40736D78036F4C8E097A25E0FEE6C1678C7157EE7542FB69327C8F958BFB351D8CC7208147CFECF3529410EEE04F628D8998114858221FBC3E5D4E8AEE09E797AF4D311B2DE4732E90129F4337EDE7C93D41D325CB52143D67A78B03C33998258B7593AF81D57E9B3B737C325BD62FBAC2D0AEA896505A0B9E856B95A263DDBF5F80C8751AEDF2865FC44C1B1762C183A788BA9B10D875DA9F530DAB936CB86049A6ED192F2E0F08A59D3560BEFA15002083415D79E46933A6EBAF9795F3D66A9137FFD5DC2AFE0205B28BE7478517C747CF517A41C299CEB19968E3BE73E897A5876633E012E4C3B85C0BD1849148BD7BD671D2CD57E719F0DE4C06340728CF7FCF5C6F3F2F31B0FBE88E70A695669A6C39BEBC5EFB1AC79B688B01BEB", + "k" : "1734967134CFF92ECDC751DD7BBA5EB1D06064DBEAF0B4E50FA0FB7EC671BBE0", +}, +{ + "rngSeed" : "5929F02A271725CB40200DE32D9D03D8BEA53B53AC83186C42C7F565CCB1CA508305D470850CF86E9B2C61A5B8CA1C93", + "pk" : "616571FEF73BF834C480630B9532B244D09C8F936E951961BCE56157F237B0919097222DF3BC6E61F47D846479A1A5BCEFDA59CDD8B067D19DB6D9586FAB2FDA9B550C5170C2772AD5A4AF4A67A19D215E45575E83A8BA5F099E4358A9E493677CE177F36A0F594912B6B850D3F719C155C01B68BF1DC89CCFACCCFC6CC38A34CE5B4C48D2E17DD2946F493A357B1105265153C04A98992C949ED774588925C697284BC537B4D795DE0463335AACBF80B10CD0A03A88256C220C3D0074FFC6C8C913C919AA19F25206A1CB7D40A50C6F55960A2298881A71A1DBC92A69371DC9A95D45A7BD6547BE9414F4C31EBFD3553B89CFD9AC05727B06BBAB300ECAB599DA76A62B97541CB3474B7390CC49942678ADD66D265772F55515E0623192668FE4C5273E3176BCDC52FCEB081DCAA4ED699DEDC59B01A29363070567772DADDBCF8605BDD1268882A355CA4163ECE88637E932C56C43405AC3844949C819646E394DBDAA475E62AC0463B8CE257520B3B4E141057449621B449C09C5B72D10464E59BDF2702A7F4BA1C1C6301BF51EC41BCBDDDC4A069ABE46D37C09050B28B073F2216A06D501BC38640600185227A63D224589A43391097226D67240619E2804589F4917DB7391A4FAB6778C91EF30AA41655E3E433854A52C9CE8130B802E82204BBE894517F1BBB4458616B0C309020ECFCC17F6B69CD0BC688963AF0FEC8F567A86CEABC9A0383681D3729A612987862E2972B6393C2C93A32861073AC3EB1CC636A52DCC23E6EA0AF7D3AF49F81858743962978245DB5A70C34E90C64560B87EF29B5B568A716904C8326481DB98C81CCA47CEC76E32003B36B26AECE764C5551AC07C4BBCE094B6772B2FAA27B518CA5B96094D178F68A7409992BA7FB776117C66E97CB0BE6854908AA8203AA916D26F3118842689A5347BA29D337599799691729B812961720CB80FF993D8A124E2027EFFA1BAAD40A17B564B0412681A6005888C0E27992FAAA370EA3954775949A553B75AA35D5956373DA54DA7EB51C7E68C05777760C6B9B0A78FF2F34312876F2DB27898D3AA4A187110402537F2AAC7373751954F3BBC5445DA3907429FBC817FB0A732BF4077D4630C93A4BF6785274019C5DE6C3D8A66441620491A8537FFA1A50F0BAAC622CC765052AE0049EABB20D05B987B303D17714C4E79814DC5CC9593BAB612359D0C7A3BC9614D0C8EB4E0A7C740520E077E2215BBBCB693A92C0293CA28B4D0CE316B5E14E165FE4745F9665C36A651A6A8AC11A162B4A111E40851EC2B29DBA05590140D28AA945B42310659111A4033F972BC0163BC26A5872957C6977BBF8D727D65A8C806B4699050C994BB85651A40C6D590C337C680306FC231B7487305C4155654471C3003B93C206CDA82C19F7B047E12B5CB94490F4BC850C4668B366BCB23BFF1A744DD3362E94CBBC658178A012D9B784D12E965F4592067B636ED3CA3BDD89C0B30C8BF798F2282C49ED3835B70AB1EBC761B880E0779B5AA34ACAEA40C83EB0BABD6CA11398759415252064C4E70B62D4CC813D346CA789EB86B5D3606BC3239758A62B5F76A709B602AD6987228433A01A8AEFFCC22D0D315D59B15E8ACA53B02FD160C62DB910FDDAAABBC4C2DF1256095317CDFF9F1E7EBCC48F8382101", + "sk" : "A89CAC07514FD7EA49DE1C8A4AAA75CCF901439529EE48160B4ACB10885320B568B9377B475B180CEC4C3EA2A1F6584DF841B54BC8147EC79457896E24B3592A4864DEFC44F4E811CAC6ADEC8C91C46BBE80D0CCD9F08E4FDB6FE1509E4932CFAE8BBD3D299A389402C0E16E9F44BBB34729EC9AB7E56906491A538681607EA7AF800ABC2040B2411596C1E9669B2C57FED92D1DE814B0351F7C99BA49613E8B8C5348D49142141FD104A6C43C66906C389903B91FCCB4E3A4245049C134291B67D0C596894CACC026CAF067014415D1335829795443C4924E38308DA8B229C129C0BA43B98BCAD09A20FE4143607C5117FCC1BB89BEC1A32C1882B6C733AB4292158B71A76305856BEC631532BF830309D7833E09095E008473AC0928DB8202BC971821125FF288054348608978417314CA916A3F2596253CCA6018C990C3C54C858C33438B28723889CDFA2A5EFB9C20B11ED6228560F897C5B5ADB6A3A505E4C7138C68CF550D3CF9C21EE12D83F9BAA9778707075CE5CA7E319172A0A926E96B421D0C1A3ABC2029A3ADC2ABB5163A51F07924EA727D979996FE4949FB7892A74C1649DA7A382426CCAA0D825766ABF51D8390BDF6116D107510A1529AF44B37D6561FEABB8B0704BE246632F58A7968DB7D3835BAD6C49B29429B9A443571A1C2B1B1C8BDDB690B387F5F9798ECBC84D0567D53676E93C38A38B63EA8620702C13BE48AB37E02C303B2250C45BAAD168CBAB8B87E7CB9F9E55073DC0D375A88CA92C0370B161BB35F4D4A74D6F1A4402BC32A0B50D8AB576834C15305A7EC70525D5B42FAB77286DCCDE4D6CB79AA7C46F425209064622A86EE94A6F5F3A6F23536B63C9AB5F8BBCD148A30D46FEF07C4605B2B81B75D46332B340B6719A735078C3508925F5FD4C1107C69A560CCE9F74041FB521FA61A552A756BF638C88A61F103BA9ADC02787A398BC35ABE3993553AC0118124EC4C67A706C3FC60796CA531EE28AD89172ED5CA12BBC84CFEEB35885ABDFB5061D6F774C17C1D5755C437CB7827D8107CA8B420D07331D762E73622BD22B4373CCF918C0B08A954D6CA33A1020127346B981CB750842B9EDCAC1CB9A6D482CD00A80136575017DAC0B0345819A3A099D859C2DA56A45523D3E776FECA225E5A464300648845BEC13B332F3BC78A497A41DB4F8E88CD18694887A3BABB3A97838519D3C0375E95CDEC5596E0486C4A354085201E0CA9C6FBD1754CDAA05A9B204F602793AAAE97D240AD11AB2C54CD0EB897F76CBD851038B09AB1442B081E6122E5B495570A7BF8363D3AE1C793A9206785B59204B1E7A46974F2CDAF9AB6D830457788921E72862A499F1EA938D08481EA103B9D6B0294BC0C5F90B6B0566FFA897592BBBC3738A0E69CC5E5A127C1622E6F245FA4607E49064AED22C7D082C62994B419807EC9D8B0C7CC3C993C3F1E2538BA21C21DC885FDC8BEAC5963CE9732C34A0C34637BB368A87BF2452463CD5E66275E94650D7766845BAE2D79BB30336ADAB7AABE52774E5198AF3C9EF532CC5C27780849B1CC8427EB1B451591AABC5CC5A7461A578A36AC371C66841C0FF05A90E41E79ACB69C31459BC30DFF0AA24452709407AF616571FEF73BF834C480630B9532B244D09C8F936E951961BCE56157F237B0919097222DF3BC6E61F47D846479A1A5BCEFDA59CDD8B067D19DB6D9586FAB2FDA9B550C5170C2772AD5A4AF4A67A19D215E45575E83A8BA5F099E4358A9E493677CE177F36A0F594912B6B850D3F719C155C01B68BF1DC89CCFACCCFC6CC38A34CE5B4C48D2E17DD2946F493A357B1105265153C04A98992C949ED774588925C697284BC537B4D795DE0463335AACBF80B10CD0A03A88256C220C3D0074FFC6C8C913C919AA19F25206A1CB7D40A50C6F55960A2298881A71A1DBC92A69371DC9A95D45A7BD6547BE9414F4C31EBFD3553B89CFD9AC05727B06BBAB300ECAB599DA76A62B97541CB3474B7390CC49942678ADD66D265772F55515E0623192668FE4C5273E3176BCDC52FCEB081DCAA4ED699DEDC59B01A29363070567772DADDBCF8605BDD1268882A355CA4163ECE88637E932C56C43405AC3844949C819646E394DBDAA475E62AC0463B8CE257520B3B4E141057449621B449C09C5B72D10464E59BDF2702A7F4BA1C1C6301BF51EC41BCBDDDC4A069ABE46D37C09050B28B073F2216A06D501BC38640600185227A63D224589A43391097226D67240619E2804589F4917DB7391A4FAB6778C91EF30AA41655E3E433854A52C9CE8130B802E82204BBE894517F1BBB4458616B0C309020ECFCC17F6B69CD0BC688963AF0FEC8F567A86CEABC9A0383681D3729A612987862E2972B6393C2C93A32861073AC3EB1CC636A52DCC23E6EA0AF7D3AF49F81858743962978245DB5A70C34E90C64560B87EF29B5B568A716904C8326481DB98C81CCA47CEC76E32003B36B26AECE764C5551AC07C4BBCE094B6772B2FAA27B518CA5B96094D178F68A7409992BA7FB776117C66E97CB0BE6854908AA8203AA916D26F3118842689A5347BA29D337599799691729B812961720CB80FF993D8A124E2027EFFA1BAAD40A17B564B0412681A6005888C0E27992FAAA370EA3954775949A553B75AA35D5956373DA54DA7EB51C7E68C05777760C6B9B0A78FF2F34312876F2DB27898D3AA4A187110402537F2AAC7373751954F3BBC5445DA3907429FBC817FB0A732BF4077D4630C93A4BF6785274019C5DE6C3D8A66441620491A8537FFA1A50F0BAAC622CC765052AE0049EABB20D05B987B303D17714C4E79814DC5CC9593BAB612359D0C7A3BC9614D0C8EB4E0A7C740520E077E2215BBBCB693A92C0293CA28B4D0CE316B5E14E165FE4745F9665C36A651A6A8AC11A162B4A111E40851EC2B29DBA05590140D28AA945B42310659111A4033F972BC0163BC26A5872957C6977BBF8D727D65A8C806B4699050C994BB85651A40C6D590C337C680306FC231B7487305C4155654471C3003B93C206CDA82C19F7B047E12B5CB94490F4BC850C4668B366BCB23BFF1A744DD3362E94CBBC658178A012D9B784D12E965F4592067B636ED3CA3BDD89C0B30C8BF798F2282C49ED3835B70AB1EBC761B880E0779B5AA34ACAEA40C83EB0BABD6CA11398759415252064C4E70B62D4CC813D346CA789EB86B5D3606BC3239758A62B5F76A709B602AD6987228433A01A8AEFFCC22D0D315D59B15E8ACA53B02FD160C62DB910FDDAAABBC4C2DF1256095317CDFF9F1E7EBCC48F838210130A5771B76066FEB7F606A82CCE122964DA1BE0B6872EE319832214EC677738C7373D22CACE9F3A09FCC5E85067EE05C0E537AA0738F79101236B4E7D28F2889", + "ek" : "8FDCDFCCB204DF5C4579EDA2F64AD99ECF0A1FA15D3C411F5D642E6B2B6EBCB9FA34F652685C742496873DB0BCCC98805B1B5C3C3011ADCF965680FE6C37BDE11CA49ED096F4AF3FDEF2F1F3BE094E3C9BBB5AA8AF8FBC4CA5E145EC525E254B3604F2E8E77BC182D8D6175C8D088A9358149F785CFC2709FACCCE04DEFF990FDB3F9A03A13D535E5A68B7ABCEA08F8323AE2860E9E2B2C7B8C00CCB0A6DFD743A4F8FA0514CED5DF5EEE6DD837A3E5602E9F1B1366CEA6A3C7D9F822DF192D0BFE807E0DEFBD8C168DE5C29BAAB9952459BA2E4DE92E6227CBD58C3A2BF574C68DBC9965EA0BDF634B0DA34C802986132CA78964B4B67123B841DBA50599436A4272C30F50CC51B00A2E7015BDFC4FAB6A3FDAA64C3E7F00D1A5D4A6C118347BF11FAF975ACB2BB41F60EE7461C56E25F2A58FA443BA006D7277DCCEE1F9D170D841BAA876C92A49CFF0E61157ED3E86C099D1B6D6B7F9D0E3721469AF3FA1BADF2AA0DA7E64EE6E99EAF262E4C1399800A1D0AC3191E1DC514C9F51E3C51DBC314166CF86B83DF5AE45E19DA1AE9BBFA93BC45D79EF43BEF0F67D05031A0D1BA5D58E9994BC6E695FCF4552F33E207D68EB788FA0651A124A67D456A08344120FF991E6D00493D7CE4C1CB4CC374AAF6188E29DE0BB5DF2B8E60E806881FA8F73E3B6875615CE97200AC86C2E8389A4B290B694D3140F26FFE12362A7D117B58154F398D2078AEA9516505586FFFFC0E9F450DBB59A3B73CB7C012121CDA903953ACBA2A0BCB0FA0ABE0AFC9BC32F3E24663DADDAF9E0DA5C8590E99515AEE70FB7E91D697F9380237D7DC77A56949729D7201B4E9A5F497FF11F009C4ADFF7EC2D8AE1C3E3D610EEDC53D61691407EC92BE05136C1B8D733605C70F3C69D8DB177A6C3F5B2B4F83B5064DCEF6C9DECB051F46F796191815B1C7BBB1E7473C7098C29A59A5407DB24D956C541BF60499F2B271E105172EC0ED456C6FF6B7622C11D2478D232DEE1F3E416EB2C23EC1F891CC4E9606F3920DE879D9FA6D9A8E53D34576084148AF4FD21731F692FDC299407432662160290A12C23F25BE402121E483569F5E3171B0F577B923A8BDF556333576A4244539656E7220DD5772018D416AE4E2FB495CE2702155F28BD2AB50A1918B62139346B8E0B1D8E0DEF3A014F83C05EBB85BBD2511ED97ACF752A49D1E626501E5027807FE763EC8ECB7F27EE23B4109FBB224134979D2E9131022EA9B37ED68C8060E874F846627EA57F3C5A9097F50AE4969C6AC1E15AC2AC01F58BA53C157B5B5FCFDA3F6C1F794093F4B3E5BDCAB1C6FE98D9713C38D797EFCC912B6E51D2EB12DFD75F3160870582D299DB69E9387D4E14779AF6E35BB66DC18C79870E556DAF7AB751850CAB942A8255BC32C5DC1D80EF05866A099798E248A362DC7284036170AABA8AEA9C2D2DFF1DA01615117B5E8ABE02D07D6F7331350E44FD73C489083C36C4046F4571B56F43E6CFA2DCF816B8178ABCD0AF628C0603FAD35B06B092E0BB469008958D7BA", + "k" : "06F1986E60D3B7D0A9ADE67141A521DB6B1C4B6858CDF748C5BCCC4AC1FBAAD2", +}, +{ + "rngSeed" : "905074033D7B75DEB2D06A2F29144EB377B452534C5710632989F02D45312D156557E96D4486020826DB200153BC4A8B", + "pk" : "36509AA06326FF5CC174F51D963CB5E5B1290EAAB649C91D1A03B9CB45400087248EE90F5B9509B9D44F27E814B55B5D7FD341BB663523CCCCA02C277F1A12F2E054008405DD7B8FB5B78F200266D62B00DB2665A728B9231B99D957904D4278C9B99933972006C0AFB2D46AB58810BD59492891A77F96B7E9D06EEAC63CD9E3A2039A1F30AB0EB4E6A7DBE875253174F2519092761E9684C00726B8548AAF2AB3BF79C8255EC6C1591234672ACAD20C0BEC4A5FF7B4AB4442C2982799D0203F1DDB53A260B95B51980025140556582A0C5DD9D20BFE542F79A743D45095B25C9565C1BFD1D82E5DBABBF37B934BD43A9AF92AE5BAC65570CD0586621708A30D8371DDE11ABDB8079616896533B90611A58843CA38F6105164B1DE4B227B0C4B14749F5833C5F76CB5AEC703B2ECA6FA40C7BD224059A4938BF125653901D5D80CB4FA7213E9136D7C0A4F2059865911F68C19EFF169AF063E76887F192359E5E60516A92FB1842AF25599AAF530B08A171D35BE896590EF3A9B7878B4A3764A3BC2A800613EF1C2A31FEC6FF7A8C8C4E0158202C4FFD35C1A45738D1CA197F23B8858A31DC60770E38796DA35136500EC868E209217B9A10C7AE465848C82E815490DA5BECB32A55973AADC18AFB2172C0D086DE7E21D309226FD549219C0AAE0C672BBE832C515811584AE3E4A59BA98A80E2A0386A187036961B4F6ABEB6A84AE8B55B4E95CC9E812BE00BA0925CE00EC3390E7936B52482B420B9D051F91A117122A0778C2434CB661AD59050342C63CE986E1B590D2B0B81FF4C3A1BB5A9AB4CEBFA96C9F072DDF8332F5A3AD0A156FB5B6B35E38A595F30F2156815656CC487313C75952DCC12ADB5B0528CA68BD53BCB1F750D5F24D15D54E83B165440528D83057FA12A983AAAD4048C53C62C4A789B82728A94CAAA50F7A7DF6FC7D07C76727882FB8AAB09811A611C5188DABC366494263CB8EAFB78EB40A7F33763EA9B51318F0AC1A7A34BE71AAF436AE4248346A7A25E2DCBAAB226111D96D5D9165B946AE29283118BC34A46409F2EB37C469A36311CAA843C112EA83C0364EC2B8B6E9EC68CB8485BFD87FF560912FF21C43D59A1476952E82A2D3F3A00CFB7C49A61E9216B728FCC30861A23E171C2C7954FD85528D911682066DB1A062B50A5A11CC385DB16D4F4B81785C9B8368575409738683847CD46F9389128414082C5515B5B3310658C54BE69A6C3B02B5E0A1B6627E0512999862ACC0B34340172A9A0B144627CAC4D36FE8D71272E6AC69AC94D1F8C250515580B85D8AB300BB29B43B02195EA7C966947BFF9CC323D017B48BB4F6A88B0201956E095B8092B250B53DD9F58CA90B28EAB574034372D9F8305B39668BC90E2B6BB77257252B0BC36EE68AD25A7C883691A494C5626B5BD870C45A06CED4F39FC7E21958811A7B7CC93410B2FD8245B45B7462F72033D86EF2FB9B173397BBCCBACAAA7177760202A8748B440F82D49218331C3760918C640DC58073883B5721548ED6E529D7F95E02A65CD7BBC3383317FBB166BF751F47FCC216513742596C2E9BB75EE80D2DC16D036B1D45102BC2275AA09B8800213F67DBA3987A2F5EFA1AE2C7868CE276C5110F462E65B39B2F4F753B3A3D41EEB50F7AA17723BB620B800AA3DBDAB7FC", + "sk" : "8A4487C253844156A9EB333C710C70398293058632014350817B2D98D68B4E0C536EE79FEBE01F3F423836E34436600866CA139193376DB576F3920D47181EB7B2264CFA494DDB768BB10DDC002D55D25724D20F9D125CF6718466D7840941CD4783BBFFE342F4A584CAB59E0322CA151BCAA29BC76DFC0AFC525E0791B3F9E6279D56CFC4775D84054B51E604D5EBC1A8922D783C840A9B00CDC58DA2EC4A5FC1BDA820622E5C10051C3C041571685697BD49CEECFA455E11AF28E8A8F9C0B6C74314D2DCB8B571C5D78A7CA354567338344A305338897241D3991F3B4BF448479BB36F9FD3183C703F57F5903918BB71FCC701F586EA719E2E8183CE605575819514F4C59B72AA76BC6C0BFCB7FD19C51EF3612D45A9ECB396CF5B13C96A0BD7D3CD70A84A2ED11E66FA39C5967D080B8F7106BF00A81D208C66FA31C94E548E50849C992608DB9C0AC1816ADE777D36A04E6989AE0D5C1A703541F2F2CCD4570E9657CDB17202880C0C5AC3AB15B13552F91632255B02EB9DB48973A3990495900ACFD3B3301B38BFC4374758B0D6956241600033B55F30DA2F8D1A046C27C80A403B935905F455943B0459A9A5046BC9CF54B82E175A34E628BF529A225EE25B07D73BCC4A80FD4580DD0AB679185718E5C196E25F4BC89C206409A5BB0D1C233837776832338A1D1B907E493C6240B0C6524A9E542B91F48080011B3AC1AC062BB528399B04C3BCF114A0F46424CEF1C1BBB675B1999C8DDB883E7B40A1BA5CA13875BB022D8C088C810601AB2C4844AA916EC2348AF4C28B552C08E970E535CB674B388BCA5D3566A6EDF10D10856B2EEB796BD8CB8B503F2BCC7CBECC528ED121BDE4782F717E5F63658CB7251694BF0A4C2EA4D98ABC70A4D87994A3317A206C34AE972A54E74D235418A5790CADC9333F2C9C349744BCEB28D5BC7AE1521AB708CCA937A9E10072F412A26037312145500EEA42D04A549EDBA62185A93C1CADFBC4721FE827DB83C4FCCA759D575EFF93848BAA22D23B5A659CC5C3C3608684229BD736DC6452690C742A59B9C9E9ADF6AA0FAE27664A28C1490BCDF1865802A9BA2A6B49951B3753C12F3ED57FC88BAE34D21BEFB269AA3663793B56FE162A2A47643FFAB946F94CD012479F5BCD1A6A6B8019BCC4D38E180BB993D319F43AC809CC2BB8A63C9D2854AB569DA8F7C0B1B24088056D799B49D6CC12BCD15AD75C5DADE497AD0B312B9739214098BCF2CF90604A72013C3B52994A691105C4060657493947BE3B0A6CFA91B83580457DA7A6411A984CC661F0B7C59A012C5FA895096A354EEA5ABF893E2EB7389D0A649481421B13201AE66E3B3B4FBE6818D0F47EF7477F14E792B35AB3FB2737F9EA1C75A3001445920C2B1C65C38EA42A02D017C93924C4B3E7492574C368401276643549F5AFB69177A4D807937102686958A1D564A8184624FC47E713B7D9728AE6CBCFF5C52BA4966429B9C0DC659081156BC7C398D9A9BD4807907B307B1501A8BB518268897DC8610B649494AAB4743E5AC392568B771433808476E6B32DDA6940865C3E43077E0D9BBCEE84CFCB523895B36C5596880F036648F37D483138BDF24C40D182CEBA0DD3E26236509AA06326FF5CC174F51D963CB5E5B1290EAAB649C91D1A03B9CB45400087248EE90F5B9509B9D44F27E814B55B5D7FD341BB663523CCCCA02C277F1A12F2E054008405DD7B8FB5B78F200266D62B00DB2665A728B9231B99D957904D4278C9B99933972006C0AFB2D46AB58810BD59492891A77F96B7E9D06EEAC63CD9E3A2039A1F30AB0EB4E6A7DBE875253174F2519092761E9684C00726B8548AAF2AB3BF79C8255EC6C1591234672ACAD20C0BEC4A5FF7B4AB4442C2982799D0203F1DDB53A260B95B51980025140556582A0C5DD9D20BFE542F79A743D45095B25C9565C1BFD1D82E5DBABBF37B934BD43A9AF92AE5BAC65570CD0586621708A30D8371DDE11ABDB8079616896533B90611A58843CA38F6105164B1DE4B227B0C4B14749F5833C5F76CB5AEC703B2ECA6FA40C7BD224059A4938BF125653901D5D80CB4FA7213E9136D7C0A4F2059865911F68C19EFF169AF063E76887F192359E5E60516A92FB1842AF25599AAF530B08A171D35BE896590EF3A9B7878B4A3764A3BC2A800613EF1C2A31FEC6FF7A8C8C4E0158202C4FFD35C1A45738D1CA197F23B8858A31DC60770E38796DA35136500EC868E209217B9A10C7AE465848C82E815490DA5BECB32A55973AADC18AFB2172C0D086DE7E21D309226FD549219C0AAE0C672BBE832C515811584AE3E4A59BA98A80E2A0386A187036961B4F6ABEB6A84AE8B55B4E95CC9E812BE00BA0925CE00EC3390E7936B52482B420B9D051F91A117122A0778C2434CB661AD59050342C63CE986E1B590D2B0B81FF4C3A1BB5A9AB4CEBFA96C9F072DDF8332F5A3AD0A156FB5B6B35E38A595F30F2156815656CC487313C75952DCC12ADB5B0528CA68BD53BCB1F750D5F24D15D54E83B165440528D83057FA12A983AAAD4048C53C62C4A789B82728A94CAAA50F7A7DF6FC7D07C76727882FB8AAB09811A611C5188DABC366494263CB8EAFB78EB40A7F33763EA9B51318F0AC1A7A34BE71AAF436AE4248346A7A25E2DCBAAB226111D96D5D9165B946AE29283118BC34A46409F2EB37C469A36311CAA843C112EA83C0364EC2B8B6E9EC68CB8485BFD87FF560912FF21C43D59A1476952E82A2D3F3A00CFB7C49A61E9216B728FCC30861A23E171C2C7954FD85528D911682066DB1A062B50A5A11CC385DB16D4F4B81785C9B8368575409738683847CD46F9389128414082C5515B5B3310658C54BE69A6C3B02B5E0A1B6627E0512999862ACC0B34340172A9A0B144627CAC4D36FE8D71272E6AC69AC94D1F8C250515580B85D8AB300BB29B43B02195EA7C966947BFF9CC323D017B48BB4F6A88B0201956E095B8092B250B53DD9F58CA90B28EAB574034372D9F8305B39668BC90E2B6BB77257252B0BC36EE68AD25A7C883691A494C5626B5BD870C45A06CED4F39FC7E21958811A7B7CC93410B2FD8245B45B7462F72033D86EF2FB9B173397BBCCBACAAA7177760202A8748B440F82D49218331C3760918C640DC58073883B5721548ED6E529D7F95E02A65CD7BBC3383317FBB166BF751F47FCC216513742596C2E9BB75EE80D2DC16D036B1D45102BC2275AA09B8800213F67DBA3987A2F5EFA1AE2C7868CE276C5110F462E65B39B2F4F753B3A3D41EEB50F7AA17723BB620B800AA3DBDAB7FC31FCD120F19FE976236711E58B4AD172D25CE01EB88BC9D6D051C56564A0DB11C1B070E4E519D727F677E011716436BEE9DD0188FE38C00D0FF425AD794C07D1", + "ek" : "6D8ED73A73EA4B23563F5DE828A1376122A0888F92848C868437FC74A8DE5816742ABF5787929C2253870FB38885EE4F286A03C7691DEFD803EE41928DE3A64FB039FF490C23DAF3863DAF8BFD89D52B523346C0919FDCC4544C94464EF898462306AE6EB7CAEA1AAF804C37727BE637CF777E6A381823EDE66DE68ED2438C54BA7F379B75C7586334DFEBE3647BA9FE76215DB511F4F55CC1D978B6A7449AEC496E9FA55B927692A2075645E6199059E8A2CEA227D7475FBA3E308620B421EF4F26DA0FD0B35626AC6593C4D2BCC35806BB569529020607B19717FE41DFFB4EF2BEF7F5ED5592C6C290508E9F4BEE2A2ECAEFE52DB959690A2FE32E8CC611DE62D623015D4A3E6FB36EEAE7B48B884229469833AD347BA28E7E61EB045A9E6A572C8BB97884C28C75C5D8F3615CF66B2CF556D2FF941DA6D65D56BB25481E105ED42A23E159970AABEBD7724A3083D7F3628E7ECF18D0C72BA1DE124895D37252349496321F7BD1EFE4D6A60A0B74BA72D31D51462F3CD6A545428029E963FB9AA7D62A93C9B88ECA5D2C889DDF6426E79F9D712E3965A37CC6517C0C60443331B30AE8FE8252C8DD086A52A17E0BD300FDE93BC76DC32775E17A2076FE574EAC9AD452BC6D957D015299DA4255BEC6A636A0EE57B86FC395339BC58DEB1BD32FC25C35A94315F7FA3527DE2587BBA6816A360941FC996E4D7205F2375231D6291D88D126FF2E8DEE6AF50DB48E753E1B47CE59ED4320D61AC1CAB373360A87B35A4BC77AF415CE4B0F8235FCDB0E11524479ACC69B2E2353E948991324F3681867D2C4D82ED8E0D03AD87F72F5AB5D266F29840B9C66116C5B1955FD0B6F877CFA2DADD3CB2B3BF76B8FE4F028E3BC0FEAA4EB960C404197A21D4A983E765B650114795E8C643A009015B82FE3CC176F3C570993853845B85B7F9B11F405FFCA733EABF3178D8D78B71B868F8D5EB81171084112A87534AEB3BB950ED6481BB67C57850860E7C72E03C724CB2346F7E86CDBA1E2414C0D32E510D0D20941FB02471E2EBDA600E11B723A6F94B179797848A4CA2845487C7917C46E86AA0ED25A068D2573F2C958ED87CCB9558FDA0392AD430AC182CBAB4E9DCA45102FDB094DD3354CC7346764A219371A1B56017E450BF83ADCF96EF237B9C78D0EB35AFB25A30AFCD4C69E89C29811CFC00B0C98554415F6041B47923404EE97838816C42CF34A3C70D38164D0C1A5C097EC0B2C54C62B148A10BC543DB7E53B2008899DF8EA354E7B5EEFF2EEC343B68DEEC82B96B9F18C3BCE10F826730E5C70240EF1AC7C16495D0FAE4259DBBB88453D73A94F66A38CF8B7CC56C386C5666945840F258B1E3897A9FAF74D7EC149657665FF516F6BD1F392186A849255BF20EF5B563761C1F896AAC82BA7FCB47B90A106A0DAEE5B097B8DC5E895AE645B7918319DA2AD1C389AA96580C9AAEE069FB1AD6720DFF1EC7B9654D6AF92E8C2E590F00051E12E373E8617F2449A0F5AD6BA60317320B0093F2FE0AD51215B1E296B5B64", + "k" : "60244727BE353AE27661185D2AB70EE104921E240F3540F19626D8004E47FF76", +}, +{ + "rngSeed" : "A3E2E511AFA7BB560446BDADF67D2EE2E16FFC7BAEAE7EFB8C5455068BBD4E91BF9BE9D98B280072FABA7712C75B26D4", + "pk" : "C5E450AB970D5CC6678DB12AE81962959A3D68D8A4FAE40ED343CBD2E84322E2342CBA7756328FB5C80A3FE07295DB0E136621F8ACB8EED4685CF21BB28A7FD34A9C6AF4A8D1FBC8DB21AC4D334AFE1B71B87CC1DDBA5501D38DD7E74C6C502BA04B8D1039322734418DC438FCA99D0BF44F700CA473D07C0AD5094181BAD2E90910C08478920461C750AAEA6658112933753153AA9BDF090EF91A3F08E7C07278369DF0BEA9220B7D4C6B6F6A7135A5084AA54DDD270E9D41128D1944D8E7C3E1AC11A4089FE4541324DB369445B5AFECC41406B277E8BB93F310DE57B55DEABD8D2CCD2E9A417ED916EBBA260E0BAF95EBC0FBFC0A1B63B6F5342B3ED7C1FF4135F0A26C3DAA7E2D60BBAB8051123628ABBB3CF9FC6369A46D4DEB7EC0032847D7474356AEC9A417CAE8B62C9C7BF3B077EAF52C622B6A2BFA6AC49A9CEBACCE996A29F89ACF9349363606A86A6696481233C73B273E847798B530B8662194896E22EBBD8F3640864791964069684338F453710D841AA83A2997316FC3BA06E7D6A3855CADA69C35CC801CB49928EC66A56CB8A28DEB2329D75C6545251EBB8526903A13F5174119B9C2037B06C165D2012723BC817297C42465CD77044436337591F239153629C3140B0CA85783D2460B207268F013988176F4C22D8EF5C096C93A52706931B4399A1849488665026A615E5955D972429EB32213CA16B587B0F7366192366F523732FB1127731CB06BC39F15F35B1283654BF361F403BE5A9AB154F786080CB8EC42C8EC356847839DE84A23C6E4321136477C12B20CA5642EFC84C658323F90C2509B62DF865E54072AAC311A6D3B4EB9073B17F2291001A37E6BA438918A42663BB4D15896239F9F2B2D17A5C93C024AC595806620A8891B89F7297901A9B63E7C799CAC22A515BFB3CA9A4772A5BC9A11154011E4DC0D758868A9F646D5390C631381E8566FD5603902C11686CCA1F876322CD7793C338876D82008EB30F32128511A872DB5CC0AC689C75266D5A9BDCD889F73DC92F1DC5076F373BE64308012553D3109C7B5B2A819AFDB93BB3447C878901813849C5FCCA97B116CA1C2115961AC4B8C926303BD7F502EB299421CC9CB82F556327584118C6930E03F4368AB915C3DF0A46B08518CDD280E17F86824958F0CA8079E857D8BA9A522A49C3F539C845968FAF37E4BEB443B577646967F4F824C2A706B3A7B74866AA4BFB83DD8E4356DFB1D9F4678A0A120CD2569101B034E36BF24A58C690B69EA27CA88DB6645682C13B57D9A397B83772C5357082DBB6981674A772B6A94D0210B14A7703202CFF38419297EDF92A305A59BC51A022919B1B61BC853ABCA39721B83A794F1C27D17DA71A205571573CE31EA27F81B744371274D6A8138B69EF967ADCC75730A652F134B0F198B86A2A670A96C58D45295433851F61850D7B318245849A140A407A60080ABBAB77ABF58D8C46F2580716A0BFF0481B1973C804A406DD2BD08370CCABBC9FC7557B26534CDA249BA1B3AFAF2956F10B0B6AC0A7EF02252F5869A972142E06B86B64684B34B2592BC91B7C5B24C14D232B81880B3844409C6038E06023321DCA0F2271144373FBFD47884F3AC96E4BEE4DBFEA5EEDF79FB157B32E2818048BCD9B8E9BB89118362E59C75B4917014C2", + "sk" : "5A837A98D1B7D23C06AC804F9008924221681A5B35141311B383A995A75DCAC87BAF79B484EAC622A6A594CB1DDF122030096548285BF7DA99F27A8033F1AD1E442E3452913092A0F666CE6A910968E00B1785658C576FAC3A68AC13ABDB91255F6B5104D26750894E02A9610A632B558B4739858F72B9CED305CBF9C6929A7664EC49B6F6D18F728664953B77427180E6B2895BA6A56B391CB1263C5154061E1A4C4DA221418B363F09C669C6918E911E793B92249885299923783CCEE355330118199DEB5A4C6890C5E61E45A2C89B3A74657686A9B1987834B309E074133A34A4A11AE92A9BB6A4AF14C15B2705252FB69CDD159F5084159681183FD01287555A3AD3314871483C8040CC20894D4A5AA239CCA6C733FE17220E55394C2A2063D30497716255BBABDEF6C71A925A24F201B096A39AB3CAA54438222B23F6C16F07910BB04A04AA1C8299053855F4A8CC852DF639CE559ABDB7E1A5EC9861491269BB829226BC1E99F392C1C6364D64886AEA98F0E25C1F27862FA64AEB017B73F30AAF8CCCF543C6E054B23B33BF926125CB263F844C70832AA6F9D66141903AAC5B7EE78734949196C54A558210C91EF006E266ACF833C77FD97F75B8800178B6E2B89A81764F9E851189E2AB41DACD5EC31604396D5811641FF21A40F9C45BC947AED2C629B457684252CB713DE7D25955A66DD6E801BFF34028101A21D10C3A6624C234B0640B4C26140E345B778A04929A596176D922DCF737F5198F677467F2990DDD5194FBB5BBA6AC7A8F2C90801131BD1C9FC50CCE2C802AD8DA968FB71ACD79CA2ABB87991B90E2A76E5D547D96C4A300C32C0DA3C29BB40D611B7923C4B6796B8DABE5A277EC1B444050F0B17221744E38582F95FACA6807B566948203F00A0B4A8A77F724C067C5C464CB59B8547ED3B2851B9F8EDA807317B5147533AB879A26B982187366BFC50266435DC2A96E8B104694F63C355435D6030AAB601755B30B38E3434352660CE98E89528E9C54245846C58E914363D61D33D825B1C8C6AE439E6959743F3B6F2B762916F65F6E765044B4A3A6244C37B1B0A671779A840CDC5A7DB3703A670C4F5E9C65C9BC814356B4AED09F60162ECD143F86E3B81071C917124615821E4C5BC98B312D2FF525D178A61EFA0D465565E5700DE4069D3C7864FD15AA9BD4C49242B0CFF231AED9A270E41AA5C29E74787524A6085A129795AB5C9049C985304478578A907903AEA16934F73DCDD17ED1FAB3C629605BD1AEF9D16B674A6411123A0ECBC718927B18642ACEF5A055D47AF694C34B300AB6296DC2884984441EAFC861FFD7767F306B7CC72F3580AD5214AA130A7E89C634C6B1923415C75DD0A256461EE6F94271027779D0B79C8B943CA32C2F62832A04CFC79786EB017F561C0C5EAA60BB44800E2CCCCBD64755C8B6008BC89C52827E737DBB37ABABE87980407C503CC5972A34C76913F37085C699B4A95BA473E21C14080D26315DB9F17969F6B629B48DE94309140104F7DBB4511A8977266101C26F5B1C78E3896E051202EBF9A5621797C775B1A2B3B7F3A53CFB9C90A545473000569214C151088A082A237A8AABABA3B69BD3CD415CC1F9AC91C5E450AB970D5CC6678DB12AE81962959A3D68D8A4FAE40ED343CBD2E84322E2342CBA7756328FB5C80A3FE07295DB0E136621F8ACB8EED4685CF21BB28A7FD34A9C6AF4A8D1FBC8DB21AC4D334AFE1B71B87CC1DDBA5501D38DD7E74C6C502BA04B8D1039322734418DC438FCA99D0BF44F700CA473D07C0AD5094181BAD2E90910C08478920461C750AAEA6658112933753153AA9BDF090EF91A3F08E7C07278369DF0BEA9220B7D4C6B6F6A7135A5084AA54DDD270E9D41128D1944D8E7C3E1AC11A4089FE4541324DB369445B5AFECC41406B277E8BB93F310DE57B55DEABD8D2CCD2E9A417ED916EBBA260E0BAF95EBC0FBFC0A1B63B6F5342B3ED7C1FF4135F0A26C3DAA7E2D60BBAB8051123628ABBB3CF9FC6369A46D4DEB7EC0032847D7474356AEC9A417CAE8B62C9C7BF3B077EAF52C622B6A2BFA6AC49A9CEBACCE996A29F89ACF9349363606A86A6696481233C73B273E847798B530B8662194896E22EBBD8F3640864791964069684338F453710D841AA83A2997316FC3BA06E7D6A3855CADA69C35CC801CB49928EC66A56CB8A28DEB2329D75C6545251EBB8526903A13F5174119B9C2037B06C165D2012723BC817297C42465CD77044436337591F239153629C3140B0CA85783D2460B207268F013988176F4C22D8EF5C096C93A52706931B4399A1849488665026A615E5955D972429EB32213CA16B587B0F7366192366F523732FB1127731CB06BC39F15F35B1283654BF361F403BE5A9AB154F786080CB8EC42C8EC356847839DE84A23C6E4321136477C12B20CA5642EFC84C658323F90C2509B62DF865E54072AAC311A6D3B4EB9073B17F2291001A37E6BA438918A42663BB4D15896239F9F2B2D17A5C93C024AC595806620A8891B89F7297901A9B63E7C799CAC22A515BFB3CA9A4772A5BC9A11154011E4DC0D758868A9F646D5390C631381E8566FD5603902C11686CCA1F876322CD7793C338876D82008EB30F32128511A872DB5CC0AC689C75266D5A9BDCD889F73DC92F1DC5076F373BE64308012553D3109C7B5B2A819AFDB93BB3447C878901813849C5FCCA97B116CA1C2115961AC4B8C926303BD7F502EB299421CC9CB82F556327584118C6930E03F4368AB915C3DF0A46B08518CDD280E17F86824958F0CA8079E857D8BA9A522A49C3F539C845968FAF37E4BEB443B577646967F4F824C2A706B3A7B74866AA4BFB83DD8E4356DFB1D9F4678A0A120CD2569101B034E36BF24A58C690B69EA27CA88DB6645682C13B57D9A397B83772C5357082DBB6981674A772B6A94D0210B14A7703202CFF38419297EDF92A305A59BC51A022919B1B61BC853ABCA39721B83A794F1C27D17DA71A205571573CE31EA27F81B744371274D6A8138B69EF967ADCC75730A652F134B0F198B86A2A670A96C58D45295433851F61850D7B318245849A140A407A60080ABBAB77ABF58D8C46F2580716A0BFF0481B1973C804A406DD2BD08370CCABBC9FC7557B26534CDA249BA1B3AFAF2956F10B0B6AC0A7EF02252F5869A972142E06B86B64684B34B2592BC91B7C5B24C14D232B81880B3844409C6038E06023321DCA0F2271144373FBFD47884F3AC96E4BEE4DBFEA5EEDF79FB157B32E2818048BCD9B8E9BB89118362E59C75B4917014C242F75D6E3755C28F3081ECC9DB44F6CC7CEC9891756D74093716697781FC8CB5D89CDCF4B8ECE9F441926532427F01E9DD71B86EA949A59B14189AAA249AAF77", + "ek" : "B17FB2907EC5AB46276F5BD99DCA664B8FFAC58476E3BA72F1C0AD427B568F1A0A1B90EDEFB24CE79447788D081ED6F2701AF9B6EDD228983D26E35D5B1DB62294BDF22A4D7B439C8D455230007DE43EFC99C9DB479ABC54DEA518070B62C4520E4518F6C27705AC4BD9479D91F78A8A79F6BF678F9F2387D90659EBC166DD663FA29673F99A0C81985D3EA4B60997BA196A627F5BA5A08E54462CE7B6C3E3CFC8DBD2D9D3BCEC2407C39C99BE1E071830321FD0B49E56DAC175C21414EDEAFC03583815723E83D2BC10F3712B118AB85FDA4C60ACA29FD53107D45E911D85EF5751DEFBEC457CE408B2E0FB3446A8888C64B0F37339456102A44B47E3D687965823C06C9F0010E67111D26BA8650C1F1D209D6F65BF776E4E8E4C46385765608E35451BA15322ED5C397746A91050168B60A40D8B3367FB460D48BFC130BF7FFCA1C0C3658500FA76D601CF95D71F4EA3841D13DB72B436E8D9A7080B72E9BA3BB488A2793AC9355E20BA7674D007907E1465DC0A9BEDBE26C4FE77D35C8ED09441AC301C327B0B5973E86F4448FD0411A166AE1B039DCE584B64A5B9D74D81021607F47E1349ED2435D6A26A1B26F9D4EC63091F835BB2B1FEED1E6220FF9648A139CCDADBD2ACC8EAD42AB23019623793CEB81100D9278EEAC88FBF1989CB962554B0A503E49E75D671972CEB5C5B73D1B71F56704BACF5C84E951DBCE87D636AF0EC3F72B8FD5BAE552C091043804388C625039EA5D03DE1C5DB068527FD8A534ED642C597EDE1F2EC1EC9B47CE441E73D2387041A5E9EF7D78B0BBA2C600B8649F1C6B46D5A111E8DE10A7B5E64E740956F516AE7A80B5AD7FF63C69943E33BD53403680EA95838D844EF7FA605C85C3AF7447ED22AB79A465C7E4FF04AC0A260AFEAD921A66144F85974FF791BABC61838B86C19544473CAA16795C6AD8F6F739DC9A183A1F4935769E70293CF3E1EBB1A994805150C7FAD096BC628DBCDBC3B8B9A782FF4B56F392B64D5CB4BD1B0303E51EC3ADA31CEDE4E5D706291C9778AEB59FDA6DC88EA48403BAF7B9A395372BCE10B5EA4448D87ED52A2545DFEC7C66249277F29FCFDEE6AB448A018EC4CEFAB112F84886F77D4260768B9439E322F1248F5D32BCD4C128F45614F654B13900E717DBB2A8413F648E29722E3F2B2FEC6A75001257B500960CC666981506210F237E28D124824583988A9E56C423B3FEC7E3D057EAB9353BFD2C096C539C31940AA2F38040AD46AB9B97147310C0A9AE1EE110B3A7BD23DEA8418D19134126F5704AFB10FD0A03A62584F1DF2ECDA1E1238ABA40C315ADFB041EF9885089B355ACB9F449DA0019A3E809337EA61BCE4503BA6E136F1FDF444E18D8FB0134CA818095744C94C75AF1259FB603EA6E8FA1697E4FD9298AF42462709FD32C085B36A0841C7A5D9E3F20A66E153F3D6DB7BCE31465E6EB5D95C866C13F44C912B934C285AD7EC829BC107B88AFB0818A1E32824F37B757C4623828789315028E29639F7BA359B913F58DB081A5236", + "k" : "AD00A42478EE0C7DD283DF6D1B02820FB18656F36F026E273745D10A0D323FF8", +}, +{ + "rngSeed" : "074AB1A37BA5A0403D8F68D26FB787BC2C90F5EF88F2A6D286C3E6B168ABD85D393D8225618608B8EEB301D26AF53BC0", + "pk" : "08F7945E6597C9872B0CB4B1401288D7915BE8E3715A8391A486047C15B4AB758C8D9B47541C3411417A439BB2144049744460810C01B778879425077E91AE06C1BB831C75E9D1552264A6543266E769B898B66644CA93F9DA7735135D743C62A3876C0C891AB71C73C9B88B5CC14DE0238C82103FA8F634902A01CE5B15E7823A36AACF6A05639A812221085B38B2AB933A12552C268CCCA3CC07CB4E1CA03CDC02B1A5A8231A386456B26878B673644BC3C1613090454B582D5845268F381EB0E70128C1B06F356A9DA736222400ACEA7C58216040A1AFFC5771081743B5F0721EF2B601A651D8A2658EB9C5AD8599C2F040F791AB5D93C6067BA30014AF51766A41C70BE6542B7224767301885A030A8D68A795E9924ED844CBA1B696B18C5A64ABC7AB83A163CAE74CA186C01CAFB53C05FA535D43786679A429677CD3F672B7C9CDF9224030B32C3A147EE0B2A8E50A0905A778AD9269BF04C2A801A1D986B15CDA0EC2F51DEEC2005D450BC070C5E9E2A9646C3A6029BEB907B632F17163B260FA5B75944B00D776862C3C362D06B7852ACE9F93AFBE9A4D77C548D04C68206277F569875FA677921C671FA887B98866E8C25815FC09D194ADCDD34430E2C3725178F6C509FB359E5C3959D72B37A52C303490AE22138DC495BB2BF0C4FEFCCC89EB6B70764CF64CB2B02699E84A562F076DC4221153D8BC1DC0A29387A15DA95EEDC808C666B3CAF04882188B5509106BA5BA1869463834B48DD9A2D7D6B46DE1B83834B7DB556A0B624869641A7B77C1F15291696798FD0CC1D01C417062AB36548F4F7B842E99A85A502D2ED70BB82037FCC6237F058D88AB2DED194BC6F65C723656474830581BB92F196E9FAC65FBFB0E662C34CD1739ECC28ACE01291F24701EC6A836A11F54D44FB50A9150D9401DD96C39B1B02EC73B86827FA1CC39D3EC5D5FCC4523A948A30BB1DA4B3588F029C11234B9B571EC3593E82A0CFD428EA68B727622464FCC35E3DBA3BF911CDB717AD690147AB70DEF66A2A66052A3844B7F6866C1B4BC80C106D3155D4BCB8C13239FC96241CB1B092696A50502A887547638499216FB31379A45BF7B43F92175FE282D98D7A4AD22844661256B711228A31FD2B01FA8F72DD357C455768A77CCA28E6984913C352726176E2192DE562781DCCFDA024FB4315EB5B14B9430BF0E783AD77A763B631F6C03C4B45ABA24A88E85B70FC3B1C3049447E688C3F2145072460B838546572A42F4659A71A95392255765426451F137E8B4CA64B5C24E5CC74A816A988447CE07886CDC59EADCACF5CC5B17B4B0D058C0B3B610DF489066E402ED63A5D155161BAC9F2E82BD0E18CF46476935FBCC0DAA0CCBFC72CAE9B217D3ADCB3BA7E0B759AAB167EBF40F6CF92EDDC17EC44508D051A6302372FAA22A993386201827BDF3A1E932C093BA2CD1BB347096B53919218F321BD761ABDC6CA5086C51B0C471A6C2781D1CCF20BB567CE472FC663AB10B75BDC6642832ACAB5C5D4DB37A46572645A166EDF46AC243805AC78E5C483E25624DAB2AA705B9B3F6D01BEE692351FB4301C562E30A513F6C73D55C0BDCF439F3F62F33E42F7F876F5314CDEDFB4526A075924C59DC03D5F604585571F7E69C7C8F254BCC5AF0CED187401EFACEF8D61E38", + "sk" : "DBB0BEC6FA248682BF1EB3B226D9BB45A19BEEC69998797FE4D9275F1A6BA518AB41E117059338F8052945A36277678F84F761FCEA21B49B9E2C85BDD2C78DF17A04F121C423BA89CF15C90BF34ED5E341156206C2ABB93B8924D6FBB1182BA029178BE8B5B38ED868C86C54AE69B491F2450B96205484B7070AABFCE83A6F0A024DBB837CF26FFD613D106C6FC6FC81F23B838782B72F7873C9F6735E71BA2D2C7F80C29EFA2AAB162767B414B71B1BBC5258AA61A984B2202E06286D8AE9CD14D2BD7B229E039613EB081BBEDBA792297CD6672241ABBF5643703B098FCAC273236687CD8AB0E4D21FE2E15D786C37A09741BC493BBC908F20EB7599E6A5A102030EAB2AD69266AD30696EB1072793B6AA613734554F681678FB8068AAB0C903580F6329BAEA7155C1BB09E846AB15427E0A092C3213AD42E3C1CBCB48CBCA59ABA88B9F60BABD8087B461A2745C2973C04A8D11CBCA9B3A74F7415D975004DB90C4B985D990AC3E01BD72A446F2E13545052A99371E459C589CE203012182A2746D74E5B914B872678C999523B6C5EC790F986CA98C448117BC397643C339432AB2B058E340E098ACE6C6A1B0E1472E8BA11CD898107AB9454A08B965329CE8758C199F10FA5C914CC236706E0A35CB5F2C4BC749B38E2184486A88BE97127EC036FA78A5780B3F0515B391EA6598D1B998141D3461C141B54ED1770EA2938066D40DC3256BC6DA09184B7957070391A1CC8629181954669DA8C33C94511020750387417F87080907BC8E48332D293CBCFA6409E814B79154B135C5A721B447D45ED274731A30215F92004E30AB64FC87B061C8940AC9153957A21AA54CA9BE2AC1ACBD46283CA83219200788EB152273C61B860AAC104F66E8043E7727216141097878D66A30EEEC7820F6C1F140989649C2F2354B81597B298826225332AAF6CE5B6CA31FF986A665067272C6A190A454BC3654699DAD2C3660E371571C8CD0B9B1E0EC5AD43106758C3B2ADC01F2E46A95F662EA6733A62C2F7F67521065655C1C9E40615584B553A4697141AB010EE4A2AC76C4703043DC41A675309774C9279CA11C717AB9518074F9C77D10C4B973FC9E1FE1026C9C0DEDF68DB0D7BD63C67750DB13E4120EDDF4012EF42DCD7907B52BCCBA359374B48AC4988F4B6731C20295EEE277A09A1140C30A6F6062DD152425D9385046417CE4808C7A44046B3C3773C90C40589524ACCA23B4755B23B267B2C5904CC3A634750B863BBB44243679483997A52A703ED867C57A0AC8227BD4115E88E9461481BF5CA1C6226283AB201844D25F2A094955D131305B5F1BD91789789F4790C193DA4F4426693B9575AF109B0824154F431FF1171E3C48686833BEB3B3A4F31388F0348F6831ACDAF70FB983502E8149B71511CACC7FFC0A411EEA2E781656487139CFFB9F7089388800AD6310015DC85502B5AB19E2CEA1FAB7EAE59CE1429BBFC55471BC8644204596B264284C31C21B1E3E64909EC044B0342FFF306486BAC1C5C2AFF2E52775E7338FC8B9C6D8A78538473CE1181B08048C6129EFF7AD07C85BD24C2803C57A28ECCBD3623713A5368C7228BFE0547566A43A1788E9E4489F8747167B6F08F7945E6597C9872B0CB4B1401288D7915BE8E3715A8391A486047C15B4AB758C8D9B47541C3411417A439BB2144049744460810C01B778879425077E91AE06C1BB831C75E9D1552264A6543266E769B898B66644CA93F9DA7735135D743C62A3876C0C891AB71C73C9B88B5CC14DE0238C82103FA8F634902A01CE5B15E7823A36AACF6A05639A812221085B38B2AB933A12552C268CCCA3CC07CB4E1CA03CDC02B1A5A8231A386456B26878B673644BC3C1613090454B582D5845268F381EB0E70128C1B06F356A9DA736222400ACEA7C58216040A1AFFC5771081743B5F0721EF2B601A651D8A2658EB9C5AD8599C2F040F791AB5D93C6067BA30014AF51766A41C70BE6542B7224767301885A030A8D68A795E9924ED844CBA1B696B18C5A64ABC7AB83A163CAE74CA186C01CAFB53C05FA535D43786679A429677CD3F672B7C9CDF9224030B32C3A147EE0B2A8E50A0905A778AD9269BF04C2A801A1D986B15CDA0EC2F51DEEC2005D450BC070C5E9E2A9646C3A6029BEB907B632F17163B260FA5B75944B00D776862C3C362D06B7852ACE9F93AFBE9A4D77C548D04C68206277F569875FA677921C671FA887B98866E8C25815FC09D194ADCDD34430E2C3725178F6C509FB359E5C3959D72B37A52C303490AE22138DC495BB2BF0C4FEFCCC89EB6B70764CF64CB2B02699E84A562F076DC4221153D8BC1DC0A29387A15DA95EEDC808C666B3CAF04882188B5509106BA5BA1869463834B48DD9A2D7D6B46DE1B83834B7DB556A0B624869641A7B77C1F15291696798FD0CC1D01C417062AB36548F4F7B842E99A85A502D2ED70BB82037FCC6237F058D88AB2DED194BC6F65C723656474830581BB92F196E9FAC65FBFB0E662C34CD1739ECC28ACE01291F24701EC6A836A11F54D44FB50A9150D9401DD96C39B1B02EC73B86827FA1CC39D3EC5D5FCC4523A948A30BB1DA4B3588F029C11234B9B571EC3593E82A0CFD428EA68B727622464FCC35E3DBA3BF911CDB717AD690147AB70DEF66A2A66052A3844B7F6866C1B4BC80C106D3155D4BCB8C13239FC96241CB1B092696A50502A887547638499216FB31379A45BF7B43F92175FE282D98D7A4AD22844661256B711228A31FD2B01FA8F72DD357C455768A77CCA28E6984913C352726176E2192DE562781DCCFDA024FB4315EB5B14B9430BF0E783AD77A763B631F6C03C4B45ABA24A88E85B70FC3B1C3049447E688C3F2145072460B838546572A42F4659A71A95392255765426451F137E8B4CA64B5C24E5CC74A816A988447CE07886CDC59EADCACF5CC5B17B4B0D058C0B3B610DF489066E402ED63A5D155161BAC9F2E82BD0E18CF46476935FBCC0DAA0CCBFC72CAE9B217D3ADCB3BA7E0B759AAB167EBF40F6CF92EDDC17EC44508D051A6302372FAA22A993386201827BDF3A1E932C093BA2CD1BB347096B53919218F321BD761ABDC6CA5086C51B0C471A6C2781D1CCF20BB567CE472FC663AB10B75BDC6642832ACAB5C5D4DB37A46572645A166EDF46AC243805AC78E5C483E25624DAB2AA705B9B3F6D01BEE692351FB4301C562E30A513F6C73D55C0BDCF439F3F62F33E42F7F876F5314CDEDFB4526A075924C59DC03D5F604585571F7E69C7C8F254BCC5AF0CED187401EFACEF8D61E3843D6C8562CDEC0E87D00C8CA8060DA3F031AB663DDB43148EEBD67969B7FD4908AAE27E7D301495DAB212A61FD3F209A8068FCF9A61AD83463C00D2CAB426633", + "ek" : "068A0A4B809B7F0276AF37689CAE51D69C40531C76034B1E81C5FF744CA2AA9ED3ED6A81816485563B77F5DEC3044962EDA6B14A8EA6F7D907D5445CDE91BB36F6A8A61246E6E509BD8AF74F24C879FF9AA743A9D40CD0FD487F95E5AD5BEA4C9B47DDD5B793E75907D1882F203F80269FEC3BE3BB607A5EAFFA890948AACE0E4A21166FE75418A6EA5812B2A1C97EAF774C2EBB91E76CCED52B64459B522CDB3298B43E247EDE0430065562C758449714F08973E44D963890B2D81E146A39D376F8AA43B3767C3EF8B38A9A1C6330AC3AE8D5A7C679CBD590A6B3D4DE863B5BFFE57E9ADCD968113EA39A49383066373C79841CBBE8F1A9EDAB27EC0A2F729E4A7C03A3653B378DA2ADEACB4359F2CE0227E5AF4AD4EEE426A096443E29827C7608C80957E698434FE6725A8206B482D53476A31E671AFB1C2FDEA88EEA3E7C92357C03D4B7F7346770A32B45DE51C79D5ADF7E8459DCD1384D58624FCDE17E90F9DC09FBA556732FD2632081A3F31F3E0BB01ABEA706BCA5673271F979723E6442C496C98FB8273524438A081D7E3996F0AC5F2CDBF618555D4F299A0ECCA8FFD28BCDCD20C2F417B85EB0062C664801817C916CEBBF55ED5BC974663BB9FF8FDC2201A71A72C51FC58B532ACB1FD40C7F83EA8FC7CB5998D4C96D514AB8181F52D91074CA1C58606325A9EB6C7EEC283F9278D56898D64C594E8F649AC0B7EBF14FBAB01E0316938D2B8916E79E3BD2804C2FCE5FB98624374A2ECC13B6CB9020B4688FDB5287050F88BE37384AAF9A9CDFC642E53B34027EEFF611409898C0B0780C01840423353600AD825FDCEE4275346CAA60FCA8DE8BB6ACDF2F4C73ACA82A817F25A3490BF8F6C6957FE5398CECE6C535764B89E40F0FC6E1D0CE2EC3FA9D0FDE724D80A3CBC97F1105E4CF0E03E634F7D43D8594EF9A53584CD2B1B34E9EA238BC5765D21DF01FBFC1CCBD2B803DAC42A8C8FAEA3F69A758F7D929E74A56D45CEDE95B2140D239B0F1C3761EC4152A9B00AF2C70D11CC63EA9AD3049B18590543A34265612B09122842799D7A0F3E910B0A5E821679C696AF0CDEC6200BCE64551551A53870A9B63E26D8CB3BB63EBA8F783B76D326EFC12D0B5632BC6BCD5C38F0C33C13D1CD3E9CAAE45B831CD07489C0C60FC07C83AC32DB002DA4E2AC7BBC1930B1CCEF48AF46C3F1529B545A2350262EF76194D0D022C02DA957E1E9BE3F84A7C886197EB92D9E33AB05162836A4F75E7B26EDBAF9002A90C7A9C749B3FAFC2258CBA92359F31FD6AEFB9AF32DE9CB24D1767EC36AFFBCA8E733C8DE3E953CC7230B0B52A7130DBCEF39C69C5CAC3E891EB1879723C73D18E88F0B400EC695B1530564AFABDCACD1405A2992C127BC94B8B1E83E0BF7972EEB8F208ECACA9DE1FA909117FD8502AF03FB295D3E15858BF64DD0EEFC1F1688BD5311CFBB96F11B99133677333B50AFFFA7D75505F112C8031D409DFC7B694682D3BC145EE7B4235B033A5C524CEF9D72F0F2AF0AD10A4CD1ACDB1674611CE09", + "k" : "0EADEB34588E860B6D25B7D65DD594D103BAE1C33B3D436F219A989E0B0D1594", +}, +{ + "rngSeed" : "CC0C86CC0ABF86FA21899BE1953913C00E7C46E6B5F730C4E88B3C034012763981D7F14459D3081638080378348856EA", + "pk" : "D743A9918C149231C6BDF338098C07F21064775B6700ED30FB2153478B67B0F344DA35CA35E4B7C289A503D5AB9EAB6E374279EC8AB67B2264D7B9B80D6BCE26098A305734E44342A5078597F3BD574B931C3C74461C8DA856239C24C576815F7F48CFC026BAEAE328A8207F5091CB7248615AC076F12763F8B63C0B75A1EF075B6E1C61B1C3BACB9C8895286E30729CE083B90DF566CEBA4C00E06214C295AB2B95E2B70032E04422572C87B475A63B53FA84AC9FE3C8BDD3CD06C13859B263D22A588B8126F2C615E3A705E0BA960261B47638A9E83C5BD3F791B362652290C5BCDCC4F3C93909431A4EF875C5E30F0C311E5E8344DEEC53C3B4BF584932F168710F66CBE718886E2ACE059034FCECBE39D50D012C0EA26B8CF13807F1117F32661CF997145470C8AEDA68022CCC43D1BB66732F5966C11EC221AC678BCBA824F43C3EDA94401C17C4877490E4393404DB53A27B1DD3AAB78E152A58F3741E1BB1B9A8202DF64434EA9C5A8C9FE7584EA538250DA92295D3A4ABBC3E392A36CAE9AF1CC51095B2B2DD97BA7072ACEC4B7B83BB6D284C5FB3FB634AB3012E8825F8748022D8CEF7367AE46B021DF68AA8239D06C09FE0555E07DBC356293D41BC4F1E133DDCA95D2298B2AEA88AEA5637D262390A79980220095D7116447C5D5B6BA2B962C794C899F45860658A0A530C7669134519A501E5A0759F9A50777A2A6DFB942F98B50067455A7B692FB1CDC2C10F64E9114B29CBE173AC4FC2ADB95C550AE7A55387BF01AC3C45222FED7BCF9E240A6D9B0D088C032AA9714A6A55C692635B6911D92353C68794BE250DCD65782A6674F87343A6654324F47F5AC9B384B22766D0C96852753A4449E08371D5128F31831EE766219E910B1F6267A57BC991DA5B2B69A5A9212BA06AC917D45C9AA25BC1B513F7144217E84F1693360EA0690E51688A704C45CB6B1071A0E9A130ABDB6CD3B52B8A429C33D126CFC10C73C928DA9507AAB00950F37E9BBA0AB981394B137E337A88249100DA175FE9299DE1D1130381B3FCD265F7B36C00959B5BC2C150EB7DABF05BDF590E32E063A01A7CFF6A9A22C56752C8B948502F3F8AC5CA444E10BB6BEAD1C7557B2BB2E37D55646455162806A7778B1938FCDB7DA3E64C01C4A36A847B77958D27AB9DEFA6256B6A30A9B9962175C13721CD28E979E0D60196BA8C3C940AA4718D39A9B280486A6C2264640C4B09642499957BE9642B6B545DBCC868098332FB103D75E38EB7CCBEE64A341B38B0097479C019257BE03D5D290E89A6A6F0B61039B128B46B02BCD750A9496EC4FB8DD6378E1AC77AA9F37A75D072D268C365725926CC76B58B9DA040C173D7732E1401AB222553D6AEC7911D052C569C59393997372E548086ABB4DE201AC1C17F25D76FB58C4FF3380CC5965720B989F4AA252623C215369076E771FAC786E7F0CCDD917DA64126FC610EB76948F97A5C3116869A11A46E612D9DF04BE0B1AF0E8C8BB46607EA4BC4B4B04B3F79A30A2A154691A79217537B97A7DFF6AB4EDC9E2AD6CD97D3AEF52837AEB232F799A3CE30A6ADB88F6A0AA73FEA00BF0146CD5447C6DC483B4955A0A3C241E7CC353C2C7085B84C5162A49E7D61A2D0E85A009833F3EB2305D7D435E2A4C81F358AA8D0DD50628096F4", + "sk" : "ED0C4DCBCC3304E1646A04B9675B94430B49A83BB1552C211F8928C47785C90422BB658F33890F3FE25078CB0C5D52AB737C647B2080E32164DE411C489664D5AB23130C1B4A409C1C0296BCE722BFFAB9D60BA4854C9887F0089567994E3375E438069BD40CF0E08E1DE134C1F902D0ABACCFFA0E866122F28894F5275A8A7C2BE316811032738F99B53AF64C6B346FCA072EBB38B665EA616687042B240C53501E18A424B5150B98A4897A168E5BE9B9A1F04F0F14858AF0666E177BA7F52BE6508674EA48FA23313A71372BE5A718A13D41F4887892BFC013889481339B2438F8516B24990D70C1159581A109FA1CDD460E6910465E71CCC362798670933052BB03E23768C3C255D0BC7F002E7DC299AC0145BBB585B9682978302AAE26047BC8A2CAC90589DA65D604ABAAE2B36BF78604D33E23A67544A79FB8131970199116B5BEF702BA74506CF72965D7D8BD8B438935C1C8A1E535806009EA22A5EF4B215003B67627358151238BD50391C8384A938E7098929B7870F87321903C819C6480C992CDDEF1C969E4A1ED4A98D367994394571AE93A61B4336D537140887C792290A196B01BC7C30E364618FA371BA975F49B4637F9BFCC7BB1AE789156C4AB2FC6CD62195A44C7572CF9239C3B951BF636B43CCCAE63B82CC2BC4BC6A03BA5A087C534339905F4280B7A79186B2652F3582C1865CB6AE4B334F75CD7F358F2BC69CD1B0D21A7AC35C926772BA764A72157E51E38CC66392A1BF409A068E033B00B4A4D04516873516BEC242CE93EC073C366E8534E4B55FEA906DAF090EEE9A1FA4A17E61A644CE54536F70871E61A2A728CCDD7C1E702869A28A2ADE4CD234119229C9CFE80AC664BB2016125B3822AB240989E79A72CC26207EA4B139BC1BF5A257645B9B372763D4A318D4647024C797B8A1C2D49BBB4857CD1272F56B8342C46541000C84BD676BD533E9529072E77A8F73164FCD8443C3079C1AB5EDE2305E6C5C22AF691A25ACE01436E43D56E204B4DAE93CFF827C061D1354ACB6CD4070C92BB4B145BB0649A6FB8985E03E4A82AA178161A2BBBF23562B342F4818100B502C88904C196C08920AAB3EA154C9535DDD8C9C12911500A38DB80BB70C3794EE15F7A44097A7407851007B40801D16C417E5905EB994EDAA2807B9C7BEF6BCA9065374B856F95F09FDFA2751C20C5A42A3ADEF757EFB8276303A6E65C4CB17ABF0F97C29581139FD655D4D80224275799645008F42EF508AC9445C388A989B3AC09627041741C30B433A0D0B81A59D237753ACE7A89C1DD0689CEE8663AE8497E9BB885436021D4BA553C706FAAAFE7C8478E346CAF5280E171BA24672E850CB80E491BE2195749A8CAC30355F5B386E47A65B22592A1F7B09317CD6F3449BB22ABA8C2711E979E898A2706D80FCF52AF28A68F0F7A0F6C3221CA73918140447E166A00669929B915C4AA507E49672B45154C92239EF0190B086B65FA9E4CE7995E39166C8BA70B5026EE2745C2CC409E40C56294A9D4539101CACE01A2861D31924D8C3F7E824FA8BC552BF6B70C042BEF1192D1517091FAC862776C9A33CEC6939D89A30130561D400552C195C702BB9322378A12E144A0F956D743A9918C149231C6BDF338098C07F21064775B6700ED30FB2153478B67B0F344DA35CA35E4B7C289A503D5AB9EAB6E374279EC8AB67B2264D7B9B80D6BCE26098A305734E44342A5078597F3BD574B931C3C74461C8DA856239C24C576815F7F48CFC026BAEAE328A8207F5091CB7248615AC076F12763F8B63C0B75A1EF075B6E1C61B1C3BACB9C8895286E30729CE083B90DF566CEBA4C00E06214C295AB2B95E2B70032E04422572C87B475A63B53FA84AC9FE3C8BDD3CD06C13859B263D22A588B8126F2C615E3A705E0BA960261B47638A9E83C5BD3F791B362652290C5BCDCC4F3C93909431A4EF875C5E30F0C311E5E8344DEEC53C3B4BF584932F168710F66CBE718886E2ACE059034FCECBE39D50D012C0EA26B8CF13807F1117F32661CF997145470C8AEDA68022CCC43D1BB66732F5966C11EC221AC678BCBA824F43C3EDA94401C17C4877490E4393404DB53A27B1DD3AAB78E152A58F3741E1BB1B9A8202DF64434EA9C5A8C9FE7584EA538250DA92295D3A4ABBC3E392A36CAE9AF1CC51095B2B2DD97BA7072ACEC4B7B83BB6D284C5FB3FB634AB3012E8825F8748022D8CEF7367AE46B021DF68AA8239D06C09FE0555E07DBC356293D41BC4F1E133DDCA95D2298B2AEA88AEA5637D262390A79980220095D7116447C5D5B6BA2B962C794C899F45860658A0A530C7669134519A501E5A0759F9A50777A2A6DFB942F98B50067455A7B692FB1CDC2C10F64E9114B29CBE173AC4FC2ADB95C550AE7A55387BF01AC3C45222FED7BCF9E240A6D9B0D088C032AA9714A6A55C692635B6911D92353C68794BE250DCD65782A6674F87343A6654324F47F5AC9B384B22766D0C96852753A4449E08371D5128F31831EE766219E910B1F6267A57BC991DA5B2B69A5A9212BA06AC917D45C9AA25BC1B513F7144217E84F1693360EA0690E51688A704C45CB6B1071A0E9A130ABDB6CD3B52B8A429C33D126CFC10C73C928DA9507AAB00950F37E9BBA0AB981394B137E337A88249100DA175FE9299DE1D1130381B3FCD265F7B36C00959B5BC2C150EB7DABF05BDF590E32E063A01A7CFF6A9A22C56752C8B948502F3F8AC5CA444E10BB6BEAD1C7557B2BB2E37D55646455162806A7778B1938FCDB7DA3E64C01C4A36A847B77958D27AB9DEFA6256B6A30A9B9962175C13721CD28E979E0D60196BA8C3C940AA4718D39A9B280486A6C2264640C4B09642499957BE9642B6B545DBCC868098332FB103D75E38EB7CCBEE64A341B38B0097479C019257BE03D5D290E89A6A6F0B61039B128B46B02BCD750A9496EC4FB8DD6378E1AC77AA9F37A75D072D268C365725926CC76B58B9DA040C173D7732E1401AB222553D6AEC7911D052C569C59393997372E548086ABB4DE201AC1C17F25D76FB58C4FF3380CC5965720B989F4AA252623C215369076E771FAC786E7F0CCDD917DA64126FC610EB76948F97A5C3116869A11A46E612D9DF04BE0B1AF0E8C8BB46607EA4BC4B4B04B3F79A30A2A154691A79217537B97A7DFF6AB4EDC9E2AD6CD97D3AEF52837AEB232F799A3CE30A6ADB88F6A0AA73FEA00BF0146CD5447C6DC483B4955A0A3C241E7CC353C2C7085B84C5162A49E7D61A2D0E85A009833F3EB2305D7D435E2A4C81F358AA8D0DD50628096F43CABF1C47E7AAADA59DED4FA8CE378CE1D9EBA621EBFE8CC96A111AAEDC4B6CFC30E299218D4A39C2EA3FC06439FC4C411E99BBC34B8F30D23845E91E71FEF3C", + "ek" : "1DB16D4CED75D797DF5606FB9BBDA26BF887628D593E8D81AC6D4D7AE804C1712BDCC475F6334AAEF5F3E66E4825B1666A31D3BF9179404E27CAA4E3F175F3256F3218C90975101171CEED25C2CF3F8CEE43695F1B3D79F847E14D36ECBF97E6372F0EDA75B64FE009E8E8C437FB0391E3CADADE444A815BED4E6DC62105F5006275836CEDCBFDE5D4A8B70D64CFF6A3280D4433615557EE57B963A051E211872EF61213799B66FA778E2055B48944E865050CEAB2DA25B5CD93E1D701F099C35BF2914212F9B117B4861E76D51EA610F86FA90CC8258D71280683401CE3F4BE443052C7E3979D6A008BC239B623A298E10361858A9A5BCA5A84AA92545A30EC8AFCE73BFBE94D86B28E99A509CBF4B3812B7D2C437BAE8AE5E652AD93CC728E655D2CF7105FF9511F8E82E701B8C3F80D24A0DF7F08F889AB008401711F0B32CC63A5421BC8AA4EFC0F7D241C3E7DF8200C04AE14C70D6B3096233608894A794400708D4C234C246B6ADE0E9B148926A6392273116C4E4BEAD89B7481ED5507F379B62B33AED41AF2DE272F469F206E484742569351E0D57D4A8025B288E6E69B001039AF74A11E4E76854CD9CF7225424F5F05D149830E527D00FB1168C688E7037C3A523B8F70EC9B930E49DB169E25BE09BA06264061DF9ED62B0649C4D59E3D84977AC1C461042033390B05B81D4A941D7C6AEBA26D1E24574313E2E925EEAA417869F1C8914C4E2ADD0BCBB688C5C9BC93EAE02BB9699DEAD5B313D0C5E2C095771EB258DB263BF47AF0BDD0D5DEF9D0C6E486BD0D3876FB0910D243A25CE20210EFC18764589C4D4ADD56FB048F0185226DA5237C3798FB27C95CFA45C334989CBFCE049E48195524F803D21720C9A244E67ACED14A1B75AB17A8DC4A6C8F63CFEFEE1A8A8C1F647B471BAD12418B99651D3D8DAC509F9EA9D61AD8AA68C8AD61292D72FF26EE6A741D94383DE1B66519137EF359C911EA5C13394F1C66BBF1073E4262B9008E777AD47933294F26C9628E10301A2101EFEB8E7CDC53A89F9A1CCABA60C50587D3C714BF5852D3198D4D5BFFB7C1CB66AD77B99FB21DC4CA72A7E0DF5A86E5005D93D089285E19D65C652E2A55F4C5C49DB62AE3BC5287799224A3AD324F27F0B9BA3E75AAC6A2737C48621FBC2A95F0DDBF9B0F31A484C3C301D05AA0829265BBD8AE67536970D28F28832E406C3863D77BE8A9792C4E16A64ED7BA5BD18CA4603817A84E66CAD01258456711B94C847FFF150CA2701A62584FC24FADC58884A3DEFA27C0E926A77B6087128E80ACF6D24F87CC5D7E3F4CB4F1DF8F2E428E9751C73282E94B15EC869028DAB10D0825D3971686604CCCEE2E9EE96336F4B8018F1BF8AFAC503458C5BC5701073DBC16BE9B8D41F6C7D5FBE65857BE97E0649C96782A015E29D222AE9DEE897AE2E1C76DACF9B09128E72E7A31AEB311C985AB5EDC14C588623761A39CB89ACD452607ACB12429A5755D5797DB36FC9CA90693202849E89BA14BD3A7473FC1D13A5770E155E31DA847", + "k" : "333942E086869D07706D181DC08CE61213F4E908056A59242DD93D06F63C30CB", +}, +{ + "rngSeed" : "6D5A7CC326ECF3983C4E7683F45263A37F692F3BCD2D920E1FD9584350119E74F9A3F905F70D3E20318C1413DE2A0DEA", + "pk" : "8E4458305AB8304A53B5C47B42911BA1B011C4DA11C08B281E625F6F37815DBB1F3908C4C1646142B14D846B8400114FACE5CBA669179EF121436A1975845652C5CB4FF62FA0073738F0264401ADBB78B44E61619977804ACA17DEEA16BAD48655133144781B196C2A949BBC9AA8714758061465A9CFE09F2A1316CA875523E07FBA515296309B6B7391B8D192012278D684B2527318F30A7C1E598A05027409F65A7F36B57F693A660C7A9F2B0BC38420128B87B005B5CE7631E4A10FF858831CB0112F5B6F04334565563E751820DA374CE2819E4ED9BC5A959EEDC4052C502ABC54BAF3FC0E426B77DE7A274F81451070042E70C19A09421454141D2600DF76A740423CB887065939CFB657A76785B35A5868401CB4D88AC8194769AD2499F2F20ED2A188E8E47E918CBA7342B4C8893FE411B47B058B0070771161970C4331EF67BE34BBC4781171BFA19D51E11612F93CDA611F4ED88F85B87E8BEB6359EB410E7175EF6171FAA03E29E11EA8A6CAF023C357A87AFC652A00CD422020295BD34170068D31B7A058800026A49FA1F7523EBC5544389CAB259815114D4B01D089D3CFF6956F5D0B5A9FE652825B1150E21D11F562196892CA41941B46018EE73683E008525059496A07BB029737103B729B1FCC13AC3236B47C63A6ED4458A9724EF7B62361E75BA726BE6774CF6B3572657B2A6ABCB69182CD3B880328BC4F52C075C150BB22AAB08CB2326815712AE20CF1F257B9E6CE0725782E9590191B2055A45C4467C5E7D70C35B8A61A48A317022C298B612782203A820F2161844F6A6FEA58CA9F230713C701AAD2700BDC951FC9BB8F560DB9E99F2849AFEFEA6C366C982F3680DEA24891C631A1032D9D884A5AD9A11FA8331BE85F1C91C6DE2B4143AB403B153D9DD714DB314C683CA24CC45F86C2276058BE32CA1CEFD4116BA386069856C6128CA86A63FBF6C15E876D63F738F847A32166B1592C3307D9C6190C5C42B7AB756CCB394C7C26C28FCD158BFDAC9F04C99E30254D500CD0DA1B9F2B74823F14283A888BDFF45CA218B89B9450FBA868EA9B1A5858509137160DB31AA292863ED216AEF822123C294A825E26FA3ADEE0291AB37C1462C89A4981949BB764F4222B3527DFD8A715682D159BA380339971857272C7BD7442CB73739C450B58CBEB6936B8CB619654037856935376ACAB92026BBAD18C512DEC4E19671180599E01651F008C3A04007CF02535AD7608E1E9257FBB04E419976294702E84341531B95E1B20C2B152A4D849649113C69A8F379B5D72AA86E01A4C5202AB2E276712F1131C411D4072CB45147C562C60080C56EFF7AA7D90C4DC293B01BA935E345B88FABA62DCA043D94C4A666786C35F9318A579A9B67E429144240D206612A6D802FDC24AADCB42B0DB4251E06DF92A67E632AA4A29000A77CB2FD2959F851288464C824872AE6A9FA1BB3A71D8879E303C51445956EC8AE49C4AE6AC4DE2047EDBF3C0B23A29B8B86B83CB24530B0D17739331292BAB85868E4A9BCBB2B4D4514E52D9AFBF66172AE560C08C7F9CFC0C98EA4EC9C785FFE76AB5098E9F3C5EAD6A7759B529661B50E0368246C5AFBBB9B876C8072C1C1CA63A4E6607FE4286FD2062614FCFB544FCA36EDF0785C37BB6F5FC33E2B9D9D03A0A6C", + "sk" : "2E497FEAE75AF1F280ABF2085C0321A00911D5008BF8A4042BA44691367FCCFCC2D496CC40E113A0D056B5468B190C0E2E629F3264797F0C3B647865F4D782A9601DF6BC5F03C1437A23B5D222BAD406874F1459F1F9AA3AC061A20677D9D785535CBE7073667E4C916725AF4D7302CF76BC3C23AB89666A2019625044A8BD954DF6D68C2114B31EFCCB7D91AF07F3AD3FAA852D4162FD847AE7A11D8E11133089B9307806A9237AE3A9949043B10107ACC9345C17697307E0C6C3CA1734F6CFBDE73C6A09AA1B8159C51179EA8B93509B223668849B1B7C59118033F969B9D34B354B32BC0B7540D3CCD2995BC36ABE44C0394EF5724B058D0A575947024CE6E72463389BFB36BB851864C38097FBAC7204036DE72CB0DA94CD2F98A1E52C1E630748A7C05838AB53B2D33B0D541C1BD31A2BA803F4205616423534C982038622B70BA4778886F2D15AAA681D6468848FB0601D7097B99040E9E8A981749F741127C6A0000B0C32E28976ECD97514C2AA15F82979497E1DA91BD3200D4B0AB373E41A56AA9ABA24693CF9C7939CB8733C27A7707EDA2AA4F3F304C5215EDFA3CC3F785BC0BA83D9F291F8787FC0032F112133FCE87441B473961CC87629337CD4ACB5367432CBC7407585A3E2463DE228895327E883604A19AC2C46389F1B0706F720DB8C17F709A796E03D53046C4AB2013AFB40ED73247D0C52B0F88E2C9100B1B31813346904978D3BF6BF13B4A6C54C3894F2A2266A9987A4C8505CBD94028EF7963C97D80575549559BCCA5D78C99AF532B31A382567A6B1E8C56BABBC5863144FC81C6322806A6269215740AF996B0ADAA72F425169517D1E48AC1349C343214C52482B9D19AAE42C4A6DDB550040B30CCC82E7D5578355B7313A1F84F872170A6107A52008AA47988A5A78A15A6D070E308C59BC630D1A1292FC2A41C86967B4A3B3EE312EE3C2327A80CB9A112B07B9B0E5858191164A7A87427A8423F7116C2E84377AF5CEF303B7E9069661F1047C15BC52876C45864DD78854D0F07FD2E530FBBB9B13A4034CC38E34344D5EC41CF544359B93CCB0338BCDE09E9B938D5E0C2065126AE81581F62668AFC819F705AF3B82BCA5921699602C6AF9810084933C438D4DE95A6691CA3FF425FA04B614BB973D899BB8748A7571B112545548F08FF98931EB555F8308AC724A8AD09A90F109219C3032F4013CDFECA92B4CBF23E528AB6ABB29370361BAA8F74C3A2CA8A29D6A893EC06E60979E351B4FF6247B8FE3923CF027C55363A9243CF9A237FF09C0666AA7B6C56B17A63FEC016B4C15CC70C59DCDF3294CC0C72DF53C9B0B00D2383E7F48335108629762793FC70642CA91DFA1BA6D97A1A36A55FA6C9D73246A3930B31FB644E34579C2866FC4C5671667B0DCF1AEF82BCCE732052D766673B398AAEC441CFA73DFD3B463E8AA018C4272EB0C3EF15618F9ACAD61BCAF64017648539C766EABF8038F5467D446912C98836055496B1B7D777CC82EB255766568822704A12640ADE87D0BA066B4F3405177C9E1E41F624C5AE055887D68C97BE0B0EAB254DC3756D00BB8E78676FF62A94F842E9F5774B4F07B723577C742BF4623B0ADF246F87C53944CBC8E4458305AB8304A53B5C47B42911BA1B011C4DA11C08B281E625F6F37815DBB1F3908C4C1646142B14D846B8400114FACE5CBA669179EF121436A1975845652C5CB4FF62FA0073738F0264401ADBB78B44E61619977804ACA17DEEA16BAD48655133144781B196C2A949BBC9AA8714758061465A9CFE09F2A1316CA875523E07FBA515296309B6B7391B8D192012278D684B2527318F30A7C1E598A05027409F65A7F36B57F693A660C7A9F2B0BC38420128B87B005B5CE7631E4A10FF858831CB0112F5B6F04334565563E751820DA374CE2819E4ED9BC5A959EEDC4052C502ABC54BAF3FC0E426B77DE7A274F81451070042E70C19A09421454141D2600DF76A740423CB887065939CFB657A76785B35A5868401CB4D88AC8194769AD2499F2F20ED2A188E8E47E918CBA7342B4C8893FE411B47B058B0070771161970C4331EF67BE34BBC4781171BFA19D51E11612F93CDA611F4ED88F85B87E8BEB6359EB410E7175EF6171FAA03E29E11EA8A6CAF023C357A87AFC652A00CD422020295BD34170068D31B7A058800026A49FA1F7523EBC5544389CAB259815114D4B01D089D3CFF6956F5D0B5A9FE652825B1150E21D11F562196892CA41941B46018EE73683E008525059496A07BB029737103B729B1FCC13AC3236B47C63A6ED4458A9724EF7B62361E75BA726BE6774CF6B3572657B2A6ABCB69182CD3B880328BC4F52C075C150BB22AAB08CB2326815712AE20CF1F257B9E6CE0725782E9590191B2055A45C4467C5E7D70C35B8A61A48A317022C298B612782203A820F2161844F6A6FEA58CA9F230713C701AAD2700BDC951FC9BB8F560DB9E99F2849AFEFEA6C366C982F3680DEA24891C631A1032D9D884A5AD9A11FA8331BE85F1C91C6DE2B4143AB403B153D9DD714DB314C683CA24CC45F86C2276058BE32CA1CEFD4116BA386069856C6128CA86A63FBF6C15E876D63F738F847A32166B1592C3307D9C6190C5C42B7AB756CCB394C7C26C28FCD158BFDAC9F04C99E30254D500CD0DA1B9F2B74823F14283A888BDFF45CA218B89B9450FBA868EA9B1A5858509137160DB31AA292863ED216AEF822123C294A825E26FA3ADEE0291AB37C1462C89A4981949BB764F4222B3527DFD8A715682D159BA380339971857272C7BD7442CB73739C450B58CBEB6936B8CB619654037856935376ACAB92026BBAD18C512DEC4E19671180599E01651F008C3A04007CF02535AD7608E1E9257FBB04E419976294702E84341531B95E1B20C2B152A4D849649113C69A8F379B5D72AA86E01A4C5202AB2E276712F1131C411D4072CB45147C562C60080C56EFF7AA7D90C4DC293B01BA935E345B88FABA62DCA043D94C4A666786C35F9318A579A9B67E429144240D206612A6D802FDC24AADCB42B0DB4251E06DF92A67E632AA4A29000A77CB2FD2959F851288464C824872AE6A9FA1BB3A71D8879E303C51445956EC8AE49C4AE6AC4DE2047EDBF3C0B23A29B8B86B83CB24530B0D17739331292BAB85868E4A9BCBB2B4D4514E52D9AFBF66172AE560C08C7F9CFC0C98EA4EC9C785FFE76AB5098E9F3C5EAD6A7759B529661B50E0368246C5AFBBB9B876C8072C1C1CA63A4E6607FE4286FD2062614FCFB544FCA36EDF0785C37BB6F5FC33E2B9D9D03A0A6C2853CBBDA86E7039B635D4CC850F494D42B240ACB54AB2316791E9EF5B45F1D2A33923382F8863478882483037FB1282FF917EB6658A7154C6AD64B5858C629E", + "ek" : "9C679AF298EC1FE3C0816A957399E02C961F85AAE2BC27D37F1BC9E0F3CF47AAEB4E4E85956A7837A388410CC2BC914880ABC02AEF626774B71F9F0B039AA29EFB95BA7C05480EE2A34435BFDA2122B0AAF4F347C02C886D329771D4A1F037D913B91177AFF18C1EC98AB7FDD201FC17D141573B6AD8DD3A6BB57294AB12124829B828DD837D5DF86805F9B7843F8EFF99F3610CCB37B3EA46A0F8EF0D421D593E92F1357EDE77A89623AEA65F3D2ED1310CF45D73F8B788DCD4FDFD732FE284063A36C4157372CBA199CD9B04392457C00747A25866EDC72E74152EACCBA055DB71D3A635C056F7F48AE7564D68750CEBD6EEB7ABEF2ACEB6B762382825A3FD28228A614512C79A7ECC14B36A07B6AB3B5AEB55E4E18AB1FBFDAEC17E8C495CA1423544641028AC2249A68D35560CB91EC8476107E09497428DA0D26F1C17954B7D439BDFCF1F3DD1D507699065A8D4D65E9F4BE6C6C2133FC08AAFC8DDD3CA76EBAB4786D0A631C9B2C829D1358FF2BA5D182E94DBF12AA209A47471A946FC2D0224867B8D2F6B69EF0E493A04889A4A58FAF0A115515C5025992D3135A72BA9A0738B3D596B2F48D02A6E75EBEEC7CE1E55D753F239B01CFE637CA50A942AD6C3994ABE23A519BECC9DC6E0A5E59CA900B95774F763D4845836D332E0DE4EF25E63E3B1A7B11F1C898E704C4095F806162B7F2BA85689D26901380ADC215A293B01B79B23064AA5BF6A97354072DA1C662598D1C0CD5206C3911F965E05BC578F180FF69B3CA5F14F1C424569EBCBBC1A3B984A0FFCEDBB03C92C7FA79455AC83185945CA73A9B927C49161EA35B0B51B39AF689889AB16A0B8F7EA755B236C85A503A587D5E0FA48405498E0523B7E1BA47CF76331F222A8EA911F389F8E5D066504EDFA6795D6DE9D184C57FC2589D71F500F05EA997F54BA4A7D2165FDDC4A421FABCCF6B8ADF90B1212653D0199D0A8669CD03A5D6158D46ADA91A85990534319891F880DD717727EF2B4F8965B67B226494EDF2B66EE5F59B8107F30046A1B94BB55AD8E6FF4CB2C8C2D4305E032AB25DA5E818A8ADAF45B62BDD2D98C4F955BA454EA4B7D341DE786F7CAD4BE70252ED22C289E30328DBC7A045EE618779893E7E75B80EB9CB1ACDFF0599F8DA498730EA5B4AD1CD91C48F46EB1D5354EBB36FC375F376F68F546C77AC198BB73836AD5089017A99EC81E1F1FE98CCF49C28BF523CED35D0E8A8E929D8E1B00443AFAE491FF4CB56383E018AC77818BD556FE4D7186CCDAF1715649D4E0265634D749A53C667F4CADA54279F4B1FFE4F48CC5C75695A57565961AE8F499049686D6CEA4B148E7261B2851480AC0B90615397D5425A4F1374B55F329EE867D176F1D10939195BBC45BAE7C1E17DF6E1438715B8977A162138C807DBA7B3D0FAB0B5BD0609D7440049A568444DB1CFBBE1FDCEE8A59BC3AF71F26499CF8148A565C2A0737DB46C10E97ED0006EE4CBDFF293FCB5A7F31ACAD523F8D28CFB08B2B02257D3E6DFB254DFDAE0B9E6659FD", + "k" : "F98DAB3657AF23FEF6A530CB4F246B11FA2FF506EF790DA069DEAF9FAAD19306", +}, +{ + "rngSeed" : "F68FC0314DEA88F66AFAA76E6C9B6804B13D4876924410D1F526FAC59A62E26C560B125B1D0F8B461F1FC2E351EFFB4F", + "pk" : "77155F91195DDA2B52C1BC4FF328C3732799EA0AA8ED4229E9A239E5B5C5A02C1EBE98A381DC56E1D4B56DEACDA3AC52B1088805476C01609A0A2373A4BCA788227172C4431B000005D855CA059B4E554D3DD2103CBC7854A12CDA368CE202873F5747450C4FD994898DAC5926765536662C81581AB4DB18E9763CD5A747659440C9A33EAC713CF907BA0D5A875B90882DE31B5DF825F337B46451705658915630035724C127C9C4B48572951770241993F777145573BC70125D35F1B03A121D09BA4388889568BA109F04617360826AD48F2765944232B1CF636FDF3C39C40AB87B4B50BFFC1019EB0FECC35CF7416DDB3146E275CC7AE209269A7330977E9DBA9CAF79C99E30B8880525CAAA84401CBDE7CCC0FDA4B250B7A2A651B3AFC123EFF52EEC55650029AF651B2014F4669DE319435B7DBEDACC173C3DD1F3A8597B80C9C3869D7389398A2404E790C9463F2634CC7351BAC9D74B62B73E7E54CBBB3AB235C7C1CE298C0C0369DE33224AB7B03517856E43CEF2D39F1D325D1E221998C53631D32A57A880F24476A7E89F8C1B2D1C49759C322E993CC7EFFB2BAB738F2648BD8133208EF26FFCAC76393714859CCCE0515D4A7192DED6AE5E828BE6653B05CACF0DF1B4816A972592089FF88FA421A490CA13C6789639C909C4DB18EE43A01989C51B6005ED2548AE24AC8CEC10BDA7649E6C9359C45BF0EA0D39F25BB1AB3C3B5B88CDA24CAA8C7C7106616BA05DA6727896D2A895835C9B83654B358E0D4728FEC8A150B39283E345F3E06B4680BC632009EB85ADB811277926662E531DB27B3CA60843A6370C304C1DD21A94AED90C3663C0948BC12F0A32AF533866F5931D5C74423246C16AA4F01808D06A6D50444EF8A3171AC641E9417E2E025390CAAFF16C6703680951B1A0E5ABCEB8FCA9830C9CE1AA08D5803280F31DE3CABC923B5A1A7C4854D841729194D3685C03F975A72440B5FA01B11868A48BCB73794C83644D1D39B9664C432C7B3BC311703EC01D268A34A8A1B3DC79B9AE07B8CD133B7D4BABA7F39B4088043E4A35FCD08A9EF141B78CB1F64841EBF894827BBE1EC47509817BA27CB42222272A00A633E1B2AB344BD3778E4A579AC7D64A32E2356B1822C1334FA0E6ACB05798F63192EE20629106130A1AC330C6CF0200908FB37184740E5CAA5AD44067AC7930F696BC9226235D212D71F57FFC2C8C185C1F3D717271022F2D256963DBAC5C5A1404A71E3546695EB27D73221892B5BFEF114D6F88415875C013F16E48D3CDB68C2000A39A45263504E0A7554386D68A4D3992C9F6196015066D3B8282E8D3398D2B5F62D7AF54698418862DB3A84286F142A8CB44BE011E0F2594D161611CB335BDB018D9E58CC71A363B29439D54CC6B293AF33B0DBBCB80C7797819A96C1316A783F60F987A3FBE1ACF80F22F610037D17247122C4AE2B2214638205328C43FD4BEBCE93D47C02B84E1CDEE7CB48805396C24410D71CED4805F36A105B05C6564EC3450654CC0A12E62F7C0DA79496FF2BC97B7B4809AA30D577A2F3428E48220239B1B97D9278DD26D93D186628812FC697D961442879AB64B4BA0BE3C46F5E55C13222058B407C1694979897CA0615E8DE05D85D3532060076ACAFC8E0AADD8CA7406C7BB316ABFDE1BCDD166", + "sk" : "65F04F655904F41A6A88535638821638039EB85517C3899BA016172B8B3120B90E4717C51FD0A6A1D8CB799562E1901128756501BB00D4B695E11CCB335B6FC4537B236C4FBA1885D89B2DE48427A65357C31990D9955AE7323B30244A0F296A259C5DEAC728403481F0745F275401C9482FFCC3CCA44832BFC0799164CBCCAB87BF04B813B32801F2CA915A9B35D60E34E95A74E660441A686C89397C915290821989286168B6CE76E485C946179DC484CE6BB94C9C375A899AFC6932CB9876796BADA211B849101AA4C5B837453CF89A0642C91721B01ABEF1A78AD28006E25762A65D23664C79C87CF79CBF4EE38070905E8B561A254394B9A4A3D40BC23CA6A2E98BAFBDB067A34C7F450A2EC9C419C8816FB71CA46D177E148541D3AB6DAD4B467ED7AB1CC94B57413C31880A418C56D851CEEF706534871DDBDC8033679D82EAA69A4C4872233EC12BA28E42870E4A43C3BA3E0E36CF7CB740FCEB3AF481904007051C137D702C890D126F7E6B1D401BB4E81A4333D7C8EE5CB8636A984841C67817411862AF5E3605FE838630A680C773725495812BFC4531106AB13B52C2D357B3139F9495C2D4E4A77A07518FAC187185B2BE2355DBA0066D8A418BD7AA5038C6F0D4A3E5A074D409A15FE77BA7E176CBF2C7C20B10116737B6232851E688FB3279D060C8C24005A73780E7713255E6498FB50C056222F376CFFEBC723AB180D4EAB9AEE52A1E08CC2A73B90419A056E32D660C7717884F897809DF5C42921871A1E59CE36AA74CBCBD9FA3069897A0A76113AB6818482548DB03455A58B127DC5DAA0CCE8A5B5F3F10A678D04B68FB46FB6A94EF87161743B2364098A40128DC3181C551CEBE151389431972498317B52D4F5332D6B74210D783D9C461453347F820ACB6E4A3315A2496CC683590B08B0503B31B97688A1F6CC957C6C4724FAA6A0B982859E961C808AEA88862C750C6045B57F53963D83448B228847384754CD45DBBE015E6254C055163A60C02B41988CC2511FE70963C632F8180333C532109047C65EBAD0AA56D3BD136EFC88B6DD832BD810CEBBB9EC40CB44754BF664773D5466FF0B86848314432E085761C3D81E2669AB41D9E3C1EE343CA24BCA795ECCFD6942DCC27170A74A02415BB732BA880A5CFA922B10E4973067109A3B210B02B691C8AA4A931252546A77B206098BA78F6E4781660A29A00AD98307B76CAC825A534003154002977BA8150D3847FCB513120F43B2AEA6788E5C17BFAB456D7B96A1CA2D217B86BA5B87400CDEE144717F5B34FA842778C0917200482C99571A36A133097365B7E36621F51AB88B0D0B3AAD022F39B4EF3EC1CD0459EC3C80E56524173A2047B099C304C71E9DB708EE55895DC1B30CC8FB1B1887F312D70C8B399944B4DE4BE1542A27BC0569674A4097288B9C60982149270D57D766C09A47045527AC8D710BB41F8C34EDAB551D0C022A627C2078EDF078B0464B81B46057296B5EBB3571EA000A72065AD11B5CD36ACCD5628283554F38B6AA39BAB97A171CF0CB3664842686ABE589A9321D7B911B371EC5A31D13A4E91C8118D504360F668591163FDD233A6BC5E65341703CBAAA931293CBAC5D0F16C77155F91195DDA2B52C1BC4FF328C3732799EA0AA8ED4229E9A239E5B5C5A02C1EBE98A381DC56E1D4B56DEACDA3AC52B1088805476C01609A0A2373A4BCA788227172C4431B000005D855CA059B4E554D3DD2103CBC7854A12CDA368CE202873F5747450C4FD994898DAC5926765536662C81581AB4DB18E9763CD5A747659440C9A33EAC713CF907BA0D5A875B90882DE31B5DF825F337B46451705658915630035724C127C9C4B48572951770241993F777145573BC70125D35F1B03A121D09BA4388889568BA109F04617360826AD48F2765944232B1CF636FDF3C39C40AB87B4B50BFFC1019EB0FECC35CF7416DDB3146E275CC7AE209269A7330977E9DBA9CAF79C99E30B8880525CAAA84401CBDE7CCC0FDA4B250B7A2A651B3AFC123EFF52EEC55650029AF651B2014F4669DE319435B7DBEDACC173C3DD1F3A8597B80C9C3869D7389398A2404E790C9463F2634CC7351BAC9D74B62B73E7E54CBBB3AB235C7C1CE298C0C0369DE33224AB7B03517856E43CEF2D39F1D325D1E221998C53631D32A57A880F24476A7E89F8C1B2D1C49759C322E993CC7EFFB2BAB738F2648BD8133208EF26FFCAC76393714859CCCE0515D4A7192DED6AE5E828BE6653B05CACF0DF1B4816A972592089FF88FA421A490CA13C6789639C909C4DB18EE43A01989C51B6005ED2548AE24AC8CEC10BDA7649E6C9359C45BF0EA0D39F25BB1AB3C3B5B88CDA24CAA8C7C7106616BA05DA6727896D2A895835C9B83654B358E0D4728FEC8A150B39283E345F3E06B4680BC632009EB85ADB811277926662E531DB27B3CA60843A6370C304C1DD21A94AED90C3663C0948BC12F0A32AF533866F5931D5C74423246C16AA4F01808D06A6D50444EF8A3171AC641E9417E2E025390CAAFF16C6703680951B1A0E5ABCEB8FCA9830C9CE1AA08D5803280F31DE3CABC923B5A1A7C4854D841729194D3685C03F975A72440B5FA01B11868A48BCB73794C83644D1D39B9664C432C7B3BC311703EC01D268A34A8A1B3DC79B9AE07B8CD133B7D4BABA7F39B4088043E4A35FCD08A9EF141B78CB1F64841EBF894827BBE1EC47509817BA27CB42222272A00A633E1B2AB344BD3778E4A579AC7D64A32E2356B1822C1334FA0E6ACB05798F63192EE20629106130A1AC330C6CF0200908FB37184740E5CAA5AD44067AC7930F696BC9226235D212D71F57FFC2C8C185C1F3D717271022F2D256963DBAC5C5A1404A71E3546695EB27D73221892B5BFEF114D6F88415875C013F16E48D3CDB68C2000A39A45263504E0A7554386D68A4D3992C9F6196015066D3B8282E8D3398D2B5F62D7AF54698418862DB3A84286F142A8CB44BE011E0F2594D161611CB335BDB018D9E58CC71A363B29439D54CC6B293AF33B0DBBCB80C7797819A96C1316A783F60F987A3FBE1ACF80F22F610037D17247122C4AE2B2214638205328C43FD4BEBCE93D47C02B84E1CDEE7CB48805396C24410D71CED4805F36A105B05C6564EC3450654CC0A12E62F7C0DA79496FF2BC97B7B4809AA30D577A2F3428E48220239B1B97D9278DD26D93D186628812FC697D961442879AB64B4BA0BE3C46F5E55C13222058B407C1694979897CA0615E8DE05D85D3532060076ACAFC8E0AADD8CA7406C7BB316ABFDE1BCDD1662D5680B483287BBD3E61A91839CCA9E761429186176B7BC64034AD43F16F65E97B2DAF2EA1F1011C4BD04208E9E90B9C2BBE2D8B96A1565CD1163966F5337E4A", + "ek" : "D2F1F306E2F7E78510BF6B6C55AD871FF5BF714BC49E4B0A9032E82E5D0BDFA4A852C9ABC43175E4192C5F05600E3869A373572C0246AF101A8AE09402E8E82FE9FC4F9DA1A42CDD1F372517651FCCFC6FFBF24ED58B70B289F51A5704EB7F3EA5682A2224F139E713CBEA19A21F006669EAB71B5B62438BEF5A7F8E2F95DC7F2544AAB579B479CC16F55FFAD51F619854BDEE72A6CA256ED3C41A2C48AA97A9592337844E645268DF8DF6CF9278CB8572CE5F042D0C5E7434F75A7636DE8986AA3398DFA5D771FA5989EA61C0F9EFA5112BCAAB7CC2E7FBD0B29299CE5BA8026787F0BAC50F5DDF23DDAE918D5D4B11204158B0A44B16C3E67098A4C7730A674177453ABEB837CA147AF29FAB707090A8323C7A0A6B56AFF9205A43CE54A42965B1394C5CA1F2D7E3015AB47D476600E8F064DFCD7DFBF9999E8B8E1CDA1F2C5F8573A2FEFFD096408A92D6091174482EA4E081E4DEF33E3A26FB44F278BDFFF03CAED04B7AD0BD0F6D50E1EB5FE117E5284713E660D54974BBEFDB7AD9FE6174961AE3C8C6D435F2C6D057F67B5BEE76B8D3B1DCF8C78BF3914D6B3E11FFDA5F7B8CC76BDDCDE4EB1153691D29187E0A298BA246F4ECC048F7B80412B216EA795ED58ED0F86B8FBC88C67CBEC782BAD2A270A73527DE5397F56F10CC9A341F9D407B7732BAFC125E524531A20C322D470A6B0064B023D8EDDF18B80A1DAD9CFF58147C7D8C1A5974E3D6F58ED796038826A63588F08AC0CE12CAC3C2D6CB1C51E0A8093EF376AE2E2D3F2CD0EA0EA817F0094EF78CF3FF6B70C8CD80D807F3914847E7927E56550206C071771D26378247FE620F38A8E7A64C294938164241022E4955482D4466F321CD4DE02594CA24C3E56DD8CDD02B9677D107F73F990C91FDCB277DC4837B2B92606FBDEF62EE546A27787B1F6AC50A6BE6CEBF804D43D76D0C31897BF74B71B37FAE2C6EB74CB4F4AE0C8C914B4C8EA1D5619DB7B77223AA92AE199B1DE0F40B7F8CF122102825FC9E96F0C7D3F54DA7B6928218B6F47B710E2D4FD6F5A8B3D1287C8AF8790C8CE56DAC28C4CE430A0279E9ECD36F24861E1327AB9D47D08D7EA212C8FD922F25D63FF2990E9CF2AB8350900FCF9C2E9324A34746F7AC1B95B10AFC2BA33B0C395559747F3C81B5A1D009B2D88C5E017CD49A5C0F3364BC1115492B543ECAE476ABF077163651A373D06733876A1FE89CC938301543656EF8874900E3BBFC3B2FA8E4C4B78815E320C820A4615E08CC0B104B29886BD103576C4DE85EDFC8B4823464236FFA22906D2190DFAAC8EBD75B1FD8B1002B7E9702B9F459203F8BF5B63D1FF966E54BE4C01A885BB8995D2A4B977DEF567F2D516639EC6C47DC19F0D5473017FEE21BCFE2C09038EB1BB8B79443D9F443C56396DCC15EC3588D4C5A17EAC5D8E257884AEB8475562F8CBAE47C91B61B3F0935E16C99563606ED8393F7A9FB5BE034B4117C8365AC5BC7DD6575FEF9F124085CD89B9FB98B52005266E7760487270BC2415ED6AB46E0E20D25", + "k" : "EA0B5BBE658FAEC247E80C4BEFD85D60EC65F850D4F8DB579B8AE4A834A117BE", +}, +{ + "rngSeed" : "A229218B0D51F58D915DF549901548FB0722F352C7470900E7E4D8399205764A319BBDDBD06C00E8C5932722EE5A404D", + "pk" : "697588A4004634FC1C77215F0677879AAB3E63B51AE7436C5B47370E226EB4AC15DD0281EC65C56B83B60AC42DE17B1374D1680B76460E294D841C1062638CC003D043A26307C08025A594FA3676DF03C87789A4499575948B2574F6931673936E971F2C79598A1B7B35D28103252B4DF98C47F6AFA057BD87B1CC516722FD72BAE0F437479C1EC6F68087453E23FB4381E5930E5A19FC9A267565B1DFC7AAB9C13441101E57D9A4A454A6D1249C3CDBA091113D0F1B257D0986F23B4FCEB35C95AB05E2911DFB2899398808582A6B1AA9950EAA9C87C8BDAE7372D46C2852E85C629C25E05A169900B24CFC0A68661B6D44C74C658AB8C00C756861BE79272339A60828B9F0B8A325850B41950F97849DECE714C494BA9BB09B74AC16138251363B52DC166F220623982C19EF565F80583B84D0B91267BA98B63AFA31160F65961181951019419FC0627CC48DE9D6B2C689969548641009CDC56B02A140BBC4A995A7F2593E0213CDD2CADBCCBCA41947FC8033BAA1754A8815AD52CC31940451F8A62DD6B39E22A6B0DB8A0F953C6CBCA43F9C1285315F59AB9980EBBF57C1457DD8361DA04E0EDA771CDB37A6A54C6A47719790976A957978E198446320AAA840E0F1C076260E75E9A92980891AA6245E003F1FD6363D0B6E5C73B476B77EF867A60B225A99A763D0EA80A4C61739875BCE5C0F361322450C93040B4D6C08120827B8026ACE0EC73302FB6824367AC89A0E7DF45B850618612ACE284C2DA4421689D8C7034113F9A1B2342736F5F11CFDD7AC7F8468075A4A2D7960DFBA9E264514A8D7C6D11C660CEC1EFE33C04B4681DCB31FBEA47247BC83C581B174B0CEDCF0BD0B7B622126CBE323986B75A407E416FC0032FA2398E504967ED021E993A955713A76365ADA810F9BEC7AD1A6929A466F08113CFD6919E014085D4148BE060EBC014FB1FA3A1FF70A3AD94BAAC7BE6C96BC0F28A021E39CC6BB8A6E16312255880A84778CBCA55F4173B2070D527357CAC69C22587208496AF1715711F76D5C185807A13B2C791B91F54B23AC8B66B71B3E211E55180FE7A1BB2BBA7F97DA8F82734EF777B7D2653E66E814ED7871DA35C95761A88A611BC383ADD9A329706212B9780EF5D53E933C99318AC47E26859F507BB50597C3AB1A252C77D22A817B402B80A63532F21A0F296C40BB8021732FA9DA01BC60BC662A0754914462689DE756A397E2384C2372130C5A6F05AE6C8B81EBC22125830F04D3740D2638D031A21F1653C4F664CD182B11887F4784C27954984AF251C923B5C2CA4F1777CB3EEB7A13C351C07C4F5562B4A8A477FD348BCB9B8E6BEC787C2340C02C0DCB236FE8D7C6EC8BC9D156B89BFBCBF4D0599838263AD5B90FC155051137D6800C898C8A50B82A4E3940BBD3BCDE2013889BC4F3A7022D7C49370AC8D826A3AEE946B79897BEA8512D8B899A8C17E439760B58859393A5C264B5F1549940914FE278A40B6C9A8304775BA30C8EE4CF234AC56862CA2E935691E426923973C32B4F2408CF63C99D7B2C5F0C5AADBBB9CB98B53F787431FA73542C5569E5F5CCF0E4A868CAC6529BBDE42A5F1881CE0A729E6A531B0C401D4979A7425BAA8B0392A8CA9374323DDF2794C237E38E45A43A5A34CCA2875D19217CE7547D2EBA6BCA", + "sk" : "000D8A738101A329832189BFAFFB213CC5789003528B06754014CB91A09B7625359B2CBE463B356E298C95A6A24646AD6114900034C83F19599BD0173846B93153AAF6F9C1E1E11D41692BF5146A48810AA89604BC2B09B32230C6C44F5A0A0086B7C688008702517B4D807BC34B8A23E968A8316DF5207F2788975F458CB0DB5A37C80BB2823270A3130C18BCF793147EE0A5B63A499FF28E3AE290974BA44E8730F4E56018073E0ED54924E38865BC076A809862470525D5C32B74C81D4CB95278705F01B6C6D098B951A7EED095EF386EB8D47F0D7984102872706B352C12119ADC1FDE40259F5450C36C4327D31F09EB589281A590F1131494B50264719A740C6D0B1C8F9AA6D281B8EDA923308B02DFDBB7C2451BF80A769C683F2FC02822838F6AE1CEA8D81AC91C53F53041952B82AEFC4122B24CC15B3A8CC2450860869FE622036512344132701B8043B387D37986482318C134AF38014CC075756838415E1A461CF0313B4907EE6753AD625EF593C99FC70B88587095E66C03044AF109BCEF59A3CACA13E027C2CF3B350D28C1610B9BEE0718EE44C223AB522AE57B532526F003345440CFEDD463A0FB1AC60A2C6BFC37C7EBA6A7667475D278C3A4B7C486B68F2157E9BB7646045A7AB452CDE7539C755E5FE390F0174153F1531D5737DA4383202103F6E01339255A04D04C83FA5119FA0F0C15C2C2D50E41D9BE98C66703903C73A05680F6C454676916D1C03DA6BB45482C588C6CBE57CEEEF924CAEC94FBD096CBD13528770995BC50D0BC02B24959F4D61DE3BB6DD7FA1A47DB7856D53C7623897A24ACAE7473439217D52A2EF34A3A6C793017D6B22A3845F8087589AC311D00BE84197A8BD6561FCB8472924AF6547CBC78395721C75538278579469CF38553E4066027A43D9584508C7FE8F87A7F122B484A1CB922B62609CFB48C7F3BAB00FD709097C87F5EF401CB9520B55CB021211B23131B2AC07EE9DA735B90A37A84747A26A0F0C7B28672BB4D3CC6E0F1C3EE1C418DCB26A663519907354D2BC106FB72A1607A0905886E292D3A77716590CA57B6459EE647906401E8B268D6E782F904BE442858FDE72513318C06D0715405229ADB7632B5BB2E9923D4FB49A5F7B995EC7B2C971B0BE3AEDB622CBFC344D9C9AB6536B323A68A0EC97B5BB491FBB0AC20F48873443707DA5B82D85F61C98F06626761A20436F20DD1E66D5E452874E9B1C6947ED270CAF85A9BE3D8250E539451F61B28014144BC184E7AB57FD496A1E3A9F2FC2BAFB02CD837AC91F61A3EC39E9892293A6A2BE5A91739C64418A173E02870F4845D3F56AE573C5DAA9387F78156C7D42D2A2C7A051964127BAD8B728FAD010FF0944DD6C2807B748D62492494B25BD32261115014D91BAEFB38A3FA06070646C71E5C6E07E64AED181EC46BC0FC4284630A038813834CE3467A0B4B615496B80681149262B833247CFA8F4B4C364833B074A467EB1623FE475AA1EB6734774995E99745D40C5C149FC91264B3149DDC2318B149C45944370CC222BAD6759454CC4AE66D30091297D6468F8734DCD43E3F078FA0955D69C90E0F97CA3DE54B2F38005E8296C52A27E51A1CBB69BC1C3CAD697588A4004634FC1C77215F0677879AAB3E63B51AE7436C5B47370E226EB4AC15DD0281EC65C56B83B60AC42DE17B1374D1680B76460E294D841C1062638CC003D043A26307C08025A594FA3676DF03C87789A4499575948B2574F6931673936E971F2C79598A1B7B35D28103252B4DF98C47F6AFA057BD87B1CC516722FD72BAE0F437479C1EC6F68087453E23FB4381E5930E5A19FC9A267565B1DFC7AAB9C13441101E57D9A4A454A6D1249C3CDBA091113D0F1B257D0986F23B4FCEB35C95AB05E2911DFB2899398808582A6B1AA9950EAA9C87C8BDAE7372D46C2852E85C629C25E05A169900B24CFC0A68661B6D44C74C658AB8C00C756861BE79272339A60828B9F0B8A325850B41950F97849DECE714C494BA9BB09B74AC16138251363B52DC166F220623982C19EF565F80583B84D0B91267BA98B63AFA31160F65961181951019419FC0627CC48DE9D6B2C689969548641009CDC56B02A140BBC4A995A7F2593E0213CDD2CADBCCBCA41947FC8033BAA1754A8815AD52CC31940451F8A62DD6B39E22A6B0DB8A0F953C6CBCA43F9C1285315F59AB9980EBBF57C1457DD8361DA04E0EDA771CDB37A6A54C6A47719790976A957978E198446320AAA840E0F1C076260E75E9A92980891AA6245E003F1FD6363D0B6E5C73B476B77EF867A60B225A99A763D0EA80A4C61739875BCE5C0F361322450C93040B4D6C08120827B8026ACE0EC73302FB6824367AC89A0E7DF45B850618612ACE284C2DA4421689D8C7034113F9A1B2342736F5F11CFDD7AC7F8468075A4A2D7960DFBA9E264514A8D7C6D11C660CEC1EFE33C04B4681DCB31FBEA47247BC83C581B174B0CEDCF0BD0B7B622126CBE323986B75A407E416FC0032FA2398E504967ED021E993A955713A76365ADA810F9BEC7AD1A6929A466F08113CFD6919E014085D4148BE060EBC014FB1FA3A1FF70A3AD94BAAC7BE6C96BC0F28A021E39CC6BB8A6E16312255880A84778CBCA55F4173B2070D527357CAC69C22587208496AF1715711F76D5C185807A13B2C791B91F54B23AC8B66B71B3E211E55180FE7A1BB2BBA7F97DA8F82734EF777B7D2653E66E814ED7871DA35C95761A88A611BC383ADD9A329706212B9780EF5D53E933C99318AC47E26859F507BB50597C3AB1A252C77D22A817B402B80A63532F21A0F296C40BB8021732FA9DA01BC60BC662A0754914462689DE756A397E2384C2372130C5A6F05AE6C8B81EBC22125830F04D3740D2638D031A21F1653C4F664CD182B11887F4784C27954984AF251C923B5C2CA4F1777CB3EEB7A13C351C07C4F5562B4A8A477FD348BCB9B8E6BEC787C2340C02C0DCB236FE8D7C6EC8BC9D156B89BFBCBF4D0599838263AD5B90FC155051137D6800C898C8A50B82A4E3940BBD3BCDE2013889BC4F3A7022D7C49370AC8D826A3AEE946B79897BEA8512D8B899A8C17E439760B58859393A5C264B5F1549940914FE278A40B6C9A8304775BA30C8EE4CF234AC56862CA2E935691E426923973C32B4F2408CF63C99D7B2C5F0C5AADBBB9CB98B53F787431FA73542C5569E5F5CCF0E4A868CAC6529BBDE42A5F1881CE0A729E6A531B0C401D4979A7425BAA8B0392A8CA9374323DDF2794C237E38E45A43A5A34CCA2875D19217CE7547D2EBA6BCA38635CEC71B814AAAC223F748D13158DBE8EB902D9125FDC22202C4D59251CBC5C2478CDC8D59AB164856623D53B9E60CF0AA8214CB64E674140BFD6DE9FDFAF", + "ek" : "A504BC5E4623D6B25E9EEB70B0B02B81B53CB52B864F8080A038DCCB9EE4E7CA2E9390DE807C7F862FC520554BA94F3FA9E295D7868F61C3133CADAB5421370A6B4FB660FC31C0831353A906511425237372FD409B2515E6ECC8C06149B3EB4AE9C663CA3786B51CC0D26ED4D0C1DF8AF70F09CAB6D310224AA8CBDA7B5456DB62491F41F2CD4B938665D960FD41BCED52E163AC694679210FC8DE5C238AAF497A05259FCDE9D821435082E5A8658018880B8018A71E2F912A75275ED672F3296ED7CB42F11F77C80BB78920EEB4198E2678D9567683C9A8676E22C4877F516E7358F70303FD3BAAFCDEE8FDF796E91BA6934DB2A31738234CA246D5D5E358AB72CDEE1C76F5D8234CE4B4689BF395B3B67978A5E4F8531F03695D7FA0BD946158AC353E15616467DAC9D0EDFF7BBFCB1644ACB3F938C18C7F8C1595B7EC9D26B3A66DCBCE7F3E75D3D91676D7B0592B27E3673557890299FE748BB1D865CDF0F172A5641D26EE5AB35E5ABD2AFFAA31E9305C8100F9B28EFB070906A0BC41CCD71658A703962D674300F2CB2CB931092C9A442556C20B907D9BE17F755B5A297146F3509E935E1B4D38872034A13B6727F4BB5BBBE89272F2D2888F3C030D425F888783798AFD2D5CE7C49D7BA4172EB7A1888A43E77F16A8FF5ECEC4B0EFBD28E2FD45C7A519347330ED50997DC0AB92E1D98622749D7EA83BE7933675C738C21C394875CB52834DCF0A28ACA9C7313818E954B5527859CC375F6F41430C43465CCA42FAC28295E48C33299CDC4B17AC90719B03B454B983A2933D1A4A691BF580345874550266BC8855241877769F6C25E62F0BA6317E0D65C55F293F06E1AC36AE8AC35270C9C023223971385FE02AEC47CDC83CB475667BC2A2C17B652EFEDDDC1295792489189013764CDD4F4C09C4B5D8FEE7154405B7C8F223A0761F284A41294B88CF68775AEE9F5D0A9591AED1FE76440056F43C8AF489856E0A57EF16D8424C4805F54164F23AEEE88523203AD155159BE3E7250E42BDD3911538EBD6A9D0A4490F0E777858627E4A27E5FB271430108351EB1D7506C882F0DE970098670F631BD6EB502AEC7DBE8B0C09372B6222D95D4EC1A1F222348A4FAD87E24F003B7C14F074E7D02C0D1084E4669B894EA70550C52ED71D4C431DC940E97DA489B969ADA88FF65075E4BF0FB3D28F7D58014ED99DB14E61D54E7E7AF3D17A1DDE72B317C07FD9CAE6D4CDDF9295C7498808A56D87A217364B84B110D4CFD8CDEA8F4577E682C3F5701E3E7B777C97F4AD847EA78F4A65F13150704C45E0C6D2EC6B90AB24F7BE2E830526757D6FD4A9B91FC14990D6E0656785E9454844C1FD32E1701B5B1D2FAC883B8C4005DF6E88CA20EEAF0EDF45A4D611B0B007F29F85C88C3B302B8CBCA061966B1F4B189056C2DFD19EB99C8345B0D10DE3005B628220C729FEA06720BEDAC1B8DEBA6544873DBF3C24F552AAC901BA5ED4E03C0433DF3DFA84FBCE5F413AF3FFE766A0815EC09A9595FFEC7E4ED4E0FD52EBF3", + "k" : "8483CBD7DF17C2BA72C4616C33DC5D1E7023589B9156CA0BE42117AB0542DF90", +}, +{ + "rngSeed" : "6960F21C7350DCF41B4770C551DC8692D8BA2C0B6E162C589166FF22E7A1AC0F94C2F48504A5F7EB0DA094DF427BC98A", + "pk" : "BAFCC65109CD59F7084E05CFABE4515255CCB724B3388239CE1BA8C631C1E8C0B444BAAA6AC481DB8B4D670AB65CA27F33A92A11C48F6AC038F0914637B749D8B962C00AC8AB0C019C92960EC3817F34840AA7B63B19826A12234A81C9FAA8995D28C4D4C44A0FD2C51720CACC8751BF6C31CAF045A79C6F9B15C2D406C11FC3B5DF6638E1B83164175DCA5A1260A88C74B4C2432A9B76C39D43597CE2E3AD1797C25F967868B66BCEE9B6A4D1B53FD09540220C7CA75943C52E3D4A124453499C681C1FBA4DFE80919BD9467BCC0AB34B7DB6012B18B3CC4C679E325B82518BAF5123C88786745C4A0600A302A2A367B717C3DCB4C32AEB4770FC93E0213AA54B2C6A37A326F121D907278203724CEB6CAD8717FA3A2106217864274E6220061620052799BA22675DB36863B2A447E5A62B3D2511FFC83BB34CAB6CF7356A27C29798C00CB32BBE1023FE1221313CC7AD59144FBB98D0182BF0183B44990DA81016E2995206F2B0AF19C8E21B1AFE8C98D608C0C7E52075137CAF22C69DEC4E0F1763C8BBA263898B30946663D84B5E0808E6AB9A6DF970D2568303704D4C651C912B7297A89534E324FAE62628580BECC3A2051CCA9D5757D5E53FF8FC242E42B2ADB06CB2547296EC8431FA6EB8F7384FA559F9284D528761F9A23E85A0BBB3E57B7A876D2D4934D33838906606E6DA9A311C15CBA30F39D05236892462824BC4A4B4D6B343E3594FD9D68972D99EB26538F9EB1FA7F0718AABCD5DFA5A670B0F8CD595EF7A082ABB518FA34891A4ADE983877A333E956BBEC9A82A19650866981B8B8C406E22ABD784AAC085B6EA553E30409ED6B39B4F367AE45B9FE109C6ECB51F23D2A755CAA347AA95E656CF45A15E9438B61031717B3551E9E3020CCC330F254E82D89B5E4839A9F8AE267B9365AA228786A371859D3847AE68713DF98768A1C792ADBA39BD2359198224376CB9C011777EFC4AAE1C3D179583AB0952BCB5B1E8577A5C476189D3301BF87FD8A1163B81BDB4A8368934BA4867AE4DD03D40C2CB5F974A5C36A8D699546D831095E7B354490838A40900521DA4A00D2FD7117E1060DFD363593AC11BD31FFCC08C1EB8806F249719751EA3EB328D3A36590919C2317429D0486266968CBC6973D483015B77EEC543B7F971523589655732BDD1783365761D937266A420EF3B849A630AB5A4003FF09C116C1037F4576C58ADECB5A5E0899892854B8971C9B76685164A14BC5C8B9BF212C6C7AB15B35E25A586E465AC05F3911DA7063208C3DF46923622402559CA963A39F003AC0334AB19D02ED58C990AD983318B33429ACDC637A8393082684C517B75194506BBEB9686136A3C8A284C852CA747FB709D4533D133B5798B50C1E59F9E99781FCA9F447340705C6CB7E2231E257F95D681805B8CDCF3147804405F30B4EE63C1AA9C367EABC3FC606306616EEFE91026507780E6339B209CFB7A227596957B136E1CBBCE15FB9A6FD9BC798C40F0CCB7651B150D281D78B3508939BA836AB719CC19C61860BD3C624827AC26639C05A39C88A1873204175BF297561723A16375DBA51947B83E46E84899377411B2BF8B743CF8DC23FD2CA07D11AEEC1990C42A7321AC6F01CD866F8719EF21BCC0E02346FC5D8BA3D3E7F1FCB52D37551212D647", + "sk" : "4B390D378CBD58818696F39433E9A34A46109FE98B4E806A306119E2110A5AD3993F7646213C0B27DCA918E624EB6090930BAEC770A838A501E8979C1E210F71DC4674999CB8B92CF0AB1011AA67CE5039446957BE38A16DD683795621FDE5AC77E94C07572FB2D95CD0169803DB5698E47A6EF3C3B11766F095496AE846870A68D34B9032527902760CA97B913C42490486063F0AB27AFA8B92B33D88FB6653DC6FFB3B55B3A9B5D3A9B5F89916A727439561AFD8E172F5313FFEBAB7587649D77563DF970A4030ACA239B225C78177058C9EA3CC388A3F5F2732E1DC00C11B936E65833CC90F5597266E29846BA70AE0239820E47426B8A092792334F390E399469EF13FF2301F9AC94EB42386FF882A3BE8BA23F473EBB271AB6C52E5B26C5EDA203C0B6418250C8E2216285CC78C70A386F1935EC41740A114F5A32EF703B4A4540143165337F5BCB42743E574B93D62AE23081E2DD7C51E923FF1E25F4734395AD0AE016A6C45F8096BF2AAD933027D1594D98175C91143E320C3122BCF16F10F7EBB251101882AEB94D6B8CF893B7C05373CC9BB3EE58B148D1124183C05C116B6C178A2C7756700E15B8108144F5024C9CA04A3DC2E476591A7C79970274F112C210D00C198860202A408453985A3D9B5488BC61F4C8C93741E6E733E1358605C6A2E30D7075008CD5297A5EF5A18081143D5907D88284FF284804B276A193352AD3BA5463383A024908FC05578D0521D57BBF7D03CECAA93EA1326582307725C62DC79B7E9B34BACD94BA9608463C72F68DC0EEEF10BC3C52E9F295A65F460AD368092D3BBCB2C9F9E1B2783737E1C3B0EC0442AA7897FFC75471B18730399257F019FE5D73AFBCCA9B83932C94360612B297F3A84EFE90278940E98EA2E746857AC73ADEDB6B4226667DC779285C6987CEB03EC14A00302444DDC02E76AA6D95392053B176258546FD0959C8A6D969CACBB809115B339D6A517578502A46B833F84712DFC01B7C35776595AD656059C4CBE72E637CA5C95572952FBC772463042D9ECC194F93C8B577A220116E7E58BBE5276A90324C5492DBE3781B623585A22A77B2CCA935009EAC03FF1947FC00562F1561457F0220A764B7D0C06AE3A4CAB90276581445AD7BB07C817F4E3A05613541967388C3A1A784642C9952E8376C57D82A16BC98ACB908521A366ADF18DD95569AF860994858236F5BDC7AB9655A95D28A956049C7365C84C34F33AB305A35FE3117A563B1947658988650E3C65A6551660650B33217295E79FAD0BB567054B2C0C1FE5E3CA560B3A565A58D9054FCB171AFEEC538A1C01781870B19C63A49243FCD9B384635AFF5B1642036220F15C3414A9C2F82DA81B6E625C1944109A6A1AC06A07A9B8C85F86C043BBF62AF18C05C5EB3BBBB3BE723A8E04B9A1F875C0D645412EB8C51FB1C305C2447628C2F01B3B6A6A89D8C849F48832F7A9662B8C476BC426F54B509A8037A52023A5D02FD10394CEE11AA1D5464AC41CE6961174A528E2E3677032CE03B79CE5620A3DFB3291E7BCA9C249C27232BB535DB78918C2A56303090E98C1503D211D95221E278764479A1EACD92E5C50B9D1A3AA9C547194275630CB7644BB5DBAFCC65109CD59F7084E05CFABE4515255CCB724B3388239CE1BA8C631C1E8C0B444BAAA6AC481DB8B4D670AB65CA27F33A92A11C48F6AC038F0914637B749D8B962C00AC8AB0C019C92960EC3817F34840AA7B63B19826A12234A81C9FAA8995D28C4D4C44A0FD2C51720CACC8751BF6C31CAF045A79C6F9B15C2D406C11FC3B5DF6638E1B83164175DCA5A1260A88C74B4C2432A9B76C39D43597CE2E3AD1797C25F967868B66BCEE9B6A4D1B53FD09540220C7CA75943C52E3D4A124453499C681C1FBA4DFE80919BD9467BCC0AB34B7DB6012B18B3CC4C679E325B82518BAF5123C88786745C4A0600A302A2A367B717C3DCB4C32AEB4770FC93E0213AA54B2C6A37A326F121D907278203724CEB6CAD8717FA3A2106217864274E6220061620052799BA22675DB36863B2A447E5A62B3D2511FFC83BB34CAB6CF7356A27C29798C00CB32BBE1023FE1221313CC7AD59144FBB98D0182BF0183B44990DA81016E2995206F2B0AF19C8E21B1AFE8C98D608C0C7E52075137CAF22C69DEC4E0F1763C8BBA263898B30946663D84B5E0808E6AB9A6DF970D2568303704D4C651C912B7297A89534E324FAE62628580BECC3A2051CCA9D5757D5E53FF8FC242E42B2ADB06CB2547296EC8431FA6EB8F7384FA559F9284D528761F9A23E85A0BBB3E57B7A876D2D4934D33838906606E6DA9A311C15CBA30F39D05236892462824BC4A4B4D6B343E3594FD9D68972D99EB26538F9EB1FA7F0718AABCD5DFA5A670B0F8CD595EF7A082ABB518FA34891A4ADE983877A333E956BBEC9A82A19650866981B8B8C406E22ABD784AAC085B6EA553E30409ED6B39B4F367AE45B9FE109C6ECB51F23D2A755CAA347AA95E656CF45A15E9438B61031717B3551E9E3020CCC330F254E82D89B5E4839A9F8AE267B9365AA228786A371859D3847AE68713DF98768A1C792ADBA39BD2359198224376CB9C011777EFC4AAE1C3D179583AB0952BCB5B1E8577A5C476189D3301BF87FD8A1163B81BDB4A8368934BA4867AE4DD03D40C2CB5F974A5C36A8D699546D831095E7B354490838A40900521DA4A00D2FD7117E1060DFD363593AC11BD31FFCC08C1EB8806F249719751EA3EB328D3A36590919C2317429D0486266968CBC6973D483015B77EEC543B7F971523589655732BDD1783365761D937266A420EF3B849A630AB5A4003FF09C116C1037F4576C58ADECB5A5E0899892854B8971C9B76685164A14BC5C8B9BF212C6C7AB15B35E25A586E465AC05F3911DA7063208C3DF46923622402559CA963A39F003AC0334AB19D02ED58C990AD983318B33429ACDC637A8393082684C517B75194506BBEB9686136A3C8A284C852CA747FB709D4533D133B5798B50C1E59F9E99781FCA9F447340705C6CB7E2231E257F95D681805B8CDCF3147804405F30B4EE63C1AA9C367EABC3FC606306616EEFE91026507780E6339B209CFB7A227596957B136E1CBBCE15FB9A6FD9BC798C40F0CCB7651B150D281D78B3508939BA836AB719CC19C61860BD3C624827AC26639C05A39C88A1873204175BF297561723A16375DBA51947B83E46E84899377411B2BF8B743CF8DC23FD2CA07D11AEEC1990C42A7321AC6F01CD866F8719EF21BCC0E02346FC5D8BA3D3E7F1FCB52D37551212D647AF97825A77F2F4B6A45EC1A579F9F83E89C025D8D6876DB26874F3834860429388E66590B5B102B223291CC78119BB94E799E37B95B7BEF0337E6A572284B9FB", + "ek" : "9C5584CDD3F9A9445FB2E7F1F9192190112ABAFD63B333E6D5C83F5411039A836CB97DF0B68598B2D8DDF9AB031F33E8930FDE369E7ED344748F8E613779F9D69ABED49E811BF1D4B23033CEB9A66DFBA90EC9F356FD30FE6CDFC8214F9C2C0154CFC60F1FA62892E7D1CCFFD258A33BBE324263EAE5139C7DA59EED02583BED2F77ECBAAEFB83E96B9A59B264FBAB2E177C9A793A84F14C57436FABC798EC2ED2593DB68497AB143674991BEB050FF57003B01C26F3B3C96FB89BB36BF9112B2A01BD1B14D257C233F7CC61FA0A73EA66B8FC933D444B94691013BA6ED6966C1AC0E46971279CF12878A04486279EBF236703D783EC8612A8BDE377069E5ACBA9E0745B3B6F92957A9CF84572CD2CA4F0CA8ACEBBBE04F8149F29CFF07F7C4CFA2CEFFEA2E7C34EDBB4564F6730C8846A5C4D8E1F915EFEB1ACAA02DD53CD1E70F588BDC96BC5EBEFBE2464E47D860B932301DC1EDAAEFCCFDD34298325EE10C258D26674052D38BC7D680589C10918A652A97BF2F43C20A7B2817BE8FF153E5C52B0F0F5C7F3A625AC27A668D8653636ADBDC3D6196FB2932E06944A4D4321D952D7EA106A5C57BEC5FF44DAC861E92585691DCE4A69762EDB8E0FD38582908A8C915E480854A9CDB264A754DA45F5223B423ECD01C73B9194A36FCA8B40201E8BCC663FD9CCC3C4D5E4274EE4D38D930BECF539F5E382D9A48AA04F9BE10D54BB8BD6996CF492EEC0C19E990A37C123EF2EF274C9D07CFAB9C1BE74B3A8C67D72DF70651F4E387B2C736A93EBCE06FBE684EE30F564FE29602102516DB0B6BA5F2DE10B8C12A928413D76CECE8A4959EEAB92D3239D46DA4867309D108A6E1AE79A151FE2231487ECF7E42E56620C02B65B934036CE63506820B28984F00600444A9FDF04BCCB6B0415314BE6F42BE47F9E6CB9D7B488E62A8A59699004F3DCAA3AF5E6B5050513D61AD166D57DB3EF1FF9A5E4824121212556CCA41A799D31BF2597FAA588B60A99E36D9108E6D33220D3134333747DE8557FE9CF74DF8D110C7BDEA81A1052CF9AE476D15DB3BB0EBABE04FD00ADF2D37A6F84852F630971949AF7342D1A412BE0F6FE2BBBB012CC4740FE194A685DBB6CC192A39119E87DDA3E6EBE8B352AB2FFA9AF2EA8A256275EF7A94D3855A0CCFC715057A5EB01B17833A75C8B24C16624ADA81C128A323123A8D5296334860DE0AA3CAE18E784E933752C53EBF594F1C2F5861AA8EB33B7DEF1B94E49065C37D189437870C650B0580EFAC57590DB6AAC38FA9814BC0BBE44F84FCA064A44A969DE8CF5BDC37D24891F33B58D9AC411F33783CEDAF7A4DF71FE4DE77C8CB63A729D16D9D1D227B7AA68F7D990F0062C3E08ED98409957C0A91E637812E413E5E14E3E07C92E045C9D803C7A0D1CBEA3C564BFDCC430297579ABC747A8F707F6A6746E279952B4B9A0E22984FBD509A2714C9918E2E88F916012CF05F6591D7FFA264C10C461DC4CC5E784F860D2AAB503AF7F5A515D4A9F846CCCDC14C1F61530A04FEA5A8B30", + "k" : "7437DCD29D1ACED3223E62B257C732893B797E915A6123E5D862E8FD1A01226F", +}, +{ + "rngSeed" : "53DF46012CAD4A745B7A3C06E18CA95E0B839FD8161E3025749A0887549EB0ED6A44EEEA08BD6060D6509DBF7E9DC864", + "pk" : "E180A227AB843CD49D4970AF3B68C255512920773ABAE9A2E402B154B8159B63B4885736E63632313B2F99DB66FD4307D411A66871C8EC859807205535D907C3C6541B283824861738ACCE081A14E8047A63CBA2F42C71B23157C85A7763D3CEBFE93AA7FA0A083284ECB7C4DC16C8119B5D90546A461A5B744B1084F120BEE2B548801C381A9D561BB0C5C35336601D1CDC310A610C8DF78DE62477A6F26DBA6038AD04371913B831C326C0537CAE530469292CE41C40A81B92A5C04D69EB0303B4B38A5CC45FD2B0EE90CFF0B81474D0406C8B34B34C1EFB596A704CA4893949614762A30C54846023DC3A345268CE55C0BE97139F5F733664A58B67656EA211A87DE01F9CD902A9295355D13A15BC044FDC77C4C53F671A1438E283371B5DB5F82FB0D789E877B6820771F0EBC64DA864A01CAFF73C4A42B5416BB043E29C7B2574C6E214A352F4401D786B4D5351A2559B87AB00BA84511BAC1A099B1B33E8CD45DA078D447B23326574379DD3D32DDB22C6A4037FDA719FB104C85F0264BA4A9ED0287A31A2AF6D58291676A37C434ECB234E4E1C648FA0760DA57ABE45703E677FEFD03687415132D03252291F02F3901D20427904511F9C11A7F07041302033054605E97FB719A2F70648A2C30A0B42899B195EA8E6CC96610943C3276698A34A61893BA8770C69CD55F1BC0F00CA0E04177D0469C4833FCC23A6ED339ACAA91B6E081692340F53CAC66AF5A6BCC2391729CE4E1C88D5C2610B00454FA21E8FAA6487022F19F2C81D5452D5170255108BEAF3979FF9ABC2E04C8E3669C6AAB80E2B6464644AE2189C81FC92D50CC56039CF5DE2325AE5163A1B63652222AAB35E17430D16477537F867BA4CA0E9B1C83C61A562C6822E61BB1450426E9716A77C1934AB17EC69563B8299E6AB371D996849C8CF7A84CA1A9BB654E1AB20A81D65314595A52BA18076F8712532A81B00E19E8734968F87C03FA4763208862D9A3CA648582482BF0D5441FDB7C84AB237D9F8628ED2001A501339682F9B8AAF6606344B95342FA62E782C1D9560B6AD55AA332C1FD533A74D026A9C9757F0E91BFC96545D0B6477F31F95840FF0A4127B16C32B635471480523F93017577513EA96159AC60BE179D3A09C5CCB6DF44174DE866CD7548339D314D160718F262EDF32382915197BC2AC6E3A4F77229E22DACBDFECBE3F4B72AC6BC9D9354E7ED2C31CE7ACD7F3A2C8B9ABEEC00613B1600C8992376B73F8C245AC9841EA06409454B48D8C3A152BB8D6168A3FA6423373651CAA7AECF0A5971641BD66897E5991E793343B5190BAC3107EEAABC71BC34788A345BCB9AD8A45A50A1DBDB1846BB76205B06E8AEB692B4200A596524954963F01C946131704F6B181D7781772CA6365824F6C6C22A1AF3328A2C8978EA8D7C38F6A00F7A6B3A50C2507F103F72420BDF98DC19AACE30B792851142D8B43319C93CCFA966D71CFF9352F25FCA9E8A3064CD96E42E9A2959C128FD532902419B81972838532CDFC08F34541459CC68955C9C2A431BA5126C9BC08039CA45533AD8108BEBA49BF8D56BD44433FE12A6C55C41F3CC20560B28CF050CC1F195C5E817D23D95E105A13555923CC21B13C9E46D34182974451BD97B6A3DA440DE6E5BBED681D6EEA2C6822B361019AFC", + "sk" : "5E49938E23A5C65C89D4C40917379CD2A5B5D32881A6D68C28B48A2E356DE63896BAD68ACD4A474CFC288113AFB2418173AC4B1C3255136C73A00C7128B59A50042BF4A3AEF9015FDF0108B01CB701D2BF6597637227604841651E3A964326A23B038D0AF855F307413236A3EF95B4433A0164BA6BB27A858ED9B22A31234480B7E559AE9194AEE9945DAD45B0A5E85BB486962CB19D8B52C7D4B473F5F566F2779CCD79739649665820BC0E8307457B9AF5844870CA580DE2394FB092EDF512310B970F5377FB80118FDA8517B5B16E212447E16E3A5A5DE7587FF3B271533803B9282901192FB20CB298D666CEA3C5386BC658C5C1DE9673857A3091A413CC69B2C8E46382AC97A13A9F31C1A47F0B6F898A84DC0278BAB1A7863746C03576231B59AD2610E79A933661B6F23C63ED9404DE06791C087F42ABB7C088AD15C54AB23C78305826CBF263D441BF62E23180A79AE14A1A1FB31E115B02A974CA7025AD0C634067D4082A835BD274A44A218FA4642CAAF1C4D108570C13BC3137468A6037A0709F0C0069443C1E7FB2822A282D08B030539628448C5B0396CDB76C89BA0C13F8AB2902D44190A0342ED5ACC88B72C3BAAF18880561F95196F56889F1854B4CC348D6019F4A5036123C1650332FE47115105A085C2591C952B35289EFAA90D55C6C888868C20075291435175C086EDC5D07B01E4441B8B3867B8A93CC9ED07AD71B387EA3363064194363B77FD106CA5C13F6B585980664B2A036B730CA50610798E3B14D176E28066719581821272157D81EA550992BD76875C22736D7163B01B6E353CDFE05B63BF5AE02A68C3E105731D8AF5DD90981A02715E061F8D3B94448115247BD23137CFC165DCD4C26D065A28B84CBDF4B17B1A9A27046898C529BA42217502ABBAFD68BF6990D2D1064A7AABD89075891678E2610120FECA2CE72C0E1D8BE55F4C0EBF7CB565B492D9A2370E93482201F25B5AD667B0B90FB31DC8024E4123BE6733217488788980F5216116A702BD8C1CA18D0B419B785961424F6289F7A55A211615398575755B8535FB0ABA1491F00517863C41F4FA1871DAB1BA42599E8E54E8F4C6A54E20F5125C595E2099439B0402794B9FA3A632B4C789C9CD4613776218FCF066C22E4B12DBC90FF0B4D08CB7032C07603557EF6DBCEEDABCA671B7B07A2CD1DF6A89EA6A7DBA65E145B9515068A15E7053D5A4B1323CB75A8AD0D6BA3885A7E77460CF19637C1B6C330725588091EC1F158484C6EBFE43B4E01CB5424BCE33758EE10A438C0621C9217979C958AE89591F69D54C4A71719CD4AA76DA6AC4EE4B472AFE45412718E65A5807D452491E1A0788A570BB3723D438362F50C2B26B19DC696F492452AD13501C3BFC81766DCCB5034CCC29D4C152499000AA458C961AA17D74CB5819A84135CBF8181832748917C951A468FE70C08C1333DE71B64B7AB158255C20AA7B2CA8A912F898574568E27691F8B517425C1BE2BF183401CC2AFE08FA65A2A1135A5DFB9A86DD3985351B61DE0228C112A35A889EAB8A57273258A471551E15AD23328C6D00A3F78A1CB9C836E304FFEC75EE1F0927962B642EC0694E50963A246D97A240639A611C414E180A227AB843CD49D4970AF3B68C255512920773ABAE9A2E402B154B8159B63B4885736E63632313B2F99DB66FD4307D411A66871C8EC859807205535D907C3C6541B283824861738ACCE081A14E8047A63CBA2F42C71B23157C85A7763D3CEBFE93AA7FA0A083284ECB7C4DC16C8119B5D90546A461A5B744B1084F120BEE2B548801C381A9D561BB0C5C35336601D1CDC310A610C8DF78DE62477A6F26DBA6038AD04371913B831C326C0537CAE530469292CE41C40A81B92A5C04D69EB0303B4B38A5CC45FD2B0EE90CFF0B81474D0406C8B34B34C1EFB596A704CA4893949614762A30C54846023DC3A345268CE55C0BE97139F5F733664A58B67656EA211A87DE01F9CD902A9295355D13A15BC044FDC77C4C53F671A1438E283371B5DB5F82FB0D789E877B6820771F0EBC64DA864A01CAFF73C4A42B5416BB043E29C7B2574C6E214A352F4401D786B4D5351A2559B87AB00BA84511BAC1A099B1B33E8CD45DA078D447B23326574379DD3D32DDB22C6A4037FDA719FB104C85F0264BA4A9ED0287A31A2AF6D58291676A37C434ECB234E4E1C648FA0760DA57ABE45703E677FEFD03687415132D03252291F02F3901D20427904511F9C11A7F07041302033054605E97FB719A2F70648A2C30A0B42899B195EA8E6CC96610943C3276698A34A61893BA8770C69CD55F1BC0F00CA0E04177D0469C4833FCC23A6ED339ACAA91B6E081692340F53CAC66AF5A6BCC2391729CE4E1C88D5C2610B00454FA21E8FAA6487022F19F2C81D5452D5170255108BEAF3979FF9ABC2E04C8E3669C6AAB80E2B6464644AE2189C81FC92D50CC56039CF5DE2325AE5163A1B63652222AAB35E17430D16477537F867BA4CA0E9B1C83C61A562C6822E61BB1450426E9716A77C1934AB17EC69563B8299E6AB371D996849C8CF7A84CA1A9BB654E1AB20A81D65314595A52BA18076F8712532A81B00E19E8734968F87C03FA4763208862D9A3CA648582482BF0D5441FDB7C84AB237D9F8628ED2001A501339682F9B8AAF6606344B95342FA62E782C1D9560B6AD55AA332C1FD533A74D026A9C9757F0E91BFC96545D0B6477F31F95840FF0A4127B16C32B635471480523F93017577513EA96159AC60BE179D3A09C5CCB6DF44174DE866CD7548339D314D160718F262EDF32382915197BC2AC6E3A4F77229E22DACBDFECBE3F4B72AC6BC9D9354E7ED2C31CE7ACD7F3A2C8B9ABEEC00613B1600C8992376B73F8C245AC9841EA06409454B48D8C3A152BB8D6168A3FA6423373651CAA7AECF0A5971641BD66897E5991E793343B5190BAC3107EEAABC71BC34788A345BCB9AD8A45A50A1DBDB1846BB76205B06E8AEB692B4200A596524954963F01C946131704F6B181D7781772CA6365824F6C6C22A1AF3328A2C8978EA8D7C38F6A00F7A6B3A50C2507F103F72420BDF98DC19AACE30B792851142D8B43319C93CCFA966D71CFF9352F25FCA9E8A3064CD96E42E9A2959C128FD532902419B81972838532CDFC08F34541459CC68955C9C2A431BA5126C9BC08039CA45533AD8108BEBA49BF8D56BD44433FE12A6C55C41F3CC20560B28CF050CC1F195C5E817D23D95E105A13555923CC21B13C9E46D34182974451BD97B6A3DA440DE6E5BBED681D6EEA2C6822B361019AFC8517AB7585926764EC7ACFF3C747479E837831429B97B7CF49AC3763BD9EBBE008A2455063246EB5761E908816E48990D670308B0D34D7823A325D49A1A4DC0D", + "ek" : "FEFBBBC6BA99DE3349C73CAEAD3CF1E0C58D9EF8E5EB50BE0FA20C64CCA821E27370B3273EDF16F68BE56CFAF3ACA9465AA868D2A660F2141E2797250B6F58EE6252F0A04947CA0A0CF7456B3E7BD60A99A376A88097BE8FA6FFCB22CA8ABBF76467CC7EEE57BC4D2B71B64562522D41166C0CB9CDEAD5CA1D5FC743B4BA666001773D4994B9E1CA6B70B6B0B99A5CA40D17B17AAE075F0F26917FA4E4E556E0C0CFE048AA54D8419805A64D54D4EA414B203FD18815520B52CFC4963FE6D853C69DA97A312D297B11EFB15D7B1ADE1CFE393804BEB18B0E672A05A47E074AA8937FB31C27E2C509F8BC14D762AE7F027FBBFAA3BEABC5BEC99451CA885D54BB5083CF220EC6746EB05B7F8D6C4A3C83064ADA04FF198F95392FE9F917773FE48714ECBB530CB33AAB252BA2E132EB707426B88B61E3282848ED2E641B4CD39EABC6830294385FD1563DE60D2CECA2C27EA08C1A2105A297EEB5FBE529922C06F4506A60C71740A1EC3482ECFDD859FE4A08B94C5D4D9ECE19C9DB64CD4249B16947CEDDB4014D30B43A5C8351DA5012ADE575529CC1681B1AFFA5AF7EAD9DD3F339B24C344DE982534A9F4E99D0EC9121D04686A3B4777EAE9A72FCB39361057225A7545D21369D54BEF64057969C591ED1E9DA6AD2FBC7E7C511EE7ADF09362017D76A0FA297F2748F4D74F56D34F819408D7C158CAA9AA57ACEDC9034877DECECF14A13CC912AA65AC30826AC52681EE745199916BD3A07C6D35A8E161ADF551BB0A1A881A69EEA3166E139C758B6DB79640010F882F7091EFFBC8705B23468140AC6E1966DF58364235350405F3682196A31A24CDC9DE68A465CAAC2E059F5C35873A5637C2E946998A57043BAFE29756044BDAEEB77FD50260849CA63336E99EA00324DA1A360C3DD921C4D89A41DA29D6FCDA4EEB73738E6E38EC639A7CF398642A5893785657952AFC09193574F1DCF7E8E1714A6D5750822DF9C7D5CE0BAA8D2F8234EFF746813B684BDF4B381CA61C436DFDF4CE10AE87ECCC76C6AFB7DEB699A0BDB9350D8898CF8154A15C898DA21A04C890DA6A0A01A850292A7715251FEE6E68565F8BF9380192073597BB6045783AADF41A952B78DA452CE066DAA2D4796009E7024D05C85C4F042B6DD0D2FA1A51D72E35DF10B44B4D788864389C64FEB2786255E1EFBA4E9EA91EEC920DA022148F69C9CFAAAA5303895EEC4DE41B2B5589128141904495512CA758878CFF9CFED17AF85B96E47F6DA1FB5314D5EC6EC6117AA5FC6AF25A51E7CCCF7954D12D282A51AE06B851D19FF679716B42014751935E1A5F6E5461FB2E11055E9A011E7841AA6C4B2EC6C062BA05B405B8B725C653280447D68BF51AFEB0DBD792FDED2ECD348D767F9E0313D95DA6F01D16F726F5EBFCD3C742A7F268B3A5698EAA58825AE31CEB6E7CDE3DBCECCE34FBDFEF1944E8EE031EE832D4D20DCE457EE740BAF8307D65A77FE706589FBBE23C2B6B94E6570B29B98918512C0A56F9E69C4D8BD9D93DEFA9B207831B5E8", + "k" : "AA6F2A9658D3FC756E5AEC968E5489AC084217D5495F5B69C74A5C443D99FDCD", +}, +{ + "rngSeed" : "DEB963F8B1D8FBDF499D564BA8D2D47915BB402DA02F17031B37B4039A842AFB9B7E48F37200605992BD2429427A7A4E", + "pk" : "A6CBA4E1A93CF066B6C6284B85C1CED4A4B17634C2DD8C758EE3CAC74B2402460D2FC12D98943DE4DACB2F5912FDC41E8B1886F38C6619831677E2A32A63860D2A1E9B994BF4F9CDF0C3C83C5B044C14B83E57C59D55629A9704994A4793A7178B69AC1892A578802A69D22D609A7832B55E731A65A1F29753870F8F6B26443824BE227F578C6D97C57E570864092A66C8184CA58B1B8F89BA9C2A3E7A17C1BCD851AA552DDBE301F2774E81397A57247362426807F370FF2B7F6F7B1F5B83C2F3475CB225B71CA0750F333D72A434C88A902D542CB8F50F6BA8AE5531CE60C5C29057C2A995CED8A34CC1DB7005C478FA174874BBB82981107FAAB591B8C9581365E7205578C55FC06B5F588C65E2EC700E6473752708853A8C9A1ACAD3C08BFD67C553B9C603206A1D26276E66C53A166398DB6B2E51754E2A67A54902CD5839B97C66D2421DF86C42C7181F89D2AFAE41BC116212A7492688424A2C81B85BF616ED686E8D0183C1082DD61C1144417DD10CC0E29B3168144064D700C2A295C1042AE40848FB07ABF2AA7CB2883FB19454A8711C72670D8C0B152DC9CD39A108AD9348089754703A608C0B544350879DDC71C09051F92BA755717403130DC4B95C19D3510363A5DD620CDEB1918AF90DD1267AA9696EB0334810B9351DF981A0749A7E0C253D399A0115AE515C97B63A1B0CA42794E00EF59912A357565B427DD5AA54B706B0DF583E2FB68CEAB61395024ABBA0A8BA4AB6BAE958D9C13EED40CD20978EEB5BA041B837595427A644A850340168847ACBB69B8D6809B849A7D6A6B67C170DBEAA41BE8341C6977DBC025688244396503411148458AA2800C44195211A86763C54E45345AC258541926B4BCED6A337DF4506113647828B2D4E45723D68985DBC2772A6723A032BB3B84A140A95DBC480F1495118238E74376C3AA78C25E3703CE121E8576C22EA29119B1EB5B946D261CFDC71980AF7961961074584A7ED970FEF29172CD98A3EA5550F994F5D763B00FD37F9C0ABB1459B825C6DEAC0B35D451A9EAC64B03C3C0139806586C8E0F63B8F77AEF5B207D2615D5F296894C9A1EB0B68D0571351E18A20084580D98AEF13BC4ED039D132CF015BCBF0270D5B971F10F581093656A091AF7F3725A2E16C8A74C541345EDE689321A436AC488B23895ED3E81FB4F25B83964400EC33C529350AC29F4876128C010CA9C4B6D3E47D7AC798559251BBE4BBC7EA4ECE0B76E9F519D819B286F14FCADB1231067BCB113ECBC737020B47587C491FD26541F47EE2B6BFE6908C73EBC3715C58AA93484A5C2692598B4945209D47258441C2CDE253434A5A1EDC934C9762B2740795857E255921296A8BD4542F82BB6AC7E293F9E4B7890810A2E46511E241162B2AF6E38C2A07B15A38A494F8412FC40D60847F957B7839E78936B6C1AE906089A80EF5C58E2659BE2643083922B22DA53912055F26FA7CCF410ABC42CF21448290B168CF7C8BA20B28DCA959ACC253BFD4B67E60C0C5F82728382C96F78B48B4A4C746C32C019BF8C3202C46A7A2C9C401700EEB1C013BB399D9B62EAE9A4E68E4A4BEC7B7FB92888EE9BB5F52ACA49B2E3F6AC6B72B2CDBF2C755F85FD14903D8712FE0BF82AC0B06AAE9BEA06278C21E6257BC96AF0379BCA07C7833", + "sk" : "B8F488E5F0C30B5CB5052115F097A6F20C0F6C4206522A50492991829251A189C53FD67AE08A467590A38099994BD5A0B5109827B888F5322BF6EB9C6D75911B2A721C92905F145514A3138EA132E5DAC52851160C171E80B728A87B855A78CE550678EA20044DB943C708962C25A86C78A29CFA801AA15350841989C00563FB46D299274F18430D66CB6ED9BC89145CDB262C18D5C095703E779C14FF34459ED12C13427733C59BEF3C8A6C24B5BD5171712B074C797960E2BE7BF2B58A8111EC9C01A3F938E83637FC9B59123880FD26A845D26DE5FCCAC29657CD2C8831BA76168421B276120639A98F13A07F905C2266BCE1F825D1C464BB2016665A2817C84369B7708F975641026321FB4C409531CB1A3827B80F2C94B1C4D36132B10E69B8C94502CD46C540902B96EBA76A55E3BCB8FA037A217BD91816EE09CE30F19721F12432D7238FCA919A2B4F718674D4558DC7095F0461A20B4AA1AA080354AC60FCC8CA2400B2EF73246514C41CF3945CD6A425959D1AD08B51E43C02A834DF3C8E084B04B9695B2D1500E9D5761E86C95C7C1A0E12783AEB6F18E14E157881640204CF5A7A2ED815797A49E0696EE990448C312CB7A55A28FA1367B196001CCE6A56796208100828BE8C241CECFB82CAEA1BDD36B19351CD8BB1CAB7014CB887BC6E232E74D036437A3222F56BD3E0893EEC360FFB220C03222513293AEC7EA6DA408F9C12016CA03659791ED14241331E5CECA1B53A2453689F8AD819906CB19D731E0BA7ABF0096998F18917E4794C4B15659678DCDBC8980B76A4D5C5B8567D55719E774A2D1C952612A9AF1EA7C77F896F88242790D989EDF3781588C10A7C50ED25821B4ABD882370AA74BF299975E9C54120B786F5917135B69F3AB24465AA134CB1BD3FD61F27FB38692B5F3DB5CEDCB40B8530834C9ABDBAE738C45017CEF302FF334C9E2567E0CA791175813A8382489B51015BCB8AD5CB37626DD3C48C745006F5133BC5557F6AFA7CA4633BBB26524AE968DF362F33C716EA9131DF1754515083325BB3F4E91E40F2C598912CA1DA3770E81DDDF8980797277711216B93B41FE456307A8135829CE7D7AF348A090758BACE57AF3F353CDDA444629A596EE64D10A5881EAAB061782314D218982602CFDA25A926BEC7D57228844ADFC31109D210BB2C88809C47AD09C466141B66AC6A013280EFE78D38E73D6EB9BA00F59841050558964B2916AC04757E968BAE6BB715D94199F22A81F4E3247B7CAEBBE3CD9BDBCE68C931357A568C39ACEDFB0093337D95D92DDE215FDC5B6BD7E2B14AA29046D2A601A91F9D4635F985A393E4408D64BE23052DDAA323C5D0235D4A578A63CF6C655D55F78397D72FCC0CBB490253B9A4AD0888C742CCB474CCA41BF4B51C6693767AB872586DA6B470CCF0066A038DECCBA3E229BEF1FBBBE33B42A5C524533B08EA926469C9822255150CD0633DF08B01670F0C134074F22DCDFB593E477853FB383A4B683C786139891F647C8A42680D89352004560EB1232FE173C47379119B29226691B015649253673187F98827D22AA0C168FD7A339992CE4FE717B6E797F616C27D49B8DF377F1300AD643220DB8315A30429A6CBA4E1A93CF066B6C6284B85C1CED4A4B17634C2DD8C758EE3CAC74B2402460D2FC12D98943DE4DACB2F5912FDC41E8B1886F38C6619831677E2A32A63860D2A1E9B994BF4F9CDF0C3C83C5B044C14B83E57C59D55629A9704994A4793A7178B69AC1892A578802A69D22D609A7832B55E731A65A1F29753870F8F6B26443824BE227F578C6D97C57E570864092A66C8184CA58B1B8F89BA9C2A3E7A17C1BCD851AA552DDBE301F2774E81397A57247362426807F370FF2B7F6F7B1F5B83C2F3475CB225B71CA0750F333D72A434C88A902D542CB8F50F6BA8AE5531CE60C5C29057C2A995CED8A34CC1DB7005C478FA174874BBB82981107FAAB591B8C9581365E7205578C55FC06B5F588C65E2EC700E6473752708853A8C9A1ACAD3C08BFD67C553B9C603206A1D26276E66C53A166398DB6B2E51754E2A67A54902CD5839B97C66D2421DF86C42C7181F89D2AFAE41BC116212A7492688424A2C81B85BF616ED686E8D0183C1082DD61C1144417DD10CC0E29B3168144064D700C2A295C1042AE40848FB07ABF2AA7CB2883FB19454A8711C72670D8C0B152DC9CD39A108AD9348089754703A608C0B544350879DDC71C09051F92BA755717403130DC4B95C19D3510363A5DD620CDEB1918AF90DD1267AA9696EB0334810B9351DF981A0749A7E0C253D399A0115AE515C97B63A1B0CA42794E00EF59912A357565B427DD5AA54B706B0DF583E2FB68CEAB61395024ABBA0A8BA4AB6BAE958D9C13EED40CD20978EEB5BA041B837595427A644A850340168847ACBB69B8D6809B849A7D6A6B67C170DBEAA41BE8341C6977DBC025688244396503411148458AA2800C44195211A86763C54E45345AC258541926B4BCED6A337DF4506113647828B2D4E45723D68985DBC2772A6723A032BB3B84A140A95DBC480F1495118238E74376C3AA78C25E3703CE121E8576C22EA29119B1EB5B946D261CFDC71980AF7961961074584A7ED970FEF29172CD98A3EA5550F994F5D763B00FD37F9C0ABB1459B825C6DEAC0B35D451A9EAC64B03C3C0139806586C8E0F63B8F77AEF5B207D2615D5F296894C9A1EB0B68D0571351E18A20084580D98AEF13BC4ED039D132CF015BCBF0270D5B971F10F581093656A091AF7F3725A2E16C8A74C541345EDE689321A436AC488B23895ED3E81FB4F25B83964400EC33C529350AC29F4876128C010CA9C4B6D3E47D7AC798559251BBE4BBC7EA4ECE0B76E9F519D819B286F14FCADB1231067BCB113ECBC737020B47587C491FD26541F47EE2B6BFE6908C73EBC3715C58AA93484A5C2692598B4945209D47258441C2CDE253434A5A1EDC934C9762B2740795857E255921296A8BD4542F82BB6AC7E293F9E4B7890810A2E46511E241162B2AF6E38C2A07B15A38A494F8412FC40D60847F957B7839E78936B6C1AE906089A80EF5C58E2659BE2643083922B22DA53912055F26FA7CCF410ABC42CF21448290B168CF7C8BA20B28DCA959ACC253BFD4B67E60C0C5F82728382C96F78B48B4A4C746C32C019BF8C3202C46A7A2C9C401700EEB1C013BB399D9B62EAE9A4E68E4A4BEC7B7FB92888EE9BB5F52ACA49B2E3F6AC6B72B2CDBF2C755F85FD14903D8712FE0BF82AC0B06AAE9BEA06278C21E6257BC96AF0379BCA07C78331BB014BB0D6489C14F5411051F9667AABCE54DA7A8DEB73B627E3873D9390A35DAD700CFD0BFC439237A0CDB3F7D6C76699AAD545D0ACD755F14F7CB3B30096C", + "ek" : "B2AF2D4A1539984C5BDF4A4E55EC378F11F7824F50B62259BE56A35CDB6FA000D11557841F525649EB88C70F462B27150A28B56DF5CF2123BA57CA2D61975FDC56973BA71C3DB9405768F72B136887AFB16B7DBD0D06084E07B0C8FC617B20F6C0092A98CE7B3AAC87A1985BA0BD8DFA3D8DB2DB80086B8A0997E287157D6177F34A5457722D628F9D0877F237CAD57F94A818B8C757700300249D10907B288B03DF8D995712AEB3AD4F7C4D5689E0AF58FE7F7C2AC06D7027E446D28FDDCDF7AEF84CA787DEB6FB2CC4813E074641E3785C1F3578608395B465752FA115A87814FF0A2D0471AFF1EA16A9B2F81CDF46B1DA7771CA1990A8A2D3E6DD8358F5D0C8BBA98853E15149ADC1FA200AE4FAC4E2CF89C6EF99B5B9BB743A47E613A68AD8E2FF775B7793C9820C85B4B41866C5D400B964020EFE20BC81F44EA4877F4C7873E415A30C769E2B61CA000E1A18E51D57A2B0569AC21368D68637C5D21881647CE5DDBDBADFEEA9F62F6E553D68BE6518803BE1FF7362607C5AD2DF3212287BE6C36F0B6957A5F68D3D682E3254E782AED2DCF14BFBEBBC7CE052EEC4CEFF474F8E1ACCAF8511A0D5F488FF24A4BB7089890283C8517C052CCD9F109A286CAB3DFA17C2F32E26A3B7465A7D3E5FE9821A68321C9AE02EDFC2B494AC32107EFA2F3267DCA1C7E32643CBB246F4E09E86BF126A9B7B20C4D897DE8728EFFDE0EF62C5881FFEF23E848B41B8DEC2DA43D2BAB65D6F19B440D664E1C9583A053E6485B570DE809AE055597553DAD43EE2C2AD3D53D68D2040CBBC4D008FC37D280A1EE47A6449B3405347EEE1F20A755C0AE36164B3868FA32D13768D4DF72E38BC0E306241D0FC25233FFB3AF07F145A9A09431DCFDE5BC7173F1540B503E1AF423589033889864961AE0DA26FE686E7887B37604B6745E69B140BAF9A5F6BFB990098C4AA51D643488556562930B2FD33F7734379BD11A7CCD307943B3099ABE35AA3083A08BE3B1398C2C41E9A9F9DC55CF2F55A26365AF89C45574CB838D8D4FC7DF3C2A8F237DDC7D3E8802F6B28157D93C356DB2CC6ED88344EAC40711CD1BDEF1DBBD48E7AB0C92BB6B825DE2895CC75603764DD0F5E42535CEA6FACAC91C26A6124518C4695D7B919FC4026AB8BA42A0D8EDFAAC5926C5BF92CD9CDFBA592EDC4ADB26571657FCE1D9D5856C8007483C4067C845568B196C6495A714431926F2D5EA3DF519E7D4D8A2F3AA29F43534FBDC598795C891D7846D54A234DF56003663B6369AF6B71BE3BC0005C881BBED1BFDBEDF6A18FC9B44513A24308EBCD190BF8BE04B351D4F638AB1CA9B0D0F518C252C508B12AB15C58859BF895C58B4DC5ED3D32A676A17B4D462C4081B0C24B127F26D29143180C8DAA472502B0FE4A086744307C2CC9B19BDE4D6D322807E1162FCE5AA79022CEAEC9EB5895EEA0D7E2C9B045722E85083091371F3FB894E699BBEFBE32D8D029898E421B28F23AF10BF658EC7C5EE4E3B55E3351ED0921F58C57A455B2720167553B9827F5", + "k" : "8C67AEDBE382691996C9729142DD8BB57AD54197A7C5E64119E77745900D0FC2", +}, +{ + "rngSeed" : "8E2995F1B3E43853B18916BB1212ACEB05898E2B177A87ABEB928AD7184E59695C56B2CCCF5DB80853C28A525E327D13", + "pk" : "5A0322A62AA889781C4FA3C36F765586B2C2A20CAC081CC08D06CE1CEA6036463DCCC34BC294A51F7B1A5DC0778C143F57B9AD2C8B41A3B3A7E3317FEC687F50294158AB07441C119C299D421B3D6CD62019B4CFCE69C9DC5509856B7CF087B66391793E7B2A77262DB0909861B46B5D4C23FBF134AD43622357A81CB7C9F5AC9CF1C190B9F711164A9CFA4892927364D800AD7FA2888DBBAA21B689D4A20FD0BA43F27386F90026322705B0F1069B32760802581231C44DB0A43753779FE88F3A824F2ED858211BC172D49221931C3E86188C287A093B1EFF20AF18C1004979221C85C2EBD5700473913D465359AC18DEB3055075386AC3C330887879D5CA762B6B576B7F2D422F23889D51788CD84B77AE879B1EB7026DBCCE20CC94F7857AEA148213C1CE857277A7808857F47E45CB9B561B80895142463BCFAB6C69A7712ACBD64A3B6721AA9671AA934CB0C1BC52B464603779FD6AB10D57CCA0A749F3A1889E10386CB7AB0BDB86CCB02EA614A0966A0EF2699DA6B7282713874F36468C2014539BC804911053D1025133975E591E357A8D88A1C7138A200543A90F4AA250F44CA61870D206A236D1917B509638FB6442AA7B886A54FC21B7C40A1B7D027A09863EF94280C67A4693D28A0F842EF2268E0A67A11BDB4A18B3C459E11E977A5D143AAA82B80520F72C50D248073746662B78FF685086632E304085E9C7050A754B302338F7A2AF0A223E45730DE36074E1843876A6B1CAB85E0D984ECE18A3420AABF4D740F6039DD183C57279469BFB9F26FA4F6AE59DB60532372B729CDB8BC8B26B9E511234177AF2717538383BF2103726C79D84B4489D493423F7375C273A9558611B60C9FBEC197047566AE9411637CA9DCB956962354872803891C728429FCD99C02AD020C11A2F1AAC40B6FB13FD6C8508500FBFC34D752080536C150B402155E130C3AA1A4E914ADA0740B5178C83A67FEA746803A35C36A3CC034052143303BEE180D8DA097B24C89FDB16583B972A50C89B5CA27DD4AAA1002FE2316940A7AB294B02ECA4C69957B3D02B538C239F18A342AEE0C15FDCA57D28930A62096567801F64C3452697D5F4A66781975B440AB3B27A5DA41E889928FF41402B20B93F992DB6D4216A4A2B169A6952816D61B93A82C5C0D5923152900BE6B9236AB96D076B36D406B06793C7C8C85D69F423774C4A0C143E27673CECAA38C66C1DBA02860CD305214A2637A90CC84A7AA6BB919E73C06DDB787B1B9117A2C6FD577A7EB417D5A34922767BADE412BEF212694373401554211C1213AC7BD1D1CC61F40FDBC65B89CCB3383C30476932D738B181B64E2BBC9508268C7061A4731C659D18749EC3B87C3741D1660D10978CC91CA44DF588C8A0A7A68670A003BA23F03AE733067139083ED33C98DAC4C06331E90B59514C7005E27F179A0EC8517931B678EC849789C656B30C4A736209E70151CD970ADE5557F9E6872248B94C894220C0BD1B6A3A0149C1BBB8BA4C9337ABA868B78199929044F44018FC261ACA4BCF0F70CC1444411FC8CC3B6B7AA7EA9F8D06A30C7A61D89C19E7C50B84A278A921B74E2936AD07AE2B17344356A8E640A9A1392048CACC817BB0924682A027F2CF6EC9B36AAD177FAEDBA70E26DB0E2958E3D520D23B10254587", + "sk" : "1E556E2047C1BE5B68FA204C0F36ADD1B8C00E6B66C0906958635733F82238D1AC4686929E4664B5217A774299DF70822CDAB3E06C5468D8BE7D8745F7569E5851317D6B6CEA6909C70B72897395C57494AA20551B4501E45825018260DC315B71E72ED21049A91B01665440345A102EFCB0C9329F7CF0C619941C9EA7A1651CB0591C53E804987395760CA688DD7C75BF2B255DD618C168B8AD735876E9066C7275F7EB8200970EC4B9C36E296A7BE41FC8B64C35E9B15473337A3003DC62794A0AA8CDC71C65577085253220869FB2845358EA4D73BA898F123F7F0CBB58DB2DBC26A98A5B8299B40318285A26573FF928BFBF75915AD0518965BD345C2072157748077C16F562067B154EC88694C1B71D20624F19B62E30844D930C91E95B28173F9DF878D9507FA35812654353F99B93EF9AC6F61503229A72558570C9D5213DB68347F8145A9798597219DF160BDB0226EA8B569C894E2CECA7C3C86CCD66450FE13E5C4556DB3C9BA3441B37E26CEB9C7FAFC460ED1373AEFAA3D593B7F317B2F0F8782B76C18EB11D0D804192627D8657BDB0E440490B6C196797C0459CDD791B82B329C6439D2460CCF37621A34B263B7B46F522C24C294BE8B36C117418DAB096FB874DB3516E889B3E92569C32E17F3EEC3C5B28766D3A2F4D06475BD666EDF00BF0A514D8C06309934CE4A191805A38D7D69D0DC926EB58110E9C5BEE187D0675B36AF68F6DE7A294FA7CA80486D1E561D28C8788A75CBFB718BC740D131A83F9E64F5B484DE82775B2B8762DD568E8528E6F213A198A8D6A21B9EF668B49B87E8BA97AE468A379968FD18236C95C96F9C84B23296D5A9210869C5DF05421E9C3C2B65975A93ABA3EEAAF5D746FA679C5E93021CF93CE71A8B45FD44ED92BCF43D0172A8589585B9CDB7BAAF1041E81772B37861FFF4C60FC5B7E8D6871382C63FB3C7249C3059385C7D856CFF293138A3B30B6B13614354A502C7BF922076D028AFFC5BD6D43706F5304FA2783A862552A5B2DD48471880529EB230851B6091B59139732102F66268286828FC767930C1B4A3BAB3F14BB1490BA329401F8D95D347B3450D6CFD2C8355DB3697052A4F3884DF8BC28D3792FD09352DAF9023B6484F8553FE15336A788550F6023D9C9A42034874CB0BEB25A6A4517A1ADC72BDAB35293F16EFD7171455B948103BEE4FCB7D635723EEA0A4F7A3DFA3838E7243143971BEBD25EC82C0EF059992EEC1AA37835FEA57AB04347E86855E0EBBCEBD828556A18B167B5A4C7BAA945560A276EBCE40D8B6C6B23B417FA8C39AB55791E703A3568BA28F022FF8CCA8F6965792067CE23465AFB4B3517B5AA80C3C7001E78B62617E87E3B27021636667E60A47258155F9A06A1F8C93F39420C141372015B70A3B69DA51DFCE42FD748C48916851D78C8AD5C5BDEF8624DF33600027495F6BE5C6A78CC43B660767CC1E77D5B7396F31C8AF0B35C9826C185569255FBBD7FE0533767C89FB43D1E282B0B9B348EF31D7CB15719A0C1DB21CB57A1171046BA9409920F08A4A6D12855E113C427B2CCC4193C11781DF61345229191B60283ECCC3B05C49316C144A8B21E494D3CE1B11D58391BFB7BCCB3A95A0322A62AA889781C4FA3C36F765586B2C2A20CAC081CC08D06CE1CEA6036463DCCC34BC294A51F7B1A5DC0778C143F57B9AD2C8B41A3B3A7E3317FEC687F50294158AB07441C119C299D421B3D6CD62019B4CFCE69C9DC5509856B7CF087B66391793E7B2A77262DB0909861B46B5D4C23FBF134AD43622357A81CB7C9F5AC9CF1C190B9F711164A9CFA4892927364D800AD7FA2888DBBAA21B689D4A20FD0BA43F27386F90026322705B0F1069B32760802581231C44DB0A43753779FE88F3A824F2ED858211BC172D49221931C3E86188C287A093B1EFF20AF18C1004979221C85C2EBD5700473913D465359AC18DEB3055075386AC3C330887879D5CA762B6B576B7F2D422F23889D51788CD84B77AE879B1EB7026DBCCE20CC94F7857AEA148213C1CE857277A7808857F47E45CB9B561B80895142463BCFAB6C69A7712ACBD64A3B6721AA9671AA934CB0C1BC52B464603779FD6AB10D57CCA0A749F3A1889E10386CB7AB0BDB86CCB02EA614A0966A0EF2699DA6B7282713874F36468C2014539BC804911053D1025133975E591E357A8D88A1C7138A200543A90F4AA250F44CA61870D206A236D1917B509638FB6442AA7B886A54FC21B7C40A1B7D027A09863EF94280C67A4693D28A0F842EF2268E0A67A11BDB4A18B3C459E11E977A5D143AAA82B80520F72C50D248073746662B78FF685086632E304085E9C7050A754B302338F7A2AF0A223E45730DE36074E1843876A6B1CAB85E0D984ECE18A3420AABF4D740F6039DD183C57279469BFB9F26FA4F6AE59DB60532372B729CDB8BC8B26B9E511234177AF2717538383BF2103726C79D84B4489D493423F7375C273A9558611B60C9FBEC197047566AE9411637CA9DCB956962354872803891C728429FCD99C02AD020C11A2F1AAC40B6FB13FD6C8508500FBFC34D752080536C150B402155E130C3AA1A4E914ADA0740B5178C83A67FEA746803A35C36A3CC034052143303BEE180D8DA097B24C89FDB16583B972A50C89B5CA27DD4AAA1002FE2316940A7AB294B02ECA4C69957B3D02B538C239F18A342AEE0C15FDCA57D28930A62096567801F64C3452697D5F4A66781975B440AB3B27A5DA41E889928FF41402B20B93F992DB6D4216A4A2B169A6952816D61B93A82C5C0D5923152900BE6B9236AB96D076B36D406B06793C7C8C85D69F423774C4A0C143E27673CECAA38C66C1DBA02860CD305214A2637A90CC84A7AA6BB919E73C06DDB787B1B9117A2C6FD577A7EB417D5A34922767BADE412BEF212694373401554211C1213AC7BD1D1CC61F40FDBC65B89CCB3383C30476932D738B181B64E2BBC9508268C7061A4731C659D18749EC3B87C3741D1660D10978CC91CA44DF588C8A0A7A68670A003BA23F03AE733067139083ED33C98DAC4C06331E90B59514C7005E27F179A0EC8517931B678EC849789C656B30C4A736209E70151CD970ADE5557F9E6872248B94C894220C0BD1B6A3A0149C1BBB8BA4C9337ABA868B78199929044F44018FC261ACA4BCF0F70CC1444411FC8CC3B6B7AA7EA9F8D06A30C7A61D89C19E7C50B84A278A921B74E2936AD07AE2B17344356A8E640A9A1392048CACC817BB0924682A027F2CF6EC9B36AAD177FAEDBA70E26DB0E2958E3D520D23B10254587C9A546B5C0A567855039F6C1BCA60414684E7BD1F8EEB7913F3A1795BA4BAD4C2A96A70166E26D17A7319E8A5E12E38CA01A98D8A5813049A5BDD355A7D71347", + "ek" : "7BDE5FFA791B0F36B9975F4E90B09743C72F0E6CC44513EB1731D2DFB37F2653503D5EC14A0963FD2C0A6AEE31B59448CA79EFE5407D07E88D415C959D2187D2D375373D614A20E27B0EB3CDF5F1B81D8A16D4B89461E30D67AEA15D72278C917283CDA05D8A32FBB49C487F9EBE344C7B37CD7A0071CF10FDCD71EB1EB3AB5BB4B243BEF41C61BBC74BF2658F9A9F871E2F5553C733BE77B969C72B85DB7BE9A6F3F010C1CB622FEAF2F27AE265BF2EB4EF59F5A56ED6D5530F1B31C8A9D9C52FF47F49B39D384D29B079C36415F3BADECA8B70044FB152FF98592BDC0D41B0A56A01A011CFB152C9C0B3238B463BBBB7AEDF82DD9E4980DEEF83ADC2E07F61C9F10999807627302E92BFC35B3E3C9040B0670FC461F44AD752155E1A4A1CC44F56E96FA87BB03D0A9C675F693FC95D41197CA4A02D9945022EAF97064C62554639FCAFE03F47ACA998AD4541F50CB796B02E743F0D88362977E879BE3A70B518BC53A10862AF41700E24C7FCA274B21C7963D59E0176719332753A5D96ACD344ED5BB0F8C843B3D6216AE4C5FC8C9571029C22F1BB19206D227338C0D9F79DF507D72ABA04D78BAD864A324645D2DB765E6393D64761481FB4449CCAED10250B215532C63868CDFC6BD9B7A29B080AC05272D3E4B42809E76A0C22E7F1083BB7792E0E0A0246280DD567DD4C8CCDA30E76EC22C142A803501CA801E475AF7C6D99BB40358B02C3483C6B3F5E6AB746868179EDE004E13036C0180D7005269D52438037F7C5F7DA94F40ED6FC6D155997AFE961B448F1B871FC9676DE3B5F1433CB27C4C056183A79323F37C2D05DC55C3838E5AA2F5BD3F12C2686701FA1268B3F2649D333A327FF649D23138AF26668D0551C47B925CC7B96D5037B8445A238D4DA99F083FF421E59F1145D98A4FCC9BF7CFE3A3D1438E18B161C5600FCD1378FE72E046ED5ABE647E9963AC59F2EAA5B5D25C5B617338035C8ED364AEE97BF71B033B5CDFDC461AC9A5FA32F9F8C5C1291C923BB30B83C64E8BB1B57488B18A65EC82F58D8E0CC36875ADF565A91FA0CEE3DAC95C76D5C1D2DD21731CF211120DEE5B3C035703A1F4BA0398924C7985DAAAC025DE475E32BC36DB0B9BB460BBDF40474B6477679504F7B1EBB28E4197059D8960756E7F15E2AC15B24F87D1437F996F280A6A1377B73A5E6279EAC711FA8592100E893F4852903CB404062D5310F97492C080A098637B653C00DEEDED5CE5A4CC617B5E17904170C4230D2847C34647A175E893D7F2ACB9205573995CD1698EE125A39F86EA4D4AC45281EF5EFEB908958BC183DAC260791D8E62ECA0D616972ACAB787382D9A243A83C3A9E1FA59EE8938B76B7289040DB66D2FE6D47DAFCBE27469C0FF1D22B1C287A312D1189A9B4E42DE13869E0CE7BD5D79E51C732FFB71D3BF3975BD977A28491B24ED052A41CB07AAF320F95F8EE9B31ED8E54E7F77656132E7A2188E866CAE8C354839A0824DA89B256D9E8FD13698C63F8853F70076F81D425E3EF14973737D0", + "k" : "18B621DB0616EAAA4022560D24346F6E6DF0612B13AD6B580EA62B1451D62638", +}, +{ + "rngSeed" : "9218943C51FD2DE47E509AAC67EFF176795102F37D7A2017E3AFD768FCDA7877AF38739B00FCDF227C2FD62EB635942C", + "pk" : "EC8C397304996CE42773532B2798C4BB8A987E57B41B820C6F8B2C64181873BC6515B0C810109890B8ABD9BC650F0344E3E7A672E269547AA4BBD0BAF9F2B2F3B53B1910B255F7CC6CF0394CEBA359685E9F6C77DDFBCF0217611D076AB2140A8DC58199A2A235955B69FC2520B192555C1BED2777EF623760CC71B0208DBF2A5D9841A231A60E2516C5CA3C6156A0C0862B54C311CE2B6B3F442C8082348833B193CB2B22D252A9AC88098C704D83F217AB2A8799F031227B95E1FA5D1A6410E3F025485338FB8338B5C7C4C0F6641B71644F11124B13C2DD21088684035A66A4C4451B5F66C9D5AAA7ACE15EAAF03497EA2E1D693B77A4402DD1943E9C68CC642997A44D2F86A339C78912E678D0E314FF162C0E3C9ED8EB726ED910D1B26B99061C01142380E5074B5A46505863F6287DC18422B323C89966340FF7146FEC18095147429148C24718301C106DCBB5A1B644E5A26EBB566B504A9B2984100BB6C40B45286D4C2841D774DC8915839C32DDB22ADC41C0197431BF8C5F26C2329E6B2A0EFB2B0D872C4B8B125D997937236CAA455389C60F9E38BA3A662AC7349A5C872D84A353F9710C6C74463F220F37558458D68DA5E67F1130CC5DD5AC4608220DA2B8C9048BC805BB1F6BCF04379330025CA86B42CC361BAAB986C32A9E266BB1FA27552192A56B4B111564646B701DC4771B8F61BB5D41278A291920AC1D01649267344732A85109A3CB45B7B8E9ABB8CEC49FF602C819695F61011C7AC5957FCCC50859432F324D6623459D7BCBFA20645B2A54C5A8BA0DF27F93ECC2ED00821E98553F680623EBB221953D3D9B8D188044D693ABB88BC965984B08D112EA6B4885ACA190F9877F1BC123220AAD662FB7F5B0AFBAAAE118C6108C98B31A5B6FF15AAD0A87B172BB40998EC232A9D218BCA9F03E88633914561C9FF65BE6DCAD01550903276646208248A56E5C3239F951585EE9326808A4E4F829A15996452A3328253CE2CB3613AA4FB02ACF3030B64C6A27AFC5863487B9538B53A2E1456168180D257F4403B41F16B415740ABB024EB54C23D6A851BF9C54932259D1BB510964445067C68AE362DAC6A7C3E29ED3080B0D21A76EC220C7D562340123F7A32C62184D2D707144A1565E432DFF443940736CF628CAA3607076783B2B29BEA7058BD164219518AA77C2B303E07DFFCBB00C930EF0F0632C10AAFDF32FA7BCADC5719FDB591C7635C3AF83198FE306076A9DA2455963B91551A1618040B0EAC945F788820A1442CCD10FBDBC763CDBBB6E221E8AD076880ABD561C5059E23709D40996D41FA6F129C4758B62644C30C1C06D0080091B4D5A8705F4B0694507252EF1A5980A347846160BA3256475741D50A7AE465F1B444A25729ECB66585E51992BC781F28C180593C4E5882C243017440633007DB1C637733A01BB8A994347D7602ED0B34261603B84B8C2E14C5C46167AF459507152DA216F272371A0981FDBE740DAA78B9EEA655D98CD14EC90CD383863AB5FE8137EBE820DF5A007A288586E18A54B43387DE9B73F9037F27384BE092B09941262706DD6DB377F733B31A49D2467605649B9609365232252A62555B1451674B717182870C1088F4B34061F3E8B9034AF0CF2C5F7EEB665E064F5F27CD5E4C84531D45D38051EF9", + "sk" : "243C03E7374A7157B1F0C02C4D542E2B31A45A902D908592F3F620C347511D650AF8CA8932B70A3563CA126391F178C7C1477C9AF532CF1897DE99BDD7F07C0D304F90190EDE5967898A0E7818622CD76724F77C4D73248BF67955726AFDE4C4E4201A21EA48401099B05B196B4C698565094B3421C2B429CB83A99B2A7BF5C784117B9E8F7C00D8F1C801B66F63402AEB49822A92AFAFA445F1FC7B3E76CDEC3091CBD474D10CCEC25539A658A1A48B6697252D28442A36E70578B810898045C0118468E6BD05C664E4C19440B88E0E847A15CA747E9990D995CD4172B5933B58FE7062B871CA02F539E74872E283ABEE046C7E15372E58455E4A6DE59BBF716BBB62417B6E46296E68C501D4007E1A97B7D970B5BCB8A9586FC42433EB457993E7B15D7C35DE95176B09065A1A3F61734B9D453FF0B0313DD8C0888A92F6270EA93AB6E9F15E9F6C207CA9512A41364AE6591C578AD93639E795CD00339CC5B67176F771FA6C5496CBA3071B67FFB88B72993ECEA38F4D8244D94676E55AB3E484B0AD4776BE5BA4A99766D63128828B7497725ABFF8A932B1A697B6C0A27B3B69121607288DDDC03A4C144CBF0A0B11886B2130174B99921B1920320BA515032ED7D536F5B352975697B8A05855CC78D7979DA443A06D443D52B4931C554CCF03B43631213B68385E1A2C5F87C84E13B84032804F5929FCA18C2EC8A15869905A216FE2852631E00B19B45A4A0B51243B118EB358435B9B46A0525426BA232439CEE0CF6F8B164D72901CBB4F1B2750279C18AA255F5D7053F10C1750894C886B59C9AC43B881CD5E4476056884AB9A246248892C0C7A3AB8425D77C178B47C8CA5262949CE47C25B90CB90942B1AAF64825A7658C4E0BEF219BA2E609EAE90BB6983589E128325DC42D9422C72D0452C208B23297387A9B77AB8B89BA34266130D5CC35568AB1487C335FC9A91DCE293D807AB73A41EEC932C0E398A762881D2DA7D558352D7B8ABDAB79687E3CA3DB89036022ADEBABE39175232B36703749391C9B772A79396862972EA6C0B92387FA423FCBB6030F83D68C4A44600B25C547F7173376704A6E24C12A5906AFC43BF539AA6AED0281D786336373A44147B1E943A9C0C7D8F995F61377134EC1F536334AAAAC6EF040DAD6A42FEAB2D6972880C602D97540A52305B24DC7CB243259FAC61D2632285099A0AB740083178CBAB0EE8F17599F115E106C4ABD606AE5568F7A387A086B334F7AEA5F92249D678ADD0C26F268CA769696FC14EB1C6AB8E182E5A727793D6BD94461B0E985D67E64F794B0DEF70C43EF927544081011A74A28C976C553AE2E0CA49C80926F460078886F49A55475C456F2BBB84270F22C5256241AAD6E05B4A9A276E3357C1B92D5DF09DB23A783F19B1D9D594E064B09FC815BD43B5CB8B9AC43C64A2BCA445B235F7BBB3CC0A7723D0A2E351CB4ECBB1B688CA217A500FB20CD37B1A0A2C4EB79775EAB657425C8B264583B5C37BBCFA624AE1AF5575571AA59960F37599D25CC625916CA149502766AA06CF31FA23C99B2099B9677BA327CA317E49E029EB33993068B022E00411462D7A548F4BB6B435D8CCC1305067F923C7A914D5D77FEC8C397304996CE42773532B2798C4BB8A987E57B41B820C6F8B2C64181873BC6515B0C810109890B8ABD9BC650F0344E3E7A672E269547AA4BBD0BAF9F2B2F3B53B1910B255F7CC6CF0394CEBA359685E9F6C77DDFBCF0217611D076AB2140A8DC58199A2A235955B69FC2520B192555C1BED2777EF623760CC71B0208DBF2A5D9841A231A60E2516C5CA3C6156A0C0862B54C311CE2B6B3F442C8082348833B193CB2B22D252A9AC88098C704D83F217AB2A8799F031227B95E1FA5D1A6410E3F025485338FB8338B5C7C4C0F6641B71644F11124B13C2DD21088684035A66A4C4451B5F66C9D5AAA7ACE15EAAF03497EA2E1D693B77A4402DD1943E9C68CC642997A44D2F86A339C78912E678D0E314FF162C0E3C9ED8EB726ED910D1B26B99061C01142380E5074B5A46505863F6287DC18422B323C89966340FF7146FEC18095147429148C24718301C106DCBB5A1B644E5A26EBB566B504A9B2984100BB6C40B45286D4C2841D774DC8915839C32DDB22ADC41C0197431BF8C5F26C2329E6B2A0EFB2B0D872C4B8B125D997937236CAA455389C60F9E38BA3A662AC7349A5C872D84A353F9710C6C74463F220F37558458D68DA5E67F1130CC5DD5AC4608220DA2B8C9048BC805BB1F6BCF04379330025CA86B42CC361BAAB986C32A9E266BB1FA27552192A56B4B111564646B701DC4771B8F61BB5D41278A291920AC1D01649267344732A85109A3CB45B7B8E9ABB8CEC49FF602C819695F61011C7AC5957FCCC50859432F324D6623459D7BCBFA20645B2A54C5A8BA0DF27F93ECC2ED00821E98553F680623EBB221953D3D9B8D188044D693ABB88BC965984B08D112EA6B4885ACA190F9877F1BC123220AAD662FB7F5B0AFBAAAE118C6108C98B31A5B6FF15AAD0A87B172BB40998EC232A9D218BCA9F03E88633914561C9FF65BE6DCAD01550903276646208248A56E5C3239F951585EE9326808A4E4F829A15996452A3328253CE2CB3613AA4FB02ACF3030B64C6A27AFC5863487B9538B53A2E1456168180D257F4403B41F16B415740ABB024EB54C23D6A851BF9C54932259D1BB510964445067C68AE362DAC6A7C3E29ED3080B0D21A76EC220C7D562340123F7A32C62184D2D707144A1565E432DFF443940736CF628CAA3607076783B2B29BEA7058BD164219518AA77C2B303E07DFFCBB00C930EF0F0632C10AAFDF32FA7BCADC5719FDB591C7635C3AF83198FE306076A9DA2455963B91551A1618040B0EAC945F788820A1442CCD10FBDBC763CDBBB6E221E8AD076880ABD561C5059E23709D40996D41FA6F129C4758B62644C30C1C06D0080091B4D5A8705F4B0694507252EF1A5980A347846160BA3256475741D50A7AE465F1B444A25729ECB66585E51992BC781F28C180593C4E5882C243017440633007DB1C637733A01BB8A994347D7602ED0B34261603B84B8C2E14C5C46167AF459507152DA216F272371A0981FDBE740DAA78B9EEA655D98CD14EC90CD383863AB5FE8137EBE820DF5A007A288586E18A54B43387DE9B73F9037F27384BE092B09941262706DD6DB377F733B31A49D2467605649B9609365232252A62555B1451674B717182870C1088F4B34061F3E8B9034AF0CF2C5F7EEB665E064F5F27CD5E4C84531D45D38051EF98F7BFDDE2A7116FF4010CF829CBB18512F7CF44237C02241A1F75FE3BA8D22BFCD2DD7A1BE89575BE8C14529BDE4D832CC005DEA955065C08B3185B215DA3A2D", + "ek" : "A930E52E4653C308D8584195FF17457380577F8BF4F8A33D02B4526B45AC58A48AB6F2D3564A7356F2D02C2E0F1E8D92A2F88B79D0ABF9C0C8B244405DE90157E93A9C72F4D92436C8CB532A9CEF04EE4E1AD087EB7659D3982D222B22FEF4D001FF0EF96779516F91C6265DAC37EC707AE09EA99CA0A4D8479F050D765CEF0A28D749429FA5AB2FED6C9AA1489E0D31A6DDBC217D1F09E027F7F5C8108E5916ADAB4885E37A10FB0F2EB1C4108B9232996BB9850E17D65DD7279FF860284189346310EBE4BA66F64F4ACB90E0A64807D7B64FFF67FBCA2F9A7D9B7B18D4159021CA26175A79E25482D4773FD7DF2358A6A50FD886EEE7E2DA64C0E5CC4F40D27F29530E7995CBD393C5C8373B5338A1869B5CF991344149D5106DA7E3BEE959828B25FAB92FE8D81A65D4A658DFC3907AE042EE727A37D70FE6F3CB2AD54011B560AB9E2C2A5D0E9F90F804401F07C70ED8471E6347CFB2CB90E9EFC661D4952010D833DD46009C4ECD72E1CB5D38A7776EB499F863CB7F2ECF106F4B71E1F39C1301B4CB75C648EBC1E143C2B8ADC3B5787EAEBF1FA5B0D0BBA07587BB7AB6774785F7A8E9E89B9CC3E5A1B23CD6F82AE5F8D326B235B4207399C3C80FB5E3A71F614C5B54666A45B152C83DD66253F14ABBAF4ABA222A4476C8052B7114D0919510C5B6085A262CF1CF12B5E47CC80020E4D2DC2C62D1390FC287F96A316192FDDBE2C3E909D81EEEC74FEE007A6220E1AF00B59DAB25B697D396BA6EAB5A6F7B9F2DCEB209613D1B6A549F79D9B9B7205FCCED41E166ECB7DFFD443C12F058DA2903EE21AA9AF327BA47E181457E34C04CCC00B9434C55DEF7307648E980C9C1C289A2533B534695494CD7BDA6248219F664267175737E8548D23BF2A63B9485C7DDA933E0F18648E49928B124FE10E223DE8F9BDB0A32C148EA152DEFEBA72018CD6985A535FC1933D9F445EDD9AD243FF179C9355664442699BF390912FFF3AF8A6FA14AC15E2C01E6EB40BEFCA821899DA8DAB4A2623C2DDA69C7DB38024F3A744B50DA20F643B40167AC75C1F7AC1711FE5798D531CD933BA5FF4A706981278B3AAA950F01E7C559DFF6A418B17B24AA7548D61A486279467E946D5E30E6CF6029243AE9BCC30AF45C5C83C43B3F5E88663107165EEDFF9CCD7A777A9E730E9F61C55D6846E7258A79E796C4C1977FD433AB50F121D84263082474CB06B33D5A6CFF30C26B652947CFF4BEFC294C56E818117E7AAC167A6A6F18ED1C781CEEB2A7F1BD81D107F9694585E95067606C11F145F4D53AD6CD421859B119FD593797CA263F3DA845D1F41349122A22ADBC290390DF12E9E7378F686054C795D497F6420E1538B0EF2ADD5EDC98768D1454955E8A8B513FAB56751AB7FB5BE54066B48BA136F2A77147B917E0B273300686B7A3E5F882B04EBBEC7A5C89F9847C878356460F4D40DE6CF838B682865A2E294DD95E3C5F1DCB6F7480C5867417CA337DE7C258EAD4561B0A9C904B0F8D0827E6DB94D8E972946E9FED62B9D4", + "k" : "F9FAE5849A514A9AA4B5C06583D45B01AD084B62136B0118F6D8BF052C71BEA9", +}, +{ + "rngSeed" : "542E20078ADD5296050AF150360F057F6B9AB3BA835589DD56987DE805F900B906505B5390A0D86CBA28038992DFC59A", + "pk" : "18F81E47490CF733359BB77D86B1B949396BAA99C9D73485E378B6EDA76318B961948497DB54149F386E51648187C48A94FB603EB114A9408BA0D27F3C717694F9459DDAB7C6D51A58C50A79BC072D7717781A6B12073577D3A89A405829850AFF65023A771A5F5456AC5B3970D545043A2254178375268ABCA9A967F50DB28635B1D01E7D1969080438368A4B61F63EFD82A811F63909AA48A055CD9345C09191ABEAAB8237696BDF3512B7E8625212BFE5500BD7002066357954344FE361BE074069A520A470EB64BC0289F85C981995141A246EE3C6673D9026B7B490A82819EE1825AD39284FC41A01C936D0280C4C681D62E47DE8E339FC0A0F958B279AB95114209231FAA8962754B12A22EFB67ED1C42E8C144F74476F552A297E7573A81717144648BEFA3B6C6096F428C10FD925BA86B29C8890F2750D1E7956664A714FCC00C88A3CC259B503D3CA39942986D19AB6D76378858D679CC61AB40EDC5A007D33813698A6AE96ACBE95474B188BFD3208C885179DE868DD027F12256B9FE84FF460B180C7655D514168C89A516BA4DDCC56C1B5325C9312E067949A57178251158EEC2FDE69BC9D61BE726338830A86E8E525EC00152CDC0E86473E2B54AB64790735C3A945CC83B999352AD2587FB67DCF2C9FB3B921DEAC54DCCC8201D36562F64831C8129E67B2AE78BFACBA95F29C3D20942781E090EBBAB81BC5C071B0BCE826173F0CAD6C101518B56DD03A8BDC872D338225BB16128CA8C7212867DAE513C971B687297E4C098FF7C478F841A29DEA278D1BBE55423321372A44937D2ABA34B279C99E8847C5D4B51F54143DE991AA16AEEAB267386C7F286445ACB87A98CC93029658BB0981048876F0884B526BA58F201257A2245849A57CB425CD2CA92A3CBCBF963A4F360E8616C082D8BE4820323DF715BF5344FCF85BA070AC3068AE91989E61600416D7CC28CB6D42A461DEC083F6126C749CA457146D114C84FBC576A7DC8F9C2C03CF4A3CD2535A7A396F59D73259654254E5BCF616B4970770BC8A3D030C8C61D93EB08644159414DCC6428BE73357531E50BA72B5EB99D9380BC4802339070366A19760C0B15E32A48AE0038453527B10C4AB6B1AE8497F49DC47E25A514258B5C0336A812525C5A86E22D73A9A8C3DA5E88A468C3439464FAC42491B0BC91CDACE7CDB15166A01B62CB22B745C38CA32A9727C8C57537C72563EDB4AA2B400B778115B36817F188E659B2BF7C999D108C5B2D252F6A3BB78737EDEA48C9BB91E917487E4E6156DCA609AA97BF47BAB00047602F296CF611299510B195BA59AE7BC245B8C9721901995B6DF4918842017945C330290C6BB3C46D9104FAF014DB6728C4268627F8C884BF52E011344CFA795F864A474F9C015AB09C77911A8A52C1AA46AEED6560D4BB1F3B64D65028D373AB3D51A450E600A239767AED9CF25B5C85FC24CC794162EE70E13D88FD3459CB37A92D348A1956BBA09E24513D5A5FA79B593A849A1930456F39FADE44B583CBD7EB4CE058056DF38CD0BE15205161F53F2C8681CB9E00525FB59CFD86BA1AE81CCC1636DD69C81EF620651606326A41DB9B68827378C2EC238E9179C02965F938A2D0AAD893C30D27267E416287D7DDEC314A79402A769C3D953F0092EF4F8B595F8", + "sk" : "77F83DF8951068A026BA38B5E53487B6D6A39B69129E8B45498746D529CAC78B4E9437565F39083AA50AD651B2D536BFEEFB93F7AC40F4F4100B231564D4880140873D1C367DA759B54C5CD9409382EC3183766A4BECCEDC375DF891C75D4866AFEB0ADA4A161386B698BC63B5850CD3A1801A4A80F0053251664C7642971E0A0F415A0CDA2C660A052A7876A5945C172FC87D8D8C9D06C9C30357CA3F8964B9B76B4544784C16981B075BF49653FB520F99A23E2465789E6B5864B969DF900FEF3C80E1BB0E12FC93B6CABCDFEA9006E638F265880AC630823A0678C29069284A16020FF97404E6F4B2CEE5CE8434B869177134F1AE861784B4F7332C4AC89CF8C36E7BCE1A59B4682376B33300B7696E3BBB6B301CB3311934514BABB29A187DB5A4A656BD02D379F40694A6F1B55D1A08DE840126740F14BC994DA75F2FC3BFFCF88FBD9B88F21122DD6B5EE5C2393A69803CD5CF67647E78B94BBCC81355E938EEA2AAC1053675251DDDF380173316970CB1990153C9A0889C3CB05715A02597BFDCF925949873558BA5CBBC8782E57B3720959C19A21BC19C65A27599F32B0F91835C421EEFCB3CEEDCA0B02659F4805D1A5CC916E2B46873CBF6C403E97123271725932B3BB40A0DE7B08FF71919B249339A22585CD99698DC1F3413B15CB09142EA1A8D8B0C1F64B1B6FBA5ED3068CC262D2067686276C302B20111CBB602F29756C32279DC578E20801D2A3ABB762640409B8BA349CB72C9D3056AA788B023F15160832E100B7E48D14DC4B81229C744FC20C3A94918E78C668F1AAF01BB8B202A3C8DCC0F63D456B50461C44101A6338C4B7C725490AF0563968A8184DAA8720BB36DCCA4AE3B3BA26927284C10093C079A4AA3B846A811CE237EA9033541D91FE5308DC32CB8BCB77B064BACD816BD8725569BC85CD7F63D34539C14B56534DC516F1500631A59AD1B985C77C262A0B70C3A14D9B6B81F2C88432568AE2A7BA32824ABE9866738ADC1761293925C694428EA9153FCE0542362BE09154B4E06B8A60B57F96176843B2764C3B5F55A1738B71BB2C87E371AB7A70560C245AADEB9742951959A25895D40B453376FDD844C9126C78F3A553B9C9B9D43033EE8C6AB13348058589EC1523321A823D32A97E0BB5270672E9990A0012842C38F3212101034CA8A863AE632B53A412537A40928C503A71B7B095163E222A757F3713157B8E8E369F2E2688D50728EFB42229325F475482D167515D2656B1C131BCA452892C39B8B2EE658816813BB66A0B16256271F8A23C7C0B31A45C4F42551A9A15E87D507D0547921A26BEF229265B24BB96B008DA638727615C8686F897925B6F27ADA067736A7949BEC8D23778708163DA61C68D806067BECC118785EA432A06C3A99F6648341E80B1C5956B650AFD100A63474A32FA53E2A9B49AB935FF4616292D9278E839A70BC1CB7A61A49855216D5BD3C10774836469B48496F0590127850D20C52125150E25BC8388483847C92494C0B48E66AA8805AE8C3A0E7C5AE3EC64BA22381EAF7AC28EB0B76DAAEBE0B6B6E28BDD478002359C79811B2F47A3C45D938C2690CA38A7A2411C223855BD7FCB83D614266251E76684418F81E47490CF733359BB77D86B1B949396BAA99C9D73485E378B6EDA76318B961948497DB54149F386E51648187C48A94FB603EB114A9408BA0D27F3C717694F9459DDAB7C6D51A58C50A79BC072D7717781A6B12073577D3A89A405829850AFF65023A771A5F5456AC5B3970D545043A2254178375268ABCA9A967F50DB28635B1D01E7D1969080438368A4B61F63EFD82A811F63909AA48A055CD9345C09191ABEAAB8237696BDF3512B7E8625212BFE5500BD7002066357954344FE361BE074069A520A470EB64BC0289F85C981995141A246EE3C6673D9026B7B490A82819EE1825AD39284FC41A01C936D0280C4C681D62E47DE8E339FC0A0F958B279AB95114209231FAA8962754B12A22EFB67ED1C42E8C144F74476F552A297E7573A81717144648BEFA3B6C6096F428C10FD925BA86B29C8890F2750D1E7956664A714FCC00C88A3CC259B503D3CA39942986D19AB6D76378858D679CC61AB40EDC5A007D33813698A6AE96ACBE95474B188BFD3208C885179DE868DD027F12256B9FE84FF460B180C7655D514168C89A516BA4DDCC56C1B5325C9312E067949A57178251158EEC2FDE69BC9D61BE726338830A86E8E525EC00152CDC0E86473E2B54AB64790735C3A945CC83B999352AD2587FB67DCF2C9FB3B921DEAC54DCCC8201D36562F64831C8129E67B2AE78BFACBA95F29C3D20942781E090EBBAB81BC5C071B0BCE826173F0CAD6C101518B56DD03A8BDC872D338225BB16128CA8C7212867DAE513C971B687297E4C098FF7C478F841A29DEA278D1BBE55423321372A44937D2ABA34B279C99E8847C5D4B51F54143DE991AA16AEEAB267386C7F286445ACB87A98CC93029658BB0981048876F0884B526BA58F201257A2245849A57CB425CD2CA92A3CBCBF963A4F360E8616C082D8BE4820323DF715BF5344FCF85BA070AC3068AE91989E61600416D7CC28CB6D42A461DEC083F6126C749CA457146D114C84FBC576A7DC8F9C2C03CF4A3CD2535A7A396F59D73259654254E5BCF616B4970770BC8A3D030C8C61D93EB08644159414DCC6428BE73357531E50BA72B5EB99D9380BC4802339070366A19760C0B15E32A48AE0038453527B10C4AB6B1AE8497F49DC47E25A514258B5C0336A812525C5A86E22D73A9A8C3DA5E88A468C3439464FAC42491B0BC91CDACE7CDB15166A01B62CB22B745C38CA32A9727C8C57537C72563EDB4AA2B400B778115B36817F188E659B2BF7C999D108C5B2D252F6A3BB78737EDEA48C9BB91E917487E4E6156DCA609AA97BF47BAB00047602F296CF611299510B195BA59AE7BC245B8C9721901995B6DF4918842017945C330290C6BB3C46D9104FAF014DB6728C4268627F8C884BF52E011344CFA795F864A474F9C015AB09C77911A8A52C1AA46AEED6560D4BB1F3B64D65028D373AB3D51A450E600A239767AED9CF25B5C85FC24CC794162EE70E13D88FD3459CB37A92D348A1956BBA09E24513D5A5FA79B593A849A1930456F39FADE44B583CBD7EB4CE058056DF38CD0BE15205161F53F2C8681CB9E00525FB59CFD86BA1AE81CCC1636DD69C81EF620651606326A41DB9B68827378C2EC238E9179C02965F938A2D0AAD893C30D27267E416287D7DDEC314A79402A769C3D953F0092EF4F8B595F827B1B921723CEDF55FE756FF5FB67D555296C6185D171ED8BA01393D1A7350189508257A83CCFFBD0677795070695CD40D7B7F39A891D25E7E208BB9D65AF538", + "ek" : "CF6C5D2C8A48E3523D3A34AE7FB7995DA8CE7ECB5929D98B69EBD8FAA8FC58AF5E0F3DCA9768D5CA2999F01177914DA8F6A7ABF23734EA5B00578DA9687C412D949DEFDE6887C3D059479C6CEA77F20AB85D0B9624997A9C77F66227C16416BBA2E9035459E25C88D192EB213B49BBFFF83B941D601F05996159BD013ABA0ED5496BD94BE804AA0297F7496D12B156C5FA30BDE9587BE66CE182C23656B76742DC25603B9D67E2AE2C25E0A6E22AD331DD0C609046A6544D4A1FD9089BAB39F55CB918BBF64EA695A0DCCC49B520C1D897A7492CA63280B8046CCFBFD1B8FC4E68CE21138BFF346B6C3BC15F64905E2733A66E4F724037E2A2F9304849DA7419E4F0E206FCD63C0EA071254B5BD8342D0D0FA8BF3A3F668AC9B15FE042F42290F8C44E17F6F2AC5314A5FE4A94CDEE0509889D4C55939CB416CEB404D01E6E565BFC13D725D8CAA88566D0AACB06C5C09B7CCB80CDF7A52CD421E32DEDCB87E8312AAEB0F4DAB7B83672680FE0B6E7C768CE566B0A9DDF30729D5CF71195216B607A35D9A28FCBCD311E4FA3269475C81F4347D44A2FAFED4B89194C89C2D6FCCC96DDD003A9FB5A22F8CF67344E199911F8C6B02D6C5DBFF116428CC3278A40FE108810F9D2CBFB3A47FBAF8164B5D126C7D299CC681F278D46A91F30188D403CBFDFCFC85B389385B89DED3DDB558D0D663969A9CDA8108D62CDF334E3AA0376D038DCD4FDB31FA8597D16992F6E22D4706D1A3141620A0A76F959A60A50B3938BDB51A71B6CE6F8E87E0E2A703CDEDAD0B790487FE449AAE7C67491D96BD3021F33EA39DD80287ED19FC94594BE9370B2D8A8664F78DDD84E2A2868AAE497A1CDB4CEC021A3F415B286CE65EA2E79436FA7844199EE1C649AB9C5A44DE6F8AEFCE67EBB4FB9F1FCCB32A6ADF5D7A381B823A8B014EA5849B45A7C4C97610F77A3CF68326635F869654191688D706739EAEF12E04BE5FB3AF42B681AC6E3CD6436F957CD991583A1B411508A6A7F354270EF67A1E4D85ECE6EEF8F436A391C6B304AB0BF2331EF085EB9931328BF5F5E9468EEF454762114BB2358530E48DD0A962E96546654508A94B1262549A5A96CFFAB493CED7D727C2FD9D911850A1EC6EF6BB3A9FBAA809C12469CD5D7E03652098BEA24761C1195000D1428BFEDB44209AED38BF03B18199A392D7CD73333C90E20C8E689EE740E59A4AE4A445CBBEC6B66776F147AEBAACF3D3BD4538631BCA92B8D82608FB0F8136288BF34F145493C865D11B2C0655DDE49A87BC5F8F4AFCCCAE2D26583DFDD0FD1CCD13D05BA70C090DD91CE1B8A60C1FF9368AE743BA8E41784773C355FFAC69D5E5594058ED22F7F000BD5C909026C69C158BA5BABF16D959387C9E4A99AFE49FBBAE98B20EBA9621600932C5BB88F12EE1A468AEBA1F660DB0104CEBE8D3FF87CFE7B331081DA362B6466279BA4AEAEB1B65791DAB80F85A3CAF8E4696A8127AE3B9110B0E5BE136629041A8B32E758745DDACA52277B0221A57C1BD23130F9BC38CD6CE9", + "k" : "6CF641B3F23732B49D5A2DBD88521ACF90BA637898F5EDD517FA4F5C64879573", +}, +{ + "rngSeed" : "6A85A61DD08C0733FCBC158ABB49FE0B0D96A50DCCA140A2E9F5A254F1901985844613B1C656C0CB0112620591B88AD0", + "pk" : "776B6F121675622857B8B376D708B2A861306FE931126822E2E8672FA0B577E8CA3F16495AF10AAE456A734368677A87FD3C2199060DC1993690C1AE2B76959664A1DF6CB2B3738B294124918596B0D69394EB1EFBA83895D0A7F3081EF81769437CB63B726D4236A65C87C3929B79FE34438A8931CF2B889CF100747CB58D373491E7CB62DB266BFB3B7E745500FA418EAC8CABD966DC388D0F1B3FBA850BFEC8C03A29182DEAA5EC4256FB3B436F429CAC87399C61BC98497A3ACA07CEC06A128231F945A4A335AB6D1A54A9A59DB106C0FD61360CE8870D1CAE99201506C9C96D4969F4B487E4D87BA1D45ACCB5A754585F29DB0991376150C65927B20C9EB421366CC840D528734C8B4F1421FE30C99F4C55F1E25D18A1B012424CC9F6250064A61C1B42AC243B6C701E293055A9EA7C44855E575CB6217C381DE770CF461040C20B2CEA6C2A921C9BE483ECC2718DAC01C4A5A15B60BFD5222FC988C60B23504919137B1226D7B72FE4105154711D25790A9F64C95356A787058018CBA996410AA4F29A62B6CF77439B5784B67390B96DB77C1583BAB490719D804E79B8954B948388514A7FB78EBBE7959599CA374A66558A8FBE7AAC91E8A62AC623690A952E94BB91E64FE57AB4DB066867ECC9EE027163A8010BF901489C10EBB736AE619DD0177FCD060C4657488BC50044E4C895191351CA72AFF9698577BDA5536C3FA75F0D9B586822211CD88D686CA8921CA65BF8081F8604277839CC9757653A46511876F7B98983FC052BC088BC85A686AB6BFD5C2B91DA8AE210313949191D13279BE375D3D3197FB01808A76CAA8A843E178D0DFC116C041030F2047F4B35C0900498FAB680D45FD0710D75226EDDEC6388D56D1C2263768603AC0BA9B68A21173704BD25B6B5181405029CC4B18C6446B5AFE5431F0A26BF50B2F33B0AA4032E9F28AC9FB58ACD85A670F393351B33DF4079A5533C44A94E968B677A68931491310CD48EA1213DD416AB650B3294F06F91AA5004F622BA173795136EEDF91598153B8D2935ACF33709A8B33E4B32384BAB51FA69ED123A4EAAC726DC7041B486E8AA3641FB8D48F908C27866753B821AAABB9894B504F845FBEA8766E82671506FF5B5012765A6A7B08F9FD3C10357523FB423E02024577235FE4694349C1188B1AEFF482BA7A15AA188A8BBE7108CCB7AD6A469054A45C01AAC131C6A7C4ACD5C050184CA77B8466B6D1992DE80242454169A33382972760DE2B69C3C000B900D25F2CF4731224DD9A2B84562C15C04D3D1A9AD447EE9404888141A7DA3A522F90B9071AD7AF54552D0060AF1A66A31B9457024A46B3FC1038A7C54B76053909AB07EB36C1DFDF897276B465155AED0E70F9A4B9398E54D267377FC298B9BBC053B281486F8436017C6D98B3249C167B17358C134299AE17426BC9F067849D7C55541A205C1359A41D7A5FEA37E758A0893C18226A44BDBD27E0266096DC20DA357C5D1A23956B796B305C29E87718F65B8331888CBD53FC2FC011F92C6F49C7F9901A5B17059B81CB2EACA2D348A22A91105F69140D122BF59D74C16A840E4B646F5E1CBD921A24A60A0ED6CAD243303A1448B6750B4E451C5E0E41B3A12A73C36272ED86537F1D2F51A0E2B5B5847B0A2D9BBFF0A051BD5227600AD", + "sk" : "B066BD9303C7BB0C4A4A01812CF463CB338CDFE80953FB0C90D2AA7A2C1E110443D80BA64F6A435051083AF14017F02886B63C8F0BCEEB544B86E74E85A16DB9539DE52C76A624086031C0A9B84380D02CE49B0736E2277995A63C43A2ADA9A60883024D50314D919C98E7A4F34C167C830C717693FB4A2F4AB1C684BBA76365403D6B3B27F76A4D9570BBE73B09E32D45B6B89616BB014C5FA995779144107FF6AB3B523EE121C3CF601CA7CCB13C7783EB8702D34695C686298824884C46012C16C40576497314A0D60675FA0B1190E13A816C75543C9E54867F9FA495A4E43F0CC964EA4B19C3541930E33A63750105149484094D30A28C6EB73DE702238E09272CD0415AA3B19007C90CE6407A864703D9A9F1FA3AAA762E66736F7F692A7344AE84A544B6B289C2D2187D61AE6EF70122D180CBBC09A4878CC6E4B71F1962627746A9D33C0B7C3A78048AF6E811A34943FB01C5B2A248AB256C729A8AE2A1CAC87870BC880BEF16BBDD0724E25A0257C244C2A59737DA52983CB5EC02B44FC0BDBD40C8882470285654C61BB27A9A9FD0162594343F31307CFFBAC216481CAB73BB215B73FC96507BEA727E5505E31848306C6647F7875D708FDB57C2F5A428C4D3B462122DBA423251B5AEB94A2C034C025C0B39FAB66B1C10B01441B9F5D9B736272718B44894820AEE4C5DCA164080B4774CD6AF8E7C5218065A6D03917F215D2F6595DD13141C9505DA959CC10BBEAB184396C2B552DB0C9C7A878A10A63AD920C19C9145C2CDB4556D823CB6D1E48458D72AD9886DACA3BF7265B4FED2B11AE1A8B73A1BA62A3A298C339F01CF70D7118A094DE950723A9B0E837A74BA18A92410228D0803DFE49E740AC2BD50BBAB741743795E292616999033C7A18765648441BA9725BC1B6275484741A625A9AC0516980B903FF40C58C348940817A40BC02B0F7487FB0A09C3EB6BCED56580F09EDD262EC2C251A0FB303E33202D27B509B31EE87304131518B0E17AE34158ED1565CAA77013A7161BF1CB6159841F8566A4A8A0C6823892BA94A541B18DB1A68C9A3AD1755A1648BDBABBAEB8C8BA0A105EAE48CFCE175A2070693138CF6CB3C3B09C2285540E83B2B5CEF51E634B5902AAAC61D63B5E72069EB52A977A3E8B442F6106C13B1108EFF9CE87D387640B3EB1914E0587298AA10CBA2B09726AB542E2101CD6620564B1ED8945C60C674F2233236BB744307AA7DB84ED11CE1D01AC0CC9B86F463C13197C7C1AA3F443CB0EECA93A817319BC45F9A587CC8A2EF05B0EB2998AECAC2920387695E154831C96BEB5568D880D4E480087499F0E818002A7A2DB2B717AA39B2FD755C1C7678CACBD5AF344AD38578A894B9D795FE65B701D3A6322F15E501610C6CC1E6FE90CD5048C93B80632FB6E18D70ECD44B36BEC3EF955813D338F3AF7331774962A04318556551B18930F91B3EAB4464572B39F996D71E4AA3B7179B07B7717C1373194CBFEBB4DCE5CABA80A7A7BB5AEFD069DB471BA0641383B0A006978B3BF5BB14348B507A624FB44C41D4C8156E2765069281E2836A7859BF3473B10F24C8D371148077014F1268824859A82BB548C25ADE15CC60128A58AB4301032776B6F121675622857B8B376D708B2A861306FE931126822E2E8672FA0B577E8CA3F16495AF10AAE456A734368677A87FD3C2199060DC1993690C1AE2B76959664A1DF6CB2B3738B294124918596B0D69394EB1EFBA83895D0A7F3081EF81769437CB63B726D4236A65C87C3929B79FE34438A8931CF2B889CF100747CB58D373491E7CB62DB266BFB3B7E745500FA418EAC8CABD966DC388D0F1B3FBA850BFEC8C03A29182DEAA5EC4256FB3B436F429CAC87399C61BC98497A3ACA07CEC06A128231F945A4A335AB6D1A54A9A59DB106C0FD61360CE8870D1CAE99201506C9C96D4969F4B487E4D87BA1D45ACCB5A754585F29DB0991376150C65927B20C9EB421366CC840D528734C8B4F1421FE30C99F4C55F1E25D18A1B012424CC9F6250064A61C1B42AC243B6C701E293055A9EA7C44855E575CB6217C381DE770CF461040C20B2CEA6C2A921C9BE483ECC2718DAC01C4A5A15B60BFD5222FC988C60B23504919137B1226D7B72FE4105154711D25790A9F64C95356A787058018CBA996410AA4F29A62B6CF77439B5784B67390B96DB77C1583BAB490719D804E79B8954B948388514A7FB78EBBE7959599CA374A66558A8FBE7AAC91E8A62AC623690A952E94BB91E64FE57AB4DB066867ECC9EE027163A8010BF901489C10EBB736AE619DD0177FCD060C4657488BC50044E4C895191351CA72AFF9698577BDA5536C3FA75F0D9B586822211CD88D686CA8921CA65BF8081F8604277839CC9757653A46511876F7B98983FC052BC088BC85A686AB6BFD5C2B91DA8AE210313949191D13279BE375D3D3197FB01808A76CAA8A843E178D0DFC116C041030F2047F4B35C0900498FAB680D45FD0710D75226EDDEC6388D56D1C2263768603AC0BA9B68A21173704BD25B6B5181405029CC4B18C6446B5AFE5431F0A26BF50B2F33B0AA4032E9F28AC9FB58ACD85A670F393351B33DF4079A5533C44A94E968B677A68931491310CD48EA1213DD416AB650B3294F06F91AA5004F622BA173795136EEDF91598153B8D2935ACF33709A8B33E4B32384BAB51FA69ED123A4EAAC726DC7041B486E8AA3641FB8D48F908C27866753B821AAABB9894B504F845FBEA8766E82671506FF5B5012765A6A7B08F9FD3C10357523FB423E02024577235FE4694349C1188B1AEFF482BA7A15AA188A8BBE7108CCB7AD6A469054A45C01AAC131C6A7C4ACD5C050184CA77B8466B6D1992DE80242454169A33382972760DE2B69C3C000B900D25F2CF4731224DD9A2B84562C15C04D3D1A9AD447EE9404888141A7DA3A522F90B9071AD7AF54552D0060AF1A66A31B9457024A46B3FC1038A7C54B76053909AB07EB36C1DFDF897276B465155AED0E70F9A4B9398E54D267377FC298B9BBC053B281486F8436017C6D98B3249C167B17358C134299AE17426BC9F067849D7C55541A205C1359A41D7A5FEA37E758A0893C18226A44BDBD27E0266096DC20DA357C5D1A23956B796B305C29E87718F65B8331888CBD53FC2FC011F92C6F49C7F9901A5B17059B81CB2EACA2D348A22A91105F69140D122BF59D74C16A840E4B646F5E1CBD921A24A60A0ED6CAD243303A1448B6750B4E451C5E0E41B3A12A73C36272ED86537F1D2F51A0E2B5B5847B0A2D9BBFF0A051BD5227600AD32A2A1197D78798BBEB13CE2E92CD7ED94B410ADC37B1B31DC060AF11FEC8A8B24D67704139CB68EDB8F14C5ECFFCE83828208EDF58C0F494FE3CA22CFDF58AE", + "ek" : "7944D66F98DBAC3919E0C41239A7A39031DE64E47A9E04CDBE7404FB0AFC620F071B06DC1DA166377F71782920448E0240F8EC63D52B6C92902025F49259C9603A5F01B23111F94CC879FFC562E4342272648993C0F4BC5E12A02AF4355A30F8A7239958AA9C4300809DC4F5565BDFD9E4405D381618104D13D9932DC5D10CD622DBE954B59D867B949FA61F0E84A56D2D7F13727114B79AAB7E29F7A30B8C1AB1700EF4C13982EB8EF01B6AE1CB9622C06C3EEB91CB7A8FED460CDEA9233BFEEF34AABE1BAD42D0F20FD16F06790775C3924F83F95217536F3AECBA3D6C4DF64BEFC149ED16698D4012C6BE4946CB3FCF539733B7C9FBE2FC9651E3799AE6AA3BCF50466DA8859C5847A997BD13CA34EF685EDC00B4527A644ECB60F738B0AC2BFE917A97AB723063C2F616B2F9D2272D04978CF013BA2CA719861D91C14C292AC589AB00C46D73F07DDBC08EC2FF1DA3C1684ABD1FAB3AEB3133EB9F1059B9CFB060E177156E7244840C45BFB6B420DD70768E89C0C8ADCA9C5A96C1CBB3B0C6A50623BFB487AF770A835560D5CEAF6E956126BC3003F0336957299B9FB9F906A25FBA67E53F6F0E4B2C0B54D659C96E7A5E8F9F36B7D8F3D194B1044E6668441A61E29D8A8868EB94D4374291651D46B5F025AF292E57EC98C7D2C0CA192571DBC6D1D1409FC97369D62654DE7C6CE739235A89CAF2EDFA479BE1D980B900F8EFA714D4B8ABE6E311E9E544802F79C9236692B43E6D1C030172AE88CD9C02FE1B979DD8C6EF3D6E16E4EC3B386FE53AD5A01D9894CA7C10C0DA04E29424ACD6DD908805A196749C14F385AAEE5870ABC9ADC5D04070AF86921C4B1A72A8EF7E61FF26A1A72524B3B06AD61A46DED9536FBA92D4E62FC1E75280A0203B8EB81DD9AFAAB6FF150275760E939743EE36DCB1AA563F89F6F8F2FB4DC84E14EE73B93D2344B0072EA57FFAE6299816362F85FDC6C793DD50067809E3CA9FAF4E93C293006D3FDE37E038C77EB5080F268F55B145F0C81385764643E6E09D612518954FA2C3C606328D9AACA06937E36E8CD3D113689409BDC72FF502FB5A9ED6CBE13B56041B8EB0CAE8BD4EBE2C6AC4A24738DA00E8FED57CE0D9B97E02B9B1C00F35D37FA45080AC06265591F7AC375230A43FE1F41434B9C6D12FD40E155CA58FBBAAC197DA75BB614AA665737FA27FCF4DEEEE83B53995C6E53D8AAC6D608EE50F2903D70865879EA59B33CE86197A0E4BB9682AEB91CDF9450D7604DD134674FA6F2959F275638CF540C4FBE2E97CED3CD8576511BF70871287CF9A0AFA4B6E25085C05BFE74504FC49FEF9A07AF15F4F9B0AE954B23DFA5B0C1080F418ED8F885D6CF6234F1CDF2342CCE702196C8B8F07B4145F60695694B2B6DD85A1EC9747FEF3E7D181873D3AE440119CAB1BF17265653F7ED3676992A71D4F29CC1AF6ECBEBB72A5A499B3F525A46E802DBD750CDECCB4D0E3D428B11DE3E389382DFE4C43872D80E31DA1F035081C5703F667CDBCBC8CC3A9EAAFB08D6B56A2721C", + "k" : "6E71FB3CD1C437D8C81F0C760A495C554E72136CDA40FD8E9A4B505CB9BCB932", +}, +{ + "rngSeed" : "7F4A56EDA151E7B097CFB8EF980440FFF707AFFBA91867C89522CED6C5FF3BD7F5F00BB49DDD615D9361A7E4EFA42851", + "pk" : "A6F3B26CA06AD98A9A6FF2122B8889BB513558FC1A8701376CECA1F7D87A53F78F953AAF9F977C2FFB4D04F88E33E0BA7D83BC6FD27914A769AE382BA5F211B2F59F0001CA30B0A0EF138ADAA485953CB8B6F6CCB56A7C92598C0C83AE97684C26D70D69210C8DD16AE08C4B3C1C30110A581669245529BE92D38D9CECB10F22C83D01B3B3660FAB4662FC559F48041167FB3E7960328C612A7E99A0C546B63B1B04F22B78B85074E6D32F6E04B096EB89DA611F30267BD8760E05C238EA2A587691181112A39C88C528977F0399CDDB7A7C8BBA3BA71507B3DB7131302407052CC4E8125E2BC035172A967A21A0582A05F8AAE28228DDCA417545144882CA3D644F6167BA30E91368879EFAC5971C8B1A7A9674E804C08E506ADE53BCD778C1AF4637584B9752AA1F16A4319D296B93E5368C10863A85CBB55C11C56338285B21CD740695757ADEB2CE48B7C658A36B26B670E59947A0D94D022284BF0995D56666BD7968BED8858895C779A3318275AFE42488953791E97CBD6256C29A6C6E4339A15D7A7C3DA95EDD2A562DCC2F6FE077CBD2317A914B975692AD1C3C3D956B26634FE1D2235D66226BA766A447BC87E8674800CD898B4B02C491658B97E25A4F836AB98A99C669B60AA4C30518A6644FB048A4E34822782644038AB04A3815C61DA99816EAF388E495CDE4A65C12F1BB5F02A1A1B1CEDE817952625FD2502F2A4B8BBBD4123E71462EE433AC923583C830CC54129BAC51F96846D8FCACECE9B19F6063734158008342C6F48234D24571E5777074170AE24B20D125F1BA311F4B33CDF91E3A2305FBE12E44AB54CC8C4EAF8553F697C00E8040E858569120BCD0166BCFE1A66E2500C3AB8ACF3B58F1309C68772154602BA6C0968553CA553252D27A0B05733D81486D86C590291A643EDCCA9F8470D573880D5856A6B2CBCFF2803713790D17297EF11549D5412713A3E4206B1B7C85483192164209F5B32F709AACFC4BAE51F180EDEB7E999ACE2BF98D958514951362B08A6B529A2A7669C5492C0A61645542BC1DEA0B707282A0797291B8C7A510884F12E92F3200AC5EE91686E109ECF245B2672F94C0A4525B7F43FBA328099BFE4330888B186D026231D2B2EAB7B971BA7680F0CB4653652F8AA8B4E01BB77461D792CD5E941A31DC02D52622B37C498E4169BC0418E23C5D32999726462D3A0A6449918B18DB487F422849B67CF047BFCB0C6945BB87CD779DEA915B64AA0975D313F8A740DE77B0D40612459C2EB73A3FC876AC39C821A52761E13115D87BCD17052FEA2B98D9D83ECE9B1DE7124C9738C0DF539045279EEB21042A13791FEBA9D0E23445293EB3C2C194B76C5FEBB5582220CA350ECA9B90435372F3C5BAA0549FF847AEDB815C244B27DC5866B151041E884BEFBC7BCCCA2FA098B592C5AEF7F53E0D712BD2119214C15F8AB848A1864705D0511C50A9942535CF06952B0357445A9854240C026733AC8A39EB3C8BCA2939D195763A572353DA2956799448570A21D58623635F7A7461A913C24AD04D1495C1EE42C88B82942012B2D4B410FD1907799623F1B373B9C438D2B4C3FC48C054BC5206273F7A9A3DCCC0AD8D40070EF20FE4CC99C8394ADF63126006EE8CBB821B12A2A0A3018C4F8E52A50183FFF79E84C69427", + "sk" : "024755131769C7169F4B3A0B89F81F45E6A48CC2CB0EB87BADD4AB94E9BC67E85EAD80158C390DAC09C40A6A8DE8A95B21C5158A853442A908278A6EF80551A7C16A800242C7086144444E488BBEC51C3CAB83594BDC2457F0152C43A9577C51799CA7B03C9CE3CB4F5C6564792AB8201A3B8304CE4D8339A2171700D7A6EC1A03C337B639F7C804A50A6F41225C1143F9D8AC9698A3EB126B9DA000BB2137489A165848865B487051B7665640B2E5E2B1B4633583589F30D4572306614DF8080791040DAA0106633A26237A244B6A18920D87653E8B516EA895A1F75BBFA912742BB540006A95AD20B95471CD4C282A64A36AB09A86B1F90F44D41753B0A8CCA50D9780351F253A691824C785AD8BE9790D48643BB4611792905E5B80D2717369E4786E5901C43366A14B3B423B11139349C9107FE3F55958FA8E4DF6006B3607210B525304BE6551AE57E826C913CBA2503260A9493BBB3CC2319D791226C27A54233C48E7084EE9EA82376142BB419CFA6C0F51426CEC39B554255F56B1CDA42B4AC33391B08172F7A82574B6943F6A79AC51A5E6E254A0A5C80D46538C03705705ABFB2B3EF63A756AB8AC03530AA6CCCB005A05D73B687D45529EDBA35AF03C411592F652C8F1131640B943629806CB21482F8913F436A06DC790B89B2F2A49245A51A26E107BD18624B51B406381CBA1AB3E8879C401A30FC9F0C40BEB557343735D0A44BA150D4CB404D752805085892B709F2A97ABC413C81F7A1E14811745878D66E98F1FC176E4A3CABE60557E104D24733668985EF15B87E78B57D22C4464EBB4B9EB1B124B80C6328C3BB93349359777FB09A19C1F7DE48274FCA6D91BB51A97C49C66295BCC6C53933E1F327F2037C7BF9C80CDC5406FAC0A9F067E7703A0AA79AC0EDA8C14E4C7F6B05D7FA84CE9A487AB489227910D86B0B6A3A91E21EAA9493A986EA773AF7C16CCCB3B059AA724A02CF936A45730AA93CCBC2B3377014350CEA39C36908F5167B08001061867C603F6CE64B081B2E46B1985837684B5E3318F4531C13F80277A35683CF599B373136EC3977AFA12E1D32085330C0A6828A57C2902AB0CA679C2F7F9A844091B87A4754FFAACCFF0C50ABB01768927AE0B2EEA885B54E92DB59533AE6A6E9253C18C9184C1127220775DA93C5964845240A7A3795B5DF5D00BAA34393D3009E641828C86173CCC1A9F9749A0F9271867B2D2A364AD7335EDD1C02E131117A93B0F6113DBC9AC36924EE63CB954B60A325971501B3822732007629B00A965537C3FC07791AF7A0C000446D15506C8404DA9676A9907969D40627A18448F353735706015F05005403AA7A7B79AC7C5A3759B569B8B5D3B86BDA01C4031A1F4E45CD663BAD410123A973B2B6633DA3C88BA0A26F0347901C6236CA76E1266440ADB415FE5C7ADBAB8F5D8B3DD5BB4F88C3A1E450A4850629166102471294FD05696A54F516A0263E31A895010DC034CE6A72F6294A3CB6120D59C0E57827133A2B53F40B0D5F060E9480E77EA39E02A48F4327CB066BB32D2289BD97D10EC6615A6CE06088D6F63391952C89AE8BFEBC43B554AA5E4B6A87CFA9E5B457C581A437422C48AA35DF5C939694737A6F3B26CA06AD98A9A6FF2122B8889BB513558FC1A8701376CECA1F7D87A53F78F953AAF9F977C2FFB4D04F88E33E0BA7D83BC6FD27914A769AE382BA5F211B2F59F0001CA30B0A0EF138ADAA485953CB8B6F6CCB56A7C92598C0C83AE97684C26D70D69210C8DD16AE08C4B3C1C30110A581669245529BE92D38D9CECB10F22C83D01B3B3660FAB4662FC559F48041167FB3E7960328C612A7E99A0C546B63B1B04F22B78B85074E6D32F6E04B096EB89DA611F30267BD8760E05C238EA2A587691181112A39C88C528977F0399CDDB7A7C8BBA3BA71507B3DB7131302407052CC4E8125E2BC035172A967A21A0582A05F8AAE28228DDCA417545144882CA3D644F6167BA30E91368879EFAC5971C8B1A7A9674E804C08E506ADE53BCD778C1AF4637584B9752AA1F16A4319D296B93E5368C10863A85CBB55C11C56338285B21CD740695757ADEB2CE48B7C658A36B26B670E59947A0D94D022284BF0995D56666BD7968BED8858895C779A3318275AFE42488953791E97CBD6256C29A6C6E4339A15D7A7C3DA95EDD2A562DCC2F6FE077CBD2317A914B975692AD1C3C3D956B26634FE1D2235D66226BA766A447BC87E8674800CD898B4B02C491658B97E25A4F836AB98A99C669B60AA4C30518A6644FB048A4E34822782644038AB04A3815C61DA99816EAF388E495CDE4A65C12F1BB5F02A1A1B1CEDE817952625FD2502F2A4B8BBBD4123E71462EE433AC923583C830CC54129BAC51F96846D8FCACECE9B19F6063734158008342C6F48234D24571E5777074170AE24B20D125F1BA311F4B33CDF91E3A2305FBE12E44AB54CC8C4EAF8553F697C00E8040E858569120BCD0166BCFE1A66E2500C3AB8ACF3B58F1309C68772154602BA6C0968553CA553252D27A0B05733D81486D86C590291A643EDCCA9F8470D573880D5856A6B2CBCFF2803713790D17297EF11549D5412713A3E4206B1B7C85483192164209F5B32F709AACFC4BAE51F180EDEB7E999ACE2BF98D958514951362B08A6B529A2A7669C5492C0A61645542BC1DEA0B707282A0797291B8C7A510884F12E92F3200AC5EE91686E109ECF245B2672F94C0A4525B7F43FBA328099BFE4330888B186D026231D2B2EAB7B971BA7680F0CB4653652F8AA8B4E01BB77461D792CD5E941A31DC02D52622B37C498E4169BC0418E23C5D32999726462D3A0A6449918B18DB487F422849B67CF047BFCB0C6945BB87CD779DEA915B64AA0975D313F8A740DE77B0D40612459C2EB73A3FC876AC39C821A52761E13115D87BCD17052FEA2B98D9D83ECE9B1DE7124C9738C0DF539045279EEB21042A13791FEBA9D0E23445293EB3C2C194B76C5FEBB5582220CA350ECA9B90435372F3C5BAA0549FF847AEDB815C244B27DC5866B151041E884BEFBC7BCCCA2FA098B592C5AEF7F53E0D712BD2119214C15F8AB848A1864705D0511C50A9942535CF06952B0357445A9854240C026733AC8A39EB3C8BCA2939D195763A572353DA2956799448570A21D58623635F7A7461A913C24AD04D1495C1EE42C88B82942012B2D4B410FD1907799623F1B373B9C438D2B4C3FC48C054BC5206273F7A9A3DCCC0AD8D40070EF20FE4CC99C8394ADF63126006EE8CBB821B12A2A0A3018C4F8E52A50183FFF79E84C694277CC3F47F319F88DA508F841E536A056625F206FE499387D27307257682237F96CE71AC90659FF2DD31B35C165D3929CFA5E94407A5A798C568E6098F631923EF", + "ek" : "C6279704058D0883C9024919E95B1031CC668BAD6CE74A8AB5317D354247F6034B7DEAD1768FEB3E2E08F2190398B5E056497585AF85AEDBDE2C505D9D1ABF4EF2B903E1E0C8BFC40960C01353152D7AAF6656CB68DA3E05FC8B85A32D7E1C2C6CDDD8CF63BB4C9C139B8D4CA664CB598B6154163EAA8553487DD59621A4243C4D57A473DFBD81B0BDDD20800AF04A3BE2F8119039943698012AEAA6CC0B937F9C9FFEBE6B0D592A2B0D9AC1FAD9619902AA35276CE2AC5BDFB61C449B5AA451CFCD1BC3FC87C099AB9B1D2C8C224BBED3DCE9C88131F8ADFCF48CE5418276A9BE35B74195D092A10B34B65C0D1C2F32196B765FADD32641187605EA628F583BEF4EAD81931BC0122B1AE8FF476C31D5528B90DBEFD9F9BDB5ED8FFA6AC22AF3BAE6E43B6D95D0720DF1E57C72655E73A42061B19F63188CCF0944FAFBFB041DAB8E8DDD5EA090E6C1727D57D30EC0BF21718441598F47B9EE34E43FE8453B5FA16A522791C2FCC7DCAF4E2482758ECB1C2C56E95550EC344BBE01BA5441D2E4F5DD4396C81EC30EE0D1A93680A1C22D01B4B0DDD78F18AFFFC2A1EB12C6C812552CECD377E79B670E104FF32A82DD4A0959097A2098F24FAFA3F05DEE3D2D61E1E650B6E054991238E583CE4BF97FBBB6C503D326223E406FE107A3528F9731F1572D54D4622273839FE6133E7378C408D7804FD9BC65647BCE69400BE3D63ED351D7D52DD2536ACEC7EC60DF91997ED124DA5A9F7A91447722EE5D2D4D27CCFEC2E2E50576C168E447BF10EA4E52B01807C69B89F47E032D8ABC62C34FBAA2CF9FC8BCEB1C55F86272AADFCF1C8433CB725C42488159C5EE4853E9FC644177B0C45FE884A15794258385FE7FCE0DCAB3F673F86530E2BF9AB2E2C8290EA0E36E27A0702F4D35C91B4E568D38C15EC86673DCB3B7CDC8E7F972AABACD5858DFB6A95CFBFB2F862ECDF80169A44C50A5421DD4BBF15B701A170A0D161E79AE741D1CBEDC665327A36AD064D1F6D55C63A4070619B7730BFE2FAE653C07286078F41AF2A103F0971566DA2FEC1813650BFB13062794148B901B010D7801B4028860EB6BC941D77BF079790BCC9311C48F2F2D1D40F4CC048931EF560EC451D13C89A6B18D81A9BC98C95AC304526AFF20D914A813FBA60665CA287ED7AC883B8EED057CB24A5DD4AEACFE7C466598CE6D0B118A148FF1A2EC684C449D7A7B4AFF426CD2DE10C68C0F121EECF471D2E80453DB117C6E1EDC73B65F09743AEAF4DE1F52B031B33FB33EA4165AB914BF659EDB6C537077C1AA4BA634324453FDF8231A4B5AD1A8007BA93AA3FA1092099452678ADCAA44C9C3D8CC2DA527BBAAFC4C10A8C58D8EF7136E806B15640E81BBC659620052028D4FE18B722A91BCEEBC1C90CAC98A54E949B87794972C1FBA1AB16EF7FB81C03D4F6C2CD8805EAF972A49031945FAC07F5A996D538891394CC88D0E97750899401D6EE634311CDDE34ABF112DA827C370D4E0A31175F16122AF0A3682857CD56DC667CF2B9668F01451F7", + "k" : "C877CB8C37171B72FF5CAB74F3C1B4253623DE5D886FD8C142A0639321CB2C12", +}, +{ + "rngSeed" : "09FC004519BCF85B20D25D314A0DFC79E00CB6262A7DDDF9C52473641AFB8CFA0F5DD5F53558184CAAE9EC34B459E98E", + "pk" : "190B29F6E7CC26755AABD20D4BE75F2FA4C18303319EDB00809152B33726B1E54C0F328C73C6805354925B43A6DBE0CADF00C9CE3B1D7FD9B47322C8B91844833250E0E99369E90C279AB48712B4E1C10C0456C754251CDAE4CB4599843510BE3A13277D775A3242A6232B1CA2979E6F260B3C4C86FC24BFD95255C765CDF6187854F0C9BEB8CEE6A8391F98475D6AA080A7A2C6147F70C2A9450901F705AB0EC23FC957619D611ACC2319C6042E137496F51436A788334AA5A6D561A3E3A0937A37BE9F7711C5FC6FAA1024C434CC3E41A3865BC0BEAA732C1789E7972F999007D4F7AFDF953163197590E757A297919766428FD18CE1D531466A55109287C335BC26F946E06A4D51AA27B220001A46C2F4E339DD83511D135A9621C1DDF1083BCC9B24B994B4A3394DF8CCFBCC743304383C300A9761859074A3D0E91CDD96A34513735A424238E71F42C328EEDB1CDFB3AD704A1667C15045C534C448B429C474C494C7B37114911771D62C39D3F4763D881C0A21C074201301EA0EFF13BB5DF861ECD882A0350031B2AF63572845950535E85FB323BEEBD613BA600702192D7CC1218309885AB9345EF32DFB757528229D73D57CC2328A5A86ACC3180E392144C04CC45CA57573395EF38A95674B28EA7BC8684C8E6A81865A93256517BE79FC456472976FEA2538BB8B52A188CB43881C19AB47069B36968DA1CACCEAB9BFC5C7985614A3FFF7300E621E4865C5F8D30792099D3F793E58B591CDD87CFA36430AEA876F30CCA5D824FA29AB2B56AD3ACA5D483C3C7EE90B4E028B7794592E1ACAE0FC721D355891C257CF821928104E1C994B8BC33EDDF70C3CBCB5E272B43B5777B3921892AB198B4132EA4B200618B1E4559064D491487B1F0135C9DA67A39950A5F13A1E6EB409C30957B04C645B052DECC23A391A7692390DE9085147C96C67F04EA8212C9D80CD00DC07B7D22826E01FACCA51DAB91413E8CBAA24A66A00B4D2076D58C398ECF03EE56C40A1AC03CB02658E6240C41C6F06C174F3414E258A11478C7A76E05C156C1B164903B22991391955C3E75BCF0CC70D4CB79EA27638C54DCDCB1EF35B8F3CAA26B0418F340597BED55D586981C77CC6093A889854A85132997BF706177099EE8B5AE44CC1F1F3C413FAB7A51254490A6AC4175A99DA866E5464283A74C5C300436AC1C7829C953128E5D17CB056AF07B08D7F114E0BE00F93854E09EB5E0BE82A5A4C526030468F95BD82E08C2147736598A656476E5CB855E0C486D1FA0C661202A79B37357995ED445973959CF04116ED0C687227768A41A1B4F79B8080A740F012DD547403A30A36E62C9F5A1659ABAE73A165202122A330C61F492822EA25DCC22CB97C00A38BB7A4A493AE677CEC267379C3A1B80AC2F4612221976FF4C7AFC685283AF88EF813A9BEB73EF380BE8A31C87135C6573C0D1D5807E63CA6F1418B947C1615233B911736B0870B766C9465CBB8B29573ADDB33F21A07CD890F1325C200545D5A21C5DA1A0082B9C198158AA2B82CD5D94BF5718D39BAC4D9096093C78A069B9210D305E9199D45AC09ABE6A8033C971B2903874AC6408B3510D318FF4B464EF16AD3E56BD664CADAB4CBC2EB1F13656C6547DB33B5F529D253C85A728313BD36B9F09F6455B7594A10C1", + "sk" : "2B006F1C2787D3F704935762FEB046F67A0A59163ED30C83B577CAF4667605730B11364A383366A74125DF3526FBABB7AA3916E9A05586920F9B130AB980B2A940109552047E231CFC7A9CE7987D3D218C52A11C22953722E861A1F000385AAEE23378C6372315E73315893FE0F027A44CAEB37CC796CA1954B79ADB22887B41B3E9C98A4C5A7101714F4CB78C9D3886393567016536A0706FA1C950DFB71AF86B91610509738B3F6C192368416B1213AE508439C8C9C4F5382F926C6DF08852E8955A04D5A8A30912C201483096BD202BA4B82855236B804FAA20EFF056E288CB699237A1E5150D027347BBC06412C972C0A783A1B794E7B2A3B45B7F842AD18B5520A143F4635059690DF45B1F99BBBB0F18AD5BE48006727FCCF41D400430973B8F62481B73D611DBD13DF47633C1A27B387398DC32AF9E71A40C84CB48F131D8A7ACF8D91EE2513F3F225A2D61B752E24A2860148CA68C3A75243200547FC054710293B7C7A939752959E6256CB29C0F0535055B18E2F78EC4DA0BF9AA91CAEB9B5C5150AD42A867C18DFF50B2A1E8C2D31951D5FAB52AAC7D603500D9FB4B5F516FD26BBC51A622751636D2C2BA24CA5C3AAC696EDB821B237E7FBC2414E7CF2388644FF702821AC1E2068C76D0717C40BFC47C7F96077504D5B9B2C7A187C0C746E904CDE556BACB9CBEAAADC865BA93D4837B42192B539E6DE749692916DF131F26C26F4B3C93FDBB33CC8B39D176A4B27351911B8B85B5567B839CC6AB5F65A3502CD994C812B72A2037E5E38F08EA97291292FE51185A603F94FA6FF6E247B8E3CC82A8B111DCCBFDD715D7458B3D984EF4A17BA7314FFA8A069031B28E9B858E22900D364BCD095079C4C06A515599443FF5F434BE754BAD6AABECE45A1ECC7DC5C95541223BF114CE60D663A3621B95826747B7005E94B8A84025FC43B8DC320964D2A610B7CE10B7C7D56C37DD647FE1920B876267CFC0607A35700CC51A3187B69C488D34816753607BC22B59AEF9C3BE78A2B7959BA69212BE46C9411A4C1357493A73A50930020FC732ACB44C036602C22341D5039DD99CC53333091E983C1C1AC47607B5E47727D1D8A313CA73E1B9C47A63A257E1A5C01BA55B802274BA8C3A35C8427C9130C71D77165E00F2A723DA6FEBE7A17D89CD6319718452BE2A80777F1469AC36356E73CA7EF420FF64661161B3EB459B33C694A6399015716D8D7B3B0669648D2331EDD6A9E54933A5447946465FC21B51C31328A6763829100D02C9407A8BA8BD150E540755E210102DEC9FD9A06744BA9476D0B6252CBABF718C4A917FBEAC293408531C46CE91402C91B10A3994883DD83FD0C97A952441FD6485C8C34F8116B1FD392F706150FA0867BD0078B0E32AC7828B6B61624677B55C18AAEB494794B1632E686338315C92028B3828598A4AC462646349F17ABE582440E39AB346052219537E909E8E80135303BFE731BA04CAAAC6CB89B3C37558243D97881587F45DE25B128F9568AC45B4E3F39DDB861CCB0749EC3541619B164163C77B7397DA453F57377C49C2A8A78C568E300A635612B7C95035F4C71CA174E7653AD15601BFA46BE017610240B045032453B51ADE516F190B29F6E7CC26755AABD20D4BE75F2FA4C18303319EDB00809152B33726B1E54C0F328C73C6805354925B43A6DBE0CADF00C9CE3B1D7FD9B47322C8B91844833250E0E99369E90C279AB48712B4E1C10C0456C754251CDAE4CB4599843510BE3A13277D775A3242A6232B1CA2979E6F260B3C4C86FC24BFD95255C765CDF6187854F0C9BEB8CEE6A8391F98475D6AA080A7A2C6147F70C2A9450901F705AB0EC23FC957619D611ACC2319C6042E137496F51436A788334AA5A6D561A3E3A0937A37BE9F7711C5FC6FAA1024C434CC3E41A3865BC0BEAA732C1789E7972F999007D4F7AFDF953163197590E757A297919766428FD18CE1D531466A55109287C335BC26F946E06A4D51AA27B220001A46C2F4E339DD83511D135A9621C1DDF1083BCC9B24B994B4A3394DF8CCFBCC743304383C300A9761859074A3D0E91CDD96A34513735A424238E71F42C328EEDB1CDFB3AD704A1667C15045C534C448B429C474C494C7B37114911771D62C39D3F4763D881C0A21C074201301EA0EFF13BB5DF861ECD882A0350031B2AF63572845950535E85FB323BEEBD613BA600702192D7CC1218309885AB9345EF32DFB757528229D73D57CC2328A5A86ACC3180E392144C04CC45CA57573395EF38A95674B28EA7BC8684C8E6A81865A93256517BE79FC456472976FEA2538BB8B52A188CB43881C19AB47069B36968DA1CACCEAB9BFC5C7985614A3FFF7300E621E4865C5F8D30792099D3F793E58B591CDD87CFA36430AEA876F30CCA5D824FA29AB2B56AD3ACA5D483C3C7EE90B4E028B7794592E1ACAE0FC721D355891C257CF821928104E1C994B8BC33EDDF70C3CBCB5E272B43B5777B3921892AB198B4132EA4B200618B1E4559064D491487B1F0135C9DA67A39950A5F13A1E6EB409C30957B04C645B052DECC23A391A7692390DE9085147C96C67F04EA8212C9D80CD00DC07B7D22826E01FACCA51DAB91413E8CBAA24A66A00B4D2076D58C398ECF03EE56C40A1AC03CB02658E6240C41C6F06C174F3414E258A11478C7A76E05C156C1B164903B22991391955C3E75BCF0CC70D4CB79EA27638C54DCDCB1EF35B8F3CAA26B0418F340597BED55D586981C77CC6093A889854A85132997BF706177099EE8B5AE44CC1F1F3C413FAB7A51254490A6AC4175A99DA866E5464283A74C5C300436AC1C7829C953128E5D17CB056AF07B08D7F114E0BE00F93854E09EB5E0BE82A5A4C526030468F95BD82E08C2147736598A656476E5CB855E0C486D1FA0C661202A79B37357995ED445973959CF04116ED0C687227768A41A1B4F79B8080A740F012DD547403A30A36E62C9F5A1659ABAE73A165202122A330C61F492822EA25DCC22CB97C00A38BB7A4A493AE677CEC267379C3A1B80AC2F4612221976FF4C7AFC685283AF88EF813A9BEB73EF380BE8A31C87135C6573C0D1D5807E63CA6F1418B947C1615233B911736B0870B766C9465CBB8B29573ADDB33F21A07CD890F1325C200545D5A21C5DA1A0082B9C198158AA2B82CD5D94BF5718D39BAC4D9096093C78A069B9210D305E9199D45AC09ABE6A8033C971B2903874AC6408B3510D318FF4B464EF16AD3E56BD664CADAB4CBC2EB1F13656C6547DB33B5F529D253C85A728313BD36B9F09F6455B7594A10C1BEAEB6FF178F3228DEFDD117E6BA75A34ABB70E86F31FDB16D74D91E6C1B47A74248FF45452BCE5777B08108E059234029D3309CBC2BCAAD8EBB37DCF27832F2", + "ek" : "6F7691819CDFF0EAEEAB51C81A5C770577E6EBEFCC4B9F35147400F84E399BB191A5156A78CB6D39CEB431E54445C4F3D82A428ABAA90F6C08B97271BFE1F5C37551D062B978602354A92D8F90CFF777AAA741A37993BFEDA17F654070A3F2CB2F2E8F56B7F2F8917FF4D594639D1DC5B0D91A75BE37D60BAD9CDF7946F919FA99F85B4C2756A86A205DCBF89DA31E80433011B38FA22B8B6E7E444BCD60A224708C1DCDDC12238725752475A94D4084E05D13348B2FB8562D3B994F4B5525648FE2F1AD11F6A20329C514823A4B7C8D1EB41771B312529690141D1DEDAE58EBB97DF27E686A1426ABFF185969CF0A6382FD44A8F0BAF115F65C3913A19036B6B3AA35C6FB379C4B32A619AABBEAB9CE7C4A532F4BD78E289B62DC71FDCFCCAC5CD175D1EF9C303549A99BBF119E2DAEC63CF9441ECD55B376036745E614FA38A293EF8BB9A8E245CF614DD27875850902F05B3824037E472EBB48374CEE0E092AE8D9619C204F2FC9314FB2211C7C599FAE6133CA161A4E2CBECF538C0A997803A352B15AB19766C45DD0B73C47047792E59A9F88C19A27DE527E8203717A0FBF1C4107A67EADE1D977B7AE7AE5AE5B63DD9C50A1A384605C38B0FD1C70106EC83488764739572E70025B21A404CCD7976C6017E735231B9E9C49FD5F299DA3735100697E9CF7E6A5A6C3BA1EFEB89F0EAE833CB235FDF2782609866664BAA564FDF00372AA070822C983ACF7B94BBE6E926A9C305CFD5C88D63CCFB76C88B0E3BDBB4A7E0FA58E1A93B2F8F167CA20B6814E2979FEB146F7A22C1104874A2D10759E797359346140359D1E77221BF169BC054DFC6CDD296E4A4E00AFEDF33F0432DA4F424850635B95DB02371F2BFB941CC0A261788FB119C8DAC00ED3290D47DF57605551DBB36F36D7EBB921BE7B539CE3D42D31649CF722619ECBBDFE9681AC7F455A55B12D0C131238858D81ABC1722A614AFEB6D8931B14C4EA794E380A37FF8E1BF27BCAB87F3E0B75FBA7C6A673ACFB71D13188AE2CDF3CD7160DB848B80366AF5A9517BEA6EFBEC33BC2538E0E8DE910EDE255ED47FB3FCBBBA2907DC04EE36C1D136460896738C40C9DD912060A656BAB12EC61CC40F767CFE32B79A2E2D39D67F99E4270426017BE3E8A03EB48D55C8C863DB254AE1FD2AC5D222004335AB68CA77AE33A70D8E73CA72AE0F8609ADD7E36AC8DE83EB2B4062C4A87AA42D2C4CE7B2AF9589FAD231FF9C5088141BD01C60EF333640440E9C5BDFBA5B11B8DFF6A0D251845ABB8A86F0FCB5C471124C654E5BB68AD2F626A39252796458E49FD71BF05DB258AA72B6B91D2D46E7F1C13196F7A8502FC310686F051D9CAB265D087E7A9B8F790CD8DCFE2C4E73877A8EC663CC6E6A00620B9A993ABBAFF1CE802153437DF080AB8E84E8DF2CD660D656673452B1BC270C8255E3E58FBA94BF8EAF81B7226A73EB33865EB1881D136E24369CB8C5244BCD7C5D5BD6FAE4C9CA6E136F4F1CF2540079E94DFC5D8BC2B6C4C11414DFBFD87B8B25CE29A", + "k" : "231AF912421C1ED5A64B937FE19422E27ED9C21F415E16D7782E6211BBBDF074", +}, +{ + "rngSeed" : "E3C41CCA6F04CFE7732FD54DE30CC5CAAC93E2F80E76AED7D24A962A3969C1B6A311459A3EC3E510E3E9B1E4291D4D7D", + "pk" : "8DEC41FE4093B014449985121E134C925B37B11612A9C61E97D5863F81A83F903383A517D1AB1769921563B86069C9C20841481BE7A75311CB1B2C74F4CC96D2AA916509CC24D33CA7906AAD07938E701177B42158C19FF3040389894F5D4C9CBD608C8234CEFAC9BF75FA177D5669F45A195F420B189BB340EBBBA649996863618366766B7C990C6001A397B00B71272CB1734ADB60A5B1523FB46BE42752EBA4BAD8D6B008883E2697747ADA77635174D5F7ABC89157ACC61202100CF719C9B8C5BFD7409FA95641202384629B925C240BE94889BDF96BDC176E4DD3AD75F7B2E4C2ABC9EA8280F07DF64A162D016DB3A634071944F6468E00ABA03255430375660BD2C413A0B3CC530DE305948D783AFD0A41B4A202FCBBB620D9BD47B1181859B66F922D0B5C464F71AC5682829C8C6F4875BCE8C37C5212113CF77A8CF480660B0AD108A0B67C063ED52BBA442567AB31B30858CB33584D5422ED7427BF085D163005BF182C90C96CBC89CA70591DD0606F95DC6ACFEB3315274F7C4937AE511963E90E6D03646292743A4178A6F344C244194F989E1C34BE06A09BD5086C73992DA8528CAABA4FBEF1502C1ABB01B145A7A825A971A001055E2B1841725CB06EB23625BC0D99F89C1998023D760DB1960A751988529628B6AA54308A3C895688047A003C089EF4A3232FDA6AEA0194154339B75A0A25402212211F3EEABA98CB656925C34F46037A436F89E01BFE408C138601E3A490675ABF367194B377158F131B12740636B92BB5D184C05A23CEA0C66519B2E8B094610655699976538471D77BBB3A8613A3EA1EE7B22642D63611B498E302540CA71E9B5C1AAD6BBF309A13F9AB5EB57A5670FA9244280867CCC48130C74C50219DA3168A26A52001713EE7B81157A6392199FDB4A56631B2D17890E6B0BB82051B9A1C85CE8AA92A2557FFA499C8910F7E98C3B4681EBE6323F4794E3E7324330A710B6A87186C36FF04602FCCB97A7842104547264437921B413D52229A1555226A3BB3F090BD8CB09DF92F4B4093319C434C04A773ACC094BB205062903ADC121FF6C178AA5D02F4B401E2B43BD79966D83A014BC8A8FA8347E1A9E8C6947134B837F019B05124279B26F20414FE326F3464929105974A853961A6B55EE90BA8D730BE6A51FDE90B4C23753BD9728077B90BF1C656C0738946BBBC5A2D72F95D876437C659B1BC663F6AB2B9026BA0401AC168C05933DC0509F7390CE8A024A3A1267217BAE20C0D26C9D824182BF67AC60C0B121184A42C89DA7A1F2DE023EE6C291DEA37DA360B6F912EB95727E0C83EFE0796D603B1C4702B2532AF8D34053E1C70F8B73D5874578B3A2A8108B12E603D8CC1637D54BCCBA48F73D08F63C12FB8BB2E40938456C46209B262D8F08FC9B576D463329057A7FCC86652008832712E15E31EBA79CB33A58262F822B9B8ABBE8C4A025729DBAC6F4DF64F14C9959993004E0A4398B7C1E049120D404FC2683D65E85CD279B8D9E9595E995631F3469CA25412A54535C569D80C2A09117733F529BFE9A9DC766C8DA35BDF0B64D1C27D0FE31AD736C06A92186034468539A3ADBBCF0E67AF4E797B63A0494CD91D2B9B89F8D486236B9B24772383D81AAED73286E5DC6E35A1DD0121B0A362D8C94022A515340F", + "sk" : "13276431F3634D420A374A0ECD8B81C035431DAC244DF1AB3405626490C7407599CCD4C146C5B79653BD845286ACA5C7FC13A527784BC0B0B0171261409978A4754FB612203267804A524E81772BA34B99A20047F642363F928AE781C89A7374FBC0ABB1373CB3485EE31A76DA703A8D39C12668A6E0869E558612A481BE9AB6AC8C00109F3A184F808B1BE7566250CD36CB38B57771083C64CDEA6FE5E9AA02F5CD1B6C08272078745424A7A11FECE731FEF736471674506B9BC56707DEA19858860825A14FE820563CD70DBA44B57932048BF50EB27B76D8405133172EA16A5B0FE77BCA259CDD46414F13425616BDBC006EA23B21BEDB23EA86A099DBC48B4746AD35830D694A218B0E233842566B9DCB18822F9301B8D7A6FC2A4555278828AB27BB74B1B3CBC19B343EA64904C35C67A1BA1AD4F9CD44A2B2887B4ADAD130BA263321469A4F50C6A6F06B29047A3E253A19E21F3C027C55091D7777AAB2B955546B58BB212D87F9361154837460966A80881E967E379A1365AA96CAD80613B2CB0A34979F6C1D00E7010FA2456807217ABBB1DF6849BE50BEF9A67C973BB14F8953E7597360C076D5290F0B1BCA76F02D6A600DFF97CF1DF0AE59AC851C29A0F99B17759182002C8141D20166F8BF1979321C1A6234B608257B6BFEBA7EF679B837D6A23673A122CB1E817B5FDFE9904B1A2F953906D7A585F074AF3BD445A71B431F776008B133D6269CAF16B306D444FD819B4D4783828266BDB13E0807409AEBB11D867667522EA606A210F68D6288BC3A484CC4464706538712921E107885834B4ECDC44AF3C866EE0504D191724E5704B8B20795B6520F0CC8F1D89DDC46572024294503735551330E887E6B71BB47E97AA498791B735733A8A81D962A68D32230F0C4403056B065B379A44BA61188C7F102511AC0D894B6457402FCABA82FF0C13DA32EBE5785B44B937FC020EE1544B95228FB6447E862803C941705625E0758AB5D1C3E7D771780ECB188202B23972C9DCA283BEB4F3303064C922D8EC8081B9529EDC163AFFC3F585274AB0143060527D2050B34842D15D1508AFA2AF069744D7620E02C2FAC7954BEA06A1BA04C28B0287BF71CCB809D7C966B9F94B05906B003B77A0730A787610340C600CE3B4F1ED9A4B5195355501B5720498AB185C75740F2184F5A16C18B7BB58BC120A030B5D20240D570545F349365A97BC387A6BBC2C001151ADEBC0375FBA522B7994FA4A78FF6390507CCFB8B47E208B70BEA1899512FB068A9DB8B262235191F6403CA5B8517DB25CB8B202085CF6FCA6B6E55A75DFA7557A43116179AB5C1510F887DB6A9C5E8AC41FD5010C11411D8F24529674A97FC666C565CB7469AA7C8AB943606880A9832DAC41FBA34F3AABCB1BB0050C66F4C5B53B6892A43EA98EFF429F4F6206C06290CDB504029B29752CD75FA4DF4A59C5919607616C074861F3C00C18F1AB27C190937FA9597C165D8D61281873BF1EB36BDAA9F95360E54F5B8B44542F618BC99077CF75C2FE4A04EFC112EB2618FC3424AE296BA1FFB9A92726BF0BB7D74960868494BAE529438C898CE0C95AE47415400ABA6C47CA4B301A64B97777B7209039A2403758DEC41FE4093B014449985121E134C925B37B11612A9C61E97D5863F81A83F903383A517D1AB1769921563B86069C9C20841481BE7A75311CB1B2C74F4CC96D2AA916509CC24D33CA7906AAD07938E701177B42158C19FF3040389894F5D4C9CBD608C8234CEFAC9BF75FA177D5669F45A195F420B189BB340EBBBA649996863618366766B7C990C6001A397B00B71272CB1734ADB60A5B1523FB46BE42752EBA4BAD8D6B008883E2697747ADA77635174D5F7ABC89157ACC61202100CF719C9B8C5BFD7409FA95641202384629B925C240BE94889BDF96BDC176E4DD3AD75F7B2E4C2ABC9EA8280F07DF64A162D016DB3A634071944F6468E00ABA03255430375660BD2C413A0B3CC530DE305948D783AFD0A41B4A202FCBBB620D9BD47B1181859B66F922D0B5C464F71AC5682829C8C6F4875BCE8C37C5212113CF77A8CF480660B0AD108A0B67C063ED52BBA442567AB31B30858CB33584D5422ED7427BF085D163005BF182C90C96CBC89CA70591DD0606F95DC6ACFEB3315274F7C4937AE511963E90E6D03646292743A4178A6F344C244194F989E1C34BE06A09BD5086C73992DA8528CAABA4FBEF1502C1ABB01B145A7A825A971A001055E2B1841725CB06EB23625BC0D99F89C1998023D760DB1960A751988529628B6AA54308A3C895688047A003C089EF4A3232FDA6AEA0194154339B75A0A25402212211F3EEABA98CB656925C34F46037A436F89E01BFE408C138601E3A490675ABF367194B377158F131B12740636B92BB5D184C05A23CEA0C66519B2E8B094610655699976538471D77BBB3A8613A3EA1EE7B22642D63611B498E302540CA71E9B5C1AAD6BBF309A13F9AB5EB57A5670FA9244280867CCC48130C74C50219DA3168A26A52001713EE7B81157A6392199FDB4A56631B2D17890E6B0BB82051B9A1C85CE8AA92A2557FFA499C8910F7E98C3B4681EBE6323F4794E3E7324330A710B6A87186C36FF04602FCCB97A7842104547264437921B413D52229A1555226A3BB3F090BD8CB09DF92F4B4093319C434C04A773ACC094BB205062903ADC121FF6C178AA5D02F4B401E2B43BD79966D83A014BC8A8FA8347E1A9E8C6947134B837F019B05124279B26F20414FE326F3464929105974A853961A6B55EE90BA8D730BE6A51FDE90B4C23753BD9728077B90BF1C656C0738946BBBC5A2D72F95D876437C659B1BC663F6AB2B9026BA0401AC168C05933DC0509F7390CE8A024A3A1267217BAE20C0D26C9D824182BF67AC60C0B121184A42C89DA7A1F2DE023EE6C291DEA37DA360B6F912EB95727E0C83EFE0796D603B1C4702B2532AF8D34053E1C70F8B73D5874578B3A2A8108B12E603D8CC1637D54BCCBA48F73D08F63C12FB8BB2E40938456C46209B262D8F08FC9B576D463329057A7FCC86652008832712E15E31EBA79CB33A58262F822B9B8ABBE8C4A025729DBAC6F4DF64F14C9959993004E0A4398B7C1E049120D404FC2683D65E85CD279B8D9E9595E995631F3469CA25412A54535C569D80C2A09117733F529BFE9A9DC766C8DA35BDF0B64D1C27D0FE31AD736C06A92186034468539A3ADBBCF0E67AF4E797B63A0494CD91D2B9B89F8D486236B9B24772383D81AAED73286E5DC6E35A1DD0121B0A362D8C94022A515340FB2B71B8AACCF14842A6D4ECB713612F801A5044147FB9E6987AD3863759DE31E7B129A56B51BE635054CAB9E84F2DEF59A3F8168E301EA2BE388C45B8CB022EC", + "ek" : "92469286D3ABE9E8043838BD60D7F234E87A9D74D189692F802E23A617DCE86C043F9C16C5D69D463E7CCB37A422817C5364626D2FFD2C094C5BB4D1BBDF98701327FA7437A4F443912561D8513D6A772A7328CB1D3B95D3788561D53DDDC35FB935CD5F9C0D0E08C9B38713FAC218A6DF65438F9B866D6EAF41DCA178F93D8C1BEFCCA911783F6E2B707929AF0F665E4D267E83443512B57FED0EF37EE53C20E9CC4730C2C9EB648A2F00791A46DD14FE729A22F232992C960C44E9F4B151F48603BBC9331EF3A788116D8784069BA649DA563A90DB9F0FEC061B78FA9F3FDD50021FC0E81246C586646B8000A1AFD92E066EBBB1CBF19104D64C1C7CE14875F623792E8C79C1E3467891191A2B5C9BA4775F925B704C6329E1A479E538BEF9C5157477A44553373B9805D24C6497E6AE63FC13D7C53AF93804DA3435D6D19017E91749ECCF2412A222B5A8919032556D3A09821470B0BDECC84A28CEE46327681B998FA569ED0E53BA6691E9AA4BE7041AEFDBBD2DA3FC8615E266A9D905E1B6924D4B5A1840776A66B07863060D996D023965D6BFA79AFD4747F4C8001024ECE53ED7019E91039679BAC3FCB71D550307AA347A1F9762D068E789D66C13E913608B3632208437D4C0FCD2F80D9E656ACD1FBA8DEAA3F28914B095CBB54C332DA926EA90FBE886B068AF2C94D58EF745E2308D8C6880748F908DA36D2FBD7C89EDBA56E0481354C7AA9FF533DDE925C7553DC4F1975CF0FEA2A007E7749AA569C22771DBDC6089C952207FBFD96D55DEFC539BDEBE86C58A51111E3518880B9301A366C97D520A284F6E5A39ACD4B8CDBE3AF989BC9C4E385A4CA212FB25B955BEE021566930AB632146F5A69AAE2B812910E40E20ED1480F84C2A1BD0A45695E9812D0A62C71C8F5EDCA63873BF9A0C4B1B6450AAF61490A5741B39B97020B43266364ED61364C44221FD01E79CB77CE52504C7089C9B3CCA1778783AA7A31182E0ACA7763C2273CAB7225CE17F71E1ABA62E89293D62173589B9C528191436A6F1C5736326407ED167DE98936F6793180E26D64F877A1AE253152D1CF485527D23BFA5281C3E3B4EDD6B7650062D226184F74C69B3C928451B4BF40D82E8844A35D25E5D712F9C07B3982083671EA5D3187EC689A3043E1CF2A1644A384C6B606121F11DFB0CC2AFFE564EAAC95D188D15BD0CC6226B487A2180EA381A7E51D85A62C2FC30DFDA3FDD325FFC855B62F229BB92D9E5697F5FB07C4A09426AD8159454253F97D3D1D069B43DB9B249D15483AE623C0DAB881C3DA760B2CF2160302F7CEFADB8B9AB558B751653CA6331AF17EDCAFFBEC558EDD9237C852424AD86F268C6967BD391E2C16686237DF3D880BE72C0175F62C6CC2BDD345673D488C3B7FAA8BD4A65AD6427B8FBB3EDCD1B916F21A1D76BAE92F959F64A4F5039AF661019D5F603E994F9A5C1A2D74286236C52DB35F01BBD583DD75CF760CC6F43F1FF8D02D9DBF2C739B354F061C2E516E7C4E613DFA87FF9DC028DCF112379", + "k" : "13D30256885CAE7EB50FB54B19EA986EB806ADD00DE890526380C7634D6274DA", +}, +{ + "rngSeed" : "373FDDE922CFC416ED96B444E445BDD0962E8989F6C50ADF9912A89937C57217D3600B06C95440448E3F601AE69CA5BE", + "pk" : "86335A761609CAF862810BA70E00C83DA3CC1C208CD893233C8AC3247B013417CECD467E9CB87280AA13B061BD0A661034EBABE9AB6E7A447C2826AF3CBA6798270A36F7431AE9119DE2245704110D159AA438A6F1546A39286A7A179C5F286073D5B944EA2000AB61FCB9373A4A94DBA5C9BAA94056F35CA1810106F2CE65B579C4744F94955DB4730265053B812634EB5156EA819069F6371040408A2036019967F4163C1EA611C02BA295A51581644DAB07872D1A5B21A32D0FFA349E3739D961A9E9BC07B6D8CBA3B945BE491958813600E781ECF54912D70E37832E05784C5E12271A5AA5D628233062305A28493BC2B180D802423AA4F75CB6610C16E8798CEC72253798B189EB217238B5D063224F78114715818AC4AB40D34042860BEE445FA9B1B02DD5A7C7B6BD8B03768E7C38282806E5FC7A93A9094246A403111A39BBB89CA4CA33F9B381FC8D6447450D3B4F6C794B565B2735F8014FE35E78A94780BC1557BB380DB47D25791B1283094CE08AE4EA9961882D134BC5579AA9FB44127E2670B85001D58A162E38680D3C8FD2D3517CD4B36ABA9BF1930F3D4C067F2A5B4DD702CB9B9E138BBFA91C0F49A86BA283091350A2AB3C1F3C75CA20A4A160318CF88849EF2102E47211DF95A2FA325573F60EE7EC5E70D3B88D291CF9110B9906401968462D2ACE979A825B088F7C2B330FBB5F15B1B9F24B84A646CC6A9B27B03767978268CBA750B5429823E7AD3A00A4E813052011BB0F47CBAC838A489C568391C7D05457F4033814BB9D52A011CE787F0DF2AB1BC885E293BF23900F3FA019238B7447561EB85B296930232B175379F289982312790BB65743CFE65017BE280063C19B033C19EB988D5A827B64777EB8B13244A9B6763C63523A6AF78672B652AC38F33F2A870C494B1DD34A9AF239556ED9412A48A7B3501DAAAAA976DAA971C1565F37BE80C33FD3126C7BB3AA09F47F4C9C503E2677325418ECD2058FC7518FC247B36C0C8F59427BD2311CA493510794CDB734CDF69C6B1A9D5C990424D819F35CCC8750B4750C43394605BB60B7C4DC39D8F71DFDF1C6DA319F6D671AA170065102086665707B95CA4D241C26CB4ACBE928D23318D372AEAD3A99BBD075B5186ABE6590CF5278BF289050C13789F82476620472BAAF258C78EEB7755F6C6B1A113D91DA945A837F0C84B353F9AA1C223404A3C071A27C84A6AE90D31A0D254234A18656095BF989456CD9AEC6A837DF6880C9BA79476431929C9B22D9BAC09ACDD8D94B7A884E261037F1BB5335F98C4C491FECE5AE0A485611A50224809D48AAC84C16957221924D3C2D6500107E71BAB5580339B0832E0292B89A3F25BB40FA0445F2B3122F97856F739AABD568D1B0851B47AC947B25D2DA6910D05B44E26088901D487CBDF2F782C2E35193021501B2CD264A6526B4AA6DD439502601FD7B203B088361E6218C1B72854648F4023199E5AAECD51A33990B74E4366C07818EFCAD158A56ED623F63C20E5EA3C519350CFE16B0DFD3AF10A45755641A388590EB95B6E5158AC5BC4AABE686140B981CC5C2AC896945A4BE089201B56744C439630B56A15B4A3591ACC88F3C4680311C24D80B5725BBA86CDD22A3732C6A1BF7CB10F14D57EE8E5901E46B97E63848EFDC76368B797D", + "sk" : "E5A906286950DB6187780184CC302F14A9AD2F7A382D93403308B8676C20CCCB52347A515303A2BD15336C0B711B3A31E8D0CBDB59BF42633823AC1DF61C63633171282B537CD1A19A80160D97B9DBA7322D935577031C081A035890BE315B7A4275979691B612B764111BA6AC57AFA50C29EE436AF02131442C5704B585C663935AB698DFBBC882D23FB39C75370B8C199CB0DA26BE27E8AA6391B5FC30BDF077490BC677D6E631AF504B9AF2CCF7939536D819455B91AB172CF01639FBD47618B8708F460284ABCFE6D21371DC3B00E579AFF432C9417D33511D9A0170BAA0A3695004EDB18599118146D83EA548CCB0069A3379430DCC8E3D728EAEA7433ED4A704987624D0994D454374F9218B2A08EC20B2B216482A1C820E8C5CE99413DD590BB042C9D294AD98408C407B88CF6B32BFE9B95F9A9D45A33184CC8B79CBBFB379639C9B44A128C211E700A59AA4EE034E1A3375DD216EC3E2447757C70A0B4ECB6B1677755C327914CC38B425925F9F910F4F618CFD425E5F55C4955B14B08C64F976068DAA8E711A3D00ED0E47E222F201891F6C7C52F282A4D471CC199E68FB9BB8BC81766A457A6ABABE254C4AA96546B96F56375E68C9A713072C5CA9B0D0D36B1F1B663613075E62071F97C6C2AB44E98A76DC767FE1C0789EF155BCC976CF1B879F1A151606B996225ABF147E7CCCB615243E0D0775E339C909E93477B9B66FB863E726A4F231CBB98435368ABED797A00DB8B4DEA236E75673AD8B857206D03C50B0767961F67BA0B58A668A02680F57372CC8C175C6CAC858497EABBB840A5D87389C7A623FA5707353438E7A4388A1C34236294370343F90C9B38F4AC28D187BBAB21C3D656C4EDA62DD8127771C8038B67C80D58EDCF81F526344C48B29F73A5197B0B51FC29D19396B8B7295BF524D38371C71013263C95694138A27FB56670101B0F06F6B568B4C05C486043F53C44F321A9BD8827312E5537608B5A2D7123971081E8BB7A05AB1336A2B7EB487359BC8287C42ADD6B72E5635E9EA9455552EAEE4C92812AC32E254A90669CF6728AF07763FA3BA74EC0E1C8090F2706378BCA30FA69C85E50A03E8326EA4917B6515FB887D3601C83C5B4F520804CD401D0C67CF229299CEE141DA094A5F117403F94465C62761EA05ED1016759C60B14C352B41C8EA619E5BCB167A851EF8842845ABB4F7A6AD75FB610408324EA84C665B36672B5E58F985C3A45BB3F926F5C82D16D519303271AC83368D28B2DBA2083350B6205C718E2BB4AA1518FCC3C76A9B02D678732B4BCB8DD4CD9C2526FA919AD5C9BCA0C6171C1A7547772C957B74DCF877B1F62921C7A17A7A8382B81F44F2A6CF559B761BB58FE8031539C02BB3222332513921411C894819A2AE856B65C1C3B113B09A6AB06AD6033BD79227AEB397D90AB3CF5985BAB7C826931184642AE25755F79667AEE64918575118349AC0B19963549C17F71EE14944F98B5EED708B2AEA5A305458F699505083BF54EC70B80CA1287715AC2046EDEA5ED722AB14FB8514E67E45343DB7C91324357A99DB343C735C918464B532AA2D9649D33A1CB38039B176BDF69470F1A1839562B94B3B7294A77C72CC5686335A761609CAF862810BA70E00C83DA3CC1C208CD893233C8AC3247B013417CECD467E9CB87280AA13B061BD0A661034EBABE9AB6E7A447C2826AF3CBA6798270A36F7431AE9119DE2245704110D159AA438A6F1546A39286A7A179C5F286073D5B944EA2000AB61FCB9373A4A94DBA5C9BAA94056F35CA1810106F2CE65B579C4744F94955DB4730265053B812634EB5156EA819069F6371040408A2036019967F4163C1EA611C02BA295A51581644DAB07872D1A5B21A32D0FFA349E3739D961A9E9BC07B6D8CBA3B945BE491958813600E781ECF54912D70E37832E05784C5E12271A5AA5D628233062305A28493BC2B180D802423AA4F75CB6610C16E8798CEC72253798B189EB217238B5D063224F78114715818AC4AB40D34042860BEE445FA9B1B02DD5A7C7B6BD8B03768E7C38282806E5FC7A93A9094246A403111A39BBB89CA4CA33F9B381FC8D6447450D3B4F6C794B565B2735F8014FE35E78A94780BC1557BB380DB47D25791B1283094CE08AE4EA9961882D134BC5579AA9FB44127E2670B85001D58A162E38680D3C8FD2D3517CD4B36ABA9BF1930F3D4C067F2A5B4DD702CB9B9E138BBFA91C0F49A86BA283091350A2AB3C1F3C75CA20A4A160318CF88849EF2102E47211DF95A2FA325573F60EE7EC5E70D3B88D291CF9110B9906401968462D2ACE979A825B088F7C2B330FBB5F15B1B9F24B84A646CC6A9B27B03767978268CBA750B5429823E7AD3A00A4E813052011BB0F47CBAC838A489C568391C7D05457F4033814BB9D52A011CE787F0DF2AB1BC885E293BF23900F3FA019238B7447561EB85B296930232B175379F289982312790BB65743CFE65017BE280063C19B033C19EB988D5A827B64777EB8B13244A9B6763C63523A6AF78672B652AC38F33F2A870C494B1DD34A9AF239556ED9412A48A7B3501DAAAAA976DAA971C1565F37BE80C33FD3126C7BB3AA09F47F4C9C503E2677325418ECD2058FC7518FC247B36C0C8F59427BD2311CA493510794CDB734CDF69C6B1A9D5C990424D819F35CCC8750B4750C43394605BB60B7C4DC39D8F71DFDF1C6DA319F6D671AA170065102086665707B95CA4D241C26CB4ACBE928D23318D372AEAD3A99BBD075B5186ABE6590CF5278BF289050C13789F82476620472BAAF258C78EEB7755F6C6B1A113D91DA945A837F0C84B353F9AA1C223404A3C071A27C84A6AE90D31A0D254234A18656095BF989456CD9AEC6A837DF6880C9BA79476431929C9B22D9BAC09ACDD8D94B7A884E261037F1BB5335F98C4C491FECE5AE0A485611A50224809D48AAC84C16957221924D3C2D6500107E71BAB5580339B0832E0292B89A3F25BB40FA0445F2B3122F97856F739AABD568D1B0851B47AC947B25D2DA6910D05B44E26088901D487CBDF2F782C2E35193021501B2CD264A6526B4AA6DD439502601FD7B203B088361E6218C1B72854648F4023199E5AAECD51A33990B74E4366C07818EFCAD158A56ED623F63C20E5EA3C519350CFE16B0DFD3AF10A45755641A388590EB95B6E5158AC5BC4AABE686140B981CC5C2AC896945A4BE089201B56744C439630B56A15B4A3591ACC88F3C4680311C24D80B5725BBA86CDD22A3732C6A1BF7CB10F14D57EE8E5901E46B97E63848EFDC76368B797DA13CB3F23CCBD9CA6A75823D1BA14EF03664560F397133935103DED2D7480B99F0C083AE8CFF7A4BD779D4385E111ED4583FE00D30E651F171D7E8A90EEC0DB5", + "ek" : "FDD19BFCDA1C6B0F9BCF14C8A1AE4C6038CC59FF1BB6F5F1CD8701127E15B96497E65246ADF62314D23648A545733501255E3F8E4BC7CEC18F84687B4065592BEA71D49714A7703938BCB4537621EE481F7B02D8B278F0178AAB339B7D305F53C3E7777F98B46B796CFF9E783BAD77AA824145B4B1D168D6024BA27C04144A30DE7537477309356363DFBC45D7FFB2284216278EDF390B44333F04E77DCD1EC2D2C0027A34A76B624EF78480F268BFCBBC3E7078B71A01A26D25113615DBDD57D2274E26468CE658BEC1B19F20C560279EF81E7DCA81C80AE28309CD746A716ADF9A0F6A91EEECF33A4929168CB0D7CE253D6907AF60B6DA7C36EEDD0005DEC1472581695B2406A35004E91F85F1D55CABC7B0E625CD96C3601412D996899EF77B5D6C56D385F9652634B5D1FD2B61E9B725952349135078D9C6198C96BE09328E52C95C38652D0CDDD479E9B8E1DCB3FC4D3EF11FC84A0598B8C7D2C5A663C3A84FD04F7039B879D46CCEDC06A5F33358FC71531DE57F30A822BF268F92D83441C1919294F9951338A8D8A8FEBD8279E1EA166525BD379B798AC2FFDB124DC733B205EBE764B4F7EA273AA2EEEC533A8FF8E54360EC7D3A5CBB2DD5CF265F6B97EDB2F8D88A2E7C88BA6E0F113B50032AA65D9684FA344A7741D6E035E31D01E8519B2876991F549A0473EE1F98D87273FFFEDF0C51E8327F397A8B3DDAFA9EF5A5B2D6C0130AF4FD61B99D75BA5603586C0BFC137DD354EE05330EA526AC2FFC04D429F9AD0E6487704DA4B7076C9597C2A4C34F83341C8607345CB1F37C85E24748C5A8E69FAD2EA5EB2296EFAE606CDC91C9E4406086FDB80DDE22ADF0673B7A7032CE9A87ADDA7E78F5CC622CA0EC6AECDA69D860F9B19CFFC839900F16BE9F8A684F3FD3D8D51B5FF21965471AB18AE4C9ADA482660C1C17DFB9E1750B1D7CBB30B92BD5D7C9F54AFCDA3529B691E1202260862A69B218494E09B5FC8BC70E727F7CB1F26567C765201A82666BCC60FE65599F3B3F869B813B9D5134B1962D41196D0898660C4BEBAD4A870EF5E3A5E93E9069E709E700D340A0371C7280CC2C263ECA718E0C0DDBB4DB467F61F1B590B92D496D849C0ACEB6F67EEA02D152512DE849C491852EF124778CD96816BDD700FA8776642FF20E5AF309255930197C5720B1119CC5AB8DB813C6F3E8FFC76435C72E2C702D99679E5347AF384488CFC9B1B77D3AC3CF12DE9B76D69D7D0EC98F4ED9746451EBBFDD4D6D1EB56A3851E4571FFB13C4036736B198542063A9598E43F43A65A288ADC2FED22CFD55D068AF221ADD925E5FB54911A54348C1AAD091755D8DEF29E242C07DDE378BE8E634292E47C5ABC9E19C7FDE2C65E85374AEE50DED270C2A15C5A36FCC948CD25BEE41F49248D818D196AA2C97276D8AF5EDAEF740C04B8A90A0CBDBB24BFFB9EEBE55689E12AAA404C7C6CE7F26896A1947D18017B314B37233129FA8A218EE7CE3D77D265C1040660E7CB6952D2E441E43BE415148CFCE3099BDA6DC56C2", + "k" : "724F229D740AECBC4B4B4B495E7C594BCD0D648D467BC07902FF1B910715FB31", +}, +{ + "rngSeed" : "16BEF67F7AC3A755C59C816478B75FCC16CE5844DB537791ACCD1EBD49D2824B105FD2E970F728C8F0CF16E439A9AE2F", + "pk" : "A4B21FEF3306A34117E05C4F4736AF0E8CC5AE6BC3F294188AE5397EF69F26303F9592A694E12916BB56E5AA43CEF5C183E6CE00F78EF423C3A838AD2CD3C4F68C142EB23DD5F774054668EFF212B2BBAF8274C7AD10CFCEC5B10BB603EC6AB33C963AD2A22B23F7412F93715A3B0BE0B1754EF383C2D52A5A16A22632C88A9635AF81909D347E64715806F93E0AA26756B25A8F5984F8E298ABC12BE53850B83213960428562455D6A7BCEEF90355318B5BC78734864D1AF0BF1393849AD715C711A5226065586B80F1357D961A9BA74999C8F47C7583675245749BC56152F1428910324F2706C8718208C4A13158360365337642279F5009EA86197109B78F0A037CC298F3085C46F68AAB45379CF59CD504A9461B47268BA03FC7CF7B1AAF9D461BFB3A7E68B396419A44BD56462E7AA2BD82223A09C155D26DFF3873A6052472D6796E24BB7DAA3583711CC435A9B3D3463812734B700614396A6DAC3C2D838AC103D04239C847241835768A2BCC3D6F8567F6C998B4E7CA8D30A81582686F211936087D3DB54972615D4A9B0E1AB1765A18C753FB9513D097322154EA4A3F934C8FFF8520AF32AB05F26D1030888C0A1613CA74164793B5F798EE3C589684BFB115CD6740BDD5141F1A17393B191550192FEEB3C8D2C0B4C37790091312FAB615C6D194F076C49D01CB97190ED9D4A6BFE0957047933E2835353085EF611C6F9C1F86DC4366C45CBE2281B0910AE39AACB271C03260648F7C955E99367D1B130C85289D586272FA28807CCD909185DBD5999AF47F79DA95CCC4859E8A84B2983F0E9693B1DCB506D7B7AAF03F158759B8006511380B3AA4B46CD060F96C0E16060161698F26E073C2F74E9C5B31F9FB4DF5DC0F3B0773470BBFB95135C39199F6F281280480AE88573284C44AB9B91F8942AD423783263927C5857D5832A6E1576C6A59E7B1A498AC2F5F71C51B4C9A36CC4D28C042DEA588A4756740782B07CC245A069D42245943977780F11EAC0C8221F9938FB05A5D096401D2A4BEA8C9F46564AF831C907C4FEF6743EE482339212BEA730113A930C0A5649951ABBA2C6A3AFCC4738580C61A4730AAC4DC3C84DEA158365CC6C760B13EA10B194B2539A55DA5F01EF6C55213815FC6479F1BBB67D5754161D4064ED1247AAC8EDC486A8CA1B311FC653DA3BE4FAC0C81AC0FA54B99030AC2F824598ECC699A31973FFB34648183CCE8CFE6495723975C7ED7CBC5281811462CC1AC48FD9C5CA3DA126B8125179B651A95B7749BCF711A018EAA951CC078AFF16BDE9A2F5B180EBEE3032B5B2826EC83AF147AF8288470B267A97C5AB0244D3FE538E986000DE3807132937A811DE5228BFDBA209E642FA3095045266E11F46E99F1B1EAE584DCB8805D7455D3435956CB1679B8AFE26CCFA7224736998AED363C0D82B1D23B339A16ABB5E60DD447BD78C80E6657BFFEF9BCEB18A0C8E602936BA32D24871D6470C338921366A009FBADE8F4AB940BBD22158AC5201F09157D0C010825B290581B4108573E720ACAF53344FB876DB0BBBA53D14A26DAB409F137535A794294814E2B3F8F42C09F323E072B2519588342448E24A769AF363293F4C8786BA4B70330BB80F37DE30DBA857DACE4B8291ECB2F6EBD5A06323B11A89242DA833741E9C4", + "sk" : "2556BBC99CA8EDB774F8B427981046C94CC902F20C2C9B1EED7555F800AEAE621CD247555B383508A8A601720695B5469F21627E0AA9C7185557718DE0A16B920454A642152C779BE09307DCD0AA6FD97909E7227ECB7DB209AACADB7D1BF5AE03CB2D14517861B2BE3E0936B47B7CDD488E22956B7DE9CA14B52E848C90FAD497F6D1BDB42C799D8A9B51F0C9A3E3835181A2D3CCBBD95785E1E3930B410F955A311FA69AE39B9A240C50C221C61D687853658C611717EAFC14F8A27F8CD190FFD433D9D863C530425DA8072E467893C7B621260490F1497F4470B43507161B23729A5DB94585A9D9C83A9554127AC9B7252AB4E100D346CBD7A496501979CD0B5317EA39ADF970A490AA9F2B7E4EA8122900C1C882A0CB0162F9256CDE1126DF07BC4A30042C6587CE0B3102673E405B623416C06F9ABD9BC62EB70CB794844A6A428CE8736BA9364882AAC621D304B98799AEA35287E023290335DA841A51E4C1B2063F1198661A0C01315B2602712B47D16B5F2B19BAF2A67FB13333DCBEC5D9557BA4A2F103097F14BE6C276F2A195A57B9B28B312C6967A3334851B075A7C3D2AC74D5897470286AEB4B29982B002D5751528C3FFB488EC4661BD58B275C229BACC62D85B8B8C560A02850EE24ACA565CA30168721A182936CA8A6508226D64840903038C339C603233A9046733C0E15E016F6F080414734903BAD3393C5671C5EDEE3CD8DB0CC8AAA4927C78D51AB2309B1B053D700280A0BDA9A5D268AC47D746EBFE01E6BE91264FC6A180C1051A5A87038BCE12A4D70930BA259CBF49039C0397845301F307922C763BE3BF83FE34147E319082990A45102A1D328A0E90A8E56670577C14AD53426CE36B863E501062A5634034B98DA407659B9E8F3A539907D511ACE034CA15A91BC8ED3715BE3C095B60B8332B6C068663D61781378C9F6D352ADF794BAB90FFDF330DFC77E492B6CA5BC53DE21A81AC93DB6B520CF3AB8B4837729F101B992C7057030271B4A7C6A7C61F399A2302155306ED3D8A0336C8081206F6DC09CD8B11BBEB89165321660A217D9F0BC770B2023832DEB6492E961184827A2BFFA27C13AC42844B3FBC14B0B96946427912432196E95BA949B29265B58FEE38B93232AFBAABFB1482F2307BDA7A3004CF74FAFBA6C464840CED7BCD38AA764D67BF20A88E9A99549FB66EF1A53D1EC60ED744632C7875299B056C8C9375C6EF4F147AB9C8B1240822AFCB68F028D4DC2BE9DA530C14A552ACBAC77D914C561C25284A9A4DCCA04637048F29A99CAB95117881DA8404596CD0A28004A47A77F8623B4A2811AC6B90E5069D7DC82C829ABC4B14FFE251507BC970F702341E382D9524672F88F33E16814977225659C8C321A0810A523D44190A7947A9B2EEBA262FBB16A0AB35100385C238C55601363CC5996FCB46454C142C25046EB507D4F6287630BABCF485BC5F19FD99051F12A3E683A7D89B21C2E903136B674BC0B1490D91548394738C417614077897BA9BA577F8AC9B584090D32973B4261C05385788BE4B63783728D59CD5539413CDB537826AEF3D304E8102C6A3B2E72E4185292C35AB60DA55ACBE3C6417E179C80F0024EF5113A2C42A4B21FEF3306A34117E05C4F4736AF0E8CC5AE6BC3F294188AE5397EF69F26303F9592A694E12916BB56E5AA43CEF5C183E6CE00F78EF423C3A838AD2CD3C4F68C142EB23DD5F774054668EFF212B2BBAF8274C7AD10CFCEC5B10BB603EC6AB33C963AD2A22B23F7412F93715A3B0BE0B1754EF383C2D52A5A16A22632C88A9635AF81909D347E64715806F93E0AA26756B25A8F5984F8E298ABC12BE53850B83213960428562455D6A7BCEEF90355318B5BC78734864D1AF0BF1393849AD715C711A5226065586B80F1357D961A9BA74999C8F47C7583675245749BC56152F1428910324F2706C8718208C4A13158360365337642279F5009EA86197109B78F0A037CC298F3085C46F68AAB45379CF59CD504A9461B47268BA03FC7CF7B1AAF9D461BFB3A7E68B396419A44BD56462E7AA2BD82223A09C155D26DFF3873A6052472D6796E24BB7DAA3583711CC435A9B3D3463812734B700614396A6DAC3C2D838AC103D04239C847241835768A2BCC3D6F8567F6C998B4E7CA8D30A81582686F211936087D3DB54972615D4A9B0E1AB1765A18C753FB9513D097322154EA4A3F934C8FFF8520AF32AB05F26D1030888C0A1613CA74164793B5F798EE3C589684BFB115CD6740BDD5141F1A17393B191550192FEEB3C8D2C0B4C37790091312FAB615C6D194F076C49D01CB97190ED9D4A6BFE0957047933E2835353085EF611C6F9C1F86DC4366C45CBE2281B0910AE39AACB271C03260648F7C955E99367D1B130C85289D586272FA28807CCD909185DBD5999AF47F79DA95CCC4859E8A84B2983F0E9693B1DCB506D7B7AAF03F158759B8006511380B3AA4B46CD060F96C0E16060161698F26E073C2F74E9C5B31F9FB4DF5DC0F3B0773470BBFB95135C39199F6F281280480AE88573284C44AB9B91F8942AD423783263927C5857D5832A6E1576C6A59E7B1A498AC2F5F71C51B4C9A36CC4D28C042DEA588A4756740782B07CC245A069D42245943977780F11EAC0C8221F9938FB05A5D096401D2A4BEA8C9F46564AF831C907C4FEF6743EE482339212BEA730113A930C0A5649951ABBA2C6A3AFCC4738580C61A4730AAC4DC3C84DEA158365CC6C760B13EA10B194B2539A55DA5F01EF6C55213815FC6479F1BBB67D5754161D4064ED1247AAC8EDC486A8CA1B311FC653DA3BE4FAC0C81AC0FA54B99030AC2F824598ECC699A31973FFB34648183CCE8CFE6495723975C7ED7CBC5281811462CC1AC48FD9C5CA3DA126B8125179B651A95B7749BCF711A018EAA951CC078AFF16BDE9A2F5B180EBEE3032B5B2826EC83AF147AF8288470B267A97C5AB0244D3FE538E986000DE3807132937A811DE5228BFDBA209E642FA3095045266E11F46E99F1B1EAE584DCB8805D7455D3435956CB1679B8AFE26CCFA7224736998AED363C0D82B1D23B339A16ABB5E60DD447BD78C80E6657BFFEF9BCEB18A0C8E602936BA32D24871D6470C338921366A009FBADE8F4AB940BBD22158AC5201F09157D0C010825B290581B4108573E720ACAF53344FB876DB0BBBA53D14A26DAB409F137535A794294814E2B3F8F42C09F323E072B2519588342448E24A769AF363293F4C8786BA4B70330BB80F37DE30DBA857DACE4B8291ECB2F6EBD5A06323B11A89242DA833741E9C468302CC5AF214CEDA67FF8161B29BC300C4BE8E1A4139437AEAD8A9EDE3CD4CAB46F84F01FEFC519E118AFFC4A7A1560F1F8ADD6DE72615229B997B2CAD6393C", + "ek" : "3999F906CD4183DA6601E1E3D328C4B5BB9188421C31BF40071986F2EA08E82BB9322D3F610F1481D2C626F17ABB9B3AB283380E22208E50AFAD5A00EB6850A77A14B5BCC98C03CEEC3522A157BD2879ED7EEBFEC4353E1A335B39B49061B6EA1A1CC7A165A9A493989B21B3539B245B45B0F9A3A2E8498A444811573B579BF7F5926620055861F05188AAEA277DC7DB1AF4B50B02831C9FE552F48DED1D675766C2CF124BFF853BADD7CE6AAB3DCB009C14866DB19551C7E0B887AC52936D269CF71A4878376D738BBEE9B1F3FB11E42BDFF0699CA9619AEE858D4458ADD5C95E3FC716525FE0594840377FC0FF2BC88D1FB4C268E793E00199C74611C94DC3A0DCBF9A9B6C1D4DF0E40199FF7162569B41ACD9CD27AE19A06166083BF8EF305046ECD8C598E6998FAC5EE4B932657CD462BD4F5DC0DEF1F78A7CB54180102120347CFE322EC3DCBE9D418AABBEE15ABCEBE7A91E86FA00F73E7F9119D6C77A2EA3FB523584BBC7E4608899922786611A67D868546DFD42308265BFCF56F667D10CEC220F71A8BF7AF2D1FF4F52D0A375825F348ADF7920AFAF56BAC5D1C291C9A156C03209F4B10B347C78343A499B5EC2AE7F6592991DEB223FF4A4EC6009537CA3BE029B040FA5ED153552B7826184EB02EC41C7BFFA8BF76668896085FE4DC21865FA66CC8AD0283CA2FA73289DF304EAD8654A45E18F6462D20ED0CF880B57D5A58B7D019E7A7CCBE47A0B54FCCAD579764534CD8857669E30D561130019604F429881EDD733A7D1D762D959C6B90C3565A293BFBA70A42B570A9365EA6F65806F937DFAE9B8D40CAA62F3F9DC88CB4A9F77B1E1B913924E54FAA5BD4791624CCD1D4339A435226E8B22335E3CEB5139AF3CCF8DD859F9E4335592B3BC2F5B89737F8157751E90EDDD11A8752A09BE197A5A9A7B82E68A0781886D8D9482FE9C131E67B5E4BD699E3A3C0B5AAF1655803B8F05C3A5BE1DF02A2A35C341F52F723C0D207BE9AFA1597F48D1DCE02EC5949B7C7C5A24E676CED86156C6C953E841323BA5A12FD419A71FCCF827072C821DC1D4E82C6ECD01FDEB09AA0822C33CDDCAFB6C0CC716D14DBE0C6DECFA713B909CF7C11FB8DF044C51C0F561BC498D6EC493C7798FB51A2C86FAFE9B366F8850BD81E59088A6E45EEB0299611421F2BB9A865720F229DD289C2FFBA6581BFF9C501B226610CEFE80B1D0C1D209613CEB35957A9C5563D13F45F314E644EAB25CC24953CA648BAE426D77D0446A39C0F598E5CF934DCEB5236297580666889E97B0A257DB709E548A835FF072C9851288BC6AB7E89E37E8021EF68CBE13F62BBF9715B7D526558534B632BD8468211F0D4B0DE378CE786366E8DC2884672F081F1CAB7C51BDFBD0CC3CF7F8D8B27C5B47FDEBC7ACF9E3C96E56FA1C462E7CE7E2B2CD3C6583C27130A597734E492589B863432601ACB244F76BFF29F2CE8EA2FCC9B232DA903247EEFF072B911C8A6E8B59917A3A99EA9E3AC0F73326401D708114DD06830B86416F6BCFC5C6F5", + "k" : "62881BB82AA26272A9C13D99D0AE671B441109970F811762C1C4110D852913DB", +}, +{ + "rngSeed" : "D0611F9AE5BE4DA5D7EADC9109944348E716CB3DAEE545721EEA8C892E7831CF2E54603146454CBFD92387739E9A78D8", + "pk" : "2E248784527EC73160954A18DAB4986FD146767BAC1506885A7ABBAF203FA7923CF3644B146A7687DC0F56329E3C64B052DB6C14E3211CC560D9A70A1BA641224B2EB8E70E44B25B4B346F3037454AA69744D1777498C98CE741AC1008461868839B4149135B41817D135060ACECCA5AF744E982142DE574ECAC5F1432A7D907628EB75439D8AF02D37E5181681F1B249BCB22D52961D20458C860CEB3175730ACB9B8C8500DC258FEC13677F40506BC76F8EB31CC91A605E905EE839C3E0B771C32595A3238ACC079FE6034769652E5CB492DA0A3E8C0CDF13C899CD5838BB46A27E343BC62CCB6294C1619AF96817D77EBC2E1431F997566485327CB9331A262153CD31C80D939D473B81FEB0910E027B02C29CFD66FBED3CD09C11FA08744B9E0B62DC3093C2552BC7A770A0550CD601B2E6559851BBB5D8665865555AE510C2DF9637C07790639C0AF6B4BDBD567B704C267E6ABF2B371F580686A1910BCC02B7EC3C08A7ACA3FD121CDA343A61C6C995742159CCE5503B4996A7A6FAB9E8DD5713BF62F3C0792628AB621741034208CA01C6130D3A3499A186FD69DB4B3CB77417A12992E8E448FB75B73F4CA54FDA42B2DF2A4F9E14C39424BD1592B90968434EB8F52A6A1438CB7E589740C8B9B2B6123600B28EE954CF0D18DAB1BB3FEC8A0FF6379A4313325C7011F4C7FEAD33C8FB543C3C90B6AB35E01E31E2DD4262BCC92BA11BA055295B3F2A273620576813232876D1E9B18E22639E9C3759EB460390BCCED9BB0E368C6CAD846767C69349C59FDE27405D8CCC900AC2ED762B1AB6381EAC33F14AA27C047E5A63921030F8EE7055DF00F7CD353BDC1487FC0875746B9DEACA76FBC70EF5925EBBB994833A7EED732235B06E6EC6B28217C7D9A86A5396C80D43C22C56C19570238C70E7A7C2B6A77BCA45785CCC31D8A880BE379B05E45A1B9A8B3B2520826F888A8A025E28ABCC4320BD1E30FDD17CBB3018A7A784534379C46639A21227D279B61DA608BDF9BB9304B322F103A6A762DB152548F192534A94DF0BA1B2C97B9AF8202DFC646A84270400CBECA95AADA593D8F4719ABB6CD4A4699787B92D63279FE9BACC0A989A59CB0AD279A567B8CA9536E8107AA7B81B2BF7730B9F4A470C8170655A0842602BC4610F9E7BBDC6ACFBDC4732E4266083C9C91D41ED1F2422822ACD01BAB34C4789A63A700A5A135D65495841E69CA2F5334CBB1FC4C7D42B0F53BB63F888146163A51759C43349377CA824B32091E9B9C30E025981B82CD23AEB5385BE7F398AA5025E87B605827328EBB32D6682896298F652243EBB3B8A6F759DB824D3F577CFB8AA04627A80A03804039478ABC2A627779D1C87FB23453CA254FB51C629F17C1EDC8CD8C71AAFA135051320F81C65B06711282EC6E7E4B021EEAC0C3FC7CEB4B192897899F6C145F53BFA2D68A5B583002667D101A9C7E721F0DA0711CA79DF954126D9199FD6351BE89225CC52D6BE5C906860F6AC81C56477CD34C94EE43B920EB6CB62BCF27E5669F9160F0EB2CE7389B8DA47CF8B22F46452961457DC39C54FDE66A41F95CEE1BA87682CA6342AB76F6BC262632282A22293BA7BE9CC567700B5C13AC19F126B16A43BAE7E4AF067D280590FF759D4C3A502AB563080DBFE1DF14AC06D254FC", + "sk" : "76C9AB126B3D022C31745279F6E684083A496BE39AEE74BB599A8B6DE9940A26535A2600D3CA572EDBCC37D721B7614824A123B4C6C8A01A0568B8AB61045C3339AD02E68F16D16C17AC572F9BA77D279D38636C9134C501B7C00518BD0E3293FA3A1612D16488C7BCC4CCA7FCB5595191CF0D43C2974C0D8551A72D252896A8BAA7740C419A1270E6B7145B053FF828344B30D5C18BE9F2C633799970C44BC49C2C485921B96BA685AC1BD9A914BFA026A35BC1EEC70B8562C9D825A4C7D5A60470C61244C88681AF5804B587141DBF72BCBF7604A0705D655B00B89B9045C0A291A355CE68A07F79847A181401C028590788B7A2C3D95B84F13993DA06556A240B16887B78E43C310928459312F196BB04A7BEE1E0969D72264DB1BA0FDBB54ED8C49C3BCCDC44A9D4605DB677002A0CC84402968CC7759743BF2AB97F0A4A67D95B93A5C7C51FF91201676394E69ACC8AA6C88C17535CABB8DC07ACDB239B848A8BD88ED0430E3381A6A92B9DDF04955DD06E01717F9036920DDCB33E017FA3103CDCB955B3958347A162F0DB95A3B2377C4C6027353266A91876F698EE53787DD73BB9978C7984713DEB0017FA1DF2B10FEEF4C7AE5734ECD7CE2B043793B1A19655950799243EB493EAC103FE0A174D67B728B7097DEC31BF1188813B16C1129A27669FC557C0DEA7BDEF1303AD98B81E8665FFB009FE5440478267AB2310A34C3F11C88EF8FA5736B91CB2972D1BA772AED1B9FEF64AF7E547BEE627FD9232CEC559D4CCB36E8702379231EE5A604CDBAA53DB415E0588958321709CCE82748FDBC257535584D8D89DBD7CC2D857CE3AB498C31B74FA305D8B145184A906B89A28A82B071D8BC4C52623C306766A150606B63021919759C76102503C03478DCDD7CDDF71042173C91C70682AE684FB488F6378678AD114D8E6C625087741E868F1176CD09721E9812D7BF5C63E21974201D0F2844959C898581994AB664FF6784601268B4589C20B4C9873E49F03856DEBCC266764339329B327E375406A54A0B4C89439116FAB279D6B2B9AD0A09ADA94A1D572ADE29DFF802813699026732C30167480CC2230283801BB2BAF3CB3CDF88E18F79852A13269C328A555955DC04733E48582F0768F40168F468C83060D0F1BC735BA197CDBBA40DC50CD38C53C2A3481B763935B1071879D77967598B2AA8AA1AD34863A6DB84DCA6628907723F9891A4434339DBCC19213BEC2463C5B37B82BC40821F5A33CC391CBA73E3C7AA397C71B6F835C29D70C226628FAD2AD7014345098A55502A6BC75003B449786B9534AC31E8B6871C7C98BE6CA03A974A0936C4598438BFC953B691771C93B83B87579DDB6BC6F5721E2490FA9E0B36BB26C7607BD4BDC003AC9C2B0F41B7B9B5FBE9432B9D7C164D938B43698271A991D4A234FD1BBB28B07B5B5206FB75B4EE75BB3A28539462C01CBCEB619B3E2814E5EFC79ECDA14462B46782308A5E61C2696B71CF367FA421CAFD1C0AF5BC6B6A7BF07D3B504C05C57F184700572A777BB0C32C7B82212D6C783D9696E96F11A9AF791857526BE109141793C7B92823F4B116196B8695C0B00A46D521B49241452331A4EDF2A56E0264505C0682E248784527EC73160954A18DAB4986FD146767BAC1506885A7ABBAF203FA7923CF3644B146A7687DC0F56329E3C64B052DB6C14E3211CC560D9A70A1BA641224B2EB8E70E44B25B4B346F3037454AA69744D1777498C98CE741AC1008461868839B4149135B41817D135060ACECCA5AF744E982142DE574ECAC5F1432A7D907628EB75439D8AF02D37E5181681F1B249BCB22D52961D20458C860CEB3175730ACB9B8C8500DC258FEC13677F40506BC76F8EB31CC91A605E905EE839C3E0B771C32595A3238ACC079FE6034769652E5CB492DA0A3E8C0CDF13C899CD5838BB46A27E343BC62CCB6294C1619AF96817D77EBC2E1431F997566485327CB9331A262153CD31C80D939D473B81FEB0910E027B02C29CFD66FBED3CD09C11FA08744B9E0B62DC3093C2552BC7A770A0550CD601B2E6559851BBB5D8665865555AE510C2DF9637C07790639C0AF6B4BDBD567B704C267E6ABF2B371F580686A1910BCC02B7EC3C08A7ACA3FD121CDA343A61C6C995742159CCE5503B4996A7A6FAB9E8DD5713BF62F3C0792628AB621741034208CA01C6130D3A3499A186FD69DB4B3CB77417A12992E8E448FB75B73F4CA54FDA42B2DF2A4F9E14C39424BD1592B90968434EB8F52A6A1438CB7E589740C8B9B2B6123600B28EE954CF0D18DAB1BB3FEC8A0FF6379A4313325C7011F4C7FEAD33C8FB543C3C90B6AB35E01E31E2DD4262BCC92BA11BA055295B3F2A273620576813232876D1E9B18E22639E9C3759EB460390BCCED9BB0E368C6CAD846767C69349C59FDE27405D8CCC900AC2ED762B1AB6381EAC33F14AA27C047E5A63921030F8EE7055DF00F7CD353BDC1487FC0875746B9DEACA76FBC70EF5925EBBB994833A7EED732235B06E6EC6B28217C7D9A86A5396C80D43C22C56C19570238C70E7A7C2B6A77BCA45785CCC31D8A880BE379B05E45A1B9A8B3B2520826F888A8A025E28ABCC4320BD1E30FDD17CBB3018A7A784534379C46639A21227D279B61DA608BDF9BB9304B322F103A6A762DB152548F192534A94DF0BA1B2C97B9AF8202DFC646A84270400CBECA95AADA593D8F4719ABB6CD4A4699787B92D63279FE9BACC0A989A59CB0AD279A567B8CA9536E8107AA7B81B2BF7730B9F4A470C8170655A0842602BC4610F9E7BBDC6ACFBDC4732E4266083C9C91D41ED1F2422822ACD01BAB34C4789A63A700A5A135D65495841E69CA2F5334CBB1FC4C7D42B0F53BB63F888146163A51759C43349377CA824B32091E9B9C30E025981B82CD23AEB5385BE7F398AA5025E87B605827328EBB32D6682896298F652243EBB3B8A6F759DB824D3F577CFB8AA04627A80A03804039478ABC2A627779D1C87FB23453CA254FB51C629F17C1EDC8CD8C71AAFA135051320F81C65B06711282EC6E7E4B021EEAC0C3FC7CEB4B192897899F6C145F53BFA2D68A5B583002667D101A9C7E721F0DA0711CA79DF954126D9199FD6351BE89225CC52D6BE5C906860F6AC81C56477CD34C94EE43B920EB6CB62BCF27E5669F9160F0EB2CE7389B8DA47CF8B22F46452961457DC39C54FDE66A41F95CEE1BA87682CA6342AB76F6BC262632282A22293BA7BE9CC567700B5C13AC19F126B16A43BAE7E4AF067D280590FF759D4C3A502AB563080DBFE1DF14AC06D254FC149CA4D94813F81C792060502E09A88EA694C5DE863CE6A50516CACB1C3F44BC1056461570B29E27126962068B2D07EB33DB448A2938785E6FB3E02675A6EC67", + "ek" : "F86369AEDBE31BEBB3E3E837726D3CD9574A144FDABC021B644683F366DAFF8CB24A9269140F4DBCE23612819DC1E1EAAA31470951D362E9DCCE363504F564D453FCF206B4F381FFA8EF4F34A24C1B43470762AB52D6AECCF707A8F995DE430E9E0573F0DFFDB41CA0CFCED92886A1D2ABD027BB649A6048B434EA1BFE9E380FDF9929F602E9D78C4160C85B4096C740C5974E8E5ED18A23F1FE021ABA998ACDC93C5164FA8EB9BBA3EA8ACBC9B3161BF37AEAC56A7192E4F692C90EBE44E4D314C22F2EC8AEE83D215614C798F994D022B2D695A0F712DD48673280CD1A121D7AD11269D3B268AF94ECD01FEE113D39ED99CAC102CD6C7486D68554C973ABF78DF24ED2775B301854B935D22808C4EE0DA424FD6E964C401DE7FB2AD5712D071E2F46F01CA1B953706E4A2B31885A7D11680A180C36DDF3482DB2430FD1BCEB9A4636616E46E89052C2663E4B23F42FFF809F8DB68BEC7402C3946822217BAA08BB05F70A9F3F813265A435EE0EFAB6F6937632E92278A48877E0433477231A67985DBDE65BD2D9CEAC815BF0106D332800857339D640073904944CC3CD006079F9D267D4D112B8EECFEAAB43AF43CBCA422A7C445E5C2E9C05A252C030B366EEC7FDAC0BD133B34DF3EF2724C4191A2C90DCA54BC2C413C1F8D89F9BE47F706D298F596FCF3970B5D6362C1C50CFE2BB08C3D806ADD8411C5FFB7F2EF84EA3E7F05E73095C75C2767CB14EE91032210FAC70481ED11D94726D7A36F390A8951655471CC9981B4E8C69F9AAB789FFD01E559B78295667857B1023C471F7B37765525629F8E57BCFDE531EE9BDC24BA7E2AA8B340903B3A6E2C1504E0768F5C2CFE5571AEAE0C9CAF2D9D6BAF0872B974D6581EF22B33753431DC4CF5559140C48FB40C497C2CE401F524EBB2B61368129F12B157A12F905F49C6E71EB2F7F7309D4E2F89358997C985D3DD436D6CBA77F5977631532A27DA99603B8B9DBF9365BB99ADC8DBB0E4E7992D73654227C93B1F68E0DD31C02A7F3BCDF5ECC35E0E7C4C4F094E200B8232602338CAED0B9FB44CAE930D36CEA67F1E8FE293999B37709A799C61487863C81D1CF541A4F52EAB500CFB79161DB0D4B0B922CFE760AB8CD6E3CF26F263BD0205B9C719A0387938850D5343FFD17919B2A5C999E561047F4D58FF0EA9035ADDA5902AC7C047237B18DB38EB3EC177AA441A8631512188875CD38E2246D881AA0BA2110A6408B9EC892500A8F79EDEBDDB156EC5EF298DA32CBF5A3E072D9CD14C4EE71D3B77E1EAEFF008B0A60445F672DE5E36D01655D0D6F25D3180EA19E6405853B79413289ECD4DB1F059F8EC043E4D0689D38EB97E9A400950A68852BAC3197C84C03E06D59D819039DCAFC06E74D3DAF7A4FCC1B7183BF0E0EB58A49DE1E5693C96D8BC4A2FF3A1EB6E469FBCDE1B5F8285E7499CC28D1B5891DD97F83F993AC3E1C0BC0692675504168442D0F1B8709D50C21971C5A24DE8D4E44086BCEA8BB5A10BB3DDC564D04E852B55E11D73DE6B7325140", + "k" : "E6C95F2B105F6E6EA86B35568F4F6EDD09256234CE001DC7CB173B35FB978C1D", +}, +{ + "rngSeed" : "FBC38D7614D7718E931EDB850D2C6F0C5EEA9EE889B3E25BD69AC255D5B91E885D93E808E66BF9C88C655DC594DA5792", + "pk" : "0055AFAB2B0F8C4481D2316C876607A02B744637928897C26C1C5762524F42A00B27D4AB7C198334A13750B8BEE321CF5021CBE4536246A0879890CE6F042DE3955E373C113D7C2E2DF360A8FB5C76FA7F1F594B64B562D0C3B524756B2F94667DE31F9A67AEFECA35D6641D17D167D6D955D6BCC1709297C9277CF614423B212E96281F6100074D2C2209F976DF6332285B3C412A8F618C5B5175302952366A5C67462B07FB74CECC5726CA861E47D4C599819D26329568C139ECD31B22CCAC2901D0BD347BA5F10A51B69DBBBCA90B574405D8C0600617E682BF81472018284A70982773434D07286B319CA4E3FA6B24B25171093CEFA559AA33AD3A0336A1A18205A07EC4463511D3BE9CE0B05944819B9647FFD94337C94B7831694BA31CBF8C7AF238C21DC1060799C09BB8AAE0A084CAB07C3BB8502275398E05058B142794309E3BB287FA32A016F46E9FEB9115F09A313970293B25E7D25C4ABB623C1959D6246D7E00BA79068EA03963D9598FB2B04879C3379397B086960C0D896E419CA5F7667264E1907102329474867CF43A426B1E117826CA542CCE64ADCBE154F36637DE2CBDBDD6C1AD7794A0C18FA339993E873EA54C3F92A68AFE0445305BC97B76C61B3BC693E30B2A2B18A6CC28ADD35CDCF601554B17DF39998516549B823AE1596D2A88ACB9433433926AF62263DEB704A561B2F2397381228FC5B15BD93C3911DB634B19CD7217508E328113D565B475393D95C7ABE5A94FD6C1CC1283587B97DB55109A08B1AE1060CECBB15675A253EA154EE19AA9EC29EC33400E4946B89B5B1B4CCD41362A3CC75808408F50CA8662B236F1830656A432E2193BC4F09AD1FC6A82252174A6530B3B078808C8798C9E110820C295797580A74572ADB025CC31C75017468CAE17C697A79DF023AA250C827C11A1491944B9D6156D24B1F0F53C12A1AAA5946BDA21485CD18AAC0034DE843489B7CAE9EA90197CC471444067D01F873175693224C5368E3F3220AE48832C0928E65195510B5D4EBA93DD3B217B79481AEBC34F2123CE42C0ABA83ECE60034ECBC0EC4420DE32851A998207F770F3E2BF94B047779B6187E083F7E04458C243D9125DD1641EC413CCF0A02811AB65D7D954BF4CC0CAE00C384889D1B23405419180EC83D9CCC170E0BD6BCA3E2682BF3471024445329A515456175EF6C167DA459DA6F3439DAB20FB28BFB9764D5D9B9AF055B442399361E91F84965FBCB31A4DB147CF5CBD37B955FA3B0A34B78F8F4B2CF584C1F3646B5D7887A99B3847BA9010A69C89F52653C2C4FD2A6CBCEC2D00392A1AA44DDAD605D8E1595D2BA305CBC86B24A47725810A761C45C6CD0177262B2C85BEABC07F5086EA31BD443889AE657C9528ABB2769EDC8CC74BC80943F92E88402EC231823E15112FF5624C982BE7669010E31AC9494334488105EB88658339DB648F30B3A08B7A7B5BD1113A83055F673A8FD6CA10CB4CE3C32645FC42ED24420B222D512C68651A0B99875EF8E913B984C709221228E51BD2C2407CD49A06E83F7F12C15D33B0252937F857BEAF9BA79045CBA8264D7706270D4787F6ECB8922582B7321C26DA7813EB1C61A80038289CC84A923E03D7AE3CB232D5E0C1E7715D7B305D86D34FE89069774BF4339A1249BE49B1", + "sk" : "672A64B0079B3B7C18878338AEE97B73D9AD10231709A4547941C0C5C1A6297367BCE3B5D68B929F611C5BA26F39B199CA2A82BEC9AD6318BE48D75F9EC7CAE3EB4D1732B8EB9A742216723B4BACEA934113054AF3CC752201859DDC1A990680FB573EFC845A85DCAB5C352DC701A45E5804A819644037BD095615E7389C2BBC49CB9BCF192B072B539D93FB993BB73F5F3B1549B13E5F90C8AA82991384B310BCA58183116FA964DC1CC15C933DD9604BA6CB83C694132C628AC0901C5FDC45C808C2D06947008515CA95C77B486B1DB3406665B0201498F721588335C55D2366EB7867AB2A8DEBC248DF0CAA3E637643455F7CE625F9F0B43C8787FAD449F9214F78551F9556272F7A7040687EB185521A1A576F201373C61840B346D91B94FFCA34DF0045CFA4B5364432C7E2344A837D3C09C21CA23A957038D8EB30DC91CD9B25837155663B923B6F6766A4555475B04D74F350CB2640CC07CCE818609033A8730B0E7C234D9B8B4F7D77CDC095C11E0C8EF16B3EB63C06F72514B57501DCF04DDC162096B99E6B1036EE0118975932041A5D5EF118E62B0429D4117D89B72924AFD97770FCACAF9BF92824B9ADA2674DD4AC40DC8471ACE7102D13058A740246010A685B9814216A295538DEC1A9289473AEAB46C6E3CDFF4335DEC9055C5BAA481918BCFB0A63CB7E62123E19F1939C1030EE95709DEA6844FB978410989AE9B2666984E38062A1D066FB91B362120C7F3BB5488628376B1C827B50FB11B3E4A630C52A32D5A40E671BA0E99269EF09BF1EAB049CA04ECFBBC213B74AC06AA790A85757A9BE1C852199E7CA0ADA5E07E7CCF352B3F3307631E30C604BBA95D8AEDBC44D12F73E7F51B4B8537E5DB967D2738E3A13A33149C00ED24560753F34B85B85C535CE644B15E046B104B23B3C51562C47DBC92F2B44AD0F1890F98044FF3092498416996886C55CBE1812AECC6AA3D08A4F89C62708495ECCF13C02A6B2B202732888297B3ACA8861BBA2E1CAD6E7658686CE07DA3580232B5B75C61AE1AE72A344293855F47A3AAD11C4B716C211128091065A07439A40ABAF2D62C674D40A6B1468B61AC2E22ACCCF25C0783B5CDFC60A47131F0BC6133C55B92E246B9C722EF680BC0CA12C7DC1C46128863507781937B9E02B5355D2B8399C31B6A80EC1137E5FE9AE01D980E0CA647A7B3678006C678147529A32DF269DCC378416B14D61B240C4742247BC1B77EB905C6889FA022910A974F262733EE14B75B302E5148063E5CCF3984D073410BCD9096C38AA99C14DCF69AAA3FB32282352FB4A315B736774558753D7A1615C9FD5D30904E1186162A2DACC96003841934A40DD604983979838FB5382FA6DEE1A4CDF3063326503ED665FE3EA84953B522872C36E7888864A0E55F3466BF20DB1263CC0FA91660561C6F3171F45C2BD5652C95359E0150988F58AB5F69232008B62114195F570A3DC9C916073373540538A56E22B4DBA234EB315BC15B3C89AB64A9962282E3C20BAA7AA540C8273B83A39815131D24E3643353E5A4DF3E986ABEA49BCB2B96BE28A6C4998CE24278652C59F0C5E6C39A52A7269BC769DC6E3B75BD34E7BE7C4F86A93506B0510310C0055AFAB2B0F8C4481D2316C876607A02B744637928897C26C1C5762524F42A00B27D4AB7C198334A13750B8BEE321CF5021CBE4536246A0879890CE6F042DE3955E373C113D7C2E2DF360A8FB5C76FA7F1F594B64B562D0C3B524756B2F94667DE31F9A67AEFECA35D6641D17D167D6D955D6BCC1709297C9277CF614423B212E96281F6100074D2C2209F976DF6332285B3C412A8F618C5B5175302952366A5C67462B07FB74CECC5726CA861E47D4C599819D26329568C139ECD31B22CCAC2901D0BD347BA5F10A51B69DBBBCA90B574405D8C0600617E682BF81472018284A70982773434D07286B319CA4E3FA6B24B25171093CEFA559AA33AD3A0336A1A18205A07EC4463511D3BE9CE0B05944819B9647FFD94337C94B7831694BA31CBF8C7AF238C21DC1060799C09BB8AAE0A084CAB07C3BB8502275398E05058B142794309E3BB287FA32A016F46E9FEB9115F09A313970293B25E7D25C4ABB623C1959D6246D7E00BA79068EA03963D9598FB2B04879C3379397B086960C0D896E419CA5F7667264E1907102329474867CF43A426B1E117826CA542CCE64ADCBE154F36637DE2CBDBDD6C1AD7794A0C18FA339993E873EA54C3F92A68AFE0445305BC97B76C61B3BC693E30B2A2B18A6CC28ADD35CDCF601554B17DF39998516549B823AE1596D2A88ACB9433433926AF62263DEB704A561B2F2397381228FC5B15BD93C3911DB634B19CD7217508E328113D565B475393D95C7ABE5A94FD6C1CC1283587B97DB55109A08B1AE1060CECBB15675A253EA154EE19AA9EC29EC33400E4946B89B5B1B4CCD41362A3CC75808408F50CA8662B236F1830656A432E2193BC4F09AD1FC6A82252174A6530B3B078808C8798C9E110820C295797580A74572ADB025CC31C75017468CAE17C697A79DF023AA250C827C11A1491944B9D6156D24B1F0F53C12A1AAA5946BDA21485CD18AAC0034DE843489B7CAE9EA90197CC471444067D01F873175693224C5368E3F3220AE48832C0928E65195510B5D4EBA93DD3B217B79481AEBC34F2123CE42C0ABA83ECE60034ECBC0EC4420DE32851A998207F770F3E2BF94B047779B6187E083F7E04458C243D9125DD1641EC413CCF0A02811AB65D7D954BF4CC0CAE00C384889D1B23405419180EC83D9CCC170E0BD6BCA3E2682BF3471024445329A515456175EF6C167DA459DA6F3439DAB20FB28BFB9764D5D9B9AF055B442399361E91F84965FBCB31A4DB147CF5CBD37B955FA3B0A34B78F8F4B2CF584C1F3646B5D7887A99B3847BA9010A69C89F52653C2C4FD2A6CBCEC2D00392A1AA44DDAD605D8E1595D2BA305CBC86B24A47725810A761C45C6CD0177262B2C85BEABC07F5086EA31BD443889AE657C9528ABB2769EDC8CC74BC80943F92E88402EC231823E15112FF5624C982BE7669010E31AC9494334488105EB88658339DB648F30B3A08B7A7B5BD1113A83055F673A8FD6CA10CB4CE3C32645FC42ED24420B222D512C68651A0B99875EF8E913B984C709221228E51BD2C2407CD49A06E83F7F12C15D33B0252937F857BEAF9BA79045CBA8264D7706270D4787F6ECB8922582B7321C26DA7813EB1C61A80038289CC84A923E03D7AE3CB232D5E0C1E7715D7B305D86D34FE89069774BF4339A1249BE49B1E5C52E639E5ACD0FB97C7EB44DF56DF5250C6DE7D171C467CE6887EAA4EE3D612DC85FEF74A61DA258EDFF86F377FF16F321689E7BA5052364D2448A333C7961", + "ek" : "2A4E56F0614B990EC4A6F65967A99844664F60CA86A5092963CED70816946C37A5A4A354333A2D68BD446C1B8F9268080ECA275A51E00719A43F445FAB9E7FD343700F72A31310D0625D4327CFED5F36CD6EB2319D249E60F8744194A8D6E48539527E4527F22FDB3FC41DD271EEDA2D3B81270A49FE01D447A1E607A84CA653DAC0F0494D85F6D60DDDE9828F5C89D10ED9325C68EABD8CC76042FA7ADBF0A642460F32CC348F385A05C9A00D29B75E6BB6B230A38D414A412F587751FFA89B784474C8121832A86E4DFAE189A0F8B7DA63A6DFE2017F7990A78A717514D9A68E0B44989C708D1FB64901FA0F6BB9D3F7337F30DD2EA6C4040E25D225099020E00F724B18B66C749440BF3FA214040F9F363A4BE810BE31CCDACE9511C2D15203A5928591BD762720DA39D202DC43DC38BD41C4C576FDC0B5A1F6AEA4B8B59DA883D2557340FAD8540D56BF17CAF1BD4BE056D415003804DFC520686C38F7C9940D170E1043B137B715217DB5EBC17233FAC7A29A51BF49C8C6BFA291ADA9CB0621880D5DA6EB1D347A4234FF62F71EB2653453BCECFE53C5D3121663BFDD301FA46821BC7E4AC08AB4450B8789120E7460DBD9D58B90F293E8E027DFE3CBDE0F6F87022A2D2D7591E7E230E88B73573A5008420666FE7AF031DAD33E2CD7BE7195215103F8858D1F6530CD9A56A032FDE765BA98AA53B8F3F0DD9CD63B017DA27AB54551A8123A639DD06855ABCF26BECEBCC1A0ABA9A5FB8843E53A3963F25E4C085D1B74DB6B210F8DE4F13333D2B5EE1A2216226296604616DFD7DEB88D756716989C2BA09073DA2DDFF0A7446613D1B406C880BE63BB274C4F8FC9CD08E6F603BFA7016000FF5AA76A45685D9D54B6C3D64D726619FFCA6E56F5729EF4DFC3A17795F6A33076D854D8CE3C8EB5AB0BB281A3EB337FA278A54C1892DDBC5AFEB8ADC3CC921680B5A273A813B6A2E6BAFC2C8CF235AE4BC5022F66613AC2EC8DA1263A9FFB6C89C4BA72BCE5BD304B211A6F5AA6838D649C8687C5939A635250D2FD3B5298F1A51052D82F8D33BF73CDF7413B54647DA3F7051C4B865737D79E434B7469A51168ECC92071C1B9C727D0F27ACB1924E796BC19ADBFF9684FDBFEFF11D7784A7C1158078AFB76525DA319C4B474993EA5827651C55AF8DA3318D1D1D9CC7B72330F4C13F3DF23EF97826CD644DE2A6C666414EC1484D505AC9BCB9F54E3C292F615DBB93EF6F0A11F8FABA95CD33AB3504A164A18FC801FC72F5B296C05CE8C3A21924D0681E653775E8E609F159B831E3ACF6CD18F369734536AEAC6CA0D3B9E86BAF6839DFA26B2EE24A7C68F4DFAACBBD2948684B275056287CE63BA50326BD6A34469F39202E1025E9426121D3381B70387112F2EE6DD9AA273AE5A132081D1BC4725E9B0FA0E9B538D7888D1344F4BE201B161D3AA3AF1AE40AB0124D1A1235FBFB441C871730897D8609BBA23AD1E9C4D32A02612D17DFF87FFD65AFB386ECC48C73503F276EE0EA76829EF3B2EC4B626004DFCB17A", + "k" : "2FF771C30FBBEE5F0D1E8E8D2F0F27BF3C858141C3FCD6846181767F27A149C8", +}, +{ + "rngSeed" : "1722219CB5DB47374EB0AF0232C856A57F026F1CB09E5A5799F4C333DD422FF6A0A67C4DA502FAAE727FB2D45DAFCF35", + "pk" : "C1CC248A969A9DEB8BA9C43E80799F3E287B4263BDA1A1055D152BE8C84A4DF5447B43295D0BA65D2A9B2D15A3B139507A3C2A44965E68E7CAA4D9AEB4F67CED404305C81782CA49656775E10AA531F01C66793E198092E2B538DF264818E7AFDC94AB3CDA837164CBAEEC93FE2B8B59397482F084AF51976BB6161C026761A22DD5A26457C648ED0817FF0A45FBC8C7E0E6C45767B7A720997CA60453785B73A43522979D06B365481A54E8124E9F4274950315FAA27F5F8C50699164414398D72321A9D5C2181338DE5187BAA2C0C5097BFBC72945B15406EB1E88CAA3FF92886A6A4FE2C8794700211AC32E1968643AE5A6C3AA309433CAB3E48AA93A560FD18550F19831F6C74E811B8BE5771244954DA635A2FB6C314B9D77F1BF26FAB613872D0A2098DFF0B060516FEEA45293E28C0ED088BBFC0165A1906473063E97C5B2825100116793FB1DFC9447FE3227D96BC5E999CDF1F545C8753E4AB43D211C80BA9646E86651D928B0C9E64F5C2CA80B99914D878641A53A6A385ACAAB6D9B5690D11A8EF5A08C35E80C5DF91463C76366282543B08C0BC3054CE07C32FC10AE021BDAFCB744C20DD131C8D4146F1FBB282250941D8A1CDAE68B4C5961A7A437B3251F144586AEC15F505AA79305797A16CDF4C89209B02BDAAA0C0D367E2DC7097A9900BAC5CF7063C3B2027AB05B204FBC997F333122798670E3488CF4BC64089A15A97F0C0A4AB5680FB9D5A9A815234E158316F31948B80CA33523E2303838D55EA2368B037A607B643EE8B2488EE456273158A3675B56967CE7B4A1BD2C22A91083E474AB9121CFA0F2BD1A24B27AA317C34B968DF055DEB839EF172FFD0489BC524109AA9897383F9CF0226810B56BC75B699187BBE86D465C7A44B65AA828C40CE76DE88CBD6671093CA1689506657CDB6B3CC5A9A0293D16057E700A3BB7623E3CE1C8815B1D17066853B1CD807C0803F9A9FC2B62F637C99535A1733159FF79A863BA9203D57C80F0BBE02052E41004CD42388FDC695D9722BB0147C55510CFB9347127002FA9038F42551FE1656F1C4BA91C47E5FBCC5E83013864209290CF7D901213A26E1FA79AA7576C7C4103CFA01EC6E1459C9AACC449AF7D10ACA0A4171B284D4473C9AF9A84546B03C7D5CEA7BC723DC5032157B58431BA9A895D35F89274E827470BABBA0342567648BA84A51AA5A604B4C36A27C0B2710B2388B53085603CF62D9EA0A6A6864971323ED9E934D7471E65A4915ADA5DD1E7482A37517CFA6255782EBC7B789C4A6D2AA746A811C0BE90079F138DFCC812ADAC7C4BD862DDB83CF0D6B74B623B523318BC807163E6C98D777C7ED0628266BD53A29636B601E162466CFB700ED35B0966A7DAF32E7DD67AA1C08E7CCA8F18FCB7BD3104BB5408637C08EACA654B19523AC0A031B76968D71D9C013501A1350742467970C2813762C1B4219DC904202984CB49B33E91328B0350AD36B4A7650F7505B11B5C6F0520CCCF788B87B5AEF42B44B567C42555C74F40CE66CC9003730928E859C77099D8149C78588FDF0C347EEB6752B39B755122E715843ED2A859C02A81E7705127A52D53047F973952321D34D4278739C4BAB50A5C344011CB196DBA2BC5197ACCD11B3F6E5D57B37115E763177A6910C9866C85ED61C6", + "sk" : "0BCCBF3CF040D5B87D74815458749AACE6C82DC66A6A7672E534A60474B566C4060EC61E23F5AA640245FB2817185B0B4DE26EAD3744F0373F4172A6095821BB873F34B94733E60DDDB312A1EC916DC0C10ACA85B65A9407547C133B1CC32205C7362F3E458BBC507ECE9C7B13176F877336A7348B4D785C3DE0641D000268A37929C254C826BB643117E36A3B28120EB67104D8EA4509536BB0D54D1D11720A31B4E20B14AA57A81F45B3133525D5A49EB1C59E9CB36774421149F734B3B7778E4B3A2ED20E5CD8A56636C100F7A704F5691D0383140A633FFBCBDC5324FF329F46E5AFB27070EEE32C5008637708A248593EC00884A87231B7C457D969AD8BB44841D5C76A35AB1FC3031E704CFF9045F80B3A2B925AF1714FF78B25E798218D163B17E154634C1141A39BF9D35AA7CC9BD2A56032032CAF8A6C61319D524ACDB42B1FFDFA0B6D70673DE99972B21E046737B11850DFE62E30C40D2D7C212354AB529477C9345AAF8A0E840B7BA236C7A3BA508DC995E6DC4A80B77B6CE1C26F8AC42304C91C215698829137E446E49414FD91CF7B9034F5301A81CB4D3251A47C64979EA133EA16012B2C48FEA9AE3EAA71F53272AF878D356447C9FCB163C938225A53119B3CB914BF9B9B8BB40A2B99A6C4B6AB5055288639802DF6810A9F28607FF0537B92A640EC4A2F222075AB917DD2BD49FB1DEBD6435257AC656687FF75BC70F7B62722664DA57882FA1B336819D8367466E936A62724DDF9C6CF439D44282645D5B13D84754799AB7170BB13FAACEA545EC2E52394851C21C01AAA5B31F72247600A25EB05D00443B3B85C3C176450CED12A8F583716A93EC1CB9D8E03436F383A3AF0322CCA926DFB45554045FA903A5AE8BE04BBCAF858A84EC35793AA9D03D3882AD873289A337E37AAAD72B912882AD657BDCCF82E65CA3E554AC1E16A44D609C62DC71356AC04536B7ED72AB0FFCC9981031F7EC68F7FA6C761D219A8A78FE7D527F82BA81592C89513B47BD41470E7110ACA8B85B9042BF9B4F2E29221164BB21A0EAA30A624A285C15C92FFE3630F19C35F02B9B54BC0C2B958C1C088491B990018BB66996BFE868A55F9C000A72264A649E535BC5E5CC86B1079F556947A80A6352C6BAE64A97EF3A1BB1B2886FC5E0D284F81534CC3C1A6403B8C2842CC5909BB642343FBBAAA17FA255723055F7644366C7F4744C01427B9D9D1935AFCB732EBC6F2F6CFB8A6C492482E7F046B32A232C3D74472CA7CF64490F0F68F4DA0B1D81650384A1288F374A2A9C0153805A2709DA5D5154F79CFAE9A564166C601D75D7FD3A434269497E41AD316ADC65CB152148327F86134D085B2B809CE96B16F6C38E4B107A2FA3CF11B0DAE7B37C4285F3F9A10E0009FC8CC1459CBA60E38222648BD76A8C770282FF5C57B74F393A8D01C0EC05B4169BBF487769DE35E4890382B376C030AA67B28A2A3AA4D8CC8AC6D96254DC7911EC48076247DC2DB021880975A49B3995854C22B89F3B1B1D4993C43456BB647C8F83CA66D613BF3EB3B7DA4A252A0A7E2E61BF82C20EFB11A83D1B9D1E087520991636728318602D4F8C5B918763BE1C1B1479035B2A52F4A194042A006B483C1CC248A969A9DEB8BA9C43E80799F3E287B4263BDA1A1055D152BE8C84A4DF5447B43295D0BA65D2A9B2D15A3B139507A3C2A44965E68E7CAA4D9AEB4F67CED404305C81782CA49656775E10AA531F01C66793E198092E2B538DF264818E7AFDC94AB3CDA837164CBAEEC93FE2B8B59397482F084AF51976BB6161C026761A22DD5A26457C648ED0817FF0A45FBC8C7E0E6C45767B7A720997CA60453785B73A43522979D06B365481A54E8124E9F4274950315FAA27F5F8C50699164414398D72321A9D5C2181338DE5187BAA2C0C5097BFBC72945B15406EB1E88CAA3FF92886A6A4FE2C8794700211AC32E1968643AE5A6C3AA309433CAB3E48AA93A560FD18550F19831F6C74E811B8BE5771244954DA635A2FB6C314B9D77F1BF26FAB613872D0A2098DFF0B060516FEEA45293E28C0ED088BBFC0165A1906473063E97C5B2825100116793FB1DFC9447FE3227D96BC5E999CDF1F545C8753E4AB43D211C80BA9646E86651D928B0C9E64F5C2CA80B99914D878641A53A6A385ACAAB6D9B5690D11A8EF5A08C35E80C5DF91463C76366282543B08C0BC3054CE07C32FC10AE021BDAFCB744C20DD131C8D4146F1FBB282250941D8A1CDAE68B4C5961A7A437B3251F144586AEC15F505AA79305797A16CDF4C89209B02BDAAA0C0D367E2DC7097A9900BAC5CF7063C3B2027AB05B204FBC997F333122798670E3488CF4BC64089A15A97F0C0A4AB5680FB9D5A9A815234E158316F31948B80CA33523E2303838D55EA2368B037A607B643EE8B2488EE456273158A3675B56967CE7B4A1BD2C22A91083E474AB9121CFA0F2BD1A24B27AA317C34B968DF055DEB839EF172FFD0489BC524109AA9897383F9CF0226810B56BC75B699187BBE86D465C7A44B65AA828C40CE76DE88CBD6671093CA1689506657CDB6B3CC5A9A0293D16057E700A3BB7623E3CE1C8815B1D17066853B1CD807C0803F9A9FC2B62F637C99535A1733159FF79A863BA9203D57C80F0BBE02052E41004CD42388FDC695D9722BB0147C55510CFB9347127002FA9038F42551FE1656F1C4BA91C47E5FBCC5E83013864209290CF7D901213A26E1FA79AA7576C7C4103CFA01EC6E1459C9AACC449AF7D10ACA0A4171B284D4473C9AF9A84546B03C7D5CEA7BC723DC5032157B58431BA9A895D35F89274E827470BABBA0342567648BA84A51AA5A604B4C36A27C0B2710B2388B53085603CF62D9EA0A6A6864971323ED9E934D7471E65A4915ADA5DD1E7482A37517CFA6255782EBC7B789C4A6D2AA746A811C0BE90079F138DFCC812ADAC7C4BD862DDB83CF0D6B74B623B523318BC807163E6C98D777C7ED0628266BD53A29636B601E162466CFB700ED35B0966A7DAF32E7DD67AA1C08E7CCA8F18FCB7BD3104BB5408637C08EACA654B19523AC0A031B76968D71D9C013501A1350742467970C2813762C1B4219DC904202984CB49B33E91328B0350AD36B4A7650F7505B11B5C6F0520CCCF788B87B5AEF42B44B567C42555C74F40CE66CC9003730928E859C77099D8149C78588FDF0C347EEB6752B39B755122E715843ED2A859C02A81E7705127A52D53047F973952321D34D4278739C4BAB50A5C344011CB196DBA2BC5197ACCD11B3F6E5D57B37115E763177A6910C9866C85ED61C69A350302631BD506BE010A3F42112AE4EA731D515D80C3A21FCCE60CC4D945ABF4626AFBAE65EA913CDB263C9615A5F66061CCC74B1AC83B5FBAB8FA1EB6799B", + "ek" : "50FD9A9CFB26AB3540603D01896B2FD89F810E7CF843150B2B3A9014E14AA269C3275FE7C6F31D7EC6A33648969ACA70E3AE2EF83D50030C608FC2ABEDCCBBF0866D1B8268F18EEB847055862727A74053EFA013D8A8A47781F983BE84F4E7C796DF95E4B4F1DD8E2702F0CC02B89407D19511657A78CB744C5E147A88A862531CAA15AFADBF64B203C345FEF0FE74681EE54AA6402414DB802B9581F65EEFECA65F5A2101CAF1B83AC2E128D6DD5711434D8C6CB693F12575B9E355E857613DD3D9556B5F5F557202649C209C86BB1C3694F55F4B66D25E4AE28ED228C52794FBE9AC52AA8BE8C562C762C594E7D0C646986040CB1C18925072DA0A1C8C614A573B27D1BFB22F7A809E129F9D06E1DDB53E8744D433D8E3576374ECCF0064837B275997961EB6C4B6EF28A70C4EA1E4B6BC6E381BF54C9C9F1F0832E9EA0CF047DB0AB82B707DE6FA3AD77C4D6A7433777F42E4654C33A8D9006A90096B864D872099EC93174C5B27B00A970508C49C80E6B78EECB58178CC475D3577AE029B8D42A71D70D66D704010036B52922E28C0F9BCB6E99F8307A1E20BB701EAE987C7654E49FBDC6CDDDE97A26E0A439024FE1A8F260F68F93D5BF850BA07A32C5D7BE2E2AF007BB6DC92BA168E8CE458FBBBF298E5412C28A4E567337EEDF376FD99C4A074BA8A23055B23427FE19857D4941394082770A6ADE95EDC7564FC42170576ECE2357E595523EEB69FA73C72A69151A9E2E1A1AE360CBD428D3D753707B948459A5A85447A7080059DC4EA53FFC9E6FDAAA130AF9B2B27C4FFE2BCFFA74451FDBECD9846C1A2490E38488C13876D071538B58DD15F466E68D290287592981589E98F31305BFBE5435B3484F8167899838C1088225D7E0E4173A5FA6E0F440DD4735742B09711BE0426CB603B30EA93FE9C4ABF44617C09BBAD4B7E2FEF71FF60B3286E2E1D663E5CB67862BECC92ED2B343FCDACF9EE9E241A2E57CF0B03B39FBC324125F768620CC537E6CA506A9CA96683245C76E7C58A9ADFCBC10BD7163779F0521C1087949954F77C8B10BAE4A3F3E140D6C97362B86394C00FB79D3711F4DC7A6EC0F5FE50D039310DBB16279CB79F083E0EEBCA30D32F806BDD459EE3D21BD3FF77483051DDC2D9EB6BB905DCFE130CCC80D0F1004394A5ECE01691EDF81BF6C497ACEC8E7B01C3013E24CB8839CF3D247B3675109A3D22383B5393FBECCC8256F2AE9CAD334BE38A8A00632088E9E7DA18CBE15FFD43F865BBDAF710B0AE46BA441CBA23D824E0876DD01130C71343329477B29C51486E59FE6FCC51C629B4A61C656D226CA392D01A7D6AD9E3E0F48EB4AF93F9E7878289F854EAC0CEAE5C976D0A576CFEF076B95B32F56D6205126C6FD287C6B3D6A442001130A79256FECE1DF8FB1A1E32E0F2D14BBB7204B219C0A57E91403691662453E5CD163D3850E22DCC80055A1A06309FCCA838A4670F41BE7B97A466457FAF68D8DD50FFABD0C7D2BBE74C358C240779B2E788C0D7477A59FDCE6A0798033E1C", + "k" : "6495955FE4CA97A491C097CAC7D837B6180808D608E4155CEBDA47D8F5D1C3E2", +}, +{ + "rngSeed" : "AC139B78FD16CA0F26D6D7F9E15345C888D857B1910CF38D883339B37EAD2DCAC30F7CF10176F23FF34B4488EB79437C", + "pk" : "33E4A6BF137A2D5C4408040972BBB41342A6F2F97C6BF7B5A05A92EF1C69A3E602F5062B4D651B9AF148EBE566059454AE71919226742AC151FEC6623BD5531699282CD0651A1BB436D113202AAE301A6DE6C132DD020CF0235944D0A041F6AD92E404F87432BF3A28035C4F6E236CA6E6B56D924800667F8816839549535F1325CEEB5B0E194B89A5800819215737A40988A43336CEAA914800278944BA54EDC65071B63374FB041F07A66D5781EE8492D35221C53495248365CC438B4A65A745A64585242878997853597CE1F45371CB1F97F8638837BEE3CAB372C024EBE4AA52455283CC2249D82739EA481D685204A61840C856617A210FA431A31B27532B5B0868C2DD0A1E2947AEF0575934905EC50C33193C8CBF15C5BB4A89B39C63337B3F4BB3B61B0581FE2362037BCAB4C62EE14AC3D8A70486789A6D9641B4A112F1336D7E613B13502DE7D1BDD103B6A712BD4C9AB0F5611BA825AA5B344CCAF940C5ABC296088893626120B4AA3C73C3E27520B6C6411AA745CD4399BDB627EC584AE3E2A9081C4125CC37F20107F70161975355AE779D74062D4EA062A36A4B63A20E22F3AF346A57B37747D3D68A486133857577DC3040342AB2C8A38C9702C66276B5439C82465304F22CA9A316B6C078BBD00A748D9689283AAA0FA584FCB922DE15C170412AB5819A18019CC9221533A691503A79C71C43DE9453922264CE5994C78A3CE43A1595CB0C761291200B9BDD8B6DD037326E5B40D43717E6507B5F7BBBF71800CC7A1143E7101995CA2C2A06D3A501229A913E3B350CD567E59A03AC54C35A8CB0E4FAAD7402CF6353A048461649D4171406503D0380F543AAE846A21DF31C561451FB8707B6F15AE138A8D11B53B4820E97D1293938680546000C7552DEA31D4AD50E914CB85935CBCF18821D22B20D309023018A667424AC7AA71532AEF2C69C0DC545E3E501E5706BC1C19B5179BD4C4AB22DCCC9269560992637A7887B996A6754721A2FFA97BE2B5FC2A512788334871577F7530BC06430E539AA7EE0ACAB022607554E2A3160C2026B8F169CD3537F523B4CB3096DCAEB4413F93E8DD26C774C98DAA269CFB702D3592984A3304AA56809B61F5FA4557A08C8AB20A634BCA903F456C6E835CBF23F647A47971C3726CA216014459A96531896C8BFE74FD0EB074D74A085BB32BD57857054629A3B19D0105F5AEB5E79D10B0CE0CA1189756BD74324ACCCEBF80E849969BC008ADB76AB38FBB47C59CBBAA33F22759D5F879F178A6EC6E37309A15D70C286D7549FEA354B438B48D4E73D6B0584469433CB86A74BE82CCEE60E4A0AB3296A31FDB9A66116A765E2828F3CAA12DA7E0A4A0A54D1AD9D141B98413C45D277A4E0A11732B9E6A816E3F1CFDCB62D11EB09406B83C5746032E128CC2897E3243840652253B7865A079309B7CE6A1A5B2007B775A463199C4A90358B416435D69BC7C6EC48A155BE7570B7FE2626515A09037A6D9DC449E344B0D570BE3CB7B70A720156858D8656C296B54C7377456D22AE66402C6FA7A4D2921666171352F56CC03A76365723682C5EF77437A5D16BF343972C43B10F56C5770CB8E9C2A955E89C35D932DC466B0C198874BB242E511F4F4D35FDB1EEB7C0006FAFE38C636DAB4728B6725DBF53E59CB8", + "sk" : "88F007F412264252BD88A985188292640647B1B3CC05C76AF4A6CF3675B42F4482D95993DBD327C8D4B863A8A52446C45E2019E983C05C5C95AFC4A0AE860FF06189406C1555BB292A521BA8EA0EF46125E590AB804B42284B1B2BD3338E18A6D6077556FB4B4C39CED51A15568B9D0234112556385329375D55847D6CA3B3C3444A48282C166A218A1C21181B641936EE5527A9848567D5B2A0185E10ECBEAA87503A338E98C0ABE960B6C0F129A8B5A532A3598D6A99D55B06CD37BDF8D7ADFAFAC7291C00E07A2816C7CEB5D04461D503E7F382F0E2BCD3389D7DAC197EE47EC1CB2261059300A70A34C4007B3579A26884FD771CBE0929DEC5B2C7BA08047C99FAC165905A7664F27536CA1A8995A976439CD67A7E4FEC693EC8BEB3EC2E1353C43538159F545BBED6612655762AE90F7785CB8C2051A4BA328CE09977D85434496C9EAB763F796F77A94DB4343888EB753F434A1906071EA765A07C7F21257D834681BE97347FF20C45A207FF7968DC200B48909B62CA4E2CAA8E90D1518E7373966B76B69B65B099814E091C2867374E4009B1A76355B2B04BECA33F9949C3D700D1583F12A07EC7349C57AB810CD3471A818F8BD8C7E8656AD148561C82BFEFB827C2423E92E792F6F79A8FEACA75F663B765106B9376BF66B099135C1A553E5B3C0326B6774B384ABEE645B5CACE1BDA4EFD521967678ADF291B6E6602DF992B13A0444E817576F9487DE014CD563AFC086DFE864C0F565A2304338E87232847C2C0885E008536E4CBBAD69B78E73794999A5A3AA1096AC7789EFB049F273F4E04A92B85304FDA1BBFBCBBDC303607D85B4504B544597BEA524B79C3C438DC25CA6612D434857971CF95D343AD31C7A8AA5875641D2773535A80CF0B331840A55290CCA82B74BE2F4915AF544D397552D2678A9C771FC89B0F00D6A36BB6276C10C1DE195A271B7CB34B971DB38F27F071B7BB4C44358766EC23D9636E933B23907A08EF691E453958B325C6A9136E57D2555485AE036BA34A9CA1333BB07015821187538A58C2AF375DD5A106C9E01D357B280F07CD7A08A6A9F6B7ADC63CA50589CBF21A16E0B35072BA13D9792BC5555B87598946471ECCB42E27C9E2A8641C5524CBD17642F41B38FC888914C5D3462DA370738FB1A6BF61330F17147B87A8FD294996B3B6BB0997B3E9A076262E7206A879177CEC22B51CF1B85535CB3D056E3B6190F528349B245E1FB524DD149D218C5B41B34CBD579C2E2B2EB328CC66233A806177A316956E37A69513CA6183621407075B61B655EB5E5E60AD1582359D954D859550C115C07F71304368546C926531A78479544A6FCC492EF728FE0183DFA6AEA27B75BD9B1717262022D75D383C813A2247B065939D20968981AE67D343179118DD1682215631DD7179BA480E54D4A49DF6687B1537AD841E668B36AEE700301151EDA7706ADC6572465289588555D263BB484BEB51A428DBACB9487A35830597457411C899C20995599C0D3E0759650040127B92C85A58B4D87682B310D165AF1B7118E7332DE8F90CEB223195CC1A421A1685273078FB7CAA4438F7AA4B45087806776188DCCCC327170949C45CFAAE192C8FBFA0A033E4A6BF137A2D5C4408040972BBB41342A6F2F97C6BF7B5A05A92EF1C69A3E602F5062B4D651B9AF148EBE566059454AE71919226742AC151FEC6623BD5531699282CD0651A1BB436D113202AAE301A6DE6C132DD020CF0235944D0A041F6AD92E404F87432BF3A28035C4F6E236CA6E6B56D924800667F8816839549535F1325CEEB5B0E194B89A5800819215737A40988A43336CEAA914800278944BA54EDC65071B63374FB041F07A66D5781EE8492D35221C53495248365CC438B4A65A745A64585242878997853597CE1F45371CB1F97F8638837BEE3CAB372C024EBE4AA52455283CC2249D82739EA481D685204A61840C856617A210FA431A31B27532B5B0868C2DD0A1E2947AEF0575934905EC50C33193C8CBF15C5BB4A89B39C63337B3F4BB3B61B0581FE2362037BCAB4C62EE14AC3D8A70486789A6D9641B4A112F1336D7E613B13502DE7D1BDD103B6A712BD4C9AB0F5611BA825AA5B344CCAF940C5ABC296088893626120B4AA3C73C3E27520B6C6411AA745CD4399BDB627EC584AE3E2A9081C4125CC37F20107F70161975355AE779D74062D4EA062A36A4B63A20E22F3AF346A57B37747D3D68A486133857577DC3040342AB2C8A38C9702C66276B5439C82465304F22CA9A316B6C078BBD00A748D9689283AAA0FA584FCB922DE15C170412AB5819A18019CC9221533A691503A79C71C43DE9453922264CE5994C78A3CE43A1595CB0C761291200B9BDD8B6DD037326E5B40D43717E6507B5F7BBBF71800CC7A1143E7101995CA2C2A06D3A501229A913E3B350CD567E59A03AC54C35A8CB0E4FAAD7402CF6353A048461649D4171406503D0380F543AAE846A21DF31C561451FB8707B6F15AE138A8D11B53B4820E97D1293938680546000C7552DEA31D4AD50E914CB85935CBCF18821D22B20D309023018A667424AC7AA71532AEF2C69C0DC545E3E501E5706BC1C19B5179BD4C4AB22DCCC9269560992637A7887B996A6754721A2FFA97BE2B5FC2A512788334871577F7530BC06430E539AA7EE0ACAB022607554E2A3160C2026B8F169CD3537F523B4CB3096DCAEB4413F93E8DD26C774C98DAA269CFB702D3592984A3304AA56809B61F5FA4557A08C8AB20A634BCA903F456C6E835CBF23F647A47971C3726CA216014459A96531896C8BFE74FD0EB074D74A085BB32BD57857054629A3B19D0105F5AEB5E79D10B0CE0CA1189756BD74324ACCCEBF80E849969BC008ADB76AB38FBB47C59CBBAA33F22759D5F879F178A6EC6E37309A15D70C286D7549FEA354B438B48D4E73D6B0584469433CB86A74BE82CCEE60E4A0AB3296A31FDB9A66116A765E2828F3CAA12DA7E0A4A0A54D1AD9D141B98413C45D277A4E0A11732B9E6A816E3F1CFDCB62D11EB09406B83C5746032E128CC2897E3243840652253B7865A079309B7CE6A1A5B2007B775A463199C4A90358B416435D69BC7C6EC48A155BE7570B7FE2626515A09037A6D9DC449E344B0D570BE3CB7B70A720156858D8656C296B54C7377456D22AE66402C6FA7A4D2921666171352F56CC03A76365723682C5EF77437A5D16BF343972C43B10F56C5770CB8E9C2A955E89C35D932DC466B0C198874BB242E511F4F4D35FDB1EEB7C0006FAFE38C636DAB4728B6725DBF53E59CB8866573E536B4017C02E31C8ED7455C841A5CCDB795FC200ACAF1DA2FB936BB59D79909F31E8168AC129FEED8EFEB21F07C02F282CB90F63EF10EB2F4A9ACB886", + "ek" : "A0A1B602C3B0BC55CEB01081B75C26AA1ED3654B08A18B7C906E7359D1C535145AD09DE4E1A63D227DDDAA5D982E5CD3DBADE2FBFEC6692E95FDCCB66E85A604EE4FDA280E38B260F3989980E3911826C5F54CCB36033F5451276BDBAAAD936F91F4D3C9C158BF589C41C97B423A5EF2960280A94C16CD27DBA4D04545D7420485F3D77569725B1C0F4A079FBA48FBCCF4C2A3A3A1877D5DBBA01B1754855A62A86E70DEC8AA00815074428ED537CA07AB68A1B386B2B439A01C1E7A4F1DECFD0AF91CD8CBA4A84E7BD87C9BE35931DFEA81FDF1AFAF3EDD665A950B1DBA40CE0801E1B999FD30A562CA2C30353559AB10432FA29DA1A6483220DDA6DE493C7AA8091FD0A8812C4CEEF55FD08DA70668DDDD2AE771EBEB0C89DAD0612A0F1F1C9D91FD424DB1914F21E64B1E355E8C7C771049490034A01ECEEF8C5553687F291BABC911D1067A9179424D5C88BF33398556395D2DD1CCECDF521E1DFF325FB91DC23D1E30B26CE108C953A61266C4FF0A70C174B7485A25F9E4F621CBC75366FC6A919E63907B037B9281C359DF9B91ED1B905ECBD118E0129BBDED8326CC7DD41727C3E490989DC67E6BA1C0518DC1910C23EBE75127A726C47EA868A94944B50D89A01313890413E815BA129D1CDF8FFAE184D81E6BC2D48B101E5DCCADE7FD37305CC6B9EB56F4804C2CB0911EF0D1255296C2E147ECF7503C3F69B57C5F8D63AB4473D71D64E2878A69BF10955C0040A72EEEAA222664E9ABE37603406A458BF7BFC43F17C662E07F3900C1338AF367D4DFFE6F18B3E07BFCA2D1F75483F399282F34A5092E05354D9E6A7EA02F63858CCD3B14B926325DB7399799881113F0137B99C0EB4FEB9F6A2401C376214DB1F3274AEA37665EA2FBA25D6C6320265ACACA5C9CB0EE6721245A8B2351FE11F5009353D17D763F36992EA0B2B1BA1A5B6D872EF40E47C32B866EF1597AF5F96AB20170CE12BFAD32BE1E77DDFDF4366CFF5BE9C06D927FF04906893AEAD4BD6B9C873132A4E49556565EBAE1623EC9D4AE130F8BC0FCBEC42026A9B850E53995986ED745D3BA7A406CD768BBBFB91FFB0EE0B72E7FE28317A2E2A20A6FE55B3662375728BA193FC80550AA9F27C8D74FCC2F50C56BD67DF412811C1D040657D4425D74CA080E45A83F7D1324328E0C99A6E7AE1BE2F6356D4CE8519337879B053B68F05053A400F9AE728C9BD13AAF72972D73B3383B11667BFEF5B898005A6AF62B9808CCC2BA76DFBBA5DA6A6BE48F38F8162F577C4B7EA8E0134C79D1D7486AFC899DC5BB4F4CBDB469AB2FE93737D56FE7731AAD4740CCE672E50A4AD9C415B1CB21E71AC3DAA5322D673D185919116E2CBB7D2E1462FD3CD75240418D9BBF779CCCED5933DD2D61F7492BA1314318AA002D50EF6B5C942F0A3E1E9FB7A8979626FBA441E1CA70E77568B1E8C005B5E114543D0DDE0720ADABBA71294F001F00C88990D0E94106CD325B6FEA8DA3669EEB8D8B9075F2981FBBBD9B9D2FB16535A41478AFDF9EE86D9B2C43C9", + "k" : "D85F4B5FBB0D00C728E84A451E23DEC2C91CE22BF6327B109F8AC79D928C09BE", +}, +{ + "rngSeed" : "CC7152849C98D5FED2813275D32069E44824ECB14EAEF425CE017448CD9A401C91C06D0F7EED6D22B7BBE8BA6C429EC3", + "pk" : "C797AA612A100811C3131B8B99B3785A4A32C4AB212B5C0217B18A55190890073F2C12521BEB9410040129D5947EF96B72C92AE0F58AE1AC236A5426E7A4440AA42C4BD501AF4823CB621C3E6374E368ABA59C45932AA0ADDB3473E96854E8A706C510E17BA91B8B865DE529CBD093BDA7B6FF8B182EF71651035EA6D8B7C00A6F6EFB8DFC0B192C44260A9479539C5A4C38CCCC6B1B7FF3697E3759F8E1253CF71E2D7C9119B77090A99B3BE67AD965919BDAC787F116A67B1AE1C7230B957CAFE398027596D510B2CE87A73CF8547977631D872ED714193BA7BE01BC7E16260B5BB00A4227B976EB5F0DEA457D3A493D19494E5219FC67006CAA818EB43AB0D80693EB616B8BB9C87C5E899321D6719801A9982049C6A98C2A63800405867251E20C117241E222A1281745E3929CBEBC2444B9B0FC0148B81B96F83B9517A2AB24171C5C55898948B7F16C6A1A09CB7DCA509A3876AEAAA4AB299781582CEBE73E9BA63390B35847480A9A305CA7B4043CA32FA6875B88085115681BFB806268A7BA33BC0DD5311266E672147B089943C2310136EC47AD1652C681A94FF9D09F87E851F1941AB4755538D50D99169AE1BB2BB70AADC0C87BA3D2CB70F1043BE7272663740AB74C05899CD7881BE63A86ABC13EC4E014CD1868C5799992A58A60AA2BBDC6B5DFFB8915C3AEBE3C9FC8F70DDC8B9B8BD69FE4F1B60202919022AF3DF26369C190F5F518A6479DECD8626E1C16A1094E2DC7C57A1A189B8B2ED0D4B9B0D90662F134CF4325A1867505A43E411C3FB4C4477C74B658D302FEA66022505A25CC2A06713FBE1C2407F187E427A0DACC9C0D20A8FF3C4538A71A639A9029F1C826E8612BA30B2DE1C63BBB0F70058F13973CBEE40F371C490581C5A61BA074175B6488BC9829AD658568304256BFB88DB3B10A4FA1744E220BA121772D94B35233CFF9F8CA6053A364CA312FE1ACDE98BCAA937121806B40C972B1AC1E15700AE67441E399BB0641977D058020F205B258A29BD53FC277609C31150A0134849B6B7D4564D27735507AC25BB2164D4664C0B37CD5B9000D33201831C732AAB32EF114902104BDB90B638B42960AC870C14E6220806292B9D6D3BCEF1A9B6E859516651F9019CBBA1C636EE550A72146AB17231F22A8E1EB68209642CAF3814A0121565504859810F4A81CD8C5BF10716136E77FEFD995A8956D6FFC0A38F841A0905B19589619649ECB2B24AB314A9A85BFA85CC236D19600C7440771A727E6745829CEC312346B92C1685507BE82A7D3638D36D4A7641A9A042617C09681E0DA904A21207CD7B57F183640797142EBB3AAD3470B82511BB88C8CD2AF6DE0A4F789161F7B2C00E2000C95BCB0D270D00C89C5F102B86650E2F8A4C46C052A817CBCD978DBF2C776CC98D53C1F7DB97A0F42594EF18B2444A21BB2C1A59A61DDDA53D0105489967488046FF8679187800587F2AC8946688CF49E81DA406A2684D1A6495D33A8F12B72686482B91C2272215975A484E8488D2B19AE220CC1387594DA69195DC47AC1127738BC03EE72772481892734246681B818B16F06943021363AE890AD5E213303D86F890478A91C6D0AE28E95B4CE2A861CBFD681A47A25545C2A29B75946D0F45BA0AA193CA5544686D9F9A802FC4CECDEFEA4A0", + "sk" : "53A58B52229950C6B8AAB3BAD4F53ABD319322C80414D817966365DE802C0F8888B1EB3411256BEA64BCDE19B9CF5142E5698316E8CAD22846D3EA9A4008512EE83CF1C8517789366E358143832624213A30079F2E8B07641A6816C1052111AE088792C7C305E9C442A47697B312945D5CCB417CCAF9B1649BB74485F4C73CEAACB7A69E06647E531B5944D64586A089CC8892EE0094C230998A22C9A1B0230557C4BC3C454FE33E96B9C5FC74B2E051178BC1A0895A782F84B75457B81A905E50AB4CABC57B2FB99C5C9978A9A4B2915459FE8B474B66C73EC2A4F3048BC5387DDAA066C2DCA233AB00019BC2B3A89BA4710CAE9A8FE1937BE7E26B63B039F7E324EC870F2FF3C886AC649048659896294E55C7FAE52F50753117E02F93751708037410E3558C87382EBC052D1783314B5956804DDCE8C378EC3A4681156FE044237004F2F58C59EC8B977C9DEC63678D494A22B76E1D7B22092B16A39C696C7A04DEF98C258B774A4323ECD6905E3C0267304D94A59028E084D7F1AA0C926965F087F0D89275B88ED075C51EE424C4125CD153782E0BCAB7F57E0C038BFB29798DF5579C95BDC021BF6A005A599C3AC8317A26D94B6810CB1007B9E3AC9447399DB970B5B77544636481434C2ACD4A92A7575C227079813447939938125670E9027BE04462EF7C00345A26EFD3803A26710BA975798102F8452659D2B9BEDB387FB92AA038A996C51C92681DFCFC2D5754BBE04B1681C01D53D2957B6327417C4A8F22B80468808D099055E781B5C4A594FA2C57B91A70DBA9909824B46944CF553D15A8C0FFF742F10127183C00E3C6814CDBB87B88915FDC92A273C364B18B9C16AFA3F5CA251A417816A13214A3ADCAC650674C309923D74972A50114D951640610A9B4278BEE19C2D520A23791A136BB0AFC3565750295C93513B819BEA7B0144472B63E2B76E1909816B88BBA368A6E41331881923EE92ADC1827D2C292195AC1AD64064272A562BC0C9A325731CC2992D373403B1867746C78A89773035D1F7BC833A0C9EFD1142564CB53B494B226154E7CBF86E0CB85230C2D2B2499486050509BBF8340A935A53910BAB694B229103158776B4A85113E3B8BF8438FB7950D2DB1153627ABBDA1392560611C72871455125A4984DD743A2222A6CEAA88B3FAB2CAF9C7BF17ADB2E9BE841163BD3880C6C1A6860A8EAFDA0DC8AB3BDA2051F6A1BB313332777AC5EEC69E0F70AE83958D397A488727B57553A7C4B209E6C6A0D062AE0C988AB89786F764622879BE2C227B7A717A3C7962ACDA48DF3C84043A21D2D85564159FA7E7BFADBCC6DFCCC335AA3425FA958DE87A6FB0B55531B66DEAACA5CA251C359535AACC818ABF8FCB75A9423E2BB903D2811618F5A696F230CE50BA48EB786B34AE60E8B5D6D477C3D363E838030F586796272728C37EB82773AB186968A0C2D5E03717CA5918DC420BE60F77D6AA7484C730BCACBB970DE161C525973171E638B73A2B824508F038AC5C5C0B43098863485EBCB91C08B60A0C731842A569C92A077C06949D7865E3F7C8B6E96D9EFBCC48C428BCB8BA049669494663D2BC5FE761B42089581AD73437C875B9D89F96675BF09809C797AA612A100811C3131B8B99B3785A4A32C4AB212B5C0217B18A55190890073F2C12521BEB9410040129D5947EF96B72C92AE0F58AE1AC236A5426E7A4440AA42C4BD501AF4823CB621C3E6374E368ABA59C45932AA0ADDB3473E96854E8A706C510E17BA91B8B865DE529CBD093BDA7B6FF8B182EF71651035EA6D8B7C00A6F6EFB8DFC0B192C44260A9479539C5A4C38CCCC6B1B7FF3697E3759F8E1253CF71E2D7C9119B77090A99B3BE67AD965919BDAC787F116A67B1AE1C7230B957CAFE398027596D510B2CE87A73CF8547977631D872ED714193BA7BE01BC7E16260B5BB00A4227B976EB5F0DEA457D3A493D19494E5219FC67006CAA818EB43AB0D80693EB616B8BB9C87C5E899321D6719801A9982049C6A98C2A63800405867251E20C117241E222A1281745E3929CBEBC2444B9B0FC0148B81B96F83B9517A2AB24171C5C55898948B7F16C6A1A09CB7DCA509A3876AEAAA4AB299781582CEBE73E9BA63390B35847480A9A305CA7B4043CA32FA6875B88085115681BFB806268A7BA33BC0DD5311266E672147B089943C2310136EC47AD1652C681A94FF9D09F87E851F1941AB4755538D50D99169AE1BB2BB70AADC0C87BA3D2CB70F1043BE7272663740AB74C05899CD7881BE63A86ABC13EC4E014CD1868C5799992A58A60AA2BBDC6B5DFFB8915C3AEBE3C9FC8F70DDC8B9B8BD69FE4F1B60202919022AF3DF26369C190F5F518A6479DECD8626E1C16A1094E2DC7C57A1A189B8B2ED0D4B9B0D90662F134CF4325A1867505A43E411C3FB4C4477C74B658D302FEA66022505A25CC2A06713FBE1C2407F187E427A0DACC9C0D20A8FF3C4538A71A639A9029F1C826E8612BA30B2DE1C63BBB0F70058F13973CBEE40F371C490581C5A61BA074175B6488BC9829AD658568304256BFB88DB3B10A4FA1744E220BA121772D94B35233CFF9F8CA6053A364CA312FE1ACDE98BCAA937121806B40C972B1AC1E15700AE67441E399BB0641977D058020F205B258A29BD53FC277609C31150A0134849B6B7D4564D27735507AC25BB2164D4664C0B37CD5B9000D33201831C732AAB32EF114902104BDB90B638B42960AC870C14E6220806292B9D6D3BCEF1A9B6E859516651F9019CBBA1C636EE550A72146AB17231F22A8E1EB68209642CAF3814A0121565504859810F4A81CD8C5BF10716136E77FEFD995A8956D6FFC0A38F841A0905B19589619649ECB2B24AB314A9A85BFA85CC236D19600C7440771A727E6745829CEC312346B92C1685507BE82A7D3638D36D4A7641A9A042617C09681E0DA904A21207CD7B57F183640797142EBB3AAD3470B82511BB88C8CD2AF6DE0A4F789161F7B2C00E2000C95BCB0D270D00C89C5F102B86650E2F8A4C46C052A817CBCD978DBF2C776CC98D53C1F7DB97A0F42594EF18B2444A21BB2C1A59A61DDDA53D0105489967488046FF8679187800587F2AC8946688CF49E81DA406A2684D1A6495D33A8F12B72686482B91C2272215975A484E8488D2B19AE220CC1387594DA69195DC47AC1127738BC03EE72772481892734246681B818B16F06943021363AE890AD5E213303D86F890478A91C6D0AE28E95B4CE2A861CBFD681A47A25545C2A29B75946D0F45BA0AA193CA5544686D9F9A802FC4CECDEFEA4A0B33387825115CBA8B0AE7DA0D1AADA1CE4AB05BC2479B360B6C56DFA870CA825648E3FAE1AEA06E15778F3442223574E9C7823F36CD16C72618846331F95E91C", + "ek" : "766462BAE737BABE25A1C5B6B75741E32A7A068C93C8BEDF940EAF061A9C149AA7CB121E1B94CBD4AA1AE7D782BD3ECBDB6D6A3CD3C56837A3052986E4E18BFE4A394C3A21AAD514ECF905DDFBC7D61C3E7379EE03433CEABA916F5F7B4B851AA25F1F9CCFC5EA19560D985744B829E9F5655BA4DB25B0F01FC534F47993BBBF70B357F3973EF212E22F94F138184A62A4D8A97A74F56876718ABFFA832A1CEF259D580C3BA8A2D3599106827533759167DFBC0AC9671C169C278E5F650AA4D17884D5479F301E819755529121931DA30F60C27139DB853FEF7A6D4A2019967E52DF398680D4E2A029634D38D7884BBA8B974F8BFFE018FA857A490943BEC494C028D82D8C0A1A4E0928A1EAE1222C419D50EC62009F198AC7DD7E77B97D8D5AD77622200F273F6E14441546A5655E3CF837460F40B07CC06083B0DB9ECB5B46309A41E80CF869B2C1758F423D66D8F84F30E42F512852AC5187CA7AB3D1DFE5E26253E41AB26BE4D797748246B50AFF6496A3DC5C945FA0B8356CD5993CFC412E6C44605F8D908A98357F84172F7F73DD94845FEAFC83E816B7E613E65E7E355D39D94D204DDA777020993C7758AAC125C6941EBC127D7A2E477B104BBED1D153241CCDBA995511E8F1DACA05879619073B9E9CC31FD2DAA8D1C1F8FFE07D76C809CE7E446A078B7E8BD590E11476F14F45196D03E4415E0F317C4D13DBC184AA483B8B1062A91C27A338EC1F526499D6F11B60D1236F45FFFD014319A4D587313F6B50970A66DED9D96748F3F2C7BE6E1993A632E111E0931AE326A56B5C416505F36BE4AE7475DF27BBD6D93949547FF66B47978E7E0F106DE85406D1B1056384B71B9168C0E79E9E56AB27E378F35878EC61EA052AFB548FB8E31A24B70B52B61FD5EC0D83C4E9EC9C8E69E784E1D89B70AC21000CCF4BE4EF5820902719878C06A85F1CA0C0A727F7C6CBC26A41CDB508F639E7ADC8E0476115A2DE2FFBCEB330D2E4BD239E2FC33348295BD1CD5E8F2370E59C235BA5A162DA5A84A092D318D0F3E1BF2D3973FF6E597E481DA1B84D3A98C4D94B7A9A1DF7F67C6F5ADCA1E02ECEDEE1E0BFB40163A1765EF319435CA7FC131964AAE0899EAF72061C14FB5682FEC5FB70977E49783DBE356264DF0C80D8313FD7B24335D3B874C03F3AC3E0B943A7CABD8DFCE594830A94F90FF84BA48F720863DBD61E809339E0307E232D9F2A35E4A78200743EC40D8F53D9E7DF395703F3F4202C6884CD3160498514AD576ABACB1A576B87826F979C5B0AEBB0EBC6842594503C51D45C693FA3908F3B0965CFB27FEC8B4E67D68016E69B4BE7DC1B77819F53C09DC4428E2B8A62C679BE5EBE19E077D0E0330A6D8837AC7C9E07162E60FFA3BA0989A496B8F5E8FD974DC41F218D9AF9E197BC3ABA59D42F437F33AA2D7B589E5D1B62DB5E1B5BDF764F74AB20B5B578ED8D725FC3A2189558579F9A0DA72B8E2BAD03B2B359B772E9480041813E6DCD1B00820AB57FD32B2C36053AA843E458326749E3ED0CF6", + "k" : "DEE7C74E825DFAAE8F3B5C3AAF2D1BE7CD0BAF1BC362E43DED7533F5A75B5B22", +}, +{ + "rngSeed" : "96D9A06F88FF2C2036FA8E914B89C765E4A510B468DEE40F914F78858C811857EFE9FD0E17C0048E7389E8D996B7E2B0", + "pk" : "D800414FE5B14DFCA90FA6BB7E350684C3B08656374D54776C312A645987B9C80B28933550922990E2CC4064114EE12F93D3000164C333BC77D566CD91C904965367B2350B87A6B0B5AA7F8A746FFD4576D22083F23C0F3EFC4D09CCB86DC4CAA55365A8A406ADD3CBA2127ECE221C9139C6C273BD4D3B1BC1EC0626B35DB44230662CC44AF683C92176C5171337746F0F4900B7369DF2B705B6387670B411E26288B8680F9CBB0A8EE01C9D0A9E4C61A19F1CBA55459B78602DC14BA52A0B9DE9DA0CBF330D3E71625228A6A9E471D70639B05792CB8550B24AC159C5B069C30740D09065C9280BF2B4F86C1CD9B78357383B2BCC4E771661F4CB75C6589DB317058E428398EA7BB88450F22525813058C609BF5B02A3098A619101C092F87AAD3881EEF6A2EA91A49DD3CDF1CA6952205E74F68AD5C06FC04163A70C0972C4AD752ACFCFD5529B75328548C18748026BD7965F73076D4BB8F84159756C879A5919FA7286E0DC39F1884587BA5E124177EACB2A3E96410A64C2D5403CCB939E428B1E7149CA2B3368C11C8E1F38082AB06F39455D55D12E95C585F0098FE6DC44BBC97C1547600D79B193FA838E42CEF6BAB08D462FAF017EE8414C9914316297CD56889207E13E71E544C6793B751174C5BB22294800785BB003589A899A562C6252EA679779522C03A0B933B07F29194C75B29693E27DDC6C4757CAC5B9219D98137516C450884C374CFA8572F3B9E27CC706B205C398866DF7972B8A44B7F975CFFC3401212BDA14C0BB9A50A5E5954F9534EE90C0F1F2328C618BE5C2166BE064D5D0A04392183FC5B3BDE635992998B68B8C7BD7A0A1C3BC99975AAB55AA39CC0E1D4C019EF73A53485349B58F4271AA29A4C8F8E97935981A83426B3BD0B5EDD1CC10458579450ED4D065A93AA0FA734F3206718974CA6EF35191C930EF67819F535EA5E80E54659B1AEC30534442E03CB9C4673679CC1CB205264EA53D20E383D98C08BFF78447C3335A4C3BD6F0794BA019E1EB130FAAC0D2F4193A6476CF014DDC988E757B66AC5C95BB7767E6C32EA8027B5E5A00E62C582EBC4AE6738B9637355F62A053737014C475FA24B144B2B47EEC97DAB92F58BBACCB0C36670CCC9326287FEA9FE7DC6A2ECC896652C9606943CA1A6E8688A821B69E33412025E26442AA2F70A68011F8BE62DB6E6283B9B85651FB8883ACAA20885807237A51CEC50CDD007B27C121FECA8A2C026D82359DE6D8B548D9A49A9914CE76584338BFC8F2CB51466414548CEF544B82ABCD277A6602887E4EDC5E09A20B1FF343541C7FF3D4C0641109ED04CBDAD8C2EE80CCC3723A3609454B733AEC068FE6D28772E388255A87710AB88848722CCB2C3ABA63AD04566B1BA4FDB2A2C07CC42C32B18E7280348C245E29BA51B10D4AE840B8F9858DFC68A73215DDD58DF30729D2966D11D4A5B20A6D441071BD5083FBC050232B7E594B11C60A5F7EA438E015018D145B979428A899BB53A42A96E081F7DA939CD0CA49DC3EE11B0DDDF94430014CE96485BDE669F214A3D4A88C6E4B3FFED1AB4DBC24C08224E03C47FA2A7D55997C2491717297155E1B1CA09898447AC0153435444C69B3B704D5B99189E346BFAD6143BDD2780D2219878823ECFF9DF861E3A729F913ECE36B46C0E9", + "sk" : "F2B0B79AEAABCC2B79B4BA975E0BAEDAAA5C80D842364CC03524088C1CA3B752AFF7A0BA70138DBBDC45A969C12E36819B4B101583A9E64407932796190751D393A651844F785A5FE92B567C2C2AE877BCE902C887555F93B6235D80A23D049E3B9867F6164C1DC6AE80B8A22108625DCC31465703572B3A8D599F55E694F391496AC402E4B754F97B4203E30BF4267BE95CA1047B2B67B36C00D6A9A86843B0508440D441AFC56362CC3594B9B1093073D4FC6EA7C35901066B25305398F58485905C6F99B9F583927AE80F81A06B5C1404E04C361B236A3A6818613C2245A47DC1A613549611C627AE63E38100D1049E0C6A913287DC810D7546B6AD4891C63C230EF285ECF2A47716C8E1DA751175B0D5D4C34B569B93D895461CB2382C71C4C5AC2E53493EF487DD617B7C643D7AA1608CD798854051B02093904C5F3EFAC3A39B98D6C69F4F02BB7BC62102E326D421CB72EB40411549B13C0B443568BC53070F381B962A5452B7AA8BCBABEE0AD090E7493077B3D3DB2F9D1B2833462A738629FA8174A449463E39CB097B6B81A95F01237C967C63FB3646A931C063E33A0457BBD8984CD02438A61CCD7AF577C041AE58442D48591D7C65AFEED9761736852A374281DB883F07092DC2B1E52CA803B90EAA3CB130D86DDB67303AA9CEB6098EE45B2E34C1CC1F149CD9F6907FD104AD01865E84C6ED72567B2497B86C889ACCCCEFB61A35E9412BC25D18C438F658615793814D93C42CA9B8462568D3E389B08756843926A9A7C0B65B4C1191995BB309117C52A27545F67B8A18C270D8B7A96CDA9EBAF08B546097D0DBA23F543E9AEA0421BB328C7CCA3792B392FC53B31C411312A592A5604BE84FE7F0B8F393A451EC73B7C831D3AAC3D1A1058E17BD68658F73E6970601CBEEA3C798417DFD3B0911B364F3BB650245581751BF75400226AB2A45CA5AB5D5C31DC018B5113676A7132C931CF87832AE85C53320BB18904B6D1CB9C87BA1ED007A80166F1E649A8A0C12CFEA81A2EB4DD615794EB006DD29713E608BAE25C1AA842773D82D7A624327E826786B38F184AEADD49808D5B2C650113B5C36CCE812FD95156CC0A1D9C6990C637433F1C0179B47C7389E7214652DF549F3724F112626B5D1418698A66DE09E6828645B8CBC405A19A9A910D7AB16AD1384B109535DBBA89023222F2335CC9C68AAE9BEDB241475D8C5140177494C7F1B273F64558647228D562131B4349368764AFDB054C12C0341FC8F7279234C2170CB7434F370C601053D77355191E03F9D516BC40A53E450323FC76B465B13A6D66E8B0A61A6808822E21866F6BF7B77B9D92C2CED831A594028FE50A5A005D02133840E0696236990045B5920F1789E4BCCFA90BF88B4A6266B04AE1854FFCB0AC0D6870E0A76AC5449BB9C9A9A8007AC28BBFFE998ADF5CC9DF03E9CEB139FE293A3FC908366C179004F9F587265711C008A14A44B29C3C6699C2CC57DBC6C540274FE500082E0885DB6BD71417E10A3B98C695FB812883D68C0E7770C1BA14D50E5493DA79630F35E229997834207BC3387009B5201B4A6B53CB90BF60755A048DE73BE31338B4ED00F942ACD6FA10040D836E12B650C1B9ED800414FE5B14DFCA90FA6BB7E350684C3B08656374D54776C312A645987B9C80B28933550922990E2CC4064114EE12F93D3000164C333BC77D566CD91C904965367B2350B87A6B0B5AA7F8A746FFD4576D22083F23C0F3EFC4D09CCB86DC4CAA55365A8A406ADD3CBA2127ECE221C9139C6C273BD4D3B1BC1EC0626B35DB44230662CC44AF683C92176C5171337746F0F4900B7369DF2B705B6387670B411E26288B8680F9CBB0A8EE01C9D0A9E4C61A19F1CBA55459B78602DC14BA52A0B9DE9DA0CBF330D3E71625228A6A9E471D70639B05792CB8550B24AC159C5B069C30740D09065C9280BF2B4F86C1CD9B78357383B2BCC4E771661F4CB75C6589DB317058E428398EA7BB88450F22525813058C609BF5B02A3098A619101C092F87AAD3881EEF6A2EA91A49DD3CDF1CA6952205E74F68AD5C06FC04163A70C0972C4AD752ACFCFD5529B75328548C18748026BD7965F73076D4BB8F84159756C879A5919FA7286E0DC39F1884587BA5E124177EACB2A3E96410A64C2D5403CCB939E428B1E7149CA2B3368C11C8E1F38082AB06F39455D55D12E95C585F0098FE6DC44BBC97C1547600D79B193FA838E42CEF6BAB08D462FAF017EE8414C9914316297CD56889207E13E71E544C6793B751174C5BB22294800785BB003589A899A562C6252EA679779522C03A0B933B07F29194C75B29693E27DDC6C4757CAC5B9219D98137516C450884C374CFA8572F3B9E27CC706B205C398866DF7972B8A44B7F975CFFC3401212BDA14C0BB9A50A5E5954F9534EE90C0F1F2328C618BE5C2166BE064D5D0A04392183FC5B3BDE635992998B68B8C7BD7A0A1C3BC99975AAB55AA39CC0E1D4C019EF73A53485349B58F4271AA29A4C8F8E97935981A83426B3BD0B5EDD1CC10458579450ED4D065A93AA0FA734F3206718974CA6EF35191C930EF67819F535EA5E80E54659B1AEC30534442E03CB9C4673679CC1CB205264EA53D20E383D98C08BFF78447C3335A4C3BD6F0794BA019E1EB130FAAC0D2F4193A6476CF014DDC988E757B66AC5C95BB7767E6C32EA8027B5E5A00E62C582EBC4AE6738B9637355F62A053737014C475FA24B144B2B47EEC97DAB92F58BBACCB0C36670CCC9326287FEA9FE7DC6A2ECC896652C9606943CA1A6E8688A821B69E33412025E26442AA2F70A68011F8BE62DB6E6283B9B85651FB8883ACAA20885807237A51CEC50CDD007B27C121FECA8A2C026D82359DE6D8B548D9A49A9914CE76584338BFC8F2CB51466414548CEF544B82ABCD277A6602887E4EDC5E09A20B1FF343541C7FF3D4C0641109ED04CBDAD8C2EE80CCC3723A3609454B733AEC068FE6D28772E388255A87710AB88848722CCB2C3ABA63AD04566B1BA4FDB2A2C07CC42C32B18E7280348C245E29BA51B10D4AE840B8F9858DFC68A73215DDD58DF30729D2966D11D4A5B20A6D441071BD5083FBC050232B7E594B11C60A5F7EA438E015018D145B979428A899BB53A42A96E081F7DA939CD0CA49DC3EE11B0DDDF94430014CE96485BDE669F214A3D4A88C6E4B3FFED1AB4DBC24C08224E03C47FA2A7D55997C2491717297155E1B1CA09898447AC0153435444C69B3B704D5B99189E346BFAD6143BDD2780D2219878823ECFF9DF861E3A729F913ECE36B46C0E9720FD4F96AB2CAC1BE382907E8CBA0702018CA27B28EA8F93CC19C4809885A3BBB02D701FD1350AAB462CB65DAC4B2F75928D378DFD7A0360DFF9185175538FE", + "ek" : "7FEC5CB63BFABE3D234C55686564581765EC8F8031083AAFE988D89E4AFA8F875C81FAE071624861450C58BF1EDE6926D08943AC2DC9ABB67A11118B8AD3BFD3C61979215647C1910582E5AA8F93251DB753812A8AA63D0F38F471EBE751884DFBDB15810500AA5160AD1DA28C1BAEBCCCF865398414FA4CC4624B3E8D7E51CF65E08021BDA3C905980177A6BE1B57A280D2D3C3859F5F6B08E4AD0EA425C9D0AEE759B7E6C52D17A704C7485F24637DE5E8E9C48251257784AEA688612E802BE53A91CAFF546EC1BA21B6ABD0D1B536F87D5723F4B6BC309E103EB96D2C0F33C52294553F3061355885FC249DF6DB8F7F5195C829E548C4DDCF487826388E98C7A00D59E8241463376452280DB9EEB77116339ACD7F95B60020282D90883932562DC9FA27A4C05A4F18FCCD489FFA3B66B5E741B25B2362E0A3DE5C1C55EA1349E126614A0BFEE505841AFACEDB27102336810536E577DEB14FCF7AE19FBD9C6D2D66D6281089AA5D65F789C7B84D3E3BB1A43B59A81220CE4CC9AC48FA5B78B23928073A9056D1B1AFBD5B1ED0A4BBB6C950236D2F9794316F705535D4DAE047BC31A14A57F05F3AF3BDF8D2A142006315958576B2C10062D75C25D01BE9D6E30B9B55C38D7EB0218EDA7F6ED424B1BF2E5349EE29CA58BC762BB537C41164A0203433AAFF8EFD2971B93F4E486F0FBCF0AD2BAB2D0C5C780FE774E166A54E84EC2623832881DF0E9FBDFC0F1B5DC35C6765E8570E688C11FFD0B66E2AF0B5814E748E1B9AD1F065736BF3B9B0E72EA0F0ABC5A2F81E67D3C4B29BF8E0AB475B21D4F129C4968F575F24927C6A2C62C1C706DDF79EAB00B4707246C7A1A78DB6B3101E68BEBD39896FC8466E23B3E601AC54DE72A4B20FC29AD9827AB2E799ECA5E78359F39C6CFC54D39E3EE77740CFE6CC25BF58EC8BA5661EC058554BF833415B83C4B486C0F30D6F1E6E7A970E5785885183C76AA40CFEB22AEA1773FC87C3458C9BFA36814CA01646B287EF29AF67C24E41528471729EF77C4535E7E38D37B6C828C866DBAE0F7D3F5977D49954B03875F03AC5A9F19B8A8B9C436A026B8A660E2DA06A780630F9DD64764406D85378A7790975CD039490C40232DAB29890AFD1BFA21950591DDDD6D970C1A251D9CCD760B221B68F980581A3F1EB7A747285D46C8665296758B53127AC18006F41B73FB5CAB072F733593A47EA28DD3B80E7BF573D02685221CEE73920C375A2599A8B74815090467161B11C13218023FA9306396DA437E5D0F0DCA56F5B85B4C3C995048F62F2ACEC8247325C4BD47B9ADD164BDFE9FA4C66ADB506D99923B055F528871C9D3035CF3FFED6E8B42AFB63E6BE31B1A5D4B3ACF7E44F021CF5E2167FA47131C8456D7A1668EED54AB2C2DC5C44CD48D7455210A3B5C34427C16876642E3210D319A6EBCCF63DBEC6291116F92D5EFE77519339E63F81C4739946A5AD1300715BF9AE053999A9DC75F00EEC459F2F37EEFE16CEAEAA000DB0456CE442F79D6080D9DEDD9A149BF1E0F2", + "k" : "121A53C01480A080190320AABED769DF50CD33F93F36AA89FF5D83E771460E6E", +}, +{ + "rngSeed" : "D26CE360D399BF7B89DC364AA7AC06BB513EAB8F527383E93E30727EDC3F22C262AA0EC70257B39EDFF0630DCDC1B79A", + "pk" : "0E4C3B97C9C7BFD505E2AA01B3CBCDA4096B37AAC72B5B50A41AA8F6CC518181B70FD3270561BED0938D964972BE491B6331A148317CD548124B7653F1709AF074B1FE4424DF4BB22AC91BFF7C04489526E5E2C82F2973408C4828368B87A7C14A569ED7B58F8EB6CCA19088C15031FADC0E5B37C442543E1EB944EA4A0541248496795BFDD56178C188F3642FC0580E70A62676555F6B3810DBC89B0A227A8AE554DDAB721C954DB21A87FDA98477D0C2AF2820B4691FFB046AD544B3D3919DCE8303E2F27152170A182A756B981E6CBC0B0F00274B521C1782B0516743D17A7D7B4B29F8DAB31C50739F68C57EFC48FF5B1D3757CD13FB8249ABBFC7B5A794E11E5B56B9F20C8E8A5718184167264BAE901B3AE5005F796341897542C70545A9B6B260BC13CFE536416A0F5E8440907A4FA1E79A292BA20A461285584D3A2993F2BBA8397756E1AC5050541806207FB8B313D0A6280B473C59ABC9964B5DAE58C6860337EB69396A24AA990349C62AAF8420B49E8A95AF404B81870B3C9459ACB62749E4AE2CD518E329776A6B68E33A7AC795330A8C1DDF2B326C3C269303BFDC9137ECFC9EDA856148AB9DD0A920CAC260E6B70A1B500D80D085FB9B91593254372C8E13B69B0D691A508A391B04478729CA19D75B566B472917614A53CA485C44E5600793A41A180697F20ACA35501E7215A49F591D376A2DFE4A3E0BBCBF4652710D0BA75898CCEE4C5B63514752CA8778F09D737337C9219F4B51A1277964C9E67B92888300CDA37C382700A40FC185AB8FEC55AA539CF115913C9C73AF0819188965E57B326F6615682915363C54A267C27D625CFAB0712138703CF709BC5C6B0CBB1D5D3884011C1B8AD8CBD1BA12BFDB8A80E9CFD1526D940233254B5DBC2BB17495B6466C0EBE684FBF331CBD99981A4362FD318B28015D9F3C3F1DA328917CB140A0567B4782EC8BB1FE31B298B6533C39733304B5F7C74206CC688C144A23CC72AA491E48701CD7F14FB3B7767A679BA4F4C4E1B778019471BD78BF6B55C2EAF43351F85190B07A66C35DDFA67DADD28C30C5264E3C3EE88B62D2C12541D1595A519897A99BBEE0207867AF34B245B00185A60B4A9CB92EAEE58B16F2977CEB180B32243839487ED6B88F6B94D2D4686EC7B7EA022E6D995C398896CD9876815A27EC77188640A4A4E64B65436440FAC565CAA10EBA9D48824541A6165D0BB97A634E6715ABEAB2BD8F91C18A3A6E899738188744CB6B817D21CF092B64E68CB6C9747D3CC34D0D294B4770548D61CF53BAC839B70F0350994ADA273312545462BCA9118848A343F2AACDDB2207F84A66B08958576069C7B7B69C02CF4F954CE3252FAAA0B7BFFA5952C51FBCCC7FCE3B6A0C8074F72519930395D967603D327FB8231C1811712308B914A75539128A658A2EEC38CB7081926E94A2903471B79B33ADF94456FA6A09438DBA6103062C1F5A5C66A8D15B829C8F01E7C1E21B10BED1AAC6D142EA94334660BBF448511563B5564ACD67F87A26F779527000584B61A65293CBD85AB5F3362BB96A61C922FFA77B8D90ACBA77869293A03D7CAB81B688306546AC348B22E368B8D717BC969ED83A12000548310A929E9738B2448D1CD7D1CAB551AE0E7B1C495565EE65F180ACA4A38847375ABE6C", + "sk" : "F67C9CCC171F6D04BD584A4502F796E5395AE59862DDE86FDF29192419A75E1B50222C8FDD18964D750AD5166EC56416C44715C22C29BA8B3F663517CCA3995DE71E8BFB5EBEC66F19A4C7F8098908A93650E2374E483C731219EC68B480B95F4A81155703BDE5AA7B5B6C57062C809F960A399A5E9D59C4E2F895BF30BDF60255EDBC0D59350A2CA86C18FA200543A1F94B05C8CB0A07476FA556905415CF1DE45568F07E37B37CE3E857F1D94AC9954CC9C9237439B9B0179AC0ABAADABB2ADA8559C80214C6A07A282627F949112218C13FC360E1FC589B6C05CAE9C42DF2A759760D2C5791F6E4203474A43836BF046CC931D133EBE82EC8B6414918110734318DB61739568A0AB42B9642759C57333971C406C6CE9CEA3C751C3BD9DB336FAA9C87108D80C152E51A543546548F1A7559681DD531ADB919163C716AC791B5782175913B95F36BB1DBEB4FF0F443B4829DEB738F76C8BA26E7A9C06A95A86543C2B95402F39180C08BD0E1AD1741BDE9722819A910227B34121CA404CB6245566002174ADE638533AB1D1FF9B37B9420813A28FDA5B02460B1460126C80614066B2137798215266EE571759B7CB0A0E266972C4AAD41612E743A8AB6022E5263D8576BB01959D2F23BF9102CEF541896F2523F3422BEBB252AA823B2291D3156195E05090C050966769D8774AB08D8314E29002E921AEE609E40790B1531300142B9E3701058BA90BE1757B5CA62B813A82A1A3654A130A8F38523D84D15D1A59EB5A81F918484037F5BBA53A564399DE86FFF3A2850BC2946704E6721B023D01552737CCED28415E819DB6B6C103A71DB13A9A0E4BFA74C24FCF8452630047B1A4F2C3851E7BA2FD6340E376B7451B767E5D3C1534447E0030AC023054EEA4477B290AC861E16CCB00A079E68345FC626CF17A42818F3BA685377E7A1596B37791297691DFCA02E02244A3372C4479E1076AF237A030AB511FDF60981364D82D0909D81B0FC691A1589287EA99496FA16DB4712DEA0A12A1814196B1E12091344A27336D80F10B2A877D70550026A39F68AEB97606466735418CD47311FFBBB5AFFC90DCA723518FA69615390401C8E047830F3F6B0059A9A9656A277D5B966A69E8D450BF3ABA7477656E67B689F91147E3979F230996C566DF9E0AA21B52E46868988E5A39F2461A5631AD35B7E049990A0F99BF39B9FEF962CA8403C7453ABBACCBAB4215C0BACB8BA27A7427806FE2842ED930F4858B6AF52098E3083E21078BED264FFA4A9CD911427B707D9832ADFC28B51AB407C9C45C10C12CA15226F1036EA065388A1499CE967CA619AF1D75C350A26E8673366377887F4B788861979A3218C2B5F3859C8BFF841736B3B7F029F3C542DDDFC271D3216F9EA9FEABC14DEDA35399CC927D42CF17B544413826875338E8B1B7F9CAB947700A55306B1A88FD5901FBA92923C7C353FD5B2CA793640A57B42926858953B7B544317BB85E6189A2A162203645622885A22C8B595B36E221488C0CAB5B3146CA5D04E6E218D8A215400972FED78C89A687ABF95716041CE1F213AE42459470084712B863A0C574B1062F472466947296DB330405B8E101C483077B1C397849032230E4C3B97C9C7BFD505E2AA01B3CBCDA4096B37AAC72B5B50A41AA8F6CC518181B70FD3270561BED0938D964972BE491B6331A148317CD548124B7653F1709AF074B1FE4424DF4BB22AC91BFF7C04489526E5E2C82F2973408C4828368B87A7C14A569ED7B58F8EB6CCA19088C15031FADC0E5B37C442543E1EB944EA4A0541248496795BFDD56178C188F3642FC0580E70A62676555F6B3810DBC89B0A227A8AE554DDAB721C954DB21A87FDA98477D0C2AF2820B4691FFB046AD544B3D3919DCE8303E2F27152170A182A756B981E6CBC0B0F00274B521C1782B0516743D17A7D7B4B29F8DAB31C50739F68C57EFC48FF5B1D3757CD13FB8249ABBFC7B5A794E11E5B56B9F20C8E8A5718184167264BAE901B3AE5005F796341897542C70545A9B6B260BC13CFE536416A0F5E8440907A4FA1E79A292BA20A461285584D3A2993F2BBA8397756E1AC5050541806207FB8B313D0A6280B473C59ABC9964B5DAE58C6860337EB69396A24AA990349C62AAF8420B49E8A95AF404B81870B3C9459ACB62749E4AE2CD518E329776A6B68E33A7AC795330A8C1DDF2B326C3C269303BFDC9137ECFC9EDA856148AB9DD0A920CAC260E6B70A1B500D80D085FB9B91593254372C8E13B69B0D691A508A391B04478729CA19D75B566B472917614A53CA485C44E5600793A41A180697F20ACA35501E7215A49F591D376A2DFE4A3E0BBCBF4652710D0BA75898CCEE4C5B63514752CA8778F09D737337C9219F4B51A1277964C9E67B92888300CDA37C382700A40FC185AB8FEC55AA539CF115913C9C73AF0819188965E57B326F6615682915363C54A267C27D625CFAB0712138703CF709BC5C6B0CBB1D5D3884011C1B8AD8CBD1BA12BFDB8A80E9CFD1526D940233254B5DBC2BB17495B6466C0EBE684FBF331CBD99981A4362FD318B28015D9F3C3F1DA328917CB140A0567B4782EC8BB1FE31B298B6533C39733304B5F7C74206CC688C144A23CC72AA491E48701CD7F14FB3B7767A679BA4F4C4E1B778019471BD78BF6B55C2EAF43351F85190B07A66C35DDFA67DADD28C30C5264E3C3EE88B62D2C12541D1595A519897A99BBEE0207867AF34B245B00185A60B4A9CB92EAEE58B16F2977CEB180B32243839487ED6B88F6B94D2D4686EC7B7EA022E6D995C398896CD9876815A27EC77188640A4A4E64B65436440FAC565CAA10EBA9D48824541A6165D0BB97A634E6715ABEAB2BD8F91C18A3A6E899738188744CB6B817D21CF092B64E68CB6C9747D3CC34D0D294B4770548D61CF53BAC839B70F0350994ADA273312545462BCA9118848A343F2AACDDB2207F84A66B08958576069C7B7B69C02CF4F954CE3252FAAA0B7BFFA5952C51FBCCC7FCE3B6A0C8074F72519930395D967603D327FB8231C1811712308B914A75539128A658A2EEC38CB7081926E94A2903471B79B33ADF94456FA6A09438DBA6103062C1F5A5C66A8D15B829C8F01E7C1E21B10BED1AAC6D142EA94334660BBF448511563B5564ACD67F87A26F779527000584B61A65293CBD85AB5F3362BB96A61C922FFA77B8D90ACBA77869293A03D7CAB81B688306546AC348B22E368B8D717BC969ED83A12000548310A929E9738B2448D1CD7D1CAB551AE0E7B1C495565EE65F180ACA4A38847375ABE6CBFA4B55C7BAF2651415D3F28D221B291B175340A07843B299A46E02E22657634165FD0A50A39142F7C6FAA2BFD417ADFA4224858281696965772F448C7AE22D4", + "ek" : "FF3BA18322AA2445F7DD65CFAA569CBC19E4CDB3D518C379F1956252C4852DE45AE7B5C1183802AF78100CAB80CA72FE8E0C87ECFD81A400FF238DE49214C05838D7C0A550833028A923B5D9A4289F28413579539DE3B0A1927E4A5ADFDBF54BA2B51B748C3BEEBE4E4701612ED1C996A75727EBAE7647D6D67DD8175D1614938BF5129B31D50D428D94CE9884BB56ECF9E2B7EAE5C57435F58E4A7D5E222698D4D2120E270625ED9275CA784E8AFE3295BDFA1FBC9F1548B74E3F5CCD01AFC61F257739BD96AFECCE86A3A7AE97D6FEF7A231813E04C79B69B001E8196792B619B4B1B3AEFE78B36F8DFD9F40CE85D0E6CDFF6B80FFF817638832E0389EBA1C09706AC79B456F7BFA20919D8C6D907C4D73176A1CFD42463184533913C832066EEB0F37655F58CCD276EB9B2962436571A1F41F00FEF65FCD9E398E37E49011EF9E302C4BB74E05D095B27A923966505B1C39B97FD282ECEC774C4D2EB43431FA0D4AA07D6AE0F5B95C8D3A26EDA8489343C7A6EFE0CC6EF087E1F5D3726CC6DDEAB85395F1157D789B41BE57AD0ABD228C7C7759547D7F59509FF7D415571D28D98370871AB34F817A06C8E8709CBC67D180BF21BA1650AF94CB0168AE0708175EB4EA72EA58C69BF09462175299F45C6DE651CF4CBD610F9D4FC2C814208751FC3A94D32168133BA4B410D8FE30171AED31B569CCCD46DE70B8742B333FFA0DA2AF255C107752FC58CA5E550A2E536021B5CCBCAC21C78625FD5899A7881DC66D7D3A483E8FAB1C4CB1ECB242D5126085D2B8952FED482D79DD65FF83E658CA6C199E71113F3AC016804D5E6EAE4213391CA5070EE4D73BE2373556704BA692F402F4E5D6C8E10FD99F3443899A2C79D64CCA40A683D1B8CB1CB87BE825248F03ED3251B2FBD20DCBD1E2FB422A6EFF373A49B08386137611A24A466BF8178DB051DA579F873BC709D3D8732D99FF9D193FA3A5E67C15814899B78A27DB79FC5E73D33F6995CBE31ABB6EBAE6FD8618E857484BF2504948A485D71441F5DBB98832198DCE47374C1E082F271DC26F0DB350C3E18EFC73F6871CE7925F958DEFE16757BBCEA1F5132FE8C123086C6BF14E4E7F65393E29C8BC98FB980A62BD91EA257AA472751D947B21AA6849F5A886C8C8CAB21E64398AC48337E96E0AA3DF5AF17A52F9CDB9780E720028CC18281E9FD2006AF14D3FD12D35FE30DE3A5109AE97856F945E7708FDDCA2A4507A7CAC7F9DC6601765B5A3FF570DDFD145BD97B6F1AEB3282161444E6AD085026525D349AF774A698E9B9EBE117A1EB8CBB1FAEA34E55F6F59576D3A45ECAB738D9BE187AE5F614CB9200988F260ED9ECEA65A9EA343DDD343F6B4AF8EC55E0E846000CD58D20C5602BCC74FC7D98977B107992C93CF3FE010C2574593686752AF82BDFAEF27489F5DFE3BF5F5EB6F79F27FBDD7D2B5F5018F5D0F002FA58D324D151762BDCC5E52FE31FDF0B410CFCCE399BB54094806144DEC1868AD04F943A34291B68B71755610165EF8EF57F21D6CB6", + "k" : "6469647FC39DB841A1D7F42521EF487AFFFADA02EC2E9E7A7EB4F0C78954466D", +}, +{ + "rngSeed" : "C5856298C3CB6AC9787A0F30938537AB2635B96F6D19CC9522063360E7A5C88E644929D2879180E3E5BCAD2422B7CFC3", + "pk" : "91F33DDDA5B9ED269034B722CFCCCEAE14AACAA81038E45B53518216CA5C332BBE3117BEB9CA69287A19DC7A078B412BAAE7CC5181A389B121BC4AC5D0CA67A97248D8F97D7526063CD88219C396EA11435E5C1D61DCCC963444B35C99C86B87E40928B88C47F64B919A028EE601229E5A01BBE17B600ACB7449A291B131543709A2B8A7D015419726563E366324588038E71FC3714CCD0A68FDE524932496BE0BA7ADFB6E15DBB99F995419C8AF3DB630E22393BEBB25819159ABC78C435342628CAB40A6350A8A86D1B1A93F6C9151F1895C4674CBF76313B1992D82C6DB218339292622807557F458CE057EC1969578379B75D1BF518976B9C69DC22008371930F06B4D1D2465139BC0A62C1D13DB9282C00549C45CB351518DF67CA3AC881501C3272B9C6EA1A7C527B0CE8AB9124257484B341B2200B49029E2624EB37B15E7D5823A3CA608F09A5FC590DD14CD2CB15CD238735D25BAB119B06026884AE5176BDCCBAB3550FED9B8D4A473A3D0A47A5C78B7B16B880911C7015A7EC281E3EA03274C6199B345DB21C0B0C541962A965FBA799840C01409463D138977D9BF8EE8BB3EE3B80E021ECE71CA0C6CA72F614706E0941B60C3C8C263AD8187A5D70E98740A0A729A0D07123C5B95D553CB1FD086D853869B68B44DB974F5161072D6B1F2A18C5F112376C434B9E777A597B6304AA0D1DC3D2F00010E481B9A9AA60E0ACB9394CD554A047A6262E4B32191E875E1688456A1877012933FFA51ADF131CBD47C28535595E7BC0777B954E094D6D62A5F67BD8B674ABD34500DA1A4C94BCAC04746C4234314E16C1320C48D714481A43C486C96D183B3EA54B19AC54E971710A293121181A16F5BCD861835C78357EA4A6E8B9B785C085545C85A36B3963288851A15ABAC8A39A109D0D092AC3EC60A93077486D7920A6C274E91B4F04A7E90D724D1E47F65A9CC80F806B20C98D9867A705472738982F3C608F61095548552CC01CBDF10C34F10709A31AA47A27807C74B9533523912637B1A89D8383945DC9553E9911F4B012D6C397F74C250A70D43DB4AA7DA34DF3C9490109FE7B1561CC25F0F37907FA567DDE3AE9DA24D425A7FDF35B2E61241400783BC2BA3B6098D6180B25194912175548453A669650E9007BE369A2181E1A46763170FC995770627B6E48903F574F06037D580CCC1649EF6EB1D8BE40392B86377532FE5B55BCD7177CD817701B4700B71A498359BCACA6393710105108C6C33894A41BD1E4A659B22C76C58C0D2F9648B8908397B2D30E9A4EA60C820AA12A58C3AAC757BA835483F02AE08F7C9AD8B593D756A33835759F7024867B5D98477EB6CABC4B7397FF52C6719CF73D42F00A4B362073325D48651C2088FEA27D540884851CF95F1A85626642F825265411F8B25067D98B5F595482D767B1C291A9E35100E49AF47A71CAF2214B592831D1024F56818997BCF035B1CE53C5213AA664E2226E83C50594354AA7974D39B09860B3560A534DB624B9A595BAF31BFC40978CB2903BB549EDA3445241620006371B0F7A410E16C828C6743846AB3644413C8C995A4527F82460E112DAE7A0D0A963B87E38A66E07290789200D6018CC7C454BA7BD5E56D7CE2D10FFA73F2A284BD579DD64E4229A9F36E58FCD24287C47316B08F", + "sk" : "619075D10644E5F5C9CEA8446DE5AB5C9BA99FFBA41A77CC6698B06E59AFF51A688ABB284A6C26FBAC9DDC31BFF11956651C149946797BD265338376144B67693C60DB18450DB25D9354A1D0D99E2E7A5BA1A871E7E60DF77115D7E08AA6B96133E0AF9050B784834FEB9BBCD0374C0116CD0339CBD3A3649A713ED3E1C185C73A693482DB86ACBB2688F2C622F8ABC7E4041A767698131012F51B9719208B76CB019533798563A55FA7009786049C79C8E617246AA98C4EE0407E0B262CE771EAC06AE8C4354630CAA42B2C8495481BD640D7A65831B099D0142DA3F3239F3AC555AC6440F5B14613147294B736D7B84C035EC8B8A478801C3460509989AC71BA5163618BF25212555BAB461994D58C95C3C492DF3992E47687962358AD8629B8B0C9F1A1AAD180B2C84A7788953145A885D388253E77B274E9C7E9B5882E386DCC9C0B34747265444B8DFB06C6944D84A9C16B9929A19451E4F09954FB2858DB2E73B0C940B2239CCCC167A60C18212967D7C262C6B06D9566C65C9EA1A86D665A802F5C96D75B67B93C07CF914EC50691BF676276652422A21840DB291175A58DA6246D5915E321CE3089ADA24791A7431DCF4117D3C167123BBE4E9C4670D3696CEA143F7C1F12036C63C4699D4C5A32734E85621311C4B826666DFC4578BA4C953D2A037EA1BFA58780EC1678BE56997B9375D74966CF9B01A6669AD2DBAA22A26B24A61E2F982B21E9A734C88A32035EDB12832F8B59257A0A84B75CC5EB2F7D194D3E1581D9E513598C0CDEC0450A255808040A69DB3A151C3709C80D55B985E5634839700250389D5AB81F04757A15359A0EF9263F2AC8E152AEA3D60E310868C4A71B01761A6C041346D840D1924468F41553F11A14846D694B3918856D0C485562A95071F31B83EC87F3A50EBD89146BF528592B32BFAC5DBCE78D14467FD873549D998A8F623383861640581627567CBB0310B19B0D554803FE4202E6D41AAF0C58E9F12B1C210E1AFC9FFA9C6E18381030D9442A41793BDC274105ABE23471DC2423547CA8C92983C0503D1A96B4CB44852B18C5C4F8AD53010C0F3B4F0CE61CE407556FD09814F2563D64134E082BE7FA574059CA964B3DDB0053B89627A4194399D01EB24B5E4777C82F7394D95ABB10C320032814288799CFD089DBB8AC6941252AF08D0248CEC9B62B124ABBC4A09DB3F6188E28A07329C26AC38DBF108CD7CA28DAD55514E481969A0F797A341CB05F617372046A68A221B3CFDAC744B6AB6A229FDB184DEC4BA266952836077129D7C1DBE0859B573F610995FEEA652FA35C4026B26F194D9333091DDC0FB39648C1B1C6DD69275BDA5F4D725DE01068ABB96C418C283FF65A4C5256DF2B2698D82062616DE5F93FC6D5005BD449B134361467CCCE99BC2DBA54A65A6234851FD283B9B77AB43DC40AB1D3AE8C749B9071596785BF53E34D76910384E1A2CE38586A628B7B5B4C50D325A3D340DFCCB929996C601969445121D39839CC1AC168236F032A656A01016DB1109D9692C81BCC192285BC4BAF0ED03D9D68849F723DFC630DD91258A2636BF4AA3C5FB429B8A01074F1983DE27CE91513DD44415675597C440CBEB434F8723891F33DDDA5B9ED269034B722CFCCCEAE14AACAA81038E45B53518216CA5C332BBE3117BEB9CA69287A19DC7A078B412BAAE7CC5181A389B121BC4AC5D0CA67A97248D8F97D7526063CD88219C396EA11435E5C1D61DCCC963444B35C99C86B87E40928B88C47F64B919A028EE601229E5A01BBE17B600ACB7449A291B131543709A2B8A7D015419726563E366324588038E71FC3714CCD0A68FDE524932496BE0BA7ADFB6E15DBB99F995419C8AF3DB630E22393BEBB25819159ABC78C435342628CAB40A6350A8A86D1B1A93F6C9151F1895C4674CBF76313B1992D82C6DB218339292622807557F458CE057EC1969578379B75D1BF518976B9C69DC22008371930F06B4D1D2465139BC0A62C1D13DB9282C00549C45CB351518DF67CA3AC881501C3272B9C6EA1A7C527B0CE8AB9124257484B341B2200B49029E2624EB37B15E7D5823A3CA608F09A5FC590DD14CD2CB15CD238735D25BAB119B06026884AE5176BDCCBAB3550FED9B8D4A473A3D0A47A5C78B7B16B880911C7015A7EC281E3EA03274C6199B345DB21C0B0C541962A965FBA799840C01409463D138977D9BF8EE8BB3EE3B80E021ECE71CA0C6CA72F614706E0941B60C3C8C263AD8187A5D70E98740A0A729A0D07123C5B95D553CB1FD086D853869B68B44DB974F5161072D6B1F2A18C5F112376C434B9E777A597B6304AA0D1DC3D2F00010E481B9A9AA60E0ACB9394CD554A047A6262E4B32191E875E1688456A1877012933FFA51ADF131CBD47C28535595E7BC0777B954E094D6D62A5F67BD8B674ABD34500DA1A4C94BCAC04746C4234314E16C1320C48D714481A43C486C96D183B3EA54B19AC54E971710A293121181A16F5BCD861835C78357EA4A6E8B9B785C085545C85A36B3963288851A15ABAC8A39A109D0D092AC3EC60A93077486D7920A6C274E91B4F04A7E90D724D1E47F65A9CC80F806B20C98D9867A705472738982F3C608F61095548552CC01CBDF10C34F10709A31AA47A27807C74B9533523912637B1A89D8383945DC9553E9911F4B012D6C397F74C250A70D43DB4AA7DA34DF3C9490109FE7B1561CC25F0F37907FA567DDE3AE9DA24D425A7FDF35B2E61241400783BC2BA3B6098D6180B25194912175548453A669650E9007BE369A2181E1A46763170FC995770627B6E48903F574F06037D580CCC1649EF6EB1D8BE40392B86377532FE5B55BCD7177CD817701B4700B71A498359BCACA6393710105108C6C33894A41BD1E4A659B22C76C58C0D2F9648B8908397B2D30E9A4EA60C820AA12A58C3AAC757BA835483F02AE08F7C9AD8B593D756A33835759F7024867B5D98477EB6CABC4B7397FF52C6719CF73D42F00A4B362073325D48651C2088FEA27D540884851CF95F1A85626642F825265411F8B25067D98B5F595482D767B1C291A9E35100E49AF47A71CAF2214B592831D1024F56818997BCF035B1CE53C5213AA664E2226E83C50594354AA7974D39B09860B3560A534DB624B9A595BAF31BFC40978CB2903BB549EDA3445241620006371B0F7A410E16C828C6743846AB3644413C8C995A4527F82460E112DAE7A0D0A963B87E38A66E07290789200D6018CC7C454BA7BD5E56D7CE2D10FFA73F2A284BD579DD64E4229A9F36E58FCD24287C47316B08F9675FC6D1E3CC4E0EB62D31B6B4F10022D373D2718F3D20EE1CC00EF6892D9A0171EBB1A64C173B3D4D997C12F734D2D57FA2127052887DCC6461FCC23B66FEC", + "ek" : "836E9F5A78325E6C0ABF69C6171879ACF9F68BC0D1C84A814D9268641E51FCD9DD3755B9A9DFCB37C42482981A8F66C7F7D9BD6D2B752B38590F3865B5A9EC88F0D5D151EEAADE887AB44FF758C8F119E7FCB60D8870DBBA2D3D81D6D29539D06BAB35D5DC8E9D2DDA8355799D1468887D3A04A6974C5F59EE0D2AD347FD28C38C895AF4E3BDF6CD7850A81133F514C0B8D90E0C6CDA2045B6747F98432CFD51C7380FAF09541A2C7758CD338F2F7B9ED1C79825EEA5E14C1996CF9AF40598BE80E4C563F1D1F14F4C8799237C3CFBF3A9FC55BE0E525DA357FC9C34D3D5B1D0AE8DCD15447882BDD95C8B0DFB4BEFA911C34B23D2ACA11504ACCAAFE82408F6214890A578C6CBC7C3DFF83ECA2FFC61C1107304D05881F288A52332FA99B2411F6C4B466FA830B6466808DD16080467B039EE534C3A72E9F4B8FD3A6669340E94E4425F07D8030F4134C6BF6AA6DE184E75024C1D5D3AB91B12DBC48C96110025841550F91BEBBD7C23892338E79E8D17660C2BAFC2F5EAC66378929156E8241AFF689A4AE51D63060C894579151FDA42115B7FEFD3EA2F929B4A043A7F58CD23D10DBABDF7FA48320D29A20E90FA999CE010D67B74C9ABD692B60980DA62D66152DFA64734E52C1ECE1C561ABE6A217C7F0BB6EA6BDB52D66F00C9DBEF13FA4672E8FBC067570A6D1E22CBE54A9F9801E9117F270F97409D4E2BC6F2F8FCC551BA9719CAFE0817A7D6A5FFF90FC4B39E987834D5EFAE5F8A755C273693EA0C996EF631CF30935C91647E7B2407B61EB49449EA7269F25438C7ACD9FCD9B9DB8CEAC614A4776C5F080A0424188EA123968CA5F19AC5CF37413EC5F7737B7E03EE7DCE9B5C61B1D3A9830892C740EE6551622F1B9A172FEEF7839475DBA25BF6F90D7CBF34C2E92FFA89A2A21F8FE3F4A6A2B59AA6E9547B222FCC6B7C4F75257991D2887E9938984846430E9E56AD6AB5F31B44F426849CAC07CE596277CC4B146947686EDD0ADFF124DB663EF7D53553979E5E296F039AC882D33E0BA17B1905569A603A4A6CB6E460107EB3F2D6AA83993E51F04A4337E311A580A1C2C56B8F880DEC7064412C848E56BC659CB0B7BD10CE38B3872C98AC67B10A47844A3374C64170D062F0C374773E92D7426509A64B9186A931D13F39BE2DA88A5DD380A174C81C5F9ADC80EF6FCAA34151BFD33056B97C6495A2500E045E4298F4B198BB12FCED3BA77822B22DB4AF39769F39431F70249E40DE4498381941F3138B0FA555E070DFF6011828C08DE9E9995F768A804EA49553C66B70B6FFB1D550A29CED6127CAD56A33D2E11E95FD75D576ACFB4CCA387736AF8E4C902B555235D488DD6369455661ADE58A975D112F09DE13CED0A3BA339D6B1840BAA0542B7CC77744D16B8800B81DA2853C43C706CDCB4F9AE7D29D006032EBF3493B2326CC6EC122BCC3CED32B531862E674DFFB6CE4E8C2EAC52A583ECEC557A804ADF987A27149DBB6D528D79A36A1C709D3D359189F10B8CB1C2296A91655FE34AAD18C4AC2", + "k" : "09E8810ADBA182BD9E7FB9D943A61E095B8CB965FC02FB209310595B65915C1A", +}, +{ + "rngSeed" : "A28EAD0A08E7228AEFF602B16A1E752278B8ED1E91DAC67994F5ADC372E1D82F95CC390CD97AB9212275E0566C833FD8", + "pk" : "2ECB47BC7C78372B75DE587297848724335F44545A35FA11E6E1208ED4764FB8BD4AF9712E21C8B3C99E5A04432EC7C0B3200384534AAE227C6400883AC21EC5152380B458BB69C5CE909842D3B07EF2C539C44A2DF2013AA97A08B511E444996144CFF78CA394B5440F4ABA566383B0375EDB2544A42C4DF25B6A96E0263C8962BF9B716BDCAAB098B41F735018735D8A26AD7D93B0F17452BB64180A572F75091AF0BA9B3499A134E90A167BA72DDA62CFDC27E3234B1412115AD0463DA2600DEC2E7010B1FC914F3772C858C80608244CC014A31036A9ABB68946B51354D07FB914BF22E17EA21854AB778B67B40CEF331CF8374594385C28586DCFD5421D1A008634B006965F88D58A5CB449F52136D7F82CFD0ACA3B6355117B15CB51240C6A239BA26380C55ABE19912BE90466CB701D4BBCC5E138C525BF28D23CB2E0452927873C17C7E431051F99A6F585B89FACBF71F594B49BA84C7235978AAA2BAA1F9E7496509009ACF56C5D09A4C53B1CF2845A0D0555528C8C1D287CE7E0AA56E85ADADB89440305EB942B1FDA247457751FC1B5B8811FDAA95592A047E297B9418C52F0189AE8A21254F838DEB89360292956749007CA73581AA79F37116533068D2425D5ECBA7447B7CC5729D987564EE3CB2CCABB6C31BA24375304A70638533C67BC6E53C51B17559133D4ACA5A6BF44C635615A9881E25E4D137393B76B5017254970B56ED13F7AEA587458A43B3435BB018FF6082661DA9FEC065C0EC23BFF1B919633806A835139DA4C4D34C6F4567DAF07536EEC3D4D0347F3ABBD7F32317C33C2660393AF455C2DC506CA111F48DA051D8350EDF5590ADAAE9731C2E301A824721718968CE3E66BE430B8DB293A22859D68B353DD45467C85AB7F4BAA0D5B2CDB83C94A895A58E09E9F249153F25FC6D3C7EF50B1929B197128A64DE27C48041E08C26D64B8C229CB24F9E9667AEA2A33531D19DCB6ADA725EEE88F063CBC749C2E90F989C8F0C7CF6BCDA814BB2B321F1862B32CB8294E99C78BA21D86A402A1C8C3E7F9A11F09306E588FD1856B7F5C5EAA768DD72793A3A88D35E931DE0BBE0BBB697010B2C75C3308649C1260648BD3A6D6E57C56E00D5DE7270D2C26572AAC88E08238658332879D5FFA005F7C8DB415403AE73AE728A5F3BB228A326B05BB26A0C91544D98DB8CC687C597AE2E6B142B101E9731AC8C20C7ECA11887B7FC8886C304A162B30CBC510CE54EA5324DC9B82F39B0D971DFA69B81AD99D49BCA9E3449774985F5051A7EEAABDBD33857741C11ADB51744539B1095C1B32CC99F81A0CCC6DC88BA829B11025CA5DD3353639FB8148088763EC9E7C14370766B918E93D8839A8B0A34D3090933DF3A86E3976D09776A0EC3229741B2155B6C7AC5431421C7B80812523155C9CC5D890268661501628231C1C660583829E7B3984BCC8AD20632C16993673818F7BA15A5064AA42CDB9F7B0E0708328213388B06A04D559FCD83A10913C15167363F997F62B6A03614C46B9ACD703BE1A1B641E7910EA273022168352C89CD7616D7746983B3B51D57770196A68A50125F1634FABA0C752826CE0AA6448C86FA76C6A3E2390840B0C7F333650C53E0A998B66B533746765316F08A94E18DE52516228102FF16993AC61ABD8D7884C", + "sk" : "A46A88DF4035C55137522295E986CB5E6605F7DA81FC0B1F29903B3D283022DB4F8046378FCA124F5580A1DC4535E64DFEA6C4FED63AA73960B4E14808383CBB12CF6F204D07F852A815A793EAAC2F147D24C53E412A21A7550EF4E8122F46CDC9C560BF725545C82B743041C3933EFF115D15746F3FCC5934C132AF7A18B2A37FDCE899E9C1CC0417124F0C279360C311A08CFB301655483D7F92853274C9F81683E5CA26283527647A0EF6D09225D4AF7F1C1CA7563E824454B4A2CDFB5C582C498B4A1A1645553BF7DC30D6A56E0B7CA57510AA315818E527A64BC1B7841801EDAB2446863D48A53DC83203A0F68BE3FC498B288E8457CF6F8132B367A9529BBB814151950C3619FB49D5888AA7424C30D415D08492A7CA50E76B56FB18BCC1CA99C45CA066340FF1E5BECA8C51D6355504496E9E4A407AE57EE5A30F92CA1E0D3298BC252ED70114E426A76C5C08AB67304550CD7EB6366205B639B30DA30978BCE2C745283087C9BA87D3273DF10E3E2573479BC205824ABA06AE5FD6171355A73C771939E767412333685C6CF9CB622554AF01672967BBA8E043AD491568AEE39E35888A4B996F6279223E820F20F5C95A6A66A972CEA5BBA874FB018CF05AE1DC60208510C85C6E3211583C4C21965B27817982E1165B6A59017B4BBF3DB1BA31D95F14BC76C104C1097AA3372992026035E89895ADD31669481B6C558842B3BD1AB5BC9AC2BB6754B0A8B07419A35096B2365B60B317571674012EEB7157B233C4A1D309BC1C4C7FC047D5C3382DBB4CF65C9D9A24BDA690C37D47AB27500BA5748A0294C8C9FB8ACC8B3D938270A73C55DE662544C7C576C73A2BD9CC983A60DDC0152BE508D341A29595A40C7B617D6BB45D247128505A930A4BF9194EF4E27FA9D9CBCC55C8C9B4CF675876CEB2BB711798C850C3E85BB9E84BCC716195264737C03B4B2738188C0922D50BA49C01B4FBB85E48AC9E02739FBF556C5D5210283014FF280263D7C5353A0454D93195BC4B8ED41551B10A7A19808292C73FD63E61840D10F5C5B2853EE55265F78CB112B3A3521577C90B2744D855B758431E71816FD200B47791328481C49B24F991C9824742DA7043CA2B47B7449126533ADB1191D4CA1E3779515EB05E9C57C383A3BCDD991FAE460AC8C6983E16484D7AA00AA12AFB778004366765B3AB6365737E7A4227E7B5B7729BD9086FF4B64CC7AB06AD353C6BB24E05557FE2D60436F9596639ABAB693449247E881827F0133B9C1569BAA2BF87486CB1FA0DBCCAA179B397B01906847A970CA28F29F9A8EC0A0FD0A6C02C52A75BF7C3C0C180502590F3766E56556502B1A94383866082681D564B333B852B180C91E6873B143F8475A3B9D67C1421A871A1BDD3C073CDC16F4A717084B95528D43DDF2870BA2A9689310D761A6FD4179261F219DE4500AD4B186D97CD1074B71FF893B3D4C889CCBC03264540A26B8EA3551DD86D77C29756C6972AB87AC9D07999F0BDAC8A8796C8B83E9311B1A529C20A715E382F21E64F9FD0624792B818D93EB2E3BE8CF8BF16793AEE06A018EB86AE09292D5599EA78A2553A52793C7148F12762BA5DF79B5242249684B1716B818498A5B82ECB47BC7C78372B75DE587297848724335F44545A35FA11E6E1208ED4764FB8BD4AF9712E21C8B3C99E5A04432EC7C0B3200384534AAE227C6400883AC21EC5152380B458BB69C5CE909842D3B07EF2C539C44A2DF2013AA97A08B511E444996144CFF78CA394B5440F4ABA566383B0375EDB2544A42C4DF25B6A96E0263C8962BF9B716BDCAAB098B41F735018735D8A26AD7D93B0F17452BB64180A572F75091AF0BA9B3499A134E90A167BA72DDA62CFDC27E3234B1412115AD0463DA2600DEC2E7010B1FC914F3772C858C80608244CC014A31036A9ABB68946B51354D07FB914BF22E17EA21854AB778B67B40CEF331CF8374594385C28586DCFD5421D1A008634B006965F88D58A5CB449F52136D7F82CFD0ACA3B6355117B15CB51240C6A239BA26380C55ABE19912BE90466CB701D4BBCC5E138C525BF28D23CB2E0452927873C17C7E431051F99A6F585B89FACBF71F594B49BA84C7235978AAA2BAA1F9E7496509009ACF56C5D09A4C53B1CF2845A0D0555528C8C1D287CE7E0AA56E85ADADB89440305EB942B1FDA247457751FC1B5B8811FDAA95592A047E297B9418C52F0189AE8A21254F838DEB89360292956749007CA73581AA79F37116533068D2425D5ECBA7447B7CC5729D987564EE3CB2CCABB6C31BA24375304A70638533C67BC6E53C51B17559133D4ACA5A6BF44C635615A9881E25E4D137393B76B5017254970B56ED13F7AEA587458A43B3435BB018FF6082661DA9FEC065C0EC23BFF1B919633806A835139DA4C4D34C6F4567DAF07536EEC3D4D0347F3ABBD7F32317C33C2660393AF455C2DC506CA111F48DA051D8350EDF5590ADAAE9731C2E301A824721718968CE3E66BE430B8DB293A22859D68B353DD45467C85AB7F4BAA0D5B2CDB83C94A895A58E09E9F249153F25FC6D3C7EF50B1929B197128A64DE27C48041E08C26D64B8C229CB24F9E9667AEA2A33531D19DCB6ADA725EEE88F063CBC749C2E90F989C8F0C7CF6BCDA814BB2B321F1862B32CB8294E99C78BA21D86A402A1C8C3E7F9A11F09306E588FD1856B7F5C5EAA768DD72793A3A88D35E931DE0BBE0BBB697010B2C75C3308649C1260648BD3A6D6E57C56E00D5DE7270D2C26572AAC88E08238658332879D5FFA005F7C8DB415403AE73AE728A5F3BB228A326B05BB26A0C91544D98DB8CC687C597AE2E6B142B101E9731AC8C20C7ECA11887B7FC8886C304A162B30CBC510CE54EA5324DC9B82F39B0D971DFA69B81AD99D49BCA9E3449774985F5051A7EEAABDBD33857741C11ADB51744539B1095C1B32CC99F81A0CCC6DC88BA829B11025CA5DD3353639FB8148088763EC9E7C14370766B918E93D8839A8B0A34D3090933DF3A86E3976D09776A0EC3229741B2155B6C7AC5431421C7B80812523155C9CC5D890268661501628231C1C660583829E7B3984BCC8AD20632C16993673818F7BA15A5064AA42CDB9F7B0E0708328213388B06A04D559FCD83A10913C15167363F997F62B6A03614C46B9ACD703BE1A1B641E7910EA273022168352C89CD7616D7746983B3B51D57770196A68A50125F1634FABA0C752826CE0AA6448C86FA76C6A3E2390840B0C7F333650C53E0A998B66B533746765316F08A94E18DE52516228102FF16993AC61ABD8D7884C9D162FCE2F019205A2106ACC8E3E3465B6FA3912A06C764E625CBE3B95DEA6C80B472C6DA19B790E6C9591EE625B42CA0FC04FD9F69D72CE4EFDB3B9ED8D9C29", + "ek" : "1E45497C2E6114D960AF5C28895D6626C9EF4BCE80AC125D4EE72DBBD61B4632E53A08A065B4F0E3D326B571A2D6BB3C775FAE93253C21B03511E72B2AF7C0D7AF5B22A3E01CA6BC8D5FA52FB54E7CAF5443AB33D0241ED3FB72A0E55BDC0CFCB5C4EEFB2F7EC848430E9734DA11F7A2405048022CC0A658136E542D5D177521D13C6758BFEAB7952A52904D5AEBFCB7E36857E9DCCF8BB587E1CBEE7F2AB66B51BD1CA8141498C5759C8F018E33F3CC0A63CED05F0619319337EDF66D5F5B87E3FA44AB8C6C32D6687F0B26D5527A724B158C95A566A33AC5F8DD1FCB98AE0E840E3C870986452AE876B40B6686B35B800A6A12BC2CD0BC0D9F6E78E143B6195A1F521918D93C9EABFB87FC4F66818484D1BAE556E9BC895C7705ADA2B23F7B03AE9CF84C144881E001D1EE33425C436183164877FFADD07BDD658B36CA387E63E330D2A2660A1BF9952F70A828CCF5F2E97E1CCCF23906C88DD2E2D6BB943BCBE2B53603F8E7870B7EFF150F8D6C1EBF18A04532466960991146CCFFDCA02B90BB8F41C116B76DEEFC94F5D46A01BD88C56038A5CAC208FBD96CF1D859442FE883A9C18D7EE18C67A106E78DB742808EC92E350E772CDB1FD2D71F3C01864E297E9A55D50BA8CCA1FA801FA08B1041C2B2564E79173CB0DA613350A96160562AD867BF8BC8ABB54A5B60DE094BF2E25C52D5BAEB99300A293AB3911932873791FF4D3E54C92FF26737BDF54B6CC9758DDA50FD47D9DC0658114DF57EB9026002E5F97A38AD7D8C8224B235093CB339C16CBAEE6DD780459AFC3BFF88DE7E2E014E3E2EF913829368E6597043AF84FC42991E76EC57162BB3FC58B6886333EA5F44B6D3E8F95A268C1BF72B3B1FDB96BFCC3CC669F19DA484C46664E3FD83A0E1F47951DA3A9EF3F3D590C4459D71D1E740E1B4E0C6AF35142750A88C6EF9CB6C060A8E6CEFDE10F37C36DEB07E385FD85E6808B4E883DB563A939DCE4C6B5B58354E3AEB3A56F777D8193D4E559F1F4B6412ADBD773452EADFAE66AEA4809D46FE2F8F654A190B2DBA1FE0F0A89840E800C26E0CD8D2BB21CDFA56A1BBFE09A1C4BB0861041E92ABA003BC87AB9D0230E6749528677656C21BFDBBBA899955584126EFF8F5919F4AC06D6DE46BD34645B5EBBD0F505D1CBABFF874BC0D22DCD948D4F0525251AD6AF53682B12260A859FFB7DC94FAC4F7A48EB37D5AE35A6F5576443DDC4782530568C5EC0834650811D3C466396EAB57E3BC87B830F05808919AF7DF40F6EC4062A295D57E46129524C18D6D09F9110B1B47461C64A0F49371431D7B4BA243392500CFE6F809D200B69B9227D1AB2495C60ED619C69AD53CDBA59E7FC12F7435F3C8D97C44EC002F0D1A664B286A538735C44279CE05CBF1A2F39D5BC94F676CB8663F0185519524D9390663B4A97ED8B652CBE76F422A1E17E966BBDA2A9F31EA2AF767899B33541ECB0B92CA2C19EF9DA540B2D134A3AD01281977E8BDFF2B2284D7B926A168109B1546C9BFBE10DA85AB1372599443D0", + "k" : "89C2C2979111B77108A9B6A8A68BF4AD591C07936423601C59CC7C3913B8C45A", +}, +{ + "rngSeed" : "92877D706DAF88EF3412EB143DB8CD91BC047A9A43B7ACDAA42523560DEE4C172697BE4332042FCAB91135839BF74AB2", + "pk" : "7A6917006162EFA4CFBD499B8C853E102C9639457F66812D58383E629A7522F1C683D48D8A216A0AA82454F29732077F4BAA593DE951857227B976A35A8013A622AFE355144B63BBBE58265287CF6D605421E73E7DF7301B59A885821EC0314EE76359D9D715EEC1C2AE726FC0592EE01C1D45D6C94C76CFF66BB3BC321358E33F16E1AD44B35E256BAC5AB519E404C3CBA647637537A524849CF952DEDA7940DC1C3A213D8C13580EBC10E2B458873BA5CB30C00D855530B0B5F86003A2C6641A72170B238FEDDB624F9660E16A9C545A0FE8102612979552F311A9417FCC8C8768280A4902A8AE696131C76338097F0C3A2F8731CA25D55A21B619D1C48550371CB2CAC00E27C8AB9C8D7BB944E4BAB625EB1BF7C55F0DF84CE67C48FBB4438EABC818CC2871C619222A0C504C6898C31B9E859998911F4A29000E4063CC0A5D13975182C97047520A3FD7430117B5D0B2B088741690B5662A3B02978C5A2F1C330871957C5C73BB5A2FDEB0B5F3E5953B509B2887435B41BADD607307941AAD1CADE20C4A22B80683B80DFFF1BF82A4AE80EB0915190197C1AE23145522C86F86955D0D3B7B4B83B019123674AAAC2B4138E4B36169B1784A4BBAC8570ABA1ACB13AC0AB84A6BF987A23EC91F7C6C2DCD6B952C505515B4B4B1E7C749E693EF4A7DCDF8B7E2F89168991C0385829E46C7FAEA3C7FB18EBBDB333A4A16676AA81DAA4AB519638807BC977729D4474F4C068897E77ABE636DF8525C35E7C691B49C72E50BBD8570D6B888041380A6A4B9A65868F247141EE137BA422807A57A9389CC195345968086359B36E5316C594A88959B7B006ABB88D754BED942230B36945A141D4810050834CAA24CF58747820A6AACDAB186BBA056BBC043DA570F874EEDD29718795EE19C9E8FD4378FA8A42BA6812DC51874CB0285420419D408E897A7F8FB9AD0238EC632674440B66E838FAFD731B50092324A9B11A545BB9A9D7A242D54C6BF897A080AC0B06B57535E542D254AC581450D82D73EF779865708A2563C86E4CB3133CC5FC2E16DD2B043449A73E59A5C6A29A227A469CE406192BA4825E3503F3552F743BC3DCB945048A95C70209BF5C5EFC76227EC7D947A19DFA0AF12B078BC588C1CF9C1300961C59CA8529C357B9087B572A8BD2739A7A526F3D874E6E2A23C4242BDC652569C7ED3546E3E85B7865611C2CB7AD551142B2503E14C0FB8220755036F6BF95DE3F1440598076DB3410A4AC1E52C91F038956731622DF255646CA02FE7CF1AAC75D972A5D744512B4B498C666CA68660B984BBE6A1833E83CAAFB80E17EA49C484AE2B6475D2E276E0C9317C47090DC9BC134B606A6A1336A40881D76EBFA954DC550CAC192082E1AA81F9A6D9162B038A021E09B28BD0B959884ACC836A4A95100FC93071DC474E593A1D7CA409001B6C40C3FB13A5B6640A32DA0B6DB086F1691614D935C29B67D8D54732948DFA27296A63607C17973B764B9C05713BF0026BC0534B9187FE33690826A6C80014B2F97312D53B3B22AA1740B0A47CA8807145EAE577C994B1DFEB19109B5B99019329FB6ADAE267C2759FDAE64CF479462C4185CA67255971AACE8351A94501D772B15890042363B3BB64B6373E44C5BF6AE2CAED5DFC3E0F0DCA2015579E6C636683", + "sk" : "36059BF728AAB04B86AC60B0F5C233A78A036BEAA04A2873B71A3E29272E922B4537F97AEF0700AFA68B6DA877B25B1ED143BA6CA538BF04662DCB500466A70EBA596776C6D3662073F20C7582614EAA1517B5578378069F2704A4C5836A55006E054D623B6D04D48ABD14570B4613F4C155F9D86C8C695AB9A2744E40794375C07CA62E1A3269104BB9CE60C8E2C6C3F9153AE3555A3A35A1717739CCB195E315400F3704C7C839614C4CC799A4AB250AF448B70B871A3A1B8AEBFA6278F6222C41AAFD51BFD126032BA90E8D103E64E1036FA72DD9E752B72903D3B45443FA5302103D041B12B1A2CE0BF7406F81812807764ED435074A6A55DBCE1065913DEAA3E7164FCC6419A0D0CDBFC314AB66B2BD40A1E2E0AF801B5E9A22023D1C797F49A345661E9C0352D9E880EDD71B2E4A674265B3DBE4822738877F305F6E59BD5E4A4BA8AAAEDFB28A87733411DA7981F458F09A0D8BD55446AAA44F382B4BAC9B08FA53B6932337B438744064C7DC9B5E95C61BE3C454590DF2A88565DCAEA473BC3051A08BD6C238E36EA4D28064814C5D210C2CD8A8325230EC330063585B8472AD1415725B51950C171FA4C325C9A8795AD3585E515285678AA43470AF7705D800BBFC14A9172B11275471F0948DFED89782D2A214095F11815026F202E18CBCCFC75B46763CF37AA5558A34BFE51176B904025B16A08A07635455A01B69820541336A0397ABC928E735FB969321216D17341CABB82D07A6A036D7CBEBBAA1B7771497B329D67A9C247B6C31798D47347E41A425D7A5B3B1F38D914364A5176FFEC86A8F743528179A5C544FABA84C48387DD3264423BC083DA506B356A51EFB1D18DA3A5EF2361EC43D2C80395D126097A7A5CC6A4354699017A7CDB02A4823F8327D729A89C1971F6A8646B92D1D38031E5C4A29733AB30063BD86ABE6BB19B85687575B85406861A6A3C93085501F62088E245F25C450867C349700732578BEC2152746C724A4DA7B5B0A0A6DF57A67341ACD911D12E2774A78A6F003885CF26BFDE0C8C1C24A63F33E5444AC342451E5F51820217FB20C14A64738F43A5AADE60E3367C3D1695E409BCFD3E57885D87B4D19C3744CA797B74E1AF7253613AAA5E9644279CCF963A8AB38AB07A1C8EC6558C3B6A285B38EA34ACD49C1A74F3610745C8CC3DA36202C6363079F3E252157C8882860A1852663A7B4416D33BEA9A08157F61E5AE8BF3AABB7098B2110DBA39E4A681EAC0E765320D0FA6A6BEC730A1848D5137A2F62A7B234180CB4B82568202B59713FA38D10D6C6ABA1BE37325DB36896B80B0E6B356CB735C004D98CAAB7893E383DA8A467C4A71C0E9316BD640F226A68EE2C138B8159A6147C9939CA45304B5DF944B377BA4826964B2B86D50B9EDD5294C3DA3B2DDB02CE786EB02B79E8850AE923CF8B99211BA97806795C2BFA713079BA7728BA7B94B985728B83BCBD64F26A8D5594FBDC18764307A9F66A1E2B0D0D290CD23878ADF03E2EBB9F0C48C9132835121C61709A740D937C8010A866F494AF723D57B91B98034C6AF9388D1B7DBF264F775462A5F581C0CA23C2D45F98C267951B40D36913B23612091000F49577EB8CAF83744B7A6917006162EFA4CFBD499B8C853E102C9639457F66812D58383E629A7522F1C683D48D8A216A0AA82454F29732077F4BAA593DE951857227B976A35A8013A622AFE355144B63BBBE58265287CF6D605421E73E7DF7301B59A885821EC0314EE76359D9D715EEC1C2AE726FC0592EE01C1D45D6C94C76CFF66BB3BC321358E33F16E1AD44B35E256BAC5AB519E404C3CBA647637537A524849CF952DEDA7940DC1C3A213D8C13580EBC10E2B458873BA5CB30C00D855530B0B5F86003A2C6641A72170B238FEDDB624F9660E16A9C545A0FE8102612979552F311A9417FCC8C8768280A4902A8AE696131C76338097F0C3A2F8731CA25D55A21B619D1C48550371CB2CAC00E27C8AB9C8D7BB944E4BAB625EB1BF7C55F0DF84CE67C48FBB4438EABC818CC2871C619222A0C504C6898C31B9E859998911F4A29000E4063CC0A5D13975182C97047520A3FD7430117B5D0B2B088741690B5662A3B02978C5A2F1C330871957C5C73BB5A2FDEB0B5F3E5953B509B2887435B41BADD607307941AAD1CADE20C4A22B80683B80DFFF1BF82A4AE80EB0915190197C1AE23145522C86F86955D0D3B7B4B83B019123674AAAC2B4138E4B36169B1784A4BBAC8570ABA1ACB13AC0AB84A6BF987A23EC91F7C6C2DCD6B952C505515B4B4B1E7C749E693EF4A7DCDF8B7E2F89168991C0385829E46C7FAEA3C7FB18EBBDB333A4A16676AA81DAA4AB519638807BC977729D4474F4C068897E77ABE636DF8525C35E7C691B49C72E50BBD8570D6B888041380A6A4B9A65868F247141EE137BA422807A57A9389CC195345968086359B36E5316C594A88959B7B006ABB88D754BED942230B36945A141D4810050834CAA24CF58747820A6AACDAB186BBA056BBC043DA570F874EEDD29718795EE19C9E8FD4378FA8A42BA6812DC51874CB0285420419D408E897A7F8FB9AD0238EC632674440B66E838FAFD731B50092324A9B11A545BB9A9D7A242D54C6BF897A080AC0B06B57535E542D254AC581450D82D73EF779865708A2563C86E4CB3133CC5FC2E16DD2B043449A73E59A5C6A29A227A469CE406192BA4825E3503F3552F743BC3DCB945048A95C70209BF5C5EFC76227EC7D947A19DFA0AF12B078BC588C1CF9C1300961C59CA8529C357B9087B572A8BD2739A7A526F3D874E6E2A23C4242BDC652569C7ED3546E3E85B7865611C2CB7AD551142B2503E14C0FB8220755036F6BF95DE3F1440598076DB3410A4AC1E52C91F038956731622DF255646CA02FE7CF1AAC75D972A5D744512B4B498C666CA68660B984BBE6A1833E83CAAFB80E17EA49C484AE2B6475D2E276E0C9317C47090DC9BC134B606A6A1336A40881D76EBFA954DC550CAC192082E1AA81F9A6D9162B038A021E09B28BD0B959884ACC836A4A95100FC93071DC474E593A1D7CA409001B6C40C3FB13A5B6640A32DA0B6DB086F1691614D935C29B67D8D54732948DFA27296A63607C17973B764B9C05713BF0026BC0534B9187FE33690826A6C80014B2F97312D53B3B22AA1740B0A47CA8807145EAE577C994B1DFEB19109B5B99019329FB6ADAE267C2759FDAE64CF479462C4185CA67255971AACE8351A94501D772B15890042363B3BB64B6373E44C5BF6AE2CAED5DFC3E0F0DCA2015579E6C6366833E834E34F198AB5A3504CFA0C6AF6AB78DE3A3EF5667E6065E084CF5D2A5BB3256DDB63A495D1AFA553A815CF751D711478A39E8D1AACA992796B619C84565CD", + "ek" : "7FD78E512C849CCAFA4918999973A73C7905131A2A81F16D6C340191FB2062F08411CADF8CFDEF900B32D741396BC05EDCAE4E421775ECA64AB633F879D48FD87AC49340A612D64F63795B5F3C1DF244AF2ED52482A0559FEA25EF1E5E3984CF5E4994DAC41276E84F7820811E8128BAD04801639D42D7CD183B4BC2ADE5F8444E650D3383E16069E3FBB17F60F6D38F2CD12442DBCB49EE7C30B3BE52D85F3755457AD1C17C42FC82872965FF80D9819C0027AF379BA9FDD3C7579956C8C404EEEE03B476BB234713F129C0D9F6DB28B30236115B64A74F9C1D37C249D428D11BF11A2CFDE8D0450AA531A047B16DC8C24FC25ACF7FA7CF8F45B7544D12099883CCD91D61F785DB60395EDD138CD087381678CBF5732FDA3A5CDB000292037EA725DDADF5F1548A71ECC4922A874E264E1381776A04523A8CEBD379C9D417BD5B933F9D4A275A8EFFACCCFE7AF5C831604902FCC208D0FA5C2397C2DEA5A9E67C626957FDCCDB8771A876A35FE464CD08F325723321A7004F89F4C62E089DB9217F425138EA52F6137B9EA8209478599EE24B5ED344D2FDC6E60AF758EBF984C194E30EBF9275B00AC616F9741F0C673F347A9AFF9CAD9A0199C01CD95991F226B3DB2ABDC8DC3F0D07A9AD6D5C1FFE89AD5951AABBFBBA9E3EB95C290D51FF3A2A8B0B9DC3C01D3142237CD31B4911A81780A9D97025E7AFAF95EF10E324C006BC613CD66F159ABD53497AC510A473AD1DF50A353F6BD12AFEBEDE1D82E365BAB0F5002D48B970380E4D32D4C0E036A58D6D83FDED60EF04654356F89B4856531891FB35E9BABF79C160429F6DB8C7550AAC277A03A9F55EF9A89DF0BE14CECFB6BF91D8CD4E971A845CCDFEE742A3D8A24A30F0DB25CA976DA4AB7231F9BE42852229562937F09703FBD2BFB315F03B26EB626F81F3CA7E3CB9C94BC39707BAB224054F181AEEDD98076A5811FC245C5509CE31744DEA7684C7E380C4367E6F9B83104AD2266365BB7E2E38DEE7527FD0BB4844820AA9AC0C0D9F3561E8CC007398CECF7490431CED987D9B6424E675D1FA0557FACDA5720D42F9ED3EC84DF3A62201D79C55CC47FCCB6A9A22C5A144809BDE6A75C1CBBA29E6FC2E3CA95497AE2C8EB41ECEC8B3FCE8CE4E262B6CB0E7875E372B25A67981FE46882D4D431A83EC23041CB815AF1EE1DBBECF6A20121702C089BBA946546D4E585B6DC9BFE68A0DD0F9F482A4835AA3EA746D3D83CA871FE3E493929A930D8A0BF5B566C83E0D588E499CF765AE127118CF25225B660ECDFD495F4F45D16130C47383AB70B0D79EFCFA87E3E3E3F70B3E8F3CFC8BB5BD3D132B153DDDE90449959D02FA9861E1F5314C238F5463DC5E07BD73772BEA3411561202DA9355E86298C21F9F7E6762533E1F568E30C537F21785B8FB2522C3411C71EC0596E7B8DF31C697557D629CE5E7B8A25D84E38CEDD5C3469BC99FAC71EEA0995F6C6591B031B8BA04884A5CC133A070D707FF472E6B8E6F499CDCFC27EE8FC9E9DF4B42711A54C2BE22", + "k" : "F699E74CB16627D3515684353A327E582F6795E25194BD01A8B447F589AA42A6", +}, +{ + "rngSeed" : "BB4C0082CA4044B1FF60B036C9B0E0495D58667156786C530BC69D949A13BFAFF53798E456423D7A0E162A60039367D7", + "pk" : "4860867E75349BA9999FE4BE93262A08F868ABB10652B51BD1C67C266156EDA768E30B0C82F910EB96062177A882435C74353DDA7279F2141D23A6440B900A8A476C66993477B999E23B40EDE83B1E31781B4303E4BC5E0220CB0A6409C88AA8238B83D78792C5632751FB0D5246CA42FC89CE31A64069560BB87360BC2696E78062600F24DB78AB630079A64C87900D4B7C9EF9201822B6BDBC69C6BE718C3B2792EA32756E1A465325A763DBA22861A423E65458272E77400375AAB4DBF30D564A176613C264631D33F37CEA0346E71649D1314862BB0D2B05711CF1AF088A4C619048A7242D0BE6A8B536C41A9368B22288ECD0AC7298335E5C91DB419C2126A8DF45B2E6D8793DA63FC7E94D75D3BCA2AA58F5B5BEE0B43A462A12C34B93F68952B6E7ABD89C97C293B0693192A44C0D4E69245E14983E87AA26DA8C63517F58D66AE1610936E6A89DCA87B6C70C1A78C66743B89B3C2EB854067AD97D74771F77B0906A9A7E78640DE75A7B8273851DC55DECE9B1941CCA76CB2DAC265E487585780928DFE7402710B6BD914D564568D3D4075E4141749990C40214EA51B71F855DEB9349DAE2108843B5CD9815F1E8458C020FADC1C65796B117F8B9851776E896891DC05AA0095A914457016172A17624A608CD49DB55A42BCEA68778A26A910EB566A2D942DA58A4CEA53EA7A67954B085EAF642405B1674309B68CB9BC3C04D67505D861A605BD6163F7CB49FB8CDCD40917BD59B94892459FA7EA64A4872F51B97E66E64F02818520164E20D5F952A3266840B4575FDB7625D07D00486BD433447D5E1ABFA65B215E034ACA74670D4B7FF61C36AC2A1628A20D79B352D1C82C1626233BA527967302131BC1CA837D9EB4238404A20A515FE98A9E6D9B34EC28F0B252263FC2BFFABA508A6375ABA51B4A36AF23740D2D51705B2A1083B23BF5A6B75A214DFCBA5EABB82FAF49E4D326D369CAB0F74C00BD54310A3620D570EEE533A1A89A51A418A3CD14B25244F0C66C8E8E454E358364FAB5997170A90A25F3816AA1B272B09E54435AB3096E8161926299ACCCAE3D689EAFCC7E220CC42F5A347173EC4C2510DA02C3B4526D75C9B01D103B8914E41B03865E16BE770A0E642251DC312CD10AECC6A9734CCC815DA2BEF09CD18C3A8AD6C0F90574F41075CEF470039A62891ECAAB5F033FCD4266A510589F7423B4992F488C3CBC450DB074FDCC7CFB4A51C08E2359247C1F564CC94383892757A8164C8C985C28E288ADFFA9C866A6779FAA0F0882ABF650A4B9C5E0FB36E4E51A6442167AA97C8E25BA55A3B5D7F164F07B2917F57B16B751AC08167AE88CEFA14668E7634D05865D1EA24D1013E1B270C9EE9164D18654646BBAE973745E64F90E69064F38FE5744A6343CA04B1A05293C5DEA9CEADCAB0B1F07CA177CAFFF03D582B123BEC8CD829AAE8D7CBA9F91D4C89CF9E9B52038638F54721F23C6B341419EBA880368782D1A0990F57211BF31012148D74451AE1E79850B75D6EFA172744CC6D77A46DD0272924BCCEF49053198B87E1AC122A0753950586D14C6B22BC12939F0661638B5191E6DC2FFAA147DAC984CD004D6DCB637BB18B2F04C115F98CADFA79F64E6253CAB64110A71D94DB5762F8CB4D277E03B2435A473D60B193ED2646F4", + "sk" : "30251DB04B83A5B5969CD3354A375CA3003289D59F5197A01E2B103162BD63C0CE71E9C5B0259AB5D7BA48FC72FD3C90A5132D3B0B36DC9C411FA10BD5B45168AA6C562405D478487545B0C4034F0761897DB4CD2DC13DEC0253ACB3051F71B170A731CF1C0E5F17CAB24B64CC7682A2D4313BD23CAB0849B20BB094E4570910AE5C58989A99880107CA4E617E66020043874EB861A0F72B50A924B8A4BB021504CF299B08B610BC14B0BA6226B162290C3BF6559DB1CE5694BC9C75A8F4E3290900AE68E4A29A543DFCBC8E10E90472675381E0376AA408C858491BE00FA782049766097A787337A616E04CC0FD8A57612CA816073C47C97D93C6A134DB23B84198A0F196DD8C6EC88BBB5D08634C378B678455B005795518CD66AC170090207C84BFCE5A89FE0CC1D16A3A60C810FDD780654277940A6E86E75B563B794649A29F0201D7A79930BB1A2B6177002560B5A06CA2D84DD8B45615923BD58543E53221C244AE917459149C13D15139AFDC0CA0828ED5C32B2327A8BBF71E86A4071A579D6CD180A1F5248D3A148C318271A378921061041C186FAAAB73CC3465CC603B90138E125D909427F0C6C13C7B1AF731BD7FC9C2EAA601880174B82A28A1D29DB0BB708FF06C255BC17BD427275C2C12128C1253207808CF9EDC6D3B106CD016821814B9EC498ADAEC702AD8BD24B894CB21B94DE3175E2335B1E22B88C01FEF553C42108F531C265F85BF7D0597D4C9B11465C6D8DCCBB0B4B06259AF20885458F58924B91EDB64778D970A20A64F5F2C16A1736C1A81B350A14DC6F4CE1CC569BC8C197C897F4652C59CC7C9A106A2A4D8B826E057149167F2A30988504212B33322B4988E3987DC514968D4027F16C0440CBC1B4B48C18C974F8B20B6E5605D650C2C9B7E594665BA42AB96A4CD287A76E1E05F64C542E4753B2B8A7AC2EB52BD637EF9D50B4F077CEA215859BABBB2EC105FF5B5C37C0F5ED41B1E71A22F59922DBA1D9E004A93DC69215669F530A04E45A878F14DF4885BE6D2AB820890C35C63061CC2F2582F575C364BF490E9365F6666A5247C950D7AADBE9BC3EE7638FDB981E574C9CF5960CB1C9FD504B6CC347C6A30BD6803CF99E003AA588CABA4969B4329010C3FF6762A9EF273E6170AD64B4DCD9488C4E152D3D78AA5D91258E991E1228273372F5A4A01CB815AC2B69EF370838F28C50D82867761556F04C5D5D21ABDE15784DC486DAB0D593069BC2401BE13A7945821E2A18DE2C331B9A8304613A181AC5A5ED121E0739994FA9B060C1411B261771A1321B62A614972A502A58B712C594B16AE82955817781DC858D645B354BB37E9835DE8029B5ED9C430F7103857B25B888FA4BB7E36B30AA3A93D18B158A6365D598546EB025C7D7AA722B0494781C9D29121E071AB4AB73F86EB1D8AAC4D5E66375D868AC6A6060F36B2A80730B541895E32C8B68882D945AE32D115E70A7E61F1C9C6945B9EAC226EA551781A1BD48208A9E36D12915B69D04C278897EC79C7891A4BD44530D78B63C92640A0E07576322825998166817689799E070B2FCC7780ACC596C42786FBEBC5356185B008589F7363D863CC934446DD12420E6C5291A66EB2D2964860867E75349BA9999FE4BE93262A08F868ABB10652B51BD1C67C266156EDA768E30B0C82F910EB96062177A882435C74353DDA7279F2141D23A6440B900A8A476C66993477B999E23B40EDE83B1E31781B4303E4BC5E0220CB0A6409C88AA8238B83D78792C5632751FB0D5246CA42FC89CE31A64069560BB87360BC2696E78062600F24DB78AB630079A64C87900D4B7C9EF9201822B6BDBC69C6BE718C3B2792EA32756E1A465325A763DBA22861A423E65458272E77400375AAB4DBF30D564A176613C264631D33F37CEA0346E71649D1314862BB0D2B05711CF1AF088A4C619048A7242D0BE6A8B536C41A9368B22288ECD0AC7298335E5C91DB419C2126A8DF45B2E6D8793DA63FC7E94D75D3BCA2AA58F5B5BEE0B43A462A12C34B93F68952B6E7ABD89C97C293B0693192A44C0D4E69245E14983E87AA26DA8C63517F58D66AE1610936E6A89DCA87B6C70C1A78C66743B89B3C2EB854067AD97D74771F77B0906A9A7E78640DE75A7B8273851DC55DECE9B1941CCA76CB2DAC265E487585780928DFE7402710B6BD914D564568D3D4075E4141749990C40214EA51B71F855DEB9349DAE2108843B5CD9815F1E8458C020FADC1C65796B117F8B9851776E896891DC05AA0095A914457016172A17624A608CD49DB55A42BCEA68778A26A910EB566A2D942DA58A4CEA53EA7A67954B085EAF642405B1674309B68CB9BC3C04D67505D861A605BD6163F7CB49FB8CDCD40917BD59B94892459FA7EA64A4872F51B97E66E64F02818520164E20D5F952A3266840B4575FDB7625D07D00486BD433447D5E1ABFA65B215E034ACA74670D4B7FF61C36AC2A1628A20D79B352D1C82C1626233BA527967302131BC1CA837D9EB4238404A20A515FE98A9E6D9B34EC28F0B252263FC2BFFABA508A6375ABA51B4A36AF23740D2D51705B2A1083B23BF5A6B75A214DFCBA5EABB82FAF49E4D326D369CAB0F74C00BD54310A3620D570EEE533A1A89A51A418A3CD14B25244F0C66C8E8E454E358364FAB5997170A90A25F3816AA1B272B09E54435AB3096E8161926299ACCCAE3D689EAFCC7E220CC42F5A347173EC4C2510DA02C3B4526D75C9B01D103B8914E41B03865E16BE770A0E642251DC312CD10AECC6A9734CCC815DA2BEF09CD18C3A8AD6C0F90574F41075CEF470039A62891ECAAB5F033FCD4266A510589F7423B4992F488C3CBC450DB074FDCC7CFB4A51C08E2359247C1F564CC94383892757A8164C8C985C28E288ADFFA9C866A6779FAA0F0882ABF650A4B9C5E0FB36E4E51A6442167AA97C8E25BA55A3B5D7F164F07B2917F57B16B751AC08167AE88CEFA14668E7634D05865D1EA24D1013E1B270C9EE9164D18654646BBAE973745E64F90E69064F38FE5744A6343CA04B1A05293C5DEA9CEADCAB0B1F07CA177CAFFF03D582B123BEC8CD829AAE8D7CBA9F91D4C89CF9E9B52038638F54721F23C6B341419EBA880368782D1A0990F57211BF31012148D74451AE1E79850B75D6EFA172744CC6D77A46DD0272924BCCEF49053198B87E1AC122A0753950586D14C6B22BC12939F0661638B5191E6DC2FFAA147DAC984CD004D6DCB637BB18B2F04C115F98CADFA79F64E6253CAB64110A71D94DB5762F8CB4D277E03B2435A473D60B193ED2646F4C5E157FF4357D3C26B7C4B45315F0689F135C85D952A64648B0A8CEC03741FE0D3698490455837FE52948613EE5FC2284F00B130C72334B1D8E68C7B09B2DE2E", + "ek" : "DFDAF103B9BE1502A5567AD69FE51B964AEF1A4D35302837CB8EFED79A4BF7AC7192CCC6AAB234CD055C0C98D529BA27BE19E924B1150C3E74AE46530306E3523B862954688B4CCA5DB4D05B2FEEA94AF8E184664C2D5DA4FB0C43D4DDA56085C0FC8310BE5D55C692FBFA1F59655DFAA6C602678F97BF85987130C0695B076ED0B7B5CE9D4C391C422BF0F6074036C47831F677AB78E63666019D1E6BCB5218DD6FC2005BB138D151D7AE3D5462715FC4D552D30258AF3D53148CB11F2A292371A054AA0B4925424FB5DFEF98E5152B5BB5DFBA5B50B1995158C0AD624529781CFE3881216FA128BB6874059E37E9B7B58B0A3B66D46B942C2CD27FCAD3E41E0798C636525F8E5FA6A8FCD8BBCBD1D58C9921A890CE66C976D813204B860D3989EBC4FC8EADBAE54B666EE5F92642F2C9BCCFDCD882CE07C3C20D4530F4702F7C9DEB0AD6366C50D4584CF6832093D19187549366E80B359A662DAD08709FD0968962CAB7F8EE852060A1EB29A5B4F8A45AB5F3A6BD56C98F35D4A5AE0FCDB5F88186D6A505D3D544121CFB063AFD102CF54BA4CC442143632F08D4018DEC1991B7BBF2AC709E7D2DAC5903CEBEA34E82B95A08860A829708DB81DF00CCF51287A987CB20EC96F3243F37CFE2B1F76A365485027B470D2C1689A016762F8DB9779B31476784E544F6AA5FE6793E637FA98E96069D887898DF0095B904817469764B87F565148B1D38D89EA8F9767F175F595AC3B0D6AC885DFC8396A06D148359AFE19E230CDF129B29DA9273A4C5BA71FDE99CF93F96ED1B9C9247E57111494A9507E347D170E1AA4D8E81009243CBC787D52E9D68AB4306288883D3BCE9D2FF707ADD47957DA80CC5921096791EFB42AED824AE73F97C38D00F98DCEDE10D22FBCF98E7EC797332F132556E3DD0F691B98BEAD50284B2ECD0ED1C678CE3FEBB8D26DF0682BA7318C783C0FA18113814F49071B4486A7884470C257509B8D2EC25C23CDD18A8E0A4CC5DB32C6E5BBB3A59B8476DF078AB02291D23341DF4FF7FCBB299817CE58D143DA54B0329058918262ACD1C69F4D78CEEBDC890E05C07A8B4C890C3DF162E615AF24E28C2BAEAD47B73D9608434390976307EDC51DEABD9551C05C51BFD3185550DB73DB0CBAEFF0F414665AFB4B4CAB9F6E2415C48106861C4DADEDBAC35F856A614810DD3C14C08E5C084DFD815E3EA7F64FBA4CB1881178C912E1D4121F52A4B763CEF1D33D6942A9814552B7D47C559A2795A70856BC97DF27C7F67195F646CD18CCE908FC3E39BFB2D0AA44C1ED2B94AB8BFD9F5062418B32194A2DAB9FF2D8B00F3AB206FFCE08CF1249CEA058DB66CF54DA83A8D60E7C5934659874683B5D5D35460C4C5B9F3EE8DCD3ECC804D43C78235873B419E753D23BC4A41998B6AB76A213CF490AC474540169271D5589111CE2261756A91F47D6725C87EA07B00B7D9BD11664D173CFFF93A7F3E52FA94A5DE32681716CA6CA1898281BD3A0174458B896CF7FC0FEFDC4DF6CD4FCD1D6332153B29E2", + "k" : "CBDCA4350EFD81BDAF39E1F84B3B6303521ADB62CAF13AE006013DE292D8277A", +}, +{ + "rngSeed" : "121D90E70AF6204445D0DEB28AC0C108262719E9FD3476ACA74BBFDE89FAF04D8D5F89A624E8A75DB80431F0D10AD28F", + "pk" : "345881AB11467FE9883654870F7266D76755B0A368661001E627587BA42A2FFC1E2C90B154BB61C2CC3D82A3588D4004D112534F787858D23E8A182971229BB2BC77809A1B118137FB91BB09D2B39DC77773E291FBE2CFE8FA2CD4882379F9471A190F34018C5819AC4EABA7A4A24C703C8876F321267B3EAA58A90CB0271208C6631A773021B3960C14605B5E24B01C2E3C9B2196499DFA69D6A76F0551907CC79611BCBCA6B1500D50854F719761A59E8BFAC4D5B27A54791482AC5426F73B906631E784C3BE822599BBA514540EFE6A7C13440AE97844A6C73CEB51C471F8014FE51FA94B271BF3206F56ABFEC55ED7002C27A9250FBC12C9F328EA63B3A2375ECD35634BBBA0A4A0619D4571EBC7868FAAB83C6180DC3C129E8596EDE2B64762CA7670282DAA233620445BD64A44F5C395A212A088165FD16FC69C503A33B8689217EC00A738F74210D074DC3706E9A412B7982A3E0804458560ACE39B54C114F8DCBEB9A1512EEA2D8636BDB91C15653926B0FCAB1978A02EF694086C062F097C32C9445606050E454A5EC2A43D5CB2704049EABBA1933AB857ACC1527C254B35CBF6FB4E267B567CA2A125B1552D1C83F408B12420B0B10C2E0AA430F695AF478C9D1C54406BF400170A84C4C52E9657C1B4EB652938B4A281A809851A5F62CCF930A56B5588F6FC64B6FABC62B6A62795B3372637BD641BC55C76DF070288678012247D11B09118C43FBA2536F5DAAB402377791C906E4CBDD5291EC81A1E71A3A696C0165AA1ADFB978BE46A8FA5CC7C8EE30036C085888BAC3797A1F189CC4035658CCAADC61432141B67BC09CE04685DAE806C681729E71B62DCC56449101401D967157C093A8A2B442C3AF483408791769BF7CE8910CA4F4724FFC93647375E702BACB559C11FB18B1D4A5371FA4BCC603C22254CDF2654B2873CF9E03591F4173E6A4CF86AA30E9480D49215AB503B2CF6BF42C4B314C7595C907BD4526569B3122234B9E27259619B520412B43B892A6770CC32C6C276A391A106959560687C9620D8D1A60A093F9982A46BB9365D611A86D064F3F82D81BA5C3A39578EA4583B8882EFDB5E0B3517BE2AB82863C68DB0336F6A1B9E1777D7139BEBD15AF3B73E21332D471100A8A8CDC9D926D2D7C23BAB39E015C65A072E0409609C0C0607BA94FDBA9842146E8524CC6DDBAA3DC3C9153C667D2B4F4A4871ED642FB284C573B1735B24B9F14AA72F316D3E8B1D8BB415E28A895A7A55E5043EEBB04DAD9A1D7D2CA9C1973BBC485400B8BC3E897D9D977BE1D6CD7D93607A123E43B56B55189586703BBB505185F167D9E24D1C1248A4BC4A98B9332666AFAEA93AAB55B09CC95E8691872C48B3594A1930D82917823362DC6E5CA19094526C462B52D8C842183B214F710908369E9E1599C8E43EA7D890A7E5A8CAA6953D774A2E6A1EFB1529411228D3637F1B28437C0773A719CC85681CFF772EF05B3BBE5753FA2AA5E414BDB599384FB6462565BB04DA4C84E550B20163928C9673427B5D57864CD0BA25065246D3914338CC9BE47B2DDB2D18888FF99A087D0012B789CC3D6C0C2D93567F7A4C87F1382C4C5EA6D084E524B82EAB586AD8C8B05C9AF5971A56A31F2B73AB45392BF60B762C5543DC3A259DD67FCCEC3ED3654C6559", + "sk" : "9C6B1557D747FBAB1DA3D8BC22301B37E5A5850C9E482850601C129A909DA97A9090840EFC118A287B19ED091E4F39B7657853502B4322B687A28532F6620BDCA934361B1A5DBB0E9AF71CAF65280E6ABA338AB888CC80CDE458720BA6146C39A22BC2C8F9CB0078A54031614D60CC9C91C319E3241FDB73A78C4B5715B0CF9620E0449C8C67493A987659C19E8E9B6E2ED12EE5DC876DE75589CC6D4294B40A0463D0A4899DD54A60CCBAF545166D693CE6BA3E073C63757AC06A9AA2E5E93385B9723EB339155C1E3A043779B193AF883B91F78DA091358C2C2DD7DB9086598546C6886D1BC611C3B586A3304A473FFF62371AF33142B1A212236E63351903A652261093EE44209C72BCD1DB9CEFD7866B15B6C434C654048CA845AB31C65E93D00288C6563E35080522415E42A9D5D749F308C36C860FDBE004F6C38BBF15CFE728A2806C10AF833972A6558FC204F052CFBED8B1F8649951E44949720364F752B4910616E57603342953E47F0046AF76867C98FA0ECDE6680B14BC14EA34569AB583C86C8F3B1AF9F5BA2EC68935729F0E03844976A8C5B965F56660E60B2B93D838D3697B86D6CF3E8AA0BD6865DAC093966A0793030BE6A03BC9E472354471B367A27ED30E129A336DF19114CBA8AB99571299128B323721703BD11649FC371AEB1867C5079FE04B169501CEE5B2A54F14884C5AC1B42588C5BA090382320AC8233BCC442BA2BCF9EC34446A716BF34F1C183A8829B22216855107BF6E9218D26010E63A72316CC5DD8994C4817880D4144A26A0967A25D0A82546098C6C55BA8078C0BED3BB91B5B2CB10C95B464852D7973DFBCA7F6396DEE46984F220431CBC969B0482453FF729CE625A3498AB299239465FA79B2D50C0CFF698D2E4CFF7B3182B88ACC0785C69B406A3DC9504840A2A744DFCC29A99458F74B3CCDB753EF2E83065111C41052C539C83D1AC049D215EA5291110287E80977E3F578FC6DCBA985327DEA382C3BB9561444F64232137624E32703CC4CC12C63BA5D3AB496B7B493C1000858B8DD51368F1458D255AC57D829928DC2A0707660DF753AA9C1B868703BF69013CD15F17A38496E51D63AACEC4F594CFF35DD027764A56B2751080D3D76B91DA373636CBA86395B992A7CE972C5E1101ED43176F5A5BA68801D0763762B92E499110648697389B98C5586BF69356B4623647CB0D1366B0804166299C4DD1BA0F29BBBB5DD393C40CC03967919CC32C62D6BDF9138E6B45184D445AE94825AE092DF33CAEFB2B737E9A23F58126A6C52780E48F5FF7A14A7B255C9A474C752D9DE424CCD4A8A05C79164779B8B452F3245926E2538F7299186259678298749412E96B444370BC583AC4A4D43DC7E1329D9630A7B3A79B0CC673789EE0D8026C93C17097CB83D515CECBA69B13783FE1BF72338846C955B7B1AF27128F0C1A2DFD0018DEF1C24FB16C29D326129213D831728ACC4CF339CBB6D2A7DDC8B0EED4CEC8850750BBB740CA89180B224721648F44A8CCCBBA6C2538006BC38FA34A04053DBA971F165C5003D70BF9C0B7F7578D03093A3D496A0E9242B0C23A92788B668B1ABE421080770078F97118E7C35DD589CE1AC805D953345881AB11467FE9883654870F7266D76755B0A368661001E627587BA42A2FFC1E2C90B154BB61C2CC3D82A3588D4004D112534F787858D23E8A182971229BB2BC77809A1B118137FB91BB09D2B39DC77773E291FBE2CFE8FA2CD4882379F9471A190F34018C5819AC4EABA7A4A24C703C8876F321267B3EAA58A90CB0271208C6631A773021B3960C14605B5E24B01C2E3C9B2196499DFA69D6A76F0551907CC79611BCBCA6B1500D50854F719761A59E8BFAC4D5B27A54791482AC5426F73B906631E784C3BE822599BBA514540EFE6A7C13440AE97844A6C73CEB51C471F8014FE51FA94B271BF3206F56ABFEC55ED7002C27A9250FBC12C9F328EA63B3A2375ECD35634BBBA0A4A0619D4571EBC7868FAAB83C6180DC3C129E8596EDE2B64762CA7670282DAA233620445BD64A44F5C395A212A088165FD16FC69C503A33B8689217EC00A738F74210D074DC3706E9A412B7982A3E0804458560ACE39B54C114F8DCBEB9A1512EEA2D8636BDB91C15653926B0FCAB1978A02EF694086C062F097C32C9445606050E454A5EC2A43D5CB2704049EABBA1933AB857ACC1527C254B35CBF6FB4E267B567CA2A125B1552D1C83F408B12420B0B10C2E0AA430F695AF478C9D1C54406BF400170A84C4C52E9657C1B4EB652938B4A281A809851A5F62CCF930A56B5588F6FC64B6FABC62B6A62795B3372637BD641BC55C76DF070288678012247D11B09118C43FBA2536F5DAAB402377791C906E4CBDD5291EC81A1E71A3A696C0165AA1ADFB978BE46A8FA5CC7C8EE30036C085888BAC3797A1F189CC4035658CCAADC61432141B67BC09CE04685DAE806C681729E71B62DCC56449101401D967157C093A8A2B442C3AF483408791769BF7CE8910CA4F4724FFC93647375E702BACB559C11FB18B1D4A5371FA4BCC603C22254CDF2654B2873CF9E03591F4173E6A4CF86AA30E9480D49215AB503B2CF6BF42C4B314C7595C907BD4526569B3122234B9E27259619B520412B43B892A6770CC32C6C276A391A106959560687C9620D8D1A60A093F9982A46BB9365D611A86D064F3F82D81BA5C3A39578EA4583B8882EFDB5E0B3517BE2AB82863C68DB0336F6A1B9E1777D7139BEBD15AF3B73E21332D471100A8A8CDC9D926D2D7C23BAB39E015C65A072E0409609C0C0607BA94FDBA9842146E8524CC6DDBAA3DC3C9153C667D2B4F4A4871ED642FB284C573B1735B24B9F14AA72F316D3E8B1D8BB415E28A895A7A55E5043EEBB04DAD9A1D7D2CA9C1973BBC485400B8BC3E897D9D977BE1D6CD7D93607A123E43B56B55189586703BBB505185F167D9E24D1C1248A4BC4A98B9332666AFAEA93AAB55B09CC95E8691872C48B3594A1930D82917823362DC6E5CA19094526C462B52D8C842183B214F710908369E9E1599C8E43EA7D890A7E5A8CAA6953D774A2E6A1EFB1529411228D3637F1B28437C0773A719CC85681CFF772EF05B3BBE5753FA2AA5E414BDB599384FB6462565BB04DA4C84E550B20163928C9673427B5D57864CD0BA25065246D3914338CC9BE47B2DDB2D18888FF99A087D0012B789CC3D6C0C2D93567F7A4C87F1382C4C5EA6D084E524B82EAB586AD8C8B05C9AF5971A56A31F2B73AB45392BF60B762C5543DC3A259DD67FCCEC3ED3654C6559F5CEDD022077B1A6A052F5287219393CD2E0366D0F5531B2F7EA8704D2900CE5229EF54E776C02586F3F46D723E7932215FB7E09C397D1552CDFE3457241FC30", + "ek" : "D17CB5249AF23F9D4D0696EB9267FA66AB5A94A5FAA47F30E7B295233FE837160D307A1319597535CF233F5E22402D9CCEA96E56C697F0B4DCA64786DCFDEB88DFFE16C26A2ABC1FF48251D6918F25B42EAFCABDEDDC0F4F8903D84629E6FE44179EA3038BF19E3236C41741841545994CE3104639AD7516F6E0193DB1F47C566634CB326EDBB826BA08DB925D41A2871AC8CDE81D86A7D7DBA2444D259B3D60A96AA4C9B18A1F07A9BFF13E16AE70408DD781C62148F461C8C3990880FC44F7297EE902C7FE1E07891291530784B6006F85100CFCCAC56A7FEF89A579FBAF69D305C0DCCBED7E70E4019FDAD2C985ED22BD58B10D981237F032BFCE6D4FC6FEABA518988AD75D18304A2E2EEA66CB777CA5F007FFF7887AE217294F44334F92EBE8255B4068248EEE06177370A284355AC931E6F4BAFB403F519B4C56A443C3AA11EA6A2F1CB2C1C129D9961576A8AACF8D78685B530BC5CB453EDF1C5814DEAF95CD394E84FF3AA59C0E5EBC568D3E69547D731174B23EFB8743759F18387C05564472F67965154ACA6BB07404FEF65FC24B247BD834C762466DCFC71D65FEB7BC40A20BD3CCF1BF337E7BA6F344065C7FDB5FC008BE883CD7B1C1C959F429E2624BF7A1223C0C42E9ECE0653D39735C0697B059D02C7BB5373CEBCD5DFA0288B9F1C91725CFDBEC43AF3981D86187A0701BA36E6426C349617DCFCF9786574DF6B0FCBC973FD8514E53DCB169E13B503CA3FB91D4C148B7CD1EE9373809EEB44132E680D52FD4861AE0FCE63DF272F9DC830CF0B605F2EC9ACFBAA316877A147C1024640AE18E236B7F239811E684C0861CA1432B7376F3883CE0B9A48D7E2FF1C46802B6F36CEA97B09A3175FDF5466670F4DFBAA33207C33BA5F29DEE882E4C1E5D53E103D243E066BA99193EDBD15FB2A00012162DB4371E113510C8736ED8BDB6FFEC390F88187B89586822B23D8D26AB6D6AFC874AB0AE4FA01B5D93916EE65E55F3368D9B397F9268DE83B452F6BCC68604989BA4B47B1FA99612CCE5D12A02BDCFBBE52231144ED2F37E4A3FB07791905CCF8F99537DB0CD935F26049AB6A29B4C406E2D19FD6F79FFFA31470847DD7B160479A49407597971C6792ED89540B5427E2A2B8127582280EFC15EB815E1054CFEBEBDA40CEECDFC90ED9E2D44A8E423424709345FB695E05DAD90545FD022848D6854B30531CAD3FE276CB3914D06795CD08420292235178D8F84E2FEBFF21BF6D30D20EF882E5D5015602417C9F70A5FF91E9B3DF227B1B81919DC7535C98A8685BCBDAB37895AADF5CC57E4E0500F3EA24AF85369D4C9F85F0818ED5C744C4B5ED8CEE9D8115A23AEE58C03CC6A114D2D6CFBAFBD85227B37248D9ED6D81545309F6582CE620DAFA54F9DFECE717C8D06293F6F84290536A78CBBE1BECC874C58E9FA5DD2C8B0773C6C549E5D555F9749BA245E5E66F7AD802A188B66DCCCE2D8DDC1BF893F49305AC9EE5BB5AA45E3ECFB8CD2E4C4F904046782038D04650FDEA4E37D432B5DB735", + "k" : "43F7BE158DDF7E91D1D65FEFA671C766CFFAE2008052C72A546C346D7AAA3E6F", +}, +{ + "rngSeed" : "B3AC6503206ACCC2A92CBC210D020A2654726911D11CE676AA04FEAA08AF1D20C654E4105883AE470EC3AB299075D420", + "pk" : "2695ADFCF444770C6FFAB16E9211ABF5D019E1471B843A3E7A38B5CE109A0A6796A0D822A926756F0C4A0FA03F53200D6CF37A1CB741F10219102B63425063D6A910B2FC574C49067A1A40E22CCB754926481B7F0AD0111943B3E67A570F0BC269AA50DE26CB5F3507791B757370517D486D7A55A88CE86B42856705F6A7A48A8892E96FF20C304E74271E0B555C1B4B0D065A50D61BB2813CC3723009179DD2B4C37A0A06B2099C2AA0C4D256A2FE2042BF4B3DB91B11028275B33B4484F2CCB9971DF29703DD61C17DBC0319AC63D16080F5B5C460149EF751933AB60142404B66690A2C10A6E3AAA186F6C7E130577CB02EF4E043A6D4AB22BA85B5396A4D61AA1528BECC59A1843A4D70283CD2F91457762EF34424B934BE9A1547DBFBBCDE21552F968C2C8692475632E78AB3D7330619E74D8C71BF3797844C717E70B51367963A7CD3C4869A85DDD213A8D34B788239056544692A7741124697D237D7E2677A908358D81DA2CBACEFDC511D3110E1152BF2D036C4593A0512523F80A26620AB1CD8B6B1D99A08F25AE3121713AC070833C544E42ACFBB78D86476743923D7310C5A4238CCE27773D3989D598AFFE6650C1166AD4BA0E034CCBBB5A75D69B113F2A1952A2CC6980C58CA6DA32718E4484D562AC700D924545B6CEF439234980611C99E69706054981349041E1962B272C4B0B8B416569952E4F98D4BB12DE6A13BC1C903C5477B0FFAA1C0DCBD8E4ABD4670832EBA3D43D9C31147AA803C17BB32C65E3C350520297DA9CDD6DCA30CA025E85A051AF5AA82D231C159A5026A0E8F2C16769105BAF7708FAB822B1777C6C53137BA11298CCC15D522400B7F85430DE739514C90453BA97D9359807568417EA307ABB8982707B7519A65B116466E984772F87A6346AC808C7B2CD22F08ABA151E79AD8E45925D29294879A9DC00F60713E33091C42BC3AB24B65B488C764EC75B4117DDE39ADA784835D3129CBD7B777B1B69CC3293F07ADE724639B761CA598464E6676E216874C9668B19ABA660974C9918D52761ACFA325031835B4D44B42FB91E431373781A2F60354E837458E69A89D830E00801178BA697F82A3A914345ECC1B5CB4B3357B6B7D41B708C5A7E4F862C44C8FFA90473495B70607386C02B4F0261E197124DE180CC793355135BDF37CB36B9A180DACC2F6B09EFD80CF35211A0371C59F396CD9EC226E1126D69A6AB8441FAAE9A1CBD18E17387CA0333F94ACC7E35306A8B05F4DD185FC467E5E888159A50C6C9A51CA6B2DEB9BA212822020D67552D4317449B51B21C37348C44E3880367574D5C195DB588AD0189A80756EDA780DDA9A7D3C946B10D897AB8BB40D6441179B1B0D58271EA83000C5AD56175A23D20322D516B2A487C74A64EB3514C93B919D65CEDF429BD37515FFF66F4D72CEE39A0081452F791B8054660DA44937C4A443A09727CA5198322C341C12413C19B6075BB9118540BDC105313422CF9B8FA687540AF66728FA9859A642BB9479B31257912CB5E0046DC9273199F27F4F3665AEE6A7BDD19E0AB8BAF1D2A868B465AEF75F3CEB916C82BD81791E80158F8E5B358C218305D96A683A19C930C1903B5E0A4B15CCD8AD0B9E61DA304AD616AF46073A781ED8D08060C1678F48941D67B3685A39EE7491", + "sk" : "29013C0DB356ADC444062A6955267CBB8132D72A58BB1B34ECB955795BA52F1624694741FE3C646E734C2462547A72553C51559C2C88830B1CD43089E924080807B4DAA964BB85CD5CBC56EDEA257EC59B9C808BB66835FEE1ADA8FAB7DB67268DDB23454680D3A7245BE4917A1ABEEFD809D7906C1B8A4DFAD2160313AB7C69CBA472BEF251C7E1E1CE8771C1C30B7DB129B8A8140AAE05780664CE800600DBC8BA42E1B4AE629424735B57529F35F9ABACA9054AE346C9928A3FF7884485195D02369D046DD68A7129197CC91C3A911C0CC361C9B8FC44C0AC8D98C8A18B185B9E174BDCA360F589343F9509121B7B3C8046F4D8086D471B5F1B3E20C6296936A2E78583640590D52AAFB321A23215546309676DC84C445AB78BB5660137A50C97AA05B7B004E396619B632E855D80C6CDE8973C055C65B7A06A90421E8CE484495820D9A66F878A19E8E1BBBBF86437545A5DDC4326E400C384CE96C4698F628F9703BE9AA7181A361739F7701700C47EAB9F1B805D86450094C76445413FD57B20D9794AAC17B1EF33186A345351C851657A9EE61463F0E912DFD8AE113A378BB51BDF5B918B6344FD74C573430259B2B18F37CE9AF0BCBE3807A0D94626DAC6A22C4E31F3BAE1EAB69F768DD4A68405290566E20ED156B5AC5A73B1C08E64E68DF973B9DC8692BBCB17692C496817BB1F0465CDDC6AD25903BCEA873FFBC9D8472487A92C8CE7148C25288D9687532035B81B584494524F796F99904C0BFA402FE265BB7AA143A0329F4A199692472F25B2B59A3A845654A88B9356526C25A740F39C3476020B99A601B41831CD832E3053A90B5CB4DE61142F65B2A2BABD9A45618036AF6BA54C9A2B093CFB5BD7426056E09E6771AF41D607CB9375846A4952ECC3A991225DB49B31753F0839967AC9319B6C5D23A6365970A3FC4497CDF793196B6C9AD5280B949C825599B5D312B2F484939B960CAA2696D26789F09B4D2CCF211CB3BC580ACC4B0126380A6DA109EF86385640667196A2C135A3FDD780D34513C0D35F78836D0F811945B7B617C024BA5AAC93438397F216A4520213C036FDC81957630236323A56C72562236BE7F127653269C2A6248357B134973CA90A100618279B1306907A9076F05E46A716CF79882707C942DAC8200BAF3A454D8E74258682313CE3252FD7A602A3114BDC50E33B29F18ACEA7180226532288AB678D4C6DC60A58366A61D6B124E247A39B24BA960B39A2DA80637C9CF5838CBC5A5B7C1B7FC7E16777C9CDD1460C9EB32F1DA32CAD0C2437E3AA59F0020A106B06113F5E896730962D1EFACB72084DF7475EAB9CB467ECC1F41177B644C9A68A961EA65D2323628E558D6B03ABB2F5491C7C36244A3BA56191EFF6AE71496DA7372C5E1500E22A7796B2AFF8856D75D3278B5117FBC42C71743BF7F24C78B76E3EA45EE2487A8F2899F2127D687B1F8DC579C2EA811D3C50D60C85F6E66457D88F91A63AB1EBC98A0B2167262700D35201975091B9BA30120C6EECA45992376A200D161A234BE0C93B68661DA9CF44A01071A8614DAC8906D39EB475312B0C2E998CA7AB67BC77387E5B6CC8AEC14D7EA894809C54E10649325881A89B132695ADFCF444770C6FFAB16E9211ABF5D019E1471B843A3E7A38B5CE109A0A6796A0D822A926756F0C4A0FA03F53200D6CF37A1CB741F10219102B63425063D6A910B2FC574C49067A1A40E22CCB754926481B7F0AD0111943B3E67A570F0BC269AA50DE26CB5F3507791B757370517D486D7A55A88CE86B42856705F6A7A48A8892E96FF20C304E74271E0B555C1B4B0D065A50D61BB2813CC3723009179DD2B4C37A0A06B2099C2AA0C4D256A2FE2042BF4B3DB91B11028275B33B4484F2CCB9971DF29703DD61C17DBC0319AC63D16080F5B5C460149EF751933AB60142404B66690A2C10A6E3AAA186F6C7E130577CB02EF4E043A6D4AB22BA85B5396A4D61AA1528BECC59A1843A4D70283CD2F91457762EF34424B934BE9A1547DBFBBCDE21552F968C2C8692475632E78AB3D7330619E74D8C71BF3797844C717E70B51367963A7CD3C4869A85DDD213A8D34B788239056544692A7741124697D237D7E2677A908358D81DA2CBACEFDC511D3110E1152BF2D036C4593A0512523F80A26620AB1CD8B6B1D99A08F25AE3121713AC070833C544E42ACFBB78D86476743923D7310C5A4238CCE27773D3989D598AFFE6650C1166AD4BA0E034CCBBB5A75D69B113F2A1952A2CC6980C58CA6DA32718E4484D562AC700D924545B6CEF439234980611C99E69706054981349041E1962B272C4B0B8B416569952E4F98D4BB12DE6A13BC1C903C5477B0FFAA1C0DCBD8E4ABD4670832EBA3D43D9C31147AA803C17BB32C65E3C350520297DA9CDD6DCA30CA025E85A051AF5AA82D231C159A5026A0E8F2C16769105BAF7708FAB822B1777C6C53137BA11298CCC15D522400B7F85430DE739514C90453BA97D9359807568417EA307ABB8982707B7519A65B116466E984772F87A6346AC808C7B2CD22F08ABA151E79AD8E45925D29294879A9DC00F60713E33091C42BC3AB24B65B488C764EC75B4117DDE39ADA784835D3129CBD7B777B1B69CC3293F07ADE724639B761CA598464E6676E216874C9668B19ABA660974C9918D52761ACFA325031835B4D44B42FB91E431373781A2F60354E837458E69A89D830E00801178BA697F82A3A914345ECC1B5CB4B3357B6B7D41B708C5A7E4F862C44C8FFA90473495B70607386C02B4F0261E197124DE180CC793355135BDF37CB36B9A180DACC2F6B09EFD80CF35211A0371C59F396CD9EC226E1126D69A6AB8441FAAE9A1CBD18E17387CA0333F94ACC7E35306A8B05F4DD185FC467E5E888159A50C6C9A51CA6B2DEB9BA212822020D67552D4317449B51B21C37348C44E3880367574D5C195DB588AD0189A80756EDA780DDA9A7D3C946B10D897AB8BB40D6441179B1B0D58271EA83000C5AD56175A23D20322D516B2A487C74A64EB3514C93B919D65CEDF429BD37515FFF66F4D72CEE39A0081452F791B8054660DA44937C4A443A09727CA5198322C341C12413C19B6075BB9118540BDC105313422CF9B8FA687540AF66728FA9859A642BB9479B31257912CB5E0046DC9273199F27F4F3665AEE6A7BDD19E0AB8BAF1D2A868B465AEF75F3CEB916C82BD81791E80158F8E5B358C218305D96A683A19C930C1903B5E0A4B15CCD8AD0B9E61DA304AD616AF46073A781ED8D08060C1678F48941D67B3685A39EE7491A53A20EA03E400A843C8CF4D04BFE0C0A3CE63DDE01045E2669F7AE5DA79057766BBD48DEEA2A0A14BCAA97E18D848E609339DC39BCECCE7077F2D7432DA536E", + "ek" : "112A70DD80C6CE4FC3B290110E3E113B882706318FCEF127B4E56B090DDB2307448A81EEB2B147634CE6853AD6140DF304D47B9DB09F15484EAB7A59F7ACDFAB1DEBAF74458AF2F7C9ABA1FEF3F30E05A5E760385BC08F75DE378C81A682E29A1C87277A2CA843E592E302274767EC650FE6AD27ABE2072367EF21E01046836DA11FF73A580C14898585A16C6CEF89A1AF38F66F6447632CFD01DBE364BFEBE475F0FD784D0429EB503331FB05B30D6FA76121031ED3D73C9978BE3C32F4070A558CB11CE22E398ED65CFAD319882A035EE38B3B78B7D6CCABD6EC62BC11B8F8BE0DA5372BB54A6E9AB8F922DE0DC872EC4FF82201E534400C1F635C4A240D08DBD4CBFBEF47B66CF20803230283EA3174545C9FD3034F9A1F08109479F40586277EEBBC4CD831A1C9968D727B238B5637CDAEEED539B12F5123002A425B92BFF08BE194114DD2CFDD26A067F9DE81218C372356261088894A01BD1498EE56A06009A71B4632EB90B7399FD0144B31AD7F01AF1430B9B8E26AB9FCED85C80DE9A914C163E71C2A473770EBFAE7D7FA75481DCEF1AB4131CD1390EBD850967AEA58B3518787AF9D9B69D4BC3D7BF0B66FD0E1DBB050500C6A85EC90253B76796BEE0CB879864D69EED6D5FCA701599B8D4460C0575513671D0DF9AF71D26BDACCB76C391688E50B217F858D52B9D5AC1D86C3E172F00B7A2CEA141DA8B50DF26472D6A539062646FE8BFB51CDA8791A9C74779B8CB0353316960F00CA6D5593AE5D588837C4E05038341E78D914F5982CAEB7DC714A76918AA9D6A9A26AF88D39011DD7A27102CE0209FAAB008A3BCACB8A258A2A0F6D1AFB95A80DB34C7DCB99DAEC8D037C20C588B046FFEC80A6E86E3239B9F0034BEFF7A690A71CCF5A67BFA139A318F1BBE5568103B1A9A90BF16C8D00921E6D8FFBB3946DC548764869391E8BE12F02AFE11288DA5EB9119B9BB120BC98D80CF929131B3EA3D24006F0AA75743B77D4CE9EAF511885B1F4626A5B707E16A5901EEEBE524DA3E822A71BC642A6354B2A32B2356700C469F37F426095E1E8918220016756CB7DB36562120735514DCA2B4016AF8C4AD9DB6D655CF1FDC24CFC9857058C850147D372397C2148FA0F240778CD5A57411E7880F126B6A8C712297B52482FBFB262B51346A9513F1E835DB43BBE9053BA575A48C17885E624ADF945145CFCB6D31DDCCECBEC2529826013E643472D3104F20783B993C71BF2B194A5F6F724AFA0F35952BEBC7339FF2915B0C1F76332E6D3A92448C25B4DB332DBC682A7136AD6929513113E6CDC088038F622380B3FFD3919DFA12306E4EB20D31498B6F3D34032FEF6FF5958B61C6779A690F1DBCA3956780F272870EB96FAD425E88E43C1F4F82EBB2F7FF07F6AD870321371D48991467A976EB6ADB1788E414B3C554BD6A3F8F28C772EE29050B918E12F2A03F53970E48528435022BBF929C4729671AF00E7101EEAB800B71DE989A9F9301FC82D38B5FD8BD882A9CACA34C98914C1167B3174D51FBDA8", + "k" : "80A4CEF5BA0DDCCEBD5B13A0ED5DBDA0ED64684551DD1952296BAADA2EA8FA1D", +}, +{ + "rngSeed" : "59EFF60B1EF6185DB34EE1E3B1DD2F159106CECEAA79BEB74923B4F5623D5BC52DBF5D2594A1F7C6C64D12CF144E9ED4", + "pk" : "09ABAA56083952C0C1B6EC9A50251F3C16859C2C91C0076750016AD3EC36C42941AF9C13E4086B37F5373CD29EF4D46D6179C948EAC2738BCB765BBC58C8C0FC206A4E30267ED62537DC5202C5A717926744B296B2983B8291495161C920CC1258F209640549E5E7CBBE13BA52B762C6767C92A95678E066631B57E256880AE56189B699691999FA294B71135A7537202E8873D2653EACABBA9D3082A5F01353B77DA1CB4220301B84A14848B94D68309C6A29035E7CBF083BCE5E659C0A226274E8534F61021D1743BF66525AA7C62759C9EA85155E139A9CC20F6B0776D567A8F1E697B97CA60982555C0197BAE535A0D20EBD00A7774550E928647C40598D16A45DA0810399CF38865CEB5C2ED7623AE9F55987FA37CCE79AAE79030F8C3B90898F758366F7F591452C77EA7C3203C147E591304138568D2257D07689865447179C017B0560B3165673526981C65858E842D913A9C22C0A9AAC9FA4E16EA6B128B0BC99FF863B3F40B2819AB2E8A04CB353C7ECB2409E495E617A410E638BCB370B2C887B8ADAB2B9F95E8E922BAACB1D148610CC4748CBF31B88DA477029CA130B152DD923BD7796D0128AEC6706C204ADA1B37DC0149A7C318D8356A4F8C9CF917443FEF20B02096579580D82BB8659B18365BA3347B081F42B17C3E2064A441B1A3A876C26060D22C370F82424E9B156145E93894DE3CA09E4FA8BA6524EB9EA94980A038B257FB4DA57D4C8B40AE5465A3A9C7169CCD30B13295546846A6BDCF13C3230B5A961B1ECF578ABFA8BAC3542820053717BAAE30A545261B873F278CEFB73EDF8CB73B9272DD7552E381DA64C055470C199BAB07CDC3293C0577D9ACD9D9063B536412AC7CDEE30A1DCFB6E25DBCEDD5425508A1091555998931326FA69C78B5021F818F8A55DEEE77DB38229B4104980C230DBB872CD671FE776A09BE47852204C6A339126E3BAC2353D36C094506092AA597449241121332900A69F8BA1B79EC56F047CBBFBD6BB2AA08F6E606D54C72CBB758357E49B937590A1191D88BA26CA576ECD320CAA1BCBFF8533695AA486D222B5749BC8F4297BB7938D5B4CB4F46D6EE701A35A287DC16F7DC1347EE97830EC69CDAA91EE061D3F0C81BDC695CD6939AE56BE11681847629EA555747C664B5E111A9AC5159281438729916D45B8F0D3AD0E0514619CA93A8A971E9433C9EAA731192C760C5C5E32259F569DCDF39BBA4C1B7269BD98417ABFB1521FCBB640030563118E0F35BBFD0665023863E275C7D5319A1087BB2F956D2DD3ADE6C37AA09C36CD5AA9ED09B8999C4473665AE2B784197CC9268C57BFB78DFB054BD1278E044582CC3C81C547C50FE7BFC270BF6ABA9FC159A5853045AF3758A8D552C3881D7C2879DBBB0B79B5A5C2300B5A380ECD199E3309251F9647598B7376290452A575F4EA7071F2A0EBB7B3DD9057350ABBC1707E25D0B68D734689F0AC4C9B3242FB703EA6BB7FC064E599CE8F9269A0D63A719879AC8C396D79221BABB2C4A0B7D38AC5B7E984F2212C481A353BA6BD95039443658EEAB625D3D00FAFF2509A2C208AFBC6016BB5D8726DC74993AD329BB9A554BF61209CC20E521B628D9C89C8FA687EB7464AC51820225B65B2AF8489ED896D11825BC4DF67F7002453D16875CE21CCF49B", + "sk" : "BA593157E38D7E6735B6159AD0338A4F35CAD3B7AE7E79C024B4B913A313D95059E2AC7273692EE4D6217090C1774B4CA473B09214A81A374E5D5350B51C4F52376E3C7A1622CBAA2226965AFBCECF5B499FF7220D572DB7D7916989CDD4D2ACE6CC3A40949B02C52FCEEB941FF6B6D2713DE078753AA73836D72ABFA96DDF790F0B8243C48247ABE779DB1BCD5CE01BFA061FE1B5436AE7CD7B7A3A65971E35360AC52B9C5B7214478C46F5864948D20396387333D7615F872BB94B0E7D71B2F831A2D30870FEB190F42771F1F1B73ED88ADF6BB732A1C159147ACA38950060394CF04E7150308897B3B76706A17695943500E589B10B348BEC1335CCE863BF68BA50019C6D072E9A2AAEBEF070A7D65D5D2A8BC285B22DC91915008E2854A9B408A5E1F847FA492670EAB6905A6367528EFAF08A688CBC6FC86672E599C3D5ADE10A4A92942D5705A03E881EDA311CDA81982E6ABA55F29CFA835B6B19A7E0C39B48939344C1CAA5882A7AA86721CB5674A14E62CB613F115E0CC36792467A7DD5701543898CE06223FB505BA4503192747D4295FB57508446C927B1C8378A96B4A56243D257C89993447CC183DB3F6DB7B8606C21536C01EAF14A7F2931DA629365A0B1DF157BB60424312155A8E80D049B66E9E134006C64BEF8AD0B5A33FE857DE7D244B4CC2F0D29A8D50C118540772ECA4517712B4ACA18F64C758E6698F701804CF0821C178D6D7BA43C2C694E8B4A8A356A8C26894DE30658917BBC6331A6E77E6A327AAC4BA2B19B02A79484EBF90CC2A235A8737802F7B71E6731F358156232A913B63BA94B932581162B622699659F66C984155187FFE53D8D6A3EE4D84E3B190088E001B3F3ACA703A39551BEE2A852AA4656F355B05B28194DC025EBCA70EF90A47E96049F441082861BA5E563080B27035AAA0AC761C66B6B11978C18D1431D25CE69A6373D869D8ECC72B47550DD901AED51915E61ACD36C50CDA5CE545B7B3293263AE13880879BF96B7C6915074D46C636F4522F340B993CAFD07C91FD646893DCA37EDA658DBBB52A3211A4E09DC20240A3F8C606A7B095715E5AF180167B5807E3B414F69EC28874398B464E08254A60CD9B693B36643D82996AE2C82B8D26BACF106879091500B6A289C4C1A0A7B9C872865498BB2A40455E0BA3B6570A804204AFD3942EE6B4169B8842508B9F6A5C1883A3EC98BD8119B147671003472CE1905981326B5057A6AD026843D323CC0593A132114D70CD030AA979D639BF22BCB286C13902CFDEB0BEEC163F8AB3C377D211B6D502CCC41137DB92CDACA20CE5B83C2BAA93D5C063DB6D419537A7597D03A91F9D214869CA00AE46CAB450CE11591CFF53610053C3DACC5901A43959E55CC2751F792AC5ED288402782DFA4912989032295B967E4145D7046E76F4079338BC26D4C9F88203EE1412683899DDC534AC37608A6959EFC72D7E24582FC9629A20059FB382E5891C85091DE6C2600C98C58EA8205D2574C25C9C0D17809EF40D1DB44E8EA895C40C8AA2448A6655442F0BB7A160AA8DF8BA5FAAAEE0C19D16DC4D267279C0BBA589972948F7C198E8CEC71569E9863F968CB5DF387C6A350A81F32AD9797C09ABAA56083952C0C1B6EC9A50251F3C16859C2C91C0076750016AD3EC36C42941AF9C13E4086B37F5373CD29EF4D46D6179C948EAC2738BCB765BBC58C8C0FC206A4E30267ED62537DC5202C5A717926744B296B2983B8291495161C920CC1258F209640549E5E7CBBE13BA52B762C6767C92A95678E066631B57E256880AE56189B699691999FA294B71135A7537202E8873D2653EACABBA9D3082A5F01353B77DA1CB4220301B84A14848B94D68309C6A29035E7CBF083BCE5E659C0A226274E8534F61021D1743BF66525AA7C62759C9EA85155E139A9CC20F6B0776D567A8F1E697B97CA60982555C0197BAE535A0D20EBD00A7774550E928647C40598D16A45DA0810399CF38865CEB5C2ED7623AE9F55987FA37CCE79AAE79030F8C3B90898F758366F7F591452C77EA7C3203C147E591304138568D2257D07689865447179C017B0560B3165673526981C65858E842D913A9C22C0A9AAC9FA4E16EA6B128B0BC99FF863B3F40B2819AB2E8A04CB353C7ECB2409E495E617A410E638BCB370B2C887B8ADAB2B9F95E8E922BAACB1D148610CC4748CBF31B88DA477029CA130B152DD923BD7796D0128AEC6706C204ADA1B37DC0149A7C318D8356A4F8C9CF917443FEF20B02096579580D82BB8659B18365BA3347B081F42B17C3E2064A441B1A3A876C26060D22C370F82424E9B156145E93894DE3CA09E4FA8BA6524EB9EA94980A038B257FB4DA57D4C8B40AE5465A3A9C7169CCD30B13295546846A6BDCF13C3230B5A961B1ECF578ABFA8BAC3542820053717BAAE30A545261B873F278CEFB73EDF8CB73B9272DD7552E381DA64C055470C199BAB07CDC3293C0577D9ACD9D9063B536412AC7CDEE30A1DCFB6E25DBCEDD5425508A1091555998931326FA69C78B5021F818F8A55DEEE77DB38229B4104980C230DBB872CD671FE776A09BE47852204C6A339126E3BAC2353D36C094506092AA597449241121332900A69F8BA1B79EC56F047CBBFBD6BB2AA08F6E606D54C72CBB758357E49B937590A1191D88BA26CA576ECD320CAA1BCBFF8533695AA486D222B5749BC8F4297BB7938D5B4CB4F46D6EE701A35A287DC16F7DC1347EE97830EC69CDAA91EE061D3F0C81BDC695CD6939AE56BE11681847629EA555747C664B5E111A9AC5159281438729916D45B8F0D3AD0E0514619CA93A8A971E9433C9EAA731192C760C5C5E32259F569DCDF39BBA4C1B7269BD98417ABFB1521FCBB640030563118E0F35BBFD0665023863E275C7D5319A1087BB2F956D2DD3ADE6C37AA09C36CD5AA9ED09B8999C4473665AE2B784197CC9268C57BFB78DFB054BD1278E044582CC3C81C547C50FE7BFC270BF6ABA9FC159A5853045AF3758A8D552C3881D7C2879DBBB0B79B5A5C2300B5A380ECD199E3309251F9647598B7376290452A575F4EA7071F2A0EBB7B3DD9057350ABBC1707E25D0B68D734689F0AC4C9B3242FB703EA6BB7FC064E599CE8F9269A0D63A719879AC8C396D79221BABB2C4A0B7D38AC5B7E984F2212C481A353BA6BD95039443658EEAB625D3D00FAFF2509A2C208AFBC6016BB5D8726DC74993AD329BB9A554BF61209CC20E521B628D9C89C8FA687EB7464AC51820225B65B2AF8489ED896D11825BC4DF67F7002453D16875CE21CCF49BCACCA228846450EBB8F04A2A5EF2D919DFA47C4AA265F4CEDD10CF74EEF3ECC13E3A1BCD39C74C1B899FFA21A6FE100804A551199D32DB4A75E6314BFB58F70E", + "ek" : "C7A8AB42859DAEDD8F99E7277C68F7B1560E1A63AF0FF74752BE0727FEABA1EDCA0AEC33B943FB9A6FE76A514FA101B7216F84C4535943CE2F056DCF56CC58B7C5740BAC17CD27B225D9CC8A98F5FD00E011F20187922EC63315E68CDC53D1782774BAEA73C46F340B7125C365005CFB7375D5EC268B346A08750F1D39F9B2F7BCF3E801F2269EE152613FBD02219C072188339B477C36BD8686D6FF4F6D006FF00CAE572B08B872774382B490BE32B0D3720DC9970F03013DD3AD45934B5B35974D45030EBBD23E88920D9A06E5B65334DCCCCEA4840191AFEB73234C81FA1A9E31578AE459EC6ADD78BE0EC30CE5CA8786BB9BFF2AA5C54738326462E0710474647B461FDE1AD8F18992CB09E834A8ED2A310DF6FA688CE009A8C2B9DC8A1211900EED8E1F9C390EA6006AD528E638E45405DBF7B750EF70C7BD3B285D05E2476C810174FC56D800DA3969197E959F364A9E4837274AD10015CACC351C16FFDD9961787F18F61DD2BD6F2DB505D6422FAFC191C4642A43CEC9E32EFFEBCCFBE31FD6C19DFA4E870B1DE880A0963BAAE8D0449D002AEDAA834D66E39CAC95C8CFEA46558C1471CEEEE2549156669E9DCBE6F806848BFEAD2E5AE17A84752D28D82688FA77F4238B40D3E55F8DA514B95EAFC6EB6D589AEE057F04C3E34262E1FA7CF0CFF63032C5FA43E850655ED512D6365163E57832BD9A3F02298372D10103DCBA881B698807DCF581A0FCA752E42D8D4005CF3566C11622BC4F011DF597F5DF39872B2892EEF80341F3D569DCF2B099822071EA540FEA314119471CA01D9BB78563E0252C1F85FC9FB98031E7CED2167B98B3AF87F44BB31D70BCCA78E758AF8DEF5D9D96C4FCD9B801FB29202631B9CE874BF203103DBCE580248C1135CA2CA0D8E73AE7307512CF01BBD3914EA91C1C5A12C0096BF03DAB7B34F4DE53C24BA68BF7B02E743AF6B5B87A9C2A65F82DA78D33E637D2ABE526698A87B6543907E45B8E89DDA882E1AA455DC5A3296079A437844A5AEFE79C6860267CC7B4818F1DEF73374EAA29FB4EA2DA53C3E2581E913B3FBD4E2D924317E469F8F56AAACA800981A55A49F8EC02827977D270C0B6D34C121EF9D0CCB9EC0293E8A1C2EAA408DCBF7C92A60467A173A67934B535C57446B868D05A551A9C0707F812BB7D40031B3D6BE55B82B27A203F8E59D3562416E2003C68F2608DBAEB94506BDF35051F977487850D1D15EC13D6A068C3EF158C9F203809D5D22649D83D94120C2603338F26E13521C7E365ECBE73A26E5578F4CEC9CF6657D02888BCA0F471BA24E19ABCCD10CA6D6E1B802180C062E9D9DB8E1C2EF288BD9570D238BDC7F08C328BADBE9FFB06E01B05C19BEE0BDBABED0D210D7B628EBDF6E9EE422237545728DA1D1608506B2D5E062B1C1CFF7C6B6DE05479CA1FA398D33C5995497F220A4900153C78A161EE02846E22465EF3AA052BE5F01B67E0CFDF319B5348512933C191D6C6FCC0245548E5C12CD7C436F461B9171539945B9CE0638759B028FF4F", + "k" : "C5D1DEB1F47BE9C37FB6124E91946040B4E0705C3C01A34DC2D71E3EFE786814", +}, +{ + "rngSeed" : "DDDCA9DC31BEA737D3F474E7560B37FACB2F53C803E768FFAADE7669FF94B1D4FBD17068CFFD5DFDD24AADADA4EF6B12", + "pk" : "9734408C884E736A271A17A9A5829A56E4AD6FD90402C18327F4B5B052A5D72585AD276A52228EA0794D4AE19235304674705176F76E909792B32B3F45F3C179464DAA653C4885346B0921F72A2E186210542575E7ABCC210BB7572C5BA97C475D8BA2810C54B9F23988725DD17967E9764513E1A34E55A9E32B05BD6A030425250A285FB331351BA4470EB2380318C9C7A56ED0664C6A16AF63DB6DC2A7C1C4E5A901C89FF7A589C099568C9BBB0482B04205595C242C66D99725A17468684B2BE16B2757760B72A57974549C44C17BD2AA028A2C2D74B458C2BAC3D34537BA095C34459B58AAE4940FB3B68A73B28ACA34CB018B92F65320BC3C04008394E17215ABEB505B4BCD37D473DA43569D557EB34B06EECA22C1264DB881A6B37BBE9467899117B602304FDB72AAA60BBDBA128214CC87FB980C1BE3BCF9348BDA62CCFA591328901C9B9851E9F9258E2A5F500053F9266891FC1DDF267C58C1AA7DB72255F8C277D8535FE48DB1D9B12CD97FDE35C837D12F6B1C84E2C019E77469350BCB9C3791AF132BF2EBC633F3C681E3801D0BA00A30672E955D84930C4012100C18B7A5A342D226341924034AC0953CE15584911D86C0689FD12D3DC4CB2D8748EEC4ABECC185FF63162E414E709CC3C5163DE7B80E9E550D4A0B90DE20B2FCA850E3B11338BC3B5C369D616A2B64C764F78122ABDB66860103371B773586463EA51366792872F36C53603CD876C4AEA446E8811FEB4417E3F21B94059F1D3C47584C09B128C549E48F6346CC3FA60AD19CB9B65359F04506CF52994FF5225AA24D68A00BC5171E0A492733E726EFF02C2B956F9D6A6E7A8519E2B9C4C90B8DB6B5447A0B589CB71CF0B74B899272A966C0B0DA3824035C70C334818BCDFA2632E7A47AE8119661B96A6B4B17810A8840CC05BB3A0DB2C6A60D10CB3E7CA365576250A380FA4B956CE066E72A0D7739A4B4E317988B64270732FF94C319A368CF0B8D8018A2D210BB37C695032A3B4DA71E25E2287EF34ED68B5711CA99AF1CC6B83CABA7EB91D1F10EFF920D9B41091E086487CC438E461344905B7E954121948AB8251FB0044E6CD8075F28B70A67132C8362B71B77298C2200E11B3013B6B2EC8B21E7A23A3CB9456567B3A090FBE642A1693501DB47F8C4829D86BB1AE7ACCDD7763FC0B5E754CA5999A1544615DBB1ACDA7749C1D89073B130A4823600E322904C9599C31B67C963C307987FABC4E482910B57A56E2417EAF978008C9FA38103C15AB1A811B2B198A5B7201EF767A26A758400469CE0B1CA83920FBCBBC51C8697CC4B687D8BA41D45725551A09E5CB230532760CC15292C4CA9CC77F6E215D70C8F6E98B35FB21C5E0993588C8F76775F92C575C013270C167CDDFC76DE12261E84C1B506737A7448D00A6D07456FABB620D985607A32526D276846CC739276122BC14CAE94543E11276805AEDF36C404FC079117196383CEF2681074F954249B859498A8EDE375663755890613B15C2A8FF25ADE0ABC4D674A050369A596AC3E446CFC3171600367F89C9251E33DB95C508E09A64F683FE7420C5FF73EBE5836EBEC9E0EF1A39C02ACD90275F5D9AF9EAB8C741023BC91806D255282846CB5FBCEF030EE8E721D0566C29F469F5773938D679DBE17BFD7DE66BE5E", + "sk" : "632B0098B51F1DC64AB2B096E5BA16867CAA3F5621B10C50008939ADC17177533CB98244B0BC287309A67BA147C572ADAE003472437389D957F1D048F4B7C0E8D88469A6A87B771A7BD0A3FD1074F1B29080008FA72C9241E1B7622748D65BC6DD307645419A65FC5BA5D68E66C5AD250897B72C109541422019275B4CABB57A675EB3144BE222F417AA85250C773B0689063E89802D6BB4010F4BA0CB57A1C69A5869E5A5508599744321F23496A6A9B8331786FFD2CA9B83B78469089885ACC3F46B9F45437CEACF1A9707C394919801BB44F3ABCC5A504F466890B15E902B9B97B8197AA19F25A41E0DF87EB6B88C0C029ACA3534F807837CC2C253A06C375C8728390263A6CB8D240E33C36268D283FE891E8B99BB935A33D15C0C588C82BC2905DE885DAFDA4422E61B43BCC1B8731F1B6A85486988AE392D71AAC97D326CD6115E26C23459C74EBF4AC2EDC6209933A22E2162DA6CCA192271517687110C070D6A154A11054421BF8E3A9820F8A77794B3DA4931A333928FD37E7C057117FB2F2FE9A19D65907801248A8009D0DA2CBF572063AB7BEE490F2C930C8BA0709579B9FC11079D48845DE37A1AF371C6947B12AC4A142250C92C63B7336967CA1797BAC7B3A66E5A997672C4431C28A601CC1360689D1CB6304F8CC04F6C3E2F67A2A72746E5221B1D9A6018C4B6F0A6943AE927552968F7877F28CBBC9BCC410AFCC780E06D6759AEDF4A1B57D7CAD7FC89B7B29E03810BD7BABC8797768E930DFC3983AAEA0A910A359B5C87D088961D529896183627277E707AA88A21096658663CBB756469542E9053F1102A73644D510B69DA8B089C73CE4BF4BDC5B72FFCF4CD1C73CE0508393E409EAE79C9FBF44B5E36C73D33AF7FC9C084C52B3DA21A57171EEA865EFA7C917FE92B52B40E36FC5CD8E961FD207FD7167C7D302137C5841352663A3931E96382966C58C3039E182CB1E0369813BC90312A9AC6026D4F8C24DA0445B3687C27A8363D702AB0579BBD3A418FB6AF26792BF96281B0373469D96E74803A5658A413F19A43F95E784B91586C14461134811A0C976C25A7B8491514A1CCF83904489585B841884C0BA39046508728DD02A9A3163EC17CB1422C3BD8194F845259952C1BC7DA1616748C19E002AB8948BFB00F7B53446BD1138D7B87794423BED453E5A7BB0E915841984BAD6CC970F9C95F120855203DF5936A8871611EE897F9E050D5A3931C1219F61A8DA6D75BA0E85C0A674CC39C583AD01F794B628AE221D9E8AAAADA889C43B56602C73ED2CD5FA084C7B207A43360A8C58A3F405BBA290B39723B63B10951ECAD19DC266D045A49A38857941534F28E775269BAB9A381A60E244543B3E26FCBCC0D47575A82DA58ACA50239DA726E0570A8EB3F6714B2FFFB9038D42345977FB3156CA1EAAB577C0CF4516AEB81BD1F6B92276AC4CD37B67D1B6083E126CC32C91D28C531802E41F707AB740903E5213E2A378397A52793C0B8762D67D846DE86520F8745A8112C80F48835A4033BA53AE0E7B43AFC44994B13E76663D1E6A2519844AE08536AA055A428AF5144BE296B43AADA192D142EC933546735A6ACCB4A5A99852CA751C24CAE5738A99734408C884E736A271A17A9A5829A56E4AD6FD90402C18327F4B5B052A5D72585AD276A52228EA0794D4AE19235304674705176F76E909792B32B3F45F3C179464DAA653C4885346B0921F72A2E186210542575E7ABCC210BB7572C5BA97C475D8BA2810C54B9F23988725DD17967E9764513E1A34E55A9E32B05BD6A030425250A285FB331351BA4470EB2380318C9C7A56ED0664C6A16AF63DB6DC2A7C1C4E5A901C89FF7A589C099568C9BBB0482B04205595C242C66D99725A17468684B2BE16B2757760B72A57974549C44C17BD2AA028A2C2D74B458C2BAC3D34537BA095C34459B58AAE4940FB3B68A73B28ACA34CB018B92F65320BC3C04008394E17215ABEB505B4BCD37D473DA43569D557EB34B06EECA22C1264DB881A6B37BBE9467899117B602304FDB72AAA60BBDBA128214CC87FB980C1BE3BCF9348BDA62CCFA591328901C9B9851E9F9258E2A5F500053F9266891FC1DDF267C58C1AA7DB72255F8C277D8535FE48DB1D9B12CD97FDE35C837D12F6B1C84E2C019E77469350BCB9C3791AF132BF2EBC633F3C681E3801D0BA00A30672E955D84930C4012100C18B7A5A342D226341924034AC0953CE15584911D86C0689FD12D3DC4CB2D8748EEC4ABECC185FF63162E414E709CC3C5163DE7B80E9E550D4A0B90DE20B2FCA850E3B11338BC3B5C369D616A2B64C764F78122ABDB66860103371B773586463EA51366792872F36C53603CD876C4AEA446E8811FEB4417E3F21B94059F1D3C47584C09B128C549E48F6346CC3FA60AD19CB9B65359F04506CF52994FF5225AA24D68A00BC5171E0A492733E726EFF02C2B956F9D6A6E7A8519E2B9C4C90B8DB6B5447A0B589CB71CF0B74B899272A966C0B0DA3824035C70C334818BCDFA2632E7A47AE8119661B96A6B4B17810A8840CC05BB3A0DB2C6A60D10CB3E7CA365576250A380FA4B956CE066E72A0D7739A4B4E317988B64270732FF94C319A368CF0B8D8018A2D210BB37C695032A3B4DA71E25E2287EF34ED68B5711CA99AF1CC6B83CABA7EB91D1F10EFF920D9B41091E086487CC438E461344905B7E954121948AB8251FB0044E6CD8075F28B70A67132C8362B71B77298C2200E11B3013B6B2EC8B21E7A23A3CB9456567B3A090FBE642A1693501DB47F8C4829D86BB1AE7ACCDD7763FC0B5E754CA5999A1544615DBB1ACDA7749C1D89073B130A4823600E322904C9599C31B67C963C307987FABC4E482910B57A56E2417EAF978008C9FA38103C15AB1A811B2B198A5B7201EF767A26A758400469CE0B1CA83920FBCBBC51C8697CC4B687D8BA41D45725551A09E5CB230532760CC15292C4CA9CC77F6E215D70C8F6E98B35FB21C5E0993588C8F76775F92C575C013270C167CDDFC76DE12261E84C1B506737A7448D00A6D07456FABB620D985607A32526D276846CC739276122BC14CAE94543E11276805AEDF36C404FC079117196383CEF2681074F954249B859498A8EDE375663755890613B15C2A8FF25ADE0ABC4D674A050369A596AC3E446CFC3171600367F89C9251E33DB95C508E09A64F683FE7420C5FF73EBE5836EBEC9E0EF1A39C02ACD90275F5D9AF9EAB8C741023BC91806D255282846CB5FBCEF030EE8E721D0566C29F469F5773938D679DBE17BFD7DE66BE5E4126F5151D1B086E26A88BD9F20710EF06AA0F834722B801F6B79C031F1F9213AFF7ECFE33EFE4042A44F2F801170616925BE8CCA1BD1812A7335DCD80F9CF14", + "ek" : "8E2ECF8342E820096E96FD700B4DF309F65BBFA9BE807A2E79B5F90CADE74F9ACD25F120892838CECAE0246EA2EE87055620D55C7B21FD0442966A50A6BF346A09B38F7744B971305989FB81531C8C7876BEAAFA67D9237ACF6E0E31B00F33753404A92AA086E8E85F8B4C3F79E5B4C4636890F3A6880739A6907223CC4FFE2141D42673CF7473BF0C6E1E2B214D8D3ABFDF75D5281003ADE47C3EAE2D77C24065B524918E765597E998CA17E0A4BDCBE6A19BC49B5540A679CC157862170F20869A1EA92DD32F1E6BE3B16D515834C4EE4BE98A2ED5B194E98B0720AB7FB1615D04EFCC9569664383CA371FCD68BF150396D9370D756B95F28A658DF1972B509ECBD46962FD6BA11FFA7C8C3CE521D3CD5E4E221E2CB0C75EE09857895B3934E0D25ECAC36238B2B4FE86B590090A20D27C1BABF1BAFF30D8248ADFA524B50DE3A1B9FBAB7C5507EDC90F305052546920841AEAD3F456D5B247C73761FB5BCF24FE09308002355739F6A14BCBB339B743452941D6186552E034EA78F1857C7C7A093C86DDA6CFC821A67868120F98122E52E06F3BE6F27319CA00C9F3CF47F85E0CA2767E234615EB2F571051930FFDF7B8927AB804E505B751263DC84089B83451BA969A99DE42DC84C484C418473B32D21B0140C1CDC2EF346F2DED96576126A4F7B45C11EA7373580605315626749F9C2F772E49AFA84A827DD395C1A529581901FB464ED2EAA46A81A5F920E372D52E0D95B4F6F7AE7775A5F98E29AD610DD178239781948114A8211835C7A832550004C761E1008148FF0F9AABB2C56777CE257266FCD5C3A57E652F1D75A3F879CDE6419F19494A6FBF90B143A92F0D120820A2FBC4AF91488694DD217C621A80E20CA2FF81F7BB8C40DA7D3D5AABAD47CE6991A071A9F0DD11425C81C50FD40B39FA4B2286D5B36C7418A3A024805FF6A48C82270D1B9BC132B3C2012A1A76733861762481C98792686CDE939CD8C77F7B701839856FA2A9C5A616B6CA77F46FE8B9347EBC598F4E420848C1433D25C5B4D5B14219CA745D19B674FE0D83C1224C82690EBC579F292208D1B4680FCA74A83726ED799AB93E99D35EBB9D9F8574BA2A25E802AFB725CB2BFD2442ECA85D4599D9BA4707426513FB4ADD04CA37083D36FE2E4F62D0DA6E1BFD6859E136680020C7A7E8F704FFBE0C21698B514F41DB1C9A59575851113904CD10D4FCE77A33AF859C7BEA4327F32F558DF45E883A15B31C4B029C777C506B13EF935A23418B1402A300A72E6845E723136E6DC869B6C3CF9274C0A32836D5D3D119E67F88C9DC0DBACC626D2D70C1E809EA9F89A09D020E97364A3349D87CC554C2F214D306112F822B4385AE7F96CE5629CC4134089BA03EA0DADB52CB6C31E363EA423A20F5DB5CF26E611F4284C3DD42EF90E2EEA413D1CEC905EAEA7D6F573547804E4D43904A35EDAEA76283F88BB401DFCE974510E25589A934E5E9C91E08C87A5629278BF0210B0A114760A6C2EEEC5591E4D675A75FD241F0B05A7317932997", + "k" : "F816976A5EC4A3AD1EA8902A32B86140EBCF1933EF44893CAAC87BA27174D307", +}, +{ + "rngSeed" : "2A6F7386B815366F572AEB6C79E272CC21B7095FE09575F18072C9D677DA23BC9C8A4BC393B7524604D299BEDD260C8B", + "pk" : "5FE1C21F16C49F6B02F2450F4AC135A9EAA5E24A3E3F350A6982B5979A93120285DAC88E01923060A795D251C1FEDB130828582C95CA7340B2E8E105CFD64F63E63F85A955DCC4B12B0482D0994DF7EC61B8B09AA4D1B8CEB94B769A2AE12031D16C05CADA3A4D0350E8D970CCF716953543A984CDB086C425915858D454880C97505BBB9AC7CFA54055526689033C8241300E11D09283441043B91354D1C0DCB4A869F225C8BA5B290A77629004BA336C8975366002667C99B88B53A4B08AB564733B5D2A3011F944B2259845DCB6AB8956836656E3370F5981203943B343389F2A98CDC96BC1A996648580B7FE837817AC4DB31A2D325A869950A32D99446256CB3D8B91C159683BC8C1FF41287CA54530E84082BBAFAD485C0F179781950A4722C9114485F6B403F3760678E3BBEFDA309ADC41CA562DBCB739654ABC6CB05216807E2FE18FBB485977380D8C0282E271C7F1F8C14694484B76241A1B0CF3928AD9E328357AB75FE909957419DEFC8E0DA3469E7720A5E91DF7C4857ED50B89D18FFAF6A045E2C950E178ADEC7A3D690FA23527D3D353D8731857018D7CC909D081CAB0370CFCC8BF8F5463A4FA8706A1ABDF2C6A7FE8C834A4CCD8B6C869C6BF93C808A43274620B30AFF22BBCE53A7FF85145779CBA220DABD1B597F4515C1664A374A64AE18884B0919668A70B371E24D2AC1A84AF7DE3B84F804E105177F6A9B914CB5DCE45C678C886B3B24E3649CB194C548FBA4114F278A56A4310A7CF1CB16E8ECC0B0FB8A2685B30631753B7F87EEC8578684A67634119FE8CB334B67B741305AEE8762639A212B9BAAB4032653B1537327EBA5B6FED245D17631E748532426C5A4F4646716521DCC72F4C34A38BC87A892650DEF1BF09991E4C175D0BAA1BF6469277F75A2812AACB88534C491F4D3C884A4470F01B805EFC160EC17F68B0B0EB9910889A02467232FDB268848A5D6969C91410775FE717C9103CFFB9A2BC13B1BBBA01ABB92AE303ABFEFC51AF169D25D29316E7A12A5BCA6827C25DF567EF0C20F13A6FD728A32E229F72B42E74470C88C105BEC0A12A1810C3D2A3D84B89A8C9BF66CC305F0B0C3FB989C3541DAF147D5B02813E7904CC18A5DBB6632AF4A34CD42007F09AB4A88C1705958058BBD6F996FE7642A0B45B690317D0E658EA82094D6B8D55722123FC1BD349433AD4850B19A4F6616685767E67BC21333A9F667A6C422087398B3331C075CEA9AEA6E29E424653D5E7A86766613732343341491726869EDA4F97F1982E62C4CF135B1553A0A842B35E8AC23F29A921039BF31833F12CA8C4F02021559E1AB5BC37D247A5078280F02956BA2E2F897B48E18A769908E6B8B15C63B5A780580D02B5F70749A5442C824A0F56CB00378BC0EA2B033FBC9D45D535ECC00F5579A687865702436D3065461A06C8B274561D938D92290A8C0BBC0CC746AEB253E4823F8BD7B6BECB5B1F8A5403FCB40EFA5F6C34C43620921A416AA769A6EA1CA15C765D0E53C70B0A719F7B47FF783B63701AF5A9CFE704C7D99830734C1B1FE00A1D9166B11060BAA09501715310B93EAD6825BA9998D922AE362092349AA45ABB04781A98B25989E8309C40698A2676B49FBDCA7775F554D2448358E6A4BF5373892B712B63AF3392FA95DEA1A8", + "sk" : "2FEAA7E47B8E973CA66CD8BE82E5983D295EEE270134086481A92E55D3A282CB4E702B234E3A49AE7B532F6183E0B57E4CF688121A5DA377AAFDD36F1180816ED91C28038776169EA0A11937E229F7B57447F4295F457BDD89191D6A89F6A7146B55A5CD16C743BC3F3F60BDAC4C1EE7727946157BF1929D6B7C15836C6B28445601497E07376426239AA3C0BC8135570D9623AD828F858A6EC5E4946F189864E87249EB574875409AA22967141380C633ECE33567DA5811B9A40759403BECC297AB63622BB9F0B5CBF52378BE037882AC9B25414817B4784101683B8696A6F9178323762BC419FE939AB0C8640422743B3A7E628382D36BC42AFC4DD206A160DAB1D1551B0E7A349E14B5B66077D6B85082306B1DD83AD0B16157E0C1B910A5D3FA562FF2C008804F6C1CAA8F18336082AC4F8ABCE7D4A1E680361140B69B80574658C6F6F0A4D27104DCF29C55C74500DB129E55114121764152C0EAFC1E88350816057197466B50DA92CC034996001A503040B7847FAFA5950E8ACDA9A3C3EAA6B7E475C806401BE2183100447D82284515A1A191D01EC7EA8EBA84701FEB15BD149AF2E66CB3844204E3BCA83976A088A291FB6C70425A09E42D292B1AFEB0C0AC94361B5673FFC25A4B5812D211B0AAD388FE1538A5929EDCABB11E317DE597B8DB653CDC552938925A2BE642FCB78BBC271584A8B27904C4FB6001304822CBA9B96B9B0A79901668236494D68A455129E9869693DAB64D4B13B7CA6FAD71942B955C1356735B0A27AA037B420300983155C96903BD4B1235C21E8273416660B5B977CE37B6B44BBB09BD197A97CCA98CB87A2FF1BC9C0A051ED98560B6B761055D84143F052A686BB3623DA02A208B184D1426683484A7594AA22CC705173024F35B8E24977D421606197E0C21C9D145C316B7CEDAA13202DC2CD4C62224E01EAF865F7B018A4A938920F848F436AE530A591A2617AA97143F8AB2005B9F9B734C82145C34567C59518A8CA13100EA8B4E3420D698450B70237765B62E433CDD2A842468BCDB42A639AA9644D89F4840351F3096F5C67CF17BAAD6CBA5C79C002AE25A55F224E3B577111B4647E0CB0CB12907554FB96B77A8F267593A3F506B1CF53B6A01136EDC0A684E2B8B4825066053C8C232B736C321F1708226FC3A131B1073867CC0872C53A85426CA1BC3756B329598072A352AB82FA8A61429A58EF21C2833D1BDE2C1A919C75AD52A4162ABBE2829B2FE93C7990AC7CFEC8EEA930FC5CB9CA13B2DA2E80DE600325D965982626F001371F59AABFF88C74E028C49D5AC3C766EFEA499E2375A330C91385831E990CD69D6CC8A415A4E563EAFA0319607B171B130AC842C66589DCAE283AF2B884BEB6B6EC84E48F037AFAB54FC2C6486A7A13C9C3396D3B6512A576CB87599AA7AEDC97275766D6A96AF28327DEDB27386923B98B647D5003D5EDC718B0477A5164000799CA30C08E8F8A9EE728CD0B0AEF4C16B1D61C751E32463E4B785223BEE6227E3F88FCB469CF250A64BC7A3149AB3EDAA730D6B4E6920B7B5C2BD55B97473B91C3C1C5923067C08DB693C97AE832427DC6439576749DF139E19D9580AB8C49EB15B80E09E6845335FE1C21F16C49F6B02F2450F4AC135A9EAA5E24A3E3F350A6982B5979A93120285DAC88E01923060A795D251C1FEDB130828582C95CA7340B2E8E105CFD64F63E63F85A955DCC4B12B0482D0994DF7EC61B8B09AA4D1B8CEB94B769A2AE12031D16C05CADA3A4D0350E8D970CCF716953543A984CDB086C425915858D454880C97505BBB9AC7CFA54055526689033C8241300E11D09283441043B91354D1C0DCB4A869F225C8BA5B290A77629004BA336C8975366002667C99B88B53A4B08AB564733B5D2A3011F944B2259845DCB6AB8956836656E3370F5981203943B343389F2A98CDC96BC1A996648580B7FE837817AC4DB31A2D325A869950A32D99446256CB3D8B91C159683BC8C1FF41287CA54530E84082BBAFAD485C0F179781950A4722C9114485F6B403F3760678E3BBEFDA309ADC41CA562DBCB739654ABC6CB05216807E2FE18FBB485977380D8C0282E271C7F1F8C14694484B76241A1B0CF3928AD9E328357AB75FE909957419DEFC8E0DA3469E7720A5E91DF7C4857ED50B89D18FFAF6A045E2C950E178ADEC7A3D690FA23527D3D353D8731857018D7CC909D081CAB0370CFCC8BF8F5463A4FA8706A1ABDF2C6A7FE8C834A4CCD8B6C869C6BF93C808A43274620B30AFF22BBCE53A7FF85145779CBA220DABD1B597F4515C1664A374A64AE18884B0919668A70B371E24D2AC1A84AF7DE3B84F804E105177F6A9B914CB5DCE45C678C886B3B24E3649CB194C548FBA4114F278A56A4310A7CF1CB16E8ECC0B0FB8A2685B30631753B7F87EEC8578684A67634119FE8CB334B67B741305AEE8762639A212B9BAAB4032653B1537327EBA5B6FED245D17631E748532426C5A4F4646716521DCC72F4C34A38BC87A892650DEF1BF09991E4C175D0BAA1BF6469277F75A2812AACB88534C491F4D3C884A4470F01B805EFC160EC17F68B0B0EB9910889A02467232FDB268848A5D6969C91410775FE717C9103CFFB9A2BC13B1BBBA01ABB92AE303ABFEFC51AF169D25D29316E7A12A5BCA6827C25DF567EF0C20F13A6FD728A32E229F72B42E74470C88C105BEC0A12A1810C3D2A3D84B89A8C9BF66CC305F0B0C3FB989C3541DAF147D5B02813E7904CC18A5DBB6632AF4A34CD42007F09AB4A88C1705958058BBD6F996FE7642A0B45B690317D0E658EA82094D6B8D55722123FC1BD349433AD4850B19A4F6616685767E67BC21333A9F667A6C422087398B3331C075CEA9AEA6E29E424653D5E7A86766613732343341491726869EDA4F97F1982E62C4CF135B1553A0A842B35E8AC23F29A921039BF31833F12CA8C4F02021559E1AB5BC37D247A5078280F02956BA2E2F897B48E18A769908E6B8B15C63B5A780580D02B5F70749A5442C824A0F56CB00378BC0EA2B033FBC9D45D535ECC00F5579A687865702436D3065461A06C8B274561D938D92290A8C0BBC0CC746AEB253E4823F8BD7B6BECB5B1F8A5403FCB40EFA5F6C34C43620921A416AA769A6EA1CA15C765D0E53C70B0A719F7B47FF783B63701AF5A9CFE704C7D99830734C1B1FE00A1D9166B11060BAA09501715310B93EAD6825BA9998D922AE362092349AA45ABB04781A98B25989E8309C40698A2676B49FBDCA7775F554D2448358E6A4BF5373892B712B63AF3392FA95DEA1A8B6F12914ED31F14F79C652EED4DB478DE7EBD263FE27052509FEE10B50F2D053D375BC4FB24E98F1EAA01E50A588E96A2B26DAF9421437313FC7E4B520387050", + "ek" : "177F41B9B64589C5D2EF66B90AB107EAD212E81CA8D535F1A557EEFA92EB0589AD013772B2887DA7E5D42E919F172A2E5C14ABD6F1BB91F24367979E1DD77F0E56485C17EA025C1A8F1B937E3CB24EF9BCFFC497A3FBE52B715A768596D8C2E719A63B4E4CDD54A618E3A0CE2C096122871D80A19F711378A8B4C49A0D546A2894FA15F258F7FC9ECD28B49D12CBBABDCBBD5A24F48819C759F129948CA37C7357AF8C347C74D3F3F4810AD64540AAEED14D91B56F103E73CC554CA04366A3AF19E32106B37F11999927A2697E4066EF5055D7ED89B216C0641249205577B31C8E544A41AB20D7D928E06B2553B9EFA97033F9E6C02F5185026CFCF3CCD9C42B1AEF8855232A4FEED18B6AEC2D6910C9AD69EACDF45C56B0A1E04322D4AC9AB1CE4A71E02795B8DB434D1320E853A8407A4CF271EE8B12931897CB44A782F8C5093FA5AA6A54CF6A72C380DC14150BFFA6842E715C6350E0CDDF3BB743BC6233B5EAEAF880B21E225217DB7808FB251BE150E4F9C08BFC26CC8A84E1FF59BCB51D5F879EBC080BE2D9AF5647B36A5223C500B93C65B3DFF81CB0D9022A37CCCAF605E837B802530B4356FD4A6AEE8B1CC0E31F6456650CFDB32FD14B25DF3D5471123D9D11DB8678C54BC2C4C7B0EEA185A7986566714B717229998B1A279B1DF5668A9E4B59984F9270E7FF3AEEBA9A460DC014A1210C29CF9CA98399B57EEF6A5F73092E827C223941F6F26FD8A128333776C01167D080F14C000E774CD81170A4AD1F71B57B623D0F6C48862304538846B99E86FB65C0F4CEBE2B88121710877112755088DAA2C813D4841EEE10565E8E7BF35C5772950BEAB8CE75FE10522D0614936C7E74486111F18434F95B49563E06FA2010E499D028FCE138FC9AA375E49A913C99A52F57942ECF5AA87F3E443445DE57E2371C41C11A11C4B1B1C9CCC9819EAE6AD95201CF3D7763E8FFBE865D76ED6AFEA235AE4FAF4EEC4E71BBB400EC03264C4C62F2E3F0BCEA61F19641FC532FCB0020D4D75C2E88CDE4DE91696D946D4CE2B7D42EF9A9A0027E8860B9E9D62A656F9984026C134AE3E6FBA27121EE04D3D829DFFE819E9D9B7286F3E1F5524ADB8D944D6A36DF45D1B7B6797326C83A3BE57040D58D2951E4F51EE1989E39C9F0A8B8747DCB519C8A82E94DB3F58FD2DE9F80341CEB6633E11D6A089EA68E52D7B07B43E9A2D1F09B7F39D9F33C8E36970C9560DE2DD9ACEAC6737FCE5EE2F82E85F183A12C5775859351361B3E30C43A1E6DC2EF970AFB368E2EF3C61BF1F52D7EF51F2FE4BF2F8D791A474881ECAA2612159C78053B763BBCD9C1706C718B1F8DC9B3AD53E53D3C5AFB5120A44E36DCC57445A79874EC7862EF332FEA86C1C49E0658B1DBFCD1B58EADC74AE1098CFC645813869D0FE39611184059FD388BD587CA09CB5D2DE370C6EAEE1FFA16156CBDAD34B05C2355B89ACE5C33FB142A7FBA3AE676755D79DC692C410F6EDDBF6B2D582A3919D13AF94CE1AF17C12D9D5AED077780760C319BDFE002", + "k" : "1588E00D33A4F3502533F98DDC3BAF046290750A99025C630A6DFBEFAC3150B4", +} +] + diff --git a/Tests/CryptoTests/KEM/MLKEM768_BSSLKAT.json b/Tests/CryptoTests/KEM/MLKEM768_BSSLKAT.json new file mode 100644 index 000000000..c284333bf --- /dev/null +++ b/Tests/CryptoTests/KEM/MLKEM768_BSSLKAT.json @@ -0,0 +1,502 @@ +[ +{ + "dz" : "7c9935a0b07694aa0c6d10e4db6b1add2fd81a25ccb148032dcd739936737f2d8626ed79d451140800e03b59b956f8210e556067407d13dc90fa9e8b872bfb8f", + "pk" : "a8e651a1e685f22478a8954f007bc7711b930772c78f092e82878e3e937f367967532913a8d53dfdf4bfb1f8846746596705cf345142b972a3f16325c40c2952a37b25897e5ef35fbaeb73a4acbeb6a0b89942ceb195531cfc0a07993954483e6cbc87c06aa74ff0cac5207e535b260aa98d1198c07da605c4d11020f6c9f7bb68bb3456c73a01b710bc99d17739a51716aa01660c8b628b2f5602ba65f07ea993336e896e83f2c5731bbf03460c5b6c8afecb748ee391e98934a2c57d4d069f50d88b30d6966f38c37bc649b82634ce7722645ccd625063364646d6d699db57b45eb67465e16de4d406a818b9eae1ca916a2594489708a43cea88b02a4c03d09b44815c97101caf5048bbcb247ae2366cdc254ba22129f45b3b0eb399ca91a303402830ec01db7b2ca480cf350409b216094b7b0c3ae33ce10a9124e89651ab901ea253c8415bd7825f02bb229369af972028f22875ea55af16d3bc69f70c2ee8b75f28b47dd391f989ade314729c331fa04c1917b278c3eb602868512821adc825c64577ce1e63b1d9644a612948a3483c7f1b9a258000e30196944a403627609c76c7ea6b5de01764d24379117b9ea29848dc555c454bceae1ba5cc72c74ab96b9c91b910d26b88b25639d4778ae26c7c6151a19c6cd7938454372465e4c5ec29245acb3db5379de3dabfa629a7c04a8353a8530c95acb732bb4bb81932bb2ca7a848cd366801444abe23c83b366a87d6a3cf360924c002bae90af65c48060b3752f2badf1ab2722072554a5059753594e6a702761fc97684c8c4a7540a6b07fbc9de87c974aa8809d928c7f4cbbf8045aea5bc667825fd05a521f1a4bf539210c7113bc37b3e58b0cbfc53c841cbb0371de2e511b989cb7c70c023366d78f9c37ef047f8720be1c759a8d96b93f65a94114ffaf60d9a81795e995c71152a4691a5a602a9e1f3599e37c768c7bc108994c0669f3adc957d46b4b6256968e290d7892ea85464ee7a750f39c5e3152c2dfc56d8b0c924ba8a959a68096547f66423c838982a5794b9e1533771331a9a656c28828beb9126a60e95e8c5d906832c7710705576b1fb9507269ddaf8c95ce9719b2ca8dd112be10bcc9f4a37bd1b1eeeb33ecda76ae9f69a5d4b2923a86957671d619335be1c4c2c77ce87c41f98a8cc466460fa300aaf5b301f0a1d09c88e65da4d8ee64f68c02189bbb3584baff716c85db654048a004333489393a07427cd3e217e6a345f6c2c2b13c27b337271c0b27b2dbaa00d237600b5b594e8cf2dd625ea76cf0ed899122c9796b4b0187004258049a477cd11d68c49b9a0e7b00bce8cac7864cbb375140084744c93062694ca795c4f40e7acc9c5a1884072d8c38dafb501ee4184dd5a819ec24ec1651261f962b17a7215aa4a748c15836c389137678204838d7195a85b4f98a1b574c4cd7909cd1f833effd1485543229d3748d9b5cd6c17b9b3b84aef8bce13e683733659c79542d615782a71cdeee792bab51bdc4bbfe8308e663144ede8491830ad98b4634f64aba8b9c042272653920f380c1a17ca87ced7aac41c82888793181a6f76e197b7b90ef90943bb3844912911d8551e5466c5767ab0bc61a1a3f736162ec098a900b12dd8fabbfb3fe8cb1dc4e8315f2af0d32f0017ae136e19f028", + "sk" : "da0ac7b660404e613aa1f980380cb36dba18d23256c7267a00a67ba6c2a2b14c414239662f68bd446c8efdf36656a0891a3cc623fc68b6572f7b29a6de128014411ee41906d08071f94856e36a832b40338d743516659bd25879c007a52bc9586f79876afac6c9a30d8fac243bd22425d6adce42ab7ed39014757a958bc8a74565f019234ff04b34893ed6d05501c37255239aae2ac19f8c75ac5900dae8300dbba710dc2caae1bca3a38c58342b286b8518f136ad15b9f7bcbb06a5607db375dbe976457c26c6598257531b2cfb6ee7f51591840804c38388376c27148413da9e92920bfd9a069e018bd272053da8775c0b739f761db2107cf35a434d69b07e5bcdb87434138b0cb556761ba522a5747b28747d80eb9d6cc673bee5769377b996d36ceb0c0c7ed9a658533324869c18a1a36f31470f14c5ae49ab070507f8249ce404b49c0a8c3ee42fea9631fa1a0d10d86b93f986e0e3a82e703b74e5ae6101242421a89aa07fe68588460baa368786486a72e4f24d2dd76cfc03b694a5ba91a755a0b98f3bf93307c0ab64639aea7a6498a3c3ddc571141abca4678cd2e2b857fb88f600caa596b44bc422250b2819e0515f0472391853700b01eff9453fd11876b7c759a07dd845caba4555264a82765193fdf81b620a1e1f923fb24442cd1cbe94175003ec06ce77a3c64493c199987a300c95c53c0089b5d65c92ea971b2ffa93b52a461ea2ac8c199c2f4c2b704297ce3c3949e0735ea8a14aa59e8dec0c878399ff70747ab244ce46b5f2230473323d25c66fe6b419b1f4a112e5214035256bc43ffd2b6b7b378769a6b47000bfb6357d45814baef3857d379e2fb8b5e5201ab26274bb1b70ad322cd0439b2db109cff0a2f8e600995571ffc38c590bc4c7615c69d0c98ef430f30861a77238ffc07061e475d6a30ad1b47fd039c3a447762db2211dc31d0acacfd55890a5824798f9aead7413dfe028b1012be8b6ca1026666ac6bc9440a449b51ad8bba7b0921dd4d8b4a578136d1a05db38cc858437b25161d1c3c28ee07bbcf2b249110d22781dc3050d8cc0090096b38a850696f86e9e6bab325271b2248675011968502881090497fac0af843c1aea76dd81cf29c012c66227b7f06d9961309b0262f732c9a4d0bbd06727abb8371ff2c11899a098375c460516b2cc88bcf628ede37d8f3b3342e4490a85606ec03da29b0256275382a3313dc041114801032c519f350c3e6abac3e33b93b4a19f7c5466e58cb1dc14b4a96c475729f971bdf173cdf354824d019427f95b3b4a4a4a958e476a6e6991ce6f06cb5dfca7d4380c3d920b5711ac1fcbaf4b9ac800b976d1ec766a626cc1900b66b3a9dc62c5c144527a296baf70433bf657c0437f87597bd7c8bbbe9abc37050931a4a86982a2028a74454c9b810c88d1701c8cc98a1d4ca107a6b25e962fe4b6b03c95453260b807228637cc9eb12acc0954959a52ae54d1977300aba0ba2c14609bb28c11d5fac5cac88297603283e867a3648366c724d9354cd7a196dbd9802f7b88d3fa001f9c9773225462235e91352a20791fd8b87fe3377ec6a3940b1130a0bb04e7410a34e2580d071d6c56202086787a6590f84393a8e651a1e685f22478a8954f007bc7711b930772c78f092e82878e3e937f367967532913a8d53dfdf4bfb1f8846746596705cf345142b972a3f16325c40c2952a37b25897e5ef35fbaeb73a4acbeb6a0b89942ceb195531cfc0a07993954483e6cbc87c06aa74ff0cac5207e535b260aa98d1198c07da605c4d11020f6c9f7bb68bb3456c73a01b710bc99d17739a51716aa01660c8b628b2f5602ba65f07ea993336e896e83f2c5731bbf03460c5b6c8afecb748ee391e98934a2c57d4d069f50d88b30d6966f38c37bc649b82634ce7722645ccd625063364646d6d699db57b45eb67465e16de4d406a818b9eae1ca916a2594489708a43cea88b02a4c03d09b44815c97101caf5048bbcb247ae2366cdc254ba22129f45b3b0eb399ca91a303402830ec01db7b2ca480cf350409b216094b7b0c3ae33ce10a9124e89651ab901ea253c8415bd7825f02bb229369af972028f22875ea55af16d3bc69f70c2ee8b75f28b47dd391f989ade314729c331fa04c1917b278c3eb602868512821adc825c64577ce1e63b1d9644a612948a3483c7f1b9a258000e30196944a403627609c76c7ea6b5de01764d24379117b9ea29848dc555c454bceae1ba5cc72c74ab96b9c91b910d26b88b25639d4778ae26c7c6151a19c6cd7938454372465e4c5ec29245acb3db5379de3dabfa629a7c04a8353a8530c95acb732bb4bb81932bb2ca7a848cd366801444abe23c83b366a87d6a3cf360924c002bae90af65c48060b3752f2badf1ab2722072554a5059753594e6a702761fc97684c8c4a7540a6b07fbc9de87c974aa8809d928c7f4cbbf8045aea5bc667825fd05a521f1a4bf539210c7113bc37b3e58b0cbfc53c841cbb0371de2e511b989cb7c70c023366d78f9c37ef047f8720be1c759a8d96b93f65a94114ffaf60d9a81795e995c71152a4691a5a602a9e1f3599e37c768c7bc108994c0669f3adc957d46b4b6256968e290d7892ea85464ee7a750f39c5e3152c2dfc56d8b0c924ba8a959a68096547f66423c838982a5794b9e1533771331a9a656c28828beb9126a60e95e8c5d906832c7710705576b1fb9507269ddaf8c95ce9719b2ca8dd112be10bcc9f4a37bd1b1eeeb33ecda76ae9f69a5d4b2923a86957671d619335be1c4c2c77ce87c41f98a8cc466460fa300aaf5b301f0a1d09c88e65da4d8ee64f68c02189bbb3584baff716c85db654048a004333489393a07427cd3e217e6a345f6c2c2b13c27b337271c0b27b2dbaa00d237600b5b594e8cf2dd625ea76cf0ed899122c9796b4b0187004258049a477cd11d68c49b9a0e7b00bce8cac7864cbb375140084744c93062694ca795c4f40e7acc9c5a1884072d8c38dafb501ee4184dd5a819ec24ec1651261f962b17a7215aa4a748c15836c389137678204838d7195a85b4f98a1b574c4cd7909cd1f833effd1485543229d3748d9b5cd6c17b9b3b84aef8bce13e683733659c79542d615782a71cdeee792bab51bdc4bbfe8308e663144ede8491830ad98b4634f64aba8b9c042272653920f380c1a17ca87ced7aac41c82888793181a6f76e197b7b90ef90943bb3844912911d8551e5466c5767ab0bc61a1a3f736162ec098a900b12dd8fabbfb3fe8cb1dc4e8315f2af0d32f0017ae136e19f028f57262661358cde8d3ebf990e5fd1d5b896c992ccfaadb5256b68bbf5943b1328626ed79d451140800e03b59b956f8210e556067407d13dc90fa9e8b872bfb8f" +}, +{ + "dz" : "d60b93492a1d8c1c7ba6fc0b733137f3406cee8110a93f170e7a78658af326d9003271531cf27285b8721ed5cb46853043b346a66cba6cf765f1b0eaa40bf672", + "pk" : "93c140f6c47b7e53b96f72bb18447d277cc021c144a0f7a35e30b57386a78ac976376262320a5e7e1cb42e290de684462ce1067e920ee86c32418b130a5a41a0e8268cfa7e0db2b441cb927d7897c42b1d50f9b32868a35a2c04cfe91040e9a9208902f20c477e1b1ee5c290d2e5244eb1b4b7b4c6ad074533b58d9914a6aa8829f96789f5cb87607569983003f3a2461c33c81a3672af5924c4ba37e6827fccf86d8b4103fbe9c0f6226dd0a2145a6b7aec76b186466f9c67bf169039259574456497140c8cf4ac05091973ac8c08d809465785a677a032ac09ad1d666e8c48462813ce5ac75f184b38251c30e362b0e2501d6800c8ad103c8b773780b6717cf15c401139acd54b1598b2b7c79492a86631090268c70d875bc040cb2b75a386fa96b092b8cbc25c47f70aa76cd8b9afc12b42b536e27c5578831a96dbbab7138c3f247e955a6c08b4407d4708f1914bfa48af4b28533f747b860b7076c028e245c9727b42f3248fb0408b3ef0c4918ab76ab96daca81afb1211ab3a0329ba1a5b069a68934c1ce84c2f72839311257fa19e72c62fb5686b61416caf8b22d2b26a6dd01bb7387f88eb8606980a5e2259cbd56ca1ec051cfc66f96239991a2360d75dafa1534c8a05ab9c95e2e586853714600a3455511b62d94525d8b1a965ce69f986731888d1ecce536000e4863322a83e3c8475d9eba5414a65b0561d24a7b09dca6ffe23836058bec0a85671641008c831233c7890783dafe8c359a263e796869118c4e74002dc3b0ec5b1c4ac641bafe30eb2bb743713bfed2c1e79c4a6f46593006acb35f7031f194807b893aa7a9323162168d384d0e96f2f23368626a2e027891ac94f12f30a044b85f0322ce2b16517d36aa3f23b5f391be394b54ddc28e5a9775372869a7b50b4898c072c0669d43c641a3cb5e8c170ba63bed6ad1008615201305e292e1c818e1ef64f3e0c52fba67e7249c1ec4a140dc89ce0050647f1c19f5897c77b9059040b4b5b4282e0669cb4c658f48f67338413c92fc7412e444bc635dabc93c51b030784f21461dca210cc6a54fdc25bba09705baa77c1826636b16644a5ada51270d8317a787abf53192d40dc765bfb45c7dcae58481af3a49fe762b90bac1f6f69a5de8045981c67906b9f692625fcb6a4df2641688aba61fa49a84b47c96661e4701e5826c1108069c4b9c6e480251c4b021d11cfdaca12bbf9c09a0234186668e389454ac4046f5b2468aa2fa9b117868574e729574ee57ea7495af310627b85916d6b4c708374f9fb0c9c3aa4664c6651281d8eeb98132c1af13a816ca5b869f50b50b291efd466dea090918630c6fc77247c458aa82568a41dd9d4708af3bbca5a5716447e8c2c24ad788a8632473fdc4a257196bd2b549091176fe654d3694e10a118f7b66d1cd5af199b6e90b3bffa88a92e36717fd4bbfcc78b0e08634bc080c86885c92c8ef67aa4933c7df097891369bac5fc5d0c36737aa60971310adf02c257f76a7a7b3f7e132c2a71c52ff4affb6846391c0868241a3df13408d419a78bcffd49619b03a192c683900a244289c9f7b4564823900ceacffd9a9371260d5e57a8271196f4759eead0ceac318966e76f68de95ab9db2ba4fbf83c3b27092cd339cfe48d5ca0ba11591d04566f4ed24a5", + "sk" : "a2b315a16cc2cba3500aca6746967dfb808d170c0583b1ad737b50ee3408fd1c793739845fc18297341662ca3630c11f7bf77710c414cc925a3c4734cdaab8f1f677b33694067b230acb79b30262f74b923afbb06ab880b75a609463b40d908115489f3942473dc8a555e2403b7c1dec411b9818b627457a583305301cc34c4cb1db2b12d6f10ceed4269fdc9a67402b89b71fb372a4ef593a17a56d329b10ae24c6b3e750704b0993cc64a71840399bce5d7b182b561c9cb2b914673b6a5337393c1d77d497f426cde194363b50683e1b2c8bd909621158fa8b0aa234a47ac702a95a96b37c9f2a233e69b9779ce793788a0c2ea25f9b5a9a8444afd6b62f5ad6860c8ab1267a0e57acaa53bb86c6428cd7139ba48954ec55bee3f83ac5a47ebd328f053182d395cb7576ca56a639b3663e92f79af13abc20b251fd903524f9a16cc32b631c83b1e7cf5e04800e193f1595c563870ea1fc996f3828b2abc626c59137511ff6f40122a25bc644b154267a0bc6c1067078c993b3d5d018f44c56363b9c5cc9b1ca6569cff876578b5e86703d30c20d733553550b1a8e669f2999b62720b6dbf1100ea550fe6c3973b6a396b50a03235142d75603240f78055f082b1d2f490dadb8b3a0cb0ebae99ab2179f2b38b274c51febfb57cc87291e34bbe5fcba818a3f2da4c3fc8950f51c1e806c5e6f4552f3e187d82a0cf92b7da3f26ae04b8c86f7a91b545670b409dde5863cc7b7e30b937b13accd1c68e808ae6827175bb8239904a88a15824bf6489d1044620844a6d92469a311942c21294ba5f26c18dd0a0e85fc85f241c2151815ef00b3bed322de98a7f7092df5a0a5d3d6b424b26b38e1931dab2402342bc12463aa96a0a1c42dbf73ba15278a22448a4fb6012c214def53b0fa233dbd096cfb2045a255c75a9931d7e3284f9b95f648071f00343ee580193627ff1981e982264e63940287860fa763663cacfb61350e7a4b53f7702432347f22596c678585e3cfbba07d782766c8399ac21b37a8b16a79e6a41ff606469947af07c226f79145174ba4ccb4bf226cd5cac54055b8a0815020135b94e6560ca89c7d837e737a73a0278f0e8b1b29806c19858b8337967d527d0dd6a25a5b0f2338b23ac6a4a0496ffa8672d17075cc9c3b20b24fdf9548567a85f707998a375bdd044038c09bb4fa1af3f08a37fb6b17ecc29c756ce9085edd76618b5c459bdc4e361199ada77bd1f91086f443dac6a9eca4ce9403b4c5cb1eb6d74ed2f79ce9ec032174748c64416b676d11fb28e8ccbe1fd3aed6d0c168e92e3f7096403a3fdbfb28505087c6db9f2e44233773b03e5166ae1669041212ccd58ee8580a2d6861a30b6814f6cb550a7d9314080413bef5c847c94174e590b765869d0c9c6002aa377bf77d7f068316050e62e72a7bd083403240c1088f84287849112a03ac8ddbe907ab574c4bcb356e9834d4fab5c28b200fe233a61599c14259464a24e3210a99c7c601a81d2ab07d65a9504bd68906285545241131100cd03b5dfb05b5b4ba29166c226ed4347c2ca99d327595f29cefbc8636161c4b755f87851675d5553308c70ef0a8fee3be05a27f53075ac7d1710ed3177c133793c140f6c47b7e53b96f72bb18447d277cc021c144a0f7a35e30b57386a78ac976376262320a5e7e1cb42e290de684462ce1067e920ee86c32418b130a5a41a0e8268cfa7e0db2b441cb927d7897c42b1d50f9b32868a35a2c04cfe91040e9a9208902f20c477e1b1ee5c290d2e5244eb1b4b7b4c6ad074533b58d9914a6aa8829f96789f5cb87607569983003f3a2461c33c81a3672af5924c4ba37e6827fccf86d8b4103fbe9c0f6226dd0a2145a6b7aec76b186466f9c67bf169039259574456497140c8cf4ac05091973ac8c08d809465785a677a032ac09ad1d666e8c48462813ce5ac75f184b38251c30e362b0e2501d6800c8ad103c8b773780b6717cf15c401139acd54b1598b2b7c79492a86631090268c70d875bc040cb2b75a386fa96b092b8cbc25c47f70aa76cd8b9afc12b42b536e27c5578831a96dbbab7138c3f247e955a6c08b4407d4708f1914bfa48af4b28533f747b860b7076c028e245c9727b42f3248fb0408b3ef0c4918ab76ab96daca81afb1211ab3a0329ba1a5b069a68934c1ce84c2f72839311257fa19e72c62fb5686b61416caf8b22d2b26a6dd01bb7387f88eb8606980a5e2259cbd56ca1ec051cfc66f96239991a2360d75dafa1534c8a05ab9c95e2e586853714600a3455511b62d94525d8b1a965ce69f986731888d1ecce536000e4863322a83e3c8475d9eba5414a65b0561d24a7b09dca6ffe23836058bec0a85671641008c831233c7890783dafe8c359a263e796869118c4e74002dc3b0ec5b1c4ac641bafe30eb2bb743713bfed2c1e79c4a6f46593006acb35f7031f194807b893aa7a9323162168d384d0e96f2f23368626a2e027891ac94f12f30a044b85f0322ce2b16517d36aa3f23b5f391be394b54ddc28e5a9775372869a7b50b4898c072c0669d43c641a3cb5e8c170ba63bed6ad1008615201305e292e1c818e1ef64f3e0c52fba67e7249c1ec4a140dc89ce0050647f1c19f5897c77b9059040b4b5b4282e0669cb4c658f48f67338413c92fc7412e444bc635dabc93c51b030784f21461dca210cc6a54fdc25bba09705baa77c1826636b16644a5ada51270d8317a787abf53192d40dc765bfb45c7dcae58481af3a49fe762b90bac1f6f69a5de8045981c67906b9f692625fcb6a4df2641688aba61fa49a84b47c96661e4701e5826c1108069c4b9c6e480251c4b021d11cfdaca12bbf9c09a0234186668e389454ac4046f5b2468aa2fa9b117868574e729574ee57ea7495af310627b85916d6b4c708374f9fb0c9c3aa4664c6651281d8eeb98132c1af13a816ca5b869f50b50b291efd466dea090918630c6fc77247c458aa82568a41dd9d4708af3bbca5a5716447e8c2c24ad788a8632473fdc4a257196bd2b549091176fe654d3694e10a118f7b66d1cd5af199b6e90b3bffa88a92e36717fd4bbfcc78b0e08634bc080c86885c92c8ef67aa4933c7df097891369bac5fc5d0c36737aa60971310adf02c257f76a7a7b3f7e132c2a71c52ff4affb6846391c0868241a3df13408d419a78bcffd49619b03a192c683900a244289c9f7b4564823900ceacffd9a9371260d5e57a8271196f4759eead0ceac318966e76f68de95ab9db2ba4fbf83c3b27092cd339cfe48d5ca0ba11591d04566f4ed24a57b00751eb9b1253231213f8a14f06f0fe1b7a4fdb7d1cfe44c161e577e5e8f0a003271531cf27285b8721ed5cb46853043b346a66cba6cf765f1b0eaa40bf672" +}, +{ + "dz" : "4b622de1350119c45a9f2e2ef3dc5df50a759d138cdfbd64c81cc7cc2f513345e82fcc97ca60ccb27bf6938c975658aeb8b4d37cffbde25d97e561f36c219ade", + "pk" : "c02b820292c46c8a8a92975a2e27292cf893a7f54a84a67022845d66236dca3c4844604b16879e849c7fe3475d03f82323d822ae2cb6763842a319114f5c77754613d5fbaec05aa801a03ac1989a725337ea38a668ea65cdb36343ec3d690ccdfa47ab1fe473247bc488d98e1e33175920a0f2272a03982c8386485bc2c4245884f1d941750a1d27fa85f0067f5c377532304261aa908bfb950894cecc1bbfd197ced78a641366b9199a4ba190446e03ae51549be7959c87a629abf24cbb7a58d01cad4949734f797ae300a78f45c70f668506977d7c85a0cf64c700a5b1f7879801bc3ac75584302c8bc81c0d7f6b237a9400681bacfc7192f9c653f8a9551f796ccfc262d3a438a551ad74c80ae9e3b5a7f12c5204ad44c21f488b7824a4b1eed79da9b44e60d8b225490c062b924da04f0ef0252304cca34bb4fc70ce6b1800fb6c5dc771bf7bda9e9db2b6c6046a1672c6f6f01a0406b903411c271b20e139a69138adfbf50c1134ae0899c166b1b1a5d818515b0dd94895a253059b167630f3a0dd3c64cf257cdf93596e54288c7a4580404ba8da541abb1b6aec7e530c58a61a64d9b9bc32d870bc105ef7063b9a97519b871a60d7aaf8c193e948c267c9c815063d6a603ee8d2249b386d94395804a9af8cd2184800c7ccfbaed98c4f9f95b70145b448387183f5cc8f4b5f35a949bc74706bd03db7645c2d084624844a55a0a5abb9244cb5b8736b835b512bcd912361fb660479b2c51b99734970808ba5c6db0169756cfc986dbda94915563c15a109aeb77c01a7cff55c8430696d6e83aea5d49292462d725c428b984d15e97ed4a76403094699e1336426b54281067e675788b3a4fcebca4431bfdc8a49c215ba11004a341516018419abeab2374184b0e2b7b7a54efc678e812588960a0d009418e5289eddcac582d3c73dd93e1234518da003648853c5b5a24b389e88300aeae78c41e62e5ee303a56b548375757cd42e21a7c59ff29a133868d1d0784197573464292547161b3a8689dc0c7de11139d407f0b5784d942278d49462965f21f72cb992add160620f6a82f70aa9a830190ce3c9fa8015071c2877483c2203bab7228ee2f37bbb17c1a4bc499ec249ffbb42e4989905a878dc873e456a7d9db946572936d8d81777d1b992c00db12a35df1348ce8c9d1a02898c7403d4107f45a6bee864375b623d30e0c191f8ad835a3f3709362cc763d63c2b91649d722825402c9ec1b1c7aa02b154d69e39da196e72a25928212fe0711bbb2fd2f9550a361a28d4295bf0c036d7b79be9130232060206c919f8b864f03d6f02348ed2c8001a30124b40c6d61dc3e18bcb27c60bd1324d8386da99c3e098cfb94b018031a4d6aa5788d27a75a67b630327add804adc21642d58080956a03f03c8193ac302c92e949cea31721813390382c814b2c5a6d34a1eb44b8b62aa77bf88b5067455fc0c7be967c21bc281ad38ea6978d228a83a820c57b4039175c910a450e300101cae45b0736a4dcbb0e6eb58491da31de3b65cba0a7c80c7815f677eea7ce5ec571bbf7c4516c65e4b2528e160959c815e1bbcad0a29ce59573d749453d9b6b52a951de9b889c79cb355c345631070b7c30f1934123c9ec68ebb324d254e5d246b14a0259e49b2ccec72b8c494834", + "sk" : "c22702a2a8b54046661fe48e8c686eac807794eb4a67454d68a12825c99c73b3620f1482eba71c724cb8edda16d05a2d630a4b7d967d33f42b352a07538a8ccfeb481776baf74073fee48709f01229d087b9f16d36e907ab792be2b86baca7c58bf31b63aa556613168140ad1cb45a70f3ad8f88ac7f6b42179b62707ba00fe0776ff45f575436ad70bdab0769e05587314ba7f1802b2ce6536152a5076a991eccb79a908351f62e38c75bc3db7b8702a104155b87129b2b3a6d3a157fba573c1b96b2b8ebc5327267aa47847259bf46f54c315b26748a6f49eb3721e772032b6f0dd48a44755eeea543624cb62c6965840caf314c81a7d49c1a2ab46d047ba45244b8b292f72252844335db158496302e1554086b4a2df68a1af1737f743b0bc4e07be5fa2edcdc4ba03cb61101327fdb6e99a2b1de800462431a5e45870f5bb61e058b21ea5a4f86404f99459b4c8cc5d91ae4e630ff1c380b3919c2f22f06f633fc062451b462130117e5f20cafc2760c434e404944fcc03d64d5aa8ad11eb2f727dc71917e6200f61b53ac7497eb198a417753482c3fe988c53883372d08ac11c5ae57a24b787a995f6acf6e359bc7121032e4bda65c618963b84785a86da1236289bb2a6b6716f2054dd43c77020d8686b47ca1b7ec2ab36c07141fb86937141f45d92219c25ed9c13d14c7ad682640a5f88b5574a283aa3709f26d9aa739f55c776526321942cc8115a69e790ae357765c7a05ab35266dec2de96acf5d126ca86763e18999e9513f5b5809130b7e2616392a3514638b39442a6e98c44a35005fa4a6b1488c9f181c4747a935626895f3c623ddb44e1d581a11465ffac0a0a1f2a5f881456654490a1b1bf1e4485a94841519babccc2ab594b1c2532fc92982db3994161b15194c265b679fbb768970f885f04ac06f62692c9576c81b8979f221e545b150c9a57f232dfbfa7d9ebc91f5aca92a3cc39ae922f1257f1973979b46ad1c967baa7002c36080a926467f277ac234c31c716ccb954b617694e7d228164a1be2e13b7b855534fb50b88c937a191ce493ceb19561d59b1f198b81c78371a58c5ca4f38bc6981faf61a9b60941978569162004abfb82ab729d4358c207a915d55458c13250ba813a8a5396cfab1157b4a266033050d31c1b74afc55c645bf256f00392b432a99092a30ecc456bba202bca14e5c741830c931ec377fc163b5f16b81b3897fecb961c6a0d8d97461cfaa8f4c48069648e8b48864dd9923b9b1bdd44290aa66290c151024285c3732a2b717c55072d2168ae92f001a1c44b54dc24a0145781923138875d8f4a0c76e2a79fab7d10a141c57ca9c8434c8ca18e9d0271ae62a391f28c53361c759914852859f1970caa124a1ffb3797723429874f3088197af94a9557cb66fb76fa84bbf5bc87552605ff00c67ef53c5e5c68c5800057f6a36b391386743bde6b4800b4aa1c1984eac8a728a729ad60a6321a22d6a9b27b56bbc7c65f7ae34304827e833aaa867766079074c8e020c32b87fc6564e5e4953df85b24991aff87b052847fe6371efb03a326a96514dc6ac8f42106f59df9b10d668111a1a9b08c7bacf2a42243504ccb9abd737593aab617c02b820292c46c8a8a92975a2e27292cf893a7f54a84a67022845d66236dca3c4844604b16879e849c7fe3475d03f82323d822ae2cb6763842a319114f5c77754613d5fbaec05aa801a03ac1989a725337ea38a668ea65cdb36343ec3d690ccdfa47ab1fe473247bc488d98e1e33175920a0f2272a03982c8386485bc2c4245884f1d941750a1d27fa85f0067f5c377532304261aa908bfb950894cecc1bbfd197ced78a641366b9199a4ba190446e03ae51549be7959c87a629abf24cbb7a58d01cad4949734f797ae300a78f45c70f668506977d7c85a0cf64c700a5b1f7879801bc3ac75584302c8bc81c0d7f6b237a9400681bacfc7192f9c653f8a9551f796ccfc262d3a438a551ad74c80ae9e3b5a7f12c5204ad44c21f488b7824a4b1eed79da9b44e60d8b225490c062b924da04f0ef0252304cca34bb4fc70ce6b1800fb6c5dc771bf7bda9e9db2b6c6046a1672c6f6f01a0406b903411c271b20e139a69138adfbf50c1134ae0899c166b1b1a5d818515b0dd94895a253059b167630f3a0dd3c64cf257cdf93596e54288c7a4580404ba8da541abb1b6aec7e530c58a61a64d9b9bc32d870bc105ef7063b9a97519b871a60d7aaf8c193e948c267c9c815063d6a603ee8d2249b386d94395804a9af8cd2184800c7ccfbaed98c4f9f95b70145b448387183f5cc8f4b5f35a949bc74706bd03db7645c2d084624844a55a0a5abb9244cb5b8736b835b512bcd912361fb660479b2c51b99734970808ba5c6db0169756cfc986dbda94915563c15a109aeb77c01a7cff55c8430696d6e83aea5d49292462d725c428b984d15e97ed4a76403094699e1336426b54281067e675788b3a4fcebca4431bfdc8a49c215ba11004a341516018419abeab2374184b0e2b7b7a54efc678e812588960a0d009418e5289eddcac582d3c73dd93e1234518da003648853c5b5a24b389e88300aeae78c41e62e5ee303a56b548375757cd42e21a7c59ff29a133868d1d0784197573464292547161b3a8689dc0c7de11139d407f0b5784d942278d49462965f21f72cb992add160620f6a82f70aa9a830190ce3c9fa8015071c2877483c2203bab7228ee2f37bbb17c1a4bc499ec249ffbb42e4989905a878dc873e456a7d9db946572936d8d81777d1b992c00db12a35df1348ce8c9d1a02898c7403d4107f45a6bee864375b623d30e0c191f8ad835a3f3709362cc763d63c2b91649d722825402c9ec1b1c7aa02b154d69e39da196e72a25928212fe0711bbb2fd2f9550a361a28d4295bf0c036d7b79be9130232060206c919f8b864f03d6f02348ed2c8001a30124b40c6d61dc3e18bcb27c60bd1324d8386da99c3e098cfb94b018031a4d6aa5788d27a75a67b630327add804adc21642d58080956a03f03c8193ac302c92e949cea31721813390382c814b2c5a6d34a1eb44b8b62aa77bf88b5067455fc0c7be967c21bc281ad38ea6978d228a83a820c57b4039175c910a450e300101cae45b0736a4dcbb0e6eb58491da31de3b65cba0a7c80c7815f677eea7ce5ec571bbf7c4516c65e4b2528e160959c815e1bbcad0a29ce59573d749453d9b6b52a951de9b889c79cb355c345631070b7c30f1934123c9ec68ebb324d254e5d246b14a0259e49b2ccec72b8c4948349bda55b63cffa9bf953993918b18cd6595ea6433b479e89b5cd3c9339e4468cbe82fcc97ca60ccb27bf6938c975658aeb8b4d37cffbde25d97e561f36c219ade" +}, +{ + "dz" : "050d58f9f757edc1e8180e3808b806f5bbb3586db3470b069826d1bb9a4efc2cde950541fd53a8a47aaa8cdfe80d928262a5ef7f8129ec3ef92f78d7cc32ef60", + "pk" : "25c1215d624156828088b63da622afa9fc5476b3603474b24d8394b93ab494ea3eb0f33ff5d91a33d34a2f666235ea009e35544cf135eff54e3575afe2fb15b6b59a4db843c25139ed345fa170003fda60b240065f761570471c4914aefb01c38fe36b3c7b80f77887a03b74bafb64d3b922701a86b027651fdbc777bc4d90d387fc15b8c12443af8636e35224c0430520bc984d71c56df26e84b683c1dba081b0a584b5793e725775482ec45b1db7c84949644d405579659cc31db130bd190d2247210c043bc8f227450ac206c13e8baa896e471f7cab2bdab29220c051ba354dc404767e812765c66ec19acba3b993caa2c0bc2367dd50846bb40d6587b51a76277f6865a5c69d885553ddfc200e970b9c0666c1854efc932af57a1f3bc0a805024efcf978f77b1dd739604b8a87b44b522ea80e87ca2cba7220e62c441a429d19b76425d51cd1e61e2a2950922637a1ab84fbf645a1f6413c288b731945d4029958d56db90aa01b712c83b73aa88581522757d505b83e61ae06eb6f5270021c61b7dabcb0229878d85c8f352a9a4349bdecb2ab0c2ab4039940a887b665f8b9dd10992b3b0493db6074fa85e1382a970953ebf113d4835e9f031d390836732b3ea6a89145183f72dbb095d7617a3abdc28912972035f1cc30aed3101d91c9eb397680c8ae222aa61e515a9396cefcc75c0cc255535a3f41212141c12558881e23798e1748bbb5464adfb167a2c44388044754a87a5ad1ce752c38b504bc443a24ff73a6cea4768e22681554b56dd59da1c7b88db126b7ec640c1bcae8a20b5f864ea6385dbba1c4ddd31775ca9f72ec6f137570fa9356de55c5c2ec92048a0cd9680837f98763fb35d1431805a7420d2bb803cc37bdc90fa921bd4d18b4f33419cf03ad0e2360d92192d7d87df71bae83d2b538741914892c0d778cfdf429be268a22f4043c29b62ff74fa770156d93127c3a7fe2c6c6c65470d1931f85a3af1a963bd919ca3c437b43d368e6e7a199407258b8bde88b4742192673499ac440b247d97225e7554482c6aa6567486074f15b19588c6d9de4619d4c493bf73f2bdbc05343a581e95197b64dcd8826442565bf629d5ce4045218bb908701a5e53b2d0679720598fa1b08f286b60e5c377ca7afafb206ed4712d6d16a47b99360426619f97db0059a15592353577765a8368d93928802704836c2279205446bbf7a2465042816d7907f143635b1434680156523b02cf1d8565ca5c7ceaa126a2753dc299c10e4968a4729991a0f5ce31c595629301c135b5810a712910a84ce1f2164c3aba248cb89c591ca0d24a7681c0a140672bf01c7f5c967f3e41b9a925af6ea75408a24684b725b446a30d0199f67af94b958c4b979c2a841b28878b5dc5154b79c944c7156538e6a130379674bba5438d64775fe1a87d3aca677541bf82c27c6d18f3bb182bc7494dc91b23c35392f21ac49e69e3c70454bdb16b2394d00a549734a1aa4790b01508be670841e09042e5a1a4a73c3b830ac5a35b826f36411639e20576a89197426005c08380c13a4a464892bc6992e236771e7b135aee096e9f65738c531b8e63c3f4a922a79222cf8b8309a04c3c7464a69982a072fb895714eb8f4e6d0a4c447ac97280a7a7b63bd585c521a49bf9230588ddd7034", + "sk" : "edda9b4fa2880d5778280a51a25a02b4d08f44f83afcc7ccc3692af517738bf8aafaf53eb33004364aabc42bb0a640b12266bc6eac91d124867192c485209660d625c33aae9f38535903cdb178bc2ae557e71acee8208169d80c74044490b3ce4c06b2b68b44b2c0b47d3c9178344f7a7a30da49548656b011b74b5bd1b23a1b39f9f37dcbc91c697799748007f80b3d55f6cb81b926311636ff11cfbbaa31bb02689e9b3b983213c2b3cd8d4395bbd46dbd25b345ca920f9b3545f13d4b809daa02608b4c5a1e041a98b3320b91802544aaa98a4916c7c49da792f6a04a4d64afa1294a8e71abd47c4d96d9203c7610a10b762e91b386471c8eec6ef94259b8440c369153ab6b9d6b52994271a865e20ed1136435ca490264a541207707881ebf74be6259b913b38a2c54be4ea88de1dbb3eb59b91497a13304c54a23a3a1810674610255350967a612b55bc82a22aed447b09bbc6f92fb9427a4baa183406ee6ca14e35808e33bd339a9c428213aabc6ecf473c38b62aa7c6cc8b30f9a559565d413c8f504cc000fafc4420177c054ec19c9360c2e04504b8b7e7bd86b820b1996a815337043f65975401c76a863a2803b0c80a6062e827daa973efca23502faca371cae8b42c4518b52070b91ed07a5be9c9dd304386592988fb1162449ac12589115e7c14776977bb34aff985c95f40265c20b4cd6216702c9ad91345cf120ce0c2961872bb6e42547412bd226ab8fba97b8e074eb0746d61140e07a51176227c9559c4bea306be88e2b84515c528af3ba34cc71c06e7cac19b998b23c549dfa2e253a33ad23b905e1c55f96054c3c4d0ee68f4b447404b8a752f4a9cb6acc624a7985141055733f47d4220ef164f6c7b6573bbda39365890c0c0318827a701ac4670878fa11ff24b3c57b56abf09ed2ac5ba554a8dd184fd09695cb2c798ad23b86f0690d6840c77c53f98491845c0c335b601b26582d9758a244603035139c98b9a723872d16694a4b5165a22fc281142251855998cd6eacad79b8987f143b5a7a69feda51d66b1c0e453dafa5209a225c1298a8f922cecb2c6ebc63c762f285ff667469d1371cc5ac957a495b55834c3b3a4ee9bf2a85c5b7062742a940a686bf0149542b6a350fd2144a849d6d71ccbf7336fa06aa4f7aae89e586c4d093145b8265699f5ef000eedc0cedc96e3256072dda4fe71789ef1c4734e3205ae617aed6a8848083fef84c61128c00645e6b4319b950ae0322ad845a58bc4564d2bbcb9e08858aaaa8f547070ea54412eb5b608cb7883472d10abf2ce4143e461c1de11b5178cdd8924d93666ab8f44cecb954ac431ab89208d812cc29073e2de706953c2028fb236c731dd838af9d310c1538238743bb71fc3546a08fe4e35e965903f2fb7e1a9a2201f6a86f38b21f22906d659f4bb8a226ecb8a107b217ea41e542075d01cba7caaf1c97c014a97ab49666e0015eeac597717b1e1e8773838958dfd1796fe1a7b62583f575b1c0e676a916799bfacec28ba707974131f36bb2292ce4e99cc2046b689624e069ae46db94fd66a5ca083851940ba26341bb891fdc860d53741f084b2d9e846ec2bb5eabaa69a8d96a8975a1d6f33835a53225c1215d624156828088b63da622afa9fc5476b3603474b24d8394b93ab494ea3eb0f33ff5d91a33d34a2f666235ea009e35544cf135eff54e3575afe2fb15b6b59a4db843c25139ed345fa170003fda60b240065f761570471c4914aefb01c38fe36b3c7b80f77887a03b74bafb64d3b922701a86b027651fdbc777bc4d90d387fc15b8c12443af8636e35224c0430520bc984d71c56df26e84b683c1dba081b0a584b5793e725775482ec45b1db7c84949644d405579659cc31db130bd190d2247210c043bc8f227450ac206c13e8baa896e471f7cab2bdab29220c051ba354dc404767e812765c66ec19acba3b993caa2c0bc2367dd50846bb40d6587b51a76277f6865a5c69d885553ddfc200e970b9c0666c1854efc932af57a1f3bc0a805024efcf978f77b1dd739604b8a87b44b522ea80e87ca2cba7220e62c441a429d19b76425d51cd1e61e2a2950922637a1ab84fbf645a1f6413c288b731945d4029958d56db90aa01b712c83b73aa88581522757d505b83e61ae06eb6f5270021c61b7dabcb0229878d85c8f352a9a4349bdecb2ab0c2ab4039940a887b665f8b9dd10992b3b0493db6074fa85e1382a970953ebf113d4835e9f031d390836732b3ea6a89145183f72dbb095d7617a3abdc28912972035f1cc30aed3101d91c9eb397680c8ae222aa61e515a9396cefcc75c0cc255535a3f41212141c12558881e23798e1748bbb5464adfb167a2c44388044754a87a5ad1ce752c38b504bc443a24ff73a6cea4768e22681554b56dd59da1c7b88db126b7ec640c1bcae8a20b5f864ea6385dbba1c4ddd31775ca9f72ec6f137570fa9356de55c5c2ec92048a0cd9680837f98763fb35d1431805a7420d2bb803cc37bdc90fa921bd4d18b4f33419cf03ad0e2360d92192d7d87df71bae83d2b538741914892c0d778cfdf429be268a22f4043c29b62ff74fa770156d93127c3a7fe2c6c6c65470d1931f85a3af1a963bd919ca3c437b43d368e6e7a199407258b8bde88b4742192673499ac440b247d97225e7554482c6aa6567486074f15b19588c6d9de4619d4c493bf73f2bdbc05343a581e95197b64dcd8826442565bf629d5ce4045218bb908701a5e53b2d0679720598fa1b08f286b60e5c377ca7afafb206ed4712d6d16a47b99360426619f97db0059a15592353577765a8368d93928802704836c2279205446bbf7a2465042816d7907f143635b1434680156523b02cf1d8565ca5c7ceaa126a2753dc299c10e4968a4729991a0f5ce31c595629301c135b5810a712910a84ce1f2164c3aba248cb89c591ca0d24a7681c0a140672bf01c7f5c967f3e41b9a925af6ea75408a24684b725b446a30d0199f67af94b958c4b979c2a841b28878b5dc5154b79c944c7156538e6a130379674bba5438d64775fe1a87d3aca677541bf82c27c6d18f3bb182bc7494dc91b23c35392f21ac49e69e3c70454bdb16b2394d00a549734a1aa4790b01508be670841e09042e5a1a4a73c3b830ac5a35b826f36411639e20576a89197426005c08380c13a4a464892bc6992e236771e7b135aee096e9f65738c531b8e63c3f4a922a79222cf8b8309a04c3c7464a69982a072fb895714eb8f4e6d0a4c447ac97280a7a7b63bd585c521a49bf9230588ddd7034647a81f0f1b3e3dacb6e73e900f7c078cdfaa7119a5ede48c7685fdb7e0fe2f5de950541fd53a8a47aaa8cdfe80d928262a5ef7f8129ec3ef92f78d7cc32ef60" +}, +{ + "dz" : "66b79b844e0c2adad694e0478661ac46fe6b6001f6a71ff8e2f034b1fd8833d3be2d3c64d38269a1ee8660b9a2beaeb9f5ac022e8f0a357feebfd13b06813854", + "pk" : "711cb96f0cbb88a8c1c298c7837b2f2c3525f2313ee5cba7f6dc77413cb58ed86f75d26b39729561c28b795073c1994f69256eb0ba9c934146c4421419475d005150897a17d310bc52f43d50e8ca5706a774d5079719754c6336d1142d2387bdc1732c03e2a3a04a9dde91c46612b54ca6ab15921bc20ab4f2d21910629ff4e37516870d60ab8bab08ce45dc89ca6712f17869e645b702141ef5d64f67f62156ea90ef1c502024858e91c89de92056f3675c1a6eb2191e17300845cc3f7b52cf93c566ffa732c362a8e89c5b6f4a5a827b6259d26a31932e3141486ecc746027776a852faaf0c3c436c690e3664ffaca01582022a99130bcc402bb7234a14db7baaddf7981d6557dfc44788c7506be021359e1917837a3c3d5a598757e00f77b6b785436b6840a16151939774a10a7cb8089fda55e6ae49f30512d691716f29c8a9fa94a8a113632a20c71138851ea6ab3f84e6e18b8531119e36cbbc6d0229a491f6b3b7e20866dda8ccf802abf47a769676550e2fc52ce438c48946eeb22756734bd4572c501dcc311b26fbc9c8ed2100a68e44435520848590375b59687c94a685b6490e236193c722b7b4acb84ce9a69388d13a984f696b85122c3dc0a5c38c2992ba60a280c9c6783855093a9b886953194eea273225c1a3e10b9db18c548c05c392631dc47320f411a618c943b7a201c784885b62f7c56a6b698abf1c76a039b3e6f95c466dbc31b4173778a9d5770b68b8a8195e886e8191e043b909723209553bb942a96ec4cbda1382d02f71a6c009bdac062c791c12f68a1f0506478d1869b782bc8b0181de6ac62bc8dc844aad6403a2b907f2d1a992bc44313f711fee1bc70d326e7199fe411354db2c4ab2526d09227bcb42cce2650e341368fb493d6754715736f8151019df22b07e5b5bccb3d0d161ffbeb2e93731600c85b6ccc226c790ed5e7384e8c3555497c07ec074f2253713b1ef6927ce4c1a80da11cb609c826718a5474230d62a40b0824675c95d0cb05b7c77b1dc4aa2872b8083bb79e201a0c847061e18be1d2ab68b2bd55d24925db5f4479bc12dcbc834b0254b891bf373cf5c4971bb0811182527c72c2ee6479217c70214106b416bdf0d818acecb63fa6af4d7031bb50312023acf66986c71a25cd8a88d767844c312dd5198b965c3df3e244ffd64610eb0cb3431f98889e72e864590191692b8857675afd45b6cc31374888b40183720e1985d811098738b63a823bc7716f9ce94ec70738d7f5228199bb78b811ea912500c71e1cd93c955c0049519ffa8b523a7861b6b2a3dce97d82449b00b8961877488b50542221ba79aaa0d33b3a47025acbe47998952b08e27ac2fbce08d6bdac7b6990297504194bc0304871472cf3cb952d439646aa86c47986d160afd7f401c70bb200e6182f91872812c551e17ea8438ae4236cdd743159802b034443e8d7ba0a249b312ac91981927440cb0bdc8e4615974bd2450161614068206bdac3c2e69eea0912f8a4ca1af21ac4c033a6076e6d13039c97ca930599aa12b93d58c09d663de14158b72ba0803a1b7917b71284802340422310babf6572aec23ae33a54a1f9c65dcb70821393b95178ba5acbc0756dd8a02f8afd156dc73958bab2f2c0d24c2436f9f00b7267da9f8b2678c14626ec", + "sk" : "9aa91962f6556d921b81c4946aaa26b62ac53197a49e1701eff367d7ab00b27677ced51b9619541ec8a180db9a7ed7342c31000063578851bbe9095816cc689b701a0cf7acccc64abb1355807703a6a759a2d89ec01c9b8196573576c06395335bb39903187233a3c89811447e8346dc70ae390544145abb14004e6e132a43e59364b249b3cbc13084c9a3487bafd0bb66d9414f607e6cb33b35d990ddf40d87135c3abc43a5b431b72ac9981b753a4b17ea48c3ffab5917b387657bc537162631e76ef6eb68c670caeabcc613b439a1f265d1229f8226c1a76447b535a81bb311b58b1236324c20762affe367155678ab01bae2b3bbbe3519ccc6840cf305e432b5c92966f45809dde31b7c30c2ccd77aaaa236ecda9260c361e71c7292e10151d165bf6c9cc709a49182807543651a844fee7703876921af5537365c50f4ca07b2895725505db00c6a3d240089f51c7dab07dde7a49217a90bb46462b4957ab22197844335b620e0226d1df94ffb5983bbe8aa3197ceb6180ead6561bcd7914841af1b954dacb4c5ffa694a1a45064e2c3b0bac1d265abbcf2ba35b8b3b0f660d83680be5c12dd2437a46a3367d6bd94d40fdae51ce2ac800a0881b3b3a12995bad39a2ee4ca5e07446943f19aa5dacc7b8c9042950ab5ea60a4e54de2e8378589722bf711a1c92113471259b2070041287e51742ac79902e4ccea25712943285fe5896427c8eef2313277b91ae9cb55ac2edc49b2d194a325f6836d29812660209802c457266ce3688de79a40d5b6a4c2b606b56c0b2e13b262990cf23987e138742eda24c0cb551aab1024eb095e929be557b17326b2daab78c981bd26a393a175385acbabb1a87983c271175cada26b2495705142e0c4fee912d1e19d97f2ceeb1653b70c9003165d7d5a4a6e916bf0298dffd94523762790f0108610c1bff81a59ec4cc890a716a29f4ad24d75d53360c423d0c921e66b59d96347112c918ff680ed460c8d590db11992cf86caf3ea3baec9370456c6c354859c040fd1c126f736c92e50860694b29dea4c1bf31061ca259e83035c01a27ec57eca8aca80c6c932261e1f44b6af8a0c571a833a826d2c8b749832566230cac47644eedc9b288640e32b4dd75282764c152b87648f7baeba3a73c31c7e2984973e74a6a7236b3c364bdaf2a5fe64b4da0b49437102a550ce04f220ad907e8853028a370d0b501d6fa849858339f63b8beff42fb5986135090bce450455b561f5d2c1d0a846dae4b2fea86507aa38c2257eca186ca21b87364643ccb668f7d880c164c398f9c46bf75a9a7c975e463bcc0b9b26c4291839c43136614f9c9133793fed561adc63992bf968d4c373b8531e6af04d58476b33585c1e9ba49539043e726340c4cce9223519227cd66b5f3d05702b9600a2694d5b23c4042b603018cf25fcbe4cb86422420cec820ceb589b42791c010cc4aa306fdb55452a49c66071c81aa3bac6f014be88602a6b4c49db2a7a9a57e6c97bae7bc483f5a54be7970300bd2445758027311e4949ce43859426b23999a0568a55b2304a838546d3f4b6cf8303798837b229b3b1aa3b3ea60bf3a9aa5c8b79f5293556a45010b5a571dc246ed749711cb96f0cbb88a8c1c298c7837b2f2c3525f2313ee5cba7f6dc77413cb58ed86f75d26b39729561c28b795073c1994f69256eb0ba9c934146c4421419475d005150897a17d310bc52f43d50e8ca5706a774d5079719754c6336d1142d2387bdc1732c03e2a3a04a9dde91c46612b54ca6ab15921bc20ab4f2d21910629ff4e37516870d60ab8bab08ce45dc89ca6712f17869e645b702141ef5d64f67f62156ea90ef1c502024858e91c89de92056f3675c1a6eb2191e17300845cc3f7b52cf93c566ffa732c362a8e89c5b6f4a5a827b6259d26a31932e3141486ecc746027776a852faaf0c3c436c690e3664ffaca01582022a99130bcc402bb7234a14db7baaddf7981d6557dfc44788c7506be021359e1917837a3c3d5a598757e00f77b6b785436b6840a16151939774a10a7cb8089fda55e6ae49f30512d691716f29c8a9fa94a8a113632a20c71138851ea6ab3f84e6e18b8531119e36cbbc6d0229a491f6b3b7e20866dda8ccf802abf47a769676550e2fc52ce438c48946eeb22756734bd4572c501dcc311b26fbc9c8ed2100a68e44435520848590375b59687c94a685b6490e236193c722b7b4acb84ce9a69388d13a984f696b85122c3dc0a5c38c2992ba60a280c9c6783855093a9b886953194eea273225c1a3e10b9db18c548c05c392631dc47320f411a618c943b7a201c784885b62f7c56a6b698abf1c76a039b3e6f95c466dbc31b4173778a9d5770b68b8a8195e886e8191e043b909723209553bb942a96ec4cbda1382d02f71a6c009bdac062c791c12f68a1f0506478d1869b782bc8b0181de6ac62bc8dc844aad6403a2b907f2d1a992bc44313f711fee1bc70d326e7199fe411354db2c4ab2526d09227bcb42cce2650e341368fb493d6754715736f8151019df22b07e5b5bccb3d0d161ffbeb2e93731600c85b6ccc226c790ed5e7384e8c3555497c07ec074f2253713b1ef6927ce4c1a80da11cb609c826718a5474230d62a40b0824675c95d0cb05b7c77b1dc4aa2872b8083bb79e201a0c847061e18be1d2ab68b2bd55d24925db5f4479bc12dcbc834b0254b891bf373cf5c4971bb0811182527c72c2ee6479217c70214106b416bdf0d818acecb63fa6af4d7031bb50312023acf66986c71a25cd8a88d767844c312dd5198b965c3df3e244ffd64610eb0cb3431f98889e72e864590191692b8857675afd45b6cc31374888b40183720e1985d811098738b63a823bc7716f9ce94ec70738d7f5228199bb78b811ea912500c71e1cd93c955c0049519ffa8b523a7861b6b2a3dce97d82449b00b8961877488b50542221ba79aaa0d33b3a47025acbe47998952b08e27ac2fbce08d6bdac7b6990297504194bc0304871472cf3cb952d439646aa86c47986d160afd7f401c70bb200e6182f91872812c551e17ea8438ae4236cdd743159802b034443e8d7ba0a249b312ac91981927440cb0bdc8e4615974bd2450161614068206bdac3c2e69eea0912f8a4ca1af21ac4c033a6076e6d13039c97ca930599aa12b93d58c09d663de14158b72ba0803a1b7917b71284802340422310babf6572aec23ae33a54a1f9c65dcb70821393b95178ba5acbc0756dd8a02f8afd156dc73958bab2f2c0d24c2436f9f00b7267da9f8b2678c14626ec811aea11a24a4b09e428415f82ee836e930c3b77867aafc5e6728149e3f2bd1bbe2d3c64d38269a1ee8660b9a2beaeb9f5ac022e8f0a357feebfd13b06813854" +}, +{ + "dz" : "7ec408f52c9aa723d0c41d9987682a5f4ce6c9da7cd0215af60bbaf5484ab353a08ccf451b049fd51d7a9ad77ae14a81569df8c9bd3a8f1ebea86fdcfb823082", + "pk" : "317771b7e77466880e15c76a39356cb459b78e6821e69b2f0f817b236a04a7cb834a743f830934043856e0dcc376730b3afca17aab6ae2c59ebbd57f52d84cb107b6c5e536edc31e57c3cd404a618700aa1dd87e43d92d4e601ca8d998c927451e9205429c643b251e8307553fc755dcc06d9003c35c310780b31ecdb05764e3c479913063978143fb9a462b011446394a287888a61f4f57b6c0548718faacecfa6571381ce25c2d10c27386cc255086419275a3ca59bfcbec4c63e5b487c41661520495e7b54b9641a1e16dddba5794a42d42e86b0007444cba4db161c6547c69a9cc18b2923b2a388710578043b77513173f6eb0190854bd6cd2612d1048e79435eb17680e99bb932c232b1ac298591d98a881696b3a46e117bc4a50565ba52e4704eb1c23c057894878434c61789ee8a594f94ac55748e2b111170c391b6b8403099928a2c60a42383ce5cea5880701aa5b60e4c789c759c12703d946416ed316e48c62603920e2f640a347a2f305602f4138aa82b78cd08fa071ba1b9711a333a3d22244dad09aac8058592b1edf9193291c8854b18003c6cfea4a8728e7ab378905e3d04349fa5e4ed9baa17b41b0a7189ab5cd0e352f174a51f3518badfa7df523bfcb64c43fac3bc5b6532bf4ca91e245e1e61a815c865bc7cf3cf87891eb1234a49b624c0e1169c400cac05359b6a15c9f3201b21f02c3ff0a4b94980757688ae0c48d0ac5c3fb650ddc38a8167c87c51cabd1698f8e3654380cbc8819599699615ef5495efba00a7a2c805c1d49552183b37bdb782f652682e02b7e26893fd97b8a7025affc7062e99557751a6a1da7828d7a003d0c62c8d006fac92589594fd729c17f38c5c83bacfe5bb8add8c1749a7550765f872c22e3e8be9db4c50a915fec511c31900890192861366d9177612d731f1912ccef5534248408c31605ed8960a612234cc23c94275a0b77302f0b82b4d121bae15539c3111b9a21031314076199849302f4274fc54b284d95903cb543902aaa5cd39d034304ee86814c6119f7fbc17d35c68b151e9048434973ae06030cff855291c71d58740ea00254ed926ab8835234490bad7b51eab118accb66f4a6a172c9a26717376e678771b44d9d452dc93988b9c9b5af98907b17487bca1397b8547ac8382f8a28a78a91b1b105f107200e839218a74d16000e90334ffc8709976b7fcdd4b742dc6bd2667ba6ac24dc510314f6b98dd711bd7a7169798874225627f2c7aad1bf37e97a4771542e8c7898fa0d8bf4c0fd91bf598580df6c0ce231a96368c8b8435f5507429006883fa88ee4e5791c2685f61c9247e72378478492ec90778c5fb8aa4a70e6cd48890bafeb05798c13795c58b62b5ba8f7c522e78365089ae735a796825d9ea8c572a6544aea86b2e08ea9748cf6b5717103a6d1c02f5d87a5e1aa94beda8691d454de0b547e951afe05061399804bfb32eb7b0857b8851810ba48e92518ba798dd54135a74419217a687620a0c665a050318e3672cd616f6d41618005cba6ea47faec63daba709acc2489417fea39b74ca2b13d4a60ab61ba89b2cdf0912757e08214b0671d8867cd2794fb30a8983b410f149ba2ca7134d00f83ccc8d1d4e2f1e83c9d8d4b95e33927f84741e362d80c3ce5833b7f2498d841f4c7e0", + "sk" : "7390b68a5071de21628a6256426aadd676c604479578d418ff77b4280c2901a29085e9ad9ca81c7639bae82274ee094fa38cafaef26fb27723c8c3c2b5276e28dcbd7131a5afb0bb238249963216cd81118a881dcf9628332661e0eb07c55465403b81d31407cc5b20b2041f5455c3fe8061edc7ae33e06982999e185106322564bbf9b03e309e1fa6bd61412f15091e9c523885b6134788a19d812a4cf4372ff35a24823a020c97cb59a9f5b698471483b04410107a2c2d8824d1ba5646a89e697738ebe6926c54874dd6a55ba2b89b64b1aec95f918a65c9e92d8fcabd58e25fb7b07fd880ab48f6581b661d4ea3cfda38875c9568a2162ec367bd78c2a7f7b3776511a8ae16981838bb3fc6006fab2457f2964bfbc5ed5c67da4987ec997d5eda305b389cb9234b39e23ccb316fed518f35c757bf77b501b983130282f598039435a6b402b679b14f5c1c2c69e32b1ac9421c888b6d935911d4aab56a4b39b3a2c6b8049f8584d74110fe63a1cbd633c63051953b9d12f36c5e3885dffa5d45309dcf56bcea5739a85441dde06b9564a4d1e416459a809964c16d574a42eccb18f51ccae7b016ecca4df2365596ce27958d1227a72a4ca336c412baa26afb154809243b5a448a9fc38b39dc90d2177f142b1959fbc767146dc8d17a3857b84e987479759997ea85ada8662035a939a30412a771b3893ab5184dc94106ef0790ab7617c57c8875d842010c08c142ac0f347709684302929d1d4371cff2019adc2c9a0a34b1f4a70dbbc3b18011348c7e725345a50197739a83a86c7af54960c11c3b03093cc3a39a7e2c8fb7f84e1d452029692bc4a872946a23cfe834254845d46bcf040267a93602b74a6fa9580b134500edb9bd2aca5cf1959991c8716e28c2ecb026a398444b853408b371ae438d4459a3a6bb00fb63175005cf15125136c2b069b9560d213acd3642c3b3c26620af85850922d27fe8f8cfb7b79afe08b9459a36281379c4169b73234c7649b8a0416eee2449ef7a1adce07910673d2ec3ba18e74914110e2bb7a9343b74d5551a80dbcf61d52367f387259408bb7b87d466593cc9b872766cb7021e9c741c040b397d842a80c952c91070838833efa83f36ec134be6156dbbb63e720b07d2197a4b4719f8a7815b682813a55e369721b88ac78144b738177d7788c2970e8591ab378bb4f26998845a8238a51352d33ed9b5533797a7e3d801b63a3542b11642ecc9e3808db74700cc622762a4132d8a4ee583cac8898005760351d6b70f71b52dea75c07a7d5970875e500ac13c14f1f2625d217ef13404a493526b115c6af01540629e07795fa78195ce23809911475e9ca00cb3caa0b5bfed575a6c33bb16351c60bb5bb050218f259811bc669ce68fe4fb1d6369cb7913013a16108d8204f0e09f351156713495e7a045175876f2836a4ef381b6a426ae55370ff4c8e740015687a8828c19426060581523bb184baa9972d946af2d2c34eaea9869304b095106fd759b2040908d175f02ca0a87762af4b57daacb432ad5558a41aadd2c49222460515178740c8f552cbd99653ffb4953d3218f8efa2fd6a1bf7ac7101cf320060c537e95381623872a2607a8447a317771b7e77466880e15c76a39356cb459b78e6821e69b2f0f817b236a04a7cb834a743f830934043856e0dcc376730b3afca17aab6ae2c59ebbd57f52d84cb107b6c5e536edc31e57c3cd404a618700aa1dd87e43d92d4e601ca8d998c927451e9205429c643b251e8307553fc755dcc06d9003c35c310780b31ecdb05764e3c479913063978143fb9a462b011446394a287888a61f4f57b6c0548718faacecfa6571381ce25c2d10c27386cc255086419275a3ca59bfcbec4c63e5b487c41661520495e7b54b9641a1e16dddba5794a42d42e86b0007444cba4db161c6547c69a9cc18b2923b2a388710578043b77513173f6eb0190854bd6cd2612d1048e79435eb17680e99bb932c232b1ac298591d98a881696b3a46e117bc4a50565ba52e4704eb1c23c057894878434c61789ee8a594f94ac55748e2b111170c391b6b8403099928a2c60a42383ce5cea5880701aa5b60e4c789c759c12703d946416ed316e48c62603920e2f640a347a2f305602f4138aa82b78cd08fa071ba1b9711a333a3d22244dad09aac8058592b1edf9193291c8854b18003c6cfea4a8728e7ab378905e3d04349fa5e4ed9baa17b41b0a7189ab5cd0e352f174a51f3518badfa7df523bfcb64c43fac3bc5b6532bf4ca91e245e1e61a815c865bc7cf3cf87891eb1234a49b624c0e1169c400cac05359b6a15c9f3201b21f02c3ff0a4b94980757688ae0c48d0ac5c3fb650ddc38a8167c87c51cabd1698f8e3654380cbc8819599699615ef5495efba00a7a2c805c1d49552183b37bdb782f652682e02b7e26893fd97b8a7025affc7062e99557751a6a1da7828d7a003d0c62c8d006fac92589594fd729c17f38c5c83bacfe5bb8add8c1749a7550765f872c22e3e8be9db4c50a915fec511c31900890192861366d9177612d731f1912ccef5534248408c31605ed8960a612234cc23c94275a0b77302f0b82b4d121bae15539c3111b9a21031314076199849302f4274fc54b284d95903cb543902aaa5cd39d034304ee86814c6119f7fbc17d35c68b151e9048434973ae06030cff855291c71d58740ea00254ed926ab8835234490bad7b51eab118accb66f4a6a172c9a26717376e678771b44d9d452dc93988b9c9b5af98907b17487bca1397b8547ac8382f8a28a78a91b1b105f107200e839218a74d16000e90334ffc8709976b7fcdd4b742dc6bd2667ba6ac24dc510314f6b98dd711bd7a7169798874225627f2c7aad1bf37e97a4771542e8c7898fa0d8bf4c0fd91bf598580df6c0ce231a96368c8b8435f5507429006883fa88ee4e5791c2685f61c9247e72378478492ec90778c5fb8aa4a70e6cd48890bafeb05798c13795c58b62b5ba8f7c522e78365089ae735a796825d9ea8c572a6544aea86b2e08ea9748cf6b5717103a6d1c02f5d87a5e1aa94beda8691d454de0b547e951afe05061399804bfb32eb7b0857b8851810ba48e92518ba798dd54135a74419217a687620a0c665a050318e3672cd616f6d41618005cba6ea47faec63daba709acc2489417fea39b74ca2b13d4a60ab61ba89b2cdf0912757e08214b0671d8867cd2794fb30a8983b410f149ba2ca7134d00f83ccc8d1d4e2f1e83c9d8d4b95e33927f84741e362d80c3ce5833b7f2498d841f4c7e076c64235d8bd63438f13dcd038f286b9f4242070a5bec4d8990075008667aad3a08ccf451b049fd51d7a9ad77ae14a81569df8c9bd3a8f1ebea86fdcfb823082" +}, +{ + "dz" : "c121915bfef6abdfc177dae2f5a24218f9abda2559afc6741b08e0e61ab433eb84ef52db5eaa6df8ec3a0bc5ffa730db0dde8c5f38f266d5c680a78d264a7b96", + "pk" : "611425c6bb62e8f60764db8466613486836fa07896314a6ea13a56e2f467483848c3451602e4c6ceb2cadf378d85654a63024c5e1aa3ba242136e5302881274c1316cb26004a549b19db794fac3f7c454fd8223f560636fa5acb56f0611911954131ad94ac88272b6cf4c89fa0635a7a838c38c92e1d640955453ea44ab5a6a0868cb9c071e51705e24a1cb1c4c9d8c59082757fc5cf95b17ff0064c0c47b021b244de30aeda11251fb170efb279154515b69cba0400875c78c1844503d411521ad54c651a738bc32da29ccfe992bbdd937827c6503735116ab5079dc04006fca98a66acb6519187fca7ca935c090bb8d31b6062b34513f01e157976183a1873db1c9e878a3eb37b650205ea5245fcb614887a8def4bb44b89cbd3c221e1a9b587a8c4a50633a9f386e6aa43e360649da46ab688116e01aa75943ce061b362d74ea824870a94cdf84b38d809bea8c994d2e10057b78ea6685fee45548e6bb681a32f5346ad5467558fe6c345e6258175a84edcb32b378ac3bb24e85739681234c0f1633c334df7d853c9d00dbde8a23d463289423536a44bfab94f2c76c113fcb086e5c4cf40193220c40b509065cc3ae5c861212b898699ce1c224a04a77bf165b0bb057c30d9cca16b4dc8128e7c197a4999372906cbf38386d66c27d1e36e8d504613c36d8f655d49750a72509f32f09580fa4518d9a34eb63ba76c063af7cacf158607890380c034e2429e49125c3f543c77c3066c374a43d24a7eea2608a12b845a4c42f7354699bb169bc720b175ce7c0d6e63843f543c0a84162e388fc21c313b3a5902430cab0a61d3e3aea195b13cec41e38539f41c6e22d63f5d60825d7182ecb31dc8a0a82a952b765c0eb279b75d20be877b8fb8fbc290f56efcf5240779bd2c639a67476fae730be123236ea68e4afa9d3200d0db30b7a771bb97fc1667e94cff70bd02f32d6b0b19548b61bff4a43fa5cb73ea11483b23b1394ad5812c8875002be49510656794033fb3150c7e13611126afa639355de9c04de445eb5c7430287815771a937707e88b3c8f42587f30baef55aeb7a392c14a4dc858abb9d537f8043c64100aeee6a597315bcdb65528286e0fc7ad5a59a066725cc965c562acb9d6330f28220bfb35b21cbb4321fbb556449c5e1108c46744e48c578937cc12c20df49b79ce96aea9b231892597b8a57683c495a9729bd7b969f34899116104abb00ee4049ccbc7c37ea5868ba5c2f4a3934d6599ceec340d6a488fc28d84ba371456caf9c52da9980904e253e54332505cb9322b1ce3c1904c739433d99fdb35461d4b3f949c8734904974c5cb7dd54531e86e7f9a69b8c78e137a77c0eb6b1ff468d0b2973819ca6a69b1e640af8f3b35af45183f5284425393472b3b7674503a86592947621dac8352a64427d313d51716ed6cc78bd85412d97561c910f31923361485d138b80585cf2a59a04896b3bd8c7ec2923ccd290c962c343561226a076e7e13a0d51233b68062d0e02512aa96fd701ecb80b7f45b210311246bfb594c5059f25c1167094f966c7d88da77ba3a71d186936f6007cb7cb4941c599103792edc82e3708e4aa9706da72ced51924d19ba561843c3a70f3f91b4ff04987cc4a914fc6ad33290975bc0b534d415efbe43f7d4a4b917723a", + "sk" : "2d8ba8d5472d324746fd3a4a9f999726cc13871a6ce75130aea07566332c05dc3b99c8626cd69917f025f6898a3112b7119c168bd86e27c6af08b292aa37745f993146dab93b159e9685cc09d750ebb58ddd2615236b298e8422db54b971192d69857d3cb1c910c948544b6270a1c5854936dfa643710b631c245e8b00c42fe15552a293b6f20278d82588bb164eb3636465cb0bf931b77c087a475dc35414c896069321080de41d58644f14143c5b75719184172eb2add8dcc059bb5dac9a22060283b5c87ca05b068405a9e2e4c7cb88941d7162667733b95a76d2e3ab9803b547047c95eb86995b1abfa050346788ef0c682405852bd9bd8f178e4adac309e8aca30ba6ab1bc5f8ca8dcc96291a616d77d31a0504229e206704db130e8b4480822833597d36db65cfd130d4796a254c360dc2799d256eae54b01a264af8020c4422aa837a61dd2c983345bc158bc878987ac4f22e49b21d21d47f32625ca0386637668517531ee2f13a5d0665c8d41ad19b3faa53793232974ec3193f2568c092595b009d40f3301f033f479192d016106be49303a1616347853b107626e49cd14c46be4660883b0b4d7725c0477887eb771e305ee2aa49beb1c00d6c42b5c33fdfa225db0640e973855d504ffa70b23c6c1869ba0dab69aa2cb75a02d9acd2f57f66c0983182a334e2796afb96ab2293751ace0f51219a994b2c5625f1ec7de1891840d0c6f0b300ad5146b5b682d5a6406455a475a799c0ca7c2d89c8bb759fccd178d278217d086dbce5a5946a0d6811518dccb37e898be658321fe262df3527fc5271e7b2b164099042900f2dd44491a72361bb0aef38106cf5ce7dba2316fca7ff2843f4f00a7ad94726f04bcb552dc8b24d6a644444ebc10cbb5dac08afceebc9dbf7910e031c8bb5038bcca34dd77fd8c7ceaaca6321715e639b5ae7573c0a0ba32668245a09aa278b86e2f2118c5bc6e9331063fac6d43c63d21728bb691233337668e7400fb08c54f98894c45a3548b74a7b1490a4b6009a05a9919195c20d835746d092bc6d3c02d2613e51832049631d3dac37d5951d50a2bbc5c35ac63a8d9c0318c2491ed5ec0ffcd0baea679150ab737003cca56556063b2abdf7286e887e92737f3651329235492c7221aaf0609c8b2f54a9c001f30d7314581ba821ba5b344463a88fc046d06a0eb422a524ccac23f7bd722c487d955c81836f7b49329b81231d371c7d3994bc54874e85bbaf278899c544236b49c04c688aa6170dea386d11b840634e75932b01716fb33459e63393f8da1281136f217bbfe8c10a14fb675e1a5074c1551530139c57312b4c9b5f4cca2219c4b35b63b1590ee6e3ad66d301b4609075737ff7a37aca7193d489762e75ada15ca43fa8be146232e5029b3f2a7d94f551ab625b8f963c79bab4123489317923eb54ad997b004ad53b3332b25cb27dd10a3576776eb1d77bfa10a9edaaa42c385cd5c871a4cc37e29a3da2e51683a78c09d63e64f6895930bb314080028473bc8c53ab6a2038dc1dc018c219108087c3b2bc2389e8609c0a8737f01c8dfee13e2014a77f2722e0f60d71f162ddf0c521f434d51a49befb613fb28fe9001d35c250791b0c611425c6bb62e8f60764db8466613486836fa07896314a6ea13a56e2f467483848c3451602e4c6ceb2cadf378d85654a63024c5e1aa3ba242136e5302881274c1316cb26004a549b19db794fac3f7c454fd8223f560636fa5acb56f0611911954131ad94ac88272b6cf4c89fa0635a7a838c38c92e1d640955453ea44ab5a6a0868cb9c071e51705e24a1cb1c4c9d8c59082757fc5cf95b17ff0064c0c47b021b244de30aeda11251fb170efb279154515b69cba0400875c78c1844503d411521ad54c651a738bc32da29ccfe992bbdd937827c6503735116ab5079dc04006fca98a66acb6519187fca7ca935c090bb8d31b6062b34513f01e157976183a1873db1c9e878a3eb37b650205ea5245fcb614887a8def4bb44b89cbd3c221e1a9b587a8c4a50633a9f386e6aa43e360649da46ab688116e01aa75943ce061b362d74ea824870a94cdf84b38d809bea8c994d2e10057b78ea6685fee45548e6bb681a32f5346ad5467558fe6c345e6258175a84edcb32b378ac3bb24e85739681234c0f1633c334df7d853c9d00dbde8a23d463289423536a44bfab94f2c76c113fcb086e5c4cf40193220c40b509065cc3ae5c861212b898699ce1c224a04a77bf165b0bb057c30d9cca16b4dc8128e7c197a4999372906cbf38386d66c27d1e36e8d504613c36d8f655d49750a72509f32f09580fa4518d9a34eb63ba76c063af7cacf158607890380c034e2429e49125c3f543c77c3066c374a43d24a7eea2608a12b845a4c42f7354699bb169bc720b175ce7c0d6e63843f543c0a84162e388fc21c313b3a5902430cab0a61d3e3aea195b13cec41e38539f41c6e22d63f5d60825d7182ecb31dc8a0a82a952b765c0eb279b75d20be877b8fb8fbc290f56efcf5240779bd2c639a67476fae730be123236ea68e4afa9d3200d0db30b7a771bb97fc1667e94cff70bd02f32d6b0b19548b61bff4a43fa5cb73ea11483b23b1394ad5812c8875002be49510656794033fb3150c7e13611126afa639355de9c04de445eb5c7430287815771a937707e88b3c8f42587f30baef55aeb7a392c14a4dc858abb9d537f8043c64100aeee6a597315bcdb65528286e0fc7ad5a59a066725cc965c562acb9d6330f28220bfb35b21cbb4321fbb556449c5e1108c46744e48c578937cc12c20df49b79ce96aea9b231892597b8a57683c495a9729bd7b969f34899116104abb00ee4049ccbc7c37ea5868ba5c2f4a3934d6599ceec340d6a488fc28d84ba371456caf9c52da9980904e253e54332505cb9322b1ce3c1904c739433d99fdb35461d4b3f949c8734904974c5cb7dd54531e86e7f9a69b8c78e137a77c0eb6b1ff468d0b2973819ca6a69b1e640af8f3b35af45183f5284425393472b3b7674503a86592947621dac8352a64427d313d51716ed6cc78bd85412d97561c910f31923361485d138b80585cf2a59a04896b3bd8c7ec2923ccd290c962c343561226a076e7e13a0d51233b68062d0e02512aa96fd701ecb80b7f45b210311246bfb594c5059f25c1167094f966c7d88da77ba3a71d186936f6007cb7cb4941c599103792edc82e3708e4aa9706da72ced51924d19ba561843c3a70f3f91b4ff04987cc4a914fc6ad33290975bc0b534d415efbe43f7d4a4b917723aae654e4412fd220548280b7a6ace9f2f0bc7b059fc103060346e53bc3c3161d884ef52db5eaa6df8ec3a0bc5ffa730db0dde8c5f38f266d5c680a78d264a7b96" +}, +{ + "dz" : "d86634ecf96cc2603761e284c0e36734cedec64e7ff486469e38539c71141c5a99daf37400cfe59841afc412ec97f2929dc84a6f3c36f378ee84ce3e46cd1209", + "pk" : "3790b3e85bb887d46ec144b4d8ec8bed82bddda538eea77d818c7081b3bfcec68d496035b71280b23985c6d9cb7580568286b405f937e99a8ac1fb28a927940c0a7cbd36290d130a1c23a42f3a437c6291dce36e39e8cf2ea8b9613c1fe7571ac74bcab99bc452b9c5829b586e5544e27432f06ba9c96869f5b1228a0a70fcf95212b0b2b84b45f29a49b6572483807543baa6e4f8b7b40119a5d483fd20224932a3af6869f00c8e9c6c5bf4c53dbe092d879bcd7843475a3110a559454a7375ac0418c37444a16a164acc751f56b2ac97a1158c76bb9976d750cd23761265d16473429c3da3b82eac213876c20d639bf5951e94d939985abd149b99c249445f4c9cd7421ddf21c536bc8fc2029e65d5c7de083296d88bdcf04e38d26dac500ad4457cecf8a795322f45997bcfea18ebf807e84c659937cde6d89fb490765ea9713b768ce05099e7386b4037b961a81edd79add8fb9f8ddb71ee56c349b453d2a3bf22c56730bac0ce19c4f961c008e03ed3928c7d068cb6512dba564855289bdcbc2f2b179dc7631b9372872d05c4e373577861a67eab16cba898beb2ab70c69447a156df0b36ef9c451931b4b7212c8a850799563cad55bc89fb3460f0c56ab434c5e9abe9363f1992577698af0058b54bb5b9a7b42e8d148d9dccab2d1a31d661018182ce207c036ff201a95b755e041f2e1623bef565b01a27d870046018cf65c8324fdca0dad64883da659826bf82721c3712700f435ea40c872b83935bf6cdccb41fe29c81e2210477babe0012cd635079d5932d42038c615a476ff35a523c7761d4560554c8ae0532e8d23a16912a804908411bab5fb96b9802737db82ca0d40c1a3b9913d81fc1330cee7504e2a056a994c4dc70768bc216f66921d93b81973b46352796d37b4f9009312aa957a51692ae8a65d514ab5bf7b46e0964a8f827adc51765384e8c35c900c4899ff30b1b53be227a39fd8b3acfea46bed8832c38555252b38cc5cf750221e3490ddcb80d0d73422ff47623282d273645c316181a36bf787ac90ec326d758ae71e5863c66b914db005655b1ebb057f8444e2689ad91a69150f71000ad7908897b4a3ba94c881c20271532a9653071cbd55669719b5c613abf45b3335d734b718779d51cc5162a91e4f2622a94469e09a41e8a9dbb3667312bc8d5ab7839374f689b32afa5a25de333126a49555909cb27002b18333a6a0d255b905e417eb8460d8f7566b12c99d2900794f4c0b78451777a3789c834c785274b65881bf055dc1875c6392dbea82811e49c34a3b2978468e10ab7fd91793b2856666a7c28473afbb467e60ba603230c5ef681af07c1779c6598a20e051254384467868c0b21ab7d89604153aa680611b767f19956a3b16229bc31fa3ca4315048b90f9f3252c23c02c92a6cfca28c5ad6adeb242c26023b8f76a914f888d39b59fdd1042502a68c0b416e6853e9cb5894253a129a1016108e44aa4257c2b547292642c3ab2c5abf1b5967c8fcb377eb91fef8c0d4daa3f2e04a0f869ff4bcc458f4c118a4b59715c6f3dc25a304b2fc9877d1aaa3af43a512a680f3e1bdaa90c816b95c339331f5fccdc969363977a7b9695dd6b9ba34809bb613862a0561ec25ce0d2dc86f262dc0ed164c2ad357a709eda919cda2c4f880", + "sk" : "6dfc120e15395ffc3fea71601c36939f3ccb68116ecb66a550a284c09bafe6bc93ee929efabc348b015ad58b34f589891d9a7e34630565751b15f42d93412f81f511ac6587ce0121d32a4760ac0b6c3779c6bb5b4c0a983b72397c544b15cc7aa38502d37132040889c575bb473b0fca1bc1c50815496606bb99a7dde8861fda4799955b1d026535021a01840bc82ccbac7b99f745747dcacbb0ab34036110cba31b58c0ba3273349f2927fc0b32128b1b41c256067642adea66cd35482bebc757d2005b8c5579c5844989551cbb7377d550b17ccfa6bac2ce6012701988ea580435e0533bb5879cf5715eb75c69322b9015a4824b33f2647f0b23b4343940965027ca10a58a8a4bfe883c5fc90f62eccb9eaa3dddf68b0c1671bb249a52898faf3397fe07d02aa723efa27261a44d721acc9c8b6556267f06e872e6888d03463c3f7133eecc26b01b96879c0b5438a1d218820c91782f6b19ec5bb96362c09d1c9329912c45618735424a05c64cddc9c8b53c556f7b4302226440c6909339603dbb5a66a76e0a898c53c700270bb1c375c2c91c222b4c54b0c2848ce5208e18864cec0cbd86507a1b87df6929c80a6bb0e93d6eb085fdc1ad97a713e3ba1470c1c33dfbcd89a802acb9c222052073230ea3179bb75cbf107525a938b49a552b8fdc21c262740a55724ef28bb4d63bdfe2ad28b3246b4452578646623ba78509a286c258e69480a835c2b9820cedec3767e12e1d7b324fa1a51558b31a914d9568bb22e72a1b55714488a699fa705a4ac58daa09348022f0d65df68b8841dc7fba2506d7fb2e137b8e6a921788b5661657c677283d16c16961549368129397492b1a849005917f695b2305e529871b61811b6cd88a535692c48e058f9cb826bc53411248a15c39b2e7ba40000aa9d5134cf2471574aa201e12601662b7d393be919979681abf59136dbf44a1b66704d8a68b23ec2bc1f9525b986b8a640a2f754702ccb321205c9ee916f7342fa86c8f48d817f9f72208474d660b5f23186357f43681d93440aa562ca93d3353154a42a4790a8811439a84a19f8a087b8614c6825a4eebe035b794caa7fa1ea967b63928965ae044f9740bd4986fd3eb78f2d42c76132c89d960bf32197c432452b6b2e117b248e511b8fcb0fd850a57852e071b6567c37263d3b45bd439095ba0572584bb1990c0d287cc826f13468d87d91725586707f1c29c5a7fd4e67faaf6558fbb8990463297d00a196407057316b331cc911911e7da8a82ca1c77159c4d654b74fb89e5597ce0640ce97861f37b79b47291676103d6ec6822770bbb40cb7332b841e7243cb55a934c488555652189bac26c508b438ed6799f2c108d4357096c63080af57fffd17731e41a217393c2198eead7adc7099e1b0154a010816073882fbc2409a678f1db0c6e5942298a5b2088a2abd39b8cfa8b2a7c6057482268c29b88566c5e97042f8866f469b69ae16db06c1657f91a66787e4a06597a6c0dd2300a914ac1cad196d5564864c5a597db2c62f4bcf64c4cab3bb077d331337a6b0e39c03891a64a369b202c1b51330ae01798b3834eb87cc5bf234e7e14b5a419b68c114fb0989d2a67bbd0da491d75113790b3e85bb887d46ec144b4d8ec8bed82bddda538eea77d818c7081b3bfcec68d496035b71280b23985c6d9cb7580568286b405f937e99a8ac1fb28a927940c0a7cbd36290d130a1c23a42f3a437c6291dce36e39e8cf2ea8b9613c1fe7571ac74bcab99bc452b9c5829b586e5544e27432f06ba9c96869f5b1228a0a70fcf95212b0b2b84b45f29a49b6572483807543baa6e4f8b7b40119a5d483fd20224932a3af6869f00c8e9c6c5bf4c53dbe092d879bcd7843475a3110a559454a7375ac0418c37444a16a164acc751f56b2ac97a1158c76bb9976d750cd23761265d16473429c3da3b82eac213876c20d639bf5951e94d939985abd149b99c249445f4c9cd7421ddf21c536bc8fc2029e65d5c7de083296d88bdcf04e38d26dac500ad4457cecf8a795322f45997bcfea18ebf807e84c659937cde6d89fb490765ea9713b768ce05099e7386b4037b961a81edd79add8fb9f8ddb71ee56c349b453d2a3bf22c56730bac0ce19c4f961c008e03ed3928c7d068cb6512dba564855289bdcbc2f2b179dc7631b9372872d05c4e373577861a67eab16cba898beb2ab70c69447a156df0b36ef9c451931b4b7212c8a850799563cad55bc89fb3460f0c56ab434c5e9abe9363f1992577698af0058b54bb5b9a7b42e8d148d9dccab2d1a31d661018182ce207c036ff201a95b755e041f2e1623bef565b01a27d870046018cf65c8324fdca0dad64883da659826bf82721c3712700f435ea40c872b83935bf6cdccb41fe29c81e2210477babe0012cd635079d5932d42038c615a476ff35a523c7761d4560554c8ae0532e8d23a16912a804908411bab5fb96b9802737db82ca0d40c1a3b9913d81fc1330cee7504e2a056a994c4dc70768bc216f66921d93b81973b46352796d37b4f9009312aa957a51692ae8a65d514ab5bf7b46e0964a8f827adc51765384e8c35c900c4899ff30b1b53be227a39fd8b3acfea46bed8832c38555252b38cc5cf750221e3490ddcb80d0d73422ff47623282d273645c316181a36bf787ac90ec326d758ae71e5863c66b914db005655b1ebb057f8444e2689ad91a69150f71000ad7908897b4a3ba94c881c20271532a9653071cbd55669719b5c613abf45b3335d734b718779d51cc5162a91e4f2622a94469e09a41e8a9dbb3667312bc8d5ab7839374f689b32afa5a25de333126a49555909cb27002b18333a6a0d255b905e417eb8460d8f7566b12c99d2900794f4c0b78451777a3789c834c785274b65881bf055dc1875c6392dbea82811e49c34a3b2978468e10ab7fd91793b2856666a7c28473afbb467e60ba603230c5ef681af07c1779c6598a20e051254384467868c0b21ab7d89604153aa680611b767f19956a3b16229bc31fa3ca4315048b90f9f3252c23c02c92a6cfca28c5ad6adeb242c26023b8f76a914f888d39b59fdd1042502a68c0b416e6853e9cb5894253a129a1016108e44aa4257c2b547292642c3ab2c5abf1b5967c8fcb377eb91fef8c0d4daa3f2e04a0f869ff4bcc458f4c118a4b59715c6f3dc25a304b2fc9877d1aaa3af43a512a680f3e1bdaa90c816b95c339331f5fccdc969363977a7b9695dd6b9ba34809bb613862a0561ec25ce0d2dc86f262dc0ed164c2ad357a709eda919cda2c4f8806ecea55c3d5c042d2dca3a3925faaa9112561827dceb0754580814a84be19b8799daf37400cfe59841afc412ec97f2929dc84a6f3c36f378ee84ce3e46cd1209" +}, +{ + "dz" : "0610678ff4dc3128e1619f915dc192c220f8fad94da1943b90aaec401683a492da1804ddb5aa9b1c6a47a98f8505a49bae2affde5fe75e69e828e546a6771004", + "pk" : "35775144c098e6756148a30e8ce75a67137ad2455860252b764c15823c08358c45ac820bbdc3525543a66a22854bcb8dd8e1c920a10f67e9c8d8495865b3bf16c39ab0a86cc231a521f42316f7bbe4d019616c167e88a40b4532b1ea688222a48150c6e24859edd0210ea54e4e80654b86abaaeb52a022742fccbb336921d5807d0769bb5674141fb791c6025ead44c79cf8c1fe80987086cda07546811471cebc7eb7e8a5c554a6cc0062bc6c0b10900a8ee95239f844d26527423c30f4a1be90e29424263663406debab5025e11f00e09c24058f8077cc2313842a5ac74bba5e26cb78c4f8557cd38dc67286d9d25b18f005fbfa852c5ac738f33c24e07b26d635a09a3e3d12c9eaf432a06c4cc88b15ee7c4258b279631a9756e5086145cc2adca624410d58db0def549d2c13caa2d80ed4a088531221e9881f16e39659c3425b31b4e5c0462df53375870c2360b984a881ade524777489b8a184304372464ac7099b6afa24a9545b3ad02ac8b9c968d0b4b6e991cc0a83550dc70dfbba36de192bdb2a2239672f011bc2924622ca6c2c7c4c334ea05db489ca290390e5a18bf18b564a037157006fb9131b35983a9bd285d66482863c0cc4270a32b13e1299328acc2dc4e1812f1522a88177e813a0e6b52f11573873fc512bd004eb31cbe1446a3b3518ae2253ed3204c3e3c36439ab128c322a0160a5b40a27f3ae6121333400b050d60e9fcabcbc82ca7fb1b1399715a23417691542441923750abec3607b47b380835191d6f790a7d08f00ab209a6ba608cc9cbdfc6c8f4cc194bb22c630ae48899a058bae66f3b0cb12a0d2e3209d995010644fae989eb94cae8128585933ad0f7282940606785c07e882031c08a20f4a194be008aae8ae5ce77c17505bb0854579712f7f5231d1c32301053e9ae2a1866b634949bcb4c6952fb78376fc91bbdac8fdf096d1d987db5c71e39371f894adff2a099cab93d5353ba013aef5c58796f906e7a434590181a793ca012a6610c912daca06903b719e384c827ac62e2b2590f82f29d00bfeb50d66815fe13085395663f722399c187cc2784198b028e585b305e6126f6a003b05aba2c0a87eec6b186623dbb37dad789f7e8ba7ce01a792366117c308601664d6b7ce64a03a03090f55c5b59e66545bc0c9a29a29d2eb89eeea017026c2a4b88ccd12c96816af697c5b5f1896d340a60729984857072234c71aa5c8fed44f05dc7defa39cf409b063e68bb28b3789344bce267db328542a5530222203d6d8858e51caeb8c913163a97c0759a1d1c3562288dcd48d164004b08a1c9eb76f956ba5a562a84182caa6417e237bbe4e09a5bacca54a32c76773c84c14401a348108b2cd83377f6470019af3591b7c65bb33833517ce53f7701c4b1b2db8665cf5259b6052e73b41ee2641e9c998df327f750c44dec00ad7bc0ee69992da9455c2b26e4c7605dddbb3ed942542fa5c255b4f9d037a4264939c3a26f8a817d9c21aa958677193c13a3b1b76619a66b2a0b351601a1750ff9b78cd4506e1c19f04671fce65c5c34a6e8141628dd696b3d5b962497ed3433bcd707537ac4715a7192687826fac2fc0a60fcde02f78e69dd3b996b937332ad2161db433ef850b4c8a5bc8a48556a927ce345679d1595b8a12a0e85dc5da", + "sk" : "5edb8568e989d33924746212f1b7131e5a247c6b73d58a8fb30c75b7161461f7b7f5ba4b38b924484964e7666dbf6177aa2662b193704fb19e60376614bc92e811905a293cba30a81b4401fd067f4185c3a0e72b5cb260aea81924b85105a7403bd6c6ee09627c13ab53dbad06999d276004e290b41720a70202c5f1f4585a68c56ceba1d7b21e079552fc591c6c3bc8f49c089527288ce6be22ecc28ea6bee8db35a8024a03f77e5d7c8c79a825ecc4c002566335e9355c0a91e5ec451cd81c14f355ba3b82e0a29365723ff30cca66a845e849a96093cea945c7d242461a94b5c9595555932ce43107e000c251f13fdbd699dfe6b5d2a3aa3b7662f988c39bf4573c59b38046317c65ca2cd9304448afc62190bb32bee74220b32b85953a5036065d230c2d28c80f0a164eee4b72b599be3a3961a8a70491d4ab680a46615450eea25a2fdb2c7352b7ce36ab05dcc5a933404925854ea5330563b41d477a775679c1f8b3e69690913216e9c479434ab55af2996f6b431d01a9f4d7904c80c666d1cab7e90da6f125e14320d46861bcc11d50d9b21b0196902a7e26b720df911ea80716cc478cce204dd796398d108d04eb31ee3027b8f0197bb89079e87d2abc641d7030923052046504788bcedd194c5807cca3202bfd25bae48493ff273cccc55446b2bde23547c45a36bf295b32e18122a008bac4a83ea05260930061d6c1205498549567ad11ce95f105b6e18fa282bf33c5102e0c18f2f44837980d85b26273c450c5885233f101cb8ca85039afd9e5c9cad0239ec63eab8063a3a76d7069b5767603d7f0921729910dd29c814a08fc67587de5020057add33c04bdc40c82015af9c7a41ce541a4c11832459679cbbd0626a670246104a33cb4d4769069253fc2379835be32e61ce6f12593d453071cbd7df3441d30b8540c4a515279def5c44a8c397bb018e4e377bd84b1c09917df0058bb8916caa26a9417b314a79c536576d97a5d0091787c24154a1aa9f2f39a70577e9d61803be48e2bea7c245cab5073cec1b1403775922260005f43706950a261b99e22302b1e63bb45438d9da39c2ee780e9db6e0b6495d0fb966c9352873a342a914ef189854832ab4dd42128527e9251565ccb21f6646654e6b78aa3466a0ac82337b90ed86dce3b0b62bb376827a5a1b467c63114e597bc7da7016561be00970200f710ef523ca3988068bbbb9a1a8fc5a94d37b930ae0758bb3c1fe98c96f5a90c94aa649a4647135b9169e6b81f18a192b19015a50bd39159f1e8ccaa881e34f53ae469a51756c220bc827546b0b9632d2110b86c43cd1b04c35bc183d68c1837b3b08e0c2ad5920ab4093142738a5545a5fa97951d735aec4a3e090175abd999bb1b1ca1c7499e7c5d46242fd605ce6e18047ae23231c605b6a81b320261cfa0884bb87bca9902ba3b71fbd98c0a97a53989637cd2078ea5cfab93b33b1396028270974b50c4d6c8f4c8a0a610ca689c981926c9013ccb06ac855f229d5a832c3bfc8f78b1ccee078b4e893783934115923f26d747312450aed0731d99375ef6b8291b39ec146d0a2218c9084f1575b11fb4894d372bbca066a621a334086fb392affdf4384cf64735775144c098e6756148a30e8ce75a67137ad2455860252b764c15823c08358c45ac820bbdc3525543a66a22854bcb8dd8e1c920a10f67e9c8d8495865b3bf16c39ab0a86cc231a521f42316f7bbe4d019616c167e88a40b4532b1ea688222a48150c6e24859edd0210ea54e4e80654b86abaaeb52a022742fccbb336921d5807d0769bb5674141fb791c6025ead44c79cf8c1fe80987086cda07546811471cebc7eb7e8a5c554a6cc0062bc6c0b10900a8ee95239f844d26527423c30f4a1be90e29424263663406debab5025e11f00e09c24058f8077cc2313842a5ac74bba5e26cb78c4f8557cd38dc67286d9d25b18f005fbfa852c5ac738f33c24e07b26d635a09a3e3d12c9eaf432a06c4cc88b15ee7c4258b279631a9756e5086145cc2adca624410d58db0def549d2c13caa2d80ed4a088531221e9881f16e39659c3425b31b4e5c0462df53375870c2360b984a881ade524777489b8a184304372464ac7099b6afa24a9545b3ad02ac8b9c968d0b4b6e991cc0a83550dc70dfbba36de192bdb2a2239672f011bc2924622ca6c2c7c4c334ea05db489ca290390e5a18bf18b564a037157006fb9131b35983a9bd285d66482863c0cc4270a32b13e1299328acc2dc4e1812f1522a88177e813a0e6b52f11573873fc512bd004eb31cbe1446a3b3518ae2253ed3204c3e3c36439ab128c322a0160a5b40a27f3ae6121333400b050d60e9fcabcbc82ca7fb1b1399715a23417691542441923750abec3607b47b380835191d6f790a7d08f00ab209a6ba608cc9cbdfc6c8f4cc194bb22c630ae48899a058bae66f3b0cb12a0d2e3209d995010644fae989eb94cae8128585933ad0f7282940606785c07e882031c08a20f4a194be008aae8ae5ce77c17505bb0854579712f7f5231d1c32301053e9ae2a1866b634949bcb4c6952fb78376fc91bbdac8fdf096d1d987db5c71e39371f894adff2a099cab93d5353ba013aef5c58796f906e7a434590181a793ca012a6610c912daca06903b719e384c827ac62e2b2590f82f29d00bfeb50d66815fe13085395663f722399c187cc2784198b028e585b305e6126f6a003b05aba2c0a87eec6b186623dbb37dad789f7e8ba7ce01a792366117c308601664d6b7ce64a03a03090f55c5b59e66545bc0c9a29a29d2eb89eeea017026c2a4b88ccd12c96816af697c5b5f1896d340a60729984857072234c71aa5c8fed44f05dc7defa39cf409b063e68bb28b3789344bce267db328542a5530222203d6d8858e51caeb8c913163a97c0759a1d1c3562288dcd48d164004b08a1c9eb76f956ba5a562a84182caa6417e237bbe4e09a5bacca54a32c76773c84c14401a348108b2cd83377f6470019af3591b7c65bb33833517ce53f7701c4b1b2db8665cf5259b6052e73b41ee2641e9c998df327f750c44dec00ad7bc0ee69992da9455c2b26e4c7605dddbb3ed942542fa5c255b4f9d037a4264939c3a26f8a817d9c21aa958677193c13a3b1b76619a66b2a0b351601a1750ff9b78cd4506e1c19f04671fce65c5c34a6e8141628dd696b3d5b962497ed3433bcd707537ac4715a7192687826fac2fc0a60fcde02f78e69dd3b996b937332ad2161db433ef850b4c8a5bc8a48556a927ce345679d1595b8a12a0e85dc5da576cb9d31e5146967756cf7356926f2e20fc7c1fde9954cb2f593d96a80ab860da1804ddb5aa9b1c6a47a98f8505a49bae2affde5fe75e69e828e546a6771004" +}, +{ + "dz" : "d322d56d8ef067ba1f24c92492b9c56df3a6ef54a304adc1b69913766a1ce69756047447b810cc094d400ab204cf9ae71e3afa68b88586ecb6498c68ac0e51b9", + "pk" : "023753735c1bba67bbfd117911d0be47b827ed9773e4d50d8d11a5b6481357473ae2a766156b9a4e74169a1b3cd0bcb90eebc31f587d886accf3027c8f6620aee70741c403e4a72d4bba51af5b1362180158fa5867d25168871d599b04819635bbf096c4980cc336267ac6b956bc861e0a9864766a18d4b8b9ea61a0573fe60a5ce58a87cfa2974cf17d4f599673137dbc662eee9706ad9a85d780a911c209644980cea134545375c031b8e1082b4c201ea83877dcd7158435ae34d52376816719070d76c0683e0c4422750a1959932e88562ebc932bb7ae688c09cb703c6e567e6d898b6e135f483290da271d7ef16b15d12d4e0872ccb05130f52cdef878ea83768ad44885e5a2dd6b2a94493ca519c14efa09e9cc0739354cccb3850cb0c4b504c2eabb1128f55bccdc17c534b5e68b94526aa46888ae970372ecd49a7f03171872633e78997b51ca867852e638215be32eb2fb832c42038624035de54d7f4938ab78210c47bbbc931c336917c9d2a0d58454ded14fc7fcc6f5a97a6c3a5649689286f0ced68963cf24a05e9851fe1277fed36812e5984290701d5bbf138ab76f32b6043853415790a540878c3bb297b6bc7b000036007d8dcc7d32e6b7544c3225c2ca861052dd65c8f1d103103959ed0753e81258ec3770360aa924357315c18b33aa12ca06b24f1c59aad1b4ebc58f3f75b77c1b07bcb9a23fb0019de06109050b0ce30e8d6809c8a0ca70eb56e366033841ac39a6a198c5c105c85899e6403781c72ab30bf1d5917035b9fe50b081b6cc6103b72d423237189c583c702f7768fe43c182075a48828d041178e6a616340178aba89be3418c4e968f14b9396574b370f1c7d2858a1fd78b5351213b7c0a7e05382d0217457ba27a344546e197b22256b3f031c9e6b65ff377be25b6953a4dbc9a6e9aeb3b08c01358e2bcacec80033990f282b0bda655951a2b0ab83ef4459ac56a76af2b2d2669c0239496610a4274c9b3e5e998ac948b3e7427c8b380c1077480789b008054373a7fc65080f3772d1f6626e345bb417c9fbd97add68640dc12028258970cba5deaaaa32c7b022b0183c89b3e1be25606b3109ef88c9f07180c110703153a247981b5b465318abcd0a78ad1bcaa15b07edb66bd77a14b23e84afa6500bdf15b588009f05925a2fb430b0629bb4c2057f8a231760d9255746781c83ce932afe10b8602a80fc1a98c694e80333790b59e67722a7bcc2fcd9b61a56a5a8ea6b85b5861b44b521cb0b6adfa9c84f624ad499c0664aa97270d1a0209897569a64650c0a9b2cac1879e671d9f0413be9621b415641ed645fad52e2ce49f5a3bbe49655649a62baeb5634e50807f737dcef63a7fe0c5d2f573b9bc5914b97f28691f49045ec87767eef405c3b3c8c6089e03268a5f0c530f1682c4c022e3804ade91c20a0793265a45be711a607465709a24dee763ac192d0d57626561c3a6092f7777c8dba75516c39fb49c2353157aaff0787be318ce2c7385101e4d23c043742b9c5ba0d96419e192c20bd426de458585e11aa4d5c8315bbfba129a446c80b726060be07458991e973a394f163e54383d14d420ae0b4746a4b891d092db39b8e1c708768046cb0e3ca324d417302e861358385229492a291da3d601a3f41d29a75becb44d66", + "sk" : "1e981c27e35d12192ff6ba764b9715bbb53b6afc9c3db6524bf480bb240d905622d8015afa41b9cc78a3f039269c9579d1bac3f6041827e883b3a073f22758a8112a36b91e2e1330d5ea0d5f91a09b7a2463a1a2025425b28ba10d85033b9a8fc3ca7ae949a8b5ea5c6f5b706ed22e949a1d5be2a573306b8e0c226634ae3b500a24b08c771456179bb24ad2c3024c5414fbcea4455cd781bf0fb5439f67285644309a8b6454d76463e69f27870e9089463d9abe0f450d72572fbdd678d6fac98c7989f0990d897913d0d1cdc6a378cefb0e202c4389626dbab6646b00be17377fc027c27f9694ef320b48ca51ba744d7c7c29555ac0c1c8cc134572893bbfbe45671225273db5b54659a67e41b2dcc744ab120917d3c952d9c847b038b53c36a369631493681b43512968069e2c7c140550bae5aaf35b64b9f9b8fd6c75e8063108e7237cc320ad32a8bf9a74987098e3e828f99bc54a5504cfbbcbd36ccab973ce8e4690ca8a37805657af89c6811b8c0045ca3ff373720ca1087259da8a27de2855f32c16e7d7aaa32c761d2241aab42db19353de53a2bd125cdae17468356d63256e22f6b2eeb95bc3b343ddb33164e297c32572c41459e5890777d8623e3a7df541945128004ce4ab73e25763e1236d1a99e5408a6bc59ffc308f2c810b4c18ac29d72581f46573843f75f57986979e77b28355e7bab59a9f71500689d0200589a2da8149beb260241bcbd147af09cb545ff104a603c1e22cae6476626631256e3720705287dc984fd4b3cf06583344011a4975cd490488dec64653d01b0394b413814f17b207e1a9bb5cb1661ba5c7439244267859f1544e50b03911188bee97a12b62052390cacbc9c83c713dae170cf927c8b4fb94d1b0c9da83088bc62e9e112bac46af692c77c57c0008e44c08b737944bac8c15901f2564ba2056c03660e7c6bb25c1c6075112a20338b8b413ef9c7421530741cb0df30c785a86ad78aa519ed65993578e65db2cb31c138ca6820a05231dd56b17668490d9393911c8e567060d368afd9bbf3d9369b6b2aa4393899111b72c8014f1d967d61286adfbb16beccaf0971fb8a2257bdac12b60372a61768ac242df6b575ef18df59c174acc51c26276da960f34219b8f50728290c99ac8c6971c9032c34fe682a58de45e4b2615bdd08ba6e11af9030e1968443a3b08e2877d04da6205a274565953ad6b7fe40565c0b680daf685049bccde9bb6616b325bf11e7069729a6a42544a0e13e90df4b5a42c2a340fc28960b7171b638173057519568a83fba15e40bb467b7e33d9785ae34f9e705f2211137e473b88c978d9a49eb4cca1b5d6b52d5b303a3a8151ab4654544fc791755efc094222ad8beb3057a24bf6f60bb6d876c5f7b8d7e6358cd1acec6254d97075bf02af58338f1a787dd335a70fba4c2ae3625a840ef18b53f8d8a2d051a2be6bba4fa6c40992acf1326abe29b852c7592e052045655a9acb5228b4cfd8c54a43fa2f76ba3fc7b10c603c958174894cc0277f688020013c7352b4b282389d9c178ae1af179c3d7ce495f82a773035b08e512eed8b309a5294b904c46012ad03bc6466d033a551c700624d0055421cc1cafd8568023753735c1bba67bbfd117911d0be47b827ed9773e4d50d8d11a5b6481357473ae2a766156b9a4e74169a1b3cd0bcb90eebc31f587d886accf3027c8f6620aee70741c403e4a72d4bba51af5b1362180158fa5867d25168871d599b04819635bbf096c4980cc336267ac6b956bc861e0a9864766a18d4b8b9ea61a0573fe60a5ce58a87cfa2974cf17d4f599673137dbc662eee9706ad9a85d780a911c209644980cea134545375c031b8e1082b4c201ea83877dcd7158435ae34d52376816719070d76c0683e0c4422750a1959932e88562ebc932bb7ae688c09cb703c6e567e6d898b6e135f483290da271d7ef16b15d12d4e0872ccb05130f52cdef878ea83768ad44885e5a2dd6b2a94493ca519c14efa09e9cc0739354cccb3850cb0c4b504c2eabb1128f55bccdc17c534b5e68b94526aa46888ae970372ecd49a7f03171872633e78997b51ca867852e638215be32eb2fb832c42038624035de54d7f4938ab78210c47bbbc931c336917c9d2a0d58454ded14fc7fcc6f5a97a6c3a5649689286f0ced68963cf24a05e9851fe1277fed36812e5984290701d5bbf138ab76f32b6043853415790a540878c3bb297b6bc7b000036007d8dcc7d32e6b7544c3225c2ca861052dd65c8f1d103103959ed0753e81258ec3770360aa924357315c18b33aa12ca06b24f1c59aad1b4ebc58f3f75b77c1b07bcb9a23fb0019de06109050b0ce30e8d6809c8a0ca70eb56e366033841ac39a6a198c5c105c85899e6403781c72ab30bf1d5917035b9fe50b081b6cc6103b72d423237189c583c702f7768fe43c182075a48828d041178e6a616340178aba89be3418c4e968f14b9396574b370f1c7d2858a1fd78b5351213b7c0a7e05382d0217457ba27a344546e197b22256b3f031c9e6b65ff377be25b6953a4dbc9a6e9aeb3b08c01358e2bcacec80033990f282b0bda655951a2b0ab83ef4459ac56a76af2b2d2669c0239496610a4274c9b3e5e998ac948b3e7427c8b380c1077480789b008054373a7fc65080f3772d1f6626e345bb417c9fbd97add68640dc12028258970cba5deaaaa32c7b022b0183c89b3e1be25606b3109ef88c9f07180c110703153a247981b5b465318abcd0a78ad1bcaa15b07edb66bd77a14b23e84afa6500bdf15b588009f05925a2fb430b0629bb4c2057f8a231760d9255746781c83ce932afe10b8602a80fc1a98c694e80333790b59e67722a7bcc2fcd9b61a56a5a8ea6b85b5861b44b521cb0b6adfa9c84f624ad499c0664aa97270d1a0209897569a64650c0a9b2cac1879e671d9f0413be9621b415641ed645fad52e2ce49f5a3bbe49655649a62baeb5634e50807f737dcef63a7fe0c5d2f573b9bc5914b97f28691f49045ec87767eef405c3b3c8c6089e03268a5f0c530f1682c4c022e3804ade91c20a0793265a45be711a607465709a24dee763ac192d0d57626561c3a6092f7777c8dba75516c39fb49c2353157aaff0787be318ce2c7385101e4d23c043742b9c5ba0d96419e192c20bd426de458585e11aa4d5c8315bbfba129a446c80b726060be07458991e973a394f163e54383d14d420ae0b4746a4b891d092db39b8e1c708768046cb0e3ca324d417302e861358385229492a291da3d601a3f41d29a75becb44d663e9976d61a687df88a8abcc6651446b81b7d136df42bfa03473c84dfd64fdb3b56047447b810cc094d400ab204cf9ae71e3afa68b88586ecb6498c68ac0e51b9" +}, +{ + "dz" : "2f1d8a3bebb34540324b9485fdf3d5be3b858f544abc3fc641b5728cafab03ba8d6c42e7270ee2b77b6045385f3d175984a0e260363166c73b0c70c971644363", + "pk" : "87fca4992854f318a4dd4188f7f334d83a3fe0d5709e89b4ac382e9873baf2525afb10a2785c5ad09c4b28b311b4579a79f06fbc91378109271383ab1ef7169385aa2e78b70d435bdb604494a246be23b1f26874ac9165ab451355f59686a33fc6cb78464cbd98021ad69c1ed12511ef99428e3b3685380dc2b16c0ab5cf46425984702e70fca396140a95e2c1bbeb245572049df3a4192a420fa52bda254fd55186aa960669f7ae2d69954aba444fb9c6b6cbc42b5ba82e262957089c76f48ba7362d6865259c321083c464bdc992bda9635cbc88ea89726a268a34d5cf1eb9aad5347350f67d1fea925f5677e393984818053eacace1844fc52b43d408761c385cb5491645696339ba086bc733c547546e540ead9b1a7942a0316cb635a856836075d3a87b84b1944a5587cb33c653e44b5bd764f6f8b06aa8688afa0526188fbba82707a326817087ea807e2ae51071d5badc027ddf781483d906259c30ee410b69060e4f47222481cf9dbb2075f330e4cca839b093668b82c02680c236167f3621921b863cab9a42e420a050986d481cabb873b6c19fa34b7e21bc6c029598daa77e30177357ba8b0e7696b692116a97ae2f535cb5208c93611ef5e952e76417fb974879337874f3c56d47a0d695797e1313e2fb7c3c6b2c32167f7faa9f10d18d512865f6a453e3e37c5bfa100631863b4a5f4b6c957eeca3bef28f62f98336c05770e001d8fc4f595921826cbad9825a76048aef2b4d97cb354784b4b6768377342685f87142ab06a67477b66a9457c48a2f779e0872cabed62d6e73278baa3406922f8ff5465af790e02310c9b8bf6e1b2987ca6521c55bbadb249ecc26afb244029312960a55fa45b448397264aa03530b9b56643a0d7cb9a73589955631883aba865c4d34fc5f5a6b8d596cb2c4db2b740645eb0a29647089ea2bc8a92bad95c15f52f5a2d24431d83ac4e701210c5b0ba3f31bd0086e47ab3f7984363ba00041c082d33064f1b27ff26958b85c46612c6556561a2e40600ae14fa70b4c1a81109fa6822c01d0c2786f0e17cf198009349704159866e557947b81928feb459b2337f3dbca2c82162107b5e34aa202b893c103ba5cf9b4580107c1f36b6ffb9ac34c2cee189571dc7f411349ad112d20f35a740c216ff98175563599d3cf6224ba230c2b2f087525059f9ab5b80f63110719972156aa30148bfe4c907b214f683c56a38a146e1c21e688c44f40bca8d4a87d3011bf64725360478359ace455c5e395625c95cc84ea3f0d004b2e3a4a12180a1463a234c4912f00be8324906b3805151841a1f4a5595621d66ca8b1863b6ae4869b4c93e2c6c94fa6af25f37e992cbc7ad23f6a274bec8b537f89b996439b762b2faca39d1f743db79451cbcba86de02a9d8567d8977d12066a1817bd9fc2b1bda75b9d6c78a39bc851654008b266c45361dce46fb2b02e4894c784f0b017428db0ba8f1ae54f3e8050381a90bdb073c186aaa458a2e8c682b919741836397e3c59e0ab75dbdc48976a6a474969356a75e171bfb2ca76e968191d970cd9e43d2fb2843b2a5e9d24cf4b2ca947e01f0c129a763ba55b9b92260c21113c03c7002bc8c6a2c544af711c18030ca984dc584e0b0627b3d23abd9c4d9e5087bcae2bfe6581eb7f9cbf532ba6", + "sk" : "6423bec1793d33f81bdc6a591ee2bb7d7c9c29e43654600eeb353459a19199234ca950ca5e51b3c8b24c5a96c164086ea746c3b68582ee171c0a03cebac11b39ea6b1c5218025118ba696da2dc9ba9a87d197931261273de87bd360389016131e47b66b54216474cc8c68c6f8485201692a53d3cc06d6bb1a4cb19a69c435e42706b1068c8872412e1520f7a2ef7cb361dac74f339059108277de75ec66b76c7d432f84bc17e5c20f0a94764c66dd8738e61012960b9b2798b4c0dcb213c0672b5530818b82a6bb29277735451147fb4a4a1bac36949227479b74c358c2b3ca852048ac6d52872dc63187bf87f47a2c3024b41aae5ce52e56607b5541e67b9c528503013354038197a86a2cae824b6d282b37c8332a2bce5a30f2357022058779d5a2e266430b89b3fd752cb5ca26ee317c628061c33203787f2865342cb9012158c113e402640d5e900c6db4da9c1162ff9079b482a4eda56b63a626572734c417952ec894b10aec7822121a78150042ad321a70554ae6043a6f0fb12c411876ccb65bfabcae28b75126189fd8a1cc5510a95d36fb2318e96441ba4dc09631166905579429badfdbc6bd7c231c971837ff422327c5f769a1a89668da2669eaac1564ae75e7df44b9586011b6cbf7aba51ce68260b5505a99207438837a2c67b047896f9f64c1b2a54959061e92c8a73742962366c16b72ef3509b11748bb819adbd0b400964be48cb7adda5627eb578933a698ef8137e362308c32af7e93ec744984ac31dbb34bb8603b48965ac93891de258a9bf942c36ea4c8d7c23a3978eb5f176554bc809d5946828b0f4fa0c55744e702a715268b8dc684133738ab9cc9543a74164e9731854327d7361b636069ad00184b5b3ace48900bc0a28411c123b4c79d1a22346a10ba3488732b2a9e194bee742a36ab3c1ca9003a76e28439c6667c3d6a731873150ded546f132644ae4965ecc29a5c961f04612b194b0509b3157a80859c2a95c9ab2b5486b3fa8732bd4c18bd4b806148d64d22f38c7685c9934f7b990cc378106579f981c36d5c99a26dba6df2921c6385ca329127342cae148974d2b2faca90adb629020104e4650acf41c5d85036bcc30581f304a5db46b269424282776b6ca06bb3119a009ce22811e7a004c58b28f6ae24ee8e7499b331749db0aaa33710cc9737ef18dc1994218ca439a46367590086efb839589380560c6cebc4db59cace187700a80508e3c9fcce960637ccbb4c8a5bf3a6d3db865696a5a5e824f91b7cec516415db47d0b706b99a0cf5963875e89a08c5272df90987a7c374de99113b54bdc5063c462011e225f223a377c3a15ec81c376817aabb785ad0b5c2a0bc7e55525dbbb305396319ed108f7fc527be906f6e20b975b9eacf7c6cd574debd4027bf367518a0062260d0879b343783adcc44372667aac541b454a84b8cb6fe1db9589e43950761d82c512ba923819a4078cb620fb750464d10e0069516028b145628ff1f06927965935e5b23592959f9b39bc32bae290a583c24422b5545b22846e42cc1e45bfef5396cfeb544a865d7739cfa0891a01d1c2d36c6f341c24e677a8218640d12cca27792ddf9a488afa799e580ae6b08287fca4992854f318a4dd4188f7f334d83a3fe0d5709e89b4ac382e9873baf2525afb10a2785c5ad09c4b28b311b4579a79f06fbc91378109271383ab1ef7169385aa2e78b70d435bdb604494a246be23b1f26874ac9165ab451355f59686a33fc6cb78464cbd98021ad69c1ed12511ef99428e3b3685380dc2b16c0ab5cf46425984702e70fca396140a95e2c1bbeb245572049df3a4192a420fa52bda254fd55186aa960669f7ae2d69954aba444fb9c6b6cbc42b5ba82e262957089c76f48ba7362d6865259c321083c464bdc992bda9635cbc88ea89726a268a34d5cf1eb9aad5347350f67d1fea925f5677e393984818053eacace1844fc52b43d408761c385cb5491645696339ba086bc733c547546e540ead9b1a7942a0316cb635a856836075d3a87b84b1944a5587cb33c653e44b5bd764f6f8b06aa8688afa0526188fbba82707a326817087ea807e2ae51071d5badc027ddf781483d906259c30ee410b69060e4f47222481cf9dbb2075f330e4cca839b093668b82c02680c236167f3621921b863cab9a42e420a050986d481cabb873b6c19fa34b7e21bc6c029598daa77e30177357ba8b0e7696b692116a97ae2f535cb5208c93611ef5e952e76417fb974879337874f3c56d47a0d695797e1313e2fb7c3c6b2c32167f7faa9f10d18d512865f6a453e3e37c5bfa100631863b4a5f4b6c957eeca3bef28f62f98336c05770e001d8fc4f595921826cbad9825a76048aef2b4d97cb354784b4b6768377342685f87142ab06a67477b66a9457c48a2f779e0872cabed62d6e73278baa3406922f8ff5465af790e02310c9b8bf6e1b2987ca6521c55bbadb249ecc26afb244029312960a55fa45b448397264aa03530b9b56643a0d7cb9a73589955631883aba865c4d34fc5f5a6b8d596cb2c4db2b740645eb0a29647089ea2bc8a92bad95c15f52f5a2d24431d83ac4e701210c5b0ba3f31bd0086e47ab3f7984363ba00041c082d33064f1b27ff26958b85c46612c6556561a2e40600ae14fa70b4c1a81109fa6822c01d0c2786f0e17cf198009349704159866e557947b81928feb459b2337f3dbca2c82162107b5e34aa202b893c103ba5cf9b4580107c1f36b6ffb9ac34c2cee189571dc7f411349ad112d20f35a740c216ff98175563599d3cf6224ba230c2b2f087525059f9ab5b80f63110719972156aa30148bfe4c907b214f683c56a38a146e1c21e688c44f40bca8d4a87d3011bf64725360478359ace455c5e395625c95cc84ea3f0d004b2e3a4a12180a1463a234c4912f00be8324906b3805151841a1f4a5595621d66ca8b1863b6ae4869b4c93e2c6c94fa6af25f37e992cbc7ad23f6a274bec8b537f89b996439b762b2faca39d1f743db79451cbcba86de02a9d8567d8977d12066a1817bd9fc2b1bda75b9d6c78a39bc851654008b266c45361dce46fb2b02e4894c784f0b017428db0ba8f1ae54f3e8050381a90bdb073c186aaa458a2e8c682b919741836397e3c59e0ab75dbdc48976a6a474969356a75e171bfb2ca76e968191d970cd9e43d2fb2843b2a5e9d24cf4b2ca947e01f0c129a763ba55b9b92260c21113c03c7002bc8c6a2c544af711c18030ca984dc584e0b0627b3d23abd9c4d9e5087bcae2bfe6581eb7f9cbf532ba6c0cfd4113c5edd408adcd03d38b12f0b6ac17525c618d6d151a761a9eebc26358d6c42e7270ee2b77b6045385f3d175984a0e260363166c73b0c70c971644363" +}, +{ + "dz" : "31beda3462627f601cbc56f3ddf4424e1529c04737ef0ef2af6d7401f653b8a1812083bfa3b670e3eaf9b443702fb6db16ac1197656bbd61a8e25ed523b8d1e5", + "pk" : "0d40b119341d9e23062c693509304bac635f93f91bd48b362989751078ab995408ddf6787ceb3f99c6802aecb703581dc6979c4d405dbc80a985f991f31924383428d4f5a2cad4acb5f95408a3406ec53425f175651952f5b76acfe2a465b30c1d56ca0e53953dac0ee2da352a687441f45dae26b37ce8008a99308639999d325ba89585656a6d59f51d10e46f93d099490c2385788c994238ea1155ed22c96a5c5035a3488be1c29e345ebcf6b1b7288abe95c29b272a7817704bd31589a42b22053226a43329183f6160105ed05e73203d172354fa176d3fd084ce690a8b6a4cef4035a3e06bc6464e8c913b88a48c81e58dfb1267ec6c1462d93433193e50d1b2d3e3828e90b6a412c1c45668272307f4b8294f37b84857bdaac6190706ca31380533c30643fc319c866534562036b37e825462c8442641c7817650333fb02ed6a2bcd6c1ad0689001098af3657363aa1b689a20683044d15275d0fc3c9aa720c8c4c6212fa70095a2243232cdd0b0fbeaa1c8e7b45ffc2870efa9bf56c8ee86659a618a0a96c42acb48ae125af911558f7cb20c9cabc4554c8fa6c70e297625286456ee625afa756145c41373ab4fb59b2782b4a406115de4966d07629cf8cc2283b4307e6a058db3dee6413aad72f89a7c1ab4131d8ea9df020b033b1473d92c4d89aa84f044e429a43b4e22fbb693a694bba3e315e78475437387b78b33261d786288b20440c44138c84f5592bbe74c1c2ab01ccd1124394082319780b24c593149cf660946f75a930f0a8f93a50ed01b5276ba96ab6ce5f794e638697ceca94d80585ced04310612a3c6cad80dccab1c1cbf5e08b2bd6b7df8c4cde4c4507a56cc97b456e10050bdb3acd6a7e00c1742aa4710e1674c59a8240680d04b8829752332324490ed6139b550c7a832862b2c831d4093db2b256f702850bba03053fecac41a61734229b2dba3210eea0c1e8d9a54c915f54b32344296ea64855dca92ab81aacc9e73153617d8464852e8208904ace7b84509b2266f9fac55bf68378d98d3fbc0a468543a8944b9975637162a4d50c7fdeb479daa8ba43938333b897a12c224ed1c790f967b2d9708c6b67640ca9ddcc1562613c2904c6f3856d13d904cd3094965abf1ed32ce52b7dfe4429ee68a8a3ab03446376d6da1de56a7a7fd30688f513fadc5627619a99d191bd4c0ec8bc1933c00757ab3e1f5826677b5e9bec2b151058bd9a6b5d2285122c23466312559c89a634abc2a5a11324cebbda8d167880f6d59bc5fabcc23487eda84f3543386e0b8d25422d5051816315532d2120ea4723809509bcd0c2edc1c93c275ade244d4f5b27f73b0941820da0183ca2b7af8480c90243af6334b36af00bda4c1e5f50463b8c350923b4696b7eb733762d189c9eba08c09050a4946388d736ee73c62f47cdffe453776730e88531f07abdd8699e8bdc9f05bb12f275c453866d46519ce2a592a1052c1e0c6b8f093f53a057d6d1bcf759abea90883eea68c5344a0ae96cdad42f0e756070dbb496535b9e7325c02badae5533140b0d9e013c75013ffdebc855734aa9947f1ca4b879c35b32c862c933479d884b2c675d3e1bbd26391d7c429db547041502307d975aee26905f7fdeb44f418d3d1fb5b081a3b06f87691170917a1e9f3c2cdc", + "sk" : "c062bfea197ad53bc1f0556d6dc8a863d46bcff5bbdbe919d96c4099627710b0417c889aca6964a75a336eb5aaae40674ef3a3f3f96d9207cd0988cfe76838bac93b4ec866fc4b6b1127bdeb5c9978ab3cbaa6999cb508358b92cb3a859754461bf25a471bca16ba9259b40b3cc31ba8831ee9c95904b9303be152827525db350f9ca65183b63a02b289192a224b781a6b11ce7a40bcab396feae20158536ba9d86568401aa68b42856427b9003053c15d7d36b9807960b94b5f3f366896c59298689efb101c8ae162f4b4b53d4bae816c01a56bce8c1232548007eb887a93703b66ea609869c7155ba0e8e509aa7c29dba60337d8364ab61de403a45f49041e82671ca0cccb5002efbbaf65a7b452a0237f1979a4988c524570815017f794a7bae806a651a732659a36938b86ab36f7536eb27c5d9b72cee990131c1a6b31acce8fb5473cd0cc8fc2605b3c06f24866a36138e1148f50c9a530c24911d031a0f1a2201137ea201eb8c3b788f15d3c0b0fad52bae069818480132992512bd5b57df93b288a6b9a18c3d1f337d733a6e1a7b7780b45f3813aa855c64b004ef55b89da05a85b1c0638f56f6d6c87ebb947273277a9c5392e489afac0276dfca66687709f69bc73f373c929c7cd37c01cd2437060cecbeb1d045671500743ca451f7d9871fe252ccc39c341860a25d47ca90b18adc3af22d849389022ddd3a6e887212d6c9ffeb47da0131f76c9cae0467c35968242118f0f41330cab99a5412642ea0817ea08f0d49380a94952956346087012ac595d85a2339779c956abb2b25fad4512ca46527b54954fb81bbf79ccc0801279db6d57d5c16da1374ac841b5b441be3944003c30a90c56ee10239e746ac6fb867a50808839639af13f36d516b5056605236f57572844d657ac209135569455d2349ed67f3715902c4b5894229eaab63d0ba964bbc6884c1b57346caae6f1bc953b62f73827ee67468644ac383128ff6a3e97ec0ca3689a50ec5aa40392bad95e88e241666b18bc7092f01b9c7b3194bfa77937839ebfd2495ff29cb659a9374a8dbeb51306a21553995ab9ecb83637bb702365690812c3d18196ea0069ebba9f952b6b468b0e9846f4f7af8c17054189cf5c2200140ad0551697387842dc20a4eab8a1f0380934eba5c34113962c652e11c97a0144348c3218d371380c476ce987870472d72a38a2475539dcc545693d4a17af010a8ff93873dc24051f7a69ee7c3297ca508c3229d9d215b95b369d4126862a03531bb1fd7092bba391d5541eb962b403b50565253a1b91c63901269d18bc41003bc75c876a277adbf709def9b54447641f01027174334d963813a678cf7507b5562d1028a63df2411f6a6d5771c60b4a26f6ba1971943248607d9ec3b72df5b98802ccdafba8a7b0661a662c87001c3646a888208cfd68996fdb37bf9906ee99a0d09693f30b1c924c919de4b7ae0359b2b159d648bb4fe41d197c8d8444c530995ce8c3aac17637f699ad24bc0153fc7572c759e741c1fb71982fc61921c4515fc260afc58fca4a92dc3b9426f717cc0b60c6535d1f34b4ef858bd12677eec80451791191148a0fe00343d0aff44250cba46b9b6263594c940d40b119341d9e23062c693509304bac635f93f91bd48b362989751078ab995408ddf6787ceb3f99c6802aecb703581dc6979c4d405dbc80a985f991f31924383428d4f5a2cad4acb5f95408a3406ec53425f175651952f5b76acfe2a465b30c1d56ca0e53953dac0ee2da352a687441f45dae26b37ce8008a99308639999d325ba89585656a6d59f51d10e46f93d099490c2385788c994238ea1155ed22c96a5c5035a3488be1c29e345ebcf6b1b7288abe95c29b272a7817704bd31589a42b22053226a43329183f6160105ed05e73203d172354fa176d3fd084ce690a8b6a4cef4035a3e06bc6464e8c913b88a48c81e58dfb1267ec6c1462d93433193e50d1b2d3e3828e90b6a412c1c45668272307f4b8294f37b84857bdaac6190706ca31380533c30643fc319c866534562036b37e825462c8442641c7817650333fb02ed6a2bcd6c1ad0689001098af3657363aa1b689a20683044d15275d0fc3c9aa720c8c4c6212fa70095a2243232cdd0b0fbeaa1c8e7b45ffc2870efa9bf56c8ee86659a618a0a96c42acb48ae125af911558f7cb20c9cabc4554c8fa6c70e297625286456ee625afa756145c41373ab4fb59b2782b4a406115de4966d07629cf8cc2283b4307e6a058db3dee6413aad72f89a7c1ab4131d8ea9df020b033b1473d92c4d89aa84f044e429a43b4e22fbb693a694bba3e315e78475437387b78b33261d786288b20440c44138c84f5592bbe74c1c2ab01ccd1124394082319780b24c593149cf660946f75a930f0a8f93a50ed01b5276ba96ab6ce5f794e638697ceca94d80585ced04310612a3c6cad80dccab1c1cbf5e08b2bd6b7df8c4cde4c4507a56cc97b456e10050bdb3acd6a7e00c1742aa4710e1674c59a8240680d04b8829752332324490ed6139b550c7a832862b2c831d4093db2b256f702850bba03053fecac41a61734229b2dba3210eea0c1e8d9a54c915f54b32344296ea64855dca92ab81aacc9e73153617d8464852e8208904ace7b84509b2266f9fac55bf68378d98d3fbc0a468543a8944b9975637162a4d50c7fdeb479daa8ba43938333b897a12c224ed1c790f967b2d9708c6b67640ca9ddcc1562613c2904c6f3856d13d904cd3094965abf1ed32ce52b7dfe4429ee68a8a3ab03446376d6da1de56a7a7fd30688f513fadc5627619a99d191bd4c0ec8bc1933c00757ab3e1f5826677b5e9bec2b151058bd9a6b5d2285122c23466312559c89a634abc2a5a11324cebbda8d167880f6d59bc5fabcc23487eda84f3543386e0b8d25422d5051816315532d2120ea4723809509bcd0c2edc1c93c275ade244d4f5b27f73b0941820da0183ca2b7af8480c90243af6334b36af00bda4c1e5f50463b8c350923b4696b7eb733762d189c9eba08c09050a4946388d736ee73c62f47cdffe453776730e88531f07abdd8699e8bdc9f05bb12f275c453866d46519ce2a592a1052c1e0c6b8f093f53a057d6d1bcf759abea90883eea68c5344a0ae96cdad42f0e756070dbb496535b9e7325c02badae5533140b0d9e013c75013ffdebc855734aa9947f1ca4b879c35b32c862c933479d884b2c675d3e1bbd26391d7c429db547041502307d975aee26905f7fdeb44f418d3d1fb5b081a3b06f87691170917a1e9f3c2cdc71c5534bb819e61a9d8a257ff2eb29598ae92eccfad38abbfc9bccde5ff95a1c812083bfa3b670e3eaf9b443702fb6db16ac1197656bbd61a8e25ed523b8d1e5" +}, +{ + "dz" : "cbdff028766d558af4466ef14043a1a9cf765f7748c63cc09dceb59ab39a4e4d8e9a30597e4b52ffa87a54b83c91d12a5e9c2cd90fcac2c11b3a348240411a4c", + "pk" : "62032561926a6380b6d6d90aabc5617126aa509168eca264ad67c5cccc5320c138e4053b4376924e6cb250b3a61fea8689804ac3179588a29196e05d0efb6915b3526d945cfc183dafc40d46537d907a292cd63b950659ffaa57e280ade8c09dd80655fe45979b612a6c6b1e350ba0cf433552e80f58c79d91f5cbff0717f3161f83b3c59fcc021bb5cb1922b0fa3c29984bbfc3363333f561dcb99395561590409fd7b56bb7db88e4162a61f8a81ca6b55af485d9b06645c42d1f706e9ef2b3d6e425285b4973202d46f150fdd4a6bad34a455b274814ac5c4053d680bfb4816578342fad152b798a1d592a3c88b45bdc275c45a862179557d437304151548a568159691282bc08f9280bdaf30559a3a177e6b8a62b101d8342c9d72452e05bbb1634cc1a7465e479f100b6f2952dab8ac806c27a8c555ec20a995c25a9ea8c090261085bd65c137a630e787da7a6b039c38573006c79bb5c20e39756e1a72e2c016f6cc997464546283d76543d9774345ac619f9200c308c25cea332ff25533b7983db495100f24a42e4a8df11504c4b96c017871b5a594e9c0b241b01e066043d07a366e343a08ac561ec5a08168a1c61755d5c33bd693608f42e63706bae5cc8c7f47aea360093fc78045517be49566f35728bd6a8230984a5e21133b63a9cb4a7fab4befe053e37bc78900141eb21189cf2abc0764b3cc507382c8db2320ea49c988c5aaa7ae896d10702c2082a59c3a457f382f44a1f2ce5b3d29a5a08d047537163916c5f6b22995541b87e1904b62a3585429d938a1b37d419bfc533cb918a424b5a1f73a65a8605edfcbd00678b6361399ac794f2cb0c9b26939b09baceb79ffc55aaa528673ccc4a5b844ad0873b4d6a31465cc479c30273aa2edd362625512012f83b42d52781c3bc947872c78378164cb0e077cf9ad87974c75ca527aed41a8b6993073d711c1873965448b14d307c5b218717b94ca27b354ff99de1f581e9561ec3cc196d1815a7a60a8c9a94cf4354140cc5e3b98bfdeb9c95c7c87182b878ba20939a0280e2c453567215a15803c01f7f03bb0b90741df964c4fa02f1007c466ba6b8f78bec07956611420220499a013ad3e3a874c4ad961b02e4c27a9ae71d57377dbffb556334797ec28c701c220129b856e747b90aac0803b2cbc7b0bb428583b810efe1727e0598cde9681429616c7b3f8bd8b691841a7a5405ad288f77b652a49c38eceb4088201b651a5c65bbc05e40a7a0f4151eb0962c34b10c1869a003cc4cf86d39036778b3ca32d0c500f7918cf027ef920b3718ab1c191618f294866b2fe77bab8c84118ce55157714ad2d054102a4d38ab73d1f3967e98351631582545c5a60b3aad50a7852c9d43b945668bb8b6781f56057ec058b2cfd6310506133e38b75fe3086d990d92cab098f06cd376531bdb8308e5a4d2e323c87c36e7ccaac87b00a7d4cfa3b3342d74a02d888d702cb44bc31201e41fe62c7511493c068a92717cc5513045bfa197d7f83db35798354797cca7891392ae9587245e92974920551d826101d44d9f73b3113746114ac94b8c8e291892be9c8015a0114ee44e26879c02084b0192194b922284956a8fc2b26e9071847fb901fdb6603c3bf7bbf5297bea11539fbe18868709fc57dc4d46d7d54159", + "sk" : "77996be8a7ae3546a363e340c57039fba8113adacf805385ead18c56b75320cc714072c4549a225c86ba31212146220eb217133a70c987e3819ff1b6364806d6750b9e293ea05013c1241e0760537d867640171741645f18d451670007ad4c971dd16dd3c55f8ddac186f029796979ed9091cbab1a46d093b1b89265b7a5bc81459dcc638ef08aa0bab48ff95e48c725fe90c8694274aa6365ea4bbac173a658bb3f2e646f9d4645a914b70cf92394586a3420c60ff2290217576c43518e1088b703cfbc3a3837794706188b5772c03685c43a33ae27410aed7825e2f2541ce67c07f15a71a5910422be6ec94631b1b465443b7215c30146c7049076ee1418e932c2a4061c1f1044b7456ed355851c41214ac25723ba486cd575b608359d2a948d85895eca59dab3cfcbb6a366815dabe7323ec05ccb9042c994b18335077c67187f352ab30a06d1d40007a1636af51602f936f7694a0da510badc59fa21b3ad033f9b03103f6655feb646f217809d00a521f6227876263b8b7663610f0392bdb9a5089362828bda10667a36af12bb9ff090cdbbcc6b1ca0e8259422f376a342944b118f74960f3d322bc11b0010ac32c49584003b2c66198acb0239d7a55f7aba6fd5546efec7a27c39c658d15332ab36f2988754f86f51c642fa087bcc935219e2b35ec7aa4194bfcae007e465cffa530c6b9982dcf98924f924591b2542b34fd28057e189a0448841b121a39ae17ea5d7101971b26301c43fc84edb0b8b0cb35d6e729955208f650610822918589c740667cb31b169ac104160647f50c77924fcc6ccf95ad81603aa8481cb4bceadcb3a6761b87831274dd8c5b6a7674f0412ec341589c303d6833fd3d25fee059c5ef269f7a910b3060fd60217c7a83a75c53115083fb68a9ae2da8f906c13522331b329c6eda84ece980284d9bd405b5a8ccc821b8aa99d49969871448d3921cb2c8c8c3b4e34ec07fdd299c532bb291329a4555c257a842d93badabc414778c76b7293e369597e7c092a3020ad72b5335a93cac4cd74d51fd3410da6caaa98085d107ba0dc3070a1284bad4398ae8b9acf58992397c9f0f9b2ddcac60bf539d0253d2d3377903a6963597298f97a82bc92f7160282e25387f57c4629a0a3482a563a0b1c776c18870b26e289b511ba601884864787cd922b84b7cdececc21e07120a9c5f23e5aaea649eff523ec0b54fb5face103a1a30714f6429421dcc4c3066abdcf33356c09109eccebd2a68acbcbdf3b162fb9a7b3d1c3743ac47b5dca488c561caaca4b2fb1a86ab91d00a65e97b213125836bf4190549c300f1a010515f0cf3c5acb2bd10a20851078df28999c831c14cfacc45d5872af85800431d350921e959a231c64103f332bdd55b3816c150b61defa324f7dba659e0ca30b9bc6138abc707be19a476f857ab9226cbd26a31e9f6a06d72369b6b5e21a7bf76538da8fa06fad879ab62c292a44e448b8252278eedf1bb283ac71b93b50d592bef275749c4c154bb669df436f081785988c42b99270c1435af451030fb08ec871285a9720646acc3cb015f63c87cc0bb74705188e145efe133b657a9cf360f48dc1e2fb11163ab31c6613a51307641e25662032561926a6380b6d6d90aabc5617126aa509168eca264ad67c5cccc5320c138e4053b4376924e6cb250b3a61fea8689804ac3179588a29196e05d0efb6915b3526d945cfc183dafc40d46537d907a292cd63b950659ffaa57e280ade8c09dd80655fe45979b612a6c6b1e350ba0cf433552e80f58c79d91f5cbff0717f3161f83b3c59fcc021bb5cb1922b0fa3c29984bbfc3363333f561dcb99395561590409fd7b56bb7db88e4162a61f8a81ca6b55af485d9b06645c42d1f706e9ef2b3d6e425285b4973202d46f150fdd4a6bad34a455b274814ac5c4053d680bfb4816578342fad152b798a1d592a3c88b45bdc275c45a862179557d437304151548a568159691282bc08f9280bdaf30559a3a177e6b8a62b101d8342c9d72452e05bbb1634cc1a7465e479f100b6f2952dab8ac806c27a8c555ec20a995c25a9ea8c090261085bd65c137a630e787da7a6b039c38573006c79bb5c20e39756e1a72e2c016f6cc997464546283d76543d9774345ac619f9200c308c25cea332ff25533b7983db495100f24a42e4a8df11504c4b96c017871b5a594e9c0b241b01e066043d07a366e343a08ac561ec5a08168a1c61755d5c33bd693608f42e63706bae5cc8c7f47aea360093fc78045517be49566f35728bd6a8230984a5e21133b63a9cb4a7fab4befe053e37bc78900141eb21189cf2abc0764b3cc507382c8db2320ea49c988c5aaa7ae896d10702c2082a59c3a457f382f44a1f2ce5b3d29a5a08d047537163916c5f6b22995541b87e1904b62a3585429d938a1b37d419bfc533cb918a424b5a1f73a65a8605edfcbd00678b6361399ac794f2cb0c9b26939b09baceb79ffc55aaa528673ccc4a5b844ad0873b4d6a31465cc479c30273aa2edd362625512012f83b42d52781c3bc947872c78378164cb0e077cf9ad87974c75ca527aed41a8b6993073d711c1873965448b14d307c5b218717b94ca27b354ff99de1f581e9561ec3cc196d1815a7a60a8c9a94cf4354140cc5e3b98bfdeb9c95c7c87182b878ba20939a0280e2c453567215a15803c01f7f03bb0b90741df964c4fa02f1007c466ba6b8f78bec07956611420220499a013ad3e3a874c4ad961b02e4c27a9ae71d57377dbffb556334797ec28c701c220129b856e747b90aac0803b2cbc7b0bb428583b810efe1727e0598cde9681429616c7b3f8bd8b691841a7a5405ad288f77b652a49c38eceb4088201b651a5c65bbc05e40a7a0f4151eb0962c34b10c1869a003cc4cf86d39036778b3ca32d0c500f7918cf027ef920b3718ab1c191618f294866b2fe77bab8c84118ce55157714ad2d054102a4d38ab73d1f3967e98351631582545c5a60b3aad50a7852c9d43b945668bb8b6781f56057ec058b2cfd6310506133e38b75fe3086d990d92cab098f06cd376531bdb8308e5a4d2e323c87c36e7ccaac87b00a7d4cfa3b3342d74a02d888d702cb44bc31201e41fe62c7511493c068a92717cc5513045bfa197d7f83db35798354797cca7891392ae9587245e92974920551d826101d44d9f73b3113746114ac94b8c8e291892be9c8015a0114ee44e26879c02084b0192194b922284956a8fc2b26e9071847fb901fdb6603c3bf7bbf5297bea11539fbe18868709fc57dc4d46d7d541594b53b4aec0d9f86a6377c63ff80150e40fc5347714c07591dc71c6beb8daaafc8e9a30597e4b52ffa87a54b83c91d12a5e9c2cd90fcac2c11b3a348240411a4c" +}, +{ + "dz" : "4c04310bea66305c6ca8ba6b8f61ca96257a67663afc11761f13fb5c7b324b6b8aec87a9a79204cee2986867a2906eb851b734b8b22b91d6749b1a5f07c44e3b", + "pk" : "ed7c794ee05d9b58740d13cd78ea15867a5c3cb14051223efcb36969430b45fb699c26caa918c3d9041589a1bde4484e95859a700c2510d6380c2a323e34526e22adb44a862c417b34d172269b32430c6b8a68cc3dd2bee2447555c82189e2562aa82df2a40e33b91d65b60d0ad93b127294d71002dd16b35701670564b1c07436dc2a001c751765dc93da79aff6177e9795b00c5bcbf66175357174032a2a742b3587e35f055268551c57af78090044be4200302fb0b16a40b80e092a1933bf99878852342cc6574c6230a9460b08376c42c51a48aca14d0e59294f3bcb464a74c0a296fb0182cef42b25b58711c6cc939c9e02c8302e2499640737ea07540ed89b5335a05c552472172e8bdb2f40c49a5b0295ce99a0f567af39169313c8b61ba77fd2143f97cc762c8b6be4c13300a8b78dd06011c144a1d747e1c3825cc1674b825838953574e8b6a16b3dfa8a05355c8977006c649b58d9f0ac2d704f774817eea95f6da97ab5ca71c521a277d9618881563f47792d99bebc73a74ceb5560070b75c3b8b2e2c9598195feb08ebfb5cb1d86a87f93465355a796520d0c24744c7b852bac418fd620d060118d135947d9b174cca55444096ed97fd6442dda02b4a3364732c6818c39a9d199b4cb5a4d3659c8c4851d39db9301047370351c8dc417bc1b86fa50486e759b87c4cc69a8a9ec282909c40f0b7ca0896c01f7221639b18fc3145eae4b4b8252b4af720f1a22c1e5cb980cea6b103082b31b0542ea8d64d8c9b119aef3524cad116689280a51ccc08c09a8c3313a82a581b55cae6a394efb5146ad9884344ab6904c7d5bcc75729a261239c76ebc83e2557f60d125a9578fe0b4ac8d57b08d729a8d86647708483407ba16344049f8b842496a64f84d5bf42540429ade11b10f567eba812aff9179e263a2899b770f8b3166da15bce789dee3cc7d1846f3204b26933d4803b74c3c3885748a417692f0f5ac2733804cd2a98f45547af8ccd28542ab3062211a51f454b28559c28d0751c5c6c31045a8aa41c79cd1cca536c3d6a779afd9175a006b663620bcc92b4ddcc92b61b88bd422f1dc7962a70569dacbbfc7ac9ce90f8d16c3b6973ab3e96b6539a145128631c6993c776fcf488f4ee692772645dc2cc1541874c02aba0564a46176005f6ccf2ab27893dc60d2d44ce1e5b6e317a38c032ad98bbbf79554ef2882fdb51115782ae862c9dc79a6a8293a39135460f96329548507d58c39a07ab9aa7fe913a7fbe4c466f693ee1006f6091346a4b75a2a506f6c787cab948fb76f4398b2110781ae27644211476364abe4ccc2f0ac6cc4e917dd391bd0b369ba862d5f396d8627285b0c5d9b3692ef8069ea601e6e493d841755cea52194b32b5f787f15a6478db7b6b41336000d2bdf3270f8f0aaadab89325b6a3dda4ea88021c8b61b6ba372186321f4f5575f2508625685db168830063860965a71a27ce34a7e934b9444d411da9a151b27b3ed738869100ff19099f0c2a8583b872c8a0745e455bf715b8f526cb4f378fdd931c8111d53a97379ab1d57684224780690b2c1b36bab3b0762b8fb6afcf39cdda151607a6537b985c37989299414b4c9b1894c6051242482b42289ab24793e2d7af2ca0cedbc27d0595b94c698bfa000840bb2d63e1946", + "sk" : "ed1263888c6658d29766539e247cb2ded8bd4aea61e1998c090c96c40c513ce38507b3c1c171131ef280496b0324907d31b2b1d1e53ba4e2b3795c6b756cb113bc64dbd0b4f47978c048892f3a5b64241c3bbbb9bc7c593a8865f4923097180352d9600636b8f639704ce868d0b5069fa99a395c30cdc4b4ce3807caa07130cb5864610f7c5a6234930a8a519b3b6ccb63c7cb898565791b8a32c594fd826cd283cec434930b0161e183065dd48cdb392f0404120dd86253906605284bd8d16970382c5288c598f3220504c4bf05189695c0f8055a08c062c4889db96c1e960bb8eb9009f060cbd9818eea119886fb84592093610371a09358f351704be5b7ba18308021afdafa52af2a4b42b7021459318b15aea8d04d700766a00428d8d3ac383a3cfbd03e49a8ba99713c7191b61422769ef5594954a4d3f00a0359482de59d0b9c18c787aaf8bab676acbc9cea9cfca41b43946b52b262dfa8302ce58f749260dcd65e81b7055b660d9341a67a352de1084353252d15e02d2b8bcddedc11bda1cc3aa46ee307a1fc29019182b9d817c1a3d922bcdbb2a8eb5fc2370b9d1a36ccf94a5af3b52ef094cbfb63ca590e24e43ac2e983b7760a187714daabb7a7d02f961c3452298b0e93614a8baf42988721965b4a7b1efc3b5b6e1968e927ce28e08bc12cbfb3d23ee095836aa5b2dc941ff1e0568942b8a6d6b997ba271c37b25d8b1147e6515ff788861b7e3b454d5e66b22cd059a34696b430890e8a9e0007cd62a1bb1bb0897ac835dc26ade4528bde16c8a00995fa9362c17981c794793b199eb348606f68862fb29c1fb154ec28314e65983343c3897499afcaae97752616c87076a00d54eb8bee6b3bf5e5be83bc3eeb874594147369775d02352936e51d801335e0a656ce9c12eff64ba0941fa6a563274ca536c3bfe9c2662a39b4c3eb07482201c93c50c95b823788606e81791ef21b27bb4eece135f1c961fc0095c0dc83b5226204104c7a919d5b3489e4f8144ab2c0045b72ffe77a509a6cbd8061da15371c03a6d028cd88f13494e8699aec9ec54291c2e16f787718b730c7cf436844d7bce9302aad448c01213c1d14844845601dbcb556ca85eecc54d426621d846d01e62796c011a231652904a8a9e7a73b5a87dea3afe747662bd696913cbfdbc1bc31893d89f4af3ed249ad946b7c2a31c8f35a7b9c8ff01988a956634bb06329e176d2e6c38aa3c8ab27b9dee0135962aa08a909ca8196e8e626f123bb3883b9d86c23883c9dc9910cb9e6805c5859a0e08a7af64d610a332b30cf41871fe8da13b503156f6c031ea4a5c33cb5ef9384c8047c58532cb7da4c9275176536a5f4ca0cd6cca9b399a938ecbf61eb3dcb1660b160698996b3fa21714715299927723f3609d11526336b6ad0c2cf91491927d07aa4e0c7234c9249803a3f43460ac19597b4c47c9c4e64dc174a8241a913aaceb8a431973d552416e3115301a969c351ac9b8c798d83cad6c925b7d467b132071bb9af4a3c2c6cf6358101a620f857f6c55a9fa077ae25455ff1249c562ade011ac64b659d289616284259a2cff5144558d1149671b350b18d0cc20f0e164d47a8382fd07d96232e39c0a6ed7c794ee05d9b58740d13cd78ea15867a5c3cb14051223efcb36969430b45fb699c26caa918c3d9041589a1bde4484e95859a700c2510d6380c2a323e34526e22adb44a862c417b34d172269b32430c6b8a68cc3dd2bee2447555c82189e2562aa82df2a40e33b91d65b60d0ad93b127294d71002dd16b35701670564b1c07436dc2a001c751765dc93da79aff6177e9795b00c5bcbf66175357174032a2a742b3587e35f055268551c57af78090044be4200302fb0b16a40b80e092a1933bf99878852342cc6574c6230a9460b08376c42c51a48aca14d0e59294f3bcb464a74c0a296fb0182cef42b25b58711c6cc939c9e02c8302e2499640737ea07540ed89b5335a05c552472172e8bdb2f40c49a5b0295ce99a0f567af39169313c8b61ba77fd2143f97cc762c8b6be4c13300a8b78dd06011c144a1d747e1c3825cc1674b825838953574e8b6a16b3dfa8a05355c8977006c649b58d9f0ac2d704f774817eea95f6da97ab5ca71c521a277d9618881563f47792d99bebc73a74ceb5560070b75c3b8b2e2c9598195feb08ebfb5cb1d86a87f93465355a796520d0c24744c7b852bac418fd620d060118d135947d9b174cca55444096ed97fd6442dda02b4a3364732c6818c39a9d199b4cb5a4d3659c8c4851d39db9301047370351c8dc417bc1b86fa50486e759b87c4cc69a8a9ec282909c40f0b7ca0896c01f7221639b18fc3145eae4b4b8252b4af720f1a22c1e5cb980cea6b103082b31b0542ea8d64d8c9b119aef3524cad116689280a51ccc08c09a8c3313a82a581b55cae6a394efb5146ad9884344ab6904c7d5bcc75729a261239c76ebc83e2557f60d125a9578fe0b4ac8d57b08d729a8d86647708483407ba16344049f8b842496a64f84d5bf42540429ade11b10f567eba812aff9179e263a2899b770f8b3166da15bce789dee3cc7d1846f3204b26933d4803b74c3c3885748a417692f0f5ac2733804cd2a98f45547af8ccd28542ab3062211a51f454b28559c28d0751c5c6c31045a8aa41c79cd1cca536c3d6a779afd9175a006b663620bcc92b4ddcc92b61b88bd422f1dc7962a70569dacbbfc7ac9ce90f8d16c3b6973ab3e96b6539a145128631c6993c776fcf488f4ee692772645dc2cc1541874c02aba0564a46176005f6ccf2ab27893dc60d2d44ce1e5b6e317a38c032ad98bbbf79554ef2882fdb51115782ae862c9dc79a6a8293a39135460f96329548507d58c39a07ab9aa7fe913a7fbe4c466f693ee1006f6091346a4b75a2a506f6c787cab948fb76f4398b2110781ae27644211476364abe4ccc2f0ac6cc4e917dd391bd0b369ba862d5f396d8627285b0c5d9b3692ef8069ea601e6e493d841755cea52194b32b5f787f15a6478db7b6b41336000d2bdf3270f8f0aaadab89325b6a3dda4ea88021c8b61b6ba372186321f4f5575f2508625685db168830063860965a71a27ce34a7e934b9444d411da9a151b27b3ed738869100ff19099f0c2a8583b872c8a0745e455bf715b8f526cb4f378fdd931c8111d53a97379ab1d57684224780690b2c1b36bab3b0762b8fb6afcf39cdda151607a6537b985c37989299414b4c9b1894c6051242482b42289ab24793e2d7af2ca0cedbc27d0595b94c698bfa000840bb2d63e1946c2d52d0c837eb40dac0653a5e862d9fb8b832629cece9eaeb6d5feb48b6ef5da8aec87a9a79204cee2986867a2906eb851b734b8b22b91d6749b1a5f07c44e3b" +}, +{ + "dz" : "38a0d5f41d7dc1896efd1b45b0485634cef149828751b96087a0a6dd81b4d58aa2acf359556df4a2abaeb9dcee945829beb71185b4d6bd18b76e5668f253383a", + "pk" : "109bab4be52b48818412eb1353680f2a3c3bd9fa7e55cc79c38207fdaba1833452dcb03763672212953c53532e6051ab040208acd348af507616562d96c7c04da93c8f21566df563deab2f18c9359b0b5391e8b03b485e3dc1a7c981b2a30026b0f83b84c4505a5966f648383c9abd16638a3e557ae4925fbf1c0125d91d97511175895082a78c1272792a50a5651239cb66b3f6c1376fe332260cc27ed5972c4b6ecef6462d3b712627928cda42ce150d3d96b7f032209ca92e9937517bf2b7c5f66e3b837ec347643a6a8a4d8c299de167395c84c2aa8bf1a8a4d5db29c2962701701ead468368b40e87da45dee76ff4b287950889692a838bba17b2b47c3140b7761cb389e447b2a540ae251d61808341dbb2b9aa5f04a69c6010431b28c17b980fd00499e274c9492840cc7a1e90215be92759db8b14ef41c059c546d4482343106adb27a802c3c3f8759a8fa20141fa63c65081d40090eb1abebac9c5708a9ba50656b4e7616151a4f1b0bd678ac18188450ddace2b99b3f170ac2635a62ad88320d17a9a75ca2e1bb52576274ee12f1f3b0b1696a247c70a6cda6264dc9e892cb08548c0c8824168f471e19078737169b4549b62b634a611ad53699a5550635faa7ce4589938501834f8c4856cb2e991bac84809b424cafb5ba089f14338780178d71b1cb7b1ed12c036f727fc2a94e9a62ecab6a95c8800aaa237cfb224af5c8fcc939443176ca4bca59ce54400dc7639e0630fa7cfc292604e6ab0bcda993a78107d108783d19dded13c2033297ff513fa75c4c6d65640206b43f33cac26950533b4b053190cb23e45587509acbcfc57acfadb6160f5345a599caed04eaa02937bd5a5620a5f24e6b194c52da021233b13cf950c270f8262972031790ba4cdb4524bd92781898427b6a1adc7a986f88ddf7b39be1c7d9700c87d52aea9140aef5c6454328f666a8f476b772784c3b13494dab57b06e320b2aa701acacdce41b8b3843e9913ccb3705dab48cb9d85ab5b36bbff148c5a4239b32190193112e1184d33b88ed1e6c3a9ba0ced62bb5e634b72187030bc8dfc1a3e80e28bfcd1828ec4a2e4888d68e4bafa3ba8622a87314432801325fa66c142760272e594de825560c7c19e881ef238bd9a38013f601885e02acec715b25730fb004009eba9111c125bfb0d6b2c154945575743cd66d85906981b24c1b2029452879608a34bce8e610501b6b12f32a1b3e99b76143cc1455485b3802778b7ed52210b976cd2ba26f1551c0fda036fb33891ac77c9265c30db5a513baca1524b8499932d5633b127ab98d8c07ca1704fbc8404957251f11dbeb7000b363255f5aae1261ea5b7c741445cc2852666c5437a4054f5d3a421799318098f5aaa5262b46187f60a09d98442499e30bc54c86838e256c24ae481b6bc33bf076b04bbc798f0615cccbe8eb66dd3c97da6a89394d4c7e07b8c4d5c70a01c9e7c43b8a37c3a09d728d9fc25d933028a504dced76c2a3900ca67369cf5b822107a9ddb2a168419ac87b036064786f500e9e0a279294df8a7c632484723ba28b38b52937b40e20984c46b23dd81bedf629da6a3512ec060fde7b8b2dc987395af460998230c20a9a08c1dfbf3824cf7a6fb4ed55ed1ff461d800b59a6ffd7287e1ee3fb94cb59c39450", + "sk" : "263bae3c310cbd4b6423ac0195592363652d2c1b470a718073e18e08e412286a4df32501e9926d27c43de1135df1281b65c6738afb062d1a0823c01617da701b97a11c26055972b875d29d42985737502ed0551c85f11e2e9b28157049248691d750a4759184ab00b02595460a91acb77a6272d49273c35895ac796eb6406999b8d5b824617393fac877749ca787456211fabfd8c1ce7775ba14c51bfb2ca962b6a3acd7ad4084c90d000cef83aba7ec45910bbe37598422c8419585111055c99af87e08d5656dc5678b488fa9c96d366b5e6c2a5c8d900f40bc69db4a9fb9021723e043d42b089c68831a0525c14c8e9b192b14b83962b7662202cc753aaee4d18e23846e4ec1cdd9434a77a47a69596d8b5b019c60568a63734384b83a9406f461b9f940a9e0d3add5d21ef67c8d8f8c83259952c3cc86c35403fd713ef26a9cd239381ad4370414506edaa2da027b2821ac9a8c4e5a661f06038ff4b209acb4a71b916386a928a57183f9a5515b704aeec9654b7c17798c57c07911a038bb9b7715c0ea69cb3c9baf14a0bf881e6ca1905bd405e876234102c572db0b7c705efc93a49d82303de400003897c3f9196c758701a5946c947b32709268a9a265841408f038e280a9b441366f983316cb5fc5109c29b2320b156794ec3233a523bcc5b1e0ec6f0158c4346ac04078c244375ae8c8ab9b57296450aa75d8231ae3cbeb21a17f29c8d8fc628ff315bda563961a2014338d294743269c4876689eb938141d31001f932440b0a0aa079b6f3c82553c5350827a4a768c1fdb5e75253423d95043989cfeaba0ec544da71ac75a62a3d4d5600914972198cc95bcb1e4d04c1f4621ace5c02b1b0536b0350fc09b23ec125af05e92cc08362b6e1c1142484b736fcc46f4233ee2c52c2f810ba3148d74681fd5b158068cae9d701819a16917c81cf3f5a31ad1873930b59294c32d915791510ef0d8c8ac8a6cb4673493aa6bda6a6244810bebc286cc8020cb86cda351caf9e801d9589cf29b9cad0025ce563b1aebac4362b176c8a6c4349ff62124c53902b2c10636c88d612133e872759631b31d4ca637bb1670377ec7b97444daaebca78664188885c134fb04205a266895b7909e3271e141ad62090d5696a0221415e5a711a7ac0a9512a1c528767bb617bb79b9aa55b47cc2acb573aff4b4b5442bc573a8b9e937ad1205a4e6311834899caf3824eca782530186209c25d7e810c8f6c5b4559f436c7365642d28933a3a1234415b9728c061365c74b73ccd3e36222db3747c289d13942a32ca6fb1d7a75d563097e91399a2b967c3737962cd1fa0629f2b774d25a2021b458524b3c2f8344ebbbd2b7a70f7ab1574158e89117f3f8962aba45bb0cbc297ec3c2cc546096078894308310241b8ecce3fb787219c9e0b7443d622330877bf8c4c9637c6b9aedb75cb763356eb7772ba5664791d4f439e6a317b1066452d698dbd235fdb4ba5c37ba57ea8be97849345f7b3e8d56485329933b9b49f92a1a67b67c15c72a3b0cf05f36bfb2567f70ba9139cb6729212bb6b48b71590513bae6489b47c03220a72af6094045293ca3623842de85677c16aa910b9de06924dd3986df541109bab4be52b48818412eb1353680f2a3c3bd9fa7e55cc79c38207fdaba1833452dcb03763672212953c53532e6051ab040208acd348af507616562d96c7c04da93c8f21566df563deab2f18c9359b0b5391e8b03b485e3dc1a7c981b2a30026b0f83b84c4505a5966f648383c9abd16638a3e557ae4925fbf1c0125d91d97511175895082a78c1272792a50a5651239cb66b3f6c1376fe332260cc27ed5972c4b6ecef6462d3b712627928cda42ce150d3d96b7f032209ca92e9937517bf2b7c5f66e3b837ec347643a6a8a4d8c299de167395c84c2aa8bf1a8a4d5db29c2962701701ead468368b40e87da45dee76ff4b287950889692a838bba17b2b47c3140b7761cb389e447b2a540ae251d61808341dbb2b9aa5f04a69c6010431b28c17b980fd00499e274c9492840cc7a1e90215be92759db8b14ef41c059c546d4482343106adb27a802c3c3f8759a8fa20141fa63c65081d40090eb1abebac9c5708a9ba50656b4e7616151a4f1b0bd678ac18188450ddace2b99b3f170ac2635a62ad88320d17a9a75ca2e1bb52576274ee12f1f3b0b1696a247c70a6cda6264dc9e892cb08548c0c8824168f471e19078737169b4549b62b634a611ad53699a5550635faa7ce4589938501834f8c4856cb2e991bac84809b424cafb5ba089f14338780178d71b1cb7b1ed12c036f727fc2a94e9a62ecab6a95c8800aaa237cfb224af5c8fcc939443176ca4bca59ce54400dc7639e0630fa7cfc292604e6ab0bcda993a78107d108783d19dded13c2033297ff513fa75c4c6d65640206b43f33cac26950533b4b053190cb23e45587509acbcfc57acfadb6160f5345a599caed04eaa02937bd5a5620a5f24e6b194c52da021233b13cf950c270f8262972031790ba4cdb4524bd92781898427b6a1adc7a986f88ddf7b39be1c7d9700c87d52aea9140aef5c6454328f666a8f476b772784c3b13494dab57b06e320b2aa701acacdce41b8b3843e9913ccb3705dab48cb9d85ab5b36bbff148c5a4239b32190193112e1184d33b88ed1e6c3a9ba0ced62bb5e634b72187030bc8dfc1a3e80e28bfcd1828ec4a2e4888d68e4bafa3ba8622a87314432801325fa66c142760272e594de825560c7c19e881ef238bd9a38013f601885e02acec715b25730fb004009eba9111c125bfb0d6b2c154945575743cd66d85906981b24c1b2029452879608a34bce8e610501b6b12f32a1b3e99b76143cc1455485b3802778b7ed52210b976cd2ba26f1551c0fda036fb33891ac77c9265c30db5a513baca1524b8499932d5633b127ab98d8c07ca1704fbc8404957251f11dbeb7000b363255f5aae1261ea5b7c741445cc2852666c5437a4054f5d3a421799318098f5aaa5262b46187f60a09d98442499e30bc54c86838e256c24ae481b6bc33bf076b04bbc798f0615cccbe8eb66dd3c97da6a89394d4c7e07b8c4d5c70a01c9e7c43b8a37c3a09d728d9fc25d933028a504dced76c2a3900ca67369cf5b822107a9ddb2a168419ac87b036064786f500e9e0a279294df8a7c632484723ba28b38b52937b40e20984c46b23dd81bedf629da6a3512ec060fde7b8b2dc987395af460998230c20a9a08c1dfbf3824cf7a6fb4ed55ed1ff461d800b59a6ffd7287e1ee3fb94cb59c394504ff02338c9bb711d263140c471409f3c42813f38424698563d9550f85a168f2da2acf359556df4a2abaeb9dcee945829beb71185b4d6bd18b76e5668f253383a" +}, +{ + "dz" : "97b5665676e59e3538ebadaa8cd50df1f9fda1502d9894c616a946078e56b621df05318b5f655efe36f1b678cf4b875108a18db2fa312261caf839f84bd956c5", + "pk" : "034626f03687751b2f1abac22b4c2b1ac19567f3324fca5d82b147af141a004514d831039a612ed69b621ffb4223109171e6351bb35177b85bb5063161273abf861988a1803e647820bb53b282bc6d04cd3e075a4a1b6755b97251901a81c7911437c528951d007d9ed82368d4c833ecf2aa1a806cbad08259470461f7774a922227e812689bcb59a3483c8346d130650e06383556c067f94d41dc1171941efcc96e3fd769623861bec9bbcca4a5ed22c10a36a59efb5d7153859df348ef9c3a2745cea329a73cb831441762820c7d996b88c1d453c775a16ab2c752e68bc55839d2e79544b87af56019f02b794b166f6dd60e8efb0b14f00d1ae800e37bbe5ff7c7d47a257adccd2949cdc3d9318a0cbaa34a14e080b968533ab1d9ab674c89774187d592b4c86461e84ac0e6808c96090abe6b0cf69a2056a1c4287b1cf3dab74f8ca66ae8421fa200fbaa4b11760ac7529b92db75231958e20a3f55b8a3396a10fe957361a9bf41941b90583d8d97cade8828b8a3a5ebc36730c19fa7346aa427c489f56c7cf3716928c9082b36d3f3b82ff1348eaba325ba8c49acb2673570dc5548229ba93a5c210b586ece088d6679c975b60e0106c0003625e42c1bafc1ac1be1c1779556a95ac68776ca01363961132ff75c2185339d79a426e6c0a0011a260acb7cc0583e71623b251cb8ec1049da730c2f9a26a61075aac24ab1da2732f708221a01b27c9da1b520beb7686843360a11a292568993c28bafc7088c1767b87523e9450873f9c73912cae517ca29c066631137faa16d217ccc07f840e1013440da2ddaec6b7161b29742a2c941c7573bb0b57a58a25b00db5012a3362774fb35cd80c6f0a095753688b156b510561ca47b436cd5576ee0323f2bb2967022fe391b9cab3f41477787a96ec6667337fa4ea29b44b7c9610ab69706e820557ac7c9f9c55ab4a04fcb05ecc4157b943bbafc0b0e42567f95b8b436838d363da680a42ee01cd5353dd4276b4dc625d492aec385bfebe9767a2731fa8b3ce9271cd8d28042b66714d98d0bc0675a54b3ea3c322830a5616816c43260f6f21947e3499dfc4f9d76a7977cb467899b455a12d8628e93acbfed99cd8b813d21a15024da9ef46b1ae4f6333dc8933b52a5f100bdbdf2b23987270d550493d949e83a269ab42027b34a12a177f185af5f76ac9f9b1cf9ea4eff5529e0247d3abc3ca08b3a1d081a8c75a1ffe4337711759d25b9cc673b0263177ea93b56667c15f82b483702973c6436d40953aac60929a36a911ad25ac109a10841fb95e1ec05962c5694cc3cd7372260ea4863109254c26a44f62af0957960634354f62c624c5723416f14966417681fec883ae47544b753340f749b487a095f89784f15a6e7945da56c9e0d2c358162213403609a1c938c98c68b70a0fadc5aa746ae4ea9868f19b9ebc3282ff592960b436a7a7301e4c7fa075ff50762b866c4a9f157ad25291347a9dba5cad62c35b28a3933f5269f33a0e6d403e5721a0d36bae734481c43918f9b13acea8f6a13b1bb584938284c10e3806ed935d8e543fd5bbbab0685f099c2adf254f4906d6e05590dfb1544a32ff3bb766109561ff31c164792b6b0991fa93c14a74086a585353c3e620d3ec5b1da6ff7959016b53093137c512dfc18", + "sk" : "4fd2be0ff2ba62ba7ddec6a73c032e9a15cd9db841b4791620989c38508bd6733c15c206c84402e286ba0f2b274b94ad18a5ca003d7689aab71ef8cbce7b75ce844622fc9f57b974f8991a89032206f59023002c938c6d66622a7033442c190134d06f04339fa61390ceaac12dec5d0e5275456873107a8cc1ea6d5e5450aab97b23a06e34c8a812cc29794897a20bbfe7790c3404c25dea2fea4c80f102ad1e750780dc79010811fe680bb1c8000ebc930ff8257f912140db9e0a9c5c7410388384591f500bf0aabc4258272deb2871bcbb85757e9afb2699f45142ebb80ba8ce2fd095cccc1952579a8a67bb57f78e2feb4e484a96854a8d4d16bea8c08d04f91f31779e0df23222f5768775c026148cb1895b970cab860bac34aa6612e8a5b93c5aefc78e408a0312fc027f7a509d6c12b55453e9cb2f4e5c4360a4ab1e350f8122a008f69cf2796f6b72a58e388921863ab2fb82ae627c60593a99a4ba7806572dca7179476b16d5aa6adc6ccc90ad700cb1304c2b299c1aaf09369cc2ce8a9c31cb799185c24ad16967fb1269d0dba48eb0a258d4c37f9484c9cc8d214232f88b919de59ffaf6c00029058efc1e4fe55a8457b16d3c49017c88909c0eef37973a6b2e55d19b8114b074d8c95a57c5d897c87f024b3bd8578c7921536b1b45c19484e220ed87bc647c57aad958e01c74a433074a660de8824060108b1c44cc45486f0ad2c00fb79a7d88a2eff62887a3171d132e441cbaddf2bc1622045562a893300502779c3cf072ddf61187d42da0acc451e6b56bba37b3da8f1b105483955c7b169f89db86e7fb04a493b69567bc5a8b8655c919f8a70d6ee1034c1478effab227622029f5997b14696f4bc4415b6771d3701b461e76d686c93699c96165b00a593d69827bb39a256a1385d8b77b2222a5c920a6864ba5f413800c95f2ea9c303a064a173c764437eaf13444ec34192911400506158a0ab1c56399c012c30a7290cc0b0d330bad27b8c0c80b7dab5ed21c38459a436b5a5b2b0822726815180395dbe69a472672fcfa17cc331ec910096480affc8c667bcc7a2ca92e6ff80b1735a5959810dd3a5fe9938836d1b50d772a11c1b126fa498009b730139c3a1c9a22d12a55f1755f81ab7442399c8bb509775a24b3987e4432fb3a4a22fc7da509578c34302ae845b818894c7a6283d71d42657544b558f74b7977d270be722b9a51bbbdc236deb8898c65a92457b260d3816f57030f510e4f885450da20977451b2a731ded6287fcba24b4c7f09e4a7532965774c0578eabc13d1b123542c1d1b6a710bb3b55038a28155528caf974769557318c617306f72acad23c7c475b9a568c70e7552b65917217677fe625b15548be7465b147c60f857a832d08ca770c83ca3b201ec1e8ca1ba25630997a69ee54921e7ba611ea1c0928c0c99d65d0c0a39f2e18f8ff9980044477899411410a48ac2c6c2893e83c19f7f1080edd9058270374f0aad2f794655f594b3cc15bbec6db0d647e45805318534c4da9484ea4d55464da7231bdfd31e9bb6c53e35a6f0764ed3443823f9991ca3aff1caa50edb522c42112ada999dca8a8e678ea1a8417d77920f723061c87cb29a55034626f03687751b2f1abac22b4c2b1ac19567f3324fca5d82b147af141a004514d831039a612ed69b621ffb4223109171e6351bb35177b85bb5063161273abf861988a1803e647820bb53b282bc6d04cd3e075a4a1b6755b97251901a81c7911437c528951d007d9ed82368d4c833ecf2aa1a806cbad08259470461f7774a922227e812689bcb59a3483c8346d130650e06383556c067f94d41dc1171941efcc96e3fd769623861bec9bbcca4a5ed22c10a36a59efb5d7153859df348ef9c3a2745cea329a73cb831441762820c7d996b88c1d453c775a16ab2c752e68bc55839d2e79544b87af56019f02b794b166f6dd60e8efb0b14f00d1ae800e37bbe5ff7c7d47a257adccd2949cdc3d9318a0cbaa34a14e080b968533ab1d9ab674c89774187d592b4c86461e84ac0e6808c96090abe6b0cf69a2056a1c4287b1cf3dab74f8ca66ae8421fa200fbaa4b11760ac7529b92db75231958e20a3f55b8a3396a10fe957361a9bf41941b90583d8d97cade8828b8a3a5ebc36730c19fa7346aa427c489f56c7cf3716928c9082b36d3f3b82ff1348eaba325ba8c49acb2673570dc5548229ba93a5c210b586ece088d6679c975b60e0106c0003625e42c1bafc1ac1be1c1779556a95ac68776ca01363961132ff75c2185339d79a426e6c0a0011a260acb7cc0583e71623b251cb8ec1049da730c2f9a26a61075aac24ab1da2732f708221a01b27c9da1b520beb7686843360a11a292568993c28bafc7088c1767b87523e9450873f9c73912cae517ca29c066631137faa16d217ccc07f840e1013440da2ddaec6b7161b29742a2c941c7573bb0b57a58a25b00db5012a3362774fb35cd80c6f0a095753688b156b510561ca47b436cd5576ee0323f2bb2967022fe391b9cab3f41477787a96ec6667337fa4ea29b44b7c9610ab69706e820557ac7c9f9c55ab4a04fcb05ecc4157b943bbafc0b0e42567f95b8b436838d363da680a42ee01cd5353dd4276b4dc625d492aec385bfebe9767a2731fa8b3ce9271cd8d28042b66714d98d0bc0675a54b3ea3c322830a5616816c43260f6f21947e3499dfc4f9d76a7977cb467899b455a12d8628e93acbfed99cd8b813d21a15024da9ef46b1ae4f6333dc8933b52a5f100bdbdf2b23987270d550493d949e83a269ab42027b34a12a177f185af5f76ac9f9b1cf9ea4eff5529e0247d3abc3ca08b3a1d081a8c75a1ffe4337711759d25b9cc673b0263177ea93b56667c15f82b483702973c6436d40953aac60929a36a911ad25ac109a10841fb95e1ec05962c5694cc3cd7372260ea4863109254c26a44f62af0957960634354f62c624c5723416f14966417681fec883ae47544b753340f749b487a095f89784f15a6e7945da56c9e0d2c358162213403609a1c938c98c68b70a0fadc5aa746ae4ea9868f19b9ebc3282ff592960b436a7a7301e4c7fa075ff50762b866c4a9f157ad25291347a9dba5cad62c35b28a3933f5269f33a0e6d403e5721a0d36bae734481c43918f9b13acea8f6a13b1bb584938284c10e3806ed935d8e543fd5bbbab0685f099c2adf254f4906d6e05590dfb1544a32ff3bb766109561ff31c164792b6b0991fa93c14a74086a585353c3e620d3ec5b1da6ff7959016b53093137c512dfc18bbccdbce67cf49fea044df5c767996681dd2714937d31c822f3c58cc34785aa7df05318b5f655efe36f1b678cf4b875108a18db2fa312261caf839f84bd956c5" +}, +{ + "dz" : "ef99224a03a85a46ef115474ec5b5d620da6795d6efcca4c9135d19958a9de62df7d92dda83e6b2ef4cce08c9134563063068a196d7b1a1a13623e48ae12528e", + "pk" : "cd187009317a52773c57d435faf794021bbc709b8e7d688a5dfc686c15931221a9016c3bb461a487982ded37041ad0c1d032714f7379e2fb9faf5aa6d0f5469c7156800ba258fc5b25d0996b6735665a806a74b03d9819a5832a6685157e7285df397e23b13a543a983a5b24264c971a73708de1572852465732c94830719c197c7985c0a7c53525a1ae76d18e1e9112eb4b57c1222320a8156643cbc9535a27658a3709123cd61af7798addd888053bb0de254eff530296f9ae75b2ca756539b61c62decb0e9ae611678b5190503344229096c34990a61ce8b10ed3841d48d266cdc249acc96b7d88010899c453467213d8bd23e1764e0237480c34d8396ef57c1aaf781c042471d04077eff85338ab8caef22ed064bc38164070a00cc78b8074e7569a627b49e0416a705386601d3b8a6c10a4adcbb190b4877422304ffc776b4a129d4098c603896a6020725986cfcf0083fffa66eabab82db734f5d1b5766104e8a2b8b859b6cd166dec691ae331b87e794a1c9b083c14b50b85b7e97148745c9f8975733d4262e247473ce53b85d01c6de505a352bfc0c233a396c87f856981c83fb74542c9f3cee1276f3096486ef23359c51ac553931b80c6bd245b2114c4a2d344ab53765c02c82b41412afa1ad5ba6ccee9bf09e375eddc0cd55bb6c727be26bbbc4e7392293c59455084b1542c87578c63511ae3e384e027bc07ca7401cb0096d1205f4ca86d3c73ee8273de930799369133f83f4667a92e72bee2655b17120dee233433f9c68a50c57fdc8617ac1d03f0961d4a7bd17678d8729329a0ba0591ca84670557e15fc5eb4e8255007b8c4e48206f62062e1dd53bfc43af02405d2e300d4858b1b9c9ceb531a910c0bde877450a9aaa8878a2fa45089e184d1fec1cf4e3909670bc11e78da5d8cfeb86a4c087a1b73a6099c99836b3cc76366d35a9854b3b205f4b2b69666878614117163fefdc32b6db37fdeab0a0197f79db088c3a355877cdb1313a2f200e27e37e12b4bfba04691f82b1c2e8b8172c11e466cd8d01286f2a3a4fe5a5f920476a9278b9d25e420b77d489386f9c167f2731654b19fe4886867b79ee10c18f679fae87826a0b65b44a83da5a35e0723bda3467541228b80b35d5ab869b52b5dba9b8b309360ff1022d67bc93747c392469c28b288cb73fca74001e5bb47d5b0321e08fbf832d0a9b0dbdf566d3898e1f9aba7e3c011a14c3e918589282c0f167bf14470d1f6c774e6742e40a1452c70cafb941624c02ad201e6030bf3dc6a039e6465d6772d1c184c693bd16c3367f02730ed6beb95940ff783cf9e307f38a7f4f37754f6c4ed26a1c70c90741ac89e56c989b0260f7e1178b5b975d54aa6f420e97a7b90c3c74200359d561beae98b1af044be40a2ad8491f42662e2f34bde200c63ca48e7409727c8b2185138ae7859ce43558349a1f3e641df0c14428c0c12d0a49abb904cdf8ae5cf34d379024ed528e5d84a3d25920b7a94b61a8abf9e557ff61c784501fc9e332f2b652f16a0a11148b8e594d1f377035e124d637659d4485d909543818814fe7a8a173bc8aab7066d2c927c90660dc8d30364d60a31f1d94a9e5f586cd84c167e2577d3326e41a614382f4982426e93391380c4b03db38d0f7bf0ff66d2d93c251d3347c64", + "sk" : "999942a0ab8086204428a2098a205a297265ef3b725de17ce121512fba2225b20c2fd0147cd903dbf08722201c4575784a5370556715f8ec09eaba14b38863c5402b9100407b35375098a55f568ff0b4324b43098debb5085558fda00084584bbfe68d94280636809f8d408256913d32152710a132380243c74455b7f11532d3b88145cbd61745aa7683bd204c4e035d526a488465170fa86a099323fce43b78b4a3b959a1b1ec25d4593181dc22ba883a9f080316c23d07d1490daa68c8fa2f43533635439b5bab445a6c1df2a2c22aa84355556c80a9877ac9453469b02d998476d0cedddb9f3d05c7c6f99253ab62109376dd9b384b26786872030d95c23b3cb38238066978b55f2746124a98d90bcaf1c958e08b108f6714fe7658f6e0a67cb875522090856761d47189bdecb13c7746aae24c12294db2662a65d9241b513cf244223ec0ac4be18935c788e04421da1071611a3349843b7c760ce3568413756b7d838c3f3827e167b1db27bf0546606ba6bb7ff11a2e7b86186946cd00d0fa143122729efa29adef75c499f2c719e985e6014b110373ad2164ef7a85e78b7fe1dc25ed60027de464f3c133338404bcd89f2680c639d956be5a8cdc6254e670b5400139e0c136a132763f6c6664a6b9283b03ef18c809d94347187d91f97bebd0bde9134bf0414d219895cbba75c9b262e6e62ad70926816bc02818c71d542ad6e3bc2e58796d7a90a4ac200c1b135940b4d0346366763c2672ac70c03b56a62afe49a1ef043fe9657391b7274b6ba05e3184fda8125b412c46f986212ba2948b6db9130f54fc33f9574f7a82aeb209b6441886ed83816c173ec9826f8fb6c8e36237d6b32376344cf01311346b19eb502a6cc61811d6728ac3288fa5c576380ee2286839e4a8a01761fde8a2fb49a3dab98bcbfa9633a2bfeb116072c479ddd28891305bca71ae8622cc89dc4733846cfa56cd2ecb4d60623b92797bf8d8b2dbd2b74804c7cea19f40b67394c46b46906a44a5b669d95d4514a95f6327465baecb8a439114070884338485468b36b103c4af5ce9c1c9a09feb2a2f9b7324e703b23dc63192422e5b2c38228c36a3cccf39777d2015496972c6c618a296908cf6eb54169a479d5221679a7829e27c92c5550a4156d5631450753beb34cd4ba8ca8949a7390a4a2e4abce4ba418525620b7c9064d82f8d080a68f058d847bf69833cfe025f0e090e185234b6f6a260c7391c97b57222606bd0b488d37ad71774636c9e1ea8a449958c1b944e76f48fc8401deda708bc039a81c497c2e028b52a714b40679563263305bb432b3e120bbc561b121a2026569951986c94000235e96a2fbb70acb7a50a79c06947c02db12609208c101bab9e63d449c1c0a0faa336d7b0c1ba9c84b6518863267ee61624669938cbe07eec601ad3649675ca12cc307724db6ed5a60766f423c47100b75c41deb4bb78bcb19d4c486c098279d53ce0e6295086ba75525e22d3551450cfabc72c781008cfc5830d6c603311abbd81934e874b1c4a55e4884cbff57dc4ba0549724c7603258ed6b63456af9bfa0bdcb3ca86b09ec25aaf41911400e8bbe409604ba8919cc59b8916c8c8745c2e8042cd187009317a52773c57d435faf794021bbc709b8e7d688a5dfc686c15931221a9016c3bb461a487982ded37041ad0c1d032714f7379e2fb9faf5aa6d0f5469c7156800ba258fc5b25d0996b6735665a806a74b03d9819a5832a6685157e7285df397e23b13a543a983a5b24264c971a73708de1572852465732c94830719c197c7985c0a7c53525a1ae76d18e1e9112eb4b57c1222320a8156643cbc9535a27658a3709123cd61af7798addd888053bb0de254eff530296f9ae75b2ca756539b61c62decb0e9ae611678b5190503344229096c34990a61ce8b10ed3841d48d266cdc249acc96b7d88010899c453467213d8bd23e1764e0237480c34d8396ef57c1aaf781c042471d04077eff85338ab8caef22ed064bc38164070a00cc78b8074e7569a627b49e0416a705386601d3b8a6c10a4adcbb190b4877422304ffc776b4a129d4098c603896a6020725986cfcf0083fffa66eabab82db734f5d1b5766104e8a2b8b859b6cd166dec691ae331b87e794a1c9b083c14b50b85b7e97148745c9f8975733d4262e247473ce53b85d01c6de505a352bfc0c233a396c87f856981c83fb74542c9f3cee1276f3096486ef23359c51ac553931b80c6bd245b2114c4a2d344ab53765c02c82b41412afa1ad5ba6ccee9bf09e375eddc0cd55bb6c727be26bbbc4e7392293c59455084b1542c87578c63511ae3e384e027bc07ca7401cb0096d1205f4ca86d3c73ee8273de930799369133f83f4667a92e72bee2655b17120dee233433f9c68a50c57fdc8617ac1d03f0961d4a7bd17678d8729329a0ba0591ca84670557e15fc5eb4e8255007b8c4e48206f62062e1dd53bfc43af02405d2e300d4858b1b9c9ceb531a910c0bde877450a9aaa8878a2fa45089e184d1fec1cf4e3909670bc11e78da5d8cfeb86a4c087a1b73a6099c99836b3cc76366d35a9854b3b205f4b2b69666878614117163fefdc32b6db37fdeab0a0197f79db088c3a355877cdb1313a2f200e27e37e12b4bfba04691f82b1c2e8b8172c11e466cd8d01286f2a3a4fe5a5f920476a9278b9d25e420b77d489386f9c167f2731654b19fe4886867b79ee10c18f679fae87826a0b65b44a83da5a35e0723bda3467541228b80b35d5ab869b52b5dba9b8b309360ff1022d67bc93747c392469c28b288cb73fca74001e5bb47d5b0321e08fbf832d0a9b0dbdf566d3898e1f9aba7e3c011a14c3e918589282c0f167bf14470d1f6c774e6742e40a1452c70cafb941624c02ad201e6030bf3dc6a039e6465d6772d1c184c693bd16c3367f02730ed6beb95940ff783cf9e307f38a7f4f37754f6c4ed26a1c70c90741ac89e56c989b0260f7e1178b5b975d54aa6f420e97a7b90c3c74200359d561beae98b1af044be40a2ad8491f42662e2f34bde200c63ca48e7409727c8b2185138ae7859ce43558349a1f3e641df0c14428c0c12d0a49abb904cdf8ae5cf34d379024ed528e5d84a3d25920b7a94b61a8abf9e557ff61c784501fc9e332f2b652f16a0a11148b8e594d1f377035e124d637659d4485d909543818814fe7a8a173bc8aab7066d2c927c90660dc8d30364d60a31f1d94a9e5f586cd84c167e2577d3326e41a614382f4982426e93391380c4b03db38d0f7bf0ff66d2d93c251d3347c643ef3581d438af7dec621304e0091f797346ca18a41f39401e9d03200ef48beb6df7d92dda83e6b2ef4cce08c9134563063068a196d7b1a1a13623e48ae12528e" +}, +{ + "dz" : "b12f6fd965ea9c5b947db80fc60c83d5e232dca82e7263027c19bd62e5a6ff550f6aa3e88f7fa8a96067f8cdaeceeac90c2d0b5e277e56e9c405ec9420c30252", + "pk" : "d8b6c56dc931d12a8092102490881b4e2064c5a9588e257834c1aea2668e69d907db5158c3cc7321d83b9703cb74864c1057660b718c3412cc47bb92612643313c356b6b2cdeac80ec5b657e78cb2fe9ad14c28747e45466847d71c49d1355aa845a5c0fb27160156d49a3af1d8b975d694186b06a5b1111ac504df3f91ce9a4b2e248697f9a972e7b0cd048c1b6f7581af20afae4c1b9333f60e73a0dd1ceb2e19887cc712d0bbb5c24054553c3c7c972e87253d4c46c971826e8955ac0017ca6d6550335916d6a939f5c167bd68c09d85650e89b40a4686ff0bbd921ac3e43641b1600a84bad0fec9524f09fc920916a31b081e88a36803715b1476e57ce39ec27fbb04256ca64fd11225e474b06bcac9657b31de3a39f4cab5b65bcd8896655eb924243972b0bc9b755b0c69b837030a07937652c8c14f71745572882d222ba1208327d3228f0778a215b8fe6f4a14a9b3a56ecc56f09c49ca31cda853db12a2fe5d395a00cce6621833e61c2cea5bd6f0bcc6ec6b479e334fa543229b619be566e8c00a1dc7837c7b5651b8b6a94412ccddb63b8213635a5745a54bb56198d325a59109c75d2b733c77738a1328bf1370ed99b7ed8f611e69c3ed82620ce95088a91c6c6d472294260a1c5455291188e010a9467c816938f9835c1a4fa01223494c885642e5c416c82223d614a108a1128e53d9b264d61d798c4ca9bf6abc72fe779346a3208a77542272b591a6ae781996ef17961284666c85ba91b2de5f0bf9af10eb91c5793e48fdf367f46f586e05b2dd65b262506043de419482071dbaa2568256a14825b8f094b796a527fd25b8071a4041a1be279c2e3f543021364a147cff6740ba448b7010b4ddba6aa90265a95905f141a9374970a1a071799d813ecd77073b453cb2b6d83ac9cb8267a5861b9e2f23d345581a074657554781e4782d98333f1237dcafa48087aa66de4209a9a78700b09d44a0b5c929ae6612acf6b5d8ad20404a161fdd3639e659bf88291d41711015432f0e7ac759a67e0324f94c1876314687ac377ae48a30b48ba9986714ef3064f087c953ac6f86430bba9cef9857b849315dc4379799092af4c5531fc13f63b186939040da2233be05371d448fa748d76f98c3f638a6bf5864b9bc5fbe496d72966e3004409e420bc4353a5d55d0610843d0b8e6ee5bb5d6c4dd1462ae99a43df586b398a15ff5b5ff58a4006987613f5caba694dc0f736f6d47af66673e8f308a6044338d23c817c0420e679ef621739e21a4a35140dd2928e79584f787671b118e9e71e1d9430b9a3210e11c266876a44c7082e7ca5f6dc4b8d931f5bfa302fc790bd424cc3643844418f6c090e2cf5bf60f08c489bb87315464d90006375c34a5297a238a117a8770cb9795776c11f8a54ff13adb3fa77df3757938c28d03a612324858a11a860235e0e15284e36035bfc0178db841c679a47b93e3b09a9f735955d6bce328a91f2fa64273917b7371fbf166c47e9683776aec02251eddc84032cb0a852594f4c7875792fa345a43a68a193c51492a39c306b02f22c60ce5a8468c3050cc3965e2982e32b938a31cab1f36c1da3ca723261be3a864e2912199262c46741fddca501df33d04a79f8e3017e6197ab24b062cd98486dce2a7ffb22e5798643cf9ba5", + "sk" : "c0b38724691a735c3fd82033d0535c3758a5d4298ddcf542556b73ec6009c4640f5c26471849a2289c469a975839fa5d4b389e75f8423a4633ebd29d8d1a5c19e609f12240edf33ae9c07cf93c18950cb1dbb07963d69dd1e2447db0500255098cb88083a633c5181f75d53a7f0681900747c8eab98d3aac6ff35d2bb01c80a1cb4e5a654a852a07614da10c5ec8071ac3d6394b3a13d47312f03229604c682f05245cec41b3b55098090b6044a1a3c0af26ab4a6ba21ecd50a08d8723d32563c36aa8c3bb01fa3798c42aaaaadb9d0ac8925342264dd4072db982309c0460d7380f02cf5ec0afe3fa13c7297337dc205c0a1f8b3109363765d44a29f1a7bd2b17c24c3130c26a8b872575970239ef12352eb15aab0c9a96b5c51f47370aa5372bc97a22a4029ea0b9156622903354f5a1cb3d49693a198413380075174d2969a95831b1051ab40d1344d809cec691717579a1b7eb52c9087d9244cf9ae6bdc32766b694708d1ba22fc76b042a6f9ad668971b4767e6a54a95290b699a04788edea5c914e3cb431337c0736efe7244d139bbbba28ce82b72ae92a23121b7560c9db5b908bd12539890a172f4c68f381d1c7b562b1b5bd88046359c29dd933ba1ec1f47bc4c485c8dd599767822ca7c4cb300954821695eb5eb2f87fba33d61284b187ca6726a1be742286959e38456594763f5ea53b9a7959382c348c7449783b5c784522f44aa3c25bd21d48660f78f70a00e49e59bead90c4c8367c22981d8ca6b5c198cb5906b12c55915232afc1a4b1ce5c4ff346f5f536fe68ab9d816c98dd6c5ee103d251874b4cb0554f38ad0712ba687634882856d453daef102d3835cd81b5791a50ed5934a0734a81fc78c6ea23ab2d96b679866458c21ed50abce98875167361a62991052bfc7123cd4f9b5e0e98c4266536573742c431d9d343bcb9a8bc1e2a927496a71d73ab6195cd7194d31ba631d025570725e6b37abdd60a545d2cd2532b32a9548f1a319df6184614405832954d89a61dce3b5cbdb1ff691550117402c027da07b2b5bc20b25ca36b0e70d45771e3561526950a8216a7f09db88ee46578a107ec0a46f932751d77a167c4809c14ca056923d2f540692c9b8de07cc05a55aa5aca7607a5f5b071139620ad4309e2e3a2995a31059cb8f3d09b65f171bc3740df13cc63e51bbc33b7922951073ac3e51013b39a0464ea67a9d5a76546227ea7974e1b61847036d94e13201644d585cc7b4c9aa301980eeba05e9e21dcc5163f7802dd3557e0fd6aefa1305e2f84bc42c8fc057a4adb58d3545ca8d767ae622cf7bd3c3178b92c5e776695ba375fb841e12760656befcb915d6a51f2cac896d7380a879a41001ce067a602a73cdce00a4321aa880b7382407c3da7a3702f28a098719e3822d6d8c12c88b460e691dda17bc4f5b589f2b46fc773fefa492e1112cfac69392c80abc1084e68903be87b76364caf5fc82039015bef0c9fee65311407f970b695c8759287898ea39bba8f61fe9d48936b1935b2a2770d498fc2bb22df5980904759ba64f05230378266c8114a7b3a1a5e33129efb4a52fc163628c5c1a65a0441325b3f3b8bcbc7dea5c42c7897aa8956473d54ed8b6c56dc931d12a8092102490881b4e2064c5a9588e257834c1aea2668e69d907db5158c3cc7321d83b9703cb74864c1057660b718c3412cc47bb92612643313c356b6b2cdeac80ec5b657e78cb2fe9ad14c28747e45466847d71c49d1355aa845a5c0fb27160156d49a3af1d8b975d694186b06a5b1111ac504df3f91ce9a4b2e248697f9a972e7b0cd048c1b6f7581af20afae4c1b9333f60e73a0dd1ceb2e19887cc712d0bbb5c24054553c3c7c972e87253d4c46c971826e8955ac0017ca6d6550335916d6a939f5c167bd68c09d85650e89b40a4686ff0bbd921ac3e43641b1600a84bad0fec9524f09fc920916a31b081e88a36803715b1476e57ce39ec27fbb04256ca64fd11225e474b06bcac9657b31de3a39f4cab5b65bcd8896655eb924243972b0bc9b755b0c69b837030a07937652c8c14f71745572882d222ba1208327d3228f0778a215b8fe6f4a14a9b3a56ecc56f09c49ca31cda853db12a2fe5d395a00cce6621833e61c2cea5bd6f0bcc6ec6b479e334fa543229b619be566e8c00a1dc7837c7b5651b8b6a94412ccddb63b8213635a5745a54bb56198d325a59109c75d2b733c77738a1328bf1370ed99b7ed8f611e69c3ed82620ce95088a91c6c6d472294260a1c5455291188e010a9467c816938f9835c1a4fa01223494c885642e5c416c82223d614a108a1128e53d9b264d61d798c4ca9bf6abc72fe779346a3208a77542272b591a6ae781996ef17961284666c85ba91b2de5f0bf9af10eb91c5793e48fdf367f46f586e05b2dd65b262506043de419482071dbaa2568256a14825b8f094b796a527fd25b8071a4041a1be279c2e3f543021364a147cff6740ba448b7010b4ddba6aa90265a95905f141a9374970a1a071799d813ecd77073b453cb2b6d83ac9cb8267a5861b9e2f23d345581a074657554781e4782d98333f1237dcafa48087aa66de4209a9a78700b09d44a0b5c929ae6612acf6b5d8ad20404a161fdd3639e659bf88291d41711015432f0e7ac759a67e0324f94c1876314687ac377ae48a30b48ba9986714ef3064f087c953ac6f86430bba9cef9857b849315dc4379799092af4c5531fc13f63b186939040da2233be05371d448fa748d76f98c3f638a6bf5864b9bc5fbe496d72966e3004409e420bc4353a5d55d0610843d0b8e6ee5bb5d6c4dd1462ae99a43df586b398a15ff5b5ff58a4006987613f5caba694dc0f736f6d47af66673e8f308a6044338d23c817c0420e679ef621739e21a4a35140dd2928e79584f787671b118e9e71e1d9430b9a3210e11c266876a44c7082e7ca5f6dc4b8d931f5bfa302fc790bd424cc3643844418f6c090e2cf5bf60f08c489bb87315464d90006375c34a5297a238a117a8770cb9795776c11f8a54ff13adb3fa77df3757938c28d03a612324858a11a860235e0e15284e36035bfc0178db841c679a47b93e3b09a9f735955d6bce328a91f2fa64273917b7371fbf166c47e9683776aec02251eddc84032cb0a852594f4c7875792fa345a43a68a193c51492a39c306b02f22c60ce5a8468c3050cc3965e2982e32b938a31cab1f36c1da3ca723261be3a864e2912199262c46741fddca501df33d04a79f8e3017e6197ab24b062cd98486dce2a7ffb22e5798643cf9ba5fa06bb0ff42f4d610a7b3df7544d66b97a486967cd9b62ba0142ebb10b8ee4ee0f6aa3e88f7fa8a96067f8cdaeceeac90c2d0b5e277e56e9c405ec9420c30252" +}, +{ + "dz" : "9f52af92ca165fdc38788f2b59ba02e01c8281ff7c1e60504688043a5fe814b04f3029e1be4e1c0258c3a22ff5b50b2674cc094ba7018da2a61569845c17d26f", + "pk" : "6f22424d97bfe0b7cfeba385c55253559b0372fac0c533055ee490bed57446b637fd0c07c173b2c61345185a0288f1aa074accae383c75208fa03a6a175c3d19481e79ec833057a8d2c234ae9b01376c21bc75277738b17dea03eae594ea939e125c2592bcc95d3cb4f76a8d8383b318a48f7481b6b8419e8bb47cf1229c23c4800788cf91e465088a580762ac5d31616f114606c54efa9c0490298ccc23200154342dc7709a5ca5ca3a94b7a2ad8ea734b6e20a2d15acd47c6aeada3ef3331fcae173af5191ca8b74bee31f1b7506b595a3dee0899381111680ab02090429b93efb7b52a6884d401841a0d8193953a5a5f2417df927e5934c109722cfe18d0ff93a3df69d9cfa4d7f5801d3294771156e828924c65a18bc798006a1c8eefc3b4176634690c061b902738024c0ab981c3506d11b8f307c8f1cbc25ec764fdad76fb2117aff430c5a5a468f2966bbb877d2b8335ba3bfca985864f21a9912bea56a007e7223c7249b2e45a37db9c104438e76d16321289d4b07001241aa2f0a1a24d81c27a9adc0c768e1b3c72fa08e33f77c90f4cbdd530949b2b67da9a15f336b679937aa825989b9a450fa5f69304d37e585bc039a154257ee78907f689dfdb246d05c94c3057066d03a2f9825be6a52c3376efbea3fdeba68e13716d810b73662adda56bf30031b8f682c8ab08c4b0978bdf113b4432ec712ba306a63c327978224597c3b8155551997bb7e2881102d8b3eef786be65196ba84478c1c629f45a885db1aa4ca443d8a3300316608e8c2f71c6c7516ca5eb453cf9184bed2888ec592dcd53fed23b5ceb98cb575c474b51e7fd64d73d54f37b51fe1d432b2150ecd5b0dade606d83729586b2fdc60414a558c3c19122e47858675179c2229779b40cd882bfeb3059ffaa93552443fb70fcabb54a7015f8b6a0798b090fec5aef185cc95579aae5caa2b4923ddf65b2570c15b1b0464c086114975dbaac5a564cdfe02cbce8c68752000ee81a9eeac55d4a81be9b3c66aa3875761049565a46e305459fc7a47d75316b59a371cab01dc3bfe9108003d5f868b39ea617ce3091e3ab646db07ccc4a09367b352d1848b26e920100827c8d4c92f0c222d8482606233adbaba3005b58fd3248e67cc75733feb52a5acf5a41ab71ce0ab7e8fca8113261dd4b7297ffc9d37899ab40b0637c02ff1c73e81a02762fb264f51c849d387b9f7aea345b5e2ec44f2e0866b9574bcb13ea0d0aeb7a78d6dc7b5b0c9838297c05409bf90d86b3c1b59b92c998a8abf34fc490259289b431c5c5368acd762df8ca04e0235ae91bfd5332d67169aac2586deca4c8174386617ac98471366283f3d30a971c62f35322ac96a7b0c45779f6c17f1117a2f1b454e3557ce5733cf979156400c5a780a4da91ab8d99c4f98b141920731f361ec30950bd0c5653c83dba87658674c57473dafac42f293bee44034b9489ccfd5141ee42cd91b3c3cbacba092cfef6ba4b0a716d8162521b29853522356943c697a10948a50f27008d8a303254327c4570af822024f5b9aea82a62100856b2140015418a9ba3e77325b911a582e92a8b8e123816405ed8382820c0ce5ca491c0692b2b542b6a67ec87bb6b0334c1833e12aa958fcc0747802853f8536c1e24a0ea6e13ce23c96726b5cc8", + "sk" : "d95b5c5667b797b1797a73806df8906819743e0322070c80d97b77242040a2c6154ce152e2bacf89ba871dcb835aa873133a331dd3450bb51893cbc5b072459026552001c56e6a9ec0da3ace136b5ee150946406f032a475d8cd05c31c14897445ebbb24cba8a9e9b9fc819d752a5f6830162c89c4e7e16dc3b12823739d44c063f55aaadcb03d02c3325649afa5a63e26a23f16cb48091b388f503f9eb6751d44bcf61989fa953c10a5b8ea9ca81c56a04498509f380c1675b273415bc9285d0e765b0222927a979ea9a47b9103c0b73326a35945ec1cc870a693980cb73722b855690bccca1df9290d15b6cc53db8b99a89395994e3f39c13c81b9f3a313a6ac1407585ae1015eb2298defd84a5258a2e62aabe709c8243679dd85b82c08a82021206cf0424b7cab4df614aa21c81d931fc5f0bab9f373fc4a98484bc6fd5606af987bf57842cc4461014c4c737b6a52234153986aafd737d4a834971b96a711693716cdd1639f822a43936b94b7421bdd660503f3034c0c2596e8155684abc1e81c218151e2d44845d781e4a54f33fa8eaa0cae0d96c3509c6e5a973272c0b7616a929a579d6d9b83ca8c6631b87f94457312d9c58f66b20c04297b881d11e9c97357a9b0e50572b3430722963869ca2a1688f623b5a3224d2afb7bf6f4ca115198beb213679c210067a32219cb9557042018467863c10a4b449bea2b486a85ebc0ba8da9a3ca50a632451a5754b7eb0b7067c2c939bc192bdb8315427146ab6fe7390ab60264b0875fd2603d09466acb2694091340bc8c6df3fb8eaef1664b533c0e377bfd0bca39f801f40a92989619c41756af7b4cc7551c8779558ad4031a6459e6abbd9fc68103fbb95182c9576135e154a619180b1a694e384212fa89963360791666968cd9aa5ed3bc0f72939c24cda10a9f2a62aa4cba9b9d677c5df1282e47c29a790bdbdb664ddb30cb154d01da8e87035d62a099a9e9a47f019d6a769579eabddc851416fc9a2f144b2d2c3fecf889f19a2acc434919a89d474ac628c03ed6050b3503c2ccb4612eeb831ceb76ec9798c2738429dc10386b36be606622d2152db389b200c219e4957bb6ac6f59739bb60de382c88ebc442fc16e5b55cfdda0c9b78a18b07a5e72ea3927070d7d15951f87b0e09bbc631bca04fa0d5f4630fd04a16d24bbcf351c806c07c32aa05b19009b66181413c202536d52b8946fd8bbc65215749359a3687cca6982c3ab0435da4edf454a69b23726c503cba4ced872311799c4ce57c0e1fc48cff587c4b552da83b5472353c711c6f220bb72540cfa651352287e88d0624df8248b17914f654a61ac0fc30856cad09f5fb984a8e334b5333c3010c1bff26fa7164058b2343fec330f4c2e93b07c7e568d6f437c0a307131c70e0821637519b1673a3846829ae11ca2801b5a5eab191ce686ebd2c2a8695f357bbcf18c95c51591b67aca77521de32b1426173a0e059686007508da93ce9089bbd43479183d0705496d1709ef41424219054be29ec816868a95146ac5106e261d6331a692306bf9013207d60a7f1519d0d7ccc03755eb5c31a2982a81339cee7b810727471d447df481b87da70f7651b7eff647a2eca76f22424d97bfe0b7cfeba385c55253559b0372fac0c533055ee490bed57446b637fd0c07c173b2c61345185a0288f1aa074accae383c75208fa03a6a175c3d19481e79ec833057a8d2c234ae9b01376c21bc75277738b17dea03eae594ea939e125c2592bcc95d3cb4f76a8d8383b318a48f7481b6b8419e8bb47cf1229c23c4800788cf91e465088a580762ac5d31616f114606c54efa9c0490298ccc23200154342dc7709a5ca5ca3a94b7a2ad8ea734b6e20a2d15acd47c6aeada3ef3331fcae173af5191ca8b74bee31f1b7506b595a3dee0899381111680ab02090429b93efb7b52a6884d401841a0d8193953a5a5f2417df927e5934c109722cfe18d0ff93a3df69d9cfa4d7f5801d3294771156e828924c65a18bc798006a1c8eefc3b4176634690c061b902738024c0ab981c3506d11b8f307c8f1cbc25ec764fdad76fb2117aff430c5a5a468f2966bbb877d2b8335ba3bfca985864f21a9912bea56a007e7223c7249b2e45a37db9c104438e76d16321289d4b07001241aa2f0a1a24d81c27a9adc0c768e1b3c72fa08e33f77c90f4cbdd530949b2b67da9a15f336b679937aa825989b9a450fa5f69304d37e585bc039a154257ee78907f689dfdb246d05c94c3057066d03a2f9825be6a52c3376efbea3fdeba68e13716d810b73662adda56bf30031b8f682c8ab08c4b0978bdf113b4432ec712ba306a63c327978224597c3b8155551997bb7e2881102d8b3eef786be65196ba84478c1c629f45a885db1aa4ca443d8a3300316608e8c2f71c6c7516ca5eb453cf9184bed2888ec592dcd53fed23b5ceb98cb575c474b51e7fd64d73d54f37b51fe1d432b2150ecd5b0dade606d83729586b2fdc60414a558c3c19122e47858675179c2229779b40cd882bfeb3059ffaa93552443fb70fcabb54a7015f8b6a0798b090fec5aef185cc95579aae5caa2b4923ddf65b2570c15b1b0464c086114975dbaac5a564cdfe02cbce8c68752000ee81a9eeac55d4a81be9b3c66aa3875761049565a46e305459fc7a47d75316b59a371cab01dc3bfe9108003d5f868b39ea617ce3091e3ab646db07ccc4a09367b352d1848b26e920100827c8d4c92f0c222d8482606233adbaba3005b58fd3248e67cc75733feb52a5acf5a41ab71ce0ab7e8fca8113261dd4b7297ffc9d37899ab40b0637c02ff1c73e81a02762fb264f51c849d387b9f7aea345b5e2ec44f2e0866b9574bcb13ea0d0aeb7a78d6dc7b5b0c9838297c05409bf90d86b3c1b59b92c998a8abf34fc490259289b431c5c5368acd762df8ca04e0235ae91bfd5332d67169aac2586deca4c8174386617ac98471366283f3d30a971c62f35322ac96a7b0c45779f6c17f1117a2f1b454e3557ce5733cf979156400c5a780a4da91ab8d99c4f98b141920731f361ec30950bd0c5653c83dba87658674c57473dafac42f293bee44034b9489ccfd5141ee42cd91b3c3cbacba092cfef6ba4b0a716d8162521b29853522356943c697a10948a50f27008d8a303254327c4570af822024f5b9aea82a62100856b2140015418a9ba3e77325b911a582e92a8b8e123816405ed8382820c0ce5ca491c0692b2b542b6a67ec87bb6b0334c1833e12aa958fcc0747802853f8536c1e24a0ea6e13ce23c96726b5cc886538ecdf65b7a485b73a34a72193af1ea3f884d820463601c7f843672bbec7d4f3029e1be4e1c0258c3a22ff5b50b2674cc094ba7018da2a61569845c17d26f" +}, +{ + "dz" : "851ea90fd3854cbf28fe39fb81f68e4b14345cf0d6eee7ec4ce772513df8410d1c0ec046899a777655233e4e1b5ca44e9afbdc67964bfd5d5e3dbb45e60d03cf", + "pk" : "010510677c6c12c76cf7149f35031c8df3b243140f9716a571f62a5365a0830169b612abf0075ab40132d51070aec5566fe953382ac3a3705b8566064af52b926b765bc039d6f86ab8b27cb93b809e670da4457bfb8b6be9aa54d9b2bc94eb0c3e15ba6ce2b08ad229a469312a5caa04c8a4fca7c76cf905c6fc4d32127d84981608810a4752b9f26baa12665bdf30882d2a38200798de4a5f1d3bbb571085ab091c03e896f25b8759e43795dc83c2069fcb2cad05b166def78d18b920e0e59853c66bcb11795f604963ac3af33b43f78252e06b39d11449012b0b35bc65c2562a66f7597302377eb13119fb4285d5613d618c2227a8a187b132b08bf5b154745451fa627e0587c24118573f3628e3da59e96c6a66d26c2880c95eb1abd96202b3673bd64a74d1b11396aa406d378183325c9d03b8294177d3d6439fa79a2a6457d9f81ba8134bc781c575413e40082c686ac2f59c3fb45a580d3a50add274add391a09cb6c559623c997da498c1d002b0f9b5254c26266757849e7598c941333d580a11a1c197617b23d98b7da60b6af0521e287f8b0cb21522236395a60af9ca4dc7120925a4bf497e2ed65bcce78a33555ea459197bd5a499bc7c2b788872916ab3b961f25094cc96659db67bfeab52260456bb775f56e492564456c5d25f3d0c9bbe7118615aa37b21547255112e590eec52928173292450abf2e834f6207751b068200875d7303e3bf7141f28aec8653a463a774dbc33772849385304b42c99d3e531b0376beb153a56734887c1cbe59b55bc3cbb32da63d908345b200cfdd6303f3999bc873db53342aae6ccc789b2a4c72c7d08a58feb9c939a3214aa3b2bd27ab108aa89682e08729cbaf93a68613a8f56b7764c23cf085f6a970d8abac213f7314128aa64da213d5a53d2475f7002a6c354c1181bacaed645fae9c7509a0b10c8317f714d37f3791c03ce39c79aa0548f88a69dd6f87dd49a8e63307331e00c5c5b5fd7d9804f3c57028c2d3fe65d87ba7c07624fa35754421c4eea618cda1c5434b09acd0754e04439240988ebfb5f6d6a43c0683a287b5686364fb9fc6a62551916046442004caa42428dac71ef5879bebb09c5dc919076620b9701a2d8af248672e2ac0107c62159511cde45120ab84993fbbe65022dcaa6369508212d7a915183555181b1b9610dd147516f2496eab20f727724d7178357f50e23691c29400bf461c389932e2e663faf31ac53273058ba675cc0c3367c4872383f683a834b4a522b92276f70022153aaf4622f24f439a0d382fbf5059744c487013501d41fe9a99966506f2f5651b3ab0fd0a73c02634dae9695e850c67b154455aa749922229090b621e259d1f193b524579690262f94c114d9c690e170e526a99f5149a2840129d22c740cb5b2a50ae7809388147b943a4263d50ce72a2fc2fb6efc85c065502642f015d6b83aaf0880b715983bac12fed75b1c973046c79f72436a420b790543349b917fc4c3b18db80a1ad346389180fbb9bba1a6a8a0f0a62e6c24d580a16580c682553134738d0cc1ce766c13bf74c82ef5c548f79de19a0f2a9236100a7adc1b2f1e1b1d0066b9352ccc40663d53b0af0df9ccd6353381e5030ac08c3920847f233164df98ae8ab017efb305fcc83fbd22ea59ee59bb", + "sk" : "9d897195e7139d5b6b8075aeb5d176b60bbbad949d5890c707f460341c12a79ac5e18a9126c7c2d0d59456d1ca072034706bc5444519fbea529b17b3306113f73c840ad3bc015862de98ce93344a849094ea71a6d5b1742fd2a811d389ca465419cb8aee9b2dc3961c4723a7bffc96acbc79dc4b17c99b4022655d7ccc0a645981b990ad8ab7b9fe6a69b511731c84a2df77c2bd917f1220235e91ae5fe91e30573dd67a16ccecb18f4b9116958f812c7fbccca50ed732b3b946645b409b74bbf34c3769757c0aa0a04d690fc2c14df10b334c089adb54cf6b731377d433cafba345dbaf06366eda0975aff207e0d545a31aada7f85369b62f7d1983997a542e899aa2651a0f3417b142bf1317aa9b766de2135546fb2224d5aa298bb4a90b4aa92a11ede75f441734283a2baccc2f2b851a6c314e81ea510c7a31f85855fe55ce0656a88ee689339495d5c293f483bc67e49c86644d08d896681cb2d28278dcfba73c2bc2e050c9e277ba7aac072724b7c02c2ff0e24a48ec9d8b46298d14657fc74dabf368c6b0272fe3a5ad280130936a2db57e5d971d18916ec39b9960c73e2bcb5697e9690900b9f25496127a58d50062ce88c0f3ac9dc60b9a9f82406e0b0f7c6898806807f6bb9e0945b7563136cabbcaac04c6b0ec8eaa60c26fa604b073a0ca8a925ac99bce9bce26fc7ab69c9a1509c7ae8c97e006b5b8f3a99db2850332986d65b17a67a1d2cc80d476cc3a90cd419920e302074925375987cb7d268ff1eb4adb07cc4d133c381b47c40b42311a8f21881f50ea68343483ed6bbf34344d710c7e0f769eca3388b84c62688b4cfec37104f0717cda20e21b871e267fd275826da7aa92b372fac774b1611b18e35dd6db3e52a58c015a8badb33c54a60aa4005d55eb16af7547d217670a621908a9b25bdbac84753495c244af191f7d73ac08c94b7c1b522916790a245d6de2b274250159f89bb47a1e7c0850cb97bc843a7a29e594a5428c2ebbcca5a989993934b9a36ed1e7561663a8c9d400ccaa7d5cf4484cbbc80dc6b3ac20926b3a49941903c4eb41fb988f0d77a8d26c2c68a14a0162b926f4bd8a26c45e76c706f68bcd738626a2afd235638f6741d229427ab4166920850db4661d4019fd7ba362065aced015ba3259eeaaa4acd2cf8b1189e4e1c4a3d67982d942ff2734e3434a45e842e157103890c7d3510134466884bc16d7078430e2048fcb58ff0717a5e6987999a5400973809c30cbcca50efc4ed5c1a37f3a0ec71842d88b35d53c49b040bea967a8466772e9e3486306a0cbdc449db2099c349970e8462093b398b7ba10b505a76c4aedaa4ea661af1a712a560417cee26c4b109d8be72b88467752f5cefcc752ab3c324d2684b1145f4e7715e9d98f0a1bcd3f1a567676a138213e202aafba10c15ac75b45e06a43987d9f6c07de147e05f42693d12f9a8877a2cbc7f2e81ff9540ac09bc620527e919542fbe53379519f35c70a4e0ca6f0253caacc2ec83749aeba42bd4a0fb6902946da8320ec2e7954bf2a184f94a31e58c505b1d1ab9c3a19aa8a3c1da7274838c768e21978982f95c41998058c9b58b861b1090a5bc3277a1346f2108db4c0399454010510677c6c12c76cf7149f35031c8df3b243140f9716a571f62a5365a0830169b612abf0075ab40132d51070aec5566fe953382ac3a3705b8566064af52b926b765bc039d6f86ab8b27cb93b809e670da4457bfb8b6be9aa54d9b2bc94eb0c3e15ba6ce2b08ad229a469312a5caa04c8a4fca7c76cf905c6fc4d32127d84981608810a4752b9f26baa12665bdf30882d2a38200798de4a5f1d3bbb571085ab091c03e896f25b8759e43795dc83c2069fcb2cad05b166def78d18b920e0e59853c66bcb11795f604963ac3af33b43f78252e06b39d11449012b0b35bc65c2562a66f7597302377eb13119fb4285d5613d618c2227a8a187b132b08bf5b154745451fa627e0587c24118573f3628e3da59e96c6a66d26c2880c95eb1abd96202b3673bd64a74d1b11396aa406d378183325c9d03b8294177d3d6439fa79a2a6457d9f81ba8134bc781c575413e40082c686ac2f59c3fb45a580d3a50add274add391a09cb6c559623c997da498c1d002b0f9b5254c26266757849e7598c941333d580a11a1c197617b23d98b7da60b6af0521e287f8b0cb21522236395a60af9ca4dc7120925a4bf497e2ed65bcce78a33555ea459197bd5a499bc7c2b788872916ab3b961f25094cc96659db67bfeab52260456bb775f56e492564456c5d25f3d0c9bbe7118615aa37b21547255112e590eec52928173292450abf2e834f6207751b068200875d7303e3bf7141f28aec8653a463a774dbc33772849385304b42c99d3e531b0376beb153a56734887c1cbe59b55bc3cbb32da63d908345b200cfdd6303f3999bc873db53342aae6ccc789b2a4c72c7d08a58feb9c939a3214aa3b2bd27ab108aa89682e08729cbaf93a68613a8f56b7764c23cf085f6a970d8abac213f7314128aa64da213d5a53d2475f7002a6c354c1181bacaed645fae9c7509a0b10c8317f714d37f3791c03ce39c79aa0548f88a69dd6f87dd49a8e63307331e00c5c5b5fd7d9804f3c57028c2d3fe65d87ba7c07624fa35754421c4eea618cda1c5434b09acd0754e04439240988ebfb5f6d6a43c0683a287b5686364fb9fc6a62551916046442004caa42428dac71ef5879bebb09c5dc919076620b9701a2d8af248672e2ac0107c62159511cde45120ab84993fbbe65022dcaa6369508212d7a915183555181b1b9610dd147516f2496eab20f727724d7178357f50e23691c29400bf461c389932e2e663faf31ac53273058ba675cc0c3367c4872383f683a834b4a522b92276f70022153aaf4622f24f439a0d382fbf5059744c487013501d41fe9a99966506f2f5651b3ab0fd0a73c02634dae9695e850c67b154455aa749922229090b621e259d1f193b524579690262f94c114d9c690e170e526a99f5149a2840129d22c740cb5b2a50ae7809388147b943a4263d50ce72a2fc2fb6efc85c065502642f015d6b83aaf0880b715983bac12fed75b1c973046c79f72436a420b790543349b917fc4c3b18db80a1ad346389180fbb9bba1a6a8a0f0a62e6c24d580a16580c682553134738d0cc1ce766c13bf74c82ef5c548f79de19a0f2a9236100a7adc1b2f1e1b1d0066b9352ccc40663d53b0af0df9ccd6353381e5030ac08c3920847f233164df98ae8ab017efb305fcc83fbd22ea59ee59bb27757389a4a68c898dab92d0f63c3340dfba51e00312a05e721932b95b11f6da1c0ec046899a777655233e4e1b5ca44e9afbdc67964bfd5d5e3dbb45e60d03cf" +}, +{ + "dz" : "d304c9389cc973477f169788abcb9d511f843219d246a9b587822f422a70c2386590a2e5c7ed86cf2c5c2a898662bc9a81418720bbb632ef9cf0b845ed052d73", + "pk" : "801c4c929171c164522aa3ac2361b8c80b8cd3e644f7d169f9a20380bc575968901ed7783b6969c57461dd879d4781bda106a913c629be512788d4c1f92a71f9f819ab7207d1a65499e061c5e0447360b4e70503bd58511e4c3333556b75f6a8945b8661d0572c764c82ca70ec870ccde0cc5810b816c10a46491e091c75f8b24eb975867e179d38345bdedc627a725b4d732b7b453d9b15710fe7afbc55beb26c77e9e8a58bfa764fa430f1901928fa4ea1eabe2ee827d44191708310b5e708dea4c5242a8949f658b548a2ad1badb9a6322c56697b513bc1c29872b56fe1e32d9271b44ea0b43bb896ca9a7358f45e1f1821fcb361c6ea91abca91ce95a75588402d1217d1e37a80b3c880aa83c31c5683783e3bc77bc231afc0172beb9957fd7228d8589bc171a2fe24757400cc7e9cab13d90a2cc12b771725e0f2180acc221fe5879a317fb93a10682044d6e22ac67c0722c1062ee70959333c08aaa16bd9cc1b624405f40b78411baf7bcb4af46b80ab021d7c8a02ec8d0417b759cb2dce94409be96f5b5abd1e207a9b906c71c18c763414b2d48d77c19d8e617dc4e41c3328ae39c18aa9aca985964597686c919584114c4b2429308e123fbe9a8fb86327054817bca07df8c7adb4e2a941742395cb6ea24c6106eb95cc0868f8a6452efc5aed297d933919b39a8da93137925b87ada9a5cbfc5a541c2395bbca59f95ab2c4a5352831f0d143dac60b418c2051390396326d49e27b7b6159c43b5de3e40d05956dab59088f417302588e38c1a21261c62abc8891e44ec4c7395421ac09e1b448bc2349dc88c571c74e470474935ec58001be48b854a13d9855b8c87131985c91484a695ce9931267c1d0d0b9ceb4bc7c4a11676c267958566d59431a630d4ecaa8beb98bafd22172a30e14c9acdba26922f0aae067c9a0e9b658630873139b9555b63a73bf8c65319d9423d4a927abe86a95b383a7c0c8c54170dcc70a535b1fd814cb6c87900ea94eed7b51cba571dc7b5e6370bf4928bbb27b1f66d770e43cbbf3ec0c615521e2b8adddb42971a12db3a208f6b690289b059913760471367b4154113c14606c046a9591aa744683c4024b857293eb0e02ec7c75270c571248c0aacfa7e47a35e72157877847db1efd73c0922cb211c4538d018c05382e9c97c3d98cb375f78d056196466519baf3312559315796ce3504731e811432a83294d75d8365391fb348f0136a7fd90921fc3844f57d286845d6d663e855b50d884f511a2020b09048298dc4da2be4a8398d260ca4735d84f2b66b2405d48032cf3174fb36b325e723af241d280863b4d2099fb429c0414433786d33f880d7a15d3fe019e75861c7836490ca2a5b0771ecf904f794c746b4244d99226899c847814967454d7a4aa0fa743e2d2838bc9461446b61d9b006b4240098f37021c7631131a84bd75d33374b9067aff5e900c4d0490995875606a7baf87b8f4960dc84a7eba96f4055ab6043c9fab61fbed883705893aa89899ab975284867f63035a392902a779c8df9cc63a1b944943691b770a9646cc731a93f6cb3dc3b183b71429770032d08a778217f9b72bb16ca81f07c66d436396038372aeb8edc031083d95399084751bb9f3d32490393b510796c16c630cd2d7e0666cab62b5d904b", + "sk" : "f789391672b25e088e06ab6e0167cbfd56b01c01876cc67ea0cb13a4491472c4710f9cafb5d1068c207fa9875879dcbf60e78bb6236f2f00bc77f81b98d74da1f3354de5007c0b5243d15dc87282f2b2c298a5324f35cd2e6327a7008c51d2815d833e17f09b91a047d15b25e0c9782d34bc474a973ebb1585a23bdc22811448299a0a6d42669b31951da1f949e8573292089bf6b0b866f4cea0bb110fa5435550c11c477622b6c859691be5683198c198d2960f8932606dc3310f3193663abf161bcc6e1521a3c527b946a8cd20bb9c4b0627e9778e521ed5ebb7d727c79b687214c1c55b9a5da230598ec71dad4ab1833911e991531f0a32ed2a773d05a9c166cd4cf4c625f3665bc80bf1d46f88560800ec2c04a92fad947e406b8a14061642d879b6f14a4b2651d3e1c502322b256a7c0fe403038125c9f5412b5c0fb62bbc8ee41dcf071c5236c4d54621010a088970c956a5588696412d75b9e6f5a920481349634956a9a097cc8a0a5897a6fb60cc103aa1136131c5b30f4469a73c52d43578df35914d5436818a16d3eb44ef9760922c354356279b793a05a93214ac499b454e4b66ac1c1188e0c8375d0221c8b80012f21305b57ab023b822ba5de2d96f4bc0a2420ccc8afb3d9a983a59a46d4a32c3ee764b0d696669ea5b458816be782f3db39df35b6624a59f092782c886806d8503ea4c177e7385fed9c8d7416bbb9708cf8cc32a2b3e198b2c93bbbebb7aaf53f811ce50cbf173a92580861af698451c77fe1556d79a486dc75dbdfa3a09eb150f477c87857b0352418c4a66c57a0f73f60a16941ca247b4981c4aebd24985062b1fbb2f85323f87f248a71657760c8766900a1f260f2f9b2a4bb1073746ac6b73998b6171597b9d7fc42b873271801b6dd111162f7b2ffb55b044e08983f6ae95f731d0c32fb8d3108d4a048255a42ee290d33031521b46579c864cc04652e59252a3bcf315577c31695d6c8e44517b5ff76a75acc608b180a6d10842c4c92aa0ac13a5515d6c21ef25cdd3f81556f336f1da4e7fb89b73c195dfd5c772b5abf20223ce84c297b32e57a1467225314c37a27eb43f0df947b8baa3cd38b6c5cb2e5a99cc35b9637fdb1ea82c5fc3ab3c9db9cc9491b6095c499a2377a698b5b77799b1d00412d0c258d48e86801bf267cb01f17d335bbf4406463ed9c6575b10ba16622c888517579d68129603b0bdfd8284351183b6114ce424557eea2d2986bc238c85d2a1443af19b8d7051e84ac6ecfa8339d22deb23472a856b3056cd5b280c3f395f2b2370df8752827602d64bc033b26b1970c9c8f020d41c15736190db9a5ba1a87afe9575e7918e502382d9f763bc3c5b7313c8539564df19c1deab0ff7ac7d3c48981e5ab31691c0a52c4818611456481668ba8612f410b78c21a68505335b8f4519c7bab53328a700763a6d95163f75dc2ba489ccf92cb2ed1b72f2d904a54c35aa0c8397bb06cd676b28cb6d1e44502550c9d259a05204272b93600b09244423a63b4c753b69529d2b3d16114a836273fc702f17fcc046d7205e47c0903541f519641981576409a35fda1e3e76cceb8109ef446338424aa13a741b38acfea91a1c4795925026801c4c929171c164522aa3ac2361b8c80b8cd3e644f7d169f9a20380bc575968901ed7783b6969c57461dd879d4781bda106a913c629be512788d4c1f92a71f9f819ab7207d1a65499e061c5e0447360b4e70503bd58511e4c3333556b75f6a8945b8661d0572c764c82ca70ec870ccde0cc5810b816c10a46491e091c75f8b24eb975867e179d38345bdedc627a725b4d732b7b453d9b15710fe7afbc55beb26c77e9e8a58bfa764fa430f1901928fa4ea1eabe2ee827d44191708310b5e708dea4c5242a8949f658b548a2ad1badb9a6322c56697b513bc1c29872b56fe1e32d9271b44ea0b43bb896ca9a7358f45e1f1821fcb361c6ea91abca91ce95a75588402d1217d1e37a80b3c880aa83c31c5683783e3bc77bc231afc0172beb9957fd7228d8589bc171a2fe24757400cc7e9cab13d90a2cc12b771725e0f2180acc221fe5879a317fb93a10682044d6e22ac67c0722c1062ee70959333c08aaa16bd9cc1b624405f40b78411baf7bcb4af46b80ab021d7c8a02ec8d0417b759cb2dce94409be96f5b5abd1e207a9b906c71c18c763414b2d48d77c19d8e617dc4e41c3328ae39c18aa9aca985964597686c919584114c4b2429308e123fbe9a8fb86327054817bca07df8c7adb4e2a941742395cb6ea24c6106eb95cc0868f8a6452efc5aed297d933919b39a8da93137925b87ada9a5cbfc5a541c2395bbca59f95ab2c4a5352831f0d143dac60b418c2051390396326d49e27b7b6159c43b5de3e40d05956dab59088f417302588e38c1a21261c62abc8891e44ec4c7395421ac09e1b448bc2349dc88c571c74e470474935ec58001be48b854a13d9855b8c87131985c91484a695ce9931267c1d0d0b9ceb4bc7c4a11676c267958566d59431a630d4ecaa8beb98bafd22172a30e14c9acdba26922f0aae067c9a0e9b658630873139b9555b63a73bf8c65319d9423d4a927abe86a95b383a7c0c8c54170dcc70a535b1fd814cb6c87900ea94eed7b51cba571dc7b5e6370bf4928bbb27b1f66d770e43cbbf3ec0c615521e2b8adddb42971a12db3a208f6b690289b059913760471367b4154113c14606c046a9591aa744683c4024b857293eb0e02ec7c75270c571248c0aacfa7e47a35e72157877847db1efd73c0922cb211c4538d018c05382e9c97c3d98cb375f78d056196466519baf3312559315796ce3504731e811432a83294d75d8365391fb348f0136a7fd90921fc3844f57d286845d6d663e855b50d884f511a2020b09048298dc4da2be4a8398d260ca4735d84f2b66b2405d48032cf3174fb36b325e723af241d280863b4d2099fb429c0414433786d33f880d7a15d3fe019e75861c7836490ca2a5b0771ecf904f794c746b4244d99226899c847814967454d7a4aa0fa743e2d2838bc9461446b61d9b006b4240098f37021c7631131a84bd75d33374b9067aff5e900c4d0490995875606a7baf87b8f4960dc84a7eba96f4055ab6043c9fab61fbed883705893aa89899ab975284867f63035a392902a779c8df9cc63a1b944943691b770a9646cc731a93f6cb3dc3b183b71429770032d08a778217f9b72bb16ca81f07c66d436396038372aeb8edc031083d95399084751bb9f3d32490393b510796c16c630cd2d7e0666cab62b5d904befe6e93d8e755292fa875609f2f63bd194c87e6f04db7c83d8bb1b9d868bb7796590a2e5c7ed86cf2c5c2a898662bc9a81418720bbb632ef9cf0b845ed052d73" +}, +{ + "dz" : "89a6e3be304a3518fb82b18ca730f0b359cd6ba90664a493fb4f8edaf965b9c3b6591121e25d64010c25a18676033e1d7278ac5f2d0b43a31f3a4156ae710465", + "pk" : "daf0b0019241e200929c660cf7770e111043c8dc4af1014f7ceba48a445815408b2823666c6b40684616d823c86787a412c26e521ac8c16868d7eb5646909027820444b8bff59ab46086631d5a0761a75a79d76468b74fd8c20cb9784929f2a78ad1882a094619325cdfd05de5a30d622551c840ac79b0b5b7a513f702cf58333f8b0382ce055a4c138c80764b8f882cf14324015212034581b2876efbc3ae9687cdd7f2acb964cc18ba90005730d55673bd519be3173d3e231166c7ac0193a4fd26085bcc6607d4a6f73367efb5ac1a1a063fac0207766da41901b8a61ec7e45bcdb73584b5891ef112251a84e9c07ae7c16f52362cef10aa3cd69927db4175ba47e225a220dc2653a58dc9854210087ecc2486ab13408f92bf902635d2ac331ec1c95402bb55b73b5cf063d3885fd1874d5b03100a993eaca11e978393ff33a31b6a98f72479ad9b88d3d1395c2726ed285b793c489e09a8a7bc744b361ec87427c399290d092a1d58a5007ab2209044895941088a81b1b44175ba3e7b038ed17b1b0cd5bbdd1bbea3f58812a51ae58216b1c18907f131a80897353a328435b927d377a45a6be2310cb22076cc428371d4b772ebcead61c765c875312cc91e73b20be811706caa4b52b089ea1e43d7b61cf4b705c1b7b3739fb92c53268a685c03723b4bc316f679f4d8b87375a4188382e711b1911502e502a3f523bd5531b30298815717ce2211283cd675ef106ac5d4c37a6809d7e3bf3e3c40c6c5092c34198659849713c090db27c78689c6d57ddc90c04bf1af5cd56b11c013ee7126958aba8ba7284ed58828f1384786379eb0bb2b8c50a504a3b0fb83eb5964ed6c20b908731ca5c13d980d9a1c0af7c7527da50262c65f7c2132355aacebc1ae5fa7059e7310d6d95da97871c50a17c0d1c68dcb6bd7a9a697b9bd9bf15a643748c83bc8b244058f0c93e7d1a99111ac6f046a5cd1713d977650935ca5925d6e10c84c7ac692527e27c8465ea46fce97c64dc66eb1110188c7a3afbc94c1423a845b3530e35540805c881b999a6b28ef185273e584b9acaf26746829fc6b1c88ac03578f98e71b67f5101de2233c841d2f303c52a500b3d1bbca883fe49b5a233b270bdca755658448666dff384efc9cb26a664106c49aa46c4237d9ae0ef37df159a0c9e880d7247566113c12bc4451f4c6b4946cf76c7b57f737032741a3047934b09e697acb2210b05b17047ea8a460e4cd9e7068b4202a8912812a04286208202de04d0c91b9d62992de76497dd0986917592e9902f33c4999916576eca4bc8495fc7233ea94671a3588adba1355804f1c475ebd788d683967aaf9b07a3cc9ec4c2c91a61e0456c18dda1a238132d2eabff8002c0ea6ad88d3ae3f4769e298aaf954550fa3cf86944184da2cc7303f1be393b6580cdc1a0e55bc3be7300166d570fc4b8644156cfd6c8975c29059c7a550d4b63d242b3e11b887a31bf764a911ac62801a6845d6589b0acc55e4c80cb37a3784ab8c048abe21204b152069fba2d6b75cad8ab3f133678889a99d346e3b49c0c41147deaac27bfb7c8aa3810e3b74bc0b205f02753a48457bd4b7b624a3fba1443217a88c65c5f63a0793951666453692c56b790391a7c9297e5224771c7a441d5363741dce698c33558c584f", + "sk" : "0fe71ced368f0f36b7b8f1be4802ab897c8919617030a5381945883b69ba1b456a2704c52d3a24a3dc3e8c35c09655cfd6c2c0f14489a1db0a991cbcfda5b52d708fe30229c272acdaa3b7577cae68845776579ace017b2c0112adcc57ce39265eeb0c5b2585ef868b6bb56a74089fe2373294298809d820499342c7fc5343b85493f30e773668c790aa55234ae7a230fe2cabed5a55d4699b6e14155f5793300676533c230f529f8c762ff0520ddb9b78894c241181b69bb09e3f7645391367499c707cb4454353b8f6d86fefd8a3383b00d35089d6a62be348645d8c03d5e815810894b0e962e1c5303fa5580b8483b8556f55a62d49da3257f63e03533c10b74190134f1cf3530c025bb0035896628927e8c3c926b27ac05265ec90da933104232b0eaca457c9131f95069f40141db8239c483cfccc26a2f41f5b7533bcc26f4ae13ebd26986227bc4501a3f5d74d11da48bf1336a8483678a4be53154bcbb62d609733fa678fc2f946ca4c5de03741ad6b5becba4a9688c455c81b4aa528c2515c9cd33c2d071c1cd96b5b483797e9616b43bbee62088e5987eceb1a7b3217a31c37494568b40b453147644ff6b199465266911342b3cc7026b62338413827b51aa16ea0066c0e4228d0887775b89c4858a46e018e5368ccdac224ba600ec8329b0a75150b82b51fdc5eedcacb9589c870b48f02338dd3bb99501a6c6580ba52dc4f98b66564736c3f9ba887eb0351b60df54057245c8098dc440e76100d4a4d572a7f34f80d5742833f41a3bb9508359801ed187b2e94a97472c9da7374d33ab4bd425c7592cd0eb155f1d90ff1a03867599fa4c693472233f2f8c5cf86c89be5921e607566c226c515cc27447d7c6970eee6851ff06238ca9b8b18058f77357590b6e88b5cdd2c1ca7e477b25a21b2a586ba231dff318f972a1805b280df4445545a8c874053f740b462725007748dea3866df03c1b68b4d3eab9984837f0958a905ea14403a1f135c4eae2299acbc5986dc0cabe31de5459188365bb20aa917894967b39d535b5a022c5f2d02cf6431afff02b9a52162622249871b537e10cb53aa14d301b0ab13216528893b08bdf9145bc56451fd251dd0a926357303860909a1e132ffb58288752eb9cb5629591247d3456113279ca92dce372f877a42802c1dcdf175c2dc159a082c0727122618761d667b80a272244ac8b34b56004580627ba261749849c0a5986494ba851dcbb0bec8a75b1355656a824a6f37bce21cbeb1f5a36fb1639ee743fae1ce0cebb973d2a0e6ac024f434fac8882715146a5d0cf3f3ac4a6374a672b3dcc122f2ccc37d4d8a60fe34613e2b5f828674c8216eaf0402f319e3fbcc1bc9620ca698b42821312289a2f511733611ac45b0d1354b7fc815afbdc7ad8ab14f1e43f7ff73eb626944b97044021761d352468cb334e1abee2e7a7d07751a34b35c9f2492f258791763be524a00e37a3cbd31c86371cfb71388fea7e67a85c3914892d216aec165eede03cd02233a5c97af27c5ee0219c8fea7364933fda62a3702a05c207527d79a4aa44277e3ac03874c14588bc60f32b5cf60226d15377884c1b37272507915fe97be0c4aa282560ba5b2ddaf0b0019241e200929c660cf7770e111043c8dc4af1014f7ceba48a445815408b2823666c6b40684616d823c86787a412c26e521ac8c16868d7eb5646909027820444b8bff59ab46086631d5a0761a75a79d76468b74fd8c20cb9784929f2a78ad1882a094619325cdfd05de5a30d622551c840ac79b0b5b7a513f702cf58333f8b0382ce055a4c138c80764b8f882cf14324015212034581b2876efbc3ae9687cdd7f2acb964cc18ba90005730d55673bd519be3173d3e231166c7ac0193a4fd26085bcc6607d4a6f73367efb5ac1a1a063fac0207766da41901b8a61ec7e45bcdb73584b5891ef112251a84e9c07ae7c16f52362cef10aa3cd69927db4175ba47e225a220dc2653a58dc9854210087ecc2486ab13408f92bf902635d2ac331ec1c95402bb55b73b5cf063d3885fd1874d5b03100a993eaca11e978393ff33a31b6a98f72479ad9b88d3d1395c2726ed285b793c489e09a8a7bc744b361ec87427c399290d092a1d58a5007ab2209044895941088a81b1b44175ba3e7b038ed17b1b0cd5bbdd1bbea3f58812a51ae58216b1c18907f131a80897353a328435b927d377a45a6be2310cb22076cc428371d4b772ebcead61c765c875312cc91e73b20be811706caa4b52b089ea1e43d7b61cf4b705c1b7b3739fb92c53268a685c03723b4bc316f679f4d8b87375a4188382e711b1911502e502a3f523bd5531b30298815717ce2211283cd675ef106ac5d4c37a6809d7e3bf3e3c40c6c5092c34198659849713c090db27c78689c6d57ddc90c04bf1af5cd56b11c013ee7126958aba8ba7284ed58828f1384786379eb0bb2b8c50a504a3b0fb83eb5964ed6c20b908731ca5c13d980d9a1c0af7c7527da50262c65f7c2132355aacebc1ae5fa7059e7310d6d95da97871c50a17c0d1c68dcb6bd7a9a697b9bd9bf15a643748c83bc8b244058f0c93e7d1a99111ac6f046a5cd1713d977650935ca5925d6e10c84c7ac692527e27c8465ea46fce97c64dc66eb1110188c7a3afbc94c1423a845b3530e35540805c881b999a6b28ef185273e584b9acaf26746829fc6b1c88ac03578f98e71b67f5101de2233c841d2f303c52a500b3d1bbca883fe49b5a233b270bdca755658448666dff384efc9cb26a664106c49aa46c4237d9ae0ef37df159a0c9e880d7247566113c12bc4451f4c6b4946cf76c7b57f737032741a3047934b09e697acb2210b05b17047ea8a460e4cd9e7068b4202a8912812a04286208202de04d0c91b9d62992de76497dd0986917592e9902f33c4999916576eca4bc8495fc7233ea94671a3588adba1355804f1c475ebd788d683967aaf9b07a3cc9ec4c2c91a61e0456c18dda1a238132d2eabff8002c0ea6ad88d3ae3f4769e298aaf954550fa3cf86944184da2cc7303f1be393b6580cdc1a0e55bc3be7300166d570fc4b8644156cfd6c8975c29059c7a550d4b63d242b3e11b887a31bf764a911ac62801a6845d6589b0acc55e4c80cb37a3784ab8c048abe21204b152069fba2d6b75cad8ab3f133678889a99d346e3b49c0c41147deaac27bfb7c8aa3810e3b74bc0b205f02753a48457bd4b7b624a3fba1443217a88c65c5f63a0793951666453692c56b790391a7c9297e5224771c7a441d5363741dce698c33558c584f87ada29bf78a689417b645fe127d124339422be80a993e623d13bc59f3406a6fb6591121e25d64010c25a18676033e1d7278ac5f2d0b43a31f3a4156ae710465" +}, +{ + "dz" : "d569b935ce015c85f792f8f7fb0d83c4f53b492959361dd4f75fb764d656450176eae84d11c4528382828f7a689a0d5cff87b8ca0bba97feacb39b935a8788cb", + "pk" : "670855bcfa888f30a50035208f5a75de6a8e3799cc4afaa7aee007788547e7b79c7507bed6a8522be18743c101463c9d0c28328a68b0d3ec380d04a20a31ab8ce6465e5aab4e2332f30870c5024718b1412c13b7094228e6f3a1a32440edba8f5ca66d968961a3f28705b9778713cd96974e42a50ee9eb61eba399cbcbccfc8786f7963c15d61ef8d194ccf37db2e16a31cb57ba79c9aa4a5da2593eb56c29498ab66f370d7b76971f797f9cd38ac3262226a64f91e03a1119b8eea00c103358572a1f4ab68f8eb4a5f889540913b23ff11768200694597d19218a2c30c3c25829467ac2d1b67f85d37522b22e7e44b950d152a8e087a3a35e3eb1c41fb15c7fc264c39272f01a0a2a91324a1ccbec627fa1ac81edb30ce0f84a727b36a4f9015a25ac67e3c76629c2347c2478d61b42bc413f6920f7b6774542bf25b92a7715745120ac1c4226e3b623860b4a42566829317e09d5868719a1e9babffba9517ac95a7c020882939cca54005f94791f37093eab5f2d15c1e7a09b9ec7b3738a197977c3ca0baf9f093271d00387841f2ab98c9cb16f19272d5e4b8d15e69da97517cf833475336d8850b5c3c87e4ef2c526b95e75060dc52c0292eb69e3f04294c854bfaa0f0fd5432dac0fbd03414b5a4a3b7c7cf36906fee8be6479c193b7336f4c870aca768d3ac2d84234b330a1f160b105214d469c8c1529bf31b3aac01a3ee1e231f389a27d4340b35a463ad002a7f8327dd5abed8b4256e87129b1be8ac475c32b97d11397db247a019533acb1a61c15b9aa4bc91d45af064a608b1926c93acb18b7c75d9798569a89a78463b51b5bbf038dae3c5cd133690ae80c1ad4541267bc10c83343a12439d6844b931a1cc79a0b5090214ca721f61e633600e8f76db52274c6c736e4c8b63089014a4012015522a9385f863507b1f1cc7c814cb47b00395724d601ad7bb27e4b0c43deab0664cc858d4a74576642eab3c76c211a58274e14f615ffe70084d7b7c0189d4d97a927a8b008b85888c57a0f6a307234344a5960836cbf6f4473ad988429a4ae3ba697bf07429d17c059a65d9e35a845735ba0a58e989307376c1e61f33023221a6611ca0465be5200363d49c53cd44b003307e5cc0c4f7b15e1545c72a7c3410ba1bebc8f7314b3b9d295c676bfe6aba9848554fdec9192f808329c60a793754bd6256cd030da12bce0d0765e51548aab0985ac86d1537ba49635641b3a26c05def260e94593b2e0558567c5da09b2cb122655bc4cd3e985eeda6c3f4322765e6a808ca387cc369dc11c9dfab64d4a30584e5329c905dc480801dd57d9ac8ab4087967177cb3163cf3e934a951a3e248a54cb922b6ca6ce9b4cb8bd788023e6425e75aedcc135cd3c59920c5ed0356fc0fb5a1ec0035b7c8271726dc8d63dbab3c78326a26c5b0f9f952cde7373aeca36cf6a438fb39c38a56124171593ea3bb076320bc8b5e74204777b7120ba97c3e803560605cf80c39324a0e3045d0f687e8f219a2ce70aac209b86d869febc5b51398341827204ac584c6b3381471937e68efbe5866a8569838251171647b4127514db9b84482d5b9a89119761c7f6508a099961376d6ae3706f6ca1c7c031f430190d6231425b14c6544cabe8701f8e475892fe31b587aa42d334fd189bdf", + "sk" : "3937043d61a4126a8c1ae01ab274b31b8424ed88cd180029be89cf1ea58b2a6325ffe8627b7bc4e3e8a4b3c60fc42573225946ca400235bb54494a386eeaae44f7bb8896c4f040836110c4b5796985108d116a76e05c984cfb2a9170811e7cb4c41a12e3601b9fb24bbd3cc0132c22d814bb98f049a8c155e38c242c2156c8b058eac343c77b11f550c52e9207a25213b40648fc70872ed8c050920c4c078a9b4576b60909bce496289168114a24111b7d15f10c06d7b719ac4c4872756d760970132bf15b08972c78f4f1a5a6a15364c0aca1c4721b3c82777878a861b751aba6a1eb75172c952b017ed03c9007541110a935207b037aa7296e73b998597240b60115333e50ba0c6b837c4cf26a027470770358a537481675a7fb7cccb901ce7836b75b010fd687691e96487bda2664756fd6057ffb122f69b26e3fb3ba2625b9fd9c41f4887cd0124df978bdc26b0c6f3b0f9416c38b2145361343c2f2b752c7a885586e4ac9955ff924d2365847c22e06c6556b7858f0d9318c037e03536ce9c5a16220967ac1c55e6c61f00a5902322c8b35bd190042425249f54a3229f90453b0942aa9a31f421463f514dc64024d5616e653c9e94bbae8e82fa914863338c65413a33e520243f92f1c3a888ea8121be984b4e4cfd08285e904c34465bc1477cef53757b1025b10d45415fa2e57931ecad301929437b837146fca445211b5719a933714a1c29b1eb52a3bb36603c072b4ee0b4775d17b7af9c6049825e2b654e1c4bdd8e56f531406cc5297d2ba2cbf19b8c43835d1c184eaa661d9b90a6e99854787c82d53b794d8624d2406e57693143736bb34284608c8b20a9d99695d8f87ae57c83d095a106e793fb7325b80eb26c8cc345ea2b17ed66e3d437631a018a2c8bb7cbc42761b95f2508f92732bfcf9343c4ac48a935fd9260ae0463bdfa69120ea90f3e9909b2541da03516f922e1e58411d1492686529cb030e1c9846f63abd6ae9a781853bcf31af495acf79a49767731eba21a3403140a707c106425c5bfa2ca326247515b229eac449b01227fb1b228c8637732d818c6579e4a5f0189a23793f8e39c1cad40aa70a3c6db8707aa76831dc26a446287d8a4e45ec1ff7eb00782596f7a7aeed5307e5c84039b4231ca6609912c6e4e71dad93012a21800914997f99970489380e12be57979cb6e49861c9605d02a14727a17e286b40712233141e2fd5b3834033e2b215ef44aa752201a65334ac223817e290d2c50338a2681d298061586ad704862770867b0493d0941c4925acda9b4185b64588e25f1015705a885faafb1518a70ab415cab51a25e3139644f31f1bbc0ab9573bf63230ab125891d58143ea8bcb858c7521100ff581ec7a97b351bbcf5b4161f3141ae78986713d5bc15a57e07f2bbb8244b11d81a0804a18ae63104bf75c755f70aa758997233154bfa942a47277ef20b312a68e96201f227a908dd7bc02e19391f73825dc44cd258b707b6da20ca56a2b32c0202308357e48945d79a38c0560271ff0ab2e8c1af246940a797cef018b62873474a38a595127c026699d625ebf0774334b0a953881fbc1b0f5c472f549818d44b63ea59541a826c49754926135670855bcfa888f30a50035208f5a75de6a8e3799cc4afaa7aee007788547e7b79c7507bed6a8522be18743c101463c9d0c28328a68b0d3ec380d04a20a31ab8ce6465e5aab4e2332f30870c5024718b1412c13b7094228e6f3a1a32440edba8f5ca66d968961a3f28705b9778713cd96974e42a50ee9eb61eba399cbcbccfc8786f7963c15d61ef8d194ccf37db2e16a31cb57ba79c9aa4a5da2593eb56c29498ab66f370d7b76971f797f9cd38ac3262226a64f91e03a1119b8eea00c103358572a1f4ab68f8eb4a5f889540913b23ff11768200694597d19218a2c30c3c25829467ac2d1b67f85d37522b22e7e44b950d152a8e087a3a35e3eb1c41fb15c7fc264c39272f01a0a2a91324a1ccbec627fa1ac81edb30ce0f84a727b36a4f9015a25ac67e3c76629c2347c2478d61b42bc413f6920f7b6774542bf25b92a7715745120ac1c4226e3b623860b4a42566829317e09d5868719a1e9babffba9517ac95a7c020882939cca54005f94791f37093eab5f2d15c1e7a09b9ec7b3738a197977c3ca0baf9f093271d00387841f2ab98c9cb16f19272d5e4b8d15e69da97517cf833475336d8850b5c3c87e4ef2c526b95e75060dc52c0292eb69e3f04294c854bfaa0f0fd5432dac0fbd03414b5a4a3b7c7cf36906fee8be6479c193b7336f4c870aca768d3ac2d84234b330a1f160b105214d469c8c1529bf31b3aac01a3ee1e231f389a27d4340b35a463ad002a7f8327dd5abed8b4256e87129b1be8ac475c32b97d11397db247a019533acb1a61c15b9aa4bc91d45af064a608b1926c93acb18b7c75d9798569a89a78463b51b5bbf038dae3c5cd133690ae80c1ad4541267bc10c83343a12439d6844b931a1cc79a0b5090214ca721f61e633600e8f76db52274c6c736e4c8b63089014a4012015522a9385f863507b1f1cc7c814cb47b00395724d601ad7bb27e4b0c43deab0664cc858d4a74576642eab3c76c211a58274e14f615ffe70084d7b7c0189d4d97a927a8b008b85888c57a0f6a307234344a5960836cbf6f4473ad988429a4ae3ba697bf07429d17c059a65d9e35a845735ba0a58e989307376c1e61f33023221a6611ca0465be5200363d49c53cd44b003307e5cc0c4f7b15e1545c72a7c3410ba1bebc8f7314b3b9d295c676bfe6aba9848554fdec9192f808329c60a793754bd6256cd030da12bce0d0765e51548aab0985ac86d1537ba49635641b3a26c05def260e94593b2e0558567c5da09b2cb122655bc4cd3e985eeda6c3f4322765e6a808ca387cc369dc11c9dfab64d4a30584e5329c905dc480801dd57d9ac8ab4087967177cb3163cf3e934a951a3e248a54cb922b6ca6ce9b4cb8bd788023e6425e75aedcc135cd3c59920c5ed0356fc0fb5a1ec0035b7c8271726dc8d63dbab3c78326a26c5b0f9f952cde7373aeca36cf6a438fb39c38a56124171593ea3bb076320bc8b5e74204777b7120ba97c3e803560605cf80c39324a0e3045d0f687e8f219a2ce70aac209b86d869febc5b51398341827204ac584c6b3381471937e68efbe5866a8569838251171647b4127514db9b84482d5b9a89119761c7f6508a099961376d6ae3706f6ca1c7c031f430190d6231425b14c6544cabe8701f8e475892fe31b587aa42d334fd189bdf0c87bedd5c16c32cc3867910f734bdcf09869c7604a59ce36660074f561e12da76eae84d11c4528382828f7a689a0d5cff87b8ca0bba97feacb39b935a8788cb" +}, +{ + "dz" : "5cbb141c2763425c274f7404fe530d9116e08c33f9f200a20b011cf563a28990fc9ebbe336dc464489861db8253606971bd0a9008a433ed17752d04023781552", + "pk" : "7dc26db4f73dd1859b06a852e89a4845a0943e5513e8a056ddcc2623034a4ef251e607268997b7e90471d5d0cfba5639da844f0c9a7227c8a22a83b9e805942b67019ebc45502c22d369abbe52a9aa6cbef78ab914337375d9c075854bc9a3484a0995a239121d918aa64b2ad76c6873790211162509ca2347366d8163803c3433d32068d0f8b64cf38c2370a3546083ed45716dbca7ceea50207736fa51c062a6a15ab8c124ab6b00334e03808c858ab4b20a368df787cde92169aa4100a2adbb4699510753b80a63b492c51f43a81be012fa13405ccbb0dcf1166ef55f450781244420a0ac9301d485ab561b9ab67f5805afff924c1f43a5b1628f60baca631931bfc6c9bb04d0fb3727d7ab6bcd6cadffe84ca57851ee201f8153ae6d64c0d2aaa432baaa0539a17e731cf4360ee37c0e38e0cd77ca85e817a827173bd9c0ad253a44fb244f47f956146b4281109297b05a9320953c022024373d60701a68450cca32883848c4cff3c64f548cf7912ff61a11f06030c5eb29fbf8bdd2b16541fa85b8683493e8239e22c01383985aca367d6cba52c7808ff12b79976b794c70471ba5cc7908e4168d5c916605337f26199c34519236a855ef063423d7777631bddf164b2375098a25c9fbe9a7f9344ac12aa0b65a1380946560123f82e033fe33638788c82e7abf79b2c4df9c6da2f4301d70465a3c05e3a485a26a3b8d98674d91594f24761f1654580719260c4b409b2fcc418a24082a11140d043a6dea028dea1a51e9224fddaab5f3aa64564b3c336586dd8587442800ead481c9d27ef08908b938945b7204557c38aee2753709b68088684637bd39f1b78c6929c84873822caa30b2584a02c93b085380524405caa5d9147e6c837bf0ccb1aea19db39471d1a573fd893028479391680282922b11ab4d78b407f7d68eb89b615c32593f2207a4b017fd1cb922778ca806b305600546700d9ecc70ccf292ca7ca0ce6b6fc2a79731f6a9e8b83c9492381ad561f657192bb3867d3cc663bc5ffb48c997403b4814c915616d03ca71d0e8a93ef0acab8a55a61a6a58d22845e27d6c453b79391dbe02797d390e262a6be41cb564152768a5b1f2b7306872bc9dd63327e22e518082ad337f0eb8494ea23e7c730f48e94d21ca9ca3f660d4f960a6285f1e586d04120a083b814ec4229717b23b73c0c14aa6bd45294601bcaa89429814ad6e8a6190289758354043eb6d81842a6f332524da9e63dc7570865695c043c9eb9c5925bf4c4b15bee14aa58a09c4d37c822ba891f2626a414d01a10f9fbcbde5609bf4d982e23392a4cc16c461260bc518717584bfb96e6960b6d4b673f61663be1b2babe74d46494ca9576f3200ae3ca8a58de308d8e99b65384ccc30aa1669898722b1a76c87dcc276474a74c2985e746194844c0e98f811dec520bb54a1b4572b0c39ad04820f8ea878baa9caf03018d4a196c5363f55373ef5a98890c719b7a019d0eb023e319241081694e74bafda502529020a8b8f1590b73d1bc36ccbc8d4bb76c44361309977270231a51a7999e65b923b1200366ef381b8fcf8c4c5d3add0c465f7db79f7563dcc67940312ca49981581a798ae477915f078f11023c50efef1acf4f751801bfeaa5ef93fe27771a40a3d377f0f1b1655f6ed13320e", + "sk" : "e2903ded4136ae2736d2f6522417953c15774fd1bf9160b6553b0a6f8810e2208a9205833c5479562ac268b6618787c4859838020a1cf2d16d7f8cce4f18872c20703522463ae5c2cdeb4952d579a9c2726783562364cf8d86cd1254c76ce667df6155ddeca4572506240723ec8561d7c65ff953158ef4cb3be6ce823c5501db9e29d8c1fc23327b04067f755b87d984348acb362b22cd416d754b82e52483d8cb422eba4ba8e649faf56f30586f09d4acac0c3007ec6ca1732eae602a004b58368785325b06124156248b22d69806b6b2947a75cb16b824d35c7ec26a7a6722c4fb36a5aa538c16e4b6d366344d049b36e53a6980177f3989c301293d3450c8e2abdbc186972990dd933f9cba7ba31717bc3126d19a0fc3d090ba37c447db6143b63383745c866371c426171b667096e46e0c2942d40b4ac2f08f48b136ef09c82eb5bdb13a514876274bb20c6b40a600d1cfa0a8b29ddbcfaca547d1680067786d6e50a64b70546ae3af52451a08028976ba78b9275a2b011858e0cabff149f7854abd2b390d28a661c7a871467a2603c5ce29866839208b5386714618b6a2012fe2b4b9753c8d21bbe74c477f427e72181988d0a094c15a9c24a7eab46be919a71fd60879a67480178453f4aed9b63c11040d370322d43b4077e74d8f8966319042c9559b021cccdb0874009d61e3a3970c14b34a180cdfe0a2f9d5bf60954cb79b5b69169598fc88a9b11ea1287a8cc88f877659577433a97c16af3ca892d40cdba7642fc24f258a0207da5e818580694582b7b7982a7bbb5de714e7425b7552aeb394037827a98e765d96310d5014a7e69b3db3b6797bd60650e36e1ebb0342a77576f496a7255d936c5eab1ba3d9fb57d72305272a5e567c621746720878cdab13a9f5b0afa5101a6f7b844af1bbf660c584205bcecb22a74b79c5b4302f29bbc502b4a3c9854682c8b123a33d949d878b4ae609ac5386ab5896ae2b877338b3200e582f34fa450adbb27480296b0bc6e0e73c2ec1b633f56d1b8a54ea65ab7cb62e5e4a2c4e82a957194321e1bb39413c3990b74b54ce213008979146c47301e3c8489b257be7a50ae6d39a5cac1dafd41ef2a91b54756779e5a8e5ab79ce481ef9f80195ba808769a158e0b48b52669c01980338042d2a5e21362703827ad9433cfce6191c7c737deb92ca3053eaa80d9c9234f54715b31013cdd31afa49a24993669adb72ced3c7e3c02c76aab8ba56a29686a115f4b36deb2fe00bb42cbb6ba8a825d9888f6347a6e61a7892e06c8ff9b8fbf1270d02beddd4268fe4615f9994ef8b93c8615b6a63c9b4d752a46c51ebe9c4d97c160fa27f8cb62aa22344f14339875b6d0f920875c3b831186ee6f04c745756d57b875098a55fc1b060f353f606bb073690546769dc61600a671cac18b563aca5e6a8a887eb76bf88a33d814ce9f32db7cb5cc3d16636493421fbc550ac90a4b99611b39cef828dbf056c0f5043be8b003e260610f27a59a2765d57a13d2281d6904526b93d7745b4f8b98085397688ab559d073f88716dfe5a39d09975de107a3e6c68ee17b3b63a9b10ea6f4531bdb627bb07494f279052cbca04722bcc0014bb3993219236397dc26db4f73dd1859b06a852e89a4845a0943e5513e8a056ddcc2623034a4ef251e607268997b7e90471d5d0cfba5639da844f0c9a7227c8a22a83b9e805942b67019ebc45502c22d369abbe52a9aa6cbef78ab914337375d9c075854bc9a3484a0995a239121d918aa64b2ad76c6873790211162509ca2347366d8163803c3433d32068d0f8b64cf38c2370a3546083ed45716dbca7ceea50207736fa51c062a6a15ab8c124ab6b00334e03808c858ab4b20a368df787cde92169aa4100a2adbb4699510753b80a63b492c51f43a81be012fa13405ccbb0dcf1166ef55f450781244420a0ac9301d485ab561b9ab67f5805afff924c1f43a5b1628f60baca631931bfc6c9bb04d0fb3727d7ab6bcd6cadffe84ca57851ee201f8153ae6d64c0d2aaa432baaa0539a17e731cf4360ee37c0e38e0cd77ca85e817a827173bd9c0ad253a44fb244f47f956146b4281109297b05a9320953c022024373d60701a68450cca32883848c4cff3c64f548cf7912ff61a11f06030c5eb29fbf8bdd2b16541fa85b8683493e8239e22c01383985aca367d6cba52c7808ff12b79976b794c70471ba5cc7908e4168d5c916605337f26199c34519236a855ef063423d7777631bddf164b2375098a25c9fbe9a7f9344ac12aa0b65a1380946560123f82e033fe33638788c82e7abf79b2c4df9c6da2f4301d70465a3c05e3a485a26a3b8d98674d91594f24761f1654580719260c4b409b2fcc418a24082a11140d043a6dea028dea1a51e9224fddaab5f3aa64564b3c336586dd8587442800ead481c9d27ef08908b938945b7204557c38aee2753709b68088684637bd39f1b78c6929c84873822caa30b2584a02c93b085380524405caa5d9147e6c837bf0ccb1aea19db39471d1a573fd893028479391680282922b11ab4d78b407f7d68eb89b615c32593f2207a4b017fd1cb922778ca806b305600546700d9ecc70ccf292ca7ca0ce6b6fc2a79731f6a9e8b83c9492381ad561f657192bb3867d3cc663bc5ffb48c997403b4814c915616d03ca71d0e8a93ef0acab8a55a61a6a58d22845e27d6c453b79391dbe02797d390e262a6be41cb564152768a5b1f2b7306872bc9dd63327e22e518082ad337f0eb8494ea23e7c730f48e94d21ca9ca3f660d4f960a6285f1e586d04120a083b814ec4229717b23b73c0c14aa6bd45294601bcaa89429814ad6e8a6190289758354043eb6d81842a6f332524da9e63dc7570865695c043c9eb9c5925bf4c4b15bee14aa58a09c4d37c822ba891f2626a414d01a10f9fbcbde5609bf4d982e23392a4cc16c461260bc518717584bfb96e6960b6d4b673f61663be1b2babe74d46494ca9576f3200ae3ca8a58de308d8e99b65384ccc30aa1669898722b1a76c87dcc276474a74c2985e746194844c0e98f811dec520bb54a1b4572b0c39ad04820f8ea878baa9caf03018d4a196c5363f55373ef5a98890c719b7a019d0eb023e319241081694e74bafda502529020a8b8f1590b73d1bc36ccbc8d4bb76c44361309977270231a51a7999e65b923b1200366ef381b8fcf8c4c5d3add0c465f7db79f7563dcc67940312ca49981581a798ae477915f078f11023c50efef1acf4f751801bfeaa5ef93fe27771a40a3d377f0f1b1655f6ed13320e9a9a59f83fc58d7194ccc92bd78a45f97f721a1eb554499d0e4d5b37aefc23a8fc9ebbe336dc464489861db8253606971bd0a9008a433ed17752d04023781552" +}, +{ + "dz" : "293abb6d1c207927945417cf84883ef010823e11b487ed55239e466e83696d0cff8563038aad865a817cab9ce98846ba75be9363718ecf5fea538aea90b2a558", + "pk" : "790847ed9a831c0cc2acbaa793c41913a02db8ac1c6bf056573bb75e2990a6fcb732c3461ccb174dab8ea4c55781317e400ab4ef68138ff84c27fc0bc4c68e30eb664cc8bb32b617916c155d28a195fc39a1a0419af64a59c99664f744a375113228ba3730752ce5a06701112d7328649a3755b45ad6bc4bc0859feb014e185b2e18603ea0437b31432457b36d13a5ae96b03905bb2fd0d5377eb04f34a68c57448e7909cc660a31d9f9540af17324e4b31bf04f465665b5538f7351687f238d6c423c9237b5ca35618f092cf7da879d965b67b1cdb2467c9ef3862f260c04727594aa6286f4035f0b0eeeb4b141306cf7d9c4a6bb942b7a1e30b56ae958b16c3c1237603ae6f879dc9ca96a2439e26c0834369e8b041c6327254608ad3727cdf23b842a003b91d1aee60193ae1497d5b75e2a370147f052a08b1f86179bad52605df44f6c99c75df478017318c6ba017a1b4a8302888f495acf796e0745adb0292ea6b5526fe43f96e20d98fb756b2553a9493401d4a25b9bbac13b62967a228bb6446b2067063619af66383e6bc2b3d8cbb9e6969196bb45d665bce49284c5b50f934774d500c90134535930ad2169488c4ba8ac0854f36e085318a293bd65ea8e033c754ea44191d9ac8033c031e066b2021c13fa11a15222cab4829a5c47df7418761620aad92135169e0f008760ba30a289cd41f1325a4c90334978c5176cdc5496962443b118a641d6130baca422d89fac5c968adb461ab43729b6c9b1349e71116c0226b55fc00323d6a74c03282f24997949207d72ce58fa4d87a7413c3bbaeac91fb2131c418c11ba501701549efb25cdf560239223c90e1a2f99897fad594930848a1ba2494fa87bc03c57c7bc33463b77ef80b978724153a956779028b7a565c40144047747e124c7db801d309333d3150493c3b3ab68c34c939243454d90c3c4079174a8171c77a0b0c9e54277b5bbc5033eb1eba3cac86039492b4e75a23c8c51c88177edd639a55b56fc557b580b03935765cf586c95178c330319c70a8c15c95fc18a23da11798cf6c54f68bfb766a61a9c9c461b766b4a00608575c4309a621b28d27122cbbcc76c30a30286483ba85a68524c0e21591b7347a0ac0931e121eb3bb8d0fb7d9ec577a5821487619e196400c2169a42a71c7665505bf333ac70267bb50380b947ffd54745e41de5a30a27b78a62f43786ac88b2012de563cde100358065485a73505982a265a505ed85cadc02228ff90a03d088da7410c6179558d52ca36ba1d87353985189a709a1c0a7a10cd8513c4aa26d27cf802027aa8c5bb99c12a51b7f16e10838500132cc24d79c805cf11a5bac88c4bb0377ebcc4fe7c6ffb927ebe7234016bcc1765ae9e72e62d51f9cd91017f508ae207d181ab0c4dcc8d1c4742494876d118f40c84e2706914c65a161d184a5765aec67c9dcfa4bf3418e114c6f3cc34e94a149fc84b041853af9b213759cc5a181abd5641285613875367842f1a2549c09eb9b1dbd851365d58e6335c91ee7ade6c23135c1200cfc1de3f5cf6fd13967150f01053b943c3389bc4670da9857ccc32528920f781cbf16a9dde2299db9912e87321c02aac45c4820ba2e808666ee521dc4bed006527df29a124412a4a19aa26c09b490188ccba53900a2545022", + "sk" : "eb9a0f50030024200b530580640112b904c9190bcc0f7b6c9b071086aba50212517eb401a356cdbb8547b1e06ceb0695f002c9982518e6258faaa84cb7b0885d1c9272bc8acef294c2aaba89696e4569cf3493cd69db0c9629c6af282a6828a0dba65f1c2802af72bbfcd102e9ec5395f0473d29b9bcd99d8c803aedea59aa5b11f798230917c5196b2ea9a950e3834e7f272b8c6760b07c8597025cf62b63922768d89955315c2f36907ecb89b97db098d7348b9643ba56582915b9558fa519bb1530d7b8461831c996731cfd2b4d46643c0de99c459b93279173a83b423a073367ba8e79904bb431760b969a4b7b98f10a0e5fd1aa75e52b59fb9af4123ad65b645aec03c7e2c35eab02e201b92c266b98c5932ea3b6029345f1f8085c955fadf2c840cca34cc801ce489415781cbfc598f1f39ca240257a0c173b6108482c9720f56afcf250c2c704c514214fe0155289470ea5470cc1a4eb5c999bf8567d688d5a4a2a7cc1c3381c68bec925ab312acf037113fa8c5cc43a75f3baf932672ecb3ed412b17b5520351918297525c5d352076ca04d2a3833d306a321b9a9b1564504b8e70aa8e9a91ef47001a42c66b33370db2ab3e9b43f32e926e7ac189252af3c9ac7bd420c35767e1b26b161823da4fbcfa11232dea1143718b6b9e6aad183311f756c04c15e8df99bafc854e751417c1aa5fd64623df434f2c70dbd8ab6d41395cdf4814bc99ebe5c1dd0777c7344c1504b7e2ff4b82d974e01600d1293c5ec2a4b34fc895e608ad7a32b2fa6cdeeb2b2867a8aef27aae73ca70a5670c3857501f5c4231448a4e7b4a9926c1ffb58b0aa73705c1eb1e70068d97de17b19a1814c34d746570bb3d142a6b7c49d52d78f501a6bfe37abdb1905a30077a21a1b0e5a14f6784db89197121143b851ce1d975db4f50ab75a8138e60a542cc41aaa6c55626d81535044d0a1865b4d6303c649b3545511440a320cf5260d0b85041f6c26f92a13f01c77bca3357c26bd0dd00084a54ebeb7330f59683597bb733182a4ec7b15e8656dda8bf0a8b38fc3632e00bcf5938706c55d94623dd9c11bb57036783593df9b85bd9b9b2c430d94c73a53b65da10a614d93c6da7cbe899a096ef3c608f747cb782955d0402d9831b9889f6a7708ffa7caf87a8dcb1a18b74c363037c890470d18805befe3a0bf058e64850d61614948f41a2f03446bc9c6d65750ba421e2bb8510f2a8789b20ae70c1331402a550480fad8c011494d7cc25c573b4b23ba4c96f99abc5a6d8ef2195284ba54678f15543243362c6aeaaec2812e76382dfa36c2b1704dfb559a27d5b8f7469596a28c9e2b0d426aad0c57b2407346a6ba267690cc8f30857d2858aa5b97e286017c494bcbf398ace755fb5b0d041aad180691c85994d331616e91a9bc4932122c35b55b8300264e5d3533f7518c59c4cc4cdc5c3894b48f247b1433666efc9934f18234535e18bb43b5ba5d9b6979bb14bb8d407d0e15704ac6cd1bea3466d41362a261e9e3c4cb73b625690f1bf755db67ac556528700a78ca973391b34d448abe2bc96447dc8f96239e6d06c41dca9fe04272e438b7437c6e0bab01797475adf9cf716430dc2b4a9ad16e790847ed9a831c0cc2acbaa793c41913a02db8ac1c6bf056573bb75e2990a6fcb732c3461ccb174dab8ea4c55781317e400ab4ef68138ff84c27fc0bc4c68e30eb664cc8bb32b617916c155d28a195fc39a1a0419af64a59c99664f744a375113228ba3730752ce5a06701112d7328649a3755b45ad6bc4bc0859feb014e185b2e18603ea0437b31432457b36d13a5ae96b03905bb2fd0d5377eb04f34a68c57448e7909cc660a31d9f9540af17324e4b31bf04f465665b5538f7351687f238d6c423c9237b5ca35618f092cf7da879d965b67b1cdb2467c9ef3862f260c04727594aa6286f4035f0b0eeeb4b141306cf7d9c4a6bb942b7a1e30b56ae958b16c3c1237603ae6f879dc9ca96a2439e26c0834369e8b041c6327254608ad3727cdf23b842a003b91d1aee60193ae1497d5b75e2a370147f052a08b1f86179bad52605df44f6c99c75df478017318c6ba017a1b4a8302888f495acf796e0745adb0292ea6b5526fe43f96e20d98fb756b2553a9493401d4a25b9bbac13b62967a228bb6446b2067063619af66383e6bc2b3d8cbb9e6969196bb45d665bce49284c5b50f934774d500c90134535930ad2169488c4ba8ac0854f36e085318a293bd65ea8e033c754ea44191d9ac8033c031e066b2021c13fa11a15222cab4829a5c47df7418761620aad92135169e0f008760ba30a289cd41f1325a4c90334978c5176cdc5496962443b118a641d6130baca422d89fac5c968adb461ab43729b6c9b1349e71116c0226b55fc00323d6a74c03282f24997949207d72ce58fa4d87a7413c3bbaeac91fb2131c418c11ba501701549efb25cdf560239223c90e1a2f99897fad594930848a1ba2494fa87bc03c57c7bc33463b77ef80b978724153a956779028b7a565c40144047747e124c7db801d309333d3150493c3b3ab68c34c939243454d90c3c4079174a8171c77a0b0c9e54277b5bbc5033eb1eba3cac86039492b4e75a23c8c51c88177edd639a55b56fc557b580b03935765cf586c95178c330319c70a8c15c95fc18a23da11798cf6c54f68bfb766a61a9c9c461b766b4a00608575c4309a621b28d27122cbbcc76c30a30286483ba85a68524c0e21591b7347a0ac0931e121eb3bb8d0fb7d9ec577a5821487619e196400c2169a42a71c7665505bf333ac70267bb50380b947ffd54745e41de5a30a27b78a62f43786ac88b2012de563cde100358065485a73505982a265a505ed85cadc02228ff90a03d088da7410c6179558d52ca36ba1d87353985189a709a1c0a7a10cd8513c4aa26d27cf802027aa8c5bb99c12a51b7f16e10838500132cc24d79c805cf11a5bac88c4bb0377ebcc4fe7c6ffb927ebe7234016bcc1765ae9e72e62d51f9cd91017f508ae207d181ab0c4dcc8d1c4742494876d118f40c84e2706914c65a161d184a5765aec67c9dcfa4bf3418e114c6f3cc34e94a149fc84b041853af9b213759cc5a181abd5641285613875367842f1a2549c09eb9b1dbd851365d58e6335c91ee7ade6c23135c1200cfc1de3f5cf6fd13967150f01053b943c3389bc4670da9857ccc32528920f781cbf16a9dde2299db9912e87321c02aac45c4820ba2e808666ee521dc4bed006527df29a124412a4a19aa26c09b490188ccba53900a2545022bda0815dd53b263afcc1f71d2501128c41fb3606af71c5e68f0752c6d3a479c5ff8563038aad865a817cab9ce98846ba75be9363718ecf5fea538aea90b2a558" +}, +{ + "dz" : "74d87c7556f2671f2d666854a4d6e073e69f35421e6e1a428cccea49c37f972ce1fb7456ac0aa1b97068f452cba64ebdc138bcf5d36b0a0fada2a3b374141eb9", + "pk" : "39dabcbaa131e892a48fbb80f78961f9c440322b49edb03f0e554328eac7c0b3ceef957a82370a8e8169cb24a81595cc89f95d70179834da375d55a1d16a7a8fac8e7da64508c97f4f7a53066ac34d407b42a6be091696351b3fb1f12c05e5429cb0a14208336e110ae4b89fc9b91edd0037392948e7d3beb78b880d3c6d933a73bf909593a0654ea18a5cec051cd17c25abb7020487579a98f62b49c2969e3df7407f9bbf0b01237a0994cc7312b0992cba7566cfc2818db511d37b1f06781b3dab99db5268f527123a0366bf481faaeca57e16b37e27758c8b83125049f3f38681ba5438a795021652b5f81c02876c0f404b44f06976e368aa2cb923081e3dd07781562ae4750bc5f3809226ae6f100fb8f67faa433b66f8153d6a1b846c589b471ea6479bdb05c741dabf217a6177f2ae8224bd05b46de5f1a42ae20a1e641238f541fd282dff3821414890600a970811795c993c8ba5418a8732b6c8b8abf738fc5ca7d32aa3f87884021968a93cc271a490de61c5f8143be65485c9f34f0d433e492bbc5e215cfa037428a51d5921404d89aa0ba6181f5294d706786a30508c5990ad24c7bb6a70d6017207d3c03100a222396c44752579859e07315cf9c397549708901748c6958cbfd41e9d2880e9773ff03808480bb38c36bdefaa5f81f85700fac88ca85829e03d9bb845227a0a799b156d0952d0c54bd5b010c565a381b55885d26cd9e9b82d21a31354c17d2bcd43d93946bb58ed2a57c13509e9537fe879714c64cdbc842e93326aac0944cb3898335004d0fc9c81546086f29136227efbc798032aaf0cba0f3c6aac788886e03c87245964c99c18e62c008d646621d127856c7559370f5fa26301321bdcf502d1d12305002b2ae42e61209892d7b3afaa6cbfa9a38ac097cb26c4745a4eae395a1b10bf80829d1b216b4da59fcb4a2a57d4070ac2ab59a82b6af3b0682b53f9928f7759ce20e1a09042948ba966cee8bd176b2ec6880c063b3ed6d1160fb26714b3ae7b44a4ce6c759555c6e478c0a71a90b62a8cf8f282a4f7c21c31c5becac2595a766a977c886009e9414123e5723e101e667647bb9a2489b3acd17a81ffb4512516893ceba8838949e998043713bb41073013d487cba107f31c84480a0ce4378732d9446970716365278f70719da66ddd8283d62190530566904221b383441124b6f3d47103d64983898f8d83a4fef6489b0c08a11b82d30cc4d9eb4fd0d99085c875dd4801e3902405f0b292b8487a72867e67200c9231ffdb43e2048caaa203c7883218f9a1af7a365a19b0d2fa595a087b2afa1f16686dbd24a98b931a5999483d467d2d264b21ba527ca419b6523fc046bf7fa96bf0a277af5094f3362dc863b8bc2192e5d78173d77139d6ad07e091e7ea507f2a7a9bf982aac812f736c787c27b04e25d1cb74d5d01c3fe6aa2e7248921225632a5033fc6342495167405028d410bc42c8bdb498d9a5260693ba326e2230c6040f332454f3b2020280ffe6bb0b7021f4ea6bb4c06980b62a9b6c89a935ac206b13e091c3c6ae609417ab8c66b7bce94986e92596ee64b08a53844b706f84731755ca02c7c49906cbbdce97c64019a52f278c2f286eacd5a261f5b502251ec136ec0a3c697fc30e8b59807dff5dced3d6bef9c96bf", + "sk" : "878a1795956ec490aafe2190fe1a0018c9b51fcaa6b97c13da28a8c09a7fd0434596fc21d4e65bfee21efdf30059aaa51bc63c7d646f14f1aa487540380155b4e51fde096389c3a1b983373df0669553334da5ae1e9304619948cb85ad5be4219683033e33ba0f01750fc62ffe5331b4e3756e46cbca7b2fa45c26b8e6b8121719a6655f0952b9df797717ca88bd79a769938ac2f68d4347baa9dc2908757e19157953cc9522261118155df98419dd88556d961ef9855e20c86c4511cc7642c50bb4a35ab30e133b3548055c0ec585d9e1a390226749a739ebc5ca7834ae6776cdb6e461b5b736b11806e59521f010543568ad18097e8654c4cb7c9366db7990439b93a06e83391a62b90fa84a0b842500cc5bba4505ab41f60e8414768ffc1cb9e1b8334869723185aa5b141b94a21d276d3b769237e44f8ee373a8591ba9f6ca2bc852056334e41b1b3348c7687c8688c02b6d3acd484b4f2d9513bf181363a683547176cb1219fef44433899d93863e22274d7e157ee0188be6f53492655c801b4a29c7bde7048d798caf9c475665462732a51a080345fd0292b3b93b4c354a1f3c8b5680c9ef6bad9249472d761d25740e92e1c29e17bd38e989442b60a178ac720b935fa41baea41d1124183784941f510763001f20004caf2b4314cc6e3cfa7d3eda5e78451f27c7c49fb8253a93500ea757f1bcb4e97778b3866f9709083fba0cdf1031a0c667c5f65880d157bfe5986368ad80362dc1a596d31a488835b8e9b1a80ee55ddb146880a235ccb5c8dc64913a80c6c02c44e86bcd40e56737443c49d6bb4ac1501b264fc104a522784c5cc94c9e186ba7a22c329612985b6eced06e373669b691c620c4c6ea170c05c28d022158ad3053c89cae8b144c634ccde032503dd03beeb602e06165487ab4eb1292e484989f6135f50a08251bb5030088583187a57b10aac08b61b0911caa8685657bfaa40ff389310ab3b54efa8df4bacc32d112a2191a8068a390b1a8219a7954fb3cef743c22abb2c1820f86a7b3c8488788816493d300883b8370688b7d0560eca63430aaaa3f4b44d7ea887d70431c266e09c7769992328bc7b2a53734729297130a59e56c3d57893dc3fa7ffcb0070f7267cbe1ac7f2c18061b26409819d9526ee5dabaa47092ce07c2db567a72f80ce9a5284c70c6f6482701ac71c71454185099f62424c81b344fb83ab3475693d6797c5348c7985536550bfc1cabfb6806d1686139a8c920832ec675049f40a0ccca236375153a79c4ccb7380aca2e30038c8f2b745290bef444a71b73839707b524d07a2d1c4f4b00782e9c91447700594b30adfc7868eb546ac27fad089f7046ba8715c41e292415d274c3f03c5f57b311110000fc614bc30960b26edef3961c258240e333a8494b5aa3152c39c728464d6915c8016106cd34213e1137fca383d3b94d545bab479cc11231be67634beb00272b59728f628555baaf35e7bea2c664f616945629cc381042152ab0062902b6d5b3204266a98701f376a278778cb4281e47a6a82c6c1b0f2221577909f9297616f356be210f0f3265f6690ee5b1385ffa8f457a5ec860c01388480a09413181b9602909de7a3dcce34f39dabcbaa131e892a48fbb80f78961f9c440322b49edb03f0e554328eac7c0b3ceef957a82370a8e8169cb24a81595cc89f95d70179834da375d55a1d16a7a8fac8e7da64508c97f4f7a53066ac34d407b42a6be091696351b3fb1f12c05e5429cb0a14208336e110ae4b89fc9b91edd0037392948e7d3beb78b880d3c6d933a73bf909593a0654ea18a5cec051cd17c25abb7020487579a98f62b49c2969e3df7407f9bbf0b01237a0994cc7312b0992cba7566cfc2818db511d37b1f06781b3dab99db5268f527123a0366bf481faaeca57e16b37e27758c8b83125049f3f38681ba5438a795021652b5f81c02876c0f404b44f06976e368aa2cb923081e3dd07781562ae4750bc5f3809226ae6f100fb8f67faa433b66f8153d6a1b846c589b471ea6479bdb05c741dabf217a6177f2ae8224bd05b46de5f1a42ae20a1e641238f541fd282dff3821414890600a970811795c993c8ba5418a8732b6c8b8abf738fc5ca7d32aa3f87884021968a93cc271a490de61c5f8143be65485c9f34f0d433e492bbc5e215cfa037428a51d5921404d89aa0ba6181f5294d706786a30508c5990ad24c7bb6a70d6017207d3c03100a222396c44752579859e07315cf9c397549708901748c6958cbfd41e9d2880e9773ff03808480bb38c36bdefaa5f81f85700fac88ca85829e03d9bb845227a0a799b156d0952d0c54bd5b010c565a381b55885d26cd9e9b82d21a31354c17d2bcd43d93946bb58ed2a57c13509e9537fe879714c64cdbc842e93326aac0944cb3898335004d0fc9c81546086f29136227efbc798032aaf0cba0f3c6aac788886e03c87245964c99c18e62c008d646621d127856c7559370f5fa26301321bdcf502d1d12305002b2ae42e61209892d7b3afaa6cbfa9a38ac097cb26c4745a4eae395a1b10bf80829d1b216b4da59fcb4a2a57d4070ac2ab59a82b6af3b0682b53f9928f7759ce20e1a09042948ba966cee8bd176b2ec6880c063b3ed6d1160fb26714b3ae7b44a4ce6c759555c6e478c0a71a90b62a8cf8f282a4f7c21c31c5becac2595a766a977c886009e9414123e5723e101e667647bb9a2489b3acd17a81ffb4512516893ceba8838949e998043713bb41073013d487cba107f31c84480a0ce4378732d9446970716365278f70719da66ddd8283d62190530566904221b383441124b6f3d47103d64983898f8d83a4fef6489b0c08a11b82d30cc4d9eb4fd0d99085c875dd4801e3902405f0b292b8487a72867e67200c9231ffdb43e2048caaa203c7883218f9a1af7a365a19b0d2fa595a087b2afa1f16686dbd24a98b931a5999483d467d2d264b21ba527ca419b6523fc046bf7fa96bf0a277af5094f3362dc863b8bc2192e5d78173d77139d6ad07e091e7ea507f2a7a9bf982aac812f736c787c27b04e25d1cb74d5d01c3fe6aa2e7248921225632a5033fc6342495167405028d410bc42c8bdb498d9a5260693ba326e2230c6040f332454f3b2020280ffe6bb0b7021f4ea6bb4c06980b62a9b6c89a935ac206b13e091c3c6ae609417ab8c66b7bce94986e92596ee64b08a53844b706f84731755ca02c7c49906cbbdce97c64019a52f278c2f286eacd5a261f5b502251ec136ec0a3c697fc30e8b59807dff5dced3d6bef9c96bfe3e96e658787ba3f6ffb47de56322541a2c81f68e2825c74cb75ab01d4b719d6e1fb7456ac0aa1b97068f452cba64ebdc138bcf5d36b0a0fada2a3b374141eb9" +}, +{ + "dz" : "013bab0212d04ecd54b478daf72748003a25e2cb060ba6cc50bf95c292b8206b9da0c5da5f195b80fbb99c2e8b06926074f3f604b3f6195b5a5b9737876bba72", + "pk" : "185bb36d9c3ba85a46a5f605706979ebd66da03c15f1b4c25b886faca00b16e04f87b773d0b8724bb4947c615344f9466f78cae8d049876c9f7143154abc47110b0deac571bbe83577f577046830031a08b465b86e1c341c82660818cd2f8173c5c558975868f0281470f39e737b6cf964008e040382b290795254380b4850db27dff98838d9921eaa8146022937e36af6b030b8919bfea844d9d602ccb3547d5c07f612c12c3c179ffc30fe52c9273b5c0dd27934b5a41737817be0739425736bb0cdd267beacd0bd77085cd2794947051099c3848fe0aa2bcaa18f6a18afb626fdf1b977f376ea74a9cbd638932600efd84fc053650474c801b1a8ed941cc5444922915173ec1971698172f8a61730358c751d2d776d93c866c47802e2ac19c7c092aceb53996c20375b47413a66c06541b4343c548b4dc5341ea92b2266d9c0f1665719f62a72650414940bf3a20a260a5953d578d5aa48a2b670aff7512bf6937e49052c3ab8ba07016d06a9d643081dd52009b358ac13c3136cc65b0127e675bb55b8598940c054c8b797d37312a1ae48120934a559ba31042e160ddd13c744d7ac5dd614d198a33253b829016fae7ca51d397330ba1aac557a8fb56477224324924276aa52b7000f77db547a604f6d7189ef83071293465012b6133a6e1209af3009a867a46bf2868f8ab8a932784b76084998e37eaa4496c661a42e9802f5e1ca947c75bc4a572562733409757855031c9627152c02cd25a9b9725adae909175b27c53c6233e4480cd3a06954afed889ae97a091df86842483edfcb5df9a365929b6da98917ca7b025490b416a7abfda408f07429244a9202a23d23ea8ae96bc8ddd747d1eb9b79a3cf3610bc4eb56f9de38c3fb77db2740504e85107f46896202684db8103b1c488e9b731f0a2bcc40b563226d05946c9fcc1a4e287628bc4985189e05a5174709f00c43eda4897429773140b30bcc090ada25c91b8858f07068bc6c154030f048c1a7002ab58e157ee5b0e682877372426e193cbbdd3c63dec0a725c90d29411986a249cb30ecd981a92519ece4074f18ab92967220ac1c963503a295c570d7084c2917ec9b6a4663a931d6a505d11757ab2935fa708e9b6ad5fc1187f3717c6a4a818d57cf5395626c8a3917012fba13315902391116ff5015051dc8d07ec0716356d20a184458b4089a37fa9a713aa35c8ad1635a7fb49e6bb44cdf4628a3b84b9869dd760262cc487f44a361b9c1106553338cc5dd71c45c37a3bde98036f45231dea2a83001d82203b27aa054cd1bfcd215f477a7e43d31d946971b0d3223868922699b0d810b6fbcc834104bc0ba2cc7a50bc198616468c212c9b9dab2550282a9b88f8a1b6d006ba801544b62564dc05cad68d7f6b143222a5bb28bc9cb57788d417fdb73bd0778fe0529a35190b0912623df81a7387cef7d201aa007a199735bc3aaef9706c6dfa1b0256b872320459951111b90caf3202ceb8c10a480addf08dae881eecd0cec08a2adc61c20e8c15b60824653492e603bc3c203fc35ca536fb7c64084112c878741b83870620eda2997f38aff953217bec592eea7947e8be23fb627251c13fdc9bb0b705491151b8197cb07ec66dd1d49dab7f9d23aa8ffa435f2cc7a7a3a1cddab6e37ab7be45fbbc8a", + "sk" : "4b11a51a0bac67897ea9cc5d7d071855bc8bb375a18d838016fcc506bbbc7af38473e4275eb5449b0a5b7145b49c700626f7b6e5a6907879c541a0c6f027b7403a5fc25b42da3a7c9308a51e863eb346c178c469bb27022cec566df469340205fdd84f4f0a79842913a974a7f50c2aeaf35e37673c4ae52e5820c7ea843109e403ba5329a9818a856050eff789d4b71acdfc34761c39ae130fdadc300bc6b3295380d3c6944213100e43788204a41c75395142b5b5bcce2ee71ba4b14ff09325c9d884bbf9199e132551a444e527bb98e6b12a8210c6fca2a054bf8fe346c2db0ee9e97390fa2699c60a1e9c4599cc37110460d27b8a5f741d58fcb62962a38143aee0377d6d440662506200fd44bf71631c479080660a9c6286ca3bc0d5f9aa44e7cf23342bcf37a9d710c86ae39e4795c796805f0198b25d0b87e4f77e01b970e2858d26542e92eb356c276e7e95bc77019c4e90bab92c139ae10ef59b44cf8cc7e9b5b59d710f4bf2b8a4a5c5881018d9f593fa5b4c745a3f12457171b735920250778045c0fa3e1378c4aca8388245484a232d1bb020ea665e60da9f28a10e9992022098286c918cbc40476e7c8bde62cc27ebbfd4c10dc76982781ca59d630e086771dbaa1338814496a7ab32913c837264c527080c9b6d39c25e623b61fc180a29aa3271f84a1bc50b7e678143939ae5fc17d33bbf52d95e53b525ff8a8a408acf61d887585b561c3a69b088388f88532c8482a20c445e40362d1c4a331211d8f999c3f2424379b560b5ab4e6b655ff16e0904136a27774ab93233217ecfa58501c1ce6feb7e448ca9f3c76a52511a4a10008cecad9742368b104521b1b4e5461bed4c1a78ec9265d23272c06ba6c492bbe9af2704b9043510ab869af5d9b63ebbb8c2d26051b9b452d5c1605a7c4d60ced3a930aeb63a865056e1f00e3fe450a2da299d3c1583e52ff109cb2837c6b34abf6b063afe82c86b2049d7335ba4762f8b9c039f49c3554c9ccfa95e9105aaa0419d39bc695c873ea42313973724f02729383b90780c55ede19ee06b631752c2c835b0c2f04666bbcbbda79077a270bbd670edf111f5d578cc1b4589e31c22bbaad3c4044c1cb67707aca78c6d7c3441fee377720a6ab1c5b13f3530bc73020200983a962c1403a20d388b2ba71e777c28c3fa066ef0bdc5c94e0df40188f06800cd3ddf1c34b139bba633cc680079042b934db02ff093bd38fc9779f694196b160dd35c0a51c9f56bc4768333b07c4736e5c41ce048582c69f066ae08bcc4bb3c58fae435f6b53f8b533af1309a5b91bf3301b4a315491eb60670b1cb7e60424451031d6786b1f13360c8119be05955c37336f49bd4c2a7e7b15fad1a6d2c52af63870daa148ab0f8476e7a09309b529450b7e75b95988a66f037574ea5b1f3ec3d2d8570a6c46320a30286196e363028923b8af1128847db9b42c618dac72698044144d5c205d14331e91e70f55da87a45ad049d7beacfaf079b148a9da5981e1b40c36837b9e344affb519f961c45a8270d6bb125f42bc5c5089d9c7324de600184336210f57603cc229489a4e27b7fc25cc0861962ff738f06c03d4422bf12855abf225b25b254873079185bb36d9c3ba85a46a5f605706979ebd66da03c15f1b4c25b886faca00b16e04f87b773d0b8724bb4947c615344f9466f78cae8d049876c9f7143154abc47110b0deac571bbe83577f577046830031a08b465b86e1c341c82660818cd2f8173c5c558975868f0281470f39e737b6cf964008e040382b290795254380b4850db27dff98838d9921eaa8146022937e36af6b030b8919bfea844d9d602ccb3547d5c07f612c12c3c179ffc30fe52c9273b5c0dd27934b5a41737817be0739425736bb0cdd267beacd0bd77085cd2794947051099c3848fe0aa2bcaa18f6a18afb626fdf1b977f376ea74a9cbd638932600efd84fc053650474c801b1a8ed941cc5444922915173ec1971698172f8a61730358c751d2d776d93c866c47802e2ac19c7c092aceb53996c20375b47413a66c06541b4343c548b4dc5341ea92b2266d9c0f1665719f62a72650414940bf3a20a260a5953d578d5aa48a2b670aff7512bf6937e49052c3ab8ba07016d06a9d643081dd52009b358ac13c3136cc65b0127e675bb55b8598940c054c8b797d37312a1ae48120934a559ba31042e160ddd13c744d7ac5dd614d198a33253b829016fae7ca51d397330ba1aac557a8fb56477224324924276aa52b7000f77db547a604f6d7189ef83071293465012b6133a6e1209af3009a867a46bf2868f8ab8a932784b76084998e37eaa4496c661a42e9802f5e1ca947c75bc4a572562733409757855031c9627152c02cd25a9b9725adae909175b27c53c6233e4480cd3a06954afed889ae97a091df86842483edfcb5df9a365929b6da98917ca7b025490b416a7abfda408f07429244a9202a23d23ea8ae96bc8ddd747d1eb9b79a3cf3610bc4eb56f9de38c3fb77db2740504e85107f46896202684db8103b1c488e9b731f0a2bcc40b563226d05946c9fcc1a4e287628bc4985189e05a5174709f00c43eda4897429773140b30bcc090ada25c91b8858f07068bc6c154030f048c1a7002ab58e157ee5b0e682877372426e193cbbdd3c63dec0a725c90d29411986a249cb30ecd981a92519ece4074f18ab92967220ac1c963503a295c570d7084c2917ec9b6a4663a931d6a505d11757ab2935fa708e9b6ad5fc1187f3717c6a4a818d57cf5395626c8a3917012fba13315902391116ff5015051dc8d07ec0716356d20a184458b4089a37fa9a713aa35c8ad1635a7fb49e6bb44cdf4628a3b84b9869dd760262cc487f44a361b9c1106553338cc5dd71c45c37a3bde98036f45231dea2a83001d82203b27aa054cd1bfcd215f477a7e43d31d946971b0d3223868922699b0d810b6fbcc834104bc0ba2cc7a50bc198616468c212c9b9dab2550282a9b88f8a1b6d006ba801544b62564dc05cad68d7f6b143222a5bb28bc9cb57788d417fdb73bd0778fe0529a35190b0912623df81a7387cef7d201aa007a199735bc3aaef9706c6dfa1b0256b872320459951111b90caf3202ceb8c10a480addf08dae881eecd0cec08a2adc61c20e8c15b60824653492e603bc3c203fc35ca536fb7c64084112c878741b83870620eda2997f38aff953217bec592eea7947e8be23fb627251c13fdc9bb0b705491151b8197cb07ec66dd1d49dab7f9d23aa8ffa435f2cc7a7a3a1cddab6e37ab7be45fbbc8aeb3fdfcc0b171aa975028f96cd47fdba421ac08e29a0044cedc29fce35eb85109da0c5da5f195b80fbb99c2e8b06926074f3f604b3f6195b5a5b9737876bba72" +}, +{ + "dz" : "ccb073c4b90be0ad746e26fb093b60c70110bd1dcbcddb566a8cffb7b3caf80e71600a8982c350df524cde514431ded7aec23576530894bcbf0ec0bfef0bb64f", + "pk" : "e80434a94334b45589b1866bcc69bad27ba323a563f47bc34073496a468dee6013330bc9a219452caa35c1a522c45c498fd4ac5564627d564d3881c731a9856ff7619622aba6f928beb9b9373b1104e2cd2e6246bdd88268c1b512867ae4ccca21140f0c046b5e5817fd64a2f93383c3a5add2f62784e2c8e80c150a1c8e1a8a47232787ad529333a07e0c512332799d9896a6071bb4e4fab647440f82cc85630c629c2c2068037948b575a1693f81d2a045a9c5a5c2306e83b911ea1e86db5763f13ca6b02ca8905b50faadf5440bec7b49913b371f0c5786fc585dea2813fa9ced349d9fa32cb5030b5efc274522ca4c6985b9dbbb245465a8849c4c78688392b0ab5bca98b04c7bf988ea84292c8505fc7acf90199eab7c31c13252680c71c9c333e91a0adbc1bd00d023c8d7a7c9068c3fa9b3cec75234663a2b73572ecc71e53a8eb5889860a336f77bbcc1c854d0c3c61c65216373bf2603a0ee72af8f747bfbd7401bcb9d599b6cdb02c210010d0425917b72891c33c97e9b39a677010d22a784003e1b917dfa3273246acbb45a79c7848143f0b583781626ba02a94922490c7b3695a787d9ae22e5470d32cb68790d75b81c55d084a43c4399aa587e07829510220469ab5e6381517bc9059353b68160ebcb0edf969e8c317442c4058423c3356b34035b9761744fefc76145300908da3c13f95eb3065f2cbb911437cd24f815197c0dd3f9c87e3b54432c50de1c7549228c5f9c32ee8c19fc4cbb04514025645e0fd1468dfa274e59a50d62c560eb051eac35bdd148ef75b0b05357619490cbf08b0b13767557c5fdb310da985dfdb9c35580217067a8c68491ba64307a618d272363ea346629ea6885acc17733a801166fd404cca58b591b68b2c73a9e890a13bb173584d2b6db351133e75d258995ce46a8f798a44ddb8526633949e5442435c7b3c083875760c00614665c4a2ab92c378863a3755ddf681905ec2044c331c4b976f6ea5335bac739c2be9cf141a9f3ab3f669c5fc49d74f79ba066a7d03b0c2036247c86305bd45194a00e33a1179ccb8d05b374deb491bf5c1d6adc4506803a8c65b18dd6621a5820ca93c339dac2bbc098c22b4e1fca3cabe58ceab66da6a35191a29ad82c74abf1c823200bb197015e074d14f224fdf30a51bccc015a152b8443892b7450734b34e77356231c6a8016aac430db0a8954c7a416b43d49120fdc4017cb61c3bfe70fbf24773412b6a91375f381658d57677fe571c3bbc800cc80ac597a8f2c5cd1f19567ab1f4c797a68e6133507aa90d1ae096148d313b48096ab96298c33c3828d645a28098c777cc10ce068c035a71f7a2a36306fbbc311d3d14214c042871388dc899ca2116baac1aa5cb261af35a0e255b228498295f6b4ae171dfe21b5f66671af532253dc724a893b933829a0c275c20407898911472a02eb484d4ad5b8d274c00bd9377f3c497e6845161868434c968bd847ee90c2ecf600867cc790b005061c8d5c49339dd3ae23920e65da2a19d649aad1b722552e07f51cca7b87efa315b6191b31279509d78b0e974860ba9f635283412038efe3ccb2a0c643c68756149a03b50f6891b9fdaa099ed50d7a012c0175b9518c15649396d94ca1266979893e82811af8c142323fc3d38b8b5e554f", + "sk" : "06e67b30992ac43a09b6572f7b4764ea9bba93b05cc3577a8f762279c1c9991044b7c57ffec6c73a8cab976031b32c33430807913524a3e5ce0e1627dc11495aa31a0712302cd26e7d980bdda08542d30fef9a1cdef2c302c61b39d119c09909b338529b89c4b52cbc5111c20a880b493b01902ac47feaa041a72426b4625da3a79704a239138eca642f24d382dde6a0c549676bccbc63010ea8f17dbca231e69ab7acc5a9d9081090cb653871532fe48879842e7dc41bfb8820f22367189b31d1f201b7c50e25466fe4891115c2c8337a637e964c5d88c5e752c9a247047bfb2b0df93a36d06d80c3230cb628ecb5997d999b1a70a5fdd8b9588678d1e892c330bad5aabe0927029f173b6beb512d59369739ac8f0b5fb1663a874426eb31cf1818199b984c6c01b70cb56c2317078c393e5a35cc749c7d06a29c08a3637854a3cad724e8c93199dccc115b5a02902f29b482c6f1560ea778abc9c0bfcab0f4468761e17c8d265b93ba7927a2868f78bcbe6374723646a82821a4925c548679ed3bc29fd6022ea952e7b8acc220aea82c66c75c1a9d4a2a7f793ebb969b877a85a3a1a886cb57c58b3d0e091c5d136dfde61f1685626d73bfab6b672e95628be27071897d880007ef364982ea4547b195bfd79323874000d8179876a61b0589fe769e7193378c61149627acec65616d701f08f654f486628cba1574e92ef7f96c44a0ad9057b2b175012dba705a4735db91cf96155146dc53ee32a8e7620d1f6c0d969007ba84b36fd2bbad660882467b6675b77d838b95aa32c6fb04f109b1c8eaa181c4afe3cc7e2e301c8c89cab8e4587fb472dce46f3980aa62a61526b79108d611c9c103eb05746d58ac6cfa58c4a474d2a54f96e8617453847cbb296038498121b867f9aac8776fe153bf3f8895a5d02df74c934e2309414597c176857955bc7bb3c5989157ea63bddba696cbe57fbff0c71ff637a54117939708db26732ba13b33783416d0cd3390a437e8cbf4c978989000ada7c5405254b9e9094c5b9c3d211f03e205e6469c478ca212136c9ee79a427b00370b2138b0c11cb435f93c4ced3326c3b1bf9a2991f9c4c285ab09453a2cae4797aee106fd95949f2007b8a6177a18bcfa717106688c7c536d955b3db2f730c832b19cf84b31462c6c4623527b7e454085aedb59aec591b69349b00668e170b2667358daaba2d959250cb0486f0448768689b2c5450e8ba2fa3a77e9e9080dda636ffa09081576fd2b0320e69cbf017d468309076884aef925f6a9938e76b52b453eb8c563411977551057ff750f1c206236679c09f98b34026b42a2c778407014396f9cab89940a3d66d76ee512b7f07375ecc039c4258a1c7a8fe521868a99c18cb78b17e78334e598a5260ca42163ba705295f28c36cb19a242216a56079826483698bafef6755ecba3b7091ee2c3c6afc9b9d2f42317a51e2a61bdc229a4b7051afc6472062a440cc7b684e200aea93232ba945d21007bcb58bca99b269c5cb46b3915197278c27bece1b9a4e6ba09ba38573987f30490f57c09e750c9fd87be933a91b9c59717e3b5c6fb660eac8556488d942b4bb00711b2c93e4232c1c7a08669776a3f607ce80434a94334b45589b1866bcc69bad27ba323a563f47bc34073496a468dee6013330bc9a219452caa35c1a522c45c498fd4ac5564627d564d3881c731a9856ff7619622aba6f928beb9b9373b1104e2cd2e6246bdd88268c1b512867ae4ccca21140f0c046b5e5817fd64a2f93383c3a5add2f62784e2c8e80c150a1c8e1a8a47232787ad529333a07e0c512332799d9896a6071bb4e4fab647440f82cc85630c629c2c2068037948b575a1693f81d2a045a9c5a5c2306e83b911ea1e86db5763f13ca6b02ca8905b50faadf5440bec7b49913b371f0c5786fc585dea2813fa9ced349d9fa32cb5030b5efc274522ca4c6985b9dbbb245465a8849c4c78688392b0ab5bca98b04c7bf988ea84292c8505fc7acf90199eab7c31c13252680c71c9c333e91a0adbc1bd00d023c8d7a7c9068c3fa9b3cec75234663a2b73572ecc71e53a8eb5889860a336f77bbcc1c854d0c3c61c65216373bf2603a0ee72af8f747bfbd7401bcb9d599b6cdb02c210010d0425917b72891c33c97e9b39a677010d22a784003e1b917dfa3273246acbb45a79c7848143f0b583781626ba02a94922490c7b3695a787d9ae22e5470d32cb68790d75b81c55d084a43c4399aa587e07829510220469ab5e6381517bc9059353b68160ebcb0edf969e8c317442c4058423c3356b34035b9761744fefc76145300908da3c13f95eb3065f2cbb911437cd24f815197c0dd3f9c87e3b54432c50de1c7549228c5f9c32ee8c19fc4cbb04514025645e0fd1468dfa274e59a50d62c560eb051eac35bdd148ef75b0b05357619490cbf08b0b13767557c5fdb310da985dfdb9c35580217067a8c68491ba64307a618d272363ea346629ea6885acc17733a801166fd404cca58b591b68b2c73a9e890a13bb173584d2b6db351133e75d258995ce46a8f798a44ddb8526633949e5442435c7b3c083875760c00614665c4a2ab92c378863a3755ddf681905ec2044c331c4b976f6ea5335bac739c2be9cf141a9f3ab3f669c5fc49d74f79ba066a7d03b0c2036247c86305bd45194a00e33a1179ccb8d05b374deb491bf5c1d6adc4506803a8c65b18dd6621a5820ca93c339dac2bbc098c22b4e1fca3cabe58ceab66da6a35191a29ad82c74abf1c823200bb197015e074d14f224fdf30a51bccc015a152b8443892b7450734b34e77356231c6a8016aac430db0a8954c7a416b43d49120fdc4017cb61c3bfe70fbf24773412b6a91375f381658d57677fe571c3bbc800cc80ac597a8f2c5cd1f19567ab1f4c797a68e6133507aa90d1ae096148d313b48096ab96298c33c3828d645a28098c777cc10ce068c035a71f7a2a36306fbbc311d3d14214c042871388dc899ca2116baac1aa5cb261af35a0e255b228498295f6b4ae171dfe21b5f66671af532253dc724a893b933829a0c275c20407898911472a02eb484d4ad5b8d274c00bd9377f3c497e6845161868434c968bd847ee90c2ecf600867cc790b005061c8d5c49339dd3ae23920e65da2a19d649aad1b722552e07f51cca7b87efa315b6191b31279509d78b0e974860ba9f635283412038efe3ccb2a0c643c68756149a03b50f6891b9fdaa099ed50d7a012c0175b9518c15649396d94ca1266979893e82811af8c142323fc3d38b8b5e554fd046d93317dc6d0ff28990721c3f94a93024ce01b01c0ca55d634c191c4280fa71600a8982c350df524cde514431ded7aec23576530894bcbf0ec0bfef0bb64f" +}, +{ + "dz" : "2e889f44e28901e9ac7ca6b2fffcb124c8979401b17064d7e1d51a7e3c3adbfa0e145e44aae52cfc609e6f47fd7a6f6af877190ff52256d0ac5b05b89c3f449f", + "pk" : "70d99d171745edca3a65045bf6e0625aa4955fd125d332ad33f9a3ceb2313ad50c97614d038547f22a135a33c06c61545b9a26b46c41d1830b83d0257fcba82b36510199224855bd1a837a369a2c823391b1f84e54959a06938513681d97f34eeaa7bc42eb13574b29fb785c457786ac69ca22f644a1d53278d4c2e0f325a1209a0ca40fc32b92e906650b484e7d92cee99a078f5090d2fb60f84b47dd44224228443d36219a081f9956cd7983ab223bcc094a0c65414cc2aba8564977b147088ef41aba589653e535847450c762517dfa462037c2c1457ef3d1909d0b79d66ac6ed9803ca88a7295c4a3ae53cc77c235cd8922b36ba8b837f375755326a960beab71aa1b33a8b64d6076f0889424b1875ed6316ed420db7e02d731b2b3065c7e80115fc1406c125b651c2b4ced28ae9c67cc505bae5b747e5722f4729602bd1aaf25ba333c29ca011ce36f55494204b0f70895938c9c4658044740521097d696c8efc045709369f88c1cd46bb763b957db8f48abf1a07f431845c94beb7a3a68d42af6c2c3095f829de51b37c134f977461aa2818073682def71a65291904f0c214b727fcc7b522c2a33f7a2e07a65926fa5661172103b390fde2814b21273b318d029a112fd389d0324506d280be8c49bb923412f4c430ca82f58ca8b7122907b986fe912c323b1758901007067153db7b16168f791610df534aec8050a58296f58b7549f0665e13918c784da2d00da79559ee006566050482b2a13baa4884aa83351753cd7a48e6385292a990ca559c8d630a7dd4947e428198b06242179c369741fc067dec411765c58364d32ba655350530a4aad934a1d14b76f55a19ab7f2dc60720124a2b69ca703030b2320dcbd459cadb6662fa0aeae170f880797e2bb0a2f24e8dd1442549ba4510153640ba7f093acaf41f67f55e4269260ce2aa28261d4dd4acbc2a4a134751261991e7b36183387893c5900e8a611894c76c26217a390f86e5068a947457db75e7214b8b05a3c87251cc2101d7e6115c908d2721aab224b038c1b9c348a3c04c081496928da726c0d140d363a427b93427f16841c97447698cd0f360529725ec86113594045e143659cc1a0667832f40aa7e059d0b1389048a75429886095b3ec5a646ea12a09424338c6ab729a27e595ac7784169c6e7c7bc208b07a44cee5940f85896a7285845a2a262da092d1b0295821975754898bab492530e44a410f35563a1e45775613192dc45df526cc19b6eed8186e6f706e233542a4450fa6c89bf993af5699dc0e46965417433d5b1882340a1294d4b229d42061bade4683f8557dab0603fab1bcd956b29ba8a2af60093654f09e70f07eb3398f7bed1354a7982416ac40860538c36722ce1b37322c4a888c2359080704490b613c9a5f7318566a37139563c40d58c055b827145bd659c8fc6b7908a071fcdf0b17e4351cf3bcd9e8cb9361985c70c49bad71f860b36ae120f62c06f3b34aa4942985d149db7b13e1412cc1ff59dae21cf50017883a0aac754ae6cacbe87a46919c05752877840556af8d56fcd848f982b415d333fd8640794918ead0121d12309bf622d9c97551f294c3822644834b38fa844a035cb5458aa7240f750287f95feb1696d88988eb0648c3cc0fa9d4277fd9af8c579271f4c77", + "sk" : "101ab759f6afcd596d4445b4e3a1907b3955f81641cbd1aaef79b22ec38af5a081a570b67dabb410aa3c78925c82384b5931908d147926230522da5cfed372e9eb2b94900625e74caf1098144572a3d9ba32d875c9184989c823a3f23da4144938b88836e9c708e52967b8413f206758f578b340b2936b798775b7aaa09efd567834e52afbb17bff8b11fa0435e6f55ac73219e79254e166cbd8dcb95f0874f26925dfcb93f9461b2a48925026651b0cae117483d65b3f57b90639a39b16b1535647079f12a0d897c51cf60291a165fb884680071656c407c9e09b31977042a2ab6783a9b448ae7d924243dbadc5b00c00303c9a12308bbaa51f024884126e01346665f67344d2698adc13159a316e4175dc532c75d40d6ce54916da9ae3f763efc74dc9a904d7d8941fa34e493a74e0f9032e44a84481916530573d4b372fc6790b3c357a6b6b075b87e6b1a82928037da41f265c7a493abae425c11b6514a96c6e3949520ea4b9a7a18c76c53016a0ce644237cad882d79c60739a4d2651a4e900463a224f1769a40d04cd1c2796ce2860844ac6fbc87b00379446a637f868b73be31c57f41830d3628babb45bd5b9712b33bf5637e897c6bae6cfc6717dd87ac5da5620ca04cae154bf58f61024873f4ca93738a444801cb5b61acbc6098b36747bf6926e78b08939116ac1604e5f61570dca65832ba04c8c64da99838be418b61805b1382cc899559a62b73230cf126a701a56aea6795e6ee95c2169ce82ca352a5c411d89881a3a992704143a06d01ba15f9f59083bb70c69fa5b7eb72036da024a3707bee499fa4057a52c36272579209215f21890216c0f0dc83b5dd38867604a6175c417962a8a8513dd5aac8e0a806bf24a855c89252c392f6acad0404f9445b0b781bd26e15f4cf4a7d815bdef3936001219955797c90191c7c794987c3d1d80b07c04b14ea5a6ad49bd4ec27720e68a8e855a042a8b223821dad9b53c00912ec92249ea15af46091714759d04b4734a5c60d979735741c9acaa7b62b413c439a3bc7a6510c9c5900af2177bc5104c0c079c67a03a12f923ead47e1ba85753f822c7334e25a02a1b155e0b4c22af82b353db202627b2e4949a3c874c7207c0d96480c33c9070723b9ca1a2111321fe22170544c255d3246cfaa6960264ac042168922153970a6df7a465690a7348c1ec77b997bba243ec7508c88b730407bac2a9b6040b83ba7e034a7388e78b010ba662d15eade2495ae63568a12349c57baaeba16a32c363245f599475f7e141d1d2462076abe3071fa2566c85197bc79b24876461f9a0082f4701eeb619cb5c4b1c169715729fe2e27d85890def829473d33f47bc7216030063466f2a8c9fd5e14e87374001b256a6b98d3c53094811108c1cb6101a6bb18a8bcc7bbb7b4278d030c7f04368d655c848d1a22d8a79fa787613b653cd0106723c9e8f81439083a7f022b9c98b6dc7d39c2c7b5b61f4c8dc06728741a641a9684808b20ff84a9b2a569784705ea2758c0176517ab47c22b408ab16ec20b849f1cbadd7ca82332107d41f7e6a6135365f86098fd9a66847e03641bac2f1c933baf967e94265d40847976b68c49730d245b5723b9f70d99d171745edca3a65045bf6e0625aa4955fd125d332ad33f9a3ceb2313ad50c97614d038547f22a135a33c06c61545b9a26b46c41d1830b83d0257fcba82b36510199224855bd1a837a369a2c823391b1f84e54959a06938513681d97f34eeaa7bc42eb13574b29fb785c457786ac69ca22f644a1d53278d4c2e0f325a1209a0ca40fc32b92e906650b484e7d92cee99a078f5090d2fb60f84b47dd44224228443d36219a081f9956cd7983ab223bcc094a0c65414cc2aba8564977b147088ef41aba589653e535847450c762517dfa462037c2c1457ef3d1909d0b79d66ac6ed9803ca88a7295c4a3ae53cc77c235cd8922b36ba8b837f375755326a960beab71aa1b33a8b64d6076f0889424b1875ed6316ed420db7e02d731b2b3065c7e80115fc1406c125b651c2b4ced28ae9c67cc505bae5b747e5722f4729602bd1aaf25ba333c29ca011ce36f55494204b0f70895938c9c4658044740521097d696c8efc045709369f88c1cd46bb763b957db8f48abf1a07f431845c94beb7a3a68d42af6c2c3095f829de51b37c134f977461aa2818073682def71a65291904f0c214b727fcc7b522c2a33f7a2e07a65926fa5661172103b390fde2814b21273b318d029a112fd389d0324506d280be8c49bb923412f4c430ca82f58ca8b7122907b986fe912c323b1758901007067153db7b16168f791610df534aec8050a58296f58b7549f0665e13918c784da2d00da79559ee006566050482b2a13baa4884aa83351753cd7a48e6385292a990ca559c8d630a7dd4947e428198b06242179c369741fc067dec411765c58364d32ba655350530a4aad934a1d14b76f55a19ab7f2dc60720124a2b69ca703030b2320dcbd459cadb6662fa0aeae170f880797e2bb0a2f24e8dd1442549ba4510153640ba7f093acaf41f67f55e4269260ce2aa28261d4dd4acbc2a4a134751261991e7b36183387893c5900e8a611894c76c26217a390f86e5068a947457db75e7214b8b05a3c87251cc2101d7e6115c908d2721aab224b038c1b9c348a3c04c081496928da726c0d140d363a427b93427f16841c97447698cd0f360529725ec86113594045e143659cc1a0667832f40aa7e059d0b1389048a75429886095b3ec5a646ea12a09424338c6ab729a27e595ac7784169c6e7c7bc208b07a44cee5940f85896a7285845a2a262da092d1b0295821975754898bab492530e44a410f35563a1e45775613192dc45df526cc19b6eed8186e6f706e233542a4450fa6c89bf993af5699dc0e46965417433d5b1882340a1294d4b229d42061bade4683f8557dab0603fab1bcd956b29ba8a2af60093654f09e70f07eb3398f7bed1354a7982416ac40860538c36722ce1b37322c4a888c2359080704490b613c9a5f7318566a37139563c40d58c055b827145bd659c8fc6b7908a071fcdf0b17e4351cf3bcd9e8cb9361985c70c49bad71f860b36ae120f62c06f3b34aa4942985d149db7b13e1412cc1ff59dae21cf50017883a0aac754ae6cacbe87a46919c05752877840556af8d56fcd848f982b415d333fd8640794918ead0121d12309bf622d9c97551f294c3822644834b38fa844a035cb5458aa7240f750287f95feb1696d88988eb0648c3cc0fa9d4277fd9af8c579271f4c7721b12640bf755e94ba06204982458a9be11e1da542ece4f3d284886800fc8e8e0e145e44aae52cfc609e6f47fd7a6f6af877190ff52256d0ac5b05b89c3f449f" +}, +{ + "dz" : "174aaa36410566dc15a5e62874218d7abdde0b2c0f30d877bb80b1abd5f5a0a450a7a2354f7e5cefa6f4a4e9a1c411eb9364506e9e1204a8acb3cb77fbd2c4ed", + "pk" : "e770043be600f7a60b3b370bfa6a30c846c475127924071e3120879e2a158433a2a3a7791c204912da8576bc2722eb9e38139c198915986b58a9671fb054a81443553ad74563f587b226a9117c133ddc10dc0655a7d52d493b7b3db9584c49b4d1f41c06665a3d07383057ad70b69f85b6cb2682238120b830681794e042d910467a24091d81322a08aa1d83b0861113756615a119503af837eba16768046b7e64ab5940aad4da6e3165ad036959c39bc69070bd7f074776089aff76b33dcbb17bcbbe65b526c795b65943821d5b52ac1044cca52e3403a02604a1b4d9cc84e4b72b2c136de898a12451d8c74c280a67cabba42dfcbea68455c5f45bd3ec03bbcb3f72604df70737a01683369c8a57091742c60f089a673da350db8ba39c2a1108aa6a4e2a6f24b13d95f004801b240b50067dd34b60991db2a42de3dcb2c24034d0cacd24c890cac7a134bb183c92b5d66c7000a5a3f80898754827c9a7cc01a1550a9cb4f4f18d5959be0ef84c35b54468c55a15d274f996cb74449d1e5b2f88bcb6d00912a9305879bb156bbca9843610af2c5193363177d2b5867240d207819498a98209c109273dd44a4f2a06549335a63afb2660d212592c417b426268485a7e8693f865c0a7960e073153d5e578a74b34e9c3a57eb20fc825ba59e56359a627f358a4d7127be7d571c991078d9630e1262402a731b14b9f0ee4a3fa4494bde9aaf2d4603af1178b8b49a649056fe314caa92df6d816fba591fc4961cf0509d0dbb02ea7321ef75aeb20813e33a9717478be58b49fca3130ea2b54e62fd3243f4e240e54c08d26c5020a9512d2536c486772e725267bba974f3a451bd50f29c55c7189012473ae1e5a7ef35c0b479679f1a71fafb41ca6d16b39f100201bcf2515075a1c9f881a7ae4f4733b149e7c29973588c161616e9918062236332cc67f26a65fc72c78564312c429cd1f3854eb98c0ce91be6d9a24aed0ac65bc5d805490e1d8c86963c8adeb8755e0bcdfa473ee23037673773c46911ce0baf8c81bcd8047a9d19175f6bc31c2997c62c502b934d7651fc51562625538e24b235c4c38cdb82fcea4abaa963b3d67b3679b51a21cbd77228338a95b4d641b5eb26644a58a59abb0a8c0afc8894792b3c6edec9ccf7c29c620b9ca262c634621d225228f1503609b548f0418648cab5b9609e7486d57e5824c538037d32319427a3b077703a7368270c9b752217eb04b912a3843f4afa829b38174bbdd1cadc8c74697544f6229068344441ee2863150716339716ea6a8245a3c3c142b986b7462fa2417a413ab718ceb196f15f887a465c8f901c55db4718ea58c71926ea344c49635149014297275baecc90ad1c95c75281eb885264f11123ad8cd7cf1968e885220f0964f25510539be63263a4eb6169f7319f0086fecf996d2e852f139b500dc1fec8824430505a7702360d81823269ff4b2622b54b7f917bb44714660051c31d9b39494a64a86c15c516437c4a437f41c0fd5922dda52818336d93a8c750203fd859b06e127d8e33b52c34411e4199cb01cbd70b8ef0180b045119129aeb04398841bc8261444c963c3fc11c8dd4c78dc5a8cd902687e36aca5f2667abccdf2093e5ecb1a4f09769a8251104731ee68587d0a470e2ee6ab99d3af13f31776", + "sk" : "b6a8be5c6c9e94c1b41a52cb1165b3e857604ea413dc11813442a518bbb3e1d84724109f9b1288f5f34d06c3aa30d913954c5c053486b60b254f3250e9aa656dd71553679f5f112d8e8c7f11e6b19072ab3784284dcb2988cc10d673a423a0c202f03cdcc74a43422a2fd3b934b67bceb074a349b8524786f6c126d72a384c0a84fcb8304af2c3d65994e5095274d2715d057b920ab40219ab156cbaf7c314fad57122505ed15a61dbe66cd83bbacdc9b3d3a1afb0d607d6e01a3e227d3109a1ea14696d84beb84c0cd02b2964762a36f153a8b82733872b0ba6103437a191a59439fc3e2ec899ba841de42bacae534bb3100854283175548ab055cedb836b49fa5841ca698571c4794c7648c65d5fba44b3c57d925aae29cca857301f61b6940bbc28b634bbefcb51037c301674297170469cd7ccf39a828d2110f8f3b9cec915c6423163d90b2dbbc644864a6f8761e83371e2c3724617b7ccc893561337bfe7832cc4a0636ab871f07fe9b93b7169029bebb7afbb02ab249ac3597e0ad052b233a454f6628c52c6727a4267447bf11064b61a1ba6a4b7eda764de23b0bec1b954d3c5882432e1ba6ef1b94eb1464086ec2a5ae0167eb8b5ea2b40c01953f223544e49bb5c441174537cf8953c74d318a5b4b6190881cdba5b1305b6a3e2528c4c8825107fe323ce9e979f5d33aa20712b6ccb5cdb449989922b8e571a71cc458537bbd8e9a696d644c713bd25607d4c26a39bbcc11d58a4154c1161bb1e771986a4d923dc9936806498cee91c3ffa819baa73d1103b868772340a1b1ab664ceaa82d60b328e2963259c039e12798adb66e62b827fabbd32d7b29e615ad76cb5690550af975c2edc1aa8849566cc8bd2639f009453d1fba689ba14d5c68d55ec1d90074de4b47a84944714a9c11d55b271727c64e566762459f7e381763981776665c3d908110a74b7977678e011c36058de9606ea225084331c0f2479de36c333c26122ba9fce2b360628b5b8919838829c2ce55b12a6b80a3a5ef01998549a1a26223a96916ddb8a0258b5ac936b74d496b8bd249412176b697182054b744301c2a3b10b2fcbcc11ccc89ff5b40f079817c186893bb044559ab646626f683191a03fd6f41506ccc6f49627c09a821ca427e8122ff91234d5d92318863aebe86466f108e9a51a37822a990bbba5e01292543e756b64a2191fe855844185a673c584a2c0897e1b73ead8ce548833c03447dc32bfe6f0cf615469ca61c376a3365fa6cb79c6129636c48ad68dfe2c1553f01dde270d1830096a03072095bfa24282f1d100c2673aca13c1acca01f158aa3a593d0b78458b75c8f34ba4f9391afe255dcc715eced306545a6a683191ee731cab1177532882d301a482677fb4c38d6b69201f0920162641f7f701290969d5c63eaf13a133563e95ac5e88a42f4d128b9c69b5c3f16b76a6731fccbe6f58547799bac3c9a6f3cc9a13ab0cd26a50bae9774acbb86ce8944fa01b16840a8b220d7886197f671e64a41886c80af2f66e899155b125181118697db62a4a4a0da162240e0218739cb439406219c679f9857dbfdc73d96a0f7a3181eeb3b38d8b31b7da8e65f30995f778ec5b4026a28ee770043be600f7a60b3b370bfa6a30c846c475127924071e3120879e2a158433a2a3a7791c204912da8576bc2722eb9e38139c198915986b58a9671fb054a81443553ad74563f587b226a9117c133ddc10dc0655a7d52d493b7b3db9584c49b4d1f41c06665a3d07383057ad70b69f85b6cb2682238120b830681794e042d910467a24091d81322a08aa1d83b0861113756615a119503af837eba16768046b7e64ab5940aad4da6e3165ad036959c39bc69070bd7f074776089aff76b33dcbb17bcbbe65b526c795b65943821d5b52ac1044cca52e3403a02604a1b4d9cc84e4b72b2c136de898a12451d8c74c280a67cabba42dfcbea68455c5f45bd3ec03bbcb3f72604df70737a01683369c8a57091742c60f089a673da350db8ba39c2a1108aa6a4e2a6f24b13d95f004801b240b50067dd34b60991db2a42de3dcb2c24034d0cacd24c890cac7a134bb183c92b5d66c7000a5a3f80898754827c9a7cc01a1550a9cb4f4f18d5959be0ef84c35b54468c55a15d274f996cb74449d1e5b2f88bcb6d00912a9305879bb156bbca9843610af2c5193363177d2b5867240d207819498a98209c109273dd44a4f2a06549335a63afb2660d212592c417b426268485a7e8693f865c0a7960e073153d5e578a74b34e9c3a57eb20fc825ba59e56359a627f358a4d7127be7d571c991078d9630e1262402a731b14b9f0ee4a3fa4494bde9aaf2d4603af1178b8b49a649056fe314caa92df6d816fba591fc4961cf0509d0dbb02ea7321ef75aeb20813e33a9717478be58b49fca3130ea2b54e62fd3243f4e240e54c08d26c5020a9512d2536c486772e725267bba974f3a451bd50f29c55c7189012473ae1e5a7ef35c0b479679f1a71fafb41ca6d16b39f100201bcf2515075a1c9f881a7ae4f4733b149e7c29973588c161616e9918062236332cc67f26a65fc72c78564312c429cd1f3854eb98c0ce91be6d9a24aed0ac65bc5d805490e1d8c86963c8adeb8755e0bcdfa473ee23037673773c46911ce0baf8c81bcd8047a9d19175f6bc31c2997c62c502b934d7651fc51562625538e24b235c4c38cdb82fcea4abaa963b3d67b3679b51a21cbd77228338a95b4d641b5eb26644a58a59abb0a8c0afc8894792b3c6edec9ccf7c29c620b9ca262c634621d225228f1503609b548f0418648cab5b9609e7486d57e5824c538037d32319427a3b077703a7368270c9b752217eb04b912a3843f4afa829b38174bbdd1cadc8c74697544f6229068344441ee2863150716339716ea6a8245a3c3c142b986b7462fa2417a413ab718ceb196f15f887a465c8f901c55db4718ea58c71926ea344c49635149014297275baecc90ad1c95c75281eb885264f11123ad8cd7cf1968e885220f0964f25510539be63263a4eb6169f7319f0086fecf996d2e852f139b500dc1fec8824430505a7702360d81823269ff4b2622b54b7f917bb44714660051c31d9b39494a64a86c15c516437c4a437f41c0fd5922dda52818336d93a8c750203fd859b06e127d8e33b52c34411e4199cb01cbd70b8ef0180b045119129aeb04398841bc8261444c963c3fc11c8dd4c78dc5a8cd902687e36aca5f2667abccdf2093e5ecb1a4f09769a8251104731ee68587d0a470e2ee6ab99d3af13f3177695d9e5b9151d87fed52e287992acb897a07b10ada1dd83409a5ccddabf9d7cfa50a7a2354f7e5cefa6f4a4e9a1c411eb9364506e9e1204a8acb3cb77fbd2c4ed" +}, +{ + "dz" : "351fe4313e2da7fac83d509f3103caf7b4c64a4d458fefdf636785ac361a1390f072d9b5a99f9c7a0a011e4dc10f6b600d611f40bba75071e7bee61d23fd5eda", + "pk" : "13568b12232135a5896094834cf450d789ba498787368b4e15f1b087a704e8e327d631290177add97c0a0d84820ce367dc515fc362aaa98aa7911a867a3789f69a5b68bbbabf3aabd037b5160a3f3d8277ec47898ff3ba5ddbbca6980b5ad47c59236eb33b2a9c84b212e93d9e70aae78a4f9f6bae592ac2b5f96eee627971d27389905b215869d9f4b706c379aa802b5a99abf754ca9316872f033ecbd5b34f72c610c14037540a2c86ac7eab0c3af84729c48610615c9956751759660b3c7bab57146f7b1088501fe14b2f59141b1bc6302d88a35fe27e0cfa18c1a22a9eb517ca6060f25408d4299a7f46c458b3bc38c4794bda8f9079043854179db0071af69c9f074a83438874c882cd18b69b0b2009497b6fe94a9264470be8256b49b6c353374ad49c04b1276fd484338796e4389a523598f3776291512e25fbb5fe98591320c1bb47c6ef3b4bd1d62b6997b5561bae038854ceeb41b2925c1f1a81a702b57b2815f62aa9eb2625ff3512cf9595073ca623da43f32c21d63297a491b28dd8b1361bbc91b40b34a65f1a2b7db86b0b3bd21b26ca5795b795e355b45d1623b3a9731218174b50966d6937ed057fb10b631a51b7d42072a0845be8553e19901fb0eba35f5142c75857f642918bf24544355c4041102d8b197b429fe548433eac36c42077ed787f8e631edb856d4398a26d536911ebbd9f9c22769c756f858d180b6b51797fe9ec0833c908d9ab2730d937b76a0febb68fd84372c96c3c05197093e26d01219c15f898b2c7ac75d11485a2a413a065be744e0908b6340155a244838ddb14b74c578fca2d7e6c4e15e68421a568e7e39a4a04231926768ac4a061d67550a8512e780198738bf3e2420cf75680d1cac07798c01ca06102cb2ae5c9b99b62a7349fc8a2c558989b68e3789c2c7074b476d18212846c8a8d562166829a36587eafc95a362874e812aa951a6995f5a94d370afc9b64777a7e58cb54b62a95476ccd323073d6e466e6ab909b4b4cd840aff393c9391902f4c05bea833d254207cfe938669cbee478c57ff4424004003d151fe5e90413924bf1378419e08dbc46911e2ab2b7f45dcde5c549f679691632c3d9bae26b9fdb85c7bc3301a3900386873345974bdc007f869155df79cfc6f06c39d8bc9a99675382358ba25836a15cc222ae78e4a85a19c5da9912e48128fb37a7f386c0fc86afcd2869e292ca9b521e6ef9b12908ca5d800ae1a7a3a7070766e2802a947c7edb3452a377d9c1bcdb152d37db41ce7c74c36b32c59131b1b85f9b68a3b66773ee4a2b81f12509c33cdaab4caa563e9bfb3cd9c4c72354c1e88423f94169e18bab1a9798cb99031ff852e79229630c8f35459bf40c425af7cb0843498a3cc7fda53d932a07382018de07808aac2b4d60a1e242beffb89489ba69a6a26446180103c11f7b22361f651777b997b76ca8f5a25b97291058620ee5479e92aabb218444aee52e5c8294d578c709158f655a8930fc197f765fb3790bd62a5fe11b57f273775da27fc1b5128663c623f5175513b753543bd71aa045e77e4bd42b7e7baa5ab2c4d3c41f4db84af265acecd4906fab897b5abf5af66b4c4a0b4e783b417c6fadd71d34ea294ccf8b8c8012edb8badb3437b191165cd639bcde9eb71378e71fb55129", + "sk" : "9d4548bbb50474e5909a3b1b9fe69c379117a840ace316a8fe3a0f68cc2488c4737f5469f025bdd6378875b173ea5b34119481b7a23388d20937eb5d85a566c8695106645ec3cb1bdc1400c1f3220669b2cc09ab752205ef2bc16961278eeb863d2c58df1c77fbc01d6f298b89049326314323a49b99c7064e8aa44f148616aabbaf76800101406ab7a34402a8da606aa9e2560deb8f00a14072e204febc3d2a48afb18608d03aa8c0a1ce1d591ee79676447a1657e19897f20b0b19a513daa2ca415ad65a2e77066606890c5de69e45367a668619e7e4a38ce656fc3702e5185142f65a6ba43d892b6f086ac0e6bbcbe0e04869eb48921936ead6c91ff3af5311b10f2622c1b137a5bb82b63247d6fb12200901e93acf5e3466ff8160d7677a0f9825d2ca85dababc27b24f3e52aa957b7371685e5fb56f1edb91d66c8ec23287846119eca062d9050cec162a8a6332cb4087d9270c7f022773c6664fd74b85eab209d15e6fa2145297232394138bc54cf4c6cd2841a65ef48cad8384a957b42885236821a3d152b631f01f1574b28990045da08eea352bdfa8bc79fb621c504dbed81b0577aeac881026322c0f295216019bb3a11569b74e91d019a6da89caca94879c801b331c115896054750fa6111207c0ab1d2ba8b328912bbccc2494a300356041c7ce28043880b56db58c78da121b41ab4d2127711c5088ed232b7b536bf00b542b15800accc5b3677802807f0b23878258d18071c1691ae63054d3aeb129798bad2f11b64238d7e83cec2717c023b5e7ee404555393541191afd8b7a79a88c36a2f711c3c2b79c64c405a84f2722643458f4c6cce4cb2556963926c42303c85d87861f4055673b7405c5b6760bb52909290168c50e7f599b798b2f6ea119f3a387d59025954c2571b095d6c761d2932d5a79761f25e52c8a64c765b2220a3ddc38039d7658b1cbdb770574f0464875b7e5c9585abf8b4b9ca9391c1a6ef647063046ddd857f7811c075250621228b80787879651f5843c175eb86883a73cdf97edc6c6b79cc917cb710744b44a9d455cec7a0c81919b600c755b8506003a86ed3276840afd59344091a8430d4705ddab1dd849b96d7238ea9bf63696f709532fd49b0833840e373336c8119a1e229e4881b23868ce260b3b3378feaac8730e69642cc068b4a6b16a0c83e4a484de007b6eb2464836242f7279a754a73e3a8cf378eea351fa7393a3baabcbe08b23ae9887b973b6c653b1bd06a5cf89326d223c365791888b7010795f0c056428425b0f647230c669128b9e0865152aab666561d43ba060decc51a4aa7a0e20502167b69f31d2e6b8b6c63135d91ae1b899afca84ca89bcfd49a725184a6be2289142248439aa568d9c18f492123301792a1ce41fc15c0739d88d05c5ae4508db9936717049df17384b261e8e1910a70cd56208689954a50a41711f9bb170abfed596fe077053603694ff7bba7f41789801df0e64119e962594716c585a30b13c44cf97d9bba5d577285827537688976933569cee793f24733656b97ad6475024cac8902760fba36ada22b9086187ac68dfd26ade8e66dc8773f4eb764d322732450675fa715cb02095b326bd0970713568b12232135a5896094834cf450d789ba498787368b4e15f1b087a704e8e327d631290177add97c0a0d84820ce367dc515fc362aaa98aa7911a867a3789f69a5b68bbbabf3aabd037b5160a3f3d8277ec47898ff3ba5ddbbca6980b5ad47c59236eb33b2a9c84b212e93d9e70aae78a4f9f6bae592ac2b5f96eee627971d27389905b215869d9f4b706c379aa802b5a99abf754ca9316872f033ecbd5b34f72c610c14037540a2c86ac7eab0c3af84729c48610615c9956751759660b3c7bab57146f7b1088501fe14b2f59141b1bc6302d88a35fe27e0cfa18c1a22a9eb517ca6060f25408d4299a7f46c458b3bc38c4794bda8f9079043854179db0071af69c9f074a83438874c882cd18b69b0b2009497b6fe94a9264470be8256b49b6c353374ad49c04b1276fd484338796e4389a523598f3776291512e25fbb5fe98591320c1bb47c6ef3b4bd1d62b6997b5561bae038854ceeb41b2925c1f1a81a702b57b2815f62aa9eb2625ff3512cf9595073ca623da43f32c21d63297a491b28dd8b1361bbc91b40b34a65f1a2b7db86b0b3bd21b26ca5795b795e355b45d1623b3a9731218174b50966d6937ed057fb10b631a51b7d42072a0845be8553e19901fb0eba35f5142c75857f642918bf24544355c4041102d8b197b429fe548433eac36c42077ed787f8e631edb856d4398a26d536911ebbd9f9c22769c756f858d180b6b51797fe9ec0833c908d9ab2730d937b76a0febb68fd84372c96c3c05197093e26d01219c15f898b2c7ac75d11485a2a413a065be744e0908b6340155a244838ddb14b74c578fca2d7e6c4e15e68421a568e7e39a4a04231926768ac4a061d67550a8512e780198738bf3e2420cf75680d1cac07798c01ca06102cb2ae5c9b99b62a7349fc8a2c558989b68e3789c2c7074b476d18212846c8a8d562166829a36587eafc95a362874e812aa951a6995f5a94d370afc9b64777a7e58cb54b62a95476ccd323073d6e466e6ab909b4b4cd840aff393c9391902f4c05bea833d254207cfe938669cbee478c57ff4424004003d151fe5e90413924bf1378419e08dbc46911e2ab2b7f45dcde5c549f679691632c3d9bae26b9fdb85c7bc3301a3900386873345974bdc007f869155df79cfc6f06c39d8bc9a99675382358ba25836a15cc222ae78e4a85a19c5da9912e48128fb37a7f386c0fc86afcd2869e292ca9b521e6ef9b12908ca5d800ae1a7a3a7070766e2802a947c7edb3452a377d9c1bcdb152d37db41ce7c74c36b32c59131b1b85f9b68a3b66773ee4a2b81f12509c33cdaab4caa563e9bfb3cd9c4c72354c1e88423f94169e18bab1a9798cb99031ff852e79229630c8f35459bf40c425af7cb0843498a3cc7fda53d932a07382018de07808aac2b4d60a1e242beffb89489ba69a6a26446180103c11f7b22361f651777b997b76ca8f5a25b97291058620ee5479e92aabb218444aee52e5c8294d578c709158f655a8930fc197f765fb3790bd62a5fe11b57f273775da27fc1b5128663c623f5175513b753543bd71aa045e77e4bd42b7e7baa5ab2c4d3c41f4db84af265acecd4906fab897b5abf5af66b4c4a0b4e783b417c6fadd71d34ea294ccf8b8c8012edb8badb3437b191165cd639bcde9eb71378e71fb551293a7acfc3d283541d985e0abd85eba5315a17d6c4a7e4f248673da60c341c29fef072d9b5a99f9c7a0a011e4dc10f6b600d611f40bba75071e7bee61d23fd5eda" +}, +{ + "dz" : "9bc5315580207c6c16dcf3a30c48daf278de12e8c27df6733e62f799068ad23d5a4d0a8a41c4f666854e9b13673071ceb2fd61def9a850c211e7c50071b1ddad", + "pk" : "b30c011788cb97cb439789a67d476d3dd265cae63cbe43cb63aa124b93071d6812bc662f346481f974a73b16a505c48b9608359a3c035135258029a18b0217461830785379d3355ff3968d3c63a46685902425660b232b11b93997e60ae0a5bb95a27d553081f393040b1c30ec87535ffc6fe528b1e9866cd1e69520e376e0071087748691dcc057b95cd4c60707d8b976d6a67af4869d960d5466a9f3251dde92cfe8a0b03ea2c43bf03fabc9c9b5d97ea2f558b2bc0ec1908335ca4f2607cb04380a830b245f8b43fd06098269bf9ce33fc07c1e68a05f63560d70544eea4c0bc528859a5b09683b8b3d3c6842e6458061b7ddc4b23ec6ae83d557e5c4b1848445fe253b35e52102517cd38030e6ea28a5e1a24bd09ac6b83c5dc658d11589900a7bb09a963480a2d76225ae55bc54108fb233785174b375a184eba110e05762e7f26139dca4cb197620156c06e47e5b74a0970bc6e18b1e1c919a6c0b10e7470d5ce09e2719194da0440ac3aacd86bf724aa841a83dcf64c8e1f7704397a4cd57bbabc9a0cf940e97e8921211006044228632382ef48fb5d3b65219a5a6983ad0e48ee39081f2ba1103bc9c6314090a31aa34213c0c319eead96b865cbc98327570b965bf00cb9bac18c640273d342cedd11d72e2078399c458068439a8a27e388d3f4bb285b63992b5a4354122ac298222e39d31cb886c4958f28c5c2f37384632b4db216b43ca6246051fd704b5969c07dbd525ac6a479e730f8b11c5d41111ac65764fd71a4f43be55c563cee5c26c69cdaa485d850c2126f2bb16f5766fe86bce17535198ce99c2a66918af96641b2ec74be2b61752076a2db330984ccd7021ce360a0c488143648389f492ba20ac566cf401383a496991497208b760d36da6896bb3587788597191c3347539be92b78cc6a2b0d8eb4188320ceb8aa6ee1018e9f78f4f8097ae7527ec947cb1b27dc8a86ee200020127531273983bf66746a7b731464a6b1524b18744a8c606648b2fb1a4339d5a15d7f6a5ea3a1c08122b773ab09564792fba2e28719a603c3ed0850f2d5045de3bb93dda7a84e692c25537ef695787fb0889107395f87c6b836e138bba9f4a711daa421a396f556c26e3778f4d364d5b1844118b367d78af37836fd7a9637f1714cd9a3e52155b0047468b5420cd5c6bb64138ba16863e18b4368542800b378537b5cf303cd2b191ccf783719142ffac1ad0585b1938281ceb5c86587c43b28c49d9111982ba7ac567e1fb64d8e3c450730305cc2e4e12cc698a728977cf1c9b373f051c17f1935177ae90aa8856a5a24d18a08aa942b4250a6447c35289cf0b334af45647e21b5a2153a8a05a38ac4c728a3350a15502cba347a876cc4bd12034935bb3dc14435930d912aac8a787db3ca33521637c5159b015920100b416d22c18d6a0a52612c7d75c15741b6954ae752c4d31fbaf1b483b6b6862e6a983d5465e3b7b80e1654faca5c669e77295f86263d344031b5ea7ab99e714c0a821042bd9512677ab9e89309f41cf47944da1801521402f211a6076490ae393818ea2056954b24a624e6e54acb7d5bbb32c14b339730af6a72647a66f761bbb78012a76540763cb29dcb9b8c27a3c1e43769c31af3ef54f7c8062d713cab3803437e759a01ee76fba1a5b", + "sk" : "b141b7d0d3c420b8548eba8e71f2a751882023a2938a0628fea97eacc45bd2fa0e89f485e57355e9c58b57746519e2538060924d9032508a508a8a36382254b5880e77248c6734c7f841c309830ce19898233116c0482888c03378b5946eb53e4a59b190b62dbba173d4297405f9cd189c76fbab0786fac8a0e90eb3e8ad689726b1f8b321175094260775e143cfea2c22a5aaec749e7c7002cfe8ab16345adae43b6ca04bdc21632f799c77da62755184c51b3535830277d83ed07574ff8a478c06a7dc817afef2684c00784865116fb8755cf13d19750e01aa165132c2844c1d27409d975bb2b0c97ffc7222db3b13d47c8a5ee20dd147307bdc65b3ab91bd6481e17686d2f1534c0c73fb633260930a92c25adebc2bbd1299185439d0811ea303551e0879d825ccb08b7e307ba37b843854215ebcca1eba3237d95080c317979da65172146645a543ba045f13851781028669c9b4ccc217d5ba8585a1495d652dd89b402c87043e285d3b0c72eac388960367a428bd3e7a903ffbbd83614df2b33180843375f1c9af398975faca439b0a15b2bcf804c340176400d1b80e399597372b53380df0c61ac2f0a1757616825c8a3f90cf227ca44fc88e8608162232b1b5b882017843a6b61af95193b6375951ca70ade7a525633c75333450cbb38338a493099990080d99a788426047426cc89146b4afe079fec981884a4bb1a27931074a88bc9bc1271c40f2a8b6a1bc0ca4a24d71024bc7acc077b97cc47531d21de9f94fa8dbc522f78f698c77078788f6d90f67a661095b942cc5a349076e79ea90139cbf9c2216ca4c704f9992fb7a213c0b97d2bc5fc3491a6cd3bc599c9eb4d1469c3a3efc14b7c6020c4a85481cd86d8c2b2f51410ab1cccd55458bad9422bae77c1d544cc52c94d0d22d2e9783165548baf519bd05b4909626da8991fb48cb82b0c3a25b34f3c57a537039dba031857b40023b6ab8baa64b5234dc5403bdf3aa647ca09bec6f32148e99db47c7d141edc70c804b722559caa7214184ba97ba9802a7604604e90510295b21204b22955402ea572a12122205ade2d1524e57b85acaceb767086ee1218fd51f4799be7364137b364dd2f832e8731605c9c69f4848b3237b51ac791d4a5a3ecaa5edd29de90412ca62c5556a6389ec98948735e162745f383c9c59a99764583d19c72255454b568b908a0e0828b7dd235dbf2268416c1be640289606609f0122c0b492169954cf201a7d654e21541eebe5448b0175d9b10314397a6632865cfcc055e566b476be03773781b35842b6583105200e1cad7475bf95355268aa1cfb1c7c16a68d2c38b92b6841c0b545c5e972dd7794110b5d34cbafc9678e66d100ab1c6a1e0b5c262148f730762086bb7fd017aea3069ef76c71c110db4c80cb2c4fdc8c779486223920731906cb4553a00a400a3878afa709079354a7f3e3795ae77698668fab278688f3b21558306ee6844801b625b017203ab715d110fd636f4fa3c2c3c56ed43879468c9cca379d3cc77197908c54875b0ab7b35ec8b774b5ad15d3ca75291b1ceb201a959b57215657606dbc9b8f1c124eb8a57c6146b1931c019a0a94ea266f441b6520b199161877b30c011788cb97cb439789a67d476d3dd265cae63cbe43cb63aa124b93071d6812bc662f346481f974a73b16a505c48b9608359a3c035135258029a18b0217461830785379d3355ff3968d3c63a46685902425660b232b11b93997e60ae0a5bb95a27d553081f393040b1c30ec87535ffc6fe528b1e9866cd1e69520e376e0071087748691dcc057b95cd4c60707d8b976d6a67af4869d960d5466a9f3251dde92cfe8a0b03ea2c43bf03fabc9c9b5d97ea2f558b2bc0ec1908335ca4f2607cb04380a830b245f8b43fd06098269bf9ce33fc07c1e68a05f63560d70544eea4c0bc528859a5b09683b8b3d3c6842e6458061b7ddc4b23ec6ae83d557e5c4b1848445fe253b35e52102517cd38030e6ea28a5e1a24bd09ac6b83c5dc658d11589900a7bb09a963480a2d76225ae55bc54108fb233785174b375a184eba110e05762e7f26139dca4cb197620156c06e47e5b74a0970bc6e18b1e1c919a6c0b10e7470d5ce09e2719194da0440ac3aacd86bf724aa841a83dcf64c8e1f7704397a4cd57bbabc9a0cf940e97e8921211006044228632382ef48fb5d3b65219a5a6983ad0e48ee39081f2ba1103bc9c6314090a31aa34213c0c319eead96b865cbc98327570b965bf00cb9bac18c640273d342cedd11d72e2078399c458068439a8a27e388d3f4bb285b63992b5a4354122ac298222e39d31cb886c4958f28c5c2f37384632b4db216b43ca6246051fd704b5969c07dbd525ac6a479e730f8b11c5d41111ac65764fd71a4f43be55c563cee5c26c69cdaa485d850c2126f2bb16f5766fe86bce17535198ce99c2a66918af96641b2ec74be2b61752076a2db330984ccd7021ce360a0c488143648389f492ba20ac566cf401383a496991497208b760d36da6896bb3587788597191c3347539be92b78cc6a2b0d8eb4188320ceb8aa6ee1018e9f78f4f8097ae7527ec947cb1b27dc8a86ee200020127531273983bf66746a7b731464a6b1524b18744a8c606648b2fb1a4339d5a15d7f6a5ea3a1c08122b773ab09564792fba2e28719a603c3ed0850f2d5045de3bb93dda7a84e692c25537ef695787fb0889107395f87c6b836e138bba9f4a711daa421a396f556c26e3778f4d364d5b1844118b367d78af37836fd7a9637f1714cd9a3e52155b0047468b5420cd5c6bb64138ba16863e18b4368542800b378537b5cf303cd2b191ccf783719142ffac1ad0585b1938281ceb5c86587c43b28c49d9111982ba7ac567e1fb64d8e3c450730305cc2e4e12cc698a728977cf1c9b373f051c17f1935177ae90aa8856a5a24d18a08aa942b4250a6447c35289cf0b334af45647e21b5a2153a8a05a38ac4c728a3350a15502cba347a876cc4bd12034935bb3dc14435930d912aac8a787db3ca33521637c5159b015920100b416d22c18d6a0a52612c7d75c15741b6954ae752c4d31fbaf1b483b6b6862e6a983d5465e3b7b80e1654faca5c669e77295f86263d344031b5ea7ab99e714c0a821042bd9512677ab9e89309f41cf47944da1801521402f211a6076490ae393818ea2056954b24a624e6e54acb7d5bbb32c14b339730af6a72647a66f761bbb78012a76540763cb29dcb9b8c27a3c1e43769c31af3ef54f7c8062d713cab3803437e759a01ee76fba1a5b21916dfe025b78fc6d4dd1d1541b51cd3eecca90ae52177431b33c708faf17b55a4d0a8a41c4f666854e9b13673071ceb2fd61def9a850c211e7c50071b1ddad" +}, +{ + "dz" : "d8b907b34d152ff8603b73051f772daa71eb902c47b7e2f070508269d757e02e36b817736cbc5f7b1dd6eef5fe6332fb1a598f3871e5470d440fd2ea631da28a", + "pk" : "d23b1a80b6c91017009cfa4925f3cca1b97d1a820b204a4ad5f4bb2147307a5350d0244ca20102b8f800c924bdb5667a5866303ed52e27c932a1d84c637c707537409fcb7515f195e557920ff79a3001354cea327f274edcbb99e66acda0aac52dc503717a3b24786afca70dd84c7c4ed1c1b3ac454c832caa687bef8a96bf6c1182f5c663c1ada4784654393d4c83219c149e31fb0ec1e9afc4297968c80209594aa567c65000a883b32e3fb82d9eeb4e9af65ca4fc0cc1ec794eb2b7ede1a5556474f3b023c45b5d8712109a2281f4527a4bbc8262c9bedd0758116643bc6a85f836825541767595c0b54516a330137f0724a1b232cf0a399e0478f732c543f81b9d05c7f5b086c64291b2d94cf02462df7c0f43eb06319265ae25656b462f1445ca5299166731b114e8458a0a0361b135e6002315b65b337304404a907f3c1d41ec9220055939e11f263186c3751f96d750f3a8588ee14f40b09178368ef03a9526a5444be096c3da8a7441638f64b4fd201e31b34f2c456ec89890f53c9a25b559b47856053227e3b36c16297949c6b11159a79a4344f0759c7071a738eb0f80c25ec2f0a2efe614c7766c9dd68fb488c4e514769d9b6be2d59e9c9cba6b5b1dbc9b0d8e5c7078663794fb4eb8c7060bc1b61286cb173ab6a80952424423746bc91bc953b67908bb34226eb382bd54bcbbf5c60e467652728186c357b3fba85f6b8553c79c730ba51ab90d06ea9edd407b89e0c0a4276ea3698ee5e6a8348a2f9f571c2b7b93f5eab702f1acc3480bbb223e68361fd89a57d1716fc8c99ff43734fc58969d35077f5bb422b859b271b085f41394f28b416565d2f90848216ade3cab7c205ef2f47d8b50b9152a9ba6032322e737089a1e5152387e3437d2190cb9e394bbb6857a1b1ead7a3d7118b0ab8367ba1cc09f910518420a46a18271408121db5dcb0670ed789d537ba3639c530a720ed9f40c023c75b1a8261b6c0192b14843252cb8d713c8736b34daacfa235c9a51468dbaa6f2e4507711344b5a722ae46a70e683c42a9056ecac5d143f9929006bb168ff2ac983ca8b1d99cfc1c8cd919b282eb921eafab2a778b227968f77ec885077ceb7bb5fa13884b6a4bac782b31f250569e0671396b780e810e4a34416166c18c4204ac4124c1020064a257c32369c892420510811f28872d59cf8db48f2a1510a5895a09c008be695699a4845210777146b56093d36960d6c36860cec578de3688bf338a28118a67833f5c4c7d93b8867d93ea7aa99a3743434d236d786cd8e617791bc5452c88e70f1189d5004e17146f3c69c60682c11e78b06b2c0815bb889a17a15eb1d985b601e6c04604cce34b13d82a328f61c2dddaaa25fd9ae0dc83962c0887e392a25c8657d61cc2ffc980d4cc4c9557e7dec446828b03e8bc9a1355dc32b1c06d504cf613235b6b9b1b04c0ed550545bc37e7000a2366786da49d637ceb5c4273041706597236be0a7213cb0394282aa998411e1236ab964a7998055a183dcc4ce765b8756760fff965d2b7c5adc272ef1d3b214b4ac9b543e0f24876e773edc54c105892cd882848fcb039e5223d0c68fa204cfdb793c5ee56659932cab213cd4eb18fa4b045103a1e865b0c567574e523be27974b08adec6d539f37479c61fe8d8c4", + "sk" : "5e74b833c0808f44300017c6b2773ff7569ccc971250623710e01c79f2457f572dc1a8c9e23bbabf0b16de993a063931936a4d6f4a22e1961949ba5df2e3aa07693ed37b2b9d98668019123162be5a1c2907e35d0ecb258cb034e4489ff1616d5f6b83a7877e0cdc5ed4677d84924381b1aac175377b4b953863b296c601140281d9d5889f649d3a4c8c2ad662bce81753b85d26eb058b7536ab98afbd4a969ad26db781bb40d980afe249ae56aea88b59f1b28dd3f99ea3e6b8dff2bc91544f7173595fac70c0d50edec867b90188f165c8b1725a00a45406e18d242b2f63f7736f68c13c5b9606e700f9d3cc64ec0a94872adb04437cfb7ed2623eadeb11da382785c74d96c96647e482e8ab1c9af58cbcac5d4741cad8e6a80028219af15baabac6d2e884599c2b83a1307a03ad2d4791bcfc767dd36b810ca63a7587486749835514fcf4c0b7d3b06d950cb1b26b69b8abe466029fa2b66966501f6c812bb24834c3b72bca0a98913816737384d29a3e70327f86bcf85aa92d393a5d516b2aa49694e32845c559ceb89f6351b825baa599011efe9558da35a05b4537d01c6ce8b88eaf796b36a35c9ef41ddef86ef4bc695424bb63fa5cb4533abf2497d39057651b22a9806b20a9a4dd6075cdba87c04051219a8c7fbc564ca84f1d51baac7bbbb8bb2118990e5138726fe0c4ec51aa44780d5e66169ff17312d214e4d908e8461b2c004557f75ee749889fe23612875f02046ea6a6604c6c74dc746bb7c08ad8fc324be971359ca32e17864987712225257af3114be35a3483bcfc1135c0ec9a34b67ce5e20290b13d5e8a601e55633c154a83d65e1ea03d8da88bf5875429690f848bb314b664c851a266a880f68c8b69c184c773cbd73a3e32556207f432ea9126e6e778d76638607c341ab42b61d59d4be986e686474878a4d43c0877599689b35247061f98229384250e78408b76230a5485486ce70b076447bf96263c0058bb455cb4901d4c99a00eb316d4ec3540e6cd269b3093c6123d855fff761e2e394e4204366e7a132425978a0561a4e2347df685c5b6b7d291cb3e0970ddba9bf9166a91f5cfec7c751bc793a574181421c07e854103b4c5943cb3f89372e23cb98f75bae819c71de64a98b145794a6b006300f851c5581a30293542ee4482fa8987dd0a00bab3a9881a292618724d8c164281bca6a903caf5c52b31b3f341a5f3626d30443190422abd129f2e677682352c4c9427139a2b77a362043cc1af5737af761a62f27161018d76f8137df25c1872a25cb81243aca20fa738fba24d708c7f2d610422481f3ad74061c22141b7a448ec8bf7670ed198c0ea72456567108cf56991d47069e6a6639c2dca8c95086c8d3a5cc49e294400bcc2fcc39c5b673ad1e6248204969af47a4b036fe7478ea16349a4b49b857469d115be01c2662afc5880d5924ba498e353597157b559343848f2ccf4ec17951943b39cac83bb52c5665ffd1618bcd6446929cfda114ca3c554c6b9821b6b85084873a3b20e5dd8486aa7b591b1b6f7b83b585c9112884756386a35a04f60b74289e206f2994d8c56185b1698c0583717368f7ca58e7635090aa262cff0b93af222dac695d23b1a80b6c91017009cfa4925f3cca1b97d1a820b204a4ad5f4bb2147307a5350d0244ca20102b8f800c924bdb5667a5866303ed52e27c932a1d84c637c707537409fcb7515f195e557920ff79a3001354cea327f274edcbb99e66acda0aac52dc503717a3b24786afca70dd84c7c4ed1c1b3ac454c832caa687bef8a96bf6c1182f5c663c1ada4784654393d4c83219c149e31fb0ec1e9afc4297968c80209594aa567c65000a883b32e3fb82d9eeb4e9af65ca4fc0cc1ec794eb2b7ede1a5556474f3b023c45b5d8712109a2281f4527a4bbc8262c9bedd0758116643bc6a85f836825541767595c0b54516a330137f0724a1b232cf0a399e0478f732c543f81b9d05c7f5b086c64291b2d94cf02462df7c0f43eb06319265ae25656b462f1445ca5299166731b114e8458a0a0361b135e6002315b65b337304404a907f3c1d41ec9220055939e11f263186c3751f96d750f3a8588ee14f40b09178368ef03a9526a5444be096c3da8a7441638f64b4fd201e31b34f2c456ec89890f53c9a25b559b47856053227e3b36c16297949c6b11159a79a4344f0759c7071a738eb0f80c25ec2f0a2efe614c7766c9dd68fb488c4e514769d9b6be2d59e9c9cba6b5b1dbc9b0d8e5c7078663794fb4eb8c7060bc1b61286cb173ab6a80952424423746bc91bc953b67908bb34226eb382bd54bcbbf5c60e467652728186c357b3fba85f6b8553c79c730ba51ab90d06ea9edd407b89e0c0a4276ea3698ee5e6a8348a2f9f571c2b7b93f5eab702f1acc3480bbb223e68361fd89a57d1716fc8c99ff43734fc58969d35077f5bb422b859b271b085f41394f28b416565d2f90848216ade3cab7c205ef2f47d8b50b9152a9ba6032322e737089a1e5152387e3437d2190cb9e394bbb6857a1b1ead7a3d7118b0ab8367ba1cc09f910518420a46a18271408121db5dcb0670ed789d537ba3639c530a720ed9f40c023c75b1a8261b6c0192b14843252cb8d713c8736b34daacfa235c9a51468dbaa6f2e4507711344b5a722ae46a70e683c42a9056ecac5d143f9929006bb168ff2ac983ca8b1d99cfc1c8cd919b282eb921eafab2a778b227968f77ec885077ceb7bb5fa13884b6a4bac782b31f250569e0671396b780e810e4a34416166c18c4204ac4124c1020064a257c32369c892420510811f28872d59cf8db48f2a1510a5895a09c008be695699a4845210777146b56093d36960d6c36860cec578de3688bf338a28118a67833f5c4c7d93b8867d93ea7aa99a3743434d236d786cd8e617791bc5452c88e70f1189d5004e17146f3c69c60682c11e78b06b2c0815bb889a17a15eb1d985b601e6c04604cce34b13d82a328f61c2dddaaa25fd9ae0dc83962c0887e392a25c8657d61cc2ffc980d4cc4c9557e7dec446828b03e8bc9a1355dc32b1c06d504cf613235b6b9b1b04c0ed550545bc37e7000a2366786da49d637ceb5c4273041706597236be0a7213cb0394282aa998411e1236ab964a7998055a183dcc4ce765b8756760fff965d2b7c5adc272ef1d3b214b4ac9b543e0f24876e773edc54c105892cd882848fcb039e5223d0c68fa204cfdb793c5ee56659932cab213cd4eb18fa4b045103a1e865b0c567574e523be27974b08adec6d539f37479c61fe8d8c48f62011fbd5a1c10713d42a00a79ae7672e5e321872971f24ff71ed754178d6336b817736cbc5f7b1dd6eef5fe6332fb1a598f3871e5470d440fd2ea631da28a" +}, +{ + "dz" : "684a29e4e5480a5f2533e1526b5fac8cdf5927f3d85087c71f928c59690eb56575d12195ec32a8686d0600e45d4a7f54219b0d7a3826d193a51b9156ecf2edd6", + "pk" : "4f27944614c35d121bf2390402bc93797055936a2d49699cdeec2f29413403aa1024d802d97c54aa316707c26a0b432821f63cd89a87f769597cec8356c2c399d3a34115cca89b9df6a55e4556a3b2150b51907ce67b860f697a65b199b370691fdcb31cf7937d1524bef41a0732cfdf464175c95d9092176ce52814d3a9231114cc31718755ccd3a7b3fe69b4290175dc440cd38c69faecb190ca684fb1001b5308fb4c1ff6a55b4be8814d602ec59c2deed654c93a45d55a3e020800e98aa786c76fcf33cea3a7bdbffa5037a171044b1b74d6094d1a3b606009b4fb0f060b6dd1d29ae67ab90c90c25db895c9515fe0a17bdd69c6773518a532ae8ac731e32155500204dae2c9284cc16f61b5a9e48334859357506e2c391d1bd38865ea489e492d8b847a6a50ba074320fa32074d89894324a705dba4e1847a5059645c77063809cbf3cb0555b6be4069c77b10a6c6f67ae1e7c09d603e87a34acd3b814d7b4798dc05acba65220289772abdbd89403e698f3556511e152bc0f77509dc36803b57d08129951ac44ecc49f43b7cfe8436baa8b5376999f6442293352e76ac592b95804217817ad5a75a76caa72172df9c69da4c170e937a69d93f12c7b533d4bce41b34d0cc8a1c969947db2c21a960d975ac029280ecbb527654a42385576286915d4b8f3fd163f0cb280736bee89786fa277c8487b0820416985855a95a10647059cf34c08915985c32321b5b8b45a468cd4253c662847eea36fb238098f059630cac83aa70cc9596cc1a0406e993b737c236e78cfbea1191d60fc6428fe7090997f1ab41c13e0c57a256a813bc559ad1e6ad10dc3cf43a64dae2955f03b46a09ac6ee30326d95d6ca8b80e61aab77579c017a1906279ac09766bd8a1b40b24d8bc4deefaab47f9c14a8441eb413dbd718e5122ae7beb94f526a31bda25d893a544670d994530d3c6ca29879085870f6d54192b1a7fd63193c7423be4867d2c134683ba25f9240e0fa2a96b47c5ac05b541c2980f51557989b3eba42dad002412f462acf75b141c5fc320bdafd3c11be291eafc04d6b5a1d4117c7703c313eaa30477253e938764364b25d859aca263962c5d6d898ada856b70e151dfa41289213acda6cdb5241bc7067bee5cb467c34d2b0a6ded6aa746290ee2e40b7be1294c583aaf415dd03213a3cb2e41f10731823e749acbc53767c12b93d8f32257a54c6a71b2041a167d685f0bf789b94b277f1b60af22c09b639ac72ca25b1c69b855bed6377126999c5708789091cedce768b253ccae981715c8922dc9562ea8a0ba102b02585281b15c7e44339cf630529c1b076106ee2b5c7be0181ce43d397a398c8547da703e2ab47bc15284f4c6a50dcb904ec9c1f60a1aeef38435997871e8501d4832bbb2a3354c70d9579f237427135329cda32573089687d9a9130375bf66ac321113a25a08aa75cb667635455a93eae7a0a6703a2dc0a85637681ecb097f1b16b2b331210b6288b13f5752bb6c731adab30ca051a817099095022892d923f571b8d879c8ddf0ab03145a32298dc6b644b25640d808006e3113accc6a0c1ccb05ec273e6b6559e287539c72d754ba9bc48c915acebb656e3cb7713e9bfc0bb6f311485ebaa078b78a737d81d38d368c220eb0e982fb0bd8a7ed97", + "sk" : "c2bcc42efa0baf63bae062a1b1322114519cc504048ff26ee73b208d659518a286dc411c3097293d79bfe04790f8b87c1dca42059c447ca5a382733c27550b41a367e19175e084c49b9bc5b8d1ace0eb4ef2b220f187929171a10d5a9a46c8b89ccba3b2435720780f6851b01cb06ef5127100c4ca44c6188aa3af8e875b85317f47797d6d699e6d619441b26fee871863392ff455413ea78d53852d5b19361ce82432410adc6ba90793cd3330444b82a06da38a131a1ca91756848ca59e200c86001c21d19a7b5a40692a979bd351ff140276f176c9f189e3499d067cb054f9a5725236abba148cf05a539675331352834ca583b8029c764ebe829cbeb934ba76bf3e75a1a2b0a65b879cb0b881dda38487558adec31029783ba7ccc94ac879690049452724c3073106790748d57102236f4e9cc4159a14a042cc4c6986ed5c4027b28053d673f42811b4e54fd62507115b990849a9c3ea6153b405b6c73f27f6755db5c489761da376ca05031e027b6a34b12117ab8cdd1965cb958e6e0a7a8f9b8a780b0d06625ae7b8b5d2e97510c3c8a3b010b46506db23ad99f509d3342df563c2ccd951a7f0446d582ccc872aac034a27a90822506af8acc35f321bced03f1dbba19507c17688965b59176563088cd44dfcbca8a60baff382b15f812768c41d3aa6227c760e78fbc5e8191b01e697104164d8c1bdd2133aa222886263a573cb3d18743ebaf7abc486c5ad24cdd770250ff860acf05a88cb464088cf23c82f9a191833a780ef44bbf5a06cf1442fcffa547ffb354c8476c0b8135c6abff733c30f38a3ff331a836492ba26c668b679da54463b68573d566de97a2b4a53cf9621a6a5a7493ff190b5c9a7ea63019fd1c3a4dbc395d0b254c80f7b5668e6074fb0bccbab9811010b1c42d55982928d604ac9f3b5c0a3888cbce54cf0e1ae0c9914fb5474ec29492cd1bef2537c4e3837ffabb058993c3fd11253e87e15e84451269b6a48911ef15e4f82606a475cacf420ed6796ac04af07633b6ea63af927c611b07dd932bd0ce852c4b785f7348fe2906eafc76c3df8706735813ff796ae51837c198e2eeccbd0a64b45254209882351740fb6414363976ddbe5c302a29dcd832270732e2c6abea1969e8b17ce2b1807aaf2485e6b07e3a7419b5019b8172a3ea0b7907a70589a88cde16d1b043d7985860f623b95645ca1921ac8109870758016a5bdf37acaa273c18b6944d0911a0d255b4f9580e3b50383f93bb7871f3fc2b280f2871b1c17b2c74b9368773ab747ec2b87209910cfa859243b7a75288c163ba025fb667025433b12c471e7c9642c4ab105413e0641d7e961b3fa462ec797d6a9cec7ab1ef6a64b5d5869c4e6c3ec884afb87b2a8711a46014dad830fcc195dcc5b966252c5a350561b0359efd07df9a4b4bfc39ae6441cd70b57a4718d55a0bfd8f979c0d01e31787afbb1a8c2a87e5a7b70d8976ae4814950d00e998927039111eda21993c17fb107034faa658617568350a48dc4bb3b124b032b35ede2ba312162b57067ab245533177dae67894349327663c329c2a752002326b18cc60b1cd1098968d18168bbbcab459f4a4c18f63a7dd0e9ca68f43a6592484f27944614c35d121bf2390402bc93797055936a2d49699cdeec2f29413403aa1024d802d97c54aa316707c26a0b432821f63cd89a87f769597cec8356c2c399d3a34115cca89b9df6a55e4556a3b2150b51907ce67b860f697a65b199b370691fdcb31cf7937d1524bef41a0732cfdf464175c95d9092176ce52814d3a9231114cc31718755ccd3a7b3fe69b4290175dc440cd38c69faecb190ca684fb1001b5308fb4c1ff6a55b4be8814d602ec59c2deed654c93a45d55a3e020800e98aa786c76fcf33cea3a7bdbffa5037a171044b1b74d6094d1a3b606009b4fb0f060b6dd1d29ae67ab90c90c25db895c9515fe0a17bdd69c6773518a532ae8ac731e32155500204dae2c9284cc16f61b5a9e48334859357506e2c391d1bd38865ea489e492d8b847a6a50ba074320fa32074d89894324a705dba4e1847a5059645c77063809cbf3cb0555b6be4069c77b10a6c6f67ae1e7c09d603e87a34acd3b814d7b4798dc05acba65220289772abdbd89403e698f3556511e152bc0f77509dc36803b57d08129951ac44ecc49f43b7cfe8436baa8b5376999f6442293352e76ac592b95804217817ad5a75a76caa72172df9c69da4c170e937a69d93f12c7b533d4bce41b34d0cc8a1c969947db2c21a960d975ac029280ecbb527654a42385576286915d4b8f3fd163f0cb280736bee89786fa277c8487b0820416985855a95a10647059cf34c08915985c32321b5b8b45a468cd4253c662847eea36fb238098f059630cac83aa70cc9596cc1a0406e993b737c236e78cfbea1191d60fc6428fe7090997f1ab41c13e0c57a256a813bc559ad1e6ad10dc3cf43a64dae2955f03b46a09ac6ee30326d95d6ca8b80e61aab77579c017a1906279ac09766bd8a1b40b24d8bc4deefaab47f9c14a8441eb413dbd718e5122ae7beb94f526a31bda25d893a544670d994530d3c6ca29879085870f6d54192b1a7fd63193c7423be4867d2c134683ba25f9240e0fa2a96b47c5ac05b541c2980f51557989b3eba42dad002412f462acf75b141c5fc320bdafd3c11be291eafc04d6b5a1d4117c7703c313eaa30477253e938764364b25d859aca263962c5d6d898ada856b70e151dfa41289213acda6cdb5241bc7067bee5cb467c34d2b0a6ded6aa746290ee2e40b7be1294c583aaf415dd03213a3cb2e41f10731823e749acbc53767c12b93d8f32257a54c6a71b2041a167d685f0bf789b94b277f1b60af22c09b639ac72ca25b1c69b855bed6377126999c5708789091cedce768b253ccae981715c8922dc9562ea8a0ba102b02585281b15c7e44339cf630529c1b076106ee2b5c7be0181ce43d397a398c8547da703e2ab47bc15284f4c6a50dcb904ec9c1f60a1aeef38435997871e8501d4832bbb2a3354c70d9579f237427135329cda32573089687d9a9130375bf66ac321113a25a08aa75cb667635455a93eae7a0a6703a2dc0a85637681ecb097f1b16b2b331210b6288b13f5752bb6c731adab30ca051a817099095022892d923f571b8d879c8ddf0ab03145a32298dc6b644b25640d808006e3113accc6a0c1ccb05ec273e6b6559e287539c72d754ba9bc48c915acebb656e3cb7713e9bfc0bb6f311485ebaa078b78a737d81d38d368c220eb0e982fb0bd8a7ed97ed3d1dd05854a6542b24090a680b9aa9d6c65ef31cf1f4f5708affafeb2e398975d12195ec32a8686d0600e45d4a7f54219b0d7a3826d193a51b9156ecf2edd6" +}, +{ + "dz" : "d76b3573f596eb286ab5231feec7499686b13021be36cb126c7ebeb9d7030daf248c0a21ea0bb6d6f56f12300e8584d8e9a34e0e6f52227281151ae4c305fb8f", + "pk" : "39b95d90d51e8cecb49dc41a37e866c8fa1bf723c3e3815b1f388f63d791fe0cb8507020e19125bf0ba753fa89c19180a7505e15ab6c44e32f70499df5cb106f85bcc5dc4f20d9660c17307de05bc1eb6bdcebc52727ca3544772cc56a08b30c0c54a847b28387808a1747a23f6460054c582b4ca1e09691c64615a6ba3f89a05a18eccea06b550241047c1807f3323dec674f17056d71b7bea906463efaa0fa50b051723e0cd66cc7587df4b58d49fb029fda6e2e507d637ca7d489971d897b09148a6a2b47d3b4bc3a4ac0715b3abde096bfd8622ca24141683771ccad1094595b20c8af004d54873b0d42977886314fc889e5804474005527170c49882ca89648d24ba29cd30a7c2868f287345f4926f1141531d3a53cf68c8662247d47348cb1a102613ab236b67bb9a7cce47e794096c0a93d54f743cda16ea09c8d87c43e4a1b2cd9b0b5ea711f30b39812ca44da20b02cb4c8fe12343896ae6eb838ac648acb8bc8e887ac69602e7d81263315373029b2d6713705935a43177b9f9888115202ecb1a60e433d8de2bb42d235135224c7f795d342466b4c5bb8bc93931116479171800b717c033a304bc619d2a79a687e005d6215fb1e76ab67d8b46c72857a46d753674a7ef3962c90f2b62f51458204b71d95734533875819a495360ecc12b66005330593456c516ead7b3c942688a822bf0d92bf849bab6068480a0b0b4b8c3a451007dc2a733de7b51d835e5b7900ac836fbdf13a9ee82b34ccacdf6b8f4cd0594c80473040b633b7ceaa091259a21c5c881602c146e4444e1e48800a189239241813c13b724a02e6e7a70834493f794ae7991bbf1b60d4c0084c213471eb3598079adf95004942176f297ad3d55b5cfac5a3b385679ca6af26217ad8309547a0738328bc1a519712ba545ca739e8c253a65394817aa6874e432a95e5f35aa045cca1fc1c7bf467424a8d498274646c05c15b176c8a69f90a0a524b6e4b6053979499e7526ac66830d28b28ca2c6dc4061b1546a4e8d7348416c8a8fcbc0779c51ce855dfc54d94d74bee674bbc383adb248c07eb8889b0b44937356906a61b1074362754440856bb26b2fa906ebbb94ccc943fb39c00292843ed501f5f673762e3afbd7179e41835208700fef233793c0850c5b48499afed371e56e5a92a4109662247b72338db4769f9849f9516266acb133af5666b18131ed347454250cb04528c91b8334c2f5b3401cfb28e45824e73c1b6854b330c47c443d931b9e5b139f31b25d4458ac53a32025d49bb5d1a89b73bf930c74c233bba7afe30239a41587985726fa09d0a7a2ab19559ed380d9eec34b5fa83b73813a763beab0a1f7df5b87962709f255256a36800b94062d3af90990b2a43251ad9b0e400bbaa4a306520443ecc8cf45613a8fc1c61e6312cfa02d23c1547a69cfe43660d987a0210cf60965fca77c850503416c7c18a37bc10ca47f517abfcdc018ffb538f474404917dd65c8a680a667b1762b5958e43547fca1aa0da8907d7d3a25b430724477eb2844e54f35ae8f27598d568d413914bf66b70e37ddbfb7df01c08e1310932ba90ac2287187b022dc659c83b9f554871ae4aaeba7ac76f1254f174493d31eda27def0331de8e68f7b1568c4c8919e4de7a5005ce152fef9c8c88ec9e", + "sk" : "9ca01438ccaf5ad79f0d253c6d29707c603905b40d1d3b93b269be9072ba04020672ec15ec059d3fa9598edca4f4db3164557b1737a0de750ef5c31572d80c5d82ab52184238c439862492403b1cc06c7efc7b94b41bb1718c6523db1e6f63533db04e4e91c405527a4ea866210731a687ce09d10e5e0945cef0807665bdfd797802092f0b6837d61550a1d481782045c99b7df6e2b9ac95bb44284f472b5ce1636b1b3662d732a82d76517b57ba46fc9bee14511be585cf0a6549584a361b7009a733c9595f01dc6290471e3d656371cb6d63c9bb25a8c5caf03a84f6684af3c7daa48b2850be6c4270412572f0c1ae74613752e6bf6d53c927f110f41922492780ad486de631565e99886a077c209b025a6561ba503599897444642db4750728e09d3ea6498d236153a743744217df5400876690e393b0f3e2a481c31b52d605cffa140651ceb93c1189aaa372e906a14b684bab42c82b2071133cc31892048c1ad57ab99a00680e03287516141c281d2e1978b44c84595a59e13647f11623ee2b822a36b4f41b8a153a3dcf6b6daa97b9240b25813343561750ab7abf17816d76616879e09668b9c277d1cdbad74a5e429074c07a3394ce72a99af63010be35611d296348a163cc2b412eba4873988ac341566d1c2e60191dc9603c62f058391392494976e073760c0a9fe058564d0334a14a4d8e9b41c2e7226842aee7dc263f35b47619c99ce66f6a546be0e716f8a61830c23f37f152607032d34a6ae3501a00818bca04cb9b7145673917b9252f449a7463565662513f92a5ad5bd4bdc6d63c7d7866019c0454956b92595efce15c900b6d60db94ece8c2f4bc7fd52240cda936a5ea069980837c32c777f60b2a5bbc41a540c0394a3ed53bf34b37d8e7627979cd52fba35b144df35cc975209f232a0d24000c826cb54d365d74182631a326ba0674b86b1af79a169ba6361d30737840bcc5f3798a9c5439541f6e036abefaa66a44a5d017855b48bab216170db6489d74a7acd5339e43ba3b6bb6d1411add611735b9083c75b5111b903965a4b56b4b27585e9670b0fa2c5ee631b6db0acd324710ece9a429c83b76bc417a087b08d989a44b3d9cd1217d835a12c62a437a34dd1568e25c6db41c4c98d0bb7cf7b12be2152c361c1a881b409730c4a9b82498245a8141a903c88cc7aef187628c226fa3ba83d2453ca397290a0cb7ead61047bc4d4f36cd6d70200a1a4139505e3a86885bd61cea052bcdd52a1cf33ff2411f4b9c91bccb7142c6657db694031649bfb8800885bb076a0eab3921e53b40c1b075677124b0187969db8384244f63c6936aac3f6770b9ede5c7129a8e55d46ad5d8636c80082c47611b5c3ad3b814db17157df41585e68f5ef027e9537d3375cf7df44bc807a7e88b8b9b083452a35a6a5844eaf3c4afdb3789806d658276c4a18361aabfe743c67b2c626f1cbb2a8cccee295e6dc7a4e695b205d4980151a89e404a2a1940b58854a7e12e0d221fca36592044492094619ebc7783dc1a12d8a6bdb95f697514f214a7707949c5e6ca4ab227800554d77639b9d2862bfc27bb686c701b0839402a33a60e0c253e32393e6a1c45003140d2b7cd56f34a39b95d90d51e8cecb49dc41a37e866c8fa1bf723c3e3815b1f388f63d791fe0cb8507020e19125bf0ba753fa89c19180a7505e15ab6c44e32f70499df5cb106f85bcc5dc4f20d9660c17307de05bc1eb6bdcebc52727ca3544772cc56a08b30c0c54a847b28387808a1747a23f6460054c582b4ca1e09691c64615a6ba3f89a05a18eccea06b550241047c1807f3323dec674f17056d71b7bea906463efaa0fa50b051723e0cd66cc7587df4b58d49fb029fda6e2e507d637ca7d489971d897b09148a6a2b47d3b4bc3a4ac0715b3abde096bfd8622ca24141683771ccad1094595b20c8af004d54873b0d42977886314fc889e5804474005527170c49882ca89648d24ba29cd30a7c2868f287345f4926f1141531d3a53cf68c8662247d47348cb1a102613ab236b67bb9a7cce47e794096c0a93d54f743cda16ea09c8d87c43e4a1b2cd9b0b5ea711f30b39812ca44da20b02cb4c8fe12343896ae6eb838ac648acb8bc8e887ac69602e7d81263315373029b2d6713705935a43177b9f9888115202ecb1a60e433d8de2bb42d235135224c7f795d342466b4c5bb8bc93931116479171800b717c033a304bc619d2a79a687e005d6215fb1e76ab67d8b46c72857a46d753674a7ef3962c90f2b62f51458204b71d95734533875819a495360ecc12b66005330593456c516ead7b3c942688a822bf0d92bf849bab6068480a0b0b4b8c3a451007dc2a733de7b51d835e5b7900ac836fbdf13a9ee82b34ccacdf6b8f4cd0594c80473040b633b7ceaa091259a21c5c881602c146e4444e1e48800a189239241813c13b724a02e6e7a70834493f794ae7991bbf1b60d4c0084c213471eb3598079adf95004942176f297ad3d55b5cfac5a3b385679ca6af26217ad8309547a0738328bc1a519712ba545ca739e8c253a65394817aa6874e432a95e5f35aa045cca1fc1c7bf467424a8d498274646c05c15b176c8a69f90a0a524b6e4b6053979499e7526ac66830d28b28ca2c6dc4061b1546a4e8d7348416c8a8fcbc0779c51ce855dfc54d94d74bee674bbc383adb248c07eb8889b0b44937356906a61b1074362754440856bb26b2fa906ebbb94ccc943fb39c00292843ed501f5f673762e3afbd7179e41835208700fef233793c0850c5b48499afed371e56e5a92a4109662247b72338db4769f9849f9516266acb133af5666b18131ed347454250cb04528c91b8334c2f5b3401cfb28e45824e73c1b6854b330c47c443d931b9e5b139f31b25d4458ac53a32025d49bb5d1a89b73bf930c74c233bba7afe30239a41587985726fa09d0a7a2ab19559ed380d9eec34b5fa83b73813a763beab0a1f7df5b87962709f255256a36800b94062d3af90990b2a43251ad9b0e400bbaa4a306520443ecc8cf45613a8fc1c61e6312cfa02d23c1547a69cfe43660d987a0210cf60965fca77c850503416c7c18a37bc10ca47f517abfcdc018ffb538f474404917dd65c8a680a667b1762b5958e43547fca1aa0da8907d7d3a25b430724477eb2844e54f35ae8f27598d568d413914bf66b70e37ddbfb7df01c08e1310932ba90ac2287187b022dc659c83b9f554871ae4aaeba7ac76f1254f174493d31eda27def0331de8e68f7b1568c4c8919e4de7a5005ce152fef9c8c88ec9e6fe12a1e2d742dcaf56c585651ed6edce4f410aca0fc83275b5acb19daeb149d248c0a21ea0bb6d6f56f12300e8584d8e9a34e0e6f52227281151ae4c305fb8f" +}, +{ + "dz" : "b87439fde81c9e39eebe7cf741c685785532c1dd23e8ef868b9ce7a541010f3d1646460817a0fce5836bdfe124a7448e7adf7b8ecc2652ac6d280e986682df71", + "pk" : "e1696955c4bc38dc838761a183d31e38bc21fd2b955d9002ac69ad96c03822fb4283c4216e93b96d86bbf81888b68b1e67741d4fc8af15d4642a7b65d7b408ec711055826bf634557c8a7ce4a32384592f3c5881aa530213c2435141505a8c0918186c1508ab11101b09397d82b31c85ab64f4bb38947726d2c717362858a0a3656487b0deaa38c8109e5fd061496a695581347d52aa7ed71c20d8a613bc54e8a49a92ebceab993b0fa81de448c156550aae181a537c38638c6320abaa08c50b7b54211dbc8124a487eff2b545ca3db8a07be7674b51a95efd08c4421cbf2aeb8cd92383851a044985aa9a062bf5267382db45519bbd747852ed1a590ca3a89602a6c65cc06c856e22484244fa15b928b13b91736b1680e18cb1f76a7209b76754076db872295ec76e246b1f58f80fe0610372938393288c85b2b2f2107fc39c7d805678e68a38e3e57c30ecb650dc15468674cc54aa8aaa424b5060a03bae4d74c8a43c951e6b53b2c8b1502459868a1b03a5c1395c1b10551c28a6756d251e1916c24ba33792d74eb88a5c84078f60c612beb4a7d94bca27e3377e53442284c395ecc235309d1281c53964bd34a067f225829e5cbfaed47da9e393895aa82a67ab5b44a92d8423bcb59265e73b84f549927427e9295acc8694d77020d0e4342d3c784b121250140db1c3bd38806351416c8f86b4abfc7a14911bc865baaf867f54e92f935b044b60bd5343c5fc9b2d1dc68735baa31ce155e37c1ed0c85162d2ae3492c44c29343b50351c64747f9765b6f9306bbb3e543334c987c9a1c2a5783a576ce94b8f10bc3539cd55f30b0cca01a5985eb5993d35b8cbb136bd769b13f0c5c2d40b34335a52bd34ab04f9cf3f6c313b6c5b9ef879c10c1e1b249cba2580f7da8bb06c003db8718f318979e358292b881f9ccf984c525b61a34f6681197a7834913230627b56388ea26cce0569680c968b31aaa97710c9b2cc019771a57f8b5739554e45048d59610ba990b2e1967648d3c87410aff7981a57e2bcce971b912c2bf633bb8ea55314f3327d3b4fcde33aa1e235e6eb603caa19ba83c98eea4196c78a80e8b5680227caf06ebb22042e9a5c63974650fbcb1531404c6862710215012671093911d67027d491a916539a1b84b3c966b89ed3b1e9980769267827731ece44826a3a0bfcf037d9fbb9bab4b85ad668fd1573c0e9b227fb5ad32c948037384145188b17620eb91cf6a6318f331cae3800164ccd138c8c75a3071a7c0166f5156d74171b5b854c0783f9905b88950c23ca8835e530c4037260500be9f00510b5357fd1b80b09aa06b7126ecc8bdb709e3e698761f756ad0624280778c0ca140c426f91c76f81b96cef425403c95bc00852359b638a8a75b3fcbea47990e002b346d5a9481083c4336d02191326f6ab5c5777f622cd4819bd1187cc6099cb7968474ed93c0b830bb301314551970b86a25da05dce97ab5db744c78536712c752d02206c8585285268c5842491f92636682b223b6bddd39c6070bfd74aae3f8ab1fbc357136028aa3542f006cfbe429001377d2112c5ae3805244b865ea863257aa671d0b146d04b89b233f70768a373043a59b9060b0943f56865e6a91bcdc54402574a0f1c143dd36948d781d2f3c44e2f08b52e339b6e1cb3", + "sk" : "7079b0361596d968aeaac085c8f649ef02a20b947efa34800067938ff753bc0aa132d1a51944634ba6308e64848b60cf01ac01a7a13c5ac5763f2a07da294d955b5044f2b46e2b6f51d501c3949e32a64bf7ab5b6435986a1719812bcdba766380a0601c807ddb1a0c532017c0540b56e82c63da8276e665d0c4418101af9e07092a48422c960f7a818cb266141ce16f76dba6973b5da07449a2b5cd3e20650d753c044787a6154257785aa738418254281298c272273ee880099772c5a8d0491eba4930280f75664d6156928967c2f855053b63aca1141b8fb3c8e7720c0bd8c17d18a2c3a73902d6711c5ac31110a4008d920ef9c6cf918d0b457cc2373229516f2f0a9c70b91fd640c2959a3d95634736910c840b173fc4565912a332914bc4c6251483691ed7aba7906693eb54f36794bb0777e5b45f32756ea6889d6fb75c84845d99a5458b024257a6210c657555ab7cdb802351e1016213636c3b37af4b57aea9cdc5a336fe2b987fa5994c991c5b59aeda80a5dc1639a5dbc994e330f710752af651b11a2be27c57413704c0685973c67f969098383b341747ad8849b0d86715a2a296f0321f2e9c72b69431d4253970f25d653ccc2bf72d617bb861ac66781576a6f7aa70953d6d3c40dd659a373a1d7be285ace7c2e7c754d42c780ac5a8e9f7beac93610b9c56c64b28703b63a1684a88d76576743b650178c79b209d28a616d79ad68092b5b0cab578c4af895aaa20455000a07a9cb4bd57c04dc5ad159488b70a289f229e87552bbb9aa1f24aab37099d0db07e9ce14f500773d7326103405f5a516e0240647f556001d6cf77924c2eb3c546a25aa10a80bbb20d09faaa6115020e988a85093f2e15447b536b6c610776403afab7037b795a7fc93eab9639f400a383454e10a591ac0ca3ab344ca0892a022532bd79ae558710451175134801106c615e47ac6b333b1ff430a1d2a0b8230afca93d65e83049f01d00ad5e795902b8ec7dc496268584cc90bb8c88148bc5082b74e48b1fc2116d9033bd342b53215aeeea5788447c0c50b567b88888841b9d8c9e9488ba2a4a23a3f913e00631ac784f13c858e5b49b920b428cd24cd1ecafe553acd95982af5b8b8b00bcb1074f6ae52ea7eb34cb4482d4679efc337eab910d78210b94f7b5ef150814c01459c0154d67493fa276dbab403950a609b23d1fd37f23e6c40be57c2b9bac82d9923ae3cae126be2c0c54eb88c9e0307402971543b58b67d21760590c818b4c71855fe90080696644e074bf2a45237f037565e800e071abd930abbe6b6e4fcb8774aac945898ee8b74911726e316568068a1c545ca5e75c02c2b2872d478605341ee5b8b914690d9b0938940540a595744cd8bae7483d39d1511344ae19bc99fe5b5180f22c032b6bbe67bd507c6a9a22c2e19a8ea2cbc5436a8b307a9e69d237076a0fa8d52df9852205c4592461c252542c95e2847651011e1233834508a8b7b3d09c833e8837150ba67405ba5d651075e39590d74ead502157253a703c2d460cc21ef173e197200aa85e497c9e6989996cf2c29320bec0b671133bce293268fa9b4ee48c31c9957dd2319385301c2ba97338c99e33d828119174e1696955c4bc38dc838761a183d31e38bc21fd2b955d9002ac69ad96c03822fb4283c4216e93b96d86bbf81888b68b1e67741d4fc8af15d4642a7b65d7b408ec711055826bf634557c8a7ce4a32384592f3c5881aa530213c2435141505a8c0918186c1508ab11101b09397d82b31c85ab64f4bb38947726d2c717362858a0a3656487b0deaa38c8109e5fd061496a695581347d52aa7ed71c20d8a613bc54e8a49a92ebceab993b0fa81de448c156550aae181a537c38638c6320abaa08c50b7b54211dbc8124a487eff2b545ca3db8a07be7674b51a95efd08c4421cbf2aeb8cd92383851a044985aa9a062bf5267382db45519bbd747852ed1a590ca3a89602a6c65cc06c856e22484244fa15b928b13b91736b1680e18cb1f76a7209b76754076db872295ec76e246b1f58f80fe0610372938393288c85b2b2f2107fc39c7d805678e68a38e3e57c30ecb650dc15468674cc54aa8aaa424b5060a03bae4d74c8a43c951e6b53b2c8b1502459868a1b03a5c1395c1b10551c28a6756d251e1916c24ba33792d74eb88a5c84078f60c612beb4a7d94bca27e3377e53442284c395ecc235309d1281c53964bd34a067f225829e5cbfaed47da9e393895aa82a67ab5b44a92d8423bcb59265e73b84f549927427e9295acc8694d77020d0e4342d3c784b121250140db1c3bd38806351416c8f86b4abfc7a14911bc865baaf867f54e92f935b044b60bd5343c5fc9b2d1dc68735baa31ce155e37c1ed0c85162d2ae3492c44c29343b50351c64747f9765b6f9306bbb3e543334c987c9a1c2a5783a576ce94b8f10bc3539cd55f30b0cca01a5985eb5993d35b8cbb136bd769b13f0c5c2d40b34335a52bd34ab04f9cf3f6c313b6c5b9ef879c10c1e1b249cba2580f7da8bb06c003db8718f318979e358292b881f9ccf984c525b61a34f6681197a7834913230627b56388ea26cce0569680c968b31aaa97710c9b2cc019771a57f8b5739554e45048d59610ba990b2e1967648d3c87410aff7981a57e2bcce971b912c2bf633bb8ea55314f3327d3b4fcde33aa1e235e6eb603caa19ba83c98eea4196c78a80e8b5680227caf06ebb22042e9a5c63974650fbcb1531404c6862710215012671093911d67027d491a916539a1b84b3c966b89ed3b1e9980769267827731ece44826a3a0bfcf037d9fbb9bab4b85ad668fd1573c0e9b227fb5ad32c948037384145188b17620eb91cf6a6318f331cae3800164ccd138c8c75a3071a7c0166f5156d74171b5b854c0783f9905b88950c23ca8835e530c4037260500be9f00510b5357fd1b80b09aa06b7126ecc8bdb709e3e698761f756ad0624280778c0ca140c426f91c76f81b96cef425403c95bc00852359b638a8a75b3fcbea47990e002b346d5a9481083c4336d02191326f6ab5c5777f622cd4819bd1187cc6099cb7968474ed93c0b830bb301314551970b86a25da05dce97ab5db744c78536712c752d02206c8585285268c5842491f92636682b223b6bddd39c6070bfd74aae3f8ab1fbc357136028aa3542f006cfbe429001377d2112c5ae3805244b865ea863257aa671d0b146d04b89b233f70768a373043a59b9060b0943f56865e6a91bcdc54402574a0f1c143dd36948d781d2f3c44e2f08b52e339b6e1cb330c784bb2ca3538979b24246c2644907484719c531ea39f13c5a34046f8e5cc31646460817a0fce5836bdfe124a7448e7adf7b8ecc2652ac6d280e986682df71" +}, +{ + "dz" : "056661b38038da4fdd7426f32a81576c73ed84843b305168a374f934e27a4e1b79238a80dcfd7c992d84b2dffa67493e669243d4fa38c46b090bdf86bc548411", + "pk" : "00264fbcf666abba49136b6e6ca0ac8636bb20d305bca62bdef6301aa51899d7341147b72c210afee6a3294a4ac8685b1b6003eafb7e94d91fd958b5c3944129198bf02a2e9491491a2bad9375cd9f184aab285e91c877884b101511775cb31f2a2a3e7337406d7662c8d8c83c1933f0e27b8b2b39b1aa8897440ea5142f22b218c77c664092996e39237f577139014da6da6870d848cf98b006c9633ff138323261e1d042ea645e60813c11f9489714c197607e568c8045f0244ff40fb86634dd469033456604f19255645898181cdb830c1a82c4eb1373ba820515b6a44596342ac8b912c217603cc92b8a2b52caa29972bc95ab334a93307d7b9aee013b22118eabb947b1a23150481fa1e7b9146b9ef5fabe9debc682003eed2534d9614d90466c80a73fab8b94d187a383463e7f6a380d1b34ae5473f58167e97794767a20bce5b6d5dca88b35695e0a2baee03abd55ba0fe768a8254d40836233fab358842675508302a337840167dee53eb3ccb531a7637dd1b9dac9a00432268002165f72a5aad8ccc7131ccdb1c986a7b29bd89311099fa3e9460553900e51560364bf9af461f1487cd9f0adeff5079b07240870c310ac4702e113f68433981242c153c49c43cd93493b52395b5db073ec936f3518b7f6954426b9757476cc1bd0c4ff870a2124a8f8daa3299ac21178235c260a018c169d083cf40842bb6a0f2d407861106b4e752091dacbb85677fabcbe180abdc6235d0e8c34737a5934f431afa670d000166f6c5e4516174a205f4bb6182bb24a54907be5360cb81b5333a937c4e40ff2579b0039c0ba3374664859e376a8515b390bb46acfb54bbd4aa6daab1dfdd44c712b311798c71e162f36f562017821cc96227cc431ffbc3634acc704937187b8200d9bcbb0c25df359c386e740195662ae24cbb24b181a23a2b4cb5e3a767701d3a80f7bb82133be97daa38a706c7e2949ce86587246bd5fabc774956019c2247f5748f0988087159d42b8c6b1aaa398879c77e32b0a5494926588dc537fe1f05a10741fd8814f191cbdc50cb2a0ba1ec053a789396208415c77c18d283510f410a722a187cfc552f63159648317ed696695413ec894ab80f4c106d73933e312996b23f073bdb9625727d8c0ff1818d9f78b91c4a6c33075f9a91b772138cbf6861937c53aca7b535baacd2bceec96223ba7747b4a7d50c36d3cb0297967cc447c3bffbbb723455e421ccfd791c48f8ba558692e2ce278dd351e28d35ec1039f16d8281bc0867d529ffa6544b1663a14b6843fd85feea2b00e3c8b2131bbaab0b2161493caab5464501ff6e30074a372dc6a905b9a1a66b637365b48af4b55e45ac4236781b71b130718941f06c17d84786bf1a033b60da7c6b0d4d385f3f323dbea84c0bb8fa720569d1959473b1af84459c0ec4ef133c0688323fe8503069bc15cbb391ba7041e665f652880ee367c97f34e7230009fc401d7a34b536529ef544233761bd2a01a9da338a215492252906f979290202e5c666bb31a74feb13b05cbbb341076674c02567c80531c5573fc6428b8ceddf3ae84b8bb7018a3ffb02906770c4528c73360a867c2701158927eb5a9fac60a2f401affc4c65198b4a5e1439001d5882496fa682185d21aa4ef95ac3eb5e675c7a4a4426f93", + "sk" : "06f99e63362cf6dccc11a8854b1407ff12142d91a19d0395f3923abff155cb4807aa932e218232dfe932aafa673150bc9e7155794565aaf7375f7195f0c1c35279a51d613c6bc32cde086f61725c28324e9e392d1d3a91b0661f1524592f6772d4e012402c18ea162a3cc36b8f565152dcabe80691ea3b84d9eab83dfc429036676d1109d9e258343b418f840a1c53b47211b55f490202c4659126bcc5f4ce23f2906630026cec8418526efcc02b0feb7728a53a3298232ad37a424b4f980827e24ca9cef26115a100bd224b4a304914c83629049f7e836b8aa539eff61a60fa8154ea97c31259b3c629dc891c027c8e5441b5f164759b13980ee0a5baa71deb08c99e6340419b0f6ec82ee2536231e2634f9307781097f8ba2a22db4412c5bcdf764f0b58bfe176163e1b5667ccc45b39c77b3673ed4c70786a33b5aaafb5d5c12d4077baa3223e2614a7e917c7462f220545fbe9275b1a62a882797e5a96cefbadb309995c9b26747ab33e543b36080c29a4bafe68ae41911aa763a8d90162a1959dfcb7890a394ed40a5340f0b8a89434baeb9414ba460178b2c5db503a28bc8f2a42caaca2fbd6c77d758f30e14bb1075ffdf535fffc76d02ac264787e45340b1dfbbbc4513ff15abd2337b6d4543492160575f44ba1c793c3054bfe767a827875322ca753e200c717c47db1ad47f12ad103c28e9380be2868c8b32f7102c26b977760e67d98109921425611b9878e215494910730956bdc7a015506c45f919071042e921607560560237bba0c3190c759295ad059b7c99ecb62222a54563ba730a7d3a4dde375c9f931cd16c4344552ff984fd6aa9ede0602a840bfcb705e078cc375437d3927455aab6ea3872499b0795df7bfd436cda3368bbbdb990d6ac9d3f637be663e7590055e00558d0177f7c63e7fa292097303d68a34f240a17c7c0b80c5a69004c195d915dcc880acc9cab1db842c14722ea534b865488c41824017cefbaa5c1127aec9e535112764e713ce403c64a6a27662a254836327d5924846dcb646b79de5ac0bdeab9223f36f5c124e595165753656b0110241f6b805b0b30b1b698190b5d4f1ce112c93b4f6a190106c7be120d2dab2995578fe9c08db3bb36c99c2c3f2001c6a269f563edd088f3b50a39d508a67c75889012cc090217b321e99e95f4f310f8db2cacbb853297601895a3430405f828827cf151a83480b4276cb73996fd5d7b357a52573912ade3394c48b7709d50cb8f2381cf50eb0e14bdf5740836138e539a7fa6a4a94339cde3bb71ec34ebae4bf4763ce93d6041f62bd61c81868f81e8b88124e667cc83c0b226157560647996a2581837b75eb59d5a934bde44cb1e664de41184ac480323ca59f624662b17bcbc20424c565385958c99246d2383a9e2000f9b817fc57b7f32513d96ccbb6140510e11e224702893bb891350404f376b0b04a674b2161bc3c68e8901348a9a9d7742aa3a210319dac25a7ea909f2e877728914cbc2332bed4876f5453aeb3365879a0a24244c6172a8d267cdf9c10787740a5852e66e3663a879a35208a07959b9c5997e57a779e8679563caf551a597697473776519f87b0d7e03c1a686d705c55d1b1ab00264fbcf666abba49136b6e6ca0ac8636bb20d305bca62bdef6301aa51899d7341147b72c210afee6a3294a4ac8685b1b6003eafb7e94d91fd958b5c3944129198bf02a2e9491491a2bad9375cd9f184aab285e91c877884b101511775cb31f2a2a3e7337406d7662c8d8c83c1933f0e27b8b2b39b1aa8897440ea5142f22b218c77c664092996e39237f577139014da6da6870d848cf98b006c9633ff138323261e1d042ea645e60813c11f9489714c197607e568c8045f0244ff40fb86634dd469033456604f19255645898181cdb830c1a82c4eb1373ba820515b6a44596342ac8b912c217603cc92b8a2b52caa29972bc95ab334a93307d7b9aee013b22118eabb947b1a23150481fa1e7b9146b9ef5fabe9debc682003eed2534d9614d90466c80a73fab8b94d187a383463e7f6a380d1b34ae5473f58167e97794767a20bce5b6d5dca88b35695e0a2baee03abd55ba0fe768a8254d40836233fab358842675508302a337840167dee53eb3ccb531a7637dd1b9dac9a00432268002165f72a5aad8ccc7131ccdb1c986a7b29bd89311099fa3e9460553900e51560364bf9af461f1487cd9f0adeff5079b07240870c310ac4702e113f68433981242c153c49c43cd93493b52395b5db073ec936f3518b7f6954426b9757476cc1bd0c4ff870a2124a8f8daa3299ac21178235c260a018c169d083cf40842bb6a0f2d407861106b4e752091dacbb85677fabcbe180abdc6235d0e8c34737a5934f431afa670d000166f6c5e4516174a205f4bb6182bb24a54907be5360cb81b5333a937c4e40ff2579b0039c0ba3374664859e376a8515b390bb46acfb54bbd4aa6daab1dfdd44c712b311798c71e162f36f562017821cc96227cc431ffbc3634acc704937187b8200d9bcbb0c25df359c386e740195662ae24cbb24b181a23a2b4cb5e3a767701d3a80f7bb82133be97daa38a706c7e2949ce86587246bd5fabc774956019c2247f5748f0988087159d42b8c6b1aaa398879c77e32b0a5494926588dc537fe1f05a10741fd8814f191cbdc50cb2a0ba1ec053a789396208415c77c18d283510f410a722a187cfc552f63159648317ed696695413ec894ab80f4c106d73933e312996b23f073bdb9625727d8c0ff1818d9f78b91c4a6c33075f9a91b772138cbf6861937c53aca7b535baacd2bceec96223ba7747b4a7d50c36d3cb0297967cc447c3bffbbb723455e421ccfd791c48f8ba558692e2ce278dd351e28d35ec1039f16d8281bc0867d529ffa6544b1663a14b6843fd85feea2b00e3c8b2131bbaab0b2161493caab5464501ff6e30074a372dc6a905b9a1a66b637365b48af4b55e45ac4236781b71b130718941f06c17d84786bf1a033b60da7c6b0d4d385f3f323dbea84c0bb8fa720569d1959473b1af84459c0ec4ef133c0688323fe8503069bc15cbb391ba7041e665f652880ee367c97f34e7230009fc401d7a34b536529ef544233761bd2a01a9da338a215492252906f979290202e5c666bb31a74feb13b05cbbb341076674c02567c80531c5573fc6428b8ceddf3ae84b8bb7018a3ffb02906770c4528c73360a867c2701158927eb5a9fac60a2f401affc4c65198b4a5e1439001d5882496fa682185d21aa4ef95ac3eb5e675c7a4a4426f93b30fe432c2e9744430805aef6b75cf3011ff387e323558212b9d71ed71f044f779238a80dcfd7c992d84b2dffa67493e669243d4fa38c46b090bdf86bc548411" +}, +{ + "dz" : "a1b52d871612a1c611ae0944f9e71858f35d3bd14f20e96a931720668bdf0a6b1f135cf64b6403e103afae34da038613e2853bbfc36baafa3c6a95347193f37c", + "pk" : "869719ce20c5abaccd8889286f2a77b388a58ebb7c53e79619762ae5111b6f352192288128a83202005adcf0b15c0640f2b84d2ed58ee806bd4fa22ad26c5c8eb9a035768951a579f8facd48428e508abecd418617fa5901fbbdacb6b539c148af327823009e86fa49b96c42d8ec5accecc423fc979c475fc9c63696c21d206301e9d54ad1088be167af34c57facc25d4bb49ba5677842e27c1fa666b0659c66dc412de949980ca6a707a0c21976822579a0fb1d697892fc87251354a17f630271cb3b10f5c578777a990361b467c1374897675748f763619e065104a31999a765815ca7a22103f3631879b790a862450c69af8d29c0f9a48e8dda82f2c03c0e12b62484c4ee35002848b030e41dcf1084b1f70d405677a059774e322c7b72265e32810e761d82956cc0194257f31157928b786b6fb6011a130620d2f51678d27de0965465d445e6777660865df9e73bc6858fa8155bf5cb4bf9c23527340c32211009144fe456950694b656a2a30c55647d17cfa1856981867aeb82af63f1525c31cf643b32ea822b2f389ad4255838a2bc2ff850cbbca834c87f9fba1c05ba251acaad9ad99075920653d29d94c399cc4a2e4c7a871e176a275b7ac0a4401d36b35113595d51b92ccb8618f3ca40b4900774a784644973477dd492c66d09ba9b074c3d0347dafa08dbe43a9b890f62a5b9caa996f9e362b9a2103942cb91915ce8e390af54a2578227a9389e922b9c382907853ba05eb13e7f03c079301db2135d95c934da5784cb05b9726a1c1e28b01f5c5edba7a340053ea51c32d0930653f46170025204c0adf94c2075631c55790895495f23ea104a60b88c8b627db4256b6892d1b7886f959a18ac238aea494e45aaefd72056f362e7f34ec5e20e9c9aaf2efa8683970e310390a620264ec1ac3af515c24409ef4a4b99d0725de1506c706303e2848e2904f8c4824260162e5392b5b0595d699357b190e237ce1e3692ed95b7710488ad285c04db243eea475520605cb98b98a1cc893a7f1d7492f038795da03f63a91ec925a914b3c1fd9a3b5a74bea6b6770a5b1400348f7002555ba8c9c95b88cd829eb179472245228c21afa2d39238c76cde000898b718884ac8108c06e81c02f264bb6c9c5c13081c09d431aae78a26d62fbd041f32fbc012d0c83fb9450448cfcdd8cf881036ac096396e311e923478c5a346cf5c930d01c84b04400b38759a18d3ba40e46c8af5f133258f353aaacbfa68b0bfe206bf7fa65b192a4798a0faa68b2574725dfb69ff108b7c155cf77426ef8a776f0455bcea85ffb91a74f7203bdc2a9d0096fe7ab57ebb4cf1dea1ca0c5c4f9e264d2d5a0fb64658bb3b1ccc93ea5814407b6c865bc2b2fa14311ca50016b782716841bf89474c10e182aa51c0416580769312419d1219261a548ef0aad81159e4be73bda9c8903b7a4955456a3a8b405a27c18968901d54f8a0ca16e41aa1d0c128edc33b069a1c1e4b22438beb74a996c8b30c1717f07092c46402b1d9b710c46540ab32f38381c95b7445704461c0589cb427606057c78f911fc72ba38d1b664767df30901b148b1d609601bec3e40e41136ea9edac60f1f097c49906f105c99c4b069d5325baf3e6882dfda254850ba1ae5ca738086b4bb3c91df05c11c1acb67a98d", + "sk" : "93b888d05aa46698878f187be0da6290127b2cacca5fe508c40a523aa56b923b5325fb7bfe0b3cbff11fefb8c9acf6b1add2a41d265be89baa96989afe97a5a749484d27b8761b6e9cbb2a957676743cc79b22a74bf92ac693bb54a31c4f269e5d00c470630f7c491a708b40bc7160415576db195fe78b3c33140882723387d4af2d120b0fd015b41b5984a8c217e818300831f1556c5489139f216a4ffa5799246e9151790b98c2b907b8cd917f8d981e7dbb760a725a30e34d997774c657cd4d2648e974510511583f15c5f0100872b91d0c1c89c307ab4dc31cde68c364a20712559a7c7c58d6cc0c8feb1645d85436a8188d7c171da14451685591380bc0a5417870645e4c633a2a430f23941c80c92694b8cea6674e97a032c89516397d42e44855b4ab29f484d4e33097754d0fcc672f452be0b3a2b752c2e2a87275aa89e65ca0efd096ec158f591557c7fb1b6e696ef2ba704006b7f6e811f2385dba947fb10c404b79b90e620a842a569dca77f1039b62403787cb36bdc8984c352c48635b552361c77b82eb67abe8ea1db025302a98b9b075a5569243a8725493f07cd025494b5c01cce508d594cd36f473b8416a9e7a8de0a99879c109161ab3adb78d01e1b2ba2809b7266575086cbb2622a4e708733bcaf322420a65873c624dbf1c20a07821a0ec02611a36f4501485a6399a91b888ac547c50120e5070e597a9a6a67f06a2039cd6ccf7246adc0576a3f4457cb9a4c4b46ccd846a77f416961072cfe64a32920851ab1a20555122942b7c3cad5b137f6885b39d66cfc4f5c7c6e63d2d45c8e184467ee336945aaca71442b1508bd9687f40a4b70db764bbf90510526ef1842151c56da153a100fc92efca3539ac6efac23fcd60665263cf435ab34336b08d2023eb147eaa00c5271459b026638b9c18d2d04e3b429ba38053dffa2b1930a7453146e798323dc5c5fda63ab285810dd734b9988691c8445098a2ed96cf2324067fc45d12f118b2726104404c2174097147cc6363c684215a12b4b34b161231331c56fab25f0418f5e55fcd8bc258349524004a7534b99051113efcb310d61556788e187c1f410b6563530d8aa4bd07690234d504b4a9795d8141d56049d8e1c019932d46219124596a64e20658f010724547e8aa25d55c042a8a58de53b10c9c26740812ce6952f765bfe6153e1b43582f5b7af3ab3881ec42b4f80163f89648c622ab625da6b730f47244d2391e32c2bb19da532c726f30772cd90b64f481cad12c86c6166bc6f38fb0f92975b9aa31b8acdbd5bf5e746891a7087849497feb4fa63c28a4836784ac8a6e631055260ebc0b33c5140fd3ecb5d82156f16aab8349411d1192fe578e3d359e22705439317b7df77d08d38e7abc8b146307bda7a7e00b8e0d51836b1ccd35611835755a72a6bcc069165164a1181920af68434bd639fe0764fe07d0b6871ccc617b5958c26763113c9062be342dc5e44fab720a30a44a10aa0458379c9d8719606a564df808e63581820606ba242ae664c4fef748ad311ac4156f597c39f17c93f88a74418b734e0caf607c4f9d72877c925c0f25410f551c2b3860fc26cae2f3a319815a239bc4fd627ded7181869719ce20c5abaccd8889286f2a77b388a58ebb7c53e79619762ae5111b6f352192288128a83202005adcf0b15c0640f2b84d2ed58ee806bd4fa22ad26c5c8eb9a035768951a579f8facd48428e508abecd418617fa5901fbbdacb6b539c148af327823009e86fa49b96c42d8ec5accecc423fc979c475fc9c63696c21d206301e9d54ad1088be167af34c57facc25d4bb49ba5677842e27c1fa666b0659c66dc412de949980ca6a707a0c21976822579a0fb1d697892fc87251354a17f630271cb3b10f5c578777a990361b467c1374897675748f763619e065104a31999a765815ca7a22103f3631879b790a862450c69af8d29c0f9a48e8dda82f2c03c0e12b62484c4ee35002848b030e41dcf1084b1f70d405677a059774e322c7b72265e32810e761d82956cc0194257f31157928b786b6fb6011a130620d2f51678d27de0965465d445e6777660865df9e73bc6858fa8155bf5cb4bf9c23527340c32211009144fe456950694b656a2a30c55647d17cfa1856981867aeb82af63f1525c31cf643b32ea822b2f389ad4255838a2bc2ff850cbbca834c87f9fba1c05ba251acaad9ad99075920653d29d94c399cc4a2e4c7a871e176a275b7ac0a4401d36b35113595d51b92ccb8618f3ca40b4900774a784644973477dd492c66d09ba9b074c3d0347dafa08dbe43a9b890f62a5b9caa996f9e362b9a2103942cb91915ce8e390af54a2578227a9389e922b9c382907853ba05eb13e7f03c079301db2135d95c934da5784cb05b9726a1c1e28b01f5c5edba7a340053ea51c32d0930653f46170025204c0adf94c2075631c55790895495f23ea104a60b88c8b627db4256b6892d1b7886f959a18ac238aea494e45aaefd72056f362e7f34ec5e20e9c9aaf2efa8683970e310390a620264ec1ac3af515c24409ef4a4b99d0725de1506c706303e2848e2904f8c4824260162e5392b5b0595d699357b190e237ce1e3692ed95b7710488ad285c04db243eea475520605cb98b98a1cc893a7f1d7492f038795da03f63a91ec925a914b3c1fd9a3b5a74bea6b6770a5b1400348f7002555ba8c9c95b88cd829eb179472245228c21afa2d39238c76cde000898b718884ac8108c06e81c02f264bb6c9c5c13081c09d431aae78a26d62fbd041f32fbc012d0c83fb9450448cfcdd8cf881036ac096396e311e923478c5a346cf5c930d01c84b04400b38759a18d3ba40e46c8af5f133258f353aaacbfa68b0bfe206bf7fa65b192a4798a0faa68b2574725dfb69ff108b7c155cf77426ef8a776f0455bcea85ffb91a74f7203bdc2a9d0096fe7ab57ebb4cf1dea1ca0c5c4f9e264d2d5a0fb64658bb3b1ccc93ea5814407b6c865bc2b2fa14311ca50016b782716841bf89474c10e182aa51c0416580769312419d1219261a548ef0aad81159e4be73bda9c8903b7a4955456a3a8b405a27c18968901d54f8a0ca16e41aa1d0c128edc33b069a1c1e4b22438beb74a996c8b30c1717f07092c46402b1d9b710c46540ab32f38381c95b7445704461c0589cb427606057c78f911fc72ba38d1b664767df30901b148b1d609601bec3e40e41136ea9edac60f1f097c49906f105c99c4b069d5325baf3e6882dfda254850ba1ae5ca738086b4bb3c91df05c11c1acb67a98dab02b962b6350a9e1314baaa272b6b13db3d1edc9f09d3addf07f6826a3556bf1f135cf64b6403e103afae34da038613e2853bbfc36baafa3c6a95347193f37c" +}, +{ + "dz" : "952b49c803d6d6fba69f4375adce8594847a00bcae2179da49af2aed0423250262d7033947ae42ca53522a65fbafe18d3bc3e0cb66164e9a094fe4b44d8977ed", + "pk" : "fe04b19e38680e8b5f005167b4ccbd4bc2a87c3a98d2b2af18738b8b44b1ff480ad69183c828bd372a4a3ce12ce72867a886733f3bade4144ab55b63be2902aef88ab4e129551540e8390357631233eccf23a0668886b39942c23f902265a84a08b07d11b85c096512c09ac3c82023f23aaf48578bca4b50426713c7e5270980c78c6643ef615c2b6ab57b98111a321e30d8a38b5a376f9a2c793ba196e293fde201ba7261e222080d951b4f249a47da98c2aa4b87e165de574efda9577dc815c847ad269210970975d8322645246cfcfb46a194a9b3cb2b91a20fd9107948d8777d0a14d6187c922a5beed80600991f3040643480286a580e932032a37b8c82833535f721edf44e97397e14931cf7f49201d80b75d650f204bd37416c643ba725d2b3b4f368b033589e01cdc10ccfe264a6efe01ecd3b8e92478bfd7c1abba973459346798007990a9edf57b081c73d699b7a758a6013106597ab803870c24e4c2e0d649dea9bc0e0fbc742571b7b6bcca714881db2597c3a45cf0794022b58985a61d582aa59b17e9c567e4b4268976943982705f389566f53c49526ab6c210f4e694544d307d2c8612d1ccc23658127e8b071e58136734082616ed011397bb781896953c73b5127b28437f38c27d663b05745d3fa37e9c2a07dba767f0859e7a30e9d48cce5f37632e817060ca46633c9b4f6735c3bcbb9185abf39ba9ad600718c6fb84b7c7b867b5e5c51c0b0cdb03cc83b49568a4a02ad831fc93157a4e5010ba81c0b6bb34afb908a77b2e8d106f752c39ac1a00a9467d58484bd273733947a619439576a98b4360811c97e73431901978d295148bb991433ac72b4cc3e5cac2a8f68ac9d9a3f5d53889343af7e6b02316831b7208939a88e613c0ec5d07861099488b08deaeb2cd295b6977c7c9b2630cdaa5b0a93ab7d98728b3ccec979b869d506b9c679ecb673b7d83df908aa58603275a36291ca60fb717b74406ec852b802eacf4ec3c2533315240624b5b7a8ec960ebeb04d970cb815fb059c458d02254fe8564f154a8c240086fd98ab6a4a4510fab5205a99ab873f3ec29b603a660061b8eb803b6e71740ef174db09bd6c3447197765a0907d31fb1635435601b0a8337972263857f301ae5cf56a23dccfa392020bc84e79aa6a37450389a616f6e626e001592f7a71fd00ad82f3ac9d1979e83955bcd1248e7c9f5245a22bd26479caca02f70303b8c978187f102bb949b7a709e94fc2069489601c2752222da41090578edfc1083e0a8bc9110b0e64623e320f0bc56c4f2b2bef38452ac7c2e17c5a72166a48d55ce5d3abca1a98d6eacf734249e8820e29721931faaebc3abc1a7453b5b01b52a27284995df4f07a3827bd9567cc31b2bb08825046226e059b52bf8b0f864793926b461574b73198b6b4a128f19607bf1205380127e6597ea4b099eba13b38fa376177cf8d090881a20164d804320469b15988759025f5089d7b98675d554ce4714c124c1c30775cff79229b1b99e4206cbf28bab4017077d4721c263542ea1742ac45cc500d327a3da9c46309ba09742305b25390c50abae20b6e8c8b3ae0208aade68d9e2004bd0c26d21c8096cb97a1a2ab02548ab8f1be5fdea37e49857c092ebd421eabeaf7d76beea2feb7cff7d2376a329549", + "sk" : "7db7cb1612bd434144e3e8c45dbcbd0983a000da3ad94150800c6ba82929366027b9f3213cb2aea2e094ed979a179b95629b885a77b3006d6735f6ade15589f06397ee572a11c9a23e206168d10736e0a073b28240518febc2a88135b290231c78e5afe50a21bba9256280861ef75f0e97336f1b735ac69b0f652bb6d3b46d6520964671a8309df2a2997b36a4430c7f1af27443b869dab0973793a39014614f96b4b0f554737b77481c0d16288183b71dc9794f713098edf87bc947a96f542e2a6c11670401dd475e3214be00c0054c687fd3774263bc9fd3cbb85050a02d53c1cea22c6da3585f743d14984c64046217555f45d9aa7b4944d14cbd3dd69bb520c150453bcf91387a1ca4bf4353b15a9792ea89def5cd09a6658ed57af3cb2d2b1464af2bc28e016379569d7c352ce2d2c350f8c494807a8d239c2b0654bcf2cb866bb35da6289f5505f0059e4351a44810920cc6ac87c224be4902f2f002936c4dc13554ff7588c13a1ab7a12b23c273e7fa5e94b152beccc94e0a74d3580414c60dd2e4806a056235152acbd21e7042a3c3429436a52bdfe45be4247a0d24cbaa1821543bb6d860889933897b85397c94764dc2b1aa94555ff42412377bc6902fdef97295569c8cf1585ad8ab64c124af41a534ea4b2e5b6d76e33dcc5cadd7e376dec13652115e9733c1aec91dc9446fae1702a7420b45f32c719473033925d7996915f40fd1f13d11807811f1c991b0137524acef597686b61c146526564ca162935307cb6fe15606dc660a550c848ea8171c392f5a916738db2d90534a4332c303601d14b98cf5e7cda3009bf50809d194000b10b63c7c718d8299497228932758629b5529610bf56c7a33464b206888228a257eb8a8c149b8a0846df20c84722ca98a458c09ca598d752f8273326f27600c179f1a8cb1e8f14072dbc9866058a0f448a1556531e010582b4672cb9ff873865eac6096f9a4fa0225f4855ff15c7a31968ea1447caba5c295f70d5c7990057751dd91365c4c57b601cf45547153b2258a897bfa5b3d23c00d0be449ce5172fc513141caa315b397d6d77eaa67c6570a60a3b16f90f1087da1196b363ca47b830b4902c23c97b1ac33d464b5293959f1a007e51374b3f016f7bcce7417695dc015ad84b37e07aabbb0630c467206d2471509968f88914fe6bbba9742878632ee6655418535b4e45b5595c90b4ba088541e51a32f4cb920879268f56861dc40bc9f661e8f611288faa6f0c911bdf631de2bc9d53369f2b116a26ab2bff14981fb817a9b4d8ab928fa19a3e1b03f4b89cd459a64521300f5e5ae6ed8125f2544bb039a4f09483a799ebabb8839c4111f45a013276ff79a3ae9e5001ce451a0aaa5e84b185f8747ba35c58a253618a8593d155adfd05a5f755dbee456ffc3883ff715bb42ae09531fd6d88ecbb21d3138223326b8e9362e5382be38e7035701c2f0d72c678b47a79a891487bb3c9c7d6b823231da391b2b3c6751bb66b7a7e326526f3221a3a936ff82a09c07cf33763b3072b93a2426f2508b2b734e184b6f00488f378373209552a4701c43a746e207342e463c4e11bd5ab1b5f2e2b8691057d6162dd66a1bc97ccfac8537fe04b19e38680e8b5f005167b4ccbd4bc2a87c3a98d2b2af18738b8b44b1ff480ad69183c828bd372a4a3ce12ce72867a886733f3bade4144ab55b63be2902aef88ab4e129551540e8390357631233eccf23a0668886b39942c23f902265a84a08b07d11b85c096512c09ac3c82023f23aaf48578bca4b50426713c7e5270980c78c6643ef615c2b6ab57b98111a321e30d8a38b5a376f9a2c793ba196e293fde201ba7261e222080d951b4f249a47da98c2aa4b87e165de574efda9577dc815c847ad269210970975d8322645246cfcfb46a194a9b3cb2b91a20fd9107948d8777d0a14d6187c922a5beed80600991f3040643480286a580e932032a37b8c82833535f721edf44e97397e14931cf7f49201d80b75d650f204bd37416c643ba725d2b3b4f368b033589e01cdc10ccfe264a6efe01ecd3b8e92478bfd7c1abba973459346798007990a9edf57b081c73d699b7a758a6013106597ab803870c24e4c2e0d649dea9bc0e0fbc742571b7b6bcca714881db2597c3a45cf0794022b58985a61d582aa59b17e9c567e4b4268976943982705f389566f53c49526ab6c210f4e694544d307d2c8612d1ccc23658127e8b071e58136734082616ed011397bb781896953c73b5127b28437f38c27d663b05745d3fa37e9c2a07dba767f0859e7a30e9d48cce5f37632e817060ca46633c9b4f6735c3bcbb9185abf39ba9ad600718c6fb84b7c7b867b5e5c51c0b0cdb03cc83b49568a4a02ad831fc93157a4e5010ba81c0b6bb34afb908a77b2e8d106f752c39ac1a00a9467d58484bd273733947a619439576a98b4360811c97e73431901978d295148bb991433ac72b4cc3e5cac2a8f68ac9d9a3f5d53889343af7e6b02316831b7208939a88e613c0ec5d07861099488b08deaeb2cd295b6977c7c9b2630cdaa5b0a93ab7d98728b3ccec979b869d506b9c679ecb673b7d83df908aa58603275a36291ca60fb717b74406ec852b802eacf4ec3c2533315240624b5b7a8ec960ebeb04d970cb815fb059c458d02254fe8564f154a8c240086fd98ab6a4a4510fab5205a99ab873f3ec29b603a660061b8eb803b6e71740ef174db09bd6c3447197765a0907d31fb1635435601b0a8337972263857f301ae5cf56a23dccfa392020bc84e79aa6a37450389a616f6e626e001592f7a71fd00ad82f3ac9d1979e83955bcd1248e7c9f5245a22bd26479caca02f70303b8c978187f102bb949b7a709e94fc2069489601c2752222da41090578edfc1083e0a8bc9110b0e64623e320f0bc56c4f2b2bef38452ac7c2e17c5a72166a48d55ce5d3abca1a98d6eacf734249e8820e29721931faaebc3abc1a7453b5b01b52a27284995df4f07a3827bd9567cc31b2bb08825046226e059b52bf8b0f864793926b461574b73198b6b4a128f19607bf1205380127e6597ea4b099eba13b38fa376177cf8d090881a20164d804320469b15988759025f5089d7b98675d554ce4714c124c1c30775cff79229b1b99e4206cbf28bab4017077d4721c263542ea1742ac45cc500d327a3da9c46309ba09742305b25390c50abae20b6e8c8b3ae0208aade68d9e2004bd0c26d21c8096cb97a1a2ab02548ab8f1be5fdea37e49857c092ebd421eabeaf7d76beea2feb7cff7d2376a329549c153354b0187e658306a0c860b1fe6ed14686ca77d37b7c82d66ff62149406b762d7033947ae42ca53522a65fbafe18d3bc3e0cb66164e9a094fe4b44d8977ed" +}, +{ + "dz" : "3c815e57e9233e975fa1630208aab206b71ae0db37a7a8789ac683d9f9b2d29801c8e376fdb140ee343106c093af7cb149b316ba79446ceb4e5e0cedb9b164f9", + "pk" : "57c8b4dd8ab3b7e3203f2358221c9cc0f2a671ac1846e59b3d5c95576806b571c64746bd4bd541d4c55128b9a7d5208960a2b74a900a426013f6b48fe7fa1adcba5ec1e44594d3850c1a90e2a6bb341210039b48224b97efc62583f5882c71505a96284cc7cbe9873215697ba688546d3a6f97729b22251f479ab3f92cb08fcc3a9d962a661c6150ec6dfdc7560986bf808b4504ea2d44d595a8c34f4a564147cb798fdb6836cb448ca857d5d08242e233e3826797a4191e53cee0b375d395cefad91a395527ed094daff389a198c9d3b28b9e42b002fab4aef17b3089885e8017c047c35152a0e2709cccd7bf4d4a081d3160ebbc3d7a3ba977e221fea55e01823f2f61bfbeb9388d04103fa0c3330770c5ea5a882b26d14c4266b27722f29863b60c9f6984a5f0c2ee8b6f27385933994d8f9973728c5be6898012e4766d842cd1d7b360e415286c965b0b5277a5a1c5f731dd085df0f9579a31b5920227f238c389a723f8c31ea1c45afcfb6a62e555b0b2b766e78889dbc7a8a174fec48e328b4411338b26074002261e3c19c575b42f5a09a268b223aea813706900e785c3a05a98a5708d083c5e6243872ad78f3b456173267d61d57b2f330d01f7be8cac65b1ca46d8492f39c83338d92f3ea9a3cc7b502b115d5a7700e5885f264c384aa36ff52ba08ffa3eee17531915baabb5c9c04033aa091c36a0c5e99aaf0fa446a945a6fa281750bcbcf8e6666c799a43780b4024b97a6a0b14d9722856838d00890b9a982eba53f8254072f07ec00748a61ca18b0b516076382a9a52eb19ad329bbb81534da023cb03e00cb65046615c2d41e24d6e8ca6da872d46a1181133662735c6e382a615707e3d8aa89d49801f7908262c9ba7f1a49cd3c1ce9a5344f5b3df38bf82121cc9d4284da0c662d8b74ca9470051524ad108a2756bad834a1b1b2f5c01b29d640ad11c70643c0553721504ca90edd32cb4c693fd451564a1ca80f447378423888b3a2d30022997281aaccb939b0bf2f5643b036596983768758ac6b97da4843e9d8183633a65e35cc669592ba3a73e0213489ff186cbc66b8fc49fd2916322b30a6f2cc89e42715a8722c672c246822938b32ca6c47f05c21f9da66fb457206e7b58dda0a7f28b93ce24cd182b068cb951c5b29cfe1c30eb226a81bc06629133fa0a590de985e680550dc370108a7519a0b9da5b06170bc8a647c408477333e63972a7452cac811ef60cce2b8af8cc43b848cdddd7168b01ab9d138270604671d0ce57d94481eb1361d9a7f1c5906a11cb80f6454a2c358ad27086a5214dba5c5f69b003d9856831a8c13b9c28c7087efb8cd7247853b1a9c50b70d5e086a4e48ec77c8c6f4a83a11421ba4b0871692477a6b38f68c004f4beb011a137813ac02ccfe7b73271262fff16227da310aff06a8d23938444436da66d7ec6144ab44edd1322b27179901c3c1703279fc86163f804136a13cc925e47901514da5f7c68a23b23347d2b78ecb07ab4d81420662633b8a07d686aea3bb8edb04da7d2616efb147049c45e2a0deb0c85260862d4d25b47932b54487d6396c7f94193e40483c928460eb6b9b4349e1e4c0bd180111a72246c4bc20377a7059faffaeb0f304a1a64398249b1e8626fd1aa24ae11f67a7f23fdcaeb349484", + "sk" : "4284a3f8fb141bdc3c3eb0abe19b14e1c87cd6b667aaa115c1e4004a122459887fd63b38bac7421b0c3f4b19cb8aa591e6bb8d54039156627b305638e718c92682c05b56a9005338623a54d1fa92fd8b6630d4c1e0e50cabbbc3d054ba0f03443bc87273602234441ccdbb601d30263f260c567a096fc18fd719bb7e4c6d7113a7e4398d30f793afc45f484865aea22ba9119346374438a29c3b068223a4474f8a3c6fd4ac8c009226a346bcb72d61273ae1f65ac87060cfb129d7172bc452a3e8809f6763b0641cb9e1611699cc158c5043b8d4c995cbc438f549a4454bb147cb0ae27b726c1cbc906f4920b91ddc8531fb2ac06274519096c23975404253c6bbc00a816e5a0a20d86aba4380cfab92c5dd125156b7642e8552582114beb7b38a8b1050a42a2123470bb736b68011b809549c4550459b21ac656a301c0ef8723503b29b0d2370b2f4728cfb7ee17a1952a2354216155bb9072bf307f294bdc5760724dc75ccc315ec9bbf60e78cf11c27943289a0519d75b8aabeb895866c061fd02682e5c210a552e8278f8f296f7397a8da315a83d523bed7b99137078f1010d73c3b53321f0e5b0ebb44252404811ca113f7475f7a9b3cb9229e2e2b13b4f8abf5fa62aed176fba02361f24b9fb88d82147b2a299cf084cbb6c812fb2a1bd9b89a2c56a766350123355d3bda9774527fe9eb9af2c31b25a66b5dea238f27281516bac6e02ec69c8e5c9a9a9a180bbfb7a189b66043bc379cdb58f7c1ceec0a3ea4e931e854047c95565bf3bdc15098fee54b992aac09109197e82bdd28ae36b2c60e259788b53e8eea988d93bfae472499181176627e3d823af9e23870f771fad75b9938647ff39788a24b6c4a4ffb82399138387c9037b851ce74dc41182323ae935a0798126048c32aac4d7c7390691427ca53ca52eb65fe85ac44983f80fa7923419abdf8b14c834611d5908d742e373a7dba8ba8e3d35efd6c8fdc1c12e0f7c272a350fbd275d2eb1e0d836a4254c672251c06dc560f7a7ec7c80b8fa59475479f32a258294957d5d979a83cb6fc3c1ce6819f84e45c1e311b0e873f250283ec486323219a97373f5278a52aea7b88d1c7a43974e0402e58a55e6fc91b08381078f0285f898f4282ac8e5950d09343c7827df67a74ba1275e070c15ef44ffeb681c42b35c2c1b9c9d82cf07705fdec10e5f244759699ba6c5a2ca59b76e5ad5b09187a7bc3049389a94b2e25fc295310b30a9b3fb22ab3d9f893d9d696579648a77bcaa6b4213b23c65d4c303bc50aa0493c76c9387d186f85b0cea44488f0917612244c844450a81acb15e25aee3213e5bb647fd46b974bb45cfa21d6e1cc3af7799b32caacca0c80bc61a3f3991d367515276190e061b2ca956655514090b0667673e898a13e9c8573077641aca677c81eaf09cfe2dc78d0484af1557adfc9b32809aa5c6038020166b891920bc577f0064ed0b3112b727f800b22e9ec89bc691c883133a2b43a61c539701062e8512b9d1227e8eaab2985705418a8de6029832c2bc7eac2d5c0ab4aeb9e92324b83424b2a12c04b58681748aafc566d919862db6a516934ad61abbb17024665ba258f7299d7786ba6960a04f79b57c8b4dd8ab3b7e3203f2358221c9cc0f2a671ac1846e59b3d5c95576806b571c64746bd4bd541d4c55128b9a7d5208960a2b74a900a426013f6b48fe7fa1adcba5ec1e44594d3850c1a90e2a6bb341210039b48224b97efc62583f5882c71505a96284cc7cbe9873215697ba688546d3a6f97729b22251f479ab3f92cb08fcc3a9d962a661c6150ec6dfdc7560986bf808b4504ea2d44d595a8c34f4a564147cb798fdb6836cb448ca857d5d08242e233e3826797a4191e53cee0b375d395cefad91a395527ed094daff389a198c9d3b28b9e42b002fab4aef17b3089885e8017c047c35152a0e2709cccd7bf4d4a081d3160ebbc3d7a3ba977e221fea55e01823f2f61bfbeb9388d04103fa0c3330770c5ea5a882b26d14c4266b27722f29863b60c9f6984a5f0c2ee8b6f27385933994d8f9973728c5be6898012e4766d842cd1d7b360e415286c965b0b5277a5a1c5f731dd085df0f9579a31b5920227f238c389a723f8c31ea1c45afcfb6a62e555b0b2b766e78889dbc7a8a174fec48e328b4411338b26074002261e3c19c575b42f5a09a268b223aea813706900e785c3a05a98a5708d083c5e6243872ad78f3b456173267d61d57b2f330d01f7be8cac65b1ca46d8492f39c83338d92f3ea9a3cc7b502b115d5a7700e5885f264c384aa36ff52ba08ffa3eee17531915baabb5c9c04033aa091c36a0c5e99aaf0fa446a945a6fa281750bcbcf8e6666c799a43780b4024b97a6a0b14d9722856838d00890b9a982eba53f8254072f07ec00748a61ca18b0b516076382a9a52eb19ad329bbb81534da023cb03e00cb65046615c2d41e24d6e8ca6da872d46a1181133662735c6e382a615707e3d8aa89d49801f7908262c9ba7f1a49cd3c1ce9a5344f5b3df38bf82121cc9d4284da0c662d8b74ca9470051524ad108a2756bad834a1b1b2f5c01b29d640ad11c70643c0553721504ca90edd32cb4c693fd451564a1ca80f447378423888b3a2d30022997281aaccb939b0bf2f5643b036596983768758ac6b97da4843e9d8183633a65e35cc669592ba3a73e0213489ff186cbc66b8fc49fd2916322b30a6f2cc89e42715a8722c672c246822938b32ca6c47f05c21f9da66fb457206e7b58dda0a7f28b93ce24cd182b068cb951c5b29cfe1c30eb226a81bc06629133fa0a590de985e680550dc370108a7519a0b9da5b06170bc8a647c408477333e63972a7452cac811ef60cce2b8af8cc43b848cdddd7168b01ab9d138270604671d0ce57d94481eb1361d9a7f1c5906a11cb80f6454a2c358ad27086a5214dba5c5f69b003d9856831a8c13b9c28c7087efb8cd7247853b1a9c50b70d5e086a4e48ec77c8c6f4a83a11421ba4b0871692477a6b38f68c004f4beb011a137813ac02ccfe7b73271262fff16227da310aff06a8d23938444436da66d7ec6144ab44edd1322b27179901c3c1703279fc86163f804136a13cc925e47901514da5f7c68a23b23347d2b78ecb07ab4d81420662633b8a07d686aea3bb8edb04da7d2616efb147049c45e2a0deb0c85260862d4d25b47932b54487d6396c7f94193e40483c928460eb6b9b4349e1e4c0bd180111a72246c4bc20377a7059faffaeb0f304a1a64398249b1e8626fd1aa24ae11f67a7f23fdcaeb3494842ab47ca9355ece6cc643c3274c46efbd6e927b8b4d11ae8f80b5345b487a5c7101c8e376fdb140ee343106c093af7cb149b316ba79446ceb4e5e0cedb9b164f9" +}, +{ + "dz" : "588760826dcfbd36d9abe6ae44a669bb3ebba6a218eab69e30f18a3bd536576e0e860576285483bb5fd36e2f944d32c4317bebc1e441470c1372046a790d79d4", + "pk" : "f784b4d0a3b69a60403f5b9c4aa3808d7b832ab9939b2a5cd15bb36ba710f13c934f0b5dc5f125b4c4604d330608c0c608f14795f690d21ab54bb9a0ed443601f821b3c153dda33f6b102193a2343bbac83b938e521676ea2a20bad2b515c13bdba9c7efa9b8b460a8cfd6a54841bb306819b2ba7adc5b93951653c6d116c86c302e067b358631259012f1d230b892c393652fe9d778e755bb1d8bcb840c51eb93371c2cb377da1f0a33c13aa4aec4c9b79f492ebe34906b6777aba1470787bce5ecc92f494377555685e32b6d52afd230464469adda074d5a159a54e3493a3364d7443d81449006f0b88669b8f507493dfb67b1f012037438437982c868362c172556989272c8b338b8a56ac0af290c3be991c5b552b77a370c026b1c7b4044499036dff32c06bb4b1b73b66d2644d0709f59050fbdc62b36e7977a7278fdb26798d264241914391c71ae928d5c7c7800fca963f4a5ecd9ad5b1590bc941909e142be1c382d7a38b123cc23aa02c9273b5f377d97637091db6455447574bb0f26a250c63a6aedf6ce4ef9cc1c86424b226b06da65158114fdf2bca1c457f68248fea0ba9576bdfc380e45781bef85bfc87ace9f6b5c6f5805bc3403b9e9a86503396b109d2ca2916e16bc4c7a9c47270b77db678a724bb9e461e2f3adcad69ab78a60cbc52134a7557afa452eb758d4c357af310247f2b61db9c2edbb126d7284f38829861870bb494fc65b8b16d97cc5c9150d4c4318ec698cc5704f8011b19037232b1e337911565382450a4afdb8c8e07a7b4127a7d6d630c74098b528aa9cea5249a6a424536a6003787b7723027bc8dfd07b9519337d5125b8bb631502701ae2bb9c352a3407cb3903a617303a5c29cdce23c4ed747eb56bae79084ad705041ad27cc7441dd8d51ac4f5be1c594019143f41c56cf9b1773ee0cf9f116036aa65896420f82406c1b36009e12433e60993b691bf9295ba6621bec9060c82bd3d8c75d2014cb774a3eb8c8c7e698069437155da058aa4a6831c6cd0b47fb425c4f85c5481282107d4b5c61756dd3235ba61a95608404c11546a28c0191c5bf8473135a98c582608bf7c4a1387bcd92b449f888c6b9990a59725ea9c896fc58288c5905bd8ad06a80ac952106d42b298377a0da30db7f68df4119edf5b45d472c3b11c85ca1439d2ea0f074899c3155a51f26af1f52265553e2136ae3a69b529767549f146ecc6592a4448918a892af6a895a27a64480546db66c42b8a9dd029fcb2bfc14189974531c37405812295e0e85c2c44620bbac2b5376463a0490f628ba67c7bb7257bca690ce4fbae57b717423abe164a43ece7b30fc768779c5a82d3265b7a0d012383b1d8a6967a33969a5d368bbf5ca6137959093c9b321539236278043112c8ec819e1d9b532f5c7ad7506ab9c31cf2f4b95f978cf642b67b2995c8f56c272775023a438845ca46a6858b32201ca14f1bc19761452a0a6a2b6ae4bde620cd8685a89bd02f64eb51d7bb5d29e71f009a79bd060273ebc51a48bfb575afebb57215aa0fdbdc0d0ad91120d3799c8843d50068363b5c47b09572623d7ad8071ea1424799c1eaa7165343af0e808afcb39f5cc8a7f5e14bd573052725185dbcc71968200bd272d97f676c08e4a6053f4e0a7071d7abe99607e757", + "sk" : "72a953d60437f6c7a3855582b211c7d6d97df18c8c53a787117758a3246ddaf89668d5c71e999418e9515a9c95926688bebc25e0f003496bc0804a66ff68ce3fd1820c5320ed9992a92b8227d5042c72c1c1839d74b790ddd371d477b29230a66526a81a0962a52b5b501075f50086f041924e6889f5f6a6a7c15826a70e3c7268b4f224dec35a73da9db8500def40ada4d7b210513acc63c753cab007981bfb876171ea867197ac97716bcb830462e59167616528e840cdd703ab4516b1e307fd5703da82bdecb0047ec49355a60ce27598d739cf9a493c9c388613b05cdb302aa7d82c0c934b95d602fbc810133a7d5c15639f52ca0bb93b06392cd8223e31a3af2aa19cf5406f5953705c3a1e649346ba530b2e34618f520382569d8755563802ca6a76164da8227d904d2e86cf653123c725c0d0b6c799a35a5c517237d405c8d945119a1c573a4b00ac224cc19115c301b8a73cd9fa72fe8366d596a3eb781aab80895704b8f298571eb3a10fd7b6bcf590bdc4461b6c1522dcbaee713bfbeace03b4ce5a8c3d0bb6a3d7e410d0e5640be91e43a134412313cb170a1ec771c73b91af1c5a20a2b097f2be408155d0e3905f1b043f8b888954384adb7916154f0683619ddcc74086a6981a18f9a51d38e44dd4b7690b37a0694c434f9869140a5f4764c968598462d7289146044118022651c6ff259aaf878c584524eb4abb65424c0d3649a76c3b2a9168ffd4c44c074d94632d615bb6a8e2a318c6144c949c27f2a7b9f914cf97025677ae31329f5fe484909689873c2987f6bfea1b4f04fb2aa7880c8e4065ced03eb5fc49df2bbd38a3aa2295c541c47faca59145eb864623baad417975fb4b5b2b3f7629505393bf590b7b21579e3f7477be32b2b7a2819ff856395a700353b6eee92dadd46703ca3be7b033770744b6216a6aa06ff38ca6f3c21bca7ac726e7a665b45c46e4b5e0ea5cef6728f1bb25a2503645b063be0244a4bb9bbf1562ee76c7c859984c878c2f299e2bb0438e11578301a39c3288d5a4657c88901789438d35a29d0446af5782d5263cbf13c831b32c4d052f55746f6d555bffb74ea5d71b136b732f0041bdea87c3a81c4af28db20c3b7d92bd355b340d234fd7a78d0b7057e44c509fd139f7bc84d3a6161295c0438509014c875b2b6b9da55e222183cc0ab15c8c1751725ff90c5a75608b96c5c18a43a315fa5d5411c5717660b5200fa01459f02171647394caccb11426c7f535545931550c6a7b7acb725525ae17ec946c062ad845105072be4ea32b12b67aa73cceef80c8f9d534ec9650131a138745010f96804c8267691824c336c41e2a9169b1ad7de971f59329e3b6548267c1ae1642c649b8ca704e7dba94d6a343ce998611745307501c2c90c5ee9795e2ec58bc825f81979bf9821c4a0b00ba2415e6ba54c36778959540e2b9797f925adc7cb54ab54f5a58c3210cb677aa8be0d6cd8d354666b70f30e7718fc107a9c3289c0407886678c4da7acec224bb85be78c23443c24be09072e03a8ce92aa8323303c09266801a6444fb6267853df12bb0e4d54e9af982168c7941e785d1fb9701db1e46da1359c53f6c9370e7700e7dbc3e120b4ef784b4d0a3b69a60403f5b9c4aa3808d7b832ab9939b2a5cd15bb36ba710f13c934f0b5dc5f125b4c4604d330608c0c608f14795f690d21ab54bb9a0ed443601f821b3c153dda33f6b102193a2343bbac83b938e521676ea2a20bad2b515c13bdba9c7efa9b8b460a8cfd6a54841bb306819b2ba7adc5b93951653c6d116c86c302e067b358631259012f1d230b892c393652fe9d778e755bb1d8bcb840c51eb93371c2cb377da1f0a33c13aa4aec4c9b79f492ebe34906b6777aba1470787bce5ecc92f494377555685e32b6d52afd230464469adda074d5a159a54e3493a3364d7443d81449006f0b88669b8f507493dfb67b1f012037438437982c868362c172556989272c8b338b8a56ac0af290c3be991c5b552b77a370c026b1c7b4044499036dff32c06bb4b1b73b66d2644d0709f59050fbdc62b36e7977a7278fdb26798d264241914391c71ae928d5c7c7800fca963f4a5ecd9ad5b1590bc941909e142be1c382d7a38b123cc23aa02c9273b5f377d97637091db6455447574bb0f26a250c63a6aedf6ce4ef9cc1c86424b226b06da65158114fdf2bca1c457f68248fea0ba9576bdfc380e45781bef85bfc87ace9f6b5c6f5805bc3403b9e9a86503396b109d2ca2916e16bc4c7a9c47270b77db678a724bb9e461e2f3adcad69ab78a60cbc52134a7557afa452eb758d4c357af310247f2b61db9c2edbb126d7284f38829861870bb494fc65b8b16d97cc5c9150d4c4318ec698cc5704f8011b19037232b1e337911565382450a4afdb8c8e07a7b4127a7d6d630c74098b528aa9cea5249a6a424536a6003787b7723027bc8dfd07b9519337d5125b8bb631502701ae2bb9c352a3407cb3903a617303a5c29cdce23c4ed747eb56bae79084ad705041ad27cc7441dd8d51ac4f5be1c594019143f41c56cf9b1773ee0cf9f116036aa65896420f82406c1b36009e12433e60993b691bf9295ba6621bec9060c82bd3d8c75d2014cb774a3eb8c8c7e698069437155da058aa4a6831c6cd0b47fb425c4f85c5481282107d4b5c61756dd3235ba61a95608404c11546a28c0191c5bf8473135a98c582608bf7c4a1387bcd92b449f888c6b9990a59725ea9c896fc58288c5905bd8ad06a80ac952106d42b298377a0da30db7f68df4119edf5b45d472c3b11c85ca1439d2ea0f074899c3155a51f26af1f52265553e2136ae3a69b529767549f146ecc6592a4448918a892af6a895a27a64480546db66c42b8a9dd029fcb2bfc14189974531c37405812295e0e85c2c44620bbac2b5376463a0490f628ba67c7bb7257bca690ce4fbae57b717423abe164a43ece7b30fc768779c5a82d3265b7a0d012383b1d8a6967a33969a5d368bbf5ca6137959093c9b321539236278043112c8ec819e1d9b532f5c7ad7506ab9c31cf2f4b95f978cf642b67b2995c8f56c272775023a438845ca46a6858b32201ca14f1bc19761452a0a6a2b6ae4bde620cd8685a89bd02f64eb51d7bb5d29e71f009a79bd060273ebc51a48bfb575afebb57215aa0fdbdc0d0ad91120d3799c8843d50068363b5c47b09572623d7ad8071ea1424799c1eaa7165343af0e808afcb39f5cc8a7f5e14bd573052725185dbcc71968200bd272d97f676c08e4a6053f4e0a7071d7abe99607e7573ab27768ce397a94bb7d29f5dad97d54054915eb66be41023e5d7052a10ed1e60e860576285483bb5fd36e2f944d32c4317bebc1e441470c1372046a790d79d4" +}, +{ + "dz" : "47550e9edacb6ddce3d9ab81f6b61080dd4f2693854acb05e0ccc7a4fb6390fbf89d7d99d5c3e0d10d6ef9af054d842375f695abb28e3b8eb495100f04306e92", + "pk" : "8645bfe5dca2202ca92a9b07a6b33b49872ff21b1cd901020e4ac369fca24c00593be105483a24076cafff8220780c9bcc9150b3a65571fb426ec47a82974bb2a6ba13a13551d737e1ca2cfb50103e14269263caa5b15b16066ca63b867a250318fb7335babe4fd81a2ef56ce7b5beb88c65c2bc6c5a75149898a3d8a552cbfa6af1a463a19a071cb64280da48f3684d99e0b4adc7b48d039358f201a7baa1ffa4ae95fbb0d45776bf76523cd504a379377b740d26069e933748710a63781a23765a6659eb4718dac557a8553fd5be04230166782860a3012290b068542dab126a9f921aba2b61afd6958052baa7b24ac50cbf1f613abf761d3315692c49184cf3995cea8f161c86768714afd1185161b6da86c73a6b228b953dde1713108029d7a729811b85aa906f67978239c6b6f9f4a72656b9536b23691b27b3b2316176357c07b671eb562c41621c7552265914c500a21299b17dd258e2a04352b506138187611c19e7d8860741b110c57372a3be2be7a3b5a6c688390f06a5cdbaeb6dece153ce5181c8080e4f879fc063a68739032481c2cea4611291362165a63ef3c0f436230409c8e5e57c01651471694bb67729919920c6852bd78766a5f5c1b5db45c84ac14c764549b54d8b2404523b0c00052c5d3538cbc00bfd96b8034206714a645d447dc83844ee82c069f63b59587f53c3cb0047cfe63b4f6ef41513ac5194b91eab2a5ef4d7bc55e1762e9162f2fa009a9c437d2c93308ca411e8ad7f9c2a642636d5e89f93f5bdedeb78062032db389bb6fc77be489506a98022e83c9aa9b7bf65c561e1a8a95871e4ab1875535981466286175eed087e61ea034c9488fe953106aacb251c7fa044bafe474c2eb602cdb091687558c02778f4b562692349f9b132fb3a921f75a4ee6c33440ab76fa420bfb339e2f8c225bb85538cc4388522f9628aade183c1532baa778faf937035639a5367cc64c4c036fc25a61b4f85470402e85ebb245a43c92f2cfb0ca69879a0fccbff31a35f2b46c986c66386308fac63978534e5eccd137561a6b110d82a2328a90636b55b8d67337626115448ca7eda95a6d2740e33c6cba56a9f34a95a7bc8f304702e25315f81182e54b2656913939083c052664a9844535301fcb730dfc9c5571ba72f279a0412b98cf64c069b89acda010494498f92838e32c711f1712d8b34303b3d594681305b20d2f8ad43fb6598113415460a0326bbca4c1d658a1462aca2a619abcc5a61a99921ca82882e1569c3902769e208c61124e741630fea09ec58065b889890a667d25bad039c4846a77d17acb5e726b5717b00e0b3918fc767205028cc4b67cb29b49196b4dc288a3abcb112bba52f0cae6ef09cfbd74d939b73ee610f0afa6d8b345d3ee95749cb4373ca3f52f69ecd767893135e7dc4ba6d069c053b79fea0c69b5c1258609046c761c77322a9d4626de19df5543165958a447432d5237f399bb1b9a8923ca45521b21cc4b17d36e724f5a09772a7b8609c9c86140b03e8a10c54adc91204c686049a643db89b0c375a359c943d5961a803c6ad28512839f42326f53b22dc20455c843ad64753498e10145af06270a81213046196d2192d0ae3924f4dbffa093a9eb51025b31d268a74f44b849a4c408426071fe5e18c3ec8b5c4", + "sk" : "32f2c581d0b288cb18c0512172098f6e200cf9e1aba837175da86a45d4b6bd985728f5bf966b284eb96e059a8b4a99c0406046d117640ca029ff7864516cc6d49ba33b640c313569944b07a10b3820c49ddf965187d6794f491734531700571c788243cdf2c620b676657bc6cd9743242b6688d22baaa432f9015f69a179c01652d6f1c3721b4a35841bcf620552e4100beb54f494586c73cc5727c7dc023976d20bcc248bf6da8b6e36878f51177ce3326e9989c95c5219c017f59806defc68f466213c131811ca618df02df0ea6fa759b095e259243c897a132aced9661c3c04584bbc4bb218ccc118a91072cb32691432540f73403af7c09e520537592965483f25394e51a57f2403cc6ac6471ca8633a3c00a049669a3061f82770b7a7cbe4638a8c98b686c499940a004e9c3a7e9c1d41a5081943579620003f738e2d9489d5b24967b6be64d3984e4c2b69394f99f7062caa8f9be60c6fc6c801e77fc2d9b2286674df0c20414832d4193a024b26448bc33c30405c134d78948c34fbbf5a442636b87bfd3051bed47f86b2083a4198c8b224d1f8c0b0f5769ed72a18027fe4a85d9ebaa57cd20f696193645c9b1e6251b695061a711eb95270f541a730842f56d24981881b5bb071bd15af02e8641d1a3d0c093d680a7b4283c4d9751ed3c9b5b86c001da05bf5970f42b86071aa81e4d534be3b4c92b2b14821a54d9817212cc1364525bfe9cbf9978429c7c1b3a3615aec75d4651ec85469f3442ae17b929bf8aabdf0539c2b783c30875f29b68ca5ab28579f3d7722126598801368ea9648017a77c7608e1e54c5ed0bc0ec48b1af037b23665c1e675de79312637482a9655a5e72c155581b79bc9b8125c5f32248274128a993a6543172a6570c4ffa6e5968239174c6ca9a72a8a793c5fc61362c424b525fe2c23f94aa4d4bd610f1a55e330a6a9b6056aa7605b6623f8962a996e806de090adb40cb34cb8d2c024b00940bbdd025be366d12bb0b78c6b88f4a28f01731dbc7c1026a2c68da6a5bbbbd1e6a898f36a19610abb9cb6f04b3881d85bf9300142ec300ffe20b1f33763b816d6dbac076373a21501495eaab2ff3b3d0044d03658590a4c73f5486dd055745511bb4d176c5b7cc66fb0fa500b5cf14700640b2679c80da38762af61a4442687af30d5fdc2308c9af02753aa8a93b294b6e541490af4c7cfbf60415d9be34f6b7f73c4b6bb4842b5c608cf90fd8c1beba947fd9fba4eb0513e8d35c8995473ac200051c6063a3022fd6a8db9c0377f62639982556f8676464c86d856e6a599d031c35a294014a5b30b4aa5bfe779c14b50d4f6a3bec6318d6312f028b6bbb237f203b4737a9cfddf252f9b90964c01cb736a832cc337e078c6b66b9733c4f8401b8181926f2c73bfeea63cf3b843e017f60e35e062219b2e76c9c830aa187bc8a863b58a8aedc9a9e443c93520b109709089f4b40c8f7966df7af854b4718b91d3061a6aa153d7d336deeac9ccf0072d6540970741167281eab315fa2857915144f73f9b508542492706e1d285ca9c58eea9c3118ebc21c8374c6374cfe7c846e9815007b602ae23e43f68b82811498d2bf5a357c62275609022877e48a8645bfe5dca2202ca92a9b07a6b33b49872ff21b1cd901020e4ac369fca24c00593be105483a24076cafff8220780c9bcc9150b3a65571fb426ec47a82974bb2a6ba13a13551d737e1ca2cfb50103e14269263caa5b15b16066ca63b867a250318fb7335babe4fd81a2ef56ce7b5beb88c65c2bc6c5a75149898a3d8a552cbfa6af1a463a19a071cb64280da48f3684d99e0b4adc7b48d039358f201a7baa1ffa4ae95fbb0d45776bf76523cd504a379377b740d26069e933748710a63781a23765a6659eb4718dac557a8553fd5be04230166782860a3012290b068542dab126a9f921aba2b61afd6958052baa7b24ac50cbf1f613abf761d3315692c49184cf3995cea8f161c86768714afd1185161b6da86c73a6b228b953dde1713108029d7a729811b85aa906f67978239c6b6f9f4a72656b9536b23691b27b3b2316176357c07b671eb562c41621c7552265914c500a21299b17dd258e2a04352b506138187611c19e7d8860741b110c57372a3be2be7a3b5a6c688390f06a5cdbaeb6dece153ce5181c8080e4f879fc063a68739032481c2cea4611291362165a63ef3c0f436230409c8e5e57c01651471694bb67729919920c6852bd78766a5f5c1b5db45c84ac14c764549b54d8b2404523b0c00052c5d3538cbc00bfd96b8034206714a645d447dc83844ee82c069f63b59587f53c3cb0047cfe63b4f6ef41513ac5194b91eab2a5ef4d7bc55e1762e9162f2fa009a9c437d2c93308ca411e8ad7f9c2a642636d5e89f93f5bdedeb78062032db389bb6fc77be489506a98022e83c9aa9b7bf65c561e1a8a95871e4ab1875535981466286175eed087e61ea034c9488fe953106aacb251c7fa044bafe474c2eb602cdb091687558c02778f4b562692349f9b132fb3a921f75a4ee6c33440ab76fa420bfb339e2f8c225bb85538cc4388522f9628aade183c1532baa778faf937035639a5367cc64c4c036fc25a61b4f85470402e85ebb245a43c92f2cfb0ca69879a0fccbff31a35f2b46c986c66386308fac63978534e5eccd137561a6b110d82a2328a90636b55b8d67337626115448ca7eda95a6d2740e33c6cba56a9f34a95a7bc8f304702e25315f81182e54b2656913939083c052664a9844535301fcb730dfc9c5571ba72f279a0412b98cf64c069b89acda010494498f92838e32c711f1712d8b34303b3d594681305b20d2f8ad43fb6598113415460a0326bbca4c1d658a1462aca2a619abcc5a61a99921ca82882e1569c3902769e208c61124e741630fea09ec58065b889890a667d25bad039c4846a77d17acb5e726b5717b00e0b3918fc767205028cc4b67cb29b49196b4dc288a3abcb112bba52f0cae6ef09cfbd74d939b73ee610f0afa6d8b345d3ee95749cb4373ca3f52f69ecd767893135e7dc4ba6d069c053b79fea0c69b5c1258609046c761c77322a9d4626de19df5543165958a447432d5237f399bb1b9a8923ca45521b21cc4b17d36e724f5a09772a7b8609c9c86140b03e8a10c54adc91204c686049a643db89b0c375a359c943d5961a803c6ad28512839f42326f53b22dc20455c843ad64753498e10145af06270a81213046196d2192d0ae3924f4dbffa093a9eb51025b31d268a74f44b849a4c408426071fe5e18c3ec8b5c44c20aa5a85b2e43c56e051698c75bfc27bb9b1722501a6502d1c0dac0aa7f1b0f89d7d99d5c3e0d10d6ef9af054d842375f695abb28e3b8eb495100f04306e92" +}, +{ + "dz" : "610afb64be8cc1df288cfb016ee2f44c6c07113de7f6fee071fe0c3fe31c6215cd292e4c5f9e1a55e0489bceffb204d672a6215f4f3980a646d9f880817c52dd", + "pk" : "38724d9a8308ac6b70d1c87bfeb07775d56703980c9a563040d1ba17297b1f253afc339ddc11a42cbb051ba2722854cbf45bb80cecaa81ab63ce32acfe953f9ac8648b95be8668822060bafbc10b59e72944185a57f790351a20de6679328169b954465f8cc028558328f3baeca98e42404299719d205cb17c745a7784b97c09130e26376778a9330c99ed84288ec3955df4076d0c9f5847af05bc58352c1364f34b0213a3cd05b2d79108af038e457a30bb5626b1dc404605678ac675201c537a8a6ad67a8e3e0b17a0e8632ca1714dd341831b2790591c1f39c530288dc8448527fa542d64192e407f2304747ca7cad98986c59622b2e63e076420916635a538871aba5469f36a5536356d176265191fc150a4dc7349f07c932c053ef4b6bd245448ba8173ca0896e51092e06537d2157b0c1624d3a29eb0d055d48a038c858e53c1045c392d6f59408df2bb19b35a87737ef90b9fdcc380af6a1ea122838c673e39f502a08908ac33276b4297c712b3c7541c7806c71dc76e9291c89cfac3a56c9c94852ec4a47bf6642349b95f69c43005fbc927113288caa2cdd6175b2a627149027e3688b436c336b51c8539cec3c5537de5ca6955543f984c73005181e916317262bd638e249cc928e048a20045907b79c441cfebf0b9106c8847b8088b4c41fe6b7356d7947ae9a9549305c9278e6e3a39060854b88b65cf9a20266218864c94377a475c0822d454ad8fb42c50a13f1be65dce1728388a8d4a81b372a1486a86b0e6d1abd445559dd3b827b834e2ab3744c0c5abc51bcb7551cc888de7f590ef780d7cc94225830732f47b6ab4777261944cbb3e6d943eab827da40a7b00d8960db1810d028529449dde0c00eacbaa321c14249b7113ba43968b79070b9117dbab36b44f05022bf25a9ec77c7a396415c7f24ce5e364b09a16308472e1d49ce92a41d3b868e4664e93279467745b9e04c39bd67cf0226d198110e6235a3a35af970a73a3472027e1c7368c867d23cbc1895790f2478f807b756516acc4c7dae3a350f26a0353930f4c23c3d982fb90176bc70e0e6b739fb67aada24d10f2ac30685c2d7606fd6bce5df369a0d176fe32b0e0e8cbf583b0e2019167640fa63c23d7223259441152b0c79d9b2012725b6eac08ba8438cb90309123abe5980b6ce6889d6b7d1c756aa7a90181a1422f5a6f803b1e772891a61ca657175f7b815cb3549d3ee613deb001c7ba200730b2771b5743d80ee48683d94015ac7221671a3a711468f8b3be5ecbc1af824dfbbacf87972874e847b399280eb649304a3687f43dfd769e13a4964892b5e635c0a2216273331da5c5b18ec0b406ab1163d4179af5aac5fc8273296e2433c8fd993f9340c5d365070cb72715188b52cc0426146c54a3687f6a57f36b0b1dd639c505bef4c71fadc68d62009bc6b27b3817660df31faad06e86b91aad252b80461200168290848f963010511763f8614f202a3a05680831b8bde86a18dd79248d46c144730bc7b4757ac95f34ba2cf0436bda09cf5a9285e7c924f3b514695300c33cc6d92c280ff81e72b549694aa7aedb46afd394a2d5826e657897fc53285905406430c2b7786e64ba44225985f95146947535aae744a3b3707467701a8bbd99b938f2fc7737f22bcb9f146983a07f", + "sk" : "f8108802536a5e0b192cd8a761c1163c02bf2c457bf4162799884650185cd6e7a978c74516e85541b212b90321a0014615a973226b927046cc24e709e988562964213a874ed5007d8c483336d80b2338313606c716a25d7fc8617a506899187ed9a73d835997de71904ff82fc4c59b12275677b90fb6c079ca872866483ebe326e33f369006b4341bccc759b6565816c8bfb3d00e11bfd7b2de14b9bdf163bba82852ee76037795df78b9a2182c883652e17621055397c6b7848b3a8365467669ecb1ab81a8747fa449f22aad5db231873bc4c40a45ea265fe45c9f8f43dcde1ab1573bf0716139549490acc91affc45aa816809d53879678d90132ff321b2c2f32892ea9e4a112258f8236623a701a453fcba1d26c3aeb37c50b72625887b5cd9eac2cae774783abebdaba500eb9445739eee33114852a841447fa19cc360e31c95012227aa11e35412c2b5716d7602cd07a5b48b35dfea154e6780f8573203d367bc9627f414879251738e3b8cb2e3c09956c798144fd6c9249b214cf25ab84ab0c7d0b03728b7847c485663470c41d59b76fc48f959199305d05117cea0e04c0c2c056ae740fd21c0cad76e70f55ed7a62bfd440a2b5601242837cc6205196971a5993dee6b51f399ae1ba47334985ca1e26245897ce954a7f393105e75cfa25302f17b45e04059803bae94251d9f51530012ba052cc8948463e48367dccc5842354e7fd7596122b56b6604fec0c58db228a2170cd64a2be9757d8be35c1a0975cc1267d789c774883de06bbd6572129b57a5e185195cf06bd70352574c68a4b71d2ef5580b57166c3746ec058302ba3da6f916f1ba4b572a82e289593dd57277c0c570c22d1cdab6aae39b16a68f5684a5e367c713e649ae802776f6c3488b494cbab596f73b1908ceb7c05c46304f4e26a54b388b61aa3c663a316314405049c67accb2a7ab62140915a09488627b3c3683c3aa198400fb6a53396f978b71189b7c4fb1ca005a79727c5e6d129af7220705222617807460948b33197ea35a091ce9ab5a2b9437f961b70c432b360be118a4b589c66af374f58668e7515b029a14a272ae4af399552796a4ea3a8d37c265b42e38c2c586792d6be661c9c4753d373004da166f69368f976bf1016550013388b562b43a00f801b2a77212237b5cf53c647714218b94343c0b06d3fcbe446514289a3bbab9a3678284ae46242d1b56bb0845b30817c669cbdda709576b91072aa38ae0a6cfe444c09239d189cac861667cd6449c0ba8a773c7106c6b8bb40b100b39a562823d33a180da2bec923d1e707d59d7a8e397c68029b93428bca352495966a79c299e531b9b59b437e86398b72157fa43391299770b7ab37c71b387401b5ed5ce81b88a26a7a9dc023635c932c26199b5c437536ab194074d1cb24f65285af6b03f6a9a7174a380ad03c6826ba5fb32c6e93c2fe011a0146717e8265b31659a806975bd589f7630461bd1b6c51a0a2cb6ad3f825c919533c24c807a9c6e3c780d0e333105b43044d7931920621874395f794483820afb55483e34abf3f0440f3253fc702e71e34270d38e4875cb9a6090dbbc53352128c18a948ee821e49bc9c690563a92728b610a38724d9a8308ac6b70d1c87bfeb07775d56703980c9a563040d1ba17297b1f253afc339ddc11a42cbb051ba2722854cbf45bb80cecaa81ab63ce32acfe953f9ac8648b95be8668822060bafbc10b59e72944185a57f790351a20de6679328169b954465f8cc028558328f3baeca98e42404299719d205cb17c745a7784b97c09130e26376778a9330c99ed84288ec3955df4076d0c9f5847af05bc58352c1364f34b0213a3cd05b2d79108af038e457a30bb5626b1dc404605678ac675201c537a8a6ad67a8e3e0b17a0e8632ca1714dd341831b2790591c1f39c530288dc8448527fa542d64192e407f2304747ca7cad98986c59622b2e63e076420916635a538871aba5469f36a5536356d176265191fc150a4dc7349f07c932c053ef4b6bd245448ba8173ca0896e51092e06537d2157b0c1624d3a29eb0d055d48a038c858e53c1045c392d6f59408df2bb19b35a87737ef90b9fdcc380af6a1ea122838c673e39f502a08908ac33276b4297c712b3c7541c7806c71dc76e9291c89cfac3a56c9c94852ec4a47bf6642349b95f69c43005fbc927113288caa2cdd6175b2a627149027e3688b436c336b51c8539cec3c5537de5ca6955543f984c73005181e916317262bd638e249cc928e048a20045907b79c441cfebf0b9106c8847b8088b4c41fe6b7356d7947ae9a9549305c9278e6e3a39060854b88b65cf9a20266218864c94377a475c0822d454ad8fb42c50a13f1be65dce1728388a8d4a81b372a1486a86b0e6d1abd445559dd3b827b834e2ab3744c0c5abc51bcb7551cc888de7f590ef780d7cc94225830732f47b6ab4777261944cbb3e6d943eab827da40a7b00d8960db1810d028529449dde0c00eacbaa321c14249b7113ba43968b79070b9117dbab36b44f05022bf25a9ec77c7a396415c7f24ce5e364b09a16308472e1d49ce92a41d3b868e4664e93279467745b9e04c39bd67cf0226d198110e6235a3a35af970a73a3472027e1c7368c867d23cbc1895790f2478f807b756516acc4c7dae3a350f26a0353930f4c23c3d982fb90176bc70e0e6b739fb67aada24d10f2ac30685c2d7606fd6bce5df369a0d176fe32b0e0e8cbf583b0e2019167640fa63c23d7223259441152b0c79d9b2012725b6eac08ba8438cb90309123abe5980b6ce6889d6b7d1c756aa7a90181a1422f5a6f803b1e772891a61ca657175f7b815cb3549d3ee613deb001c7ba200730b2771b5743d80ee48683d94015ac7221671a3a711468f8b3be5ecbc1af824dfbbacf87972874e847b399280eb649304a3687f43dfd769e13a4964892b5e635c0a2216273331da5c5b18ec0b406ab1163d4179af5aac5fc8273296e2433c8fd993f9340c5d365070cb72715188b52cc0426146c54a3687f6a57f36b0b1dd639c505bef4c71fadc68d62009bc6b27b3817660df31faad06e86b91aad252b80461200168290848f963010511763f8614f202a3a05680831b8bde86a18dd79248d46c144730bc7b4757ac95f34ba2cf0436bda09cf5a9285e7c924f3b514695300c33cc6d92c280ff81e72b549694aa7aedb46afd394a2d5826e657897fc53285905406430c2b7786e64ba44225985f95146947535aae744a3b3707467701a8bbd99b938f2fc7737f22bcb9f146983a07f72c30933b8e50425fefbf58d711f58cbf9fd8ebd2835a1b55469a2a1b993eacecd292e4c5f9e1a55e0489bceffb204d672a6215f4f3980a646d9f880817c52dd" +}, +{ + "dz" : "e1953800acaa85ac02a906c72cb8e8d704e8d27820345f88f71e89c1f549afcc8c64c049c6dfc0f1476cffd520b055756162f7ec94243de6b14ac0b9e5fb366c", + "pk" : "be19be36c8ccda4c9852a442d4259905628087c232f28871b05512dcd2b769179ad09a9313252dca243d73b387b279a1ca1151fda2781ab7757d2ca5c64052c8440bdd93acb5152203987bd5a693453957504242b3f8667d3c800e9a969372a13fd014715a0bff3a24c8f31a69c329a1c30ef37ca29903ce0943982413b0ba694ed53cb416f125151c8f036709aa2174ec365a56d608a2b54ec71183e2b4258e71adc09c81fe05065be2bd972979eef093cda03bbb82b6ee4180731c18fa997195d4917476427d7c07d99b663c4b50a9cbccb3c364df354685273b8b42b9e118a427c765b08036350a330be79b3ef4171b953faee56f719483717854b29aa3385545d3c9cd71b0a070aa2734f8327c095aff6b342584a570371ee7ca3f6a2a2bbda60c4e3aa264078b6c9bb206781f229b9a5cc2bba0c8933d01b469b4c687f5a1749513bfa3401cf1443ec0558c89c58cb795e3686640f6350420bed4b839ebc8106ff7043107c590c0bfb753c0aa2305e4920d1f639c3ed400a2836d3b638051b58ea9580390ab57dd7138421709759b89aab4279c5a9768cabfc44ca6a2f1cf5c039e2b0563a9048931f1565d164c13ab60e4c92ac843451cb75662ca03c47a652445b7ef0b8e622187387059a614cb08796d34758133050161743677594d51d02f290b3cd7f23d4cba1a64377baa36082249ad896990d79aa040a7858f1b3dfcb43adf040f1b245d216b2e23420e0b9613e9db6c7535063d05079c739f70759f7de0291537aaf5d6b3f4b6291c147855ea9a79ecb0ad80714520971011365dca81ab5bc0d9d70ade36a125ab2295858b79370fe21932504b9d583c787bf28762241a279663baa450172651f126bb20b85349b6344ad404e3093369569148a2a8cb7b7e08e68fda3408349b4761a171b0c2c85b37227cfa3d7c16a3950298c100955402919d14a71e7b231d60ac11e81a46515cf2f25fde507c0df59b352187af7059f3620026c84469610d0098895a3330f7638082d5b5a925afca637a1d160ecd2c83fc522a3bf40591fa5ecfbaa0a3b1859fc58b1d157c18b71d540b6aa398179bd65dc00866275cb0473964ffe5a8c638bf57304d32e24007b3c61429881ccb1a0403566bf3c46d8a19e852aac6f58d4ae32f45cc7b0f5181f18675920680c2c0ba8ed283fdf20c383bc08ccb7d46eb85204126be034374769caf39ae633924bc8ba6b7b89daf72ac4a86bf86008c02fa0fb18a5de6f8952eda2526fb1d994b4165149ed11b578359a7b9d0bdd7257a2d00b676268a38528fe34140eb408ed5b916c0c43d79ac29b0946702341cd7c20ee23c16a6b2cfd1f9107872b8965952a9a45e0e435c56695c819b71b9a6b6796553271c029d06cdb0308112a89ab4b714566a4b18d03c18d223fb6427c7b3144e64874c26a8ca418cd6f14e4cec2a0402698aa1af6ef63264806e4b42ad3dea298a404c1ec260935166418068edb71abec21040f9b3eff4389358b7cce70461ec8c0ae8873a45504e8688e266787421343699089fc31f84ec95a9f2264eb3ceda71261ca791d052a43808ba1f4706717a10fc4ac21b625fd324cd86ab8b3dc254da31bac0f9106028258adca5f754b309a6c7dd30e11b8701ef37e8715f03c0d8a32e9fa39d37e7637ba00940", + "sk" : "257c04ec995fb9757415bac737300b03c991bc8a5c4be86cb0458f66a551cea67fde748c88113c07f09e2ea03efc14328381b21220741c12c1cdf9a81d3a28e9b7b4bcc88d0f38a700dab5beec59d6073ad85697d14728603b1190a81151061f3159293cb2096c093d72f33b1957cccf7085ab031f0e404b1c1bbd06831a9574b90db6025fca778d68151edc4bfcc11292f240d9e6226739036cf000dcd1b275d12316e605c72a2fccc55887220ec958412493c8aa4759dd0848ea0271c55bbbbd178642331e8c910a932a5a8d0a3479153a480c9b0ac58b10334c6b186b38526546eb31a0186e622520b2b60dcd00345222948cc833170427a301a26e920ccc6a71b979b7f8a02f86e983f1eb1b2aca4202100260a94b847ccedd8101e1b16041f96d72b8cec772c08bf5a75c5190f78b123e943e1693169eb726771a7c2826351b5a05a803134c24b72deb2a6f282b94689ee47bb47102926849821981322a03915086670896152a022036351a046bbb6d178bc7605f92254cb8ab2e24544650da4e29fc0ae9abbf0b2296d6bc7e99b4c1f9d50fe7fc7a130432bf98b28e142cb1924efe5324bdd2887a9a7b6a1c18dce15b5b127f17b5739b5c5e33e63fb2494fe403cbf9c2059618ab6fea5b1d78c4d0438fe94c447a4a2e42d974a44890db571ddfc288528b683a363a93a56eb6c9b1da246f64f0b0d3d6c38b4975f6ac2adb2c62a9d208812c0365f3a2aa39ac575595fddaae5ef5c7f7fa49d8b209784aa25c7166c92759f58421eb203a1e8291604c84d24565dc68ca7b183f78fb5a6869115bc7b7b1b33bf4e4afdac9af6dc0604070300f7273223aab0fd85401b923d6c6180c815853994ac22bc45e5b7961a176811780af4b0bd84a490a0a3ce1062204c535c9932be4137a7b6a1ff75579e72b75eccb806b67419119721fd03e59713920949e8f6b5bb278b7dfd40f1125ace9336b5bd5b46f5952d4fa0b780a875b87bbb8ba2096d940555c69e45602975b1324875e891c6c326539052c811ffc4417bc61205b430b522a1a7b4df509a4e2c9bb5a595333f29b986c113f57a9e0d91af791c8096c0330cb59c27b3b29c15b13128b86336cb0c270dbd80d451b08cfe35876594ac4011b621792458042e8906deba57ab57b9565344e2af27d87a68108a8487a817ab5c779683cb81b7bb258e598047505ee98c7d666766110256eac0694b3565b07124786966ca81f1ea5a8be616544d54f03c5bec6d81b392a723bb1176d94c75b47cd8a00aaa7836e1774824289803df38c0f6c74b4c42660d1b27e5036c647bf4089b3be19a76dd8ca518307ca92b3303253dbd9765bd26635f3bca865c215723c20358f2b4c487b008a7f0221359889dbac532deb2b38ec8f35a4a6af306597f09e1f84b808140dc31a36b1db11b13c23edc79ae5f1861dbc4eba427a62b153f721a543224caf3c54e15467057cbda9b1ae41fac0ca7658a542a87060a960d57f839712aa497f0ee03a9122315409279cc89fc6f5afaf72497f99ca8f3a18da1b7221321c87713bd484612204783117aa4f2219a9019c251c8f92d8bdb946b42068207ac04e0ea116a9d2cebb25391415630db5300bf51bbe19be36c8ccda4c9852a442d4259905628087c232f28871b05512dcd2b769179ad09a9313252dca243d73b387b279a1ca1151fda2781ab7757d2ca5c64052c8440bdd93acb5152203987bd5a693453957504242b3f8667d3c800e9a969372a13fd014715a0bff3a24c8f31a69c329a1c30ef37ca29903ce0943982413b0ba694ed53cb416f125151c8f036709aa2174ec365a56d608a2b54ec71183e2b4258e71adc09c81fe05065be2bd972979eef093cda03bbb82b6ee4180731c18fa997195d4917476427d7c07d99b663c4b50a9cbccb3c364df354685273b8b42b9e118a427c765b08036350a330be79b3ef4171b953faee56f719483717854b29aa3385545d3c9cd71b0a070aa2734f8327c095aff6b342584a570371ee7ca3f6a2a2bbda60c4e3aa264078b6c9bb206781f229b9a5cc2bba0c8933d01b469b4c687f5a1749513bfa3401cf1443ec0558c89c58cb795e3686640f6350420bed4b839ebc8106ff7043107c590c0bfb753c0aa2305e4920d1f639c3ed400a2836d3b638051b58ea9580390ab57dd7138421709759b89aab4279c5a9768cabfc44ca6a2f1cf5c039e2b0563a9048931f1565d164c13ab60e4c92ac843451cb75662ca03c47a652445b7ef0b8e622187387059a614cb08796d34758133050161743677594d51d02f290b3cd7f23d4cba1a64377baa36082249ad896990d79aa040a7858f1b3dfcb43adf040f1b245d216b2e23420e0b9613e9db6c7535063d05079c739f70759f7de0291537aaf5d6b3f4b6291c147855ea9a79ecb0ad80714520971011365dca81ab5bc0d9d70ade36a125ab2295858b79370fe21932504b9d583c787bf28762241a279663baa450172651f126bb20b85349b6344ad404e3093369569148a2a8cb7b7e08e68fda3408349b4761a171b0c2c85b37227cfa3d7c16a3950298c100955402919d14a71e7b231d60ac11e81a46515cf2f25fde507c0df59b352187af7059f3620026c84469610d0098895a3330f7638082d5b5a925afca637a1d160ecd2c83fc522a3bf40591fa5ecfbaa0a3b1859fc58b1d157c18b71d540b6aa398179bd65dc00866275cb0473964ffe5a8c638bf57304d32e24007b3c61429881ccb1a0403566bf3c46d8a19e852aac6f58d4ae32f45cc7b0f5181f18675920680c2c0ba8ed283fdf20c383bc08ccb7d46eb85204126be034374769caf39ae633924bc8ba6b7b89daf72ac4a86bf86008c02fa0fb18a5de6f8952eda2526fb1d994b4165149ed11b578359a7b9d0bdd7257a2d00b676268a38528fe34140eb408ed5b916c0c43d79ac29b0946702341cd7c20ee23c16a6b2cfd1f9107872b8965952a9a45e0e435c56695c819b71b9a6b6796553271c029d06cdb0308112a89ab4b714566a4b18d03c18d223fb6427c7b3144e64874c26a8ca418cd6f14e4cec2a0402698aa1af6ef63264806e4b42ad3dea298a404c1ec260935166418068edb71abec21040f9b3eff4389358b7cce70461ec8c0ae8873a45504e8688e266787421343699089fc31f84ec95a9f2264eb3ceda71261ca791d052a43808ba1f4706717a10fc4ac21b625fd324cd86ab8b3dc254da31bac0f9106028258adca5f754b309a6c7dd30e11b8701ef37e8715f03c0d8a32e9fa39d37e7637ba00940bce58a5d05a4840f835b8ce39703f77bb31f20b9ee4fd3795c2e326244208b288c64c049c6dfc0f1476cffd520b055756162f7ec94243de6b14ac0b9e5fb366c" +}, +{ + "dz" : "c719f9b2d16399b7326ce4eca30dabefe8fdaab18e9f6df888b0a134ef355570e40771856eb77e4633504899fcb86c6a3d433d0b8d60e26f07bd61f1d4ed69bd", + "pk" : "8afa99db2599004da53ea126e94c903605aee44b3d56abab69438320c91918abbb1ea2b6953753e475bc33c159c590bed80760731565279c640d361de46aae78d0a837912c66c5a347c0946f6943866750c6ac1eee713cb8636e543b2f8a08857d53834233603391417a23c88b6003246a0c8ff39edfc7ab8759207dcb7c1d923ad891c31ef564e5f53c0447a25728c934303bec26875c44a26aa36e0324ca6423855bf2ca04e27cb8f42329a3a0e28a7285658fe1748a58c538ddb710c6d7839b573b30a5c4486a448dc0bab7c07b86279058578d4a56c781752e8ab270914534c51923a6d0c226967313695987314975dc7c7a101578f326d02a086513b2608a8b58ea5a63f2c6a1cbbdc847c312f5a2309c1749c349101a42757073224b0aca598a6a72cb308a010c327afac94798f8b4c6a1279389c12d1c3015b02e37a95705d3b2b8277c2c141bc8148c94244ec5c50e65790fd6e0842185a5f2ac1e72a21d4d652a63001c650b6c8d06cd758923d42479cba96d7eb396803c77be54c831063707a35067b87b2876a1a0844d11e1a895db70d596871fd1434798771b487aed562ee1d041c06505786205166812fa718424708a207cb4a6c25ee78b8b85e869bb82a89f647a813b97dc1abfb22b430d37adcb43b7bb1616dae73b0d606940e5af7d139f73b48b4618bfd5c22274d3a27c20195794344eac73b9a09de5cc4e59a2853a412eed7062dad16b0e1aaeef83221d34b3225868da033822248e5e40a692c20ae4cb112b9c4f9e373d6dc3393f385b5f65c7f14b66d7d0b31dd7902af39812d76d5ce73ebfa4c392b069be694bbfcc7b9c0825d158b431898c9cc9080d632196378049a5a02b43cf83d37e4a731505f23009661070038917a93c452004a8023b1da44b4e5cc53adcaea033c8759a3bb4bb52761191d76c95599a9dc2a2292bf37aa3803278726b660233e9b476748a31f9fb9f2d93b59b9cab33356782a976e05b083716262278349fb14b806a7cd3e52c1a6a6f603468c4b420cd544bfa916d157a21d15c1945b31f7c6285c30529ddf735350c92c546ca776cb44360cd62f05620f8b23b94a0a720270f122b0f22316050b7cf6623cc0658a9146861785c03fc4e0833c3565ca4ebc951f5145e2e434555d45c3819ccc4c2546673c18d70af49f0aeaceb83041556d52754c10b1d66b9c0519985e9b0aed559074743c8796881e5a189a4707b8923097669b2d9a162dcda33c3b825e004aa20b1749eb198299476bf45a519d341e9b507b1e411bd5382a6a84b6dc9c1bb437e98546074076ea76654ca6519f7a71d1f39c5328b16a5b182bed6b57ae058c3201554d612628274bff57755022b7e653dbb461958ca3eefa117b57299245a9917158f2409384a7b234ab390152b01d1383aad99747258c61bd24f7b12a0332c6d7b5ace324b4e1dd9b3f8574b17382bf387155f0abaf4fc8830b7774275821e91a939da83c9c189ec08774c739fff041d40d512b171c2d0ec7e404349bf5a64a876aaaf72c9c16a004578842bfbb6ff221debdb6ffc8a6de429ca0d7aa50071bc8d68c23c379364e56e4ac247a99523f8d90b3de4b049b526f8961621b98dc534b9a756aa9c4a1b2b4c7726e701ba03d885a39d59a76d92bba31013f2a4714ea384", + "sk" : "8b814f850315f33901f955a7dcd2971bb73d44db90b874804457124002ba681347b4dc33910ba22a903f480859275523598a1ff7cb818f8cba2ed0668edc45f1997f3e76628767b63890c35d334f209b62a208700820c7a41689a4c81208b05573361dd30642baea86f25bbc87d1157f05368582aac0958e87fc84c431bb2eda3c479a9cf0984a90e668427046f2946e50a43e3889aab5d649b5a17242aa6d6350a1b72b971a748cd2a0a6cababd4f77b6fe905ef270bf222c1b5c2683165b9c87458f849405aca37dc8e99699128ebc6317274993d74c77cee907e536b1a1871d1f8a3505670cdab00080db31cd0ba9269c84d9ea565d194e22d3c11573685b166f02245efde45f04ca2d851aaacf47c711a536aa1855b7693161f27e51eb52cbc1b6322537868386715b16c4802d2fb43e9ee7c28c51a5fbbc1fddf670e02cc3e24bcf75389651268e4c78949e284fe9a2a0fd3428875c7d4ba669e1f7116eac952640b9966626a867348022709cb54b05704c136b5538ac7c6e018107a27b1040211562cb1183714a2c9a634a8bd547965fa04fb62441cf7601393293f669420dd0a04d18af0c0249a3b57e0905758b7073db3c80e2634366285a86d6aa7fa8561fd4a6ed745aa04872fa7ba732c514bf045445cc4455accc40e499f71a2d3a8ac73be9404f3736908745b1c40985e4920edbaa2bb8933053124c4c300f7302fa634e6c6830b3671fea4965d58aa5c653682e88ba5ab34361409f4c1656f1772643f71134ba1b1471192de503f97868e43a4d4e9a2bb2ec38ecfa1835f24b3ff1b850fb5f4de32f196377503c25ca0989703b72d72494a2217276c9a15b600bd4dc76585774b2512da602553807aeffc5c6e8f0187bf5613d35857e7b4a1a4b805946224b4a8989c0bd4fd445cf64910194ae3ac96cd0e22144b9ac51fab7ef671b6af68d7f5c2a3b48b82fb2cb49722cb5b668ad021240871307b185b6426451588626850080d68a917b2fc3720dfb33c365934ef37bb5e7359a6008ad72d255b4e921c6b1926b917cc00c03a286b8489a53b5a7429e1cbfc42507f33bbb5ce082b58cc550e03a41b9cca243506de21f3946019dc87683b35caca42fe8272861b4633044773e5c399f8c6423922d05c528af950b6f6b0445d98c5243c932451303222e8a8a55039b34c2bc643582871236553f96b80c9041400682f05c6795b64160006359270c4526baca74b515b224ab234a6b127c4612acbf82bd540226927675f5423cce59034f4596276647c6c8c3d53b54014b6596fcceb0c29609b50e1d599bc728a41db0c3e2a6c41ebc956fec70d2b58866c3c2665ab98b153052d917ebd9ba3ed037f62c8299a02f575742d7102fdaccce7759763ad2147df656ad878ceb1b7ad5b4cd3ee0a2320727a1051d74f84477ab5c2463cce42295f656978b470708a4a26f21949635a957e12bbcc9c8c83753ccd6781474b067099425c705d78631e69632dc5909deac940398b8a6918e2f69587a5992b354b54b7931d0b4c0eef60c61b46170699035ea014778a28d8a224196beffe96c06303e5f8ba659d0229df3b5ff445cc7019e8b54b4f4346c7107b651d0277d8a195c59ae8afa99db2599004da53ea126e94c903605aee44b3d56abab69438320c91918abbb1ea2b6953753e475bc33c159c590bed80760731565279c640d361de46aae78d0a837912c66c5a347c0946f6943866750c6ac1eee713cb8636e543b2f8a08857d53834233603391417a23c88b6003246a0c8ff39edfc7ab8759207dcb7c1d923ad891c31ef564e5f53c0447a25728c934303bec26875c44a26aa36e0324ca6423855bf2ca04e27cb8f42329a3a0e28a7285658fe1748a58c538ddb710c6d7839b573b30a5c4486a448dc0bab7c07b86279058578d4a56c781752e8ab270914534c51923a6d0c226967313695987314975dc7c7a101578f326d02a086513b2608a8b58ea5a63f2c6a1cbbdc847c312f5a2309c1749c349101a42757073224b0aca598a6a72cb308a010c327afac94798f8b4c6a1279389c12d1c3015b02e37a95705d3b2b8277c2c141bc8148c94244ec5c50e65790fd6e0842185a5f2ac1e72a21d4d652a63001c650b6c8d06cd758923d42479cba96d7eb396803c77be54c831063707a35067b87b2876a1a0844d11e1a895db70d596871fd1434798771b487aed562ee1d041c06505786205166812fa718424708a207cb4a6c25ee78b8b85e869bb82a89f647a813b97dc1abfb22b430d37adcb43b7bb1616dae73b0d606940e5af7d139f73b48b4618bfd5c22274d3a27c20195794344eac73b9a09de5cc4e59a2853a412eed7062dad16b0e1aaeef83221d34b3225868da033822248e5e40a692c20ae4cb112b9c4f9e373d6dc3393f385b5f65c7f14b66d7d0b31dd7902af39812d76d5ce73ebfa4c392b069be694bbfcc7b9c0825d158b431898c9cc9080d632196378049a5a02b43cf83d37e4a731505f23009661070038917a93c452004a8023b1da44b4e5cc53adcaea033c8759a3bb4bb52761191d76c95599a9dc2a2292bf37aa3803278726b660233e9b476748a31f9fb9f2d93b59b9cab33356782a976e05b083716262278349fb14b806a7cd3e52c1a6a6f603468c4b420cd544bfa916d157a21d15c1945b31f7c6285c30529ddf735350c92c546ca776cb44360cd62f05620f8b23b94a0a720270f122b0f22316050b7cf6623cc0658a9146861785c03fc4e0833c3565ca4ebc951f5145e2e434555d45c3819ccc4c2546673c18d70af49f0aeaceb83041556d52754c10b1d66b9c0519985e9b0aed559074743c8796881e5a189a4707b8923097669b2d9a162dcda33c3b825e004aa20b1749eb198299476bf45a519d341e9b507b1e411bd5382a6a84b6dc9c1bb437e98546074076ea76654ca6519f7a71d1f39c5328b16a5b182bed6b57ae058c3201554d612628274bff57755022b7e653dbb461958ca3eefa117b57299245a9917158f2409384a7b234ab390152b01d1383aad99747258c61bd24f7b12a0332c6d7b5ace324b4e1dd9b3f8574b17382bf387155f0abaf4fc8830b7774275821e91a939da83c9c189ec08774c739fff041d40d512b171c2d0ec7e404349bf5a64a876aaaf72c9c16a004578842bfbb6ff221debdb6ffc8a6de429ca0d7aa50071bc8d68c23c379364e56e4ac247a99523f8d90b3de4b049b526f8961621b98dc534b9a756aa9c4a1b2b4c7726e701ba03d885a39d59a76d92bba31013f2a4714ea3840293675aaefa1219f8794d114bbb004463f9c631729734cb430f26f38886537ee40771856eb77e4633504899fcb86c6a3d433d0b8d60e26f07bd61f1d4ed69bd" +}, +{ + "dz" : "e9acbb774be970206c3a738e243b420805a509fa59fa902044be2f0d013650d2ded5edaec5de3bf5b4d7c2f2e18e87f499c1968993eff196753db8045e2c8ba8", + "pk" : "a7c9ccf796828b704efbb194d5d895cec082f5dccb78b59a61090eada66093c84267079597c9881dfb2ca8fa4cee6682c4375eee25a08bc0766eda05bedb2cabf734c4243987012a44e86cc013b7e555bd15d45306479a78ea7d4fd7723d3b074860914e24395b264d35e57867f0229912c6ad0238587355b44c155bf7b5e5c872afeb136bbc32b1a950b3122f3a5b71d8c140940b1ee62a5543f3b61719896499721f5466f7b57b119568c960a3796bbf2c8877cf8a762d6a8852619abcfb85ec7c6e79652311490b03f61bb18a23fa100fee70a0fc693163b28ebd6505773324404341e6c79b0562207ec1077cbb64053a4447866efb1894a6a544daf283474c6e0e99323f962b5cf4667640af8351059ab42e0925431d864339258752a3b08ad52f985520a1247af44366f3377d5875589ea9a8e38455a3bb5ffc29083664cda47988f4f0c59622454a7109a6722a77703b0a69a4db2ac154d53a6bd60603e9be794b0b1b0b88da57a64802ac771134b1a4776d07703db8746e610331ec3ad3926891c05b4b738d3564b79b59287174696d119717d3650aab049b401466467ec352102ce597f6e867726543067acf511975828799f920bf139c176fea838144797e79441af218d9c2c0f15a350ef82d588b45b86a2c58464239c121ed2a7650d2841eb21dd6547bd32c0e4d654a3823c4051609ed49220c2651deb6b0e55a00d261caebfa9c17d82d5f23a111c391d06c0441102c2745875d6905ae21412c2c14ae51c5609c5872828ca8d09239b82abd602005cc66ddeab736db3cc0e946d6232177e6c012a8672bd62d0a4253dbb5a908c42341503b76d428a0c38f7e978d4fd2532d075c08d9cb3a440018b323dc3ac28bf8875e412745962e512c0e0e81b4919a813766bb020c831ce0c3eea5a496e57e8d598d3bb34733b6358cda44b1960e8890ce525578d100257ed8a916a02fa2d8b59478966835c0603a8f48715ab2544d0fc487a7eba7a96a6e3918b9c9cac54c841c2899cea0312b40f9bd93eb7d392a4cb889144c224a23244067a9712ed9cf52a15edc35895c7c121822468716704e3617ccd59aeff5120524495d44ae3019adf7d25bd7871b2a98a17ab6c68c789174a28a4863ad69362fc5982aa68b3c0cf35fd2d63d064556e55b6df0d636dc5ca56a928f19c61816349c6339c59febb2b8675807a6a9181a91620a684dba5c4c596a821b66014851966547d60690f7a805bccc4bf9620c188495795c3dad55c8e7529fedc92ee3192a68bb9250420f6ff04f939c82c8442350d40f9d518c10c53ed5c3539e373d0f955d3d451e7873a22af2aa87c08105c044613334e6b585aa864795e0a6af988affb2b2eae653be5c76383b66f5205e1df2b557b66b0f9b7063d3039510ad13a9b5ae6bbae433808db7275271917d75524eb2203202c1f0b4c9afb402f5798214c28667d28727f89b95d3294cf38c129a792b16161e6b9eca60c18ed802c72225d585c7f59059dfd74944f764035c073119395478651f88352c204f89222bfff7c8bedcbb6be1728ef74e54435b40b22276f1199ef34673ebc70047956a543f3d8569f334a5fb22b4c2bc34aa9a4b27a11795a730eb96003ed4662f2f0344da2b88e634672fe48e40ec83f4ae731342e77cdf4a3a", + "sk" : "05e74ae857ac16003fd911741a1323a9621de488789eb612908928e0435aac49ce2097cd03ebce2c8c0aa232b19bc64e81d38750395af4499de139be5d8a4152b66a56067cd9a372c667ac143151676399b516377daba3bcf2a846074786f934c8c091921353779b91c1a201cc293a83e11bac68c3e68350a90c13d65628f379c1e181a8a9783b897102be367cd21629d198c39686c02339cb92278ad1d17ce563797e9b4215ca88a37a9379ac6ccc523cd94049225b900ce145950cce099700672300ba71b22b7a1a01d30ae26975fc53795d2b49a1620a80d0076ca983c0b8b87e96399fd6869aea85d35159d5a9872242515d230ae0965d5ed31cca22a35b33c5810ac4737481b2448f324b7c208387ac045c0b7c9b25a678526857c34a7748c443ced32bd4b7a2155ab7d67297c67080f507ae2309b66800728d661472692ac22063f3886e111a5176387fa410422bf571c79a4d8b764abbbb56ef845ceec23c8381671009c1e983465e090ecac84d3e7b567ca59e5af8477ea89dba3784308c680033c3ee65b670aa43fc6932dd9692dbc8839bd94c89e85e20b2b9ff015ef85a2c9dd7208db5815e73a4ed469d38a967ba42b2ced1c959e400aaa10957010a23fb7e086b82b1e1309b64977a77b9f6bc15c92149e3587c9bc5435d4a50a62c90dfbbc339b3467795bd3e125bcc6cc83b797d4d7a6e8701953a57cec99b8c7939697bcc488f0b6601dc2f31ebca4b15059f12962e153a164076a9f6ae88cb737b8ac4f5eca0fa8b3bc9d03f7b578c8de160daea49a0211c7b007a37cac38ee02d07aa48e355cbfc43a540d9096dbc5504949239cc0b82d94755c4ca182852d56b9b9819c42b6c22f3246cd4a879662cc901e4904ef791fb34c7423a23876204618276e45cc8893b15f5277b67c391177889d8868a8c14949b684467094a9e2566bdc58b00b339e3b91fb54b63e1f43dc57a7f107cc988cc1d65e456b85325fec11db5a7c947fb1d82631fecfa57dff3a1de5ba8bd0a5c2004cddf442699c4acab590730c8aebd853a51a8ccd68839f1ac397ac4a9b6f54316537bdb99879596bbd2f517b296906345a2517318b4146d4afbb7e1c1bf377337c6b84d3363b49a7a8937cb58db3524a2525f2f2984598797b835a41961b99bab237077a5b6dacdb161c86b19469e4b99c5b552c63c3f3fe3140770c369c49e6f696f11639d625647b3fb9a38a0cbfbc01231c2206975c0c7b931597881af2cc267da7f5a320eb4408df9e39d15a7558429390048331c2109d2c46ab7d16b0412c1ba8b6b1f9b58a47c3d54564e70440eeb43c80abc8d67792324287b3db329329267f53549b6a72d94d9bbb2a02b7c985ae8f4a5c39218cda99f6d461bd27723bb20af88446ea65a7b85c074cee48feeb881ddf9773c5c6740a178e1707c50788478d3500f6aac22b0be3ed5ad240a9a336378af185dc1519c0948cbba81790da7929ecb464406cf618cc019a84868745591496ca38ac57dc5010ba815b24507ace51edee75dcba3877179c4cec474101395d9f831241c2547487636d39f1c6082041ba679b7a1b1d5bd0b295eb137ab4b210d0149b4fb0c8df5515ca6d7a67393a9f5b57aa7c9ccf796828b704efbb194d5d895cec082f5dccb78b59a61090eada66093c84267079597c9881dfb2ca8fa4cee6682c4375eee25a08bc0766eda05bedb2cabf734c4243987012a44e86cc013b7e555bd15d45306479a78ea7d4fd7723d3b074860914e24395b264d35e57867f0229912c6ad0238587355b44c155bf7b5e5c872afeb136bbc32b1a950b3122f3a5b71d8c140940b1ee62a5543f3b61719896499721f5466f7b57b119568c960a3796bbf2c8877cf8a762d6a8852619abcfb85ec7c6e79652311490b03f61bb18a23fa100fee70a0fc693163b28ebd6505773324404341e6c79b0562207ec1077cbb64053a4447866efb1894a6a544daf283474c6e0e99323f962b5cf4667640af8351059ab42e0925431d864339258752a3b08ad52f985520a1247af44366f3377d5875589ea9a8e38455a3bb5ffc29083664cda47988f4f0c59622454a7109a6722a77703b0a69a4db2ac154d53a6bd60603e9be794b0b1b0b88da57a64802ac771134b1a4776d07703db8746e610331ec3ad3926891c05b4b738d3564b79b59287174696d119717d3650aab049b401466467ec352102ce597f6e867726543067acf511975828799f920bf139c176fea838144797e79441af218d9c2c0f15a350ef82d588b45b86a2c58464239c121ed2a7650d2841eb21dd6547bd32c0e4d654a3823c4051609ed49220c2651deb6b0e55a00d261caebfa9c17d82d5f23a111c391d06c0441102c2745875d6905ae21412c2c14ae51c5609c5872828ca8d09239b82abd602005cc66ddeab736db3cc0e946d6232177e6c012a8672bd62d0a4253dbb5a908c42341503b76d428a0c38f7e978d4fd2532d075c08d9cb3a440018b323dc3ac28bf8875e412745962e512c0e0e81b4919a813766bb020c831ce0c3eea5a496e57e8d598d3bb34733b6358cda44b1960e8890ce525578d100257ed8a916a02fa2d8b59478966835c0603a8f48715ab2544d0fc487a7eba7a96a6e3918b9c9cac54c841c2899cea0312b40f9bd93eb7d392a4cb889144c224a23244067a9712ed9cf52a15edc35895c7c121822468716704e3617ccd59aeff5120524495d44ae3019adf7d25bd7871b2a98a17ab6c68c789174a28a4863ad69362fc5982aa68b3c0cf35fd2d63d064556e55b6df0d636dc5ca56a928f19c61816349c6339c59febb2b8675807a6a9181a91620a684dba5c4c596a821b66014851966547d60690f7a805bccc4bf9620c188495795c3dad55c8e7529fedc92ee3192a68bb9250420f6ff04f939c82c8442350d40f9d518c10c53ed5c3539e373d0f955d3d451e7873a22af2aa87c08105c044613334e6b585aa864795e0a6af988affb2b2eae653be5c76383b66f5205e1df2b557b66b0f9b7063d3039510ad13a9b5ae6bbae433808db7275271917d75524eb2203202c1f0b4c9afb402f5798214c28667d28727f89b95d3294cf38c129a792b16161e6b9eca60c18ed802c72225d585c7f59059dfd74944f764035c073119395478651f88352c204f89222bfff7c8bedcbb6be1728ef74e54435b40b22276f1199ef34673ebc70047956a543f3d8569f334a5fb22b4c2bc34aa9a4b27a11795a730eb96003ed4662f2f0344da2b88e634672fe48e40ec83f4ae731342e77cdf4a3acadbc64e263f1afdcddf2ad63f2fcd19799a0a8f43ec867477e249ed5fe716f8ded5edaec5de3bf5b4d7c2f2e18e87f499c1968993eff196753db8045e2c8ba8" +}, +{ + "dz" : "c1b3cbffad4b306f9af0cdd3028876486dbe858875c9b6497fe20172a986c82b1c96249919cedc2369d8d739ab125e0d2ccb82dfebcd90240a545cdfe07511f2", + "pk" : "b854a0daebc2831a4f20695579b52d3369af228842776a03c4d3284d763d1f663000930377dc86ab14486673a349d8073ff6ba44496c64467d5f531f5203a074ac7ce9090e59f1c308d2c755910af132ab81b50ad6d6c2c6716190696ae6a51433f61185a43cb1d23708d8286d066b61a6b7f9e13f8248c232d8315f40053fba0d7ffbb4ce60410899200a8a5e51bc1d8392cd56f41fbae85f35b110933a931084444036aab790cc09b84b7a235f34763b9ab5c9b53620f627778c661c4c45b36ebb3a4565795656227fdc280b327ee2f96c16e7bbbde89e9090318787b2abba7727a393cdc04dc38205e3c86ed5d5291a1149ee204b24661ab2ca16c1c0a35d3cca0d7c57f4e01985242c3b43869d9914312678710b039be4c2b775cca014b1d936ca8432a4614c4e67b69620fb49cbc787599c4bffdc3a2c786ba876864e7a5be33ab200bc2d087c3e6cc642f4a96771ba212778046b5823085c4068b209c54a5bd4153e4d986ed3512d09d40c37c1a2e57495e0a594f4430fdb1c88c4fb677b007d8804ca114c0991b90b5140761d59325502a1f0476e961a0c2b2ca78a82c8b5581d98da26de717f84c140fed0a00221ba71c34821374ad7c565ec20cefc949e98d1819702a4d38597c1db9239b9167dfc8651498927bb0e170c151e881577f58963593d3ae00870b8bb9fa3b77c468e8bd365dde088f24c2577c5aae2f24aee1552e4482352674d1d96b90880336ed44f6bf007b5eb67c52a10910a9a3fc82ab8d50aee17b667a27b4d014161f1a60c3084a25524693364ac1876cab0c93c01a153b03486e75c3a01728f625f9a7a6a99e78ea9b77b01490ab49c6dad9ca584229a8a890effe47ce0692aafb17a3db2b855a01666514e8a800a47c0cbfb4872c8c8a4d4bc52c8db43d3f7360d568f4f905ada2565a494901f229ed51bad9106bba6dc4fa7ac59a3a5a64d033be1e47c36c2cc9da10a2bd200b681c2caac5cb1eb03f36455241367d30019aac00afe312c5323cbb4575e271c01f09c6eac03ce1f02bcc4186768493f6cf97671e7a02db6047557306bb8ce086382bbab8312460663dc1bfd01b2411b3c49835690627f133935c27308be6b5d09844f477523521c2b1bb1c92b6b3c46c20cf97217683a3f2e46b0151511c7c9c4bf8620d4706ffaec98e524360986386a7b5c20c312c5b6237bd17271bc6c146124d190205f468dfb00bae08318350c1aa5910a07a67bf13a99a52a39b2b04fa56143c0c1290c5c412ce1647ba8242c851c8bea960c9c4879b83037886ae77b10e8126dd3b633a33a662076cea326765d6262619b8d0c8c3217435450070dbbd67404f5255b6557267178ed99cd4257768e728f3069bc29f8484a127d84098ff4325946371384463c4ff489cd8b6eeed0c5e3e92b1b988c41a31df71047cf78ab1ef9adac2a1ba3121672505ec77b0620617598f84d1fc7b00fdc65e7ab72274c86a424746dc74f53142be6423545d02d581933bb92058563279e522ad8507f4326699bf4831970775640887e875e1cf29a09843210a23976941af397a3c6c5605af133ba94126132311224388f340448a1252c5bc0197b4699aab73a4237d40204a46103bd605bc698111ddc3d6bc04804722c35600b001c554180d16628713bdea10cdf", + "sk" : "b6f76178bbab01b89443c00292ac914d658044f13fbbd19cd4c0a385141c6a91208665bc45c04ad73185e6e3a0cd102a8cd20547c2335ebb3bd7e9ad50294b07d9a45e617473814ccd41078fb58d2dac1f872c6cb96c73d1aa4356a917c94704a36b9ef791c6c021cf9ed2270685c645a76141f6373b8ab6ab18963b580ae0134d8b175382847811a590080a3dea2b863e06a0990c93839906e2f942b864bee7410bbb17bc1db6373ec99b45754ec78531c205919c27a4f2445b8a777683819709c1c9a3660ccad39941e496aa791ff8d2671b74580df965d0126dc5c034b8b01f31179c1c4746d3820955206b447174eca321a5c22ae852b631e12025b5675385731ba9234ae36cd90c3e16fb5ea2494012b96498f02edc23cd0db74970961fe430129af1b94ad5b1bd95931aecb365fc257c7c1d1668164edc9d2b869a4cc95d54759182c6086785246794a6a0f81431d75fc7189416a9b1efa3832c187fea912474a8a4caa5c9d08b2386240a3d26755111a3a3e830266473b6e02286c10e23ba34ec08c1f643a8f2b74519631706690fbeb5be8bd581175412c1b83da81700ec92bd03b9516a779205c78f726126d67ac2a4c528663acd985296d187c7f6e231a95707d0f9854a4c051a12179678adbf8285b5e58251d08f2da015bcf219edf39f6be56e53b95be3165114616175a5ab44607612fc40ef814c9ba52b6c060c0f11adc8234d865282c3dc5e106753cf221ab2996ab9887ed5334bc7b83d6bb413e1fa9c074903f3c94c685c660ab00a6be85c384478cb42bde6715c9a3bb77b7acab909ce428b955476c85f153263874ca3a7429c6a79a0834c15237dc5fc7a7620897876a3c0970e1b7b789a13482a38c5455a187995960806304ce34b72e676fa589f9823c949981b6eeb887bf7c09ee147645602a640598bd29ac48c94daf0771f46acacaabb4bbb73e841b4be5ccc886987b56cc6e25a7260b3364ec4a897ac22816048756a530ad269759929bcb4ce03435784b25f6f87ca320060d2a1b3b800986cea76229b1d5fba58afa9ac3514289a9b7f63d80f2b48893b376018a0baedec2715b01d61c8cffb63b839c4129c8b97acd904a23a0cc5a38245802ef5eca812870a5717c667ca9bac328f08305621305e5d40980cb7a3f8bb01ec4469b7e17cb4657944a739448a461de11e3bea1d7141a6b7dacf8f41a8f9c6437a9c26ad5b2dffb4974bb7762c76715a9694d5d012e2254ea717369766c22cd9938ec0a4b5a88e7c45b03027926984081414cf7b3a15d46895c362a0a2928c1215601f665d675abfea867957f68178e6621871bd7ac1010abc494517804e68be80151c0aa332102822b0674915208afaa21efb3ba32b0aadc9778869bbab9ad2cf934a690f40917593667cc2ad0cab53c387957ee24960149b07a109465c5de3eb576d99481fec4ca5e8a0de36756f951896322d29c5adfd124c867a5286b59f0c2a0c632c6778a098d39c1e6029285a821c06958671651804e75de2d2414eaa19d0a18003c12f74d50655041aaddc6f5daa6dca8b46367c63bec73ce1e181cc166efe3baa2b986bff325187369982978cdfec651946a4995a20b48b035dbb5eb854a0daebc2831a4f20695579b52d3369af228842776a03c4d3284d763d1f663000930377dc86ab14486673a349d8073ff6ba44496c64467d5f531f5203a074ac7ce9090e59f1c308d2c755910af132ab81b50ad6d6c2c6716190696ae6a51433f61185a43cb1d23708d8286d066b61a6b7f9e13f8248c232d8315f40053fba0d7ffbb4ce60410899200a8a5e51bc1d8392cd56f41fbae85f35b110933a931084444036aab790cc09b84b7a235f34763b9ab5c9b53620f627778c661c4c45b36ebb3a4565795656227fdc280b327ee2f96c16e7bbbde89e9090318787b2abba7727a393cdc04dc38205e3c86ed5d5291a1149ee204b24661ab2ca16c1c0a35d3cca0d7c57f4e01985242c3b43869d9914312678710b039be4c2b775cca014b1d936ca8432a4614c4e67b69620fb49cbc787599c4bffdc3a2c786ba876864e7a5be33ab200bc2d087c3e6cc642f4a96771ba212778046b5823085c4068b209c54a5bd4153e4d986ed3512d09d40c37c1a2e57495e0a594f4430fdb1c88c4fb677b007d8804ca114c0991b90b5140761d59325502a1f0476e961a0c2b2ca78a82c8b5581d98da26de717f84c140fed0a00221ba71c34821374ad7c565ec20cefc949e98d1819702a4d38597c1db9239b9167dfc8651498927bb0e170c151e881577f58963593d3ae00870b8bb9fa3b77c468e8bd365dde088f24c2577c5aae2f24aee1552e4482352674d1d96b90880336ed44f6bf007b5eb67c52a10910a9a3fc82ab8d50aee17b667a27b4d014161f1a60c3084a25524693364ac1876cab0c93c01a153b03486e75c3a01728f625f9a7a6a99e78ea9b77b01490ab49c6dad9ca584229a8a890effe47ce0692aafb17a3db2b855a01666514e8a800a47c0cbfb4872c8c8a4d4bc52c8db43d3f7360d568f4f905ada2565a494901f229ed51bad9106bba6dc4fa7ac59a3a5a64d033be1e47c36c2cc9da10a2bd200b681c2caac5cb1eb03f36455241367d30019aac00afe312c5323cbb4575e271c01f09c6eac03ce1f02bcc4186768493f6cf97671e7a02db6047557306bb8ce086382bbab8312460663dc1bfd01b2411b3c49835690627f133935c27308be6b5d09844f477523521c2b1bb1c92b6b3c46c20cf97217683a3f2e46b0151511c7c9c4bf8620d4706ffaec98e524360986386a7b5c20c312c5b6237bd17271bc6c146124d190205f468dfb00bae08318350c1aa5910a07a67bf13a99a52a39b2b04fa56143c0c1290c5c412ce1647ba8242c851c8bea960c9c4879b83037886ae77b10e8126dd3b633a33a662076cea326765d6262619b8d0c8c3217435450070dbbd67404f5255b6557267178ed99cd4257768e728f3069bc29f8484a127d84098ff4325946371384463c4ff489cd8b6eeed0c5e3e92b1b988c41a31df71047cf78ab1ef9adac2a1ba3121672505ec77b0620617598f84d1fc7b00fdc65e7ab72274c86a424746dc74f53142be6423545d02d581933bb92058563279e522ad8507f4326699bf4831970775640887e875e1cf29a09843210a23976941af397a3c6c5605af133ba94126132311224388f340448a1252c5bc0197b4699aab73a4237d40204a46103bd605bc698111ddc3d6bc04804722c35600b001c554180d16628713bdea10cdf5ca1708c7c6e354b69720b4b4a0c358fe9a6ad3febe78bb2a71691658acae21a1c96249919cedc2369d8d739ab125e0d2ccb82dfebcd90240a545cdfe07511f2" +}, +{ + "dz" : "ff7495b8575b5a98e4fd21fb4c3e58cbb60f14bef21aa74cf8802e3153f14807bdc370460375a778d1a31d01c42b66367ed8d9e8f84551002f552f0e52102b5d", + "pk" : "add1cb33481d37e546d75b5398198a82126a7d306a26c7124518075ee6701d1ca69d16a867115582f22a7c382bab3acb5de50c34c13a5378b2b1415b5538987a77681597abab9a0b5bfc7bbd19550064489be9b897a54fd12c7229f0af5313429fc85f1936b5a325aea955021a969ae289657ba4ce7393477afab3ec0b6e46bb7a8570b2dd4372d51537ceb3023e477a36bc2b784444d0f71c3165395ae71f98921ed160be83e0572487691a43128352b3d82b223c67b33d8277b05c6c071418799583e2b87c9c2a81bb2a7658d67e637b99d5770e04b592bd5961f0c726d0058b31086ab1d23f4d200bbe6b418fd53a0131aaa5fc0380f70f1c90cd1dd5bfb3839cff013375f49919214e756856042bb10e1252a0108c1dc39a1f69bbc230a4e9c93a87a87899faaa210a781c91bdfec9a59080ae642aadfbe20f9ec600a2b297c3394a751354b6e8ac65ea45d3b66c57328249034738ea2541476ab0f2717940930c8551314851be98351d96acf6232e1960b97d930e3f424efdf706c2da2f652796caf344b86ab388f412853a5643a7932409b476d3c81c2a301e968dae28742d18232efa09b81177dc9ab33d7b2ed5e711c157bbb123506fe35c5132bd04ea87e173a7d8ab5b2e35a7eeb58ab3f549dd30228dc5197f778359b4b9b9b989b697839fbc013426016110bbe721c1c89c1d463248887491f0814c4bfcbfe7445144b88cb4ec535bb85a3016891b009dd4ea020e3799d56a710ff097b79384556c5d7d717436bc9626cc15ea509fed2bbb74c2636e8cb4e0435283c7159d8c9eb6e11e5bf977a80994278161671346b368372ab5612c85ad48db8a82067acaaa39bc0b1f49083e71e8727adca1f3c7cfacf907a71c3c73e6737bc51795c9761b5c36c87b46141400dd43874c4500606c616d90bd9d588905fab9b538c23a07b9fba6c0699259b6b81aca207138884886205955250e3e7b5d4d549a8b73c0ff41b88c305b7efa4178695abaecb97ba46dafe090a81c038ff373b13582665665b2058835b629f2925ed99082858152433bc3bbe90937c763d835638c3225e0c3485f9555d3e1556ffccb1b059dff8667ac445b474a17f360a2dbd895048b29fcc003f3c46768668b88bc0053bc3821a95d5d49cf1510894f1739c91174310b0ab2cb7836b41bc44aad9681c0067192d4a46c2fd60e2323b6fcdaa15a6581b4571b4ccc09fae5b24d8b11f67aa629e79652388ce04b9ceeb5029e80341ab6abbfe38b2584b55108a21ac64d61636ddb2094cba91c2b606cf3d2ba09d4863ee900decc2d594a042b5a63c822631533a14b6cccaa0775ea3210e3ebb22137a749b22c1eb129c872578feca153b312efe6238583793852485fc53952e4a513e64b8ac7b60241944d704246551d3372ab9e60bd8411729cab31eb908c5348c34db74f3ca60384e93c91479a52b321f8544dc13620f26c9fd324784a294197d9935551ccfbcb93f9f2ba8fda993a3598a5d37c36469024129c8f3a081c9b3a680a02ec450b0a805da455c5f696bf46681ba9f80f6b469af9b1c09fb2bdf618242f449cd017308dd80a9fa7a3a6aa25becb6f07b241f0f72b345664751b83b46a276ec74aa2569b79de21a5198e7f0c3bc2aa84e7f5c79f4cdea5b473ba2d344bf994fd32", + "sk" : "48f2003d718ae6848e47937d58e68162209b6c88892c931b4cc4b1ce0a0e762020495c60e89cc854f72444d21def3a5b96a004e2d9ac9b110aa8844dd02a4d8508b0ad3c480e37196e343ebc01c12cc2ce6616cbc395a8c7e02b19d25041165832584742a07fd3207dd3687c91d17e111a945985805fec8836231b7546263d96302473abfbe36fda05345950c7dea6affc45c87a3272e780a3ee920eacba1fa17500ab04a091fb355d906430cb4bfe66697a09cb08f992a3cb9b2f31624726b13223122c5694d9e0757b65b46682694c82b862aabf3811ad14db6a31b602030498993b8eb5364f3c9213e66c81744b018dc895fdfcb81a77672e71b320e3a2df75403d57c229e745310a7cf780291fe169da8290ed96a2056995fc7c59cf6cc162bb10678736a4f56af0430e6c22419a6c3535b22fcb837bc2214a1d83a6ae7414d6521149498b0e0841e7775f1e783b376c1ac39067db769af6e691c59683114c7420fba6723bb3ae5a137224ba7e816b5463902d21223064c8a8cb10f49abb765281ec372c647b862f11095b25a41705b9b327456a7859c7033691353eeba926ef880500f34fac746d9e59bef7b50457acbc33369f3f85af047bbd75a40cf62ba1ecc27cd5a6437bd28c37ea3739a784f068cd4cc68f0cc6b01e4933003c950985042b1609e0a748c9f87ce5099356ec846f9b40f6c13a6187cab40b47d04cae05d43c53956ff4553f62761068e9938f21a24734305098caf7c9022a8b52cdb54860419a532cb9750c3e439a742d9031076b99fb8a934c2c8a42430a8e65cca75286518cc08a6925c2e3b9fc854d8343b36d652f37c339b951b0f7d774b4da5171a96cf6981f1848703dc93f2ed6bfda065b7ec4056632a56a549353c12c0953757b2077e65c93c00673e88ccec700b6d2307a0609ae9035177fc41c97fc32d1b8bfe7266ab8eb2b9bdb9ec6692f7d6678633b030cc19905bc46960ba25ac8b9da762165485a7c07744d1b8fcc080993d0bf86496262f268f19b7dd7d7bddd4c947e1146f2196ceda5bb53137fb107560c4ccedb96351945bb8ab5092c9975db266e621c53c519caf639c80225248e6804d78108789b2238644f33136e853c26e1477827d3797d7c75a09044bc77b9ea05bad41a1da87a460e17779a5233a080377294a1ba3a99b4db42cd42893b937c369983811c14305cbfa0e57c3e4b19f0a77c4a2a6998525ece48cf45635c5672429b67630e603d1ceb5a22e429aff58c2ce61e79f6780d59575ca3309d559cbe6572e0671af2259a39063f628bbcdb74345af9caf02aaeb0a381e39a5bf08107811b243d130c482b0c74a47738d9a6c5d30538e64cc513160d9a8351b9ce82521ae1cc03c8a48f72252ef1b2a15e6785e639246cb8c196f9949ec094ff6639c8e216b90bc3c2099bb3093ae5242f252807bdb162b3232f3e7383145655ffb71ca43456f1a5137e7977ef214ecbc6113f198d7712178da090620a9d343025ac11595ab6b6844262822b128b8826fadc7b3f218d37941825733f43ba4cd99b63d26812772980679c3b14462b762ac8c3e8942a0b1d4ac1838a2795113c365a535d483658c4531a0ec63c010a2c7ec159add1cb33481d37e546d75b5398198a82126a7d306a26c7124518075ee6701d1ca69d16a867115582f22a7c382bab3acb5de50c34c13a5378b2b1415b5538987a77681597abab9a0b5bfc7bbd19550064489be9b897a54fd12c7229f0af5313429fc85f1936b5a325aea955021a969ae289657ba4ce7393477afab3ec0b6e46bb7a8570b2dd4372d51537ceb3023e477a36bc2b784444d0f71c3165395ae71f98921ed160be83e0572487691a43128352b3d82b223c67b33d8277b05c6c071418799583e2b87c9c2a81bb2a7658d67e637b99d5770e04b592bd5961f0c726d0058b31086ab1d23f4d200bbe6b418fd53a0131aaa5fc0380f70f1c90cd1dd5bfb3839cff013375f49919214e756856042bb10e1252a0108c1dc39a1f69bbc230a4e9c93a87a87899faaa210a781c91bdfec9a59080ae642aadfbe20f9ec600a2b297c3394a751354b6e8ac65ea45d3b66c57328249034738ea2541476ab0f2717940930c8551314851be98351d96acf6232e1960b97d930e3f424efdf706c2da2f652796caf344b86ab388f412853a5643a7932409b476d3c81c2a301e968dae28742d18232efa09b81177dc9ab33d7b2ed5e711c157bbb123506fe35c5132bd04ea87e173a7d8ab5b2e35a7eeb58ab3f549dd30228dc5197f778359b4b9b9b989b697839fbc013426016110bbe721c1c89c1d463248887491f0814c4bfcbfe7445144b88cb4ec535bb85a3016891b009dd4ea020e3799d56a710ff097b79384556c5d7d717436bc9626cc15ea509fed2bbb74c2636e8cb4e0435283c7159d8c9eb6e11e5bf977a80994278161671346b368372ab5612c85ad48db8a82067acaaa39bc0b1f49083e71e8727adca1f3c7cfacf907a71c3c73e6737bc51795c9761b5c36c87b46141400dd43874c4500606c616d90bd9d588905fab9b538c23a07b9fba6c0699259b6b81aca207138884886205955250e3e7b5d4d549a8b73c0ff41b88c305b7efa4178695abaecb97ba46dafe090a81c038ff373b13582665665b2058835b629f2925ed99082858152433bc3bbe90937c763d835638c3225e0c3485f9555d3e1556ffccb1b059dff8667ac445b474a17f360a2dbd895048b29fcc003f3c46768668b88bc0053bc3821a95d5d49cf1510894f1739c91174310b0ab2cb7836b41bc44aad9681c0067192d4a46c2fd60e2323b6fcdaa15a6581b4571b4ccc09fae5b24d8b11f67aa629e79652388ce04b9ceeb5029e80341ab6abbfe38b2584b55108a21ac64d61636ddb2094cba91c2b606cf3d2ba09d4863ee900decc2d594a042b5a63c822631533a14b6cccaa0775ea3210e3ebb22137a749b22c1eb129c872578feca153b312efe6238583793852485fc53952e4a513e64b8ac7b60241944d704246551d3372ab9e60bd8411729cab31eb908c5348c34db74f3ca60384e93c91479a52b321f8544dc13620f26c9fd324784a294197d9935551ccfbcb93f9f2ba8fda993a3598a5d37c36469024129c8f3a081c9b3a680a02ec450b0a805da455c5f696bf46681ba9f80f6b469af9b1c09fb2bdf618242f449cd017308dd80a9fa7a3a6aa25becb6f07b241f0f72b345664751b83b46a276ec74aa2569b79de21a5198e7f0c3bc2aa84e7f5c79f4cdea5b473ba2d344bf994fd3204f0066489947b572f76e1dfc2e24297b210ed0aaf228788a0b349d11689e064bdc370460375a778d1a31d01c42b66367ed8d9e8f84551002f552f0e52102b5d" +}, +{ + "dz" : "bdc3fba1c32751139fc45bacffb3ea97f26573d804a5f27a459293d95190ed8efd5a08f656a6eb8cd20679930a31caa6a6331c4b133a6838c223ef9f769f6246", + "pk" : "a7a8102df0c61577a7cd4b9a04b17ac55708d8c6746289529337b9e267737d5345f4e768e0d6656cf23593a84eb0ec290c8ba078eb9f8d1cc8ea18280981cad0f46dd29c474fdc57cb5bc93e318537ca343bd03ea6a7a466b021b3db77021a8e20b94907ea294f47baad599d51d74219e38f883b36cb323a317520997988342a7452c3aff4522ebee30211444fe78854f9f853cd189be04cc1c800607cb4acccb650ae546323e7993bf2a203487becf8328a2979dfc5c3bdfc1b47533a9a629e5fba5a2234bce8eb37d686a75bc33eeb945d80d92c218548eff794ad6c0d825b57f6f12f0ef6b8201bc0d1fb0354f051ec1a217a9a0f0c77b1d6f76c1f25b01ff356fa390079d3800f1468d745a0dc852ac140307e700f97d557eb42164844b0b6d5a37bf1bc41db5aba156359e9b4ad5649189409be58b8ad5ac89e348099ab9ffe81c71d54853eba7b42167d478693c39837f76182e0c894e0f5ccf19643fbdbc5278b500d1b07f1e62ee797930c0cc4a41832ad093b28460c8700678bda847edc6bafa64ca182016f75366af8c330d201c7ac4327b2326d8b57997734bf909b0fa1c619155aab7bc5f4026079926d04619186c4334f48bdfaeca777e91d0b0b7fc4b180e5e19f0162c5d3146b5ac5ac820781209c455d195f17d541d6916f56838f7be838ac0293cdb63f28529df3fc7d54475062b90d3034c2583b00c942102f82b9553c1120891b77d61b8c86ba21b4a78f772c4049869b56442d33c642a5c0ad167747807d5f6105ccc21af8e06c85031a2a73ada9d59453017f131b55c1e0176ee29b021b7933606c5425078b7b49cfa99f24b21818e78a0e856747e4a7888a3d1313624af81c75eca6c3c43238bb078b94c2a9c57f0c4c66ec5b59ab93b73a1000630aaa28a79415320bcc8a96195934c9f14d5dc41cb70c1104a63f5fa29953495abf71b9359563f16c7bd6bc319ed7898fd00cb580902f2196b45311962cc17a9a9f002a916d9bbc1a452bd3e6a48ca05e50ab35bd828cfe66b483e96ca1d917001b46374c41c2d079fdd8257bc339a6e13a7fa2c0948056f6553803d10fc9f1c87725230ba3713903193f200a9851a78b61534b5a949d140c9b457ec66769c6544d79f0850c4cc8e4b78eae0b260dfc9cf0848e4e09cf52047d62bb8e7e6231f4ba49859b1dedbca0d8832bd23789c6fbc40d61485e5a951de68639e07e624a72395b9e25b603acb330a37b998b7a9ab3f973003c15624c6abce84050fc0166924a397708c12308c578105c1457de7cb41dd609c0c3333be5b9c3b93e2776aa0ab3a4054c98789a4bf419bcb6eb914c2179bae02b462b1126a3a28840b9e7170618c20e8527993623cd0c776e54f8b4eb237b4f8c075fa2175f11be86e2bdf3b9b9dff89b7534134620116e0ac025f6707b00b5c743aae144241b935ba61827909b591b44cb6f36107ef81a214c6aa5b9b3e1f441c774cb7102310c4031e0e4a213a8c1f1593906a0424d657cda7c10c1354b0d5a83d2cb9d0407073fa77abe480854c953eedc6cb06c75695665b92873552cc053a9bba0c99aaf970753299db3528276b56feb8a5bbf373d13c20c2f22ae07e9542206b296f3b101d07a3bd1517d9eb8db21e1f18e6da63acfce1e0dc597cef3abfc7d0aea99da", + "sk" : "3e3a14084387ae125d7f5a0e51841407d61f85d7574b1abea52b6315d07a404372c827aadd3aba668bab52d5943c59bc500b78bd77ccc7da7a3a6c8b613b9cf761bdd73a222bd11b246431d989a9b5d7b68f8c2364c8bb9380caee16bbafec6e4ee157655528dfd8399b3912b303481607620c941cf3a314cb7013a2526229c4bcabf7642596c4100023140a4ac869a30c2a20501ab4838581f42783a18b83f5165907985363d766edc0606594188427a979d171c4a52152fa4ecf0c4d4bfb10306b98ec4a409e2baf598124abb31e34bac176a29fe7316056accc59f38a268ba03b39bb48e0a763e340dca4c3f1d8580ce304f696144efb3db5975157260dcd26194b476c5c6552f9a39b4c556028493f0bba23c96ac03d03ce54a4680e8075cfe70b01bbcff4e3026fa3185f059d401552dd966e70032f7d198a17b8620ba30a39cb1aa3f84ec2d82d154ca88f392c28574cd8dc1025e832751769560569e9bb0cf3f7a4126800142753f7e4950908bfe86b468d095f422c1dfaeb3b196a1c62cc8b0beb47fcf6a456150b780b5648ec05387cc81d485318f1bca87bc6cfd30ae2202e342345159154c8b561f92565ee2c20d7e1c385a7a1d99cba75a3121e410d3145284c826c408455a068625d35b69ff944cb880601483b81f08ddf8ca0b8931480878b25e7c73a6795222b593bf517f0c25f6b862f970bc2a652ada653838c942a68098aa6931a9a858cd4251c19b07f69b208ca1c479777907fb752d24ca06c96b394232f0e1982f4d0b9c6c245da5275f75246f4d58472457ae842c6fa886dc2305b1e2654f1a999664c2e7819571be87bd2f8216bca5486615776e30a3bbcabc3b094d90c9fd24a083d03ccc29590647c533b278a28eb667bc71e2cd62cbeaa74821456278003b9fbc18cf23f2837c8326031bc8ab260a92524e9812d307004ca9f6d709a83b77d3b15b417b1cc7de93737c02e22d0ac4486157d0a8236612f0e25985847185007c41a5846dbea0987794eb2743c87020063277cd366b2c5105421c453257a63683a719a57bacf373b8cd90bb10542fc979c92267e04e0612cbc9fafd485933b42b15404002c8ca8930d295359ff299d5aa3a5b82acf26722542819389891509d24ac2d34d7e10aecac27edf022d499357d4d8548220148a082a504baf876414faea7ddb11639a073e87c3a273713305fa19604b33f6c362dc792a0007aa577a0f3740a246ab4226297a0e66c073564b954039dea916efd14b4a32afb361b80292c6b35244ec1b9fbfeca496b35c1bd5ad7e313575dac43478816868b094c1756bab5503723d39dc2ec6bcba3103b6107544f9bcc74e25355597b69425ae77f04c0fa9a17b1351c0854964261e60284507f0b2a89b4a76cb9481c986198c3fe8514c76465de4eb364bdbc43ec1a1054462643a0d1ff57d957685d0e70213505449119628e86c02f23e1315829cccc9f60a733b8414161673c66a0f33371ca0b10df9faa4f142c4b4300b79b0c18ce8cf76811e459c98b56871345a57844ab6a3749a3e14c18c463e5596836e8c436296a84fda143e69517b8176fef3c52606170194aef5b429057b9edc7c48f1dca18605bee3e26aa7a8102df0c61577a7cd4b9a04b17ac55708d8c6746289529337b9e267737d5345f4e768e0d6656cf23593a84eb0ec290c8ba078eb9f8d1cc8ea18280981cad0f46dd29c474fdc57cb5bc93e318537ca343bd03ea6a7a466b021b3db77021a8e20b94907ea294f47baad599d51d74219e38f883b36cb323a317520997988342a7452c3aff4522ebee30211444fe78854f9f853cd189be04cc1c800607cb4acccb650ae546323e7993bf2a203487becf8328a2979dfc5c3bdfc1b47533a9a629e5fba5a2234bce8eb37d686a75bc33eeb945d80d92c218548eff794ad6c0d825b57f6f12f0ef6b8201bc0d1fb0354f051ec1a217a9a0f0c77b1d6f76c1f25b01ff356fa390079d3800f1468d745a0dc852ac140307e700f97d557eb42164844b0b6d5a37bf1bc41db5aba156359e9b4ad5649189409be58b8ad5ac89e348099ab9ffe81c71d54853eba7b42167d478693c39837f76182e0c894e0f5ccf19643fbdbc5278b500d1b07f1e62ee797930c0cc4a41832ad093b28460c8700678bda847edc6bafa64ca182016f75366af8c330d201c7ac4327b2326d8b57997734bf909b0fa1c619155aab7bc5f4026079926d04619186c4334f48bdfaeca777e91d0b0b7fc4b180e5e19f0162c5d3146b5ac5ac820781209c455d195f17d541d6916f56838f7be838ac0293cdb63f28529df3fc7d54475062b90d3034c2583b00c942102f82b9553c1120891b77d61b8c86ba21b4a78f772c4049869b56442d33c642a5c0ad167747807d5f6105ccc21af8e06c85031a2a73ada9d59453017f131b55c1e0176ee29b021b7933606c5425078b7b49cfa99f24b21818e78a0e856747e4a7888a3d1313624af81c75eca6c3c43238bb078b94c2a9c57f0c4c66ec5b59ab93b73a1000630aaa28a79415320bcc8a96195934c9f14d5dc41cb70c1104a63f5fa29953495abf71b9359563f16c7bd6bc319ed7898fd00cb580902f2196b45311962cc17a9a9f002a916d9bbc1a452bd3e6a48ca05e50ab35bd828cfe66b483e96ca1d917001b46374c41c2d079fdd8257bc339a6e13a7fa2c0948056f6553803d10fc9f1c87725230ba3713903193f200a9851a78b61534b5a949d140c9b457ec66769c6544d79f0850c4cc8e4b78eae0b260dfc9cf0848e4e09cf52047d62bb8e7e6231f4ba49859b1dedbca0d8832bd23789c6fbc40d61485e5a951de68639e07e624a72395b9e25b603acb330a37b998b7a9ab3f973003c15624c6abce84050fc0166924a397708c12308c578105c1457de7cb41dd609c0c3333be5b9c3b93e2776aa0ab3a4054c98789a4bf419bcb6eb914c2179bae02b462b1126a3a28840b9e7170618c20e8527993623cd0c776e54f8b4eb237b4f8c075fa2175f11be86e2bdf3b9b9dff89b7534134620116e0ac025f6707b00b5c743aae144241b935ba61827909b591b44cb6f36107ef81a214c6aa5b9b3e1f441c774cb7102310c4031e0e4a213a8c1f1593906a0424d657cda7c10c1354b0d5a83d2cb9d0407073fa77abe480854c953eedc6cb06c75695665b92873552cc053a9bba0c99aaf970753299db3528276b56feb8a5bbf373d13c20c2f22ae07e9542206b296f3b101d07a3bd1517d9eb8db21e1f18e6da63acfce1e0dc597cef3abfc7d0aea99da67ce6c8abcf3ec4d93505d3be02c039e5a12538e5e59adb5a5d709b9b342938dfd5a08f656a6eb8cd20679930a31caa6a6331c4b133a6838c223ef9f769f6246" +}, +{ + "dz" : "447f6076a627bbc5ad7773fbfeb14b4ba9ac43a0f8b99fb6dcd5e452aa3c47ec20a7237801f470fcc2bd9fd7bea8322859b850f7882d362947432913dd068c01", + "pk" : "e078c4a3954f40a2697092bbe4460f27c4ce6886628382606f395b55d1a29939a2f754a0b82968d3c865f30066c5e21e3e2839416570f5b54f24d347e2e10169571a3935307a4918b5d68ddfea58a90382e70012911729238a4919a7531242228995215fcc96ce8c1970faa902f79c7a7207a93613de0066c384786f5913b24040e6b4b48b6b679e5538f953540c25c18402be1c58762fe8bcee6a1e58d93b21165f95895afefba1f735b11fb7bbfcb40d3d54ba24ca7ef507973aab9017b66a3e271f980462752137d9ab0d1937226129bf48f68b700021b2fabe81573e49fc17819bbe46858b5c58b4ca7c83a57398a667b09c681b990b648e96ce79b72104b13e97611ee8528c9f64c376eb04925ba46d3c8ab859304ce17b9435309726045de17d8a7cae32aa9c80e1aa4058cff89010dfe22daf0a002a905f945accd2f9225739aff1863006b46f9ecba5243bc48ed1184bb9a57ae26c8cda147cacbb4a031112279dbe727fa6c467ead943269ab1e3c9657c19ba0b648c9d4a48c6163a0a79954c0c7ec63529cb8a65c851c39840bb1a7c584104016f16b43da179189343c3276bfeb5839d6622e684b421526d69517ad57b67494bca6db58cf6c95266170ddd9455a6867de052adc8909790659fa0dc0a1d011487b16a1e08bc82b22aa9444f123632ec889719e754993ac8319a72ee83a988a2c77d28acd4bb5ebc486c33b0af1d67a84a349480fbb2b0b252e8749401d8488df52356a75ba2883090dcb757451c9956888b43806431bf9ed956e34806bafc15fcb1cf2b45729eea12a6580c6d1c366a76187fc20fae7657f560973838abaa510fad13c59c5baf4773188859809d1bcdba937845759c9af40dd2f14bd7dc48028a77ff4165f2204fb3b0b9f585061616ca4fc405a0c8533c344334e511053a548ee86998e9094863b8bdc02aaf6bbc916481ac9337acbac10d90794ec239268aa376157b1955379d30c2cb4927a8077cba969ac398bc8521450efcc7e1cc617e69a66fd16b771a2497d14e35a61919dc129844379a314821c333a2f4443651a4cff234a3dcabad32610f5b54d138065d8a5a81fc5068c5060af125265cbc42c580f47b9fbda72a893329999958b026c5661ba116346ccd86633e0a603b48c8acab78662162a9f11c4349c5235a5ac46546b16b25e355b4408456f7339122b67bb48334836214e431955e979244c8c7864ba189eb24c818c15417cac84682f719c9bdd8479be5c643d937605383c6a9514118498d5b4e81d5b74a063fb53cc19a20a9cfa26e479339b988c40918c192435db1a3b2a7c6046376b97aca7a9bbb30335a0e8fd237f8833e89e41a1c67b8aa9b0d539486b1855b9fbb53b5103ab2d19606165acaa588b9d14a4e6a7823800d8a9334ff7456e75aabb81408b791c9c6bc3b5829c1ab241e8d310bb7b15a5b24123a2c691ef1b5dd80640a7b94892aa1ad7300797a3de52a66c794426230640b303e71f0b93654708bd81f706b0f71757c08fcc591525bb6c9a57777bf1bda0d81b4922a56586d21b04daa2684e14ee8c0cd542824205b2bac3c1232f2bd37109d621a25cf570573465a706583da17c39ff3ad13826b6d5988158a1602a361d7a2f86a9219450ff713e184c0f6ea4146b79b03e5ee3454a79f", + "sk" : "1fe26897d8a471a69851d6bc3e69088da81dd3534ab410b3a3f55c8cf805341651896a61c919668c97b2db572d15b2799236545a4675d37c1ae6d96a8f640cdac13c66c98e849abaef549ab109085f0190bb5315aad870867630e41133087888231a08be1baffbc0a74cfb84f24ca020c401d79a6e615604fb1bc80b2410a0e9b251ac2714011702717f6ffb2e1a7a3ddab5acf7d3211091471fa02f0838cc14d281850465a6a51e2cb6a5aa8a9560461ab67338b30c43eb49bd5221c26d366b21db0e6f4194edd60ad499052b192c2202b6c7962e6541a8e124410bf0b4ce9964dfb153576960b1ac01966552f8230cb3fb267f57650c783f6765c4c396a864d1762df70ff2f67165a6bae7e8b6c20a63a3668b7fd76160dc0cefd968ceabc3827cb2fc191df6e1472f27015c65a222b0a007a33993ac3270ec3aafe4c869ea2985088269323829bc0304d0c21569a3a14095939224a40c9922f77bc59734b58385be242cc8329fd9a4117e38a72019301bf8c55082186b84724d541529c79d8dc1a54b2cc3b3512bac4127f683b5fb1ccf6d10539eab9c8ab4b875733a903acae2b725854934b4b28f09e966e8e987077076ba508432f02f17322cded648b206020f94171d8b82b413b7cb3573197c83c50b1387eb6caed48c26e33d8cac079fa55ad0c83fb7c045d640482c805b5845ba5a3767098c7058e43542f19e74d9758a025b008440b07a19a9fa9b24b8a4550a8a925bac6f60476ca877a459b60e285feb8a86458029cc31c3643a1949208491ec529e566d9e2b1118086cac7252740098fcd318f2b319a89ab1ea4657f06a5034ea2e4e2a9db6f06304fc27d6002f6ddcb487777d18b7c8994cbb1305a516383667c29a8144be189697e36b068b2b6e2556794e53526388ba53e10acc0373926898fbf1136420c50c01d063b7ba87233b312792b031ac0d8668afb43ef651495663263ccb99e03540015c0a9eb7b88bc888877a766f15c0f28b947aab9d74c212f80c78a6bccc9ec78c97bb5242e25790305b9c222373536c481137ffe5b9903196c85c4ea7620b854170aef2173e69af57ec93aa20168bb679140a4bb668719d8773a1c7bca0415e645006bdf7967ffb55717199dca172f70976a9f1ce41db56e088676377acecc04f7be426a57c71efa95fea2366562b61945a56e7502782c41e7ef46bc4427acaab204a8a8bd78c05471301ca4134d727bb025411e9836d14b2c7117b4e135401348697c0c66a8ac13476d67791247d97d34657514fc5829dede57c05a6404d8044dc2aa84a26bafe9bce4c1aaa8de6a43c007cc1f203d814ca06f0a4643c2b5a650e2061c1a5b7cb30684dcdab80ef3c03eb2a6a52b0c531305486a03c95aa0473a3cd7fa9861c8a9feff0c15e66094639ae7db30863a35730db258bc69b7cbb915918ce42b873c944a7907b7bc014357ae981861c36a1600050e019711360a4e227f5fa7cd54742e111028372057e982e4be277a2728b4e381333902eea825b943128b897c74c109475b3a70312c1830c7ccad8a6f60020149a2a4b843d19daaf10d426a074711b35cbbda9797ab756de92bedb7bb19ba174f7ab74aaf115cdaaab7d09c8e078c4a3954f40a2697092bbe4460f27c4ce6886628382606f395b55d1a29939a2f754a0b82968d3c865f30066c5e21e3e2839416570f5b54f24d347e2e10169571a3935307a4918b5d68ddfea58a90382e70012911729238a4919a7531242228995215fcc96ce8c1970faa902f79c7a7207a93613de0066c384786f5913b24040e6b4b48b6b679e5538f953540c25c18402be1c58762fe8bcee6a1e58d93b21165f95895afefba1f735b11fb7bbfcb40d3d54ba24ca7ef507973aab9017b66a3e271f980462752137d9ab0d1937226129bf48f68b700021b2fabe81573e49fc17819bbe46858b5c58b4ca7c83a57398a667b09c681b990b648e96ce79b72104b13e97611ee8528c9f64c376eb04925ba46d3c8ab859304ce17b9435309726045de17d8a7cae32aa9c80e1aa4058cff89010dfe22daf0a002a905f945accd2f9225739aff1863006b46f9ecba5243bc48ed1184bb9a57ae26c8cda147cacbb4a031112279dbe727fa6c467ead943269ab1e3c9657c19ba0b648c9d4a48c6163a0a79954c0c7ec63529cb8a65c851c39840bb1a7c584104016f16b43da179189343c3276bfeb5839d6622e684b421526d69517ad57b67494bca6db58cf6c95266170ddd9455a6867de052adc8909790659fa0dc0a1d011487b16a1e08bc82b22aa9444f123632ec889719e754993ac8319a72ee83a988a2c77d28acd4bb5ebc486c33b0af1d67a84a349480fbb2b0b252e8749401d8488df52356a75ba2883090dcb757451c9956888b43806431bf9ed956e34806bafc15fcb1cf2b45729eea12a6580c6d1c366a76187fc20fae7657f560973838abaa510fad13c59c5baf4773188859809d1bcdba937845759c9af40dd2f14bd7dc48028a77ff4165f2204fb3b0b9f585061616ca4fc405a0c8533c344334e511053a548ee86998e9094863b8bdc02aaf6bbc916481ac9337acbac10d90794ec239268aa376157b1955379d30c2cb4927a8077cba969ac398bc8521450efcc7e1cc617e69a66fd16b771a2497d14e35a61919dc129844379a314821c333a2f4443651a4cff234a3dcabad32610f5b54d138065d8a5a81fc5068c5060af125265cbc42c580f47b9fbda72a893329999958b026c5661ba116346ccd86633e0a603b48c8acab78662162a9f11c4349c5235a5ac46546b16b25e355b4408456f7339122b67bb48334836214e431955e979244c8c7864ba189eb24c818c15417cac84682f719c9bdd8479be5c643d937605383c6a9514118498d5b4e81d5b74a063fb53cc19a20a9cfa26e479339b988c40918c192435db1a3b2a7c6046376b97aca7a9bbb30335a0e8fd237f8833e89e41a1c67b8aa9b0d539486b1855b9fbb53b5103ab2d19606165acaa588b9d14a4e6a7823800d8a9334ff7456e75aabb81408b791c9c6bc3b5829c1ab241e8d310bb7b15a5b24123a2c691ef1b5dd80640a7b94892aa1ad7300797a3de52a66c794426230640b303e71f0b93654708bd81f706b0f71757c08fcc591525bb6c9a57777bf1bda0d81b4922a56586d21b04daa2684e14ee8c0cd542824205b2bac3c1232f2bd37109d621a25cf570573465a706583da17c39ff3ad13826b6d5988158a1602a361d7a2f86a9219450ff713e184c0f6ea4146b79b03e5ee3454a79f7fe853da745a27a1462668bb66c4348b7f4bf25c70527b360b2fd104cda48fe520a7237801f470fcc2bd9fd7bea8322859b850f7882d362947432913dd068c01" +}, +{ + "dz" : "2d5df64d62cb07fe630310bb801c658dbf3d97993e68626745de39d37fbfc2b27b534537addaba4ecf14f02ab317d36cb9f0f50222ced7cf029dff8a0d3d2fd9", + "pk" : "a4163313f3cf10a65afbe14a738352fd20b1931827758905dc32c20cf8adf6c081009ca396f270b23a5f26117862a13cb00b65f5a2850e8252053255b8232626b5bdcfe44e95c0b7b5b09802165b5310122a434c5456136cb3a77c3c7c23fc61271550cf15122fea612600aa722c8646a6760ee18ad6028850fa36b82156c09429fa188db2ec3dc229a78f92112b4357d3681aeb19779f1785195b65469c6d3af60ff063562817c4587225a10c8e9fd56c4353711f287469b87cb533b99df46bfbca625c4601aa86459b27778c7200f6a12ac8e8bc078231a37c87400a7429c476ddf7516fa4b7e27841abacceb3c24e92158eb168cd3dfc48ade061b2c02c33b2a33b59ac45a77a439371f3683aeb6a18b107bc34e7785e4146b3f668d9565cb32a23bea6af6daaae79b39a8f725e61f1355c6965d0ba0cf8da22ace189cfd0652213501b3b5f791061ca929e2fd057f357bfaa4047c28577d2105be1616044a6383ff9a087f4754926338e486cc3e76511c7946a02893d058f7100c98bf0af514a47a7630e6e2564b5459d3b52bac6884fc32c7961a34df387ab85c07965786d6bb731af75742147304a5cac936797ba658fdb88c1939c78565914ddb0334fa291fa3182e31a36d6c159ac637a0d3a37098569a009911f54b13efc46e403ba4bf0bf59499cac06c848754903a7b8a1b7549a13b2de5a2cb106a21a3a58d1d71ba30700d74243b1030258294ee022037ff9c7e752cf0fc60f582b6310d4637309ccaa3940e6617b72c0b0217924febb6f971a56a979212a452796a217909547598330557a9309161fbf7c59004d7b3a88a2c3066534153d99ac87dc5918401b860c1b4d5e763440389290d2b656c97cb9784b201a90553acceaca0f22b17852f391ded7094225053f88b6578678f178067ac944f1fb6c2e99abd946953a49b059babeae527408f520844323d9496e51e88f0899857a07b8bf8586ac7a8d13579ca934161d10c08e3b400f084cbe9c6f21e29523c41bac2187b7470f752b55addc6250c08338bac7fd0879620023899041576191b502c736115e65977de34c740c75a5c5f54ae4fa07a2943a7f5a3b8018461445c3ce938579680b68fab41ea2bb26e40eeb13ac84fc3a38b78dd66186558426cf59a1dd4958427bbcbbc13037c577b0e0551238a67f596cd0a2627965216bf733fe88718d64725ffa4b6e73077a37a4585159c887b2a2f5077d1b457c06102cdab7a0e5752263cacf7914ddf836b0e1a95ac4b941388bf7c5bd62f616726100f448001e1c6e4100bbb922b265942bcf37966a5b61ba4957dd02c484413084985d5b22b37964b5f66c11b27c25af757f08cb8ba3b3115a6839483454239bb9d0a1b6b1bcbba5060c3ae47fd0476107919281a508e0606b4ab51ae12b0866c21ca994817b87244ae55222c0807b02581856936ec0ca25e08c7e604e1f1379914702a9e209d7796ca44879a363cce71a0d9850c8ae8596e9b7157a71052602cdbf1c2ba113341fb8b612f114a82c6bb106c703603eddf80ed634be616884b9f2bb271240ab48126a40cf7c0958e0c5bb4f73185cb41dca542888720f8f930a66a66bb9c79acda38a22249f5240a5db0067a23151a6f02abac2477574d9b5d49ed6c25fc46576ca327d614492eebb", + "sk" : "6206ad862474f8463a601909e145bb7b68c12772311f5474c295a7bcb93ee331a5a891cce2a69af9e0820fc9ab484a6ca985090035970a587e860126801a87342cb627e769fb9badf4c075aa78cbb127ab20f34d22cc4299abafae49812a5190b95182eb635e844a5111490d754c0674c7a39d8b3323cb1bfd04a0430893b013555d253aa2739ab64808ee6c6b59572f40e3c1e42224c3b20648513172a7895a52b633f63292c04f3e61b25d064ed4834f854c932a897b7f093cc4ac98a22366b184480ba746968523c91a8a0e0980aa8a1d1dd3401966b27b7838ba246ea90432cd723793271cfbb4719e60912df891d7e4a9a63781e8b1bafb40431866ad153bc067d871ed8bb096152bfc1b731153711bb40876e835033861cf981b4de14c24f2542f84c94ea39cd757ac011c8fc5785a9021626f476df9cb687894582348c0ce00af7cd3bb01685f5cd73304011e1b989b1a509660301217130302705c4fb868c1123e0cd633514b4648a347557a9147f44ce88bcf8db4c8e18c826d34ac25c7b5582b3d1d552f2ae28174d0a84b5605d909a6051258d11a941378377f457700e2c8b3901ec33710d179639ae04d661aaa9b3caae38972dd5075d7ca40ff783bf79c1ff4e4ba037c16e3839b76b88ede1779d025841072cb21520f18ecb6e0c9bfdc0379ffa6c074a12c9482ae39b3b51c1c7d02b72d3b844e4d80a8ca3663dc7016e49b0fd686ce826205e463bc164b59bab5cb2ba3b973f7750e61a8697bb1368bcc98aa3d670b7943d7ae89e64f006783e8b67d0142bfdbe4a335a564357202d57566a8d97ae750bd61021cfc9b4fcfaa38f7b6cb55ca53f16b0edfb36ffc1bc4c347c9deb19e75873f2b41613b98c73d346e0ae0aedc0a5154342afa6a1872a73e1ef77f5d34b49f369c4529587c391fe885b0c50ca38f7227adc980df096254374553672992f84e7fc55712a1234fda91c4eb8172128e5c012d75e4ccb0b440afd1787f3a26e0230fe8a35a5c76515e4c4c6b335e60a0b417cc43109c45e6ba639a84377c204adffc0736144d43a005bd35434737c301ec15564b00ff6b8f8b83bf2d99b72a71419b83a39bc3a637276125e9037dd4741f515a41e71dfb75c94e29339a235107f3564e939828ca499986230312caf91045fd6363c9dbb7a822027fba5607dc12b4f19257e1c8832b95b537583fa6642593122eb2c0a25334da883160b9cdaf4776ff14cbe2aa7d28bc271ca7985c1b1f9324042272c1590b737b5963b8894d58670e535775e7c3bea20628b3292a43407cde31b0718678be28b05c11811e1b0016c456d63163549522ea65673e188a27a39783119d70106e9f35b437aa65cc685ae0a200a3b225516b9fd0f4687f3485cec27a7be012766ab18783cc77274c6487bd0ac369ca29a05aa0cd5ff8ac68e7b582392800fcc4ada35e2974bb1da5254ef6af37e487100b4500f82f5c76a14542c9198ac57d699f26005c37b94e7faa5ebd5c62f562351b58bdcfc15199849b33a1be9afb67cdfcb4a201a29c3b61274349f82916c9dbb38a206d81dc5036c51f70293dd51562cee893fc80b7e0abcd5a625470436af7cb7c3cb76309490df6254297f2bda4163313f3cf10a65afbe14a738352fd20b1931827758905dc32c20cf8adf6c081009ca396f270b23a5f26117862a13cb00b65f5a2850e8252053255b8232626b5bdcfe44e95c0b7b5b09802165b5310122a434c5456136cb3a77c3c7c23fc61271550cf15122fea612600aa722c8646a6760ee18ad6028850fa36b82156c09429fa188db2ec3dc229a78f92112b4357d3681aeb19779f1785195b65469c6d3af60ff063562817c4587225a10c8e9fd56c4353711f287469b87cb533b99df46bfbca625c4601aa86459b27778c7200f6a12ac8e8bc078231a37c87400a7429c476ddf7516fa4b7e27841abacceb3c24e92158eb168cd3dfc48ade061b2c02c33b2a33b59ac45a77a439371f3683aeb6a18b107bc34e7785e4146b3f668d9565cb32a23bea6af6daaae79b39a8f725e61f1355c6965d0ba0cf8da22ace189cfd0652213501b3b5f791061ca929e2fd057f357bfaa4047c28577d2105be1616044a6383ff9a087f4754926338e486cc3e76511c7946a02893d058f7100c98bf0af514a47a7630e6e2564b5459d3b52bac6884fc32c7961a34df387ab85c07965786d6bb731af75742147304a5cac936797ba658fdb88c1939c78565914ddb0334fa291fa3182e31a36d6c159ac637a0d3a37098569a009911f54b13efc46e403ba4bf0bf59499cac06c848754903a7b8a1b7549a13b2de5a2cb106a21a3a58d1d71ba30700d74243b1030258294ee022037ff9c7e752cf0fc60f582b6310d4637309ccaa3940e6617b72c0b0217924febb6f971a56a979212a452796a217909547598330557a9309161fbf7c59004d7b3a88a2c3066534153d99ac87dc5918401b860c1b4d5e763440389290d2b656c97cb9784b201a90553acceaca0f22b17852f391ded7094225053f88b6578678f178067ac944f1fb6c2e99abd946953a49b059babeae527408f520844323d9496e51e88f0899857a07b8bf8586ac7a8d13579ca934161d10c08e3b400f084cbe9c6f21e29523c41bac2187b7470f752b55addc6250c08338bac7fd0879620023899041576191b502c736115e65977de34c740c75a5c5f54ae4fa07a2943a7f5a3b8018461445c3ce938579680b68fab41ea2bb26e40eeb13ac84fc3a38b78dd66186558426cf59a1dd4958427bbcbbc13037c577b0e0551238a67f596cd0a2627965216bf733fe88718d64725ffa4b6e73077a37a4585159c887b2a2f5077d1b457c06102cdab7a0e5752263cacf7914ddf836b0e1a95ac4b941388bf7c5bd62f616726100f448001e1c6e4100bbb922b265942bcf37966a5b61ba4957dd02c484413084985d5b22b37964b5f66c11b27c25af757f08cb8ba3b3115a6839483454239bb9d0a1b6b1bcbba5060c3ae47fd0476107919281a508e0606b4ab51ae12b0866c21ca994817b87244ae55222c0807b02581856936ec0ca25e08c7e604e1f1379914702a9e209d7796ca44879a363cce71a0d9850c8ae8596e9b7157a71052602cdbf1c2ba113341fb8b612f114a82c6bb106c703603eddf80ed634be616884b9f2bb271240ab48126a40cf7c0958e0c5bb4f73185cb41dca542888720f8f930a66a66bb9c79acda38a22249f5240a5db0067a23151a6f02abac2477574d9b5d49ed6c25fc46576ca327d614492eebb65297f711f12a5ff123e6de59d1f16878e93a31612015fb961bc572f3e999cea7b534537addaba4ecf14f02ab317d36cb9f0f50222ced7cf029dff8a0d3d2fd9" +}, +{ + "dz" : "25056d1b8113bb362dd979d98643d7a7ac9c4f95994c0ba060609b6d07002ff3f48a9254dd40b117941fa35a66bb50296327b725525deef70e128ca8045ec451", + "pk" : "25b2ce04e31b6f647abde39d7b1cb988c37f2ab219c67839064481c2539f7c947a5187a850f61ba075a002e4621ebc290855c9e75818e3a99da9e50522976372ea0e6e201f8cf3c49e4a86c503c38ab764b2f45bfd1718f6b5c0d2e66181045be2a2a8a1e10becb8a6bae9569f42654187a9d9b24c8214abf933063526804d0998b89c884b1055a56cae82557455f3a47c677e8e262fe9569aca0c5b1c0cbbf768302099a4cf3960f9d432a0865031e2b65ddaa43e00aae05aa39152256061021669b8f2ba6bb31045e7e539830095216a846aa39d5b16bf69e152aa227c61287137e2b29d3931c6211510ea33325b2ecd20a1bbab9d30a7ad9bf83e3058520606641dd23b092831d29022542513070c8626a42386c8177c7bc1ffe5754ef5b3a2c41f91f1463b7b068816b058da287b4ac2ad82191d061630337d296a08a02030174a219c143224b4b1aa1324feb23e7d52ccdc757929342ebcc02c9a080aaff12763894928a16c1f7830d7dcb2ebd77837d97011001d83f3512f9578efac3ce1c0a17da13b375c44ac8c32e616aef48339c19a4f379c216feb9672c20d78262fa99887f92324bf667502517cd42b340b51ac0d0c71c2ca5d357554eed04c1206baee66707b10bf52a424fc7567ca023b605a0e160aba5be5aff753983b19938205188fb87a867b6cea58112a3323c2ec23a92a1c16b48f8cc7bc55c5b18a33b67580cd9383275e7b53d053aed3f41f1a74859f3536a3c07832d4b64d6a9bd591c4a1901c46490efd73c9aaec1466528bfda0af55fb7a28f4af2c332de8024f87567e1ef87dbf3061ad29490c658b8367b0b911ba3c3c91e48189c8bb1cf3a229146cb537958bc1b427add62348ba0b54718753acb2ec3a0783c58c8b6b1023580a3417cc08745feb9b3f19397fda09002cb019be30a8d3781c936847d5c7c5a8e9a7b5d8c18bc5877ed4a8d787a7b11a0464440da596a4250308398aa9cd482e0f685703058987b63e21c530b3b5367654bc30b86fe6f0645e328714fbcc0f666bb8eb28d7279339f622cb89b813c72dcf5944ecf68e4ce422744abe30261ed3e127118cbdc1d224e538b48d441359d673470978bd4b5913b6cf557760389b3f6991344d4b622c7a332239a50626ce553a6e0677bdeea96a3efa72931b6921a23be5cbba9f51166be80a542b5f341866f78225d50a608e95bdbaf02a599b7a2441537f5124b0d5150a19a7de9ac2de2460b80884512c970e7c700aa259982bbda59773c415844b272dc45807f9d641c9443717c61bf9fa9201568868655e0f791910b5077cb77a93e40b85211f9953014d953fd3f8780189840af9ae60da1fc6c48d19d88dfc689a8421c28f569bfc5184ed6a66a50202bcb51425202b6428187f0c7a92d2ad1e7a35d3bc7f7d7664cfe9765d217f766a3c068149964b7c9bdb328a7821a9646ad53a8bded2912c3c714ec81190c966c703a5b9b6bc74c89e2e0635d614624c5371efc4099c00576d05aa5552b862455fd14641e1e80f4b468cfca6cc37e032079617c6cc3c7cc68bc8fbb3329c9e28c1caa811cd6b8bcde9ab6ddfcc98f9534f3d7aaff2a508b3237070c39e22b43a424b2af4ea59c9920d24d6cda3885cad8cbc7a2e3b82554fefde1a383c558139f9e1808c824829ab0e", + "sk" : "a8a66e47b025073a79d8e2817c64306dfb4da1390d93060be758ac111030fc2c3bf6147c63981ce6399f31e5941f65b96c13c9b09a0ee6a08c9171ab262a400a926a628b8ccb307f9bdc7eaa06424c071bc7105637e90421eb1c8db616ceb2972ae38cae319c3b181686a9adbea05305b258a2a2a965630beb687fb2f47b9a4a770d1370781b2526ca326261cdee50ca3ee802a9d5b8e1944b67fb4db24753756b9eb4289e81f1cdb1684c00c58c9977892eb7ca78b205678a352d3a7592e3970a124c9aec88b521bc26a368db678a45682d4208b9e1b099c5cb30506371c8a44b2113931e1bc1fd88a43c91b650c312c733c913835f7118b898a27b7a4a75f927a03fd914ce627d9e156b8153584f12b753e62a7148bb83f83f474985701c6d051110cf270da672a5cc72c85f560aa7b91d99539224159466387de5d39f9254b46735a0c30ac40f2b1a180a8ee30bacbd09cb45d52a4bb8336c269a78746f6a337f44604de7b76690d23e71fa307c315c377555dce8b26a945baf1225df553f518aa453b823fb618daee2aa5cf0a60414af7cf39aefa3a2fa2944d139869ffa51dc115e2ffaa1abc7438b776a7b2a869d03b05aa0238903008372a3975c36d8d6067caa75152a0305b6614c3815a589a332a860a0d1c6ebe2ad2d68b7bfa1687242960f8b8ddfab9b3e851d4d814c94371b4c9b26c3838eadf70daa5abb4952b01a44cf5426b28b4c8c2f66bca49a21e5763501708ac050b1f8d81b4bd0c0a0e5c171372c877c31882005d65580da2b33165b87eebca160c50ee970b8e1567c9ae1132b65a6bd414117eb4d2a458520a55876f17941f38045b117ce004c299208220c16d10c70124529ac8a10980cb481d069bf0319bd990e34b31ccfe87d3252bf51c2687b234246943b248104baa9ba21015ffc92877d550f5e0148c36bca544c1b1f613afed6aad1132a91aa823b1accccc3bd43b94c47b902ceea431abc8ee15aa32c1b3da6a605b0b5b8ca905c7492a9bf137f2805133275bd3cd98cd5453943058a668456e9a334302c5872307ae5db01de5b4808d477eed39efc00335f31116653cee8f81b6f147d4dd9cccb080c2dbba75b5310c0348ff8ac88e09895422c371358b248509df2d46089a5514f919ff271cb44bb70fb61bb2ed88f6d111dd8b38e155103955836be3812bb255da8db97da862c5a2491892251280c6c9dc779124c08947251f3574d3a5998f8ac8c68881927733fa59816c6aaa629d7893a3313a327a9e2401ffa5c8436f289e167ce68f4a4d232c84c23133d4b7f9b43b7e7ac8060d9bda7d11aa648add452423d91a0c7b3702da16bfed820c0f1420a842a04759f4dd336b1858d0af93b81548f2c8cc8ef064bc554b1cc6cce84968f8bf991649b59f5ab51a6e56375716e1d3074c5849e28f961d75b6f33275819342467e69498a713caec4e78f9b6c1ca774b026703167270e14b4209a9b5353cf6949eaf5c947b458038ab9761f6bcba06785852b78b050d83d70b5c845cce62cca1d8723b472907d6c8482224f10318219c42ee848425787640636a7eeb651e2a2bb5207928a68f65a6318743bf7b43c223549590463ac38acfed84aea13a9025b2ce04e31b6f647abde39d7b1cb988c37f2ab219c67839064481c2539f7c947a5187a850f61ba075a002e4621ebc290855c9e75818e3a99da9e50522976372ea0e6e201f8cf3c49e4a86c503c38ab764b2f45bfd1718f6b5c0d2e66181045be2a2a8a1e10becb8a6bae9569f42654187a9d9b24c8214abf933063526804d0998b89c884b1055a56cae82557455f3a47c677e8e262fe9569aca0c5b1c0cbbf768302099a4cf3960f9d432a0865031e2b65ddaa43e00aae05aa39152256061021669b8f2ba6bb31045e7e539830095216a846aa39d5b16bf69e152aa227c61287137e2b29d3931c6211510ea33325b2ecd20a1bbab9d30a7ad9bf83e3058520606641dd23b092831d29022542513070c8626a42386c8177c7bc1ffe5754ef5b3a2c41f91f1463b7b068816b058da287b4ac2ad82191d061630337d296a08a02030174a219c143224b4b1aa1324feb23e7d52ccdc757929342ebcc02c9a080aaff12763894928a16c1f7830d7dcb2ebd77837d97011001d83f3512f9578efac3ce1c0a17da13b375c44ac8c32e616aef48339c19a4f379c216feb9672c20d78262fa99887f92324bf667502517cd42b340b51ac0d0c71c2ca5d357554eed04c1206baee66707b10bf52a424fc7567ca023b605a0e160aba5be5aff753983b19938205188fb87a867b6cea58112a3323c2ec23a92a1c16b48f8cc7bc55c5b18a33b67580cd9383275e7b53d053aed3f41f1a74859f3536a3c07832d4b64d6a9bd591c4a1901c46490efd73c9aaec1466528bfda0af55fb7a28f4af2c332de8024f87567e1ef87dbf3061ad29490c658b8367b0b911ba3c3c91e48189c8bb1cf3a229146cb537958bc1b427add62348ba0b54718753acb2ec3a0783c58c8b6b1023580a3417cc08745feb9b3f19397fda09002cb019be30a8d3781c936847d5c7c5a8e9a7b5d8c18bc5877ed4a8d787a7b11a0464440da596a4250308398aa9cd482e0f685703058987b63e21c530b3b5367654bc30b86fe6f0645e328714fbcc0f666bb8eb28d7279339f622cb89b813c72dcf5944ecf68e4ce422744abe30261ed3e127118cbdc1d224e538b48d441359d673470978bd4b5913b6cf557760389b3f6991344d4b622c7a332239a50626ce553a6e0677bdeea96a3efa72931b6921a23be5cbba9f51166be80a542b5f341866f78225d50a608e95bdbaf02a599b7a2441537f5124b0d5150a19a7de9ac2de2460b80884512c970e7c700aa259982bbda59773c415844b272dc45807f9d641c9443717c61bf9fa9201568868655e0f791910b5077cb77a93e40b85211f9953014d953fd3f8780189840af9ae60da1fc6c48d19d88dfc689a8421c28f569bfc5184ed6a66a50202bcb51425202b6428187f0c7a92d2ad1e7a35d3bc7f7d7664cfe9765d217f766a3c068149964b7c9bdb328a7821a9646ad53a8bded2912c3c714ec81190c966c703a5b9b6bc74c89e2e0635d614624c5371efc4099c00576d05aa5552b862455fd14641e1e80f4b468cfca6cc37e032079617c6cc3c7cc68bc8fbb3329c9e28c1caa811cd6b8bcde9ab6ddfcc98f9534f3d7aaff2a508b3237070c39e22b43a424b2af4ea59c9920d24d6cda3885cad8cbc7a2e3b82554fefde1a383c558139f9e1808c824829ab0e51634cb33a2bc3fc22ff47b58d7879d703bdd661ad3c290a6d812485ef0ce8fff48a9254dd40b117941fa35a66bb50296327b725525deef70e128ca8045ec451" +}, +{ + "dz" : "e4d34e12982aeeb1d62fd488d9b9e28557ed3429292239fb4f76fa9098009acae6c45c7fc62329b13c8d29844405db8ff6860de474bf727ecd19e54e6e1a141b", + "pk" : "d9f945a651693bcbb0c7a385928129f004263fa16bef92ae400780966a8ae8750e574947cf6a607fa4b3d252c77cd9925ff3a89e762378ebabe4c413af52cf969068d86acb44683222f93bc50bc8f7058def77a3241173222359d25c3a87c817461210c6e4c30d4a428bea8b2d459c4d9c71594c597fb9c3bd17598afa098329bdd15b1c23222f0f39189fa06319bbac7d6866ed7953a2c933b3479235790942d6146a818edfd64227e78bb47168709bc5e490291234929206a3fa1c2ec9359888641d61897927f0440929294439095db0244a05c20f9678b69ca13268622d174a915a210b8908328b162454c1c0c3c36b8acfe4ba2c38e0279ac15898f393f01468eb23a8db1567ede8b493608d3194b2f2f82e91e739479c35a59267a1c84fcc5a1ac12289b3e5845d0c8e9969bba50211ee716774ea03514c3b7359892bd4b8d9db4fd006af53961687e5b0d0fb9e16fcb3764b1b0271b9803019048048cab04e60119c8a140b401cc8c5f5770863b066429e71c8ac3751536dd3cbf4e775c7778c15920849d4b1c1b6ca9ac63d3de47cda549ed009b4ee7759fdd66eb5555b199022846671b1a819aa732a23e6bbd27605b1fb22b1aa71408b2e55bb651c1a676e13a8e9cba2b65b246b6683ab20820ff40eab949eb219851a7c2e1bc1a4cb7b06cf526bff6b1ecb4b5ae4d05dfec33de9504d2eaa4538dc9b9bb39b051ab7d2239ae0b98a34f55474871cf9059e9bf463dda3895e32c27a534737677e40527313ec993144841bc756e9222d756c3c22e56ceaf336e107c3aeec9b1dc71131271392b4a4436a14292aa0e24957534856e30ccff827cb3fdb31aaa086298c59ab71278885308803591513870867a018e61d2705b48210240739ade4c7100210bbbcb524966a9123aac92cd711f5da3b5b614eefdbc39bb36cddf47ecb196840ac84a6c721f1fa2f031c022844a64c4433f414a707992200b857ada964d17c6ceef31186c248adbc83ca2a528738ac567c4c8afbaf8ba57b3f42700dfb8c563b5e494c6679e69acae47a9bb14c79396bfa2593d63224e29cabdd0991101496a0380ac19b759cb0220517aded8371ce74667dc827c1141a233709fc47bd5ea6664c0b6c2182aa9a088df3c92bb5e6047c7b03bd9c4347db41efecb80fbbac90662c0d56b8f91b3f3b7b3417d592994771ec3695e94cc3ac73747f279984b7350ed9b9400201ed35b785f0629225af64b05bb5b6016ea50a8689c9ceaaa234748400db67ef9514e7ba63c683b4f5f6b35869586f0058ba7b9c4bac500a0034bce3b2bda7c5fd5c8ad37c6466a9b877278b7773ac79809222f80eef341236053ad1d0c95862796a9702fd977e820420d611c66163c5cd6c5fdabab7ec96a51bb24328617e375367ee616ecdb46089c6604909d055033d53d828c7f8cd6de0823022babcf521aaa67959c1881161620e397b0a25682cbc805a96a84bb84a9a99acfb6012e2ecc2e5bc1518036e40dbc3347caba399178ca912eb8367c86070833137d1bca5b5b3186ad23c2e76a4cc467d092102ba081494bc7f963a9a6ae575d2c57a38371be5b164adf29f392014d11522535b0173126bfb82721e153e74049c1e170144484dddc2716b4c487aa0398ee9ccd2804df58fab8e2d32ac05bf22a8", + "sk" : "a3854bbdf04e2f617b377ba9d5c1652f27b377bc73f4828fd485afb4c2a7ef05a02b1a1f06a707d68799ba1094f1208e52c9c44ec15580c6599cb244cd2617714c7ea5b07648f91d2230bf35a6910371289dbb7a6329436c4ba502c83633b64f99cc16f6c641ff62254c65511584cbe208a080495762eab49d57253063a50fb45f61544d6ad39a4a0003c4e05d193a59efa80949e1400643962e896c0c9a0c2af30e586c0821388292768538137195009d907853aab7459925498cca238419977c36bbfd326acb9832afd3b46d934255a10a0aa0932a7abff1402da645c0d2cba5d03abc21e0c09f9ca9f28032207a707b21619f7521b9a228386c29a89c53c38b8bd2db9fa4fbabd79421551b6f4e1c489c0a3692e695c73b6f04bbb2be72516ebb523ad794e9101b4cc6b7b16c5f7c2a8e41aabcdddb3f070a5de22a52b80165b3c6872f279ff87ba6eea982bb741a768640d70797724841699c45ab10a522b74c53e55a8a8968afd6ba69bb39eb4489e47343f807424ebb8b4ac8097f43b2bab8cc37990ca185a19c9c6b28dbbdb7822517670ca050ba28d724176a7a3e887bb47bc4dd648b41cbc6b52656405ca5f4e7cb06e64477b2806fa3b52afb3533034cf4772e4a383563aa5a057a6738338f92d9070ec94ab05489e278bc6688a98c2ab7a18ab86397631751c47df75ba27a801497517845b99c0b692afb31c95a78f96267cbec760743cf92140f1ed46f1cd5840d13ce1df028238c941c6044511592d2520188e86690707092eabbe9505cfba46b710b642ff2a87fe7a3d5431773378e5efb378e627058000b4921ab6e6368677492b2eb2ee219ce2e6633286b73863451ca01cbcfa570b806b5d2d5a2fc237c44d0a84c0ac097b8b299446c63a47f2c93a87c95c4b02a3d160bce70125c9073ca35f663e0ec64a189565460b8da009778a8324de7211d072522476418a6c33c17046177359f9bbe5fe72d2ca483bab4bcc05440fcfa67c17c326331b65a04acf68c1ae870208f41c66057c3483c8b2870a3308bb90a5ca085ea8c15891a39a0ac3b09297c99320568504b4284a035be76380e368018394a66be5b2f45dc3ddbe6179ad60860123d55b28d270ba24cc0a49aa5a30bca256d7148ef466b468c06ccc8c2ce439e75953c07013999ab77532b13c9e477905997ffa42f6b28c90f9471ff6b2477e7b311b34c89277803747257791a7325cee25246f656cbf57391037a3e90d74729b16b1a5175eca2871ebc7e4994b3759089e215933144909991550cd812f8f29658852ec11b3b604aa07e47c5db88c98143467ab358db51b5372124af9c983e542e74ba6f273943a646065e603f11395d92ca09f1771adc29c6bc202a9ac159ef356d3934a3a9c073ad459e1de4bb1d81ba30143302013d7043776db346d2239dcc81305386628a2c1b364ccc606804604669ada153ce5a7e6367838a6cbc8971ca750342170509e4124c09846314185387ec47a501a0c5243adb14c39c1105938292f09aa117a5bfb4649f8705696097466f25b32c4a382c877d82d31abdd6b364b936f617b532b29c837a375846bc44635c8d55a5e5dbb44315090602830ad70b50a1cfb92723d9f945a651693bcbb0c7a385928129f004263fa16bef92ae400780966a8ae8750e574947cf6a607fa4b3d252c77cd9925ff3a89e762378ebabe4c413af52cf969068d86acb44683222f93bc50bc8f7058def77a3241173222359d25c3a87c817461210c6e4c30d4a428bea8b2d459c4d9c71594c597fb9c3bd17598afa098329bdd15b1c23222f0f39189fa06319bbac7d6866ed7953a2c933b3479235790942d6146a818edfd64227e78bb47168709bc5e490291234929206a3fa1c2ec9359888641d61897927f0440929294439095db0244a05c20f9678b69ca13268622d174a915a210b8908328b162454c1c0c3c36b8acfe4ba2c38e0279ac15898f393f01468eb23a8db1567ede8b493608d3194b2f2f82e91e739479c35a59267a1c84fcc5a1ac12289b3e5845d0c8e9969bba50211ee716774ea03514c3b7359892bd4b8d9db4fd006af53961687e5b0d0fb9e16fcb3764b1b0271b9803019048048cab04e60119c8a140b401cc8c5f5770863b066429e71c8ac3751536dd3cbf4e775c7778c15920849d4b1c1b6ca9ac63d3de47cda549ed009b4ee7759fdd66eb5555b199022846671b1a819aa732a23e6bbd27605b1fb22b1aa71408b2e55bb651c1a676e13a8e9cba2b65b246b6683ab20820ff40eab949eb219851a7c2e1bc1a4cb7b06cf526bff6b1ecb4b5ae4d05dfec33de9504d2eaa4538dc9b9bb39b051ab7d2239ae0b98a34f55474871cf9059e9bf463dda3895e32c27a534737677e40527313ec993144841bc756e9222d756c3c22e56ceaf336e107c3aeec9b1dc71131271392b4a4436a14292aa0e24957534856e30ccff827cb3fdb31aaa086298c59ab71278885308803591513870867a018e61d2705b48210240739ade4c7100210bbbcb524966a9123aac92cd711f5da3b5b614eefdbc39bb36cddf47ecb196840ac84a6c721f1fa2f031c022844a64c4433f414a707992200b857ada964d17c6ceef31186c248adbc83ca2a528738ac567c4c8afbaf8ba57b3f42700dfb8c563b5e494c6679e69acae47a9bb14c79396bfa2593d63224e29cabdd0991101496a0380ac19b759cb0220517aded8371ce74667dc827c1141a233709fc47bd5ea6664c0b6c2182aa9a088df3c92bb5e6047c7b03bd9c4347db41efecb80fbbac90662c0d56b8f91b3f3b7b3417d592994771ec3695e94cc3ac73747f279984b7350ed9b9400201ed35b785f0629225af64b05bb5b6016ea50a8689c9ceaaa234748400db67ef9514e7ba63c683b4f5f6b35869586f0058ba7b9c4bac500a0034bce3b2bda7c5fd5c8ad37c6466a9b877278b7773ac79809222f80eef341236053ad1d0c95862796a9702fd977e820420d611c66163c5cd6c5fdabab7ec96a51bb24328617e375367ee616ecdb46089c6604909d055033d53d828c7f8cd6de0823022babcf521aaa67959c1881161620e397b0a25682cbc805a96a84bb84a9a99acfb6012e2ecc2e5bc1518036e40dbc3347caba399178ca912eb8367c86070833137d1bca5b5b3186ad23c2e76a4cc467d092102ba081494bc7f963a9a6ae575d2c57a38371be5b164adf29f392014d11522535b0173126bfb82721e153e74049c1e170144484dddc2716b4c487aa0398ee9ccd2804df58fab8e2d32ac05bf22a845cccc2997b502ed631257065214ab9afed11f00ca5c18c92c4d6b917165fd1ce6c45c7fc62329b13c8d29844405db8ff6860de474bf727ecd19e54e6e1a141b" +}, +{ + "dz" : "cd6a99396eb3539ca663a51e42063a3a262cc1c5a5fce1566f0597b52ad9fa325a3407f591791a5db4578b5972093a95bec3b8e70c1d542c9b5c9789729f8922", + "pk" : "698035eda89cff189f730a05dabb3254297561072317010327d4222de388a7e95d8d0076665061705209d59984540471fc61032904b13dac27d520a2b7cb653a68a46623316557500cf4bb6f71ac9b5ca17d45331ff06507d5732829af25417defe7aca7364d99041448328f57d94f1af2572f7468da3b9f2e432064144f0396c1a8d95ce9951530a3b33b092d67590b307944095c50c30762435b76a5dcb3af494a5b112fee2567664a376f3b30c32172059631318821de71ad62b0227d9a91530a5ef2e6c2ecf925fb95302598b722a991e989a1fd198836fb340fe44849ca144545a5a14b46f464078529bb6dac09d148949e91cb0d7912f8701d84aa48ddacbc1aab0a4eb63f9ba41465f03f1bf4b4285cab3e315acd8a3f79c465d1d31fb50670423b278f042442e2b5797483f5a2bd21e83248e3039626006d7124a324281545b8c4356396f413a1fa67577c5d15c638b7d23199aa5343473dd5b45b66f41d451358f74b82a3c18627a60c08513d34e14e3f2a4b13d7332fd8014ff817077b7ee2db80a9c00eb1da79c2193201996036d214ee7b238d82afc2e3a226159ac05240e6683ad00a55a006190a279e116626b4f70fe345594d21a8d54b9017a76d6e2a61b9585bd5e378875ca26ac071d6b1546ee99d716cb8587b7a4e184c8119cb3150611389a8ca0bcd1ab6a7107942769cce08c00174a19305d438a7a475f2a29b28d230a016479f8aa8da24273c15094d3c0e10a8a0f0d3344169b81ca508e6cb662a4ba28c8693b9a27bd46a35acbc27a6b7cf30292064b4aef36bb29909af11d8924ee59af80b5871c2bdf0c53830a360688ab31a94cda3b12c0f61ce341bc0566ca6ad1cae54989aa3083707ea74680ac1fcb254fe3866bc9c7fc33189d3f4299a8a0a985ba3fbd51fbaa45d26aa352eaa710826aab8f600ff8a9554c842657a3cd2d6588f42063e9c08e9955ab7f3ca032b440c7889595a3454025853ba4070f1cd09dc26392b2657c526052373eac80c920c58c3a24827456be174842ed722487c64373b2457836f13c4065dd7b555f3914567cd87426e1196bb03c08c7a77c77d586f18e9603f45b1b9675bc62a4e71f215c3d7071729b0a8e9069f35ab73e55948f9c3e766c4f150394716b198721676495416e54841908cf60148a7104a4df00f21a10fcf508ae9438ba162291e5245afca757ca88ed577057f543921f670b262a0022a4ea4044318a4b1af8a99cdac8e1e550b732157e8ea9194970f786665c817299a7914b4c0b3394a57adb179bd3067897421a09410a34c658daabe6250047bf15b76f826bd371f0c504a2cf9106eca67816a4865b60a87d48ef4753f90132663fb26a5fa08c59394b6770ab13081aa200c79a6802ee826396cc9b3ea9cbfb482d601952752758cb7cd18605a9336735ea2322bc82b7bca773be27f17bb8726a8cfa9070b9aa6a77cdc0b64081cbfbab45c4314f855a953231c6fb6149bab90707b87239c2f7c7103bb9b2532180bc1f16670d90b7b77c6028c4d4bf92195ea54bee1150c25cc363c57f812a0754c9bf66470ad820e12133ebf44810b7318d2a79e5eb98c17c40b0ee10179f1b5b6870f26d27ebfb588f3a0d02e10a041ab4e3b97c35070f0da64f7e0e7076ae69b2ab51a956cfd04f8", + "sk" : "f1cbc95bf8705ee2aea2832134f8b633a20a3f3b6a82a2cc688728de320944ca5e74b42744e4b2bfd860ad6920f671c4ace706ce8903e0eb9f434364d1c09aa3f81303b195e704375adc01242907f12173077384493049a136821ca239c7889fee120aa015813f987611101bbba9115a026c3766264374ac28b0c9c422b844889df150caf94409fbe61f08daa4dc4b6bc3e0c866f82145fb813dc88bee809177b13c2db2ce1c3b8e8c93c8cb86aeff1383adf0afaf5600bfdb178fcb56c899569bd497ae05186f19cd9e6baba7cac85f6317792bc6da6c6222da77b100595e84a2c9a9b9d9b131c9a0514e9c8c59c3b1a12637fff8353d468239358834d11bb0fb0cf6f37a461132f8bb5559b26eb03c0e36872399ca6e5b18a05aeb934516a484116ccd72bf780379d82c396ad39eba5b48dda856e0c82f7b9c4ccc36b20054cf5d1b2f0ea00333527c6e6977a775aa2d58b180609ce57346f9e8a2b686b7d85cb4c58a2bb938b26dbbc6ccd685a6e309838c9fe2e335b74462c2f7c521490ea527af3dbc91034c74e3e94a69e42ffc290920d64f4d662ff436345c06c242749ab140121ae330f254478d851d5f34048c2ab65c8460e8020499c33b4cb9851985817c62282dd49da96064fb2881e18697696960d9a52f409a2e3136368c0c5146ac3ed3b4aa580c143ba22ea9255397203e95c4416161447698bdd6dc462fa5cbfce3933a3cc26b2ccd5295c3e3b30429493244f63b811640f2111e86b54146d59b2e761c793b4920939c88a0cd12c882ef8192fac7bf2af22c08580bb4e20226ab02428731b72a81cdfb654ef9286b73713ecb2c90341e78a8b0d6699f59230b298a658648109b003840a2424aca7d30d7c15d3704fb88c6f66592a04ab803e83eeeb4294b2bb5c6f957b65a6aa8c88a88f5337411404ac7cc76857aeb3ac07ef32d8bf0402cd135969669e2743ce7f8060cb06be964991e797923bb291cac6e78a8c55c65a85d402e2184491e474814086824836405629f0e68cd2f86691df301f00ba2ed971fda2222e1322101130ff1f1a2d870280dac8cb98a29f93870047915146aa8a486afc16cb4d01458edd0b4d5b027fe2a6c4a884ee93a495a5c15af938e5b37aafe655ec6220c0d88557801890e6805c80a3b5e0c395548a19f404a4a6286e041a95506be194a7ab1d7ac21f52932bb3b5f5393e5d5173d2c7c8653b9433344af489f7102199523bb401cc75d80c8ce1162a69627e3a743b3201534c9bc21243961f7011731c1a3e01fa3847cc08ba7d1970e2e70b3f0c4349e707b40bb9c4b5519b8642334a97574529fde05927b25b8c13bae1e456b87d90087551d0c2918a3658e9a9b7dfc105ad9f0cc7a180bd0d0aa5042702afa02fe67801137a1faba5813f2bbcec3b05b1aca701385e159031fe9043199b07ae02682a0861812749294bdd42b6d09330248fb52fee84e98b68b49830508197a06caadb913295095108f2ab2b4854fdbc44742c673d0f55626e726d0ba68ab3508b7304d767b7f868676ddb33c917ba37b5b0c8a831756383235b81e872114278c2ffb29668df706b38153bf7b39a388b9cfb38066177b0695a511b0c9e6c709cf0cad698035eda89cff189f730a05dabb3254297561072317010327d4222de388a7e95d8d0076665061705209d59984540471fc61032904b13dac27d520a2b7cb653a68a46623316557500cf4bb6f71ac9b5ca17d45331ff06507d5732829af25417defe7aca7364d99041448328f57d94f1af2572f7468da3b9f2e432064144f0396c1a8d95ce9951530a3b33b092d67590b307944095c50c30762435b76a5dcb3af494a5b112fee2567664a376f3b30c32172059631318821de71ad62b0227d9a91530a5ef2e6c2ecf925fb95302598b722a991e989a1fd198836fb340fe44849ca144545a5a14b46f464078529bb6dac09d148949e91cb0d7912f8701d84aa48ddacbc1aab0a4eb63f9ba41465f03f1bf4b4285cab3e315acd8a3f79c465d1d31fb50670423b278f042442e2b5797483f5a2bd21e83248e3039626006d7124a324281545b8c4356396f413a1fa67577c5d15c638b7d23199aa5343473dd5b45b66f41d451358f74b82a3c18627a60c08513d34e14e3f2a4b13d7332fd8014ff817077b7ee2db80a9c00eb1da79c2193201996036d214ee7b238d82afc2e3a226159ac05240e6683ad00a55a006190a279e116626b4f70fe345594d21a8d54b9017a76d6e2a61b9585bd5e378875ca26ac071d6b1546ee99d716cb8587b7a4e184c8119cb3150611389a8ca0bcd1ab6a7107942769cce08c00174a19305d438a7a475f2a29b28d230a016479f8aa8da24273c15094d3c0e10a8a0f0d3344169b81ca508e6cb662a4ba28c8693b9a27bd46a35acbc27a6b7cf30292064b4aef36bb29909af11d8924ee59af80b5871c2bdf0c53830a360688ab31a94cda3b12c0f61ce341bc0566ca6ad1cae54989aa3083707ea74680ac1fcb254fe3866bc9c7fc33189d3f4299a8a0a985ba3fbd51fbaa45d26aa352eaa710826aab8f600ff8a9554c842657a3cd2d6588f42063e9c08e9955ab7f3ca032b440c7889595a3454025853ba4070f1cd09dc26392b2657c526052373eac80c920c58c3a24827456be174842ed722487c64373b2457836f13c4065dd7b555f3914567cd87426e1196bb03c08c7a77c77d586f18e9603f45b1b9675bc62a4e71f215c3d7071729b0a8e9069f35ab73e55948f9c3e766c4f150394716b198721676495416e54841908cf60148a7104a4df00f21a10fcf508ae9438ba162291e5245afca757ca88ed577057f543921f670b262a0022a4ea4044318a4b1af8a99cdac8e1e550b732157e8ea9194970f786665c817299a7914b4c0b3394a57adb179bd3067897421a09410a34c658daabe6250047bf15b76f826bd371f0c504a2cf9106eca67816a4865b60a87d48ef4753f90132663fb26a5fa08c59394b6770ab13081aa200c79a6802ee826396cc9b3ea9cbfb482d601952752758cb7cd18605a9336735ea2322bc82b7bca773be27f17bb8726a8cfa9070b9aa6a77cdc0b64081cbfbab45c4314f855a953231c6fb6149bab90707b87239c2f7c7103bb9b2532180bc1f16670d90b7b77c6028c4d4bf92195ea54bee1150c25cc363c57f812a0754c9bf66470ad820e12133ebf44810b7318d2a79e5eb98c17c40b0ee10179f1b5b6870f26d27ebfb588f3a0d02e10a041ab4e3b97c35070f0da64f7e0e7076ae69b2ab51a956cfd04f889560d4e598328f6302a9762bda2b0f29fa8ee34fe48dc4847810fc6f44cc1985a3407f591791a5db4578b5972093a95bec3b8e70c1d542c9b5c9789729f8922" +}, +{ + "dz" : "6c8c53ed6f65e6b2e324b84364e10de42d1c26a106d4d1c99eee79c78586fb55b9402bf02481ce4b27a52e87feb92c4399c7f2988d40e942e7496ad15ad2aa88", + "pk" : "4981b339e1a1368287fc699e4d50bab5ba45320968fb7cbfb358c92e2564944571591211b510a5b044663ffc7deac3546a8aa060537bf36229bacb4c5d918726b5ae7dfaa45f153f329140106a80b3c54eaf273384dc8e47f58e68621f3be905ace09a76ec9839ac471f9404c196587cc95d90166a247029aae0802ae3cf6983355b330bc9c6a4748a6130aa510ca1afdb876ad0d7b2653c3c88079e14d7898ee482f34651b7a238f3f07bdb4989740861d358384a4863c39b8912259bd78653386801d2450cabb6bb7fc287c74b2cb24c5688b66f7952c289eaa5051b938fc833f343c273652e4a1a6ee6c35c8c8131ebb63c82d38046b41343fc0fc660168931c899088c92db171f75b1f691577e09ce56435ab060c8fc084068133cb67cbb0fd36a73d8a21200623ef324256b99b0f60841ba9cda515f62a978881318fda87c95664e4a5755c72026369813dc90c8d6c18f48d61c10e49a7e9449f95492f0e4ae14f6969b654fd39bbac79c7e0b507559d5137d2179b59b21dc60679cf1b455b94208d87514c008898a95747ca9b530164743a6f9f1878f7badff6a4b2023ca367944f288a399c52648f834c28014b0f921ef04127ff4ac656196c034c0db9a7e8ca64109b904b2427fc601732c12241cc32589790e3bb71d924c184edb521d3b090a90ce0b296365ec6911341ad4d8cc7c136c87469f1ff101faf3488f89b52e98b920a659375125b48c403b4ba3175bbc6cc5a2ccc206dcca0440d54c6dac74ce4674e46444dfb4b5070926074c089c28c5cb11cd4c9c715af34aac79644cf2ad471213889c5e7ba92d114150233c673e505376f21dbc999997f43ff9c3b0f8f1b3dec09a4ca3ac581b9192984e43999f0d34aaf32218b02c8aa2f21c579457f204bd18191811e7bd6e4aacca5aa7c6f41fdd192bcd24760a2243034021b192575bf811e1344a25e1629b019564c39b09c88ef9b1ce6761066030bab14ac202bb6a8d858c3fd316c4fa81d21904ae691f6fe7931dbc93afc09f18f3b278e4c453ab5081372c093a9a38ea1622379f56397ec6c47cb7067fef7225c952c262792dda68135e45c3c6cbad23593ffde806fecac55d682fb23839b37186d4a40b83641d9214b7e0490e305807745534de18b9d4bc5eea755cc117b68b7a30f76a9458708249f02dfd59691f0b720f257f1f96cfcc3573c5696ea33017af14a843b81ea58821db21b73a9b80ca187685dac1f8735ea219cd01c6688f5bcaf4611fb3b58ad65b8d7c8ba4ab950bcad9b23d5b2d0b718397e111feb25f1739ccdbdc5c41d943e977aff5209134722dd3d54b923b511661127b284ae9ba0c27f05aacb20181602d9bfb32c3e255e7f48735bab94e515529a9591d51be015a009a9094591c7e07a13c57e636b6e11cf4835a8180895a6581507805a1c7a39ab05633798aebcaae89e37d8d75b4f34c73c2184ffb567069f0b3911943c2060f34f10f835c8233a34b5618501aa36ebf678dae07af9a567ac7143567c92a89a94a0a4abde383706ccc3826a83dfab8ae7165c6c6555bc77a43b5b3b2b590c56ce25e792796283737c6f5b300a0cf06e0060e1634a434793383860d84a76807c2983c57522fe3f988486bc386cb335ab55689d6b449b7a38dbce911f512e4f148aa1567", + "sk" : "61d034b4827c4405b4ce0226038c1e98f42cb587123ec8a44454c38d4407d5fbad7068c373ec34f303a6c4272990957c5803536618bf07418a9397ca03a81eb4490762da41aa5731a8b795e077ca1da336279132d785b9816819f58cad7804bbafa32fc501a5f68981c48b4e06a7088c2784e917b0645cc28116904eebc3417c525cc312a3102db9d97cee85827a1775751ca137e117a217a6fcb4546d946ced119c6b1c45a2282415e9c11d6cb18d22616be6917a38878281bade6241410a42047c156d0c6fc5dc8060d9046fa658727b8e4e045548a5909a9c7139391e058722c7969b0b48c737b3a092082bff215e98d8ae1b09b50c25176b2764bd414d84c57ec41a4b8c04c82eb22a2e52ad200a6e127968c844c8887c014ac99ba8f54067621601121de01c8f5b923fe089584ae181fe8cc353f12390c565332a7bd8953f97e75b2deb83fe53b3aaeb9f4a02ada9401fb339c9bbf09bc6b826d9d0a1ca5a563a8213b8858e91050994472dd9f1c81c831d8096b72f360a65e194c5b758b37528808b9b48a65c9a04b34ccabea12cac24599f2c366646581366b71ac7724f01d833a5e76126617bf7630886e44dede81bbbb44de625bd89e41ae0e28bf897202439c346a438b1a8b518698af80418548664ae3699efb8271e7c2ee995731d7309bedb87c2572a6b805f46654a92d188ce661b9e197203113446cc5fabe73a35b97cb417297988cd02cb8b3e0498130341dff42a85281f667abcebf576fa266f44b2368c926385cbbde21621094c492607cf58227c2a12a8ed79c6a726a7cad81b7e9a50d78417619ab575a3c54bc77f5a80206967029ab92db447b0914168d8b37be0438037e2bb3eeb95221a8db95b07fb252044760832513bb0a7032e493ed529267c278dce0b8d954b4ff0bb62785c6d24328addf3608c50c0b9eb5e3bc685fe198be984735764bea637b4f8a149bcf356d8a57d21b426b736cc8e9b396ac1577f41291f433cbfa04697180f623a6564c8c1f9723896437fe216715a30820db78f7f0a78ad2ac034f701ec129c95dc49d8eb3b7a585aa00046876a7456278bc4a617cf9b8f06e89af742c14de2a7516c65c83bc53c3335df6c00c0b344f79635f232420ec893d9e29a36986defa37403354624607e343b82660b3597eba841b250a15574b009716b4812d5b175b88929d3539e3fa97b3a16644fe6bac74c67db2832a9e8807eb9745ed0afc0025ee199b39ee3954a112ba484b3528838a4605ec659a046b1722da037f9e2b007c895217927d9aa8514ac263a08cde86720cdc012fcc84f7a089ca7c51f4ed71d7c1379fd34c713cb65ce3410214385dd6c91ca1b74a3b24bcd45b5ca097a02359a70008adb82921f7a79b30a8689053f0340453e6b9979c8c522f606eb4c72a30970c09562d9fb00899c2127311ab57653b5833035aab95c61c50680592db86718bc6a5393a96c07907748be2a9c2c2324cb1247876b9c3a53fc2340e32abe72b39ee59e284a62dac56964c721c3d305125a22a94b2b981a5f16f7ceb6a72007c92ee110362dda1deeb28d26c5a5ddb58b4b665f1aabc8a90628abb65e5769194ee98f61ebc4835775efc50cd5136a4981b339e1a1368287fc699e4d50bab5ba45320968fb7cbfb358c92e2564944571591211b510a5b044663ffc7deac3546a8aa060537bf36229bacb4c5d918726b5ae7dfaa45f153f329140106a80b3c54eaf273384dc8e47f58e68621f3be905ace09a76ec9839ac471f9404c196587cc95d90166a247029aae0802ae3cf6983355b330bc9c6a4748a6130aa510ca1afdb876ad0d7b2653c3c88079e14d7898ee482f34651b7a238f3f07bdb4989740861d358384a4863c39b8912259bd78653386801d2450cabb6bb7fc287c74b2cb24c5688b66f7952c289eaa5051b938fc833f343c273652e4a1a6ee6c35c8c8131ebb63c82d38046b41343fc0fc660168931c899088c92db171f75b1f691577e09ce56435ab060c8fc084068133cb67cbb0fd36a73d8a21200623ef324256b99b0f60841ba9cda515f62a978881318fda87c95664e4a5755c72026369813dc90c8d6c18f48d61c10e49a7e9449f95492f0e4ae14f6969b654fd39bbac79c7e0b507559d5137d2179b59b21dc60679cf1b455b94208d87514c008898a95747ca9b530164743a6f9f1878f7badff6a4b2023ca367944f288a399c52648f834c28014b0f921ef04127ff4ac656196c034c0db9a7e8ca64109b904b2427fc601732c12241cc32589790e3bb71d924c184edb521d3b090a90ce0b296365ec6911341ad4d8cc7c136c87469f1ff101faf3488f89b52e98b920a659375125b48c403b4ba3175bbc6cc5a2ccc206dcca0440d54c6dac74ce4674e46444dfb4b5070926074c089c28c5cb11cd4c9c715af34aac79644cf2ad471213889c5e7ba92d114150233c673e505376f21dbc999997f43ff9c3b0f8f1b3dec09a4ca3ac581b9192984e43999f0d34aaf32218b02c8aa2f21c579457f204bd18191811e7bd6e4aacca5aa7c6f41fdd192bcd24760a2243034021b192575bf811e1344a25e1629b019564c39b09c88ef9b1ce6761066030bab14ac202bb6a8d858c3fd316c4fa81d21904ae691f6fe7931dbc93afc09f18f3b278e4c453ab5081372c093a9a38ea1622379f56397ec6c47cb7067fef7225c952c262792dda68135e45c3c6cbad23593ffde806fecac55d682fb23839b37186d4a40b83641d9214b7e0490e305807745534de18b9d4bc5eea755cc117b68b7a30f76a9458708249f02dfd59691f0b720f257f1f96cfcc3573c5696ea33017af14a843b81ea58821db21b73a9b80ca187685dac1f8735ea219cd01c6688f5bcaf4611fb3b58ad65b8d7c8ba4ab950bcad9b23d5b2d0b718397e111feb25f1739ccdbdc5c41d943e977aff5209134722dd3d54b923b511661127b284ae9ba0c27f05aacb20181602d9bfb32c3e255e7f48735bab94e515529a9591d51be015a009a9094591c7e07a13c57e636b6e11cf4835a8180895a6581507805a1c7a39ab05633798aebcaae89e37d8d75b4f34c73c2184ffb567069f0b3911943c2060f34f10f835c8233a34b5618501aa36ebf678dae07af9a567ac7143567c92a89a94a0a4abde383706ccc3826a83dfab8ae7165c6c6555bc77a43b5b3b2b590c56ce25e792796283737c6f5b300a0cf06e0060e1634a434793383860d84a76807c2983c57522fe3f988486bc386cb335ab55689d6b449b7a38dbce911f512e4f148aa1567878025deeed7dab8e62d43c3d2096e4682692537c70ebab9e1561cba88b05ec0b9402bf02481ce4b27a52e87feb92c4399c7f2988d40e942e7496ad15ad2aa88" +}, +{ + "dz" : "2107204cd995f1df14314d5381f8c5440f09a347502e161cffc0a2ec3dcfbc7324c3da70fe850e80aa818301d60c70f3038153866dcd5d179e22db59b8991bb4", + "pk" : "5b19b76208b41eb99b73d2b00d7884ac289c5b4632f8362ed9f238e07a34fd7b3acfc5973070c83e03b9b45c65f8eb64a08b88592b6676db235096694073143ef758fc84c9d3097266b66c9c34a6c5f876779936e345c3a07614e2795e65c0793ef3a22cb65bd06bbd90b391eb425223c2c395674d9841109b6929d353437dd49c7cd50d781cab5850363865689dc8bcf81a80c4269a05060965b80a56081c186a2f4bb00e2e942863fb8e507230c29215c98a78e37201c263783f703b17928f36656b99f9cfe31917f05c25f57063d728a4e2bc652e4193e52877b7310f7260a1985985c26caad60c9e6f01b54be183a7c2ae986ab2a85b33788674dcd42566b406be251837266ebc6261c3b62fff702f10298119d414b580bb4077791b7096a7471595d8659614c878d8097e7437503a7c7e058a3dd295d34ace86b9302b901100adb0e6140cbf44161ab33b9aac34a0dc6f1faba14d259c546c672ebb7f528a010d5585c21c00c4b19980c6490d76083a77b8aaebcaf7917a81b55a6f2a6be7941393d0a9ebd2c549417f38682def039b4944cbc6fc629bb3a3ade353ea2005115a665087c00a4b771ef0490748b370d8b4c4ec37cdd352562a11479597d8035c00824f48805000778a81d6a31a0bb8b6201cbd3149ef96428c79569c5cba273a9bb4a77eef98bfa54ba8267bc42c643c29577b2bea5802ecc038ab70fdb1b23d9272b7ec30cfe1791126a185c40a77c57ec3088822c808ed8b1866068035590460d6a9a00c50db70b19b765e7ca8229e1a66f4fb52d752b515eba35f64097ee85399d78ad4c2cff7935ccd269731ca2b3b3217a22203e3b9438cf0b396fc99b6113cbb883c16869bb114bb1adcc06863738541acc61458ec9ac98df381825ca80ad954562ab931d1bf47a1c45a5c1c72d90cc2d3b4cf6135b8b5454ec4967523ab82e9aabefc89780722b5aa12e47344bfbc8c3426802c77c02195255e71555d9045bac868c7d45c06b6474bba2f40fcbc480112176a83ce361dacf2b386cbcd270456e7563a873c55d752151b76b3fe3c3233c5199011aead401b88b9c36efc295fe03dee6015b1ca00c5bb06dfd2c2848125af903c298c5f74fc4b9937412ac70aacf07fb99488c797287c04335821cbd6475e91d66a7d89c2f67285321442c4e7ce61d0212cc16d74c211ed2a7bd829044ff82491d1cb1746430603a0091110f626804e0b32edb0cc827c8ba7c36f87cbc67cec250f65ad2fc621363bb715557848c5a01b256524271be7b6956b72be644aa0dd33925f64bdd3481615246e95294196d6af1aa5aef6880ce2a609715b50fa7737be749cead7c84977747924bc25792509ca7a931c3ffee7341547913ee695f8144afe83430bd5c96ce61f57610f78d6c64c3c33b468b6f3cac46f29b60f0705ae1a05e5c63d21a62f5dc7208d25a7f0c09d8f77a7a7a03d51d2061fb13d9ae97386fb6da4cb6fea0923937536511ba8ff00ba753897d16b76058a15b5c706121cc792076ebc2ac1ee492a36e65d12d23f6488245e998457d4337a2c62c731afa43085a94892bd30393b1c9fcfb380f9815ea491968d6514b8707551443fcdd5926991599da552acb4a19b6342d309b5027cb88909ffc8c83b1778d8aa46c9d07aa2594a7bfd47cb7ae1", + "sk" : "fa9abdc750b445e2973d9c85b0599a6310583b93c146a61256592258e79664f8a22558cdf55c2ca0240d5b1425b6d6177956afedc12885e12714982872ca17eef52085dc965de960b29972f5828d3410506e34bc54bb2dda3c6a54b5aaa89466cd44afe56388c21b0fd19b744020cf83779359097c3e3086a904376b56814a454935bb53289c1cc4d08198fa6797149c74da0d21f99177093de6dcb8b5579a9641ceaedc74ab8c3e91f2804bfcb94eac1245b53e27bb5907219bbc6b7f61ab3a35a11c3cda544dac262b4289a4a930283b56d5779ee14c62f3a89308f1120e3b34ef87087e0c0ed6b55280031927682870e09db8800467fc82602b95d1f16d680562a2b866380a411546475d1a529db537c1f2b3e3f393c1919d6fb97877297cf2ab346273478afa7ee1044bf4d3353374051e0a4ed2364587e0694920a6cd6abef9f68d00b16c7b2a53d64bbb0645098ba1a9745a15323b2bebd956942090ef2381f8fb747f5964b4ea9a57b22659635dce7c55ff10b7d1c3a76687334542315a05a0931a9a5da734f6b647de025e05e480b5a27fde1116fe03630fdc074f542ab358341ba08fcb79b48cf4273b46c54219c16bc7943887cf451b1fe224bcff9121098a75b2d9b35e71ba2bd94f106800dac689d6002df6ab6528876c39a74d63dc41490077cb94cb243947205841f8b698cc214bc9b2442ab418d7f4a7bec2a793fc6975268a4cb66f304bc7cc142a81f057501c75baf9b3a5f94935b3991c228aa52266ec289ca3333d35dbaf59aab37d659423bc9953656317f48f025076240b15fd145e86db6ea8758b9b265ccab860cf5268aa627c02ab245f466923b91db6a240d1731642229f22946be1ec538a86b7df1a1f4801791ddc487c6acd7fbcbf9f457eedc81cf0a03ca0c15e4524748ff08b7ba020e1c6a4e8e573a6d9c996842f8122bd876c4f6b193f22a68af9111f302b895d2624f992aaff265c996171889661897856b963c92061c4c1db767ecc725056b473753ad6b9046afc82c60a8d7000ccb18b7a3831933eeb9eb02c76e379a5b326c72b0647addc393a6676e6b948bc465578e9b4ccd670bb31a39c5b1aa52c6737433e930b0c2db239ff2a55d8eb649b4aa69b56987e0273d8829db39ac057f89194186dce30b1b20b17f5592c5737cd12ec38bbd228dbf7863ceccffe9587bd485090e45d84c298f811af1925b37a4ace9c751451e326ece073c1503f54984e910ba12fc79f502391784b1bb3b41211e654655868a8d2b5aa4920b9fb2ee7605bd7e8a3aa668f9721212a860dd762113efc1e1ba93a4a10cae185bdf9c80c06ea30757b12768b29a4a3950d9175e15873f104413f22ad79362643599f7d6960f3d662d24255814c2fd7b445d35651ec7c0f873a2a2c255aaac51c41118e4cbcb6f91745150c51cb7a5d5987341c807cf8969c523913b8659dc5120c6d90782d463acc647f16976f641c54ff50bff3dc1194c56c3c71b6bb296f65fc99d20b92662a19a0d8748a90932d498b7e315be3388f87b73ca99611035224fad81792e8c7a3a23dbdf0a44ef9c0ec0c4ea68804d9c9078fc08ccb733287862e01f8712f30388feb2abbd0810cf2485b19b76208b41eb99b73d2b00d7884ac289c5b4632f8362ed9f238e07a34fd7b3acfc5973070c83e03b9b45c65f8eb64a08b88592b6676db235096694073143ef758fc84c9d3097266b66c9c34a6c5f876779936e345c3a07614e2795e65c0793ef3a22cb65bd06bbd90b391eb425223c2c395674d9841109b6929d353437dd49c7cd50d781cab5850363865689dc8bcf81a80c4269a05060965b80a56081c186a2f4bb00e2e942863fb8e507230c29215c98a78e37201c263783f703b17928f36656b99f9cfe31917f05c25f57063d728a4e2bc652e4193e52877b7310f7260a1985985c26caad60c9e6f01b54be183a7c2ae986ab2a85b33788674dcd42566b406be251837266ebc6261c3b62fff702f10298119d414b580bb4077791b7096a7471595d8659614c878d8097e7437503a7c7e058a3dd295d34ace86b9302b901100adb0e6140cbf44161ab33b9aac34a0dc6f1faba14d259c546c672ebb7f528a010d5585c21c00c4b19980c6490d76083a77b8aaebcaf7917a81b55a6f2a6be7941393d0a9ebd2c549417f38682def039b4944cbc6fc629bb3a3ade353ea2005115a665087c00a4b771ef0490748b370d8b4c4ec37cdd352562a11479597d8035c00824f48805000778a81d6a31a0bb8b6201cbd3149ef96428c79569c5cba273a9bb4a77eef98bfa54ba8267bc42c643c29577b2bea5802ecc038ab70fdb1b23d9272b7ec30cfe1791126a185c40a77c57ec3088822c808ed8b1866068035590460d6a9a00c50db70b19b765e7ca8229e1a66f4fb52d752b515eba35f64097ee85399d78ad4c2cff7935ccd269731ca2b3b3217a22203e3b9438cf0b396fc99b6113cbb883c16869bb114bb1adcc06863738541acc61458ec9ac98df381825ca80ad954562ab931d1bf47a1c45a5c1c72d90cc2d3b4cf6135b8b5454ec4967523ab82e9aabefc89780722b5aa12e47344bfbc8c3426802c77c02195255e71555d9045bac868c7d45c06b6474bba2f40fcbc480112176a83ce361dacf2b386cbcd270456e7563a873c55d752151b76b3fe3c3233c5199011aead401b88b9c36efc295fe03dee6015b1ca00c5bb06dfd2c2848125af903c298c5f74fc4b9937412ac70aacf07fb99488c797287c04335821cbd6475e91d66a7d89c2f67285321442c4e7ce61d0212cc16d74c211ed2a7bd829044ff82491d1cb1746430603a0091110f626804e0b32edb0cc827c8ba7c36f87cbc67cec250f65ad2fc621363bb715557848c5a01b256524271be7b6956b72be644aa0dd33925f64bdd3481615246e95294196d6af1aa5aef6880ce2a609715b50fa7737be749cead7c84977747924bc25792509ca7a931c3ffee7341547913ee695f8144afe83430bd5c96ce61f57610f78d6c64c3c33b468b6f3cac46f29b60f0705ae1a05e5c63d21a62f5dc7208d25a7f0c09d8f77a7a7a03d51d2061fb13d9ae97386fb6da4cb6fea0923937536511ba8ff00ba753897d16b76058a15b5c706121cc792076ebc2ac1ee492a36e65d12d23f6488245e998457d4337a2c62c731afa43085a94892bd30393b1c9fcfb380f9815ea491968d6514b8707551443fcdd5926991599da552acb4a19b6342d309b5027cb88909ffc8c83b1778d8aa46c9d07aa2594a7bfd47cb7ae17d30385f988dc748b843b7b7f569e58ccc9215503e1bc2f28f5019fc72fe6d3324c3da70fe850e80aa818301d60c70f3038153866dcd5d179e22db59b8991bb4" +}, +{ + "dz" : "63a925685a8ac5bbd918faa33ac397d1ffbcf99135d9da7c3d6ff7aa4c50af3d3afdb8a246a56ee71465591831c371f2eb87467b0559dedd776ba063ee6d2f93", + "pk" : "3610631d29c37a90908cf2c89d075928ccb3b9558a5453315acabb5a228d0abbb99d63b0294b68594a0a648367fe044e14347073562aeb475c17196a3da38896f2168996ca917a0423614431963b10b5a0d3b228aeca3b26363026d1a5a952b5333cadf79a59b93b5ba484bbe4618b41756a101429cba6407b44a2b001108eb30e92d60c093b4abefb63438c481dfbaf08442d607088ebeac83a950623e057c99cb0f9e31639cacc82852f4cf9bcc83228151b91cdb0423f610552b0c170203c7f2b345443bd7d274ab14cb67b328d914366ea9a220cf46333a41feb5193ded4a5d94c6e0a43bdd6b2a52c3c4c718591f11b32ad64930a638ea9f217e64a9e31526313133c02b5b0cab821544543fe24aefce70927d9248aec2937385c79cb85df91256e176eaf3a239b370d4ef56a90dca3935507a6a86d84b021312bc718662abd432c08bb4dca3614f357321b191a8522ac109a643a5a9a63419be6845e5f5837b6188de0c779fa01430b219470a20da019688802ba8440c60d8727394114db10343fbab0993ac5d967b658b1551a6570f7d9b283445cc278298b4740884ba72b338c45249ab74c84a1435a84c42533a0bfbdd0509d7a3bd0b0635f538ce72645650931dbbc6e2850cd2585214f5cc12f2a2d9c2820d6c0550be79d5276747e2c04bf976705227c842b872e294aff495e06502819c6c92de3622ea968b07c0646dc0301c009fcd5bf7f19a357693e032cc46b4777a1714d41a59bf07721a2490be2e3cc7e4a04fe48a8db361a5cc1390d921325875f80629c2abc4d468a40d9c22911b9bdfc6ba986b9bb7226227dc63d75351fa4613de3654475c5668d651f9f03a386179cad00100b35343f48b7e36a79dbf979cdc734d5855b90128fee10c9bf40acfb67332cc8c9ecc4a3a9a98bd30c708e7a630a0909dc8ba2b1721e42250b83623a1289960e7288758525d4088525ec25511bca906930602b5ee1d127c23205e681c9db3474aa774733100838b2461e45cbd603c3a74122b679cdb9992063e089d5acbf74b03469a3ce7993c6b978313a7a735e75bb94976b3539b4298cc47af58425c24310667b1315baa5937741e35309f1c70cb8c60e06ae1793502a316a276b2e21087305f453d8e99d08730e174159db09324e4cbaa067cb1e766e455a34159465bf1138a285cc386502d698538ac63de2f496b120be468a952b02c5dcfac5a997023b5b3d98691572103e158672eaa0a4e4f44fb6920ffd874f52748a630aa41d188ece499aab324e916079b3bc2427b35896b26b0d2564b2a875881a074706713d326306fc66efaa1b8d4cadc7c85b7ac211c4f61f68a124465397385b2ac7a09686935cde06638f156e6e4670f963ca82950d3207889446be69e2a0d7cabfb16141868a6187b5be7977c354fb27a8c9cb8197565480244bf296692a02701580a2b4ac4772b13a27c869123ac3b6cb6699698c11261f657ffb6c8d78102e0c60c004c0796f319330435a29abaf33dbbb1c566aea10349981409ac31c18aa48631a1f0657116821a2a36c2403870a3787a1e3f36349b3373ae729a859af3163c078c38ef38c464ac5ba1fa8150d9093f97c17106c99c632bc42a5ca0595508bfa7485b23bde8d12ad7bfc9c10c68374b70a4a46655b5a67d1", + "sk" : "26424f439191e67b1755d6893ee31789b8c6985191c9c21c1ec7cb8c990f82ac49b7996b1ef48046f8b3093a36c27cba5c35b7cd733678c10ac06a5108609e47da30a048312f1543b8761714114d37a3c70ee09813e79f37e6402d584f51673f70c5331b89a52e61a51d363a8ad8081df227dd621b20469ded708bb64374e2678424787c57940617980def632a61eba801c1a079517302f3b02db4b136d588e2a41fca2729b541c9bef00940270e257c47103449bbd47eda9bc7a9b508d42076fe7734fa5454228958d7cc932ebaa0f8d12123e7ccfddb039a2a66d6d7a0140c6ce16b9fc0b6a0a3b7a0b50a06d8d397c9020f1dd1b5f4216565dc84e8911102e54b60e88abce7714ad29668f79b7f2a7b09e7c8a92480f30b072ec14e96e77e63342841167afe3421c37c2ff3f25ccad60c652c9831c5519390bf0ee9b2f108104d77145ca4b5245b66db6607afc0141324328d746787ecad7f5a0ffeb50ddde16ee1ab87440389fa0b9c44b75fd26c726773bb8049a77784860558107e069d3d0521c6015093787ac6f263d356130b9a39e5093f62d7b2f8e5411e61a18d44155fbb4d2ba7b09072cf6fe666109ab5fc078eb026490720c82b4990a28406a450268414ad4ff1791b370722258bf103507fb9a09b09bb4373465ce5a1ea263bae6b723036af268700d496724a42539cc9b7f7357cc7b6b33e11937a884dbd30888508bdc442379eb8b3682341b3b4b760a879fc229397e05879b003a06acdf3c5530a7b90013873f47139c2d96e1d7b67427467e64cba2965766603ca30e13f2e357e3e6945cda2906416370cd699b3da77889b63be284ad538269929914092b805aac7e9a04d0275c71df020ffa6002c1703ed674dc5633367bc086ce15e4e61a93de94023b823d1fa29bc6250b92a8a04533987a6bc510bbe84ba7fa1699b077c3a05992ddd52a19aa238b466c2801b3fe9f72335e15ec2342ebebc7694ba68e276719371b933dbba3fa07262870ea9521e95650444845b41258f6ca77915345c0af3718ea09f6ad604c9a4971e618b59551f5ef54e57aa138e52cc03313398c0ae03bb4ee5d36799618955789e80a78bd896aae9e87f2bc0a6b730a02bf82af19c541ca93449b127f883af13713bf5229238b19a216478a4880a7d9b6009719209f69519e5774cf48c8aa20b96e4b0f10a94027819204532a54c48026a5cdd5841e6c8a736cbc99f9caf46b8a90648a854f9c6ae37048c6671c5e8a1b2731019351631829c205959a4b4ae87a4c3234c63e653cb75c92237c4721c66ad05871b22d69f3435baaaf311491394cb1238b899973ef79f9c371f045b4145bc20ddb71d53fb50b25c46e674778fe9069197a9861337edab3de55cc28bcca65b2a5fbe1a2a67197bda012ecad40bc86593a06c833c82aad0b714428296248a8e49304cd3955081ebb2e717b36deaa928c3c09ce1bcab3114627a7886f64d69b206cb7aa8f978c13e84a6c6453efb1328684859ec20a9ff7a560d436977294daf2abc08b78ce10a22d5fccbbdb192d57534ba04c5dfba389c3bbba4f5191ee9ac7a344cd519cd39100012da9afba0bf9a2373ac534ada885cc71322e5b4a4b84c473610631d29c37a90908cf2c89d075928ccb3b9558a5453315acabb5a228d0abbb99d63b0294b68594a0a648367fe044e14347073562aeb475c17196a3da38896f2168996ca917a0423614431963b10b5a0d3b228aeca3b26363026d1a5a952b5333cadf79a59b93b5ba484bbe4618b41756a101429cba6407b44a2b001108eb30e92d60c093b4abefb63438c481dfbaf08442d607088ebeac83a950623e057c99cb0f9e31639cacc82852f4cf9bcc83228151b91cdb0423f610552b0c170203c7f2b345443bd7d274ab14cb67b328d914366ea9a220cf46333a41feb5193ded4a5d94c6e0a43bdd6b2a52c3c4c718591f11b32ad64930a638ea9f217e64a9e31526313133c02b5b0cab821544543fe24aefce70927d9248aec2937385c79cb85df91256e176eaf3a239b370d4ef56a90dca3935507a6a86d84b021312bc718662abd432c08bb4dca3614f357321b191a8522ac109a643a5a9a63419be6845e5f5837b6188de0c779fa01430b219470a20da019688802ba8440c60d8727394114db10343fbab0993ac5d967b658b1551a6570f7d9b283445cc278298b4740884ba72b338c45249ab74c84a1435a84c42533a0bfbdd0509d7a3bd0b0635f538ce72645650931dbbc6e2850cd2585214f5cc12f2a2d9c2820d6c0550be79d5276747e2c04bf976705227c842b872e294aff495e06502819c6c92de3622ea968b07c0646dc0301c009fcd5bf7f19a357693e032cc46b4777a1714d41a59bf07721a2490be2e3cc7e4a04fe48a8db361a5cc1390d921325875f80629c2abc4d468a40d9c22911b9bdfc6ba986b9bb7226227dc63d75351fa4613de3654475c5668d651f9f03a386179cad00100b35343f48b7e36a79dbf979cdc734d5855b90128fee10c9bf40acfb67332cc8c9ecc4a3a9a98bd30c708e7a630a0909dc8ba2b1721e42250b83623a1289960e7288758525d4088525ec25511bca906930602b5ee1d127c23205e681c9db3474aa774733100838b2461e45cbd603c3a74122b679cdb9992063e089d5acbf74b03469a3ce7993c6b978313a7a735e75bb94976b3539b4298cc47af58425c24310667b1315baa5937741e35309f1c70cb8c60e06ae1793502a316a276b2e21087305f453d8e99d08730e174159db09324e4cbaa067cb1e766e455a34159465bf1138a285cc386502d698538ac63de2f496b120be468a952b02c5dcfac5a997023b5b3d98691572103e158672eaa0a4e4f44fb6920ffd874f52748a630aa41d188ece499aab324e916079b3bc2427b35896b26b0d2564b2a875881a074706713d326306fc66efaa1b8d4cadc7c85b7ac211c4f61f68a124465397385b2ac7a09686935cde06638f156e6e4670f963ca82950d3207889446be69e2a0d7cabfb16141868a6187b5be7977c354fb27a8c9cb8197565480244bf296692a02701580a2b4ac4772b13a27c869123ac3b6cb6699698c11261f657ffb6c8d78102e0c60c004c0796f319330435a29abaf33dbbb1c566aea10349981409ac31c18aa48631a1f0657116821a2a36c2403870a3787a1e3f36349b3373ae729a859af3163c078c38ef38c464ac5ba1fa8150d9093f97c17106c99c632bc42a5ca0595508bfa7485b23bde8d12ad7bfc9c10c68374b70a4a46655b5a67d10697d2f9e047e603b8845c9ecb168576f9d8bc7f3c831b6ec15c5fa4f744315d3afdb8a246a56ee71465591831c371f2eb87467b0559dedd776ba063ee6d2f93" +}, +{ + "dz" : "6a1aee5e708c1b47f02bdacce4f56c860f74fc7cfec1ef3b58285b1c8ad7fec2230e05b7114ff0395cc6634db1eae8258072d09c09f291e92d6620b177dc50d7", + "pk" : "00e7a56e91a766c72c04ab283d25787224a588eb4fe0c6b54d889d127a471a72c65f06375d1a545ad9b058a654324b5615138b2ec4a375989b3f1b60fd30bddaa2307205a103b29be6cb75f3567705a0c05eb845d493caf795554ab25fd03b379a6284988763698b1bbb4b3c1a54b9c2038e9ef30a3870a11604288b32336e15939fd181525909949c6cdf7737cdb382b1dccc0c49317213683b349f8da22db0b45e359b2f8e70916a0c0142fb264cb6bceb80afa3a36912d635d7b4cbf33a4a36e4c6714c551d70a18b967539b7a604c5182ee7673ce91d07736f5b97b407879e77050bcc089a14332138d92ab3e09b497b834df573dea32829b471bd5a73e61361ec699ee60320ccdc0e6fc983d3238a8d5abc3412bf48d67dd2e1b0c2692a4e705de666aaaafa9eca476a1b155d52459b563b6ef1549c51f83bee2963a93729d4746a01a21dc667b120d38d79a45a112067205c3edd378c7f65c940719f79389436a5595010678e1558ce163ad95593a751c737d4936ed9c7cfd41effb1abedc07564fa5238ea2d2908793e2a9a33e08b67ac3133402d42344f6d1c804536263661a557739cd8c29682549fff416c069a39cd48229e47066e02612988bf780256e25009ec5b1ef829bd39bc0654a0c8c3c113cf421f06965713849a83cac9f6415482d82074fbcba804b4c5f2b1fbd941c7ec8c4c691dee981392bb0736d43adb3ca548829a55bb9537396d7bb11922a9167ef01cb1aacdaf17902f671a6cf5487bb643e0a1cdfa3522860326d374ba8009833bb08eb09a2b3cab0d3193a6561c17d60b1cacb24cd3c26c455c040cf9ab0a7292bbdcab2d5b783d65bee7a666ebaa2764e98b7df61bd5ba546bd307ad7469e4ea85b6031224d9b1315720ccf95273c35767c43a3b27a31773c5b35c7e4aa0316c53cdb2fb1a60ab77c4a76f2af78bc2d6479b909eeb9c26ff97a47c468dbe7c439d232a914766fcf8772e7ba92b3182e362735c237bcffc3e940cbc5e6042df923eaec04d96e31cc3187f66735ff1e62fb5460895b22145787484e529a1d654a2d72cb9d81b4d283bb15682e8f9bf1037cc95e29cc3716fd89810e1bb95da871a2562645e0c60a27cb508c2885c19befc686db2e7a78aa66b934aa0d42c856cd361ee93294759549929b59adc1ebec3686e70c4a15c8d56dc23ad080945d4734b76b0a64b73de7b5d810ab8daf48542a4c13b8a14aef05c788448acaa51263cb31be69a91888ac66075c0e59ead1b29d6439e94253d20f965d9f0aca53a28b4903bd40a1310f0123ad221a45961527589e7048faa407028601e397a96b39728bf55437d335f1e14063d3902e923863bc90572891117516fba340263d6a0aaa0743e959da8f21ef9fb38431b36b1328a15696e97aa78ea97936f8b38bb1556d2625f5ac31e1b8cb3baeb1be7f808b6329a440045eea532624354dfb71dc321109d0058f24ba4729c375ccc0440948fd345561715654f60b378b477a208cb83f3afed2534c5ab6efc0a5761d46b6cc0a6ada55d1c92c7558bad4091772f65bedaf335ba37af34582e0bfbbc6609bdd3568001734520f45d9f4772d1d21d5080b9a7a2b2e72a0b6e030f1418beb28a229c8f63411446b83fde11b3d946c9bdabba08d495aee50911cc66291fd0", + "sk" : "1023c0608301ab03cae768b68fb495c496b583b72006f0aaa985800df2b6ba238cf37748dfb231fff957ab744cd8c5710b301340426d66507f48a23df19878d9cb0ddfc06e1674c03124cdc4c1c70acb645ea55b22403190d813f287a5c245b4e7a31d11988d218988faebc195366760303ff99433cf07b68fb4bf6b8a507e902b0a07bd2f048f0393bb9f5b40ca588208faa73789a0107ca9c4d12239caca11500f3de39995d11911b9386e8bb22cc908e9906bbb247c96a0bf6ec14bb0e33113aa4ced8531beca2d415066cbd299a9dc920a935b1bb599c0c14a695253fbbc8ad7344122e8948f5b10e46138b28740348aa888ea0c18d53b875232c34bb0d44197352505231bbf5dd356b8955856a4c3bb4615dab0a07724065f4ab0ace46fc684a3dbbc9ac0e776e6d628af8a2794829567a95d2ac0699e3a87a46086781965df032586290d2edc5c57a7332a286bcf39b8af181424884863123d1145031ad069e0a56f9212c76378871848b121489773a623c69c139a33363bd032a40b4fa15637c01916c132754bea335771810303418f75a35d591f212a603dcb2f3fe9ce261acc082b4e38477ca9348dbf6bb981128be73c189147b21949666cca3db8e433fe66ca43206356884431266b9d1a92b1899217aa636d3c7d7fb11a2e9ca61abb586d20ac1e46198da618cc71bd52b922de064ff5211a2b53c51f206e025505d3273f3f682e1a873cf41433b77608739b55d457364c04315dd8b304604c2fa52734fb25ba6c69f9030008a310ea76b450281168a3201b9892e5b7926cf53c3e3a591979874248a361c5c1f601d0580351cd51a78392bc4134c708dc822ac8b9c032a80875b30eb69f9a636b2ab13c6a35ccf4d704ce40aed8fc2a3f47b50599b024f73444a09df092775f5a77113225b87cc295e336eb8668ca6b3dc1d7b5af00a75730c8c3a45f05f9a22c66143965466f5b7cca564b6afa4a3ba0a57dd5b7035651725010ac088727c5b7b5b91f173589e7b94463f70bf9813c28b405ee53c10e1943cb61ce66527d7c0529cc67b181ec6b4077ab764aa9455052495c9dadf033ce50c51a3893aa250f6e47711e96aecc69a13aa60b1e837c1ad98b5ad2931a9084c6c364b4a33de1a02d01d9155b527f036b35d5ec3d13b5bf49e8be9b0234f49400fb512e22a705e0b6212908b77f715b3813bbbe29539cb63f78075f0f3cc60821b4d24b5674e29af16647fe917452b85a1c887286a89afc31955fe8afa67aac2ab30295d8564ea94c720268ed866ad36c8bd634b2b6e6977ea1781a592e532b3f292b8fcbb10235246f8c320d6daab3a7fc26b63251dd98a12550166b513a8d66435789bd979436dbd263b18c15660693e6eb99268a3d80ea6c995234d7e08b7712b295543b0b3b9856c72cd2268f7f66a0c67c96a2a1bddeb26a4ccbaf9d7499a7a48a65982c8059851b79c735897109479108acc7e668bb16c8a530a7bf4f473841e17c191cbbf867b36059505446cb30c26ff5970fd21a4043854d96d9575ea25415c263028a2a4f35c824001eba5062e23098fc4556399241b8e48933e28c67068d34155507e23ccf4877bd170f38203fea3b9e2a289602301a00e7a56e91a766c72c04ab283d25787224a588eb4fe0c6b54d889d127a471a72c65f06375d1a545ad9b058a654324b5615138b2ec4a375989b3f1b60fd30bddaa2307205a103b29be6cb75f3567705a0c05eb845d493caf795554ab25fd03b379a6284988763698b1bbb4b3c1a54b9c2038e9ef30a3870a11604288b32336e15939fd181525909949c6cdf7737cdb382b1dccc0c49317213683b349f8da22db0b45e359b2f8e70916a0c0142fb264cb6bceb80afa3a36912d635d7b4cbf33a4a36e4c6714c551d70a18b967539b7a604c5182ee7673ce91d07736f5b97b407879e77050bcc089a14332138d92ab3e09b497b834df573dea32829b471bd5a73e61361ec699ee60320ccdc0e6fc983d3238a8d5abc3412bf48d67dd2e1b0c2692a4e705de666aaaafa9eca476a1b155d52459b563b6ef1549c51f83bee2963a93729d4746a01a21dc667b120d38d79a45a112067205c3edd378c7f65c940719f79389436a5595010678e1558ce163ad95593a751c737d4936ed9c7cfd41effb1abedc07564fa5238ea2d2908793e2a9a33e08b67ac3133402d42344f6d1c804536263661a557739cd8c29682549fff416c069a39cd48229e47066e02612988bf780256e25009ec5b1ef829bd39bc0654a0c8c3c113cf421f06965713849a83cac9f6415482d82074fbcba804b4c5f2b1fbd941c7ec8c4c691dee981392bb0736d43adb3ca548829a55bb9537396d7bb11922a9167ef01cb1aacdaf17902f671a6cf5487bb643e0a1cdfa3522860326d374ba8009833bb08eb09a2b3cab0d3193a6561c17d60b1cacb24cd3c26c455c040cf9ab0a7292bbdcab2d5b783d65bee7a666ebaa2764e98b7df61bd5ba546bd307ad7469e4ea85b6031224d9b1315720ccf95273c35767c43a3b27a31773c5b35c7e4aa0316c53cdb2fb1a60ab77c4a76f2af78bc2d6479b909eeb9c26ff97a47c468dbe7c439d232a914766fcf8772e7ba92b3182e362735c237bcffc3e940cbc5e6042df923eaec04d96e31cc3187f66735ff1e62fb5460895b22145787484e529a1d654a2d72cb9d81b4d283bb15682e8f9bf1037cc95e29cc3716fd89810e1bb95da871a2562645e0c60a27cb508c2885c19befc686db2e7a78aa66b934aa0d42c856cd361ee93294759549929b59adc1ebec3686e70c4a15c8d56dc23ad080945d4734b76b0a64b73de7b5d810ab8daf48542a4c13b8a14aef05c788448acaa51263cb31be69a91888ac66075c0e59ead1b29d6439e94253d20f965d9f0aca53a28b4903bd40a1310f0123ad221a45961527589e7048faa407028601e397a96b39728bf55437d335f1e14063d3902e923863bc90572891117516fba340263d6a0aaa0743e959da8f21ef9fb38431b36b1328a15696e97aa78ea97936f8b38bb1556d2625f5ac31e1b8cb3baeb1be7f808b6329a440045eea532624354dfb71dc321109d0058f24ba4729c375ccc0440948fd345561715654f60b378b477a208cb83f3afed2534c5ab6efc0a5761d46b6cc0a6ada55d1c92c7558bad4091772f65bedaf335ba37af34582e0bfbbc6609bdd3568001734520f45d9f4772d1d21d5080b9a7a2b2e72a0b6e030f1418beb28a229c8f63411446b83fde11b3d946c9bdabba08d495aee50911cc66291fd0d49e426ae85eaa6c911c4dca80caba6e28e5f645a54d8c016de51a2b98241a29230e05b7114ff0395cc6634db1eae8258072d09c09f291e92d6620b177dc50d7" +}, +{ + "dz" : "6396b328b100e4c7f4bcae69875edea1a1982421558c608c13c592bf7b5d0fef1100ced48add211a5c937b8d6079d8e271af3f949edc61f70e60453aef20dea9", + "pk" : "2450c193211551409a9ff92089c54b048b6a80127c7742ba34333bec498e28d729d6085fc7f5b6e5c4212a0aca0772af8f83200d422b49a80dfa17cf56d8277b792d7b4675dba3a7502674f595a45fe93008acad026410de336fa41ac0c725bf601280bf7b4d7dfb63789175b7748dc54846f3a8b28d055c69e2424704bd84f61c896a40447bcd42b96834c8429ca79dc4a4be300c7dee38a253e35819a43d833046f6437622094d003a3b9914bc6946bb4f4cba41246ca027cf2e599a54a23e8cca88086a6bf8aa92305185a8b232a0f45903224ba2d3276715640451bf49c350fbe5b2d95a5f55223a1a794bde26012bb48ccb4384b3027855331e96ba09c7e757bc71ae9ab2a1adf51ff01bbfd4c77a40dc3e24da767d8b456979913ae97fa9446413084a45fb7827a082eca1094a9437154b2c8edb48d7bb893ae3213b5a95f86bc9e146657ae653f1c9bf54f87830aa968b96b747b9aed4007ab4030ed652652daa9612d00f36bc2dd1299c8f2c84fb56045ab45279735aa1f57ecc470d7e66696a8b7a65bccf23b63ea1d595363466a4d24540e21bde05733154180d1a80652b166cc05af5a7cdb2158471d52fa5006a8ea25c98167f4574a8a47a00b7c031e667a7daf41b32c714ae1855ea9bbd0a1aa18bf64071c44f3783b30ce8301f20cbdc5c194d6131712386bb135af9b55c680790b5147f55a6cdb94075d0f0c289f42aa638623c16be446289d099777717b89922476d8c5511997419d8b5a44ac8c4a9589c5b39c03b045ac31a6e9967fa22c21f5bae213065867945ec746f776b0daaa96d85b61864fa94e76474beec06815b556faa81ace15c552558c0575c44e26cc4f919d3e26fe1374d2afcbb3de23a9be5b366c1a174d8b78ca462705ba70b358d57a751180c781b28075435b2528104ac0bbfe5912f8fda282f93b7e3292a64b83494563741789c98eb7e84d69c7cc2cb1703ab94aa71d7491c69b52949818245acc6ef07c11fcb68c336738fd762269b7ac562aa7401965f2c5b2909404b32cbc86671043ac334e283ab194bdaabc390b0b2e275bdf0cc2651d11207a53db1a2166b7526633cb779d88da83357b51c962f567d03917f0f2b5c3c3b9ba75699efb4a8a5736d98a56b1510cd6f233c2c05909a3ba6203c11ed72a0091785acd729dd609704e51dafd4342275564615b258691b59266a0ee3a8b261c6e9e9894b681806e97fbe3b25b4b133d804a0286a909752220c11c8644417f34597db43ac66159956a11541cb4348c23196095be01023e7b267c1e51fb0c11d9b787a519b3ca3f0ae08c79ed3f256a63b488e38040195983da72f9cfc03a9c5a7c428898291a9bff3cea8089a343b73e616c5e02227553511722b04a1604d5ac718ed753e8adc001fa47665b76f944c10dce0635e9c98dd91b9e6790da2b09ce323ab41cc7c29839784e6ba907979ce815f982585297b5170dc7afeb94524563510257d99131981128c7953ad87ca696d58250aab373ffa3476aac3f650bcf58aa6bbe85168b7c4012b3359a2b6bed702524b8498d3aaa04c7915211e1e013e1961b0e2e32b90e01e0b372446931a0fe6255b412581e2b5c0d60d3b7208a63449b4216546209bab2ad3767f9793d0be98cd2899da27f7d980122d0bdf593022e2", + "sk" : "d77060c9fc07dc7287876347eef702737a25a8b192146a5bfdb637f936b280098224a38ce6311116518028cc005089bcce93c7c4f65451b893eb1872d5470342d3627e90110022b78ca23d5eb97ffd9a16be398271444d6b17c4c5cbc680fb9f65c844c86c40b291a3cc5a85096b3f150ac9cf1540d1a29ab0d30874db91d17894d234c6bb376b3683273d198c73cac396d942c7cc2c63b19204c15792071ea41383dc864d2619bdddd11431d0b7299aa720516fcada90aac7148fea3d63a14e95d01fb51c03d74bb49aabbf70ab50ef225795340086a0b95a9cb15349501f4c059b26abf18161151c21bcf30d325c1f1d348b58b3bb0da69da24c18d6c75df0f6b0e63414ae9739e9eaceea4b00f0d33775121e78742f9c6ab1aef5aa83b14d8be365270583c0c90847724e39978095c297799774ae05cbd4794882349c68f5a2a2f23877e395c5e14286c9774aa159703312ef63af3fb2978e22a5c1c0152b4139429783ea5bc90016701f1868c2cac0acf4649886b773e5c29dfb7bc142615f93216d2c3ec9eb90e772359614c57ca97c75b593ced123f6a8bf76854d856c65d5069ba084c75f10290d104f5c9ac498200190b72f004897a8d83b0db3274148443f1b14108615a3fa02668bb9baf1086503351ff1301e65085f65cba909bcc42b32fd5578522baea9f515e48b040a259fae266127bb6a8e338965051943c63ea536b5db2c3b6c8998d4287922d5657da1269e8071939b28aef119b0eb66a87378064162b1151e852cb00f927d6dec61bce0631a93c1b51379546453c63626f2a792d20c36aff9a3182c6e7b5833da416f29772b70216732c376a4f59176617c885816bbe72c38a1230f484f1fe4671fdc1224e1bdd8d795c2e0917692517c4441cd4cc3bcd71765212b2e4986c881b2b0e8a0405ba2f7676a41f4aa152003cc185be7cc22c9f402b878bf9d44cd32ca21cf92a720e35f81007345d3bf40b821f48b4b2d693eeed8cd292b636e7360f79237720625e966b9a5d99a7a452d2bc7066163a00647aaca62044938ac6b6598e9eb003175c2a29c46228c7b6464815e9a271a690e771601e252b251f411e6ea91f2f55ea0150a7a5405f536849af80e0840c322c5b339470196b16cbf24484f407dc84819373109a9676298ca273d82bbe4e24946e0617e33897f170bacf4b7a312245ffb780f4c5100109f8c4b629ac1042cb7a946293f740a3589e069987aaac2d996f5c9886d7125cb772a6d93761851076931180d87ae808a908d3c3c1203ba85739c6095b4fbec78066ba9da4433dc4928f4d73e03108fd8f531cd6ac47c088a64562e607c7bde3867691206ba9c058432466eb54a9414c3a3127208a512ab5973b5d118c51468fa70bef827649be94d0d97acf60b693d73b062249806275a5d475afbd943e96a512f45ce54343bb6f353a9b1540f420cf4f01bb3611a09925e430237712a8c2b91beaf7623cedc6988990ef8006bc0da49c57b5eb718409c8a06f81ba501090ea67519c261574b118ebbe1765a145309677ae4fc9ed499934e24500056372a25271f40bef480218d978d6457aac1f9761bb63679396490242558b2b6c617050fd902523a8c2450c193211551409a9ff92089c54b048b6a80127c7742ba34333bec498e28d729d6085fc7f5b6e5c4212a0aca0772af8f83200d422b49a80dfa17cf56d8277b792d7b4675dba3a7502674f595a45fe93008acad026410de336fa41ac0c725bf601280bf7b4d7dfb63789175b7748dc54846f3a8b28d055c69e2424704bd84f61c896a40447bcd42b96834c8429ca79dc4a4be300c7dee38a253e35819a43d833046f6437622094d003a3b9914bc6946bb4f4cba41246ca027cf2e599a54a23e8cca88086a6bf8aa92305185a8b232a0f45903224ba2d3276715640451bf49c350fbe5b2d95a5f55223a1a794bde26012bb48ccb4384b3027855331e96ba09c7e757bc71ae9ab2a1adf51ff01bbfd4c77a40dc3e24da767d8b456979913ae97fa9446413084a45fb7827a082eca1094a9437154b2c8edb48d7bb893ae3213b5a95f86bc9e146657ae653f1c9bf54f87830aa968b96b747b9aed4007ab4030ed652652daa9612d00f36bc2dd1299c8f2c84fb56045ab45279735aa1f57ecc470d7e66696a8b7a65bccf23b63ea1d595363466a4d24540e21bde05733154180d1a80652b166cc05af5a7cdb2158471d52fa5006a8ea25c98167f4574a8a47a00b7c031e667a7daf41b32c714ae1855ea9bbd0a1aa18bf64071c44f3783b30ce8301f20cbdc5c194d6131712386bb135af9b55c680790b5147f55a6cdb94075d0f0c289f42aa638623c16be446289d099777717b89922476d8c5511997419d8b5a44ac8c4a9589c5b39c03b045ac31a6e9967fa22c21f5bae213065867945ec746f776b0daaa96d85b61864fa94e76474beec06815b556faa81ace15c552558c0575c44e26cc4f919d3e26fe1374d2afcbb3de23a9be5b366c1a174d8b78ca462705ba70b358d57a751180c781b28075435b2528104ac0bbfe5912f8fda282f93b7e3292a64b83494563741789c98eb7e84d69c7cc2cb1703ab94aa71d7491c69b52949818245acc6ef07c11fcb68c336738fd762269b7ac562aa7401965f2c5b2909404b32cbc86671043ac334e283ab194bdaabc390b0b2e275bdf0cc2651d11207a53db1a2166b7526633cb779d88da83357b51c962f567d03917f0f2b5c3c3b9ba75699efb4a8a5736d98a56b1510cd6f233c2c05909a3ba6203c11ed72a0091785acd729dd609704e51dafd4342275564615b258691b59266a0ee3a8b261c6e9e9894b681806e97fbe3b25b4b133d804a0286a909752220c11c8644417f34597db43ac66159956a11541cb4348c23196095be01023e7b267c1e51fb0c11d9b787a519b3ca3f0ae08c79ed3f256a63b488e38040195983da72f9cfc03a9c5a7c428898291a9bff3cea8089a343b73e616c5e02227553511722b04a1604d5ac718ed753e8adc001fa47665b76f944c10dce0635e9c98dd91b9e6790da2b09ce323ab41cc7c29839784e6ba907979ce815f982585297b5170dc7afeb94524563510257d99131981128c7953ad87ca696d58250aab373ffa3476aac3f650bcf58aa6bbe85168b7c4012b3359a2b6bed702524b8498d3aaa04c7915211e1e013e1961b0e2e32b90e01e0b372446931a0fe6255b412581e2b5c0d60d3b7208a63449b4216546209bab2ad3767f9793d0be98cd2899da27f7d980122d0bdf593022e2903d69da169d8f3f65eec290acf30078fe51bcbd1aeaf412dfe2d31c7b10157c1100ced48add211a5c937b8d6079d8e271af3f949edc61f70e60453aef20dea9" +}, +{ + "dz" : "a453bcacdd2b0d4646009e5ed451c3c45f08fb827ef733db3c517a9dc1af93e67a3cc8aa3239d4c52ce4c95afdeff6efbfacac10d294edc0e7cf4535059bfdba", + "pk" : "352071c0a607e459c907fa29619ccfdb5147f56c208e20b3dcb82fa2304e40c46aaeb47c5bfca8a9079ecab4471d4bcf914c8ba459433ccb950772038f6892062535603b536da65dfd5c33430069a7f33a08092bd9c9617df3a5778b1d15a8a91c8b99bf5b0d4596a3f8a79d3b6994e823c20f102cb2353273471e2675633d9ab2c7668f02e7a68b2534489b169eaa92a8d78e4e182647f71758fc7f49a17fb400c1de30cc76664bd10b7c55885af696478feb919f3c24fdcc98991177b52ca647070cef77ab47c891b06575e5a0814311a75bbc9837a1c564246c163017696294533999b6700a1402552063a621205bc28823e539ad1c1795e0a23b6b47737ae839617548a514631319a78d99350eb77dfba97f7208d04ea980546a9e6642395c5177bb7b433dd47351b85e569091eaa30ce450c1b786c0272b91f9763478ac5410bc1f78175edef0021e8c0b4f074bce255ac2238a5d67b84b08a12984696e1ac7ad1131cf64bc64c5b0a1ccc94e3bba85271975c63f8d314d9f1a2d17835f873846c6858f9f285428478b2efc10bd7b49ffa006a6537684b0093a633d9cf9bf6bf97017690b4ce511b1898971b2978b6a1371e8aa70d970f8600bdd0109c84521e663845805235dd5849b192c12b49b43f824d9a16dba939609e166a8b05e4811b970915dfb527d803672c7a418293937a0c508272a5186203be64b4b1b33578d48be3e23913e73a385a8ada0fcc4cebb1070ca3006ea16f7da6eebf8b9e6637dee942cbe43395c8a7806f2c23d1c146d6359d268303a1229e5d513c79b2095892d553038b6a3431948195bac491a879c4dec39cb1b97374a65d5f066f6c66045a25b9b5889999889db34b1f42b4151126dd7431389a8331b9c123aab61c2122285530566ea23bda21cdedac78ccaa9ca1566ea1817f4791da6754379f9b0f8acb217085fa380910ed3ce4a52cabbe52d75472a63c88ddfb423c1ba6c1deb6ed3172cbc7244fb71300721aa13037ede787ffd546e60890131d8add25551d72881be0c8647aa10eb5cbb5f73c891868d4641bf8a692bcf0a5867091f4313bc976c989d1c184aea07eed11e36c215008b56a55ab5062bb41f7c5895837093671fbf7c4ec63505d15ca7efa5c6e45a5f5a757a4fda02f9f13c7926ba7c990e6dfc8b20ca1a2a9490a33210c14accde09764153bc9d4a2a68b7a80d9a91d3d47789c2a79bb212bc92812f8660f23a833d78a3f056ac030bcad487431a6357b8a1c13b512deec79ceebc37c6099b720445390277dab65346ea323d33c76e30483d51b9d01b5fdd55bb7d116b2dcca951292f3065b1628b1dbb86bd0cf5ce6a66ba1ab3717829019ceaced283c6b748b26425588ddcc47bc89ceb267ac7c03172b960160a6317d44fc5287c5e462911a8c995bb92ea1c81fed5baadabb569f9cf7c1cac71926f3e4a1a7411295a623c41240ea4e9011660227a785d989ab00a2c3091b02bd65a5b244246ffb97e23213f57b86aa21669541a60ed7014f1831839e41539dc8634d0125d61100ea4438af59434a25a1ec0bc99aa0edeb19d67ebccdd22ce5ff925ae364af7868ad6308a602033e0221ab609560144abec5a4792b8894337c866ec1a5df4076739fed133a74636ec9d904e88876b678088d8c70f3c70", + "sk" : "d98cab94a33c2a631d4bb8a0e314b78e68824f7b2156d3c481c32f35c82cdc5b2f0f41c2ae64295c246661dc0052209ca274b3aad8221ac955b0f30344f775b759adb1031bc5fc34e6eab6a8a10f7c576e848b2c78a31aa0f951ed8b917277153d4842317474693c5643ea6a9d49a8e5a9baf7c61f967c8679647e8c25ce3ff5a766f34b5e481dbf93550bd36595c51c51cc1c50dc278da95325f483209119942a604d3724328a28f18a6559ebc23a2ccc7d647ecfd866b17b2f2f63b31e1886c309211e7238d2c2510568262a48291a9a7a1d5c38aa61c0acfbc20e8c347c59c6cac9bc402788da55baf1a7c3c0093e4707699976bdca93646607322368addd9420df669079322edfd59bf09397c4e2392062b455d25044382e26510197106f681663a2616d7ec46efd75646952875bf708b2a20b9b7a688f256b078a140f170e3187b4ffbc2d742756c1ac1b07a29916f8347c6643131ac72c8c0840ca7f6c866f20d32dc53a448f193b4b81583da61837873b4239b9e690486c240315c387b6e5763ca226d86a028caa07f4c9963af99850f69401200f69c74a0024a4d9a7a54bb978e23c0f13474e978740422c606e7c5576702c25020415d263d9ea362f9556d64129ee182d22b76a8ae4892bfaa97b68709bf905379102a435500835871d192b48d64b5b31a5647c3634489cc2f33c6ca400371152d8148c0ea4acb95b96f3e2919ccc251e6bc458ac635470437165c2bd4a9efce81471d652deb6aa06359123b532a4c7c1a0ab0abbd193042c4a2d82b69df83045bb933eb43d1199a818f85ca0239ebefbb9294657dbe33dea89a844eb54f624c39732201db37ac46838bca17e0aa3b01448412bcb8ec98b26fd78cee583948a37bf2ce996ee852fe1d1a744f2098ca5b0720409fa592dde17432d424ba40a5362596393932c8ca7022435a763a367afb41818e12b88548392f9973619b41430cc48339a241cab26c68855b07ca4163169497e31831aaa57c3ebf384f3926b28374fc4cb2ae37173dae034ec61c48e804ac0a347d721c670357a7e78198d3b3eab02c168d26e3ef04d1468bd7ba4be00013266fb8fe3bb98a138b63a45167494c17b89c6a6e939d75584e755bbe8048fa2443c57f07f1f178965047e2a59c6815a5b92b6691c9c9dcb6250bb73725586b57c8239eccccc2fd418289a0406671d68e79e4118304637c9468b7312805599960c19a824582b5182dca37dbc63d5d33559a79beb56c60108c5655789bee1c42b75b73b9b336140b202b61ea32324134b8dbd064bd3293650c5b8e8f87793080e509cc7beab0eac8679ca5a723cfc119bc1a18e7631910a2f50601fa280084b98aa81c38907f0a685b3acdd630a3532ada83648bf858084d087c60b1ac73c76ff4477d9b01375a7cea52280b404564dd69c46e3a2125729463ca7fd724c35738094e627e5f1610a9a00ef7294f4549470b993d0447dfe34b8ac264c547a0b7a134d19ac2bff750cf2e4c80f32679375cdf0906346d64a56ec7648c4b7a20613c9b74301b12d40d1ac64f8318708820006d06e088811860a1cdb300187c694335170f6539df45834b93edfd4275e939fa5f828b6e471a5e09b352071c0a607e459c907fa29619ccfdb5147f56c208e20b3dcb82fa2304e40c46aaeb47c5bfca8a9079ecab4471d4bcf914c8ba459433ccb950772038f6892062535603b536da65dfd5c33430069a7f33a08092bd9c9617df3a5778b1d15a8a91c8b99bf5b0d4596a3f8a79d3b6994e823c20f102cb2353273471e2675633d9ab2c7668f02e7a68b2534489b169eaa92a8d78e4e182647f71758fc7f49a17fb400c1de30cc76664bd10b7c55885af696478feb919f3c24fdcc98991177b52ca647070cef77ab47c891b06575e5a0814311a75bbc9837a1c564246c163017696294533999b6700a1402552063a621205bc28823e539ad1c1795e0a23b6b47737ae839617548a514631319a78d99350eb77dfba97f7208d04ea980546a9e6642395c5177bb7b433dd47351b85e569091eaa30ce450c1b786c0272b91f9763478ac5410bc1f78175edef0021e8c0b4f074bce255ac2238a5d67b84b08a12984696e1ac7ad1131cf64bc64c5b0a1ccc94e3bba85271975c63f8d314d9f1a2d17835f873846c6858f9f285428478b2efc10bd7b49ffa006a6537684b0093a633d9cf9bf6bf97017690b4ce511b1898971b2978b6a1371e8aa70d970f8600bdd0109c84521e663845805235dd5849b192c12b49b43f824d9a16dba939609e166a8b05e4811b970915dfb527d803672c7a418293937a0c508272a5186203be64b4b1b33578d48be3e23913e73a385a8ada0fcc4cebb1070ca3006ea16f7da6eebf8b9e6637dee942cbe43395c8a7806f2c23d1c146d6359d268303a1229e5d513c79b2095892d553038b6a3431948195bac491a879c4dec39cb1b97374a65d5f066f6c66045a25b9b5889999889db34b1f42b4151126dd7431389a8331b9c123aab61c2122285530566ea23bda21cdedac78ccaa9ca1566ea1817f4791da6754379f9b0f8acb217085fa380910ed3ce4a52cabbe52d75472a63c88ddfb423c1ba6c1deb6ed3172cbc7244fb71300721aa13037ede787ffd546e60890131d8add25551d72881be0c8647aa10eb5cbb5f73c891868d4641bf8a692bcf0a5867091f4313bc976c989d1c184aea07eed11e36c215008b56a55ab5062bb41f7c5895837093671fbf7c4ec63505d15ca7efa5c6e45a5f5a757a4fda02f9f13c7926ba7c990e6dfc8b20ca1a2a9490a33210c14accde09764153bc9d4a2a68b7a80d9a91d3d47789c2a79bb212bc92812f8660f23a833d78a3f056ac030bcad487431a6357b8a1c13b512deec79ceebc37c6099b720445390277dab65346ea323d33c76e30483d51b9d01b5fdd55bb7d116b2dcca951292f3065b1628b1dbb86bd0cf5ce6a66ba1ab3717829019ceaced283c6b748b26425588ddcc47bc89ceb267ac7c03172b960160a6317d44fc5287c5e462911a8c995bb92ea1c81fed5baadabb569f9cf7c1cac71926f3e4a1a7411295a623c41240ea4e9011660227a785d989ab00a2c3091b02bd65a5b244246ffb97e23213f57b86aa21669541a60ed7014f1831839e41539dc8634d0125d61100ea4438af59434a25a1ec0bc99aa0edeb19d67ebccdd22ce5ff925ae364af7868ad6308a602033e0221ab609560144abec5a4792b8894337c866ec1a5df4076739fed133a74636ec9d904e88876b678088d8c70f3c7008cff1967030a528e748b708b0fb783577f249c04ea5536d2da034fd0d15fbac7a3cc8aa3239d4c52ce4c95afdeff6efbfacac10d294edc0e7cf4535059bfdba" +}, +{ + "dz" : "47ca2b77c5b717f423222c2730ca5cb9c856bc951d01b2b2c80bd76ccb5539b78f1481d7cab000e33fa07de8dc9627a85e76fabb4428a3376e66300cf12a0787", + "pk" : "4a5058d467b5ff439fb0c2916ab09bd306661b18626746c8f4db817e3c4dd2c71041929dd7c5918a760f50715c6528c2d2e7c9b97c51e9009281849cfe4410b616ce03455c73580fe16634fda087387023e427902180c5e8276b797abcc47028cac91bc751c9ec4a9c39d682cb38b38882103839947b920ed453a766c04df7ba58f9714c6c370b98172a71fb7d254285e609551f31444e90c2b1d595472825fb9cca49d55c237a67377808ebcc1bb4848a75527ec467a7f94b8c4f8b1a16f789f3ca15f4f332fd0160ff6c4985b08b9996bd08892d5a836d50566bddc6adc6ebc7d3c95068c08682d54e70666f5f62b238f69bf86a3a48421bcd8b762625c06f03cd8e013561abbb2f01b1c314a6a61500aa02b9a54682325340ba328761140781885febec3a4090a5989b914a494d07e9793b703ed4b45af78c42f3bcb46cb4c7fc5352802ba0eab35b9f66c34c39259ae52d1b75b910a82fbb464d37f6befcaa811abc6485f41d38c8a4d1592ec69b5ce90c7cd10c0082c0b72dfb2e5a16b4c7ab6e65f58fbeb6c442fbaa2b4345b3a3326bccca3b5104730520383178589c4b4c751796c31aa061346620ba90d30b340c541f7cad17f86e05c91e4c21162f618b52117ddb572e1b90c0e19235a82a3e51b59c3b280ce3fa739bb70e4af9233831269ff87f3114596f317f28dc11b8b53d578a8ca85b290d31abb115b76c0a8748124fdb822f989c241b801c8b982fc733921d45853cf63880107704baa331b725a416471032a9289673f3ecad22050d9c5c9e2706a341553d168bcbad1a41a3c554260112336430fa16ca8fb98cf5d92acafa8fb427c460a27aa08358b36c5ab849ca2725b72c939fe0601d1e2abcc4434bd0ac835751315856922ed53cdc7b49468caca339aedfeb25ec2b97d43ba409693fba524ae4ecaee5b84b567432270644d6aa618669734e10c8b05a0d697b81d6c83c9f844cdc8ac755403044b14c288131e8c0c21c2361b206597782313d40bad1d56dbe159735491f7b800d6b14ca69d92bf2130badd1858b2cc4a408c33ee56fdfd719abb2a431132e15b89d83498b6bb5aeb0d7404e94cceb2a29fc392a2e466469e53da9c371e0155a774a298d515d70ec5e31aa070be92c3d6290f285a6034a97e389277eb393c5100f066c588aa33e66028976493bf41481b2eba07a720937bc02b5324d63b9487a1789a6baca91512c1a3a0a70b348c1596cce7997ed395b971442ebb3b0e2dbbf5608012030a172b259ac705af9634ad585916cd63ee1248ca143a20001a20cca0496734c2c52a59bb40f76411578e2c60f2364e8763ec1e5641c80a9d6235d4ff9ca73f4c4d6db9bcf3383d7d9a025ac76db1ca49710aa281c222a4bb81b1027d80c38c8365a39988a029a93b5dcb2b0f410fd1b63a54297c65b7de3f3a948f10988b507955aaaa2d3c699dc83ef348e3781c8723b9bd1c6637b94b6cd416427592c71311a16d449d15c0fb2753b338586f7260cdf255ca65cbc8c54101731a45544312099a66405b01eab124f116cab0003bde314b25690520a9a2131154271c89b97539035652c03b462f2635db501f9ab6983017f22b3391a67397066c86032a31080d329647a7c4f5ab89a47393636ff0671a4b06948c9f87fb580358d467fd3", + "sk" : "9483b4fd275acc8cb660713ba7a57bb442aa743537e9e4b3dd73c5d3239cb876cdadd5a1dcd364327a7f8cda092d6841879b0fc7b64e81216c9acb87a4150a3fe7bab7058a6c6464fbb9ac71954e65647083f42acdb15829426c53c55a7984074dab019220b5f570211db614357ca0d3da2b648b2af10c0cd6008ac31ac8d995af6c44531d1125cb710a6bc4a573f04558a97eed49071f748310a9c844c63b491997109ca079613d96c2910b365eb343b3e405b749f33cb6a3502ed634c50196d364352aa06f5a149cebdc2e59d5b27c828292332157e98893494fde7bc51996562f13081f2ba89ec4b416c4732946b4aa26c5e5600a8b9b18278c51821ca36e153ab0a763dbd397693800a62a1e3682c9f71154aeb6772cb3368b6465400c7b4b200e571390165cbf56452072e38b797ba0465238f9e80652a0ba700951fed03fae6c91787c8b2c752a02a4ae52a16b4d1b057931174890656b53984ceb20b1b90d6fb10103c97f5dd7a0ee83cb2b34c85825766edb64e2135f897a6ac1b144ffd8225a9887d546c0d9f1b3d851003e810fa2193c856c7944315869349c93dc84616134c3901d1f137358984341069546da01864a16ca44025e78cb36744db7b3045425243526524f064f8b46c862a7660acc557d71574f227ea5d83ebf2c52db172b4fb7a70baa0df43a776a326cd2dc4367b89843a79205f34365f3b206798550c5624e241f03b41d56776c88636611fb1be2656fdc1c4e1ea84b0bd1b7c804bd53795db335531c896eb72558e6805599ca66ac7a77e4d9a1ff20349dcc76f78cae6c59b93a8165788216a7a611e2233bb4346aa01b47e5b458c970a0cac589f0cc8435b25d74a12d25f10dfb51536b465f085cb170757f8181c7b7c32176109a1a8bb3a59a4d545365960267746349caaaa182136e17f4a32bb040fd3038dada40c8443694789654db794f185cb7054c6bc50f9a24ac2edb5f34eb6a5b410561c0b12e803b998bada9e346785cb2c8e251989354540acbbbfc8517abb5071055ce7ac646e0197b89390516b9e56bb174d2b28d3aadcd0a51bf098f3325642e9b753015af338a8d309000c2313949b2b30314b924e5050bb278c2c4cd96520fd8009c8944569187a69a749b651039ca5443c30b7755782d1d5a289c4baec0f0b0e8153f3986a969e113cba21b41a06f8184b586fa312606419375387eb08980b86f97b382811400e82260d3cb5c74fa5e57b15c06aa2d8b250f92ea0ba222be524459a589a7ab46ac01a5564975cab66002c20745824c313d6167ef2c5a0266419b291401f6cd5b2497cc4cb7a7fb8c67a8761541cb281665f6da184da0ca520395cd492c86a3ae8aa91ba3d24d52322cefdb38be7a6cea16209cbc69e796a2c43b1581a015c2e37dcde072cc4012187276e81b54c20c6f95a6100093cbd9bcac7b75a904eaa9ec31338203c40cf28425ea9c5403ac6cba4cb8051cc2c5ba3f592100aa4188e2696211846bb68c4e39cebf26464b19812c98c0472a76e0a44b2631c01201546ac9982eb8334ac30a4be25342d48666ca41cb63423b9baf290499c27321b5705e8a70474b2ba392a34c17e1a4aac49da90cab751b0e5f50984a5058d467b5ff439fb0c2916ab09bd306661b18626746c8f4db817e3c4dd2c71041929dd7c5918a760f50715c6528c2d2e7c9b97c51e9009281849cfe4410b616ce03455c73580fe16634fda087387023e427902180c5e8276b797abcc47028cac91bc751c9ec4a9c39d682cb38b38882103839947b920ed453a766c04df7ba58f9714c6c370b98172a71fb7d254285e609551f31444e90c2b1d595472825fb9cca49d55c237a67377808ebcc1bb4848a75527ec467a7f94b8c4f8b1a16f789f3ca15f4f332fd0160ff6c4985b08b9996bd08892d5a836d50566bddc6adc6ebc7d3c95068c08682d54e70666f5f62b238f69bf86a3a48421bcd8b762625c06f03cd8e013561abbb2f01b1c314a6a61500aa02b9a54682325340ba328761140781885febec3a4090a5989b914a494d07e9793b703ed4b45af78c42f3bcb46cb4c7fc5352802ba0eab35b9f66c34c39259ae52d1b75b910a82fbb464d37f6befcaa811abc6485f41d38c8a4d1592ec69b5ce90c7cd10c0082c0b72dfb2e5a16b4c7ab6e65f58fbeb6c442fbaa2b4345b3a3326bccca3b5104730520383178589c4b4c751796c31aa061346620ba90d30b340c541f7cad17f86e05c91e4c21162f618b52117ddb572e1b90c0e19235a82a3e51b59c3b280ce3fa739bb70e4af9233831269ff87f3114596f317f28dc11b8b53d578a8ca85b290d31abb115b76c0a8748124fdb822f989c241b801c8b982fc733921d45853cf63880107704baa331b725a416471032a9289673f3ecad22050d9c5c9e2706a341553d168bcbad1a41a3c554260112336430fa16ca8fb98cf5d92acafa8fb427c460a27aa08358b36c5ab849ca2725b72c939fe0601d1e2abcc4434bd0ac835751315856922ed53cdc7b49468caca339aedfeb25ec2b97d43ba409693fba524ae4ecaee5b84b567432270644d6aa618669734e10c8b05a0d697b81d6c83c9f844cdc8ac755403044b14c288131e8c0c21c2361b206597782313d40bad1d56dbe159735491f7b800d6b14ca69d92bf2130badd1858b2cc4a408c33ee56fdfd719abb2a431132e15b89d83498b6bb5aeb0d7404e94cceb2a29fc392a2e466469e53da9c371e0155a774a298d515d70ec5e31aa070be92c3d6290f285a6034a97e389277eb393c5100f066c588aa33e66028976493bf41481b2eba07a720937bc02b5324d63b9487a1789a6baca91512c1a3a0a70b348c1596cce7997ed395b971442ebb3b0e2dbbf5608012030a172b259ac705af9634ad585916cd63ee1248ca143a20001a20cca0496734c2c52a59bb40f76411578e2c60f2364e8763ec1e5641c80a9d6235d4ff9ca73f4c4d6db9bcf3383d7d9a025ac76db1ca49710aa281c222a4bb81b1027d80c38c8365a39988a029a93b5dcb2b0f410fd1b63a54297c65b7de3f3a948f10988b507955aaaa2d3c699dc83ef348e3781c8723b9bd1c6637b94b6cd416427592c71311a16d449d15c0fb2753b338586f7260cdf255ca65cbc8c54101731a45544312099a66405b01eab124f116cab0003bde314b25690520a9a2131154271c89b97539035652c03b462f2635db501f9ab6983017f22b3391a67397066c86032a31080d329647a7c4f5ab89a47393636ff0671a4b06948c9f87fb580358d467fd3b5ed4c3fb678a44d92486cf091333c7f035541614729496d5dd45ce580f0d2638f1481d7cab000e33fa07de8dc9627a85e76fabb4428a3376e66300cf12a0787" +}, +{ + "dz" : "aaf6eb40e596a5e3e8218871e708b089240dcbe7fd3641f0e5e41e071ce49107e2f8d320ac3cb0c52efdc753282f092bc39baf4a18783a48ea031a191865eb78", + "pk" : "d0a4700800708a0cbaa0e3347235004460c8f86188ae66af363ba5cee88b03a341f5255c329a7d119bcac87c46bd77a1b5966a3fb22a45d89c712909fa8c69967b1fa8878d89b8541b8a1ee6858932e0793c045deffa62250c0d0072a46328992ba7ac4fd72b48512c7448cedc902d9d69ca55626a09d1a700a92cfb1a6bd89291632c74af580e3b4aa932c8c6714337b1d72a3002c6b68b1fc981cd0686502189712f0c5327e1050ef71549aba312a59e9a342c9e76a96de6907cf235b6e3b5e36a9072ac95d856aa7014699ff48bcb7b298e5168cffa740e0a5bb1f65df9cabbd715096ce738bd39bad530a05eb58efa8b9e3dd426f1781a06179736570611c89a6f99b3c0aa5f4ab2737592082ff73dafd7671bcb60a87c5adf3445ca3381a279c6a4fb1724373827494e294ca5d83574e0877e4a31634abb106b81afd515402290318ca8a2511cb129aa52228ba4a64444b761c184a3a29b221e11cc1335e4b87c457710fa4fdee790614249fa060b0417cfaf9bc4fe88632a76766fc8c5ff424849cb91d4351ec621c2335a2d7813c01cc893c646986f7c2246b2bb05149ebda38f00acb65cb8bf53314561893eb0f1053b237915711b7577b18aa963315a3b024629689a52bdfc81e298c059380920aa5bc39759f2f56d2811c89c59acde3a5496f1a8cce9bf5266b363a40cc1b6c78fbaa4241340dd4563a5603413cb73ba1893bdbcb3ff93bb7f1132940998427769d19047bc051506b5b990074e8d1bbe2d988699b526726a91513988627c2301b44f206696353cab38f68ca111270ccc6cab887ac3b8bedacc12513ca349228b0d842bc193299ad1812b69c63c2b8233c20121d50793906c4014453e19a62da12c76f03667031f2bcb59a074cdd2417ba3789e7af38ac71335736890dac04f77e0b10529381e930c8c0031f88838efa47772a7b2541963b0c7b063472ccdf6228349cb5619c943067ad86019cd964c64767c838407eb32a4ed9c40581b63e0379d00adb275f6578f065894e8a47796489b994ab9471235455fe1f819f3cc2b378648ac625107805ec8946f1599a8329981a7775523f7c8ef7426d8a31d1d5cc98820186fc7b55076b14d2c7c1533cc3217354bb24661c162aa0895cdc4aaefa666686a0f12d1791adb7392b78d31d6bec44068c4f31cd60a768ac0b056c24864c03387715dc48bc86e1b51a649ce4945708951065f946e17c06f364590e4d16520fa2b47b230f1511fd02aae79bb8fa72791806b0d3e211de92455459066b410bfd4d437f0acbbfb02bfc5e93dc7904b649a6f9a7ab09e2679e13040c8e9754032cc3feb8c2bdc21d8f7aa56ea31370169ebcace98d54362ec24b6b6c63732b882984e58839a7f825b17871820ea9dd0dc8c5e7a15403888e80150cf5a12c5e26040708791d2074df71945d67f221b6d2bbc1b65d37559a7c248516cb4ccc19cc15f93ba6d6085bdd95568cab1069cf13138b83173ea7c58ebbea7516c6ae25bf5e07ddf29a0dcd64b455aa6e050c1d5663245318833cb95702bcab1a11fda773a73454e1055104f917b75d650dfe1c59e807314a096de713e35837ba4f2a5f3991f6ac18302647fe01a05c055ac9d19fe27027cad17633dc0f4693c1f79cf69756e79c9fae7c954a0caf2c6b326", + "sk" : "fb2abf16f6cdb674757180738286b5cbc25ee9eb1229f3781a8678ccd0c5d4219d49352913bcc4a404503d7282cc215ae337ae96c60fefc6a77e5c600962024e25328ac211d6d6c325746ec168777bb4489b04cd869522d44a62d1bb81dea56e8ef8384ac64fad710efdd327410c6b7d184fbc639e2f6c72d64b44bd303c06779be8c2b2cffbcb8abc582a2766efd9503745773ca2c4f92769cfa2b4e9052d06d1adab40137a2419891bc9098898935650197a0e3dba7f6ec54aa9b521624c48d265a667aa4269a12bea0abfc0e705fe422621848a6a87265f687de0669f56c63968569c1d807826ebaac30173586312f1ec53b0b52ebde2aa82f32ffe592fb90363cb3a281f49cf9e16b9ba4390072c5a796c4e4ac95ce2e14070014034a4a92f8c1fe4733c645b5dbec38129a4021d5c1afb9005c1756e37f431d89177142891827519d2874c9d1273967b176a311f041270cb3bc8d0779c3e40bf824102374a55fe5b2598d20d8d30249b59479946936fdc6b0e17a39d4684bd914479110e68c780f8468e3155be5acb0930fbbeaeaa79bd655592a28622cc0553a3123f2a9fe15b78c89501b0943731e71d2ab05fce4129b6324d66991114974dd7e79ddafa46879286d8d5ba285526f8767aaf45184e860e8e23ba7458aabfeb021ec68b19253a19204c7fbc81ca904cee1a2b7c38982c97a01e2330292168198101e0f30c1a429b3d243eea7114de5849e50249ac66bc24e482461895a9d28f4f181e5b036e7299832a14bb02435d9e087f7340432a632bdd84aada7a657402bc91b3b0a1075e39d66741e18855826fef247b6e1496e3866f9a2226c4d2a198c050ae706f007d1a4317b45aec0a1e7a2e359b695dc7523050c564b717e2b1005f570235129d913ab2e5fa99cfeca4b4262d48f0486e6b3c47a61946114c69150b068b92a8853c26a9c4c1016e67cc90cef8cdee024785e58586caa9f990b48546bec008956a1744dd9473f4a150445b8c46a1c4b171712c1b94a9743fba6b389b8852175b0b1d093d8d7c10fb079dbe65771a8120c1930f769b8fdbec6f857025c4c44771842d8d42ade8dc3712d9a9256167dca6c1caf1a95301cb6401afac63a7d0915059b6a7e45c0567c951a3096bf5cb44114091d497352fd2be702990608991feaa7302511e838c9a346ccc267caaa9c5221ef60b317b6c3a18a07ddc737e6221d28667c70caa3cd24533175aeb0a99bcf7cf60aab105385906fb1167cc26923a2f3c390fc2d150d3760d77b8954a61065814b6d134887b570ffa944f2d1299b6e6bae557cdb041b2b084792215cfbe30302f39573e6456f486b8dfc22b95f96b78098ffd343126671219244df0c4443f46473818c78f185dcd4765ecccaf4b67276f697d21108ebc16632be86fa48278d467021a1520ae6b0668fc7471c9262eb716cd307c98a1c205a83be5279b0143806d3aa443cc7e1a255d2df178e7e298d938c97df6260a278052b763e1bbc2f85b1389b78abadb449ce848b0eb8a5b44b2e881ac3e6bc66a2cbb9c998a0f3a2439816809b97d066b87da226907d581d981481fa8833d9aaa2eb6b5458288872c5974d9cf06cb6da269471e51cd2945b1d0a4700800708a0cbaa0e3347235004460c8f86188ae66af363ba5cee88b03a341f5255c329a7d119bcac87c46bd77a1b5966a3fb22a45d89c712909fa8c69967b1fa8878d89b8541b8a1ee6858932e0793c045deffa62250c0d0072a46328992ba7ac4fd72b48512c7448cedc902d9d69ca55626a09d1a700a92cfb1a6bd89291632c74af580e3b4aa932c8c6714337b1d72a3002c6b68b1fc981cd0686502189712f0c5327e1050ef71549aba312a59e9a342c9e76a96de6907cf235b6e3b5e36a9072ac95d856aa7014699ff48bcb7b298e5168cffa740e0a5bb1f65df9cabbd715096ce738bd39bad530a05eb58efa8b9e3dd426f1781a06179736570611c89a6f99b3c0aa5f4ab2737592082ff73dafd7671bcb60a87c5adf3445ca3381a279c6a4fb1724373827494e294ca5d83574e0877e4a31634abb106b81afd515402290318ca8a2511cb129aa52228ba4a64444b761c184a3a29b221e11cc1335e4b87c457710fa4fdee790614249fa060b0417cfaf9bc4fe88632a76766fc8c5ff424849cb91d4351ec621c2335a2d7813c01cc893c646986f7c2246b2bb05149ebda38f00acb65cb8bf53314561893eb0f1053b237915711b7577b18aa963315a3b024629689a52bdfc81e298c059380920aa5bc39759f2f56d2811c89c59acde3a5496f1a8cce9bf5266b363a40cc1b6c78fbaa4241340dd4563a5603413cb73ba1893bdbcb3ff93bb7f1132940998427769d19047bc051506b5b990074e8d1bbe2d988699b526726a91513988627c2301b44f206696353cab38f68ca111270ccc6cab887ac3b8bedacc12513ca349228b0d842bc193299ad1812b69c63c2b8233c20121d50793906c4014453e19a62da12c76f03667031f2bcb59a074cdd2417ba3789e7af38ac71335736890dac04f77e0b10529381e930c8c0031f88838efa47772a7b2541963b0c7b063472ccdf6228349cb5619c943067ad86019cd964c64767c838407eb32a4ed9c40581b63e0379d00adb275f6578f065894e8a47796489b994ab9471235455fe1f819f3cc2b378648ac625107805ec8946f1599a8329981a7775523f7c8ef7426d8a31d1d5cc98820186fc7b55076b14d2c7c1533cc3217354bb24661c162aa0895cdc4aaefa666686a0f12d1791adb7392b78d31d6bec44068c4f31cd60a768ac0b056c24864c03387715dc48bc86e1b51a649ce4945708951065f946e17c06f364590e4d16520fa2b47b230f1511fd02aae79bb8fa72791806b0d3e211de92455459066b410bfd4d437f0acbbfb02bfc5e93dc7904b649a6f9a7ab09e2679e13040c8e9754032cc3feb8c2bdc21d8f7aa56ea31370169ebcace98d54362ec24b6b6c63732b882984e58839a7f825b17871820ea9dd0dc8c5e7a15403888e80150cf5a12c5e26040708791d2074df71945d67f221b6d2bbc1b65d37559a7c248516cb4ccc19cc15f93ba6d6085bdd95568cab1069cf13138b83173ea7c58ebbea7516c6ae25bf5e07ddf29a0dcd64b455aa6e050c1d5663245318833cb95702bcab1a11fda773a73454e1055104f917b75d650dfe1c59e807314a096de713e35837ba4f2a5f3991f6ac18302647fe01a05c055ac9d19fe27027cad17633dc0f4693c1f79cf69756e79c9fae7c954a0caf2c6b326e9037042553968ff3007cdb135e368ecf440e4187e554af9d0ff272911ced339e2f8d320ac3cb0c52efdc753282f092bc39baf4a18783a48ea031a191865eb78" +}, +{ + "dz" : "6500f32c93415cfdbc0bd31d78d5be95cb9060c8cfa2013955b56f8b6868b322393308641a9a4647f230201e1389624a296b55192a9819fcb19ab77c25f95445", + "pk" : "60e29047d95726801982a9349aa17edbe89d04a6ce4cc52b24d989327c855acbc39e6b9880a0783166af6d03043bd34eb427b4a8b32676a874b0c18da60759a5248ed4508abfd90723cb161e38058d4cc3b162c75261380c119c712639e50494bf195b0e6a9d4b22803278832d52a6cbfb542f451c777396ea0ba5c9d186c0786180a4a032d12bba793e2e29328c91a40de06b9b754a189c2a01404f2dc7011b036c969b1455f7a6c05b249e83009b52ca5ec643b92c0e4ec9469e3abdfc2b8dbf5638450aa498c345f126782a5c29ac7673a8db84b0f87086da21728067f3193eed391376317450a3acc5ea0322b189f56accb246bdb6ccaf7252c89be8bd846aa9d07995bf2c2c5be82385d77e566c90fd797bd9b2a5dba704d60341b1530cf3f60f231066a06590f6e3c90f1b6bcf5cb316b482c2817462ba2cd3ea4a5f0744db5128b6d07851e15266280414b6710fbbb7da113c8eaa45974c62bdb7b335315e5d093d11e5176f019dddba19b379399c7c88a9911e17d16fc5194b2a1998d219c4a5fb5531ea6e6ad37052a57fb5560ea39719c378b69c902acbd3324f9c29da73145b409a5f79c8629b4853f65d03eca0a8718dfb7295ae3483eee45bdb265638c0511864a0e471a34d839419ccbe42303fd2c51232246e0a6b81d9ab00c50a7fa656893693a8e6e245fa7b119a14336c9a0f57108ecf87a9c249c01d3a214bd42649e092e2c3c8c89a2e4d980b0bba5340330717a01f5b3abd426ccf6bfc3e5bf8969af7278b0c428cc39a36da6a7c0b8bd666a1d07bcd2845718b755d76fa61d3ca51b3b77486708606975fc377b6ee0596a6f37474b91549f6899a3c4e46a5309f035133aab371eb5599809bf32034a73c8d4c0240a306176c6b09135719ce9478d3f8136c189b715c6b4ce6612bdc973f40238994b763065d08308597ca22a3f4a43681cb500a680a476e1110005c6c6acfbc13c91abf636a7eba2a1f1280bf41293f3031a8abf8af4faa1d617a380e925861185a2bc37a806cb8bcf92354a26340481aa0e6230758a667020145057f8fc55b49b530ad5ba6f490c9a73b8fbde960a8d123c648155418b373b1189e10c9f91a4bb15592da329f61682f70e03143846b09c09da648454901ab938928280628d4a57a636397e5ca0f57dab388c65fd6e7bb5a9a0f3f95892973c990f393174bb8aa669bf28322f80a65320bc69b6460be565265e7b8af86587ad9b43f1c3e5a582773045bab8cc6e03329ab1a4e05b33afcf8009dcc67986831d0a60662b427ff5a7b9991017930524bf678c7d461e1bc95fd441a7693c3b842460ee186b3f973b35bad2fc258972c2c309490163109cd6c87a81a2d30bac5c6766e7d151da391a83a2a5e96904cf9f268706b23e8758f514072b43a6d7891a92e57ad6a9b82246a7f3459cb9cbb5e157a957b27c8192407e9820a906cbcad6794e16bae2b0664811400ca22941e576fa6fa1083571ba17884d5073c83b7a7a1ca53a90ac098eb7dd1627c2ec28d61f86fdba69308e27fa50515cdb19445405a3e6c720651ac5199a1085c8ef1995d8db0a43ecabb5229353316780f12258867c65bf257af667da224c271b02f52b8bcf4805bc2031fd9d999b3c825fff0f4c8cf37e52c6007bb4a2b63952a0c223185", + "sk" : "218284084cc5e95bb4c8a7648d77bd0fa0b91235af9d447d8bf062d322bc4cd25ef1532433193509d4839baa0f4fb63143e64bb1d35408eccc80da5ccd6123344182ad9734602221c02b6cec762eb6416be03562497768d22146dfd3b04281a0542b4ce1070feb56a0b21165ba91b3b06a0dca42b15f556a5a6793de72c4548969f5f8102b49bb8cb47c8890afc022ba481837c301a619c69731743b971302957207196a56b1f071cb330a7d26327a55b296c8422b87456024c9363798a5fc94b5e026a4a3be75765b2827852908303e6ab4764c33569c657c864a39ab991b61a45de4c3d37811fea6bcbb6708cb27b83178c03571566d090647330cf9b91fa3d9b49fcb0090b226e38322603249005d3ccb00d0a65843fc3149a407b672b88aa3c6331cca33ca7a33136ba5bb4520917a9bcb673f22852240b7a577c3a78e2b0c36e32bffe4ce17ea5dbd016fd00745ddf48775e9274adbb45cb4946bd05b4ee0a38285cdc8760fdb871f629524d3e89438c5afa2ac2b5258c3923430ceb99993c9b95fab5ac7563e6e1068406860ac10bcaea63c609531ba80a637d395485111db501f78a98ac1c0241eab362ef092ec2c4306eccd5274a729b7909002831cd65fca5cbdc9440e95eb2b588c1430903078a625c9b67a4c5955c8ea25175ba7244b57290787ccab76ffb6262679b4b4130426d31d6dc754009573aee9443c4a9af619637be8c52e9486415565a6a3c3dee9a5c9f31d6ee716e0db5c219b01287a8a046bb038939baf2939a2a608674212b5743f6ff99c2a3496cbe21414c646d51399e7048ee398238beb8f0b33806ee33655573074abadfdb22df14952937cacc143c885aa0c7e144e172c1b4690cc6144304475bc02a3cdd84126e3fbbc0d5b6bcc875f89bb4883b7c841d6588a3a5b68a79613d4bb04486a2c10ce76378e07b19824d83ba89a649bb3936e6a060e84b8af0c91e1e6cf9e3b03c00320ecc5b493c88e93f9419c1aa71f27ba194c3022634ad0441f3f36280f6c2e4cbc68aa05a681aa4f16e978b0582e09fbcac4b849800616ff820b5764961e299f462a55a3083477fa15827937c7746e01c22cb1a878dba2ab1d1b5856aab05f3960e4cbc9754351c691c646a29bdbcbae01b670a7284c5a608b8609026a28ad2da69e1d5707770a6c5252917afa476d68ad7c5ca1e9b839aa887e2bc92520552523fac50f29559a803ca9da4fcaa58c1ce05e1d987b05d71ccd4a0eb184a9486819a745010ca92937a16c177c97743cb7fe680617279a0bf40f23a5456ae0346f38a5b346358cf76cf2549528815a272008d748a7a5fb3b9454cfef492b52d350b5710a3f5595e1d6473d2134070733bce526128579d7a80ead61611912644ec5171ba940398301ffb282a0150acf047c25892333514ce4595089c0702d7300a76470ff191b8b8634e56c7cb720ad8429adda29294e1a1a92e06be1e4c4b2a37af7a36515d58873972c1b40336132c0d29c0088989bb4c29ba0cba4b878c8c096c6fcc868efca2d03540f9317adb81b808aa3bd1a118d0ad70aba98792b830c7379012df373820c7e70a7805d357733d543eb657334096fd616c6d1097ab106ccaa3b1460e29047d95726801982a9349aa17edbe89d04a6ce4cc52b24d989327c855acbc39e6b9880a0783166af6d03043bd34eb427b4a8b32676a874b0c18da60759a5248ed4508abfd90723cb161e38058d4cc3b162c75261380c119c712639e50494bf195b0e6a9d4b22803278832d52a6cbfb542f451c777396ea0ba5c9d186c0786180a4a032d12bba793e2e29328c91a40de06b9b754a189c2a01404f2dc7011b036c969b1455f7a6c05b249e83009b52ca5ec643b92c0e4ec9469e3abdfc2b8dbf5638450aa498c345f126782a5c29ac7673a8db84b0f87086da21728067f3193eed391376317450a3acc5ea0322b189f56accb246bdb6ccaf7252c89be8bd846aa9d07995bf2c2c5be82385d77e566c90fd797bd9b2a5dba704d60341b1530cf3f60f231066a06590f6e3c90f1b6bcf5cb316b482c2817462ba2cd3ea4a5f0744db5128b6d07851e15266280414b6710fbbb7da113c8eaa45974c62bdb7b335315e5d093d11e5176f019dddba19b379399c7c88a9911e17d16fc5194b2a1998d219c4a5fb5531ea6e6ad37052a57fb5560ea39719c378b69c902acbd3324f9c29da73145b409a5f79c8629b4853f65d03eca0a8718dfb7295ae3483eee45bdb265638c0511864a0e471a34d839419ccbe42303fd2c51232246e0a6b81d9ab00c50a7fa656893693a8e6e245fa7b119a14336c9a0f57108ecf87a9c249c01d3a214bd42649e092e2c3c8c89a2e4d980b0bba5340330717a01f5b3abd426ccf6bfc3e5bf8969af7278b0c428cc39a36da6a7c0b8bd666a1d07bcd2845718b755d76fa61d3ca51b3b77486708606975fc377b6ee0596a6f37474b91549f6899a3c4e46a5309f035133aab371eb5599809bf32034a73c8d4c0240a306176c6b09135719ce9478d3f8136c189b715c6b4ce6612bdc973f40238994b763065d08308597ca22a3f4a43681cb500a680a476e1110005c6c6acfbc13c91abf636a7eba2a1f1280bf41293f3031a8abf8af4faa1d617a380e925861185a2bc37a806cb8bcf92354a26340481aa0e6230758a667020145057f8fc55b49b530ad5ba6f490c9a73b8fbde960a8d123c648155418b373b1189e10c9f91a4bb15592da329f61682f70e03143846b09c09da648454901ab938928280628d4a57a636397e5ca0f57dab388c65fd6e7bb5a9a0f3f95892973c990f393174bb8aa669bf28322f80a65320bc69b6460be565265e7b8af86587ad9b43f1c3e5a582773045bab8cc6e03329ab1a4e05b33afcf8009dcc67986831d0a60662b427ff5a7b9991017930524bf678c7d461e1bc95fd441a7693c3b842460ee186b3f973b35bad2fc258972c2c309490163109cd6c87a81a2d30bac5c6766e7d151da391a83a2a5e96904cf9f268706b23e8758f514072b43a6d7891a92e57ad6a9b82246a7f3459cb9cbb5e157a957b27c8192407e9820a906cbcad6794e16bae2b0664811400ca22941e576fa6fa1083571ba17884d5073c83b7a7a1ca53a90ac098eb7dd1627c2ec28d61f86fdba69308e27fa50515cdb19445405a3e6c720651ac5199a1085c8ef1995d8db0a43ecabb5229353316780f12258867c65bf257af667da224c271b02f52b8bcf4805bc2031fd9d999b3c825fff0f4c8cf37e52c6007bb4a2b63952a0c223185806aea6700e293f433a97e4b2c8485e6b4ac19ad493c4c16a10a2a884d58f5ee393308641a9a4647f230201e1389624a296b55192a9819fcb19ab77c25f95445" +}, +{ + "dz" : "7643cef2d62cc5aaeecf754653ea62294cd2208e5bf3ddeea209e3dc45373d49eac9d531a532770837a854b4f5531f6e0c8d6c10183b30d3435498c2dd142951", + "pk" : "7eac95cb2439a4d5171062a42523cc5ec7caa414654394003942aeeb720d4320c10d609de9c397d0790c585398fe0c42374ac2d220bdc6f507fe62cc592bcab77bb0a5f4ce73a380ba3640b4e491343ab7a33310e7f04c130a70f75b75e6aca5306837e9ac03c84b01c3fa4f5032069f492cfeac1585054a9fc4271da3636639aef3a065f2857a32d590e416866e71ab92d2ac27cca217756b528776a6319014867816d00837e476afc08d5da82293d37042709567052370b553cc925043957eaa3c34d2810a28163e9f4807b492301a4aaa232b1834db5932d20d8866a37fa312ca9cb129116634e95d551764487c384cf00b35682927808a28660d92e51610c68edc994c76a95549c79c162487d445293f0758a43b525b04477c2c50a47a963531b727964828c5b567fb538432c92a8c5a0be6136b9b05c2e68353d5787a0a455dba373ce60f40c4b48be8723ff760ece23d135887be491157b6b4dc8591b5046735c5588cb405057b96de0097f158c67223c5a854be20238126f1203dc59ba6d5bee4d7aa52f1a92441cb23340820d9afe134097bc8512bba1d2097201d6b7952641369649eecb884a4c35848314d2618c283ba9b343922b7cc18bea9cd1a4a3597c146d433692d15c55172847b9cbdda7a049ee455e5e43f6b18a80e60ca48822b1061835431644ee1b307d581add3b21df3367350bde75b1366505b0c88302eb1c6b164290e29204fb005f81567571552a6e22638a0018bdc94e768a9ecc7cc20e50ebc8bc9774c7caea9a1fbe1cc6c925f3fe70fe2f523fa9017b714b7ba820968b3898c1410b7e46fc54226c2c15056ea0ee2c071635b70fea288b88c9cb43a1faad97671e763d04b173426224cf217b2937246ca012edc14c529a2e2d47bf3b15b96804590e5241254a3b1e6a29378522ca0b2598491509127869a1a73dc2f334386c3bc7542f5bab81c89e938071892709f3744ed560c77d43d6ddc2537c544a4f64b19d55917165001bb74d93a1437835442c83b989bbc22ca67e6f96fd44787b8865f759419a409b78f209dc87a89e3ec883441c3ea39627c2524c4f88625594c2b0b5798386866a2c9d45c2d50d438d61c571564040893ba00a7752eb28fbf6b737088103c2a0fdfc87d99b978d2521949683b7dcc98b644504c297905d2417649c0a60ab70b5c674783739fac213f1ac5c5d69f7fe32c5995073e846d12da57cf17a73fb70fe8e7013d681dfb393a4b40922a654473c40b50249362e4aecd22515f256250365660177bf345a2cbd0884933b45d7ac67ef3871969bcf94570adc7bbc2cc948f82b7731a8bf0f980a3c373d30a4e85e1482686ae98501810c28108670078830254b7ccfca27bb0c57c56490e1a5b593816923d722d7c433534980293a1ce65219e0245a2fa049d9fb10fb54917ad82019a51212f0086afa520f34799a0361a083211a415a42b36237d40a5138c5ecfd7c70f5b084a05156df817071b709e745eb3e0252be9b1d89247b6917c72bb9e3ee78dcfb819ef5308f2aa4375578c72d02c348b16fde51f80602d0fe50da8bb5be6598fda0bb8bb1987de7bc575832baf123948215b833821afb7087a65014511a50e800cf6714ab446e189261a2a3dbac768c1e9e232985c430516bd8e18c79aef56cdb5", + "sk" : "8d3542bfa71c67eb9c7a824d7179882305ad248622b6dabebf2c435436bb86777a43380bfe26126b1089399cc3816a435621643d354d7b4989646381b6393851822276641698a597cb173f0888a3db31529a41492a5201608a30cea5114ff52686e874a676c8c9a6a5b8429451c294842904f5d4327f6a3bc30b7ebf35be21aca79126b8c3827f7dba4474e308fd9b2f4a80982d93b4c6bcb05956b5295a59a6703e8b6c4e254606fcb353ce2c2649ab07f8e8275b8536e204847f774e5b7a94dafb15a2c5571d107ee771941bec00519c1b2ee464b12b0cb4c002320c0997e5c516f402960b33363c57851a72989a5570420da7dc1d5ea5c885796bb43a9030f105e58546510129c4506b89a62f03337890d89a40ea2ad1e62ba420a321180108a8a1abaa124c5613c4cb680ed621149315c734209530185ea709d6538ebd8c2eccc6c58a1755df1090881b1ca516155b3458800735f98282b1b1af72697c6de29be547cde7f64ca29b6070cab2f9246e068c99777987c86885ef65340e868196b040007784464cb9b7f30a8410b1bf363436e657b1bc2c62d5c14a8ac3d6b636f7714b641560a0e88eb5982f36c3ce94c14a7fb979ba5110a633a2b70517c0eb0e79512844b50ed0c1b41e68bc3f1224c4cb03cda780a5105e2ce01a4921193dd86ab7f41997f893a5947464e32b2092c48fdb1d84c71a74f087e25596cb21056349b15fc73b838bc679f49ab5041fa9d53049070de760b5f574b2d9ab48d5328cb799ae5efa0c17855ad57001f2cab922c4788fa6be39b1b9656a11be63c57cbca770e5217f54b5d61990c3409d0e1306667b228a27425605b9b5802b6b795ff5a5a423138c098b4758553c14ca7a198c9960e806b2a51ee39a0fc9c7136a876187963b02e6c6e4365a33eb1dd938ad6d2510f3c873eca835c9176b4ff5921ef52dd1f671a85368ca35b878347e42b3a3e42b731fd4051f37ad84f5a1b16c72512aa959e8b0c7107a5454ab96b585099b1db79745311a80ceb070c69b1fec37598fb63f32ac282611a5c37337a0c44c960c35800018e2e1c040978260b50cb51217a22104634118d4287e88045229998a7ceac32f532c48358ed48929d7133d67ba96087586bbb37107f5423dc56f84d390ff281ffb8344139caafbcb140d065912678f8ee44cc3c78c681cbe530637de1cab0d0112dc023163031f7cd70b4d7ac2bd43678989412b0804add344f6541e007a46fbd79dbfd4156892a2d18a05c34c028f46ade763103a079d03a3945ea614d8ccc84ffabcfd300acf38c319b32d92bb18a3870219307c0394546de89e738a9f7d88c767825823b2bc0c368990681d183a1d3078b3bd43cf2f47727fa8bc6a4607928090f57c74539ac06413567c4c968c9ca8c5da0632799526b3b9df7c6271aa4906371b46c0b134a7c1d5709d8548485bb2103eaa27bd515d409cc07db2530a569c1d617a218aa215b7a2bfb0999e791f35d07d1b5b12cfe53dee8a8edc91725b138b1fc7001955991dd32bb9196cf41acfdc773899aa1ecab0854203b421406eeb85820e2116aa746466c49837a69d8e18af5d82c3a0fa0777f9800a187f327ca08e0c1e29e13dfd0ab97eac95cb2439a4d5171062a42523cc5ec7caa414654394003942aeeb720d4320c10d609de9c397d0790c585398fe0c42374ac2d220bdc6f507fe62cc592bcab77bb0a5f4ce73a380ba3640b4e491343ab7a33310e7f04c130a70f75b75e6aca5306837e9ac03c84b01c3fa4f5032069f492cfeac1585054a9fc4271da3636639aef3a065f2857a32d590e416866e71ab92d2ac27cca217756b528776a6319014867816d00837e476afc08d5da82293d37042709567052370b553cc925043957eaa3c34d2810a28163e9f4807b492301a4aaa232b1834db5932d20d8866a37fa312ca9cb129116634e95d551764487c384cf00b35682927808a28660d92e51610c68edc994c76a95549c79c162487d445293f0758a43b525b04477c2c50a47a963531b727964828c5b567fb538432c92a8c5a0be6136b9b05c2e68353d5787a0a455dba373ce60f40c4b48be8723ff760ece23d135887be491157b6b4dc8591b5046735c5588cb405057b96de0097f158c67223c5a854be20238126f1203dc59ba6d5bee4d7aa52f1a92441cb23340820d9afe134097bc8512bba1d2097201d6b7952641369649eecb884a4c35848314d2618c283ba9b343922b7cc18bea9cd1a4a3597c146d433692d15c55172847b9cbdda7a049ee455e5e43f6b18a80e60ca48822b1061835431644ee1b307d581add3b21df3367350bde75b1366505b0c88302eb1c6b164290e29204fb005f81567571552a6e22638a0018bdc94e768a9ecc7cc20e50ebc8bc9774c7caea9a1fbe1cc6c925f3fe70fe2f523fa9017b714b7ba820968b3898c1410b7e46fc54226c2c15056ea0ee2c071635b70fea288b88c9cb43a1faad97671e763d04b173426224cf217b2937246ca012edc14c529a2e2d47bf3b15b96804590e5241254a3b1e6a29378522ca0b2598491509127869a1a73dc2f334386c3bc7542f5bab81c89e938071892709f3744ed560c77d43d6ddc2537c544a4f64b19d55917165001bb74d93a1437835442c83b989bbc22ca67e6f96fd44787b8865f759419a409b78f209dc87a89e3ec883441c3ea39627c2524c4f88625594c2b0b5798386866a2c9d45c2d50d438d61c571564040893ba00a7752eb28fbf6b737088103c2a0fdfc87d99b978d2521949683b7dcc98b644504c297905d2417649c0a60ab70b5c674783739fac213f1ac5c5d69f7fe32c5995073e846d12da57cf17a73fb70fe8e7013d681dfb393a4b40922a654473c40b50249362e4aecd22515f256250365660177bf345a2cbd0884933b45d7ac67ef3871969bcf94570adc7bbc2cc948f82b7731a8bf0f980a3c373d30a4e85e1482686ae98501810c28108670078830254b7ccfca27bb0c57c56490e1a5b593816923d722d7c433534980293a1ce65219e0245a2fa049d9fb10fb54917ad82019a51212f0086afa520f34799a0361a083211a415a42b36237d40a5138c5ecfd7c70f5b084a05156df817071b709e745eb3e0252be9b1d89247b6917c72bb9e3ee78dcfb819ef5308f2aa4375578c72d02c348b16fde51f80602d0fe50da8bb5be6598fda0bb8bb1987de7bc575832baf123948215b833821afb7087a65014511a50e800cf6714ab446e189261a2a3dbac768c1e9e232985c430516bd8e18c79aef56cdb533df23b37987c6b557e4c0f8fa9e466312f19e7e90cd0a67abe6a145cbca9d44eac9d531a532770837a854b4f5531f6e0c8d6c10183b30d3435498c2dd142951" +}, +{ + "dz" : "f8ee95521060c03bb8dacc79f7eb7db640f545f315613a35d447a09e504cb4e13fc3d8392cb53f36ed647364a04e37278a0e0a45b720f4a75c580c9920eba98d", + "pk" : "616571fef73bf834c480630b9532b244d09c8f936e951961bce56157f237b0919097222df3bc6e61f47d846479a1a5bcefda59cdd8b067d19db6d9586fab2fda9b550c5170c2772ad5a4af4a67a19d215e45575e83a8ba5f099e4358a9e493677ce177f36a0f594912b6b850d3f719c155c01b68bf1dc89ccfacccfc6cc38a34ce5b4c48d2e17dd2946f493a357b1105265153c04a98992c949ed774588925c697284bc537b4d795de0463335aacbf80b10cd0a03a88256c220c3d0074ffc6c8c913c919aa19f25206a1cb7d40a50c6f55960a2298881a71a1dbc92a69371dc9a95d45a7bd6547be9414f4c31ebfd3553b89cfd9ac05727b06bbab300ecab599da76a62b97541cb3474b7390cc49942678add66d265772f55515e0623192668fe4c5273e3176bcdc52fceb081dcaa4ed699dedc59b01a29363070567772daddbcf8605bdd1268882a355ca4163ece88637e932c56c43405ac3844949c819646e394dbdaa475e62ac0463b8ce257520b3b4e141057449621b449c09c5b72d10464e59bdf2702a7f4ba1c1c6301bf51ec41bcbdddc4a069abe46d37c09050b28b073f2216a06d501bc38640600185227a63d224589a43391097226d67240619e2804589f4917db7391a4fab6778c91ef30aa41655e3e433854a52c9ce8130b802e82204bbe894517f1bbb4458616b0c309020ecfcc17f6b69cd0bc688963af0fec8f567a86ceabc9a0383681d3729a612987862e2972b6393c2c93a32861073ac3eb1cc636a52dcc23e6ea0af7d3af49f81858743962978245db5a70c34e90c64560b87ef29b5b568a716904c8326481db98c81cca47cec76e32003b36b26aece764c5551ac07c4bbce094b6772b2faa27b518ca5b96094d178f68a7409992ba7fb776117c66e97cb0be6854908aa8203aa916d26f3118842689a5347ba29d337599799691729b812961720cb80ff993d8a124e2027effa1baad40a17b564b0412681a6005888c0e27992faaa370ea3954775949a553b75aa35d5956373da54da7eb51c7e68c05777760c6b9b0a78ff2f34312876f2db27898d3aa4a187110402537f2aac7373751954f3bbc5445da3907429fbc817fb0a732bf4077d4630c93a4bf6785274019c5de6c3d8a66441620491a8537ffa1a50f0baac622cc765052ae0049eabb20d05b987b303d17714c4e79814dc5cc9593bab612359d0c7a3bc9614d0c8eb4e0a7c740520e077e2215bbbcb693a92c0293ca28b4d0ce316b5e14e165fe4745f9665c36a651a6a8ac11a162b4a111e40851ec2b29dba05590140d28aa945b42310659111a4033f972bc0163bc26a5872957c6977bbf8d727d65a8c806b4699050c994bb85651a40c6d590c337c680306fc231b7487305c4155654471c3003b93c206cda82c19f7b047e12b5cb94490f4bc850c4668b366bcb23bff1a744dd3362e94cbbc658178a012d9b784d12e965f4592067b636ed3ca3bdd89c0b30c8bf798f2282c49ed3835b70ab1ebc761b880e0779b5aa34acaea40c83eb0babd6ca11398759415252064c4e70b62d4cc813d346ca789eb86b5d3606bc3239758a62b5f76a709b602ad6987228433a01a8aeffcc22d0d315d59b15e8aca53b02fd160c62db910fddaaabbc4c2df1256095317cdff9f1e7ebcc48f8382101", + "sk" : "a89cac07514fd7ea49de1c8a4aaa75ccf901439529ee48160b4acb10885320b568b9377b475b180cec4c3ea2a1f6584df841b54bc8147ec79457896e24b3592a4864defc44f4e811cac6adec8c91c46bbe80d0ccd9f08e4fdb6fe1509e4932cfae8bbd3d299a389402c0e16e9f44bbb34729ec9ab7e56906491a538681607ea7af800abc2040b2411596c1e9669b2c57fed92d1de814b0351f7c99ba49613e8b8c5348d49142141fd104a6c43c66906c389903b91fccb4e3a4245049c134291b67d0c596894cacc026caf067014415d1335829795443c4924e38308da8b229c129c0ba43b98bcad09a20fe4143607c5117fcc1bb89bec1a32c1882b6c733ab4292158b71a76305856bec631532bf830309d7833e09095e008473ac0928db8202bc971821125ff288054348608978417314ca916a3f2596253cca6018c990c3c54c858c33438b28723889cdfa2a5efb9c20b11ed6228560f897c5b5adb6a3a505e4c7138c68cf550d3cf9c21ee12d83f9baa9778707075ce5ca7e319172a0a926e96b421d0c1a3abc2029a3adc2abb5163a51f07924ea727d979996fe4949fb7892a74c1649da7a382426ccaa0d825766abf51d8390bdf6116d107510a1529af44b37d6561feabb8b0704be246632f58a7968db7d3835bad6c49b29429b9a443571a1c2b1b1c8bddb690b387f5f9798ecbc84d0567d53676e93c38a38b63ea8620702c13be48ab37e02c303b2250c45baad168cbab8b87e7cb9f9e55073dc0d375a88ca92c0370b161bb35f4d4a74d6f1a4402bc32a0b50d8ab576834c15305a7ec70525d5b42fab77286dccde4d6cb79aa7c46f425209064622a86ee94a6f5f3a6f23536b63c9ab5f8bbcd148a30d46fef07c4605b2b81b75d46332b340b6719a735078c3508925f5fd4c1107c69a560cce9f74041fb521fa61a552a756bf638c88a61f103ba9adc02787a398bc35abe3993553ac0118124ec4c67a706c3fc60796ca531ee28ad89172ed5ca12bbc84cfeeb35885abdfb5061d6f774c17c1d5755c437cb7827d8107ca8b420d07331d762e73622bd22b4373ccf918c0b08a954d6ca33a1020127346b981cb750842b9edcac1cb9a6d482cd00a80136575017dac0b0345819a3a099d859c2da56a45523d3e776feca225e5a464300648845bec13b332f3bc78a497a41db4f8e88cd18694887a3babb3a97838519d3c0375e95cdec5596e0486c4a354085201e0ca9c6fbd1754cdaa05a9b204f602793aaae97d240ad11ab2c54cd0eb897f76cbd851038b09ab1442b081e6122e5b495570a7bf8363d3ae1c793a9206785b59204b1e7a46974f2cdaf9ab6d830457788921e72862a499f1ea938d08481ea103b9d6b0294bc0c5f90b6b0566ffa897592bbbc3738a0e69cc5e5a127c1622e6f245fa4607e49064aed22c7d082c62994b419807ec9d8b0c7cc3c993c3f1e2538ba21c21dc885fdc8beac5963ce9732c34a0c34637bb368a87bf2452463cd5e66275e94650d7766845bae2d79bb30336adab7aabe52774e5198af3c9ef532cc5c27780849b1cc8427eb1b451591aabc5cc5a7461a578a36ac371c66841c0ff05a90e41e79acb69c31459bc30dff0aa24452709407af616571fef73bf834c480630b9532b244d09c8f936e951961bce56157f237b0919097222df3bc6e61f47d846479a1a5bcefda59cdd8b067d19db6d9586fab2fda9b550c5170c2772ad5a4af4a67a19d215e45575e83a8ba5f099e4358a9e493677ce177f36a0f594912b6b850d3f719c155c01b68bf1dc89ccfacccfc6cc38a34ce5b4c48d2e17dd2946f493a357b1105265153c04a98992c949ed774588925c697284bc537b4d795de0463335aacbf80b10cd0a03a88256c220c3d0074ffc6c8c913c919aa19f25206a1cb7d40a50c6f55960a2298881a71a1dbc92a69371dc9a95d45a7bd6547be9414f4c31ebfd3553b89cfd9ac05727b06bbab300ecab599da76a62b97541cb3474b7390cc49942678add66d265772f55515e0623192668fe4c5273e3176bcdc52fceb081dcaa4ed699dedc59b01a29363070567772daddbcf8605bdd1268882a355ca4163ece88637e932c56c43405ac3844949c819646e394dbdaa475e62ac0463b8ce257520b3b4e141057449621b449c09c5b72d10464e59bdf2702a7f4ba1c1c6301bf51ec41bcbdddc4a069abe46d37c09050b28b073f2216a06d501bc38640600185227a63d224589a43391097226d67240619e2804589f4917db7391a4fab6778c91ef30aa41655e3e433854a52c9ce8130b802e82204bbe894517f1bbb4458616b0c309020ecfcc17f6b69cd0bc688963af0fec8f567a86ceabc9a0383681d3729a612987862e2972b6393c2c93a32861073ac3eb1cc636a52dcc23e6ea0af7d3af49f81858743962978245db5a70c34e90c64560b87ef29b5b568a716904c8326481db98c81cca47cec76e32003b36b26aece764c5551ac07c4bbce094b6772b2faa27b518ca5b96094d178f68a7409992ba7fb776117c66e97cb0be6854908aa8203aa916d26f3118842689a5347ba29d337599799691729b812961720cb80ff993d8a124e2027effa1baad40a17b564b0412681a6005888c0e27992faaa370ea3954775949a553b75aa35d5956373da54da7eb51c7e68c05777760c6b9b0a78ff2f34312876f2db27898d3aa4a187110402537f2aac7373751954f3bbc5445da3907429fbc817fb0a732bf4077d4630c93a4bf6785274019c5de6c3d8a66441620491a8537ffa1a50f0baac622cc765052ae0049eabb20d05b987b303d17714c4e79814dc5cc9593bab612359d0c7a3bc9614d0c8eb4e0a7c740520e077e2215bbbcb693a92c0293ca28b4d0ce316b5e14e165fe4745f9665c36a651a6a8ac11a162b4a111e40851ec2b29dba05590140d28aa945b42310659111a4033f972bc0163bc26a5872957c6977bbf8d727d65a8c806b4699050c994bb85651a40c6d590c337c680306fc231b7487305c4155654471c3003b93c206cda82c19f7b047e12b5cb94490f4bc850c4668b366bcb23bff1a744dd3362e94cbbc658178a012d9b784d12e965f4592067b636ed3ca3bdd89c0b30c8bf798f2282c49ed3835b70ab1ebc761b880e0779b5aa34acaea40c83eb0babd6ca11398759415252064c4e70b62d4cc813d346ca789eb86b5d3606bc3239758a62b5f76a709b602ad6987228433a01a8aeffcc22d0d315d59b15e8aca53b02fd160c62db910fddaaabbc4c2df1256095317cdff9f1e7ebcc48f838210130a5771b76066feb7f606a82cce122964da1be0b6872ee319832214ec677738c3fc3d8392cb53f36ed647364a04e37278a0e0a45b720f4a75c580c9920eba98d" +}, +{ + "dz" : "b8bd0493a882e3a49b4e0f6256fb1fea0912562fd9ba26ec3d6c9cc12c8973abd7e4b5d8021c486b9c3114d7cbbeb7cd49eba8a61bc2bcae1f1bef30a1daf76d", + "pk" : "36509aa06326ff5cc174f51d963cb5e5b1290eaab649c91d1a03b9cb45400087248ee90f5b9509b9d44f27e814b55b5d7fd341bb663523cccca02c277f1a12f2e054008405dd7b8fb5b78f200266d62b00db2665a728b9231b99d957904d4278c9b99933972006c0afb2d46ab58810bd59492891a77f96b7e9d06eeac63cd9e3a2039a1f30ab0eb4e6a7dbe875253174f2519092761e9684c00726b8548aaf2ab3bf79c8255ec6c1591234672acad20c0bec4a5ff7b4ab4442c2982799d0203f1ddb53a260b95b51980025140556582a0c5dd9d20bfe542f79a743d45095b25c9565c1bfd1d82e5dbabbf37b934bd43a9af92ae5bac65570cd0586621708a30d8371dde11abdb8079616896533b90611a58843ca38f6105164b1de4b227b0c4b14749f5833c5f76cb5aec703b2eca6fa40c7bd224059a4938bf125653901d5d80cb4fa7213e9136d7c0a4f2059865911f68c19eff169af063e76887f192359e5e60516a92fb1842af25599aaf530b08a171d35be896590ef3a9b7878b4a3764a3bc2a800613ef1c2a31fec6ff7a8c8c4e0158202c4ffd35c1a45738d1ca197f23b8858a31dc60770e38796da35136500ec868e209217b9a10c7ae465848c82e815490da5becb32a55973aadc18afb2172c0d086de7e21d309226fd549219c0aae0c672bbe832c515811584ae3e4a59ba98a80e2a0386a187036961b4f6abeb6a84ae8b55b4e95cc9e812be00ba0925ce00ec3390e7936b52482b420b9d051f91a117122a0778c2434cb661ad59050342c63ce986e1b590d2b0b81ff4c3a1bb5a9ab4cebfa96c9f072ddf8332f5a3ad0a156fb5b6b35e38a595f30f2156815656cc487313c75952dcc12adb5b0528ca68bd53bcb1f750d5f24d15d54e83b165440528d83057fa12a983aaad4048c53c62c4a789b82728a94caaa50f7a7df6fc7d07c76727882fb8aab09811a611c5188dabc366494263cb8eafb78eb40a7f33763ea9b51318f0ac1a7a34be71aaf436ae4248346a7a25e2dcbaab226111d96d5d9165b946ae29283118bc34a46409f2eb37c469a36311caa843c112ea83c0364ec2b8b6e9ec68cb8485bfd87ff560912ff21c43d59a1476952e82a2d3f3a00cfb7c49a61e9216b728fcc30861a23e171c2c7954fd85528d911682066db1a062b50a5a11cc385db16d4f4b81785c9b8368575409738683847cd46f9389128414082c5515b5b3310658c54be69a6c3b02b5e0a1b6627e0512999862acc0b34340172a9a0b144627cac4d36fe8d71272e6ac69ac94d1f8c250515580b85d8ab300bb29b43b02195ea7c966947bff9cc323d017b48bb4f6a88b0201956e095b8092b250b53dd9f58ca90b28eab574034372d9f8305b39668bc90e2b6bb77257252b0bc36ee68ad25a7c883691a494c5626b5bd870c45a06ced4f39fc7e21958811a7b7cc93410b2fd8245b45b7462f72033d86ef2fb9b173397bbccbacaaa7177760202a8748b440f82d49218331c3760918c640dc58073883b5721548ed6e529d7f95e02a65cd7bbc3383317fbb166bf751f47fcc216513742596c2e9bb75ee80d2dc16d036b1d45102bc2275aa09b8800213f67dba3987a2f5efa1ae2c7868ce276c5110f462e65b39b2f4f753b3a3d41eeb50f7aa17723bb620b800aa3dbdab7fc", + "sk" : "8a4487c253844156a9eb333c710c70398293058632014350817b2d98d68b4e0c536ee79febe01f3f423836e34436600866ca139193376db576f3920d47181eb7b2264cfa494ddb768bb10ddc002d55d25724d20f9d125cf6718466d7840941cd4783bbffe342f4a584cab59e0322ca151bcaa29bc76dfc0afc525e0791b3f9e6279d56cfc4775d84054b51e604d5ebc1a8922d783c840a9b00cdc58da2ec4a5fc1bda820622e5c10051c3c041571685697bd49ceecfa455e11af28e8a8f9c0b6c74314d2dcb8b571c5d78a7ca354567338344a305338897241d3991f3b4bf448479bb36f9fd3183c703f57f5903918bb71fcc701f586ea719e2e8183ce605575819514f4c59b72aa76bc6c0bfcb7fd19c51ef3612d45a9ecb396cf5b13c96a0bd7d3cd70a84a2ed11e66fa39c5967d080b8f7106bf00a81d208c66fa31c94e548e50849c992608db9c0ac1816ade777d36a04e6989ae0d5c1a703541f2f2ccd4570e9657cdb17202880c0c5ac3ab15b13552f91632255b02eb9db48973a3990495900acfd3b3301b38bfc4374758b0d6956241600033b55f30da2f8d1a046c27c80a403b935905f455943b0459a9a5046bc9cf54b82e175a34e628bf529a225ee25b07d73bcc4a80fd4580dd0ab679185718e5c196e25f4bc89c206409a5bb0d1c233837776832338a1d1b907e493c6240b0c6524a9e542b91f48080011b3ac1ac062bb528399b04c3bcf114a0f46424cef1c1bbb675b1999c8ddb883e7b40a1ba5ca13875bb022d8c088c810601ab2c4844aa916ec2348af4c28b552c08e970e535cb674b388bca5d3566a6edf10d10856b2eeb796bd8cb8b503f2bcc7cbecc528ed121bde4782f717e5f63658cb7251694bf0a4c2ea4d98abc70a4d87994a3317a206c34ae972a54e74d235418a5790cadc9333f2c9c349744bceb28d5bc7ae1521ab708cca937a9e10072f412a26037312145500eea42d04a549edba62185a93c1cadfbc4721fe827db83c4fcca759d575eff93848baa22d23b5a659cc5c3c3608684229bd736dc6452690c742a59b9c9e9adf6aa0fae27664a28c1490bcdf1865802a9ba2a6b49951b3753c12f3ed57fc88bae34d21befb269aa3663793b56fe162a2a47643ffab946f94cd012479f5bcd1a6a6b8019bcc4d38e180bb993d319f43ac809cc2bb8a63c9d2854ab569da8f7c0b1b24088056d799b49d6cc12bcd15ad75c5dade497ad0b312b9739214098bcf2cf90604a72013c3b52994a691105c4060657493947be3b0a6cfa91b83580457da7a6411a984cc661f0b7c59a012c5fa895096a354eea5abf893e2eb7389d0a649481421b13201ae66e3b3b4fbe6818d0f47ef7477f14e792b35ab3fb2737f9ea1c75a3001445920c2b1c65c38ea42a02d017c93924c4b3e7492574c368401276643549f5afb69177a4d807937102686958a1d564a8184624fc47e713b7d9728ae6cbcff5c52ba4966429b9c0dc659081156bc7c398d9a9bd4807907b307b1501a8bb518268897dc8610b649494aab4743e5ac392568b771433808476e6b32dda6940865c3e43077e0d9bbcee84cfcb523895b36c5596880f036648f37d483138bdf24c40d182ceba0dd3e26236509aa06326ff5cc174f51d963cb5e5b1290eaab649c91d1a03b9cb45400087248ee90f5b9509b9d44f27e814b55b5d7fd341bb663523cccca02c277f1a12f2e054008405dd7b8fb5b78f200266d62b00db2665a728b9231b99d957904d4278c9b99933972006c0afb2d46ab58810bd59492891a77f96b7e9d06eeac63cd9e3a2039a1f30ab0eb4e6a7dbe875253174f2519092761e9684c00726b8548aaf2ab3bf79c8255ec6c1591234672acad20c0bec4a5ff7b4ab4442c2982799d0203f1ddb53a260b95b51980025140556582a0c5dd9d20bfe542f79a743d45095b25c9565c1bfd1d82e5dbabbf37b934bd43a9af92ae5bac65570cd0586621708a30d8371dde11abdb8079616896533b90611a58843ca38f6105164b1de4b227b0c4b14749f5833c5f76cb5aec703b2eca6fa40c7bd224059a4938bf125653901d5d80cb4fa7213e9136d7c0a4f2059865911f68c19eff169af063e76887f192359e5e60516a92fb1842af25599aaf530b08a171d35be896590ef3a9b7878b4a3764a3bc2a800613ef1c2a31fec6ff7a8c8c4e0158202c4ffd35c1a45738d1ca197f23b8858a31dc60770e38796da35136500ec868e209217b9a10c7ae465848c82e815490da5becb32a55973aadc18afb2172c0d086de7e21d309226fd549219c0aae0c672bbe832c515811584ae3e4a59ba98a80e2a0386a187036961b4f6abeb6a84ae8b55b4e95cc9e812be00ba0925ce00ec3390e7936b52482b420b9d051f91a117122a0778c2434cb661ad59050342c63ce986e1b590d2b0b81ff4c3a1bb5a9ab4cebfa96c9f072ddf8332f5a3ad0a156fb5b6b35e38a595f30f2156815656cc487313c75952dcc12adb5b0528ca68bd53bcb1f750d5f24d15d54e83b165440528d83057fa12a983aaad4048c53c62c4a789b82728a94caaa50f7a7df6fc7d07c76727882fb8aab09811a611c5188dabc366494263cb8eafb78eb40a7f33763ea9b51318f0ac1a7a34be71aaf436ae4248346a7a25e2dcbaab226111d96d5d9165b946ae29283118bc34a46409f2eb37c469a36311caa843c112ea83c0364ec2b8b6e9ec68cb8485bfd87ff560912ff21c43d59a1476952e82a2d3f3a00cfb7c49a61e9216b728fcc30861a23e171c2c7954fd85528d911682066db1a062b50a5a11cc385db16d4f4b81785c9b8368575409738683847cd46f9389128414082c5515b5b3310658c54be69a6c3b02b5e0a1b6627e0512999862acc0b34340172a9a0b144627cac4d36fe8d71272e6ac69ac94d1f8c250515580b85d8ab300bb29b43b02195ea7c966947bff9cc323d017b48bb4f6a88b0201956e095b8092b250b53dd9f58ca90b28eab574034372d9f8305b39668bc90e2b6bb77257252b0bc36ee68ad25a7c883691a494c5626b5bd870c45a06ced4f39fc7e21958811a7b7cc93410b2fd8245b45b7462f72033d86ef2fb9b173397bbccbacaaa7177760202a8748b440f82d49218331c3760918c640dc58073883b5721548ed6e529d7f95e02a65cd7bbc3383317fbb166bf751f47fcc216513742596c2e9bb75ee80d2dc16d036b1d45102bc2275aa09b8800213f67dba3987a2f5efa1ae2c7868ce276c5110f462e65b39b2f4f753b3a3d41eeb50f7aa17723bb620b800aa3dbdab7fc31fcd120f19fe976236711e58b4ad172d25ce01eb88bc9d6d051c56564a0db11d7e4b5d8021c486b9c3114d7cbbeb7cd49eba8a61bc2bcae1f1bef30a1daf76d" +}, +{ + "dz" : "c0407e41ddf48d333978b89bcf2db01e4613425b456249e76a6f25b8a2827bf5b2dca81e3f5f748d23c9d356a2209f6b2d60247b2e45c9808de497f64f124643", + "pk" : "c5e450ab970d5cc6678db12ae81962959a3d68d8a4fae40ed343cbd2e84322e2342cba7756328fb5c80a3fe07295db0e136621f8acb8eed4685cf21bb28a7fd34a9c6af4a8d1fbc8db21ac4d334afe1b71b87cc1ddba5501d38dd7e74c6c502ba04b8d1039322734418dc438fca99d0bf44f700ca473d07c0ad5094181bad2e90910c08478920461c750aaea6658112933753153aa9bdf090ef91a3f08e7c07278369df0bea9220b7d4c6b6f6a7135a5084aa54ddd270e9d41128d1944d8e7c3e1ac11a4089fe4541324db369445b5afecc41406b277e8bb93f310de57b55deabd8d2ccd2e9a417ed916ebba260e0baf95ebc0fbfc0a1b63b6f5342b3ed7c1ff4135f0a26c3daa7e2d60bbab8051123628abbb3cf9fc6369a46d4deb7ec0032847d7474356aec9a417cae8b62c9c7bf3b077eaf52c622b6a2bfa6ac49a9cebacce996a29f89acf9349363606a86a6696481233c73b273e847798b530b8662194896e22ebbd8f3640864791964069684338f453710d841aa83a2997316fc3ba06e7d6a3855cada69c35cc801cb49928ec66a56cb8a28deb2329d75c6545251ebb8526903a13f5174119b9c2037b06c165d2012723bc817297c42465cd77044436337591f239153629c3140b0ca85783d2460b207268f013988176f4c22d8ef5c096c93a52706931b4399a1849488665026a615e5955d972429eb32213ca16b587b0f7366192366f523732fb1127731cb06bc39f15f35b1283654bf361f403be5a9ab154f786080cb8ec42c8ec356847839de84a23c6e4321136477c12b20ca5642efc84c658323f90c2509b62df865e54072aac311a6d3b4eb9073b17f2291001a37e6ba438918a42663bb4d15896239f9f2b2d17a5c93c024ac595806620a8891b89f7297901a9b63e7c799cac22a515bfb3ca9a4772a5bc9a11154011e4dc0d758868a9f646d5390c631381e8566fd5603902c11686cca1f876322cd7793c338876d82008eb30f32128511a872db5cc0ac689c75266d5a9bdcd889f73dc92f1dc5076f373be64308012553d3109c7b5b2a819afdb93bb3447c878901813849c5fcca97b116ca1c2115961ac4b8c926303bd7f502eb299421cc9cb82f556327584118c6930e03f4368ab915c3df0a46b08518cdd280e17f86824958f0ca8079e857d8ba9a522a49c3f539c845968faf37e4beb443b577646967f4f824c2a706b3a7b74866aa4bfb83dd8e4356dfb1d9f4678a0a120cd2569101b034e36bf24a58c690b69ea27ca88db6645682c13b57d9a397b83772c5357082dbb6981674a772b6a94d0210b14a7703202cff38419297edf92a305a59bc51a022919b1b61bc853abca39721b83a794f1c27d17da71a205571573ce31ea27f81b744371274d6a8138b69ef967adcc75730a652f134b0f198b86a2a670a96c58d45295433851f61850d7b318245849a140a407a60080abbab77abf58d8c46f2580716a0bff0481b1973c804a406dd2bd08370ccabbc9fc7557b26534cda249ba1b3afaf2956f10b0b6ac0a7ef02252f5869a972142e06b86b64684b34b2592bc91b7c5b24c14d232b81880b3844409c6038e06023321dca0f2271144373fbfd47884f3ac96e4bee4dbfea5eedf79fb157b32e2818048bcd9b8e9bb89118362e59c75b4917014c2", + "sk" : "5a837a98d1b7d23c06ac804f9008924221681a5b35141311b383a995a75dcac87baf79b484eac622a6a594cb1ddf122030096548285bf7da99f27a8033f1ad1e442e3452913092a0f666ce6a910968e00b1785658c576fac3a68ac13abdb91255f6b5104d26750894e02a9610a632b558b4739858f72b9ced305cbf9c6929a7664ec49b6f6d18f728664953b77427180e6b2895ba6a56b391cb1263c5154061e1a4c4da221418b363f09c669c6918e911e793b92249885299923783ccee355330118199deb5a4c6890c5e61e45a2c89b3a74657686a9b1987834b309e074133a34a4a11ae92a9bb6a4af14c15b2705252fb69cdd159f5084159681183fd01287555a3ad3314871483c8040cc20894d4a5aa239cca6c733fe17220e55394c2a2063d30497716255bbabdef6c71a925a24f201b096a39ab3caa54438222b23f6c16f07910bb04a04aa1c8299053855f4a8cc852df639ce559abdb7e1a5ec9861491269bb829226bc1e99f392c1c6364d64886aea98f0e25c1f27862fa64aeb017b73f30aaf8cccf543c6e054b23b33bf926125cb263f844c70832aa6f9d66141903aac5b7ee78734949196c54a558210c91ef006e266acf833c77fd97f75b8800178b6e2b89a81764f9e851189e2ab41dacd5ec31604396d5811641ff21a40f9c45bc947aed2c629b457684252cb713de7d25955a66dd6e801bff34028101a21d10c3a6624c234b0640b4c26140e345b778a04929a596176d922dcf737f5198f677467f2990ddd5194fbb5bba6ac7a8f2c90801131bd1c9fc50cce2c802ad8da968fb71acd79ca2abb87991b90e2a76e5d547d96c4a300c32c0da3c29bb40d611b7923c4b6796b8dabe5a277ec1b444050f0b17221744e38582f95faca6807b566948203f00a0b4a8a77f724c067c5c464cb59b8547ed3b2851b9f8eda807317b5147533ab879a26b982187366bfc50266435dc2a96e8b104694f63c355435d6030aab601755b30b38e3434352660ce98e89528e9c54245846c58e914363d61d33d825b1c8c6ae439e6959743f3b6f2b762916f65f6e765044b4a3a6244c37b1b0a671779a840cdc5a7db3703a670c4f5e9c65c9bc814356b4aed09f60162ecd143f86e3b81071c917124615821e4c5bc98b312d2ff525d178a61efa0d465565e5700de4069d3c7864fd15aa9bd4c49242b0cff231aed9a270e41aa5c29e74787524a6085a129795ab5c9049c985304478578a907903aea16934f73dcdd17ed1fab3c629605bd1aef9d16b674a6411123a0ecbc718927b18642acef5a055d47af694c34b300ab6296dc2884984441eafc861ffd7767f306b7cc72f3580ad5214aa130a7e89c634c6b1923415c75dd0a256461ee6f94271027779d0b79c8b943ca32c2f62832a04cfc79786eb017f561c0c5eaa60bb44800e2ccccbd64755c8b6008bc89c52827e737dbb37ababe87980407c503cc5972a34c76913f37085c699b4a95ba473e21c14080d26315db9f17969f6b629b48de94309140104f7dbb4511a8977266101c26f5b1c78e3896e051202ebf9a5621797c775b1a2b3b7f3a53cfb9c90a545473000569214c151088a082a237a8aababa3b69bd3cd415cc1f9ac91c5e450ab970d5cc6678db12ae81962959a3d68d8a4fae40ed343cbd2e84322e2342cba7756328fb5c80a3fe07295db0e136621f8acb8eed4685cf21bb28a7fd34a9c6af4a8d1fbc8db21ac4d334afe1b71b87cc1ddba5501d38dd7e74c6c502ba04b8d1039322734418dc438fca99d0bf44f700ca473d07c0ad5094181bad2e90910c08478920461c750aaea6658112933753153aa9bdf090ef91a3f08e7c07278369df0bea9220b7d4c6b6f6a7135a5084aa54ddd270e9d41128d1944d8e7c3e1ac11a4089fe4541324db369445b5afecc41406b277e8bb93f310de57b55deabd8d2ccd2e9a417ed916ebba260e0baf95ebc0fbfc0a1b63b6f5342b3ed7c1ff4135f0a26c3daa7e2d60bbab8051123628abbb3cf9fc6369a46d4deb7ec0032847d7474356aec9a417cae8b62c9c7bf3b077eaf52c622b6a2bfa6ac49a9cebacce996a29f89acf9349363606a86a6696481233c73b273e847798b530b8662194896e22ebbd8f3640864791964069684338f453710d841aa83a2997316fc3ba06e7d6a3855cada69c35cc801cb49928ec66a56cb8a28deb2329d75c6545251ebb8526903a13f5174119b9c2037b06c165d2012723bc817297c42465cd77044436337591f239153629c3140b0ca85783d2460b207268f013988176f4c22d8ef5c096c93a52706931b4399a1849488665026a615e5955d972429eb32213ca16b587b0f7366192366f523732fb1127731cb06bc39f15f35b1283654bf361f403be5a9ab154f786080cb8ec42c8ec356847839de84a23c6e4321136477c12b20ca5642efc84c658323f90c2509b62df865e54072aac311a6d3b4eb9073b17f2291001a37e6ba438918a42663bb4d15896239f9f2b2d17a5c93c024ac595806620a8891b89f7297901a9b63e7c799cac22a515bfb3ca9a4772a5bc9a11154011e4dc0d758868a9f646d5390c631381e8566fd5603902c11686cca1f876322cd7793c338876d82008eb30f32128511a872db5cc0ac689c75266d5a9bdcd889f73dc92f1dc5076f373be64308012553d3109c7b5b2a819afdb93bb3447c878901813849c5fcca97b116ca1c2115961ac4b8c926303bd7f502eb299421cc9cb82f556327584118c6930e03f4368ab915c3df0a46b08518cdd280e17f86824958f0ca8079e857d8ba9a522a49c3f539c845968faf37e4beb443b577646967f4f824c2a706b3a7b74866aa4bfb83dd8e4356dfb1d9f4678a0a120cd2569101b034e36bf24a58c690b69ea27ca88db6645682c13b57d9a397b83772c5357082dbb6981674a772b6a94d0210b14a7703202cff38419297edf92a305a59bc51a022919b1b61bc853abca39721b83a794f1c27d17da71a205571573ce31ea27f81b744371274d6a8138b69ef967adcc75730a652f134b0f198b86a2a670a96c58d45295433851f61850d7b318245849a140a407a60080abbab77abf58d8c46f2580716a0bff0481b1973c804a406dd2bd08370ccabbc9fc7557b26534cda249ba1b3afaf2956f10b0b6ac0a7ef02252f5869a972142e06b86b64684b34b2592bc91b7c5b24c14d232b81880b3844409c6038e06023321dca0f2271144373fbfd47884f3ac96e4bee4dbfea5eedf79fb157b32e2818048bcd9b8e9bb89118362e59c75b4917014c242f75d6e3755c28f3081ecc9db44f6cc7cec9891756d74093716697781fc8cb5b2dca81e3f5f748d23c9d356a2209f6b2d60247b2e45c9808de497f64f124643" +}, +{ + "dz" : "334382d39164d1989696a2ff77b25a28af8bead9883b5365eb6fcca7c1781cc9aba5068af837be962f439f233593d193ce5e08f7d66efb3389885927b89d2523", + "pk" : "08f7945e6597c9872b0cb4b1401288d7915be8e3715a8391a486047c15b4ab758c8d9b47541c3411417a439bb2144049744460810c01b778879425077e91ae06c1bb831c75e9d1552264a6543266e769b898b66644ca93f9da7735135d743c62a3876c0c891ab71c73c9b88b5cc14de0238c82103fa8f634902a01ce5b15e7823a36aacf6a05639a812221085b38b2ab933a12552c268ccca3cc07cb4e1ca03cdc02b1a5a8231a386456b26878b673644bc3c1613090454b582d5845268f381eb0e70128c1b06f356a9da736222400acea7c58216040a1affc5771081743b5f0721ef2b601a651d8a2658eb9c5ad8599c2f040f791ab5d93c6067ba30014af51766a41c70be6542b7224767301885a030a8d68a795e9924ed844cba1b696b18c5a64abc7ab83a163cae74ca186c01cafb53c05fa535d43786679a429677cd3f672b7c9cdf9224030b32c3a147ee0b2a8e50a0905a778ad9269bf04c2a801a1d986b15cda0ec2f51deec2005d450bc070c5e9e2a9646c3a6029beb907b632f17163b260fa5b75944b00d776862c3c362d06b7852ace9f93afbe9a4d77c548d04c68206277f569875fa677921c671fa887b98866e8c25815fc09d194adcdd34430e2c3725178f6c509fb359e5c3959d72b37a52c303490ae22138dc495bb2bf0c4fefccc89eb6b70764cf64cb2b02699e84a562f076dc4221153d8bc1dc0a29387a15da95eedc808c666b3caf04882188b5509106ba5ba1869463834b48dd9a2d7d6b46de1b83834b7db556a0b624869641a7b77c1f15291696798fd0cc1d01c417062ab36548f4f7b842e99a85a502d2ed70bb82037fcc6237f058d88ab2ded194bc6f65c723656474830581bb92f196e9fac65fbfb0e662c34cd1739ecc28ace01291f24701ec6a836a11f54d44fb50a9150d9401dd96c39b1b02ec73b86827fa1cc39d3ec5d5fcc4523a948a30bb1da4b3588f029c11234b9b571ec3593e82a0cfd428ea68b727622464fcc35e3dba3bf911cdb717ad690147ab70def66a2a66052a3844b7f6866c1b4bc80c106d3155d4bcb8c13239fc96241cb1b092696a50502a887547638499216fb31379a45bf7b43f92175fe282d98d7a4ad22844661256b711228a31fd2b01fa8f72dd357c455768a77cca28e6984913c352726176e2192de562781dccfda024fb4315eb5b14b9430bf0e783ad77a763b631f6c03c4b45aba24a88e85b70fc3b1c3049447e688c3f2145072460b838546572a42f4659a71a95392255765426451f137e8b4ca64b5c24e5cc74a816a988447ce07886cdc59eadcacf5cc5b17b4b0d058c0b3b610df489066e402ed63a5d155161bac9f2e82bd0e18cf46476935fbcc0daa0ccbfc72cae9b217d3adcb3ba7e0b759aab167ebf40f6cf92eddc17ec44508d051a6302372faa22a993386201827bdf3a1e932c093ba2cd1bb347096b53919218f321bd761abdc6ca5086c51b0c471a6c2781d1ccf20bb567ce472fc663ab10b75bdc6642832acab5c5d4db37a46572645a166edf46ac243805ac78e5c483e25624dab2aa705b9b3f6d01bee692351fb4301c562e30a513f6c73d55c0bdcf439f3f62f33e42f7f876f5314cdedfb4526a075924c59dc03d5f604585571f7e69c7c8f254bcc5af0ced187401efacef8d61e38", + "sk" : "dbb0bec6fa248682bf1eb3b226d9bb45a19beec69998797fe4d9275f1a6ba518ab41e117059338f8052945a36277678f84f761fcea21b49b9e2c85bdd2c78df17a04f121c423ba89cf15c90bf34ed5e341156206c2abb93b8924d6fbb1182ba029178be8b5b38ed868c86c54ae69b491f2450b96205484b7070aabfce83a6f0a024dbb837cf26ffd613d106c6fc6fc81f23b838782b72f7873c9f6735e71ba2d2c7f80c29efa2aab162767b414b71b1bbc5258aa61a984b2202e06286d8ae9cd14d2bd7b229e039613eb081bbedba792297cd6672241abbf5643703b098fcac273236687cd8ab0e4d21fe2e15d786c37a09741bc493bbc908f20eb7599e6a5a102030eab2ad69266ad30696eb1072793b6aa613734554f681678fb8068aab0c903580f6329baea7155c1bb09e846ab15427e0a092c3213ad42e3c1cbcb48cbca59aba88b9f60babd8087b461a2745c2973c04a8d11cbca9b3a74f7415d975004db90c4b985d990ac3e01bd72a446f2e13545052a99371e459c589ce203012182a2746d74e5b914b872678c999523b6c5ec790f986ca98c448117bc397643c339432ab2b058e340e098ace6c6a1b0e1472e8ba11cd898107ab9454a08b965329ce8758c199f10fa5c914cc236706e0a35cb5f2c4bc749b38e2184486a88be97127ec036fa78a5780b3f0515b391ea6598d1b998141d3461c141b54ed1770ea2938066d40dc3256bc6da09184b7957070391a1cc8629181954669da8c33c94511020750387417f87080907bc8e48332d293cbcfa6409e814b79154b135c5a721b447d45ed274731a30215f92004e30ab64fc87b061c8940ac9153957a21aa54ca9be2ac1acbd46283ca83219200788eb152273c61b860aac104f66e8043e7727216141097878d66a30eeec7820f6c1f140989649c2f2354b81597b298826225332aaf6ce5b6ca31ff986a665067272c6a190a454bc3654699dad2c3660e371571c8cd0b9b1e0ec5ad43106758c3b2adc01f2e46a95f662ea6733a62c2f7f67521065655c1c9e40615584b553a4697141ab010ee4a2ac76c4703043dc41a675309774c9279ca11c717ab9518074f9c77d10c4b973fc9e1fe1026c9c0dedf68db0d7bd63c67750db13e4120eddf4012ef42dcd7907b52bccba359374b48ac4988f4b6731c20295eee277a09a1140c30a6f6062dd152425d9385046417ce4808c7a44046b3c3773c90c40589524acca23b4755b23b267b2c5904cc3a634750b863bbb44243679483997a52a703ed867c57a0ac8227bd4115e88e9461481bf5ca1c6226283ab201844d25f2a094955d131305b5f1bd91789789f4790c193da4f4426693b9575af109b0824154f431ff1171e3c48686833beb3b3a4f31388f0348f6831acdaf70fb983502e8149b71511cacc7ffc0a411eea2e781656487139cffb9f7089388800ad6310015dc85502b5ab19e2cea1fab7eae59ce1429bbfc55471bc8644204596b264284c31c21b1e3e64909ec044b0342fff306486bac1c5c2aff2e52775e7338fc8b9c6d8a78538473ce1181b08048c6129eff7ad07c85bd24c2803c57a28eccbd3623713a5368c7228bfe0547566a43a1788e9e4489f8747167b6f08f7945e6597c9872b0cb4b1401288d7915be8e3715a8391a486047c15b4ab758c8d9b47541c3411417a439bb2144049744460810c01b778879425077e91ae06c1bb831c75e9d1552264a6543266e769b898b66644ca93f9da7735135d743c62a3876c0c891ab71c73c9b88b5cc14de0238c82103fa8f634902a01ce5b15e7823a36aacf6a05639a812221085b38b2ab933a12552c268ccca3cc07cb4e1ca03cdc02b1a5a8231a386456b26878b673644bc3c1613090454b582d5845268f381eb0e70128c1b06f356a9da736222400acea7c58216040a1affc5771081743b5f0721ef2b601a651d8a2658eb9c5ad8599c2f040f791ab5d93c6067ba30014af51766a41c70be6542b7224767301885a030a8d68a795e9924ed844cba1b696b18c5a64abc7ab83a163cae74ca186c01cafb53c05fa535d43786679a429677cd3f672b7c9cdf9224030b32c3a147ee0b2a8e50a0905a778ad9269bf04c2a801a1d986b15cda0ec2f51deec2005d450bc070c5e9e2a9646c3a6029beb907b632f17163b260fa5b75944b00d776862c3c362d06b7852ace9f93afbe9a4d77c548d04c68206277f569875fa677921c671fa887b98866e8c25815fc09d194adcdd34430e2c3725178f6c509fb359e5c3959d72b37a52c303490ae22138dc495bb2bf0c4fefccc89eb6b70764cf64cb2b02699e84a562f076dc4221153d8bc1dc0a29387a15da95eedc808c666b3caf04882188b5509106ba5ba1869463834b48dd9a2d7d6b46de1b83834b7db556a0b624869641a7b77c1f15291696798fd0cc1d01c417062ab36548f4f7b842e99a85a502d2ed70bb82037fcc6237f058d88ab2ded194bc6f65c723656474830581bb92f196e9fac65fbfb0e662c34cd1739ecc28ace01291f24701ec6a836a11f54d44fb50a9150d9401dd96c39b1b02ec73b86827fa1cc39d3ec5d5fcc4523a948a30bb1da4b3588f029c11234b9b571ec3593e82a0cfd428ea68b727622464fcc35e3dba3bf911cdb717ad690147ab70def66a2a66052a3844b7f6866c1b4bc80c106d3155d4bcb8c13239fc96241cb1b092696a50502a887547638499216fb31379a45bf7b43f92175fe282d98d7a4ad22844661256b711228a31fd2b01fa8f72dd357c455768a77cca28e6984913c352726176e2192de562781dccfda024fb4315eb5b14b9430bf0e783ad77a763b631f6c03c4b45aba24a88e85b70fc3b1c3049447e688c3f2145072460b838546572a42f4659a71a95392255765426451f137e8b4ca64b5c24e5cc74a816a988447ce07886cdc59eadcacf5cc5b17b4b0d058c0b3b610df489066e402ed63a5d155161bac9f2e82bd0e18cf46476935fbcc0daa0ccbfc72cae9b217d3adcb3ba7e0b759aab167ebf40f6cf92eddc17ec44508d051a6302372faa22a993386201827bdf3a1e932c093ba2cd1bb347096b53919218f321bd761abdc6ca5086c51b0c471a6c2781d1ccf20bb567ce472fc663ab10b75bdc6642832acab5c5d4db37a46572645a166edf46ac243805ac78e5c483e25624dab2aa705b9b3f6d01bee692351fb4301c562e30a513f6c73d55c0bdcf439f3f62f33e42f7f876f5314cdedfb4526a075924c59dc03d5f604585571f7e69c7c8f254bcc5af0ced187401efacef8d61e3843d6c8562cdec0e87d00c8ca8060da3f031ab663ddb43148eebd67969b7fd490aba5068af837be962f439f233593d193ce5e08f7d66efb3389885927b89d2523" +}, +{ + "dz" : "6995143e8eb8a6e93840f76eec844f67d2b5f75b1839a5040337e61f9806764a0f4dff8e56f68440836a072412a30d851ace2c7c6f02d60e7a8420001a63e6c6", + "pk" : "d743a9918c149231c6bdf338098c07f21064775b6700ed30fb2153478b67b0f344da35ca35e4b7c289a503d5ab9eab6e374279ec8ab67b2264d7b9b80d6bce26098a305734e44342a5078597f3bd574b931c3c74461c8da856239c24c576815f7f48cfc026baeae328a8207f5091cb7248615ac076f12763f8b63c0b75a1ef075b6e1c61b1c3bacb9c8895286e30729ce083b90df566ceba4c00e06214c295ab2b95e2b70032e04422572c87b475a63b53fa84ac9fe3c8bdd3cd06c13859b263d22a588b8126f2c615e3a705e0ba960261b47638a9e83c5bd3f791b362652290c5bcdcc4f3c93909431a4ef875c5e30f0c311e5e8344deec53c3b4bf584932f168710f66cbe718886e2ace059034fcecbe39d50d012c0ea26b8cf13807f1117f32661cf997145470c8aeda68022ccc43d1bb66732f5966c11ec221ac678bcba824f43c3eda94401c17c4877490e4393404db53a27b1dd3aab78e152a58f3741e1bb1b9a8202df64434ea9c5a8c9fe7584ea538250da92295d3a4abbc3e392a36cae9af1cc51095b2b2dd97ba7072acec4b7b83bb6d284c5fb3fb634ab3012e8825f8748022d8cef7367ae46b021df68aa8239d06c09fe0555e07dbc356293d41bc4f1e133ddca95d2298b2aea88aea5637d262390a79980220095d7116447c5d5b6ba2b962c794c899f45860658a0a530c7669134519a501e5a0759f9a50777a2a6dfb942f98b50067455a7b692fb1cdc2c10f64e9114b29cbe173ac4fc2adb95c550ae7a55387bf01ac3c45222fed7bcf9e240a6d9b0d088c032aa9714a6a55c692635b6911d92353c68794be250dcd65782a6674f87343a6654324f47f5ac9b384b22766d0c96852753a4449e08371d5128f31831ee766219e910b1f6267a57bc991da5b2b69a5a9212ba06ac917d45c9aa25bc1b513f7144217e84f1693360ea0690e51688a704c45cb6b1071a0e9a130abdb6cd3b52b8a429c33d126cfc10c73c928da9507aab00950f37e9bba0ab981394b137e337a88249100da175fe9299de1d1130381b3fcd265f7b36c00959b5bc2c150eb7dabf05bdf590e32e063a01a7cff6a9a22c56752c8b948502f3f8ac5ca444e10bb6bead1c7557b2bb2e37d55646455162806a7778b1938fcdb7da3e64c01c4a36a847b77958d27ab9defa6256b6a30a9b9962175c13721cd28e979e0d60196ba8c3c940aa4718d39a9b280486a6c2264640c4b09642499957be9642b6b545dbcc868098332fb103d75e38eb7ccbee64a341b38b0097479c019257be03d5d290e89a6a6f0b61039b128b46b02bcd750a9496ec4fb8dd6378e1ac77aa9f37a75d072d268c365725926cc76b58b9da040c173d7732e1401ab222553d6aec7911d052c569c59393997372e548086abb4de201ac1c17f25d76fb58c4ff3380cc5965720b989f4aa252623c215369076e771fac786e7f0ccdd917da64126fc610eb76948f97a5c3116869a11a46e612d9df04be0b1af0e8c8bb46607ea4bc4b4b04b3f79a30a2a154691a79217537b97a7dff6ab4edc9e2ad6cd97d3aef52837aeb232f799a3ce30a6adb88f6a0aa73fea00bf0146cd5447c6dc483b4955a0a3c241e7cc353c2c7085b84c5162a49e7d61a2d0e85a009833f3eb2305d7d435e2a4c81f358aa8d0dd50628096f4", + "sk" : "ed0c4dcbcc3304e1646a04b9675b94430b49a83bb1552c211f8928c47785c90422bb658f33890f3fe25078cb0c5d52ab737c647b2080e32164de411c489664d5ab23130c1b4a409c1c0296bce722bffab9d60ba4854c9887f0089567994e3375e438069bd40cf0e08e1de134c1f902d0abaccffa0e866122f28894f5275a8a7c2be316811032738f99b53af64c6b346fca072ebb38b665ea616687042b240c53501e18a424b5150b98a4897a168e5be9b9a1f04f0f14858af0666e177ba7f52be6508674ea48fa23313a71372be5a718a13d41f4887892bfc013889481339b2438f8516b24990d70c1159581a109fa1cdd460e6910465e71ccc362798670933052bb03e23768c3c255d0bc7f002e7dc299ac0145bbb585b9682978302aae26047bc8a2cac90589da65d604abaae2b36bf78604d33e23a67544a79fb8131970199116b5bef702ba74506cf72965d7d8bd8b438935c1c8a1e535806009ea22a5ef4b215003b67627358151238bd50391c8384a938e7098929b7870f87321903c819c6480c992cddef1c969e4a1ed4a98d367994394571ae93a61b4336d537140887c792290a196b01bc7c30e364618fa371ba975f49b4637f9bfcc7bb1ae789156c4ab2fc6cd62195a44c7572cf9239c3b951bf636b43cccae63b82cc2bc4bc6a03ba5a087c534339905f4280b7a79186b2652f3582c1865cb6ae4b334f75cd7f358f2bc69cd1b0d21a7ac35c926772ba764a72157e51e38cc66392a1bf409a068e033b00b4a4d04516873516bec242ce93ec073c366e8534e4b55fea906daf090eee9a1fa4a17e61a644ce54536f70871e61a2a728ccdd7c1e702869a28a2ade4cd234119229c9cfe80ac664bb2016125b3822ab240989e79a72cc26207ea4b139bc1bf5a257645b9b372763d4a318d4647024c797b8a1c2d49bbb4857cd1272f56b8342c46541000c84bd676bd533e9529072e77a8f73164fcd8443c3079c1ab5ede2305e6c5c22af691a25ace01436e43d56e204b4dae93cff827c061d1354acb6cd4070c92bb4b145bb0649a6fb8985e03e4a82aa178161a2bbbf23562b342f4818100b502c88904c196c08920aab3ea154c9535ddd8c9c12911500a38db80bb70c3794ee15f7a44097a7407851007b40801d16c417e5905eb994edaa2807b9c7bef6bca9065374b856f95f09fdfa2751c20c5a42a3adef757efb8276303a6e65c4cb17abf0f97c29581139fd655d4d80224275799645008f42ef508ac9445c388a989b3ac09627041741c30b433a0d0b81a59d237753ace7a89c1dd0689cee8663ae8497e9bb885436021d4ba553c706faaafe7c8478e346caf5280e171ba24672e850cb80e491be2195749a8cac30355f5b386e47a65b22592a1f7b09317cd6f3449bb22aba8c2711e979e898a2706d80fcf52af28a68f0f7a0f6c3221ca73918140447e166a00669929b915c4aa507e49672b45154c92239ef0190b086b65fa9e4ce7995e39166c8ba70b5026ee2745c2cc409e40c56294a9d4539101cace01a2861d31924d8c3f7e824fa8bc552bf6b70c042bef1192d1517091fac862776c9a33cec6939d89a30130561d400552c195c702bb9322378a12e144a0f956d743a9918c149231c6bdf338098c07f21064775b6700ed30fb2153478b67b0f344da35ca35e4b7c289a503d5ab9eab6e374279ec8ab67b2264d7b9b80d6bce26098a305734e44342a5078597f3bd574b931c3c74461c8da856239c24c576815f7f48cfc026baeae328a8207f5091cb7248615ac076f12763f8b63c0b75a1ef075b6e1c61b1c3bacb9c8895286e30729ce083b90df566ceba4c00e06214c295ab2b95e2b70032e04422572c87b475a63b53fa84ac9fe3c8bdd3cd06c13859b263d22a588b8126f2c615e3a705e0ba960261b47638a9e83c5bd3f791b362652290c5bcdcc4f3c93909431a4ef875c5e30f0c311e5e8344deec53c3b4bf584932f168710f66cbe718886e2ace059034fcecbe39d50d012c0ea26b8cf13807f1117f32661cf997145470c8aeda68022ccc43d1bb66732f5966c11ec221ac678bcba824f43c3eda94401c17c4877490e4393404db53a27b1dd3aab78e152a58f3741e1bb1b9a8202df64434ea9c5a8c9fe7584ea538250da92295d3a4abbc3e392a36cae9af1cc51095b2b2dd97ba7072acec4b7b83bb6d284c5fb3fb634ab3012e8825f8748022d8cef7367ae46b021df68aa8239d06c09fe0555e07dbc356293d41bc4f1e133ddca95d2298b2aea88aea5637d262390a79980220095d7116447c5d5b6ba2b962c794c899f45860658a0a530c7669134519a501e5a0759f9a50777a2a6dfb942f98b50067455a7b692fb1cdc2c10f64e9114b29cbe173ac4fc2adb95c550ae7a55387bf01ac3c45222fed7bcf9e240a6d9b0d088c032aa9714a6a55c692635b6911d92353c68794be250dcd65782a6674f87343a6654324f47f5ac9b384b22766d0c96852753a4449e08371d5128f31831ee766219e910b1f6267a57bc991da5b2b69a5a9212ba06ac917d45c9aa25bc1b513f7144217e84f1693360ea0690e51688a704c45cb6b1071a0e9a130abdb6cd3b52b8a429c33d126cfc10c73c928da9507aab00950f37e9bba0ab981394b137e337a88249100da175fe9299de1d1130381b3fcd265f7b36c00959b5bc2c150eb7dabf05bdf590e32e063a01a7cff6a9a22c56752c8b948502f3f8ac5ca444e10bb6bead1c7557b2bb2e37d55646455162806a7778b1938fcdb7da3e64c01c4a36a847b77958d27ab9defa6256b6a30a9b9962175c13721cd28e979e0d60196ba8c3c940aa4718d39a9b280486a6c2264640c4b09642499957be9642b6b545dbcc868098332fb103d75e38eb7ccbee64a341b38b0097479c019257be03d5d290e89a6a6f0b61039b128b46b02bcd750a9496ec4fb8dd6378e1ac77aa9f37a75d072d268c365725926cc76b58b9da040c173d7732e1401ab222553d6aec7911d052c569c59393997372e548086abb4de201ac1c17f25d76fb58c4ff3380cc5965720b989f4aa252623c215369076e771fac786e7f0ccdd917da64126fc610eb76948f97a5c3116869a11a46e612d9df04be0b1af0e8c8bb46607ea4bc4b4b04b3f79a30a2a154691a79217537b97a7dff6ab4edc9e2ad6cd97d3aef52837aeb232f799a3ce30a6adb88f6a0aa73fea00bf0146cd5447c6dc483b4955a0a3c241e7cc353c2c7085b84c5162a49e7d61a2d0e85a009833f3eb2305d7d435e2a4c81f358aa8d0dd50628096f43cabf1c47e7aaada59ded4fa8ce378ce1d9eba621ebfe8cc96a111aaedc4b6cf0f4dff8e56f68440836a072412a30d851ace2c7c6f02d60e7a8420001a63e6c6" +}, +{ + "dz" : "995eff7e0d195c6d0533f3dc194d47e60f9ad14696144cde694d60a95f3e96b4b28f7e7a15a005f92400ce33db073d49b53871594a88fc45e0f94207b5f0f2dc", + "pk" : "8e4458305ab8304a53b5c47b42911ba1b011c4da11c08b281e625f6f37815dbb1f3908c4c1646142b14d846b8400114face5cba669179ef121436a1975845652c5cb4ff62fa0073738f0264401adbb78b44e61619977804aca17deea16bad48655133144781b196c2a949bbc9aa8714758061465a9cfe09f2a1316ca875523e07fba515296309b6b7391b8d192012278d684b2527318f30a7c1e598a05027409f65a7f36b57f693a660c7a9f2b0bc38420128b87b005b5ce7631e4a10ff858831cb0112f5b6f04334565563e751820da374ce2819e4ed9bc5a959eedc4052c502abc54baf3fc0e426b77de7a274f81451070042e70c19a09421454141d2600df76a740423cb887065939cfb657a76785b35a5868401cb4d88ac8194769ad2499f2f20ed2a188e8e47e918cba7342b4c8893fe411b47b058b0070771161970c4331ef67be34bbc4781171bfa19d51e11612f93cda611f4ed88f85b87e8beb6359eb410e7175ef6171faa03e29e11ea8a6caf023c357a87afc652a00cd422020295bd34170068d31b7a058800026a49fa1f7523ebc5544389cab259815114d4b01d089d3cff6956f5d0b5a9fe652825b1150e21d11f562196892ca41941b46018ee73683e008525059496a07bb029737103b729b1fcc13ac3236b47c63a6ed4458a9724ef7b62361e75ba726be6774cf6b3572657b2a6abcb69182cd3b880328bc4f52c075c150bb22aab08cb2326815712ae20cf1f257b9e6ce0725782e9590191b2055a45c4467c5e7d70c35b8a61a48a317022c298b612782203a820f2161844f6a6fea58ca9f230713c701aad2700bdc951fc9bb8f560db9e99f2849afefea6c366c982f3680dea24891c631a1032d9d884a5ad9a11fa8331be85f1c91c6de2b4143ab403b153d9dd714db314c683ca24cc45f86c2276058be32ca1cefd4116ba386069856c6128ca86a63fbf6c15e876d63f738f847a32166b1592c3307d9c6190c5c42b7ab756ccb394c7c26c28fcd158bfdac9f04c99e30254d500cd0da1b9f2b74823f14283a888bdff45ca218b89b9450fba868ea9b1a5858509137160db31aa292863ed216aef822123c294a825e26fa3adee0291ab37c1462c89a4981949bb764f4222b3527dfd8a715682d159ba380339971857272c7bd7442cb73739c450b58cbeb6936b8cb619654037856935376acab92026bbad18c512dec4e19671180599e01651f008c3a04007cf02535ad7608e1e9257fbb04e419976294702e84341531b95e1b20c2b152a4d849649113c69a8f379b5d72aa86e01a4c5202ab2e276712f1131c411d4072cb45147c562c60080c56eff7aa7d90c4dc293b01ba935e345b88faba62dca043d94c4a666786c35f9318a579a9b67e429144240d206612a6d802fdc24aadcb42b0db4251e06df92a67e632aa4a29000a77cb2fd2959f851288464c824872ae6a9fa1bb3a71d8879e303c51445956ec8ae49c4ae6ac4de2047edbf3c0b23a29b8b86b83cb24530b0d17739331292bab85868e4a9bcbb2b4d4514e52d9afbf66172ae560c08c7f9cfc0c98ea4ec9c785ffe76ab5098e9f3c5ead6a7759b529661b50e0368246c5afbbb9b876c8072c1c1ca63a4e6607fe4286fd2062614fcfb544fca36edf0785c37bb6f5fc33e2b9d9d03a0a6c", + "sk" : "2e497feae75af1f280abf2085c0321a00911d5008bf8a4042ba44691367fccfcc2d496cc40e113a0d056b5468b190c0e2e629f3264797f0c3b647865f4d782a9601df6bc5f03c1437a23b5d222bad406874f1459f1f9aa3ac061a20677d9d785535cbe7073667e4c916725af4d7302cf76bc3c23ab89666a2019625044a8bd954df6d68c2114b31efccb7d91af07f3ad3faa852d4162fd847ae7a11d8e11133089b9307806a9237ae3a9949043b10107acc9345c17697307e0c6c3ca1734f6cfbde73c6a09aa1b8159c51179ea8b93509b223668849b1b7c59118033f969b9d34b354b32bc0b7540d3ccd2995bc36abe44c0394ef5724b058d0a575947024ce6e72463389bfb36bb851864c38097fbac7204036de72cb0da94cd2f98a1e52c1e630748a7c05838ab53b2d33b0d541c1bd31a2ba803f4205616423534c982038622b70ba4778886f2d15aaa681d6468848fb0601d7097b99040e9e8a981749f741127c6a0000b0c32e28976ecd97514c2aa15f82979497e1da91bd3200d4b0ab373e41a56aa9aba24693cf9c7939cb8733c27a7707eda2aa4f3f304c5215edfa3cc3f785bc0ba83d9f291f8787fc0032f112133fce87441b473961cc87629337cd4acb5367432cbc7407585a3e2463de228895327e883604a19ac2c46389f1b0706f720db8c17f709a796e03d53046c4ab2013afb40ed73247d0c52b0f88e2c9100b1b31813346904978d3bf6bf13b4a6c54c3894f2a2266a9987a4c8505cbd94028ef7963c97d80575549559bcca5d78c99af532b31a382567a6b1e8c56babbc5863144fc81c6322806a6269215740af996b0adaa72f425169517d1e48ac1349c343214c52482b9d19aae42c4a6ddb550040b30ccc82e7d5578355b7313a1f84f872170a6107a52008aa47988a5a78a15a6d070e308c59bc630d1a1292fc2a41c86967b4a3b3ee312ee3c2327a80cb9a112b07b9b0e5858191164a7a87427a8423f7116c2e84377af5cef303b7e9069661f1047c15bc52876c45864dd78854d0f07fd2e530fbbb9b13a4034cc38e34344d5ec41cf544359b93ccb0338bcde09e9b938d5e0c2065126ae81581f62668afc819f705af3b82bca5921699602c6af9810084933c438d4de95a6691ca3ff425fa04b614bb973d899bb8748a7571b112545548f08ff98931eb555f8308ac724a8ad09a90f109219c3032f4013cdfeca92b4cbf23e528ab6abb29370361baa8f74c3a2ca8a29d6a893ec06e60979e351b4ff6247b8fe3923cf027c55363a9243cf9a237ff09c0666aa7b6c56b17a63fec016b4c15cc70c59dcdf3294cc0c72df53c9b0b00d2383e7f48335108629762793fc70642ca91dfa1ba6d97a1a36a55fa6c9d73246a3930b31fb644e34579c2866fc4c5671667b0dcf1aef82bcce732052d766673b398aaec441cfa73dfd3b463e8aa018c4272eb0c3ef15618f9acad61bcaf64017648539c766eabf8038f5467d446912c98836055496b1b7d777cc82eb255766568822704a12640ade87d0ba066b4f3405177c9e1e41f624c5ae055887d68c97be0b0eab254dc3756d00bb8e78676ff62a94f842e9f5774b4f07b723577c742bf4623b0adf246f87c53944cbc8e4458305ab8304a53b5c47b42911ba1b011c4da11c08b281e625f6f37815dbb1f3908c4c1646142b14d846b8400114face5cba669179ef121436a1975845652c5cb4ff62fa0073738f0264401adbb78b44e61619977804aca17deea16bad48655133144781b196c2a949bbc9aa8714758061465a9cfe09f2a1316ca875523e07fba515296309b6b7391b8d192012278d684b2527318f30a7c1e598a05027409f65a7f36b57f693a660c7a9f2b0bc38420128b87b005b5ce7631e4a10ff858831cb0112f5b6f04334565563e751820da374ce2819e4ed9bc5a959eedc4052c502abc54baf3fc0e426b77de7a274f81451070042e70c19a09421454141d2600df76a740423cb887065939cfb657a76785b35a5868401cb4d88ac8194769ad2499f2f20ed2a188e8e47e918cba7342b4c8893fe411b47b058b0070771161970c4331ef67be34bbc4781171bfa19d51e11612f93cda611f4ed88f85b87e8beb6359eb410e7175ef6171faa03e29e11ea8a6caf023c357a87afc652a00cd422020295bd34170068d31b7a058800026a49fa1f7523ebc5544389cab259815114d4b01d089d3cff6956f5d0b5a9fe652825b1150e21d11f562196892ca41941b46018ee73683e008525059496a07bb029737103b729b1fcc13ac3236b47c63a6ed4458a9724ef7b62361e75ba726be6774cf6b3572657b2a6abcb69182cd3b880328bc4f52c075c150bb22aab08cb2326815712ae20cf1f257b9e6ce0725782e9590191b2055a45c4467c5e7d70c35b8a61a48a317022c298b612782203a820f2161844f6a6fea58ca9f230713c701aad2700bdc951fc9bb8f560db9e99f2849afefea6c366c982f3680dea24891c631a1032d9d884a5ad9a11fa8331be85f1c91c6de2b4143ab403b153d9dd714db314c683ca24cc45f86c2276058be32ca1cefd4116ba386069856c6128ca86a63fbf6c15e876d63f738f847a32166b1592c3307d9c6190c5c42b7ab756ccb394c7c26c28fcd158bfdac9f04c99e30254d500cd0da1b9f2b74823f14283a888bdff45ca218b89b9450fba868ea9b1a5858509137160db31aa292863ed216aef822123c294a825e26fa3adee0291ab37c1462c89a4981949bb764f4222b3527dfd8a715682d159ba380339971857272c7bd7442cb73739c450b58cbeb6936b8cb619654037856935376acab92026bbad18c512dec4e19671180599e01651f008c3a04007cf02535ad7608e1e9257fbb04e419976294702e84341531b95e1b20c2b152a4d849649113c69a8f379b5d72aa86e01a4c5202ab2e276712f1131c411d4072cb45147c562c60080c56eff7aa7d90c4dc293b01ba935e345b88faba62dca043d94c4a666786c35f9318a579a9b67e429144240d206612a6d802fdc24aadcb42b0db4251e06df92a67e632aa4a29000a77cb2fd2959f851288464c824872ae6a9fa1bb3a71d8879e303c51445956ec8ae49c4ae6ac4de2047edbf3c0b23a29b8b86b83cb24530b0d17739331292bab85868e4a9bcbb2b4d4514e52d9afbf66172ae560c08c7f9cfc0c98ea4ec9c785ffe76ab5098e9f3c5ead6a7759b529661b50e0368246c5afbbb9b876c8072c1c1ca63a4e6607fe4286fd2062614fcfb544fca36edf0785c37bb6f5fc33e2b9d9d03a0a6c2853cbbda86e7039b635d4cc850f494d42b240acb54ab2316791e9ef5b45f1d2b28f7e7a15a005f92400ce33db073d49b53871594a88fc45e0f94207b5f0f2dc" +}, +{ + "dz" : "3e809ec8dd0fec0d911a4e3fac20f70fbb128c5de94dc7184ca7310ae9157a98d8128601c28b1def8d393a0db283229f7c7383152a814e7cefe8ef9d9768c473", + "pk" : "77155f91195dda2b52c1bc4ff328c3732799ea0aa8ed4229e9a239e5b5c5a02c1ebe98a381dc56e1d4b56deacda3ac52b1088805476c01609a0a2373a4bca788227172c4431b000005d855ca059b4e554d3dd2103cbc7854a12cda368ce202873f5747450c4fd994898dac5926765536662c81581ab4db18e9763cd5a747659440c9a33eac713cf907ba0d5a875b90882de31b5df825f337b46451705658915630035724c127c9c4b48572951770241993f777145573bc70125d35f1b03a121d09ba4388889568ba109f04617360826ad48f2765944232b1cf636fdf3c39c40ab87b4b50bffc1019eb0fecc35cf7416ddb3146e275cc7ae209269a7330977e9dba9caf79c99e30b8880525caaa84401cbde7ccc0fda4b250b7a2a651b3afc123eff52eec55650029af651b2014f4669de319435b7dbedacc173c3dd1f3a8597b80c9c3869d7389398a2404e790c9463f2634cc7351bac9d74b62b73e7e54cbbb3ab235c7c1ce298c0c0369de33224ab7b03517856e43cef2d39f1d325d1e221998c53631d32a57a880f24476a7e89f8c1b2d1c49759c322e993cc7effb2bab738f2648bd8133208ef26ffcac76393714859ccce0515d4a7192ded6ae5e828be6653b05cacf0df1b4816a972592089ff88fa421a490ca13c6789639c909c4db18ee43a01989c51b6005ed2548ae24ac8cec10bda7649e6c9359c45bf0ea0d39f25bb1ab3c3b5b88cda24caa8c7c7106616ba05da6727896d2a895835c9b83654b358e0d4728fec8a150b39283e345f3e06b4680bc632009eb85adb811277926662e531db27b3ca60843a6370c304c1dd21a94aed90c3663c0948bc12f0a32af533866f5931d5c74423246c16aa4f01808d06a6d50444ef8a3171ac641e9417e2e025390caaff16c6703680951b1a0e5abceb8fca9830c9ce1aa08d5803280f31de3cabc923b5a1a7c4854d841729194d3685c03f975a72440b5fa01b11868a48bcb73794c83644d1d39b9664c432c7b3bc311703ec01d268a34a8a1b3dc79b9ae07b8cd133b7d4baba7f39b4088043e4a35fcd08a9ef141b78cb1f64841ebf894827bbe1ec47509817ba27cb42222272a00a633e1b2ab344bd3778e4a579ac7d64a32e2356b1822c1334fa0e6acb05798f63192ee20629106130a1ac330c6cf0200908fb37184740e5caa5ad44067ac7930f696bc9226235d212d71f57ffc2c8c185c1f3d717271022f2d256963dbac5c5a1404a71e3546695eb27d73221892b5bfef114d6f88415875c013f16e48d3cdb68c2000a39a45263504e0a7554386d68a4d3992c9f6196015066d3b8282e8d3398d2b5f62d7af54698418862db3a84286f142a8cb44be011e0f2594d161611cb335bdb018d9e58cc71a363b29439d54cc6b293af33b0dbbcb80c7797819a96c1316a783f60f987a3fbe1acf80f22f610037d17247122c4ae2b2214638205328c43fd4bebce93d47c02b84e1cdee7cb48805396c24410d71ced4805f36a105b05c6564ec3450654cc0a12e62f7c0da79496ff2bc97b7b4809aa30d577a2f3428e48220239b1b97d9278dd26d93d186628812fc697d961442879ab64b4ba0be3c46f5e55c13222058b407c1694979897ca0615e8de05d85d3532060076acafc8e0aadd8ca7406c7bb316abfde1bcdd166", + "sk" : "65f04f655904f41a6a88535638821638039eb85517c3899ba016172b8b3120b90e4717c51fd0a6a1d8cb799562e1901128756501bb00d4b695e11ccb335b6fc4537b236c4fba1885d89b2de48427a65357c31990d9955ae7323b30244a0f296a259c5deac728403481f0745f275401c9482ffcc3cca44832bfc0799164cbccab87bf04b813b32801f2ca915a9b35d60e34e95a74e660441a686c89397c915290821989286168b6ce76e485c946179dc484ce6bb94c9c375a899afc6932cb9876796bada211b849101aa4c5b837453cf89a0642c91721b01abef1a78ad28006e25762a65d23664c79c87cf79cbf4ee38070905e8b561a254394b9a4a3d40bc23ca6a2e98bafbdb067a34c7f450a2ec9c419c8816fb71ca46d177e148541d3ab6dad4b467ed7ab1cc94b57413c31880a418c56d851ceef706534871ddbdc8033679d82eaa69a4c4872233ec12ba28e42870e4a43c3ba3e0e36cf7cb740fceb3af481904007051c137d702c890d126f7e6b1d401bb4e81a4333d7c8ee5cb8636a984841c67817411862af5e3605fe838630a680c773725495812bfc4531106ab13b52c2d357b3139f9495c2d4e4a77a07518fac187185b2be2355dba0066d8a418bd7aa5038c6f0d4a3e5a074d409a15fe77ba7e176cbf2c7c20b10116737b6232851e688fb3279d060c8c24005a73780e7713255e6498fb50c056222f376cffebc723ab180d4eab9aee52a1e08cc2a73b90419a056e32d660c7717884f897809df5c42921871a1e59ce36aa74cbcbd9fa3069897a0a76113ab6818482548db03455a58b127dc5daa0cce8a5b5f3f10a678d04b68fb46fb6a94ef87161743b2364098a40128dc3181c551cebe151389431972498317b52d4f5332d6b74210d783d9c461453347f820acb6e4a3315a2496cc683590b08b0503b31b97688a1f6cc957c6c4724faa6a0b982859e961c808aea88862c750c6045b57f53963d83448b228847384754cd45dbbe015e6254c055163a60c02b41988cc2511fe70963c632f8180333c532109047c65ebad0aa56d3bd136efc88b6dd832bd810cebbb9ec40cb44754bf664773d5466ff0b86848314432e085761c3d81e2669ab41d9e3c1ee343ca24bca795eccfd6942dcc27170a74a02415bb732ba880a5cfa922b10e4973067109a3b210b02b691c8aa4a931252546a77b206098ba78f6e4781660a29a00ad98307b76cac825a534003154002977ba8150d3847fcb513120f43b2aea6788e5c17bfab456d7b96a1ca2d217b86ba5b87400cdee144717f5b34fa842778c0917200482c99571a36a133097365b7e36621f51ab88b0d0b3aad022f39b4ef3ec1cd0459ec3c80e56524173a2047b099c304c71e9db708ee55895dc1b30cc8fb1b1887f312d70c8b399944b4de4be1542a27bc0569674a4097288b9c60982149270d57d766c09a47045527ac8d710bb41f8c34edab551d0c022a627c2078edf078b0464b81b46057296b5ebb3571ea000a72065ad11b5cd36accd5628283554f38b6aa39bab97a171cf0cb3664842686abe589a9321d7b911b371ec5a31d13a4e91c8118d504360f668591163fdd233a6bc5e65341703cbaaa931293cbac5d0f16c77155f91195dda2b52c1bc4ff328c3732799ea0aa8ed4229e9a239e5b5c5a02c1ebe98a381dc56e1d4b56deacda3ac52b1088805476c01609a0a2373a4bca788227172c4431b000005d855ca059b4e554d3dd2103cbc7854a12cda368ce202873f5747450c4fd994898dac5926765536662c81581ab4db18e9763cd5a747659440c9a33eac713cf907ba0d5a875b90882de31b5df825f337b46451705658915630035724c127c9c4b48572951770241993f777145573bc70125d35f1b03a121d09ba4388889568ba109f04617360826ad48f2765944232b1cf636fdf3c39c40ab87b4b50bffc1019eb0fecc35cf7416ddb3146e275cc7ae209269a7330977e9dba9caf79c99e30b8880525caaa84401cbde7ccc0fda4b250b7a2a651b3afc123eff52eec55650029af651b2014f4669de319435b7dbedacc173c3dd1f3a8597b80c9c3869d7389398a2404e790c9463f2634cc7351bac9d74b62b73e7e54cbbb3ab235c7c1ce298c0c0369de33224ab7b03517856e43cef2d39f1d325d1e221998c53631d32a57a880f24476a7e89f8c1b2d1c49759c322e993cc7effb2bab738f2648bd8133208ef26ffcac76393714859ccce0515d4a7192ded6ae5e828be6653b05cacf0df1b4816a972592089ff88fa421a490ca13c6789639c909c4db18ee43a01989c51b6005ed2548ae24ac8cec10bda7649e6c9359c45bf0ea0d39f25bb1ab3c3b5b88cda24caa8c7c7106616ba05da6727896d2a895835c9b83654b358e0d4728fec8a150b39283e345f3e06b4680bc632009eb85adb811277926662e531db27b3ca60843a6370c304c1dd21a94aed90c3663c0948bc12f0a32af533866f5931d5c74423246c16aa4f01808d06a6d50444ef8a3171ac641e9417e2e025390caaff16c6703680951b1a0e5abceb8fca9830c9ce1aa08d5803280f31de3cabc923b5a1a7c4854d841729194d3685c03f975a72440b5fa01b11868a48bcb73794c83644d1d39b9664c432c7b3bc311703ec01d268a34a8a1b3dc79b9ae07b8cd133b7d4baba7f39b4088043e4a35fcd08a9ef141b78cb1f64841ebf894827bbe1ec47509817ba27cb42222272a00a633e1b2ab344bd3778e4a579ac7d64a32e2356b1822c1334fa0e6acb05798f63192ee20629106130a1ac330c6cf0200908fb37184740e5caa5ad44067ac7930f696bc9226235d212d71f57ffc2c8c185c1f3d717271022f2d256963dbac5c5a1404a71e3546695eb27d73221892b5bfef114d6f88415875c013f16e48d3cdb68c2000a39a45263504e0a7554386d68a4d3992c9f6196015066d3b8282e8d3398d2b5f62d7af54698418862db3a84286f142a8cb44be011e0f2594d161611cb335bdb018d9e58cc71a363b29439d54cc6b293af33b0dbbcb80c7797819a96c1316a783f60f987a3fbe1acf80f22f610037d17247122c4ae2b2214638205328c43fd4bebce93d47c02b84e1cdee7cb48805396c24410d71ced4805f36a105b05c6564ec3450654cc0a12e62f7c0da79496ff2bc97b7b4809aa30d577a2f3428e48220239b1b97d9278dd26d93d186628812fc697d961442879ab64b4ba0be3c46f5e55c13222058b407c1694979897ca0615e8de05d85d3532060076acafc8e0aadd8ca7406c7bb316abfde1bcdd1662d5680b483287bbd3e61a91839cca9e761429186176b7bc64034ad43f16f65e9d8128601c28b1def8d393a0db283229f7c7383152a814e7cefe8ef9d9768c473" +}, +{ + "dz" : "dbf1c465fff3d9f783bd9ee61a573715e45691147b8904439b5ffaa64f94ff7bb6d75eac6c76ced1b0a025b40a55440712ad8424672e761e9bc400d63812006f", + "pk" : "697588a4004634fc1c77215f0677879aab3e63b51ae7436c5b47370e226eb4ac15dd0281ec65c56b83b60ac42de17b1374d1680b76460e294d841c1062638cc003d043a26307c08025a594fa3676df03c87789a4499575948b2574f6931673936e971f2c79598a1b7b35d28103252b4df98c47f6afa057bd87b1cc516722fd72bae0f437479c1ec6f68087453e23fb4381e5930e5a19fc9a267565b1dfc7aab9c13441101e57d9a4a454a6d1249c3cdba091113d0f1b257d0986f23b4fceb35c95ab05e2911dfb2899398808582a6b1aa9950eaa9c87c8bdae7372d46c2852e85c629c25e05a169900b24cfc0a68661b6d44c74c658ab8c00c756861be79272339a60828b9f0b8a325850b41950f97849dece714c494ba9bb09b74ac16138251363b52dc166f220623982c19ef565f80583b84d0b91267ba98b63afa31160f65961181951019419fc0627cc48de9d6b2c689969548641009cdc56b02a140bbc4a995a7f2593e0213cdd2cadbccbca41947fc8033baa1754a8815ad52cc31940451f8a62dd6b39e22a6b0db8a0f953c6cbca43f9c1285315f59ab9980ebbf57c1457dd8361da04e0eda771cdb37a6a54c6a47719790976a957978e198446320aaa840e0f1c076260e75e9a92980891aa6245e003f1fd6363d0b6e5c73b476b77ef867a60b225a99a763d0ea80a4c61739875bce5c0f361322450c93040b4d6c08120827b8026ace0ec73302fb6824367ac89a0e7df45b850618612ace284c2da4421689d8c7034113f9a1b2342736f5f11cfdd7ac7f8468075a4a2d7960dfba9e264514a8d7c6d11c660cec1efe33c04b4681dcb31fbea47247bc83c581b174b0cedcf0bd0b7b622126cbe323986b75a407e416fc0032fa2398e504967ed021e993a955713a76365ada810f9bec7ad1a6929a466f08113cfd6919e014085d4148be060ebc014fb1fa3a1ff70a3ad94baac7be6c96bc0f28a021e39cc6bb8a6e16312255880a84778cbca55f4173b2070d527357cac69c22587208496af1715711f76d5c185807a13b2c791b91f54b23ac8b66b71b3e211e55180fe7a1bb2bba7f97da8f82734ef777b7d2653e66e814ed7871da35c95761a88a611bc383add9a329706212b9780ef5d53e933c99318ac47e26859f507bb50597c3ab1a252c77d22a817b402b80a63532f21a0f296c40bb8021732fa9da01bc60bc662a0754914462689de756a397e2384c2372130c5a6f05ae6c8b81ebc22125830f04d3740d2638d031a21f1653c4f664cd182b11887f4784c27954984af251c923b5c2ca4f1777cb3eeb7a13c351c07c4f5562b4a8a477fd348bcb9b8e6bec787c2340c02c0dcb236fe8d7c6ec8bc9d156b89bfbcbf4d0599838263ad5b90fc155051137d6800c898c8a50b82a4e3940bbd3bcde2013889bc4f3a7022d7c49370ac8d826a3aee946b79897bea8512d8b899a8c17e439760b58859393a5c264b5f1549940914fe278a40b6c9a8304775ba30c8ee4cf234ac56862ca2e935691e426923973c32b4f2408cf63c99d7b2c5f0c5aadbbb9cb98b53f787431fa73542c5569e5f5ccf0e4a868cac6529bbde42a5f1881ce0a729e6a531b0c401d4979a7425baa8b0392a8ca9374323ddf2794c237e38e45a43a5a34cca2875d19217ce7547d2eba6bca", + "sk" : "000d8a738101a329832189bfaffb213cc5789003528b06754014cb91a09b7625359b2cbe463b356e298c95a6a24646ad6114900034c83f19599bd0173846b93153aaf6f9c1e1e11d41692bf5146a48810aa89604bc2b09b32230c6c44f5a0a0086b7c688008702517b4d807bc34b8a23e968a8316df5207f2788975f458cb0db5a37c80bb2823270a3130c18bcf793147ee0a5b63a499ff28e3ae290974ba44e8730f4e56018073e0ed54924e38865bc076a809862470525d5c32b74c81d4cb95278705f01b6c6d098b951a7eed095ef386eb8d47f0d7984102872706b352c12119adc1fde40259f5450c36c4327d31f09eb589281a590f1131494b50264719a740c6d0b1c8f9aa6d281b8eda923308b02dfdbb7c2451bf80a769c683f2fc02822838f6ae1cea8d81ac91c53f53041952b82aefc4122b24cc15b3a8cc2450860869fe622036512344132701b8043b387d37986482318c134af38014cc075756838415e1a461cf0313b4907ee6753ad625ef593c99fc70b88587095e66c03044af109bcef59a3caca13e027c2cf3b350d28c1610b9bee0718ee44c223ab522ae57b532526f003345440cfedd463a0fb1ac60a2c6bfc37c7eba6a7667475d278c3a4b7c486b68f2157e9bb7646045a7ab452cde7539c755e5fe390f0174153f1531d5737da4383202103f6e01339255a04d04c83fa5119fa0f0c15c2c2d50e41d9be98c66703903c73a05680f6c454676916d1c03da6bb45482c588c6cbe57ceeef924caec94fbd096cbd13528770995bc50d0bc02b24959f4d61de3bb6dd7fa1a47db7856d53c7623897a24acae7473439217d52a2ef34a3a6c793017d6b22a3845f8087589ac311d00be84197a8bd6561fcb8472924af6547cbc78395721c75538278579469cf38553e4066027a43d9584508c7fe8f87a7f122b484a1cb922b62609cfb48c7f3bab00fd709097c87f5ef401cb9520b55cb021211b23131b2ac07ee9da735b90a37a84747a26a0f0c7b28672bb4d3cc6e0f1c3ee1c418dcb26a663519907354d2bc106fb72a1607a0905886e292d3a77716590ca57b6459ee647906401e8b268d6e782f904be442858fde72513318c06d0715405229adb7632b5bb2e9923d4fb49a5f7b995ec7b2c971b0be3aedb622cbfc344d9c9ab6536b323a68a0ec97b5bb491fbb0ac20f48873443707da5b82d85f61c98f06626761a20436f20dd1e66d5e452874e9b1c6947ed270caf85a9be3d8250e539451f61b28014144bc184e7ab57fd496a1e3a9f2fc2bafb02cd837ac91f61a3ec39e9892293a6a2be5a91739c64418a173e02870f4845d3f56ae573c5daa9387f78156c7d42d2a2c7a051964127bad8b728fad010ff0944dd6c2807b748d62492494b25bd32261115014d91baefb38a3fa06070646c71e5c6e07e64aed181ec46bc0fc4284630a038813834ce3467a0b4b615496b80681149262b833247cfa8f4b4c364833b074a467eb1623fe475aa1eb6734774995e99745d40c5c149fc91264b3149ddc2318b149c45944370cc222bad6759454cc4ae66d30091297d6468f8734dcd43e3f078fa0955d69c90e0f97ca3de54b2f38005e8296c52a27e51a1cbb69bc1c3cad697588a4004634fc1c77215f0677879aab3e63b51ae7436c5b47370e226eb4ac15dd0281ec65c56b83b60ac42de17b1374d1680b76460e294d841c1062638cc003d043a26307c08025a594fa3676df03c87789a4499575948b2574f6931673936e971f2c79598a1b7b35d28103252b4df98c47f6afa057bd87b1cc516722fd72bae0f437479c1ec6f68087453e23fb4381e5930e5a19fc9a267565b1dfc7aab9c13441101e57d9a4a454a6d1249c3cdba091113d0f1b257d0986f23b4fceb35c95ab05e2911dfb2899398808582a6b1aa9950eaa9c87c8bdae7372d46c2852e85c629c25e05a169900b24cfc0a68661b6d44c74c658ab8c00c756861be79272339a60828b9f0b8a325850b41950f97849dece714c494ba9bb09b74ac16138251363b52dc166f220623982c19ef565f80583b84d0b91267ba98b63afa31160f65961181951019419fc0627cc48de9d6b2c689969548641009cdc56b02a140bbc4a995a7f2593e0213cdd2cadbccbca41947fc8033baa1754a8815ad52cc31940451f8a62dd6b39e22a6b0db8a0f953c6cbca43f9c1285315f59ab9980ebbf57c1457dd8361da04e0eda771cdb37a6a54c6a47719790976a957978e198446320aaa840e0f1c076260e75e9a92980891aa6245e003f1fd6363d0b6e5c73b476b77ef867a60b225a99a763d0ea80a4c61739875bce5c0f361322450c93040b4d6c08120827b8026ace0ec73302fb6824367ac89a0e7df45b850618612ace284c2da4421689d8c7034113f9a1b2342736f5f11cfdd7ac7f8468075a4a2d7960dfba9e264514a8d7c6d11c660cec1efe33c04b4681dcb31fbea47247bc83c581b174b0cedcf0bd0b7b622126cbe323986b75a407e416fc0032fa2398e504967ed021e993a955713a76365ada810f9bec7ad1a6929a466f08113cfd6919e014085d4148be060ebc014fb1fa3a1ff70a3ad94baac7be6c96bc0f28a021e39cc6bb8a6e16312255880a84778cbca55f4173b2070d527357cac69c22587208496af1715711f76d5c185807a13b2c791b91f54b23ac8b66b71b3e211e55180fe7a1bb2bba7f97da8f82734ef777b7d2653e66e814ed7871da35c95761a88a611bc383add9a329706212b9780ef5d53e933c99318ac47e26859f507bb50597c3ab1a252c77d22a817b402b80a63532f21a0f296c40bb8021732fa9da01bc60bc662a0754914462689de756a397e2384c2372130c5a6f05ae6c8b81ebc22125830f04d3740d2638d031a21f1653c4f664cd182b11887f4784c27954984af251c923b5c2ca4f1777cb3eeb7a13c351c07c4f5562b4a8a477fd348bcb9b8e6bec787c2340c02c0dcb236fe8d7c6ec8bc9d156b89bfbcbf4d0599838263ad5b90fc155051137d6800c898c8a50b82a4e3940bbd3bcde2013889bc4f3a7022d7c49370ac8d826a3aee946b79897bea8512d8b899a8c17e439760b58859393a5c264b5f1549940914fe278a40b6c9a8304775ba30c8ee4cf234ac56862ca2e935691e426923973c32b4f2408cf63c99d7b2c5f0c5aadbbb9cb98b53f787431fa73542c5569e5f5ccf0e4a868cac6529bbde42a5f1881ce0a729e6a531b0c401d4979a7425baa8b0392a8ca9374323ddf2794c237e38e45a43a5a34cca2875d19217ce7547d2eba6bca38635cec71b814aaac223f748d13158dbe8eb902d9125fdc22202c4d59251cbcb6d75eac6c76ced1b0a025b40a55440712ad8424672e761e9bc400d63812006f" +}, +{ + "dz" : "1f7cfd2b70863154e8a69d1758532e86c20cfc763d67c758bd10a13b24e759b5273b38bddc18488024ec90e62a4110129a42a16d2a93c45439888e76008604c6", + "pk" : "bafcc65109cd59f7084e05cfabe4515255ccb724b3388239ce1ba8c631c1e8c0b444baaa6ac481db8b4d670ab65ca27f33a92a11c48f6ac038f0914637b749d8b962c00ac8ab0c019c92960ec3817f34840aa7b63b19826a12234a81c9faa8995d28c4d4c44a0fd2c51720cacc8751bf6c31caf045a79c6f9b15c2d406c11fc3b5df6638e1b83164175dca5a1260a88c74b4c2432a9b76c39d43597ce2e3ad1797c25f967868b66bcee9b6a4d1b53fd09540220c7ca75943c52e3d4a124453499c681c1fba4dfe80919bd9467bcc0ab34b7db6012b18b3cc4c679e325b82518baf5123c88786745c4a0600a302a2a367b717c3dcb4c32aeb4770fc93e0213aa54b2c6a37a326f121d907278203724ceb6cad8717fa3a2106217864274e6220061620052799ba22675db36863b2a447e5a62b3d2511ffc83bb34cab6cf7356a27c29798c00cb32bbe1023fe1221313cc7ad59144fbb98d0182bf0183b44990da81016e2995206f2b0af19c8e21b1afe8c98d608c0c7e52075137caf22c69dec4e0f1763c8bba263898b30946663d84b5e0808e6ab9a6df970d2568303704d4c651c912b7297a89534e324fae62628580becc3a2051cca9d5757d5e53ff8fc242e42b2adb06cb2547296ec8431fa6eb8f7384fa559f9284d528761f9a23e85a0bbb3e57b7a876d2d4934d33838906606e6da9a311c15cba30f39d05236892462824bc4a4b4d6b343e3594fd9d68972d99eb26538f9eb1fa7f0718aabcd5dfa5a670b0f8cd595ef7a082abb518fa34891a4ade983877a333e956bbec9a82a19650866981b8b8c406e22abd784aac085b6ea553e30409ed6b39b4f367ae45b9fe109c6ecb51f23d2a755caa347aa95e656cf45a15e9438b61031717b3551e9e3020ccc330f254e82d89b5e4839a9f8ae267b9365aa228786a371859d3847ae68713df98768a1c792adba39bd2359198224376cb9c011777efc4aae1c3d179583ab0952bcb5b1e8577a5c476189d3301bf87fd8a1163b81bdb4a8368934ba4867ae4dd03d40c2cb5f974a5c36a8d699546d831095e7b354490838a40900521da4a00d2fd7117e1060dfd363593ac11bd31ffcc08c1eb8806f249719751ea3eb328d3a36590919c2317429d0486266968cbc6973d483015b77eec543b7f971523589655732bdd1783365761d937266a420ef3b849a630ab5a4003ff09c116c1037f4576c58adecb5a5e0899892854b8971c9b76685164a14bc5c8b9bf212c6c7ab15b35e25a586e465ac05f3911da7063208c3df46923622402559ca963a39f003ac0334ab19d02ed58c990ad983318b33429acdc637a8393082684c517b75194506bbeb9686136a3c8a284c852ca747fb709d4533d133b5798b50c1e59f9e99781fca9f447340705c6cb7e2231e257f95d681805b8cdcf3147804405f30b4ee63c1aa9c367eabc3fc606306616eefe91026507780e6339b209cfb7a227596957b136e1cbbce15fb9a6fd9bc798c40f0ccb7651b150d281d78b3508939ba836ab719cc19c61860bd3c624827ac26639c05a39c88a1873204175bf297561723a16375dba51947b83e46e84899377411b2bf8b743cf8dc23fd2ca07d11aeec1990c42a7321ac6f01cd866f8719ef21bcc0e02346fc5d8ba3d3e7f1fcb52d37551212d647", + "sk" : "4b390d378cbd58818696f39433e9a34a46109fe98b4e806a306119e2110a5ad3993f7646213c0b27dca918e624eb6090930baec770a838a501e8979c1e210f71dc4674999cb8b92cf0ab1011aa67ce5039446957be38a16dd683795621fde5ac77e94c07572fb2d95cd0169803db5698e47a6ef3c3b11766f095496ae846870a68d34b9032527902760ca97b913c42490486063f0ab27afa8b92b33d88fb6653dc6ffb3b55b3a9b5d3a9b5f89916a727439561afd8e172f5313ffebab7587649d77563df970a4030aca239b225c78177058c9ea3cc388a3f5f2732e1dc00c11b936e65833cc90f5597266e29846ba70ae0239820e47426b8a092792334f390e399469ef13ff2301f9ac94eb42386ff882a3be8ba23f473ebb271ab6c52e5b26c5eda203c0b6418250c8e2216285cc78c70a386f1935ec41740a114f5a32ef703b4a4540143165337f5bcb42743e574b93d62ae23081e2dd7c51e923ff1e25f4734395ad0ae016a6c45f8096bf2aad933027d1594d98175c91143e320c3122bcf16f10f7ebb251101882aeb94d6b8cf893b7c05373cc9bb3ee58b148d1124183c05c116b6c178a2c7756700e15b8108144f5024c9ca04a3dc2e476591a7c79970274f112c210d00c198860202a408453985a3d9b5488bc61f4c8c93741e6e733e1358605c6a2e30d7075008cd5297a5ef5a18081143d5907d88284ff284804b276a193352ad3ba5463383a024908fc05578d0521d57bbf7d03cecaa93ea1326582307725c62dc79b7e9b34bacd94ba9608463c72f68dc0eeef10bc3c52e9f295a65f460ad368092d3bbcb2c9f9e1b2783737e1c3b0ec0442aa7897ffc75471b18730399257f019fe5d73afbcca9b83932c94360612b297f3a84efe90278940e98ea2e746857ac73adedb6b4226667dc779285c6987ceb03ec14a00302444ddc02e76aa6d95392053b176258546fd0959c8a6d969cacbb809115b339d6a517578502a46b833f84712dfc01b7c35776595ad656059c4cbe72e637ca5c95572952fbc772463042d9ecc194f93c8b577a220116e7e58bbe5276a90324c5492dbe3781b623585a22a77b2cca935009eac03ff1947fc00562f1561457f0220a764b7d0c06ae3a4cab90276581445ad7bb07c817f4e3a05613541967388c3a1a784642c9952e8376c57d82a16bc98acb908521a366adf18dd95569af860994858236f5bdc7ab9655a95d28a956049c7365c84c34f33ab305a35fe3117a563b1947658988650e3c65a6551660650b33217295e79fad0bb567054b2c0c1fe5e3ca560b3a565a58d9054fcb171afeec538a1c01781870b19c63a49243fcd9b384635aff5b1642036220f15c3414a9c2f82da81b6e625c1944109a6a1ac06a07a9b8c85f86c043bbf62af18c05c5eb3bbbb3be723a8e04b9a1f875c0d645412eb8c51fb1c305c2447628c2f01b3b6a6a89d8c849f48832f7a9662b8c476bc426f54b509a8037a52023a5d02fd10394cee11aa1d5464ac41ce6961174a528e2e3677032ce03b79ce5620a3dfb3291e7bca9c249c27232bb535db78918c2a56303090e98c1503d211d95221e278764479a1eacd92e5c50b9d1a3aa9c547194275630cb7644bb5dbafcc65109cd59f7084e05cfabe4515255ccb724b3388239ce1ba8c631c1e8c0b444baaa6ac481db8b4d670ab65ca27f33a92a11c48f6ac038f0914637b749d8b962c00ac8ab0c019c92960ec3817f34840aa7b63b19826a12234a81c9faa8995d28c4d4c44a0fd2c51720cacc8751bf6c31caf045a79c6f9b15c2d406c11fc3b5df6638e1b83164175dca5a1260a88c74b4c2432a9b76c39d43597ce2e3ad1797c25f967868b66bcee9b6a4d1b53fd09540220c7ca75943c52e3d4a124453499c681c1fba4dfe80919bd9467bcc0ab34b7db6012b18b3cc4c679e325b82518baf5123c88786745c4a0600a302a2a367b717c3dcb4c32aeb4770fc93e0213aa54b2c6a37a326f121d907278203724ceb6cad8717fa3a2106217864274e6220061620052799ba22675db36863b2a447e5a62b3d2511ffc83bb34cab6cf7356a27c29798c00cb32bbe1023fe1221313cc7ad59144fbb98d0182bf0183b44990da81016e2995206f2b0af19c8e21b1afe8c98d608c0c7e52075137caf22c69dec4e0f1763c8bba263898b30946663d84b5e0808e6ab9a6df970d2568303704d4c651c912b7297a89534e324fae62628580becc3a2051cca9d5757d5e53ff8fc242e42b2adb06cb2547296ec8431fa6eb8f7384fa559f9284d528761f9a23e85a0bbb3e57b7a876d2d4934d33838906606e6da9a311c15cba30f39d05236892462824bc4a4b4d6b343e3594fd9d68972d99eb26538f9eb1fa7f0718aabcd5dfa5a670b0f8cd595ef7a082abb518fa34891a4ade983877a333e956bbec9a82a19650866981b8b8c406e22abd784aac085b6ea553e30409ed6b39b4f367ae45b9fe109c6ecb51f23d2a755caa347aa95e656cf45a15e9438b61031717b3551e9e3020ccc330f254e82d89b5e4839a9f8ae267b9365aa228786a371859d3847ae68713df98768a1c792adba39bd2359198224376cb9c011777efc4aae1c3d179583ab0952bcb5b1e8577a5c476189d3301bf87fd8a1163b81bdb4a8368934ba4867ae4dd03d40c2cb5f974a5c36a8d699546d831095e7b354490838a40900521da4a00d2fd7117e1060dfd363593ac11bd31ffcc08c1eb8806f249719751ea3eb328d3a36590919c2317429d0486266968cbc6973d483015b77eec543b7f971523589655732bdd1783365761d937266a420ef3b849a630ab5a4003ff09c116c1037f4576c58adecb5a5e0899892854b8971c9b76685164a14bc5c8b9bf212c6c7ab15b35e25a586e465ac05f3911da7063208c3df46923622402559ca963a39f003ac0334ab19d02ed58c990ad983318b33429acdc637a8393082684c517b75194506bbeb9686136a3c8a284c852ca747fb709d4533d133b5798b50c1e59f9e99781fca9f447340705c6cb7e2231e257f95d681805b8cdcf3147804405f30b4ee63c1aa9c367eabc3fc606306616eefe91026507780e6339b209cfb7a227596957b136e1cbbce15fb9a6fd9bc798c40f0ccb7651b150d281d78b3508939ba836ab719cc19c61860bd3c624827ac26639c05a39c88a1873204175bf297561723a16375dba51947b83e46e84899377411b2bf8b743cf8dc23fd2ca07d11aeec1990c42a7321ac6f01cd866f8719ef21bcc0e02346fc5d8ba3d3e7f1fcb52d37551212d647af97825a77f2f4b6a45ec1a579f9f83e89c025d8d6876db26874f38348604293273b38bddc18488024ec90e62a4110129a42a16d2a93c45439888e76008604c6" +}, +{ + "dz" : "3a19577908efd37697b8edc7fdaf47d1bd3ad01a1b77faf794bee5b9c3192a6fa3729672816f3eba84c9638a79676eeac0f22c8a48e0c5d50a26ff0844c66b99", + "pk" : "e180a227ab843cd49d4970af3b68c255512920773abae9a2e402b154b8159b63b4885736e63632313b2f99db66fd4307d411a66871c8ec859807205535d907c3c6541b283824861738acce081a14e8047a63cba2f42c71b23157c85a7763d3cebfe93aa7fa0a083284ecb7c4dc16c8119b5d90546a461a5b744b1084f120bee2b548801c381a9d561bb0c5c35336601d1cdc310a610c8df78de62477a6f26dba6038ad04371913b831c326c0537cae530469292ce41c40a81b92a5c04d69eb0303b4b38a5cc45fd2b0ee90cff0b81474d0406c8b34b34c1efb596a704ca4893949614762a30c54846023dc3a345268ce55c0be97139f5f733664a58b67656ea211a87de01f9cd902a9295355d13a15bc044fdc77c4c53f671a1438e283371b5db5f82fb0d789e877b6820771f0ebc64da864a01caff73c4a42b5416bb043e29c7b2574c6e214a352f4401d786b4d5351a2559b87ab00ba84511bac1a099b1b33e8cd45da078d447b23326574379dd3d32ddb22c6a4037fda719fb104c85f0264ba4a9ed0287a31a2af6d58291676a37c434ecb234e4e1c648fa0760da57abe45703e677fefd03687415132d03252291f02f3901d20427904511f9c11a7f07041302033054605e97fb719a2f70648a2c30a0b42899b195ea8e6cc96610943c3276698a34a61893ba8770c69cd55f1bc0f00ca0e04177d0469c4833fcc23a6ed339acaa91b6e081692340f53cac66af5a6bcc2391729ce4e1c88d5c2610b00454fa21e8faa6487022f19f2c81d5452d5170255108beaf3979ff9abc2e04c8e3669c6aab80e2b6464644ae2189c81fc92d50cc56039cf5de2325ae5163a1b63652222aab35e17430d16477537f867ba4ca0e9b1c83c61a562c6822e61bb1450426e9716a77c1934ab17ec69563b8299e6ab371d996849c8cf7a84ca1a9bb654e1ab20a81d65314595a52ba18076f8712532a81b00e19e8734968f87c03fa4763208862d9a3ca648582482bf0d5441fdb7c84ab237d9f8628ed2001a501339682f9b8aaf6606344b95342fa62e782c1d9560b6ad55aa332c1fd533a74d026a9c9757f0e91bfc96545d0b6477f31f95840ff0a4127b16c32b635471480523f93017577513ea96159ac60be179d3a09c5ccb6df44174de866cd7548339d314d160718f262edf32382915197bc2ac6e3a4f77229e22dacbdfecbe3f4b72ac6bc9d9354e7ed2c31ce7acd7f3a2c8b9abeec00613b1600c8992376b73f8c245ac9841ea06409454b48d8c3a152bb8d6168a3fa6423373651caa7aecf0a5971641bd66897e5991e793343b5190bac3107eeaabc71bc34788a345bcb9ad8a45a50a1dbdb1846bb76205b06e8aeb692b4200a596524954963f01c946131704f6b181d7781772ca6365824f6c6c22a1af3328a2c8978ea8d7c38f6a00f7a6b3a50c2507f103f72420bdf98dc19aace30b792851142d8b43319c93ccfa966d71cff9352f25fca9e8a3064cd96e42e9a2959c128fd532902419b81972838532cdfc08f34541459cc68955c9c2a431ba5126c9bc08039ca45533ad8108beba49bf8d56bd44433fe12a6c55c41f3cc20560b28cf050cc1f195c5e817d23d95e105a13555923cc21b13c9e46d34182974451bd97b6a3da440de6e5bbed681d6eea2c6822b361019afc", + "sk" : "5e49938e23a5c65c89d4c40917379cd2a5b5d32881a6d68c28b48a2e356de63896bad68acd4a474cfc288113afb2418173ac4b1c3255136c73a00c7128b59a50042bf4a3aef9015fdf0108b01cb701d2bf6597637227604841651e3a964326a23b038d0af855f307413236a3ef95b4433a0164ba6bb27a858ed9b22a31234480b7e559ae9194aee9945dad45b0a5e85bb486962cb19d8b52c7d4b473f5f566f2779ccd79739649665820bc0e8307457b9af5844870ca580de2394fb092edf512310b970f5377fb80118fda8517b5b16e212447e16e3a5a5de7587ff3b271533803b9282901192fb20cb298d666cea3c5386bc658c5c1de9673857a3091a413cc69b2c8e46382ac97a13a9f31c1a47f0b6f898a84dc0278bab1a7863746c03576231b59ad2610e79a933661b6f23c63ed9404de06791c087f42abb7c088ad15c54ab23c78305826cbf263d441bf62e23180a79ae14a1a1fb31e115b02a974ca7025ad0c634067d4082a835bd274a44a218fa4642caaf1c4d108570c13bc3137468a6037a0709f0c0069443c1e7fb2822a282d08b030539628448c5b0396cdb76c89ba0c13f8ab2902d44190a0342ed5acc88b72c3baaf18880561f95196f56889f1854b4cc348d6019f4a5036123c1650332fe47115105a085c2591c952b35289efaa90d55c6c888868c20075291435175c086edc5d07b01e4441b8b3867b8a93cc9ed07ad71b387ea3363064194363b77fd106ca5c13f6b585980664b2a036b730ca50610798e3b14d176e28066719581821272157d81ea550992bd76875c22736d7163b01b6e353cdfe05b63bf5ae02a68c3e105731d8af5dd90981a02715e061f8d3b94448115247bd23137cfc165dcd4c26d065a28b84cbdf4b17b1a9a27046898c529ba42217502abbafd68bf6990d2d1064a7aabd89075891678e2610120feca2ce72c0e1d8be55f4c0ebf7cb565b492d9a2370e93482201f25b5ad667b0b90fb31dc8024e4123be6733217488788980f5216116a702bd8c1ca18d0b419b785961424f6289f7a55a211615398575755b8535fb0aba1491f00517863c41f4fa1871dab1ba42599e8e54e8f4c6a54e20f5125c595e2099439b0402794b9fa3a632b4c789c9cd4613776218fcf066c22e4b12dbc90ff0b4d08cb7032c07603557ef6dbceedabca671b7b07a2cd1df6a89ea6a7dba65e145b9515068a15e7053d5a4b1323cb75a8ad0d6ba3885a7e77460cf19637c1b6c330725588091ec1f158484c6ebfe43b4e01cb5424bce33758ee10a438c0621c9217979c958ae89591f69d54c4a71719cd4aa76da6ac4ee4b472afe45412718e65a5807d452491e1a0788a570bb3723d438362f50c2b26b19dc696f492452ad13501c3bfc81766dccb5034ccc29d4c152499000aa458c961aa17d74cb5819a84135cbf8181832748917c951a468fe70c08c1333de71b64b7ab158255c20aa7b2ca8a912f898574568e27691f8b517425c1be2bf183401cc2afe08fa65a2a1135a5dfb9a86dd3985351b61de0228c112a35a889eab8a57273258a471551e15ad23328c6d00a3f78a1cb9c836e304ffec75ee1f0927962b642ec0694e50963a246d97a240639a611c414e180a227ab843cd49d4970af3b68c255512920773abae9a2e402b154b8159b63b4885736e63632313b2f99db66fd4307d411a66871c8ec859807205535d907c3c6541b283824861738acce081a14e8047a63cba2f42c71b23157c85a7763d3cebfe93aa7fa0a083284ecb7c4dc16c8119b5d90546a461a5b744b1084f120bee2b548801c381a9d561bb0c5c35336601d1cdc310a610c8df78de62477a6f26dba6038ad04371913b831c326c0537cae530469292ce41c40a81b92a5c04d69eb0303b4b38a5cc45fd2b0ee90cff0b81474d0406c8b34b34c1efb596a704ca4893949614762a30c54846023dc3a345268ce55c0be97139f5f733664a58b67656ea211a87de01f9cd902a9295355d13a15bc044fdc77c4c53f671a1438e283371b5db5f82fb0d789e877b6820771f0ebc64da864a01caff73c4a42b5416bb043e29c7b2574c6e214a352f4401d786b4d5351a2559b87ab00ba84511bac1a099b1b33e8cd45da078d447b23326574379dd3d32ddb22c6a4037fda719fb104c85f0264ba4a9ed0287a31a2af6d58291676a37c434ecb234e4e1c648fa0760da57abe45703e677fefd03687415132d03252291f02f3901d20427904511f9c11a7f07041302033054605e97fb719a2f70648a2c30a0b42899b195ea8e6cc96610943c3276698a34a61893ba8770c69cd55f1bc0f00ca0e04177d0469c4833fcc23a6ed339acaa91b6e081692340f53cac66af5a6bcc2391729ce4e1c88d5c2610b00454fa21e8faa6487022f19f2c81d5452d5170255108beaf3979ff9abc2e04c8e3669c6aab80e2b6464644ae2189c81fc92d50cc56039cf5de2325ae5163a1b63652222aab35e17430d16477537f867ba4ca0e9b1c83c61a562c6822e61bb1450426e9716a77c1934ab17ec69563b8299e6ab371d996849c8cf7a84ca1a9bb654e1ab20a81d65314595a52ba18076f8712532a81b00e19e8734968f87c03fa4763208862d9a3ca648582482bf0d5441fdb7c84ab237d9f8628ed2001a501339682f9b8aaf6606344b95342fa62e782c1d9560b6ad55aa332c1fd533a74d026a9c9757f0e91bfc96545d0b6477f31f95840ff0a4127b16c32b635471480523f93017577513ea96159ac60be179d3a09c5ccb6df44174de866cd7548339d314d160718f262edf32382915197bc2ac6e3a4f77229e22dacbdfecbe3f4b72ac6bc9d9354e7ed2c31ce7acd7f3a2c8b9abeec00613b1600c8992376b73f8c245ac9841ea06409454b48d8c3a152bb8d6168a3fa6423373651caa7aecf0a5971641bd66897e5991e793343b5190bac3107eeaabc71bc34788a345bcb9ad8a45a50a1dbdb1846bb76205b06e8aeb692b4200a596524954963f01c946131704f6b181d7781772ca6365824f6c6c22a1af3328a2c8978ea8d7c38f6a00f7a6b3a50c2507f103f72420bdf98dc19aace30b792851142d8b43319c93ccfa966d71cff9352f25fca9e8a3064cd96e42e9a2959c128fd532902419b81972838532cdfc08f34541459cc68955c9c2a431ba5126c9bc08039ca45533ad8108beba49bf8d56bd44433fe12a6c55c41f3cc20560b28cf050cc1f195c5e817d23d95e105a13555923cc21b13c9e46d34182974451bd97b6a3da440de6e5bbed681d6eea2c6822b361019afc8517ab7585926764ec7acff3c747479e837831429b97b7cf49ac3763bd9ebbe0a3729672816f3eba84c9638a79676eeac0f22c8a48e0c5d50a26ff0844c66b99" +}, +{ + "dz" : "ae0f65e29f38804a6759f70f4d01e2aaff7fe1c91ebc4f892dd0de3ab2e68ea5e03ff73e02a217659f53d8c47556bf3d8c94040f630d63605e2d0f923579370c", + "pk" : "a6cba4e1a93cf066b6c6284b85c1ced4a4b17634c2dd8c758ee3cac74b2402460d2fc12d98943de4dacb2f5912fdc41e8b1886f38c6619831677e2a32a63860d2a1e9b994bf4f9cdf0c3c83c5b044c14b83e57c59d55629a9704994a4793a7178b69ac1892a578802a69d22d609a7832b55e731a65a1f29753870f8f6b26443824be227f578c6d97c57e570864092a66c8184ca58b1b8f89ba9c2a3e7a17c1bcd851aa552ddbe301f2774e81397a57247362426807f370ff2b7f6f7b1f5b83c2f3475cb225b71ca0750f333d72a434c88a902d542cb8f50f6ba8ae5531ce60c5c29057c2a995ced8a34cc1db7005c478fa174874bbb82981107faab591b8c9581365e7205578c55fc06b5f588c65e2ec700e6473752708853a8c9a1acad3c08bfd67c553b9c603206a1d26276e66c53a166398db6b2e51754e2a67a54902cd5839b97c66d2421df86c42c7181f89d2afae41bc116212a7492688424a2c81b85bf616ed686e8d0183c1082dd61c1144417dd10cc0e29b3168144064d700c2a295c1042ae40848fb07abf2aa7cb2883fb19454a8711c72670d8c0b152dc9cd39a108ad9348089754703a608c0b544350879ddc71c09051f92ba755717403130dc4b95c19d3510363a5dd620cdeb1918af90dd1267aa9696eb0334810b9351df981a0749a7e0c253d399a0115ae515c97b63a1b0ca42794e00ef59912a357565b427dd5aa54b706b0df583e2fb68ceab61395024abba0a8ba4ab6bae958d9c13eed40cd20978eeb5ba041b837595427a644a850340168847acbb69b8d6809b849a7d6a6b67c170dbeaa41be8341c6977dbc025688244396503411148458aa2800c44195211a86763c54e45345ac258541926b4bced6a337df4506113647828b2d4e45723d68985dbc2772a6723a032bb3b84a140a95dbc480f1495118238e74376c3aa78c25e3703ce121e8576c22ea29119b1eb5b946d261cfdc71980af7961961074584a7ed970fef29172cd98a3ea5550f994f5d763b00fd37f9c0abb1459b825c6deac0b35d451a9eac64b03c3c0139806586c8e0f63b8f77aef5b207d2615d5f296894c9a1eb0b68d0571351e18a20084580d98aef13bc4ed039d132cf015bcbf0270d5b971f10f581093656a091af7f3725a2e16c8a74c541345ede689321a436ac488b23895ed3e81fb4f25b83964400ec33c529350ac29f4876128c010ca9c4b6d3e47d7ac798559251bbe4bbc7ea4ece0b76e9f519d819b286f14fcadb1231067bcb113ecbc737020b47587c491fd26541f47ee2b6bfe6908c73ebc3715c58aa93484a5c2692598b4945209d47258441c2cde253434a5a1edc934c9762b2740795857e255921296a8bd4542f82bb6ac7e293f9e4b7890810a2e46511e241162b2af6e38c2a07b15a38a494f8412fc40d60847f957b7839e78936b6c1ae906089a80ef5c58e2659be2643083922b22da53912055f26fa7ccf410abc42cf21448290b168cf7c8ba20b28dca959acc253bfd4b67e60c0c5f82728382c96f78b48b4a4c746c32c019bf8c3202c46a7a2c9c401700eeb1c013bb399d9b62eae9a4e68e4a4bec7b7fb92888ee9bb5f52aca49b2e3f6ac6b72b2cdbf2c755f85fd14903d8712fe0bf82ac0b06aae9bea06278c21e6257bc96af0379bca07c7833", + "sk" : "b8f488e5f0c30b5cb5052115f097a6f20c0f6c4206522a50492991829251a189c53fd67ae08a467590a38099994bd5a0b5109827b888f5322bf6eb9c6d75911b2a721c92905f145514a3138ea132e5dac52851160c171e80b728a87b855a78ce550678ea20044db943c708962c25a86c78a29cfa801aa15350841989c00563fb46d299274f18430d66cb6ed9bc89145cdb262c18d5c095703e779c14ff34459ed12c13427733c59bef3c8a6c24b5bd5171712b074c797960e2be7bf2b58a8111ec9c01a3f938e83637fc9b59123880fd26a845d26de5fccac29657cd2c8831ba76168421b276120639a98f13a07f905c2266bce1f825d1c464bb2016665a2817c84369b7708f975641026321fb4c409531cb1a3827b80f2c94b1c4d36132b10e69b8c94502cd46c540902b96eba76a55e3bcb8fa037a217bd91816ee09ce30f19721f12432d7238fca919a2b4f718674d4558dc7095f0461a20b4aa1aa080354ac60fcc8ca2400b2ef73246514c41cf3945cd6a425959d1ad08b51e43c02a834df3c8e084b04b9695b2d1500e9d5761e86c95c7c1a0e12783aeb6f18e14e157881640204cf5a7a2ed815797a49e0696ee990448c312cb7a55a28fa1367b196001cce6a56796208100828be8c241cecfb82caea1bdd36b19351cd8bb1cab7014cb887bc6e232e74d036437a3222f56bd3e0893eec360ffb220c03222513293aec7ea6da408f9c12016ca03659791ed14241331e5ceca1b53a2453689f8ad819906cb19d731e0ba7abf0096998f18917e4794c4b15659678dcdbc8980b76a4d5c5b8567d55719e774a2d1c952612a9af1ea7c77f896f88242790d989edf3781588c10a7c50ed25821b4abd882370aa74bf299975e9c54120b786f5917135b69f3ab24465aa134cb1bd3fd61f27fb38692b5f3db5cedcb40b8530834c9abdbae738c45017cef302ff334c9e2567e0ca791175813a8382489b51015bcb8ad5cb37626dd3c48c745006f5133bc5557f6afa7ca4633bbb26524ae968df362f33c716ea9131df1754515083325bb3f4e91e40f2c598912ca1da3770e81dddf8980797277711216b93b41fe456307a8135829ce7d7af348a090758bace57af3f353cdda444629a596ee64d10a5881eaab061782314d218982602cfda25a926bec7d57228844adfc31109d210bb2c88809c47ad09c466141b66ac6a013280efe78d38e73d6eb9ba00f59841050558964b2916ac04757e968bae6bb715d94199f22a81f4e3247b7caebbe3cd9bdbce68c931357a568c39acedfb0093337d95d92dde215fdc5b6bd7e2b14aa29046d2a601a91f9d4635f985a393e4408d64be23052ddaa323c5d0235d4a578a63cf6c655d55f78397d72fcc0cbb490253b9a4ad0888c742ccb474cca41bf4b51c6693767ab872586da6b470ccf0066a038deccba3e229bef1fbbbe33b42a5c524533b08ea926469c9822255150cd0633df08b01670f0c134074f22dcdfb593e477853fb383a4b683c786139891f647c8a42680d89352004560eb1232fe173c47379119b29226691b015649253673187f98827d22aa0c168fd7a339992ce4fe717b6e797f616c27d49b8df377f1300ad643220db8315a30429a6cba4e1a93cf066b6c6284b85c1ced4a4b17634c2dd8c758ee3cac74b2402460d2fc12d98943de4dacb2f5912fdc41e8b1886f38c6619831677e2a32a63860d2a1e9b994bf4f9cdf0c3c83c5b044c14b83e57c59d55629a9704994a4793a7178b69ac1892a578802a69d22d609a7832b55e731a65a1f29753870f8f6b26443824be227f578c6d97c57e570864092a66c8184ca58b1b8f89ba9c2a3e7a17c1bcd851aa552ddbe301f2774e81397a57247362426807f370ff2b7f6f7b1f5b83c2f3475cb225b71ca0750f333d72a434c88a902d542cb8f50f6ba8ae5531ce60c5c29057c2a995ced8a34cc1db7005c478fa174874bbb82981107faab591b8c9581365e7205578c55fc06b5f588c65e2ec700e6473752708853a8c9a1acad3c08bfd67c553b9c603206a1d26276e66c53a166398db6b2e51754e2a67a54902cd5839b97c66d2421df86c42c7181f89d2afae41bc116212a7492688424a2c81b85bf616ed686e8d0183c1082dd61c1144417dd10cc0e29b3168144064d700c2a295c1042ae40848fb07abf2aa7cb2883fb19454a8711c72670d8c0b152dc9cd39a108ad9348089754703a608c0b544350879ddc71c09051f92ba755717403130dc4b95c19d3510363a5dd620cdeb1918af90dd1267aa9696eb0334810b9351df981a0749a7e0c253d399a0115ae515c97b63a1b0ca42794e00ef59912a357565b427dd5aa54b706b0df583e2fb68ceab61395024abba0a8ba4ab6bae958d9c13eed40cd20978eeb5ba041b837595427a644a850340168847acbb69b8d6809b849a7d6a6b67c170dbeaa41be8341c6977dbc025688244396503411148458aa2800c44195211a86763c54e45345ac258541926b4bced6a337df4506113647828b2d4e45723d68985dbc2772a6723a032bb3b84a140a95dbc480f1495118238e74376c3aa78c25e3703ce121e8576c22ea29119b1eb5b946d261cfdc71980af7961961074584a7ed970fef29172cd98a3ea5550f994f5d763b00fd37f9c0abb1459b825c6deac0b35d451a9eac64b03c3c0139806586c8e0f63b8f77aef5b207d2615d5f296894c9a1eb0b68d0571351e18a20084580d98aef13bc4ed039d132cf015bcbf0270d5b971f10f581093656a091af7f3725a2e16c8a74c541345ede689321a436ac488b23895ed3e81fb4f25b83964400ec33c529350ac29f4876128c010ca9c4b6d3e47d7ac798559251bbe4bbc7ea4ece0b76e9f519d819b286f14fcadb1231067bcb113ecbc737020b47587c491fd26541f47ee2b6bfe6908c73ebc3715c58aa93484a5c2692598b4945209d47258441c2cde253434a5a1edc934c9762b2740795857e255921296a8bd4542f82bb6ac7e293f9e4b7890810a2e46511e241162b2af6e38c2a07b15a38a494f8412fc40d60847f957b7839e78936b6c1ae906089a80ef5c58e2659be2643083922b22da53912055f26fa7ccf410abc42cf21448290b168cf7c8ba20b28dca959acc253bfd4b67e60c0c5f82728382c96f78b48b4a4c746c32c019bf8c3202c46a7a2c9c401700eeb1c013bb399d9b62eae9a4e68e4a4bec7b7fb92888ee9bb5f52aca49b2e3f6ac6b72b2cdbf2c755f85fd14903d8712fe0bf82ac0b06aae9bea06278c21e6257bc96af0379bca07c78331bb014bb0d6489c14f5411051f9667aabce54da7a8deb73b627e3873d9390a35e03ff73e02a217659f53d8c47556bf3d8c94040f630d63605e2d0f923579370c" +}, +{ + "dz" : "6084a235f79dd093ef6d185b54e69df33dacee73a9bf2f379004421a10e3a79d9f684fb055ece19459eb464e91e126a7a6e3ed11ccee0046da234d964c985110", + "pk" : "5a0322a62aa889781c4fa3c36f765586b2c2a20cac081cc08d06ce1cea6036463dccc34bc294a51f7b1a5dc0778c143f57b9ad2c8b41a3b3a7e3317fec687f50294158ab07441c119c299d421b3d6cd62019b4cfce69c9dc5509856b7cf087b66391793e7b2a77262db0909861b46b5d4c23fbf134ad43622357a81cb7c9f5ac9cf1c190b9f711164a9cfa4892927364d800ad7fa2888dbbaa21b689d4a20fd0ba43f27386f90026322705b0f1069b32760802581231c44db0a43753779fe88f3a824f2ed858211bc172d49221931c3e86188c287a093b1eff20af18c1004979221c85c2ebd5700473913d465359ac18deb3055075386ac3c330887879d5ca762b6b576b7f2d422f23889d51788cd84b77ae879b1eb7026dbcce20cc94f7857aea148213c1ce857277a7808857f47e45cb9b561b80895142463bcfab6c69a7712acbd64a3b6721aa9671aa934cb0c1bc52b464603779fd6ab10d57cca0a749f3a1889e10386cb7ab0bdb86ccb02ea614a0966a0ef2699da6b7282713874f36468c2014539bc804911053d1025133975e591e357a8d88a1c7138a200543a90f4aa250f44ca61870d206a236d1917b509638fb6442aa7b886a54fc21b7c40a1b7d027a09863ef94280c67a4693d28a0f842ef2268e0a67a11bdb4a18b3c459e11e977a5d143aaa82b80520f72c50d248073746662b78ff685086632e304085e9c7050a754b302338f7a2af0a223e45730de36074e1843876a6b1cab85e0d984ece18a3420aabf4d740f6039dd183c57279469bfb9f26fa4f6ae59db60532372b729cdb8bc8b26b9e511234177af2717538383bf2103726c79d84b4489d493423f7375c273a9558611b60c9fbec197047566ae9411637ca9dcb956962354872803891c728429fcd99c02ad020c11a2f1aac40b6fb13fd6c8508500fbfc34d752080536c150b402155e130c3aa1a4e914ada0740b5178c83a67fea746803a35c36a3cc034052143303bee180d8da097b24c89fdb16583b972a50c89b5ca27dd4aaa1002fe2316940a7ab294b02eca4c69957b3d02b538c239f18a342aee0c15fdca57d28930a62096567801f64c3452697d5f4a66781975b440ab3b27a5da41e889928ff41402b20b93f992db6d4216a4a2b169a6952816d61b93a82c5c0d5923152900be6b9236ab96d076b36d406b06793c7c8c85d69f423774c4a0c143e27673cecaa38c66c1dba02860cd305214a2637a90cc84a7aa6bb919e73c06ddb787b1b9117a2c6fd577a7eb417d5a34922767bade412bef212694373401554211c1213ac7bd1d1cc61f40fdbc65b89ccb3383c30476932d738b181b64e2bbc9508268c7061a4731c659d18749ec3b87c3741d1660d10978cc91ca44df588c8a0a7a68670a003ba23f03ae733067139083ed33c98dac4c06331e90b59514c7005e27f179a0ec8517931b678ec849789c656b30c4a736209e70151cd970ade5557f9e6872248b94c894220c0bd1b6a3a0149c1bbb8ba4c9337aba868b78199929044f44018fc261aca4bcf0f70cc1444411fc8cc3b6b7aa7ea9f8d06a30c7a61d89c19e7c50b84a278a921b74e2936ad07ae2b17344356a8e640a9a1392048cacc817bb0924682a027f2cf6ec9b36aad177faedba70e26db0e2958e3d520d23b10254587", + "sk" : "1e556e2047c1be5b68fa204c0f36add1b8c00e6b66c0906958635733f82238d1ac4686929e4664b5217a774299df70822cdab3e06c5468d8be7d8745f7569e5851317d6b6cea6909c70b72897395c57494aa20551b4501e45825018260dc315b71e72ed21049a91b01665440345a102efcb0c9329f7cf0c619941c9ea7a1651cb0591c53e804987395760ca688dd7c75bf2b255dd618c168b8ad735876e9066c7275f7eb8200970ec4b9c36e296a7be41fc8b64c35e9b15473337a3003dc62794a0aa8cdc71c65577085253220869fb2845358ea4d73ba898f123f7f0cbb58db2dbc26a98a5b8299b40318285a26573ff928bfbf75915ad0518965bd345c2072157748077c16f562067b154ec88694c1b71d20624f19b62e30844d930c91e95b28173f9df878d9507fa35812654353f99b93ef9ac6f61503229a72558570c9d5213db68347f8145a9798597219df160bdb0226ea8b569c894e2ceca7c3c86ccd66450fe13e5c4556db3c9ba3441b37e26ceb9c7fafc460ed1373aefaa3d593b7f317b2f0f8782b76c18eb11d0d804192627d8657bdb0e440490b6c196797c0459cdd791b82b329c6439d2460ccf37621a34b263b7b46f522c24c294be8b36c117418dab096fb874db3516e889b3e92569c32e17f3eec3c5b28766d3a2f4d06475bd666edf00bf0a514d8c06309934ce4a191805a38d7d69d0dc926eb58110e9c5bee187d0675b36af68f6de7a294fa7ca80486d1e561d28c8788a75cbfb718bc740d131a83f9e64f5b484de82775b2b8762dd568e8528e6f213a198a8d6a21b9ef668b49b87e8ba97ae468a379968fd18236c95c96f9c84b23296d5a9210869c5df05421e9c3c2b65975a93aba3eeaaf5d746fa679c5e93021cf93ce71a8b45fd44ed92bcf43d0172a8589585b9cdb7baaf1041e81772b37861fff4c60fc5b7e8d6871382c63fb3c7249c3059385c7d856cff293138a3b30b6b13614354a502c7bf922076d028affc5bd6d43706f5304fa2783a862552a5b2dd48471880529eb230851b6091b59139732102f66268286828fc767930c1b4a3bab3f14bb1490ba329401f8d95d347b3450d6cfd2c8355db3697052a4f3884df8bc28d3792fd09352daf9023b6484f8553fe15336a788550f6023d9c9a42034874cb0beb25a6a4517a1adc72bdab35293f16efd7171455b948103bee4fcb7d635723eea0a4f7a3dfa3838e7243143971bebd25ec82c0ef059992eec1aa37835fea57ab04347e86855e0ebbcebd828556a18b167b5a4c7baa945560a276ebce40d8b6c6b23b417fa8c39ab55791e703a3568ba28f022ff8cca8f6965792067ce23465afb4b3517b5aa80c3c7001e78b62617e87e3b27021636667e60a47258155f9a06a1f8c93f39420c141372015b70a3b69da51dfce42fd748c48916851d78c8ad5c5bdef8624df33600027495f6be5c6a78cc43b660767cc1e77d5b7396f31c8af0b35c9826c185569255fbbd7fe0533767c89fb43d1e282b0b9b348ef31d7cb15719a0c1db21cb57a1171046ba9409920f08a4a6d12855e113c427b2ccc4193c11781df61345229191b60283eccc3b05c49316c144a8b21e494d3ce1b11d58391bfb7bccb3a95a0322a62aa889781c4fa3c36f765586b2c2a20cac081cc08d06ce1cea6036463dccc34bc294a51f7b1a5dc0778c143f57b9ad2c8b41a3b3a7e3317fec687f50294158ab07441c119c299d421b3d6cd62019b4cfce69c9dc5509856b7cf087b66391793e7b2a77262db0909861b46b5d4c23fbf134ad43622357a81cb7c9f5ac9cf1c190b9f711164a9cfa4892927364d800ad7fa2888dbbaa21b689d4a20fd0ba43f27386f90026322705b0f1069b32760802581231c44db0a43753779fe88f3a824f2ed858211bc172d49221931c3e86188c287a093b1eff20af18c1004979221c85c2ebd5700473913d465359ac18deb3055075386ac3c330887879d5ca762b6b576b7f2d422f23889d51788cd84b77ae879b1eb7026dbcce20cc94f7857aea148213c1ce857277a7808857f47e45cb9b561b80895142463bcfab6c69a7712acbd64a3b6721aa9671aa934cb0c1bc52b464603779fd6ab10d57cca0a749f3a1889e10386cb7ab0bdb86ccb02ea614a0966a0ef2699da6b7282713874f36468c2014539bc804911053d1025133975e591e357a8d88a1c7138a200543a90f4aa250f44ca61870d206a236d1917b509638fb6442aa7b886a54fc21b7c40a1b7d027a09863ef94280c67a4693d28a0f842ef2268e0a67a11bdb4a18b3c459e11e977a5d143aaa82b80520f72c50d248073746662b78ff685086632e304085e9c7050a754b302338f7a2af0a223e45730de36074e1843876a6b1cab85e0d984ece18a3420aabf4d740f6039dd183c57279469bfb9f26fa4f6ae59db60532372b729cdb8bc8b26b9e511234177af2717538383bf2103726c79d84b4489d493423f7375c273a9558611b60c9fbec197047566ae9411637ca9dcb956962354872803891c728429fcd99c02ad020c11a2f1aac40b6fb13fd6c8508500fbfc34d752080536c150b402155e130c3aa1a4e914ada0740b5178c83a67fea746803a35c36a3cc034052143303bee180d8da097b24c89fdb16583b972a50c89b5ca27dd4aaa1002fe2316940a7ab294b02eca4c69957b3d02b538c239f18a342aee0c15fdca57d28930a62096567801f64c3452697d5f4a66781975b440ab3b27a5da41e889928ff41402b20b93f992db6d4216a4a2b169a6952816d61b93a82c5c0d5923152900be6b9236ab96d076b36d406b06793c7c8c85d69f423774c4a0c143e27673cecaa38c66c1dba02860cd305214a2637a90cc84a7aa6bb919e73c06ddb787b1b9117a2c6fd577a7eb417d5a34922767bade412bef212694373401554211c1213ac7bd1d1cc61f40fdbc65b89ccb3383c30476932d738b181b64e2bbc9508268c7061a4731c659d18749ec3b87c3741d1660d10978cc91ca44df588c8a0a7a68670a003ba23f03ae733067139083ed33c98dac4c06331e90b59514c7005e27f179a0ec8517931b678ec849789c656b30c4a736209e70151cd970ade5557f9e6872248b94c894220c0bd1b6a3a0149c1bbb8ba4c9337aba868b78199929044f44018fc261aca4bcf0f70cc1444411fc8cc3b6b7aa7ea9f8d06a30c7a61d89c19e7c50b84a278a921b74e2936ad07ae2b17344356a8e640a9a1392048cacc817bb0924682a027f2cf6ec9b36aad177faedba70e26db0e2958e3d520d23b10254587c9a546b5c0a567855039f6c1bca60414684e7bd1f8eeb7913f3a1795ba4bad4c9f684fb055ece19459eb464e91e126a7a6e3ed11ccee0046da234d964c985110" +}, +{ + "dz" : "acd1c0217fad5caa4235544dd9de153ab1880ccf4c76f16f236fae4e4bfda04cf03a8abb0a5010f400ae5722a75bdf5a2f6d5b546b34d73857cb1bfc7e587aa7", + "pk" : "ec8c397304996ce42773532b2798c4bb8a987e57b41b820c6f8b2c64181873bc6515b0c810109890b8abd9bc650f0344e3e7a672e269547aa4bbd0baf9f2b2f3b53b1910b255f7cc6cf0394ceba359685e9f6c77ddfbcf0217611d076ab2140a8dc58199a2a235955b69fc2520b192555c1bed2777ef623760cc71b0208dbf2a5d9841a231a60e2516c5ca3c6156a0c0862b54c311ce2b6b3f442c8082348833b193cb2b22d252a9ac88098c704d83f217ab2a8799f031227b95e1fa5d1a6410e3f025485338fb8338b5c7c4c0f6641b71644f11124b13c2dd21088684035a66a4c4451b5f66c9d5aaa7ace15eaaf03497ea2e1d693b77a4402dd1943e9c68cc642997a44d2f86a339c78912e678d0e314ff162c0e3c9ed8eb726ed910d1b26b99061c01142380e5074b5a46505863f6287dc18422b323c89966340ff7146fec18095147429148c24718301c106dcbb5a1b644e5a26ebb566b504a9b2984100bb6c40b45286d4c2841d774dc8915839c32ddb22adc41c0197431bf8c5f26c2329e6b2a0efb2b0d872c4b8b125d997937236caa455389c60f9e38ba3a662ac7349a5c872d84a353f9710c6c74463f220f37558458d68da5e67f1130cc5dd5ac4608220da2b8c9048bc805bb1f6bcf04379330025ca86b42cc361baab986c32a9e266bb1fa27552192a56b4b111564646b701dc4771b8f61bb5d41278a291920ac1d01649267344732a85109a3cb45b7b8e9abb8cec49ff602c819695f61011c7ac5957fccc50859432f324d6623459d7bcbfa20645b2a54c5a8ba0df27f93ecc2ed00821e98553f680623ebb221953d3d9b8d188044d693abb88bc965984b08d112ea6b4885aca190f9877f1bc123220aad662fb7f5b0afbaaae118c6108c98b31a5b6ff15aad0a87b172bb40998ec232a9d218bca9f03e88633914561c9ff65be6dcad01550903276646208248a56e5c3239f951585ee9326808a4e4f829a15996452a3328253ce2cb3613aa4fb02acf3030b64c6a27afc5863487b9538b53a2e1456168180d257f4403b41f16b415740abb024eb54c23d6a851bf9c54932259d1bb510964445067c68ae362dac6a7c3e29ed3080b0d21a76ec220c7d562340123f7a32c62184d2d707144a1565e432dff443940736cf628caa3607076783b2b29bea7058bd164219518aa77c2b303e07dffcbb00c930ef0f0632c10aafdf32fa7bcadc5719fdb591c7635c3af83198fe306076a9da2455963b91551a1618040b0eac945f788820a1442ccd10fbdbc763cdbbb6e221e8ad076880abd561c5059e23709d40996d41fa6f129c4758b62644c30c1c06d0080091b4d5a8705f4b0694507252ef1a5980a347846160ba3256475741d50a7ae465f1b444a25729ecb66585e51992bc781f28c180593c4e5882c243017440633007db1c637733a01bb8a994347d7602ed0b34261603b84b8c2e14c5c46167af459507152da216f272371a0981fdbe740daa78b9eea655d98cd14ec90cd383863ab5fe8137ebe820df5a007a288586e18a54b43387de9b73f9037f27384be092b09941262706dd6db377f733b31a49d2467605649b9609365232252a62555b1451674b717182870c1088f4b34061f3e8b9034af0cf2c5f7eeb665e064f5f27cd5e4c84531d45d38051ef9", + "sk" : "243c03e7374a7157b1f0c02c4d542e2b31a45a902d908592f3f620c347511d650af8ca8932b70a3563ca126391f178c7c1477c9af532cf1897de99bdd7f07c0d304f90190ede5967898a0e7818622cd76724f77c4d73248bf67955726afde4c4e4201a21ea48401099b05b196b4c698565094b3421c2b429cb83a99b2a7bf5c784117b9e8f7c00d8f1c801b66f63402aeb49822a92afafa445f1fc7b3e76cdec3091cbd474d10ccec25539a658a1a48b6697252d28442a36e70578b810898045c0118468e6bd05c664e4c19440b88e0e847a15ca747e9990d995cd4172b5933b58fe7062b871ca02f539e74872e283abee046c7e15372e58455e4a6de59bbf716bbb62417b6e46296e68c501d4007e1a97b7d970b5bcb8a9586fc42433eb457993e7b15d7c35de95176b09065a1a3f61734b9d453ff0b0313dd8c0888a92f6270ea93ab6e9f15e9f6c207ca9512a41364ae6591c578ad93639e795cd00339cc5b67176f771fa6c5496cba3071b67ffb88b72993ecea38f4d8244d94676e55ab3e484b0ad4776be5ba4a99766d63128828b7497725abff8a932b1a697b6c0a27b3b69121607288dddc03a4c144cbf0a0b11886b2130174b99921b1920320ba515032ed7d536f5b352975697b8a05855cc78d7979da443a06d443d52b4931c554ccf03b43631213b68385e1a2c5f87c84e13b84032804f5929fca18c2ec8a15869905a216fe2852631e00b19b45a4a0b51243b118eb358435b9b46a0525426ba232439cee0cf6f8b164d72901cbb4f1b2750279c18aa255f5d7053f10c1750894c886b59c9ac43b881cd5e4476056884ab9a246248892c0c7a3ab8425d77c178b47c8ca5262949ce47c25b90cb90942b1aaf64825a7658c4e0bef219ba2e609eae90bb6983589e128325dc42d9422c72d0452c208b23297387a9b77ab8b89ba34266130d5cc35568ab1487c335fc9a91dce293d807ab73a41eec932c0e398a762881d2da7d558352d7b8abdab79687e3ca3db89036022adebabe39175232b36703749391c9b772a79396862972ea6c0b92387fa423fcbb6030f83d68c4a44600b25c547f7173376704a6e24c12a5906afc43bf539aa6aed0281d786336373a44147b1e943a9c0c7d8f995f61377134ec1f536334aaaac6ef040dad6a42feab2d6972880c602d97540a52305b24dc7cb243259fac61d2632285099a0ab740083178cbab0ee8f17599f115e106c4abd606ae5568f7a387a086b334f7aea5f92249d678add0c26f268ca769696fc14eb1c6ab8e182e5a727793d6bd94461b0e985d67e64f794b0def70c43ef927544081011a74a28c976c553ae2e0ca49c80926f460078886f49a55475c456f2bbb84270f22c5256241aad6e05b4a9a276e3357c1b92d5df09db23a783f19b1d9d594e064b09fc815bd43b5cb8b9ac43c64a2bca445b235f7bbb3cc0a7723d0a2e351cb4ecbb1b688ca217a500fb20cd37b1a0a2c4eb79775eab657425c8b264583b5c37bbcfa624ae1af5575571aa59960f37599d25cc625916ca149502766aa06cf31fa23c99b2099b9677ba327ca317e49e029eb33993068b022e00411462d7a548f4bb6b435d8ccc1305067f923c7a914d5d77fec8c397304996ce42773532b2798c4bb8a987e57b41b820c6f8b2c64181873bc6515b0c810109890b8abd9bc650f0344e3e7a672e269547aa4bbd0baf9f2b2f3b53b1910b255f7cc6cf0394ceba359685e9f6c77ddfbcf0217611d076ab2140a8dc58199a2a235955b69fc2520b192555c1bed2777ef623760cc71b0208dbf2a5d9841a231a60e2516c5ca3c6156a0c0862b54c311ce2b6b3f442c8082348833b193cb2b22d252a9ac88098c704d83f217ab2a8799f031227b95e1fa5d1a6410e3f025485338fb8338b5c7c4c0f6641b71644f11124b13c2dd21088684035a66a4c4451b5f66c9d5aaa7ace15eaaf03497ea2e1d693b77a4402dd1943e9c68cc642997a44d2f86a339c78912e678d0e314ff162c0e3c9ed8eb726ed910d1b26b99061c01142380e5074b5a46505863f6287dc18422b323c89966340ff7146fec18095147429148c24718301c106dcbb5a1b644e5a26ebb566b504a9b2984100bb6c40b45286d4c2841d774dc8915839c32ddb22adc41c0197431bf8c5f26c2329e6b2a0efb2b0d872c4b8b125d997937236caa455389c60f9e38ba3a662ac7349a5c872d84a353f9710c6c74463f220f37558458d68da5e67f1130cc5dd5ac4608220da2b8c9048bc805bb1f6bcf04379330025ca86b42cc361baab986c32a9e266bb1fa27552192a56b4b111564646b701dc4771b8f61bb5d41278a291920ac1d01649267344732a85109a3cb45b7b8e9abb8cec49ff602c819695f61011c7ac5957fccc50859432f324d6623459d7bcbfa20645b2a54c5a8ba0df27f93ecc2ed00821e98553f680623ebb221953d3d9b8d188044d693abb88bc965984b08d112ea6b4885aca190f9877f1bc123220aad662fb7f5b0afbaaae118c6108c98b31a5b6ff15aad0a87b172bb40998ec232a9d218bca9f03e88633914561c9ff65be6dcad01550903276646208248a56e5c3239f951585ee9326808a4e4f829a15996452a3328253ce2cb3613aa4fb02acf3030b64c6a27afc5863487b9538b53a2e1456168180d257f4403b41f16b415740abb024eb54c23d6a851bf9c54932259d1bb510964445067c68ae362dac6a7c3e29ed3080b0d21a76ec220c7d562340123f7a32c62184d2d707144a1565e432dff443940736cf628caa3607076783b2b29bea7058bd164219518aa77c2b303e07dffcbb00c930ef0f0632c10aafdf32fa7bcadc5719fdb591c7635c3af83198fe306076a9da2455963b91551a1618040b0eac945f788820a1442ccd10fbdbc763cdbbb6e221e8ad076880abd561c5059e23709d40996d41fa6f129c4758b62644c30c1c06d0080091b4d5a8705f4b0694507252ef1a5980a347846160ba3256475741d50a7ae465f1b444a25729ecb66585e51992bc781f28c180593c4e5882c243017440633007db1c637733a01bb8a994347d7602ed0b34261603b84b8c2e14c5c46167af459507152da216f272371a0981fdbe740daa78b9eea655d98cd14ec90cd383863ab5fe8137ebe820df5a007a288586e18a54b43387de9b73f9037f27384be092b09941262706dd6db377f733b31a49d2467605649b9609365232252a62555b1451674b717182870c1088f4b34061f3e8b9034af0cf2c5f7eeb665e064f5f27cd5e4c84531d45d38051ef98f7bfdde2a7116ff4010cf829cbb18512f7cf44237c02241a1f75fe3ba8d22bff03a8abb0a5010f400ae5722a75bdf5a2f6d5b546b34d73857cb1bfc7e587aa7" +}, +{ + "dz" : "241191401a63afa750f05662e354dddbc683c776ce3222beb83e3cf913d7ed7ca59b3bd23b49a95bc1fad20070fec930b6060bd827d742b077092e422268e15d", + "pk" : "18f81e47490cf733359bb77d86b1b949396baa99c9d73485e378b6eda76318b961948497db54149f386e51648187c48a94fb603eb114a9408ba0d27f3c717694f9459ddab7c6d51a58c50a79bc072d7717781a6b12073577d3a89a405829850aff65023a771a5f5456ac5b3970d545043a2254178375268abca9a967f50db28635b1d01e7d1969080438368a4b61f63efd82a811f63909aa48a055cd9345c09191abeaab8237696bdf3512b7e8625212bfe5500bd7002066357954344fe361be074069a520a470eb64bc0289f85c981995141a246ee3c6673d9026b7b490a82819ee1825ad39284fc41a01c936d0280c4c681d62e47de8e339fc0a0f958b279ab95114209231faa8962754b12a22efb67ed1c42e8c144f74476f552a297e7573a81717144648befa3b6c6096f428c10fd925ba86b29c8890f2750d1e7956664a714fcc00c88a3cc259b503d3ca39942986d19ab6d76378858d679cc61ab40edc5a007d33813698a6ae96acbe95474b188bfd3208c885179de868dd027f12256b9fe84ff460b180c7655d514168c89a516ba4ddcc56c1b5325c9312e067949a57178251158eec2fde69bc9d61be726338830a86e8e525ec00152cdc0e86473e2b54ab64790735c3a945cc83b999352ad2587fb67dcf2c9fb3b921deac54dccc8201d36562f64831c8129e67b2ae78bfacba95f29c3d20942781e090ebbab81bc5c071b0bce826173f0cad6c101518b56dd03a8bdc872d338225bb16128ca8c7212867dae513c971b687297e4c098ff7c478f841a29dea278d1bbe55423321372a44937d2aba34b279c99e8847c5d4b51f54143de991aa16aeeab267386c7f286445acb87a98cc93029658bb0981048876f0884b526ba58f201257a2245849a57cb425cd2ca92a3cbcbf963a4f360e8616c082d8be4820323df715bf5344fcf85ba070ac3068ae91989e61600416d7cc28cb6d42a461dec083f6126c749ca457146d114c84fbc576a7dc8f9c2c03cf4a3cd2535a7a396f59d73259654254e5bcf616b4970770bc8a3d030c8c61d93eb08644159414dcc6428be73357531e50ba72b5eb99d9380bc4802339070366a19760c0b15e32a48ae0038453527b10c4ab6b1ae8497f49dc47e25a514258b5c0336a812525c5a86e22d73a9a8c3da5e88a468c3439464fac42491b0bc91cdace7cdb15166a01b62cb22b745c38ca32a9727c8c57537c72563edb4aa2b400b778115b36817f188e659b2bf7c999d108c5b2d252f6a3bb78737edea48c9bb91e917487e4e6156dca609aa97bf47bab00047602f296cf611299510b195ba59ae7bc245b8c9721901995b6df4918842017945c330290c6bb3c46d9104faf014db6728c4268627f8c884bf52e011344cfa795f864a474f9c015ab09c77911a8a52c1aa46aeed6560d4bb1f3b64d65028d373ab3d51a450e600a239767aed9cf25b5c85fc24cc794162ee70e13d88fd3459cb37a92d348a1956bba09e24513d5a5fa79b593a849a1930456f39fade44b583cbd7eb4ce058056df38cd0be15205161f53f2c8681cb9e00525fb59cfd86ba1ae81ccc1636dd69c81ef620651606326a41db9b68827378c2ec238e9179c02965f938a2d0aad893c30d27267e416287d7ddec314a79402a769c3d953f0092ef4f8b595f8", + "sk" : "77f83df8951068a026ba38b5e53487b6d6a39b69129e8b45498746d529cac78b4e9437565f39083aa50ad651b2d536bfeefb93f7ac40f4f4100b231564d4880140873d1c367da759b54c5cd9409382ec3183766a4beccedc375df891c75d4866afeb0ada4a161386b698bc63b5850cd3a1801a4a80f0053251664c7642971e0a0f415a0cda2c660a052a7876a5945c172fc87d8d8c9d06c9c30357ca3f8964b9b76b4544784c16981b075bf49653fb520f99a23e2465789e6b5864b969df900fef3c80e1bb0e12fc93b6cabcdfea9006e638f265880ac630823a0678c29069284a16020ff97404e6f4b2cee5ce8434b869177134f1ae861784b4f7332c4ac89cf8c36e7bce1a59b4682376b33300b7696e3bbb6b301cb3311934514babb29a187db5a4a656bd02d379f40694a6f1b55d1a08de840126740f14bc994da75f2fc3bffcf88fbd9b88f21122dd6b5ee5c2393a69803cd5cf67647e78b94bbcc81355e938eea2aac1053675251dddf380173316970cb1990153c9a0889c3cb05715a02597bfdcf925949873558ba5cbbc8782e57b3720959c19a21bc19c65a27599f32b0f91835c421eefcb3ceedca0b02659f4805d1a5cc916e2b46873cbf6c403e97123271725932b3bb40a0de7b08ff71919b249339a22585cd99698dc1f3413b15cb09142ea1a8d8b0c1f64b1b6fba5ed3068cc262d2067686276c302b20111cbb602f29756c32279dc578e20801d2a3abb762640409b8ba349cb72c9d3056aa788b023f15160832e100b7e48d14dc4b81229c744fc20c3a94918e78c668f1aaf01bb8b202a3c8dcc0f63d456b50461c44101a6338c4b7c725490af0563968a8184daa8720bb36dcca4ae3b3ba26927284c10093c079a4aa3b846a811ce237ea9033541d91fe5308dc32cb8bcb77b064bacd816bd8725569bc85cd7f63d34539c14b56534dc516f1500631a59ad1b985c77c262a0b70c3a14d9b6b81f2c88432568ae2a7ba32824abe9866738adc1761293925c694428ea9153fce0542362be09154b4e06b8a60b57f96176843b2764c3b5f55a1738b71bb2c87e371ab7a70560c245aadeb9742951959a25895d40b453376fdd844c9126c78f3a553b9c9b9d43033ee8c6ab13348058589ec1523321a823d32a97e0bb5270672e9990a0012842c38f3212101034ca8a863ae632b53a412537a40928c503a71b7b095163e222a757f3713157b8e8e369f2e2688d50728efb42229325f475482d167515d2656b1c131bca452892c39b8b2ee658816813bb66a0b16256271f8a23c7c0b31a45c4f42551a9a15e87d507d0547921a26bef229265b24bb96b008da638727615c8686f897925b6f27ada067736a7949bec8d23778708163da61c68d806067becc118785ea432a06c3a99f6648341e80b1c5956b650afd100a63474a32fa53e2a9b49ab935ff4616292d9278e839a70bc1cb7a61a49855216d5bd3c10774836469b48496f0590127850d20c52125150e25bc8388483847c92494c0b48e66aa8805ae8c3a0e7c5ae3ec64ba22381eaf7ac28eb0b76daaebe0b6b6e28bdd478002359c79811b2f47a3c45d938c2690ca38a7a2411c223855bd7fcb83d614266251e76684418f81e47490cf733359bb77d86b1b949396baa99c9d73485e378b6eda76318b961948497db54149f386e51648187c48a94fb603eb114a9408ba0d27f3c717694f9459ddab7c6d51a58c50a79bc072d7717781a6b12073577d3a89a405829850aff65023a771a5f5456ac5b3970d545043a2254178375268abca9a967f50db28635b1d01e7d1969080438368a4b61f63efd82a811f63909aa48a055cd9345c09191abeaab8237696bdf3512b7e8625212bfe5500bd7002066357954344fe361be074069a520a470eb64bc0289f85c981995141a246ee3c6673d9026b7b490a82819ee1825ad39284fc41a01c936d0280c4c681d62e47de8e339fc0a0f958b279ab95114209231faa8962754b12a22efb67ed1c42e8c144f74476f552a297e7573a81717144648befa3b6c6096f428c10fd925ba86b29c8890f2750d1e7956664a714fcc00c88a3cc259b503d3ca39942986d19ab6d76378858d679cc61ab40edc5a007d33813698a6ae96acbe95474b188bfd3208c885179de868dd027f12256b9fe84ff460b180c7655d514168c89a516ba4ddcc56c1b5325c9312e067949a57178251158eec2fde69bc9d61be726338830a86e8e525ec00152cdc0e86473e2b54ab64790735c3a945cc83b999352ad2587fb67dcf2c9fb3b921deac54dccc8201d36562f64831c8129e67b2ae78bfacba95f29c3d20942781e090ebbab81bc5c071b0bce826173f0cad6c101518b56dd03a8bdc872d338225bb16128ca8c7212867dae513c971b687297e4c098ff7c478f841a29dea278d1bbe55423321372a44937d2aba34b279c99e8847c5d4b51f54143de991aa16aeeab267386c7f286445acb87a98cc93029658bb0981048876f0884b526ba58f201257a2245849a57cb425cd2ca92a3cbcbf963a4f360e8616c082d8be4820323df715bf5344fcf85ba070ac3068ae91989e61600416d7cc28cb6d42a461dec083f6126c749ca457146d114c84fbc576a7dc8f9c2c03cf4a3cd2535a7a396f59d73259654254e5bcf616b4970770bc8a3d030c8c61d93eb08644159414dcc6428be73357531e50ba72b5eb99d9380bc4802339070366a19760c0b15e32a48ae0038453527b10c4ab6b1ae8497f49dc47e25a514258b5c0336a812525c5a86e22d73a9a8c3da5e88a468c3439464fac42491b0bc91cdace7cdb15166a01b62cb22b745c38ca32a9727c8c57537c72563edb4aa2b400b778115b36817f188e659b2bf7c999d108c5b2d252f6a3bb78737edea48c9bb91e917487e4e6156dca609aa97bf47bab00047602f296cf611299510b195ba59ae7bc245b8c9721901995b6df4918842017945c330290c6bb3c46d9104faf014db6728c4268627f8c884bf52e011344cfa795f864a474f9c015ab09c77911a8a52c1aa46aeed6560d4bb1f3b64d65028d373ab3d51a450e600a239767aed9cf25b5c85fc24cc794162ee70e13d88fd3459cb37a92d348a1956bba09e24513d5a5fa79b593a849a1930456f39fade44b583cbd7eb4ce058056df38cd0be15205161f53f2c8681cb9e00525fb59cfd86ba1ae81ccc1636dd69c81ef620651606326a41db9b68827378c2ec238e9179c02965f938a2d0aad893c30d27267e416287d7ddec314a79402a769c3d953f0092ef4f8b595f827b1b921723cedf55fe756ff5fb67d555296c6185d171ed8ba01393d1a735018a59b3bd23b49a95bc1fad20070fec930b6060bd827d742b077092e422268e15d" +}, +{ + "dz" : "b9a6b0c05677e957d41a34ba03bd06f2a9092e31f63389397d7e70fde6409d18e99c0e7b82be89bc3c1eaee6680aa4efd394e40c2b3f30523c8117f7c26a8969", + "pk" : "776b6f121675622857b8b376d708b2a861306fe931126822e2e8672fa0b577e8ca3f16495af10aae456a734368677a87fd3c2199060dc1993690c1ae2b76959664a1df6cb2b3738b294124918596b0d69394eb1efba83895d0a7f3081ef81769437cb63b726d4236a65c87c3929b79fe34438a8931cf2b889cf100747cb58d373491e7cb62db266bfb3b7e745500fa418eac8cabd966dc388d0f1b3fba850bfec8c03a29182deaa5ec4256fb3b436f429cac87399c61bc98497a3aca07cec06a128231f945a4a335ab6d1a54a9a59db106c0fd61360ce8870d1cae99201506c9c96d4969f4b487e4d87ba1d45accb5a754585f29db0991376150c65927b20c9eb421366cc840d528734c8b4f1421fe30c99f4c55f1e25d18a1b012424cc9f6250064a61c1b42ac243b6c701e293055a9ea7c44855e575cb6217c381de770cf461040c20b2cea6c2a921c9be483ecc2718dac01c4a5a15b60bfd5222fc988c60b23504919137b1226d7b72fe4105154711d25790a9f64c95356a787058018cba996410aa4f29a62b6cf77439b5784b67390b96db77c1583bab490719d804e79b8954b948388514a7fb78ebbe7959599ca374a66558a8fbe7aac91e8a62ac623690a952e94bb91e64fe57ab4db066867ecc9ee027163a8010bf901489c10ebb736ae619dd0177fcd060c4657488bc50044e4c895191351ca72aff9698577bda5536c3fa75f0d9b586822211cd88d686ca8921ca65bf8081f8604277839cc9757653a46511876f7b98983fc052bc088bc85a686ab6bfd5c2b91da8ae210313949191d13279be375d3d3197fb01808a76caa8a843e178d0dfc116c041030f2047f4b35c0900498fab680d45fd0710d75226eddec6388d56d1c2263768603ac0ba9b68a21173704bd25b6b5181405029cc4b18c6446b5afe5431f0a26bf50b2f33b0aa4032e9f28ac9fb58acd85a670f393351b33df4079a5533c44a94e968b677a68931491310cd48ea1213dd416ab650b3294f06f91aa5004f622ba173795136eedf91598153b8d2935acf33709a8b33e4b32384bab51fa69ed123a4eaac726dc7041b486e8aa3641fb8d48f908c27866753b821aaabb9894b504f845fbea8766e82671506ff5b5012765a6a7b08f9fd3c10357523fb423e02024577235fe4694349c1188b1aeff482ba7a15aa188a8bbe7108ccb7ad6a469054a45c01aac131c6a7c4acd5c050184ca77b8466b6d1992de80242454169a33382972760de2b69c3c000b900d25f2cf4731224dd9a2b84562c15c04d3d1a9ad447ee9404888141a7da3a522f90b9071ad7af54552d0060af1a66a31b9457024a46b3fc1038a7c54b76053909ab07eb36c1dfdf897276b465155aed0e70f9a4b9398e54d267377fc298b9bbc053b281486f8436017c6d98b3249c167b17358c134299ae17426bc9f067849d7c55541a205c1359a41d7a5fea37e758a0893c18226a44bdbd27e0266096dc20da357c5d1a23956b796b305c29e87718f65b8331888cbd53fc2fc011f92c6f49c7f9901a5b17059b81cb2eaca2d348a22a91105f69140d122bf59d74c16a840e4b646f5e1cbd921a24a60a0ed6cad243303a1448b6750b4e451c5e0e41b3a12a73c36272ed86537f1d2f51a0e2b5b5847b0a2d9bbff0a051bd5227600ad", + "sk" : "b066bd9303c7bb0c4a4a01812cf463cb338cdfe80953fb0c90d2aa7a2c1e110443d80ba64f6a435051083af14017f02886b63c8f0bceeb544b86e74e85a16db9539de52c76a624086031c0a9b84380d02ce49b0736e2277995a63c43a2ada9a60883024d50314d919c98e7a4f34c167c830c717693fb4a2f4ab1c684bba76365403d6b3b27f76a4d9570bbe73b09e32d45b6b89616bb014c5fa995779144107ff6ab3b523ee121c3cf601ca7ccb13c7783eb8702d34695c686298824884c46012c16c40576497314a0d60675fa0b1190e13a816c75543c9e54867f9fa495a4e43f0cc964ea4b19c3541930e33a63750105149484094d30a28c6eb73de702238e09272cd0415aa3b19007c90ce6407a864703d9a9f1fa3aaa762e66736f7f692a7344ae84a544b6b289c2d2187d61ae6ef70122d180cbbc09a4878cc6e4b71f1962627746a9d33c0b7c3a78048af6e811a34943fb01c5b2a248ab256c729a8ae2a1cac87870bc880bef16bbdd0724e25a0257c244c2a59737da52983cb5ec02b44fc0bdbd40c8882470285654c61bb27a9a9fd0162594343f31307cffbac216481cab73bb215b73fc96507bea727e5505e31848306c6647f7875d708fdb57c2f5a428c4d3b462122dba423251b5aeb94a2c034c025c0b39fab66b1c10b01441b9f5d9b736272718b44894820aee4c5dca164080b4774cd6af8e7c5218065a6d03917f215d2f6595dd13141c9505da959cc10bbeab184396c2b552db0c9c7a878a10a63ad920c19c9145c2cdb4556d823cb6d1e48458d72ad9886daca3bf7265b4fed2b11ae1a8b73a1ba62a3a298c339f01cf70d7118a094de950723a9b0e837a74ba18a92410228d0803dfe49e740ac2bd50bbab741743795e292616999033c7a18765648441ba9725bc1b6275484741a625a9ac0516980b903ff40c58c348940817a40bc02b0f7487fb0a09c3eb6bced56580f09edd262ec2c251a0fb303e33202d27b509b31ee87304131518b0e17ae34158ed1565caa77013a7161bf1cb6159841f8566a4a8a0c6823892ba94a541b18db1a68c9a3ad1755a1648bdbabbaeb8c8ba0a105eae48cfce175a2070693138cf6cb3c3b09c2285540e83b2b5cef51e634b5902aaac61d63b5e72069eb52a977a3e8b442f6106c13b1108eff9ce87d387640b3eb1914e0587298aa10cba2b09726ab542e2101cd6620564b1ed8945c60c674f2233236bb744307aa7db84ed11ce1d01ac0cc9b86f463c13197c7c1aa3f443cb0eeca93a817319bc45f9a587cc8a2ef05b0eb2998aecac2920387695e154831c96beb5568d880d4e480087499f0e818002a7a2db2b717aa39b2fd755c1c7678cacbd5af344ad38578a894b9d795fe65b701d3a6322f15e501610c6cc1e6fe90cd5048c93b80632fb6e18d70ecd44b36bec3ef955813d338f3af7331774962a04318556551b18930f91b3eab4464572b39f996d71e4aa3b7179b07b7717c1373194cbfebb4dce5caba80a7a7bb5aefd069db471ba0641383b0a006978b3bf5bb14348b507a624fb44c41d4c8156e2765069281e2836a7859bf3473b10f24c8d371148077014f1268824859a82bb548c25ade15cc60128a58ab4301032776b6f121675622857b8b376d708b2a861306fe931126822e2e8672fa0b577e8ca3f16495af10aae456a734368677a87fd3c2199060dc1993690c1ae2b76959664a1df6cb2b3738b294124918596b0d69394eb1efba83895d0a7f3081ef81769437cb63b726d4236a65c87c3929b79fe34438a8931cf2b889cf100747cb58d373491e7cb62db266bfb3b7e745500fa418eac8cabd966dc388d0f1b3fba850bfec8c03a29182deaa5ec4256fb3b436f429cac87399c61bc98497a3aca07cec06a128231f945a4a335ab6d1a54a9a59db106c0fd61360ce8870d1cae99201506c9c96d4969f4b487e4d87ba1d45accb5a754585f29db0991376150c65927b20c9eb421366cc840d528734c8b4f1421fe30c99f4c55f1e25d18a1b012424cc9f6250064a61c1b42ac243b6c701e293055a9ea7c44855e575cb6217c381de770cf461040c20b2cea6c2a921c9be483ecc2718dac01c4a5a15b60bfd5222fc988c60b23504919137b1226d7b72fe4105154711d25790a9f64c95356a787058018cba996410aa4f29a62b6cf77439b5784b67390b96db77c1583bab490719d804e79b8954b948388514a7fb78ebbe7959599ca374a66558a8fbe7aac91e8a62ac623690a952e94bb91e64fe57ab4db066867ecc9ee027163a8010bf901489c10ebb736ae619dd0177fcd060c4657488bc50044e4c895191351ca72aff9698577bda5536c3fa75f0d9b586822211cd88d686ca8921ca65bf8081f8604277839cc9757653a46511876f7b98983fc052bc088bc85a686ab6bfd5c2b91da8ae210313949191d13279be375d3d3197fb01808a76caa8a843e178d0dfc116c041030f2047f4b35c0900498fab680d45fd0710d75226eddec6388d56d1c2263768603ac0ba9b68a21173704bd25b6b5181405029cc4b18c6446b5afe5431f0a26bf50b2f33b0aa4032e9f28ac9fb58acd85a670f393351b33df4079a5533c44a94e968b677a68931491310cd48ea1213dd416ab650b3294f06f91aa5004f622ba173795136eedf91598153b8d2935acf33709a8b33e4b32384bab51fa69ed123a4eaac726dc7041b486e8aa3641fb8d48f908c27866753b821aaabb9894b504f845fbea8766e82671506ff5b5012765a6a7b08f9fd3c10357523fb423e02024577235fe4694349c1188b1aeff482ba7a15aa188a8bbe7108ccb7ad6a469054a45c01aac131c6a7c4acd5c050184ca77b8466b6d1992de80242454169a33382972760de2b69c3c000b900d25f2cf4731224dd9a2b84562c15c04d3d1a9ad447ee9404888141a7da3a522f90b9071ad7af54552d0060af1a66a31b9457024a46b3fc1038a7c54b76053909ab07eb36c1dfdf897276b465155aed0e70f9a4b9398e54d267377fc298b9bbc053b281486f8436017c6d98b3249c167b17358c134299ae17426bc9f067849d7c55541a205c1359a41d7a5fea37e758a0893c18226a44bdbd27e0266096dc20da357c5d1a23956b796b305c29e87718f65b8331888cbd53fc2fc011f92c6f49c7f9901a5b17059b81cb2eaca2d348a22a91105f69140d122bf59d74c16a840e4b646f5e1cbd921a24a60a0ed6cad243303a1448b6750b4e451c5e0e41b3a12a73c36272ed86537f1d2f51a0e2b5b5847b0a2d9bbff0a051bd5227600ad32a2a1197d78798bbeb13ce2e92cd7ed94b410adc37b1b31dc060af11fec8a8be99c0e7b82be89bc3c1eaee6680aa4efd394e40c2b3f30523c8117f7c26a8969" +}, +{ + "dz" : "28a96c71577ba00c94f99fe965bc595a26db2b3ca6ab5cf8e443cdd8462b17929c35d165453e5fcdc6f9df64526d9de698f2bd3e6bac6c7fdd86601b9ba5f4a5", + "pk" : "a6f3b26ca06ad98a9a6ff2122b8889bb513558fc1a8701376ceca1f7d87a53f78f953aaf9f977c2ffb4d04f88e33e0ba7d83bc6fd27914a769ae382ba5f211b2f59f0001ca30b0a0ef138adaa485953cb8b6f6ccb56a7c92598c0c83ae97684c26d70d69210c8dd16ae08c4b3c1c30110a581669245529be92d38d9cecb10f22c83d01b3b3660fab4662fc559f48041167fb3e7960328c612a7e99a0c546b63b1b04f22b78b85074e6d32f6e04b096eb89da611f30267bd8760e05c238ea2a587691181112a39c88c528977f0399cddb7a7c8bba3ba71507b3db7131302407052cc4e8125e2bc035172a967a21a0582a05f8aae28228ddca417545144882ca3d644f6167ba30e91368879efac5971c8b1a7a9674e804c08e506ade53bcd778c1af4637584b9752aa1f16a4319d296b93e5368c10863a85cbb55c11c56338285b21cd740695757adeb2ce48b7c658a36b26b670e59947a0d94d022284bf0995d56666bd7968bed8858895c779a3318275afe42488953791e97cbd6256c29a6c6e4339a15d7a7c3da95edd2a562dcc2f6fe077cbd2317a914b975692ad1c3c3d956b26634fe1d2235d66226ba766a447bc87e8674800cd898b4b02c491658b97e25a4f836ab98a99c669b60aa4c30518a6644fb048a4e34822782644038ab04a3815c61da99816eaf388e495cde4a65c12f1bb5f02a1a1b1cede817952625fd2502f2a4b8bbbd4123e71462ee433ac923583c830cc54129bac51f96846d8fcacece9b19f6063734158008342c6f48234d24571e5777074170ae24b20d125f1ba311f4b33cdf91e3a2305fbe12e44ab54cc8c4eaf8553f697c00e8040e858569120bcd0166bcfe1a66e2500c3ab8acf3b58f1309c68772154602ba6c0968553ca553252d27a0b05733d81486d86c590291a643edcca9f8470d573880d5856a6b2cbcff2803713790d17297ef11549d5412713a3e4206b1b7c85483192164209f5b32f709aacfc4bae51f180edeb7e999ace2bf98d958514951362b08a6b529a2a7669c5492c0a61645542bc1dea0b707282a0797291b8c7a510884f12e92f3200ac5ee91686e109ecf245b2672f94c0a4525b7f43fba328099bfe4330888b186d026231d2b2eab7b971ba7680f0cb4653652f8aa8b4e01bb77461d792cd5e941a31dc02d52622b37c498e4169bc0418e23c5d32999726462d3a0a6449918b18db487f422849b67cf047bfcb0c6945bb87cd779dea915b64aa0975d313f8a740de77b0d40612459c2eb73a3fc876ac39c821a52761e13115d87bcd17052fea2b98d9d83ece9b1de7124c9738c0df539045279eeb21042a13791feba9d0e23445293eb3c2c194b76c5febb5582220ca350eca9b90435372f3c5baa0549ff847aedb815c244b27dc5866b151041e884befbc7bccca2fa098b592c5aef7f53e0d712bd2119214c15f8ab848a1864705d0511c50a9942535cf06952b0357445a9854240c026733ac8a39eb3c8bca2939d195763a572353da2956799448570a21d58623635f7a7461a913c24ad04d1495c1ee42c88b82942012b2d4b410fd1907799623f1b373b9c438d2b4c3fc48c054bc5206273f7a9a3dccc0ad8d40070ef20fe4cc99c8394adf63126006ee8cbb821b12a2a0a3018c4f8e52a50183fff79e84c69427", + "sk" : "024755131769c7169f4b3a0b89f81f45e6a48cc2cb0eb87badd4ab94e9bc67e85ead80158c390dac09c40a6a8de8a95b21c5158a853442a908278a6ef80551a7c16a800242c7086144444e488bbec51c3cab83594bdc2457f0152c43a9577c51799ca7b03c9ce3cb4f5c6564792ab8201a3b8304ce4d8339a2171700d7a6ec1a03c337b639f7c804a50a6f41225c1143f9d8ac9698a3eb126b9da000bb2137489a165848865b487051b7665640b2e5e2b1b4633583589f30d4572306614df8080791040daa0106633a26237a244b6a18920d87653e8b516ea895a1f75bbfa912742bb540006a95ad20b95471cd4c282a64a36ab09a86b1f90f44d41753b0a8cca50d9780351f253a691824c785ad8be9790d48643bb4611792905e5b80d2717369e4786e5901c43366a14b3b423b11139349c9107fe3f55958fa8e4df6006b3607210b525304be6551ae57e826c913cba2503260a9493bbb3cc2319d791226c27a54233c48e7084ee9ea82376142bb419cfa6c0f51426cec39b554255f56b1cda42b4ac33391b08172f7a82574b6943f6a79ac51a5e6e254a0a5c80d46538c03705705abfb2b3ef63a756ab8ac03530aa6cccb005a05d73b687d45529edba35af03c411592f652c8f1131640b943629806cb21482f8913f436a06dc790b89b2f2a49245a51a26e107bd18624b51b406381cba1ab3e8879c401a30fc9f0c40beb557343735d0a44ba150d4cb404d752805085892b709f2a97abc413c81f7a1e14811745878d66e98f1fc176e4a3cabe60557e104d24733668985ef15b87e78b57d22c4464ebb4b9eb1b124b80c6328c3bb93349359777fb09a19c1f7de48274fca6d91bb51a97c49c66295bcc6c53933e1f327f2037c7bf9c80cdc5406fac0a9f067e7703a0aa79ac0eda8c14e4c7f6b05d7fa84ce9a487ab489227910d86b0b6a3a91e21eaa9493a986ea773af7c16cccb3b059aa724a02cf936a45730aa93ccbc2b3377014350cea39c36908f5167b08001061867c603f6ce64b081b2e46b1985837684b5e3318f4531c13f80277a35683cf599b373136ec3977afa12e1d32085330c0a6828a57c2902ab0ca679c2f7f9a844091b87a4754ffaaccff0c50abb01768927ae0b2eea885b54e92db59533ae6a6e9253c18c9184c1127220775da93c5964845240a7a3795b5df5d00baa34393d3009e641828c86173ccc1a9f9749a0f9271867b2d2a364ad7335edd1c02e131117a93b0f6113dbc9ac36924ee63cb954b60a325971501b3822732007629b00a965537c3fc07791af7a0c000446d15506c8404da9676a9907969d40627a18448f353735706015f05005403aa7a7b79ac7c5a3759b569b8b5d3b86bda01c4031a1f4e45cd663bad410123a973b2b6633da3c88ba0a26f0347901c6236ca76e1266440adb415fe5c7adbab8f5d8b3dd5bb4f88c3a1e450a4850629166102471294fd05696a54f516a0263e31a895010dc034ce6a72f6294a3cb6120d59c0e57827133a2b53f40b0d5f060e9480e77ea39e02a48f4327cb066bb32d2289bd97d10ec6615a6ce06088d6f63391952c89ae8bfebc43b554aa5e4b6a87cfa9e5b457c581a437422c48aa35df5c939694737a6f3b26ca06ad98a9a6ff2122b8889bb513558fc1a8701376ceca1f7d87a53f78f953aaf9f977c2ffb4d04f88e33e0ba7d83bc6fd27914a769ae382ba5f211b2f59f0001ca30b0a0ef138adaa485953cb8b6f6ccb56a7c92598c0c83ae97684c26d70d69210c8dd16ae08c4b3c1c30110a581669245529be92d38d9cecb10f22c83d01b3b3660fab4662fc559f48041167fb3e7960328c612a7e99a0c546b63b1b04f22b78b85074e6d32f6e04b096eb89da611f30267bd8760e05c238ea2a587691181112a39c88c528977f0399cddb7a7c8bba3ba71507b3db7131302407052cc4e8125e2bc035172a967a21a0582a05f8aae28228ddca417545144882ca3d644f6167ba30e91368879efac5971c8b1a7a9674e804c08e506ade53bcd778c1af4637584b9752aa1f16a4319d296b93e5368c10863a85cbb55c11c56338285b21cd740695757adeb2ce48b7c658a36b26b670e59947a0d94d022284bf0995d56666bd7968bed8858895c779a3318275afe42488953791e97cbd6256c29a6c6e4339a15d7a7c3da95edd2a562dcc2f6fe077cbd2317a914b975692ad1c3c3d956b26634fe1d2235d66226ba766a447bc87e8674800cd898b4b02c491658b97e25a4f836ab98a99c669b60aa4c30518a6644fb048a4e34822782644038ab04a3815c61da99816eaf388e495cde4a65c12f1bb5f02a1a1b1cede817952625fd2502f2a4b8bbbd4123e71462ee433ac923583c830cc54129bac51f96846d8fcacece9b19f6063734158008342c6f48234d24571e5777074170ae24b20d125f1ba311f4b33cdf91e3a2305fbe12e44ab54cc8c4eaf8553f697c00e8040e858569120bcd0166bcfe1a66e2500c3ab8acf3b58f1309c68772154602ba6c0968553ca553252d27a0b05733d81486d86c590291a643edcca9f8470d573880d5856a6b2cbcff2803713790d17297ef11549d5412713a3e4206b1b7c85483192164209f5b32f709aacfc4bae51f180edeb7e999ace2bf98d958514951362b08a6b529a2a7669c5492c0a61645542bc1dea0b707282a0797291b8c7a510884f12e92f3200ac5ee91686e109ecf245b2672f94c0a4525b7f43fba328099bfe4330888b186d026231d2b2eab7b971ba7680f0cb4653652f8aa8b4e01bb77461d792cd5e941a31dc02d52622b37c498e4169bc0418e23c5d32999726462d3a0a6449918b18db487f422849b67cf047bfcb0c6945bb87cd779dea915b64aa0975d313f8a740de77b0d40612459c2eb73a3fc876ac39c821a52761e13115d87bcd17052fea2b98d9d83ece9b1de7124c9738c0df539045279eeb21042a13791feba9d0e23445293eb3c2c194b76c5febb5582220ca350eca9b90435372f3c5baa0549ff847aedb815c244b27dc5866b151041e884befbc7bccca2fa098b592c5aef7f53e0d712bd2119214c15f8ab848a1864705d0511c50a9942535cf06952b0357445a9854240c026733ac8a39eb3c8bca2939d195763a572353da2956799448570a21d58623635f7a7461a913c24ad04d1495c1ee42c88b82942012b2d4b410fd1907799623f1b373b9c438d2b4c3fc48c054bc5206273f7a9a3dccc0ad8d40070ef20fe4cc99c8394adf63126006ee8cbb821b12a2a0a3018c4f8e52a50183fff79e84c694277cc3f47f319f88da508f841e536a056625f206fe499387d27307257682237f969c35d165453e5fcdc6f9df64526d9de698f2bd3e6bac6c7fdd86601b9ba5f4a5" +}, +{ + "dz" : "c08ba2ef8c3a0a043afad931652d7a19e6e8cb670f840de5f1fa03309b2ca9ec5fe6141a25f7ab9f875f79e0a82d6ea5cde5a017ab637d5fdb7c42646a1d71df", + "pk" : "190b29f6e7cc26755aabd20d4be75f2fa4c18303319edb00809152b33726b1e54c0f328c73c6805354925b43a6dbe0cadf00c9ce3b1d7fd9b47322c8b91844833250e0e99369e90c279ab48712b4e1c10c0456c754251cdae4cb4599843510be3a13277d775a3242a6232b1ca2979e6f260b3c4c86fc24bfd95255c765cdf6187854f0c9beb8cee6a8391f98475d6aa080a7a2c6147f70c2a9450901f705ab0ec23fc957619d611acc2319c6042e137496f51436a788334aa5a6d561a3e3a0937a37be9f7711c5fc6faa1024c434cc3e41a3865bc0beaa732c1789e7972f999007d4f7afdf953163197590e757a297919766428fd18ce1d531466a55109287c335bc26f946e06a4d51aa27b220001a46c2f4e339dd83511d135a9621c1ddf1083bcc9b24b994b4a3394df8ccfbcc743304383c300a9761859074a3d0e91cdd96a34513735a424238e71f42c328eedb1cdfb3ad704a1667c15045c534c448b429c474c494c7b37114911771d62c39d3f4763d881c0a21c074201301ea0eff13bb5df861ecd882a0350031b2af63572845950535e85fb323beebd613ba600702192d7cc1218309885ab9345ef32dfb757528229d73d57cc2328a5a86acc3180e392144c04cc45ca57573395ef38a95674b28ea7bc8684c8e6a81865a93256517be79fc456472976fea2538bb8b52a188cb43881c19ab47069b36968da1cacceab9bfc5c7985614a3fff7300e621e4865c5f8d30792099d3f793e58b591cdd87cfa36430aea876f30cca5d824fa29ab2b56ad3aca5d483c3c7ee90b4e028b7794592e1acae0fc721d355891c257cf821928104e1c994b8bc33eddf70c3cbcb5e272b43b5777b3921892ab198b4132ea4b200618b1e4559064d491487b1f0135c9da67a39950a5f13a1e6eb409c30957b04c645b052decc23a391a7692390de9085147c96c67f04ea8212c9d80cd00dc07b7d22826e01facca51dab91413e8cbaa24a66a00b4d2076d58c398ecf03ee56c40a1ac03cb02658e6240c41c6f06c174f3414e258a11478c7a76e05c156c1b164903b22991391955c3e75bcf0cc70d4cb79ea27638c54dcdcb1ef35b8f3caa26b0418f340597bed55d586981c77cc6093a889854a85132997bf706177099ee8b5ae44cc1f1f3c413fab7a51254490a6ac4175a99da866e5464283a74c5c300436ac1c7829c953128e5d17cb056af07b08d7f114e0be00f93854e09eb5e0be82a5a4c526030468f95bd82e08c2147736598a656476e5cb855e0c486d1fa0c661202a79b37357995ed445973959cf04116ed0c687227768a41a1b4f79b8080a740f012dd547403a30a36e62c9f5a1659abae73a165202122a330c61f492822ea25dcc22cb97c00a38bb7a4a493ae677cec267379c3a1b80ac2f4612221976ff4c7afc685283af88ef813a9beb73ef380be8a31c87135c6573c0d1d5807e63ca6f1418b947c1615233b911736b0870b766c9465cbb8b29573addb33f21a07cd890f1325c200545d5a21c5da1a0082b9c198158aa2b82cd5d94bf5718d39bac4d9096093c78a069b9210d305e9199d45ac09abe6a8033c971b2903874ac6408b3510d318ff4b464ef16ad3e56bd664cadab4cbc2eb1f13656c6547db33b5f529d253c85a728313bd36b9f09f6455b7594a10c1", + "sk" : "2b006f1c2787d3f704935762feb046f67a0a59163ed30c83b577caf4667605730b11364a383366a74125df3526fbabb7aa3916e9a05586920f9b130ab980b2a940109552047e231cfc7a9ce7987d3d218c52a11c22953722e861a1f000385aaee23378c6372315e73315893fe0f027a44caeb37cc796ca1954b79adb22887b41b3e9c98a4c5a7101714f4cb78c9d3886393567016536a0706fa1c950dfb71af86b91610509738b3f6c192368416b1213ae508439c8c9c4f5382f926c6df08852e8955a04d5a8a30912c201483096bd202ba4b82855236b804faa20eff056e288cb699237a1e5150d027347bbc06412c972c0a783a1b794e7b2a3b45b7f842ad18b5520a143f4635059690df45b1f99bbbb0f18ad5be48006727fccf41d400430973b8f62481b73d611dbd13df47633c1a27b387398dc32af9e71a40c84cb48f131d8a7acf8d91ee2513f3f225a2d61b752e24a2860148ca68c3a75243200547fc054710293b7c7a939752959e6256cb29c0f0535055b18e2f78ec4da0bf9aa91caeb9b5c5150ad42a867c18dff50b2a1e8c2d31951d5fab52aac7d603500d9fb4b5f516fd26bbc51a622751636d2c2ba24ca5c3aac696edb821b237e7fbc2414e7cf2388644ff702821ac1e2068c76d0717c40bfc47c7f96077504d5b9b2c7a187c0c746e904cde556bacb9cbeaaadc865ba93d4837b42192b539e6de749692916df131f26c26f4b3c93fdbb33cc8b39d176a4b27351911b8b85b5567b839cc6ab5f65a3502cd994c812b72a2037e5e38f08ea97291292fe51185a603f94fa6ff6e247b8e3cc82a8b111dccbfdd715d7458b3d984ef4a17ba7314ffa8a069031b28e9b858e22900d364bcd095079c4c06a515599443ff5f434be754bad6aabece45a1ecc7dc5c95541223bf114ce60d663a3621b95826747b7005e94b8a84025fc43b8dc320964d2a610b7ce10b7c7d56c37dd647fe1920b876267cfc0607a35700cc51a3187b69c488d34816753607bc22b59aef9c3be78a2b7959ba69212be46c9411a4c1357493a73a50930020fc732acb44c036602c22341d5039dd99cc53333091e983c1c1ac47607b5e47727d1d8a313ca73e1b9c47a63a257e1a5c01ba55b802274ba8c3a35c8427c9130c71d77165e00f2a723da6febe7a17d89cd6319718452be2a80777f1469ac36356e73ca7ef420ff64661161b3eb459b33c694a6399015716d8d7b3b0669648d2331edd6a9e54933a5447946465fc21b51c31328a6763829100d02c9407a8ba8bd150e540755e210102dec9fd9a06744ba9476d0b6252cbabf718c4a917fbeac293408531c46ce91402c91b10a3994883dd83fd0c97a952441fd6485c8c34f8116b1fd392f706150fa0867bd0078b0e32ac7828b6b61624677b55c18aaeb494794b1632e686338315c92028b3828598a4ac462646349f17abe582440e39ab346052219537e909e8e80135303bfe731ba04caaac6cb89b3c37558243d97881587f45de25b128f9568ac45b4e3f39ddb861ccb0749ec3541619b164163c77b7397da453f57377c49c2a8a78c568e300a635612b7c95035f4c71ca174e7653ad15601bfa46be017610240b045032453b51ade516f190b29f6e7cc26755aabd20d4be75f2fa4c18303319edb00809152b33726b1e54c0f328c73c6805354925b43a6dbe0cadf00c9ce3b1d7fd9b47322c8b91844833250e0e99369e90c279ab48712b4e1c10c0456c754251cdae4cb4599843510be3a13277d775a3242a6232b1ca2979e6f260b3c4c86fc24bfd95255c765cdf6187854f0c9beb8cee6a8391f98475d6aa080a7a2c6147f70c2a9450901f705ab0ec23fc957619d611acc2319c6042e137496f51436a788334aa5a6d561a3e3a0937a37be9f7711c5fc6faa1024c434cc3e41a3865bc0beaa732c1789e7972f999007d4f7afdf953163197590e757a297919766428fd18ce1d531466a55109287c335bc26f946e06a4d51aa27b220001a46c2f4e339dd83511d135a9621c1ddf1083bcc9b24b994b4a3394df8ccfbcc743304383c300a9761859074a3d0e91cdd96a34513735a424238e71f42c328eedb1cdfb3ad704a1667c15045c534c448b429c474c494c7b37114911771d62c39d3f4763d881c0a21c074201301ea0eff13bb5df861ecd882a0350031b2af63572845950535e85fb323beebd613ba600702192d7cc1218309885ab9345ef32dfb757528229d73d57cc2328a5a86acc3180e392144c04cc45ca57573395ef38a95674b28ea7bc8684c8e6a81865a93256517be79fc456472976fea2538bb8b52a188cb43881c19ab47069b36968da1cacceab9bfc5c7985614a3fff7300e621e4865c5f8d30792099d3f793e58b591cdd87cfa36430aea876f30cca5d824fa29ab2b56ad3aca5d483c3c7ee90b4e028b7794592e1acae0fc721d355891c257cf821928104e1c994b8bc33eddf70c3cbcb5e272b43b5777b3921892ab198b4132ea4b200618b1e4559064d491487b1f0135c9da67a39950a5f13a1e6eb409c30957b04c645b052decc23a391a7692390de9085147c96c67f04ea8212c9d80cd00dc07b7d22826e01facca51dab91413e8cbaa24a66a00b4d2076d58c398ecf03ee56c40a1ac03cb02658e6240c41c6f06c174f3414e258a11478c7a76e05c156c1b164903b22991391955c3e75bcf0cc70d4cb79ea27638c54dcdcb1ef35b8f3caa26b0418f340597bed55d586981c77cc6093a889854a85132997bf706177099ee8b5ae44cc1f1f3c413fab7a51254490a6ac4175a99da866e5464283a74c5c300436ac1c7829c953128e5d17cb056af07b08d7f114e0be00f93854e09eb5e0be82a5a4c526030468f95bd82e08c2147736598a656476e5cb855e0c486d1fa0c661202a79b37357995ed445973959cf04116ed0c687227768a41a1b4f79b8080a740f012dd547403a30a36e62c9f5a1659abae73a165202122a330c61f492822ea25dcc22cb97c00a38bb7a4a493ae677cec267379c3a1b80ac2f4612221976ff4c7afc685283af88ef813a9beb73ef380be8a31c87135c6573c0d1d5807e63ca6f1418b947c1615233b911736b0870b766c9465cbb8b29573addb33f21a07cd890f1325c200545d5a21c5da1a0082b9c198158aa2b82cd5d94bf5718d39bac4d9096093c78a069b9210d305e9199d45ac09abe6a8033c971b2903874ac6408b3510d318ff4b464ef16ad3e56bd664cadab4cbc2eb1f13656c6547db33b5f529d253c85a728313bd36b9f09f6455b7594a10c1beaeb6ff178f3228defdd117e6ba75a34abb70e86f31fdb16d74d91e6c1b47a75fe6141a25f7ab9f875f79e0a82d6ea5cde5a017ab637d5fdb7c42646a1d71df" +}, +{ + "dz" : "0e3b30e102d707538c2671060f603bb0b8a014103f132d63b09ece07e4a4c75b11eafeca9e810796c34e8cfce9d59342884456007b01ddd12edce6d10ed87e4c", + "pk" : "8dec41fe4093b014449985121e134c925b37b11612a9c61e97d5863f81a83f903383a517d1ab1769921563b86069c9c20841481be7a75311cb1b2c74f4cc96d2aa916509cc24d33ca7906aad07938e701177b42158c19ff3040389894f5d4c9cbd608c8234cefac9bf75fa177d5669f45a195f420b189bb340ebbba649996863618366766b7c990c6001a397b00b71272cb1734adb60a5b1523fb46be42752eba4bad8d6b008883e2697747ada77635174d5f7abc89157acc61202100cf719c9b8c5bfd7409fa95641202384629b925c240be94889bdf96bdc176e4dd3ad75f7b2e4c2abc9ea8280f07df64a162d016db3a634071944f6468e00aba03255430375660bd2c413a0b3cc530de305948d783afd0a41b4a202fcbbb620d9bd47b1181859b66f922d0b5c464f71ac5682829c8c6f4875bce8c37c5212113cf77a8cf480660b0ad108a0b67c063ed52bba442567ab31b30858cb33584d5422ed7427bf085d163005bf182c90c96cbc89ca70591dd0606f95dc6acfeb3315274f7c4937ae511963e90e6d03646292743a4178a6f344c244194f989e1c34be06a09bd5086c73992da8528caaba4fbef1502c1abb01b145a7a825a971a001055e2b1841725cb06eb23625bc0d99f89c1998023d760db1960a751988529628b6aa54308a3c895688047a003c089ef4a3232fda6aea0194154339b75a0a25402212211f3eeaba98cb656925c34f46037a436f89e01bfe408c138601e3a490675abf367194b377158f131b12740636b92bb5d184c05a23cea0c66519b2e8b094610655699976538471d77bbb3a8613a3ea1ee7b22642d63611b498e302540ca71e9b5c1aad6bbf309a13f9ab5eb57a5670fa9244280867ccc48130c74c50219da3168a26a52001713ee7b81157a6392199fdb4a56631b2d17890e6b0bb82051b9a1c85ce8aa92a2557ffa499c8910f7e98c3b4681ebe6323f4794e3e7324330a710b6a87186c36ff04602fccb97a7842104547264437921b413d52229a1555226a3bb3f090bd8cb09df92f4b4093319c434c04a773acc094bb205062903adc121ff6c178aa5d02f4b401e2b43bd79966d83a014bc8a8fa8347e1a9e8c6947134b837f019b05124279b26f20414fe326f3464929105974a853961a6b55ee90ba8d730be6a51fde90b4c23753bd9728077b90bf1c656c0738946bbbc5a2d72f95d876437c659b1bc663f6ab2b9026ba0401ac168c05933dc0509f7390ce8a024a3a1267217bae20c0d26c9d824182bf67ac60c0b121184a42c89da7a1f2de023ee6c291dea37da360b6f912eb95727e0c83efe0796d603b1c4702b2532af8d34053e1c70f8b73d5874578b3a2a8108b12e603d8cc1637d54bccba48f73d08f63c12fb8bb2e40938456c46209b262d8f08fc9b576d463329057a7fcc86652008832712e15e31eba79cb33a58262f822b9b8abbe8c4a025729dbac6f4df64f14c9959993004e0a4398b7c1e049120d404fc2683d65e85cd279b8d9e9595e995631f3469ca25412a54535c569d80c2a09117733f529bfe9a9dc766c8da35bdf0b64d1c27d0fe31ad736c06a92186034468539a3adbbcf0e67af4e797b63a0494cd91d2b9b89f8d486236b9b24772383d81aaed73286e5dc6e35a1dd0121b0a362d8c94022a515340f", + "sk" : "13276431f3634d420a374a0ecd8b81c035431dac244df1ab3405626490c7407599ccd4c146c5b79653bd845286aca5c7fc13a527784bc0b0b0171261409978a4754fb612203267804a524e81772ba34b99a20047f642363f928ae781c89a7374fbc0abb1373cb3485ee31a76da703a8d39c12668a6e0869e558612a481be9ab6ac8c00109f3a184f808b1be7566250cd36cb38b57771083c64cdea6fe5e9aa02f5cd1b6c08272078745424a7a11fece731fef736471674506b9bc56707dea19858860825a14fe820563cd70dba44b57932048bf50eb27b76d8405133172ea16a5b0fe77bca259cdd46414f13425616bdbc006ea23b21bedb23ea86a099dbc48b4746ad35830d694a218b0e233842566b9dcb18822f9301b8d7a6fc2a4555278828ab27bb74b1b3cbc19b343ea64904c35c67a1ba1ad4f9cd44a2b2887b4adad130ba263321469a4f50c6a6f06b29047a3e253a19e21f3c027c55091d7777aab2b955546b58bb212d87f9361154837460966a80881e967e379a1365aa96cad80613b2cb0a34979f6c1d00e7010fa2456807217abbb1df6849be50bef9a67c973bb14f8953e7597360c076d5290f0b1bca76f02d6a600dff97cf1df0ae59ac851c29a0f99b17759182002c8141d20166f8bf1979321c1a6234b608257b6bfeba7ef679b837d6a23673a122cb1e817b5fdfe9904b1a2f953906d7a585f074af3bd445a71b431f776008b133d6269caf16b306d444fd819b4d4783828266bdb13e0807409aebb11d867667522ea606a210f68d6288bc3a484cc4464706538712921e107885834b4ecdc44af3c866ee0504d191724e5704b8b20795b6520f0cc8f1d89ddc46572024294503735551330e887e6b71bb47e97aa498791b735733a8a81d962a68d32230f0c4403056b065b379a44ba61188c7f102511ac0d894b6457402fcaba82ff0c13da32ebe5785b44b937fc020ee1544b95228fb6447e862803c941705625e0758ab5d1c3e7d771780ecb188202b23972c9dca283beb4f3303064c922d8ec8081b9529edc163affc3f585274ab0143060527d2050b34842d15d1508afa2af069744d7620e02c2fac7954bea06a1ba04c28b0287bf71ccb809d7c966b9f94b05906b003b77a0730a787610340c600ce3b4f1ed9a4b5195355501b5720498ab185c75740f2184f5a16c18b7bb58bc120a030b5d20240d570545f349365a97bc387a6bbc2c001151adebc0375fba522b7994fa4a78ff6390507ccfb8b47e208b70bea1899512fb068a9db8b262235191f6403ca5b8517db25cb8b202085cf6fca6b6e55a75dfa7557a43116179ab5c1510f887db6a9c5e8ac41fd5010c11411d8f24529674a97fc666c565cb7469aa7c8ab943606880a9832dac41fba34f3aabcb1bb0050c66f4c5b53b6892a43ea98eff429f4f6206c06290cdb504029b29752cd75fa4df4a59c5919607616c074861f3c00c18f1ab27c190937fa9597c165d8d61281873bf1eb36bdaa9f95360e54f5b8b44542f618bc99077cf75c2fe4a04efc112eb2618fc3424ae296ba1ffb9a92726bf0bb7d74960868494bae529438c898ce0c95ae47415400aba6c47ca4b301a64b97777b7209039a2403758dec41fe4093b014449985121e134c925b37b11612a9c61e97d5863f81a83f903383a517d1ab1769921563b86069c9c20841481be7a75311cb1b2c74f4cc96d2aa916509cc24d33ca7906aad07938e701177b42158c19ff3040389894f5d4c9cbd608c8234cefac9bf75fa177d5669f45a195f420b189bb340ebbba649996863618366766b7c990c6001a397b00b71272cb1734adb60a5b1523fb46be42752eba4bad8d6b008883e2697747ada77635174d5f7abc89157acc61202100cf719c9b8c5bfd7409fa95641202384629b925c240be94889bdf96bdc176e4dd3ad75f7b2e4c2abc9ea8280f07df64a162d016db3a634071944f6468e00aba03255430375660bd2c413a0b3cc530de305948d783afd0a41b4a202fcbbb620d9bd47b1181859b66f922d0b5c464f71ac5682829c8c6f4875bce8c37c5212113cf77a8cf480660b0ad108a0b67c063ed52bba442567ab31b30858cb33584d5422ed7427bf085d163005bf182c90c96cbc89ca70591dd0606f95dc6acfeb3315274f7c4937ae511963e90e6d03646292743a4178a6f344c244194f989e1c34be06a09bd5086c73992da8528caaba4fbef1502c1abb01b145a7a825a971a001055e2b1841725cb06eb23625bc0d99f89c1998023d760db1960a751988529628b6aa54308a3c895688047a003c089ef4a3232fda6aea0194154339b75a0a25402212211f3eeaba98cb656925c34f46037a436f89e01bfe408c138601e3a490675abf367194b377158f131b12740636b92bb5d184c05a23cea0c66519b2e8b094610655699976538471d77bbb3a8613a3ea1ee7b22642d63611b498e302540ca71e9b5c1aad6bbf309a13f9ab5eb57a5670fa9244280867ccc48130c74c50219da3168a26a52001713ee7b81157a6392199fdb4a56631b2d17890e6b0bb82051b9a1c85ce8aa92a2557ffa499c8910f7e98c3b4681ebe6323f4794e3e7324330a710b6a87186c36ff04602fccb97a7842104547264437921b413d52229a1555226a3bb3f090bd8cb09df92f4b4093319c434c04a773acc094bb205062903adc121ff6c178aa5d02f4b401e2b43bd79966d83a014bc8a8fa8347e1a9e8c6947134b837f019b05124279b26f20414fe326f3464929105974a853961a6b55ee90ba8d730be6a51fde90b4c23753bd9728077b90bf1c656c0738946bbbc5a2d72f95d876437c659b1bc663f6ab2b9026ba0401ac168c05933dc0509f7390ce8a024a3a1267217bae20c0d26c9d824182bf67ac60c0b121184a42c89da7a1f2de023ee6c291dea37da360b6f912eb95727e0c83efe0796d603b1c4702b2532af8d34053e1c70f8b73d5874578b3a2a8108b12e603d8cc1637d54bccba48f73d08f63c12fb8bb2e40938456c46209b262d8f08fc9b576d463329057a7fcc86652008832712e15e31eba79cb33a58262f822b9b8abbe8c4a025729dbac6f4df64f14c9959993004e0a4398b7c1e049120d404fc2683d65e85cd279b8d9e9595e995631f3469ca25412a54535c569d80c2a09117733f529bfe9a9dc766c8da35bdf0b64d1c27d0fe31ad736c06a92186034468539a3adbbcf0e67af4e797b63a0494cd91d2b9b89f8d486236b9b24772383d81aaed73286e5dc6e35a1dd0121b0a362d8c94022a515340fb2b71b8aaccf14842a6d4ecb713612f801a5044147fb9e6987ad3863759de31e11eafeca9e810796c34e8cfce9d59342884456007b01ddd12edce6d10ed87e4c" +}, +{ + "dz" : "2478f7d3de6041e7e5cd11c5e2ef483d1aa6218eb126444091535f6ae532fa7311136e2681df2ef881b51a092a9badbe72c9772c169808521c47149578621e28", + "pk" : "86335a761609caf862810ba70e00c83da3cc1c208cd893233c8ac3247b013417cecd467e9cb87280aa13b061bd0a661034ebabe9ab6e7a447c2826af3cba6798270a36f7431ae9119de2245704110d159aa438a6f1546a39286a7a179c5f286073d5b944ea2000ab61fcb9373a4a94dba5c9baa94056f35ca1810106f2ce65b579c4744f94955db4730265053b812634eb5156ea819069f6371040408a2036019967f4163c1ea611c02ba295a51581644dab07872d1a5b21a32d0ffa349e3739d961a9e9bc07b6d8cba3b945be491958813600e781ecf54912d70e37832e05784c5e12271a5aa5d628233062305a28493bc2b180d802423aa4f75cb6610c16e8798cec72253798b189eb217238b5d063224f78114715818ac4ab40d34042860bee445fa9b1b02dd5a7c7b6bd8b03768e7c38282806e5fc7a93a9094246a403111a39bbb89ca4ca33f9b381fc8d6447450d3b4f6c794b565b2735f8014fe35e78a94780bc1557bb380db47d25791b1283094ce08ae4ea9961882d134bc5579aa9fb44127e2670b85001d58a162e38680d3c8fd2d3517cd4b36aba9bf1930f3d4c067f2a5b4dd702cb9b9e138bbfa91c0f49a86ba283091350a2ab3c1f3c75ca20a4a160318cf88849ef2102e47211df95a2fa325573f60ee7ec5e70d3b88d291cf9110b9906401968462d2ace979a825b088f7c2b330fbb5f15b1b9f24b84a646cc6a9b27b03767978268cba750b5429823e7ad3a00a4e813052011bb0f47cbac838a489c568391c7d05457f4033814bb9d52a011ce787f0df2ab1bc885e293bf23900f3fa019238b7447561eb85b296930232b175379f289982312790bb65743cfe65017be280063c19b033c19eb988d5a827b64777eb8b13244a9b6763c63523a6af78672b652ac38f33f2a870c494b1dd34a9af239556ed9412a48a7b3501daaaaa976daa971c1565f37be80c33fd3126c7bb3aa09f47f4c9c503e2677325418ecd2058fc7518fc247b36c0c8f59427bd2311ca493510794cdb734cdf69c6b1a9d5c990424d819f35ccc8750b4750c43394605bb60b7c4dc39d8f71dfdf1c6da319f6d671aa170065102086665707b95ca4d241c26cb4acbe928d23318d372aead3a99bbd075b5186abe6590cf5278bf289050c13789f82476620472baaf258c78eeb7755f6c6b1a113d91da945a837f0c84b353f9aa1c223404a3c071a27c84a6ae90d31a0d254234a18656095bf989456cd9aec6a837df6880c9ba79476431929c9b22d9bac09acdd8d94b7a884e261037f1bb5335f98c4c491fece5ae0a485611a50224809d48aac84c16957221924d3c2d6500107e71bab5580339b0832e0292b89a3f25bb40fa0445f2b3122f97856f739aabd568d1b0851b47ac947b25d2da6910d05b44e26088901d487cbdf2f782c2e35193021501b2cd264a6526b4aa6dd439502601fd7b203b088361e6218c1b72854648f4023199e5aaecd51a33990b74e4366c07818efcad158a56ed623f63c20e5ea3c519350cfe16b0dfd3af10a45755641a388590eb95b6e5158ac5bc4aabe686140b981cc5c2ac896945a4be089201b56744c439630b56a15b4a3591acc88f3c4680311c24d80b5725bba86cdd22a3732c6a1bf7cb10f14d57ee8e5901e46b97e63848efdc76368b797d", + "sk" : "e5a906286950db6187780184cc302f14a9ad2f7a382d93403308b8676c20cccb52347a515303a2bd15336c0b711b3a31e8d0cbdb59bf42633823ac1df61c63633171282b537cd1a19a80160d97b9dba7322d935577031c081a035890be315b7a4275979691b612b764111ba6ac57afa50c29ee436af02131442c5704b585c663935ab698dfbbc882d23fb39c75370b8c199cb0da26be27e8aa6391b5fc30bdf077490bc677d6e631af504b9af2ccf7939536d819455b91ab172cf01639fbd47618b8708f460284abcfe6d21371dc3b00e579aff432c9417d33511d9a0170baa0a3695004edb18599118146d83ea548ccb0069a3379430dcc8e3d728eaea7433ed4a704987624d0994d454374f9218b2a08ec20b2b216482a1c820e8c5ce99413dd590bb042c9d294ad98408c407b88cf6b32bfe9b95f9a9d45a33184cc8b79cbbfb379639c9b44a128c211e700a59aa4ee034e1a3375dd216ec3e2447757c70a0b4ecb6b1677755c327914cc38b425925f9f910f4f618cfd425e5f55c4955b14b08c64f976068daa8e711a3d00ed0e47e222f201891f6c7c52f282a4d471cc199e68fb9bb8bc81766a457a6ababe254c4aa96546b96f56375e68c9a713072c5ca9b0d0d36b1f1b663613075e62071f97c6c2ab44e98a76dc767fe1c0789ef155bcc976cf1b879f1a151606b996225abf147e7cccb615243e0d0775e339c909e93477b9b66fb863e726a4f231cbb98435368abed797a00db8b4dea236e75673ad8b857206d03c50b0767961f67ba0b58a668a02680f57372cc8c175c6cac858497eabbb840a5d87389c7a623fa5707353438e7a4388a1c34236294370343f90c9b38f4ac28d187bbab21c3d656c4eda62dd8127771c8038b67c80d58edcf81f526344c48b29f73a5197b0b51fc29d19396b8b7295bf524d38371c71013263c95694138a27fb56670101b0f06f6b568b4c05c486043f53c44f321a9bd8827312e5537608b5a2d7123971081e8bb7a05ab1336a2b7eb487359bc8287c42add6b72e5635e9ea9455552eaee4c92812ac32e254a90669cf6728af07763fa3ba74ec0e1c8090f2706378bca30fa69c85e50a03e8326ea4917b6515fb887d3601c83c5b4f520804cd401d0c67cf229299cee141da094a5f117403f94465c62761ea05ed1016759c60b14c352b41c8ea619e5bcb167a851ef8842845abb4f7a6ad75fb610408324ea84c665b36672b5e58f985c3a45bb3f926f5c82d16d519303271ac83368d28b2dba2083350b6205c718e2bb4aa1518fcc3c76a9b02d678732b4bcb8dd4cd9c2526fa919ad5c9bca0c6171c1a7547772c957b74dcf877b1f62921c7a17a7a8382b81f44f2a6cf559b761bb58fe8031539c02bb3222332513921411c894819a2ae856b65c1c3b113b09a6ab06ad6033bd79227aeb397d90ab3cf5985bab7c826931184642ae25755f79667aee64918575118349ac0b19963549c17f71ee14944f98b5eed708b2aea5a305458f699505083bf54ec70b80ca1287715ac2046edea5ed722ab14fb8514e67e45343db7c91324357a99db343c735c918464b532aa2d9649d33a1cb38039b176bdf69470f1a1839562b94b3b7294a77c72cc5686335a761609caf862810ba70e00c83da3cc1c208cd893233c8ac3247b013417cecd467e9cb87280aa13b061bd0a661034ebabe9ab6e7a447c2826af3cba6798270a36f7431ae9119de2245704110d159aa438a6f1546a39286a7a179c5f286073d5b944ea2000ab61fcb9373a4a94dba5c9baa94056f35ca1810106f2ce65b579c4744f94955db4730265053b812634eb5156ea819069f6371040408a2036019967f4163c1ea611c02ba295a51581644dab07872d1a5b21a32d0ffa349e3739d961a9e9bc07b6d8cba3b945be491958813600e781ecf54912d70e37832e05784c5e12271a5aa5d628233062305a28493bc2b180d802423aa4f75cb6610c16e8798cec72253798b189eb217238b5d063224f78114715818ac4ab40d34042860bee445fa9b1b02dd5a7c7b6bd8b03768e7c38282806e5fc7a93a9094246a403111a39bbb89ca4ca33f9b381fc8d6447450d3b4f6c794b565b2735f8014fe35e78a94780bc1557bb380db47d25791b1283094ce08ae4ea9961882d134bc5579aa9fb44127e2670b85001d58a162e38680d3c8fd2d3517cd4b36aba9bf1930f3d4c067f2a5b4dd702cb9b9e138bbfa91c0f49a86ba283091350a2ab3c1f3c75ca20a4a160318cf88849ef2102e47211df95a2fa325573f60ee7ec5e70d3b88d291cf9110b9906401968462d2ace979a825b088f7c2b330fbb5f15b1b9f24b84a646cc6a9b27b03767978268cba750b5429823e7ad3a00a4e813052011bb0f47cbac838a489c568391c7d05457f4033814bb9d52a011ce787f0df2ab1bc885e293bf23900f3fa019238b7447561eb85b296930232b175379f289982312790bb65743cfe65017be280063c19b033c19eb988d5a827b64777eb8b13244a9b6763c63523a6af78672b652ac38f33f2a870c494b1dd34a9af239556ed9412a48a7b3501daaaaa976daa971c1565f37be80c33fd3126c7bb3aa09f47f4c9c503e2677325418ecd2058fc7518fc247b36c0c8f59427bd2311ca493510794cdb734cdf69c6b1a9d5c990424d819f35ccc8750b4750c43394605bb60b7c4dc39d8f71dfdf1c6da319f6d671aa170065102086665707b95ca4d241c26cb4acbe928d23318d372aead3a99bbd075b5186abe6590cf5278bf289050c13789f82476620472baaf258c78eeb7755f6c6b1a113d91da945a837f0c84b353f9aa1c223404a3c071a27c84a6ae90d31a0d254234a18656095bf989456cd9aec6a837df6880c9ba79476431929c9b22d9bac09acdd8d94b7a884e261037f1bb5335f98c4c491fece5ae0a485611a50224809d48aac84c16957221924d3c2d6500107e71bab5580339b0832e0292b89a3f25bb40fa0445f2b3122f97856f739aabd568d1b0851b47ac947b25d2da6910d05b44e26088901d487cbdf2f782c2e35193021501b2cd264a6526b4aa6dd439502601fd7b203b088361e6218c1b72854648f4023199e5aaecd51a33990b74e4366c07818efcad158a56ed623f63c20e5ea3c519350cfe16b0dfd3af10a45755641a388590eb95b6e5158ac5bc4aabe686140b981cc5c2ac896945a4be089201b56744c439630b56a15b4a3591acc88f3c4680311c24d80b5725bba86cdd22a3732c6a1bf7cb10f14d57ee8e5901e46b97e63848efdc76368b797da13cb3f23ccbd9ca6a75823d1ba14ef03664560f397133935103ded2d7480b9911136e2681df2ef881b51a092a9badbe72c9772c169808521c47149578621e28" +}, +{ + "dz" : "9d405d3ebdaf35fa8722de431b669722acaaea2fd10b814310b17f78b66147d16ceb14f7662be0c42779459f69a145c0e2ce9f0bd9a0cd1bf32ed5694cc9ae32", + "pk" : "a4b21fef3306a34117e05c4f4736af0e8cc5ae6bc3f294188ae5397ef69f26303f9592a694e12916bb56e5aa43cef5c183e6ce00f78ef423c3a838ad2cd3c4f68c142eb23dd5f774054668eff212b2bbaf8274c7ad10cfcec5b10bb603ec6ab33c963ad2a22b23f7412f93715a3b0be0b1754ef383c2d52a5a16a22632c88a9635af81909d347e64715806f93e0aa26756b25a8f5984f8e298abc12be53850b83213960428562455d6a7bceef90355318b5bc78734864d1af0bf1393849ad715c711a5226065586b80f1357d961a9ba74999c8f47c7583675245749bc56152f1428910324f2706c8718208c4a13158360365337642279f5009ea86197109b78f0a037cc298f3085c46f68aab45379cf59cd504a9461b47268ba03fc7cf7b1aaf9d461bfb3a7e68b396419a44bd56462e7aa2bd82223a09c155d26dff3873a6052472d6796e24bb7daa3583711cc435a9b3d3463812734b700614396a6dac3c2d838ac103d04239c847241835768a2bcc3d6f8567f6c998b4e7ca8d30a81582686f211936087d3db54972615d4a9b0e1ab1765a18c753fb9513d097322154ea4a3f934c8fff8520af32ab05f26d1030888c0a1613ca74164793b5f798ee3c589684bfb115cd6740bdd5141f1a17393b191550192feeb3c8d2c0b4c37790091312fab615c6d194f076c49d01cb97190ed9d4a6bfe0957047933e2835353085ef611c6f9c1f86dc4366c45cbe2281b0910ae39aacb271c03260648f7c955e99367d1b130c85289d586272fa28807ccd909185dbd5999af47f79da95ccc4859e8a84b2983f0e9693b1dcb506d7b7aaf03f158759b8006511380b3aa4b46cd060f96c0e16060161698f26e073c2f74e9c5b31f9fb4df5dc0f3b0773470bbfb95135c39199f6f281280480ae88573284c44ab9b91f8942ad423783263927c5857d5832a6e1576c6a59e7b1a498ac2f5f71c51b4c9a36cc4d28c042dea588a4756740782b07cc245a069d42245943977780f11eac0c8221f9938fb05a5d096401d2a4bea8c9f46564af831c907c4fef6743ee482339212bea730113a930c0a5649951abba2c6a3afcc4738580c61a4730aac4dc3c84dea158365cc6c760b13ea10b194b2539a55da5f01ef6c55213815fc6479f1bbb67d5754161d4064ed1247aac8edc486a8ca1b311fc653da3be4fac0c81ac0fa54b99030ac2f824598ecc699a31973ffb34648183cce8cfe6495723975c7ed7cbc5281811462cc1ac48fd9c5ca3da126b8125179b651a95b7749bcf711a018eaa951cc078aff16bde9a2f5b180ebee3032b5b2826ec83af147af8288470b267a97c5ab0244d3fe538e986000de3807132937a811de5228bfdba209e642fa3095045266e11f46e99f1b1eae584dcb8805d7455d3435956cb1679b8afe26ccfa7224736998aed363c0d82b1d23b339a16abb5e60dd447bd78c80e6657bffef9bceb18a0c8e602936ba32d24871d6470c338921366a009fbade8f4ab940bbd22158ac5201f09157d0c010825b290581b4108573e720acaf53344fb876db0bbba53d14a26dab409f137535a794294814e2b3f8f42c09f323e072b2519588342448e24a769af363293f4c8786ba4b70330bb80f37de30dba857dace4b8291ecb2f6ebd5a06323b11a89242da833741e9c4", + "sk" : "2556bbc99ca8edb774f8b427981046c94cc902f20c2c9b1eed7555f800aeae621cd247555b383508a8a601720695b5469f21627e0aa9c7185557718de0a16b920454a642152c779be09307dcd0aa6fd97909e7227ecb7db209aacadb7d1bf5ae03cb2d14517861b2be3e0936b47b7cdd488e22956b7de9ca14b52e848c90fad497f6d1bdb42c799d8a9b51f0c9a3e3835181a2d3ccbbd95785e1e3930b410f955a311fa69ae39b9a240c50c221c61d687853658c611717eafc14f8a27f8cd190ffd433d9d863c530425da8072e467893c7b621260490f1497f4470b43507161b23729a5db94585a9d9c83a9554127ac9b7252ab4e100d346cbd7a496501979cd0b5317ea39adf970a490aa9f2b7e4ea8122900c1c882a0cb0162f9256cde1126df07bc4a30042c6587ce0b3102673e405b623416c06f9abd9bc62eb70cb794844a6a428ce8736ba9364882aac621d304b98799aea35287e023290335da841a51e4c1b2063f1198661a0c01315b2602712b47d16b5f2b19baf2a67fb13333dcbec5d9557ba4a2f103097f14be6c276f2a195a57b9b28b312c6967a3334851b075a7c3d2ac74d5897470286aeb4b29982b002d5751528c3ffb488ec4661bd58b275c229bacc62d85b8b8c560a02850ee24aca565ca30168721a182936ca8a6508226d64840903038c339c603233a9046733c0e15e016f6f080414734903bad3393c5671c5edee3cd8db0cc8aaa4927c78d51ab2309b1b053d700280a0bda9a5d268ac47d746ebfe01e6be91264fc6a180c1051a5a87038bce12a4d70930ba259cbf49039c0397845301f307922c763be3bf83fe34147e319082990a45102a1d328a0e90a8e56670577c14ad53426ce36b863e501062a5634034b98da407659b9e8f3a539907d511ace034ca15a91bc8ed3715be3c095b60b8332b6c068663d61781378c9f6d352adf794bab90ffdf330dfc77e492b6ca5bc53de21a81ac93db6b520cf3ab8b4837729f101b992c7057030271b4a7c6a7c61f399a2302155306ed3d8a0336c8081206f6dc09cd8b11bbeb89165321660a217d9f0bc770b2023832deb6492e961184827a2bffa27c13ac42844b3fbc14b0b96946427912432196e95ba949b29265b58fee38b93232afbaabfb1482f2307bda7a3004cf74fafba6c464840ced7bcd38aa764d67bf20a88e9a99549fb66ef1a53d1ec60ed744632c7875299b056c8c9375c6ef4f147ab9c8b1240822afcb68f028d4dc2be9da530c14a552acbac77d914c561c25284a9a4dcca04637048f29a99cab95117881da8404596cd0a28004a47a77f8623b4a2811ac6b90e5069d7dc82c829abc4b14ffe251507bc970f702341e382d9524672f88f33e16814977225659c8c321a0810a523d44190a7947a9b2eeba262fbb16a0ab35100385c238c55601363cc5996fcb46454c142c25046eb507d4f6287630babcf485bc5f19fd99051f12a3e683a7d89b21c2e903136b674bc0b1490d91548394738c417614077897ba9ba577f8ac9b584090d32973b4261c05385788be4b63783728d59cd5539413cdb537826aef3d304e8102c6a3b2e72e4185292c35ab60da55acbe3c6417e179c80f0024ef5113a2c42a4b21fef3306a34117e05c4f4736af0e8cc5ae6bc3f294188ae5397ef69f26303f9592a694e12916bb56e5aa43cef5c183e6ce00f78ef423c3a838ad2cd3c4f68c142eb23dd5f774054668eff212b2bbaf8274c7ad10cfcec5b10bb603ec6ab33c963ad2a22b23f7412f93715a3b0be0b1754ef383c2d52a5a16a22632c88a9635af81909d347e64715806f93e0aa26756b25a8f5984f8e298abc12be53850b83213960428562455d6a7bceef90355318b5bc78734864d1af0bf1393849ad715c711a5226065586b80f1357d961a9ba74999c8f47c7583675245749bc56152f1428910324f2706c8718208c4a13158360365337642279f5009ea86197109b78f0a037cc298f3085c46f68aab45379cf59cd504a9461b47268ba03fc7cf7b1aaf9d461bfb3a7e68b396419a44bd56462e7aa2bd82223a09c155d26dff3873a6052472d6796e24bb7daa3583711cc435a9b3d3463812734b700614396a6dac3c2d838ac103d04239c847241835768a2bcc3d6f8567f6c998b4e7ca8d30a81582686f211936087d3db54972615d4a9b0e1ab1765a18c753fb9513d097322154ea4a3f934c8fff8520af32ab05f26d1030888c0a1613ca74164793b5f798ee3c589684bfb115cd6740bdd5141f1a17393b191550192feeb3c8d2c0b4c37790091312fab615c6d194f076c49d01cb97190ed9d4a6bfe0957047933e2835353085ef611c6f9c1f86dc4366c45cbe2281b0910ae39aacb271c03260648f7c955e99367d1b130c85289d586272fa28807ccd909185dbd5999af47f79da95ccc4859e8a84b2983f0e9693b1dcb506d7b7aaf03f158759b8006511380b3aa4b46cd060f96c0e16060161698f26e073c2f74e9c5b31f9fb4df5dc0f3b0773470bbfb95135c39199f6f281280480ae88573284c44ab9b91f8942ad423783263927c5857d5832a6e1576c6a59e7b1a498ac2f5f71c51b4c9a36cc4d28c042dea588a4756740782b07cc245a069d42245943977780f11eac0c8221f9938fb05a5d096401d2a4bea8c9f46564af831c907c4fef6743ee482339212bea730113a930c0a5649951abba2c6a3afcc4738580c61a4730aac4dc3c84dea158365cc6c760b13ea10b194b2539a55da5f01ef6c55213815fc6479f1bbb67d5754161d4064ed1247aac8edc486a8ca1b311fc653da3be4fac0c81ac0fa54b99030ac2f824598ecc699a31973ffb34648183cce8cfe6495723975c7ed7cbc5281811462cc1ac48fd9c5ca3da126b8125179b651a95b7749bcf711a018eaa951cc078aff16bde9a2f5b180ebee3032b5b2826ec83af147af8288470b267a97c5ab0244d3fe538e986000de3807132937a811de5228bfdba209e642fa3095045266e11f46e99f1b1eae584dcb8805d7455d3435956cb1679b8afe26ccfa7224736998aed363c0d82b1d23b339a16abb5e60dd447bd78c80e6657bffef9bceb18a0c8e602936ba32d24871d6470c338921366a009fbade8f4ab940bbd22158ac5201f09157d0c010825b290581b4108573e720acaf53344fb876db0bbba53d14a26dab409f137535a794294814e2b3f8f42c09f323e072b2519588342448e24a769af363293f4c8786ba4b70330bb80f37de30dba857dace4b8291ecb2f6ebd5a06323b11a89242da833741e9c468302cc5af214ceda67ff8161b29bc300c4be8e1a4139437aead8a9ede3cd4ca6ceb14f7662be0c42779459f69a145c0e2ce9f0bd9a0cd1bf32ed5694cc9ae32" +}, +{ + "dz" : "9a86490f0615f3edf789cb0654066e9ee339cc59f968281f3b89213f83c692edfaeb2ef44d2f608621e831187ce79b2d2f4a20f1568bbe76b0d3d5af36111714", + "pk" : "2e248784527ec73160954a18dab4986fd146767bac1506885a7abbaf203fa7923cf3644b146a7687dc0f56329e3c64b052db6c14e3211cc560d9a70a1ba641224b2eb8e70e44b25b4b346f3037454aa69744d1777498c98ce741ac1008461868839b4149135b41817d135060acecca5af744e982142de574ecac5f1432a7d907628eb75439d8af02d37e5181681f1b249bcb22d52961d20458c860ceb3175730acb9b8c8500dc258fec13677f40506bc76f8eb31cc91a605e905ee839c3e0b771c32595a3238acc079fe6034769652e5cb492da0a3e8c0cdf13c899cd5838bb46a27e343bc62ccb6294c1619af96817d77ebc2e1431f997566485327cb9331a262153cd31c80d939d473b81feb0910e027b02c29cfd66fbed3cd09c11fa08744b9e0b62dc3093c2552bc7a770a0550cd601b2e6559851bbb5d8665865555ae510c2df9637c07790639c0af6b4bdbd567b704c267e6abf2b371f580686a1910bcc02b7ec3c08a7aca3fd121cda343a61c6c995742159cce5503b4996a7a6fab9e8dd5713bf62f3c0792628ab621741034208ca01c6130d3a3499a186fd69db4b3cb77417a12992e8e448fb75b73f4ca54fda42b2df2a4f9e14c39424bd1592b90968434eb8f52a6a1438cb7e589740c8b9b2b6123600b28ee954cf0d18dab1bb3fec8a0ff6379a4313325c7011f4c7fead33c8fb543c3c90b6ab35e01e31e2dd4262bcc92ba11ba055295b3f2a273620576813232876d1e9b18e22639e9c3759eb460390bcced9bb0e368c6cad846767c69349c59fde27405d8ccc900ac2ed762b1ab6381eac33f14aa27c047e5a63921030f8ee7055df00f7cd353bdc1487fc0875746b9deaca76fbc70ef5925ebbb994833a7eed732235b06e6ec6b28217c7d9a86a5396c80d43c22c56c19570238c70e7a7c2b6a77bca45785ccc31d8a880be379b05e45a1b9a8b3b2520826f888a8a025e28abcc4320bd1e30fdd17cbb3018a7a784534379c46639a21227d279b61da608bdf9bb9304b322f103a6a762db152548f192534a94df0ba1b2c97b9af8202dfc646a84270400cbeca95aada593d8f4719abb6cd4a4699787b92d63279fe9bacc0a989a59cb0ad279a567b8ca9536e8107aa7b81b2bf7730b9f4a470c8170655a0842602bc4610f9e7bbdc6acfbdc4732e4266083c9c91d41ed1f2422822acd01bab34c4789a63a700a5a135d65495841e69ca2f5334cbb1fc4c7d42b0f53bb63f888146163a51759c43349377ca824b32091e9b9c30e025981b82cd23aeb5385be7f398aa5025e87b605827328ebb32d6682896298f652243ebb3b8a6f759db824d3f577cfb8aa04627a80a03804039478abc2a627779d1c87fb23453ca254fb51c629f17c1edc8cd8c71aafa135051320f81c65b06711282ec6e7e4b021eeac0c3fc7ceb4b192897899f6c145f53bfa2d68a5b583002667d101a9c7e721f0da0711ca79df954126d9199fd6351be89225cc52d6be5c906860f6ac81c56477cd34c94ee43b920eb6cb62bcf27e5669f9160f0eb2ce7389b8da47cf8b22f46452961457dc39c54fde66a41f95cee1ba87682ca6342ab76f6bc262632282a22293ba7be9cc567700b5c13ac19f126b16a43bae7e4af067d280590ff759d4c3a502ab563080dbfe1df14ac06d254fc", + "sk" : "76c9ab126b3d022c31745279f6e684083a496be39aee74bb599a8b6de9940a26535a2600d3ca572edbcc37d721b7614824a123b4c6c8a01a0568b8ab61045c3339ad02e68f16d16c17ac572f9ba77d279d38636c9134c501b7c00518bd0e3293fa3a1612d16488c7bcc4cca7fcb5595191cf0d43c2974c0d8551a72d252896a8baa7740c419a1270e6b7145b053ff828344b30d5c18be9f2c633799970c44bc49c2c485921b96ba685ac1bd9a914bfa026a35bc1eec70b8562c9d825a4c7d5a60470c61244c88681af5804b587141dbf72bcbf7604a0705d655b00b89b9045c0a291a355ce68a07f79847a181401c028590788b7a2c3d95b84f13993da06556a240b16887b78e43c310928459312f196bb04a7bee1e0969d72264db1ba0fdbb54ed8c49c3bccdc44a9d4605db677002a0cc84402968cc7759743bf2ab97f0a4a67d95b93a5c7c51ff91201676394e69acc8aa6c88c17535cabb8dc07acdb239b848a8bd88ed0430e3381a6a92b9ddf04955dd06e01717f9036920ddcb33e017fa3103cdcb955b3958347a162f0db95a3b2377c4c6027353266a91876f698ee53787dd73bb9978c7984713deb0017fa1df2b10feef4c7ae5734ecd7ce2b043793b1a19655950799243eb493eac103fe0a174d67b728b7097dec31bf1188813b16c1129a27669fc557c0dea7bdef1303ad98b81e8665ffb009fe5440478267ab2310a34c3f11c88ef8fa5736b91cb2972d1ba772aed1b9fef64af7e547bee627fd9232cec559d4ccb36e8702379231ee5a604cdbaa53db415e0588958321709cce82748fdbc257535584d8d89dbd7cc2d857ce3ab498c31b74fa305d8b145184a906b89a28a82b071d8bc4c52623c306766a150606b63021919759c76102503c03478dcdd7cddf71042173c91c70682ae684fb488f6378678ad114d8e6c625087741e868f1176cd09721e9812d7bf5c63e21974201d0f2844959c898581994ab664ff6784601268b4589c20b4c9873e49f03856debcc266764339329b327e375406a54a0b4c89439116fab279d6b2b9ad0a09ada94a1d572ade29dff802813699026732c30167480cc2230283801bb2baf3cb3cdf88e18f79852a13269c328a555955dc04733e48582f0768f40168f468c83060d0f1bc735ba197cdbba40dc50cd38c53c2a3481b763935b1071879d77967598b2aa8aa1ad34863a6db84dca6628907723f9891a4434339dbcc19213bec2463c5b37b82bc40821f5a33cc391cba73e3c7aa397c71b6f835c29d70c226628fad2ad7014345098a55502a6bc75003b449786b9534ac31e8b6871c7c98be6ca03a974a0936c4598438bfc953b691771c93b83b87579ddb6bc6f5721e2490fa9e0b36bb26c7607bd4bdc003ac9c2b0f41b7b9b5fbe9432b9d7c164d938b43698271a991d4a234fd1bbb28b07b5b5206fb75b4ee75bb3a28539462c01cbceb619b3e2814e5efc79ecda14462b46782308a5e61c2696b71cf367fa421cafd1c0af5bc6b6a7bf07d3b504c05c57f184700572a777bb0c32c7b82212d6c783d9696e96f11a9af791857526be109141793c7b92823f4b116196b8695c0b00a46d521b49241452331a4edf2a56e0264505c0682e248784527ec73160954a18dab4986fd146767bac1506885a7abbaf203fa7923cf3644b146a7687dc0f56329e3c64b052db6c14e3211cc560d9a70a1ba641224b2eb8e70e44b25b4b346f3037454aa69744d1777498c98ce741ac1008461868839b4149135b41817d135060acecca5af744e982142de574ecac5f1432a7d907628eb75439d8af02d37e5181681f1b249bcb22d52961d20458c860ceb3175730acb9b8c8500dc258fec13677f40506bc76f8eb31cc91a605e905ee839c3e0b771c32595a3238acc079fe6034769652e5cb492da0a3e8c0cdf13c899cd5838bb46a27e343bc62ccb6294c1619af96817d77ebc2e1431f997566485327cb9331a262153cd31c80d939d473b81feb0910e027b02c29cfd66fbed3cd09c11fa08744b9e0b62dc3093c2552bc7a770a0550cd601b2e6559851bbb5d8665865555ae510c2df9637c07790639c0af6b4bdbd567b704c267e6abf2b371f580686a1910bcc02b7ec3c08a7aca3fd121cda343a61c6c995742159cce5503b4996a7a6fab9e8dd5713bf62f3c0792628ab621741034208ca01c6130d3a3499a186fd69db4b3cb77417a12992e8e448fb75b73f4ca54fda42b2df2a4f9e14c39424bd1592b90968434eb8f52a6a1438cb7e589740c8b9b2b6123600b28ee954cf0d18dab1bb3fec8a0ff6379a4313325c7011f4c7fead33c8fb543c3c90b6ab35e01e31e2dd4262bcc92ba11ba055295b3f2a273620576813232876d1e9b18e22639e9c3759eb460390bcced9bb0e368c6cad846767c69349c59fde27405d8ccc900ac2ed762b1ab6381eac33f14aa27c047e5a63921030f8ee7055df00f7cd353bdc1487fc0875746b9deaca76fbc70ef5925ebbb994833a7eed732235b06e6ec6b28217c7d9a86a5396c80d43c22c56c19570238c70e7a7c2b6a77bca45785ccc31d8a880be379b05e45a1b9a8b3b2520826f888a8a025e28abcc4320bd1e30fdd17cbb3018a7a784534379c46639a21227d279b61da608bdf9bb9304b322f103a6a762db152548f192534a94df0ba1b2c97b9af8202dfc646a84270400cbeca95aada593d8f4719abb6cd4a4699787b92d63279fe9bacc0a989a59cb0ad279a567b8ca9536e8107aa7b81b2bf7730b9f4a470c8170655a0842602bc4610f9e7bbdc6acfbdc4732e4266083c9c91d41ed1f2422822acd01bab34c4789a63a700a5a135d65495841e69ca2f5334cbb1fc4c7d42b0f53bb63f888146163a51759c43349377ca824b32091e9b9c30e025981b82cd23aeb5385be7f398aa5025e87b605827328ebb32d6682896298f652243ebb3b8a6f759db824d3f577cfb8aa04627a80a03804039478abc2a627779d1c87fb23453ca254fb51c629f17c1edc8cd8c71aafa135051320f81c65b06711282ec6e7e4b021eeac0c3fc7ceb4b192897899f6c145f53bfa2d68a5b583002667d101a9c7e721f0da0711ca79df954126d9199fd6351be89225cc52d6be5c906860f6ac81c56477cd34c94ee43b920eb6cb62bcf27e5669f9160f0eb2ce7389b8da47cf8b22f46452961457dc39c54fde66a41f95cee1ba87682ca6342ab76f6bc262632282a22293ba7be9cc567700b5c13ac19f126b16a43bae7e4af067d280590ff759d4c3a502ab563080dbfe1df14ac06d254fc149ca4d94813f81c792060502e09a88ea694c5de863ce6a50516cacb1c3f44bcfaeb2ef44d2f608621e831187ce79b2d2f4a20f1568bbe76b0d3d5af36111714" +}, +{ + "dz" : "6dfd9b575872560c7bdc2732c4a28dac4db04e535eb8e402c3dffd145c09ce47a2985c1c4d203778597947d710dec806e36b0cd949fe460ef141213bfc525e5b", + "pk" : "0055afab2b0f8c4481d2316c876607a02b744637928897c26c1c5762524f42a00b27d4ab7c198334a13750b8bee321cf5021cbe4536246a0879890ce6f042de3955e373c113d7c2e2df360a8fb5c76fa7f1f594b64b562d0c3b524756b2f94667de31f9a67aefeca35d6641d17d167d6d955d6bcc1709297c9277cf614423b212e96281f6100074d2c2209f976df6332285b3c412a8f618c5b5175302952366a5c67462b07fb74cecc5726ca861e47d4c599819d26329568c139ecd31b22ccac2901d0bd347ba5f10a51b69dbbbca90b574405d8c0600617e682bf81472018284a70982773434d07286b319ca4e3fa6b24b25171093cefa559aa33ad3a0336a1a18205a07ec4463511d3be9ce0b05944819b9647ffd94337c94b7831694ba31cbf8c7af238c21dc1060799c09bb8aae0a084cab07c3bb8502275398e05058b142794309e3bb287fa32a016f46e9feb9115f09a313970293b25e7d25c4abb623c1959d6246d7e00ba79068ea03963d9598fb2b04879c3379397b086960c0d896e419ca5f7667264e1907102329474867cf43a426b1e117826ca542cce64adcbe154f36637de2cbdbdd6c1ad7794a0c18fa339993e873ea54c3f92a68afe0445305bc97b76c61b3bc693e30b2a2b18a6cc28add35cdcf601554b17df39998516549b823ae1596d2a88acb9433433926af62263deb704a561b2f2397381228fc5b15bd93c3911db634b19cd7217508e328113d565b475393d95c7abe5a94fd6c1cc1283587b97db55109a08b1ae1060cecbb15675a253ea154ee19aa9ec29ec33400e4946b89b5b1b4ccd41362a3cc75808408f50ca8662b236f1830656a432e2193bc4f09ad1fc6a82252174a6530b3b078808c8798c9e110820c295797580a74572adb025cc31c75017468cae17c697a79df023aa250c827c11a1491944b9d6156d24b1f0f53c12a1aaa5946bda21485cd18aac0034de843489b7cae9ea90197cc471444067d01f873175693224c5368e3f3220ae48832c0928e65195510b5d4eba93dd3b217b79481aebc34f2123ce42c0aba83ece60034ecbc0ec4420de32851a998207f770f3e2bf94b047779b6187e083f7e04458c243d9125dd1641ec413ccf0a02811ab65d7d954bf4cc0cae00c384889d1b23405419180ec83d9ccc170e0bd6bca3e2682bf3471024445329a515456175ef6c167da459da6f3439dab20fb28bfb9764d5d9b9af055b442399361e91f84965fbcb31a4db147cf5cbd37b955fa3b0a34b78f8f4b2cf584c1f3646b5d7887a99b3847ba9010a69c89f52653c2c4fd2a6cbcec2d00392a1aa44ddad605d8e1595d2ba305cbc86b24a47725810a761c45c6cd0177262b2c85beabc07f5086ea31bd443889ae657c9528abb2769edc8cc74bc80943f92e88402ec231823e15112ff5624c982be7669010e31ac9494334488105eb88658339db648f30b3a08b7a7b5bd1113a83055f673a8fd6ca10cb4ce3c32645fc42ed24420b222d512c68651a0b99875ef8e913b984c709221228e51bd2c2407cd49a06e83f7f12c15d33b0252937f857beaf9ba79045cba8264d7706270d4787f6ecb8922582b7321c26da7813eb1c61a80038289cc84a923e03d7ae3cb232d5e0c1e7715d7b305d86d34fe89069774bf4339a1249be49b1", + "sk" : "672a64b0079b3b7c18878338aee97b73d9ad10231709a4547941c0c5c1a6297367bce3b5d68b929f611c5ba26f39b199ca2a82bec9ad6318be48d75f9ec7cae3eb4d1732b8eb9a742216723b4bacea934113054af3cc752201859ddc1a990680fb573efc845a85dcab5c352dc701a45e5804a819644037bd095615e7389c2bbc49cb9bcf192b072b539d93fb993bb73f5f3b1549b13e5f90c8aa82991384b310bca58183116fa964dc1cc15c933dd9604ba6cb83c694132c628ac0901c5fdc45c808c2d06947008515ca95c77b486b1db3406665b0201498f721588335c55d2366eb7867ab2a8debc248df0caa3e637643455f7ce625f9f0b43c8787fad449f9214f78551f9556272f7a7040687eb185521a1a576f201373c61840b346d91b94ffca34df0045cfa4b5364432c7e2344a837d3c09c21ca23a957038d8eb30dc91cd9b25837155663b923b6f6766a4555475b04d74f350cb2640cc07cce818609033a8730b0e7c234d9b8b4f7d77cdc095c11e0c8ef16b3eb63c06f72514b57501dcf04ddc162096b99e6b1036ee0118975932041a5d5ef118e62b0429d4117d89b72924afd97770fcacaf9bf92824b9ada2674dd4ac40dc8471ace7102d13058a740246010a685b9814216a295538dec1a9289473aeab46c6e3cdff4335dec9055c5baa481918bcfb0a63cb7e62123e19f1939c1030ee95709dea6844fb978410989ae9b2666984e38062a1d066fb91b362120c7f3bb5488628376b1c827b50fb11b3e4a630c52a32d5a40e671ba0e99269ef09bf1eab049ca04ecfbbc213b74ac06aa790a85757a9be1c852199e7ca0ada5e07e7ccf352b3f3307631e30c604bba95d8aedbc44d12f73e7f51b4b8537e5db967d2738e3a13a33149c00ed24560753f34b85b85c535ce644b15e046b104b23b3c51562c47dbc92f2b44ad0f1890f98044ff3092498416996886c55cbe1812aecc6aa3d08a4f89c62708495eccf13c02a6b2b202732888297b3aca8861bba2e1cad6e7658686ce07da3580232b5b75c61ae1ae72a344293855f47a3aad11c4b716c211128091065a07439a40abaf2d62c674d40a6b1468b61ac2e22acccf25c0783b5cdfc60a47131f0bc6133c55b92e246b9c722ef680bc0ca12c7dc1c46128863507781937b9e02b5355d2b8399c31b6a80ec1137e5fe9ae01d980e0ca647a7b3678006c678147529a32df269dcc378416b14d61b240c4742247bc1b77eb905c6889fa022910a974f262733ee14b75b302e5148063e5ccf3984d073410bcd9096c38aa99c14dcf69aaa3fb32282352fb4a315b736774558753d7a1615c9fd5d30904e1186162a2dacc96003841934a40dd604983979838fb5382fa6dee1a4cdf3063326503ed665fe3ea84953b522872c36e7888864a0e55f3466bf20db1263cc0fa91660561c6f3171f45c2bd5652c95359e0150988f58ab5f69232008b62114195f570a3dc9c916073373540538a56e22b4dba234eb315bc15b3c89ab64a9962282e3c20baa7aa540c8273b83a39815131d24e3643353e5a4df3e986abea49bcb2b96be28a6c4998ce24278652c59f0c5e6c39a52a7269bc769dc6e3b75bd34e7be7c4f86a93506b0510310c0055afab2b0f8c4481d2316c876607a02b744637928897c26c1c5762524f42a00b27d4ab7c198334a13750b8bee321cf5021cbe4536246a0879890ce6f042de3955e373c113d7c2e2df360a8fb5c76fa7f1f594b64b562d0c3b524756b2f94667de31f9a67aefeca35d6641d17d167d6d955d6bcc1709297c9277cf614423b212e96281f6100074d2c2209f976df6332285b3c412a8f618c5b5175302952366a5c67462b07fb74cecc5726ca861e47d4c599819d26329568c139ecd31b22ccac2901d0bd347ba5f10a51b69dbbbca90b574405d8c0600617e682bf81472018284a70982773434d07286b319ca4e3fa6b24b25171093cefa559aa33ad3a0336a1a18205a07ec4463511d3be9ce0b05944819b9647ffd94337c94b7831694ba31cbf8c7af238c21dc1060799c09bb8aae0a084cab07c3bb8502275398e05058b142794309e3bb287fa32a016f46e9feb9115f09a313970293b25e7d25c4abb623c1959d6246d7e00ba79068ea03963d9598fb2b04879c3379397b086960c0d896e419ca5f7667264e1907102329474867cf43a426b1e117826ca542cce64adcbe154f36637de2cbdbdd6c1ad7794a0c18fa339993e873ea54c3f92a68afe0445305bc97b76c61b3bc693e30b2a2b18a6cc28add35cdcf601554b17df39998516549b823ae1596d2a88acb9433433926af62263deb704a561b2f2397381228fc5b15bd93c3911db634b19cd7217508e328113d565b475393d95c7abe5a94fd6c1cc1283587b97db55109a08b1ae1060cecbb15675a253ea154ee19aa9ec29ec33400e4946b89b5b1b4ccd41362a3cc75808408f50ca8662b236f1830656a432e2193bc4f09ad1fc6a82252174a6530b3b078808c8798c9e110820c295797580a74572adb025cc31c75017468cae17c697a79df023aa250c827c11a1491944b9d6156d24b1f0f53c12a1aaa5946bda21485cd18aac0034de843489b7cae9ea90197cc471444067d01f873175693224c5368e3f3220ae48832c0928e65195510b5d4eba93dd3b217b79481aebc34f2123ce42c0aba83ece60034ecbc0ec4420de32851a998207f770f3e2bf94b047779b6187e083f7e04458c243d9125dd1641ec413ccf0a02811ab65d7d954bf4cc0cae00c384889d1b23405419180ec83d9ccc170e0bd6bca3e2682bf3471024445329a515456175ef6c167da459da6f3439dab20fb28bfb9764d5d9b9af055b442399361e91f84965fbcb31a4db147cf5cbd37b955fa3b0a34b78f8f4b2cf584c1f3646b5d7887a99b3847ba9010a69c89f52653c2c4fd2a6cbcec2d00392a1aa44ddad605d8e1595d2ba305cbc86b24a47725810a761c45c6cd0177262b2c85beabc07f5086ea31bd443889ae657c9528abb2769edc8cc74bc80943f92e88402ec231823e15112ff5624c982be7669010e31ac9494334488105eb88658339db648f30b3a08b7a7b5bd1113a83055f673a8fd6ca10cb4ce3c32645fc42ed24420b222d512c68651a0b99875ef8e913b984c709221228e51bd2c2407cd49a06e83f7f12c15d33b0252937f857beaf9ba79045cba8264d7706270d4787f6ecb8922582b7321c26da7813eb1c61a80038289cc84a923e03d7ae3cb232d5e0c1e7715d7b305d86d34fe89069774bf4339a1249be49b1e5c52e639e5acd0fb97c7eb44df56df5250c6de7d171c467ce6887eaa4ee3d61a2985c1c4d203778597947d710dec806e36b0cd949fe460ef141213bfc525e5b" +}, +{ + "dz" : "6fca9f4e384d8418075cc064c70730801bdb8249899d456a77130d5beeb3662cce7683f8a03d3cf04e46970ff7d6a12494ae12558346dfc8fd9370bf944a0102", + "pk" : "c1cc248a969a9deb8ba9c43e80799f3e287b4263bda1a1055d152be8c84a4df5447b43295d0ba65d2a9b2d15a3b139507a3c2a44965e68e7caa4d9aeb4f67ced404305c81782ca49656775e10aa531f01c66793e198092e2b538df264818e7afdc94ab3cda837164cbaeec93fe2b8b59397482f084af51976bb6161c026761a22dd5a26457c648ed0817ff0a45fbc8c7e0e6c45767b7a720997ca60453785b73a43522979d06b365481a54e8124e9f4274950315faa27f5f8c50699164414398d72321a9d5c2181338de5187baa2c0c5097bfbc72945b15406eb1e88caa3ff92886a6a4fe2c8794700211ac32e1968643ae5a6c3aa309433cab3e48aa93a560fd18550f19831f6c74e811b8be5771244954da635a2fb6c314b9d77f1bf26fab613872d0a2098dff0b060516feea45293e28c0ed088bbfc0165a1906473063e97c5b2825100116793fb1dfc9447fe3227d96bc5e999cdf1f545c8753e4ab43d211c80ba9646e86651d928b0c9e64f5c2ca80b99914d878641a53a6a385acaab6d9b5690d11a8ef5a08c35e80c5df91463c76366282543b08c0bc3054ce07c32fc10ae021bdafcb744c20dd131c8d4146f1fbb282250941d8a1cdae68b4c5961a7a437b3251f144586aec15f505aa79305797a16cdf4c89209b02bdaaa0c0d367e2dc7097a9900bac5cf7063c3b2027ab05b204fbc997f333122798670e3488cf4bc64089a15a97f0c0a4ab5680fb9d5a9a815234e158316f31948b80ca33523e2303838d55ea2368b037a607b643ee8b2488ee456273158a3675b56967ce7b4a1bd2c22a91083e474ab9121cfa0f2bd1a24b27aa317c34b968df055deb839ef172ffd0489bc524109aa9897383f9cf0226810b56bc75b699187bbe86d465c7a44b65aa828c40ce76de88cbd6671093ca1689506657cdb6b3cc5a9a0293d16057e700a3bb7623e3ce1c8815b1d17066853b1cd807c0803f9a9fc2b62f637c99535a1733159ff79a863ba9203d57c80f0bbe02052e41004cd42388fdc695d9722bb0147c55510cfb9347127002fa9038f42551fe1656f1c4ba91c47e5fbcc5e83013864209290cf7d901213a26e1fa79aa7576c7c4103cfa01ec6e1459c9aacc449af7d10aca0a4171b284d4473c9af9a84546b03c7d5cea7bc723dc5032157b58431ba9a895d35f89274e827470babba0342567648ba84a51aa5a604b4c36a27c0b2710b2388b53085603cf62d9ea0a6a6864971323ed9e934d7471e65a4915ada5dd1e7482a37517cfa6255782ebc7b789c4a6d2aa746a811c0be90079f138dfcc812adac7c4bd862ddb83cf0d6b74b623b523318bc807163e6c98d777c7ed0628266bd53a29636b601e162466cfb700ed35b0966a7daf32e7dd67aa1c08e7cca8f18fcb7bd3104bb5408637c08eaca654b19523ac0a031b76968d71d9c013501a1350742467970c2813762c1b4219dc904202984cb49b33e91328b0350ad36b4a7650f7505b11b5c6f0520cccf788b87b5aef42b44b567c42555c74f40ce66cc9003730928e859c77099d8149c78588fdf0c347eeb6752b39b755122e715843ed2a859c02a81e7705127a52d53047f973952321d34d4278739c4bab50a5c344011cb196dba2bc5197accd11b3f6e5d57b37115e763177a6910c9866c85ed61c6", + "sk" : "0bccbf3cf040d5b87d74815458749aace6c82dc66a6a7672e534a60474b566c4060ec61e23f5aa640245fb2817185b0b4de26ead3744f0373f4172a6095821bb873f34b94733e60dddb312a1ec916dc0c10aca85b65a9407547c133b1cc32205c7362f3e458bbc507ece9c7b13176f877336a7348b4d785c3de0641d000268a37929c254c826bb643117e36a3b28120eb67104d8ea4509536bb0d54d1d11720a31b4e20b14aa57a81f45b3133525d5a49eb1c59e9cb36774421149f734b3b7778e4b3a2ed20e5cd8a56636c100f7a704f5691d0383140a633ffbcbdc5324ff329f46e5afb27070eee32c5008637708a248593ec00884a87231b7c457d969ad8bb44841d5c76a35ab1fc3031e704cff9045f80b3a2b925af1714ff78b25e798218d163b17e154634c1141a39bf9d35aa7cc9bd2a56032032caf8a6c61319d524acdb42b1ffdfa0b6d70673de99972b21e046737b11850dfe62e30c40d2d7c212354ab529477c9345aaf8a0e840b7ba236c7a3ba508dc995e6dc4a80b77b6ce1c26f8ac42304c91c215698829137e446e49414fd91cf7b9034f5301a81cb4d3251a47c64979ea133ea16012b2c48fea9ae3eaa71f53272af878d356447c9fcb163c938225a53119b3cb914bf9b9b8bb40a2b99a6c4b6ab5055288639802df6810a9f28607ff0537b92a640ec4a2f222075ab917dd2bd49fb1debd6435257ac656687ff75bc70f7b62722664da57882fa1b336819d8367466e936a62724ddf9c6cf439d44282645d5b13d84754799ab7170bb13faacea545ec2e52394851c21c01aaa5b31f72247600a25eb05d00443b3b85c3c176450ced12a8f583716a93ec1cb9d8e03436f383a3af0322cca926dfb45554045fa903a5ae8be04bbcaf858a84ec35793aa9d03d3882ad873289a337e37aaad72b912882ad657bdccf82e65ca3e554ac1e16a44d609c62dc71356ac04536b7ed72ab0ffcc9981031f7ec68f7fa6c761d219a8a78fe7d527f82ba81592c89513b47bd41470e7110aca8b85b9042bf9b4f2e29221164bb21a0eaa30a624a285c15c92ffe3630f19c35f02b9b54bc0c2b958c1c088491b990018bb66996bfe868a55f9c000a72264a649e535bc5e5cc86b1079f556947a80a6352c6bae64a97ef3a1bb1b2886fc5e0d284f81534cc3c1a6403b8c2842cc5909bb642343fbbaaa17fa255723055f7644366c7f4744c01427b9d9d1935afcb732ebc6f2f6cfb8a6c492482e7f046b32a232c3d74472ca7cf64490f0f68f4da0b1d81650384a1288f374a2a9c0153805a2709da5d5154f79cfae9a564166c601d75d7fd3a434269497e41ad316adc65cb152148327f86134d085b2b809ce96b16f6c38e4b107a2fa3cf11b0dae7b37c4285f3f9a10e0009fc8cc1459cba60e38222648bd76a8c770282ff5c57b74f393a8d01c0ec05b4169bbf487769de35e4890382b376c030aa67b28a2a3aa4d8cc8ac6d96254dc7911ec48076247dc2db021880975a49b3995854c22b89f3b1b1d4993c43456bb647c8f83ca66d613bf3eb3b7da4a252a0a7e2e61bf82c20efb11a83d1b9d1e087520991636728318602d4f8c5b918763be1c1b1479035b2a52f4a194042a006b483c1cc248a969a9deb8ba9c43e80799f3e287b4263bda1a1055d152be8c84a4df5447b43295d0ba65d2a9b2d15a3b139507a3c2a44965e68e7caa4d9aeb4f67ced404305c81782ca49656775e10aa531f01c66793e198092e2b538df264818e7afdc94ab3cda837164cbaeec93fe2b8b59397482f084af51976bb6161c026761a22dd5a26457c648ed0817ff0a45fbc8c7e0e6c45767b7a720997ca60453785b73a43522979d06b365481a54e8124e9f4274950315faa27f5f8c50699164414398d72321a9d5c2181338de5187baa2c0c5097bfbc72945b15406eb1e88caa3ff92886a6a4fe2c8794700211ac32e1968643ae5a6c3aa309433cab3e48aa93a560fd18550f19831f6c74e811b8be5771244954da635a2fb6c314b9d77f1bf26fab613872d0a2098dff0b060516feea45293e28c0ed088bbfc0165a1906473063e97c5b2825100116793fb1dfc9447fe3227d96bc5e999cdf1f545c8753e4ab43d211c80ba9646e86651d928b0c9e64f5c2ca80b99914d878641a53a6a385acaab6d9b5690d11a8ef5a08c35e80c5df91463c76366282543b08c0bc3054ce07c32fc10ae021bdafcb744c20dd131c8d4146f1fbb282250941d8a1cdae68b4c5961a7a437b3251f144586aec15f505aa79305797a16cdf4c89209b02bdaaa0c0d367e2dc7097a9900bac5cf7063c3b2027ab05b204fbc997f333122798670e3488cf4bc64089a15a97f0c0a4ab5680fb9d5a9a815234e158316f31948b80ca33523e2303838d55ea2368b037a607b643ee8b2488ee456273158a3675b56967ce7b4a1bd2c22a91083e474ab9121cfa0f2bd1a24b27aa317c34b968df055deb839ef172ffd0489bc524109aa9897383f9cf0226810b56bc75b699187bbe86d465c7a44b65aa828c40ce76de88cbd6671093ca1689506657cdb6b3cc5a9a0293d16057e700a3bb7623e3ce1c8815b1d17066853b1cd807c0803f9a9fc2b62f637c99535a1733159ff79a863ba9203d57c80f0bbe02052e41004cd42388fdc695d9722bb0147c55510cfb9347127002fa9038f42551fe1656f1c4ba91c47e5fbcc5e83013864209290cf7d901213a26e1fa79aa7576c7c4103cfa01ec6e1459c9aacc449af7d10aca0a4171b284d4473c9af9a84546b03c7d5cea7bc723dc5032157b58431ba9a895d35f89274e827470babba0342567648ba84a51aa5a604b4c36a27c0b2710b2388b53085603cf62d9ea0a6a6864971323ed9e934d7471e65a4915ada5dd1e7482a37517cfa6255782ebc7b789c4a6d2aa746a811c0be90079f138dfcc812adac7c4bd862ddb83cf0d6b74b623b523318bc807163e6c98d777c7ed0628266bd53a29636b601e162466cfb700ed35b0966a7daf32e7dd67aa1c08e7cca8f18fcb7bd3104bb5408637c08eaca654b19523ac0a031b76968d71d9c013501a1350742467970c2813762c1b4219dc904202984cb49b33e91328b0350ad36b4a7650f7505b11b5c6f0520cccf788b87b5aef42b44b567c42555c74f40ce66cc9003730928e859c77099d8149c78588fdf0c347eeb6752b39b755122e715843ed2a859c02a81e7705127a52d53047f973952321d34d4278739c4bab50a5c344011cb196dba2bc5197accd11b3f6e5d57b37115e763177a6910c9866c85ed61c69a350302631bd506be010a3f42112ae4ea731d515d80c3a21fcce60cc4d945abce7683f8a03d3cf04e46970ff7d6a12494ae12558346dfc8fd9370bf944a0102" +}, +{ + "dz" : "e58f71bf175c0550a67e00e0f7b3b7fc36bc2707bf0c93044a492626de36301a7f7054814869cf7625e45647bc1547aff288dbb90699b2ad84893f3b755d9722", + "pk" : "33e4a6bf137a2d5c4408040972bbb41342a6f2f97c6bf7b5a05a92ef1c69a3e602f5062b4d651b9af148ebe566059454ae71919226742ac151fec6623bd5531699282cd0651a1bb436d113202aae301a6de6c132dd020cf0235944d0a041f6ad92e404f87432bf3a28035c4f6e236ca6e6b56d924800667f8816839549535f1325ceeb5b0e194b89a5800819215737a40988a43336ceaa914800278944ba54edc65071b63374fb041f07a66d5781ee8492d35221c53495248365cc438b4a65a745a64585242878997853597ce1f45371cb1f97f8638837bee3cab372c024ebe4aa52455283cc2249d82739ea481d685204a61840c856617a210fa431a31b27532b5b0868c2dd0a1e2947aef0575934905ec50c33193c8cbf15c5bb4a89b39c63337b3f4bb3b61b0581fe2362037bcab4c62ee14ac3d8a70486789a6d9641b4a112f1336d7e613b13502de7d1bdd103b6a712bd4c9ab0f5611ba825aa5b344ccaf940c5abc296088893626120b4aa3c73c3e27520b6c6411aa745cd4399bdb627ec584ae3e2a9081c4125cc37f20107f70161975355ae779d74062d4ea062a36a4b63a20e22f3af346a57b37747d3d68a486133857577dc3040342ab2c8a38c9702c66276b5439c82465304f22ca9a316b6c078bbd00a748d9689283aaa0fa584fcb922de15c170412ab5819a18019cc9221533a691503a79c71c43de9453922264ce5994c78a3ce43a1595cb0c761291200b9bdd8b6dd037326e5b40d43717e6507b5f7bbbf71800cc7a1143e7101995ca2c2a06d3a501229a913e3b350cd567e59a03ac54c35a8cb0e4faad7402cf6353a048461649d4171406503d0380f543aae846a21df31c561451fb8707b6f15ae138a8d11b53b4820e97d1293938680546000c7552dea31d4ad50e914cb85935cbcf18821d22b20d309023018a667424ac7aa71532aef2c69c0dc545e3e501e5706bc1c19b5179bd4c4ab22dccc9269560992637a7887b996a6754721a2ffa97be2b5fc2a512788334871577f7530bc06430e539aa7ee0acab022607554e2a3160c2026b8f169cd3537f523b4cb3096dcaeb4413f93e8dd26c774c98daa269cfb702d3592984a3304aa56809b61f5fa4557a08c8ab20a634bca903f456c6e835cbf23f647a47971c3726ca216014459a96531896c8bfe74fd0eb074d74a085bb32bd57857054629a3b19d0105f5aeb5e79d10b0ce0ca1189756bd74324acccebf80e849969bc008adb76ab38fbb47c59cbbaa33f22759d5f879f178a6ec6e37309a15d70c286d7549fea354b438b48d4e73d6b0584469433cb86a74be82ccee60e4a0ab3296a31fdb9a66116a765e2828f3caa12da7e0a4a0a54d1ad9d141b98413c45d277a4e0a11732b9e6a816e3f1cfdcb62d11eb09406b83c5746032e128cc2897e3243840652253b7865a079309b7ce6a1a5b2007b775a463199c4a90358b416435d69bc7c6ec48a155be7570b7fe2626515a09037a6d9dc449e344b0d570be3cb7b70a720156858d8656c296b54c7377456d22ae66402c6fa7a4d2921666171352f56cc03a76365723682c5ef77437a5d16bf343972c43b10f56c5770cb8e9c2a955e89c35d932dc466b0c198874bb242e511f4f4d35fdb1eeb7c0006fafe38c636dab4728b6725dbf53e59cb8", + "sk" : "88f007f412264252bd88a985188292640647b1b3cc05c76af4a6cf3675b42f4482d95993dbd327c8d4b863a8a52446c45e2019e983c05c5c95afc4a0ae860ff06189406c1555bb292a521ba8ea0ef46125e590ab804b42284b1b2bd3338e18a6d6077556fb4b4c39ced51a15568b9d0234112556385329375d55847d6ca3b3c3444a48282c166a218a1c21181b641936ee5527a9848567d5b2a0185e10ecbeaa87503a338e98c0abe960b6c0f129a8b5a532a3598d6a99d55b06cd37bdf8d7adfafac7291c00e07a2816c7ceb5d04461d503e7f382f0e2bcd3389d7dac197ee47ec1cb2261059300a70a34c4007b3579a26884fd771cbe0929dec5b2c7ba08047c99fac165905a7664f27536ca1a8995a976439cd67a7e4fec693ec8beb3ec2e1353c43538159f545bbed6612655762ae90f7785cb8c2051a4ba328ce09977d85434496c9eab763f796f77a94db4343888eb753f434a1906071ea765a07c7f21257d834681be97347ff20c45a207ff7968dc200b48909b62ca4e2caa8e90d1518e7373966b76b69b65b099814e091c2867374e4009b1a76355b2b04beca33f9949c3d700d1583f12a07ec7349c57ab810cd3471a818f8bd8c7e8656ad148561c82bfefb827c2423e92e792f6f79a8feaca75f663b765106b9376bf66b099135c1a553e5b3c0326b6774b384abee645b5cace1bda4efd521967678adf291b6e6602df992b13a0444e817576f9487de014cd563afc086dfe864c0f565a2304338e87232847c2c0885e008536e4cbbad69b78e73794999a5a3aa1096ac7789efb049f273f4e04a92b85304fda1bbfbcbbdc303607d85b4504b544597bea524b79c3c438dc25ca6612d434857971cf95d343ad31c7a8aa5875641d2773535a80cf0b331840a55290cca82b74be2f4915af544d397552d2678a9c771fc89b0f00d6a36bb6276c10c1de195a271b7cb34b971db38f27f071b7bb4c44358766ec23d9636e933b23907a08ef691e453958b325c6a9136e57d2555485ae036ba34a9ca1333bb07015821187538a58c2af375dd5a106c9e01d357b280f07cd7a08a6a9f6b7adc63ca50589cbf21a16e0b35072ba13d9792bc5555b87598946471eccb42e27c9e2a8641c5524cbd17642f41b38fc888914c5d3462da370738fb1a6bf61330f17147b87a8fd294996b3b6bb0997b3e9a076262e7206a879177cec22b51cf1b85535cb3d056e3b6190f528349b245e1fb524dd149d218c5b41b34cbd579c2e2b2eb328cc66233a806177a316956e37a69513ca6183621407075b61b655eb5e5e60ad1582359d954d859550c115c07f71304368546c926531a78479544a6fcc492ef728fe0183dfa6aea27b75bd9b1717262022d75d383c813a2247b065939d20968981ae67d343179118dd1682215631dd7179ba480e54d4a49df6687b1537ad841e668b36aee700301151eda7706adc6572465289588555d263bb484beb51a428dbacb9487a35830597457411c899c20995599c0d3e0759650040127b92c85a58b4d87682b310d165af1b7118e7332de8f90ceb223195cc1a421a1685273078fb7caa4438f7aa4b45087806776188dcccc327170949c45cfaae192c8fbfa0a033e4a6bf137a2d5c4408040972bbb41342a6f2f97c6bf7b5a05a92ef1c69a3e602f5062b4d651b9af148ebe566059454ae71919226742ac151fec6623bd5531699282cd0651a1bb436d113202aae301a6de6c132dd020cf0235944d0a041f6ad92e404f87432bf3a28035c4f6e236ca6e6b56d924800667f8816839549535f1325ceeb5b0e194b89a5800819215737a40988a43336ceaa914800278944ba54edc65071b63374fb041f07a66d5781ee8492d35221c53495248365cc438b4a65a745a64585242878997853597ce1f45371cb1f97f8638837bee3cab372c024ebe4aa52455283cc2249d82739ea481d685204a61840c856617a210fa431a31b27532b5b0868c2dd0a1e2947aef0575934905ec50c33193c8cbf15c5bb4a89b39c63337b3f4bb3b61b0581fe2362037bcab4c62ee14ac3d8a70486789a6d9641b4a112f1336d7e613b13502de7d1bdd103b6a712bd4c9ab0f5611ba825aa5b344ccaf940c5abc296088893626120b4aa3c73c3e27520b6c6411aa745cd4399bdb627ec584ae3e2a9081c4125cc37f20107f70161975355ae779d74062d4ea062a36a4b63a20e22f3af346a57b37747d3d68a486133857577dc3040342ab2c8a38c9702c66276b5439c82465304f22ca9a316b6c078bbd00a748d9689283aaa0fa584fcb922de15c170412ab5819a18019cc9221533a691503a79c71c43de9453922264ce5994c78a3ce43a1595cb0c761291200b9bdd8b6dd037326e5b40d43717e6507b5f7bbbf71800cc7a1143e7101995ca2c2a06d3a501229a913e3b350cd567e59a03ac54c35a8cb0e4faad7402cf6353a048461649d4171406503d0380f543aae846a21df31c561451fb8707b6f15ae138a8d11b53b4820e97d1293938680546000c7552dea31d4ad50e914cb85935cbcf18821d22b20d309023018a667424ac7aa71532aef2c69c0dc545e3e501e5706bc1c19b5179bd4c4ab22dccc9269560992637a7887b996a6754721a2ffa97be2b5fc2a512788334871577f7530bc06430e539aa7ee0acab022607554e2a3160c2026b8f169cd3537f523b4cb3096dcaeb4413f93e8dd26c774c98daa269cfb702d3592984a3304aa56809b61f5fa4557a08c8ab20a634bca903f456c6e835cbf23f647a47971c3726ca216014459a96531896c8bfe74fd0eb074d74a085bb32bd57857054629a3b19d0105f5aeb5e79d10b0ce0ca1189756bd74324acccebf80e849969bc008adb76ab38fbb47c59cbbaa33f22759d5f879f178a6ec6e37309a15d70c286d7549fea354b438b48d4e73d6b0584469433cb86a74be82ccee60e4a0ab3296a31fdb9a66116a765e2828f3caa12da7e0a4a0a54d1ad9d141b98413c45d277a4e0a11732b9e6a816e3f1cfdcb62d11eb09406b83c5746032e128cc2897e3243840652253b7865a079309b7ce6a1a5b2007b775a463199c4a90358b416435d69bc7c6ec48a155be7570b7fe2626515a09037a6d9dc449e344b0d570be3cb7b70a720156858d8656c296b54c7377456d22ae66402c6fa7a4d2921666171352f56cc03a76365723682c5ef77437a5d16bf343972c43b10f56c5770cb8e9c2a955e89c35d932dc466b0c198874bb242e511f4f4d35fdb1eeb7c0006fafe38c636dab4728b6725dbf53e59cb8866573e536b4017c02e31c8ed7455c841a5ccdb795fc200acaf1da2fb936bb597f7054814869cf7625e45647bc1547aff288dbb90699b2ad84893f3b755d9722" +}, +{ + "dz" : "e3fc575ed51513e62aba655d24cd9c8f1c6c848aaffa946c49a53ac3ea59e474d82c2f1bf2e6aebde5660fa73356982e12999d8fdafbb3cb186341d0386dead0", + "pk" : "c797aa612a100811c3131b8b99b3785a4a32c4ab212b5c0217b18a55190890073f2c12521beb9410040129d5947ef96b72c92ae0f58ae1ac236a5426e7a4440aa42c4bd501af4823cb621c3e6374e368aba59c45932aa0addb3473e96854e8a706c510e17ba91b8b865de529cbd093bda7b6ff8b182ef71651035ea6d8b7c00a6f6efb8dfc0b192c44260a9479539c5a4c38cccc6b1b7ff3697e3759f8e1253cf71e2d7c9119b77090a99b3be67ad965919bdac787f116a67b1ae1c7230b957cafe398027596d510b2ce87a73cf8547977631d872ed714193ba7be01bc7e16260b5bb00a4227b976eb5f0dea457d3a493d19494e5219fc67006caa818eb43ab0d80693eb616b8bb9c87c5e899321d6719801a9982049c6a98c2a63800405867251e20c117241e222a1281745e3929cbebc2444b9b0fc0148b81b96f83b9517a2ab24171c5c55898948b7f16c6a1a09cb7dca509a3876aeaaa4ab299781582cebe73e9ba63390b35847480a9a305ca7b4043ca32fa6875b88085115681bfb806268a7ba33bc0dd5311266e672147b089943c2310136ec47ad1652c681a94ff9d09f87e851f1941ab4755538d50d99169ae1bb2bb70aadc0c87ba3d2cb70f1043be7272663740ab74c05899cd7881be63a86abc13ec4e014cd1868c5799992a58a60aa2bbdc6b5dffb8915c3aebe3c9fc8f70ddc8b9b8bd69fe4f1b60202919022af3df26369c190f5f518a6479decd8626e1c16a1094e2dc7c57a1a189b8b2ed0d4b9b0d90662f134cf4325a1867505a43e411c3fb4c4477c74b658d302fea66022505a25cc2a06713fbe1c2407f187e427a0dacc9c0d20a8ff3c4538a71a639a9029f1c826e8612ba30b2de1c63bbb0f70058f13973cbee40f371c490581c5a61ba074175b6488bc9829ad658568304256bfb88db3b10a4fa1744e220ba121772d94b35233cff9f8ca6053a364ca312fe1acde98bcaa937121806b40c972b1ac1e15700ae67441e399bb0641977d058020f205b258a29bd53fc277609c31150a0134849b6b7d4564d27735507ac25bb2164d4664c0b37cd5b9000d33201831c732aab32ef114902104bdb90b638b42960ac870c14e6220806292b9d6d3bcef1a9b6e859516651f9019cbba1c636ee550a72146ab17231f22a8e1eb68209642caf3814a0121565504859810f4a81cd8c5bf10716136e77fefd995a8956d6ffc0a38f841a0905b19589619649ecb2b24ab314a9a85bfa85cc236d19600c7440771a727e6745829cec312346b92c1685507be82a7d3638d36d4a7641a9a042617c09681e0da904a21207cd7b57f183640797142ebb3aad3470b82511bb88c8cd2af6de0a4f789161f7b2c00e2000c95bcb0d270d00c89c5f102b86650e2f8a4c46c052a817cbcd978dbf2c776cc98d53c1f7db97a0f42594ef18b2444a21bb2c1a59a61ddda53d0105489967488046ff8679187800587f2ac8946688cf49e81da406a2684d1a6495d33a8f12b72686482b91c2272215975a484e8488d2b19ae220cc1387594da69195dc47ac1127738bc03ee72772481892734246681b818b16f06943021363ae890ad5e213303d86f890478a91c6d0ae28e95b4ce2a861cbfd681a47a25545c2a29b75946d0f45ba0aa193ca5544686d9f9a802fc4cecdefea4a0", + "sk" : "53a58b52229950c6b8aab3bad4f53abd319322c80414d817966365de802c0f8888b1eb3411256bea64bcde19b9cf5142e5698316e8cad22846d3ea9a4008512ee83cf1c8517789366e358143832624213a30079f2e8b07641a6816c1052111ae088792c7c305e9c442a47697b312945d5ccb417ccaf9b1649bb74485f4c73ceaacb7a69e06647e531b5944d64586a089cc8892ee0094c230998a22c9a1b0230557c4bc3c454fe33e96b9c5fc74b2e051178bc1a0895a782f84b75457b81a905e50ab4cabc57b2fb99c5c9978a9a4b2915459fe8b474b66c73ec2a4f3048bc5387ddaa066c2dca233ab00019bc2b3a89ba4710cae9a8fe1937be7e26b63b039f7e324ec870f2ff3c886ac649048659896294e55c7fae52f50753117e02f93751708037410e3558c87382ebc052d1783314b5956804ddce8c378ec3a4681156fe044237004f2f58c59ec8b977c9dec63678d494a22b76e1d7b22092b16a39c696c7a04def98c258b774a4323ecd6905e3c0267304d94a59028e084d7f1aa0c926965f087f0d89275b88ed075c51ee424c4125cd153782e0bcab7f57e0c038bfb29798df5579c95bdc021bf6a005a599c3ac8317a26d94b6810cb1007b9e3ac9447399db970b5b77544636481434c2acd4a92a7575c227079813447939938125670e9027be04462ef7c00345a26efd3803a26710ba975798102f8452659d2b9bedb387fb92aa038a996c51c92681dfcfc2d5754bbe04b1681c01d53d2957b6327417c4a8f22b80468808d099055e781b5c4a594fa2c57b91a70dba9909824b46944cf553d15a8c0fff742f10127183c00e3c6814cdbb87b88915fdc92a273c364b18b9c16afa3f5ca251a417816a13214a3adcac650674c309923d74972a50114d951640610a9b4278bee19c2d520a23791a136bb0afc3565750295c93513b819bea7b0144472b63e2b76e1909816b88bba368a6e41331881923ee92adc1827d2c292195ac1ad64064272a562bc0c9a325731cc2992d373403b1867746c78a89773035d1f7bc833a0c9efd1142564cb53b494b226154e7cbf86e0cb85230c2d2b2499486050509bbf8340a935a53910bab694b229103158776b4a85113e3b8bf8438fb7950d2db1153627abbda1392560611c72871455125a4984dd743a2222a6ceaa88b3fab2caf9c7bf17adb2e9be841163bd3880c6c1a6860a8eafda0dc8ab3bda2051f6a1bb313332777ac5eec69e0f70ae83958d397a488727b57553a7c4b209e6c6a0d062ae0c988ab89786f764622879be2c227b7a717a3c7962acda48df3c84043a21d2d85564159fa7e7bfadbcc6dfccc335aa3425fa958de87a6fb0b55531b66deaaca5ca251c359535aacc818abf8fcb75a9423e2bb903d2811618f5a696f230ce50ba48eb786b34ae60e8b5d6d477c3d363e838030f586796272728c37eb82773ab186968a0c2d5e03717ca5918dc420be60f77d6aa7484c730bcacbb970de161c525973171e638b73a2b824508f038ac5c5c0b43098863485ebcb91c08b60a0c731842a569c92a077c06949d7865e3f7c8b6e96d9efbcc48c428bcb8ba049669494663d2bc5fe761b42089581ad73437c875b9d89f96675bf09809c797aa612a100811c3131b8b99b3785a4a32c4ab212b5c0217b18a55190890073f2c12521beb9410040129d5947ef96b72c92ae0f58ae1ac236a5426e7a4440aa42c4bd501af4823cb621c3e6374e368aba59c45932aa0addb3473e96854e8a706c510e17ba91b8b865de529cbd093bda7b6ff8b182ef71651035ea6d8b7c00a6f6efb8dfc0b192c44260a9479539c5a4c38cccc6b1b7ff3697e3759f8e1253cf71e2d7c9119b77090a99b3be67ad965919bdac787f116a67b1ae1c7230b957cafe398027596d510b2ce87a73cf8547977631d872ed714193ba7be01bc7e16260b5bb00a4227b976eb5f0dea457d3a493d19494e5219fc67006caa818eb43ab0d80693eb616b8bb9c87c5e899321d6719801a9982049c6a98c2a63800405867251e20c117241e222a1281745e3929cbebc2444b9b0fc0148b81b96f83b9517a2ab24171c5c55898948b7f16c6a1a09cb7dca509a3876aeaaa4ab299781582cebe73e9ba63390b35847480a9a305ca7b4043ca32fa6875b88085115681bfb806268a7ba33bc0dd5311266e672147b089943c2310136ec47ad1652c681a94ff9d09f87e851f1941ab4755538d50d99169ae1bb2bb70aadc0c87ba3d2cb70f1043be7272663740ab74c05899cd7881be63a86abc13ec4e014cd1868c5799992a58a60aa2bbdc6b5dffb8915c3aebe3c9fc8f70ddc8b9b8bd69fe4f1b60202919022af3df26369c190f5f518a6479decd8626e1c16a1094e2dc7c57a1a189b8b2ed0d4b9b0d90662f134cf4325a1867505a43e411c3fb4c4477c74b658d302fea66022505a25cc2a06713fbe1c2407f187e427a0dacc9c0d20a8ff3c4538a71a639a9029f1c826e8612ba30b2de1c63bbb0f70058f13973cbee40f371c490581c5a61ba074175b6488bc9829ad658568304256bfb88db3b10a4fa1744e220ba121772d94b35233cff9f8ca6053a364ca312fe1acde98bcaa937121806b40c972b1ac1e15700ae67441e399bb0641977d058020f205b258a29bd53fc277609c31150a0134849b6b7d4564d27735507ac25bb2164d4664c0b37cd5b9000d33201831c732aab32ef114902104bdb90b638b42960ac870c14e6220806292b9d6d3bcef1a9b6e859516651f9019cbba1c636ee550a72146ab17231f22a8e1eb68209642caf3814a0121565504859810f4a81cd8c5bf10716136e77fefd995a8956d6ffc0a38f841a0905b19589619649ecb2b24ab314a9a85bfa85cc236d19600c7440771a727e6745829cec312346b92c1685507be82a7d3638d36d4a7641a9a042617c09681e0da904a21207cd7b57f183640797142ebb3aad3470b82511bb88c8cd2af6de0a4f789161f7b2c00e2000c95bcb0d270d00c89c5f102b86650e2f8a4c46c052a817cbcd978dbf2c776cc98d53c1f7db97a0f42594ef18b2444a21bb2c1a59a61ddda53d0105489967488046ff8679187800587f2ac8946688cf49e81da406a2684d1a6495d33a8f12b72686482b91c2272215975a484e8488d2b19ae220cc1387594da69195dc47ac1127738bc03ee72772481892734246681b818b16f06943021363ae890ad5e213303d86f890478a91c6d0ae28e95b4ce2a861cbfd681a47a25545c2a29b75946d0f45ba0aa193ca5544686d9f9a802fc4cecdefea4a0b33387825115cba8b0ae7da0d1aada1ce4ab05bc2479b360b6c56dfa870ca825d82c2f1bf2e6aebde5660fa73356982e12999d8fdafbb3cb186341d0386dead0" +}, +{ + "dz" : "470b4943f0fe7fd0d8ec5185aba0d1db09d112934e4fb4787e2bbc6b88466e7b8b2809fd40008be70a6b184981101724bc3d5ec5e1956b510b82fd5ad0668a5a", + "pk" : "d800414fe5b14dfca90fa6bb7e350684c3b08656374d54776c312a645987b9c80b28933550922990e2cc4064114ee12f93d3000164c333bc77d566cd91c904965367b2350b87a6b0b5aa7f8a746ffd4576d22083f23c0f3efc4d09ccb86dc4caa55365a8a406add3cba2127ece221c9139c6c273bd4d3b1bc1ec0626b35db44230662cc44af683c92176c5171337746f0f4900b7369df2b705b6387670b411e26288b8680f9cbb0a8ee01c9d0a9e4c61a19f1cba55459b78602dc14ba52a0b9de9da0cbf330d3e71625228a6a9e471d70639b05792cb8550b24ac159c5b069c30740d09065c9280bf2b4f86c1cd9b78357383b2bcc4e771661f4cb75c6589db317058e428398ea7bb88450f22525813058c609bf5b02a3098a619101c092f87aad3881eef6a2ea91a49dd3cdf1ca6952205e74f68ad5c06fc04163a70c0972c4ad752acfcfd5529b75328548c18748026bd7965f73076d4bb8f84159756c879a5919fa7286e0dc39f1884587ba5e124177eacb2a3e96410a64c2d5403ccb939e428b1e7149ca2b3368c11c8e1f38082ab06f39455d55d12e95c585f0098fe6dc44bbc97c1547600d79b193fa838e42cef6bab08d462faf017ee8414c9914316297cd56889207e13e71e544c6793b751174c5bb22294800785bb003589a899a562c6252ea679779522c03a0b933b07f29194c75b29693e27ddc6c4757cac5b9219d98137516c450884c374cfa8572f3b9e27cc706b205c398866df7972b8a44b7f975cffc3401212bda14c0bb9a50a5e5954f9534ee90c0f1f2328c618be5c2166be064d5d0a04392183fc5b3bde635992998b68b8c7bd7a0a1c3bc99975aab55aa39cc0e1d4c019ef73a53485349b58f4271aa29a4c8f8e97935981a83426b3bd0b5edd1cc10458579450ed4d065a93aa0fa734f3206718974ca6ef35191c930ef67819f535ea5e80e54659b1aec30534442e03cb9c4673679cc1cb205264ea53d20e383d98c08bff78447c3335a4c3bd6f0794ba019e1eb130faac0d2f4193a6476cf014ddc988e757b66ac5c95bb7767e6c32ea8027b5e5a00e62c582ebc4ae6738b9637355f62a053737014c475fa24b144b2b47eec97dab92f58bbaccb0c36670ccc9326287fea9fe7dc6a2ecc896652c9606943ca1a6e8688a821b69e33412025e26442aa2f70a68011f8be62db6e6283b9b85651fb8883acaa20885807237a51cec50cdd007b27c121feca8a2c026d82359de6d8b548d9a49a9914ce76584338bfc8f2cb51466414548cef544b82abcd277a6602887e4edc5e09a20b1ff343541c7ff3d4c0641109ed04cbdad8c2ee80ccc3723a3609454b733aec068fe6d28772e388255a87710ab88848722ccb2c3aba63ad04566b1ba4fdb2a2c07cc42c32b18e7280348c245e29ba51b10d4ae840b8f9858dfc68a73215ddd58df30729d2966d11d4a5b20a6d441071bd5083fbc050232b7e594b11c60a5f7ea438e015018d145b979428a899bb53a42a96e081f7da939cd0ca49dc3ee11b0dddf94430014ce96485bde669f214a3d4a88c6e4b3ffed1ab4dbc24c08224e03c47fa2a7d55997c2491717297155e1b1ca09898447ac0153435444c69b3b704d5b99189e346bfad6143bdd2780d2219878823ecff9df861e3a729f913ece36b46c0e9", + "sk" : "f2b0b79aeaabcc2b79b4ba975e0baedaaa5c80d842364cc03524088c1ca3b752aff7a0ba70138dbbdc45a969c12e36819b4b101583a9e64407932796190751d393a651844f785a5fe92b567c2c2ae877bce902c887555f93b6235d80a23d049e3b9867f6164c1dc6ae80b8a22108625dcc31465703572b3a8d599f55e694f391496ac402e4b754f97b4203e30bf4267be95ca1047b2b67b36c00d6a9a86843b0508440d441afc56362cc3594b9b1093073d4fc6ea7c35901066b25305398f58485905c6f99b9f583927ae80f81a06b5c1404e04c361b236a3a6818613c2245a47dc1a613549611c627ae63e38100d1049e0c6a913287dc810d7546b6ad4891c63c230ef285ecf2a47716c8e1da751175b0d5d4c34b569b93d895461cb2382c71c4c5ac2e53493ef487dd617b7c643d7aa1608cd798854051b02093904c5f3efac3a39b98d6c69f4f02bb7bc62102e326d421cb72eb40411549b13c0b443568bc53070f381b962a5452b7aa8bcbabee0ad090e7493077b3d3db2f9d1b2833462a738629fa8174a449463e39cb097b6b81a95f01237c967c63fb3646a931c063e33a0457bbd8984cd02438a61ccd7af577c041ae58442d48591d7c65afeed9761736852a374281db883f07092dc2b1e52ca803b90eaa3cb130d86ddb67303aa9ceb6098ee45b2e34c1cc1f149cd9f6907fd104ad01865e84c6ed72567b2497b86c889accccefb61a35e9412bc25d18c438f658615793814d93c42ca9b8462568d3e389b08756843926a9a7c0b65b4c1191995bb309117c52a27545f67b8a18c270d8b7a96cda9ebaf08b546097d0dba23f543e9aea0421bb328c7cca3792b392fc53b31c411312a592a5604be84fe7f0b8f393a451ec73b7c831d3aac3d1a1058e17bd68658f73e6970601cbeea3c798417dfd3b0911b364f3bb650245581751bf75400226ab2a45ca5ab5d5c31dc018b5113676a7132c931cf87832ae85c53320bb18904b6d1cb9c87ba1ed007a80166f1e649a8a0c12cfea81a2eb4dd615794eb006dd29713e608bae25c1aa842773d82d7a624327e826786b38f184aeadd49808d5b2c650113b5c36cce812fd95156cc0a1d9c6990c637433f1c0179b47c7389e7214652df549f3724f112626b5d1418698a66de09e6828645b8cbc405a19a9a910d7ab16ad1384b109535dbba89023222f2335cc9c68aae9bedb241475d8c5140177494c7f1b273f64558647228d562131b4349368764afdb054c12c0341fc8f7279234c2170cb7434f370c601053d77355191e03f9d516bc40a53e450323fc76b465b13a6d66e8b0a61a6808822e21866f6bf7b77b9d92c2ced831a594028fe50a5a005d02133840e0696236990045b5920f1789e4bccfa90bf88b4a6266b04ae1854ffcb0ac0d6870e0a76ac5449bb9c9a9a8007ac28bbffe998adf5cc9df03e9ceb139fe293a3fc908366c179004f9f587265711c008a14a44b29c3c6699c2cc57dbc6c540274fe500082e0885db6bd71417e10a3b98c695fb812883d68c0e7770c1ba14d50e5493da79630f35e229997834207bc3387009b5201b4a6b53cb90bf60755a048de73be31338b4ed00f942acd6fa10040d836e12b650c1b9ed800414fe5b14dfca90fa6bb7e350684c3b08656374d54776c312a645987b9c80b28933550922990e2cc4064114ee12f93d3000164c333bc77d566cd91c904965367b2350b87a6b0b5aa7f8a746ffd4576d22083f23c0f3efc4d09ccb86dc4caa55365a8a406add3cba2127ece221c9139c6c273bd4d3b1bc1ec0626b35db44230662cc44af683c92176c5171337746f0f4900b7369df2b705b6387670b411e26288b8680f9cbb0a8ee01c9d0a9e4c61a19f1cba55459b78602dc14ba52a0b9de9da0cbf330d3e71625228a6a9e471d70639b05792cb8550b24ac159c5b069c30740d09065c9280bf2b4f86c1cd9b78357383b2bcc4e771661f4cb75c6589db317058e428398ea7bb88450f22525813058c609bf5b02a3098a619101c092f87aad3881eef6a2ea91a49dd3cdf1ca6952205e74f68ad5c06fc04163a70c0972c4ad752acfcfd5529b75328548c18748026bd7965f73076d4bb8f84159756c879a5919fa7286e0dc39f1884587ba5e124177eacb2a3e96410a64c2d5403ccb939e428b1e7149ca2b3368c11c8e1f38082ab06f39455d55d12e95c585f0098fe6dc44bbc97c1547600d79b193fa838e42cef6bab08d462faf017ee8414c9914316297cd56889207e13e71e544c6793b751174c5bb22294800785bb003589a899a562c6252ea679779522c03a0b933b07f29194c75b29693e27ddc6c4757cac5b9219d98137516c450884c374cfa8572f3b9e27cc706b205c398866df7972b8a44b7f975cffc3401212bda14c0bb9a50a5e5954f9534ee90c0f1f2328c618be5c2166be064d5d0a04392183fc5b3bde635992998b68b8c7bd7a0a1c3bc99975aab55aa39cc0e1d4c019ef73a53485349b58f4271aa29a4c8f8e97935981a83426b3bd0b5edd1cc10458579450ed4d065a93aa0fa734f3206718974ca6ef35191c930ef67819f535ea5e80e54659b1aec30534442e03cb9c4673679cc1cb205264ea53d20e383d98c08bff78447c3335a4c3bd6f0794ba019e1eb130faac0d2f4193a6476cf014ddc988e757b66ac5c95bb7767e6c32ea8027b5e5a00e62c582ebc4ae6738b9637355f62a053737014c475fa24b144b2b47eec97dab92f58bbaccb0c36670ccc9326287fea9fe7dc6a2ecc896652c9606943ca1a6e8688a821b69e33412025e26442aa2f70a68011f8be62db6e6283b9b85651fb8883acaa20885807237a51cec50cdd007b27c121feca8a2c026d82359de6d8b548d9a49a9914ce76584338bfc8f2cb51466414548cef544b82abcd277a6602887e4edc5e09a20b1ff343541c7ff3d4c0641109ed04cbdad8c2ee80ccc3723a3609454b733aec068fe6d28772e388255a87710ab88848722ccb2c3aba63ad04566b1ba4fdb2a2c07cc42c32b18e7280348c245e29ba51b10d4ae840b8f9858dfc68a73215ddd58df30729d2966d11d4a5b20a6d441071bd5083fbc050232b7e594b11c60a5f7ea438e015018d145b979428a899bb53a42a96e081f7da939cd0ca49dc3ee11b0dddf94430014ce96485bde669f214a3d4a88c6e4b3ffed1ab4dbc24c08224e03c47fa2a7d55997c2491717297155e1b1ca09898447ac0153435444c69b3b704d5b99189e346bfad6143bdd2780d2219878823ecff9df861e3a729f913ece36b46c0e9720fd4f96ab2cac1be382907e8cba0702018ca27b28ea8f93cc19c4809885a3b8b2809fd40008be70a6b184981101724bc3d5ec5e1956b510b82fd5ad0668a5a" +}, +{ + "dz" : "6df4385db978d27b27d2aa5e452e4152b36f097503d9581ac3390105c5727e7dc95fa08ed106ce84660e8a4c90bd2b22634e40769aa0090a101c5dddad45edc5", + "pk" : "0e4c3b97c9c7bfd505e2aa01b3cbcda4096b37aac72b5b50a41aa8f6cc518181b70fd3270561bed0938d964972be491b6331a148317cd548124b7653f1709af074b1fe4424df4bb22ac91bff7c04489526e5e2c82f2973408c4828368b87a7c14a569ed7b58f8eb6cca19088c15031fadc0e5b37c442543e1eb944ea4a0541248496795bfdd56178c188f3642fc0580e70a62676555f6b3810dbc89b0a227a8ae554ddab721c954db21a87fda98477d0c2af2820b4691ffb046ad544b3d3919dce8303e2f27152170a182a756b981e6cbc0b0f00274b521c1782b0516743d17a7d7b4b29f8dab31c50739f68c57efc48ff5b1d3757cd13fb8249abbfc7b5a794e11e5b56b9f20c8e8a5718184167264bae901b3ae5005f796341897542c70545a9b6b260bc13cfe536416a0f5e8440907a4fa1e79a292ba20a461285584d3a2993f2bba8397756e1ac5050541806207fb8b313d0a6280b473c59abc9964b5dae58c6860337eb69396a24aa990349c62aaf8420b49e8a95af404b81870b3c9459acb62749e4ae2cd518e329776a6b68e33a7ac795330a8c1ddf2b326c3c269303bfdc9137ecfc9eda856148ab9dd0a920cac260e6b70a1b500d80d085fb9b91593254372c8e13b69b0d691a508a391b04478729ca19d75b566b472917614a53ca485c44e5600793a41a180697f20aca35501e7215a49f591d376a2dfe4a3e0bbcbf4652710d0ba75898ccee4c5b63514752ca8778f09d737337c9219f4b51a1277964c9e67b92888300cda37c382700a40fc185ab8fec55aa539cf115913c9c73af0819188965e57b326f6615682915363c54a267c27d625cfab0712138703cf709bc5c6b0cbb1d5d3884011c1b8ad8cbd1ba12bfdb8a80e9cfd1526d940233254b5dbc2bb17495b6466c0ebe684fbf331cbd99981a4362fd318b28015d9f3c3f1da328917cb140a0567b4782ec8bb1fe31b298b6533c39733304b5f7c74206cc688c144a23cc72aa491e48701cd7f14fb3b7767a679ba4f4c4e1b778019471bd78bf6b55c2eaf43351f85190b07a66c35ddfa67dadd28c30c5264e3c3ee88b62d2c12541d1595a519897a99bbee0207867af34b245b00185a60b4a9cb92eaee58b16f2977ceb180b32243839487ed6b88f6b94d2d4686ec7b7ea022e6d995c398896cd9876815a27ec77188640a4a4e64b65436440fac565caa10eba9d48824541a6165d0bb97a634e6715abeab2bd8f91c18a3a6e899738188744cb6b817d21cf092b64e68cb6c9747d3cc34d0d294b4770548d61cf53bac839b70f0350994ada273312545462bca9118848a343f2aacddb2207f84a66b08958576069c7b7b69c02cf4f954ce3252faaa0b7bffa5952c51fbccc7fce3b6a0c8074f72519930395d967603d327fb8231c1811712308b914a75539128a658a2eec38cb7081926e94a2903471b79b33adf94456fa6a09438dba6103062c1f5a5c66a8d15b829c8f01e7c1e21b10bed1aac6d142ea94334660bbf448511563b5564acd67f87a26f779527000584b61a65293cbd85ab5f3362bb96a61c922ffa77b8d90acba77869293a03d7cab81b688306546ac348b22e368b8d717bc969ed83a12000548310a929e9738b2448d1cd7d1cab551ae0e7b1c495565ee65f180aca4a38847375abe6c", + "sk" : "f67c9ccc171f6d04bd584a4502f796e5395ae59862dde86fdf29192419a75e1b50222c8fdd18964d750ad5166ec56416c44715c22c29ba8b3f663517cca3995de71e8bfb5ebec66f19a4c7f8098908a93650e2374e483c731219ec68b480b95f4a81155703bde5aa7b5b6c57062c809f960a399a5e9d59c4e2f895bf30bdf60255edbc0d59350a2ca86c18fa200543a1f94b05c8cb0a07476fa556905415cf1de45568f07e37b37ce3e857f1d94ac9954cc9c9237439b9b0179ac0abaadabb2ada8559c80214c6a07a282627f949112218c13fc360e1fc589b6c05cae9c42df2a759760d2c5791f6e4203474a43836bf046cc931d133ebe82ec8b6414918110734318db61739568a0ab42b9642759c57333971c406c6ce9cea3c751c3bd9db336faa9c87108d80c152e51a543546548f1a7559681dd531adb919163c716ac791b5782175913b95f36bb1dbeb4ff0f443b4829deb738f76c8ba26e7a9c06a95a86543c2b95402f39180c08bd0e1ad1741bde9722819a910227b34121ca404cb6245566002174ade638533ab1d1ff9b37b9420813a28fda5b02460b1460126c80614066b2137798215266ee571759b7cb0a0e266972c4aad41612e743a8ab6022e5263d8576bb01959d2f23bf9102cef541896f2523f3422bebb252aa823b2291d3156195e05090c050966769d8774ab08d8314e29002e921aee609e40790b1531300142b9e3701058ba90be1757b5ca62b813a82a1a3654a130a8f38523d84d15d1a59eb5a81f918484037f5bba53a564399de86fff3a2850bc2946704e6721b023d01552737cced28415e819db6b6c103a71db13a9a0e4bfa74c24fcf8452630047b1a4f2c3851e7ba2fd6340e376b7451b767e5d3c1534447e0030ac023054eea4477b290ac861e16ccb00a079e68345fc626cf17a42818f3ba685377e7a1596b37791297691dfca02e02244a3372c4479e1076af237a030ab511fdf60981364d82d0909d81b0fc691a1589287ea99496fa16db4712dea0a12a1814196b1e12091344a27336d80f10b2a877d70550026a39f68aeb97606466735418cd47311ffbbb5affc90dca723518fa69615390401c8e047830f3f6b0059a9a9656a277d5b966a69e8d450bf3aba7477656e67b689f91147e3979f230996c566df9e0aa21b52e46868988e5a39f2461a5631ad35b7e049990a0f99bf39b9fef962ca8403c7453abbaccbab4215c0bacb8ba27a7427806fe2842ed930f4858b6af52098e3083e21078bed264ffa4a9cd911427b707d9832adfc28b51ab407c9c45c10c12ca15226f1036ea065388a1499ce967ca619af1d75c350a26e8673366377887f4b788861979a3218c2b5f3859c8bff841736b3b7f029f3c542dddfc271d3216f9ea9feabc14deda35399cc927d42cf17b544413826875338e8b1b7f9cab947700a55306b1a88fd5901fba92923c7c353fd5b2ca793640a57b42926858953b7b544317bb85e6189a2a162203645622885a22c8b595b36e221488c0cab5b3146ca5d04e6e218d8a215400972fed78c89a687abf95716041ce1f213ae42459470084712b863a0c574b1062f472466947296db330405b8e101c483077b1c397849032230e4c3b97c9c7bfd505e2aa01b3cbcda4096b37aac72b5b50a41aa8f6cc518181b70fd3270561bed0938d964972be491b6331a148317cd548124b7653f1709af074b1fe4424df4bb22ac91bff7c04489526e5e2c82f2973408c4828368b87a7c14a569ed7b58f8eb6cca19088c15031fadc0e5b37c442543e1eb944ea4a0541248496795bfdd56178c188f3642fc0580e70a62676555f6b3810dbc89b0a227a8ae554ddab721c954db21a87fda98477d0c2af2820b4691ffb046ad544b3d3919dce8303e2f27152170a182a756b981e6cbc0b0f00274b521c1782b0516743d17a7d7b4b29f8dab31c50739f68c57efc48ff5b1d3757cd13fb8249abbfc7b5a794e11e5b56b9f20c8e8a5718184167264bae901b3ae5005f796341897542c70545a9b6b260bc13cfe536416a0f5e8440907a4fa1e79a292ba20a461285584d3a2993f2bba8397756e1ac5050541806207fb8b313d0a6280b473c59abc9964b5dae58c6860337eb69396a24aa990349c62aaf8420b49e8a95af404b81870b3c9459acb62749e4ae2cd518e329776a6b68e33a7ac795330a8c1ddf2b326c3c269303bfdc9137ecfc9eda856148ab9dd0a920cac260e6b70a1b500d80d085fb9b91593254372c8e13b69b0d691a508a391b04478729ca19d75b566b472917614a53ca485c44e5600793a41a180697f20aca35501e7215a49f591d376a2dfe4a3e0bbcbf4652710d0ba75898ccee4c5b63514752ca8778f09d737337c9219f4b51a1277964c9e67b92888300cda37c382700a40fc185ab8fec55aa539cf115913c9c73af0819188965e57b326f6615682915363c54a267c27d625cfab0712138703cf709bc5c6b0cbb1d5d3884011c1b8ad8cbd1ba12bfdb8a80e9cfd1526d940233254b5dbc2bb17495b6466c0ebe684fbf331cbd99981a4362fd318b28015d9f3c3f1da328917cb140a0567b4782ec8bb1fe31b298b6533c39733304b5f7c74206cc688c144a23cc72aa491e48701cd7f14fb3b7767a679ba4f4c4e1b778019471bd78bf6b55c2eaf43351f85190b07a66c35ddfa67dadd28c30c5264e3c3ee88b62d2c12541d1595a519897a99bbee0207867af34b245b00185a60b4a9cb92eaee58b16f2977ceb180b32243839487ed6b88f6b94d2d4686ec7b7ea022e6d995c398896cd9876815a27ec77188640a4a4e64b65436440fac565caa10eba9d48824541a6165d0bb97a634e6715abeab2bd8f91c18a3a6e899738188744cb6b817d21cf092b64e68cb6c9747d3cc34d0d294b4770548d61cf53bac839b70f0350994ada273312545462bca9118848a343f2aacddb2207f84a66b08958576069c7b7b69c02cf4f954ce3252faaa0b7bffa5952c51fbccc7fce3b6a0c8074f72519930395d967603d327fb8231c1811712308b914a75539128a658a2eec38cb7081926e94a2903471b79b33adf94456fa6a09438dba6103062c1f5a5c66a8d15b829c8f01e7c1e21b10bed1aac6d142ea94334660bbf448511563b5564acd67f87a26f779527000584b61a65293cbd85ab5f3362bb96a61c922ffa77b8d90acba77869293a03d7cab81b688306546ac348b22e368b8d717bc969ed83a12000548310a929e9738b2448d1cd7d1cab551ae0e7b1c495565ee65f180aca4a38847375abe6cbfa4b55c7baf2651415d3f28d221b291b175340a07843b299a46e02e22657634c95fa08ed106ce84660e8a4c90bd2b22634e40769aa0090a101c5dddad45edc5" +}, +{ + "dz" : "dbacba825728444921b227cdba54446b3f6881b47be9cd02832f78b023b1bee0e15274a8e2bc08fe818b117ba28c5dfae74d54fcdf6f20052f79be333edc8dde", + "pk" : "91f33ddda5b9ed269034b722cfccceae14aacaa81038e45b53518216ca5c332bbe3117beb9ca69287a19dc7a078b412baae7cc5181a389b121bc4ac5d0ca67a97248d8f97d7526063cd88219c396ea11435e5c1d61dccc963444b35c99c86b87e40928b88c47f64b919a028ee601229e5a01bbe17b600acb7449a291b131543709a2b8a7d015419726563e366324588038e71fc3714ccd0a68fde524932496be0ba7adfb6e15dbb99f995419c8af3db630e22393bebb25819159abc78c435342628cab40a6350a8a86d1b1a93f6c9151f1895c4674cbf76313b1992d82c6db218339292622807557f458ce057ec1969578379b75d1bf518976b9c69dc22008371930f06b4d1d2465139bc0a62c1d13db9282c00549c45cb351518df67ca3ac881501c3272b9c6ea1a7c527b0ce8ab9124257484b341b2200b49029e2624eb37b15e7d5823a3ca608f09a5fc590dd14cd2cb15cd238735d25bab119b06026884ae5176bdccbab3550fed9b8d4a473a3d0a47a5c78b7b16b880911c7015a7ec281e3ea03274c6199b345db21c0b0c541962a965fba799840c01409463d138977d9bf8ee8bb3ee3b80e021ece71ca0c6ca72f614706e0941b60c3c8c263ad8187a5d70e98740a0a729a0d07123c5b95d553cb1fd086d853869b68b44db974f5161072d6b1f2a18c5f112376c434b9e777a597b6304aa0d1dc3d2f00010e481b9a9aa60e0acb9394cd554a047a6262e4b32191e875e1688456a1877012933ffa51adf131cbd47c28535595e7bc0777b954e094d6d62a5f67bd8b674abd34500da1a4c94bcac04746c4234314e16c1320c48d714481a43c486c96d183b3ea54b19ac54e971710a293121181a16f5bcd861835c78357ea4a6e8b9b785c085545c85a36b3963288851a15abac8a39a109d0d092ac3ec60a93077486d7920a6c274e91b4f04a7e90d724d1e47f65a9cc80f806b20c98d9867a705472738982f3c608f61095548552cc01cbdf10c34f10709a31aa47a27807c74b9533523912637b1a89d8383945dc9553e9911f4b012d6c397f74c250a70d43db4aa7da34df3c9490109fe7b1561cc25f0f37907fa567dde3ae9da24d425a7fdf35b2e61241400783bc2ba3b6098d6180b25194912175548453a669650e9007be369a2181e1a46763170fc995770627b6e48903f574f06037d580ccc1649ef6eb1d8be40392b86377532fe5b55bcd7177cd817701b4700b71a498359bcaca6393710105108c6c33894a41bd1e4a659b22c76c58c0d2f9648b8908397b2d30e9a4ea60c820aa12a58c3aac757ba835483f02ae08f7c9ad8b593d756a33835759f7024867b5d98477eb6cabc4b7397ff52c6719cf73d42f00a4b362073325d48651c2088fea27d540884851cf95f1a85626642f825265411f8b25067d98b5f595482d767b1c291a9e35100e49af47a71caf2214b592831d1024f56818997bcf035b1ce53c5213aa664e2226e83c50594354aa7974d39b09860b3560a534db624b9a595baf31bfc40978cb2903bb549eda3445241620006371b0f7a410e16c828c6743846ab3644413c8c995a4527f82460e112dae7a0d0a963b87e38a66e07290789200d6018cc7c454ba7bd5e56d7ce2d10ffa73f2a284bd579dd64e4229a9f36e58fcd24287c47316b08f", + "sk" : "619075d10644e5f5c9cea8446de5ab5c9ba99ffba41a77cc6698b06e59aff51a688abb284a6c26fbac9ddc31bff11956651c149946797bd265338376144b67693c60db18450db25d9354a1d0d99e2e7a5ba1a871e7e60df77115d7e08aa6b96133e0af9050b784834feb9bbcd0374c0116cd0339cbd3a3649a713ed3e1c185c73a693482db86acbb2688f2c622f8abc7e4041a767698131012f51b9719208b76cb019533798563a55fa7009786049c79c8e617246aa98c4ee0407e0b262ce771eac06ae8c4354630caa42b2c8495481bd640d7a65831b099d0142da3f3239f3ac555ac6440f5b14613147294b736d7b84c035ec8b8a478801c3460509989ac71ba5163618bf25212555bab461994d58c95c3c492df3992e47687962358ad8629b8b0c9f1a1aad180b2c84a7788953145a885d388253e77b274e9c7e9b5882e386dcc9c0b34747265444b8dfb06c6944d84a9c16b9929a19451e4f09954fb2858db2e73b0c940b2239cccc167a60c18212967d7c262c6b06d9566c65c9ea1a86d665a802f5c96d75b67b93c07cf914ec50691bf676276652422a21840db291175a58da6246d5915e321ce3089ada24791a7431dcf4117d3c167123bbe4e9c4670d3696cea143f7c1f12036c63c4699d4c5a32734e85621311c4b826666dfc4578ba4c953d2a037ea1bfa58780ec1678be56997b9375d74966cf9b01a6669ad2dbaa22a26b24a61e2f982b21e9a734c88a32035edb12832f8b59257a0a84b75cc5eb2f7d194d3e1581d9e513598c0cdec0450a255808040a69db3a151c3709c80d55b985e5634839700250389d5ab81f04757a15359a0ef9263f2ac8e152aea3d60e310868c4a71b01761a6c041346d840d1924468f41553f11a14846d694b3918856d0c485562a95071f31b83ec87f3a50ebd89146bf528592b32bfac5dbce78d14467fd873549d998a8f623383861640581627567cbb0310b19b0d554803fe4202e6d41aaf0c58e9f12b1c210e1afc9ffa9c6e18381030d9442a41793bdc274105abe23471dc2423547ca8c92983c0503d1a96b4cb44852b18c5c4f8ad53010c0f3b4f0ce61ce407556fd09814f2563d64134e082be7fa574059ca964b3ddb0053b89627a4194399d01eb24b5e4777c82f7394d95abb10c320032814288799cfd089dbb8ac6941252af08d0248cec9b62b124abbc4a09db3f6188e28a07329c26ac38dbf108cd7ca28dad55514e481969a0f797a341cb05f617372046a68a221b3cfdac744b6ab6a229fdb184dec4ba266952836077129d7c1dbe0859b573f610995feea652fa35c4026b26f194d9333091ddc0fb39648c1b1c6dd69275bda5f4d725de01068abb96c418c283ff65a4c5256df2b2698d82062616de5f93fc6d5005bd449b134361467ccce99bc2dba54a65a6234851fd283b9b77ab43dc40ab1d3ae8c749b9071596785bf53e34d76910384e1a2ce38586a628b7b5b4c50d325a3d340dfccb929996c601969445121d39839cc1ac168236f032a656a01016db1109d9692c81bcc192285bc4baf0ed03d9d68849f723dfc630dd91258a2636bf4aa3c5fb429b8a01074f1983de27ce91513dd44415675597c440cbeb434f8723891f33ddda5b9ed269034b722cfccceae14aacaa81038e45b53518216ca5c332bbe3117beb9ca69287a19dc7a078b412baae7cc5181a389b121bc4ac5d0ca67a97248d8f97d7526063cd88219c396ea11435e5c1d61dccc963444b35c99c86b87e40928b88c47f64b919a028ee601229e5a01bbe17b600acb7449a291b131543709a2b8a7d015419726563e366324588038e71fc3714ccd0a68fde524932496be0ba7adfb6e15dbb99f995419c8af3db630e22393bebb25819159abc78c435342628cab40a6350a8a86d1b1a93f6c9151f1895c4674cbf76313b1992d82c6db218339292622807557f458ce057ec1969578379b75d1bf518976b9c69dc22008371930f06b4d1d2465139bc0a62c1d13db9282c00549c45cb351518df67ca3ac881501c3272b9c6ea1a7c527b0ce8ab9124257484b341b2200b49029e2624eb37b15e7d5823a3ca608f09a5fc590dd14cd2cb15cd238735d25bab119b06026884ae5176bdccbab3550fed9b8d4a473a3d0a47a5c78b7b16b880911c7015a7ec281e3ea03274c6199b345db21c0b0c541962a965fba799840c01409463d138977d9bf8ee8bb3ee3b80e021ece71ca0c6ca72f614706e0941b60c3c8c263ad8187a5d70e98740a0a729a0d07123c5b95d553cb1fd086d853869b68b44db974f5161072d6b1f2a18c5f112376c434b9e777a597b6304aa0d1dc3d2f00010e481b9a9aa60e0acb9394cd554a047a6262e4b32191e875e1688456a1877012933ffa51adf131cbd47c28535595e7bc0777b954e094d6d62a5f67bd8b674abd34500da1a4c94bcac04746c4234314e16c1320c48d714481a43c486c96d183b3ea54b19ac54e971710a293121181a16f5bcd861835c78357ea4a6e8b9b785c085545c85a36b3963288851a15abac8a39a109d0d092ac3ec60a93077486d7920a6c274e91b4f04a7e90d724d1e47f65a9cc80f806b20c98d9867a705472738982f3c608f61095548552cc01cbdf10c34f10709a31aa47a27807c74b9533523912637b1a89d8383945dc9553e9911f4b012d6c397f74c250a70d43db4aa7da34df3c9490109fe7b1561cc25f0f37907fa567dde3ae9da24d425a7fdf35b2e61241400783bc2ba3b6098d6180b25194912175548453a669650e9007be369a2181e1a46763170fc995770627b6e48903f574f06037d580ccc1649ef6eb1d8be40392b86377532fe5b55bcd7177cd817701b4700b71a498359bcaca6393710105108c6c33894a41bd1e4a659b22c76c58c0d2f9648b8908397b2d30e9a4ea60c820aa12a58c3aac757ba835483f02ae08f7c9ad8b593d756a33835759f7024867b5d98477eb6cabc4b7397ff52c6719cf73d42f00a4b362073325d48651c2088fea27d540884851cf95f1a85626642f825265411f8b25067d98b5f595482d767b1c291a9e35100e49af47a71caf2214b592831d1024f56818997bcf035b1ce53c5213aa664e2226e83c50594354aa7974d39b09860b3560a534db624b9a595baf31bfc40978cb2903bb549eda3445241620006371b0f7a410e16c828c6743846ab3644413c8c995a4527f82460e112dae7a0d0a963b87e38a66e07290789200d6018cc7c454ba7bd5e56d7ce2d10ffa73f2a284bd579dd64e4229a9f36e58fcd24287c47316b08f9675fc6d1e3cc4e0eb62d31b6b4f10022d373d2718f3d20ee1cc00ef6892d9a0e15274a8e2bc08fe818b117ba28c5dfae74d54fcdf6f20052f79be333edc8dde" +}, +{ + "dz" : "690eb71fd7052b906eaec09937a8ed374e0b02afa27c2f14399932be5839fad281c38c2cb5cfafac81b96a810ab749b61806b6d54c9f8cf4bf1be0192423288f", + "pk" : "2ecb47bc7c78372b75de587297848724335f44545a35fa11e6e1208ed4764fb8bd4af9712e21c8b3c99e5a04432ec7c0b3200384534aae227c6400883ac21ec5152380b458bb69c5ce909842d3b07ef2c539c44a2df2013aa97a08b511e444996144cff78ca394b5440f4aba566383b0375edb2544a42c4df25b6a96e0263c8962bf9b716bdcaab098b41f735018735d8a26ad7d93b0f17452bb64180a572f75091af0ba9b3499a134e90a167ba72dda62cfdc27e3234b1412115ad0463da2600dec2e7010b1fc914f3772c858c80608244cc014a31036a9abb68946b51354d07fb914bf22e17ea21854ab778b67b40cef331cf8374594385c28586dcfd5421d1a008634b006965f88d58a5cb449f52136d7f82cfd0aca3b6355117b15cb51240c6a239ba26380c55abe19912be90466cb701d4bbcc5e138c525bf28d23cb2e0452927873c17c7e431051f99a6f585b89facbf71f594b49ba84c7235978aaa2baa1f9e7496509009acf56c5d09a4c53b1cf2845a0d0555528c8c1d287ce7e0aa56e85adadb89440305eb942b1fda247457751fc1b5b8811fdaa95592a047e297b9418c52f0189ae8a21254f838deb89360292956749007ca73581aa79f37116533068d2425d5ecba7447b7cc5729d987564ee3cb2ccabb6c31ba24375304a70638533c67bc6e53c51b17559133d4aca5a6bf44c635615a9881e25e4d137393b76b5017254970b56ed13f7aea587458a43b3435bb018ff6082661da9fec065c0ec23bff1b919633806a835139da4c4d34c6f4567daf07536eec3d4d0347f3abbd7f32317c33c2660393af455c2dc506ca111f48da051d8350edf5590adaae9731c2e301a824721718968ce3e66be430b8db293a22859d68b353dd45467c85ab7f4baa0d5b2cdb83c94a895a58e09e9f249153f25fc6d3c7ef50b1929b197128a64de27c48041e08c26d64b8c229cb24f9e9667aea2a33531d19dcb6ada725eee88f063cbc749c2e90f989c8f0c7cf6bcda814bb2b321f1862b32cb8294e99c78ba21d86a402a1c8c3e7f9a11f09306e588fd1856b7f5c5eaa768dd72793a3a88d35e931de0bbe0bbb697010b2c75c3308649c1260648bd3a6d6e57c56e00d5de7270d2c26572aac88e08238658332879d5ffa005f7c8db415403ae73ae728a5f3bb228a326b05bb26a0c91544d98db8cc687c597ae2e6b142b101e9731ac8c20c7eca11887b7fc8886c304a162b30cbc510ce54ea5324dc9b82f39b0d971dfa69b81ad99d49bca9e3449774985f5051a7eeaabdbd33857741c11adb51744539b1095c1b32cc99f81a0ccc6dc88ba829b11025ca5dd3353639fb8148088763ec9e7c14370766b918e93d8839a8b0a34d3090933df3a86e3976d09776a0ec3229741b2155b6c7ac5431421c7b80812523155c9cc5d890268661501628231c1c660583829e7b3984bcc8ad20632c16993673818f7ba15a5064aa42cdb9f7b0e0708328213388b06a04d559fcd83a10913c15167363f997f62b6a03614c46b9acd703be1a1b641e7910ea273022168352c89cd7616d7746983b3b51d57770196a68a50125f1634faba0c752826ce0aa6448c86fa76c6a3e2390840b0c7f333650c53e0a998b66b533746765316f08a94e18de52516228102ff16993ac61abd8d7884c", + "sk" : "a46a88df4035c55137522295e986cb5e6605f7da81fc0b1f29903b3d283022db4f8046378fca124f5580a1dc4535e64dfea6c4fed63aa73960b4e14808383cbb12cf6f204d07f852a815a793eaac2f147d24c53e412a21a7550ef4e8122f46cdc9c560bf725545c82b743041c3933eff115d15746f3fcc5934c132af7a18b2a37fdce899e9c1cc0417124f0c279360c311a08cfb301655483d7f92853274c9f81683e5ca26283527647a0ef6d09225d4af7f1c1ca7563e824454b4a2cdfb5c582c498b4a1a1645553bf7dc30d6a56e0b7ca57510aa315818e527a64bc1b7841801edab2446863d48a53dc83203a0f68be3fc498b288e8457cf6f8132b367a9529bbb814151950c3619fb49d5888aa7424c30d415d08492a7ca50e76b56fb18bcc1ca99c45ca066340ff1e5beca8c51d6355504496e9e4a407ae57ee5a30f92ca1e0d3298bc252ed70114e426a76c5c08ab67304550cd7eb6366205b639b30da30978bce2c745283087c9ba87d3273df10e3e2573479bc205824aba06ae5fd6171355a73c771939e767412333685c6cf9cb622554af01672967bba8e043ad491568aee39e35888a4b996f6279223e820f20f5c95a6a66a972cea5bba874fb018cf05ae1dc60208510c85c6e3211583c4c21965b27817982e1165b6a59017b4bbf3db1ba31d95f14bc76c104c1097aa3372992026035e89895add31669481b6c558842b3bd1ab5bc9ac2bb6754b0a8b07419a35096b2365b60b317571674012eeb7157b233c4a1d309bc1c4c7fc047d5c3382dbb4cf65c9d9a24bda690c37d47ab27500ba5748a0294c8c9fb8acc8b3d938270a73c55de662544c7c576c73a2bd9cc983a60ddc0152be508d341a29595a40c7b617d6bb45d247128505a930a4bf9194ef4e27fa9d9cbcc55c8c9b4cf675876ceb2bb711798c850c3e85bb9e84bcc716195264737c03b4b2738188c0922d50ba49c01b4fbb85e48ac9e02739fbf556c5d5210283014ff280263d7c5353a0454d93195bc4b8ed41551b10a7a19808292c73fd63e61840d10f5c5b2853ee55265f78cb112b3a3521577c90b2744d855b758431e71816fd200b47791328481c49b24f991c9824742da7043ca2b47b7449126533adb1191d4ca1e3779515eb05e9c57c383a3bcdd991fae460ac8c6983e16484d7aa00aa12afb778004366765b3ab6365737e7a4227e7b5b7729bd9086ff4b64cc7ab06ad353c6bb24e05557fe2d60436f9596639abab693449247e881827f0133b9c1569baa2bf87486cb1fa0dbccaa179b397b01906847a970ca28f29f9a8ec0a0fd0a6c02c52a75bf7c3c0c180502590f3766e56556502b1a94383866082681d564b333b852b180c91e6873b143f8475a3b9d67c1421a871a1bdd3c073cdc16f4a717084b95528d43ddf2870ba2a9689310d761a6fd4179261f219de4500ad4b186d97cd1074b71ff893b3d4c889ccbc03264540a26b8ea3551dd86d77c29756c6972ab87ac9d07999f0bdac8a8796c8b83e9311b1a529c20a715e382f21e64f9fd0624792b818d93eb2e3be8cf8bf16793aee06a018eb86ae09292d5599ea78a2553a52793c7148f12762ba5df79b5242249684b1716b818498a5b82ecb47bc7c78372b75de587297848724335f44545a35fa11e6e1208ed4764fb8bd4af9712e21c8b3c99e5a04432ec7c0b3200384534aae227c6400883ac21ec5152380b458bb69c5ce909842d3b07ef2c539c44a2df2013aa97a08b511e444996144cff78ca394b5440f4aba566383b0375edb2544a42c4df25b6a96e0263c8962bf9b716bdcaab098b41f735018735d8a26ad7d93b0f17452bb64180a572f75091af0ba9b3499a134e90a167ba72dda62cfdc27e3234b1412115ad0463da2600dec2e7010b1fc914f3772c858c80608244cc014a31036a9abb68946b51354d07fb914bf22e17ea21854ab778b67b40cef331cf8374594385c28586dcfd5421d1a008634b006965f88d58a5cb449f52136d7f82cfd0aca3b6355117b15cb51240c6a239ba26380c55abe19912be90466cb701d4bbcc5e138c525bf28d23cb2e0452927873c17c7e431051f99a6f585b89facbf71f594b49ba84c7235978aaa2baa1f9e7496509009acf56c5d09a4c53b1cf2845a0d0555528c8c1d287ce7e0aa56e85adadb89440305eb942b1fda247457751fc1b5b8811fdaa95592a047e297b9418c52f0189ae8a21254f838deb89360292956749007ca73581aa79f37116533068d2425d5ecba7447b7cc5729d987564ee3cb2ccabb6c31ba24375304a70638533c67bc6e53c51b17559133d4aca5a6bf44c635615a9881e25e4d137393b76b5017254970b56ed13f7aea587458a43b3435bb018ff6082661da9fec065c0ec23bff1b919633806a835139da4c4d34c6f4567daf07536eec3d4d0347f3abbd7f32317c33c2660393af455c2dc506ca111f48da051d8350edf5590adaae9731c2e301a824721718968ce3e66be430b8db293a22859d68b353dd45467c85ab7f4baa0d5b2cdb83c94a895a58e09e9f249153f25fc6d3c7ef50b1929b197128a64de27c48041e08c26d64b8c229cb24f9e9667aea2a33531d19dcb6ada725eee88f063cbc749c2e90f989c8f0c7cf6bcda814bb2b321f1862b32cb8294e99c78ba21d86a402a1c8c3e7f9a11f09306e588fd1856b7f5c5eaa768dd72793a3a88d35e931de0bbe0bbb697010b2c75c3308649c1260648bd3a6d6e57c56e00d5de7270d2c26572aac88e08238658332879d5ffa005f7c8db415403ae73ae728a5f3bb228a326b05bb26a0c91544d98db8cc687c597ae2e6b142b101e9731ac8c20c7eca11887b7fc8886c304a162b30cbc510ce54ea5324dc9b82f39b0d971dfa69b81ad99d49bca9e3449774985f5051a7eeaabdbd33857741c11adb51744539b1095c1b32cc99f81a0ccc6dc88ba829b11025ca5dd3353639fb8148088763ec9e7c14370766b918e93d8839a8b0a34d3090933df3a86e3976d09776a0ec3229741b2155b6c7ac5431421c7b80812523155c9cc5d890268661501628231c1c660583829e7b3984bcc8ad20632c16993673818f7ba15a5064aa42cdb9f7b0e0708328213388b06a04d559fcd83a10913c15167363f997f62b6a03614c46b9acd703be1a1b641e7910ea273022168352c89cd7616d7746983b3b51d57770196a68a50125f1634faba0c752826ce0aa6448c86fa76c6a3e2390840b0c7f333650c53e0a998b66b533746765316f08a94e18de52516228102ff16993ac61abd8d7884c9d162fce2f019205a2106acc8e3e3465b6fa3912a06c764e625cbe3b95dea6c881c38c2cb5cfafac81b96a810ab749b61806b6d54c9f8cf4bf1be0192423288f" +}, +{ + "dz" : "32e0ea9089fa928482c0770da545af1bb871a03ce38604138b0d08ea2a10ca2bc06c5bef7b6508409daf847a64c8d30d0974fd3ba7476dc76c46b458a036d884", + "pk" : "7a6917006162efa4cfbd499b8c853e102c9639457f66812d58383e629a7522f1c683d48d8a216a0aa82454f29732077f4baa593de951857227b976a35a8013a622afe355144b63bbbe58265287cf6d605421e73e7df7301b59a885821ec0314ee76359d9d715eec1c2ae726fc0592ee01c1d45d6c94c76cff66bb3bc321358e33f16e1ad44b35e256bac5ab519e404c3cba647637537a524849cf952deda7940dc1c3a213d8c13580ebc10e2b458873ba5cb30c00d855530b0b5f86003a2c6641a72170b238feddb624f9660e16a9c545a0fe8102612979552f311a9417fcc8c8768280a4902a8ae696131c76338097f0c3a2f8731ca25d55a21b619d1c48550371cb2cac00e27c8ab9c8d7bb944e4bab625eb1bf7c55f0df84ce67c48fbb4438eabc818cc2871c619222a0c504c6898c31b9e859998911f4a29000e4063cc0a5d13975182c97047520a3fd7430117b5d0b2b088741690b5662a3b02978c5a2f1c330871957c5c73bb5a2fdeb0b5f3e5953b509b2887435b41badd607307941aad1cade20c4a22b80683b80dfff1bf82a4ae80eb0915190197c1ae23145522c86f86955d0d3b7b4b83b019123674aaac2b4138e4b36169b1784a4bbac8570aba1acb13ac0ab84a6bf987a23ec91f7c6c2dcd6b952c505515b4b4b1e7c749e693ef4a7dcdf8b7e2f89168991c0385829e46c7faea3c7fb18ebbdb333a4a16676aa81daa4ab519638807bc977729d4474f4c068897e77abe636df8525c35e7c691b49c72e50bbd8570d6b888041380a6a4b9a65868f247141ee137ba422807a57a9389cc195345968086359b36e5316c594a88959b7b006abb88d754bed942230b36945a141d4810050834caa24cf58747820a6aacdab186bba056bbc043da570f874eedd29718795ee19c9e8fd4378fa8a42ba6812dc51874cb0285420419d408e897a7f8fb9ad0238ec632674440b66e838fafd731b50092324a9b11a545bb9a9d7a242d54c6bf897a080ac0b06b57535e542d254ac581450d82d73ef779865708a2563c86e4cb3133cc5fc2e16dd2b043449a73e59a5c6a29a227a469ce406192ba4825e3503f3552f743bc3dcb945048a95c70209bf5c5efc76227ec7d947a19dfa0af12b078bc588c1cf9c1300961c59ca8529c357b9087b572a8bd2739a7a526f3d874e6e2a23c4242bdc652569c7ed3546e3e85b7865611c2cb7ad551142b2503e14c0fb8220755036f6bf95de3f1440598076db3410a4ac1e52c91f038956731622df255646ca02fe7cf1aac75d972a5d744512b4b498c666ca68660b984bbe6a1833e83caafb80e17ea49c484ae2b6475d2e276e0c9317c47090dc9bc134b606a6a1336a40881d76ebfa954dc550cac192082e1aa81f9a6d9162b038a021e09b28bd0b959884acc836a4a95100fc93071dc474e593a1d7ca409001b6c40c3fb13a5b6640a32da0b6db086f1691614d935c29b67d8d54732948dfa27296a63607c17973b764b9c05713bf0026bc0534b9187fe33690826a6c80014b2f97312d53b3b22aa1740b0a47ca8807145eae577c994b1dfeb19109b5b99019329fb6adae267c2759fdae64cf479462c4185ca67255971aace8351a94501d772b15890042363b3bb64b6373e44c5bf6ae2caed5dfc3e0f0dca2015579e6c636683", + "sk" : "36059bf728aab04b86ac60b0f5c233a78a036beaa04a2873b71a3e29272e922b4537f97aef0700afa68b6da877b25b1ed143ba6ca538bf04662dcb500466a70eba596776c6d3662073f20c7582614eaa1517b5578378069f2704a4c5836a55006e054d623b6d04d48abd14570b4613f4c155f9d86c8c695ab9a2744e40794375c07ca62e1a3269104bb9ce60c8e2c6c3f9153ae3555a3a35a1717739ccb195e315400f3704c7c839614c4cc799a4ab250af448b70b871a3a1b8aebfa6278f6222c41aafd51bfd126032ba90e8d103e64e1036fa72dd9e752b72903d3b45443fa5302103d041b12b1a2ce0bf7406f81812807764ed435074a6a55dbce1065913deaa3e7164fcc6419a0d0cdbfc314ab66b2bd40a1e2e0af801b5e9a22023d1c797f49a345661e9c0352d9e880edd71b2e4a674265b3dbe4822738877f305f6e59bd5e4a4ba8aaaedfb28a87733411da7981f458f09a0d8bd55446aaa44f382b4bac9b08fa53b6932337b438744064c7dc9b5e95c61be3c454590df2a88565dcaea473bc3051a08bd6c238e36ea4d28064814c5d210c2cd8a8325230ec330063585b8472ad1415725b51950c171fa4c325c9a8795ad3585e515285678aa43470af7705d800bbfc14a9172b11275471f0948dfed89782d2a214095f11815026f202e18cbccfc75b46763cf37aa5558a34bfe51176b904025b16a08a07635455a01b69820541336a0397abc928e735fb969321216d17341cabb82d07a6a036d7cbebbaa1b7771497b329d67a9c247b6c31798d47347e41a425d7a5b3b1f38d914364a5176ffec86a8f743528179a5c544faba84c48387dd3264423bc083da506b356a51efb1d18da3a5ef2361ec43d2c80395d126097a7a5cc6a4354699017a7cdb02a4823f8327d729a89c1971f6a8646b92d1d38031e5c4a29733ab30063bd86abe6bb19b85687575b85406861a6a3c93085501f62088e245f25c450867c349700732578bec2152746c724a4da7b5b0a0a6df57a67341acd911d12e2774a78a6f003885cf26bfde0c8c1c24a63f33e5444ac342451e5f51820217fb20c14a64738f43a5aade60e3367c3d1695e409bcfd3e57885d87b4d19c3744ca797b74e1af7253613aaa5e9644279ccf963a8ab38ab07a1c8ec6558c3b6a285b38ea34acd49c1a74f3610745c8cc3da36202c6363079f3e252157c8882860a1852663a7b4416d33bea9a08157f61e5ae8bf3aabb7098b2110dba39e4a681eac0e765320d0fa6a6bec730a1848d5137a2f62a7b234180cb4b82568202b59713fa38d10d6c6aba1be37325db36896b80b0e6b356cb735c004d98caab7893e383da8a467c4a71c0e9316bd640f226a68ee2c138b8159a6147c9939ca45304b5df944b377ba4826964b2b86d50b9edd5294c3da3b2ddb02ce786eb02b79e8850ae923cf8b99211ba97806795c2bfa713079ba7728ba7b94b985728b83bcbd64f26a8d5594fbdc18764307a9f66a1e2b0d0d290cd23878adf03e2ebb9f0c48c9132835121c61709a740d937c8010a866f494af723d57b91b98034c6af9388d1b7dbf264f775462a5f581c0ca23c2d45f98c267951b40d36913b23612091000f49577eb8caf83744b7a6917006162efa4cfbd499b8c853e102c9639457f66812d58383e629a7522f1c683d48d8a216a0aa82454f29732077f4baa593de951857227b976a35a8013a622afe355144b63bbbe58265287cf6d605421e73e7df7301b59a885821ec0314ee76359d9d715eec1c2ae726fc0592ee01c1d45d6c94c76cff66bb3bc321358e33f16e1ad44b35e256bac5ab519e404c3cba647637537a524849cf952deda7940dc1c3a213d8c13580ebc10e2b458873ba5cb30c00d855530b0b5f86003a2c6641a72170b238feddb624f9660e16a9c545a0fe8102612979552f311a9417fcc8c8768280a4902a8ae696131c76338097f0c3a2f8731ca25d55a21b619d1c48550371cb2cac00e27c8ab9c8d7bb944e4bab625eb1bf7c55f0df84ce67c48fbb4438eabc818cc2871c619222a0c504c6898c31b9e859998911f4a29000e4063cc0a5d13975182c97047520a3fd7430117b5d0b2b088741690b5662a3b02978c5a2f1c330871957c5c73bb5a2fdeb0b5f3e5953b509b2887435b41badd607307941aad1cade20c4a22b80683b80dfff1bf82a4ae80eb0915190197c1ae23145522c86f86955d0d3b7b4b83b019123674aaac2b4138e4b36169b1784a4bbac8570aba1acb13ac0ab84a6bf987a23ec91f7c6c2dcd6b952c505515b4b4b1e7c749e693ef4a7dcdf8b7e2f89168991c0385829e46c7faea3c7fb18ebbdb333a4a16676aa81daa4ab519638807bc977729d4474f4c068897e77abe636df8525c35e7c691b49c72e50bbd8570d6b888041380a6a4b9a65868f247141ee137ba422807a57a9389cc195345968086359b36e5316c594a88959b7b006abb88d754bed942230b36945a141d4810050834caa24cf58747820a6aacdab186bba056bbc043da570f874eedd29718795ee19c9e8fd4378fa8a42ba6812dc51874cb0285420419d408e897a7f8fb9ad0238ec632674440b66e838fafd731b50092324a9b11a545bb9a9d7a242d54c6bf897a080ac0b06b57535e542d254ac581450d82d73ef779865708a2563c86e4cb3133cc5fc2e16dd2b043449a73e59a5c6a29a227a469ce406192ba4825e3503f3552f743bc3dcb945048a95c70209bf5c5efc76227ec7d947a19dfa0af12b078bc588c1cf9c1300961c59ca8529c357b9087b572a8bd2739a7a526f3d874e6e2a23c4242bdc652569c7ed3546e3e85b7865611c2cb7ad551142b2503e14c0fb8220755036f6bf95de3f1440598076db3410a4ac1e52c91f038956731622df255646ca02fe7cf1aac75d972a5d744512b4b498c666ca68660b984bbe6a1833e83caafb80e17ea49c484ae2b6475d2e276e0c9317c47090dc9bc134b606a6a1336a40881d76ebfa954dc550cac192082e1aa81f9a6d9162b038a021e09b28bd0b959884acc836a4a95100fc93071dc474e593a1d7ca409001b6c40c3fb13a5b6640a32da0b6db086f1691614d935c29b67d8d54732948dfa27296a63607c17973b764b9c05713bf0026bc0534b9187fe33690826a6c80014b2f97312d53b3b22aa1740b0a47ca8807145eae577c994b1dfeb19109b5b99019329fb6adae267c2759fdae64cf479462c4185ca67255971aace8351a94501d772b15890042363b3bb64b6373e44c5bf6ae2caed5dfc3e0f0dca2015579e6c6366833e834e34f198ab5a3504cfa0c6af6ab78de3a3ef5667e6065e084cf5d2a5bb32c06c5bef7b6508409daf847a64c8d30d0974fd3ba7476dc76c46b458a036d884" +}, +{ + "dz" : "6fb2ec719f2a0dea152bf3f64b9d148f8ab8ba88f64e61f5db53e12d59f525574f797c007e4061f95c7d56cfc7ee5c49e849dde3fea8f25e7876df2a18515c34", + "pk" : "4860867e75349ba9999fe4be93262a08f868abb10652b51bd1c67c266156eda768e30b0c82f910eb96062177a882435c74353dda7279f2141d23a6440b900a8a476c66993477b999e23b40ede83b1e31781b4303e4bc5e0220cb0a6409c88aa8238b83d78792c5632751fb0d5246ca42fc89ce31a64069560bb87360bc2696e78062600f24db78ab630079a64c87900d4b7c9ef9201822b6bdbc69c6be718c3b2792ea32756e1a465325a763dba22861a423e65458272e77400375aab4dbf30d564a176613c264631d33f37cea0346e71649d1314862bb0d2b05711cf1af088a4c619048a7242d0be6a8b536c41a9368b22288ecd0ac7298335e5c91db419c2126a8df45b2e6d8793da63fc7e94d75d3bca2aa58f5b5bee0b43a462a12c34b93f68952b6e7abd89c97c293b0693192a44c0d4e69245e14983e87aa26da8c63517f58d66ae1610936e6a89dca87b6c70c1a78c66743b89b3c2eb854067ad97d74771f77b0906a9a7e78640de75a7b8273851dc55dece9b1941cca76cb2dac265e487585780928dfe7402710b6bd914d564568d3d4075e4141749990c40214ea51b71f855deb9349dae2108843b5cd9815f1e8458c020fadc1c65796b117f8b9851776e896891dc05aa0095a914457016172a17624a608cd49db55a42bcea68778a26a910eb566a2d942da58a4cea53ea7a67954b085eaf642405b1674309b68cb9bc3c04d67505d861a605bd6163f7cb49fb8cdcd40917bd59b94892459fa7ea64a4872f51b97e66e64f02818520164e20d5f952a3266840b4575fdb7625d07d00486bd433447d5e1abfa65b215e034aca74670d4b7ff61c36ac2a1628a20d79b352d1c82c1626233ba527967302131bc1ca837d9eb4238404a20a515fe98a9e6d9b34ec28f0b252263fc2bffaba508a6375aba51b4a36af23740d2d51705b2a1083b23bf5a6b75a214dfcba5eabb82faf49e4d326d369cab0f74c00bd54310a3620d570eee533a1a89a51a418a3cd14b25244f0c66c8e8e454e358364fab5997170a90a25f3816aa1b272b09e54435ab3096e8161926299acccae3d689eafcc7e220cc42f5a347173ec4c2510da02c3b4526d75c9b01d103b8914e41b03865e16be770a0e642251dc312cd10aecc6a9734ccc815da2bef09cd18c3a8ad6c0f90574f41075cef470039a62891ecaab5f033fcd4266a510589f7423b4992f488c3cbc450db074fdcc7cfb4a51c08e2359247c1f564cc94383892757a8164c8c985c28e288adffa9c866a6779faa0f0882abf650a4b9c5e0fb36e4e51a6442167aa97c8e25ba55a3b5d7f164f07b2917f57b16b751ac08167ae88cefa14668e7634d05865d1ea24d1013e1b270c9ee9164d18654646bbae973745e64f90e69064f38fe5744a6343ca04b1a05293c5dea9ceadcab0b1f07ca177cafff03d582b123bec8cd829aae8d7cba9f91d4c89cf9e9b52038638f54721f23c6b341419eba880368782d1a0990f57211bf31012148d74451ae1e79850b75d6efa172744cc6d77a46dd0272924bccef49053198b87e1ac122a0753950586d14c6b22bc12939f0661638b5191e6dc2ffaa147dac984cd004d6dcb637bb18b2f04c115f98cadfa79f64e6253cab64110a71d94db5762f8cb4d277e03b2435a473d60b193ed2646f4", + "sk" : "30251db04b83a5b5969cd3354a375ca3003289d59f5197a01e2b103162bd63c0ce71e9c5b0259ab5d7ba48fc72fd3c90a5132d3b0b36dc9c411fa10bd5b45168aa6c562405d478487545b0c4034f0761897db4cd2dc13dec0253acb3051f71b170a731cf1c0e5f17cab24b64cc7682a2d4313bd23cab0849b20bb094e4570910ae5c58989a99880107ca4e617e66020043874eb861a0f72b50a924b8a4bb021504cf299b08b610bc14b0ba6226b162290c3bf6559db1ce5694bc9c75a8f4e3290900ae68e4a29a543dfcbc8e10e90472675381e0376aa408c858491be00fa782049766097a787337a616e04cc0fd8a57612ca816073c47c97d93c6a134db23b84198a0f196dd8c6ec88bbb5d08634c378b678455b005795518cd66ac170090207c84bfce5a89fe0cc1d16a3a60c810fdd780654277940a6e86e75b563b794649a29f0201d7a79930bb1a2b6177002560b5a06ca2d84dd8b45615923bd58543e53221c244ae917459149c13d15139afdc0ca0828ed5c32b2327a8bbf71e86a4071a579d6cd180a1f5248d3a148c318271a378921061041c186faaab73cc3465cc603b90138e125d909427f0c6c13c7b1af731bd7fc9c2eaa601880174b82a28a1d29db0bb708ff06c255bc17bd427275c2c12128c1253207808cf9edc6d3b106cd016821814b9ec498adaec702ad8bd24b894cb21b94de3175e2335b1e22b88c01fef553c42108f531c265f85bf7d0597d4c9b11465c6d8dccbb0b4b06259af20885458f58924b91edb64778d970a20a64f5f2c16a1736c1a81b350a14dc6f4ce1cc569bc8c197c897f4652c59cc7c9a106a2a4d8b826e057149167f2a30988504212b33322b4988e3987dc514968d4027f16c0440cbc1b4b48c18c974f8b20b6e5605d650c2c9b7e594665ba42ab96a4cd287a76e1e05f64c542e4753b2b8a7ac2eb52bd637ef9d50b4f077cea215859babbb2ec105ff5b5c37c0f5ed41b1e71a22f59922dba1d9e004a93dc69215669f530a04e45a878f14df4885be6d2ab820890c35c63061cc2f2582f575c364bf490e9365f6666a5247c950d7aadbe9bc3ee7638fdb981e574c9cf5960cb1c9fd504b6cc347c6a30bd6803cf99e003aa588caba4969b4329010c3ff6762a9ef273e6170ad64b4dcd9488c4e152d3d78aa5d91258e991e1228273372f5a4a01cb815ac2b69ef370838f28c50d82867761556f04c5d5d21abde15784dc486dab0d593069bc2401be13a7945821e2a18de2c331b9a8304613a181ac5a5ed121e0739994fa9b060c1411b261771a1321b62a614972a502a58b712c594b16ae82955817781dc858d645b354bb37e9835de8029b5ed9c430f7103857b25b888fa4bb7e36b30aa3a93d18b158a6365d598546eb025c7d7aa722b0494781c9d29121e071ab4ab73f86eb1d8aac4d5e66375d868ac6a6060f36b2a80730b541895e32c8b68882d945ae32d115e70a7e61f1c9c6945b9eac226ea551781a1bd48208a9e36d12915b69d04c278897ec79c7891a4bd44530d78b63c92640a0e07576322825998166817689799e070b2fcc7780acc596c42786fbebc5356185b008589f7363d863cc934446dd12420e6c5291a66eb2d2964860867e75349ba9999fe4be93262a08f868abb10652b51bd1c67c266156eda768e30b0c82f910eb96062177a882435c74353dda7279f2141d23a6440b900a8a476c66993477b999e23b40ede83b1e31781b4303e4bc5e0220cb0a6409c88aa8238b83d78792c5632751fb0d5246ca42fc89ce31a64069560bb87360bc2696e78062600f24db78ab630079a64c87900d4b7c9ef9201822b6bdbc69c6be718c3b2792ea32756e1a465325a763dba22861a423e65458272e77400375aab4dbf30d564a176613c264631d33f37cea0346e71649d1314862bb0d2b05711cf1af088a4c619048a7242d0be6a8b536c41a9368b22288ecd0ac7298335e5c91db419c2126a8df45b2e6d8793da63fc7e94d75d3bca2aa58f5b5bee0b43a462a12c34b93f68952b6e7abd89c97c293b0693192a44c0d4e69245e14983e87aa26da8c63517f58d66ae1610936e6a89dca87b6c70c1a78c66743b89b3c2eb854067ad97d74771f77b0906a9a7e78640de75a7b8273851dc55dece9b1941cca76cb2dac265e487585780928dfe7402710b6bd914d564568d3d4075e4141749990c40214ea51b71f855deb9349dae2108843b5cd9815f1e8458c020fadc1c65796b117f8b9851776e896891dc05aa0095a914457016172a17624a608cd49db55a42bcea68778a26a910eb566a2d942da58a4cea53ea7a67954b085eaf642405b1674309b68cb9bc3c04d67505d861a605bd6163f7cb49fb8cdcd40917bd59b94892459fa7ea64a4872f51b97e66e64f02818520164e20d5f952a3266840b4575fdb7625d07d00486bd433447d5e1abfa65b215e034aca74670d4b7ff61c36ac2a1628a20d79b352d1c82c1626233ba527967302131bc1ca837d9eb4238404a20a515fe98a9e6d9b34ec28f0b252263fc2bffaba508a6375aba51b4a36af23740d2d51705b2a1083b23bf5a6b75a214dfcba5eabb82faf49e4d326d369cab0f74c00bd54310a3620d570eee533a1a89a51a418a3cd14b25244f0c66c8e8e454e358364fab5997170a90a25f3816aa1b272b09e54435ab3096e8161926299acccae3d689eafcc7e220cc42f5a347173ec4c2510da02c3b4526d75c9b01d103b8914e41b03865e16be770a0e642251dc312cd10aecc6a9734ccc815da2bef09cd18c3a8ad6c0f90574f41075cef470039a62891ecaab5f033fcd4266a510589f7423b4992f488c3cbc450db074fdcc7cfb4a51c08e2359247c1f564cc94383892757a8164c8c985c28e288adffa9c866a6779faa0f0882abf650a4b9c5e0fb36e4e51a6442167aa97c8e25ba55a3b5d7f164f07b2917f57b16b751ac08167ae88cefa14668e7634d05865d1ea24d1013e1b270c9ee9164d18654646bbae973745e64f90e69064f38fe5744a6343ca04b1a05293c5dea9ceadcab0b1f07ca177cafff03d582b123bec8cd829aae8d7cba9f91d4c89cf9e9b52038638f54721f23c6b341419eba880368782d1a0990f57211bf31012148d74451ae1e79850b75d6efa172744cc6d77a46dd0272924bccef49053198b87e1ac122a0753950586d14c6b22bc12939f0661638b5191e6dc2ffaa147dac984cd004d6dcb637bb18b2f04c115f98cadfa79f64e6253cab64110a71d94db5762f8cb4d277e03b2435a473d60b193ed2646f4c5e157ff4357d3c26b7c4b45315f0689f135c85d952a64648b0a8cec03741fe04f797c007e4061f95c7d56cfc7ee5c49e849dde3fea8f25e7876df2a18515c34" +}, +{ + "dz" : "527fb88c8bd9a4d6031dad15e63878abd2b559e7e08d61f69e8e78fca964ee6ae32d432b4f9f751bde0496c580a181ffed762aa35454a02d3f1f47ee0394c89c", + "pk" : "345881ab11467fe9883654870f7266d76755b0a368661001e627587ba42a2ffc1e2c90b154bb61c2cc3d82a3588d4004d112534f787858d23e8a182971229bb2bc77809a1b118137fb91bb09d2b39dc77773e291fbe2cfe8fa2cd4882379f9471a190f34018c5819ac4eaba7a4a24c703c8876f321267b3eaa58a90cb0271208c6631a773021b3960c14605b5e24b01c2e3c9b2196499dfa69d6a76f0551907cc79611bcbca6b1500d50854f719761a59e8bfac4d5b27a54791482ac5426f73b906631e784c3be822599bba514540efe6a7c13440ae97844a6c73ceb51c471f8014fe51fa94b271bf3206f56abfec55ed7002c27a9250fbc12c9f328ea63b3a2375ecd35634bbba0a4a0619d4571ebc7868faab83c6180dc3c129e8596ede2b64762ca7670282daa233620445bd64a44f5c395a212a088165fd16fc69c503a33b8689217ec00a738f74210d074dc3706e9a412b7982a3e0804458560ace39b54c114f8dcbeb9a1512eea2d8636bdb91c15653926b0fcab1978a02ef694086c062f097c32c9445606050e454a5ec2a43d5cb2704049eabba1933ab857acc1527c254b35cbf6fb4e267b567ca2a125b1552d1c83f408b12420b0b10c2e0aa430f695af478c9d1c54406bf400170a84c4c52e9657c1b4eb652938b4a281a809851a5f62ccf930a56b5588f6fc64b6fabc62b6a62795b3372637bd641bc55c76df070288678012247d11b09118c43fba2536f5daab402377791c906e4cbdd5291ec81a1e71a3a696c0165aa1adfb978be46a8fa5cc7c8ee30036c085888bac3797a1f189cc4035658ccaadc61432141b67bc09ce04685dae806c681729e71b62dcc56449101401d967157c093a8a2b442c3af483408791769bf7ce8910ca4f4724ffc93647375e702bacb559c11fb18b1d4a5371fa4bcc603c22254cdf2654b2873cf9e03591f4173e6a4cf86aa30e9480d49215ab503b2cf6bf42c4b314c7595c907bd4526569b3122234b9e27259619b520412b43b892a6770cc32c6c276a391a106959560687c9620d8d1a60a093f9982a46bb9365d611a86d064f3f82d81ba5c3a39578ea4583b8882efdb5e0b3517be2ab82863c68db0336f6a1b9e1777d7139bebd15af3b73e21332d471100a8a8cdc9d926d2d7c23bab39e015c65a072e0409609c0c0607ba94fdba9842146e8524cc6ddbaa3dc3c9153c667d2b4f4a4871ed642fb284c573b1735b24b9f14aa72f316d3e8b1d8bb415e28a895a7a55e5043eebb04dad9a1d7d2ca9c1973bbc485400b8bc3e897d9d977be1d6cd7d93607a123e43b56b55189586703bbb505185f167d9e24d1c1248a4bc4a98b9332666afaea93aab55b09cc95e8691872c48b3594a1930d82917823362dc6e5ca19094526c462b52d8c842183b214f710908369e9e1599c8e43ea7d890a7e5a8caa6953d774a2e6a1efb1529411228d3637f1b28437c0773a719cc85681cff772ef05b3bbe5753fa2aa5e414bdb599384fb6462565bb04da4c84e550b20163928c9673427b5d57864cd0ba25065246d3914338cc9be47b2ddb2d18888ff99a087d0012b789cc3d6c0c2d93567f7a4c87f1382c4c5ea6d084e524b82eab586ad8c8b05c9af5971a56a31f2b73ab45392bf60b762c5543dc3a259dd67fccec3ed3654c6559", + "sk" : "9c6b1557d747fbab1da3d8bc22301b37e5a5850c9e482850601c129a909da97a9090840efc118a287b19ed091e4f39b7657853502b4322b687a28532f6620bdca934361b1a5dbb0e9af71caf65280e6aba338ab888cc80cde458720ba6146c39a22bc2c8f9cb0078a54031614d60cc9c91c319e3241fdb73a78c4b5715b0cf9620e0449c8c67493a987659c19e8e9b6e2ed12ee5dc876de75589cc6d4294b40a0463d0a4899dd54a60ccbaf545166d693ce6ba3e073c63757ac06a9aa2e5e93385b9723eb339155c1e3a043779b193af883b91f78da091358c2c2dd7db9086598546c6886d1bc611c3b586a3304a473fff62371af33142b1a212236e63351903a652261093ee44209c72bcd1db9cefd7866b15b6c434c654048ca845ab31c65e93d00288c6563e35080522415e42a9d5d749f308c36c860fdbe004f6c38bbf15cfe728a2806c10af833972a6558fc204f052cfbed8b1f8649951e44949720364f752b4910616e57603342953e47f0046af76867c98fa0ecde6680b14bc14ea34569ab583c86c8f3b1af9f5ba2ec68935729f0e03844976a8c5b965f56660e60b2b93d838d3697b86d6cf3e8aa0bd6865dac093966a0793030be6a03bc9e472354471b367a27ed30e129a336df19114cba8ab99571299128b323721703bd11649fc371aeb1867c5079fe04b169501cee5b2a54f14884c5ac1b42588c5ba090382320ac8233bcc442ba2bcf9ec34446a716bf34f1c183a8829b22216855107bf6e9218d26010e63a72316cc5dd8994c4817880d4144a26a0967a25d0a82546098c6c55ba8078c0bed3bb91b5b2cb10c95b464852d7973dfbca7f6396dee46984f220431cbc969b0482453ff729ce625a3498ab299239465fa79b2d50c0cff698d2e4cff7b3182b88acc0785c69b406a3dc9504840a2a744dfcc29a99458f74b3ccdb753ef2e83065111c41052c539c83d1ac049d215ea5291110287e80977e3f578fc6dcba985327dea382c3bb9561444f64232137624e32703cc4cc12c63ba5d3ab496b7b493c1000858b8dd51368f1458d255ac57d829928dc2a0707660df753aa9c1b868703bf69013cd15f17a38496e51d63aacec4f594cff35dd027764a56b2751080d3d76b91da373636cba86395b992a7ce972c5e1101ed43176f5a5ba68801d0763762b92e499110648697389b98c5586bf69356b4623647cb0d1366b0804166299c4dd1ba0f29bbbb5dd393c40cc03967919cc32c62d6bdf9138e6b45184d445ae94825ae092df33caefb2b737e9a23f58126a6c52780e48f5ff7a14a7b255c9a474c752d9de424ccd4a8a05c79164779b8b452f3245926e2538f7299186259678298749412e96b444370bc583ac4a4d43dc7e1329d9630a7b3a79b0cc673789ee0d8026c93c17097cb83d515cecba69b13783fe1bf72338846c955b7b1af27128f0c1a2dfd0018def1c24fb16c29d326129213d831728acc4cf339cbb6d2a7ddc8b0eed4cec8850750bbb740ca89180b224721648f44a8cccbba6c2538006bc38fa34a04053dba971f165c5003d70bf9c0b7f7578d03093a3d496a0e9242b0c23a92788b668b1abe421080770078f97118e7c35dd589ce1ac805d953345881ab11467fe9883654870f7266d76755b0a368661001e627587ba42a2ffc1e2c90b154bb61c2cc3d82a3588d4004d112534f787858d23e8a182971229bb2bc77809a1b118137fb91bb09d2b39dc77773e291fbe2cfe8fa2cd4882379f9471a190f34018c5819ac4eaba7a4a24c703c8876f321267b3eaa58a90cb0271208c6631a773021b3960c14605b5e24b01c2e3c9b2196499dfa69d6a76f0551907cc79611bcbca6b1500d50854f719761a59e8bfac4d5b27a54791482ac5426f73b906631e784c3be822599bba514540efe6a7c13440ae97844a6c73ceb51c471f8014fe51fa94b271bf3206f56abfec55ed7002c27a9250fbc12c9f328ea63b3a2375ecd35634bbba0a4a0619d4571ebc7868faab83c6180dc3c129e8596ede2b64762ca7670282daa233620445bd64a44f5c395a212a088165fd16fc69c503a33b8689217ec00a738f74210d074dc3706e9a412b7982a3e0804458560ace39b54c114f8dcbeb9a1512eea2d8636bdb91c15653926b0fcab1978a02ef694086c062f097c32c9445606050e454a5ec2a43d5cb2704049eabba1933ab857acc1527c254b35cbf6fb4e267b567ca2a125b1552d1c83f408b12420b0b10c2e0aa430f695af478c9d1c54406bf400170a84c4c52e9657c1b4eb652938b4a281a809851a5f62ccf930a56b5588f6fc64b6fabc62b6a62795b3372637bd641bc55c76df070288678012247d11b09118c43fba2536f5daab402377791c906e4cbdd5291ec81a1e71a3a696c0165aa1adfb978be46a8fa5cc7c8ee30036c085888bac3797a1f189cc4035658ccaadc61432141b67bc09ce04685dae806c681729e71b62dcc56449101401d967157c093a8a2b442c3af483408791769bf7ce8910ca4f4724ffc93647375e702bacb559c11fb18b1d4a5371fa4bcc603c22254cdf2654b2873cf9e03591f4173e6a4cf86aa30e9480d49215ab503b2cf6bf42c4b314c7595c907bd4526569b3122234b9e27259619b520412b43b892a6770cc32c6c276a391a106959560687c9620d8d1a60a093f9982a46bb9365d611a86d064f3f82d81ba5c3a39578ea4583b8882efdb5e0b3517be2ab82863c68db0336f6a1b9e1777d7139bebd15af3b73e21332d471100a8a8cdc9d926d2d7c23bab39e015c65a072e0409609c0c0607ba94fdba9842146e8524cc6ddbaa3dc3c9153c667d2b4f4a4871ed642fb284c573b1735b24b9f14aa72f316d3e8b1d8bb415e28a895a7a55e5043eebb04dad9a1d7d2ca9c1973bbc485400b8bc3e897d9d977be1d6cd7d93607a123e43b56b55189586703bbb505185f167d9e24d1c1248a4bc4a98b9332666afaea93aab55b09cc95e8691872c48b3594a1930d82917823362dc6e5ca19094526c462b52d8c842183b214f710908369e9e1599c8e43ea7d890a7e5a8caa6953d774a2e6a1efb1529411228d3637f1b28437c0773a719cc85681cff772ef05b3bbe5753fa2aa5e414bdb599384fb6462565bb04da4c84e550b20163928c9673427b5d57864cd0ba25065246d3914338cc9be47b2ddb2d18888ff99a087d0012b789cc3d6c0c2d93567f7a4c87f1382c4c5ea6d084e524b82eab586ad8c8b05c9af5971a56a31f2b73ab45392bf60b762c5543dc3a259dd67fccec3ed3654c6559f5cedd022077b1a6a052f5287219393cd2e0366d0f5531b2f7ea8704d2900ce5e32d432b4f9f751bde0496c580a181ffed762aa35454a02d3f1f47ee0394c89c" +}, +{ + "dz" : "ac6fcfaeeef795b6ef9e062f02bf42975fa01e7d91ba832f74e05269a72684d05aeda108ea4d6c6bc0fb958286850422bc357ca67b83c986048e0d0087fa11ec", + "pk" : "2695adfcf444770c6ffab16e9211abf5d019e1471b843a3e7a38b5ce109a0a6796a0d822a926756f0c4a0fa03f53200d6cf37a1cb741f10219102b63425063d6a910b2fc574c49067a1a40e22ccb754926481b7f0ad0111943b3e67a570f0bc269aa50de26cb5f3507791b757370517d486d7a55a88ce86b42856705f6a7a48a8892e96ff20c304e74271e0b555c1b4b0d065a50d61bb2813cc3723009179dd2b4c37a0a06b2099c2aa0c4d256a2fe2042bf4b3db91b11028275b33b4484f2ccb9971df29703dd61c17dbc0319ac63d16080f5b5c460149ef751933ab60142404b66690a2c10a6e3aaa186f6c7e130577cb02ef4e043a6d4ab22ba85b5396a4d61aa1528becc59a1843a4d70283cd2f91457762ef34424b934be9a1547dbfbbcde21552f968c2c8692475632e78ab3d7330619e74d8c71bf3797844c717e70b51367963a7cd3c4869a85ddd213a8d34b788239056544692a7741124697d237d7e2677a908358d81da2cbacefdc511d3110e1152bf2d036c4593a0512523f80a26620ab1cd8b6b1d99a08f25ae3121713ac070833c544e42acfbb78d86476743923d7310c5a4238cce27773d3989d598affe6650c1166ad4ba0e034ccbbb5a75d69b113f2a1952a2cc6980c58ca6da32718e4484d562ac700d924545b6cef439234980611c99e69706054981349041e1962b272c4b0b8b416569952e4f98d4bb12de6a13bc1c903c5477b0ffaa1c0dcbd8e4abd4670832eba3d43d9c31147aa803c17bb32c65e3c350520297da9cdd6dca30ca025e85a051af5aa82d231c159a5026a0e8f2c16769105baf7708fab822b1777c6c53137ba11298ccc15d522400b7f85430de739514c90453ba97d9359807568417ea307abb8982707b7519a65b116466e984772f87a6346ac808c7b2cd22f08aba151e79ad8e45925d29294879a9dc00f60713e33091c42bc3ab24b65b488c764ec75b4117dde39ada784835d3129cbd7b777b1b69cc3293f07ade724639b761ca598464e6676e216874c9668b19aba660974c9918d52761acfa325031835b4d44b42fb91e431373781a2f60354e837458e69a89d830e00801178ba697f82a3a914345ecc1b5cb4b3357b6b7d41b708c5a7e4f862c44c8ffa90473495b70607386c02b4f0261e197124de180cc793355135bdf37cb36b9a180dacc2f6b09efd80cf35211a0371c59f396cd9ec226e1126d69a6ab8441faae9a1cbd18e17387ca0333f94acc7e35306a8b05f4dd185fc467e5e888159a50c6c9a51ca6b2deb9ba212822020d67552d4317449b51b21c37348c44e3880367574d5c195db588ad0189a80756eda780dda9a7d3c946b10d897ab8bb40d6441179b1b0d58271ea83000c5ad56175a23d20322d516b2a487c74a64eb3514c93b919d65cedf429bd37515fff66f4d72cee39a0081452f791b8054660da44937c4a443a09727ca5198322c341c12413c19b6075bb9118540bdc105313422cf9b8fa687540af66728fa9859a642bb9479b31257912cb5e0046dc9273199f27f4f3665aee6a7bdd19e0ab8baf1d2a868b465aef75f3ceb916c82bd81791e80158f8e5b358c218305d96a683a19c930c1903b5e0a4b15ccd8ad0b9e61da304ad616af46073a781ed8d08060c1678f48941d67b3685a39ee7491", + "sk" : "29013c0db356adc444062a6955267cbb8132d72a58bb1b34ecb955795ba52f1624694741fe3c646e734c2462547a72553c51559c2c88830b1cd43089e924080807b4daa964bb85cd5cbc56edea257ec59b9c808bb66835fee1ada8fab7db67268ddb23454680d3a7245be4917a1abeefd809d7906c1b8a4dfad2160313ab7c69cba472bef251c7e1e1ce8771c1c30b7db129b8a8140aae05780664ce800600dbc8ba42e1b4ae629424735b57529f35f9abaca9054ae346c9928a3ff7884485195d02369d046dd68a7129197cc91c3a911c0cc361c9b8fc44c0ac8d98c8a18b185b9e174bdca360f589343f9509121b7b3c8046f4d8086d471b5f1b3e20c6296936a2e78583640590d52aafb321a23215546309676dc84c445ab78bb5660137a50c97aa05b7b004e396619b632e855d80c6cde8973c055c65b7a06a90421e8ce484495820d9a66f878a19e8e1bbbbf86437545a5ddc4326e400c384ce96c4698f628f9703be9aa7181a361739f7701700c47eab9f1b805d86450094c76445413fd57b20d9794aac17b1ef33186a345351c851657a9ee61463f0e912dfd8ae113a378bb51bdf5b918b6344fd74c573430259b2b18f37ce9af0bcbe3807a0d94626dac6a22c4e31f3bae1eab69f768dd4a68405290566e20ed156b5ac5a73b1c08e64e68df973b9dc8692bbcb17692c496817bb1f0465cddc6ad25903bcea873ffbc9d8472487a92c8ce7148c25288d9687532035b81b584494524f796f99904c0bfa402fe265bb7aa143a0329f4a199692472f25b2b59a3a845654a88b9356526c25a740f39c3476020b99a601b41831cd832e3053a90b5cb4de61142f65b2a2babd9a45618036af6ba54c9a2b093cfb5bd7426056e09e6771af41d607cb9375846a4952ecc3a991225db49b31753f0839967ac9319b6c5d23a6365970a3fc4497cdf793196b6c9ad5280b949c825599b5d312b2f484939b960caa2696d26789f09b4d2ccf211cb3bc580acc4b0126380a6da109ef86385640667196a2c135a3fdd780d34513c0d35f78836d0f811945b7b617c024ba5aac93438397f216a4520213c036fdc81957630236323a56c72562236be7f127653269c2a6248357b134973ca90a100618279b1306907a9076f05e46a716cf79882707c942dac8200baf3a454d8e74258682313ce3252fd7a602a3114bdc50e33b29f18acea7180226532288ab678d4c6dc60a58366a61d6b124e247a39b24ba960b39a2da80637c9cf5838cbc5a5b7c1b7fc7e16777c9cdd1460c9eb32f1da32cad0c2437e3aa59f0020a106b06113f5e896730962d1efacb72084df7475eab9cb467ecc1f41177b644c9a68a961ea65d2323628e558d6b03abb2f5491c7c36244a3ba56191eff6ae71496da7372c5e1500e22a7796b2aff8856d75d3278b5117fbc42c71743bf7f24c78b76e3ea45ee2487a8f2899f2127d687b1f8dc579c2ea811d3c50d60c85f6e66457d88f91a63ab1ebc98a0b2167262700d35201975091b9ba30120c6eeca45992376a200d161a234be0c93b68661da9cf44a01071a8614dac8906d39eb475312b0c2e998ca7ab67bc77387e5b6cc8aec14d7ea894809c54e10649325881a89b132695adfcf444770c6ffab16e9211abf5d019e1471b843a3e7a38b5ce109a0a6796a0d822a926756f0c4a0fa03f53200d6cf37a1cb741f10219102b63425063d6a910b2fc574c49067a1a40e22ccb754926481b7f0ad0111943b3e67a570f0bc269aa50de26cb5f3507791b757370517d486d7a55a88ce86b42856705f6a7a48a8892e96ff20c304e74271e0b555c1b4b0d065a50d61bb2813cc3723009179dd2b4c37a0a06b2099c2aa0c4d256a2fe2042bf4b3db91b11028275b33b4484f2ccb9971df29703dd61c17dbc0319ac63d16080f5b5c460149ef751933ab60142404b66690a2c10a6e3aaa186f6c7e130577cb02ef4e043a6d4ab22ba85b5396a4d61aa1528becc59a1843a4d70283cd2f91457762ef34424b934be9a1547dbfbbcde21552f968c2c8692475632e78ab3d7330619e74d8c71bf3797844c717e70b51367963a7cd3c4869a85ddd213a8d34b788239056544692a7741124697d237d7e2677a908358d81da2cbacefdc511d3110e1152bf2d036c4593a0512523f80a26620ab1cd8b6b1d99a08f25ae3121713ac070833c544e42acfbb78d86476743923d7310c5a4238cce27773d3989d598affe6650c1166ad4ba0e034ccbbb5a75d69b113f2a1952a2cc6980c58ca6da32718e4484d562ac700d924545b6cef439234980611c99e69706054981349041e1962b272c4b0b8b416569952e4f98d4bb12de6a13bc1c903c5477b0ffaa1c0dcbd8e4abd4670832eba3d43d9c31147aa803c17bb32c65e3c350520297da9cdd6dca30ca025e85a051af5aa82d231c159a5026a0e8f2c16769105baf7708fab822b1777c6c53137ba11298ccc15d522400b7f85430de739514c90453ba97d9359807568417ea307abb8982707b7519a65b116466e984772f87a6346ac808c7b2cd22f08aba151e79ad8e45925d29294879a9dc00f60713e33091c42bc3ab24b65b488c764ec75b4117dde39ada784835d3129cbd7b777b1b69cc3293f07ade724639b761ca598464e6676e216874c9668b19aba660974c9918d52761acfa325031835b4d44b42fb91e431373781a2f60354e837458e69a89d830e00801178ba697f82a3a914345ecc1b5cb4b3357b6b7d41b708c5a7e4f862c44c8ffa90473495b70607386c02b4f0261e197124de180cc793355135bdf37cb36b9a180dacc2f6b09efd80cf35211a0371c59f396cd9ec226e1126d69a6ab8441faae9a1cbd18e17387ca0333f94acc7e35306a8b05f4dd185fc467e5e888159a50c6c9a51ca6b2deb9ba212822020d67552d4317449b51b21c37348c44e3880367574d5c195db588ad0189a80756eda780dda9a7d3c946b10d897ab8bb40d6441179b1b0d58271ea83000c5ad56175a23d20322d516b2a487c74a64eb3514c93b919d65cedf429bd37515fff66f4d72cee39a0081452f791b8054660da44937c4a443a09727ca5198322c341c12413c19b6075bb9118540bdc105313422cf9b8fa687540af66728fa9859a642bb9479b31257912cb5e0046dc9273199f27f4f3665aee6a7bdd19e0ab8baf1d2a868b465aef75f3ceb916c82bd81791e80158f8e5b358c218305d96a683a19c930c1903b5e0a4b15ccd8ad0b9e61da304ad616af46073a781ed8d08060c1678f48941d67b3685a39ee7491a53a20ea03e400a843c8cf4d04bfe0c0a3ce63dde01045e2669f7ae5da7905775aeda108ea4d6c6bc0fb958286850422bc357ca67b83c986048e0d0087fa11ec" +}, +{ + "dz" : "ba2fb9318d4dbe7488057c33e95e6f054583a2800c41bb83083c330a914a12cfe63f8ffda3565c2424c89b20974b748a65a5aba75133fcb3156dfb6626a83bab", + "pk" : "09abaa56083952c0c1b6ec9a50251f3c16859c2c91c0076750016ad3ec36c42941af9c13e4086b37f5373cd29ef4d46d6179c948eac2738bcb765bbc58c8c0fc206a4e30267ed62537dc5202c5a717926744b296b2983b8291495161c920cc1258f209640549e5e7cbbe13ba52b762c6767c92a95678e066631b57e256880ae56189b699691999fa294b71135a7537202e8873d2653eacabba9d3082a5f01353b77da1cb4220301b84a14848b94d68309c6a29035e7cbf083bce5e659c0a226274e8534f61021d1743bf66525aa7c62759c9ea85155e139a9cc20f6b0776d567a8f1e697b97ca60982555c0197bae535a0d20ebd00a7774550e928647c40598d16a45da0810399cf38865ceb5c2ed7623ae9f55987fa37cce79aae79030f8c3b90898f758366f7f591452c77ea7c3203c147e591304138568d2257d07689865447179c017b0560b3165673526981c65858e842d913a9c22c0a9aac9fa4e16ea6b128b0bc99ff863b3f40b2819ab2e8a04cb353c7ecb2409e495e617a410e638bcb370b2c887b8adab2b9f95e8e922baacb1d148610cc4748cbf31b88da477029ca130b152dd923bd7796d0128aec6706c204ada1b37dc0149a7c318d8356a4f8c9cf917443fef20b02096579580d82bb8659b18365ba3347b081f42b17c3e2064a441b1a3a876c26060d22c370f82424e9b156145e93894de3ca09e4fa8ba6524eb9ea94980a038b257fb4da57d4c8b40ae5465a3a9c7169ccd30b13295546846a6bdcf13c3230b5a961b1ecf578abfa8bac3542820053717baae30a545261b873f278cefb73edf8cb73b9272dd7552e381da64c055470c199bab07cdc3293c0577d9acd9d9063b536412ac7cdee30a1dcfb6e25dbcedd5425508a1091555998931326fa69c78b5021f818f8a55deee77db38229b4104980c230dbb872cd671fe776a09be47852204c6a339126e3bac2353d36c094506092aa597449241121332900a69f8ba1b79ec56f047cbbfbd6bb2aa08f6e606d54c72cbb758357e49b937590a1191d88ba26ca576ecd320caa1bcbff8533695aa486d222b5749bc8f4297bb7938d5b4cb4f46d6ee701a35a287dc16f7dc1347ee97830ec69cdaa91ee061d3f0c81bdc695cd6939ae56be11681847629ea555747c664b5e111a9ac5159281438729916d45b8f0d3ad0e0514619ca93a8a971e9433c9eaa731192c760c5c5e32259f569dcdf39bba4c1b7269bd98417abfb1521fcbb640030563118e0f35bbfd0665023863e275c7d5319a1087bb2f956d2dd3ade6c37aa09c36cd5aa9ed09b8999c4473665ae2b784197cc9268c57bfb78dfb054bd1278e044582cc3c81c547c50fe7bfc270bf6aba9fc159a5853045af3758a8d552c3881d7c2879dbbb0b79b5a5c2300b5a380ecd199e3309251f9647598b7376290452a575f4ea7071f2a0ebb7b3dd9057350abbc1707e25d0b68d734689f0ac4c9b3242fb703ea6bb7fc064e599ce8f9269a0d63a719879ac8c396d79221babb2c4a0b7d38ac5b7e984f2212c481a353ba6bd95039443658eeab625d3d00faff2509a2c208afbc6016bb5d8726dc74993ad329bb9a554bf61209cc20e521b628d9c89c8fa687eb7464ac51820225b65b2af8489ed896d11825bc4df67f7002453d16875ce21ccf49b", + "sk" : "ba593157e38d7e6735b6159ad0338a4f35cad3b7ae7e79c024b4b913a313d95059e2ac7273692ee4d6217090c1774b4ca473b09214a81a374e5d5350b51c4f52376e3c7a1622cbaa2226965afbcecf5b499ff7220d572db7d7916989cdd4d2ace6cc3a40949b02c52fceeb941ff6b6d2713de078753aa73836d72abfa96ddf790f0b8243c48247abe779db1bcd5ce01bfa061fe1b5436ae7cd7b7a3a65971e35360ac52b9c5b7214478c46f5864948d20396387333d7615f872bb94b0e7d71b2f831a2d30870feb190f42771f1f1b73ed88adf6bb732a1c159147aca38950060394cf04e7150308897b3b76706a17695943500e589b10b348bec1335cce863bf68ba50019c6d072e9a2aaebef070a7d65d5d2a8bc285b22dc91915008e2854a9b408a5e1f847fa492670eab6905a6367528efaf08a688cbc6fc86672e599c3d5ade10a4a92942d5705a03e881eda311cda81982e6aba55f29cfa835b6b19a7e0c39b48939344c1caa5882a7aa86721cb5674a14e62cb613f115e0cc36792467a7dd5701543898ce06223fb505ba4503192747d4295fb57508446c927b1c8378a96b4a56243d257c89993447cc183db3f6db7b8606c21536c01eaf14a7f2931da629365a0b1df157bb60424312155a8e80d049b66e9e134006c64bef8ad0b5a33fe857de7d244b4cc2f0d29a8d50c118540772eca4517712b4aca18f64c758e6698f701804cf0821c178d6d7ba43c2c694e8b4a8a356a8c26894de30658917bbc6331a6e77e6a327aac4ba2b19b02a79484ebf90cc2a235a8737802f7b71e6731f358156232a913b63ba94b932581162b622699659f66c984155187ffe53d8d6a3ee4d84e3b190088e001b3f3aca703a39551bee2a852aa4656f355b05b28194dc025ebca70ef90a47e96049f441082861ba5e563080b27035aaa0ac761c66b6b11978c18d1431d25ce69a6373d869d8ecc72b47550dd901aed51915e61acd36c50cda5ce545b7b3293263ae13880879bf96b7c6915074d46c636f4522f340b993cafd07c91fd646893dca37eda658dbbb52a3211a4e09dc20240a3f8c606a7b095715e5af180167b5807e3b414f69ec28874398b464e08254a60cd9b693b36643d82996ae2c82b8d26bacf106879091500b6a289c4c1a0a7b9c872865498bb2a40455e0ba3b6570a804204afd3942ee6b4169b8842508b9f6a5c1883a3ec98bd8119b147671003472ce1905981326b5057a6ad026843d323cc0593a132114d70cd030aa979d639bf22bcb286c13902cfdeb0beec163f8ab3c377d211b6d502ccc41137db92cdaca20ce5b83c2baa93d5c063db6d419537a7597d03a91f9d214869ca00ae46cab450ce11591cff53610053c3dacc5901a43959e55cc2751f792ac5ed288402782dfa4912989032295b967e4145d7046e76f4079338bc26d4c9f88203ee1412683899ddc534ac37608a6959efc72d7e24582fc9629a20059fb382e5891c85091de6c2600c98c58ea8205d2574c25c9c0d17809ef40d1db44e8ea895c40c8aa2448a6655442f0bb7a160aa8df8ba5faaaee0c19d16dc4d267279c0bba589972948f7c198e8cec71569e9863f968cb5df387c6a350a81f32ad9797c09abaa56083952c0c1b6ec9a50251f3c16859c2c91c0076750016ad3ec36c42941af9c13e4086b37f5373cd29ef4d46d6179c948eac2738bcb765bbc58c8c0fc206a4e30267ed62537dc5202c5a717926744b296b2983b8291495161c920cc1258f209640549e5e7cbbe13ba52b762c6767c92a95678e066631b57e256880ae56189b699691999fa294b71135a7537202e8873d2653eacabba9d3082a5f01353b77da1cb4220301b84a14848b94d68309c6a29035e7cbf083bce5e659c0a226274e8534f61021d1743bf66525aa7c62759c9ea85155e139a9cc20f6b0776d567a8f1e697b97ca60982555c0197bae535a0d20ebd00a7774550e928647c40598d16a45da0810399cf38865ceb5c2ed7623ae9f55987fa37cce79aae79030f8c3b90898f758366f7f591452c77ea7c3203c147e591304138568d2257d07689865447179c017b0560b3165673526981c65858e842d913a9c22c0a9aac9fa4e16ea6b128b0bc99ff863b3f40b2819ab2e8a04cb353c7ecb2409e495e617a410e638bcb370b2c887b8adab2b9f95e8e922baacb1d148610cc4748cbf31b88da477029ca130b152dd923bd7796d0128aec6706c204ada1b37dc0149a7c318d8356a4f8c9cf917443fef20b02096579580d82bb8659b18365ba3347b081f42b17c3e2064a441b1a3a876c26060d22c370f82424e9b156145e93894de3ca09e4fa8ba6524eb9ea94980a038b257fb4da57d4c8b40ae5465a3a9c7169ccd30b13295546846a6bdcf13c3230b5a961b1ecf578abfa8bac3542820053717baae30a545261b873f278cefb73edf8cb73b9272dd7552e381da64c055470c199bab07cdc3293c0577d9acd9d9063b536412ac7cdee30a1dcfb6e25dbcedd5425508a1091555998931326fa69c78b5021f818f8a55deee77db38229b4104980c230dbb872cd671fe776a09be47852204c6a339126e3bac2353d36c094506092aa597449241121332900a69f8ba1b79ec56f047cbbfbd6bb2aa08f6e606d54c72cbb758357e49b937590a1191d88ba26ca576ecd320caa1bcbff8533695aa486d222b5749bc8f4297bb7938d5b4cb4f46d6ee701a35a287dc16f7dc1347ee97830ec69cdaa91ee061d3f0c81bdc695cd6939ae56be11681847629ea555747c664b5e111a9ac5159281438729916d45b8f0d3ad0e0514619ca93a8a971e9433c9eaa731192c760c5c5e32259f569dcdf39bba4c1b7269bd98417abfb1521fcbb640030563118e0f35bbfd0665023863e275c7d5319a1087bb2f956d2dd3ade6c37aa09c36cd5aa9ed09b8999c4473665ae2b784197cc9268c57bfb78dfb054bd1278e044582cc3c81c547c50fe7bfc270bf6aba9fc159a5853045af3758a8d552c3881d7c2879dbbb0b79b5a5c2300b5a380ecd199e3309251f9647598b7376290452a575f4ea7071f2a0ebb7b3dd9057350abbc1707e25d0b68d734689f0ac4c9b3242fb703ea6bb7fc064e599ce8f9269a0d63a719879ac8c396d79221babb2c4a0b7d38ac5b7e984f2212c481a353ba6bd95039443658eeab625d3d00faff2509a2c208afbc6016bb5d8726dc74993ad329bb9a554bf61209cc20e521b628d9c89c8fa687eb7464ac51820225b65b2af8489ed896d11825bc4df67f7002453d16875ce21ccf49bcacca228846450ebb8f04a2a5ef2d919dfa47c4aa265f4cedd10cf74eef3ecc1e63f8ffda3565c2424c89b20974b748a65a5aba75133fcb3156dfb6626a83bab" +}, +{ + "dz" : "aa6dd1e5799cdf7af9c4fc632b3eb9d51d66e85c8e0a21ec98664fc51ab63c7dfda268813efab5204efa60f78bf81d320d01ac09ac06244f7afbd2d80fd356d9", + "pk" : "9734408c884e736a271a17a9a5829a56e4ad6fd90402c18327f4b5b052a5d72585ad276a52228ea0794d4ae19235304674705176f76e909792b32b3f45f3c179464daa653c4885346b0921f72a2e186210542575e7abcc210bb7572c5ba97c475d8ba2810c54b9f23988725dd17967e9764513e1a34e55a9e32b05bd6a030425250a285fb331351ba4470eb2380318c9c7a56ed0664c6a16af63db6dc2a7c1c4e5a901c89ff7a589c099568c9bbb0482b04205595c242c66d99725a17468684b2be16b2757760b72a57974549c44c17bd2aa028a2c2d74b458c2bac3d34537ba095c34459b58aae4940fb3b68a73b28aca34cb018b92f65320bc3c04008394e17215abeb505b4bcd37d473da43569d557eb34b06eeca22c1264db881a6b37bbe9467899117b602304fdb72aaa60bbdba128214cc87fb980c1be3bcf9348bda62ccfa591328901c9b9851e9f9258e2a5f500053f9266891fc1ddf267c58c1aa7db72255f8c277d8535fe48db1d9b12cd97fde35c837d12f6b1c84e2c019e77469350bcb9c3791af132bf2ebc633f3c681e3801d0ba00a30672e955d84930c4012100c18b7a5a342d226341924034ac0953ce15584911d86c0689fd12d3dc4cb2d8748eec4abecc185ff63162e414e709cc3c5163de7b80e9e550d4a0b90de20b2fca850e3b11338bc3b5c369d616a2b64c764f78122abdb66860103371b773586463ea51366792872f36c53603cd876c4aea446e8811feb4417e3f21b94059f1d3c47584c09b128c549e48f6346cc3fa60ad19cb9b65359f04506cf52994ff5225aa24d68a00bc5171e0a492733e726eff02c2b956f9d6a6e7a8519e2b9c4c90b8db6b5447a0b589cb71cf0b74b899272a966c0b0da3824035c70c334818bcdfa2632e7a47ae8119661b96a6b4b17810a8840cc05bb3a0db2c6a60d10cb3e7ca365576250a380fa4b956ce066e72a0d7739a4b4e317988b64270732ff94c319a368cf0b8d8018a2d210bb37c695032a3b4da71e25e2287ef34ed68b5711ca99af1cc6b83caba7eb91d1f10eff920d9b41091e086487cc438e461344905b7e954121948ab8251fb0044e6cd8075f28b70a67132c8362b71b77298c2200e11b3013b6b2ec8b21e7a23a3cb9456567b3a090fbe642a1693501db47f8c4829d86bb1ae7accdd7763fc0b5e754ca5999a1544615dbb1acda7749c1d89073b130a4823600e322904c9599c31b67c963c307987fabc4e482910b57a56e2417eaf978008c9fa38103c15ab1a811b2b198a5b7201ef767a26a758400469ce0b1ca83920fbcbbc51c8697cc4b687d8ba41d45725551a09e5cb230532760cc15292c4ca9cc77f6e215d70c8f6e98b35fb21c5e0993588c8f76775f92c575c013270c167cddfc76de12261e84c1b506737a7448d00a6d07456fabb620d985607a32526d276846cc739276122bc14cae94543e11276805aedf36c404fc079117196383cef2681074f954249b859498a8ede375663755890613b15c2a8ff25ade0abc4d674a050369a596ac3e446cfc3171600367f89c9251e33db95c508e09a64f683fe7420c5ff73ebe5836ebec9e0ef1a39c02acd90275f5d9af9eab8c741023bc91806d255282846cb5fbcef030ee8e721d0566c29f469f5773938d679dbe17bfd7de66be5e", + "sk" : "632b0098b51f1dc64ab2b096e5ba16867caa3f5621b10c50008939adc17177533cb98244b0bc287309a67ba147c572adae003472437389d957f1d048f4b7c0e8d88469a6a87b771a7bd0a3fd1074f1b29080008fa72c9241e1b7622748d65bc6dd307645419a65fc5ba5d68e66c5ad250897b72c109541422019275b4cabb57a675eb3144be222f417aa85250c773b0689063e89802d6bb4010f4ba0cb57a1c69a5869e5a5508599744321f23496a6a9b8331786ffd2ca9b83b78469089885acc3f46b9f45437ceacf1a9707c394919801bb44f3abcc5a504f466890b15e902b9b97b8197aa19f25a41e0df87eb6b88c0c029aca3534f807837cc2c253a06c375c8728390263a6cb8d240e33c36268d283fe891e8b99bb935a33d15c0c588c82bc2905de885dafda4422e61b43bcc1b8731f1b6a85486988ae392d71aac97d326cd6115e26c23459c74ebf4ac2edc6209933a22e2162da6cca192271517687110c070d6a154a11054421bf8e3a9820f8a77794b3da4931a333928fd37e7c057117fb2f2fe9a19d65907801248a8009d0da2cbf572063ab7bee490f2c930c8ba0709579b9fc11079d48845de37a1af371c6947b12ac4a142250c92c63b7336967ca1797bac7b3a66e5a997672c4431c28a601cc1360689d1cb6304f8cc04f6c3e2f67a2a72746e5221b1d9a6018c4b6f0a6943ae927552968f7877f28cbbc9bcc410afcc780e06d6759aedf4a1b57d7cad7fc89b7b29e03810bd7babc8797768e930dfc3983aaea0a910a359b5c87d088961d529896183627277e707aa88a21096658663cbb756469542e9053f1102a73644d510b69da8b089c73ce4bf4bdc5b72ffcf4cd1c73ce0508393e409eae79c9fbf44b5e36c73d33af7fc9c084c52b3da21a57171eea865efa7c917fe92b52b40e36fc5cd8e961fd207fd7167c7d302137c5841352663a3931e96382966c58c3039e182cb1e0369813bc90312a9ac6026d4f8c24da0445b3687c27a8363d702ab0579bbd3a418fb6af26792bf96281b0373469d96e74803a5658a413f19a43f95e784b91586c14461134811a0c976c25a7b8491514a1ccf83904489585b841884c0ba39046508728dd02a9a3163ec17cb1422c3bd8194f845259952c1bc7da1616748c19e002ab8948bfb00f7b53446bd1138d7b87794423bed453e5a7bb0e915841984bad6cc970f9c95f120855203df5936a8871611ee897f9e050d5a3931c1219f61a8da6d75ba0e85c0a674cc39c583ad01f794b628ae221d9e8aaaada889c43b56602c73ed2cd5fa084c7b207a43360a8c58a3f405bba290b39723b63b10951ecad19dc266d045a49a38857941534f28e775269bab9a381a60e244543b3e26fcbcc0d47575a82da58aca50239da726e0570a8eb3f6714b2fffb9038d42345977fb3156ca1eaab577c0cf4516aeb81bd1f6b92276ac4cd37b67d1b6083e126cc32c91d28c531802e41f707ab740903e5213e2a378397a52793c0b8762d67d846de86520f8745a8112c80f48835a4033ba53ae0e7b43afc44994b13e76663d1e6a2519844ae08536aa055a428af5144be296b43aada192d142ec933546735a6accb4a5a99852ca751c24cae5738a99734408c884e736a271a17a9a5829a56e4ad6fd90402c18327f4b5b052a5d72585ad276a52228ea0794d4ae19235304674705176f76e909792b32b3f45f3c179464daa653c4885346b0921f72a2e186210542575e7abcc210bb7572c5ba97c475d8ba2810c54b9f23988725dd17967e9764513e1a34e55a9e32b05bd6a030425250a285fb331351ba4470eb2380318c9c7a56ed0664c6a16af63db6dc2a7c1c4e5a901c89ff7a589c099568c9bbb0482b04205595c242c66d99725a17468684b2be16b2757760b72a57974549c44c17bd2aa028a2c2d74b458c2bac3d34537ba095c34459b58aae4940fb3b68a73b28aca34cb018b92f65320bc3c04008394e17215abeb505b4bcd37d473da43569d557eb34b06eeca22c1264db881a6b37bbe9467899117b602304fdb72aaa60bbdba128214cc87fb980c1be3bcf9348bda62ccfa591328901c9b9851e9f9258e2a5f500053f9266891fc1ddf267c58c1aa7db72255f8c277d8535fe48db1d9b12cd97fde35c837d12f6b1c84e2c019e77469350bcb9c3791af132bf2ebc633f3c681e3801d0ba00a30672e955d84930c4012100c18b7a5a342d226341924034ac0953ce15584911d86c0689fd12d3dc4cb2d8748eec4abecc185ff63162e414e709cc3c5163de7b80e9e550d4a0b90de20b2fca850e3b11338bc3b5c369d616a2b64c764f78122abdb66860103371b773586463ea51366792872f36c53603cd876c4aea446e8811feb4417e3f21b94059f1d3c47584c09b128c549e48f6346cc3fa60ad19cb9b65359f04506cf52994ff5225aa24d68a00bc5171e0a492733e726eff02c2b956f9d6a6e7a8519e2b9c4c90b8db6b5447a0b589cb71cf0b74b899272a966c0b0da3824035c70c334818bcdfa2632e7a47ae8119661b96a6b4b17810a8840cc05bb3a0db2c6a60d10cb3e7ca365576250a380fa4b956ce066e72a0d7739a4b4e317988b64270732ff94c319a368cf0b8d8018a2d210bb37c695032a3b4da71e25e2287ef34ed68b5711ca99af1cc6b83caba7eb91d1f10eff920d9b41091e086487cc438e461344905b7e954121948ab8251fb0044e6cd8075f28b70a67132c8362b71b77298c2200e11b3013b6b2ec8b21e7a23a3cb9456567b3a090fbe642a1693501db47f8c4829d86bb1ae7accdd7763fc0b5e754ca5999a1544615dbb1acda7749c1d89073b130a4823600e322904c9599c31b67c963c307987fabc4e482910b57a56e2417eaf978008c9fa38103c15ab1a811b2b198a5b7201ef767a26a758400469ce0b1ca83920fbcbbc51c8697cc4b687d8ba41d45725551a09e5cb230532760cc15292c4ca9cc77f6e215d70c8f6e98b35fb21c5e0993588c8f76775f92c575c013270c167cddfc76de12261e84c1b506737a7448d00a6d07456fabb620d985607a32526d276846cc739276122bc14cae94543e11276805aedf36c404fc079117196383cef2681074f954249b859498a8ede375663755890613b15c2a8ff25ade0abc4d674a050369a596ac3e446cfc3171600367f89c9251e33db95c508e09a64f683fe7420c5ff73ebe5836ebec9e0ef1a39c02acd90275f5d9af9eab8c741023bc91806d255282846cb5fbcef030ee8e721d0566c29f469f5773938d679dbe17bfd7de66be5e4126f5151d1b086e26a88bd9f20710ef06aa0f834722b801f6b79c031f1f9213fda268813efab5204efa60f78bf81d320d01ac09ac06244f7afbd2d80fd356d9" +}, +{ + "dz" : "195d6c86a3df4c21e3007d7f2768b43c74cb3060e0eca77f0a5d3271542b9a84ae77e0f9f21eabd8c0c6eea7767f4e10fde5c2d79b8400bf96b19014b457ec21", + "pk" : "5fe1c21f16c49f6b02f2450f4ac135a9eaa5e24a3e3f350a6982b5979a93120285dac88e01923060a795d251c1fedb130828582c95ca7340b2e8e105cfd64f63e63f85a955dcc4b12b0482d0994df7ec61b8b09aa4d1b8ceb94b769a2ae12031d16c05cada3a4d0350e8d970ccf716953543a984cdb086c425915858d454880c97505bbb9ac7cfa54055526689033c8241300e11d09283441043b91354d1c0dcb4a869f225c8ba5b290a77629004ba336c8975366002667c99b88b53a4b08ab564733b5d2a3011f944b2259845dcb6ab8956836656e3370f5981203943b343389f2a98cdc96bc1a996648580b7fe837817ac4db31a2d325a869950a32d99446256cb3d8b91c159683bc8c1ff41287ca54530e84082bbafad485c0f179781950a4722c9114485f6b403f3760678e3bbefda309adc41ca562dbcb739654abc6cb05216807e2fe18fbb485977380d8c0282e271c7f1f8c14694484b76241a1b0cf3928ad9e328357ab75fe909957419defc8e0da3469e7720a5e91df7c4857ed50b89d18ffaf6a045e2c950e178adec7a3d690fa23527d3d353d8731857018d7cc909d081cab0370cfcc8bf8f5463a4fa8706a1abdf2c6a7fe8c834a4ccd8b6c869c6bf93c808a43274620b30aff22bbce53a7ff85145779cba220dabd1b597f4515c1664a374a64ae18884b0919668a70b371e24d2ac1a84af7de3b84f804e105177f6a9b914cb5dce45c678c886b3b24e3649cb194c548fba4114f278a56a4310a7cf1cb16e8ecc0b0fb8a2685b30631753b7f87eec8578684a67634119fe8cb334b67b741305aee8762639a212b9baab4032653b1537327eba5b6fed245d17631e748532426c5a4f4646716521dcc72f4c34a38bc87a892650def1bf09991e4c175d0baa1bf6469277f75a2812aacb88534c491f4d3c884a4470f01b805efc160ec17f68b0b0eb9910889a02467232fdb268848a5d6969c91410775fe717c9103cffb9a2bc13b1bbba01abb92ae303abfefc51af169d25d29316e7a12a5bca6827c25df567ef0c20f13a6fd728a32e229f72b42e74470c88c105bec0a12a1810c3d2a3d84b89a8c9bf66cc305f0b0c3fb989c3541daf147d5b02813e7904cc18a5dbb6632af4a34cd42007f09ab4a88c1705958058bbd6f996fe7642a0b45b690317d0e658ea82094d6b8d55722123fc1bd349433ad4850b19a4f6616685767e67bc21333a9f667a6c422087398b3331c075cea9aea6e29e424653d5e7a86766613732343341491726869eda4f97f1982e62c4cf135b1553a0a842b35e8ac23f29a921039bf31833f12ca8c4f02021559e1ab5bc37d247a5078280f02956ba2e2f897b48e18a769908e6b8b15c63b5a780580d02b5f70749a5442c824a0f56cb00378bc0ea2b033fbc9d45d535ecc00f5579a687865702436d3065461a06c8b274561d938d92290a8c0bbc0cc746aeb253e4823f8bd7b6becb5b1f8a5403fcb40efa5f6c34c43620921a416aa769a6ea1ca15c765d0e53c70b0a719f7b47ff783b63701af5a9cfe704c7d99830734c1b1fe00a1d9166b11060baa09501715310b93ead6825ba9998d922ae362092349aa45abb04781a98b25989e8309c40698a2676b49fbdca7775f554d2448358e6a4bf5373892b712b63af3392fa95dea1a8", + "sk" : "2feaa7e47b8e973ca66cd8be82e5983d295eee270134086481a92e55d3a282cb4e702b234e3a49ae7b532f6183e0b57e4cf688121a5da377aafdd36f1180816ed91c28038776169ea0a11937e229f7b57447f4295f457bdd89191d6a89f6a7146b55a5cd16c743bc3f3f60bdac4c1ee7727946157bf1929d6b7c15836c6b28445601497e07376426239aa3c0bc8135570d9623ad828f858a6ec5e4946f189864e87249eb574875409aa22967141380c633ece33567da5811b9a40759403becc297ab63622bb9f0b5cbf52378be037882ac9b25414817b4784101683b8696a6f9178323762bc419fe939ab0c8640422743b3a7e628382d36bc42afc4dd206a160dab1d1551b0e7a349e14b5b66077d6b85082306b1dd83ad0b16157e0c1b910a5d3fa562ff2c008804f6c1caa8f18336082ac4f8abce7d4a1e680361140b69b80574658c6f6f0a4d27104dcf29c55c74500db129e55114121764152c0eafc1e88350816057197466b50da92cc034996001a503040b7847fafa5950e8acda9a3c3eaa6b7e475c806401be2183100447d82284515a1a191d01ec7ea8eba84701feb15bd149af2e66cb3844204e3bca83976a088a291fb6c70425a09e42d292b1afeb0c0ac94361b5673ffc25a4b5812d211b0aad388fe1538a5929edcabb11e317de597b8db653cdc552938925a2be642fcb78bbc271584a8b27904c4fb6001304822cba9b96b9b0a79901668236494d68a455129e9869693dab64d4b13b7ca6fad71942b955c1356735b0a27aa037b420300983155c96903bd4b1235c21e8273416660b5b977ce37b6b44bbb09bd197a97cca98cb87a2ff1bc9c0a051ed98560b6b761055d84143f052a686bb3623da02a208b184d1426683484a7594aa22cc705173024f35b8e24977d421606197e0c21c9d145c316b7cedaa13202dc2cd4c62224e01eaf865f7b018a4a938920f848f436ae530a591a2617aa97143f8ab2005b9f9b734c82145c34567c59518a8ca13100ea8b4e3420d698450b70237765b62e433cdd2a842468bcdb42a639aa9644d89f4840351f3096f5c67cf17baad6cba5c79c002ae25a55f224e3b577111b4647e0cb0cb12907554fb96b77a8f267593a3f506b1cf53b6a01136edc0a684e2b8b4825066053c8c232b736c321f1708226fc3a131b1073867cc0872c53a85426ca1bc3756b329598072a352ab82fa8a61429a58ef21c2833d1bde2c1a919c75ad52a4162abbe2829b2fe93c7990ac7cfec8eea930fc5cb9ca13b2da2e80de600325d965982626f001371f59aabff88c74e028c49d5ac3c766efea499e2375a330c91385831e990cd69d6cc8a415a4e563eafa0319607b171b130ac842c66589dcae283af2b884beb6b6ec84e48f037afab54fc2c6486a7a13c9c3396d3b6512a576cb87599aa7aedc97275766d6a96af28327dedb27386923b98b647d5003d5edc718b0477a5164000799ca30c08e8f8a9ee728cd0b0aef4c16b1d61c751e32463e4b785223bee6227e3f88fcb469cf250a64bc7a3149ab3edaa730d6b4e6920b7b5c2bd55b97473b91c3c1c5923067c08db693c97ae832427dc6439576749df139e19d9580ab8c49eb15b80e09e6845335fe1c21f16c49f6b02f2450f4ac135a9eaa5e24a3e3f350a6982b5979a93120285dac88e01923060a795d251c1fedb130828582c95ca7340b2e8e105cfd64f63e63f85a955dcc4b12b0482d0994df7ec61b8b09aa4d1b8ceb94b769a2ae12031d16c05cada3a4d0350e8d970ccf716953543a984cdb086c425915858d454880c97505bbb9ac7cfa54055526689033c8241300e11d09283441043b91354d1c0dcb4a869f225c8ba5b290a77629004ba336c8975366002667c99b88b53a4b08ab564733b5d2a3011f944b2259845dcb6ab8956836656e3370f5981203943b343389f2a98cdc96bc1a996648580b7fe837817ac4db31a2d325a869950a32d99446256cb3d8b91c159683bc8c1ff41287ca54530e84082bbafad485c0f179781950a4722c9114485f6b403f3760678e3bbefda309adc41ca562dbcb739654abc6cb05216807e2fe18fbb485977380d8c0282e271c7f1f8c14694484b76241a1b0cf3928ad9e328357ab75fe909957419defc8e0da3469e7720a5e91df7c4857ed50b89d18ffaf6a045e2c950e178adec7a3d690fa23527d3d353d8731857018d7cc909d081cab0370cfcc8bf8f5463a4fa8706a1abdf2c6a7fe8c834a4ccd8b6c869c6bf93c808a43274620b30aff22bbce53a7ff85145779cba220dabd1b597f4515c1664a374a64ae18884b0919668a70b371e24d2ac1a84af7de3b84f804e105177f6a9b914cb5dce45c678c886b3b24e3649cb194c548fba4114f278a56a4310a7cf1cb16e8ecc0b0fb8a2685b30631753b7f87eec8578684a67634119fe8cb334b67b741305aee8762639a212b9baab4032653b1537327eba5b6fed245d17631e748532426c5a4f4646716521dcc72f4c34a38bc87a892650def1bf09991e4c175d0baa1bf6469277f75a2812aacb88534c491f4d3c884a4470f01b805efc160ec17f68b0b0eb9910889a02467232fdb268848a5d6969c91410775fe717c9103cffb9a2bc13b1bbba01abb92ae303abfefc51af169d25d29316e7a12a5bca6827c25df567ef0c20f13a6fd728a32e229f72b42e74470c88c105bec0a12a1810c3d2a3d84b89a8c9bf66cc305f0b0c3fb989c3541daf147d5b02813e7904cc18a5dbb6632af4a34cd42007f09ab4a88c1705958058bbd6f996fe7642a0b45b690317d0e658ea82094d6b8d55722123fc1bd349433ad4850b19a4f6616685767e67bc21333a9f667a6c422087398b3331c075cea9aea6e29e424653d5e7a86766613732343341491726869eda4f97f1982e62c4cf135b1553a0a842b35e8ac23f29a921039bf31833f12ca8c4f02021559e1ab5bc37d247a5078280f02956ba2e2f897b48e18a769908e6b8b15c63b5a780580d02b5f70749a5442c824a0f56cb00378bc0ea2b033fbc9d45d535ecc00f5579a687865702436d3065461a06c8b274561d938d92290a8c0bbc0cc746aeb253e4823f8bd7b6becb5b1f8a5403fcb40efa5f6c34c43620921a416aa769a6ea1ca15c765d0e53c70b0a719f7b47ff783b63701af5a9cfe704c7d99830734c1b1fe00a1d9166b11060baa09501715310b93ead6825ba9998d922ae362092349aa45abb04781a98b25989e8309c40698a2676b49fbdca7775f554d2448358e6a4bf5373892b712b63af3392fa95dea1a8b6f12914ed31f14f79c652eed4db478de7ebd263fe27052509fee10b50f2d053ae77e0f9f21eabd8c0c6eea7767f4e10fde5c2d79b8400bf96b19014b457ec21" +} +] diff --git a/Tests/CryptoTests/KEM/MLKEMKeyGenTests.swift b/Tests/CryptoTests/KEM/MLKEMKeyGenTests.swift new file mode 100644 index 000000000..a2a4d194a --- /dev/null +++ b/Tests/CryptoTests/KEM/MLKEMKeyGenTests.swift @@ -0,0 +1,118 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2019-2020 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import XCTest + +#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +// Skip tests that require @testable imports of CryptoKit. +#else +#if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +@testable import CryptoKit +#else +@testable import Crypto +#endif + +final class MLKEMKeyGenTests: XCTestCase { + func processKeyGenKATFile(filename: String) throws -> [MLKEMKeyGenKAT] { + #if CRYPTO_IN_SWIFTPM + let bundle = Bundle.module + #else + let bundle = Bundle(for: type(of: self)) + #endif + let fileURL = bundle.url(forResource: filename, withExtension: "json") + let json = try Data(contentsOf: fileURL!) + let stringInput = String(data: json, encoding: .ascii)! + let tests = try JSONDecoder().decode([MLKEMKeyGenKATHex].self, from: stringInput.data(using: .ascii)!) + return try tests.map { try MLKEMKeyGenKAT($0) } + } + + func test768KAT() throws { + let katTests = try processKeyGenKATFile(filename:"MLKEM768_BSSLKAT") + for katTest in katTests { + let publicKey = try MLKEM768.PublicKey(rawRepresentation: katTest.pk) + #if false + let privateKey = try MLKEM768.PrivateKey(seedRepresentation: katTest.dz, publicKey: publicKey) + let publicKeyHash = Data(SHA3_256.hash(data: privateKey.publicKey.rawRepresentation)) + #else + let privateKey = try MLKEM768.PrivateKey(seedRepresentation: katTest.dz, publicKey: nil) + #endif + + XCTAssert(privateKey.seedRepresentation == katTest.dz) + #if false + XCTAssert(privateKey.integrityCheckedRepresentation == katTest.dz + publicKeyHash) + #endif + XCTAssert(privateKey.publicKey.rawRepresentation == katTest.pk) + + // Try initializing keys with incorrect integrity checks + #if false + let randomPrivateKey = try MLKEM768.PrivateKey.generate() + let randomPublicKeyHash = Data(SHA3_256.hash(data: randomPrivateKey.publicKey.rawRepresentation)) + XCTAssertThrowsError(try MLKEM768.PrivateKey(seedRepresentation: privateKey.seedRepresentation, publicKey: randomPrivateKey.publicKey), error: KEM.Errors.publicKeyMismatchDuringInitialization) + XCTAssertThrowsError(try MLKEM768.PrivateKey(seedRepresentation: randomPrivateKey.seedRepresentation, publicKey: publicKey), error: KEM.Errors.publicKeyMismatchDuringInitialization) + XCTAssertThrowsError(try MLKEM768.PrivateKey(integrityCheckedRepresentation: privateKey.seedRepresentation + randomPublicKeyHash), error: KEM.Errors.publicKeyMismatchDuringInitialization) + XCTAssertThrowsError(try MLKEM768.PrivateKey(integrityCheckedRepresentation: randomPrivateKey.seedRepresentation + publicKeyHash), error: KEM.Errors.publicKeyMismatchDuringInitialization) + #endif + } + + } + + func test1024KAT() throws { + let katTests = try processKeyGenKATFile(filename:"MLKEM1024_BSSLKAT") + for katTest in katTests { + let publicKey = try MLKEM1024.PublicKey(rawRepresentation: katTest.pk) + #if false + let privateKey = try MLKEM1024.PrivateKey(seedRepresentation: katTest.dz, publicKey: publicKey) + let publicKeyHash = Data(SHA3_256.hash(data: privateKey.publicKey.rawRepresentation)) + #else + let privateKey = try MLKEM1024.PrivateKey(seedRepresentation: katTest.dz, publicKey: nil) + #endif + + XCTAssert(privateKey.seedRepresentation == katTest.dz) + #if false + XCTAssert(privateKey.integrityCheckedRepresentation == katTest.dz + publicKeyHash) + #endif + XCTAssert(privateKey.publicKey.rawRepresentation == katTest.pk) + + // Try initializing keys with incorrect integrity checks + #if false + let randomPrivateKey = try MLKEM1024.PrivateKey.generate() + let randomPublicKeyHash = Data(SHA3_256.hash(data: randomPrivateKey.publicKey.rawRepresentation)) + XCTAssertThrowsError(try MLKEM1024.PrivateKey(seedRepresentation: privateKey.seedRepresentation, publicKey: randomPrivateKey.publicKey), error: KEM.Errors.publicKeyMismatchDuringInitialization) + XCTAssertThrowsError(try MLKEM1024.PrivateKey(seedRepresentation: randomPrivateKey.seedRepresentation, publicKey: publicKey), error: KEM.Errors.publicKeyMismatchDuringInitialization) + XCTAssertThrowsError(try MLKEM1024.PrivateKey(integrityCheckedRepresentation: privateKey.seedRepresentation + randomPublicKeyHash), error: KEM.Errors.publicKeyMismatchDuringInitialization) + XCTAssertThrowsError(try MLKEM1024.PrivateKey(integrityCheckedRepresentation: randomPrivateKey.seedRepresentation + publicKeyHash), error: KEM.Errors.publicKeyMismatchDuringInitialization) + #endif + } + } +} + +// Struct to parse KAT file +struct MLKEMKeyGenKATHex: Codable { + var dz: String + var pk: String + var sk: String +} + +// Represent KAT with Data +struct MLKEMKeyGenKAT { + var dz: Data + var pk: Data + var sk: Data + init(_ hexRep: MLKEMKeyGenKATHex) throws { + dz = try Data(hexString: hexRep.dz) + pk = try Data(hexString: hexRep.pk) + sk = try Data(hexString: hexRep.sk) + } +} + +#endif // CRYPTO_IN_SWIFTPM diff --git a/Tests/CryptoTests/KEM/MLKEMTests.swift b/Tests/CryptoTests/KEM/MLKEMTests.swift new file mode 100644 index 000000000..c5a22935c --- /dev/null +++ b/Tests/CryptoTests/KEM/MLKEMTests.swift @@ -0,0 +1,167 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2019-2020 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import XCTest + +#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +// Skip tests that require @testable imports of CryptoKit. +#else +#if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +@testable import CryptoKit +#else +@testable import Crypto +#endif + +final class MLKEMTests: XCTestCase { + func testMLKEM768() throws { + let privateKey = try MLKEM768.PrivateKey.generate() + let publicKey = privateKey.publicKey + + // Test Public Key Serialization + try XCTAssert(publicKey.rawRepresentation == MLKEM768.PublicKey(rawRepresentation: publicKey.rawRepresentation).rawRepresentation) + + // Test Private Key serialization + #if false + try XCTAssert(privateKey.seedRepresentation == MLKEM768.PrivateKey(seedRepresentation: privateKey.seedRepresentation, publicKey: publicKey).seedRepresentation) + try XCTAssert(privateKey.integrityCheckedRepresentation == MLKEM768.PrivateKey(integrityCheckedRepresentation: privateKey.integrityCheckedRepresentation).integrityCheckedRepresentation) + #else + try XCTAssert(privateKey.seedRepresentation == MLKEM768.PrivateKey(seedRepresentation: privateKey.seedRepresentation, publicKey: nil).seedRepresentation) + #endif + + let er = try publicKey.encapsulate() + let ss = try privateKey.decapsulate(er.encapsulated) + + XCTAssert(er.sharedSecret == ss) + } + + func testMLKEM1024() throws { + let privateKey = try MLKEM1024.PrivateKey.generate() + let publicKey = privateKey.publicKey + + // Test Public Key Serialization + try XCTAssert(publicKey.rawRepresentation == MLKEM1024.PublicKey(rawRepresentation: publicKey.rawRepresentation).rawRepresentation) + + // Test Private Key serialization + #if false + try XCTAssert(privateKey.seedRepresentation == MLKEM1024.PrivateKey(seedRepresentation: privateKey.seedRepresentation, publicKey: publicKey).seedRepresentation) + try XCTAssert(privateKey.integrityCheckedRepresentation == MLKEM1024.PrivateKey(integrityCheckedRepresentation: privateKey.integrityCheckedRepresentation).integrityCheckedRepresentation) + #else + try XCTAssert(privateKey.seedRepresentation == MLKEM1024.PrivateKey(seedRepresentation: privateKey.seedRepresentation, publicKey: nil).seedRepresentation) + #endif + + let er = try publicKey.encapsulate() + let ss = try privateKey.decapsulate(er.encapsulated) + + XCTAssert(er.sharedSecret == ss) + } + + func processKATFile(filename: String) throws -> [MLKEMKAT] { + #if CRYPTO_IN_SWIFTPM + let bundle = Bundle.module + #else + let bundle = Bundle(for: type(of: self)) + #endif + let fileURL = bundle.url(forResource: filename, withExtension: "json") + let json = try Data(contentsOf: fileURL!) + let stringInput = String(data: json, encoding: .ascii)! + let tests = try JSONDecoder().decode([MLKEMKATHex].self, from: stringInput.data(using: .ascii)!) + return try tests.map { try MLKEMKAT($0) } + } + + func test768KAT() throws { + #if CRYPTO_IN_SWIFTPM + throw XCTSkip() + #else + let katTests = try processKATFile(filename:"MLKEM768KAT") + for katTest in katTests { + let rndGen = try Drbg(katTest.rngSeed) + + var keyGenSeed = Data(count: 64) + keyGenSeed.withUnsafeMutableBytes { buffer in + buffer.initializeWithRandomBytes(count: buffer.count, ccrngState: rndGen.detRngPtr) + } + var encapSeed = Data(count: 32) + encapSeed.withUnsafeMutableBytes { buffer in + buffer.initializeWithRandomBytes(count: buffer.count, ccrngState: rndGen.detRngPtr) + } + + let privateKey = try MLKEM768.PrivateKey.generateWithSeed(keyGenSeed) // 2 * 32 bytes + XCTAssert(privateKey.publicKey.rawRepresentation == katTest.pk) + + let encapsulatedKey = try privateKey.publicKey.encapsulateWithSeed(encapSeed: encapSeed) // 32 bytes + XCTAssert(encapsulatedKey.encapsulated == katTest.ek) + XCTAssert(encapsulatedKey.sharedSecret == katTest.k) + + let retrievedSharedSecret = try privateKey.decapsulate(encapsulatedKey.encapsulated) + XCTAssert(retrievedSharedSecret.dataRepresentation == katTest.k) + } + #endif + } + + func test1024KAT() throws { + #if CRYPTO_IN_SWIFTPM + throw XCTSkip() + #else + let katTests = try processKATFile(filename:"MLKEM1024KAT") + for katTest in katTests { + let rndGen = try Drbg(katTest.rngSeed) + + var keyGenSeed = Data(count: 64) + keyGenSeed.withUnsafeMutableBytes { buffer in + buffer.initializeWithRandomBytes(count: buffer.count, ccrngState: rndGen.detRngPtr) + } + var encapSeed = Data(count: 32) + encapSeed.withUnsafeMutableBytes { buffer in + buffer.initializeWithRandomBytes(count: buffer.count, ccrngState: rndGen.detRngPtr) + } + + let privateKey = try MLKEM1024.PrivateKey.generateWithSeed(keyGenSeed) + XCTAssert(privateKey.publicKey.rawRepresentation == katTest.pk) + + let encapsulatedKey = try privateKey.publicKey.encapsulateWithSeed(encapSeed: encapSeed) + XCTAssert(encapsulatedKey.encapsulated == katTest.ek) + XCTAssert(encapsulatedKey.sharedSecret == katTest.k) + + let retrievedSharedSecret = try privateKey.decapsulate(encapsulatedKey.encapsulated) + XCTAssert(retrievedSharedSecret.dataRepresentation == katTest.k) + } + #endif + } +} + +// Struct to parse KAT file +struct MLKEMKATHex: Codable { + var rngSeed: String + var sk: String + var pk: String + var ek: String + var k: String +} + +// Represent KAT with Data +struct MLKEMKAT { + var rngSeed: Data + var sk: Data + var pk: Data + var ek: Data + var k: Data + init(_ hexRep: MLKEMKATHex) throws { + rngSeed = try Data(hexString: hexRep.rngSeed) + sk = try Data(hexString: hexRep.sk) + pk = try Data(hexString: hexRep.pk) + ek = try Data(hexString: hexRep.ek) + k = try Data(hexString: hexRep.k) + } +} + +#endif // CRYPTO_IN_SWIFTPM diff --git a/Tests/CryptoTests/KEM/XWingTests.swift b/Tests/CryptoTests/KEM/XWingTests.swift new file mode 100644 index 000000000..32a34f019 --- /dev/null +++ b/Tests/CryptoTests/KEM/XWingTests.swift @@ -0,0 +1,123 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2019-2020 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import XCTest + +#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +// Skip tests that require @testable imports of CryptoKit. +#else +#if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +@testable import CryptoKit +#else +@testable import Crypto +#endif + +final class XWingTests: XCTestCase { + func testKEM() throws { + let privateKey = try XWingMLKEM768X25519.PrivateKey.generate() + + let publicKey = privateKey.publicKey + + try XCTAssert(publicKey.rawRepresentation == XWingMLKEM768X25519.PublicKey(dataRepresentation: publicKey.rawRepresentation).rawRepresentation) + try XCTAssert(privateKey.dataRepresentation == XWingMLKEM768X25519.PrivateKey(bytes: privateKey.dataRepresentation).dataRepresentation) + + let er = try publicKey.encapsulate() + let ss = try privateKey.decapsulate(er.encapsulated) + + XCTAssert(er.sharedSecret == ss) + } + + func processKATFile(filename: String) throws -> [XWingKAT] { + #if CRYPTO_IN_SWIFTPM + let bundle = Bundle.module + #else + let bundle = Bundle(for: type(of: self)) + #endif + let fileURL = bundle.url(forResource: filename, withExtension: "json") + let json = try Data(contentsOf: fileURL!) + let stringInput = String(data: json, encoding: .ascii)! + let tests = try JSONDecoder().decode([XWingKATHex].self, from: stringInput.data(using: .ascii)!) + return try tests.map { try XWingKAT($0) } + } + + func testXWingMLKEM768X25519TestVectors() throws { + let katTests = try processKATFile(filename:"test-vectors") + for katTest in katTests { + let privateKeyDrbg = try SequenceDrbg(katTest.seed) + let privateKey = try XWingMLKEM768X25519.PrivateKey.generateWithRng(ccrngState: privateKeyDrbg.detRngPtr) + XCTAssertEqual(privateKey.dataRepresentation, katTest.sk + katTest.pk) + XCTAssertEqual(privateKey.publicKey.rawRepresentation, katTest.pk) + + let encapDrbg = try SequenceDrbg(katTest.eseed) + let encapsulatedKey = try privateKey.publicKey.encapsulateWithRng(ccrngState: encapDrbg.detRngPtr) + XCTAssertEqual(encapsulatedKey.encapsulated, katTest.ct) + XCTAssertEqual(encapsulatedKey.sharedSecret.dataRepresentation, katTest.ss) + let retrievedSharedSecret = try privateKey.decapsulate(encapsulatedKey.encapsulated) + XCTAssertEqual(retrievedSharedSecret.dataRepresentation, katTest.ss) + } + } + + func testPrivateKeyRepresentations() throws { + let privateKey = try XWingMLKEM768X25519.PrivateKey.generate() + XCTAssertEqual(privateKey.seedRepresentation.count, 32) + #if false + XCTAssertEqual(privateKey.integrityCheckedRepresentation.count, 64) + XCTAssertEqual(privateKey.integrityCheckedRepresentation.dropLast(32), privateKey.seedRepresentation) + #endif + + let recoveredPrivateKey = try XWingMLKEM768X25519.PrivateKey(seedRepresentation: privateKey.seedRepresentation, publicKeyHash: nil) + XCTAssertNotNil(recoveredPrivateKey) + #if false + XCTAssertEqual(recoveredPrivateKey.integrityCheckedRepresentation, privateKey.integrityCheckedRepresentation) + #endif + + #if false + let otherKey = try XWingMLKEM768X25519.PrivateKey.generate() + XCTAssertThrowsError(try XWingMLKEM768X25519.PrivateKey(seedRepresentation: privateKey.seedRepresentation, publicKeyHash: SHA3_256.hash(data: otherKey.publicKey.rawRepresentation)), error: KEM.Errors.publicKeyMismatchDuringInitialization) + + let exportedFormat = privateKey.integrityCheckedRepresentation + let importedKey = try XWingMLKEM768X25519.PrivateKey.init(integrityCheckedRepresentation: exportedFormat) + XCTAssertEqual(importedKey.seedRepresentation, privateKey.seedRepresentation) + #endif + } +} + +// Struct to parse KAT file +struct XWingKATHex: Codable { + var seed: String + var sk: String + var pk: String + var eseed: String + var ct: String + var ss: String +} + +// Represent KAT with Data +struct XWingKAT { + var seed: Data + var sk: Data + var pk: Data + var eseed: Data + var ct: Data + var ss: Data + init(_ hexRep: XWingKATHex) throws { + seed = try Data(hexString: hexRep.seed) + sk = try Data(hexString: hexRep.sk) + pk = try Data(hexString: hexRep.pk) + eseed = try Data(hexString: hexRep.eseed) + ct = try Data(hexString: hexRep.ct) + ss = try Data(hexString: hexRep.ss) + } +} + +#endif // CRYPTO_IN_SWIFTPM diff --git a/Tests/CryptoTests/KEM/test-vectors.json b/Tests/CryptoTests/KEM/test-vectors.json new file mode 100644 index 000000000..2cb8ab083 --- /dev/null +++ b/Tests/CryptoTests/KEM/test-vectors.json @@ -0,0 +1 @@ +[{"seed": "7f9c2ba4e88f827d616045507605853ed73b8093f6efbc88eb1a6eacfa66ef26", "eseed": "3cb1eea988004b93103cfb0aeefd2a686e01fa4a58e8a3639ca8a1e3f9ae57e235b8cc873c23dc62b8d260169afa2f75ab916a58d974918835d25e6a435085b2", "ss": "d2df0522128f09dd8e2c92b1e905c793d8f57a54c3da25861f10bf4ca613e384", "sk": "7f9c2ba4e88f827d616045507605853ed73b8093f6efbc88eb1a6eacfa66ef26", "pk": "e2236b35a8c24b39b10aa1323a96a919a2ced88400633a7b07131713fc14b2b5b19cfc3da5fa1a92c49f25513e0fd30d6b1611c9ab9635d7086727a4b7d21d34244e66969cf15b3b2a785329f61b096b277ea037383479a6b556de7231fe4b7fa9c9ac24c0699a0018a5253401bacfa905ca816573e56a2d2e067e9b7287533ba13a937dedb31fa44baced40769923610034ae31e619a170245199b3c5c39864859fe1b4c9717a07c30495bdfb98a0a002ccf56c1286cef5041dede3c44cf16bf562c7448518026b3d8b9940680abd38a1575fd27b58da063bfac32c39c30869374c05c1aeb1898b6b303cc68be455346ee0af699636224a148ca2aea10463111c709f69b69c70ce8538746698c4c60a9aef0030c7924ceec42a5d36816f545eae13293460b3acb37ea0e13d70e4aa78686da398a8397c08eaf96882113fe4f7bad4da40b0501e1c753efe73053c87014e8661c33099afe8bede414a5b1aa27d8392b3e131e9a70c1055878240cad0f40d5fe3cdf85236ead97e2a97448363b2808caafd516cd25052c5c362543c2517e4acd0e60ec07163009b6425fc32277acee71c24bab53ed9f29e74c66a0a3564955998d76b96a9a8b50d1635a4d7a67eb42df5644d330457293a8042f53cc7a69288f17ed55827e82b28e82665a86a14fbd96645eca8172c044f83bc0d8c0b4c8626985631ca87af829068f1358963cb333664ca482763ba3b3bb208577f9ba6ac62c25f76592743b64be519317714cb4102cb7b2f9a25b2b4f0615de31decd9ca55026d6da0b65111b16fe52feed8a487e144462a6dba93728f500b6ffc49e515569ef25fed17aff520507368253525860f58be3be61c964604a6ac814e6935596402a520a4670b3d284318866593d15a4bb01c35e3e587ee0c67d2880d6f2407fb7a70712b838deb96c5d7bf2b44bcf6038ccbe33fbcf51a54a584fe90083c91c7a6d43d4fb15f48c60c2fd66e0a8aad4ad64e5c42bb8877c0ebec2b5e387c8a988fdc23beb9e16c8757781e0a1499c61e138c21f216c29d076979871caa6942bafc090544bee99b54b16cb9a9a364d6246d9f42cce53c66b59c45c8f9ae9299a75d15180c3c952151a91b7a10772429dc4cbae6fcc622fa8018c63439f890630b9928db6bb7f9438ae4065ed34d73d486f3f52f90f0807dc88dfdd8c728e954f1ac35c06c000ce41a0582580e3bb57b672972890ac5e7988e7850657116f1b57d0809aaedec0bede1ae148148311c6f7e317346e5189fb8cd635b986f8c0bdd27641c584b778b3a911a80be1c9692ab8e1bbb12839573cce19df183b45835bbb55052f9fc66a1678ef2a36dea78411e6c8d60501b4e60592d13698a943b509185db912e2ea10be06171236b327c71716094c964a68b03377f513a05bcd99c1f346583bb052977a10a12adfc758034e5617da4c1276585e5774e1f3b9978b09d0e9c44d3bc86151c43aad185712717340223ac381d21150a04294e97bb13bbda21b5a182b6da969e19a7fd072737fa8e880a53c2428e3d049b7d2197405296ddb361912a7bcf4827ced611d0c7a7da104dde4322095339f64a61d5bb108ff0bf4d780cae509fb22c256914193ff7349042581237d522828824ee3bdfd07fb03f1f942d2ea179fe722f06cc03de5b69859edb06eff389b27dce59844570216223593d4ba32d9abac8cd049040ef6534", "ct": "b83aa828d4d62b9a83ceffe1d3d3bb1ef31264643c070c5798927e41fb07914a273f8f96e7826cd5375a283d7da885304c5de0516a0f0654243dc5b97f8bfeb831f68251219aabdd723bc6512041acbaef8af44265524942b902e68ffd23221cda70b1b55d776a92d1143ea3a0c475f63ee6890157c7116dae3f62bf72f60acd2bb8cc31ce2ba0de364f52b8ed38c79d719715963a5dd3842d8e8b43ab704e4759b5327bf027c63c8fa857c4908d5a8a7b88ac7f2be394d93c3706ddd4e698cc6ce370101f4d0213254238b4a2e8821b6e414a1cf20f6c1244b699046f5a01caa0a1a55516300b40d2048c77cc73afba79afeea9d2c0118bdf2adb8870dc328c5516cc45b1a2058141039e2c90a110a9e16b318dfb53bd49a126d6b73f215787517b8917cc01cabd107d06859854ee8b4f9861c226d3764c87339ab16c3667d2f49384e55456dd40414b70a6af841585f4c90c68725d57704ee8ee7ce6e2f9be582dbee985e038ffc346ebfb4e22158b6c84374a9ab4a44e1f91de5aac5197f89bc5e5442f51f9a5937b102ba3beaebf6e1c58380a4a5fedce4a4e5026f88f528f59ffd2db41752b3a3d90efabe463899b7d40870c530c8841e8712b733668ed033adbfafb2d49d37a44d4064e5863eb0af0a08d47b3cc888373bc05f7a33b841bc2587c57eb69554e8a3767b7506917b6b70498727f16eac1a36ec8d8cfaf751549f2277db277e8a55a9a5106b23a0206b4721fa9b3048552c5bd5b594d6e247f38c18c591aea7f56249c72ce7b117afcc3a8621582f9cf71787e183dee09367976e98409ad9217a497df888042384d7707a6b78f5f7fb8409e3b535175373461b776002d799cbad62860be70573ecbe13b246e0da7e93a52168e0fb6a9756b895ef7f0147a0dc81bfa644b088a9228160c0f9acf1379a2941cd28c06ebc80e44e17aa2f8177010afd78a97ce0868d1629ebb294c5151812c583daeb88685220f4da9118112e07041fcc24d5564a99fdbde28869fe0722387d7a9a4d16e1cc8555917e09944aa5ebaaaec2cf62693afad42a3f518fce67d273cc6c9fb5472b380e8573ec7de06a3ba2fd5f931d725b493026cb0acbd3fe62d00e4c790d965d7a03a3c0b4222ba8c2a9a16e2ac658f572ae0e746eafc4feba023576f08942278a041fb82a70a595d5bacbf297ce2029898a71e5c3b0d1c6228b485b1ade509b35fbca7eca97b2132e7cb6bc465375146b7dceac969308ac0c2ac89e7863eb8943015b24314cafb9c7c0e85fe543d56658c213632599efabfc1ec49dd8c88547bb2cc40c9d38cbd3099b4547840560531d0188cd1e9c23a0ebee0a03d5577d66b1d2bcb4baaf21cc7fef1e03806ca96299df0dfbc56e1b2b43e4fc20c37f834c4af62127e7dae86c3c25a2f696ac8b589dec71d595bfbe94b5ed4bc07d800b330796fda89edb77be0294136139354eb8cd37591578f9c600dd9be8ec6219fdd507adf3397ed4d68707b8d13b24ce4cd8fb22851bfe9d632407f31ed6f7cb1600de56f17576740ce2a32fc5145030145cfb97e63e0e41d354274a079d3e6fb2e15"}, {"seed": "badfd6dfaac359a5efbb7bcc4b59d538df9a04302e10c8bc1cbf1a0b3a5120ea", "eseed": "17cda7cfad765f5623474d368ccca8af0007cd9f5e4c849f167a580b14aabdefaee7eef47cb0fca9767be1fda69419dfb927e9df07348b196691abaeb580b32d", "ss": "f2e86241c64d60f6649fbc6c5b7d17180b780a3f34355e64a85749949c45f150", "sk": "badfd6dfaac359a5efbb7bcc4b59d538df9a04302e10c8bc1cbf1a0b3a5120ea", "pk": "0333285fa253661508c9fb444852caa4061636cb060e69943b431400134ae1fbc02287247cb38068bbb89e6714af10a3fcda6613acc4b5e4b0d6eb960c302a0253b1f507b596f0884d351da89b01c35543214c8e542390b2bc497967961ef10286879c34316e6483b644fc27e8019d73024ba1d1cc83650bb068a5431b33d1221b3d122dc1239010a55cb13782140893f30aca7c09380255a0c621602ffbb6a9db064c1406d12723ab3bbe2950a21fe521b160b30b16724cc359754b4c88342651333ea9412d5137791cf75558ebc5c54c520dd6c622a059f6b332ccebb9f24103e59a297cd69e4a48a3bfe53a5958559e840db5c023f66c10ce23081c2c8261d744799ba078285cfa71ac51f44708d0a6212c3993340724b3ac38f63e82a889a4fc581f6b8353cc6233ac8f5394b6cca292f892360570a3031c90c4da3f02a895677390e60c24684a405f69ccf1a7b95312a47c844a4f9c2c4a37696dc10072a87bf41a2717d45b2a99ce09a4898d5a3f6b67085f9a626646bcf369982d483972b9cd7d244c4f49970f766a22507925eca7df99a491d80c27723e84c7b49b633a46b46785a16a41e02c538251622117364615d9c2cdaa1687a860c18bfc9ce8690efb2a524cb97cdfd1a4ea661fa7d08817998af838679b07c9db8455e2167a67c14d6a347522e89e8971270bec858364b1c1023b82c483cf8a8b76f040fe41c24dec2d49f6376170660605b80383391c4abad1136d874a77ef73b440758b6e7059add20873192e6e372e069c22c5425188e5c240cb3a6e29197ad17e87ec41a813af68531f262a6db25bbdb8a15d2ed9c9f35b9f2063890bd26ef09426f225aa1e6008d31600a29bcdf3b10d0bc72788d35e25f4976b3ca6ac7cbf0b442ae399b225d9714d0638a864bda7018d3b7c793bd2ace6ac68f4284d10977cc029cf203c5698f15a06b162d6c8b4fd40c6af40824f9c6101bb94e9327869ab7efd835dfc805367160d6c8571e3643ac70cbad5b96a1ad99352793f5af71705f95126cb4787392e94d808491a2245064ba5a7a30c066301392a6c315336e10dbc9c2177c7af382765b6c88eeab51588d01d6a95747f3652dc5b5c401a23863c7a0343737c737c99287a40a90896d4594730b552b910d23244684206f0eb842fb9aa316ab182282a75fb72b6806cea4774b822169c386a58773c3edc8229d85905abb87ac228f0f7a2ce9a497bb5325e17a6a82777a997c036c3b862d29c14682ad325a9600872f3913029a1588648ba590a7157809ff740b5138380015c40e9fb90f0311107946f28e5962e21666ad65092a3a60480cd16e61ff7fb5b44b70cf12201878428ef8067fceb1e1dcb49d66c773d312c7e53238cb620e126187009472d41036b702032411dc96cb750631df9d99452e495deb4300df660c8d35f32b424e98c7ed14b12d8ab11a289ac63c50a24d52925950e49ba6bf4c2c38953c92d60b6cd034e575c711ac41bfa66951f62b9392828d7b45aed377ac69c35f1c6b80f388f34e0bb9ce8167eb2bc630382825c396a407e905108081b444ac8a07c2507376a750d18248ee0a81c4318d9a38fc44c3b41e8681f87c34138442659512c41276e1cc8fc4eb66e12727bcb5a9e0e405cdea21538d6ea885ab169050e6b91e1b69f7ed34bcbb48fd4c562a576549f85b528c953926d96ea8a160b8843f1c89c62", "ct": "c93beb22326705699bbc3d1d0aa6339be7a405debe61a7c337e1a91453c097a6f77c130639d1aaeb193175f1a987aa1fd789a63c9cd487ebd6965f5d8389c8d7c8cfacbba4b44d2fbe0ae84de9e96fb11215d9b76acd51887b752329c1a3e0468ccc49392c1e0f1aad61a73c10831e60a9798cb2e7ec07596b5803db3e243ecbb94166feade0c9197378700f8eb65a43502bbac4605992e2de2b906ab30ba401d7e1ff3c98f42cfc4b30b974d3316f331461ac05f43e0db7b41d3da702a4f567b6ee7295199c7be92f6b4a47e7307d34278e03c872fb48647c446a64a3937dccd7c6d8de4d34b9dea45a0b065ef15b9e94d1b6df6dca7174d9bc9d14c6225e3a78a58785c3fe4e2fe6a0706f3365389e4258fbb61ecf1a1957715982b3f1844424e03acd83da7eee50573f6cd3ff396841e9a00ad679da92274129da277833d0524674feea09a98d25b888616f338412d8e65e151e65736c8c6fb448c9260fa20e7b2712148bcd3a0853865f50c1fc9e4f201aee3757120e034fd509d954b7a749ff776561382c4cb64cebcbb6aa82d04cd5c2b40395ecaf231bde8334ecfd955d09efa8c6e7935b1cb0298fb8b6740be4593360eed5f129d59d98822a6cea37c57674e919e84d6b90f695fca58e7d29092bd70f7c97c6dfb021b9f87216a6271d8b144a364d03b6bf084f972dc59800b14a2c008bbd0992b5b82801020978f2bdddb3ca3367d876cffb3548dab695a29882cae2eb5ba7c847c3c71bd0150fa9c33aac8e6240e0c269b8e295ddb7b77e9c17bd310be65e28c0802136d086777be5652d6f1ac879d3263e9c712d1af736eac048fe848a577d6afaea1428dc71db8c430edd7b584ae6e6aeaf7257aff0fd8fe25c30840e30ccfa1d95118ef0f6657367e9070f3d97a2e9a7bae19957bd707b00e31b6b0ebb9d7df4bd22e44c060830a194b5b8288353255b52954ff5905ab2b126d9aa049e44599368c27d6cb033eae5182c2e1504ee4e3745f51488997b8f958f0209064f6f44a7e4de5226d5594d1ad9b42ac59a2d100a2f190df873a2e141552f33c923b4c927e8747c6f830c441a8bd3c5b371f6b3ab8103ebcfb18543aefc1beb6f776bbfd5344779f4aa23daaf395f69ec31dc046b491f0e5cc9c651dfc306bd8f2105be7bc7a4f4e21957f87278c771528a8740a92e2daefa76a3525f1fae17ec4362a2700988001d860011d6ca3a95f79a0205bcf634cef373a8ea273ff0f4250eb8617d0fb92102a6aa09cf0c3ee2cad1ad96438c8e4dfd6ee0fcc85833c3103dd6c1600cd305bc2df4cda89b55ca237a3f9c3f82390074ff30825fc750130ebaf13d0cf7556d2c52a98a4bad39ca5d44aaadeaef775c695e64d06e966acfcd552a14e2df6c63ae541f0fa88fc48263089685704506a21a03856ce65d4f06d54f3157eeabd62491cb4ac7bf029e79f9fbd4c77e2a3588790c710e611da8b2040c76a61507a8020758dcc30894ad018fef98e401cc54106e20d94bd544a8f0e1fd0500342d123f618aa8c91bdf6e0e03200693c9651e469aee6f91c98bea4127ae66312f4ae3ea155b67"}, {"seed": "ef58538b8d23f87732ea63b02b4fa0f4873360e2841928cd60dd4cee8cc0d4c9", "eseed": "22a96188d032675c8ac850933c7aff1533b94c834adbb69c6115bad4692d8619f90b0cdf8a7b9c264029ac185b70b83f2801f2f4b3f70c593ea3aeeb613a7f1b", "ss": "953f7f4e8c5b5049bdc771d1dffada0dd961477d1a2ae0988baa7ea6898d893f", "sk": "ef58538b8d23f87732ea63b02b4fa0f4873360e2841928cd60dd4cee8cc0d4c9", "pk": "36244278824f77c621c660892c1c3886a9560caa52a97c461fd3958a598e749bbc8c7798ac8870bac7318ac2b863000ca3b0bdcbbc1ccfcb1a30875df9a76976763247083e646ccb2499a4e4f0c9f4125378ba3da1999538b86f99f2328332c177d1192b849413e65510128973f679d23253850bb6c347ba7ca81b5e6ac4c574565c731740b3cd8c9756caac39fba7ac422acc60c6c1a645b94e3b6d21485ebad9c4fe5bb4ea0853670c5246652bff65ce8381cb473c40c1a0cd06b54dcec11872b351397c0eaf995bebdb6573000cbe2496600ba76c8cb023ec260f0571e3ec12a9c82d9db3c57b3a99e8701f78db4fabc1cc58b1bae02745073a81fc8045439ba3b885581a283a1ba64e103610aabb4ddfe9959e7241011b2638b56ba6a982ef610c514a57212555db9a98fb6bcf0e91660ec15dfa66a67408596e9ccb97489a09a073ffd1a0a7ebbe71aa5ff793cb91964160703b4b6c9c5390842c2c905d4a9f88111fed57874ba9b03cf611e70486edf539767c7485189d5f1b08e32a274dc24a39c918fd2a4dfa946a8c897486f2c974031b2804aabc81749db430b85311372a3b8478868200b40e043f7bf4a1c3a08b0771b431e342ee277410bca034a0c77086c8f702b3aed2b4108bbd3af471633373a1ac74b128b148d1b9412aa66948cac6dc6614681fda02ca86675d2a756003c49c50f06e13c63ce4bc9f321c860b202ee931834930011f485c9af86b9f642f0c353ad305c66996b9a136b753973929495f0d8048db75529edcb4935904797ac66605490f66329c3bb36b8573a3e00f817b3082162ff106674d11b261baae0506cde7e69fdce93c6c7b59b9d4c759758acf287c2e4c4bfab5170a9236daf21bdb6005e92464ee8863f845cf37978ef19969264a516fe992c93b5f7ae7cb6718ac69257d630379e4aac6029cb906f98d91c92d118c36a6d16115d4c8f16066078badd161a65ba51e0252bc358c67cd2c4beab2537e42956e08a39cfccf0cd875b5499ee952c83a162c68084f6d35cf92f71ec66baec74ab87e2243160b64df54afb5a07f78ec0f5c5759e5a4322bca2643425748a1a97c62108510c44fd9089c5a7c14e57b1b77532800013027cff91922d7c935b4202bb507aa47598a6a5a030117210d4c49c174700550ad6f82ad40e965598b86bc575448eb19d70380d465c1f870824c026d74a2522a799b7b122d06c83aa64c0974635897261433914fdfb14106c230425a83dc8467ad8234f086c72a47418be9cfb582b1dcfa3d9aa45299b79fff265356d8286a1ca2f3c2184b2a70d15289e5b202d03b64c735a867b1154c55533ff61d6c296277011848143bc85a4b823040ae025a29293ab77747d85310078682e0ba0ac236548d905a79494324574d417c7a3457bd5fb5253c4876679034ae844d0d05010fec722db5621e3a67a2d58e2ff33b432269169b51f9dcc095b8406dc1864cf0aeb6a2132661a38d641877594b3c51892b9364d25c63d637140a2018d10931b0daa5a2f2a405017688c991e586b522f94b1132bc7e87a63246475816c8be9c62b731691ab912eb656ce2619225663364701a014b7d0337212caa2ecc731f34438289e0ca4590a276802d980056b5d0d316cae2ecfea6d86696a9f161aa90ad47eaad8cadd31ae3cbc1c013747dfee80fb35b5299f555dcc2b787ea4f6f16ffdf66952461", "ct": "0d2e38cbf17a2e2e4e0c87a94ca1e7701ae1552e02509b3b00f9c82c39e3fd435b05b91275f47abc9f1021429a26a346598cd6cd9efdc8adc1dbc35036d0290bf89733c835309202232f9bf652ea82f3d49280d6e8a3bd3135fb883445ab5b074d949c5350c7c7d6ac59905bdbfce6639da8a9d4b390ecc1dd05522d2956f2d37a05593996e5cb3fd8d5a9eb52417732e1ebf545588713b4760227115aab7ada178dadbca583b26cfedba2888a0c95b950bf07f750d7aa8103798aa3470a042c0105c6a037de2f9ebc396021b2ba2c16aba696fbac3454dc8e053b8fa55edd45215eeb57a1eab9106fb426b375a9b9e5c3419efc7610977e72640f9fd1b2ec337de33c35e5a7581b2aae4d8ee86d2e0ebf82a1350714de50d2d788687878a19644ae4e3175e8d59dc90171b3badeff65aeaf600e5e5483a3595fdeb40cbafcbd040c29a2f6900533ae999d24f54dfcef748c30313ca447cdddfa57ad78eaa890e90f3f7bf8d116968a5713cc75fd0408f36364fa265c5617039304eaeac4cbee6fc49b9fe2276768cdbec2d73a507b543cc028dc1b154b7c2b0412254c466a94a8d6ea3a47e1743469bd45c08f54cf965884be3696e961741ede16e3b1bc4feb93faaef31d911dc0cb3fa90bcda991959a9d2cbc817a5564c5c01177a59e9577589ea344d60cf5b0aa39f31863febd54603ca87ad2363c766642a3f52557bcd9e4c05a87665842ba336b83156a677030f0bad531a8387a1486a599caa748fcea7bdc1eb63f3cdb97173551ab7c1c36b69acbbdb2ff7a1e7bc70439632ddc67b97f3da1f59b3c1588515957cb8a2f86ab635ce0a78b7cdf24eac3445e8fc8b79ba04da9e903f49a7d912c197a84b4cfabc779b97d24788419bcf58035db99717edb9fd1c1df8c4005f700eabba528ddfcbaeda6dd30754f795948a34c9319ab653524b19931c7900c4167988af52292fe902e746b524d20ceffb4339e8f5535f41cf35f0f8ea8b4a7b949c5d2381116b146e9b913a83a3fa1c65ff9468c835fe4114554a6c66a80e1c9a6bb064b380be3c95e5595ec979bf1c85aa938938e3f10e72b0c87811969e8ab0d83de0b0604c4016ac3a015e19514089271bdc6ebf2ec56fab6018e44de749b4c36cc235e370da8466dbdc253542a2d704eb3316fd70d5d238cb7eaaf05966d973f62c7ef43b9a806f4ed213ac8099ea15d61a902444160883f6bf441a3e1469945c9b79489ea18390f1ebc83caca10bdb8f2429877b52bd44c94a228ef91c392ef5398c5c83982701318ccedab92f7a279c4fddebaa7fe5e986c48b7d8135b3fe4cd15be2004ce73ff86b1e55f8ecd6ba5b8114315f8e716ef3ab0a64564a4644651166ebd68b1f783e2e443dbccadfe189368647629f1a12215840b7f1d026de2f665c2eb023ff51a6df160912811ee03444ae4227fb941dc9ec4f31b445006fd384de5e60e0a5061b50cb1202f863090fc05eb814e2d42a03586c0b56f533847ac7b8184ce9690bc8dece32a88ca934f541d4cc520fa64de6b6e1c3c8e03db5971a445992227c825590688d203523f527161137334"}] diff --git a/Tests/CryptoTests/SecureBytes/SecureBytesTests.swift b/Tests/CryptoTests/SecureBytes/SecureBytesTests.swift index 7845c5e2e..5be78cb32 100644 --- a/Tests/CryptoTests/SecureBytes/SecureBytesTests.swift +++ b/Tests/CryptoTests/SecureBytes/SecureBytesTests.swift @@ -172,12 +172,7 @@ final class SecureBytesTests: XCTestCase { throw CryptoKitError.incorrectKeySize } } - XCTAssertThrowsError(try testThrowingInitialization()) { error in - guard case .some(.incorrectKeySize) = error as? CryptoKitError else { - XCTFail("unexpected error: \(error)") - return - } - } + XCTAssertThrowsError(try testThrowingInitialization(), error: CryptoKitError.incorrectKeySize) } func testAppendingDataPerformsACoW() { diff --git a/Tests/CryptoTests/Signatures/ECDSA/ECDSASignatureTests.swift b/Tests/CryptoTests/Signatures/ECDSA/ECDSASignatureTests.swift index c60b33170..a13eff23d 100644 --- a/Tests/CryptoTests/Signatures/ECDSA/ECDSASignatureTests.swift +++ b/Tests/CryptoTests/Signatures/ECDSA/ECDSASignatureTests.swift @@ -226,26 +226,12 @@ class SignatureTests: XCTestCase { } func testProperSignatureSizes() throws { - XCTAssertThrowsError(try P256.Signing.ECDSASignature(rawRepresentation: Array("hello".utf8))) { error in - guard case .some(.incorrectParameterSize) = error as? CryptoKitError else { - XCTFail("Incorrect error: \(error)") - return - } - } - - XCTAssertThrowsError(try P384.Signing.ECDSASignature(rawRepresentation: Array("hello".utf8))) { error in - guard case .some(.incorrectParameterSize) = error as? CryptoKitError else { - XCTFail("Incorrect error: \(error)") - return - } - } - - XCTAssertThrowsError(try P521.Signing.ECDSASignature(rawRepresentation: Array("hello".utf8))) { error in - guard case .some(.incorrectParameterSize) = error as? CryptoKitError else { - XCTFail("Incorrect error: \(error)") - return - } - } + XCTAssertThrowsError(try P256.Signing.ECDSASignature(rawRepresentation: Array("hello".utf8)), + error: CryptoKitError.incorrectParameterSize) + XCTAssertThrowsError(try P384.Signing.ECDSASignature(rawRepresentation: Array("hello".utf8)), + error: CryptoKitError.incorrectParameterSize) + XCTAssertThrowsError(try P521.Signing.ECDSASignature(rawRepresentation: Array("hello".utf8)), + error: CryptoKitError.incorrectParameterSize) } func testP256SigningDiscontiguousData() throws { diff --git a/Tests/CryptoTests/Signatures/EdDSA/Ed25519-Runner.swift b/Tests/CryptoTests/Signatures/EdDSA/Ed25519-Runner.swift index c39736c58..326bf3d68 100644 --- a/Tests/CryptoTests/Signatures/EdDSA/Ed25519-Runner.swift +++ b/Tests/CryptoTests/Signatures/EdDSA/Ed25519-Runner.swift @@ -57,7 +57,7 @@ class Ed25519Tests: XCTestCase { let signatureOnContiguous = try orFail { try privateKey.signature(for: someContiguousData) } let signatureOnDiscontiguous = try orFail { try privateKey.signature(for: someDiscontiguousData) } - #if !(canImport(Darwin)) + #if !canImport(Darwin) XCTAssertEqual(signatureOnContiguous, signatureOnDiscontiguous) #endif diff --git a/Tests/CryptoTests/Signatures/MLDSA/MLDSA65_KeyGen_KAT.json b/Tests/CryptoTests/Signatures/MLDSA/MLDSA65_KeyGen_KAT.json new file mode 100644 index 000000000..4894d91d9 --- /dev/null +++ b/Tests/CryptoTests/Signatures/MLDSA/MLDSA65_KeyGen_KAT.json @@ -0,0 +1,127 @@ +[ +{ + "seed": "70CEFB9AED5B68E018B079DA8284B9D5CAD5499ED9C265FF73588005D85C225C", + "pk": "D2FD03F3A1B7F635AF9F34D580A98F524C735BD5BA2355DC6E035BD21765580CBB111923F194A7CC8A7BB2EBC5C0E71AA637CC800E6103B850A539B2A39E1B6D713E5DB8314C9AE1F8BF8A38F06AFB9D73B161B0FFE3A4891706AE26D54FFB496DF8DC0F1983509500C9ABBD28E59B3FCDABBDADABD45EC31499378BDE849E7C1F19B7044D67E05106D7136D95380D5605D4465D877557065DF0A75D3C28542F40FEED42EC7E280637B083D988BCA5F6394E02396C4676184FB63318DAFAF5BBDDE00E308FE84019C2340A3F3E1C0865624970711283356AE14BD6B94D1C9AE188DE1A8A2CA824A8EAE2FE6AFB38D83A2D99996AB21FE3E84C0BE6B6DA08879B677374FA7C691B13D40FA9D4CC26B2288D5A8C9A43724381004D61B0D57FF400314C8E30EE796AF10F7EE21BF13D08180465ABC72EDDB080C6A07184E3EEDC47C19AA7F09D1F3309E183A2BD9B0573DDE474A81BA4F78D0C523D0C04F90060FD571A35C037E079C5E210D7390DF568F2E2F03CE44420C82F3FE69EB9B48EE90962D6B0F24440648F71EDB241EE6566FC1A64CABF66BE6FECBCB1387C82A7BC202D9E367998E2A291AF0CD1570677FE8D63A3285A2EA6EB29AF9DC1AEC1C36C4706B12BAA20839692F286A6E0321468F7479345C4D52FBDB2F06725B554B89E2492612681ACEBC6C7BADA9225818DBC35D64C22C48BFF80A730D0716DFAC99DFD5B8992611D0C93EE90BDB260022AFE25D913E06EFFB59CB1F8A60CBFA5AB2F459A16F467E989525E0A37EBE56E833FDE55DB9D1530ADCF45846DF281E47CAA1E0A27EFDE2107D354CEA0F6A454692F04CD838EBDD46E191E5D9C11839A2C3F488A4FC7CD265A7B5D32B08CBDBFAB9D2CCD76222C8EE37DDCBD2AA063ED861473A6454CAEA377850B1A2B9DDBBCB374FAB5B12F351C8E5888872E5CD1F60A4FAE1FF837D192C22BEB41EE6FA392FCDF4550FF46B5CE906D017EF3077DF132300D8BBFA9BB03C75E79E2F04C284AD06A44399649C3E2A2A8D1EFE9B7A4E0C271047AB75908BFF7DF9E30ECA547745BAE23A86FF9A8B58C2538B88B866401076902DC5F0BD761687B49EAFE36D350CBEDFDD36C121CF23786BFCF7E47076496EAB6BBDA774049C2EBABE2DE99C4C24F2DB73684015B373977496760CF9AC23D8B623133DB2DE10D73FA6AD1C6DAC8434F28C6E251CE7293CFF3F3B61EFCB5A435123670F29846A13DF3EE712604461F1BAB8F4EBC836DE058978AE734396A98081B35CC98188A86949C99270D4709854C5B35B17F48A373134C814CC8A0F3E2FA807F2A918530907864778282D75E03A41B2504EED816A417A3AC6BA16080C39B7310192002A728F7F20395009A9E16767CE1971F5DE7D229A50613369E4382045A8E81901F4DBA8102F3D413FE35B326A874F233B719A7137600D35D33AEB6B7259624083AA968730C8F78292AD28F14EEABE660835984FE69EF23DEC8C327C0EB0B882D587E1EC433DA85C9FD1E0A34994DEA240C854452D18C30F496E49EC904B602E0F5062EDCDA03280A53B4313574CC2C0D5471BC9613BDFD6641F5BD127BAB5B5EB3D499A33114048220E819F8EE12CA922C8F17D9C9F51AD5BD6883B10E6AA2483BA49DC547DA7686151344F4E9099B38E430B5226B059832CF03DB48FB02DBA4E61593DC4576360491890E53EC0E6AC73CF32B25D823B38456E286505A541E5AEEE96B1914F5F76687CE2B0160227ABED77993594BCD831366206D75714082F1C46F1F4439AC81A57AF31C81C555307A070FFA94E0479B784BBD88A60CD4C7CFD94E6AFE02F6B21F72AF0DCD6609D40C965C14E5F2389183E53DE930F7DE1D44215CF49144844E8B87F78A7F132AEFE22BE80B4E3A05EE3A68CCF609EF44047402E4493046E6F9C767FF8A75E28B3CE077FDE7E7EED313B5BF7E460127CA8182E9BC794C0DFA730FB920080575A751B5CAEC85A109B4422BA266743F0D032BDA8F1CA6248CDB917530DF1302A5F8C18DC642D52478C98C12A3F16EF2B62B4F59EA1BB58DE7B65B3C7153CE6DA5E4950746F80E087A0E3586D097791BF36DEF865D68591D39D0903773EEA962147F34704138B54DF7924CDD8C333DB5E1A409CCB2B34E2C3C8C7FDD3FD8D012CBF382AAA85E83A12F235A2D147D035B7B28B34B6F57949F322482A7D4D3B15045C420D5ADDC7F0E69B4DC1CBA58B01D872480B06A260D827D891B13C4C5CA50C748DE3C771BE61E9AA170165CB01F4BF5DA27A7791D3AD3F6267B4CB4E61B28FA1708418D932DFC4161880C5D3B17A9663A9061FA8F1804315850FE4E7306C882B38227E867F80872CDC1944D472615EA4900EF7D270B881D4130F56C5CC980D92A47ADA6657EB6F37A385D2D8CC993E1442EB05281853636991E34AADC68954D04E7ADEF76BF880F059B0CBB55D915A4B123E2F1339A073CBFBC409BEFF6400AE096D5AE18EC42CFFAD5B4980FA35BF03413ADB5D7E6876AC355D1C9ED70CA2B973954D12B3CDD76AC6835DB96003ED8C4E288B71FD77DBAA7635720E12AE0A317DE808C664E317F55275791F3245CA4FE5D4D41077FC150A6E403D5A208E46EADBE8F2CFB8AF472F4A0CEAC015219478E6B86C958CF86525B7485C1734C7EF00E90683FFF5DBD0A7D413A855021026A1B32013A4616CBCD3700ACBC705BE3EFBA625C69A025267BCE9D135E3F5B5CC8C43956407E84B6663103E29C242035551AE797F56C6374BE0C798C0CF398F1ED", + "sk": "D2FD03F3A1B7F635AF9F34D580A98F524C735BD5BA2355DC6E035BD21765580CE38D1C14F6467C35A9F380D27DE61F7C75031569EA2EC8260EEE9105261B7FE160C91344B0C6764C204E5B8D424650BEC06B9E2E625AF07E23F4950CA24FB4D6EC2C8B3A717C9311EB87279FE25E311F48B8256501F6463412B50DBC89A869BA2241112648400738730212442544575483725033356258423201621183610245665648356120845260685045655512724747212125402221428117650306426152134325243382121135623332074786223150837084264345645148311486246686743371366726014707721161588558387183806701657870647785600288534846622583548804744012574371077544387121142208887223588746148553716773822822741403577328718380781434875207647401607561060861322146156542670820841073130361028650452612166833552584735354526517106000385777812426804146432667410603554128333725230677821516317300087526584634638808846451112405321011181864782241003855754210468343733880078343787413576232688065864853483551585074460588700772013100875488142084166115605685115808058863018286131417220168171786585310622852822615043142885431780580115045688233663636406515244767064536422686750635413347851217808387655142313887566205174085281417213812608124414575018287101002132557042172427861117005304772132030216744315771455710541665741524024371512055116783678252533566424613702232740007068187175780286801721004275522864253158176308640831143305382735303723568704541157314123164326663562151508210302338172127102314227577283771627506887214187313030150715862866288868603270146172271385381703388681378810486573016523140830756821032312850065081630675766511601417121255564811411328826207476424482324775326081758115637483551478685666681732021367522746683445700666477204722285687124702480702542301257137367536005268153335820613732408717615224260185343116457761761566876606554781033631421832160155580423842031312343625273082812547513544126735001001838574424013036127812626811887435120627127515610222281118141666638208675561240065461127440345858781007852572885722222550840041260836462878467805022820771360751443687864313877737355412700540708286880045383432281006435486766501775761275438162403343453887216614704841431466587845820225457315213203024880801371255432720568652468040616835054533737272220680825508472867422361680075518121784448115645071105815511010471621075861187800527264521743234076486730776364875131638468745363842354661048363385214842038251103357468016433402070353221275733465833387438517503660880258758088316360182132261568741110331413053416726535501334808710264868845271442358803557705484287055888683862521827261177885176773005771117851106563570287401340012653451205467518807033356622620070232687726311133333814170622861514731302546511761580741613737061400548877756777665316726666887643583104875706764700436358605203442736486123721610624208608323540355557300610365342714158662558016531018261135468246132583477050060156021168545303687336418886334252015833423288568177555148481201581385041471835707545554552827313602123268321382587028585344867273428418220883610214161712415748852510260736761266172132360325411011226660161632642605186351585131425384566627833354507646508025434157357825430282384745701567517747803152750000947BCA93C27D584E2C66EAC9C7640C1CA217EEF66DABBCB260B4C34300FA051357820F57392544982FD11057DE233E6D2DD84972A7E47D4DBA99BC30CF8F2AD5A2C0243195ED2730FFA92D227D153095972D4B3447FFAC45A23EB41CBC87CDD1250A8A478B0F7A1D5B39AA2206E48645584FE7BF7A13168F482765E57BB924AC6D9A11369F4A6AFFCD169B7D75129B35D5134A31761BB8355AEEED27E201A06313013E307A01A73AEA7955C0578C8C5E5A1A2D2FA4593FACD904C62040BDB9F329933536BF8D81C4256BAAE8723FD4DC66BB5E7F9CA49031A193ECECBB5DC390EC6D5513C79A052B3FD43612FB7375315D8091F79BAB1318F17854561BC93AE0E5CD6D131E562C8114810C939AE563AA10B47CE4484317F34ABD02D0CCAD58DD29BCF657BBD9254B01CA9726091938ED32054B37DD617240F4434C1A4A8711AA3A399A8A5388330B7059ECCBB6B1B9CF7187ADF10B0C9171D3C0F6E2D460A419247672E3B9FEA2C95910BF2FB6A5D61F257453B07AFB64B0BA2758BCD735751F2D53515E236FE8A5B4393B80BF06DF97BDC6380087E6AA8DDE6E098111A7343FCDD1E903708E637EBF28323CDA6B9405810EDCFB3691149ECF224C50F8DF92A94AA4770A0E91466194BB0E27BF1CABF16ADFD351220033F76F5925557BCF9634E9461359621D80B4BBAD7E2A6E432DC43B126CA42AB88AA88F0A84AF58029C99A0248F0C454071F35B831FED1254D6F4E2720485786215F7C7F0C4ED15FA853CD3AA07259B39240A82135C2923A72B876FABB3F0F2C09613DE39D459A07C14E7BA437D8041491FCEC1433404BAD1DA9EE9471E17CB691B2A353710C9FFA4E5178112027764EB7DE809C3E1F1FA4178A5D4DC9EE27857EFF26B91711FC144D5A775B8B50D5DB939BA3207680C242FC821947F934C8DAEE203563D28606BE624A32901932DAE85712AF6C8016026927E9B8129574BE3CB1E95332B052707AC8AA8F435E88B7E568D4987C6AC0E902B0609A02D91B3F5FD3FD901DDD0DB9873BD7C71ED921D4577A78C4FCC9BF075203D38F5E76E74F277484E057B6189004131B0C9B1A155294D1CD3D5208E266901D7D314FACCE7E2AA584583A11E4D7C21B94A32E508EDDBBD7A65AA86B4FDFA6BC285D4CFF53926C7173FBE1F89CC303234B878C6B8101F58AC8D3E5E1BF5AB6B26297CC97B95954AABDB25BE008A3F47E56487B00D3DEDA890D92C83957FEAC6B8291AF65959E1D1FCA3BD196E9FC9E67E0607094822E5B4191DB96824B9F03F2EF57F5238BA7E1E84ED55B7DFF3D6C2C1273692A9A19272166130DB89FC67DC94DB614E3E82BA3A3512B012D51FB486B5A3150B78E724E2A12DE07D8671FBA2DA7FD5D147208FC3AF653E6520FC40871AF2177E65CBD0EAF304217B367A665F224CAEDFE93006AC1E14BCD67A88D171F3D8F3E358A71926BA3E5C239A531263EC9437BF2A033B8B55B2C0CB6E7E97316E22DF77CAD910D20EECE1C50910A5CC32ADAB09377550F92D5BB1F4C07F4A2822338E2CFF5348DF77CF8EF8E6657DED1E0CE058E3CCFBF39B3F166E303D33C3556C9AC8ECB3DF7C74AB36D0F2794441BA9808827B578FB5C29E494E21539AD3AB2B41BF161D7F69589D4524C54C89B486F75D252F541CC63B9E706D64A1289A2306C595363CB6FBEF0A1B5B17AB5B1794BF27036F64EAF0BD430DD58D80010CCDADA4A5A3A1E41A6FBF129D73779A37AE5C8D6841A9993C51E364E04FAC8E25A4E6872F6C860FA265C1C4426AD9C21D26DA8C278546ADCD831F2B8B26D4E1F670623D95C8362DA662D1FF0AB687503F328DE095810EDE12B49EAD1533519558C1E940B46E4EDB027BE9DA2039B25DCF7357E19E5416AE268C14FB3A8BABCB3D23F70CC9D59681C5D833AC22E653D86E22CE822540755D8D243C15213D076C6B26436DDC07C7E001347B0CB8783DFEFEDF275FEC4792686734007F0FF8540811C2AFE6CA151420532FA5526A1074C3D789F2932DE42E3ACFBF94760F426D96CF033FA49E2F458F9A9C2E71DACFE009DD9C3F3C8AB3282D6F383B981C82D6364F0E4BDB2AF6A95BA61F474150CAD7233F8903DF972DBB0328C0CB9D0CCBEF883D2E6ADD180ECA1B662FC1D2DBBDDB3634219E1EFF38B1E52875356C03EADE942055F483504BBBCB4302A417CF6D328ED793B1A3C0969B7B3418F50AB39F83C5666C90E38356F7F9D494A6DCB63D67C34E3D14A4E15596497926C8568D8EC3DBD9C2E82C385BCFB8D9674863BD4FBF1757DB447BF804AE950147C91FBF9AA17891044CCAA73B45528597462CED751D015EBBA9E2B7CDCBE6DC05AA9EAE0C86848A3475BB1C5744F5903EE4A842A469CC181271F245AD70D02A4837863B296B4ADB4E8D03D82B64AA11DD31CDF21EDF1DFE3276C4DBC877E35B15FB2835EC3A1C453168A38CA8E563CF3E9A00736CD5CFBD2841D10F94AD55799C2927E5461B28BAC5174D0CE3F8F7CD7609FBC8DA0C38CC21695CEDAD12F8D2E64951A8996E510D6D52797C5BA0EB4AFA6BF2CC43DA09DE3179E899BD7188B32A98A499D372F3707CED479B0981CB50C0C0539CF7E3100B720E466652A4F499C2BA3A17F5232268730B962BC572C0DE96E8C9E28F7E3532C2224196AA9E27688DD050D7CB7854FB3C35F9C62EFB10DA84833F29BB1BE5EF3B533638EEF743D8119DDC290BDF08B6F0F9E4E1E13446C53ED69805DA26908A15DF1C48E009EC1253BD5A5898EBB5121CC24904C8B10E24E680E565985076FDA11D13FFDFA4DB28AC9F0AEA2F81FD7ED4DCA8D3B2E3848B4D6046F6E0DE3A4F683F25E0605E84B36F483C404EF899CB3FCCBE8CB2A6F0A7E10B1948CD4F93F181555F661D31D426808BBF9F66FD60D649269CA3FE991B22428C37AD2A08680F747CC0360CCD373DC6A9F43A66470E014E72B3D8C38E020442D8AAB974E6049374145B04CB7F3044AAC1EFDAB2A18BB464D4F2F2D8143974C95EEE856D59EC00288ED43FF5CC8803006C995514A2CC9CA622B61BCD75EC51C202A917105B4A4BED1B80146831DCED07EFD2ED25739F54096911B150D3077CCD731A0361682725D53803F8FCEAA83919291EDB4493EC84CCE1D0F82A679236EAD1002AE8018CAC9FDBD246FF093D803C0DE3326A57907B0DD6B01D081458C75728C600829928890A56AAAFEFCF7423B70A6D86B415B8358DD044ABEE00B9C9795FC8F61A64686DF5F876A8F33061599AE830F7EB4C4BFF875F4A936C403C5D160DE5D33CAEE40FB718DDA4478AC6F51C59C2155254BD77671118411E2609D000306FC9507004A31E8957EA40C2564B83C3ABB71A87C11BD18D7891C449DBBE79B4A4FB048307CE0E812B2C68ECAB77FD1111526AB0817306CEBCB0497C552431CE15E4AB52283F679480D69DDDE1F2579CFDBE0BCA95FC5B2DB0C5CC76A31950F5116AAE5F02D46710E4257A75FDEDF2F47CE37C203E7F24D3C9179713C5D807C296149A75CCB444F0C6F6ABDD2DBB2985FE267482858A1E" +}, +{ + "seed": "4B4B71C5A1BC1074F2167A1D68729CDB9E16ABA3651FF02A0A0F4C883CAAC827", + "pk": "F8D4945A92CE46DD24D751DA02F068482C69B0DBF0501634C4A247E1ECF98B270474C81AA0D8F45C0E8B5D02751E797D101904586782EA09F4E3A567C2BF5146DFBE766BCF8D0E4EF46016C6ED7B167490FD2F8E9C53CB42660331B1B62810D21477F5C9301D6D054FB076E77F35C1942AAE874669E0957A031223861EB563AD723781105567445B5422B179E4828A4306079C4D42B793A1358B05D02D4565E4AFA2D1CD32B6E7A4224D3A86E8AB79E1DC33A11D99411636F939C3AD0D39351CD057FC6BDB32ECA7427CA0842F70B416DB14518796F68C66E3CD04720DA02B32A3430E0E027F48974602EBAAED0F1FB5763A914CD6DB7C4ECDFBE076B0348DA1AE1F67C63EACA5DD8C27AD54900779952239539DFEA22BE70D54661BFD973D1342F71F6A97CE798EFFF852FD789DA56C867C1FD2317C8174CA0E0787DE99F77D264655A36B1D8589B4C4C1743E742C31AD19539CBF8366EC188DD606392D727A53C3BC4111CE2CD330FA0E484F19324AA5FD577DBB055A3BA6F2E964371C0D4B9150E4EB9155DB871B6A3F321DB2B3EB9E679ADCA62EA6F7DB5C4471F470D42D6C161CC1A43870E7BF845CFA696D71629C21D53A4DE22AE73C39837222077ABD8A1AFDFAB6B4DC5A2D68BAF6EC95621BAFE7257071A62F07848180FE4BDC29CE7CAF2911564BE1DB7DA45EE58852D0457456D19979CE66F3821C30539965E4C3A1691DCBB4AD0E7AA133185D2486860D4A5FBD260585241772B5976EB449A72494637DB59CEF54567F7FED5B0ED618C9527C28C38BA362621CCEDA11A00DEBB824D31C7D5B3599077B9FF736C3245F1F3DCCA6D8D74BA96B195B51CDC1C68E29E5EAD59CDADF5A05B924B2A790F80CFD8B8B17AE1FAD36ADFD77B078C5A535A5293696C7259AB0305C589B2986B6A841F21CF8686D6B186EA538C29C7654A6AD74DAEDCE943627BF5D497CD7611DDD900EFEBE11F9E611F416B0694B621D4EE741CF21759C92BA8BFAC90ED9D274A9EED59774CABDE532D7644D048B83CA97BFDAEF30F0B2400A1BB647C7BC9E60F57451915A0B531E29D21C2007AAEC522F4129A7C251D7FFFAB20BCD5B0563ED78814A3B2047A375DD9A919A3E8FAA0EDFF63E0307EC9CD14FAB372E965324CBF541D99EB498CD093B188B1CB79DD6ADACC1C9E306483BE70C1BDDD1F67B0B86DAF8FD905F7BB6239138A73300C58EE30B6D48244803A5FFA9936B0A06B16EEB2A880FF2FBDDA1A0813006C96ED0B6A30B5D10528CF5AFD45BEAA82369BD8254A1A7250048252EEEA523DCEC9FFF069006B2F9A8653103D47ECF79BDAD2572A11871C018646505164837DCF91C2E22CC55B344990BDFF2D50363FE34A19C5CB46CF0C193175248EC50978F2CEE4E83ED2B7BBFDE4471859017D3418CF3D3822BCCEA6B8D30CF11FF008569D9F0BF462CE6D73F8C119E3D3AB30A68D467CC60A907661FA1DD47FF3977847BE38ABADD7D4B4E1B127EAA131BF3B0B1FAFC57165B69A48500753B9DC141B9819CCD9B4CACFBDFE4E05CA5CDFEA912602CFF1EE04FD2914780E713176AB4383F3CEDAF2C0B5E6B640D3B5905EC8EA9630BD3672A18135701E4140627E98F1BDC78B05D9F2224C59AB3951A0653E6729B7B4BB0035FC964C15086FCE0C6AD85155B940C1AA13428F1E6C20FF95661D283F2ABE3D43C072B169D68C740E67E3CD9D44D80BBF1D455204D3B56F06D9CD266A2A928C918F737A9E475BE20F26D97A3C0B7194D6043CABCB8BD14BB4BFA94D13C0D9BDD4E6B062D4685D22F3DD7A2EA64FAB53A0E06E0E425FD487E333AC6669017492AC45FBB9E2313F6BCBC6E484A5965E9412FABAD6A6FD03675CE1C70158B33E17CD18FB44392F06753D565FBAB2D4CB09A85EDC20C9C12276557B03DC41B7042A0D7FCB5D236BEC4B907F6FCFAC62C3A07BD92EA85740F1A501591FB8D930A527FCACA427A61256F6591DC1F3CBAF19CF3F9B5AB5AAEC97A95BD5D9056F5E463BD86EE03D1CD5A14312DCCC3345958DE85488D1DB2C54D3393B8BBF90C1411A9A8B3BCF9A13305FC5AF52818FCC4039D5C8C6ED87D8C01A089982ECB6FEB7AD09A79603ACEED01CF453B4620CD36E73B76B91924D9BE973C8BA8B5B360998A182F9A4FEF5563A0C5505B18110723A268CA4543039979231FB082A639658B9F5468E1BD16F96A158E0F39A160109A7CF244CAD177B2B1F41806279296E7D6622425B75A1320E7E3CEB2DEBD1F739B29A8A3BEF23D5DD2712A82E320450AACD8E9EEE78A7D019AA09E42CD9923702086829308ADF09C0D0A88B58B2F7C4534F75631AF1A5B0B68552F402481F9A96B6A6A0A14E93E2772EC72D286AAF2CC9EC6450E80F42673A2DFD25C0E0D5831DA8ABD631966DC0688C38D602AAFE8BBAB8FF5FB9003BFE2E45A74A1261598AF634F896CD8F4C04C5FAA6442A788121CE8163A085B4E66308FF572CF005E960C8A21A82552AE6DD1ADDFE08CA37B82DFFF782609F03DC16E0B862398C9FA09DFA4D35510F4BA7E77C0233CF923E4792FAD9C5D7A05FA174438537740EC822B2670BF1F244280A5A7080B21CED5646F5077CB39F23555A112FA1E1458BC45C491D5092B763AB7D291B8C07BBEA2E39982CA19DFF6E4EEF17557E8EF101D808FFB6ED73DAECEB77C4CFA2E391CEA50F1A75801C2D34407AAAC4B5138B4632A710A40F39BA7ED36454E0B054E00BAFC027D01303273DD2289E7666D98C3B602CFAD31B7680E6B1572", + "sk": "F8D4945A92CE46DD24D751DA02F068482C69B0DBF0501634C4A247E1ECF98B27B870452948D3FD91DFABBA184B7778E2223C610196918C5AC471FFE27C45C216906A32E421BA0C8EB43BDE774C8151020BB33E6DD3CCB67E07FF1508A591C40F29C4F4E03C0761DAFAA6C4E4D7515D3D044F7E5D9B6F76C3523F07B86B966BC2050273654131572050232540265501410321121824027783508650550741845227675205140764772006807238701150672363522380823186775485346122741232101846044762034061346508846856004508217531847506553422270003465001318843366570722341256676412710345762503442766148802031700065838665810155802123526425443477780225517686668627385732838374183830578328430875075738806006057215372237255330206645686206532007402436187730431525465867647825811554786647043104375540063472868467521138444506855840850622072745156652883730438734305732524737387063014705036441133615604518408815122131125202504810267182170514218811002085201254838156820201088584847214346753735887361787368723385680274880675716073083468858754024781441460451718621650764072470876430018540463314037653043260254403334013420554376741651526887384367232437772872571236432846113158844048402448026234443446356631655624571084504437148135030305335563616217056075630605830233420552628432373442580105268442188606664005688153573261574404273251112701374300315715427425557365723036707713333154501238558575528577180345582234204444027511078611230842318434676756513328416871728302630727767221615188778420705148760282006015420340813653580172668162025543061257714607056886527838253463775286557467874302385541175163873125403136883123024782644056005776454050450463856458231030266773238561883245373725805362358236861886558048054373517006153723263352805784612747766872528551515675467320836133213785558662842164780507124010780705382731865322261671658563251820625605486727154222632331845371780377110620406316868745534211605053684662067164782272500355338031585232841457166288521403104854878437265654262373837268281560786012704588254043617732675622047062353066104016602755704578677260376636082632526506057173816361868253348168171755151062823522066020418818632307513542804243556317063765822868038468506613448543036820231730106212347485234367884828616827033357121850832050360848747865116708334325478114764064545882530235517784101378158280387668200424153038757453662564868561401622005841426338428326845853813752150205647048731768316114171432031210530176405308626212315625877622410617144857321075301351544462610553051243543667566675865335022131344837646363774338358017020828322812301042686502414653278867536671246033825211786357550517555870412326345585188457210000315518722276643085112001162624655523063655320741885067301234547663482785273242871867433610317833314257358238168035870421442233173234774652833582072540045143452135211450447284405865524301678168533008608553068110010402510031273465112253237686727627477608688360860655175382170833104267041778753258183846702848155552758183213003518102058824468267721170670211086383333614167717873621734000234476376137205763060645015200727731656541667312526120835206388554240354487387761200858280506664805026810157822733523020574251831872646604616365770712618804337567105781AA2BBE68AEE92FFD1BE88D01DD90EBC8D1A9F5DA65FB482FA23E92A0BFFAB2416637956B1A4F7D0E392B910710069FD0E18EB26E6CA741ED0915FC9FCE0C0EBCCA45C7BE24649829B0AC3A43C4CC2E4CCECC827FD3191515DF2A120359341577BAF0BC05F8358D518A57ED3033A73B8230E8B23F627F6145AFB0ED0742146C61A21AA6CE40AC75928F007F39E2696383FA48C75694F106E623B6F41E070D0E985E9D542BA2B5F53A47B00CB6472F9D03C3DBDD1C113B08128105F6FCB281C302C0410C32234E0E9F279AE96F3CEB0B0A490443A8CD46BDE80AEF7B1BF7DF48F98215B2F556D0EB916695417DD643C93AD1D703CB238418C6199F7FB4936CAB6490072A245577FECAFA7507A2ABBF3E2D185D9DCA22CEAA93662168F43ECE8421B7A9A5A2226227F22BB497615426881EB9BAFAEB7E14A177AC6102425791A1511FA9BCF2B3E453CA701D0C8AC45714541A0478353173A6EE57078F1059517910BCCCF0C9842483CC8E5D35166AC13BDD7D9C760819752AC40CC61528F4A93749BF5711216101CB0EC79B6E0BB92D4F9042DA176E6C175EA1B2738B7A6355551AF4C11AEB5BA92ECDF28E521E1730598E480A6EC130C65388FAFAF5BD3F43F566D0206A6CEFFDC01AEFBF52B46BCCABCE80AF453D1CE840B3157D4B1D15DDBF0E864939A5C411B471A9077E5785ED9928EE1C05E0BAE9D4FB8C9B0B7A814A23784B04F63BB5A533AEF4C186217A24302E706AF88D4F9E85B71CE427D19C149E01AC698EBBE6B5CEA2E3A43DF2976CEBEA3C96424D2FDA27DC3DCD7A36990CE7B9547F247039E83194E34B3DCD90D65D3641AD5B90C4114D0441FA46FAC16A9F0691B36B39012F2361EE0B87C23FC454B21205AE0D7E6D9C162061924C2513C369CA744DD2DDCF9C0C314413D4898311080757309D5AAD1A3761A3223B60F66B0E392F821597A011188BF35B25002C298F01D6A5463D3176E1C7FD0FF1A70E112ADF9230E9FCC9C423E310E67C35860A09CC4D3DFC4EC0B16AF467373FAA59D0E326D82B6054382476A1D47CEFD2709EC829E3B29AE0C09E6B41DD540CEC37F0032C949B9298ADE79306E376C6184FBF7440C14D217B1A557886CA79AF8625DCB9142126A70FAD6F813F3A5625F2E138E625D38B399E20AD05D682552180FEEE5C1E370F2B6E6D5720AD313B98BFD466468C727DC1F2F1CD141DC7CCE3592A46FB3C63302932B832F309AE30E6714AB952AB84D76A59306D05E1251171F8C7F8B7B2ABED123D47428741A8583EE5B8E973950B4F5C754DA4679F3A06EB18115C3049DE8E232AFB65747C0AEEAF5716FE5B89AD6ACE90F8CC4E137A8D9C65CC3A98C7FBAED0E7451A8F623890538DA9A7B821D8CD9F49A1AAC810EDDD7EE00AA8CF342F0491A50E617DCD535242D54F0EE8392D1B8BF7D69C81FA335FDF4AE163A1BB7024EE883DBFF9A1CE154F4316D6063DC7283F151C4ECF5A9E8D1C25D0238CAB9A925788FFF6BD68519713694B231A07E826CFB6F3910428E3219116782E07E132228B558CD380591866C028E1F3BD2327BF7C61FCACAC8485EB43213C20922252B2931861E077712CBB5701876BCF66FAF1CF6582D4F4EB87CF82C1B7807A255E73DED3A7FEF23139DE96AE800C2922246A54F3F3A6EBA2C8E8388DBDB41A4131A69280924F6D7C13952ADF9F6131C1D6AE6A3A085F8FD5E4A45C2951A8D65C345CC067B13CA32B1A6C28A6359C48DFC119FF7AE92054169DAC29119508F17FFB0BC925E357AF70B85C214DB0368E1425AC878978C346485CFEEB9935BD94D203E271C2EE9EFFC63C54B6D05C15EAFE0D0D562C458B0C7EB0D84CC123FBC30EAAB78B47F9CB11AD7ACB54221F56998177D85EBC62DEEA042E411707FA78C545445372461BF5D4C9E4B5778BDE3C9DB02F697965D2CD2A10BE66AA9DBEE728B52A9117C53A5A2D90D59F86D8A601436CA41D4A99E3C2E66261E37A3A5B7D4DD21CDD46EB4C62268520FFBBCAA8BF3DE714652CBF83E7E2CD57FEF6ABF8946392A33D984FE1CB1A08FE5DD088F974499B704D94F0646C7977DCD7A75E8012CA35E39CA7EE7AE1C0C27013A32DEE29CD141379DA504CFF6ED8853959840E829170D2D15A265CD9A8BA48718848473090F40C1BF3DD4159267324BF9858400091FCE515D541F6608D395DEE9C5F673375E443F104339F444C4819A630232EA7D413CD8A3556E60D7D20ED42E45CBE335AA1EC684CEBE7B32C5BF4F68F969932961930247E2A9F279F5C587120879F3F61025D6B6DC617C9FCA4AE8034B00C8DFD6797061A36C12979E85F4AA7C9F7E57FAE4AA44DB1AF6306E982A723B6F58E9008B4BCF4A948FB131D08AFEA9B4BD093CE76F8F6366ADF4EBA4E31FC5EE6DF22E1FF1370C81937D29007A9138904F569B95A38C5DE1BF03711C9D41FC0E72744426EC510E600D1231C99C7FCBD91EEAAAAD1EE8A27544D0AE7871B4B881D80DEFE22F3188C250AB8760277BE2295157BE5F33201233B53E2348661384134E6A9BD89E8F85B2F4E217368FC86161F491413C8959DB67AA5D51DED0854FA779AD305E3A6895542CD84DA2E8F4739585F7AF91DFDDCB35F7E8C6F90D1EB810D8ABD36334AA02E84A4CB0DF03961F5AADC0CFD45A7F59678B06204CE0613F040F3DAFCFF3D59C56B655A3D3A0359340A0F91AB9AB1A17621A1A57AF588C31385D44667E9258E5870756AEF7AD2E2B3E3364BAEC218E0D6BE14EA5139FD672755F7942F4BF9E023ACF94B1E15C58298E29B958276F0C4F04631D41D99559E7A7483AA39252647D8600D33A4C8624D9A663AFA8C927808072A4C6A63B92A76F76A79176261D9050E890D52CA68279AF0B09B443C001A4092531BB8E251F7ADCABF4E49DD1616F42528CD67283F2C52479D7DFF2F383AD7EED58C1621E4DAD50AC9C9FA5096ADB9EAE77B19122ACA00D48E967050303C93D90976A3DDD5B3BA4A816CF0019B508DB2E65CC47B187C78432E41DC9BAE328EC529DC3F6C6BE048CA843832EC04348421113A02B60B35CA66132059D4D5EC297E9B92E8AA3130E30DAAD74EE7E021541F0B3FFA72DF618969D18B7C6936242555FFF1161D85C033BBB934894825BE9271EAC5A445363743F81C46315F547995D6925FE76BE6B7145D022AD1A015C0B8101FE30A81D363B2BCD627BF178FF12023F1BD82665393A49BFCC5AA1F1C4FA318736A301D00DD5D015A14640B91E104C814056892DE7C624240C06A3C5AC14E565FE5FC6170BF315913CA6F5BCBABEB9C110803E12D81CCBEF3C48B0DBBEC02F8616227CCEDCE48437D801861964934B149CCF34FDF7D60D29FFB46854CE5F3929AE9B6C051C6825399B9EC10A9BAD1586D2E75DAAC68BA2527B021E3153F419B0AC23A961799F016A37572C91EF790635A1D7B7E7968AA570B5897C6CF03395B5FD2022114BA84DF417F8F105810384BAA41EEF2A5B0C7C3E320237BC67DC36809CEE73AC388FC9A0873B2AB63B638AD364F28B1B7D002EF2CF5C" +}, +{ + "seed": "FB27DBBB4ED8F4F7D2700283C2B092866694246932EEACEE72DB730EFD172576", + "pk": "0FB4B45D59D6BA35576D1F75ECF682E5C901372E65678E959DD61F6652AE3F0533A0BE6A3BEF98F0A550CFCD43CB1CB9ECC3F4F7DB656C9FAE8122A0A88DFA6262F3B11454457167C1DA30042867A37B26AD62D594591BDFDB36B833DC83E4B8109CC2EC0D4126D24B2BEA48781FBFDAD7659F1D8E60987B9722DA54627EB895226B360C61FE3F2A10A69CEFABA3219AFACAFF22FF5BC7B564B01A65BD698AED8A7AB78812EA6960C2B766783ABFB85613B069A7CC173425F701B62238FEA489407ED3F2ABBF538B1184996CC7B9AF15FB5754928F552AF73696B18FEE24038A1E9A11DF0C78ED6814CEF3671D60DC38D483DAA6A6822FB4381FC036C805C8D2B7151BC6A6B12466211C0E1EE663BF4EE737F4D942881E9675FD7D87709B5F473054834599DFA499306B3E727EA6FCB7990E0ADF348321DCBFF6FA886C5846B1D05F5E08C6C4BAE416FBC7ABC1867082834616E3B4757616E9B7E04E2013B534258015E06A114192F48E3C5F0E6A48775EC05F554D69843684FFDA6A2FAB8F2138817596115832AF77A10E43A4FFE98DDE79A9F80C0710E5450B681D620BCE626FD0932B4D9D87BE222B7D0D8FD010172F3C5BC2353F44C08470871E38EB3DCAA19C92D3D028D61662C54EAF7ECA32C0D48F4AE0B2FCB0F517000A8BC96A76648347687815254ED5905A1B4A2ED4E43364B48886FDD5B86F90659AA03B2AD85B54D3E85E3380FA2E050120F555FBE241B86E481E020BD0AC3445CCE71D9F8FF56A7475B073F1F388454B3605EA18A5E183831C948241DA34EA3E1112BC706102854423A4DC16D9D3A79BACE600F8098AA60744E1C7FE18A047BC7646DA4A569E0A8C41D0587053A22209371E4BDF5A7CE8241D97670BD81E7FC61069292BBAE13D8F729B7F5C2ED3E90BCAF55DCDE5B20EF92E1E7A159B6205E7ABF72571F02505526928DB09F65562D628443925E7DED9586393DDEB4E59874077CDD4F7FD4CE68D2CD311DE78B245872AD56078CF3DE1D88FDCF541AF7D6CC69A1C96C2E5763BE310BF77283A820359CDEE43B53B2F004F2FA2F1725BFA6116AB9A8F37FF4011106D1E65C6A3828AF1E92671953C26ACAACBC48031D7E9919DA915B9E5D89556FA82E9498A0BA980892B9B9427B848D095A0BAF3857B6D6969E99CCC337EC6E166B1E1F55237BECDA10256C8D97A38B21986AE06DA7C80A17F84BC448F9539BF3630D7D01E12E80B616F5F98C47170DF5E16450D393CC4542FCA66359D48B1C29D4C997C6FEC087540AB588663F5824A4F09E5871A78E06C18D3A708CBCD7B4A957BB69818D38BE03888BBD62738DEBA58E3A6DB3FFE477A5EE262297F96C26ACF7CC419CB7F3EE8D09E47AC1B134B6AAC3191F7F586B507F58FF9AFD67FCA0C10E7676ECEEC78132EAAD0F8B91588C62658ABDBA03C9FBB0630B2E9603E5A93F9A04A3E07A09FA0B3AC4861D368ADB53E8FCA932F997952AFC5DA4058C48AE6F9B634B624E50D2DB8E3CFA23FE41C2B88C3C588FB22066A0894893D4FCD55FFEA4352F8A27D7714A18309B7997CE71EF16ADA021FC52F3652561A1D6518559C250CF1E35D109B04408C998E457F06F73349CB8BECA963EA4DD65826141A59FE60F1DE7F8D8A67F5873A7696E206E4EEA9FAD9FE00C97A07F7D7DAFF316CF85BC1A465F61A381B2EDB3EB4053B8F134B75DF5C6D133E7CF38AE416D24D4AC66AE61DB1F682A6B42B26A421E7497FADA9A97717D2A9D7B028FACF01CE14F3F834D84264E688BB7C0305EF9EF28D5A0A491B0C4AC763FADC1E260790E0EF2A70E6BC78A6D3A136E0EFA5D86C9C0993F3E91F5AE6DA55BEC8425F1838298F63601B4E9E71AA12C07D2FB6C0CC5661BEC9A0D929FAFD8AEB545B729C7BFF035E67EA7377D2162622018F54F780289FA8BF24F9FC2E85D06DDACEB91D064D4DDD3969FC213AF6292EF7FCBADA5CB3D5D1B5833CAEF100EC657056B69324F2E5C3ADB519120193157505F5A0C1044C0034C03A664CEDC465C79BC2B915B749AD0DC2E88DEB3FD6BFA8EE42631F22938D735186CAF7F273D9C8361851028362F54A9CD50536E31BF835D13DD4435911CF01B1A8E27339033690C35C311760DAB34E391FDDB690156FA47B169043E6D5E1AB721619CA3B8095194B7802A7FDEA8DCAB9F43BCFD1F5893EB4F58EDF1C0B9DDD0BD4615FC1EAEA46C68BB84697DF3787775E4DF560B1A43FBC7A33A3E084ED97E59C000529CDC1F97EB92E9DB331EB207BA478E3457D1648084D267C0603135B8DACAF2C15B42299DA433C0E5225C934DADA9B701751ABACF9FC47D90CEE43A2FA47F6D05D169623B369A7133D0F73922B2EB869E91B5737FC3A2DE03A3A92DA98A253C022B4466DC591772D39E04CB1E4F176C1A282BA15E912E2E5C8D81E00F92A2FB8BBB16D6B7733A785F620BF52557B3C3E87EBF625B4FB0B7B65101053532EA099A1B0264DB218EFC19BA207203089CDA1FC2B32BC416C454A4BB977FC3528E423A3553ABE4C48DCF662BA7F5B7E1B2A4E2DB9A388EBB0E39BC229AF71ECBF2F40727D6CD39C2FCE2464AAADEAECD47BD08FB1FA5B6627D274E3D31C078FFA3C3ED29980941CEEF8853704262B23DFE88780FD9CF259EFEEAB01255F0CD354A473848798CC5C1CDE63AEC6AF2EF078777CB67A4BADE7C3D5F345111FC73261B55E8E257EC5824CC829B5F5EE31D4ED03A16590396E2FC381A7923E81E3F582252EB19A7D61ECFBD72F0C3C16FC79", + "sk": "0FB4B45D59D6BA35576D1F75ECF682E5C901372E65678E959DD61F6652AE3F05E8F6C5312F27292980146AED5BD4CDCCCF105C59DC052E9A5604839CFBE13920A93E9DAD0A618E59915ED8D751E04CD99BC661E5EC654FB33C82AD84ECA806453B9145C9335E1A95D987D85954A8DB9BDA8280BA76402E489AFC07D90DF7567C36560273017280466156464484345270285178305711250242618355037451272805831334710075688556205675635811344085746515547468075008004432316642077378448408234860066117021246184447148263433760087826350221845428303755534425555717783464144721524485283480133537526651561143130746043842062162336620037333860708821510700458474260707108783552112553517880140325080003741440347208756274083066034241155117413308076178401187304037688762030146873725228304172627873352187338032728273353058572467830523107526832557771072150587632044015331378888724574122703235400051288424471463017425114740686283126323770788487586151073237435056574117185656340627503508855871406032154132457173517406070365623071357215822006317662446377112741371334240268625017522547202654825346782030134741711776706347452824240741863480127103262631840235133582166006304237018151562258370018144006703338563061314556680178581266374583457127838148005138183311168871835130403368588740370785287432187408630065074371213480444706406001571542517601870046628537585864013505382654286745611688562826411460181216012170130671033666664050228621047288450184107351840765645803278162817607642382073553002556568788426586683475530285773666151835665516303380616363227666858618761871385373345822418160086702271023726638411777186012145217307263853282062146678035810787254502315346844448377284120122775352576074324353408540721484446660113184477760757722801866776724528834717535547588852626733700730625755854828563408352458634703417047181611758852002888110270451664011082677250413015718850326577835815683880356606382152683807252371042722116282841206422056134168747282480661425448572771268256417857244404004266015646767320855751075500451662804257710454343255256810735615778555006233143718626653125262772466865157188155020522535172225206165001848253325225481217513861451643867711572822836715814443656054847322127382261373454384541346144146522301347070057540552088832373200502381445727625633138630426301227580101874474535184582276070136541128502418006160228766041816107568722737402742376833648820075260766071780446008477251682432221347088684304624471851307716637632473404150070457208081263267878825854610503616057514005155454106025132382716413517273075776773481460567806534468274677273732307402176400528254003850741282758634420707000148538120762573172316826678588360778452648825333124015705775726667545085706211188383356315880631315705723620874123576711420723155615800885213201562654580242880636273014718214588481101167063874558732715713124774232421012565602130506631727226611188335482535363622858870107022383508628013502852406025771446035382361661005267412153785415157213823542604756172745743260401151135822128877563768657521545878000334705788040273517532403014046181623871830487143472731360310027464080371511476477842670552846448716276586070267871218265501785588404888023122544554862135404377441518C06B6969446A99968141308658E13180DBDD324D01DF12295072B0689AD24B8D909F5B912FD4484F8715495095E72DA498D11E17C8FA5179C034D020D13333D45F044FE079EBB5CAAB5AE07027DFE0B451C647A7CEF0F2D7A516278D0146904E6BC5F9A019946F64F3A69C8739B47FBF768BDC2D10AE0DFB3EE486115C3D29D0390E9A6F0C66F32D20EC247C23A95324346E87E5064A651255FCC49092B4C7E7C1FF85C6BD646F40ED3A8C0BEC3EEEC4357DD01EA975523E50A5E1F1357B0BF59087F056A70AA4757348F5FAFFF7BC3388DA206D92ABC9A373472E188B55F03A2F5B2243A3C2FF86A3934AD1C63EE4D31EC38B980F22141FE77B29CEDB621B6E7689343BB29699FEBEF26346177BE01999A5A1A916987138E7B84EFD5A8EAB3B995C6E4202354B659A391EE0305DCC82347C50CAFE8C3D25D5BCB25648CC4CCAAAE062FFB75041874FD14302B3189C8EF04500EB3B9E6AB7E021647C79E1FA19BE67D1826D3B96F3E6D49C6EB5859F8EFB241B8E583005536A8235C5358A64E894847194A3EC4CB7BB6D445C66C08AD99D4BE4243FECBB6F340E175CC9373FB62ABF024CD913F03BEC9E8D28F7C8587E1C3A7620A83C3D4C31DDDAEEE9E1C965823A2F143F1F295B4A9665715EB2FC4A82AE0E16ADD7F58986E68A720783D14D0C48E92467B3DECED57A169CE42E9281B180F791C3A9A84D936BB4CBEA671510899F35A4AC0EE2F8547C2685913069FFD11CA7DDA5349D545BD5705BB5FB3E233F11A6A6B21DC638A4410FFB2420B123CF8503FF4FB53A19DD70974D90231B90914F92E52A38B13800C194427204D3AF3DF2436AD50F85DC6EED13BE12870FCB051023505363E848BAF4D01594BC35A9C35DD23A4986ECE378A425EFCE6CC49C65F5D829D4A7AC4AC54C3C4766928315F23400836DA42717ACCF7061CF91BBBE8C47127F5A8DBE151B37FABF6477718B11C3FF2CAE39246CF44520C92411A2D9B365570462F2545364A6CEE318330123FA3389E732BBD135E74C6CDDE764AD713A40F19EEB1315492378130247187C9444D7E5AB0E56BEDD59ECBA7D27AC32618E1DD23D1452664D465B968D86E53DD0D9B50ABCF572BC1A2B072C1FB6A6B2B4DFE7A8261E5D074897EE0ABD4E82C53624CBC3F94879323A4A7DEF36E80E579F824129D379515BD42F67F68D2A0D0D212D102B19D2D1BB4365C0F5DD6F6FA2F32010A9CA755599992C68FC61E4528A68A38F6ED6E70B45E1604221C27060F6336062F6F85A846E9586D8D9950C0517905C23BB99384092E333985D1E8F51F9A1AA6ED855B4288674D02A04E15E8485C086F952B746351755F31BAFD9BB9D0BA02D7D23E0915B8A1C5C2E8372FD6965EDFE496ED5A2859440B1851F2822F1C199C041E863A9D23AC3E03D510507BA8B4FB7ADB6F85D421B0ADE9B3B6606C9571E49EDE3ED93CC85A23E4EDA6D014B9F93E6B38FF145C8B10BCF6D019E8BDAD78B8FC0C70FDA4B21CE9652CAD055EE62C195CB2031847490633F9BB81D1F2B81E9FDE6F8101CC0E633676D5CC8B0431B917AE43248BB2749CF38561F409EA1D509BCEDC177601ACEBD99DDA198F4E4F215AB890CE8CD9AE75384D27EE7C3460DAEB72BD2BA90FDF270FC05C52DA014BF09F1C30DEF071E1750E5F9218F57DEBA0C90192D582B25A63B18F84E4E06C741AE8E125753F5FBF4E5CF08D64F6BC8A155B1BF4A6CF1A252A8F6167833D3895468B438EC98548A3AEDFCF0A3A31CF1E0D4E442B6FC59C86C10287631B134CDC1832D83AC335F04D10306C75C1A45AF63B48BF8EB03F89CA6E0DA78BE299F98891922A977E6EA182A5AE7B544D2666CD0F3CF2387FF3C5E4FAC94C220BF532394269304FC8A57FF17FDDE31B6D233A0EEAFA3614DFCAAC06BD6CBEF6EE74248DFE9C6B7A5A0F284A0CD4EDECAF3DE0B4589D2408F851C2036812C7D46B15F67E8C9713ADCDC1F1B2B82ED7DA48AEF24DF9B400BB32FE89AE95608D7164C377279F779CC1E8FA6D6DDF67A264D112CF7E0733FC450AA97B286EEDB959A57BB82AFA333D1F0CF965087815023B51B1E41D035E29AA99C90CAE7E16B0E7C03E52700CFE574A165460732537C413C701E69700BA941A9386FE8F71FCCEE6D3C10F832439B754B8BDFD49E3052C0AB1DFA70111A4558B86CB6054A4DCE74F81990850ACF6FC778DDF25D395527577D9D0CC34C72029AA9627D3649565F9013F6DD2E586824BA63C18D778F6E9D8AB85682DBDD723315AC9DCC02DE0E8789F64F1DB1A7F011CE71B028BD8DD3D1DB7C2496E67838649DF2CC4E4DDD1F5F3308DFE57DD1A5074C45F0346043BFA4D949AA2CAC83221D27ADA31EBD5A4F458A54D128BC7B20F410BB6C19F1652B84D05D5C173261D701D5EB7053769BA9C62362CFC52FFBBB536B1C21C497732C6894F8FECCF35C513A14EAD53C3A067585C1E021ECC3F023DF543F624DEFED6168C92C43B0858AF64DA72240C0BAED28C53C59340AE604DCE4E4E2B316FAA0B04A39800DEFB5DC91611754B00FC9D028BEB2732568EA481FEBBC3324E21D2C9A3F8990DD20E39806D90FD50F1D19D34CFB18ACEB5B7D8810B57F79753D372D0E7F4E14A6BFD4882A351083FF53DF1505A5973CF63CB015A38CC8F595AC862EC9FBCF3A3F7CAC508E6A48535AE97A56468B874AF26711CF989756757F8D3F31CB1A22E5A06B86AC8CA86D4ACDF5815F52B6E3F34CF728F1C735ECB35DBBF9B0FB14932D3B1816BBA6FB3DE65C1F537C0A36579EEB49F34A82881FCA14C2D6D8F2C7F9D9DAA879C8BC0CD3169489F44303A90434E8FAA1387885286B5F837769DCAD8F8B654C85C6FFFE02ACBB7C2881A7E3A3B2466E3F12EC79138A3FFB47C7758DC2F7A6AD0C76A7BE44604CC264F8CCD1027812AE9B47C94B70C27DF3F208231879B72947F61F98AED252698ABFF431C37170BCDB9D5894FC0F580F7260720C389CEC04D82F5CF60A6D3501554065DA790BEEF3F18A2F05625D0FA18FA51F0FE8D1C0583933FC814006EA9D3C8D94465E5EF36C65F9333B08C63CD0220B98313A465F5B25F406CE4906E74BC44D3F7A98211A0440A8BFF2ACC2F6FDD48DA95A02F110D809A0304A756BF23EEB96E2E72FDCB5DFCEBD2FBBB293736064C39C45209001FA2E4576ECBE80BB7B69B99BBB8DAB7BC45A1D39F8C52EEBDACBAA68650C20424B6D77FB03B39698DDE6B33860A485CD2DFA29EE384B7318E8DB0A8A1BE5BD032F75DAE98C5F3993DA601BC00FD13BDB70460635D4DAB8C59E1A1B74CD5564501214893C915081957EF886A68198AA776C29BE1EB747CAA6F68DA72543A5AB3107F46D6259F932F616F3ABF7414516D59418B14E95BCDB1D5703131CA20BDC8C429532212068437A90E8F992DEBF36CD1412EC24E9029D83C0DD6C6C049F9134F45968BB94C9F8004EED39378FA089241DC3084E253D42A0B9B91C5367E6BE1F1B35C37699ADC1DDF545A1DCAE0F0D002F21A32279DFC1DBE455CF17A7FFFD3EF781E727AC" +}, +{ + "seed": "334ADAD056F76D74941FD87E5263E449D97C06D748A82018D0C794154C20A870", + "pk": "05F90F8FD12BE86F4F09A59E0A0873933B75A7C33C76BA4CBCE5A2216610D5A228E9CFF23DC094B0D3690EE5B3DC55F243F2FEC1DB1046CEB35578AC48F680F9F9F8E20B4C96C67FEEBA4918C4D7AE555CB82338D92A2F2A97B722F09107FF5DDD88C86007FD3187E8EF195B678F1765644D5FAA99773F0188DAAFD9DA6BA2598D440F2639BF2C0A3729078CA78907C54E332EC2AA6D9E79698BC72D082787D7FF28929CCF6FAC633B2EFDC7DD0B82078DC8CBEE7709512583EB2BDD9177C4691D4AFAB887A739B396B308B7004BE2C7E9D83404D185DAC00168869F5882FF81C9C65FA6AB987C0B356C56F3E8ADC931E780F2255C39E2D40C0D741D4266B1460344737457D5DD07889B30B640BE49615EA8FF6CEFB05A17AB44DB8DEBB3E883E8682158F566561FD4FA8027A04A0153ACC065EEEBDFF09138F621025527079E7FFA9010FD95C8791CA36377B60E2F92383841E15C8A8BA07F2BD34F78D9D2E6825DC476687AA780B642B26A08C33CAB33860DDD1858DF04A94C2405F94EAC54A005AE53B7573CE87860FDF4A59F0E96FD87B451A2A897D8E9EFE4294949E8D663669D8474DD5FD5580A366CE9A282A5357DD7B96A66DF961484072EF21552CBAE892BEE96330FD3A2C55008D71D23A4F0579BCBEBA343C65C3D565B77474C178DF9A97B451A4EEB90041DB4B50BAA022037E1E60D98F4109B9FA51275A7662BABBD7C6F791F54EA56752E20284B56CBB853368A2F54C02778BDFC742E8FD566ECBC97596388F9F823CA2EED4CFCB83084749165B17425A8719F4822CFEB3040EB3C8611E1322799D5247FD27D403C74A80FA0A672FB1CBC62443A222DC7A1E783E5BCBFDEEE18A8D880C65B9E827493C318478A6573533C4C36A6387CE1CB01CA70985B39088AA76F4C13A774DA5B86599DCE9FE1A87D2A48AADE42DC5F1849AB42C8877B5936FF2E53D860B54918B02617FC78CBD03765EA6D9F554C8A6DE18D7AEDCED60BEC084BF93419B7B5FF489457CE976625236CB16C26686C3BBC5BBF2E1D37C69D70976A7A3B332DEA756B3B84FEF984BCE70637FC376A8F4A02EC317D4E67A3F259141AFC2B061D48015294497C276D87459894A80B2C7B9C46D988E6550567EC4F3035E23E1921818D2A4D060552AB0088A27C9A022DB688BE947C231A99F22D6D0B225FFE5CEE23A5E89789F5AE58F4C50603B37A0624A96270B849E867366D8D82E02445773DF5648A15C857C6B04AEB21AB4A04A0552E9F30CC253B2FE7CE0071D3335976BB702B11716420B43AB11639589E5D5A3E7477B95E598208AA46DD30E1606F30DA0C616DE7A3CC31653545894FA958E8DDC026EA1A8A8B807EA45297A04AD11EC7FB3EF4DA1377BC6C36CD3E0BA08FC90B4B80C541BA6A5B7D2D91E299D4AA9D854EA59F45E0D76F8090127E8E834F3A652AF71F18935A58DBDD18E9384EAB5E2E10D78CD57BD4EBCDD45BD2125F2E0896BCE153B5F84437E076145B61C050F3A45C1C311FD8D880F38D65E89C4302FB3DC58C6DC1F58B0C52B73C00A421261AB5B9EB317C79E2F885ED5734F638C8EED36081404A048C26219B04E526FBC1D1A5058685AF88028247D6ACB43FEE3F546CE2BBE4BA456E6868CACC2557C07ACA318E1C8F70AF0C9F55AED0515905E775F5921B3AC8EEB5137182F487ACA7DFEE88E77954A94DE3AD78C518B438915FCED9160A4CACE1D7A005FD60BD34E1B328321C22F58E70741117ABC5F819722742187C9D3DD19BC3B7726DC3E81DA040CEEE823157A14470E9C0A04DFEA594A05DFBD1E256BB1524FCB591786379FCECC7545A875483D4B2E58383DA1807F5222CEE95E21BC52316A886590F55BECB6F2D5F8184330C82BB50427BD6DEC0C5E164ABDCA44F77E80231FABFE8BF02012FD377536BABF6C7638FAD14870C97F1AB0D4273DC9C4BA426169B659278A5BAC8B63E4318A0E85C4B22403F13C9E74B03633FFADD939FBA9EA3D746B37E4BCA503370DC6ECB7EAB6537E16EC64DAA24C1ACDD2F98531C594CE745C70CF3ACAFEFFA1D36CC062D4FAAA76AFE291B8FF281FFD546F500786DA4E05E7ADE2D37CD519BD78819F27ED9B9A950ED2D0129253DA2B7F3F660281C9B0183E5F753FE96D123DBC27FF6F56FA5465B8BC9F48CE4AA4963D17FCFB50FE546164F901B04ABD909B78108ED8C5DDC8BCAEAE0669B740E0F7DCC833FDD91A789603FA9A2EE551A387F944C3A032F231EF0E7CA775905CC5ABC8755886BA211E698211ECD3B04B959BDBF431A454A08558D4CBFF01D177901671831E2A0E9838E7D9D0CDF1C6C8827E97CD341DEDCC53097C9BFBCF0B4347E398E1132C5CD5A505D45F6F5D944073716672A2B0BB6C41C8AD65F843B1738FADC6018B4C8D6D5B2E2E331B8FC41E98A91A0F43DA608F49AC0126561625D21147BB3D5A9120BA264A703D5E37494FD4AB883DCA023A73DF9AFFB4A3930B5ACA133CE57920207D3D1642365EE718C430B51AD7D4FCAA294B1F42D8BDD7F08C5B8FEF631EE7F18904EB84F867B7407F93DA884128EA3E4E1E9144ED351F40FB460FD511AAEF20ECBF20398C701717409289AB22C2518BD464D28D76D9420AF9C9E91734E36F355544A80E50BE0D3A36556620D9D217946CEE219C990807EC0D1F2AC904CF661F6906D58D8A8F500C3D54F1966A8557F8224415F17279FF93489AAC8E8C09BABE490C6F34688EF162133B19B55FABA9E3AE1E2573E51966CA827E3DAD50FF9", + "sk": "05F90F8FD12BE86F4F09A59E0A0873933B75A7C33C76BA4CBCE5A2216610D5A2B3B647FE6B2D597C0BB64BF8EC612AFE415BF8C6EE9C1C89BCC07825BB4E0635E279D6F8DC3E90FDE70867F7176F78C7375112D6738CCFA4081C0A267427E6456A9CC1B62D301B2E61490266CFDE8BFA6105E0A538AB1C1D0AB74430B33713623581386483755445243753473438078511606051368073160115738012354521300214633143005060458451614181317625600850828658142078641844516326445870256686653680383537701272643265207087826247876408370160122140768874166087151412676620180320686408856302667266662275523315434588681761074568070028312208584121154004344663581510807865182675883813108000025672850572778605381322036260037871137460676071517771314675682566577436544573460506504832281442435167233455724534277207215216360738167150836460874031736450610842824275257455405400364275587451282130682375546268016543663485208367258707108220164027637784307552716318515481724518532741014070576523654860028123444648726543434463586358076328861862385412143118625642628126672617763635717788356608737358238865854478487075717624743613147755325577155202642662650113374865061032648163018768724404227837151260534245414730837040272670625518524816844173752604713612421427581014835327884216357004103827372624624825607613685321838718783121783201546220877332618523484033418836504550354845557501255723257746365364533724770053004852604007145007653484371135700033413050162143608712741065021721558584332535787122020613285457067071122166270825871245825500252511451404363724313586561623662725341448326850605637645520652710734061103603553721504585707324281583008610265170617622430557127532416631412258328838374307302264678282601782132034871337644843401462742842107215876302171452753735780621218157840378626106652400582488562616865716354530113688531563273150642540215680704544160562010462168227847102043537372863606227863485764564280612335786655251320053243774704426146103767351675004061227771882487418563217101228257228474177206416048740843757752314642706176054186108442840481072688807888245121437337668018848605137653166518641703180318156612602033260572357615555665686231008127660607683820542312302436523202472348222103574847503136060448373050426708734310818546100012558051246608155643310633872255780650310786552541215201745381263325165137452788463576343674204721826037356042184745266584825467165112106006355167510788781105623465658773756883868012110284321513014454716525175616611768137427681534886023486205351442728858581666752868236430175106745042638321062083108321702340453041130612457481178582752050626158025384055005352376672458346427221748425807137606753806442562318172647335860725474830371583802351251766113664310376562367167407343086650862744558342510760512033105786441765808007204600605264376872847174351175438301566013163416683413510128707207468874177221405114514851318225231514632664730885425005816216567873025118726014288180357621523872378502177300555886517581515484033478831137167558052224442144782845268072021678508733840333135173515826820635274207417088856814547057513727206644577603710446785322314856685424538803253760515563520538716116405141054573465220348762101770782046356737660564646108A71710BB56C4A58168EDB0C30F9ABA6528629B1651EC7F3D4FE010447640C0C2463FC2632093713C10EF12918F6716BEC6AC202B2DD43B2637A4BB8EECF09091A92FC1B9F1081128E4DA97706698A51AEC985B77FA207BBE267EA379FCC692A53EFBD31773E886C3637A229EDE8DA0CDD2AE15AE92D780700C84AB8B6EC9C0B337C52BCE50FA59D420FB4246E1E62264C0EAE5D22AAEC278FE76F27EE4F43165E6F28678B613BB2B482E36470569AAEDF12B0F6A1E8D63761668120810A035FD8AF1BEC04BCECE6CDB44A97176F4E1F5A8AFBEA4F4C08B6C42CDC167F933777F012D11BBDC6A6BF83E1C7CAECE6069181B7CD884F482FD02FEA80CC499ECCAA88B46847020E6154B30DD124FCB9ACDCFC1B458B21F2DFBBB4192ACE07E445DBC9024401ECAAA68BBC1FBB615BE93CFBD2CC1C395FDC0F31E7054324F37E00506DFBEAFCADA9EEF08E082F130396A22F0A1B82854B097FA713126BA0309BBDEC3BEEE33042044D9FE6A20D72948E54421739E3B5DF5F07DCDD343EB4947873E77E1D092357781F35E8771714A168897FE3C458D16621462F3D2130D661E83CA346BDE9B68F238B264B5EDBE0EDFCE0FE7AC1F6D51DAFAE7C15FDCE3CF6ABFF710CE4CF52D7340C6C6C5FCBFE3ADEB72987B53CAF3C8462DF45649028E57BD96FD918156A42DF582F2D404004E4B4C589C2214937200B4E8AFEE6FB4A00EB88E4827D39ABB8741FA6B2A65632F76BF3F242FD2455FB6FF3CD06D09B4548BBC0FDF4E3399D5926C62C2C962C708FA6A58A546A1C27D5A4F067F7CD0D6BBD4032493A68C6CFC5D050D779E9F389F8DB5A522FB052D2967DCFC2F99A911AB8F7BABF73944696B334A3F3DFEB250BBF6E79E95ADDA9F8A1678712D752F4A0F2028C6871BEF429D9C6784C7739FA8CFEC41ACDB06496D8F7D013693DCB1000E8B8269A3AD0685D7E611F9D0E268D5C0BEE1DB5E0C103AF2B416C6207E498A4B15A3F6FEF22E1691BA30E296790414C4CD257501DD5AC4236D338E092B32170120ECE4A9699FAB32BA0447B32DD4957684793A77B53B7088545BCE9D2351391C6F68D4F5B7AFE553ABE675C716B66B3733D20C87EB5E334829B0BA1EFAAA6B909F9FC2D24517B38FCA6F0EA0093583C0925B0627C5536CCB9891C801C2B5CBA522A8F8F036D45B4022DF9763186D34D2D137BD4D1D865BB5C49D7F5A73B2DAAC7299723A36C723367083E76D2AFB0B74CF90EB9DBEE3B39D756A69299AE2042F37B087BCEED9CE935FFC25344E5D9EB9337A9EF17637A200567FE6C3E6BAA5A69E8E340726D60AE730CF963CDFD0AD05745A145E9FE92D80546D7AB67602A09B777581A1C8C7DE45A6ABD1DF2AE9F5489059C40EF605661C75B5D526BA9A928B41FFC93C36ACBAFEF9EE13DE5660790E44BE35D8C797EB9831724C86A069BC4153E44CEEA0746B04B9821B24CDA4A98FC7A42C8BA35E7A191B937D4752619CEDCB00D21CFB9AC21F2C933669AB073CF8F3B51B6D5791BC979C7B7BEC9D49CFE66CECC937C5045B21CB6FC234C29FA963328B174C8537D204D79CCF2250CBAA5AF3A8BB1014105178A8B98A4EF49E09BF837452D6D2AEABF589674C893BEE8BBD01EC13417CCC95B7A07C6139B5EA1F069EB7FCA0BF92F3744DBF1E24D469FA24767D2C0E7028CCD6AEE3807A2D3459AE84E9E5516F50CA3C42669F70A61CA3427919E3D3C4F865176FC08C68FDD7A48EFAAF92828C29AF85F050B45F03511BC0BBAF555627A12C53550BBCA665884239D3B68F419214FCE906A47B036F3C5DDB300B1E58A545B71C74733AF367D6DE5519FD56775B84DBC99ABBF3F135FDE98052CAB7B42825C3D76B5D3E0F6BB0C04FF8CF2FB3888F3350C4BA6027254E124D1E9871DE84AC5289A465688C4BD68A2D187D461BBC4535F824CCBA09DBA5B7FE5EBF9F7F97A85E31D5898D13D770DCFD92FA3B7872EC42853760416AAEF34C0CA96763D8B38694827248B062948A42821B841E623089709B55A9A26E7C985CE42B5F1DB99136D057069D582E2AF5AD2A18827C6EE2B5342D2A1DAEAF1FB1E0220B95E850CC04F5806FFC11B304F842683CA1B65A02E76FD0A2320819B27E43E50D7F75F4CC3988C087FCF409DCC6BD92DC9B8C72A67890FDF4919A2A0E4BBF932C7806D25B5E728DE08B26AF413F0D74BC7CAC88FDA1B54B6C4FB584FDA5D7D6A9E2F24C4548BF3F7A3F173845AAD914A3A78BAEA5877841329694A3402600C5183A1E773010F7351FB0E57062D715DAFF483EF5E85965ABD16973DFFA3558ED9B50ADF802C495A223A3A19B82C1CC1AF654C2690E46FB629FB5E13A8DBA83A176338A298057EB7FD674B43446D0BC50070A420AB426A1DDA272148CC2D1253AA827298D6D402CFB1D89652E3993E42D52DDA92F7A171EAE4B652CB65D0F6D55B54D7CC5E2108E6D5C85DAC4D5FD8E05E3CA6A060AA0AF6BBE310F61CD874C16AF5992609909543AED87019D72D07781CC8A42DA9F0D680035A7703309E191A044031480D19B8A6A6CCCFF7AE2AD1804651FAE4A2971C28D03863F5960F31DFE57831653F09A7BBA185FD036DFE22C594D63342588422F1836F965150750C94F27B77085E49DC02E750275F6EE30EDA4A0CC30725884F8B563B9F7DC7F6B3C27F46298F8AED120F634755D1CE1CD2E2E5E3EBAE4BB5BC3527C6DD97DEED0FFB644053EDE8454BD55C3307A12DA90AC6940361C310C081F13BEDCF3EDDE165162E4E20B6E33201E3EB4E7D9307D5AE918F0015158A500E4E3EF914999EF073E34CAE6A1C483B84372E29E600ECD1CB69115119BCED399ACFBD65DC3049BE0377CB27A1670A76B8C162F7167B8ED59EFAE205BDB393374B8AA7D23010D475DA30331F5D63AC67D2E1AF8161CFEA4260ADAF702464837CEA071AED36A217A029F59E7F38BA9E1C1DDCEF91DC436F5F685AA0C2A1BF3F30EAB6B6E2F7D2E4E43ED72FB8782AB5B7DD91657613081D04959FD045AF83330EE67DE3D388B7B20787A5768D1BDD982F5B7615986172387CBB65DC3D6EBB1F08F9E05EA69415383F51BDB25A21ED4F8DABCF3BA769630FE0A421DD644B1971F56709BA1BEC4F69BDF336977122129EA64310792F7A48BBB12CDDAE504A179E3094964A8835B360ECAEEB01A834C383A1E726290BB2031242952FEB5A4C3A02C9106A66905DD6BC931DC245DCC48995BC1BE9F0264148D13A92C16FADEA763BB62DC71454FDF1170DBD696C34C3AED4D20DA0983C7ACFBEC2A87E0C45C2A1CD2445564B400105CCF9964EAA5B64CEE57412B70C0EEE991DC9E868F1BE1C254DD006E814ED5412B5BC7EB5F60D3881A4D36D5DEE5216DB93F2258F42F96E21B58B547FF72F93DD3D5228C2C17771ED77FABCBBAC14D2775C098A1CD66028A0E448BD33DF3189B10D9D7520B0E3ACA333B5F8551A3554CF140D2EEFD6E30CC1E900B5A2906D11CB8CCB35FBCEB3776573E86B9DCCC6B8DAC94959BF1969804CBD7990F664B517995093886D4606BB0" +}, +{ + "seed": "06C016CB8566F5B81F8457F56175AE77DD05C35EB37B687EAE89147DD7ED008D", + "pk": "CD136BA844EF8BD51AEE2DB3103524DBA4AA971E5521D273DBFD2D69F0EF2CC3AF64CA232E59C2E1F4EC56A8C2AA886F2D5266B72B1717E9F83EB353089EBD02636BE7E2629D9128819E0E3B47C28F05AB0F06805BCCA20FE0BF1CA4DD2DABA5B9012D0D828A9F752074C5C40BA640237BF00E137DAB33468B4073B7DFDB9BB3F512E092916F137C77FA23152B1C1C6C0E7204DB7B0D0263401BE8474A54F00B6E8BBC5E596ADDD254FAA848224FA50551433BC786D063368ACD6D412D94B34C5E6067651F0356A30CAECAC274FF0C1A87117F589C41E6C7D62822F0DF036DA4A646406CD44780C0CE6A6C960D7523241861A9AFB5434F3C6A36F8C317FA267D0F1A25C1E4E5B62318D19C7DF5F2AF5A269205B638119D3479C692C611DF51D2D4CA3E68306FA2C8564532AEAB82F5AD8EBB33668028AB8CD97E8859EFAC229199B507995B1F96B3AC5683D00F3B44729A9710084B1069663552F64BCBC1EFF043F53FB1A689C6EC82FF5A0FE1C91978C52140B048B4A656FD535143D9E970172B28AD4B2D41E28EF62618D7C6E7B9504DE18F3F845A3FF291EFFC26564B2FA62E8D73788004E47899925B63712F211E707048BA59A9FBDB2079BA8C0E35CCDCE7009BB57E425C734A9A2430B32647603293D6E769E6BEB0448AF3AD30B6309AFAC2AC80E1BB5285B233A87BEEE427A02D983AA02D6261E92C7771DD297CE29C1597481E4D8B2BEFE04915DCF2A2F2391424BA449BC7F741B2AA0E8653F92B8A03310EE8D79E060212DFBDDE4D17BAD0F78C84F21DDE401B94318748994771D60C0C572C51FCCF8BC6F45F5D5556A827E8AE043127D7F2C948B45CCB5D9BE71AA6B02AF82DC2702BCBA3C8B970B0C6BDE654CEBC291EED77E1691852555E3C01E8F6F28537F1F20A9A175FDF01C333806011955B4DAE11D9EC8DFA9277C77F03172754EED071BE138D240785580F653CA8A21CE95C10152D9F82C1F50FDE555496EF081CA858BF719AB9BD245847EC23B6CD76175F94D26A72BFD150EF152D7D5C975EADC946472F2DD7A8EA557F9A197CD420928593F1A971A95C99FAF383B2786C3453892573F936FD4E58344E3577B062DDE2F58413787759A861AF09E94AD4EA06B37F818893093C76290FF0C96183412F0ABD94217D830BC21827D0F6B18747A8A31812364A8FB9988CD10CAC3BBB2A649C4D5614ABC022143716BA5351ACD138B2A06957F5CE978FEB935933119E2FB0A8965D0EC3C14ADBC82D37904E4AFEEC034CEE4031A3BA4EB3B1FD6033B45B4C35A5D309AC256DD9DDA40963C69BE485653EA7EDEBB8CFA20B422AA14DF1D5D91194490D8905740C8165F911D6A311C5CCD3B6E07CF46F0A9C57DBF4DC4A5382AD40460CEAC5F6EA9CE7C79F8B7064239123A5563D2C33C1C122F5B221CCDACF9D577576213267D6AF351F601B7D4C22B7956F363A42910D90A99CC77D4C858918007FE70865A6256C0A2C82821883627F2FE31798EB532D24317AF4818BDE315B82AE5ACD3E9B468F2AFB40EABEE4E05891D4A09709A409B0DB9A5A80F30906D99E9B67AECCFC8862B3E499B7CF7B77A2E79734B93724FDB0C35983DDDEF4B7476BA43EF8CCDD6E1E09B538E777E71BCF9ECFB6D26ED0846D58D2552BF2525242839D8DB26F82D9C6404695E1AAAD195D3D0F4E6F9795CCA693554DA5EFA82B3C773A04A526D4086CD1AEBBE609D55DD4A0CD49C2D5DBE590EB66B9B061639C524F01CCEAFB110361AE8C9D819220337F38B6512C68DA333CC2325EBD47C0BBACC9BA651D7F60B6E7AF1B8A04D3F64F4FA011EC5A15493A08F823AB7878684D9D6C1B23CCFD136EEE2203F6E7585F97E36E4DBBE652B4184BF6E761475C0AFFFA4A92E0FB139BD8D736AEBC10448FCD535598188B2DDB4D4DBF6D2662F769A9F55412B50D5ABE76339FE3E162FDCF3501AD9182C250AB14AB6ED95666D757BAE8486FC0633193CE3D3A3EC9BC8F29259BA6E8AC0F699037A172CBD5034DF788C3B9114C9A605A1F19D63ABE13DB3F4255BD1C7205E9A352825FF340D794C70FE5A641BDB47573C5C884A575D768F6AC5049083387B348C77BA6D11F506CED5FB296D23899DC35E3C13EB984B1B8874C8A5C333720162E4EEC1A43C77535A885C43DB98BAF15F0F07BF2C74858E3BED6EBEB210EEAFBCB2D771F8815B567DB720ECB17A1C675C1B014C365197D4ED8AD420D10F103D5069C83D0D2E39852AC777E0EDF6681EF4A048B3AD6F4B6134B7150E8B29D1B1B0FB69112E99185E513A7A05E470A5384956E6196B2D8B1018F7C2F876ACDC83763C390DC4A057073EBB972B89FFEF171459652B00DB20F0058FD0CCB8161FB0EDBC881B84ADBA66EC0FC5826A4128F45BB1ED48B5F6D7CC8D8418C43B444F60E7C9D8C2C1F04A3D86516AFFA6E418A4660ACB13390B44E7B17B7C63DAF2460F4C00E9EFCC531F2C1FD31E63336BCE51B89BD1E6B867ABEA8EDDB837D23B3B16FCCA05CDD2924E2A35802F55BD8AFBC8B96C50E55FAC219FBA35DD618F31C81ACFEDA2EEC25350898046106815713BAB9210D2A05A1B478170AFE4B3778E051375D021831371B16402F9BF9E137D55E4FEA29AA18C3AF0760F6C9C647D472EEA663B41FDF52F3832C8CE454E451B6E4DA179DD5DE087ADCE8DE05F2A5D5961ECCD6E362F76329A27AE77210D2330EC2AF69E5898805C8402CC41F2EDD9A2DF411FB8FC7EF0C7B590A1D751223C6D770B8E180635C3A7EE8", + "sk": "CD136BA844EF8BD51AEE2DB3103524DBA4AA971E5521D273DBFD2D69F0EF2CC396F5787D5293F0AA21C1EF4982D6D92B03578807EE3B173529E67CDBC4592C01FE4C422355C1791E28132FFE128EE7400A82DDE9DC6C4A9A4446552457FC67014618934EC838799C91EC12872C9A7B41B56AE1B4F2D84E0A1C45E63613CF23B8143058026560631877225541240870755028612211601113257620730333171113133326014734054530822257254625481781338656606531637062386428216843125583177381435215743200728750178828264283858572338340174666155423803410245053881552033512106268217163576701115100151420758458254007203647278565678136022872018662578473315183258324430858168453864072542224242317055776525374818573571728183430228822052531150150563757546718458310706857665406856725636865568642212311532331480501803576035710033308324482566338724804414110081242517212343043345322274804530744840017770682328836674404578040172026160252354482574075878623707433412042010420315324686631430437621117246135145667012805637822015676733372011026256612787756404678851224687705061484330880505326284055581054124668286658020382004078761776361161527740048635207170416215413243527764483287008340567823406070005843544321560087377528537112747351413323761711545608265808303065815242428578631040654613162778428574137416806766647656885762514121044168162303486044752838523570078420858537671500835356333734424688301521706686448255386087425664222682810214243348461332478264228721251287155070578654184140476811887216103058536107683826460515064853244078875520430770825153374152041800752886860880705277852311445620558643661375387135831547560175412405304476660057527456133616354524282235243658540065376850627062681617338104541451788220635858838672766573864142370366455786746353087604586187606056712725063187712712448173850448611574436042456606878057101783345634527487132824126777640311332086444211084406665723663416404615362244124732217810466715618067505057624817681836341825188410360207772465666127650130242187521306645231253000028638486005737424660746138014572216528038511631376771854823406270830132667674806184712737536564845562848003181411682763004664515632264310472672641657307765353303431853146262328068560152456358001505514157483485470687546573587047517328521130710682881183360163073041784613833175275612544847536060656800117884142016825672787262425284372054865151236484576661230323038363486585601502573856284167732206132578258425346636431584100337878378274840833177664013564252244411184708104348334304276470112213147701405086214104113215886548778307185000683785205742088186133061432162674560501614305005453476872274532448663370472187828212621133266066680423603181222832354734806782474407505641561545776848377668885033003456617755578432240766407055388340333658406402462202510811201771475150833626185035600871018847510308042575856566110553231327801543061080331388054232227503550601672838252561463072541831582337012688050512015154818313653303778611543867346215811512217107581100031233816616052755553316276881007300046414722210544405685155425152663633145137786125875381612221375311321043307001662685838057425460185646272147556360106708043553528546214161058211015442016678886740618868527873410028761B9B238BADA333C6E82897B4A54AB928D97C4A87932DAEB797FA5D677E173B5BDDB92434B1676FF7B965AB309CA58ACCBF0A6CFAA4B0C0C917677C9414FA1E9230BE5F75CF5C63129C70C2046214904DA3C43B4DFDEC7562261C2856D1F86724673F89D790BB11B55623F5426106D2D5625CEA933459A75DC1A8DAA87D6000330112EEB17537734ADB71B349190A2A70FACB2F42CEDA5681691B6CA9DBA1B48A4AA72C1C7235BECF0170B8CBEA2833B25C064F320D8912FD8B5B30E4ADF2CB9AB32BD6D2A63DF5118B12C37460FF7E8F9D9830C51E36C7E725B1A8E1F52A94985BF1E5BE49DF468D46249F5C9B664A1BE2CA6444F8873A76813078E4DB1F05DFF8A8A66759F94FC117EA2B6415ADE0982B73C9BB8EC1116DAB7670F46518CBB729CC8EDFDF8DDE4E7DCC960F15E4B417F655A5FE1B69A1AF0DAE73EFF122A5E52907932CBA3930322622B00E35766E0D5C55F1B7995F5729C857EB80F2F109C3393F7251D45AF89D038A0F303A4C273A4FC38CAD50D3BADF909C4B8748C760D6688FCBDDEA1A1836FC133EE714874628E4611959291DCD686FB40693D398214B2C5CE4A0C88A2D9E6C1521F4FE425ADC889B8E237E90DB6D4DE8899CFB85EF1B61A31EE0C68F6D59E1CBC52EA02B4FB66C05FAE0B4E78A492B883A15806EC911F58ED3FE072E779DF0251771FCA6354B4972B21F5BEA540875EE1A72D2D8A3A9A1707D6B0F562CE6D045C9D925F88A709BE8C1933AE1EC9603F497A5013B4BA550C024C1DB116783FF1053A6BECA7393E4313F407316571C113004572F4A39346F2A67279218DFBF61BC7C7BD1052A3E38014F926496E5CC895C6412CBAA59771A01B5480027FE3431C6A09BD2DB91F62C35B19F0A92451167516E041F49DB672D99D71E1EC63B59A0BD8414EAFF6C351C4F7FC9B73DFB508C1A3C198F9DBE0155F57E89CA8546845BFD8D4BA6953BD5AC46C7C652911583D2ACD204B24B2A9850D6944A5B89A4FECAEF23387BB845E5ED9630F72E3A54B2DB5E6FB991AA77A4C2714AD041F6B88E5E013651488ACB4F74E327FCC55CA05491E8919701D597D1510C5B47460B9163B736713DF60DB65EFEF3E022C326ABA7D3A48ABF958F630F15EC8ED234BC829D7BB4F1E7F4FF512627713205B6451804E3167FE01B99BA0BADFB77C203046C750216852A4E7EAF44F97E24A5DC16245E738B5BC153B39F040488EDB47609FA698AE5F8F86BAA6B051BE56063C9EC478ACB41FB247A7349B9E8B1AA1B1E8F3351D2849AB1080E75BEB8C68E4CDA3F482C6F8FAB0AB67A916DFD2A98F5F22473D55FE31508A73A14A1035161714FB6D813EF94E25D1AC9F8FBFA3641C45F5AA2083AF05E31A458F8ADBA3A23E9C260D9EB3DD99FF4E6A5AC63A529D0F09BF70C9FC9E4092510655AAC4F6C07BDDB7B6BB4113E66F843C0826BCEADE05C0F06CF3E93959B9F0256E3EC12CD2B5D45527F1A99C2D51AEB9FF19E9B0C4B33EBC7F689127C5074A39D5CF78E7F5433279DC235749EB8A1242CF4534643137796DEE5B74647087282241FD91F01613606517F852ACB9B6E7FFD2B64DB930F7459A47A4FB74EF9280768E7C427129BC6C488459C023B06CCC997FCAB04BFC0A012BBA03FCF13A38C225366B948C8874E5E958AC64E68DF8EF055D071AE59ADF52ED94E2F83EEB207D9630FE28FEE8E78B41B1B46A1673E6EEE92FFD61C9ABF92C5507B183DCC30A239D3998D7BC2ED70E6A2024D18D26191F47EBFFD7B5535A871A9071481725EDA4312C59207B90188146F6F22D0C25DED8F0FBEEC69C2F7438891451C366F1014F4410EA91491B77569EEBB61C9BB500150F42C3586B37C39836D7CAA54CE6CADD9880EDEF79EAAB352131AB1A9A9E61732F74B20B5B438411EC812EBCF717A07CBE0FCC2C5D70BB46A741E0DD7E2B97297310AD0281CFD683565B40D7DB04C47D34ECEF6FF88965B4D858564533E3A6E6744E84BA84B250880FEB8E88E748ADB8B545AA0255FFC70574CE9ACACE6FA948D4307EEA22F4B21711DA0276A64365F00F23A15827D16DD172B33CD1500D59F6A093E787FB38ED23E3AD1F2CC5D2FA18043FBDEE30108D1E9D2BCF53488BCBE02E7979DB238B079E88D90175E922127A7C6CD6B72B87AF752522CE2C0D6E766416CFB97930AAAD9FCE7F6BE37B3BBD1E6D4F6759265974B5AB9F6BCC1BAFE0F3D9810067E2F1ABBDDF421A21A22CDA9AC3123BC479FF33DABFDD5C6F49E139FB05B0B7A5DD024B2725996FB0AF19DB7FB1462B7C551CC2A7DEBE3CFEB95170381A407849D0E0CC9E11089EC05E2E898EB2456044BEF899F24629B311363521208B1EBA36F8A619DE49FC20AC474FACB7AB2318491F72E26C7FB9E0C387DA35DD7869D82134A9C61919C16790ED81F07FDE26C56E5ADC9E0803B260CD0B85391293DEBDA809F61B781C79C252E03EA43026521BC435E47842D24B711CB5F75C6E12E2B10BE53E09EBDB5759291F4887350FF986A16862DEBD9F262C8FBE71E2F106781F8DC94BD7E3F89DE77893B3853146F1FC5265870F713557CE2E514B92AB652BAE9E758F4ADCB8399EF0BACD87231BE1A84FFD58F4B6CCA555EFCE7F70C6E18D1CE8380EEC6DC8D34A41383B97A7B2694E8FBB09AE1EA9976CB1423418A9C13603AA67D167C7DE85481CE58EF553D9C3781A795B6022C1C00B119256547091F4B5A334016DDEA662540AB95882C608BF370513E1D041463AFBA71AA2086EA700061474FDEB1229A50E89BC1294CAA0F892E93C2257925AF7F18F9D28EA8D8419AD1121A6D8097E048C82FBD885EC3EB14E90DC59FB365C30C12C427CC9205E56CC1FE60CB6758E351440F4EDEEFCC35BDF6BCEDF4A4E2C1C68A70ED0FFEAF5A03D4DB22DEDCEE8DA1F7B6B37046EC3279DC9573E128F51BFE42285D8E64CE98836D6C80F470C64048CBDE71C10DA83556803DA4671323739FC4BA80278F2959D1C43E59105C3A398B8DC626FD58377373CEBB033FE1211F05583EE5F4AE3283780C682056BC77C7855AC186C1703B8F5CA6BD50735C1C5369EC4E180BD5430A5E33108E1547914D3C0B7EDB6AD734EB3022355F9327A23BFD535124AEDD1CC9A36BA514E91785B36695795462F5C4BA58660313B1023B075812239A12320787C5C6721304651BA9F269F1E5656A875C8EEA9E782EB912D52EB43F622A6D770F3201CDF2A5C20CE6A1D1945C5A93CC6C65A2A7627E42622B7954625D0CF8EC441C16B04DF7602F52CAD75BEE96403BBBAEA1B102A60D4AA3FCF4D5F8208A30E821EA585A130EA928E74BFCDC435BDE8AE646841BFA7A535FEA5FE89510B96B33C7A3002C442E311A45A1147F705E1E73962DA730CACF5C94A10286EFBD3A7CAB12AC574ACEBB4DF64253F387FBE4036F9330DC3670AF3D5C5E5D39E9D527859CA6CB8CC47833BAC8A07F80CAF9DB40D927CF6B2F88D4F8FE74E0DC4200854045B4E7BEAA849D23A7FAC82CC7DE0FDDABF825B720777A4FC2B4FD7BD65549F156A8AE" +}, +{ + "seed": "AF5A2ECF442AF8C0371F89C499ABC337021992F221C1D3A66B551DEC917F1B1A", + "pk": "CD40501C8F6E1240FFF9B675CBF9F802F93CA9016083A7702216C49F56FA13802B4AAFE16A2BC444D2F77A328CF9839DA78E4138842050AF64AD2D071B941A5C525C66A5CB33C4061626386EB5BD8586A4A7D3598BCFA9367D58BF650006F07754F6820D7B43B312E6A4B7A3C19E870D34D80372F54BC43EB93BF58AB87ADE1ADDB21F3DBB7CE2C3A6A39A89D3E1EA741A6C74D8ACE6BF37E97578DA064195161D174602AE8EAB65C8DE1D33896F3FA4A3181A5D6E75B5B718D3D8E36F39C54361FDE078E2286759A322BA97AFD217B72517B3F1397CE10960726700173783865AC596B47B6B8BBDB8D6B64D4CF8CB7ACD5C58DA9AD194D15E849D96CC51268C288EAA6133B8567607215778012FE046BAFCD663D2FDB47101C02326A475C2DC8DFBAB87790A11CE0B672F41E102980E7039E07B52267DC7B7F46AA07CDB42B65BF9E7580C16C05E50AD305CB0E4D68EBD4B92980EBC978E67CC115422391489E1C067BDF627F78F512C77DA348BF38BCFB89CA9053317D3C7B3CD1FBFC2793A367D367EF412454863B00C6782EB813A59B0E46F4D653F2711E225807D59D5398A12D57653193B951B25AED9811A983734C5521F068C1DBE1E008088A81C88A7FDE81D8A44A219C987CECF76E1A1849443E17F07C2B56A6CDC36FF4D9F30F4AEA525853532710E21EC5DC16C24D1276C11B36C328A5D4AF570D6C9DC7820258A71E1D5EE4B0548B49AEC9C21CCB5C2FADC7C9BAD23D8DC8B746FFB82CD78E327BEA707968C82FFF2DB878AC9810015A9D88493DD6FEE55A5FB18A35B595D7A4833EDC7114ED47DD87D5CD236533B60D732CF6A24D27ED0B68DC9136B276CEB4FC918A87C1B410CEF13D062763C54735C267694D07E6BA17D66F88CA7A3B082492BA8F4AFFAA66945F7B5AB62BC5777C443DB0E7F84F2E6756087A5634EA81DB361A78409386F569F898FD257C9307C9FCABC5BA0E391A012DA3E65101492A7FA9D5CADA36F0D613C1CA3C1BB57E9F6165C06934EC1859D13A1C3888178087106C6F4F1FC46A10FD4A9F1E5D83165C97B7D1D71A9E09B1D8101058739499342FA5291112409B93953B989FA7E68B733AACF0927EFD4302572052CF508D3FD9AA1EFFE53B4D57B22CA8E9ED9F0C06102F47BA853AD5E4E01501B6E77E31F2010F7813F339F01BD0F43C3F300B15D36AD32CFD7AFE8C786185AC8773E0F30A8CEA310D24B7CD068872FAB88120A24448637182F477AE10473BD3653FE453002CBAE148AF0C6C4DD1034AD15843AD2A83795090B1C738DF100BA32199D0CC01D3FF7844C524973B652156257BEDC07A533C0F1083827B24C3D77DF19F07249C8523F7DD350E75EF3509B99B77ADFF5CDDBBA4FDFF0BC89A3F2AD2C2EE8137B0EF847B4B879EDD39E299CC205E5E79995D80DC8D67EFB93AE3D6318C2FF67F8C31EB39818ABD6B3FA0F2C6D6646E9795D5727458EA5918FFA9A62E7528028403EE1F34213588411E691672DC1989EE929F69FFC1A87EB72219577E24D3F31E8013CACF03F8600490C84CF2348E10D4B1DA72573A9F4AD9156B3FFAF41B104FED8204E64A51353F47904B42DBC4311520E3951A45E2C1373F206D558E0AA127C400CDED08D087734E52FAD8366D786622A62A617A3A6CE792618837C635F60C45608110F191912D3584FF51D84C35340B9B5B3B9C94D6234E17E7B3A0FC76B48B34DB6409B0353B4245E21A15253D03EE89FC1C25DA0AB260ECF9994FA14EE59EE88048C12CEAF3E28D1E0208BC09F4E173FDCF0CB4D985913D093B6A37A3B1AF4989948B979446E89D24B121F4EE30A3BD9611D698B1B4B9F652724BC80B2AAB623727574485377C20E9621F3F5BEABA3943B61D4938238509A327EC910C4C91DDBF0B4A648B1F621DEA766217BD65AD8A628A39F28071B741CB1276620A2C55D975B1C2C56F6E81BB57B284AD1D6985A204478FF3A4E849F5B0FEE7B428C058D1D393C90F436D772FC7B8F9B9DCF2052E275F917E888FCB7E2916D48FC51E93AF143CCF0BE2ABBC05BF10577D769AC2706177D5919F5AF6DE12E99B3D9F09952230B036E3BEF89B20B235B9E250A02D4CDB9D14551ECDD5C5B0669EE409EE6654A9223F24C8A1FC4BE88C993F8BF25D783C79087BC66C00EC0664F33051B18BC2873B997B15A38A2C7E8B904C00170B5E9874DA8F50B76490D0F1649134107BD2ACD3717B5D5474B49BDE361DED36EB52A0132BCF5EDAFC82AD33618B77F3A382BC32624D39A6732522E4CCC05BFEC4B8A0AF5AC143C3A403BD5F14BFA86A71A85EDF5EEFFBD081C99C221355D5A1657A45370C5815ED7799BE3308A774746878309180DA20792943ACD1D30137DB52DC46E39563E1370C4EB09577FF3D58D1DB81DE0C7241DD1AB6254362FDE4850719D5B57B237882CAEFDA260CE190536AEED81503F2D7713D62C8E6DCC668EF5E8EF6DA38BD71C2E0E2B93D66E1406A8930D36376832A1621B1BA35A7CD1F572AE2A795FAB0787ABC98EA6BD6089D9F02EC071205B603F988BCA2E327D70259F08C6D57DB635B740BDEE9DB47658426ACA91A2A40EC65FE7171B1D8053F05883EC08C8484E599B2EF851C330471F78C0A8819154BE4770401B7A309ACEC2C412F3DAB3C89EAE5DB44B9D4AFF661D47AAEF05E63DDC8C4AD2BCD6A7F32C6685D69D97D28DB01EDA78B988B974D275CA566ED69ADDF84F34E5A7CD4E57A95E19E73ACBDCE88C33242A932F2945F2096ED0688D31", + "sk": "CD40501C8F6E1240FFF9B675CBF9F802F93CA9016083A7702216C49F56FA138013C48B3CEC2477128AA4F1138D64C065E4AE6F90825B8883A318E3C0E57D79608872D8B10C822DAA41CFF163BD1BDBF8F00E9422BAB08E519A346A00559FE33C1937B0006E751D8E89206D6BC60CF86C989CEDC6A650A9D8CDD7A885A5D5959750448826460188004101125111186074620576284254126602486514650254327504054426658404637850147516850678005764401755744635128034716451535421171000447534622142286762007017285656210134675821180311780513280388413616213558436053280311820410525136513060540160781021887535516157262345448444784701867043127643363865707424667300015652134858161472800247384008538765723005036486454028675180110070100585227018422187630788540325626225188813123884672141516606825703365081484622675274186476437010486026151361553084613341471802783747425386776481227074016862284216366468674776440845680570115565427708841053204705545428355530152603721866522350763826432546480520011000217246455705043270634768453003815312660206530127032003278361545060180436455308127725487262482742654007210440273753502818225888755041314584755808333558051776484568406766162183053205233717482617042441680463342553134108652603646478047082474478071810434283471763142724425102083470712525401031116854048436637142716444771867644085821750556353854203622388308758477100636263240477537720385175337344211355475034614513544055425640506651668811324364614815740531827808364780478544043850587041437810503082400163542252323515405157863646838612144458502587220415731546766633753238104428464045120204231781335071761541014428403711427277077374826708330641275013578628428874500743644104623670603744818368054481625408140001614207775166058635432827321472400672317435015252346535680281888151477005612260638815080663703827487130616081186003343810854681567106141615804734621383114175553858354054073406806336125653830065280187374320341007765836446711861021424842660758755784704122132480132102238862510143518701447661211335031546207621450714706100313847443215510114355878185523877811720703570726544284774414545134241257007847220580113313158613736252646822524660278672558356438724635513883380417860673588850524465417657131258443717224832306011153434405086734832734238855846814657087130365072151474425107710001447436647300443625157617824024324281003277361345864124855547568664642638575406011371083735120870107051813268152180133151542028272641804564120630702784343172240455064040414206576102854172281178857284212558163858228783344551685467747877225614622512371447002823523287806683488140720812213887102060221860281611143315388888484862187875060500504384547208612234821708336400356848478172006063423822373324570772060541305847652773286164648028265165301157086073527525123782386608802465083320180637434353766062137470236812473248565115246843013483416800782261353501433487770254236463403451508568564101825531344410267156466015063128101007831428421211188415154723111285433565758007356644774022346717041065367152658860424264228021125381712078461548403462250318848437146704741046774408631383441511034835475844544150855632038827538235253151753601010467407471214815105021732547307206305612530887784636307521185FEF35B7E37D1212C06AD85C4AB401622C11D1DCB7BA0A9F7552B03D3F263D4A66A0986F2EEC297734A9D60561FB3C8129C37A3BA600C75F4365911F47D8DE507165F9C6C79DB19992779F091115BE1569F4237446174C11B193532C716BFD2AB84BAE3852ACEC911DDD3C0895040BFD0587F898B70E09E71E1C8CF9BBE4580F17AB55CCEF554ED6745F46455862B00EAC4F3CA7EB66FBCAE117D94003C1DF2A43CB4BD00A4CBBFD252B0B6956A61893F022F0709000ABF488D366A1FF501C32E1F3EB787728672ACE02A5F6D2A40D734592A8BBCF5EC8111DB6DF677A6D0E01006EB862FF074377799C7560E983FEB4C382F89DEDAF21D5B2A39EAFABDEA4C3693B63D0D1B121886E5C3EDBC109FC0D412A548567CF467EF10830098EFD8A010038236B05DEB89D1D36664FDA3476C5EB93D71BE938250D307E5D9B42DD6EF72188A2FE5B408518DCE4A36EC95C4C1E23E73827DBF9AEFCB93C8B5DF3D281EEB9BBFEC3B29C29AF773433F3DD11ECD5CC94C0E9B58F96315BB12DC9C7F43FD1A148F1F95BF7F10ECDCA26EC30515249869E2C73B976499E14628090203FCDEEBF7ED6B91F6BC99A8B346421E991BC5B2E938D73D04B93413B870DFD517E6DA6EB8A94EAC931B83A68BB40482AD982ABD87DDF0F32EEE6699FBF7679205006B6D103432C9AC032FB18AC75A1AED57F37E28F3188D143340666677A1F9F6F5F7FFBF777D593BBBE243999F24172D2F74305F082DE10517528C0DE33F4DF1D4CE360EBBDC1FE3EFBAAC2E2E573D2AAE42F0535DF07B6A2808A5960A911D6F04B87B15731BF08A394DF18A7E2A9F9738305DAC46C5C0B8054F8B06E9C4F846A0E49B8D194DDACFE9478D0D08074B7C27E5FB13E9A8B6A7AC3C85717E39870825AAA1853DE322A904455A9C42DA9D8D6C0254C943E5978899C6CD910E7FFA2F666DF2864CF0CF668AE1CA8B062ABE1DA95132721921ABE689DA865DD04EBC092BF2AA2FFF57DA38DDE2FD9DF29E48D2049C61D7E506D9E5B0026900B80A9559FC6745A794F5264794EAA738A56829350EA9ADE450C2786CC6D51D74A8F8C8FA724B4458CBD35C71D02FF49E09997D6CF57E3E0B3EA3EDBAD9AA594D69355A501B09873B433997FB9FB03EDF9ACEF14486C491D4543B6D22C20F5B82DCB757AA7CE5A58B6644F45DB334622FAE70D4BB957CF1365BF1DF8457AC1A6116D50179B9F4DE05367B0313463982AA2177F9E66986EC007A6EFBBCBF6A7DBBDA21536246EE27A125C40F42399A56935AB1D52CD64B66D79DBF26AF291EEE29FB7D2FE6B07DFC2768B62756671AFF32BF43AC85A36E62BDE7F8364FFAC0BB74E43B4620C18E308C6694EE8F6656ECF25157BE214C498DD7EEC3CE6C8CDEC15F90DA71BFDAF7E35FF79C10CF28BD2B4E6CC5B006D8892BB49F3A1AF40ED845AF81F7EE9D26D6199DD628F0A1A0965760FE30E6C3B00C3ADD14C6484664D640933ABEEDF8AFD38E4BAC598353ED16CF66ABE9A27156A16743036D0FDADA91563013CB4577F691075FD5827796531D3C3B4219E904C08418F3B05D699550F9B6A42A2274A07D3BB00A1C127869BA20DA27B494904737EA8D06C75C26C74E745680BBF20713CF7DF7F800CB9393A6EA984AB452D8472AA18FB9B77E1EA98E2B949E78E7DD5B136DB996FE57493669A063275131A7C1207E7110E4620569C51B5DA00E6ABFC839F3A301B65F6EE92EA148F631FECCDABB60E6C64A3D1A03AD1FF48F540D0212E6F49C283E19B805040FF74EF6982FAE0FB8BC3B4BC123405EC37DF7A76A7F90522017702DC629A4D4CDC38EEC96B786B7E1C7A8BD559D28CA2782618F771A02D6AE77C64B0340F1205F2AD0AB202AEF7BA2908DEF8FBE78848AAF2A7FF551FA952D0BC58581A9C95C7A2BFAB8DA745DE41A694425BEB6DF3652DEB5325D0A42E5F2795BAEEF5B76261A1DD5C836843B50BFF75F53CBE0094AF351990E3B3AEC21A7EB5341EB652EF5EA8D8E6DB9EA862E1807531ECD0C0BE38A51282B8FC579D8FCBAC82E49691FAD4B45364F280D7BAD3902E745A16A94929870DE881207DBF076691A7AE81A66BA6CED9FB349A466935BB34028EF6C30A03C0E68AB4C39C129FFA85379152013245388984808C56185C779510ED716006F4B014778A5706D4B8D02496EF7C47D3CAF14C980BDD48BE3D37AFE25BE1B6D18E131D88FC1043AECB1CAC973707F61CA8610A107793C796F87F40F67AD15A6B2E84CE6C8E6C58EA2113FFBA3EE77D357322AEEEA80BE8E6B2FD7F52C8689AAEBEC7203C56F6DDDE1B2E29AA4CC6034A9F2DD07DA138B21285F075FE2FFC8329F5E8BE9D82F4762CBB746CC7F327FD21720B74FD3DAC57B8786299F49C6C602C7956ADF6BF661594CC5E90F4DA73AD1305FB1B554DD4DA00AED39BF0EE6FFADB87F427095E10EBB336B7036FA99FFC21CDA513AC77DB20998DCC3156AB73991A158E9136A688B70C85048F09EC38B6691FC708B53B9B6E520AC55A48F7D50F3C863EEEE841D984C75444105937FFD6B3ADB67B48E7342323856C636DE826209FA66411AC5605EC7F7F255FBF88B236AB77B2763F25155265411C74271B5B8A5B835A019CFF0BC55233EF268AAB76B4E9859538E90E818E6F660CDC4AE93906DA2A5E80DF4B1D5E0FF92243BE91418D5E3FDCE6B50D2727948D2559994C2C40A5FC27CDDC97D1EA18194DD3974325E8650DE63DB2977B824D7354F5C90E91A2950E69F4F628535D2C7BC994FA6F175B31B7EDB3CAE4D259BF6477EECEEAD8178D6C67D44D6C4DE1EC3E5C09AE82B40C65E181F0A70F10199322A7CB53FF2BADF4FD53733E5760B2770AC53EC62E25A9B82C3B14DA51F746D6AE4CF7713AE33ADD9ADC97DDE11552AE2D9A75455F97CEEF197DAF5F83DAD6B96E22773E4B0A1EE2C4916E9C07C0931DDBDBB251F3135C979AC8B81BC76AA46BF932EBBEAE2303E35E723B7C90C48B61811B210001564D4B9A58D18C46E58B33D70251699500854BDA27C1F58DF5FF692B138C1E8A42504D83369BEEF19CF466DC78A9FB69FDD283BED6E70E89693A083E577F628C099AE38065D38FC2FA9CE5AF0289AD653A3C4658CD7A65784F9935CA396451990CC56064933D7A52A5A047BF87C551A842F5BFC0D29F21DA27C40771B86C310B7345B5A9E29F99960E795500947958ABC2A22A166AFCF6F60A4564E5B00E3955318AF13E10F79268992D58A73C3C17D739B2B1F3ABEEB1EDC560C2E25C846C31BB644D4E3F24A07E7FB23506DB4D8FBDBFCFF61FEB010A02C004F33B39D99EB602035B190950E5F0AFF31DB5B603B1D578E054AF0CDC324E2D4AC1753EE363AC120BB50B70FCA0E7A9A30569A701C7723CEE90B3E25299D35EC97EE34A8794D730BA79F249D7366BEA5B6AFEC2B3071343198B3077A3290957F89DA865C1013D80A3B1CE9A09B282F989218DF94F15F675A65DAB79840EFE887AC9A15CC16F1C075E6C7941812A77CC8938BC46FD8621DCF20310FEE350EBF4C07DFE758" +}, +{ + "seed": "D85D7C2928288CD0B90D7269619F8D8B4EB3541F7E084CDE0E39CEFFECE9AF80", + "pk": "C105520234769BC75FD0F4ACD281DCB4B43E2406041E50BABC04ECA333DA1B18AF77A88253C8892F6EBFECE56F0433C3E0D5500CB944BDCF554EEFFFCDF172CE264916F22B21D87FF3ECB966F0BA2D34A36C726537ABFBE2EAF279D740B4AFC1D4AF798EE5212C7B6AD63E0B14A10AD15C405F2C159CD98FB38DF453448473CB86634080F983B1309134427B95C48CE4D80933A4E8C20969AE50D31B087C3AF9E2E5F189B5E92221C7A699B2874BA12319FD27F1A96BFCB603752C24B89E02EA863C80E5D5B906F5AD17F8812FC928BFB27C168D87348287C6112BF1C48569C719C20586BD825FC4C8CC214C8B8ACEBE8C305255B078035919D22683A3CFCA6CC1B02EA3327DA2483791EBCAC9F1884CA45F16FC2086169856819AC7F73EE4BF3D1FB334AB587942021FACE990AC71EC9C938AD8F9DA7873BB98C195FA477E6D66815264068B2267800E7036E955DFCA260102D9DD90849A603F2504CC142E3C0FE2744BBF908674370FEF10374554D090C039E78558F178412F65C59336E8D5351AD74D4BEB2E82C1423AB672B58E9D27B3DB4A39CA733BC6F556AD171B5302A9D93A194296AE78F4B3591D85CCFA3E75BDC7D59A080CC9C42004C3DFAA70492F2019213B72837234783A11F1CB88D6A0E35C1CE3D4B8AAD793FB0E16F10B32DB641DF8452583C8059270FAA562A0A94D250304FA03F6C445EC45F6F5EE7E1CA89881108503FE71182466833FD09E6229AC09CF285E86D2F755DDD58E6E0B4250898ABDE89C802B7F1D8960D74FB9912D156B81A4E9C9D3DC052DCA9045E0B666A85AD6F334E4EE090014C3B2D23E902757DBF78FC382AEDC9F2EA122A582CA90907C1BB3987AC70E353FD45A3F819931E53FA1ABB705F2D143065CE7BE38AB8144DFE1248B9B69C2367D377BE5588DACBE8B572540A0E6585EFC801E4B03786AAD9592064459DFCCC3583132DB9A8A500A87684981B121B6635D5DF056539DFB063BAF1B3486A4CF80AF43E828B8C1A1B41C9822475048C91281D206E056BDC06B1B8865ED92FA5286F6BBC00014A4F3F28A2C47A609AA667174BD0EC308876F0043193F68E3067279AE809CAE4DF6029CE44F836AD611B27DC35DA4295F1126903E681F5A97239F08A2594768A91D01374C403243283EA763F4D23C530CC383A6E532D70F9B02C64847394C44285C20591DDC84EA24581DA5D98FB248BFAE3E66E20233893F89D50320E74473A1045E0C2A540F0797456C6C121B3D2F5BB94809C0FEBE8FFAB8D9FEC020ED5979685B9191BF509592F1C1D98D3EAAFB0FC551AEBCD53DAAEF10B997A46C593C0BCB3605F58B8847AA9DCA8A04F3CD980825F8B61055253C4DE89D225F7907D9D0D3E9D5BA1E3AB13C3E3AD89BA579B28F7D11FF0C757DBB8C1653C1C28F39649CB19AD2CAD524FFBC21FBBE58A4CFC367BCA0863175567BFA73A681948C462AA0D7146307988E3903C9971A81BEABBEF66AD382B69EA297B80422B480F0872CC00BAB0FACCBA788941D4374FDFDD56419B6031A1DB23A5A4A7BB0B363366AC5DF5A75A72BD9DD57069074E3AADE3D154ADD4743225564BABE2E68B1E0028392E23A3A4B8E1ADEBF4661F64191DC9F46DA8FCD5B769C06B8349C1C25090A29EA254D9CB9537662D339108D5B8C7D5D2B81524ABDCA3B2C5F18EB38F2751062CB30FAD5886D287E968CE885AC1631380DB84A304C5ABD351F78261E2A4F42A9A175B87752485C984936831A7B8012746FBDDCFBFA2BDC0DB4FCD0B79F7E652E5D402AA7B640EEAF8D607AB02021DBD0920EE6188ACE856EB0298F6C2DDEFC46B4D5A38D4B8AB9EF29065499A0A83D5F319C634E281F54C7519235AEF1DB1963D436E0173CA7A7FAE1B54303067D95D33EA9A25A94A490C55634CF4628061A864FA25E6E22E2E6FD7D733B0D1996C4E47190BBAF6E4578A81B7A1704CFA07951F61D8023AB3F1C5E173785F974D53ACF35B3C66A99634D2DC3A8C404247A51134D41A2161C4A3D0E4251B0579A9FDF7B3A7FED59637BD9F8A68AC98BD5B1009BAF290EF5117D6FAF7C8DD87BFC21FA226A9B0126F35BE6694D507695FDDBC48528C104DFB00662DE32E79E0C132FF9C08FB5EE336C98A93F7115171B6C2B3269E3AF5690241A66645E96799ABB45BA96CA3F558E293681A28066504F3B70943C99A465925906FA7CF3B820988DB0356AEEC8C9132BA78D212A33576524812CE85DCA2817B3364D68670EE07329980CDA3E39D88A8ED2199D55F5558CF7B817739E618D9405BE4B8427A3793D8DDF359F19A9FF09B2E2BEC22CA7DB34F2B22D88DF8CC728F5DFD167294CD22B144788C97CCB5D93361E6B74B072191BDFF77A6FA78F3220A47924A3D04948FFEB146838006F58239496E4EAF29C66ADFCE9724090FACBDE3951C053F42F34F764EC61A1D3A8A113CE2D5209A071BEA934101A571797F5C1C0194B9C1FC3B6599AC9C4790D83F55BC1875347F3607BAFAFC4DF2701DC07B68030A693BE88DF3C0372707318402801BB20CE414795D7F250053D0AC39C75FB68EF64EB419FF859D89A3C86C879CFECE9BAE38941F2307C920F1AE48C3DF72487AAE2BC63FBC20F165DD1C22091392D43EABAE0A6C4FDB3824E48548310526AD7A74E4EE6D73BEEBF13EDB38A59D7232E14A3778DF9DE871596C32F0546A16FBA37C16295B69EE997641791C7F3D5777F09AF55EA3F65314D27785810371470FA5617CF2AE06818318A0277474984", + "sk": "C105520234769BC75FD0F4ACD281DCB4B43E2406041E50BABC04ECA333DA1B18EF9BC3E4CA859E29C9AE87D9F6ABCAA84A84B20DE0894F37538E4133F557BE79C5075909BBDE7F5D579760FC0E58AB046E437DE6407CFED9CE5DD4D5E29AB04DAA70EB9EBB4D9F8AF32E0F7827F8D21BF738584C05D72BF4849F86A939718E8758445758814405066377236336162422838141762541276638856732360636423606651537874070450512230825442745831855684586351301333083575603024146601761737864228634768611208800655885828450737877205363001110217403351766632673281486707612045613182023667776367266083085712334830625737734852167672546845358411430645183583205065515383430563752021515024067500252010305132523852061423631568837802262668835487215855713274656266553465801348565243281764238745587354847434233833785336228853521530475450885388486887835421722800658106572655224626170632788231534531055663633012723460285353506035756252730815271414513036013604238484541566535734773380388840006280582113173886805271424366177715072681663764401431567346132851240273782202733172167802164088384310178216148840587511022757608251252064470305511284744230376254058476377274278086212488134263172827505611528825772601057638282760062084248067366371506358270582646651731160837361726605566053122200085235782558202084671262280830376814326676177807216075382173587246317674115285874745625236467814027788077336464042438520155042207346565724471747218387263118251375556767004053380182005875423780068363181661642242542646383023783342543587832154174778867365514222838388050642140134550860437148533084783344668707368431437015074670186306765104170870588047846213541524414736145150241215537864250374007845472700883417116237873657100750277242403235832704882353311545437405684075044150771571660005121055388384687305874147352600277663431646864700661301872840663534130204184605151861678802848543043027112104621511332255801120370470314425616558471472110733484223773623516535806637808681554467580118184582804154876801541184062762533732181015884585322680581165844687268617606655544276240638067611886232388527868508066182130307666322465628720528384531681113858304217150642806020144620080026852272610816183175145551704480131107232330465767126775852210875576883641346622737681600741174706303221251408630641587163003138713755442054141327080413822046600263640713611635310468722133311135012064031401143771510032260820885658416866680820730365314128654311255766615845301470057467310803472744450477206372254274621747370402131043815278774511034112778031445315048801015187323248127122555821044371482802710874843188101116516365815731456515676384256760350158471615247286366525363544813275860301445876074135438836883327838320860533654243487313251171802278742026065607171267878685588702652134688634745721733478005842454053488684540346456381110877324404284677613573082782065301706732632677347535583500558363725728148105342685468251370277036362661674818553152823343661441735136803538852043417412770322111347850373120404206488162576682561408525683855506861223536747512321018852123356208573123754682321451266335483743432708612575374514747037003725505244127842514108713422352781075135017606254307364886354437140385584416227381884E738DF38784D80AFE74520CBE851F26E4100D19105EB33B399D0F6165349133CE404E2030F5CAC75974179AFABD7E4D86FDE3830B6B1BE3E413814A2A06DE211380DC4FCA05B008125D64A4443FF3663725BC63345E388CFEDC27F2EE4C8F8085870C29E360B3A695C984A30C63511E479ABA406A782A2EEFFB4B6D787F867C45D1F6EBED522C852AE8FA4A561906B019A62E654DEA793EA955C6DA7ECF03261947EEF8FBA2C47BFD27A3314B46FA227D0D2798CDC22BEFAC39CD11BF0DB030A68A9CB8C33E7890BCA2AF77CFED475871FA7617E98C86A5FF711B1A4F6A68D2D29423AB4A9C7C9844F93E90F3118DD81198708A1AF8017B7B8178EE2117AFE34A2847A97592B9BA517A1A54FE7CF4BA360B62A1DAEA0FA6ACCCC1E588C46129F8F0BE8123C8215DCA2091E8227746F62C7FBD2E0C4EEF88497C185CC912436F45A64724175EEE4FEC4605B792E336E3D457BF1891C79C9737153C9339544D59BE170FC0508D96002A7C70E2A2E826F59EB661EE644F1FDC88469D851A9A5114787EA6C29A3C583A3F15D32FC93E0FD8D725D2257B8151CC001E681A51E05E26BD4FB60E39E2EDC1F6CA39E7E55F8FE1B24CB959B44A55268932E7DC18B5D80E97182AE3E1042BCC32CB57FA5648DD6C8053AF7FB0CD6FBA70BEE596D9141AC92D626FE36186772D75537BD37FF20BF97881DDB831E9B3D1CCFE9BFA5B8E5A52DD3703E5E11459C17DB76DC12BFA716458E1F0245C9B177E341E3FC113AE2B827544BAABBA5DDEFE017CB3098BA6448AD135FB0AF73B42090FBC3968E9802BBBE9C6162BCE1F76CD5516FD323B415ECF937E97CA231A64B7E587E33402947A9D51CFF658FB63B529FAFCE3A6A5CCCD13DBC3A24C08F6ED0D2B218571340C716C4130925D9D0307645633CFC52E6C38FC41215D367F414C5C123B1AA87DEE2D91E5980BE6B2D1FC9F46AABDECD0A7C189803E287CDEED22C683ABF3D4A9E1925B2561BD880CDB1B92E2A1C6AA4C33EA39A06FE4F358B73A87E935713745FB8632CB52DA1E46DC009BED11FBADB6B917026134529A72340B2BFFEC7184B0EE9E5CE7558AF7EED869C884448DC3F7FE694F1529EC766EA9B5E212FA217AB0D6CA1F6F99B4DBC7F62DECACE5FF9F9197EA29CB99D3ACD62AD709ADB2399CAB425AD994DA40CA7BE048BBA952E7E0C9E41EEBED32E0A4DE84DEECFCDCCAC70F270FEA91BD399D24A9E0EA318888C3D059C7230F5E8BCB616EF8D372F34345F478250512E313A828143B4596892F19818DAD08BA3CE4F8A57FB343EE0B7A750FB19F7C598609B6EB01EC54C571A907411D72D5E04EBE8FA14574622764D7B1C087FEC221F1ABA307F8E9316DB1D5E843526657639E60FBB7A8A1707656F1E6FFD50D0A2B6C900462A2A93235151B6D3EB32F75798147D69CB2D55D48C48F68DA83B578A8DCAE89C480520DF326CDE6C92367D373E473FBFFDC81054E8BDC470690B1DF0935A77F004231476FF2D6A47DB802593AF5CD584ECA26AEF41E6D8C94C552481790F6EBD50D48C142F575E3B5CB5B3B9C01EE818BBABDC9324E5E88A842AD90743771E4B542D468F7623EF77BC0F330A71CE2F5F093E3EE3B4F0DFAA56088DDF128AE9953B0A5AA1264DFCAF098E43C77D5A2C4BAEA68CB34507BAB46C516B06F7DD0E9FAEC5BAEF6000FF918E53D15E4D8FE7828720F8608BF2DD2BDDE7062F4ED9DA5C547EE0DC2B1F4B9035E1643D5A9868ED871DF630A007E1AB95B8A2D42ECB35C6059E162B7E2A04CAE5BF1911C1D01508B96413E4DCBA4CA62BEF8AE8613434621EAD3A9C5EA09F170EC59F7E276B669E4E133DB5A3E49EE89C98D3223DDC2FD36C2F14C03D51300991D3EB9AE3E432C6119AE978302BE54052BC4871EEBF247A79EF131E39ADE8020C61BB07D065672FC3CD14F91DF7B3D48340456EA9FC42C3D5C0AAFDD3F04AF870629698E9AD9F5CD9EC8F3086B937A6DEC7619AE58B32295037DA9DEA0DAF9EFD6867DC2E045BB8C38CEA5A9E2F32E1129D29FA3C44590F0D25D84B851760EDBE3EBDF02263B5B1AB4A3556CA3A66483A2D415F261E03CE40620BADA221305CB7E811EAF8FEAB983EF9463F41D23DA60B7D737677F7AAD8831C81BEFAE0088322C9481B841E0268FE919397B2C48BC6D4828B375675EEB0BD41CBE839C9225D92DA70958DF89269316F263100671FCA80218EC06BA6BE4DF202AE0AB204C2E3C06CBD25F160EC690FAAE53D977752713DE3C6140F828AE24E1157BC6F5552E306B08CE3B3445694A7CDFFD491AC58A2DE5C0544369B9BF6FEFD1010633BD19691935BA21E31A2BDE9E11EC2ABD52EE99EF84E792CE7D5756925A58ADCD522932E8C3DF4A7BDC1E6D45F0D32907082DDBBF5FA15D1AB759F6B1E5622592D6F867F0E680672434341A653C9B435551AB55A1990061A8E4FF56700E76FC3FD715FA2CDA54D5DCE687CA17ED530B13F8E100306AB9A5DFD3655C3359BA4C20933632CA2A00004D0B8A6C4167B46949355C1379FA6C34F5D7A2AC4D3C3357C3B1C14D7D7D66B520C80A39CA5494F2B32F9F94063B1F6BB20CBDDDA4BC56F6599C343035492299D28D0889D3D794424C224DFE4BF48D414151662942D8269879DCAEE5E924819985CC88F49F1D9BBA5829579E823F0B95BA75BEE15A828EF9B77AC2D08352477AD23D8EDD2A0BF64F2EE58083B2EBCDEF0DFF4ADC99C2A809786DC4E1E12E6CB6A6BA15589CC627A11C784A944D255B8EA82D48089451FA1DE1E8FDCE437E97F8EBE4D3418CD830705D1B134038D95B8AF89E0B851364C8A75874FB98E1914783556D1A81D767E5A346A7EFF827392A0CA0680A48BAFE20394FE98AB290374776D1CD314127164338C2DC78FF219EF6DB244BB73CFDB3A2272DABA26016A6A82BE03A50E970CAF008326A51976D717C121B22D2196582DDE1CE8F226D53BC95572DE85B5590806AF84589B7D608E6485AE2DF98538074A56D5B15406DC95C08DBBC27FBF6534668D77386EDF9A079F79A6BEA49791E55E53391B2D6A21A394BA1FA6FA9955A500D702624C8A26992CC1454C5118814F959A3BCE54E308353C2252106A4679635A1692E160EB5C5C028EF93538D082D77946DB74C0175FB07CC7D2E98C77E674562DCF316C7FE27DB9B95CDD3AA13857CCD3107CE654EC46B39143A411D4A30AC43CC3203E8C1702CF30FC879D1647C565A0E3F204D87CBD8A3DD7EAE4D3339023B995B85204E8EEE81106B8A51F00C8D8178DAFA786BAF1F4D236784A9C9B3C02976605A820B9615D1BE26E8F43421E49AB558B07B4A05353571CD088B8CDF1F7077209486B9A3176F5C934A5A3EB79D2E60FCB687DF8BE0325681BC48ABA956D006BC0022D6DF92B14456087DB752C4FA8DC5D3A7ED18EC9A5678F43AC498D1BA6C68F1E4BEECAAA3DAD0B6D5BD678474A21CC8CD4E188FD229243D08D7F853F79E4EC4DD73599F826DF9BE380A60A896DC2490918792D76B7A7761452A8C839DEB25B09BB87CA360E" +}, +{ + "seed": "62E511A6731C2FA10DFB5F68A538CCDC1BC578C16E7EFFF458A82627438E78F2", + "pk": "EF51EF72F1C3E29FA159F3AD631E7BCD3C593D3386F4EBA484DAAAAFC94C774D810D2C97E964D54DA11C0B0E1525D2AA06A90B4FCD30ED22106FDC449A3405398F7F7D3C48D5B8CE2BC01AE8080D7530F7B37BDDC656F530C58EF169451340B9E77F1D6524CACF35436605D4BBE69DF7041209DFB7EC91250D5F81E8E18D1668C46163191F96C81A82989633577880AF1E16A4F46A7EDE15AFC9CE8123F8881351422F69B3EB258897CEFF699742871F2C2A9680CF8E9ECF81AF1B5350203C7C6893D02808208092E2976ADB732C9D4F48B919D61580F19EA0DD6BB86DDD200CEE38D631BE40936D869C50D9F2D44537B1C4A6E42407C427B41FA05B65A12386C67C0589E2741D580EEFC484B46AA6C5F7A588722F6F6A61509E92BE36992DA24182D50A4344FDCB8214A1DCE582C1763FE83605B3C05AA678868CBAE21F168E10D585B83A0D815ED9C4E82AF259DE6C0334C6BA3613B4D909FE6425204CB344EEC4370F171173BF4280D817BD3A60D8C6787A0567A28E08B931CEDB65E236AF33EEC1F40D8F5626649A9F7D94AA3A92A735B33BA79F755B7F0D5E85242F71BCBAC7BF03EDC47A7170C62E007F2C0FBF62738A4C2B4D4DA2A3EA1D297EA7F0C2035ED2D73689389C8E2A8016BF17838144983FA4DBDF402380E2DBB34DCEFE65FC0FD8A66439794ECEDFAAA71D767AFFE9D9B5DE20B5F6EBD276B474547537861F4B09BF224CC0244EFFC27F77380E90D9ADCC9F51554566F9C40096E4F922EE4AD9E0AA1E3DB8B1F1067B68CAC4B5BE9EC9B055194D9223F2CDD7C1CF244CF6DAFB0BA08505D009B0D9878B555681E32D47D056139D415366AA5B7DAB20333AECD22E661204F6AC710FD8489E24CF4E665ED1CC4CB6B38A690EB5B44EBA1F664C7F3EF4058A07B903CAF36EB5D53FFECC16D217623984F3AB54696AF2F68B3780260EEBA27FBA1C968B8AF0CDD8E3D53FA9D307CFE3B7885972BB129876CB12FAB77918EAA6D4DE61E4038C3791B9D56FD46C7EC08F2CA37AFE5E88B95A55FAAA3A0A014BA87CAE8ED39BE46D9E3D59D25C48A08AA1120167B6D03E7B829DBE1F53B3C626ABD9D971CB096424D66053DF2252E01A53D6DCE5670A0BDBB79CCE9982EC044E8F2EFDDC47E90AA819FC6D53C63BE6231278F15BF5BB295C775C72E77F26D4E24D8EBC88988C08AB1E4A89D62EA91A1C3C66C102736854B2A04DC4CABB39330960A34122C9620DF3FA99A1326A2B6E56EEE28708E6C1E51DD1B442AC0B78EAB11A887348EE2ABE3F1541FED4B7663FA46B6C17FBE2DEB0D2F0EDBEFED39C07D16495FEAB5FEA1B07ED6FF827BD0D34F2063745755CB0009660A2099D9CEA2DB9AE6B59DB696CFB7082FC585046C03A4861F798638CE6761DE09F4112C52B4DF752A34507469FAF20C302E33AE7E9CCCAC61123AC80E2B7368D68E21B14AC237AE3705A4E039EF57D6A93220C644C74EA59B565BEC30777AC494CA92887B1D460F1D6B0CC153201948076C94847453F9AFB845E56E6D8D5D6D4C80A1D90032246989F06FD556D4FD8268A1221E1825EFF23049724A686C50F9322A2778D85CC368E80402464A578C98810A3BB7C73FD347ACCC742AA20C096CCA8A9AA971225D78F3A5031B828AE7E537BC77B3F956648F29D4198CCEC25D05F2CEB0FF38792B727BC0567FD1820C8FA0D4C15B3935597090E91B961BC2DC4898F184581CDEE606A0A8F23BECCE52192DE1CC9F2047B5D28BBD8082DCD7679C923344697B737BF564A2AA5372BA50D245E80B3CAEB8B615767B7B395240D844711B025398A4C2E35837B5805BC97E4C36E8D8ED45F57FB4CA404F484446304E5A548309FF4F024CDCC27E89D38E1E4E131928DB431D0150FABFB2ED4A928B167D1E296E68AA860EEE76104718B00340872994B369C368410B30D427175184F5242107CE1B8DE0AB862796D637ABAB7BF5E62A4730C8810E3CBE109A6ED835D66F9D5C192632CC1F2CA69F675DEBF82B3F464DE1E5A22EF221A87B6D8412296AABFFC87E86C1EC25BEA15F0B193D5B8D5EE58FDE46EE76DB19F6EFACECDED8DBABB62DC0D7C1B7B4CCCCFC5D6BAEF0369C16959C7EE04AE41283A187D8BB83255CC0081EC18AFFD608002610B168EC1FEA21806835C183BB37853B3F19C5121AE3670648E162048F248BD669EC2E9F90869264B7629DA97F8A48985D59B5E317B5D41DF7BA781564ACE32673E4ED2C267429BFC26C03DAE87BF1AD04E600B8EF12881D00AB2BEBB88BE9B80DB3A59AD91BAF9567D3F02D38A84F01AC9DF8A6E6733499448CE8891A7DE203660F064CC3C3BD9505FA9B0D4471693A72AE18E35F52E218629BD7A92A3811EABC1B3CBC78F36F1209CE73D536E9BA3539AB3D6070F493DEA35C9921BAD86CF5CFF9283CA21260D01B5293A85982CC7B257B007DCB366AB842BB2F827AE1ADDE271A3FB87B801C47F3B350E46F15AA15D76C12637286BE088EADB07A66139FBBF4ED10FE023D758E55C2C8D890097125F4608EAF88B33AB5D72EDD4479059A2813CD074A0E34CDD75D13084BED9E7A006371EA1E797BD57DCC737710DB399FF2D7C40B05577EF13B8FA0A04496276BF54E1E6D1C3F9868DB83F854D22B4CA511348C1C138BB095AF9D9295FA9ACF1E34FC3E153E0DC5E3FE6C26732B91BECE623D0C0A75EE15F3EE55725B544B88BE6D7D29FD77C18E063696AB7DB9C7D9C7728FE418E0CE81BE10AEC7F2650E270B60557CB36A88D18F4", + "sk": "EF51EF72F1C3E29FA159F3AD631E7BCD3C593D3386F4EBA484DAAAAFC94C774D8543967E2BB6AD85E15A3179E43AB6210B92C397EF2A36304015F31F60DC83520B3E2E2C7B7E3A652EC0B51BBD31658BFAA01BEB6CE0DD16703E8306F1421CABBC2EEFD701D60E5F2072A86796AC63A284748DE25B6786D7576C9591BED5250D1121664437027712683823110134744782325716701825326106281417512402562610760774070343722070662367530147028781502758603157256305388552722426744506877140170222115755788830108151370532112385248757273210600417046550866454217847036112165217026334580616264266850007412410034322610722874412460415117243752444301602835170505851723667537487687808834221236561731042711113664647265734388234256740808277021024657346336844647180827423804866772028353351361670188658044347366350218124262267334435473855537211130380776088281881551766412145021645553875408724137851647668330658315135038267670382522043487733486060561457458043303027081056283277024535724768402670634777386227288035465267040734338784170132363651088253345304861706644881714370321243303456008237433072503686580630655646152582141715035716673665747140801705080317547517185862266481747431722632188065665210410582248202410334706237247575063208513068542270135344480624807537048480257675722323868828523667548614484014178247848124228773143444620546765572057224808221064011331533864761613330733788818550157340764213234637215043534188225246248281740085824730061387131717516063000018352515166156772488565363385310845267712035500857213573868153280775421661767877171368115267572412817754047622165670213137627105670022861852722630553286872248723225586151310467404677764356827417400515120767731720865132638665281483360808157072283037470672371102636515325400318878128348651077203370773663621888364417646737251134728117508742145812273038200087512187114012422063043160048858500181257281883384253120871138472364018411544174868763812527841472624285482785457751546051004821681781406613433481252758641876587085482852562232237523732553411565212412604250652414531618530613526624881737841718756787780272121431872321183822088511353210454732244658312661582133328744116472840474843221621543832313310685346707326357765544520442308307863180375243803077277353233600485441327804771085561221300415863220114516267846385655746223526784608523021285328004700858523753543662754344646814246060073571775452627175168743175130112638655838615286783432204861821730783716411812363468715234157311333307828807358242827006155513883707261038435330521613355045286071466437258168088086533315463186611606788828853586717026080606737676270286022426073737051117462454068011642116863107044530477611414484156003044801451425172355417510241275561626552532775433703464354358238878657601860456477867740546616006031482073282787538313203724131644133801723168488715667283314218312128313170507635704084481126205514816851386454877547178307011008511063001268188821288520661657308875484062782067558134202582486678183064415640006521703113811861612754566427581001647120348066328787758180026152053480046235012435117513720852020136141848740456316226257681303354467224068344155288562637885645005055251476280088665121557083876761876614184437734187175A705DE4CE30DD419A30FBF87F172F493F6346DD3FA5C18C5F5506F4DA575F7E76A12F54D1483FBB94D05AFA2EAB6115DEA5AD6C86943D11B5F914174530AD081E5B99D3630652BC23534C4DCB5774AFD15445075AFF50D97A93C7C83D80AE7DFA051EF731E3DA1960CABCAB92596054E42B6D3AB9D4324F147F3737792EA623A4047091F692A02F11B46C992509087B4BCAF1A3A5B961E52FB08C28331A26A7933BE9F5285A6F49F617B504F31D822F8A7716CDC23B1D3742DCB3C5E039A9DC0C049EDFBB1A615DE470B035A0CC7E15B6F1EB7A92F031541358234E70495C375152ECFFB86F158172A0C63C490CCCE17318386A5EE54319281EE85E53B6FB44DB01412AE8E8172FA3A09A4907B7D8AF2202801CAA448330E8CB0FD28048BF01201ACD838C30FBFDF7D01626574287D93078A0CD752800B761DC4FFD79E997BB1179C67624A0BF3B2441C9E266C78C07E99F788C55A4694005F8505191EA20B3A6C41D2E6AF4ED78B9B48141F498425257E015805244D88AD9F7E7803EEFF88EB2C74D940C7F4F93BB99CB6B582C0940D412787081003CB9BE3F3D2974FB0C5211B8C7746F8C66D0F5DB018BC8B5DBB4C5863C10247083B3701904FD7A498EA1011EC87A31D3F22E3637965DD63F564717C737CB9EAE48B00EF49F3EE4D875712DEAD9634078FCF28FF19C3DCFBCE7CEA5744DBB1BEFC10CD4B01A3E818C244EB1330F7BD35C2F18AF7789A2040C09F040505CB5036630A7F3EDA0962B2D5DC590AFF47D6F1B39C4073F5CBF139D865D531828C8FBF5C0D5A2366AED1610974BA8651D152E2DB71D5FA7BCAEB56B9C0A73C1ADDCD35DA6828FDF652F6E92A1A0307A3F274A9DD3639402774BB62AF2CDA387854450E34589F1DE919852DE1E7FF90C58743E29EA4402E64E30F75C8329A5EF95F66960904B245AAD166BA02D685589930C4128A95612826BD06999A967F9147B18D3E966C3A9071F709671B9CB6847EDE93AE225C70DFBB4623CDC0066DD7D13788CA2EE4ACDCD857B8803C01CB90DBB650B324AB2BDEA62304BEDE414B4422F7610F113EBF9B7E137681F209AD1774EC5D6389EB46C736D1503DFA228B7FDF5E69BEDA7901F61F2024D9699A28E3B3AF085EFF26C17B962D6B340CAA2EA1FA927F273D676667A1A873B60607E7CE4EE1739D334321FFDEA839B9B9DF69D621BF1DBDA580777084614623500E3315A570ABC6722CFBB1E20B32FD410680D87A789648E00A129FAB4BA628C060DA271877425034A52E2DBDE5720A333C3CBAE2AFF7638D3005553CE6C69456E835E23B98EDF88D5037BECAD644EBC0413B77D942A73B47C87A399E18144323CDD51ED50038485D144344F56089ABA4ED70B8DA96A630D71EB80CA91D410764A030AC66BF04CE2A837A345747B1BC355B751A591B95974D2C7065D14C8DB475ABD6061A9FF3FFA4701119DE5075CDFF32DE15150222DD9F6EEEF8197E73FD6EA63C778DC9341FA9F312945DC20E8E24C607512C501921B7740179F2ED8DE976AE0D6F8EE5D821A3668CC9ADA6ABFAE60816BAB6E67DD74AB8D3C271F0BE15C583A561ACA92A7CB63F2BF60C0DEE6DC87ECB3C0C1BD5F16956C8A937646595822DAB1CE09B1E194C77735A50F8AF265C630D20D8612A3080B2FB41EAD3977D177AEF12C2498DF63EDBC91A1BC2929283F7C66ACA5CC4B03D9A410043B8003419E1CC5D09293D526D79304ED589AD6EC522D10CEF80FE742CABC90A82A209EC4B0BDC1E202928BE4A6DEFD6EB37CABF3574DCDF357CAB6AF07B22416E82722C5023E96CB6B518754ABD8DFEF198474A37AFAD1900755BB1DE56249D3C5BE147954670C91C4BD940FEEAF275D87C04D2934BC71214A96BC3502448156F5B4F3DED83ED55149DEF3CF1B39F43BECFA1ECECE545111A996C8B6F46066F759C8F307C7ACAA31A1823F27CFB8A0FBC4E5A11D6AB0A180E78AE4FA0DE073200DF8717D08021B72F1ED67089000F5694E518FE3C286610E0C18CA312883F5BD806CB6EA30F4BAF513FE183FE3109C43BD5BCB42EFA5FA0A5D6FF7EDE6CFF61DA65BCC6EC78BA9A35FC2B05BC4D3255A19C79332F80AB35177352A6DBA730C6071099F3DD56D510A129E6DE2D38AD6895C5B917E22CC6763CEA81E8B2A88172AAADAE3600A911D34A0AAB6DDA0374DC776FF50CAF62801E2DAEFFD58453B27E2A367F24106E35D1625936D31E3C26AEFB9354D70417CF264BD5B394D5DDCDE1F90C20CBEAF24323BDE3078395CFA5D9AA74F1E97BD4628B190F480D717823786C3EA5B6C0F54ADBB0B2DAC9CE7B1CDC6EE67B036F16CAFA4D25F6C74592E535302F8F3FFE3B91476BF588CAB45580CD0EB2C421183805DF21D51BAA4D6607E40469A5509AACC29605F64C1E48D4FF1E91674E52CE9A6D5043380580EE746CECFFA49B6DED160B70B3C62C43A233D6F584E554EA5D791EFDFF310A7F5225E7873B26BC5283495CB1C3C2BF64D868B85D463ECFDD28B6682F2DF7E57840F535D95153F6AFC2BD713228D1E9FE546B9C65D665CB01603C9FA03BCC4F8292C81F7195FB9453BA15980BF464CE57999547175981ADA808847786ED93460A43627BFE051F15F871B38D02C9CA224AF4F90E0EECCD4B2DE7E7AFC950C2F770AC94ECED9C18B05DA5B7067D6A984624F800982F89E6E0385DB626203F958392B16E9A86FEBCBE65231E8F3EF03AC7DEECD07543C8F8BFE409C3CD0EB88CC39223366CBAEB968EADACEEF97C5C7FD24C3BA4D97C898734C767029BDAFB3B11419CEA7E2E4F913B85333990B5B0F794E86342797D8ABF0F4742895A0D93D03E43DC03722FE38858E00976981C555DB0B708B3089D344851CA1CC42C7F9DB437E6F2750F21FB4243557F70A591354621E43712A047CE2F8951483719CE639A50C951E1E7326A7F089D47E0EE2BA28BEA4204D8478237CE7DE9482FFC1A8B7D3A56D4022D159C5099A69DBA88C71DE62275BE5B1707B4567930C6C3AB019585998F5A1F167737265DF9F1677B9AC771AD5A1E3F460394FDC249918C1911668D7464786293AE2D81D41C27EB0242984F922AD5596BE51C31BEBA3B9C474ECA02A440A2B4E9F4767719A92632285D176FACA6D06DAB7EF77B8FA4BA88168A9802912B3B2B3326FD1CE0A1C960CB5A197143F547B657038140C79B7CCF828D81A9C1D4FBC7F03FBDD2F6EDBB163FE0DB9BB9B68ED9389372F0D767FA985C573461A5F246AD3BA30BB6C90BC205C763677CA8871BA4682939F64180AFA9CACADF68EC838B56E6A71A952C8769299C4CF572B205BAE167DF5FC183553C152085B54FD5173BBBEEB615BE96E737C5C1A52FE068C71C433B512C5FFFF769DC2132F94FD7E1F1ED296A061C63F8BDD401B76E602247A109179EBE7F47E7755A21BAAA0F3E5118A3440CFE071B1A3D998423BEF4BBC48E2C172F1BFF8A5FE505016C9270BA787604D29DB56EC0B953DA5AC54FAF7505FA30516A3F060E3894DEB7C5ED8175493DB7E246D87467C2021C" +}, +{ + "seed": "BC4EF6C46CB18061966CD872D2CB9826B0220173E42F11B451DFF93C0577CDF5", + "pk": "172044F0965950FBA5280238696E84E25AC1A1911FCE85C13FEDCBA82879572CA7CF41D9BC636574F8629CED228AE8F626FEF7328FF39DF8079AB8C24840B1241920B4849E57981DDB978AB5B4437EF87198E91E20AAC7278EF115FEADC43E58F9C0F135E7833D289A4F33738FEE0DCEA8B50DB3F0521C1C3C76987A7C82C0AF3C38C59AE1A888B9397258CC71340AD2886D98207ACA566A30605C4E2E545161A9BCE5488870FE6C48C13B0F47E5661A7409A6C5A568988C9814FD2862FC5B1A690841478F579BA587598558C2C07E988614B7D8628FF00798F57CC1440A0C5163156D490F3A3390D4498881BB67A58964B73826446965AA930537B55A701F4F635A67FE975838B59962DCE9E020C77352929FD327D0106CC0160B3AC5F63252F85C151C889D096C942939ED146A04A44C9F2395CAB0F4399E1F603FD0E3E5D4E7FC1DB51343425D8CAD80076FAB19E3DD33A007903D12CAAC1673FCC06C401E8315D9603CEC9D3C7F0FBDB3D00CC2B23E10DF63A9E4B2D3E0CCFEDDC5DA1C2207A7EA9A0B81D4878A7CABA63E494A67466A401D1988270F6DE08608C304EF6316B74B39BA6EF4D5BF3B66E297B275B81DA2DF24FA1129D88785D558C3F79C235C8243F0FEA80018DC6AB8F375EB17A778E349A87C7B5DE5666D17E41154BAD3C5B00E5B07CBF9F46CCF1759FCA574BE7257F1160F65E9695EFF1FF32F92C386489AC19B3322F30214AE8B008E342E21ED559A035299CB6733CC34B2C2732BC3A3A5B5C5E4370CD940FAB60D9110071DFFC23831D984A446FAB028907A71A423E5D22A073F069A2539195F1CFDDAB21E3B163D2A1A3B16C749C181E3E68EA90E1C2E98D64661E0830BE2E2C967C0EDF86FE3E0021C6B217367C8D0F3CD28B8BDADB49329DE289EB3746BA459AD8B783155FF8C151ED791DBB33BC6EBE60E6985D98AB003F613674890E1FB72CF2FBB11EE24C2C3CE6148A152A4B0F44DD890AE262D53B0A5FB18C748BE880B432CBEC5616FC0AB592B9732B69E6A7C4EC149AE75CD286D133E812D94C262E273D7D6053007DE2609A40109EF7759045C601774DF800222897974438D6CE98884FA79C99B205F00C743452710BFF448AE9CF00401C99BB75DA90E7D99877282D1CD6C9165F372ABACFFB6474E94E7C9DFADC925B7D7F14F2AE043A0B8A75124C2152DC45310FE37036874F466E088FD22384C798A486E1878E784DA4C4BD790C972CF118A64F176FE8A8F6E565EE26A293A4593FC80B685AB615CA5BBA86BC046C413D9937D544E9AF7F23C717796416C56401A0E68043F0ADA7F4C6C9E2C257F36580B2A63F9A6D8961EA4DB955739DAA153152B8D6C2DBACC52B24BE9692DEC785509A23C01E1969C1A6E2225CD3B28F93439174C104A24A6258C813E74C46FD95947D8AF64D93461B6AA50136C799C140097C7D8B24EAEB87BA50E73FCC8DFE9447C228DC6438574E21A23BD082146A0E617A439BF81A9118FF3094B8D794C72EC7ACEE9E60C24E151BFCA9D51CE368904AEE0C608DF45FCA8C2C536A4F0F1038F280D06A15CA43FA836DD54F2A2235C1AB14621F8F57F10ED45814249653F1DE0FDADBDAB1E95FB502DBE85D05047E7CAA8C4C6892B421F2678C8868F852A51F0E5BDF82F776DD1FD40DCC4404DB2CF4625597FD5FB69F10806866334853F0B40FCDCF64A02641226BB7BF4F33CF8449CA1921380091F5255DA7968333EBABC8F9A84F6F8C84041AD2FA7EB9C80F95D874A860ED43980D7597E4789F8A69424DA042351EA9D5B19E5C128F8C5DC505AFAE0956D913193D1453EA24FB0D8AB64584718A61B447EFCE208312C475D2074928DB96FEE1BB910D06DD6CC3F474F4335EEE418BECCA71138A3B435787B4CDF209325865676EE3DAE6AADE50AB8A075C4EC28DAFD308F53028A5944272A9D2A6F199F08FAB81689786F08312EE0AF4AF1FCB0AE0B693627C1254AF89BA8C1F2613B1D5D46C0FA308AF2372248797CF2B3AF9CCDFEE69DC21B09BB390D4B2AFA00EE51B83065ED83E4BF1E60C9CD0B79E5C7EEE4390B28144FD2FFBF03FDC97A4AA39361B9EC50A2AE3BF8C931947DE3675849361608E171BAC9772296BB218DE9505544B50D8BADBE77959219A611325A3F6093549362F07C40FEAEF71B25A9A7F928A001B1180BAD6B4C57BEC8822888EF44BE1EEEC17600FFB00305C877379815BFB09CFD4744B4CAF48DB5E4859A476C198B4118B48AFE8176948E837BB8E54289F995C4900B0E8CEC41A6550876BFD950E5E3F346791C4AD110F6D6C728E5E58EE33E47E57848C7DB6CAC53DE450CBB9E1A679D2C74E0FC8A01E0D2D9AAE47855BD6C1864AF95EC834D229809ED6D3096113C199C156A80D10EEFC8FA3B41BBD23E5BE9E618A379160FFD6578D158B9E04790248737A43FC8999D25D549F67E194D992E63E51DE388654C3B5956626443BEACD55F433AA07B010FAFE318B5763BCBA9FDCC17C88945FA5358FB0DB345EDE62FCAC8D70E59E3E326C41944F26E6E9414AE356F7011AF46C21CF051982F56E1269BA3286BA4AB4142253E75FE6F38EF6E43A708D7F12E18CCBFB88B31B2DC2E3604AE8067A29ECC47BA2A7EAEC61C20A286FF7C2ECFBAFB722120992FFD8DE17DDCF8120A77F5AB9BF66E0ADD0AD97444EC43322950FA02D746D4182D649A6407D5ADEE07D215566860364DF3F554F784F30390B1B4D942148525F7F5B253BBEBF71EFC2DA6944BDDE76BFFF42B", + "sk": "172044F0965950FBA5280238696E84E25AC1A1911FCE85C13FEDCBA82879572C29C756D826F40EBE63389844B3856FD107649DDC3AB99121F9B5F658A25B2BE42D2B0D0AF78FE1A314C90B3A426395967DD3BAE3D5D1029DBDE410038E39BBFAA7E20FE03217656BFA7930D08F4BC65E22EA8FD2054D1CCAEB3071650956921C8818383516546652345845348341062226750117678070784570688375188710570177501547154781433305500441388730375103588405375867617654308866302441600407576855334525682615663181476154841163774257413648636855878347220644304842024115888285246226138068538618624402515488050667520351648113356388605656772231715728008745145588726836117405018742345584424117700018427422172663251250586644286578757304668042003246205338202634818086486123301785675071012243767856118835760130687363568514152268258478147501550424740841243831124168575576778672513600028474115545671848450525620062025268211708511303805861272607274170036384165863223506451565485030532523838221603121287121258746072176713758303632550312407040655188220360357083342722457032075015106782627515768051832500124057822141806717818130204348522116668168451131021286034235335052683755014564880081527078434626244324244510065258144513486042326238540065740028287018174303318278605860268612373017402063473525711430312023244056812545442844100520001864131458455054357850851616055356500742453276075824111777566866705768584830046800321427826811111278128707133771780512815062885416415722083566437861458372806671084678275584322766418754517617566503460016327270648231052836222025133383052468854188306714172464176800512243177780687715053575280724703280270467263745336412286256741502851718788040761600037416853226678306578787264856847665327562026070278647542104163834357747751682268186422832211685401007454675858764182640437071260473443336570828403305146626232784033300107168103446217346137550463081382500454211446123826604371182686275337146882401545335814524011776880487111118424037210424342370242086353287448665040282354413775244701060055434041608100180153521065422144718432411453616532145776130503005125174035851250505745133537151673466754538347058334505557141046336117404485764114821312541582861414507838063640842508474877435530016238621821578103225262201873646007042385113361266433360344375647126042186828638601077581056113382282548525480625002560854472737373661454043588228486646342684336122607353740480842165545624654407006382410124026814128213476402880362710601084361726087002868561358056824863415583231157101337220888846877801156782588770147556680432713113728653328533633450458645337136485473234337704500632556522004715764426011055020800404283451041078541112463436778348678102033630286016710360132806074553635343634681186558240305064843460704424377205042621258166181681515748037366075414103086201016510622332567241352646460736353614088313652185275227160484630482480168165272140537778813161341883025552377040525524854466625216273363852012381002677764353275847134654001617637546856066738302850036854362132481856731425248733072822146707717830226726020857302425511116774864817318644468555074138657504402057020263158005116668616551570538040051435731622821807634486281403783750583701308338531138562104F2255924EC380D004EA05A4303E25E0C1778839405DCF83B74FD2754CF15FDAA6DFA98B2637DCA46E9DADFA726EA4AC153EC7DC0CA42E86F26D03494E5206BD4408DF6E7C499B5919869C447963748E4446F2F0C38AC7DF52BCD04070490846041583216B2D157DE1051B4E55FF75DC6A03BC20895978E3D6FA56F43CC5C7CB645D97C028894A25FD2BA8592BBE355E903162615150CD05416835570F12F5A5C9229AA1A9D7DA3E4D2DA4B3F80979B944A30004EAD2A590228A828C878F5176AC162892F11369811C7A5877771A00C47EDF2473A4C01B760FC2598F505B942C92CE8483CA8A3050D63522B7D669B3BE2C3CB85A3BC7E618935E6B72290E2570F719EFF0FCDA400DB8A7BBCB6BD66BE529B200FFDACA580C0CDE827AE11F2D920D2AB1A55900067A4E3C0464C80F12A7BA1A0F7E8C796BB391995A439EDA1F11ACA434A24BED01DC28CCF448791190EFB864A094D564B3D23005A492D0D2F1D6845472984C8C0822822C9E978F85F9E36E38BCE8FF48E3B485C7D6888BFAD21A453DF01BE666A4BA5AF49A1922BB368EDE947E12D4AE08237912699731F33AAF445C8482DFE2AB567F7B3B256956A800CEA10765BA7F10D5168AE9053C2A341DBB59290437DE92C05A93036857A19207821AD6693DB7552F22229CA392566E4A019BCC21F76AD18EFA19150681B4EEE85D1292AABA0A6792D1514D4A550FAAADE32DA084DBC9AD9384B11D482B10F8FA1858A9E558383D5ECFFD75238DEF0C09C9CBEA14871A310FB813E6792897B5054FA56371DA801EDF8AB1EB122BF4A2F01A1511490A48B8339BA9C6DE477750F5FEB46ABC9E3DADC5C667847030D4A8CB532B89ADABE7F2809AC03C4C88B09313901B6F358B3F9EE0E48428469884974A726EA63B675E51AF76D4ED98F2108CCDE6C639473BB9979AB51DF674D1A65F889B41D9B18DABFB776BCCF4791DBC901A24FD9EBC2FB2C9452589CBB629E681393C019E35F5D6BDCBBCACAC054BA8656DB830F1881FFBCA556B0C6AC73CA5416ABD5AA4816F5BD277DF79D984A06CBE50E4E0AF9B9B150099AFDDBBC907580B09745FD335E006CA7F61934B890BEAF2B94F52F99BEFE94811B2827006042254CD2D8075A0B34FDA4B31E7420DF4D96DB803C0A62FD802952CFD8E1BD3048540D1918E52666E185A21564BFC9CB42AFBA374979B139555A8909DC7BF49C4B4BE6842C3D692C67188C169E10AC30D5C988165C33DFD7DC21269D276F1D3FA22C10C9012A5C8A0C8423C4838A62302094CF3A213C5721087AA6C43E589C3B0FFF04FDF91CAEFD1498FDCEC993ACB4659935D5D90BB5A709704774181FE001EE1E05A9DBA1251115A79173B1C33895EA761F0C5B6DD42BB06E96765D8C242D457A986118FAF8CE1F089EF1CF293518E066410EB04AD8EAFFBD0A59209E2053B7FF0C2E221A6F27CF8F05022BD91B0AAE3C01ED28B41732A4D89CD55F7D491F4E431C40A83752D470AEBB54EF96A630576E8DA05EAF5218F8C09A8D1F3C80A90DC77F15B3B44CCCED6149ECEB7569EB5ADD3873D2A23133BD723F71A2AA7B0D3E2EE1CC75493DC0361477AFD5E6658E9787CF117243CE7C17DD8B4FCAF65B3107AE60CA15A8C5FE7A9745E27EB4674A6B55539B445843A2870AB67BF2AC6F80FDC5B53929447C6C0A4B42DE8BC3CD22783A17B5AB083B4649452913DE9E9B5321E86544BD771ADAD0BBB5417213E3FA62D80E92548A4AA7518E2462B08EB141B98FF44D6B4D7CCB1CEA4552B75AC71C1F4D10CEFB20A6C703559F26899DC2693FB287574455EF767BDAD3D668EA8477B4E5FF4E263C3C7F50151487480D7A6C271412ABB763748E342CAAE563A2B2B421E067B275F709CC452D011B2AF96985275C1CB1945172CD2019388894D7C450D5A1DB83A80771456D9D0CF16FE983086090DDFCECD8BE9F6AE66CA936FBBC0FEEF1F73DD2C19F4ED1F1F2855906A2EE18A100B79F1C3FAC6FBF990982B0139664C08BFCA09277370F2639C5260862AC4C7D03B7F4E48EAB9DF4E9050F67A50FC665B1022B00B0E7635D9462EDF1D602E04808DE10A0C123DC21C4F8BA28A94DC1B1EF5F070F70AD18B6BECC8F9A529903502AA982E974A6D17FA57A52BA878508713E7BBDF882C2FA50FCD0EA27F54E1A5FAC2D4101AB0D6F3FC3251D922AB2E3F90F8D61598EB15C77869B32F96D364B70B609D9630E8EE18D71A4A05A0767DD2632ACE2342F037BCC0D85ABCA48F10E3839A8D727BA55A7ADAAC526F63A60775743E06D61AF9B9C20A3F10DE2B8BCD545C3296274751AEAB66B7A0883CAB9B07D48A24CC567AD135BDFCA30B61C47AE969509F34126EAC2FFA5F2DD08984A23430B7ABE4FB7DCD8A6EDFF1BEC22E7801ACAA855FA5F3DEE21EB1FCBF9204DD2586F6F78F775B26856ECAE89C80EC645372C7B21036591CC20CCC96F92E16E1C36D4A0D80F8ADF3D8BA6D2536FA67A5F9FCFFCF291C29200F9592D3EA56F85ADB431D481F4297085FFDB8F669E523EB96BEF366DE05D2DC8FC0485977FFBD719DC5CBF4BFCB3CD191AF4BAE90696DBF52BB25D164DE472A64C57002D434A1C29BD379D72A4CD86C1380BB8132BAE06620DC219C8E35D0B042CAE54B32358F68554E34D55275CBE89E9526D5285818D5D9907B52AA21F34ADA8C74576C46CF25794CDFE19AB419AC44F3B05D0A40068945F7564B17012499D0602B4A1774002D18E4F7DFCAF3E6CB035776704457632913826B64C71018C4949E7B97C4A31E042CAD3D25AC3B47E540D3D0DC6491BC021FC56328E6300462D8820EF3D9BF7A40FE779218A0CEE30390A183F571CC592FEF2ABDBD47B3A72F1E779815C0787FAD9A4D5F817C20E1CFC2799783F09DCBABC4A4692538F5B8A8F71172A738F947B899FD431B6C82673F78FB88D528649E8FC794A1D3A89E7C3DB3075C2C3AD5CA00539BEB10C4FD6169A05836A3FD524405BACE465D0AAAE4CE9DF3836701CD7914382C27E73CAA08F1B252A4B7EAEC1C861CFB443B28ACC5FFD0058E0E9BA4864979C7EE56A42E0070CD18B74340D92A83DB40276B1AB57F84B6ABFCDCAFE227C08415700B6163B7D57EF45FFD23BC0DCE56F1CA8FB58E52BA415A58B87A46078F44EC0EEC9482E4E032D61512BA21ACEFA846B408856D64A1D868EA98CF4C518EF6D0F9CADF76F13FF1A90EF4B42B49ACC0FB61EBA9D88A51D6F9143C3713C91D623D173EC0BE6DCD11B02B2B7EF08ADCC1C7A78E262441D6D919E3E3AAB0B61C7ACD6C5EF95908FB789D44EB01E505F9709CA1D47C9AFBCD88806038DA554B6CD3CDBF274A8E0292D9B451ABE590D7F7B8B32EBC60848AA5C0528A8DD435498EE46AA7E89F72AEE8D96A590B5FA434FA4159E190C4A668912C80803CADBA8970D57EBB2FA73828F955754F81F2A3B5144F891F886E74D3F2604B0E6A2537F491B786A50EDBC03CC756C89D59C7A29E372AAB728FCD082A872CFF573D0E8D0C6C60BCA9B21627651BFEF05975499BBC05B2" +}, +{ + "seed": "135DF872744277E90019BD1E904DCBED63741D863E82388B61A2B069E509B25A", + "pk": "60F19C2888D3332957F177B055ED15294B33E36071D56CAFB5318FED1C8C590596037B30546386F06E9FDAB6AE2E88BD93633E9C27EE046CF437994D9FCEA1BCBED601082DA3973209A408440CDEC12AF383AA23DB274E7393884CB7AA4672AFCE26A95511BA62CF43EBFC7945800D79CFEBE0C41FCFB7A7F1B11DBD5D530BA969A56399E76EF1E8244DD225204AA140C71C90400D0E6A99593B346BBE05EAF414AE396F169911754E3A631D9C28644319BD4BA952B7E935AEBBF0AC81326A8FD03EED551623BECFA9637898091FCF12FFDA8CC2636C1699909804FBC6050617F4E0454A45DBEDF647FCFC47F678730DE0FC9B7793B88125DD22DA136105A23FCD1E7B581CC9C8D62204472BC2A8F8690543812A157AB1D3F7C3A8380BF7724ED623B938318CC45D1D8B907C460E1516192BE22678A7B508477EC3FFE1C2F085146CB921012010F82AF16ED8E8A4185D4C77A21C1A6DD6B56E0721CA1F701B92B04C9429C460E04C02E07345D6305205E21DAD975783669E4EC89521FAB64BDB3A31EB76B18C33F81CF39D5AA9BF1B19F819EFCD38AA04EA3DE374A6E155F8457768DCC6B7E14D2700AC4248710D527A60CDA5A2DC3CBD0E74EB82625A1642CB80B7310A230392148A4812CA7A64EC7DC9ACAB74C592A1CEBD7E4DE2B05953B3500AE2586B4357A511340821EAB6C8F2DFE6576487C93C47B4B2B76EE0C96552EB31A5C4415EC909F74C5BA9513A10EA8B54ED292D8D76AA92CC131BE5F3FB10DE22D5480D88499EDF7C3B265B96DD9CD13A8964C6D642A10371D69F6F1948C203AF1E321CE53C48AE77A06E2DE4B4CC942E9563E94B75BF4284E7EBA1BB3850CFC2F1E9AC42D7AFD4BF6D7F99E621EF640AD2BEBA85DB0721CF550AB3E2BB3346B36C9D13E34D7C9FF5FAC1EC257DC2B38122855C5A762CDB08FC3DE4D546F2FAD9B51A3F6D5D11AEC965BF60B834175DC3DE02431B2A82C528689BA90C735DDAD72BD930939EA04E750E33BD3F94F47D4F39A60E0EC2B30BE74CF49CA04B100F470B8AC60BC47522064F540F9A5D0F57D19452C02F0BD526D17E86942DBFEF921D82F343835288974D4DAFF657D0D53A08D1530ED85A50F8683A98D98B402C67FE58879687A39F05192A082C830365D577EF0545D4D1BC183A2EF070D817CA4CB941562B4487B4BDCCABE417567C6C5DFBD09F512E34CF996A3C73A5D2E1ADF8EE94B255ED8EAB9FFC7CC5B1CD8D213474BB1213E47F6F7B040C77517C58CBB8E77F5165C590691971EB4587FA441410BBDA483AE2E92000D2C96869EA239131039B672D125034926D0B31CC481EF36CDECEC45E3258791C520A185249ADC4E1C946A9214FA6D29F264A07FC039737DC0A4B0FAECB74A8B539AD875C9BB2D6EED2DEE6B69CE2E12E1E92F3F0EADA8A64AF5933BEF893C0D9AB0E4A19B18A9EB56F7079D7D730C1695BEAE4821CBB97E3D5752BBEBF6666194695BE5E1FAD0ABFCC280FDFA1FE2BB45F371F642C93EBA3A0D7FA69FCD30AF866B1360A8FF6707C54504EAF05AF44D2F41670033460009A8C7156B24EAFDB2BEF3A2FBA97AB039518EB8950BB8E9D07D5138AF47F43058EFD57AC450E7CAF54C275121BDAC4C2AA70CF6422F7910B01D058CB4806D28C55C69FA3FE7801DBB2C62BFB86D7A0925136C4055FFDEA8F47FE22332F09A580CE44DA4311CF51EA68495D69079A5C9C8FB442E7681A021A32EB88AE12EBD16F91753C54A56435E5F244F0C2CA4103DFF9AEE7E780FB423BF148C9026EC9E649AA80CFC411310C3440B5AB6FA3605867751790EA9A54E053C81970B3CC5CFF5FC000261616524768F7E06034B55053EF0B7B24C52ABA0F4A40C56E7BB72857C893AA25BF97761819A2EC8B9319C8B8F55A8042879795D06971EDB9A63D85D2E5839CB704D66497508A8628AD4A7B8C862F965DACC4D9BE011EEB5C46CDB6A2AC03C6AB7C72DA20889E6EE48B9D6E84E2ECDBCABA5BBB7CEF9DDB7B97286185283809E6D6AEE4189AC17BA586A274E5DA9FDF56C0C86ABBEE67525D27B15E08CB949F8F38FCA263271B5BCF92121269EF692AD7DD182B917E50DEDAB1B8C5A42621DBFC682B2767A4C91E1DE942A660D3D1F4E998FAF32F652C68C09D4C6D278FA8DE215F6EDF6E254AC8E9A8A09DC43E93ADBBF8D9A6D5BDFF52A0F9A57CBF07B2F1C2690B2D4D1B92012A0062CB0D39C5F51E1357A3A9F2B3F063A194BD68D09412DFBEBB39A19E0B6994392F9925D1C7554456D0D633549616D56536B4F6AE1F0C6F2991899DA65BC1B8F2913F05B88ACBBAE77F7BE27302EB04789E605724884525219327477E4BFBC964207408DF867A12C8554216DC7F0EDE2A74F3450F09719965593AB620804F6160D493437BF2647B17AD8E9087FB9ECAC796362B20C47AA45F5F0EE2A3320D844E78AE6DF61597E05B25B4EB804161678C180C70978B5DB16F0532C524FE4644507A178A31D84BC823241390F2906E2A5007D9364CCD5E332E65595488F65CE00C15C33B5A7E0D2AEB23BF53C953858130287B021AF19FD83ACEC0160129166B7CD39305B32029423C9EB7C1C86FBAEB08302E8E98783DDC23DC2C88A916F061A17A436208D565B2F29D31F38881CA031EE00FFDBA53D5F27B1CFBF8959138D3935AA2340CF37F8F1519849A087DA12C3D0E025E33EDC19022911C7F78F49B1D3FEE3F87250E38EAB61B2E607173F880B9534B370ADEB83BF9AFF3CAFD9BEA06878E66DABF", + "sk": "60F19C2888D3332957F177B055ED15294B33E36071D56CAFB5318FED1C8C59059776BF0982F58C5BF8760131D784CBC59C83506E9C37073A735B862A90A1351FFDF2CBF21F6C592F36C142E7372741317808CED0E64E75242A8CA167DDA0931C12067EE31EC05CB5D76762ACCB588D97F885DA913EDB932FD9EFC597E31C8FE7483732182417476267842312383478154743246465608704018564385702145640032387477480015217732076670716666467833626011865105780352472546415744556138516780087816437287418113876478510168466361118214334241670114075453510780284573135100347550388577701188017176163033247283666855118737431883475501656605683610738528276807102471644770484440320781171351481611644187385155343613247758636820584746160088566426010428203244046441730233448316034754248183573334761217257455360176028465830788381643240768766280464653231063260878410470574307373316874208716171123303817623837725475353711451040420210541882572050248682047242423200011856287765407446474167417575752066354152702022122578670844232737845641088335275415401011387716361864551521567112453813325131754308472287050122011151372646414852012325538044287833806555000572835360174353656765502258874142856141381211338024426087777686324317468856134168305145721077050524706654710068461234873625832256211720256300534682510444126505380610114274108128652105757116102101610027146353055681174423780414631814766604742016505380053811753008368165204378032838721314303164347700288275788623102537480584471452714476335173848668614437618187610552480265653710132536135642551212270583780386871528154403781704407403277421066170314475687213210526636380221070102627478732365161434256612014823302523866118448752603774022243324574346365536516014470447434451828251230234262820774158573160724435457606050617288264125822135802242853578238058441418124730762135158784477176721846631804675433384776456172658806162800784657603315350128042358401711706737852082571514521858816256047683653501611414232632543716484572216533733465564646410787800711631308540481036537622137273362580821460630373846686536351643184220531260100470718632847612280013042337373536221652732260400271713866033384882613587553853154040621820351770001324430483350066467206672766355051513856777165413015284625031416666867715458402036710374272215323506650536575663454041153038824213555822740826103470534308818637830853622438247348816776304148463123075133283488484062036787547713120366474014578455581134567708113412242521388135757240176263555784173124460318616660500408413380503574433416272072522707577581862022240481421307758281540872888122804243684675014071523047532418622155330485380820231333301134246558278003026512810705606767804263084124781578616637246768362221215416245532858754872782888871325412358451314080488111481442478110611135071715543656513067667176448838086323467381317537420507301435855664835265066015501051842518277816662454485756187478822648427083443138015222802362876282417008521324004255156877406860744830428285413554573067703281106187011234434728360065728454415716563261413046158800686358771553030874538582228413307033286145140814246244015884017253404030718260532684216764132301055016015132773621625305843836355723257172476645626154671D230BFB6EDE64D1F4CE65CDFCBA4F8B6167127DAA9CD1A3251479BF6BFD0CBEA010D6D3EECD927DD933C6784BE30834AD1DB0AD5B2E416D86836615051F434DB116D8388EA6DD7F7BCBF7D28A72489CA067DBD3F478010F9E1CE759D5B1AF7A5FAF197533023B7C05E835256D849C1CEBEBF17844F39E36D0ECAC807874050C8456855F01EC40AEAB3884D384E2A12F0EDA8AA841E8E0B1C5BF11E2BB6A29E8444BD802C1F460405AA21E7717EF90739E3F7661BC8F0EF1C66208E66DA244292995889158F64819551F4174038EF3C2D60B98EEB43C53BA96056542A215055432FAFBE0E7A812F0F685E24E66ADD8CF09DAEB92445DC2FBB144176866DDFD663238E81F668AD55B4411AACDC07811BA48163C49056F7B442BE8533D9E3A2B83A057F6A996B6267CBB9433FC85A4DDDA41806DD8E067765C29721E6D5A1BB34A80333C199E00C2E3563F9F77185CD100B4A2FF5F1F97ADE70F1928CF198E1298E35161CDCCA9B9A832F4413B732FCD271FAAFBACBBC9664C43FB4C24206365E7FE7C5E30D12FFFF90A3064BCCD44BC8C59735CB95CE2A91D88C0A635E419FD0BAC0270800109644EEA88C36FD78393B42384CA9B58EF61B3BA9EA7EBE3FCEE044054FC1BD24FA70C71243DA12B338AC7461C39661CA4F2C7E9529AE53937800BEA814BBB2324AD2C05785920AF96834B994FFA29F8674F30E2DC5E502E74296E8B5B731B53DB9AFC4497C2A7856D23E28AE1E78D957BC73E8EFA29AB3664A3FC27F5D9BAD4317EE47EF6CD1B6077236600C2767F7BE560AB260D07C6FE184F7B9D928242D269C655D7B896B859CF410C2C61BD5E6E5C34531EFC22ABD9B02E21887BF37AEC7B4B7B1C7AC9BAFD050CE93E6586916BA766F4AE1EA035B0CEEE4BC362CF87AAF83577427C8F76BF36D631B72ACA5575F48D293F451F66F11FCE6F725C6D2DAD3C7045C2CD74875E122F14B3D988E207FAFC198CEC59FBBCE70C6AB11E686B5775CF08673DDBBD296AC617326D3BD9B1DAEE12896671CB0546A7F6A74ED11456EFF0A74391136A5866F61A5D3FC6498CAA1ABADEB900A0C9C36931A4A25987F25E31E2A72388D84CA70102409168C348AEB13833BAD91281CFF1D4C76A4D2F0747448E8F5525763543E2731C97D506F826232C55C1B85C661F5FC726EF9C2E8667D9FCE4D3386081657629CC1658D3BA4559CC0F0290215BCBA010CFA280B87D23BC79FA094B3CB4A08157A69E3BB41B009DD5354D2EF5C0C617A72853533A24322AC5C85BE8C31C3C8BE7A71065978006D5867A3968DB01AF0165B12A557D3B0BF8B44321F948F367A5E3A5BFC9F190F26FB35527DE4C06EC155607E377789E2203FF48A04F837BBAE45E2E4A4F049E181E2249F59F38B151C3F66765130DCEAD1436BDAAB9A4B813E6B2D418CCEDC699F126321E429CE9837B9D00FD9413AE3EFD9649AD2F58D0BE9A1682D9105769C111886B68EB0DBB6B16AB16C9578D3952D24C03C8E6E43347121FC1510952228FE16CF87EFC1B0E6CD47A01752DF9AC81479C7434EAADB137433256ECD2D9DFF8C49A68E758AC3594A0C06B84A19393935C4F6A894B0E90D7166F2F65734568CB3F837A406A8CAEBF9922E5327D5FA2D2BB98D63EB7359E75FB836F5D392B25D32997DADF301F8154F320DCF941D309C78D09722E17AF06055EC65F2F9DD341BE705134C83BA04DD32064CAA6ED894EDE02B81CB33FD86056B40F303CC4B236EED3BE34D4555C8F51E8BC20866EC97BBD57FB754956A1E52F371E4287886AF8152347589BCE15267BC603E9E707A83D14B0AEBA6E94205BFD62F743CC4D6C401FE1E1CA130872083A039F7D3B52CAC89A56EECF96BB3244C4CAEAB615E2A45814ED80A153EBE5BE67DE0F87EC8D48A404120D2DFE26395AB2FAD1A1194C89A0AAFE42EA15B64AC806AF8BAE70E770E73491E55122303D0F0A258086033E6716E58F18519C13B13E07B4567B8057C06F68C6650BD7225DE1F8AFC79C0159CE5161652A10BED61895AC2495777CB165912C0E24331A21B6F4604E8D6F689E06A1EE856968E419FD01E8E36BD3A071F21F9B4B778859C0C524DEA1E1F8EFF0D92DE8EC7BF8FC5DA396046CE9966C198B0B1968EF2776C43278A0416DC2904167CE9DABDE13D82676A8AA9579564356774AE62F4A7D86B43AEE8EC84B3FD55445F1C84DFFBE038C0D5899AC1BFA5CC258AFA4FEC802737F6CAA0BCDA4143729F233E4AFCA6B243CD21B44906A5EF8F2A45698E91C23B0F3BD7BB03548BBDEFE24900B400F5DF27822C2434471F460DF2118108AC3AD2D7CF5D5D824014546D29D4FC258088B2EE8601729BE1F2C8509446FA37FEA4BA7D057216A14758C88E75D7D72B625C50B18BAED848BC23B28B775007963C010B1710243A455CF3F4F2D90363D4E50339B990C449ED1A26E95F997CEEEAEF283FC98D59C172F0CC9127B564AA488E3B18330EB1F945EE48475FF1968E0C2DAEF0F582EB5D0184A983159A894687674ACCCA811C570B5452492E8C79C21F8373E379C5B189948ADA6099A3465003F8A1A3F8D89565A09189E8A9F86186EB786C4491C728542ACB5B333B0FE345FFBCD9E0069619B04502A06ECBA06D6C3D9BE70025346A4E879C55BF000B9FB374716DD20F41B91BE43059AC0EE454D11BE599FDE39386EB72B6E195365D061DCB06AFF60543117F7742EC0B0402F398FF1E3AA7777400108C2230F266F27D3BC29C547FCD0C57EC098CECBBD10E12CBC26BF290909A62E6D359A823EDFB728E714ED8EA40ED58FEBFE6CE2316D8F294CE3C9EA68F08091659A99B3C12F4249D931ABD465F8BA18205F57C46BEBB5F245D1F9F29C64F3791292A8F9DF9C6473418AE055351962795185DD60555BC277C8A7155172408F0B99B78D43896CF17755FF5200A7DAF16112A93BDAED173A2BD934021C22F25AC6B761FEC2B992BD8E28F1246670472AC2A2A76B2E15F336F211E99912520728FA86C130951A26D456C47D5C51B8322208A0944704A815975DE32074DDEADF567B9346DF1FB066F687354828D5BD41A0E3FD2C38EBBA74010BE647EB75E866CAC2C8289B3A097832EF0B2FED44F6AF239A7556027C41E7CD42B18DDF709E75E94360C0B404060CE057FBCF1B6100E2D9516A91B7F7546305A447C2647F76F588ABD7EF3CD823CB6042B59160B8BB1F14BE18AF1134C8959A84E25C1B5C22D1BAA419D547107791E1CFEFDD112C9488A9A57DDA15FBF312DB3A122F70BCC5BEAEEFC35732070465309D2888B65848DC47464AD50ACBF88DA25384240BF2E3D4FF2EE4B59E85FC47F7127814EA1C014B127B1F09BF09FFAFE7E748EA504B6EFD20180329582ABE04EBE4E20C7C508C32B2DCA0BE8E01E80F21693EBF250E1FE7237BF04C58E5EC60116BE1E6BE90655D5EECDA10D59858A678A7B137F82618A913096D3C479145D361FAF0E926F2D9C87CADF302A950DAA88B4F9CDFA66B1D111C3C9B80259187E78B2C0DC3ED3D6DAADAEDBD1865" +}, +{ + "seed": "AEF72BA72607B5D3E49C579752BE9CB9FA67A01B2E8B654EE92177BBA596066E", + "pk": "A5BDF0F8455F85CC9F37DA908E52A9F70DAC2C1473306439E4F3051E897673F5CF4217CB02FC3BBE5E08E9A257D0B22F3CE939D6E809C88560A0847C8A51AD8C6FF596A8708CDA9CE65190FFE3D24B457FB29C88F670803DBDF7042F8A07A2CECF2E8711F639E561B84AA9357A6C403174E942A05919B4533E28BA1F4A9724C1455A82FAD68762CA8EA8EE25A024961D1991B2E4A5587D2F48A61B00B348B059A44A41E44498DBCB2026AB577083A10EC5A527E27047C3ADABDE815555D16CD092ED86C26863145C296C9523DE0286328BCC16FFC27D7A2E5BED590D20B77B51FC2D5646DDCD385F79D03E63AC83B7522F01FD1A9B5A7307B5D6783006E935465DA875DF5D53CE648B0F570F5646E607CA5D226E2FE06451CEF35E687056AABFA25834F69275634D2E223B2814848EBA21EDDD175C895F66EDEB9A59F4D303C873236FDB5C5551DAC07F5693117C93827201B56109C398A490136D67501EEFE48BA2DCC0E0DCA3E7BB099182AEB71A5833A258985035D8B19AFC76B622DAF4F5A441387F069A6CA00F4077D22E666E32A9953B34384B950FF2A9F4759AAFFC066BAB54D6988CFB35636F2568E76ECD41BC6823054C733DCEE6AB65870DE742A4D61AF0FCD5ABD5210C40463FAA984A27C9E731DD994657274E3FCF55C436B8A956FE21203CBCE1EC1BA965A8E43F5580F9AA4DBBDAB65564DBCD86B1B28FE0033CE376049223B08BBBAC9857B5104CECC681A8003C40295B69E0EA73ACD0252DFF155AD4340BB95B9DDB0AFC97F2CCA3FC70052B2FF327CB4FE8AA6BDA893BA30D2BE86B2430F7A99DFE1634B98AB67327D50C366369AFACB1C842FFD41273DB7510E07CCF8C062AEE290095B3ED299EEEBC585C2BF2DCCC9FC3FED5CB80BCF8A6576E67EE732979D3D82D0619AA0F0280CDF50601AB7A6E3E3A0F62F24A704E6252293D0F2C343B2CBB4F3E988B6309A287EB4A3943290B9C82F6EA93768DFE50A8D51313443CE3444E4B99790964B7282C49CB98CE2C28C254B0D508677DC2E2F44DE41EA0428A5EBC125E7CFB3034247BFFEB234DF2910B7DBA0F4DF808C1EDB42E9234A1BE15735F0928F05880EF8FF25E7C03393A2EDEE2828B374AE0BAF1A63D266FEE71DB913FE4B404DE35E28E1584AE938F9578C5B06799DA2EC43803980F77850F4A557892DAFA4708EB4D933510770C40DB4DCB7BA4F8D9138D78A2799662990FBD6142CEE38B7CFE9F7D39ED50B4327FF111ECA523714A06C642AFB2406299362D16472CC49B9D01A6E0A38880B447F3903AEEFBF5A920145143D559E623CCD860432121B5B0161A43D8FB8280AC4E7320A412E36053F78FEB287EF0AF32E1FE5A1C1E9BDB6497E7A4EF9FB4F0A2A9983F40F66C5DB8AD972E422E2098CDA4955812C09E649842636B6CBEB0E29A50260078E3505B1235471DF74E2E737588078D8641AF48C1AC39CF05632F80C99836B0935CC15FD80F3FE9E941E68C3FDDC8DF1CD641722288A20EFCBB09620F0376414F34E380E13CB09B43B105B3A22A4F54518CF28CD644830BCB267D18793542026A1258F8E3EC4920FF798152E054444183CA5621222006AA18DD9E42619BFE90F35634967CBED9DE93722D38D8011A5EFCA178C6314A43F12798F150FA2AA9BC9C2BAEA30008BD61E1BF257144B67A704BD43823B3E06F6E251819CEEB264383CAEB49B1D7180AEB56DCC735A09C0EACB926BB4407F4AD016346BB9F68624087A22F50D5EF91521F3CA8A68906E56761C37A5F001B0B2120CE86D1FDD86A2F795086C1E63300EF953DC5F94264350762780F703F89100653A83F9E80E3327D6886F85A6FB4A68C22C114DD54DA899008347F08C7ED6064DA26DFC8F9250DB0D33263BB5ABC997A949D845AF963F3CD51CF4240B6C2EF3AF3D0BFA3938BB5F48F0562A06CA59B662D726317A8C02AB28395C3EF958E06816CA972792C6FBC051123C1564E65C9FE5E13A8E91621773694FCCFD4692D4D35A27F6E2412B49804CE472672692C636F3DC22A2A6FC050CF9895AF34A33851AC37AC2E7A2E42D401088F119BE6D66BF6AD4B7C9BE4B65937C34137924B5F9B789D93F598C5162C500C09E8EC2E4CCB47CFD919FEE8671239A3159534FFD44711F515286F4C5F043C02B94727832F41862ABAD03EB0A2DAFD8CA9B766AE254B1568B75CB65D8491B488DFFBC6E5DAAB4F6B2910A18B0139AF77F10137026116DB1C75BB206CEA39C2EEE4A760A37187DCFC9A3BFB67A7688190D5B408B8F93404F22BCE4DCB1EB2443EA95A12495F9881E303AB7491056C1BEF4EE4DE242FB2ABA8FFC4210D9290A291549804F308D1F1E79453B8EEF08B7E94F306C9350263C2C3FDF9288E6B77B74308548BCDCAACD999B72998E6F43B037AA19746C92964EC170D8F4C45C9E276CFB38090287A1FEA8C2A3DE69F246F66BD1EE6D99BEF25D817136AFF0518584C04103EB4BAA1B0C13A09F53A5470CA0D3BF811F78524F8BB1059A6AE908959015917EE1D6C458067B0238125ECCC3870465FC8DD6FCE667DAC35C3395F2F99D9412478F69286176F842C12480AC3C1F10E17327FF41A9C9F3CA25B1DF71746E38D495AA39278EDF66784200E41939ACA3A5C6B30133FD34648CBE9E05D7F8203C4ED349F61B06898DFB59472A50C5065FFA3EBDCEA251B37FDDBBB1638B7B7ABC392DEFD6D8C2A623B5F8C6B2AF21837E4DBFA31049262A89C6DFB0DF74D4236C231CAB14926955BD861", + "sk": "A5BDF0F8455F85CC9F37DA908E52A9F70DAC2C1473306439E4F3051E897673F586D92ED7533389C0202DF540751374583C97B825C4370216AF4AB36DDE304D43D0DACA16C3F5087918EB0AC74D767F421FE3D1FBC7EAA3AACCBD5CB5D09F333CF4B78F53C71C613696DCF9DCAEF19B3C1EE2EFAF0D828521A6CE01FFA7F61A9348527342744071064226038054116606320141710221271257486326667037121338804027786413333762444565247120260711112481538554528818355348570835703121724850217680085831247330511727221071532777537181252433162511266101870334182868555603545033287523215207404240325534605842331807636112112578123748213488427847140378435253062845364733136513038331863665164167881816537665065848863257260565026575136330876105673463618643727206285030703671806436818322112274163527184354571804314504110461483305276281527585556577604221866560252247227633024375431035511576001826578516576032642038878266403868054841663872067833221181722456668288121320355140013335216064378035186542241363324612723361344715333431546685723672037350475440828822807350518723244126165140441743684004218174044766245273324152220377505024108077250427538553813160114380427476282474087652860170448374247256182540047212386666433380053013860147850648461451277375447570165767818683367627182818503143056367684131733603212447465727282433537555073853150367373683784851317615160568487055012186553755658442635833444503161210303854541265435850086145313831714057147057120854520605228538737665130427538038232223511606506354232283180315487066067657113311376130525682787352874263703354678684763224515801735756766354734254556702053117703010838153428847256422882168222781354461343605223116617002218761072342227774472342364510245075075620557536146654153377441306448752117273127761641170377382766582167256065853886542021656228353632167205880115560215680560306250271500428858201477207883872516256244502862366650053734802237606638246801357641266043847685428523576470862427772605087355417711178011230254130776185056386880131707363610348377857813822161177008735870862408816363434033522876874245827032130687514032517084000404550331071880041411855515353347350748833163660475436163376714460516374334807032470377016148566161642212524742565118144158720586251383718220750427038855211255848338323237278850416582248665388024224073714504355652603153613411853445800308877122483607514485078628638685574852023328770115826675755280543602581333212557321868322175661562521048051805784217422803480451341517247206525267651220578854840124507450130330783180120225057375467878261257470561528834570641813282421264533224140164101541355026886165283383701241282521170736675535341222832655883108544384278163414862621416360817830726530353375153418874861316345662582058367316632462543274165056545780126454850320726117724140462523727278438211532634765078536860488641558502057617183425565211328306367418664731407825108631866633714182740052163310713218483574715351876351327521183865501355706182848758085863563015436623450348571177625576370888877313167468486714351112267202247833152524060633413850751063367135630834183838550563386607380546701865460634035501871746162676710175335260356668310562162041187655378322137251758003287138288249A1A4563679824EA12950B80F31653B5EF7BEBC201E938EAE950102A93B46E11F5123313957EBACE11D440BDC9459D1B9CDD345863D81F2FED1C4B534D0F17E0908F1FDE10C037FAFAC1E0FC865B74D15D41E1211EC7AA0EF69F87FD0F8F9CC42B0E0E827570776232D4ED86A84D1F7A2201B2F29B6BEC81A3238DA71A1AC6667AF0A3F35124133C5F3F10D7F5FAEB27DDFE82B59C85D4EE7340F84787D4EA738D16861E4E66238C4873957D0EDDCA68F884B726E10AF47E431DC904EE034F9F491208466EB6168FE6B399E5ED34E118A77DEA15BFD11DE8A531C8C25F4F73F8A35282E32094F291308B6EF60DBF7B54CA3B0F5386AD179DA593BB9C2B7A2461C2B7C1713231A1769F03FC1B2C7C152AF80809453EB6E97C8B4149A04626C93E150EF3DCC298C13A439CDB871893CF3456B9A59FDCDD6E5A873BAE7E5C778C99605EC7B01339D8882DEE88B7DE879BF3AC89910C00F99EF2E8DCFA2EB7D8FA6B5555685EA2B5350BF55633C0AEB1F244C1026E62C82A5685757D3446B756D9ACF6C049A18EC4C9359B4DB246D9B455016821EF4C598BBF834DD6FF82A494531BB5E0A533F225D068A1AC496AE8D28F08DA00DCB8209BD40CBB0CFED32241FFA1C33275A2565D1CC24D3A6BAAB228C2D8764680A105A834B36C18A9D522D0A25EB34FE00B32193DC9F976B0A23CB220A6799E4D596EFD98A71EBE0454E25E93E233191D14A78B5DB29D4CFA2435CE41B13404A2324517F0EFD5B59F714889C66DB5327045DA45C38E3DC4D8AA433E1962F9313AECA58B3122B437F0CA17B09414EFD52EEC5E2F94DE8CA5079CC79F1A11E7F968844F8DA1CCA85D9AF2759A3FD75A9EC44BE6857B403C88E69F1A9A66764CE7F92E622D963E8ADE4BD4973D739FB946ECEDD9BD829D5BCF02FB87E25DECD98C8EC507EB5FCEE4A0AAF62970A6C4F4D66FB4BF7FF735391A27DF24B848E93B4E1CEDC8B77497A8EDB73A3C9AA8B4EBD9443235261C2DCBDF5606DE190C35AD76494DDA71E9DD8EB70DEB2649CB944A60F50F38C4B6EC1E64E12F029D1E0A2D619E4E783BE3AE5A06FC4A355511F177411CBE64395AF69F744773572B5073FC1BEB8797D0508204B3658EF87C62D94EB85E991D2C7A4CD02DF7D64B6587102D4FA321D961AF7116CB37E62CF3B1AD0C3FFD9D9401F175A359D69DB9E86EE9A4255F1574BFBE38A18E94BF0536125045C20921D10CEFF864A3A583C5CFAEDC1151CDBC4C31043A8763AB3714F942DA758D352CB03AD534EBC81764D21285B10E0E0AFC28CFE72A84103444A2D1DD6CE6D7964FCB66242F08B36623800E34510DA71F518C941EB8452C1BD29D0F6A575C7551D2A208CB579F05E9F94AAB26AFE4C7484E86CD05B41BC669B7A1EA0DB9E9F581528D5C29B0A684766E7881E46625AF5D0A37BA1D50BF3F90FE08697B20C7A205362943282350E1747A7B91CD9D0358F2101F5759D81533FF5B83190BFF33443F6C73A0D3CA0BABCB4A7DE4832DD9DCF2A144690F6DAF40431C7F9FE41944E4D168474700C8AF6EE39668FE2ADA2F8B9F015314EB7C230EC3C21229EB886D37F17F9457233C055A7F4504999521EF38CC8B4183088B52CD9A8246107C46108586D8AC5EBACA4072D8639AEA5743086B46553E10A6803BD86B494CE06D7FE6AEA812946D6B939A315F7E200A7DFE2571CAAF009C909FCB75938E421CD542507F50DE26F813B41D10E67E4B5756E8412E272715764C1C097D27434E2D2CCCE49E6A4477CE65008EBB1365865ABD4F709129E7E045368E8DDB80ECB4180EBF5705F53551E2250978C21874FCE6069D4A5A51C2DD54A2D61E189AAC9247DDD58DFAE54EDB816A5895959E1BDE574B0316363658B71CA5A3B859212799DC9D1B1EE75A8163D16263D7024D03F76FFAA106E7CABDA18B5F943F39B420486E45FEA2714914421C79D4315BDADC6FC2A77DA76D2099C28D59D865850152588F33837A06E33323263ADFC75705C1EF5E0E6703999E3DAFB419BA86ED5CE3486D6655D6E320C3D43D98E4FCCD31E28CC2F51B524414562AE41647F16EF6AA763E354952B44AD5E5576BAC79C2DDA9BC2361A08BC24697F6A129CE30999A3453B3ADDA3410DEC30CA11EDF278B47A6E6F92B0C6670E118EF97138C2D6BFAC34B20B11175260994BD93D41FD44B7BBD5EED310B3C13880D095B1A73887288BABA953ED922A46A42450D377DC23495707A35510EA3D0AB741BE55E1107A439F136BC7E1D03B75E733FD6AA3236F379C7825FD5401D1217003C11C422CA7DB8A8AE40CDFFA642F76544CFF87385E7E45FAE6E68347D45A2E32FE15A25DB579642B488C05D3BBF597DE46CE67DB5EED0EC59641ED85281D5E2CAFB15A43744B3B60DBBCEE50990DA608DA0652AAE2EB1CABABB36FE42C414DB0689112A37DF8CBE831B236967497F4FA17AC452B2BD8935211FB423D415FA916058E45CF7AD447F3F19660EA9A069C447D14603B23BE2C6722A581661798A1D9348EE1CBE235243645B20A6F0584621F460D3BAB447520372F041684942C76C7CB510DE9258BCAEFEF8FF3B7C3AAB4D9C4F3FDC9952F1E4B3A232EBBA94FEA8DFE75500FD89221B7339A3C61CF0B44CC36CC17E5339137A5FC7265438D76ADBA37465E9E30E858B5C9B4B162B4769EE7EC9A2D2090B1D5CF77A86FDF7F7AB76B15988703454FF678AFF7E7D221F2A3A5E984739C214BED903A842B4DA9F29E26E820A2D70EF0217C544A930A8C2150FF41D6F1450DF4BA0C81AD2F6AEB54BD5F82612B11DD9717112F424DF4C3F27006B37A51407B133110D0C827640468B287B8D41ABB6693D7A041892DDE1D494CE08ED493C59C68E207A281F953EDD91B978D31F459DDD6BB9AC2CE212C5BF3B15457287E4B95347A1AFB976733BC848A709900A08FCAA732F6558BD818920509933E915EC76CFAB7EE55821C56804FF8322C246CD2D14B66241D0D88F1670124B5E48FC5744E4DF74F5EA51CE9FEE5C5ABD4523D88B98B12E0BEF3EC7CA3AAE48B7C3C311A8840D593F74134CC0D4D6244051AE18C44E5308B3A997711735B438AA4D2409481DA436A84664D64BE7F941DCA6C4DB2724E7F1FED95D4FCAB4960ECCF7A478B6F6AB5C7674E01867D6DCD3BBA6D51747C19B94A4F0039226B658BEE299F23388FB5E7A71493EF7C2016754D020825616B2F4810FC765A67876F979E73DFF831F0ABE6569AFEB611CA67997253730B44979FFBF105F0A06D6FB360BE8877C111D6D0FDB5D2578BD95B34F4408D7D894B8B211FF1F753FF3290E54A9D05C6A5CFBFCBA0C9501FB4441A4B9362B1537C589BB27A17113EF54B068B28FB6F74474D6FC5AE8AA7B66B156FAF6AE9954F52518EBC897172971BCEEFAEADA9B43E4DE8B074EF0D7B47800930D076C6592E859C722960D32355A63DB0ED8138BAF10DB3C235293944153C60F09739DF20B96F76A0171C11B8A704AD44B035EB9366567F9B429AA2DE76FA9C12D285B53EDD61AAA85459EB7951D" +}, +{ + "seed": "16759CE55C6741D02EFAFEF5D7521BC0D2B3ADB55088F61F0028656AC970C70E", + "pk": "CF27EDD0B90ECE6104CBC5AB296C0301DAB751FE1C6F0648469E74231A5CB309168B20B154BAF03E312224727FFD0F08E7775B2B9FBFDAA283E0D6DD20B3F8F0EFC52B971F2203B8973D0AFEF578DAD5875142780C13728B3E658F87C1FE077B39C9CD7B7F84F28948250D51D5C3875E58A74DFA7F795C2B0957C6F699127DBD0C2265EC4F9CF0DC6C3D725936B3078ACD64B7C6835D5D21FCB9CADAB91A3DB704958FF70D33C1FF00396FA561A1BC4B4B0D069A71D287FCB1CB90B369C96D88987FD3147ED2838C7C15BE066768C48955F3E1166C62A5E3BD3B66151B0291E3E6438A682606E15C04BA8F56BEBAAB1E7008391765BF0D55C4C9C7E535AE9E01FB3EBC261FAC00B483A77537231C532F453E6B6F1F4D0313612B907005C3DCA1B733CFE377D4D9AB990DABD1B85C3EC423992CF77667D685C318912CDD91BF31350708FE8F401031E57E06878CBD155BF260AB5910757335E98026B22141460CD14CEC795EB5389D025B48C0F2D9C1B19A41D730B508F0C23DF59A93C64A7A2EB32658080F546479955C410399390E2273AB80F87F28AC0892D059E46C338177ADDED57900EB14D554A0F807284CA2B1495E6DAFB461054B0E6E14E7FF9313D1EE9FF83A32DDED566836CCD22B72D6DC6E52A58C7E56ECFAF68133A8B6CFA5F754653EA2F0C5AE9D26C10631B747BB4A452A54BA96F59D339EA45DCBBC0ED32028BF612753AABEE62D59A59D1660F88E6D9E2F1679C7E4196075260D45C9C3058961F0BE3BE6F61D26C30AB6517BECBC07FCC4B06B98E7B5FD9D14EC59E7CF89A4C7E1014BD3D157F0EF8DC37139683F21AB04E9AC8C3525554957294009796B80F0E1C05FBD63B3B1ACEE497DFA493F2559379B3F9A5D94D739BA9AD4214F746F4103F64B0DA83F779D2C404CCDBE4672177956F6600DE124F820E799F69EF86EA372F49780EDEDBD17604606971E8A41BEE1770A85B7DFEA6E6B8B2810E41D8ABB894A506E0880079E093978F11F9FEDEF1CDB4CFC370CA5BA9CE0DE73811CDDB1E7B2BE7840C3378A84ED126CBFC75C209984ABE1360DE2139ACC0363979EE99449B50BEFF8B48AFBAFB27C9458C9A914F3A7607A8E8707B3D2B1615097BB80F07D83BAB83BD863D46020F49BF08F343DAEE8F320AC9424D36BBB91F3D7A8D00579B07BB7C53BC700CF771A420ABF7C656F9CDD5134B2B0C6FB53C8F93BC5C4A475C11AB043C1B0A50FA5B9FA29D5A1E684F50FE9E2E48B8BE54D7DDA7B94EF28274EF5B88C3433D60E027383ABDA44DBD1E0CA737B48AAABE9F98984D30F2DFD50B678741993B8A5B483A2C56E038046B64705E23621BB23870514AF33B36911F97D45DF2D47DB94A4CBFCDA78240C77E9F7B99710E5A59A9EC2F5C89DA2E9C927CB40C58E562CB0AC1971F92A5BC1EB371DA6BD1541662EC4F0F78FF3702CCD723D1B4FC3AFDD757B75BB44A5F4DEDB9A63A15FE399B6E59928CDFB3342AB4AEE2F4DB0DFD48C5969F7409A69DE1CA6939D9121D119AB00B16F934707D83728916086E22F1E09B80A30E3DDA76D1F76DCBF9706B3CD4A3554671D9092E891D14FFD74DF0CB8835951D0233BC1068D6D1BD766E487144DB791DD5A72CDFB5A39F0C5DB47141706925FFF615A2605CE1B63792D35197CB9CA7E518F27E65CB32617BF91A07D5D14C186A4CFB7E36ABDC8C71D4245B2D70F20B6412D478B36E72CBC2E1D44B23AB09C5B89C4725CFA3CE27C79FC2F7451DDF529183FE7C1E230097DD5AEC1F23D3A817ECE30F843BE07FE76DB36FA3447362197E69575719E80588E93E4A57C11FF8AA1D8657E54B1425B6150FFE3BFBEF5BDDD58B867CEBD10DB74B4249A0B650E3AC3A65F828582FFC7332F945E82241CFA3D25D731C01FC7601E2F5874983F2D9E9D5AA781287AE5FB25F8D9BCF73EF5576CC46AFB1076B95382D89875CC30BECC32719098B5BB95FCBD22601930D5A76660B67870F269965F6115E1771D558631002E7388C4761AD4C18DFC07C3B93E7D11257099900A9B6ECA8086970B9CD7F0EA9C1FDF0E37ED7F18F79A81EFC726780F544F4E4F6C49956EF2A70F56152F030BC73C0EE7C57AE991F7E3362115A029FB411CDE0308F2B1ADD50590D7B6110F161BCEC333C5F70A52F6EC186FDE7331A5C2EA232F91C7CAA5308E79E85993FE7FBC06930FF98AA4356170AE3BB262B22C24F3971B3092AE0C4EF033B752B17DB8AF26F660C775EEC805880E12F0F87D5E1965AABFB1D235D5DE332B177427650E0162C7599217184FAADED2CA7946F3033BD6DBD59D9B2758386F463D187D97F2CD436E789415EB50D4A567B623A45B3ED8E1E8E03242E7B85CB501C04BA6244AC3010F7FC8047DF6F46D2B86662CE0C3C6F3AEEAA5D8AB02FBDA8039EE7385C4F139D47F70C5623B2D434A138BD4DCB5B7C40965512CE283CD83B63DD9B1739B19172537C6C50CA6B212117EB2B9F26A94151D473C865E5D860B272872E9113C8399A5A150376CE51EE643918EB0357EB4E785E8BA5FF3259831D63195BF1E21FA81F36D213D7C8BB52B4D9DC17D1C592518B6B97D0BFDC160CCB1C44CC624BECC28B49E294F206073185EB1414A4B80B18B376BC1CA498A9873E76A225DD2E8F8535FC267E40BD627F6ACC8F94B8A70563E55823775C4C58EE180E3AB69E42164E3778E389DC4A4689132CF41BC3816437B97AF05C126D658386DD57159CF61124448FD580F539DDF48FC22B46B103790705A63E0", + "sk": "CF27EDD0B90ECE6104CBC5AB296C0301DAB751FE1C6F0648469E74231A5CB309D14E7CEDDC2A30311AA8FA8F33273747D84A4F0D8EE7E194564633AA61E52915D5D8E2DBAFDE6D3F5D79C3B28AD634EF193197738F18E4A676CFC57CD89CD0AA6F0E234E1EF9628DAA5784D6E88DD9BD172917508BD299439586A2C69EC9EE37516408456805453875186164354434762851144032503062044733174535345336243074007370072077081545713763660866431727740068416380203118388213565687636452870788087330528072715111223815614114023416424628572273654761365202371732860200885645176752622184560057533370811066568577508011873252658610003344817466632285818231285557473165208431105636756216358276868345764816338628113787615730106550304583831526218881611205302483650721835183030737847070762778474055733402548878760487075428407073405005144801723170186433372802720438860108856746505547118015547131122453566773381342522407281545850801183484018184666083467106168381252845568124004675454602314541338432622742687024545623154163133642142284145826740831864111748641572426058870067085812666034786330234235402238130001884155852477742051765281745785073343582078116414130602308708382046610771844771422553017257116530515834771623210643083653453123174273203072120652165461603377577853268801105230325786774860038401255212558785474148811005612536620386306604704351810446347070743027613512061524183212465467663737220484528055077682744477361738537607035114778361715572673801101334710201843154010635705268423258373218118673778880168467346108724815012616873216832455740487844547741518240111500865103473675713041381803575311157872410255701424078321127582473648431113027582351430662278746751035665641182434584325772861215525770615370625335026857551177161702753358126622760777226647078220754285585438101185067104306615265684566031171156370644844601446724773223546111143485217226474815348070603068162168730827730621315400104575240651321414881564033855112770221780800225157528348444266604837745836675662685500716522842326213800620274755378763818201620041432256675142301443166263778606832838270748825315058517802584084457456813426874047456608883514726678781223637518532315712014762086217806235541401078781766415284331567726815303634475775271858640741021524306284275220610644874785084105424161267563884428838216142316446781311233544824647208842466574102173038377413542118331143367050032021043212425764087110600105282382455268312103048345414288052540078876487667764823025775566311214818185543787576556256857315236518510021215252482803706248475668860228066666672561867742220301027605488000438235713416236536151436128508016780048467212168013085034575086368465731676561760082315388865064664006463851448257676647715152480874332803114601541422802066821101585027654741377572383658717163467081225212357315441278864346071400588203756538864216143433263515106785455401547748303686407408160384157550870668870806518373802647386257117430103643478524250667688677831215028557767150786248416665782857323615017621284673503646038567228556675312835873622053521367101744308644383425387466430243221642874703241566431377885506752554645704356662457447386007618112165350121803204124113324380005611435572303115406311786186209CE53C40AFB0F90429725B870E47031CEA4209326358FDAE2531B5CE92A42C724AD1D1CFF79DB6D07F0215E6ABF1DB5F9303B27CFFC420580A0A8612C08E1F54005EF429BC8378F59DBF6A3FAFEAFA03D9C41EDBBC0DAD976D8E103CBB49A9DD674BAE19E45D44D87BCC9D83E8B6C9D99E4EC4406B744718F49DFBB12932775C82161C63ED883BE33FDC9F724B44F2CC2544CF1851237D53303B82A6C8E2381A7B92345530A7740A6A456DF5245388726AC8C568C075D849EA225C42187D25F435DA2543E3842D46F747400AC1D566CB1763133EAA110B66A72E025082B70845813A7AD6D4D39F017C9E8CB006C11A73C369DA6E1E20B6282ECD8D0553CFDC39621890EE0110F0A0CEC2FD1220C7DFACB8DDE955E336C9536DBDFF7600A64E59B113C28C86CE93B035C75E204F0FDEB7362F598475DA64251CEBD14B95600B39269C6C5FE67462ABF76B26363946B3DE38F6A3A53C261990A5E147CB12D093016342E57CA38E28736ED4F331EE1A75129386DC2A2D8C49FE616BFC5A321B5650FE51B38EA51776D1EEBC454AAA446B1C2EE18C10690AAA7889EF9C2C25FDE8E988EDFB39273A0D180653488C1C541308305ABB2E8C430EB68AFABF503DD082D8EAE81E196781A735D990CC89E024DD22901C5A3C382960D25B076BD38E01FBFE7173997760ADFD97D94C49BBB4848DD24666AFE02AE5D592CFD8354ECDC74C1C3BD713355D733E7BF531031491F869D01037AE0336E979F263D7D1217EE11554B90BFE16A103CECE88C19FC1D9B5987BD0557AC9D09F07B0CE6C01D2FBDBEC726FA5C7712E60F70F1AD4C566733CCCFD650DF6ED846727D7C3D6C8412843ABEC36750D8296776123A10A1FAAD44EE0F19DEACF8C7233C8E456D3964E0DF8603FE8BC04F73A261E1F37EBD5DB516645F4C800186A10FEE9D9271B68A0B27EA99BD19ED87E91519F795C6A1A5F7FE26D0B07D9B618CD7153E8B302FBDD7010A03A58817D00F4B9BB5BF8D9F9FBFC5FFB3FADA79F1FFDA8A028F85FEC0A6B74019EE18CB7AFD4EFCFBB259AA3104545A64B1B6F226A72065E053FDDD950096E8A7FAFF0125B4AA880B78C84D02F00421A72942C7D7E36F3D346B4434703FE26D063DC65BA0A9F15CD05021AEFDB4A5FF916FF20BFEB723F90BE1517D49C16DF4C919E9F46C54A508A9D564CC781C2271DC08086ED0265F60AE93D8BDD7D1A6AAB191F3A91A13D7F513A136385D94C83E770972FF7D4602BFB1A95DFC204CC0024CD5AD7EAD3B5D464EFDEE19A01D57AD19EF3E47BE36CDF2913C145B77A144C9457841F5A855FAEB9470BDC69641EDF4A800F20BF88BC5307DE87C5A0CDB7114ED6F18D7638ECF577A406110B2C343C6404C5A4A1E235C50E48C81F60AE78A351080122107DEB5B3E296919881EF977A12F3D5DB6ADDEC4A89E31DC7FCD81F217E31674072C5E199C43A7BACA72D697A3093766BAB7C2DADC817BB26257D032AF358DFBE2CBCFA8C2B87A530323D9EFF5709C2AC3358657A51C13C0F8B55BF17CCB04A29359380208CE79F80DC384EDE6B501CA27E290E51B02321AC77DABA35F297A552E21AD4231298F58C91E56FEFCA7C66D27BBA45ACDBF7B63DC48BFA63A0753C47822B39D11D60F4734B81E7FC8895E1ADF2B7C4A4574EE9C0F4A829806A4A99841E6F836DBB8D6CB007014005140D2C39DA195E9429A23B889ACC8223104125C68DE0E79CE6886BC06ACE7479CC99B3CDA6F568FD8A02329055EC10DAFA1AE57E09EB6D54A9EE3444B73F38D2E6B8224F7D7B2C80C490C28FAFDB2E22A83BAD4D75658DF39F4372C0B9F1C50D284642C303E5D7F54DFD50B5D097E2F1DF300D7B8706461445438FDF83CE2BE35E17CE5DA9E86A843AA24072F2B20C5377841DCA8A45DEB6ACED51B9C95FBB93B2E4D80274142DD1A20139B7E1DA43748F1DECAB315FECD77F74ABC890E6443917052F428FD8A41FC938343A3DB5D89338F2AF43B84E83D7AF389156F88D06FC97658B37B9A6BFB6238108BAA40E9C6ED8A348E2ED58FAF6EE3D3833E4F0AA517CEC9F7D83F5DDF46F88DBDEA230F761544E1A10E0E69517E47F94D7230C0C60371E2A99897EB97D7BA3D8B6931FBE0B3849265C65F1E2B8BD120645BB724A0EA60C2CBB6FE46287387610F139CF5FCB6B0BBB32A44BA4C3B705903DD54CF0EE1933F4D7257FDC4331D7ADA07FBA0B9179FAF1FE3C8F4F9B654BC6719AB70F9B36799476EF0C4449F1CAEBBAB550F52041F88F0F4F32A0697FCD0A28B73E26A4D8FBDA826A680C37B3006B059363062AA7B04D561D38170B831C47D656AF0EB7BC00E25CC423FE75DD89BF7527BFF04CA793CFAD973706D5ACB8C4362B4ECB3DEAA59E9ACD999137131A1A324FB43D88D9A9670067507FB95FCD80B29E675093145442BB9499428CE0CD635D997924AC4C38C5A21C452E5A399AA1BA6CA0050A0E13CD6C612E9E7282BA21C4DBA82F4C65D6A6E0A5D616AE2608C804D463BE286F73526E70719EA9DCB16790B31A6AB7087DC60DBC370078BD1C56219CD548BFF20163B8568056EC6DDB1EACAC12C873DCEA792BE7B6CFC7D792FD57808FCACC0C32684DE298E6EB382C0CC03D6E6AEFF28EAA92F028757D27C4809614AE4372293CE517CFAFB94D6C49EE963D2B887CE13EE6994E56BF47C7927058D1FF0DE5C7DDE04F6148F8B0694FB6D99DCC4F84417EF371F76638B4BAF8B83CD7810116DA648B202DDD928C91B0DF5E9D4D1D830AFDA050397AC882E315F809374C7FCF31D9D011F367F0AFE7B0D05FD0330C3EBBF0B5003635D007461B155911D26F93CFE7822B509B7149771979FABC066E73B5B959187FD903C4E0960A5C748358F7CD0A86D44F58B53CB53B37C47558E1253440250D0CEDF6E19F9EB8C341DCA787E05E1E7BE7FE2DC244E2B5F915BE5EF2CC789DD77F8816D1D29CDFF437F4D6C76BB0F99D395B66EBAC0F8BC4414260B5AB7AA5C430B330A4B325A725B709DE25BAD74D3A08F6F7F76C76001AA207C54A83EDDC4368A0585EFA3C5439CCF0BDF11F8874FF7A196A1703004714015D28DB1BF8A626CEA8E9439A0919FE802B5CA19F3A4C1BE83F0ED3EBEE4A03A3A438DE157EED40FBD96C379CCFDAB89FA5FBFE123F10D552CBCB3CDC055AC854E52D5198BE1C745A79ACC57660C22105A786C8E1349CCBD5A7A76F115A7DD98F16308661E2AB3842AB455D11BC3D16658CFF8C4E128E36BC8912461F883B29164E984F8808DE92AC0AAB4CC3C8D966B365312A6B525E421780FE0434FACD08E09FC65CC84B8B21E42FA7115BB5A1FE4CF3FF75133BFF1A437BF2087F7E31C7D7C3782BB75419DB512DFFA88297B50C4BB234435A301489A066FBF12A6581F634EA9E219C3805CBB63F9ECF1A47BD4A1E5731CDDB28CF8C0C40F8FFC2CF7290503A22F4B118A7ABDF6E5FC44C6DFAAB37C8E3304A10D601AADA7228029397B58DF0443C155AA2AFCD634E505BE5B1CBA8EAE7373C5A933E429CE58F8C520897A98D6FB3D4A" +}, +{ + "seed": "1A1520478204D8CA028FB48EFD49367A562F66452E43B305118C85B4444675A8", + "pk": "842770BC8569EF9B4564D078EEB6270114392348DE1AA90FF94B56976D15AB3E1836BE3233AF866B20CC02AAA8D87FCD7FEE1326D80FF94E2DE3A72AE84AF0FD92016765BF45634B405DECC316B73502E31674F8FEE147801679DBE2FAC60774795788B5125266762E8BCB71AB672119CCBED4EE4C5DC5429D98A6A6AA102A79F245752044F2C74992B08329D30A6B51A12A9B5B36CD00DDDFDB5DAEE56EEF87CF31CFB0BFBF4C51F1150DF8209A85231B9F3A22E12F64F27AFACBAA0141207D452C53E0CCDBC6CC09F3B4A2F1264500668971383AE96441FE2C4ED0DCAA91ED7C2452F1826EFEB2421BB1B336C7707B6BF68F8BC603CA56883E437B5075DEDE9B50C094A51C6E47B3D06FB25F5369480AE7BEE9C3D9635D684E563C50329E1D32A6CAB3AA491B53E6D48BEA9C140C14BE3AC917475ED7FDA2593883B6EB71C950651F2A82D16F446B58CAE9709C700C2AB622D824A425785DA8799FBF875CFFBB5F55AF583378D624DF7B21A97A241130C0F18EA8B4921FC70542CE3DB20E6730FDF6629566E2656F84B4C96E6F021270A248E31E9B718B08B47D2C42558793E148FF4548A09A091592F6A57D8D0242A8C2B0EB3EFA26E477D9B530D091EB884B2B720D9DE025D9C0D0E4CE5961CF59C550BF62FCD7BD659A3631159C2F0FF4DB34E64A2C3E13B6D48EF5E420444B95655A0EECCF6A8E898305D6C9C117F4EDB5772415C0A005A1CA40BE58FBA18059BB10E25E2F483E3B58B2C59EA4794A07B493555AD4A555FC253C8019AF81DB432AB4624A59C4004A9BDEE75C91CC41A20401965BABC0C55992F87F538F9ABB80EA4C91CCC954A3E2BFCDFFBE8D22B9754C8535F0F642810B2DD2ED3ECBB2BDEC3243E6D1CE1B489BF6C0BE50B8316D0045FFF424F49961157BF6853E1F902A3B118DD650C529C603E9438463204F7DA7F489CE50F7A77157346AFFE9BE973DCA0AE076B2DF85AADB46DDDB57302F92C28BB77890A0F50B9D74E12AFBE40FB386D08B394AF62AD94C0538AA7A77A7422167604E9AA9CC7C08B443A25F850B093AAE707D883FCCAD208B7D991A9C0465BEFEA4865B6A267427A7F2D02861EDD8BD6E72962EAA6D2578FD45A27036F5E9EB6631EF5ABE2084AAC7AFE8930DF7834F4B13DCCEFAF45A632E7783852CFE5FFFF87ED126155D3EE0D40CA5F2E76E1BF47FA91BC450602584301A7E8B20E78DA1290AA8700BC6F0863053D0558A35DA679286CC974BAD7337FF1B8BD169CDD3C15A17ACC02201D536869C6FB56AD8D3CC0E3BC86816E94A7C07F220D03A12C86B77C13FE2F03F455A5EB3339FC709DB02F89DED1D43967495C75DE8FB8A4F37F458159842FD69C3E1AFF691C3FDBA87027603D5B99B2ECAF26752A115B0AD623CB527A82F6AEEA016F75FA381B2325C7BC4370357C2D53FC27BD2DBB6B81FE1522533016861F1DEB34B78F3F76E12D30F4C674FFD86EF1607309ABB3F015A9E81E4E292F41EF0FDD97E81565C546E4A8A2336408A1E6F7A7BF878F352338E18A428FAC3CFC7DF4F9013678CDBCEB12FDBDA4FAC1144DFD42CFEC6EBD951555698732835B701B6895C0383CE71B07ADF320893C7CF3A50F3D067EB9BFE93F4994388DDD99928EFF959C6C1A78B3474F8311938F6D8E488BB45CC72FECAA84224E5A9D9693FCD8486F78385B81DC192B2126E8729DFA640CEFF389CBD01304801B56B23E3CD64F32982EC8AEAF6D1BF875B97A07CE44F342FD351188E9798E59EAF1BB3F80B710D732992323780EDEF912CD529391ADB9C4C7900A3B5D34CAD48C14C49AC3CE951EA8DB4E944E8DDD5E83BB2EE3444B165C56FB6DA01F5CA9BE7A7D2FF84B085D8939B3B17C6DDB32D117E1B0AFF70C9B6C7FC29264A709A92B216B8C62C29434C876A12F7F44F1D27D58F7A5F7707B6CE80A538D05C40FD23572B9AA2DF9C6C271296E0A6D9078F42BAEF55C62809E8FD044C898873EDD2299216571F832DDB7C5DF718C4270ADBACF6D5EB3C5390418F561A2ECB4CF28E24A082387CC373C3A59CE2FB294E1E547BE587E65D8045A1AD8F58936FB2BB7776CDC4794E40A11DBB22B9EE9FB06AEF118FB9A72A7B710C1AEB4761034BF4AF7042989B600B4EC8D6DCE81184B2D6FC27FD97BA2ECA40EA85FE3006566BE60CE8674CEEB9493323AB6561FEABE98373FD7B45674C8161B16F147001B1A2FF74DC51A0A15AC87F3CE086BA134BC3579FEB31625C07F698533BADD414E9A8CD0DBD21E0678E2ECD7356609FFD4E96ED65C3BB6E917C6911477986665BC9D3BC2FFD480B5624C143E09FFCF5EA8433411DE214990BB6A452391C1586C37D6AFF7941B686D564AEBBAEC3F704E4EF03968999EFE95493368853458A40266CB1B1F1C3E0249D816CFF02C42980A73CAFCD929AA9536D8AF31B5F9AFD0E323C3E174AEBA0EA50F9DB0FC04E270EDC19249D65AF12A09F133A02913388B386AA897A7D4F4BDCD3F90B3282FB48DB6EBBFB21257644DF17C58E57A150E36F78F802CB0F05FCA557D5A77821CC74A0B5D9F76E0D5A9B63AEAFFA3869EF79CF2F2A139CB07E245E9A5AE90037FBCE24CE4B076D4795224C2AA886E423785E0E9B014D4A7FFB688BDA6219DE7CCE223762EBC9A48830A4B935D0F4D9768F84F7247E896015063AAAFC1A613F575458043420E2E5650043D230F06B6A78D093B660A26573A645C1BDC900A01B8CFF95BCF5A2DB23A69A69179681F550E04C324A48BC52E92DA43EE0", + "sk": "842770BC8569EF9B4564D078EEB6270114392348DE1AA90FF94B56976D15AB3E71C7A10C110A218599985787FF89F74BC94F14CEED203C92F76B5D67C5B8B6796B86718BE88A979951E9AF1ECC344FB99232411F87888F3FBE77FEFB6626DCF784DB0C7EC04A3261153E64729255E5CE6B894CBB1085A600E4BB0B03317F8886231702201058730723376188778513655812720172542417247143646428467073443314821558505445472081234686830274636170123228128315700625348670708056866251602156687542664438717868470378622443800377346336674542226381071034445030257183710411707658015133175365315628308222508432565388880836567878400317604235388313286765740235347182434457158814480762440746180380258134310686500677042318457626156280488882282674122811574762127248672012054076701118281460302420147013883802514645737522146600613056240136251846755266808132084387728784208687387732824316004177161457846583175562587327431712865534241213236603884536300716533078315626426655820641212230038185751644338668423426326635871105864138063716425330034814786417767388845064650681757471566615121140773133884856204744373720784387445647085255465817762845160020133010878367040062383084562467661733017263525738783274220670582858510453422721212564255311404704722055575627231518700445822334550788684185480667112556485545130470664356488815156248663062318887582478736241505814413368843465478500161842054157741700704620375746677448687646640465602446038662064506232040688488545875504681671327453411777175183001230743263842058632518307126387382745311055143874741412652558685470007145300836667478266765746720400414877053756562543853638554022055767416327752773186204257730441432226483061516523786268418417712485468645471672265731856455178786356443681803602068235327538110083351515556343615860803101225335447663035673464647078555401071381357720555132331165637465300650732644127750530363550200566217756741351568334658823132266106657664531167085175005811475037652261325817387606338288620565380266463665550880676743051820742216586384231472841757814014150130847064753035562530164461378674013218167481421451275114210804288236311323672003873724375163251155154108303660515386682522367768687520216231844201453516302058387034720361772125260457738774237645072531304857314868085873347454730385585338757726430656643873504153136638132646508716410685703137771500478115462036447706678642871630833317150172751226273671655845870784214880067160103258382278756008163457685251154205335015838270738631741007511261313311742713137207824551084847527852768414008530840523524707832357752407838621837744764534808245473201313077736628712454463573282036047606177628356273553851122846857773665077638871445056113471408877065460343677241566065401740402885336200350816455438826025210267242615477370212156817586755010774300244226438052721318725583862702644650137844613448618726312407205277538504854674606264472087585650666470602431007157683533714105566221537353610384157440670683218006615808544110058801184806484305030012037257405731613708843171027163255001108804531421323638770136218052673025686322362266664828487564412206143775215655602403825841434121722386033731087561201120571426628221551541811228681254526288715703202548412644DDC673FE876BF31B6D62AA38B221921675EBFCA9AA50D8C0717D3FF935281266A40B58D839659D70D618AF9961C2F09DFEF7FFFD9DC74FABDCBA2BECC333FEB52599A3F8B570E6DDA5FD6FE6502B04C560A1CD59AE5C67EFED02291FE2A2B190C226EFB19D5871371D5DE58883D163437507226F54E01AA46AD228F395AB023F66A866AE5DA63D9DF0B66314B5223802B27DF610449449A29851565467C348740D53D1ED8E4E0C36A4F422079704C39702CA65AB322A370379733AC070C30BADB277E629CAE8175504EC40F52C12D6C6B2B0CD641158CFF4526973827AD68D7729E26A56DFAFF82831D8EECC3DC1B296E2956C7F7848CD3C70FD67F4AC16405AAAB4D4C78A1FCF2646D7F763D6F295F0D35095C4A3A2E83A86CA83D9E24EA38EE2C8667804AA73D369C5FA0EB148ABD763D5E04E16D7179343FDE380715F87B2F5C1D96CA406D412E0371B9C5662BFAC94821D3FB1246FCB77A7FA9232C9F3972B0484DAF748CE475AC1FB2339686348B6BC674FB7ED3E4E6A6C92A480C839D153BE71AA61B23DC004E22D7D1C6E1BB696565DEA94CD434E458D3580E1847DA39BB228D13822695850C73464EE3E88C9209ACB603F2097504FFE662B0B20B8B27138DD27E0B338A37045A93DA327D7EC4F28BBEC8415CD0A5BE2D0A95C67DE588A539521C11FE14346FD714F4B51F07CB6E7CF466F8B1D979A2362E08F1F49F5621D6AC52917151E61ABADB7E2BFC10A6CC96664CC0335BDAE35DF198CC44ED61B282B69C7A1B3FB71DEE7B3E053B7193170A768601978DD4A8DB92805E3C8778AD770CB7D94098E4EB999C16F4FE59552A3073C194251179A81BF3BDFB6547DA36D70F46FAF467BB216DA5074E8FE7AB595D495A20FC5A0210D6D0D660DA3F716EA06BE4C56CFF576CCC2328EDAA460E37103A7B03ED2A867B1A454A9C667C1D01F132F2348ACD9B8A7C4B18FB1A2C64C2EB54E3EC265C864B922AC2B1AAB30E7125E5F6EC16F37D63C720BB320C40B12A39E4259C9FDA98C37ECEB212714055E0BE07F85E39FC4679B9F7DD1FF402E7E6F97CACB1D2548E8C469C0EB5C25A98693AA70813BBA53B351463FFFD5801AF39E58F8490665D4133EF03FE83ED3B6AAB0E2BECF0BA18A66B6401308FDF1720D03005A94B4C2E319BD76AC95ABABACF9B26EA783A231B444CECBC8C55CE98A038983BE9439158FEACC518CD113C27DE1F901E43BC060D7A32AF33224639DC2A2A0CCC60B31721F44961DD64B81E1EC48852D0CC0A784B23179EF02BFE135790AB578B473F95EBA1679E48679C0EF848DAEEFFDA4C1310F0BC23E4AB154DE62FA80727341622E0E77062F52D4586BDF4AF660D067727EBB7B050FECB835F2C6AB3D2C8D758AA6EC45AC79845C62F92759306FD1D9B97411A1907BE21EF244651A9B22F196E59F21567F9988C8021B85B7C981E60105F725AF1089719F039F6EB31FDE133E783F085CD5683C22EE3E70A5C0593C500CEF37888797874DF0A3DF2440F1F8898253D477CB53431DD42DDD25DB96CD6193AF62C6E3B69EB0C73BC449BD7CED979451937249C05502BD32CE73818794484190D3570D3C3495A46144884E1D0683266EEE8857ABA5853BBB5A0F222815EEF93B2F471D2054727238F19383D29827FF65A093E1EFB0B14141CE90391E8A6CB166F200B6C763DC6FE3E5A1BEEA03DE341277465F89D78FC1399BC92D4EA0D5D62CEBCF1876BF37A137B8229CF0183C835FE9DFA73B7239E6342D0078A247908EAF1252A1065A60CFCEB37492E9F524CC408607EA865B361DA0AD206E2C9D4D4CCDFF50F9F63D3706C9163B1055693EF2D9BDE961BA85994C304047EECA80646FD81F8FD46CC44863457DAA860EFDE929A491989C80E6ADFC794850EEF0A0C01D343974C407DD514CC66050BD439F9053F663C4B4CC486F3F11973C161E532E5D8E9AEE1CEFDE8E5CBE1A80D1D8C436544AEED490A664FD8F91B6FBA3077334637FEA2E549E64281F306178F9E1A8F56ECD758F95F94DC952E38D78F92837B99472A13F677E6B5AF3EF6A6CE2E9AA54C622941CF98F938D79B78355F3AC80CFCD0647C0C1E1DBB4B04F5688E1D5E0F4D30655C85515DFCB1C49EA1DD2D7FD441B7845E60369A9D73FF79DB6C183CE9AF44265B450F076E73D089D8AC083D237CDBA4A715D33F03E8EAD25B4120148B36C63F2296D9DB09D017C946A265CDCAD3263E72DEB0473ECED20E9E3FDE02CD2DEFC2A166978EE2B01E4EC75F1A32E96B24958F1DA8F0A3193F6E0200F4AFD59ED941909EF3D5D041B1D1AA1B1ED79280A82604AAC11F8EA04EB14EB8B0D4A06FAF2FC99D2A5CCBC5A759500CF648A1A67A60F10CC7CD0B6B5A4BCCBC7622D9ECD7FF83E1599343A22085BB4A11DA0446B22C668078D5211F5DE6EAD9272165A631BBA60FCABFEDE47AAEC562970DC24F7946C279BC0E9312DC6B74BFD311E24C18FBD011D59853967DB754B17FF0AF52F6F1B602EB0DF2C2880E47EC87DCA35AA46F7E6604D2BFCBF71166EF6160ED38C70AC14AEB97E39FB97692B118A6E18B692FF6AB91D196A4E718C60C2558CB5CB658AD4E5FFBD90278B3169512B5EB12FCBF21563249699C8F2DF7BEE98264901605C1820E1DAC4D6D626F4C5CC06A05CD6DFCB538B06C0634F5E147F555CC54BA7AF371F70978FA3501F069C481F43933A979822D2A79104C1DEAAA9363A520475E2CCF6321F0F123E3AFCFFEE327A0F59883C17FC1D3EB5FE330AF9E981A3B895A78FB31FABC1091575E189705B0B27B04E05EB9EA6D05A6AA7C6D32436AD27AD9F4096DFC6EBB2E85D4449E308835A4B49349EF96B0AC82CCC6730E1429AF80DD8D5E0B84BF3F841ED609E898F906E1B09753FA0E0A5AF43952C84B400D6EF09F7CFB78C430D6BAB17FFCECCA98DEBC078236FB65944AE95B34CA33D7AB27DBAABF52ECB3123A8278C2142FF7DC357FB491D7BDDCD3CA4284D949D1EFE905F02A01DD44620A9A0112CB78214057F6F0711755814EE3C596EFD7230824BDBAB540445010AD16DDF5FA0EFC4B5D90F2AC2F57CB1F88515A9977724C643737B472619278BC747BCE1877C041FA8BD3027B56D7F4C826B75681BB146E2D42C4E8F205EE779929D74C419B1A309B9B53A2F7100355894CBE365561FF62FE3F0F0E9079B37BFC52E1198DD26471B7A6450AF9FA64DC9A070612C1650C9805D3F7336BEEF26FBE686A9A5314E0EBBE82E5F80C6D596D145B9B3840063A7FBC04D3A2945B483CA721B90CA75DBC79191A1FCDEDDDB499A96A0737556A2B6EF536653632A92FAE2C6106F069FF829F2CCF8FCE667AE7D617C9F245AAA18B60A57103F6AEB0E225971AEBF3D9A5D63866502DB16CCE4326C5B544B604145EE44522988614A6F92AC10FDA5D064413EED3B14CD9D410BA73FD59599C59475201044982DC6617AF7A00010F99614272B18CACF644BE0126C1840ADD2ABC4D20CBF39212379BE93C6AF8B1978E69C41C514FF528B6E3BAEDE9E8817C479EAD" +}, +{ + "seed": "C2B63699D7C013E2D0C3A6A5D79CB60122B8C8574694975F4D703D75035DDD6D", + "pk": "919F02200622095E1406B0D36B1A90A3702302AD0637553809B0A3B8FD3B1DCD170667CD085153D0943CD38A3D1DBF3D912FF53FBE702635789C4DAE8F6BC6750483D1554E30AB38AC6C796B7E838B39CEE22570048BA090BDAD7A851C95BBE48A564FEF34D9F72C88BD7223ADD4FFB1577F0A24FD5DE75289710830695932FC0F619A7E0E41B26436E26F277C8C1A6320460444EE13363A353C003B8D4DEC547FB6B5D054382927984E791C9A718566AA78C04C744FC587AD18F55157D269554A5EBC1FE0A876FA2B1ED8BAA686625A99DE374B93B300EA39571116A9F7C82AA6B96CFD98F8891CCD2B7B8854C3EC1145D9A069F0BCF0D34F9DBCDE3DB51B2E87AAFED50E92F8D4DED20C5F7986BC99C0A0780ACA994D56D867A10890BE4A89548BE3E790FE52951AF0860FE66B8665802D9DA9AAF1F32B2E37CB3CA788A11F842C851AD20DBA6EBCD90CD27377FE75D3972A07FBB99CAB3ED4EF317B6A43DF763A70A5F6C23B5C5EE6E0F104EFB6C57B338FACAE6C0C437EFC90D5BA12C0146CA119284686D863B5B35470E620025AD064673C0CEE9839D9E047B78450C4882BBD36FA17E4DDE53AFCCA9527EE9F3B1A5A99C65128EC41F3ECE1B3782C20AB53F2860F472C31D04206AE73E8C9A43AE565DF540CDFAC9B7B267723D324678D11BC421F3D724CD2439762CA45E0E66E06DF3FD2D218CB2B35848806881266E3AF9685FB1487D81B39EA53A90F449693F7D4C942255B3621AF43B46E928E0CCC4052432D1066AFB4D03C6BC118740A2056044896A2C6460D0FEFD7E5C9E19B2426BC4423DE45F9F698BD5A803178AADE9AABF9D3E9A01377C299820C4F61A2341FA1BC5321FF5E80F9D1A99D7475C8B78B851DA80167AB21B815D4EE09FD51A2C7FE400914D2FCB2455AA43B96154B27D6164D0A48AE97F5AF447444A15F0228D31C2655241C98AAC48719EEED2DFE0A766C6E199699DB26CA099BF1943359D8AE608576D33937992A268CF6490755D79C1B6A14F494C2CAD7FA3908F9222C786E4776AB984BB7F77B0C892D806C867EFBDA69FF21BF473223067FF55913BC844C2CA71790428BC00EEE3D60F1ADD02ED9E27C631D3FFC6AB6A0D381DB59A82BD9C0FB751AA0AA3E12399C0B04195A852EA5294C27A31D9080B0565812F829A8E9F4D112E29ACC735152FBE32DB5A47A9B519B01D392BB1DA7C9A856E3CD9B1F9F462F8990C7668F289F7B03FA92F443BF11A4494E18582B0A778548D193810EFFCB0DDBCBE9DD02683B9A9BB231187D5955E04AF986A3448DE0A377887E987F7BAEB025EB273739EB77E88DB7B7855444C6CCF9F6343F30AD4D53D7B2A4923265292DB0D1D0BF85AB199D7A6FE544541B66544CBEBA4518BA5F47A7264FF66CFA2BA8874135B4EB23E094A61A1D3AFC3CE418CA9CF97A4B08C512C6C1B6B50FD6B393C278405AA5091B54F12B576FE0499369E90BA685EA7D5AF915485F5A93A721A342D999C985FC32C6E2D1E43D4CE319A8C907874B807182B5E0F0794338E851B21543ECDE72080FA348FF7CB9855819F905880C9DE0081B149B9D74169D0881C37E89E4874E6D8D665BAC4DEC61D3200F4C7B88CAD336449E0B2FF4E46961685645347280BE9EC144ECFB60441A3249CE8C9444ED17BDA3803F075660AD88296DB499C54C17934DFB76E1B1557D03BB14106960A0F2357832B314478F694EAE1829D53CF696A7200AA667D488C85D4CD25A4669ABB2F69B3CAA7382F99A1A73E75C48994D00CE8A9E844E4A9D74301F8138A765B48980BA5605221C3646867A19A02D3060AED73858BBB4DB5B21FD9C03BC670A61774CD447F55DA763001D56B5121FA9AF4AB04E7CABA5A34FA17A40A696E11C40FCD4C9091A61006D7A0790F0384ABCB8EC3A00C882BFA11058CFF423E43E0645D20F5603D116BB3DDEAC4FC27165D7D5387EA0EAA963BA3FCD28BBDA753053607C9D76BB2977E7E15695A4E922F348522C3DF49D789281BD70A39DB9718AA259997A3A5C9C7BDD7FBDE7078792CE4909CA2EFB7ED0FCBAAE72C48AE021C0952E5EF7E569A2E12DF64974A2C0AF1DCCD4DD9CC1576E1F630CD8F8E60BD5566DE711BC40EEA8358C025984DAFCDE3838FD0348AC1D5D7F4513F20AC862EF322AC22C2E1D6D238631C5048522C1C5464BA55F9FF4C1DC8132CA7C3245D540374ED191CA00CC43BAE8FC824E18D83E481374E43FB19C9EB861F9CCAFB005C009525D5024C47100580D5EC7919DDB28972B0988B4B0B408A75537B424318C0E706BA8A4EDB0A13730D6232FB1A5555AE54760CDDE6E1344476774507E414690DA8443FCCEA1C1EBD5C47A96FE2C1FCB69E7D377E359C43F2571256E7ADB761483F3D814D96C1AE16B242E91BF78AF86F8EC9485B5A1762ACE803C64305C57D0897F4A059778A1E9D6CF18352BACFC47C57ACBB1AE6E04E27E83C0FE3875F5E245F04E983DB085A3710FCA645533B87F8E3ECF3A1A01B8FB88FDA78F4F20CBAC99F71CE4C50A829112DD9A5C27F4191145A514FA8894467704CF58CE847D5212E5A0ABC0C2A54C8CA4416C3B99FD5DDE80FE85276F166E017BA7B73DBC33CA68D681694C93A495FE42A5C463C7F0F920AEA1209A5CBFBE2D1CA7F5C2A00DD79E5C4F511031B5F4503565D5F3A7FA9BE4FE244CAB01E9A3F0D432A58A8FF902C7EC52D6D5956D57DE83642E4CB86299406C408A69EDEFB75C73526CB5DA5DC9C726CAF4A67841E2EE89EE84B2", + "sk": "919F02200622095E1406B0D36B1A90A3702302AD0637553809B0A3B8FD3B1DCDD6098D72264E7D6D4D2526269ECD818BFAD40D6E450F1CAED968E46DD015BF860C64F11F1C8B68B0A93E3A587B4A7B668405275BA0E02F7A9B9ED5C2A3A07D58638B2F079D879E4A963A71E48AA6A1AD48A53FB6975BE80A87EDA3DC2C45E3E2535347252511162373444883864234312171761112443113274541262551337205657337562142564641810327758354632066283246026032660562804546204201032100470857008704485318757233871080537100440075887712430860310035716105637805207148726226407183117674134077685281072455240143304525435254517217271628230002881303005708644321451536774560055002568231011653601844825336871747306308225147337254564776486761652475071243277768387525351423682277653676710247471164822022210263745461742764530838303826607831325346722787012407686084857676626567311027633317684127048724810304183188573153261558525367337033801513347178210115184560288328727438522687047476323872420601657314862574234236007814048147752447545347484058034681872780107524724278612143027328675538021258766156243708623415106424264857207356713470438274025516222771841842254336038556352053512561056210538731218660581146781731417410102603685057454531087820334516527768741004147848406586028810822338421580355365452504827026415403608881208676827215416335512862313241750784333244556575172312606561322356524231667412531172858170544156587437378562074674811724802217158383553162701447171412448374380216533350052350232168585430430038546666427434215210776566432862887475236726102445460355684288760664335323010118554183206073738163224141810160528738375535763352866840268340018558752747872223772826467564754525856800736608302314355680585125466035281342871425278510600680607610868737872577318456358351064687712720078162564728847764466144165122526208337786674382106466856735504105256432573426072255878810568204077874201326268870137766250031860247320056725710627478252872153077206662734770617680505174037136271378240535272306826168630171048300027443113217376461110152053250267224762485262338638447582146463383730585507550657233653638216033427160072055538301436882311630532018878501457673434108006610310811853163472486135380248156020871742778818010634356287622737627032567085008145130063600135307373066250323073525614304006334526265375820448468046114113141828615350121800562146785177371376766480605223276434131846634530460107814758043353551835534481112537700631102252224444448644311222281052385284857636008820160843864850064545034076558382755214271046680842130583103778217641677217787005862414285106751001024270630427040075517615787225164836210742813206221343126760806276705656662837772503318234073411728338565231372213525857540671013027723486135138826824336244204230151581264235632588644223333771521856662577177028188663150465003874131033684300235477368611231125344672380206712007222430300558053788063326274337621554730280578778138875722058258442357632740701132645843862338815650446440677274306103004233323287706324404276838811203068132048447336288350384168670840521354057564146760626677354826831558367781860451050315725567188201475818213440704580241507306186380161351432371542176271552136705726572162781943A096ADF0AF810187F7FFBE7E1889300AA1174F9E6D0A86989C07D14BEBA934B88A1C1BF040A0F417BFC476AB1F88F58608609DE882E23EAA30B70720422BB19F8FA49F47AAB5FFAEBC8943FF6D379F0FE8B6F8D3501621A2C550BCCAB4DFDA85773097690AA34B1D5629CC72BAF11DAFC173B3EF79BF07E7F227876BEE79911241664D127C56B89E0CF0F0CE2682616BA0E0712FB4BD025C744812CB0EFCCA37BD57B0CA6E732B2E507921F6B763F398E0418AED1257A75DA7BBA0BC52D3179CC3D35079702DC9E4A96A384D7D6C0056F0EB8B0C5974EDD43EA0ACFBE53C5F7198C4F7DDB2B5D07544BAAED6E8DC14FD14CD723B4E90EE80649EDDB402375DF04111BDACC8BA98775E2806773B311BC4D104801590C17AA20046CDD6F28A44536E6174EED2D0AD4041B5617AA9395712031F1227646AFEABE17C43EEC78154EF0D5E890EC372CF314079E80C6C680529422C82E4E74C8BB35BE3AD04C4FF6045067E3C2E4FC1055E68C8BA0FC55F21DE15F50E46EE5A455865B48A41B44205A01ED6509994BD7FC9A0237323EE302ACEA0152355BD7EBA6350FE80314C9B6D30FEB4B5AF6AC0DF133733C5345A5B2EB5DB77A401F4135EC523F95F13D109B42C4FC3B8C824BD0D11BE7A6B5A74B70E24605914E4AE44FBFF0F14AC56E75A8347DFCED9B1CC22E2F6CFC1A72F444653AF7ABD1170774DE8BCA0F7D8B80390CB8ACA45EF671CC467A674B3C1B212F41F029E492FAEED1749AF0E57F3F513DA2A43DDD5A39DE2396C3EE779507A3E7C99BB1B101260B60354553C8142225AC393F633E1880EF686D3DE4AB903BABCAAA27109949BE89045D4FE4341EF15B833FB0C1DF7B49BDC3C949687305952B4BA446059D168C4218DA3748D88713A49A14467D38C668987B461EAD58934B0FB8ED1B92019E10E511A1A2B302A880570DF72B3903780B281C17DFBA7B9D1448A81219A5212E228B58B9EE6B73A28ABA81006AB7C31BCC56D3E7C9C5E8F1E1FE1D62FB61E1B26121456A909B9516D01230F4B841189FBE50DF83937057F038E4CBE75D347EF024CDBE00BD73F9680A36B7BB26640C49570F6DB11AA917145D14C56091D0585FD6D42DB68B8BB5EBCA9B555364737C8AD68DD72BE29608324E651766B1A6936F8C8B42D902ED712E3EDC6F6B5E5A07D4C2B65033958C4102A0B5A6251C27E2CB6DB3A0F246E0D7AE6EF8BC1027E91B705A674F9690A73CC2D5396726C977E15DAE96859A01F1CF0133138F043403CBBFDF079FEE2C0E345C598258BB03BC9D77DB0C5743D56F702D9031FB3254BEF6A141FC529F09F1FFCE797A5D343FAAB8854DB3B88EA42DFD2AF8F463CBD6F7733A221C528634FF3BCEAC7DADA963FE6BFC671527AE0D117ACF1127580B55E5C4B9FD980528242341283D20BFC220FB3F89B5710AACC60F9353FD31FFCDCFCA6F5B1CC594E9F8FD0F3E9349CEAE2B25955A7B5EFF5606D0E54ABA830B29BB257AD63C94962F167F32C174B3FF9BCD0DB1B97ED070A3C81519F65DA57E526DED042488C0DDC4B4746754564A0022592DA6F25023F086BEA4A9ABF5023BBD53F193C949A455F1EA061A8DA38D93FCF0A41781E46E91CEEB1287A7A9CFBCEB62C38792FBB967268365E9D6469FC18FE2D2E0CA4C5DA62A0FE4B8E58A7AD31F2617E5377EA66768AC3AF8AA6973F36747320CEDDD50B687B314E4345105248F2B9B1B9451C909B7197556225A56030833FEA15F1B9A088450D8DDFDBBF073481F50795F5CB9CA2B8E1BA02A02657718D823EB37499824CB0830FC6368AD6793EA27D171E7F1351AA04D86652E738140B707B17C7548F9800EF75B2640DA5DDDB88D34E9AB788239F37E6E4D5F7BDEDA86A1A35514C022C24107248D15C2B07E1CFCC7C2F239BE83C585F7485DF3D893E99A7D6A8A6C4E58F5F8D049571BD45506C6B64B02BCD3F778A652DBD5745CDF4415C524E29BE7E00AD3AF934366C3E90B7C7E987F6DF87498525206027AB905ED56CAC425C3F89F676B1CDD1E1E44ECA7E0E2868B58A81ED88AF0673DE18E22C2C58B4540D03A51D5740A5AC058DB3BD115A45AD77EB66AAD1AFD01BDF61E7A81946F0B52AE30ACF0FF545A4574F6B8383C041BCDF1B358C2E40AF9A98B31996D5EB214F047355C59DDF6CDC74E1ECC931BA3814E2854AEC822EF6B9F7B22FBA347E340A629CF0E49AD22513BB390F88BEB7993F240D8A0B6DAB823ED3F13A05B392B22712B20332E876D14C51FD09F2158833F9A7DC653605CF7E77AF15BAC2D1FE6455DDC105AB28FEC90B142297984F0398D5D5C6678977850A87CA0977B94D0E8DD2FE094EC00CA615A13E7CA73EE2632EF460BC06F3480E214263F8C3D22AC12153BF2D5670C87DF4548521F1FF527CBF044C01156B3FED897059D5EC24659F50210BA483D0828CE8E4BBF64E06739B04AE712E89439EE16EF5056082C45DCDCFDF008A4CB806749036A05209101FACD435E456A0339862485335B7C0AD0EE13312E18EC8E9FEEEA48B8C2F1BC07FF9911255C0B1A9836DF57B14A8AE166B3624CBC71C4B9F5BA0652C4029CE365AA6EA990B032957B26D02932C2325A3A956051D5BCEF413B0DE3FB94E89797855270D27A2381BA1039942F59A2675E4E645B672FEC30AB3B73F2495C27A47EE3EBC400ABB1CB54FF15F934FE8B791FE3F3A228424222B88D8E676F8158A5F39034417249EF1CF70CB94B7FCCAC8303DC229E6187B2E1B0B04701D9DFBD4ADA26F766EF6A89AD54906A608A973D5F72C189A2BAB4993862FDD7B54E24E8E249E6F0336207B754396D1E508943DA1329BA186A366376F653A0CA2D4092228E1D82B094F7D96CABB71673533F51CECA70263744D54E945FA027F2577343DCDE29ED6B1820AC47BB5BE66A9018A5BA9277598267390B5B63423C6C8D6211F037E841AFFB719B35275826B98DC9A06EB64195376161AAF7E34E1767367F42E25457CF6843A6D5263F62124A7C76B8898A90578FA477883776E799B822D5F595F2F7169B76FA211C48B7A8169AD4C7EBCA7D967A7B48E77DB51D3FAA346753970D50E5DF88A65AD8E319666A553A68F4CB529BE3585400211BBC4496DBE5B0BC75A7C5079FBB3DBB6946D911361D69679AF4BCFC8296928A4D5FE3FE21BF0D0EE246259331BC7C1558FBCFD53741B4680D80AA34F67E1011BCD4B27A7B9C6FA6A90FBD916EECAAA000AB00FFF4A933273EEBBC587AEF3C7B2E172EF16087F6ADEF740FD12C30FF23D2E78D9FD36C74739C86AB3F1258C8C04D66DC611092EB653A7661B28B2785AA6A9A9EEED2E33D857926DE535FF13A6A8750E6013AFEC7A25CB85D35CFE4C39B79E767CB6A0406ED3DB06B5942B9BF364E1A1BB13E69DEB759A0D0FB49830886D5DFAF405741C073FE3D6DD3AFD4D4F8282B6C04C89ABD1BAB8A2E67E1BA0005861A5D06AB2BFC4B674A0985C4145075FA34A69036EB7C23333E986963590BDDC8A849606A173AB3002DFEB4268D26391D55ACB0FD16191AD78" +}, +{ + "seed": "821ACBFE29F941CD0F02D6BDC0112688B212D5C925AC08FAACC248E7510CF88F", + "pk": "FD5109D8F14AB2D879B5147687B0F8B89FF635D61BE11E0F7542BA19D611758B17B5A84B76C1B3E7ED0C4C857A0C27F3DDABA85382A3B84768185346EDB47C3DEF01B18C78A91BF46B2D8BE7DDBEA67AA746CA879FD71BAF265AE6F3A9C977C055C678365FC92BF8AA042D197A5F9BED4FCB58AEA2B65FECDBDD93E2AB456510A65332E08233C0672E9213B7124820567264C5D12A5A996A595440AB364F4AED75B98A77838C8E4E98CB0F53BB9D44115BB69F02957725BC11050CFDF0930F82E45EAC8F709FC805683CD81DAB07A6B6FD3E44EA3251BB67D0EDBC895CC9A3794D240815B8618EE49EAA29D7FBC6013DADBFF2A48837B4084BD6E8A7D522058F5BDC77F378B3F76D483FB4C9D99856843C639B3ED99AE06537630E7ADFCEE1A7D3D9E44E4464F79F9ACFE32C384744DEED50057FE32028C9B2A7B84086EBE6545E619521DFCB6FC02B90F00ED8769497531AA39477C3AF9DC8E2BF9C51FD329ADEDC1725F760FF5E28B5400D917AC413EDA735B58B26FA7E0C6E07749B1A5D087325EDC2F08ED9F9ED5A98E388AF03B44860930904A907A66E00D09CBF98C0921248036F48323EC5A42166BCAF893195DBEAABE232AF704BC64BFB10E43FAB2874602D8641CC997FE3C074924B6CAC536D6536C87AC0F8F658FC3F99DC98CBD835520BB3441B55CCF3CE7F263451CA1B3CBCF45D12C3B889728EB7E401C1C2458528DAF2C40E90101A3B423A4E1B8609E74C60C9B7595CEB8F35FE51AF78122D9C487BD89A03DF414746D0F2009E852A3360AA422D035715E5713F7CE28D7D8DB37C40BD86EF6CD55C0589B6E52CF9C7643ABE4096EE53CD1C1EF65E1F9C7286452191ADDA05F133BFB18378B5D898201F7EF9FD77CF76A4A81B8A732B316CA1C2682BF25C4FF2F500F55FBD60EC6DCB48282984FCA4054E8A3DBF5E0834B312B2C867ECD962F27846FBD1B5FAAD67FB4B17C20BFB0211D96039515F9B0BA6691E8493F122236F9F52325AD5B1E30C3301C0D3F60DA86B77BD81B4823CB636ACB3DD28052A278737D2E5B07B5E9363B2395B51F1210AA53F627F58109B695516E2A8CF756E5FF531DCC0C51F3FC5BB95B28B2EF1676F15C6827A4CB2520C719A90BA2AB409B31E74B99771CEBF87AFF0BFE549BBED6B678ED0B331C154D42FD7F6A7F07B99AB0460FAF7803FCFE336CAD1D3FD5760025DE4C2727D386306EED3B3D5D17D9851A5744EC70B3A0F29A76A180C46D2D49F50E9D8D1046F2BBECA53543A0C3646FD736E39175A2D66E142B0A94927F2A937846A1C44CF00F55CC9B9D62D4F25AF4F87A25B8BC932259823F3CD59F3F09ADAFD033F1802293EE5CDD49E70D8DDE9FDA65C0EA4063D4F5F0810671635885B49C16601F531C7FABDDE3A63611DED6ECF67D621F2CFD48488DA31D0FD102001D44AB947AD5296635C45D853624BAF09A5BA447CFB8C874ED98EAC7B867BA6CC10A4675E6C2F5F54EEDCD52D500DA4E15C338B1E12CAC96B0E52D483A17F9D1F90C4DD385CF00DC0AC12DB97EA1FF33C3DF6DE8BCC81E70C6C153C2BCBFC6001A815D17ECC8C61C24DE9933BECC9C9F18A790564174BAE2599F93E5BB1216FC2674FB34CF153FFA690962BEE4E9080EDD9B49E3EADE139075AAF1A187531F51D05F7BAD888C1E717BC4B368FCB12ABAFEE6B29FE72132ED8173C4FE6F711405381D3E2049A627F4DE50353CE804CE5EEA3F3C94008156E7042BB252CFB13F512B1A5F28A10CC70686B22E9759C4C8A62E021F8366A4173A0D3BCDF8B550EEB9EE396BBE86D0A851B77B2B404658AB1A8B3D69DBAAF61CC7D539FA05193A6F70C2956B0D2B3757157F54AEF2D70DBD8B0D48D70FAD4D88B11465375B7CB6178F3DA79268079DF5110F668168C6E9BD362525EDB99B80F87FFBAD11E8D88935162251F7B4DF2578DE0532551FCC2AA0A23993C6BC289AC0215CF664FEE314BB4C21354F8B69BC920FBF0B8BB2DC499D3E4BF583B9F2EB574A5AB25205FDA5FE123B09A777B10E945F508A22BEF885746B6F4CA38CE73D2B4E843A3CAC214146C71925EFD237E09707B138A252D6396D8E9188BB08ACC33720C7DD7A87613E55C903C436BAB24C9D5B74B7948EEC3C44B337201643E4CAF2FEFF9B6AA4A553D1A6678592C630D11D357348E14A8DA3B6C274464F96AE6554AC76BD4340361E7A599207CB88B7517679CFBA163AEDA592CA982AA4E3E37DB705ED5E26592CF91DC803C4BF9A8B6058CCD426BA80B4BE2FFE8D0B2B5A9BBD1CF149F4EF6BCDAB30F7A4A9FD2F6D0C2C9887EC40B41A33E4AA0FA37FB61E9A1736A78E75B0E5B668F648420FB37885BBDCBBCF7898B77159083BA58918F7F190A7AD04F6F941FD99A09338920E9522D9F41F9C8807FF02C0350D0A91CEB260CC8F4690B2E9D5A6FD3A4032AA09AB96A7B4C02B3AFB62407546B0C584E142C93BF127405A17548FFAA23832887ADEE53B90117163D8D5CCAA96FAB1FAD4DB883688D376B3D582363D9816CC85E16A5BE1167F25883184FC078EAB9A0C09A5172C0F557BC314686F961FAAA93BE14B8C239AD5925B2B9CE7C2D507141C4705671E7105190B54AC4008D8D845435A9F68164E7DEAD5893406DD21898E4F6AB7CC23EDA1D768E427F2349F329FE8A838A03DD7DED95657D82D05F6753B6E3800C2CE345B1D33AC488534171FDD124360ED5EB4B62061D61B89D95EE2D3D9D5F8792FE679ABD0ADDC5B1100A5D56FF8C8393F6698CA302", + "sk": "FD5109D8F14AB2D879B5147687B0F8B89FF635D61BE11E0F7542BA19D611758B37F4413E6607D0819662237E4F7746006787833B1F0BE10734308C1E564C8FED69592AABE7289459A5882BECBEA41861C798A02A0F36DA0AA1D00BEDE17B87FDE6DE5DB5083B879955B99177B83F46383E2E5048700863247F8B00DDA1432F9475845411106010802403124423006207171123637626358064004744217668563237888426103620752544733884730188200687105834153425720865281708118271854426277451381137237063130331623234106723431860347548763207658577260187146861448155686826455003173682641840333567008330412485633328752625476441625800267213531873672382311441364125312140451047067036187188453426367824516587741606322451571174808077083645343475863427745255815618608637822668140778022078564357408860015574881153222705772820283282645138703666837082845457545642483327554486635104572840030702644546883155868854848727734687116530122331273316185560038723621705252685722207460533380311867184216400552714105740853578622762727822013200126021044283211375323117003650187002088603640345838844504335503120832113026778216041020078002871175114780338718740318457762655342324868368435104511507781314186715333714808404824660120450275541327480357767864878521734380425386623801541346774823118010158808603360723632020412452027121234068688716164441521887108240101786315371520841447607250516005315365686168717574678054651203116875838316668026521024171872707164174688353341467360173172577764432418112331306083318608605402151567381436862124117738672361158226325887710338805385437741854660070530741053300731051058032536663754782277723523405535684511367423724838044746436665367216702401504057760861543160842185113378015224425623321268204241475232123052525186526436170475223506404246556168704551444551388733525384672264531670007310781725425740047878568634613747664237017616081148818153324800302322626514831370370752655505652444514474570366145827603375858080460822137114012511117868251538483208262330710570084046510350650067607452046145226203135104263664202836618344162630317470784727848257402470148421118752145271066152161743850236604061501516023741745433718841304847033226752765102660665216844000747725857377655737286628628855470800115846468544603448604421136682275115820474718124475360816350707076840045427737648741006206344653466760485601222162728263052643450841137207405423267533600508015253620825076388520610231453565801282615681627051432685018612236467086817638250582501884472046848272635753014406331123268541531386173156646817565463500686735817646042771537270561435557563865543005755720030384235037845153625183357188765067524510541785723483746082513261716357675385520117254805854813722260257761547732624410547504153484802545113081035450188274886618452447827427357657813402550236060754048666817727427460350022175101303701227746503115654701150825304136500402467436180731888868347168086754418454456816581305381780810850606827744730528684184014655603763554220413703356318438650383817117084323856267162872086718276068621466341542271674584731366742432452022720723523885440383735736758540137861645710336031513401537787442784487630878114247615133473366832843613332177588724308575184307203156767071BD4D1A723FECDFDE655FF7613698836154D8F6C5B46E3CC037A90876BAFEC493D244CB2B771BCE1BC5AAF7D9F8A75D94A2E9C6746DAA9058ED347D992A707C5D654D696521403D04BFC933DDD819C17A97BB4685A827F2FA843ACB0DE979BD88FF69CE5E62BC74BB3B0917EEF8C603269990CDC67E4AC99A6645412A1C2326FC2D13CB588740F71E9012AC9A07EF086670BD981722F8A7103CB68C33933F6132E78803316C85F6AB3AA8BBEF2A33A19000031CBD73C643E226C156E5CEA88BD3743B3B0FE16452FD7BC84380CAA4DEFD3AC5D38DB01F74B9AEC1E3C368A77B9FC8DF87A1C909A7E10B9369DF94460B8567C38B75267EBE99CB7E07EE626772BF70E721B00050D350BAA16B0AE07FAAAE61716FAE72B10922673534E83950769A5AAAFD95D3DBE428E66C7148508D2CA2914AB6DC20F0BF7AE92FF51577093AA98FD383A5E62791AF20206690BB1231736CD5449ACE93061E2A71FCFB4CE9752188A4A86302C6799B882E44545FE4667023FDEF2C13939B373E2A85030D23DE62FC85F3AB765699E898D3F06794193695BB0495684A4AFAA4C9D63843CED531BC122EBBC3D9983319968FE57D037699C3722545D5AA32FC648CCE93EC746C020607513559820FD9F4178FEAE2620BA278613A0832A3068BB65A445ED00D0623DC6B668983A5FCED6D8BDA41164E8ACCA99DE3CCFF3C4A6D5CBD019F53F6B70C97FDCED46ECB1D6D969B16191DA7FB093A0200AB28055A045AA9B544A543C96AF75EF9950E36B9D661999929DCBC2D697CFC6A3540B56EA3E4F4187B8D892447B63D80B75035D8E594BC8D7D8FB55694DADE5463804985B3718FCB59A946BB3B66D6BB38257D0430E18605399C6F460CD33FD9E4353CE5F7DABAB57EAF388310B828BB008F1F8850626680D2BDF2D1D7FE348B18CCDCB1430A689954CFD60A683438000C1295711F7196F9CD524243813388702248346794DE6AA4CEAE1CAE5E1AE474F4CCA0CE754B8021464522E4A845C1FAD51F775EF7375DB6A21004DDFC8FBCE0DB93DC275494E937424C4C3EE97063650930794917F57BFDA70D2CA74B1BA7235BA947C587B1C9D86AC4CB9C8DDBEF333DC988894FCB2615B3562FE939A5D171257726B6C789ADBA53DDE401D5168418FA6C1CBB65DA20308DF78EF6A719C059EF43A5E01CF6B2EE5259EAC541CBA7B6321E5B592ACC42F6E5278785AACA977E2658145258EAFE96A544A648E709B48EE39646F1B1F1040CAC64ABA7B6A69DE4866832FA041C36252843F20FB4679744D6DBC09C8260A3CEC898ED2D8C33CC790D2D7798824F0A05A1299C4D7F2A4EBE7496956A5C7A033340DE8A044619D48013BE1E4B43213B3689C2267D4541853314E807EA6A1C69485CF57B80A106246F10242E3C96093C960EC0F9C0159A45B9007B7A8141A1834B8B328F44BA0A1FCFF7208B476988686BE639362CB120465D1AA9A6054F596270E5A3088329A91A070A6A9B8D86489DA8AB6FD21F21B163D0DBE579C2DD5F102DFE9FDCBD9EEA6EB32A236360EC67CC685495DF8ECD4E0DA5AD27E9F313E3123828A3A7F54D793B1227214759A72AEB0D64FD2E9A134BAF89ADE482ED7CC5DB0C9593C63219CF38CAADEE0C0D297C9201F7F25680F0EDEAF516A4914B2A4606234528FDB99E5F5C0CD2A881CC1B670EBD170360877E7FA4D884A67EC0E3D6A4D3CDD304C4633A1E6DE168AF86FE586895EA49E390C0A9A92662EAD24E05EFC92C048372EFBD3AF11B87809C0D7EFA38C24C7E082DB4B542468EFCA41F88CC7C999FFE3C6568586C39F3750745F0D3F551620C227109DF9155437A87A04E08A4FEAA648E9288299E47C351E34AA509EB4F772C78E33ED4E36858E4055E7E3AF5A958E96E69E93BD86DFE5DA8D1A3AAF0769DD87558024F2B26C6C6C42224760D12B52832326B7A1F70CCD530B9951CB3B7A499C35043789E79EC68CD8EE1FD56CA5F22A5D54FAB7F0689F1B9584FAB8AAB9842A3A30C8780132F14AAB121CB09F0B4941A882FA8BF4935BCC7F2F698D93FE10F2393FA96B9F957296B24669DDE4B600927BF5A469C0001F0B1D8F1DF0E6B208EAF552D52F15FD1A80B1B4831E65057641FF84E9CB6811980DD38C4B26B11265B4E71CC306DED99E3D48209545DDEA12328A1A99972AE9C849718A2E1D4E356BA7E93409F9BA01BFEB6AE78DA17DF50924E428926A844580DBADB3439D98C6B89818907EBD7B7EB11DCE48478CABE0A49DBE5918BC45DB4B88FC045D1985B918789F9ECC59DB72F2256382841AD1317805DC32E60CE2096562BEEF9482EDB130FED0B00335AF2A8EC79380349E1564C3A382418550623E7A87A7CAAC056EA6B44FBFEE65C93890FA3AECCDCDDD24469D418FEABC03543BEE545F9FD977D77FD44352553D32A365AAB23E0916F18775E3DC4D41163794884596AAE4251F7527725C98483C72786D46EB2A11992B40DD0C69AC7092067B3EB63A179A5C61446FBDCA3B21BB919032B97962B7E218C2DC34409EBBD5BB360F2B212669CD16F45F5AF4EFA777627DA59B6E2AA0EEBCF2DF02D1954B16BC0B5A718BB95C1A905400C5E0EC0F326C8ACAB20DDB69525FEBCDD32067CC74DAEF2E79511F10CABEBB69F11AB14612B38190F8C02C4526ED189793D059CE759D56B00505774AAEA728C79CD8D2588919500EFDCB2CF7F870C999EE2B5CA16CAD7CD92C50DA46274A1946A0D8B3EF4FB6D498339F2C7793267C92B0AA4A73CF40C362416B487A83A9CAF3F7C6772AD70DDCC5A9D1FFF56B5E37B821FC398DCB15E60E1FC0D8E6DD569E315C5B12187FF345D749D66967F3E7EC97117330894138DA444597DF7B5F7A014431C253C8D19F9E8E6D143F406B6E9518F18EB3E3A3B72CEF48F2AA245CFBC1F1219B4508BCA6EFE40F80357A1CF1C9D061955A746318A75969EA691C83B5219A9354E0FD92ED1302314944BF62EB3E75EC9640E2CD6E0A7C955EFCF41DC0F90D25C855FC9F54ECDC4CDB40AA95E7E53F8DD2DD6CC33F2703E8DC4C09C6781DF792E6DD945FE0EA4FA760FE35380236138F6B49C99DD5D6FDED1151D5C461DAF39717916CDE27834BAB0A5E3D5C0C5FDCDAFFC3E372F5335DF494288D5176786CA73DBB2B58FD519B10531A2C9D6D390F7D4EF4D9C4F8D0C6F36B68E3B502E2D0F4C97D027CF8629E2239B3ECCA9547EA8D9E8A357602319CE01B0B76D2F5CC5B4A3A906762554A37F0B8FE5B4DF29D434D98822C9D3CA495A103D1096DD042D6BAD442BE6D7A5882AC7B79C9B588F10CEA4EDA495ADDF22A8A52F49D21ECFE6FEDC77A459368C18819BCB9380A0C115A5280CFEA7136EA7359A78392C27049A55FFF75FD69F70D08E2FDAE617DDF1E43749D9BD0DCE026FC0B8722DB70AD47FB3ADF73C1BDAC24A27A596739F7AB09B92A6005226FF18ABD52AA5131BC9F86C786D87576BD3D8291A471D4F40EF51B214069D7B0096744BD9856C499641140EFEA44192F40ED4CBDF2C562E30881532543471258282" +}, +{ + "seed": "19B20AEC7AED1C129B55D7A5143192A3CF43BB55069017D695581B74006788C5", + "pk": "C1876C7591D9FE2918AF831763B053D7CED29634CAF7C28E44CA8DDFE79B741612FD62C3049C2B665EE8EF14D040867275020733F0E2673A1AFF38F32C07C4F0792A7BA4777256077FDC933F991ADAE12D5C0C79299769DC28F2445FF043D563DCBCDB9E8F3B238C441CC329E13925A779F9A3B65552EA2793F99A95577745BD8CF86DAD4373B22A7FDCDC1BA31543C649C4B6B7C8E60795AAA4C4A9627D97B5C8A04BE0EECAB50E02F59139751DEE11A401FD23F3A0B47837EA00CC146D668992DD97AFEF17751A01449B0850E3AB1838A512015737199483769E060CFF8B66793CCE1FB3E4EA781C6D09D12231775AD1D98CAA9B1EAFB9390D67D76EA3026113396B8DD311516577ADB15A77CF47C2082B7982B07687C2C88A6BDA5F9E5FD7F2AF932D947DA6FD42A219E297E65486B5187330E4C465DDA55DDBCD1823D7349D9305691C3EDCA07DD547E46AF919C780BB03C670359EBE80CD4FC98DDAF6449677FA7C045CBED1C04BE230690177AC880286407E301219D305DBB3FBEB56B0AE253AF69ECEB2FB19FB66302C828D375328CE26B8EF9FB97BC95B35D9F0294E157A98F50AF78A451AC533529E98196987D2D0E63C6F9857750AB8CE1503814C87FDAA84B0D345C477BD8E87A09DBB0C176573B5369A083C852EF8B49D4F30E6082E619CD0E10A141B161832E94B14D6B0150CF32A8054DFEC80C2500F230D4FCF86236D72C02EDBA3CDFD83B28EB7A282D4CCDFA1E1E5438F54D15704E76C92352FF2F28BB112372E5B532AEE918DCEF2585E3163520A08182CDFE1A3D35F8F4039105AD2BD4400C6F8EBFBCA9FE312F7D95019912E2945890AB754881AD378AD92D00498EEB82113897D555DFB6EA7A49B8D7115DAE705C2C7BE0D5BD7C79A19636884686B9173AC7EC14310D08361BE6ACFC6FDA240A73722B6704CC3D2BC0F0C0C040E44D11E185A21FF149F8AF17D2E056A3C3B5A06FFFB6E8BD3650E538AF954024C4E0B55B23941FF945513A64453A0BA9A4D3DF118C31263A06A3DFA7E258862FB8BD066179117F878662746872C7AB66F2264E4765EBB0DD19CB31F55163D8BD964D3B359A0A79D4695D4E0A1D6106CFF71ACA80FA61841BE0783D3CBDF843C65EF755A7891C0C40C98E6DAD9F565E51FFCDD4E982173903ABFE03BA08BF60E5F14D3C88E00A2D882253D88CE6860EEA90A9E4C2AA2EDC6AB0424493C1A79B5B6A3F73089F4A64D0B2E55B7BA0415A53960B870BBA5799323DD2D00199E2FCBA9547A9C2B823F753408FF143BDDB72B3C1E6696EB3C6C3CA2984453B1916FF4DFD6B3B43477C42CBF433C752D0749FA7D13E53363E6A22D085EBB93AAF260D610EA9694AC2DF8BD0E7DD543FEF57685E381630EE414FFD89269CE6F0D9D1B1E32EB744120325F092596DDF8CCCD53FCA530440EE9000EDC1D9708D0359A2B8C20008639F164A7DEEF0E1F83FAE0C6D06AB8A4E82CA74ED9AB0144A93F681BBB54356567E24D8F8A8C013D1E879F666EC62B94F2617C85CD57323A72FF71AB92E322C339AAE371AE06BB79AAA775C3E52B9480619D6D32335C8BB45EBFD11F8A5C5CA339B69E0F3FCED6A857EF3435732919568F1212DD9D02CE7F3FC1B22ADEEB3BE460D19235DD54C85AD0DB8165F30AA209F34D043A9D9DD186003EB29BA7DFF1ECAFEDD36767A7A389C685C4D3ADA09626C652C7985F237D69C31DB93A8CC116BBAE071DFAF8466908A9975C29D8CDDC236BA5EB447EF045AD83CCFC8FF9663D027A8138C6133A20D9AF2F89B2C183811B8A6868D5701C9466C54C78DEBF571A18DB524A7AE18C935B624446A8B94F25060D695949D7AC47DE11475C427B3BC987CFF890932E8BD341E51D0DD8B178D5C4F40C35B9B2E2F2AE493029C6C63867EFE1D7CB4B02C53C5646A9EEAE87E6FDE7C073BCC7F0A79B4F7E25383185292D735F0DE85B4F3FE9FBFDD21268CCB903640CC081E19BEE7184D3C2338C83E2259E59D8606357F325D5867265A2DE3FC8BD88AD8EB2D4AEA4E89CD08283DBF1E7C5A7E97E3AB43D9A385F162CE3AB3CCAC6F86AF9C45FCF60D997C3A6DCF610DD4C6978A3BD071BE03C0495DB413D5D2ECDFCAB95865F0CF0C732AAA3ED403DD9901B1DBFB603FE933F994F6C0B5A7FA6788AF95F676F20AFA37D7590C31D10AE2B0FA71239499737C004E7436B1539ECD7E442AFC74EE027398AE51D87128BEDC2C2F1E8DA5FC017A748D6D51428853B71B4F8D07A593AB61FDA4C401CEF4AD4A202E957DC207B20E15F5923CABD23E5FDFB19C66EBB92E1A8226F546A3637CF69054CD173614E5B69462BBD53FE82386BBD5AF6B807DB21B6FEC62AC9B6FE7F6D1BD777B2940B43516CDBFBAE26722F6A88552544C656CAC0C1726A3E5EE30BFC1E140D40EBF234BFBF07AE5B3FAD3ACEE3F8A134CAC9B9EC925E8763F21E85A113C6E59F5CCA70EEDDC2540BED7C92817B22D464CF0B13CB824684728E1FD84E497E4D8B1968F9103E5B820D97BDCE02BBE71CE0D6A8C26769ABFE48ED47BFAD693EB992632B6B934B54EC903A5C35CD8845F0E43A0E856BB8ECD9CEB4EB70010BEF602C7EC170BDDEB6A1CE2474E3323EB133BE60E1A23C0AA0A88DAFDB69B4C492981A53EE45F006F687951F13E6399C0D3953F134B5015A62817F8F631F22F029EE3167D9CBDF890CC68818FD12DFFE4BE01B4BB04325C36770E85ACEAB462A919B5A2CBE9F6198F9E3C8D8F253818C5C1B6B3472DF05C8", + "sk": "C1876C7591D9FE2918AF831763B053D7CED29634CAF7C28E44CA8DDFE79B74160D9539D135C3137993C93CB7E9DB32D97BED2F47CD513927BEAEA3EA4DE8DB3BB6F69EFBE8BC30B741160501F042738BE204496408E7B322B4F8810CE5F0A1B4F5853BD042BDC71BD3F713995F90D2997BE98853A3E0B05ECA0C2CD529C62D1D31142720430162555220261408757487051805486321463505328548138872674635348656038584807581556616567024781108748714006466586518105002840004152155071684402283301625468608582682871478285880112418701887856542813261486851086715532015038018055506582001004343174024123728627110402632383478155035530668058030807805254735026344715438314074570828778555510310503127760081644038768664440013167025735144760220153688771326556654136677416836236681275767825505783518026507108541306761822164356817775213250763580875702357583307542021077861788684686144273011537008501712324033761721553654884040484566604226000214651473588064077132555143158421687651533365271426802716634284747711533266322568582853708027003861221727624188548224553846320154218535004558846614210714725845776845035032840301165860462661558567062356487726862640113066862340546354378052445185333237853473826544553735144445868050241350888774173617075453531720267316818175415433376853422836031112605825812128668124221221813720163332878132662740616835058334581511783268088514555323113603245767313468456805542257754161745144715584644762635222801770257403571224173224101775575421637641653561651523472523353220007246647685422882100323788035807815471744883353670332227331383575023847310756871261578822337587022523242818335102643211010036128440207207414604308060212184302087706651107415366331635141330688886357276684550512668846326170485080755401433066163136305042535141770172143571578534537566273505072131666672802302137400258356111170004050122176802185713363384107338013714068046336638073677671825887712654440634342104756450234366074785063373770138355536602834482336117841811656443744500552574381774725612554820152456181136173480528377444617573837506101566008482616254362626412148541878576272451278865273175261065121480628166312811217332443874218160274773587204140232054516151580731416010517360222140016312345165580552765116138228663835802871501003418662168472077781187768025576001388352286135461575165005568123188068230433318746647171256317558746767878042633203465265747801218226257524465703521066601441767437260017503655584555626781625645828607216813374401208635875826640523026864485803177516421032408802243351517420170357837500517573422583060107563784043772507424567258253886871303426754383234648741138366371401462647365832748247554435886122467742424232347324855363843371303526333082723501448384560734138412613126277377455378767072466561765062756763081555387882428742444264545182347872215788716415115613725675021506301847681043752187440344541180617014583366082216418784124548587567538635417676816656583151701337688684365852214350536148165082118684731162728603020045865388212864485217252720226467655245757761056558883368818036647577235233732437782724674158151572615477036118545377305340788610187136740007740123076210307123022813564872374047362802876653816510510783134134880883380826444C8103AAD8657AA9B63770DC7A193DBFA1E0118E192420247B0444A7F836CA9CDC3A0980662EBFD520D15D923C37ABC4C3FC417AE01F017B157B85CA4AC48B3A5FBF10BD5E1F3BD2CE7E7477F4D47CB502DA2BF1D75FC48CBA9CC78781E33A3076A96F7D482609820FB1A1EA91EA2C423DA8C5E9ECC59F34BB5D58CA360DFCB4E4A10ACB046AC8A0C2F093FEF48DAB309A7645EE2FF18D88CB14737400C44B2EFD12D8C03579A5E0FE1B260F691B9A9D001FAE92D5C04A46D0232751D51B4945B86609AB60D80A9B04F573318062929CDB4EA895013B78D88B6379C1FBA2E729C7BE337DDDC9ED90FDB05595D48E12CC38732E00FB97735476D423EBFCD8B91D7D17D9C9F23FC65EDAE2281BC482EFAC37B48B23B9D1FBE8B8AEC1533844536F1B61BC8AD5C0DB80DF89B3DB99EBAF8014A8050F721123B45A913DD533C8C9A5789F2D6BEBD95CBA04555E36779C2F1D0F562E5C8597970C009A815FBA3F86D76BA778365365BB5D897B67076C9B826EA46578DE54285A6DC36BD9EB85F0B282376CAC0EC1ED7E22B05CF123792CCD02EBA13BC9079C62528075652685B70E291A659B578CFF8EC7858CBF990929A639F20455F3CF14A6E9FC8DAFADC9415B3B20C8B26B5775F66DD90851653B30C382D3FCBF8C823EB5F6FCF70C0357F71EBC54BDE2055615A1A1CFDF3A92888C5831A3AD66B5CB128397210804C3DED05CBEBC4B9F982CD5AC73154EB629E8EAEA4F5239E7A4F6A4628469169FFB74FDD8CD475F395E95C8F6CC451E46AFC3977BBE7EE3D2ACFC1C29C197752863C0ECD61060C90F3837A276DA89A7496435923C2B89786724FAE94EB1F585E8EA4CD6B0B8127B241A889BA2FD60CB8AE279F77BA7EABEC33EDB596D6EDDEDF252800F448C2FE0DEB52C00B2C59DFECDF7761ADAE9FF8B7908A5B441A70B451E136473FAA2310C59733200D238C75AA10FFBF9189580C53EA961A72FCD49EF3F7A7834FB0E0FB5101F0DC77819319223D1BE54CE05321D70BEB5347227EB13C2EF4BCB75DAE62B80BBC3F89FB40D83A0BA7DB94AFC86C469EF7EAF8843C508C465D90F850F85203A978134C4240479EA0E241F805161E7C0B28B2E960EB281270A26FD00B0FCC8942125B0E73474B186BBF1B2A22BA5CA4EE34BDABC5CC9729B25F02AEB9BC4FB18F11053DE96BBE76611B1AA5D3C8D1E256481BE19B03CD3FDFC9BE306F35ADF8B229CA3E2470D65DDC3F3774C453AC9F049D4E81AC955283B8C85B5F52F13A5B9AE74B08BBEEEB7FF9C7DB6F0DC10A8E18B5DE83725FA5B1A6E5A009753C694078CB88E8A2E95DBA4C5AEF8C041B8AADB984F533CEA6B560807CA8FAC3E16000DE18C94D0346BB6B6E01A739685207BADC4C641201C159BB256E56216CCA2DD471F34E97891785CF7E6BEDD14C92FE0160EF1B25DA80FF86739568F006E778AEAC09EBF4FB56D2DC914D549FC91CAE30C1F044AF84F2F814C3BD9EEA0FD43E04FB7C5ADAEEE456414DED08A0270B1C418AA964C31C0D9326618DB93BB2885A7F734DB1CFBD903D5A2ACA03185B3406E015DE23AEF3DF47F4394C6C406D63EDE57EFD3D00555592FF3454608E00D5B04B276D8D52E8533FA59D8DF4DA27AEB1A4D6E54FF340C9AB6F79DF17057517B7E50CAC46E99C2433A3F14CCF5A398AD94C433826D0497DE022529C0731FC5D567A2B63CB8473B1DD8EB40EE86143562E6A549CB58A94FBEC6E75E71ECDB0321D4E5FD2CFB9E8BE3E7B6A9CFB42FC42CF3D8A8FFF70E2E31A9D4DF35D6AA73AAF44A0E9FA0C49F1AD3A624B88DBBB2CE5754850914FE76938D2FA56298E56DBF447BC1DA818B2CBE6DBA78A240A070FC43A9C776562864A6846A4929C94B4F1138ABCD75DA0945C9AE6F1EA9468249DFF202F2E338B9BE3CE4CA099315346ADA893A49B969D26ECB3A05913DA9FFC13327CEB3DF6F0D1CD855282CB64CFBD0F695ECA2D4C24AB18FE07A79F2A129CFCDCEF608835AD2F56001E7B73DB415A132EB72D0E752E08849CF5F663A841D25792E3073A4A2634D9B41C3F9C73464F4694D116EC073C67C507C05FF3EF5FF1441D2396FC4583C8709C89E2EC6CB688B3713934E76B95E8C10CD2F3B9D0F298D2B66380C547D992894DA2554CE583743490A6792FF5490CA64868DFCD95C4D3AE21130DF4B00FC50CEA9AAA2277B76CE9F7CBF8778C30591A81F2FDB4F16C614FAD89600135B8084BC2494A119470C6D622B4B6DD534D086074874202F9772C190C301987A0BADD318C2152697E8397D4EEF55547C672F35985E3F298881BE917043C8B3E9679AEF3A65EA7E641F3805ACDB18E716493B597DADC3021293C234B5F3B548E82250FA5A2872357D961486CB95081829BB567AA3B352B64C0FB4F7072055FD8AAE50F855C9AE69A1850BEEF309A41D1B91A5E181E5020FC73DD5A90AE7271186F470E20D2093F44E128E044E5F7B516D746818B18A8D4E155B0CC322DEC548324B0241F4038C29E6CBA77C80228AC9291D1E5046F7AA321548AECD85847EAB71996E3AAF47738D06010DD373DC12FE362B599EC7B060120AF6435301B6324B7B99771300C7DFD369F7983D1054C1C45D37C8063C73765CC399CDF2C7ACCFF7A3B6F80C0110748BCA149DB1C7503E47CFBA8C4D44A9466D1DC0F3758932BB4F960AD5A67CA4EFE34F5D946220BEB96C787D88F87587D3C09DC4F6DE6CF1A91E463BD48398AECD75ABFDDB9DA29839D78260DB74FCD26D6918600C74C4218096D1BCF7054D7DB853379B88235AC069EEBA3BE170D9D5742E085B468D3ACB79FBA3972E46AD34CF645A979D3AB0E93E1B69F16B4C1225C048F5E5CB06AE5E9D84C59DDD9AFA1BA1291F3E02CB46DEE9B22EE622393E58AD1CD6EC3A9EF39BC5CB2252C17EFEE60F2A139EB84BD7E9131D70CDF35983D81252927FCD3CEAA9A6256CDBD0BB4A310945E7A6EBE10EE50AE002B281797313E621013D1F9E9537A51A9C32D89FD4C830D47E6F87F84B9C600861FB7191A73EBF28F9CCB83D031CCAFAB2EBAF1F4B67B651128CF35F70F8315D03E9AC420B730C7C7EB1C16623B89B89015E59A57EE9E4AA835436725459AB6EC1C3509384E1E44C50B86251EFA538C3050032DC9BED5245CF7708DC6C07382CA7B5664ECE3AA5C357492A1CFB76D49D4CAA23D237BDF1EA3F8EF35D2C893BC45329027AE33D9F63E9845BA7DE22DFE6A7222D1329060C4C8181D92C6B399E71ABA66FFBD4C29CED409B8E083012ABF3A8A1A9CD64F97E972CAFA4CA3861F5F73D891155F7DC9B49FDFCEA857981590E424752F9D80BACB50CE48AC3B8C8F25062DD793AD88B89E94A93A4A38753DCD1EE3FCAE78D680638C0B181A99F08EBA730BC90805E56C9C89BBCD093E1C8D9737FCFA8B1958D1C5E022072A04CEBF6CD3552CB1805A598EE9FF199144A5C4CEE2DFC1D318965DDEEFE9D2668281263143D9C38F4681A72096CD7DA420305ED6D5AC10B021D8CEFA981B0015099F5E5725B8D735455EC2FF2B8ADAF" +}, +{ + "seed": "12FB6DF663126191038F413001776E0791E024B1129DB3084A1CDB809404B555", + "pk": "8DB98D451A84D7C9FDB7E2BD7628EC0EFE6BA51499BA12BF981EF380195E1D8BB3E4B6E7AC1320C295DD121AE504385663CDEE9BBDC461D9AF9B74A36F30E52598E024FDC912F1D51924E3BA090D5E131218F69A80C44D920AA8B3569B36505F4D50F161A5DEB45E736CF04E61D6AC17948F496BDFCE3E9968861D267CE87D3233D12E0FC6A4DB86895F7D1F436483AC051DEF1E5A4738342B95890C90176FB8EF27029026E333E944A88D08DEE0340580A08DCC4A6ECAB4761279D76CA4DED5AA147D656DAA41EDE66F4C838F0A04E2A7B8E18E4413BECF01CE5415A17B6F39A5B7996A84D4158CB664AC36EB09980FDDD8323B2207384F60A63BAA446C0CA5A8982EDF24DD4DED8F07181000A22F9FED786FD3252749DFE193301414174CA01BDFD362D25985A6CBDB315026F813E3220FE8DC1E35EFE3F07772BA54861933B9CA9F8F68BCECE60F9F28148395C1605890D5F2B3E859EB7EAA3CDC66C58C9782AB8D67BA6EC271F454DD8EF82854D2CE61B5A513AB8FAE77A081D4A5B34CCE0100D31DAAED0852B9E77C904EED16AEA439B46BB2BCF42FD3ADDF320B4F1CA1737B8D7D3F7496C7C77107F2BFF1C907BB145CC2FC7F92CC3A3A4289CFD836AA2B7490393563E2848F0783EE4814BEB9F1FE75B5371BC9944029FF463361F65EB6654B588F9816FAE2083A4614DE3AF064D65A1254B4252C8B02F1919CFA11F7E523F51C99EF17CEFB5EB1F692FCDA240C3A0C504F2527A477A41BB2894AE3F3117E96FE3880D3447E1110FEBEE17CE73F1BA7956F397023E6CE4CFD8D3E1E84868C94C0737ED138FD7EF28A7D6E0A047215A3490A031C2E7085EA975FB16D129B7A70521AA45E9300355B930916D40FAB7E197244CAFDAB36C55CACCDD9EB203F48CBAB6DA41A29D686AA198576BA05F4575145DEBC8322DFBCE5A1D0899913DBE93F96033DDD73E8CFA20D92CC1E9869C217586E78FE30351EB421CCAC154089EDA5E4716E1BB022F264E76385AF044FB2EDD00D351B0FDC49B10ED29510FADEC7D7BCB72EDBE46650198C7B221335B354A7F6623842FAE558380FB0EFEDEAA161D0AC5CEDF64CD3FB1C709DB76C8C046CB5337438A72F283476687D26987B2C6C205F9B39BC2DB90EF13CD5440993F802BFC120F6062F8B62344231A268128B4AA66EB6A30EF98CB94CBD50667D9BE107A04C54631570584FD0132EC1F3AE8F115C54CA0849C05258CE87E6343BECC597087369594D1B847CDE8AB9D7D3EE1911953FEC22A2473064AE8BC3F406D81AED4C546C8E0DEC5327F2CF883DB613D5353837C823C005420E2114468B6B29B862FC6D0946964DE31D2490A14D5022ED160288F1C1B08DC9852FA66FD00138FDFBF6A1297B90152580AB8EB3E7374B627F32233E513FC9329A5062B3B376C5A3BD11E82979A0310E6BAB7A66E6A8CBF829E46C69BA03A9827EE64E0077DA863E7B046EE8521020166108EFE63D089A598E1930748A6446E4E817EC5450A07A01D49C767EBDC711F89B07C63B2140052C42AC2EB6243A4386E4E8FBE98F17F28C3C452AD376A2BF51C5E305904A1357D1F1B12EEE2D782F91DBE7891C7255872F43C697E8FD6CDC923FC866223812C568EEC14530BFFB2987E45F44E0F792B234718307275546DDA727789F918EF4897A6B586F9A614187FA19CB3AA3EAE11FDCF108F69581082882AAF9A85744BBC451263AE2E71A2E9EE1413403444FBC4CF5ED48E73211835DD7F2EB21545F4749CDD8FD83EF61A836AFB24FE46DA4A70E8241E81080D6AFA07CD3BEF47DD96A17E079EBCD81231D0D6496BD46438CB6342B7B7934A42F375A47B64B9CE0C08E21C5050204E576E552002FC90C86E92CD46A8E038A647B3635639DFDECDE6CC2628BAF8680529E9669EB28D02F1DD514943A034374C14A603327DA8F83A196FF531DEB4D642513977742745222F18DE817FE9BD55C4DC0810B56F516B673498F7EBEBC49BFF7C73305932E8F86DD79512EB52767154734816624DA121A925DE9A2CFD9104CD2C67F1CC2ED5413ED2C56AB5634DCA211DDBB333C8EBAFAE42771D9F4BFFED56D4C0B1C6683BFF51D0CC804E1E2F6B288C78CF292E0840D60462130DE3224AE058533B510D70CD9D5ECA048AA7472C5DF3CD8CA66FEE21194798237CFB506EE058319764FBC09F21B46850459CB581AE2417992351339F5F253895CC4251670192824A76F8FB63D926EFB1A070E0CDCFCA3B6D91E4564E085AEE5034A10FA2DF175E0B4EF2AC9BB6CE88DC16BEAB87A5A73350D5B7C964D005FABC58BA0C6CA62A7C127A49B8F01B6EB8AA51D3C102591E7A96029A248E4C65529613F177DF501C88DE3938C378EB4C71BAFB61624C15B8A14AB6C5B0840E0BEF1F6BE9FE4D469AD7189B3FD79B2AF4E9FB2D019F98E57E56D33EE4F32F2D21D8C11FB3190E3DE9DBBE9B5C96044D92E684B16C8A2AC216CBAEF735B2C72690F7692392904CEDE6BF8591833D4007C7732E7C0D70FAB6179D13CA6F77ECF27E689F7A6D4702D9BB293F3DCF7761DC6405CE43E32E73D8BBBC46C9EE7DF606BB4DECA8B197BCFC79D6494793C6DB02BDB2F14C3B81AB1D5F7E5F9E07AFF50B64CF2D82254D8E7658D3909BBC27522AB2B6A31394E925C84B665A4A030D5B1399902C0E31E27733E1761E460095FEE4E811C98A8FF6CBB37A27329B9DF33DF55A22E52DD17DFF78643675E913640FB6EBF88430487D1DA2CDB6148076F0EE6C84393D5", + "sk": "8DB98D451A84D7C9FDB7E2BD7628EC0EFE6BA51499BA12BF981EF380195E1D8BBDB2D29E491867090B9E965A697B5E5AE1CF087CE91425ABBE0CE0A5AF62653F1AC1EF5C1FEE6B7F332FF0876353BF37596D0FD0BD5144B2D28DF122762C53B0E688BBABC6FF40CA6B59885C172D7B8B03DF7E9EB847FC64437129BE6491FC9F17844745181084765356218212331443581827422547478716583235137304142402455774301672220067702281740345182635367206821152585408456654052728583200823033372154310824870472281817357366180438076076674475812436718415054614482424484278483046206360807771787771054735117481860335283427845150441828024348673056854648847118566408478657304738565734805614324307071342515464763053856836203744407720261127508640865603645571763504615240651218232156110531767574417578488131402811708672300570030415207614860486716278605250054542784421203140032858080104483743443502057255687503365145364325545780515742727205012463332228222545378481253257774532743251224012706856360000657410838731676482345513625233382538338360685487381801863581234163171801118480454512304805870580353572172486653225874875432158856321508853750572842660701771844633807757246836606614711553870048011642387468317806408144712357547215517244347457800162502560134340120227860884181180845236075730547174351241070547148484732728430350804426817052716534122672621650022564668418360272021232568277144644726668188641422271467488778515871817362810073182218026675237214022420675082370102767463268407376823612174601552176822253665808322107310413688206233547728348046326336582588831571550353146288604673611722768507738570106650282730540010814825386303560441675734048647887803531221650516815166201144723144731234257121763440850075481006600576245770066430232611184655640121061423732475158340280276165264230773851076665813040613203748418653067610885602255487480571513758574384651854415626417420543166747785171622576046385374026360446536560323364081514531124255163224126611340585256771327070023233175712863557000643568748470265527880027314325564436741673163013613563057262677350520653061006868115275687721800851442668541753630261381875745384251303754538638404618280501713206120252623514460810823423805714323631500120804284855515134331476516481847486650288541442660882611657005023631346640283306348184686066537312548854776538144604140728572838456414638133171874875422240152881130760145071162647006611762068256704854336802543356764210411586424602276003305764112061322443824572765215233587274448602602032341352101470571466720431168327107605723515030588630603022537525532211385730001520137417308382054521477265701811070771684871876723563513581351236548745640701728104731485470714068785004725608360521461771588538108418144581302136103731866083078237762606701124574620400076086186400026430204242416313181665824713128874033465213378736357151255754782458148571410206886244328708502561842137167528742821045110640483861757763044035404758481557643071506274125252625457522422851864812233285804123447364523664267670644684325263185521744116250655620038007410050478715435430444716138012661608280614268743443256531360686636133112133285152162217110212444684675883403052787004876652088607383057786732820085417285882C942ADDEFD289558DF68F84C5D3EEABC4272F5977AD513D3A8539D23950C631FB6FEC0A49A32EA5EE0B732A751FFA8281CF1C1D4A278E6F9C87F64D6D7DF0AF6DE3521AF8623512F6E27D4EFE4A716FB72F483FC9811832A56BC22612C7DAA2779EC83276AC46D188158D448FFC8316E526CE5194A2F2AFE14DC009EC89C712C705017E68EA63E9FD3FF5EDDF24AFC4533190A999F2E3909B93B0144CECCE997B32EEF929D73635EEC938BDA1660F58D15E5D9241C6061FA2DC43BC8E282081E324975DDE1B84C32C1031987B8252E1B2D3047EBAF0206691348A5FEDCB7988BA0D967D7FA8610CF7DE3B08A8BB536D2A80C75D74DBDC6DC1383A74B936E5E342E3F425E64660D230779C1BA1AAE18001BFD14EE3EFD849FDD81A561CA83F31531DCD1777AF16A8A7E37280D2C9D7989198AA342F845BE6F3FDC99FF6E4A2CD7E5DEF8D44CF72CFE0FE7A659ECA1816919613B8BF2255B77565CA0E332E18959EF7C4E3912F98BCC325AA4341C079A04C0B62050C9405F4E87C52C829C84AD60CB904B99B45653D5BC9B7CC96B4A8EB2BD62282F2B58A2FCDD4F48031B355B2C5D4D940B3E5EF791277D27E4D9E91EE5C1DD53C5F2C0F77D0CD693B80A97D7AAA4CA942D34879430BB0A5B354B51B3D61B47CB9C53339BA44BA39F617E28BAD34125090052479A275F9C9F787FE355C4B8E965EFA9EC3122CE4ABEF743361422AFB61D4136D5D83EC2476A17682B3E16FBFC14348B2A3618713F78BB39F23843A5FD50906920185AD1692597DF722B6C8EAE0324C615FB051474185ED261C1FEAD15086C88FD18A99226AB93DCE1A11C289B91B6DF0D7466B1AA26880FAD838B520EE9EB1753479FB5E9D17440336302A2E3B12A5602EAE3D561ECF7580B4308852BE844FBD025E598D3E4501DA5F0E4E8059AB05388505374F5EF6BF6D587AD79EDCE255211F91878B4CA75465884C75801995B4F21A2AC32E38DE736FD4D1C9C165F4C5FCC8F9392B768206084F4508ADE4AF5AB87DEA58B42F82AA64B03E32CBB5DEF948A14B6D93881EDFA5890291018F7BA6CC7148398823CD8840075A3335B5E0B1C164750CBC43D852C4D1778F258BCF6898E363E368B4DCB4863DF4667FA505557C35EF6150E74862FFEEF1C42779E870FEF08C55C1B7DFD433CAD4A6AD2DF25A90E840C07D5695AF96120BB6A41D48D4121E05FE703B1F5C8343BE403BF30868B215A36B9E79141409A0AD19E087E39AFAC1102A7D7A2411B4D435E4D731E6CB826F727508B0E7B360BD2AB2A778087FC0D6C2FBBB171EBF7A0CC40DA389836E895A6E0AEBD0BC0101D1E10BD7FF82DFA214631B38688BCF620F7188F33BBDF17CA3FDE11C60D4A68F62C2FAEB9082514944C93E31C69BA1446F4DA0390C250DBD21336667657326246A4CEEAB541803F7810FCC2A9136A186319E8A164D25EFE0CF08D98EEDEDE98BC226826F3AEDF19F5837818514E15960757F5B705FDD106E061BD6777A000169961D5800E5CFB63F81AFE396861CF87271C767DB3F023EA090270D46E4566533590CC29553316C3BA34655CBA17EAF8227C14A87019324D843641D3AA9E08BEFA9CBDFE9E43693E10E3CE2989AD595B1C279B971CB03B02644C8D205AD9AC00E52C9D66042875ED8A8340CE37CE026AF25B8ED1EB503AB1F29EEDCEC95C1053AE4CDEC7987E1AECF5FBB61ABCCD1AB81C38A674067B1D3D1DBB587BE58F0ED4F390F329ECF85EECF686FE7FAF7B065D14AE1AC5805611EBB4E24C609ADD608864FB88339A7C50135BF3B9FD149AABC7B812D9DD9902884ADA215039D1CC6DD687207BA91A9EC8FC2C18C15F2A841E2C7539AFC58C2F998B8D6F683B786F8A0859808150129BE0E57F7FCB39D102BA7346527F6C24DDD21B021835B32E094591087D20E0CA859159E033BD06C7ED6B76D56E49BB8DB788FEF5C3649197DFA25572301076AE65F3CFE0F135B8784614B65C458FF7EC6D386F10B673B5D17E5A2CE710835E5504902484DBF2D4C99B66821F94329F6159DC50B5F9611356F47FF4CA62C0BA7EA6CFF3953F68B3A2C4161D63C74AD4BED2EC2B7B57C81166016141F8684C26B7F7B7A6D136F1DC6669DB16215AEB0664B322E339AD8ADEAEB2631A18E423BD66ADB9DA0D7E29210A82F41EF96654032378DE32083A9DF91D237A69F7895D2AD7EE5695E498D7DA5FCB33ED831361A3AB049D36D605E3FBD7F019651467D06E9D8F14975EAB9E1D30296FAADEFDFC435BE54A23774D2D34284DDE0632AE5BC3EC76CE59675494522AEB4242F296B32D1E8F71B9255D7424CABF83377F94417CB6BE226FE2E42B020EC0132BE43E0D0F0A346A8451AC76122A44A15DD801573C704E0FEB63E9E5C2A7242A1BE0D3BAF8C887C05E032A4E5CF49C462DE9FADF951085420FD67A5E31AD9AB33B8FCE6C22C5E3CFE8B87BD3A13CB921CA861315C7714F96CEBAE615B179A62AEF869E81A3A5A16AA6C5A7EB6A7025BD47D1E734818A539AB8AABB6FD1D14F2D92A22A9977C9DAEA678DAD360EC2B7E8BF72A5EF72556251356937F6F515329887914D81B66FA071C538152D75208B58BD381139F5626F5373A6A319EEC4C79A37F759F27CB2CB76D18CCF5185370D3058C9B9571845554BD64D87D5999CDA335E3F93AEA99588F2BAFBFC9DBA476B06ED3A57D8D913C46FB9734A4B5FF97ACADDF5F6E08C9273F712639633A04C7E7B7CEF00876AD865F2895680A808EBBE6E8AF85EB2FACA81C33E4AE8097A9A003DF4161640CC96506F42227DE85E93177100AC01F05A6E5701FB8841DFA529B35507442480B00088C5C60026AA77DEF2B81EA411C88EA6770C5F849528EAE68F1D83E2462AFCFA372241A988E0738514AEE3F32723EC78EFD8C04ADE28291C309B2217D251C19BDF9E051394414E49AF076CF8A5DF9BE6A4C7825839F1805D3DA89EB2071B9E2486FBEEBF1A5967F1AC58A072901B82DBA4D6090E4A40020590351837EEF6CF6E4CC678F3FAA67BE1E16740E7FDA873BE73C71ADD485001D002CB3DF4FEF3ED277D130BF66D8C4106491448C10B8C402DD50C95CFA53CD8EB375D64E5E7500C66932B33E0A1A1433B8FC80D0EDB37004A2F64A3207512CA591123313DBD5C0C5D99475595F2CAFEE7E9BB138E518E679264D977E2320CFC59F467D889B5B4D3756D532C61BEAE3199EE83D905A440BA311D8F8B7529CC0350BEAFB908BFD7BDD542F6FFA460D2116008F16F0471157C117982506D82E13A703EB53544A8783484526D8251628E1020DADD2F502A5E70FA9E90BDF1CB9899F79B2F24BD5D09DFB876B1845515D947F8DCA2EAA40820556D16BD93382DD3283D98BC11CCE2418C43A35E07AB307766206C0F137254FE736F15821E3AA07EAE299A33C31C896C2569BD39D2A0736ECB396FA4AF9799180C693B342A56D7255659F75022E37D301041297377C228A367A8672D0FAFF459A0DA9C40BFF60ECE85782E991F0682DFA73099A87AE293860B143EC788148" +}, +{ + "seed": "2D6ECBAAE0E5A784B543BE58A0650680AE813A01C7E0C9FE65ECB32A304DD218", + "pk": "1C2B6801785DCC358FCBD37F578673850CAD84EFBB28ECD828783DA9EDF6503BFCA2420ACE9FBA45D4F39487658C0AF41E5C876C107B772C7366B70DF124C15DE0029FA1F002EA566AF04441D7C7E33DFAB7936F19F34A73AEAF42026E4A7245D6FBA3C21F26EDD80652442522019A72E586BEF8C655AF4B3E6C6AE8B8678A81AE39E3A4D756AF595E15AA8C4ADEDCC4E5BA4F8EB4AB5BCEFAAAEF15A629FBECF7BDC657910A62E5E02E3FA3F1D7FC4D94EE56F252B53020E325C25129C5C4501FDED83D071C59FE6454AEB1271161DD062D0308D1C515360E3DE60C383074944762EA6464C175F7A9D317CBEB83A8238FBC383F02E299EA185C37F259EB4BBE3A9B26353BCA9A1D877007A48B1BE4ACF21AF2B6D1B27EDD5C3DC2A77A17C6EC0A9988F2DF6EF5087FB15D482439D26CF63256ECEC16BEBC92A65A112C2A277DAB80A0FC49A18873F9F62E48E44BE451C161D5DF260EB14EC62083485CF28AE98FABB0008FEB12B0387AA1BA88E70CA703F8E2DA0F7DE8F08419FCBD0A5C120081E0F57A91857D476DAB4BBF70B3BFB7695B48486F3E8ED074B258B930C092F73D749E2671A9163F631B9EAD06D631BD8325B4DCB40BEDD67D9CCE14963C5D4B2EAD21EBEEBB441936039F99BB12E5629D5959DFA5627335757A6FA6A2482DEF787BFB173BABC595DF3D03477F8CA89B82923799BD5A94329CF9B1B950260CAF3152441B51B576C5CA9213E8AE2B34858BD4BFCC5642FD4A65C1F38F5444BD0FAC0C24E6D9AB20791FD3AE3298CFFA4B1F2C113CCACE75ECF9A83015C83ED7C6B20FA037E83529D8182A16070C6AF08652AC7F4190BCB569A7BA00BAEE9FCA16D9B0485FAFB55F048EACCB80D72B34299C9820C0D3E06EA8B08F844D296C180D7F86AFEA7355BC0B48C58A65C55F7582EBFE9D23FEA305B645F31EB1BC7C158F3D14D74101973FA0975202CCC83CC962B2852A409E6C757427E9309746BEA177FA23FF5DAC5ABCC5F85A8D87861104B41B04AEF79C31C907F9774C06C2A4CF36C2E17829149743455E419E672F744C3A75DF01D6239E4492E643CCCEF324FFDC0E42E531E28D98E9EB41A5906BC6EC0C4B41ED82CA86262F768D89A3C8860C18F1B42356ADC9C1DEC2A311DBA00F7E24688642E75C1325D4F72619535302B520660EB56BBF4E7CC7F35EE8261D3AD2174EF0F5B5AAAF9F664B61AE18C5368F080A9238B6D4F4047836C9D784B95B84BDE8AA165B3FA5E582A2F24AEFC50F1DAB9FBF666E4ECC858599568FBD3CF90EF6F23365951A00F808AD1B8B6EC09084C97268330A5E24F4F8F5C73D5C365A5F88D1287C5E37076BF79D3CA40EED1FAD9DFAC8B7A954CD58BFB24C200704E19844BB47F5CEDB184AF2939341D28229F63EAE74D1AA2D14550474247FA3922D2C24E40A5F3A765B3E41F0126DF8A494F8C8EEF43F05E8AEBB1FC899013BC21B764C33CF4EDE643055DE39AE5394C570646828AD265FCDF37E0CD152DD07ACBA5C28E57BC8D82D871C49C457DC3CECE1758EA883E0E13166E4B82262492136FC221A15B9725647B10663ABF3A3B589A73226D8CDC97B7CA86CEAB4AD973D83F85190CF0F50938C1E11D3796FF3BC839308C3E8D96AE71239CE9C189F7F00DB181A95A5F59D371B3F238F456D736AF7A948D9CDEC9AD6DAAED77E47AAA925D9EA0B0B4007E6FE9078CF127729AD03FA43789F38D7277262502D17580A2586453B1C38A24C7F5C59D96500FF01BF04224A9A868264189DA9CF4F3508B145EF402D217CE991419B68E5A82E00BC46DA3149E392D042E785817A41E33C823F4C6D2551D5EB03E9EA862CD175D58FFD1B5D7BFD1C7AC8C6A505D937A36C89A60702B7F64345D13D82BD29C86302AACD1B1835186C5F3F56B9E44E085106CC96907A332F0FDBEA742A6715BFED95D606C9F05B5F37F8F51BB049BA47DBD5EBB80739817EAF3F09810B00D9702A91077D60A09E7E70562EA84492B9DADFE4B8DC957727FA2296A97D24CA5F065F17DEB081395DCF58033AFC2F424A0CCC3220C477CCD627AB4E1D7104477D799833E2AC49AAE6D055C97D32391F7C138DAA8CA142D33CC035E4FABC57F3D1B0D8F93468D08BA33BE80C820EA5B3445B4E07E584B42DC27DD24FE42DA51B410ADC3D8AD3B8FE21C573858EFC0B6E709F91D86F6360C5B7F1F98A4B7D0F606DB60BE93CEAEE79A2112A93D0D6581A58ABE136FC6A87A6FF3D993020A6E5BBC682BB2175C5E6AC38708BE21A501E515CDF4D87B0D1C57ECF232936A78C525FE54557695ECBFD0B8751BC299F0B8A98979960939A1C88F3553A98A30021D27C72C9B25D274D642D50E0B438A65A68C6A2FFCB3D0E7CEFE9F0F5722E033F7358D7710D18A1BCDB12E4D01E3E8A580EF1A830DA29207ACBC45FD589270A9A82D7E090406C60DF24886E62F3055CF4E9E2D03400475D226228DCFCBF396868B1E79F91ADAAD9542CAFF5FE3483D51FFEF8CB247F2E90F489D0066E40BAD3D00222047BCC934FCBB4084D5D6B0397C93DECFBDD0D22CCB2A04ABA3DDCF8E6BDC4BF271EF1B55F808AB58CFBE7B8D27D334F0CFB0E2A8E3926AF6B584BF746DD8E7106EB4D0272B234A48707A9731159BA9F772D1BB885A8BE43CC527EA6F304D1CC25A41F876D393838C13D3FE8E7B1232DD59C553977D86D2F0634C9061CCCEC779862398D13753F046CBC1C6BBCB2184D3B93EF6307D094600520A13C9A61CF8F24B966F33A4E1D4A63129B", + "sk": "1C2B6801785DCC358FCBD37F578673850CAD84EFBB28ECD828783DA9EDF6503B2A3D818FA1632E882FB4B102891F36847D725EFB265104C96C6249D614CE2DA2FD15B9A2915A14F0F18067A2EBC07177869430C6A3900FFDAD11EEA8256258954C53CDC5092E082B959CAD36E830534AE598CB9A40805DA6AFE3A33C781B67682304811862666262674883630257466336654176127111610188405651882248835621772103713057301461408544446057187771006674605835060402676635418131476413436003120645277455515485670383644331501872624770716378003605043343662173545134662807012482221028367326430336535664448056113574018581120523841166041143840318651156482606328312581566713531544126481316674737206548863641151137443513805664368650232741372866237083842038500867032145440548358704527308541843850274876810732814453828163568433334252171168355156128245552322375020411688726150257732451832171850113208171275024208763087043620431368784852342633345325381082054768367221670638442265455241150542031786524420340504232434554630307202834160338843770683236510173416158055663006632524311202770074186756864725651225115207874172102767108723215410126544502265753858458031284223785244845208708477813813164616574044334063467141642437824662515130780320530524304615455323331052410022757028285822155463465307887721528548442757207157143662703603322523164328585723017213078884661343736471304300711110210007661410452167826762283616602211111814737670478671581647376618273266215607470650400468274107273140772805621181485466005826678168630861123665356648222147531357331816374484742736281012353528830064601303473326670343601815332320656614136537004121661334847127484167341210426215347444665228633775855605113481362562501604066143748138675085214380117534354518528803214733100542576016451870144542343240477121026665084103270221073287781215258026275727484778353836573535212634148130745855242442608642460711873814258078850618877672413774513172426032072356862074508810306014067080867427757824824028824108174406026218102520624880108734712762825145441131055432206348270026562148550718452404551485343104823587357361075363067777608700730787068538524620734084330357617168267260432467052780270082138751130213247302351083133755083746701327633651771612817385522241687365428627888010160240244451556860642616888021741676615122361567710825223512105410650126041326541401456171026106665284806160355012356447348246653058504148285820087475110160353520303780551734644523605167821608646410237607101761118786078003148446280063422132668120564163088754007557568310505200680472867527162330302442631523115778167707572822871262554364140832017606753138334338852737720140605628627473251125862002613337020675245162661260861007155034720455157108418561023828220700355382181424101273721445815451858423724440784253713785183511880022873741854405034651712631638575532026648282103088505253625664346403781263188161174460770820772032382661577887440223154505470856385852111666161268622021383012686823504876281517266854274311810301526324508130485562286633448201880388745815358336710062432506786440757406072140568841501477456514813456204417571574122527482775515235688833535654757407187843821823872746421510747450775537360482055485647333021465B68C4EC5CBD1447A46D08AAE37528E592C1BABBCC9F5FE65F159E1C54AD88B07A7C424748C63C42101D44A8CBC87510BE76B9F61F3314BEA466B2F7AD9C7831DD8F077ECF863AD498AEC0735DBD6D0A86F2DBE80487C08E0E15D4F7CA9DC09822E3A541D65A07BB3BF9C39AB410EF2C0A2F707985F8DC2A72C9269912A3282D6D0480D37927959BAE33003B5A03A2F82850BD15266F977EDEDFFAABC2B0BC9BA8C550B5D7519806A574BB1402812D52D6133845DF5EC6172352C2FF5D258D3D5858A2EA5EE606A40CB2D76F461980816BF6A536A79D1667AE5422346BDADBE2F6C70FC143AA30F4C154E22E5DCFCD641CE01EEEE50F42AD9BA102FE9D8A186190A495FA807A5CA7552B8827D90FF2FE48F8F195391E358754A3B032D155286A324CA507F16A815706A3A5A1F127E134BC5B5143659E4601212A46651A4C7F8823AF02BE5E3E04F41F47259C66B131850A7D9B0DBD3A415E078625127DE9F1D602DBA207C0720F3F96A44D86D60802ED16271AFEEC041FA8AABF92209A4D9E53B311956E46550E4326A5C50CCA7AEAEB692176DBBA39C51272036B38FF92182A22C4758D1B865C1BBFB342C1F9407BABEE19DBFE046E122E18CF7A25FEC6A28CE4C33C121ECD9316E9AF0016A16BCCC46CF6329D878F48990351829BE43228F200656D57813FFAC51DC487A86F6858FCDC46910024AEACBBA199DDC66963D914E970EBD38F18EFE709BA2691DDC8CC272095302BB2D25657C32BC64915575B173085D920AEDDFC37177B5FE4F38ABCE426EC46E0723E00982FBE5C7E8E5A4F26540E37DC39E022DE7A08F13B3E9F88D05C30C8970899E2C3FB898CFBBA00AB8DF919FA51CDA3E8193F52B8390D7C274C7F5A344EE42312B823DB36BCCAD37C4B213011F0310DC9BA72B851658DDD5741731F21A6CE7F9059872CCB9ED69F732B7410033D8B5ACBD66B33928E3A7D7D5A28E3245E883A2AD84F7C2409AFF0402E982BC95719C10BD187A454DEFC7D3693AC537ADA62BE47D6681667CE11F9AFCBD8031F92085400BC086CB4B61FA363096DF205CAD59F6859667A9BF44888A0BEE5D4B63C4E95AA59F02C2AA9BDD02519E1758ACE89AEF92F32789656E071BCB10767F2727C309107847DE2A0C06360DAABB356C35086E4C95AC668F0F4760F636754879CED6A1D569FB11E5EFA2802E8B1C8C3935F6C5C097B96EA478143C2D2EA5C1E64FE19E03F180B70F4EA91FA327AE0BA6F4C3179570C62C10A7AF043BE2419959F53A31EDBFA1E091029F96EA203BF98E6798D96727DB60909C09A9339FE71CE9E4DA0BE641F0E8E53B43277EBFBD0682459DC028C6F7C042C1CDEAE9DAC9511E6EDE9B4927454EF9BD651B233606B644BC2DA0B29500B0890D64CEA0EEC968146C5E5FE395087BB4884F0206455290BA892B0D929632D098C33C8D6E27022578249C9DC0C207409799801ECABD7CE84729884E8714A19A05B9C7C8E6D203400ADEAFB0CA2669C8241914F85186EA0B50AB4FF646C5D386FCC3F4178EE18BF5AACAF6B1ECF1F5F894ADE5FB8F5EA336BF88548102EB3C897AF6CBDFC7A6F6667E075475359840328BD9131D2D17FEC3A9034D3C7766110EA3118161A42D3B61AB5AADC71352BCD0B5A1DA9CB741F70A6ED9EFB8ABD5229697852AC27C189CCE811A9025BDDDA939167BA717F1C3EADED18D9FA05C2828673AF274488F154B63FFBD853AFA274E182D83D37C97C7090BB9F2DAF9B37862F846C46E55BE02AC19D23AC0760E2B657C0B1B134FFF3C6753F96EE8B2CFF394B0F5B50CB77E8F7614664FB3F0EA8BA85D45582A71F3CAC0DFBEEF6848C63A270DE0D2696AC4FE1EEAA781349B02614DB517807CF4D2B0AC80FFBF0160CACB94F2C700D57E156774D85B52F5245DA4DD8E4FBD2B9DD1B9256FB65D538582CA08C20C289C5AF404349B12E5B3A431F53194E894A45F7AC68FE4A0BA8FECEFF0749ADA4A9B87D52563572F1B0594C62586BF28A821DE955696AC76565861F6F44A167534232C3EDDCD921F5D939284DA288A8233193B231905C76CA822B72FB04C21B4D7011D4DFF88544C1408FFB8159A597E7C4184BF2AB570C9CD7C0B8682EE942B864A52F4B71C6A79121E16C40DA0AB4718FD859598A4F52790835A5D87018339C221DCCB8011796CA373C9DB8EE2926046B0BC01C4CC6BD84E824CAF382EBB9D2BE3F8366100116F0234CB3C53CB418BED8B8A530CFB64832C78E6FCDC31D830E894DA330737C0D14EADA335E7BBA9E270751BBC0D72A137F3496D3F4057428F00C5E8A6782ECAE0E48C3B0D1220F2738AC092793C18FD30478B57BDBD2C4C9462A37B1639163BDAD2D9A11C36467AE1906DFF0F3C5A7134D09168DF7811FB2418C43D576CCC191F0343373CE73432735B178BB122A9A65AE84B27EE42707895C6412A4970628DF736082D11D2022C08C2759BB086547148C885128882C0D716DB047A5821BC1BBEE85E4AB3C5B8B40A5D673CE74357A475D47E96EC40337FA16C6B2FC3F09EE71E7FD4458712112412F6549775D0F66DA948E34BDC30FAA8BE5241D57C48DAE353CA3191AEE310A055850A266E04BB78982D0432D84531B0B20A2B3D238C2EE1556468A193A9A032657226AC726D9757641829615989251393CE0171AB29F94C1D583ADFE35EF8B9859B67364DFD3EDE5DA27CF277680C65C0589CD7F715727017F02F14CD9622468DF17D5697AC895AE8D46CCB1FB0DA103AE57A97F316BD0179B297061F6286C07294C55458144C6AA2E1932388362559F28289B0361EC79A8D81E6C77E7EF0D3327A85ACCAA082862BF5D99DFE89243125A9BD7BB2FBA35DB442E41E1DB8563F54AE40D444974307F410CDE68CA0BA9B923F82D5F181C141F3160A0450F57454FE6DE530F8661D49E1A87883003C5D1B83E0F21004E2648970E3807DF2B865BB961242943733938ADDD5D219B7FBDBAC5ACF5EF250A67A0923E8908C265876E56907F71FF287A6C16F21F61424D72F58CC468D399045F32083A17736A99A263E976E14492A6791E1EAD4D568AC062168A7E85F115CDC302B567E66A6FA7BE6FC6D6F7D4E8751603079A64EF9E46B9EB1DD50D94D0D85CEF2F7BFC58B5BCC193555D4B83D454CFBC2F910FF7D6E22E9A27BAE8A95A229D79C64BBCA7F563DA32246BD8C7B1D5022E0EDCFF163B03E4A3CBF2ED74409FA652D82311A753CFAFF4D9EA50BF7D91212E60B23424C90EDBAE25F0202D71CB566D6C4E5106C6D618B8E49ADD7156561D11963D2A1DD17A7C2C00145FB0AC9673788D8AC7886470719E405BFCE819A7083DE2D841FE616078208EF2AF75B38A20C61573A4094A6826DC2AE481A2E3391260BB9F01075258B7EAE81E2CBE387FFC018EA827BCFBC92CD49ED433DAFCF00CE55812FF8FDB0F566DDA8C6F7942CF7A9E07E2BCEDF02D2AAF40A66D0A55912F32A1F1D5C5071DCB5EB86CFC576791FBB66B5F0D38C9D2F2E31F86965ACFE661A9954F3FA8E9652988D0D2BF72" +}, +{ + "seed": "3199830796190C3968520DAD86A85B677558A22257E43459AC684B68CE336DA7", + "pk": "525654293354C2A1B9A2A76C9A4908CF2361EFB2312F8751932347FCB8153A473CF3EA6AEBDEE745DFF2CBE7A31EDC4221052D97347909F0567ABF97ACA00EC5FB1D9044A346866B1D7F99084C55E01687D6482390FF78468628D011FF6435C1A0FA157A895AE77B1745E49EC365F051A461980C4A22715FBDEA55972D41FB6549BC5085E175042CF5554C03D4179095625449D7EA256949E94469DC1E1BC3D5D91F2DCEF107EB8F17EFDA721EC1D1B0F6BDD2DA9F4B628B4D467584A1DC37F33D4BA326A6E783C562548EED4891DDB715072A7105CD1F65D4E5CF147896E3D16AFC221CBE3ABBB3633709A91293DA31A0C351C9974731FC48D72BB69BA69A76F06EF17E3DE3818570809848DA31EDE05D9BA734F898F38058C8726B8E08A22CB0F07482E4E96CD9AF73C9A04A16E3DCAF2DF45DD49EB0AA4B0F263D071141C0AA08CFC61CAFF95AB9AA4D66C20FCEF62F2E4D7A85EC0E4996AB14DB4130BCFED9C9465BC93D8C424D1904A732E5A198D183B7184E0BE2123A135139DBFE7721B5863B30F8A99FBC5221F1863CD22BCC710632B300C8A667C702E091807A3BA8DF2A96A072C991673851B0F30E0570A68BE0D1AAD7910E68C40C240A6F151B559A970A1F10A81A91FEAA8226389C9378B178BDC69A4DE7AEB439007741EEBB06F2C57BBD01D80114659939715C42E7CBABBEC944E40129E4C626A53CB1AEEA0D4C1EF556A9CDD6411010227CCCD4BBFCF634B2B59FC7F51E42AF50339ED2BD88F7D7840CF2A26CB5F64B1CDD1D7671687400219F4291FA480134E3BA5CBC8DDBC463E552F8F92268962D97154BFFD77C061EF9C14D343F49EA0BA241124DD41211E1B75F6C0623CB0822E5FAF8CE10BC07E9AE9441BD50F4AC7D79846FADA78C9793A55BBCDECDD98CE0A669665E33E0A8A142CB338D05CCC9F776A04DF80A95AA00775D52803EF71A57732657EAB19493C212F9EC961EFB24302F32A489624CEBF07F23DD09412045A413C67FA16592C8BAC0C98A5D5476EFCA9B6BFBB38E87D301579F8D8AD6DAF8B2C6B9DD026C19C931C42FF9155DE9D0959F30E04463F264FFC1589A9DBAE3D96E247925892C230A6200D446FDD0010BABC17BE23EB98183ED8E333EE2837B43895E5378D3BE60136696C2CD55DEC42AB817844E77E430964BA68E700B766BF046655954BCB9685929C018B0B3C7747B8CC37F1141AA9A3B190E46578FE93DA3B44BB48F339C861FD4F97BA0B0B4852F839785C542E4151D9944E26A131D5C248EA31C9F41B158F8DA5E025F3AEF3D2A15386BC095FEFB360E4818BD76446D5F0A72FD4954E5329523202D7C05EFAB170D185B2BF0D32BDB32F33A7460DFBC4ABDD929FFA5FA21340A5EA68DFE1DB724E0E9FF2E734FA6A11E5FFD61F086C90ACC6EDADFE8DF68946901C5CCFB5A74CB6B9CE8C490709B0834605FBD161839568FA1413571BC7B350F78F48D23F67122FB629DE30A85C594620B92284766F9F2664C7DD414F2933E0E62C0DA5E48A8C82E34D66C559D9BCA52A06E55E42817F4B5AC06ADBFD3B06433442216E47FBDEDA317C50E2107E8D6592C0BDB963DD4DF016102C8BD78C5134E9E120D0462606EB5E3822D00D235AD9C7A8CF169610C65AAD5480C45E2D9D95C80ADCACBAF5857F86FE4CB5DE389ED1803B05FFE13F724B02FEAD70E900F3AED263624AF0EEF24DDAEF803AABB07EA37366323B6C306E77B81B00B3A5823611C803A62C9287A09035834BEE86ACFDA3EE3A3FC69AE707A74C37CC597AFAFEDDC3490E4F19CF0195217DF1BCD3E24D1BE5787C6A08369EC6867593388E2CC5677A10CE6D9AF6C0FDD970F0D484F041C5A4C2697F92E52DEF895ADB8194A11711F055FB06C5B9137D446AFB847E562A1F5DDFC6F17DB54DC8FCB33C600EC7BD5045F8EED910D2D19D14B422EA6C1F31D3AA272C2D6E4635F38AB155FAB5C8595F5A1ABD240150C1D20DA320A7702A499BB3F51AE6DC74240BFED48D152FD628E7B2854F894718D3B5A94A887B12BFAF7456C418A83356F5D0ECD7EF4955CE1079D4781BA21044E64E71CE375B5AB6977D09957DAAB44CB2B349670B11C3F740E85518124332EB859718719E4C3A7EC3EF474C0F4EAFD0C104C1753396E8DF1090E4E42A4900665BA62434D8F1D3E3DF25569950E401205A3A8649853EB34DD026D35CCA312C5D05842D2744B643728053A93EAA878AF045632C4DA0986AEC5F4E5E0F93DAD38911A8307622A2EE9FBB93EE62B7F2D90B222AB0D23211E71227A2152D6DC2E536EA0F8118464A9C8F9B1D85D6C10BABEA6FDB2262595687ADD404C4C15C4C2189BFB7660C5CBA279EB6FD85A4C5276005C7EC5B3765D299783E926124597132D7EB623D665CEA1DB454578985E785022F680BD1439AAFA60E90694CB720EEDEB301B9E948E424B5D5B4E6D976B6E3BF31029F346024DE71AC2C2B42105FFB6054226FEE8A80C2471C052C3C07D6A4CF749135E03A0B263576F9F19BF7FAD0FA16F39A3A8C4335B0039A197C12465C9C9D6E5D5964186FB6FD7E7EC615F1DA758F207ACAF8B219B256CDC6B5200B64FCB9CAEF6540E2B4D5F382C9D8682B72F3D359650D74E69038527A215221980B30AC3C066F2198F781D1D318B53F0B0EF5A8FDCA5D1B1D6D978CFA7D8681E2BDCE2B0D494A30D7092DF7536B1EAF0ADC98E00D9FC718CE797240CF4E3AE2B8AAA87AF2FAB32922E4A87CD267FA2B6F1CA38F4F5ECBDFF0C879E12", + "sk": "525654293354C2A1B9A2A76C9A4908CF2361EFB2312F8751932347FCB8153A47AB123CECA94687F65EC4FD6FC892101A78F01026F29E0135AF71EE700E7C2CBC73CF903B7B4888927C0F819C0CA2EDCBD907067803377984AA4FF3E17734478A57E2B35B766399418F75C7975ACD04F60063F2F0BFCA26E50F070B0A1A195353724566837267013523843061217340448208603377516427785068105543815455713385838378638182068387137202878174761230078700864648646024855062224860686668854027226160574716084705654107343266361631364842553385601555588856047580535034530370012175508353073724842155863748067168114848882320522407062271240544578230102367855236538671440435531266463107672883753384543572436706682450834316033375243560363701823084801423101304218866444185862300771604518682156827233004524227545010242832663758743810826325221807752832476605018480872813137847777000653666127557527716638486160042404864166636102870313548832240045178714184303667865718102217306530807425665255147226317774324026116685410151810861754650667058078686427182806416042711402016888435813707675336867138675385874877012367321122252527373105272488877008643087733704347456662422460586083063645404228215715050611018103186084667757203763065215143246526035450665527055616815808787430678265678120245012578311308256263333860323880466256476062110526427163351471203052665006541664736828465247818142306281443835837182183652107651602852387576021550653670563332605536365174537158126383246523487401623134168384464856206204768217870623261824124585771546525528033177675181171075524844712203858364348868366630338263454740137745641040281333252087128027252246866743284811231073882131764045468851375840422556572064517855348352776346620056667224700385762102065606267611202427345130114347574537103157673262766574536203507836868203424662260332464514814176307376835282323336537583824722072737215563716516622534570868515740510531360567302685310330081808880645123531722346410845162360657713551527237544415554545544676603556376177653716885147033372853404163258617884540527813328211514033674414257460047837602245324068143272035585220146643616441718725600482680403063464864523457642605402244220645225704532847633875702715808568343465273572577521166715627587343885578373673372766332716633554116600462443030006236252146783520750515425417144815346847112732253776133677705301441278410464448741113474825577724608565567664387072414188665482012132181145627744672156457615822101260650685316686216446276142280271565741485500215068572175027842512176043780617184765347663010028034833058116425222513618208124855666167843357777361347708737016118061814685808301052444558752468101207730047385746728811752708526513738756226634713860484428284725564228166015837222131614501433104081222168277767128212721462486143511455718342443083388355003610147772667647654723627762544342374672085384358876058841431863634132804448410306706760647544551074056854262848837436080043515363533205588831716267387132602472322688526176687873184770211636173375004366841185377208728801202224543227412038046055442545283515488671645386881814722167054187675850246200624520546261410308840183184005181485267722758628353566744521701762386445637465210013676767755BF422E848963E128A6250E1EA8CD6994A61AC9A0145EDF10B3F305466E0ED49A068336C98B0567F9FB23C5A87F7ACAF7F22A9CDECE4215215B168AFAB7821266C858A92579D96BA48BC94A120657B5C60BA282A2BCA3349C13C2E56D7BBDA2D0DBB6072FDEA7A1D8FBC9B9D965E9C8DAFB3DD8EBF78BBC57AE218800125A80765173C6C95FB23FFF90C87F7F090758A1DAC96DA7537B8CE57B1E313312CB26799A65E9AAF0387D2CA3DD5E348918B7CA888E0BCCF9136E55EE70903A2DBBCE3476AEF4CF338E7CAC5FE067E23699FAE85A9EFD9E68242949786AB2A2EA82EAF8053E20953A1EF07BB9E22D7847D9BDB6A06A09948038BA5448337264179180AAC89158B68A6CC91507E552AC1DAE3619FD2FA2E0CFA0C2489B3C9AB4FACF1EC5BDFD188BEC71782AA4C3C6B0C6097AE93C7EA5920A832F6536CF5E81D1A222B9B936D5B57BF539014AFB8ED19B076D5C3EC355D06A7B56523273AB4231A4DAC8942D5DDFD58A73F968CCE3A8BDDC5D4F703CAAEBBB910C264EC2079FF75F9417A97502C91DDC2FF5625A3C535C04C8F95FB0B557B6335299DAD717D21A9973433C5B11AF908BF9B88E4B1941EC12E9BCB9F2B2331B7F08B2EB04FC30CD0A99ED2CBBD3DB18E32CB5C160FA885EDF8188FA8716C0FA9232FECFD3EA34330A61465D4E10C25497BBDBEE15070C3EA66E172EADD1DC7686CC32418CC26AF4B2D61259672B51D6E86DEAF4208F6822FDF28D4F3706D92FC66EBFF9E6AFD36D2D18F25292E8175ECACB7465FC04E674ECCE3A62ABECF9C2D1A52171FB411FDCC893C43C6CFA94B1731F21278378EB94ECD9774054F2D6DC682A07980C87F6C37D3C0822FA30334B90DA764856BC84CFE131172E75639935E9FDC42027907FA20363B0A32C7A29588C003DF13DB2AE9C7BD6682B743B7919DE78F8E819376C1D9E64FD1EA0750C335F56E9326E94107DF6E441EC38507755D3C48301B616782A1F4ABDC98BC8585A18C29E80A32DB88EBC3959DDEEB53638F6D58B58888EE0FE37AC86148BE1DEFBBF3E5FF194F9538044036B95639DD219592F0433D695C074CE6E9710FF9C0B1D6891ABF1396B5CF34BDECE6B3F559B1D813CDAA5DF038A949AED51DFF2C2E821C643032FE6DD6A74803E2E2DED13D446BC969AF4A0BB2B973D5CC54E2AEF9896EE166D807B0E41353D6DA28D8F5FC2F3D991CE68AAC6DC75663323080D5688FC6C6DBA56C033896F0581BB8E9F0E9E3AD561490FE9B8702D9FD32B652C7E7B74B74A489B981DCB598B6DC38A7CD69C8F429D1B2B0C827D8AA31860842758AA1720D87B23074DD0B70601FE0C2AB6B72BC4FC836C81EFD49B94AAF378AA828CB90242448101732633D0E68DB2573588809CB76A80066109F6805445F3880A4CF143D02384A5198E84796EB9E3EDEE3C64DE761DAC094B05A4D8981CB54B72C317E4ED791C49159A4E4E8C21F869FCF320F90C0E67B0BC2BA193E29E5018213C1AE8E9D256D8740C5103DCBA8EAB450A6E259B334E3448CEFEFF100D03104F810A7CC5D085FA80F054E4AE67AB242545A818E4EA1F3586945C3A4D242EE5ABE14DB6EA38F50407A88DA116D6D3BAD935A32817B4A24119E9A103FD7E6FD5D5E020EEBBA1390E5151FF456669E4C14EA8E7F343769E7510AA68D624553ABFC6EF2F839AEB4D6D5E1FB57510D3D7A7F0EE969CCB11FB023EF279FAEAEC6CF377B524D206C5BF4E529C315E6F23D9AA4D8229F3AC1A0D77B26F3530C80EB77A55F45AB9FFB9FFA8B8EC28F733BC500BD684D49DA1FF31EDCD20C24231086BEC40E937C2AC1F2D4C9EF4D4274E9F15A6F961820699B40D0DBF4D11149E5696652A75D571C61E8ACB9EA96B5EE185ACFB344C9DE2EAF7F956F0569766EEA44AB42F0A2982F0957F5C70DEB7248F6EE23D322669E2FB3520CE9FC98BF79636F5156D9678BEF7B19F916A8ED1F7EF9D34FF853923CBA360B10086A64BE6BD6B52A90EC48D763C5E00A9BC0822836E594AAD9BF91D0945638B6C6A961DF953F69C4DD75799C7B73CA6864746EC3402BD341CB14EACB6343FBBD244BDFE1EC43BD6A5A0B1D3FE2D896A04FE8419DF95A691020BF61D214E4736EEAF25EC01304E6CC167D8EF969B8E2ED2BA6F5328EF83903C73ADD97CC6CE4BCA6DB63615932D3D0865EF837E335BF54AB3CADFD6EB4A7AB5FB441644AE5748CCE75157F669863CC89930393083D8BBAA83735DE31812E471B9858E267C7E646C3F204250F8D4280494ACB87D82052B0BE33002806912DBF10597CF46D78E8C64E648A0BC8A756D8F09D1927B73385E8E8E960CA2F3679ED81B0461706F4864043D5DF4E5CA59CEF9A484513C86E2FF44C496498EC88C0CC8BBFEC45C9A9E233730C4336A8D4DA876BE797B57635A6CC532DDC701A688AB712C8380CD169FEB3CBCC1004637BCC616B7D300400B6C55B0134FA2D6B96A8AEE0A54FF88895E9A16FFE4EBCD308C7E112E0FD81E64C08239BB95D52EF32266668E4F0F39EFD341B159DE7C8EE179A223D398BA70A07B774C04FF711EC50B94631BE472232731808291AEBFCF6894632B1C1AB119243043AC5D0C054B60883D2083564133FA82F3A46FB59F86334BE0C6E79E201DB85D35432BD1793ED3B28DA8F65C7970DCB9FC6EA0902E9B83C4C8AE86BEFE01D3D5DFBCAB946F017CB2CF63AAF8B65BB26C8D6A5A73C9DAEFF2FD482839916D9D60D3919607CB99A7434574F05FCF15F4F4F03293F3EF2F5C493CF867A4114F134043C5A5CC26F8875B6170C787FDE2247DE3AD7E80610F6CC09F58B66F6DAD4354795D49F994535B4424244F18FC65881F9DDA7900F7066B3CEE542575F13C9B0E3E236E0813F2D7580AAF8F9E564A3AED65DC17F0A6EAF79F4015ACC811F5D2145E51F72A1680957A97D36050028DA3D3FFE4FCFBC223CA4907BDCED64101577E2418821D77EFB9D868FC824D7BE13A28CF1EBA4418BDBBBAEADB54B3E162DEDA47FE29C993488D2B5E41B390BB4895A49717BABDFC798474E852CD8B573E960B44E85A2174FDA806F97A991BF9CFA8260D0EA441A032DD91A24C2AD52F3B8064226B22C73DCCAAD5DAAE55E5FD30FC31A43B022D997E14E71D3DE8A8E1F4027324E22E2A7616FEC4E0ACDEDDC12C04A56B65F0C00A95B8C1DE9B61F7C589D0D8F158E5C9C65439376E5E935CD7B149DC883FC602370D38676571CA764E6E5A2467EF5E775336BCEE1450E0F978BFA4A0B4CF5A72C259FDFB18E54425ED83E6DE7086C5A175729E38DDE3B46E751AF79BDAF0325EDD7CA791F4F760FA7279A7C17CACA8DC172E47362F90097EB36A8CF14DA378670639D239BCDA3A8BAF29B12803CB26891E4B0B24BC61066A490078046F000324E5186C39EFABA39C5EC4AA8E9BE23BBAD6D7ECAF24A5BC0EA0DCDCD90E17EB7B90AE56D12420786F07C8F2EF7944442AD36E2ABCD1E66E694D6B949EC2C5DBE99832271F3A70782CE889A55D93F78BD4F5FD19C580F456E684644DDE65A045D6D64BD99" +}, +{ + "seed": "E788F93DB12EB4DB91993C6636C009D06D503D5331125A2AD635354AF49ED3A5", + "pk": "370D66BF2921162F6025F1784F8CA45A58E6E72EFB8006078785BC023D8CDAAC29339D545F3F03DB0EFCC2AD356020BF1DB8178B123AB7222FF4041955E4E9338DE146932623EB6517BD73687A51A67623F79A36735AD64D63641D2AD2A040E8CE85DABF03D47DC9A3E98CB8098FB22F84C370D240AE0DDD46369D02ABA059E31DDFD5F56FCFB2CB7066B488C73AF6958DCDEFE66FE5CEB0FCBF298CF576C48F3A1DF542B5343EBC8F2E80CFE4A2D31DE6913EE5962A889DBB22067FB377606CC1AC663787C04BA8C2BBD0273D38D71D18BB7AB435544535A60271B3B2045636DEC30B0727C3C527F00DED0F08D372BC985F3C8FC12E1A46FCE031D8A2B5FC93EDADD15EE8431435A7C6797AA343D33B57AFDAFD870A643D927EA85C01CB43AD709B72F1909DF60499B75B0A29445CDBD1211EDA6666695052E4A80BA3A4B22C33B40BEB3CAB8100017807E5FE4EA49E3FE419EC2A86A39631638C0122728897254A58A4571E31B46583A8E37AEDC5C437E27728B1F14CB7493E5698959B6909FFE54A0293A754E34B335703DA5D99D6B146F4C7118A27AB8E1F9DDA161F03DCA0C6408DA273D5517683E5E1F7B3C2F29AEF73F75F5E60CCEB99AC5327F168A283E590E637D33D6535001492DA965AE977212056569F2456C8F9596DA43989D9162DB32D8B2B989000ED4B3B9F87D1251F5FC9EA71780740761711E74D7EFAB8D007B81E848CD2493117D3DCFC2BEDE8F85592D8265AC04B95282A06EC534E056ED8CBE73DBC07522E1E03E160227CA1AB5CB3F08D7BAA56D03F9B7C12DDC71B69EDE3F6181FE721A75DC0931C11F75D08754BB461F4A2C6CD584AB8419B7BFCB7EF2E39D8A4C1292AE9528FEF05C1F5D6C7F57AD50EF626B32EB916501E6FBB5F9A854095D28F8F6CCDC3C8B0D56D6BEABCF8578FA38FD947445C8A486A8AA17CC5012C64B21709EEDDB0C4D5955FCCC688A9838DEDBB005B7D73FB63480B296F23282D32C01601758632EF62045E9DB865BCBBD026F5E560A8B3A7784EF75B37F03D2A588B53B76DE01553F78477731FC4FA2759CA49D03004A722825118A931E9E0B360B2AD76293F52CB80A0311790CEB79EB2ADEB151052A4B8C220140BDB45699C12824D1416EBD2A1A18A16EA70035E69D2902873423AF69E7A7385F1245BF06D1683CE862441914D77DA427C210311EF8A703CC2BFFDC70FF7BBF310ED56EF30EC8D9125755AF03D2809557C89B32CCBBECB40110E0B786567D8531216EAB5CCB8C96DDCF03A3CD7E0E5D6104239D38B8DEA3131716238B2429CC6E02CE3DC8AF757D852AF7CE141E70A0BE92AE640ACC586FE960A440C4089A515A6979345D087C9A31B7F6594782EB57FACF3ABC51FE40D5CD0328CD90A4C840C058313B97E3C330BE1273C27F4F96BCFC066A3476F7D89B5B1609718A1CB91C3580CD215DD9EAA4A95564F42D6D6909C52759B030BFE18EB47A7B9FD72E1AC05C946C372B01CFA06682B48358F48E0D76F9DA3CDF60BDD53B9A09A641E12CD593B6593A62702A1FC7925447B1D7AADA5C8EA884E1D2A9510BC2337728EF44D66411E112B71B2C203C1F7746F918CF4F29033293BE45AD2B4A7518C3055778FBFBEF015E57777BE7A8F6AD535C0985E174AB4BD96CB78F322C2EADDBAB2CAA52C8989C1F3F03F230EEC98B52AC6A0A2DE8C7EB09D0E1B81834B686DD3D9AC1920EF6D817F429B3C314240487B0C527D4FE754A3E0D42D8167AF4B05283437A76D164731B51894F4C3879CE88645F389DCCF109BAE5ECE09193EA6C35DE193F6C68BE0827E38F4FE434A06E761B8B669B22896B9BF891F2F0A339FA0938CC231C37A223D44FC2E44EA78398F452D32BE8314802971ADCACFA737B2B90CF1B8FD3387D4D774C7BCA754BBE8A06C6425B24A0F08152FCBBD0044063BD419F6286B26CC3104416CD3D34FB06A7494D1FEC445589E56E2FD976E96912F72D377E4BBBFC482803694045EC116F4D5CE28AE3D453100F2F2ECB8057F47D41DA549FEDD18C27D79499CCC62A503F4B91E44EE4471D13B89A3630A4B622151EA3AFE335F19ED80FFF32267A32A2FEF8B49E60C9437B7405A35412292B74D3C38C825DA7D27EFC433167AD46AF0E341E8309CE6A95881DE1C8A67A9373E712E95B1EF948AFE624E66588060CA6A4197335E6BA537520DB6869B6BB114E718519BB72FF3F913074EF5FC9CF8C115104E514B22E37A871C48AED07FF93656FC99C3F1F1BEAF5EE12CD9D86A8FC6EAB7CAE5CDF5BE07699B0E801B9B83947C6D78254DA8E77B82330585EA02B42F87329A76CD09703DD0A24E01B1B63ED00926B4F4E9DF2277256A06EEFB77BB04DE09DD8B19237D40F141304BA7DE9F9EBACEBA0A86B0A73310E138E02F0FA284AD4F47B2F7A4F18F0A166E24025201F5449F1BCBEAB76A18832F27CC5650F9B3AF19C9FBB8EDE9C5561E43FA39503155C865BB9FA2D97FB64E8675CB8540E10480A85AD854AB01C94909C07A4A8DC2122ACFEE00450E5455B7BE692DB87A94CE0F367B3E6E40687E50D427116A9DE98B1FEB0AD0042FED0482CC695EE6ABAF5EBA5FB10DC46820643F4C40226197096714135716F74A10888B2CABBC27EF3D4C4A51E18EFF63771B43C5833B3C7577340D9E729CF730702F2AFF7BA8C0C3812028AA36A112686DAFCDE36D5132D4EE31203623224127DF3E69372C45D7B9E0370A3EFCB9577BE0952AF2E4C2856C0C156858A12AD1E6C54E51E4", + "sk": "370D66BF2921162F6025F1784F8CA45A58E6E72EFB8006078785BC023D8CDAACB6D6FB5A7F5B3C55D1B7B4D99FF4A4E464226FEDA9E8C986B4E5F41A37EDB84F87FBD62731259FE7266BF78C8C1622425EF797EFA30EC80432808B12AC45919A2C30DFA9968D2FA70B94C03CE2FE4CB15E52A9B0AFEC74FAA276A5A6C3913558165301232343767500140645258743061342542321447425681352486528374628548377702443573345023511515432272262636387653371116077564331128261673582164376865470573778011771888324265183248748526461364218768355482805103865333082167526282242560783314370341456383857383578161652306885528655175662755151047138555553146534343846644604080124474864542472815033627744112223432243010282717120330873340070542331872402377068660004410221333432814123760781816702355556354318770785856176381340622240247180674627437023487887142122356311528327715685414266201482028121764321760138877428245535571814667284614438305271345087160060677013335670831368663514625548365687250184502508737813417187476721462666327610566282504268562450465824881154630675748446771056374112326181781302812218455007821574286647628015822857841575474420251404400700360143301022535255431143253062813825455084682005502132778411085234725034175400186665763287222312538538408377111638782350433570758668635031106555035670557521681012082802587051366781137117633440736821514153673831736211187582851663268227614710433747764655121055850228627771006367547345372746630418234207825131867834621675040540865400710271240446255678587535712646677663862756162648235733574803251637433612543243468478708540037560522713432554677321560753633540782667588111844775721082267830084100184201347637783057758451023428802706114581247815517568146814871862414358208702618046381513554368158677108340188165884412034464317538338522232138722036733523471141710411066612126271743047838718830351623801480688837684510742872845350422860251052626017351858365885606700612771843631480036820157031348205867520520487765402767737510616772508510833486814641587451664151854305857511507587221816184780048357254801883803628823755313454274573606336453016746307562240318134330413451401315522363547183446584200387332666582654003115726104061523538637014810542557514371810386337213708847727654658851037453520630457682353101720774353267248527376013051436822206685057775611555457025261832548641805611352714453114181682076074007865877368448848734003148417023366531156644485347310062806883886101206088240403774741141888061787233830058632806617875630436082502522148484676107601474733117287574076826454801581084362107263126264670065123516671432478772264052013128365223266326033557830542056876118774244531751804203463628628086531048064586012217077568726234013258648566632205661202682265777756507302764142182572022616275154047553442287404117336235135884581014567433756542883011752430774456756024433362318460726861231472815238026480165521125855780525541506454870715826252784875538606765743657652331856072572662706465271157248031452273677063333062566472476428010820161672272014834502781064534320058730853758777214125800834724680368831480488687653825566260382261818011441503256800555554122412786818455524643670578000882636824433184045576563440255AFA30ABB273C678163F2E011A3AC11D88762AE6242B03E2CFBD09C41F274AFED4E7B529A15CD5D36CECB76A7296FD7EBD5B56C185AEC70357C401FEAE5F89AF063AC7333ECF31BE378348FE5A5022A54F3A202BC48676BB6EA1B284E85D76EA61CF1C09A97584756145D383D3495A2EF5718D2A4DEFC2C8F46AF896B41D399BD324987CFEB50CEFE71170D668EBD607969325C3C342411B647BE4CD2D77653EE3F5F9C0685BE270ED0299EF45E119CE37FAF027EA64B0D54603C59566CA9708087A67B2D43CD438848C4A3A0485FE9F9DB87522F3E552A2C91A18BFE6685D335D48FC9A633301C126D4098310B4B24E1B142377FDFF5B9E55404FE682E8743A36BDE3AE2DF8698E8BA14EA9CB895BE64D9AA061E2ADF95692AE3C28E90A30F65662A33DDDBA2598CF925C5EB9A76D7388BB43108FAA4208565D77EC00ACDF271FF2A3D017CEC9DC5893A655EB6E438714AA9B05AEE119FBF4E18147C2D21357BB68686165ED35550862CDA47A9B374B7F7AA5913A4B502DD3113A85B5A125CED5E88F384A4862A9BFCC42B74F52DD34871C27C03C90F288A43BE6AB6EDB01CAA1E99B311330950E28893D355978FDE12BCC2261CCA37078D4C74ABB70E46F82D5062BCCC4DA6176183B4DCCEBB601D2C8BE0953754652CCE06E599DDC35C3C717BA398882922333D52F70D9021C57EFFAAFC163474707749105460B9061320CF20E7E53686B306C2963FB84DEA297D2B4C4192F1497F369D52460705F25A1C9D1CF428A59020261B100A444FD057F2CA21A5401B178F3795C6D95260673EEC3216A93C128E7B50A6E7C70D2FDAB027D4E192FE36BC45D738CF0A08BA7922FABB19EC4A755C8B22B57C66215C6CCAE9421E93719EDF47929E4999538241D144C68947B5D9CE9D382F797D0C993760F0E42DA8051E8C1709DCD8BCA4534EBAD89C67187E704E22636893E910D10C125A873224BFA48ABA7D753DB4677F2AB120BFA18F8F0493A396128F6426D2A4265FF5B14D0A287834CF4581F6B978C66F306688BA4FCF67FCBA53FF05A6E98F7E288DDCA4A1DFC43A1492F3587D450099693ECD43BAA35DD7AA59513E515C1EAD179C6004D9FBAF3787EED000374BDFF6B72789ED74191B821B595DFAA5D359DA953E26E9B572A040E4CE2172C4B73AD0FD3CC21F2B099B7DC203472BFD8DFD40C8AD841D81A1AE0A7677A666CA8BE53681152E682A18EB6C804F4605630A1429A58C0293B880F455C4342EED532E240D27861D084C14D32469CBC8C62F997C24C8E43D675673C8713CE03F460DE306DD194AF165E021F049541793C97343B1716CA0BF9B5AE4D330985B3EAA44C60F706326208C8BFC2889351656DE62F647AD6B40D6ADDEB7345BFBDCCC14099F34A77D09DBDFD65E2D9CB09F24EF14CAB57AFFA9C5FE48C483F63212821CD2C8C9FA1046594646881D40A66656AD9E0534E3EBDAEBE1DC3FE5A6F96BF5FADA52A7F730411635B3F696448A96EE1C5ED717D13978D6EE381065AA9D3C8A2E3508BA76001427ADEB8E9C706E030AE2C41E64AAB319C767546AFC2DDB7E1E5AC0F51EF6D235C6FCF2401F9DE246C80261E2469F26B8F77973F22460398DACA28FB963AD5FC4715999DA55FB88864E72BEE8415B441521930A00C08577B609CC1240723E565B06541522075446BDFDFA6E21A45CCA5297032F0DB06024B59F347BA50F2787112131ACC9A67F41E81A8F4562BBBDE74381F3142F43759600BA69887F5E80E0488BB1DE61E1169088DDBB188D2464722469C9D9339019FDF3D1421390A156B33F73E23CF9C2E1E8139CDC12172433D7E5B62AB55A88E34BE956CC62AC6E469C4DADDC4A3BEFA5B3D7EF2B061C541A6C8ECCF2137CFD0EF24D0052646492014BF6A604BD3B8E3491497EBC008C68033A48EB54673DD28ABF05137C408EC9051853BCDC392F6AEC82F8EC5CF285B7F8EB7EDA1DD96EDF0B264880232EF5F659EABB78ED48DE3BF7FB439D3B1BC92DCDC1F53EDE8957C8FB244483FEF72CA1F18F458CC5F1B8A15DA992AE5E69C364B59D69E2BDF82B25DD56AF4E34546DD732882E83530952AA7ADD397BB69FB4A5091DE23E60EE3F2FABD5D81370AD1A16DCE0D4660A5488925BBDE4E7F3C989026D8788659EAA0CEAAA8EC16261F255DF7298906D9418B92DBCB4D1471A4BC7C6842321794E3CCF1DD5EB2E3D13A47E5489223BC1A9630AE2B881A160650CBC38E7198494A58FF65F2099B81B44251DEB1D4DA99EC3658366FDCF918919741A4C2A0A91844F4B97F3C135392A9E0D41AE6C189D0D93D4E0F6826D142D2160B9CFE60B7EEB0AA148BBBAA4DA7669C72990F8BEAFBC6ABA9AB11D3083E2C337D3BA6778BF7009F444C122AEF14F6C8C1D800619D22045C88E80FE1E80C505FEBB6670A79802E85E96CBC73E15982DA42BF530FA5500DD321D8BF5EEA7E02B578A16C099ECFB47ACDCBA485436FF5D13009F51E53BE19F457187CE214C7E4D1C4BA0AC68CB54D3471F5B1CA714B5ED52BAA5EF9FE75E9758D1C92BE75B821692BEB24B8025D2BCC2D54F46CE8F0EF4BD81D35BBEE670592184F63C6D87E458F442718C7D5E85BE6F0C1EB0D9EA0238A33040D4D8CB0CB0DEA36931D1D932840893743AA426DF8B9222E80338C15883DF42DE0AA6B837A9BB7ED65F570ECD05DDE4294A4AD23D39588B218ACF34419F3FA581E22B4879093E4B35DD2ED116690A96AF422F10C511C49393FA25B61FAD39A14AA33564EACC82C8F65A5D0227657118527D66F942CBECE1C776E252644B8A97E5A564038E3670C31F3BFE93366BCEB27648A904152FC907E6BE8B6A91103CD55C8000BEBB60545276D595CC738B4A2B1F9E30693FE9D6796DCEE7709FD2458A38856E579347C560F8DE440F2888F38FEE3C905BE51303807F2957932F96A3ADE5CA77E5616A44B510B9686500CD8E97950AFA67680E236A0B5258A13DBF0E096ECD086C74FB5476E2EC7BA929DEFE11DC8F4BFA2DBF21158EF72ABCF0675B29709AB9FCBD2755633BD274AA3D5426EEF9B1F712308E7CAD98CCF4704F1D49CF5E189FFE80B4E17F950A1A4D14FB6CB6B0C0D910BD527F35498A1379C9D034A15AE852BD20395D4302358B3E09ED64724432ACE05DF83C3573D71BC5C168C4CE160ED2B7A79684AE20662651F988AADAE591159A1400FF9B91E13279764CE8C14F293A0346FBD8EC833BB9D6A4DA4260DC221401A4AF80CD8B71420551BA188AD8DE6D9723F49433A7AFB855747530246A4D1128B28A85A6F16B7584D4AED3809F9A2BC0064B5237823FCD1EDDC92C5F24A168AD3CECDA772D8A9740FFA20FF91612B1E13F905B2A81EC4A2C69D088DF89F2F20E59523667109F3664056BDA4A5D70718302E509DA989106B1AD7370C4A9527AA79D2BF8226ED487FB44A5B872DE95581E491B241667C01C4AF5B639BA1B496A2191A23DE453C15F9EEE2EBFC4FCC3D6098E31C9C33BF8908D4A21CBD14302E0F0AEA458DF776D75E929487A623A2FEC1" +}, +{ + "seed": "03D86B249CF84472E3B78B12110E2C09C7428FAB65D362760D0800914696D411", + "pk": "8848322A566CA6F4AEB022CC41ACE242F84AFD48EC429FF2A107FDC381DBB63AD301F719FE8E5784BBC4F7952B43182748481EF5F9AC848D277C819E86827DE234CE3D1D90CBCBEF2725971CF3A559CA903896566ED66E4B452A1080B7E825179882563CD73AAB0FE07452DCCAFC27FBDE1A94D750E27C2A67F1B47397C50BF0B53E1C2CDC2DC13B333E9BE0399F271287E4C9BA16FA122C418B7AC8DBD5769CE792A66475ACB94CC55D70BD7CD91A62FAC1E59139EE46072A7F76766AE4A1AC3C52A0C689ECC001849F5F6CE436B29FB5552FA5F3BDBD662A85EF86228EFF2EE4C9B0CC0FE78F8DA5A70231D6594430A70C878DF82AF33F1EC8C979FCC8777E00E77C457300461CB93E9D33ACA87102F0B217D36556D9BA2C2A23A736628357831128B5BA6B649109972B42B15C563B51CADEDE4CF3D9FDE08B456F7A9F2EF28F3A7F18D5F3CF4BBB6BDCCC98F801391D78FF0511A09DC07CCA1A81E63B08C0EB738E1F942387946D3B3BC7A0F658AE2FF83310988BFD4ADEE4129C68DD665D12211211C2D9582F80AC92CE3F943B61C6C45B935D38B27D3C1C2ED6DDA42FE43D5DF6E5F6BBBDA654C35DC259114D288C9359FD41AE8C2233AF33D991BD283310BFC261CA0C45288DACF1319A70E93A221ECA835A6CB1FEA3EF0CD1837C0C20C51C3C8A6E81A2FA638355EE80B61354F50A061EF5DC9E3F3D41B37BB08CD9BDBFE42A0BB909BC24EDC022CA57FDFA2AC70ABBFA851E2A2FC73E72E06DBD0A73CCAA91F399C72879DFB993F17408C9D8E5B60A6E74C61DDE19893512E63DB8CB69AF370A8D0A91EB39334900EBAA892BC6DAE48D97073553B4A479475EC1AFA797345C6743BD395D95A16B2E8D494BFB306B83D67222B09CA917334406EE4A021D318F364405D74AC23859899B6C758762369A63EA6EC3C9236FC91578C6601ED2ED93F0873026E792C010E187C54FA1CFC58BF88939D295539566DC50600B4182D5013C262889AA964FD15ECC00DCFDF57B2F7513A623A405E31811481937FA6D4DEADD7402CF84D050E4FEA37F5B86DFAE2370B1BFC8B9E6DFAB3859A6AD8712558E782E5D5C41206A007D19D20071E925EE25E8F10A9F04B09F03A4E1AA017A7779CB13AC5D67AD0E45F32C216F60897DE2B77B2741920EA73DA07ADA1CB1E3AB5C7FF0841C8B4D3B369DBCD7E5E705DB112D0BBAA7549ABA02AD762460BF2A80D39918B99B5A0D8CF7BEC174C94490C3FA100C19595786AB729C05E0E02538983A145E4DE6CC10936CDF2ADF465401A15492A9C0834D5A61F41099BDD7E92E27CAE2377D44F61E52C5FCC46F58981A1FEBA332B1F19118362EF2D12D12CE80BF017A1AE2753C20A9AE0E8BF4ECC5568D741BC64C3F783CD1397400DDB3DA525A3338F1A725EA5759A4A2B0B4D3B0895EE07D534154FA16D77A3AA3B205A8CF06274957C4190D47FB9108EBDE24ED0CD544086C3ECABCEC0DEBFBC368C0AB67D065ECEE9CD671784DCB4DD769A944E44D9B951AB3F4A890C215C1B9C9B962687A576A0BB15357CB5F250EDBAF7AD5EDC3FCDA793425AD3516AAB5AD9A01F5EB036C1B6DF02EF51516BBA767E1071178CE25D8591BCB5276D59233F91EDEF0E217F39AEEB605F6422EA5D0F47CA2034C4AD449C87DB3C42A5F2DEE9F111455DDD988A7EB4C285711AF467CF8BE4832DEEC585F2CDF7F68DCB3CD25339451283E618A6A3FD8095DB07B8F5B5DF79E8055CC8EC3C2B55E0B23E18CAA12A991086C7C6B87A0713B4268A72A9C3A2DB6B07514C6B7EB0449F20B096F88A754638E55E9ABAD72343C92DCA03FD2C4DF16BB2CBB1963C8B9F48704CAEAA22359468BA67D58FF29E38D783999218888650D6B414A41417D239E6FDFF8E382F107BF4FEB81744E074A51531C38B6DACEE427547E17BFD2C2E4F4596071CAAB4ECB31CE7769F5EDBA651F6CC4380A8A1711E3BB12A3D8A061A11F669246713D29442F0AD39629722ABC838CCB51BF80E9C440C2E2EC88D93076253F56C61816FB725739B4E44427FA7ECBB415B6E5675B6AAF736D592C28308CE432D117F388536C83F90CA8FB66F1DD543AFD147289DA0C8DBA45FBEC3499DB3EE000B26B49B0FEEE4044F231D5AA9C71405FBD754BB43659E3B59980FFAA3E0D78B8E067CDA206D7809D76650E4672EF4DB8C74E6244E82EFA9AC02502E3734FC188F434D3ACD65CB7F9B988B1D69B1FFFB69D88EF2EB1F2B70A2D165B0EC78CAE92447EE5376B0AC4363B98689076123F2DE26DE1928ED2C4182C3180056694CD6C8949A85FF3B1E24EF12614151EFC76D8652F04017ACE8E91D57D059D826CFFB93F3EE6A0405D9A4CDA1BAC97D906A14537F3F4E62DF70739B94442884C0C0694B438083B5009646BFD58B73FDEA8E9C97B18ACBC3693C07CB6C750353F8E8B704B2D01346619ADAC4A9B05FA4A478C7B8F2F6FCDCD6F9766E059E9545BC566E2ACF6961B29BA91BE7C425B1EFCCFD2F8ABB9E3B9FEFBA2A4371F8F9BB20448E9F2BDC6B5B0DD4CBBF04B30A6F819FA271635FA5CCB6F5FC1C3A70E40E31E2FA23A640AAC6B4C56BC07B948710E66284E483A2AC418313126D8E79CE9D31A2B657BC5E5D7260019E101F04CCD200B29DFEC7CF888CCE69C11E70115E36E62D94BFEBF99C2B37427AE66E576A9A7D66CE0BACDAB0836343FFE0C5AD719E503A07952FAA8A08BA3380AAD12C1B16918719B8035109B932C17129B881015F976CB27854279888BB5A7", + "sk": "8848322A566CA6F4AEB022CC41ACE242F84AFD48EC429FF2A107FDC381DBB63A8B9205612461E15A894899F582B63CE137E1A2F6449844C6E1AB07FFA975AF9257EEF1899B521DC105390DBE918F8858644D8B4BE502F657606AB402E005A1E646FAB4CCE2A201FACA5D3F8073585D77E8DAEEBBF03327BE684DA62F446FB8BF11333781374634823864042432083342054315306250442250826183726662656836707207736660161824455431866318670240311553240312347115152581385651705245784026155414134588730150508327407213452331305655400268516817024258565182057835868833071380163376245221257278005855363453284531033783707576026861505718742866514771740874438446244726810142022470677257603785402032470565871511738035371647503025642426405205382454702086852403683351111368612567430634780474174484634822170721682005744765345483340267364815826771864626134365402244150866005531353283300630053128674405643208648637486012828554178631542254248251856301082170407214768471150867840383624825684364366438030362238282104043061255215621210686101367563532532562306760522550345502415700162084747110886865313326700027831108836087336210727177214467302222658180777371060148146602645888401352857182336671315855802221313438166008560261203061705863553051286285235608241467031187205708420581371001823637854571517586144832155022232600160485088873722360483602837746658646860177715055875558150641212362263864175584814328466146518265263274857302328063567642227558860841183338043285138556553222668166416277534867861727330746664576480024537803586435081208274002737517430415402722305805887888006778232512782523462685012826525455106007263311385032752711256051815357843176702263215670485563168666680358667680544184345338385515177482431554648487165220470888673712742761144130066376423527701312468340042581563652578411642814866606020050483618642353848611076208376042661087664224038705704184504657206570044150271443252440031002705772661801304248550017226385876682044215363807531016374814725644264133280774048845453460315230256666151016313714182805604006003275203431342570007274782878487383272346602306120123182336428852143161760614620647282877803338426417217267534810317714120637715587447884238722162264175700647268123018833033454700328881216065721525378787614880383841413262040530202264523768288244748401630013064582441506825281343376027562685201588256074212735338587526201851804705483838426483651360202665338765886456254245744670566111870525780254234553032810841267361136718675661103883076155035127073645528165635100567720655217755421301357108034726505744587147310040141010805646522087147007255714057158741217277422625282364731745870783664616160434555775443743502840544863386473378018153247320635606807438754156737641371466713704031817403002217663388070881274501471075834867805472376776326800354057684821603313825840027201144475741126230724105836354806407505613633022136647710632508145086447881758420157178754808160145254472146725788070481561266847405464138405113446032102601304210208730306401431145205104734535487474140772264560342348655301266821517162211403658702262776371234537788132058858823145524452147323040308527184140733703820531813674657553835474053654050304073176263545064447138716350737634B643A171F66CDF58DDC280697C53B4E42A4BEAA9754E6BE2BA3A38995D758B1139FD3553664E16C952BAF99035D4E2D089E48D5AD9CC29E4D2B41B6A413D7807F5321F52B06C51480F368B2EDA86074AEB9E30427BE5CF548FE5042AA154DD0DEE531E37AAF546BDBAED6F7BF1226FD5395449897E9935770991B81D23C884DFB0834B1493781662514C3F1D666185ED811847CF1C0042EAA330F42139C94928BCFD81914E52F29BF32E9EF9276B381D6D17FB6E487CF8CAFC1FA8988394161595DF71D66D504B4AA20B17EC08848D59BC328EDDD2CE0B618790CBC344AE2721DA47092A438AB33B41A490475323593968858B61EF2C0E9FEA7D67243AE69EA6561ED8F586C3EF625B0E560A7F908AC491F6F76D68E73DB4718346F5A3DCE4C3BDEC93C1CE41C1A86DE45AFDF43E73B5A3226367DB267C39D75D80F831033C0932E537A8A8B27B1C82190990B9A949AF6A2B9CF6595D35862BE8BFD084C117494B56CB00C671AA902A6A7179577C0B9C4D615F7E1E2058820A12B131BCB96BE297F14407FCC7F99AEA65F1E4F2557F6B946A55754B594C1DE5758D76B541B568FDAC78F3C6ABC68EDFFF0BE8CCD2DF86E536F1ECFEFF0160459EE05F55BE0BF6CCCEF37DF0AA22A2C01A28A0FBAFC4ABC22A07A2B60907C6523E891F18C264EB0A0589762622F664B7B6B65D9ADA3DE8B1D3A417F88B9A821CE7D5D321FA2A64D4B2017CBA63FD177D5A866D537BA28E1D0A22DA42B471A5D4CA50C9CCF42494FA002A35D4B9B3931DB7B4D30D1C6FAF0FDF7F3980A20D1D5861207FE143222415FDB586A410FED5B40DDD57B5208B804261880E25DE41A4880A19F7F6D49589CE530961FE2E28827621F561515133DC1FB9E2BB61DD7183EF2CBE906E292C0C7D61E04A0D61623C897258F4BBD645B30D2DB836C75481AA3313C12660F8DC1ACC7EE159D6799B587C85992BBBD1A7794068D7980BE486426156A19B9096EA4ABF36E4E8B524D474CA60AE27B9DFF771C64F0AB2844372E6DAA50DF760E5A56F6A0BDFDAF7224B48692CFC811ACE083F19CECFBB9A72C309CAB467DF8B79D2F34860C7C056E8C55514A53975D407B4000119EEF0D0C8EB05524EF006886764580F697C849B8B2D2E4E1DB15992EE072BF4B5252AA1542ED4CC9E714C0EE6A447B838D233355228BF4E427790D8A46132C50D3E340018A9A3999CE187777DB336FAED69D7259AF20E104E9D13F4F89AFE3D60E449C8075001365EA6A5B150706B94828106776831D8335078F1D590F6EABFE3A01C351DA0C8AABF324AEC14BFB0729AF86EEB4C646D293C3F5F3520554540451573A93BB05BB3D70771240652751356A52429A866AEC7396BBA9D71AA078221902DC1ABFF960DA9583C58D4806D65D509BE5743C9D42AC7C8F7611226368A49D60F8E24DE73FC614EEF55D705DBFEC254B6579E207322426687E3B1C5C0A05A869CAFDDE8C4F06E799010DB17FDE4815008E9DDBF7DD9A3C63ED11866DCC739C6C97B2EC58B94900657F3D881BB9761D8F64469C68A5791311ECF13AC0D22877D4D2E6629E5C4D4640DDC30CE904C5FACA5356C72FAC8ABFC421E18642A1A7CEA716D9A4A93E115D749E16C79F29CF637A5A6A17577DA4FA5184FE7AF22A88203B77818B24FB77715DC2B44A59FC2B4EBB58289BC308F8C0B8718C8E40A87A6E6B5133CCFD2D846AC98E02EF3B210FD2E6E1CE8306BCCCB4BD9C345F4BE59E931B8A30E3F9F82549C0084F72CB13D6C645FBE61C81319BF98474B386B7799D561E53771AED22AE04FA425D3F61027FD710D897CC4E6894973146A6FB2E485EA3C127EC6794554B4282F399DE9897E1C70F2886D4A3F487220B00E85572A4E291B99691AEF60E10D4DC1515D3259F8E74144087D4C5EC5B0CCA2812C27E3DF2746C1A015644FC5B21008227B29328109922DC95128E9B646ECB9468374594C748DE019C492BB0B6444743ABD20A08EFAF84892B578FCD389DFE25F0F6BC20AA8993759AC87A0920D7A43B34CC43CD7FCA8A2CE25BC8FA3D246869E3D965D98CEF0F3FC39A5A62239D803B7E311BCFCB9D9C6C484516AC3E65038DAA2806D4D0D4073EA623A60F7F68B66C97511C1E15AD5F72ADBAB64F772C4A3F4E161E0BE0386D7EFC60D497F664400DF69924028764A92A26959F3FCAA30923D3F3D219C91F0831A1F6F02B24931D57D5CA427D8E2C02D4E4E6D4EA3EFEC061CFC72941DEDDCF09FEE339E3A208E286D9E0B8E4F9CB900D9F36C013ADC673DB1F69D6CE170197FBE60EE4E28E9DC66BD1423E80B78A10BD0119BD59C1C2D4EEE1CDBF028BD9D0C459CA885D83ED2BA145CF9CA5917F6F276B4DD4C9DD4E1A0D4545D2C66492B75A42DA066BE5D5B40A28F023F49AC263A45FB430DDE7C55CB78882BD689DE65C36AF223925EB14F26CFFB6CD082CF6AEDA6371DE32C5276D3070F89EC7342E94ADA62DFC11BA4A0B05FB6537F36BBB02630643332F121C93089F26DE6EAA4886E4C1BBE25E2D0660A1DB2582A6F586C1EF875A406143194E2783BA9BCBA4BE28E643887D14A13652CB8ECDBE9E7DA4A73D05C926486AC2518DEC9C82409F20679EF33E48AA0A44BA2FA9FA2B26A8922D5EB846C96B32392C46AB9F7930ED7A0B0D121FF874DDDC303DFC57D278760180B9692579BBE0A079B8AD5A41FAFEF9A8DB95BEC8C5BB0512479D2E810096C729AEE88741F85A308ABA9D5D1AEE42564C1EA76D41BA78AC1B05D5C604D3860EF722D0EBD73FF6DC894F54FDB8E4205BCFD05D199544BFE6AC3136DB83FE2794C5376BDFB6EB1C886A03CB2939F31761B0EF1ED877FF28E5C9F2FBCF7D1DC24079B4790825410F3319C76425CB9E8C385DCC2917AB8A9A743B8BCAED7DCA410563565B553A4D89EC927DCA4A4B8C1085EEEC5C53F5D43F99C1737587276012E5DE24C8C012600907737C487C472117BD48F726CA8D4E876AE35DE494E63D0D844C53CEE75AF13111251E338D057D5A88DC3132126F597DEEC69C149220CACB942B07746200CC72758412FAF7A22C0F73389615BD5FB87590C4F42BB451E48A21BBAAAEB12B427748F4FB02382D105FA962B180D1901307B1F03DB38C8A0AD97A8CF615C0A9C18FA3A6C10E1B7E0A83777A9BA648D25B0051BE791A05BD7CCF713942F17EEE24042B0FF47AAAEC674D0C9876BCD3AC11580DB1245691DBD8DFE791AD40A1860F485933C477ADAFC3EDD030624DB77DA7E01E7F81417E394B3629C687A464DEECB42C1ABE5EF245A717FDA612A85663CD9684A58B3124CEBD1CC5CBA3A2A8A48B168FAC6760375B8A62BA4CD7BB4F177CEC05ADFC9CE35908D78DEBE63E3BAF803F2A0079528BB4B2F782128C0AD576092140C94A980045F998D89350278BB6867806228F8B0A8617A6CAAF54ED3C70337963B986C68EEBDE477790BD316E572D823D2032D065891EF8560BACD14F910D3279501F97342A6120EC2FD8A4F130DF18C0880304697662F66877BD07AD2E79ACB4CFE4F039" +}, +{ + "seed": "B9446E8F78C8B7B2ACD335B10F0B8FE1B34007A1D827EB5517710569E060AFC7", + "pk": "940F3A043905CD31A66A0B5E776022C026B8CC8C9DF839951EC3038ACEEEF9F203EAEFC937D6D289CDDFBE4D5B104ABAE3BD76989357408C69922BF39217134DF5C806D34574A1AB61ACC99A82F51852F173E0BD61E50552CBF5A8AACF06588470F649ADC715E3C7CBC646E168B4BF0468043679AA7363144CD6F751578BE3EE5F74C96107189ED1759929DC3107C1CA5F14FD14F3CB31503FF08C8E79875FD529AE80A1421C0643DEFAA35D6889FA5B6E018ECAC896447BA6F5095929B4A5CB636B4C9E0875D5B02DE68CE6DD54B24156952E081ADF436F064795C4D099A9C17F5CEFE19B8EE8406F1BF40AEC03A15D243F870E2FA2B0AA54EDFF17D2189D240725354C2A680F3E3F7F937D2190A2076B6437F5DD6983699F2F87CFE04AEEBB22A88132611FE673EAE978F01BBE3959AA3F4E9891EE9CF6D6031436C8CAF9FAAAC52E037BB69BA454C6D1A7F1472D85C66F978A2784C79E792D1B8B0155D85A7FE1F9B049F012690A2362A82F4CD9E913DCB0EBD67D68595B0D17D085AF96BC64F84E069C9CB9572A7864CA1DCAD25AE60F37889D416A8867D4DEBC7D1AF997AD04EEEAB9BEEB027ADED41D0ED3B46FDDA94584C0F787802B7A9192D8AB1547A15BBDA48E7EC65AF00152E4A385F755D6C156B4A5443A145F84268A55437EDE5A732CD7C3B2A6A728EC698E975758A1B65906307991AD8CEDCAF9ECA859DE2A7635EFAE365647B4AED61B28C24BF4662F7FEA3F14B8E373E4F3E4ED51FEDD1D39A2B70460BE3E7D213FC51357C80E292B9649AAF7B464332FAB8595BC1F87BAF2056574AC9C73168E13DB1FBFBF29820EFB08E5CC9465BF31431A96C91364CDEF8A7A53AC440FC40BD990F327DB60E980499B7314CF5A63D95FE20BAF80D001BE16ADE597188CAB8CD217877521E9815F274D8FEDFBF8AE11D36BC42B8F1D2F1C7F4397FF4087B73E00AAF4E9FDA6F9499AA469220B153DAB01512ABCC6F5DAC0C54356ED2ED0A1A260F3F8BA1F67D047CCD333A26C5137BA76DF6A45BDD731366A04BCA2F80F7B011BAEF941E91835EE218AF34357F47A48C6D5B47DCC282BC53B1465D5775FAF773807634A647701BDAF3455E1536FE96CEC471A090D5FA7B737AFB670CB0E2CDB5EFDF5757CB52669AE1907D991A187E87F19DD5F2751CAE3205FDF832B312FB44225B7D9285328011B5E081CD0261E255B4C74A1AA551305CEC1703CFC5CA1E55A3D1E4002410A5935DEA3B3F33EA0B9E17793CE6D171E70D954634DDC50D6B06A499F25AC5959F282E12D8B9C28A00C58371A56A4500B2C507F57BFE85FDE137F82929FB9B813B205F72FEAF23B9457B746E8C70EBA61C80772FA8DCC94AFC0AEB59426043CBFDD6CF69F97DA634D884BEEEAD96F24963E9DCCC71FEAD90938956140AE0C486AD185FED8266C515037A1FDCFA2E211FE52E0E45436215F123D8137DE4A679B19922C9A6C1860BB7430D0950BEEB635C0937EDFC5966D1AEB418C2E52AC41D134B43CB9A4A3305C4C669892F65978006FB56EE2F8A7566F2841BA1FECCBABDC49BB92BA7E06842F6C7B24427923802EABDF84CAF5B3E77DA7F1207F8B0497D17EC1B5E3527AF0539C64277918EAF8FBA7457833CA80AE2A8E001CA9BF08DBDBDC19CDF82F4230B494B07594B8AB32710E794605F93ADB877FCBA8B4BD3A89D907A92F1FA309727754A42EE1DA7EBACFCE46D07181D4B7F7D20028646AB680CF108BFC3A43834BF955483866759C7A34105B4A34F92DF2190BE8E5272D0DAF80E8C5DFE361B66D75A7D8783DB9BDB92DEAB2BC703D13950EC2ACFA686F97AC0E04B1E69E5DF49E54AAFE615A493E96BFBCB008385116FEED54A2B984930886A514521EFECE22F449EBD0F18BFED1970A86E7F4D96EAFD11F135A9BD8320A12AEF389BBA46B0DEFC101C3A90A99F00E6D5CB28298BC35DDB62A1629374353EAA79830BA5B051DBA82FEB251444B3044B432E675792DCC8E464BC40958C2BAB862208486647AA879B8AD7A71F48D63C3BD0B38BAD9EDFFFD1A28FC3221F67B26A2A36A40BDEB3D01E0F4AD90B26C5CC9AD0D80E24D5D354D5AACAFAE1000AD21E4F60D994891621B19214F92657006E01EB4B28B94F804A7BAD9A120226CC03CD634731CCD5D7610218FF40735F7964C6E2E4C119A590786E693820DD75F6BDD58CD6A1B8857645C3C23B52C96694462832ECBFD27FFEEEC6284C4C27B1FD95B7252857BFAAF2E5C34F51A4055DA5C9A2C8E941FDEAFABF87074713DDFD9443AAB31270CEE2801588E7B89F3329F3B9E9F398738FB0EB0F50E337BE42000B5876E84F623C258C4BAD7D1E536528E8BEF4AC6F6869AE9738AD76BCF8FDDDBEE023A5A836020DE542CD56877DC97CD33586A637FC6C1406ED18333A32995E14D79DEFF1E258B7FBE76461680C9F5D7CD79165944EA50C29087F46AC6392C1CB8C3FF9DA336D4787E81C3662C384A603EC6BDE0089A5D48136D08DFAC460ACAA0BFB0770D85ED2F859CF3D2F1E4C82D5C5E8D6F9BD5F1538E21FA15ED28407AECD7E78633734118CC4C5EEEC2E2D01FE75E1B7D9BD0D149B13B57FF5246655ED2259544BEC5D06639BF6180BB8DAADCB49ECF1C0732D530D0817337C4FDEEC4DBB99F0DF41ACCFA48ECA5C5B8E48CEC321C8A1187B3E2018211CAFA625209296D77F6EF6F14DA8388FEB69C11A912619F514DD8BCD5CF0AC64E7FF3C97FDF06B6620D18A0F95FFFF5DA533BFB61DED91BE2DF2B", + "sk": "940F3A043905CD31A66A0B5E776022C026B8CC8C9DF839951EC3038ACEEEF9F24A60ECA34FC68FC31F37093DD96AA4B9F3D5830C6F16E5218B03461992816F1E6C46ED2183EC938F9BACE6D938995AB55B79D7718E0A65ED1CE086775CC7EC0B9D8ED16CA18D454DFD93287074F1753CF1A106D43832069924E934B69A056D6D176426004013076575326430863137681154388472321482327058660264144318587126616777245665846085207077377620134715340864342265500652186150467601565650873175644064416834227733720173774587668873453654245237887584735816803431317252007518455862453438544280565558788488641766433715102273116838853016286781356764553350815576130623142120288320447330858634146116010314662770062074375774867186530144058337264066324211032656066333521814241564325222500443323140011323440703778825861335111403817102184704327185386633608142215442067221665320752283741503126550045540138523388552553756710758782221066048054785368634370510608715285855830261461583231884206487168348502251624181358250452363431358088283280220684850274887682136732878487628835676427436605335002250861670280661746364663333746081501851137351028871688754020075563164387882072231828620163852404354634175131783368268806428070410450722647813676878073455762434565702154475408122163541077486410856021580604143745384424577785383320062585216722084220844048307024134432474888345716725321201005120225816884018256740445853733442120313688418144003171551700522688612013631552624366072347843226703122460417203012430812021833811420720661868774436374256462732481621436813002757624755522350808162680011825038722214273025248005052317717234810061288158327831563165021287226153061841412807135642600053623232871172234266585054154037728672161210616458710643372418828532614851034330455673523587742236477452251870078026584337870552270745526756623860278447626062284834315340427146171232766872568061730756050724247027148476041120506552842756071205358731326167423273744026237525138835086634357501537604145556133481414804060470432652463216123837200443812665470481367442016456162841127017802443686606775850025538847122687372785518286573566563606242666874533554403325385363656115174748320261462840552772623674410481265030724763256241631486648346756261368748180167401048541280737780881841151540185080052416176233736633170701131856087368601514425225057047273141367358256783768616620301431740016335013544305727222457250283187257250743134642552508353067725664027065305156731547334833675272822335860257083672157731427677103643242465216121111244014577786563871520155270585467046042052457113044834347701052060663740758787647888206363867766446811488063441365214110100556377588423480631304107844013871142521788152386654530207028734623080264311677371668465072078164640706288825415386285222822305247408773601071322560410302142821481811133677651772473201332288815205035613301832085104746827523346476715450002575314316042733172642714440446820038280042757635636678707806871714311068015364432431546245667366443671858840683530203154356038363103684425222575835848370481228786854711047404557132636566284507601070068815183715138065502835833765443038333301854266005471082640210720634670243202468375243858240881712734844607240223EE143A505C81AE49370E4B4215ECC3A31B3D08AB2504AAAD76952654536312F6B2298A20A48791A9236B32BB68004CE49F169A4A91C189FA677AD10A25604A4BCAA38BAA0E572421A79CB1F82E3543A285C5BC6BF25EAB82287027C386D543242119C74576C1126E284DCF1E25717306223CD0AA9F6AD025842709572D1A1A2D656AE4388B6F3F491A0EA231798A70A3A0FE3A7F0C97E74251068D009CD0088B8B9026EC8FB19F181F0838BC4FB5C7196127D97D91108D5C7AE2893C85C32023175DC204D0C000261B382FA078DBB3F0745902A445FD5A32A7CD12AD7AB014F5DF7B9D504FDA8EB8A00DFE5DD832348FDF7A6298AF21A8D9730DDE60964EC8FA10B3140D409278C238A78DEBEAC947E740547530AF8A98C24E6A2474F1BEE79E762D710CE68ADF282FC8110FC099041B5A0CFC307176FB9FA214C3D42A7F2BBBBB27FEDE0EB37C71D84811DC34C83ACE1A41D078B936205CF5B726230109A099B75ABF9152824E04C352A9085BED558C7C894D886DAFB46C3BBCFC2A74AB8B4407E514767D90692F94862B2F7100FE76CB36F52C3BB2C7920A76F642799C213B80A6561A6980D611D2887A0531CBB412DEA4BE23D41F515BB8AE38C77D93BD603F9AE2E55B5F0DC6F4B2E217C98F6F2F03F9952F43BE49E6A7EF8129A265EB342AF271D2B3CEABC86729E962200FAAE9EAA62D04C64ED91E0B3D8F8300A7C24719A9F64AA35804D2B5FAF7F3F617963BB8199B2B842FF5317D43F32B04052CE5F3B7DF5DE8E2FCCD0B183FA767A3779307D8DC95ACD2E36F4A99945E12C0098B2FFBAAB97B08AAAF9B30D2531906506EB5194564C74468385A83D0D4291EFBDBCEE7A3E781DBB81C3F876957DC169C19E376D76F7E4AA0663FB3E332410ACECCB0457E076F25CBB2436A89D5BF25C376392E719B2B49AD2EF20FE5F51595217239E0E3C7D40BA0EA3F3BDAAFE29E283B9A2B93BBEF4977E2574082E8BEA041DE33244DC52D71376FD051BB790DD94899C80466C2216879166FA46766B7D23899916FB8100ABF1A1ADEF0FDBE68DE44774E13E1104432503C0CCF39BE4444E3564A4740A101DD654F76DDEB32C510077186709684EF6EA61B325B8FAB6E039C95D6C19BF09CBCF7F6014E1FE85920AAF974C164D8079E3CA16707BCD5DA704F0A66A48EAB2853225A795DEB51D45632AB38A07F093308545A7EE29FC0309B48A177DCADE869484814652B70073AD0CBDA32D2965E26E2BD2AE66FBD91FC11E9B5D71969953981D020AB89EF3CFC3D902CE078ABF948260035F9583C34F1650E647992A7FC4B3814EBC58723349901171EFC1629C0C2DDD338891C48A19810779C2941ACBEF58361B3A84DFA71D80373DA5358990B65922E17ED7066E4153CB637FB56605684A94284A907C92A2D717243B731FA6F3895E8BE09B7EA23A023C6692E8F2DB4872213EBA4B402D764D2DCA50A3F2AD278F33493E9AB83777F971476A1CBE9F7A448E3E9D9E47D55D8A7F04B1A380ACE616DDEF3625EFDBA9A625B19715D38EAA295185B7199D81700A9BA454A07C912187BC269C7BD8D499E14557BF206A33381996038E27A28D19EA9672574B017799A27582421CAB69B6F187CDE5AF2526266EC10EBAC90E4554143ABA9FA448ABB8CBD380903EB2249E124F2FBD230E6A91342972B3C01F81D7993A5A1BD25C4E0F564CD4597A18E828F536CCEDBF66DC85F343949B1DC2A50D58FFEB67949E596AF43E1E00E13C3BFA84FEC72E364E88509B8F95E0E9C0341F3A3DA99C947BE21DA56DE9ACF630DDBB190CCA9312142640556962599A52FFAE981E3FB372C0A2B99EF2CB3B86CA9AF186939CF277F32D503A5E6554ECD0259C52B348A7E107DE4ECFAA35D86A62F98AA403F911491C1B393F4CE1333D517A731E106E191C66C7ACFC13EDAC66E9E2C5C3AA261FFFC6CE688BD711BC748376E25286923E55322E6483D96DAB4765AE5D91DFB477EF5A5B61FBF78F248A92D03B18A7FC247615405701C08E5147700F41A35CABE1D1A592582A2BF2067653D7C925146776C0BFC84A4EAD67619C0196A0293B94AB5FC30900C25D341E819F443C2BFC9CF7D4C3960C6C7E6C33F656B3B512752A55FEE1DB2B4FD799DF192FEB8B775E141A0B263A24710AA98FD860C18D490C55D9A44A92E1ED5FB9BCA06562F2D1611E35559C2DFEE0AE1DDB8D724A36CD16CF728B2652C92CD8619B96AE1EF21B2D2C692CF02F9BB43FA0E4C87E001A3D6F1B7177EB43028F88FC024005FB095958BB35DBA11E72D800A971B1FEC05548BDEEFA046947449209964328C1B95607AABA6DCCEBAA3B9A4A175760F65990E36F0299604545311179B3A0FA7A3695053EA99B5164A22E1DA59DA3964D76DBF5D46193055CFE1408BA943B86C0B7CDD2CE95EEFFA95EED74EA018D42D891D7ECBE5C8DAA52C04510253F8CCBEFF351274CDA464F51D4762B68E36C783041063128878D9820AADABB2BEC4FFDEAF61685D9C0FD2CA6626F8E3BA66678BBB3B46ED7FD3A9B4EBF623E37D90BB6FBBA31C9823E8D7379EE6A42C4AF6C15D183666195F509F3A23D14ECC4FAA4A35B55D122D4F0BAD9E0DB8DCA918CB2D13E96B5E2EB2AAEEA1788614BEDEB39691B072A094EE22A6DFEE43BA77A46A9F341C9A95640C26E7596CB6F0D0889F75789FC54E31FEDE42BE11D09F6EC514BB5570568D395751CE5D4764AC64F4709C919967AA7E04FEB19CABF739E1B240CFCB302321E3D012A2231D0DC0D1038F84BED48ED94BC06F65A3F437C9D8FB2961E49B292698618F55D06360C8661DDCB990C68D1F47BE15640BF059B7D7EC8317548E20C83961418C38B4EB278C9D86671AF17D2A2E22A2BE605FCE1E496B5B1DC08A0D4E7B956CA5A28116CF83FCE69190B1559DA0C19A40ABF85D5030E0E979C3B8E174B42D0F2709E28EA9579332E47045733C15A63DD2026C6540654C5B481DF921B2C4FA9729B817A3282AEB9568A6AF7DE57D73ABF0A04347A96263C97B575EDA6E1E17B2CAF8B1374FEF9BE11042813B4D64DBED1DCE9D452CC0E17F67D51022B8AF47D32494188868933BF44B956B9660A9103E2AC233F907CDF2ADCA9CA51318148B325BD29AA508D9A6F121CFD6BF37835F9EF9E3D9523F53BE11687A2F19DA1580BB868038A1CB0119585AD8A2AEDF39C8B3B7130FC5FB02EEE22279EC7ED7192B4FB87FE60CD64700CD4CFFDC4ADC518C216DB78C77D8E78E2A8509636B9790AF99616BFC5CF3394EE1E044F4DA0E22D50495B887C6B2A07102828E8CA08323B3071972286022AB78A794E3CE3A31897A2DD60D26C952F51AF92DFED277FB671CDEDA5667887CDCFCE78103037742274A82DC620B37DF769EB2332D95E3AD6E2B38EDA6E9530FA7803BF52A32A1907A880E18E7B5CF7FA751751D24A59CED3C08CF90305FD55F19C6C902BA7AF6F02464C1F84A67FD85F81183866C544F080425FEC22CB6304296E00F41B69F2ADDB5AE7F286D39EDF19DFB02161BD6D5AF66D2D" +}, +{ + "seed": "910E96CAE3F7DF10E0686DCAD2D6CF8E0DD9ED69F3661F0799DF91CD6C494986", + "pk": "EA95D53403E54CAC9521C5635E9F335F75DA4CA76005562E75F666BA598DF28DB7EFFE2546EAB9785D75DA10F4FABF8BC5A3BA57B8510AD8825E296F6D1ACBD0350B05DFB4E58A120B6D001DD51732740BFFE855ADF7B48AE537BB790DEE364A702310323EBE2883609D8219E85AC252EE56FF58C5D6579323EBEF4D3EA265D1E65B446AF2436C3164B0B984DF75B63DAD2D3CECC1F41BB23560ED67842CB76723DFF07717DD3D9516580F94514B1FB3450D88F507F1BF07A3766A6E52C93F972F052BA165BC8D7A06A7C96A0FEF43EBCA6FE4BBB0D236832B70DD54F4BCFD007A09D4E1024817EC0AA397E9A88E4BD740D6588B30B6A994701DD970AAC571E66CD86B3C9B9A524F144D80A96565EA9BF9096721787D5E484A7CFC24FD04D7384455905DF6BC6E3F526481A38648F0EE49335EC0B9C067AA8071E0BD4DF9F23960754CA894342673CEE8A3F5A6C26DBC476C42715E23D222F3F8365F69F2571E777B4AA51126303A1E90AB3F9A445DF08FD853F64ED4A737BDEF71AEE8E54454F8AF5680C0B996F7EB4E3D3F01B95CF449E1301FDD80B4D3D238E7DA61F7BE64E26623EDAFED874581CE54C35C4FC6B302B565A8A1EAB844D086001B74DBCDD14424721BC36828EBF3C3B70A8FA289C11F0B1559988D4993B696E1C6FE6E62C97F4239E305524157540E9F472E979F9640B26FC6F79E69DB22928E76813E46A1B056A938730C1F4C0D5D5C763ED3B78FA56073D2A41C639F4AEEC923FD761844882615AC1EBF3DEC850E33B7D00EBDC62E2BBB0729CC465ACE1C8A50B4B35B4CB6C51CA9016EA38A79B65EBA47A955D41DA2F23460D822BAF79E08658253C019F1E393C0392389E527FA0C446CAA5B93EAF129C5EE2E0FA36D08D763042AF0A9CFB0FCFE6A36DAB0A78EEEE90AD2D5F63F3EEA6357EB073F9F912AF9BE8E04D86F4A34B9D7A351FBDA890AA01EB34DFE519195043B116AF01D47A45E5FFDD73D799CE1B9A5E584DF247B5B4F1128861F43A322AD193D94EE12741817A6324E0E8F747D20B20BD5922B1A1B3BCA25C7F910275DC3A93932CA5B6257E7476EB35DF4DA8B5545A6073D308CA77822A72CD72E2C3E82CF108DCB05F50AB61DFB879BF731AA258877628DF11ECE67758390946519D566AF6BBD45D621E53BFED5D874CF1D22AB489AC8DEB3F8943F9927AEAA68CC4381CC919D25CC10C2F4938496D9C787FE032F956419D8463ED1385A0D1C96D3510CED99AB14E14CA9AAE0FFB645AA8AA0D09C19A4CC4A6F83468148403AA88C2655ACC1C95F93FBC192DEEDD77A7046F97824B1E412FD8E70A71514892FE27B53118E4D3362878DC31EC6343D3595CD0BEE06D9BCCB6E96E8F5DB7CE8A8F31B24F989C4CEA43E55B3D2AB85ADD1907C5543551FDA44AAB69DA22483C2BE0000D3C49D00AB453F30F5E2453F8C02B20A398BCD082B6254FD6B923F1EBE56AF4195A336246EEAE1E92B8AA72FC6E355A0A1FA1A982363BB4C73C6102CA1393267A0A9DDC14CF5AA12F3A070FAA3C1865ADD1080836C2BAEAA598FA3F522133E7213B9BD4CDA65F0B98C377432A28F6FF093B6FB769B4E9777ECCB333A9977BC3C1C2B8D95D2A44CBECD962981948F1667EE8D64DA1989A8266056B632F5F7DA9018F290C98D6B546F98DD220DF299901AF1C0C8A2155230D7D46061BE46795A5982963FF1A6D507E256EDB08DF304E8F9358A32ED22B8BAE3B06154FB5DA7C4C0E448509A0B61CBD6E4E585823890BB1E2B44DDA6A8822C762F6E8BF07529C4F5A7690C24DF96C5586FE5131CE825937A5E5C8D90AD3848919D937EAC19FF862E5E4ED51C7EEEEE626D601CCBBD055F68C03BED53D67EB8B1668E06CF7ACBBBAAFB7855964B6C7BE342E63C9DF5B935338BA29FC651F8E029499B6F8E12971326AB7A0B836ACB9B0C67EC72900AF728C55755596894C8C9E0923799A5B7D0F37372CA168044292A1263CAB005323DB3747CBB1F6C08341320DE056418B32C9BBDD9DCDA8842251ABA76DA423D40DBB390A62F696FD3F1E063BB0ADC562326F2884C0CE745740C1CA4C3824349C175F75BE9C3DDF418894FCA12C0121D428DC9DF635A7DE5D6C1DB6D359A07F02456B01DABCBF49B505243A0E295F3BD03CD70209C2323131D9A300E7C626E8A30013716EE6564E11E349D53404C2001F1B77744839154D52CBF3D1045D71446B4B0E7C4E3ECFF88385C35A0764AAE46296B9EA80197D74DA2BBEB8A430E90AE1C341059663F51B58D756290858B054AD60D0CAD93AEF729824F81B9809D6C0F3E8C15CDB5C79F5361C33CEC09FF86195888F214B7CF69A19E9B3D3A91C09FE6EB43C970A1C6262180B9A0D599629F12A61702F03C0CA5A45F8518DB4481C721155791368CDBF786D1A7CCA77BEFD436F836B5BBD548F079FC87A3509D12179EB3DFF109EB6EEF56D21F70A3982B24C3661DB64310412DEDD44F6AAFC252A2CD4F8DB9BBEF12E0FABA2381C18B5A43C9A16EBDFA9F9C2A4FF5912E46FA2599FD16A318EB62A971A03890C8DA8B9360065D11FD848857568D08E8E5813B159CE3FF0FEA253593625F82B5BA5794C015BE84AABB34409E937C51DD3F6565932561571AECFAE711B61A9AE5CC1D12AEDA3659669A481A433137BD5EC3DB59AAC18004DB0F96E708E06990C35856DC612B24BA27D4D837B3E8196A2536D5E388D8E51C6FB25D54043D0D2DD5FB1F827B451B7846511E5F51B6F48C3EC08FE39A677E2C8E", + "sk": "EA95D53403E54CAC9521C5635E9F335F75DA4CA76005562E75F666BA598DF28D24492CAB5EE1A838CCB870B738CD2BF15845081EC92FE655EDDC3DAABBD70463345E717BF4E9B77E4E42C41EE081FB7609E529306FAD0D010253818BED6F5C36E80F0CF2E1CDFC3644B0FBAAA332C91B8E9BAC48542587DDCE3B89B85AC95B67205358448251106374330761616370840427403060131555776484032685263315404265627140818478237330461730266886678220206757852370307812313186670777525377243410283855032620382282420030862325482173385126618006425080660754150507021155510527010400031730580268480057432412702246646585006018341365521716483413675564656536487671660142316774020375316380713786272377283742823337111220565020523286660270378010320780454435727328225012270684854752384080330327232568564232334624785300247078327824557671535222210477505366750273350760622046230230260051216004274018134720587804852011513328437632380487348538761062461618530322680868132352785267226346453636340478012526081750131434530007670441442545000101046220634032432113214835787158680732862056026304846838602761436702478386234638586703304407840415284465247473208178635703585423748148856167002814048306441188623612783876688861220036258078151885032812826481381533241417755607323112011074124487501132778203584733520654651330088421647830628846050045765114501255050401362864274111122784215666102828748217571715050331524203557710257341457213042182483316853151265470516218556873288758186361667570271538733143722872641133534773365442068318176733601261602087128454576104402730785325228074080124728136803212012176421321531125876743834555426446750774328825708846140833734063225565260787734461625334052344861774220588771408021810607471156332580632280701173562858681586364176474502351131460358610510860814212667307781071767853607451544703521337335512585050362481526644627232206577243115336803784153432761563147764470542241266534771730877768307535531184023433563146435118336554118553322683875347873514134711335415277733516356657622323524047003022507454625047621173572485725784623060878303721555357201478557707263311371545530238434748271222817073038030533437284816784301801712411264351214303745068324677180701387874004318531672172357360350653266358643677401786781602256310774310423523102138875113656455771583275031265507486382852658323110101755161235083527248117325406547684577540263666157667871418616544150267046727347840767160533104681104207400671472835332830774825088686527066365754634711824660710703543823161528234747317210601368642418361673115730670838723373875628051373556788162537260577837888028732672353482401052021665413247585302187633005427258870173180733401656355241728775560065687277881464582763237044678011865760682717142166374624528785211470160157277740506621763080770285055044428134504455441747414021514780758088166611667254100231637072441607706077511335806828544374880608121171511770560080601164106110827266126106183135415882627445120836107122852801612426738230306530455072677400205525856874676132831248508378511646237882435637476882748587424351284047403241180001573406464365334575336777303464222072838174364367877848211517701774258316522054107175211473552828834313110583621807140335000560AA86F8697754821BB4793B67A97B27699FC1124FD3CC779CCE56FD068D0A004D91A5A8BBC7C8517437AD5FA4114658257B24FD6CF7D1E7D4D0394DBCE171425087C232DEC09410FFE82C67427A4D97845CF0922C29BF38D3E6E31E8758A43839569925EB3D9834C352C2D2124EE24F5CF61207FD6BEDCC70E1D665D12BEBC188F3A1E6AE462464BCBF05587BD0B5E960A9D20DB52C7326DD7BEEC6D2B20BF82B9D551475B32A77AA5540D2C15D44C948A2F0EA266F6EF1F619659B0C4ECFE94D45045941FB3E3D4940A0B7412B2152AFD4796104D0CEFE9B5EEDB94ECF11B0F31956E2EC3AA935BEDBBA75AE3878667DF71006587AE20D9310A2E4D32A9ADF94C7995EBB2D72E1EAA238EEF912458918099AC43D157EF4B4480F8C87EF8F8A14B083F85CF46F795EB40EDF4CEF2661566D605CC62AB1BD197CF13596777429D7E7AB5835D736AB302CCFD90E5A0A56342F27496F7FD30064B1CCFAB8C3A052353339DF7D25C05601B8B7BB86D0B43BB4E1851636FF4471C26478460FD4F90230F3882AD8D5770B366B8A2055ABA7045DF54915850B48C4C191DDEBB20F0178B950F711757599C73B31024344EE04EC84E57B818F3C77C939698E895FE92BCFA7B2A8E6F271C39718C9CD91A278EC554A3746ED04063964FF384DE5D9E53D8D018D99F974F022A8820B1AB4F2155FA7CA8D8D454058AA179FE01CF8808B33EA1CE9FA5F57F59EAD79E60F374A5AC959F35A22A336F505061D75497E374DDF66889B6D72D5AD04E73A7BE7DC43EFCEBD248140B0A57E31152EF1AF3E6EB4A203B6292A867ECCDC211DC0D42B67D7FACC9156D159CDDD0CA254D338AD67093232D10E94B5D6DA4492704D9A35501FE279B2B6836978C0520B643323D9E0FE1830B2EEAD1BA1ACBD76DE53C8F4539EA793415E2059582406601BA40A2981EC3B5CC4EC5328F6F636FEC2751870923788D0F8331313B0566C859E01FFE88335DBD0BA67F5A6F73B41BC9E501272C7D2B6DC0047E3C7796B0E716C1D5E2D9601E84876B9A94E91FA7A48883FD3829786162BBAE86B4F6E0B97EC079BEF8C57FD43444D2602D3A9C5DF317C870C34D8B530C92B905A8B192F0CF1CB31F67CFE717775652D3EB6BFD7F3736CC3B956BAC5EEB82B73A29D6BC8FC64375F4CE18A066DD7E8AD4DE9B051DFCD749232AF775A24597BAFB20CF25BD08EDC60D9A5030BDC28E600EFA01701C9F19EB20755F17FF66A3BBCE48CC727F7D0B51FA1652EE2A9B8CCFCBBCFFF80EA6F6CF977A757A1F079CDD91094E4BDE475DF195DDFAC60D47101E459EA750A9B6668F66B7832B1F96EDA29FFEEFBB4F4B988CAB6E0000377B19820B0A12D0650A60DF4606D92372376134D184E5E7F94688AE41C3E7067F191BA295C1CB0F283BDC5BB02D6B77DBDD22B36D7028AB787EC423F026C5615F4BDF04859EB68BB550797756F148ABB10AABFA479271B202AB399A3D5B6B269C3B04B6E6B8282F38155AABF1B5DB61513DE96993C82F7F4528894EFBD76F99ADDCE4CF7C6BE8F73C341EE5BE2E9F6298BE4E1A00D9751D65A5414B760CA2BA96D26A7B2E77884280647BDD9E6ABA0DDDF1E84AB104C34D0FC10DE4D634C18BA991932DD0BAF307BAD274EAE729CE4E642A070A9C0F5B5343816D3DFD78EAC59A8A36CFD5CCFBE250F5F6294FD58587BECE6C9255C2A419B7614A08097AEA3851324C533003874849CAE7606F190090299C473D3C367E2A11D61363C7BE70A0A9E8553E572B926BA73ABA9E149890E61A07088406EFF8A352189F6D68FABDE060E3F3592B9F729D83272D62A02C933A2D425B71D9EC5839E53AEA96CC7761064DC37DD434B6AA283FACF03A5230F54AB0A6FBF7858E1434EB58D989318FC7270E0C76ACF28EA8B6697408668B1F556DE9A53ABDB587E7F8D7816418EFB92AF93E8EFDE2F0843208B604E483E7BA28565E4ECE92A54501639CC754F0D5BF5BCEA727AD2AD5030FCCBADC4BF27A16057B3F948C45924968D9F69F0FC150944E4D541416CC46AAC433325AD2788A944A607E001CCD824C3A1BDB3F5E0F5FA93A864A7C7B0C2F95B99A5E64944F07C4AE95F9EAB462E90487EA2FD02218BED373536E1E92EB7B9F48F6027941A289E2A63CC9CE55083D93514D5EB734F9CDD5045E4A910B824BC105858E6B4B2A964A5303A9593E26824D5956C18B5E7CD5E926DF580043C54B3862DA98CB9D84A68954E96026EB0B9C9CB21C6F04E783E759E49B7FF5E33CBA7B10DBDB4DBD84ADB01D725625B86B60B8819B23ABFB84F8540A953A53E9002896F00636D96928F5D6462DF2F1E5E3BADDD3E7EE5F9BED9ED8E29499AA327083CF6E3C6759F34F61B3BE3EBF6629646B6D7370667A36BC53056B1C045A5D460AA6603DDE5C0E80B864EA6550D2529F9DE9202A8731D21518E489D90B16F89D1C31734CBD18DE5F1F31872593AB9037F3DD87EF3E91877961D075532305BAB20FF22ECFF44DE46CD7E4CC5E19DD5C101AB28487DDC6EC920DB72A30EF983E8F4D009569F2864B35B113D050032CDFBAB343086BA92D2BF00D7CAC698BB5D436070566604D793E945C98420354077FFF14D5D4B7366AE9FFB7B3F6E8B240A82E85853C73FA6165975A4C11108678E1E30B82B5F6346B283C41964FEA6D525D66B46C2BD259137CC02B4EE78532A1B76409F95498655F6A28C4EB4CB280E6F78019D2D5C70BEBF9BE1943FDA6897EC6B56ECF64622B520AC230BF261F60C2E66CCB7BE18A0B16BA0A08B6F8468F2A0797AFC66BE782A6F6684760CB189A287F74996DC6A2EBB0B17FED11641D89819761D3C0E4E13F165BB6AFC6706FB4C9D27AD6ECA1F8F8FB4C919D88ACED483DFF586203904EFC7741ED28771317645FA2FB2507391A663F6E58ADA8E219C9B379F4DF03DC578CD0AFBE62B65BD18943C81B9B7276F47E81351BCA38770A57894B2F54AFC746155111E928A7A65E7B4620C976BAB3BD48401327300680153C2664D303B5365C0F967D39BD92DFB53583ABD16838110DCCA3FA0BAD45F485F686D1003D62C3F7E86D87E908F3CFD77223AF4D4F6EFC817F14EE85617ADD35C630879FD6EA0E20645316C26FB4B9E66AB6FCAF5CEAA95302E3258EEBA216082A033843D592F9D9B655A5509390C63B02E904DC2EFD9C1A4F9B782BC6AF1F7AE315C0E7E25A5A8DFE3FF2745504BEAE8D41EF908C45F3FA6F2E40262C88278E89B02B3C8415C2C8CAA76F687EF30014C2C9ADEE89E46B06383F4FA33E66FC80B7C505972D8164F6B651A4D037A5FB2ADAE708F4FDCEDD202F9D114F4F78BD2507274E87FA4701BAB73390650D02E254729C33DC1378E9C97BFCDB32D2755046E1FD63CC0504B8117F82E7C1CC796DE16126AA3F50A9AF0373A819B01EB63FF834EDB711DE4E877EF2F1D46AA1B7E0EB0DF171AD0FC1F2CD0B6B029CA782FB259C5F860428478DD9E2270A0B9A05260DB661CFBD0E80E75F06020221115BA18B0D6B455040050B23BB87D9DB5F87877E7ED688" +}, +{ + "seed": "D0632A6EDAFFE0A71E94E62A5135066E6F7ABF8065774A2596B6BA2F7F138BB8", + "pk": "CA806CF2D4690C7BB3AC7CC12320888B62C8202262BC7F8766EB6D7A3A067A74348698A5CDE30D2256E33639E45307470DFB674E427A6A441012D80ADE3CF8133B307E29842FFBA09E7D04C123ABDB4CD41F27291E5A6ED55827769503EE1112AC884873EA789644C70B424A6056038E2A0D785EE036DA2DA53B724CC1FEF74831897636ACC26947129B21ABDADAE0D105B07FA4C1CA63651D23355419307E8C44EE19373AFD8CB061F1B1E8406627482A1BA2E2DABE2E5A0CABDAC7D2A7025A8BFDDA46D9ACB02AD4C9466FA203059CD5673C2018923A9304890E3A92DFFE7ED3592CB07E0B23181B20927F96F0E85E4FD59EFFBD51FEF48909E36F153DD128C001B59F164EC759C9D8D07B1DF6252F1B8DA19B9E9019FC5B2164A88A4B4C34DA7A8DB6B96E653750BA8039A34D5699ADD2B5DCF3C191F4C10F4F3F772074B4B726E65E783AA34E3B09079CBE2E68F0F52C647EAC333FDEEC274DC4E123E078D47FD52D01961E2BBBE62A1472311BA4AF5481D92659594812A4A1D841CC35A3CEED21F5D69C7F1C4603CD4E1E94B9FDB5FBE2EBF720D5481FC0A095FB987D2F2B0C5E54E9509B87EFE228A21E547A28AD9784477D275A8959AB2013BD8C8702153FD2B1870F02BEB1D1B25B2CA038AEE8E93A6BC6E5154624C6A734736124C3DF027D3259F5F89C51B18F4C3772795B1E31C7C566FF6F2D8BE4BDBF75F6FA4FB5EE4D9243A73F6D7C6DEC8D4E0E5189D50D0E419FDCFA07F03246B00C9D866E87DDFF61BA2B7FF863B7B120520C67BC5EB4690249EF688065D94AEA220EB3E3A11AD5BA7A29D9F262CC28A2E24668834DD679A87C1A0A3F36F905DCD7829A772B1308FFD56D021E58A81B60BF95276EBF04B1C1D6308559FAD1E80F39627D82DA5B0D23CA64BAEDEE87EFDD8C34BBA8CCEC047843C84AF46C435AEC0B23F9471C73A78456734A715ACE1AF64BD69FF7ACB6129B1C78608D5C64BF7CCCA2F9696ED1C64369007541D7D76DCFFCEB8D2E4F911DEFADBDF740A4048B0006EFDE5A73B73D553505B7286211B85F64C7B9CBBA721652B8473B4086C95FA7D0743EC2F9CC5C887A727DC2C7321BDCCDB028644ED73EAB821BE8F951A26A516779FCD5F68EC495C9EF78660683F08A85A610CFDECFC58CF49A79A3B9E3B5FF9E403BE51C274DAFCDD07E2051B44849C2ACEB79CCBF64BD6741B58FC4B6BCFD23B4496918E9BAC4FD4FEA6EEC1ABAC8757C6A972D3909BD94169DB5EDB540225550B600BD347EB3EFA51A5F6171321A6F1AFD6FA0A7AAEC65A612DBFC300AA4A1921CAC1D77EEAC226CA0F8993D1929F4E0F0E85FA38D436C035F49D85D1A802F4DDA9E4DA98BAC92A0FA7D5C2BCB1EB89F3394226766E4AA513928DC910311B086B19611A58F6A9A2B494E67E22BD10DDB62E6DBD775E7269270E2A0270D60191C8B2C8FC511D6CEEEBEC5ABA95375412E14BDE0906F2007EE4A61EF0E535FB22E6DA4FEB9BABDDF775E0394997574AF4750ACC98DB4C7979B90D9DAA0F35EA877D4D868F828340D1E38C767F413E89DE0645E1E2241A79FAB882DBDF87A04B279703435E3528CED89479D163917C1F990DDBA9B625509EE7B8AC53C38060BDA1EE697A6F237C5AD3E3347A7C6F4450A363F171901165C2DA96393FA31A057B1C1964607D923E5E4C658177D5BC0B05A6CC0DE1BDFFF0F1D0DA1F1C8752D3AFEDA44129507ECB0A8FB52114F5ED6F0CD1BB486AF44A3D74C8F88A2AD42A1B72FDBA3D6BBD2943153B55A9C8A4DFFFBE8E0B0794E60C9B64D7D716C58634F7AEC6D33CF50E604048A2FC28E9C03C7A77511D7EF20482FD11F815852906B0B9F4A40D45FBB972CA67149CADB90F9BD3EA69E42291BB1562464BFE78AA39240CB24B0BBB8D76BCC8057A3697A2B5DC71C8E9AAFCE7EA04A0498B365520621B1CD4B38C5BC3B2CEE7FD7599FB79D67269BDC4E5E2ED33F9C90D6EE42C9829845D7E6D6E861EE870119E99095777327297927A552D2D3D8D850D3E4B63C8934FF69ABAF1A69B408DD2C630B3B7AF05C1F0E22DC7E90C4A31F585FB9D9E4DEB4E9607CB49C47E6D8DCEC439AEBD1EDF4CB0075B1164A3F29C33DC9D0D59ED5763AD8B1646D0F655A00B6918A90A417989F9AA44B5CDD08CF1BE46874218E1247A263E64DC1228B540E70CE9F0FA70EDC4B5D02CDC450AF18F6B586FB850848E09682C5B6ADFB680A6262F90856FEAE11843B277EA039786313A1AE260DB0062AFAE786B61D4A4C3B30B8194379BD44436879EDFD61FFACAA894498CC26E2F7D823F0AE7687ECC67930799DC402BF4F95DB72001F508D7DA37EAAAB0C2C553A53E7587ACC342167F62EA39C37B3E61A5D7AB113CC38F8B7525768A67BEC285F0ABE9BA6A9957C77A45602BF82F1059E55AE9B9FB126D24E3003D4B21C9CEE851527A324A6F48FAF80387D09B59CAB3643925EC74FEC4374EC3E63853E741638EE27D829CE5DC11B8120279EA9605061513C6A69796FE9CB8DCFA0EC70EEEDDD70927703FA4C64BC723B94D358371310ABB486F086ABAADA7B78B1C0C55D88EF497EF7B10071D8AE72E2E28078D04ABF04581FC9D4FEE6AAAC4637E6F9F6F65AAB1BEC7526CC1BE743A0EA8481AA9E069A9CCB7DC1575345305FBBE7338C1D82BC10A1B64E69EEF7EAE67C5819A3B49BA603F7477F19B217AFEC4BC32DADD26255E2F917806ADF9E64F769AF70AE5691B26070A6C65732530D93AE6D1CCBDC77AE37C494B51775", + "sk": "CA806CF2D4690C7BB3AC7CC12320888B62C8202262BC7F8766EB6D7A3A067A7482939DE8E5383E4A4D7CCA79A9B7B5F621A461B2A1894E53315103F03C391E0A38F615C6BA1E541A423565FC34907D84917BEB652AA4C7C89B35EA83F793FB3869705E5DEDC1D7D34ECBB4D95C1D35DD6B40DE0CECA740A4E31A27A3B9B98B004167782002506841243131365280841862554703104113155456536303543617108241084365386764253004844717327286064008824375547612437003687713635685066644742221774873358808665720400037071175028268662180577204401046247407058352323335075052670824212300407483106303227830177854464331616047542826861670237417840476056071515848278403033816884841214314076440461221508580035331828782618221062670850105785181770543082612856215036712840812726467805080064220170772536041034233473660817847175128245640505226614302508264364233558221033502567126054184687247511388085075262104876576227676324033577673623810188261171678788152746506166666437714701318570634332258550030740802413325435742263763045437462580115223212302255580103400865160557838787133716521241880267285308440147661876354467437784576735016345306611633062308811754584122563375147088373865225564243753521041540308730534446822385070861372114166326555121551770304536258008600364651176054363425836546104588565084542687503166017467336054565181617671174833865845685463658560857723333778762132475402167621010761623608348147038670132886240342442203328236027687753446546143324435782630665465553071476465625052657022353521572181631224342003132015665731086200251034727642342042768724157205803313336582551523358281602585074476178580187227145207635537012102513281730837422237248644518856730446206270316046650705818616665454358454738580353684110371157587563500822416111325582357584873627108128414201573148520755163811133056706316481086737445764287175387115416137177806484511265720218435445723261765302547621018234141462250030101638825222058372031833322338705318630036282520683874156368725686845163013242685832845523211553403620674105511622738815740862134023810117557426767760474585642644381655073854814045378307374382347381682033386078518685732885231765713423524881768718425148633644633286058714086311531058034818681263601377352475382525127272081155327226706655400072010405570087661815758158316283675713547420087156758728037757338135282288202782248501716018427204542088117607023584376282157782581470415233186584826507805762724272460033571412651326634402130004312645872667823075287652008020443487546340027782053437118628753610138356363183678428866266814623572045615003787625306877435726552077775273853857342148168433307612655423471126126802170023576688573236778627018467128804074385508720177344051461510855273367027750453251260135356145844210610652605165255220226672777165242368018647605284032071386241066412541114087584161112462346880726742547517663078120246705222743787525124154100750480507431087464341512207843441744722418777548374068250520572687713551245737701746245167380432348183857040811300514238606167175033186851181631382615450327661753468814784210764752450808523060630255288500182478823571263715802420751310703278612077507052483158216127060610280280340534522742587786314172781347215116342513C16B0A1B5B614ED286BE55E5CC1777A2680709F20FB7C0BE8326186386A4F081761EA493C531A8A89B64AC384C313F63EF47D643A8E614A9D8D00EC276D1FC7D84034EA545B2FD2BDADF7F90D0BF68EC519E47A35F14510BFC78314E51AE02001C503E723A4B6CBDF23A73D7E0150A27CD344520027639033E28C34E7E6413827C4F8213F09BABD184118676D5E1361B056F3CF3D5E0CBDAE14AB817EB1C8C4F9A94B65900259F62B3E099DA04A73CB7A671DD3814FD163472983BC8656C8BCBF2DC6EC110827656B37ADD2B79E3B7FBCA07D40DA224F67A06EED7E57B0226434017DC436754C5A9464C687BDFD74E5EF2ADFA208F44F18A40E36EFFB2271C634F1FEB5DDE90C929EF2106368C73A7672217BD86489E0F17B5EE32A61AF1950DF50E15E3E0DB1293E0D02F9DAA92999AB5BD13EC2AE956BA90C226FD88CBC6BF31FA87B403AD68D166F60B25E539B769ADC1A80918218DF163062A8671F090CF07686490C4AEEB58D396CD41C2111316444FB56200FC8B902A2EDE74F410C30153B8EF03552470F1C00852C564EAF18CA6D5DE6386F2077837388D3EC51894D90C2F86601E4CE8D6A974962189C43AF8C9F682573C794669379FE22EFAD679E4CC797DAAD13E7F41EA7990D62074DF58E69F0F33AD8A1C77EB95FD8253C692E3009239B5664FD4B86ACAF7403591C3FC2AC97FD750F09786A430351079FC257DC7884A45F9B418EEECCAE1D5F63759E3C9D61443EFCCFD751AC19A9959455AF7A49433032F8CC4F5678F65E9D6FA74761B9B9A1252928D760113DBED52CAA13DBD0B1B9D63D7F97C4A71A417BB8C823853236ED58721F903D8F3B8BA4142D9E4D3D95B59756B9A7D5FD0484AE286CCDAF3BD033F9B743F5DB8592253848FDC1E2DAE0FC717D056D8D36FE91B3B15C1165E018BEEFD0A28C43BBBB5D95A82CFC1FA2782F2593DCD3F982143E7AE80F70363AEDF228A7D847B185CDA5AA435BEF32D2E4033C34D3C164F0CDCB98DC36BB52A2C8E12E3E3B3D08DDB265528C7F4743E34CB72CB663EF69E086E6D46002138E35B2130FF2CD40D9854D674F98805B0041123CA280589EB45F066E7048A2A6E612E81AB1FA93BEB0FE673A9092C6F72856B696CCBFB6558A39209C92C800FA0ECE324091B88E67FF414AAADF439322E4DD3D6EA72924E4960FB7A4D9357BE2EC4C3279BB9BBF39AF61F0E390C6DE1F94A4786689C0CBC2E9ABBF3DC6D0D3538BD872B882284231CB76C5AD72560CA2FF6B7BF99639459E2861500A34384862856D6AAA944737ACB263294264209E02501D97FDE1307C45D733C4D35B4EA5EBF63A6CD16A8D0D3294CD4C678AC133BC2B6315E53F4E823F3FC259FA2696AF74E1EDE6C36A5452BC5A339068320123A24D097A379EAB362619070A62033949204024915836AE207E0855C28512DAEC08E70A931C69D96AA565C55B4917CEFA3D16F6505A77CD6DA985B4D2276658A0DC6055F5BB0463C6B8A521AA8F7DF7D9CC08BBA26D85670C888FC2B2DBDBB0D42A1B15067865E0991FB0CFEF9CFB7531769B5B3311845ADF229DD808243927BE8604495F7FEFC90021D1B5CE27D372DD9ACE488C83D99EDA25A84C794FBF626BECFEA5E3B1B360D520264910496C4922A59EFAA779CC9F5491000AB2A5043E18718FBFAC21BD187CCCA87199F63C29BD1F402DC1115F07CF993C9C46AC89F394D96A58F68D9682384AE586BA5E6F575837270B8F00062EE4A072AF52C5915B770C30C372BA591120DC8B0EB63CA29660AB16FC95D8F5F804479786B68D0BE9DC758775921EAA7B1A4DB99DD6FFEF29AF98DCD566210EFB33CF062C2555F0495BC654FC4952AA72E4B5C9793917440D63D5F5C4ECB0F901BCFA5F3309D57ACB366396B88EA9DDF1B9A07F649D5C0ED5B945FA4BEAA1F01A900F5B3FB64FCFA7D087A41CA397895EC045BF595C2B4DCF5488506A3C7EE9C4B588AB0E49FCBC7547EA2A8F867813321658A6240F12A1C2E47B1960BF1BA97FEE40A82B0AA13146BA443A891EAF7E885E82089A5EC21D75760BA5B0197DF5306B3438D3FA2B799C6E171B6D9BE22377704AC307B54A6EC6FD1FC98C57BD4A8B2E5CD5777799E3B86FA8F0D0A683EEE2167BF15C064DB860794D93ED601C425598F5A4D5B354CF0B8367AD742144B1CE70DB908A466F4312FFD7FD55FDF8F820398BAEA18ADF3B14710325B93877EBF94A8F68BD5A57D899D12FFBCD261373D2940D78A940D936F9B2F88599491928A9D54735F676516330E6D3E9F284FE32001BD5A72C0C0B29E2471D77FB31351CBA2D41AB5EC5513C568EE993457BCD6950D259E41E0682763F057D3C2234075C6380D65221E6E475AEEE13CB9DAC1D789B0BE04941985146149F3BAEA4F49053CF915721D53E4969B9E5EDC83342A2328FA0FC758E806C8B9507464E9BEB51379B650F6548F26930B7AEC18FB76FC3CC6E74C21A01D3CB206E2381EB61D9203C3BDA62B8BC2AE048FF6B3484E0EBE49D3689F51061A02D31AE18D0F3090598E4E0DA7079914B8BF4D9826B2ED5CD4FE1DEF48D63ADC7D66FDE0215A74A333F13F743EEF7CF61F6403CF927EEAE489A978F0EF1FE039E1AA74EBDE3434412474F4C9EF6F5A0F1D765624E7C7F5ADCE07434F8744D966B685139258006DB7107F7B0995C923E19A1A778639DA3B596F4ED950B4FDC87057DDD5BE1D59A6E52BB6BB5E3FCEF06ED76171DE35D7342E1143A7FF257CDDB98194934ECF249468FA77339BCE39223C299840D7F9A584A3C9E791399874235B3F1C0551486FAC4BD434A4AE8F04F011A849F2C8343900F0F9BDD9F9F8B80A7E6D9D1B127ACF0A37170415A2146B03BFCFAB50AA890EA64BE874D4A67AF2799FCFBD7772B5FED6CC2E6646845B007545EB24B12F7C5EF5F9B2AB7B4AC774B30E8FFDEBBDA4CD07CEF7023F20EEBEFC5D32D138F7DA6AC5C55D9896F618E274CC0BA43F058917667894F99BD0CA6E25912D6848AB545449D1A86BFDEB77929CC9E21FEFA8315AF65FEC0A4596F95BC3011A9F461A67E65464D36A7F7FAA07C487CFD2FCCEB9DA28745B4A7543C5EF49835914B25493A43DE0DDF4ECADB68EB4DBEB7EFA3DCEE7765D07DF439BB632F9723877DF94BFA7EF26936610F41B07D56026C91933F019C923CF98C255AA95748E99475B77F21F787D3606A3676A215785728734A7446B0A54EAADF962EDFD0C11F31187F84F2629069CDC97F99885A5F0B8A52FAF7B9171B40AC47B14E00D6C708A109F03C7E7130B1747BB5243C73D18BED9F97FB2F2D0449A0A9F4D4348B0291C47F2CE493209A7EFD0487D19A41383FC7C6CC8989F641918078ED90D2154E3CC3D4D0627FC86DEE37196EE9469D5446AC97A1A491E3FECFB656A4A3FB198FEA6D3CAF6C9FC09F79935589FDA995C90AE9D78BFD33954D0F78D322EDCA54E3C4F78F9B99B9C60CEF18C611ABEEBE7892D3CEAF5D6954F7C599BE6F283E9C1F60EA8509D8EA192EFE792E389D2E2F0180B92631226" +}, +{ + "seed": "74C0714236873EE53E7F8F65B1159ACCB1994B4E9D3E8FF194CC87D7116BC0B4", + "pk": "10EE0CD7D3E3C3D54FDC1B5367B8EF0DB5A20C92946B3471D8AFF7026C8D7406ACC5943341CC53C189A843AEA7399002EEFA251842F86CE14D00D974B4208734A416A048806AA9BE9D7B5B9EAC0C6CD7A3C163801253DCC0CCDD9AC2B4A663992B9E2B7EF3E2E8B1D93E4B677D1B36E8388A919E5B3A2F90E4EE69CE88735B8B105E98299ED5A9AC192479052030E6C56CF1FB2E5A822B3300950EB73A8FA59918C5468E3EFFA4A410E44FF78750D7B209F0BF48EC6E3062B76690489E1AE93A278D4FF6EF799079A8B42863688BC71154A32818CD76131FC400F2EC7AC3DE5C2954DF90AA3324756C8F31404A9094CFDFE98FF12D1F052C94C68026A214D0825A9E009A53AC5B8AC30777E05254E0C966160397FFFB0436A2CDF4FBE10B373349524AA455BF3A1A90AE05D9EF25843C8E9AEADB5FF113ED03BDAFC1EF32E3EE3F073C0FE0906D4331E2F18EDCD335F094CB3AB30214E3AD3A919BC1470685E514F86AE2008172226495349F4A9E55C3303072497571C1F4A2A28328E7D83E2B392943A5ED46095F55CB28A38BCEA6B801C1328031889A252851093FDF0B888E2E35C0CA28B5D204955BB6A41DF6AB0256B985D59FAA55880379B080DC7C1B856642985198F4B693AFB943B6C9463EC255013265C586371774AEC9E3251817ABAF21580D50A849328A828E5CAB4C9DF78C177FBA51527791437AFBB01B2D7E88824BB7A138AC8741606270EA33EA27AFFF8B3EB0F0732F60A8D179B95A513CDC9A8072C202CF4A5DC2DDFA51BA3BD186F6299C3F7AF805993808F3AF31E43BAFCD1A53A494E0D6B2B230FD9EA2E647614E50694B9FB19A810A83DE294C6BE35D3053CF2B16591E57A76B0D67C97B1BD8AED950BFC5F8526F571C72E6646F2B9FC09C9070E4A761FD82D723FDC96110A3D50D2B58CAF753DE0C8E55F32C80932662A8C17AC9B219456AA9649629CDB604322676C3E3BDA5EABA95F4F0DA031DAB5ADF92D8AD4190EEF2742CF42B26EF53A310C15D792DDB795114505222D05C21AA2567BB52E0C20A7251A672267D3B1F6728F5A0C00E957A534BA80D996379BF00BE4A725F2822643803F1F6780785B0583E0D41A67831E9B664C4E843C8BBBBE525C10FA7A7D5D3F082BC9CE72046EFE9C40EABDDE491C1346395412845B3E94EB9AA0E54381BFAFDB8186D59CF00E9EEECA5C369FF92930B569215FD7733BEA2B7BD8DD511C12EDE27ED5BF1A28080737C73557007890FB77BC5942433E8AF06234BFDCE21FC132C27A754709AA5B8640EB2C24D5F2D3E6DA9B9584317F27FE2BB5F74F95F512CB81BCCB2A0D70333B52415A39129759D6FC97954D0CF9DB5DE9F091784BA15D360B2FCB7F0F43F07FFEC2C3161C5C80C9586BA6323714391FD388A5DAFD74B436CA9455A5A025DD79D8F35632536C1E4B1BF67A3AD009878D1C067635AA9AB6989EAA3B8D788887ED3A968155CABF5BAECC99BA50F5257E9F712DCAD05EA58412B05ED7B484F54C04FE9F235E5E65AEBF23A55F60953F165C0820A9B2FFBFCF3FC6DE3DD30C1A82731705146E8F9D32B61E4AA16279AAEAC2E04957025C3C8D8AF4064924DEFCE4CA07E6F76BC56833A83B3CA4B9AC61527577C1BEF69312FE3C61A09954B0CB6261BB1272A736E66577F3DC268C026898961886EE7822056149C35CF6F96FED8885342D12A22AEC7B669A4700D19DBA1C275FDDA86EECF0393840EA0510F6BB5033C05914CE4B1F44615C12347A45405CD323738C2BE21385DEA60ADE73CA54D52F14203616471E0D0B3C1895BB7013FB7E549347D4F8AD066E20F8AC282B8EA89B83014303D2D9FEDFF90E3FDCE51124F167C9D32235E8126679D8033567FA1E5E41985CC108E5AAAF363BC677F961C30C1C34E7A866243E0FCF79271571BFB713D86F28F61C5AD2999FE7259F15EBC0622607553AF79AF73F01E8CB369CF6716B91F46444E6E5392AAFB8DEDAE015A50DB6C032EE026BB1C33C5D26B7B6656F6EEAF7C099172BDCD632F03BFAFC76F8C2A81EA19BD8981901B4C4304912B0D4CB25A27B3562956FE094422570B08089F1E28D87F46057D4F4ADE163E9045159D0967AD8377792C4FEF17A25F11E36B21DC0347A70D7BC79DAF4BAD4A6A153FD403F601AE7BB3E78B597521633500532B75A046CB78183C5E1EB84E3AA84D09EDEEEA0354B9DB64E9B5634E2AFA4FD66D08028538D1756826CD9D467DF890AE16A9AF40E4399BED757EB5D47B21B16D271E58DBAFDF8A98B669EE8FCD42108C746AA70A050E950828E4FEA76F3ECC3CECECB99CDA5CAB069A66E216CF977C623035346574198B607CD9E4582FD7F4FBE32DA87F7681451252D9440A33BC7021E41280DBF732DD2EF73CE59131F972903EE6E46D61B1E7CED204CB149D8429BF4B05E25E28685B021ACA8BD5F70D8FC737EC696DCF647577CD3ECD2CAD3116D9EBF7177F6AAB6EE5980822E57AFCA971D4057D141F1F55B82BB8F420A064B6E7C71077BBB137C0DED97B2AFA2A4988CD3951D2447DBD3D5079920CF75E569191EE46AB04393617B188EE9F2FE6F0E256C8C95266732007A1CF3F2A388CAEFD375BA4B78FC8CE538FC3E70151E94706A111B8A26F5076C4832D8B6691012081EA71AC204F3E318DFB7590A873E0E70362807693A30B7F251E9F363E494428BCAAD217FB9D035E4195C2D0DAA0B598B426B7EAF237F88965B4A4D674056AE40F5EE78ECE6A862144AB77F48F5B37486075D2", + "sk": "10EE0CD7D3E3C3D54FDC1B5367B8EF0DB5A20C92946B3471D8AFF7026C8D7406B9EF82C67AD72D44F22E10F89E426CCFB2811A8E07750EC2935A1F9444FF4131CB48A42D748BF952B8690AD6524023F73316D90AD774123DCC5319ED02F202FBFA1F1D197EFDD905014C177FDAEE49DCBC747225D2FB3CEA3ADB8E2F10F5755F31436765238773811321733542255302236533175246241780115462104128007273467573581348025535202227888706643664845147473688287871520557661451418514328878413038641373366831185718407742631304024076022441684115028005630816212057231680771587242263888473502112263046460617144852151674704418681846542541312625882506057864440533060357780443856681154777055701564087151872280855644718015658280312863677851147420664002785211407513254877075818406464328248013813154001322331624050147360555283035458016011331203524038706005326522546840872070671102851110243378174102083335884817020806875402760403831201100510876353316634888227144764415084733285837346265644801676051255766352818487278123042115281377854803730378374471578305031582424347547435583025488480537442240264682550287888171205276633203648543708665200471783114087658344004102353745875558615862028665386814251361853842784661712201842436134335654038651468851708818528563106713814084732620424444237602114074526706512504115573852618086623748284154003702757757885036608640844880578740408271280183246214564565328110404504021103016366323280028504148533853428165340303521887433431373146283407730451035150720684600438720240345177513074482742355148418025323238586232103826864137218026215613418453320312007670683531321512305778830220658672678877563067006255872600208024500124245128464104281008478520046576600633618564710588403104531170654438824562483140304830274223077451374414444447124376042865584403545752862327612288316107336565543304420625625012177810618312506023087408115701507637225608287258644060687666174638270058500353333121758648835266567510606053434880354021738386588676806063236654101672728166185228385412582015006285747468822340712803265176441520244078283446424774241033356353475612312701617237258760886425214443261704054342328120028688506282815074881887174845040542014534164721023455783006371746652275687272147487705001375251724275752155608832577703522335257124614767107557731356735056633724055282726761568051586048862533873550710632478825084814164307166347670722803851310738410137755085005608733655557485423453372808253002062253267038441144230483053567613201418323534713125770348632334075865343351277534834615026336638362833351283363448556373502072322478778438815815664723328454262752274860247747123500500630273565256443614682104088854483626725222523065686710162472081316104233804041537588555546274842073138881460052176546281423571573185338586307437833408755217507062427213105610460654803111545817106235831580136240252415456220148378568237665852106565412111146242167358174564532174715154103728681582144676477318056841602550434801435838750170373643147742013068813731813005134634107011047674042315218355460415773452841407821547664873708810126218821246161302682282412113460675813240713848158403046611047337524175380380808012270778466665852652317643364873677411852533564414508451220153F0E1707371B65F20CAB5D5EBD4E8E11B4E4F5D822E845589D4DEF994F5257DD296A7A8B7A99B416B8A67923C9C493A9E4D235D76686F0A80C3B1D922147A744D5094C44F262C209CAE25B9424FFC972DC73F836FB02178023FA1C32F80C9738BE0B43A1D592EC849D675B7294D2F44CFE4C1075D945B06C11A2DC643477A1E4AF420C3599D3500CCF5CD9BE91602F3A3DA09678E49E076642697D5AF3BEADB383BF51FF2CB2E2C2B64175524E1F55113A4920AF070BDA6AC714CC7F10DBAA72879B73234B693B2A929FD8637A13A93A8CCDE2C5B3E5003BC9224FE8F0A0480C8BD9D12FF50B4DFBDC0EE6EB93038017377F024B2439A5E1F4C918818F3A775C63B8BD67F4D532C0EFB323CEA9B2F4860619000DF98E5092ED4E55B5D56D658A7F92FE58CA2751A17C91B82043A9167E891015CB90B1AEC900BF74770D7F442D102119F26DB95E31E70E8B3D31604F8D3F3E74E6B0936F5AD20AACCDDD7A70396F0167419BCBA7CE8B32334D2EB0688755838A03713A9C47798E4B1757734021FC6288E516492B37BF2A046E56419A1910564A564D642F14DEF38D81C4B963DAC9D23B3960E549DAD867F4280567033314CDEA6092AFC9D9A42AEA5E551EDFC4AFFD3542671EDC7740CBCAFA2299C3111287115CA755C7F9F14BAD648427A5D8DC9F687262EEA0E594D29B0B9AA6405219400C0FA2B6B8AECABFF90B0906CBC77A22926EDFB96AE021E20F930D307479D1831956EEBB08F4444A63597B3B3B2788C8D05CD519CB40BA1F74D6B8A8F6E71B809393A47522A8AA8220D0B1042CE95A744E81B65BB048B6ABF484F1747923D394BE5DA2C34F0BD81A28A2B0DCD1589EAA9F88F2451EB22B5A4C7906E818E0D8ED383749A87740F9261FB122F3E89DDE0D1CADF056D40D293574C0D8BEF6C7AE7FF2155B5098A2C83960F77E778CA8602F0EB6C019529D01B73EFEBD4F97FC855E4D11B2B8F0C791772A72931A4617535DFBF99F5FDC39CE1964D7D6F42192EE5A2F58685D18062E50AE46DC5C65D3561D4D09615111EEBE6D3ACD0B7E197255CA4BDE22464DA1C05C1601D72954E7AA5412541EEC3F43C3DA5956FB65C3CC0128AEB685C00D8B6C0A4155C1AA505D0C93AACE11BD702CA0E7FFA2B21E840DD71165D5E734738419D8A01549B4D1EC3194C6CC3243D67054C4AE559BE3039ED73BF7E9594051C30E32B31FE7B83577384336BA458201CE23414CB2DDA8E99F660B287B391F023DE4BA97F6FA87F7C2E98DF43DBF31A852EA4AC420DA3597EBECAE663A35949241C987AE63F2E0EE3A051C1F03C402FE17101680E21163886860B9763066EB9E2708865C97D9D2E06C938153BDEAC0C4BD252C5A9EAD82A5B2E757405E2538774E4E17C403C0FA87D92275C995B09345E288179C36815EE2FECCB138F5647275E4F87540A913DC6EF4C280F09549CF05A6FE2040F402C81BCA531D51A3BDCCB5552B48D4162B64F59C65E12B5B2DB7A6ACA488E5BEA8637ED36D5D1A774F8820274FEE0899CDF9BB802BF37311E398F2516DE4D4129B2A7043B39D10E0ABABD0EC17EA263F174CED22937C3DCD184531A79CD1A96F3CDEE3D1156E65623B1723F666FCB1B0DE4C0FE5303C99BCFFB31E583434E09BDD74932C1C77B1BA299087F584CF2C58C573413F84D98E499F89B50CBE9B261B0FE913F2B4C9C79C8177B749617F91ABDB62F1A7EE394FBB5CF355BAFBC6CE1E0CBC2D536C56CA0C72CC618132679DF48CF13C5C769487825F8755F616D62261B68B3BCC9837C5ECD952109FE184FD8AFD3DAAFA61C873E460C4362CBDA2D1A240BB919FD44914DF357D4BFA3943077B3FC3D052C98F325A1D0428E528A4BD88BC1E2B453AB657D514C0C38DAE4E628830881E73CE0FF6EE2D1112692D26DBEC1E66A7ADC56010BD25F9F6A7DEB15C2D9D8EE5CD0AE8FFC88F1175F5FA7380B8D1B81F0A70FCAF97B0DDE29257FA9729F5C423D8B532B3EBCAC59974DC03F487BF29CCC5D7ACD904D656DBCBB79989767A198E0EBEDA8F96840A7AB61ED3DB3C863B742B6A7EF8FE2D3F01530D554578C18E174F8A8C49F0A2B66D246346BD9D8122087714AD87FC884C42714BE251D28FB2CA0AE72AE94B340BB6EE71364F9E6D4A56F302DDF19D068E4ED6ED57D2BC913852902026E41B8AD643899FC77FC4ECF764F66EA6280D71C4B3A4BC8CD08BB218A22F5254B819626E5F809D9334A2F84AF3960B52849B7534705EC80075859CA6565EFBAA5594869242801B602B3A0D25E749439035D8EF7CAF3E24B40C7D4A666F83B0945232C192F60FA1341122C772FF83A9F41CE6EDBDBB4880C2A67F340A3163A28F1450499381B211458CB711723EB29C6470AFABAAD2B0BE532291A17CC537CCB4F8ECB9263A2AE4850C6C51C9F0195A284A90A22BBAA60C111B561D00FC0D3A9E82FD49A932E516DEA0C20E3F48F2D02DCFCDBDBE046384CE410BD650EAF21252484FC22A8E5DC4157AE37C91380F74ADE3170F70515AFD3143394BAA087532C523A2F33DB97AF8DCA20DEDF113633371974E23FD5E16B5FC5CD6A9FBB5201D0B5C55E2FAAC5AF3DF589C1A8F3F30CB4566CCAFC4E1E29618E03E936A1AB09AF052D0ED3D382DA96DDF004D59201AABA01A9809BDF5BEFC65C18FED60F885003827EC4B285C108FC5EC86CC54F400AB14B8424163857C8BDE700BB1351E1C8D9F4CA2CDF4071E5AF5623895C5E027C71B69CD0F50DE48ADE15E59F3FB5159B588F8D707BB6F78E178013D04E0B57F4601D7E473AD99C19A1077D6220AB78EC6A29F79B6F7A100A5B722343246C0F5998D77EB22DB6FDA2C14A143BEAD0BB9153F5B46E02E7527AC77B712B31785EF66DA524BD680097D1E4BF448951968D83817BA6AC22E08F337032944B070E0DE17D58E0CE99A55BC758F43BF743B1E978BBACFFFD698D85C356481CBD10C272DD6EE2DFCA53913AFB41E0B5EACB693ABEB5F10F6D9F4475A73184D208698E7D89D7623466EF4AB8332B753A4419FB459E29B67F392D008A2B64B97FDC17EBD81AF4B54F5ABA6E9B66583267472DDE96F20E5767D25FE0954A2EE9DF8F6D71FE8D31EFC6D0321EFB677C2BCC9EFAC39F517C66660B0D616FF28BED9CEEFFFB72C6222EAB8F8B85788422E0D450C1F8FC81478A6AE1523AB9C5002E0D46D83480D7885C43C990AAEE60B1697CA9153FA1EA89FD1655C5BB7EFBC097F1323B3D9373BE36842BAE4DFD30A215CA0386520B6FE10C18DCACA30E22048775434D95436D37D58BD521F7AB1CA8179744F236AF8DB5C49EFE51E54BAD9D254533D086B31C2752D1BA51AC37478728E22051A70AB190B860049D379A2A605F36BDFEFCDD7349FB8A84A1DDB132AF28F87F17A01D32CA508C1384537C79A6DC538E1C412BFDAC18A556F630DE3858D292A89A0BBFBF179AD4403F746A62D02707AE7F4570CB3A40B065B987A3D92D3D8327B1230DFC0B1263D66EE896A58FEB52E96CB87565C9A1D5185F907FF852BFFAD7ADFAC" +} +] diff --git a/Tests/CryptoTests/Signatures/MLDSA/MLDSA87_KeyGen_KAT.json b/Tests/CryptoTests/Signatures/MLDSA/MLDSA87_KeyGen_KAT.json new file mode 100644 index 000000000..3ce72897d --- /dev/null +++ b/Tests/CryptoTests/Signatures/MLDSA/MLDSA87_KeyGen_KAT.json @@ -0,0 +1,127 @@ +[ +{ + "seed": "38359FBCD79582CFFE609E137EE2EFE8A8DBCBAD18BA92BB433AB4F09B49299D", + "pk": "6924BB4257A7B9AFF095C30BB35C6AE4198263120F8039AA4E78E174A786CE008301E666F59D3EC5044DE456788FDE19EB39677B5F9FE14150DA463A706F3BAF715B95336B2D685A7CD7880713E4587BF7D857BF7E315696B8D0D9D49E142918BF0974E7F43237D4BE3AD394599E3D39BB7649932553447E5D5ACC3499930176ECD3A844A425F50D0511C9226C4B9A24F2A011CD88D32308E0312A0C87CC34A995823C65F4F0F98E50C37788CE38DC28FB8B9BFAAFA904B541EE712F6A041E0611374F6BF17EAC0BD56F3B6BF336DA9242070C2469A20C4D1616149A6159252011D299F93F986D875DD30B38A22549174570138C2BB3AA9CBEA91974F3D89BF5AE32BE9E58B854A2F8E86FF76780C03490F467DB0651C20B1DF60EB97A3C99D9BD664BE6A5E4C8A8AD4CC36390D7004E4BB421DAED654C357DA4D68498933EC71777AD64C2AE013C73EB457C68EF9A745ADEEB4FDFC879E774D03FAF6B14AAB10752E24B52D0F2D94D540A1EBE10F597E514442D6C13C2E2498E8AF3017C52DB233A90717DF25B4D072B7D88EE8731D16824C95D1FB983C449DEB466276060FEE4C7EE381451F232C29C7C3220850C61D1C3C00DB1CD9726A02A56609F3A65D3D164604588CD9B431412F1ADD914C5C2DABBC90467C0C4EA5F76E24AA618765F8B0636D7B065E1F4E6F622EAE17152458C766586772D363FA99214F472B0DB8A1E49D82D0278F2958B0AAA1586DB134BDFD2438742495007E2FE5B60E246399226947A12EA17631CAA534687CB75C060B4797EAB8277CC4F8A7A20387606EFE2DBD3E736249277D90FCAB992A8C99E85AB03EB4CAC5D88553958528AF92974718135F1D0C793EB000EA0AEC3EC1858FDD18688D1DA27278DEBF2CA8110BA4A204F7930E1C8CEECAFB73F75DDB34C5C55968A7933058426B55D039F7292AC43F64584F6DF187A1D6B003F514CC13B26C2F348195AA321DE6A27EC11348DE50D825A2964C631992E4B0B425B1BEB4F9600E3ADC4431CF2E88B4223D2DB663C3CE70EF85DDD56A9BAF138A9D7EDD894131C3A8F41A04EF9F86752B72181FABB37C86B877E61D60EED95EEFFABE6376E14ACA817C5F41961AF8A7849BAC094917B2D132276B6B3486AFF950D23D4AADC24CE98A5269E1C69917960A31EE09A527C358175CAA0CB1B018E9526D93534EADBACB52B273D735E22DD0D5C28FA3E47CFE90B5215AE24F146C3464BFEAF01D28DAA553C1E94428A104A9D78AEC762591E8879F76851CFB4648566721B0CAC1F14FE16149A9D8210CC8F2F50DEF7B46C843BE93BD8D55602493350AB560EA5BA17716423BE0EB8360AB109D8FB18BFEA040847B7335145D4F200D19CF6FE7BAC917F426C9B3D39A9CA4329818F240E7DA382761072F4A6505EA8E76C1E446FEB6625E38DDBCD3CDA81E83BF768F3E01D9D263B367303AE156C0B7183364A1E7941A09298A3ADF7BD231E6114B9DCE7952B113F78163138B9266F843F1ED97D9C2B163A6E8BD4C1AB4E179367C5AC96CECF5050FE821FDFA44E9E680B61C6018932DF717811459AF2542E2CDE77178C2E9880F011E405EAFA59C8CBBED76E5A1941104B1B9D3A60491C954755E02E894103F1F4977475E9EA36609FD67C9DE318EDA2370DCCDBB9CEF7AE6360905EC220838C9769823441CDD0DA8EF0ABE5F2D1D76E2FE08FEF53DE1D6166AB1A92B1AC093E5ABF7658C4B57287F2D1FD7B82DEDAF8D5A4FBAC4B35D58231694E162497578ABD7AA7C8FE7B3541A7F18E54E8B7F08764C5E68449DF655901549832D628FA63D2B2C5A150933994A9863317AD40D778D9D2C05C7898850B90173223C7A0AF890FD7E66221B6F06318B2ED5E199CB424885AB841E7A4726FABA2F9BB53BC3236434C35FBBE4B1A0F93F50C37896C29F8E302AD31ED3331D620E3B629455101A1F1CC7BA5E46E68ED4A8CCC87B4DC75BC0162B6330F833FBA2575DFAF5B5F28BC54FF2BA81E7A47313C15482B605E66BB38C6198F1392104080FBE78B86B1BC9A6FB881F5C7820147E6BA14B81ACCF20CAE96641094C216902EA5C125F6C935A150D7C9ACC5D9E2E5D90E38C0503AA9426017C76AAFCD5261B506274EC13A9679FB09796027A4BB759D928279B94D841A097393BF7E5BD69A496CC3DECD2B0F07F83392AADE33DC51B2A84F6A07635DC0EF57A9AD5959B6A50B7BA509AD5B11FAD26B419F9F1E3F9C7329B5A953D7CC87B2DE210611CF52A639EF2B3908012CB88E1D6F57625079CB103D6C98101A11BD2233B65602CA3049BD320520419F76B061E3598DE38152C88767D1A24FBD02BB10C38EACAE317DE6BB287B4D2CAE5DA0214965D8773778626E9B972859D8482B8D0547E4F56DFF87681D5BC5120F613FBBD91E1F14E6DEFE672E2A7EABCBBB9B11082C5E700AA0B1F7C1785FCED19A93AFE7C59FA2519BCDEB494C3D13B2125F385323B816C68F8F5628C7C2ABFD0278A337073DA74D16099698C4B114E8A8CE344E0A15D0FC7ED497B001D53D4C96DC3954D3B4B956CB9D2A272C51F1559B22904B40CC8531E40CC412C68CB6EEA4A4090B38E2797329985467E818A524D3228EACAE7825D3DAD2EAA422FDC77AED71A205DA7838D945E7FEC37E4DCA67E504CE35E5B045F56F1E8D7529EBD6F1AF7B6E939E2B7AB4027D37A5135D172DA1AF9CA2F728A6F37DE60DD23D97D11E75AB1FD51F8E9A1397E5822159DB583802B32EEBB4567ECE3746D1AE33314785643DD2A0741E7F1BF2D261F22124E8DDD08C640A48B54717517C21CD325328BC239CA028B2630D063C8CC20BE9BDB48502DADDE73FFED5963816533E020AED1208536255B1CCE985433127FF4F04D5B1E2F2108704B8B966588C0156AFC2AE192986FBEC443BAEF6CB85A6F29C7792405A24114710AE1C746444FDF5FB659E5E346826207B8C54463A0617CE17FF33E40F931FE576715C932EF29FD76B04A69B58E0303D8EF25678C8B70AF12E9045591C04E8B77106940415177E868593A09C7E14619A4B332F9ADC3A658B86017F32656C5429C115E110037A8CC7E544677D2DD239A59D54D0F3C7460EC15208346BA56DF5086C5DBCC41E0C95FCB6861C2C0C32AAF3454EFEE2FFBA214B430EF248A59B32444D8D0D3DB87C9D4B1536D157728EE7585EF532776A003A023C0AB0E9FF557108C390684D565A665063266AE6670ED53B0FAF8FF67829BB737825B153A9338CBE3DF1A462849B93A81F84ED07BE6D6240003274737F618DCB26E48252CE4204DD3139FF6876F43B305D835620FEDF79AA67433DC25287320E9917967B70B2D866D17B698BFFF2B3AB9514949E58B57C68A45412C1FC421C768BF5EE8A10C8AEF56926F51EC62C11569F31AA517868E5CAD89E958066EB9EDD7271B31CB4B1D6CE211225AEB5B57F749719DA07ECBEFE03881DDE3D81E4135F2DC81AF779776C1B8057162A6C982FBB4DA6A9AD284AB10C70022044F46D400BF6AD7182D197789983BE99227979A1334BA149D869BA1C4088123435BF978541356DAF171F33ADB1C97907A0FB5845074A85D26F546135AED0F91BE4539C12BF9411E4B556F687D069DB6B21FE2B7F321887448CEA55DB19FBB8B0482A55AEC16738D74CD265093836BE99D4FB53E9B014B037CDBFE9", + "sk": "6924BB4257A7B9AFF095C30BB35C6AE4198263120F8039AA4E78E174A786CE003B9AC2C1422A1AE802DDD7464D3F32729A3C7DE894D506ACAD25CEB372EA3149C98780DCD1314BAA29B9B807754C47DE5DCA954064F28528B815FE27B79AC506B3AD7629D2C971AB8F282E0C6E7E5548EE0E113242B7A0E064A6DBCE30C5619B19800889A04404B50013C088C1302962124CD3B4910A352C43123119996522185202C38523440D90244A1A30224428618106291897680A200908326A44A44C4490218A16689AA8511AA52C62468D04C340D3862860A46013187084948C63C04404A92820082043162A23292D1AB12948B60921883100C53000C48CD98268E1304C6332450C328618083191980D10B8709B302264040893A48C21C9700C35715B000D143122CC98102104809B28641C308021307118335024254408178CC00848844490489830CA440009195119230C52200E4906321C154E194885132549A3000408156D20410CDA4252C1348C00316943822464946D1C81110196214B0200CA2884CC466451186A181000A4982160B06803946C94485180404692222C23446998264D1C01085202208AA6080A316193400E9CC81181322E21158484C24100227254226258069248484411270404C011928245A1C68CE33266C138725A86010CC99084340858A86080C070D026629B302A04296904108D0BB904504628504824D04805A24802C3208CA014004138214B240104B5494200000C2428124084A220449B069063C0888C14214912105416242087445010850CB564DB2441D042299A168A21B44C13B77010C085190269CC40611C4846980625601446E4226224272262242944C62D08318420322104B4610A3812D92844A40820CCA8290B21310A3429032140C1A26C8A161252A664A3B251042951C4049163B02D1444308C40660C400C01A52C09942D62C61103985019104D19A828D38640C0306554A671E0B4859B8610043669D0462918A371402249004385CB4028893666412269A42851D98029140721DA80911B26505BA0609942715088491023095A902122278E43B2700CC94CA402709240100A397002360E113041D8402D1B246DC392614C868D21B800D3242212C82112998509160C5AA22409344210A22403428CC0B28D12B66963340DCCB065A112114A3869CC148158440954A6800CA805C4388A8406019B322D831290090260A1288858104124400219344818A04D001062132250E338219A962153088051260199C4281BB97104978404052CA0C210D3428181424D61846C5A30491BC224C02028CA922D4A90100427864C962109194514822C11A69113B80403187001A2515214495A0230CB302C94102C00498609A025C2124C1B026940A444411662022528DCA22D0016425830665B8624D42448DB260C4C088501904921244154068402434A244205401448CA4484C0420C9826049CA205D1C2511301861CA150D902500C39868C0031220548D31081124805D1086962382C0A23709B4472E3486E22967014336CD8902903004963208A039125088921C0820C994032C2344E4B9869098044E4046994200999246D09A96001292DC842288A3402E408700C236E0A054964442A82C800024831CB90501C056812122CD0800C594861CBA6099CC08142B80024418A94204042144D19466218050924336AD400611248328A047293B46962C27141A68944963162304683426C00192209464D8B0649E1B070424431C180659C002411A83113212C4B46281B180D884270D1B00D90C845DAC248591426224400C2944150C804180000CBA62419021010890C18222162A881C89248D3942082067209A8900C498A41862819C5809A184D14102E2212520008120C334563C63010934C60C631DC400E98825060022AD22240E4062DDB320ECA324ED4182408C3284AC268E28040A1C86451C265CB166023094C820468D9222E1C499242242100370EC812726408250A202A58240459164C08173000460512904003072152C0641C836D9C322E11158A1035885AA08DD9804803B64C0110651086401101420AC164DB224D64B25102360D93463114B668638429C8102494300819370214824588284054A8299014126136120B098CA49828C292454C006063C481C03625CA882D244030D3A82DC9C825D2844800329250A271D3440D223460121312868C5F8620794A050E20D0E1011786240EA664F2F69BB1B7E30EC66B1A4A0BE59B79F2198AD9804483E475E53B3C49CB0CE5EF92912AF440F23B995813D11B59F798E93C9D13539817C7AC68CAD1AA1AC27656BD0C4797E9C8EC17784C1A327A9DFEAF4D6191EECDAFE049B733FE39D5EB4000936FEEFCF82928E9F94CFD5CF4C1E3DEB1433A47F6D328B5E83DD156D0182DC692347591AA6F732CFBE982935FD1846CACF4CB8515C55AB85EE5AD44CB09D3269E2E6D11780961FD131D5E6FBF89849F47F2B71D8283FF25385E52B07DBB266C674CEE3D0B5DF5A56D8BDCDCFAAEE6A248E71DB1345AFC597CA830A1A35B4396EF4C1ADF9ED01BCE9B6EB637FA24AA160B9076BAE30559F8B29DEDB3D25B79064AB0CF8B8D70ADDDEB8B174248D5AEA4D18DE43B8938CDD2ACBA5477BD4AACC3CE595E5D269FE675210D23152B04710F368428794A75F49B683ED20DD647515777955A8CB38A36AFCD2CE0ACEC4F0DFE807702D1EB3BDE72E9E085AA4E09EB1B0947413852EC3C0AC52F06CB959C85394EB3748119EDBE6C80D2D8F792CE0D915E4F4B151EFB135E7F4DC97D858141C57F70417B43A6A126956978D78EFB9F037243B4CB41DF968B7EE5B52087F05AA9FE487BD16C0347CF1335760BD2398AD54DDA00A5AAC446D80B1C7998C602192ADAFCB809D14EE328641BA3AA00F8D29C3A848ACBDC1946BC0D35E0BE0F8F7E3DA3F68D9FA9768F5CF275534A0ECA9E60FCEA38F1E042C316143A767B33ACCAD8C8D66C70C75FD1F0B2586B653AD4AF54E56EF06933EAD31DE365D110B9C4A2A98BCBA165CAFE386F887C72156EB14FF0DAD665616CE3CE65C1904F2C1747B2EC2B5C9D6776BCD79E5AC64B7933BDDEDEDDBBC725BFDBCCDE2FB375AE2BE3537BDF89BF4C25F83A49D6A6A8D0761CF39D620C53ED837D198255CF5B910A6DB57877DF92D8BB6E9C526B8C4EC93100DEE0500A210C984583E1538160EDAC2C6F866E7F5D99D7B1B81582F5D0EBBF2786E3F556013BA9B6F656EB798838EA0579201A95D56BBC3BCDB9511AFBD4D81288896F87108C077F1A81A3BD297BB124A80086890242995E03CF42A0C21E272A9AFA1DC103463D2AB494F7D017686D31894DD2F6EBB0C3CB6223EC79C65D45C1B0D4EF1961F16D653FCF25977B651EC51A13AE8D4A3472EE71969A7A936F5DBBB9396A46D97642358CAF4894C9A6DF84A59C5962A6990A76F0614890169F001870D49CF2E75008CC4A5D85E72DE2D6CF3FA71852253522FE8B0E423CB417A38EB78C8763C3720C04E67FF88979EBA09E34538BB523B99B8E34167412F77AEA894D83ACF946FC054D0AF47295E51ED83F7486940A4D41C04AD7EBEE610BF1D03FA54071D51A1509E4F49163A25081BE8790D087F5F4F05C88550FCA9BF99C9BE5953D51DD0845C93E41EEEF62E0794B2927C4F5ED9BD3E34EA9200A79DDEB4B2D8F305FE05F827C7E2ED186341CB5D1152FC80104E0E13683D941294C778417164B684A976E56E78DA4D17C3C73229314870B85C455C23B830B9A28A3D8C0B566426DC169F326ABCE2EFFF39E9B199AE5C1292B6F2EF37AF1DEA9272C8D5423DF8A5632F991E14DCA2514788B62BE164828E9ACB893DDA602A5E2FB9EFCBEFD95ABFB82D2B02D49CC53084A49AB1BEC23E5B4C8E714CB03405F1BCF7E11BB59729DDC0B7BEFB291276DCEDACAAD39A2F01C7DC98B9E065EAFED1CC8CE3E848080A2FC5B98C9F6BF5040273342F0312F8B9844594A503DD3E6AF1C9E35C1032A4A8A5E7BF33A82F35E16EDF8C60C90021D8C0BA4C386245DFEF09448431D8C00D1E26EE4D8C77DAA1A705ED4792ACB4EA27C1566FB56683C43BF67842E67534CB3F9677C8AB9D0EEE7827CDEFC223AC948B880B5F1CE9537272932002C1A4DD218F527166EBFB2B2FA2BF37246ECDFDFA72B6DA11C30D1C7D248AD64818F691D59B755DAF71BED9AB5FB52E03622A900D66B4C6384169BDF9EB61C02DF45FB76B1A26F34E938B190861745C021FA876200C7FC8E222DDBFAD8BE781B185424AAAFC65862DB132BEC6D18837A1F58A876C99E63F51420B83F459675612F7ACF80B4EB1DD0721CAA1B4970DA608679C6383E817FE16B66B19181EDFC39270C7E917B1F10EB7A011997E967853B78E00CFD58D224D933CC5A995532DCD4E532E4030515F4A05B331D575DDAC29BAB069F09AF0D173373DB1EC2B6366BB371008A2386FD88BE77F5ED5E198CBE88DF24BC6E393FEBC10C470A72D47C0F834653C9AE800E893C6BA68EA28A838FCBB69C3E964A5FAFC2067DD406B257C98DD3979EC7C7ECBE96A33D85515DA2CB6AA5E1FFF204AF62DD4119A0E48C04A3F2B38660F52964D8D4AEE146A9C53C31906DAD0FD90B5D83B3E31B690A4C4935249981BE1F1A85EC6E0FEE4C88F2D89E2969AB8CBBEB501916558D29EA7C3ECF1C9EF1A04350633B4CDA737DFB151CB5E7361173F3AEDDDF527D73F2F9D5B6213AA68F883E9A2633785EC6BE642A9FD0F21A42F6B9DAABDCD1E6ADBEF64841B59686EAE3EC88EEF0A9CBC12BC012622DF2DD93A86229044AF2F260D2183F51E833EE92D98F0251E3F85FAB74CE367B8B7AA63D3CF8C8BF4D78358BAE0A0241E210AC69353087CC7331357EB4450F9509CFE595F54032EE057754A8EDD746CB9282E768DC6B830C5B4A219343AD124EDB3BBC42505566A7038C959BC35585B6055F1968DA243F778F4E46DB462ABEB93B81243C31EB59622EDF81F06CCC61D2A6EA73E109C387915F277BCF1FC11105BBA70293C0FAB5C065F23BAA19290A302F08091107A4B1D568852622098383427760EF8F2928625BDDA5F514C5ADE959891EF2959F248A3532BF9D30E714059EBDEC958708F8A83C268BEF2682D603CA886347E198FD68233999C77D30D7455DE6BCFD0144277062B304BEF0E34C5A9D8D780D29EC2321E07340771C46360483ADCAF12D5B79FDBFE2856ACE8859F6B12414B3F7E8BB5813498960F34FDC64FC848579CAF9DCCF19B4FB825ED5716DCCCD6872CBDE3831D67384942CD8A9EC4BBFEF5706B8F9F05FE1E8FE69D3EA6A8621C22144177B1C1259E1A79DFDF89728887BEF1A70482556831B672440E13FE3E3FC8204A02EA1EFF19D95253887285BFBEA16A0F219EFBCEC30A8AE86589A5703103A8A393FA6F6B657704AC677C14CD10D3D62D13FBD378C2DDA325B61B85952D51293871E1FCDC948C77BEAE9A6F0E87CE1A8051C8F8087685C12624BDF58380ED66F55B43DDD6D362173A5BD389859C17D95ECE3AB732639FFE451CD103EE4854DB2F39614F658BAA384BC9948D0714EB48A887143E7A1FA4B690C22B492A70C612B59FFD2D6B3B5E99C2003E2C359B1E62DCB620C7A246A7B9B3246131556F2F3D513A23C6A9FD2280ED686D767CCD01754EB4C99692F2B380C36081344C1D35EE1949736B6976F4852CFBE64FABCF11B9AFB828576B4F9787AA7D03E84598A7143EF7311FAF2970E23ED4C173F985D6450165AE3E241A18234E74FF3DDB921A5300B1C4FB6E432E698F53F66E38C07BCD6E77605DF4624D579076292DE1CE6FC6F0081A38BD92D39B24B73BAC1C52BD68E9181D3DCD0AC7534DB48901E5984F9902557BFA231B2EA28C3183262A1B2221F7426EA88A5816093A5CAE2CD5D59A9390FC93A2956944B064CF013BCDB67FB423D1328D2C6D7BA329013FA2D30EFD69FDCA1A95EA6D06C7363534B2F3F7DAAFA296EAA09B3668E9CF82D9BA959B32F3CAD3C10C6EA48611554539C37DF6BCA3385EAD3FCFF96D372B42393B73C8DAAAA31506EE0527B7FB3E593DCCCA57C8FBBD4A3C7F8A53899869132FBC3E4050607BBFE29C675E3945E74A31CD531BA7AEB2E2F0CD990B8F983A90DFEA0568F0677EA9563F7C479DE968940CF242992692865CFDA89FA078BBEF49CE4575BDFB380366011C8435F12B42D9AB99AB6A31912C4354149D723101D1365A65E7CC68D82E30517773902FB38DDA2B324E7208E987ED287D092E7662A430241BFCA552D314127E38C8597A89519D4F1E62A79465AD5F4EAA3FA77CD98326D2F92CE9852055CECCF62D63CB9D7F198AE085E4D45C8E48FCFFE593AD652D9154167BF3E6195810A445AE158F1F9A6793363AFC1F22CA882FEED3A5F5727CA76477C5F23F0FC8700CDC6A5BCB2B20B4F9266351D304A96A82BF5F314AF685C1C707C92E3E847B7047D689C70B25E5501CAEC9919626F4A0FC81586AF1EC88889B423387D5D95482618A650E80B53B07CACE3228940602E3DB47466CE9BCCB6E4D8AA61C8912583E810B3B2E7E9CB48BD403ECF08D28C70AE0B620859C1F09B61131404C3D5BFFCD860E0F42AB299006230B2876D77DDA91C8C62BD93A844E4B344E3255EEA531C6C458D04ABDB0FAEF2D1C0B4C55F570A5A51023F4D4EFFF59F9ABE17922FE732CA71BCD434AD7710B84CD4AC9F2507A06826562AD7F647826F9DBBE4EDD23F124369DB8526FC2B4D52F0741415F972BEF6A935BD812A56C8221B7DEF0F5106BC01E913E3D43DB86C2BB4C7E0762663C6DE788721C2AA07F8954887E2142F2E914A099EFC0AEE1339210D3E53DA3ECF88624B1119BE34010B886C80F51D1850838F2150E72B042AF32899C0D3D7B02A57F8CF263A369562E4E945A31282A502A95EE9BB0316C6861006DAC17F936F54C4C7" +}, +{ + "seed": "29B4987C62218C19C77D695EB904AFFAA1BFEF6A52F138604CDAB1534E66DC10", + "pk": "4E130489218BC6CD1A9DF06B2586365F4362D8A007563DD1BF7D77F29663CB459F1B080DCCA1E39FA04CC66B9DCD4A6CDD2FDC25B96E87D778C068A41D7D4AB8FFA0E156AEF370568021A0F56EC60853AA4579F7C7151A31A7A8E5257D791D06ED11CB264B658467E82EC5EFEEB6FA224577EEB84D4453C82D821B87771FE57B10526B6B003E94F9CC812731C08A4B9FFCE90A06AD3134BDA3CF4E7E46DA7BC775B95116E96B53817CDA3FD3BC4D6F612C52BC2EEEE4153159B6D223E7A7B20EAF926C822DD064375FD26CEE2DA8DBA4665409D5A4F38BA2464D393FA00258379038331E4FCE0115988C634A95656888EB26E95049435440F42006C3515C7BCF4EBD138792B163ED11ECB45719D9B7821D6F7768B631D67DC614CF595C42FD2255252152C38190A5E41BC5868839EFD2E12DD73AFB61E8719C0ABC10679249DA931B4BBA405A46C3C112A4004A8E3A273965DB3AEBD8CA5D2BD12584160CB21369B1C5163D111DDBFC040CECDAE8B580B038B0D476211B05414A04B72AEA2FF2BE302422CA22F77CC5E4B576BDB838FBCDE65606F841030C2EBEB821619EE7C3C60C82BCBC3D55B0150A72A95EB2363121B925414138674A0619E128EC73EE4A9868D257F79F27658657CB72D9987FD03826C38DE6509F97B25144E4D0FAB4F40A3C152CCEDD908C50F8EB12E775CF512337BE1DB1AE9B320541EFC0DBC70ADC7C50494295C11D5770D6AECEAE9EEDDA468AE90800474D80B5BAA4CFDFA0A56F3C120C8A2397F31C429F915D1E748539C2A60BF05FA043E93D503FFFFD538D5B22BC0FE8498DCF20EDEBFB9FB973CB00EFFB3B65DE718292D783A16BF01301AD2EE546D48C0F44A05323EB15137C0527CB1A55775A6BE5B0F3862BD8EDDB3CD54F9AFABC42916DB1473DCDF9FB115A64F8EE011F2CA6D11528384B3757711ACA40979C23E65DF41F8D4B2D593C1351B713AF8421970D9ACD3F7E7ABFC764B8CD985159A78205F20C7A478CD987A18325F20D30C33B172E94A7C8F3B097A0627EFB6DDF787973F4B410EBF38E3215B59A4C218FCB5973A378D9A2CEE29986A61B841069BAC816147D0D8DB1BFC8E7E0FE811B589484F19FFD03890861703A27A0C9D451048C925C40C888410044F7420FC25B6B79F99E1055BE964968C354C917F3F981F7B67D1AB451E127CB50E5A1B8C3F179C3FF2175DE548D1137297555BE12489E6F3CF2831DD0E45F2E4151011DBCFB8D55AB280C0F0B5A81B492A33C674BE15221A990B800D9CD5DA9048FDB938633A3BA965398D8FF1AB77F301ADF74FB7AF818E4ECF587416D1CF1BD0F50A65D5EE7EE34E1B6388A3FFF8063B12551BE96AD882EA8D4DEBD9E7DEB05990221114784E7D1092FC01F7BEE9EABD72D3F49E572BF79C771F3E912935C2C71F61BF53EEED86D4FE1D85D702E0CD0D322A92C39935C9ECDC838242C3C97B708A40CC8311F72127FA66F6B63F640C1499F1C70AF48179629E404ABDD56518268BDF1B55F3A6A61E4836B881CFE7B64A9663402FF2DDA2997BE6A557580477ADDC419D5932324306F4BBD3E014CDD8D8FC9102D1431BD895B0809F8BF9214932E915FA0CD1A67A00DFBAC207189D9DCC0A5E1842B92233B8336F19868F29EBD31064EA8227E157942ECBB4C05D40926B4497F277394A7625DE21518C1CF3880F6E23A0A18918BC441A8E7A2E63DE4A37EC35E559FC5FB0CC0E016CC7FE06752866DFB1117B07B635663F39974FD138700545F6B64B2AE401EF894DE97FBCCD34ACBD5CA3AB9A63864E2B0B5B12306065268BF0427478CA944BCF25B2AD50BA6D6481AD0D40EADF2977F12D028421AFF4556B7C450BD8BEEBC697005FC656051E8EBEB7F288361DA5F91AED8F578DF23BB964C68107E0FD6B4C022779F84D78B31F2D152B07D1DA564D425484A0A5F223C4EDE705CAA2652179FBC9A65BA065039E2D531B80645FF9F54FB131F697FA80277B743F33588636A771CD9DDBD0511FAB5F1642A02E043AAC57618887534FBE5EFD1441028BA58D68A390A3DF8EBCBAE896170BAF3E352DB8C2857DD5EFA25E2695C157234115D136631CA96CACF71D6DAD9138B86366FF62C30064EF467ED753D8560E47EBAB157E5EFE8115907092BFC06DA6F33FF14AD29573D61EFB73651AB2B515E67E9215DDF86BC52D2DBF2A4206AEFC55411784D8A44291AC7EE56E9D124E1E69B0C5DC4E418D88D3AEEC568DC2CAB4D812B124C7CD91FA8613AB0A5CFCD6F668075DC4069AAA37DC3C7EA67C184E02B5BB33D604C983CCB9ECEE5D4B6AF74E6F44932937425B18438F3D5F358BDCA002F8E0596EF63BB934A91B0DBB69D9B3830A5CF6E1DFEC05629AEBF50F31D2EBBD9ED0894617878F1B9ED88F0F718D765CEF17A06DC288484062533681506E440A3C0E84C90119859C0978D612F0C062BE8FC5FEF3A4759C9E6193C66B56FCCFFBB6D44C713B748BD4C4A4FABB9DA38468CB4300437E5258C383EF438323F23CFC1D6C77304EAB8629A8910CDBB91C3B5C6EB81DABD2240B62E0D3C60C25554150F33387461C514A258DD2FBC1EE8E39DA5BAA6AB3E26AAD009EB78906B488E41ED03EFEDE7D7F8E67605D3C3131F4FE41C79F9C146B6BF51C56734BBE8961421DED7C16A44730093AE312563B6D98305DF2EA0527E797DCB46330690ADACA60C4A240CC42F770375EC7A49800FC573D94E168B053DE9B5B485A530BE485EE5291301D8A70F1FAAE35B49274BF0739E0E5DE495FFD791B6A3C5DB7D81BD7EBA6DD2D9E326DF27F2DC957943B5BCCCF7A616B41B2DCF2269B9AAC96CC06337FECCAD0A870F0DF3F1F1E99E45869ABD22282EE80603DACADC28288B4D3BCD5FDB39C176EE3E92592310B3A7D42B58AA477D832E113D696BDC4E2A5946410803F24203EE93C13BF380F4C84E2C62722F75851E54B0718FF23DFFC937BD3D1D2D787673E60BD218C102B572C874EE3F5971EF7F24EA5EF2A093B6813718E526806F270F7712117AD6BA1A91D1A3CA817F66B0F354BE66DA05A2EF3B9D05685C107C74E09EA8BBFDD182A1C7A6AB9191224E4BA13AF29076652B79419E11060A0BCC68EF8F97598888C12BA214AB25FFE68298A959B0CC755F00D6FF2688E20451728C51AC2FC96F53115591845AC9E330AED88A7387B5F73A136E598041F7E81BA18321A0E620F088A8A882C691E9D8F99E4C00AC849B3057069F9A5A0024E3015D613B773AEA1E1581AA57FFC246E5EAC3DA2A84A4E48B60BCFA9EC42686ED217469CDEC1912ECD07A5BAB69FE67BE98515D200022B408ACB03E2E927E3A77E4DFF29AAAE0D1DE55779FBE73FFD37FDCE0A3FEACB64DF225FA31324C3E276BCD4753A2594032FCD27256ED4F34DD2BA992C3AAEFCC89F89D9B46635321368F2DB71A3F9612BEFDB641A6B33DC3D8AA317476BC805959261426F7331DEAA84B8C6BD2142B3077BA40A9284B6DBE7D6C92DE0A99D0C1BA619946BFE2537BC7AA29BA4347AD4FF2F5EBB554E740E49744E3200B7562CAEBB9FF565990B6C79E917884F162973DA858811C0A8D2799F65AA7B3CC8AFEAB97204EAEB83EBFBC6A688E48E7FCCDFF21987AD436DF23C16E27F9715F7660884E553421292862B5CDB5A246B13E75F5677DB14EB5802441A3F01F", + "sk": "4E130489218BC6CD1A9DF06B2586365F4362D8A007563DD1BF7D77F29663CB45F5A174EAF47F9C8BB723ECAE888081EF19773FD058691588480FE23247C9886F403733B8A4D5923E737E3EC5A5BC019D015672BF421BDB6A830CE2F9D229B6D2275C41BB2F14A0B5632D21945070EE1653E97CC251C8CDFCF4068211CB6A24D68A1290123730C4B87141040164442E24B4251B05251A248C94166EE33450844251234085591286DC08915CB870C2326A2497109186095CB2101BB2485C445261344C591012D9286023950DC0266220C70100108413A869C2322942C62520202182948908153153166CCBA0000944501AA90412318851427254B66002222A209130182344931629C80689E1B82101426D52242C1C13855322229B22916290909244308A2861E0A4518B222813111218098100076A1921419302908824621832280C898CD434000A800C22238CC8981181046D13899048024E0386204342699C44650CC2895A882559A06812316C1127680A394648B651DC384882102DC2364A02A12C5BC02C24A50118912160A64D20219100164620400150321011A2808A360E94124C1A1525C2C88C43248CD0266109076498B401C1484E04A010620201DCB0818C066624170222151251327291800024272E2009450AB9101400668410260CA25000828198348854060E9B36321C87040093444A300DDB84899A484A1B474513805053B840A38431412429CBC248CB3646A1340E18A269C9926D48128E04183049C8448C92800A46450CA05102184D19150108B8315A060813446A5B48655494411001689A448800305012070152442CD83080C0A22581226A194500489250CB82851394484A1051C3046D89124D02922C2313400AB14CA3B4241B228AA012204C0401A144898C4271641226C8028A884600E10445C808699A00804A3001DB102618B40D0C3204DC8665D898499B140964844161862D10808510016C22000DE0A830C418044CC049923485C03671A3022103A16DE0207112A7640815208AA4044C164EA12066D98001233730C3182220460410346890B42454424444B89042C888DCC29090106D13464C98C66443048582362D620009D0962812C02C88B00C5BA805A2C8619A84694008321B87644228011BA74D081761D4228E82006A5A420E5CB86101B6055B32668800318010901BA631C0401101443010450111A728843426DC90648C306481300A1289681CB92122472E21482A242705E312401B994114808C4B40104C1681584488A24672D3021121444552425108172C4A902188120221A02841822D58224420C500E00030129844E04231D31226CA960D0B4909CC480181262613248D98182C18448CD39200A3C46888102223136423238081A22C582009DC90445A148EC93291E1463122C981A02462181384DBC285E100905A10655B262982B09180C600E0986059306D18190614276D0C24851110200429894B2288C01080A2160A48B08C62304EC0446D4114211C3392A102891C23260B1209D8340422C224D4368D041451539021E1C2608A841114132920B90D984292C4361203909093C84493009221156523257092106E14C3701AA470E146209096280B342D18078D1A373110831083102DA20470822010430860501610D1447288906DDA94245226281025000C334143A04993386624A75182082844C2300BC47121356D0A300EC24240D4024A80302591B860A3042291A08113940C883800D4B670801268620648D848064806602423509A346222433183A6210C04484130844994805838049324286300020CA485C9C05162B28499166D98108183B681C0340961B28541348044064AD8320941022D0A352C983664C288695208850AA01000A22D1C137001A50081928509838891347111222D43862CDB24728CC4645A288A1C826854B04191024003486824346D24336C5C266A8104280BA4501347911122280C4301192124503840CA20315A488A04B8509BC26421450DA1340C634072DA288224C28404006620B729E2A6258094250C4265521040C32882DA1286022586884690D9288C02403123A861C930711828688C0866C90206582088A4A445201560521832C092600A09519404042302219B0620D1C02801122D2089600AB604642051CCA42C51164C21110563C23188C20544444563144A6130888B3860A118904C3852EBFE4A5235C8D8FDACBF1F0546D7E244B119225B648A9D6F84949F1097FF2A302FFD636B8ADCA5B833657227F6432C2409C7BB078696CBF666B7BFA550E7DD1EDF40119D51EBEFA2862A773F05427480464D6279581BC7E8829DEF05EDAFEDBA3894960E2F9C2700C52EC53BA72C8467097E08805A4C23106F3559C1CCE2AA70C23DF45DEAAFA26500E17E93C2A9FA71062E3DD628EC4065F78E192CEE47AF2C01FDC3A495EF01FAAB25C9AEFE9431154CEDBCABA4D2E9793291F52F8AB834129044E3C69DA4F726CB6909DF7FFFD4B7B48C1DE143CCB63E84276CC00595C1DFDA1FF6B134DA457C2B66E893EB6561DE33F96F8426E0E2791A278286A6C5B5155AC2E3B90821828C3546E451945863C0E9E2853F7B44C296C454F991D091B65221C1324809A8F683DA113DE0FF641C9141D68B888E816602F165B46777F1157C4D6C4656A5E99BD0EE46F89047B0C4A509AB2C3BED7A175E45815C16F9065F49C7261959FA0F9CF4B6A5A5742AD6C4D768F7B7AF02E453DABE24AE382DD50458A1D20E4D9F30E98404061F927F26A5B6A677B2957FE4C973B42F2A1A9F61A7C4DBFC4FA590130EBE23E0921760EF05F25D6C7A61E2B0D636FB21537298EEB279D38FD4B85744CEE35D168590C53AC9AF082A1B0C7A46EBE5828C6B98BD89F562C1145DC5A54B4ED8F7997D0E48CF90D56B9569D3A4C4847769BA3D1ED526724ADFAB7229E5CECAB2D08E7FA9B096669D063CA3FD42D2153FEA0E703E23178233435AB81E7588C9BAE343FBFDBE77AEF158DBDCE8E1A4C3A69CDC67F3EA1D4C923118310930CD2B83BF534EBA764635D12E5FC86EBF2560D12DB4B24E4434C9135E4CB7631E0B8AD570C54584BA92B27B54A502FDF57896EEF6054D55E2B15769B53784C8D024EF9B10CF583D99CB4155BB4E3E9B2C28D382952C062F6319D26D7DCB0E946767D13B11CB870265BF829A93DE55E17AE7AC5D706CD0484E62DDE8DC2B16CFE5063EB8327460C516921C312F2C47BE9E71AF239EDC87FB8EB3F2D712609B615FA634CF9991DD10C1897654D5534A537A193741AEE36EA98D768349BE367F63E21EEC6D6A5086C7490E6F6AB0D7776CBA761A28FB5C3FB1DCBB4A5A90F6A8147C80D5254C8870725FEC69C93285A5A974917A7F3E6C7EA58416B814FDFED39AE3AB71A62B0CBB0427EA697DF596784EFD9D650990DFBFD2B5AED08AE76A243497ABAEC5591150616BBA7D7DDAE4D522067062D98FCDDEB0360C2099F13CFC66D001B18C4D1A8CAF7AB4C8F12D9E931F641AECD1F894BBBD3A62E7EC18CDC02C2580625B5334E32E565D4FD9CB7EDC25E9ED12D0DEFFE81E94F62AD696BD3F2BD17585E9E3D87AF16C9EECF24CF61F53669918666F8585A4E2BC34F6205F5DE856BFC767C4D0E2B67622416CCF8CB89A619B65D9B0D002D457C5388314DA854C4CA94EC466B97C8A55DC08C73F7FF0DA6D898B7A77062F9150E322FBE3339C62AA192DEAB57816A27EEA7C9BCA609E79AB10C88B0137811BCE51E17298487C287074A0D1FDB59813BB535AC57FA6DE8178C6CEBA4E6130063DCA5D7E256D173C11E31BC072BA6A70582B3146113DF433F93D74A2A72CF55482A1030DFA0C2C6A0AFDF5E9837D22F7CE89C9A4D81FAF4EEAC6262701B011CAABAD823B5CED6918627F66B1A07C3E5944D53E161AF56478F7598530BFAC4317BB363D4B2B04BC3D0CD938527437C2F88DAE1D447033A315EA49B2ECF62EC6BF95711A57B7B6C0AB04FD6706FC3553A7B726F30C06347F4CF35D989F57AD779DB038280BE50125B9A8AC1A2C84F9B8C7A650A3EA1533F575CA029709E943DD9E1F2ACE7757143A8CB9FBA11025D49CA9CECE240D1B63140C30CE7D0EB2311E5BD9CD7EAA3FE81E93607D14D5D329FD28FDB0E62FB87D448C3C1F85B42FAEE0DC60993EBCFA8D848903E55E2E987D34467400B8F50741EB573BB9FD41A0A5BA61EC07EBDB2675912DE28FECB52A40494245EA078A754C1B9641F4F2B6D7512944A83E8D1A70B7F3E62A13E9C456152F163BA359752A91A8F833373D6CA24EE0901657636FB2DA1E9E0C16A789ED447036002098B7D9D66EF633047792E9CB8C8CD45DA05EB5ED49377F060CB67CC33AD0D609741D0B3DF408F584D83910FDBCED95724714F4334E8C6AAFF680D5AD60C5A1402A97641DC8FA7B1531DEAFD369EFEA623F475694B04E8E5F52FAC99D8BA2D928E60C4D8AF2A68683FE7EE6D82021E35B895D57BF7F4BED6E2DE8B0D1DD0D0662068D4A9674AA65121489ABF8DEF5F2A9F1E2D36A8AAFF54C56E2E6217C7C9DB4B750207C5AA367A25401C7A3C7ADA45E1BF4E3D777D1306755FC0D69830F3BF262B83E727E5415992D6BDECD7EBC6DCE31FCB1EE0B54DDFAF20B522608870C9A0B1C9DA746DAA1E13A451FDD6192EE7E4514B8B99BAE4FA2107CEE404A7BA585FA7E1F1529E66DFC6435A1C26D3CF0CA13836F0B44E8947833F8DCD0DC2FA60C9E6303BB78E1C6E72A3615F9B3719E9F6A0D2F043DBC9AD7BFA803DA6FF03BA5B366B50EA314E42AEFAB8D2861462982115C2C7D6248EC74F7289A3151EEBD3DA0F43B89E9B5C50FBD0955DD803A3109EE451F96F5DBF1F9B42CA04724779F0FBE9D1C672F6BC478E919A07A486732817EC3741F231E9ED25715FB86EA804DC1B23BBF148E20DA21E6301EDAFF8813F5A97BD9F196E40BCCC824281F7C7F0F4A5D396BD2D3AC94A99B0BF24BD7888276A52543B0435091B4E94328164576AE7A572D2C4693DEED54F583D85C783BCD540A1240C40B68AD8DEEAA7255387029653228EC60AF145C2ECDD26A1D0B267695ACDDD490495CCC87BC1013C065357569790FC44001EFCAC9DD18BDF6EF505BF5C4FC555DCFB2A098108A1C06A3400C10248480C8B3836B26CE19BA22EE4C087C687559B6B6EFCBDA275926CF10F151DA7B2A0EC4DC214EAAAB6F93043437B32E0CE139EA665E2CBAFEBE56D6F1B98BC82FB299C381076BD1E1B0564F39FF03795794374269B3321C8E2E9BC6EE8D03084C3BF949E26B759E5A71CCBCE856FD0CE5FE7F0531178B2C80E2F913D777CDF265CA351FD1EEAF2650A2C8A52ADEFE7EFDA688556AC442D9D4EF43AFB177987831AD7ECA98C3042581F2389EBB972BB11C8D6845C8159FFFF7B2B7AD2E77F6FD4FE21E00A528F1C243D84B4793ECD4BE3F94E59B2B0435518B9BE6BD0633E310F254B822A66EAA384D7AC066C4F273254F3A2C00CFCC43C3A52FEFFB2B51CE1564A0CE3682727BBE58D9455533269FCE603C7F6872A6C07BB290C0B8AA95134D55B8D551AD77F071985EDE813578564EADA5632B9AE931EEB24D6966DC6863DD2DEAB2E3D0F4CB3AE862AFEF5B6D4C9288B1B3079C395924C67B03C415E7A8070A6839996C5BAC53E427A61A7EA100CC10F3ABF7D311845DCA174FFD06C3F05B88CD2FF32E9E44659D7E80F40EC56172C68BC5293820886BC47E8339CBBAD03383D099888E668AD95A905373D30CDDF91756C9C7C89F6DCD6E0BC9E9C4ED9A876F1568B49B6CCE9C520110BB205E307ABF68A8FEA783D1FF4BDE01F57A6B1224E9C83FBEA507BF14F77BC27BA0806D48F8A0FA1CC1DC0EEED7FEE5FCBEA5FB609D76413329F54685CEE7E4FDD309114F71F864A26F05A672315150823110947291991437C60902AE0767BBD42C57D6C97F5CCEC62207C8123E750945BA0BB444C894A98DB610ACC5703121CF8A93C7CA9CCDA90EA0938304651EB84D2534F2E67960064F81A41ACFE3560066DEDC1D7F954C01CEC3A8083975829149FFD8A54E3EAB95A076361EB7561EFAA8E678987F381F662B59A49579D9A2453AE756C133EB4460E72218696DF703DCE965AC32CD144C83819076D6D82D8B5451E0FBC384EA3A2C5675F2042F48D1D1A914B384DD0727CCFDF0A07218B3BA7BD10A55A550679C12244059D2DE9F76A4B1855733725EDB2981CF956D22223833FD43B9669BA21B38FE2C6BF49484BB4FE9E5CCD5F883E856DF05525D9E3BC452B73E6CB6DB583E3641D215019D0C48EAAC8C03D646CE537800AE96457CF187D3CD456D13AE4B657FACC6D9F78581F209E94CBD19B6768FBE0F558AB7E2D4938A0D2D92C6C8BCA7A01D7500286756E87C9A55F10BF60E23F7D6039E17CC6340445E297FBB213730455D0A7B33B852E4829D31BFE5DC6AF3CB5916176E4D125863A49592A306B9ED9CDBA4E2F40A4C8F3C85943C10BA10B688DDF847FA2212E374C64148BF6D1D856768696C6C8F04D213065A453530CA6964377687CCB2AF180ECA47260A493C8427CD418E91D38C50FA9ABF904E419A612881CD595821657C95729FDF8D1D965E80D8F8F82C6009A8BFEBA81ACF69503B873F92E557DCA50F87187BFDAE231D0164CA86E58025F51B0BCC8051D9A88313A619B87BAAF7B16EC52808CA8CF9856CB09A58B71FD67FDB4B3A0B88536DC3EE689101CC39F7F0418E3CEA104C62E83DA5631998DE88562499C4D18A98A1DEAB254C74334C325C11EDA989F98548674C19CA942AA95CEBBAC2A593BE1A1595B702B701DD42E89C8E65DFF6E104053815FE2D7D0908CC2698D2B6C26FE981025691A1680727A0D65C37B0D87EAE23CDA4E6EE98F7A981B9CF44B6B2752AD2337E02CEE156BF8968174FBF7EB0574BB62434D69EDE82D49BE6DADB3510026559B7" +}, +{ + "seed": "9B54B9C91E0201251489E07D1442A42D0BF32189D0C0CA8A2D4871DB25F531FF", + "pk": "9C17C88109B6927D423D887BC2FC24A5C4405C8E736C1C9D9A799C5CC09DAC3BE947BB391590EBCFB93BC00F569874F69780502C80C4EDC87DC9378294EC3D62F584E70AA18C0F1139DAE97590D0C89CF57803A26FD82F264F2CF2A184B2DA47F44E22306B95879CB3A036C918B6166E1408E59D35E2177F6CBD05EBE6F1230FED71A3CA9CA73F3333070A1DF3FFCBBFF32F82EE2ED47285D8F05809240ED1F91873D3D817AF74CAA85BF78EF02EE9B36FF3BEADFEFC436001A219770927C1756A8FCD265721CC8CCD367C7B19A40DBA1C9DEE9611863BED506F42203AEA72EF21026307AF0602437BD5A8E7B1B1F1DED44C4A009E785BD170BC98C839753F076BF7ACFCF3DB89FACDDBE5F5CDDFF76931C0966CD935102FA75A967C67222D5F8DDF2412F0CEDFA4C9FD94C6C58F26BA4954D872229BEA543107613C71994652F9268EBF81862CE4DA0D172233D358823229618803AE54608871866DCE80B988BC82F702A8C16C9A6E58B465C39197432152297524CCB00338067CC08DA6E2AAC288AA9B3AC40493A454ACC7786D6A2F261E86F4FC6A341896C2E1B7EB46AD1E4F35D970B5B4FF1AE8F514F6C78BF27A40EC941DEC16C95D9D91F869B578BF37E5164EE77DB6D38F7E65D9E703C6323750C24C6B41BCA787AD02208421D3DB8D7090FD3D154D9561B9638BC20BD55EABDFBD0F772D590EADA34FADD191F4FCD80C4B0A9EBE8A069270B89FDC2F0C54C5E9D835951E76E4255B9AD8DEA2092E806D7C62BCD7800E175C93420D7D8E3806F2B6F325171A80C34F0EC7AE7C48CF4664BF07675B8C617FB7944795070E7B47EA9BE7509BEC0514439E9DE57E4C6A2A64303176D1BC37632DE696CA7A3785943E299A1B152AC93D1FC8EBD3A451FE780098A13A72F4EFB4A41131549038C38815687150DA19FB3DD1CB611B9196135606169090D426B33C0B267CCB630172BBBAA67ED2817227DBE6FCDE76CFEA14A17A36B034977559C9E8AA525052CBCDCB66E3410DF8D321F3992B02C3CA8FEF477F2E22ACD2B31A89D194CCFCB4C41F8FAB34128EDFF327C80022CB9E15FD41ADEEE69F227CFFD706312AEE2C824FD281D62C31C98B2306D08A39DEE41BFD1CC702E55EA718A0C265E116BE6B87678927373592B6438B7FD490B2810132579BDDCA4FBBCC0764DD245F6D4DDB97943F52A0FCD190C71744C2E6352F4D0D2121ABAB3870994E21D617A96D77C195436B291ECD15E9CD29C6E05617526FCD8F853C8CEF29CEC0549073D4AFF72CB975D3B6F4EC0BB0CEBA04E35E69E702D5E1C671424EDD6A6835E0E9FC9FCD7FF16B90B039BC1B1295F88F724AFC6DF5F70C22A6E7CD16315F5B7DBABEE28B7651EB16293E2F4998A4F4640EA6EFB4C0E8F51B7DF809CD8F53A4C18F4F4EEBDB18F3CE2DD37F12E0931A46B296158A82D6F4980ED9FC9316BFD7C519688C0C4BD22DDE4EED750EA96898481D7790B95907F3D7E9323EC42B59342A52616E288717B8DE4D5550DE95560EF33FAEB2E2A4D9641FD0630F487DB670B9490D8F91F4E2E9DDB7B6B2ED9DABAE448622DC60A5F869C96E12F1B26A77B42FD6F513E9F8C0D53BCB5610EFBAE271B754C735787E9FFC5FE8778E967D713C2C3CFBBAF59B2262F1C4B8C0499EA77CD587A5296A819955781AC371C20E66471CAE28C6B098A6D25216F5CC3F52A258EFD3E22B010DFB5971B5EB004ADEB9D34375B157EBDFD3331B6A9D56D8DADA55AC152C3AE497A36269F44F3180C47EB8C315BC3F3A0C8AA1CC062C487BD917FC3988AA468C63856277620F576CD6B70BA66D3F9377CF20452DD3E7A8890FFCF309D7E5FDE1B2ADB2BB6E96ED3E8F2CD1F075D82599B92F74602A87FE5506E25E2307FA48D0C171E61BE15E10C3EE42398D078EB42049D44B0A343915F3A99547E2E27DA86B6D0B88F9529613412FF6D6AD459F30C1BBAD521E99869F1F01EE7540407D645A7B6ABF590DBF180A85076CF838D89F0BD53CA96759CCD3F11726257FF862A565217B82068BEA4BE94215F0DB4775558FC6D97B7D4F3254A4D733E6604A003C804BD380D6046469E310AB9B07CFBB605A32DF6E1B15734F8C2580D792AE5AD45C13C37D90D893218FB7BC6A449161C0B91B2FE8197C81929EC8823942A2EA8F7C04A307249CD3295B6B529CC87041B6866E9F358B5EF30486D7CE9BB297FE73B2A0BF7FE5D4F7C56281DFF8CA46B5F1DA6A14A15EBE6F6D7DFC4327834E655CE52C310B6DD6D72A9D948A930A11FAA6E57A08A6FB873341A3F1211D0396884C07F785BF4531839AA77EEE2D5BD8D1B767602C01F6CA35FDB0F6A3967C367F88762FFF45A67A4E75C16F744B6E6FBECEDB03B346EBB18B1A35D0F2CF387277CE01F8068DC250E19F0E37FE36783C0D4FF4A1292577DE8F3E81CD769B2D22EAE286E75756ECF31E56B00A57DB2C17750909ED9959946C86E25112ACFAC5F526A331B5E49DECEDAF38EEFD5D5368A8539E49A0766C22CF5F713E6EE058E9BE157805A521FECC934987809B9C5190EBD0E709D1B2EBDB06F925F3203131171ABFE76684849C0A82EC8D66ACD60A24794BD39C18782506BC7F9F7DC6B1BC7EB2D70A3FD7AEF3DB81568C5F6513161D8DCF0B9383DD97207C186572449F7B55806FB564723729394C85291E01C5EC803D8FD2D702BD9F84BAC47E6E659A3FD90D04B4F53A01DEF302898D4EC430BEB2936C70B976355DC2A68D798EDE02F534872E369582E8B4DF771AA3FB15C2602F2487A21EE9DCA0C2ABA12ECBAB2C8B49939180C3E305336EACFDC339F502EC730B55E0FE4227415EDD151811D018FB34839DCDB684C9C8453F681916316DADB8BBB025A6B66DB0C6315C73D0654113CE37FAE29DA59A893C4C7F001DE15F0AE4B59C211EE59808021DC7CCFC2BC8B2C15214B783FC55E8C50A19ABEEC8093D82C3E12058B7023AE561384D9B28307EC60D004BE81512B0D03F02388FCC2878832C1F881251BBD73D3245336E12653445B6CD704A796A284A7A7F1F7F37DD9D22C2B2BE0D3C497E2F25CB95933D154199A32D4971965BE442C914ED7C42F28D33BBB61684AC719EA5F4D7FF7202E3D476519B3CA236A143B1DD22B34F479C0519531BBFF5E1E1D8330B231D588AEFB2BABEE0A1BED4A1D775C5BD5177A8CFDAF83E5B4CE662418D4A13FE34D3875E9EA15BAA45033CFD746673AB16FDE39F31BEF02051CFF7DC335C6B9DD8CBD17CA9B652F01AF2E3044FC3B1F15378A967F023DAB2AFC2CFA577B82DA875E1FAB014728BD7A8948859EE9619EE02DFC85859D28DAD6B8B2AA72F7973D6709D1DCB0C625084771F3EAA12D4B6D091E6E5026845F0C30FEED6BBACD4A9B5D623CA247CD6622D1E18590E5EF3FE9A094263E886E567BD1AFE24D7E263C5B2CDCF03D1FFE2DE85D7C81A7634066B30E0FF49B71234DB9441017954CB05B8BB72C11710A55041C737AD29A58B9EC6E2CD871B56976C389133F45EA4A6C39545AD15BAFD9863A333637F7AAD613BB82E61652A00BF90DB3FA1B4205198A42151DE6A3500F0A770AF589AB63C01299A28F94B9395D652866BDE7505BAD85DBB2B9D56E43D02F679F94B4F0DCDCAEC1487E18B89F96BA1F1890BCEA47E60FB0165092BA684F8381625F83C86FA90F006", + "sk": "9C17C88109B6927D423D887BC2FC24A5C4405C8E736C1C9D9A799C5CC09DAC3B0AC8866103C621D3464AF8A7E67C30C8FA7F66580CDABDB9E6848E611578D0E85F99D936F0B17CDDAD87C4107D0642F26EABDDE9732CE11AE78FACD7532C2868A1A29A6B5A0CDD35F4EA2F536DEB14A7146F4E94F723B69B976F4688FE8B5D22A0B281D1426D18144D1A066403A98808390E010241D32428233764A3C220190322C8C0405A9265C8B82813B789C9089211082AE4B464D018300031644A928812A52DC2280108C58559A86111270912080D4B384621B144994268C0062999228D01A511A2C46882928C24B70D81168ECA0465D920289442329CA00924356059348EC4C46D23C52123A425CA10921441240B424E02C94C6094318C082908260440046249304A21154002180DD282294CB051211406DB2480DA08012125661B96641819125B9649C9406C180004090380CA1210D0444EC2A271D822694B2091DB8251E0A00D0C9788D044091BB020C3C04024C7251849450AC84001164D1BA96960A691C2B2288284818BB44404B90C9C4206D8063198926098846589240800098209B349A0286CA3C428C1145198222919266109A208081152E082895CC06423A641C408721126321431122231700B15868A16426480311B156E023702DB4491A130804114200A119098142519A1519814264B422C0A878DD9386402B33080B25104B785D2120D11C44864A88DE2868D1C2090CA940D0C15500A188011870513988D94A265CB164D1486418B168C88002D14C680A39069989431514866C44286A304302449048C962C0312806124456312806182098B300699A65002942D08C44124C96C000546C2B6098C0025531872CC108C13A0458482080A972554C2886342859C3049CC18929AA82013220AC0282694367049A60850C850A0B22C60B220A4388D1A128008346190366C0094700A0912C8302C41B66859B669D4C2814226699A2404542442A3245203115123234801B2001AB24843B0615806890AB66811B5641230841AB88DDB280A2437645A262164340508075200B7689B988DCA164810B9440B8490E0A41011880494184013B500440060181469540050030864C40062512030C42200C9828900496CDC96404126051B87245036495006029116449A105213A62C528224214690D4364D24014044B628D8264AD0A26C82288AD4C66920A36C49A40440068E63B405141168E0264008884419158C19C62994966110868041C43108458949B030A102851990041A166A8AB631C33085DA1672E2028E119711E128810C8388D21200CA164419C52544468D1134615C946DC0485154808C9C045153040E09380D110248D814880B88719CC60C64142812854801938DD894890284258312698BA828C2A690D4264504B57120468D21462E410241A3C0082030028B442C02264849024D530065CA24465904460A290E11A460D0A020D1140D130185D4B829494684989081DB2290D9B011C4460209182C63484E4314001CA24450B20CE0C48C09C98C8AA28011B06058C20914B9208C384CA0A49124271223112C63807102B31048866DE0882D03488C61A4895C241143282541409118286D54261191B82CD82069A4A229E4304153A20D08C1400182694A440948222D6304066434212490648006418AA40DD094690043819216649408486094715CA24D61248018B8814194200AC650E1468A4CA65192822844140D4B2006CCC84D1C3460D04069208641C4C66DDA904880A2111BB44CC4926DA1B0080C11724C204C93406111494258948920388C89982504A68813412699B6458C148060288A032402A442658AA82C1AC5412288705C882114A78C0A447241402C88180012B48C4BA8640A934CE184400A984DE13070E08404230900CA326249846400378492B08141A629C20621DB162409B74DD9A28D1A8208A3388483B60C8A824D20B48C4BC82C8100640BC4850A054E84B04CC1204C503851131305CBA210040002CCB660DAA8084AA091121121612401D016920CC950849804DC803081A465C986301803321BA1681AC904D9062C042149CB480EA11088D00802E01086D9346C22850C9B420A122948DB0089CB3088D9940891343294C8051B940420226010849114A58CD9341101355020C361A31682630231CC3881DBA809149349038948134210A304094A2688956D861BEC7549AE8CB7B5AACD88780F7B1D1597FA1BE27973CE28C4C0E9F35194AD0E2DF62E622B75E06E7E21AF5FDF3E4908FBA7D0B657FCE0A512FBF13D3C83F16CD3BE385BA075CEE26E68A28502C3C097539430E8F19916B44E53AA7742910B719CF4969D5EE2D246F5CA207AEFEB037E7CCD592094DDB72621C5937813A5B324ED4544200460F4EA7744DECC6D182A604C142D6212EB6F9F90B1AEA0F89EC07D9C083EBE1FD78D3C4C2282E1D5BA47064E8DFE71ED9A7FD7C0F95481F3CF0610CEA3FAD5C4E73789C70AF963A1DFA6DA9DF610BB98630EB4419399AFD1412E0693E33BD24381050FF62883D65150AB1DD0C67F443E5FD247412DB729D2E58453C770F934C475B89B458111DC6268F1CA0E9D143E7F0570D22AB5B7BD9446BFC7DEA9F06383FE1A0BD9E644CAF2B91AC44BFD37DEDAB4237990A3AD448715940001EA30E7219172B64D86E85C1FCA8DFA922B61819BB4BB68FFD44970FFD9CBD6BD2F09FB12E5265A5B0F919F6D4D6D06534FFE792CDF6882DA5D4557B51AAAF3A80A8CEA69E8678E66D1F47592BFF128EAAEBF38C70E8FF7AD31035DA28AF239FE245D2FDD4F853029A65399D5E6B6F4F4CA2D862B62AAEC8EFCC4B05DDCB351DFAAF1F7E7ADD9AF9FF44D2E2A384368200217F48DA0DF5013BECD2462D4BED2359FE44D9612EC6505A76071E116AB5F0F1DE88288DBE97A8B0EA32B9A6FC53695972A8F6B33542457C30C553DE91B118B15A6DB2D3F56FB0CCA91DF79741AF737E88A88A69424F7192EAFB981DF8256989189D75E0C7183E3ADA99CED3913ED35DF5AB82C8FD07D7B67DAB7EF443DF51D82FE87F8CAE103713F88E9B73F649B1D3C8589B71F06517B18502CB230EC27150C072D985A98790DBE1F83BD59421D19CC9E23D845C50CEA8515690944950809CF95FA636AB3509AFA1A7ACD2F6C346CD76362D15907764749F3E16C8BC84186E1FC9FA120F49859F7E4E6C75F7CE19C9C129C72A7CA129D10AD8EB9650DDB304F5F02FD7257DD8D71B97BD9ED47B9111236E3B706AE4800401B77E1E5A541E44DC1D686234884A5F910AAF16C8D23E593A307DA8F1180095D7A707566E9CBB125751499D748A7E1A78108B93DCFC165D2906A1DD9AAE8C5BCFCFD1D5879A8E30B6FC3EE38F470428E8455162261E7FB6F8D5BE329C0FD494492C296DC8A78128478F88BD6E1B2CBBD731ADB947300A82DE410B27C87180032AFBADEFF276BFDC0072179E36053A3F4C031FC2F94116938EF7B2A02CDED2C4C101AC0CBF0F0404BF9246F1E4B71EE2EA0569BA6478C4929DE40C56B075432203D8CD2C0EFAE663001CCB0947CA073C0301A3896793F7FDD0248F7CB4CDB184408FFA24AC8016716A7C40572731CC95DF6954A94BD2E507FCF71A8E250124E29313ACD6AED2EBBCB36ED59F102F706D5E1B79DC3D956F46997B4172C7FE20F550CFA0F1508312CAD73AAE7AC30BADFDE7D2A8B2ACEEA2FC564354276AB61A8F2D6A3CE5D43A5E6496894B66E72DA30370692421D267F04430397C3B9293F7EB11C107C2D2BB007EAB932BF25CA65D050CD061D3653BC1B25B5AFDAD7A9EA9352718CB9584615D8670CC61D7C165D778EB2766930470AC115F488C3767A6B80D987EBEA29839642720275E20602ADD280FFEF51005BE2AFFA3F69BCDC69C7C40FBDB9F8AB2C57E8745A9CA2124FFC3E088B5564C088B71847A2AA574A4251C1F5ED3F02E22A85BFB1AD2B137477439D4BAA4DAB63644A44C0CB121478A2D91E2B7B9D6CD02968EEADCB51BC5450ACAAA81EF9C1A05B475DF46C4D6603C371D6AE3A1E777A789E7205EF7AC574753F60493B81F8E0AD527A6A561F5C1723EB7E9AC1D82658C00F1CC538DD8E5552366FC9A34D0EEE1EEB9C4228C58D2D7132E3599686930BE56B9A59097B2238AC49FF4F6A9F893FBA76F511C6A6126686C0BB6CB946B0D3CF7DAFAC886BEC911564332E773C10ADFFAD490B94EC6545DF90CD12695E79936A7CE77E66C3F2781F6606874BD2E1379A8610B0BEEEF465334A455DC2887D8B35066B496856A5500AE079178EDD320A7AD2F0D350B0B3E78EA658787AD5F4CDD224340E93A06996904F9D5EA21219B871E21DD3BF7BD3BAD750048702059C86584B0E8B4EFB144503609D021C1DBD98F04C84BCE4304C834BB502CBA56A6AAFEAE643F76FBE439033D13F5FC93D8D852710C3CCA4E2507CAE51BB8779C622AE8197CAB5E51C9D11BD38BE4145CE12BFDA8F8B9ADAD8D8033D38143C92ACA69D5F72ADACB8D6BD10D427726D0F51AB7114A174E5187B8F9D114C2F4FB768EA80F74A49CCC642F5DBB7CEF2DAC669E250451CB9AD8EB2A7631E6884934E2A25FD710F3E47726D7709BC89800C6376158917026C299CDF76976624AB877136A19ECEBBBC1C36DE60EBB3CCBD43508EE6CCA750960543C16A0EA3676CAD076DC3464517FBB3B2D929AB2FA80FC0B31BF2026E4FFDBD2C20D2DBB8FA09BD88CB4B3CC124CE260BEDA345EE0232B2034AAE1E1918365878D4A0BA98CD4D7011014FF7569CDE130389A7D59E860AEF59BEB4F4D3259C1B092E68FF8AF679327F4181F6476D54D933B7EA376B1D4C0564D204CBE631C4AD3DB45F3A7CB894AB139BDEEFBAFB6EDDEF0DF6F7FD5EF140882E21CE59AC45417686DF7CA38AC90A7B44DDBE0F085CC397B3B65E6D2524CB2A6D4AE4BC69911CFE84465C9D6B697D28D84C8C28EF60ED5BC34B0EABDAE529CFF3C00F0C706584C48B565CC060A80F6DDB0DAD0799B8907E94B0C29A4E7A8D6CF0C5750DA5EB717B30341352E6046420C7A226A1935BB7F0D25E4067E30B527A55BF410B4335063ABC9BC76A5D885882AF728AD934BC7E55553B9ECA69D97311EB3CFB1DBC28891D3DBD954084E911DCBEEC1056C502385C8EDA9B4ABB93E623132084C5950FCD44725BDB70C9B9187A30DF477E128F143D870A7F02E5D2F20A3F1B034FA05475F58D98A6D8C22FFC0ED3792A1A2DDF00F62CC03CA04060BCA60EBB9CC27C2BB6636BBA116CFD03BB196D85DEEFFE0C2D6359129FE1877F723EA225FEB1E995A34B9A3A75D1E6C0786590E159CDD62B39D084AA5BD2EBC4456E694054922D4FBCBD5335F7F8448ACA08E650D296D45F3511365B5304F1359EEC32E4616C166F938F2F36C790BD577402C4A605149A4B4F8E1A101E97E22AEACFA89273B3C1824B42B0019AFE8C4ED8B7F6A265573E11AF026464BFB2C78532C0AC303EB5D36D88CC33F528E56310300D52481BBB27B7F8C523DC036B2D1A36C002B98BF5F58B4254D097DF7912D4189287A14D7AC1A30691BCB53FB9E86056852075B7278E4A50F76EBABC11761BFC5D2A86B5995B1CAAFCCE5F5B3BA2C195B692743B637E424AD4072C4B5DC6BE4A3DE4E041E72C64FFB9AF9C66353C5BB2A3967830B9CFC9AE5C632A14BB32797BCEC4A595D8761524026F13D237B165CA4240D4972287ABE72AC7F419F37E99047F17D5D9DB57C508AA0730D6D9D2049E19B1EB3C7EFEF2EE719047A777FD281A0960C09BD79443C5891AD8BCB1ED643B9A9F1E66FB5C7EC6DB926CD73DDFF4D39B15E386AD92170C4F678A7BD7FD6EFD600FE082A64AD91E2EDC675DF911B531074660096E85C66005318A3B85CF7E1C5D269C5BAE4096C9E05145C01C9A6294A50B3D4707A93254B0CDAFAB7B0ED1CA6CCB3DDC1FAA5304055C41095C503DD79F86A499F292C473C3B975DBBE53216C85D42E3E5A819E1A947639131CA18CA7831091D64FECA2713B8BA5577BB6B7FFAB6D376856A4D38856651EBF90929784436EE1F09EC9C99A2BE601294AC1C7ADBBC0EB050BC3F728D5D0F3D4831BA4DEE0E4674EBA6C2D26944029B8BBF90891C37A69DE342EC829625544A82C3FD8F61DBC40ECCC6527E06C26868B33BA362FE4E85FD8F76132E9065F6FA1DE7FC0CBB92A3306534AE9FA01256B24ECC2C63854D3F46284D0EFFEE19CE5B7998DD8DCEB38FEFEF074EF35A3748A9E44AB4F75F656FD08866DDC4F58252B25A0232180E8DB2CE8D346A558B03DD71B19D81E5B23BA688099DDAE1D10BF52932FD2EBD360E653BD4C3A254FA4B71F2859757FB024B14356BC00DD2877AF29BB57ACD812C22119F8CB62BA81C946C36B0D4CBE3A1B4810FFB27A47096108AAD74A5A0413D2A1B85286569853AC230BE9E34C78C84FE0F6269685878AA1246A55F37842584EE302301941B9A6CFB8BB4ABFBF3DAE55AD8ABF6CD6CD7B2C881DF7D5DC264A5F61584A990A8D1CCCE1C0CC05881B4358494283964EEFA16E9A47586FB9ECE3B39777DC6C1DE6931C5448C0AE2D6C51924D7F6BFBCBAF485F0F22FA2228A162C13240EB64C050F2EC800E937FA97C77E2854693A4CC83E1773EBA74CAD800F4AC6CE461C9693005BE0B3C288EF1898900466318B96AD247139E5E8D8CCCAEDD20719275E102F50F1CA019692642092CBCB21210EAE0DB708D96E50FF249E6918A628B7834BE30349EDBA515A46B0229E6E7AB1A88C25A7F6A3BDFA84EAAFCB52AA1A143FB09DF7CBF6E39FE1B813AD64FA786155C298D9483C2F9B39CF46F936AF6B95E3BA82356D7C99EDEE47CA00C3DF9A80E8DE0F246C5DE4FEB6C55B457A59CD82AFF7A60E3100D409E3EEBF2E695DD3D047CE2B35D3820AA8D4D7692C299C00B78EE7BA40DE61560CDE3FA77BE3AE68E" +}, +{ + "seed": "A5B67695D7DBBD6A7B25146E30DC3F577240AED2E4E20158D1E24143698D1178", + "pk": "E7DF05EB34DCC34DCF645BD3E04C7B55D12FB65E508F4B2FFD3EAC19A060BF01B627A36252963C5562CE2AEDC3FC4916914049A29F8C76CD6C52BAAF00A7A4EC403786746B5B4496F0288F9E3F8C6A9927FCB787B53860FD3C5604CB0C0BDC8E62FDDF2B331260AE7F949B77769407A49DC31B2DC7301A39092E0D33C511B7A51AF129C482989ADD0097F5A66E9D5AE2E477A0BADB20105E1629E8AB6730D5BC3E889C7802AFE8439DE26DBE2D7F4A58ED8C9566202690719E286E92CBE0C7CF65749EE602B6E31DE6E6CED9A84AF50790611D383202CE6D01A83032842084163182FFD6B6E901EC74D36AAAC5896BE92833EBB7E3EB266D11A342E0297CC492833DC8B850123AD4C33C60924C402FADF0D392166B3620F906189187BA9D761EEC3226C43F698F2D5F6310357355166FCBDB45EECF917D0E3D0766C5EBC748B58DB09B515529DD320957374CEEB807A2BB38C9511C2CD0AE6462162E2CD28E1513B87973561D5BB9E3FF260F64F9EB2E1B9A1FDBCBE4C9134E3745000ED804C2A3A55D769C6FCBE947D9557E5EC2EB08E9D416FD7345EA46547649E936A51CE643D9518B595AF4E2BD75ECE8D2E04D4A0840C8E8516E25A797C0E9A93FE8B8D31DD314BD271410C85A0CB6755C1FAF225D0CB4B8672CFD6459E65B4F071A9C5A802646F1660F8FC24BA57199DE9257AFEE8C8BA7D6256BDE7E6EF090B5DF3A549856D95C0FAF20CAAA31D07A980A76E638B122BCA0EBDA0820B9779C5524F8A6D2048B4285DEE77A755DF9142E03BD78D2DD07F62894D169F21BFD8798F5F5FB0CF73D7D14BE1536749C0EFB447C253F1ACF93081DBD309BDF7C3DE11A1414A00914A82C0EA649232470B3714E39378FAF4C7178384BF7EBD5E793645EB4D11DDCF00454E62F95C7C6338C8AEE320754DA40AA48F8FA227C5C22775F0D665DB438B7950F7E5CB69743888C5A41331D78605BC5069E273DA0083603578D43D696F54EC21BB61394C5DE4115F1D3531105C5D3047BB102452871CBAC4D78DFB3AFEC545999EBC8BEE5F818DFE0AC009FC62D4B752CCA004EAF4B07FDA82B3DBD3AFA9C65E43EC7AD116BB3BA07F14B2074E34DAB889FF6B9A48541ABBF8B556BD5E16F0AE9BD303AB1224234A0938EFF04D524F146DB003A684C781569C3014D7714A124AB667CEB521A3F6AC60FBA8F5CB620311F4899D922596423EEEB10E8BF9D8CD3CA609469CED630436DF478D959368D0F175E88E5A563556B3628DC43A2D0AE9BDE3431DCD968C1F2A5C7BBA792F86CEC0E3BCC0DF797C128AA551B1383505DD6ECDBE11B086F11DA4A933D9AD88DDBC444DAD18DE114AB44D5512A5341C089A496DE50157232F67438F8B99650436DDC8C4837E2FBA469180C84F2B36D0B4C85BB9E38862306719DB53DE9F30689BA76B42BBD0881084E0C8732023E1C83B41AB9132A7D64332618B7E6E4B084AC61AF78035CACE0FD16D1E586F79FF97810111CD7C73215655ACE992EF34EA6EEBB64F2A392612DFFA868E8430905DCDDE0A3C16B33DAA6A75DBC5FD6421EA72DE15325E05C07FA81E6D71C49CC41489F1BA0B9B95CBCB8A8A8C7A84F47F8823C6C3D3A57FAC5565B805E6E61B1F5E46CADCCBF8F2A33A3C1535FAC6862E996592CB6DED121F5CED4DC2FD06079BCF23747991DCA6ABE74519F59A39DDEF6E3802411FAEA858FC6C7CF7D90351A17C7CE3DFDB3F870C21CAE3149E04B0BD138233DA4EF3FCC1714683181300A01EF5AF0BEC3AD30160F11BD031F950DAC48DC43618A08D3BAB7E36190951F0E4F2892AC5FADCD872C4D1E2E878D65051138AEA899108E16199F9B3D134271B52E316AF09B7578C5ED66BE73DB9D0E68A0553CAE44F68E3E13DC3497680E742204B8F44996C916522C86B44F313DDB26B73B8B049D6FA8EB13784B2E4062FF47FB3CE7CC046C3BE30BE98E242960D7C81B68ACB705A2714DC73916F41156E43015B69C0687C336963DEFD66F56DB93C58F3CB2F075579FEDD47E1185AC5A7586A038C2135EAE0F2F86C6F8F6AFB6650A351ACB622ADFBF2B1D991A12EB7EE3C2DACA56AB6B200E64E0D1F81CC98D0181102477B87D4BF3CDE84EB42C2BA59BBDFDE06C9BE229FE207D9865C941D9D3FD239EDD161FCD62FE98C096435A01F56A5FB73A703778044480B706AA6D0B70CA8DDA70FAA87E63B718CC92A00765AF46BF3983D6D0B4A6B134F4E4D7BE7AE06792429DEF01D28D61B17207956786C0B008262DD4C6A759F497A8DDBCD821DDE864458EF445B4A9E836200525149982BF2A76CC10B8D571187A9E63C36221AF169F6B61E561783F90DBC461D53A05F54E4F0BA20C5F25B85170E680843E484494497F65001722DAF1083C96D7689CE83BC727B27A9E162D32872D1732F64816FA45AAABA864A47D46492A5BEBD45D4E7D5EE5AF5163CFED4B439A03AE80FED99D5977745B56AF125DB2FCED60CB48C4F3FA1B8C7ADB43229BF9CFABD05BCEA82B4B0CC543C45310D2E11ECA9998FD2250C1430F6AA44824484F857FF95BD99550259A8D680D471131ACE5E8C56F5DF7150B2A25144387CEE08FE6237F72618076554BF662504B565204BABA2698EB4F2F7FAF673057FDBDFF119F8BB6B1D394B28A4D87148C1AC976C842E563CFA16C0B7900B162B084A23775F7E961C25A7C50990BB10EC2C46A986B991758DC28EBE9572C1795CBAE8BDB623C7314EF4BE3DFC62E827E3A1E61DD4F9B245D1916AE9A2802311685189DBDBA7ADA866BD2F81B4B5FA49FF8D16C3BCBA223B94D3C52832BED1BBD87753944B3AAF1108FBF3DBAF9367F5FE18E958AE66F1EFDC9A71E7CFBB81F4E88AD8E37E97A407967B3EA89ADFD6FD9D2CD95A6500B39777EF946904A15241399D596BEAF23E41BCCEFCAC92795CDC8B7F6E5E2657BDEFB3FA24349D0E10B03B6AB6C24A5D8260E227755713C3E57D1B5AFCE8F1067D1EF1D93232D59A545EDA53C1FF692668985FABEA4192A6C4B11AB02CF89B64B564958AC4D237C1B739217008201897F93352AAC793A7A1C7511B5ABFA83B0C040922069D71CB1071516333112730AAC7210F3C74B2D45D80B6530147C24E2D9893D5CA662405D70F5D91D5CEF7AE93BA7025B2FD907A86125E68E50A01F34458F318444C643D0DD307CE5B59F12E4B54382D9EED313DC725CA4C553F56A1CC943A5FEE6A5EFEADAFC2ADE956C6FA6FDC0468BB0513DD7301B87F8276029C677FBF38D0A7AEEE19B8423A7DD9A2FF85AD6FEE2978044EB0A31CAC6B74F20F8F379E1E46BC1414837AE5780F31D21AF710914A559D5744457D2F831EFB1ACB39DB7B3E4B126357266DBA8776BCBC8AD39C8E7D7EC6574541CC669DD38AA5C8F61D90DED5F84D662CE2E7292305304D139E65997020579D6CC60C24356223DA1E1AB33C51BDD14A619F8AF8F646DBCD319AECA9AD9C0292FCAB1BD5393122D2C9E23DF817C9971BB81E3887D25D9652BC0BC34D3E11B87226F08C997052D2A3E96FE7BD4C70EDB0837049C51A50C77EDBAEBB842847EA248B1356B1647C7E1ABE36E992B5757723F1116848C52EDC61E21A274A27A94E25037BB0E949C7BF6E01757E283CFB9DDB647989BB473631D7D2B6A421E0BA8F24CE4CFDDC175D69846535879872D99FCB91DF3", + "sk": "E7DF05EB34DCC34DCF645BD3E04C7B55D12FB65E508F4B2FFD3EAC19A060BF014AF666446690104A56370BD7F6719BF71E367577A2A1848656792C8BFB5AE2E1CAAF65980284F4E23A19D6DC9A160480283E3072E9FDA05C6B1F920D405C7C96F4D0D1E111C9CF5715903931D93ADD0A029C126C3EA29CC48B1BE330CD6866568CC43142162101C46D6444860189451CA730C2186C83162511290DC3242858B4400C9030D4904913440688402DD9860501142462061082108E94A0651A374D0C1801A3167051248062C6451B332419C3684B4069121804C4283161223240202D90226C9A2608DB4421E2280A23B98C22472521A124D2A850E48665A1402860944D60382298348622816CD2882120226DDA048490442E8CA01198B00C03B901CA282258968011056948347011468C1911008B204293280861A465C24011C49861A3342058184119A1504B28698A360EA09230D9C0911CB12549226198928D84A288123612948468992212E4364941A40812C26194142162222E4B202D44344013312E420425A2A0805C82684A100CD9C2891A452D8C04691A436520144513C85102A0100B076042B26CE10484C9020260385053342D0C428853B86404486691820DA1302E58186261322D13C44992B0499A442CC3202E53B4890AB14CE19050DB400CE4922423C58901934413C389432620C2A2309A1849218909220541093989DA968409498A4C2471E4260A6432261323201B016602243261366402323000C6890018481CB60DC2480A2206068A10451A2441D0240EC104281A892D83907049084E1997058046921CA8611389290A20322180610A022D5902062311612417709C926DDA06516022000A098553168220274DC2C689C822280C152C1086011385510B996804029262000180C0841A0024D408710999281C902DD2062E00B68CE010921A050201826D52388C232829A148728BA24021859000030422C009144244CAA0441A030993186EC8226CCA106600160E522890E04812A3282EDB9484D0B21013B56D19325210474501327111142102068018C288D1189251268DC2464ED002524A98258940920A280400A00C8A465109B041D02066D40805100208D0B85091386D24418D0840040A448994444C8318318188898946284806414A484C93864CA11489041664C430229A4061D814865C4681211749D1800403956141426D23456ACA203012944D8C480058A28D23C404C8360C2384294C80681A2400A2C81103070518B0205410328B246819C625D4168A92C4601A32218318049B382841B611A3A00148402C19B284020306128529A198090CC78D98C45181882848169141B48CE4160514874D649281D1B804E432020CB201C086009B045053301181B641A2A24C22B40101455082168DC884706046660AB1015C2090DB1872C4347122902962180C89A65043881104386C50148A02828480104183B28402317154B6304AA43118890011404E23476023182E94426683A6481C0670522082E4A82D54A2419422720B1562121086DCC62912114CE3A070D01260A4B62D23114AD8B24D032668D14649642610DC8280DA286882244922048113934D998408CA268A90106C50880100B82522904943006E10298182B641481460901605E0B86D92B04101949102C460A39070E2B291A384209318640A8700C4948590268214C749A1086C110924A12041E0202E43124CA4008092960C139930C33664894281191880530444082949DA92298A088980B021DA126A88C44C22808521A1250C103213026190260D0B29405B488852B22C0080400025846384415A908D1B314D93380A10B1301B398241120D0B0650E2420ED88689C8A0858142841C382412328203C261DC406822910D9A424E94108988082823936512C8916020220126259B84200C05845A344D1C316203946101908192324694462DE0125041320021C970D40065124522608670A4280A4BB02D82C8299B122919B14184A82922C02464C00124060A89148A01C80820C620E4184282B68DC0A86D61A461A3240090826110203042266521444EC2B610C1B48D838411E4266E5002884040491935320BB24CDAA011E1A64522B251C3868164B82CA0B0504092499C80819B348859925183C28D14B48021B5506032410AA16C004209C0062CC2A290E430011C090A214968D4162C0A1085123244C7F415C457066B406B020246804A5CFB387AF746CDE5026AA81A7110CAC17CD438C4054028B3EA5C703646EF389AE1D9A81D6BA2E708F058E4A7A5BDE33563F88B33A72941DCB16794220455B1DA8169E387D521C0A8D2F2D08B030B500193A27E2140EB59D11B2C9115379B45FA7630DEB827E6B0850626819DEF3A85E9479C2B1434E3C39ABA253E56BD1C500772D90A2402BD89A525CBCE62E45F7D213A59E0C61BC98DB7283E3711E449AC5DA6CBDA9E140FE91112EF9728DB78535269F77F38028BF65B9CEF282EBB8ED0D6D16C23F78C2FE6A1B9D6BE06A7D42D003991536BDBA3C9F28221A993D487678DB5747DD4ECA2EF7D0CA9D8CC235192A3666DA395EB597E37B16C5F32F68E2F557DB7C77F0101DE84843A12925D6C3D76F0412B9DA765967D4B2917013CEA751F38EAB0FAC3D8ACFFCC272AC82ABFA37DC339FA4A6D3D36560196B1F3DD59BFC5E078B998C2BDAAE167C4C80FEB38ECD4D7CB9ED838ABBD6D7A093D9B3EA10AE51B6C1C54F84082D1EF05AC2E0841784AAF4F6FC997E43E3FECD50BB333703382048F5C415886AAF3C95A5C1351938B496E8FE0B10F1808BEB61921B0916097BF09BF64D1B263FFA7031AAAA99269C0C5CCBDA0ABCB9D341E87BCE1F3FB0FE594AB152CBEFC3EF60925F95D1112B8078EB30E616C22E05BA9CD77CD5A67301AAAB35157232E7C9DE936FA6D43722CAC883EE29E52EC8D7F4B95CC17E2EE860FA4591550C1E01CC78577B337BD1D8BFE84DD8B95982EED0E023703F242602645672886BC03C4AD2FF64815C916EBE6A33A282E440D9012E70A630DCA4CEE5C65AF2A880B54CBDB44923FBC20B2F5FEAF1C2D9092308E930C3B044F2784902D8AB7A3F65536226180C75B33B236BE642C00F00C94108FAAC067D4E1DE83203CFCF316849EED95DB2ED332A645BCCBF648FC93C895FDBDD4368E4089A5C07BA22B17EC08548925F53B73D021C5CD2A5D0656AA67762C16CB6D5413A6F7168C527E85688FFB064659C7A048D7D7EA0263C275E0E1B3260789A58060895A8B907B2FC200EE8F559443FBF7434D42C35D6E2208FCED553FA75EB4029B95E2C0B3BA401240F2050E3888D9738A5C9F3557243C39D1C133FEBBCB9E08B2D8E7247A2EB1065F4415170D74E74817AED0E26303D38890A8F733D4627ABF548834F74DAFE9468AA3A31045B540449549C617CD8E674E608169EA321B6BA7925DA5CC3AF9FBA32B3C6F73E41C8DC1A8F2F59FC7A266E0009EA2A478C9015FD7DCC160AC6E25A36502F0575A28B6FB60ACB4AEE2B4DD8BD6B058CE9F230E541D6E0EF35A403252736012AB28AD15FD5034D3D388E627EF590840B486FC7665E4360CFDB03FBB01C9C65F2E6788D7E0145598DDA606A24E69C6A6542702FBD214085961532211713D71CFF0AC5BA3AAA2E97B11C7A9929BFE7E050393E126E94E8746ABEE2FC812356A4A442D3B9B18FAC0AC475A3F10A0E614866B113A457293BBDAAF7A5E69D438C411660A99672BBB8D8C1EC1C25138F5003F3CDCA247C34D56E6B6A3A36F9DDA05E64961D4893B51537D61C78044B3C29691F907EAD4E24508F75FA50162B00F0C599E461FA88BC622D6F1DB60163C19B4D1CFBD773D29DF49BEEFCE2E13748AEA33DD426C2EDEBC38F7E3DD6F1140FC79D5B42A96262E8028F8515D2C2B698B5670E658D9D7A1807507DA6F55902CA9745631E0FA7A85842A7D834A236708E09B390A4EB06E43B2978120A8D8EB31351EE66085D11990780E2641A8825C9D55684E1DCB887AF400F70C2006CD6760D5154DC0F3071750B3E547889D4B9A8617A94345BD754082726C381EA0494409A12CB1B1F38DAFDD05C2AB37505C3AA2584CE613866F3540931E341F5CD65A25ACE0B3B0204A09B1B094A8A502A92B7D4006657309611D601CDFEFAC3D748B27030351E5841E4E4C26D7EE937322BA7B33CE13960C3ABB665D14D7329AEBA2F5793AC65CE83D3CEAED892E402178B448654E367823E62F858F2AFE39795CB33DE23688F97793D94D45DF6868CB401E8278CF88149505D9439C9D9102DB9FA43205DC9C9EE056ACCFF52E240E00144C4B39987BE1F7C1D4BD1EC8CC0548D55121CED6ECF8F3E8AEC28762AEDCA7AF154806950ABC2E62C2FB91EE9518F847E4E4923A92EC23A5D67930DB82BCC8AC9F75028E071A226AA2E04A384698FA19A7E05CB1D1F96BD2EE8E3D2DF43BBB071BFB916C22E2A7874372BEF00898B5A49E1BFE2F670259AE8531DB29A717D26E45C3E70CDC7EAC1FD9B4B299ACA741AFBE1E9FED276AFA2BE5A26F7915EAD4160DB608E4927D7EF20B27ED2EA11D0778A784C16771BCB8DA8309162BF023B0F1084ECE6E1F9B54C7FB02534A721F9790392B3CC1BC4A45D55AE8BF40D041451C97CB68B0CD5AC0F99FE8C5B29B8067A0B831A4C1F01CD36B3736C3DBB36EF1375DBDEA234AF41C697C9B1DB05896EE7F7C5DFCFCE2D50236972A57DCA809796D911A174E2D3E9919DA93A324AC4BC87C0A6E9E7E67068D9908BA87DD5C501F46A712F8DF069451C6CB0202BFA81BE9C7EB139BBAE81BC34A057FB48BA38D0A17BE7D41E5DCC429C89543EE5E907B18BC6BC605EDE5061CE12D98D8C1C7675851D3DA2304A2C9666BFEC43C52BB16921DA67DB8D6BFE253FF14921588B596D470FE7B0FADA80C495B54B134A22F88B3E2928C82D63A06CEFC4FBA8205DD726C5F6F69212BCABC83DD0E30B15A20F3958ADD691BA2587A54D5927339786309A7E547F3173DCB861FC697E7904158BF9EEF3F9326B39562670E73F59FA2B9D851FDF775580CD2A0613F07C837095E71BD65EF43290DC39F202B16993E0A78DDBEE6C2D18C561729354E0B820E7375284CAF9B684B252415CECD9F472B3E57A552CBBD9544048DD45781BCE46C3438837AE9648F76CD428854A52FDC237B4CE44D9DCA477A91514932D2634E8E7888D3AEF0440952674632F1ECA2A51D0E7412A25EF12DA34AB2A3C00C0EE546B34450CBEF5B5B420E3D9D27DD8C17FF907CBF57042BA694BC8259395787857AB435F5813102D862E2BA6F653F01776BC2E0F0FD7060FB36C1AFCC21A64624360D19BA9EBB8E3E780CAD1785ABBD8843D472BB30D91173422360336FF44195765B755790280D8D29FEE9729F5444A3BF960B487F0B351E0A3D340FA4EC6E6900F91BB980144273757662CDB2F21C976D1607095848323C9AA30F6AEC830F9B4E568CE46F2B56147DBE0C676A81A8C5BF36AC0A8A21FCCC19E3C44F1AB7D73B2901FD68B1D475D9F492B540F7BF903B643BB536BD26C858EE493502B01DED2AA4C2564C561C0E87049631919E5BBA3CDD2A805A0F79BA9F40B2C8DEE61DCAA4975935052EACC9663DD1E4FB3A9B62C84922016F791EA8CE13789BE56DEB2AB36D187427C860A4E7507D0A8ABB54D52EAD11BF3835578D52C775DAA5112D2392D0C991ED55913139AA026CAB18472458EF7BE5C29992F6A6727D5800980439AD002C1D5D78FDBAB8D7C10B3F9F370D7B152013B128AB2A9E896A1C7E91292B78D3EA1C5E74CF23638EFA30251A5335AACD939B2A562192165AB3CD509FA7855318A52F9A312DC17A52BFF12CE382D878725C5742AEE4B7B34C80E587A05E4D19EDBD180C661CC89953D32B18F19DD0608DD65D415AA9B51B08687F61E73A8F204E55BF61FFDD5EF25C5EFD9A5332E9D81D70383FDF6A137E5B0F816E003079E266A89E40CE0BC721470142DC86E23646F9C14233332369CF3AD37C879C64C905DCB3430A2921FD9421560F2CF8FF0A819F5299938660432BB60CADB0A626761236294FD3E6BBE5D75265E20821BA874679417D92A17078F8A869733AD88F15329982FE21EA39FF935F1E458A8874EBCF16B79CF400E2A252E5D05F61B1C1B1238BD48E256D65F1786B4E2969816C0FBD38A1269AD423D33EEF3E46093555129F4F1E8B79631270F562E1B8C396B5E8CFE71096A174237C8DCEFB2A577495E777FF7BDF8177B4C2397ED36113769A39BB41EB7710DE471FD2D36324D3A3F8320E4F1BF34DF5108520C4D61B0FE7DD7CF5E396757B1FEB791043A6188BC5DCFF3522D80A5AE3D7C1E65B7B419B86A3853F7089F93B7C42976F252C23F0262A681C8C3BDD6FF91E36DCBAD1BF28416F4B7A458538B778F645C22EE027998E09B5824F3057453F2BCA68066615286D430589EAC58BA8F0BFA78263B37E0C3EAB69BC8E8C1E5DACAA84FADC7FADB2D23BC8A24B949FC23CB65668A8D562F03C7DC70BD3C5BA42D83907199B026A2A09758268122CAB97E4C892344F4AAFD0E46356D6FA535C8A89A90ACA4A72E24E27998D16EE58716BC7BACCFD99BC293D029BC976C54230A321184B529D588EE131274102C74A22FAF4AFD3453BF40FC475970D4D6C0AEBD9D219EF8E57FB0B5F9C82B09838D8E24B7B30943027BDE7FB5C9CAAB2C8B1939CC7870F4EBF0B6B68261027B282FD7E6A200601D3E039E6771B8F2CD009A466145AB437A6243F73B1036C786F9F6038D0190C29570830A3B67D418A78311487795E5B47ADDA457D89626D03EF3150A20C6AAD1761E3DD47B51F5BAC74134454EDE11F443CCCB5F8161EB366D4DD6ED93F78D92FFC147F9F793510D799C927630939DD0C2BC565737BC1DEFCBDE3DBD246955B1BE65319673C2745C88618C78D6BBFDE1D4D400D" +}, +{ + "seed": "1B87631F6ECC4BC8FFD14B2792F3D1691A46C22A26BBC98DEB2554D7FD2522AB", + "pk": "B689F9AC3F5C158C92A7E8B562670CA310EE4CA3CDB9D9D7F1CA5C754179312F05DBC4579BA8280C83DD2D58FF98104B3FCF0996EFFDD337220B411A7AE227E0938991890F8E7495057295E2D7FB7B8CF1F39C6C59AEC37FE6FB87311D39BAC27EAC5351B11BF84EF91FB0BBEE3E35B26578AB0E38FFDCE479A2972A4DF2D001778C393E64CEA03373328EEF17AA3D0FE7A9C366CD3440501358229177701B96E7B669CC1EE3B4CE04DF63281FAD18FF66EE0DCFA087EE942408064235E4FDDD7D97D8D83E3EE430EE24A11ED96B2AECB9069D9CAC9D2530780499A99F16721E4DAA25F96FD0DC511C597BD071576A5E6E7F911AE6EC7F18FDC9048720E629C419B3B86B09352B4515CE915FF36C997342BF2A194785BAFFC4001C248566050BEF62D089EFE99AC5C6F0DAA2BFEE64070B5E9C04F2312CA8E89C5C04D34A9562BADCE42432A88C27799F297FCC0DE87AC67D62E95668FF38D6E533CAF5B5B54278B5646BCE6D0A82ACEA726E017C42032F8B09AB7DFAF0897E77EB1BF671721F21EE487F5F1BFE267DD47DE4FE32EAB7BF5B2E0E0D20D8570C3A079AC3AEC06E686EA22F3FB5474CDC726517D8A85E42862E0F607B9F0977D4153C90BB7C29A29B8A0552E6D3B8C0EED949945BD4816A73CFD89D59FCB1D2B41050812065E4D7302BB78865439B9EB9B43ACB92E435027A151492AFD484E0D726B01E967854D24C5A889013513C614126E3EC8B6955E32EE4040A467FFDA26C349E0DB3A9D5A0B2AED925E7E8387B0A387FE1C5307200E254236B90D7202655FC3C06C3B4B7BE97CF96EC48A247F550CFF02EB276A841D013DE1315BB2AE74B8B7D05EBEE272895651D99747E437ADA14D73AC327A311F1AEAB23B04F9391D662BF71B04A3D943A90DD88C4926EBF16E4A3D11C9B7CA61F82F5A6EED8BB27EF576558B336599E6A7C4D4E9CF57B8222F82E370258E356BF4CE670B1F8F3EC6226A4A9B66827A75750B58E8C9E5088733CDE9B578AD555C2C9BD5348A285147368EAAA71A8B31FF7E70FFE682683B4E471E54988D242B76CDE527012C7B0B07A83428B40087E297068C60A07C66C49E447D06BB9A669C331570418A4AE6E80A3606B5CFD9097091E5518C3CB835B72A81362A2665864162BD4A72DDF1668515873FCF144D3FFB8D5F0BAA4B66F7FD69F74DE0712458A8F393AF2AC74C6D6F3CAF95593AACD1ACB4367A196E455B94D45E2C411433CFDFA0DF743F709B9CBC27EA3617E288D598F3B56831B3EBB23A93A539FB4112CD03A2FED70A8FC10236F4B716E0BD41465FA958A149184328531F255D9C67474C87D547829385899C3AD7E832C5E6C659E402D2E06F2587C5497E2FCBE8A8E26186F2697CA30183811E39FD5D15B8CF0EED21171B1284740B2D5B8D32D0FFA061D16536ECCA222BBA35C1E7509867F240F72F1784CEB2CF15D0E38D4B9F30058A2EF721F65C303999A614B12766126D78FBF0A69CAAACC462CAD5082273B89B2A72067047253ED7818C0D4B72AFB1D256C37CD4BC2B6172BC68C96DC2C068D9533F97B86BEF6DA7317C217D27B2175491718D08078621CFAC83EA62C9599795E156BE08B5F03D0735C2B8048F777AF9154F534A2890C07F83CFDD9CF8468B79940C0077D39B7D8AC914BA4B561C848147471C0A60A93A29B4DC10ED4FCA90C2832BB159FB02D27B340A0FE663B1472A04CFF2939763034A19EA164180586FC4EB65FB5269324591474ECDDC7949EFC8CE1AD9BC748E5818404E63E44866EEC341E26B0A2B9AFC20ABA61744BD0306A8F9929622CBD81B73C81A8736B49528CE0977005FE82D640EC6034FF3C48B5FED6AE260B99A4A57EBE358172D82A90EADB4D1C316C3E01AD35EFC26F0391FD349990B333C347B27378F78DACB57788D264564E022D732D8632E174B66F91E4147F534F3B5485FDCA75E97F91E2D2C7FB11270000AC0605C947A300E2D3D30F5B35B51712CD369E6E6EB0B8893764E635CA8E65886746150C3AA300CF1F69800DE062DE2E64648533FAA6623ED0D59285AEE2E5518EBE278260A6D3B4DADB9543721E89D7722440BC7549C396DF1A56EEFEE0689D710090A84FE0AB06EFD61DEAF590F5E78D6810097DA74E2FB0852759D03D6023004CC6B5DDE3767FA7695D4E3F1DFACA0904557585C11D6198C2ED3CFDAB074C6D20A622722366ADDCFEAEE60CA40238182E92AB4EC629171216203885F307E1A5EBA8021EDF344D1298064D6992632871F33405C1E3C1067C47DE6EE1E5047FF7D2E03A803B2228FF640E1510D250A7AAF25F4B865697EABC300041370350C2E919F8014DB1B7162718AC693CC0ADE07691C2D967787C816670BA35F9753FB1D30954AC64CAAF4308B56DB027B75FEAEA74CF0B410CE18585685CEDE880ED4180AD470B0BA03F81C62F896BCC1CD19B7D0C506F9517A5A891AD03D062FF5F5CCFED5A6E96F20769692FD5C53C466091F2422A89110BBFB5C26993AE1A5B9506AB0C5349307D05CB3296D66ECED8B478A81BC6FDC6840F62615D6CA202B09731F5712C0D68216F1BBBC569405F349044E05012AA45618B41FE9304D3ABC6E28D1F680835AD46120B7A642116FD7CC91AB87A5F7585365C0FD25BF729494BFE12A9C5BF0E885067CF4B5CDFFF2F52C8F0A39F376E33067BDB64E34608ACF07E16673DAD6D5D33E7265FB88D4F0070388D92DC012C1E51C53638C5DCF7E5A254608987A25333CC8B9B7214843F88179769ACB4B544A744DD69297CD2D8095882D835A4FB3026FB6F821C664E544B37D543B3CA16F49418765897974F0F90F4DD909486684E0CB7F18A55FC8CEA86C5083CC5463F803DEFAFE52218F00478034A9CD4B83746026DF96BA4ED018F9827763359A1D200EDB0730546911A97B60D481C099C0A85EB039BC63F94E271CE865978446E5A5E5FE681F1A7079FCF3D3CAE2583535FDBFDA03BF965D928F0914D3E80A1F53879D3B1AF6381CE65B74F0D43433D0A99E4EA8B8A6E9A78BDD50FDA1A40BD4D10967F4748732AB7532A7D155CC6AA9479832924677096D8FED679462E5FB2B3B70673181409FB79A155BFF1B02EE64B6E68ABE957EB842F7525BD6CA82839BFB365FF23E8F42F37C12071F4A97691AFAB9696A2CFFA97956BCA8E514A4165C00A6AADC7AB61249C5DA346BDD2173974568756D99AE3B9A30ACB15A52B98F71E17B58DF2F9FD2D8D8C11BB83C402DDC816209000865571148430EE351DBBA27C19090BEEF78148CCD9E3A3F5783395EE6ED8EBD1489DDC8570DD798E92336F104D61BA205EAE82E190C9E899CF338B8C45A12C8958E4B53B47496F6118351E348A892E14B9FA1E54467239970497D7F208DB6E112F5E4E57194F9DB93E39AF2E9F35514817A4C4AFA2A543E7F25D759151C5EB3F56EA2A5C2BB352538B45984B06B239E053A0A6598BEEDEB1ABD97BDB21F4BDCE8627CFA0522D78581304D30DC5781CBA5A913EC0F5B4EC9E53FEFAE2F739807911E422193A492B479F100CD9829CAA7E62BD53A997F6533C04328284B2A16B269FE758E8EDDEEF76E1F4ABA2E9ED27C3D630CA83F3792DDBFCE6A41517B8494BD449F602037B67A1B742CBC09C3C13CD441337F0D20E6957BA4A3E64993661ED46573792DC663B62A6", + "sk": "B689F9AC3F5C158C92A7E8B562670CA310EE4CA3CDB9D9D7F1CA5C754179312F965B3B86DDCC8A3BD84B23A843FFA28A75C1EFC4C51BD35E9C5AA8C6C6533FAB87ED5E5E7FB72A5297E5A8D2C6B87FE1A07A4613F21BE746F8D357FE8B60DC395576CD911592CBEBF452C434EE7B7F9EEF354B0355CAD920C35D9DAF50085136D28640DA401050140CC9162619900C59C63110A34DC1120E09808148180E1C123154248493188A040670CAA43140C64DDC140811428582402D49460EDA2486829460009431A340881C224108B03022B58852322C9446445C140053160DA492814BA62521066A90360564480E1A2950C218614904490A87215384046228519040284A2431CB06416422881347711B024854B84D4804410AB005C1320082084C4B244A1926251C302ADB10328C00856040208CA0098C3210C3A48593C280A3900048808522864051B02419411220488CC4448DDB022DC4964C1B30122193440CC125D106209C2491C4328544B8884AC8100B986920C6658148010A208A92069180406D23C84022023204174D22B271D904241BC3900CA104D2046922840419254A80224C02996002459082444880182022474558B650C3866492445144B62402B00DC8C89051320D4336714BA82408347118110C992002E0048C1041259426054C466453A030D2003119192554840CA0846C8C12464A904920B70860322642142899340EE3326DD2A440519284612289949844DCA44C0C971092A4008B40664B2231D184601AC58CDB406A52B88819B9851CC92449426600B869C4404AD81409831449D3A424842265003100C1043014356C24C9010C176CE4120AE0046684B05152802D5846295482505316911340621B466E10484AE1308CD1982153B860A3C2000018601908888C4804CB1860133286E1A02508332D43308554443058168C1BC5241CB26D18C1892396699CC00153144AE2B0509CA66561C610E4840C44342259146422052241240E04940050B28809A021C0C88C2347724C486D0C054E8B220C08483180C4081B91080A81811BB52CDB326C8B82680C318E60128A00938C20A96862A849223930D9B2488B844DDB1882C41001938401CBB850CC146A03398604B4680B828C99101184288008842DC3A065C49860C3080020164E10410DC8A2841BB14900410A1BC5881430414A886D8426710C1500CB466480382D53B62CA0C024A08284E0C208A00642DB100A14C39192B009A4927180340A03886C2141098A166548122EC326665108068C1266E1B2009032728118658194859B20040B81456242821C82100BA549DA306E44C6111BA548541071D4C0089A402DE0C42183C66023B68181248E98824010388D54426260C089139588CA120284422D8A1812CB14251B4126C1820D9AB8459AA4688A90018BC80D99A2888014305BC00422450610C011C2148D1019260B240159386410319008C380A2388222C708C82032CC406510192160462E22A9248A849100B510D8362524353184848D84A40C1CA6400AC22CA0188D92A42D123709D9322DD33025480250842805A448000B318C1B9228C8100A19315289A84823C90C1C1164940024D90802D99221920468A240892322109446689022110320700A055214B560003970213806CA8040C0B2844C3231D1466901264E9AC28CC3108CD842898CC8415190214402890B93249C264C03A70D21C08CD3C0810CB68D4C3450918488A3C86022447282868911984DD1380C1301910B372013848112A2414A007024326E10416991B86424064C41382893B8641A3165203171DA14291AB905CC060A180960C2C4510924708096040AC82C0B23400B8741C02425D11648D2001124093003412D4A8420D09644DB424D52422809942C10A82DE2A031A2328CA33252231302222026C42400502685519080DC46890A0446241046D9240822426981C28589306C0AC37193848D013092D4B26D10A92100085083364918C10DE3942919B3500B132813046823016C18144121948D90C68501B8844C904DD91864D9228AC9A604181441C4362A13917023174A6400885084051B162A14332D93200C90468D12B19182447199248408188058C86D5CC68463B6050C816D1BC93023A189DB0481DCC648493265834064C11048190629143904CA068DC132018418308296250301508AB64998A628241606C3484D9044482664C6C6B124A2857AE26A5B0547C8D17FD20BDDA77BBA851BFF1E2A3D6F2449A3D7661C42E5F7FE82D17697172DDF3CFB1E3BF29831D5483B46825D43539C4F159D3EA9CA18BAC04196CCFE47BAB835111D405BF52F5CAF365F6E1FC3E6B5AC52CA6F9D04A2DD1B2A9E0A5268790AD507254B22E62F3952282041954DE4CE98460CB4CE67E8CEC031CD430D1E825D39389BE8E1288382C1C1475EFB6EA7A3773B9A25D3A99794B1D073D121B65F5AF9D0733620B5A30DADB57985AAB262E87CC6B1D54EC13213F78791760C9413E273B7215A654A9BB4C0482C291433BD76AFFC47A2AA962B7DE542DE840B99CE6428BFED4B95205E72C0021527E1C5D3E810D91CAFD3C86AA4BD0A40EA7DDC80E1AFDB978EEDEAFF5307AAB7E6FAF6FA25CE431CB75D08099D83D4763B6214E48371AA9AA59E1CB39049CB8665AFE3FA792C5356F9D757019DEE92E18A6CBC33B0407D18427794C8752CABA14C54613AD42B7F17A7C2D6F76FE7891B138B047E8004FBF4DE4EFEAB8CF2148CBF623B41EB4EFEC749236C52138AD9150CA2160A24F9672059E6C50BB1E282722B2A46668638A37601E3291C59C97940D15F916B59871339FB26DE864C6451FA615EEE6FC615BC0FC0BBE440DD431FB61C4A89C381DB8C65C2FC41D3483CC89E16E34BA6EA4D564B053D834504F9BCC93EEF3C6E84F046029BB639BD681D66F58B30EF1CAF54B46F87B9029472B297277774DB9E491A29953E356AF1DDFD874418B04D649B64BBFD74A8723B451ADFF707F95F6EF897A563DFA14673B2870FA588DEA8FF1A66480686B24D918E7D24A70F48C061AEF8E546E71119FBC46838B3F58A908C247A06FBC8F54553700934C6C6189E27319975328E092AA66C228464D21D3AD3DFE4533B7539FBD05D26B245D21DF4401EE265F9300CBA6614A670D8D07D2BDD9B58EEAB9314BD0D8B669DB1736EC4B15714C11EFC6CDBA9022CFEE95F88DCB1C9B94CB9286D4CAC2265BD8AF5067E86190F3CBB14CB37766363C205F5BF5EAE9C53C7F3C8471FE7C8F2ED4E54B2B46530232D4879E8B151D0900B37BD78DC9E3E6E82BCF874B131A4CCA2FA669745EE1875CA3036CE3388102E975BAED3DE91FF7ECD36DBE1A1B9F6E8F015222F173D14758616BE86C322B45C79F7937210199B30FCBA68A92F6715D078DFA45CFE6908AE66611B7854E468C837715907C4C67942F729DFC9DD8ECD36CCCFC80C08483D8B045BB23279696C6279A1AA9A1954BA3C2EB4078368C5CF38E735D6F2233258DEE2DED0DF254E4D29F8E62709F9842349D2C9F5C0FAE386A8007F76BE0E6289C2E44742D80855B198290888C82123141ED6DC69CD9883E932E0473BCB64E83BA3F0DC1E093A64F912FB71154911539775FE594BF9BCA2331D4651EAA5DEC5651EFF2D96758138100768BAA50BB969D4F8BEA490DE88325BCF7EE32960FB59ED0CDDC5E2759404E18EB0D3B5DBDEB0DB7F3F83F5EB30C385083B60AFE529E9934F5BE43DD962FFFCD48D2FB362D8B2FFC91BE657ABE6F4D26CE63B7C10025BC3F22CA472D34E410093C388238C901482960C74D9C616ADD05ECA6DBE268875C59F6C086EBA2E1DBD9A7FCF6288A423719EABEA8CA57C83F2DC11CA0927E2F294EE55D4E61DB87377682130D88C9F30F8863BA646AFDE045168D16BA07EFD56BC30D51F3D53E99200F86C2A9EBD506DD7CB43612119F56E546AFE24306A406483BADD2ACA212918F42847E58191DA91889AB58256DD3A482248917E144CDCDF37F5DDD84D365CF048B7165536791E2EB0FED48DF9F3407C79CC7E9FD5CB2498D1E9332C9FF687FF9F0099F78553CCA3F02DC9BDD3520118DC7026248CB69C70D13A48B04AFA134CA4B1F1AB074D5ED7B36AFF20EE54683D593F6C06F6D643AEA6084BBB0AE9008502502CF8A6CE986A48CB82E20FC64E5C81351E217653162F62BCEF020DE2F3D5596D7E3C1750A3BDDBB7353EACF11B27FCB566A404A8EAE3FA66B1E5A8DBF95A69FF822ED5CBCEC9604070650A72F69F8AAA81213F6F9BDA507DB2032620E2C587DB8DA486FF4680284423046814E030C62EBFEE80DEEB1D760D838AA963C3321DAF041DF16CC206E43BAF0CC1095115233707567D6C905E01BE0074657F0AA9C9697FD9D8E87BEF5C9BCFC77BD2D4A4476AD3497E359EA9BD2BDE4614D9CD03085F7C473E3698F98CA9DD4127DC2BB41C547D5ADB304F38EC348767C7605F0F01DC475D4D4D00A4337C0795B1EC50282282EA3C30BC2F9288B79FB7F5F433122BF2B2B1935C8B747CC2FF3F41A85AF9FC3E7CED7DC8AB0F3D9482890A09E990B7B57443EE62EC587CE3A6EBDC78D9AA327C35E1FBE16959D031176B522B5BED9A18FEF91A0690832CF87CB560FEC9EF1163F34EF7A0A96B6C48904F15BC28F8D753D125BF55955C5D4B52EA7A35171C812A135C5A0AEBF21B53CE9371DE75A77EB5F8EDDE3C900DECCFECB184D78461460C192233E66C50A46FB89BBA14AA02C434445239CBCF8A92914EF5A9ED12C7706615CC8B0DF0C596830B1C40C7C8364CD0B803C20737C779F9D25F35514AFD207BEECFC82F10B0C8F22E1B3D86C91F2A5DAC2E63CF6DF5003DEF1DD74439B2A0349904FFB4B05A4AFDA774578C70F409B3CC6328B1D87AF729A60F2455349D48420368C22692DB5D0D9BD313142AD2FBAC6FEE29EAF2974E66EFA51BA6A52349C3B451AC2FCF38E3B5073213426724F2238AF8932297B6900E5F1C62F518122792813E5FA5ECEEF796AF07F8DC316FF3D81461B1CD352DDD9F962A3B46DCEA26FA83D0D1AFC09B7468A194BED369EEFF11DB12237F0E9A69EF7E5F1DAD3DAA42335ABC804CC18291E1128CC6111E605922CC7B136DA254D674B1D717C642194E7E41827AB76CDA5B9881FA9115DFADEC0FD0ABCA1F00C8D93496F8EA2FEEE3E9677F0CB05608C4F3A6A42BA2A694ACA9AA045E88734FC818965D95812B613A24638757AD8E9037A4A5AF89B2ABFF94C500DFB98E5CF43DC41C9A988194EC689D8972F74F65064BB9CD20B16B8AEBE6C258EF9F128281F6DFE1F0A6453D5D16DC11949E7049AF3F55B22620DE1E75A5AF95030E4F2386AF4697490FFAECDCE76BA131D61FF45BEF33DF3AAC63FC355EBB1B24AAEBB0E31FF057ED0CDC9ABB146D99A7276FBF686B9B1DBE51533F12436CF3CFF995BDCDEE6D5660B3E4D5D37FCF633D6FB28318D2A847ACFB4F8AFBDC8396B7172D2F21D17A666C08A66F37A79CE711AE936FF9BF807C3DA758D416030D5BCC38633129C4DE4EF4C763B2D9FACAB758942B827BDDC9DBECA273269B330E5BD41CE84566A1B2D39DF36EB89780EBCAF7A7BEF02DAF9A343F7FFAD821FAAF0138E6D73F7621BB699FF0809AE312D168A449E8748B455B01F2EED9F894A4F47C4D84C7E7FFB382FE90B7BD13737A01FDC8F3A8C1C692961267E9E0238CD70887739B28774882064812EC9C431B59572BD177B3B0C21D352782FCEB70255650ED77FCB9C4D8C65808558852BB57ECB9093C835491028BA284C6B97D9A4D2F1C0530E3169C2628C16AFDF0826EBC9E4405FCBA358134CBC596C89017E76351BB213D2677575E6820019CB6EDE7852FA932151D7A72BD7232EDB1F019F45254D2C49258895DD6EECEBC1C1406FA927BBCD8FB1F03A016505F63A5CAEA9E301ED9101B10C72F27247442FEFC7576FE89E218B9D5D9CE59A54F562A4BA435A35873177CCECFC477B782870C4E34D95759315FEDF52B9364E9FB4B9757AD1F777EB55DA8A3F5FDF2363F795981364D028C3C3A39A41B13EFD20C4E0D776FA1D4B5A3AF641E5C4C5CB5C4B807CDC39B8C246D9182445EA95F8552DFD97D5EE22221C155998856E33E4EB5A438A7A62213276DF3830DA45A0F5C7ECE630290C8BED32F6CB5B899FD85B36BC3F60670993F6428A445B330B81092144A7167BD9B7929991176D4EE46FBC683546D268E1006120738E5933228131FA464C9A415D15F79A1C184BCDE8C9B766B0822A5951E3EC815B5ACE734535277CBA2BAE71EDDB24E58DDF971B6D757B77EA1B97793F501226D02CA95A8FE15D4B31897654CC0F934B5F8DBD37AD33A05170CAFF4CB31B1CA19B3C3C6C14E9B4211CB64C75D42C4A538FF1CB982178B7A9BF8E073886312086896AC4C0DCDB345418BEC5D1AA64B29CCEE1984536E27F50D62997FF9E46F0EB0D1FB74F456E8553228DF4CCD20E6760C79F88FA9EC924D0D04F13500EA3B99F3DDD1BEE0BA0EB4207EC4C8628419A434ECF5BA680CFF2750AEDDDDC2D1DBE375E77E5D133C833848CD35AAF2987898C0A03B93EBE86ECA1AC8568613288485C8BD9F49251527369B066152F34A4B6AE4FB46B0240F48A2ACEDFFB5553620BFA82C83AB61179014D224C57063375077E3770ED0C34478108D619D8E297E1EB29D48BE286A74980154C488BE7960D56F22BCC1D5FDFD992D5FF1F44D97534DD9C5A3D4A9F8D9359716815996BDADA33637AC3DCA3460FF446E51CD05CDE9671EA6BA24378CB83EF1F4EA2AB8CEF6D50767C79B8E1199CC823E20AD3AFACFC8DE12AA149FCA7D0912C719444BE6F68187BB166A46BBF7E953ED1ECBB3B607E8F8F851F27FA4CD603705BCA0C6532574AEB3B5CC61636D468E785AAAD1520004D408FF1BF1FDB5361F6E8D1C91B6F6B42C4362E50A0474E1452380" +}, +{ + "seed": "5C3E3EF0278EA9197F30C4DD9C4C06425C05401253E77DFB3E1D5315CB00915B", + "pk": "7E83C905A40C4CE71D44578ABFCE6A7AB1978527F0057F03112D8567FED36093A4B1D6FC48D27FE2A3AF6FF6845B999A74A457349428C7F042ED012B9AE0C11733E6F8BA8CED9D41BE522BBAEA8C37BF24DE1C2D025E3B148213D573FCAE27A8E14BC4758430F9CAA5D1B808A88BE38761C0D2C4FE040210783A147F2BD6D81565E72D7E1C1E7451F550AD6880B5BFC38940FEE73ABC4E0B8A68065F0B8B9DD4F4AA9E171E50626277ECA42E71DE8A2D364572F7D37A498F451702992703A86DF74F1417BD5CC752E6D4DB90B11C6786A85EF82BDC80C3B53AEC20DC571A2EC1C36C242FDB30D527F6D483072A0700B57BD31728F7365522D6A288FB78160723AC2F89C6AE609EE194CCB75C49AA533FF6FF6D070383CF326C42D400A70D31FD15D835FE9B278F53BA6E4FAC9710D1D03D32FDC47A3203EC23A34420714BA70D683BFE891118350D91B56CF9FB95533FD4F8024BCAD4E2AAEB0BFD729BF5746BE9BE6FDD6025A209AD606F49F8987998600BDDFA807C3DADCED192F1767B58C1C037579C9AD0D8148CB7B125DC66697A0C9690F86DAFA2478AAE0D2F9BD9069F77B2EBB4C372C1116BEA7488337B5372960C0192715FFEA7051DFAEA0E86E43F534EFE805E16BA45469370C50C15CD48CACBF0565514550167E7FBBB86D777B006F1E13CD1025E4A7327FF7F999A26DF2718D5551C30ED776EE9BB36F497B4B845D40F411BF7DD622EFCFFC6D0E581B05AD660417F3C5709261AECC043B2BB10AD07A605228225B647141D06294F246ABA4B66CAEAE4B97E72290FEA8AF0E3888694AE54BF29A9F587F0817201BABEAEE17B32A8E1057B48AF5D9A29D4AB9E479F105E95DEE4C855BF4410E5FB7D2AB55EA4E55331B7B3DC1B31A9AA99813FE42CB602ED0A979BA9F684E545C44E9185A176F25CF89AD2303088F80B726CA30D326F46E37ADFD11B10037655D4B84F10B7618AE37C3494D29B0BFE308183E652EEF324BFBBA27FA0EAEFE1DC21B8709A51B1E253E597D6FEF829DDB5B1DE50BEA95E862C7B61991975AD3AA56DB6BF405742D0EFECCE68F9D304AC4A162E031DAA216854845BD8ACE7917385C8C6BDD8B91577BEA5BA5527821F8294E631DC5F6EC6FF91804FC9B9C48334FFBBF667438563E0EB92CB6DDADF2AE8834194CA5600F7297CA00F0EF247065E02D991543E58C4FA424D20484FF85C0EF98A881E96F327DF5662ABB6462B4A5E1AED2D87244A1030C80A5145B6DEEA9B5F6539DA2237C7CB913AF4F24701B4DE514C6BC9D82DF6BB0EA9727D2BF8CAF3F79FB45B89B9F9EE6C7822957C650EADD34DE288A3BA14CF632510314F8304706EBC27214E37B5E9356408FD8F30C1B7E9AA7699D4ABF460D82A6AE6BA3AE6997C596C368A5FAB46BA4D106120560B5E7F87007A3EAC7CF822C414C4F480F3ADA0721C979BED1D39451C9845C23FDBA4809A35D23512750760493BF1E9C0FAB92E09D4DC3C2B757EAD5C3C039610427267B0B60B3B7F258E110332F88EBC474C7750E4531F8C19C8F2DCECBDD9CAC2645C18AC7A8B7AEAA1D79BFC79BF73CDF5BA09AA0762EE739B503384F3C8194AE739AD48076174D3193CAADAA9A5B1F4ECA6E948B3CE0B46AAA6138689796089137C70DAD610C88605068EF8FA29AA47B8F680FC2B663443913233BCF5263BC9081A50A39B8A31D7C5905D281A10B40550B3D38DA910C731200DC6146D44BE24FEC8A09AA2EFD512D1E417DDCBEEA76F83371DDE60F6F5324C38E9E4A9D26636C5C3AB5E2441EDCA559ADDFF294EB07C77DFD26104C67BD4F73CE2F068F72578DCB83D5B5BECC01CFC4A4A424C24DAE233AD0B48B8277083EF5FAE224D372E52C5628BE386F647A811CA7C564C8EE4CADD91C1A63DEF5553542D1DA7B9557C4407481F4150D381515F560FC2AD136D9276B1AC7B4AB9C08D911347BAFB5561A6F6B55E8509462425B37A8E96D122B5FC5718ADBAEDD87DFAEC689EDB28AF8A0CCD2CB5A97300DD6716579C9B9A15436BCB3DC4A917144FB0285804A8BEA421D9C39C4653196190FC5B45F2CCC55401744EB7A2525042120C900CF3EB6D7A8E685F44749D47A704C47F96B49E95C216A0C5E4E4CE5A0E15E798FFAE9CF8912FD985734E3910E82CACA9494EA7D6AE4904CBB3ABDB02B3D51C18178A308FC058D28F0AFCCD14D0F488B82CB3B0DF13CBA10B1F6A5FB93F557281815275BA3969AB0F685BE6CDFF611B08F14FE31D3A569C25A4A92FC946FF8C803F9A7D3249C7AC9BD08D06C631C79DD06BFAC714E4CF8D0096A985A80F3AFB7271AB976E2E1E3494F03203C7234DB5552BE5A58B46BE553FFB6DE465E01E6C66B019073666CE1D9BBB9952CBD44E93CFF7E2CA83C5C12CFB63B0198116581EE8BB3F9ED569B5BF2BBE7BD0B3A6A71A5616144C8EBD7C8D56FCEA92E4732811ECFE8BD075FB5490D46F30FD381D2574710CDFCCD62733406F788A29D32DB7A63E4F7735035D49BDD302596A2DA212886ED1F394FD70E4AF7E94CB50A43301827382F6DC651F895BBA5C6583A5704737954736F54CF7D3AB3FE8CBDF64AD8705F7553F672FF47B4E9E47784D65E97011B4630101317D55BC680BE0C687E1005892861AAE665274A78EBE97BE2524C94FA37715F3755831B49BF2BBBB1589D5859C34C663751CE53BEF8ED43C551879BA0EF952B94AECAE204AA097EB577644CBBA015F00A40136C7B819A0348270A89EA4A9428BEDE241B67DDF0332CF32182B20F551C82E366C95C42891353219147A1FE908AD18835B69CFEE9B8913D30E9A651E15AF091A2FF4316465B410A41597C8FBC32ADA0A6925714D68C9E72561DD67DC8793B15E7776BC92F3E545215BC3104BDC06D8F2FBDF4A4E79E74522EA0EAF37C3B716D592E50C97FDC2FABE637738272B633CAE325D9474EC4232FB8DD3777BC687D55A81CA8DE116674615534C3B1B6F79BF472C64EA729FCCECB8C30EA3937D1EA8412C5CEA57B5CD2D8621A5AD4CCA52C24339F4110517D287AD4DD6A9B2C77A60F2BEEC6502B1347C021E4221ED89CBC77A02B76764C7800BABB59B6AF7A5285F60BA88DC08D10317711C93E677403676170E05574409C79EB948C3F80F7B613E4D6C29E6FD81D8CC8BE62C6DE83FEBB801F7FA7E557F9CBC99C2BA8E33E8CD9A75F82E4DC604FD765230520E66FE375D22F732864BA892CDD4F76948DB7341407F0DA5B122654F955A1E5A65D43CA269FF3499374F5DE5692B425628948B91EB42DD35306666E6677581EC6F6683962F959273DE0C963A5BCF89679FBCBE517E5DF25868097820A2F0E52B78A27ECA47429985DC3962D99749F0C9AAA1458FEEBE8AB691EE7A3D68727CAEFA85E935057A1FD37B5A8A2D32C86227E85D2D385BA4D01B4C51911D7B98118E5634D3F2B41EF296B978FAB20880C7A165A534A38218BA366AD83893E1045E1EB03155612FB9ABDEB6FEED1B7A5AC81F26783491F0A89C71638853E22D0B0C26BE7B0909EA33D2AB9D47EF4CC6B4B4C6EF0E61CF108162C0B250FEA52ED6174F81AC2BCADFE444C60906334A7787F68DC2FE1DEDDFE0E9DD32C5EF156063132F130EDDA0C6F6FC7ACC1ACB9128F6EA3951CAA132F68F3CF69C42DC4604B359F40AC8D7FC6152C33E2DE529BB3E29", + "sk": "7E83C905A40C4CE71D44578ABFCE6A7AB1978527F0057F03112D8567FED360937FD1E64E1BD8E8E9ACA63A1587322108D5FD639C9693E7AE0C24729A3792C655C3306686F2684A6AAF99F90F3A79D38DF3BB3C6956B38F223E1DE0C628B87AE5093A25DA52B4BFEE1B33A931CA2477EC2AC3BBD94A97055E1A453FDAC9BEBC19C126094C100C9BB49120386513C66D13A54D0491484924100AB52801459012B0010AC22192B625D0A00DA4983122A34563080CD2864D1AA44CD140325300888C262952922C21234D10044D5026122494458484645A38012341214B104E4BB06112908C4B90501C26120901291C141263322D44269010A268DB226E20A690A0124611C2041407620331211A470A50068813A6081106614C988548C24C11000119362C0C969114192151A88C8A804520166811B0610B4120C4B84410368C22C66403A1800C35800B366D98340412328E49226211B0441B21001A190149224249123001488462B6040C0280211712934624A2109201144583C44520073220A851522628E1080A5C264514B184DB480AC0088EC04850A0922180820191022004468C88B2890B36919C48619C4005042350C804050B196119270E5A4085D4B851CC94248936659342201CC34010900182B640D1B4290402291A948D92848988969009392A91B869C890701B334AD02450C1A29048B26123490E0B200A812289491665E42425E19051993290D4824D09B731E03692CBB8908A90251216724BA285020022A4006013837119032E4A1622D0444E62268D0B370208C485D9B02123C240112024882840C8B02984988181386221C644E3A648C8123201312D5AA6441A434EA33090C9266288B2850A12040890400A862D0A03129A4062A3C2694BA425A1040199268E21C46412344400C68148A81163268251A21123930589208EE1328E0C1246649260202281134161548881DCA28043460820C3301C39010C46665312060A046909004002015004426524493218A94410162464246C19392241A40D0A261014C00CCA068080A489938000C1468210354A82462210026C131729A0B2501C278A4BC2650A39080228281338424126061A2725E4483019228E0B02429C400102988181088C92008AC3306E40366E04B4718B280E58282689960959202924869003404199126242C6440A359123B20C91B285C8168D622631634881C9A2440C4330E2A844C02248591024840265A0302A02182E9100711020718B1631E4964980C420C02866D8C6811B06050A98819826308C14668CA4280A24091C876524014954B28891C8109BA861E2306414C7291B2726124125648849029169E29871592681D8C48450480C41368D1A44421C142DC43292CCB28563080C99205244B431249688DB3642A4C800DA30042207811A1889C03824C1B48D2321245A126059208DDA240514392662807103370C40C091C3488610112DE1B2100A3384E4822010324D11084E20A52D50A871E1C471E1184621A84C408224023580CA180D8CA46511A71004358211974D61008108308042265289A6910B2781C2A8651A27410C44649224515188651C20805A0229994042A2108A022708D01670580620A3B231A2182C1002650BA12C01387162848140202889386521872D5A86500A066A03A58551C8488A8465E49411548249192749E2A208DB066120178ECB3020DA4082233981191948E1C48404B40D108710D1864088208D8984915A3441E4C668023681E1A02981C489C0B6700A2988DA226D5A180400C25022044A88980D9CB048113228C9966110A12590C65119A821D9B4601AB98118A52D239445C00832C24865433408112631D916861903501C31515C36424BB405A4240423244612474C408088E280010AB210421249993668E04261629481E20250012669E34085C1364894B0888A1642D03669DA047263144C09224C92862D91900961C44013148122004588464022A7051C146AC4400C4436698CA468D4087149A8300408320838701C98641A880403854D84B8010C208E1B342ADB324D42B621A3B629D0268E21A725242060D1C891C40262CB268D1C89318BB60C09450220900120A8110122651BA880198744E0086CDA484592B80953B850D8A68CDC2885A0A449E12869523221D304824C164594A04C203522DA80611B81801015241BA821A2C2285BB2456094280A1706F4F0365F55F2BE8949D5203EF1028AD89E2DA16C4168B028F367D8FCCF890C765E5C2EB32FCB2929D16755C766B50BCACDCC1827555BFDDF1BACE70F6C8B1AF5D462B60394554125321CF87626152CF5F8485F3F0EE9F6B3D931438FF408C3152304E84E6520ED35381404A49B64C293DE829FF71F275F86820E20E978EB0AAB289A1EDA6B775F95476B15BFB7EACD51017EC4525B36798E9C4CE58B1B495C035F961A00F14DC562F704B76CCE278DAF1E0E52BF4EB9164BEFA385C17DC4274320C7448A4002537925C7C4A3A6F21D8DAB362858FA41870C6B9960CC295571476FCB24F2AE5054DA00DD41009577D61F11622F92F9F5F1C6F02FEA6E973B254A202DEE4AD4FE676E0F1B590EEE5E4D5CBD9A2FC2C1D6528840854D8617600F184C0AB59D5EFEECFC8584C101B66C84C3F87836BF7BBE88EC92FB051800FCC93B105B41D60D7BC3FC322FEB2789F1BA946F20865ABB4A1BB506282A69666075BB813D254839CA5545F6345B24FB87255FBC6952444F836D4FC69D0F5C1851445B9F0C473E67DD7D237FE167D7C9B74341D851E92E3AD9CB9FF33F9157B79152B5AA5922F4EA93540C8B798DCCAFACD157F5DF97113957205F3F96FD74F4D7B0CDAF9A8BB933C37322BAE53F46607B29BEAF09635E572CB6D9F6353DAA787B8C4D593A2941D45A6004B9CD4C8769911A13525B64E8C5978C198C8808F15236F0E8B1B2DBDE6647E8B0D9FD48A4E36E1E5D9B02DA044C47BE711FC4717B850105F9E73B334FCD2071ECC2DC2C1DFF3B5E0668860EB25CEFC8F9285462DB6671CA572DAB0B9C8CCC1C30D0226582511F0D8E3E6943276014091272C9F87D62F8A688659A50E929E0C3A8F6A0037ED12ACA7A6656E4C8F0C77562795BD4CAA8FA2CB9D4ABAFE7A8F07BCBF3B31F3350BCDE58BCE638994508E5C8BEB7E25FB42DE3EEAE234FD12B7E2B388F10C604D36737EFE96DBFA4ED1406C4626998CAE8BE592058EB09B58662B366CF6B079CC14D8700F5EB1850952AB6A1F33A1DBB02B7799D535FC21193ABBECE2AB3C1542F4091C5D45E7272DD11FBD6F3F836D90B1153CC0CC1241B75A373FEDEC25E826E3C9CD4725A8B9BF07792D5640F16F1F0EA0341374AD6CED8D0A4309CBD6A8C41E8704F7812ED3441F8AEC9AA3509BA788F98E04F5DA6EBAEF3F0F21C15E2D6AAAE85028C8B46D4D91718413EF4D2FA536EB32CC22626DA5F2B47FFEC60D021AF9D5AA4240D0F585F2B3E84540EF4AC604917DEE3D871A1BF91C71803A4FCB102C1508B82FAA8762FC3A302B03FD941F575DA3140C793C84B715E4157AB305D33580D463C1759D61BA72CDDF830662D37AE61BB401CA7F67F838522434C53D70A30785690593489B7AD6DE0B07AB116F72AA115A1289F3CF2375839FDB8D0B0A6B97C5BA7F8B427F398DB15FB4E2CE60F7D4F854BEC87D7BE03E133EFC3F2EF7A41C0789114451BA731170409074C8FFB5215418C4C1F53A6DFBD73765143A9880D5B6EDAC970A57C294BFAB08903F337329934160DD8E0964B51C7AE278817B43AFC5642CBD4BB2F78FBCD3A22976A1756805497B5DA22C288CB6810E772A61208DD2846DA977E25BE46AED080354DF881106885AE297977E4840D557248C1CF73B8C637693C3B42A2F9F54566AD851B9BEA3626C7FFDA65401D731DFABE20543305F70176A3AC14B724682BD1787E930181FC3F13AC48FAF7563C26272E7AAE34B5CF530482BA36E9BB5ADA0FC5104E6F94AF5E496F9D38099D89D2589C83E5B2BEFF5C638B86A15359B48A41548B848AAFF320779AF8AC3B88B3ED71F7934323CB6E90D5BE36310E8291AAF090FBD93E154D43CCE896E669985D8DF91EED305409E292D9622DC28C0E3DCC6D2886E6D938D4A6877BE7403E0CC855A45218532B25B335469C20C47A5D25810DED94FA0FF238160EC4E271CD746E9D2C70E5632B2DA1290F8BA2A10E2680BA001228584326814C7C338770F483BF4A2DBE3101A52ECB16927252C2A391B32A24574B4B630F6550CE1690807D7383B24378EFB03386259E666AB0AFA71C53D3DD2CA5B0952F7695D1B66B091BC23CE1115DECE076DED2D12AB0110876C27670CAC62195285DDD229E41165706CEBCC41A5E6BAE4C7DBA625575965198B6661B3E5BF5AEEB7531B1EEAE07798E1BC65B53CEC5F01566A0042BF943E9C79AA6B55AF98732E5C84DC8631155E23B5FC5409BDD46B91FE3541F375314E4C0A0FC172BB3A7418911BEF933C5136E90574BFEBFEB839F0631781205918F5E942F9F26EF336302E1D2703A86F900449075B0C50C21CCB144CE02CA278BD0179ECD9F3BA61EA97ADE4A1E338EB905FB45CCBCAC4A6235CAAD8EBE97ECBF6B7D90A05EA10376DDE8FF931781B239038A1C026557BD50BE562626A5F1877236E8618D7505CD73BD32AE6447EE3D058231C3C5B60E703C9AF21353631345A7D401B74EC894F1DBEA23ED32B1FBDDFA1E12226719C58FEB4E7790F7B4D329F72CBEB1AF9149100355EF3FE317F3262D53D1D50971B53574040390DBDDA3FB3A8FCA81D833454D3025CABB2729B84D1358003DCA4FD88EEBC8317DD4F73666271B9F74763B2530FF7948451FA1A3BCD67D8798DBACEE3FE4C7FD017F523263D2C0A4ADE6BE9901489C4C230687E89FB079C52DA5EE5FF6224DEF88DBC52655BFF36D00ED2EF944BABA692CC95935ACD610B5F5D178D202778B7FA7F7D1E93810879FF10018EA10EDAA6435C1CB44E8DEEF08C095CB456183E262585D9DB2691FFD801F78C293A378EF8B818793701F8282469CCD8AF52C7849ACE0DD55B6117E93AF8CB7D385D618A3880095F3AA75837775ACC7E580031F5DF23CD3FEED158DDDAC8D1927F3F583BB56E37E60198DA73133AF222D346B6C1832BA8E78A1EFFE22CFB7B26E069E197D72A88F1D2EB3A6BE7D965054D74033CCB7BB7A1C7886B10B7F21C7205938172444529DEA76585D79C8CC779BE23884A206DA8BB54792C7133D5A7FB82991B4C912B0469DA9D7A4DA41F745939C237229D3D8EE31E1CF642734AB95D2906728B8404A9E8D7CC7EA7064BC2DBB35E7B3BC85BB54118765FDB66CC543776FD6D36C1192FB351BC177AC038C6573918F46FB6642D9DEB08EDA8D8AB84D963FA4274BF6B2D2E6ACC216FE379056BC5BFE68C217FED4678D711A8B16275EDE204D0C9E7B50875EF31A75880908C466F46B870E5022E015B71E16290A2CAE99761DCEDAC9A485D224D711261F32B35BEE7A76F5DBEEBAA6804AD6E27F1E214FA839C6AFFBE6AB73907D2472CB5F6A1A12AC28A6F2A37D6EA2E6FCDA312B5EEA3F830F1BA742CBFA517B28EB7336D96B208E72819AF82E9D6E3B00C4B6F2E7CDAC5AA3B5E2509B8E963CDCDBE118D71577D810F5ED946AFAC62257BCAC3F6043AB5D6A022D9E161363575C17DE278353B4F891F74C92D1261304D9594C4ACDD9C516A80685300A23864B9065C42C388F91E43941D7242E61F5924D069CC065B53652D13C3CC37362B93982DA0C954F57CF00A287DA54A28D347B2E3E0B30E555E14CCFAE6871CF9AAE3A9E18DAC84CB59EBC4AE3056017B6E70D000A756EEEAE8A44AA706DD8A1E14FEDCDAC101AC8AE90E0DB8B640ADEABA76E8B45EAAF648DE53C63B323D67FE5BD9BF979405229327B364073957EF733EAD46A0BACE00CCBDEFFDA62E50CFAF19648279CC04BD9EED6877B0BE78542DE7073C86372CBE407C05CAF3D264E8BAE22B74A3B9E59FB0269512D481DD3F44F08ABD0129FF336E7C1E464BC2A11EC50685F3AFD0E00E6CA0C99FD1646EC59E313835C929FD4BA95F6B0CD1CD737F22047355F61582B508A8EEB2F3466E37A04856FCB46B289D461274DA1764F1B4165DF1CA0F74C42FE780A96350133C502744F566BA027A5E7D40EB37CE5E810C80AF2329A410317CCAC602910FF51CE61A37CFA056DF2D89514ED3DBEDE62625E4B25DB654FBDF1851674D7DE0CA3549B9B1DBE6F46448BB4011AC09E27B80E3A225B2020F2D6144449AE0B832A6B5D44DC64A495E66BBC6D837298F0C9DF6E8EB0BD4DE699CE17C8112E4EBE988CB6609F21DC4CC71AB5F41CD95BB5AB56970F4BB663C0DD47621F2B0F22DB700ECFB029F24E1C879570F7BB42BFE66470D13F283C591B172DA62B4ED80E1508C1FE545651DD9D3942C26EC580CD2E59F298345C150A88AFFC87645DD0272ABEEC35C244CC981E489A93655F1EBD125F7273E2DC2990C0050FDCAD84DF8D8983BD68E5BF237DAECC5ED9D182B9886D70F602FBB6F6CA966C952EF4C386E2EFE91AFF326EB056E05F17F7A08FC8E93135F41C7D69E463F0519E0FB89B86136CB557D321B25E73034AFAB218F8D5B04465A3421EB91C88790A0107BD39DE71CBA1F9F2BEFFF0E3F64D146C52BB9AAB4279CDC2AFA34A376161F335B7D283F163108AD93A2E3FF2215126BDA53C05A0F0CACED1D6D5338FCF5ED6017153B458F126EE7D7B3D47B33EBE84A56B0755C0A5B12D9C822336C35906A95049D106C71A4067BD78DBE14EAA94925FEA88CC0693F35358CC3F4C52C98C8DF7F01F120D2FBDDDF6ACBCCB7EE08B8D334E00D9FB725538AD6747A7C6D62B0DDAA19A29EBF40381FB20B8D06E76703CD97905EEBADEC69F4FFF29D34D7AFC51FBE040B75860FF10A15FD30ADFC0781DF7626828B08BDED220EFFB" +}, +{ + "seed": "E3B2350AF8A1817D936FB7435C4C0CC758F79FF4696C46E4642670C5A78B30EE", + "pk": "ACFAB5CCDBEF80DAC19069D509D3566EA4330AF00F35877E668230EE94D457101C42488C6F1A2D1C64EB30539F25231207BF67714530E1CA918716CA2DA13641617C283E30673144B5BC85202152F70A41ED9C72BB49F4BA7292715D446CB040CA1A1152A8E77E24865855234131483440E272DC217F789AF13AD77DBE65DEB2300568EF26C729F7A2862C5BA15E58471414A3DCB37A7C39E64A33328AEC25EC03B62F7F5583760161A2109A93CB4F76CB0A9C19C42AAC905028AEC29E8287493F88FDCAEA9F46F6FCD36BEAA4DBA41933747D10640A0F4B129CE215D6CA1E041DE8B7A1E791B7FD19D0FB8F975580E828ECB0052F11E2D2800B0EF8AEADF8605F04F8CE1E1AAB8A817403D45C554D03B56E7711C5A10A8353C0D7249620A4C2454515B4A61D10603494FF26521B93177460FF497B98F170A7E7F12EEC8831052D0852580D3227257827749E9BCA234EAAD2E13589132997A410FD9B4B5753E5E6A48FDCAA4DC1EC7D7679767160D90B7842A17B01084303203C257D4DB439944AD0CBA4F916EBCE4428EC5E8EF6A06B30B162CEB539F9EA80DE510996BB857D169F9705B362E097DCB529BD20EA815D55E0DE2A117084C29FDD27E6C48796C162E2EFC4FAE9E53ACDCB235B795C671B2D72B34A5CBB7493D02FB84BE4229BFB4F668E5DCA4F65F7370B9AD2D19B89E2EB2D33DCFD904EEFDFCCFE640942799677156A3072D5BDE13A927C34B4509924C78AB56661B37D9A269DA60A4941E0BD9930915B4EFC5D7783C0D111B172632AE105C8B79EC3C540CAB50BDD214E9EDA38058463E10EC3DA5D2553B3F823D12515DE2321247E570B9A4769E90451F16527C5EFA6EDEDB8CCD23A7EE53ADC0D6CA0E289486BE0A1E1246FBECF67968FB50F93C5C018F21AF32EFF9A34EDC42F2CFDDD60CE0D41214999903304470798BE4D2AA0E4579374E97CE363427AC8FE4B40BC2DF55DF1089DE653FDE138D1B9549CF0D4B9CB5C53C74769D7524B0E9695045E3A4484C7817EF4A653DCEAF454F035E7E424EFDB45ABD91B78028E53A1B6DB3A8DA27F60BD5E0504899A955A0501D581FC471FD5560DB991774A39E202103041993A7274AF5B7FD0084E8D87F6351DF5626AF931D9644C544D134FBE29BB49F23BCC552596056AC4D260D52676D8352A17575130C245E43443EECC0109D29B1FDC3EA1F42C4DE1C603D4C1C67E871F706BDBC388648D416BC38699E6CD89BB0794FEA545A5150D2B4960B6CA483EBF71083295FC9F104BF804E700E3CC855F1F379701BE232ED6DAA4642D9FE83901D8B76388ECAE976F08B80CE021744CA29603923E1E6EC4A907BFEF119B9979D282D3D989509C91F254FFDE6F3339B0A69136FCB45CDD650889981547CCE33DB5A12D6702F9D88C16496C9D623C460EDC58666ECB3014ABB54CCCB326F7A6C405E5DA27E06FC2D02EE8F785B968AE2F05836D74ACB9086EDC3414D192ED69341F8249E8AA300EF050B8370B8ADBC5353F6C90E7726B41367E0954B3B409A644FF8D04E56539928C8C676DCE1810EB9B17F209C0A1E02F8D27BEC5BA5C516644DFB80DF016EA59245F730EAC356F37393A2A014FB6E1369384BE9A7CA34AD85348021BD9B2BB488DD6966052DC377676B7906AA7640B9A7E0B246BD0D6A49BD9CD8C6DB4628C5EC1CAF0D154A702D3CD838FA69163102E4A41605D847751404C0F6A75BA3A4E88612140AFEECFC4835BA4B8972B3BEE3CC22A52877FE08AD7A4ED7001144F2D5E4D27F59D310BB4C77EE606F5F4A5918408C64DF84ACE033668E43FFF6CC05A994B1A8F68CED63CAEBF95F3C30E71AF35CFEA31B9A36834698EAFB54F4B9EF83D8C597491F858BC89218CBBE22E7720FE2DC057276028BAAEF3E260560E0ADEA89C59E67E7A5B6860EE069A50CD10081C87C9FFC5B1012E9F79B15C924B7FCF1CB17FDAE8B79C4E176478173429B92C916F34C0D139F11010AE39D34B5116D9CD02E232597C3CF8FC740B8EA0F8243FB2923DE5ED7131F028435424DFDDAD4A46FCBB33A2ED42FBAC77FA36F2816678F2787F5AE11C64431410E63861B972C87599C1815368CB1C6AE9B956766F78621FA0D0B6214FEFE093C6DB2554C70AA472F6B332E1A5DB4068AA73ACDF50588C0B95DA328A862388F6E3C4191406F38FF5F526ABE35396CBF57BF6254218671472FF46BB4AF7905CFDCC948D61E4D72FE8D09418EA27C67095D608315EFABFED54B95B3CFED9BBCD55A13DC2ED0AF7C014BBA0B2239D511257B28975640CAF13C1AEBC2EC7F77AEEEB9617D6E5DA22AFA50CC6092F1D1DB34EBC2B873621B4DB9EA05FC497B799B0FC136D107ADCA22502F7BA903B3486DF8ACB9FEFD436A30D6E5488E6819167719D22ECCC383C146B72E6C6BDA12A6B7879BC9DAA5DCC85E78CD072B87B13C7914A249BA9C0F0DA96518B7BE227E5BF5789401C32C9FE5801206352B3FBF4E684549076AD1F10D4ABB782FE2DC75EAAE70D7B1F0FF1691BFEB248019FB45DEF28DCE655F1F4D9BDB083C8A7FF9C820D0C95F6480BF9F134AD7E7322E5E5D9CD8E77D02B106312189424E7E33BF8FE5EAC286E38F38D3C2DFF15A2CCA7A2EF382CC7180A39EA0962EDDAF7831EE8D91642D847108CCC7683E293B181E504293EF9738AE06A54A97E2CAD6DA5B2F1323D4B988CB92DEAE70B0027C58C31CE520C88C6E162AC21BDF5F30F8E2CF40881544FD7E4BE982E471E70D19AA51A0E564C49BB8B216993D6BE1C148FCF1AE1763FE1EAF4D05202425007FBD68F7FA81541FC8EA87CC13B93D404BADA2CC10DBE8996E9A694465BC91613C1E4F49FB61E8A7B75B954264537A935409AFD7FBFA00EA14798B8C2CCD0748801F5DCE2A61EDD9496E7508DB5C321D88D18979AA281C64202F945EF1F9855D0C867320B5E2913EBB84761338E7D990FB77B3351B1C433AC5A7C03E58B68842533D36DF772ABC7B9C20C9893951DF56821EF1C49C240F00AF16B5A9D1041E96AD648C5FEA9FE4CCE57A058858191153F181D9634E2969BDE6D86BECE6E1BA52A3D9BB29FCF5F85312EF2C28C9100E8BA0CEB4063DF7B54D3B4D52F90B055A1D6CADC626DDAF48F4E0B647C0DBD5A07C8F197F13C69D05158E134A6893E01ECB1D1AD019B5172CA938AF7699F5E459F65F807CFC9B2B21F4151CDF0FFE2FE786BADA75CFEFDE1A17D3B2C56B5A16DE8267E163045D71F540AB7508B8E89A6B825C416E54BE002984743DE2CF344A0E8292F18A533A9588A05102F40534F34A030B9E6BBF8A01695D9BD60153AF79CCE2CBA83167A256D56BCB87A088069EEFD87098F162DF64318A33D4618554C49E7F23EB4BEB0DDAA3F03D1FEE20A2C6E95CFECD06BDF650755725870048578CA2440194B8E1084E7BF06141D1F522E080308CB9B84C09AD7E5CF72A059E4AF8761425EB74D0C8EB536C7465678416E9E94F0C2093E9EB693D5BCB78836272486793BB4BCCEC65B45186EDF4A6743F1D2726533A8ACC0132DD55DA3031834FDF5B9E18B6F5F24020FEB4D77BBAB0C0695E0FABD4909E5DC525CCCBB455B3FBDA6AA900F062CD64730C27BCD5935E6C3A5191BB50D5EA974D366A14DBABDA87CC826B6BE346388A488777696E52860E6AA85383DFA8D354061AF381EB1", + "sk": "ACFAB5CCDBEF80DAC19069D509D3566EA4330AF00F35877E668230EE94D45710588C61A2D2102D4454B6B8E789B753FEEA928AFAEC16993C07F775DD0C20127B45D6F35DC9989A44EFA13013F86054BC0A09A307B909F7052AD59029C184D87AD0189BA7ACE7A66BAAAECB99361E393F00770F54A5ED4BA262B231C1DC79F67008846904046918106E14476109A52DE4488053346291022502212883348C11290DC3C84558B42991A6201036808AB4209384044236821AC41042004812162891A24860C685A09448DAC071D22050C8449140364ED4A804812088D2A4891CC450E1B86C9A3080C838324A000599B8649C12441800326420415B1868004728C292402101621341300016224046025480311B158C11838090348940344C0829864BB80C599444DB060E42C8709B122EC80252DA242610192E59A23103138E23C03052B46C08132208042D5C402D194046980481114790982682C49091A09804E042300C8824D308684938841A0104D1302EA1122C4C008989281204B7511AA76818372E2012802315840A87691B1085D99020D0B22DDC04490349292141269AB66044968512A34D013769CB2080D0B66DC434698B246EDC440EC23801922485E412008A122D1A497104174A61C64419286264080AA3B64C0045111296804B363014806102871002312588388542000D8C906501050A89A68C8406851448811B0562198608D902606018009906420381096240115440068A0210C92884D830420436219BB22C8A4452A09805D8428E58C40D54183110042D1947200131321A335088268AD2804919C8214BC04DA11405A0300A919629A04051DB925110C748504860C09650048205480265DB2424992226DA966C09B98C09174551424000060A1C2109D12628591410E3B4904B1809642029CAC849E4168ACC424E03456A22180513822C813261CC922C21254923B39101B349E236851AC650CA2840A0348DD21045D3C241DC886803928D6008266398201195700884481C1646DC48218AB22D43164663420C58423108A58962946C1C016DD4422A10336113A86C224210E0021212B00D0B358610A421C23631CCB0614922524A1685539001014669821265E0A869A124122122814A486A91406D1312445A466A080046139008C322889CA04863966814892DCA08042141614C2844A482440445120417458948705C08501B062000204CC1C86552B83119372124402281280148A68C94C42C2404300429012348899092051324625400709A108E21944D408029841282A2884150248484820D214109D2B80594266094C670C4806DE4962D9A240C18B9315094700134496298495C164203C92112014C9014469A342D61404EA4C28DA3B648D2984DC91620D9B0801009869C90410B8825C31832D2388DE0222151B068849400D214089CB21124086641A83182A224E4A04412B4689A04801410889B980CA3C4815AC0115B86685C444E23C5640CB231D4C80004C98521432108344458440100068D133411A2C81154062511C9281AA8885B1282583402CAC68D1A838941260089A41084A48902088421B30118C68813116A44022688028D1B409010846C12284C414252420881231624D8C8501900110144508406481291081102211B878DD2184192C4019180681CA004402024911468932024234062A24464121004E3946C19A931E4468640C4059BC2504C404A01A8089A321102A94491380D0026640412111A2212890212122325A4348A23B321C8A424512821D806681008084BC865C12692DA00609B34061836060B809111A94C13092504420219261012290122228EC91400143989C4048453928D11268252045052309094245012147222350C18B22D228430044281920452144052133789C8228E0C204504B344D3C83101A131002466A490041A494610296A610212C896494906700833868CA6514200624C424E932089139865DA140A501245014711C308648BC20043404C0B49325922462291014426240B264A90422121110A10840DC23482014249982640212171114045134610919620182310CB340123952013C511C38230A0144488209201233258C831113184E4106501940059061193080222A78922A42CC124711048214CC605C3284E1B471104998901C04CC3926CCB2068D890859AC44DA29089884892D2B46C0B180620C571238490FDE05088FB395717595EA65C813DF854DFA8AEDE97C0F8DC701BE92C6C79873B0FF5BE6B0CFAF8464A45D2BA5F1D2110B599D7F81608ADB80FB5A2CC5CD7092C5FE4EF02F6AD15902E03A5FD6D39BB6B4E3D79E52C23AE1A3CF269E1F501FAFCEE6AF25C5CA0C47043C67D79C421E081CC89C6B28602174B27E86C5D1A3E1876C2F53F7C3FC53A2405D6035ABBDA69AC32174D18746907E86DCC25B949C998FBB6759163EF9D4AF56539A86E21A8BA90D7A36A92043ACB02A205A23F40B7BBF7A00D6E6EB96CABCCDE88992F1EA76DD79900BB0BA99A562AA8BB9BA85A5F9B43FCA8F5E9C98B93D1A69DA7C2056FDD455B45E4DCF2E4BD359AB127424933ADE5EC8578F4E7262D2BBA50BB96CB5F8C00DF7DD90297E696AEB1BB7E8F3F16260CEBE3C1D61A16E1C92B286AFFFBA544AB264B8140BF77F720AED373F4C730D66E6F03D18CC26F1319F489FDC69F9993ACD0E4B0DF6E8B60EB06039880622A21E407449F30CB25CA14D4A409F1AE4419D87FF5927F932BDA8CDF972D7E6851BCA99444BF90E604877B865D9BDB9DE70D66219DBF4E9D5328B411D801F75C655DAB68B00A573FFD1C7E3D6F60EA042120242BC737B9684F3B9575324C72EF5CDBF236E6ED6E36464757396349CDB9ECD7F2827624687F6657071DAE514A27E6386837DFD290172F6F0EB41F237E19662293ABD847CDA90D1F83B231A1F10229A05F11CC6CE6A26712A5DD5042CB4E87394FD46D09225A4BC2BE61302461C432D3CC5A8726000A1A5618747DEA42D2261CD7B0659E05E1BFB90B7B796A31503EB4D73703A4DB8EBB852C270AE75C9CC8828B36C9172E6AA87C25116CDA489854D478C1D635D18E678CA822EA5B9C84EF2647F83705BB39584FB28C0074F805D6AFA08FEAE60D3C503F3124579D3B4E6DA94DD8AB0246416F036A99D7D5E4D042D3F5CF1E1852154B7D54B2B44018FB2515E6A78B09D7BE1CA294348D43348CF84666E99B8AB0A157D96B3618ACC41DCD53631966A2C86C4312447C66F71CA4B43142D46F6F45CF255731665A130D659B11A18173EEEDF4FF7546391AA8EF0E88033365FE8203E45B4A1F9DE544CC1DD6FFF4C467F2E78DCCF966FC3A7D9C37441D870C01B5A0D395C06395D15861B09396C1A523066AE76A2141652ED9E4594F8B4755135D9AAF4EF0B3A3256B18A78CB726DCE49E98AFA5DFCDD7C424007A1E1E66708B82B5AFFDC8F49CDAEED382FCD8056CDC4FF2DB11D5188C2C17B8286BA12F02E46D11346D2E31E2665D2B75872ADEA0A57731226B3962F152AAECD13526F8DFB912C63FAF7750E3C764F03A1011BCD546A6EB4E27E7C1B002B3044E50F3806317C9B8B610B91135E00C6E3A5937A0A6E964DBB3EC9332256D19553125A4A698E03E6ACC934B004C9926C0D6FDC79AA333534989300A5F207FF439ACE49F7E81E4A4BBA2924602FBAF3B335217BE6422C45C3B8EC631A88A9F71D20CC650E068C50F3046D88AFFD7CF983BA68EFDAB1762D0E32EC722142D5BB6347CE84F2E05DCBA3C6772CCB887F7F90AC4B070DC92D52C6BC717BA95EFE12BCEE3232250770FCD7488A2E75962B6F8A21D4BB83C03A59A3869285387013D4B8D7198E8889A108A42FB2EF83529D934D1D47B4EADDF9A87F45FF75C0560BDB637BE1D10129886964D2E127C7F204E8840390D89C6616FF17DA2D681B5C6C3A58BC8E741416F4A38764BF1DEDDCC392BFD82B7F50137F8D6898901A2E1B9A2BB9FE3BBC66F464B9A48A3DFC2D78A0DB91B57DFA09920664642B6FF95AFBBB3D75FA02DE3AA35703DDE0F9ED297B82E8533139A82CE6915926B704C4674ABD62318909456A4A2C9144FDE0427372B5AB67A1A2629D4365F57CFCB295BCB077B91EEB7955C6A0F5484D2D7D023BC51DEEA0B506D453C58DB34C59D883E7FC6114D38BCF367CEB384B23EB9E0DFCA82072B2A6552F8CF045D49F4F1647359FCDD137AE02F00135E5E44949E6B44A8745CE5AA7B3F06DBC894A67548550B68EE4DECC21AE41A9E06D980734920AD3B5CDD4AB69F8615663A9FC0E4597061471B234B0D04EFB5D74CA1957C1F6F59348AB738C737F38E7423F6283DFC1E9892052C09DBCADDDE2EB0D3C3996A737346CB09FEBB61EF3D3D3D0DCA6D33866E0CABC54FECFBE3EBE661205AB52DFF8C3386B19B1A4A69E8423FF31919764B4FFA08FD66DBF7BF5303B1C9F01A95895DBFC8B561E57702B07DC9C32E582FEBB3F4E258D3466301E7EA0B0E08D6ECBB5A9C3CD50B42A07C5A89C828179FE709AF72ACF0D40C90F05CA7D1215CD5A644B684F34EA37F8D6784A2224546833003DA12535B62DF56B2CF5192B271BDB5FA888FBE73DA5FE30F216E834034E8E718FF4843BD74AE1E97A09234D3B7E4762B3879BB3538F8FDDD921C8BFC3C1DC9820A375BD4782D89B443E621F165C23B0D49ECB82B32E1D569A525487BA9F91E2EEFF3C24E98D3DE8E36F0D48CDA2DDBFD15CD9A9572151FC66C9244FE994F52A832A5A30AEE67D0296455A3AB6273A1CF434C830CA4058EB440352596F81476D60D28F4CC9DB7146903990BE339D8CC169768BE36F8DC43B65A0E9C50B1A79FC131B794FB8D6910BAB8B92D5644A934DFFC58FBE8DC24F2B2BE897B2CB5E2FD75C01ECCD920A21E8B7F83BF778C1DB56DED43A74D6B8C0FD1ED4F4C897C82968EDD13C31EDC86AF48A5BFCBCC30E97298EB782047625E2B125164B795017B8EB2F992BC20D39577A6F3EDEC96671906FD94DCF62518A18B4832F52BAE51342E300ECEEC4DEB7DBE314F2FE65A238DFC0D140A702DF93C3EC4FCF2B2F357ABBD78686CC650D934E8EA18011FA7BEB993AE2223FC75F64898C4C32FB487A827E5B19F818BA0190107F2DCEBF3B56D5DFB9352A04DF74F2E652D1E11BC45E419E9AC5CB55E876F5235229DE599A509C49B28BEE7F353F6AFEEAB9662D1473B6D7F3374E7A6B13A8D0C88BBDF32D2B065296ABD3A757D0022DD4CA53FC9DC8C8FC0A8A63749603BBD46190C72F9BA7A4F326C61A532706360E555D275F996F021144EEBF7EC044BF95C134073F927C0F6575B85939DEEED3370F1B123E230245E69CB6A7F16E139ABC2ECB98AE42EC1F61FD081CED3E9E1F8280735CC7BD81C73C3D66C21CE5C3592EF8391060B41EDC80FB107DF455041082ADD0DBBF5BA6E61E533AB60304D6C36AA9DEFAEB1D5F5853E119D853A0237FFD212E45F5EC95634B6580253A7924AFD59F3309B6F6E010CCA0919E7D2DB088316226D0D9171574A4476AFDAA129C442AAA16E35D5AF3E4738C4015EF996F999843BBAC69175AC26BEB89FC27DF75256F35DE4F661CF2D53A3DFC55423D162C199A7C1D9F51062E39793E74DCC9B471EDBC70EEBE20E644F5E0BE39730A3CB1086C72F9A1C2A2268E3BA67E71ACABE15188120FBD0B7EF2C1038B3D3B39BFD648B27B06F966D5B2D46FA6E867446B8E8B32BE5C585333E36CA7694F70E345B5EEC2A9C1867FA5B0B95B14DC811AD8951CF82A6D80D7CF9E62AFE36DB9694128C578D561131BBC3B3C4379CF2ED7FEA106B2C7F4EDE9F2E80E68F92C93769D36A1D1BDE344E69F6F42304BD78A2DB3AAF3F768471E75731947278394BE15015B424A44BF5B734A63441A9FD07E74BF057E5049077CEB07C3AE573AD9CED8B1AEE7E9DFC3357396BCD32E520690D9DF368E2EA4CAB79328F827882EB0DC864C8319A63A6B3170549DD11AB5521516953A1B66E07FF37E038433BD044279D1427934085171CD641D9F8049DDE8D0FFA459377C43B71A9D578D1EC458205F42058EFBAAB03CF9445384983ABBFDC4BD358ECC5EDC56CF8584D5D495D75D2ACA74073C9218F5264DCCF6E08C49DD4652327EAECD35C08A918A572A6C54481AB765F820AB0C46169BAA3017D2096FA420B6A03F81C4C759B53E80E792C438DF5EA6D147708113F36E911B56334E36268B57C3E0700123BEFC78FA5C73192EE03EAC66B225DEE28752AD43ED299AD73606B2E62BDB589E8B95E7A066D250B128FC0649363D7304D8B140D41A85618919F1B0C547B23E9762368E95FF305B16944F3AD25142D035C20EE3264B1D859F8B8CB675FDD1F343CAB8D832812A0313AEC6A1C35E24BDD700CFFE45C7C498A867B5E24CE67AA977559AE5149EA4CBB7A421958439D0134020D2FD4DA4893AA7A1095B194B71EC7603E5CC28160C5A9A808DC337AB6006288CD5570474BA78C7C9736898BF531A9AFED78617181F1EA6E33FC3F4DAFC049CF13C2F9CFB71686A7038DD43AD235E894633944EE722DF168BAF9A5D167932F4E8B2FC556D62E58407A39EE3E666CC112A38AE7F3DA55C930F3DB2CAAF599D2AD19A5F903D8CB614AD31BDCEDFAB67BC6CBB67492B9267C59AC05E4295A8CC2570FEA32ED8901ED9424FCA18D3A7E9D60CE7F0C49D0DA9671985F53822BF517CB408F061247418DFC9DCCAB5FAFEF0DF0A196477BC9713D745C3A8276E6EE5373FCAD8A13F9D410DE705F504A6FF232C0641934161D0441CD33260C77396324B644384AD560DBE219E684AB60E610F98E48EC4DD5F473388E6C7F1C6DE2A53445C117650967496749CDB013F9581FE384A893C259CD05F015C6643871402EFC6B0DF5C1DD7CE912037006330259191F50546301E992918CB4DC22C36538FDA1B3B369BFFEEF8DEC7FDEFBC498E001D18A" +}, +{ + "seed": "75E70362235CC7CC4A08053BD887CDCC4E3D88F77E1C7DACAC972A9AF83C0CB2", + "pk": "CD40B5E59137D2D9A6EACB9777C320CF811D7B43E0047ED9BA8531A251780D96603A9F1803E43FFFD3748DF1F1CD131490C539CBD0E9DB5F23BBE7B8C6C33E4678F4CA674374D7605F33F122C314638D11F21A0C810011A87F0E1D04D259A6079BC86571F5E9ED491AF727BE0659A15D9B028D4FAEB61EE093BCAA0DB72374978A6AF78E04D2D3C15B9432DFF6F3359744517D05F5BAB7070A11310DAFAB230F91E7E8B0F8AD23CC722B4E5A5E546A7D3251E4CEAF11395F15F50CFBD6BD0F5D637B1451B5386572C3B1C2E978D0005A30DC34E0CA8588E078E9E5EA8DF2AABAD9ED35782904939D14976F624D5195310F842F252C5F7A26440FA9F2C54A4D03180A514D2C215AEBD528B760D4938A0D85D6D8AA300F7D294E7C325F92FDFBA5CB5FA4320A48BCCB8616216C53470670EC8424F47149D853BDEC6F108CFC6E537ED942FE437C3D47EF70436C97A4341840AC4D6B3177A9D88333AD0B3AFC336695D8D6BEE13D0F97E87A66E5DE08C918A6D553F8F49C1E71BE5C9831308E9ADF503807606F2DC14BF46C377C6C98E780808BE91096C8B67A6D97A2555B6194BA9594D3E415CB96302A602D20B328FEB424C12ADE11626C27CC7A19BFB8308CAE0425C9340D5679BD2A7B9E7874E4DC03A323C395F204C2D1FFA0441C62E42494A13D2B59E59F8CABCA87A139989C2E38EB5C36B0CA169E4AE719ED92523E30DCD272B992C8B859ED4059029E8851C607C606673334D6CFBA44E501D596E8823A2E637D3E75EFEDB8CE122462D94075C4A0479695BB7AB98A2815A115226D93ECB20D92484EEA686A3F580225DA87780B2314CBD7B90F38589EB04706BAC8FC90824420802C87E612719DB951CCCEAA4BCA5BD77BC781FFEB29CADFDD9E91202A7CCCFD7B25DBBB91BAFB361597A3C560CE89F2E1AA884897328D2ABD7C41871197841A29F69A86316CED244125AFCB946BC968C191D91FEAB8498D58A5E5617B32BFC82C53D2E3BAB3ED5410F10F188CDDB8FCB9ED9FA20E598432482103A7583A86CAF8572F295F712CA91C0F453FE77B0175AF20DE1492EFA7289E07FA4CF907FDBD91B9AF460C6DF8F70E1B48439030CFFAB1E5D19913AC756157EE709BB9BA9EF982A679872BC077B1E61D9F08A9E7B6900DCCD71C6F0ED71A86FC6937FAF47CEA0B65E94DC215532487E634411B8870C418339B063345948BE07D3A3DEDCAAACC9C65EFE292AF924E08A78B93870CF0DE7F87FAC477F54382D597CBEC10CE7D86E68C7C7BA61CD9258A3104729CB1180AB988EA39A1C0DE6BBAEC8D544226C738693EA743E1B677F44C3322592EB0CA8350152C385F48FF8B2BB747B9EB2AB710527ECC053DB826630FEC5BCF6F42BB8AEF9611D532CD073BE341565458E47FBDF214C3006457B0D1A18187124047160D7B87BDB1790786A4A53767BC440C5DAF372854CF8C55C03CD556B98FA4E50AA37B038F32A1B76BC70E17E1BB065A03BD33C3B22AB1E4C353526B1D4B01A1F15C33DFD9DD1D30CCC638306A81E395E7F74C5CB8E47229E6E601DC19DECE6E7B366568E28AB8271EB4CEF5B81F651AD0D9D1C8D12BD5F043AB584183827144E47F64B44B5C32D154427BCFBD25F52D797B218FD44F0F41A0EB1091213FD77771E2DAE9A4413FA499212D0A2C24C39EDA4960A46B9999BD5DB0E59615C16683AE8D92934F81C4E3B1B5E3651CD088A2FA008D632A8735651ED452F882032E9AF465F5B7E339B0145B34D0CD011BD7ACE3F5CEDAFC60D14F028EC9931FDB033C1F5F38E3E9BC8160D30B5DBB61B423850DEB38139162CC2E98010F486E0B78E5AB525DD13A1155F5653BE40AB16BF2EC096E962D40F52AC47F283612E8ABF3D747F597250CD511795C784B5DD52E521EAD85792FA1FCF03A6B2D1BD256A1E1DCB832A96F2A5B3830AB8CDEA95E8F0EAA3427C443DC99511EDF971E7AD0C0B629F480BB6A4273F66FE617C63657353BCDB5E2DFD533B6FBBAE9A35828019355E3E09C44930B172C7CE28AEF9C72865086443A0C1C235C6954705BF0E5CBE6F45F7DD02C4DC2A6EF9DB288C7C325C962A27EAF3A8B3677C0207FE66D75C1E58E847569E2FBACC6A1EFCB92D728CB6EF42EC66AA447C458BFD75F3790F46D044067AECA98BBE26472EBA5660171EF4C40F18F56D1CD42C9ACB36E342E78EFD65CA3D2E7E1047701456BD9599644F7B334AA7A64B5C44318661D328270D29F7B16994A1E1139A2B52925DA5C07ADA48489AC79E8630D5E72D03B33637EF0B81A54472F634E3494844D25D8B63F5BC0A32E7296E408E55B68E283432922D82426F3EEB0B1B35681A254A2E803BF6A7D140C8B4CB5A6919960BC0E787593D34BD7E5774D9B4321B61FD2A2DF794FEAE88950CF7BBE223C0117B8C369BA854D02645C9489AE8EF9A7504CE29DC5C45939AD19C9168A5561ECA1131D52443A4457FC203854618727EA00B52DE2F7B19AFCFFA01716951A5EF5140D53E88C84C707D6CD2B1F71270C940946499FA8E7FAE15F5BCB6CFFAF3CADA3F3BD908BF5E1B73694771F65BDAB6D4EB429E83769A1A727A6C7003DA53F747B4BEA711026381CFEF0D9CA7DEAB34192952CDA3DD0B49229105B7AD22C09C75BA2B42ACE26A0877793CE2369BBF5A72BFA44384373B73C88EAC04024DDFD96D98BCAD23FFAF41EB009FC8F0210F2B3C9A95C384B1645F3BF1F6ACF5EDAE1F3AE5E68E5FF4062F6934758F0C60C6F78B8839ACC5EE0A0FF31A4A57979184BB651D62C2F77083682049D55C3C75B01AF4D29E43BB8A14ACB5E843B75ED0BE125E7DDD092DAD5ED09343695474BFA32488FEB31DEEE31AF6B6528C6D34FEDB52239FA5D834A2E5823DA2F024A7547D21E88A94DF8381EFB72C0550F1DCC9141CE1D4947A7CB0AEC57C10B4E995377E96AACC0CF03D720175A92B0D1C222D4E0652E86063A5F31EB9CD9049AC0A94982EC0AC281F34768D1AB5943F27AB87AF8FB8192BBA4E540467016F1E821C433F80D7A320EBCA0425F11F2166512CE5A4B68311305710C8AA3F1B9F18E7F3B49347F8009318F92017CD47478E73DE4C1D7666729F969CE9E401EFDEE454EDDF217C791BCABE7B1674A3FF1191D93FEE46A27AE116F08F1AC575E88A76D115D8C966ACD63BED57DCCDAE0AFBAB7C63B47277AFB200FC4693815D53F529B85819966A92AA9CBBA95397F57265F2132DC6156F2FC64F3E7E5D47F579AA01EEAFFBCB30A25E6BA8B01F0E375847252C95B33E0D1983C0161B5836A6B0F21E9452F4E0E1972098643CCAACA2CBD7430D3FA6543EC473AF5E911F0A5562F7DDEFD57FE4C22B8E742718E1F0E4C84845743F502D5A837882DC3C581EF315E16B4F46B0F3900839FB5F773E4F01BD504DDA48C110C8BB2765CA294CCFA39EFEC4005649B44B169472A5F7E27DC345D3A6457A35EC012F0DEB86381686FC294F7F57F1689E3B8F7CE1542BB3277E07954B7FCA5C5F903852E053D5D2A3BAF7E728545C8E63F6A773A694A5A12AAE8C30B99C706B84C51304508AA149EE74B659829BD7A11DF53239D6729DFDAD18F77006D282E3726208324C779E0F27BBB97465A56FE09F7134306F0F627A71918DFD4B17F0CC72684AE843A498A00BC259827AAA8A15079459D20C517D92FF1F78638", + "sk": "CD40B5E59137D2D9A6EACB9777C320CF811D7B43E0047ED9BA8531A251780D96DB67272B3329CF77EB15BF675572262FB945B85E6463A8B20CC8C2685A461A728E66AD389C34337138FBA18110FC95592D207D224F2B617C765B22BA604DBCFEDD53E9C98E5C450860FD37B00B3C2D4FC66072B312A89FBE4F1BE957C22337735430314C306C83C221928048549269E132621A87708C386D080029648610CBC068584801091300E200725300929BB488D4421004A669E08890E22290021631881842D4302E03105201B92C122045D326011A936C4A10010043022338659B365153882510C68108198522B90410120CA2C8205A142484822C12284024450EE3062D08B78082866889402A1BB821E1400099424141406109252480B690D912850B368A24A92C11C3056244819CA62861484A53B00019A67103A68901382DCB066E88B02020B7311BB3659BC20C9B1205D0324A48A049D9A27123122CE28224D9B490633648C41060D2824054108223A5510044514000110149850A21129C482C042512108784092442CA8081D9488E1B13021A098298040D90269052202D11B728DB36891C044C03226C81C26124C011C3084A1A120DC342125AB045C9C6291B30114CA60111B32C2307819B0612E31841140229C83230929841DA060D93184160C891A0200D513069E0A409DA98416346701C4261C2C604E3081118C0456146100127716336101B914402B00D144488D8944D121228234270544072114524103105CB28504A9684192368E0360892C628D0A271D204009B2220A32620418890D0128612279023A76049920184B62884407191B60561182584A2101A069264845114A104231268D2C4292205129248051C042C1A286480B4241AC8719A1209C9861189168D53A80D14148413A08461180EA012251388080A9350599228D2A2201BA008221509433492924412CA82441C144DC0008849120A52C86510A65159800860004A23B940518408E2906DE2989124249181A80023824963482A412065A3040503906C9338920C37050A058924450E13494DCB4221E1104A59A650CC420CDCA88DA4269112334660180A0422648C189080069004368513044494881021916804A645C40448E2C030102946823246142081D32601D238684AC640189740C3122C4C0441018584C2446CC400100C25712243901C4486221610CB468D1B2008E29250E4B864E3C6814000300CC151D3A4101AC04CA31486CAB8018B909198C44D82B800C9C20D88063099246D1B356D49B00804064D4A3686994228E12280C2C4681A244D180328CCA06CC4288AD83804144951599670C01645E1906C9432252416411C30111CA14894048E9BA208C1980409C649CCB620232652D93460CB08044A1624E04668E3C20C23258C50282E54326AE146045B245002176E13300093362D9A064ECC44080B44310BA3501B430D53168943240A018525A3362A20318012874893C265D29221E42466D3008A1931129028680B2444C49828C1046C92B86DC9A889080831D016480B322A88823011490562200989066891B24020A048D4046C981646C9B64D23A429CC0490D08200A382841A450859148ACB805009C645493061CB126C41286A024980D8262054B64CC13086E2100D648021148524642646D0448889306A11426119C47051A445440001C2B86CCC388058126C928031080202CC340A62C8691CC73143B681113062DAC40580300118844188288D611064108680198421C82050102592144568C8802110C4100A039224412422A94102240684443262100DD3B84881988CA020805A46651893919A108081A02D01076298124E21B161143070400830044891D1C221C2060A60A6658B84800901255C24850B396058A4884B961062B01111247009078411844962A2454C844D81302E80142D00133043C01018866850320DD0284AD9824554A6240B94258C302C004849D134868918008B847122470A5888800BC884141640C3144E13336422448A9A8651A0A4648BC04DA2120894C0441C918C8A042ED8064D5B1800940822C2C40DD8A4900398694A86901C440212470C122950A0940414203181288444486E82884920B22D139371101188DB080E0C328A10A8300B274D88940843886899A281C82012C9482C0B154A4A1689E29864A0382CC4203124A4009A068622B405D20809C304417D180ED93D26C5171687CD43FBF6BA795D1C7C15936B549B680CF2EBE9FB44C51D62DD547CD205659A2CF3BFF3D9AFE85044DA2EFC2BE70E056EC313F7B7FBA589265226BC8A24B7B112CF7B967AF99CB71A120B479F611BC3D000E4B38D802E2533F9886A6AFE8DD383581DF8FF83DA2F308D687EA7982DEE7F81DAC574B1F7E3DD2CB010ECF084CAF4E3AD55744CF59A7BC4F380DE877837974EE1489900865C33DC3CAA99E08A6FFC03ECD8EBA4356CB5D23D9612F0A4992FF216A006ABCAED535B5DB40445F5AAFC3680EA522D260B86BC75ECF87346421243D63B889B08E52E0C1C9C1C783E4DF09E61CADC7ECE41D317BFD4F2F6FEF777E681E4E6690B08830E5F1F4EE92959C1981E4CB746D1632C00096EBA57C8D0C9C77FA74BACA4AF7C1C117E7918286BF2D4CFBB387385D928180176B3BD05E2768247F586B4E817C6783B4EB7AE95AC792BA57C707A61B47506D99C36FDC5618BD8D2C718F278A3E9D52E14C224F779BFA8AF2B0F596E93A76D2A21DF4F766753FB34F2594ABCEE60AF2D8B08DC387A8BC1A36C6D0A08316780848457F4792A1A93FD50FB1902E94EB7AD5DABFB0B5C2EAF0C778799E72E6E13BB8EC2A117E90D0A5C9E09BF3A5AE930DA3998FD3E1247955F0502D316EDEE0E957E9DBE71E9DC1372185E89782FD984C4BB9DE1962B9CAC63D8EEB6708C69964C9EF5AAF7C3D4BB6D993977A760F29D46217FB7FEEE11443C561DD4480D48C3F4FF1987772C108A2178BA9E0756FBA4FCF0FEFAD74D93D1B40A04B82C922EDB9BA2A2EE3C3B0C81184B7C29709E6887084F3DECDF2CE555200947E9C5904949EF41A30576B8A387E2B82748DB73EB7852929E6A8BADB3F446EF4947C099638B213E55F39AA3587C5C8EEC9B2CD26F9048CFE58CA82EF70A96B8C81143E57C2E822BE4FB35EE6AC3C37A1FE6ED44CBC6A753E379832E1D912775743B62C6C96BC97D41C2F8714DD2E970687AFC42BE03557CBA071289B81F46A3AB7FF15A207960D83174DB95911DCEA1AF71F2063939D1E1AB0A9006BF623DA4AC74EBD66906D50BAA1F09D96203EC2872EB6FF36B5C8E8A3256FDACF66EB73361AFD4B4BBCF7110DD81A7075D78D6F1A4F92B4FFAAE9C32CEBC29679BB276447790C9F4A3172503475B241C5E02CC9C4DE0C44F802637829A61BEE95F587223A406B37EB60D7FDDB4B86EFBFD88159E28251F56BB37CB440F7ACC87F5324B5202B0029BEA90D6B1EA5FD25FB271A8D8133C95EEAE95BBAFDE9F2EB4BD1A0C659CA2988359708ED9235DEBE98734C867E2D120DEB050D1F2A3FD2EE73649116218BFCA6A135EC3A62F8211C77372388820D4EBDD2B77608FBDED173FC49FDEAAC54E91E5CC0BC5D809A1CBB6572F2C1F2F81D78A270BEE14E6090005AA59B897100AE1F9BC36AE83D369AB66313850D3D8A99EC8A93E7315BC90CA19C502E69A2D982642D85C5C8F80854CB1D04B74A9FD4EA1E9D1FC43733B2FA5C0C4E8A093E97D228DD5F89EAD0DF4B44E5E6B4629043427537A87BF19003736260D26BB4ABF49D703AA372E997A7F82EF15526CE44AAC8AF9CC079E8B13CCE250BF5D081EFE74C212D9F84C6FFBF7353BB91947029AB9872A5243CE69E42EBA244840C2F593AFC47AF3DD28160DD5676081F3FB67958E0C5453685748DE3CD3D20F4EB48E50F62B917D6E1DAFB4F803D0D4FAD19B844498CA838846FB1320E4B2CB7A1E3961ACC126B0D0224EFA0F871C760371A1E0FAD6B90461A8FD3F32836BCA0EAFA91219154ECAA950DF2B895C263B27B0C0F8DC45C172B1EB6459586E2F8D3F0E17C176130E94033B43808E0B7E7DBD771732E96A6CAB939BF50B955FC44F27568A065CEAB2B0FE06CF4BA6C4E2ECDD097492724FAE6EA18209EDEB8AD419D3DF0757C493E3A6E2758C118A42D823D29A04E7A2A700DB1D71A3C86ACFBB95B917B7715E393C9E4FF8C0C9924E55E944B565819FF7080AAC7BD5F87890950C02B6ECAD7E3DDCE2AF9FB4DDCC101B16B934DE4917315EA1B4F8F6BDF01C8948109EBDE1EC8165DB27AB305B8599D0F7A29961AC85E0C6F330E02B8FD037CB33A1361BE467E7C028778B8B373CAB5D9C8E0C2D55ABCCF6B39C92CCB3AE854317A9E8E91057D68087CA7D3B68F2D62353E923B87506F59C412E8CB90EACC7F6B9A3D1A1CC8D13ED4A5B35B7D6C2A4DC7FD630194119E61439A33FDF0B196FAAEEFA671AA935653181711E21A6A3B6AF02B809CF4E445CF9E5C8F9009066219E0CA4CD808669ED204BB3D1C7F69BF95400431535A0DA03FAD81253FA9B24FAD1C6FB553A8781A2C01F42846B9B25897EBD90870DA0068CDC86B0A56CE04498A6D4A3AA4C00AAD5A4FAD8A2CA3C50632DF3B43168A1A5FD6367208D751EFF65D5FA552AF4E5171BA74B1F83945F28096E1C5E997993118AD44296E740083580360DF0ADED3AE265A269A76457B6FC0F7A677200E123D8DCBC4724481F63E6EB7C8FC375D9E726ED2313E82F9C24C79F9901FC4FA87E366C67CF7CC0C1C058E37F12DFDEFBA637046EA26D86CBA5FA7B0A31DBAA3FBBE71EFD20F14AAC9CC24854BA24AA1F3BFDE1B4D9793CFAEA5D0B16AB624F0FE6A2E190EA517C5ADF6F61206E6170ECA282471AD375D0695F986D2C923346C2CA3E9DD95DA2257227FD0CC0AFB29E8E94571A2906708D45CBFC61F7B050137AB738259C34478C733E54B9AD2C6FD0B4E8A84B19EEBB8C22C4BA69AD028B1E06FAF8454AC0D20AFC3683F20B798223DDFF36606DA5CB70F82C7C8615515E982E1375DBA9B69334EA175F82F5DFB6F3F5E48BD5CB097A6DD0B93E4D438D28085C4AA54EDC4D3B365AE1E486661091CF1080A1DC3B7BCC44A56461622BD489D8BC7BD386265876EA9A8D44810B39595DFA3B5368640976F813AB802E3502357954E9FD38F7A01AF24B4901EA68368EBCD72367F8909E52779D13733EB343D9FC6E87D7757C662D7B41094CD882BB81D850D4919F26AC15BAE31F29853B8EE18F035ADD3A78DF5218C7D7F21BCE4AB2A7AC948E9828FAB018AA8D3221391ADC9A11C846ACA90F755391F8BF64370DE4355244DBB9B2B25135C75782F8106BA0FD0A1E5369D0CF473794257D4A5C2C31E65590CAC03F1501CC0F333C0D07358E08CC6C26477CD83AD3B3850447CDE75A9CE082E414AB1970CAC756F85DE6C4FF9B3EF977A7FAD9598F492B2CE4F7A4381EE6C090282BAFACCBC2D1C3EF987C0BD3E5900330F384E6C79A63628E8AE0424C605ED96A623080D6669483C77C04622DA1B86BFE2AAEA01F63F67E6868B4B1296B7A619050CA400B025BE282D415EFF74097C2B5933ABD9D0CCA6DAC48D2A0DE10A0A73F0885A978C5D1ECF61BB4132B8BD836B6063CD8362ECF2F078A50540EF38D7773F821D0947AF56A457349E59996DF23ADA9638108F297AC2F3D4E5E6ACB13B5BC0DC14CAC6BF06449A265F8681ACCFDD8C117F22A33A59CF29B4E746522EF91CC31A8B14BEBB980951AAF7B5CDF6B991D40486E9CB98F84FE7233518DED040561737C35E14ED5A7820243A3E828C6656DADCFCEEA3B96CCB0F4C791BED1269C6297CC6FD334102A37577C960E97C5AEC11E5B2C5772EACF3782D1F3EBBA987668D822406D9D22FA542918E76BA5D7FDB471077C924D0830F56D9A0A777B8FBA8E273EA670AAE201D7BC2285C78A7DD8AB1620F3488620C95F09316FA13AD0306A47740D25A9BF457A48DA5B504ADBD4C8EDE1396ABA8D8C915E3A55723BD64027EFB6B81787099F06E25AAA1A034F4F0535B6378A205C238DA6CBAC1AC7A672AE2570F37337A0FC8036A4D21F05D00CDE03E5758F57895939A4B7FF96FDA5B2A2B339BA109D0BB44F23E0A786A8664486C5FC5FC159BB988683DDF03879FEBD137AE92802CFFEE0262382350D9A745CA7C56E607D3980948AAB2AE8CDF0B560DD2E8B24DB149FCB63869710FFF439B9827B0D2D3A3D5B41C5F2ACF9B3437FCFD162FFCD26CD6FC6C0ED7EE53D27C61664AABE706E49D8D6DF790B5D43E9080AC62ED1025BFC5F205CE1FF6513F57D491C6AD0407F55C20B00F130DBDF49709785DBF1EFDE8B68B8340662048391E8C9D9A0244B62564481DE0E55FBD863076C051DB3D7D9C80560D8AFABF6E539A07A0D524F2E85F4130EDCB91F98EE4D286C38AE7DB6AC285A0CDF3C242F8A135CDA62DDF3FA2E5EA7BE1892FE9A0573C438B130966CE9B9EA94BBF73DE63760A45DA17FE69B913D736594EBA6ECE11259749E36D00A1429D6E09FAD4FB4DD3C5D1969013FF128CA3F235FEA0F43FCC8FBF1A7F48AD7C606A2A147D49BC1D8888F97DB44960C80F32B46024E05F4D346CCDDE189058F9F167E8EEDA366804DF647965C5535E24F1DA228A6D51CB73BF2D6BEC546A3C0B58EC2D5B9EAA034168485D144B8BAC206648EBBE89A235E8EAAB34DC0907896FD6A9D7469680FDCFAB4BF00840D58D3DDF91CD7C10A4183D097EAAED94D693B6911AAC624BE14863C23F0BCAD72FD3869AC4E14DDABC3ABBCAD1D7EEE9DB9E383C6DCD1FD0A2EEB4DAB2FEB2959C879AF1570271222DD74F57A9494895E01EBC38D557D7C9B67F485D5F4125ACF9A1ECDD9E22BFF830DD869AB3064609953A9665A33FC53C37ECA61B1B72364C80207DB9245FA75BBD460890CFAF3452850B61528B23276F6258AE93C641A1B" +}, +{ + "seed": "45CCECBAFEAC42F2D9166A879175A6D6263C3F7F9B5F39F27A1578C859CECF89", + "pk": "90393A79C0426134DF89DA80C733C58FA4FB87CA9CD0789211DE1E664F31BA756809063B7ED14F8401B21255D6A7B6872DD473407966AF226EFB110054B3EC01F7DCEEA3DAF2E71CDA93F08E6BEF1729455A1943A85360E3641502C97168F621304573F7E87333E7BDEFB3426C4205DF894D2E57F9FE7CCDBFEC5F34E18B7A12E8D3F5B0634780E06E9F60266C680C658F5A4D36AA27AF28438B53D15F277BACC9C8086EDCE8C30712C33D9E1D0226F7B618EC50DEC58DC44C6C1D58B95761666BF8D3CEA00CB4F0FB89866B244AF1C442FBF74872AAADBCAA326929D26CC57BDAFDD8E096ED1683D196323C38CB8A778C10E786FBFD42FFF507527EAAE2C4E002485C00F9CF1C564D11E6D703CC7ABC9FDE9B356A78EA11AE47FFCE443739CD396708F2E356265E9937EA88CCC72D11B5B163CC8376D3D9CB276185C2E54995686B858FE51C1F77D4F19BC7B6CD6748840632B5D402F2B483FFBC38A2E13623128018E6EE4C69C8104F24E2E0328AE686E1CC16BE4086F8E5BA323D242693E4D6BC86BE3E70F25D54D1DEC44400C181F6796D6A6B373ED37E684FA97B59908A4D4DCE9FCF77DE11F13A674B38C9757B458F43A69CBAD899EC4BA0C25281FFD1CB07497BA154AF58B8A8FA6F63DEFC4B8CB3980158A108E744A93109C6E54F69B38BCD851BEFDD4D3DE6B3EF1FBCE494F6FFDB5752608099DBFC9C17B09BC7443D15ED8750E3BEC0080D8ED4CCFA609D61CFC85717AF1C117FC4C0A6899DB99B5BD5293F6AB51D15A0323EE6049F21D4EE8B601B3D28A95F4E3A42E868480219795B11B7C3054F16E3C7F7457817791BD9AB310E6FA876E747BA3F6AF9E80AD06014A6D2F6B8D4529A0633B4D4C2C8664FB7A8F873DBD6B49D481D813B71D6FF5ACEAF851DBBF0E7BBEB23C276A58BB56826FAB8A74C3F7CC37DA538C5E698624C15A5E4CFB27CC3B57258CC86A5D54FE6903CE22178BF84A005A9B36AC5CF79AE5020E3D5A7E509A2B733B859FC21425746C39A36F696B752D7B7D65B32392E5B2C9636B2C2FA8C1D01E75278F687F122C294D9052A1C7F35AFE484AD5DC503B71F247B819EE60957770244D1E3654C600C79EC7CA4DA2A8D01469DE4822FDB1192A354D093782ED30D54004E624B51109B575090408177C1711AC17E779AABD1878FF6AB812BA7B616192A76FE6E310E3714643202753C780B1F83FEE484E8FFF7C8ED7CD6AA424C8C8ECEF1B1149CE636A13E9C2CDF78DCA062BB11AE3559FD627C5C78DB450D62E1C990560AC5A699985A9F0BCBF47328B68463FE60C32F1B5FC613F2E964DC1C803C1B057659F62F7A1081DF280BFB4CB7C15E2E5FE51EF46777DF704D619C01838A45A0B3A87905FBB909054A86390BA48578E42A49FDB247EBB239691FCDDD1A517B932C43C80785986CEEA1254FFC3782E9CBF427C1371858A7DD5A181398746B924FE26D85587BB2A9F6AA4485CFF37319B53D87AE34775FD2A9E3C2144870BC6DA316757A7B91B9750CF6FD370CD01F21681913117A04A7984A0A2699F586BA2D14909EA7D65EB3B2FCE05B5D53A482FCED56CBEBC3C967D88A9C9364EE93A9719E78F941DA9C91CE2B53BF861D1BF75BA002D28D7DA218AEF50D6E457A8C366A301275E5A4D8059977233417E1BD6A0921FED5DEB24417F1CD384AF00B3AAB654C61D353B4F01AACD13F47AC18164894649E261742B71F6D8222F24E7CECBCDA74B6A0E38F85BA6CA8305BCF27331295D27A4C6A005EAA38C23D29370AA37C053D71D03B58F7D7DD73AB04E19B6D0EB217C066CB675CAC07EBBAC2C3736E1FB379E5EB175C9361AD9478ADF2D5EC5C92026FA31B00540DA61DCF8C5283FE58704BA7C3D4D60F055C155A1A82C6FAE19AD4E95738B461A6D11A49D21E94A101AA40F8D4D90583EC98D2B41DAF1AD18BD3A6E41514E313CA810B8523A256E59817665A0C489D1555D382A2E5BA182802759DF12A56DB7B9451479E5A197D7CD7F61F5AF735622B4A7A3A633B16700B97208FAC2CE6EC8156500D40B28631F77621C00EA6DDA7580E4CE8E0E36D581AFCA211B369ACCA07C814C32D89054C70853189AEF7EB9AEC25F5928C70EB0FB4B7266EF39847C13CEC1615615AB6D4333A8C0274BE5B517528E68AA31F7AC2A8C312FD8A97CD52A01428AEF3C871838641164E5BBB83F9A7DB2A93B4CBB20C0E8C79291EC7A443463CD288DBDB559292FCCDA4C8CB21465EB50D1708999876D03F10368DC38EAEE4B3D544D905AC614EB7395C05DF986284BEBEF6106AE92A0969B49B645F6D859E0C22BAB4F0418D4481EF5FD272D700077C029B22DF3A2656883EB8321D3FA8EF586EF5A4C7553B990CE2BE6E8085776F87132AF4A2837A467CBF0FD52B726EDD8EB3CD3732F0A5478071FC98985375CC392B9007B88EF91D0EEE47D958ECDDBD3EE6D247335F651DB7052B06089ABDF1C7C53C467865DC009EA908CDFA799F8B6FC90CA6FBB7C57CD71DAABB94BB896AC501597298DD91E6DE37123819BF60F51704BAD0E53EE91EE8605502DCBCE921666D349029AEE37E4A351EDECA78D62F2C9F24720C2EF3B6CCD7A71EDCA01CCC0499A1BE59B69895DB80CC97CCC7E18D5534858EB33F6C9AF4E097FBDFC2D1CB8A8594508FB2F4CE77C0F7659166DBED42C4EA1C509BD565FE73D480C107AA937DA52EFF47632EA8CF47B8010DE6CADE97619A4B4E9DABA5D58AA126000BDA1CF9D201F6DCC49FB9EBC480EDAE5A9E18FD6375438D0AB21B90BCB8B37F4315BCFA34077BDE114447224D23C8D38BE4FC49AD43D9F4A8780198A1C39F767E199A7A6D808761CAA04274BDDB3CED0C56994AB555886F8B04E7A86D8E0329EFE153C2467C86D8C1AF6A8B968517FA59A197F840F642F94E282CD29ADEFC892710E23A26342DA5671FE3186D6E2A23A08BD7FC8207C490544D3ABF54B28B828D17B587DADB2F184AF2DFECA9BF5938ED222B48A44F0D22E8BFB3CC790FF04739AC85F830F9DCB538848B98A272682DD7B843C732380CD02CE32819DFD9C1499D7504E84E96F18EE41F41BD15CAF1D43F34FCEA37D1D801F4C9FD07C45FF9002ABF824B2C3C1AA33839304CBCBF2DC972186D9DE1D2AE73FDFBC0343379473632D3EB29DA537A918027A340CC7EE214B60FEBC384183FD988F2A2ABD79F01AE72898DCD3E43F7BD4656FCBD0E37FB8E055C3C481E666AC0D6E604E985564C79457195F3D12480D7F0AAF89DD4CF0A1922B4716F044AADFC79D44441AC0D23EB6B576EAF5AECC6478AD82B3E05398A06B4222F5416E153766EEBAD5013F54188823CCA0CDB128ECC2BBCD982856FF80C81BD0E2D980B57A7CDF5E3E42B713D5A6ABC45C9E24DE97B65015D1803832C412E3250B1BB9D581D19C8D3E42C992AF8AAC4CC48C7951048B701C815C78F56C33DC8A52D11F6D66642C9E29EADF97217606F3CA209F9C9550EB5F0C81276E455DE699D7EEE328089B7C2394A3F014394FBA7C9A02DF915921D33264A2F0C436DDDA7D84499B2871B53C653098B64FE8C4AF9602ECCF194A0D125C6DB6B6F171E2100DADB638EE2DE4233F56BB9BA88537CDD4E015D9DBEB2BB1B30D69912517A61C817165B8EDC34B5F03F3C9CF03EC6F4EFE0BC2B73788202675144D4D97EA292", + "sk": "90393A79C0426134DF89DA80C733C58FA4FB87CA9CD0789211DE1E664F31BA75B72D6E6F95CD49032D373F9BECA5810CAFA20CB56FC17B18BA507904403D2CF5CFAC3C3FD6A484D144B1F5DECB41B23AAF9744D52FCD9F8E51AD2CE89629609168C1376CCBFEB0EF1A9489F451A239EFB729A02244C3D7C4EB0DA857CCC7BDE880348D0882618A0649A22249DA104622A401D41864E2B20C4C16204926244B202C9900426216461B9588D1B6049414110B80908A04422428420B4491804440DC4420C2462220B051E386450930428292018BC02C9C106824246844068A02B98D4CC684493070E3164A04312992B88C1C158E08C3489C308A9C1028C0B64508888C61802C0B93494B923044A489083022DB948D5A002924077209332922495094B86863482643C00D52240953006E1C329044842D9C10521985452044259AC40154422221384459922980002218270A200208D2C68C6008601B024C0C9329C1385110B429428441D8B26093A244E4420A18B78C8006888824820C1612094742D3A860C3180143B04DC9260618A30801982C19040C0B4964D2340819364A132961E3268C0CC3200AA01050445013046DCB4491DC42701398812421284190500A956D22808DC2120C0213904040020391889A82881006321BC168D8004E08C34509B4514CC411CCC0881C1944498651404211430004E3328612A069E41211D826115C1005443249C986010A258C98104E24A7250C09009B2211019080A30811C9C84C804600A014668A308C4C360AA1A28409A501402862202984C04851618409E1B8858B168012390E1A812CE02832193121440248541891A1025099244488942101A2255B286611108C843205913684008511A294690AB080DBC23193C24553A6899896299898091B381191A26408912D0B29009BB2509024095B3869E19400C40602DAC02CA2960DD3448048460C84A66121092181B631A4864C82326182B2100992849C101054482DDA964963A820C42424E23004A1328A5C124D8B0826DB126923904101828598068812077204B864D8002983940490B464CC086D1108440947705A32852221899498215B388C4420105A0482839025C9361100840CC1428E84C628E2808450404D08467009A200E0B66958806C248510042246001264A0320804A785A246608B260E5C1830E39631C1B2812082805C38602319289A146801A3019338091C0392C11011D9A601109020DB224491445080A22D248910C1B67018B08419B1299416899A828821354C13C93050448540982CA11029E1942D582288C932804338085904301A238418466844121123078C8440814AB2916232101C475219C48C11042E0425855B80291A1542C2866D410225903670C8264809252648426582C84113394A23258D620031E40208CA8805D048018A30910A3921DC426909116C0B0380210741DB286A118130DA12891A978C1326020C2171602292A1341211158480240C0938851B062E9C846D492408924291A4468C9C4851893806DCB6290A046012447158C668031040581466E1A87063840C08A381228925E00648A01641140912D3006DC116055B46801C450463424010004AD2262C0315729B424D48868019342E04198D98A26D18083193A64101304C01268D502822E1264D1A8771D1361203392A9C428DC2000D00A941E0140124A821111172C8040D8C96600A440884068218428EA42212628248109664E0382DCA1881A180641B429088122610438CC10681222762D3B02913086193B08D2016265880440318119A3012623830029065A182846012805388901C143203256984181222A98D03298C00246D0AA96D63800C0CA5311AC868CC18124A162A52264C000892C304420BA40812184403156ED1984113904CC2A8081C38800C826C58B04904312000B87103344649382C48C050CC440122949189B40C18326EA4306E422092198601924085D9944D94B2695C328959800008C18821B3649C421019448D1A0882D0344C40040AA00204A1840D983652D4004E4C228EE32620243089A3C4610A26320935810114281B45601845086142491CC748A0184D432285E2388499469204962991C62514992923A761601022E32489D2862921A805C004715A402D2044881B21610825710C464E604400A2184923476E19C80C0A449021300054C205042868CAB290CA00317DEB52658BE9EA23E8D1D8AE6C5AB563D01DA20C5577A3695168A3DBC27E610B3529921FF3EEB2A866379379BA3689271BBBB1261CAF2736BD9BAE1F12A5E9F344E853B71C6119628427B790C8C7A1113B896B75A9A7B539E92D8D29156DF366BEFE74DE978BE2670CB07EDBDB6BA156AF6C26C5CAD55A4B44B61517511FA3B74A42FCD70207E532C68C8124E0665CB221AC3EFF05213ADE3C37B8F5A59AD00C46A5E8B11614008FA57AACC54B07E886B7CE9A4813DF22B5C1C64BD933BB76A95ACCE5787DD24816BC7AE25764FA2C83144D6FB8585F5E8895E86EE5650031AB9674F65CC012CE26B950A221795DE8F46B5DC78B9D9CDB4472C257204F32379A823B00C20F92243962FF94E5C4AEC8ED84D442F1F23ACE5D5C5850D0ACFCF7B1F56AF108E6483DCD1334338C5514D2808FF1BC34204C1740FA434BA8A4EE20C2D2A27589FBBF68D889A616FD6DA0C32FA36D666FD79E426BC54E1BDF06FA0470DEFFC93D75973D6A925FA4E5002AB614FFE1E9D5110A2DC3EA5E6096CFF0D46CB5B3B444CF67D3213BF7A139C41F70DFCB57E3490B84CFC51FEE7132FC86C3C44C193AA9ACA24A96A860D5D273DB96F35DB99491CD23227BB51105B3672BA3044457642CF680BAEE402784D2A73682BC28239BFDA08B24E4B542D5B5931F4B8CF4CA0A15A3F4012D9C0BD5FBD893543A4271DFE87E77C706186645783DC23A5BA180559C66DCD151F518B05A98EF3C64804869A46CBF41702A3E403C94B948D2E41510871FE7A159290BA88692473223266D462856CBC9280B12777CE80C8013655F6760F5715865986C688A336EFCB92E20D40F7BAC3BAEAE5DBD417627E3E2EB7D0D8E7D413BF703BC30D4E3D594C6FAB695F93B2CFECF0EFFE92D646083B6BD124141CDE5236E89579E8C76BBDF9681D80D19061147432075B4C755E1102BBD53A2E9E2136C2B02BFBA33F26CE1D39A3385BAAD5A5F8AD0F9647DC9B2E78434AE8663C7E9E14797472B4A646C8FF18470272BA12E7FEA3AD96E4E1F486569F26C60FDF7C2B4D3AA0756381AC8346636021322184D6B0B2DF793917041D152C025317A6E52134C955E21B623FC15AE57BB77B5A1824448AD18C30212390E68AF28E06A287141751C708F8F2CD6BD46FDB940EAE5F4376D8F946B9FBC8D31D1689C0EE560A8CCC84205173307B5EA39A502A9DBAA861B2CF90EFC3BEF7E3A74159ED7E5993CEC4F565626FB84059C358F2110AB4928454C4692195ACDA560267CB505B69E5F53844DCCEFA5D64CEDA4DCFC3F92A63D163184592641C2BE726FBB32E8754A83315039422681D2F902080D02EFB2D3D2A5A79822132126B1FC849641B6D2D0E56A42B32BE25C4F3CC52C7C17B18B039E51E889214A86FF898C94956327BC3A265FAAD1E1068C7C16A3C870FA03CF3FEDA3FDD9131DF340350F80E7F0CDF4B7210E971879E3E2928B57DCD40CFBFE85B147275EBD6924511EB293966BA6E42B67DD97F0F761E2C0F1B58081E0F040C5B832967B6508DB8B7786B238C598CABB104441B52D270F1F5FF333C3441337E925F259F2347A53D50CEC83065760A4E5AE4DAB5AC16A402D80C8E429FF2A90F7B5D3DA698D82DE8BD76616345B53967FFA2BC2882E4EE25C881382A4D619614F6870532EEDDB8FEFCA9A19FC809F5C6758AF8902D1E60092637AF30237A66C92FD30627AA51AFDE86B581E14D86E79B50162B7443AAEF8E4A2B3872E26FF579B09740E25CA0D674B229D96A8EF0A3FB87E8CD75AEF7706750A67C6F5A7639CDE9178CF37885FE9774191CE41A22F57660D335BA8D1AD5928103827C7FDB74655B0B7B3D3CC859A26FFF60AF0DB79F3EAE481A0472E803D59EBF3BA2C85A5B995C2CE3F0C04A7E2676A7C01C10EA1BA0A351383FDAFACD11F3F5403831704196974A4643AA6B0B57DF54B8ECCD1B1814BE540A063C7187B573D0DD528B6596224D0A9BCF5701EB056A345112A7C393A797D1C1590280EE7C6764258C4B151559FD0719094AE037C4B62350D949FDF23B7B294990033EB17C9F70E0FB465DD2F78279B7C1C313D3FCE7BBEA597CE11C5A47ADCF5865CBAD0400D0CCF8F7E0FF59F5389799D08FAE155083C2DEAE21EE6E5E72521A09C5BA7149F188F46E20ECBA23E982B7E0D28C92908B2213C6882DACC7F056D3C285FB8D6BF6EEE57AAC0E36F8EE51AF5653FBB1D358E06BD804115C0DFC572ACEE647B223A2FEED76BE581E439EDFBDF324356F7401841B3E1E192D7D3D8E19D83F757A20FA7DD4AFECD1867AF33340FA43537F7BC0F80235C1CF9A9837C94D7BBBC0E820AFFA4EA36BF685A82EEE6BCC662F94E5EFEA083802B9A24D3E9422DE0DCE4CCC298E4329B02A3956363C88E555816510E7B642A421AB4F768D347DBD05A5B1A903860078F105A7F0AD52DFE7FAB396FBFF271BCB5F7ECF387263CD0114299ECB39559066B78958B130CE25F1B9A75887F188C43E746FAF865B4DF3EBDA1304C70815AD16FE0DBC96F6BB61D659C7E80D7A46F6B1F070409829F69DEF6C1D87CAA1DC71273034D8C3C22A4694D2992D9D1B83A71DBAD8CF0A6C2B4ECA9DCD53A827A5D879B8279DC3A52E0B879293C07FF2E1DF21043E919E2449B58D75A3634E008F6D10624A3CF532F73BD41FA73571771A8278FAF79A85EFF2A2936D31BF878D304F1736F6851EE824B87B23FE9D2FAE453BFFC27757ECB335BFCB8B0B79C349DE2726AC7D3AD77C509A87BB58ED8D49CFDCF27CB80F2F9A6284BD43602568A095245C787F63BE998315F6FA0D2F7ED4F138F07706F4C9D41D9A5CBC83E649BD140BAAA55D15B87D40769A96C5E9BD9B21B786D37BB9A4D6897F80C8B89C3F3AB69D419C7DE651643CA76AD5342FED2864F3DCDAEDD6374DB3E8D044E10FF48BFEA1D5247D2E1FC075255901710801EA98404B2E0A009EB8639D1D2BF09FAC2E7163CDDBBA6C277380E786C076B762A3DEDFAB38497248BE093FD03C1259C7B770CA5532B9F0A44B6AAD5176B8D0B04993B5B76699891ED7328D340D2EAA4659D0C4A3D90505836FE0C7B7D424D2037F04DA135B91C6291FEB6B4CC190D21465863223D9CDD4D11FD8CA128377399D093768FBEB45E3228167F457E28C88886D4A5DE85E0509C0E18DF91BD71051605A51C218DB2DDCF7616FE7E61B94137D59ED68414C3012C67E0007110DA0DB233DCC71336FBF40FE2A73DF2A51639EE5546BA7EFBC8242C3093A6B6D5D96194501B72FB66B2E47806F666B1F6CECD83B8C3ED04FE14A36F218CA8B67FE20FA0C113C33328FF34EB87403E705257281543797F2EE63C7E23985F5D1147302A4316A5337650ED4F5AD31552490E1EA77A361A0E4017C51297F0883DA971E34AA452D05A44D3AB141D652D25DF3711D40A61167D8034C40E638EBA994F62769FA890D38B624076AB1260E718CCF228A338D255D24890A5701D6A80F8F944AC6AB6289D1E7D10196A173CFEA4D4FB6ED1249C11B1E7E6FEAA15544350520858314D3E0341FCD1612D6388E0079B385B2ACDD20A227A18985C27061217E2CEBE13D70F849F2512EA1F71E987BC4040002A54021B311DBB4A0F326355933A8B51E43A1B51906AA48D02B379154A47B9081F5652F418D39F4C8D8E055CE0AA5A5FFC9F6B9217D4F11D96B3859A28CCB7A4A9A4AA5D84185130C56FEFD6CE70B8F28182ED42244F8DDDD036CA93E81B31C82FD8567B2B927BD1FFC413CA02A58133475025C0D5113DCE589A0C159B0CA4475011B45C849D4D62ED00F1F81FF207C04F9CA3B8EE0308A498DBC81215A819BED2049AF1915023E72256209C924D99486BE97F6070D11CEEBF425951AC1025A885D96719D92D821C451CAA37B8FC816FDF716214AF207839FD0386E332DEBA3A94D1C583805003729872B5A9E9F1E1129C26408484BA267B48AC341DA546512E790BE48C05450F7462518BE0EF47A8D876072D4235BD7B6A4CA27A4343E6F0CBE6D5A39C9F460E1AA92F8A7097B60AD4BAE9B98DFC435ADBA536DCC0D413109644DD9D9F4AAC0A64FF68E820C36B0D151C3E51D9D98BBEF1A5740699E508205530C49FF5AABB0E0A99B8DB59E036E251F1966F86751F5A8735BA1A796DB720989ACA697FD883377DB331BBAC2736DCADD0F582F5323E3634785D777E6D41D73810934B78039D60259FCCA4B51BA231B8DD07824D5B3964EBC618618492A3E97D060FA4E2564180A1A91975C35F82E251B39650983441C7EBB4EC326B0C2958BF1DEAB2EFF0C959B9963A4F54DF3879C0683DE30C36E86C910A60CA95908434A45B5F76C5DB263BF5DF46F6D408BCCEB3A9F402FA12DFA99D756749F8CA0EA717F0F9233BAA282077BF46E93C81F4F66CA456E7B40E671848B0FDD01DD3390648870FB0AD807023B70A4626EA005771DD1095E306CC3A133D6FF7D645D2E71771FDC98A65281F0ECAEC106B9E6CA4CA473958CD65CC3875759D0222634E341008556409F022D0842A99E556B818EB631B99890FF37047F2ED2D3FC2E07B5DC6B72DB6C2F4E19636AD4C81E857F22FE40383DEC6BBA6D9118B78BA911498427CA29EA4F3E14C6E41205F1A89364CA6BDD12BEE4EF87DD7CA83890223C034B082EB6B2CB91E5ED225F6AF0D75D6BDF3DE95B55FDF6F0242B140EF5D45194A8FA13813DFE7BDEF8208939C90F71D1D68C080221748A28E" +}, +{ + "seed": "4A74BED90EF52CF135555B622A50D1A4F5C53D97D3176A1B184CE55380DE6FDA", + "pk": "B98AA05F5BA470BE6BD49954D496A45AE4710FE024C61B16C8600672106310AF6125285BCED3A9A3EE9B63F6A6732A555ECFDAA74437C0FAED714CFBF9690AD19A5D9B9E51A87B897CB2CA597AC944B1BB3657FD93DD44224A276E14C32AE838EC55213490B2F9F53B7412107A1D05D6758D487FA15F6DBF7F549F8103349D89B5872520245520879B0717984ED29684D4DA55E84E7280C297B4C7F3DBB90A7FBE7316ED6B1E075490A227095C4D18F50063781BB8A123B6407D41DDD071EC1D18607E6B5D7913289289146566F94A7C0FED3EB2B712B8DEA3DCC4CA3BD088ECD2B78971D823D661D8A1102BC9AE5164A56543FD4E2EE9C2F1ACE76A2B7285E2F23C0E6E66E5EF400E5C2DE9A6C1FCF6E4D60C714F5AD92F28D2A3209D4685C14C83380E69DA9DDFF1892D2F9BB9C9E0EB98E8E7E3E33BBE3D8A7999DF481F4B7D4857A016048D7B7BE2D44FDDE58DF6139FC8A1D0349407853D45D18630A3C3F7033961C06E5A0DFE4C449ADD2D4F66BE3BB19F39120535C9761353C5F5E695001B081CA27E1A862415C19323060BD436863669F6C1C75AE0CF896DD76D3CA157C070BE86D5B80BCB3CE5023B810F69BA4E3D54EBF2E53B92741E0E1E3086958FA66172112635A60EF6734D8BFF84A2782333586D66429437622F5CE059B210256BA414A887EF5E90CCECE0D6E9E2B294ABE6EA63BD9C26D20E4AAC170E5594A2E83A96A24BAD2F69E706E15E7B1BEE6AC92C7CF1B9AF28BF06E1EDCC572740374F4DE8DE26C06DA968F0D79C4454B12D28F2109FACDF8E1E0F8802026AC78B599929040984297F41DDA28AEFF18C3DB837E01F3D12E3752427A9068812D75C2A97263146D60DCB8333BCE02552126D5BEAE37F50BAA8FB23DE4BAC3C7BAB3C21415C1EFFA6E62E9A3DBA18F8302939A02E82B8284D104367F02FD4F484F98A0C8A2CC95D108E9EDDBDAFBD53F5D7D65C6CCA72163EBE58EC15BBEE65B9B65E3A5D240898C866960DDFB7A381DE17FDDB9226129060B5951CC83430F806A960D14F5935FA4371959B04E77EC978B09D08449D6DC2C3FD8DA655F4709198BAC7F2F42C4CF6C8EFC6B8C4EE37ADBC51F56C36D719CECABD5C3A1D63D08E6EEC48EA920D5A3FF93C2C716A76E89A4EB7946D935D859DBC99CFBD4DD7E2A36E8624B83384F7707467E336C10CB05D407A2D97EAC3E1A632C7348E8DED1EFB9DF72B4697C44F10B11111728E4304BD417FC174E85A69E8A1800FDE4FDE40071E2E06F725F11FDA67D67E682DBC3EE5DC866A0F7553F9E386AB08D2C67CBD4A6F33183F7C6631EB9818CE4620CF08BA747C61082AC71D5F1D055D91BD0C2FA96707CAE162614688E37B40CC707FE6C9EEC8CC415DDEA6E68B6F49C137B6EEC2F51B4E9D0E6A2AB2B92F7530E146F8BDE6D4CB559AAE7F8FAE27468E04ECBE4F85ADE29CCF20FFDE24F04C4DDD8C2A1E164769AA0B5A6A98498266A1BEFAE8073EB9C4EBA183AA71D6C98AB4F9D74614D259853E029710C5BA64D74C866EAFAA2AEEE577BACEA272FB76C40741853FE0552A79C6191BC40CB6CCF914E0B85AF88DF9553EDF1DF6DF7EB72275DCE3A568C4EE85E9731E44F470F00B2B95630357011C5084381B1FA5D0A55EE8D4299D17394083BA42E33778274F171A3CBDF9E0537031A272F04B283BC8F1B99CE201D9AF085A2CADA6078C7DEB922CF313065BE6FB3ED204F603ADB18395292680ACB6492DDD602EAD772FA22250FCA54542E3D68ACB4263DE0D2D442359321C200B798505E809E6B219FB2698871AA2A698544BC1C79BD6E18F8A8AF0B64AE7196D5640D0A1ABAEDA9B00CDBAA4BA177BE7FF03B0719BD489AFDBCEDD091AB69AD1BB66EDDBE03AB71179AAC1B766F14EC1B7F27B4FE46F2273E4D5EAA63DC3B83427423CA032D2BE29F057A9FCBCE8A747E59D6A5E20982B91D63C85A460E82AD028D93DAAB42DE00DA48CC0D4BE3AE85602C6CEF78BE9C238C368438144691A40D6A5A4A6E1DD19931B4D21FB779A03E86792BC63451352604BC177A8BD0DF71404DE42F5E35E6FCF96503277D09A552ECCC611A2A053887475EAA290ACD2B1F84878651552A796491E0A6E5C8270049F45D3DB482D4ABE5F91D89D5E97D985EE27BACE55AD9FFFC4DB7696567E86E8BDD799C5ABEDA6705561320EBEE7D0D3FC4203E30376406EBBE0297FEDA3E1BBCA5CB6CE1D1021CAF67BB9EEA84DF563D82B012CBC8D24D1FBF9BA366DFC1758B98AF3A3F68D0C0BFEDF4E76EC3C8D1D56B94CEA7E24991A44D094CE30A4B724A29645046196DD122727C26C96920131CCAEC02D3B45E513DA8BBD993DE91CFC10EA98A3362123FCDFFE536179F7063CD83F42D7047228C0CFCDEE216CD560BC5913D734A10286E05BBEA15CB293956F72BBA3A268303B43B6ACF89C20695A4786B01A5B8392BB975A25A6BDEC91BAA13F812567184AC8F3C0B7057A6409C0350BA92D75AE3030E2324F2BD82F09B32B7A38EE611A7B583052CE2C967192D7980F8FF7C8D826CC004CCE8ACB1AADC7E141BD2095330B7CDCFE6E3B0A7ED0A66DA4B00592B3BBCEC6414E293587E970ED78986461958EFF17F33C5B0D7A87437CFFFFC0EAC405499F12F6F4C54642325EA2FAA4E1FDF03FC9C8F26496F003289E4ACB9770DB201C92E5E437E4C0255C302648C38175C553ADC0F77AD76379D046B11E839772095805C6948FB219B9C26EE0D70EFA301F8096DDCFDFD0651FDB69F55D75F2C236EE5EAACEB2E5AE020C41B51F6329094F7B5A42C41197A574E4656B7E0D7B7108E6B3EE10BF44AE7D27E846F14EED09EC3576226098E1F4CF4FD5101334731411A1E3F438C9EA9350318331F917E0276521AD2C584D4F9AE1378512068AF29F497E4EA609B1FE0506432BEE5DCE18F7E7B83D0E5A9127F6071AB16196973AFE681FF9311D23B1CEB000E3E74D7FC7AE3B9F849A1052A87D3B6B28873337EE3A2094D42A27509E206C5DA5DF4FABED451F444C6E9699C6D4381445423928589CE9380FA8BA0EA486A8C97C5112086A4F7E5A19988CD01DE1702CC0C23ABEDD443BFBFAE11BD6BDE59D81B7A5749F4D246C7690A2656198A3371096C0AD58BB9011E1DFBB234453507EA439C5E967999DAFB04D3F030FBAA6005600BF39316A356F2C2A1FCF3365E2CD543C6F79CAED18EB04FC3BF02D2A43E69ABB3D58305C430E8482DF659994DED02814DA9FA99633979F281E218386CA9647B633672CA3232766D671779991E43BA9E8841302BDD269AEE2A6D99D658EAD444F1AE5D0BCE4BF4EEE91E03F1C2E29AD5B9F859A36EAD0BB8CB4D01A49AF7AB54CC9941DE0FB5DFA1EBDEE2C1EDEA77CB83606D77560A41BCBE9C2D43D0282D850164C4B6F2AF3F9F9AFBD7B53805D7BFBD8FAF8331864F805BF7B1ECFB72EBEEED31FD1877DC4682314730F86671A39275BC094CAFF3E9CBE4661B7400F3090AB9B638A9FF77B9DC7A5E43F4D03F2C322DAE8F44CB5CDFE794F385DA446C62AD9CB0833A7878A89968C01F9E67B3914D543B65FEF59290D107B5EDF2BAC0E8635B0BAB6A9D3FDB9A267E8C4A735EB1EAD8328030A77B497EB19787034FA2FB26CC80C9BC6AD0E63A83156BE42BD0A658F693D4D1BF4F85A3EECB4843CC7D58FA3CFEFA7C8DE", + "sk": "B98AA05F5BA470BE6BD49954D496A45AE4710FE024C61B16C8600672106310AF0DEA5466C45F3BB6D76E10FDE27C71282CC6E74D56AFA21CDB31A104662DA91A615553612DB8AD8F6D8CF8DC8246BD5970A2E14DA5EFBCD145FA638CA1945F5657B4CBFA716DA133C1D582C9562302A69C19C0DDF2925111FDEB189762B5259590B82141362452462ED9448821203110C0914C3632609010CA408210372260C209D822488C2042A13031E410684A460923C10CC0346590346218334D103462C8384C840272C832721C2372C0C4289B109298449019A631D146840BA9651AB284C14466C946069BB869E406445434106420658BA220A00081D418901886448AB82C40382903C5216334858C848848168E188451C1000159144551101040064520984544066019B98518292ACB185122089224C22D1CB16D44346EE1C66DC2022DDAB2080C894902374C11428042902C09314D0C212610930C8288041C3525E29084D1004890203221332218180058128D1BA56D222106242106CB46608CA068D0902DC2486EDCA6305B10405298410C178CD1A20991284C0BC8691BC14800A4848222298246840C4952D1448008442644028990A64C0C096D9A0481224471DC807150164400420620070840464A22244C82845109258EE1880D54265223324050242A5A4621122940A3A249D8A44C13C44103232A59924D61206A23362812A6440495211210865420406418491032411C082C03051118498018A76C9B220D03230C242820C4A81048206520426000074A0A150C22B14509430DDB008C60367081884013110618820801174A1185448C2840E3443193B060DCB4904486658C9291E1862952100A0CC248021560E1348522C6914C184D642281E0006C11212109424003234451408102A44041288E60262A01022E50C460E3406C124042D2488C8A00888B182EE19820E3481158A6600B464850B045981291D0882C0A4668C3208AA1384514286C18486D0A090D0C2765DC322D14A51122A644194845A00085DC908DA4202E18B7501BB481DCB6414A2282119085DCA64940A884444422E4326940802503C1600A008A4BA205A2262E1440600248645340825184208A14020929080049268442320B3131C10652CA981090462018A8444C4280022552DC462009325182C41091064C502031594881022904C4884148241114B60C08C568E38885D1B829D9C8601146129A0806514280E018200B2424410821C316400AC3681B235084B4840B014123B468083722DC928108129288327123862C180986CC22059B1480A4A830014624DA30080B33044148221BA148A148111C12118A068482C268242410E03682032765928224C2164201B160019968990268A2C028D1488E13422E03085263188422263289C48CDC428A03033119416512A5910205840882848438601A010E22A4281B254142A09192866419384D99C06C8032020BB780521652609881DBA8311825010A858008860C012708041148034620028111944410894200A1202464A009E00424101330E2303092A8640A460513202604B6480A962842C40960308A8C382602A408D23020CA06861B420C51B8288B100D62A830A2280143C4289C842819038D5432442385500A10901105614448519832820AB42C10490E5B360413498ED3482C8024699A3831A34468D4300464C4088AC4609436641BA70454A005A1C264D9126A5382281C062C0C226D18C36054C271898210DB808489204024A48962C03199367200B97193068110A08008A4281AA1249186119B40909814920B8571044485120685628420A2209194964D90324511A80C11C02490926900A8442023610B85858BA6004C142A14476604032460B24558380D0AC91144C80410834522387201374012460E031720C148321044051B364C8AB40D59064C82042ADC424CD1324E18287023162E832246E1A0241A3632A1182E50168263C06953B2511838800A8545C21269E3847124154563322E91020DD10469CC180523218203042D041865D20492840851DB026918462E0AA48C0C100A5CC688003311020422D4004603104EA12828DB028614110114242500C951214232E2384C14214EA446024830108A024E9940250921912489659A400613822C40C2096148420BB524E4A468E4A42812C860D32629E2464E2336900397011B80500A0165D4004C79598BA1392FFDC71C568B23C0F83C7E8B9B0A0A1FDD95163EE61894F5A05160F60DD59B40B17610366DBA74DE90016F765146B645EB2066870201C7123382F81B63D9C0700AD3FE71C0C920A8BB05E1A518B64F2F14801839ACAEC7D93FEB0019DD04E20562228D27B2807DE75432BD152AB4A8BF948AEEDCACBF55DB2BD53712ED63F99ED7DFD3D964E73687598D3E8F3874FA2D96C4C78067F6561580B5C725165EA7C6639D1041AEE5DF55BA3F8A78644DE76FF75854B5B1A3D087BA2DAAB0473AD6B3470CE0A411E4D2D804DA6B3A1DE69A87709A8312D56D74F8ECB01300E87BE085DE012148CD4FAB16765D7597890C3418034F43FA86325E2B8A883E84A315C68F6A849B863B7DF98F12D2C1C3142A7D5E425B25CBB9D761536AB1F0B149609D00A676DA927B96FB535E7F4BAC62243E29F97451FD7B04DD77DF10205EADDA73759BE70C2BB6A77778BF87A498C19A90B984BD0BEF97BA41CC4B12B915EEBB0494639B778F6AFED1857ECDECC70744EBDBB713E27AA8E87C67A0C45335B9DD700CF964A0316BC86AC91136BEF4530502A514F5D09AA73B2D94401412AB868BFA9FC7DA00D0F14245D952EA61838A7E47FD508BACC077F33C5D63EE1EBAEF84F3DEA9B7178C658FD5D30836C6AFC26234D68902716325280ACDD60FE4CE7E2B0CFB7A977A446D33EDACB8D799FEE0B71F7AF5E857DAE2373E903FCF846CB701DEAFC0E2CADEB666C13B77FDAE6807741E8AA2525D84722D07371F5CBC62574479780DFAC890ADDB7992A6930164DE9ECD36A5324D10100CB949CC20AD8092BE87315F5ECD9F1FDB1510ED1E2D073EF11A46CE93BDA2EEECA21BF2E273D2DA6E0605B2B29226982E62559E41B97A79EC72E3F35C5F847D13969AFD932C9056FD9CD9D75FE2122AC2DFA155264B8351A53868E097DEEC787B7C9DA89ED0A5F7CFF484565347954885535BC5461DC99EF622A8E261FEEB199FC4DA9D5CACD40D10015F1121D41AE315FF43407991256A74AC34FD25AF729AEBA375FCE2B8C6D92DE71240469DAEBCB0F258AC84292A3C6A3746841C5D498C5C0D490A29D4C1A29AE7A58BF9EE38DD76F91DFB357F06D9E56ED9E6F489C3E18A10785349A92126C236F5795EC6D755F6F0B36AE0FBA1B9548219ED544DF5CFDE3094B222063E416C8EA42B1DF7A1747627AE479E026205FBA28247904FCEBF44D8C06D276C163368ED2A289DE6751E3868A8BADBE0A0ECC38A85148CB0D4085B14D8760C4F928DC5802D02D55681CAA1BD468404D925B6EEF482F760C5B46FCB8F01F5114766F591E813D69FE0D51F58950B84FC2BACF7CC12B07703DD927D322F62CE7A8D903B3EF1785895F9D8643CAEFDD7449CA5B3EBD05713A202B403BA684BB7E3AC3CCE1DF7CC50819E97467827DBADA606B284D9EF2075666EB6D5E4E0315E8FCA999A12B9F1168913D34EC21FF7CFE51D161A4803371BF3F22D1983091B29B4B25D5D57D4B0045E35259B4281798D365D82F678D8A2CB8B59FA0578D183C6EEEF5426B831B89560E6F580BC2535BD184F301965EC3180156388E4729AAB4219F4782C94627FFCDEDEDD99DEB0B2CEBC9183A1A9181552BCDE74879C22A74710DBEF84CA97E1E7AB3F55C107A869662C14549B411D2E3FC3801AD44A2D4C372BAEE122462E87A1AE73C2DCF94771619F1BE13609998B9DCFA4BE1A0B5A587EFAEF65343DA0E6F0C9AC6A92D5C07EFC32806816894540DA7B75AEC207E415F350BE6D9F9D33FEF566CDD6C3F79A9071DCC18FD5F7E75CC978AB838499A7E6DC3B774261A38C01713C167893AEED2CD2A35DAEA944F497BD35722953C8CD1C82C1687AAF59C8130BFE0B2D4E7F4975DB8C0F73B17A067E4D51AEFA87A3760F91D4B468A68D7FEC98A17D0CAA58C2B30FE28F7D3DE71ACCE60024C19A1D64E97519BF5ADB6D90143FD404DF6CCD0204D05FD8AD074BF4DC841CD9D9B9C02B59E273E8BF2BA451648AB8AAEDB8A4A9E5EE5B4027804169205085F59526019DC7F1D375D40AAB078C007D674E27079A3E41EFDE7FC9CCBE11E5BCC8A3F541E20F1B2C32C4344B4580D995FB46FF8EE92E552D706EFA3E39144E48625619F0A37C39510437A1397664899216472F49D11626DA0A8B9571E330BD55DD7DA37D44ABD03328E6DBC06A7B79AC2F6A70243013E83321D0FBA0428173508D1BDCF9D2303E46D507501121844314D1B33A899A85FC8DCD0E4DADF4ECEE61C3F3AE97A2BAD70DF14B5461B091D3847A63A9236CF0E0F8026ED02C45333B314C421A2ED66E1699D844B9682145AB4FFE0A2C7F49BDBC3116513900A665B230A0A39C42078F7932AE0BDA22B58AA96E27B7F5F608497823FB58319EF4B2ACF7E3676ACE2CD1D7A1D6C9DA161320AD8B2BA1507C3B19F226E7E8496817B3DD84953B6AD645161F6585E5F8B866B12AD6B60C25FE0E653BC5E5FC4F925286668373E5D22521CDB20FD6D76CAA1C52BF1590C55D7FC0D7AD3199238D8DE9FE93857779B3C719648F9A27FA461F61200A0796036B43AF9ACA5242DBD7858AF7394F09D3B2D71EC7174DA5AF7361876416E222527B09F723F5BA70AF96123853E6EE151511202B6DE6C88847478D059C5EDF6261C2A2689890DB128603F0CE1B1929A968AFC747F52F62B5A1DDBC458AA366871197A94BC84FD22E26506B94BCAF8E229960B4A058B90927AC0D749BDD733E6D37D1BB83FF1799588A9031995A03396883FBE7788549C8F9D3F92BC4A50881FE6345FDA1C71F281BD70BD6B12ECA40828C34283C34AC72EBFC77A496E214878F29BC314121C2005E42D5277DCFB69F35C6D3C1F7BA065CFB2A18B32C00042A5F9B8E997202C8B35669BBD0ACB761939FEED5D4D323DF7FB9545BFE5321E38FAEB18C0DD2ED061BAAA890C992F3D0CC505F656488C2DBD4933169B9B57924AA5C334B58E7AB232B556C58DEDE837685D394DC404337B693D8520D41C2F277717E38190A20DD13F520AB64965EFD8A10040855798E97B9CF0BAB8B93FCFE1AE5B22582CED7858AE9159863EFC6A868C9F4D828B3FB5BF1A581F2282609D2796E771EAF96F48A2E42DE7EE66EA7A19E19886768444A10541909E296D6A7F5D1F025205DAF70979BF58F5197DC4B9F2E1FAF62175F14828259FCC16DEF9536AB559DFD7E61A4411C0EE1BC926CF41433BA6C008FEFD258D9DF032C476C7BF4A739810FDAC69847DDDFACFB46D3478F9AB34D92B7B3EDB6C7F009F8B71E99EEE78723B89CEF33F6521CE6F48B87EA2CF147EFB309C2BE1072A0392798789EEDC1F4E4A176DD68047ADC0D162C3FF71513E7FD5B2E38218705F0F00C7CE2CFCFF2B7E6D4A2DBE506E5F935099DF85E5695F0377F32D1DE93247C6D4AAAFF294B34374D527D492B5D9A30328010232913AF86739E9314874F4BAF10EAD6D5972B7C3855800EF2F10EFF5E56E4F9200B0CD7048D5B8BB69E90C3890CBEBA8E1A3C1AF9A8307308A5A10F305024FD422751B09910266C9A0FB0D81913337C2DC465B602B66572AA82C9FFBDBF34244C2A0C6D5BA00D9C4355221E0D5203AA28E5B494434EF45759815168CCB81016735F0B94DC6D8FDFA434900DFB80A8C2AADEF9AA73D47FD68E8B90B01CF2C2FAC9FF5ECE3D9CA6C70CE3771FCEFBB0A337F09790181F2122E8C5FA5B4FBF3C3559007FF5690987485E10EBEF40F252C4D9857D6E0DB2547BF0406557FD917B58D4A71A1EA69417F5E328863775F2B8692B11B68157891F84E0445E16AB94CEF77276D48CEB70A1AC4AEF4C7098733470563F1A1039D49B2B9DFC18364ECBD665809BE39B11B9E12762195C11B738D1CB69F09BF48C6F703E76A1FCB0B11D99ED4E319007C1C66ABC7AC664C9BA3CA8D4C9A20CC53A0173B6C740A70630ECB972F8952B48BF199E132A7648A25E27C00D7B9220F961ABCFF6F3A77B68E503A1AFC043DED5AF9F19B3FC8177CFC28E31902BDA123D1EDE5C892738751145B4D94767A2181FE4DB7F24C86C13CAB82420CD08BB5BADE24D5278F80A4DD7807D8C50B8B1601DD384CA1F46895D55B69516EFFF67061837D33A27675AD7A50CB89064506841FEB35EB363192256784F21598B3D883646D22D6A95AC355C8397C97350011BBD81DCE7DCBF5FE5C3231597643E3FFEDC213AEEFBA6D11B525A7AD49896919EF497757457D19729F41B74ECFCCDFB8694C0000CCD5A91239A67984C73279CF9D82D220BCEFB796E9E0A5D6008F75E5D03EEBA99A6B935BE749C2EE00B84A01258AF84585989F80B1F10D99053CA685181EF33B879148E23ACAAF5C41644D3E964C0C429488112C2133BA871D9A57E330CC7FEEDC46EFBF7413C52651717253B48EE6D91D8F24888DDB3008FE90F38D66CE819BAF939768206B04CE53DF2E7895C8D391786762DEEA768A4FABD4B49CD2858E0E7BABEA35724056049DB8225EDDCDF51149AEBDB714ED8CAA43C3EFE989625F732267E8BA56C1B16EDE1F9763B1E33307E96C3D7642DC4F666077A634E15A1314582EA6DE272EB28EA6ABCA7B57E84CB7FE6CB11672E52B8EFC875C0BEBE2181D216E09F2F9487B0A9E6A2F1D0F9DACB5CC2E6C1E19009ECA080879D5A7864E472B34B686DB7340953B607947CCC5E97EC686B747A9D19A29C3CDE7FBE56B78CCE04FF027C97EC85208DC2AEF53BFCD4EDF3EE1067CE9AEDC8" +}, +{ + "seed": "779C11F3F4D148FC911E188946C09E67EAA04DF670B6E0B6A96B661FD84E8994", + "pk": "620362188E854286566CC1DA5EC6AEAD3E5DF99AD6983669FCA4AF7174832F57EE66EF9F649D16EE8747A2D91CF0C6ECBCD7CE3B1559F864189045E2F251064D890F431855DBED63AC0C74EFF29C88D8CCBF3E8AA3ED7A3FD574D5A0AD7B7C59769B0F67BE603EBF37342C7540AED84809F4792FA42C865ADCC4FC51349E8A5FE54681B3EE84B7BA7D29C1A5D16364C30E966CD307B2AF7B2CCF6E5CD817BE45E2AFEC0E6AAD11433B59EF2A1E292DEFF179255F784EF841F6AA6B69B733C1D1C79A33953AE6119D7F63C1AEDB95D7E359493FFF919EC41B76C615192EF1161C4C8D936F7269ADC4512FF0191FCC6B9ED142D70BD7B411D1401CE1D2CBA37CCFCB465166512FB5292F434E2846D9164C2E903036284D0C27345D4E220908A7980318204162F00AD9B9F3E32A2F679CD83A561732F7601CCECD030462888E13FDE4A6E4890F277F6F949A13592DAA87C9A411C222AFB38DD901B87D2FCABF9E21AC6182ADAB425685AA9728350F608D890A0137047311C5E81932D5925FA21C0701D4ED3156AF0C88341434010DAA0C544EB8151322044DDB2AFB31613E817583B3E68D6F7F97C63D6566A2C6BF7A9C55CED36903E9CF8087A2D43D495340A880F9C009FDBB66EB831154FCB39C81DBA120E0F97D312696493B0A61A495A77052EB20CFD65309E96E802318FE469E37DDC6B321D7613F60BFC6B7F668C6E13D0AF585B870D27480835AF9D70AFC0F1915431987130DEA79D1AD60DD1D7180CD7B42634847CF782C2C8E9C9069559C5B5BC6734078BD6485444657965C68D2B453039E7F928BECEC1852079917EE1B1B268ABBF29218A9035DF83CE5002CB2B7E0A63CEBD08F488B40C9013C0F1291E12F20747F326472A60F6494E7E1D8369A4B43C3C1F66816395205F1566593AA8491F3202E79CD633688F81D3EB2D299A97FC8F8C392B0D9493C2CB4A49B1453F4390089B08A9B13E45035BD7A2ABC486F7FAC3B66EF963FBCBB21F514B1AF3D239F4D8ED7978BC89C73377495B3EB21B374887E29C915B8E24F93536B194B5145691F55962993D4A4849D8D3102E18DFE4C14882408813B623461F8501B29901CE4457EE2E5809DAC8F44BD8AFB435017E9A9135479263D3F3175DFD8852CBDFD4CD5B83A752787E212AABB691880BB3549C9D67B0748111BE8E87DED3B77CEBEC42480FDE9C8EE9063A06AB2A221B9D750511C74F7C634A40D0EC5A8173DEED4BCD836F77C6D2A7C813032D26CAA346955C5885D1E867878CBF8C08BD20DF9B0A5ACEA83EE438A7869ED52C16F3157D7C8C74FD3B6587F220A0B4E03BBC497E9AF5E9EFFB76AC7726991DA18E8189B3692EA97120161E7F6F7367B565985CDD992E6F378901272FD74C516A4E6A416FA872CDF76F18FEA2E07A614B364BDDA76514F2C6087A5A2F066909365591ABAB3999A2CE216F54FB84EE5410C6E4A35B946B8A4714D052E036BF69D8B17B63E30E1F9CEBBA5A169DAB785CA0E5A5F3CD22EF42C78803F87AF3A8B3F94E86302FCD170AE49F7CF56C2EC86873038717D2762D12F15CBFFD37889FDA773D5929D2E0D9EBD5BBFC48FC18CAA1FBA3710416790FF52AEA2266AB40D451B419504B125656EB5E3873A424F5CD46A0A11933DA8D71256FA9C6B05C7B8C8B16D869F07553AF33495ABD2B6C752AAC5CD3C9367CEEFB9C2CCDD81F6E5D68A23213DDD8D63E21E2DA9FD77C621A500451C6E5467275B2F68D9EDDC54E50A85D2CC0D4EAE55FA61C7D2C76E0641B230EC4437AD5BE19D6C9D23C6C9F854225894EF6F8DB7D4F0EDE60D239873B85153C938A4A6E9D187027C46B7E0AF04BC0E5FC91A92DFFEDF4C898883C7C2D3E6CCD467EFB826CC5094D0145B436380302566CE1FD2AFEBFA76696F25A4E579DB4D1C78DBDF6333077D687D74034672045CD9F192375F75D3B09C117BCA028FC45875A9F00078E9CDC8C54FD5DE2260DA41F500E31559AE42286E7364993EABB5AEC1D95AA03ECFE51269303E08DE7FBA7AD0D22247AE591CC7F02D234B68E290E5347BCF5BFE705CAAADD17C46F3AEF8F7300B52EA533C833CE5F878135EE57EAE7092022B9F5E07B245C24936CFD7D0AE6DE720F050FD8BE70DD460C4605FD9EF7A13BFC39A20345986B1B902F8C769A303E40D386398809C1FD139FA70503BE765DC9DCA0F9A55CAEAA9F414BEFD2E431F016EFDE2B358DDBDB9F194D9D9E306750C3416136110221C2931DD42BB93746362934A180A2DF308C7D2A6E0FD575942DAD441B862DBC9510B6916AA3DA181CB649BDBD335E43B35947E63503E13C85F33A6303C081E072CBC6B94CF8A99D6CE500ECA92B6118AE6B1787D44A6D15BEC81D0443FF56A48CB99BBAE77771CA27446BD0E2386E0750E2B506A6036DB1EC3ACCD62BEBF489ABFA41B48D160850DBA0762DC59C50CB12E987AD0CAB87D98D14796A93EC2AB551988257493C2B4DD2F9EE2EEF9C379883A81941DB034979671E0643AC03D3E787B90780C80CE271D8846BAA0C74C62B9A66B9967111A9194168BBE31169D9143CDCD2101CA8CE136BD80920ABAE16E0E9FFCBFBF50BB8F797827F17C8EC861D4426CEB4BA499E19AD2979D62E57FF43FEDC52240DDA68A7DBF10DD2A561A5CA1930128609353BC556E9208FEBFA49C5522843B2C4CB45BCCA91543BFEDFB1B9122304D86126074E0E5CA4410A291A62594D6C963D84A526BF6BA283EC7B2F2CC84FD678F77BF6425C4C05A63F8C5E254262ED597ED4188608CC9B94560E708976A4C55D4B6C7FCD9D6C81126C1FF08EB87A0CEEF192CCCE37F828894C125AB9BE842EC70CBDCC032F020DB1E7A4F174807DC874100C4CACBF898825AEB954D0F9A41351B652BD3BB25A15E4FAA2A5ACBBF82A037D6AA3D841016E2DA7C4ADD3DC90020F644297209D7EB4C97DB0860ED5878DB8A54AFDFDAAB380D93174C09A5E6D1503E8253D10A4C3D10E1F9D0A161DBF9C17C11CE861549499ED93D3BC7680708062F64520F285B7FA460008BC25465666E1DA2C4BA092DFE329BE01D13E490F13D6B6D0373168BBB49A18E4C1E72EA64B6BCB79DD36F4BDF825F990CC4D4DD78051224945FBEB810C6526FEC4D3CD1D9DF883187ABF1523852C3FB9F9196A4C0A4D94B77F1C49EBFA35576D4E5FE3612ECA937F69122651024BEF58A8646716D83E5C0213B76657D72305BF58A312CA327B9C5E630B6602013D045EDD86E9D029BB35B03D96F89F30A10B32563CCFA19D691C9A9850899D923D527ACF2F5F4FA9349A23CC4AF3E3AB52501DF3591C193B7899169E495ED5E0A60F9E59BDF3CDBB2278351DBE8B9C511C67E2CA5FCADBE5F20148B32AF131E5D9EE2827206327E80AE9A873D9C618470231274357085A74FA9BBF966BFAED80FD230BE766705232BB099EA35D7CB619D2F5558F1B8FFDCE7BEBE733003BF055CE1AD5F4C6CD84C45F537CCFFCE2DEF26AED060F0F2B23E291E2F700BFB52061BAEE5045A6E71114D73084315CA5B848F6D9B38E30C854D0E6848601E166336F937E3B6DFB568B488B4C4A0CAFCCB27C56ED305E045B24BCC32309221B1FFA9FC70EB5280DE841B642B128118B93E90281C4A2287C4894C56131452EE812AA3EFBDE1EF3643A8706FE7364190FB2597A852F9A10E", + "sk": "620362188E854286566CC1DA5EC6AEAD3E5DF99AD6983669FCA4AF7174832F578BB2B26CD59B63A1775D194E504D4D1B294977AB824677238BBA02A1533E887B983852ABDB4444A3E036E00EF0F61EB834C9DBE6E824E4A96D0971E372230667D1AABF891050A9F30FB7AC5279E270A4BE0FA7EB6F2C357968524BCB3A4236B08196491C348D1A2709E1C04C0C2505E0960503A22C88004E80C685942429532048CAC424A32012589871A002861B27210BB42C09892110168E4B260A20362511462154880818204A08099042A064E4B84C1B864041340A22200E0CC34DA0C8511BA92D10294550A6858BB46921990404150520154A2137884CB8110A420203B1881BA69190B8819900655A822519A245A136201C36050C173104424C51144963844C24B30C1125000829688C302A48106CD1C86C0AB12D8C260C00B9482103611A818112474D1B33241440821C373184246EC48630C030321134895B468988A60523471012130AD20232133420CC9860DB3650E2C241D98284D8160103C18D0A9305224024D8322D19900C60428E83926419082600A34809086E540429222102C838009AC0500B1864DBB2700B36295B08620A246484060A203066D294411A490CDAB420A39000D226461C208513C88519C441CA486918B24412934C0CA08118972CD8388A1B421110C01149242D0817864C440222A70424264D89208151400A1113855C14910081652004311CC240C98264E4A42CD4488024A84C22126D61883042C648D94420118521A33286441688E2068A941008811025D0A07064A4858B26018A964D80B80CCA1250C1C280E0046ADB2452001448141064C498601A030581442D53822909B131524808C1C4405A9450DB266A01184551A08CD322521A46015B100E9142110C2485D0B68C82166C192149C0204A89408803413202A91089B621A43262449441242788C0384441C85141A62142B04562968914086D0B128E10086162A2640C433040208D1A150203B8200982694416889236711BA791DA086E14A08D02881101234E030262613084E1966018A3109C062188846DD024209A008684B68C5B224C90C80108008840142903B63019106001354A13886D10402A58A220A1C02C130122D8288A0396109832461CB808C9A00CD82640D188241882808AB470218251C8000E8B0485E2A22590A6694C384411914041246CD138904CA66C9892298034320C1284412850229541E2A829093111E2862011A0101998692414918A362ADA860D0B370A1A104AC310481C22295B48668C3021D390104AB82D0A2012003245913241DA4412CBA4301C062AC08691C1B410E408411090688BB6088B281120150ED09605DC120ED8062C64A881DAC0018030611BC88CC93070D3424524398ECB84301B252010865089C84C61A84DD2B26D08066E221425C1B2811C904019905101278523038813278651C26402094DE0B46CD334222413501B102844360E4CB8859148800B277049004AD1B4450A310A8A04311A487121860C90444888146C2492510232914B486D22091289C88D5C204CA4862D00932140A82C20162519088D10388458224EE4C869C8C29120A528D3247109234824B541E284609A208C8818621C122C1838601B310C21A224C2443109A7011B461223A26122B76021865022C50580122C0A16650138114A3472CB206502C924110132820046C90649E1B87149446583C60C20178EC9B845CB44014B802C0C31601049801A1460C0186684A42509162950A42C21214E03040ED340248B080D9B944804A68124094862300A1CC185123424C33804A30688E4964112A70901836411230DD2A800A33660DC082A1A21290B242D834268D9084E13B645CC88248128060CB72C10B9685C1821C200818BB009E096254BA05108C5814236600104041996311409124B148C1B85452200922128284CC04D5B2684E34030910421E0C46C622612C442065B9621E3202E033446DA246DA0B05181923121A70199342A8CB6411C2951A1B8094B162C01134CE4440998B260D298241A11511845621A26064C4840182511E4A06D09170C23806448084CD3224292140280A60541242890122603836548369240486514056893C8108BA6910A909001132082140A1A200DCAA201214772149668A1266003364C1B340213C32D988420A0A824A2C8451B014A5A1622D80204AB1CB8E3E604B577A19923EAF947A1C22E67A7819853ADDABD3BCB54881E30AFE6815B99D88335631B7BAB8CC301B3150BF509F4971976DB4011FDCAA8B597F01F430AEA64761C3CB0EB40A42DDC87700A9A09E0069B6D6521813AF0A753B3D7C213E270B518FCA4C264E1BCEB736723765A8E31055FABF358131BE0827E125766DE4710F315629D514678F425F6FA9FFD962AC6B11104A068B1B370C1A367C16733B7B44BCE22B58F10F103A9AB05401D7E34CC04ACF6A12563F273D03E9F994B4E692DFF11FA1CEC32B4798DB0EDC43BD389FA10BD580409AC1D1A7CFD1F377382C5AB8BE2D6BAFD61D9A0C8B726D30756E25960B78014E64CEA31C5D050F92EDB367B7D67C459BAB1178ED64F263184AEA6BD69B712C6C9C056250BCDD8EBEB3F87A51A6B68744D0FE4869CC1381BF3CAB5E772B21893F239C248D76C56D58EE3C10FC49B24234608BBF929A24B185F850EB9E2E83D31DD614B80A35300562B29EFFD92587CC5CD9C52DF658B16260491F99B2CE74D8F19930E00685FF4EFF28E86039827BDC6E22F92742CC6C4D38AB574C6AD4E46018AC99355C6027FA721EFAB7549FADCFEDB5FC7AE3D0A1B86E65A2863E72A414533CFAA47F2225BD2901D48FBEC15420D408DEA83CDA7748AD3669D60194774109A4094C206C0F259A9FC5CC399CA32DB346D0ECF3BD5572A66521564EBDC5406AF642C8F746659D2070D7D333135A915AC586A1E017B5015AB43BE34CB26E520E9E74D6CC8F1D4F28DE97A7E26AE1442DF637AB256A24648A48AA7A5C9376042AB53C3FE776DE659D86594A343C2FB7C5747AEFE7E1CB0257BED195252F1D99D3CD9C4C9908348B93F875CFC4FB28F865CA2AF8BC595E3F57FDFD1D3DD5055D148888EC7ECA58373D40D7531F621EDFD857776A370ACD540970B64BAF4F30E2CEA3CBCB058A525AED3B9177EEEE490F007A6DA0B977411FD4DE96A891EDDABFC7DDABBB32EEF587326DEA9DCEF5EF9B4878AD0B326C465CADC5D822F207B748879DEA3BE7E949721EDF58E301118BD1EF215C24729082B29537AD23A5FB8AF20AD8F44F7619D99D6FB97EBF6D859DF8A48F76190A71582E0F927BCF4126BA09A56D9869963704939174392D88498027813DBA518E3A2A9E0177EE919C65A0233D7D5EE910B883832253846E7324C1FA3EBD375F005F286FE024EEBE9FD6ED6D30AF0A12D12936839CB9C06A39A2C92B1E7368F042F136EEA4BC8DBE85C9174269F44CDCDD890775BC9060ADA08149B7BF7B908CCBB8C463D6B6010792662F9518B65C666C9BC10BCD7E2157BD7D1F79358F4AA3F680A1E5BF243463FEF1D8DCA0D2A2414BA77B83A0AF696C9614999A9CCEB11A816701248ACFB268816388BD9525F2EFB96B0FB39547CF773A2CEB8FFE43F3F5BC26C6AF86A43314C4BADFE000CCA62EFD2FF28EADDB6C351F81C9AE719B4798091C3DAD70E8CEFB6074694381399E39817FF8D6586BFBDCEC4FD0EE57D4CDD1886344CED1877CE042C29C8BC318F28C11A9F785567695B3511A43A3500A4BFB596C4ECF42EF5052E52731271BCBFC2BADA445F77E932BB438377075AFC2462B58DDD9AE5EECC3F1C5D40B3DA1E212AD06643D7F4348407ACEF56441A66E03AC1F2828AF1A33A632D313ABDD0A7023A692579DBD9F308F604756C902DC340969EB395ECDDCEBD2455422CB099BDADA927A32F47FB1C3CD15B05434EB069A944BDA9FCC7076CCA52D91C2B54B9C5B453D18B9319746CF263DF160A9C19DF0E9B4FFC9DA665351E13EEB1CC3F8E9AA1F7BEA9B660A4A2B3E12424EBC68DBBB9D258599AAA00CC307A798DDED3437D6E02534319B2A40BFF442DA21E3A348423C90AAAF605EA626582412D088129FEAB971A287BE84FCF238410194D980B6F1FCAF520775FC39A38DCF4AE42CBC22BAB92D071D5F95DD3FDC641A508497D2C85400420368FDE2AC466B949F4F83BF7C3F2F6B6928F0DAD2C646B14E1EFBFAC24FB12A566981DA4B61FB1A20C52CBF7DB65156A898E096256AD638E7BA4D5D8810556EBAD83212A0CCC2B6499F769E5725FE1A9843002BCB84136218DA86EEA319992C806AF2D434C9192D31DEBD9E3FB8BA5F0823BD7E6C162A76DF7DC9927F651BA5AE9A6A3171464949C286EC060662FC3E8243FE5E3FD679C9DA1F0C6D7DA8FB8284392C0D947DD9541A36655385DEB72B836482291AE46A0D2E0C4F072549602186FE67EFA0F8FDBC25ECA5FCE9ED067AF4A56C60B758D4252ECDF09A2A125DB91CB8B66E7F7C124BABAAD2718732B36BB3D58AAFD1A890B2834B864D864F1073903052EA8BA2B9F3BD43DA456831919AB474EEFD0198FEF6D156B81E780DA803E9DAE22DE8BDCEF44810CDC4B071922B3D6A994A4925D7B0883F8A3CFE36AADA3A42496BFC9B9B2FDFDA2CF081A4890FA1D2B694518A675FDB38197E0409798E0F4A1F677C51C8E443E8559B366FE6C52F2254047539157C3638B691C58AC057121DDEA73F4361FAC7C62DE745DF555F4F46C15DAC3F77B8BEF4DD51A6F845667BEFF02D8E80B8C1CC97BDCD870A640C81C02618B9D167C1C48F1D235B8B4CC6F851CDC4C786E2031BAB1189C498A3410BED4C18405ACD863B92E2462FA3B6D56CA4CE4CCBA3275CAED86DF80396D52A6784A14297AAE4A5A6BCF4F55B12D64E1129A3297ACAEDE6B8991045543255F7B71917A798E81822AFAF294DE2D7F31CA0DBC3664194B3EFE7AFE2F97F5CF63D2DC7D5974D6C7C3634947054C36423D6C720EB7D2BCDFB9B020694D133F8E1E8C5C7177BD235CCF8D9CCBD9D172B76CEE1682B548A438B3E3F82DB42018D5152E0C3064275ADF5E4B14949B8DA9762B87A8BE6F1542C6BD5300C940268DF6BAE1B5B0C780B87DF291EBB582CD76AF544C71E15B299745DE59AE228FFC4C4F00B0C56BD74DA6404BE10639369C778A2FCD5E908E9E6866DD7FCDC37DA28CDEE66777BA6CDAB1AD38DF12C5A0044308837106C3E96BFA336A2EA633C88D270BB1C0610BA11A742AEF1C8B4649A5A4EF83EF7341A4BE76240B099AEBECF601C021EFA19C34CDF55159E33D0252FBF657C680BB810B51AB191B83E6446A5CB4EDB960C931112A539A7D5F6E64ACB438D98C7C1EA1914A82272F617442B80E9B37B0769BF6D7603EB5864D01B8DB6A8CED4B5DFA0EEF5F76E994662D4654DE3434CDE020B9B2CDE38B289C36263452B8C87197EDA09E2D5CC7567EF7D89253153631F384A300944261300317226F4F1E3120F3D721AA8C1E7C023316EEF66BD3B565FF54253D098896DF69B224BB1F276EF5A518A83CB6AA341C23022B5EFEFA05F5378620D0F088DDAFB9686868904D83A219FB12E6DDD1F65283A653FB9F5EEF7BF9A7AC7E39671D129E70363962752CDEAA6D05370DB9C622C4F6E7B22F44E25251F2A739C1644F2A9B1AF280BF235C2B6894F0485893ECD449C41A1788096574F773671D72FA5DD3DAB0E61EFAD5F536642B892D506A8AAEFFACE924D5008E985B3A84A781110EECEC8EB950B1E6BC8FD77F7A41E244E9BF48DFFC86178BB3B3FF62056E3E8AFD168D2907AE21944D35DD6DEA1F6CADED78C3FB4326DA30D51891E1D8C6C8F1047FCB21BBD141AB5A010D1ED5D3F0BA21A7DD39B4098C2FDA2E00A1C2B5F2B04962458DB855A310382DD4FEC536F1651D1C8752C138108368914F78398C3D185A49CD741A495815DAD06F29CD650B22FBADA0687C47414E72DF4EF0958E56FEE546D02E9B86200035253C02E22E2FE581B22D9273DECB45A33297C77819801FE7F3CA86C00CBCB6D75E1D7C97A527B56F345E0B919DD4C60E3F27DE490DF7FEE4F1C7A5CDDFEBBE24C8FC94EC9DF0644C3CABD184C112192D8165405AF437459CCA354DEF38A4E3B7D32C1246FA2B3DDF544A38F7FEBB3E28F325F00E2214C3494A26560C2F3C6D259A55EDA0D3ED8DCAFAB71CC001C676EAE836637BFE635FF4E5089F3171BEA34C21714CC1F52E18AAFD5F1E5C624E4B395826FD27AA950485CC6A4CE05CAFD975B2BF28D19FFF3930C5BE6A3BFE6166F37B63FBDAC712CE89B8182AC33DACE19E1B3F5C406B2A16411405AA4065014F49452904B54FCF4DC1F9FDE55F6932D8C8C69745F7A93592372E85266E6CCA7D2C3D01F6171451D8F39174235BA81C999793B34580C7FBB7F65ADF8F925F1B6FD6B00BF67602246FDE6F56E00FA177FFBA87EC072ED48569DC2E891EEB9D83C4882D53168FB0EB46DE6B062F9A483E4D0D883CB396D1BB2A95CE845FD33BC0ADD48F5231D73F8217205D14ED7F56F91ABE9E955A0664B957E1522A98E8ABFFB21BF293BFC7BC798025D8B380B3196E394D952ABD9FBECEDF1B24D21CFD135F7EC4F94545E69A574F62CC39F722ABFC08B4794B8B58D4653C58F76700B8DC741A3C2B37775EF52916C1AB6081309E2786269A96D1DB34F6FB31F71E40451756005A494E9658E3324AB05B4D21E6C38DE8FE99B38F46D7F5B7D9F2696BB433053C0F0A3DDB2F8240A35D708C3AA813F9CF92C090BA34A4C3BC16F039479DDA7726989CEE74B0E318B2BE904874E99A186FC2C7D74B9F5B2813941EFFADE242B1AFDA573FA2BFAA4484BB8B76858576BBEE52E49283A21EDEB92CED51071BE899FA1FA9F8ECE8A9EC2074832EE0900C2C431C101986403188AE9578DB5B26426CF2D23BF451507B" +}, +{ + "seed": "A94A73CDD32CF203AC75E89A6BE1AA55AEE0F2E45C8923F6D4954C611ACEC3F5", + "pk": "7B27025581C883B14108CFBC024B80559ECF926FFDB3856CA0A0F42D28B4225DF7C1680CEF51A4E68B41F0ADA6AA79E229C0D8EFAD838209E2A39B824A6C19C180785B8B793952431A4BCC45C36B37A9A7AF8BB92D0994933A7F5D6E733EB1DA94DF2E33A6B03D8DB42DC83EC95603DD9BCEC090B170C410D06F8A7AF8EABA00CCCA7A042CAA7F7085380A402F72CB26657CB9C3CAF878699CE620719A5B0A0CCF78255E4BEB0A30BB82872F0AFFB5625E165FC9D7A88B67759CCB8A72B6546DDD1DADFFE168AD985773ACBACA465180A0EE002B49C507571990941F9F57E366F0B8D2C6E72A40F5C100A23D8D6D887216A5620AADA2B82A1FA996862C4FB7383AEC9D8BB8BE0905232E9BE89291341B7ACA12B9364DA8B8D5FB50DC937750BDB1581F8B83C3E19278A00620465FF893346B20EB0EC8F1CB335E65ED0E152B08F8AFB1790775E069B251B1E88C63A8979722CD50AA16B883AF0BBD8B361334D263BB0C5D9582273D79B3CCA93FF2022FE1CDACA9C6AAA2C6355730FBFD657B0E82DB02E50A5EB9D830FBB9F706D2B2061B4733025C7C94B1ED50655848F0F58EFB9DD023F8C871B26F2C3C098FED8D60BEC5995B87DAF867D5549F27D2C62EA13B894176B11FEE4A0BD96B5B18262496D7F0055F9F3551C5A91FD728B08ED5757B00504BB0C10D3C776835983B8F406F066863900D8001F6D37BA6626F95AA8874712ED06E22D2DC0354B395353789AD700F9ACE628DD2E53A7E98FF3ED8DB4B625AB45AE9AB07E827A524D8B458BDA8CD3004A5D56391050B2C8E22B2993CE57592A7FA9E93F891C3DC1EC6DA769548F03175B7ECF6E3D50EA48920645D9C766138643BB8C73B2399610727FBE42F02D43B397FA07CEA23C5CA1D8D81E6FBB64E5E69A6433F37C493599DC0C96B6AB82623710A5C90BEFB870888C2197286A5014A0B38343517769412930973DFED9A5975ECB36E3642392B423124CABD33425CAF4B2F4E8BA75956CD30B4DB8CF2F378B946DDF455471E55A86E1D5643298F963CC6E2352292D281405BFD188217F4D0974393921605D94D27BDBE78FF93CE3DC0C21B212E741AA540D3639E36DA03D2C3711F2735C439D0FC5B1EB3FC920387A043EAFF4FE1C632F27D6D0E62C1987CAA6DAF11F2197F31F67B8F0EF625C700562D711586AB764E7C600EA9F8C06397683493C0FBEAAC512E41B478A30532D8D16ED092AA928608449548980FBC9AA50AE734C0E2759D9183E762DDFDD249EE6E8B4E392836FD49BDD46908667E62B367E221FAFCB297692DED3545C3AD530B2F0D6345C1D4AA87460F9CF38E05EC751364B7AA21FEF507198234C2FA189D22E5F9397628EC7FB67714912657964E6249D3FDFC24F7E0D63E2D45B1663D7C23E5B08395540CA9CC0261126B03BEE0EAE396424D774D978048CEDCEED475DF2A5DA43586AD7F0935EFC144B23C429C7F01EDF72BF4E8D1E45D19BE12B999C7F980691E23D70A5A4A0F517B8B324B125CD0071D815129A4929738882B8B5813433FEF88C58F0AEFA1AB98C1C9A29E2FD2596C9F8D2C9C7C2EA83F0CEB1DB39F914E47CA6E6D56CBD5745CF478B9B66BA527D2E36AC5DA0DF93B19818917827CF4E92E300B4ADDE59A5601BEE7CA34A189D54898576D9235DB2D5C73A083C735E87C202F2F5B7BAE6B82AF1D41561398EE17F11BBB4DA28C944011573A4E6E43C16E9550F8EA2BA407C79AF3B0E4F115625B3D822A1730361E9323F8FBE76313BA4941BE9E937D9A193E5A3BC5F1A240C60651E30FA7E0A45E557D95CC4912A6707B557F5351B6366E0C114D3FFF7385C3E90015B55D3112D7525ABBF3D773B04ED3C48995439E3A15CEB7CE577AFFFD5857CEB6EED8FFA2AE9D957F902065647E85C9AD65F54D7D88C4D3BD6107FBA1FF01139F5990625582F92CAFDA90C258990E1F40B123B798DEE01CB5BDD8E74DB0C724C93E4E65E41972E13D0D358EEB86FFCE72FCC3FC93B699F9190E222FFDE951879E3AFF4EC95552054813E8328C28C40778A3BDE116EB931747E0FB0906E2C73F9C96FD963AD300C79FBB542CB31CD8B66C6E63BA290B075CBB6E1E4EBC5AD67CB74BB07F6BABE718F00F010E8BED75F9B98E75ACF081F5DE101D233B002D37A9730FB2FF808C24D7F25A97E4B2FC73E7874DDB2EA3B573A7F7561D7DDBF1F3184457D79E8F94655A90FCE94F661C4DB9D1F14B9FA336F4DF3129E3C76AA6BE419BBF15414870CDFB257A4E2D8233CF8921DD1F69BF6F0A40803CC6E679F0C9BDC4957AE758C8669AB33F2D80E661CB66E36A9AA294AE55A450078A2A5B0EB44C8E03420F241D377F32DD22A65C86191DA857972F68D70C46394500D23AE922D13B2F7B4BFEB5EE21FE28503848422E43F1610261F42FDEEED6F7D67D80754881D755FA81E83D503703259F6CDEA6E1DC5B2FD951702ABADB305A51CC37227038F71F853A53C180BBE28CCBFD5919161826C3DFA0556685B36D7BF451E6AEF92A15F1176C040EC22B469E11AE7E3A1F371C71F49B33A583B9B9082DED6B6CE1B9983B557A458CB9E5B81A7682CC19921E7F297DE94FB9A6CDCFA40A134A1B3E282C3FE9E78982A9006FF4D49964352519B782FDC0DCD4116B8EE67E024021B8C556E2727F25C74E37B92E9540D81F6243DE033D8DB8DFEB0561A7BE63485D05661EFBD17C5C222077FEA20801271164B2DA8943593A4B65D79145DA0A9FA18229564D9F331CACC42295B09FD366F378F48A248B90FD3AC940024705252416C6498527546280CBD6B29BF073E2F458F6A1A57953DCF815C8B2EFC9A34700C9D82BE140176008950E22D814A0576C7A23F4D1EC0CB7E32CDCED7DBEF19C167C7CFBAEBE341B3889A7E90BE6B39708D7EA31E7916829D90C6EE0522EA36D7F892C14E089062C9EA8AFC3361B965FCFC27DC8525BB96B7D51428FD8F493A0A0D8E2B30E6DDCBCCAC1E927E6CF939C1B913CAECD4048D9D21B067A100F0BBD5C0BEE8E08A5462AD325041DA1DB8A4B7D7B6943227D970D8EFEB9ED5DBCFF08F93E16AC81CB544ABE1E97D7DD3E61F4F2761BE9ECDA5E6FC10DD0A9C89E9CBBBD88B25A51BAE63ACE11BEAA575D4E1BE03E084581E880E082A62FC7D48A3569FC17DE7AC1271C3E624A00B3FE59A06803B2869EAF89076463063B56384E3676C8D998B8A337FEAB096479B3AB8455248599EBB7D7B4A48AAA941F42957ACAEC111F987A68EDFDC3018857BFDDF6259ACF4582227ED9385B4BF57A15CFD9FA6F2FECE6C2755353EF4380B59D6B04597EEF66C42B829429C00A4D9283EE0AEFDDFC53DBE21383C42008CDDA8615B0D70C35FF8EE905925E201E1F7A1C4ADC176A49FDD119832634DB677C9C389722EA64C290E6B6D34529E1CFAEBFF34BC7660C9B94A35A30BF7CDC52F05CAA78B6B7F2854BFB0988F5DF23BD9CC6EF86602A371525326631C54CF73A9FB78D750B223C8AEEE95B072B021D761082E7C14418163C80EFFE990F18A63C3FB6ED7116971A488BE3E3A2BD9B81A6F48F7D0E13E218B4FDD8B66FBDFCAF2AF84ABAAAF6764506243F83C3E0963A170BE980987F8CD15157453D856D3C200EC2E520959AD657BBEF60A1EBDFE7709269CC44546F39664C98299983BA3190DE946FED23EA32A5EC", + "sk": "7B27025581C883B14108CFBC024B80559ECF926FFDB3856CA0A0F42D28B4225D480D800452AD18AA0D1D9CFECD4042C822A6D44C7DBF8A48E407403131619B7C3D984C3FD15A93E61F09726EC8D3354B81BBEA86FF3F4487CCB772392210C6D501D69726A9EEE9D235BCCD637B449DB415B0CD254B61D9EC523C8C90D1CBFD6CD0382CC44246C3A40599A66512B82084A06D1CC01020206DC910640A400C00408D12A64C90C2450A964D0345709036001C36000AA34D2340291A17458A3049A0B000CC0045D4366D2399408CB0315BC84848B885C0A64043C245E0140C5832819B824C63405053462699A20C033648600086D2004E509810A1104EDB462A242749C908445C44011B9244E4383192C2281BA348A4C48150160A819264639491D3C285121212030226E314282122091A197199262911C64980027198480112968C2233010C19841390044A22911A8988183184D006521C348E1B36044316490285458C02121A446062020A1A97444B4212DBA20018040D01B18DCC1681A0142C0B4192224964190012A1B46009B70CC3120083B220A126521BB9114846864B80218B06655990109B02018B121008879188300A6122415A00085848515034640A99484C446CD828894C082DD4980D0B10514082010B2400A49681C9902481308C1B37528A3892A0048851B85112322CCA162A0B386121456D0BA8458936459000241C87299C804C833040914085638440E1128C1C07505C20649336240833710C1866C9082808268D13B3519A026DD29668C9B864E2A24C8C364D8B00850C1224C0324D1C25302445044C14824C463010100819226C530208000852C9840514404E5428811805011B865004197050A44093442E1AA48902B90901277053044202C2711A146A50A42553202489284100080990B650640490A2B081E0B60193822024B76D01944D80A85162382D000328C04671DC1064501831D9160D21066A19474622B46121B670DB806D9424600CB73044B0711946690BC324DC220548484483308E8BA2816192085A008C582632DB1482C02611122085DC400108108CE1921052325188445248A68C19444411A22D24A96D00B06009A98022B60C1C2405E4480E5AC44458200D832628D304211322608AB42C609800180446E1922920344621B36522884D9B046AD9106D920049CBC42DC4B8818A9650C4200619284142204424104A98164508B66501B6619C1629CBC82511B08C9A9068640446110291444091DAC06004B92082C62D48327162A641A3444120422D04420C8A9209E0A00C8A041152820823051118372C1C0609A23082228870A3C24C5C1651CC242D644246A198510A4586DBA008119485D1464851344C50B21123A34C4C122913480D09176103480E1B334952062880200049C281C1248624382A04414CA1B02400C3418208490230114A364290220852C285C430911C388A99C289214340A30029819425DCB28092A03091B821DB244C22A20811C449C1186C0B1090DB162508C64000C20CA0B48921B271200488E330318804064132090216899A08112349256290248C928DC1B630A29211213641643804143491088804E4A42D92C460CC126D409030820690838424C2406D90A00451B2010BB584DA02280C22045CC889D4309203B6910AB148DB340883280119C6104A824CCBA00C12280A89982C1229491427061927020A9661C3B82154462190180550866D63148620B80908070D52364A6428290A11010A9304230585A3088493386418344D1A464ED2006140028A21B79088320D1B2581224246E3C68DE00092034928A3362C603289C14821C406881388895BA24944024110954560404613128A81404AC2266D59425192A60C21144AA0364AC328660B838D5C98251B464A5B2242144224A2200858040211B32C981488A3404C41964C0014044C286623902441068C21156AA1B07019B38C5A242D98962DD90004D4462E1C1431C11021122609411602D30446212164038801CB88609BA849A0042299C26898B6491110721AA84514470580184E111725D490701C376A1B04510445840B1106248721222549C4C26CDBA465C048801213210A04860C396A00B885180932501604C008054C364821C4119A16640B10001A858C491205CCC64C4CB2091C037103A94DA0A66CD23086029128448644CC28209A28418B282601396967AC06D55A323D137EC2E28C52F87921D3A6471C639B5056B58AD10D8961F464CB2BDF687FFA2E57C9A5323D2AF8990FDEA1DBABC7D0AA56F1BD9904D707A86A9A92C93B081C7EF23EC6EE3723EA6A53D183B3DC49B36B965DB4D62D88D88AD2A3F7E5509D23B0389E86A4E1F4B970D0E04C0E997EBB3B708967FECD1AE6E0EF71555E4EF519613B00AB50F08F90D36FB3766FC166C948415EDE215C2E8E8D596B0F5FE6018ED5EFB2D9DB07A564B30A556859B5839F0EA495AC41D497FB4F25C0ED4D8B426A89E137E7B9256E5A87708070786A89885B9E029F2BCD382E2E319CFCFB08A78F2D3C6DF07BB586F5F2F925DB887C7C2529AB8EE9969D436557BB1489C41FB119CA34A15E77F89259EB7C7D3C0DC8764DF2FED95F40749A7EF900A33B214FD5A92F9A175AA263BD002D7144BE306E4548B05076CD73CF0C22713735A2FE9CDFE7FF48115CFB6C64D9CCDA0981EAEEDDDE51372C7D49D4E5FEF4C41749228591182FDD67F9F0A416B0E9CA2B7F44455330360F8881FBA353DCF3412E832FD094025314149144B1CA88EEE470CF3B66570B0D9785470521B707C8A61577717ADC490B5FB13537AD02588E56041CFA17E086EAB73BC7C36D8EF488FAF357C118AC99E0AAA862F33773F140643D7B1E92B8BC0900E8C1E28E03E810E8F3CDF47977A5C147C434EF371FE83A11556D7D3C24CE5D90370821176073F3EB25EA4205E96E698EEA65ABB0110CAE96DA29560C62E8CFE713AA5D7B7A98586246DCBAD86A420D1C28B97AE1E9C4D1E8C6439885AD906DE2474BDA0B629D01E12C4045D343521F983909871F90073B7E2146A3A86945BB83F6693BD0A38BA209BE3FB4B193CE4A5BBEDB38A5F3C7A21F259C594952F25BEEB1A992348A94A07B579A32D167CC4C4F788A74AE9214E6910FDDC79892C97FA6A00FEA091A463F13E45707C19DAC54C67EFDFF9DE2687DEBD02462308E50F1F3AF266FF82D279F8975DF99FADA5AEA5514243B942BFE05A7AAB1579B469CA92BD222EAA2B547B7099A0218F5F43FBB0D54B11D7E8B5373306B2FC6469F694F3EECA3912BAC0026A40F2A3D9A76D76A9F3B06380C687EBD7980F901D2F5CDAD534C0D2745231155D6D51E8AB7D822EB0AF875716A0C63DA747BAD741DF19474372D7239EE17AC7A5AE3C92B5EA98DE85508065DA483D4D4FDB90329124A2BD27D77F1FCA072A83C85D31C75ACA462F39A4B82B13D49963B518C843CE2B2EEF0AF96ED23898040C9FFB7273FE3A02C5858163700E1423BF5DFCF27F0FAE92081D2E6A642F49102E60FD45C5A2BE668868820DF66F6D3E5DA79B40EEE9F1F7959AE72364EF382901D8AFA5BEC757ED80522DE6CF70E0EA970C54D044F1B16495CDF6B38D70751ACE52F9976D6EA2E47AD672310B7B71A75C1C78546FDE138F4533D8DB9A7DBE2E08F7E745A52B3913F12359DE7F7E37A6172C97F612EC3C0FFA2BA55DF61EC06243BC499AC5C7F7CA63727705C43D356C79B67497646AA7C8672AD3CB8B241A16DE6FE53C6E723475DB2A5230EEC5C233DAE829811293D1820A0B827CCE1960DC978F72B2DE4B58802DD15F396555EE4CEDD9932CFDCEA3F113E86BAC39945E996830651595017B5069DB589013DAF4916498C98042D0B807B490BEF1783C4A5A4AB135EA2D2C0DADD7B6121785201004A38D94C73B3EBED2FB3F0A26BCFB33951F89C968521D58A307DC13CE40D1188ABB84C93942580BBD8D821748915257DE1D7381321E6BE8567F0AD583DB4FF40095D45F2F09C6FB0574C198E8DC6695AC75FC1D96102D43BCB32B8D95937B7A0EFFB573A00C26B68FC52A5958E0A00D23CBAC22352929BC5488A29D974743FBCE01C2EF7169B58D23C5ADBB8CCD424686BC1D42B653CE8F149C48455F97245FA41CC97FCB39D812FD61CEBAC99B8087CA86A99008B644F262517F42712D9DAB06B0EE8C069397A80AD678E72B7766C29A3407D2406F22DAC4CDD02F83ED60EA03AA6FF891F6F06514E2D321CA475EE4025FF331F6B12F09BEEF84AA9B1E5D822CD9501310B85588798296B14BBDBE2DD65140343D20C6F6B385922EC47EBD8293B41E0B22F08201B81AC4E05C7D1F09EB994B1EAFF70F731FE66A5A49BFC6F69A9B054BD7CB410B893894192EFE02E9D0CBCD75B751D95139B6754FB856AEFE7C65305D8277E986C89C90EEF6845416E8A6BB8DD5D2CAE4EB6DFE3FCA1A0143E0AA10E247DA7233905983094C4FA6E924452FF3D8C1C074EFA187597160C864F7366169A892CBA66215707AB59917C9B2395A052CFE64EF65BB10DF9E44B4E5994C46CB8453420E232FE7CBF1CC5CDEEBB6B7C56803AC8A97AE5B7C1EF5007A09ABCED41387EA53102C85B3421D5BBAD46FE31C8F8942877BDF3430A7B9A41FAD7ADA3B2071D4D0FF83E8FAC35C26A20ED01486C8F4EA46673FB9456EF5281689BBDEEEA2411AA12380033045831417F6DAE4DD21329D73F7330B13DC60A9B970E60D7673FC65C93664B0A625F93A8350DFFEED09C8E601335363000CF31E7F41953B696141B7EFC19C0BFE1BF0873CF394984CDA52535A1E544D5D814C0399199CBDC6F8033DE07A413100F3A76B0C45D9C972C0D554AC7C404BBDF94A85A40A3AFD60DC6DE689A3B23BFF358615E940C8D243077291968035A19C576F6B3EE2A6F615A97C2B54693A586594D218DB114D7CF90665283F67B01E12D61E516781C1930BB669B53CA20D248E84F23096684FBD9733B7C0CC48A9BFFA93B4393FF5D9D2B4CC7DAEE10D8D4101D73506A6538099537A58E0C08D94AE83749271B54D27C72C889FBE32126D6EF46BFE19DF20026E1B9757000059578D33ED7B5DEF0B95D193405843C91D417FC377DEED6A60BDFA2FC20CAC04B0FB1E3CA4794D36E56FE48B363CDF2D65C891BCF8087D511936E9255FB51E0CA64D4D034CDEFF97FE7C0D4E2DD4456435BE3B50834BB3D15EA0216CD4DF2C6032FB9A83E077C5F1C912B3F5363CE67DFB373D1821F4958B89C9B268EA05AFB3AC7E9E150C5B7F0CA030130A5F03C7BBB7FE10B03721F8688B4735255A7D72B8C8A90C25F2DB9158A18A01E13AC040458DC671EBC19EE75C6D5903BA569A0DF90B986799C546947E9B94648424B742389550CA2B2F803DFCBEEB664E3AA5523BE7E14147515CC1BBBC24610A7284A6128EAC0CBF1F4472A46E4ADD7D9F4A7CF7EEC0C03578AE620DBD121F774AD46F4B5DF2155CB4BDACB1BE64A674AA7F066308468800788E4D5F4E84AE1FE5784D92883D1EAE3E66E5297554DE94B3FCB6EA3C273FDFFF08D770048BBE5D4AE753468CE61F7ACF85450C7FA93C2F828F1A888BAAEA301F5A8D3BC84D5CB3122812304226FF83F1F358DE1F73F22C48B76EEBD4B01EC34B51FC09277A70AF10CB58BA9243A3EDB5946CFCAD46E2926C717EB13AED5B90DDFE0C3DE6BEBE9511E925FED1D38CAD55826E30CED1CFBB2A652043EAB1653FC1CDF32CF5FFA2F8A4CA591B3C70517530B08ED7D663EA064AD65EFDC9947291958D5C778C29E80CD3EDEC15EBAC272993014B00A20363720F0B4241EBEEE394C3F35FF5E9C7FEA8B004DC9E53E2207B526644873D3D88CB91FECECDE2CF5809F78AB54583FD62ADFFD83FC406E40F6047D8DE85AAC6743FE2F7461D52B88FC647FB1D82150256BBB32E9DE4FC271D98C1EB5E1E3E660234FF2C182C4FD2AA64325AB09DDD1035B055B5886BB953EAECBB75826543A911E1D2D9B1674F4286ED25A5BA05D27BD50DE219A0C6E029E4DBF691471571AD689284CF9DC1E2EA170326A1B949D73392FDE52D3D7D3CC56518F652CC93F75FA4CB4DFCD52CCAF7A64505D1D8D0E83593A2AB7F083CB09AD48257F21885A9FCD2719C95701583839D6765E6CEF7428F9A0362A6D77191F6921E1E09E69F7CB8AD9E277A31FAF37B21407DDEC4B0F67872D15353AB9466B1A927EA0DC814D4A3E0649BB0813CB817EB80F2D6EB85E49CC14F9AA8A37513DA248CDA02A0A77F340DE1B939798CDC6D7C7069EEE4E2A8A8120EB1EE55AD3823D3AEB93FE55BA2126DDABDDFCA8B6A6DFF07562080166D257BEFEDF864A917DC3A875BA2B673C0E4BB33122E28A03955337082CA6350165FC16F23B404C57B971737361D6D91AE847050A18D4E70E452C9ADBD816426101A6D3DFB1EB8CF2105869B42F5718D1B8F27CDF7B42007D4942BDBAB9EBF1DFF9D92456F610F0F18A43823B2481EA8313DAC3703F342C3CC17B68AE8719B8DFD80FC544522D973EDD78D5E2EB4589665E8863103EBC554446F5054F634B01DB6C735103BF85706F45A41809C97D0C1EC449D000509B0B6C9ACE95F91E2D1FF102FC54DEEEA476726C06E198C4EB2E5E8A342C75A53C4FE727BDD039352B6E3F0139FCFCAF4F3F44B3B4751A76993F1F3C9DCCF74934FCDCDED4CD7305652ED1DB6DD60277D17EDD982B73161B144B224B6406ADE4975CC0539BAF45B3394538F0E4C368B9598E0530B4D8F5120215F64BBF2BEB922BF9F7A1422B8D5B642E6A217BD65FD68C444375BC4DD5E7471E8540C79ED21BD42E9885FB54C2FB49DB1683548B60EF7EA8D2DEE9A91506E49C51FC31121A33AA06699BDEE221634819AE6F8155B8A1F1D93E1D1F1064E5C158973C657886A115B83D2B3CD348C2813F667859046E322065FB634AA1C8185130354A137A" +}, +{ + "seed": "86CB0744A2F973D562DB3B2C47E234F02C0ED60D2EC27326407492F6A6913BAB", + "pk": "28949C37E29B1E305E3F94BFEF5E260CB29B04E683F0F1E3E2EDC22AFDB5FC6D979DE7A021924CB86D8AB86B1D64859F825CBBC99BF298B6B87E02872C489AF9B032DBE33210DF467ED148AB524A89C77A8AFA461FC57F3BD206D6BA67DD825022D12CBA8CAA79400ECC22D8D347C8CF58F0630C3C84DD051999E51944E040AD9262A60436941C3A0DDE60EFE0AABBE4AD77F8BA18366772755FC672B4E4B022E4B7E64CD3F7426890FA203FF42B439F3DB0CC90EB3146FEA0C3B5F1D4F1CECEFDF87871B04F40FCA90F3FA1C9133000C254FDE2343FB85623B75B100CD435C5BFF5E7E8490E00BE7717898DBA816BD0F3E8A7A439AD2948C9E5C829D3B1F1AEB4763FA27C90C9ED7E1EF1722CE12B1783AA64DA0384B1EDC211DB94BFB75DC689E71FCAF7878BFE16D6D867771054C080C70BA5A7EB6FE2BF34BBCB1BC26C64240A9976355336BFE99FBBB471C8DDFE0D204EB81F7B2956C8073DFB5F8A5C41DA87086F071D7C0E8490EA0AD194127B2A1E28C7BD8661DC0514BEA6861DD3B3C24CBB625128D2DCAA737EF012B4088D8BDD7D98E3F548E4445D7E753C9D3AAB45A217F0832C0EA598DC22EE9A0503BE209D020E3877724B3277EA9906957DC07E1E834DB4A4B6A335D48863D411560C5D2B54C81347B96780FB0EFE9FA6A1D5B88EB9016763EFCDF929F027B7A12C3963B07F01E87762272F958E066DD1ADB38FED33710FD6E5E75DF098ACB3D18923F710D1AADF8906D1602E3928A2197925B971E1F6469090B932E2BA6A3A2D7D73B513042D1247770BD516E7537238E12FDC86BEE336ACC7DB555DF40B80BB59CE44DE6F5F45594F91F9A8A91146F9F30BEEC6DCDD98623E145CD3DB94E3017E73B0B77803D8D2401527CE2830EE2CD7C577601676965C9113912E554710D8EBBD66E5C9F66236F10FC068E5469DD4316AC852D2B7E7E74198F8490A299F9945D19FD66947E00BCC27D18182B556183B92DC42965DF100E1DEFA542178AB65BEDABE24E668E9E354FD616A2962E89AE02951AA8F7CE98BDBE19FB9E346D02A4353AC6102A5D2DBB8600FB25FE08830CF28BC7A18113C98BD151B8FF4882C0FB6EC1C03E7AD142424F65B7A1526A907DE28DE378A2AAE7378E9B5B5D3AAC8312AB8D9A7D13DD96064C59727335EC0946B770F28C3DD4D80C46A014552F0EA2886311FD4B2B66B37D3D7D1587552BC52B11D57E78070E306D5AE16C73B8B574E90CC8B3793B68C8B2614043035A19BBAE46C338D14991C344BEC13F64C29DCB9F942BB36393C5E6642EE1F6AC97A530374EC7646AB23292FB0BF817078892BC4B14426B73213CDB2CAF3B8B33413C92D09D343A53A0FD29DFE241BB0AF15E1CEAAD5B6FC6E89FD4C0CB7D720178531D48D2B3D9397A7C1EB5BECF8566DACA5D7828F10CB9E9ADB6580FE49C574855E287805983CEFC751A2ED29DE334AA5DD15A73A6561EE82F39F5EF3479DBF324AD94317F2B363E53B2B1A4C5C4BBE954EF7C5A5550F0770B056EF847AC587B56D074033CDA9CFBDB9B3C482AD69BC46E2FDFB8392F801486BF80BB58CEAF972437E237EE4D2D40381920F3AAAEA382AA6CBEF990EE1111DF2381773057B5F48E38417DA2D67456B4A9C414A245463F9C9C25DE136CCE83E0E5157ABA9C4864F02230966F3B3D66D21289E41ECBB0BD9E27FE6C42E540FFA552ECDFF62F6434FA3D4A76ABEA34DBF780E597505B86FD6EB4FC71D6E3E880483A7D8A148172D159BBCDB13B4DD613414DC366D6E68BBC2DF8ECF874965666BDC8064696401C0BA1F5394B0BCD4C15644CF2339CC7DC02123C9947998CE4106E0E3F95895DF08BB4E343587CDE72C07CAB0EF6C45E7759CDC2102248F56205E4F9E09A6552FD4A3351D6DE431B4A5825DDE7F102E82B379429162EF057FA564F24CFDDE233E9AA94A93E67CD4E716D667CAA1E98BE971E7F46267A81DF798FA537C1470BBF40C6F0F14B4E2EB5378DC68406AD9C5A40F8E8100E141AC728B2AC51654898F8E3A7B91513FBAF32C6670C294C3F45B45F88BD8AC8B3B031AABB5E8B127B5C7FE6B136F0D61BDCDDF36DFB72C8BF60026FC137D0DE670084D4F9E99A7482791D5EC0D9FFF4BD381B66062B15BB0176EEE004EC7EC97FDB5B712F8694226CE1D60E7D79E1394046A1252EE30DD15F223505F1360C7ADC789E4DD225F4E11D72B5791BC622C43163F3FC669BDA7A7A680D58D88FCB49D05177AD1103C65C1CDDCDC2DAEB29D8834CBC6A89F04AB592FD79DA9E377192CB88EB7151DC554270E4B401CFB3F38EDFCB04C23D12A96302FCF04B2B7751E1637E146DFB116C7DC5DC7A7CCFE56E0202CADBCA4065596BFAE3A2431C6485D3AF3B727C921B5800CE77873E3E72A1C4A03D54AD3B51ABA5B1284FAC0DC80AB5889A9878B1981DF24938944B6C2D570AF90AA661B7F06342BDA8B6E67B70503D12D462F0783C900F5500FE2F8167F27977C742B29A96BF82DDA9728F173F572422625285848ED21FED7A77B89B88286639907E58D28DE09A44B989EA8883B2A492367B1DBC2925465D8EA2B3338B5FAEDACFA0E17EA560496E10EF78828765BAA8B97106D155BE46CE0535B81FED4504AA9DBCE8C01DD09943E6552B4A9A21C870AA4F0CBAD2C3A049F9ACC37915DF05CE5D3DF0665C2C79CBA877F814B8CFB49CAA89D1FD415100B8491DEE50DA1E26D13DA1EA3B886E8FCB44238536A41B4A48FBEC56CFB38E3A2E17056D63D3EB1CD3CA53F32FCD7FDE8182024F66F57B14F8FAB506A6CBC56FBF9A5E58843ACA387F1C2C50BBED57E3110B85B3D2A688B02609D7655DC6AE40EC94DEBD77434DA62E1184519F53DF6639ACC67E61D326DF1820095C03186B100EB387D77D81BBCDBCB83070A9ADA3B3BD5105D1C2C3D9B667741A7A3E126B34C3C90555ED867A3A53C61575A51EDF66CE3EC527509343ED637AC719637EC68C6D7C2FB9D4BDF58A3E16E74608957F553C193AE7A1077879361DF738DB9DC997028942D4AC711B0A14C6BAB05E5C07170E1D0393810EC9F3044A38629E65BC179866692A221B5A651937B3475EFED417DDA8FD06AF7F2555427697077A20D50F4283E31C70BDA469300A76D8A8F5756AB47D46030485BC553FB69B12CB6EA71E69C88910A86D91A039A3C5D1D29C9A1D728B508395ED7C3ED98218097DF7A65CB3E19D136620BC2A933C3C951E81C707E2DED2490451380EB0370A41E46A043467DFD7EC6B37748626ABB9A61356C95816BB24C29A4C64D6A7B4EA3997F635DEA05E400396E8B50DCFBF47859B842E1215D398F8339D8CF09DA11F9B93FB480690930EE204B18FA572AD409A16D69DA195C4BED44BB790E4BAF2A0CA406198A4E9C176D6A8A85F479E2250E0E623CED7EC8DE37E99716F2BED4F1E25A1F5C49FD6A4CC84B956EC82468777E08564E15DDE40548488ACBEBEFEECF8D6501A392FA0E126924063EF9D0285C5571D09E294959A5F1153B44EE45FFCBA5378AF7F2CC40AD35EE2EC6FBB31E3FC8EE7C89A6E07FC1B1A7FD602ECE50D139CB0BBEA22F95396C52352D0BADA3278305F1AEDE214C9C8CD9E0D8CFC81D9FA5ED48118D7A4D34F8DA18ABAAAF51D1B9A01A1FF5DC3D7E4294D3534AA3D121E938E3E8371014DD11379E88839720", + "sk": "28949C37E29B1E305E3F94BFEF5E260CB29B04E683F0F1E3E2EDC22AFDB5FC6D73B1B651557BB7138A45C55436FA0CB57DF632FC44F7E6947B2262A553675388D926CE1CF7D3C24A6125124973E6B13743F9D8337CD50156BB82556E328CA6E8D007D9A8AA09D94A21CFF8A1A2EE4EC48F31E967819633C9AA7AA697482ECFB453C48451146A1B420443C028932621DC988C4B3665D83431593886A4406D014872D1C66D40260D14278C5184848A9291904464CA1089C9304A1C432A10822D49447252420D1A322420224058160D0AC26008950C12A171883070220052DA200800398851388994360A11269221B72DC1342AD41446810606DAA4691316094BA44424262A08C110D812240C4500CC424250A60119918D53027119462961C68159A42DE33230D4360EDA0632222550143981D10405941040C20046002984D24050220746C42240023730E3A425D1C2040C3166C02430E01620440040C0C681C12825233209E3C00C50124CA42086C28211C8268884082914B16DDAB00CC0B28410846499981090224424802501A589194291E228290C05049A948990422224060EA3148DE4A2609C924D4B885102834C8C28025336022315111CB84591164164129118226E90B44921980DCAB6219BA43062366A044740D32005091486209925DBB00053428112A711DB1432C1240222936584347111172E53188924A7090A210C1BC32CA2224413C6059CA485990891C13229D8380441004924989052868851C88C2029201C252C4B440912B350A03404933280584682C49689A300095CC01010288AD4360C5BA050A2204CD3C641A04682E2267220058800084E032412230702233080D1860020834D0949115C4445D09881C236088482855BA628123650CBC88D0AA150940051E4B44004C62DD290095C880588A62918377003078D1C826D4AA67080804D63B66903A5918B0864501652D024464114682180690C17629A1021D4321014980814A37018C4659146660113015BC04023A26950008C08A18DC8140504A024091928E1960D032744891662C044324C442A8106265B08844B4208D84829DBA46C1C3160582029D1468DD2121013976D243332D4B6291845648A940090C4081C330A4B2011802885E1464C4CB688081861D8B88184846CE20226D1306440C86009416191122E649831200350E2C42C0A40214C3412E1202024022C41366E04202620414509C50582400DCB3851109550133491211022D240311217440A49909CA08014116D10082002408011920D23178601846C401292028591D9862984C8691B8650C1488C0930090B846150380E9C06229B4692DAA24000A36419404200056CDA104991C289111604908830804290CAC2059C2029220171630485C1145059347203C7009398450A0902E3064E22172614336541042550364518A150602628DBC00D53326A12272923854C9CA00CD44460E1B808CCB440E2A44948160009172DA3246A0C95300415100043424B8810D8368412436A63B4651BB32D14B14188C65110A08D1C2970D2B2115026499194691B128CD898604038680C09710C42480C078D4902008B100C02A351C8400480222A24422E8246888C26248B2832CC380400042C894449C9C20C02082E13C53153326A0B484942488D1903712386041335484C028101C4298B90016230094A00854834320003920CA201C108846144414C20201B1505D0B6045AA28018898494088084040E52280242140E40304583A400492280A1824C02B30D1028018A4652D8C690D22842A12226534410083362032672D300821992319BB24D19A60CE434704C128119067013422A4B06929232865AA424A1B02D02B66D4C06651C00100A026E902680CA286698C09010A9651A0390E3488148B4601B058CCC482C0B256692162401C66023016D1B46510A360484944123148EC4922C12084541463099067080A8108334219A0042889221D4244293B67002342420190C601805DAA431E498641131915B44418C886101A62001045190B461CAB68851C428211772503222D1B251C922059BB488833286001522A03809020466511451200672099464D808328C28869488659006488BA22D132650CC8205C944680C3590434002098850021770082771C23802A4468952360A231302501805E4084C21B14C2195501B4866128590890850D242621C002D170F4C880BEE2D7949D532833B199A8F1AABD2EBAB8DC6ED79D3CE9791B5FCC90E1440B2FCA080974B7F46CF160E36997EFA2879798E2B9763936D73CD08214CEAB7BEC430C10E250703613D29BF5D54903F114E5C9EEB0CA35CF0EA999D0FEDC7DDBDEF4076DCB97F8E4DF850BC4453F5934CB47B1951EACC8065CDFC3A02C137B0EFE379FB104EC91B4667A13C0D49043F14C02B1F493412EC2820DDE3DD9F77F62A2F73BAFAD1978706551B9908AF53751BC8B8979B3AA02BAA9BB37A9EB42DAF7FD7AD5D02295B9FF04A2A80DA3071FCDF2BF58A2B8083799DF87118689F7A34751D5039729F87DEF79E20D649665CEED960D2CA982A29FFD7A5D430AC8B1BBAB0982CEB99BF2A24038F67F4D224A794DC1DADB0D958544FEBBC073A30FF627F06259A093EE35F1E184C6CCCC51CC86E0B1933447BBBB13F1275963AFBEF220E5BF134C8062E10AD74CBE5CF5C22D4B61C7B7FFD66D959742E0CEBE90C74AC7ACB8B47CE737F6C44FB06D6BA5B7AF82D3C0031CA35C31876BF7376BC8FC59E8E74C76DDE4EAD1B648BF5E2CE28603FA017F8F0FA7F7070BAB8AA3486963B56724418F805D13E24D3B3898FEF6D4974CBB316CD41AC7B66E7377C1282FB01764F148B8E1E715B519970F842415B9FA682621D0A9A918459A480D863886B005CEC83AD809AB5909E433326BD19C92D15048A67F654C8B5DAA2015ADF5EA08704B4A20ACAD70B472005124087EBBA4C264055A2817EFD0A2CFD4CD446CD873A9BA85D9361532DDC0C1CC422C67CA3DA904C001D5254D9B2830FC1A2C54D8A9FF470D98E14EF47D51E74B1F633B9F52706DA39D6FA0EB8D8CC52375A9DEE93FABBA13BF4B808D6F27B5EADB29ABDE6E3CEE6D4703BAD39F5BF4833A3CB98B0D8D99C1B2CD4D5DA4F6C5A7C6AE64E75512471B8AE4D8E266C55854CCC37EDFCB6B361EBDD6492037252325FC694594F3031ECBFABAC41694F91178FBB7A1D93594EF83BBC94CD3E5EC1348335397BE29D7950B00424A79E47F8678CE690522E45AD670350E41439C62C4E6E722BD354804E178C5B4F226CA42D8C8E81B32C1948051AB5326AA03E72EEE8114C88372FF05CB7E5CC1D1D6829C520AA6D4462367247879C7107D619D66F9F3D01BE81BDE3ED85E87EE8710D2CCE5CC4F9E4C52758A3C819EB7D0672781EDB86AF310CDC4789C79659F9424380F42918DC60528F1EAE3DE5AD34E69D06414B5CC50B311E3C07AFDCE85BA3CA993843A18550D42FC6C39DDB61B9872226D5CE2D5CE57E427953FF303606A38CC4AE3B5B6A0886C27AF4AEB630F9BBED6A0E0688F532BFD0D727FB1357F2C8DF4FE36E3E33255BC6E74E4FEAEA7D6F99E249F9D2082C595C961438A53A8138EC8F4C7DE974208278467CB58240F4E48274C702EF2C6EEB718447F61F91E4AD08FA0C1E435A01F3E3D6EC6D7FEF96996B6ACF37632E4BDD02AD3230B6FDF302E8F93442A4693525DDDD43EA90E03DA3FDC054916614DB8CE66435DF03A2B3CDC14415143C53F387BDD0BE8150CC06C323D67480F56BF519308A7FFB993135100679C512B6D23CF99FCBCD9D998604E061D242CD7459FF389371FEE1236FCF1E85204F30B2DA3EB220CC19A2455568DC7F6637DEA11139CEC3C1D595B24B456F1261F27608008CE3B1F9E8905BF445CF3FDC68DDDAB5664394328113169EC75EAAF0B739E7F3ED08C9CFF6D5FA167ED85AEF78FF13743AAA84921DE09302DDD8D1A99705E809FB13B26F8D90652EB7A0C70623132FFD32614A7E268A5FE1CF298D8D1406FEEF6056BD42718F8256AC663FEB926F61393E12944A1644A9804513D38EDC72072A8FDFE3E0ABCD45A4681891CDACCA1EF58EFC8BF58D182B3FC7A8D61A103CE517E5ABB983E1B58DE0F07EB24ACA29725A5278CC7C06AB253A55E14C6AEC438FE8B9F5606EF06FD44A098ECBFB76355FE8D2932F72ACD219AB56F50364620B381A9AE940F7A3F6E416706278EDC9526B8783E9B9D75C523BACEBF472FC1C1741D7801ACBB3793ED9E8A7308018BAE285C2B36A3830C98F312349286F713247B4E3AAB8B089DFDE8DD3D5DF17CF3E58B06A6838EB37E5F10D6D6CA986CEEA61A73D5BB7950460774572E71BCE0DF3B5A4DBFEA69AB598FFD56E20A8318645AC33C9E53430D54A542430634B2ECD0D9343DFACEC4F2C84EC9241D1E92ACA6CCA673465AE958EEB1BD55A9B6B927F8E97CB1516E7783185E0F36A6B8AABD9653777A80DB0A8EE56875A77CC4D77D647DDE9367B0BAD8D6153E475BCE3ED8AE97C8C58F60EAA37E01BC298243BE90DE8DC8612678F3B821EB6A866276D5041172BFA9A20C2E562C1E3B3BD21A3D22BC6F276EC19E4AC85A8CD731181A3EEDC1EA692917F8DE7608F6E0DDDEC449A9C16892D27288A1710CC5142CFFD329C4CD1A4506E0706699954D0E7A8C310567900FDB0AA1012AB331AC52F46B81CDEF42B5D494309E588F775ECECCCB96925A504C9EE4D7655720C0FB1EAA63DD14A0E2EE2E37DA3D3FDE0BAFAE83C1303BBAD5991BF21CC6FEB6DA598CCA5BE15773B85A50A0BCF9502EE2B9202CA541F03371C94E1A645FFAF98BF4841CE59E1CD806E7151D9F3D568083385C2FF041D656E328EE76FA41B8DB0D60DD8A067AD012940C85A843DEC6888397258F1D4A75EC8ED9BC9D60D121E69A9AAD8F334C8ABF6942F89DC2DC8826D2904BF5B331155A9E3BBAEDD4F1A2EF1143C7651351FD7D8F473155B85B2B21BB05DE74CDAED6EBEBB8BCC2A3BF8FC30F6B89E50F160C7FC11B099C3B6DEBE53E2C6A5C0D96F3CDBC8AE448119F5D1B27E3083C82190CE1C1967B27A207634FC93986A5D9A18018991BB18CBE679FB9868E0138C4CDEC51DAF819DFD579D8726808B4A1FA6436FBEF11B4BF81FF2C1A80C8302FE90B564F87651E1F42E30C4A32A1F5546680A8FC6B3C18CFE217A86ADD3E96D0B84A9811932996C30127BD5BEAEC298966FC87ED2D280EBFB55055ACD4FB781ED3480DDF6402292D0DC41F5CF5552C35393EFD69015980494F11A9F63FAC77362555F8BDA8E9319E72B35CC0F13CB9A87D3F850FE89499B649AC97AFC97D0B1412F651895F19610245A5F9691FF5FB4E0E192BF59FBFAC4EBC77DFA81BC0BB32921C25F45E07BAB1924A5B0D7E41108C89B964C7C19EAD8D6C90E5FD77F206DB344CAE717F14C5FB8ACA5293C5C6718E1F3F9C92146DEFAB65EF3310DEC708707B2B2BA0F4670C10FB653F2F8C54A9B906DE06D2A93E36F0CE6DEC71FAEAD4C7663F160194DC2DF78D6E042FCEA0F100180A5DFB19205AF4CB8E88B22F2771806C222CB88F3C92B72CCF36D331DD803AD7080FE334CEEE9B04B9DEE66E3BE9AFB17475F8EBF168986CCD9BF4E1EC2C06998F9A26CAE3FE52B12F0331EC3C4CF85C91176228BCB56D0CC52C8C1D60AD6EF34ECD6DBA58B85F1AD69CB2F9484AC7D4446DA446487249BBC646832C57085622E25925017CF725C55F2BCC3DC155BC8064A1A6A9581584B883D3CEDCEE272728980888880CF6A23181F00E2E4182C5A191DB684518E1728E6FC9EF5FCE1523B8CE68DD790411CFBB8E58F4052727FF6CCF640DB939DBF955C84C95774449D4EBCABCA9A6637A807181F1CEE17C621CD5C29C59C155DB17DB49E838547CFE72171CE48FB1AE3B1DA964A95D5BD62F74A0C46528A4DB898854A064B7FA8E29AADF19233C3851AD0EC0074FEC5BA61AE34FF7C474E402622CBDAD9B70AD96559EE37C89163C271DBAED2D721A42F33965E70DBE0E6BF55E9A24D5F675874EEC48F417778838A0DF29BA2CA927F478063F667C7CCF1A449C48F7B14E23B54D16C3B0A284EEEC1AABC7D9A7E6DD880A980F8F73D47E4705FF2BF775D86C4578C77738D36F4E7E0885F16AC7E7384284D78CA36708B50943F0866E7438CA56134E286417E94B36234CBCD2E279BF974198EA375833C6AD770D6CAA76D10C7AC0E07886584A89BBD6E0E2F9801C1A429F7B48A3996B34D9192551A0AEF46CE8CF84BE877946DD751CCE1716E47A7A88B88B8F77BA7280B7DCAB62DF14BE6BE4B90EFFEBDBD3555CDA85AD90185C68F0C38BA2E036C685231C6CFA1B3BDF42426A2AF8F5CFAE4C998B330D4F7D4EA0D2F9F21D27BC13BC2127DFF9ACCF107B2A04CCB1FF1C85D26ECF8B897366C213B8C796454BAEE61CCF0CFFD49047A10C6E6F417764327F37A2756F6BD70E856CF3A16800D47EDE41CF7FBCFA107AA61F5CB95BC555F5ABC9839EB4DC6A6EFBF44D6727BBB6C5644EF183264082DFAA31E554E4EE9B7D3CB4B96A817430AA90257CBBD2A2AEC5202BC83CE146F2FDD7FBB0073D872BC8C9B6E52AC946EF26E20021147DCFA2550DD9FA380F854DE101795D1D05DF8A9C247318F3FA5F726A36697F1843F1F44B57D70ECD52D86ED3C5AFB7B2616925608263230B0DBADFFF5B661C8952CA48653101244F940F2C17D9E155B26E3075EA9F3D06A75A4254A628B2A15B269A1D1455B02D44BD064B5EE90ED4BA37E9A92FCE4C26D96615C726C6B604A964C9D0E498ED8D18BD3EDAE8194246F25BD618C2A53C6C88F7744CBCCCF4966BEF5BB4D2E5C03089C561F823605B2072C620F85A0E8907DCE2DD78451DD343406BB23B6AB74573C1E6F040B67940FBAFB3A4D1BB59E8E698570E0B4BFA523AA269C6C7A3908369078996189D29B9D" +}, +{ + "seed": "23BB289CC934CEB1993640DF1015693EA499786882A987414FD320489FB549DB", + "pk": "766DF1B59D8EEB563419919FBA3949609FFF99BDE51C494DC43E6AFBC7E1DA38AA9AC55571BFCC03E47C9D28AECF1C995AB14E20718C5913DB899939D5E05196AE807A2E01356A5BCD39DAA2B6097DB0A1E59BE749F147675B8E483116CE553F964C7676B6BF4876472FB095308B3F19C585DFC11C4755898BF2D2860A50B96DB8731D7A0BA1A9B9926EFFD6D351DBD3DF4E9593861DA889B4DE05F1BC908891AEE2CF827D2BFFE673237364FB80DAC1FF57EFA9C64953D04010F331C50A3A7304669D7C1FE09A45ED7822E7B16C0FA25BF50B5F45088DF18BB925E7F81228C00707AF7CE831C4303CB207AEF57A8117202EB2054199CB940522C51F10C0EDC37F7CAF4811C1D2191DE97CBF9A588B5AC18D44FA75C18978CF2A992C64D645D015204A54F62F080F2B3725C3C5B41383667BB11DAA5F58010778D875CDE5BF1DA1C7801E3DA73C9C586677D520392421621B3EB73D5673BD677A695FE158BC9B055F8F0DBCF0D6DA00FE4AB482ECED484D3B2F9BA25A7B75777E3B8E8F0AC5BE1916E144817CE53344691129AC8C1BB358D2B3FD648E879C2373EB7A945E887FC7A68D4A6A8BE8D1213590F696CD7F07A46F75304AB6F9653C6B8C3E7A4644C7183F43FE594AEAF139ED97FE8F578D752BE0A2AEC39D6FA474E8BE9C536289664E97879C2046965F2B35C5C3EE5F50E0EC537DC92F4622F8FC845AD4AAE6F3F1C1CD0F079B3C1B918ABF9DCAB771157C19445CC35149884748E9E7F5653DB0A3FEB4B6A22F7EDD4C091073B4DFA96C5567AD040DCFD03D8F8C06F7C8ADB09224B28ECF2965729DB669DAF4ACC6DA9BB53EC28F3BC40FE690FE61747D7194D878B5326C320E53E9DB8E5E31250BA43AA7B0FD09B2C88D5522527778B1AD9706551CBE64E95D005E23E3B4189412FC048CBA553D186D9C9BD52E04301E5B399140922690BABD55A89E91A89CCF125499F97509475847938601781DFF91E2C5728F63117AB5E46B0058CF23CD4DF0F850F8CBD50F9EC40351703AEDD1EE23A49285CB9040CCD83DFCC7CA64B3602D0EC606D765D73EAA65AF7483AF174EC680CF99172C60E449CB1B109D2A732910900507797237A38B14AC61AFF346E262E1F7BF5C290694C22082ACD5E21EEB0BA17D2E6DCE5B5144566C3C5D185437FF9150AF8356D22DC4CC368A66C1CD8D11609C50C28B82754EB07C6559723204E65553C93D5AD6F628B0EA65B97186A69419281F7C4E648ABFFAE38193ADA329082F0698CA091CEE2CA63DE821B5F33CB2AC74C85045FB5F7EC6B86409C705CBCA2594E4B5D1F6E9E295DC72D5BFE6CCD9590B069047346200B7E18B6F254794EDB8069FF880ACFB3FB970F4DF373D27FE784E34513C2DD0E6C700277B03D35A20167D346E247EF756E17F2997F8E8DDD86581917A78C0407C80A9AEF504069B24F52CC929B15DBCA631944F3E16C1DA45F3C55EEB697C00CCF24660B05B6DAF33E00F6EC513E2065E0090B8B16CF12E461432E6A3B21754C7F96CE7E4930C86114E2A7D7A809DAFF959BC73EFFEF4242484FFCFDC4E8A45447507BC639021BBD2B02426928BE4A37CB22D8FAB32E55B97EF5EACA5F3BB9E03C6B2E0DD9220731B6124E71773ABB62985074E1288AA955E86E7C4A9394C8E7744A5EC19B0FA9400E3C6C8F07F006034B44C31BA2FCB2C0B774B7DB59857CB2F9F82222D64055A2A2CA653CEA909B97C010BA0FFC434B4775FAA02F626EB0887CAD810C6081572AF088454D09FF2AFD96EF89DD8D466C4E3CD28972A652BD1034B65BE0E6628CCA3D9FC4518BBD8D03740AFCDBF46F4266572972666F7F5B12D4D2E379ED2DD5E1F95316AB0A7C7C807AD6904119B4168DFA2FBF3B9BBCEC239F72A1F5FB44340111C9824A1DD907722A75AC04B2ACFDD3D37BA1FDE4819F0D0FBAB61D0A72B664C8D8B0981B16E2AD0C64C2431930230F47D03C04501C29707B5FF66F8BE9819FDACD64E3ECA6BF66535E5D39998EB47B5AC726EB6EE4FE7414CC5BED56CF0C9D2F15CCE8898E5BBD9D6D9340C0C0365B76DFAB83470B22F94B53DDD079B1658801B21D14C9A2CA1632119ACFA93F741DEF70F6FE8B5ACF456AE19FD603B7D5A4609E34F9ECA9C3019B8D44C0C8A68CB7A2C9D06A9EF7314ECE97EAEC6441ECC1D4269737DB6F1870ECACCB822DF0F8FF694D8557DE50ADD38F8DD46E45035396C6306F32C665B6FF31ACB5B2A3736275C8371EAB26D221BD49F878FE270292540B7331C89D9BB0E9867A3B71AE6A7E532029EB6BB3A1702BC9E2D6F99C6D822B3DD079EF0D74F903848AA4948BAEFE05F575B606BF5C80156916C0AF0BF00D74D357A0876DABB37D2D9F5BFDE94FC9B91E65C29C1884D30573B14598AA23D969539E5DFF0A8F5F8B9D37D2EB6B07985660B0C4AFE72D94DF2B8CE9C91DF195CB13730478E4ACD65B65CF31BC6AC75545DBBDA223FABFFD0206CBBFCEE5DFDE78D2113CF2D7A823DF4D94BC6AB7853434F36F39628348A4F7EDA5B18307E6CBD69F3A5B4C0D10AB16B470A7E7D558CBD6C63C6495FAC0FF8166BF9A058EC0917F3F0B0A629AF76207D2DAD92B57CC3E559F572E5C5EA9529CC4F33FA61D4C9D027F4B862ED7E128D27C6AFA6F86C98E3A515917136087495FD441B5D54C3A7A1480F91125A2C0A71CA5E5C8AA3F015CBA22D3558C1A996B00FF50A58CE99E61E281C086082C9C8CE06704BB686AFD8F1DD5EC0AE94D93E273ECA098CC65E3664DF09E0BE3AD8A577CA5ACF31285C26EA0DC6B07D113E761D321EDB5EEB426D883E94467633D8B1E7EAC425423F2C86461D9C7635263EA5877F12BD8173DF6AAFE2E8E659BB39B17C999BC651062D7C14DE96C24EA46DC15C708B122CF079DDF3C85AA7F8116B9A59E77A5B1D16CD50DB43DE5C19DAA22F9C58796C1C60CE186405F277C3B3A32BB47EBEF753B6DE1C1DA31DF20DBD5D125A1C253D6A708243B50BEA40F5EC6A43D71F4BA01C80015B6AFC6396A3A5C9A30B555660700A92EA0476A52E6B15EE1E444264055F64F84719D42A5D854D91082117112C8840E6DAB690DA578AC625F845BF87047EB5CC21296E1F54E79B9A87B3F0440C2B277DBE20B2C5D4CAF803AC926F82A780BB5509073C3854296FA62101D444A6386E338CE310DBCF85171D8C243D71F993D21CCB7753F5CE23CCBA53DD589236F8947ED0A26E6CEF3536C75F10AFCF687E9FD0EF121AEE911062756379ABD985C2E99DEC3C204D98C58AA69DEF3FA1382DE4AC87F7E28308E872ED7826F01A365584E59A0D345F81E0EBDC45178C00BD18BDA8D5B905BE17DDB8AEC470BC1205B1DF09F21F39D9A9DAF1E04FD1FB62810B173B85FC5134AE99E44FF43B244FF07A15BE0CD15078800D60B1FDEC8964B10F9B56C4A14FDF7FE531CD2BBDD4BF17AB7B4353D00D7BE9194A13D0A313C0A166CD387134910A1707A642A229FFA05023DB92429ED54766D20FAC4DFC07C6DCE8EE38D9A7189F4364A8932E3BEA62F8A8F22473A066A1904108291541FA0F716E586BEE112EB37ECF7DB06246395A581EBC30A2E54BCBC8B097FBD50F1004337878814E932F7C8296EB90DC265B8519A3D420BE636472BA55B8E099C2C1AA6DFDA96C32A44717D52C9AE852DBD0E8E684AB00ED7C744CB881", + "sk": "766DF1B59D8EEB563419919FBA3949609FFF99BDE51C494DC43E6AFBC7E1DA382A55F39CC1DD6472202739B17FD8F6119F6EE2416E3751DEA7ACA6511201476F3A9CEAFDA8CEAF174A63524979B737ABEC12554BD7DF8E35D8141310EA89D9667F769E56FC0E0F92C9D656BFAAA28856C11339DAB43DB3057CEEDF836365F0F0C8124E8BB880DA00880C304EA0445120B10C83908D5B282A40B6511A33061C023283488C58106E1C058D03C22DDAA661C1883083C291C13420183622620011E1A20103C228084425C1A80D51182A8C24060BA54400B504C4124699088422063159921153B68918060298C26090080C8CB871A416429A102613C6450349824CA22003A3455346841C45448A24098B80211209248032669B4200C242061496804AC0906402460C246103422064066002460EA2B830DA06410892858B228800C70823239022088511276AA2486D1B1506811432122591E416515AB010C8B065111122D480915280508C92204818115884040210490006691B026659C8492011315C446E00B110D3124A51C66422210ACAC64C5B320504B72152B428D32260C4084253B431E3B60C49088C44481052221194220124A22D009085D9C625E2A84C21915053264920A3881C040599824D4C3030898865541424544422A4005111C16C09474C1936621C262E1BA64C0A1409202821A2A689CA340A234762CB04881C07058194505B2022C286508822916080480A1984228888A4466411916C248330A0280C62A24DDC82515A446621B32908C6499926482312124CA41113464851282C5B400591384021A36CA4A20990926462C04D48322C9918811244851101610CB910538225E3328ECB282E63344ADBA86124B349DB242A1B1185DBB049C0C28859B0054B20108A444890182C00B70C0138020013812200109200859B9048D1189123A005D49430D9C824D2280E2086304398000BA8301AA78DE2902098884DCB9401D04690202688DC066141388C02B18CA2040CA4964059C0710AA65004B38450422680189001904C6280845B826114B39109474A9A062ADA044CD9062CC2A80DA320008BB46D58087111360490242002220DC34664D9A22012012C83A60C01806152448204054ECAA00D23A86D2227011344094B2444E0262D99B045239570909451C44429D4062A09A72C50B84DD88660103330A314419CA825E2404CD808488C16099220894C48119C9009813692A4B68C214961431468D480201985485B160000C1656386688B302214054C80484E92C48922A72580B051D2366A921680023450512689893441D32891C328720C3025D3A2411B23828398310CB10120822CD3067152088A64A268E21250E230281BC111500011CA046E24A84849B041C3165199B06C44A00580C88002378E04A649930860CB0825A2986CC4C68CD8324153C03160B40C49266D50086920B680C0908DE21201C9126ECB4825A04892849828DCA810A3120652B64188104209236CD924294928011A32814A26200C08644A809122202A02008D84987144348C201144C8B8902240321C311103C0011A248010B08084186CD83890E2142D59066862220C63222503834198A080D0186122136943264802C0899898054A4226190206CA164C0A12604AB86D43404E0315229332054C0486E000658C987022857163081080160824C74512904D128505CA4884CB88716432101B4212E3B83098B60C94B45008050C08386420487288420063A0601322420B144019B6708AA08CA0348AD48608E00692C1A8850A92885A4426CB447260423221A091A3B471CC388C43A608C43460A3B44949C62C80B8711002904AC088A042321B872402070A99C041A4C4840CB5680C8588D0B46818104960A24CD4448858824108155193C88C09124260A251D420291A0810202810E3085123174D91A8319CC028C3A0900B1650142406E4380458082A83040813401082403119B62052A69014A364C120694000104C806C00A4085A90880C218152167000897019264D63342E0A470522994418C4401B8725CB168199B8211B964D91142D0A440483C4449BB08842426222B2010BA444613069A3186514B52101B26D11146591388AD134105B364C011891A386012110621935208BC27122A22851222404172408C32851289204952400B36D22B12919165221254AD3068A4882041C200019A650D7C1BEF09D1A5AB2F21E912D5DDEBEFFEDAF5E953791304B0D2B2BDA83AC05A83C57F672EEE2E73BE9022E63C64697BE5638B79142BFB576C0E7C4035365354E5D394A8AD64B33A9435619CEE98991E8B1E97D508E295A394FB4EE32CA9A0DE12ADADEEF508F07F2B48A5ABA6453604CDEFD5425D6303616B847D00B5D3910466F3DC420E0F4F6D5FD1E0AEF8F5848DF0FA693C3DA60383235807EC330665AC6DDCBE3918B8A46EE5A59A387B5015BEF1299FC869E7D1D30AC835B3C1F2E727F21DDBAD92650A8121538AA8A4FCADE6A13E3CECF4363C2754B3DA76DFBD4CC95917A1B1D1363329E8F11A2902640EC318144205C7758A984C596A40BA5C8DCDBCCBD717464ED2B69A65EC8D5D8EFADBA48AF762802DC0A36F89EAAC39B2E31EA348524B956A5DA78DB04E281E14AADA9B89714F8FF2E781321C8C4620A165EC37FB157208B256672DE198635BEF161FDF89B607F1727C75D9D45D70A8FF94413A93405D06C6D0D822E4FAC5137596803032A06A15BE32CAF1DDB14A7751EC712825DF6019289222D2BFF84FE8771D4680291E7BBFBD3F31242CF086504D015313914D6E6E9489648C08D7AD621DAA70237DC32C11C959BCBA0547B67F77FFF0590F7231A8026434CEB71159A31DAB3B9836CDF74C499343F9695D79D33557C13BB07A0E889D668121BEA0F0794B5319ED4B1DB298ED191C69160B339B66DEA5545BFAB625255636E5BF492E67DE4D33AADB56F924AFA84D91E8A1E6DE385714779F632F031DDD60569C5D035260EB1A0A995D3346CEB0B511DC87B13A1D73FFFF1169942E3D788C759CB3668A32013B95C5D498F4E05F26EBA9A444797458244CCF499427D4B0B457C7E7A5CB2F27ED58698E0C16F89DEA4903C7CC7419BA70AFBA2914F4ACE876A81D29BEAA27DF75E82F941D1538A631397CC9593ED423AC62D147BDFBD50E305CB3A03B4A8A0010A1CEAE0A4813F6BDF59F3EDF3364229C8F524553717D5AED1F9282B73FC37216B591C7F762FE3423C5D363F3AE6D32C06E192B135D7EE100714F5682CDB123B6EA8AE5D03642A435B6F2483D67ED91A58A3F1EDD98F342F819BF373E77BA3C5CEF082A7D58DD103B0BEFCD2F102BDC2738F6471FAA24E4DA7AEB86CD0A64E227482BC864A7D2CB9976CCC38BF1EFBBA872244EE2C9C366BF161CD5EA83E652C85C007A29ACC0D8783507256E9EA53C513612DF7A1857C12BFE64B106848688C70C05A06148B41E16B240AB2222A770BBAF3643564D5C10055AD40460A4028D03369982524D6DC3C3A0FBAEA763528EB3CAD5022F37126B72F1C239D801D4B002FABB90AE9804888F42ABC2601F18AF8BF9D319D0A8576ADFADB7E47DBB837FCFDBDAFF6AB5D16B55DA2EB56201F66BBE9E0BD78EEEB2037EB708BDE7999E2A3529DFCE57A7DA0DF50913C06A425CB665467280D2442473018214698E73FAD8C94C4CDFD01F20516B9D4C644DB04AFE2806E1767AEC74FCBCFDBDDDA474808AF96B92A2814AFB46307A06E15FB5C0254579776AFE8C7A86B3DEAFD5EE14D42E44A2A89C53BDBBF6A85F97B4DE490D1B3612F4BDAC78FC40C97AE572C5E333C202556B682D106C5E7FD814CEB696CD94E7D2F75C5DBE95D5F30672FECCACF629504C8D7B2E15505A241189A687D715686D5EF6F48B00C139D6346BC8FFDA65AD6EA7F2DEA62C91B87FF00A94DBAF52808B51F1D3E4646997D3FA2A1BDFA49ED5119B7FD5E6A3C2BAE019D5C2D52B8F4DD733B3D452D71B5D6E13019F8DC0832228B836A34517E29EEDFFA7E440B87B0A1D1A85773ED178EDF20614733F846644D9D87B2929AFC75AAADC84A8EE46CFA64117265B7CCB4987F3B9218D47DC9586D47AFBFAA700CFEA59AB29C6253A2C85D8B03DB1610761D3827B79AFA0ED64F6E4258622B717D06FBAD64589D00213FF42629368871618A1A76CBA764ED9AC529E790F6F19937478D0AD8B00F47191F5D3228922AB1CEA8F89E713E9BFF2F0A2999E765AA79F01CF93CB519929DA9A9F52534396D8BED4F997BB73ECCE290FBB34EF73EE344D7674FE7CCA81B9C3E59C087C68D0B5AA7B30D7204A8E5DFDE41FE6810B8AA73C8D3B589832C0AC61A8B5B6DCA3636C19CA8D0361BE98EDF9868AB622F504860F98EBD2AEDB1C4C21BD5E082BA30C0CF2887F2D3C379B4F1B19588EDF9881D1A01A6448D9740EE5A13782BBAA843522E82199B84FA92E12A58E440E03C17098C327DE35F91466CBD7DC9643130D91548038EC7AAAA490E25F88F2B4A50A9F32BD29AF4735D3DCE745016FA1F75A3BA7AE337DC25B5162D8EFA78CC119C57E065292C84D5A54908C14803011D82AA40678FAABA0C79D4B3981C20E0F0A7D890612A9BD8FCDDB59BE33549A6FF8E00DA5786EE8E94CD12B2163BBFAF8994B98FB8B10F96E17DF10FB24E55CA7F9E24873AB7D6A3442391B6E24B67E40E3DA4B63D558D9D79E1068473D97BBB3B842BD76EB96A3260C1F537D2E9CB6F0FFEFE3DF8677763ECDF4026159A407EA96A6DD8CC7662E3D773BA23C67E93CCF73710792A8B8E715B6F2DDF783C7F9E8F70F5D588311C37DB02B6E4BCC2D63013540ADA9C053A27E2165C872B21F867C64BAE5592C9D1601F7635A99258A2A41B94A6A1461FC2FFB1C9708387C89664E218429A1B2BC3449FF4B8BB04EE22F92383B9214C6DABC3BE103A4220E0BC93189C9672C006568C2A02C424974323EAD572A5DEE85DCF8EC343DA23071651380E5ED3F0CD03EFF650D789CB339ADC67AFDBFE0BCE8E4584A8FDB9A4D24C1137EEB55E53361C3910073DFDBFBEA44002E44B5EAE15B147B4A90EF0CD1D886DF73803AA55A6F37E9FB32F7ECEEEE495CB44A2965F0108052D1762819D04E1CA28E0A5240AE5D77B0EA36D42E49C741B09A5D9C74860A9AE013CE42C55B5BCF9988CF9A7E231F6784AF6805E5B79271402857F2D18CF59D69921AB8DF6C936F98A737CE7B1839521272477EE3F54164FDCB3BF4B6CCFAD5DF9ACE602809AF8D096BAEB9EA02A901EA7C9DACB20FDDBA38AE3898A0CB277A7170F6CEFA70864EB6571F96E5DEADCBD03BEDE4F3053F66C2BBFC01B99F05156EF302A29028C57479219E18CC73C29D4C12D70C9B99F0FD9F1C9CC7CE8B1FD4F9D0FF82B703A2C93EBB3E3E3D13A28A4D0722EF63E8BC6D67938621544140E7CA6345F88548607D737CCA54E308ADA3D17E8AD01E27159312035E0254682588F4073F829A262A1C37F8E9AD94F30C1079CCFDBF9655110D689887575A783E0FB5D3E1807F62CA14D7383C56A37695115ECC8A18D3E6E197C714AF1F0784900F8025A37867F7042E3533571FFB13FBF132F90BBE6EEB31F759E8C6B03396B5771191E415BF3EBB8F9E55F2514DDFFA7758B4842BD76E5DAC567BC7D440ADCBFB356FE1280D51351F9B12B3281F47592B4327EF74873C70483243FC12952BEDD44C4D5ACC10A7F513024B4D9811E91C1D6E0A5A015A719944AC8734EBAECA8EA22FF55C9B5FF8199DF6163F9D3955A96E9C5097311E197F4CA413B5909DE94AA2A59F681808CFD75E887747F7D539086DD980C34330515D50BAF6F7D234B99F18AB0EE6A427FB956BD747DF06B3D7078915BBAA02410EAF0EC06BE06E8BD8E39F5C0BFD43DBA1E0D8736C0E27439B43757BFDB16B46428FB3C06F7C949EE7C418815A4BDDE5688830745ED66F25C0658BE197CB157FB49DD9F490ECCC0A8D1B395435E9477767F00FB257C73B5225BDD008464F5F8B63E0760988C05E1B6BDE4B407357E3B269FFA93A75BE609F16E12130FEF601BE2B5BA2A0F34724D9B62786F1ECCE5948DE70DA662DB9DEEB037E398B19525775FFE9E07AD70507DCE5E1A0A732BDD1BD3CBE810E10E6FB46E5624BEF6AC2B4B98D4D711EAE84EB0AAAB0584A413088622CD9BA87468244C4248FC50127CE87B2016DA3C883993A16BE50E4F1639F0669EAA9DBD5B396465FA174EDC3795AB341CC27DC61E21BD724564E6AE371619F8684499E02AB62F81A5379877EDE16267C974CEB7359E4F0D951FF9FD551279899E3D88113E5F9E7CE9B3090B1AAD78C59964D9CCF80AA77E2B31BA06C8987639DC79BD927DD45DD883315696D5C67304B48C71FC7B4CF39F22F5CD3B36605111109057A1E040FE401920A237DC12EEC2B3DF5A906865F4A74A8581FC4C1CA0CA38E4C6242E5B07ED99DC57C47719F6427ED8B2AA53327D49F7E54D1155D9623053CC638A2526803EE6CE115309130DEE2A8C18925976C956AE5878B7EB82C5FC9B802A43F82E4E9019FBC644EB80209767D6D13D4AA3A6F4CF95142830B8A483E2CF474BF63421FCF9BF44F7D9FAD4F0C2C0A78B4B45AB3735D1EE0BDAE8201F2C3E40088942C20426057B4711E3A4E0CF672D52524BF283AACA49649B1F2501A155592C7FE39CE1912A1085D5709B38DFEE74EB7A8A48C1EC7D21FF37B8C6EA209D6534B6328F1A99A1AD3198894C807E4AC30F6F85E4D472EC7D58111F71037248CD833B929DF928B6A0C645578621E262A8535B4D6232E30F6A591577AFBC2CA4AFF9C6E9AEA99527E285777763D7DE120C62C37A605B02A45CC96FDD211C2E5D00719BC8061D295F060E7D85E5D09E11B959B13EC3049EEF03B479A21C4A5984EB75780A26ACD84405C1DD3ACB9CE822E7822836802B4CBF68918C213A513F41E5BFEDF1" +}, +{ + "seed": "F53C24BA9D2E6C4C35249377D1F653B2E8F7ED655292EAAA86A5720F46A9FAF6", + "pk": "C2385FF5B4D2AF60F6ECE79D62127B6BD35E7DCD732C94E86FA4412B4073753E55B13A23955D57A3FA27210CEAA2089B6B046CACD2F629C3A5B63E705F8FCFBA3D06DCEC47E3F643BD5FC5CB09E1630B5B00E28F84A8FC47D224F0F1A70FE496B0B75C234FAF16A386600CBFFB3177664915A7D1F5CE3FB7EA7A6771563CB00ACD2304AFD0B6E479CB3E054E794D8A32D35AF3E0D7AF2151ACBB8D4259E756B60EE1950F18E0FB40A914E42C1C62845949ADA186A3210429B8C38CB97002FB160676A72DB53E333D32423ABBFD6476D0885D9773E8A910DF792C50272B609DB4F8352F5C8FAA0D9C5628134A068ACEFBFF1ABF7CD5BDDBEABFEF7961B62B82380F1B8DC0C5A35B31D46E99ED6D95802349E4A7D1421A5D1E92A7EED88BEA564D5C1F2BEF62549FAE3A0FD128A2D097BE3A0C07165AA67CF0BE37DD21F9A8E0CAAA03A5232DF6E989DCC85783C1018D40E2FF19FF47298E10EC513F6D3061EDA08E182C1F322FFDE8F177A8F8A9BC5CA7917443A971C0B1E2A1BC975383B70277E132D6A5790510DAE885CC68D1B663DF26DD885187CB87142B1FB39A3E772E7C3EE3469AA9287C0EF2D1D4E4E009926A7BC7AE64779A7B30B9DEDA83230E28D196650DFB24BA8B876438E1A3034407C3AA88118EF17BC9B429A737FF98A9F8F2FC7EE49921A298EC8AA9E53E68489E75AD9AE6C478883C163EB62C002EE44E255D229FFB8C8CF64226D5E63EE312BE2635BCC35E725D5DD9D89533ED5FEB70E9FD05D23A4180785003E8E10D1A1A2B4BC347BB38F5657C96F822CC87DD803AFBA9FB1573F769D6F22706447C3EC0417C4E4F965952712DDA63945DFCB36C9BE20FD17B03939473AA8AB3EFAF165777DA74FA4B43031C1E2C3AB64B58EAFFD7BBFAD33FD09AD64B7B1338B87E4DA87375A32F1CC0C8F6C47C4BD303DDB75ACC74854861B920DE39897C2F7006C88FB2A67DF694899D0B035F8FDB04D5F8F26C901679172BE20BE761BD6BBC48D0611B9CEBD5C678F03366BCCBA33C272280B0293ACD0AAE04D86922D4016F011D0A9E9E7CB9CE0C254A6AB7CDFD644DA87BC8D868F4974CE5F404D896DD823CD44C60AE112CE6049757F0FC1BB427298D5C5183ECBBF4933A6DA01E1439B23729FAC858D12CBF2488BFB206B5169A0CC5869E18A2A4F00109643DC1898BE04DFD97A2C3B03B72925230FC5C56DEB6B1B9427ADC8F35F76CA0442BE4990803FBF2CB7277AAA475CC781F5B55B582F8AA5EF20C35D678FADE39B266D490B88481E9B7DC2400C33A4078A57B0E64A177E8275FD1ABCCBC7A7737644335B70A92EBB7126D1621143753C62473F19AC1F6C2E3EFCC90DD8353A61C1A459EBA92888100327D7D15CA5014BEE26E1899102052E39FA36E0397751859AF2742D2092D8547CFAA72A855208844C1CFF732DB881EBD9DA1A3BA485FD88C7756BD6C60A318B3B307BC6CF86BA321C67575D9521DFFF1334C630CD0FF87E9A317E0DFF3608680A16B35A67630ABE437F808E9F3D495DAEB8561F98F6E24A27C32DE6F3908A8BE72DB5BDEDD48E4C4B66F59FECB678689CB30BBD139C76EDEC7AB02FE746DD3D7F1FB180A5AA401B4E5291DC41DDB07F3035B9206AFFE0154081F22C8B9B1D33005C31C4070ABA946B4E85B2CE3D0ABA48E3B1F0944BE97080A6B0FD28B24686535E5F38FD90F11B7B6432E8DCF0C9F2728A8257E47A357CC24B4CD19F5570EC45BFD58FBB078382EE8824C181C8ABE78F1F16B39425600C5253F46A07B9D14F7D4E8B3C762AE9A38923DD422482733D25EC63B07880C51B602849B75D8C2C6DFDB81ADE1360C3A977419FF87B6249AFD11CD6FBF4C6EE7CEB3F82FEE038D313BFD07ADDA2888E7FCE44E7D382FE484DD1FCDB3247C9548D06043A0050B6370382FA972B80984B7E0DD2D096AE1D7C50307091E7A2B647E1136ADD0F75DE7596A7BD3DED6DD24E0A5017B5E875983AF1764D046DA4241CC678FABB2457C271212194F970434D893924FF3F4C41A4E58EF2BEFAABC1C264AE028197EFE52CFED818515A380D52C68EDDC680AC71D0855C024CDF4995E30B90DC161F28627694A0E010AC5480CEBFD281403AEA84C8286ED36315412924E1DBCBF220EABED8C0740F15588F072560E68B282644A023C817CC329EA436CB1257B7667C1AF8BE26B467DFE45CF68DCE933379928C6FC832E731D25B9D66AF5659FE701DC66B4EADE812F3C907E140EC23C5C06A707377749C0E448B7E4A6BE686EF9E07D7B313505A5E5235F4857E085583500C1CD83AD311668DF5D969703CF866875B74621279F5E1A9D940EDAD8063E6ACF290CF6418C3544ED1C1E9CBEA386FCE8D93690499FCD13D8FC53A6522BDE20B1E87BBF9FCA5E2B56D9E5B6D0AAC167BA43FCAFBCB5C65D3992526596ADFC708F9AE5D37F7567F60F7DB56BF23A0C3246C8E00C856D4912A0C9FE2314AACEC37EFBA21B4BF6CF684B1E06DC447C1D1C86B14DE72EF7EBA190F5D3B957A8666BE27712867443E78C194557D2BFABF475498C9AF9D5892BD7AC30E8A08660DF8203CE47E59A083ABA27C1635146D376472F663F2552FEF0F8BC36D7E63524AF82C985AB73AD44B269D3C19A12440578E55B3A10BA641CF1B9D6136540DB65B0A6CFC6D0466CF3C3736226845BB8A5788DF4AB4A96CBCE8F407D5D22D9F74C2F31644EC31498929E119D33316FE73EAC7B1441048A950F3E2B41334D79707D55114B4F5A6DF9FA6D2C699C3F6654EBB518CA8004F1DAB63CB356270ECD50BE3BC2F8452D91E3E241145EBD6F0D14E7BF95CE3B3DBB397877BEB356683BCC22F51767A1CA35436EAA5B8BF5B2BC14D5460AE1B9B6C8D9020D07C683AEE4AFBAD19E7340592AEEF4D61D17CB79288B958F2BC5FCF03C25E0FD2E5D0689F9F7D60E7D86779FD0EDC0F832F6009DC47910EFF56829C49264766854A33B10E3D5C18792D93529FA952B140EC72A876892031E1F927B30010E57FB56E2705ACC3EDEA9F98352F618B1E0E1F87CCD544FC76032B9740A1731E85E7B2348E688F8F548277B43B3A1F2071109A8FDD5B763C4110F2ED8734525D0151D6BA64C13AAB2192DBA00A1A26BF1AACF18AE3B1937EEAFBB50D7E3B730FFBC6F416DB7E47C6542891333652024A9B624F4765E7606B01A23210399D118EFF5E4EBF8DCA44CFC6CE37F83CA8F1EB2B22231DE01428C0F1CC73FBBC55A56F29C44CFC0E496481E2B2A0F5552CFFB4A275819769FBA6F1E3C15201DF78E58F993052B9831B71B70B9C2AE265B68B8FE8BDA95C0048DC0D3523A45CD5EB90463C0A2CEDC2CB20EEA3D84B814B5E5C7C5CD9ADA8B4DA4C07511A339323C30BFFD7DE9E0AE0D596B638F41DD47DFCFCF9424C41EF2D11A7A86293F0285BA6E9BE442D1C38BE1DEB2260F6457FDFC57B5EA8EE0A215A954D8D366C04818AC1DCCD367BBCEEA01553092711E9B6C2423513E4E5A15F497685FD22F02E40EEFDB890298ADC4F1A4137415F8DC0D7036CA2A8A9EBE2C1193C8DAFB209EAABF8E9B479E4F8487465450C4423665C51BBD51BA8E38F3DFB144D59A7D2339CB5E5E837695AAD09081F80524D77947982FDD5F9B3CB2605F3BAD6E9C1B4F21DDCBF9895BE62F46E8B3415786CEA7D7DADB9E48BDDA35C459A5E1", + "sk": "C2385FF5B4D2AF60F6ECE79D62127B6BD35E7DCD732C94E86FA4412B4073753ED54505441C3C70B3B7D89DAB317BA68655A52A93FAD9A042184C3ADA17DD2F4AAA36AB503D0F81ADC4DE1DE655304A8F14F5EB687DAC6325539D906C83FEA1EB81F82D91C3387AE16815E04696C47BDC3CA909F33C18723AD614C12A206C10D31C350E8B8805C912721C8504012184090552441210A092112412309C1066E4C6400B234CA2C2841A2191D142244396848016095CA65021946823217109410A1C49854348909818488CA021A44882CCC86504284621A4052383519A062E02364919112A988290A1240C420610E43651CC366EE3862C21B18419230E09398848942D54242CD1A04581A8248B448C0B950408354C0142104800409B12521947241420281A134D4414525BB06412207249102559368A500412020205814608D9C8288AB2649CB20449948D482691593252C0A6841A468618997010224A9AC429E1866C22170D14A844CB06625C466D1A054043360E0A278891409111862D4C44005CC268C2228D49460D181970604431D0C84D62B8900940061BA42500922504B100024291A420521319449C0200E3824808060081268EA0C828C2301049126224A5902192249180518104301B025144800801264219C94440B6049B269220A0611B139000222988B8300308021947301085410CA9301C24062490500B2769C9203163466C5000288B0452DA28411AC2051A9744D28660A3326982328EE3B6288C828060B22190326263408803424202882082B684A0C050138040A2A6806242200434468C2841119808D428709A469004426E01900D92B08083320A0A3240D3106221C360A43202D01232039521182206D3362463A229083420242486210084D9880D4AC601232045D3323210C210242362532062A4324C8BA0681448465248416098480B10854C882808854101224E49C421CA086A12B67002B265A0A88C5B202D01048ED8A28403460400C10941A66083C4501B200418460420276A5036111A956162888CD9A08523C70090C48D59864109220E11868C14824450A8248C220A60B09012244D53C01140B650A0A24D0BA28192106C00311042A65143026211150DA4B689248944A02084A1980DCA4648D8482509B9089A466DC8428DC89608D0886CC0104D9B466DD1B0240CB80D821486C1047243A46853840453C8608292009910284A120DC4028CCC321108899113B30542006AA0C2208330629A864CA446501C4232E22025C3242548922D91360688A86C60484AD8246919946902B1614B8205590268C1B22C1B931023150481C68D5A260DDA2244821086E41400A3B80553346562B62111C90888A2481A364EC44410D210825318128B2829A0340609424E8B164949920C9A92449A06284A180A980045E1C450A4384891C63024B96C91207049248C61802D23A331D3326113244948344D4C261021A124CA14280C1012103066948004C11848A1868109926D93469021156AA3A4100038851A99901A089219008923C1912430518CB600131921E3906D4322624BC04C51466A1A014A2034894942641839121CB291E4306A5A08861A05611A82414BA48D0A0281CB86904A2686D83841CA080A1B09059A9631E022829C308D08054A832685CCA6045338891BB06021B00418001223A921CA204EC0000890028C8B063140A8459136080C23840AC691CAB64412134500A42D21945111422519445053C425C20260D83001C99084C2224A0401011CA20CE00244DA0629E18469532086A4886D0382502288018A1200C9B07194040558B60D19442C4C9689E13865533602C4A24824122D19888850460C1819881036480A001193286408968082A04013372A20220282B26DDA3866E4442604B800D230620B0649C948728CB251E2406E03B58D0A02044184011A9980202571DA9291A0B67098B08C99C24DC8925009457011C444644026513880D48011D2B061E128660024915A00896086450B431102C084C3288102252911B24D842005A49669C0B4250AB56821904024156611C40964C0845C308913458143145013406D61C885D1A06490462DE010881C9824441010194221D802711AA65053084AC1966C8C228910236862086A13C43051B06C99104D022601183781D8109023868420272EA3B424C0340940048E40B685A486640C3344D0228D0CC10915C8D6BA68F9FD41BCC8679EC985AB5D74557F6F6D035539B339C408F2C24981BD5C4FD018955077A79C3FD94EEB1220DE199AB168B00F2EE837275D9CC54ACEBEB0613C81004681574F9943AE9850AEC08A1EDB44859E22D383A7DCDF3811ADBE6FCB0C896483F61AFBE41EE57E253EB9A42EDD4740192CF21B0708E94054CB14392E4157A5A88EB7930C7B104A6C348B028CDA9ACB2E2EF34BF66240D4B21F57E759A45EF39B60B19F7C1F9851251A46C13B973AD63EA39117CB223BC943A56D12E792233DAF0729AE2A58C56917359D2A6712A0063E87A8D424D28E2C0E3E4593A0A8DE46580DE0F74FF9B05453A34871581784160949C9AC9ACA19E18EB3143889EBFE0A2379194F8CA251AA26BF3750BB69703BF138A7FB44D4A19251FA9EA697927EB8621513E1753B10A1EC869EB486036EA73B0978FCA3017F933F027AE44461324D989F47E64B7AF616C89EDB7DBE101EB6EDB517B4F342A6FA89C3813DF0F51DF5522667425C694E6B2B872CF884B31706AA8C2B24FD6BEBDB2022C86660C7300EFDD92BCC2AF803B5D77A257000957217486444E016379DFDE75DA83DEE46B84B1F86F43B02BB0B22F46F1540F10B8C465C4412618EB64AC8235DFC7F695D22B0B7B3AB557DBAE7D5AF0DF012E595215E2A1418E7145F357BF57413DF34FD078E639B52963258113A3C560C90BBFF7BBE70E3B5589220E211A6CA8045C9571437CC9B3C24DFB14B48695E2053B88B1FF2B7ACFE1880B4D336BBFA6734747C2A6B7C460D24C3E6219A2B0AF769F794B7F239A4CA0936162903CB0DA57072466E610480BF09CC57D8ACA4A1CE8AF298D2E42AF44E380D94190E20A61BDA4CDB1E123A03DAC37A73F89B843FEDA27EE7EACBD49EE30E74A25A49D93A1972A237C95E1D8F4243BFBDBB0F9C50E03C16B37B01FAB3D0DD3BFBE2CF3CFAAEF7295BE80B120958946E02461EFCBBE668AE52DB638A7ED808B6778AD7D11EE66A705F32E232D39A0B9D73AD33AEC4799C791B7033C5949295A3AE385F7075943136685BFD59F9F1F1DC61026ACC54E65661DE4DC996B53CB612370833037A15D746880FB78CBE5BF2519280E7308C15009E0D6313D43A8DE343B51BE5C5D736CCD71C536FFF1B2BE1CBB8F4F873B580A9165A78B617C845FEB074F86A2C666CFBCA2C5582F99B7E5B2E11B7FF253D33151D02DBD056A06CAB4B43345A0CFFC2B8852D837216C36B6E9BD5307EC23DAE29719A896FEDC2A2196B426AC19667F562C3D2D97497FCC78FD50449AB975A8D65CF3F143963D4DD7B296F06113CF2E91A9054AEE8BE010E76B33B8864FF0748931577F53640207C6D335BC928080A3FDD2C0F8823FE89C53F7BD5C468DB531260D9DAED51091A5B8070B884C1DFDDAD50AB49ED6E6EA101339FC9A528D95D5AD49D8975756A3A4518D7DA8E3262CB1BE9B8533FB9FE16CA796AB247405727FB32182FA127A659CB40C810861CB048E6EE8442D6D3E9D8767B559C9180533FE3E86813707139DA97CE17457851BEA7DDAA2A32836922D29FAD031E7C9B1F9CF42621D2FC6FC785ED1585A13BB5AB8F2D119BC0A6381E29241E8B54F28479F17CC84E778AF97DC779BFB14DCF22CEB3FF7992BA5CAA89A3171A7D766178B75F66F12B6107E046F5FCC977BAEA650D6FF52DF4B2BAB3EA66BC560075A09CD8FE7081039D97F63C3FF478771747879CB4A4EC68807B4A7B70A21811C59CFA0332349F1A490BC727C4319B8004D40864C82BA3CD5C0788DBD9D7918C9309A70121B7854A4401FF8F283809C6647FE5E1C125569D537B50232E29E13BD97ABC77C083627813983F0CD96C3E79523298C872B19AD6FBA2A7754F89B8B64864FB798C80263B9138F1508157C37344137B87F3B996649D954A8BBE42A7D161E1474BEC1BEBB09AA11955D3447DA3101924DB9D0A2C499A579B140F5346C45F9BB621D78C95450FC70F245A65BA12D42AF7DAC59DB5C637D0DC8FD262D1D07BBEF45289552FC3BC2E9454BB5B3094AA778DEF3ED14175A8AAF783C115760B36D1F7AFF8FE083EDEB2495CFD65E1E363532215779DA1DED3996365B76E183E824E46DEA3D8D5CDBEEFEF60588EBB7B9E16E3B2D36EC34B463639C96200A34B5A8D31FF36661CF5E1D5E5F940EBE6012466A1842DADD06E1CD2987E0EBC10CBB7EB0AEDC00E93CA0DA7EB1E856C11BE2D6213113E3B5D52B7D5573BB8510EF41A71869A3B63A419492557EEA47E33FD67EEF605D0A77C05801B453D7765EBE207CE58FEDA0ACB4F7EF1E55E2A30C5560B1E22313B8ACEFB9BB15700CE1F60F99C87AB22269746B11EE963123E98071FEA8E5F0D28A5B960C62BC86B6A34DB2D21C82FE86473D2CF319C385B30283443486EB78CC6F6FCB70AA31988A4F6F328F83E862E1FC9DECE5D674689222C8B180CDF1D87A454C92F3DCAD346BA6FFCF56C70182EB2094BA136E4557920051AB41638277EDB2010AC169CC7AD6C326B8E73176A2D2904AE9F480A3FEC9A44F1A6552E78501F2B29D078D52F82EB54E2862D0CDFA0C5D13F166472EF24303899048911FFC3A736D45EB9202A18868999C0DB5653765A5E13801932753C3ACBA638C700B53FCB4CD1097D7D60C243F60232626F8FAB697ACF0E14158DA4C622DB29D52AE0E67F2EC9D1934C09DA91AC92205FAA39C08AB2CA18D5DD411B4451BEAB2A0A7433B7216C443904C157DA05B360265CC1DD8DD396DF03D47AEBC3CCE621CE5C0A55D128362719B1451B1246AFE01F548CC041F233A7E048AFE518C6BB90368FDF0562BCCB228A3E7315BBD1052BB42526DC233B9683955A13EFDEF5C16F18ABA2F6E073E9B1C77A60614CD39319E70D0F15F677D21AA806A68127BDFEBC6054CD6A46E12EF046DACA347E3B490DDB5F905AB786321CB587C771AD65BD4DF0C763E0E5950BB45F494D131F0F9F713E7DE8A1A38C6B0A41196CB8A5A2194E54284E295827485F79FF3D6AD5175373F09B1C9149B202FB0F4698672BA956A9342793C201B16E5BBED7B9FB67548335EBF045CB6A7D0C1CDBE524B79B6CC94EF46191FB43031AA212210EAD6184BA77883AB9DE9816D133D39D9E78CCC4927F647C703681961E26AC75293328C8C309ED3C4E1736FE30255944427E84979708D58432ECA8E6A4AFB1A2B6E49B5FDFBB03B4892909CD5272783330EDFD4FA333CD931925BBE58D2BD91DAFD8F78CC458BD2F4DEAACFD08E1B3B2BDDB6BB2AA1838BC18088E860473FD3DBB337FEB1E4B473ADC1CF470CF3E6C37B80814A1250A3A49E27B4E8BF39DE69DE5B15460347963C6ED8777BD9FF2D10CB4B5AB5C359165D8D5D32B98956C0B357BC4AD66D44F6F806EAD2C983FF682605EC53137CF7EB4F9962B2CD012025C25F7E1DDCA033237AF3F00B773130458BCF37541B140E6E61AB7EABB9596758DE62C089326AD8DC30A3BBA2DA22AB72DE3220934E10AA0DC70E7EE1F2876BB8A368ADC58F820839982BDBC1BFDF8C1DEF02F1602918D6DF4360FD8D2F3FEC610373271924296D666BAA4C90811D85E8BF06DF9583B42D77AF82BE9ADC7C6326A95E4B865A1586BC5C6BAB186F3C9247F5E8D9FE965A80D50EEC366D10059E0C1D8D6CAD7C4843263B3337A75748A9CE4595C433B3021DFFDF31E45D87AF5025A9D1084943A74F2E3794F0FF83729EE840ABA02D0EDF2E79F5897D177607EA587DB4F24A6E0C4751C8316809EEBE26527B94F25DFC7F6B8B54F4E9F5F296915BF2A8ACB20D8DB55C7B2F852019202EABE8EFFF3BD09F303A321F6C77F784637B82CC850C41028BF4D016020EDFC4F2038AF41C8EF4A22684C38338386B1B8F825A6038033AAC64D17D1EFCC3C739056E4DC66744F883616A5A24BB18AB58990617B9362F2D06CBAC7D4DFA2A728EF2388815782FDCCBA7D3AC321FE53E52B7DDFB3034C4FAC11824D823508793424A610A5462844818C928E8899F0A33E3A5C2C0E666E02E04B4FF1F7481F7BF2977072AEF7A3CD28706898007F7E3F65844128BD753873FFA555BAC0B0D04DB052BFC7825BBBE7E17EC92DDB203AE71BF85349F26194506D95F2EF54E1C6B007ED5D784BAE91B4B3AB4AEEF1933BC3E799D02F09944D20A066739B91C3018BF9BE763195BF5D934567D1F2CD6A4F639296574B06E0FD867D93DD1D7BE642A8E3A06187619240DE0AFD0681AA84E517EC1C74CFD9B3603BF8EE427D0E0B67D365C2E8E20717FD02F4ADFF1E4AE5DB91BF73D691AE1C3C4379C08B58172CAD372FA57D7BEE1CD37330B602744A793158EB421EC88B574B5AA3A64FC21B482D562648603E2067D136DBE20993A2B21F2F163A53EFCF19DDA105D9A24AFA4C916565DB7D5B462F0B48025A4FF8A7851555DA65DE6CB4D57C4AE1E786EA621870E9A6A2B37E09BDFB7CD29104D4BE15D71251E2A2032CFDFB67DA87EF99C23D4699D9804852B5F0793043AB691085A35CF4C8E93CA53E59CA4898B2005FDE559B7F5E7DAF6ACA3FFA45369373ECB89E3678AAC8E7F49F23A0EF032570D93BD21ED5F09F6CE77C21D5FE74796DEBC64CBCD156F27AB394BDED0F330757B4225A4A3074B65D4DC89027BC441EB6BB08D3C299D58CECDB15992D849C583EE935E34711833D35C8B57CEFFF60D84A8977415DCFE05D66D982529B95D5B13B18AE6FCAA86C75CB1CBB207A3210E683F1F50BFF5D" +}, +{ + "seed": "C8D0778FC6359E5FA663FC32E9DD1E53F26671B46C7750DC50CE69617A36D2E1", + "pk": "176C08BC68F3336165D67633E09DAC0322DBDF16F4C3E40455F2608A517B964397B289F9D4641D75BED239638D5292DD04BB9A264A8A9DDA6C256589EA35BBFD41C3E4DCDDBA3963BDD7DAD6E7D7701A6EF8D79A12239CC77EF52BA01D236C9ED0A09E26729988F7AA137FABD14EB0B24BA5D900628830115913FD55EBEBB1D4BB3286D9D0C9141481D3700959D415E3F1DBB222F968BF66DF0DD0239FCF22DF99D4A90F4464CD25D31A5A34DFC5B7BD06A2A7EB7A6317EBD6275003DBCC5803C13C461D98C7E2F8032051ABB67FAD382429F050E7C7662FD2287CC5C90AC807B1E3CB48B40FDBF2A2849F72887FA28F8890890B93D9F8747BB3D12A5EA03ED29CEBB36C49560626112A6F91A7451F13DB5B3F199043C9EE3CC29F2A359C87D457E87EADA7C16ED28A38ECD7A9B3E8DCA5222828A5BA5ACE01D80D416DDA5A86A6C6D765A3F699FC403583B89BA0D246C63B059C8F438EC00F6832B977A6E6075BD147E11FCA34026D6BA629D6848E80740B9972C695B183C836AC198AC8242DD6E1C2AFFA7414ED108768F210EDD47CA00CB37F77B725E53A0AE784145CBB4EFD62C92B69CA844B577DA4C4191EDCA87433C8A58169EE98CCF5BECD03106AB77B161D8D2D57D2953E6DB40172C52634C6BE81BFC10F10F0756D2D5879C25425644AC52B9C3C2B6760A635E45BC8D7853597451B113123F61F15D2CC28E5435BCC2DCF4307D1CF8641F344AB3FE26AABA75D93719A061F86D62827E648213DA604CDED56F9112FA02BEF09A700D5BD96AD48A2E76C8F4E23B23AA103C878BD2EA6DDDFB99C9CDD359A0BDF3DC5867025B97573F9236F5ACBECC1781035B4D4BE20B8DB36200D988C4F8D25A9F12F103FAA96214D1BED02733867FC2660340E145FBAE0D7F1DA8F96B82379ED215EA99C27DD25BEFD851A8A24DBD1FAD992CB6DECB0D79BEB70AE4CCA034BF3AAB421534FA7EDD20F850187F58C7E74A6A9479F224DFD152DD7CD0E3FF8E0394F1C2162B7BBFC1884BF1ED6B30988525EEF1BA9B7F0DEB42F1FE9F8529BF4CDF8EAA0A8A7F73FD682195646C89B47409A164D16F18DD5020E1039ED264B25C3950F38E2185E387F1FCD736B34F8394900FE90FC706F89FE9066CE511A2ADA019C9CC96486B3F648DA4C162C4FC6573E01B4B5452AC528657B2CA570E7719AC5D22B461CB6722C8BF8D9AC15640AE7187873ADCDB5C529359C32FE3A0CEEE27243386AE644A18A14ACC3E583561A51393898147CA7BCB0B5A1BDD624888981BEDA682791D422A5B0408F7CFDA10849124A56C3831B12219D979D2945A6299756C14C019E04A27E88CCE860B55688161364A1D4C4AFBD8F2C68FB1E7E5E55E5BE50A47E3D5B9B3A034B9338B2B571184333518A19DFCF5958E5486BD2834D9055CEC1A1981637BDA2460E6F2737CD752B20D4AFD4C10A55B4C80C330F8A5B88A298C235A046CCBA61A276966D848AF1DF48F8DF3F732BA52980BC5E496CB0E61A92C20FE7BCD9E3F3D39478FE9FFEC11C970EDD761A4B704780B7A437854C318192FC4BF602DD384BDFF3DAD78CA56F32246B5183D267F21E5594398854CA3CF56C472FAD2B33DD4D303BF14B0034466CD46AFA4C91636BBFF29BDAB9E6FA6DE92A5EBA2B53DCE92EC6CD55175756AD9DF520884439BED4D6DE233DEBE6DEEA790CC51AFB20AD228A6FE7105C534AF48BF943532316EBD8C7E3880B785614111A2129BB63DCAAC40A2E9F5F5196D56EFD7C977E3A3FE938F9F812BB5A404BF9CA0ED121E92A3AD145480C31FC408A363B1C8A578F0CC03896A298BA5A2A2BC1CB04B9B6402301346AED5D431CDECF7D3D1B6749A63468767AA5A463955BF04717DC35DD63EFAF6D6F5212A744E21F4E68D807910A8B2F4EBE90399CC91B85914E8C4FB95FBDC3FDD3E448C2A9E6664BB2A1EB9D5006F4CF8EA5C8A1785EEEFC46B7C18687A36BE0B8044989EA24D034FAF9FAC8AD1903DADB16AFB6E695802825F40125E87A51DE61E63E123B838D512A821BC6534B7D6D8EE300ED51D051B2F3E5B564973B92F961D296510BC9FCB907C024191CD652B22CABE1E6EACE1E38E5C9A4B88548B1D3187F4B3C9E2504F828E10ABFC2468727B90F018FC3EEC69B11AB8752CD7B79A233CAE01E5DF47D4E696FF2C6019A754CCB5821EB0B2071D8C09A15C7539159A46CE7424F7B32D37D24697382124DE0489C891C27B0EB27BEE7CEB43577B0B19637BB1C21837936C7E721BA0718A2F855473A8626B61722B1A254731269B906A67CE68228E9DD38F8EA09733914F8D748E909999F2E38C50308DB6217B5178B51B0786C8FAF468FA9973770984200DF7F7C798DEFD00D207FD646EEB833D1F58697ACE409D5F238B2EF191F4E4D307BBC7D563E26EEFFEAFF72EC348624D4BEF5ECAEBB72166FCD28C66A78127DBC5FCC0953F402C88BC18213D50CC5A39C309445ADD6420D9048EB7897B061570DC94C10D985568A427BA55CE067BF120328EF29C2D07C21D1D14E2D26690A55F52805C561F48AB496EF194FFD957D4F1247D73D47DD839B4C58E87966589B88ED55136B43489E038FB0466B812F810426722D3F27B3636F17EB97601A4090F9A6ABA3C771FCC8273749DB6FD1CBB34BB0526417EDF0D0532DAD39A4D42B974A1D6683C1DEBD68CA87074257DF68BFD763CFE0324B6DF92B7A9E6984776C4994B8E0B9485C869B2BF65C7CF35427A929F7A9309BDB64655A5F03B69090296F172530DF9E9E3B40FFD133138901FB70B446BD868CC97104C63A08BBDECDAE86FFB6A5FAE67AD1C9CD907D99F1D64F74B117699AEACF58B191D1B882911A0AEE60EAE4AD5DAFA80D7E69D470A69961544573339665D0309C1B6320633CE6B8B9C7470E7B7299EF8C30082BFE9D917F44978E366A6C69C67021E1C77DFCABA356F322689A73A5F18EBBFDC484F1A319854915D1B4BB34841411760B925BE2255F6CB2EF607BCE343E8BF8CE32BFFB7C6501A8CB2E300FBC7821A67C8869416BDBBA57EA4CC34C246ED9CC7BA00C929C53D830E23B6AE78C63FD01FE88897B68FCEE0EA0F43997C5937DFB070970FA8BEE130DE98E4746656EE7108D414C7380B7B16BE6B14128D5FABD602F58C308BBAEB3CAF0CC0A32304F95BA0716B9B86FE2FE8CA47019D187157290D2BC7EB024354EA3085CC9AA3CD5093474A03122E224FA85563A7A0311D6F6D52997388E582C92872A02F8236D3E3B7AD23886EBA538A9D6F4C044EEE43342CDD983537E1EE4AA695FEB706D00C267DC96BD0B58380B88F72950C006ADD3DF8E6AF886334128B8F36DCBB214151FD44C5E9093C0FEBF90E2150CB14ED76AB66E39CFF756248D57B8273070D0AB53A53E812910B5F4AE28CB7B0EC687878F0338177C472C387FDB5A5434DC97417108494C192C5A2B9C81795AB648C8C5301A356A721F3C8394441C24E415809C5C913CE55654CE957C5EDB311F386C09813042DEA14CC634886603B34B9F5C88A6F6B22F2047A29FEC04355BCB8DF6375598F0654D35F18A07426FA7FBE1BDEE98CE84B977F1915BD48F79C50296A88AC76D8DE9D8848495773D8F2C5356F053EE297E649AEE43B01F684E6131D0DDA5F016D7115D0625F4E26CFBDD0EEE09810976FC3B3BC93E0DAD1F", + "sk": "176C08BC68F3336165D67633E09DAC0322DBDF16F4C3E40455F2608A517B9643407C924EAB89568C8759675DCA08CC7B483734454E675D5624D163386CF511D6866D58601579DFBC2962D0DB3061381D276F0C11231DC2F231A8EC570699F8AD3305A0C0311D4AAB7EC90E8A9760235B08673DCCDA8A2DFAA85B4B7B14C8038F0C00841B4942D026466334910CC94191488A80003081346892820008432E081288C4122D0B423099064CCC1210C14211D022261B97601A8028C0086D20B16464161204232E18834122B3048A840102276149820812A76CE4C025D0144E8C38218A168A48C841018964CC283101C529A1968159220D20887124385023B14DE0828019A0850A924DA10828122586D8826019824CC2842801C86811092C08438453106C14198A01C9640036464C280ADA466AC320855846051322610A00729C306482B451D3264D43140D8C3444142041CCB649D420298116118806251C2849C09421DBA240C482810C492CC9A685210444D2869160C66412866C00164D10C608531884441631DA280C53202023C22CC0984010826D9324089B368E044042A1C884D41665CB482804178D11120163A2519C488E9C408C63209008446062207149380A2384118B34491412411A091098C22CDCA6310342219B465263240C110190D0885099C20112B82CCC3009CA948D22C18C61240C090171D8344694B62D63860D13B789D9369218128264C40843249160282C98B04984066122A23192408D22B22D18C624622091130290A1A200480470A1868008109022363111C84CE0B60509458E83282E60482E0C403102A1645B4049240921C49031C2466490B86C92A861D922516430911C37920AC944641264E32888602485532844A3280103C00863184CD34090121229983070124888DC424E5B8620A3A84C40280D10058899A268A0B06513B904D3C68911335009026D4AC8300C429144106002B32164B230E2A2450B259010A911A494091442604AC80D0C22710B3191E0322013B86D4AC40C04C57154969161949108B82014213204004D0A4126E1068541A0709B1091A31032C8146859B248530290D89824082646D2144C42A005A3B2501C806C80B828CCA825D1C42C113044CA02490228100A484D91B670D33869214710DAB8489AA83018428804C965644872111582184188A4206110412C00821020226A23C5841A336A10A0419A148110484E013980C3862D91468480108D41262A52B40881000ACC38518CA8210982709AB251C1C241D0A2890BB06824A04919B865A02622CA34900C392E0C496E54142181C04C183129624442093032121384DB946D80148911414454C0009A482194947041488413B66443B2605248265CB03058282DC83444044400E3960CD38000C4B804E13026411865CC282AD4B288182040D4A8408B449143C285024191C9908593209123A28C40146801472DCC986541989194B6705044005110621B328E1021321225459302815300511C374810A5010032258C448C23B28954A6800A2941CB82450A23259322110AA151A4841014C2491882840B272E0B2992E4A428DCA06C5C186CA2484414C38041022014C46499966508026EE106304C984810326292482064162C10308610946C22484D21056A8B382A5C80880AC990C3222C09028E8B9230E200264842801C291210123209A02019204C190280204322E12086CB128A58120598264A08278C1C25818A281109894DE430250B4011E1C46C404860584251C3B42CD81622513806244904C23811D3282DE12400014801D0100603962451B8614C886D03A844D1B26C2420519BA641A214921419820B27858342520C804599082E40827062C42113A020882631244621C82848190268D048496382849B90045B08211430664488245C103080420963126612252D43B08C519641D12884A49671894820D4A010431402140805A0960D13B98004A68D1CA5408C48425A98490B494DC426308C864C9B8884C3002250066A43A2849A0892C2226D02384C02C03019A9251BB26541C001DBB810E284240A17200190904B9204082945901222D9366559A2818CB42119B7284A06411C133004128EDC2671D03842DB384D0836660AC210CA402A4204041A202CDA404282B46DA23042A0480293488012137061B265D33041DAB4644CB681CA0201D4223283A871C1862909337172F739B7890830723B9ADBC0CD918254BC4E2C6DDD7B63BE13F32F5DEDEA0CA7D38F05DFABBCBFA3924BFA10E921255B06FA33050F311A3A12B3107CCF4CC7A9F12B62F93B668B3E7AD97B456C993CA037D5B71E8DA18B406C5DAC22E5A1678834B647276EC041C68BB17D997C729D27D049896211CCCC79EAF8A0E47C7CFCB081FA414A3645C0279EF465738A3CAC519FC72C918298B2F9005B740F89D7142AD3437C54C67A379B7BC9BCC513B3BC99B1F358089E711CA4F988BC5332BD98B1FDC95F44D124A5AEC8AAF99700B67BAF5F76B33859EB52F4B474E8991BAFAA566070F2B5329BFD634E718E5F99522493F43D61093D86F0A0EEFA2141549146196F9D05C778C8BA7DE2E27E9ED31AD1CCD1C6FAB2FE999D22A51BAC9E3FFD876D76540E421EF893FD4207B55D7CE9B4E67B930F02B972918886039688BB9790A5AA82112E86D4F5E6C5E50147938723914FE7D5D57327990B53655CAEBEBA41C849ADD5E6C08A6E0BCB03BB4001FD71244F8DFD440D6A2E39F32C9CC41A0A9DE17BCB4FA90E9D038E3036FE1BDD38B83477C581D32F017C4AC0182186D1391138423EEE405B7E263A62E793B09B78EEAB7723CBE9B16006F87432AF2684612E79D045A03E5E2EA748E03D09E9D14DFDDB182B175E10F8072019928B37A05B2BFE9E041BDF35D4A8EBE5D14272F928FB458A6A6360090BC3503EBCAD26F2E513CB751AA3726719DFEB146458C0ABE1CE896F27DCD6788BAB2B8EC39FEC0E24AA4B87FAD919125B1B90F1A247C7841B101B9D8532FDBCB3B4CAC0FC30403083FA67754E2E53F204A37E6E59A03FAC21EEF88930D36C3A88005E30BD2150EB22D90A46F6F1F17738243F26C893ECC437876B20AC447702BEF884CE00A916811A0B690E65124C4A90E8BE4FC064A2A7363F51F0D497F6F48D2BDAEFD43DA3E8BBE1FEE6B81482FC121475642580A6BE74D274EEB1010C1021D3CB9F887A0F9163292D80067FFC3EA45DF606AD2734D4FBD2A7BC94577584A000C144C5D7095A261A4A5743701F284271EFC1B836EBAA9020A315B941F70B8F8BA8DB2F7E326A9FBB60089B739EDB09637153AB4168DC958FA1FEA52DF8FCA1DEF7DBB2383CF402D2C535460EB45FF67BE55981BFD7D24691A2FC98B68E5450A610526A1EC6B5B65C7C7FA99999DC09B5A96A5DE21C1BC917D949D39B5682C4012057DAA773E2D5F0ACD9D2767A05D75300A83A55D8596E9B32EB372FADC58202003A1EC2EB483D41D4E48BDEB31BE9953D6A4323346A8F4A93E4045EE4D958C1CD1C4D81A77700A9822661E6FFE3FD2BFFA2AB8680176425F93BF2D6218F739A043287DAA557743078039D735EEAA2A664E30B1962A338437C24174719FC599A975417C54649548BCBC7E5BAB1F9E85F1C4D188E2E55C8A2C49EE24B6836402074ECFD06EB5E0BEF8E56DF71C2E916189B8CA9EB037B75CC193A11C37D94A22797D37056B2CFBDA7D9C6868A0C1880CCEC923B2408C122B567CD8CF49312382FC6B20DFD1A382BB624BDBCB8311E1CFE4BDCD93F148B81AED26D1A4C121551F1C3C6DA706235546CC019CA9DBFE4AB857EA45797DAD8F41BFD753402D43172B7AFC4E39A500CE7D927301B30A0317046F44111AA38CCC9A0E331202B896CD70AE69E289893642FC318990D738EDBD0240E648D5F470C81E3F6CF6664A8DD271242FDA885502C78A38CF3C7DC2FF99B658D57C8E840FEACCE406FBA15C21DE8BA1BFD9F8E50CCFC2225562ECB7CD5F4735136D2BF4CF2122C3F395B4458FC82661927D911F7D91B4CAF2A7D9B772E8AB7FD499E11551082E604F9D90E46E242FFFC5814F164E83307ABADF982BF97BF8504902D78C0FCAA889CF85B15B4E973636CDD92CE8E9FF5E7C6AD98DBF171ED629506B851B9915EC32019E8FD1AD6D7E1B31882761309EB5D44CDD89BD7BED85777AA4BA1DAB9021EDD72B6C7E428A80AD736F3EBC2494F6E3B3222A0BB32982234154BE0DC90FBE1CC576704803D9B8E91AB3E6A7E74CB94F2BF6A708E7D1BCBB24EE4F654A49FA6BA0DFB473E6594991D71942CED454B0E456147CB713EA500788EBB4D1B64F408D508617160B0ACC39FE2693D3CF16DD6BB88FC99D2A0BA06D70A9D66FB50862E768B42182BCC8F770510278CD7037BC26C5C9F04C560C004C0735718AEECDD15C1609D2BDADC6B57AAB41D573FEE8AA42E6D47F0CB63E86E276AC802D1C04FCA01A7D3B0E6C338C80FECD79B7D09910DCEA7CC993AB80EBA57DC66BD8946EDD4FA70BB4454E0938724FB2721EFF9C29F65B83B87AC0B3356E5F1BC96464A20A841B89235CCA15503FE324877A3658F00AF4BED8BD6A30149741D1580361A1460ADF64B576DE7700B2658F79462D1A0D83C2D74D5406B98F672AB9EC349AEE128FE8C3D7C7B95594FF538B4F1AC31634233BA2F319D9685D09F740C3B39B53C9ECC8F1440A66FA8DBC2BF47FC6FD4FA1BF49B157B234CC62275DCBD35A2518E752618A0E8FCF01E35C9914EA77497AEE217BE8D5560371015436304971AF556E0372616FFEEBA76F5816D33532773A67FBFAC503DC8D4BACCF893B035EC84FF7E57E2091B39817C4DC8FF77EA9207D6962A893BF36B28BE6B40C6F9DC4092535947F8CD4E0A39113E6331378CEA0C5B2A684349FBCCEB4010F9CA25360FE555B576B919DC2E50E6EFEAA97197FCCB491138B0EE6AD3A03570D3B22BD6C849969683D05BEBB536F91E6FA6519129E47A5D4DD32ECF8E33C78ACB6E2DFC8EC749641D21420CAEC7F173F8DE363A359BD30EB99518BF4190BDB75F6D7A736ED3A37264AEE6D3B44F01D9858E5DE5B38249A84E1E97FE9FF19D1717ECBFB05D75A427C1A05FF3C25E7DE9D41ECDF4A20BC63FF578C1C2803FD9914EB08F8D401BFB67CFFC1BA97AAD168E014D3280336075A1EB18086223DAFC81C45E1F8AFC071908317660348376C7E73445A165F601801B854109C648146439DF89ED4D50178E1E540779DC1F09E5446DF5E63C4B6506DF371772F055EEE761E20984F8E4C2336F82EFDC17BAF6D65450A695C9E35E3001B6620AE8B599FD276B2A6E72DBBD0F1656D97316D95A5230568208F85E11862DBE03D057F36915B797C04219F3B69E323509C34B8F8CD08003E4D79FF2CBCFBF356D1BAA8145297EAA7E3649AC3B4FB2E8141D0A120618748C2A9DD5E7C00B35508C470CCDBF167AEA475EAEC0C23D215F229A61898BA0C283B01079AEBA4967CB611CBA95E1F573101857A17DA2348C16B6E85AFF162F6D2AB893A6ACFB625CF5BDDD53D4170938E19AC93B217D0B2B81E647CC7D1DC3D67EEF85028887F6C7006FAAC2871B05983B0BA5581B744A6D3712CD39081B93530AB7CFC7176DB8C00ABFA0A758CD8307A99F110ACEDA66FD2924DF4241291FF0EE923DC36B87F2F319EFB0E1E7428D8FF2214265B7C299F73BCBC6F5991651D39A5ED54701B2A4BA1347331EC839BB5B7718DA95A8192CFF78EBDB359FECE727DFD4A8086390ADFE800BD6F128D3CD69C7A7FA9844F6CD47DFF423F98732A5EB303EF0F91B49F8F778891CF0D75BFEA4548E7C0D49CC12E68EA199667B821534FFE1646A14D904A42F3FDE71E64A19D2E008722DF6104E98A0EC766B71AD7F5A601C3C2F1C46BC8C6CA8702ABD3C54ACBC43A1B245CED4B761A0C10DD94EC0179E484FEF0A952B7FFBDD797BBF864675C55743B89BA50D671ED8A3CB0EF9FD30412BC1CA9E5399E42BD6EDBB9EAD74109BB4BFB6DF7BACA771A258E34AD80C3284047A88B69881F01F16C8FF3B819C39784C1501191F5797C37B011C12D195EBC0AF9AF97E2F712772779CBEC502FA1AA9EF66CB29574FEF386935977A4F905A1340A2BD2E57780411D35F4B39B332CFE1510EE7F4EEED19A8C405B719C5FCA2F662B137F4F95CF94DE58E77129131429304829F551A7125433B16EC0119FEA0C51C856B7D15FB2DA4468FC156E6254ABFA113904A35F31A4BA58B5968A658E3DD5C5A71155C6E16C805830DB8D2BE6B428F522E886BFE0939D404C0DB26CF80633CEEA58C42DC087C7378E30AD1C1B02CA74C06525579A548380D960F96A5D02EC88527CC7213F87171C0522D7A4876B42F3AE3319EC030FAB20FA2B84D3792895B62F8A3E7D7ADB2D997AEDB5E84F8E6ADD7DB64A3970A125E6227D70A2B006C768AB5CBA0B2812736654B50511CD477226DBD990CF68C9BF3FDAC5193D06EBF3FAFB6CD64CF56EA80C8A19258D8C02989C614595498B99A271BF0D9AD7991D0BD9BA50D8565BFD9C2FC0F524A8FB95798B0D4AF2D9BF51AF1B3B2E40AE2F126A7E34A3BF4FF0D228EE33C822DCBA41FF43060A034733F57FFBA9B95526BDB5B9BE4FD502415E8C1C521E81EB29B3F4352C1F1CEDBD5F8F6C7F8EFB52D1F8379938C4453227D9F588C41B5694B4F2ABF010B94EB6D77FFEC56A789A5790EB263BB459A84C2D015491F22011E48C1440E3C793406835144585433885947299714CDFEB915F1BFF37CEDB75C4B55F166CFB6DC7EF1E69BA5E2E03AC9A10F0F700A660AFF7440FEAB669E95B1874969901E007B39BC1D65C1746AE3A2BECF3C10E00BAC5C8B4BAE07AD4EA55EAC579FCA4C3D194264BF4C660368C75057168401A1EEF2B52ABCB9B11E53143D645FD4360A0FCAF7D0D30C22EF231347158EF56205CFE44F58304352DB" +}, +{ + "seed": "B401635BE8E33FA0D248F6F5E6E599741501A0F077AB827926E7DEA4E8A672C3", + "pk": "BCDEC84918CF157BB271A99A7CBC870E1F7D04D3B20B42FAEC33B1D41B550C0A9989F10AD3B8E4BB17FD9FF154B01A9E41501DCE6797720D2CDDBFDE8E0BA6CEF823FC5E62849ADE35BD996504D3220A24FEAE1EAF3D9BDA425DF010D11649D98B93FBC7513B8C782C0DB9D7E897440FC3C3B5B8186D57AB54290F1BB8FF3CE929CA5681849B51D6F1CC7E4136340DBDB90BC10D787DC7AFC342FCB93F8D332F779C41838A7A4E1D1AD3E5CA921BAD38B35D98B5A3AB78B0633657916CDAAAD41B63D783D98A0A0370839CE9914138A63B8F9B53871CCCFD73D0DFFB6473A6D73FA9B48035DB8AD4C96765BC014F460C84A29350EB8C1D43D43EC70B4D507B0E2F2EAAD653E81FA8077B5147A20D1DC828A90D8CEEEDF13EBCC64C74D51745D059295B532BB43E3E910188D1D57A6947EB94EB4F330C3AC8EE5C78E8BB1FE98406DC8346BE031FE55FB7AD2D37242A8290AA2F38A08E4B16B6688C6B341EF1DA0D8166B704DB0F363F254A4B113063E73372FAE0939A354B79AC67593E9325FD6C2451510244899B35A473751C5AE00AA919C937291B10744696ECB71BC34CF25C40DF84BF66D4D80CBC292005C5BBDEF16FBDFC329E7C7124CB759B8444053F69BE74B16C2345120D3D407993842807B1831AC96679FDEE72593C8C7BE3DEA2B5456F135CB536F3105101812492BC5CD9C8AD7ED2470C16F36CF46BB985429EB04B7288C2C468BD2FBCACE2CB73D660124B09AACE9F521CB97654871C89C169803FE8E62CD61FA35373F2ECE922D5D688E34A1D2F4A55E89E57BCCD0CEACCBCFF07BB663219DFA695C9B53632D6B0B9F0545AA8190584E11A2011991217CD46F798075EC26D3A0E6429A5E6BA022C191AC882CBCB57492031F85F22E2BAA0A5032E377354107BA33B70BFF808BA93730C42BE10D29C877F439243E0231C8DEA5066080547E5BC45A2D2B5FFD4B702A69835E8D86573712B6F518062DA75ECF6857BDE01E27C6198F79C68516B9226B91FB3DD7F6FA604667D9A5CBC9EF5E5AAFFFBBA7611203119EC994201AA9DA9FCD94865EEEAC6D65927E4DB04D7A4D115B119DE1F77BD8525A61605E21B3CFB4287182A429E14370615A2CEF9A2AC23784FDC58E929EAC095A421881B7413C78FF20E7BBDE5C2B0802F2DE80BAA8A78372FAF4E2FF881EE7903584073F6895C28B4B8DA913EFC0A9BC9EFCF113EA6C3710FEC2308F93440D5A9478431E82F3AE9527DA3500E7E44937A637F70F70BD4AA8E3C6B662CA326579C6167E3452EAED83A7AE98592120431C8C568F5723E8BC924FC0E9CF48617B29216FD15E0531E52FC36B4642F2EA7B50C307081139D4ADE79449DE300E20CE01B3CE1F115C8AC6EAD4CECF5DFBC6F34BF30EC76133894326C248DC33EB904D58BE3ED563640CACC4D03BCB72FCAED20BF63EEF0D2C48F6C4C39AADCDA8565B6F9F6E88A822214EC63C7D0425869F524EFD9B2AF0683E9D642410E797D8D929D3810F91804EDAA7DB074D1E06BA6A8608331AED4335C42B92AB16BAA9C5AA5366375EE302636C77B5B0628DB56DEAD05A76F35BCFD4F6566A156754A72F3ACF3EF0187476E00A2723A6105836C08675C9F896AC6353D15BE1EF3959036205E27A61BA4C072DF5E4FADDCAABFA950373060F8ECBB1223E9B1FA22F440BD423148E9940D8C43372120BEC7FEA4C8F0A9A7767E59B136BB458BE963E32951D87C9B31EDAFE66A2F6BB2E7FBA140939664D300C0380FCD15205C888DB991B7AD4CEA8DDA0283037443A5B166F0DACE0B9C5C4E935C10AE408D2F4250C15DAF3B2351CAD4D37A49B56DF652B501114BA06A3F88514A8BE2E450DB895A1A59127ADA2E3DCC7C061EF9CDB4B426EA13AD00FFCCB120C45B144FC86BEB397B390AE86FFD007B20FCD271EC56E010EC34EF2E916AC5D3F2EE8438AE34CFB53264F8BB4B060A4B5661FB707FFF2730D356A6A7344488DA60610FEF59DF33CBFDBCA271349826481049A77D9FEA09BB8D59136A918ADDAEC78AD7E673AEB7D5912B15241B7E886829F95DE8B391BA11F245FA1B106594500CAC933E438B78B0C7DE70ACA34B8F37A25CC40C419A1E626F1E0FE2BFBB62EC6717502FC5E469A6D5FC9FD866C17BFEAA175183F582CD5F6ECE90C0BCABD52C726B2BFA29D6651B5E7770FD12E1D12B9B99AE76DA076EA418F55F34F961C433CE7F1F35D954D04CADCD5AA2AB3C22A782892E5B2DC274FD009C3F59F157C3033358C2306C9822D6CBE8DD36E8D1D8FA228CD11BAC928575AE2EB50504BCBBEA36E383C1AE31A83510D344A1213AD37543F38E5009788671F4CFDB0659ACB773E470050BDCFA86035CEF439C68CCC8268938584066111BBE9DC495F694BBF77EB465903BA6EAA5B6D35FE009D4D5D268A4375820D18F19C5B0AAB94FDBCDA6DEAADA71CB09C2B6BE67B124F100BBC120B3FD20AEDB07DA8DBBDB8B2D0867D860C82BBD97F31F1EC668A55B8FA925994406AAEA47942650F0C5EA7623A46BFF43EFC24334EAC6441F240E6285839019B8FD8B0EF77A548534C6EA2676EEFA0521C58FC906C73AD1AA9B1626F136A6F19B8D4DBFA964BE0D717EF21AEAE8DF1D0882ED1FE087F4600916B2C37C9EDD2C088D7867C472D03B955FD575BC640F9C793AC3784A59CAFE0BF802AE9A618671B4BBC5606C2A2CA70F2129AA05A3CD81F11132ECA59D5026024ED99164D65439869647996A65127BB78B46C38F8112D883F08FD2D62A5A80DF9E099835836EAE4068C282E422209290DBFCF7CACF1BB029E92E5E8B5C7FA1734088E72634A6C9302A1E50EB7B13F66414E539DAA46FD15C4F494AF9BDC78DF2887CFFBBB5D9DAAD21690B02CDFF0D08C46F15A1A40C4A53BBECAB3E5914A6D5B5FFC1231183D5F05794C6A9BB8DFE2A75ADCE776BAFAA5C6EFA15E77D0296A7B12293562FCD6B78456EFF224E3B14CD69B5A92411D9B31C3B385FD660793776A622B04F8B034D864381278942C55AFB18F7A4C181620F6837EC8D240F25A0DFF45D873107E2A005715E84EC11DF91DD11E99DB729C62F424EA39F27775404E2BB0E4EF42A1053FAD6D12C531304201D0017C08CC906266D07319B3EC91DE81FB9480D3BEE6C168628E5B8D817B91A7216D46DDEC6AABA84F9474249D5927B1B5D3F4C6A91AB147F820A58CD0202A8CD6AFF75F51F9995268CC2CB3DD55A210008B667EEDB1057B067B26F4D4F11AD58C82F1DB8D4981093955C5E6C3274495AA80E9410369DA8503354F23E783CAF4E5C0D66CC2D6B632E8C45FC8EF4C5D64B6B3FAD03EB35A07D1A06593ED51CCF07FCFCD29EE195CDCC55548B8B125CF00F76167E9941FE06C57A022869425F6F5C4BE87B8DAA3C73926BF52C47B6FC324A7C69CCF9C3550167DD3309E8CB90C4E1070F9375128BD9D94B3781F5103034980017CDFE3622952EB3F303A8D233FD68F7CE52875DF1D2D35C62F96C487DB09C93F36DD86DB4618F62F6511A942B0BE2819DC2411BD0A50069E3DEDBFAEF8204F711BCAB3252650F6E97C1F347ADC1FD54DCF4B54B5D4E495C451A069B83CBE84084CB7B26C2254AC5560B712C7490192B418C21C1AC73CF45B6037E3816568709E83C8BDE8DD5C25C5C6CEB7C4C3458053A3514ADC5B9796D1C8BB0788A", + "sk": "BCDEC84918CF157BB271A99A7CBC870E1F7D04D3B20B42FAEC33B1D41B550C0A7834E890B7C74613013A6F22A3FB4FD211718E21EE7F2599640977E85E317B9A1BFC39D0774A06F948BC46B114979737FC2BF0A69E043BD9A59E1BCBA7D22FA4FF93970C8D0918561C28B8B12445158AFBDE2CC362AF25A6197519DFA2E4991D901011D2A02993320C4CA06520326A22348D0095644B364A54822489002C22162940C2902495644C3026CC982C0215665B964D48A04104804813152DA21431509601E28290C0C004C3806C091772D4C82C1098280823711A45721C0590549840DB96800C878010A86108104C02A30102B064D1321211C0911985510313810B108DD0444810995163302A4C344C102692E212601910514C480902200A1A46301C9781CB967058443123138010400C894648803886242230D4264811082944480A10A86421852C50B225212751E140054C1642D4388ED1340D13447013B86C19250E2126615BA664C386040C999024042D64B025C3C0651C319220C84503A19048B088118444C32069D9409002950CD844624320920B142C10442CA2188103A60D09B37058C26C22933024950923A5511C3225C414621A08650C016488944804C84861484A8B144041B04918444E9C96605A004013374213362CC830000A35914AA44C24834C1C17665418894CB84D0A440A0217500A478ECC046012288C1320051317429202000AC26008A801C9442C191949C4221059B82148442220B8681B144A101390C9C26C20293201912D04374C2489884A864900C86DC2924008074862286912364ECC8624C324250444204802486344325A06659BC4641C274212424651B26C243684E12068C1B224193001A2C08C03C370C3468E432064CCC20802872523292A0B999108184CC2882403190043000650C44C54004820268ACA204608460C12822119353040B02091164AE0065184800C90925043C270C9926454B8859B88000A2101121400090608628604CB1602C3C82508398EC0C24400498411885013136294928C61B8600C022ACA4020DB4069DA08864A3469A088250B0240CC96040CB10D0A9825A18400523442400060D4C8708B04101C350D42A2451B30009C140284C66C0CA064833850D848208A162A81A260C190894A020550B861810225111052923688A0B8311207425B929104146E5C266204A52D89921080228188828088040581026688840019338CE0340A4C0202240140D3308CA20266C8348120B968189425091410CC922058961159B42D51C08183306003928DC9261282964C8BA08189488D1B44704818051936821B010693046E22450082C80549347148323089926154348E24C44423B640518471A39811504446E210261BA92059A229010781E2286CA18204D00070E4182D0048614028528B80700A094A48C640C89891DA06248C221124846C412846A386914B1052D932420BB691431669C098881C3992CC44698A8831482046D98689134770DC9648984805E2188A02226A5330861B8791D3C4610233908802505A34518B248480B64D01454D82A0000B3591E4366D943624A0249201380E8484680A9441034688E1B2498B920C89045008093260444112C40D1882698AA46C8BA22C112091919244C1206D9AA4215BA47053108502070C5B164CA4A66D11366108328A02B869232602C11680D0822D083522D93684184424D93402D3A6459428495B2480081881E034498C4232C21810001664939270C8468A0381711425121CA4019BC288A240849A88642097041804000A4061A28890801092D3825112208A0B2432C8B42D81143222492802048161864D83064C21472E22408A0B3072E4860018A70C0AA90D1385699988308C2048E41472E3942809497104B56114A72099C870542825D9126249C861CC3482C2B6614B18449B2488D4104EE414484C0082093921D82660A4B80DCCA2840C239151384D0235722025511490015182214B066920234CDB3692C0964C14C0410335819C406684C4909A44600BA80803C86864140623A42824471013208D201549403890E2B289D4A0215B82650AA025599684999441CA208403373223B77058A89008158D9392041C280011C89001851001254D8A368EE4A65164B06C8B488960A24D43404622C601C9A860C000220A2140130706C2340E6034248414918B0480182109194341027756188942B1D56A02D7BA54F49175E97242D7C7D88F8B76362F6E00626D5C43CA00F79BB798C716CACE203B87156417A1FB7C8329A79265384F842A03C67B6033CE4569AAF56CE5ED620C311C8747966BDB91381BB3612E14CD3BDA295F0F60629B22CEEA9902AC68C12303F7F6C6515540176509404B164CB26B20FEA5DC505E79EE5E340A9001E58BF1CF1895D64554BA65A5AE5B6854D0E3FB55F882E8F4E0F19CD4FE65BE4950FD1B469C285F3A8EC333E386D5E0E4EF77BADC6A7D708D43BA1DB88D6A65EE2AAFED1FBCAF25DA02E1BC70762EE598140F8D5707CD4617424B3BD7EA31BF8905E5CFCEC6DC9CD5A304E160A2F572674B8CEC6643319D8C8CB5D0AF800B88C39F58AE0EB98C422BC56DEBC63E21489C8B08E5BDE780D935E5CFF895991ECE3B1E3ED0A7C73023063F620DFDC19AF60CDD2AC586A77FF592ED2213E18A00591ACABD334D159112221B4937CFEFB52F6E629CE8BF43A0E68F5A6FC04D91249F4866BCE3D7552EAFD5D4A670F5646065CB63D6DD0CD169549070E7067DFE219291097F9A80013896E8CE9A98C8FDCC57952081469E7D6176447CBBA056EA5F7AE02D4F2EB01C344777CAC8179C65650FED7D69BCB3157DD3C374BFA535DAA86C546F7011E24F9706FC7C1BD2696C38426C7EB8B60FA37EB067C7F779ED8AE09BA85EFD5D6CF15CDACCBEB2D3576A9119B69272A369A0944627BF1ED78C9BD1FD755A0CD1C3A35A0844F5E838EFDA89A69D3142D98B493B9FA013BEAEE7711E51CBDD7D6BCEABAC57DF965C87D204B4AB7166CE5E0A223670A6E1A0F2C004A830B0458A92006FAD8CD67B5587B7158527F6A8E3910CBDC864E3BE2434BA8F57D992EF33FA37464F51AFAD86DD8E9BAFBF6D515069CDEAE1A7E2E8E74AA3E9A6781F23652EB966C13DC55ACECC623B2D2DD6D0E5B4F4008AADDA7FBF552BF631AEE4811705981ADB520C7409876BC7C6967939557AB479C75220C035EE4B1C7FE1A799D1407A2FB00CDA0FADD3939182426BC85BFE28FD6B14DCF74680D356E2D405DE7203B6620FC5CB75BF3466B6B121CB10755544895491911F4246EC926B4CBC41E6E32E0FD77C375AD6880CDE407B5D598EF1E100C859076038DFAC70AD8327B36EC9AE1BA43339FFCECEC16922CB2B8A68A6D65B62F3A2D8B549EF3E7B1937FCB779863D520AC99E09DE7DB053C91923ECA1C24272991573E2252CB5448E07A55A59207F7A6134B25032933723CD9DA9066D937DE127809EBC609AE0C0F24C6FA8DED0F1D828AFB99B99FB392C247C2611356CBEE8803D93E315B5A51E3075DBED3E19A239A695C5E5AB5390F8FF93043E07EC86A40D5536014644FF07B8615BE29B3E05687AC45561D942DFBED128B23C0CDFA00C2CD5A31C2380247695B8E54E851B0701FA343F264AF65570AAA31D649EACD650634E96B7DE543F412B44B5C50B8A6876CDE9DAF9F8489DD40196F28812E73F984200102B883452EF326CB15C30560404309EB5BBDAD0F597ECA72E315A0D68172C28F0CAED2CD9395E0526B009CF272CF44F5B0225E5C031267A1D21127C793F5FE43C1F21088D6821BA3629D9ABF69862A58329BB4734520C5CFFCEF5CEACA0AB27129CC6C38EB476DC689AC55E70A73448FA082B520D60E1AC4ED624DA8DC0C4DC388221C77E5BED4C4EC6CEA078276FC7A0C896B825F87B5ECE931A06E313AFD6837FDDE0A1EE4FB20E19E31F83E6DEAF585E4145C007B70BFB1F349353D3C4682CDE4AA15F74CA68DEFAAB2F73390FEF3701286B3D6098577C2796D53F0A72BCEB07767561B8CD74394015E0557DD0A08832E56E294236D70C984DA72618AF1C4168A43C29DA42EE5FF22D194139754C14BFC9E3DB998C8ADAEE2BA207881BB3988DBE11FE2F66A243ACAE8E4EAF497969426D92FA8A4345F01E2590620EB5D66F65B1A2602F7DCF30173A3BEA40E52528DB7D4415517BD3F21AF15DA3AE1E4D14C12BD9FAA1C290A4C6ED54D2EA7109F44D4ED6A1DDA63A1B98B7EABEAC083EA3FFE1818F03F5E5647FDF858E16A72107F46F85219EF35F831AEE7A27A4731A1D24976CEB930A0F8A325C23EA3F3333490E8F68157C6B731DEFED42F82811A50967E2779B5065F988C391D0AFF5C690DC89C73FC193AB994A80BD9373FFEF654F49517B81536F92C7C811935F3D34EF94D61C1F28477C3B89420D5EB1FD39DF402982FB267190E0118E612D384C7690052477E255BC83D604AB9B4B43C716E8533AF82F942CF273C9823AABB3BF1281601FEB7C86FDAC680DFFB8A7B1318E72F4BE9FA0CBFDD83BF073006C7A9A80181202C924C79505E9D9C82C81F52C7526AFBF982877D7F7DFB2576E1D330538DE0236E24A73739E8FAB92303FA99628E463DCD0D8CF300A234EAF7D00F3325AE876D27DE643E708213FA83C4E845D8B622DEB03C344084E3623DD3B7AFC424FB46BA1C81E4BC297B6EFBDC0AD025A727354DE74609ECB22EC5E92A8364469EE3B3E8D9630DB1F0C053B96CF2D38D72B798E769A56E003DC1B9217D912861E986AD4CFD2E25F0E25A59A60BC19130B45E3E5600D483D9A8B1C9C0836C4ADE168D30B8A590A22178A755496C1BB4D439786BC813CCF5402C2DA9D0649BFCE8CED93B8C15A3A9C4B34EB22B8C244AA39E5ADC3EC51E9218699F195231B698F46FFA11C6022B76EEB5FB6CEBEE1EF2D55B780969629674251A2E401F7071C948CA1541E2A8E1CB8949A9C610565E345D98A28819A8D8C1A6E950FDAF2B41C1D798A6EFDDC807BA931F2804EC61231B09EC32D9E752D3AEA3F8DE889F17C8E4698EBB7C491DC74721A0C52A4C821994334F7D97E31546BF7612C2B6FA368231A98DC64E9D4E491E241B8B5FA6E4FA8D9A30D4729AAE430C6D1AE358374ECEA58E07E697F0B8E0D093FE9E1D036ABA07F2D55FE9D030238C0DB6EEAC21DE6E03028E1AB991F74A754C2149630FB402C025C1840412ED11BD53BDEF26FAC36B0F03F48B55CF15773F8B083436BACF90B1F3587A782D4E4C50C7324C2BF2173016892C4D17B4E9A4BB8DE1146BFA8F6E9810B3C1DF090FC61C242E097A631B5CC6D468A9DACDFFDC660D32CE702DE2A87C8ED1613D8AF09A028B2B4A716388B0533A41F6322622115C1E751581F06F1A71CADCAD7337C8881455E3C2B3725C8A82805E6EFFC0BD89A0ED3C73A05E5EAE505D5BE604330CE88B17FE43F17262F3EEB06F7E62879E94A861614400A4675A18D08C02F888F397E90C5CCA7A5BFF3957970864E68B611EC6C957FB78D799DAAC8A0B917DD94B4BCDF3152E2B739A24816A08013D7B263CC85FE4AA35393C54E85CF5F2E98F557CAC073A381019D288201A7E8C93CBB5A3CF605C80C4FBCE566371A3239B691EBC0C67584B934AA243303D1A0AAF7648CB00E75E3CD8DA7D8AA71E41C0F8CBEC1ADDF27326A9D5C4A0A4E851F8552EA8EC9C9949363C56B33A745E94B48522748250B498D447D3E1ED82193B48AC2ACAB3F87655FC3FE6DA0A6C4D9E75278A21938DA66A09053492BD4FC29E3743DE3056AD202F3455E9BA37F43EE0B74BE2642A537F3B4CDCFD2682949F6A2F869DD4562268B50766C676D01D1CC425B206753FE2EAFD9C45E54A37BCA002D2D2599ADF13B43740F6C0F912BDC68B087EC427CE4FD7CC87B4C0064FC7BDB59CD9F17CAB3289131219A0CCB59851264FB44CE4D6DCDD4C85C9015499BCB74F68929D6E6191A196900B9B662A80811E613C405241A73C98B84E2853709A508CFD5B954527CAA7AD15B3EE77DD79E581F19EC284B54E56F45EC62EE6E997FE8F6C2501F12B544DAC253771FA65531A48BDC4671F3FA8FEF9C06B0A964832802778205E8A24D6FF3498703D737A49FC3A945B5C84F9810D354385E03BEB38269AF76A9C57501D2FD3BB5AE83E6CAEB143C44AC46B3129FD3DE7935B73F6EBCD42212143F3CDA752E5453EF3BA8E13F08D6E881094B86C8269FC2257E2CFB06C82E4CFE65A91FCD70273FF08F461D4B2ADB79279443C885F209301C4693A74EA1E1E13C4EDDA1230160134276B0B0740CF8E75CCD61FF4C2948DEF15763CD2EE5FFC79B12115EEEE71DEBFF1A028AFFAB0DDE512D8C540E9F3326A86C7057A0A59B800010919A8171500EA71ABE779B7452E40FD8D31194F7D9044DF97B2AB6629A13328686358698B5A04D1CC3B38A46BF63C10A08D924D93B8EC49E1936E2C8CE86AA65AE2275B05AA57BCD6A8B641739A9FB5D941CD53033F4168FF830D04A6197378880092B6827DF9B1C8D5C397C00FB6E7F151DD93778BFDCFB1CD4BBC797A4D3E7BE4401BBE012D102AC8D8540E874D44C641834F66CA534BE7A5747CAC2ADDF4DA703FAA6BD79712E8B7C501D88F4076B2020E8E99CF95A0EA0D0B92E8A779B9AF6F00F306D78E397AA2DCFF603CE47C4AE7758731B20CE5E424EDF63C6DC99BD3C86037E46D64025A8D6CA7535E3D202B60E335F38E62FC4A041760254FB88E9E9FECC2C9F7EF7B2B9896FCADED7E614EE57D3D0E5E4A64BD649B614BE554838E38170E0748E5FC5850E6D9C805AE59928A732B01595DEF14C7B80A7D371CE80238F0448D7E43E37BB7CEC15304950E778CAE35D946317F796B5A8FDB5D85FF17E4D29042D934EC51C37CCEB4045077D212AF9E039F0E9399F75FA5407726FE2168F50CF6380566AA47B6CDE62" +}, +{ + "seed": "BF2846DEA3C6081ACAF75BF64AFAFEDDF8BD15F91767993B2512551457A429ED", + "pk": "471888CD25618D5B2ED4DA93481BCF9A1F4A4E1B781556328FDAFDF8807D1273E9D304793916EF99F55AA44E7393B5B29F8C8F3208162C338DEE1D78EC15A6B53567C948686D7E6C9ADF72D7FCFD252C0B0BAE33FF0CD980E10F65D91520BBDE49B41BE7F40F250DB70CEA064E0D553E3878E10DDE3A4FA97374A3717C5CF1CC691182D6B6030A6C7CCBE9A06B26937D07A83190768BCA23EE0D53FDCE3C6B8074ECE6B7AE0DAE5FFEA2DA18A34F7683B5099A50C32B53A7F564FF33E961153B915AB9FABC9E99DCE6B9D9EEFAB3801E4FA1C0C65335F18D45E9E947C1D95C41ACD02E3E64427FF751959A430A59CD8FF7D3540DAAACD99A668FB4FE3DC6194E52BE226FD2258DD487E8B3DA7326A1E56F0E33BCC84666BDFD9BDDE4CD9B3A2713DAD664188C811C6381126D4C4449EFE45D071818D63F7E2B61ACEF9AB8E70C643BB14B223CE465E9F06308CA83C49B69924E555F5AA6F2DC0A919B86A69B7DAEB2E4F1E1985E15790A09D8D34A81CD5135BEFA07606C17DE9E53A1B66AEBD2542D5DB491DDC8702C85781933A07C7C5E27FE9D7AE6767289D9F98B1F525448B47933C114B7873DC989093F7256389EE428E7F704C3A254842F51DBBC882967DB8AFB3582BBE75DDC260C52C0EE7E46A6B407164FBB09048DE13183A787D99E7ABCF6E485708E5263A4F568A2C4CE1AA7AE0613A50B87C5EBCBCAD91D2D5ED44E1575E8C71C55042DD445AEEAF81957DA823C175A331D41D57548A9ACD0872AEA3AF4EC7262C4E14597CBFACB123614170D8C9ACEB4A93581ABEFD24CFF5AB03844E2E95FA48F265D58EE0076EA9F44579C5D440D07A77B0F94B117B9217311ECF2DFB8BC3EEE5686EAC9F8E4150148BB5A824C379EE7E5FC383CB5D964E564826BB4DF824954D350ADC37CBFCD4CB3AF4061E778885BDDC7C77CD52E2FCF9C76656E96D432A57149DF48EC694ED04B45BD58B2616099E7997C3B7FEFA18A88E6EAD6020D959E1427B796DC14AC603F8B49AA90E1FA56A6097C97F21F327431B1590063B7C10635BAD500EDB5E6EF985F1B321203E5CBE358F8A4549CF16793091436DF517F308CEC8A80DF728DD32D8A76F7C586479AE7437B4374073C0D76C60E111EC28BAB200453BB85DA6DBE5776EFDBFD22F4F7D165314C269EA33CC0A6A14891974220B2531238B896ADC75E5AE33658AEEB3BC4F4954B44B585EBD1DF92302458FBADD906F4A69E0F0013C385935BECFD97C8BB21A127E34843BBE4D7C82C9EF7F91456C0451828620A151F4CA0260879280C14A27B0DAF873E6F9D27CE1EF9B8E50F5BF896027B415427E633C4F2D04B2B921E1F0B85E34AF2F6D1CA6063AB1F4098941330A1E2A960C885EC1B1E36876C725561CBB991B37CABE41442F439EAC01CC76153C98AB1D927C53BA0869C6244A48D2A235F325932BE12A804756346285E2591FC0EA0C5A923EB22DCD3769C22EEE39F01C211F7FA67FB1B042D21B895B54D07997E72E24DF13C35219B79CBFF013A9DAC527B230A66C50FDEAC820CD1BF82307B7E364A2DEC1360D9C4DEE5EE3330530D501D35833208F8CFC2C7966347FD4B145F7A457DEC7B07EBB60EB8116DD848BC10FE8654ADC7F0BE98642379363AD172B8A472243350BF2C5AC80208143A21768DC4CF30AD65AE2A1B887BBFE47B225B3194138A079430C1106A5D5FAD56F10CBF0945E681BA31335B40A424E1FD7DF2405628FD133BA601A9A8BEC494969865E391D18A3F2C93AF707B9D3FA2C1D909C75C0C109F4166CA1D5EDF1210A5F3A426DE8C328C6089B40E21292688B546A5017B9AB038A153B311330C7054E0BA34652353F99FC5E0C4F196F34D10EFDB967F3B08E01AB74C2A1FEC819FAB8A5EB71DA9AAB90A0C1F35EE13B1FA41EC0F8850E127E8D3A02B25FA68D5ADE727C23C02BBA161FEB29F7C6B12C887EAB6EE13B96921A1838091D7BE76394E7B00FB61F93C29D3D8E108F2A510784BD2FFB788060475F09B96736E2802D9C0FF4BA636C7AA1402B4061C9B7CE8B8017A17DFCC571BB4122583D7164FD93D58B4E204B7938D8A29D923CF59AD96483D4EB15D8272D9A5049A6464BEAD51881E27982313A4EAD2B59CE76CA107279E1406459F966F548C401273ED78E0D7A39603CE8833DFFE05CCDD7F8BD077938BDF1EFA0E9C04581AE267904C0E071F14CB7C03C47C123EAC045D023867D5417A2D79AE49D967A13B645644BDA1CB4C27475D20E0ECB22AE89A6F742FAECB1E46543B7723C782E5093A5E905924AAA37D9469C0E06A64AB77AC655E7BFC7C6D91BC4CB9A7333640827288DE99D6F0C903B4BCCC0B3B095874D7A435759F7244E08C5387B349DAFCFF6F855595660E81F691F073C33C9D9B21DD9EBCB6DCB86333540B6DBAD58AFA0DB6BC25E396FC1D54F74B57C5CB127468F655DC8FA27BE4C5F0B47DAC99DA66454CBB3D2E76796A4199370B63CAD67F8F4620610CF6B31C8C4E05FA696C3670799D7141A1CF67BBB1BBE3BF8EDE42D0C76125B7DDE298CA1413EBA6A767B3AEDAF89666A882C5D255EE76FCC79CD41021DAFF368BA3A20FF217B76E4E3A7CF9D487820AD6AC4A2A9B9599CA6F5223DD4016DEEA12E08E48E877199B281E453C4F4B6933A5B2F86461AF01A59EB1E38704C95C46A5D9C54AC66348EE19BA3BC8858F000E18B58F350DBC1414928B3F7475497EB7015AF29CBB257899615D73DE8AC220E424846F54665635DFC4BE1A8EB017870BBA1464D799B89E268A8A26861A6B038B7748CEE50BF093CB832E97E40BB978E93D8085457376BF43D1B299BD9E34DDEEC0B6DE0FCE5E0A8DA14C1E22EF0EF0F677651505E2C4E4555D04CE7FBAB8BE12FF143244E58D8BECFFBBD84F1CE3F55B521A2DE728C86B2DC3E30A9400EF325FC6526AC56C81E09093BD9BB93CBDAC6D1309A777EFCA27EF9D33B144EECC641BBDE8A4CB63B3411571BB023663E893F2020B28C98A33027D976C82A2578EF9D684C88C7ABFF2CC4C3E19817E3E8CE37478F32CFE2ED494BF0DE24E051823F8842C86D5EC5A0C9EB87C961935CB63DC5B8A4CB62B726F3C3F8416B67A638D4D7EC476305C9FAA38B1D2D89A61C68011878797A5C5E1A52205719D1327C9F26CF632F0365C586B6DD76282EB1223ACA24D41907543A17AC4B17674493039CD2E5B3C8BC15B2CB2A0F4F79EFE3575764F166CDC5351AEB71C328138D8824E558B87033B0E15B2A14566084FD1D72F375D38712EFA9238F6A3B799B5F6D92034CA1C298BE6CF526CEBB371B2240A13D0D8D6515360CD88E2AEA4DA1DE424DFC7EF79247A526E3D52C09464BE70731D2D7D409E64E4F1C45037AC85B8B3A40B53AE7A5CA4F3527ADAF66D509BE5714C94F49C205763577675452952D34992D4AC89426128C73F46108A3425BAB0E55291FA05DEAC792E91B5983BF1374F99E27946B676A5D7422579910C6EFDDFE80199B86578B40875BF7562BDACC7A9601F55D22206AD785A73F00E8EAEB70E53A5643805B1E173ECACF8FD1A70F3CF38504B4B021EEC915D8B1B2A835EDD6F6A22F06CF33C2C96529FBB54A3BA47FCC8C2E7EE9089DE5DA246A143661488DFEBBFB63CC8D2857462F55F009FFA917A63FA87D046C3F922CA3F9C1B650EB9657763DD91F4", + "sk": "471888CD25618D5B2ED4DA93481BCF9A1F4A4E1B781556328FDAFDF8807D1273A8F45A2EC134BF040EF6F32ECA6ABE19C0E70D5AB5AF5D284AD01EE26877180F80C71A31A5F3CD8B5AD5039D4CC8F5EB6C313B5E2D5236E04F2D67DB709263EDF3F7168AAD880C3EB854DBBA92BEB2B1F841BE9047F3DFB0D1DC975F36CA9CE1DB169101180E002369C93685921824E33246C346201A26511AA56DA49069003402119224A4082E04C7480BA66C61100EE1A04104C58460822102854C8B226D9426714A0824C8422112B26582284023873000947049460C2397090391708822621C41111212444C008019A205D1B44D842471A21825CC386C1342100117840B446A042006911042C2406682C845412625092560DC20254804511AC1919C2060582431DBB03011400A80347218878498024D19B38C1C388E92984991281019996D19399019B448DA986C08916113886420196A42C46DA2404889C03083C210E23408624484531061A2A68D81A48D99C88818B40D0A27428C1626E2A62800475108C309883885E112311CC39109910C59383110338E6432904346821A10924CB844244740CA3825010891A3B8819AA2499C90401C12310AA0480025605B1464DC34091C21810A116293104EE2986DE430868228625232059236881B017112071241A0109488204AC81002A128249820643850804622E2B28018B7442222665C303288986D818241CC904983C690A0980544A6281AA688140012138488E2A03163B8251184701B142604B13109A25013188402C38DDB24255AA64519338ED89628034665631420C3A050510429D414098C302ACBB4845C225289824C94C2691B268821458014B21162B00853C42410112500A8285B384181900CD0008E89184C1CA085DA244603170C81426491B0400C93685C90454BC081C08691019020501625C4244004437144062D2211324C34229B06666386610245621B4252D8128102478C903211DC3086113502C93025D2B42C1CC38413A12C01B84901238DCBC84D02B048D20449C43604D2C6254AC28C91280EC3364C00018862A49154444CC84289CB840D941804083788A1404A1C058D1B47845BA48524188D102011589880211441C3421153B0101BC92180866C0B300D12C94449406CA0A691DA14820B0532D4B08103913054404E504882519604842270839409C996490416668B88405BC240A22692C2882DCC808964B24D00180553380AC288319BB844E09684C3488E0A480CCA1692E042311A138042A86543360521B1001B2891E4422AA318855A804D5C268264221010450D21B88018A1445B864C03300A5282841927248A048D91848819A48D0C1140129981D0248964C63189068152044A5028252327309AA88523347080B48983300E88160080A66D0A9590C3481062940D49A289E0B270010260902801D8906092A86D50B04CA2B40C9B90611BC6089A4084200391D8C61009328619230D13C15050246E59189019B2481AC090E300818B944554907058B6008A26214C3264D9008184A611A0B28022104E64962D9BA86851B28051B46850382D23C27012B14449024A84A491A3C089882241CB8440A006711B38250CB83110A540CC4632C4180DA4004601316402280823B54540B0899292711C178D58A010129225D3B26D01948523336113012001058A4A8445D236315A44802124414B428210998954406E1029411CC90949B4701C1384184992E2924C090489800026CC28229B882CCA0289D0824401498AE1C8080A92045C240680020A81368E91088A1CB7601B856902092C1923518002642194888BC0711294308914100018684AB66463220D5236285C384D1C85641345900B492964204219170D9B3032D0A25104209219222848A2841C2304CCB2311C941021403089A485401269D0064E0B485080024421244D0208704922498A828D1CC810130144149371113746988605D91840C28664C1986889202CE01640048730224024220188CAA08422090E81088659B4700B212188B46800301124882D0206722125250A196510122A089501E1900420100851362A092345A4882183A46DA004909B380E42900C11C40CDB365152006A49A8911C964D214130130092E0B665DA960DA0080614282D9830650A23510B3801924001CC080E90264E23469283964193848052C845593244C984682028421449615F92CAE0C5784CCC5560F4488F89C5A8234F2D32A8E68C5D1380EFFEF6C6C3F320328F0E3955484A42BFEBFEF943FD69D962F5F6A78A253EAFC70495F96743FC5E93F127C180F1EF7E7A7DE4221F637EF2325328DFC314C96A98F66FEF266E5E3C126258B88352A244D3ABDE3844D006C32CF335FC8C2FA63F90885DA39F57B54E96D6C7D002B08427C7543F84C415CD0B9C35BAC084A84EA5667905AD532B9B96DF94972DC41F50D05211D49522F3205CF7BD9B9F43BC24320464B22B6A7590D2B494BF8C9679B36CB3817F2AA0F14070712F4D69E2A878F32EA8417200B15861014B686B2838FAA7EDA182CA8FA5352C8A9D86217C1E64ED566169925A64D0F9FFA46F681FFEEC859618FAF0217A4150D762F4297240EDB382EF9AC482642EB18CFAE0C2B6C63FAC6B13A0CC2EF187AFBCA2DE9499D8F03B7808CD4CBA3C01871CD18C770DD07E18EC4087CF88FCC75F57D5A7B48488CDF11D05BA4FB5B990EBEFF7D0FE336F6A09B47BBC587223CBE9C0C289D4D822CB6603D9D72585D9BC1B26690D773921442AE98437F669EC1E5D163F8755F01B79B64C49A4749CB92AD35CEE90AAFDA8D4D98C56F2B2C5C23DBE4008ADE3C2CE2B58936C991C1EA0ED68192024A3070B23BF1912BF125C7EAA82DB74BF70443CBAB50313237702F004AC5C9097534E7809025205F52427B5D943BCEE4B5372AB0EC4A7D5F56225FB2945E5FEE0670CD4701D4E83F876B4E35DAEDEC6010EE8050704D4F652DF7AFD0F76CA4C8AE495598CED4DA6F831D25304B0C3F8DAE68EE4587315ABA35F0AB0C57E5F8B1FC28861B94EFFD86A4138874F8859990003A7CD06C78B658F98D4C527A51449064A18EA036AD3F12A12232B279DFAA066A2A6BB855A9BF1719223E98AE78CB16B0C2BB6F01BA01A5EACBD180A5F55486D97C7C004327F70F053211BD2AE5FE5624600E6BEA4A7C3091F7D55BD0A08707D00A48BC4FBD1F5E0186B28FD8BEFABAAA378C500F0F7AAFF5AE10D7CACB3881DB61E0F25D06D4521AEAD68E0123B06C8EB36F1E1F4DAA89FE87FCDC965EE3A3914ADF98AEE505652881A23005B15D4495DECEE29FEA75E8416A73070157DA6CD4F8A112122A342AF5C1CD7175FF9878A328BB94897A79BD38161242B939B8677A161289A6501C7E404F2D26569B5203AD21D2E41E515A2B44719A7C51AF3CFC2DD19E939A6E820093A88E675FB08AFC3D681F7862F3C7E04FF3EBC47C6A8937FD5318F21E393794EB650ADEA8721869F12FC2C36BD031DA7A0F3602E143227696B6944B882A1D7F24BE6C92A8CED148002EB07A89BD4ACBC7CCCD61D79389D8959108B5FD4FC6EB6335F320D796537C4AF1D2653889757762F2FC640B546D58F30CDF6CF19849478FAA2A4CC9497B08B4198545924CD469A92DEDF4617FCE963A12F7E8DC470751A350A700B6388D07ED6968D73C92789C859BF8F5B636D62C047953774C68577E0202E526B75CD4B8C040C7ED79CD71746B644BDFBA2A3D97059D4C10F4305EE36EB5EC0FB2D4395B3AD76F267737E494AD99B0BE9D04864C08B2F59643A3887F08BA8D1262CAE59AC5EC8BD6699FF8CDEE37B62DAACC40953C1B11F11801B46598C5465FD466B48E5259F39308C1C0CC6E03570BD73C167418C10E4776AC7A88BDC0DF6CFC0A4374DBD8C46255D21760A05F2424DC7B1C5289498E434AEE87CB819E7CC121AEEECA145DD5F296AE3E9C4BEC1CA869247DA963A32D892808D5E21C5AEBE225FB47BDC71668C7671D7AD3E97F3C2C7D9F6922B723BB4A1C192F2574E4AAA172935BC5CC8D3B8FE9DE0FD6495EA954A572BF8F99A773899BC4D0860C6EE0F7124D2E8BD80552196A972B92EF0DD02C1B7B93ACE16CC072B3459CCFE7AEB8EEED6B6189A5F6FA2801C529DE277BD70C0A74A256473A24B9BCC9F70C50247A8BCCE4FD65E6CD3B0AA3EF08748075B6F5CAE090DBB0455A95C1A01F0C4132EDCC96943F6A055FFBBF014139B44E775378C8306779AD387BB578D0F6C87A17E50211241945C07BC688A4DAD2F1C67727A8318B4312AF75829DAE2642A199E2519427C0C589128F82A873318ABAF65840240881943A09D04CA3775A5491D8602D631F4A8202C5C58EBD478F54104378328630B2DBB94FAF7346F023DC13BC99E0098474BE922C50A0C373412A3C0C5CC33448560A35E98A8BA8CB9AD6555A96F9E5FE5634DBD12C6EBA9609598262C87361775A4F89EC1876DBC29B382CC3F114E1DD2193FDF18D63E8CC187F5EA984F6B7BB02E8FB6C56B8EB0F27A0E7416F68E8CB2D102D1548126EC80220DA3FF32131BFB793325301DB1BA905B64F3878FC7FF8C6880012FA168C59D901AAF36F15621DA4355E1FE9CE11EF061393CD78BF04BE8BB124A11093E5A7E083A62FF826971DFAC64E455C4AD8AF54D156C34F09DF10EDBA38F9418D6502F781421E8F5D6768C958D1FE86F3FFAFE7A338E69BEEF52E7A12A301384F98BF0F399C4A2CDF1DBC73A24F849FE3039F1021D30266D9AE86A5199D3A27971BA33AA0E1068D1198E76B410E9C5E2C360E07EFD930906C859BA5672E40F80830B555C44350AE5EABBB93CC4A9BA2CD46419AE8FDEFF49E145B403356E5614F988A96031DB41CCEF5061FC616B31E44C08965CFCE685B1F8395EDBB32991CD550700A569475224F173F180EFFE1067B3640E27E9B95529407171769C4B13A502D8FD1380F7C2451ED37724A9746EA2E6ABE1BA232D3C50CD85F5E65CE03CFCD63A1030EEBBECB0D37F98C54B3400EA4075535F56CAE74F9ADB282E54FEF53AE317DCD4C14C1018D16C5EC858888536654D22FB3FEAD4EF8BA3A766C037D950663646367099231211953627C838CE4468AAEF91595879188CEC0B5CAB9E642A74FB4BC9423A265016F8159455BAEC314CBA926F8D4BA27113E5DFC32B0188241EACD32EE8271E146E3D820A44565702982F7FE378682903C2934EA5607D03823A13DD441C76BF385053F044F8FB46C53B3B4DC84F8AE503BD085BC8A04A3881710728CF95862C3F587F5C36E5A938F935188A3E6E6435DB64FB3ABBD6521255A77DECA3131090866969FD379E88D188852430EF637B0C92EE924D632C4BFBE21125B5083009F32771209A146CA19D7AF7345F4A40641E1E1313D348B48137A9A292D6DDEA5FF827F1D5E9C30DCD09A22A03E61A18613FC55C428454BC0EE898D1B81077DD99EE00B9C24DCE5B800B434673E826169EF0B13E11E01551E4BADE5F8C23A37F69A7E66EA174F2716F5C2D8DE74067E1C72984663C2B9A85B34C2D266CFB0700DDBA3C3C33B8BD6348CC3422BB0066DFA0DD49C0A2529A095004C06C58C1512A0E303A29751B759507DB6B768BE9E0C812CCCDA432185042E6D293086A0F6CF1990C7ED3B70C0BECA4A583892272ED984DE09EF53F0BB7415EE51B1C78B69E85F317E47CDA68C558BD3303DAF307DC50F86EB29B8A1FF022EFB9BCA38D7F886766D1AF006389A31C633395DE0B16A45B02BFEF191DD0BCB72B4C3E334E7CB3CFACDE61D61BF58F8BB68D0DC480030FB0A2A5B4462CC21AC937499C3E9584B8684FE30A1B46ADAA1DC1D1747299FC67CF7F8BA46D622EC599123BB470404044A6FDF12208FF47518B13A08529817EAC984BA850E0C797BD360F8F8194600B6F61E270B588546000486FEF61F7C1BA4EE4B61E11385E200E67B2D8D3B6368A01ACCF917A530388F463CCEFFE2CE19A50573B6E5FE1CE2DE99C5FE23E78CE56127889951658DBF3C9B1CE3E9491C24ED4E6FC49B40CB0827A42CFA9DB9AB43837CFBF4189731F978CAEC3E9378C9FCD6E820B969DB94FC81C494772E41C7CADECEB5774D9CA07AF3747137A8C38706979EF7989679D72157D7E933F873B8A5788E75B47AA85DB93F4493B6335347921E492A7A008DEFDE2A8AEABC44536A68D3FD8370B7F7A7BB81F9B1237CE8E4B04EA49C8DF6F68377DE8B7A8D84D2C34B33255BA1994420A7ADDD191A8650E7F63B797B1E8CFAC5EEAA687F7F3776DE10297BEE34C884211AC44390EDAEAD160E4B47E49CE6D40D4DBF38FAD09F32179D7C88C66375777740375D790B1EC716456FB1FBA1D5CE5652AD54A2B7AD5E9D62D01739052D29973808EAAFBAE24A190716437210B3957EDA9C6946EAA9C322B371D30DFA5567D3D374310ACBCAE642EBAC96112F820C4A82C6D59158BDB81AF44C648DBA1AC84DBFA3AAAB9BB64D7B264B13CF3232FB1271C421F590FF449648ECB56325AD339DA594E0795882A95DE0A942A639D3A466D715C0EFC1B81ACA240039BD7BE62C19A924CCB07130467BF4505E1D2495A54B2EDA7A064A989D9145EA9242FC885A9706EA11C880EA099D3EB563099960D045D78100CD6A9B888E22DA1FC29A3FB4AE0A67C3AA8D6B88268D232867E2B6BC940A0B908C413B4A0B85508F5DCCFFB05AB383EA69521DD0F9543F78789F1E35F4A4B7648C735DF12AE6664FDC7F8B99E5F66E913A26622BB0F6BF658796AD22653A23EE8AD8C3ADB7B07D244827EEE2445156116E503258C47EEAE8701C4BA4313406D62FBCA964DA4D2A4B130F7433A8CC1BCCC0B8C4D37F2176E31DC885A07339A103BCBB26EE30F2D7BA66CBD6B8C675F04109965D08E6B0DBC6D9F5E4F77882D2D66C5B7536F313BEB188AD0B6748012180BA65B07A733FAC0858EC5C32BB8" +}, +{ + "seed": "12B78D9B1A0645B5744CA179DC53994C83B561F77E63C32BFA617CA75AEEA7E6", + "pk": "66396D198882B62CAD6E4A38BB6CBDAF1E27E8549F315C1A3DCE47327DBE0EE648FFE9D9C06DE86AAF547C8EEF2A52B7BF95AADE081C03F75E7E072CF6B22845C52139A10FA2ADE1B394284A21B19FB930EE6BF8DF7F5E8A3E2D3A631205E7CF8D0F8CA673E8376515B77DE4E876E5D45EC152335693BE63ADF11759BD686AE75ABA00295539174B9FC74B69FB7DD1DCFE6A989EEC66AFC30562C8E2ED0418B11356A91231BDA058A18DF1F11DF076CDD5B3D56C96A260FE22AE77C674CD34329F1FB4BE1D9EE13C1B0BB5BACA1DF12BC15AE1A5B9B939C26F08C5FAB9B72EC9E43C3C48E12C7F317F4AD712DF76D31873CAAE61C1358BE84443AA8F74CE06F67371AD4105A0F78E907113ECD4D823C6AA18857D7F5650B030A5E5580D6E37BF97AFA96D797809BB538AFCAA5C1DD6E5DC3F015BB2D7BCD5EF24B62DC34A76FD591309458B1B883CBB48477A9D58F00256C6B285849B4A59ED11BDB568142A06E44FAD490E970757E02505E8255CD0D11161F2CC467C4707F1D4CC7193BF081EBA912064AB1C37026E6C9760DA69D545A89A6F47DDA8DD68174D18AE9947DD9A2EBCB0A785CA3D7ED4087F27400F374DFA167A35E75E529D4E7C4D06B882A114561D26E83A7A000223BBD184CD3D0CA98195568C5788B3B95C246F24A28878244265E7F94EC43BE4C3B81ADD6557EF609BF2761EC1B9F14F87208883A25CE2E80809A17BFFA93D894CA65A22CD85600EE6D9C00D4D07A99BD0A219A4677B689FE953449915AD1F3788A682004DC51470A1D25214496EBAC6DEF10663C616608A3077EC9722B6089B22A6C725D118F80180614CFEE11263ADCA8867C07EB210E64243357F8C41DF170368E8E1718D782CE4FB109D7E7872FA3B242C560FD723B36315D715CE96300F450819455A0003835239F2ED79E02B4B9630BA24798159126271506F3EF3550AB035FFB963749077C537FF6420A4CBB3E09BABF7B020931D9AB34E10E42306E40DB39C1D5927BE05DF34D707E3D953DC333D01B06836B4A543867BCC216F32C3C4663F7AFF2C06FC1DA5BEB90DDC4AA33C4868B920D59512B1181C9C45341CB6F76F66A867841A4073D0FB2E0E1CF5D9725258BFF96EC3F673ECDD216BA10F8DFBE52529C8E8AC80DA471D5468DF34E211A68B3A6FCCED3FB756F59B155552828D2F4988220292C53CB3BC1277075FEE413A8F35E349054EE31389703DEBC6153A61939419FB03A347D7A20E72E742BF878A71C1E6690CABD9BD80ABD79588B9814A5C3D43FC5D6225F124EC25EAB48DAC33825050A6EF0AA9FF3A958CD71792D2D93F5C72D85CE79FECCA5FF77E72CE9093472B6478786888C39B22B5A8FD6578774E5BAE085ADCEC6B0FD7E65479A95BD9FBC5C10DAB4718F2CCB3179FB8FB4C3412BA3F123ADC9EE98DC5C4D64550FE00780F3F0775899587C1BC8C3543B8D3478D307A18A5C90C6B7FF46ADC031152B6E1547168C2C598663EB233F52B28439EAE306DF3BEEF57F4C0DB45894AF4F2BC1FDAB69A2D46B75148DA829EFAB49A07030775FED3085ADA7F3D56B6AA9A732C9F5604905ABF9A45D244B10C2C11383CB6F09A5E576E992526FF3CC0BD73941350B31DE9C8FEA826DD980504BBAC2077BD7B11AEC2DCB9CE3094F95E716CD6C6D0B541083B7F28317A65BA7F2C3FEA438F22E61A1325DD8A736E8C45098D6EE00B97789766C233387F43F43185080F51A55D20D3F07AAE1BF460C577EEDA3B27275060EDBD06019B9122D017AF5E69F4118B6AE2D8FE342D654874A46DEF2413EBF1FE4490E56612C8DB050BBA92F520C620DAF77506EBD5718F9C7D16816F4949288A9CB33F6C5268F9F4F9EC77631EEFF1F67316CBA59A0060E6B3AD6DCA2234F17ECF9CDEA719B5CF0E71EC06B16C6BEEDC0DC6EC4FC855F0D6F6B415E97640F0B6220FBCF6A2AE9215215DE029BAEAA3CC272AA37B89077BC7E7F79213B6E6ECEB4839438E410D3013B4382093CCB74C02ADE6278DD3AAEAADC8583DC7CF1DE0E46D01D6FA3C4CC2871D8C447DB6D6ED19E54F21619147B5F4F1572B4EEEFC439E63F55788C8FDFD65BB517F3EA69D368B2ACFC89A2C8AD317EDD58132B167F28CC05DB2D4BB959208B3FA284129E831CC98FEFC8CFFE3B0A93E3B23C7D164CF17B8375AD27052214C0C4BE98A8A5EAD5B58E169717938AD889E207418959B86734C31757628794220FE487B3222711EB859A17175D9F89264B52E2200489206C47CC96EE85127C93DB91EDAFCD71DE5F6D00031A685B5375C3C4AD0BD2C7DC43C338371AF943502DC9DDEFD080C798BCA7A4FA680505677CC38F2B3CD703196F224FBDD0CB5DE7CFEFDA481DDE2C6B42EF0A0C2765579A185681C88B4A8533E18B2AEB47E727101F6DCF58457F7BFEA5BA4D5FDEAB4B8D7CFD5AC619FDD94360E9960C5AFEF4B21F5449F5F974D2DFF521D2ADC721F8431E2C944C44ED8B66ED3BFFB679DF0866D20CFECCECC4B1AA6F6247D833EA7DDE92A857AB2A179A14AD8D296CE145073980C9C204EB1A8C235CE08E421517D3722FEEE717048014129E2F793B3BFF60EC8D5E413553564925140284C5779B8B30213F282D3A50ED3702C55DF71DC7800232DBFACA8EC126A0202510CDC6289327714071D8B30557F62DC7AC9E1CBBFBE4E300049079D298D44BD8A391AB033512360760A2A045C35B43EAC71DA9761C5BB4D3808FF35FA00C8A538AECF6B84BAA7ABADC51049F7F6390AC2FFD8C40DAA73600F8C243B1F2B497DA29F623235B88412DBCD721F6F8A598E31F8700D6C40590B9E191ECE668BD4C304AB4A8B21A7967CA80C01BA542FF455BA3771BF0766E1A86DE16CB03081718581E0705CCDBF01C12E4C1AAD8B0B25B5558F9A182B6981D4B32B13BDA26ED8EF813906EB171DEE95B27CC6DBBDD776F19826A0A32195CE7F54FD04B5E7DFA7BAD009DAEDF7DA531A1C85E37FDBF65C633A10FC7671D5CA85BCEEC6E17FE57E7DACFFC8663D3952C41238BB0ED95A77F7981BF23CF2B816DEF8A75B3344955C452B416E5A0C087DC913920BDFBEBBA499BEB547C7D1C06029F31C959A1EE1B16C9AADFC7CDCD41C5B8CE23C5E2FA99C78E6BB6D615BEE75B7453ABCCD5BD961E776196D7D5A07431DF4C0926A514388A8BDFA2DF581EF16A7B575357433CA0A09D28E9158802FF21B6C86CDF65697678EB72E809D3706BF37DBA403345FD7DCE699E9A9243181305E615BA50ED867B5401C12E6277D24FF7C167B317699292EDFD4E95EF132E34972D9E55BA4E84CA3761221800D0532A1A38278A079DACB541C1CC56E00C1A7CCCF0BB1B746251B649954766C2A980DEC096BC570B6A4BE8B78D17C1EDBF3CA372B4FBB610FDABA25901A38B577CEB2F627650C80DDC5C255AEC4A5AE07D361CD88717079A883A67ADA8F2B00CA7F9546EBA4279513F66DC7312117B6A80BC01F0C268205AB6FFA8D90A75BE3463D77B98D183A113D382BED583A88642FBCB2CB0211141E64F992679392122F4AC5F80CD8A5DFB86DB5A7EAC05796EED172F666903E909819FEB2AE99550D2F32B5649C9F18E09CD3BC8E8CD08F2C35BE7FBF37F8684E89F0DD02C60EC8A4B271956EF1AFA0CF20BD8CECEF167E42545E062A73D8D94DC8E34D816980681567", + "sk": "66396D198882B62CAD6E4A38BB6CBDAF1E27E8549F315C1A3DCE47327DBE0EE67F3C35F1FCC838A55E60B917C1D420F5D6D41D601A05A3E98F46FD2530A8D929CE70C2D4B69E48CF1755A2C9786E88125B5D1378361DEBD87E61513BFEEBAD447208E14897188019D65B9A54D8BD72F07B0C7A7C855ED506BC1B6FC033BDD3770148045098444C22101AC860E416290AC008932271440209E3982962026643080961C4058A4089031322C1262EE1C248102949CC4226D4B488042251CA466100092D13154522C43003132592A4200B01610C328D22C1681905860897682340210A1572910008CC066C211881224384102941C420280A324D93B08CDBB44DC92208C83269C3B8004BC2440911494CB209E4A221A3482103A6480131604934894C126A18178A1C2045448084D9342002286610B050632090C9164E80B848A14049223804D9A48C0C228A633661094410E0B08CA1A0601002868B104603192AE0904C0AC08804A2090A299023390E19B90451C071E0C4901B0152C2442A83B88591267098101124B46851220011B88D011226C3A4841948209B3072603268D8C2201B43891C97200B3109882264C2C22D9B06691C1828820045602049E4082514820848B261D20461DA8664401824A222858A9625A116496216889148800CB664494842DC2690CA9030D8064E5C820008194E24856104072862026D4C8061C91644CA864D1100904CB00CA1A290A324300C462A004406E2B645888821A2061224A484D336880C208A822868D9162192861102130201114549286A04268DE34432CC984123482C80209201336A189248E100258B2065E000601AC304C1884C083966C3982D04C66D1B1202E3B2518448651C00801CA62D19B70994248AE046120BA9701C240A5C204944189204B16C81344808A0301821929B840D020791CBB8295C323221B04803064994208562086408C5640B182521854CC820010818020093519990016140052223008838515348424414501C078CCAB8311C260E21C48124338E5C087012054D8C962459B06D4148118484849BC42D13B77144C668E3C421D882655404044B486CE3C22400338640C49012C5408A28214B364EE20002A14491A10008A1C671D0202201296A881021D3987088A8604B2491D1126A512411D10644D39284C0220914498AD3C8001007640C327109914D119984413645D8144D9BC211CAC870223382DAB491538270C9248219422A83C82C8C964C9C006540102218B0489C00600C4448023830E212100014618BC0695BC828A21029C2884582964C13147009C411D9B29020A781D4020824026991A20810C660993824C28871C0088D589685C2C848D8A481CC1089C196215C4230E3B841DC40504C48460949284A4689C83206D93485580012D3144008472024341292308EC1A631CBA82144B65081884C63046AE4B6810B20661C490E9B3611E0308021131202220490A800DA86690B020018C788521872442292A21628002845C2222C19306560A0409A40641324492303911C069213464A0A09128A082E81960C8AA06DDA304D0C854D5C222423330508932CC036311BC12852286C1B1751D3226AE2A2298A36285412311CA44804B484233989D1209060282ED092700B0321843482180331532888018120E1142C90B08C5AA09100B02504344ED93005CB12094822889B22044B4468003761944604904410E0B8012331850A2624601644201911210230CA2845A2B068D3466482884C1A888CA44865E31641DC12044444081AC080049104D222894C164209130C22072183366463B8084BB84051B46423964D4A122E1BB98442A665A4B22892248E9B048193C29098148952B090D818045BC870A1280C240404DCA231C28248CA488501B34C62120D8A3429132530E39064A3226E64C49122456C524611C0368264B20C80C091CBA8080C4480D4385282A609C80425C1082C0AA15142B2701BC381CB026DE02232081032E0264463000024C88C02A46C6226609A048D52B800018701C194411993508248500B48296232858B104C1AC57198484C03404264044920C8411940909AC22510A79100B3094C00728092240208515996085B362A228651E392318326481B382D23092E8126008A463241A82CA1462060A60988362E11348008B42D1CA324C8904C1BA54C20280821C684A11042D912881A282A1A405C88893D0D875D4B138F7D713B73367EEE0B0BA8973A1F3755C4AC11764B147CD19B397DC47BD99B7E2DE1455B607362610ED43F2532AC40377F3A637778DE4ED4ECF200E6DB54F07A761527A7EBCD2CFE22051E07CBA0DF8B953DFBEA83054AE29CBB6F6E8A85CD4303E2186CCF0C4F2B979EACCC437DBDAC0ECD89B9D97A548D40B699FCBDF8F03565303C88D23F63D4E79AA5AD78BDE673E5655309F6D57A485860FF4D9F9724AED4B0DD4A2F41257CC8ED3B28B4C232B346343BA371ECD712757CB516B1DF171D22682D77F71A5024DC31209EBF41DA1C408DACB133F9B8256B9022F59B439EDD5209F5735307865CBE687E0392C705C80CF7D31FD4E817B12488110A675233FE76105C040F720324AE3DA7E18719BB171981F3209CD7DECFAF201ABFD28D7E8D6533CD66E3B3B54C7B6854E5056057117A99D413B3C419E3C2A22DA0FBAF3FA0C87C2BBD849D9971DEA51A6A022DC4BBF16F8E08C7F2FB5EC892B18838CCF4416A38E3BBB39DEADC270C338BA467B45B531C98AF14B920E46CE50AC0C15F08C70DAD4A79E7322D76451F82F9A4C4F2D42846C5282D08A0A74E4B1E2F6F31848F1D47BABCE24EB0A435F4F4344C8C44EA295E62C909EB39773BCCFE1196E85191F34B414451F99180645B1ACAC43E8DCE346F574873187A84814108CEE348A0217780D89DA03FA80A9808B97455944B3F80765F6E74B8302308F18BA36587188A3C24D39C928DB1AC883E7D260E50B7F8B36C2D1FCEB0D581BCB57087BF5C1FE018917B09DA8F04C99A371BCC80514FD78E262A0C7C70B212D714730380B108732693FA8F80332798485AF1A988BD430B05AF2B82CFA761CC34F00AEB64CA3279EFAB0CDE1BBF50B6D6431497E7417797A1A7E58459D30073A5163ABB6504FE960733D6789D469D0A344BB719FB7454F60FD7648AA6BA34014545DA6F386CC4915279D549ABC4EF263B68DCBB9BF1A4FEFF5E729834394F2B82B95DA66A352752F20367836D01FD2D0F12D29195DACFC0151D5D5796357741A8EB32299964F9FB7077299A6343B69752E8C9B7D07DBAC9C88C91BD64D0DD16A8435F5FD9F6D809DA47C4C73F47E1A1DC203D4B134D8620C8C4784D216C7E0F650874978EA4A781B054FD3BB383DADCECEC7FFE4F83677A38A8B351520898F29EFB26E64F63113C68C97814E140A7183C5875AE4339A6CD08988E44B9746B6445D6A9112F26DD834E0E26808CB1BF7DE16FEE63C95AC8B57BA335F34AC183C12DF9F02AFF1D785309A40CE9E103BC996237DE8100D1B9904E358D56451D72F5EAD3035CD315261AC8D6B3733515656CF02123155BAC2C9C5F22AD411D5339D7D027D9B3A040E3F7E5FD0B6D9FA119D19F172C2109E43858B609F975B8BBDB64BD2DF89EC26A1FF793BBAF8AD331587A23F3C91D1EF1D4D3859BD31F48888AA2E2821E00567C12B4F3AE880E3A5D36D64811681D8D5F2A64CD9E7B0C82F2FDFCFF190D323DCC96C76816675BB9683485755BF92F1B4E58165779D583D5DE05A172EE3EA77CD632F4F96A5ACA618A4215806AC625822A67870EF4ADDFDF7953EBDE41D7C092A3FA3840AF0678578CA1CFBD570A93EC1AD52DDD876B7D45DB23414143398D14A534FB6D3EBB2EB66A67B9402EC31DE21FD064BCF30187531169BEC5641BD6D5AB835B62146A36CAE06B4CC0A2CB9740497981A915A0F4C47DC39D5E3D15C6EF289EBB5A1A8B5F151AD3AC441DD2638117692F42561DD19E89528A915FD8380980E69F46B1700CFDA67CA516B5A480BC617973603441B6CEFD8806F03D90046703259669500BC8D3FA1CA07E4A68A6A63593627DB52462C16C340CF4D5DC365CD30E616B887BC1CFEC39B6D14F84B89766F41A9EDA5E5BC73557E27365067A59D3E971B93430749896EDD778A81BACB6C60ACC0B9F892AED912718D51B06426E2F2EB8474C9476815081AE71DDCE4234E2021B56337A3A8A0F2F5C02A9024A6E94D2362F17FADEDCBC7AC6F7623DCCC3D971CBC1FBFF347C86052E3DB823055A73769834D360030A059EAA0A24531BACBCF681FD29AB2EE5572F0DBDE188374306E9C13684B7363DF8F8CD26D1600143424C06BC9A5423EBA825BA610BFA0476F94336DE1BD92CCCAB73407D6C2257ECC9A62ED558CE08F73D46CD7D6D69DB8FB0B31D0CACBA5188F87052A0A832AAB76E9FBF360DB1534F4D43860A80007738870F6250B2ED025C6F1E3C0FF5A574CC789BA63C4B6F952ECF2332A74D9F1E585AF38F73F7ECFF37CE90B8562D50F42608734430F370763DD631E7078ED2016FE17E9968D43C409044B86008852E284FF5D262D05A960976A790F9223FFBF78C4A2F347689222CF4C30CBD83138BEFB46075EE28EF109C9CBBD1A5E9F83FEF060DD98415428E0137CD302F7DD9DE430D031BBA25A641667691CF8E64DC471D5A2E2095E7BB2CA6589CEDC60F2C72E5D7C310D4FA63F3DEF1981245B308CEA4EABAF747D4DC37F77B1E532145DB7451C64B877875E8297BABD554E6F14C17B80E68336BA24ABB7D0FA5D02DBAFB105711429654EA1D31BE03165E7DF097B91D55A0A4DE087231405EB9713A225E3AFD7A607939AF07E17A804FB034183D7A2F68BF203B46D3EFE7EDD0527F698F8B5E31E736DDBF68288CB9F71F1A649448D960178105DE170AA141EB6BB24F33A93FA3DE87E0B7B3ED1C21F309BA7E7FCAF181D1FA278575E3B464C9A8F235ADD708F47DC6981BCED1A5FCDE85F5BE97233B8B08D794F34EC4E7656640B86F12396B05D9A3E73138D9F9401413584275BDD2FEF2794B63BA90F5AFEA42FF703266C19827550A162270979270A57824378A0B6A7D33973CD6A7C973AAD16112A9B65C110920F91022D9D1863D81CFBA5261BBB88491BB6A30DC5C1AF54E280EF97B718961A707494B52BB01626E9AEEA4514B3F3D4CF39956861BC7D566198909A6C7B4B673683974919BCCD022F8B69602C066FF1F400AC4B1477B860052DA996ED38A5EA25B6394F8C966D312048139D7795E0A02327C51FB9332E12AAA170B8FD9E812698F73EB22497857A6D6C91923A934F90FB05ADF11808951D8533E27EB57A734FEDBDA1DCE135E937B3081F6944DF3CED2238158C24EA96CD547ED5DF59FBDAB0DC99F9EC67BA1B29A7FB949D79BF2D40CB375A1511FF9935436373CE4CB6AF1721E824DDAFB17C233B254CFDE6979500F69A746E5ABAB4E9893A51A34675F422827CD23D8F47FBF1BF760326E44B53049059628E7406ACA5FB7E036C7CBEF9D536EBD13B6B5FF0084B16D98A88ECA76299196CF51C305EDA8AAB1C656EB18FBC6949EEF6E177BF53BE1371543E3B969A14AFFA7352179AF4686AE78936615ABDFC59BAFE63785D9B707C31CB863B8EC41F6846A19068C6BCBFE53C231DA97EB9E93D014DC7AC91E57F89B2AD96C2EDBC41DA01ABC1850B762740CF0D41E32D1865B9B240210F5B66767882170F4B70D890D3D26243D3FF816D564FD30A052FA9F81C221BC314733FDEA7E443B8659442CBF240F7AB1B8DCE657DC283659990B0511B4C45AF9275AE5AF97E3B0F29C7F9D5BF4695C06C017F6624E39E0FF68E857810CAA85C7D867E6CA49D34FC3564BAFB5CBCD33A8631701AC896E59BFFBF5FB12E877B81E7C019A409DDDD132019B3DA666AEF32CC6E900DD5C1EC750BA1F935274D1B99210CCC50F1424B42C159BFCD68B8F38D12CCD2C096FDE4970A12C251644FA891876C7E56010BFBD29022648F4F0287C1A50113DB285CD99B921876868F5674E9A00D1E6F8C63AD88D1295EE57DE3095050AE2B922F9A04E961C7A0F8D43AA957A00DD2AF966DB68F3DF14CC0FE573D0DB5B1ACA3EE7E95955F3D5892F9E20F9C16E9BDE2EA60F9E8A95964FD1472CD6118F55F5E31D765A89A79F52D89C7720058793DC269F0E93B9105CA4969C83B567C57A911CA26BB73CEE638E359F020B891EF2CB39350714717240B7ADA74B41FFCAD3DE206CB48BCC3D4AD693A6D9A8970EA2F9E2B22800840DEDBF5F7A58F9160FCD4F1444C28E74BF6798565D60470E1DDF64E48678FA187B92CA62E9AD6EB234A398B686041CB907E135D9D8AD429DB298B77CD0139AB42FE38D94EA1A26663238D351564129127D34AB7964C107F28E593AD4FFDA0A095B5614EF9C6E19BFE1B5437B6CB370E17D10E6D34343921553D672D2E6D614C56B45907CE9743E6472CE6BD959FF2AAEFE2AFFF082EECC211FFFC125E7142504EB398B8D34BB0F849CCAD124274D0F8ACDCB1D54D99DB85468CD19C96BB1B383C8079D5FB0267CFD7BCF0916F586F2554706F6F547961FA9B897721C8B6FFBD63F2E1FEE53A8DCDA34208D859D3A00B197D90CCFB6C9B7DD0CB419AA37D7DF9034074BF56256F899637389FEB731F67004C1861A8294D3EB2D8485BD9299A544D25A6841BE00C9F0E01ABC2F224A8F9282B97D948AFA3145FD063BD4B0AD7AD6C691569F19D053A85CE7BC604495BA5183992B97D9D52FA9A4E9949D3C4440404B1970FED773C298E5E198480418ED96F34D944416A7C89BB6AE2B8705E73F1EB098502EAE317916BBAC6FEE466A26077B662DE8C49FE740D3369B976E7F3AB087A3C36874E2DEF2C048DB247DDA6A2A0FEAF2BDDD7D064149280CD18D81866C2E31B9C04EADBC7D086AFA9ED63127CFA5EC4E1F2035A2ED03" +}, +{ + "seed": "BE8D7347BCA4E0611DEA6C735700DD86180C4B95CBE7FB27491F00C9445D8A3E", + "pk": "1088DFE7FD4348B1FE1AD142203AF10AEEB09381A1FEEA779EB4B292AB3FDF4400BFDFD81A7683D69E63112A0C53BBF404C0AFFFD0401EFA99346A90900A50025B74DBBDFCA7D6D3D3158732A2F7123241D3078B6529A6E170EC0EA0EA99A12FE37D209DE360D5F6D985D0F3A64D4B6BE15D17E1F7171D3569CD4CC271F8A4B8630F0954854D18D36B347D2EF4DA30729383BB5C89AFF73CB5AFA6557143C4233C4F5F178B4D118215BCE7FA19C6CE32F1B73C9DC6E20C7B2E49198BBF5A0DE3F6F4773EA9825F8F5EA1E80744ECF76F831D5A3CDB8292E7D5B6042F5B86ECB6388FAF6E706EF81745158CCF6E8A84A417D6AEF91DA5942ADB6EB8EADFA8EBA0E21A4CBC05DD9FAD44847B518A6F1560E30E6926E45E852A43A3A8275665EE0BDB0216B77AF4086281459FB912F3B692EDBAF4AD46E336E5ADBF9EE98214BFD1596F18D71B9EC1B394FAD799014D0014D340F67989CE35C574BD8DCDAD3C8C932B69A207BE31C074B84C6BA95B4667E07FF002930F32FECAB85B1CEC07B0E5017E93536E65E71223BBDD3174DBDFD3649BDA2A850966A4D5407DD6B5CC2B6EE5C0266CA77F3FC750B3191CA67A049A127644784652ED02EA37BBAE4530B00FFC20F7538ABD09157B986B4619539E99C0775CFF5FC22D4D2A605A68816D8CC7C214111B0EDB53A0F1913F609C78B8294968FC47782BB0B5CF60E82BAB42D5EC98F18F3DACB954ADA096E12FAF74F68624A1B656065175B420CAA238579102F5454EBBBA8391FCB059C1AC64B7466A69AF6A2C3B3479939F22B774CDD41950F1872874F874C83D6129C3DEBF1746A35BDC51A3086331596C242A05A34860C07426E97D5ED9FA43B7E0B2AAF7546323517795326A84BBC3DFD7B2AF2A60ECD55F0C17214C76B68120BA3CACF063DCA7286174228D2C6D918BD1B69D5FF80422E9C7BBE2C53B9C4C6BDDE5A484C7AD19EEE4E04E5C5331B33C350A84D96E60A317DBF9D9EB9FBA32BC1F1074CF4E55C6ED35993A005675C1ECDA984A06FA93F16CC4BDB6FDE74E936DF0AA09934BA66E1A096ED6DB1B0438073FDC59E3C5033381D8268A9125766CBC7864D6583362727D11324A1E4C103DE210873D5FD1216FD72C443201C6B179DA770DF8BB6C8D65E517CDF2F23732F52659EB45A711DEDF5A0E67B9F20A28EBBA2C0E4F3EA21EAD329C6B2888E93E6C3A2A630B8AEB40F31D7250D5367D3C74C36D1C68F3A537AC3351820BDA795F112EA80BAA1D2217B65405957C52434262C10CB556C0B1DEEC1059A6EA4266DE19C05C07DCCD06DB1150D24690355D6B2AB11BF4872768C339A4445AF61DF7DEBAD342A617A8C3DAD91172EC87D12D14BF2FBCEFEB7914C5806E0403874EF87C2C3C31B71A419134AEB3B57315B19EE5CB661C7DF9370E476789B493BF8B0187481A34D8EEABB828D2CF0C014E8877C050D288324ED8ADDD7B888CE3F6795F4526646ED176A7252C58C61449B7B339D96225BB5ED2B78ED0646B0A6AAB394FD8A199150763699809BF58D5FCFEAD0199C8D6C68C3800474D4871EFD1D4CA94D4890D2D1181AB759CB914925AE6EC91A6ECF11D237BFFBC352C280AB2A7184798C0BD4579149DDF67DD1A242AA2B1D3111CF32C23D64DF2BD617CDD003427C11F968628DA45D912E4B7468D6EEB3B99702F2991E6BAB9528DB72C13179383D41CB6A89D06B6FE014400668E6FCD7FAD91AA8B1D1ED618892C1C490BCEF17AFB653FB5CAE9FB09942E14ADF650824CC83E34A43982AF55908C20445391CBD8EA1BFB96F87E518908209C1D173E80B71E7417DF0DD98849D907C99FFD83FBA09C113138A51133D3C246A11169B149820CB37EB619F5D37983B6C6B6DCBC48CBFC8B728AD9934B29E9669D2CD5F427E22AE1168557F80782F7F01E4E5C2295D3A04E771DF0031B4F6974A63F9F709566A01CF9428F791AE2277DBD58213B13B91AC09330729F9B3F2F74391AE2A42B3C85D1713B6BA7DFF0677C7AE4168FC2B4C09F3253CFBBE2F6B044818A650026EA3D9CC6702DE4DEADB688F52C8774E91F31D7466D4FD5669366C1CF7D5686FAF6BDBBB03B5BA479AAB69BF6E5FF369CEA5765AB55C84B4F96D8993A6E913FD9B7CCDBE4830BEF447F66EE983A6305B03F6014E4DD0BCDE87C30EC7DDD3E0CBEB22996736E97E7AD0C94B825CCC7C489DB3C271D84B118FF68F59254604F12D22141E333AF6BE5621C5FF8A7C1D8AAD98E6EE69EC17A520F6370B070B48A804EA4DA8FDB492ACD53979A61266F93E296E89C4E3C6D7109B83E3BE77F81631B1E9A07B14C9D5CA2C511D640D2DF07E9E66D022D2A71E2371C9F0BB9379476AAD6A76A61E9282BCCE1F13322420F85EB96D29846A172D916181357683612A39C94D9FBAE611DED9E8AC2EA4CB91E2EB37494B58E33A9A661F5CDB89E7286320EE03D46138D5C62EA17382C3FAD1FDE6A3249F235FE65D4F1F62BA26510726E2E1ECDE0A156A01BF88142C4651A0CAE7D01E9987CE9BDD691EBD2B90877B29A10824AED9FA751753378204E866C755B665B17F9C8CA44A1B1D482C7B9D7533C1C96891C9F1D98FE727A286C722F3CC0737E90AFB95BB75B8A4BE465C61AD94A8D11E5969EE5C594057452EC61ED6C5B21E4CABFE07CC00DF5F734F69C747E79970DC20726F7C845E68B4C4C4F38743D716933772714C600740A9D7528030C4E7DEAAC03EA018A2304ABE5881F10C6D54A53F5203E7B65FC15FFBD40FDBABCF4F0C6FDE7E1A69E8659657FDE45E633A9E9837BE399CBDB6F06E531D62F5B5F9047D88B2C93E0603754B7D2A2CD6C51975A205F80C5FB0AFA7FC745D7F09FDB010963FB077A1DBCD1304A98256FB8C55FD86CA2CB9FB5321881D723A11CA9043C3ED48909274820127DD7DAC77B0BA8C29048962C77E10D9544159E0E9CB80CACE205AFACD6F38A680411AE55D55BE0AAE59F1A355ACB60CCE7E37BC3D8EB96FD8A8BE3E41CE80BC561A16957F7BAC93BE401F896EA0A76B56D8F34998C051AD8440950C3DE11583D7751BC29F1C5C5EF72D1244CCE46932077BE58F56BE3885618BD33265CDB2FE482AAD6FFB1F1E709ECEB145E05EC3092951C2C9C8DDAD869AF09DACB5DC161E4836147CE63ED46CCCD5E453084BA229066202073F1D2A275D4689A187F1271CF31096A1BE5B5138D45F88D385D0B0EF2B43B18ACEDCCF8890FFEA8E00DB74F0BF5E11EC8DA5C4D293A3BC5D957C5495D12B1F8CC2D131DC9E74679BC3C969CB50B06E9FB4979A81A02BA1F2CAECC2F5452BC37EC370FD00516E71A949B3D39D9E36381E061E7694F467290726E35DF4A7D86FBF5DC59F29255C0C2174A8AA5DE8189AA00C3F00B173438CCF7D19002162B608F79BD3CD68C345732B914EFE4EEE05C6951867BCF3E0663BD9EEB8B543D9548E8DA9643D3A691A1599409850528DAD2955E6A2BD84A7615FA3E4A58DAE63F35DAEC6B6A0000714ACF78C3939D97836E623CAABCD5ECFC71B8C20AF2ACA289160765C9AC91BF9C64B624337107A9B890738AB3CC92A1A5FE53C5F9741CADB323A310A7376070E941D35E0D7FBCCDC1C45D5BD65ADA152CB38FC786F230A71C47EB5E47D6E25AE74D0615F6F3CC0A27154F43300F6B6993B6613AF45C36C302C2327B7F496AB0", + "sk": "1088DFE7FD4348B1FE1AD142203AF10AEEB09381A1FEEA779EB4B292AB3FDF44FD2ACD1FF283A37368D3B17D6A7B80562452A6D0EC2BD04D0FB88621954FDFD96735F21331D6E77E8B6C8B93F7FB809353C07FFD5C703C7051EAF4EF1BA870BC6E0AA204BCAEAA3E31FB6C1AB0BB8C91FCBF6F63FD3473AA2A9C5E53D03D36C20B328091420E21954124350C83302102B96054B065092930118085041790C22080A3186592142844B26C42B6090133265BA44C4A106243266A44863040A45020B56501486013B52D14436AE120059316625A32494324641B3949601284D93268098024189705632280D39864DA482091C82CC8A620039581E3A62DA3126DA1207103B230184470934264900650902490E2964D23C8105B36305B304C003190221571C4B26943064A18155153040D58240444404ACB0642E4928DE2368121030E09162284468509070594466A2409661A412AA1208244308DC240649A4432549040212084D88601C4888883045061A02914095248C0119B106A882851CC086421358E14A661DCB42DC0B824134092A404060438091122698882042182481187101A1444090730CC8245A444100C022508152EE40820C0144512294D040649E1443101A704C116211B424A09B4481CB66114A145038791113331023331D338308B12329B000292428414B94C4B426D0805060239681A83501406488A262DA3C8001B036C0B94098C344C440832D2386ECA384A18426D09458E19468619A98C04105003312921002ED4401283069148B28911A56CA0084E49324D9040691210261BC36823302C084742A214802023881C3526C1128D98A6509C96311A9484644486E2A064C9160E94888004226849202A1CA11114820093368CC1C66D5A848C49228922C830DA18450A006E52B4215A848822B48409966554444ED432694CB02CDA362144246EA3C440624031841880E11012C3366580A4111C25020344620A164509470C22328C9BB02144288D89B00840024C50442A12C44002C48880344C11016E1130480AA2815CC84D92188E20252A5A344091343099A22100192018C58C1441218C824918208A1988299AC4490402284A025004064514B505DC18849CC40043282564262D0AC3085C1646A0B02508189212220D9C16200C33620B818C8C480110A50D0C336E4C88291A948521410164920D9486240C4808DBA44198A6844C106A0C984D21A98C82260AC3269212C550CCB48144022A00062049A861890611CAB6700B326411345203802961326A1429081A3090DA302513238C83380553320403172D8806514B86901BA6484A242153986CC098300CC4700226919BC411C4484E1C0960020361818230A2082D80048C01B500C138651BB5280B116288961192422652C88510411014C86109320C19486A1A21240418081C096918466D032168D4962D0AC08100B631C90848CA1069C2C608D94281CC208160203160442060A4000B326824318603410AD88469CC082004C685C4C68D92240960484219408C01324C64B489D9C26809890C1A224A1134601206694B2692044889E416629286910B838814422E244970092169DAA840220584D148011C220A12B4480A217220416AA1C86912044C0446704AA69150140491C0690890655B380141904408C7044004460A47868B480159406164207223312C59B4308CB2480C0971D08228582421C41825DC1462D0C085E3360E11B36802170A1C0529A4181261206098B84504456D0AB460210572C4C860A2920001942903A691E13261E004918416890BC24D61C62922426D13454E833412CC444E0B344841024DD4920451306E5B006C20016210322D48288418355104492C60004ACBB48022A864923620233892482409228445E2B660CCB2518BC68813C1442193089B828C53248C49362C1B854DD3B26923822C4A220CC8B60D13C9095A4831199009C944305AA84949022504B72810068662201044924480A6411108295A164D18068CD1448CD4A46521014203A00C1014041AA7659088284A006DA38425091346003930A4B66964446662324942468421494A5B00846224450236810989480298709A903199A02C40369019B380C2B2610A300C02454010378419256E41946D010488E3B64808848C0A1042180665D93405C1441014132C11C04D5C4268D4104C403690DC860964184691228D1C3468D20170A507FDB4E85D7F3A939B1F58FA6E23A8E76C8D110E2CE9D794F066C0ECA93CEC62369E8AE09D91EEC5237B52090045BD6A9B9D90D7C4D9709E43C83302885194AF378EEAAD715716F44A31BFE4694EED6581FBB187165E925114196CFE661ECE9F29B0F3FE4F591776A072C4908768773E8FDDAF33D7628C00490B2E42751BCB3D0CE4F94BA23D889C022CC94E7CF002AE28FD037BD0EA5B52BC24A8E781A37E7E3C656ACC219E429E504792A9DDA870FD4E410A83CCF7B58B8C98834CCEFFF71FB9B744948AF5A67F25C1D61B823585E6CE1A80D7827DBF142CD11771BE47EC2C625575D1841220B579C307C59D5C94AC4C83CF5FB060E473F13C4DC8AF10B795B2C0F96EEAF8EC24992BD40CB166EE55EBE75DACD55CF7EAFB3295AB88B3E92E499460929B728AE6C2CE9335124D34A2181E5E3CE485807F0D82845DD8B8097E63B3AAEEA170A9A33AB83D710D4B8D761CFAB70ACD863DD82E6C6E882C1CBA9FD25AEF905F3E4FE2F90A34D970284BE657D93090481B541B2E5844BF13A491239AC03FFE9628BEC0D29A31B6F4A7186BED829D85C15A4510D80D3BE6E21913221CE6E4B556B0EDDE23DE1573563DF9262373C2713D4A9553C6752F37E7F31AB495AF86B86B4F3B58075DCB2B0DE5E90455CA7608678D102BCBA5067AEB49A0F6F149A14F0F69B6E47CE388F5FF2526C714CC698CE76E4CE6661B6AF65725208DC2C03677D4D96267F440122FB85EE1E6365A03C81AE161FA6393F4B3D8617A5654F56CA5F679AA8AC433E7C1B753908AB22BB2831FC00AA9BF9F98AC985BE604A155DEA2CEC22EF7A6F152ECD49BEF30300BFD4DFF5BF834131229B4263C3E8E37277365B3078994330BF6951B2ECF80815FF69F2507946D3B22809B1C7FF75D48FA911CD6A13F8763C69D72585A01F4C3ACBC4E0CD4C067B262780475F886B9505033B219BC5D06EC5F6AA4FDD610BAEF4A313300BAE8A58A6CE7723C84942582688081A7051E5522C539DE8DE21F910BA8409A84A079117D9B85D856455B752C9125055605B4F45197B88B92F95C36844E0487F1EE7CE2FB57CF0B7CBB07930440DE8117BED892CCB06818201AE6959F9A1258DA6FB32538F6D4C7C68636039EEBFEF06D8FC56B71764807B928333AFD5232B2E3D699F9B1436E3A1E086986D3759446D8CEABB56FABB4399C9CA347D3A2DDF5BE3F13F8F388B47608C01AD4E1335F5231E3BE21A57455B6169928D9B55FC3D0802781126A9E4CC183A4BC9DE0AECEDBE90CFF67301A7CD6DAC07DAEDECF4F639A4E71EF0C35FAF29B1090BE4BDE8C2C60632D62440BEB8368F03A6576DB06E2931273F355F94F2649A35306BB1981351085D38AA9CB1723D8C535BB9267FDE6C526B69C00D89D1CE44AE51125872E612A418975403BBFA35C0D4FC507F3E810EBB1B3710A670CB27D749F1445C310C353E59244C5BDD89D7D8B9F5EFED87DE0E331E687117C439EB4249034ED6CC1F0F8C1DD1DF36977BDBFC1068C850B85DFA7F960C626CE0BD34E6B37AEBE1B267C44CDE42EB2C86957135E3BE09E8865F42ECC25BEFB39396A7782723F42F211CBE18A37E5443256B3A3DEE4C6E436B7995832D62A450B15ECF775848C6B7DD8295F8BE723A885232C9F784A99DCF65035CAA2A143528B96D94FE9347A84FEEC81017080AF833965F716F08C5B834A95A0EBD96315FBFDA08F84F42A53392F40E4B4EE85B4C0782CD74E489D0C2B398BA43CD2EB1F202C4DF1D923428DFD9816D01B51D4DC0D93E7E4AC0336F058F1D122B500A4D2647F99A373816DE2E82DFC9D1AC7C50CE69ED1C0CA96E5B158635EA75232A1210C78A83E6201CB07EAAFE48A64CDB8E62AB122F9FAB90EE073CF65C8E977F67D9B5422F8847D8B53E917915963B4FD595F920BDE01A4DC6A990ACBB5FD6D539A35C8D1A9885CC227D175C7148C166D9BC428E64EA2E8024C02D3A1C41DA20056A3177C5FE2EF228A8BC89FAF9307F6830DEE32FF753620199B990129F2CACE1841439504BA08C46FD49BC52355C0DE4F52160DFF1CAE29404A9633ACF497634D47ABC680CD24FF360B32FC7EA3B49FAEE6BE85A9C983E8490D75561C3A12436BEA48D07A1E44DFDA08B4D11AD497A8B0176766A8E596715646E44995DDB5BFE8CDB0540CA9E79D50FB78D2BB403401D7AFF234A35D820333C0C114A6F3598BA35A894EDFD495722A233D00F9879DA4DCD9BB22766E8A31A017F2BA4F50D65C70D6FD25EBAC7A79C60C41E132A833C0A46F17ED241CBB80B2E2568959B707ACE990174EB94ACEA580B1EB7A4F4FB379AD58EE1AED4A3557382EA56B77DAEE6B7E82620E08EAE12DF1EEE4F32AB402E759D5544241E541B8C8EFD16323BE507747C80311BD92383E91E0C50BD6BB663D3CFFF1F65EE004C7093DF7CBF18A3D8CA1539716EC3892086BF9F07F1D1165564E19A53B3CEAA42AA703B5A65DC6D56C781F4D6E1FF5C7C183C268677415D8ADF29461C7D64083B8897365C90CB6FB0663877A1F74972E56FB2D1EE8E4E639963AD4661EE0DC9B96A39211326B2AA31D2A5601820780D3FBF98C0AA9B7BF9AC628934F27BBACE9F207C855D23F4D70D2D5ACA4B811E8162B1CE8E88CDB6E2A90131E7A147D30B79A2C753C3D01CAC80185B20DA14E23AC7802DA5A4F9950B4AF1E346E0E021777FBC7784309E18D2260516CD018B8FD66B042B1EDE8C9D6B8526CC0BF6150BB8F6C3C85905DEC69A971B7442479FC06AA17F417D12BFAAA674817469BF682918B51F2D5B7503F5B356624FEC0EA777FA7DAF55B343A0267BE6BF4FC58615B52E8A23370B2B6DB1722130F6E1316A2D1804E401CB1D62F2AEB5C3EF08EBD4F535DEDC1585AB2C7F9861B65B30FCDF25AD1DB9DD0F1FEA0B073288D5FAFA0BA4473A5C57004B3AF12FEE605BF2AAA44E19C13D3E05D8513797C0FCCC7C71A56DD232C4CD1CEFEE6D26A17ADFDEB206FDB9E450359D3AA61BB8B98059C6D8EFB18430B048F1F0353F5DD41F5DC4C91267D7C9E24CAA329C3A314544B044DFA5E8ECFBFBA48F3B115ED6F1D6B6E4CAB9E31EEB452ECAC61624A0B6982AFECEEE7EF4E17BEF17EC35BDDAF762D3C563D42E39BE18B1305632E46E87BEF197E1CA9A39D09944D8C93FB1B4D9F739AD3B967F0F16EC63FB35E582FEF7A1E3B2E225E2137BC6F2651797AFB60D01AE4D0EF1457C25C5596788F15AE5EDB62020795F9B24A3022DD9489ACEE2C3E393119CDCA6FE0A3052A1005690EC207C31C19741F7661898DC47B1F7D77157474A2C00D5C47E603CE59C5846272277C7D4C31A2046BCB2ABBA6C0E10DEAB577CF71D9F0C96CDF553EE1EC8230ED7B200946DCBF6151DE73F0A2B811C35B00BB24C7173BA4C9125A440C6193665D855415BCA4007CC33CD00767CA96846DF15A8F485DEED0A21D011259AED3E1623DE0EDAD0E4BC516AF208EA242560627F8C36178FBEC5B05DCF2B5FD3BB72A4D993996A03B6CADD20DC3CDB8EC4219CF454020C4B8EF1B8BDD401ADD90FBC229D1BD3AE5728AA2BF7CA5E3630E63D8A14FA42B20E9B0F412623C371C6B7CCD60DF4B979A541FD21CABEF1C9D56975848126795BA1CFA451448762550C6423A114EEC6151198ADF1D5DA22C8C43EFD81DF965F8463569899068FD168598D168199737786B8C70F4BF4062AEC00FFBDB3FE78CC056FF1F0E6F0E6EA6E7DED51105485A39F60B697BF8C0DDCE72F754C5584F31153FDCEC4AA664F535F7926A89A5F1EF06EF9DA943A2C6DA79D4DC1753C42E032CCAE7510E37DA6AD20E3BE46CBF901834C78482D539B531218F83669565451443ADF15EE2B98A90A344DDE8D373964E69785139A5A7A285C3964DF177C823A67B2601938AEA360231A2A368B2A238E3D15A265249591B7D64BE7AF7598FB92202177C3CADECD5244F3C2DC503B6C63E74C27A3F6CEF73D216C4789B7DFF9962140313330157C5C90B0F62665A7B386988CC6924397807E1F2E28CA147C2028EF79D55889162686D8BC9C0391C1169515024FC5E1825E60EDAD1DDCD6E52684F79D25BC15249E01605EBB68DF71935B643ABF034FAB9202111D23813686AA284AB1276C089056E29534660FA2401EC2CF950E90BD84A742E83DB963DCD83868C98CFCBCA330E7D3AE30FC5FFEBB2A986EA6DBFD0E11E938DD3A3E19A6D6FF277B9D2CE0F556EF725560A0BE782D3F4F6DDBDE8C1EBA97F1ABDD9790DBBD40FFBCAABCD2065C0B25788EBB3C9C6D0C467C6D18455D3DD36B90B0EF0A0A3784C658E6377E93E27ABF4220426C90530E7FC078EA863A507F2D35FD10495819490BC4456FC6EF09F74A6FDB590D00EEE79C2B28268CE62822D73B94FA35B15E2419EDE1DCC6370FF6A43EE2CD3DDE1FEFE9C79B4E6324070F6539D395238B6E74F0E45303F526C1E0C21D1C60D5FE89C722E973C9228C8396322D77D9D5CFACD112D3036F8D6C9C36B4D163131E9A0DC2AC69E33000669704B6EF7B53F035398BE08AB7308B77E1590160CB2236DF3A14C59B3554F460C56B83BF1A2C6DB094F01A42E371F2DB19034358C6B62D3B028D415325315181D6FC7AD306103FC2E9CF9E1DC3587FEF8FE45606099155B0C23739DBDD123CB0EA801962AF5745ECD047717CA8922EF9FEAB11A45397B70C4149DD64BE94B75F0772AB38D623A6DE8D26D5209DA6F683A" +}, +{ + "seed": "E4CA0A81DB7A44E5F3DAE5B9770DC89F15F02126C3077642B67B361B7A75A9E4", + "pk": "BB9BBE6194399CDDD376902F1EDCEB65AEFEC308889936C76CC219AEAA403F5AFAF5C7E1BD67EAD28E19515D528596C1BF06C666294A896F79C09F1D21EBC70114085BDCF824D71D95EE4947E1E3EA0997FFCB4463CE552D31F0359555242B134B4455F3DCC906C4316DF185DDF332D24F7984B531C8977CD997BB0DE517AF11DE8AFE89150839AFD4A927F3CB5722E8C01F3DC10A558901689E7D7976580BAAD1FBDD9E390F40B045CD83BAEA0B8D8E254499E1BDAF0B69F9FE108819CA35DF692BBA250A2E381F795E25E244A2B6B47EBFAD304365E692B58BA89C187006C68CDE179621A43E5E54628C080F15591B0C1F312DA3300C4B760552CA99AA294BA7CB0923294CB53C22909876E568D125214936DD978D0E846C4DCAF5E014232672E0C5FC33985D32B9785D754D797AD9D5A5C45730F5244BBB470F765E194EF081FBA4470BD80F8CE9698F0D4BAF0B4AFEB8BC20E90A7E4F7E4EBF8B9DF483A3FA7C723B982493C7288D47CB4752285C8EE1766EFAA450A5F7EEE1347BC2302815989A7F218A08163776876177D584121E2A47F778B516CCE9418A9F55E26C8C02E4A063B5B08CC7E65DA00AED0DE22361925FE57A06AA3AF9C9C380A1699947279CAD5616CC515C677CCAB310547653797D2CD344FB5E4A1500BDA741CB36174B17618088AAF50867066203DD4B5C4488767950D9DB333D38482C31C0ED75080AB4381429E4F22996BD79C16DA38B473B677BAC22A0543BFFEA798AACF9792D879654CD01F4471D447D31B5B65F98FA56C113E19AF22861E557A1431E6963BAA47237F618DDD85A295BBC1D21AFB59404333119F816C787D0AF0A1D72E461D1376812D02C5951AD7C5656A1A6E163ECF6A80461C5636FF561BFFD0FFBD2EF0A3E7121885F474CC04D34BDC5C677C031932EA22D64306B5DC4D7E09B3E6F1034CA50E3ECB3C8D18B07B2954E7648DEEE772AA689630EBE0DF871B4DBC69BA812B9F9B7E7990FAC1EC61A85189A01EC81A0FA6431153EFFB49FE7A6403A63FCA28F9AE70E50D02109E9176DC51ECB0ADF4E85C55EC558F6F81C3588A21DB82F26FAB0C2A3F4193F41C2B31401019A491332331A37F2E4CC465A3B92D23CFA7D7087C548508884B53C191E5E6C31927F3F87FE67BF100850C036ED5C3D0608B4C31B6549353672A1DF0F45F68EAA6B4151264C7E6D8CC2A6259DA6847BAF0C3D8132001B094137701AB4D24DF93E3A0DFDBD9D6F276146AD21DCA259F23B4ECBBAE815A850EA004B8C692B77EFAA3346D5AA55E960E9BB23A270A4651058425811AAA77702A74BC60A8BCFB1808E15A022203AA2337D5A3A4815DF05CBD4C2D7C49949D750D745E5180FE7B3B5734445E8D9CA7B3BBA4AB3EE400D2CAF1E51AE5068DA38C7368CB2F99807B02E61766BBBD9A923CB75BEDCC7406B5C97ECB6CEC70D1E92BB949B9CDBCE4D94E4D63950ED163AF96CB8761DCEDB8199150BB3B8D9A28C2EA3C0A13B55BAAFA4DC2B4BF9A697C5769215394EFDADD3CD91387AD25819E6C673B9E2421F8B22465B91E62539706579AECA5F61EFD0442BD8D230BF28A45E133A3A84E670F645CB9EC726E84798DE434E3BD79743970070BE5D96BC7C59050050E51BDEDEB74204C546722C62180BE677BE5F348ECE3F1CA8754E56B4866362B3F85DA70039ECD2713279ECCC903F8912492A320265922AE7154782904DBB5CEAA41BF42A612FBC7778BEA414B72D304C0F9AB839AC3F9844002EC0936A5AB70B5598C7A2335E6B0827B4DB3FC9434AB37CD12DDF8B45B0742155D1278B823F95712C9F437DFEB37977C96A61FF58BCBAB7DDBB45591D7CDCE17FDFB4793543163DAE9EA3560860DDC797FD3A9F9FFE1089485DDF004A2E5D3420A10AC4D6332022C18BFC0B4B762555BDA20020AFA3CBB33179E6ECCF71864C200466A28D39DE24FEE24DFBF05C931B215490621DE320F5A5F8221EF5F4F085BC873C0FCF60E0DA9C30D29CF2375A98046FE90262C881961855E7945428CD255E9B3266D34844365A10F04E533C489978D055CC749082BB49B92A574F5BD93DF9751CBB7CE3B065819E0E46ABEB2BC1E01BF31F69D4D04C752D57A4AE5FD2548042383C2B3BF4D9951F575FEE99205B52215F4FD67285A47F13E27C0FF48D924E3E24061983CBB94CE39EE6FB94DE8E8FEC2CDB43D7B88592B9C1DF4C1FDDE728322E27C99BACEE3C2B40F4996F27565A454735EF4977FB116921393E964FE2F06913ABED35849782282688B2D4A05EA0B068BB24EAA04D31B0DF024CC845FF9EF6AA358957170000BEEE474BA05C98DE6A3A7B25C3AE90FF347E231841773B20C81013A6CCE8BA8B0C048CC24CDEAB59BA03776C151756C9F7D7F26801C5DE1D0A89ECF3730A7C0B960B8D458B7724B0B6C9BBE5ADE5232FFDA9BFE770E3A44F25A030D6E7437A43645C32B3715A72C44A5691DAB8A22D8F3743E5B286DD8463ABF24FAEF72D69AC2A13662BCA8BB70DC801327E5E6BB0A491564B03A33E1EF4BD468B8645338A3B0963DAF439637E4F703B6C753A5CFF812D74C909FC5A5C3C74D128EC21134AD835DA5071662846DE039D0125EB8DB4F5756B70144AA660EF354F60207ECBF4E71F78159F303DB891D0B553C8410260C8EFE95A5253CA0E6DA8F8E242BE336C15B3DBB784CCEB89410FEC3DA3E11F3D08F32556D64CF9908EE93A7CFB4A2464B8A91A845BF17E40DB9C4AD057D900FEEA19BAB0001C62203922108091940FA46CA09DFAE5AE61C49737A1A927914830261F214C97AD1BC95D3D7ACF2CC18504A768A6CA528049CF80D15D1F75A14542403BC1842B944628FB145F86CC2287E2CA2C474E9FE18DE39730C2CD48AF092A28A8E10EBFE68E0D339087BD81E3A6A13209BC84BED40CE38C3E8DD9ADA8E7AE603BC0FFF18224C2623BF1553070B6B8D247ADC9E3DBCE2059F9483656BD0C7BA2073CBAD822D8210DF3CDECD4C8CFD0E31E4AB8DAABD954C2563236917BC3B69D7FD0233A6727662D74B1DACC59902A4422DB75D49BC542C5BA53639591ED5E08A74AA80A52969C7D3B0DB9E974642734A22050887265CA80FB9D04FE6D67C8C009443386EC676C9DC3A0C6A3DE7F5068E0BB21255AC5B56CB0BAA51EF66BEE9BE3D55E836B4CE8AD55137934A65B53CE2C4D9877D31BABA7BAF9DEF94E13BCFFF1D419867F2CACF758A72C96F02F6CDF0D9E392A331ED4A712CB0904EB9E3D6E2F71740EA439F50E7E53AF0CF650680F9DFD52F6E013BAEBBC7601E1322656B0FBF8857B68BE154C3ECFA043491D3893F78CB9737A45FAE9083B99A650037108C8790B4F5C37AEEC831B1552519942DE4ABD523850D32B55F4ACAB3CD9E589067875BE6ACA634348C361281B48C59A37909C23CFBB11868169306B775ADB7A9952CBA481E0AF03181F6C0479C433DDB38DCF3F76A1F57BD79CD1DDC5345C0BC9E4B9322D0A65E9CA2ABC2CF988AEB047843E65C46B94570440B66F0272F182D2203DB65B3A62710AEFD4C1FF9D540DF3F83B04EFDDCAE5F66DD9B6E1137D6E0A6B3BBF44A995AFC1BB78D66E9CB70198D4EF8D43A35D2281CEB56712327F5CDC8A105D7C3A54172C5EA0627390785B7C47C0378B7B102EBC78356A64AADEE13048F0CA0E83359D1A5D94", + "sk": "BB9BBE6194399CDDD376902F1EDCEB65AEFEC308889936C76CC219AEAA403F5AB2A9D6678985CF8786F69F522175BD04F4CD743E00045D3D4946EE206845D21DA867F2611FF3003BAFB007C16E69CFB635423A3A162E27876374ABF58E3E14D326F06FAD2505E77263BFA84A72031CC9AC22D96945D266C21CE1C43E993EB953042722C398881B106153423299A8480846525828211A150024B46C14A130C2A66024A62453004412172D02B2080C16628806311C42099434801318862106515B226182A605D43489232705194668413229D4A82D102852520260D2324083C02981C4301AC509032724E3A4314A0245131345DA8270CAC671DC4265C9822019972160004161186820841013994D63208C124592D988640BC06420186E54B68940B651E0203089C6001823100915415A404D443231E20026E44072CBB2098016700317681CA924540491CA804512288AA1368943080AC4A2909494481AC7640B144D180906501005D2A2081401218B184401481020840C02A25114C63014359013010961B46C03C97081428823861103998CCA346904827111C921C444251C312503432D042665C2142E59442E8A848508B909D10880943866991808A4020E5404464302219A2621038421A0842D10B040A2A4050AB700C49410D9344964B42403C08484246043306648B2492401895C0470C8B061190680E2084C00466860108CDBC04102041010A4048142519930415C068160089143866C49A031E4A4610C264409C628C8C40CCCC66CE3A29002898818C98182C0491B276A0B832C03A22C64306A010272CA428E18048AA3980108A26D8C98285AC208A1C691A33026A3928CA4304164C89122B96C8802489BC680C4060654404051A0080145051A396A1106311A46420B08054BA088CA88480800049912306198710328246194609234719C288D18334A014704841211A4C82DE4282589A68042462D18028ECAA8454C82211A28881C900008449200306024C53122A1850BA97090C02C4B344E8A80640134128324858A086863024022467040945114234D52308103381008B30DD3400D999465E1246D2438901932001B08401B433251C80CA0864C901862A2301151122918874D19266C03C88824022011122CA1A42809A4305AC60492244520986D12C50884262EC2324124134AD3002D60322224181261188112242C0A3168E4088D4012841B016E88C40014A00C04032C08018D58400203B24D0C93048CC8288A866508108114235100B6901B347014C204A1C62D5B10250A4071841671E0128EE3308E138128E4846091364A1922119C966401944420954C61C4911383108904642231220498690401280A9384C9422E0413721B1420819220E42832D8B0014B444623B2640AB88518046662444CDC2670D3328208B66D1319440CC1100A183011171100092584164C82A60823C6610213610A992022858521072C244465C0B81111829119B36549A649D4A83122392024348544384CDAC29108A788A438311813001B070AC9188D23B700D1881183A60C93346188420C52126CCC866553826D22104124A820D1204D0C9870C8442210C110A1246D940480E19881D320490C48444B26681444620C060080326888304D14C9701A198C81384A52C09111236D129621A23072DAB04C0CB825242826D4348C8320905C32925C1882C1C48CDAA6290813800A0410D12425A40822CB926C024302D1027291382421314654182E11996D24118408878060B40C02152C1B2331D2A0501B080D002929DB16000040109942624B88701287615A368E0BA0718C080A61380522346564264004242DD3424911154E11A84C03923040C030C42049CC902D0947011A0349109080124910110948194260C2C24121A50D20858089A4891B3402194930CC902951B88100B640E1104012B36821116ED4366890A421A04651042001C18665C040802116610280409C0821E02044193311842081D3288823438A14B90144C640D8A82122858C94B66913444A1911721B232EC042464336490881695B4050DB164AA28850CCB48812072D09B731A3B084E0C22914B82C59488E0A3801DBB82C19166D08A28D08B668532252122632D1B4800A408CC43251024760A08010910028499845491486D4B050008544DB8888C8420C83B46C22C16014413100C90424296DA0020218384D5A2250304FAA14081992194671A66FA05EFB40A6AE3511B1B259FC17FD2F928978BE51A64EB05E5DDB644C47F9CBEB76168F5CB9E54DD51F898D296E6AF042D12F59BF6FED3069EA304F979C28AF642EDF92518D765FCB5F34FC8354803FCCAE0651AF15779E7CC672DA376509430F14C659ADE2BC8075B0056DC26A74B3C90F9E772447E134269210EA86D1387FA10CA354C03437F9DF2A77962709CBE8770CE88279C88EBCF0349C0BFB121E018D1F46AAABBDF2DF379171F7526A295C65FED8A1280FDA9EA8F5D4998EE93AADBBD76FB16F5CE48E7CAEF9C41C19CBEB3880CF6EEACC849E46A752A23C646BA788554BCD3D218A76D88A01B991AD57178B24D724D0CE12F3A70ECBEBB531206D81CC2DD8265D673DC6C5B492AA576E1027F7AA88FFE6420651CC96536103CDA90607B38B8A840A963C5FAAAC63A8CC58CA57EBF204E80A6770A39F7A8E094ED5BC4DDB86A31120F7A968F23C1E151D2479631E6A9D011671F664A59D9BB1A0192115DFD813B0CDD61BAB1B6F7660F680971C4B55DA6EB791774C64DCBC8B8F0FBB3C57618E29DF5DE4023A7D9B6CF678CBD0107B62F5A05C131F5672B5693C23CC4DB4054B92DB2B3CFB59AE81328A6F265C49A302D92A8A4BDD8C8A832758FBCD76940E85566531A946D2027EE7865F23B06A51E80EAB7777DEEF62B1CCF6E7FA3ECA6CA495C88357FB45894578D6BAFEDBE6B0F6A8AB672CD13AADD9006101C9E98738819073393C11A383DEF2A4884B8136253D3383E4FC13A9D90483DE15D4DD12D85F3A03769FB77F23CBEA1DFE0AA49843578C032D881320C6DD3091D82D106FD26C54EF7D21F539EFD3BFA928FA8D6C74351BAB5FD6DE02CB02EF09848BBEBE76D2F4FDB2A484A7CF0C6A2484BE8F56EA052A1E02F4D7D19B0020BBF3958455E2960D4A7EC5B7C3BD93AE5F716D7976CA10E4E442762E7070920C9CA2E767FA613FDE222A1C42E135165BE4852EFFA36EC20DEA6609ECBA9D57EB47DC8738A24753AB72657F4B61A2317D7FFFB55F395094C12CDE5786E13F565AEF078B62A1B19BC4DB01FD4C4806CAFF88B4FBA065230A6028F03507B99611B5A9888D64EA6EC5EA6757FFDADC5F3F0538D7C34E5A69DD305B96CD03A1904E9320E28BD71FAD85C99ACBB30527DAA2926E88ADE20CC255EFA7F4597746DBF433EBCCB94C7A27552B7075D7574EF0B9C3F7CC932AE97F827CA09E8F4F109D9D48D70D39F10F1334CD583EF43012FAB8D325BBACA1AC63D0672E41D300CEFBE29C30DFFD952F5C70CF9FA0E2FB1F954499A7412A0ED2E5F3C9373C2EF3C2774A72A3D649356979EAB8E70483305F1CDDF9B5ABC0FE0739EF3487D3FDBCF3CCCC0FE4D6E30001278973577EA567227CF6E86116E796120DD561C56CEE924F330BCBFE336793D45B310B4ECF4D59B7BD35BDF0EBC9693BE646D6E6FF663E87F32CAC11E2BCA4DE5915EFC42FB1B390B1092F703894A795A2982999F0FFC55F1958FDBCDEF309DB3869307A72434CBBF0F8EAE903301B9B62A7785754E10C7F352D886DDD1AD381B1D7C4194A413B887688A6E800B36A75CE4E2ECDB587C99CC7C1D62D69D82E0569D5ACB77F8EE771C170C1377C56EB297BB7B8511C15ECFAD5E30EF7BA659B7EF754FC9A82CE1EC7186E251D7B2CD49909DE53CC4032270B2E8B8779E6392949F83D9FF8B9F76F80F5C85C8D1D9B5D88BB4F1107AAD0E6AD1BF75AAAE13E666691FBE698CEEFBDBA8888EDFB6E918CD3AA718C6A40316C8BEE208DA05C16920182618C0431237E7BC6AEFFF8A003DF6254290488D91FCF027DBB45FC2C6EC752C9DDD9435D8C343C1052A5DCA889C8B7B5705DCFFB21A421ECC2346798883D4A38594228184B85231113B94476472E972D8E1E41B224BB1BC50DC9ADE64CA386D2E2E86EA39F164519EF36558AB08E12CE2100020E325F6EFEB62D6154C2D95EE780254C8B4FA85D02DDDD85572A9E498363C4B59AF5F65D307B6E85A91ED3F1319F5E36FDAA20B31B6DD07A7E32FA65FDCBA46BC573AE8720E728BD15B1046BAAE89FA243208F51EEA38A627DB10D086E69F4D41522C42AEB53E5C71CD10D683A362D155193D998CF296D404DFEE6BE9315D329980FD414293292F9CE857321EC51DC255F47D55594C378B7D200CCB47DC13A21962C51799806AFA87988FBAB95B1CD2DB023B6B3FE148F600D927A7F4F3701632A784532661DDB474C682C670844CB96EC569BF96187B62A869644E17393B5F52998689F41D562FD4F1DD4847566C9683D5B1E6EAD5495B94709F11E393B758D63CF05DF6A041168D153044E4F24D49210D1092C3914C4B61E410359F7311E80D79DC9169209B7201A759B50C956534E5147873ECF46812032CC5EC50D58218E92C2B4466DDB89EF5FC7795D2B6A85D159E3F5BD1A2758DA5D4F9046F50FA96A43FDF09A6883C29821DBD5BE66FBFEFEF1D667996DB4594967A1C786C03CF85B130C89946F85CD156CFF490883120A9CBA6E64C2F9279EFB006FDFFAE654D6C289364184DE60B6F2424F3D473597D2987BED78FE47220BB72A8D81D8BCC850C4DF510CABCC0CF1937D1D39768E9E21D645C356FA2D16D16987FB18C14B8D24D5D5EAC9068719B38D418CBF64774FB15F32C473BADAB5218159F6BDA323A209C699B8EF093F34B60F022009F09B2E8AEFA824178C5F8DA0E49125170D47AEFCC010837623394B396356B053405784F232DB4A6ABA2B94D821D2CE665DBE354C8F69F632551F6DC897607398A32A5B9120A044B79F7FE2776C8EB3D3CE28A13D654E58F45E5508995576F3EE3896859DB85ECFA2E1AFA06B7B455BE1048D4214F87D82C0758484230A76C27241661C08F024C2D9EE1168A8D4AE74F297DA8EA70B21A0CB8CE6CF0441A937B2F844F4E61F1AA566929972DA86FAAC9986E08578BC29C4DEAF9327BE415DB29926300C1FF3D63A4AE745275BE7F3857C2C83CFD209C4ADE1EA3215FFF40BA37E9DD31E919CF1988A5028FDFB0BB42A4C0E5CE1AE608C92E2049954DF006182932415BD872F067930FDF8ECC7AFAAB7F96429A0B516AC86B6624FFA59FB11000E804DFE0803BC3C33E77CEAD6E4C87A7BC9A9DBED7ADBC60D14A17E6369E391585EC51297D1BA15A3521B7A84E09268EF44FD7072778963E6AFEB58C07843A63514F43FA56DD7B130A991DB5412B32BC3950EF4B4BFD99D72D119B5C75C1BD676D3BE15D3AF8CED24B0401D25CDE43C259B93A4298D556FD5896971595C6139960F94DCE6B0CDC00AD70DE34EBC6CBCFAF97FEA0692F8FD154E69C3D84E0D41F4D834602AF91033F7995B599A33B1142C81C71D4C2D27407A353B91AF878303B4779F38F9E679EDF5F8FA13318B899E443B398BAB9DBC14922CAD6633CE263C5AED77848359D60E8D1B96E605BBF8164488F9071268D69FE47C0B6C26963CB56541B8F15709D49EEC66B44D638B5628D075F2385ECEA51C9FA43D1D9A51A4FD9DE4E6A8A2B2F68A09293CD1D7F52FAAE9D6D0BC87034ACF0014CE0543A2C2003F07130BFA9C0B29C7974D6C9BBC45A7995BAA62A780F7A1A168720A12509F1876F641612E70688A6E4B4C87666EAC6C838528FB409D808B36AADFC5999563B5D3AD57DC12504C0EDA94DD2F043D6E33E21D7478B298554239A9FE8361F445C2515930C1D896EE0381FC14127BB072F9FD50EAD1C6CAB24E7F8A493D92B63D30E5048BD8878A27598A51E294244BFC8C33D5C0CBC2507311438546A8D001408EBD119001D6553DBB7E78F03DAB8FC785BCD199564512A47B6F020A5E57C494F7EB73F76498ECE66C799DF38ABD4DB146C988E1C0A3FD6055AD305CFAC490E18AA791243B7A92AD3B1D8CC314871094E9111583157BF9F02BB1823B0EF0341F4A11EF810CDC887FED3705F9DC0DC24FBADB842B5509D6324D468EB9255BB0015CEF339FD2C649684F8CFCEFB90FA3E8212331E22D976FDDB86359077684DC3398D81C139A8FEFA2808FC74B7C0A56439FC9DD2567D9FDC273781C9CAD88ADC6CBD707E97DB4B989CAA4E3DB3A2CD7E419E2939041410DAB36621DCF04FA9DE5D8AA38450C44ED40CCCDE3358D770ED5C358523CB2B667986D11CCBF1F6975C8BD7BEFA496BC9670C205E725DFB4F3F28A54790740D7D56CF20282795AC1FB768E9937547306334B37CCCDA4CF158B5CA0DE2EBD75D9E40D6B664B9EFF37E943BE1E7215A70C0EB3BEE3DC576C8196EB71D97DD62F58AD25C02FFA64270F63EF90581A736BB9FE4AF4334090E471B2FBCC38ED35D8F430764A4113B736E22AF6B7AD1489F1EF2C8BC52F8D4F0A2D06CFB9412DBDF67715CCA91B3877E9681B7209178D06FCF3130067B02ABC7F9DD59A65668E259B1DB1BF68C2CBACF5B36B3645D83B4A76743C33181D93C93926CD6AE28EB4A09B1DB597BC4A9E394650104F7974AC21147900E038EA8B41BB2ABF78290B0475FD8BC6948B24B5803B0F35BB76CDC9F432D5B82A251CB185653FCF87DC68FD9EB9D1C7F84338766D8230B0CB50061702D057E308D00C3A31EBD9561BEDECF00288E3B5CF7A01CEB999F3AAEB33FFA551F3917AD20AD24BC3E54C728EEC590F8EA355D00E1A54FAE5FABF85311915644469FB3ACC0AC1DC843F6F84FB0BEC6FF513F3F1D286996AD82ED9AD86BD51A28E447196BC9B05CDFB004BF2AA19425FFF47" +}, +{ + "seed": "7B4BB05212C7AEB83E3C04F8C9FFDE0526EC4E22E29EA84260A89292AF1E4DE4", + "pk": "8909FE1147B96BB2A75C0A0A84719553B7C4D0CCB7912B824EE84F4FF444333644454CCF3B324CB3CB63B33BB9993989DECCC7E365DC5BA6BFB2CA61B49BE2AE657A20053EECE5F192374812B2DFB718D6DC45B46336AA5A230D6D30ADD86039FFA5B1E84AC2C0448E6BE453992287DD29E478EB0256552CDF84AEEEFDDB281138DE2047CCDA934FA337A9EB9D2F257D554C9E8163593302DFF2B21ABF8B7FBC319D3DB37B8A2E372235EB43A865661858A61B679F3FF11E6A03DDB1DF3FAECA1C4098686298E1070A1A5944D7BE4663312C7459DAD3F214370DD2B56F12FFE8AEEC8EE26E6E993D8341ADD70313D5E6010A771684CC81CCAF37D7A7A5FBA2CEEBD6B0F80D2A4AF55164B4188A5273CACC9053555413D8741B405D21D0601805E69300546AA837F968802C2CC2AA8CF4F0340B82001FA5BA71958FA5BEEC7A94AE095F02FC54758D2AB1401B78DC1E10910C97C5DD6F0D3076B5A09AF8A9724240A263DD2D54C16C4733551D9C70D89948B58E99C8BCCB03BB0C3CB5422169608FC8ED9FFF0E66D2109A024218D168D0952723699D3A42C082A2DDA76DDD835818C627B57A972AA51B1DC268F7181BD112AC73E436EFFEA1616794815CB1A37D6EADB92A1009F84A508E16EF9080D76DB153B6852F874EAA47DE5C338ABC83CFF5F2A99648A82C44CDFA1A50B11B3C9FBFC1CE38EB770A3531ECAF373C0F437C9941E7D0EB0D042F1EFC0B55F8EC97C785EA3B153505BAE1B52D97DB48F2D2E7D7E70E934F2C0F9943E3F9869DCCEEBFF0CEE6D1DEF7E4DD610A0835728BAC3C827B8FB92208F5B9DE25E43D93A6EAC1887F032AF66CBB5ACF6142C11DAC310F2EEEBD7FA25CB0C0F8F940E19D43AD7F5270A26365A01FF200027E173D566B5E77D98FFC1134F0628D241EF306EF8364120FBEC93F92E06058B2BD70ADECBDB9AC63EE0BF8A45F52CD80D753620D7089D6CC313FA5A759EA6BAF840271374BA5230487A928535F47843D3BAFCF39424E62693BE9712332D312B831019F8AF6F68FE5D0088DC979C9B3995ADD0B607C399CF0B8F651A057A96ED323A7EB597B51AF3AFCB9B99420456244D436E81A01B4F2ECE5B87D63EC7FE6B505FC34CA5D7373B204124AB9ADE3B290EAFE5AA73704902A2E3A404F71BCBA92F0675AFD825F10A10B4D51DA642ED0A9667C2A16CAA2BC77CAB7AE9E20D114DA7FFAF501D3D1783A58029877A86C8EECABD2E18D6CA58AD5F0961A1CBFD8A51BDB49EC3FE4EE5E796132E5671701305A650F75B4A8BABE4803C5727332D1B123508A60FD6D1961B267B4E4A418F4D1F2D95581280693AD13882433DC685B8D60C78414EDBD6A5946D571FE2D897B094C77FB5FCA27A9FEE9B6215886776F3843F681BA3A69453835BD4919D870AD573E19808C55A77642681189BAB4B2652F52FD6894F70FE1B63F31EDF0A1D3E805FF4AD806DD627504870EF04C1365B1CAEEA148A3193252927C8011A3976E5254815035132D7EEE8F3010C8DB2486336365CB7850D4E608E68974ECCA90000EA4EA4D146571D2720F79BE23C538161E5B558FF5FA40E63728B2279B1EE255D8EE65E2CC373285043CBAD5BD7A9BE42F6C282FDECE15C6CC49BBFD29E38F40993F8A17456DD3145FB717AB10353DEC3236F3F44FC80F853943B57AA08E8C543C35276D637D07F59CF67CD4453828542CBD0CCC0CA7A2CCFBD0276E70C119C37F9118962F0298AEB4663C9A1106234B4C55FF6517E775B275788263E24FE6AAEEE46E5D082C5336EED7A75ED3293BB670B49E705AB5E9EA0EE336EC8882E7FB1376B18EA60400BC9F66C112802859C8AC80C33B1309B829DA0D4C558D4D44449C02537593B456E842CAE22D546CA071A1E7D141D7808C1984E9FE431C62F259957469DADA36DF63D0E5C9BAE0620F09B2A3181CB08BB0E0BF4E6CCD34E8DB992DD8499A2AF80027FC34ADBA843F7AECC46D4D4FFC025A55B6188CD8E24496AB28F94896BD8049DB9EB991AAFCAB2EEFB31151724A19C7587773E3BA238137AF041139F0428892D255E361D375BD5FB318C4A39F524CBAE368033CB88B616DDC4B2C61A5BCBCE68F7719FDAD95655E759513CA1E6AF4D92AA96EB15E9080DBFB4CBC50399717B5EAE40E6927D574A8144B24D721CD2D1633BB276335846E2E86B2E6C843EC53A779B7A1E9CF5D94B710E824B321BA89C502D03BFA73B6B76BE8E330BF90EBC6059004F9BC8F2656F0CDA2B3B2018319B70E0024AB7E1095C22DB13F49E42DD3D9AC800D7307CEB9517567E0A4668BF4A0CACFBF1DD9C1C86D13721A026E2F4B290173B05F60093042A1B081A94A830E028B2AF8A31BB7FF432758F54B63B34E49BA2F15A7DA3638BA0F5BDBB2527BF49B2284D51DEEE54FAD5244CB85DE2AB6FD689339E6F89A20F803093E0D4D186EB60B5D8E92DED4A8A095066997943A3A419589965EA3661191FD10DD3F6F068459AC38C44598C09B4BE609174EFA39768439EB72773CEDEE9C433DF521CD530C26C08075A13FECB913A70C658AA12E065565EB15B6BE0BB52A57C5E4996BEFB524845147F836A492C46D95A8041FB6197BCD33FA9CD1C70EA3CE12ACFA92F31876DFE3CA83BF500A47CB4CD9DAF60F411603BC7A218BD0B8502D25B66039737C3B82C7F5B4FFD12FE8DFBEA60559A0317CD489FC63086A8DEC42CE55F282C264CCE3F52EA88C6DC173D8507AFD1B99350F89BC59FCAC65AB8EB136F67CDCDD0559A8E8F6E919F827C393C70A6D010F19362A3EB88FF30BC48EE9791386B5833018703C36886D0A943E8699CF2072037507DCD197E072F356C2839ABE1DB04DF7CAE9ACF98029231BCF574CAECCB78F65BB8FBC7F3C88CDC1F3E256850BBC89722CE402E424D7D0D3268B4628E93220129B715A962F3D72B08FA532EC208FDA8273BA045820B3DE9E76EE42968E8A386DE4082AC71E5F18724D7EEF285EBE1A39F6FBBD923C589840B20C07FC2E0C56DB3B521471588F8F499A71DA654ECACA5289901E02337F0E93E230621340D1F86F1DE12883C356AAC5E68131763413886DC46C754E163F53DF1164F3C266B6D468179FCC130AC5331D997CF82277AE746A9276788520073F7DB46F13877215B7DC9423452CE9E815D836C6CC0F04DE3DDB088ABA39F8F2CED319111DDED7FFFD95CB1A1081E25CA2ACF3FBB7E80BAA8B12148E1E6911351BDEB116D0AD319670ADB8E51C7D533E1CC899C47A809368B94A841D0B21A5FBFB5868654658CF6C0AB08D7069320E864DBB8DCB9057BCA35DB465E21E474CDB26833C8BC10B0B2279B8F73DE7449ABD2A7EB34DC01D30D5DFFCB9B3FE320F500734534A3BB22B4FFA1A309462ACA7F4DEA20E112A50F5FCF222B85139D908AC13F0E8C66353269344A344043ADDD5B78D25172B02E11673457547DFD6D4FCE567E52D2341D837B384087357950914441AB621C7F1865D26DAFBC209C90FD4390B87D9046FDF5BB44E98414383306504F0FF35687B2CBB29DE04E7E191AE48FDD50E74B83C7590ED2270BDDD7FA9A6E12E28F4A5286AE07D7AE1DFBADFA9127C7665902098BC3CBF12AC9F3F826EC48C9A22AE3E76D8596A1E98BB6342211B4EA25DBB92F274B542B01DFD20A6E96A69ADC103D951C72AD75A32DFCC55", + "sk": "8909FE1147B96BB2A75C0A0A84719553B7C4D0CCB7912B824EE84F4FF444333601E8A88ECD7C376304233D07CB229E18A0F8F5242BAD485115B0D4FE59F52EC045E19C137A08767D4F88F17884897464E9BA4CAEEBB414FB0761690875C322A3E134C4E894BBFDF177CA6C3B36A364B9FDF0AD02C9775A612EE58D32CEADA1E31C036440A83119042A89B0644A180C203069C046840892092148124C1009111608512266E3B88C00C5096014044C328989021291440104B2210B040E0B9390D0B64521888908A72D110821D2B448A214696446469A222154300C59A04400B64550126A004446DCA42C08A825CA40821B0869A30484C0363118998823C308A43206D104115A2420A1B840D48680544406E4462213B584641230CAB244C9301098929100860801267294904CD1923001896083445049842DCCA62CC02649E0106D62A200D490651C9471CC980C08155044A68C08B38D98C4295B208A1C9060DCA2251219621AB851E3C29114B90052A0255A4291A0423061A62400B96958A000209224E4008811886C12366C1C411203822421C98549C06864B004631826D2062C53C668D84000D2484492A46912970861128A5200055AA2001390811B036959486E5B940DE0044A94487112369123A4449AC465C8228E50008D8A440C514625D2262EC384255910329AA8110099890B073141186DDC002AC4C0901120321184804C382152160D10954942400E52B4400B290A60C60113028DC81692D8B624414830D9040D80982CE1981010B46D104800532800E1148209100692104C4204290B401114B628CCA28591A6295C424003436901B3605C404698C401D1489082B248018545013802C4C0304AB2045B386104292541426221356160B84904338921400880148421020A8B220199C64D08936D5A9668C1241104170A03C404E132811B2842C1B24C20350900428812B9115802299320711A469291140C1940459B060C4BC61109B38111B22942324111322C4C288903130A01C10C12C72141A06D22112A4C94906396505196700C12410CC06548A60C9C164053C45004110DD0881161280A113702D9A06C20C22C90C290612028591040943842604432083292023585D202020C4271E00642A01284E2946040040998480A09B36914094100278D02164D4A42908006884A220A22228D441250594484030382A2364E43247119988104834D11C19064306C8A8451D44030C24470209069C0382DC1304C60207193320E24848101388D92244AC2108E94B42580A82C543860E31204DCB644A48605643489CBA021D1226CA0202644127019A900903432DC4866DC224C492666D0060414384CA04040543805D9B090A21862221984E2300541149224222ED8128E0B304D1C816C999221898601CB48891A934CE0964162C645033484242891520806E3301001850108A064138911991251D1363019094610B8710B4465CAC04818C2301CB4702407898AB608A0126080408A49860418228E1C1001E2124CC8B40C1A8509E23628983809C0C47152968123940C10484E8C060A01222250486422476DCBB40D8A460D5B400200952960482560A6010CA56041406053284E8018651C496851948852C268A2B281228411D2C07011114D1C153004C141C8302C01B629232231CB283291324A13A9504AA4218A068D839064123528D8346522024648109000407298841194847042028DC2C8200C006DC3288D4C4062484601A3B06D08B5881829261AC1848C362660244208062024C3215A366CD2220C2229220918728940288B0891E4282ED1268D99A6718196691B986952128C4438208124294386815CA84C112824D93629CA802183C06C21004A20174613830050A608023026E2344800A48901388201A96C0B1409C3281101236E19312C5A46058A2068DB98901BC489DAA4005C2206889441A206659806901C10629A26481C2820D2228819400C19086C639664DBB05114426AD3248DA0462941382D829690A23661A3002DE40672DB082E410885D408691C26220B2342D81489A222869BC8289BA470043129A0B829E4947052966D0299654422291249510BC824E3A881C84492D996815096308C164CC116421AA61198A2444BA000A0C6904BC02DC23405A0108D20206521424EDB14440100481CA70461062623B1845B866110816188B228113484020671A426690CB7CE0406096708570A60CA36F9EC4F06EE56DC910BC6A50F8396656C7E0E92BA130C46B7C0A0E6C93545004D161412A9C88AE285DA2D9C60803900F24C95368B9456608065D9742A1BF2AA1A55A4DA1395A8FA4A17CA371A289AD8D096ABB7C376193D5BF84D5F88B131EE9377B11A77996BF37B8914DDB60AFE56846D386903026BCF2E196094B3D1856888CAFB2971FBA819C13D9FE079F9F2E02865B99F95BE311CD9DC448E51BB106C263725CA163F92A4CE0293CBDC12DEA0E49FF5244432A2D0996C2C35DA3355CFB2C6EB81E346D78DF235C64FA911F1157B6C4F0FF2EBA91D047E7FDB9908D7846E17FD1330CA271C0EBBDA6897B6A49E13DC9BE2E9115C8F3AA1802C5A6EE67CAAE5ECD8FFADFB9D126BD16AC7FA6AE5E9E2757177C1FCAD8B98EACAD20C5D7C7D9760F1624F227F35FE8B0EA0ABCC09A27BD0C98DEF908EA7EA19215E99DEE4BB71F94C1DD9EEE76137B88B2B9B331BE4ADFC417B57124DADC6BB25FDF6DA925C0B1E38A54D06AA317F9FE9C9475F79CE2293FB6AD9A1FB5DE2A0DE7F83A82657321A85DEFF62D533C05268EE059DFF288D9A2F600242D5C54D154646C005EF65D927D2B76BE7A8413CE0B818EF5558B204C18B734C6ECB75CC164B2E3787487FC1BE72CE3D6C5161B769EF8245131612B735F1FD87CDF915E365D56FF3F124AF6A565FCF3CA82B64C25AAFE3864AFE380E9FD2245331C1B59A4D62D3820BB441CDEE09E938FBED8CEEB13D2B54AD7C4FF1C9889A18BDF8842535F2837B011F9CF7253919A64F153AA00B44B343949FC8829E855E76980A357993A73EFC718A04DD59B5E062DDB30013868CA4AD30CE8F24912A7DCD2D6CA69394C229C6E09A2279F2329CEA517C1575CA61BBBCA6CFC3C4F926DC9A0923DC859A8C01FA4B1BB60C5C6BF384ACCBF366A877E91EC85A20967586FADFA542BBF0AFDBC65BD34B84E3D65DAF38B3DF497E8FBD03369EEC861575C2E4144B36CD77E23F1BDA693D45FE1C201EA08A3CB4C3517F85D24170D7AE3D2172B9175BA3A38194AAD0A82C32426B6A306906CED1BAA59C48F26F5C1D1979C47A5B495DA33FA4A359657DF97052EF48E39095FB59D7040833D67A0DF9EBC02872E905D6A6277224426D47B409674819181993C7207DA14A11DD151E4855D3C8F310D13019C60B6A1F1DAF1DC3D2E60E0BEA448D2A2C9A6E7BAECA8CAFAFC7484246C036238BF6FE2C5F817DEBA88DF00D10CCEED9EB4898A2C61616C073D5812C3C0ABC9BF0BFB9C7B7D4C8C1D13CB2224EA32071DDABBFFDE25117EF6058826CCEE53BBF25AE65FA181E60A8F9E41D0BCD99F21B5F3384A9644A6DF25BED6DA8087A29FF72C84D25B674BE4BF291DDE146DEE6AB46329CE70D2EDC8A39DE7C6263BCA03D8E09C3F7393D7ED7F4DCE3D44E867CA09E18ADE556047F72527AAE88FC99E2E02C0225075C88BEBB810210BE7CFE43921F1A509FDD72F7933F30B42607CCD44DA422863B77CB5049E466D49476644F0A26B8BEE0C30CA43AD756CC00EFB6A1A151C383C8213096A5F4695857F14777F9CFE6F4E425ED61CA6453A21CB0C9C4C3CFBE235703F6BFD3690437FDA24C030E0B0819836C08693E3FD605A2C1E1DBDA347B6CF30223C8499B5FF08793F7646610E7B683E4A9CC010AE1AD954DFEDF9FA0EEEE26BA0F24C2B88AA18A89C1441833AAD4FC205CC5D8410CDDC6D8E518E6FAB1CABEF217023E90F5383CA8F6C6EF373C907285553D4E39E268829E609D9324B393C7957CB832063863C9AB5BCF950C50B97A54CA45752126809DC9D65B889D1E0CD4CD5EDDC694EDE7BAE2374E9C695774CBB58167D870948D5F5EC047447852C44D21F66C1D289E9AA2AE3C06CAA69F35A5D5786BCC97F2934B88430F3D5E8B5091AE0EBAF0D3CF80BC4CCD15481D5C6B1FD0F3818E48525E2F9522B4163109B34C69F09860510875BAC0ED9CD0F38183CA9127CF3F5FBAF8913A2F0A4362B87896461686E43CA2DA5D58F12D44A964EF6DB0EAC5045448CF01923E30A49526439416E6471FBEB884B2B4A02F351CD6C5D9169DA9A19D7C08DF49F797F0BF8942B0DE603A72461B9A67F96F62C5024F644CEC1AE847AD75D6291F4B1B5272A38F89DA7B9B2FB44D77598CF959AD4E77FCAB290F2EC7E62A075850E1723BC1F78AF44F4F5F540419302924D27B20882A46010655C20EA9986375203E85BE0B7BDFBA844CF99448AEA3CCE916F3A8E77AA9DE340099AD924DFEC0F38F1AE9973F82CE58258AB7770BF850ACDC66F71B5F32FB159DDA18C31AE388339A74F59220069F4471C9FD55DFE359E2A6FF3EB874AE2E10288964914CA12179A4950AF63B7316DDA6C695C7050E0AA024D8074AB01C94CF663C45B69DCA8C469F0CE7764444008CBF0E8B6A0EFFC44DE1B6EDDB9E765F4E63DB6148E17A5D196F9B373ABE858D05E14BB282052B4EC190171D5220FC27DF1442BCD7F2AE89C06A9D2071297B42ACEEB9C29F386018009BBEAE7494254013DC1A7454D40720ADF575E2A4EC7719DEC804323818AFE5D24C76FEB187135BD4724E6F18A7474B873B4B4C2CF9593C0F2E27DCC68E4A993FD0ABBDF518F5B97BF1139CAEF1043BD3C7D9179EC1B6DE98DAA2BA247F2AE49D24CA571B6ED66B22CD07C126ECB37B24FF8CD5FA4CE282E482947E0A2988FEE08DD0EB3580DD21FD3D88D1D259C8CFE6F52AF9A1119662CCC750E21FA393A6BE619BB537D216F8448A473136303FB5007551A20273CDC07E058E02A643AB374538CDD5D62E86D7262AF04C2063C7836790910BD7752D4CA7A848B9AC4422D04A4A3F018785EA171A637BB55E7F63B9A4AB7B1FA038F09862D073CDF9DE0C1F1DC6CD644577F5DCCB31D160157BAD4BE7A0410966E98E845F1D8A8D36006C24056E076C2F46169DADA9E928C84277EAFF6CEE3B438E84427C4C95EEB264DE7E2E6C3BFCD5566C5F396FDFDA3E9E2405FBE3ADDCA4B4B4380150355AD3B42BDCE65FA1EE23C576BB4A4BAD816D54184C78F7273CF0227C79FE21CD4FA43E59F3BA5B73DB40E9568C852DDB9A431F788B7C402E7FDDF503858623B0E24024DE4A9D44852B16BA3F4008532E0030ADD805C896AED954858F4496418F60DDD790F4C486BA722FC0772D033678F9E8B6830FF6AEB194C102D8E81FBF4E5FC562EF8226371F384C51C6ACEB930C5F1DB967E394094E9CD59AC1332F6E93714DB498DA10804CF0F549D46050E9B1BEE7DC30F1DFC135CFCF6E9BB55A00EC42587CFE32B22C865388E2015B585F77EAD9CF1CA48E9432E46353C0DFD66271760099778CA61AE954561F76EA4EF58F11287C402A08D6E47289120606E5AEC3FBF24735E9E93647D967E61460858CFE2FD3EB7B7ACE18A5E9718AA8AA412C3D04FBACC721AE4F850BABDFED7F3DF60262C91EE63783811AE302367A5F10CC08DDDB58B7FE6A8D9F5A63F0B61D1D6D8F457222D8FCB61414551224242D82F56A95C6485993258496C43D5EDE518DC9D7D055A42C10BAB46F1B626953DE1472E52AB2A891251CBA71646A342DCF1CBC51C37F0D71F81FA4824AF714E8F2900CEF663525C82ED3720CA215AD8E6F01E6E56F4A25BC969BB455245809789ABF105B536EB2723F064446C0FFCD7F537EA1EF11B4F5FB55562B1CB57860F1F2EB5AD95BCB965635E7804045CCF4668CCF3AEC958F06CB1471B78E979A5351EE9B1379404E7A51CC4F2F3DF703027FB0C0ADBF85FF977DF5F992433C14244E4928324FBF9E527E83775A34635A2D673432588EB69D35773BEF5C6683A54D6338CBA404977F6D5EAB9D2A73FB4B93ED82D04AE0BD9F8CB820363B52CEFF4AB309ED8677130339435C565059588212D81066EB6AC462E0D0F8F11872C9E25460B45AAF5191FE0657999C54021032EE672DBEDAB378039BD67D22CBEB714B6DBAE11D3794CB44931585BC5FA02A72C5C6FB3E9A4BDABD16C24F7D314BF8DDE13BC838CA81FD964F8813149F700B0BC16C41492A8C7B1EC967327DB0AD6147CF64202B9291F1BB8DB6E31736B455E75F117F531CE39CC23043906C98B8684072BEE3350A54BB899E506EBC6FA310022A52C9FA6A0B3EA7068D01AB3B805A917B4E7146C7F6AE89DCD07C4FB4E618D564C25B6D7F272731174BD541A0AA7738FF167008B781577BCD98A3E84CC81B856CFF987AD3E9D843C14D72DC8320445031045CF9D25993C1F179764FC7102208BEE6ABB9F9A332A7A7DE13379A81D030FCAD6EFD94801FA480E5524EDE34524899FD40A4C02AD85F3DF4C7F68E6B7A66E1FD77C1B9AE0842AC3AFAA9430C57A3372072D6EBEF890CCB4987278E3AB9FA11D5EF0914B949CBA37D3F55735C550F56D1D3BF96B1C590137A91AAF14CB520794B63FF597A311790C9A0E704F836A5F89BECE8CE2B895C0E2647D5D4D2665F2AC7C95622F8B3B3E2143E81278070F18ADAF9B1ACB86A42DFFB6989856178B58CF65044905F57D58D21F1E282EDAA5F6472E62952AEE2E9E6A7526C26AF1D2E1CD05F5CB8AD57D9A2662A91F97BCEE97E43464A28B5359F66FF6880FEBC1512C66B289B318804899D517B4D2C6F224618324C940DFAB6601394141E4F66D5994FF5A5F71EDE3D6914FE8E435CAA500E809F258ED7A7029867DB1A364A8649346CC3D9CEC31B2A1CB3A2918FE6349856E037DE1EC177C168655D" +}, +{ + "seed": "31F5D7AB44ACD0072423A8E486EFF6D8E2EC8D9D25040D6209BE64FDD03A7664", + "pk": "C2008A4A1E8DFB167CB02028CB14384D00D006C3F495B89610105953FAD3E77543D2FF7D1B317F28D621ED31ADAAB6CF0443BCD8A32406E82FB4FEF87F8977878C27B6812FBAEB5D135333C20C8EA95BE99F8BE1153AAFDEA8578534DEA61D60644B8B94CAD58C78D4036581A2C3B64172B0F8D22F56EF6A7B8682B062D3D98299342781880AE568EEC5D0F30B9959FF26947FC040EB8A3C6688E33EAA162954422477DF6405361B3FC8A7B39A120972F78859B879F2C80EA81C97D048F8FED5A64114855FA72BCE11D1DADA55BC65DE976316A39B399581C5D55CC06A178ECC954F4D9D723668A9EF6416BCC88A9A215487F17A48BDF6A6763A7FF8B447E87C22D009FCB5F935D66B3F5BC2C1DFB4BF32906F12D3F82C7325CF3F53CB0E73BEF4F8919181C532E75BAEDCCD929B59119451564AA0EDD61C373D4C41AC14E739CAFD09F3AFDB8B50A8F9E4E27EAB64915725B199A32D94E573E6C9E85E1A05B06102C852564906376B1F9732D059FEB25F7A3DB4A0CA596FD49BD6F75B45AEC689207374AF4CEB82C3EF86A4F797661AB631857A902ADD3847C222D6F1B3D49B0043F0F34BEDF97F2E1984237DD115F34215FF1786941BBC42A5A80BD506D4392649C790A0FE68DF5FA9047501731BC408349D6459DA55BFAF10031D71B535D1A385BAC31B7033E315A7B4BA614A27F16FC375EB1A63A96E1C584D0710693C1442AD503C63062918F736FB8A32C68B475E46B4D27449B074150BD0B98F76A87F313F5A9F329DF1CDD180B28F5D94B100A438AA7EE4E46061C02F3B427F4D30ACE7BFB6CE65977F56F30154F2A2E489FE19F866F2BF70FC6CA1D54211398690BF62EC4C21B39C8BF13C654F596778514108D9D0EC8C90111C1A771288BE97D8099E893611B3F8820B5E169C4584246F7878288DF4FA658401ED2696CB1B69F69F3DA8C4CEACD56D33F405497CF9BA898E734F4FCF5CE5165847149E3963145859A9F9E49572A9227526921074737D444C9D56939BC22C00DDFF53007275BE52B4D3053AAA5E2B702ADB635BCAF0187C9143CD88DDC3F684E6313F840DFD666110D63B49BF1E56301C65E6DD242FC66C1FB8CE3F7C7D102FED86D50753D16D382900E6EF46EAE83A5C37C4B1B966777C6536E97EC39D74B4A1F66FE0063D41374498B1910E288C711C037306DEC815C1B3D33B28A6A151D9E7B04E08EA7DB2F829265B952CF705755CF56E9C0E38CF41DA796A621CD50048E05B2EA9903C3DBBB450CEC0EF28CD2C11831F09098001AC2AA565EDD47FAE33E3FB9456A0E5A1CA83D236B6E135C18A61BF0F90C632156B9E1579C56EEFDC8215B95052E10FA03A7DA37C2FAEB811C1003C3F475040A377C738EF8CD80E9BD2800067ACD32FBBCF14AF95EE119939BE55B9F6EF6239C173480EFA5E2BA4E10EAD1F7047EC2F342D853AAEFAA3DEA9FA6625ACF6BDE1AE1CF72421F44661083707D056298FE9399132EF319E76B2FE7D0307AB499E3CD42C472CB427B734D736C20C231DDB7F80F7232B42D72603B137B849A994BB1117AFEECEA2DF31C53B3AC7D7E060051DB3D92FC7D9C1DC173BBD1E7082D8F81BAAB54C6F96443926ADA027F9404ECF8FEDC79C214C766E441162C67BE2F15988B2B7E809B5D68173BF3CBC70E8E1959BCF3B876BBA0A7207A519C484AB07F4570F2491AE1B7E3C5E7D195887E977697FBE4807478CD5A0D181BEFC4DB81CC63FE2F1C5FC89A14F5FD48318A00EFFDB68F7779237440DCA768FCA85FEF5EF463B34AD1F7FD1363FD79CD0D1D6432D2EBAE0629D8B815D8DACA9118A12736E552BA8454F7FAEC4695AE475E5A31368E8417CC498C90FA7F23F5C230A43392A524CA5085ABFCA331553DEC1B311EF3D2F1D29D663260B06644496E1E47424EDB6E9F889DD58822131E2EC79DC037833F0DF0E65F1238B60347F9162DA336770567F4C7DC2DD06AFFA10678267A1EA2991E4506B7BF37D854480BEC70ED1D4997B351A56538632920A99D42FF569E1F474DD178E850F15D20E2BDF33355901B27354CD95D826BF2C21A624193B41D9FEEDCABC16514C4BA02B7E3A393D5AF73C8E012CE98FE6DA264976671A7B42E7A44D56F60AA010750BCD571442E02212A10E2CBF9A65AC8867D67C2382C474014D43A816E89148C8F43292F42D9BF36D5ABCDB4A33B70ED528F533E3296C2E8C2EC244D3BF7CACC8386672D32F81BDFC6F3DBE83530FF464160EB77B9F9FC0AE346BF5654D6495FCA822BFA30C5449F377B2B2F63B44CB8579EAEF0493EBFDF1C8E5E80AA530DCC1B998223371919E3FACC34FCF95022AC900E5F033082D7AAE215785D6A9DF921C63593F43C63E5C81DFC7CF42CCE0D805AC586375ADBDEC1064D16B1348D261C8F902BF4F0FF6C525D2AC37F384B3AB17B6159FBDA15899A2EB14C2E299B8145B2A52EB918CE77A29716CC168EA9B122607993AAFC496B28C456C64DD750A47186862DD36D8AF7F722B9E8565C5365C1F46F065861C6853D7C0CA82FA04A85B6A70C5197487509AB0904296B5E07149F33F663027DB06F7ADABDAB3994BB8A68F7BC943EF87846BF8CA68FFADD1BD50E51EE64CACA906C0BF0B39190E7ECC4745FAD9A27B06CD64F18DE7CD97DC12525ED54466C99E76E206DBD9C0B4D22F5F08F4FE0957FCC7915EDDE8F5E47EE620758977B49535FF4560F0DCE0EB0D992EE0C0DB587FB1E0CBC032C41CA5D2DF6A35CCA6D49CEF7FFF59D390F0A5EF2DC059ACD78AE65E1AF5ED672309C8AFCE6FE2F08B11F28076EB87ECACED71A6C65356AD2B6996402A69FF20713099088DB1504A43AE9725AF07A9F126433B755737B74CEB4D71EB610E5BA5C029676581B36F0C981C0D8D06C2F6B05205B29F9AF32AFBD23E00495D5FEF6E44050B01905EF2AF34B6EEFE5E17483450BAF54EF84590427FBD223A43E3CC3FD47C2AB86A4A1DCFFEE5A51B443B8C7395D31BFFF12697D1FC3B887D2CE4E2CE79C29002F11CCCD98E86501AE57B252675B1F88B8038CBAE8BF1D50EF5293FEF0B4AA790BBC92BD5D995BA7CE384236A59DC88962DB6364D9F27A20C969E6BC8AB636022E340E4C37BFC9105334DE64E745A9E606BD1B5D86277E0A4416B981BE9A77F2889F8AF7244FB8F973465858C4BF9244B306E610DB421F14971C3299C3C57D3F8B09212FA094485B6AC420DEF2E3A34AC7377CE18E03ED00CE575ED85B767D8787E098B7333F425E2336DA4FB1C78F3D4D4DE5BD4464B02488805FBC64907A45E37D0C596B88F989B5F9E5C307AB050526020003679BE079CF953CE9B7519D8C780BAC4EE8A44172BB74900E06F571ED9147C4D7F6C562A155AC6EDC157D62F4480E588250F49B7DD8B1C04A97AABE87486A0852DECD387EEB3E9837BF2035BD9F763507C9DF4DAED511A4ACB51DD47EF283DC43C64433090B89096539F5A506FB4FA53FF96E3ADBC74F582459ACDE4C9325589CC73330116B33FDFFE677B970844BD891E1B194F1F2F51F457D3E944430EFDA332A1E18DBA2C83F58989A3C491439BF5227C7EC2788663BC733FD5FE173AE87941687060D217AB5AF9FC10F119A177FBEAE000349FEF237DEF84C52FA1CAE6CF0F89639787BDEEB7528FD6514FAE29A06D347B2496AAD01CA951BA1B423C", + "sk": "C2008A4A1E8DFB167CB02028CB14384D00D006C3F495B89610105953FAD3E775A965DF6F74D379106E6393F7400957F1D5753F6C9EB1E8420D8F9AAE113830A0A153844DC529D49CFDB506F7A3E4A92A6F7B77271C17FB2942B1144CD5D82DB4B9BE60A655BDF10FA3F5ECA7F774E3B11F9676F5DEDB01B15423EE8E63BD9B1C61940551926C09477184942DA3B46999462A41C86144388E14C6115236600A366A42120A1CC8904C946142004A49204A23412019C869223028A296700C376403B911128528DC267222260E18466910B8519244850240280321020C146123258E1996209036201BA620400472DCB6654C44061B493122338E48A26558223024B88442C65063288203404650025263148209948412822551140CE31004D2B43118A40D0C0061C106011B3250D0202C58166509236AD3300C432289C38001D016080927480C83111B472520086A928820003751A4C484A09020CC4404D34232229771883849D3244042028022240848802D11A3699C284010854D04118D01C76DC0005013070554C40890064921A25120B6445188008B280DDA484DD0B2450C4190C896292145669B060651082A44A60DCAC06064883008226E5334120196518C8611213482838825D0B89121068C142205991282A42268CCA26D01130059284AE4A0041A818C143041E49669A4986C20B441CBA028CA80850B36529C001080040A94182DDC146108213100B550480292D318706302461019858B268E1B0386CB4482DA848D20249102B92C22902D9A90850B90655BC22C88C62D533861DC946C88368D208710884260A3246AE4C2289392889096211395440B0291C432060C13905924658B006C50C829012842031620A38090A22292D4148AE1C441E336620CA4088C922023A740D39284128710A106808BC8889B302ED498880B290A93820C22C1901B443190B205438891CC269244B48154A2209C82601C1480E31484211172090401C412621435216394000B2070D93226C4A24C61406221A2691C020022226ED1000812011221298EC1B80003804153364EC3C2814AA244590848DB42908020304B3681DB268113442850C224E2B84D5C104C449871E200661A877003364D102990D9184510A37194A8459A462E1C230D44304162004A62C841121169993426838449C32091DB026402302A5A148891204E5C0089C1862C1BB19004C1649B28080A985091942411939098A210D41889102766981492D8102220C20489446410148498324518C011A30629D9860188B28C60380D1A475004C0900092050084705304298C322159B8100A2045CC124E8C4831412401CC422CC03085D0C80109334CA3B08024462EA3486D59000E88440900134A58C2618CB88411B30921C72418135292164E49844C81166984C031C9C445A44420DC3641C49051233861228809C1102608094A8B14918A98290B160A82987049C83110462D93A808C28400583070E3C4292340320839800C078A14816DD3A66C41464012152E094828124609422065E4C800D32264C1986019906040488653064D00A741031022C3062C63008662920493C02C8830015C9869124161238624518028E3240EDA00250A9560208550604651830044C396510B024D4A984D89A08CD93232543208D012459B469112998C0808044CA8519436842033204C424161B461918809D9B8808A38448026449C8000092632E294000C2142C906015B986C13916849107058102E18438510190054288E54086089A23102334E21B485A4060E92320558100DDB962D2405704A0669A3B6618C32620CB7212009409CA430D2382514224E0CA1210444210C04485B108A2311641A178299002213A6651B88881931622005441AB34CCB2291D2006D202848C940899B82090AB03189828181086AE2042800262652860D9494891C22101200809830529C46800AA749E11291C808425B326C204424202980A2381118B829CB404ED2488981B2482409298390250047696244040C3929CC08001CB70C09450044906194900DC2B88CCA3628180545A4964021B961D3166D41984511066ACA144814222DE3882062222520976DDA304614006C5C828463482D24424448247022110282300DCA8280211701D230261BC2615B268424054414A84CA236441B819190B6411AB7311CA69124B5518CC40C09294914B870E348265A3024FCA93B3DA173B47E7A5AECA423DF1E771F6B210D4026CD835782F7C0502F779B4A30FF4732B447AAB972713634F2A5CCD9CAD1DACB157D0F8AD04A2FFFC043BFCF848458F964E1B8488300F2763F045F5774862315D314A8AC2DAF2A132421F0227734192BCD4AFE4756AB317CAE107B2891547B7F41C9523D5EF2CAA75ACB48A816EB7F371B5582FA1310F9A9EB6E77AC47A0B5182A5A9F8279599153D6E157D2602E65ACA3353D058AAD1FFD32B43AE51A11D309279F31AD00B6CCD1DCCF2D8B8A9C453F7DB22F9A11C45A42EB492AFDEA3E67382AB800F44BB853A26D5A15139D3B4D0F187AAA8FDDCABDFA5B53805A972788694EEC9CABC95683A97A7CABC1C724C738134B47A96BCE7202F0F319CA1D7A9D17D3695826BF15B3CA31E27047477E015C76FC99FB0182D955A04CF8F294E67431ACA9D168F4A32745A8F6BDFEE7EB35E2043048CBE1CB14632360AF375BCE61220FE6826D1903FB1AAA1E2B40E5810A74E85980A37046FF67A8EB28C7CD6B41CE833DB9373820869209603C81CCEEA03C3CD0836E3A65798B20E55949297FB2F2C613C9C584DBB783995BFEF772ED04604DFF8399FC81F1626306844026E0AC80FD6FAE2AFD470064383BD3C5C41DD6B4B8247A9DAE986979B651C927DC309B96BFE0B08B2CA1874E08E3231E55E619D68B7C7F86649B4CB6879938B8294C9FE3FFB1ED88885FAA3DFCCF3FEFBA69A804EC4B72A3E6CEF853B5CEA9014E9AFD963B18BEAD40DEF8EFA134659F4738E87BB2637AD40E9A8F330D01F4E6B34482065BFCADA0D8FEBD24ED280A65BF2B7C8D17241867DE8DF5D8A537658EDC0C568822CE6314AA61FDB322F1CD1720051ECFEE221922052D4B1329C8672C7178D00346E06AC0A192A805783DEEDA6EBA9852F071B544C9E11DA0D0C15A7DC4C14DA9CE3AF57FC20875DAC3EDE8418E8C59B935A4855D4E1B850FD2282704C35565C890FC3EC4968E0EC007DD5AC95912806804BA8F496E37F316E508A4F10842873EFB15CBC267D48830E3F22110AC751387FDB6FA2F097499AAACB155DFE928E17247F40BA4BFA362C80AB133F6DD1260A9D88A7B7284B5C9D4DB0B5792FDAB2E54400F7DEB0C40273D4FA1AE5D7D67D74ECA21BA9C463C7A7C96BADF827570B586D3592938F90C1A7BCB844B2D166651DBF7B4640C02DFF2B4FAB99741C694F0B4294CDA1035E70C46700CC9C359DB57F83635712B0D81EF964002CFF25F0DD2D57DB50D53120522D3D7969951BA053FC36FFE73BF28DF4A66D6316E5F82D97FA867635260778D797DC7AA6FC47D45ACA168F58BAEC6EA5E7D8B714D97F85C260528E4AF146478B2065F084B44A07D328BCC1C05C9475565AF74AC697E459D4B2CBF4ED533C79F04ED4ED43879F735E7D2B5EB2F9E095BDA1F12DF7A9A924B237C2DAB8B510C4D2F317C3DBF802ED7ADA23DCDEE73309D10BE5BF1AA397D1E9F3B8BCED866CAAAD95F12CB12C20590DBE96B2CFDB44F8F8FF240B2B18FC9AEC8921AA6344E08AF638F9EB8EDF4274747AD1D29041379C5D3B3695F6E4E76A747B1D8E1E4C1EB938830E35A0D7F0B9CB272DC43E0601E6A2E00BC4CCCBEA0DE00063E3493C8ED50616B00084476E1D144F7C3988D1E5DB81BDDF8474E591125E6156ADE0ADFC8E4C5D1E4061A044E419A5C4275B83E0203905B9F7FB95E979460BD478BAAAC8FA4F5F3EF043C67582C2F9FA959250B06DB851CD914A5BD3B3C89DCA914A24D694007E39E38C7BDC90798F0D2C86C6C9944095E094DF9A871190922F03ADBE4C8D2A0EB21FE4F7E461FF4CF3FE1C45779356E7E36877358136A1CB08A5CE83426DA7C8263A35ACA21E796C31AE64E6CB32A05008B55ACF66189F5A8AC673434363B45F475E336CD4947239DD9A127AC02436F67A5452FBFBCBA70700F52A01058CF5E300D9780F371415AEC2FF225F07A43F1F51A91FD615935EFD876BE31BE216714CB3B9C792982C29CB32F326D88746FB884B39EE76E60CD0FA83FE33CF14F83CE5F74E14F43B50D03C3E84FA81D9402E1F893A9FB85AADD403DD14C6035A0B5EE9BB98DD068E042F9619055FE80AF76500D38D7EA09249E78B020ECF83CB6E27BA6F409C40809285AF42944BB120002F98406392463EFBE072A99662C111B73C97EE1FBAEA1CA520B54F84FD2C501261C70B2E3C75DB6FF000C4562D16583473BFE99C250722EFEA75DD8DE29DC681D2AAB6DCC7BB865037B21A3179E0A5DC51E5702D48865F36FDA4E8A58DEFE7861251F1E50B6C95CDB4DBFD491A98BB918A5394D989DBCDFFBD34D722CDA9D8819D6CDEA4ADCC5D8E54B7E58B3FF316C1AD1B3BB7393590463F02FB7CDEFC5730253B6D1286A681A94C45025FF0BA2DAA47D2F7A22D97B7152A8B4B188ADACD0F657A4766E2B6A82FDD85582E11D27C0CFFDD271362BE6F07EECE5927EC20BB4B4B124FAFE95F65C0CDFFFD4606378D6A03485325F207727DF828AD10285A72CD009296D8921BC4F1F7749D105F769EABFA7A073C5C3293AA3781BF5D330A7B46D2E9F395645D996C5742CA24BAEA12B52884D354CC8A743CFB85D45029BB421FF8B06562F5F47465F1F39E6C4018C2432C82175F631C57E587012B2B35E2A61271B05D7891669C24CB02E186313A62EEAACC8ADC7B7BC08FA4EF773FBE95ECDA083F04046FDF4CEF88010CB45EAC2C4844B8246FA38AA30358DC0821D70BDA3CF5D32D17A37F708111A171744D65377017BEBF12ADA5A242DA8E602E21C7D5CE680E5BBB5EAFD621BC9D1C0CAA3534049EEF8EB9138369CB86ADBCD4AF9B5E3BFB62FC5C5EC09B54AB87D591A59106A230141085243D2922CDC2DAFB28A67E0D79BA46FF11CAA0D05D258880AE4F5A06C7609A61F70EBCDE82152E8F82F7100DEC3492A186B7C5AECA8F9156B1195A6D6D52F5B55A0A9A06B2796503DA41DF47DC49E2CA1319F212E72CF017BD5A36B7C8083D9B5A34546BB689C7119606779F3E720D6915E310B6282BF98FFB244035E5F2844FE0842498A019E7B8B5BA700B146BF36754D716E176E52C158E6C68EA09F973638D78E7223821F370D0D658885234A5833B3934A9DE8AB743777E0A77453D346066EEDC58D6FE6B13401A9A1D7B98FE7097841D48BB4448FE3D0F2E4272DD8A49C21B6521793BA492EC3A15FB51BD4891DD21AE69AE9F80E6BB6E2CF1BFDB6B74C8B0D45901DC5A63C3A71826CFFA19212F5416777D85FE9B1B815AC68B686B247815F43C3E0B094683A8750C9B51AFBC27816B6164ACA150176611C003C7D7953D03B2BDB77434EB2768CA4C212D1A9767DD5906AD1D6F5E4AB545AB0878619A538B6C317E2DC3770D24D3BC63ED31D53D5173F593B732F2BCBC08C92CCAF492AB76041EF3EE0FA77F5AE55ADC47B65911E00B3BDDD5EA3385483927A03764474224979399940E83A8A49C9B76AAC5C271ED87DFECAC18B4AFAA992B2CB1A04A6C4647C4828B4AC5E732BF7D56757EDCDC8D079883F4BC7B3F3A9AB775C8746DC376042B3AED720B913B007FA4C6E525C7EE033D9C9931769DCB844E8EFF509D3220C5240226707798C722C7B97F2C59FAFADDCD0ABD4C99335F4870D9A3D486A6D06D2A00C0FF61D9EC4085B71B90638EC2F4CF72B3B62CA92F4256A7320D848E43F7B8ACB62C04AE8E9CFC42D9C9B96442487461D71EFD90773562718988AE10E401D00199D35ECE065BC93257DBE1D38629C2CC35FE8342685E54503A75F15BB29E3283903C04B9F3CC1B02CB85F4DBC1B2BB30D08AEDC50F39ECF324AA74DBFDBD04BB87A36D31BD7BA9E70B9E7B90CA61FC5DEDD2CF1DE1868ED5E473E93E7E4557EF081C39628B13A1527D392306078C1189A0A1B6BCBE31B421C3588ADFA39E4EC6F6A16692E5BA669D3C4C67274D5206519D852A46998E492980206A01C6A1B533CBBE304DEF68FB87E423158956769016EDAA9C48AD9035958EC3AF95FC45981E329B7BEF0C5D11D7B80CB7C93465239FE69FB3A5A34EDD0BED53A93089D9E96A3AF7CC03E4F4B6690A843255202A72B93A1EFB195031947DD6A7B0FA9783731E690B513824754C7C685D7B8B61BBBFD800862D9129B72FB46BF7B310003C3D46C0F4B449C8B514A9D2DE61B0A8A9EF48BDC5AAABCB548636042C0D2D3F548332FED043A48F81BAFB4897B9C8BD16551D5908BFD185E9DEB2E66026959ADE4B9E0B3E9F04D38D011E77AE8F38C8AF8C845A05EB7D072933F3BEE00AD376962028674B7042651C91D4DC89290FEF1EB6AC780EDF600D23B8EF474045D14877607D74DFFDC2E9A7F661A5A94678CE458EF58CBE13DB5FDBE2F38CC6674A23F1DA4C7374D38D618B7E98B4B48909340DA000C0DB91FB691AF80CFE6B11944B72ED1442C142FCC6F412F258F6EC0B0B08A52BD097CA708B6A6A0A768B4AA802D50DB92ED6DF4E5ECB03B9E1F776BB4165BDB002F93AE34E8A8D28BC9F910903DF77E26D607F09891C4E7446EC76760C4B96FE3F72AD5BC0327AAAF4761A9A89C2C8E886CE9A74187FD55AB7C0E6948358BB7623849F35A4BBB487C17600235EC49B3BF86178127A3436F6580446A41A7BC4F1B352604539B90A444B603E98C20C75546D0D4F5715BE12610E44EF9AE6F600A7DB33FF2133F8695D12321D20285F4322984B0FA1819C4A0136035E134E81C43F9400736DCC8F3680E71E9FB90" +}, +{ + "seed": "2ACCB6888C3525515F10A2ABEA6D7A3B0CD43AE249F1F7CA93D1DDA58A6C825D", + "pk": "AB103F67F9038F77E3AEFC61F60F953D651B57734804C319AA1678B2E43CF2F7446001CE0A183DE5F05257D64D4495DDEBD5FC90DB67196FACA8155CE9EE2145A7A4F4CBB8E6F8B620649EE54D8BC9D680476C7165E32941B3648C86D916D8A1D738A678764AE76944DC953B8D94AF1B9535E14547F6BBB32882E43C7649638B65AF3D61995DD2D8753338E4551A5D3FDFDB7BB3AF3A251C4B05DF5ACD422FA56709A2EB698C80BEB9B83C2F7C0DBAB0639833C141A9338D03EDED1478C6F26052D3A07D6479D7D9D84C4CFF0B3E12720B766E7C805119FB5D31CE45590B52E7113F35E5EF11A5440B6567C97C81DA59A73A1040CD459B7689F6936687B964FC7886A9470711243E8338587DB7686B198AE9C7AAFE58FC0158514D6B2D51EF53C824D73DABDD5B30041EB914D4EC5EF290A3D8A55B628773C8F8B032B81A683D5850AF64753B142971B7E492153BBFB255187E54D98B887F08DE5AE72A89C55F13FE2D5A9B90B8020C5192C37CCDB325613BFAF29F44621CF82041BD335CD8DE84F2F9DF7BFB7241E7AA8579952F4FF6FDD9F7EC8EABC2F68F730CB648D00DDCB6D51ECE42409DCB3BE74DD78CCA1E392B6FC36B0675EA6549678DE83C2FDF4385C551625523CBDCAF7E13BF38B67EE2282EB27F827FB575F3C01A41ED95249452A58F5B3595A9CCEEFABC5591C873E7A726FC20FC3A34C1C665FAC9DB9445B34AD03CF4AA9F3F33BA8AC692B973AC8869D4CD25D4CB1AF9174305894AD3745046E1A536151AEFD1B2E8F6AAE6EE58756D7FAE3BDC18BBBFB750AE21C043A643310813D1C73C9D8BF31B9945C2AA43DDE3BFAB9EC891E2205DFE4CC7B375DCCA358CCA611ED274FB4DBAACD67DF7D2A7641EB04FDC5879E11B3FB7E7EB0A9324F665FBA610888CC8E471443CF83BFA95E06AF1F38A7F7A694E7D8B112DD215D34851022FD401D8551390DC00CA42557BD6C7643E6F1CFD137E2EE67FFEEA6867E2CB1956ABC5AB12E8DFCAD33FEBB318FDE62D8DDB0A5490CCCBE0A8728E74BC0891C94C0153AB15D06E93CFA99AAE2ECF7ABBB04BE51E613BB9B8E19AE454690A57276DBE1FCBFAF1052C05F0532C003A28132639BCD2EE8D453924D7A40E8CB23FD0D744ED49E1D402F4C05E739120EDAE70C937ECD9F2487B09FE332936104366025EA468F495776F17B58843766AE40D0BAF21306F4818F03329CC6414D65CD8BD1E360E61301FFEB702C571B7E35801AFFAD2DDC0CF7CE32A51B730223976E8DCBCC3DA88CCFB5BD7497263CD4BB742F2D46AEC17103E362AF1B86ADCAA662CCEDF940A009325CE2CC47E5B95B77FB23F35C188214AEC7B862569D4395B7E4CCA1F288EB7AB777E1AA7EBF0A9289BCF0F7FAD99D3529CCD6DA43FDEA0356CF1E9D0214FA068CCAA8762B6CC3DDB910ED8B1FD92702522CBD20CDF95C352624C2CA7C2DA5CB90FF964B5399BA9F0A67F4A7D062BEDA3DF4F7748058E104D97AE54BDB511A83DFC2A22934E782B3A695B2B7AC23A689021734936668BD8F752E638BA2877E35E99C3C3560EF6AC2BA8F3D8361E4DFF09EDA4196FC07D0949818B867A0721AA2E861E78CBF3BA63F52E72B9E75EB54F847CC8DF0BBAC4B1519881D6A9E3B0D3D609DC9B93CBC3569655DEAD9647732832BDBA23D7CDEF931A85B932C16FF7025E860199228E91AD9B7BEB70AECB0AFD677E0970E8C05612FF97BFAE7EBA53D6243B0EFFAF51C4EFDDB569441FED18018A90034B482416A3CB81E9CE8B7298BF8A2EAE1D58661360D2E89F3F91141F281618A9E0A598D51C4B16397D44C9E5C2DC5DC0457BC4749AC3E968EEABA9EC7876BC9E06E61764A200B2ACE50B0C4769B123A6468A8225ADFF3BB072BE044CF43E41A4D74E85E14F911BE15B950D09ADD90F01DEFC9E93F1ED782459635C0E857F77D11FA37BE582193EF0DBD16395487054854C2D3C5E9A3B30580E109873B1AA16EBE776425D33071BFC0F1BAD64DAC7EABF51C7EFCDB63C12C7B77E9BC78E8ED7F33A5E7462CE2EAA2249F0F3321B1C0EEC70C8C47D548200D531B68FA189DFF75E24174BA92BABF96919EBC584F0D35F5DDED81ADFFE82DC9803385CC3C645C3E871C9778145D45572E1DDF29BA88ADC365A2655F1C279A842317CDC42E284B213D366112966930EB6EAA58B555D43C7798853E84B6016F93EC8A0171E4BAA4E22D61491775E54E4A3EB24A618EC8C2AE256121AB12CC2BD08B2465B0F183F2E0645936B44B3D470E1D12F8872308A832F5419ABB76E78BE62B1BCAFA38867661957AB45CAA5C839BF949AF640DD0FBDF8A5F61AC689D21C4981E925DE139306092066977493B79670A5993DD3CD6BAA0E3EA035C1A53246EBEAD5A3F41AB2FC858198B84BE5304226F85D6A25DD002CDA5A06EB8193C377A905D180599C20BB3BB51FFEE1A459EC52203E81E495CE1259115205BFB9C528F929B0BE0885D8310F66933956A36A6D451E15D19EC52D5566B09F0B958651255B9E1F2AED5A71CFBE458C7D6A3723887CDA58A63DC0C768C1E6B63AF3CB8F1D0F2F22BF5FFE71111A42E0A0216E903958B5F6A02A6F6851B0E729F33628FC1D6829770D12823B17E57166F3FC6D803A138AA86CC1D10C9B704EDD7FFD328A88D1A1906C8451FDE1708D6F5E9766F026F38DB1E954A8B3FDC0C894BF4EA565F65A54A1F66B39ECDE5EC51FFF1210944A8D72DA94A9638A9ED895DF0AF096D9AFA8E98A234CACEEA1B370B5DCD46824DD6DD65FDDDE7E978659A52D9E236FF1E8196A145B31AFE40A01DE7272DB0FE2C84FD270CCE6D1E592CCC793C1446D5EC3F7620B9990381C8455AF18ABB60A8387B0BC84A2C8AE26AEB685DA301BFDAB4D41115E98A51CA921DFE3D551F778C37A8E308B02AB3684F4E91AF9B81AFA6691821FD2D36ADDA15FED1C4683AFA2140855C430985C1C41B272AD2D41570AB1043A7FA871350E27D90411AC43CEAF03631027522FA1C7F164E9A24789462C7BCA902ECB7462C4B1D5262F1184980D6AFF4BBE18A085693BB54AFCB2E95C1F24432CF4AD37BA682CCCA98C8447B698B14D06DB3F04BAC6BDFF61D9AEEA76BFB393BA5AD68AA5B5C784557EC67B51BBF3BD90E421528DDEBFCCDD52A9E0683803D89847E27E5BFF389F9E5A82BAD38C36EC56A73947631D2400C6102C9F764B81C06557B60922180754F9E728323AF15FFE62D74AC5E9E7D0F960E5ED4A66EDB2D38F775C6A41B08C43ABB3A9B561A61C908C1B2812736BFC9C6B4F60D1827E8DD66488AA1A0B570B2779AD3EABD0EAF112D06F8BEE241EA22D0FB770AE30431A3F1155D06715324281BEB83F8D6352BD11ABB05470984A91C09009AB0C4BB9AF268AA0CEEE8404D50EA18088BDB5B9D454FA747D48C843DA2268694AC4D858700707E2F01EE7895D550554441B83052969D9E6A8C7381932BA04AF70D277A0F90C7BBA0400ED0074448BE6012DAE3F2AEDAA20D0329B2B71D9F42694B69A5B77782532FDFC43F04E5850B7EB7C4421FA45C06AB0247A533FF8AA42A10AF60E01E19D1A0102EC6508DA62F044A05A27819BA6DD7E728FA7F57463E36DB3FCA730C15E08531FAD965B87B370533DD8200E3271BE939721F34B96FFC39D80765CE1FAD8949FD9460805B51C02310BB7E67A", + "sk": "AB103F67F9038F77E3AEFC61F60F953D651B57734804C319AA1678B2E43CF2F7D400BDB6C6487CF73211781219BDA2BB75DF877C94B708AD56A7838C6E8F93A03F4E076E48B75928B3477AC23A937794A4E46188574E1B75A34B3366C922159B403DC25FD105CC7D1BF6C121B4C9809AE0B7438C29E81CF41377958760C8E33D44463223246682C24CC13021D0A06CA2344AE1A8082307119CC6800B346D003791CC124008054A82202AE1004D42B600DBB828E1B8099AC4810A8209108769CA101018464AA4A40050C40502334822988501C04CA4204C04310114160A18822581C86C5AA01181342EA306455C209180828008872C1C4448033980E348689C260DE1004D92A22C42C061C426891407091C498402432A8B0061123668DCB8080A8964E03609908028018420810886C4446061144088302C8222050A3685489608200928801288230448931489624021A206101A4791E2C4450A0271409200C3968C03C44C51B804401844E1A28883822D90960DE0308610072251046502C4318C86901B338614C24114235144986543088A1A204018402D20401002C04060982818340093246004A6200A2462823090E4305251C2300205124848884C866D00233123A86D22232E11170E9A1044E32060521225191002D2C23141A06C19A910CC3040A0C04C21274642202450362921300C13B08922C405E41408448271D2322D6184800A255120A07150124CD810408A901159026120436411260DDA80258A828962921061B02C22A071809404990284C4466252868401C020219024A1868D04108A134152C2246998C48003250E4B066804367209813194445111002DA4069249B82101B32C52C66C103229CC366A11042E91B2810BC56564124AC9248858286C0346520AB6050917690B11820491214C2005D3A868133502912630C4086C081389D44642A3B84052100CD0969020188D8BA669210145C936682046458836306412050A484C54B2092238600A440821098603098AC9B230012601A21484A14046D0908DDA42114C86841B21890B1071D106891C2562D434029CA610D488400B300D440824080670A0C43043164010296418972C64B46460300E148131DC2284E4382C631892113829230024512664CA422A1306290A894450200C60A41020211121A5650C2311241065C4982100310144025000C549043100C1482453360A83406294106CE28891DC08255B0681123969E0B2311A030411C40D49388644B431831662E0062DD9A050A11241A3208480968D49340188888D110622A3200A0C990548286ACB3849D944660A81041C0766A2C28094942000862051A425E4180423116EA3946411016C04816D0C410EA234281B3692DA004D8B488C118331CC968410395003C224D2C020C2027210150ECC80484998651220218B300E63B448213690C9A4099CA22C13157001934C4B3472D0B06C5A3202C20882A40688249328CCA4500A2772C20472CC464062904D10C53163B4442397608BC44D22218C1BA54421042952A608A42402E4329164466C428228182684D036892236268B066D9912610A2206D0C0404818490BA28D121165512286D93868138768080411D8124A9318491C3381DB107041480D5A0404C82404022686C9A08482B4481928064C845009154218006518B231E4906119286D61B00050084511428494C4800C022989306ED1B4445CA66848A42424A584A298640CB90843C668102962E3368C5BB0500A4050433031A0269244202AA4122222A22404128E62346D93286153A84C9C42410A997149A24DD33831D3064D01906D9080645038511A377192126263322421244AA3026C12B2451AB96D183802132612223649D30410D9B628A1902022018C22262DDC224E1A82881A1106CCC65101195002B890DAC49020333193043190360A84066251A40101399008018E18218223022E4C942D01A6611C940921200649842D0C488E441085420448E1142063240809078223004901A900223941021992423648D3189224260152348E53022251C024598805C48291CA023241221210902018C5505BB24CA0820D239560E2A68D909669D31869A2C28D84442C13B961C390249B0885D93630E032721B424C11394C1B206043144E5A263009320A44022EC100658AA0651B176A1BC08D8C3425D9103252B401D9C24C52360ED4C645100692F07098AE41A05D93A1C684A6F85AE0C3005091536D975F58E54D87BDF53AA30AF6D208193913E3369AED4EF455E3B740B7078209EB3D94FD7326D66A8B0C93261D1AE17B84C1F92571C48CDF1197FBEF94DA93141A721132B8531F7BA05632C88D29260A3DD24FA18A3ADF458AD3ED969336F625CA4EF3AC10CFE394D8CF7AC01A42B9303F6B0EC1B6D921675C44C96E554DD6016EF83CBCA0D43F87F50F38E39B65EE5E2F371E1903E829D9B38D0465878A13774D98E98ADE50B44244C04C9AC0C99382B6CBEE6A5471D6051B1B507E12D8FA5AD2E75910CE1DF16EB223DEC48CAE8BEA1F6BCBC5CEA43B6F88F3220907D43430F3103A9DC71B99D372AE154B7F4E0D379CAEEB10E92FEC9C8B1759475A488183D3EDF3FF9B59D52A86ACC623E383D71DCB0C89151547E07F3D1B60022406D823FCD9C035F8CDD4B5D4577D31520404A1C4B1A0785B32FDAB02BDB35247031CA6EB0C1B8489689CDA38F2DD803E1B27D06D368D9F4886D33267D49DC5E5854A0BC0D76B8A152013681F24D774260A098E90C3476F59860F19A0CC0E88FEBFA673CF37E8E1D60928F014BD0BEF831C96C87ADFDDEB721CFF4926DADD97A967DEE812017D1C5ECF64B67E723C26878AEDA15711F06BDA9142F3E0B7BC5659331362BEFDB8861365154F5699B78ECF66108A9E7B689AE9177F0CCBED79051402B0666365E8BDAA3C781526AE71D00A6CF14B1AD10A3B369DBC67448476DE311EB5B66DA0520FDD4180F2FED7B5C8FC91999E09CDEB463E2CF65EDECD5255F5C9607706B9D0B066BA2D41008BF7447FF67787C3A35569A2D5E7D68DE2868F16923D61F8D0DA5C1BA5ED8AE24390D33857D4C2C08C91BF604525A0F677B0406A2D19CE949E0054F6B6EE0129E95561D62360758212316C09447F5AB159C1B327C7B90C5C32F09C4659DE7AD13702DEAA6DE5482F0EAB4FDB5B7BF570A4AD4D5726105C93560F6EE929FEA795ACDB4D3F1B98CEDCD2FC4053CBFFD8F5CF5F5A6DC1FC7BDAA5BE8C450E2EE64492A06450EFD221D228D0B824A564AB2D4FF899CE2C305B9CFAC7DF5E51C2EB65AA525B9BE9E430E607794022F0C027032E257007A576502C2920BA7A343CDAAE1B9E096D19959E80931B407CECD160DD330581590268CCA0CEDD1ACDEE0FA31B4080AC4DF0C5151383B3EB5B16C6000905F9FF28271FF7AD1AA6958CA868307DC40EF3C841F05A05E30EB923DA60BA5D8FD5ED3AB0DADEF52DD483407C96BA81C11A37E33B02FBC54EB54EE96BF1DAE0B2C8000E88C3AC653C722C93B35A983949E3C4A813831D54E9A08703B71993C13DE6A94D2E30129453E2E4D63CBDBA6744E1447481E76546EED9E83B0712CE3763CDEDD290E1F01BAE87BFDE6782B0800CA3E01683CD4D5F7926E8612C6FEC9A41B80D324E7EE054F8A56B29BDA0F9DE74E2C47C8D891B8D872E0936EEB5918CAD91EEE3D88DA6C1F1CBA76131C1538F6B0F9243331622F9A606B3EF3B3E034B77BC21ACB93063461FE91E83CEA487C6A21C2DBA19251E456F63615A41804CD99CE5CD363390827912CE79139762E72377EA7333BB81D4379956DCAF8806C7602365974448481E917FB5D453447B87E1BA456B6CB314ECB8815C918678DCBC1BE64E993C881802049A823131292E7695BBE6E743CBBAE9CF2BD1785AAEC2FE504DA418D90BB988FA6D3F1B6F9DD3B436AA466DF6B3CC0A9494B4EF308D8E3C017355AC0C4526845822B9ADFC2C2E15EA2C9BB3EE8B02B3E3CC327DDBF7BC98DEBCC2170ADAB1E9504307E7D7B777B46D8E6323F6B31C44A47DC6C25BDE2F6C4DA92A63CC4EB9B5881CEAAA535EF4531CCABC97D37933D401A09380DA609EB0D17C5857724192D01DA491E0E8E645DF8615C7285B7ADFE1959311CCF4AFB0E1187C3A83E6439F4007B689CF94A9AFD059E16B3521887FF6FB6F7162DB089D8729C128AFB65432985693F8F6F8FCCEF56FF9083C5E1843E1AFEFAA44892FFCD74A0B7DBC23321B3BCA93338961F95F4C700E5E4AE13FB45BC9458BCCA5B032C7C9884B3FB67CF59FD60CF1E9CA6563A52CC13C8D4C242BB8DB246635BA3A50624D50B1F54EC0E2F08FF9C725EFE752218F5BEBCA4C37BED12CFAD5B11601CF8BC57D5FCD3D44466BBBCF94D653512EE98F60965386A314B83957E8FBDB60123424A9F403BA489D0EEB202AF8FBD9D8D92C8F05880F60B6EE96369CE58CAE83827018E0ACB77C66755193525C80CCFFDE7DB5FF123FAB4CDA0DC97836B6712BCEAB0F4F7C4FA3F83425BD7528F51A4BDDCFAD5A66D1BF90D093FCD0EDE8FFF11DAD38BF851B2313F3100359785A0A77124C9A1E3F3992F16763881C4426BED570B96CCC534AFE4FE62C690C9CEEA653F737022A80B1E7C26CB3493AD4FA370AB6EA6A6A7B34B6494BC3A9A72739491684EAE5BFD22204939DB2D4C263C3692225327A9E00AEF5DE8F94AB7AFE69226E0DD7FE93E6331F2CD353FF55E06DA3AA647D0C1597EA2D31ED16B0200885824C3981AEB985A1D913212A48D6846BBE760631D3EC6238737E7A0A678CC3069917028D611664503E983AF9D2759DB89C298A638940486167111C39DA598782CBE48DD3EF3CB55A4BCB83C17C519666AE344F4010C80808247D6FE659643B9D12CD07C0282ED014147369D84F415B273D3A959836C01B4D7204FB7906B6271027E271B506ED489C8447B73B2FCE2019EBF11836D902027744CD0B5C3C2F1770EF816884281ABA2F758A740A2B1EDEF583B76C7DCAE57C46D09A45AF1D1D78CC4083C243BAFAF302DB0800E646EEFF1E63F0DBAAC2B4A7CACB018EB35CF8B06FB133129E6B8583ABD49B8A374B3654B0A5760B5103FB748D7723AD10066FDB16C35FF25DC0B37A1A8E650674644A38A17935272F8688CB9CCC6A2E7146E8895DE8BD18D018A5E4A70CE5A61172790A9B0C5817EBAF43078BB2FC26D202DFF4F61159E675F4F0089774BD22A5FA1BB66A83E762A7829A7D02E8A7918D786699A6681AF4D39F862F1D1731DF2214FC7D70F131F5A7412C6E00D7F63E2CDD5F3ACB0A828518CB55257EF7296F25E514D64841A4C27CD72B455F1CEA15F823A49627171B948EDB8BA8A7128CC9E1D9BE62A742CF4ED6CAD17AA5B3E31A61C5263ABFCF8714293379000BA4EC7D75D6363D4E08D1AA0E8976D319668C86366727F9FF004550AADD4AFD9E9F7000570AA12B72155FD303F073C06B550DCB7956E01C47620F72D6CD5D611C7FC252E7211E4AEE17F280CEE89B9F1FBB37279A85CE8FB3F9C81189D1589574014E0938E1E03979CB6071158BBEFA2755DB66FDE520BD38BB9256AA9EA8482AB1BA7BA2F723F26C2DDD7788A0C1B7E864D2329107DECD4F14C5C77077AB37A84461B85FE005BCCC49BBCD0659B5C193DA7E7EBF1EC4256A62472813E0F25A2B7BE0C7F305B6529BC4B0202C9535D38B99D27DA84E4B4BF4672819A44B79D7A22107AF80601B8814869D95E2B7F41C5C74ABEEFF67C3850162DE79F66CA805A0686976216A28DDD130871671A028F57BCC8CDCBDD44CC294200F980E8A1A3516D3E2FD7CEEAED42B585897CAB5967C53C5FB19541169FBEF9A6B748AD8087F215F3CC7D6336D0E70D1CA1732FD7F379DBB0785F33056D5463EBC13213A418014324C5583D2A79BD7C83B7F8CA752858DE7BC2BAEB315C8053499FBD4F1C76D862769AF953A3CA5B02A34CAB38D49A694CF7E7EEB1D14B13BE5F69D356F2FF5536C32E1B4EF7BEF1F8C70D62EB608811D4573A5787F5B31FB88728479398175AA14387623C973836A1791946B7C3B67DBF08E60E9E3A397549F3BDD095628E4E0B9601C795A925BA25C2DDAD9E92F4B114F2CDAD6377B674A991EDB6B17E9438AF7D3EAF61524E4CFD0D1CBFAF5DBB8E32BA2552CF016372273DD77C327B161F0D2BC9642007EBC98037A9BFA24C441E3E1CBB9E3A91AA3AC2FB19C0FD388472AF2C76FEDCF0879CC92BD1E75A3BF64BE4403801226E7F097B20BCAC08F580ACF09B9034B66807E9580A53D65FC2454AFC9FE6E52D39C29EB8E6E895AD2C5324DA8ACFCE100425783B3FAD39F62598D73B968605B098141D931228435622E2C3DF1B1A597AB163FB4BF480094ECAF884712E5E20226399369D4E5B5F612E6CF60489A48D4CEE551DECB1D91F100E7238DFB1F27ED04C1D2951384E96F1B7025DD0C1C3143830F8AFBA0CBCDA49118FC1A18FAE7E5BB3B0F0DF455366D3017F2548B2B7A1D20996408B194BA0F7A553B942B4AE572CCF76EF9B345547C1B2C5BD3377115E923157EC7DEE45CDE95F9B1895845D9B51494CBED188EF9AE6E6CF6275179D86F5077FA6A2E9F2BF5ABA69D9C1E937A75DE26C4C74525C8E64FF78062F508B6A2FA5FFFAFF9282953855D561724D1325F4C3A8BCFB2BFFA60EA0B0F7945CCAE9C3644E1FDD4896BBD03468268A2B8CBB5AC94AF36BFA7C1901CBBCF72F08BD9E3887215D37F0B7A89A7D07CFA92704915A104E5F179478CCDED737C1BCFB46E8D40F09919A9DEEA0858F4C2FB3613099773F6FCEEB9777393EFC9563FAF43C0410B9D66966B415A114A570F4255F6CBCAA3CE563B40E9E599C311D38A3429CE65A92283E03FA26525AAA3B71C7C897890075841717E708A2CCEC301D1D80F1062DEE01460C0A134944C33ED0AFB6048C3095FDC5FCA7F66A9B9B882" +}, +{ + "seed": "DFCC13CED6971EB1BF3243CB8EE883FEA9677D1E5DA8F3046CFA4305DFB79127", + "pk": "86EBA265F989E4500C8CB3E387CBE26508A4032AFB8E978D80EDED75AA4692D5C010151C22FC4A843F9EC4BD804908A705A154CF2A75A08DF94175AC8E1AF30AEF9AFDCBD3C4C6C265527FC557DBDF1E390F1B3112682AE1BC1AE0A45334FEAFED6D1A7FC508068CE2374188E40B4C03FE8C373551C5C1A8BD4C707AD00B6DF77808B06EE9F0464E75508C1DFDA68A543D6616B37F37FE2D1E43F94711F43A7CA806728B2C1B9DC5C3BF3FE86740CDE4BE46A95E99818CD277B12E75878FA1DA028A30040F643DDD97F5F7761056578FBA1C6AB256A803B5B73F4D1C35EDAF40370D4A82CA5AC8E7CA15C1CF77543D49292E4DDEB4CC67210839039C85FD09D9AA3B16707E91B02596240B26C9E835EDA8337DE7AAABE7D17F6CDCC29A5E1F896110265B7A4588683FE140371906917D32B2E7885DE8EAAD0035F4766D0D5433C86D8B909DAF5AFB02754AE3EC78C804B939D04FE775A777CC8BCC0AB91CE39724A2CB0449B3F2519EE086735694E2F266A3936FADF367A032C84808DD355F805DDCE286BAF7DD3BDC27DAB1714224016E1131C222187472E3F9B34637DFE6E5E5B2C9597A8C0AEB21532EEA8F9B1730A20FF975C7EE0FCE46513DF1C87C7A9ADF3B1525267F5FB9230A5E2DA4CAC0755C261AF59BE7F837550A1EF13F3927A1C19909D9A308438EEDCA0E01EBA5AC55B53A9E7DF7259A99D0F1DC5431CB9AB3EC47E0E70AD2EF0CFBA997647327A579E6A4DFC84DD4D49669F8431A401038A4C60FC5E6681F46F4CC13FF0264ADB54D1651050CCC13505E48314889F34F023B31F5AC55CF6DF0D6546486FEEB64542171DD2CE1B80A7BB0D21A1BD12B2E04106DC1D062D3A82BD92539E9AAB000B53CA1A9D22C8D3B28702CD9E0A0E4A6E1049EB64B08F47C409CAAEA917CFD656FDB1975E91B8D33168A3A3FE4F16D948677376129565C07FC961301A45B2120A6E05D0CF00FCD5EB40AFE2C45B4DFAA84CB428B1AC2379CE170A31C75F6C0E94CEE84AF08CF22EA3FD73CC31DB388F77D20764AC80E9D98F951E43443281F3922DBBD7667B436CEEE30311A9DD123A7596C46EE991C5367EACCBE4C0E0344147C065754F5B363020C9093BBDA21CEDD00B447E97C8FFE0616F976E5D9E2645633799E25419CAD1D5DBAEE26B160D3A7777C3CAAFD8993AE177C90D31FF8FAD80E92A6C0148623B3EB04F1CD67B15C0BD4C1A1838FAD512B9632D5A13503879D1E44093745B1574D236BEBC77D1AE82E02EA2924F83C942E7A11D83D77448B9939B0588D84F7E64727C73647AEC32776C2F867F49675F9807A68E4FA09B2268859F5B27AD89F7EA7F1C8FA1E62C3161D5A92C167D4B5A2E76CFFB8D74135EA212C51A4CCE21C909FA2F4B2CA63C6E193513D8C83D716307FD122E4A6482ABB12C25F57703D37D170C5DCA08D9D39498048D2BEE47DF26F64ACC6869D7705ECE719470C69B270BB2DCF12CC014DF399BB6818A1E8BCDD9769AAD420261F946B7B0E73CE859516B9342F0EC25808829E569895123AD2E98C8DAB005D8096B849497892A749A543601F846D87CD89BDF6710D5D564262DDBC5EFC069F33D9BDD8A0B04BCE9ED672038F1031937A97693B9A9933BD577935B00B3DD9249B369478F5561BAC68633577BF71C27895D0543B0BC67A068E0500F90DAF1F5F18011D04A506D3B9AFDE41F5988991A30A109DA4B2D4AAC5757A7429410A27CF63C1B5810074CFD5AFF6A4C4036DB6D4CD62CB75895291A3070D399C8F435CE0A2C266FB5285011172C444204F837C6992E2FF444EE28B22A2FB6B8193FE71D03843146099CAAA242CAC6F74ABD5FD87576A69EBAF3543C6774017B7A1FF5851660B62F54876EE54AF01FC9024BBEAE59A9283C1BBC3E92CDE19E73F34FA575803AAAB0DEE72B2088FB8E0920AED48DE6D5C12F8E9CC64E9E96F153243B997EACE87921188589167F43C660DDBA9DC067FD857AFFE6145C49EBB6FDBE9D4F6FCBE420BB5D4D315F5E2CA1D519FA65D71203ABABCD82A4167B9C8FED8A45141A2DAE15571A61E80169B234CFA1E29F352D0678A487B84BAC6DBA09EB8D66FBB7B3C1311C715192EAB0E5F51EE5C9E8FB30D102799C4E677942B957283EF9A6B5009C784975CF386318D7637AE8633752E8E54DCA2B83CA7E49CBC2FFD48AFDBC3D1098ADEFFD170E981DD89BC5996BF60DD58CFEE25C98B49C1CDADA7015406F001D8160F496131A7C7CEE245E969E44EBB91361F67F19A2F40A9414C401635A927A664B770F7BAEAAD8BC92F77C897CA3266CB1334F8F6BF07E327EF3BCDDF28552A3AF763CD526C7AAE3AE1AA021212FDD48A3FEDDD6044CAC2834C0B02015385C92CECF10DBEB46F85ECC09BAB13533E7AE1148CF63FE8CF943C563DCFB66A986B66C3A4D29D6CD59F8837B2FAF10AB55AE37C0BA03C82319C6517F1F21B2C1C9D28D328B8F8D1B2DBDD2F4E1D6106C1B96DF68818A0C16200C5A5112046197E8CCEF6987B49A9BD0D173CDFFF9B881134C572C781044F183E251EB3ACF77C98E2E09E5ABE94D560C6F240295F552192770D1E0CF08EF6573882C64DB14D4B7EC869F3505E764CA181B9898EE04CD824C93B36290B1AE286C2165B02D7A1C02CF6E3D4530317CC53164A34E675ED6FCAED968A67A975BDAF4717A8F934494235FF4BC29DD78E8610B3CBACF8776EB687D26482E7E54C4EEC6388F27BE203B582549A8AD3DE91396A613A061297CBEB572AB559E95F0CA078D9F0FE2C68983069C3722B771A7918CF81ADC6A4EB59220CF0FD2874EAEC19901940233ECE858767E85AB96C8CC5E2F671E1AD10BA56121683E92EEC5B394DA24E46DE8A0C8985DAC50ABFF991618E819A592CD3C6DBC29C433CC7A248D639CD3A172F2BD674E9D18818C78AD6E50CF09C56E7FEACEE93966BCB27AEA7D0E6D099452958EC60C5F0D1D227CA5B342004AF21B1B8C43A27CF11542A478BF3B5C87DE90E801E4C81C4EE131477B663196E03DA4A307C8E1D1716A36E1721A512748F01A595464C30FB90B1EE1F5394E8E31388BA5C7CC273A61A12ACCAA671DBFED51FC9E50EA536116C48E56FB8F8C2C28859D937A2248D4C1BEE872FF12A75A3E93A4A93840802B920ADF6AD2DBF1CDE092E2C8373FA22E6DE1E062E8D5C71413DA5DD48957BDEE89722DABC0B01464E22E3A5CDF0BFEAEA5879ED77CA5B34FB1925BB925A44C2D54BF9A00519DBC68E4591E08A7AF2547931D5403C42BD7A25C4A7C286D8D1A6D06608668E6890B222A8DF12DC7E06B891BF5B0AA145F1ADAEB9153A58F9FCF63154E18E08B6CC5FE09D7CCD659A12939A3F0986BE7AD5344D5306243F2E5E970A797A5B268A85FE721D5B9D447ADF725080E749B88F795BB2476D232BAE3B4539B5B9286DB664C547DD9A037F2DAF6034122F7F10AA8C72CA123F91909C4A1025B4F6DD88319D5BDACB85D3E1A9452668AFB8CA012B3BCC3DB180982951A287F8F376D59C573CD0262D598925E162365A79F05030D5C3C7854F19964CEF5B08BC0F1B542A8F87DCD29F6A07289F6F7138C31A6D70EAEB89BE30A63DFAAD20ED7366E0F71DBEA8B308E416321307D1B63FA54EDBB8691C2AD4B624D0781D5A6CF2118CB3C56A6D4C0F5544303DAA723AE181A787BD643E", + "sk": "86EBA265F989E4500C8CB3E387CBE26508A4032AFB8E978D80EDED75AA4692D56BEFF71C2EB5536183747EED21768A95B3CD546BAECDFD720956DF067C4F25B1B01B94DA624F662ECA6B0B7FB63829A85DC801976DCE9375ACBB16610E1F4C8410072775FCBEC4F0B34F7E9A81ADFFD2B8BC2B651CAE1D079D43DF246462AD649BA26DD10051C8242CC0B64C1C4064A326654198641317889C302AD11644241872238348C2B84C14080C892065C4204148044C10C88D0930901A25498C208154B60C1B26290BC59098028A493684DB060C4CA668C4C828CB08850C4451D2C62C0CA620E2804C62286CC2480C93880840368162964091020D23C348DC00525C466604B48C00C844C232449C366591002842960D20214C08080143A6710A9468C93892E00865609871A4C2905046720BB448E4B470232682DA466521229119415013490D19434A04B8050C020CC8108698060C4CC20C58422D533830A2C888E038711AB941DB242600892C000524C11411A3A870212224144290C9A83010046ED3C00C2237901C3169C9802481A0400A32700B25801A2548034068912820D9129102902CE2186ED2408908498899C4404A94202119082388459A4020C110649044609BA06192406560B22150324A91B48C02B210000448E0465210C344909401E21240019160C9208409C66503828882882C21475160068C99C200E0246C93B051A4229094082E92166D81A00810026411A64912315062364D604602194151188944C4282A400402801411D4B849C030495A00501C8004442812828460614045D8C424133806991686A0A42D033185500689C0A085204924194800183985D9C22512A710191704D82006D9408AC1928910170619B10150088E9AC8498036524B244D8A8221112140228269810251C92882992268C8804183942D0818894C068A040662DB3832DC346911C961E0120E40164522A08D829260042141A09051182500C1421053A664E1184C19A34000222D4822915AA0284B264012C111E0346D1B957010379023C9850C380DE4283011422614A6484A3452E142128206090C07820CB16513456224878C0993005B966CCB344818800003124A8002300302619890254C32902385001A3550083885930472C4288E10C900634204604409C80226D2442D60046243988422264422C49022B2600CA84D4B145104417061B61099A468A1440DE1368A994486401691D20281CA244420114899268190102812428D50165119404060B80C02434E0B3672A04461E0404912474211C024040592439464993282C1106D01144A002185142525224626A0B888E3C80DA02808DC848100912C0BB02902952119373041B68CC9280411195252146E64204213202DDBB40958340552C82003C80C5028281C928D0AA20510B345D438889284041A8649CA1689901808144712A2243104A611821468CC82209A04525C38501CC36DE1C46D11B161123209443890E112501C37705A4001D9444809C071D98088CC141203C92553404912C90084188E83A0219A902813394CCBB0001A296E8894718A1662223221E1B2852417412193711A86448118711CB40CA1A0310B038514154EE4168461100009B25012B94113C2290244842217411B440AD2923061002A20B390CA4204001582DB284D523224603891132801D3326C9B182DCCB450E4C024831211208384CA144D0C0741C8962D9BC631C01210CA20410C442A1C1126C92846E3B66C2021828BA29121016440142E1BA24C0148001BC38C0327261144260A010A033046DBC849E382810B0370DC208C0A9740D00028E0C06D61B28443180113B3690B394E001660249425A228251A81314B26850C32825A8260D0160D0982800B870821B94CA32460094348C2366248244C88821152044E2314040A353048C6840B976980381048088EC494646232808C34514A1220D2080C83384252262E13C211DA08648CC4890C4746D8C62512C56D64C870CB460011B4205398609294488BC809DA28848CA2681989044C443112B085E32680C234509C484A23258622472953B88444A468E11811032820D0080D8AC484138829E38410A498490C164291C8052285411A056118158ED4A430D04011224862A4868460144EA0004012B231A094802325125C164CCA8870043168C4A6851AB644D92808A4146213346A0381089234282241128192C6238102623B7DF4F576A60F0705211FF78F5BA73A020C3B5D126AE4D98FB954C361C73C0DFDB8B56A6666BEB0E11EDD0336DCA6E9A615259DCAD0FD54B00385AF5E6CF0835D2C8A20AC908793D65180777E45CD2C3397BF92CE8B121C94B3B4E410816938B434553F464F6A3F8EFCF1889553160A4E00BC90D7E0B455717633936C3EF7031EEC468053F036EF3F1B3156FBAED8E93B62132BC5C52D0478A12ACD5ED7FCD44B088588F21A416B76B3A1E05B4BD04A2EE2F210D812C67C4638587EB614E7956C3FEC3A128F41B03427624C98E2652CB37F6F6485B776C9587ECD1E24520DE64B2A9E925B950F89ED3FB37291F520B96D9AC760AB59B9933E48AA852106883D0683DCE40CBAA4EE8F04ED06C20E6F1EB8A71D843913BD8BA253524731ACB3761E94DC2C99AC1022F7713C45D85A46E7042B4699D2CCD9E6C3930EF9960BECC2C88259C89CBC9FBCA7279575D65341DE40CFB2DC3CD80590D46C5641E59DF726E68FEA6D145D0E385B4E03D98FED14E85A3ADC9A71A4C0F3852E160B1948D4FE1A2F77F417C7DAA829077B94BD8B9FE4695B063279E08445566A2E6C88716058A12D0DA5D0E619300C692B9F1622DB08385E745FDA142B21D73BA3FC12CD8D8E644B062DDCA01586597F2EAE88FB44F00C594987D12AD94A6FC54736C5FC582796F8F7E03621EE0A2C686F804BBA9C55A1AB856761683289AAAE5220FCE946F7C33F75898F01813DD1B96290B2A0D6E841A375A7CD816115147D729883731A9B84B55EE22F6D7CA10DA8CEB75C6D14C09C16C6C08E530FB5C02AE2872BD176FF90E7F7239836A74099737AC774C724ED445016827B6A7EF68CC805B0A6F42EBA2FF2D2B6A4FA44678D9D2187C394A479CA5B36011F434A2FD1A59B06EDA840F558943D90E727268448EAB601538E1D57BF18AE50A3A63D5105C4814FEA4F65C5A2BD5007B5A45995A762757B0B7EE043726881DBCA26CA06578B2E3DC06DE188153FEB80F0E798C34CF2E6230DB50072DBBE055EF4CB8F8E89F83FCC119138C531BB24F490C90DA49CF5CEBA383E5073502DA63E0EB6C07E611645EDD9BE7A8101C439A877AE8465445F17E0E665DC2E03A0459B67594DE4A2B4FB484616FD9DB0A5B593A50C4BDE3236E10D353D394C36811688BF41FA28226045B8CCC6E4D0F681B749FE0340D0AB52CF784383BE321A258048DE6971549B6549620E6A7B71D969E638ABF3A5E40CD19CCA7332B941D54661BF268C7799C37B32C639CD3C5B1CD2FE73B04282337945FEC5131FB8990B52EFEA62DC02E3408174B759E1DECF8A19398875E4DBC73BAD4369783FFED5B7CE954ADB3AED6D3DAA99746386EA51411EDE7D728CFF25BB33983950DD212D592C5C3E3FAE90E0115DB9351185065723CFA42EFE64242D105FAC50403DC35018E2E7BFABC7F868E4C7D34424BF42B14E42EE84CA911F5F3D466EC727D472BDC1D84BE1C7A4460A36966CCD8FEEC52AB551566AAD0F2C1B24AE259CD655B0AFBB2CC4BE38704499F9FEFFDE6AACFDC54F5FCD5123361C9C01C7BA5B52C128D6C3D596736CCC82E09CF7EB8FA06510E038ADB0F6C00234C3014C5D10DB6519EEC95DD9D19200930D9E5EC24F06D206399E492C10CA910A4A0CFAB970BD1BE66E2C1D9B705A1B7E3C01C443E54E0F10D9F890EF21C543138EA649759EAC899A32A3FAE1BCCA5F7522EB4D524C13AB36AE5EF2FAFE33545674CA0F70573FB0D674B14CA0CB873C33838558B7000692B288D70C09E3AD9E514D95B970911E2CC3C9A85179C2A39B8586640CF6F34D203DE9C10829DBE1BCCB34CF9C83D7344A73305DD9292CBF0160CA139FE5419CC012E69B741DCF35A3DE08822D27B9680C7E63F4FA0B824A7259E932BA573E172C81B46DC710B1F8161EC2D2B880D1748B5F08FF52FA8D6C94539A15EE5024E14712AE62B196675C7FB17C7802FB68F4C3C7888F9CE863EB82C3B9A840A9E1FE8BA0A440644A9262E7F924580F059EC0DD2CF948F4D77DC76FA360F6CBD022CE3502765AF333D79A4C2257AECB069116CE1DB6963A11401E93EEB8C54B03FECBFCC8C68B8E1C049B6D348FCBF52BA7FFB264C5EAD3D15D95EEE901DA2FB401FA0BFA8691B004A411D2925E479A05973B090AC060FCAC093AE9C42DB104420AAB012B55D5C67D26DBC5B8ABC65A189D4E7BB40DA12C121FC166BB1D73BC6625E87D42F8D633EF76F43E1F0BE4C6211C1922CED06685E895353FE67CD70219AC3BACD6EAD3C54B92985E5A12A805EB8FCDF31BDC1FED3C730D3D9D62C22E8F24A9D73D5895D92DB38D783F8EB736D809117B45C35EE8F40056D690637173785D1E14E0EA90FFA8C97864B63232D2AAED14C2415A00F84D954AF103014F676ADD1817AB83B851CC016311BF31333915ABBBD7EFD264CCF472FD99E86D535E1497885774D17F07D19E0CFDB00F7A6682E511052BE0BC1846D8DAB478977034D0CBC1DFC72FD7F68AB51C824FC88115DAAE9E203D5033294156FBFB6E0F400B7B8F0861DAF592D4936C483D5DBDC98B7A576CC9D26E54EAC4CF24FF91797D48AA1374772D7F0B9EC4AF5A76E231E2E847B7D91F8A6D89A78EB1F7A039C3F3E5C3714F2C62212382806D78424223B84615ED361C49AFDCBB92243555B0D777DFB8F00005232FA8C97916EDAD87AEB466EBCDA6150F0ACA969B2D21C2E5FE2D7C4177E622FEBCE6AACE0842386D29A17FAB242B3F926BD8700340CA7B4B5383200DE7C93A701CA22B9412AC2F1C2139B9D332FD585B8E6B1E0721090F64BF871A2D0C0B5E0A0391E2A0D1A9E9103BD08DE12749A6F6FF03D2597B1F3BF33819F9AB2EF83B0927445BD727F161279C6C2DD2B68C229BF233F8BCCDB4A61D866F2D4F705439F990A32A0BCE93360E798129D95F284B942ABD702081AB6D1813FBD52B58A421E96FC0A715EF134CB1297E2AB3C91E581E3CF97223481475D955DABF2D0B8BB5F134EC14D84F102C9C57CA4B90589C1C5250544C760EC6CE839AA85BC0681D744F716A0E08DA4C2201D3C7EC51492A0516C9CCA8F912B03CF60AEB07F4ADFCA22C43F234897A8F518271DA5AE07A8BC6CDA35A5A58FC991CCA18E59E4CDD1F15251823961E38A49815FE8C766B705DB01A92C7A13B7F68CE43F21F692EC29CD085E70CFF19C6CAE0D08B30A155855024BFC9D95C87A01666EAA44986ABCF2F9E146CE26D2C12BC816934D179D0FD0CC1E11B5BBCC03E56EB056B6196D4700C774752674861A402C1A94A0032C5642C68ABE913BDE12AAC92D335AC19326389CEC3C5BAD1735C0120B7EE10A0E34AF450A663856D5931F9195B5204CF22A426BD28A6E31234227F033F311BF0A826B7B4F6E216B63B3B184466AFFDE10DA3FD8EAAE99CF91BA078532A1ABD8680B50A5F4516E3DEF7CC3AD7BDAADF662EE3EEAF05F918A598F979A9512EB64BF3781DF8CD988403FF0570F21A6E09484950F6CEFA7AFAE4142058B39D715E0E4F620E026D187C5A3D8C05EA644F155AF31D6FDEB4313410AC7548C88B8CD9274D2B190F1B2ECCCBBD7DAC21C647038D2948DF2DC80AEA5E5923EBE72D9C726E6DE0A266A8E6B9AAC80E50C7D9AEF2E2E3919241A82739DDCD2CA4AFCF501E3500FD2EC421D9AEC0FB7A311ADAB51E213933791EA6F0557878056AE3AE35FC18428ADA90B518F7665F4E896EB78247B580DB4F2AA5FEF1483155E08683B90D8331EE8118FB4EC738A19243CFA72940FF692E736D0B5AE111350775F57A60CE87CBF19CC5677B1A3BE9E780D15E1D09160C4720713A4F74A362C99C85697586382BC54461B120D17977A09CE326803E055B1AA4FDD4BEE7CEC045BA9138A30E9B47DBED84040E983CA093159E1F3B58AD2E60E6664C801DD79A8C8E766F6FE79D72547BE2895C40A469C47E8AD31CF8F5BB5E79543830942289A5C099E89B2C723D8A72B2133C87A25F6257CA5E706EF1E46EA59EB42EEB9CD3D9AA7A20D0936F0EB8D4F8E51663434D8DAA10B5934638E49BF0B8208B7924BBF61A1AE8282AB13BFBC1A8F2DBC003B48F8A20EDEC06CE9914CE4EB1A5B916A36337E71C30AED4969987C3F56BF86F09E7353E194602161CC41705301E7CBC384EA3A15FAE91A17ED8E1B98AAA6669D3236885CC239F69DA39C2A7B358605FC2111E4B90C9674DDF9434832E0EE97171B78A2226C6099C0F5AE1F6E2A74B66F52EFA4C2CF3D0FF7B24DADA3A62790325C96B990DFADFD2AED3AB5535413C221D0C584A6D586BFDF0E13ACAB23EB2108D996EA4DD7E510C307040AF3110370D38CC72B91B72CAC1AE463F6BF174EE189CC125C9FABB1C59051DB1AD6443D93A8F83FD9E9C39A69C2D48A170BA0F2336C48D653A06BE3164636DDE839BBFD2AC9566F750B527CD911A17EAB10FAC460926DD0D49871E070BB84413A200C8EAD2E1C2F8642114EA9688540C57559DC1D3D325988E1C34E0D48F9E05F731C9104E83F39609293AA760A8D877856B68A08E99E6F5D31A4C19FB2C16B1415D1F6ED290C6C3889196ACB26018A68DE48316EDAD2FFDB783D87475EF0B3D23E91DC3CEB668BF71DC8616B32B7A308DAF553AC6C0B4BFAD25AB48166EA09D4BC36BDA8E34FF749A30278BF0479FBCCBC84DC6FF077D7776E4EB54F3A67D7CCAE3AA19C149B33658BB40751485229609E21E21BA6F0403E4AA5377" +} +] diff --git a/Tests/CryptoTests/Signatures/MLDSA/MLDSAKeyGenTests.swift b/Tests/CryptoTests/Signatures/MLDSA/MLDSAKeyGenTests.swift new file mode 100644 index 000000000..6ab3a8354 --- /dev/null +++ b/Tests/CryptoTests/Signatures/MLDSA/MLDSAKeyGenTests.swift @@ -0,0 +1,117 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2019-2020 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import XCTest + +#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +// Skip tests that require @testable imports of CryptoKit. +#else +#if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +@testable import CryptoKit +#else +@testable import Crypto +#endif + +final class MLDSAKeyGenTests: XCTestCase { + func processKeyGenKATFile(filename: String) throws -> [MLDSAKeyGenKAT] { + #if CRYPTO_IN_SWIFTPM + let bundle = Bundle.module + #else + let bundle = Bundle(for: type(of: self)) + #endif + let fileURL = bundle.url(forResource: filename, withExtension: "json") + let json = try Data(contentsOf: fileURL!) + let stringInput = String(data: json, encoding: .ascii)! + let tests = try JSONDecoder().decode([MLDSAKeyGenKATHex].self, from: stringInput.data(using: .ascii)!) + return try tests.map { try MLDSAKeyGenKAT($0) } + } + + func test65KAT() throws { + let katTests = try processKeyGenKATFile(filename: "MLDSA65_KeyGen_KAT") + for katTest in katTests { + let publicKey = try MLDSA65.PublicKey(rawRepresentation: katTest.pk) + #if false + let privateKey = try MLDSA65.PrivateKey(seedRepresentation: katTest.seed, publicKey: publicKey) + let publicKeyHash = Data(SHA3_256.hash(data: privateKey.publicKey.rawRepresentation)) + #else + let privateKey = try MLDSA65.PrivateKey(seedRepresentation: katTest.seed, publicKey: nil) + #endif + + XCTAssert(privateKey.seedRepresentation == katTest.seed) + #if false + XCTAssert(privateKey.integrityCheckedRepresentation == katTest.seed + publicKeyHash) + #endif + XCTAssert(privateKey.publicKey.rawRepresentation == katTest.pk) + + // Try initializing keys with incorrect integrity checks + let randomPrivateKey = try MLDSA65.PrivateKey() + #if false + let randomPublicKeyHash = Data(SHA3_256.hash(data: randomPrivateKey.publicKey.rawRepresentation)) + XCTAssertThrowsError(try MLDSA65.PrivateKey(seedRepresentation: privateKey.seedRepresentation, publicKey: randomPrivateKey.publicKey), error: CryptoKitError.unwrapFailure) + XCTAssertThrowsError(try MLDSA65.PrivateKey(seedRepresentation: randomPrivateKey.seedRepresentation, publicKey: publicKey), error: CryptoKitError.unwrapFailure) + XCTAssertThrowsError(try MLDSA65.PrivateKey(integrityCheckedRepresentation: privateKey.seedRepresentation + randomPublicKeyHash), error: CryptoKitError.unwrapFailure) + XCTAssertThrowsError(try MLDSA65.PrivateKey(integrityCheckedRepresentation: randomPrivateKey.seedRepresentation + publicKeyHash), error: CryptoKitError.unwrapFailure) + #endif + } + } + + func test87KAT() throws { + let katTests = try processKeyGenKATFile(filename: "MLDSA87_KeyGen_KAT") + for katTest in katTests { + let publicKey = try MLDSA87.PublicKey(rawRepresentation: katTest.pk) + #if false + let privateKey = try MLDSA87.PrivateKey(seedRepresentation: katTest.seed, publicKey: publicKey) + let publicKeyHash = Data(SHA3_256.hash(data: privateKey.publicKey.rawRepresentation)) + #else + let privateKey = try MLDSA87.PrivateKey(seedRepresentation: katTest.seed, publicKey: nil) + #endif + + XCTAssert(privateKey.seedRepresentation == katTest.seed) + #if false + XCTAssert(privateKey.integrityCheckedRepresentation == katTest.seed + publicKeyHash) + #endif + XCTAssert(privateKey.publicKey.rawRepresentation == katTest.pk) + + // Try initializing keys with incorrect integrity checks + let randomPrivateKey = try MLDSA87.PrivateKey() + #if false + let randomPublicKeyHash = Data(SHA3_256.hash(data: randomPrivateKey.publicKey.rawRepresentation)) + XCTAssertThrowsError(try MLDSA87.PrivateKey(seedRepresentation: privateKey.seedRepresentation, publicKey: randomPrivateKey.publicKey), error: CryptoKitError.unwrapFailure) + XCTAssertThrowsError(try MLDSA87.PrivateKey(seedRepresentation: randomPrivateKey.seedRepresentation, publicKey: publicKey), error: CryptoKitError.unwrapFailure) + XCTAssertThrowsError(try MLDSA87.PrivateKey(integrityCheckedRepresentation: privateKey.seedRepresentation + randomPublicKeyHash), error: CryptoKitError.unwrapFailure) + XCTAssertThrowsError(try MLDSA87.PrivateKey(integrityCheckedRepresentation: randomPrivateKey.seedRepresentation + publicKeyHash), error: CryptoKitError.unwrapFailure) + #endif + } + } +} + +// Struct to parse KAT file +struct MLDSAKeyGenKATHex: Codable { + var seed: String + var pk: String + var sk: String +} + +// Represent KAT with Data +struct MLDSAKeyGenKAT { + var seed: Data + var pk: Data + var sk: Data + init(_ hexRep: MLDSAKeyGenKATHex) throws { + seed = try Data(hexString: hexRep.seed) + pk = try Data(hexString: hexRep.pk) + sk = try Data(hexString: hexRep.sk) + } +} + +#endif // CRYPTO_IN_SWIFTPM diff --git a/Tests/CryptoTests/Signatures/MLDSA/MLDSATests.swift b/Tests/CryptoTests/Signatures/MLDSA/MLDSATests.swift new file mode 100644 index 000000000..f833e3355 --- /dev/null +++ b/Tests/CryptoTests/Signatures/MLDSA/MLDSATests.swift @@ -0,0 +1,89 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2019-2020 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import XCTest + +#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +// Skip tests that require @testable imports of CryptoKit. +#else +#if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +@testable import CryptoKit +#else +@testable import Crypto +#endif + +final class MLDSATests: XCTestCase { + func testMLDSA65() throws { + let privateKey = try MLDSA65.PrivateKey() + let publicKey = privateKey.publicKey + + // Test Public Key Serialization + try XCTAssert(publicKey.rawRepresentation == MLDSA65.PublicKey(rawRepresentation: publicKey.rawRepresentation).rawRepresentation) + + // Test Private Key serialization + #if false + try XCTAssert(privateKey.seedRepresentation == MLDSA65.PrivateKey(seedRepresentation: privateKey.seedRepresentation, publicKey: publicKey).seedRepresentation) + try XCTAssert(privateKey.integrityCheckedRepresentation == MLDSA65.PrivateKey(integrityCheckedRepresentation: privateKey.integrityCheckedRepresentation).integrityCheckedRepresentation) + #endif + + // Test signing without a context + let message = Data("ML-DSA test message".utf8) + let signature = try privateKey.signature(for: message) + XCTAssertNotNil(signature) + let isValid = publicKey.isValidSignature(signature: signature, for: message) + XCTAssertTrue(isValid) + + // Test signing with a context + let context = Data("ML-DSA test context".utf8) + let signatureWithContext = try privateKey.signature(for: message, context: context) + let isValidWithContext = publicKey.isValidSignature(signature: signatureWithContext, for: message, context: context) + XCTAssertTrue(isValidWithContext) + + // Check that invalid signatures (mismatching contexts) fail + XCTAssertFalse(publicKey.isValidSignature(signature: signature, for: message, context: context)) + XCTAssertFalse(publicKey.isValidSignature(signature: signatureWithContext, for: message)) + } + + func testMLDSA87() throws { + let privateKey = try MLDSA87.PrivateKey() + let publicKey = privateKey.publicKey + + // Test Public Key Serialization + try XCTAssert(publicKey.rawRepresentation == MLDSA87.PublicKey(rawRepresentation: publicKey.rawRepresentation).rawRepresentation) + + // Test Private Key serialization + #if false + try XCTAssert(privateKey.seedRepresentation == MLDSA87.PrivateKey(seedRepresentation: privateKey.seedRepresentation, publicKey: publicKey).seedRepresentation) + try XCTAssert(privateKey.integrityCheckedRepresentation == MLDSA87.PrivateKey(integrityCheckedRepresentation: privateKey.integrityCheckedRepresentation).integrityCheckedRepresentation) + #endif + + // Test signing without a context + let message = Data("ML-DSA test message".utf8) + let signature = try privateKey.signature(for: message) + XCTAssertNotNil(signature) + let isValid = publicKey.isValidSignature(signature: signature, for: message) + XCTAssertTrue(isValid) + + // Test signing with a context + let context = Data("ML-DSA test context".utf8) + let signatureWithContext = try privateKey.signature(for: message, context: context) + let isValidWithContext = publicKey.isValidSignature(signature: signatureWithContext, for: message, context: context) + XCTAssertTrue(isValidWithContext) + + // Check that invalid signatures (mismatching contexts) fail + XCTAssertFalse(publicKey.isValidSignature(signature: signature, for: message, context: context)) + XCTAssertFalse(publicKey.isValidSignature(signature: signatureWithContext, for: message)) + } +} + +#endif // CRYPTO_IN_SWIFTPM diff --git a/Tests/CryptoTests/Utils/Boring/CTRDRBG.swift b/Tests/CryptoTests/Utils/Boring/CTRDRBG.swift new file mode 100644 index 000000000..8e024d9fe --- /dev/null +++ b/Tests/CryptoTests/Utils/Boring/CTRDRBG.swift @@ -0,0 +1,72 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2025 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +#if CRYPTO_IN_SWIFTPM && CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +import Foundation +@_implementationOnly import CCryptoBoringSSL +import Crypto + +/// AES-CTR DRBG +final class Drbg { + private let state: OpaquePointer + + init(_ seed: Data) throws { + guard seed.count == CTR_DRBG_ENTROPY_LEN else { + throw CryptoKitError.incorrectParameterSize + } + self.state = seed.withUnsafeBytes { + CCryptoBoringSSL_CTR_DRBG_new($0.baseAddress, nil, 0)! + } + } + + func initializeWithRandomBytes(_ buffer: UnsafeMutableRawBufferPointer, count: Int) { + guard count > 0 else { + return + } + + precondition(count <= buffer.count) + + let rc = CCryptoBoringSSL_CTR_DRBG_generate( + self.state, + buffer.baseAddress, + buffer.count, + nil, + 0 + ) + precondition(rc == 1) + } + + var detRngPtr: Self { self } +} + +extension UnsafeMutableRawBufferPointer { + func initializeWithRandomBytes(count: Int, ccrngState: Drbg) { + ccrngState.initializeWithRandomBytes(self, count: count) + } +} + +extension SymmetricKey { + var dataRepresentation: Data { + self.withUnsafeBytes { ptr in + Data(ptr) + } + } +} + +extension SymmetricKey { + static func == (lhs: SymmetricKey, rhs: Data) -> Bool { + lhs.dataRepresentation == rhs + } +} + +#endif // CRYPTO_IN_SWIFTPM diff --git a/Tests/CryptoTests/Utils/Boring/SequenceDRBG.swift b/Tests/CryptoTests/Utils/Boring/SequenceDRBG.swift new file mode 100644 index 000000000..ae7c0b266 --- /dev/null +++ b/Tests/CryptoTests/Utils/Boring/SequenceDRBG.swift @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2025 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +#if CRYPTO_IN_SWIFTPM && CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +import Foundation +@_implementationOnly import CCryptoBoringSSL +import Crypto + +/// Sequence DRBG +final class SequenceDrbg { + let state: [UInt8] + + init(_ seed: Data) throws { + self.state = Array(seed) + } + + var detRngPtr: Self { self } +} + +#endif // CRYPTO_IN_SWIFTPM diff --git a/Tests/CryptoTests/Utils/PrettyBytes.swift b/Tests/CryptoTests/Utils/PrettyBytes.swift index 7610e5c0d..53563509d 100644 --- a/Tests/CryptoTests/Utils/PrettyBytes.swift +++ b/Tests/CryptoTests/Utils/PrettyBytes.swift @@ -11,15 +11,19 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +import SwiftSystem +#else import Foundation +#endif enum ByteHexEncodingErrors: Error { case incorrectHexValue case incorrectString } -let charA = UInt8(UnicodeScalar("a").value) -let char0 = UInt8(UnicodeScalar("0").value) +let charA = UInt8(97 /* "a" */) +let char0 = UInt8(48 /* "0" */) private func itoh(_ value: UInt8) -> UInt8 { return (value > 9) ? (charA + value - 10) : (char0 + value) @@ -36,6 +40,7 @@ private func htoi(_ value: UInt8) throws -> UInt8 { } } +#if !hasFeature(Embedded) extension DataProtocol { var hexString: String { let hexLen = self.count * 2 @@ -50,16 +55,18 @@ extension DataProtocol { } } - return String(bytes: hexChars, encoding: .utf8)! + return String(decoding: hexChars, as: UTF8.self) } } +#endif // !hasFeature(Embedded) -extension MutableDataProtocol { +extension RangeReplaceableCollection where Element == UInt8 { mutating func appendByte(_ byte: UInt64) { - withUnsafePointer(to: byte.littleEndian, { self.append(contentsOf: UnsafeRawBufferPointer(start: $0, count: 8)) }) + withUnsafeBytes(of: byte.littleEndian, { self.append(contentsOf: $0) }) } } +#if !CRYPTOKIT_NO_ACCESS_TO_FOUNDATION extension Data { init(hexString: String) throws { self.init() @@ -98,3 +105,4 @@ extension Array where Element == UInt8 { } } +#endif diff --git a/Tests/CryptoTests/Utils/XCTestUtils.swift b/Tests/CryptoTests/Utils/XCTestUtils.swift index 5765976e3..819d290b7 100644 --- a/Tests/CryptoTests/Utils/XCTestUtils.swift +++ b/Tests/CryptoTests/Utils/XCTestUtils.swift @@ -12,6 +12,7 @@ // //===----------------------------------------------------------------------===// import XCTest +import Crypto // Xcode 11.4 catches errors thrown during tests and reports them on the // correct line. But Linux and older Xcodes do not, so we need to use this @@ -52,5 +53,16 @@ extension XCTestCase { return wrapped } +} +func XCTAssertThrowsError( + _ expression: @autoclosure () throws -> T, + error: E, + _ message: @autoclosure () -> String = "", + file: StaticString = #file, + line: UInt = #line) +{ + XCTAssertThrowsError(try expression(), message(), file: file, line: line) { foundError in + XCTAssertEqual(foundError as? E, error, message(), file: file, line: line) + } } diff --git a/Tests/_CryptoExtrasTests/MLDSATests.swift b/Tests/_CryptoExtrasTests/MLDSATests.swift index e19582dc5..01ddbd743 100644 --- a/Tests/_CryptoExtrasTests/MLDSATests.swift +++ b/Tests/_CryptoExtrasTests/MLDSATests.swift @@ -12,22 +12,28 @@ // //===----------------------------------------------------------------------===// +#if !canImport(Darwin) || canImport(CryptoKit, _version: 324.0.4) + import XCTest @testable import _CryptoExtras final class MLDSATests: XCTestCase { func testMLDSA65Signing() throws { + guard #available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) else { + throw XCTSkip("MLDSA is only available on iOS 19.0+, macOS 16.0+, watchOS 12.0+, tvOS 19.0+, visionOS 3.0+") + } try testMLDSA65Signing(MLDSA65.PrivateKey()) let seed: [UInt8] = (0..<32).map { _ in UInt8.random(in: 0...255) } - try testMLDSA65Signing(MLDSA65.PrivateKey(seedRepresentation: seed)) + try testMLDSA65Signing(MLDSA65.PrivateKey(seedRepresentation: seed, publicKey: nil)) } + @available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) private func testMLDSA65Signing(_ key: MLDSA65.PrivateKey) throws { let test = "Hello, world!".data(using: .utf8)! try XCTAssertTrue( key.publicKey.isValidSignature( - key.signature(for: test), + signature: key.signature(for: test), for: test ) ) @@ -35,7 +41,7 @@ final class MLDSATests: XCTestCase { let context = "ctx".data(using: .utf8)! try XCTAssertTrue( key.publicKey.isValidSignature( - key.signature(for: test, context: context), + signature: key.signature(for: test, context: context), for: test, context: context ) @@ -43,16 +49,20 @@ final class MLDSATests: XCTestCase { } func testMLDSA87Signing() throws { + guard #available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) else { + throw XCTSkip("MLDSA is only available on iOS 19.0+, macOS 16.0+, watchOS 12.0+, tvOS 19.0+, visionOS 3.0+") + } try testMLDSA87Signing(MLDSA87.PrivateKey()) let seed: [UInt8] = (0..<32).map { _ in UInt8.random(in: 0...255) } - try testMLDSA87Signing(MLDSA87.PrivateKey(seedRepresentation: seed)) + try testMLDSA87Signing(MLDSA87.PrivateKey(seedRepresentation: seed, publicKey: nil)) } + @available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) private func testMLDSA87Signing(_ key: MLDSA87.PrivateKey) throws { let test = "Hello, world!".data(using: .utf8)! try XCTAssertTrue( key.publicKey.isValidSignature( - key.signature(for: test), + signature: key.signature(for: test), for: test ) ) @@ -60,7 +70,7 @@ final class MLDSATests: XCTestCase { let context = "ctx".data(using: .utf8)! try XCTAssertTrue( key.publicKey.isValidSignature( - key.signature(for: test, context: context), + signature: key.signature(for: test, context: context), for: test, context: context ) @@ -68,26 +78,35 @@ final class MLDSATests: XCTestCase { } func testMLDSA65SeedRoundTripping() throws { + guard #available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) else { + throw XCTSkip("MLDSA is only available on iOS 19.0+, macOS 16.0+, watchOS 12.0+, tvOS 19.0+, visionOS 3.0+") + } let key = try MLDSA65.PrivateKey() let seed = key.seedRepresentation - let roundTripped = try MLDSA65.PrivateKey(seedRepresentation: seed) + let roundTripped = try MLDSA65.PrivateKey(seedRepresentation: seed, publicKey: nil) XCTAssertEqual(seed, roundTripped.seedRepresentation) XCTAssertEqual(key.publicKey.rawRepresentation, roundTripped.publicKey.rawRepresentation) } func testMLDSA87SeedRoundTripping() throws { + guard #available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) else { + throw XCTSkip("MLDSA is only available on iOS 19.0+, macOS 16.0+, watchOS 12.0+, tvOS 19.0+, visionOS 3.0+") + } let key = try MLDSA87.PrivateKey() let seed = key.seedRepresentation - let roundTripped = try MLDSA87.PrivateKey(seedRepresentation: seed) + let roundTripped = try MLDSA87.PrivateKey(seedRepresentation: seed, publicKey: nil) XCTAssertEqual(seed, roundTripped.seedRepresentation) XCTAssertEqual(key.publicKey.rawRepresentation, roundTripped.publicKey.rawRepresentation) } func testMLDSA65SignatureIsRandomized() throws { + guard #available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) else { + throw XCTSkip("MLDSA is only available on iOS 19.0+, macOS 16.0+, watchOS 12.0+, tvOS 19.0+, visionOS 3.0+") + } let message = "Hello, world!".data(using: .utf8)! let seed: [UInt8] = (0..<32).map { _ in UInt8.random(in: 0...255) } - let key = try MLDSA65.PrivateKey(seedRepresentation: seed) + let key = try MLDSA65.PrivateKey(seedRepresentation: seed, publicKey: nil) let publicKey = key.publicKey let signature1 = try key.signature(for: message) @@ -96,15 +115,18 @@ final class MLDSATests: XCTestCase { XCTAssertNotEqual(signature1, signature2) // Even though the signatures are different, they both verify. - XCTAssertTrue(publicKey.isValidSignature(signature1, for: message)) - XCTAssertTrue(publicKey.isValidSignature(signature2, for: message)) + XCTAssertTrue(publicKey.isValidSignature(signature: signature1, for: message)) + XCTAssertTrue(publicKey.isValidSignature(signature: signature2, for: message)) } func testMLDSA87SignatureIsRandomized() throws { + guard #available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) else { + throw XCTSkip("MLDSA is only available on iOS 19.0+, macOS 16.0+, watchOS 12.0+, tvOS 19.0+, visionOS 3.0+") + } let message = "Hello, world!".data(using: .utf8)! let seed: [UInt8] = (0..<32).map { _ in UInt8.random(in: 0...255) } - let key = try MLDSA87.PrivateKey(seedRepresentation: seed) + let key = try MLDSA87.PrivateKey(seedRepresentation: seed, publicKey: nil) let publicKey = key.publicKey let signature1 = try key.signature(for: message) @@ -113,15 +135,18 @@ final class MLDSATests: XCTestCase { XCTAssertNotEqual(signature1, signature2) // Even though the signatures are different, they both verify. - XCTAssertTrue(publicKey.isValidSignature(signature1, for: message)) - XCTAssertTrue(publicKey.isValidSignature(signature2, for: message)) + XCTAssertTrue(publicKey.isValidSignature(signature: signature1, for: message)) + XCTAssertTrue(publicKey.isValidSignature(signature: signature2, for: message)) } func testInvalidMLDSA65PublicKeyEncodingLength() throws { + guard #available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) else { + throw XCTSkip("MLDSA is only available on iOS 19.0+, macOS 16.0+, watchOS 12.0+, tvOS 19.0+, visionOS 3.0+") + } // Encode a public key with a trailing 0 at the end. var encodedPublicKey = [UInt8](repeating: 0, count: MLDSA65.PublicKey.byteCount + 1) let seed: [UInt8] = (0..<32).map { _ in UInt8.random(in: 0...255) } - let key = try MLDSA65.PrivateKey(seedRepresentation: seed) + let key = try MLDSA65.PrivateKey(seedRepresentation: seed, publicKey: nil) let publicKey = key.publicKey encodedPublicKey.replaceSubrange(0..( jsonName: String, file: StaticString = #file, @@ -210,6 +245,9 @@ final class MLDSATests: XCTestCase { } func testMLDSA65WycheproofVerifyFile() throws { + guard #available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) else { + throw XCTSkip("MLDSA is only available on iOS 19.0+, macOS 16.0+, watchOS 12.0+, tvOS 19.0+, visionOS 3.0+") + } try wycheproofTest(jsonName: "mldsa_65_verify_test") { (testGroup: WycheproofTestGroup) in let publicKey: MLDSA65.PublicKey do { @@ -226,15 +264,15 @@ final class MLDSATests: XCTestCase { switch test.result { case .valid: if let context { - XCTAssertTrue(publicKey.isValidSignature(signature, for: message, context: context)) + XCTAssertTrue(publicKey.isValidSignature(signature: signature, for: message, context: context)) } else { - XCTAssertTrue(publicKey.isValidSignature(signature, for: message)) + XCTAssertTrue(publicKey.isValidSignature(signature: signature, for: message)) } case .invalid: if let context { - XCTAssertFalse(publicKey.isValidSignature(signature, for: message, context: context)) + XCTAssertFalse(publicKey.isValidSignature(signature: signature, for: message, context: context)) } else { - XCTAssertFalse(publicKey.isValidSignature(signature, for: message)) + XCTAssertFalse(publicKey.isValidSignature(signature: signature, for: message)) } } } @@ -242,6 +280,9 @@ final class MLDSATests: XCTestCase { } func testMLDSA87WycheproofVerifyFile() throws { + guard #available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) else { + throw XCTSkip("MLDSA is only available on iOS 19.0+, macOS 16.0+, watchOS 12.0+, tvOS 19.0+, visionOS 3.0+") + } try wycheproofTest(jsonName: "mldsa_87_verify_test") { (testGroup: WycheproofTestGroup) in let publicKey: MLDSA87.PublicKey do { @@ -258,15 +299,15 @@ final class MLDSATests: XCTestCase { switch test.result { case .valid: if let context { - XCTAssertTrue(publicKey.isValidSignature(signature, for: message, context: context)) + XCTAssertTrue(publicKey.isValidSignature(signature: signature, for: message, context: context)) } else { - XCTAssertTrue(publicKey.isValidSignature(signature, for: message)) + XCTAssertTrue(publicKey.isValidSignature(signature: signature, for: message)) } case .invalid: if let context { - XCTAssertFalse(publicKey.isValidSignature(signature, for: message, context: context)) + XCTAssertFalse(publicKey.isValidSignature(signature: signature, for: message, context: context)) } else { - XCTAssertFalse(publicKey.isValidSignature(signature, for: message)) + XCTAssertFalse(publicKey.isValidSignature(signature: signature, for: message)) } } } @@ -303,3 +344,15 @@ final class MLDSATests: XCTestCase { } } } + +@available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) +extension MLDSA65.PublicKey { + static let byteCount = 1952 +} + +@available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) +extension MLDSA87.PublicKey { + static let byteCount = 2592 +} + +#endif // SDK has MLDSA diff --git a/Tests/_CryptoExtrasTests/MLKEMTests.swift b/Tests/_CryptoExtrasTests/MLKEMTests.swift index 8a0cb8892..007a88a5a 100644 --- a/Tests/_CryptoExtrasTests/MLKEMTests.swift +++ b/Tests/_CryptoExtrasTests/MLKEMTests.swift @@ -11,22 +11,25 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if !canImport(Darwin) || canImport(CryptoKit, _version: 324.0.4) import Crypto import XCTest @testable import _CryptoExtras -@available(macOS 14.0, *) final class MLKEMTests: XCTestCase { func testMLKEM768() throws { + guard #available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) else { + throw XCTSkip("MLDSA is only available on iOS 19.0+, macOS 16.0+, watchOS 12.0+, tvOS 19.0+, visionOS 3.0+") + } // Generate a key pair - let privateKey = MLKEM768.PrivateKey() + let privateKey = try MLKEM768.PrivateKey() let publicKey = privateKey.publicKey // Serialize and deserialize the private key let seed = privateKey.seedRepresentation - let privateKey2 = try MLKEM768.PrivateKey(seedRepresentation: seed) + let privateKey2 = try MLKEM768.PrivateKey(seedRepresentation: seed, publicKey: nil) XCTAssertEqual(privateKey.seedRepresentation, privateKey2.seedRepresentation) // Serialize and deserialize the public key @@ -49,12 +52,12 @@ final class MLKEMTests: XCTestCase { modifiedSeed[0] = 0xff modifiedSeed[1] = 0xff XCTAssertNotEqual( - try MLKEM768.PrivateKey(seedRepresentation: modifiedSeed).publicKey.rawRepresentation, + try MLKEM768.PrivateKey(seedRepresentation: modifiedSeed, publicKey: nil).publicKey.rawRepresentation, publicKeyBytes ) // Encapsulation and decapsulation - let encapsulationResult = publicKey.encapsulate() + let encapsulationResult = try publicKey.encapsulate() let sharedSecret1 = encapsulationResult.sharedSecret let ciphertext = encapsulationResult.encapsulated @@ -63,13 +66,16 @@ final class MLKEMTests: XCTestCase { } func testMLKEM1024() throws { + guard #available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) else { + throw XCTSkip("MLDSA is only available on iOS 19.0+, macOS 16.0+, watchOS 12.0+, tvOS 19.0+, visionOS 3.0+") + } // Generate a key pair - let privateKey = MLKEM1024.PrivateKey() + let privateKey = try MLKEM1024.PrivateKey() let publicKey = privateKey.publicKey // Serialize and deserialize the private key let seed = privateKey.seedRepresentation - let privateKey2 = try MLKEM1024.PrivateKey(seedRepresentation: seed) + let privateKey2 = try MLKEM1024.PrivateKey(seedRepresentation: seed, publicKey: nil) XCTAssertEqual(privateKey.seedRepresentation, privateKey2.seedRepresentation) // Serialize and deserialize the public key @@ -92,12 +98,12 @@ final class MLKEMTests: XCTestCase { modifiedSeed[0] = 0xff modifiedSeed[1] = 0xff XCTAssertNotEqual( - try MLKEM1024.PrivateKey(seedRepresentation: modifiedSeed).publicKey.rawRepresentation, + try MLKEM1024.PrivateKey(seedRepresentation: modifiedSeed, publicKey: nil).publicKey.rawRepresentation, publicKeyBytes ) // Encapsulation and decapsulation - let encapsulationResult = publicKey.encapsulate() + let encapsulationResult = try publicKey.encapsulate() let sharedSecret1 = encapsulationResult.sharedSecret let ciphertext = encapsulationResult.encapsulated @@ -105,3 +111,5 @@ final class MLKEMTests: XCTestCase { XCTAssertEqual(sharedSecret1, sharedSecret2) } } + +#endif // SDK has MLKEM diff --git a/scripts/vendor-boringssl.sh b/scripts/vendor-boringssl.sh index a213ece35..5af684aab 100755 --- a/scripts/vendor-boringssl.sh +++ b/scripts/vendor-boringssl.sh @@ -333,6 +333,7 @@ cat << EOF > "$DSTROOT/include/CCryptoBoringSSL.h" #include "CCryptoBoringSSL_cmac.h" #include "CCryptoBoringSSL_conf.h" #include "CCryptoBoringSSL_cpu.h" +#include "CCryptoBoringSSL_ctrdrbg.h" #include "CCryptoBoringSSL_curve25519.h" #include "CCryptoBoringSSL_des.h" #include "CCryptoBoringSSL_e_os2.h" @@ -364,6 +365,7 @@ cat << EOF > "$DSTROOT/include/CCryptoBoringSSL.h" #include "CCryptoBoringSSL_siphash.h" #include "CCryptoBoringSSL_trust_token.h" #include "CCryptoBoringSSL_x509v3.h" +#include "CCryptoBoringSSL_xwing.h" #endif // C_CRYPTO_BORINGSSL_H EOF From e09d1499dd245d2ce4234ab5366be68ad702b46c Mon Sep 17 00:00:00 2001 From: Francesco Paolo Severino Date: Mon, 16 Jun 2025 16:01:33 +0200 Subject: [PATCH 03/47] Revert "Add an external mu variant of the ML-DSA API (65 and 87 variants)" This reverts commit e9de693b7f32c82ef36b22d2aefb5177c3ff43fa. --- .../_CryptoExtras/MLDSA/MLDSA_boring.swift | 201 ------------------ .../MLDSA/MLDSA_boring.swift.gyb | 102 --------- Tests/_CryptoExtrasTests/MLDSATests.swift | 26 --- 3 files changed, 329 deletions(-) diff --git a/Sources/_CryptoExtras/MLDSA/MLDSA_boring.swift b/Sources/_CryptoExtras/MLDSA/MLDSA_boring.swift index 329b90ae9..51941f563 100644 --- a/Sources/_CryptoExtras/MLDSA/MLDSA_boring.swift +++ b/Sources/_CryptoExtras/MLDSA/MLDSA_boring.swift @@ -75,17 +75,6 @@ extension MLDSA65 { try self.backing.signature(for: data, context: context) } - /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). - /// - /// > Note: The message representative should be obtained via calls to ``MLDSA65/PublicKey/prehash(for:context:)``. - /// - /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). - /// - /// - Returns: The signature of the prehashed message representative. - public func signature(forPrehashedMessageRepresentative mu: M) throws -> Data { - try self.backing.signature(forPrehashedMessageRepresentative: mu) - } - /// The size of the private key in bytes. static let byteCount = Backing.byteCount @@ -186,38 +175,6 @@ extension MLDSA65 { return signature } - /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). - /// - /// > Note: The message representative should be obtained via calls to ``MLDSA65/PublicKey/prehash(for:context:)``. - /// - /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). - /// - /// - Returns: The signature of the prehashed message representative. - func signature(forPrehashedMessageRepresentative mu: M) throws -> Data { - guard mu.count == MLDSA.muByteCount else { - throw CryptoKitError.incorrectParameterSize - } - - var signature = Data(repeating: 0, count: MLDSA65.signatureByteCount) - - let rc: CInt = signature.withUnsafeMutableBytes { signaturePtr in - let muBytes: ContiguousBytes = mu.regions.count == 1 ? mu.regions.first! : Array(mu) - return muBytes.withUnsafeBytes { muPtr in - CCryptoBoringSSL_MLDSA65_sign_message_representative( - signaturePtr.baseAddress, - &self.key, - muPtr.baseAddress - ) - } - } - - guard rc == 1 else { - throw CryptoKitError.internalBoringSSLError() - } - - return signature - } - /// The size of the private key in bytes. static let byteCount = Int(MLDSA65_PRIVATE_KEY_BYTES) } @@ -276,27 +233,6 @@ extension MLDSA65 { self.backing.isValidSignature(signature, for: data, context: context) } - /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. - /// - /// - Parameter data: The message to prehash. - /// - /// - Returns: The prehashed message representative (a.k.a. "external mu"). - public func prehash(for data: D) throws -> Data { - let context: Data? = nil - return try self.backing.prehash(for: data, context: context) - } - - /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. - /// - /// - Parameters: - /// - data: The message to prehash. - /// - context: The context of the message. - /// - /// - Returns: The prehashed message representative (a.k.a. "external mu"). - public func prehash(for data: D, context: C) throws -> Data { - try self.backing.prehash(for: data, context: context) - } - /// The size of the public key in bytes. static let byteCount = Backing.byteCount @@ -378,41 +314,6 @@ extension MLDSA65 { } } - /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. - /// - /// - Parameters: - /// - data: The message to prehash. - /// - context: The context of the message. - /// - /// - Returns: The prehashed message representative (a.k.a. "external mu"). - func prehash(for data: D, context: C?) throws -> Data { - var mu = Data(repeating: 0, count: MLDSA.muByteCount) - - let dataBytes: ContiguousBytes = data.regions.count == 1 ? data.regions.first! : Array(data) - let rc: CInt = mu.withUnsafeMutableBytes { muPtr in - dataBytes.withUnsafeBytes { dataPtr in - context.withUnsafeBytes { contextPtr in - var prehash = MLDSA65_prehash() - let rc = CCryptoBoringSSL_MLDSA65_prehash_init( - &prehash, - &key, - contextPtr.baseAddress, - contextPtr.count - ) - CCryptoBoringSSL_MLDSA65_prehash_update(&prehash, dataPtr.baseAddress, dataPtr.count) - CCryptoBoringSSL_MLDSA65_prehash_finalize(muPtr.baseAddress, &prehash) - return rc - } - } - } - - guard rc == 1 else { - throw CryptoKitError.internalBoringSSLError() - } - - return mu - } - /// The size of the public key in bytes. static let byteCount = Int(MLDSA65_PUBLIC_KEY_BYTES) } @@ -480,17 +381,6 @@ extension MLDSA87 { try self.backing.signature(for: data, context: context) } - /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). - /// - /// > Note: The message representative should be obtained via calls to ``MLDSA87/PublicKey/prehash(for:context:)``. - /// - /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). - /// - /// - Returns: The signature of the prehashed message representative. - public func signature(forPrehashedMessageRepresentative mu: M) throws -> Data { - try self.backing.signature(forPrehashedMessageRepresentative: mu) - } - /// The size of the private key in bytes. static let byteCount = Backing.byteCount @@ -591,38 +481,6 @@ extension MLDSA87 { return signature } - /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). - /// - /// > Note: The message representative should be obtained via calls to ``MLDSA87/PublicKey/prehash(for:context:)``. - /// - /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). - /// - /// - Returns: The signature of the prehashed message representative. - func signature(forPrehashedMessageRepresentative mu: M) throws -> Data { - guard mu.count == MLDSA.muByteCount else { - throw CryptoKitError.incorrectParameterSize - } - - var signature = Data(repeating: 0, count: MLDSA87.signatureByteCount) - - let rc: CInt = signature.withUnsafeMutableBytes { signaturePtr in - let muBytes: ContiguousBytes = mu.regions.count == 1 ? mu.regions.first! : Array(mu) - return muBytes.withUnsafeBytes { muPtr in - CCryptoBoringSSL_MLDSA87_sign_message_representative( - signaturePtr.baseAddress, - &self.key, - muPtr.baseAddress - ) - } - } - - guard rc == 1 else { - throw CryptoKitError.internalBoringSSLError() - } - - return signature - } - /// The size of the private key in bytes. static let byteCount = Int(MLDSA87_PRIVATE_KEY_BYTES) } @@ -681,27 +539,6 @@ extension MLDSA87 { self.backing.isValidSignature(signature, for: data, context: context) } - /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. - /// - /// - Parameter data: The message to prehash. - /// - /// - Returns: The prehashed message representative (a.k.a. "external mu"). - public func prehash(for data: D) throws -> Data { - let context: Data? = nil - return try self.backing.prehash(for: data, context: context) - } - - /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. - /// - /// - Parameters: - /// - data: The message to prehash. - /// - context: The context of the message. - /// - /// - Returns: The prehashed message representative (a.k.a. "external mu"). - public func prehash(for data: D, context: C) throws -> Data { - try self.backing.prehash(for: data, context: context) - } - /// The size of the public key in bytes. static let byteCount = Backing.byteCount @@ -783,41 +620,6 @@ extension MLDSA87 { } } - /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. - /// - /// - Parameters: - /// - data: The message to prehash. - /// - context: The context of the message. - /// - /// - Returns: The prehashed message representative (a.k.a. "external mu"). - func prehash(for data: D, context: C?) throws -> Data { - var mu = Data(repeating: 0, count: MLDSA.muByteCount) - - let dataBytes: ContiguousBytes = data.regions.count == 1 ? data.regions.first! : Array(data) - let rc: CInt = mu.withUnsafeMutableBytes { muPtr in - dataBytes.withUnsafeBytes { dataPtr in - context.withUnsafeBytes { contextPtr in - var prehash = MLDSA87_prehash() - let rc = CCryptoBoringSSL_MLDSA87_prehash_init( - &prehash, - &key, - contextPtr.baseAddress, - contextPtr.count - ) - CCryptoBoringSSL_MLDSA87_prehash_update(&prehash, dataPtr.baseAddress, dataPtr.count) - CCryptoBoringSSL_MLDSA87_prehash_finalize(muPtr.baseAddress, &prehash) - return rc - } - } - } - - guard rc == 1 else { - throw CryptoKitError.internalBoringSSLError() - } - - return mu - } - /// The size of the public key in bytes. static let byteCount = Int(MLDSA87_PUBLIC_KEY_BYTES) } @@ -833,7 +635,4 @@ extension MLDSA87 { private enum MLDSA { /// The size of the seed in bytes. fileprivate static let seedByteCount = 32 - - /// The size of the "mu" value in bytes. - fileprivate static let muByteCount = 64 } diff --git a/Sources/_CryptoExtras/MLDSA/MLDSA_boring.swift.gyb b/Sources/_CryptoExtras/MLDSA/MLDSA_boring.swift.gyb index a5ddd98ee..91a86c18d 100644 --- a/Sources/_CryptoExtras/MLDSA/MLDSA_boring.swift.gyb +++ b/Sources/_CryptoExtras/MLDSA/MLDSA_boring.swift.gyb @@ -79,17 +79,6 @@ extension MLDSA${parameter_set} { try self.backing.signature(for: data, context: context) } - /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). - /// - /// > Note: The message representative should be obtained via calls to ``MLDSA${parameter_set}/PublicKey/prehash(for:context:)``. - /// - /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). - /// - /// - Returns: The signature of the prehashed message representative. - public func signature(forPrehashedMessageRepresentative mu: M) throws -> Data { - try self.backing.signature(forPrehashedMessageRepresentative: mu) - } - /// The size of the private key in bytes. static let byteCount = Backing.byteCount @@ -190,38 +179,6 @@ extension MLDSA${parameter_set} { return signature } - /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). - /// - /// > Note: The message representative should be obtained via calls to ``MLDSA${parameter_set}/PublicKey/prehash(for:context:)``. - /// - /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). - /// - /// - Returns: The signature of the prehashed message representative. - func signature(forPrehashedMessageRepresentative mu: M) throws -> Data { - guard mu.count == MLDSA.muByteCount else { - throw CryptoKitError.incorrectParameterSize - } - - var signature = Data(repeating: 0, count: MLDSA${parameter_set}.signatureByteCount) - - let rc: CInt = signature.withUnsafeMutableBytes { signaturePtr in - let muBytes: ContiguousBytes = mu.regions.count == 1 ? mu.regions.first! : Array(mu) - return muBytes.withUnsafeBytes { muPtr in - CCryptoBoringSSL_MLDSA${parameter_set}_sign_message_representative( - signaturePtr.baseAddress, - &self.key, - muPtr.baseAddress - ) - } - } - - guard rc == 1 else { - throw CryptoKitError.internalBoringSSLError() - } - - return signature - } - /// The size of the private key in bytes. static let byteCount = Int(MLDSA${parameter_set}_PRIVATE_KEY_BYTES) } @@ -280,27 +237,6 @@ extension MLDSA${parameter_set} { self.backing.isValidSignature(signature, for: data, context: context) } - /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. - /// - /// - Parameter data: The message to prehash. - /// - /// - Returns: The prehashed message representative (a.k.a. "external mu"). - public func prehash(for data: D) throws -> Data { - let context: Data? = nil - return try self.backing.prehash(for: data, context: context) - } - - /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. - /// - /// - Parameters: - /// - data: The message to prehash. - /// - context: The context of the message. - /// - /// - Returns: The prehashed message representative (a.k.a. "external mu"). - public func prehash(for data: D, context: C) throws -> Data { - try self.backing.prehash(for: data, context: context) - } - /// The size of the public key in bytes. static let byteCount = Backing.byteCount @@ -382,41 +318,6 @@ extension MLDSA${parameter_set} { } } - /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. - /// - /// - Parameters: - /// - data: The message to prehash. - /// - context: The context of the message. - /// - /// - Returns: The prehashed message representative (a.k.a. "external mu"). - func prehash(for data: D, context: C?) throws -> Data { - var mu = Data(repeating: 0, count: MLDSA.muByteCount) - - let dataBytes: ContiguousBytes = data.regions.count == 1 ? data.regions.first! : Array(data) - let rc: CInt = mu.withUnsafeMutableBytes { muPtr in - dataBytes.withUnsafeBytes { dataPtr in - context.withUnsafeBytes { contextPtr in - var prehash = MLDSA${parameter_set}_prehash() - let rc = CCryptoBoringSSL_MLDSA${parameter_set}_prehash_init( - &prehash, - &key, - contextPtr.baseAddress, - contextPtr.count - ) - CCryptoBoringSSL_MLDSA${parameter_set}_prehash_update(&prehash, dataPtr.baseAddress, dataPtr.count) - CCryptoBoringSSL_MLDSA${parameter_set}_prehash_finalize(muPtr.baseAddress, &prehash) - return rc - } - } - } - - guard rc == 1 else { - throw CryptoKitError.internalBoringSSLError() - } - - return mu - } - /// The size of the public key in bytes. static let byteCount = Int(MLDSA${parameter_set}_PUBLIC_KEY_BYTES) } @@ -433,7 +334,4 @@ extension MLDSA${parameter_set} { private enum MLDSA { /// The size of the seed in bytes. fileprivate static let seedByteCount = 32 - - /// The size of the "mu" value in bytes. - fileprivate static let muByteCount = 64 } diff --git a/Tests/_CryptoExtrasTests/MLDSATests.swift b/Tests/_CryptoExtrasTests/MLDSATests.swift index 24ca3bb52..e19582dc5 100644 --- a/Tests/_CryptoExtrasTests/MLDSATests.swift +++ b/Tests/_CryptoExtrasTests/MLDSATests.swift @@ -157,32 +157,6 @@ final class MLDSATests: XCTestCase { XCTAssertThrowsError(try MLDSA87.PublicKey(rawRepresentation: encodedPublicKey)) } - func testMLDSA65PrehashedSigning() throws { - let message = "Hello, world!".data(using: .utf8)! - let context = "ctx".data(using: .utf8)! - - let key = try MLDSA65.PrivateKey() - let publicKey = key.publicKey - - let mu = try publicKey.prehash(for: message, context: context) - - let muSignature = try key.signature(forPrehashedMessageRepresentative: mu) - XCTAssertTrue(publicKey.isValidSignature(muSignature, for: message, context: context)) - } - - func testMLDSA87PrehashedSigning() throws { - let message = "Hello, world!".data(using: .utf8)! - let context = "ctx".data(using: .utf8)! - - let key = try MLDSA87.PrivateKey() - let publicKey = key.publicKey - - let mu = try publicKey.prehash(for: message, context: context) - - let muSignature = try key.signature(forPrehashedMessageRepresentative: mu) - XCTAssertTrue(publicKey.isValidSignature(muSignature, for: message, context: context)) - } - func testMLDSA65NISTKeyGenFile() throws { try nistTest(jsonName: "mldsa_nist_keygen_65_tests") { (testVector: NISTKeyGenTestVector) in let seed = try Data(hexString: testVector.seed) From e25c9419c572235d798e10c39b16792d07b7883d Mon Sep 17 00:00:00 2001 From: Francesco Paolo Severino Date: Wed, 4 Jun 2025 17:36:56 +0200 Subject: [PATCH 04/47] Add an external mu variant of the ML-DSA API (65 and 87 variants) --- .../Signatures/BoringSSL/MLDSA_boring.swift | 201 ++++++++++++++++++ .../BoringSSL/MLDSA_boring.swift.gyb | 102 +++++++++ Tests/_CryptoExtrasTests/MLDSATests.swift | 26 +++ 3 files changed, 329 insertions(+) diff --git a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift index f784d36f2..6967cfa97 100644 --- a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift +++ b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift @@ -76,6 +76,17 @@ extension MLDSA65 { try self.backing.signature(for: data, context: context) } + /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). + /// + /// > Note: The message representative should be obtained via calls to ``MLDSA65/PublicKey/prehash(for:context:)``. + /// + /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). + /// + /// - Returns: The signature of the prehashed message representative. + public func signature(forPrehashedMessageRepresentative mu: M) throws -> Data { + try self.backing.signature(forPrehashedMessageRepresentative: mu) + } + /// The size of the private key in bytes. static let byteCount = Backing.byteCount @@ -176,6 +187,38 @@ extension MLDSA65 { return signature } + /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). + /// + /// > Note: The message representative should be obtained via calls to ``MLDSA65/PublicKey/prehash(for:context:)``. + /// + /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). + /// + /// - Returns: The signature of the prehashed message representative. + func signature(forPrehashedMessageRepresentative mu: M) throws -> Data { + guard mu.count == MLDSA.muByteCount else { + throw CryptoKitError.incorrectParameterSize + } + + var signature = Data(repeating: 0, count: MLDSA65.signatureByteCount) + + let rc: CInt = signature.withUnsafeMutableBytes { signaturePtr in + let muBytes: ContiguousBytes = mu.regions.count == 1 ? mu.regions.first! : Array(mu) + return muBytes.withUnsafeBytes { muPtr in + CCryptoBoringSSL_MLDSA65_sign_message_representative( + signaturePtr.baseAddress, + &self.key, + muPtr.baseAddress + ) + } + } + + guard rc == 1 else { + throw CryptoKitError.internalBoringSSLError() + } + + return signature + } + /// The size of the private key in bytes. static let byteCount = Int(MLDSA65_PRIVATE_KEY_BYTES) } @@ -234,6 +277,27 @@ extension MLDSA65 { self.backing.isValidSignature(signature, for: data, context: context) } + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameter data: The message to prehash. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + public func prehash(for data: D) throws -> Data { + let context: Data? = nil + return try self.backing.prehash(for: data, context: context) + } + + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameters: + /// - data: The message to prehash. + /// - context: The context of the message. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + public func prehash(for data: D, context: C) throws -> Data { + try self.backing.prehash(for: data, context: context) + } + /// The size of the public key in bytes. static let byteCount = Backing.byteCount @@ -315,6 +379,41 @@ extension MLDSA65 { } } + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameters: + /// - data: The message to prehash. + /// - context: The context of the message. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + func prehash(for data: D, context: C?) throws -> Data { + var mu = Data(repeating: 0, count: MLDSA.muByteCount) + + let dataBytes: ContiguousBytes = data.regions.count == 1 ? data.regions.first! : Array(data) + let rc: CInt = mu.withUnsafeMutableBytes { muPtr in + dataBytes.withUnsafeBytes { dataPtr in + context.withUnsafeBytes { contextPtr in + var prehash = MLDSA65_prehash() + let rc = CCryptoBoringSSL_MLDSA65_prehash_init( + &prehash, + &key, + contextPtr.baseAddress, + contextPtr.count + ) + CCryptoBoringSSL_MLDSA65_prehash_update(&prehash, dataPtr.baseAddress, dataPtr.count) + CCryptoBoringSSL_MLDSA65_prehash_finalize(muPtr.baseAddress, &prehash) + return rc + } + } + } + + guard rc == 1 else { + throw CryptoKitError.internalBoringSSLError() + } + + return mu + } + /// The size of the public key in bytes. static let byteCount = Int(MLDSA65_PUBLIC_KEY_BYTES) } @@ -378,6 +477,17 @@ extension MLDSA87 { try self.backing.signature(for: data, context: context) } + /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). + /// + /// > Note: The message representative should be obtained via calls to ``MLDSA87/PublicKey/prehash(for:context:)``. + /// + /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). + /// + /// - Returns: The signature of the prehashed message representative. + public func signature(forPrehashedMessageRepresentative mu: M) throws -> Data { + try self.backing.signature(forPrehashedMessageRepresentative: mu) + } + /// The size of the private key in bytes. static let byteCount = Backing.byteCount @@ -478,6 +588,38 @@ extension MLDSA87 { return signature } + /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). + /// + /// > Note: The message representative should be obtained via calls to ``MLDSA87/PublicKey/prehash(for:context:)``. + /// + /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). + /// + /// - Returns: The signature of the prehashed message representative. + func signature(forPrehashedMessageRepresentative mu: M) throws -> Data { + guard mu.count == MLDSA.muByteCount else { + throw CryptoKitError.incorrectParameterSize + } + + var signature = Data(repeating: 0, count: MLDSA87.signatureByteCount) + + let rc: CInt = signature.withUnsafeMutableBytes { signaturePtr in + let muBytes: ContiguousBytes = mu.regions.count == 1 ? mu.regions.first! : Array(mu) + return muBytes.withUnsafeBytes { muPtr in + CCryptoBoringSSL_MLDSA87_sign_message_representative( + signaturePtr.baseAddress, + &self.key, + muPtr.baseAddress + ) + } + } + + guard rc == 1 else { + throw CryptoKitError.internalBoringSSLError() + } + + return signature + } + /// The size of the private key in bytes. static let byteCount = Int(MLDSA87_PRIVATE_KEY_BYTES) } @@ -536,6 +678,27 @@ extension MLDSA87 { self.backing.isValidSignature(signature, for: data, context: context) } + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameter data: The message to prehash. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + public func prehash(for data: D) throws -> Data { + let context: Data? = nil + return try self.backing.prehash(for: data, context: context) + } + + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameters: + /// - data: The message to prehash. + /// - context: The context of the message. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + public func prehash(for data: D, context: C) throws -> Data { + try self.backing.prehash(for: data, context: context) + } + /// The size of the public key in bytes. static let byteCount = Backing.byteCount @@ -617,6 +780,41 @@ extension MLDSA87 { } } + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameters: + /// - data: The message to prehash. + /// - context: The context of the message. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + func prehash(for data: D, context: C?) throws -> Data { + var mu = Data(repeating: 0, count: MLDSA.muByteCount) + + let dataBytes: ContiguousBytes = data.regions.count == 1 ? data.regions.first! : Array(data) + let rc: CInt = mu.withUnsafeMutableBytes { muPtr in + dataBytes.withUnsafeBytes { dataPtr in + context.withUnsafeBytes { contextPtr in + var prehash = MLDSA87_prehash() + let rc = CCryptoBoringSSL_MLDSA87_prehash_init( + &prehash, + &key, + contextPtr.baseAddress, + contextPtr.count + ) + CCryptoBoringSSL_MLDSA87_prehash_update(&prehash, dataPtr.baseAddress, dataPtr.count) + CCryptoBoringSSL_MLDSA87_prehash_finalize(muPtr.baseAddress, &prehash) + return rc + } + } + } + + guard rc == 1 else { + throw CryptoKitError.internalBoringSSLError() + } + + return mu + } + /// The size of the public key in bytes. static let byteCount = Int(MLDSA87_PUBLIC_KEY_BYTES) } @@ -632,6 +830,9 @@ extension MLDSA87 { enum MLDSA { /// The size of the seed in bytes. fileprivate static let seedByteCount = 32 + + /// The size of the "mu" value in bytes. + fileprivate static let muByteCount = 64 } #endif // CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API diff --git a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb index ed70dd236..c5b705e91 100644 --- a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb +++ b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb @@ -80,6 +80,17 @@ extension MLDSA${parameter_set} { try self.backing.signature(for: data, context: context) } + /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). + /// + /// > Note: The message representative should be obtained via calls to ``MLDSA${parameter_set}/PublicKey/prehash(for:context:)``. + /// + /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). + /// + /// - Returns: The signature of the prehashed message representative. + public func signature(forPrehashedMessageRepresentative mu: M) throws -> Data { + try self.backing.signature(forPrehashedMessageRepresentative: mu) + } + /// The size of the private key in bytes. static let byteCount = Backing.byteCount @@ -180,6 +191,38 @@ extension MLDSA${parameter_set} { return signature } + /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). + /// + /// > Note: The message representative should be obtained via calls to ``MLDSA${parameter_set}/PublicKey/prehash(for:context:)``. + /// + /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). + /// + /// - Returns: The signature of the prehashed message representative. + func signature(forPrehashedMessageRepresentative mu: M) throws -> Data { + guard mu.count == MLDSA.muByteCount else { + throw CryptoKitError.incorrectParameterSize + } + + var signature = Data(repeating: 0, count: MLDSA${parameter_set}.signatureByteCount) + + let rc: CInt = signature.withUnsafeMutableBytes { signaturePtr in + let muBytes: ContiguousBytes = mu.regions.count == 1 ? mu.regions.first! : Array(mu) + return muBytes.withUnsafeBytes { muPtr in + CCryptoBoringSSL_MLDSA${parameter_set}_sign_message_representative( + signaturePtr.baseAddress, + &self.key, + muPtr.baseAddress + ) + } + } + + guard rc == 1 else { + throw CryptoKitError.internalBoringSSLError() + } + + return signature + } + /// The size of the private key in bytes. static let byteCount = Int(MLDSA${parameter_set}_PRIVATE_KEY_BYTES) } @@ -238,6 +281,27 @@ extension MLDSA${parameter_set} { self.backing.isValidSignature(signature, for: data, context: context) } + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameter data: The message to prehash. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + public func prehash(for data: D) throws -> Data { + let context: Data? = nil + return try self.backing.prehash(for: data, context: context) + } + + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameters: + /// - data: The message to prehash. + /// - context: The context of the message. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + public func prehash(for data: D, context: C) throws -> Data { + try self.backing.prehash(for: data, context: context) + } + /// The size of the public key in bytes. static let byteCount = Backing.byteCount @@ -319,6 +383,41 @@ extension MLDSA${parameter_set} { } } + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameters: + /// - data: The message to prehash. + /// - context: The context of the message. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + func prehash(for data: D, context: C?) throws -> Data { + var mu = Data(repeating: 0, count: MLDSA.muByteCount) + + let dataBytes: ContiguousBytes = data.regions.count == 1 ? data.regions.first! : Array(data) + let rc: CInt = mu.withUnsafeMutableBytes { muPtr in + dataBytes.withUnsafeBytes { dataPtr in + context.withUnsafeBytes { contextPtr in + var prehash = MLDSA${parameter_set}_prehash() + let rc = CCryptoBoringSSL_MLDSA${parameter_set}_prehash_init( + &prehash, + &key, + contextPtr.baseAddress, + contextPtr.count + ) + CCryptoBoringSSL_MLDSA${parameter_set}_prehash_update(&prehash, dataPtr.baseAddress, dataPtr.count) + CCryptoBoringSSL_MLDSA${parameter_set}_prehash_finalize(muPtr.baseAddress, &prehash) + return rc + } + } + } + + guard rc == 1 else { + throw CryptoKitError.internalBoringSSLError() + } + + return mu + } + /// The size of the public key in bytes. static let byteCount = Int(MLDSA${parameter_set}_PUBLIC_KEY_BYTES) } @@ -335,6 +434,9 @@ extension MLDSA${parameter_set} { enum MLDSA { /// The size of the seed in bytes. fileprivate static let seedByteCount = 32 + + /// The size of the "mu" value in bytes. + fileprivate static let muByteCount = 64 } #endif // CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API diff --git a/Tests/_CryptoExtrasTests/MLDSATests.swift b/Tests/_CryptoExtrasTests/MLDSATests.swift index 01ddbd743..1a6265d47 100644 --- a/Tests/_CryptoExtrasTests/MLDSATests.swift +++ b/Tests/_CryptoExtrasTests/MLDSATests.swift @@ -185,6 +185,32 @@ final class MLDSATests: XCTestCase { XCTAssertThrowsError(try MLDSA87.PublicKey(rawRepresentation: encodedPublicKey)) } + func testMLDSA65PrehashedSigning() throws { + let message = "Hello, world!".data(using: .utf8)! + let context = "ctx".data(using: .utf8)! + + let key = try MLDSA65.PrivateKey() + let publicKey = key.publicKey + + let mu = try publicKey.prehash(for: message, context: context) + + let muSignature = try key.signature(forPrehashedMessageRepresentative: mu) + XCTAssertTrue(publicKey.isValidSignature(muSignature, for: message, context: context)) + } + + func testMLDSA87PrehashedSigning() throws { + let message = "Hello, world!".data(using: .utf8)! + let context = "ctx".data(using: .utf8)! + + let key = try MLDSA87.PrivateKey() + let publicKey = key.publicKey + + let mu = try publicKey.prehash(for: message, context: context) + + let muSignature = try key.signature(forPrehashedMessageRepresentative: mu) + XCTAssertTrue(publicKey.isValidSignature(muSignature, for: message, context: context)) + } + func testMLDSA65NISTKeyGenFile() throws { guard #available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) else { throw XCTSkip("MLDSA is only available on iOS 19.0+, macOS 16.0+, watchOS 12.0+, tvOS 19.0+, visionOS 3.0+") From e016958bcd9ac07e96a16163941416b3d3137b8d Mon Sep 17 00:00:00 2001 From: Francesco Paolo Severino Date: Mon, 16 Jun 2025 16:01:33 +0200 Subject: [PATCH 05/47] Revert "Add an external mu variant of the ML-DSA API (65 and 87 variants)" This reverts commit e9de693b7f32c82ef36b22d2aefb5177c3ff43fa. --- .../Signatures/BoringSSL/MLDSA_boring.swift | 201 ------------------ .../BoringSSL/MLDSA_boring.swift.gyb | 102 --------- Tests/_CryptoExtrasTests/MLDSATests.swift | 26 --- 3 files changed, 329 deletions(-) diff --git a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift index 6967cfa97..f784d36f2 100644 --- a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift +++ b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift @@ -76,17 +76,6 @@ extension MLDSA65 { try self.backing.signature(for: data, context: context) } - /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). - /// - /// > Note: The message representative should be obtained via calls to ``MLDSA65/PublicKey/prehash(for:context:)``. - /// - /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). - /// - /// - Returns: The signature of the prehashed message representative. - public func signature(forPrehashedMessageRepresentative mu: M) throws -> Data { - try self.backing.signature(forPrehashedMessageRepresentative: mu) - } - /// The size of the private key in bytes. static let byteCount = Backing.byteCount @@ -187,38 +176,6 @@ extension MLDSA65 { return signature } - /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). - /// - /// > Note: The message representative should be obtained via calls to ``MLDSA65/PublicKey/prehash(for:context:)``. - /// - /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). - /// - /// - Returns: The signature of the prehashed message representative. - func signature(forPrehashedMessageRepresentative mu: M) throws -> Data { - guard mu.count == MLDSA.muByteCount else { - throw CryptoKitError.incorrectParameterSize - } - - var signature = Data(repeating: 0, count: MLDSA65.signatureByteCount) - - let rc: CInt = signature.withUnsafeMutableBytes { signaturePtr in - let muBytes: ContiguousBytes = mu.regions.count == 1 ? mu.regions.first! : Array(mu) - return muBytes.withUnsafeBytes { muPtr in - CCryptoBoringSSL_MLDSA65_sign_message_representative( - signaturePtr.baseAddress, - &self.key, - muPtr.baseAddress - ) - } - } - - guard rc == 1 else { - throw CryptoKitError.internalBoringSSLError() - } - - return signature - } - /// The size of the private key in bytes. static let byteCount = Int(MLDSA65_PRIVATE_KEY_BYTES) } @@ -277,27 +234,6 @@ extension MLDSA65 { self.backing.isValidSignature(signature, for: data, context: context) } - /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. - /// - /// - Parameter data: The message to prehash. - /// - /// - Returns: The prehashed message representative (a.k.a. "external mu"). - public func prehash(for data: D) throws -> Data { - let context: Data? = nil - return try self.backing.prehash(for: data, context: context) - } - - /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. - /// - /// - Parameters: - /// - data: The message to prehash. - /// - context: The context of the message. - /// - /// - Returns: The prehashed message representative (a.k.a. "external mu"). - public func prehash(for data: D, context: C) throws -> Data { - try self.backing.prehash(for: data, context: context) - } - /// The size of the public key in bytes. static let byteCount = Backing.byteCount @@ -379,41 +315,6 @@ extension MLDSA65 { } } - /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. - /// - /// - Parameters: - /// - data: The message to prehash. - /// - context: The context of the message. - /// - /// - Returns: The prehashed message representative (a.k.a. "external mu"). - func prehash(for data: D, context: C?) throws -> Data { - var mu = Data(repeating: 0, count: MLDSA.muByteCount) - - let dataBytes: ContiguousBytes = data.regions.count == 1 ? data.regions.first! : Array(data) - let rc: CInt = mu.withUnsafeMutableBytes { muPtr in - dataBytes.withUnsafeBytes { dataPtr in - context.withUnsafeBytes { contextPtr in - var prehash = MLDSA65_prehash() - let rc = CCryptoBoringSSL_MLDSA65_prehash_init( - &prehash, - &key, - contextPtr.baseAddress, - contextPtr.count - ) - CCryptoBoringSSL_MLDSA65_prehash_update(&prehash, dataPtr.baseAddress, dataPtr.count) - CCryptoBoringSSL_MLDSA65_prehash_finalize(muPtr.baseAddress, &prehash) - return rc - } - } - } - - guard rc == 1 else { - throw CryptoKitError.internalBoringSSLError() - } - - return mu - } - /// The size of the public key in bytes. static let byteCount = Int(MLDSA65_PUBLIC_KEY_BYTES) } @@ -477,17 +378,6 @@ extension MLDSA87 { try self.backing.signature(for: data, context: context) } - /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). - /// - /// > Note: The message representative should be obtained via calls to ``MLDSA87/PublicKey/prehash(for:context:)``. - /// - /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). - /// - /// - Returns: The signature of the prehashed message representative. - public func signature(forPrehashedMessageRepresentative mu: M) throws -> Data { - try self.backing.signature(forPrehashedMessageRepresentative: mu) - } - /// The size of the private key in bytes. static let byteCount = Backing.byteCount @@ -588,38 +478,6 @@ extension MLDSA87 { return signature } - /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). - /// - /// > Note: The message representative should be obtained via calls to ``MLDSA87/PublicKey/prehash(for:context:)``. - /// - /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). - /// - /// - Returns: The signature of the prehashed message representative. - func signature(forPrehashedMessageRepresentative mu: M) throws -> Data { - guard mu.count == MLDSA.muByteCount else { - throw CryptoKitError.incorrectParameterSize - } - - var signature = Data(repeating: 0, count: MLDSA87.signatureByteCount) - - let rc: CInt = signature.withUnsafeMutableBytes { signaturePtr in - let muBytes: ContiguousBytes = mu.regions.count == 1 ? mu.regions.first! : Array(mu) - return muBytes.withUnsafeBytes { muPtr in - CCryptoBoringSSL_MLDSA87_sign_message_representative( - signaturePtr.baseAddress, - &self.key, - muPtr.baseAddress - ) - } - } - - guard rc == 1 else { - throw CryptoKitError.internalBoringSSLError() - } - - return signature - } - /// The size of the private key in bytes. static let byteCount = Int(MLDSA87_PRIVATE_KEY_BYTES) } @@ -678,27 +536,6 @@ extension MLDSA87 { self.backing.isValidSignature(signature, for: data, context: context) } - /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. - /// - /// - Parameter data: The message to prehash. - /// - /// - Returns: The prehashed message representative (a.k.a. "external mu"). - public func prehash(for data: D) throws -> Data { - let context: Data? = nil - return try self.backing.prehash(for: data, context: context) - } - - /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. - /// - /// - Parameters: - /// - data: The message to prehash. - /// - context: The context of the message. - /// - /// - Returns: The prehashed message representative (a.k.a. "external mu"). - public func prehash(for data: D, context: C) throws -> Data { - try self.backing.prehash(for: data, context: context) - } - /// The size of the public key in bytes. static let byteCount = Backing.byteCount @@ -780,41 +617,6 @@ extension MLDSA87 { } } - /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. - /// - /// - Parameters: - /// - data: The message to prehash. - /// - context: The context of the message. - /// - /// - Returns: The prehashed message representative (a.k.a. "external mu"). - func prehash(for data: D, context: C?) throws -> Data { - var mu = Data(repeating: 0, count: MLDSA.muByteCount) - - let dataBytes: ContiguousBytes = data.regions.count == 1 ? data.regions.first! : Array(data) - let rc: CInt = mu.withUnsafeMutableBytes { muPtr in - dataBytes.withUnsafeBytes { dataPtr in - context.withUnsafeBytes { contextPtr in - var prehash = MLDSA87_prehash() - let rc = CCryptoBoringSSL_MLDSA87_prehash_init( - &prehash, - &key, - contextPtr.baseAddress, - contextPtr.count - ) - CCryptoBoringSSL_MLDSA87_prehash_update(&prehash, dataPtr.baseAddress, dataPtr.count) - CCryptoBoringSSL_MLDSA87_prehash_finalize(muPtr.baseAddress, &prehash) - return rc - } - } - } - - guard rc == 1 else { - throw CryptoKitError.internalBoringSSLError() - } - - return mu - } - /// The size of the public key in bytes. static let byteCount = Int(MLDSA87_PUBLIC_KEY_BYTES) } @@ -830,9 +632,6 @@ extension MLDSA87 { enum MLDSA { /// The size of the seed in bytes. fileprivate static let seedByteCount = 32 - - /// The size of the "mu" value in bytes. - fileprivate static let muByteCount = 64 } #endif // CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API diff --git a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb index c5b705e91..ed70dd236 100644 --- a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb +++ b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb @@ -80,17 +80,6 @@ extension MLDSA${parameter_set} { try self.backing.signature(for: data, context: context) } - /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). - /// - /// > Note: The message representative should be obtained via calls to ``MLDSA${parameter_set}/PublicKey/prehash(for:context:)``. - /// - /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). - /// - /// - Returns: The signature of the prehashed message representative. - public func signature(forPrehashedMessageRepresentative mu: M) throws -> Data { - try self.backing.signature(forPrehashedMessageRepresentative: mu) - } - /// The size of the private key in bytes. static let byteCount = Backing.byteCount @@ -191,38 +180,6 @@ extension MLDSA${parameter_set} { return signature } - /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). - /// - /// > Note: The message representative should be obtained via calls to ``MLDSA${parameter_set}/PublicKey/prehash(for:context:)``. - /// - /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). - /// - /// - Returns: The signature of the prehashed message representative. - func signature(forPrehashedMessageRepresentative mu: M) throws -> Data { - guard mu.count == MLDSA.muByteCount else { - throw CryptoKitError.incorrectParameterSize - } - - var signature = Data(repeating: 0, count: MLDSA${parameter_set}.signatureByteCount) - - let rc: CInt = signature.withUnsafeMutableBytes { signaturePtr in - let muBytes: ContiguousBytes = mu.regions.count == 1 ? mu.regions.first! : Array(mu) - return muBytes.withUnsafeBytes { muPtr in - CCryptoBoringSSL_MLDSA${parameter_set}_sign_message_representative( - signaturePtr.baseAddress, - &self.key, - muPtr.baseAddress - ) - } - } - - guard rc == 1 else { - throw CryptoKitError.internalBoringSSLError() - } - - return signature - } - /// The size of the private key in bytes. static let byteCount = Int(MLDSA${parameter_set}_PRIVATE_KEY_BYTES) } @@ -281,27 +238,6 @@ extension MLDSA${parameter_set} { self.backing.isValidSignature(signature, for: data, context: context) } - /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. - /// - /// - Parameter data: The message to prehash. - /// - /// - Returns: The prehashed message representative (a.k.a. "external mu"). - public func prehash(for data: D) throws -> Data { - let context: Data? = nil - return try self.backing.prehash(for: data, context: context) - } - - /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. - /// - /// - Parameters: - /// - data: The message to prehash. - /// - context: The context of the message. - /// - /// - Returns: The prehashed message representative (a.k.a. "external mu"). - public func prehash(for data: D, context: C) throws -> Data { - try self.backing.prehash(for: data, context: context) - } - /// The size of the public key in bytes. static let byteCount = Backing.byteCount @@ -383,41 +319,6 @@ extension MLDSA${parameter_set} { } } - /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. - /// - /// - Parameters: - /// - data: The message to prehash. - /// - context: The context of the message. - /// - /// - Returns: The prehashed message representative (a.k.a. "external mu"). - func prehash(for data: D, context: C?) throws -> Data { - var mu = Data(repeating: 0, count: MLDSA.muByteCount) - - let dataBytes: ContiguousBytes = data.regions.count == 1 ? data.regions.first! : Array(data) - let rc: CInt = mu.withUnsafeMutableBytes { muPtr in - dataBytes.withUnsafeBytes { dataPtr in - context.withUnsafeBytes { contextPtr in - var prehash = MLDSA${parameter_set}_prehash() - let rc = CCryptoBoringSSL_MLDSA${parameter_set}_prehash_init( - &prehash, - &key, - contextPtr.baseAddress, - contextPtr.count - ) - CCryptoBoringSSL_MLDSA${parameter_set}_prehash_update(&prehash, dataPtr.baseAddress, dataPtr.count) - CCryptoBoringSSL_MLDSA${parameter_set}_prehash_finalize(muPtr.baseAddress, &prehash) - return rc - } - } - } - - guard rc == 1 else { - throw CryptoKitError.internalBoringSSLError() - } - - return mu - } - /// The size of the public key in bytes. static let byteCount = Int(MLDSA${parameter_set}_PUBLIC_KEY_BYTES) } @@ -434,9 +335,6 @@ extension MLDSA${parameter_set} { enum MLDSA { /// The size of the seed in bytes. fileprivate static let seedByteCount = 32 - - /// The size of the "mu" value in bytes. - fileprivate static let muByteCount = 64 } #endif // CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API diff --git a/Tests/_CryptoExtrasTests/MLDSATests.swift b/Tests/_CryptoExtrasTests/MLDSATests.swift index 1a6265d47..01ddbd743 100644 --- a/Tests/_CryptoExtrasTests/MLDSATests.swift +++ b/Tests/_CryptoExtrasTests/MLDSATests.swift @@ -185,32 +185,6 @@ final class MLDSATests: XCTestCase { XCTAssertThrowsError(try MLDSA87.PublicKey(rawRepresentation: encodedPublicKey)) } - func testMLDSA65PrehashedSigning() throws { - let message = "Hello, world!".data(using: .utf8)! - let context = "ctx".data(using: .utf8)! - - let key = try MLDSA65.PrivateKey() - let publicKey = key.publicKey - - let mu = try publicKey.prehash(for: message, context: context) - - let muSignature = try key.signature(forPrehashedMessageRepresentative: mu) - XCTAssertTrue(publicKey.isValidSignature(muSignature, for: message, context: context)) - } - - func testMLDSA87PrehashedSigning() throws { - let message = "Hello, world!".data(using: .utf8)! - let context = "ctx".data(using: .utf8)! - - let key = try MLDSA87.PrivateKey() - let publicKey = key.publicKey - - let mu = try publicKey.prehash(for: message, context: context) - - let muSignature = try key.signature(forPrehashedMessageRepresentative: mu) - XCTAssertTrue(publicKey.isValidSignature(muSignature, for: message, context: context)) - } - func testMLDSA65NISTKeyGenFile() throws { guard #available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) else { throw XCTSkip("MLDSA is only available on iOS 19.0+, macOS 16.0+, watchOS 12.0+, tvOS 19.0+, visionOS 3.0+") From 74c97decf69e9e8f7289aca2c5f6a7f92d0fa9b1 Mon Sep 17 00:00:00 2001 From: Francesco Paolo Severino Date: Mon, 16 Jun 2025 20:23:39 +0200 Subject: [PATCH 06/47] Add external mu variant of ML-DSA to BoringSSL implementation --- .../Signatures/BoringSSL/MLDSA_boring.swift | 201 ++++++++++++++++++ .../BoringSSL/MLDSA_boring.swift.gyb | 102 +++++++++ 2 files changed, 303 insertions(+) diff --git a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift index f784d36f2..634c758de 100644 --- a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift +++ b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift @@ -76,6 +76,17 @@ extension MLDSA65 { try self.backing.signature(for: data, context: context) } + /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). + /// + /// > Note: The message representative should be obtained via calls to ``MLDSA65/PublicKey/prehash(for:context:)``. + /// + /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). + /// + /// - Returns: The signature of the prehashed message representative. + func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { + try self.backing.signature(forPrehashedMessageRepresentative: mu) + } + /// The size of the private key in bytes. static let byteCount = Backing.byteCount @@ -176,6 +187,38 @@ extension MLDSA65 { return signature } + /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). + /// + /// > Note: The message representative should be obtained via calls to ``MLDSA65/PublicKey/prehash(for:context:)``. + /// + /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). + /// + /// - Returns: The signature of the prehashed message representative. + func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { + guard mu.count == MLDSA.muByteCount else { + throw CryptoKitError.incorrectParameterSize + } + + var signature = Data(repeating: 0, count: MLDSA65.signatureByteCount) + + let rc: CInt = signature.withUnsafeMutableBytes { signaturePtr in + let muBytes: ContiguousBytes = mu.regions.count == 1 ? mu.regions.first! : Array(mu) + return muBytes.withUnsafeBytes { muPtr in + CCryptoBoringSSL_MLDSA65_sign_message_representative( + signaturePtr.baseAddress, + &self.key, + muPtr.baseAddress + ) + } + } + + guard rc == 1 else { + throw CryptoKitError.internalBoringSSLError() + } + + return signature + } + /// The size of the private key in bytes. static let byteCount = Int(MLDSA65_PRIVATE_KEY_BYTES) } @@ -234,6 +277,27 @@ extension MLDSA65 { self.backing.isValidSignature(signature, for: data, context: context) } + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameter data: The message to prehash. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + func prehash(for data: D) throws -> Data { + let context: Data? = nil + return try self.backing.prehash(for: data, context: context) + } + + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameters: + /// - data: The message to prehash. + /// - context: The context of the message. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + func prehash(for data: D, context: C) throws -> Data { + try self.backing.prehash(for: data, context: context) + } + /// The size of the public key in bytes. static let byteCount = Backing.byteCount @@ -315,6 +379,41 @@ extension MLDSA65 { } } + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameters: + /// - data: The message to prehash. + /// - context: The context of the message. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + func prehash(for data: D, context: C?) throws -> Data { + var mu = Data(repeating: 0, count: MLDSA.muByteCount) + + let dataBytes: ContiguousBytes = data.regions.count == 1 ? data.regions.first! : Array(data) + let rc: CInt = mu.withUnsafeMutableBytes { muPtr in + dataBytes.withUnsafeBytes { dataPtr in + context.withUnsafeBytes { contextPtr in + var prehash = MLDSA65_prehash() + let rc = CCryptoBoringSSL_MLDSA65_prehash_init( + &prehash, + &key, + contextPtr.baseAddress, + contextPtr.count + ) + CCryptoBoringSSL_MLDSA65_prehash_update(&prehash, dataPtr.baseAddress, dataPtr.count) + CCryptoBoringSSL_MLDSA65_prehash_finalize(muPtr.baseAddress, &prehash) + return rc + } + } + } + + guard rc == 1 else { + throw CryptoKitError.internalBoringSSLError() + } + + return mu + } + /// The size of the public key in bytes. static let byteCount = Int(MLDSA65_PUBLIC_KEY_BYTES) } @@ -378,6 +477,17 @@ extension MLDSA87 { try self.backing.signature(for: data, context: context) } + /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). + /// + /// > Note: The message representative should be obtained via calls to ``MLDSA87/PublicKey/prehash(for:context:)``. + /// + /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). + /// + /// - Returns: The signature of the prehashed message representative. + func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { + try self.backing.signature(forPrehashedMessageRepresentative: mu) + } + /// The size of the private key in bytes. static let byteCount = Backing.byteCount @@ -478,6 +588,38 @@ extension MLDSA87 { return signature } + /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). + /// + /// > Note: The message representative should be obtained via calls to ``MLDSA87/PublicKey/prehash(for:context:)``. + /// + /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). + /// + /// - Returns: The signature of the prehashed message representative. + func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { + guard mu.count == MLDSA.muByteCount else { + throw CryptoKitError.incorrectParameterSize + } + + var signature = Data(repeating: 0, count: MLDSA87.signatureByteCount) + + let rc: CInt = signature.withUnsafeMutableBytes { signaturePtr in + let muBytes: ContiguousBytes = mu.regions.count == 1 ? mu.regions.first! : Array(mu) + return muBytes.withUnsafeBytes { muPtr in + CCryptoBoringSSL_MLDSA87_sign_message_representative( + signaturePtr.baseAddress, + &self.key, + muPtr.baseAddress + ) + } + } + + guard rc == 1 else { + throw CryptoKitError.internalBoringSSLError() + } + + return signature + } + /// The size of the private key in bytes. static let byteCount = Int(MLDSA87_PRIVATE_KEY_BYTES) } @@ -536,6 +678,27 @@ extension MLDSA87 { self.backing.isValidSignature(signature, for: data, context: context) } + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameter data: The message to prehash. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + func prehash(for data: D) throws -> Data { + let context: Data? = nil + return try self.backing.prehash(for: data, context: context) + } + + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameters: + /// - data: The message to prehash. + /// - context: The context of the message. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + func prehash(for data: D, context: C) throws -> Data { + try self.backing.prehash(for: data, context: context) + } + /// The size of the public key in bytes. static let byteCount = Backing.byteCount @@ -617,6 +780,41 @@ extension MLDSA87 { } } + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameters: + /// - data: The message to prehash. + /// - context: The context of the message. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + func prehash(for data: D, context: C?) throws -> Data { + var mu = Data(repeating: 0, count: MLDSA.muByteCount) + + let dataBytes: ContiguousBytes = data.regions.count == 1 ? data.regions.first! : Array(data) + let rc: CInt = mu.withUnsafeMutableBytes { muPtr in + dataBytes.withUnsafeBytes { dataPtr in + context.withUnsafeBytes { contextPtr in + var prehash = MLDSA87_prehash() + let rc = CCryptoBoringSSL_MLDSA87_prehash_init( + &prehash, + &key, + contextPtr.baseAddress, + contextPtr.count + ) + CCryptoBoringSSL_MLDSA87_prehash_update(&prehash, dataPtr.baseAddress, dataPtr.count) + CCryptoBoringSSL_MLDSA87_prehash_finalize(muPtr.baseAddress, &prehash) + return rc + } + } + } + + guard rc == 1 else { + throw CryptoKitError.internalBoringSSLError() + } + + return mu + } + /// The size of the public key in bytes. static let byteCount = Int(MLDSA87_PUBLIC_KEY_BYTES) } @@ -632,6 +830,9 @@ extension MLDSA87 { enum MLDSA { /// The size of the seed in bytes. fileprivate static let seedByteCount = 32 + + /// The size of the "mu" value in bytes. + fileprivate static let muByteCount = 64 } #endif // CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API diff --git a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb index ed70dd236..2a7a62d01 100644 --- a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb +++ b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb @@ -80,6 +80,17 @@ extension MLDSA${parameter_set} { try self.backing.signature(for: data, context: context) } + /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). + /// + /// > Note: The message representative should be obtained via calls to ``MLDSA${parameter_set}/PublicKey/prehash(for:context:)``. + /// + /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). + /// + /// - Returns: The signature of the prehashed message representative. + func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { + try self.backing.signature(forPrehashedMessageRepresentative: mu) + } + /// The size of the private key in bytes. static let byteCount = Backing.byteCount @@ -180,6 +191,38 @@ extension MLDSA${parameter_set} { return signature } + /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). + /// + /// > Note: The message representative should be obtained via calls to ``MLDSA${parameter_set}/PublicKey/prehash(for:context:)``. + /// + /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). + /// + /// - Returns: The signature of the prehashed message representative. + func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { + guard mu.count == MLDSA.muByteCount else { + throw CryptoKitError.incorrectParameterSize + } + + var signature = Data(repeating: 0, count: MLDSA${parameter_set}.signatureByteCount) + + let rc: CInt = signature.withUnsafeMutableBytes { signaturePtr in + let muBytes: ContiguousBytes = mu.regions.count == 1 ? mu.regions.first! : Array(mu) + return muBytes.withUnsafeBytes { muPtr in + CCryptoBoringSSL_MLDSA${parameter_set}_sign_message_representative( + signaturePtr.baseAddress, + &self.key, + muPtr.baseAddress + ) + } + } + + guard rc == 1 else { + throw CryptoKitError.internalBoringSSLError() + } + + return signature + } + /// The size of the private key in bytes. static let byteCount = Int(MLDSA${parameter_set}_PRIVATE_KEY_BYTES) } @@ -238,6 +281,27 @@ extension MLDSA${parameter_set} { self.backing.isValidSignature(signature, for: data, context: context) } + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameter data: The message to prehash. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + func prehash(for data: D) throws -> Data { + let context: Data? = nil + return try self.backing.prehash(for: data, context: context) + } + + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameters: + /// - data: The message to prehash. + /// - context: The context of the message. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + func prehash(for data: D, context: C) throws -> Data { + try self.backing.prehash(for: data, context: context) + } + /// The size of the public key in bytes. static let byteCount = Backing.byteCount @@ -319,6 +383,41 @@ extension MLDSA${parameter_set} { } } + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameters: + /// - data: The message to prehash. + /// - context: The context of the message. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + func prehash(for data: D, context: C?) throws -> Data { + var mu = Data(repeating: 0, count: MLDSA.muByteCount) + + let dataBytes: ContiguousBytes = data.regions.count == 1 ? data.regions.first! : Array(data) + let rc: CInt = mu.withUnsafeMutableBytes { muPtr in + dataBytes.withUnsafeBytes { dataPtr in + context.withUnsafeBytes { contextPtr in + var prehash = MLDSA${parameter_set}_prehash() + let rc = CCryptoBoringSSL_MLDSA${parameter_set}_prehash_init( + &prehash, + &key, + contextPtr.baseAddress, + contextPtr.count + ) + CCryptoBoringSSL_MLDSA${parameter_set}_prehash_update(&prehash, dataPtr.baseAddress, dataPtr.count) + CCryptoBoringSSL_MLDSA${parameter_set}_prehash_finalize(muPtr.baseAddress, &prehash) + return rc + } + } + } + + guard rc == 1 else { + throw CryptoKitError.internalBoringSSLError() + } + + return mu + } + /// The size of the public key in bytes. static let byteCount = Int(MLDSA${parameter_set}_PUBLIC_KEY_BYTES) } @@ -335,6 +434,9 @@ extension MLDSA${parameter_set} { enum MLDSA { /// The size of the seed in bytes. fileprivate static let seedByteCount = 32 + + /// The size of the "mu" value in bytes. + fileprivate static let muByteCount = 64 } #endif // CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API From a6213d750d0b56e8b53bed14663d116074d1560c Mon Sep 17 00:00:00 2001 From: Francesco Paolo Severino Date: Mon, 16 Jun 2025 20:30:31 +0200 Subject: [PATCH 07/47] Add external mu API to wrapper with `package` level --- .../Signatures/BoringSSL/MLDSA_wrapper.swift | 18 ++++ Sources/Crypto/Signatures/MLDSA.swift | 88 +++++++++++++++++++ Sources/Crypto/Signatures/MLDSA.swift.gyb | 48 ++++++++++ 3 files changed, 154 insertions(+) diff --git a/Sources/Crypto/Signatures/BoringSSL/MLDSA_wrapper.swift b/Sources/Crypto/Signatures/BoringSSL/MLDSA_wrapper.swift index 5d18b7d74..ddacae21f 100644 --- a/Sources/Crypto/Signatures/BoringSSL/MLDSA_wrapper.swift +++ b/Sources/Crypto/Signatures/BoringSSL/MLDSA_wrapper.swift @@ -30,6 +30,8 @@ protocol BoringSSLBackedMLDSAPrivateKey { func signature(for data: D, context: C) throws -> Data + func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data + var publicKey: AssociatedPublicKey { get } var seedRepresentation: Data { get } @@ -44,6 +46,10 @@ protocol BoringSSLBackedMLDSAPublicKey { func isValidSignature(_: S, for data: D, context: C) -> Bool var rawRepresentation: Data { get } + + func prehash(for data: D) throws -> Data + + func prehash(for data: D, context: C) throws -> Data } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) @@ -102,6 +108,10 @@ struct OpenSSLMLDSAPrivateKeyImpl { try self.backing.signature(for: data, context: context) } + func signature_boring(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { + try self.backing.signature(forPrehashedMessageRepresentative: mu) + } + var publicKey: OpenSSLMLDSAPublicKeyImpl { .init(backing: self.backing.publicKey) } @@ -145,6 +155,14 @@ struct OpenSSLMLDSAPublicKeyImpl { var rawRepresentation: Data { self.backing.rawRepresentation } + + func prehash_boring(for data: D) throws -> Data { + try self.backing.prehash(for: data) + } + + func prehash_boring(for data: D, context: C) throws -> Data { + try self.backing.prehash(for: data, context: context) + } } #endif // CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API diff --git a/Sources/Crypto/Signatures/MLDSA.swift b/Sources/Crypto/Signatures/MLDSA.swift index 0a079ca45..4d16b1281 100644 --- a/Sources/Crypto/Signatures/MLDSA.swift +++ b/Sources/Crypto/Signatures/MLDSA.swift @@ -76,6 +76,32 @@ extension MLDSA65 { fileprivate init(impl: MLDSAPublicKeyImpl) { self.impl = impl } + + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameter data: The message to prehash. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + package func prehash_boring(for data: D) throws -> Data { + let implementation = self.impl is OpenSSLMLDSAPublicKeyImpl + ? self.impl + : try OpenSSLMLDSAPublicKeyImpl(rawRepresentation: self.rawRepresentation) + return try implementation.prehash_boring(for: data) + } + + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameters: + /// - data: The message to prehash. + /// - context: The context of the message. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + package func prehash_boring(for data: D, context: C) throws -> Data { + let implementation = self.impl is OpenSSLMLDSAPublicKeyImpl + ? self.impl + : try OpenSSLMLDSAPublicKeyImpl(rawRepresentation: self.rawRepresentation) + return try implementation.prehash_boring(for: data, context: context) + } } /// The private key for MLDSA65. @@ -101,6 +127,20 @@ extension MLDSA65 { try self.impl.signature(for: data, context: context) } + /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). + /// + /// > Note: The message representative should be obtained via calls to ``MLDSA87/PublicKey/prehash(for:context:)``. + /// + /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). + /// + /// - Returns: The signature of the prehashed message representative. + package func signature_boring(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { + let implementation = self.impl is OpenSSLMLDSAPrivateKeyImpl + ? self.impl + : try OpenSSLMLDSAPrivateKeyImpl(seedRepresentation: self.seedRepresentation, publicKey: nil) + return try implementation.signature_boring(forPrehashedMessageRepresentative: mu) + } + /// The associated public key. public var publicKey: PublicKey { get { @@ -151,6 +191,10 @@ extension MLDSA65 { return self.impl.integrityCheckedRepresentation } } + + fileprivate init(impl: MLDSAPrivateKeyImpl) { + self.impl = impl + } } } @@ -204,6 +248,32 @@ extension MLDSA87 { fileprivate init(impl: MLDSAPublicKeyImpl) { self.impl = impl } + + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameter data: The message to prehash. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + package func prehash_boring(for data: D) throws -> Data { + let implementation = self.impl is OpenSSLMLDSAPublicKeyImpl + ? self.impl + : try OpenSSLMLDSAPublicKeyImpl(rawRepresentation: self.rawRepresentation) + return try implementation.prehash_boring(for: data) + } + + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameters: + /// - data: The message to prehash. + /// - context: The context of the message. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + package func prehash_boring(for data: D, context: C) throws -> Data { + let implementation = self.impl is OpenSSLMLDSAPublicKeyImpl + ? self.impl + : try OpenSSLMLDSAPublicKeyImpl(rawRepresentation: self.rawRepresentation) + return try implementation.prehash_boring(for: data, context: context) + } } /// The private key for MLDSA87. @@ -229,6 +299,20 @@ extension MLDSA87 { try self.impl.signature(for: data, context: context) } + /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). + /// + /// > Note: The message representative should be obtained via calls to ``MLDSA87/PublicKey/prehash(for:context:)``. + /// + /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). + /// + /// - Returns: The signature of the prehashed message representative. + package func signature_boring(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { + let implementation = self.impl is OpenSSLMLDSAPrivateKeyImpl + ? self.impl + : try OpenSSLMLDSAPrivateKeyImpl(seedRepresentation: self.seedRepresentation, publicKey: nil) + return try implementation.signature_boring(forPrehashedMessageRepresentative: mu) + } + /// The associated public key. public var publicKey: PublicKey { get { @@ -279,6 +363,10 @@ extension MLDSA87 { return self.impl.integrityCheckedRepresentation } } + + fileprivate init(impl: MLDSAPrivateKeyImpl) { + self.impl = impl + } } } diff --git a/Sources/Crypto/Signatures/MLDSA.swift.gyb b/Sources/Crypto/Signatures/MLDSA.swift.gyb index 9481fc670..3d136b541 100644 --- a/Sources/Crypto/Signatures/MLDSA.swift.gyb +++ b/Sources/Crypto/Signatures/MLDSA.swift.gyb @@ -20,7 +20,9 @@ public import Foundation typealias MLDSAPublicKeyImpl = CoreCryptoMLDSAPublicKeyImpl typealias MLDSAPrivateKeyImpl = CoreCryptoMLDSAPrivateKeyImpl #else +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) typealias MLDSAPublicKeyImpl = OpenSSLMLDSAPublicKeyImpl +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) typealias MLDSAPrivateKeyImpl = OpenSSLMLDSAPrivateKeyImpl #endif @@ -34,8 +36,10 @@ typealias MLDSAPrivateKeyImpl = OpenSSLMLDSAPrivateKeyImpl }% /// The ${NAME} Digital Signature Algorithm +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) public enum ${NAME}: Sendable {} +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ${NAME} { /// The public key for ${NAME}. public struct PublicKey: Sendable { @@ -80,6 +84,32 @@ extension ${NAME} { fileprivate init(impl: MLDSAPublicKeyImpl<${NAME}>) { self.impl = impl } + + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameter data: The message to prehash. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + package func prehash_boring(for data: D) throws -> Data { + let implementation = self.impl is OpenSSLMLDSAPublicKeyImpl<${NAME}> + ? self.impl + : try OpenSSLMLDSAPublicKeyImpl<${NAME}>(rawRepresentation: self.rawRepresentation) + return try implementation.prehash_boring(for: data) + } + + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameters: + /// - data: The message to prehash. + /// - context: The context of the message. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + package func prehash_boring(for data: D, context: C) throws -> Data { + let implementation = self.impl is OpenSSLMLDSAPublicKeyImpl<${NAME}> + ? self.impl + : try OpenSSLMLDSAPublicKeyImpl<${NAME}>(rawRepresentation: self.rawRepresentation) + return try implementation.prehash_boring(for: data, context: context) + } } /// The private key for ${NAME}. @@ -105,6 +135,20 @@ extension ${NAME} { try self.impl.signature(for: data, context: context) } + /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). + /// + /// > Note: The message representative should be obtained via calls to ``MLDSA87/PublicKey/prehash(for:context:)``. + /// + /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). + /// + /// - Returns: The signature of the prehashed message representative. + package func signature_boring(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { + let implementation = self.impl is OpenSSLMLDSAPrivateKeyImpl<${NAME}> + ? self.impl + : try OpenSSLMLDSAPrivateKeyImpl<${NAME}>(seedRepresentation: self.seedRepresentation, publicKey: nil) + return try implementation.signature_boring(forPrehashedMessageRepresentative: mu) + } + /// The associated public key. public var publicKey: PublicKey { get { @@ -155,6 +199,10 @@ extension ${NAME} { return self.impl.integrityCheckedRepresentation } } + + fileprivate init(impl: MLDSAPrivateKeyImpl<${NAME}>) { + self.impl = impl + } } } From bc935acaf387e6aae79b73daac2a241d66851727 Mon Sep 17 00:00:00 2001 From: Francesco Paolo Severino Date: Mon, 16 Jun 2025 20:31:03 +0200 Subject: [PATCH 08/47] Expose external mu API in CryptoExtras --- .../MLDSA/MLDSA+externalMu.swift | 94 +++++++++++++++++++ .../MLDSA/MLDSA+externalMu.swift.gyb | 62 ++++++++++++ 2 files changed, 156 insertions(+) create mode 100644 Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift create mode 100644 Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb diff --git a/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift b/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift new file mode 100644 index 000000000..9f1c4ad90 --- /dev/null +++ b/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift @@ -0,0 +1,94 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2025 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +// MARK: - Generated file, do NOT edit +// any edits of this file WILL be overwritten and thus discarded +// see section `gyb` in `README` for details. + +import Crypto +import Foundation + +@available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) +extension MLDSA65.PrivateKey { + /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). + /// + /// > Note: The message representative should be obtained via calls to ``MLDSA65/PublicKey/prehash(for:context:)``. + /// + /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). + /// + /// - Returns: The signature of the prehashed message representative. + public func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { + try self.signature_boring(forPrehashedMessageRepresentative: mu) + } +} + +@available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) +extension MLDSA65.PublicKey { + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameter data: The message to prehash. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + public func prehash(for data: D) throws -> Data { + return try self.prehash_boring(for: data) + } + + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameters: + /// - data: The message to prehash. + /// - context: The context of the message. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + public func prehash(for data: D, context: C) throws -> Data { + try self.prehash_boring(for: data, context: context) + } +} + +@available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) +extension MLDSA87.PrivateKey { + /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). + /// + /// > Note: The message representative should be obtained via calls to ``MLDSA87/PublicKey/prehash(for:context:)``. + /// + /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). + /// + /// - Returns: The signature of the prehashed message representative. + public func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { + try self.signature_boring(forPrehashedMessageRepresentative: mu) + } +} + +@available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) +extension MLDSA87.PublicKey { + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameter data: The message to prehash. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + public func prehash(for data: D) throws -> Data { + return try self.prehash_boring(for: data) + } + + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameters: + /// - data: The message to prehash. + /// - context: The context of the message. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + public func prehash(for data: D, context: C) throws -> Data { + try self.prehash_boring(for: data, context: context) + } +} diff --git a/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb b/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb new file mode 100644 index 000000000..01103c26c --- /dev/null +++ b/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2025 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +// MARK: - Generated file, do NOT edit +// any edits of this file WILL be overwritten and thus discarded +// see section `gyb` in `README` for details. + +import Crypto +import Foundation +%{ + parameter_sets = ["65", "87"] +}% +% for parameter_set in parameter_sets: + +@available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) +extension MLDSA${parameter_set}.PrivateKey { + /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). + /// + /// > Note: The message representative should be obtained via calls to ``MLDSA${parameter_set}/PublicKey/prehash(for:context:)``. + /// + /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). + /// + /// - Returns: The signature of the prehashed message representative. + public func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { + try self.signature_boring(forPrehashedMessageRepresentative: mu) + } +} + +@available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) +extension MLDSA${parameter_set}.PublicKey { + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameter data: The message to prehash. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + public func prehash(for data: D) throws -> Data { + return try self.prehash_boring(for: data) + } + + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameters: + /// - data: The message to prehash. + /// - context: The context of the message. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + public func prehash(for data: D, context: C) throws -> Data { + try self.prehash_boring(for: data, context: context) + } +} +%end From f8ed3ee344fe72f2dc4a23aa49842ec4be352ca7 Mon Sep 17 00:00:00 2001 From: Francesco Paolo Severino Date: Mon, 16 Jun 2025 20:31:21 +0200 Subject: [PATCH 09/47] Add tests for external mu variant --- Tests/_CryptoExtrasTests/MLDSATests.swift | 34 +++++++++++++++++++++-- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/Tests/_CryptoExtrasTests/MLDSATests.swift b/Tests/_CryptoExtrasTests/MLDSATests.swift index 01ddbd743..b1e518595 100644 --- a/Tests/_CryptoExtrasTests/MLDSATests.swift +++ b/Tests/_CryptoExtrasTests/MLDSATests.swift @@ -12,12 +12,11 @@ // //===----------------------------------------------------------------------===// -#if !canImport(Darwin) || canImport(CryptoKit, _version: 324.0.4) - import XCTest -@testable import _CryptoExtras +import _CryptoExtras +#if !canImport(Darwin) || canImport(CryptoKit, _version: 324.0.4) final class MLDSATests: XCTestCase { func testMLDSA65Signing() throws { guard #available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) else { @@ -356,3 +355,32 @@ extension MLDSA87.PublicKey { } #endif // SDK has MLDSA + +@available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) +final class MLDSAExternalMuTests: XCTestCase { + func testMLDSA65PrehashedSigning() throws { + let message = "Hello, world!".data(using: .utf8)! + let context = "ctx".data(using: .utf8)! + + let key = try MLDSA65.PrivateKey() + let publicKey = key.publicKey + + let mu = try publicKey.prehash(for: message, context: context) + + let muSignature = try key.signature(forPrehashedMessageRepresentative: mu) + XCTAssertTrue(publicKey.isValidSignature(signature: muSignature, for: message, context: context)) + } + + func testMLDSA87PrehashedSigning() throws { + let message = "Hello, world!".data(using: .utf8)! + let context = "ctx".data(using: .utf8)! + + let key = try MLDSA87.PrivateKey() + let publicKey = key.publicKey + + let mu = try publicKey.prehash(for: message, context: context) + + let muSignature = try key.signature(forPrehashedMessageRepresentative: mu) + XCTAssertTrue(publicKey.isValidSignature(signature: muSignature, for: message, context: context)) + } +} \ No newline at end of file From 64aa6ca40aa2dbbb8882862af20fb1a178d08b74 Mon Sep 17 00:00:00 2001 From: Francesco Paolo Severino Date: Mon, 16 Jun 2025 20:37:34 +0200 Subject: [PATCH 10/47] Small formatting fixes --- .../Signatures/BoringSSL/MLDSA_boring.swift | 9 ++-- .../BoringSSL/MLDSA_boring.swift.gyb | 9 ++-- Sources/Crypto/Signatures/MLDSA.swift | 43 ++++++++++++------- Sources/Crypto/Signatures/MLDSA.swift.gyb | 23 ++++++---- 4 files changed, 47 insertions(+), 37 deletions(-) diff --git a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift index 634c758de..ebc3f3362 100644 --- a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift +++ b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift @@ -12,16 +12,13 @@ // //===----------------------------------------------------------------------===// -#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API -@_exported import CryptoKit -#else -@_implementationOnly import CCryptoBoringSSL -import Foundation - // MARK: - Generated file, do NOT edit // any edits of this file WILL be overwritten and thus discarded // see section `gyb` in `README` for details. +#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +@_exported import CryptoKit +#else @_implementationOnly import CCryptoBoringSSL import Foundation diff --git a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb index 2a7a62d01..25170f1b2 100644 --- a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb +++ b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb @@ -12,16 +12,13 @@ // //===----------------------------------------------------------------------===// -#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API -@_exported import CryptoKit -#else -@_implementationOnly import CCryptoBoringSSL -import Foundation - // MARK: - Generated file, do NOT edit // any edits of this file WILL be overwritten and thus discarded // see section `gyb` in `README` for details. +#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +@_exported import CryptoKit +#else @_implementationOnly import CCryptoBoringSSL import Foundation %{ diff --git a/Sources/Crypto/Signatures/MLDSA.swift b/Sources/Crypto/Signatures/MLDSA.swift index 4d16b1281..a88ff05ce 100644 --- a/Sources/Crypto/Signatures/MLDSA.swift +++ b/Sources/Crypto/Signatures/MLDSA.swift @@ -26,7 +26,6 @@ typealias MLDSAPublicKeyImpl = OpenSSLMLDSAPublicKeyImpl typealias MLDSAPrivateKeyImpl = OpenSSLMLDSAPrivateKeyImpl #endif - /// The MLDSA65 Digital Signature Algorithm @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) public enum MLDSA65: Sendable {} @@ -52,7 +51,11 @@ extension MLDSA65 { /// - data: The signed data. /// - context: Context for the signature. /// - Returns: `true` if the signature is valid in the specified context, `false` otherwise. - public func isValidSignature(signature: S, for data: D, context: C) -> Bool { + public func isValidSignature( + signature: S, + for data: D, + context: C + ) -> Bool { self.impl.isValidSignature(signature: signature, for: data, context: context) } @@ -83,7 +86,8 @@ extension MLDSA65 { /// /// - Returns: The prehashed message representative (a.k.a. "external mu"). package func prehash_boring(for data: D) throws -> Data { - let implementation = self.impl is OpenSSLMLDSAPublicKeyImpl + let implementation = + self.impl is OpenSSLMLDSAPublicKeyImpl ? self.impl : try OpenSSLMLDSAPublicKeyImpl(rawRepresentation: self.rawRepresentation) return try implementation.prehash_boring(for: data) @@ -97,7 +101,8 @@ extension MLDSA65 { /// /// - Returns: The prehashed message representative (a.k.a. "external mu"). package func prehash_boring(for data: D, context: C) throws -> Data { - let implementation = self.impl is OpenSSLMLDSAPublicKeyImpl + let implementation = + self.impl is OpenSSLMLDSAPublicKeyImpl ? self.impl : try OpenSSLMLDSAPublicKeyImpl(rawRepresentation: self.rawRepresentation) return try implementation.prehash_boring(for: data, context: context) @@ -135,7 +140,8 @@ extension MLDSA65 { /// /// - Returns: The signature of the prehashed message representative. package func signature_boring(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { - let implementation = self.impl is OpenSSLMLDSAPrivateKeyImpl + let implementation = + self.impl is OpenSSLMLDSAPrivateKeyImpl ? self.impl : try OpenSSLMLDSAPrivateKeyImpl(seedRepresentation: self.seedRepresentation, publicKey: nil) return try implementation.signature_boring(forPrehashedMessageRepresentative: mu) @@ -171,7 +177,7 @@ extension MLDSA65 { /// for the `ML-DSA.KeyGen_internal` algorithm (Algorithm 16) of FIPS 204. public var seedRepresentation: Data { get { - return self.impl.seedRepresentation + self.impl.seedRepresentation } } @@ -188,7 +194,7 @@ extension MLDSA65 { /// This representation is 64 bytes long, and contains the seed and a hash of the public key. public var integrityCheckedRepresentation: Data { get { - return self.impl.integrityCheckedRepresentation + self.impl.integrityCheckedRepresentation } } @@ -198,7 +204,6 @@ extension MLDSA65 { } } - /// The MLDSA87 Digital Signature Algorithm @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) public enum MLDSA87: Sendable {} @@ -224,7 +229,11 @@ extension MLDSA87 { /// - data: The signed data. /// - context: Context for the signature. /// - Returns: `true` if the signature is valid in the specified context, `false` otherwise. - public func isValidSignature(signature: S, for data: D, context: C) -> Bool { + public func isValidSignature( + signature: S, + for data: D, + context: C + ) -> Bool { self.impl.isValidSignature(signature: signature, for: data, context: context) } @@ -255,7 +264,8 @@ extension MLDSA87 { /// /// - Returns: The prehashed message representative (a.k.a. "external mu"). package func prehash_boring(for data: D) throws -> Data { - let implementation = self.impl is OpenSSLMLDSAPublicKeyImpl + let implementation = + self.impl is OpenSSLMLDSAPublicKeyImpl ? self.impl : try OpenSSLMLDSAPublicKeyImpl(rawRepresentation: self.rawRepresentation) return try implementation.prehash_boring(for: data) @@ -269,7 +279,8 @@ extension MLDSA87 { /// /// - Returns: The prehashed message representative (a.k.a. "external mu"). package func prehash_boring(for data: D, context: C) throws -> Data { - let implementation = self.impl is OpenSSLMLDSAPublicKeyImpl + let implementation = + self.impl is OpenSSLMLDSAPublicKeyImpl ? self.impl : try OpenSSLMLDSAPublicKeyImpl(rawRepresentation: self.rawRepresentation) return try implementation.prehash_boring(for: data, context: context) @@ -307,7 +318,8 @@ extension MLDSA87 { /// /// - Returns: The signature of the prehashed message representative. package func signature_boring(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { - let implementation = self.impl is OpenSSLMLDSAPrivateKeyImpl + let implementation = + self.impl is OpenSSLMLDSAPrivateKeyImpl ? self.impl : try OpenSSLMLDSAPrivateKeyImpl(seedRepresentation: self.seedRepresentation, publicKey: nil) return try implementation.signature_boring(forPrehashedMessageRepresentative: mu) @@ -343,7 +355,7 @@ extension MLDSA87 { /// for the `ML-DSA.KeyGen_internal` algorithm (Algorithm 16) of FIPS 204. public var seedRepresentation: Data { get { - return self.impl.seedRepresentation + self.impl.seedRepresentation } } @@ -360,7 +372,7 @@ extension MLDSA87 { /// This representation is 64 bytes long, and contains the seed and a hash of the public key. public var integrityCheckedRepresentation: Data { get { - return self.impl.integrityCheckedRepresentation + self.impl.integrityCheckedRepresentation } } @@ -370,5 +382,4 @@ extension MLDSA87 { } } - -#endif // Linux or !SwiftPM +#endif // Linux or !SwiftPM diff --git a/Sources/Crypto/Signatures/MLDSA.swift.gyb b/Sources/Crypto/Signatures/MLDSA.swift.gyb index 3d136b541..0c8707ec1 100644 --- a/Sources/Crypto/Signatures/MLDSA.swift.gyb +++ b/Sources/Crypto/Signatures/MLDSA.swift.gyb @@ -34,7 +34,6 @@ typealias MLDSAPrivateKeyImpl = OpenSSLMLDSAPrivateKeyImpl NAME = MLDSA_VARIANT["name"] INFO = MLDSA_VARIANT["ccinfo"] }% - /// The ${NAME} Digital Signature Algorithm @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) public enum ${NAME}: Sendable {} @@ -60,7 +59,11 @@ extension ${NAME} { /// - data: The signed data. /// - context: Context for the signature. /// - Returns: `true` if the signature is valid in the specified context, `false` otherwise. - public func isValidSignature(signature: S, for data: D, context: C) -> Bool { + public func isValidSignature( + signature: S, + for data: D, + context: C + ) -> Bool { self.impl.isValidSignature(signature: signature, for: data, context: context) } @@ -91,7 +94,8 @@ extension ${NAME} { /// /// - Returns: The prehashed message representative (a.k.a. "external mu"). package func prehash_boring(for data: D) throws -> Data { - let implementation = self.impl is OpenSSLMLDSAPublicKeyImpl<${NAME}> + let implementation = + self.impl is OpenSSLMLDSAPublicKeyImpl<${NAME}> ? self.impl : try OpenSSLMLDSAPublicKeyImpl<${NAME}>(rawRepresentation: self.rawRepresentation) return try implementation.prehash_boring(for: data) @@ -105,7 +109,8 @@ extension ${NAME} { /// /// - Returns: The prehashed message representative (a.k.a. "external mu"). package func prehash_boring(for data: D, context: C) throws -> Data { - let implementation = self.impl is OpenSSLMLDSAPublicKeyImpl<${NAME}> + let implementation = + self.impl is OpenSSLMLDSAPublicKeyImpl<${NAME}> ? self.impl : try OpenSSLMLDSAPublicKeyImpl<${NAME}>(rawRepresentation: self.rawRepresentation) return try implementation.prehash_boring(for: data, context: context) @@ -143,7 +148,8 @@ extension ${NAME} { /// /// - Returns: The signature of the prehashed message representative. package func signature_boring(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { - let implementation = self.impl is OpenSSLMLDSAPrivateKeyImpl<${NAME}> + let implementation = + self.impl is OpenSSLMLDSAPrivateKeyImpl<${NAME}> ? self.impl : try OpenSSLMLDSAPrivateKeyImpl<${NAME}>(seedRepresentation: self.seedRepresentation, publicKey: nil) return try implementation.signature_boring(forPrehashedMessageRepresentative: mu) @@ -179,7 +185,7 @@ extension ${NAME} { /// for the `ML-DSA.KeyGen_internal` algorithm (Algorithm 16) of FIPS 204. public var seedRepresentation: Data { get { - return self.impl.seedRepresentation + self.impl.seedRepresentation } } @@ -196,7 +202,7 @@ extension ${NAME} { /// This representation is 64 bytes long, and contains the seed and a hash of the public key. public var integrityCheckedRepresentation: Data { get { - return self.impl.integrityCheckedRepresentation + self.impl.integrityCheckedRepresentation } } @@ -207,5 +213,4 @@ extension ${NAME} { } % end - -#endif // Linux or !SwiftPM +#endif // Linux or !SwiftPM From fdb09e23ce8772d72021935d7398a62dc47adb8f Mon Sep 17 00:00:00 2001 From: Francesco Paolo Severino Date: Mon, 16 Jun 2025 20:45:56 +0200 Subject: [PATCH 11/47] Use computed variable to get BoringSSL implementation --- Sources/Crypto/Signatures/MLDSA.swift | 74 ++++++++++++++--------- Sources/Crypto/Signatures/MLDSA.swift.gyb | 37 +++++++----- 2 files changed, 66 insertions(+), 45 deletions(-) diff --git a/Sources/Crypto/Signatures/MLDSA.swift b/Sources/Crypto/Signatures/MLDSA.swift index a88ff05ce..adaa6aa91 100644 --- a/Sources/Crypto/Signatures/MLDSA.swift +++ b/Sources/Crypto/Signatures/MLDSA.swift @@ -86,11 +86,7 @@ extension MLDSA65 { /// /// - Returns: The prehashed message representative (a.k.a. "external mu"). package func prehash_boring(for data: D) throws -> Data { - let implementation = - self.impl is OpenSSLMLDSAPublicKeyImpl - ? self.impl - : try OpenSSLMLDSAPublicKeyImpl(rawRepresentation: self.rawRepresentation) - return try implementation.prehash_boring(for: data) + try self.boringSSLKey.prehash_boring(for: data) } /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. @@ -101,11 +97,15 @@ extension MLDSA65 { /// /// - Returns: The prehashed message representative (a.k.a. "external mu"). package func prehash_boring(for data: D, context: C) throws -> Data { - let implementation = + try self.boringSSLKey.prehash_boring(for: data, context: context) + } + + private var boringSSLKey: OpenSSLMLDSAPublicKeyImpl { + get throws { self.impl is OpenSSLMLDSAPublicKeyImpl - ? self.impl - : try OpenSSLMLDSAPublicKeyImpl(rawRepresentation: self.rawRepresentation) - return try implementation.prehash_boring(for: data, context: context) + ? self.impl + : try OpenSSLMLDSAPublicKeyImpl(rawRepresentation: self.rawRepresentation) + } } } @@ -140,11 +140,7 @@ extension MLDSA65 { /// /// - Returns: The signature of the prehashed message representative. package func signature_boring(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { - let implementation = - self.impl is OpenSSLMLDSAPrivateKeyImpl - ? self.impl - : try OpenSSLMLDSAPrivateKeyImpl(seedRepresentation: self.seedRepresentation, publicKey: nil) - return try implementation.signature_boring(forPrehashedMessageRepresentative: mu) + try self.boringSSLKey.signature_boring(forPrehashedMessageRepresentative: mu) } /// The associated public key. @@ -198,9 +194,20 @@ extension MLDSA65 { } } - fileprivate init(impl: MLDSAPrivateKeyImpl) { + private init(impl: MLDSAPrivateKeyImpl) { self.impl = impl } + + private var boringSSLKey: OpenSSLMLDSAPrivateKeyImpl { + get throws { + self.impl is OpenSSLMLDSAPrivateKeyImpl + ? self.impl + : try OpenSSLMLDSAPrivateKeyImpl( + seedRepresentation: self.seedRepresentation, + publicKey: nil + ) + } + } } } @@ -264,11 +271,7 @@ extension MLDSA87 { /// /// - Returns: The prehashed message representative (a.k.a. "external mu"). package func prehash_boring(for data: D) throws -> Data { - let implementation = - self.impl is OpenSSLMLDSAPublicKeyImpl - ? self.impl - : try OpenSSLMLDSAPublicKeyImpl(rawRepresentation: self.rawRepresentation) - return try implementation.prehash_boring(for: data) + try self.boringSSLKey.prehash_boring(for: data) } /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. @@ -279,11 +282,15 @@ extension MLDSA87 { /// /// - Returns: The prehashed message representative (a.k.a. "external mu"). package func prehash_boring(for data: D, context: C) throws -> Data { - let implementation = + try self.boringSSLKey.prehash_boring(for: data, context: context) + } + + private var boringSSLKey: OpenSSLMLDSAPublicKeyImpl { + get throws { self.impl is OpenSSLMLDSAPublicKeyImpl - ? self.impl - : try OpenSSLMLDSAPublicKeyImpl(rawRepresentation: self.rawRepresentation) - return try implementation.prehash_boring(for: data, context: context) + ? self.impl + : try OpenSSLMLDSAPublicKeyImpl(rawRepresentation: self.rawRepresentation) + } } } @@ -318,11 +325,7 @@ extension MLDSA87 { /// /// - Returns: The signature of the prehashed message representative. package func signature_boring(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { - let implementation = - self.impl is OpenSSLMLDSAPrivateKeyImpl - ? self.impl - : try OpenSSLMLDSAPrivateKeyImpl(seedRepresentation: self.seedRepresentation, publicKey: nil) - return try implementation.signature_boring(forPrehashedMessageRepresentative: mu) + try self.boringSSLKey.signature_boring(forPrehashedMessageRepresentative: mu) } /// The associated public key. @@ -376,9 +379,20 @@ extension MLDSA87 { } } - fileprivate init(impl: MLDSAPrivateKeyImpl) { + private init(impl: MLDSAPrivateKeyImpl) { self.impl = impl } + + private var boringSSLKey: OpenSSLMLDSAPrivateKeyImpl { + get throws { + self.impl is OpenSSLMLDSAPrivateKeyImpl + ? self.impl + : try OpenSSLMLDSAPrivateKeyImpl( + seedRepresentation: self.seedRepresentation, + publicKey: nil + ) + } + } } } diff --git a/Sources/Crypto/Signatures/MLDSA.swift.gyb b/Sources/Crypto/Signatures/MLDSA.swift.gyb index 0c8707ec1..1b220eb29 100644 --- a/Sources/Crypto/Signatures/MLDSA.swift.gyb +++ b/Sources/Crypto/Signatures/MLDSA.swift.gyb @@ -94,11 +94,7 @@ extension ${NAME} { /// /// - Returns: The prehashed message representative (a.k.a. "external mu"). package func prehash_boring(for data: D) throws -> Data { - let implementation = - self.impl is OpenSSLMLDSAPublicKeyImpl<${NAME}> - ? self.impl - : try OpenSSLMLDSAPublicKeyImpl<${NAME}>(rawRepresentation: self.rawRepresentation) - return try implementation.prehash_boring(for: data) + try self.boringSSLKey.prehash_boring(for: data) } /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. @@ -109,11 +105,15 @@ extension ${NAME} { /// /// - Returns: The prehashed message representative (a.k.a. "external mu"). package func prehash_boring(for data: D, context: C) throws -> Data { - let implementation = + try self.boringSSLKey.prehash_boring(for: data, context: context) + } + + private var boringSSLKey: OpenSSLMLDSAPublicKeyImpl<${NAME}> { + get throws { self.impl is OpenSSLMLDSAPublicKeyImpl<${NAME}> - ? self.impl - : try OpenSSLMLDSAPublicKeyImpl<${NAME}>(rawRepresentation: self.rawRepresentation) - return try implementation.prehash_boring(for: data, context: context) + ? self.impl + : try OpenSSLMLDSAPublicKeyImpl<${NAME}>(rawRepresentation: self.rawRepresentation) + } } } @@ -148,11 +148,7 @@ extension ${NAME} { /// /// - Returns: The signature of the prehashed message representative. package func signature_boring(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { - let implementation = - self.impl is OpenSSLMLDSAPrivateKeyImpl<${NAME}> - ? self.impl - : try OpenSSLMLDSAPrivateKeyImpl<${NAME}>(seedRepresentation: self.seedRepresentation, publicKey: nil) - return try implementation.signature_boring(forPrehashedMessageRepresentative: mu) + try self.boringSSLKey.signature_boring(forPrehashedMessageRepresentative: mu) } /// The associated public key. @@ -206,9 +202,20 @@ extension ${NAME} { } } - fileprivate init(impl: MLDSAPrivateKeyImpl<${NAME}>) { + private init(impl: MLDSAPrivateKeyImpl<${NAME}>) { self.impl = impl } + + private var boringSSLKey: OpenSSLMLDSAPrivateKeyImpl<${NAME}> { + get throws { + self.impl is OpenSSLMLDSAPrivateKeyImpl<${NAME}> + ? self.impl + : try OpenSSLMLDSAPrivateKeyImpl<${NAME}>( + seedRepresentation: self.seedRepresentation, + publicKey: nil + ) + } + } } } From f8bb7ef5cfbb4e5fa14bc276ae8cb9bf94e84eaa Mon Sep 17 00:00:00 2001 From: Francesco Paolo Severino Date: Mon, 16 Jun 2025 23:30:15 +0200 Subject: [PATCH 12/47] Add `@testable` back in tests --- Tests/_CryptoExtrasTests/MLDSATests.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/_CryptoExtrasTests/MLDSATests.swift b/Tests/_CryptoExtrasTests/MLDSATests.swift index b1e518595..1e9892bb5 100644 --- a/Tests/_CryptoExtrasTests/MLDSATests.swift +++ b/Tests/_CryptoExtrasTests/MLDSATests.swift @@ -14,7 +14,7 @@ import XCTest -import _CryptoExtras +@testable import _CryptoExtras #if !canImport(Darwin) || canImport(CryptoKit, _version: 324.0.4) final class MLDSATests: XCTestCase { From 8f0671989dadfb4a813c051e62c9a2af9351a707 Mon Sep 17 00:00:00 2001 From: Francesco Paolo Severino Date: Mon, 16 Jun 2025 23:41:07 +0200 Subject: [PATCH 13/47] Make the linter happy --- Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift | 4 ++-- Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb | 2 +- Tests/_CryptoExtrasTests/MLDSATests.swift | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift b/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift index 9f1c4ad90..2566d37a4 100644 --- a/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift +++ b/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift @@ -41,7 +41,7 @@ extension MLDSA65.PublicKey { /// /// - Returns: The prehashed message representative (a.k.a. "external mu"). public func prehash(for data: D) throws -> Data { - return try self.prehash_boring(for: data) + try self.prehash_boring(for: data) } /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. @@ -78,7 +78,7 @@ extension MLDSA87.PublicKey { /// /// - Returns: The prehashed message representative (a.k.a. "external mu"). public func prehash(for data: D) throws -> Data { - return try self.prehash_boring(for: data) + try self.prehash_boring(for: data) } /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. diff --git a/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb b/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb index 01103c26c..0edb300af 100644 --- a/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb +++ b/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb @@ -45,7 +45,7 @@ extension MLDSA${parameter_set}.PublicKey { /// /// - Returns: The prehashed message representative (a.k.a. "external mu"). public func prehash(for data: D) throws -> Data { - return try self.prehash_boring(for: data) + try self.prehash_boring(for: data) } /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. diff --git a/Tests/_CryptoExtrasTests/MLDSATests.swift b/Tests/_CryptoExtrasTests/MLDSATests.swift index 1e9892bb5..a30362c6d 100644 --- a/Tests/_CryptoExtrasTests/MLDSATests.swift +++ b/Tests/_CryptoExtrasTests/MLDSATests.swift @@ -383,4 +383,4 @@ final class MLDSAExternalMuTests: XCTestCase { let muSignature = try key.signature(forPrehashedMessageRepresentative: mu) XCTAssertTrue(publicKey.isValidSignature(signature: muSignature, for: message, context: context)) } -} \ No newline at end of file +} From 67074c0bf452d34d756c1b6cc906aa87bf7bca80 Mon Sep 17 00:00:00 2001 From: Francesco Paolo Severino Date: Tue, 17 Jun 2025 12:03:42 +0200 Subject: [PATCH 14/47] Update CMakeLists and use FoundationEssentials --- Sources/_CryptoExtras/CMakeLists.txt | 1 + Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift | 4 ++++ Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb | 4 ++++ 3 files changed, 9 insertions(+) diff --git a/Sources/_CryptoExtras/CMakeLists.txt b/Sources/_CryptoExtras/CMakeLists.txt index 2ddd0cbe7..2febaf829 100644 --- a/Sources/_CryptoExtras/CMakeLists.txt +++ b/Sources/_CryptoExtras/CMakeLists.txt @@ -41,6 +41,7 @@ add_library(_CryptoExtras "Key Derivation/PBKDF2/PBKDF2.swift" "Key Derivation/Scrypt/BoringSSL/Scrypt_boring.swift" "Key Derivation/Scrypt/Scrypt.swift" + "MLDSA/MLDSA+externalMu.swift" "OPRFs/OPRF.swift" "OPRFs/OPRFClient.swift" "OPRFs/OPRFServer.swift" diff --git a/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift b/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift index 2566d37a4..76ef02ee7 100644 --- a/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift +++ b/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift @@ -17,7 +17,11 @@ // see section `gyb` in `README` for details. import Crypto +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif @available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) extension MLDSA65.PrivateKey { diff --git a/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb b/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb index 0edb300af..899df5063 100644 --- a/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb +++ b/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb @@ -17,7 +17,11 @@ // see section `gyb` in `README` for details. import Crypto +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif %{ parameter_sets = ["65", "87"] }% From 83a1500dacf84383893ab7df252bea2b48cd2e36 Mon Sep 17 00:00:00 2001 From: Cory Benfield Date: Wed, 18 Jun 2025 15:59:27 +0100 Subject: [PATCH 15/47] Replace all Foundation imports with FoundationEssentials (#363) ### Motivation: FoundationEssentials produces smaller binaries on most platforms. ### Modifications: Where FoundationEssentials is available, import that. ### Result: Improved binary size --- Benchmarks/Benchmarks/Benchmarks.swift | 7 ++++++- Sources/Crypto/AEADs/AES/GCM/AES-GCM.swift | 4 ++++ .../AES/GCM/BoringSSL/AES-GCM_boring.swift | 4 ++++ .../BoringSSL/ChaChaPoly_boring.swift | 4 ++++ .../Crypto/AEADs/ChachaPoly/ChaChaPoly.swift | 4 ++++ Sources/Crypto/AEADs/Cipher.swift | 4 ++++ Sources/Crypto/AEADs/Nonces.swift | 4 ++++ Sources/Crypto/AEADs/Nonces.swift.gyb | 4 ++++ Sources/Crypto/ASN1/ASN1.swift | 4 ++++ .../Crypto/ASN1/Basic ASN1 Types/ASN1Any.swift | 4 ++++ .../ASN1/Basic ASN1 Types/ASN1BitString.swift | 4 ++++ .../ASN1/Basic ASN1 Types/ASN1Boolean.swift | 4 ++++ .../ASN1/Basic ASN1 Types/ASN1Identifier.swift | 4 ++++ .../ASN1/Basic ASN1 Types/ASN1Integer.swift | 4 ++++ .../ASN1/Basic ASN1 Types/ASN1Null.swift | 4 ++++ .../Basic ASN1 Types/ASN1OctetString.swift | 4 ++++ .../ASN1/Basic ASN1 Types/ASN1Strings.swift | 4 ++++ .../Basic ASN1 Types/ArraySliceBigint.swift | 4 ++++ .../Basic ASN1 Types/GeneralizedTime.swift | 4 ++++ .../Basic ASN1 Types/ObjectIdentifier.swift | 4 ++++ Sources/Crypto/ASN1/ECDSASignature.swift | 4 ++++ Sources/Crypto/ASN1/PEMDocument.swift | 4 ++++ Sources/Crypto/ASN1/PKCS8PrivateKey.swift | 4 ++++ Sources/Crypto/ASN1/SEC1PrivateKey.swift | 4 ++++ Sources/Crypto/ASN1/SubjectPublicKeyInfo.swift | 4 ++++ Sources/Crypto/Digests/Digest.swift | 4 ++++ Sources/Crypto/Digests/HashFunctions.swift | 4 ++++ .../Crypto/HPKE/Ciphersuite/HPKE-AEAD.swift | 4 ++++ .../HPKE/Ciphersuite/HPKE-Ciphersuite.swift | 4 ++++ Sources/Crypto/HPKE/Ciphersuite/HPKE-KDF.swift | 4 ++++ .../Ciphersuite/HPKE-KexKeyDerivation.swift | 4 ++++ .../HPKE/Ciphersuite/HPKE-LabeledExtract.swift | 4 ++++ .../Crypto/HPKE/Ciphersuite/HPKE-Utils.swift | 17 +++++++++++++++++ .../Ciphersuite/KEM/Conformances/DHKEM.swift | 4 ++++ .../KEM/Conformances/HPKE-KEM-Curve25519.swift | 4 ++++ .../KEM/Conformances/HPKE-NIST-EC-KEMs.swift | 4 ++++ .../Crypto/HPKE/Ciphersuite/KEM/HPKE-KEM.swift | 4 ++++ Sources/Crypto/HPKE/HPKE-Errors.swift | 4 ++++ Sources/Crypto/HPKE/HPKE.swift | 4 ++++ .../HPKE/Key Schedule/HPKE-Context.swift | 4 ++++ .../HPKE/Key Schedule/HPKE-KeySchedule.swift | 4 ++++ .../Crypto/KEM/BoringSSL/MLKEM_boring.swift | 4 ++++ .../KEM/BoringSSL/MLKEM_boring.swift.gyb | 4 ++++ .../Crypto/KEM/BoringSSL/MLKEM_wrapper.swift | 4 ++++ .../Crypto/KEM/BoringSSL/XWing_boring.swift | 4 ++++ Sources/Crypto/KEM/KEM-Errors.swift | 4 ++++ Sources/Crypto/KEM/KEM.swift | 4 ++++ Sources/Crypto/KEM/MLKEM.swift | 4 ++++ Sources/Crypto/KEM/MLKEM.swift.gyb | 4 ++++ Sources/Crypto/KEM/XWing.swift | 8 ++++++++ Sources/Crypto/Key Agreement/DH.swift | 4 ++++ Sources/Crypto/Key Agreement/ECDH.swift | 4 ++++ Sources/Crypto/Key Agreement/ECDH.swift.gyb | 4 ++++ Sources/Crypto/Key Derivation/ANSIx963.swift | 4 ++++ Sources/Crypto/Key Derivation/HKDF.swift | 4 ++++ Sources/Crypto/Key Wrapping/AESWrap.swift | 4 ++++ .../BoringSSL/AESWrap_boring.swift | 4 ++++ .../Keys/EC/BoringSSL/Ed25519_boring.swift | 4 ++++ .../EC/BoringSSL/NISTCurvesKeys_boring.swift | 4 ++++ .../Keys/EC/BoringSSL/X25519Keys_boring.swift | 4 ++++ Sources/Crypto/Keys/EC/Ed25519Keys.swift | 4 ++++ Sources/Crypto/Keys/EC/NISTCurvesKeys.swift | 4 ++++ Sources/Crypto/Keys/EC/X25519Keys.swift | 4 ++++ .../Crypto/Keys/Symmetric/SymmetricKeys.swift | 4 ++++ .../HMAC/HMAC.swift | 17 +++++++++++++++++ .../MACFunctions.swift | 4 ++++ .../MessageAuthenticationCode.swift | 4 ++++ .../BoringSSL/ECDSASignature_boring.swift | 4 ++++ .../Signatures/BoringSSL/ECDSA_boring.swift | 4 ++++ .../Signatures/BoringSSL/EdDSA_boring.swift | 4 ++++ .../Signatures/BoringSSL/MLDSA_boring.swift | 8 ++++++++ .../BoringSSL/MLDSA_boring.swift.gyb | 8 ++++++++ .../Signatures/BoringSSL/MLDSA_wrapper.swift | 4 ++++ Sources/Crypto/Signatures/ECDSA.swift | 4 ++++ Sources/Crypto/Signatures/ECDSA.swift.gyb | 4 ++++ Sources/Crypto/Signatures/Ed25519.swift | 4 ++++ Sources/Crypto/Signatures/MLDSA.swift | 4 ++++ Sources/Crypto/Signatures/MLDSA.swift.gyb | 4 ++++ Sources/Crypto/Signatures/Signature.swift | 4 ++++ .../Optional+withUnsafeBytes_boring.swift | 4 ++++ .../Util/BoringSSL/SafeCompare_boring.swift | 4 ++++ Sources/Crypto/Util/PrettyBytes.swift | 4 ++++ Sources/Crypto/Util/SafeCompare.swift | 4 ++++ Sources/Crypto/Util/SecureBytes.swift | 4 ++++ Sources/Crypto/Util/Zeroization.swift | 4 ++++ .../AEAD/BoringSSLAEAD.swift | 5 +++++ .../Util/ArbitraryPrecisionInteger.swift | 4 ++++ .../Util/FiniteFieldArithmeticContext.swift | 4 ++++ Sources/_CryptoExtras/AES/AES_CBC.swift | 4 ++++ Sources/_CryptoExtras/AES/AES_CFB.swift | 4 ++++ Sources/_CryptoExtras/AES/AES_CTR.swift | 4 ++++ Sources/_CryptoExtras/AES/AES_GCM_SIV.swift | 4 ++++ Sources/_CryptoExtras/AES/Block Function.swift | 4 ++++ .../AES/BoringSSL/AES_CFB_boring.swift | 5 +++++ .../AES/BoringSSL/AES_CTR_boring.swift | 5 +++++ .../AES/BoringSSL/AES_GCM_SIV_boring.swift | 5 +++++ Sources/_CryptoExtras/ARC/ARC+API.swift | 4 ++++ Sources/_CryptoExtras/ARC/ARC.swift | 4 ++++ Sources/_CryptoExtras/ARC/ARCCredential.swift | 4 ++++ Sources/_CryptoExtras/ARC/ARCEncoding.swift | 4 ++++ .../_CryptoExtras/ARC/ARCPrecredential.swift | 4 ++++ .../_CryptoExtras/ARC/ARCPresentation.swift | 4 ++++ Sources/_CryptoExtras/ARC/ARCRequest.swift | 4 ++++ Sources/_CryptoExtras/ARC/ARCResponse.swift | 4 ++++ Sources/_CryptoExtras/ARC/ARCServer.swift | 4 ++++ .../BoringSSL/ChaCha20CTR_boring.swift | 5 +++++ .../ChaCha20CTR/ChaCha20CTR.swift | 4 ++++ .../ECToolbox/BoringSSL/ECToolbox_boring.swift | 5 +++++ .../_CryptoExtras/ECToolbox/ECToolbox.swift | 4 ++++ Sources/_CryptoExtras/H2G/HashToField.swift | 17 +++++++++++++++++ Sources/_CryptoExtras/Key Derivation/KDF.swift | 4 ++++ .../PBKDF2/BoringSSL/PBKDF2_boring.swift | 5 +++++ .../PBKDF2/BoringSSL/PBKDF2_commoncrypto.swift | 5 +++++ .../Key Derivation/PBKDF2/PBKDF2.swift | 4 ++++ .../Scrypt/BoringSSL/Scrypt_boring.swift | 18 ++++++++++++++++++ .../Key Derivation/Scrypt/Scrypt.swift | 4 ++++ Sources/_CryptoExtras/OPRFs/OPRF.swift | 4 ++++ Sources/_CryptoExtras/OPRFs/OPRFClient.swift | 4 ++++ Sources/_CryptoExtras/OPRFs/OPRFServer.swift | 4 ++++ Sources/_CryptoExtras/OPRFs/VOPRF+API.swift | 4 ++++ Sources/_CryptoExtras/OPRFs/VOPRFClient.swift | 4 ++++ Sources/_CryptoExtras/OPRFs/VOPRFServer.swift | 4 ++++ .../_CryptoExtras/RSA/RSA+BlindSigning.swift | 4 ++++ Sources/_CryptoExtras/RSA/RSA.swift | 4 ++++ Sources/_CryptoExtras/RSA/RSA_boring.swift | 18 ++++++++++++++++++ Sources/_CryptoExtras/RSA/RSA_security.swift | 4 ++++ .../_CryptoExtras/Util/BoringSSLHelpers.swift | 4 ++++ .../_CryptoExtras/Util/Data+Extensions.swift | 4 ++++ Sources/_CryptoExtras/Util/I2OSP.swift | 17 +++++++++++++++++ .../_CryptoExtras/Util/IntegerEncoding.swift | 4 ++++ Sources/_CryptoExtras/Util/PEMDocument.swift | 4 ++++ Sources/_CryptoExtras/Util/PrettyBytes.swift | 4 ++++ Sources/_CryptoExtras/ZKPs/DLEQ.swift | 4 ++++ Sources/_CryptoExtras/ZKPs/Prover.swift | 4 ++++ Sources/_CryptoExtras/ZKPs/Verifier.swift | 4 ++++ Sources/_CryptoExtras/ZKPs/ZKPToolbox.swift | 4 ++++ .../AES-GCM-Runner.swift | 4 ++++ .../ChaChaPoly-Runner.swift | 4 ++++ Tests/CryptoTests/ECDH/BoringSSL/ASN1.swift | 7 ++++++- .../BoringSSL/secpECDH_Runner_boring.swift | 7 ++++++- Tests/CryptoTests/ECDH/X25519-Runner.swift | 4 ++++ Tests/CryptoTests/ECDH/secpECDH_Runner.swift | 4 ++++ .../HPKE/HPKETests-TestVectors.swift | 4 ++++ Tests/CryptoTests/HPKE/HPKETests.swift | 4 ++++ .../ECprivateKeysFromSeeds.swift | 4 ++++ .../Signatures/ECDSA/ECDSASignatureTests.swift | 4 ++++ Tests/CryptoTests/Utils/Boring/CTRDRBG.swift | 4 ++++ .../Utils/Boring/SequenceDRBG.swift | 4 ++++ Tests/CryptoTests/Utils/PrettyBytes.swift | 4 ++++ Tests/CryptoTests/Utils/SplitData.swift | 4 ++++ .../AES Block Function Tests.swift | 4 ++++ .../AES-GCM-SIV-Runner.swift | 4 ++++ Tests/_CryptoExtrasTests/AES_CBCTests.swift | 4 ++++ Tests/_CryptoExtrasTests/AES_CTRTests.swift | 4 ++++ .../_CryptoExtrasTests/ChaCha20CTRTests.swift | 4 ++++ .../_CryptoExtrasTests/TestRSAEncryption.swift | 4 ++++ Tests/_CryptoExtrasTests/TestRSASigning.swift | 4 ++++ Tests/_CryptoExtrasTests/Utils/BytesUtil.swift | 4 ++++ Tests/_CryptoExtrasTests/Utils/SplitData.swift | 4 ++++ 159 files changed, 742 insertions(+), 3 deletions(-) diff --git a/Benchmarks/Benchmarks/Benchmarks.swift b/Benchmarks/Benchmarks/Benchmarks.swift index 64626f573..5836678c1 100644 --- a/Benchmarks/Benchmarks/Benchmarks.swift +++ b/Benchmarks/Benchmarks/Benchmarks.swift @@ -13,9 +13,14 @@ //===----------------------------------------------------------------------===// import Benchmark import Crypto -import Foundation import _CryptoExtras +#if canImport(FoundationEssentials) +import FoundationEssentials +#else +import Foundation +#endif + let benchmarks = { let defaultMetrics: [BenchmarkMetric] = [.mallocCountTotal, .cpuTotal] diff --git a/Sources/Crypto/AEADs/AES/GCM/AES-GCM.swift b/Sources/Crypto/AEADs/AES/GCM/AES-GCM.swift index 1ba3ca8ad..df016ce60 100644 --- a/Sources/Crypto/AEADs/AES/GCM/AES-GCM.swift +++ b/Sources/Crypto/AEADs/AES/GCM/AES-GCM.swift @@ -25,8 +25,12 @@ typealias AESGCMImpl = OpenSSLAESGCMImpl #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION public import SwiftSystem #else +#if canImport(FoundationEssentials) +public import FoundationEssentials +#else public import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension AES { diff --git a/Sources/Crypto/AEADs/AES/GCM/BoringSSL/AES-GCM_boring.swift b/Sources/Crypto/AEADs/AES/GCM/BoringSSL/AES-GCM_boring.swift index 666442b0c..33ae0ca0e 100644 --- a/Sources/Crypto/AEADs/AES/GCM/BoringSSL/AES-GCM_boring.swift +++ b/Sources/Crypto/AEADs/AES/GCM/BoringSSL/AES-GCM_boring.swift @@ -16,7 +16,11 @@ #else @_implementationOnly import CCryptoBoringSSL import CryptoBoringWrapper +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) enum OpenSSLAESGCMImpl { diff --git a/Sources/Crypto/AEADs/ChachaPoly/BoringSSL/ChaChaPoly_boring.swift b/Sources/Crypto/AEADs/ChachaPoly/BoringSSL/ChaChaPoly_boring.swift index 0d3933965..349cd99aa 100644 --- a/Sources/Crypto/AEADs/ChachaPoly/BoringSSL/ChaChaPoly_boring.swift +++ b/Sources/Crypto/AEADs/ChachaPoly/BoringSSL/ChaChaPoly_boring.swift @@ -17,7 +17,11 @@ @_implementationOnly import CCryptoBoringSSL @_implementationOnly import CCryptoBoringSSLShims import CryptoBoringWrapper +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension BoringSSLAEAD { diff --git a/Sources/Crypto/AEADs/ChachaPoly/ChaChaPoly.swift b/Sources/Crypto/AEADs/ChachaPoly/ChaChaPoly.swift index 223cb521b..e242c5ff1 100644 --- a/Sources/Crypto/AEADs/ChachaPoly/ChaChaPoly.swift +++ b/Sources/Crypto/AEADs/ChachaPoly/ChaChaPoly.swift @@ -25,8 +25,12 @@ typealias ChaChaPolyImpl = OpenSSLChaChaPolyImpl #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION public import SwiftSystem #else +#if canImport(FoundationEssentials) +public import FoundationEssentials +#else public import Foundation #endif +#endif /// An implementation of the ChaCha20-Poly1305 cipher. diff --git a/Sources/Crypto/AEADs/Cipher.swift b/Sources/Crypto/AEADs/Cipher.swift index 8ac46f1e7..2e7dc81eb 100644 --- a/Sources/Crypto/AEADs/Cipher.swift +++ b/Sources/Crypto/AEADs/Cipher.swift @@ -18,8 +18,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) diff --git a/Sources/Crypto/AEADs/Nonces.swift b/Sources/Crypto/AEADs/Nonces.swift index 7310294a3..a9f17c75b 100644 --- a/Sources/Crypto/AEADs/Nonces.swift +++ b/Sources/Crypto/AEADs/Nonces.swift @@ -17,8 +17,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION public import SwiftSystem #else +#if canImport(FoundationEssentials) +public import FoundationEssentials +#else public import Foundation #endif +#endif // MARK: - Generated file, do NOT edit // any edits of this file WILL be overwritten and thus discarded // see section `gyb` in `README` for details. diff --git a/Sources/Crypto/AEADs/Nonces.swift.gyb b/Sources/Crypto/AEADs/Nonces.swift.gyb index 9b05da21d..83f6c594e 100644 --- a/Sources/Crypto/AEADs/Nonces.swift.gyb +++ b/Sources/Crypto/AEADs/Nonces.swift.gyb @@ -17,8 +17,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION public import SwiftSystem #else +#if canImport(FoundationEssentials) +public import FoundationEssentials +#else public import Foundation #endif +#endif // MARK: - Generated file, do NOT edit // any edits of this file WILL be overwritten and thus discarded // see section `gyb` in `README` for details. diff --git a/Sources/Crypto/ASN1/ASN1.swift b/Sources/Crypto/ASN1/ASN1.swift index fdd17f81a..4cba7ff28 100644 --- a/Sources/Crypto/ASN1/ASN1.swift +++ b/Sources/Crypto/ASN1/ASN1.swift @@ -18,8 +18,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif // This module implements "just enough" ASN.1. Specifically, we implement exactly enough ASN.1 DER parsing to handle // the following use-cases: diff --git a/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Any.swift b/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Any.swift index 575d23d81..ec3a95cbf 100644 --- a/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Any.swift +++ b/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Any.swift @@ -18,8 +18,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1 { diff --git a/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1BitString.swift b/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1BitString.swift index ce43673ca..c5babc680 100644 --- a/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1BitString.swift +++ b/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1BitString.swift @@ -18,8 +18,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1 { diff --git a/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Boolean.swift b/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Boolean.swift index a2c1c3f19..3e4ce4283 100644 --- a/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Boolean.swift +++ b/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Boolean.swift @@ -18,8 +18,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension Bool: ASN1ImplicitlyTaggable { diff --git a/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Identifier.swift b/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Identifier.swift index c47477cb7..54c9f537c 100644 --- a/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Identifier.swift +++ b/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Identifier.swift @@ -18,8 +18,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1 { diff --git a/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Integer.swift b/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Integer.swift index 7026f634e..0238a9ca1 100644 --- a/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Integer.swift +++ b/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Integer.swift @@ -18,8 +18,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif /// A protocol that represents any internal object that can present itself as a INTEGER, or be parsed from /// a INTEGER. diff --git a/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Null.swift b/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Null.swift index 850d81747..eb0caade6 100644 --- a/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Null.swift +++ b/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Null.swift @@ -18,8 +18,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1 { diff --git a/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1OctetString.swift b/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1OctetString.swift index 1b6374a50..ced74024e 100644 --- a/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1OctetString.swift +++ b/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1OctetString.swift @@ -18,8 +18,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1 { diff --git a/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Strings.swift b/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Strings.swift index 794150b53..8fc52ec1a 100644 --- a/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Strings.swift +++ b/Sources/Crypto/ASN1/Basic ASN1 Types/ASN1Strings.swift @@ -18,8 +18,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) private func contents(of string: StaticString) -> ArraySlice { diff --git a/Sources/Crypto/ASN1/Basic ASN1 Types/ArraySliceBigint.swift b/Sources/Crypto/ASN1/Basic ASN1 Types/ArraySliceBigint.swift index 7a00fd1e2..73ba9404b 100644 --- a/Sources/Crypto/ASN1/Basic ASN1 Types/ArraySliceBigint.swift +++ b/Sources/Crypto/ASN1/Basic ASN1 Types/ArraySliceBigint.swift @@ -18,8 +18,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif // For temporary purposes we pretend that ArraySlice is our "bigint" type. We don't really need anything else. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) diff --git a/Sources/Crypto/ASN1/Basic ASN1 Types/GeneralizedTime.swift b/Sources/Crypto/ASN1/Basic ASN1 Types/GeneralizedTime.swift index bec502fd4..95789c70f 100644 --- a/Sources/Crypto/ASN1/Basic ASN1 Types/GeneralizedTime.swift +++ b/Sources/Crypto/ASN1/Basic ASN1 Types/GeneralizedTime.swift @@ -18,8 +18,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1 { diff --git a/Sources/Crypto/ASN1/Basic ASN1 Types/ObjectIdentifier.swift b/Sources/Crypto/ASN1/Basic ASN1 Types/ObjectIdentifier.swift index 2d21798e0..a4283bb29 100644 --- a/Sources/Crypto/ASN1/Basic ASN1 Types/ObjectIdentifier.swift +++ b/Sources/Crypto/ASN1/Basic ASN1 Types/ObjectIdentifier.swift @@ -18,8 +18,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1 { diff --git a/Sources/Crypto/ASN1/ECDSASignature.swift b/Sources/Crypto/ASN1/ECDSASignature.swift index 6029e5a9b..09bfafbae 100644 --- a/Sources/Crypto/ASN1/ECDSASignature.swift +++ b/Sources/Crypto/ASN1/ECDSASignature.swift @@ -18,8 +18,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1 { diff --git a/Sources/Crypto/ASN1/PEMDocument.swift b/Sources/Crypto/ASN1/PEMDocument.swift index 05319a6b3..1cd182c10 100644 --- a/Sources/Crypto/ASN1/PEMDocument.swift +++ b/Sources/Crypto/ASN1/PEMDocument.swift @@ -18,8 +18,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1 { diff --git a/Sources/Crypto/ASN1/PKCS8PrivateKey.swift b/Sources/Crypto/ASN1/PKCS8PrivateKey.swift index 3c3003edf..2b3693d79 100644 --- a/Sources/Crypto/ASN1/PKCS8PrivateKey.swift +++ b/Sources/Crypto/ASN1/PKCS8PrivateKey.swift @@ -17,8 +17,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1 { diff --git a/Sources/Crypto/ASN1/SEC1PrivateKey.swift b/Sources/Crypto/ASN1/SEC1PrivateKey.swift index 86cd7b522..3a299118b 100644 --- a/Sources/Crypto/ASN1/SEC1PrivateKey.swift +++ b/Sources/Crypto/ASN1/SEC1PrivateKey.swift @@ -18,8 +18,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1 { diff --git a/Sources/Crypto/ASN1/SubjectPublicKeyInfo.swift b/Sources/Crypto/ASN1/SubjectPublicKeyInfo.swift index 9e113a104..00f82defc 100644 --- a/Sources/Crypto/ASN1/SubjectPublicKeyInfo.swift +++ b/Sources/Crypto/ASN1/SubjectPublicKeyInfo.swift @@ -18,8 +18,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ASN1 { diff --git a/Sources/Crypto/Digests/Digest.swift b/Sources/Crypto/Digests/Digest.swift index b42e30cd6..a7b5c735c 100644 --- a/Sources/Crypto/Digests/Digest.swift +++ b/Sources/Crypto/Digests/Digest.swift @@ -18,8 +18,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION public import SwiftSystem #else +#if canImport(FoundationEssentials) +public import FoundationEssentials +#else public import Foundation #endif +#endif #if hasFeature(Embedded) /// A type that represents the output of a hash. diff --git a/Sources/Crypto/Digests/HashFunctions.swift b/Sources/Crypto/Digests/HashFunctions.swift index 887296e65..a0c1df748 100644 --- a/Sources/Crypto/Digests/HashFunctions.swift +++ b/Sources/Crypto/Digests/HashFunctions.swift @@ -25,8 +25,12 @@ typealias DigestImpl = OpenSSLDigestImpl #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION public import SwiftSystem #else +#if canImport(FoundationEssentials) +public import FoundationEssentials +#else public import Foundation #endif +#endif /// A type that performs cryptographically secure hashing. /// diff --git a/Sources/Crypto/HPKE/Ciphersuite/HPKE-AEAD.swift b/Sources/Crypto/HPKE/Ciphersuite/HPKE-AEAD.swift index 4a501269b..db00f1b14 100644 --- a/Sources/Crypto/HPKE/Ciphersuite/HPKE-AEAD.swift +++ b/Sources/Crypto/HPKE/Ciphersuite/HPKE-AEAD.swift @@ -18,8 +18,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) diff --git a/Sources/Crypto/HPKE/Ciphersuite/HPKE-Ciphersuite.swift b/Sources/Crypto/HPKE/Ciphersuite/HPKE-Ciphersuite.swift index 5bfa85f53..69fbc0c96 100644 --- a/Sources/Crypto/HPKE/Ciphersuite/HPKE-Ciphersuite.swift +++ b/Sources/Crypto/HPKE/Ciphersuite/HPKE-Ciphersuite.swift @@ -18,8 +18,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) diff --git a/Sources/Crypto/HPKE/Ciphersuite/HPKE-KDF.swift b/Sources/Crypto/HPKE/Ciphersuite/HPKE-KDF.swift index eed03a15d..19f0158f2 100644 --- a/Sources/Crypto/HPKE/Ciphersuite/HPKE-KDF.swift +++ b/Sources/Crypto/HPKE/Ciphersuite/HPKE-KDF.swift @@ -18,8 +18,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension HPKE { diff --git a/Sources/Crypto/HPKE/Ciphersuite/HPKE-KexKeyDerivation.swift b/Sources/Crypto/HPKE/Ciphersuite/HPKE-KexKeyDerivation.swift index f37ba8006..45220fd3d 100644 --- a/Sources/Crypto/HPKE/Ciphersuite/HPKE-KexKeyDerivation.swift +++ b/Sources/Crypto/HPKE/Ciphersuite/HPKE-KexKeyDerivation.swift @@ -18,8 +18,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) diff --git a/Sources/Crypto/HPKE/Ciphersuite/HPKE-LabeledExtract.swift b/Sources/Crypto/HPKE/Ciphersuite/HPKE-LabeledExtract.swift index 8e5d97e60..ba8d4b38c 100644 --- a/Sources/Crypto/HPKE/Ciphersuite/HPKE-LabeledExtract.swift +++ b/Sources/Crypto/HPKE/Ciphersuite/HPKE-LabeledExtract.swift @@ -18,8 +18,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) diff --git a/Sources/Crypto/HPKE/Ciphersuite/HPKE-Utils.swift b/Sources/Crypto/HPKE/Ciphersuite/HPKE-Utils.swift index a84c60d96..e60e6ef72 100644 --- a/Sources/Crypto/HPKE/Ciphersuite/HPKE-Utils.swift +++ b/Sources/Crypto/HPKE/Ciphersuite/HPKE-Utils.swift @@ -18,8 +18,25 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +#if os(Windows) +import ucrt +#elseif canImport(Darwin) +import Darwin +#elseif canImport(Glibc) +import Glibc +#elseif canImport(Musl) +import Musl +#elseif canImport(Android) +import Android +#elseif canImport(WASILibc) +import WASILibc +#endif +import FoundationEssentials +#else import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) diff --git a/Sources/Crypto/HPKE/Ciphersuite/KEM/Conformances/DHKEM.swift b/Sources/Crypto/HPKE/Ciphersuite/KEM/Conformances/DHKEM.swift index 5e06baf88..e6e483aca 100644 --- a/Sources/Crypto/HPKE/Ciphersuite/KEM/Conformances/DHKEM.swift +++ b/Sources/Crypto/HPKE/Ciphersuite/KEM/Conformances/DHKEM.swift @@ -18,8 +18,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +public import FoundationEssentials +#else public import Foundation #endif +#endif /// A type that ``HPKE`` uses to encode the public key. @preconcurrency diff --git a/Sources/Crypto/HPKE/Ciphersuite/KEM/Conformances/HPKE-KEM-Curve25519.swift b/Sources/Crypto/HPKE/Ciphersuite/KEM/Conformances/HPKE-KEM-Curve25519.swift index 59d78feaf..2d707f3a6 100644 --- a/Sources/Crypto/HPKE/Ciphersuite/KEM/Conformances/HPKE-KEM-Curve25519.swift +++ b/Sources/Crypto/HPKE/Ciphersuite/KEM/Conformances/HPKE-KEM-Curve25519.swift @@ -18,8 +18,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION public import SwiftSystem #else +#if canImport(FoundationEssentials) +public import FoundationEssentials +#else public import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) diff --git a/Sources/Crypto/HPKE/Ciphersuite/KEM/Conformances/HPKE-NIST-EC-KEMs.swift b/Sources/Crypto/HPKE/Ciphersuite/KEM/Conformances/HPKE-NIST-EC-KEMs.swift index e7e942b1e..2d20fdadd 100644 --- a/Sources/Crypto/HPKE/Ciphersuite/KEM/Conformances/HPKE-NIST-EC-KEMs.swift +++ b/Sources/Crypto/HPKE/Ciphersuite/KEM/Conformances/HPKE-NIST-EC-KEMs.swift @@ -18,8 +18,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION public import SwiftSystem #else +#if canImport(FoundationEssentials) +public import FoundationEssentials +#else public import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension P256.KeyAgreement.PrivateKey: HPKEDiffieHellmanPrivateKeyGeneration { diff --git a/Sources/Crypto/HPKE/Ciphersuite/KEM/HPKE-KEM.swift b/Sources/Crypto/HPKE/Ciphersuite/KEM/HPKE-KEM.swift index 3a0bbc937..a3e51c75b 100644 --- a/Sources/Crypto/HPKE/Ciphersuite/KEM/HPKE-KEM.swift +++ b/Sources/Crypto/HPKE/Ciphersuite/KEM/HPKE-KEM.swift @@ -17,8 +17,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension HPKE { diff --git a/Sources/Crypto/HPKE/HPKE-Errors.swift b/Sources/Crypto/HPKE/HPKE-Errors.swift index f94306851..677bcfb51 100644 --- a/Sources/Crypto/HPKE/HPKE-Errors.swift +++ b/Sources/Crypto/HPKE/HPKE-Errors.swift @@ -18,8 +18,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension HPKE { diff --git a/Sources/Crypto/HPKE/HPKE.swift b/Sources/Crypto/HPKE/HPKE.swift index 756926988..9a3c3958c 100644 --- a/Sources/Crypto/HPKE/HPKE.swift +++ b/Sources/Crypto/HPKE/HPKE.swift @@ -17,8 +17,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +public import FoundationEssentials +#else public import Foundation #endif +#endif /// A container for hybrid public key encryption (HPKE) operations. /// diff --git a/Sources/Crypto/HPKE/Key Schedule/HPKE-Context.swift b/Sources/Crypto/HPKE/Key Schedule/HPKE-Context.swift index 267688503..41ab963fe 100644 --- a/Sources/Crypto/HPKE/Key Schedule/HPKE-Context.swift +++ b/Sources/Crypto/HPKE/Key Schedule/HPKE-Context.swift @@ -18,8 +18,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension HPKE { diff --git a/Sources/Crypto/HPKE/Key Schedule/HPKE-KeySchedule.swift b/Sources/Crypto/HPKE/Key Schedule/HPKE-KeySchedule.swift index a45a7b40f..1569a88f3 100644 --- a/Sources/Crypto/HPKE/Key Schedule/HPKE-KeySchedule.swift +++ b/Sources/Crypto/HPKE/Key Schedule/HPKE-KeySchedule.swift @@ -18,8 +18,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension HPKE { diff --git a/Sources/Crypto/KEM/BoringSSL/MLKEM_boring.swift b/Sources/Crypto/KEM/BoringSSL/MLKEM_boring.swift index 035478808..ae7690c33 100644 --- a/Sources/Crypto/KEM/BoringSSL/MLKEM_boring.swift +++ b/Sources/Crypto/KEM/BoringSSL/MLKEM_boring.swift @@ -20,7 +20,11 @@ @_exported import CryptoKit #else @_implementationOnly import CCryptoBoringSSL +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLKEM768 { diff --git a/Sources/Crypto/KEM/BoringSSL/MLKEM_boring.swift.gyb b/Sources/Crypto/KEM/BoringSSL/MLKEM_boring.swift.gyb index a4b056e01..979cf314b 100644 --- a/Sources/Crypto/KEM/BoringSSL/MLKEM_boring.swift.gyb +++ b/Sources/Crypto/KEM/BoringSSL/MLKEM_boring.swift.gyb @@ -20,7 +20,11 @@ @_exported import CryptoKit #else @_implementationOnly import CCryptoBoringSSL +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif %{ parameter_sets = ["768", "1024"] }% diff --git a/Sources/Crypto/KEM/BoringSSL/MLKEM_wrapper.swift b/Sources/Crypto/KEM/BoringSSL/MLKEM_wrapper.swift index fbb84921e..9fc83b433 100644 --- a/Sources/Crypto/KEM/BoringSSL/MLKEM_wrapper.swift +++ b/Sources/Crypto/KEM/BoringSSL/MLKEM_wrapper.swift @@ -16,7 +16,11 @@ @_exported import CryptoKit #else @_implementationOnly import CCryptoBoringSSL +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) protocol BoringSSLBackedMLKEMPrivateKey { diff --git a/Sources/Crypto/KEM/BoringSSL/XWing_boring.swift b/Sources/Crypto/KEM/BoringSSL/XWing_boring.swift index 9a6a7f600..6d6aa724b 100644 --- a/Sources/Crypto/KEM/BoringSSL/XWing_boring.swift +++ b/Sources/Crypto/KEM/BoringSSL/XWing_boring.swift @@ -16,7 +16,11 @@ @_exported import CryptoKit #else @_implementationOnly import CCryptoBoringSSL +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) struct OpenSSLXWingPublicKeyImpl: Sendable { diff --git a/Sources/Crypto/KEM/KEM-Errors.swift b/Sources/Crypto/KEM/KEM-Errors.swift index 3d4b79bb8..2f2fdfb33 100644 --- a/Sources/Crypto/KEM/KEM-Errors.swift +++ b/Sources/Crypto/KEM/KEM-Errors.swift @@ -18,8 +18,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension KEM { diff --git a/Sources/Crypto/KEM/KEM.swift b/Sources/Crypto/KEM/KEM.swift index 584e9d69e..9b8466aab 100644 --- a/Sources/Crypto/KEM/KEM.swift +++ b/Sources/Crypto/KEM/KEM.swift @@ -18,8 +18,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION public import SwiftSystem #else +#if canImport(FoundationEssentials) +public import FoundationEssentials +#else public import Foundation #endif +#endif /// A key encapsulation mechanism. /// diff --git a/Sources/Crypto/KEM/MLKEM.swift b/Sources/Crypto/KEM/MLKEM.swift index a93d860c1..3883fbd40 100644 --- a/Sources/Crypto/KEM/MLKEM.swift +++ b/Sources/Crypto/KEM/MLKEM.swift @@ -14,7 +14,11 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else +#if canImport(FoundationEssentials) +public import FoundationEssentials +#else public import Foundation +#endif #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) diff --git a/Sources/Crypto/KEM/MLKEM.swift.gyb b/Sources/Crypto/KEM/MLKEM.swift.gyb index bdc85b20a..3a1719437 100644 --- a/Sources/Crypto/KEM/MLKEM.swift.gyb +++ b/Sources/Crypto/KEM/MLKEM.swift.gyb @@ -14,7 +14,11 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else +#if canImport(FoundationEssentials) +public import FoundationEssentials +#else public import Foundation +#endif %{ MLKEM_VARIANTS = [{"name": "MLKEM768", "ccinfo": "cckem_mlkem768()!"}, {"name": "MLKEM1024", "ccinfo": "cckem_mlkem1024()!"}] }% diff --git a/Sources/Crypto/KEM/XWing.swift b/Sources/Crypto/KEM/XWing.swift index e90c94a18..dad3f5127 100644 --- a/Sources/Crypto/KEM/XWing.swift +++ b/Sources/Crypto/KEM/XWing.swift @@ -14,7 +14,11 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else +#if canImport(FoundationEssentials) +public import FoundationEssentials +#else public import Foundation +#endif #if _runtime(_ObjC) && CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit @@ -23,8 +27,12 @@ public import Foundation #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) diff --git a/Sources/Crypto/Key Agreement/DH.swift b/Sources/Crypto/Key Agreement/DH.swift index 3a299b389..1d7c9a206 100644 --- a/Sources/Crypto/Key Agreement/DH.swift +++ b/Sources/Crypto/Key Agreement/DH.swift @@ -18,8 +18,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION public import SwiftSystem #else +#if canImport(FoundationEssentials) +public import FoundationEssentials +#else public import Foundation #endif +#endif /// A Diffie-Hellman Key Agreement Key @preconcurrency diff --git a/Sources/Crypto/Key Agreement/ECDH.swift b/Sources/Crypto/Key Agreement/ECDH.swift index 041c95c80..243aaee04 100644 --- a/Sources/Crypto/Key Agreement/ECDH.swift +++ b/Sources/Crypto/Key Agreement/ECDH.swift @@ -29,8 +29,12 @@ typealias NISTCurvePrivateKeyImpl = OpenSSLNISTCurvePrivateKeyImpl #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION public import SwiftSystem #else +#if canImport(FoundationEssentials) +public import FoundationEssentials +#else public import Foundation #endif +#endif // MARK: - Generated file, do NOT edit // any edits of this file WILL be overwritten and thus discarded diff --git a/Sources/Crypto/Key Agreement/ECDH.swift.gyb b/Sources/Crypto/Key Agreement/ECDH.swift.gyb index 3976519b3..aa815c92c 100644 --- a/Sources/Crypto/Key Agreement/ECDH.swift.gyb +++ b/Sources/Crypto/Key Agreement/ECDH.swift.gyb @@ -25,8 +25,12 @@ typealias NISTCurvePrivateKeyImpl = OpenSSLNISTCurvePrivateKeyImpl #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION public import SwiftSystem #else +#if canImport(FoundationEssentials) +public import FoundationEssentials +#else public import Foundation #endif +#endif // MARK: - Generated file, do NOT edit // any edits of this file WILL be overwritten and thus discarded diff --git a/Sources/Crypto/Key Derivation/ANSIx963.swift b/Sources/Crypto/Key Derivation/ANSIx963.swift index e222a5680..6c0357d38 100644 --- a/Sources/Crypto/Key Derivation/ANSIx963.swift +++ b/Sources/Crypto/Key Derivation/ANSIx963.swift @@ -18,8 +18,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION public import SwiftSystem #else +#if canImport(FoundationEssentials) +public import FoundationEssentials +#else public import Foundation #endif +#endif @_spi(ANSIKDF) @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) diff --git a/Sources/Crypto/Key Derivation/HKDF.swift b/Sources/Crypto/Key Derivation/HKDF.swift index e3d12d165..8d66b74df 100644 --- a/Sources/Crypto/Key Derivation/HKDF.swift +++ b/Sources/Crypto/Key Derivation/HKDF.swift @@ -18,8 +18,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION public import SwiftSystem #else +#if canImport(FoundationEssentials) +public import FoundationEssentials +#else public import Foundation #endif +#endif /// A standards-based implementation of an HMAC-based Key Derivation Function /// (HKDF). diff --git a/Sources/Crypto/Key Wrapping/AESWrap.swift b/Sources/Crypto/Key Wrapping/AESWrap.swift index 8558dd7e8..69ab68338 100644 --- a/Sources/Crypto/Key Wrapping/AESWrap.swift +++ b/Sources/Crypto/Key Wrapping/AESWrap.swift @@ -18,8 +18,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION public import SwiftSystem #else +#if canImport(FoundationEssentials) +public import FoundationEssentials +#else public import Foundation #endif +#endif #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) diff --git a/Sources/Crypto/Key Wrapping/BoringSSL/AESWrap_boring.swift b/Sources/Crypto/Key Wrapping/BoringSSL/AESWrap_boring.swift index 5eebd15bc..f493b8656 100644 --- a/Sources/Crypto/Key Wrapping/BoringSSL/AESWrap_boring.swift +++ b/Sources/Crypto/Key Wrapping/BoringSSL/AESWrap_boring.swift @@ -15,7 +15,11 @@ @_exported import CryptoKit #else @_implementationOnly import CCryptoBoringSSL +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) enum BoringSSLAESWRAPImpl { diff --git a/Sources/Crypto/Keys/EC/BoringSSL/Ed25519_boring.swift b/Sources/Crypto/Keys/EC/BoringSSL/Ed25519_boring.swift index 4a16757b1..4ed7ea723 100644 --- a/Sources/Crypto/Keys/EC/BoringSSL/Ed25519_boring.swift +++ b/Sources/Crypto/Keys/EC/BoringSSL/Ed25519_boring.swift @@ -16,7 +16,11 @@ #else @_implementationOnly import CCryptoBoringSSL @_implementationOnly import CCryptoBoringSSLShims +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif // For signing and verifying, we use BoringSSL's Ed25519, not the X25519 stuff. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) diff --git a/Sources/Crypto/Keys/EC/BoringSSL/NISTCurvesKeys_boring.swift b/Sources/Crypto/Keys/EC/BoringSSL/NISTCurvesKeys_boring.swift index fc7d7bdcd..11441322e 100644 --- a/Sources/Crypto/Keys/EC/BoringSSL/NISTCurvesKeys_boring.swift +++ b/Sources/Crypto/Keys/EC/BoringSSL/NISTCurvesKeys_boring.swift @@ -17,7 +17,11 @@ @_implementationOnly import CCryptoBoringSSL @_implementationOnly import CCryptoBoringSSLShims import CryptoBoringWrapper +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif @usableFromInline @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) diff --git a/Sources/Crypto/Keys/EC/BoringSSL/X25519Keys_boring.swift b/Sources/Crypto/Keys/EC/BoringSSL/X25519Keys_boring.swift index 67217df62..b51db37de 100644 --- a/Sources/Crypto/Keys/EC/BoringSSL/X25519Keys_boring.swift +++ b/Sources/Crypto/Keys/EC/BoringSSL/X25519Keys_boring.swift @@ -16,7 +16,11 @@ #else @_implementationOnly import CCryptoBoringSSL @_implementationOnly import CCryptoBoringSSLShims +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension Curve25519.KeyAgreement { diff --git a/Sources/Crypto/Keys/EC/Ed25519Keys.swift b/Sources/Crypto/Keys/EC/Ed25519Keys.swift index a35bde781..3ca56763f 100644 --- a/Sources/Crypto/Keys/EC/Ed25519Keys.swift +++ b/Sources/Crypto/Keys/EC/Ed25519Keys.swift @@ -17,8 +17,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION public import SwiftSystem #else +#if canImport(FoundationEssentials) +public import FoundationEssentials +#else public import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension Curve25519.Signing { diff --git a/Sources/Crypto/Keys/EC/NISTCurvesKeys.swift b/Sources/Crypto/Keys/EC/NISTCurvesKeys.swift index 41c23f03d..319e556cf 100644 --- a/Sources/Crypto/Keys/EC/NISTCurvesKeys.swift +++ b/Sources/Crypto/Keys/EC/NISTCurvesKeys.swift @@ -14,8 +14,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit diff --git a/Sources/Crypto/Keys/EC/X25519Keys.swift b/Sources/Crypto/Keys/EC/X25519Keys.swift index ffd319ee9..a34299ba9 100644 --- a/Sources/Crypto/Keys/EC/X25519Keys.swift +++ b/Sources/Crypto/Keys/EC/X25519Keys.swift @@ -17,8 +17,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION public import SwiftSystem #else +#if canImport(FoundationEssentials) +public import FoundationEssentials +#else public import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension Curve25519.KeyAgreement { diff --git a/Sources/Crypto/Keys/Symmetric/SymmetricKeys.swift b/Sources/Crypto/Keys/Symmetric/SymmetricKeys.swift index 2e7535591..0e46873f6 100644 --- a/Sources/Crypto/Keys/Symmetric/SymmetricKeys.swift +++ b/Sources/Crypto/Keys/Symmetric/SymmetricKeys.swift @@ -18,8 +18,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +public import FoundationEssentials +#else public import Foundation #endif +#endif /// The sizes that a symmetric cryptographic key can take. /// diff --git a/Sources/Crypto/Message Authentication Codes/HMAC/HMAC.swift b/Sources/Crypto/Message Authentication Codes/HMAC/HMAC.swift index 207a6d953..a60def599 100644 --- a/Sources/Crypto/Message Authentication Codes/HMAC/HMAC.swift +++ b/Sources/Crypto/Message Authentication Codes/HMAC/HMAC.swift @@ -17,8 +17,25 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION public import SwiftSystem #else +#if canImport(FoundationEssentials) +#if os(Windows) +import ucrt +#elseif canImport(Darwin) +import Darwin +#elseif canImport(Glibc) +import Glibc +#elseif canImport(Musl) +import Musl +#elseif canImport(Android) +import Android +#elseif canImport(WASILibc) +import WASILibc +#endif +public import FoundationEssentials +#else public import Foundation #endif +#endif /// A hash-based message authentication algorithm. /// diff --git a/Sources/Crypto/Message Authentication Codes/MACFunctions.swift b/Sources/Crypto/Message Authentication Codes/MACFunctions.swift index 02132a861..118bc3882 100644 --- a/Sources/Crypto/Message Authentication Codes/MACFunctions.swift +++ b/Sources/Crypto/Message Authentication Codes/MACFunctions.swift @@ -17,8 +17,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) protocol MACAlgorithm { diff --git a/Sources/Crypto/Message Authentication Codes/MessageAuthenticationCode.swift b/Sources/Crypto/Message Authentication Codes/MessageAuthenticationCode.swift index 4c546139f..13d31f046 100644 --- a/Sources/Crypto/Message Authentication Codes/MessageAuthenticationCode.swift +++ b/Sources/Crypto/Message Authentication Codes/MessageAuthenticationCode.swift @@ -17,8 +17,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION public import SwiftSystem #else +#if canImport(FoundationEssentials) +public import FoundationEssentials +#else public import Foundation #endif +#endif #if hasFeature(Embedded) /// A type that represents a message authentication code. diff --git a/Sources/Crypto/Signatures/BoringSSL/ECDSASignature_boring.swift b/Sources/Crypto/Signatures/BoringSSL/ECDSASignature_boring.swift index 28855a14f..d33110d3d 100644 --- a/Sources/Crypto/Signatures/BoringSSL/ECDSASignature_boring.swift +++ b/Sources/Crypto/Signatures/BoringSSL/ECDSASignature_boring.swift @@ -17,7 +17,11 @@ @_implementationOnly import CCryptoBoringSSL @_implementationOnly import CCryptoBoringSSLShims import CryptoBoringWrapper +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif /// A wrapper around BoringSSL's ECDSA_SIG with some lifetime management. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) diff --git a/Sources/Crypto/Signatures/BoringSSL/ECDSA_boring.swift b/Sources/Crypto/Signatures/BoringSSL/ECDSA_boring.swift index d72b0226c..0842eadac 100644 --- a/Sources/Crypto/Signatures/BoringSSL/ECDSA_boring.swift +++ b/Sources/Crypto/Signatures/BoringSSL/ECDSA_boring.swift @@ -16,7 +16,11 @@ #else @_implementationOnly import CCryptoBoringSSL import CryptoBoringWrapper +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension Data { diff --git a/Sources/Crypto/Signatures/BoringSSL/EdDSA_boring.swift b/Sources/Crypto/Signatures/BoringSSL/EdDSA_boring.swift index b2ea6d2c3..9c3e39c07 100644 --- a/Sources/Crypto/Signatures/BoringSSL/EdDSA_boring.swift +++ b/Sources/Crypto/Signatures/BoringSSL/EdDSA_boring.swift @@ -16,7 +16,11 @@ #else @_implementationOnly import CCryptoBoringSSL @_implementationOnly import CCryptoBoringSSLShims +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension Curve25519.Signing.PublicKey { diff --git a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift index f784d36f2..c058e71cc 100644 --- a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift +++ b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift @@ -16,14 +16,22 @@ @_exported import CryptoKit #else @_implementationOnly import CCryptoBoringSSL +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif // MARK: - Generated file, do NOT edit // any edits of this file WILL be overwritten and thus discarded // see section `gyb` in `README` for details. @_implementationOnly import CCryptoBoringSSL +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLDSA65 { diff --git a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb index ed70dd236..c9d42191b 100644 --- a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb +++ b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb @@ -16,14 +16,22 @@ @_exported import CryptoKit #else @_implementationOnly import CCryptoBoringSSL +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif // MARK: - Generated file, do NOT edit // any edits of this file WILL be overwritten and thus discarded // see section `gyb` in `README` for details. @_implementationOnly import CCryptoBoringSSL +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif %{ parameter_sets = ["65", "87"] }% diff --git a/Sources/Crypto/Signatures/BoringSSL/MLDSA_wrapper.swift b/Sources/Crypto/Signatures/BoringSSL/MLDSA_wrapper.swift index 5d18b7d74..c8171c6b4 100644 --- a/Sources/Crypto/Signatures/BoringSSL/MLDSA_wrapper.swift +++ b/Sources/Crypto/Signatures/BoringSSL/MLDSA_wrapper.swift @@ -16,7 +16,11 @@ @_exported import CryptoKit #else @_implementationOnly import CCryptoBoringSSL +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) protocol BoringSSLBackedMLDSAPrivateKey { diff --git a/Sources/Crypto/Signatures/ECDSA.swift b/Sources/Crypto/Signatures/ECDSA.swift index 85261a9f5..423aef1e8 100644 --- a/Sources/Crypto/Signatures/ECDSA.swift +++ b/Sources/Crypto/Signatures/ECDSA.swift @@ -15,7 +15,11 @@ @_exported import CryptoKit #else #if !CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +#if canImport(FoundationEssentials) +public import FoundationEssentials +#else public import Foundation +#endif #else public import SwiftSystem #endif diff --git a/Sources/Crypto/Signatures/ECDSA.swift.gyb b/Sources/Crypto/Signatures/ECDSA.swift.gyb index ae9564c70..a4e6a7015 100644 --- a/Sources/Crypto/Signatures/ECDSA.swift.gyb +++ b/Sources/Crypto/Signatures/ECDSA.swift.gyb @@ -15,7 +15,11 @@ @_exported import CryptoKit #else #if !CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +#if canImport(FoundationEssentials) +public import FoundationEssentials +#else public import Foundation +#endif #else public import SwiftSystem #endif diff --git a/Sources/Crypto/Signatures/Ed25519.swift b/Sources/Crypto/Signatures/Ed25519.swift index 329ab19d4..c82b85bcc 100644 --- a/Sources/Crypto/Signatures/Ed25519.swift +++ b/Sources/Crypto/Signatures/Ed25519.swift @@ -17,8 +17,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION public import SwiftSystem #else +#if canImport(FoundationEssentials) +public import FoundationEssentials +#else public import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) protocol DigestValidator { diff --git a/Sources/Crypto/Signatures/MLDSA.swift b/Sources/Crypto/Signatures/MLDSA.swift index 0a079ca45..9f5842dff 100644 --- a/Sources/Crypto/Signatures/MLDSA.swift +++ b/Sources/Crypto/Signatures/MLDSA.swift @@ -14,7 +14,11 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else +#if canImport(FoundationEssentials) +public import FoundationEssentials +#else public import Foundation +#endif #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION typealias MLDSAPublicKeyImpl = CoreCryptoMLDSAPublicKeyImpl diff --git a/Sources/Crypto/Signatures/MLDSA.swift.gyb b/Sources/Crypto/Signatures/MLDSA.swift.gyb index 9481fc670..a0cab6fe4 100644 --- a/Sources/Crypto/Signatures/MLDSA.swift.gyb +++ b/Sources/Crypto/Signatures/MLDSA.swift.gyb @@ -14,7 +14,11 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else +#if canImport(FoundationEssentials) +public import FoundationEssentials +#else public import Foundation +#endif #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION typealias MLDSAPublicKeyImpl = CoreCryptoMLDSAPublicKeyImpl diff --git a/Sources/Crypto/Signatures/Signature.swift b/Sources/Crypto/Signatures/Signature.swift index c8fca65a7..ea9f9700f 100644 --- a/Sources/Crypto/Signatures/Signature.swift +++ b/Sources/Crypto/Signatures/Signature.swift @@ -17,8 +17,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) protocol SignatureVerification { diff --git a/Sources/Crypto/Util/BoringSSL/Optional+withUnsafeBytes_boring.swift b/Sources/Crypto/Util/BoringSSL/Optional+withUnsafeBytes_boring.swift index 6f9a2a251..8d8aabaca 100644 --- a/Sources/Crypto/Util/BoringSSL/Optional+withUnsafeBytes_boring.swift +++ b/Sources/Crypto/Util/BoringSSL/Optional+withUnsafeBytes_boring.swift @@ -12,7 +12,11 @@ // //===----------------------------------------------------------------------===// +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif extension Optional where Wrapped: DataProtocol { func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> ReturnValue) rethrows -> ReturnValue { diff --git a/Sources/Crypto/Util/BoringSSL/SafeCompare_boring.swift b/Sources/Crypto/Util/BoringSSL/SafeCompare_boring.swift index 0999addf0..da810a080 100644 --- a/Sources/Crypto/Util/BoringSSL/SafeCompare_boring.swift +++ b/Sources/Crypto/Util/BoringSSL/SafeCompare_boring.swift @@ -11,7 +11,11 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif /// This function performs a safe comparison between two buffers of bytes. It exists as a temporary shim until we refactor /// some of the usage sites to pass better data structures to us. diff --git a/Sources/Crypto/Util/PrettyBytes.swift b/Sources/Crypto/Util/PrettyBytes.swift index 695ebb31e..82190c60f 100644 --- a/Sources/Crypto/Util/PrettyBytes.swift +++ b/Sources/Crypto/Util/PrettyBytes.swift @@ -14,8 +14,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) enum ByteHexEncodingErrors: Error { diff --git a/Sources/Crypto/Util/SafeCompare.swift b/Sources/Crypto/Util/SafeCompare.swift index 51a726d5a..25358f9a0 100644 --- a/Sources/Crypto/Util/SafeCompare.swift +++ b/Sources/Crypto/Util/SafeCompare.swift @@ -17,8 +17,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) internal func safeCompare(_ lhs: LHS, _ rhs: RHS) -> Bool { diff --git a/Sources/Crypto/Util/SecureBytes.swift b/Sources/Crypto/Util/SecureBytes.swift index 94be737f5..86b7c88a4 100644 --- a/Sources/Crypto/Util/SecureBytes.swift +++ b/Sources/Crypto/Util/SecureBytes.swift @@ -17,8 +17,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) nonisolated(unsafe) private let emptyStorage:SecureBytes.Backing = SecureBytes.Backing.createEmpty() diff --git a/Sources/Crypto/Util/Zeroization.swift b/Sources/Crypto/Util/Zeroization.swift index 0f115f694..ee71831e2 100644 --- a/Sources/Crypto/Util/Zeroization.swift +++ b/Sources/Crypto/Util/Zeroization.swift @@ -17,8 +17,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) protocol Zeroization { diff --git a/Sources/CryptoBoringWrapper/AEAD/BoringSSLAEAD.swift b/Sources/CryptoBoringWrapper/AEAD/BoringSSLAEAD.swift index b4033e072..55b0786d5 100644 --- a/Sources/CryptoBoringWrapper/AEAD/BoringSSLAEAD.swift +++ b/Sources/CryptoBoringWrapper/AEAD/BoringSSLAEAD.swift @@ -14,7 +14,12 @@ @_implementationOnly import CCryptoBoringSSL @_implementationOnly import CCryptoBoringSSLShims + +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif /// An abstraction over a BoringSSL AEAD @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) diff --git a/Sources/CryptoBoringWrapper/Util/ArbitraryPrecisionInteger.swift b/Sources/CryptoBoringWrapper/Util/ArbitraryPrecisionInteger.swift index 41f53a9fb..505e54abd 100644 --- a/Sources/CryptoBoringWrapper/Util/ArbitraryPrecisionInteger.swift +++ b/Sources/CryptoBoringWrapper/Util/ArbitraryPrecisionInteger.swift @@ -16,7 +16,11 @@ #else @_implementationOnly import CCryptoBoringSSL @_implementationOnly import CCryptoBoringSSLShims +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif /// A wrapper around the OpenSSL BIGNUM object that is appropriately lifetime managed, /// and that provides better Swift types for this object. diff --git a/Sources/CryptoBoringWrapper/Util/FiniteFieldArithmeticContext.swift b/Sources/CryptoBoringWrapper/Util/FiniteFieldArithmeticContext.swift index 99078a44d..f5c6d435c 100644 --- a/Sources/CryptoBoringWrapper/Util/FiniteFieldArithmeticContext.swift +++ b/Sources/CryptoBoringWrapper/Util/FiniteFieldArithmeticContext.swift @@ -15,7 +15,11 @@ @_exported import CryptoKit #else @_implementationOnly import CCryptoBoringSSL +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif /// A context for performing mathematical operations on ArbitraryPrecisionIntegers over a finite field. /// diff --git a/Sources/_CryptoExtras/AES/AES_CBC.swift b/Sources/_CryptoExtras/AES/AES_CBC.swift index 6d7263a7f..8041387e2 100644 --- a/Sources/_CryptoExtras/AES/AES_CBC.swift +++ b/Sources/_CryptoExtras/AES/AES_CBC.swift @@ -13,7 +13,11 @@ //===----------------------------------------------------------------------===// import Crypto +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension AES { diff --git a/Sources/_CryptoExtras/AES/AES_CFB.swift b/Sources/_CryptoExtras/AES/AES_CFB.swift index 6c5645a7a..0334f2a4a 100644 --- a/Sources/_CryptoExtras/AES/AES_CFB.swift +++ b/Sources/_CryptoExtras/AES/AES_CFB.swift @@ -13,7 +13,11 @@ //===----------------------------------------------------------------------===// import Crypto +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif @usableFromInline @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) diff --git a/Sources/_CryptoExtras/AES/AES_CTR.swift b/Sources/_CryptoExtras/AES/AES_CTR.swift index 85b94689e..416b0c313 100644 --- a/Sources/_CryptoExtras/AES/AES_CTR.swift +++ b/Sources/_CryptoExtras/AES/AES_CTR.swift @@ -13,7 +13,11 @@ //===----------------------------------------------------------------------===// import Crypto +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif @usableFromInline @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) diff --git a/Sources/_CryptoExtras/AES/AES_GCM_SIV.swift b/Sources/_CryptoExtras/AES/AES_GCM_SIV.swift index 8c3d136d9..33d0c7edf 100644 --- a/Sources/_CryptoExtras/AES/AES_GCM_SIV.swift +++ b/Sources/_CryptoExtras/AES/AES_GCM_SIV.swift @@ -16,7 +16,11 @@ import Crypto @_implementationOnly import CCryptoBoringSSL @_implementationOnly import CCryptoBoringSSLShims import CryptoBoringWrapper +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif /// Types associated with the AES GCM SIV algorithm @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) diff --git a/Sources/_CryptoExtras/AES/Block Function.swift b/Sources/_CryptoExtras/AES/Block Function.swift index 4cc8b8fd6..0bf0ccbc8 100644 --- a/Sources/_CryptoExtras/AES/Block Function.swift +++ b/Sources/_CryptoExtras/AES/Block Function.swift @@ -16,7 +16,11 @@ import Crypto @_implementationOnly import CCryptoBoringSSL @_implementationOnly import CCryptoBoringSSLShims import CryptoBoringWrapper +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension AES { diff --git a/Sources/_CryptoExtras/AES/BoringSSL/AES_CFB_boring.swift b/Sources/_CryptoExtras/AES/BoringSSL/AES_CFB_boring.swift index 5ce90f78d..69e57ddac 100644 --- a/Sources/_CryptoExtras/AES/BoringSSL/AES_CFB_boring.swift +++ b/Sources/_CryptoExtras/AES/BoringSSL/AES_CFB_boring.swift @@ -14,7 +14,12 @@ @_implementationOnly import CCryptoBoringSSL import Crypto + +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif @usableFromInline @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) diff --git a/Sources/_CryptoExtras/AES/BoringSSL/AES_CTR_boring.swift b/Sources/_CryptoExtras/AES/BoringSSL/AES_CTR_boring.swift index e37df6244..2ed03be5f 100644 --- a/Sources/_CryptoExtras/AES/BoringSSL/AES_CTR_boring.swift +++ b/Sources/_CryptoExtras/AES/BoringSSL/AES_CTR_boring.swift @@ -14,7 +14,12 @@ @_implementationOnly import CCryptoBoringSSL import Crypto + +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif @usableFromInline @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) diff --git a/Sources/_CryptoExtras/AES/BoringSSL/AES_GCM_SIV_boring.swift b/Sources/_CryptoExtras/AES/BoringSSL/AES_GCM_SIV_boring.swift index 141e2b60e..3bc7aff3e 100644 --- a/Sources/_CryptoExtras/AES/BoringSSL/AES_GCM_SIV_boring.swift +++ b/Sources/_CryptoExtras/AES/BoringSSL/AES_GCM_SIV_boring.swift @@ -18,7 +18,12 @@ @_implementationOnly import CCryptoBoringSSLShims import Crypto import CryptoBoringWrapper + +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension BoringSSLAEAD { diff --git a/Sources/_CryptoExtras/ARC/ARC+API.swift b/Sources/_CryptoExtras/ARC/ARC+API.swift index 3a29f85bb..4e159f32c 100644 --- a/Sources/_CryptoExtras/ARC/ARC+API.swift +++ b/Sources/_CryptoExtras/ARC/ARC+API.swift @@ -12,7 +12,11 @@ // //===----------------------------------------------------------------------===// import Crypto +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif // MARK: - P384 + ARC(P-384) @available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) diff --git a/Sources/_CryptoExtras/ARC/ARC.swift b/Sources/_CryptoExtras/ARC/ARC.swift index 73bda212a..0e6f6dd39 100644 --- a/Sources/_CryptoExtras/ARC/ARC.swift +++ b/Sources/_CryptoExtras/ARC/ARC.swift @@ -12,7 +12,11 @@ // //===----------------------------------------------------------------------===// import Crypto +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif /// Anonymous Rate-Limited Credentials (ARC) using the CMZ14 MACGGM construction, as defined in /// https://chris-wood.github.io/draft-arc/draft-yun-cfrg-arc.html diff --git a/Sources/_CryptoExtras/ARC/ARCCredential.swift b/Sources/_CryptoExtras/ARC/ARCCredential.swift index 05442263b..85dac1f85 100644 --- a/Sources/_CryptoExtras/ARC/ARCCredential.swift +++ b/Sources/_CryptoExtras/ARC/ARCCredential.swift @@ -12,7 +12,11 @@ // //===----------------------------------------------------------------------===// import Crypto +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif @available(macOS 10.15, iOS 13.2, tvOS 13.2, watchOS 6.1, macCatalyst 13.2, visionOS 1.2, *) extension ARC { diff --git a/Sources/_CryptoExtras/ARC/ARCEncoding.swift b/Sources/_CryptoExtras/ARC/ARCEncoding.swift index 7c77ab18f..579787355 100644 --- a/Sources/_CryptoExtras/ARC/ARCEncoding.swift +++ b/Sources/_CryptoExtras/ARC/ARCEncoding.swift @@ -11,7 +11,11 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif import Crypto @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) diff --git a/Sources/_CryptoExtras/ARC/ARCPrecredential.swift b/Sources/_CryptoExtras/ARC/ARCPrecredential.swift index 4b3f0cd04..27c5c5ac7 100644 --- a/Sources/_CryptoExtras/ARC/ARCPrecredential.swift +++ b/Sources/_CryptoExtras/ARC/ARCPrecredential.swift @@ -12,7 +12,11 @@ // //===----------------------------------------------------------------------===// import Crypto +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif @available(macOS 10.15, iOS 13.2, tvOS 13.2, watchOS 6.1, macCatalyst 13.2, visionOS 1.2, *) extension ARC { diff --git a/Sources/_CryptoExtras/ARC/ARCPresentation.swift b/Sources/_CryptoExtras/ARC/ARCPresentation.swift index 4cdc69068..5e2272039 100644 --- a/Sources/_CryptoExtras/ARC/ARCPresentation.swift +++ b/Sources/_CryptoExtras/ARC/ARCPresentation.swift @@ -12,7 +12,11 @@ // //===----------------------------------------------------------------------===// import Crypto +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif @available(macOS 10.15, iOS 13.2, tvOS 13.2, watchOS 6.1, macCatalyst 13.2, visionOS 1.2, *) extension ARC { diff --git a/Sources/_CryptoExtras/ARC/ARCRequest.swift b/Sources/_CryptoExtras/ARC/ARCRequest.swift index 25bf7c55b..9c9f529b2 100644 --- a/Sources/_CryptoExtras/ARC/ARCRequest.swift +++ b/Sources/_CryptoExtras/ARC/ARCRequest.swift @@ -12,7 +12,11 @@ // //===----------------------------------------------------------------------===// import Crypto +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif @available(macOS 10.15, iOS 13.2, tvOS 13.2, watchOS 6.1, macCatalyst 13.2, visionOS 1.2, *) extension ARC { diff --git a/Sources/_CryptoExtras/ARC/ARCResponse.swift b/Sources/_CryptoExtras/ARC/ARCResponse.swift index cf0e3e13f..b6202925a 100644 --- a/Sources/_CryptoExtras/ARC/ARCResponse.swift +++ b/Sources/_CryptoExtras/ARC/ARCResponse.swift @@ -12,7 +12,11 @@ // //===----------------------------------------------------------------------===// import Crypto +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif @available(macOS 10.15, iOS 13.2, tvOS 13.2, watchOS 6.1, macCatalyst 13.2, visionOS 1.2, *) extension ARC { diff --git a/Sources/_CryptoExtras/ARC/ARCServer.swift b/Sources/_CryptoExtras/ARC/ARCServer.swift index 0565536bf..53f890046 100644 --- a/Sources/_CryptoExtras/ARC/ARCServer.swift +++ b/Sources/_CryptoExtras/ARC/ARCServer.swift @@ -12,7 +12,11 @@ // //===----------------------------------------------------------------------===// import Crypto +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif @available(macOS 10.15, iOS 13.2, tvOS 13.2, watchOS 6.1, macCatalyst 13.2, visionOS 1.2, *) extension ARC { diff --git a/Sources/_CryptoExtras/ChaCha20CTR/BoringSSL/ChaCha20CTR_boring.swift b/Sources/_CryptoExtras/ChaCha20CTR/BoringSSL/ChaCha20CTR_boring.swift index bd4378af2..701bf8d8c 100644 --- a/Sources/_CryptoExtras/ChaCha20CTR/BoringSSL/ChaCha20CTR_boring.swift +++ b/Sources/_CryptoExtras/ChaCha20CTR/BoringSSL/ChaCha20CTR_boring.swift @@ -16,7 +16,12 @@ @_implementationOnly import CCryptoBoringSSLShims import Crypto import CryptoBoringWrapper + +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) enum OpenSSLChaCha20CTRImpl { diff --git a/Sources/_CryptoExtras/ChaCha20CTR/ChaCha20CTR.swift b/Sources/_CryptoExtras/ChaCha20CTR/ChaCha20CTR.swift index 837ba5c1f..385fa6e64 100644 --- a/Sources/_CryptoExtras/ChaCha20CTR/ChaCha20CTR.swift +++ b/Sources/_CryptoExtras/ChaCha20CTR/ChaCha20CTR.swift @@ -16,7 +16,11 @@ @_implementationOnly import CCryptoBoringSSLShims import Crypto import CryptoBoringWrapper +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) typealias ChaCha20CTRImpl = OpenSSLChaCha20CTRImpl diff --git a/Sources/_CryptoExtras/ECToolbox/BoringSSL/ECToolbox_boring.swift b/Sources/_CryptoExtras/ECToolbox/BoringSSL/ECToolbox_boring.swift index 44d5401c2..8cde5d034 100644 --- a/Sources/_CryptoExtras/ECToolbox/BoringSSL/ECToolbox_boring.swift +++ b/Sources/_CryptoExtras/ECToolbox/BoringSSL/ECToolbox_boring.swift @@ -13,7 +13,12 @@ //===----------------------------------------------------------------------===// import Crypto import CryptoBoringWrapper + +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif /// NOTE: This protocol is different from `Crypto.OpenSSLSupportedNISTCurve` module and has additional requirements to /// support ECToolbox. It is (re-)defined here because its counterpart in the Crypto module is only conditionally diff --git a/Sources/_CryptoExtras/ECToolbox/ECToolbox.swift b/Sources/_CryptoExtras/ECToolbox/ECToolbox.swift index 5a9eb7c36..452ed640f 100644 --- a/Sources/_CryptoExtras/ECToolbox/ECToolbox.swift +++ b/Sources/_CryptoExtras/ECToolbox/ECToolbox.swift @@ -12,7 +12,11 @@ // //===----------------------------------------------------------------------===// import Crypto +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif #if canImport(Darwin) && !CRYPTO_IN_SWIFTPM @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) diff --git a/Sources/_CryptoExtras/H2G/HashToField.swift b/Sources/_CryptoExtras/H2G/HashToField.swift index d1dfd153e..3b9b55c8d 100644 --- a/Sources/_CryptoExtras/H2G/HashToField.swift +++ b/Sources/_CryptoExtras/H2G/HashToField.swift @@ -11,7 +11,24 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if canImport(FoundationEssentials) +#if os(Windows) +import ucrt +#elseif canImport(Darwin) +import Darwin +#elseif canImport(Glibc) +import Glibc +#elseif canImport(Musl) +import Musl +#elseif canImport(Android) +import Android +#elseif canImport(WASILibc) +import WASILibc +#endif +import FoundationEssentials +#else import Foundation +#endif import Crypto @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) diff --git a/Sources/_CryptoExtras/Key Derivation/KDF.swift b/Sources/_CryptoExtras/Key Derivation/KDF.swift index 3ecae0a2b..6990023d7 100644 --- a/Sources/_CryptoExtras/Key Derivation/KDF.swift +++ b/Sources/_CryptoExtras/Key Derivation/KDF.swift @@ -12,7 +12,11 @@ // //===----------------------------------------------------------------------===// import Crypto +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif /// A container for Key Detivation Function algorithms. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) diff --git a/Sources/_CryptoExtras/Key Derivation/PBKDF2/BoringSSL/PBKDF2_boring.swift b/Sources/_CryptoExtras/Key Derivation/PBKDF2/BoringSSL/PBKDF2_boring.swift index e2df821bb..6bfbad715 100644 --- a/Sources/_CryptoExtras/Key Derivation/PBKDF2/BoringSSL/PBKDF2_boring.swift +++ b/Sources/_CryptoExtras/Key Derivation/PBKDF2/BoringSSL/PBKDF2_boring.swift @@ -12,7 +12,12 @@ // //===----------------------------------------------------------------------===// import Crypto + +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif #if !canImport(CommonCrypto) @_implementationOnly import CCryptoBoringSSL diff --git a/Sources/_CryptoExtras/Key Derivation/PBKDF2/BoringSSL/PBKDF2_commoncrypto.swift b/Sources/_CryptoExtras/Key Derivation/PBKDF2/BoringSSL/PBKDF2_commoncrypto.swift index ad3217cc4..5926bbc4a 100644 --- a/Sources/_CryptoExtras/Key Derivation/PBKDF2/BoringSSL/PBKDF2_commoncrypto.swift +++ b/Sources/_CryptoExtras/Key Derivation/PBKDF2/BoringSSL/PBKDF2_commoncrypto.swift @@ -12,7 +12,12 @@ // //===----------------------------------------------------------------------===// import Crypto + +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif #if canImport(CommonCrypto) @_implementationOnly import CommonCrypto diff --git a/Sources/_CryptoExtras/Key Derivation/PBKDF2/PBKDF2.swift b/Sources/_CryptoExtras/Key Derivation/PBKDF2/PBKDF2.swift index 90a268cdc..d222f141a 100644 --- a/Sources/_CryptoExtras/Key Derivation/PBKDF2/PBKDF2.swift +++ b/Sources/_CryptoExtras/Key Derivation/PBKDF2/PBKDF2.swift @@ -12,7 +12,11 @@ // //===----------------------------------------------------------------------===// import Crypto +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif #if canImport(CommonCrypto) @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) diff --git a/Sources/_CryptoExtras/Key Derivation/Scrypt/BoringSSL/Scrypt_boring.swift b/Sources/_CryptoExtras/Key Derivation/Scrypt/BoringSSL/Scrypt_boring.swift index 20371014c..b89c9bd1e 100644 --- a/Sources/_CryptoExtras/Key Derivation/Scrypt/BoringSSL/Scrypt_boring.swift +++ b/Sources/_CryptoExtras/Key Derivation/Scrypt/BoringSSL/Scrypt_boring.swift @@ -15,7 +15,25 @@ @_implementationOnly import CCryptoBoringSSL @_implementationOnly import CCryptoBoringSSLShims import Crypto + +#if canImport(FoundationEssentials) +#if os(Windows) +import ucrt +#elseif canImport(Darwin) +import Darwin +#elseif canImport(Glibc) +import Glibc +#elseif canImport(Musl) +import Musl +#elseif canImport(Android) +import Android +#elseif canImport(WASILibc) +import WASILibc +#endif +import FoundationEssentials +#else import Foundation +#endif #if canImport(Android) import Android diff --git a/Sources/_CryptoExtras/Key Derivation/Scrypt/Scrypt.swift b/Sources/_CryptoExtras/Key Derivation/Scrypt/Scrypt.swift index 47ef6df66..e0bc93b8f 100644 --- a/Sources/_CryptoExtras/Key Derivation/Scrypt/Scrypt.swift +++ b/Sources/_CryptoExtras/Key Derivation/Scrypt/Scrypt.swift @@ -12,7 +12,11 @@ // //===----------------------------------------------------------------------===// import Crypto +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) fileprivate typealias BackingScrypt = BoringSSLScrypt diff --git a/Sources/_CryptoExtras/OPRFs/OPRF.swift b/Sources/_CryptoExtras/OPRFs/OPRF.swift index 65ce05990..28336d123 100644 --- a/Sources/_CryptoExtras/OPRFs/OPRF.swift +++ b/Sources/_CryptoExtras/OPRFs/OPRF.swift @@ -11,7 +11,11 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif import Crypto /// (Verifiable Partly-)Oblivious Pseudorandom Functions diff --git a/Sources/_CryptoExtras/OPRFs/OPRFClient.swift b/Sources/_CryptoExtras/OPRFs/OPRFClient.swift index 0e676961c..a30808210 100644 --- a/Sources/_CryptoExtras/OPRFs/OPRFClient.swift +++ b/Sources/_CryptoExtras/OPRFs/OPRFClient.swift @@ -12,7 +12,11 @@ // //===----------------------------------------------------------------------===// import Crypto +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif @available(macOS 10.15, iOS 13.2, tvOS 13.2, watchOS 6.1, macCatalyst 13.2, visionOS 1.2, *) extension OPRF { diff --git a/Sources/_CryptoExtras/OPRFs/OPRFServer.swift b/Sources/_CryptoExtras/OPRFs/OPRFServer.swift index ef5279121..baa3a419a 100644 --- a/Sources/_CryptoExtras/OPRFs/OPRFServer.swift +++ b/Sources/_CryptoExtras/OPRFs/OPRFServer.swift @@ -11,7 +11,11 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif import Crypto @available(macOS 10.15, iOS 13.2, tvOS 13.2, watchOS 6.1, macCatalyst 13.2, visionOS 1.2, *) diff --git a/Sources/_CryptoExtras/OPRFs/VOPRF+API.swift b/Sources/_CryptoExtras/OPRFs/VOPRF+API.swift index 6f1ea6c39..44476b0ef 100644 --- a/Sources/_CryptoExtras/OPRFs/VOPRF+API.swift +++ b/Sources/_CryptoExtras/OPRFs/VOPRF+API.swift @@ -12,7 +12,11 @@ // //===----------------------------------------------------------------------===// import Crypto +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif // MARK: - P384 + VPORF (P384-SHA384) @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) diff --git a/Sources/_CryptoExtras/OPRFs/VOPRFClient.swift b/Sources/_CryptoExtras/OPRFs/VOPRFClient.swift index 15e5ffad6..299e00c1f 100644 --- a/Sources/_CryptoExtras/OPRFs/VOPRFClient.swift +++ b/Sources/_CryptoExtras/OPRFs/VOPRFClient.swift @@ -12,7 +12,11 @@ // //===----------------------------------------------------------------------===// import Crypto +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif @available(macOS 10.15, iOS 13.2, tvOS 13.2, watchOS 6.1, macCatalyst 13.2, visionOS 1.2, *) extension OPRF { diff --git a/Sources/_CryptoExtras/OPRFs/VOPRFServer.swift b/Sources/_CryptoExtras/OPRFs/VOPRFServer.swift index f42e98e76..1a20271fd 100644 --- a/Sources/_CryptoExtras/OPRFs/VOPRFServer.swift +++ b/Sources/_CryptoExtras/OPRFs/VOPRFServer.swift @@ -11,7 +11,11 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif import Crypto @available(macOS 10.15, iOS 13.2, tvOS 13.2, watchOS 6.1, macCatalyst 13.2, visionOS 1.2, *) diff --git a/Sources/_CryptoExtras/RSA/RSA+BlindSigning.swift b/Sources/_CryptoExtras/RSA/RSA+BlindSigning.swift index a1d56f23f..f21f17358 100644 --- a/Sources/_CryptoExtras/RSA/RSA+BlindSigning.swift +++ b/Sources/_CryptoExtras/RSA/RSA+BlindSigning.swift @@ -11,7 +11,11 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif import Crypto import CryptoBoringWrapper diff --git a/Sources/_CryptoExtras/RSA/RSA.swift b/Sources/_CryptoExtras/RSA/RSA.swift index df6a5876b..4d37e9e8f 100644 --- a/Sources/_CryptoExtras/RSA/RSA.swift +++ b/Sources/_CryptoExtras/RSA/RSA.swift @@ -11,7 +11,11 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif import Crypto import CryptoBoringWrapper import SwiftASN1 diff --git a/Sources/_CryptoExtras/RSA/RSA_boring.swift b/Sources/_CryptoExtras/RSA/RSA_boring.swift index cd560d759..fae4da655 100644 --- a/Sources/_CryptoExtras/RSA/RSA_boring.swift +++ b/Sources/_CryptoExtras/RSA/RSA_boring.swift @@ -17,7 +17,25 @@ @_implementationOnly import CCryptoBoringSSLShims import Crypto import CryptoBoringWrapper + +#if canImport(FoundationEssentials) +#if os(Windows) +import ucrt +#elseif canImport(Darwin) +import Darwin +#elseif canImport(Glibc) +import Glibc +#elseif canImport(Musl) +import Musl +#elseif canImport(Android) +import Android +#elseif canImport(WASILibc) +import WASILibc +#endif +import FoundationEssentials +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) internal struct BoringSSLRSAPublicKey: Sendable { diff --git a/Sources/_CryptoExtras/RSA/RSA_security.swift b/Sources/_CryptoExtras/RSA/RSA_security.swift index 0a88fcc6a..db1f9f96e 100644 --- a/Sources/_CryptoExtras/RSA/RSA_security.swift +++ b/Sources/_CryptoExtras/RSA/RSA_security.swift @@ -11,7 +11,11 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif import Crypto #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API diff --git a/Sources/_CryptoExtras/Util/BoringSSLHelpers.swift b/Sources/_CryptoExtras/Util/BoringSSLHelpers.swift index 1590b73d0..b560330c3 100644 --- a/Sources/_CryptoExtras/Util/BoringSSLHelpers.swift +++ b/Sources/_CryptoExtras/Util/BoringSSLHelpers.swift @@ -15,7 +15,11 @@ // NOTE: This file is unconditionally compiled because RSABSSA is implemented using BoringSSL on all platforms. @_implementationOnly import CCryptoBoringSSL @_implementationOnly import CCryptoBoringSSLShims +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif import Crypto @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) diff --git a/Sources/_CryptoExtras/Util/Data+Extensions.swift b/Sources/_CryptoExtras/Util/Data+Extensions.swift index 10494a8fb..a0ca7f9d6 100644 --- a/Sources/_CryptoExtras/Util/Data+Extensions.swift +++ b/Sources/_CryptoExtras/Util/Data+Extensions.swift @@ -12,7 +12,11 @@ // //===----------------------------------------------------------------------===// +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif extension Data { // This overload reduces allocations when used in a chain of infix operations. diff --git a/Sources/_CryptoExtras/Util/I2OSP.swift b/Sources/_CryptoExtras/Util/I2OSP.swift index 66ae93722..bc7dc5ad2 100644 --- a/Sources/_CryptoExtras/Util/I2OSP.swift +++ b/Sources/_CryptoExtras/Util/I2OSP.swift @@ -11,7 +11,24 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if canImport(FoundationEssentials) +#if os(Windows) +import ucrt +#elseif canImport(Darwin) +import Darwin +#elseif canImport(Glibc) +import Glibc +#elseif canImport(Musl) +import Musl +#elseif canImport(Android) +import Android +#elseif canImport(WASILibc) +import WASILibc +#endif +import FoundationEssentials +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) func I2OSP(value: Int, outputByteCount: Int) -> Data { diff --git a/Sources/_CryptoExtras/Util/IntegerEncoding.swift b/Sources/_CryptoExtras/Util/IntegerEncoding.swift index 2efe83c82..c26fbdc40 100644 --- a/Sources/_CryptoExtras/Util/IntegerEncoding.swift +++ b/Sources/_CryptoExtras/Util/IntegerEncoding.swift @@ -11,7 +11,11 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif enum IntegerDecodingError: Error, Equatable { case incorrectNumberOfBytes(expected: Int, actual: Int) diff --git a/Sources/_CryptoExtras/Util/PEMDocument.swift b/Sources/_CryptoExtras/Util/PEMDocument.swift index 22f64c430..17467a854 100644 --- a/Sources/_CryptoExtras/Util/PEMDocument.swift +++ b/Sources/_CryptoExtras/Util/PEMDocument.swift @@ -11,7 +11,11 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif import Crypto @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) diff --git a/Sources/_CryptoExtras/Util/PrettyBytes.swift b/Sources/_CryptoExtras/Util/PrettyBytes.swift index 8db832af7..9394fc846 100644 --- a/Sources/_CryptoExtras/Util/PrettyBytes.swift +++ b/Sources/_CryptoExtras/Util/PrettyBytes.swift @@ -11,7 +11,11 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) enum ByteHexEncodingErrors: Error { diff --git a/Sources/_CryptoExtras/ZKPs/DLEQ.swift b/Sources/_CryptoExtras/ZKPs/DLEQ.swift index 0eb97ed74..41cf271ee 100644 --- a/Sources/_CryptoExtras/ZKPs/DLEQ.swift +++ b/Sources/_CryptoExtras/ZKPs/DLEQ.swift @@ -11,7 +11,11 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif import Crypto /// A DLEQ Proof as described in https://cfrg.github.io/draft-irtf-cfrg-voprf/draft-irtf-cfrg-voprf.html#name-generateproof diff --git a/Sources/_CryptoExtras/ZKPs/Prover.swift b/Sources/_CryptoExtras/ZKPs/Prover.swift index b02670b42..ac5fa036b 100644 --- a/Sources/_CryptoExtras/ZKPs/Prover.swift +++ b/Sources/_CryptoExtras/ZKPs/Prover.swift @@ -11,7 +11,11 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif import Crypto @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) diff --git a/Sources/_CryptoExtras/ZKPs/Verifier.swift b/Sources/_CryptoExtras/ZKPs/Verifier.swift index a7e279156..8a9a8445e 100644 --- a/Sources/_CryptoExtras/ZKPs/Verifier.swift +++ b/Sources/_CryptoExtras/ZKPs/Verifier.swift @@ -11,7 +11,11 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif import Crypto @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) diff --git a/Sources/_CryptoExtras/ZKPs/ZKPToolbox.swift b/Sources/_CryptoExtras/ZKPs/ZKPToolbox.swift index 15c730e54..8c7db5d14 100644 --- a/Sources/_CryptoExtras/ZKPs/ZKPToolbox.swift +++ b/Sources/_CryptoExtras/ZKPs/ZKPToolbox.swift @@ -11,7 +11,11 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif import Crypto @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) diff --git a/Tests/CryptoTests/Authenticated Encryption/AES-GCM-Runner.swift b/Tests/CryptoTests/Authenticated Encryption/AES-GCM-Runner.swift index ee0f85051..c51dd7dc4 100644 --- a/Tests/CryptoTests/Authenticated Encryption/AES-GCM-Runner.swift +++ b/Tests/CryptoTests/Authenticated Encryption/AES-GCM-Runner.swift @@ -11,7 +11,11 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif import XCTest #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API diff --git a/Tests/CryptoTests/Authenticated Encryption/ChaChaPoly-Runner.swift b/Tests/CryptoTests/Authenticated Encryption/ChaChaPoly-Runner.swift index 7eb0a36b8..a36f0b55d 100644 --- a/Tests/CryptoTests/Authenticated Encryption/ChaChaPoly-Runner.swift +++ b/Tests/CryptoTests/Authenticated Encryption/ChaChaPoly-Runner.swift @@ -11,7 +11,11 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif import XCTest #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API diff --git a/Tests/CryptoTests/ECDH/BoringSSL/ASN1.swift b/Tests/CryptoTests/ECDH/BoringSSL/ASN1.swift index 2b2457b84..1a3716f37 100644 --- a/Tests/CryptoTests/ECDH/BoringSSL/ASN1.swift +++ b/Tests/CryptoTests/ECDH/BoringSSL/ASN1.swift @@ -11,9 +11,14 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// -import Foundation import XCTest +#if canImport(FoundationEssentials) +import FoundationEssentials +#else +import Foundation +#endif + #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API // Skip tests that require @testable imports of CryptoKit. #else diff --git a/Tests/CryptoTests/ECDH/BoringSSL/secpECDH_Runner_boring.swift b/Tests/CryptoTests/ECDH/BoringSSL/secpECDH_Runner_boring.swift index ef6cd8da8..6503f7d5c 100644 --- a/Tests/CryptoTests/ECDH/BoringSSL/secpECDH_Runner_boring.swift +++ b/Tests/CryptoTests/ECDH/BoringSSL/secpECDH_Runner_boring.swift @@ -11,9 +11,14 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// -import Foundation import XCTest +#if canImport(FoundationEssentials) +import FoundationEssentials +#else +import Foundation +#endif + #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API // Skip tests that require @testable imports of CryptoKit. #else diff --git a/Tests/CryptoTests/ECDH/X25519-Runner.swift b/Tests/CryptoTests/ECDH/X25519-Runner.swift index c03bd7b8b..41deb8702 100644 --- a/Tests/CryptoTests/ECDH/X25519-Runner.swift +++ b/Tests/CryptoTests/ECDH/X25519-Runner.swift @@ -11,7 +11,11 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif import XCTest #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API diff --git a/Tests/CryptoTests/ECDH/secpECDH_Runner.swift b/Tests/CryptoTests/ECDH/secpECDH_Runner.swift index aa89bbbde..e03efa1d5 100644 --- a/Tests/CryptoTests/ECDH/secpECDH_Runner.swift +++ b/Tests/CryptoTests/ECDH/secpECDH_Runner.swift @@ -11,7 +11,11 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif import XCTest #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API diff --git a/Tests/CryptoTests/HPKE/HPKETests-TestVectors.swift b/Tests/CryptoTests/HPKE/HPKETests-TestVectors.swift index 0ce8fa259..23f815e0b 100644 --- a/Tests/CryptoTests/HPKE/HPKETests-TestVectors.swift +++ b/Tests/CryptoTests/HPKE/HPKETests-TestVectors.swift @@ -11,7 +11,11 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif import XCTest #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API diff --git a/Tests/CryptoTests/HPKE/HPKETests.swift b/Tests/CryptoTests/HPKE/HPKETests.swift index 80fb0ac16..e0e9e888b 100644 --- a/Tests/CryptoTests/HPKE/HPKETests.swift +++ b/Tests/CryptoTests/HPKE/HPKETests.swift @@ -11,7 +11,11 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif import XCTest #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API diff --git a/Tests/CryptoTests/Key Derivation/ECprivateKeysFromSeeds.swift b/Tests/CryptoTests/Key Derivation/ECprivateKeysFromSeeds.swift index 06ebe89e3..ef4d0cef2 100644 --- a/Tests/CryptoTests/Key Derivation/ECprivateKeysFromSeeds.swift +++ b/Tests/CryptoTests/Key Derivation/ECprivateKeysFromSeeds.swift @@ -11,7 +11,11 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif import XCTest #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API diff --git a/Tests/CryptoTests/Signatures/ECDSA/ECDSASignatureTests.swift b/Tests/CryptoTests/Signatures/ECDSA/ECDSASignatureTests.swift index a13eff23d..f3e2fcd2c 100644 --- a/Tests/CryptoTests/Signatures/ECDSA/ECDSASignatureTests.swift +++ b/Tests/CryptoTests/Signatures/ECDSA/ECDSASignatureTests.swift @@ -11,7 +11,11 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif import XCTest #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API diff --git a/Tests/CryptoTests/Utils/Boring/CTRDRBG.swift b/Tests/CryptoTests/Utils/Boring/CTRDRBG.swift index 8e024d9fe..aff625d83 100644 --- a/Tests/CryptoTests/Utils/Boring/CTRDRBG.swift +++ b/Tests/CryptoTests/Utils/Boring/CTRDRBG.swift @@ -12,7 +12,11 @@ // //===----------------------------------------------------------------------===// #if CRYPTO_IN_SWIFTPM && CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif @_implementationOnly import CCryptoBoringSSL import Crypto diff --git a/Tests/CryptoTests/Utils/Boring/SequenceDRBG.swift b/Tests/CryptoTests/Utils/Boring/SequenceDRBG.swift index ae7c0b266..89c32f622 100644 --- a/Tests/CryptoTests/Utils/Boring/SequenceDRBG.swift +++ b/Tests/CryptoTests/Utils/Boring/SequenceDRBG.swift @@ -12,7 +12,11 @@ // //===----------------------------------------------------------------------===// #if CRYPTO_IN_SWIFTPM && CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif @_implementationOnly import CCryptoBoringSSL import Crypto diff --git a/Tests/CryptoTests/Utils/PrettyBytes.swift b/Tests/CryptoTests/Utils/PrettyBytes.swift index 53563509d..8a8ef78c8 100644 --- a/Tests/CryptoTests/Utils/PrettyBytes.swift +++ b/Tests/CryptoTests/Utils/PrettyBytes.swift @@ -14,8 +14,12 @@ #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION import SwiftSystem #else +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation #endif +#endif enum ByteHexEncodingErrors: Error { case incorrectHexValue diff --git a/Tests/CryptoTests/Utils/SplitData.swift b/Tests/CryptoTests/Utils/SplitData.swift index e0c17e48f..37283d85e 100644 --- a/Tests/CryptoTests/Utils/SplitData.swift +++ b/Tests/CryptoTests/Utils/SplitData.swift @@ -11,7 +11,11 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif import Dispatch // A testing utility that creates one contiguous and one discontiguous representation of the given Data. diff --git a/Tests/_CryptoExtrasTests/AES Block Function Tests.swift b/Tests/_CryptoExtrasTests/AES Block Function Tests.swift index 776962d45..926cc04fc 100644 --- a/Tests/_CryptoExtrasTests/AES Block Function Tests.swift +++ b/Tests/_CryptoExtrasTests/AES Block Function Tests.swift @@ -11,7 +11,11 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif import XCTest import Crypto import _CryptoExtras diff --git a/Tests/_CryptoExtrasTests/AES-GCM-SIV-Runner.swift b/Tests/_CryptoExtrasTests/AES-GCM-SIV-Runner.swift index 227e73c3c..6cfa781f3 100644 --- a/Tests/_CryptoExtrasTests/AES-GCM-SIV-Runner.swift +++ b/Tests/_CryptoExtrasTests/AES-GCM-SIV-Runner.swift @@ -11,7 +11,11 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif import XCTest import Crypto import _CryptoExtras diff --git a/Tests/_CryptoExtrasTests/AES_CBCTests.swift b/Tests/_CryptoExtrasTests/AES_CBCTests.swift index b42131c69..b2ba34eaa 100644 --- a/Tests/_CryptoExtrasTests/AES_CBCTests.swift +++ b/Tests/_CryptoExtrasTests/AES_CBCTests.swift @@ -13,7 +13,11 @@ //===----------------------------------------------------------------------===// import Crypto +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif import _CryptoExtras import XCTest diff --git a/Tests/_CryptoExtrasTests/AES_CTRTests.swift b/Tests/_CryptoExtrasTests/AES_CTRTests.swift index e154b9b4a..2206967f9 100644 --- a/Tests/_CryptoExtrasTests/AES_CTRTests.swift +++ b/Tests/_CryptoExtrasTests/AES_CTRTests.swift @@ -13,7 +13,11 @@ //===----------------------------------------------------------------------===// import Crypto +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif @testable import _CryptoExtras import XCTest diff --git a/Tests/_CryptoExtrasTests/ChaCha20CTRTests.swift b/Tests/_CryptoExtrasTests/ChaCha20CTRTests.swift index b86bfcaac..fde4a79fc 100644 --- a/Tests/_CryptoExtrasTests/ChaCha20CTRTests.swift +++ b/Tests/_CryptoExtrasTests/ChaCha20CTRTests.swift @@ -11,7 +11,11 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif import XCTest import Crypto import _CryptoExtras diff --git a/Tests/_CryptoExtrasTests/TestRSAEncryption.swift b/Tests/_CryptoExtrasTests/TestRSAEncryption.swift index 63ad1e0f3..b6d45c3b6 100644 --- a/Tests/_CryptoExtrasTests/TestRSAEncryption.swift +++ b/Tests/_CryptoExtrasTests/TestRSAEncryption.swift @@ -11,7 +11,11 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif import XCTest import Crypto import _CryptoExtras diff --git a/Tests/_CryptoExtrasTests/TestRSASigning.swift b/Tests/_CryptoExtrasTests/TestRSASigning.swift index 07da7c127..7bbb2cf1a 100644 --- a/Tests/_CryptoExtrasTests/TestRSASigning.swift +++ b/Tests/_CryptoExtrasTests/TestRSASigning.swift @@ -11,7 +11,11 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif import XCTest import Crypto import CryptoBoringWrapper diff --git a/Tests/_CryptoExtrasTests/Utils/BytesUtil.swift b/Tests/_CryptoExtrasTests/Utils/BytesUtil.swift index 5cc8abc76..4e774b83a 100644 --- a/Tests/_CryptoExtrasTests/Utils/BytesUtil.swift +++ b/Tests/_CryptoExtrasTests/Utils/BytesUtil.swift @@ -11,7 +11,11 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif import XCTest enum ByteHexEncodingErrors: Error { diff --git a/Tests/_CryptoExtrasTests/Utils/SplitData.swift b/Tests/_CryptoExtrasTests/Utils/SplitData.swift index 4b1d19307..040d9cd7a 100644 --- a/Tests/_CryptoExtrasTests/Utils/SplitData.swift +++ b/Tests/_CryptoExtrasTests/Utils/SplitData.swift @@ -11,7 +11,11 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// +#if canImport(FoundationEssentials) +import FoundationEssentials +#else import Foundation +#endif import Dispatch // A testing utility that creates one contiguous and one discontiguous representation of the given Data. From 1eb3eec7d94731d038e609a44bad2c806929891b Mon Sep 17 00:00:00 2001 From: Cory Benfield Date: Wed, 18 Jun 2025 16:17:54 +0100 Subject: [PATCH 16/47] Catch the WWDC-25 branch up to the tip of main (#365) To keep the WWDC-25 branch from rotting too badly, we'll be doing regular catch-up merges. This is the first. Co-authored-by: YourMJK <37852512+YourMJK@users.noreply.github.com> --- Sources/_CryptoExtras/RSA/RSA.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/_CryptoExtras/RSA/RSA.swift b/Sources/_CryptoExtras/RSA/RSA.swift index 4d37e9e8f..63e1bcbb3 100644 --- a/Sources/_CryptoExtras/RSA/RSA.swift +++ b/Sources/_CryptoExtras/RSA/RSA.swift @@ -183,7 +183,7 @@ extension _RSA.Signing { } } - /// Construct an RSA public key from a PEM representation. + /// Construct an RSA private key from a PEM representation. /// /// This constructor supports key sizes of 1024 bits or more. Users should validate that key sizes are appropriate /// for their use-case. @@ -208,7 +208,7 @@ extension _RSA.Signing { } } - /// Construct an RSA public key from a DER representation. + /// Construct an RSA private key from a DER representation. /// /// This constructor supports key sizes of 1024 bits or more. Users should validate that key sizes are appropriate /// for their use-case. From 794dfa6020c26820f8cab69585ad80b4fd303785 Mon Sep 17 00:00:00 2001 From: Francesco Paolo Severino Date: Thu, 19 Jun 2025 18:59:56 +0200 Subject: [PATCH 17/47] Update DocC --- Sources/Crypto/Docs.docc/index.md | 14 ++++++++++++++ Sources/_CryptoExtras/Docs.docc/index.md | 4 ---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/Sources/Crypto/Docs.docc/index.md b/Sources/Crypto/Docs.docc/index.md index 931857786..3991f7928 100644 --- a/Sources/Crypto/Docs.docc/index.md +++ b/Sources/Crypto/Docs.docc/index.md @@ -39,11 +39,25 @@ Swift Crypto is built on top of [BoringSSL](https://boringssl.googlesource.com/b - ``P256`` - ``SharedSecret`` - ``HPKE`` +- ``MLDSA65`` +- ``MLDSA87`` ### Key derivation functions - ``HKDF`` +### Key encapsulation mechanisms (KEM) + +- ``KEM`` +- ``MLKEM768`` +- ``MLKEM1024`` +- ``XWingMLKEM768X25519`` + +### KEM keys + +- ``KEMPrivateKey`` +- ``KEMPublicKey`` + ### Errors - ``CryptoKitError`` diff --git a/Sources/_CryptoExtras/Docs.docc/index.md b/Sources/_CryptoExtras/Docs.docc/index.md index b38a23dd7..50b5eca56 100644 --- a/Sources/_CryptoExtras/Docs.docc/index.md +++ b/Sources/_CryptoExtras/Docs.docc/index.md @@ -15,10 +15,6 @@ Provides additional cryptographic APIs that are not available in CryptoKit (and ### Public key cryptography - ``_RSA`` -- ``MLKEM768`` -- ``MLKEM1024`` -- ``MLDSA65`` -- ``MLDSA87`` ### Key derivation functions From 8be108101ec063df417211d2960cf9e77eb0d873 Mon Sep 17 00:00:00 2001 From: Cory Benfield Date: Fri, 20 Jun 2025 07:19:17 +0100 Subject: [PATCH 18/47] Perform another catch-up merge for the WWDC 2025 branch (#367) Co-authored-by: YourMJK <37852512+YourMJK@users.noreply.github.com> --- .../EC/EllipticCurvePoint.swift | 512 +++++++++++------- .../Util/ArbitraryPrecisionInteger.swift | 2 +- .../EllipticCurvePointTests.swift | 60 ++ 3 files changed, 374 insertions(+), 200 deletions(-) create mode 100644 Tests/CryptoBoringWrapperTests/EllipticCurvePointTests.swift diff --git a/Sources/CryptoBoringWrapper/EC/EllipticCurvePoint.swift b/Sources/CryptoBoringWrapper/EC/EllipticCurvePoint.swift index 5ca515aa4..266886237 100644 --- a/Sources/CryptoBoringWrapper/EC/EllipticCurvePoint.swift +++ b/Sources/CryptoBoringWrapper/EC/EllipticCurvePoint.swift @@ -17,100 +17,55 @@ import protocol Foundation.ContiguousBytes import struct Foundation.Data -/// A wrapper around BoringSSL's EC_POINT with some lifetime management. +/// A wrapper around BoringSSL's EC_POINT with some lifetime management and value semantics. @usableFromInline @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -package final class EllipticCurvePoint { - @usableFromInline var _basePoint: OpaquePointer - +package struct EllipticCurvePoint: @unchecked Sendable { @usableFromInline - package init(copying pointer: OpaquePointer, on group: BoringSSLEllipticCurveGroup) throws { - self._basePoint = try group.withUnsafeGroupPointer { groupPtr in - guard let pointPtr = CCryptoBoringSSL_EC_POINT_dup(pointer, groupPtr) else { - throw CryptoBoringWrapperError.internalBoringSSLError() - } - return pointPtr - } - } + var backing: Backing @usableFromInline - package convenience init( - copying other: EllipticCurvePoint, - on group: BoringSSLEllipticCurveGroup - ) - throws - { - try self.init(copying: other._basePoint, on: group) + package init(copying pointer: OpaquePointer, on group: BoringSSLEllipticCurveGroup) throws { + self.backing = try .init(copying: pointer, on: group) } @usableFromInline package init(_pointAtInfinityOn group: BoringSSLEllipticCurveGroup) throws { - self._basePoint = try group.withUnsafeGroupPointer { groupPtr in - guard let pointPtr = CCryptoBoringSSL_EC_POINT_new(groupPtr) else { - throw CryptoBoringWrapperError.internalBoringSSLError() - } - return pointPtr - } + self.backing = try .init(_pointAtInfinityOn: group) } @usableFromInline package init(_generatorOf groupPtr: OpaquePointer) throws { - guard - let generatorPtr = CCryptoBoringSSL_EC_GROUP_get0_generator(groupPtr), - let pointPtr = CCryptoBoringSSL_EC_POINT_dup(generatorPtr, groupPtr) - else { - throw CryptoBoringWrapperError.internalBoringSSLError() - } - self._basePoint = pointPtr + self.backing = try .init(_generatorOf: groupPtr) } @usableFromInline - package convenience init( + package init( multiplying scalar: ArbitraryPrecisionInteger, on group: BoringSSLEllipticCurveGroup, context: FiniteFieldArithmeticContext? = nil ) throws { - try self.init(_pointAtInfinityOn: group) - try group.withUnsafeGroupPointer { groupPtr in - try scalar.withUnsafeBignumPointer { scalarPtr in - guard CCryptoBoringSSL_EC_POINT_mul(groupPtr, self._basePoint, scalarPtr, nil, nil, context?.bnCtx) == 1 - else { - throw CryptoBoringWrapperError.internalBoringSSLError() - } - } - } - } - - deinit { - CCryptoBoringSSL_EC_POINT_free(self._basePoint) + self.backing = try .init(multiplying: scalar, on: group, context: context) } @usableFromInline - package func multiply( + package mutating func multiply( by rhs: ArbitraryPrecisionInteger, on group: BoringSSLEllipticCurveGroup, context: FiniteFieldArithmeticContext? = nil ) throws { - try self.withPointPointer { selfPtr in - try rhs.withUnsafeBignumPointer { rhsPtr in - try group.withUnsafeGroupPointer { groupPtr in - guard CCryptoBoringSSL_EC_POINT_mul(groupPtr, selfPtr, nil, selfPtr, rhsPtr, context?.bnCtx) != 0 - else { - throw CryptoBoringWrapperError.internalBoringSSLError() - } - } - } - } + try self.cowIfNeeded(on: group) + try self.backing.multiply(by: rhs, on: group, context: context) } @usableFromInline - package convenience init( + package init( multiplying lhs: EllipticCurvePoint, by rhs: ArbitraryPrecisionInteger, on group: BoringSSLEllipticCurveGroup, context: FiniteFieldArithmeticContext? = nil ) throws { - try self.init(copying: lhs, on: group) + self = lhs try self.multiply(by: rhs, on: group, context: context) } @@ -120,48 +75,38 @@ package final class EllipticCurvePoint { on group: BoringSSLEllipticCurveGroup, context: FiniteFieldArithmeticContext? = nil ) throws -> EllipticCurvePoint { - guard isKnownUniquelyReferenced(&self) else { - return try EllipticCurvePoint(multiplying: self, by: rhs, on: group, context: context) - } try self.multiply(by: rhs, on: group, context: context) return self } @usableFromInline package static func multiplying( - _ lhs: EllipticCurvePoint, + _ lhs: consuming EllipticCurvePoint, by rhs: ArbitraryPrecisionInteger, on group: BoringSSLEllipticCurveGroup, context: FiniteFieldArithmeticContext? = nil ) throws -> EllipticCurvePoint { - try EllipticCurvePoint(multiplying: lhs, by: rhs, on: group, context: context) + try lhs.multiplying(by: rhs, on: group, context: context) } @usableFromInline - package func add( + package mutating func add( _ rhs: EllipticCurvePoint, on group: BoringSSLEllipticCurveGroup, context: FiniteFieldArithmeticContext? = nil ) throws { - try self.withPointPointer { selfPtr in - try group.withUnsafeGroupPointer { groupPtr in - try rhs.withPointPointer { rhsPtr in - guard CCryptoBoringSSL_EC_POINT_add(groupPtr, selfPtr, selfPtr, rhsPtr, context?.bnCtx) != 0 else { - throw CryptoBoringWrapperError.internalBoringSSLError() - } - } - } - } + try self.cowIfNeeded(on: group) + try self.backing.add(rhs, on: group, context: context) } @usableFromInline - package convenience init( + package init( adding lhs: EllipticCurvePoint, _ rhs: EllipticCurvePoint, on group: BoringSSLEllipticCurveGroup, context: FiniteFieldArithmeticContext? = nil ) throws { - try self.init(copying: lhs, on: group) + self = lhs try self.add(rhs, on: group, context: context) } @@ -171,78 +116,77 @@ package final class EllipticCurvePoint { on group: BoringSSLEllipticCurveGroup, context: FiniteFieldArithmeticContext? = nil ) throws -> EllipticCurvePoint { - guard isKnownUniquelyReferenced(&self) else { - return try EllipticCurvePoint(adding: self, rhs, on: group, context: context) - } try self.add(rhs, on: group, context: context) return self } @usableFromInline package static func adding( - _ lhs: EllipticCurvePoint, + _ lhs: consuming EllipticCurvePoint, _ rhs: EllipticCurvePoint, on group: BoringSSLEllipticCurveGroup, context: FiniteFieldArithmeticContext? = nil ) throws -> EllipticCurvePoint { - try EllipticCurvePoint(adding: lhs, rhs, on: group, context: context) + try lhs.add(rhs, on: group, context: context) + return lhs } @usableFromInline - package func invert(on group: BoringSSLEllipticCurveGroup, context: FiniteFieldArithmeticContext? = nil) throws { - try self.withPointPointer { selfPtr in - try group.withUnsafeGroupPointer { groupPtr in - guard CCryptoBoringSSL_EC_POINT_invert(groupPtr, selfPtr, context?.bnCtx) != 0 else { - throw CryptoBoringWrapperError.internalBoringSSLError() - } - } - } + package mutating func invert( + on group: BoringSSLEllipticCurveGroup, + context: FiniteFieldArithmeticContext? = nil + ) throws { + try self.cowIfNeeded(on: group) + try self.backing.invert(on: group, context: context) } @usableFromInline - package convenience init( + package init( inverting point: EllipticCurvePoint, on group: BoringSSLEllipticCurveGroup, context: FiniteFieldArithmeticContext? = nil ) throws { - try self.init(copying: point, on: group) + self = point try self.invert(on: group, context: context) } @usableFromInline - package func inverting( + package consuming func inverting( on group: BoringSSLEllipticCurveGroup, context: FiniteFieldArithmeticContext? = nil ) throws -> EllipticCurvePoint { - try EllipticCurvePoint(inverting: self, on: group, context: context) + try self.invert(on: group, context: context) + return self } @usableFromInline package static func inverting( - _ point: EllipticCurvePoint, + _ point: consuming EllipticCurvePoint, on group: BoringSSLEllipticCurveGroup, context: FiniteFieldArithmeticContext? = nil ) throws -> EllipticCurvePoint { - try EllipticCurvePoint(inverting: point, on: group, context: context) + try point.invert(on: group, context: context) + return point } @usableFromInline - package func subtract( - _ rhs: EllipticCurvePoint, + package mutating func subtract( + _ rhs: consuming EllipticCurvePoint, on group: BoringSSLEllipticCurveGroup, context: FiniteFieldArithmeticContext? = nil ) throws { + try self.cowIfNeeded(on: group) try self.add(rhs.inverting(on: group), on: group, context: context) } @usableFromInline - package convenience init( - subtracting rhs: EllipticCurvePoint, - from lhs: EllipticCurvePoint, + package init( + subtracting rhs: consuming EllipticCurvePoint, + from lhs: consuming EllipticCurvePoint, on group: BoringSSLEllipticCurveGroup, context: FiniteFieldArithmeticContext? = nil ) throws { - try self.init(copying: lhs, on: group) + self = lhs try self.subtract(rhs, on: group, context: context) } @@ -252,54 +196,28 @@ package final class EllipticCurvePoint { on group: BoringSSLEllipticCurveGroup, context: FiniteFieldArithmeticContext? = nil ) throws -> EllipticCurvePoint { - guard isKnownUniquelyReferenced(&self) else { - return try EllipticCurvePoint(subtracting: rhs, from: self, on: group, context: context) - } try self.subtract(rhs, on: group, context: context) return self } @usableFromInline package static func subtracting( - _ rhs: EllipticCurvePoint, - from lhs: EllipticCurvePoint, + _ rhs: consuming EllipticCurvePoint, + from lhs: consuming EllipticCurvePoint, on group: BoringSSLEllipticCurveGroup, context: FiniteFieldArithmeticContext? = nil ) throws -> EllipticCurvePoint { - try EllipticCurvePoint(subtracting: rhs, from: lhs, on: group, context: context) + try lhs.subtract(rhs, on: group, context: context) + return lhs } @usableFromInline - package convenience init( + package init( hashing msg: MessageBytes, to group: BoringSSLEllipticCurveGroup, domainSeparationTag: DSTBytes ) throws { - let hashToCurveFunction = - switch group.curveName { - case .p256: CCryptoBoringSSLShims_EC_hash_to_curve_p256_xmd_sha256_sswu - case .p384: CCryptoBoringSSLShims_EC_hash_to_curve_p384_xmd_sha384_sswu - case .p521: throw CryptoBoringWrapperError.invalidParameter // BoringSSL has no P521 hash_to_curve API. - case .none: throw CryptoBoringWrapperError.internalBoringSSLError() - } - - try self.init(_pointAtInfinityOn: group) - try msg.withUnsafeBytes { msgPtr in - try group.withUnsafeGroupPointer { groupPtr in - try domainSeparationTag.withUnsafeBytes { dstPtr in - guard - hashToCurveFunction( - groupPtr, - self._basePoint, - dstPtr.baseAddress, - dstPtr.count, - msgPtr.baseAddress, - msgPtr.count - ) == 1 - else { throw CryptoBoringWrapperError.internalBoringSSLError() } - } - } - } + self.backing = try .init(hashing: msg, to: group, domainSeparationTag: domainSeparationTag) } @usableFromInline @@ -308,110 +226,289 @@ package final class EllipticCurvePoint { on group: BoringSSLEllipticCurveGroup, context: FiniteFieldArithmeticContext? = nil ) -> Bool { - self.withPointPointer { selfPtr in - group.withUnsafeGroupPointer { groupPtr in - rhs.withPointPointer { rhsPtr in - switch CCryptoBoringSSL_EC_POINT_cmp(groupPtr, selfPtr, rhsPtr, context?.bnCtx) { - case 0: return true - case 1: return false - default: - // EC_POINT_cmp returns an error when comparing points on different groups. - // We treat that as not equal, so we'll just clear the error and return false. - CCryptoBoringSSL_ERR_clear_error() - return false - } - } - } - } + self.backing.isEqual(to: rhs, on: group, context: context) } @usableFromInline - package convenience init( + package init( x962Representation bytes: Bytes, on group: BoringSSLEllipticCurveGroup, context: FiniteFieldArithmeticContext? = nil ) throws { - try self.init(_pointAtInfinityOn: group) - guard - group.withUnsafeGroupPointer({ groupPtr in - bytes.withUnsafeBytes { dataPtr in - CCryptoBoringSSL_EC_POINT_oct2point( - groupPtr, - self._basePoint, - dataPtr.baseAddress, - dataPtr.count, - context?.bnCtx - ) - } - }) == 1 - else { - throw CryptoBoringWrapperError.invalidParameter - } + self.backing = try .init(x962Representation: bytes, on: group, context: context) } @usableFromInline - package func x962RepresentationByteCount( + package func x962Representation( compressed: Bool, on group: BoringSSLEllipticCurveGroup, context: FiniteFieldArithmeticContext? = nil - ) throws -> Int { - let numBytesNeeded = group.withUnsafeGroupPointer { groupPtr in - CCryptoBoringSSL_EC_POINT_point2oct( - groupPtr, - self._basePoint, - compressed ? POINT_CONVERSION_COMPRESSED : POINT_CONVERSION_UNCOMPRESSED, - nil, - 0, - context?.bnCtx - ) - } - guard numBytesNeeded != 0 else { - throw CryptoBoringWrapperError.internalBoringSSLError() + ) throws -> Data { + try self.backing.x962Representation(compressed: compressed, on: group, context: context) + } + + private mutating func cowIfNeeded(on group: BoringSSLEllipticCurveGroup) throws { + if !isKnownUniquelyReferenced(&self.backing) { + self.backing = try .init(copying: self.backing, on: group) } - return numBytesNeeded } +} +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension EllipticCurvePoint { @usableFromInline - package func x962Representation( - compressed: Bool, - on group: BoringSSLEllipticCurveGroup, - context: FiniteFieldArithmeticContext? = nil - ) throws -> Data { - let numBytesNeeded = try self.x962RepresentationByteCount(compressed: compressed, on: group, context: context) + final class Backing { + @usableFromInline + let _basePoint: OpaquePointer - var buf = Data(repeating: 0, count: numBytesNeeded) + fileprivate init(copying pointer: OpaquePointer, on group: BoringSSLEllipticCurveGroup) throws { + self._basePoint = try group.withUnsafeGroupPointer { groupPtr in + guard let pointPtr = CCryptoBoringSSL_EC_POINT_dup(pointer, groupPtr) else { + throw CryptoBoringWrapperError.internalBoringSSLError() + } + return pointPtr + } + } - let numBytesWritten = group.withUnsafeGroupPointer { groupPtr in - buf.withUnsafeMutableBytes { bufPtr in - CCryptoBoringSSLShims_EC_POINT_point2oct( + fileprivate convenience init( + copying other: Backing, + on group: BoringSSLEllipticCurveGroup + ) + throws + { + try self.init(copying: other._basePoint, on: group) + } + + fileprivate init(_pointAtInfinityOn group: BoringSSLEllipticCurveGroup) throws { + self._basePoint = try group.withUnsafeGroupPointer { groupPtr in + guard let pointPtr = CCryptoBoringSSL_EC_POINT_new(groupPtr) else { + throw CryptoBoringWrapperError.internalBoringSSLError() + } + return pointPtr + } + } + + fileprivate init(_generatorOf groupPtr: OpaquePointer) throws { + guard + let generatorPtr = CCryptoBoringSSL_EC_GROUP_get0_generator(groupPtr), + let pointPtr = CCryptoBoringSSL_EC_POINT_dup(generatorPtr, groupPtr) + else { + throw CryptoBoringWrapperError.internalBoringSSLError() + } + self._basePoint = pointPtr + } + + fileprivate convenience init( + multiplying scalar: ArbitraryPrecisionInteger, + on group: BoringSSLEllipticCurveGroup, + context: FiniteFieldArithmeticContext? = nil + ) throws { + try self.init(_pointAtInfinityOn: group) + try group.withUnsafeGroupPointer { groupPtr in + try scalar.withUnsafeBignumPointer { scalarPtr in + guard + CCryptoBoringSSL_EC_POINT_mul(groupPtr, self._basePoint, scalarPtr, nil, nil, context?.bnCtx) + == 1 + else { + throw CryptoBoringWrapperError.internalBoringSSLError() + } + } + } + } + + deinit { + CCryptoBoringSSL_EC_POINT_free(self._basePoint) + } + + fileprivate func multiply( + by rhs: ArbitraryPrecisionInteger, + on group: BoringSSLEllipticCurveGroup, + context: FiniteFieldArithmeticContext? = nil + ) throws { + try self.withPointPointer { selfPtr in + try rhs.withUnsafeBignumPointer { rhsPtr in + try group.withUnsafeGroupPointer { groupPtr in + guard + CCryptoBoringSSL_EC_POINT_mul(groupPtr, selfPtr, nil, selfPtr, rhsPtr, context?.bnCtx) != 0 + else { + throw CryptoBoringWrapperError.internalBoringSSLError() + } + } + } + } + } + + fileprivate func add( + _ rhs: EllipticCurvePoint, + on group: BoringSSLEllipticCurveGroup, + context: FiniteFieldArithmeticContext? = nil + ) throws { + try self.withPointPointer { selfPtr in + try group.withUnsafeGroupPointer { groupPtr in + try rhs.withPointPointer { rhsPtr in + guard CCryptoBoringSSL_EC_POINT_add(groupPtr, selfPtr, selfPtr, rhsPtr, context?.bnCtx) != 0 + else { + throw CryptoBoringWrapperError.internalBoringSSLError() + } + } + } + } + } + + internal func invert(on group: BoringSSLEllipticCurveGroup, context: FiniteFieldArithmeticContext? = nil) throws + { + try self.withPointPointer { selfPtr in + try group.withUnsafeGroupPointer { groupPtr in + guard CCryptoBoringSSL_EC_POINT_invert(groupPtr, selfPtr, context?.bnCtx) != 0 else { + throw CryptoBoringWrapperError.internalBoringSSLError() + } + } + } + } + + fileprivate convenience init( + hashing msg: MessageBytes, + to group: BoringSSLEllipticCurveGroup, + domainSeparationTag: DSTBytes + ) throws { + let hashToCurveFunction = + switch group.curveName { + case .p256: CCryptoBoringSSLShims_EC_hash_to_curve_p256_xmd_sha256_sswu + case .p384: CCryptoBoringSSLShims_EC_hash_to_curve_p384_xmd_sha384_sswu + // BoringSSL has no P521 hash_to_curve API. + case .p521: throw CryptoBoringWrapperError.invalidParameter + case .none: throw CryptoBoringWrapperError.internalBoringSSLError() + } + + try self.init(_pointAtInfinityOn: group) + try msg.withUnsafeBytes { msgPtr in + try group.withUnsafeGroupPointer { groupPtr in + try domainSeparationTag.withUnsafeBytes { dstPtr in + guard + hashToCurveFunction( + groupPtr, + self._basePoint, + dstPtr.baseAddress, + dstPtr.count, + msgPtr.baseAddress, + msgPtr.count + ) == 1 + else { throw CryptoBoringWrapperError.internalBoringSSLError() } + } + } + } + } + + fileprivate func isEqual( + to rhs: EllipticCurvePoint, + on group: BoringSSLEllipticCurveGroup, + context: FiniteFieldArithmeticContext? = nil + ) -> Bool { + self.withPointPointer { selfPtr in + group.withUnsafeGroupPointer { groupPtr in + rhs.withPointPointer { rhsPtr in + switch CCryptoBoringSSL_EC_POINT_cmp(groupPtr, selfPtr, rhsPtr, context?.bnCtx) { + case 0: return true + case 1: return false + default: + // EC_POINT_cmp returns an error when comparing points on different groups. + // We treat that as not equal, so we'll just clear the error and return false. + CCryptoBoringSSL_ERR_clear_error() + return false + } + } + } + } + } + + fileprivate convenience init( + x962Representation bytes: Bytes, + on group: BoringSSLEllipticCurveGroup, + context: FiniteFieldArithmeticContext? = nil + ) throws { + try self.init(_pointAtInfinityOn: group) + guard + group.withUnsafeGroupPointer({ groupPtr in + bytes.withUnsafeBytes { dataPtr in + CCryptoBoringSSL_EC_POINT_oct2point( + groupPtr, + self._basePoint, + dataPtr.baseAddress, + dataPtr.count, + context?.bnCtx + ) + } + }) == 1 + else { + throw CryptoBoringWrapperError.invalidParameter + } + } + + private func x962RepresentationByteCount( + compressed: Bool, + on group: BoringSSLEllipticCurveGroup, + context: FiniteFieldArithmeticContext? = nil + ) throws -> Int { + let numBytesNeeded = group.withUnsafeGroupPointer { groupPtr in + CCryptoBoringSSL_EC_POINT_point2oct( groupPtr, self._basePoint, compressed ? POINT_CONVERSION_COMPRESSED : POINT_CONVERSION_UNCOMPRESSED, - bufPtr.baseAddress, - numBytesNeeded, + nil, + 0, context?.bnCtx ) } + guard numBytesNeeded != 0 else { + throw CryptoBoringWrapperError.internalBoringSSLError() + } + return numBytesNeeded } - guard numBytesWritten == numBytesNeeded else { - throw CryptoBoringWrapperError.internalBoringSSLError() - } - return buf + fileprivate func x962Representation( + compressed: Bool, + on group: BoringSSLEllipticCurveGroup, + context: FiniteFieldArithmeticContext? = nil + ) throws -> Data { + let numBytesNeeded = try self.x962RepresentationByteCount( + compressed: compressed, + on: group, + context: context + ) + + var buf = Data(repeating: 0, count: numBytesNeeded) + + let numBytesWritten = group.withUnsafeGroupPointer { groupPtr in + buf.withUnsafeMutableBytes { bufPtr in + CCryptoBoringSSLShims_EC_POINT_point2oct( + groupPtr, + self._basePoint, + compressed ? POINT_CONVERSION_COMPRESSED : POINT_CONVERSION_UNCOMPRESSED, + bufPtr.baseAddress, + numBytesNeeded, + context?.bnCtx + ) + } + } + guard numBytesWritten == numBytesNeeded else { + throw CryptoBoringWrapperError.internalBoringSSLError() + } + + return buf + } } } // MARK: - Helpers @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -extension EllipticCurvePoint { +extension EllipticCurvePoint.Backing { @inlinable package func withPointPointer(_ body: (OpaquePointer) throws -> T) rethrows -> T { try body(self._basePoint) } - @usableFromInline - package func affineCoordinates( + fileprivate func affineCoordinates( group: BoringSSLEllipticCurveGroup ) throws -> ( x: ArbitraryPrecisionInteger, y: ArbitraryPrecisionInteger @@ -440,3 +537,20 @@ extension EllipticCurvePoint { return (x: x, y: y) } } + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension EllipticCurvePoint { + @inlinable + package func withPointPointer(_ body: (OpaquePointer) throws -> T) rethrows -> T { + try self.backing.withPointPointer(body) + } + + @usableFromInline + package func affineCoordinates( + group: BoringSSLEllipticCurveGroup + ) throws -> ( + x: ArbitraryPrecisionInteger, y: ArbitraryPrecisionInteger + ) { + try self.backing.affineCoordinates(group: group) + } +} diff --git a/Sources/CryptoBoringWrapper/Util/ArbitraryPrecisionInteger.swift b/Sources/CryptoBoringWrapper/Util/ArbitraryPrecisionInteger.swift index 505e54abd..aaa2fd21f 100644 --- a/Sources/CryptoBoringWrapper/Util/ArbitraryPrecisionInteger.swift +++ b/Sources/CryptoBoringWrapper/Util/ArbitraryPrecisionInteger.swift @@ -26,7 +26,7 @@ import Foundation /// and that provides better Swift types for this object. @usableFromInline @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -package struct ArbitraryPrecisionInteger { +package struct ArbitraryPrecisionInteger: @unchecked Sendable { private var _backing: BackingStorage @usableFromInline diff --git a/Tests/CryptoBoringWrapperTests/EllipticCurvePointTests.swift b/Tests/CryptoBoringWrapperTests/EllipticCurvePointTests.swift new file mode 100644 index 000000000..4c08fd9a9 --- /dev/null +++ b/Tests/CryptoBoringWrapperTests/EllipticCurvePointTests.swift @@ -0,0 +1,60 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2025 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import CryptoBoringWrapper +import XCTest + +final class EllipticCurvePointTests: XCTestCase { + static let p256 = try! BoringSSLEllipticCurveGroup(.p256) + + func testRepeatedMultiplyHasValueSemantics() throws { + let point = Self.p256.generator + var copy = point + try copy.multiply(by: 2, on: Self.p256) + try copy.multiply(by: 2, on: Self.p256) + + XCTAssertTrue(!copy.isEqual(to: point, on: Self.p256)) + XCTAssertTrue(try copy.isEqual(to: point.multiplying(by: 4, on: Self.p256), on: Self.p256)) + } + + func testAddHasValueSemantics() throws { + let point = Self.p256.generator + var other = point + try other.add(point, on: Self.p256) + + XCTAssertTrue(!other.isEqual(to: point, on: Self.p256)) + XCTAssertTrue(try other.isEqual(to: point.adding(point, on: Self.p256), on: Self.p256)) + } + + func testInvertingHasValueSemantics() throws { + let point = try Self.p256.generator.multiplying( + by: 2, + on: Self.p256 + ) + var other = point + try other.invert(on: Self.p256) + + XCTAssertTrue(!other.isEqual(to: point, on: Self.p256)) + XCTAssertTrue(try other.isEqual(to: point.inverting(on: Self.p256), on: Self.p256)) + } + + func testSubtractHasValueSemantics() throws { + let point = Self.p256.generator + var other = point + try other.subtract(point, on: Self.p256) + + XCTAssertTrue(!other.isEqual(to: point, on: Self.p256)) + XCTAssertTrue(try other.isEqual(to: point.subtracting(point, on: Self.p256), on: Self.p256)) + } +} From 9b0697120ab72d45610b4282ad8aa58389bce526 Mon Sep 17 00:00:00 2001 From: Cory Benfield Date: Mon, 23 Jun 2025 09:47:46 +0100 Subject: [PATCH 19/47] Adopt Swift 6 mode (#368) Motivation The Swift 6 language mode adopts data-race safety by default. While Swift Crypto itself has no concurrent code, it is still useful to force us to ensure that our code is properly Sendable-correct. Modifications - @unchecked Sendable on several CoW data types - Some necessary Sendable constraints on ECToolbox protocols - Add some missing protocol constraints on ARC types. Result Swift 6 clean. --- Package.swift | 6 ++- .../Digests/BoringSSL/Digest_boring.swift | 2 +- .../Crypto/KEM/BoringSSL/MLKEM_boring.swift | 8 +-- .../KEM/BoringSSL/MLKEM_boring.swift.gyb | 11 +--- .../Crypto/KEM/BoringSSL/MLKEM_wrapper.swift | 11 ++-- .../Keys/EC/BoringSSL/Ed25519_boring.swift | 4 +- .../EC/BoringSSL/NISTCurvesKeys_boring.swift | 12 ++--- .../Keys/EC/BoringSSL/X25519Keys_boring.swift | 4 +- .../Signatures/BoringSSL/MLDSA_boring.swift | 8 +-- .../BoringSSL/MLDSA_boring.swift.gyb | 4 +- .../Signatures/BoringSSL/MLDSA_wrapper.swift | 4 +- .../EC/EllipticCurve.swift | 2 +- .../Util/FiniteFieldArithmeticContext.swift | 6 +-- .../_CryptoExtras/ARC/ARCPrecredential.swift | 2 +- Sources/_CryptoExtras/ARC/ARCServer.swift | 2 +- .../_CryptoExtras/ECToolbox/ECToolbox.swift | 4 +- Sources/_CryptoExtras/RSA/RSA_boring.swift | 4 +- Sources/_CryptoExtras/Util/DigestType.swift | 8 +-- .../AES-GCM-Runner.swift | 3 +- .../ChaChaPoly-Runner.swift | 3 +- Tests/CryptoTests/Digests/DigestsTests.swift | 2 +- .../BoringSSL/secpECDH_Runner_boring.swift | 6 +-- .../ECprivateKeysFromSeeds.swift | 51 ------------------- Tests/CryptoTests/MAC/HMACTests.swift | 2 +- .../ECDSA/ECDSASignatureTests.swift | 2 +- .../ECDSA/RawECDSASignaturesTests.swift | 4 +- .../Signatures/EdDSA/Ed25519-Runner.swift | 2 +- Tests/CryptoTests/Utils/RFCVector.swift | 2 +- Tests/CryptoTests/Utils/Wycheproof.swift | 4 +- Tests/CryptoTests/Utils/XCTestUtils.swift | 6 +-- .../AES-GCM-SIV-Runner.swift | 2 +- Tests/_CryptoExtrasTests/MLDSATests.swift | 4 +- Tests/_CryptoExtrasTests/MLKEMTests.swift | 20 ++++++-- .../OPRFs/VOPRFAPITests.swift | 2 +- .../TestRSABlindSigning.swift | 2 +- .../_CryptoExtrasTests/Utils/RFCVector.swift | 2 +- .../_CryptoExtrasTests/Utils/Wycheproof.swift | 4 +- .../Utils/XCTestUtils.swift | 4 +- 38 files changed, 95 insertions(+), 134 deletions(-) delete mode 100644 Tests/CryptoTests/Key Derivation/ECprivateKeysFromSeeds.swift diff --git a/Package.swift b/Package.swift index 4f177f4ac..3d92c6858 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:5.10 +// swift-tools-version:6.0 //===----------------------------------------------------------------------===// // // This source file is part of the SwiftCrypto open source project @@ -142,6 +142,10 @@ let package = Package( "Digests/Digests.swift.gyb", "Key Agreement/ECDH.swift.gyb", "Signatures/ECDSA.swift.gyb", + "Signatures/MLDSA.swift.gyb", + "Signatures/BoringSSL/MLDSA_boring.swift.gyb", + "KEM/MLKEM.swift.gyb", + "KEM/BoringSSL/MLKEM_boring.swift.gyb", ], resources: privacyManifestResource, swiftSettings: swiftSettings diff --git a/Sources/Crypto/Digests/BoringSSL/Digest_boring.swift b/Sources/Crypto/Digests/BoringSSL/Digest_boring.swift index b6e759cf2..479190155 100644 --- a/Sources/Crypto/Digests/BoringSSL/Digest_boring.swift +++ b/Sources/Crypto/Digests/BoringSSL/Digest_boring.swift @@ -144,7 +144,7 @@ extension SHA512: BoringSSLBackedHashFunction { } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -struct OpenSSLDigestImpl { +struct OpenSSLDigestImpl: @unchecked Sendable { private var context: DigestContext init() { diff --git a/Sources/Crypto/KEM/BoringSSL/MLKEM_boring.swift b/Sources/Crypto/KEM/BoringSSL/MLKEM_boring.swift index ae7690c33..77b6d6cbe 100644 --- a/Sources/Crypto/KEM/BoringSSL/MLKEM_boring.swift +++ b/Sources/Crypto/KEM/BoringSSL/MLKEM_boring.swift @@ -29,7 +29,7 @@ import Foundation @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLKEM768 { /// A ML-KEM-768 private key. - struct InternalPrivateKey: Sendable, KEMPrivateKey { + struct InternalPrivateKey: @unchecked Sendable, KEMPrivateKey { private var backing: Backing /// Initialize a ML-KEM-768 private key from a random seed. @@ -175,7 +175,7 @@ extension MLKEM768 { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLKEM768 { /// A ML-KEM-768 public key. - struct InternalPublicKey: Sendable, KEMPublicKey { + struct InternalPublicKey: @unchecked Sendable, KEMPublicKey { private var backing: Backing fileprivate init(privateKeyBacking: InternalPrivateKey.Backing) { @@ -296,7 +296,7 @@ extension MLKEM768 { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLKEM1024 { /// A ML-KEM-1024 private key. - struct InternalPrivateKey: Sendable, KEMPrivateKey { + struct InternalPrivateKey: @unchecked Sendable, KEMPrivateKey { private var backing: Backing /// Initialize a ML-KEM-1024 private key from a random seed. @@ -442,7 +442,7 @@ extension MLKEM1024 { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLKEM1024 { /// A ML-KEM-1024 public key. - struct InternalPublicKey: Sendable, KEMPublicKey { + struct InternalPublicKey: @unchecked Sendable, KEMPublicKey { private var backing: Backing fileprivate init(privateKeyBacking: InternalPrivateKey.Backing) { diff --git a/Sources/Crypto/KEM/BoringSSL/MLKEM_boring.swift.gyb b/Sources/Crypto/KEM/BoringSSL/MLKEM_boring.swift.gyb index 979cf314b..112376e5d 100644 --- a/Sources/Crypto/KEM/BoringSSL/MLKEM_boring.swift.gyb +++ b/Sources/Crypto/KEM/BoringSSL/MLKEM_boring.swift.gyb @@ -33,7 +33,7 @@ import Foundation @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLKEM${parameter_set} { /// A ML-KEM-${parameter_set} private key. - struct InternalPrivateKey: Sendable, KEMPrivateKey { + struct InternalPrivateKey: @unchecked Sendable, KEMPrivateKey { private var backing: Backing /// Initialize a ML-KEM-${parameter_set} private key from a random seed. @@ -179,7 +179,7 @@ extension MLKEM${parameter_set} { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLKEM${parameter_set} { /// A ML-KEM-${parameter_set} public key. - struct InternalPublicKey: Sendable, KEMPublicKey { + struct InternalPublicKey: @unchecked Sendable, KEMPublicKey { private var backing: Backing fileprivate init(privateKeyBacking: InternalPrivateKey.Backing) { @@ -207,13 +207,6 @@ extension MLKEM${parameter_set} { self.backing.encapsulate() } - /// Encapsulate a shared secret using a fixed RNG result. - /// - /// - Returns: The shared secret and its encapsulated version. - func encapsulateWithSeed(_ encapWithSeed: Data) -> KEM.EncapsulationResult { - self.backing.encapsulate(encapWithSeed) - } - /// The size of the public key in bytes. static let byteCount = Backing.byteCount diff --git a/Sources/Crypto/KEM/BoringSSL/MLKEM_wrapper.swift b/Sources/Crypto/KEM/BoringSSL/MLKEM_wrapper.swift index 9fc83b433..3306cedd6 100644 --- a/Sources/Crypto/KEM/BoringSSL/MLKEM_wrapper.swift +++ b/Sources/Crypto/KEM/BoringSSL/MLKEM_wrapper.swift @@ -23,7 +23,7 @@ import Foundation #endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -protocol BoringSSLBackedMLKEMPrivateKey { +protocol BoringSSLBackedMLKEMPrivateKey: Sendable { associatedtype InteriorPublicKey: BoringSSLBackedMLKEMPublicKey static func generatePrivateKey() throws -> Self @@ -51,7 +51,7 @@ extension BoringSSLBackedMLKEMPrivateKey { } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -protocol BoringSSLBackedMLKEMPublicKey { +protocol BoringSSLBackedMLKEMPublicKey: Sendable { init(rawRepresentation: Bytes) throws var rawRepresentation: Data { get } @@ -62,7 +62,7 @@ protocol BoringSSLBackedMLKEMPublicKey { } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -protocol BoringSSLBackedMLKEMOuterPublicKey { +protocol BoringSSLBackedMLKEMOuterPublicKey: Sendable { init(rawRepresentation: Data) throws } @@ -181,7 +181,7 @@ extension MLKEM1024.InternalPublicKey: BoringSSLBackedMLKEMPublicKey { } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -struct OpenSSLMLKEMPublicKeyImpl: BoringSSLBackedMLKEMPublicKey { +struct OpenSSLMLKEMPublicKeyImpl: BoringSSLBackedMLKEMPublicKey, Sendable { private var backing: Parameters.BackingPublicKey init(backing: Parameters.BackingPublicKey) { @@ -206,7 +206,8 @@ struct OpenSSLMLKEMPublicKeyImpl: Bo } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -struct OpenSSLMLKEMPrivateKeyImpl: BoringSSLBackedMLKEMPrivateKey { +struct OpenSSLMLKEMPrivateKeyImpl: BoringSSLBackedMLKEMPrivateKey, Sendable +{ typealias InteriorPublicKey = OpenSSLMLKEMPublicKeyImpl private var backing: Parameters.BackingPrivateKey diff --git a/Sources/Crypto/Keys/EC/BoringSSL/Ed25519_boring.swift b/Sources/Crypto/Keys/EC/BoringSSL/Ed25519_boring.swift index 4ed7ea723..037de26f6 100644 --- a/Sources/Crypto/Keys/EC/BoringSSL/Ed25519_boring.swift +++ b/Sources/Crypto/Keys/EC/BoringSSL/Ed25519_boring.swift @@ -27,7 +27,7 @@ import Foundation extension Curve25519.Signing { @usableFromInline @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - struct OpenSSLCurve25519PrivateKeyImpl { + struct OpenSSLCurve25519PrivateKeyImpl: Sendable { var _privateKey: SecureBytes @usableFromInline var _publicKey: [UInt8] @@ -99,7 +99,7 @@ extension Curve25519.Signing { @usableFromInline @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - struct OpenSSLCurve25519PublicKeyImpl { + struct OpenSSLCurve25519PublicKeyImpl: Sendable { @usableFromInline var keyBytes: [UInt8] diff --git a/Sources/Crypto/Keys/EC/BoringSSL/NISTCurvesKeys_boring.swift b/Sources/Crypto/Keys/EC/BoringSSL/NISTCurvesKeys_boring.swift index 11441322e..ce159e391 100644 --- a/Sources/Crypto/Keys/EC/BoringSSL/NISTCurvesKeys_boring.swift +++ b/Sources/Crypto/Keys/EC/BoringSSL/NISTCurvesKeys_boring.swift @@ -64,7 +64,7 @@ extension P521: OpenSSLSupportedNISTCurve { @usableFromInline @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -struct OpenSSLNISTCurvePrivateKeyImpl { +struct OpenSSLNISTCurvePrivateKeyImpl: Sendable { @usableFromInline var key: BoringSSLECPrivateKeyWrapper @@ -95,7 +95,7 @@ struct OpenSSLNISTCurvePrivateKeyImpl { @usableFromInline @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -struct OpenSSLNISTCurvePublicKeyImpl { +struct OpenSSLNISTCurvePublicKeyImpl: Sendable { @usableFromInline var key: BoringSSLECPublicKeyWrapper @@ -145,9 +145,9 @@ struct OpenSSLNISTCurvePublicKeyImpl { /// allows some helper operations. @usableFromInline @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -class BoringSSLECPrivateKeyWrapper { +class BoringSSLECPrivateKeyWrapper: @unchecked Sendable { @usableFromInline - var key: OpaquePointer + let key: OpaquePointer init(compactRepresentable: Bool) throws { // We cannot handle allocation failure. @@ -350,9 +350,9 @@ class BoringSSLECPrivateKeyWrapper { /// allows some helper operations. @usableFromInline @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -class BoringSSLECPublicKeyWrapper { +class BoringSSLECPublicKeyWrapper: @unchecked Sendable { @usableFromInline - var key: OpaquePointer + let key: OpaquePointer init(compactRepresentation bytes: Bytes) throws { let group = Curve.group diff --git a/Sources/Crypto/Keys/EC/BoringSSL/X25519Keys_boring.swift b/Sources/Crypto/Keys/EC/BoringSSL/X25519Keys_boring.swift index b51db37de..df7807cdc 100644 --- a/Sources/Crypto/Keys/EC/BoringSSL/X25519Keys_boring.swift +++ b/Sources/Crypto/Keys/EC/BoringSSL/X25519Keys_boring.swift @@ -29,7 +29,7 @@ extension Curve25519.KeyAgreement { @usableFromInline @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - struct OpenSSLCurve25519PublicKeyImpl { + struct OpenSSLCurve25519PublicKeyImpl: Sendable { @usableFromInline var keyBytes: [UInt8] @@ -57,7 +57,7 @@ extension Curve25519.KeyAgreement { @usableFromInline @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - struct OpenSSLCurve25519PrivateKeyImpl { + struct OpenSSLCurve25519PrivateKeyImpl: Sendable { var key: SecureBytes @usableFromInline diff --git a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift index c058e71cc..bfba93044 100644 --- a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift +++ b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift @@ -36,7 +36,7 @@ import Foundation @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLDSA65 { /// A ML-DSA-65 private key. - struct InternalPrivateKey: Sendable { + struct InternalPrivateKey: @unchecked Sendable { private var backing: Backing /// Initialize a ML-DSA-65 private key from a random seed. @@ -193,7 +193,7 @@ extension MLDSA65 { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLDSA65 { /// A ML-DSA-65 public key. - struct InternalPublicKey: Sendable { + struct InternalPublicKey: @unchecked Sendable { private var backing: Backing fileprivate init(privateKeyBacking: InternalPrivateKey.Backing) { @@ -338,7 +338,7 @@ extension MLDSA65 { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLDSA87 { /// A ML-DSA-87 private key. - struct InternalPrivateKey: Sendable { + struct InternalPrivateKey: @unchecked Sendable { private var backing: Backing /// Initialize a ML-DSA-87 private key from a random seed. @@ -495,7 +495,7 @@ extension MLDSA87 { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLDSA87 { /// A ML-DSA-87 public key. - struct InternalPublicKey: Sendable { + struct InternalPublicKey: @unchecked Sendable { private var backing: Backing fileprivate init(privateKeyBacking: InternalPrivateKey.Backing) { diff --git a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb index c9d42191b..ee0b1f0c8 100644 --- a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb +++ b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb @@ -40,7 +40,7 @@ import Foundation @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLDSA${parameter_set} { /// A ML-DSA-${parameter_set} private key. - struct InternalPrivateKey: Sendable { + struct InternalPrivateKey: @unchecked Sendable { private var backing: Backing /// Initialize a ML-DSA-${parameter_set} private key from a random seed. @@ -197,7 +197,7 @@ extension MLDSA${parameter_set} { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLDSA${parameter_set} { /// A ML-DSA-${parameter_set} public key. - struct InternalPublicKey: Sendable { + struct InternalPublicKey: @unchecked Sendable { private var backing: Backing fileprivate init(privateKeyBacking: InternalPrivateKey.Backing) { diff --git a/Sources/Crypto/Signatures/BoringSSL/MLDSA_wrapper.swift b/Sources/Crypto/Signatures/BoringSSL/MLDSA_wrapper.swift index c8171c6b4..671847b3e 100644 --- a/Sources/Crypto/Signatures/BoringSSL/MLDSA_wrapper.swift +++ b/Sources/Crypto/Signatures/BoringSSL/MLDSA_wrapper.swift @@ -23,7 +23,7 @@ import Foundation #endif @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -protocol BoringSSLBackedMLDSAPrivateKey { +protocol BoringSSLBackedMLDSAPrivateKey: Sendable { associatedtype AssociatedPublicKey: BoringSSLBackedMLDSAPublicKey init() throws @@ -40,7 +40,7 @@ protocol BoringSSLBackedMLDSAPrivateKey { } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -protocol BoringSSLBackedMLDSAPublicKey { +protocol BoringSSLBackedMLDSAPublicKey: Sendable { init(rawRepresentation: D) throws func isValidSignature(_: S, for data: D) -> Bool diff --git a/Sources/CryptoBoringWrapper/EC/EllipticCurve.swift b/Sources/CryptoBoringWrapper/EC/EllipticCurve.swift index 7358ddb86..c333ecbd2 100644 --- a/Sources/CryptoBoringWrapper/EC/EllipticCurve.swift +++ b/Sources/CryptoBoringWrapper/EC/EllipticCurve.swift @@ -17,7 +17,7 @@ /// liveness. @usableFromInline @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -package final class BoringSSLEllipticCurveGroup { +package final class BoringSSLEllipticCurveGroup: @unchecked Sendable { @usableFromInline var _group: OpaquePointer @usableFromInline package let order: ArbitraryPrecisionInteger diff --git a/Sources/CryptoBoringWrapper/Util/FiniteFieldArithmeticContext.swift b/Sources/CryptoBoringWrapper/Util/FiniteFieldArithmeticContext.swift index f5c6d435c..39e62b2d9 100644 --- a/Sources/CryptoBoringWrapper/Util/FiniteFieldArithmeticContext.swift +++ b/Sources/CryptoBoringWrapper/Util/FiniteFieldArithmeticContext.swift @@ -34,9 +34,9 @@ import Foundation /// ourselves. @usableFromInline @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -package class FiniteFieldArithmeticContext { - private var fieldSize: ArbitraryPrecisionInteger - package var bnCtx: OpaquePointer +package class FiniteFieldArithmeticContext: @unchecked Sendable { + private let fieldSize: ArbitraryPrecisionInteger + package let bnCtx: OpaquePointer @usableFromInline package init(fieldSize: ArbitraryPrecisionInteger) throws { diff --git a/Sources/_CryptoExtras/ARC/ARCPrecredential.swift b/Sources/_CryptoExtras/ARC/ARCPrecredential.swift index 27c5c5ac7..b1281fa95 100644 --- a/Sources/_CryptoExtras/ARC/ARCPrecredential.swift +++ b/Sources/_CryptoExtras/ARC/ARCPrecredential.swift @@ -20,7 +20,7 @@ import Foundation @available(macOS 10.15, iOS 13.2, tvOS 13.2, watchOS 6.1, macCatalyst 13.2, visionOS 1.2, *) extension ARC { - struct ClientSecrets { + struct ClientSecrets { let m1: Scalar // secret at request and verification let m2: Scalar // secret at request, public at verification (server expected to know value) let r1: Scalar // secret blinding factor for m1 diff --git a/Sources/_CryptoExtras/ARC/ARCServer.swift b/Sources/_CryptoExtras/ARC/ARCServer.swift index 53f890046..8d4bef6b0 100644 --- a/Sources/_CryptoExtras/ARC/ARCServer.swift +++ b/Sources/_CryptoExtras/ARC/ARCServer.swift @@ -20,7 +20,7 @@ import Foundation @available(macOS 10.15, iOS 13.2, tvOS 13.2, watchOS 6.1, macCatalyst 13.2, visionOS 1.2, *) extension ARC { - struct ServerPrivateKey { + struct ServerPrivateKey { let x0: Scalar let x1: Scalar let x2: Scalar diff --git a/Sources/_CryptoExtras/ECToolbox/ECToolbox.swift b/Sources/_CryptoExtras/ECToolbox/ECToolbox.swift index 452ed640f..a1eb80e90 100644 --- a/Sources/_CryptoExtras/ECToolbox/ECToolbox.swift +++ b/Sources/_CryptoExtras/ECToolbox/ECToolbox.swift @@ -57,7 +57,7 @@ protocol HashToGroup { } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -protocol GroupScalar { +protocol GroupScalar: Sendable { init(bytes: Data, reductionIsModOrder: Bool) throws var rawRepresentation: Data { get } @@ -80,7 +80,7 @@ protocol GroupScalar { } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -protocol GroupElement { +protocol GroupElement: Sendable { associatedtype Scalar: GroupScalar static var generator: Self { get } diff --git a/Sources/_CryptoExtras/RSA/RSA_boring.swift b/Sources/_CryptoExtras/RSA/RSA_boring.swift index fae4da655..b35743f53 100644 --- a/Sources/_CryptoExtras/RSA/RSA_boring.swift +++ b/Sources/_CryptoExtras/RSA/RSA_boring.swift @@ -200,7 +200,7 @@ extension BoringSSLRSAPublicKey { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension BoringSSLRSAPublicKey { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - fileprivate final class Backing { + fileprivate final class Backing: @unchecked Sendable { private let pointer: OpaquePointer fileprivate init(takingOwnershipOf pointer: OpaquePointer) { @@ -571,7 +571,7 @@ extension BoringSSLRSAPublicKey { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension BoringSSLRSAPrivateKey { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - fileprivate final class Backing { + fileprivate final class Backing: @unchecked Sendable { private let pointer: OpaquePointer fileprivate init(copying other: Backing) { diff --git a/Sources/_CryptoExtras/Util/DigestType.swift b/Sources/_CryptoExtras/Util/DigestType.swift index e4d268a57..469c56873 100644 --- a/Sources/_CryptoExtras/Util/DigestType.swift +++ b/Sources/_CryptoExtras/Util/DigestType.swift @@ -17,12 +17,12 @@ import Crypto @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -struct DigestType { - var dispatchTable: OpaquePointer +struct DigestType: @unchecked Sendable { + let dispatchTable: OpaquePointer - var nid: CInt + let nid: CInt - var digestLength: Int + let digestLength: Int /// The dispatchtable pointer must have static storage and not be lifetime managed, /// as it is assumed to last for the duration of the program. diff --git a/Tests/CryptoTests/Authenticated Encryption/AES-GCM-Runner.swift b/Tests/CryptoTests/Authenticated Encryption/AES-GCM-Runner.swift index c51dd7dc4..0a1890a76 100644 --- a/Tests/CryptoTests/Authenticated Encryption/AES-GCM-Runner.swift +++ b/Tests/CryptoTests/Authenticated Encryption/AES-GCM-Runner.swift @@ -44,6 +44,7 @@ struct AESGCMTestVector: Codable { let result: String } +@available(iOS 17.4, macOS 14.4, watchOS 10.4, tvOS 17.4, macCatalyst 17.4, *) class AESGCMTests: XCTestCase { func testPropertiesStayTheSameAfterFailedOpening() throws { let message = Data("this is a message".utf8) @@ -156,7 +157,7 @@ class AESGCMTests: XCTestCase { } func testRoundTripDataProtocols() throws { - func roundTrip(message: Message, aad: AAD, file: StaticString = (#file), line: UInt = #line) throws { + func roundTrip(message: Message, aad: AAD, file: StaticString = (#filePath), line: UInt = #line) throws { let key = SymmetricKey(size: .bits256) let nonce = AES.GCM.Nonce() let ciphertext = try orFail(file: file, line: line) { try AES.GCM.seal(message, using: key, nonce: nonce, authenticating: aad) } diff --git a/Tests/CryptoTests/Authenticated Encryption/ChaChaPoly-Runner.swift b/Tests/CryptoTests/Authenticated Encryption/ChaChaPoly-Runner.swift index a36f0b55d..f0ccb430e 100644 --- a/Tests/CryptoTests/Authenticated Encryption/ChaChaPoly-Runner.swift +++ b/Tests/CryptoTests/Authenticated Encryption/ChaChaPoly-Runner.swift @@ -26,6 +26,7 @@ import CryptoKit import Crypto #endif +@available(iOS 17.4, macOS 14.4, watchOS 10.4, tvOS 17.4, macCatalyst 17.4, *) class ChaChaPolyTests: XCTestCase { func testIncorrectKeySize() throws { let plaintext: Data = "Some Super Secret Message".data(using: String.Encoding.utf8)! @@ -122,7 +123,7 @@ class ChaChaPolyTests: XCTestCase { } func testRoundTripDataProtocols() throws { - func roundTrip(message: Message, aad: AAD, file: StaticString = (#file), line: UInt = #line) throws { + func roundTrip(message: Message, aad: AAD, file: StaticString = (#filePath), line: UInt = #line) throws { let key = SymmetricKey(size: .bits256) let nonce = ChaChaPoly.Nonce() diff --git a/Tests/CryptoTests/Digests/DigestsTests.swift b/Tests/CryptoTests/Digests/DigestsTests.swift index 1bd5c7c39..0fc345df8 100644 --- a/Tests/CryptoTests/Digests/DigestsTests.swift +++ b/Tests/CryptoTests/Digests/DigestsTests.swift @@ -78,7 +78,7 @@ func testVectorForAlgorithm(hashFunction: H.Type) throws -> Str } class DigestsTests: XCTestCase { - func assertHashFunctionWithVector(hf: H.Type, data: Data, testVector: String, file: StaticString = (#file), line: UInt = #line) throws { + func assertHashFunctionWithVector(hf: H.Type, data: Data, testVector: String, file: StaticString = (#filePath), line: UInt = #line) throws { var h = hf.init() h.update(data: data) let result = h.finalize() diff --git a/Tests/CryptoTests/ECDH/BoringSSL/secpECDH_Runner_boring.swift b/Tests/CryptoTests/ECDH/BoringSSL/secpECDH_Runner_boring.swift index 6503f7d5c..d1d82af06 100644 --- a/Tests/CryptoTests/ECDH/BoringSSL/secpECDH_Runner_boring.swift +++ b/Tests/CryptoTests/ECDH/BoringSSL/secpECDH_Runner_boring.swift @@ -37,7 +37,7 @@ extension NISTECDHTests { group: ECDHTestGroup, privateKeys: PrivKey.Type, onCurve curve: Curve.Type, - file: StaticString = #file, + file: StaticString = #filePath, line: UInt = #line ) { for testVector in group.tests { @@ -89,7 +89,7 @@ extension NISTECDHTests { group: ECDHTestGroup, privateKeys: PrivKey.Type, onCurve curve: Curve.Type, - file: StaticString = #file, + file: StaticString = #filePath, line: UInt = #line ) { for testVector in group.tests { @@ -126,7 +126,7 @@ extension NISTECDHTests { private func padKeyIfNecessary( curve: Curve.Type, vector: String, - file: StaticString = #file, + file: StaticString = #filePath, line: UInt = #line ) throws -> [UInt8] { // There are a few edge cases here. diff --git a/Tests/CryptoTests/Key Derivation/ECprivateKeysFromSeeds.swift b/Tests/CryptoTests/Key Derivation/ECprivateKeysFromSeeds.swift deleted file mode 100644 index ef4d0cef2..000000000 --- a/Tests/CryptoTests/Key Derivation/ECprivateKeysFromSeeds.swift +++ /dev/null @@ -1,51 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the SwiftCrypto open source project -// -// Copyright (c) 2019-2020 Apple Inc. and the SwiftCrypto project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// -#if canImport(FoundationEssentials) -import FoundationEssentials -#else -import Foundation -#endif -import XCTest - -#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API -// Skip tests that require @testable imports of CryptoKit. -#else -#if !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API -@testable import CryptoKit -#else -@testable import Crypto -#endif - -extension CryptoKitError: Equatable { - public static func == (lhs: CryptoKitError, rhs: CryptoKitError) -> Bool { - switch (lhs, rhs) { - case (.incorrectKeySize, .incorrectKeySize): - return true - case (.incorrectParameterSize, .incorrectParameterSize): - return true - case (.authenticationFailure, .authenticationFailure): - return true - case (.wrapFailure, .wrapFailure): - return true - case (.unwrapFailure, .unwrapFailure): - return true - case (.underlyingCoreCryptoError(let lhsError), .underlyingCoreCryptoError(let rhsError)): - return lhsError == rhsError - default: - return false - } - } -} - -#endif // Linux or !SwiftPM diff --git a/Tests/CryptoTests/MAC/HMACTests.swift b/Tests/CryptoTests/MAC/HMACTests.swift index 34f3e6bd1..df36bb117 100644 --- a/Tests/CryptoTests/MAC/HMACTests.swift +++ b/Tests/CryptoTests/MAC/HMACTests.swift @@ -105,7 +105,7 @@ class HMACTests: XCTestCase { } } - func testHMAC(key: SymmetricKey, data: Data, vectors: (H.Type) throws -> String, for: H.Type, file: StaticString = #file, line: UInt = #line) throws -> Bool { + func testHMAC(key: SymmetricKey, data: Data, vectors: (H.Type) throws -> String, for: H.Type, file: StaticString = #filePath, line: UInt = #line) throws -> Bool { let code = try orFail(file: file, line: line) { try Data(hexString: vectors(H.self)) } return HMAC.isValidAuthenticationCode(code, authenticating: data, using: key) } diff --git a/Tests/CryptoTests/Signatures/ECDSA/ECDSASignatureTests.swift b/Tests/CryptoTests/Signatures/ECDSA/ECDSASignatureTests.swift index f3e2fcd2c..fc72e4c52 100644 --- a/Tests/CryptoTests/Signatures/ECDSA/ECDSASignatureTests.swift +++ b/Tests/CryptoTests/Signatures/ECDSA/ECDSASignatureTests.swift @@ -148,7 +148,7 @@ class SignatureTests: XCTestCase { } } - func testGroup(group: ECDSATestGroup, curve: C.Type, hashFunction: HF.Type, deserializeSignature: (Data) throws -> C.ECDSASignature, file: StaticString = #file, line: UInt = #line) throws where C.ECDSASignature == C.PublicKey.Signature { + func testGroup(group: ECDSATestGroup, curve: C.Type, hashFunction: HF.Type, deserializeSignature: (Data) throws -> C.ECDSASignature, file: StaticString = #filePath, line: UInt = #line) throws where C.ECDSASignature == C.PublicKey.Signature { let keyBytes = try orFail(file: file, line: line) { try Array(hexString: group.publicKey.uncompressed) } let key = try orFail(file: file, line: line) { try C.PublicKey(x963Representation: keyBytes) } diff --git a/Tests/CryptoTests/Signatures/ECDSA/RawECDSASignaturesTests.swift b/Tests/CryptoTests/Signatures/ECDSA/RawECDSASignaturesTests.swift index 5902d6f85..a085be4e2 100644 --- a/Tests/CryptoTests/Signatures/ECDSA/RawECDSASignaturesTests.swift +++ b/Tests/CryptoTests/Signatures/ECDSA/RawECDSASignaturesTests.swift @@ -25,7 +25,7 @@ import XCTest typealias TestVector = (publicKey: Data, privateKey: Data, rs: rAndS) typealias rAndS = (r: Data, s: Data) -func testVectorForCurve(curve: S.Type, file: StaticString = #file, line: UInt = #line) throws -> TestVector { +func testVectorForCurve(curve: S.Type, file: StaticString = #filePath, line: UInt = #line) throws -> TestVector { switch S.self { case is P256.Signing.Type: do { @@ -56,7 +56,7 @@ func testVectorForCurve(curve: S.Type, file: StaticString = #fil } class RawECDSASignaturesTests: XCTestCase { - func testForCurve(curve: S.Type, file: StaticString = #file, line: UInt = #line) throws { + func testForCurve(curve: S.Type, file: StaticString = #filePath, line: UInt = #line) throws { let msg = try unwrap("abc".data(using: .utf8), file: file, line: line) // We check that the test message is correctly encoded. XCTAssertEqual(msg, try Data(hexString: "616263"), file: file, line: line) diff --git a/Tests/CryptoTests/Signatures/EdDSA/Ed25519-Runner.swift b/Tests/CryptoTests/Signatures/EdDSA/Ed25519-Runner.swift index 326bf3d68..c025e04cb 100644 --- a/Tests/CryptoTests/Signatures/EdDSA/Ed25519-Runner.swift +++ b/Tests/CryptoTests/Signatures/EdDSA/Ed25519-Runner.swift @@ -105,7 +105,7 @@ class Ed25519Tests: XCTestCase { } } - func testGroup(group: Ed25519TestGroup, file: StaticString = #file, line: UInt = #line) throws { + func testGroup(group: Ed25519TestGroup, file: StaticString = #filePath, line: UInt = #line) throws { let keyBytes = try orFail { try Array(hexString: group.publicKey.pk) } let key = try orFail { try Curve25519.Signing.PublicKey(rawRepresentation: keyBytes) } diff --git a/Tests/CryptoTests/Utils/RFCVector.swift b/Tests/CryptoTests/Utils/RFCVector.swift index ea582b32a..363a083e1 100644 --- a/Tests/CryptoTests/Utils/RFCVector.swift +++ b/Tests/CryptoTests/Utils/RFCVector.swift @@ -29,7 +29,7 @@ struct RFCVectorDecoder { let bundle = Bundle(for: type(of: bundleType)) let fileURL = bundle.url(forResource: fileName, withExtension: "txt") #else - var fileURL: URL? = URL(fileURLWithPath: "\(#file)") + var fileURL: URL? = URL(fileURLWithPath: "\(#filePath)") for _ in 0..<3 { fileURL!.deleteLastPathComponent() } diff --git a/Tests/CryptoTests/Utils/Wycheproof.swift b/Tests/CryptoTests/Utils/Wycheproof.swift index a40fe0439..fc381339d 100644 --- a/Tests/CryptoTests/Utils/Wycheproof.swift +++ b/Tests/CryptoTests/Utils/Wycheproof.swift @@ -20,12 +20,12 @@ struct WycheproofTest: Codable { } extension XCTestCase { - func wycheproofTest(bundleType: AnyObject, jsonName: String, file: StaticString = #file, line: UInt = #line, testFunction: (T) throws -> Void) throws { + func wycheproofTest(bundleType: AnyObject, jsonName: String, file: StaticString = #filePath, line: UInt = #line, testFunction: (T) throws -> Void) throws { #if !CRYPTO_IN_SWIFTPM let bundle = Bundle(for: type(of: bundleType)) let fileURL = bundle.url(forResource: jsonName, withExtension: "json") #else - var fileURL = URL(fileURLWithPath: "\(#file)") + var fileURL = URL(fileURLWithPath: "\(#filePath)") for _ in 0..<3 { fileURL.deleteLastPathComponent() } diff --git a/Tests/CryptoTests/Utils/XCTestUtils.swift b/Tests/CryptoTests/Utils/XCTestUtils.swift index 819d290b7..87e8dbe6b 100644 --- a/Tests/CryptoTests/Utils/XCTestUtils.swift +++ b/Tests/CryptoTests/Utils/XCTestUtils.swift @@ -17,7 +17,7 @@ import Crypto // Xcode 11.4 catches errors thrown during tests and reports them on the // correct line. But Linux and older Xcodes do not, so we need to use this // wrapper as long as those platforms are supported. -func orFail(file: StaticString = #file, line: UInt = #line, _ closure: () throws -> T) throws -> T { +func orFail(file: StaticString = #filePath, line: UInt = #line, _ closure: () throws -> T) throws -> T { func wrapper(_ closure: () throws -> U, file: StaticString, line: UInt) throws -> U { do { return try closure() @@ -45,7 +45,7 @@ extension XCTestCase { /// been marked as `throws`. /// - Note: this is a replacement for `XCTUnwrap`, which is not available /// in SPM command line builds as of this writing: - func unwrap(_ optional: T?, file: StaticString = (#file), line: UInt = #line) throws -> T { + func unwrap(_ optional: T?, file: StaticString = (#filePath), line: UInt = #line) throws -> T { guard let wrapped = optional else { XCTFail("Optional was nil", file: file, line: line) throw OptionalUnwrappingError(file: file, line: line) @@ -59,7 +59,7 @@ func XCTAssertThrowsError( _ expression: @autoclosure () throws -> T, error: E, _ message: @autoclosure () -> String = "", - file: StaticString = #file, + file: StaticString = #filePath, line: UInt = #line) { XCTAssertThrowsError(try expression(), message(), file: file, line: line) { foundError in diff --git a/Tests/_CryptoExtrasTests/AES-GCM-SIV-Runner.swift b/Tests/_CryptoExtrasTests/AES-GCM-SIV-Runner.swift index 6cfa781f3..3d5ddea5b 100644 --- a/Tests/_CryptoExtrasTests/AES-GCM-SIV-Runner.swift +++ b/Tests/_CryptoExtrasTests/AES-GCM-SIV-Runner.swift @@ -152,7 +152,7 @@ final class AESGCMSIVTests: XCTestCase { } func testRoundTripDataProtocols() throws { - func roundTrip(message: Message, aad: AAD, file: StaticString = (#file), line: UInt = #line) throws { + func roundTrip(message: Message, aad: AAD, file: StaticString = (#filePath), line: UInt = #line) throws { let key = SymmetricKey(size: .bits256) let nonce = AES.GCM._SIV.Nonce() let ciphertext = try AES.GCM._SIV.seal(message, using: key, nonce: nonce, authenticating: aad) diff --git a/Tests/_CryptoExtrasTests/MLDSATests.swift b/Tests/_CryptoExtrasTests/MLDSATests.swift index 01ddbd743..42edd033d 100644 --- a/Tests/_CryptoExtrasTests/MLDSATests.swift +++ b/Tests/_CryptoExtrasTests/MLDSATests.swift @@ -224,11 +224,11 @@ final class MLDSATests: XCTestCase { @available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) private func nistTest( jsonName: String, - file: StaticString = #file, + file: StaticString = #filePath, line: UInt = #line, testFunction: (Vector) throws -> Void ) throws { - var fileURL = URL(fileURLWithPath: "\(#file)") + var fileURL = URL(fileURLWithPath: "\(#filePath)") for _ in 0..<2 { fileURL.deleteLastPathComponent() } diff --git a/Tests/_CryptoExtrasTests/MLKEMTests.swift b/Tests/_CryptoExtrasTests/MLKEMTests.swift index 007a88a5a..ae6351ca3 100644 --- a/Tests/_CryptoExtrasTests/MLKEMTests.swift +++ b/Tests/_CryptoExtrasTests/MLKEMTests.swift @@ -37,8 +37,14 @@ final class MLKEMTests: XCTestCase { var modifiedPublicKeyBytes = publicKeyBytes modifiedPublicKeyBytes[0] = 0xff modifiedPublicKeyBytes[1] = 0xff - // Parsing should fail because the first coefficient is >= kPrime; - XCTAssertThrowsError(try MLKEM768.PublicKey(rawRepresentation: modifiedPublicKeyBytes)) + // Parsing should fail because the first coefficient is >= kPrime. The check may be delayed + // to the encapsulation stage. + XCTAssertThrowsError( + try { + let pk = try MLKEM768.PublicKey(rawRepresentation: modifiedPublicKeyBytes) + _ = try pk.encapsulate() + }() + ) let publicKey2 = try MLKEM768.PublicKey(rawRepresentation: publicKeyBytes) XCTAssertEqual(publicKeyBytes, publicKey2.rawRepresentation) @@ -83,8 +89,14 @@ final class MLKEMTests: XCTestCase { var modifiedPublicKeyBytes = publicKeyBytes modifiedPublicKeyBytes[0] = 0xff modifiedPublicKeyBytes[1] = 0xff - // Parsing should fail because the first coefficient is >= kPrime; - XCTAssertThrowsError(try MLKEM1024.PublicKey(rawRepresentation: modifiedPublicKeyBytes)) + // Parsing should fail because the first coefficient is >= kPrime. The check may be delayed + // to the encapsulation stage. + XCTAssertThrowsError( + try { + let pk = try MLKEM1024.PublicKey(rawRepresentation: modifiedPublicKeyBytes) + _ = try pk.encapsulate() + }() + ) let publicKey2 = try MLKEM1024.PublicKey(rawRepresentation: publicKeyBytes) XCTAssertEqual(publicKeyBytes, publicKey2.rawRepresentation) diff --git a/Tests/_CryptoExtrasTests/OPRFs/VOPRFAPITests.swift b/Tests/_CryptoExtrasTests/OPRFs/VOPRFAPITests.swift index 0a8323c94..cf4582c23 100644 --- a/Tests/_CryptoExtrasTests/OPRFs/VOPRFAPITests.swift +++ b/Tests/_CryptoExtrasTests/OPRFs/VOPRFAPITests.swift @@ -24,7 +24,7 @@ extension OPRFSuite { static let allValues: [Self] = try! OPRFSuite.load(from: URL( fileURLWithPath: "OPRFVectors/OPRFVectors-VOPRFDraft19.json", - relativeTo: URL(fileURLWithPath: #file) + relativeTo: URL(fileURLWithPath: #filePath) )) static var P384_SHA384_VORPF: Self { diff --git a/Tests/_CryptoExtrasTests/TestRSABlindSigning.swift b/Tests/_CryptoExtrasTests/TestRSABlindSigning.swift index fa42b2ee3..fb6a9c32e 100644 --- a/Tests/_CryptoExtrasTests/TestRSABlindSigning.swift +++ b/Tests/_CryptoExtrasTests/TestRSABlindSigning.swift @@ -43,7 +43,7 @@ struct RFC9474TestVector: Codable { static let allValues: [Self] = try! RFC9474TestVector.load(from: URL( fileURLWithPath: "../_CryptoExtrasVectors/rfc9474.json", - relativeTo: URL(fileURLWithPath: #file) + relativeTo: URL(fileURLWithPath: #filePath) )) } diff --git a/Tests/_CryptoExtrasTests/Utils/RFCVector.swift b/Tests/_CryptoExtrasTests/Utils/RFCVector.swift index c7d8df7e9..bc6748989 100644 --- a/Tests/_CryptoExtrasTests/Utils/RFCVector.swift +++ b/Tests/_CryptoExtrasTests/Utils/RFCVector.swift @@ -25,7 +25,7 @@ struct RFCVectorDecoder { private var index: Int? init(bundleType: AnyObject, fileName: String) throws { - var fileURL: URL? = URL(fileURLWithPath: "\(#file)") + var fileURL: URL? = URL(fileURLWithPath: "\(#filePath)") for _ in 0..<3 { fileURL!.deleteLastPathComponent() } diff --git a/Tests/_CryptoExtrasTests/Utils/Wycheproof.swift b/Tests/_CryptoExtrasTests/Utils/Wycheproof.swift index 42d9e8c95..9c7025617 100644 --- a/Tests/_CryptoExtrasTests/Utils/Wycheproof.swift +++ b/Tests/_CryptoExtrasTests/Utils/Wycheproof.swift @@ -20,8 +20,8 @@ struct WycheproofTest: Codable { } extension XCTestCase { - func wycheproofTest(jsonName: String, file: StaticString = #file, line: UInt = #line, testFunction: (T) throws -> Void) throws { - var fileURL = URL(fileURLWithPath: "\(#file)") + func wycheproofTest(jsonName: String, file: StaticString = #filePath, line: UInt = #line, testFunction: (T) throws -> Void) throws { + var fileURL = URL(fileURLWithPath: "\(#filePath)") for _ in 0..<3 { fileURL.deleteLastPathComponent() } diff --git a/Tests/_CryptoExtrasTests/Utils/XCTestUtils.swift b/Tests/_CryptoExtrasTests/Utils/XCTestUtils.swift index 9f0878e6f..1be6d3cd4 100644 --- a/Tests/_CryptoExtrasTests/Utils/XCTestUtils.swift +++ b/Tests/_CryptoExtrasTests/Utils/XCTestUtils.swift @@ -16,7 +16,7 @@ import XCTest // Xcode 11.4 catches errors thrown during tests and reports them on the // correct line. But Linux and older Xcodes do not, so we need to use this // wrapper as long as those platforms are supported. -func orFail(file: StaticString = #file, line: UInt = #line, _ closure: () throws -> T) throws -> T { +func orFail(file: StaticString = #filePath, line: UInt = #line, _ closure: () throws -> T) throws -> T { func wrapper(_ closure: () throws -> U, file: StaticString, line: UInt) throws -> U { do { return try closure() @@ -37,7 +37,7 @@ func XCTAssertThrowsError( _ expression: @autoclosure () throws -> T, error expectedError: E, _ message: @autoclosure () -> String = "", - file: StaticString = #file, + file: StaticString = #filePath, line: UInt = #line) { XCTAssertThrowsError(try expression(), message(), file: file, line: line) { error in XCTAssertEqual(error as? E, expectedError, message(), file: file, line: line) From 63d96f141c441f641a19a1daf7bafff5ca77495e Mon Sep 17 00:00:00 2001 From: Francesco Paolo Severino Date: Tue, 24 Jun 2025 19:01:10 +0200 Subject: [PATCH 20/47] Remove some warnings --- Package.swift | 3 +- Sources/Crypto/Signatures/MLDSA.swift | 44 +++++++++++++---------- Sources/Crypto/Signatures/MLDSA.swift.gyb | 22 +++++++----- 3 files changed, 41 insertions(+), 28 deletions(-) diff --git a/Package.swift b/Package.swift index 3d92c6858..a31f1914b 100644 --- a/Package.swift +++ b/Package.swift @@ -160,7 +160,8 @@ let package = Package( .product(name: "SwiftASN1", package: "swift-asn1"), ], exclude: privacyManifestExclude + [ - "CMakeLists.txt" + "CMakeLists.txt", + "MLDSA/MLDSA+externalMu.swift.gyb", ], resources: privacyManifestResource, swiftSettings: swiftSettings diff --git a/Sources/Crypto/Signatures/MLDSA.swift b/Sources/Crypto/Signatures/MLDSA.swift index e22ff27dd..b0fba688e 100644 --- a/Sources/Crypto/Signatures/MLDSA.swift +++ b/Sources/Crypto/Signatures/MLDSA.swift @@ -106,9 +106,11 @@ extension MLDSA65 { private var boringSSLKey: OpenSSLMLDSAPublicKeyImpl { get throws { - self.impl is OpenSSLMLDSAPublicKeyImpl - ? self.impl - : try OpenSSLMLDSAPublicKeyImpl(rawRepresentation: self.rawRepresentation) + #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION + try OpenSSLMLDSAPublicKeyImpl(rawRepresentation: self.rawRepresentation) + #else + self.impl + #endif } } } @@ -204,12 +206,14 @@ extension MLDSA65 { private var boringSSLKey: OpenSSLMLDSAPrivateKeyImpl { get throws { - self.impl is OpenSSLMLDSAPrivateKeyImpl - ? self.impl - : try OpenSSLMLDSAPrivateKeyImpl( - seedRepresentation: self.seedRepresentation, - publicKey: nil - ) + #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION + try OpenSSLMLDSAPrivateKeyImpl( + seedRepresentation: self.seedRepresentation, + publicKey: nil + ) + #else + self.impl + #endif } } } @@ -291,9 +295,11 @@ extension MLDSA87 { private var boringSSLKey: OpenSSLMLDSAPublicKeyImpl { get throws { - self.impl is OpenSSLMLDSAPublicKeyImpl - ? self.impl - : try OpenSSLMLDSAPublicKeyImpl(rawRepresentation: self.rawRepresentation) + #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION + try OpenSSLMLDSAPublicKeyImpl(rawRepresentation: self.rawRepresentation) + #else + self.impl + #endif } } } @@ -389,12 +395,14 @@ extension MLDSA87 { private var boringSSLKey: OpenSSLMLDSAPrivateKeyImpl { get throws { - self.impl is OpenSSLMLDSAPrivateKeyImpl - ? self.impl - : try OpenSSLMLDSAPrivateKeyImpl( - seedRepresentation: self.seedRepresentation, - publicKey: nil - ) + #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION + try OpenSSLMLDSAPrivateKeyImpl( + seedRepresentation: self.seedRepresentation, + publicKey: nil + ) + #else + self.impl + #endif } } } diff --git a/Sources/Crypto/Signatures/MLDSA.swift.gyb b/Sources/Crypto/Signatures/MLDSA.swift.gyb index 9204878b4..283863b22 100644 --- a/Sources/Crypto/Signatures/MLDSA.swift.gyb +++ b/Sources/Crypto/Signatures/MLDSA.swift.gyb @@ -114,9 +114,11 @@ extension ${NAME} { private var boringSSLKey: OpenSSLMLDSAPublicKeyImpl<${NAME}> { get throws { - self.impl is OpenSSLMLDSAPublicKeyImpl<${NAME}> - ? self.impl - : try OpenSSLMLDSAPublicKeyImpl<${NAME}>(rawRepresentation: self.rawRepresentation) + #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION + try OpenSSLMLDSAPublicKeyImpl<${NAME}>(rawRepresentation: self.rawRepresentation) + #else + self.impl + #endif } } } @@ -212,12 +214,14 @@ extension ${NAME} { private var boringSSLKey: OpenSSLMLDSAPrivateKeyImpl<${NAME}> { get throws { - self.impl is OpenSSLMLDSAPrivateKeyImpl<${NAME}> - ? self.impl - : try OpenSSLMLDSAPrivateKeyImpl<${NAME}>( - seedRepresentation: self.seedRepresentation, - publicKey: nil - ) + #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION + try OpenSSLMLDSAPrivateKeyImpl<${NAME}>( + seedRepresentation: self.seedRepresentation, + publicKey: nil + ) + #else + self.impl + #endif } } } From 04342312716617b45262d011e4304a3514e45a88 Mon Sep 17 00:00:00 2001 From: Francesco Paolo Severino Date: Tue, 24 Jun 2025 19:01:34 +0200 Subject: [PATCH 21/47] Format and remove warnings from MLKEM.swift --- Sources/Crypto/KEM/MLKEM.swift | 49 ++++++++++++++++-------------- Sources/Crypto/KEM/MLKEM.swift.gyb | 34 +++++++++++++-------- 2 files changed, 49 insertions(+), 34 deletions(-) diff --git a/Sources/Crypto/KEM/MLKEM.swift b/Sources/Crypto/KEM/MLKEM.swift index 3883fbd40..248439f88 100644 --- a/Sources/Crypto/KEM/MLKEM.swift +++ b/Sources/Crypto/KEM/MLKEM.swift @@ -32,7 +32,6 @@ typealias MLKEMPublicKeyImpl = OpenSSLMLKEMPublicKeyImpl typealias MLKEMPrivateKeyImpl = OpenSSLMLKEMPrivateKeyImpl #endif - /// The Module-Lattice key encapsulation mechanism (KEM). @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) public enum MLKEM768: Sendable {} @@ -53,7 +52,7 @@ extension MLKEM768 { /// A serialized representation of the public key. public var rawRepresentation: Data { get { - return self.impl.rawRepresentation + self.impl.rawRepresentation } } @@ -61,11 +60,11 @@ extension MLKEM768 { /// /// - Returns: an encapsulated shared secret, that you decapsulate by calling ``MLKEM768/PrivateKey/decapsulate(_:)`` on the corresponding private key. public func encapsulate() throws -> KEM.EncapsulationResult { - return try self.impl.encapsulate() + try self.impl.encapsulate() } func encapsulateWithSeed(encapSeed: Data) throws -> KEM.EncapsulationResult { - return try self.impl.encapsulateWithSeed(encapSeed) + try self.impl.encapsulateWithSeed(encapSeed) } } @@ -104,7 +103,10 @@ extension MLKEM768 { if publicKey != nil { publicKeyRawRepresentation = publicKey!.rawRepresentation } - self.impl = try MLKEMPrivateKeyImpl(seedRepresentation: seedRepresentation, publicKeyRawRepresentation: publicKeyRawRepresentation) + self.impl = try MLKEMPrivateKeyImpl( + seedRepresentation: seedRepresentation, + publicKeyRawRepresentation: publicKeyRawRepresentation + ) } /// The private key's seed representation. @@ -112,7 +114,7 @@ extension MLKEM768 { /// The seed is `d||z`, as specified in the algorithm `ML-KEM.KeyGen_internal(d,z)` (Algorithm 16) of FIPS 203. public var seedRepresentation: Data { get { - return self.impl.seedRepresentation + self.impl.seedRepresentation } } @@ -122,13 +124,13 @@ extension MLKEM768 { /// - encapsulated: An encapsulated shared secret, that you get by calling ``MLKEM768/PublicKey/encapsulate()`` on the corresponding public key. /// - Returns: The shared secret. public func decapsulate(_ encapsulated: D) throws -> SymmetricKey { - return try impl.decapsulate(encapsulated: encapsulated) + try impl.decapsulate(encapsulated: encapsulated) } /// The corresponding public key. public var publicKey: MLKEM768.PublicKey { get { - try self.impl.publicKey + self.impl.publicKey } } @@ -140,7 +142,8 @@ extension MLKEM768 { throw KEM.Errors.invalidSeed } let seed = Data(integrityCheckedRepresentation).subdata(in: 0...seedSize) - let publicKeyHashData = Data(integrityCheckedRepresentation).subdata(in: MLKEMPrivateKeyImpl.seedSize...seedSize..(seedRepresentation: seed, publicKeyHash: publicKeyHash) @@ -151,13 +154,12 @@ extension MLKEM768 { /// This representation includes the seed value, and a hash of the corresponding public key. public var integrityCheckedRepresentation: Data { get { - return self.impl.integrityCheckedRepresentation + self.impl.integrityCheckedRepresentation } } } } - /// The Module-Lattice key encapsulation mechanism (KEM). @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) public enum MLKEM1024: Sendable {} @@ -178,7 +180,7 @@ extension MLKEM1024 { /// A serialized representation of the public key. public var rawRepresentation: Data { get { - return self.impl.rawRepresentation + self.impl.rawRepresentation } } @@ -186,11 +188,11 @@ extension MLKEM1024 { /// /// - Returns: an encapsulated shared secret, that you decapsulate by calling ``MLKEM1024/PrivateKey/decapsulate(_:)`` on the corresponding private key. public func encapsulate() throws -> KEM.EncapsulationResult { - return try self.impl.encapsulate() + try self.impl.encapsulate() } func encapsulateWithSeed(encapSeed: Data) throws -> KEM.EncapsulationResult { - return try self.impl.encapsulateWithSeed(encapSeed) + try self.impl.encapsulateWithSeed(encapSeed) } } @@ -229,7 +231,10 @@ extension MLKEM1024 { if publicKey != nil { publicKeyRawRepresentation = publicKey!.rawRepresentation } - self.impl = try MLKEMPrivateKeyImpl(seedRepresentation: seedRepresentation, publicKeyRawRepresentation: publicKeyRawRepresentation) + self.impl = try MLKEMPrivateKeyImpl( + seedRepresentation: seedRepresentation, + publicKeyRawRepresentation: publicKeyRawRepresentation + ) } /// The private key's seed representation. @@ -237,7 +242,7 @@ extension MLKEM1024 { /// The seed is `d||z`, as specified in the algorithm `ML-KEM.KeyGen_internal(d,z)` (Algorithm 16) of FIPS 203. public var seedRepresentation: Data { get { - return self.impl.seedRepresentation + self.impl.seedRepresentation } } @@ -247,13 +252,13 @@ extension MLKEM1024 { /// - encapsulated: An encapsulated shared secret, that you get by calling ``MLKEM1024/PublicKey/encapsulate()`` on the corresponding public key. /// - Returns: The shared secret. public func decapsulate(_ encapsulated: D) throws -> SymmetricKey { - return try impl.decapsulate(encapsulated: encapsulated) + try impl.decapsulate(encapsulated: encapsulated) } /// The corresponding public key. public var publicKey: MLKEM1024.PublicKey { get { - try self.impl.publicKey + self.impl.publicKey } } @@ -265,7 +270,8 @@ extension MLKEM1024 { throw KEM.Errors.invalidSeed } let seed = Data(integrityCheckedRepresentation).subdata(in: 0...seedSize) - let publicKeyHashData = Data(integrityCheckedRepresentation).subdata(in: MLKEMPrivateKeyImpl.seedSize...seedSize..(seedRepresentation: seed, publicKeyHash: publicKeyHash) @@ -276,11 +282,10 @@ extension MLKEM1024 { /// This representation includes the seed value, and a hash of the corresponding public key. public var integrityCheckedRepresentation: Data { get { - return self.impl.integrityCheckedRepresentation + self.impl.integrityCheckedRepresentation } } } } - -#endif // Linux or !SwiftPM +#endif // Linux or !SwiftPM diff --git a/Sources/Crypto/KEM/MLKEM.swift.gyb b/Sources/Crypto/KEM/MLKEM.swift.gyb index 3a1719437..a5d5417f0 100644 --- a/Sources/Crypto/KEM/MLKEM.swift.gyb +++ b/Sources/Crypto/KEM/MLKEM.swift.gyb @@ -24,10 +24,14 @@ public import Foundation }% #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) typealias MLKEMPublicKeyImpl = CoreCryptoMLKEMPublicKeyImpl +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) typealias MLKEMPrivateKeyImpl = CoreCryptoMLKEMPrivateKeyImpl #else +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) typealias MLKEMPublicKeyImpl = OpenSSLMLKEMPublicKeyImpl +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) typealias MLKEMPrivateKeyImpl = OpenSSLMLKEMPrivateKeyImpl #endif @@ -36,12 +40,14 @@ typealias MLKEMPrivateKeyImpl = OpenSSLMLKEMPrivateKeyImpl NAME = MLKEM_VARIANT["name"] INFO = MLKEM_VARIANT["ccinfo"] }% - /// The Module-Lattice key encapsulation mechanism (KEM). +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) public enum ${NAME}: Sendable {} +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ${NAME} { /// A public key you use to encapsulate shared secrets with the Module-Lattice key encapsulation mechanism. + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) public struct PublicKey: KEMPublicKey, Sendable { var impl: MLKEMPublicKeyImpl<${NAME}> @@ -54,7 +60,7 @@ extension ${NAME} { /// A serialized representation of the public key. public var rawRepresentation: Data { get { - return self.impl.rawRepresentation + self.impl.rawRepresentation } } @@ -62,15 +68,16 @@ extension ${NAME} { /// /// - Returns: an encapsulated shared secret, that you decapsulate by calling ``${NAME}/PrivateKey/decapsulate(_:)`` on the corresponding private key. public func encapsulate() throws -> KEM.EncapsulationResult { - return try self.impl.encapsulate() + try self.impl.encapsulate() } func encapsulateWithSeed(encapSeed: Data) throws -> KEM.EncapsulationResult { - return try self.impl.encapsulateWithSeed(encapSeed) + try self.impl.encapsulateWithSeed(encapSeed) } } /// A private key you use to decapsulate shared secrets with the Module-Lattice key encapsulation mechanism. + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) public struct PrivateKey: KEMPrivateKey { internal let impl: MLKEMPrivateKeyImpl<${NAME}> @@ -104,7 +111,10 @@ extension ${NAME} { if publicKey != nil { publicKeyRawRepresentation = publicKey!.rawRepresentation } - self.impl = try MLKEMPrivateKeyImpl<${NAME}>(seedRepresentation: seedRepresentation, publicKeyRawRepresentation: publicKeyRawRepresentation) + self.impl = try MLKEMPrivateKeyImpl<${NAME}>( + seedRepresentation: seedRepresentation, + publicKeyRawRepresentation: publicKeyRawRepresentation + ) } /// The private key's seed representation. @@ -112,7 +122,7 @@ extension ${NAME} { /// The seed is `d||z`, as specified in the algorithm `ML-KEM.KeyGen_internal(d,z)` (Algorithm 16) of FIPS 203. public var seedRepresentation: Data { get { - return self.impl.seedRepresentation + self.impl.seedRepresentation } } @@ -122,13 +132,13 @@ extension ${NAME} { /// - encapsulated: An encapsulated shared secret, that you get by calling ``${NAME}/PublicKey/encapsulate()`` on the corresponding public key. /// - Returns: The shared secret. public func decapsulate(_ encapsulated: D) throws -> SymmetricKey { - return try impl.decapsulate(encapsulated: encapsulated) + try impl.decapsulate(encapsulated: encapsulated) } /// The corresponding public key. public var publicKey: ${NAME}.PublicKey { get { - try self.impl.publicKey + self.impl.publicKey } } @@ -140,7 +150,8 @@ extension ${NAME} { throw KEM.Errors.invalidSeed } let seed = Data(integrityCheckedRepresentation).subdata(in: 0...seedSize) - let publicKeyHashData = Data(integrityCheckedRepresentation).subdata(in: MLKEMPrivateKeyImpl<${NAME}>.seedSize...seedSize..(seedRepresentation: seed, publicKeyHash: publicKeyHash) @@ -151,12 +162,11 @@ extension ${NAME} { /// This representation includes the seed value, and a hash of the corresponding public key. public var integrityCheckedRepresentation: Data { get { - return self.impl.integrityCheckedRepresentation + self.impl.integrityCheckedRepresentation } } } } % end - -#endif // Linux or !SwiftPM +#endif // Linux or !SwiftPM From 66b120296336b02cad1854f46bdacb74f4023d18 Mon Sep 17 00:00:00 2001 From: Francesco Paolo Severino Date: Wed, 6 Aug 2025 11:58:37 +0200 Subject: [PATCH 22/47] Remove `signature:` parameter label from `isValidSignature` --- .../Signatures/BoringSSL/MLDSA_wrapper.swift | 4 +-- Sources/Crypto/Signatures/MLDSA.swift | 16 ++++----- Sources/Crypto/Signatures/MLDSA.swift.gyb | 8 ++--- .../Signatures/MLDSA/MLDSATests.swift | 16 ++++----- Tests/_CryptoExtrasTests/MLDSATests.swift | 36 +++++++++---------- 5 files changed, 40 insertions(+), 40 deletions(-) diff --git a/Sources/Crypto/Signatures/BoringSSL/MLDSA_wrapper.swift b/Sources/Crypto/Signatures/BoringSSL/MLDSA_wrapper.swift index 52651256a..5a3ab1186 100644 --- a/Sources/Crypto/Signatures/BoringSSL/MLDSA_wrapper.swift +++ b/Sources/Crypto/Signatures/BoringSSL/MLDSA_wrapper.swift @@ -142,14 +142,14 @@ struct OpenSSLMLDSAPublicKeyImpl { } func isValidSignature( - signature: S, + _ signature: S, for data: D ) -> Bool { self.backing.isValidSignature(signature, for: data) } func isValidSignature( - signature: S, + _ signature: S, for data: D, context: C ) -> Bool { diff --git a/Sources/Crypto/Signatures/MLDSA.swift b/Sources/Crypto/Signatures/MLDSA.swift index b0fba688e..485e1087f 100644 --- a/Sources/Crypto/Signatures/MLDSA.swift +++ b/Sources/Crypto/Signatures/MLDSA.swift @@ -45,8 +45,8 @@ extension MLDSA65 { /// - signature: The MLDSA65 signature to verify. /// - data: The signed data. /// - Returns: `true` if the signature is valid, `false` otherwise. - public func isValidSignature(signature: S, for data: D) -> Bool { - self.impl.isValidSignature(signature: signature, for: data) + public func isValidSignature(_ signature: S, for data: D) -> Bool { + self.impl.isValidSignature(signature, for: data) } /// Verifies a MLDSA65 signature, in a specific context. @@ -56,11 +56,11 @@ extension MLDSA65 { /// - context: Context for the signature. /// - Returns: `true` if the signature is valid in the specified context, `false` otherwise. public func isValidSignature( - signature: S, + _ signature: S, for data: D, context: C ) -> Bool { - self.impl.isValidSignature(signature: signature, for: data, context: context) + self.impl.isValidSignature(signature, for: data, context: context) } /// Parses a public key from a serialized representation. @@ -234,8 +234,8 @@ extension MLDSA87 { /// - signature: The MLDSA87 signature to verify. /// - data: The signed data. /// - Returns: `true` if the signature is valid, `false` otherwise. - public func isValidSignature(signature: S, for data: D) -> Bool { - self.impl.isValidSignature(signature: signature, for: data) + public func isValidSignature(_ signature: S, for data: D) -> Bool { + self.impl.isValidSignature(signature, for: data) } /// Verifies a MLDSA87 signature, in a specific context. @@ -245,11 +245,11 @@ extension MLDSA87 { /// - context: Context for the signature. /// - Returns: `true` if the signature is valid in the specified context, `false` otherwise. public func isValidSignature( - signature: S, + _ signature: S, for data: D, context: C ) -> Bool { - self.impl.isValidSignature(signature: signature, for: data, context: context) + self.impl.isValidSignature(signature, for: data, context: context) } /// Parses a public key from a serialized representation. diff --git a/Sources/Crypto/Signatures/MLDSA.swift.gyb b/Sources/Crypto/Signatures/MLDSA.swift.gyb index 283863b22..14d31e014 100644 --- a/Sources/Crypto/Signatures/MLDSA.swift.gyb +++ b/Sources/Crypto/Signatures/MLDSA.swift.gyb @@ -53,8 +53,8 @@ extension ${NAME} { /// - signature: The ${NAME} signature to verify. /// - data: The signed data. /// - Returns: `true` if the signature is valid, `false` otherwise. - public func isValidSignature(signature: S, for data: D) -> Bool { - self.impl.isValidSignature(signature: signature, for: data) + public func isValidSignature(_ signature: S, for data: D) -> Bool { + self.impl.isValidSignature(signature, for: data) } /// Verifies a ${NAME} signature, in a specific context. @@ -64,11 +64,11 @@ extension ${NAME} { /// - context: Context for the signature. /// - Returns: `true` if the signature is valid in the specified context, `false` otherwise. public func isValidSignature( - signature: S, + _ signature: S, for data: D, context: C ) -> Bool { - self.impl.isValidSignature(signature: signature, for: data, context: context) + self.impl.isValidSignature(signature, for: data, context: context) } /// Parses a public key from a serialized representation. diff --git a/Tests/CryptoTests/Signatures/MLDSA/MLDSATests.swift b/Tests/CryptoTests/Signatures/MLDSA/MLDSATests.swift index f833e3355..61dd8e7d0 100644 --- a/Tests/CryptoTests/Signatures/MLDSA/MLDSATests.swift +++ b/Tests/CryptoTests/Signatures/MLDSA/MLDSATests.swift @@ -40,18 +40,18 @@ final class MLDSATests: XCTestCase { let message = Data("ML-DSA test message".utf8) let signature = try privateKey.signature(for: message) XCTAssertNotNil(signature) - let isValid = publicKey.isValidSignature(signature: signature, for: message) + let isValid = publicKey.isValidSignature(signature, for: message) XCTAssertTrue(isValid) // Test signing with a context let context = Data("ML-DSA test context".utf8) let signatureWithContext = try privateKey.signature(for: message, context: context) - let isValidWithContext = publicKey.isValidSignature(signature: signatureWithContext, for: message, context: context) + let isValidWithContext = publicKey.isValidSignature(signatureWithContext, for: message, context: context) XCTAssertTrue(isValidWithContext) // Check that invalid signatures (mismatching contexts) fail - XCTAssertFalse(publicKey.isValidSignature(signature: signature, for: message, context: context)) - XCTAssertFalse(publicKey.isValidSignature(signature: signatureWithContext, for: message)) + XCTAssertFalse(publicKey.isValidSignature(signature, for: message, context: context)) + XCTAssertFalse(publicKey.isValidSignature(signatureWithContext, for: message)) } func testMLDSA87() throws { @@ -71,18 +71,18 @@ final class MLDSATests: XCTestCase { let message = Data("ML-DSA test message".utf8) let signature = try privateKey.signature(for: message) XCTAssertNotNil(signature) - let isValid = publicKey.isValidSignature(signature: signature, for: message) + let isValid = publicKey.isValidSignature(signature, for: message) XCTAssertTrue(isValid) // Test signing with a context let context = Data("ML-DSA test context".utf8) let signatureWithContext = try privateKey.signature(for: message, context: context) - let isValidWithContext = publicKey.isValidSignature(signature: signatureWithContext, for: message, context: context) + let isValidWithContext = publicKey.isValidSignature(signatureWithContext, for: message, context: context) XCTAssertTrue(isValidWithContext) // Check that invalid signatures (mismatching contexts) fail - XCTAssertFalse(publicKey.isValidSignature(signature: signature, for: message, context: context)) - XCTAssertFalse(publicKey.isValidSignature(signature: signatureWithContext, for: message)) + XCTAssertFalse(publicKey.isValidSignature(signature, for: message, context: context)) + XCTAssertFalse(publicKey.isValidSignature(signatureWithContext, for: message)) } } diff --git a/Tests/_CryptoExtrasTests/MLDSATests.swift b/Tests/_CryptoExtrasTests/MLDSATests.swift index c529bbb94..034e6be00 100644 --- a/Tests/_CryptoExtrasTests/MLDSATests.swift +++ b/Tests/_CryptoExtrasTests/MLDSATests.swift @@ -32,7 +32,7 @@ final class MLDSATests: XCTestCase { let test = "Hello, world!".data(using: .utf8)! try XCTAssertTrue( key.publicKey.isValidSignature( - signature: key.signature(for: test), + key.signature(for: test), for: test ) ) @@ -40,7 +40,7 @@ final class MLDSATests: XCTestCase { let context = "ctx".data(using: .utf8)! try XCTAssertTrue( key.publicKey.isValidSignature( - signature: key.signature(for: test, context: context), + key.signature(for: test, context: context), for: test, context: context ) @@ -61,7 +61,7 @@ final class MLDSATests: XCTestCase { let test = "Hello, world!".data(using: .utf8)! try XCTAssertTrue( key.publicKey.isValidSignature( - signature: key.signature(for: test), + key.signature(for: test), for: test ) ) @@ -69,7 +69,7 @@ final class MLDSATests: XCTestCase { let context = "ctx".data(using: .utf8)! try XCTAssertTrue( key.publicKey.isValidSignature( - signature: key.signature(for: test, context: context), + key.signature(for: test, context: context), for: test, context: context ) @@ -114,8 +114,8 @@ final class MLDSATests: XCTestCase { XCTAssertNotEqual(signature1, signature2) // Even though the signatures are different, they both verify. - XCTAssertTrue(publicKey.isValidSignature(signature: signature1, for: message)) - XCTAssertTrue(publicKey.isValidSignature(signature: signature2, for: message)) + XCTAssertTrue(publicKey.isValidSignature(signature1, for: message)) + XCTAssertTrue(publicKey.isValidSignature(signature2, for: message)) } func testMLDSA87SignatureIsRandomized() throws { @@ -134,8 +134,8 @@ final class MLDSATests: XCTestCase { XCTAssertNotEqual(signature1, signature2) // Even though the signatures are different, they both verify. - XCTAssertTrue(publicKey.isValidSignature(signature: signature1, for: message)) - XCTAssertTrue(publicKey.isValidSignature(signature: signature2, for: message)) + XCTAssertTrue(publicKey.isValidSignature(signature1, for: message)) + XCTAssertTrue(publicKey.isValidSignature(signature2, for: message)) } func testInvalidMLDSA65PublicKeyEncodingLength() throws { @@ -263,15 +263,15 @@ final class MLDSATests: XCTestCase { switch test.result { case .valid: if let context { - XCTAssertTrue(publicKey.isValidSignature(signature: signature, for: message, context: context)) + XCTAssertTrue(publicKey.isValidSignature(signature, for: message, context: context)) } else { - XCTAssertTrue(publicKey.isValidSignature(signature: signature, for: message)) + XCTAssertTrue(publicKey.isValidSignature(signature, for: message)) } case .invalid: if let context { - XCTAssertFalse(publicKey.isValidSignature(signature: signature, for: message, context: context)) + XCTAssertFalse(publicKey.isValidSignature(signature, for: message, context: context)) } else { - XCTAssertFalse(publicKey.isValidSignature(signature: signature, for: message)) + XCTAssertFalse(publicKey.isValidSignature(signature, for: message)) } } } @@ -298,15 +298,15 @@ final class MLDSATests: XCTestCase { switch test.result { case .valid: if let context { - XCTAssertTrue(publicKey.isValidSignature(signature: signature, for: message, context: context)) + XCTAssertTrue(publicKey.isValidSignature(signature, for: message, context: context)) } else { - XCTAssertTrue(publicKey.isValidSignature(signature: signature, for: message)) + XCTAssertTrue(publicKey.isValidSignature(signature, for: message)) } case .invalid: if let context { - XCTAssertFalse(publicKey.isValidSignature(signature: signature, for: message, context: context)) + XCTAssertFalse(publicKey.isValidSignature(signature, for: message, context: context)) } else { - XCTAssertFalse(publicKey.isValidSignature(signature: signature, for: message)) + XCTAssertFalse(publicKey.isValidSignature(signature, for: message)) } } } @@ -368,7 +368,7 @@ final class MLDSAExternalMuTests: XCTestCase { let mu = try publicKey.prehash(for: message, context: context) let muSignature = try key.signature(forPrehashedMessageRepresentative: mu) - XCTAssertTrue(publicKey.isValidSignature(signature: muSignature, for: message, context: context)) + XCTAssertTrue(publicKey.isValidSignature(muSignature, for: message, context: context)) } func testMLDSA87PrehashedSigning() throws { @@ -381,6 +381,6 @@ final class MLDSAExternalMuTests: XCTestCase { let mu = try publicKey.prehash(for: message, context: context) let muSignature = try key.signature(forPrehashedMessageRepresentative: mu) - XCTAssertTrue(publicKey.isValidSignature(signature: muSignature, for: message, context: context)) + XCTAssertTrue(publicKey.isValidSignature(muSignature, for: message, context: context)) } } From d9f364189995019337857e11fdbea66d11d238cf Mon Sep 17 00:00:00 2001 From: Si Beaumont Date: Mon, 11 Aug 2025 19:28:46 +0100 Subject: [PATCH 23/47] [WWDC25] Add SHA-3 implementation backed by XKCP (#397) ## Motivation CryptoKit is adding API for SHA-3, which BoringSSL does not support. To maintain API parity, we need to provide a backing implementation. For this, we can use XKCP[^1], which provides the reference implementation, as well as several optimized solutions, suitable for vendoring into other projects. ## Modifications The following changes have been made in separate commits to help with the review: - Add vendor-xkcp.sh script - Revendor xkcp#master (heads/master-0-g11297f5) - Add CXCKP target with modulemap and umbrella header - Add CXKCPTests test target with simple test vectors - Add CXKCPShims with function wrappers for macros to call from Swift - Remove #if false guard from HashFunctions_SHA3.swift - Add SHA-3 implementation backed by libXKCP - Add new DigestImplSHA3 platform-specific type alias - Remove #if false from DigestsTests.swift to get SHA-3 tests ## Result Swift Crypto provides functioning SHA-3 API. ## Notes This PR is for the `wwdc-25` side branch. [^1]: https://github.com/XKCP/XKCP --- .github/workflows/pull_request.yml | 2 + .licenseignore | 1 + .unacceptablelanguageignore | 3 +- Package.swift | 28 + Sources/CMakeLists.txt | 2 + Sources/CXKCP/CMakeLists.txt | 34 + Sources/CXKCP/FIPS202-opt64/KeccakHash.c | 81 ++ Sources/CXKCP/FIPS202-opt64/KeccakHash.h | 125 +++ .../FIPS202-opt64/KeccakP-1600-64.macros | 758 ++++++++++++++++++ .../CXKCP/FIPS202-opt64/KeccakP-1600-SnP.h | 59 ++ .../FIPS202-opt64/KeccakP-1600-opt64-config.h | 6 + .../CXKCP/FIPS202-opt64/KeccakP-1600-opt64.c | 565 +++++++++++++ .../KeccakP-1600-unrolling.macros | 305 +++++++ Sources/CXKCP/FIPS202-opt64/KeccakSponge.c | 95 +++ Sources/CXKCP/FIPS202-opt64/KeccakSponge.h | 70 ++ Sources/CXKCP/FIPS202-opt64/KeccakSponge.inc | 312 +++++++ Sources/CXKCP/FIPS202-opt64/SimpleFIPS202.c | 48 ++ Sources/CXKCP/FIPS202-opt64/SimpleFIPS202.h | 79 ++ Sources/CXKCP/FIPS202-opt64/SnP-Relaned.h | 145 ++++ Sources/CXKCP/FIPS202-opt64/align.h | 33 + Sources/CXKCP/FIPS202-opt64/brg_endian.h | 143 ++++ Sources/CXKCP/FIPS202-opt64/config.h | 5 + Sources/CXKCP/PrivacyInfo.xcprivacy | 15 + Sources/CXKCP/include/CXKCP.h | 22 + Sources/CXKCP/include/module.modulemap | 4 + Sources/CXKCP/vendored-sources.txt | 17 + Sources/CXKCPShims/CMakeLists.txt | 29 + Sources/CXKCPShims/PrivacyInfo.xcprivacy | 15 + Sources/CXKCPShims/include/CXKCPShims.h | 69 ++ Sources/CXKCPShims/include/module.modulemap | 4 + Sources/CXKCPShims/shims.c | 36 + Sources/Crypto/CMakeLists.txt | 9 +- .../Digests/BoringSSL/Digest_boring.swift | 15 +- Sources/Crypto/Digests/HashFunctions.swift | 4 + .../Crypto/Digests/HashFunctions_SHA3.swift | 15 +- Sources/Crypto/Digests/XKCP/Digest_xkcp.swift | 160 ++++ Tests/CXKCPTests/CXKCPTests.swift | 136 ++++ Tests/CryptoTests/Digests/DigestsTests.swift | 20 +- scripts/vendor-xkcp.sh | 67 ++ 39 files changed, 3509 insertions(+), 27 deletions(-) create mode 100644 Sources/CXKCP/CMakeLists.txt create mode 100644 Sources/CXKCP/FIPS202-opt64/KeccakHash.c create mode 100644 Sources/CXKCP/FIPS202-opt64/KeccakHash.h create mode 100644 Sources/CXKCP/FIPS202-opt64/KeccakP-1600-64.macros create mode 100644 Sources/CXKCP/FIPS202-opt64/KeccakP-1600-SnP.h create mode 100644 Sources/CXKCP/FIPS202-opt64/KeccakP-1600-opt64-config.h create mode 100644 Sources/CXKCP/FIPS202-opt64/KeccakP-1600-opt64.c create mode 100644 Sources/CXKCP/FIPS202-opt64/KeccakP-1600-unrolling.macros create mode 100644 Sources/CXKCP/FIPS202-opt64/KeccakSponge.c create mode 100644 Sources/CXKCP/FIPS202-opt64/KeccakSponge.h create mode 100644 Sources/CXKCP/FIPS202-opt64/KeccakSponge.inc create mode 100644 Sources/CXKCP/FIPS202-opt64/SimpleFIPS202.c create mode 100644 Sources/CXKCP/FIPS202-opt64/SimpleFIPS202.h create mode 100644 Sources/CXKCP/FIPS202-opt64/SnP-Relaned.h create mode 100644 Sources/CXKCP/FIPS202-opt64/align.h create mode 100644 Sources/CXKCP/FIPS202-opt64/brg_endian.h create mode 100644 Sources/CXKCP/FIPS202-opt64/config.h create mode 100644 Sources/CXKCP/PrivacyInfo.xcprivacy create mode 100644 Sources/CXKCP/include/CXKCP.h create mode 100644 Sources/CXKCP/include/module.modulemap create mode 100644 Sources/CXKCP/vendored-sources.txt create mode 100644 Sources/CXKCPShims/CMakeLists.txt create mode 100644 Sources/CXKCPShims/PrivacyInfo.xcprivacy create mode 100644 Sources/CXKCPShims/include/CXKCPShims.h create mode 100644 Sources/CXKCPShims/include/module.modulemap create mode 100644 Sources/CXKCPShims/shims.c create mode 100644 Sources/Crypto/Digests/XKCP/Digest_xkcp.swift create mode 100644 Tests/CXKCPTests/CXKCPTests.swift create mode 100755 scripts/vendor-xkcp.sh diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 19600e3a7..960bdc2ef 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -44,6 +44,8 @@ jobs: { "name": "CCryptoBoringSSL", "type": "source", "exceptions": [] }, { "name": "CCryptoBoringSSLShims", "type": "source", "exceptions": [] }, { "name": "CryptoBoringWrapper", "type": "source", "exceptions": [] }, + { "name": "CXKCP", "type": "source", "exceptions": [] }, + { "name": "CXKCPShims", "type": "source", "exceptions": [] }, { "name": "Crypto", "type": "source", "exceptions": [] }, { "name": "_CryptoExtras", "type": "source", "exceptions": [] }, { "name": "CCryptoBoringSSL", "type": "assembly", "exceptions": [ "*/AES/*.swift" ] } diff --git a/.licenseignore b/.licenseignore index 8f6c1cd38..e0c003fd0 100644 --- a/.licenseignore +++ b/.licenseignore @@ -43,6 +43,7 @@ dev/update-benchmark-thresholds **/*.der .swiftformat Sources/CCryptoBoringSSL/* +Sources/CXKCP/* **/*.swift.gyb scripts/*.patch scripts/gyb diff --git a/.unacceptablelanguageignore b/.unacceptablelanguageignore index 489a21bcb..71e087f52 100644 --- a/.unacceptablelanguageignore +++ b/.unacceptablelanguageignore @@ -1 +1,2 @@ -Sources/CCryptoBoringSSL/* \ No newline at end of file +Sources/CCryptoBoringSSL/* +Sources/CXKCP/* diff --git a/Package.swift b/Package.swift index 3d92c6858..6225fec1a 100644 --- a/Package.swift +++ b/Package.swift @@ -49,6 +49,8 @@ if development || isFreeBSD { "CCryptoBoringSSL", "CCryptoBoringSSLShims", "CryptoBoringWrapper", + "CXKCP", + "CXKCPShims", ] } else { let platforms: [Platform] = [ @@ -66,6 +68,8 @@ if development || isFreeBSD { .target(name: "CCryptoBoringSSL", condition: .when(platforms: platforms)), .target(name: "CCryptoBoringSSLShims", condition: .when(platforms: platforms)), .target(name: "CryptoBoringWrapper", condition: .when(platforms: platforms)), + .target(name: "CXKCP", condition: .when(platforms: platforms)), + .target(name: "CXKCPShims", condition: .when(platforms: platforms)), ] } @@ -125,6 +129,21 @@ let package = Package( .define("OPENSSL_NO_ASM", .when(platforms: [Platform.wasi])), ] ), + .target( + name: "CXKCP", + exclude: [ + "CMakeLists.txt" + ], + cSettings: [ + .define("XKCP_has_KeccakP1600"), + .headerSearchPath("include"), + .headerSearchPath("high"), + .headerSearchPath("low"), + .headerSearchPath("low/KeccakP-1600"), + .headerSearchPath("low/common"), + .headerSearchPath("common"), + ] + ), .target( name: "CCryptoBoringSSLShims", dependencies: ["CCryptoBoringSSL"], @@ -133,6 +152,14 @@ let package = Package( ], resources: privacyManifestResource ), + .target( + name: "CXKCPShims", + dependencies: ["CXKCP"], + exclude: privacyManifestExclude + [ + "CMakeLists.txt" + ], + resources: privacyManifestResource + ), .target( name: "Crypto", dependencies: dependencies, @@ -205,6 +232,7 @@ let package = Package( swiftSettings: swiftSettings ), .testTarget(name: "CryptoBoringWrapperTests", dependencies: ["CryptoBoringWrapper"]), + .testTarget(name: "CXKCPTests", dependencies: ["CXKCP"]), ], cxxLanguageStandard: .cxx17 ) diff --git a/Sources/CMakeLists.txt b/Sources/CMakeLists.txt index 0b6c1643c..55ee7d73b 100644 --- a/Sources/CMakeLists.txt +++ b/Sources/CMakeLists.txt @@ -14,6 +14,8 @@ add_subdirectory(CCryptoBoringSSL) add_subdirectory(CCryptoBoringSSLShims) +add_subdirectory(CXKCP) +add_subdirectory(CXKCPShims) add_subdirectory(CryptoBoringWrapper) add_subdirectory(Crypto) add_subdirectory(_CryptoExtras) diff --git a/Sources/CXKCP/CMakeLists.txt b/Sources/CXKCP/CMakeLists.txt new file mode 100644 index 000000000..d57545d2b --- /dev/null +++ b/Sources/CXKCP/CMakeLists.txt @@ -0,0 +1,34 @@ +##===----------------------------------------------------------------------===## +## +## This source file is part of the SwiftCrypto open source project +## +## Copyright (c) 2021 Apple Inc. and the SwiftCrypto project authors +## Licensed under Apache License v2.0 +## +## See LICENSE.txt for license information +## See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +## +## SPDX-License-Identifier: Apache-2.0 +## +##===----------------------------------------------------------------------===## + +add_library(CXKCP STATIC + "FIPS202-opt64/KeccakHash.c" + "FIPS202-opt64/KeccakP-1600-opt64.c" + "FIPS202-opt64/KeccakSponge.c" + "FIPS202-opt64/SimpleFIPS202.c" +) + +target_include_directories(CXKCP PUBLIC + include) + +target_compile_definitions(CXKCP PRIVATE + $<$:WIN32_LEAN_AND_MEAN>) +target_link_libraries(CXKCP PUBLIC + $<$>:dispatch> + $<$>:Foundation> + SwiftASN1) +set_target_properties(CXKCP PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_SOURCE_DIR}/include;${CMAKE_Swift_MODULE_DIRECTORY}") + +set_property(GLOBAL APPEND PROPERTY SWIFT_CRYPTO_EXPORTS CXKCP) diff --git a/Sources/CXKCP/FIPS202-opt64/KeccakHash.c b/Sources/CXKCP/FIPS202-opt64/KeccakHash.c new file mode 100644 index 000000000..c660f9407 --- /dev/null +++ b/Sources/CXKCP/FIPS202-opt64/KeccakHash.c @@ -0,0 +1,81 @@ +/* +The eXtended Keccak Code Package (XKCP) +https://github.com/XKCP/XKCP + +Keccak, designed by Guido Bertoni, Joan Daemen, Michaël Peeters and Gilles Van Assche. + +Implementation by the designers, hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to the Keccak Team website: +https://keccak.team/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#include +#include "KeccakHash.h" + +/* ---------------------------------------------------------------- */ + +HashReturn Keccak_HashInitialize(Keccak_HashInstance *instance, unsigned int rate, unsigned int capacity, unsigned int hashbitlen, unsigned char delimitedSuffix) +{ + HashReturn result; + + if (delimitedSuffix == 0) + return KECCAK_FAIL; + result = (HashReturn)KeccakWidth1600_SpongeInitialize(&instance->sponge, rate, capacity); + if (result != KECCAK_SUCCESS) + return result; + instance->fixedOutputLength = hashbitlen; + instance->delimitedSuffix = delimitedSuffix; + return KECCAK_SUCCESS; +} + +/* ---------------------------------------------------------------- */ + +HashReturn Keccak_HashUpdate(Keccak_HashInstance *instance, const BitSequence *data, BitLength databitlen) +{ + if ((databitlen % 8) == 0) + return (HashReturn)KeccakWidth1600_SpongeAbsorb(&instance->sponge, data, databitlen/8); + else { + HashReturn ret = (HashReturn)KeccakWidth1600_SpongeAbsorb(&instance->sponge, data, databitlen/8); + if (ret == KECCAK_SUCCESS) { + /* The last partial byte is assumed to be aligned on the least significant bits */ + unsigned char lastByte = data[databitlen/8]; + /* Concatenate the last few bits provided here with those of the suffix */ + unsigned short delimitedLastBytes = (unsigned short)((unsigned short)(lastByte & ((1 << (databitlen % 8)) - 1)) | ((unsigned short)instance->delimitedSuffix << (databitlen % 8))); + if ((delimitedLastBytes & 0xFF00) == 0x0000) { + instance->delimitedSuffix = delimitedLastBytes & 0xFF; + } + else { + unsigned char oneByte[1]; + oneByte[0] = delimitedLastBytes & 0xFF; + ret = (HashReturn)KeccakWidth1600_SpongeAbsorb(&instance->sponge, oneByte, 1); + instance->delimitedSuffix = (delimitedLastBytes >> 8) & 0xFF; + } + } + return ret; + } +} + +/* ---------------------------------------------------------------- */ + +HashReturn Keccak_HashFinal(Keccak_HashInstance *instance, BitSequence *hashval) +{ + HashReturn ret = (HashReturn)KeccakWidth1600_SpongeAbsorbLastFewBits(&instance->sponge, instance->delimitedSuffix); + if (ret == KECCAK_SUCCESS) + return (HashReturn)KeccakWidth1600_SpongeSqueeze(&instance->sponge, hashval, instance->fixedOutputLength/8); + else + return ret; +} + +/* ---------------------------------------------------------------- */ + +HashReturn Keccak_HashSqueeze(Keccak_HashInstance *instance, BitSequence *data, BitLength databitlen) +{ + if ((databitlen % 8) != 0) + return KECCAK_FAIL; + return (HashReturn)KeccakWidth1600_SpongeSqueeze(&instance->sponge, data, databitlen/8); +} diff --git a/Sources/CXKCP/FIPS202-opt64/KeccakHash.h b/Sources/CXKCP/FIPS202-opt64/KeccakHash.h new file mode 100644 index 000000000..e99d99dbc --- /dev/null +++ b/Sources/CXKCP/FIPS202-opt64/KeccakHash.h @@ -0,0 +1,125 @@ +/* +The eXtended Keccak Code Package (XKCP) +https://github.com/XKCP/XKCP + +Keccak, designed by Guido Bertoni, Joan Daemen, Michaël Peeters and Gilles Van Assche. + +Implementation by the designers, hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to the Keccak Team website: +https://keccak.team/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#ifndef _KeccakHashInterface_h_ +#define _KeccakHashInterface_h_ + +#include "config.h" +#ifdef XKCP_has_KeccakP1600 + +#include +#include +#include "KeccakSponge.h" + +#ifndef _Keccak_BitTypes_ +#define _Keccak_BitTypes_ +typedef uint8_t BitSequence; + +typedef size_t BitLength; +#endif + +typedef enum { KECCAK_SUCCESS = 0, KECCAK_FAIL = 1, KECCAK_BAD_HASHLEN = 2 } HashReturn; + +typedef struct { + KeccakWidth1600_SpongeInstance sponge; + unsigned int fixedOutputLength; + unsigned char delimitedSuffix; +} Keccak_HashInstance; + +/** + * Function to initialize the Keccak[r, c] sponge function instance used in sequential hashing mode. + * @param hashInstance Pointer to the hash instance to be initialized. + * @param rate The value of the rate r. + * @param capacity The value of the capacity c. + * @param hashbitlen The desired number of output bits, + * or 0 for an arbitrarily-long output. + * @param delimitedSuffix Bits that will be automatically appended to the end + * of the input message, as in domain separation. + * This is a byte containing from 0 to 7 bits + * formatted like the @a delimitedData parameter of + * the Keccak_SpongeAbsorbLastFewBits() function. + * @pre One must have r+c=1600 and the rate a multiple of 8 bits in this implementation. + * @return KECCAK_SUCCESS if successful, KECCAK_FAIL otherwise. + */ +HashReturn Keccak_HashInitialize(Keccak_HashInstance *hashInstance, unsigned int rate, unsigned int capacity, unsigned int hashbitlen, unsigned char delimitedSuffix); + +/** Macro to initialize a SHAKE128 instance as specified in the FIPS 202 standard. + */ +#define Keccak_HashInitialize_SHAKE128(hashInstance) Keccak_HashInitialize(hashInstance, 1344, 256, 0, 0x1F) + +/** Macro to initialize a SHAKE256 instance as specified in the FIPS 202 standard. + */ +#define Keccak_HashInitialize_SHAKE256(hashInstance) Keccak_HashInitialize(hashInstance, 1088, 512, 0, 0x1F) + +/** Macro to initialize a SHA3-224 instance as specified in the FIPS 202 standard. + */ +#define Keccak_HashInitialize_SHA3_224(hashInstance) Keccak_HashInitialize(hashInstance, 1152, 448, 224, 0x06) + +/** Macro to initialize a SHA3-256 instance as specified in the FIPS 202 standard. + */ +#define Keccak_HashInitialize_SHA3_256(hashInstance) Keccak_HashInitialize(hashInstance, 1088, 512, 256, 0x06) + +/** Macro to initialize a SHA3-384 instance as specified in the FIPS 202 standard. + */ +#define Keccak_HashInitialize_SHA3_384(hashInstance) Keccak_HashInitialize(hashInstance, 832, 768, 384, 0x06) + +/** Macro to initialize a SHA3-512 instance as specified in the FIPS 202 standard. + */ +#define Keccak_HashInitialize_SHA3_512(hashInstance) Keccak_HashInitialize(hashInstance, 576, 1024, 512, 0x06) + +/** + * Function to give input data to be absorbed. + * @param hashInstance Pointer to the hash instance initialized by Keccak_HashInitialize(). + * @param data Pointer to the input data. + * When @a databitLen is not a multiple of 8, the last bits of data must be + * in the least significant bits of the last byte (little-endian convention). + * In this case, the (8 - @a databitLen mod 8) most significant bits + * of the last byte are ignored. + * @param databitLen The number of input bits provided in the input data. + * @pre In the previous call to Keccak_HashUpdate(), databitlen was a multiple of 8. + * @return KECCAK_SUCCESS if successful, KECCAK_FAIL otherwise. + */ +HashReturn Keccak_HashUpdate(Keccak_HashInstance *hashInstance, const BitSequence *data, BitLength databitlen); + +/** + * Function to call after all input blocks have been input and to get + * output bits if the length was specified when calling Keccak_HashInitialize(). + * @param hashInstance Pointer to the hash instance initialized by Keccak_HashInitialize(). + * If @a hashbitlen was not 0 in the call to Keccak_HashInitialize(), the number of + * output bits is equal to @a hashbitlen. + * If @a hashbitlen was 0 in the call to Keccak_HashInitialize(), the output bits + * must be extracted using the Keccak_HashSqueeze() function. + * @param hashval Pointer to the buffer where to store the output data. + * @return KECCAK_SUCCESS if successful, KECCAK_FAIL otherwise. + */ +HashReturn Keccak_HashFinal(Keccak_HashInstance *hashInstance, BitSequence *hashval); + + /** + * Function to squeeze output data. + * @param hashInstance Pointer to the hash instance initialized by Keccak_HashInitialize(). + * @param data Pointer to the buffer where to store the output data. + * @param databitlen The number of output bits desired (must be a multiple of 8). + * @pre Keccak_HashFinal() must have been already called. + * @pre @a databitlen is a multiple of 8. + * @return KECCAK_SUCCESS if successful, KECCAK_FAIL otherwise. + */ +HashReturn Keccak_HashSqueeze(Keccak_HashInstance *hashInstance, BitSequence *data, BitLength databitlen); + +#else +#error This requires an implementation of Keccak-p[1600] +#endif + +#endif diff --git a/Sources/CXKCP/FIPS202-opt64/KeccakP-1600-64.macros b/Sources/CXKCP/FIPS202-opt64/KeccakP-1600-64.macros new file mode 100644 index 000000000..cca65ffb2 --- /dev/null +++ b/Sources/CXKCP/FIPS202-opt64/KeccakP-1600-64.macros @@ -0,0 +1,758 @@ +/* +The eXtended Keccak Code Package (XKCP) +https://github.com/XKCP/XKCP + +The Keccak-p permutations, designed by Guido Bertoni, Joan Daemen, Michaël Peeters and Gilles Van Assche. + +Implementation by Gilles Van Assche and Ronny Van Keer, hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to the Keccak Team website: +https://keccak.team/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#define declareABCDE \ + uint64_t Aba, Abe, Abi, Abo, Abu; \ + uint64_t Aga, Age, Agi, Ago, Agu; \ + uint64_t Aka, Ake, Aki, Ako, Aku; \ + uint64_t Ama, Ame, Ami, Amo, Amu; \ + uint64_t Asa, Ase, Asi, Aso, Asu; \ + uint64_t Bba, Bbe, Bbi, Bbo, Bbu; \ + uint64_t Bga, Bge, Bgi, Bgo, Bgu; \ + uint64_t Bka, Bke, Bki, Bko, Bku; \ + uint64_t Bma, Bme, Bmi, Bmo, Bmu; \ + uint64_t Bsa, Bse, Bsi, Bso, Bsu; \ + uint64_t Ca, Ce, Ci, Co, Cu; \ + uint64_t Da, De, Di, Do, Du; \ + uint64_t Eba, Ebe, Ebi, Ebo, Ebu; \ + uint64_t Ega, Ege, Egi, Ego, Egu; \ + uint64_t Eka, Eke, Eki, Eko, Eku; \ + uint64_t Ema, Eme, Emi, Emo, Emu; \ + uint64_t Esa, Ese, Esi, Eso, Esu; \ + +#define prepareTheta \ + Ca = Aba^Aga^Aka^Ama^Asa; \ + Ce = Abe^Age^Ake^Ame^Ase; \ + Ci = Abi^Agi^Aki^Ami^Asi; \ + Co = Abo^Ago^Ako^Amo^Aso; \ + Cu = Abu^Agu^Aku^Amu^Asu; \ + +#ifdef UseBebigokimisa +/* --- Code for round, with prepare-theta (lane complementing pattern 'bebigokimisa') */ +/* --- 64-bit lanes mapped to 64-bit words */ +#define thetaRhoPiChiIotaPrepareTheta(i, A, E) \ + Da = Cu^ROL64(Ce, 1); \ + De = Ca^ROL64(Ci, 1); \ + Di = Ce^ROL64(Co, 1); \ + Do = Ci^ROL64(Cu, 1); \ + Du = Co^ROL64(Ca, 1); \ +\ + A##ba ^= Da; \ + Bba = A##ba; \ + A##ge ^= De; \ + Bbe = ROL64(A##ge, 44); \ + A##ki ^= Di; \ + Bbi = ROL64(A##ki, 43); \ + A##mo ^= Do; \ + Bbo = ROL64(A##mo, 21); \ + A##su ^= Du; \ + Bbu = ROL64(A##su, 14); \ + E##ba = Bba ^( Bbe | Bbi ); \ + E##ba ^= KeccakF1600RoundConstants[i]; \ + Ca = E##ba; \ + E##be = Bbe ^((~Bbi)| Bbo ); \ + Ce = E##be; \ + E##bi = Bbi ^( Bbo & Bbu ); \ + Ci = E##bi; \ + E##bo = Bbo ^( Bbu | Bba ); \ + Co = E##bo; \ + E##bu = Bbu ^( Bba & Bbe ); \ + Cu = E##bu; \ +\ + A##bo ^= Do; \ + Bga = ROL64(A##bo, 28); \ + A##gu ^= Du; \ + Bge = ROL64(A##gu, 20); \ + A##ka ^= Da; \ + Bgi = ROL64(A##ka, 3); \ + A##me ^= De; \ + Bgo = ROL64(A##me, 45); \ + A##si ^= Di; \ + Bgu = ROL64(A##si, 61); \ + E##ga = Bga ^( Bge | Bgi ); \ + Ca ^= E##ga; \ + E##ge = Bge ^( Bgi & Bgo ); \ + Ce ^= E##ge; \ + E##gi = Bgi ^( Bgo |(~Bgu)); \ + Ci ^= E##gi; \ + E##go = Bgo ^( Bgu | Bga ); \ + Co ^= E##go; \ + E##gu = Bgu ^( Bga & Bge ); \ + Cu ^= E##gu; \ +\ + A##be ^= De; \ + Bka = ROL64(A##be, 1); \ + A##gi ^= Di; \ + Bke = ROL64(A##gi, 6); \ + A##ko ^= Do; \ + Bki = ROL64(A##ko, 25); \ + A##mu ^= Du; \ + Bko = ROL64(A##mu, 8); \ + A##sa ^= Da; \ + Bku = ROL64(A##sa, 18); \ + E##ka = Bka ^( Bke | Bki ); \ + Ca ^= E##ka; \ + E##ke = Bke ^( Bki & Bko ); \ + Ce ^= E##ke; \ + E##ki = Bki ^((~Bko)& Bku ); \ + Ci ^= E##ki; \ + E##ko = (~Bko)^( Bku | Bka ); \ + Co ^= E##ko; \ + E##ku = Bku ^( Bka & Bke ); \ + Cu ^= E##ku; \ +\ + A##bu ^= Du; \ + Bma = ROL64(A##bu, 27); \ + A##ga ^= Da; \ + Bme = ROL64(A##ga, 36); \ + A##ke ^= De; \ + Bmi = ROL64(A##ke, 10); \ + A##mi ^= Di; \ + Bmo = ROL64(A##mi, 15); \ + A##so ^= Do; \ + Bmu = ROL64(A##so, 56); \ + E##ma = Bma ^( Bme & Bmi ); \ + Ca ^= E##ma; \ + E##me = Bme ^( Bmi | Bmo ); \ + Ce ^= E##me; \ + E##mi = Bmi ^((~Bmo)| Bmu ); \ + Ci ^= E##mi; \ + E##mo = (~Bmo)^( Bmu & Bma ); \ + Co ^= E##mo; \ + E##mu = Bmu ^( Bma | Bme ); \ + Cu ^= E##mu; \ +\ + A##bi ^= Di; \ + Bsa = ROL64(A##bi, 62); \ + A##go ^= Do; \ + Bse = ROL64(A##go, 55); \ + A##ku ^= Du; \ + Bsi = ROL64(A##ku, 39); \ + A##ma ^= Da; \ + Bso = ROL64(A##ma, 41); \ + A##se ^= De; \ + Bsu = ROL64(A##se, 2); \ + E##sa = Bsa ^((~Bse)& Bsi ); \ + Ca ^= E##sa; \ + E##se = (~Bse)^( Bsi | Bso ); \ + Ce ^= E##se; \ + E##si = Bsi ^( Bso & Bsu ); \ + Ci ^= E##si; \ + E##so = Bso ^( Bsu | Bsa ); \ + Co ^= E##so; \ + E##su = Bsu ^( Bsa & Bse ); \ + Cu ^= E##su; \ +\ + +/* --- Code for round (lane complementing pattern 'bebigokimisa') */ +/* --- 64-bit lanes mapped to 64-bit words */ +#define thetaRhoPiChiIota(i, A, E) \ + Da = Cu^ROL64(Ce, 1); \ + De = Ca^ROL64(Ci, 1); \ + Di = Ce^ROL64(Co, 1); \ + Do = Ci^ROL64(Cu, 1); \ + Du = Co^ROL64(Ca, 1); \ +\ + A##ba ^= Da; \ + Bba = A##ba; \ + A##ge ^= De; \ + Bbe = ROL64(A##ge, 44); \ + A##ki ^= Di; \ + Bbi = ROL64(A##ki, 43); \ + A##mo ^= Do; \ + Bbo = ROL64(A##mo, 21); \ + A##su ^= Du; \ + Bbu = ROL64(A##su, 14); \ + E##ba = Bba ^( Bbe | Bbi ); \ + E##ba ^= KeccakF1600RoundConstants[i]; \ + E##be = Bbe ^((~Bbi)| Bbo ); \ + E##bi = Bbi ^( Bbo & Bbu ); \ + E##bo = Bbo ^( Bbu | Bba ); \ + E##bu = Bbu ^( Bba & Bbe ); \ +\ + A##bo ^= Do; \ + Bga = ROL64(A##bo, 28); \ + A##gu ^= Du; \ + Bge = ROL64(A##gu, 20); \ + A##ka ^= Da; \ + Bgi = ROL64(A##ka, 3); \ + A##me ^= De; \ + Bgo = ROL64(A##me, 45); \ + A##si ^= Di; \ + Bgu = ROL64(A##si, 61); \ + E##ga = Bga ^( Bge | Bgi ); \ + E##ge = Bge ^( Bgi & Bgo ); \ + E##gi = Bgi ^( Bgo |(~Bgu)); \ + E##go = Bgo ^( Bgu | Bga ); \ + E##gu = Bgu ^( Bga & Bge ); \ +\ + A##be ^= De; \ + Bka = ROL64(A##be, 1); \ + A##gi ^= Di; \ + Bke = ROL64(A##gi, 6); \ + A##ko ^= Do; \ + Bki = ROL64(A##ko, 25); \ + A##mu ^= Du; \ + Bko = ROL64(A##mu, 8); \ + A##sa ^= Da; \ + Bku = ROL64(A##sa, 18); \ + E##ka = Bka ^( Bke | Bki ); \ + E##ke = Bke ^( Bki & Bko ); \ + E##ki = Bki ^((~Bko)& Bku ); \ + E##ko = (~Bko)^( Bku | Bka ); \ + E##ku = Bku ^( Bka & Bke ); \ +\ + A##bu ^= Du; \ + Bma = ROL64(A##bu, 27); \ + A##ga ^= Da; \ + Bme = ROL64(A##ga, 36); \ + A##ke ^= De; \ + Bmi = ROL64(A##ke, 10); \ + A##mi ^= Di; \ + Bmo = ROL64(A##mi, 15); \ + A##so ^= Do; \ + Bmu = ROL64(A##so, 56); \ + E##ma = Bma ^( Bme & Bmi ); \ + E##me = Bme ^( Bmi | Bmo ); \ + E##mi = Bmi ^((~Bmo)| Bmu ); \ + E##mo = (~Bmo)^( Bmu & Bma ); \ + E##mu = Bmu ^( Bma | Bme ); \ +\ + A##bi ^= Di; \ + Bsa = ROL64(A##bi, 62); \ + A##go ^= Do; \ + Bse = ROL64(A##go, 55); \ + A##ku ^= Du; \ + Bsi = ROL64(A##ku, 39); \ + A##ma ^= Da; \ + Bso = ROL64(A##ma, 41); \ + A##se ^= De; \ + Bsu = ROL64(A##se, 2); \ + E##sa = Bsa ^((~Bse)& Bsi ); \ + E##se = (~Bse)^( Bsi | Bso ); \ + E##si = Bsi ^( Bso & Bsu ); \ + E##so = Bso ^( Bsu | Bsa ); \ + E##su = Bsu ^( Bsa & Bse ); \ +\ + +#else /* UseBebigokimisa */ +/* --- Code for round, with prepare-theta */ +/* --- 64-bit lanes mapped to 64-bit words */ +#define thetaRhoPiChiIotaPrepareTheta(i, A, E) \ + Da = Cu^ROL64(Ce, 1); \ + De = Ca^ROL64(Ci, 1); \ + Di = Ce^ROL64(Co, 1); \ + Do = Ci^ROL64(Cu, 1); \ + Du = Co^ROL64(Ca, 1); \ +\ + A##ba ^= Da; \ + Bba = A##ba; \ + A##ge ^= De; \ + Bbe = ROL64(A##ge, 44); \ + A##ki ^= Di; \ + Bbi = ROL64(A##ki, 43); \ + A##mo ^= Do; \ + Bbo = ROL64(A##mo, 21); \ + A##su ^= Du; \ + Bbu = ROL64(A##su, 14); \ + E##ba = Bba ^((~Bbe)& Bbi ); \ + E##ba ^= KeccakF1600RoundConstants[i]; \ + Ca = E##ba; \ + E##be = Bbe ^((~Bbi)& Bbo ); \ + Ce = E##be; \ + E##bi = Bbi ^((~Bbo)& Bbu ); \ + Ci = E##bi; \ + E##bo = Bbo ^((~Bbu)& Bba ); \ + Co = E##bo; \ + E##bu = Bbu ^((~Bba)& Bbe ); \ + Cu = E##bu; \ +\ + A##bo ^= Do; \ + Bga = ROL64(A##bo, 28); \ + A##gu ^= Du; \ + Bge = ROL64(A##gu, 20); \ + A##ka ^= Da; \ + Bgi = ROL64(A##ka, 3); \ + A##me ^= De; \ + Bgo = ROL64(A##me, 45); \ + A##si ^= Di; \ + Bgu = ROL64(A##si, 61); \ + E##ga = Bga ^((~Bge)& Bgi ); \ + Ca ^= E##ga; \ + E##ge = Bge ^((~Bgi)& Bgo ); \ + Ce ^= E##ge; \ + E##gi = Bgi ^((~Bgo)& Bgu ); \ + Ci ^= E##gi; \ + E##go = Bgo ^((~Bgu)& Bga ); \ + Co ^= E##go; \ + E##gu = Bgu ^((~Bga)& Bge ); \ + Cu ^= E##gu; \ +\ + A##be ^= De; \ + Bka = ROL64(A##be, 1); \ + A##gi ^= Di; \ + Bke = ROL64(A##gi, 6); \ + A##ko ^= Do; \ + Bki = ROL64(A##ko, 25); \ + A##mu ^= Du; \ + Bko = ROL64(A##mu, 8); \ + A##sa ^= Da; \ + Bku = ROL64(A##sa, 18); \ + E##ka = Bka ^((~Bke)& Bki ); \ + Ca ^= E##ka; \ + E##ke = Bke ^((~Bki)& Bko ); \ + Ce ^= E##ke; \ + E##ki = Bki ^((~Bko)& Bku ); \ + Ci ^= E##ki; \ + E##ko = Bko ^((~Bku)& Bka ); \ + Co ^= E##ko; \ + E##ku = Bku ^((~Bka)& Bke ); \ + Cu ^= E##ku; \ +\ + A##bu ^= Du; \ + Bma = ROL64(A##bu, 27); \ + A##ga ^= Da; \ + Bme = ROL64(A##ga, 36); \ + A##ke ^= De; \ + Bmi = ROL64(A##ke, 10); \ + A##mi ^= Di; \ + Bmo = ROL64(A##mi, 15); \ + A##so ^= Do; \ + Bmu = ROL64(A##so, 56); \ + E##ma = Bma ^((~Bme)& Bmi ); \ + Ca ^= E##ma; \ + E##me = Bme ^((~Bmi)& Bmo ); \ + Ce ^= E##me; \ + E##mi = Bmi ^((~Bmo)& Bmu ); \ + Ci ^= E##mi; \ + E##mo = Bmo ^((~Bmu)& Bma ); \ + Co ^= E##mo; \ + E##mu = Bmu ^((~Bma)& Bme ); \ + Cu ^= E##mu; \ +\ + A##bi ^= Di; \ + Bsa = ROL64(A##bi, 62); \ + A##go ^= Do; \ + Bse = ROL64(A##go, 55); \ + A##ku ^= Du; \ + Bsi = ROL64(A##ku, 39); \ + A##ma ^= Da; \ + Bso = ROL64(A##ma, 41); \ + A##se ^= De; \ + Bsu = ROL64(A##se, 2); \ + E##sa = Bsa ^((~Bse)& Bsi ); \ + Ca ^= E##sa; \ + E##se = Bse ^((~Bsi)& Bso ); \ + Ce ^= E##se; \ + E##si = Bsi ^((~Bso)& Bsu ); \ + Ci ^= E##si; \ + E##so = Bso ^((~Bsu)& Bsa ); \ + Co ^= E##so; \ + E##su = Bsu ^((~Bsa)& Bse ); \ + Cu ^= E##su; \ +\ + +/* --- Code for round */ +/* --- 64-bit lanes mapped to 64-bit words */ +#define thetaRhoPiChiIota(i, A, E) \ + Da = Cu^ROL64(Ce, 1); \ + De = Ca^ROL64(Ci, 1); \ + Di = Ce^ROL64(Co, 1); \ + Do = Ci^ROL64(Cu, 1); \ + Du = Co^ROL64(Ca, 1); \ +\ + A##ba ^= Da; \ + Bba = A##ba; \ + A##ge ^= De; \ + Bbe = ROL64(A##ge, 44); \ + A##ki ^= Di; \ + Bbi = ROL64(A##ki, 43); \ + A##mo ^= Do; \ + Bbo = ROL64(A##mo, 21); \ + A##su ^= Du; \ + Bbu = ROL64(A##su, 14); \ + E##ba = Bba ^((~Bbe)& Bbi ); \ + E##ba ^= KeccakF1600RoundConstants[i]; \ + E##be = Bbe ^((~Bbi)& Bbo ); \ + E##bi = Bbi ^((~Bbo)& Bbu ); \ + E##bo = Bbo ^((~Bbu)& Bba ); \ + E##bu = Bbu ^((~Bba)& Bbe ); \ +\ + A##bo ^= Do; \ + Bga = ROL64(A##bo, 28); \ + A##gu ^= Du; \ + Bge = ROL64(A##gu, 20); \ + A##ka ^= Da; \ + Bgi = ROL64(A##ka, 3); \ + A##me ^= De; \ + Bgo = ROL64(A##me, 45); \ + A##si ^= Di; \ + Bgu = ROL64(A##si, 61); \ + E##ga = Bga ^((~Bge)& Bgi ); \ + E##ge = Bge ^((~Bgi)& Bgo ); \ + E##gi = Bgi ^((~Bgo)& Bgu ); \ + E##go = Bgo ^((~Bgu)& Bga ); \ + E##gu = Bgu ^((~Bga)& Bge ); \ +\ + A##be ^= De; \ + Bka = ROL64(A##be, 1); \ + A##gi ^= Di; \ + Bke = ROL64(A##gi, 6); \ + A##ko ^= Do; \ + Bki = ROL64(A##ko, 25); \ + A##mu ^= Du; \ + Bko = ROL64(A##mu, 8); \ + A##sa ^= Da; \ + Bku = ROL64(A##sa, 18); \ + E##ka = Bka ^((~Bke)& Bki ); \ + E##ke = Bke ^((~Bki)& Bko ); \ + E##ki = Bki ^((~Bko)& Bku ); \ + E##ko = Bko ^((~Bku)& Bka ); \ + E##ku = Bku ^((~Bka)& Bke ); \ +\ + A##bu ^= Du; \ + Bma = ROL64(A##bu, 27); \ + A##ga ^= Da; \ + Bme = ROL64(A##ga, 36); \ + A##ke ^= De; \ + Bmi = ROL64(A##ke, 10); \ + A##mi ^= Di; \ + Bmo = ROL64(A##mi, 15); \ + A##so ^= Do; \ + Bmu = ROL64(A##so, 56); \ + E##ma = Bma ^((~Bme)& Bmi ); \ + E##me = Bme ^((~Bmi)& Bmo ); \ + E##mi = Bmi ^((~Bmo)& Bmu ); \ + E##mo = Bmo ^((~Bmu)& Bma ); \ + E##mu = Bmu ^((~Bma)& Bme ); \ +\ + A##bi ^= Di; \ + Bsa = ROL64(A##bi, 62); \ + A##go ^= Do; \ + Bse = ROL64(A##go, 55); \ + A##ku ^= Du; \ + Bsi = ROL64(A##ku, 39); \ + A##ma ^= Da; \ + Bso = ROL64(A##ma, 41); \ + A##se ^= De; \ + Bsu = ROL64(A##se, 2); \ + E##sa = Bsa ^((~Bse)& Bsi ); \ + E##se = Bse ^((~Bsi)& Bso ); \ + E##si = Bsi ^((~Bso)& Bsu ); \ + E##so = Bso ^((~Bsu)& Bsa ); \ + E##su = Bsu ^((~Bsa)& Bse ); \ +\ + +#endif /* UseBebigokimisa */ + +#define copyFromState(X, state) \ + X##ba = state[ 0]; \ + X##be = state[ 1]; \ + X##bi = state[ 2]; \ + X##bo = state[ 3]; \ + X##bu = state[ 4]; \ + X##ga = state[ 5]; \ + X##ge = state[ 6]; \ + X##gi = state[ 7]; \ + X##go = state[ 8]; \ + X##gu = state[ 9]; \ + X##ka = state[10]; \ + X##ke = state[11]; \ + X##ki = state[12]; \ + X##ko = state[13]; \ + X##ku = state[14]; \ + X##ma = state[15]; \ + X##me = state[16]; \ + X##mi = state[17]; \ + X##mo = state[18]; \ + X##mu = state[19]; \ + X##sa = state[20]; \ + X##se = state[21]; \ + X##si = state[22]; \ + X##so = state[23]; \ + X##su = state[24]; \ + +#define copyToState(state, X) \ + state[ 0] = X##ba; \ + state[ 1] = X##be; \ + state[ 2] = X##bi; \ + state[ 3] = X##bo; \ + state[ 4] = X##bu; \ + state[ 5] = X##ga; \ + state[ 6] = X##ge; \ + state[ 7] = X##gi; \ + state[ 8] = X##go; \ + state[ 9] = X##gu; \ + state[10] = X##ka; \ + state[11] = X##ke; \ + state[12] = X##ki; \ + state[13] = X##ko; \ + state[14] = X##ku; \ + state[15] = X##ma; \ + state[16] = X##me; \ + state[17] = X##mi; \ + state[18] = X##mo; \ + state[19] = X##mu; \ + state[20] = X##sa; \ + state[21] = X##se; \ + state[22] = X##si; \ + state[23] = X##so; \ + state[24] = X##su; \ + +#define copyStateVariables(X, Y) \ + X##ba = Y##ba; \ + X##be = Y##be; \ + X##bi = Y##bi; \ + X##bo = Y##bo; \ + X##bu = Y##bu; \ + X##ga = Y##ga; \ + X##ge = Y##ge; \ + X##gi = Y##gi; \ + X##go = Y##go; \ + X##gu = Y##gu; \ + X##ka = Y##ka; \ + X##ke = Y##ke; \ + X##ki = Y##ki; \ + X##ko = Y##ko; \ + X##ku = Y##ku; \ + X##ma = Y##ma; \ + X##me = Y##me; \ + X##mi = Y##mi; \ + X##mo = Y##mo; \ + X##mu = Y##mu; \ + X##sa = Y##sa; \ + X##se = Y##se; \ + X##si = Y##si; \ + X##so = Y##so; \ + X##su = Y##su; \ + +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) +#define HTOLE64(x) (x) +#else +/* + * Big Endian platforms macro to swap data. + * + * NOTE: we cannot directly use the 64-bit input + * of the following macro because of possible alignment + * constraints (on some platforms such as Sparc or MIPS, + * dereferencing an uint64_t on a buffer not aligned on the + * word size will induce a 'bus error'). Instead, we read and + * swap the data byte per byte. + */ +#define HTOLE64(x) \ + ( ((uint64_t) (((uint8_t*)&(x))[ 7]) << 56 ) \ + | ((uint64_t) (((uint8_t*)&(x))[ 6]) << 48 ) \ + | ((uint64_t) (((uint8_t*)&(x))[ 5]) << 40 ) \ + | ((uint64_t) (((uint8_t*)&(x))[ 4]) << 32 ) \ + | ((uint64_t) (((uint8_t*)&(x))[ 3]) << 24 ) \ + | ((uint64_t) (((uint8_t*)&(x))[ 2]) << 16 ) \ + | ((uint64_t) (((uint8_t*)&(x))[ 1]) << 8 ) \ + | ((uint64_t) (((uint8_t*)&(x))[ 0]))) +#endif + +#define addInput(X, input, laneCount) \ + if (laneCount == 21) { \ + X##ba ^= HTOLE64(input[ 0]); \ + X##be ^= HTOLE64(input[ 1]); \ + X##bi ^= HTOLE64(input[ 2]); \ + X##bo ^= HTOLE64(input[ 3]); \ + X##bu ^= HTOLE64(input[ 4]); \ + X##ga ^= HTOLE64(input[ 5]); \ + X##ge ^= HTOLE64(input[ 6]); \ + X##gi ^= HTOLE64(input[ 7]); \ + X##go ^= HTOLE64(input[ 8]); \ + X##gu ^= HTOLE64(input[ 9]); \ + X##ka ^= HTOLE64(input[10]); \ + X##ke ^= HTOLE64(input[11]); \ + X##ki ^= HTOLE64(input[12]); \ + X##ko ^= HTOLE64(input[13]); \ + X##ku ^= HTOLE64(input[14]); \ + X##ma ^= HTOLE64(input[15]); \ + X##me ^= HTOLE64(input[16]); \ + X##mi ^= HTOLE64(input[17]); \ + X##mo ^= HTOLE64(input[18]); \ + X##mu ^= HTOLE64(input[19]); \ + X##sa ^= HTOLE64(input[20]); \ + } \ + else if (laneCount < 16) { \ + if (laneCount < 8) { \ + if (laneCount < 4) { \ + if (laneCount < 2) { \ + if (laneCount < 1) { \ + } \ + else { \ + X##ba ^= HTOLE64(input[ 0]); \ + } \ + } \ + else { \ + X##ba ^= HTOLE64(input[ 0]); \ + X##be ^= HTOLE64(input[ 1]); \ + if (laneCount < 3) { \ + } \ + else { \ + X##bi ^= HTOLE64(input[ 2]); \ + } \ + } \ + } \ + else { \ + X##ba ^= HTOLE64(input[ 0]); \ + X##be ^= HTOLE64(input[ 1]); \ + X##bi ^= HTOLE64(input[ 2]); \ + X##bo ^= HTOLE64(input[ 3]); \ + if (laneCount < 6) { \ + if (laneCount < 5) { \ + } \ + else { \ + X##bu ^= HTOLE64(input[ 4]); \ + } \ + } \ + else { \ + X##bu ^= HTOLE64(input[ 4]); \ + X##ga ^= HTOLE64(input[ 5]); \ + if (laneCount < 7) { \ + } \ + else { \ + X##ge ^= HTOLE64(input[ 6]); \ + } \ + } \ + } \ + } \ + else { \ + X##ba ^= HTOLE64(input[ 0]); \ + X##be ^= HTOLE64(input[ 1]); \ + X##bi ^= HTOLE64(input[ 2]); \ + X##bo ^= HTOLE64(input[ 3]); \ + X##bu ^= HTOLE64(input[ 4]); \ + X##ga ^= HTOLE64(input[ 5]); \ + X##ge ^= HTOLE64(input[ 6]); \ + X##gi ^= HTOLE64(input[ 7]); \ + if (laneCount < 12) { \ + if (laneCount < 10) { \ + if (laneCount < 9) { \ + } \ + else { \ + X##go ^= HTOLE64(input[ 8]); \ + } \ + } \ + else { \ + X##go ^= HTOLE64(input[ 8]); \ + X##gu ^= HTOLE64(input[ 9]); \ + if (laneCount < 11) { \ + } \ + else { \ + X##ka ^= HTOLE64(input[10]); \ + } \ + } \ + } \ + else { \ + X##go ^= HTOLE64(input[ 8]); \ + X##gu ^= HTOLE64(input[ 9]); \ + X##ka ^= HTOLE64(input[10]); \ + X##ke ^= HTOLE64(input[11]); \ + if (laneCount < 14) { \ + if (laneCount < 13) { \ + } \ + else { \ + X##ki ^= HTOLE64(input[12]); \ + } \ + } \ + else { \ + X##ki ^= HTOLE64(input[12]); \ + X##ko ^= HTOLE64(input[13]); \ + if (laneCount < 15) { \ + } \ + else { \ + X##ku ^= HTOLE64(input[14]); \ + } \ + } \ + } \ + } \ + } \ + else { \ + X##ba ^= HTOLE64(input[ 0]); \ + X##be ^= HTOLE64(input[ 1]); \ + X##bi ^= HTOLE64(input[ 2]); \ + X##bo ^= HTOLE64(input[ 3]); \ + X##bu ^= HTOLE64(input[ 4]); \ + X##ga ^= HTOLE64(input[ 5]); \ + X##ge ^= HTOLE64(input[ 6]); \ + X##gi ^= HTOLE64(input[ 7]); \ + X##go ^= HTOLE64(input[ 8]); \ + X##gu ^= HTOLE64(input[ 9]); \ + X##ka ^= HTOLE64(input[10]); \ + X##ke ^= HTOLE64(input[11]); \ + X##ki ^= HTOLE64(input[12]); \ + X##ko ^= HTOLE64(input[13]); \ + X##ku ^= HTOLE64(input[14]); \ + X##ma ^= HTOLE64(input[15]); \ + if (laneCount < 24) { \ + if (laneCount < 20) { \ + if (laneCount < 18) { \ + if (laneCount < 17) { \ + } \ + else { \ + X##me ^= HTOLE64(input[16]); \ + } \ + } \ + else { \ + X##me ^= HTOLE64(input[16]); \ + X##mi ^= HTOLE64(input[17]); \ + if (laneCount < 19) { \ + } \ + else { \ + X##mo ^= HTOLE64(input[18]); \ + } \ + } \ + } \ + else { \ + X##me ^= HTOLE64(input[16]); \ + X##mi ^= HTOLE64(input[17]); \ + X##mo ^= HTOLE64(input[18]); \ + X##mu ^= HTOLE64(input[19]); \ + if (laneCount < 22) { \ + if (laneCount < 21) { \ + } \ + else { \ + X##sa ^= HTOLE64(input[20]); \ + } \ + } \ + else { \ + X##sa ^= HTOLE64(input[20]); \ + X##se ^= HTOLE64(input[21]); \ + if (laneCount < 23) { \ + } \ + else { \ + X##si ^= HTOLE64(input[22]); \ + } \ + } \ + } \ + } \ + else { \ + X##me ^= HTOLE64(input[16]); \ + X##mi ^= HTOLE64(input[17]); \ + X##mo ^= HTOLE64(input[18]); \ + X##mu ^= HTOLE64(input[19]); \ + X##sa ^= HTOLE64(input[20]); \ + X##se ^= HTOLE64(input[21]); \ + X##si ^= HTOLE64(input[22]); \ + X##so ^= HTOLE64(input[23]); \ + if (laneCount < 25) { \ + } \ + else { \ + X##su ^= HTOLE64(input[24]); \ + } \ + } \ + } diff --git a/Sources/CXKCP/FIPS202-opt64/KeccakP-1600-SnP.h b/Sources/CXKCP/FIPS202-opt64/KeccakP-1600-SnP.h new file mode 100644 index 000000000..4d0ce7c44 --- /dev/null +++ b/Sources/CXKCP/FIPS202-opt64/KeccakP-1600-SnP.h @@ -0,0 +1,59 @@ +/* +The eXtended Keccak Code Package (XKCP) +https://github.com/XKCP/XKCP + +The Keccak-p permutations, designed by Guido Bertoni, Joan Daemen, Michaël Peeters and Gilles Van Assche. + +Implementation by Gilles Van Assche and Ronny Van Keer, hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to the Keccak Team website: +https://keccak.team/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ + +--- + +Please refer to SnP-documentation.h for more details. +*/ + +#ifndef _KeccakP_1600_SnP_h_ +#define _KeccakP_1600_SnP_h_ + +#include +#include + +#include "brg_endian.h" +#include "KeccakP-1600-opt64-config.h" + +typedef struct { + uint64_t A[25]; +} KeccakP1600_plain64_state; + +typedef KeccakP1600_plain64_state KeccakP1600_state; + +#define KeccakP1600_implementation "generic 64-bit optimized implementation (" KeccakP1600_implementation_config ")" +#define KeccakF1600_FastLoop_supported +#define KeccakP1600_12rounds_FastLoop_supported + +#define KeccakP1600_StaticInitialize() +void KeccakP1600_Initialize(KeccakP1600_plain64_state *state); +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) +#define KeccakP1600_AddByte(state, byte, offset) \ + ((unsigned char*)(state))[(offset)] ^= (byte) +#else +void KeccakP1600_AddByte(KeccakP1600_plain64_state *state, unsigned char data, unsigned int offset); +#endif +void KeccakP1600_AddBytes(KeccakP1600_plain64_state *state, const unsigned char *data, unsigned int offset, unsigned int length); +void KeccakP1600_OverwriteBytes(KeccakP1600_plain64_state *state, const unsigned char *data, unsigned int offset, unsigned int length); +void KeccakP1600_OverwriteWithZeroes(KeccakP1600_plain64_state *state, unsigned int byteCount); +void KeccakP1600_Permute_Nrounds(KeccakP1600_plain64_state *state, unsigned int nrounds); +void KeccakP1600_Permute_12rounds(KeccakP1600_plain64_state *state); +void KeccakP1600_Permute_24rounds(KeccakP1600_plain64_state *state); +void KeccakP1600_ExtractBytes(const KeccakP1600_plain64_state *state, unsigned char *data, unsigned int offset, unsigned int length); +void KeccakP1600_ExtractAndAddBytes(const KeccakP1600_plain64_state *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length); +size_t KeccakF1600_FastLoop_Absorb(KeccakP1600_plain64_state *state, unsigned int laneCount, const unsigned char *data, size_t dataByteLen); +size_t KeccakP1600_12rounds_FastLoop_Absorb(KeccakP1600_plain64_state *state, unsigned int laneCount, const unsigned char *data, size_t dataByteLen); + +#endif diff --git a/Sources/CXKCP/FIPS202-opt64/KeccakP-1600-opt64-config.h b/Sources/CXKCP/FIPS202-opt64/KeccakP-1600-opt64-config.h new file mode 100644 index 000000000..085b6c958 --- /dev/null +++ b/Sources/CXKCP/FIPS202-opt64/KeccakP-1600-opt64-config.h @@ -0,0 +1,6 @@ +/* +This file defines some parameters of the implementation in the parent directory. +*/ + +#define KeccakP1600_implementation_config "all rounds unrolled" +#define KeccakP1600_fullUnrolling diff --git a/Sources/CXKCP/FIPS202-opt64/KeccakP-1600-opt64.c b/Sources/CXKCP/FIPS202-opt64/KeccakP-1600-opt64.c new file mode 100644 index 000000000..c9c345ce4 --- /dev/null +++ b/Sources/CXKCP/FIPS202-opt64/KeccakP-1600-opt64.c @@ -0,0 +1,565 @@ +/* +The eXtended Keccak Code Package (XKCP) +https://github.com/XKCP/XKCP + +The Keccak-p permutations, designed by Guido Bertoni, Joan Daemen, Michaël Peeters and Gilles Van Assche. + +Implementation by Gilles Van Assche and Ronny Van Keer, hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to the Keccak Team website: +https://keccak.team/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ + +--- + +This file implements Keccak-p[1600] in a SnP-compatible way. +Please refer to SnP-documentation.h for more details. + +This implementation comes with KeccakP-1600-SnP.h in the same folder. +Please refer to LowLevel.build for the exact list of other files it must be combined with. +*/ + +#include +#include +#include +#include "brg_endian.h" +#include "KeccakP-1600-SnP.h" + +#if defined(KeccakP1600_useLaneComplementing) +#define UseBebigokimisa +#endif + +#if defined(_MSC_VER) +#define ROL64(a, offset) _rotl64(a, offset) +#elif defined(KeccakP1600_useSHLD) + #define ROL64(x,N) ({ \ + register uint64_t __out; \ + register uint64_t __in = x; \ + __asm__ ("shld %2,%0,%0" : "=r"(__out) : "0"(__in), "i"(N)); \ + __out; \ + }) +#else +#define ROL64(a, offset) ((((uint64_t)a) << offset) ^ (((uint64_t)a) >> (64-offset))) +#endif + +#include "KeccakP-1600-64.macros" +#ifdef KeccakP1600_fullUnrolling +#define FullUnrolling +#else +#define Unrolling KeccakP1600_unrolling +#endif +#include "KeccakP-1600-unrolling.macros" +#include "SnP-Relaned.h" + +static const uint64_t KeccakF1600RoundConstants[24] = { + 0x0000000000000001ULL, + 0x0000000000008082ULL, + 0x800000000000808aULL, + 0x8000000080008000ULL, + 0x000000000000808bULL, + 0x0000000080000001ULL, + 0x8000000080008081ULL, + 0x8000000000008009ULL, + 0x000000000000008aULL, + 0x0000000000000088ULL, + 0x0000000080008009ULL, + 0x000000008000000aULL, + 0x000000008000808bULL, + 0x800000000000008bULL, + 0x8000000000008089ULL, + 0x8000000000008003ULL, + 0x8000000000008002ULL, + 0x8000000000000080ULL, + 0x000000000000800aULL, + 0x800000008000000aULL, + 0x8000000080008081ULL, + 0x8000000000008080ULL, + 0x0000000080000001ULL, + 0x8000000080008008ULL }; + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_Initialize(KeccakP1600_plain64_state *state) +{ + memset(state, 0, 200); +#ifdef KeccakP1600_useLaneComplementing + state->A[ 1] = ~(uint64_t)0; + state->A[ 2] = ~(uint64_t)0; + state->A[ 8] = ~(uint64_t)0; + state->A[12] = ~(uint64_t)0; + state->A[17] = ~(uint64_t)0; + state->A[20] = ~(uint64_t)0; +#endif +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_AddBytesInLane(KeccakP1600_plain64_state *state, unsigned int lanePosition, const unsigned char *data, unsigned int offset, unsigned int length) +{ +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) + uint64_t lane; + if (length == 0) + return; + if (length == 1) + lane = data[0]; + else { + lane = 0; + memcpy(&lane, data, length); + } + lane <<= offset*8; +#else + uint64_t lane = 0; + unsigned int i; + for(i=0; iA[lanePosition] ^= lane; +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_AddLanes(KeccakP1600_plain64_state *state, const unsigned char *data, unsigned int laneCount) +{ +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) + unsigned int i = 0; +#ifdef NO_MISALIGNED_ACCESSES + /* If either pointer is misaligned, fall back to byte-wise xor. */ + if (((((uintptr_t)state) & 7) != 0) || ((((uintptr_t)data) & 7) != 0)) { + for (i = 0; i < laneCount * 8; i++) { + ((unsigned char*)state)[i] ^= data[i]; + } + } + else +#endif + { + /* Otherwise... */ + for( ; (i+8)<=laneCount; i+=8) { + state->A[i+0] ^= ((uint64_t*)data)[i+0]; + state->A[i+1] ^= ((uint64_t*)data)[i+1]; + state->A[i+2] ^= ((uint64_t*)data)[i+2]; + state->A[i+3] ^= ((uint64_t*)data)[i+3]; + state->A[i+4] ^= ((uint64_t*)data)[i+4]; + state->A[i+5] ^= ((uint64_t*)data)[i+5]; + state->A[i+6] ^= ((uint64_t*)data)[i+6]; + state->A[i+7] ^= ((uint64_t*)data)[i+7]; + } + for( ; (i+4)<=laneCount; i+=4) { + state->A[i+0] ^= ((uint64_t*)data)[i+0]; + state->A[i+1] ^= ((uint64_t*)data)[i+1]; + state->A[i+2] ^= ((uint64_t*)data)[i+2]; + state->A[i+3] ^= ((uint64_t*)data)[i+3]; + } + for( ; (i+2)<=laneCount; i+=2) { + state->A[i+0] ^= ((uint64_t*)data)[i+0]; + state->A[i+1] ^= ((uint64_t*)data)[i+1]; + } + if (iA[i+0] ^= ((uint64_t*)data)[i+0]; + } + } +#else + unsigned int i; + const uint8_t *curData = data; + for(i=0; iA[i] ^= lane; + } +#endif +} + +/* ---------------------------------------------------------------- */ + +#if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN) +void KeccakP1600_AddByte(KeccakP1600_plain64_state *state, unsigned char byte, unsigned int offset) +{ + uint64_t lane = byte; + lane <<= (offset%8)*8; + state->A[offset/8] ^= lane; +} +#endif + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_AddBytes(KeccakP1600_plain64_state *state, const unsigned char *data, unsigned int offset, unsigned int length) +{ + SnP_AddBytes(state, data, offset, length, KeccakP1600_AddLanes, KeccakP1600_AddBytesInLane, 8); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_OverwriteBytesInLane(KeccakP1600_plain64_state *state, unsigned int lanePosition, const unsigned char *data, unsigned int offset, unsigned int length) +{ +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) +#ifdef KeccakP1600_useLaneComplementing + if ((lanePosition == 1) || (lanePosition == 2) || (lanePosition == 8) || (lanePosition == 12) || (lanePosition == 17) || (lanePosition == 20)) { + unsigned int i; + for(i=0; iA[lanePosition]; + unsigned int i; + for(i=0; iA[lanePosition] = lane; +#endif +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_OverwriteLanes(KeccakP1600_plain64_state *state, const unsigned char *data, unsigned int laneCount) +{ +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) +#ifdef KeccakP1600_useLaneComplementing + unsigned int lanePosition; + + for(lanePosition=0; lanePositionA[lanePosition] = ~((const uint64_t*)data)[lanePosition]; + else + state->A[lanePosition] = ((const uint64_t*)data)[lanePosition]; +#else + memcpy(state, data, laneCount*8); +#endif +#else + unsigned int lanePosition; + const uint8_t *curData = data; + for(lanePosition=0; lanePositionA[lanePosition] = ~lane; + else +#endif + state->A[lanePosition] = lane; + } +#endif +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_OverwriteBytes(KeccakP1600_plain64_state *state, const unsigned char *data, unsigned int offset, unsigned int length) +{ + SnP_OverwriteBytes(state, data, offset, length, KeccakP1600_OverwriteLanes, KeccakP1600_OverwriteBytesInLane, 8); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_OverwriteWithZeroes(KeccakP1600_plain64_state *state, unsigned int byteCount) +{ +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) +#ifdef KeccakP1600_useLaneComplementing + unsigned int lanePosition; + + for(lanePosition=0; lanePositionA[lanePosition] = ~0; + else + state->A[lanePosition] = 0; + if (byteCount%8 != 0) { + lanePosition = byteCount/8; + if ((lanePosition == 1) || (lanePosition == 2) || (lanePosition == 8) || (lanePosition == 12) || (lanePosition == 17) || (lanePosition == 20)) + memset((unsigned char*)state+lanePosition*8, 0xFF, byteCount%8); + else + memset((unsigned char*)state+lanePosition*8, 0, byteCount%8); + } +#else + memset(state, 0, byteCount); +#endif +#else + unsigned int i, j; + for(i=0; iA[lanePosition] = ~(uint64_t)0; + else +#endif + state->A[lanePosition] = 0; + } + else { + uint64_t lane = state->A[lanePosition]; + for(j=0; jA[lanePosition] = lane; + } + } +#endif +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_Permute_Nrounds(KeccakP1600_plain64_state *state, unsigned int nr) +{ + declareABCDE + unsigned int i; + uint64_t *stateAsLanes = state->A; + + copyFromState(A, stateAsLanes) + roundsN(nr) + copyToState(stateAsLanes, A) + +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_Permute_24rounds(KeccakP1600_plain64_state *state) +{ + declareABCDE + #ifndef KeccakP1600_fullUnrolling + unsigned int i; + #endif + uint64_t *stateAsLanes = state->A; + + copyFromState(A, stateAsLanes) + rounds24 + copyToState(stateAsLanes, A) +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_Permute_12rounds(KeccakP1600_plain64_state *state) +{ + declareABCDE + #ifndef KeccakP1600_fullUnrolling + unsigned int i; + #endif + uint64_t *stateAsLanes = state->A; + + copyFromState(A, stateAsLanes) + rounds12 + copyToState(stateAsLanes, A) +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_ExtractBytesInLane(const KeccakP1600_plain64_state *state, unsigned int lanePosition, unsigned char *data, unsigned int offset, unsigned int length) +{ + uint64_t lane = state->A[lanePosition]; +#ifdef KeccakP1600_useLaneComplementing + if ((lanePosition == 1) || (lanePosition == 2) || (lanePosition == 8) || (lanePosition == 12) || (lanePosition == 17) || (lanePosition == 20)) + lane = ~lane; +#endif +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) + { + uint64_t lane1[1]; + lane1[0] = lane; + memcpy(data, (uint8_t*)lane1+offset, length); + } +#else + unsigned int i; + lane >>= offset*8; + for(i=0; i>= 8; + } +#endif +} + +/* ---------------------------------------------------------------- */ + +#if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN) +static void fromWordToBytes(uint8_t *bytes, const uint64_t word) +{ + unsigned int i; + + for(i=0; i<(64/8); i++) + bytes[i] = (word >> (8*i)) & 0xFF; +} +#endif + +void KeccakP1600_ExtractLanes(const KeccakP1600_plain64_state *state, unsigned char *data, unsigned int laneCount) +{ +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) + memcpy(data, state, laneCount*8); +#else + unsigned int i; + + for(i=0; i 1) { + ((uint64_t*)data)[ 1] = ~((uint64_t*)data)[ 1]; + if (laneCount > 2) { + ((uint64_t*)data)[ 2] = ~((uint64_t*)data)[ 2]; + if (laneCount > 8) { + ((uint64_t*)data)[ 8] = ~((uint64_t*)data)[ 8]; + if (laneCount > 12) { + ((uint64_t*)data)[12] = ~((uint64_t*)data)[12]; + if (laneCount > 17) { + ((uint64_t*)data)[17] = ~((uint64_t*)data)[17]; + if (laneCount > 20) { + ((uint64_t*)data)[20] = ~((uint64_t*)data)[20]; + } + } + } + } + } + } +#endif +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_ExtractBytes(const KeccakP1600_plain64_state *state, unsigned char *data, unsigned int offset, unsigned int length) +{ + SnP_ExtractBytes(state, data, offset, length, KeccakP1600_ExtractLanes, KeccakP1600_ExtractBytesInLane, 8); +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_ExtractAndAddBytesInLane(const KeccakP1600_plain64_state *state, unsigned int lanePosition, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length) +{ + uint64_t lane = state->A[lanePosition]; +#ifdef KeccakP1600_useLaneComplementing + if ((lanePosition == 1) || (lanePosition == 2) || (lanePosition == 8) || (lanePosition == 12) || (lanePosition == 17) || (lanePosition == 20)) + lane = ~lane; +#endif +#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) + { + unsigned int i; + uint64_t lane1[1]; + lane1[0] = lane; + for(i=0; i>= offset*8; + for(i=0; i>= 8; + } +#endif +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_ExtractAndAddLanes(const KeccakP1600_plain64_state *state, const unsigned char *input, unsigned char *output, unsigned int laneCount) +{ + unsigned int i; +#if (PLATFORM_BYTE_ORDER != IS_LITTLE_ENDIAN) + unsigned char temp[8]; + unsigned int j; +#endif + + for(i=0; i 1) { + ((uint64_t*)output)[ 1] = ~((uint64_t*)output)[ 1]; + if (laneCount > 2) { + ((uint64_t*)output)[ 2] = ~((uint64_t*)output)[ 2]; + if (laneCount > 8) { + ((uint64_t*)output)[ 8] = ~((uint64_t*)output)[ 8]; + if (laneCount > 12) { + ((uint64_t*)output)[12] = ~((uint64_t*)output)[12]; + if (laneCount > 17) { + ((uint64_t*)output)[17] = ~((uint64_t*)output)[17]; + if (laneCount > 20) { + ((uint64_t*)output)[20] = ~((uint64_t*)output)[20]; + } + } + } + } + } + } +#endif +} + +/* ---------------------------------------------------------------- */ + +void KeccakP1600_ExtractAndAddBytes(const KeccakP1600_plain64_state *state, const unsigned char *input, unsigned char *output, unsigned int offset, unsigned int length) +{ + SnP_ExtractAndAddBytes(state, input, output, offset, length, KeccakP1600_ExtractAndAddLanes, KeccakP1600_ExtractAndAddBytesInLane, 8); +} + +/* ---------------------------------------------------------------- */ + +size_t KeccakF1600_FastLoop_Absorb(KeccakP1600_plain64_state *state, unsigned int laneCount, const unsigned char *data, size_t dataByteLen) +{ + size_t originalDataByteLen = dataByteLen; + declareABCDE + #ifndef KeccakP1600_fullUnrolling + unsigned int i; + #endif + uint64_t *stateAsLanes = state->A; + uint64_t *inDataAsLanes = (uint64_t*)data; + + copyFromState(A, stateAsLanes) + while(dataByteLen >= laneCount*8) { + addInput(A, inDataAsLanes, laneCount) + rounds24 + inDataAsLanes += laneCount; + dataByteLen -= laneCount*8; + } + copyToState(stateAsLanes, A) + return originalDataByteLen - dataByteLen; +} + +/* ---------------------------------------------------------------- */ + +size_t KeccakP1600_12rounds_FastLoop_Absorb(KeccakP1600_plain64_state *state, unsigned int laneCount, const unsigned char *data, size_t dataByteLen) +{ + size_t originalDataByteLen = dataByteLen; + declareABCDE + #ifndef KeccakP1600_fullUnrolling + unsigned int i; + #endif + uint64_t *stateAsLanes = state->A; + uint64_t *inDataAsLanes = (uint64_t*)data; + + copyFromState(A, stateAsLanes) + while(dataByteLen >= laneCount*8) { + addInput(A, inDataAsLanes, laneCount) + rounds12 + inDataAsLanes += laneCount; + dataByteLen -= laneCount*8; + } + copyToState(stateAsLanes, A) + return originalDataByteLen - dataByteLen; +} diff --git a/Sources/CXKCP/FIPS202-opt64/KeccakP-1600-unrolling.macros b/Sources/CXKCP/FIPS202-opt64/KeccakP-1600-unrolling.macros new file mode 100644 index 000000000..9f7200226 --- /dev/null +++ b/Sources/CXKCP/FIPS202-opt64/KeccakP-1600-unrolling.macros @@ -0,0 +1,305 @@ +/* +The eXtended Keccak Code Package (XKCP) +https://github.com/XKCP/XKCP + +The Keccak-p permutations, designed by Guido Bertoni, Joan Daemen, Michaël Peeters and Gilles Van Assche. + +Implementation by Gilles Van Assche and Ronny Van Keer, hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to the Keccak Team website: +https://keccak.team/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#if (defined(FullUnrolling)) +#define rounds24 \ + prepareTheta \ + thetaRhoPiChiIotaPrepareTheta( 0, A, E) \ + thetaRhoPiChiIotaPrepareTheta( 1, E, A) \ + thetaRhoPiChiIotaPrepareTheta( 2, A, E) \ + thetaRhoPiChiIotaPrepareTheta( 3, E, A) \ + thetaRhoPiChiIotaPrepareTheta( 4, A, E) \ + thetaRhoPiChiIotaPrepareTheta( 5, E, A) \ + thetaRhoPiChiIotaPrepareTheta( 6, A, E) \ + thetaRhoPiChiIotaPrepareTheta( 7, E, A) \ + thetaRhoPiChiIotaPrepareTheta( 8, A, E) \ + thetaRhoPiChiIotaPrepareTheta( 9, E, A) \ + thetaRhoPiChiIotaPrepareTheta(10, A, E) \ + thetaRhoPiChiIotaPrepareTheta(11, E, A) \ + thetaRhoPiChiIotaPrepareTheta(12, A, E) \ + thetaRhoPiChiIotaPrepareTheta(13, E, A) \ + thetaRhoPiChiIotaPrepareTheta(14, A, E) \ + thetaRhoPiChiIotaPrepareTheta(15, E, A) \ + thetaRhoPiChiIotaPrepareTheta(16, A, E) \ + thetaRhoPiChiIotaPrepareTheta(17, E, A) \ + thetaRhoPiChiIotaPrepareTheta(18, A, E) \ + thetaRhoPiChiIotaPrepareTheta(19, E, A) \ + thetaRhoPiChiIotaPrepareTheta(20, A, E) \ + thetaRhoPiChiIotaPrepareTheta(21, E, A) \ + thetaRhoPiChiIotaPrepareTheta(22, A, E) \ + thetaRhoPiChiIota(23, E, A) \ + +#define rounds12 \ + prepareTheta \ + thetaRhoPiChiIotaPrepareTheta(12, A, E) \ + thetaRhoPiChiIotaPrepareTheta(13, E, A) \ + thetaRhoPiChiIotaPrepareTheta(14, A, E) \ + thetaRhoPiChiIotaPrepareTheta(15, E, A) \ + thetaRhoPiChiIotaPrepareTheta(16, A, E) \ + thetaRhoPiChiIotaPrepareTheta(17, E, A) \ + thetaRhoPiChiIotaPrepareTheta(18, A, E) \ + thetaRhoPiChiIotaPrepareTheta(19, E, A) \ + thetaRhoPiChiIotaPrepareTheta(20, A, E) \ + thetaRhoPiChiIotaPrepareTheta(21, E, A) \ + thetaRhoPiChiIotaPrepareTheta(22, A, E) \ + thetaRhoPiChiIota(23, E, A) \ + +#define rounds6 \ + prepareTheta \ + thetaRhoPiChiIotaPrepareTheta(18, A, E) \ + thetaRhoPiChiIotaPrepareTheta(19, E, A) \ + thetaRhoPiChiIotaPrepareTheta(20, A, E) \ + thetaRhoPiChiIotaPrepareTheta(21, E, A) \ + thetaRhoPiChiIotaPrepareTheta(22, A, E) \ + thetaRhoPiChiIota(23, E, A) \ + +#define rounds4 \ + prepareTheta \ + thetaRhoPiChiIotaPrepareTheta(20, A, E) \ + thetaRhoPiChiIotaPrepareTheta(21, E, A) \ + thetaRhoPiChiIotaPrepareTheta(22, A, E) \ + thetaRhoPiChiIota(23, E, A) \ + +#elif (Unrolling == 12) +#define rounds24 \ + prepareTheta \ + for(i=0; i<24; i+=12) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+ 1, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+ 2, A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+ 3, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+ 4, A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+ 5, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+ 6, A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+ 7, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+ 8, A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+ 9, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+10, A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+11, E, A) \ + } \ + +#define rounds12 \ + prepareTheta \ + thetaRhoPiChiIotaPrepareTheta(12, A, E) \ + thetaRhoPiChiIotaPrepareTheta(13, E, A) \ + thetaRhoPiChiIotaPrepareTheta(14, A, E) \ + thetaRhoPiChiIotaPrepareTheta(15, E, A) \ + thetaRhoPiChiIotaPrepareTheta(16, A, E) \ + thetaRhoPiChiIotaPrepareTheta(17, E, A) \ + thetaRhoPiChiIotaPrepareTheta(18, A, E) \ + thetaRhoPiChiIotaPrepareTheta(19, E, A) \ + thetaRhoPiChiIotaPrepareTheta(20, A, E) \ + thetaRhoPiChiIotaPrepareTheta(21, E, A) \ + thetaRhoPiChiIotaPrepareTheta(22, A, E) \ + thetaRhoPiChiIota(23, E, A) \ + +#define rounds6 \ + prepareTheta \ + thetaRhoPiChiIotaPrepareTheta(18, A, E) \ + thetaRhoPiChiIotaPrepareTheta(19, E, A) \ + thetaRhoPiChiIotaPrepareTheta(20, A, E) \ + thetaRhoPiChiIotaPrepareTheta(21, E, A) \ + thetaRhoPiChiIotaPrepareTheta(22, A, E) \ + thetaRhoPiChiIota(23, E, A) \ + +#define rounds4 \ + prepareTheta \ + thetaRhoPiChiIotaPrepareTheta(20, A, E) \ + thetaRhoPiChiIotaPrepareTheta(21, E, A) \ + thetaRhoPiChiIotaPrepareTheta(22, A, E) \ + thetaRhoPiChiIota(23, E, A) \ + +#elif (Unrolling == 6) +#define rounds24 \ + prepareTheta \ + for(i=0; i<24; i+=6) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+4, A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+5, E, A) \ + } \ + +#define rounds12 \ + prepareTheta \ + for(i=12; i<24; i+=6) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+4, A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+5, E, A) \ + } \ + +#define rounds6 \ + prepareTheta \ + thetaRhoPiChiIotaPrepareTheta(18, A, E) \ + thetaRhoPiChiIotaPrepareTheta(19, E, A) \ + thetaRhoPiChiIotaPrepareTheta(20, A, E) \ + thetaRhoPiChiIotaPrepareTheta(21, E, A) \ + thetaRhoPiChiIotaPrepareTheta(22, A, E) \ + thetaRhoPiChiIota(23, E, A) \ + +#define rounds4 \ + prepareTheta \ + thetaRhoPiChiIotaPrepareTheta(20, A, E) \ + thetaRhoPiChiIotaPrepareTheta(21, E, A) \ + thetaRhoPiChiIotaPrepareTheta(22, A, E) \ + thetaRhoPiChiIota(23, E, A) \ + +#elif (Unrolling == 4) +#define rounds24 \ + prepareTheta \ + for(i=0; i<24; i+=4) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \ + } \ + +#define rounds12 \ + prepareTheta \ + for(i=12; i<24; i+=4) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+3, E, A) \ + } \ + +#define rounds6 \ + prepareTheta \ + for(i=18; i<24; i+=2) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ + } \ + +#define rounds4 \ + prepareTheta \ + thetaRhoPiChiIotaPrepareTheta(20, A, E) \ + thetaRhoPiChiIotaPrepareTheta(21, E, A) \ + thetaRhoPiChiIotaPrepareTheta(22, A, E) \ + thetaRhoPiChiIota(23, E, A) \ + +#elif (Unrolling == 3) +#define rounds24 \ + prepareTheta \ + for(i=0; i<24; i+=3) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ + copyStateVariables(A, E) \ + } \ + +#define rounds12 \ + prepareTheta \ + for(i=12; i<24; i+=3) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ + copyStateVariables(A, E) \ + } \ + +#define rounds6 \ + prepareTheta \ + for(i=18; i<24; i+=3) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ + thetaRhoPiChiIotaPrepareTheta(i+2, A, E) \ + copyStateVariables(A, E) \ + } \ + +#define rounds4 \ + prepareTheta \ + for(i=20; i<24; i+=2) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ + } \ + +#elif (Unrolling == 2) +#define rounds24 \ + prepareTheta \ + for(i=0; i<24; i+=2) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ + } \ + +#define rounds12 \ + prepareTheta \ + for(i=12; i<24; i+=2) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ + } \ + +#define rounds6 \ + prepareTheta \ + for(i=18; i<24; i+=2) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ + } \ + +#define rounds4 \ + prepareTheta \ + for(i=20; i<24; i+=2) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ + } \ + +#elif (Unrolling == 1) +#define rounds24 \ + prepareTheta \ + for(i=0; i<24; i++) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + copyStateVariables(A, E) \ + } \ + +#define rounds12 \ + prepareTheta \ + for(i=12; i<24; i++) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + copyStateVariables(A, E) \ + } \ + +#define rounds6 \ + prepareTheta \ + for(i=18; i<24; i++) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + copyStateVariables(A, E) \ + } \ + +#define rounds4 \ + prepareTheta \ + for(i=20; i<24; i++) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + copyStateVariables(A, E) \ + } \ + +#else +#error "Unrolling is not correctly specified!" +#endif + +#define roundsN(__nrounds) \ + prepareTheta \ + i = 24 - (__nrounds); \ + if ((i&1) != 0) { \ + thetaRhoPiChiIotaPrepareTheta(i, A, E) \ + copyStateVariables(A, E) \ + ++i; \ + } \ + for( /* empty */; i<24; i+=2) { \ + thetaRhoPiChiIotaPrepareTheta(i , A, E) \ + thetaRhoPiChiIotaPrepareTheta(i+1, E, A) \ + } diff --git a/Sources/CXKCP/FIPS202-opt64/KeccakSponge.c b/Sources/CXKCP/FIPS202-opt64/KeccakSponge.c new file mode 100644 index 000000000..705c69c91 --- /dev/null +++ b/Sources/CXKCP/FIPS202-opt64/KeccakSponge.c @@ -0,0 +1,95 @@ +/* +The eXtended Keccak Code Package (XKCP) +https://github.com/XKCP/XKCP + +Keccak, designed by Guido Bertoni, Joan Daemen, Michaël Peeters and Gilles Van Assche. + +Implementation by the designers, hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to the Keccak Team website: +https://keccak.team/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#include "KeccakSponge.h" + +#ifdef KeccakReference + #include "displayIntermediateValues.h" +#endif + +#ifdef XKCP_has_KeccakP200 + #include "KeccakP-200-SnP.h" + + #define prefix KeccakWidth200 + #define SnP KeccakP200 + #define SnP_width 200 + #define SnP_Permute KeccakP200_Permute_18rounds + #if defined(KeccakF200_FastLoop_supported) + #define SnP_FastLoop_Absorb KeccakF200_FastLoop_Absorb + #endif + #include "KeccakSponge.inc" + #undef prefix + #undef SnP + #undef SnP_width + #undef SnP_Permute + #undef SnP_FastLoop_Absorb +#endif + +#ifdef XKCP_has_KeccakP400 + #include "KeccakP-400-SnP.h" + + #define prefix KeccakWidth400 + #define SnP KeccakP400 + #define SnP_width 400 + #define SnP_Permute KeccakP400_Permute_20rounds + #if defined(KeccakF400_FastLoop_supported) + #define SnP_FastLoop_Absorb KeccakF400_FastLoop_Absorb + #endif + #include "KeccakSponge.inc" + #undef prefix + #undef SnP + #undef SnP_width + #undef SnP_Permute + #undef SnP_FastLoop_Absorb +#endif + +#ifdef XKCP_has_KeccakP800 + #include "KeccakP-800-SnP.h" + + #define prefix KeccakWidth800 + #define SnP KeccakP800 + #define SnP_width 800 + #define SnP_Permute KeccakP800_Permute_22rounds + #if defined(KeccakF800_FastLoop_supported) + #define SnP_FastLoop_Absorb KeccakF800_FastLoop_Absorb + #endif + #include "KeccakSponge.inc" + #undef prefix + #undef SnP + #undef SnP_width + #undef SnP_Permute + #undef SnP_FastLoop_Absorb +#endif + +#ifdef XKCP_has_KeccakP1600 + #include "KeccakP-1600-SnP.h" + + #define prefix KeccakWidth1600 + #define SnP KeccakP1600 + #define SnP_state KeccakP1600_state + #define SnP_width 1600 + #define SnP_Permute KeccakP1600_Permute_24rounds + #if defined(KeccakF1600_FastLoop_supported) + #define SnP_FastLoop_Absorb KeccakF1600_FastLoop_Absorb + #endif + #include "KeccakSponge.inc" + #undef prefix + #undef SnP + #undef SnP_state + #undef SnP_width + #undef SnP_Permute + #undef SnP_FastLoop_Absorb +#endif diff --git a/Sources/CXKCP/FIPS202-opt64/KeccakSponge.h b/Sources/CXKCP/FIPS202-opt64/KeccakSponge.h new file mode 100644 index 000000000..4d4d83f21 --- /dev/null +++ b/Sources/CXKCP/FIPS202-opt64/KeccakSponge.h @@ -0,0 +1,70 @@ +/* +The eXtended Keccak Code Package (XKCP) +https://github.com/XKCP/XKCP + +Keccak, designed by Guido Bertoni, Joan Daemen, Michaël Peeters and Gilles Van Assche. + +Implementation by the designers, hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to the Keccak Team website: +https://keccak.team/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#ifndef _KeccakSponge_h_ +#define _KeccakSponge_h_ + +/* For the documentation, please follow the link: */ +/* #include "KeccakSponge-documentation.h" */ + +#include +#include "align.h" +#include "config.h" + +#define XKCP_DeclareSpongeStructure(prefix, state_t) \ + typedef struct prefix##_SpongeInstanceStruct { \ + state_t state; \ + unsigned int rate; \ + unsigned int byteIOIndex; \ + int squeezing; \ + } prefix##_SpongeInstance; + +#define XKCP_DeclareSpongeFunctions(prefix) \ + int prefix##_Sponge(unsigned int rate, unsigned int capacity, const unsigned char *input, size_t inputByteLen, unsigned char suffix, unsigned char *output, size_t outputByteLen); \ + int prefix##_SpongeInitialize(prefix##_SpongeInstance *spongeInstance, unsigned int rate, unsigned int capacity); \ + int prefix##_SpongeAbsorb(prefix##_SpongeInstance *spongeInstance, const unsigned char *data, size_t dataByteLen); \ + int prefix##_SpongeAbsorbLastFewBits(prefix##_SpongeInstance *spongeInstance, unsigned char delimitedData); \ + int prefix##_SpongeSqueeze(prefix##_SpongeInstance *spongeInstance, unsigned char *data, size_t dataByteLen); + +#ifdef XKCP_has_KeccakP200 + #include "KeccakP-200-SnP.h" + XKCP_DeclareSpongeStructure(KeccakWidth200, KeccakP200_stateSizeInBytes, KeccakP200_stateAlignment) + XKCP_DeclareSpongeFunctions(KeccakWidth200) + #define XKCP_has_Sponge_Keccak_width200 +#endif + +#ifdef XKCP_has_KeccakP400 + #include "KeccakP-400-SnP.h" + XKCP_DeclareSpongeStructure(KeccakWidth400, KeccakP400_stateSizeInBytes, KeccakP400_stateAlignment) + XKCP_DeclareSpongeFunctions(KeccakWidth400) + #define XKCP_has_Sponge_Keccak_width400 +#endif + +#ifdef XKCP_has_KeccakP800 + #include "KeccakP-800-SnP.h" + XKCP_DeclareSpongeStructure(KeccakWidth800, KeccakP800_stateSizeInBytes, KeccakP800_stateAlignment) + XKCP_DeclareSpongeFunctions(KeccakWidth800) + #define XKCP_has_Sponge_Keccak_width800 +#endif + +#ifdef XKCP_has_KeccakP1600 + #include "KeccakP-1600-SnP.h" + XKCP_DeclareSpongeStructure(KeccakWidth1600, KeccakP1600_state) + XKCP_DeclareSpongeFunctions(KeccakWidth1600) + #define XKCP_has_Sponge_Keccak_width1600 +#endif + +#endif diff --git a/Sources/CXKCP/FIPS202-opt64/KeccakSponge.inc b/Sources/CXKCP/FIPS202-opt64/KeccakSponge.inc new file mode 100644 index 000000000..29981f041 --- /dev/null +++ b/Sources/CXKCP/FIPS202-opt64/KeccakSponge.inc @@ -0,0 +1,312 @@ +/* +The eXtended Keccak Code Package (XKCP) +https://github.com/XKCP/XKCP + +Keccak, designed by Guido Bertoni, Joan Daemen, Michaël Peeters and Gilles Van Assche. + +Implementation by the designers, hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to the Keccak Team website: +https://keccak.team/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#define JOIN0(a, b) a ## b +#define JOIN(a, b) JOIN0(a, b) + +#define Sponge JOIN(prefix, _Sponge) +#define SpongeInstance JOIN(prefix, _SpongeInstance) +#define SpongeInitialize JOIN(prefix, _SpongeInitialize) +#define SpongeAbsorb JOIN(prefix, _SpongeAbsorb) +#define SpongeAbsorbLastFewBits JOIN(prefix, _SpongeAbsorbLastFewBits) +#define SpongeSqueeze JOIN(prefix, _SpongeSqueeze) + +#define SnP_StaticInitialize JOIN(SnP, _StaticInitialize) +#define SnP_Initialize JOIN(SnP, _Initialize) +#define SnP_AddByte JOIN(SnP, _AddByte) +#define SnP_AddBytes JOIN(SnP, _AddBytes) +#define SnP_ExtractBytes JOIN(SnP, _ExtractBytes) + +int Sponge(unsigned int rate, unsigned int capacity, const unsigned char *input, size_t inputByteLen, unsigned char suffix, unsigned char *output, size_t outputByteLen) +{ + SnP_state state; + unsigned int partialBlock; + const unsigned char *curInput = input; + unsigned char *curOutput = output; + unsigned int rateInBytes = rate/8; + + if (rate+capacity != SnP_width) + return 1; + if ((rate <= 0) || (rate > SnP_width) || ((rate % 8) != 0)) + return 1; + if (suffix == 0) + return 1; + + /* Initialize the state */ + SnP_StaticInitialize(); + SnP_Initialize(&state); + + /* First, absorb whole blocks */ +#ifdef SnP_FastLoop_Absorb + if (((rateInBytes % (SnP_width/200)) == 0) && (inputByteLen >= rateInBytes)) { + /* fast lane: whole lane rate */ + size_t j; + j = SnP_FastLoop_Absorb(&state, rateInBytes/(SnP_width/200), curInput, inputByteLen); + curInput += j; + inputByteLen -= j; + } +#endif + while(inputByteLen >= (size_t)rateInBytes) { + #ifdef KeccakReference + displayBytes(1, "Block to be absorbed", curInput, rateInBytes); + #endif + SnP_AddBytes(&state, curInput, 0, rateInBytes); + SnP_Permute(&state); + curInput += rateInBytes; + inputByteLen -= rateInBytes; + } + + /* Then, absorb what remains */ + partialBlock = (unsigned int)inputByteLen; + #ifdef KeccakReference + displayBytes(1, "Block to be absorbed (part)", curInput, partialBlock); + #endif + SnP_AddBytes(&state, curInput, 0, partialBlock); + + /* Finally, absorb the suffix */ + #ifdef KeccakReference + { + unsigned char delimitedData1[1]; + delimitedData1[0] = suffix; + displayBytes(1, "Block to be absorbed (last few bits + first bit of padding)", delimitedData1, 1); + } + #endif + /* Last few bits, whose delimiter coincides with first bit of padding */ + SnP_AddByte(&state, suffix, partialBlock); + /* If the first bit of padding is at position rate-1, we need a whole new block for the second bit of padding */ + if ((suffix >= 0x80) && (partialBlock == (rateInBytes-1))) + SnP_Permute(&state); + /* Second bit of padding */ + SnP_AddByte(&state, 0x80, rateInBytes-1); + #ifdef KeccakReference + { + unsigned char block[SnP_width/8]; + memset(block, 0, SnP_width/8); + block[rateInBytes-1] = 0x80; + displayBytes(1, "Second bit of padding", block, rateInBytes); + } + #endif + SnP_Permute(&state); + #ifdef KeccakReference + displayText(1, "--- Switching to squeezing phase ---"); + #endif + + /* First, output whole blocks */ + while(outputByteLen > (size_t)rateInBytes) { + SnP_ExtractBytes(&state, curOutput, 0, rateInBytes); + SnP_Permute(&state); + #ifdef KeccakReference + displayBytes(1, "Squeezed block", curOutput, rateInBytes); + #endif + curOutput += rateInBytes; + outputByteLen -= rateInBytes; + } + + /* Finally, output what remains */ + partialBlock = (unsigned int)outputByteLen; + SnP_ExtractBytes(&state, curOutput, 0, partialBlock); + #ifdef KeccakReference + displayBytes(1, "Squeezed block (part)", curOutput, partialBlock); + #endif + + return 0; +} + +/* ---------------------------------------------------------------- */ +/* ---------------------------------------------------------------- */ +/* ---------------------------------------------------------------- */ + +int SpongeInitialize(SpongeInstance *instance, unsigned int rate, unsigned int capacity) +{ + if (rate+capacity != SnP_width) + return 1; + if ((rate <= 0) || (rate > SnP_width) || ((rate % 8) != 0)) + return 1; + SnP_StaticInitialize(); + SnP_Initialize(&instance->state); + instance->rate = rate; + instance->byteIOIndex = 0; + instance->squeezing = 0; + + return 0; +} + +/* ---------------------------------------------------------------- */ + +int SpongeAbsorb(SpongeInstance *instance, const unsigned char *data, size_t dataByteLen) +{ + size_t i, j; + unsigned int partialBlock; + const unsigned char *curData; + unsigned int rateInBytes = instance->rate/8; + + if (instance->squeezing) + return 1; /* Too late for additional input */ + + i = 0; + curData = data; + while(i < dataByteLen) { + if ((instance->byteIOIndex == 0) && (dataByteLen-i >= rateInBytes)) { +#ifdef SnP_FastLoop_Absorb + /* processing full blocks first */ + if ((rateInBytes % (SnP_width/200)) == 0) { + /* fast lane: whole lane rate */ + j = SnP_FastLoop_Absorb(&instance->state, rateInBytes/(SnP_width/200), curData, dataByteLen - i); + i += j; + curData += j; + } + else { +#endif + for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) { + #ifdef KeccakReference + displayBytes(1, "Block to be absorbed", curData, rateInBytes); + #endif + SnP_AddBytes(&instance->state, curData, 0, rateInBytes); + SnP_Permute(&instance->state); + curData+=rateInBytes; + } + i = dataByteLen - j; +#ifdef SnP_FastLoop_Absorb + } +#endif + } + else { + /* normal lane: using the message queue */ + if (dataByteLen-i > rateInBytes-instance->byteIOIndex) + partialBlock = rateInBytes-instance->byteIOIndex; + else + partialBlock = (unsigned int)(dataByteLen - i); + #ifdef KeccakReference + displayBytes(1, "Block to be absorbed (part)", curData, partialBlock); + #endif + i += partialBlock; + + SnP_AddBytes(&instance->state, curData, instance->byteIOIndex, partialBlock); + curData += partialBlock; + instance->byteIOIndex += partialBlock; + if (instance->byteIOIndex == rateInBytes) { + SnP_Permute(&instance->state); + instance->byteIOIndex = 0; + } + } + } + return 0; +} + +/* ---------------------------------------------------------------- */ + +int SpongeAbsorbLastFewBits(SpongeInstance *instance, unsigned char delimitedData) +{ + unsigned int rateInBytes = instance->rate/8; + + if (delimitedData == 0) + return 1; + if (instance->squeezing) + return 1; /* Too late for additional input */ + + #ifdef KeccakReference + { + unsigned char delimitedData1[1]; + delimitedData1[0] = delimitedData; + displayBytes(1, "Block to be absorbed (last few bits + first bit of padding)", delimitedData1, 1); + } + #endif + /* Last few bits, whose delimiter coincides with first bit of padding */ + SnP_AddByte(&instance->state, delimitedData, instance->byteIOIndex); + /* If the first bit of padding is at position rate-1, we need a whole new block for the second bit of padding */ + if ((delimitedData >= 0x80) && (instance->byteIOIndex == (rateInBytes-1))) + SnP_Permute(&instance->state); + /* Second bit of padding */ + SnP_AddByte(&instance->state, 0x80, rateInBytes-1); + #ifdef KeccakReference + { + unsigned char block[SnP_width/8]; + memset(block, 0, SnP_width/8); + block[rateInBytes-1] = 0x80; + displayBytes(1, "Second bit of padding", block, rateInBytes); + } + #endif + SnP_Permute(&instance->state); + instance->byteIOIndex = 0; + instance->squeezing = 1; + #ifdef KeccakReference + displayText(1, "--- Switching to squeezing phase ---"); + #endif + return 0; +} + +/* ---------------------------------------------------------------- */ + +int SpongeSqueeze(SpongeInstance *instance, unsigned char *data, size_t dataByteLen) +{ + size_t i, j; + unsigned int partialBlock; + unsigned int rateInBytes = instance->rate/8; + unsigned char *curData; + + if (!instance->squeezing) + SpongeAbsorbLastFewBits(instance, 0x01); + + i = 0; + curData = data; + while(i < dataByteLen) { + if ((instance->byteIOIndex == rateInBytes) && (dataByteLen-i >= rateInBytes)) { + for(j=dataByteLen-i; j>=rateInBytes; j-=rateInBytes) { + SnP_Permute(&instance->state); + SnP_ExtractBytes(&instance->state, curData, 0, rateInBytes); + #ifdef KeccakReference + displayBytes(1, "Squeezed block", curData, rateInBytes); + #endif + curData+=rateInBytes; + } + i = dataByteLen - j; + } + else { + /* normal lane: using the message queue */ + if (instance->byteIOIndex == rateInBytes) { + SnP_Permute(&instance->state); + instance->byteIOIndex = 0; + } + if (dataByteLen-i > rateInBytes-instance->byteIOIndex) + partialBlock = rateInBytes-instance->byteIOIndex; + else + partialBlock = (unsigned int)(dataByteLen - i); + i += partialBlock; + + SnP_ExtractBytes(&instance->state, curData, instance->byteIOIndex, partialBlock); + #ifdef KeccakReference + displayBytes(1, "Squeezed block (part)", curData, partialBlock); + #endif + curData += partialBlock; + instance->byteIOIndex += partialBlock; + } + } + return 0; +} + +/* ---------------------------------------------------------------- */ + +#undef Sponge +#undef SpongeInstance +#undef SpongeInitialize +#undef SpongeAbsorb +#undef SpongeAbsorbLastFewBits +#undef SpongeSqueeze +#undef SnP_StaticInitialize +#undef SnP_Initialize +#undef SnP_AddByte +#undef SnP_AddBytes +#undef SnP_ExtractBytes diff --git a/Sources/CXKCP/FIPS202-opt64/SimpleFIPS202.c b/Sources/CXKCP/FIPS202-opt64/SimpleFIPS202.c new file mode 100644 index 000000000..837afa977 --- /dev/null +++ b/Sources/CXKCP/FIPS202-opt64/SimpleFIPS202.c @@ -0,0 +1,48 @@ +/* +The eXtended Keccak Code Package (XKCP) +https://github.com/XKCP/XKCP + +Keccak, designed by Guido Bertoni, Joan Daemen, Michaël Peeters and Gilles Van Assche. + +Implementation by Gilles Van Assche, hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to the Keccak Team website: +https://keccak.team/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#include "KeccakSponge.h" +#include "SimpleFIPS202.h" + +int SHAKE128(unsigned char *output, size_t outputByteLen, const unsigned char *input, size_t inputByteLen) +{ + return KeccakWidth1600_Sponge(1344, 256, input, inputByteLen, 0x1F, output, outputByteLen); +} + +int SHAKE256(unsigned char *output, size_t outputByteLen, const unsigned char *input, size_t inputByteLen) +{ + return KeccakWidth1600_Sponge(1088, 512, input, inputByteLen, 0x1F, output, outputByteLen); +} + +int SHA3_224(unsigned char *output, const unsigned char *input, size_t inputByteLen) +{ + return KeccakWidth1600_Sponge(1152, 448, input, inputByteLen, 0x06, output, 224/8); +} + +int SHA3_256(unsigned char *output, const unsigned char *input, size_t inputByteLen) +{ + return KeccakWidth1600_Sponge(1088, 512, input, inputByteLen, 0x06, output, 256/8); +} + +int SHA3_384(unsigned char *output, const unsigned char *input, size_t inputByteLen) +{ + return KeccakWidth1600_Sponge( 832, 768, input, inputByteLen, 0x06, output, 384/8); +} + +int SHA3_512(unsigned char *output, const unsigned char *input, size_t inputByteLen) +{ + return KeccakWidth1600_Sponge(576, 1024, input, inputByteLen, 0x06, output, 512/8); +} diff --git a/Sources/CXKCP/FIPS202-opt64/SimpleFIPS202.h b/Sources/CXKCP/FIPS202-opt64/SimpleFIPS202.h new file mode 100644 index 000000000..ec4644030 --- /dev/null +++ b/Sources/CXKCP/FIPS202-opt64/SimpleFIPS202.h @@ -0,0 +1,79 @@ +/* +The eXtended Keccak Code Package (XKCP) +https://github.com/XKCP/XKCP + +Keccak, designed by Guido Bertoni, Joan Daemen, Michaël Peeters and Gilles Van Assche. + +Implementation by Gilles Van Assche, hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to the Keccak Team website: +https://keccak.team/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#ifndef _SimpleFIPS202_h_ +#define _SimpleFIPS202_h_ + +#include "config.h" +#ifdef XKCP_has_KeccakP1600 + +#include + +/** Implementation of the SHAKE128 extendable output function (XOF) [FIPS 202]. + * @param output Pointer to the output buffer. + * @param outputByteLen The desired number of output bytes. + * @param input Pointer to the input message. + * @param inputByteLen The length of the input message in bytes. + * @return 0 if successful, 1 otherwise. + */ +int SHAKE128(unsigned char *output, size_t outputByteLen, const unsigned char *input, size_t inputByteLen); + +/** Implementation of the SHAKE256 extendable output function (XOF) [FIPS 202]. + * @param output Pointer to the output buffer. + * @param outputByteLen The desired number of output bytes. + * @param input Pointer to the input message. + * @param inputByteLen The length of the input message in bytes. + * @return 0 if successful, 1 otherwise. + */ +int SHAKE256(unsigned char *output, size_t outputByteLen, const unsigned char *input, size_t inputByteLen); + +/** Implementation of SHA3-224 [FIPS 202]. + * @param output Pointer to the output buffer (28 bytes). + * @param input Pointer to the input message. + * @param inputByteLen The length of the input message in bytes. + * @return 0 if successful, 1 otherwise. + */ +int SHA3_224(unsigned char *output, const unsigned char *input, size_t inputByteLen); + +/** Implementation of SHA3-256 [FIPS 202]. + * @param output Pointer to the output buffer (32 bytes). + * @param input Pointer to the input message. + * @param inputByteLen The length of the input message in bytes. + * @return 0 if successful, 1 otherwise. + */ +int SHA3_256(unsigned char *output, const unsigned char *input, size_t inputByteLen); + +/** Implementation of SHA3-384 [FIPS 202]. + * @param output Pointer to the output buffer (48 bytes). + * @param input Pointer to the input message. + * @param inputByteLen The length of the input message in bytes. + * @return 0 if successful, 1 otherwise. + */ +int SHA3_384(unsigned char *output, const unsigned char *input, size_t inputByteLen); + +/** Implementation of SHA3-512 [FIPS 202]. + * @param output Pointer to the output buffer (64 bytes). + * @param input Pointer to the input message. + * @param inputByteLen The length of the input message in bytes. + * @return 0 if successful, 1 otherwise. + */ +int SHA3_512(unsigned char *output, const unsigned char *input, size_t inputByteLen); + +#else +#error This requires an implementation of Keccak-p[1600] +#endif + +#endif diff --git a/Sources/CXKCP/FIPS202-opt64/SnP-Relaned.h b/Sources/CXKCP/FIPS202-opt64/SnP-Relaned.h new file mode 100644 index 000000000..ddd6df928 --- /dev/null +++ b/Sources/CXKCP/FIPS202-opt64/SnP-Relaned.h @@ -0,0 +1,145 @@ +/* +The eXtended Keccak Code Package (XKCP) +https://github.com/XKCP/XKCP + +Implementation by Gilles Van Assche and Ronny Van Keer, hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to the Keccak Team website: +https://keccak.team/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ + +--- + +This file contains macros that help implement a permutation in a SnP-compatible way. +It converts an implementation that implement state input/output functions +in a lane-oriented fashion (i.e., using SnP_AddLanes() and SnP_AddBytesInLane, +and similarly for Overwite, Extract and ExtractAndAdd) to the byte-oriented SnP. +Please refer to SnP-documentation.h for more details. +*/ + +#ifndef _SnP_Relaned_h_ +#define _SnP_Relaned_h_ + +#define SnP_AddBytes(state, data, offset, length, SnP_AddLanes, SnP_AddBytesInLane, SnP_laneLengthInBytes) \ + { \ + if ((offset) == 0) { \ + SnP_AddLanes(state, data, (length)/SnP_laneLengthInBytes); \ + if ((length)%SnP_laneLengthInBytes > 0) \ + SnP_AddBytesInLane(state, \ + (length)/SnP_laneLengthInBytes, \ + (data)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \ + 0, \ + (length)%SnP_laneLengthInBytes); \ + } \ + else { \ + unsigned int _sizeLeft = (length); \ + unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \ + unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \ + const unsigned char *_curData = (data); \ + while(_sizeLeft > 0) { \ + unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \ + if (_bytesInLane > _sizeLeft) \ + _bytesInLane = _sizeLeft; \ + SnP_AddBytesInLane(state, _lanePosition, _curData, _offsetInLane, _bytesInLane); \ + _sizeLeft -= _bytesInLane; \ + _lanePosition++; \ + _offsetInLane = 0; \ + _curData += _bytesInLane; \ + } \ + } \ + } + +#define SnP_OverwriteBytes(state, data, offset, length, SnP_OverwriteLanes, SnP_OverwriteBytesInLane, SnP_laneLengthInBytes) \ + { \ + if ((offset) == 0) { \ + SnP_OverwriteLanes(state, data, (length)/SnP_laneLengthInBytes); \ + if ((length)%SnP_laneLengthInBytes > 0) \ + SnP_OverwriteBytesInLane(state, \ + (length)/SnP_laneLengthInBytes, \ + (data)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \ + 0, \ + (length)%SnP_laneLengthInBytes); \ + } \ + else { \ + unsigned int _sizeLeft = (length); \ + unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \ + unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \ + const unsigned char *_curData = (data); \ + while(_sizeLeft > 0) { \ + unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \ + if (_bytesInLane > _sizeLeft) \ + _bytesInLane = _sizeLeft; \ + SnP_OverwriteBytesInLane(state, _lanePosition, _curData, _offsetInLane, _bytesInLane); \ + _sizeLeft -= _bytesInLane; \ + _lanePosition++; \ + _offsetInLane = 0; \ + _curData += _bytesInLane; \ + } \ + } \ + } + +#define SnP_ExtractBytes(state, data, offset, length, SnP_ExtractLanes, SnP_ExtractBytesInLane, SnP_laneLengthInBytes) \ + { \ + if ((offset) == 0) { \ + SnP_ExtractLanes(state, data, (length)/SnP_laneLengthInBytes); \ + if ((length)%SnP_laneLengthInBytes > 0) \ + SnP_ExtractBytesInLane(state, \ + (length)/SnP_laneLengthInBytes, \ + (data)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \ + 0, \ + (length)%SnP_laneLengthInBytes); \ + } \ + else { \ + unsigned int _sizeLeft = (length); \ + unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \ + unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \ + unsigned char *_curData = (data); \ + while(_sizeLeft > 0) { \ + unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \ + if (_bytesInLane > _sizeLeft) \ + _bytesInLane = _sizeLeft; \ + SnP_ExtractBytesInLane(state, _lanePosition, _curData, _offsetInLane, _bytesInLane); \ + _sizeLeft -= _bytesInLane; \ + _lanePosition++; \ + _offsetInLane = 0; \ + _curData += _bytesInLane; \ + } \ + } \ + } + +#define SnP_ExtractAndAddBytes(state, input, output, offset, length, SnP_ExtractAndAddLanes, SnP_ExtractAndAddBytesInLane, SnP_laneLengthInBytes) \ + { \ + if ((offset) == 0) { \ + SnP_ExtractAndAddLanes(state, input, output, (length)/SnP_laneLengthInBytes); \ + if ((length)%SnP_laneLengthInBytes > 0) \ + SnP_ExtractAndAddBytesInLane(state, \ + (length)/SnP_laneLengthInBytes, \ + (input)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \ + (output)+((length)/SnP_laneLengthInBytes)*SnP_laneLengthInBytes, \ + 0, \ + (length)%SnP_laneLengthInBytes); \ + } \ + else { \ + unsigned int _sizeLeft = (length); \ + unsigned int _lanePosition = (offset)/SnP_laneLengthInBytes; \ + unsigned int _offsetInLane = (offset)%SnP_laneLengthInBytes; \ + const unsigned char *_curInput = (input); \ + unsigned char *_curOutput = (output); \ + while(_sizeLeft > 0) { \ + unsigned int _bytesInLane = SnP_laneLengthInBytes - _offsetInLane; \ + if (_bytesInLane > _sizeLeft) \ + _bytesInLane = _sizeLeft; \ + SnP_ExtractAndAddBytesInLane(state, _lanePosition, _curInput, _curOutput, _offsetInLane, _bytesInLane); \ + _sizeLeft -= _bytesInLane; \ + _lanePosition++; \ + _offsetInLane = 0; \ + _curInput += _bytesInLane; \ + _curOutput += _bytesInLane; \ + } \ + } \ + } + +#endif diff --git a/Sources/CXKCP/FIPS202-opt64/align.h b/Sources/CXKCP/FIPS202-opt64/align.h new file mode 100644 index 000000000..82ad2f905 --- /dev/null +++ b/Sources/CXKCP/FIPS202-opt64/align.h @@ -0,0 +1,33 @@ +/* +The eXtended Keccak Code Package (XKCP) +https://github.com/XKCP/XKCP + +Implementation by Gilles Van Assche and Ronny Van Keer, hereby denoted as "the implementer". + +For more information, feedback or questions, please refer to the Keccak Team website: +https://keccak.team/ + +To the extent possible under law, the implementer has waived all copyright +and related or neighboring rights to the source code in this file. +http://creativecommons.org/publicdomain/zero/1.0/ +*/ + +#ifndef _align_h_ +#define _align_h_ + +/* on Mac OS-X and possibly others, ALIGN(x) is defined in param.h, and -Werror chokes on the redef. */ +#ifdef ALIGN +#undef ALIGN +#endif + +#if defined(__GNUC__) +#define ALIGN(x) __attribute__ ((aligned(x))) +#elif defined(_MSC_VER) +#define ALIGN(x) __declspec(align(x)) +#elif defined(__ARMCC_VERSION) +#define ALIGN(x) __align(x) +#else +#define ALIGN(x) +#endif + +#endif diff --git a/Sources/CXKCP/FIPS202-opt64/brg_endian.h b/Sources/CXKCP/FIPS202-opt64/brg_endian.h new file mode 100644 index 000000000..7c640b90e --- /dev/null +++ b/Sources/CXKCP/FIPS202-opt64/brg_endian.h @@ -0,0 +1,143 @@ +/* + --------------------------------------------------------------------------- + Copyright (c) 1998-2008, Brian Gladman, Worcester, UK. All rights reserved. + + LICENSE TERMS + + The redistribution and use of this software (with or without changes) + is allowed without the payment of fees or royalties provided that: + + 1. source code distributions include the above copyright notice, this + list of conditions and the following disclaimer; + + 2. binary distributions include the above copyright notice, this list + of conditions and the following disclaimer in their documentation; + + 3. the name of the copyright holder is not used to endorse products + built using this software without specific written permission. + + DISCLAIMER + + This software is provided 'as is' with no explicit or implied warranties + in respect of its properties, including, but not limited to, correctness + and/or fitness for purpose. + --------------------------------------------------------------------------- + Issue Date: 20/12/2007 + Changes for ARM 9/9/2010 +*/ + +#ifndef _BRG_ENDIAN_H +#define _BRG_ENDIAN_H + +#define IS_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */ +#define IS_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */ + +#if 0 +/* Include files where endian defines and byteswap functions may reside */ +#if defined( __sun ) +# include +#elif defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __NetBSD__ ) +# include +#elif defined( BSD ) && ( BSD >= 199103 ) || defined( __APPLE__ ) || \ + defined( __CYGWIN32__ ) || defined( __DJGPP__ ) || defined( __osf__ ) +# include +#elif defined( __linux__ ) || defined( __GNUC__ ) || defined( __GNU_LIBRARY__ ) +# if !defined( __MINGW32__ ) && !defined( _AIX ) +# include +# if !defined( __BEOS__ ) +# include +# endif +# endif +#endif +#endif + +/* Now attempt to set the define for platform byte order using any */ +/* of the four forms SYMBOL, _SYMBOL, __SYMBOL & __SYMBOL__, which */ +/* seem to encompass most endian symbol definitions */ + +#if defined( BIG_ENDIAN ) && defined( LITTLE_ENDIAN ) +# if defined( BYTE_ORDER ) && BYTE_ORDER == BIG_ENDIAN +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +# elif defined( BYTE_ORDER ) && BYTE_ORDER == LITTLE_ENDIAN +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +# endif +#elif defined( BIG_ENDIAN ) +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +#elif defined( LITTLE_ENDIAN ) +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +#endif + +#if defined( _BIG_ENDIAN ) && defined( _LITTLE_ENDIAN ) +# if defined( _BYTE_ORDER ) && _BYTE_ORDER == _BIG_ENDIAN +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +# elif defined( _BYTE_ORDER ) && _BYTE_ORDER == _LITTLE_ENDIAN +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +# endif +#elif defined( _BIG_ENDIAN ) +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +#elif defined( _LITTLE_ENDIAN ) +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +#endif + +#if defined( __BIG_ENDIAN ) && defined( __LITTLE_ENDIAN ) +# if defined( __BYTE_ORDER ) && __BYTE_ORDER == __BIG_ENDIAN +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +# elif defined( __BYTE_ORDER ) && __BYTE_ORDER == __LITTLE_ENDIAN +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +# endif +#elif defined( __BIG_ENDIAN ) +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +#elif defined( __LITTLE_ENDIAN ) +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +#endif + +#if defined( __BIG_ENDIAN__ ) && defined( __LITTLE_ENDIAN__ ) +# if defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __BIG_ENDIAN__ +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +# elif defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __LITTLE_ENDIAN__ +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +# endif +#elif defined( __BIG_ENDIAN__ ) +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +#elif defined( __LITTLE_ENDIAN__ ) +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +#endif + +/* if the platform byte order could not be determined, then try to */ +/* set this define using common machine defines */ +#if !defined(PLATFORM_BYTE_ORDER) + +#if defined( __alpha__ ) || defined( __alpha ) || defined( i386 ) || \ + defined( __i386__ ) || defined( _M_I86 ) || defined( _M_IX86 ) || \ + defined( __OS2__ ) || defined( sun386 ) || defined( __TURBOC__ ) || \ + defined( vax ) || defined( vms ) || defined( VMS ) || \ + defined( __VMS ) || defined( _M_X64 ) +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN + +#elif defined( AMIGA ) || defined( applec ) || defined( __AS400__ ) || \ + defined( _CRAY ) || defined( __hppa ) || defined( __hp9000 ) || \ + defined( ibm370 ) || defined( mc68000 ) || defined( m68k ) || \ + defined( __MRC__ ) || defined( __MVS__ ) || defined( __MWERKS__ ) || \ + defined( sparc ) || defined( __sparc) || defined( SYMANTEC_C ) || \ + defined( __VOS__ ) || defined( __TIGCC__ ) || defined( __TANDEM ) || \ + defined( THINK_C ) || defined( __VMCMS__ ) || defined( _AIX ) || \ + defined( __s390__ ) || defined( __s390x__ ) || defined( __zarch__ ) +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN + +#elif defined(__arm__) +# ifdef __BIG_ENDIAN +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +# else +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +# endif +#elif 1 /* **** EDIT HERE IF NECESSARY **** */ +# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN +#elif 0 /* **** EDIT HERE IF NECESSARY **** */ +# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN +#else +# error Please edit lines 132 or 134 in brg_endian.h to set the platform byte order +#endif + +#endif + +#endif diff --git a/Sources/CXKCP/FIPS202-opt64/config.h b/Sources/CXKCP/FIPS202-opt64/config.h new file mode 100644 index 000000000..97f857dd1 --- /dev/null +++ b/Sources/CXKCP/FIPS202-opt64/config.h @@ -0,0 +1,5 @@ +/* File generated by ToTargetConfigFile.xsl */ + +#define XKCP_has_Sponge_Keccak +#define XKCP_has_FIPS202 +#define XKCP_has_KeccakP1600 diff --git a/Sources/CXKCP/PrivacyInfo.xcprivacy b/Sources/CXKCP/PrivacyInfo.xcprivacy new file mode 100644 index 000000000..1a71db6f2 --- /dev/null +++ b/Sources/CXKCP/PrivacyInfo.xcprivacy @@ -0,0 +1,15 @@ + + + + + NSPrivacyTracking + + NSPrivacyAccessedAPITypes + + NSPrivacyCollectedDataTypes + + NSPrivacyTrackingDomains + + + + diff --git a/Sources/CXKCP/include/CXKCP.h b/Sources/CXKCP/include/CXKCP.h new file mode 100644 index 000000000..ba93818d6 --- /dev/null +++ b/Sources/CXKCP/include/CXKCP.h @@ -0,0 +1,22 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2019 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#ifndef C_CRYPTO_XKCP_H +#define C_CRYPTO_XKCP_H + +#include "../FIPS202-opt64/KeccakHash.h" +#include "../FIPS202-opt64/KeccakSponge.h" +#include "../FIPS202-opt64/SimpleFIPS202.h" + +#endif // C_CRYPTO_XKCP_H diff --git a/Sources/CXKCP/include/module.modulemap b/Sources/CXKCP/include/module.modulemap new file mode 100644 index 000000000..b44ca3c27 --- /dev/null +++ b/Sources/CXKCP/include/module.modulemap @@ -0,0 +1,4 @@ +module CXKCP { + header "CXKCP.h" + export * +} diff --git a/Sources/CXKCP/vendored-sources.txt b/Sources/CXKCP/vendored-sources.txt new file mode 100644 index 000000000..bdb9939be --- /dev/null +++ b/Sources/CXKCP/vendored-sources.txt @@ -0,0 +1,17 @@ +Vendored code from XKCP#master (heads/master-0-g11297f5): +- FIPS202-opt64/align.h +- FIPS202-opt64/brg_endian.h +- FIPS202-opt64/config.h +- FIPS202-opt64/KeccakHash.c +- FIPS202-opt64/KeccakHash.h +- FIPS202-opt64/KeccakP-1600-64.macros +- FIPS202-opt64/KeccakP-1600-opt64-config.h +- FIPS202-opt64/KeccakP-1600-opt64.c +- FIPS202-opt64/KeccakP-1600-SnP.h +- FIPS202-opt64/KeccakP-1600-unrolling.macros +- FIPS202-opt64/KeccakSponge.c +- FIPS202-opt64/KeccakSponge.h +- FIPS202-opt64/KeccakSponge.inc +- FIPS202-opt64/SimpleFIPS202.c +- FIPS202-opt64/SimpleFIPS202.h +- FIPS202-opt64/SnP-Relaned.h diff --git a/Sources/CXKCPShims/CMakeLists.txt b/Sources/CXKCPShims/CMakeLists.txt new file mode 100644 index 000000000..44fa6bd61 --- /dev/null +++ b/Sources/CXKCPShims/CMakeLists.txt @@ -0,0 +1,29 @@ +##===----------------------------------------------------------------------===## +## +## This source file is part of the SwiftCrypto open source project +## +## Copyright (c) 2021 Apple Inc. and the SwiftCrypto project authors +## Licensed under Apache License v2.0 +## +## See LICENSE.txt for license information +## See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +## +## SPDX-License-Identifier: Apache-2.0 +## +##===----------------------------------------------------------------------===## + +add_library(CXKCPShims STATIC + "shims.c" +) + +target_include_directories(CXKCPShims PUBLIC + include + $) + +target_link_libraries(CXKCPShims PUBLIC + CXKCP) + +set_target_properties(CXKCPShims PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY}) + +set_property(GLOBAL APPEND PROPERTY SWIFT_CRYPTO_EXPORTS CXKCPShims) diff --git a/Sources/CXKCPShims/PrivacyInfo.xcprivacy b/Sources/CXKCPShims/PrivacyInfo.xcprivacy new file mode 100644 index 000000000..1a71db6f2 --- /dev/null +++ b/Sources/CXKCPShims/PrivacyInfo.xcprivacy @@ -0,0 +1,15 @@ + + + + + NSPrivacyTracking + + NSPrivacyAccessedAPITypes + + NSPrivacyCollectedDataTypes + + NSPrivacyTrackingDomains + + + + diff --git a/Sources/CXKCPShims/include/CXKCPShims.h b/Sources/CXKCPShims/include/CXKCPShims.h new file mode 100644 index 000000000..2184433f2 --- /dev/null +++ b/Sources/CXKCPShims/include/CXKCPShims.h @@ -0,0 +1,69 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2019 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +#ifndef C_XKCP_SHIMS_H +#define C_XKCP_SHIMS_H + +// This is for instances when `swift package generate-xcodeproj` is used as CXKCP +// is treated as a framework and requires the framework's name as a prefix. +#if __has_include() +#include +#else +#include +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +// MARK:- Macro wrapper shims +// This section of the code handles shims that wrap XKCP macros as C functions. +// This is done because Swift cannot call C macros directly, so we need to wrap +// them in actual C functions to make them callable from Swift. +// +// The XKCP library defines initialization macros for different SHA-3 variants: +// - Keccak_HashInitialize_SHA3_256 +// - Keccak_HashInitialize_SHA3_384 +// - Keccak_HashInitialize_SHA3_512 +// +// These macros call Keccak_HashInitialize with specific parameters for each variant. + +/** + * Wrapper function for Keccak_HashInitialize_SHA3_256 macro. + * Initializes a SHA3-256 hash instance. + * @param hashInstance Pointer to the hash instance to be initialized. + * @return KECCAK_SUCCESS if successful, KECCAK_FAIL otherwise. + */ +HashReturn CXKCPShims_Keccak_HashInitialize_SHA3_256(Keccak_HashInstance *hashInstance); + +/** + * Wrapper function for Keccak_HashInitialize_SHA3_384 macro. + * Initializes a SHA3-384 hash instance. + * @param hashInstance Pointer to the hash instance to be initialized. + * @return KECCAK_SUCCESS if successful, KECCAK_FAIL otherwise. + */ +HashReturn CXKCPShims_Keccak_HashInitialize_SHA3_384(Keccak_HashInstance *hashInstance); + +/** + * Wrapper function for Keccak_HashInitialize_SHA3_512 macro. + * Initializes a SHA3-512 hash instance. + * @param hashInstance Pointer to the hash instance to be initialized. + * @return KECCAK_SUCCESS if successful, KECCAK_FAIL otherwise. + */ +HashReturn CXKCPShims_Keccak_HashInitialize_SHA3_512(Keccak_HashInstance *hashInstance); + +#if defined(__cplusplus) +} +#endif // defined(__cplusplus) + +#endif // C_XKCP_SHIMS_H diff --git a/Sources/CXKCPShims/include/module.modulemap b/Sources/CXKCPShims/include/module.modulemap new file mode 100644 index 000000000..8bc0a380c --- /dev/null +++ b/Sources/CXKCPShims/include/module.modulemap @@ -0,0 +1,4 @@ +module CXKCPShims { + header "CXKCPShims.h" + export * +} diff --git a/Sources/CXKCPShims/shims.c b/Sources/CXKCPShims/shims.c new file mode 100644 index 000000000..761cd9988 --- /dev/null +++ b/Sources/CXKCPShims/shims.c @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2019 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +#include + +// MARK:- Macro wrapper shims +// This section of the code handles shims that wrap XKCP macros as C functions. +// This is done because Swift cannot call C macros directly, so we need to wrap +// them in actual C functions to make them callable from Swift. +// +// The XKCP library defines initialization macros for different SHA-3 variants: +// - Keccak_HashInitialize_SHA3_256 -> Keccak_HashInitialize(hashInstance, 1088, 512, 256, 0x06) +// - Keccak_HashInitialize_SHA3_384 -> Keccak_HashInitialize(hashInstance, 832, 768, 384, 0x06) +// - Keccak_HashInitialize_SHA3_512 -> Keccak_HashInitialize(hashInstance, 576, 1024, 512, 0x06) + +HashReturn CXKCPShims_Keccak_HashInitialize_SHA3_256(Keccak_HashInstance *hashInstance) { + return Keccak_HashInitialize(hashInstance, 1088, 512, 256, 0x06); +} + +HashReturn CXKCPShims_Keccak_HashInitialize_SHA3_384(Keccak_HashInstance *hashInstance) { + return Keccak_HashInitialize(hashInstance, 832, 768, 384, 0x06); +} + +HashReturn CXKCPShims_Keccak_HashInitialize_SHA3_512(Keccak_HashInstance *hashInstance) { + return Keccak_HashInitialize(hashInstance, 576, 1024, 512, 0x06); +} diff --git a/Sources/Crypto/CMakeLists.txt b/Sources/Crypto/CMakeLists.txt index 7c0479080..c613f989c 100644 --- a/Sources/Crypto/CMakeLists.txt +++ b/Sources/Crypto/CMakeLists.txt @@ -43,6 +43,7 @@ add_library(Crypto "Digests/HashFunctions.swift" "Digests/HashFunctions_SHA2.swift" "Digests/HashFunctions_SHA3.swift" + "Digests/XKCP/Digest_xkcp.swift" "HPKE/Ciphersuite/HPKE-AEAD.swift" "HPKE/Ciphersuite/HPKE-Ciphersuite.swift" "HPKE/Ciphersuite/HPKE-KDF.swift" @@ -117,13 +118,17 @@ endif() target_include_directories(Crypto PRIVATE $ $ - $) + $ + $ + $) target_link_libraries(Crypto PUBLIC $<$>:dispatch> $<$>:Foundation> CCryptoBoringSSL CCryptoBoringSSLShims - CryptoBoringWrapper) + CryptoBoringWrapper + CXKCP + CXKCPShims) target_compile_options(Crypto PRIVATE ${SWIFT_CRYPTO_COMPILE_OPTIONS}) set_target_properties(Crypto PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY}) diff --git a/Sources/Crypto/Digests/BoringSSL/Digest_boring.swift b/Sources/Crypto/Digests/BoringSSL/Digest_boring.swift index 479190155..0ecc61c4d 100644 --- a/Sources/Crypto/Digests/BoringSSL/Digest_boring.swift +++ b/Sources/Crypto/Digests/BoringSSL/Digest_boring.swift @@ -47,7 +47,8 @@ extension Insecure.MD5: BoringSSLBackedHashFunction { } static func finalize(_ context: inout MD5_CTX, digest: UnsafeMutableRawBufferPointer) -> Bool { - CCryptoBoringSSL_MD5_Final(digest.baseAddress, &context) == 1 + guard let baseAddress = digest.baseAddress, digest.count == Self.digestSize else { return false } + return CCryptoBoringSSL_MD5_Final(baseAddress, &context) == 1 } } @@ -70,7 +71,8 @@ extension Insecure.SHA1: BoringSSLBackedHashFunction { } static func finalize(_ context: inout SHA_CTX, digest: UnsafeMutableRawBufferPointer) -> Bool { - CCryptoBoringSSL_SHA1_Final(digest.baseAddress, &context) == 1 + guard let baseAddress = digest.baseAddress, digest.count == Self.digestSize else { return false } + return CCryptoBoringSSL_SHA1_Final(baseAddress, &context) == 1 } } @@ -93,7 +95,8 @@ extension SHA256: BoringSSLBackedHashFunction { } static func finalize(_ context: inout SHA256_CTX, digest: UnsafeMutableRawBufferPointer) -> Bool { - CCryptoBoringSSL_SHA256_Final(digest.baseAddress, &context) == 1 + guard let baseAddress = digest.baseAddress, digest.count == Self.digestSize else { return false } + return CCryptoBoringSSL_SHA256_Final(baseAddress, &context) == 1 } } @@ -116,7 +119,8 @@ extension SHA384: BoringSSLBackedHashFunction { } static func finalize(_ context: inout SHA512_CTX, digest: UnsafeMutableRawBufferPointer) -> Bool { - CCryptoBoringSSL_SHA384_Final(digest.baseAddress, &context) == 1 + guard let baseAddress = digest.baseAddress, digest.count == Self.digestSize else { return false } + return CCryptoBoringSSL_SHA384_Final(baseAddress, &context) == 1 } } @@ -139,7 +143,8 @@ extension SHA512: BoringSSLBackedHashFunction { } static func finalize(_ context: inout SHA512_CTX, digest: UnsafeMutableRawBufferPointer) -> Bool { - CCryptoBoringSSL_SHA512_Final(digest.baseAddress, &context) == 1 + guard let baseAddress = digest.baseAddress, digest.count == Self.digestSize else { return false } + return CCryptoBoringSSL_SHA512_Final(baseAddress, &context) == 1 } } diff --git a/Sources/Crypto/Digests/HashFunctions.swift b/Sources/Crypto/Digests/HashFunctions.swift index a0c1df748..5b6d97baa 100644 --- a/Sources/Crypto/Digests/HashFunctions.swift +++ b/Sources/Crypto/Digests/HashFunctions.swift @@ -17,9 +17,13 @@ #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) typealias DigestImpl = CoreCryptoDigestImpl +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +typealias DigestImplSHA3 = CoreCryptoDigestImpl #else @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) typealias DigestImpl = OpenSSLDigestImpl +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +typealias DigestImplSHA3 = XKCPDigestImpl #endif #if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION diff --git a/Sources/Crypto/Digests/HashFunctions_SHA3.swift b/Sources/Crypto/Digests/HashFunctions_SHA3.swift index 77ad3ce64..bd4d8c56c 100644 --- a/Sources/Crypto/Digests/HashFunctions_SHA3.swift +++ b/Sources/Crypto/Digests/HashFunctions_SHA3.swift @@ -11,8 +11,6 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// -// No BoringSSL support for SHA3. -#if false #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else @@ -37,7 +35,7 @@ public struct SHA3_256: HashFunctionImplementationDetails, Sendable { /// The digest type for a SHA3-256 hash function. public typealias Digest = SHA3_256Digest - var impl: DigestImpl + var impl: DigestImplSHA3 /// Creates a SHA3-256 hash function. /// @@ -50,7 +48,7 @@ public struct SHA3_256: HashFunctionImplementationDetails, Sendable { /// If your data fits into a single buffer, you can use the ``hash(data:)`` /// method instead, to compute the digest in a single call. public init() { - impl = DigestImpl() + impl = DigestImplSHA3() } /// Incrementally updates the hash function with the contents of the buffer. @@ -108,7 +106,7 @@ public struct SHA3_384: HashFunctionImplementationDetails, Sendable { /// The digest type for a SHA3-384 hash function. public typealias Digest = SHA3_384Digest - var impl: DigestImpl + var impl: DigestImplSHA3 /// Creates a SHA3-384 hash function. /// @@ -121,7 +119,7 @@ public struct SHA3_384: HashFunctionImplementationDetails, Sendable { /// If your data fits into a single buffer, you can use the ``hash(data:)`` /// method instead, to compute the digest in a single call. public init() { - impl = DigestImpl() + impl = DigestImplSHA3() } /// Incrementally updates the hash function with the contents of the buffer. @@ -179,7 +177,7 @@ public struct SHA3_512: HashFunctionImplementationDetails, Sendable { /// The digest type for a SHA3-512 hash function. public typealias Digest = SHA3_512Digest - var impl: DigestImpl + var impl: DigestImplSHA3 /// Creates a SHA3-512 hash function. /// @@ -192,7 +190,7 @@ public struct SHA3_512: HashFunctionImplementationDetails, Sendable { /// If your data fits into a single buffer, you can use the ``hash(data:)`` /// method instead, to compute the digest in a single call. public init() { - impl = DigestImpl() + impl = DigestImplSHA3() } /// Incrementally updates the hash function with the contents of the buffer. @@ -231,4 +229,3 @@ public struct SHA3_512: HashFunctionImplementationDetails, Sendable { } #endif // !CRYPTOKIT_IN_SEP #endif // Linux or !SwiftPM -#endif // No BoringSSL support for SHA3. diff --git a/Sources/Crypto/Digests/XKCP/Digest_xkcp.swift b/Sources/Crypto/Digests/XKCP/Digest_xkcp.swift new file mode 100644 index 000000000..91a8c6f5b --- /dev/null +++ b/Sources/Crypto/Digests/XKCP/Digest_xkcp.swift @@ -0,0 +1,160 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2019 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +@_exported import CryptoKit +#else +@_implementationOnly import CXKCP +@_implementationOnly import CXKCPShims + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +protocol XKCPBackedHashFunction: HashFunctionImplementationDetails { + associatedtype Context + static var digestSize: Int { get } + static func initialize() -> Context? + static func update(_ context: inout Context, data: UnsafeRawBufferPointer) -> Bool + static func finalize(_ context: inout Context, digest: UnsafeMutableRawBufferPointer) -> Bool +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension SHA3_256: XKCPBackedHashFunction { + static var digestSize: Int { 32 } + + static func initialize() -> Keccak_HashInstance? { + var context = Keccak_HashInstance() + guard CXKCPShims_Keccak_HashInitialize_SHA3_256(&context) == KECCAK_SUCCESS else { + return nil + } + return context + } + + static func update(_ context: inout Keccak_HashInstance, data: UnsafeRawBufferPointer) -> Bool { + guard let baseAddress = data.baseAddress else { return true } + return Keccak_HashUpdate(&context, baseAddress, data.count * 8) == KECCAK_SUCCESS + } + + static func finalize(_ context: inout Keccak_HashInstance, digest: UnsafeMutableRawBufferPointer) -> Bool { + guard let baseAddress = digest.baseAddress, digest.count == Self.digestSize else { return false } + return Keccak_HashFinal(&context, baseAddress) == KECCAK_SUCCESS + } +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension SHA3_384: XKCPBackedHashFunction { + static var digestSize: Int { 48 } + + static func initialize() -> Keccak_HashInstance? { + var context = Keccak_HashInstance() + guard CXKCPShims_Keccak_HashInitialize_SHA3_384(&context) == KECCAK_SUCCESS else { + return nil + } + return context + } + + static func update(_ context: inout Keccak_HashInstance, data: UnsafeRawBufferPointer) -> Bool { + guard let baseAddress = data.baseAddress else { return true } + return Keccak_HashUpdate(&context, baseAddress, data.count * 8) == KECCAK_SUCCESS + } + + static func finalize(_ context: inout Keccak_HashInstance, digest: UnsafeMutableRawBufferPointer) -> Bool { + guard let baseAddress = digest.baseAddress, digest.count == Self.digestSize else { return false } + return Keccak_HashFinal(&context, baseAddress) == KECCAK_SUCCESS + } +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension SHA3_512: XKCPBackedHashFunction { + static var digestSize: Int { 64 } + + static func initialize() -> Keccak_HashInstance? { + var context = Keccak_HashInstance() + guard CXKCPShims_Keccak_HashInitialize_SHA3_512(&context) == KECCAK_SUCCESS else { + return nil + } + return context + } + + static func update(_ context: inout Keccak_HashInstance, data: UnsafeRawBufferPointer) -> Bool { + guard let baseAddress = data.baseAddress else { return true } + return Keccak_HashUpdate(&context, baseAddress, data.count * 8) == KECCAK_SUCCESS + } + + static func finalize(_ context: inout Keccak_HashInstance, digest: UnsafeMutableRawBufferPointer) -> Bool { + guard let baseAddress = digest.baseAddress, digest.count == Self.digestSize else { return false } + return Keccak_HashFinal(&context, baseAddress) == KECCAK_SUCCESS + } +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +struct XKCPDigestImpl: @unchecked Sendable { + private var context: XKCPDigestContext + + init() { + self.context = XKCPDigestContext() + } + + internal mutating func update(data: UnsafeRawBufferPointer) { + if !isKnownUniquelyReferenced(&self.context) { + self.context = XKCPDigestContext(copying: self.context) + } + self.context.update(data: data) + } + + internal func finalize() -> H.Digest { + self.context.finalize() + } +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +private final class XKCPDigestContext { + private var context: H.Context + + init() { + guard let context = H.initialize() else { + preconditionFailure("Unable to initialize digest state") + } + self.context = context + } + + init(copying original: XKCPDigestContext) { + self.context = original.context + } + + func update(data: UnsafeRawBufferPointer) { + guard H.update(&self.context, data: data) else { + preconditionFailure("Unable to update digest state") + } + } + + func finalize() -> H.Digest { + var copyContext = self.context + defer { + withUnsafeMutablePointer(to: ©Context) { $0.zeroize() } + } + return withUnsafeTemporaryAllocation(byteCount: H.digestSize, alignment: 1) { digestPointer in + defer { + digestPointer.zeroize() + } + guard H.finalize(©Context, digest: digestPointer) else { + preconditionFailure("Unable to finalize digest state") + } + // We force unwrap here because if the digest size is wrong it's an internal error. + return H.Digest(bufferPointer: UnsafeRawBufferPointer(digestPointer))! + } + } + + deinit { + withUnsafeMutablePointer(to: &self.context) { $0.zeroize() } + } +} +#endif // CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API diff --git a/Tests/CXKCPTests/CXKCPTests.swift b/Tests/CXKCPTests/CXKCPTests.swift new file mode 100644 index 000000000..652467ec7 --- /dev/null +++ b/Tests/CXKCPTests/CXKCPTests.swift @@ -0,0 +1,136 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2019 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import XCTest + +@testable import CXKCP + +final class CXKCPTests: XCTestCase { + + func testSHA3_256() throws { + // Test data: "abc" + let input = "abc".data(using: .utf8)! + var output = [UInt8](repeating: 0, count: 32) + + let result = input.withUnsafeBytes { inputBytes in + SHA3_256(&output, inputBytes.bindMemory(to: UInt8.self).baseAddress, inputBytes.count) + } + + // Should return 0 on success + XCTAssertEqual(result, 0, "SHA3_256 should return 0 on success") + + // Expected SHA3-256 hash of "abc" + let expectedHex = "3a985da74fe225b2045c172d6bd390bd855f086e3e9d525b46bfe24511431532" + let actualHex = output.map { String(format: "%02x", $0) }.joined() + + XCTAssertEqual(actualHex, expectedHex, "SHA3-256 hash should match expected value") + } + + func testSHA3_224() throws { + // Test data: "abc" + let input = "abc".data(using: .utf8)! + var output = [UInt8](repeating: 0, count: 28) + + let result = input.withUnsafeBytes { inputBytes in + SHA3_224(&output, inputBytes.bindMemory(to: UInt8.self).baseAddress, inputBytes.count) + } + + // Should return 0 on success + XCTAssertEqual(result, 0, "SHA3_224 should return 0 on success") + + // Expected SHA3-224 hash of "abc" + let expectedHex = "e642824c3f8cf24ad09234ee7d3c766fc9a3a5168d0c94ad73b46fdf" + let actualHex = output.map { String(format: "%02x", $0) }.joined() + + XCTAssertEqual(actualHex, expectedHex, "SHA3-224 hash should match expected value") + } + + func testSHA3_384() throws { + // Test data: "abc" + let input = "abc".data(using: .utf8)! + var output = [UInt8](repeating: 0, count: 48) + + let result = input.withUnsafeBytes { inputBytes in + SHA3_384(&output, inputBytes.bindMemory(to: UInt8.self).baseAddress, inputBytes.count) + } + + // Should return 0 on success + XCTAssertEqual(result, 0, "SHA3_384 should return 0 on success") + + // Expected SHA3-384 hash of "abc" + let expectedHex = + "ec01498288516fc926459f58e2c6ad8df9b473cb0fc08c2596da7cf0e49be4b298d88cea927ac7f539f1edf228376d25" + let actualHex = output.map { String(format: "%02x", $0) }.joined() + + XCTAssertEqual(actualHex, expectedHex, "SHA3-384 hash should match expected value") + } + + func testSHA3_512() throws { + // Test data: "abc" + let input = "abc".data(using: .utf8)! + var output = [UInt8](repeating: 0, count: 64) + + let result = input.withUnsafeBytes { inputBytes in + SHA3_512(&output, inputBytes.bindMemory(to: UInt8.self).baseAddress, inputBytes.count) + } + + // Should return 0 on success + XCTAssertEqual(result, 0, "SHA3_512 should return 0 on success") + + // Expected SHA3-512 hash of "abc" + let expectedHex = + "b751850b1a57168a5693cd924b6b096e08f621827444f70d884f5d0240d2712e10e116e9192af3c91a7ec57647e3934057340b4cf408d5a56592f8274eec53f0" + let actualHex = output.map { String(format: "%02x", $0) }.joined() + + XCTAssertEqual(actualHex, expectedHex, "SHA3-512 hash should match expected value") + } + + func testSHAKE128() throws { + // Test data: "abc" + let input = "abc".data(using: .utf8)! + var output = [UInt8](repeating: 0, count: 32) // 256 bits output + + let result = input.withUnsafeBytes { inputBytes in + SHAKE128(&output, output.count, inputBytes.bindMemory(to: UInt8.self).baseAddress, inputBytes.count) + } + + // Should return 0 on success + XCTAssertEqual(result, 0, "SHAKE128 should return 0 on success") + + // Expected SHAKE128 output (first 32 bytes) for "abc" + let expectedHex = "5881092dd818bf5cf8a3ddb793fbcba74097d5c526a6d35f97b83351940f2cc8" + let actualHex = output.map { String(format: "%02x", $0) }.joined() + + XCTAssertEqual(actualHex, expectedHex, "SHAKE128 output should match expected value") + } + + func testSHAKE256() throws { + // Test data: "abc" + let input = "abc".data(using: .utf8)! + var output = [UInt8](repeating: 0, count: 32) // 256 bits output + + let result = input.withUnsafeBytes { inputBytes in + SHAKE256(&output, output.count, inputBytes.bindMemory(to: UInt8.self).baseAddress, inputBytes.count) + } + + // Should return 0 on success + XCTAssertEqual(result, 0, "SHAKE256 should return 0 on success") + + // Expected SHAKE256 output (first 32 bytes) for "abc" + let expectedHex = "483366601360a8771c6863080cc4114d8db44530f8f1e1ee4f94ea37e78b5739" + let actualHex = output.map { String(format: "%02x", $0) }.joined() + + XCTAssertEqual(actualHex, expectedHex, "SHAKE256 output should match expected value") + } +} diff --git a/Tests/CryptoTests/Digests/DigestsTests.swift b/Tests/CryptoTests/Digests/DigestsTests.swift index 0fc345df8..d65b4acd6 100644 --- a/Tests/CryptoTests/Digests/DigestsTests.swift +++ b/Tests/CryptoTests/Digests/DigestsTests.swift @@ -26,8 +26,8 @@ enum TestError: Error { } func nullTestVectorForAlgorithm(hashFunction: H.Type) throws -> String { - #if false #if !CRYPTOKIT_IN_SEP +#if !canImport(Darwin) || canImport(CryptoKit, _version: 324.0.4) if #available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, macCatalyst 19.0, visionOS 2.0, *) { switch H.self { case is SHA3_256.Type: return "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a" @@ -37,8 +37,8 @@ func nullTestVectorForAlgorithm(hashFunction: H.Type) throws -> break } } +#endif // !canImport(Darwin) || canImport(CryptoKit, _version: 324.0.4) #endif // !CRYPTOKIT_IN_SEP - #endif switch H.self { case is Insecure.SHA1.Type: return "da39a3ee5e6b4b0d3255bfef95601890afd80709" @@ -52,8 +52,8 @@ func nullTestVectorForAlgorithm(hashFunction: H.Type) throws -> } func testVectorForAlgorithm(hashFunction: H.Type) throws -> String { - #if false #if !CRYPTOKIT_IN_SEP +#if !canImport(Darwin) || canImport(CryptoKit, _version: 324.0.4) if #available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, macCatalyst 19.0, visionOS 2.0, *) { switch H.self { case is SHA3_256.Type: return "916f6061fe879741ca6469b43971dfdb28b1a32dc36cb3254e812be27aad1d18" @@ -63,8 +63,8 @@ func testVectorForAlgorithm(hashFunction: H.Type) throws -> Str break } } +#endif // !canImport(Darwin) || canImport(CryptoKit, _version: 324.0.4) #endif // !CRYPTOKIT_IN_SEP - #endif switch H.self { case is Insecure.SHA1.Type: return "a49b2446a02c645bf419f995b67091253a04a259" @@ -118,13 +118,13 @@ class DigestsTests: XCTestCase { try orFail { try testHashFunction(hf: SHA384.self) } try orFail { try testHashFunction(hf: SHA512.self) } #if !CRYPTOKIT_IN_SEP - #if false +#if !canImport(Darwin) || canImport(CryptoKit, _version: 324.0.4) if #available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, macCatalyst 19.0, visionOS 2.0, *) { try orFail { try testHashFunction(hf: SHA3_256.self) } try orFail { try testHashFunction(hf: SHA3_384.self) } try orFail { try testHashFunction(hf: SHA3_512.self) } } - #endif +#endif // !canImport(Darwin) || canImport(CryptoKit, _version: 324.0.4) #endif // !CRYPTOKIT_IN_SEP } @@ -149,13 +149,13 @@ class DigestsTests: XCTestCase { try orFail { try testHashFunctionImplementsCoW(hf: SHA384.self) } try orFail { try testHashFunctionImplementsCoW(hf: SHA512.self) } #if !CRYPTOKIT_IN_SEP - #if false +#if !canImport(Darwin) || canImport(CryptoKit, _version: 324.0.4) if #available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, macCatalyst 19.0, visionOS 2.0, *) { try orFail { try testHashFunctionImplementsCoW(hf: SHA3_256.self) } try orFail { try testHashFunctionImplementsCoW(hf: SHA3_384.self) } try orFail { try testHashFunctionImplementsCoW(hf: SHA3_512.self) } } - #endif +#endif // !canImport(Darwin) || canImport(CryptoKit, _version: 324.0.4) #endif // !CRYPTOKIT_IN_SEP } @@ -168,13 +168,13 @@ class DigestsTests: XCTestCase { XCTAssertEqual(SHA512.blockByteCount, 128) #if !CRYPTOKIT_IN_SEP - #if false +#if !canImport(Darwin) || canImport(CryptoKit, _version: 324.0.4) if #available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, macCatalyst 19.0, visionOS 2.0, *) { XCTAssertEqual(SHA3_256.blockByteCount, 136) XCTAssertEqual(SHA3_384.blockByteCount, 104) XCTAssertEqual(SHA3_512.blockByteCount, 72) } - #endif +#endif // !canImport(Darwin) || canImport(CryptoKit, _version: 324.0.4) #endif // !CRYPTOKIT_IN_SEP } } diff --git a/scripts/vendor-xkcp.sh b/scripts/vendor-xkcp.sh new file mode 100755 index 000000000..cbcdb62e2 --- /dev/null +++ b/scripts/vendor-xkcp.sh @@ -0,0 +1,67 @@ +#!/bin/bash +##===----------------------------------------------------------------------===## +## +## This source file is part of the SwiftCrypto open source project +## +## Copyright (c) 2019-2021 Apple Inc. and the SwiftCrypto project authors +## Licensed under Apache License v2.0 +## +## See LICENSE.txt for license information +## See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +## +## SPDX-License-Identifier: Apache-2.0 +## +##===----------------------------------------------------------------------===## +set -euo pipefail + +log() { printf -- "** %s\n" "$*" >&2; } +error() { printf -- "** ERROR: %s\n" "$*" >&2; } +fatal() { error "$@"; exit 1; } +trap 'error "command failed (line ${LINENO})"' ERR + +CURRENT_SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT=$(git -C "${CURRENT_SCRIPT_DIR}" rev-parse --show-toplevel) +DESTINATION_DIR=${REPO_ROOT}/Sources/CXKCP +VENDOR_LOGFILE="${DESTINATION_DIR}/vendored-sources.txt" + +log "Checking required environment variables..." +test -n "${XKCP_PATH:-}" || fatal "XKCP_PATH unset" + +log "Checking running from swift-crypto with no uncommited changes in destination dir: ${DESTINATION_DIR} ..." +PACKAGE_NAME=$(swift package --package-path "${REPO_ROOT}" describe --type text | /usr/bin/head -1 | grep "Name:" | awk '{ print $2 }') +if [[ "${PACKAGE_NAME}" != "swift-crypto" ]]; then + fatal "Not running in swift-crypto; current package appears to be: ${PACKAGE_NAME}" +fi +[ -z "$(git -C "${REPO_ROOT}" status --porcelain -- "${DESTINATION_DIR}")" ] || fatal "Aborting vendor script: local changes detected." + +log "Checking XKCP checkout exists: ${XKCP_PATH}" +test -d "${XKCP_PATH}/.git" + +log "Getting XKCP hash..." +XKCP_DESCRIBE=$(git -C "${XKCP_PATH}" describe --all --long) +XKCP_BRANCH=$(git -C "${XKCP_PATH}" rev-parse --abbrev-ref HEAD) + +# ----------------------------------------------------------------------------- + +log "Vendoring code from ${XKCP_PATH}#${XKCP_BRANCH} (${XKCP_DESCRIBE})" +XKCP_PACK_MAKE_TARGET=FIPS202-opt64.pack +XKCP_PACK_PATH="${XKCP_PATH}/bin/${XKCP_PACK_MAKE_TARGET/.pack/.tar.gz}" +make -C "${XKCP_PATH}" "${XKCP_PACK_MAKE_TARGET}" +tar -tf "${XKCP_PACK_PATH}" || fatal "Could not find expected built pack: ${XKCP_PACK_PATH}" + +log "Unpacking to destination: ${DESTINATION_DIR}" +tar -C "${DESTINATION_DIR}" -xvf "${XKCP_PACK_PATH}" + +cat > "${VENDOR_LOGFILE}" < Date: Tue, 9 Sep 2025 11:12:32 -0400 Subject: [PATCH 24/47] Catch-up merge main into wwdc25 branch (#403) Co-authored-by: YourMJK <37852512+YourMJK@users.noreply.github.com> Co-authored-by: Rick Newton-Rogers Co-authored-by: Raphael Co-authored-by: Si Beaumont Co-authored-by: Evan Wilde Co-authored-by: Tim Condon <0xTim@users.noreply.github.com> Co-authored-by: Gus Cairo Co-authored-by: George Barnett Co-authored-by: Fabrice de Gans Co-authored-by: Wojciech Nagrodzki <278594+wnagrodzki@users.noreply.github.com> Co-authored-by: Jesse L. Zamora Co-authored-by: aryan-25 --- .github/PULL_REQUEST_TEMPLATE.md | 4 +- .github/workflows/main.yml | 21 + .github/workflows/pull_request.yml | 13 + .swiftformatignore | 1 - Benchmarks/Benchmarks/Benchmarks.swift | 104 + CMakeLists.txt | 16 + NOTICE.txt | 2 +- Package.swift | 1 - README.md | 6 +- Sources/CCryptoBoringSSL/CMakeLists.txt | 21 +- ...CryptoBoringSSL_boringssl_prefix_symbols.h | 16 + ...toBoringSSL_boringssl_prefix_symbols_asm.h | 16 + .../include/boringssl_prefix_symbols_nasm.inc | 32 + Sources/Crypto/CMakeLists.txt | 1 + Sources/Crypto/CryptoError_boring.swift | 18 + .../EC/BoringSSL/NISTCurvesKeys_boring.swift | 18 +- .../EC/EllipticCurvePoint.swift | 113 + Sources/_CryptoExtras/AES/AES_CBC.swift | 10 +- Sources/_CryptoExtras/AES/CMAC.swift | 214 ++ Sources/_CryptoExtras/ARC/ARC+API.swift | 402 ++- Sources/_CryptoExtras/ARC/ARC.swift | 17 +- Sources/_CryptoExtras/ARC/ARCCredential.swift | 2 +- Sources/_CryptoExtras/ARC/ARCEncoding.swift | 205 +- .../_CryptoExtras/ARC/ARCPrecredential.swift | 4 +- .../_CryptoExtras/ARC/ARCPresentation.swift | 16 +- Sources/_CryptoExtras/ARC/ARCRequest.swift | 8 +- Sources/_CryptoExtras/ARC/ARCResponse.swift | 10 +- Sources/_CryptoExtras/ARC/ARCServer.swift | 10 +- Sources/_CryptoExtras/CMakeLists.txt | 10 +- Sources/_CryptoExtras/Docs.docc/index.md | 4 - .../_CryptoExtras/EC/ObjectIdentifier.swift | 37 + .../EC/PKCS8DERRepresentation.swift | 76 + .../_CryptoExtras/EC/PKCS8PrivateKey.swift | 93 + .../EC/RFC8410AlgorithmIdentifier.swift | 74 + .../BoringSSL/ECToolbox_boring.swift | 39 +- .../_CryptoExtras/RSA/RSA+BlindSigning.swift | 4 +- Sources/_CryptoExtras/RSA/RSA.swift | 44 +- Sources/_CryptoExtras/RSA/RSA_boring.swift | 13 + Sources/_CryptoExtras/RSA/RSA_security.swift | 482 --- .../_CryptoExtras/Util/Data+Extensions.swift | 5 + .../Util/ThreadSpecific/ThreadOps.swift | 35 + .../Util/ThreadSpecific/ThreadPosix.swift | 73 + .../Util/ThreadSpecific/ThreadSpecific.swift | 111 + .../Util/ThreadSpecific/ThreadWindows.swift | 56 + Tests/_CryptoExtrasTests/AES_CBCTests.swift | 8 + .../_CryptoExtrasTests/ARC/ARCAPITests.swift | 216 +- .../ARC/ARCEncodingTests.swift | 75 +- .../ARC/ARCPublicAPITests.swift | 12 +- .../ARC/ARCTestVectors.swift | 81 +- Tests/_CryptoExtrasTests/ARC/ARCTests.swift | 8 +- Tests/_CryptoExtrasTests/CMACTests.swift | 197 ++ .../BoringSSL/ECToolboxBoringSSLTests.swift | 104 + .../PKCS8DERRepresentationTests.swift | 201 ++ .../_CryptoExtrasTests/Utils/BytesUtil.swift | 6 +- Tests/_CryptoExtrasVectors/aes_cmac_test.json | 2842 +++++++++++++++++ cmake/modules/SwiftCryptoConfig.cmake.in | 2 + scripts/generate-linux-sdks.sh | 78 + scripts/vendor-boringssl.sh | 28 +- 58 files changed, 5548 insertions(+), 767 deletions(-) create mode 100644 Sources/Crypto/CryptoError_boring.swift create mode 100644 Sources/_CryptoExtras/AES/CMAC.swift create mode 100644 Sources/_CryptoExtras/EC/ObjectIdentifier.swift create mode 100644 Sources/_CryptoExtras/EC/PKCS8DERRepresentation.swift create mode 100644 Sources/_CryptoExtras/EC/PKCS8PrivateKey.swift create mode 100644 Sources/_CryptoExtras/EC/RFC8410AlgorithmIdentifier.swift delete mode 100644 Sources/_CryptoExtras/RSA/RSA_security.swift create mode 100644 Sources/_CryptoExtras/Util/ThreadSpecific/ThreadOps.swift create mode 100644 Sources/_CryptoExtras/Util/ThreadSpecific/ThreadPosix.swift create mode 100644 Sources/_CryptoExtras/Util/ThreadSpecific/ThreadSpecific.swift create mode 100644 Sources/_CryptoExtras/Util/ThreadSpecific/ThreadWindows.swift create mode 100644 Tests/_CryptoExtrasTests/CMACTests.swift create mode 100644 Tests/_CryptoExtrasTests/ECToolbox/BoringSSL/ECToolboxBoringSSLTests.swift create mode 100644 Tests/_CryptoExtrasTests/PKCS8DERRepresentationTests.swift create mode 100644 Tests/_CryptoExtrasVectors/aes_cmac_test.json create mode 100755 scripts/generate-linux-sdks.sh diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index b62b40d3f..6bfe680f0 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -9,7 +9,7 @@ _[One line description of your change]_ - [ ] I've updated the documentation if necessary #### If you've made changes to `gyb` files -- [ ] I've run `.script/generate_boilerplate_files_with_gyb` and included updated generated files in a commit of this pull request +- [ ] I've run `./scripts/generate_boilerplate_files_with_gyb.sh` and included updated generated files in a commit of this pull request ### Motivation: @@ -21,4 +21,4 @@ _[Describe the modifications you've done.]_ ### Result: -_[After your change, what will change.]_ \ No newline at end of file +_[After your change, what will change.]_ diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 96601fa06..9e537d8b8 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -16,11 +16,32 @@ jobs: linux_6_1_arguments_override: "--explicit-target-dependency-import-check error" linux_nightly_next_arguments_override: "--explicit-target-dependency-import-check error" linux_nightly_main_arguments_override: "--explicit-target-dependency-import-check error" + windows_6_0_enabled: true + windows_6_1_enabled: true + windows_nightly_next_enabled: true + windows_nightly_main_enabled: true + windows_6_0_arguments_override: "--explicit-target-dependency-import-check error" + windows_6_1_arguments_override: "--explicit-target-dependency-import-check error" + windows_nightly_next_arguments_override: "--explicit-target-dependency-import-check error" + windows_nightly_main_arguments_override: "--explicit-target-dependency-import-check error" + + release-builds: + name: Release builds + uses: apple/swift-nio/.github/workflows/release_builds.yml@main + with: + windows_6_0_enabled: true + windows_6_1_enabled: true + windows_nightly_next_enabled: true + windows_nightly_main_enabled: true cxx-interop: name: Cxx interop uses: apple/swift-nio/.github/workflows/cxx_interop.yml@main + static-sdk: + name: Static SDK + uses: apple/swift-nio/.github/workflows/static_sdk.yml@main + macos-tests: name: macOS tests uses: apple/swift-nio/.github/workflows/macos_tests.yml@main diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 960bdc2ef..34d248012 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -30,6 +30,15 @@ jobs: windows_nightly_next_arguments_override: "--explicit-target-dependency-import-check error" windows_nightly_main_arguments_override: "--explicit-target-dependency-import-check error" + release-builds: + name: Release builds + uses: apple/swift-nio/.github/workflows/release_builds.yml@main + with: + windows_6_0_enabled: true + windows_6_1_enabled: true + windows_nightly_next_enabled: true + windows_nightly_main_enabled: true + cxx-interop: name: Cxx interop uses: apple/swift-nio/.github/workflows/cxx_interop.yml@main @@ -58,3 +67,7 @@ jobs: with: runner_pool: general build_scheme: swift-crypto-Package + + static-sdk: + name: Static SDK + uses: apple/swift-nio/.github/workflows/static_sdk.yml@main diff --git a/.swiftformatignore b/.swiftformatignore index 997aafb9c..13def9f5f 100644 --- a/.swiftformatignore +++ b/.swiftformatignore @@ -100,7 +100,6 @@ Sources/_CryptoExtras/OPRFs/VOPRFClient.swift Sources/_CryptoExtras/OPRFs/VOPRFServer.swift Sources/_CryptoExtras/RSA/RSA+BlindSigning.swift Sources/_CryptoExtras/RSA/RSA.swift -Sources/_CryptoExtras/RSA/RSA_security.swift Sources/_CryptoExtras/Util/BoringSSLHelpers.swift Sources/_CryptoExtras/Util/DigestType.swift Sources/_CryptoExtras/Util/Error.swift diff --git a/Benchmarks/Benchmarks/Benchmarks.swift b/Benchmarks/Benchmarks/Benchmarks.swift index 5836678c1..155fe1416 100644 --- a/Benchmarks/Benchmarks/Benchmarks.swift +++ b/Benchmarks/Benchmarks/Benchmarks.swift @@ -24,6 +24,65 @@ import Foundation let benchmarks = { let defaultMetrics: [BenchmarkMetric] = [.mallocCountTotal, .cpuTotal] + Benchmark( + "arc-issue-p256", + configuration: Benchmark.Configuration( + metrics: defaultMetrics, + scalingFactor: .kilo, + maxDuration: .seconds(10_000_000), + maxIterations: 3 + ) + ) { benchmark in + let privateKey = P256._ARCV1.PrivateKey() + let publicKey = privateKey.publicKey + let requestContext = Data("shared request context".utf8) + let precredential = try publicKey.prepareCredentialRequest(requestContext: requestContext) + let credentialRequest = precredential.credentialRequest + + benchmark.startMeasurement() + + for _ in benchmark.scaledIterations { + blackHole(try privateKey.issue(credentialRequest)) + } + } + + Benchmark( + "arc-verify-p256", + configuration: Benchmark.Configuration( + metrics: defaultMetrics, + scalingFactor: .kilo, + maxDuration: .seconds(10_000_000), + maxIterations: 10 + ) + ) { benchmark in + let privateKey = P256._ARCV1.PrivateKey() + let publicKey = privateKey.publicKey + let requestContext = Data("shared request context".utf8) + let (presentationContext, presentationLimit) = (Data("shared presentation context".utf8), 2) + let precredential = try publicKey.prepareCredentialRequest(requestContext: requestContext) + let credentialRequest = precredential.credentialRequest + let credentialResponse = try privateKey.issue(credentialRequest) + var credential = try publicKey.finalize(credentialResponse, for: precredential) + let (presentation, nonce) = try credential.makePresentation( + context: presentationContext, + presentationLimit: presentationLimit + ) + + benchmark.startMeasurement() + + for _ in benchmark.scaledIterations { + blackHole( + try privateKey.verify( + presentation, + requestContext: requestContext, + presentationContext: presentationContext, + presentationLimit: presentationLimit, + nonce: nonce + ) + ) + } + } + Benchmark( "arc-issue-p384", configuration: Benchmark.Configuration( @@ -104,4 +163,49 @@ let benchmarks = { blackHole(try privateKey.evaluate(blindedElement)) } } + + Benchmark( + "key-exchange-p256", + configuration: Benchmark.Configuration( + metrics: defaultMetrics, + scalingFactor: .kilo, + maxDuration: .seconds(10_000_000), + maxIterations: 10 + ) + ) { benchmark in + for _ in benchmark.scaledIterations { + let (key1, key2) = (P256.KeyAgreement.PrivateKey(), P256.KeyAgreement.PrivateKey()) + blackHole(try key1.sharedSecretFromKeyAgreement(with: key2.publicKey)) + } + } + + Benchmark( + "key-exchange-p384", + configuration: Benchmark.Configuration( + metrics: defaultMetrics, + scalingFactor: .kilo, + maxDuration: .seconds(10_000_000), + maxIterations: 10 + ) + ) { benchmark in + for _ in benchmark.scaledIterations { + let (key1, key2) = (P384.KeyAgreement.PrivateKey(), P384.KeyAgreement.PrivateKey()) + blackHole(try key1.sharedSecretFromKeyAgreement(with: key2.publicKey)) + } + } + + Benchmark( + "key-exchange-p521", + configuration: Benchmark.Configuration( + metrics: defaultMetrics, + scalingFactor: .kilo, + maxDuration: .seconds(10_000_000), + maxIterations: 10 + ) + ) { benchmark in + for _ in benchmark.scaledIterations { + let (key1, key2) = (P521.KeyAgreement.PrivateKey(), P521.KeyAgreement.PrivateKey()) + blackHole(try key1.sharedSecretFromKeyAgreement(with: key2.publicKey)) + } + } } diff --git a/CMakeLists.txt b/CMakeLists.txt index 18bed6aaf..f05387047 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,10 @@ cmake_minimum_required(VERSION 3.15.1) +if(POLICY CMP0157) + cmake_policy(SET CMP0157 NEW) +endif() + project(SwiftCrypto LANGUAGES ASM C CXX Swift) @@ -47,6 +51,18 @@ if(CMAKE_SYSTEM_NAME STREQUAL Darwin AND NOT CMAKE_CROSSCOMPILING) set(CMAKE_RANLIB "/usr/bin/ranlib") endif() +set(CMAKE_CXX_STANDARD 17) +if(CMAKE_SYSTEM_NAME STREQUAL Windows) + # We need to ensure that we don't include the min/max macros from the Windows SDK. + add_compile_definitions(NOMINMAX) + # We can only link against the DLL version of the MSVC runtime library for now. + set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreadedDLL") + if(CMAKE_Swift_COMPILER_VERSION VERSION_EQUAL 0.0.0 OR CMAKE_Swift_COMPILER_VERSION VERSION_GREATER_EQUAL 6.2) + # We need to set the static library prefix to "lib" so that we can link against the static libraries. + set(CMAKE_STATIC_LIBRARY_PREFIX_Swift "lib") + endif() +endif() + if(NOT CMAKE_SYSTEM_NAME STREQUAL Darwin) find_package(dispatch CONFIG) find_package(Foundation CONFIG) diff --git a/NOTICE.txt b/NOTICE.txt index e21679747..a7756f296 100644 --- a/NOTICE.txt +++ b/NOTICE.txt @@ -34,7 +34,7 @@ This product contains test vectors from Google's wycheproof project. --- -This product contains a derivation of various scripts from SwiftNIO. +This product contains a derivation of various files from SwiftNIO. * LICENSE (Apache License 2.0): * https://www.apache.org/licenses/LICENSE-2.0 diff --git a/Package.swift b/Package.swift index 6225fec1a..ddfe1277b 100644 --- a/Package.swift +++ b/Package.swift @@ -102,7 +102,6 @@ let package = Package( name: "CCryptoBoringSSL", exclude: privacyManifestExclude + [ "hash.txt", - "include/boringssl_prefix_symbols_nasm.inc", "CMakeLists.txt", /* * These files are excluded to support WASI libc which doesn't provide . diff --git a/README.md b/README.md index 6c7e8572a..ec5134552 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Swift Crypto -Swift Crypto is an open-source implementation of a substantial portion of the API of [Apple CryptoKit](https://developer.apple.com/documentation/cryptokit) suitable for use on Linux platforms. It enables cross-platform or server applications with the advantages of CryptoKit. +Swift Crypto is an open-source implementation of a substantial portion of the API of [Apple CryptoKit](https://developer.apple.com/documentation/cryptokit) suitable for use on Linux and ARM64 Windows platforms. It enables cross-platform or server applications with the advantages of CryptoKit. ## Using Swift Crypto @@ -28,7 +28,7 @@ Swift Crypto compiles in two distinct modes depending on the platform for which When building Swift Crypto for use on an Apple platform where CryptoKit is already available, Swift Crypto compiles its entire API surface down to nothing and simply re-exports the API of CryptoKit. This means that when using Apple platforms Swift Crypto simply delegates all work to the core implementation of CryptoKit, as though Swift Crypto was not even there. -When building Swift Crypto for use on Linux, Swift Crypto builds substantially more code. In particular, we build: +When building Swift Crypto for use on Linux or Windows, Swift Crypto builds substantially more code. In particular, we build: 1. A vendored copy of BoringSSL's libcrypto. 2. The common API of Swift Crypto and CryptoKit. @@ -129,7 +129,7 @@ What this means for you is that you should depend on Swift Crypto with a version In SwiftPM that can be easily done specifying for example `from: "1.0.0"` meaning that you support Swift Crypto in every version starting from 1.0.0 up to (excluding) 2.0.0. SemVer and Swift Crypto's Public API guarantees should result in a working program without having to worry about testing every single version for compatibility. -Swift Crypto 2.0.0 was released in September 2021. The only breaking change between Swift Crypto 2.0.0 and 1.0.0 was the addition of new cases in the `CryptoKitError` enumeration. For most users, then, it's safe to depend on either the 1.0.0 _or_ 2.0.0 series of releases. +Swift Crypto 2.0.0 was released in September 2021. The only breaking change between Swift Crypto 2.0.0 and 1.0.0 was the addition of new cases in the `CryptoError` enumeration. For most users, then, it's safe to depend on either the 1.0.0 _or_ 2.0.0 series of releases. To do so, please use the following dependency in your `Package.swift`: diff --git a/Sources/CCryptoBoringSSL/CMakeLists.txt b/Sources/CCryptoBoringSSL/CMakeLists.txt index fe17a4184..9da329bd4 100644 --- a/Sources/CCryptoBoringSSL/CMakeLists.txt +++ b/Sources/CCryptoBoringSSL/CMakeLists.txt @@ -342,8 +342,27 @@ elseif(CMAKE_SYSTEM_NAME MATCHES "Linux|Android|FreeBSD|OpenBSD" AND CMAKE_SYSTE gen/bcm/vpaes-armv8-linux.S gen/crypto/chacha-armv8-linux.S gen/crypto/chacha20_poly1305_armv8-linux.S) +elseif(CMAKE_SYSTEM_NAME MATCHES "Windows" AND CMAKE_SYSTEM_PROCESSOR MATCHES "AMD64|amd64|x86_64") + target_sources(CCryptoBoringSSL PRIVATE +) +elseif(CMAKE_SYSTEM_NAME MATCHES "Windows" AND CMAKE_SYSTEM_PROCESSOR MATCHES "ARM64|arm64|aarch64") + target_sources(CCryptoBoringSSL PRIVATE + gen/bcm/aesv8-armv8-win.S + gen/bcm/aesv8-gcm-armv8-win.S + gen/bcm/armv8-mont-win.S + gen/bcm/bn-armv8-win.S + gen/bcm/ghash-neon-armv8-win.S + gen/bcm/ghashv8-armv8-win.S + gen/bcm/p256-armv8-asm-win.S + gen/bcm/p256_beeu-armv8-asm-win.S + gen/bcm/sha1-armv8-win.S + gen/bcm/sha256-armv8-win.S + gen/bcm/sha512-armv8-win.S + gen/bcm/vpaes-armv8-win.S + gen/crypto/chacha-armv8-win.S + gen/crypto/chacha20_poly1305_armv8-win.S) else() - message(FATAL_ERROR "platform sources are not defined here") + message(FATAL_ERROR "platform sources are not defined here for ${CMAKE_SYSTEM_NAME} on ${CMAKE_SYSTEM_PROCESSOR}") endif() target_include_directories(CCryptoBoringSSL PUBLIC diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols.h index f42edc899..8b97b726b 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols.h @@ -640,6 +640,8 @@ #define bn_mul4x_mont_capable BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mul4x_mont_capable) #define bn_mul4x_mont_gather5 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mul4x_mont_gather5) #define bn_mul4x_mont_gather5_capable BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mul4x_mont_gather5_capable) +#define bn_mul8x_mont_neon BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mul8x_mont_neon) +#define bn_mul8x_mont_neon_capable BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mul8x_mont_neon_capable) #define bn_mulx_adx_capable BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mulx_adx_capable) #define bn_mulx4x_mont BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mulx4x_mont) #define bn_mulx4x_mont_capable BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mulx4x_mont_capable) @@ -735,6 +737,7 @@ #define boringssl_self_test_slhdsa BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, boringssl_self_test_slhdsa) #define bsaes_capable BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bsaes_capable) #define bsaes_cbc_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bsaes_cbc_encrypt) +#define bsaes_ctr32_encrypt_blocks BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bsaes_ctr32_encrypt_blocks) #define BUF_MEM_append BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BUF_MEM_append) #define BUF_MEM_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BUF_MEM_free) #define BUF_MEM_grow BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BUF_MEM_grow) @@ -931,6 +934,7 @@ #define CRYPTO_get_thread_local BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_get_thread_local) #define CRYPTO_ghash_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_ghash_init) #define CRYPTO_has_asm BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_has_asm) +#define CRYPTO_has_broken_NEON BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_has_broken_NEON) #define CRYPTO_hchacha20 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_hchacha20) #define CRYPTO_init_sysrand BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_init_sysrand) #define CRYPTO_is_ADX_capable BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_is_ADX_capable) @@ -967,13 +971,17 @@ #define CRYPTO_MUTEX_lock_write BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_MUTEX_lock_write) #define CRYPTO_MUTEX_unlock_read BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_MUTEX_unlock_read) #define CRYPTO_MUTEX_unlock_write BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_MUTEX_unlock_write) +#define CRYPTO_needs_hwcap2_workaround BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_needs_hwcap2_workaround) #define CRYPTO_new_ex_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_new_ex_data) #define CRYPTO_num_locks BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_num_locks) #define CRYPTO_ofb128_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_ofb128_encrypt) #define CRYPTO_once BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_once) #define CRYPTO_poly1305_finish BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_poly1305_finish) +#define CRYPTO_poly1305_finish_neon BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_poly1305_finish_neon) #define CRYPTO_poly1305_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_poly1305_init) +#define CRYPTO_poly1305_init_neon BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_poly1305_init_neon) #define CRYPTO_poly1305_update BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_poly1305_update) +#define CRYPTO_poly1305_update_neon BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_poly1305_update_neon) #define CRYPTO_pre_sandbox_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_pre_sandbox_init) #define CRYPTO_rdrand BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_rdrand) #define CRYPTO_rdrand_multiple8_buf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRYPTO_rdrand_multiple8_buf) @@ -2240,6 +2248,8 @@ #define OPENSSL_malloc_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_malloc_init) #define OPENSSL_memdup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_memdup) #define OPENSSL_no_config BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_no_config) +#define openssl_poly1305_neon2_addmulmod BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, openssl_poly1305_neon2_addmulmod) +#define openssl_poly1305_neon2_blocks BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, openssl_poly1305_neon2_blocks) #define OPENSSL_posix_to_tm BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_posix_to_tm) #define OPENSSL_realloc BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_realloc) #define OPENSSL_secure_clear_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, OPENSSL_secure_clear_free) @@ -2578,6 +2588,7 @@ #define sha1_block_data_order_avx BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sha1_block_data_order_avx) #define sha1_block_data_order_avx2 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sha1_block_data_order_avx2) #define sha1_block_data_order_hw BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sha1_block_data_order_hw) +#define sha1_block_data_order_neon BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sha1_block_data_order_neon) #define sha1_block_data_order_nohw BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sha1_block_data_order_nohw) #define sha1_block_data_order_ssse3 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sha1_block_data_order_ssse3) #define SHA1_Final BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SHA1_Final) @@ -2594,6 +2605,7 @@ #define sha256_avx_capable BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sha256_avx_capable) #define sha256_block_data_order_avx BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sha256_block_data_order_avx) #define sha256_block_data_order_hw BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sha256_block_data_order_hw) +#define sha256_block_data_order_neon BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sha256_block_data_order_neon) #define sha256_block_data_order_nohw BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sha256_block_data_order_nohw) #define sha256_block_data_order_ssse3 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sha256_block_data_order_ssse3) #define SHA256_Final BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SHA256_Final) @@ -2615,6 +2627,7 @@ #define sha512_avx_capable BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sha512_avx_capable) #define sha512_block_data_order_avx BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sha512_block_data_order_avx) #define sha512_block_data_order_hw BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sha512_block_data_order_hw) +#define sha512_block_data_order_neon BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sha512_block_data_order_neon) #define sha512_block_data_order_nohw BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sha512_block_data_order_nohw) #define SHA512_Final BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, SHA512_Final) #define sha512_hw_capable BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, sha512_hw_capable) @@ -2955,9 +2968,11 @@ #define vpaes_capable BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, vpaes_capable) #define vpaes_cbc_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, vpaes_cbc_encrypt) #define vpaes_ctr32_encrypt_blocks BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, vpaes_ctr32_encrypt_blocks) +#define vpaes_ctr32_encrypt_blocks_with_bsaes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, vpaes_ctr32_encrypt_blocks_with_bsaes) #define vpaes_decrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, vpaes_decrypt) #define vpaes_decrypt_key_to_bsaes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, vpaes_decrypt_key_to_bsaes) #define vpaes_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, vpaes_encrypt) +#define vpaes_encrypt_key_to_bsaes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, vpaes_encrypt_key_to_bsaes) #define vpaes_set_decrypt_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, vpaes_set_decrypt_key) #define vpaes_set_encrypt_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, vpaes_set_encrypt_key) #define X25519 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X25519) @@ -2974,6 +2989,7 @@ #define x25519_ge_sub BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x25519_ge_sub) #define x25519_ge_tobytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x25519_ge_tobytes) #define X25519_keypair BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X25519_keypair) +#define x25519_NEON BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x25519_NEON) #define x25519_pkey_meth BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x25519_pkey_meth) #define X25519_public_from_private BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X25519_public_from_private) #define x25519_sc_reduce BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x25519_sc_reduce) diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols_asm.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols_asm.h index 2fffdb87b..8fc7f8451 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols_asm.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols_asm.h @@ -645,6 +645,8 @@ #define _bn_mul4x_mont_capable BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mul4x_mont_capable) #define _bn_mul4x_mont_gather5 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mul4x_mont_gather5) #define _bn_mul4x_mont_gather5_capable BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mul4x_mont_gather5_capable) +#define _bn_mul8x_mont_neon BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mul8x_mont_neon) +#define _bn_mul8x_mont_neon_capable BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mul8x_mont_neon_capable) #define _bn_mulx_adx_capable BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mulx_adx_capable) #define _bn_mulx4x_mont BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mulx4x_mont) #define _bn_mulx4x_mont_capable BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mulx4x_mont_capable) @@ -740,6 +742,7 @@ #define _boringssl_self_test_slhdsa BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, boringssl_self_test_slhdsa) #define _bsaes_capable BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bsaes_capable) #define _bsaes_cbc_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bsaes_cbc_encrypt) +#define _bsaes_ctr32_encrypt_blocks BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bsaes_ctr32_encrypt_blocks) #define _BUF_MEM_append BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BUF_MEM_append) #define _BUF_MEM_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BUF_MEM_free) #define _BUF_MEM_grow BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BUF_MEM_grow) @@ -936,6 +939,7 @@ #define _CRYPTO_get_thread_local BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_get_thread_local) #define _CRYPTO_ghash_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_ghash_init) #define _CRYPTO_has_asm BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_has_asm) +#define _CRYPTO_has_broken_NEON BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_has_broken_NEON) #define _CRYPTO_hchacha20 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_hchacha20) #define _CRYPTO_init_sysrand BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_init_sysrand) #define _CRYPTO_is_ADX_capable BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_is_ADX_capable) @@ -972,13 +976,17 @@ #define _CRYPTO_MUTEX_lock_write BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_MUTEX_lock_write) #define _CRYPTO_MUTEX_unlock_read BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_MUTEX_unlock_read) #define _CRYPTO_MUTEX_unlock_write BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_MUTEX_unlock_write) +#define _CRYPTO_needs_hwcap2_workaround BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_needs_hwcap2_workaround) #define _CRYPTO_new_ex_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_new_ex_data) #define _CRYPTO_num_locks BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_num_locks) #define _CRYPTO_ofb128_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_ofb128_encrypt) #define _CRYPTO_once BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_once) #define _CRYPTO_poly1305_finish BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_poly1305_finish) +#define _CRYPTO_poly1305_finish_neon BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_poly1305_finish_neon) #define _CRYPTO_poly1305_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_poly1305_init) +#define _CRYPTO_poly1305_init_neon BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_poly1305_init_neon) #define _CRYPTO_poly1305_update BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_poly1305_update) +#define _CRYPTO_poly1305_update_neon BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_poly1305_update_neon) #define _CRYPTO_pre_sandbox_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_pre_sandbox_init) #define _CRYPTO_rdrand BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_rdrand) #define _CRYPTO_rdrand_multiple8_buf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRYPTO_rdrand_multiple8_buf) @@ -2245,6 +2253,8 @@ #define _OPENSSL_malloc_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_malloc_init) #define _OPENSSL_memdup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_memdup) #define _OPENSSL_no_config BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_no_config) +#define _openssl_poly1305_neon2_addmulmod BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, openssl_poly1305_neon2_addmulmod) +#define _openssl_poly1305_neon2_blocks BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, openssl_poly1305_neon2_blocks) #define _OPENSSL_posix_to_tm BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_posix_to_tm) #define _OPENSSL_realloc BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_realloc) #define _OPENSSL_secure_clear_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, OPENSSL_secure_clear_free) @@ -2583,6 +2593,7 @@ #define _sha1_block_data_order_avx BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sha1_block_data_order_avx) #define _sha1_block_data_order_avx2 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sha1_block_data_order_avx2) #define _sha1_block_data_order_hw BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sha1_block_data_order_hw) +#define _sha1_block_data_order_neon BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sha1_block_data_order_neon) #define _sha1_block_data_order_nohw BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sha1_block_data_order_nohw) #define _sha1_block_data_order_ssse3 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sha1_block_data_order_ssse3) #define _SHA1_Final BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SHA1_Final) @@ -2599,6 +2610,7 @@ #define _sha256_avx_capable BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sha256_avx_capable) #define _sha256_block_data_order_avx BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sha256_block_data_order_avx) #define _sha256_block_data_order_hw BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sha256_block_data_order_hw) +#define _sha256_block_data_order_neon BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sha256_block_data_order_neon) #define _sha256_block_data_order_nohw BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sha256_block_data_order_nohw) #define _sha256_block_data_order_ssse3 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sha256_block_data_order_ssse3) #define _SHA256_Final BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SHA256_Final) @@ -2620,6 +2632,7 @@ #define _sha512_avx_capable BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sha512_avx_capable) #define _sha512_block_data_order_avx BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sha512_block_data_order_avx) #define _sha512_block_data_order_hw BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sha512_block_data_order_hw) +#define _sha512_block_data_order_neon BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sha512_block_data_order_neon) #define _sha512_block_data_order_nohw BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sha512_block_data_order_nohw) #define _SHA512_Final BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, SHA512_Final) #define _sha512_hw_capable BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, sha512_hw_capable) @@ -2960,9 +2973,11 @@ #define _vpaes_capable BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, vpaes_capable) #define _vpaes_cbc_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, vpaes_cbc_encrypt) #define _vpaes_ctr32_encrypt_blocks BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, vpaes_ctr32_encrypt_blocks) +#define _vpaes_ctr32_encrypt_blocks_with_bsaes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, vpaes_ctr32_encrypt_blocks_with_bsaes) #define _vpaes_decrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, vpaes_decrypt) #define _vpaes_decrypt_key_to_bsaes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, vpaes_decrypt_key_to_bsaes) #define _vpaes_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, vpaes_encrypt) +#define _vpaes_encrypt_key_to_bsaes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, vpaes_encrypt_key_to_bsaes) #define _vpaes_set_decrypt_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, vpaes_set_decrypt_key) #define _vpaes_set_encrypt_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, vpaes_set_encrypt_key) #define _X25519 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X25519) @@ -2979,6 +2994,7 @@ #define _x25519_ge_sub BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x25519_ge_sub) #define _x25519_ge_tobytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x25519_ge_tobytes) #define _X25519_keypair BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X25519_keypair) +#define _x25519_NEON BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x25519_NEON) #define _x25519_pkey_meth BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x25519_pkey_meth) #define _X25519_public_from_private BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X25519_public_from_private) #define _x25519_sc_reduce BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x25519_sc_reduce) diff --git a/Sources/CCryptoBoringSSL/include/boringssl_prefix_symbols_nasm.inc b/Sources/CCryptoBoringSSL/include/boringssl_prefix_symbols_nasm.inc index dcc370a72..cf0a13e6f 100644 --- a/Sources/CCryptoBoringSSL/include/boringssl_prefix_symbols_nasm.inc +++ b/Sources/CCryptoBoringSSL/include/boringssl_prefix_symbols_nasm.inc @@ -637,6 +637,8 @@ %xdefine _bn_mul4x_mont_capable _ %+ BORINGSSL_PREFIX %+ _bn_mul4x_mont_capable %xdefine _bn_mul4x_mont_gather5 _ %+ BORINGSSL_PREFIX %+ _bn_mul4x_mont_gather5 %xdefine _bn_mul4x_mont_gather5_capable _ %+ BORINGSSL_PREFIX %+ _bn_mul4x_mont_gather5_capable +%xdefine _bn_mul8x_mont_neon _ %+ BORINGSSL_PREFIX %+ _bn_mul8x_mont_neon +%xdefine _bn_mul8x_mont_neon_capable _ %+ BORINGSSL_PREFIX %+ _bn_mul8x_mont_neon_capable %xdefine _bn_mulx_adx_capable _ %+ BORINGSSL_PREFIX %+ _bn_mulx_adx_capable %xdefine _bn_mulx4x_mont _ %+ BORINGSSL_PREFIX %+ _bn_mulx4x_mont %xdefine _bn_mulx4x_mont_capable _ %+ BORINGSSL_PREFIX %+ _bn_mulx4x_mont_capable @@ -732,6 +734,7 @@ %xdefine _boringssl_self_test_slhdsa _ %+ BORINGSSL_PREFIX %+ _boringssl_self_test_slhdsa %xdefine _bsaes_capable _ %+ BORINGSSL_PREFIX %+ _bsaes_capable %xdefine _bsaes_cbc_encrypt _ %+ BORINGSSL_PREFIX %+ _bsaes_cbc_encrypt +%xdefine _bsaes_ctr32_encrypt_blocks _ %+ BORINGSSL_PREFIX %+ _bsaes_ctr32_encrypt_blocks %xdefine _BUF_MEM_append _ %+ BORINGSSL_PREFIX %+ _BUF_MEM_append %xdefine _BUF_MEM_free _ %+ BORINGSSL_PREFIX %+ _BUF_MEM_free %xdefine _BUF_MEM_grow _ %+ BORINGSSL_PREFIX %+ _BUF_MEM_grow @@ -928,6 +931,7 @@ %xdefine _CRYPTO_get_thread_local _ %+ BORINGSSL_PREFIX %+ _CRYPTO_get_thread_local %xdefine _CRYPTO_ghash_init _ %+ BORINGSSL_PREFIX %+ _CRYPTO_ghash_init %xdefine _CRYPTO_has_asm _ %+ BORINGSSL_PREFIX %+ _CRYPTO_has_asm +%xdefine _CRYPTO_has_broken_NEON _ %+ BORINGSSL_PREFIX %+ _CRYPTO_has_broken_NEON %xdefine _CRYPTO_hchacha20 _ %+ BORINGSSL_PREFIX %+ _CRYPTO_hchacha20 %xdefine _CRYPTO_init_sysrand _ %+ BORINGSSL_PREFIX %+ _CRYPTO_init_sysrand %xdefine _CRYPTO_is_ADX_capable _ %+ BORINGSSL_PREFIX %+ _CRYPTO_is_ADX_capable @@ -964,13 +968,17 @@ %xdefine _CRYPTO_MUTEX_lock_write _ %+ BORINGSSL_PREFIX %+ _CRYPTO_MUTEX_lock_write %xdefine _CRYPTO_MUTEX_unlock_read _ %+ BORINGSSL_PREFIX %+ _CRYPTO_MUTEX_unlock_read %xdefine _CRYPTO_MUTEX_unlock_write _ %+ BORINGSSL_PREFIX %+ _CRYPTO_MUTEX_unlock_write +%xdefine _CRYPTO_needs_hwcap2_workaround _ %+ BORINGSSL_PREFIX %+ _CRYPTO_needs_hwcap2_workaround %xdefine _CRYPTO_new_ex_data _ %+ BORINGSSL_PREFIX %+ _CRYPTO_new_ex_data %xdefine _CRYPTO_num_locks _ %+ BORINGSSL_PREFIX %+ _CRYPTO_num_locks %xdefine _CRYPTO_ofb128_encrypt _ %+ BORINGSSL_PREFIX %+ _CRYPTO_ofb128_encrypt %xdefine _CRYPTO_once _ %+ BORINGSSL_PREFIX %+ _CRYPTO_once %xdefine _CRYPTO_poly1305_finish _ %+ BORINGSSL_PREFIX %+ _CRYPTO_poly1305_finish +%xdefine _CRYPTO_poly1305_finish_neon _ %+ BORINGSSL_PREFIX %+ _CRYPTO_poly1305_finish_neon %xdefine _CRYPTO_poly1305_init _ %+ BORINGSSL_PREFIX %+ _CRYPTO_poly1305_init +%xdefine _CRYPTO_poly1305_init_neon _ %+ BORINGSSL_PREFIX %+ _CRYPTO_poly1305_init_neon %xdefine _CRYPTO_poly1305_update _ %+ BORINGSSL_PREFIX %+ _CRYPTO_poly1305_update +%xdefine _CRYPTO_poly1305_update_neon _ %+ BORINGSSL_PREFIX %+ _CRYPTO_poly1305_update_neon %xdefine _CRYPTO_pre_sandbox_init _ %+ BORINGSSL_PREFIX %+ _CRYPTO_pre_sandbox_init %xdefine _CRYPTO_rdrand _ %+ BORINGSSL_PREFIX %+ _CRYPTO_rdrand %xdefine _CRYPTO_rdrand_multiple8_buf _ %+ BORINGSSL_PREFIX %+ _CRYPTO_rdrand_multiple8_buf @@ -2237,6 +2245,8 @@ %xdefine _OPENSSL_malloc_init _ %+ BORINGSSL_PREFIX %+ _OPENSSL_malloc_init %xdefine _OPENSSL_memdup _ %+ BORINGSSL_PREFIX %+ _OPENSSL_memdup %xdefine _OPENSSL_no_config _ %+ BORINGSSL_PREFIX %+ _OPENSSL_no_config +%xdefine _openssl_poly1305_neon2_addmulmod _ %+ BORINGSSL_PREFIX %+ _openssl_poly1305_neon2_addmulmod +%xdefine _openssl_poly1305_neon2_blocks _ %+ BORINGSSL_PREFIX %+ _openssl_poly1305_neon2_blocks %xdefine _OPENSSL_posix_to_tm _ %+ BORINGSSL_PREFIX %+ _OPENSSL_posix_to_tm %xdefine _OPENSSL_realloc _ %+ BORINGSSL_PREFIX %+ _OPENSSL_realloc %xdefine _OPENSSL_secure_clear_free _ %+ BORINGSSL_PREFIX %+ _OPENSSL_secure_clear_free @@ -2575,6 +2585,7 @@ %xdefine _sha1_block_data_order_avx _ %+ BORINGSSL_PREFIX %+ _sha1_block_data_order_avx %xdefine _sha1_block_data_order_avx2 _ %+ BORINGSSL_PREFIX %+ _sha1_block_data_order_avx2 %xdefine _sha1_block_data_order_hw _ %+ BORINGSSL_PREFIX %+ _sha1_block_data_order_hw +%xdefine _sha1_block_data_order_neon _ %+ BORINGSSL_PREFIX %+ _sha1_block_data_order_neon %xdefine _sha1_block_data_order_nohw _ %+ BORINGSSL_PREFIX %+ _sha1_block_data_order_nohw %xdefine _sha1_block_data_order_ssse3 _ %+ BORINGSSL_PREFIX %+ _sha1_block_data_order_ssse3 %xdefine _SHA1_Final _ %+ BORINGSSL_PREFIX %+ _SHA1_Final @@ -2591,6 +2602,7 @@ %xdefine _sha256_avx_capable _ %+ BORINGSSL_PREFIX %+ _sha256_avx_capable %xdefine _sha256_block_data_order_avx _ %+ BORINGSSL_PREFIX %+ _sha256_block_data_order_avx %xdefine _sha256_block_data_order_hw _ %+ BORINGSSL_PREFIX %+ _sha256_block_data_order_hw +%xdefine _sha256_block_data_order_neon _ %+ BORINGSSL_PREFIX %+ _sha256_block_data_order_neon %xdefine _sha256_block_data_order_nohw _ %+ BORINGSSL_PREFIX %+ _sha256_block_data_order_nohw %xdefine _sha256_block_data_order_ssse3 _ %+ BORINGSSL_PREFIX %+ _sha256_block_data_order_ssse3 %xdefine _SHA256_Final _ %+ BORINGSSL_PREFIX %+ _SHA256_Final @@ -2612,6 +2624,7 @@ %xdefine _sha512_avx_capable _ %+ BORINGSSL_PREFIX %+ _sha512_avx_capable %xdefine _sha512_block_data_order_avx _ %+ BORINGSSL_PREFIX %+ _sha512_block_data_order_avx %xdefine _sha512_block_data_order_hw _ %+ BORINGSSL_PREFIX %+ _sha512_block_data_order_hw +%xdefine _sha512_block_data_order_neon _ %+ BORINGSSL_PREFIX %+ _sha512_block_data_order_neon %xdefine _sha512_block_data_order_nohw _ %+ BORINGSSL_PREFIX %+ _sha512_block_data_order_nohw %xdefine _SHA512_Final _ %+ BORINGSSL_PREFIX %+ _SHA512_Final %xdefine _sha512_hw_capable _ %+ BORINGSSL_PREFIX %+ _sha512_hw_capable @@ -2952,9 +2965,11 @@ %xdefine _vpaes_capable _ %+ BORINGSSL_PREFIX %+ _vpaes_capable %xdefine _vpaes_cbc_encrypt _ %+ BORINGSSL_PREFIX %+ _vpaes_cbc_encrypt %xdefine _vpaes_ctr32_encrypt_blocks _ %+ BORINGSSL_PREFIX %+ _vpaes_ctr32_encrypt_blocks +%xdefine _vpaes_ctr32_encrypt_blocks_with_bsaes _ %+ BORINGSSL_PREFIX %+ _vpaes_ctr32_encrypt_blocks_with_bsaes %xdefine _vpaes_decrypt _ %+ BORINGSSL_PREFIX %+ _vpaes_decrypt %xdefine _vpaes_decrypt_key_to_bsaes _ %+ BORINGSSL_PREFIX %+ _vpaes_decrypt_key_to_bsaes %xdefine _vpaes_encrypt _ %+ BORINGSSL_PREFIX %+ _vpaes_encrypt +%xdefine _vpaes_encrypt_key_to_bsaes _ %+ BORINGSSL_PREFIX %+ _vpaes_encrypt_key_to_bsaes %xdefine _vpaes_set_decrypt_key _ %+ BORINGSSL_PREFIX %+ _vpaes_set_decrypt_key %xdefine _vpaes_set_encrypt_key _ %+ BORINGSSL_PREFIX %+ _vpaes_set_encrypt_key %xdefine _X25519 _ %+ BORINGSSL_PREFIX %+ _X25519 @@ -2971,6 +2986,7 @@ %xdefine _x25519_ge_sub _ %+ BORINGSSL_PREFIX %+ _x25519_ge_sub %xdefine _x25519_ge_tobytes _ %+ BORINGSSL_PREFIX %+ _x25519_ge_tobytes %xdefine _X25519_keypair _ %+ BORINGSSL_PREFIX %+ _X25519_keypair +%xdefine _x25519_NEON _ %+ BORINGSSL_PREFIX %+ _x25519_NEON %xdefine _x25519_pkey_meth _ %+ BORINGSSL_PREFIX %+ _x25519_pkey_meth %xdefine _X25519_public_from_private _ %+ BORINGSSL_PREFIX %+ _X25519_public_from_private %xdefine _x25519_sc_reduce _ %+ BORINGSSL_PREFIX %+ _x25519_sc_reduce @@ -4068,6 +4084,8 @@ %xdefine bn_mul4x_mont_capable BORINGSSL_PREFIX %+ _bn_mul4x_mont_capable %xdefine bn_mul4x_mont_gather5 BORINGSSL_PREFIX %+ _bn_mul4x_mont_gather5 %xdefine bn_mul4x_mont_gather5_capable BORINGSSL_PREFIX %+ _bn_mul4x_mont_gather5_capable +%xdefine bn_mul8x_mont_neon BORINGSSL_PREFIX %+ _bn_mul8x_mont_neon +%xdefine bn_mul8x_mont_neon_capable BORINGSSL_PREFIX %+ _bn_mul8x_mont_neon_capable %xdefine bn_mulx_adx_capable BORINGSSL_PREFIX %+ _bn_mulx_adx_capable %xdefine bn_mulx4x_mont BORINGSSL_PREFIX %+ _bn_mulx4x_mont %xdefine bn_mulx4x_mont_capable BORINGSSL_PREFIX %+ _bn_mulx4x_mont_capable @@ -4163,6 +4181,7 @@ %xdefine boringssl_self_test_slhdsa BORINGSSL_PREFIX %+ _boringssl_self_test_slhdsa %xdefine bsaes_capable BORINGSSL_PREFIX %+ _bsaes_capable %xdefine bsaes_cbc_encrypt BORINGSSL_PREFIX %+ _bsaes_cbc_encrypt +%xdefine bsaes_ctr32_encrypt_blocks BORINGSSL_PREFIX %+ _bsaes_ctr32_encrypt_blocks %xdefine BUF_MEM_append BORINGSSL_PREFIX %+ _BUF_MEM_append %xdefine BUF_MEM_free BORINGSSL_PREFIX %+ _BUF_MEM_free %xdefine BUF_MEM_grow BORINGSSL_PREFIX %+ _BUF_MEM_grow @@ -4359,6 +4378,7 @@ %xdefine CRYPTO_get_thread_local BORINGSSL_PREFIX %+ _CRYPTO_get_thread_local %xdefine CRYPTO_ghash_init BORINGSSL_PREFIX %+ _CRYPTO_ghash_init %xdefine CRYPTO_has_asm BORINGSSL_PREFIX %+ _CRYPTO_has_asm +%xdefine CRYPTO_has_broken_NEON BORINGSSL_PREFIX %+ _CRYPTO_has_broken_NEON %xdefine CRYPTO_hchacha20 BORINGSSL_PREFIX %+ _CRYPTO_hchacha20 %xdefine CRYPTO_init_sysrand BORINGSSL_PREFIX %+ _CRYPTO_init_sysrand %xdefine CRYPTO_is_ADX_capable BORINGSSL_PREFIX %+ _CRYPTO_is_ADX_capable @@ -4395,13 +4415,17 @@ %xdefine CRYPTO_MUTEX_lock_write BORINGSSL_PREFIX %+ _CRYPTO_MUTEX_lock_write %xdefine CRYPTO_MUTEX_unlock_read BORINGSSL_PREFIX %+ _CRYPTO_MUTEX_unlock_read %xdefine CRYPTO_MUTEX_unlock_write BORINGSSL_PREFIX %+ _CRYPTO_MUTEX_unlock_write +%xdefine CRYPTO_needs_hwcap2_workaround BORINGSSL_PREFIX %+ _CRYPTO_needs_hwcap2_workaround %xdefine CRYPTO_new_ex_data BORINGSSL_PREFIX %+ _CRYPTO_new_ex_data %xdefine CRYPTO_num_locks BORINGSSL_PREFIX %+ _CRYPTO_num_locks %xdefine CRYPTO_ofb128_encrypt BORINGSSL_PREFIX %+ _CRYPTO_ofb128_encrypt %xdefine CRYPTO_once BORINGSSL_PREFIX %+ _CRYPTO_once %xdefine CRYPTO_poly1305_finish BORINGSSL_PREFIX %+ _CRYPTO_poly1305_finish +%xdefine CRYPTO_poly1305_finish_neon BORINGSSL_PREFIX %+ _CRYPTO_poly1305_finish_neon %xdefine CRYPTO_poly1305_init BORINGSSL_PREFIX %+ _CRYPTO_poly1305_init +%xdefine CRYPTO_poly1305_init_neon BORINGSSL_PREFIX %+ _CRYPTO_poly1305_init_neon %xdefine CRYPTO_poly1305_update BORINGSSL_PREFIX %+ _CRYPTO_poly1305_update +%xdefine CRYPTO_poly1305_update_neon BORINGSSL_PREFIX %+ _CRYPTO_poly1305_update_neon %xdefine CRYPTO_pre_sandbox_init BORINGSSL_PREFIX %+ _CRYPTO_pre_sandbox_init %xdefine CRYPTO_rdrand BORINGSSL_PREFIX %+ _CRYPTO_rdrand %xdefine CRYPTO_rdrand_multiple8_buf BORINGSSL_PREFIX %+ _CRYPTO_rdrand_multiple8_buf @@ -5668,6 +5692,8 @@ %xdefine OPENSSL_malloc_init BORINGSSL_PREFIX %+ _OPENSSL_malloc_init %xdefine OPENSSL_memdup BORINGSSL_PREFIX %+ _OPENSSL_memdup %xdefine OPENSSL_no_config BORINGSSL_PREFIX %+ _OPENSSL_no_config +%xdefine openssl_poly1305_neon2_addmulmod BORINGSSL_PREFIX %+ _openssl_poly1305_neon2_addmulmod +%xdefine openssl_poly1305_neon2_blocks BORINGSSL_PREFIX %+ _openssl_poly1305_neon2_blocks %xdefine OPENSSL_posix_to_tm BORINGSSL_PREFIX %+ _OPENSSL_posix_to_tm %xdefine OPENSSL_realloc BORINGSSL_PREFIX %+ _OPENSSL_realloc %xdefine OPENSSL_secure_clear_free BORINGSSL_PREFIX %+ _OPENSSL_secure_clear_free @@ -6006,6 +6032,7 @@ %xdefine sha1_block_data_order_avx BORINGSSL_PREFIX %+ _sha1_block_data_order_avx %xdefine sha1_block_data_order_avx2 BORINGSSL_PREFIX %+ _sha1_block_data_order_avx2 %xdefine sha1_block_data_order_hw BORINGSSL_PREFIX %+ _sha1_block_data_order_hw +%xdefine sha1_block_data_order_neon BORINGSSL_PREFIX %+ _sha1_block_data_order_neon %xdefine sha1_block_data_order_nohw BORINGSSL_PREFIX %+ _sha1_block_data_order_nohw %xdefine sha1_block_data_order_ssse3 BORINGSSL_PREFIX %+ _sha1_block_data_order_ssse3 %xdefine SHA1_Final BORINGSSL_PREFIX %+ _SHA1_Final @@ -6022,6 +6049,7 @@ %xdefine sha256_avx_capable BORINGSSL_PREFIX %+ _sha256_avx_capable %xdefine sha256_block_data_order_avx BORINGSSL_PREFIX %+ _sha256_block_data_order_avx %xdefine sha256_block_data_order_hw BORINGSSL_PREFIX %+ _sha256_block_data_order_hw +%xdefine sha256_block_data_order_neon BORINGSSL_PREFIX %+ _sha256_block_data_order_neon %xdefine sha256_block_data_order_nohw BORINGSSL_PREFIX %+ _sha256_block_data_order_nohw %xdefine sha256_block_data_order_ssse3 BORINGSSL_PREFIX %+ _sha256_block_data_order_ssse3 %xdefine SHA256_Final BORINGSSL_PREFIX %+ _SHA256_Final @@ -6043,6 +6071,7 @@ %xdefine sha512_avx_capable BORINGSSL_PREFIX %+ _sha512_avx_capable %xdefine sha512_block_data_order_avx BORINGSSL_PREFIX %+ _sha512_block_data_order_avx %xdefine sha512_block_data_order_hw BORINGSSL_PREFIX %+ _sha512_block_data_order_hw +%xdefine sha512_block_data_order_neon BORINGSSL_PREFIX %+ _sha512_block_data_order_neon %xdefine sha512_block_data_order_nohw BORINGSSL_PREFIX %+ _sha512_block_data_order_nohw %xdefine SHA512_Final BORINGSSL_PREFIX %+ _SHA512_Final %xdefine sha512_hw_capable BORINGSSL_PREFIX %+ _sha512_hw_capable @@ -6383,9 +6412,11 @@ %xdefine vpaes_capable BORINGSSL_PREFIX %+ _vpaes_capable %xdefine vpaes_cbc_encrypt BORINGSSL_PREFIX %+ _vpaes_cbc_encrypt %xdefine vpaes_ctr32_encrypt_blocks BORINGSSL_PREFIX %+ _vpaes_ctr32_encrypt_blocks +%xdefine vpaes_ctr32_encrypt_blocks_with_bsaes BORINGSSL_PREFIX %+ _vpaes_ctr32_encrypt_blocks_with_bsaes %xdefine vpaes_decrypt BORINGSSL_PREFIX %+ _vpaes_decrypt %xdefine vpaes_decrypt_key_to_bsaes BORINGSSL_PREFIX %+ _vpaes_decrypt_key_to_bsaes %xdefine vpaes_encrypt BORINGSSL_PREFIX %+ _vpaes_encrypt +%xdefine vpaes_encrypt_key_to_bsaes BORINGSSL_PREFIX %+ _vpaes_encrypt_key_to_bsaes %xdefine vpaes_set_decrypt_key BORINGSSL_PREFIX %+ _vpaes_set_decrypt_key %xdefine vpaes_set_encrypt_key BORINGSSL_PREFIX %+ _vpaes_set_encrypt_key %xdefine X25519 BORINGSSL_PREFIX %+ _X25519 @@ -6402,6 +6433,7 @@ %xdefine x25519_ge_sub BORINGSSL_PREFIX %+ _x25519_ge_sub %xdefine x25519_ge_tobytes BORINGSSL_PREFIX %+ _x25519_ge_tobytes %xdefine X25519_keypair BORINGSSL_PREFIX %+ _X25519_keypair +%xdefine x25519_NEON BORINGSSL_PREFIX %+ _x25519_NEON %xdefine x25519_pkey_meth BORINGSSL_PREFIX %+ _x25519_pkey_meth %xdefine X25519_public_from_private BORINGSSL_PREFIX %+ _X25519_public_from_private %xdefine x25519_sc_reduce BORINGSSL_PREFIX %+ _x25519_sc_reduce diff --git a/Sources/Crypto/CMakeLists.txt b/Sources/Crypto/CMakeLists.txt index c613f989c..1b560e783 100644 --- a/Sources/Crypto/CMakeLists.txt +++ b/Sources/Crypto/CMakeLists.txt @@ -36,6 +36,7 @@ add_library(Crypto "ASN1/PKCS8PrivateKey.swift" "ASN1/SEC1PrivateKey.swift" "ASN1/SubjectPublicKeyInfo.swift" + "CryptoError_boring.swift" "CryptoKitErrors.swift" "Digests/BoringSSL/Digest_boring.swift" "Digests/Digest.swift" diff --git a/Sources/Crypto/CryptoError_boring.swift b/Sources/Crypto/CryptoError_boring.swift new file mode 100644 index 000000000..685aeb769 --- /dev/null +++ b/Sources/Crypto/CryptoError_boring.swift @@ -0,0 +1,18 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2019-2025 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +@available(iOS 13.0, macOS 10.15, watchOS 6.0, tvOS 13.0, *) +public typealias CryptoError = CryptoKitError +@available(iOS 14, macOS 11, tvOS 14, watchOS 7, *) +public typealias CryptoASN1Error = CryptoKitASN1Error diff --git a/Sources/Crypto/Keys/EC/BoringSSL/NISTCurvesKeys_boring.swift b/Sources/Crypto/Keys/EC/BoringSSL/NISTCurvesKeys_boring.swift index ce159e391..4130b2b38 100644 --- a/Sources/Crypto/Keys/EC/BoringSSL/NISTCurvesKeys_boring.swift +++ b/Sources/Crypto/Keys/EC/BoringSSL/NISTCurvesKeys_boring.swift @@ -40,26 +40,20 @@ extension OpenSSLSupportedNISTCurve { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension P256: OpenSSLSupportedNISTCurve { - @inlinable - static var group: BoringSSLEllipticCurveGroup { - try! BoringSSLEllipticCurveGroup(.p256) - } + @usableFromInline + static let group = try! BoringSSLEllipticCurveGroup(.p256) } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension P384: OpenSSLSupportedNISTCurve { - @inlinable - static var group: BoringSSLEllipticCurveGroup { - try! BoringSSLEllipticCurveGroup(.p384) - } + @usableFromInline + static let group = try! BoringSSLEllipticCurveGroup(.p384) } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension P521: OpenSSLSupportedNISTCurve { - @inlinable - static var group: BoringSSLEllipticCurveGroup { - try! BoringSSLEllipticCurveGroup(.p521) - } + @usableFromInline + static let group = try! BoringSSLEllipticCurveGroup(.p521) } @usableFromInline diff --git a/Sources/CryptoBoringWrapper/EC/EllipticCurvePoint.swift b/Sources/CryptoBoringWrapper/EC/EllipticCurvePoint.swift index 266886237..b2c813834 100644 --- a/Sources/CryptoBoringWrapper/EC/EllipticCurvePoint.swift +++ b/Sources/CryptoBoringWrapper/EC/EllipticCurvePoint.swift @@ -69,6 +69,10 @@ package struct EllipticCurvePoint: @unchecked Sendable { try self.multiply(by: rhs, on: group, context: context) } + // This enhancement can only be present on 6.1 or later because of the + // absence of https://github.com/swiftlang/swift/pull/76186 in older + // compilers. + #if compiler(>=6.1) @usableFromInline package consuming func multiplying( by rhs: ArbitraryPrecisionInteger, @@ -78,6 +82,18 @@ package struct EllipticCurvePoint: @unchecked Sendable { try self.multiply(by: rhs, on: group, context: context) return self } + #else + @usableFromInline + package func multiplying( + by rhs: ArbitraryPrecisionInteger, + on group: BoringSSLEllipticCurveGroup, + context: FiniteFieldArithmeticContext? = nil + ) throws -> EllipticCurvePoint { + var `self` = self + try self.multiply(by: rhs, on: group, context: context) + return self + } + #endif @usableFromInline package static func multiplying( @@ -110,6 +126,10 @@ package struct EllipticCurvePoint: @unchecked Sendable { try self.add(rhs, on: group, context: context) } + // This enhancement can only be present on 6.1 or later because of the + // absence of https://github.com/swiftlang/swift/pull/76186 in older + // compilers. + #if compiler(>=6.1) @usableFromInline package consuming func adding( _ rhs: consuming EllipticCurvePoint, @@ -119,7 +139,23 @@ package struct EllipticCurvePoint: @unchecked Sendable { try self.add(rhs, on: group, context: context) return self } + #else + @usableFromInline + package func adding( + _ rhs: consuming EllipticCurvePoint, + on group: BoringSSLEllipticCurveGroup, + context: FiniteFieldArithmeticContext? = nil + ) throws -> EllipticCurvePoint { + var `self` = self + try self.add(rhs, on: group, context: context) + return self + } + #endif + // This enhancement can only be present on 6.1 or later because of the + // absence of https://github.com/swiftlang/swift/pull/76186 in older + // compilers. + #if compiler(>=6.1) @usableFromInline package static func adding( _ lhs: consuming EllipticCurvePoint, @@ -130,6 +166,19 @@ package struct EllipticCurvePoint: @unchecked Sendable { try lhs.add(rhs, on: group, context: context) return lhs } + #else + @usableFromInline + package static func adding( + _ lhs: EllipticCurvePoint, + _ rhs: EllipticCurvePoint, + on group: BoringSSLEllipticCurveGroup, + context: FiniteFieldArithmeticContext? = nil + ) throws -> EllipticCurvePoint { + var lhs = lhs + try lhs.add(rhs, on: group, context: context) + return lhs + } + #endif @usableFromInline package mutating func invert( @@ -150,6 +199,10 @@ package struct EllipticCurvePoint: @unchecked Sendable { try self.invert(on: group, context: context) } + // This enhancement can only be present on 6.1 or later because of the + // absence of https://github.com/swiftlang/swift/pull/76186 in older + // compilers. + #if compiler(>=6.1) @usableFromInline package consuming func inverting( on group: BoringSSLEllipticCurveGroup, @@ -158,7 +211,22 @@ package struct EllipticCurvePoint: @unchecked Sendable { try self.invert(on: group, context: context) return self } + #else + @usableFromInline + package func inverting( + on group: BoringSSLEllipticCurveGroup, + context: FiniteFieldArithmeticContext? = nil + ) throws -> EllipticCurvePoint { + var `self` = self + try self.invert(on: group, context: context) + return self + } + #endif + // This enhancement can only be present on 6.1 or later because of the + // absence of https://github.com/swiftlang/swift/pull/76186 in older + // compilers. + #if compiler(>=6.1) @usableFromInline package static func inverting( _ point: consuming EllipticCurvePoint, @@ -168,6 +236,18 @@ package struct EllipticCurvePoint: @unchecked Sendable { try point.invert(on: group, context: context) return point } + #else + @usableFromInline + package static func inverting( + _ point: EllipticCurvePoint, + on group: BoringSSLEllipticCurveGroup, + context: FiniteFieldArithmeticContext? = nil + ) throws -> EllipticCurvePoint { + var point = point + try point.invert(on: group, context: context) + return point + } + #endif @usableFromInline package mutating func subtract( @@ -190,6 +270,10 @@ package struct EllipticCurvePoint: @unchecked Sendable { try self.subtract(rhs, on: group, context: context) } + // This enhancement can only be present on 6.1 or later because of the + // absence of https://github.com/swiftlang/swift/pull/76186 in older + // compilers. + #if compiler(>=6.1) @usableFromInline package consuming func subtracting( _ rhs: consuming EllipticCurvePoint, @@ -199,7 +283,23 @@ package struct EllipticCurvePoint: @unchecked Sendable { try self.subtract(rhs, on: group, context: context) return self } + #else + @usableFromInline + package func subtracting( + _ rhs: EllipticCurvePoint, + on group: BoringSSLEllipticCurveGroup, + context: FiniteFieldArithmeticContext? = nil + ) throws -> EllipticCurvePoint { + var `self` = self + try self.subtract(rhs, on: group, context: context) + return self + } + #endif + // This enhancement can only be present on 6.1 or later because of the + // absence of https://github.com/swiftlang/swift/pull/76186 in older + // compilers. + #if compiler(>=6.1) @usableFromInline package static func subtracting( _ rhs: consuming EllipticCurvePoint, @@ -210,6 +310,19 @@ package struct EllipticCurvePoint: @unchecked Sendable { try lhs.subtract(rhs, on: group, context: context) return lhs } + #else + @usableFromInline + package static func subtracting( + _ rhs: EllipticCurvePoint, + from lhs: EllipticCurvePoint, + on group: BoringSSLEllipticCurveGroup, + context: FiniteFieldArithmeticContext? = nil + ) throws -> EllipticCurvePoint { + var lhs = lhs + try lhs.subtract(rhs, on: group, context: context) + return lhs + } + #endif @usableFromInline package init( diff --git a/Sources/_CryptoExtras/AES/AES_CBC.swift b/Sources/_CryptoExtras/AES/AES_CBC.swift index 8041387e2..f94910bf3 100644 --- a/Sources/_CryptoExtras/AES/AES_CBC.swift +++ b/Sources/_CryptoExtras/AES/AES_CBC.swift @@ -151,8 +151,9 @@ extension AES { extension AES._CBC { /// An initialization vector. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - public struct IV: Sendable { + public struct IV: Sendable, Sequence { // AES CBC uses a 128-bit IV. + @usableFromInline var ivBytes: ( UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8 @@ -197,6 +198,13 @@ extension AES._CBC { bytesPtr.copyBytes(from: ivBytes) } } + + @inlinable + public func makeIterator() -> some IteratorProtocol { + withUnsafeBytes(of: ivBytes) { unsafeRawBufferPointer in + Array(unsafeRawBufferPointer).makeIterator() + } + } } } diff --git a/Sources/_CryptoExtras/AES/CMAC.swift b/Sources/_CryptoExtras/AES/CMAC.swift new file mode 100644 index 000000000..c96293345 --- /dev/null +++ b/Sources/_CryptoExtras/AES/CMAC.swift @@ -0,0 +1,214 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2025 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +@_implementationOnly import CCryptoBoringSSL +import Crypto + +#if canImport(FoundationEssentials) +import FoundationEssentials +#else +import Foundation +#endif + +@available(iOS 13.0, macOS 10.15, watchOS 6.0, tvOS 13.0, *) +extension AES { + /// A cipher-based message authentication code. + /// + /// CMAC uses AES to implement a MAC. CMAC is useful in contexts where access to + /// a hash function is not guaranteed, but a block cipher will be available. + public struct CMAC: @unchecked Sendable { + // Unchecked sendable because this is CoW. + fileprivate var backing: Backing + + /// Creates a message authentication code generator. + /// + /// Defaults the output size to 128 bits. + /// + /// - Parameters: + /// - key: The symmetric key used to secure the computation. + public init(key: SymmetricKey) throws { + try self.init(key: key, outputSize: 16) + } + + /// Creates a message authentication code generator. + /// + /// - Parameters: + /// - key: The symmetric key used to secure the computation. + /// - outputSize: The number of bytes of MAC to generate. Must be in the range 0 to 16 inclusive. + public init(key: SymmetricKey, outputSize: Int) throws { + guard [128, 192, 256].contains(key.bitCount) else { + throw CryptoError.incorrectKeySize + } + guard (0...16).contains(outputSize) else { + throw CryptoKitError.incorrectParameterSize + } + + self.backing = Backing(key: key, outputSize: outputSize) + } + + /// Adds data to be authenticated by MAC function. This can be called one or more times to append additional data. + /// + /// - Parameters: + /// - bufferPointer: The data to be authenticated. + public mutating func update(bufferPointer: UnsafeRawBufferPointer) { + self.cowIfNeeded() + self.backing.update(bufferPointer) + } + + // This enhancement can only be present on 6.1 or later because of the + // absence of https://github.com/swiftlang/swift/pull/76186 in older + // compilers. + #if compiler(>=6.1) + /// Finalizes the message authentication computation and returns the + /// computed code. + /// + /// - Returns: The message authentication code. + public consuming func finalize() -> AES.CMAC.MAC { + // The combination of "consuming" and "cowifneeded" should + // produce an environment where, if users may choose to + // keep using the MAC, they can, but if they aren't we'll + // avoid an unnecessary CoW. + self.cowIfNeeded() + return self.backing.finalize() + } + #else + /// Finalizes the message authentication computation and returns the + /// computed code. + /// + /// - Returns: The message authentication code. + public func finalize() -> AES.CMAC.MAC { + var `self` = self + return self.backing.finalize() + } + #endif + + /// Updates the MAC with data. + /// + /// - Parameter data: The data to update the MAC + public mutating func update(data: D) { + for memoryRegion in data.regions { + memoryRegion.withUnsafeBytes { bp in + self.update(bufferPointer: bp) + } + } + } + + private mutating func cowIfNeeded() { + if !isKnownUniquelyReferenced(&self.backing) { + self.backing = Backing(copying: self.backing) + } + } + } +} + +@available(iOS 13.0, macOS 10.15, watchOS 6.0, tvOS 13.0, *) +extension AES.CMAC { + /// A cipher-based message authentication code. + public struct MAC: MessageAuthenticationCode { + fileprivate let underlyingData: Data + + init(underlyingData: Data) { + self.underlyingData = underlyingData + } + + /// The number of bytes in the message authentication code. + public var byteCount: Int { + self.underlyingData.count + } + + /// Invokes the given closure with a buffer pointer covering the raw bytes + /// of the code. + /// + /// - Parameters: + /// - body: A closure that takes a raw buffer pointer to the bytes of the + /// code. + public func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> R) rethrows -> R { + try self.underlyingData.withUnsafeBytes(body) + } + } +} + +@available(iOS 13.0, macOS 10.15, watchOS 6.0, tvOS 13.0, *) +extension AES.CMAC { + fileprivate final class Backing { + private let key: SymmetricKey + private let context: OpaquePointer + private let outputSize: Int + + init(key: SymmetricKey, outputSize: Int) { + self.key = key + self.context = CCryptoBoringSSL_CMAC_CTX_new() + self.outputSize = outputSize + + let rc = self.key.withUnsafeBytes { keyPtr in + CCryptoBoringSSL_CMAC_Init( + self.context, + keyPtr.baseAddress, + keyPtr.count, + key.aesEVP, + nil + ) + } + precondition(rc == 1) + } + + init(copying other: Backing) { + self.key = other.key + self.context = CCryptoBoringSSL_CMAC_CTX_new() + self.outputSize = other.outputSize + let rc = CCryptoBoringSSL_CMAC_CTX_copy(self.context, other.context) + precondition(rc == 1) + + // Ensure we don't lose `other` at this time. + withExtendedLifetime(other) {} + } + + deinit { + CCryptoBoringSSL_CMAC_CTX_free(self.context) + } + + func update(_ bytes: UnsafeRawBufferPointer) { + let rc = CCryptoBoringSSL_CMAC_Update(self.context, bytes.baseAddress, bytes.count) + precondition(rc == 1) + } + + func finalize() -> AES.CMAC.MAC { + let bytes = withUnsafeTemporaryAllocation(byteCount: 16, alignment: 1) { bytes in + precondition(bytes.count >= 16) + var count = 16 + let rc = CCryptoBoringSSL_CMAC_Final(self.context, bytes.baseAddress, &count) + precondition(count == 16) + precondition(rc == 1) + + return Data(UnsafeRawBufferPointer(rebasing: bytes.prefix(self.outputSize))) + } + return AES.CMAC.MAC(underlyingData: bytes) + } + } +} + +@available(iOS 13.0, macOS 10.15, watchOS 6.0, tvOS 13.0, *) +extension SymmetricKey { + fileprivate var aesEVP: OpaquePointer { + switch self.bitCount { + case 128: + CCryptoBoringSSL_EVP_aes_128_cbc() + case 192: + CCryptoBoringSSL_EVP_aes_192_cbc() + case 256: + CCryptoBoringSSL_EVP_aes_256_cbc() + default: + fatalError("Should be unreachable") + } + } +} diff --git a/Sources/_CryptoExtras/ARC/ARC+API.swift b/Sources/_CryptoExtras/ARC/ARC+API.swift index 4e159f32c..b40b8c1bf 100644 --- a/Sources/_CryptoExtras/ARC/ARC+API.swift +++ b/Sources/_CryptoExtras/ARC/ARC+API.swift @@ -18,8 +18,388 @@ import FoundationEssentials import Foundation #endif +// MARK: - P256 + ARC(P-256) +@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) +extension P256 { + /// Anonymous Rate-Limited Credentials (ARC). + /// + /// A specialization of keyed-verification anonymous credentials with support for rate limiting. + /// + /// - Seealso: [IETF Internet Draft: draft-yun-cfrg-arc-00](https://datatracker.ietf.org/doc/draft-yun-cfrg-arc). + public enum _ARCV1 { + internal typealias H2G = HashToCurveImpl + internal typealias Ciphersuite = ARC.Ciphersuite + fileprivate typealias Server = ARC.Server + + internal static let ciphersuite = Ciphersuite(H2G.self) + } +} + +@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) +extension P256._ARCV1 { + /// The server secrets used to issue and verify credentials. + public struct PrivateKey: Sendable { + fileprivate var backing: ARC.Server + + /// Creates a random private key for ARC(P-256). + public init() { + self.backing = ARC.Server(ciphersuite: P256._ARCV1.ciphersuite) + } + + // The spec does not define a serialization of the private key since, unlike the public key, it is not an + // interop concern. + // + // This initializer expects a concatenation of the binary representations of the private scalars: + // + // struct { + // uint8 x0[Ne]; + // uint8 x1[Ne]; + // uint8 x2[Ne]; + // uint8 x0Blinding[Ne]; + // } ServerPrivateKey; + // + public init(rawRepresentation: D) throws { + guard rawRepresentation.count == 4 * P256.orderByteCount else { + throw ARC.Errors.incorrectPrivateKeyDataSize + } + + var bytes = Data(rawRepresentation)[...] + let x0 = try H2G.G.Scalar(bytes: bytes[.. + + fileprivate init(backing: ARC.ServerPublicKey) { + self.backing = backing + } + + fileprivate static var serializedByteCount: Int { 3 * P256.compressedx962PointByteCount } + + // The spec defines this serialization of the public key: + // + // struct { + // uint8 X0[Ne]; + // uint8 X1[Ne]; + // uint8 X2[Ne]; + // } ServerPublicKey; + // + public init(rawRepresentation: D) throws { + guard rawRepresentation.count == Self.serializedByteCount else { throw ARC.Errors.incorrectPublicKeyDataSize } + + var bytes = Data(rawRepresentation)[...] + let X0 = try H2G.G.Element(oprfRepresentation: bytes[.. + + fileprivate init(backing: ARC.CredentialRequest) { + self.backing = backing + } + + public init(rawRepresentation: D) throws { + self.backing = try ARC.CredentialRequest.deserialize(requestData: rawRepresentation, ciphersuite: P256._ARCV1.ciphersuite) + } + + public var rawRepresentation: Data { + self.backing.serialize(ciphersuite: P256._ARCV1.ciphersuite) + } + } + + /// A credential request to be sent to the server, and associated client secrets. + /// + /// Users cannot create values of this type manually; they are created using the prepare method on the public key. + public struct Precredential: Sendable { + /// This backing type binds many things together, including the server commitments, client secrets, credential + /// request, and presentation limit. + internal var backing: ARC.Precredential + + /// The credential request to be sent to the server. + public var credentialRequest: CredentialRequest { + CredentialRequest(backing: self.backing.credentialRequest) + } + } + + /// A credential response, created by the server, to be sent to the client. + /// + /// Servers should not create values of this type manually; they should use the issue method on the private key. + /// + /// Clients should reconstruct values of this type from the serialized bytes sent by the server. + public struct CredentialResponse: Sendable { + var backing: ARC.CredentialResponse + + fileprivate init(backing: ARC.CredentialResponse) { + self.backing = backing + } + + public init(rawRepresentation: D) throws { + self.backing = try ARC.CredentialResponse.deserialize(responseData: rawRepresentation, ciphersuite: P256._ARCV1.ciphersuite) + } + + public var rawRepresentation: Data { + self.backing.serialize(ciphersuite: P256._ARCV1.ciphersuite) + } + } + + + /// A credential, created by the client using the response from the server. + /// + /// Users cannot create values of this type manually; they are created using the issue method on the public key. + public struct Credential: Sendable { + var backing: ARC.Credential + + fileprivate init(backing: ARC.Credential) { + self.backing = backing + } + } + + /// A presentation, created by the client from a credential, to be sent to the server to verify. + /// + /// Users cannot create values of this type manually; they are created using the present method on the credential. + public struct Presentation: Sendable { + internal var backing: ARC.Presentation + + fileprivate init(backing: ARC.Presentation) { + self.backing = backing + } + + public init(rawRepresentation: D) throws { + self.backing = try ARC.Presentation.deserialize(presentationData: rawRepresentation, ciphersuite: P256._ARCV1.ciphersuite) + } + + public var rawRepresentation: Data { + self.backing.serialize(ciphersuite: P256._ARCV1.ciphersuite) + } + + public var tag: Data { + self.backing.tag.compressedRepresentation + } + } +} + +@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) +extension P256._ARCV1.PublicKey { + internal func prepareCredentialRequest( + requestContext: D, + m1: P256._ARCV1.H2G.G.Scalar, + r1: P256._ARCV1.H2G.G.Scalar, + r2: P256._ARCV1.H2G.G.Scalar + ) throws -> P256._ARCV1.Precredential { + let precedential = try ARC.Precredential( + ciphersuite: P256._ARCV1.ciphersuite, + m1: m1, + requestContext: Data(requestContext), + r1: r1, + r2: r2, + serverPublicKey: self.backing + ) + return P256._ARCV1.Precredential(backing: precedential) + } + + /// Prepare a credential request for a given request context. + /// + /// - Parameters: + /// - requestContext: Request context, agreed with the server. + /// + /// - Returns: A precredential containing the client secrets, and request to be sent to the server. + public func prepareCredentialRequest( + requestContext: D + ) throws -> P256._ARCV1.Precredential { + try self.prepareCredentialRequest( + requestContext: requestContext, + m1: .random, + r1: .random, + r2: .random + ) + } +} + +@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) +extension P256._ARCV1.PrivateKey { + internal func issue( + _ credentialRequest: P256._ARCV1.CredentialRequest, + b: P256._ARCV1.H2G.G.Scalar + ) throws -> P256._ARCV1.CredentialResponse { + let response = try self.backing.respond(credentialRequest: credentialRequest.backing, b: b) + return P256._ARCV1.CredentialResponse(backing: response) + } + + /// Generate a credential response from a credential request. + public func issue(_ credentialRequest: P256._ARCV1.CredentialRequest) throws -> P256._ARCV1.CredentialResponse { + try self.issue(credentialRequest, b: .random) + } +} + +@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) +extension P256._ARCV1.PublicKey { + /// Create a credential from the issuer response. + public func finalize( + _ credentialResponse: P256._ARCV1.CredentialResponse, + for precredential: P256._ARCV1.Precredential + ) throws -> P256._ARCV1.Credential { + let credential = try precredential.backing.makeCredential(credentialResponse: credentialResponse.backing) + return P256._ARCV1.Credential(backing: credential) + } +} + +@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) +extension P256._ARCV1.Credential { + internal mutating func makePresentation( + context: D, + presentationLimit: Int, + fixedNonce: Int?, + a: P256._ARCV1.H2G.G.Scalar, + r: P256._ARCV1.H2G.G.Scalar, + z: P256._ARCV1.H2G.G.Scalar + ) throws -> (presentation: P256._ARCV1.Presentation, nonce: Int) { + let (presentation, nonce) = try self.backing.makePresentation( + presentationContext: Data(context), + presentationLimit: presentationLimit, + a: a, + r: r, + z: z, + optionalNonce: fixedNonce + ) + return (P256._ARCV1.Presentation(backing: presentation), nonce) + } + + /// Create a presentation to provide to a verifier. + /// + /// - Parameters: + /// - context: The presentation context agreed with the verifier. + /// - presentationLimit: The presentation limit to enforce. + /// + /// - Returns: A presentation of this credential. + /// + /// - Throws: An error if the presentation limit for this credential has been exceeded. + public mutating func makePresentation( + context: D, + presentationLimit: Int + ) throws -> (presentation: P256._ARCV1.Presentation, nonce: Int) { + try self.makePresentation( + context: context, + presentationLimit: presentationLimit, + fixedNonce: nil, + a: .random, + r: .random, + z: .random + ) + } +} + +@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) +extension P256._ARCV1.PrivateKey { + /// Verify a presentation is valid for a given attribute. + /// + /// Presentation verification includes checking that: + /// 1. The presentation is for the expected request context. + /// 2. The presentation is for the expected presentation context. + /// 3. The presentation nonce is appropriate for the presentation limit. + /// 4. The presentation proof is valid. + /// + /// - Parameters: + /// - presentation: The presentation to verify. + /// - requestContext: The expected request context encoded within the presentation. + /// - presentationContext: The expected presentation context encoded within the presentation. + /// - presentationLimit: The presentation limit to enforce. + /// - nonce: The expected nonce encoded within the presentation. + /// + /// - Returns: True if the presentation is valid, false otherwise. + public func verify( + _ presentation: P256._ARCV1.Presentation, + requestContext: D1, + presentationContext: D2, + presentationLimit: Int, + nonce: Int + ) throws -> Bool { + try self.backing.verify( + presentation: presentation.backing, + requestContext: Data(requestContext), + presentationContext: Data(presentationContext), + presentationLimit: presentationLimit, + nonce: nonce + ) + } +} + // MARK: - P384 + ARC(P-384) @available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) +@available(*, deprecated, message: "ARC(P-384) has been removed from the IETF draft; use ARC(P-256) instead.") extension P384 { /// Anonymous Rate-Limited Credentials (ARC). /// @@ -28,14 +408,15 @@ extension P384 { /// - Seealso: [IETF Internet Draft: draft-yun-cfrg-arc-00](https://datatracker.ietf.org/doc/draft-yun-cfrg-arc). public enum _ARCV1 { internal typealias H2G = HashToCurveImpl - fileprivate typealias Ciphersuite = ARC.Ciphersuite + internal typealias Ciphersuite = ARC.Ciphersuite fileprivate typealias Server = ARC.Server - fileprivate static var ciphersuite: Ciphersuite { Ciphersuite(H2G.self) } + internal static let ciphersuite = Ciphersuite(H2G.self) } } @available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) +@available(*, deprecated, message: "ARC(P-384) has been removed from the IETF draft; use ARC(P-256) instead.") extension P384._ARCV1 { /// The server secrets used to issue and verify credentials. public struct PrivateKey: Sendable { @@ -173,11 +554,11 @@ extension P384._ARCV1 { } public init(rawRepresentation: D) throws { - self.backing = try ARC.CredentialRequest.deserialize(requestData: rawRepresentation) + self.backing = try ARC.CredentialRequest.deserialize(requestData: rawRepresentation, ciphersuite: P384._ARCV1.ciphersuite) } public var rawRepresentation: Data { - self.backing.serialize() + self.backing.serialize(ciphersuite: P384._ARCV1.ciphersuite) } } @@ -208,11 +589,11 @@ extension P384._ARCV1 { } public init(rawRepresentation: D) throws { - self.backing = try ARC.CredentialResponse.deserialize(responseData: rawRepresentation) + self.backing = try ARC.CredentialResponse.deserialize(responseData: rawRepresentation, ciphersuite: P384._ARCV1.ciphersuite) } public var rawRepresentation: Data { - self.backing.serialize() + self.backing.serialize(ciphersuite: P384._ARCV1.ciphersuite) } } @@ -239,11 +620,11 @@ extension P384._ARCV1 { } public init(rawRepresentation: D) throws { - self.backing = try ARC.Presentation.deserialize(presentationData: rawRepresentation) + self.backing = try ARC.Presentation.deserialize(presentationData: rawRepresentation, ciphersuite: P384._ARCV1.ciphersuite) } public var rawRepresentation: Data { - self.backing.serialize() + self.backing.serialize(ciphersuite: P384._ARCV1.ciphersuite) } public var tag: Data { @@ -253,6 +634,7 @@ extension P384._ARCV1 { } @available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) +@available(*, deprecated, message: "ARC(P-384) has been removed from the IETF draft; use ARC(P-256) instead.") extension P384._ARCV1.PublicKey { internal func prepareCredentialRequest( requestContext: D, @@ -290,6 +672,7 @@ extension P384._ARCV1.PublicKey { } @available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) +@available(*, deprecated, message: "ARC(P-384) has been removed from the IETF draft; use ARC(P-256) instead.") extension P384._ARCV1.PrivateKey { internal func issue( _ credentialRequest: P384._ARCV1.CredentialRequest, @@ -306,6 +689,7 @@ extension P384._ARCV1.PrivateKey { } @available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) +@available(*, deprecated, message: "ARC(P-384) has been removed from the IETF draft; use ARC(P-256) instead.") extension P384._ARCV1.PublicKey { /// Create a credential from the issuer response. public func finalize( @@ -318,6 +702,7 @@ extension P384._ARCV1.PublicKey { } @available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) +@available(*, deprecated, message: "ARC(P-384) has been removed from the IETF draft; use ARC(P-256) instead.") extension P384._ARCV1.Credential { internal mutating func makePresentation( context: D, @@ -363,6 +748,7 @@ extension P384._ARCV1.Credential { } @available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) +@available(*, deprecated, message: "ARC(P-384) has been removed from the IETF draft; use ARC(P-256) instead.") extension P384._ARCV1.PrivateKey { /// Verify a presentation is valid for a given attribute. /// diff --git a/Sources/_CryptoExtras/ARC/ARC.swift b/Sources/_CryptoExtras/ARC/ARC.swift index 0e6f6dd39..087a13260 100644 --- a/Sources/_CryptoExtras/ARC/ARC.swift +++ b/Sources/_CryptoExtras/ARC/ARC.swift @@ -25,8 +25,6 @@ enum ARC {} @available(macOS 10.15, iOS 13.2, tvOS 13.2, watchOS 6.1, macCatalyst 13.2, visionOS 1.2, *) extension ARC { - static let domain = "ARCV1-P384" - enum Errors: Error { case invalidProof case invalidPresentationLimit @@ -44,26 +42,33 @@ extension ARC { /// Ciphersuites for Anonymous Rate-Limited Credentials (ARC) struct Ciphersuite { let suiteID: Int + let domain: String + let scalarByteCount: Int + let pointByteCount: Int init(_ h2g: H2G.Type) { switch h2g.self { case is HashToCurveImpl.Type: self.suiteID = 3 + self.domain = "ARCV1-P256" + self.scalarByteCount = P256.orderByteCount + self.pointByteCount = P256.compressedx962PointByteCount case is HashToCurveImpl.Type: self.suiteID = 4 - case is HashToCurveImpl.Type: - self.suiteID = 5 + self.domain = "ARCV1-P384" + self.scalarByteCount = P384.orderByteCount + self.pointByteCount = P384.compressedx962PointByteCount default: fatalError("Anonymous Rate-Limited Credentials (ARC) only support corecrypto H2G.") } } } - static func getGenerators(suite _: Ciphersuite) -> ( + static func getGenerators(suite: Ciphersuite) -> ( generatorG: H2G.G.Element, generatorH: H2G.G.Element ) { let generatorG = H2G.G.Element.generator - let generatorH = H2G.hashToGroup(generatorG.oprfRepresentation, domainSeparationString: Data(("HashToGroup-" + ARC.domain + "generatorH").utf8)) + let generatorH = H2G.hashToGroup(generatorG.oprfRepresentation, domainSeparationString: Data(("HashToGroup-" + suite.domain + "generatorH").utf8)) return (generatorG, generatorH) } } diff --git a/Sources/_CryptoExtras/ARC/ARCCredential.swift b/Sources/_CryptoExtras/ARC/ARCCredential.swift index 85dac1f85..915cbc3e3 100644 --- a/Sources/_CryptoExtras/ARC/ARCCredential.swift +++ b/Sources/_CryptoExtras/ARC/ARCCredential.swift @@ -34,7 +34,7 @@ extension ARC { init(credentialResponse: CredentialResponse, credentialRequest: CredentialRequest, clientSecrets: ClientSecrets, serverPublicKey: ServerPublicKey, ciphersuite: Ciphersuite, generatorG: Group.Element, generatorH: Group.Element) throws { // Verify credential response proof guard - try credentialResponse.verify(request: credentialRequest, serverPublicKey: serverPublicKey, generatorG: generatorG, generatorH: generatorH) + try credentialResponse.verify(request: credentialRequest, serverPublicKey: serverPublicKey, generatorG: generatorG, generatorH: generatorH, ciphersuite: ciphersuite) else { throw ARC.Errors.invalidProof } diff --git a/Sources/_CryptoExtras/ARC/ARCEncoding.swift b/Sources/_CryptoExtras/ARC/ARCEncoding.swift index 579787355..e445f6f2f 100644 --- a/Sources/_CryptoExtras/ARC/ARCEncoding.swift +++ b/Sources/_CryptoExtras/ARC/ARCEncoding.swift @@ -18,148 +18,155 @@ import Foundation #endif import Crypto -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -typealias ARCCurve = P384 @available(macOS 10.15, iOS 13.2, tvOS 13.2, watchOS 6.1, macCatalyst 13.2, visionOS 1.2, *) -typealias ARCH2G = HashToCurveImpl +typealias ARCP256 = HashToCurveImpl +@available(macOS 10.15, iOS 13.2, tvOS 13.2, watchOS 6.1, macCatalyst 13.2, visionOS 1.2, *) +typealias ARCP384 = HashToCurveImpl @available(macOS 10.15, iOS 13.2, tvOS 13.2, watchOS 6.1, macCatalyst 13.2, visionOS 1.2, *) -extension ARC.CredentialRequest where H2G == ARCH2G { - static let scalarCount = 5 - static let serializedByteCount = 2 * ARCCurve.compressedx962PointByteCount + Self.scalarCount * ARCCurve.orderByteCount - - func serialize() -> Data { - var result = Data(capacity: Self.serializedByteCount) - result.append(self.m1Enc.compressedRepresentation) - result.append(self.m2Enc.compressedRepresentation) - result.append(self.proof.serialize()) +extension ARC.CredentialRequest { + static func getScalarCount() -> Int { return 5 } + static func getSerializedByteCount(_ ciphersuite: ARC.Ciphersuite) -> Int { + return 2 * ciphersuite.pointByteCount + Self.getScalarCount() * ciphersuite.scalarByteCount + } + + func serialize(ciphersuite: ARC.Ciphersuite) -> Data { + var result = Data(capacity: Self.getSerializedByteCount(ciphersuite)) + result.append(self.m1Enc.oprfRepresentation) + result.append(self.m2Enc.oprfRepresentation) + result.append(self.proof.serialize(ciphersuite: ciphersuite)) return result } - static func deserialize(requestData: D) throws -> ARC.CredentialRequest { - guard requestData.count == Self.serializedByteCount else { + static func deserialize(requestData: D, ciphersuite: ARC.Ciphersuite) throws -> ARC.CredentialRequest { + guard requestData.count == Self.getSerializedByteCount(ciphersuite) else { throw ARC.Errors.incorrectRequestDataSize } var bytes = Data(requestData) - let m1Enc = try H2G.G.Element(oprfRepresentation: bytes.popFirst(ARCCurve.compressedx962PointByteCount)) - let m2Enc = try H2G.G.Element(oprfRepresentation: bytes.popFirst(ARCCurve.compressedx962PointByteCount)) - let proof = try Proof.deserialize(proofData: bytes, scalarCount: Self.scalarCount) + let m1Enc = try H2G.G.Element(oprfRepresentation: bytes.popFirst(ciphersuite.pointByteCount)) + let m2Enc = try H2G.G.Element(oprfRepresentation: bytes.popFirst(ciphersuite.pointByteCount)) + let proof = try Proof.deserialize(proofData: bytes, scalarCount: Self.getScalarCount(), ciphersuite: ciphersuite) return ARC.CredentialRequest(m1Enc: m1Enc, m2Enc: m2Enc, proof: proof) } } @available(macOS 10.15, iOS 13.2, tvOS 13.2, watchOS 6.1, macCatalyst 13.2, visionOS 1.2, *) -extension ARC.CredentialResponse where H2G == ARCH2G { - static let scalarCount = 8 - static let serializedByteCount = 6 * ARCCurve.compressedx962PointByteCount + Self.scalarCount * ARCCurve.orderByteCount +extension ARC.CredentialResponse { + static func getScalarCount() -> Int { return 8 } + static func getSerializedByteCount(_ ciphersuite: ARC.Ciphersuite) -> Int { + return 6 * ciphersuite.pointByteCount + Self.getScalarCount() * ciphersuite.scalarByteCount + } - func serialize() -> Data { - var result = Data(capacity: Self.serializedByteCount) + func serialize(ciphersuite: ARC.Ciphersuite) -> Data { + var result = Data(capacity: Self.getSerializedByteCount(ciphersuite)) - result.append(self.U.compressedRepresentation) - result.append(self.encUPrime.compressedRepresentation) - result.append(self.X0Aux.compressedRepresentation) - result.append(self.X1Aux.compressedRepresentation) - result.append(self.X2Aux.compressedRepresentation) - result.append(self.HAux.compressedRepresentation) - result.append(self.proof.serialize()) + result.append(self.U.oprfRepresentation) + result.append(self.encUPrime.oprfRepresentation) + result.append(self.X0Aux.oprfRepresentation) + result.append(self.X1Aux.oprfRepresentation) + result.append(self.X2Aux.oprfRepresentation) + result.append(self.HAux.oprfRepresentation) + result.append(self.proof.serialize(ciphersuite: ciphersuite)) return result } - static func deserialize(responseData: D) throws -> ARC.CredentialResponse { - guard responseData.count == self.serializedByteCount else { + static func deserialize(responseData: D, ciphersuite: ARC.Ciphersuite) throws -> ARC.CredentialResponse { + guard responseData.count == self.getSerializedByteCount(ciphersuite) else { throw ARC.Errors.incorrectResponseDataSize } var bytes = Data(responseData) - let U = try H2G.G.Element(oprfRepresentation: bytes.popFirst(ARCCurve.compressedx962PointByteCount)) - let encUPrime = try H2G.G.Element(oprfRepresentation: bytes.popFirst(ARCCurve.compressedx962PointByteCount)) - let X0Aux = try H2G.G.Element(oprfRepresentation: bytes.popFirst(ARCCurve.compressedx962PointByteCount)) - let X1Aux = try H2G.G.Element(oprfRepresentation: bytes.popFirst(ARCCurve.compressedx962PointByteCount)) - let X2Aux = try H2G.G.Element(oprfRepresentation: bytes.popFirst(ARCCurve.compressedx962PointByteCount)) - let HAux = try H2G.G.Element(oprfRepresentation: bytes.popFirst(ARCCurve.compressedx962PointByteCount)) + let U = try H2G.G.Element(oprfRepresentation: bytes.popFirst(ciphersuite.pointByteCount)) + let encUPrime = try H2G.G.Element(oprfRepresentation: bytes.popFirst(ciphersuite.pointByteCount)) + let X0Aux = try H2G.G.Element(oprfRepresentation: bytes.popFirst(ciphersuite.pointByteCount)) + let X1Aux = try H2G.G.Element(oprfRepresentation: bytes.popFirst(ciphersuite.pointByteCount)) + let X2Aux = try H2G.G.Element(oprfRepresentation: bytes.popFirst(ciphersuite.pointByteCount)) + let HAux = try H2G.G.Element(oprfRepresentation: bytes.popFirst(ciphersuite.pointByteCount)) - let proof = try Proof.deserialize(proofData: bytes, scalarCount: self.scalarCount) + let proof = try Proof.deserialize(proofData: bytes, scalarCount: Self.getScalarCount(), ciphersuite: ciphersuite) return ARC.CredentialResponse(U: U, encUPrime: encUPrime, X0Aux: X0Aux, X1Aux: X1Aux, X2Aux: X2Aux, HAux: HAux, proof: proof) } } @available(macOS 10.15, iOS 13.2, tvOS 13.2, watchOS 6.1, macCatalyst 13.2, visionOS 1.2, *) -extension ARC.Presentation where H2G == ARCH2G { - static let scalarCount = 5 - static let pointCount = 4 - static let serializedByteCount = pointCount * ARCCurve.compressedx962PointByteCount + scalarCount * ARCCurve.orderByteCount +extension ARC.Presentation { + static func getScalarCount() -> Int { return 5 } + static func getPointCount() -> Int { return 4 } + static func getSerializedByteCount(_ ciphersuite: ARC.Ciphersuite) -> Int { + return Self.getPointCount() * ciphersuite.pointByteCount + Self.getScalarCount() * ciphersuite.scalarByteCount + } - func serialize() -> Data { - var result = Data(capacity: Self.serializedByteCount) + func serialize(ciphersuite: ARC.Ciphersuite) -> Data { + var result = Data(capacity: Self.getSerializedByteCount(ciphersuite)) - result.append(self.U.compressedRepresentation) - result.append(self.UPrimeCommit.compressedRepresentation) - result.append(self.m1Commit.compressedRepresentation) - result.append(self.tag.compressedRepresentation) - result.append(self.proof.serialize()) + result.append(self.U.oprfRepresentation) + result.append(self.UPrimeCommit.oprfRepresentation) + result.append(self.m1Commit.oprfRepresentation) + result.append(self.tag.oprfRepresentation) + result.append(self.proof.serialize(ciphersuite: ciphersuite)) return result } - static func deserialize(presentationData: D) throws -> ARC.Presentation { - guard presentationData.count == self.serializedByteCount else { + static func deserialize(presentationData: D, ciphersuite: ARC.Ciphersuite) throws -> ARC.Presentation { + guard presentationData.count == self.getSerializedByteCount(ciphersuite) else { throw ARC.Errors.incorrectPresentationDataSize } var bytes = Data(presentationData) - let U = try H2G.G.Element(oprfRepresentation: bytes.popFirst(ARCCurve.compressedx962PointByteCount)) - let UPrimeCommit = try H2G.G.Element(oprfRepresentation: bytes.popFirst(ARCCurve.compressedx962PointByteCount)) - let m1Commit = try H2G.G.Element(oprfRepresentation: bytes.popFirst(ARCCurve.compressedx962PointByteCount)) - let tag = try H2G.G.Element(oprfRepresentation: bytes.popFirst(ARCCurve.compressedx962PointByteCount)) - let presentationProof = try Proof.deserialize(proofData: bytes, scalarCount: Self.scalarCount) + let U = try H2G.G.Element(oprfRepresentation: bytes.popFirst(ciphersuite.pointByteCount)) + let UPrimeCommit = try H2G.G.Element(oprfRepresentation: bytes.popFirst(ciphersuite.pointByteCount)) + let m1Commit = try H2G.G.Element(oprfRepresentation: bytes.popFirst(ciphersuite.pointByteCount)) + let tag = try H2G.G.Element(oprfRepresentation: bytes.popFirst(ciphersuite.pointByteCount)) + let presentationProof = try Proof.deserialize(proofData: bytes, scalarCount: Self.getScalarCount(), ciphersuite: ciphersuite) return ARC.Presentation(U: U, UPrimeCommit: UPrimeCommit, m1Commit: m1Commit, tag: tag, proof: presentationProof) } } @available(macOS 10.15, iOS 13.2, tvOS 13.2, watchOS 6.1, macCatalyst 13.2, visionOS 1.2, *) -extension ARC.ServerPublicKey where H2G == ARCH2G { - static let serializedByteCount = 3 * ARCCurve.compressedx962PointByteCount - static let pointCount = 3 // TODO: delete +extension ARC.ServerPublicKey { + static func getSerializedByteCount(_ ciphersuite: ARC.Ciphersuite) -> Int { + return 3 * ciphersuite.pointByteCount + } - func serialize() -> Data { - var result = Data(capacity: Self.serializedByteCount) + func serialize(ciphersuite: ARC.Ciphersuite) -> Data { + var result = Data(capacity: Self.getSerializedByteCount(ciphersuite)) - result.append(self.X0.compressedRepresentation) - result.append(self.X1.compressedRepresentation) - result.append(self.X2.compressedRepresentation) + result.append(self.X0.oprfRepresentation) + result.append(self.X1.oprfRepresentation) + result.append(self.X2.oprfRepresentation) return result } - static func deserialize(serverPublicKeyData: D) throws -> ARC.ServerPublicKey { - guard serverPublicKeyData.count == self.pointCount * ARCCurve.compressedx962PointByteCount else { + static func deserialize(serverPublicKeyData: D, ciphersuite: ARC.Ciphersuite) throws -> ARC.ServerPublicKey { + guard serverPublicKeyData.count == self.getSerializedByteCount(ciphersuite) else { throw ARC.Errors.incorrectServerCommitmentsSize } var bytes = Data(serverPublicKeyData) - let X0 = try H2G.G.Element(oprfRepresentation: bytes.popFirst(ARCCurve.compressedx962PointByteCount)) - let X1 = try H2G.G.Element(oprfRepresentation: bytes.popFirst(ARCCurve.compressedx962PointByteCount)) - let X2 = try H2G.G.Element(oprfRepresentation: bytes.popFirst(ARCCurve.compressedx962PointByteCount)) + let X0 = try H2G.G.Element(oprfRepresentation: bytes.popFirst(ciphersuite.pointByteCount)) + let X1 = try H2G.G.Element(oprfRepresentation: bytes.popFirst(ciphersuite.pointByteCount)) + let X2 = try H2G.G.Element(oprfRepresentation: bytes.popFirst(ciphersuite.pointByteCount)) return ARC.ServerPublicKey(X0: X0, X1: X1, X2: X2) } } @available(macOS 10.15, iOS 13.2, tvOS 13.2, watchOS 6.1, macCatalyst 13.2, visionOS 1.2, *) -extension Proof where H2G == ARCH2G { - func serialize() -> Data { +extension Proof { + func serialize(ciphersuite: ARC.Ciphersuite) -> Data { let scalarCount = self.responses.count + 1 - var result = Data(capacity: scalarCount * ARCCurve.orderByteCount) + var result = Data(capacity: scalarCount * ciphersuite.scalarByteCount) // Serialize challenge result.append(self.challenge.rawRepresentation) @@ -170,21 +177,21 @@ extension Proof where H2G == ARCH2G { return result } - static func deserialize(proofData: D, scalarCount: Int) throws -> Proof { - guard proofData.count == scalarCount * ARCCurve.orderByteCount else { + static func deserialize(proofData: D, scalarCount: Int, ciphersuite: ARC.Ciphersuite) throws -> Proof { + guard proofData.count == scalarCount * ciphersuite.scalarByteCount else { throw ARC.Errors.incorrectProofDataSize } var bytes = Data(proofData) // Deserialize challenge - let challenge = try ARCH2G.G.Scalar(bytes: bytes.popFirst(ARCCurve.orderByteCount)) + let challenge = try H2G.G.Scalar(bytes: bytes.popFirst(ciphersuite.scalarByteCount), reductionIsModOrder: true) // Deserialize responses - var responses: [GroupImpl.Scalar] = [] + var responses: [H2G.G.Scalar] = [] responses.reserveCapacity(scalarCount - 1) for _ in (0.. Int { return 1 } + static func getPointCount() -> Int { return 5 } + static func getSerializedByteCountExcludingPresentationState(_ ciphersuite: ARC.Ciphersuite) -> Int { + return Self.getPointCount() * ciphersuite.pointByteCount + Self.getScalarCount() * ciphersuite.scalarByteCount + } - func serialize() throws -> Data { + func serialize(ciphersuite: ARC.Ciphersuite) throws -> Data { let presentationStateBytes = try self.presentationState.serialize() - - var result = Data(capacity: Self.serializedByteCountExcludingPresentationState + presentationStateBytes.count) + var result = Data(capacity: Self.getSerializedByteCountExcludingPresentationState(ciphersuite) + presentationStateBytes.count) result.append(self.m1.rawRepresentation) - result.append(self.U.compressedRepresentation) - result.append(self.UPrime.compressedRepresentation) - result.append(self.X1.compressedRepresentation) - result.append(self.generatorG.compressedRepresentation) - result.append(self.generatorH.compressedRepresentation) + result.append(self.U.oprfRepresentation) + result.append(self.UPrime.oprfRepresentation) + result.append(self.X1.oprfRepresentation) + result.append(self.generatorG.oprfRepresentation) + result.append(self.generatorH.oprfRepresentation) result.append(presentationStateBytes) return result } - static func deserialize(credentialData: D) throws -> ARC.Credential { - guard credentialData.count - Self.serializedByteCountExcludingPresentationState >= 0 else { + static func deserialize(credentialData: D, ciphersuite: ARC.Ciphersuite) throws -> ARC.Credential { + guard credentialData.count - Self.getSerializedByteCountExcludingPresentationState(ciphersuite) >= 0 else { throw ARC.Errors.incorrectCredentialDataSize } let credentialData = Data(credentialData) var bytes = Data(credentialData) - let m1 = try ARCH2G.G.Scalar(bytes: bytes.popFirst(ARCCurve.orderByteCount)) - let U = try ARCH2G.G.Element(oprfRepresentation: bytes.popFirst(ARCCurve.compressedx962PointByteCount)) - let UPrime = try ARCH2G.G.Element(oprfRepresentation: bytes.popFirst(ARCCurve.compressedx962PointByteCount)) - let X1 = try ARCH2G.G.Element(oprfRepresentation: bytes.popFirst(ARCCurve.compressedx962PointByteCount)) - let genG = try ARCH2G.G.Element(oprfRepresentation: bytes.popFirst(ARCCurve.compressedx962PointByteCount)) - let genH = try ARCH2G.G.Element(oprfRepresentation: bytes.popFirst(ARCCurve.compressedx962PointByteCount)) + let m1 = try H2G.G.Scalar(bytes: bytes.popFirst(ciphersuite.scalarByteCount), reductionIsModOrder: true) + let U = try H2G.G.Element(oprfRepresentation: bytes.popFirst(ciphersuite.pointByteCount)) + let UPrime = try H2G.G.Element(oprfRepresentation: bytes.popFirst(ciphersuite.pointByteCount)) + let X1 = try H2G.G.Element(oprfRepresentation: bytes.popFirst(ciphersuite.pointByteCount)) + let genG = try H2G.G.Element(oprfRepresentation: bytes.popFirst(ciphersuite.pointByteCount)) + let genH = try H2G.G.Element(oprfRepresentation: bytes.popFirst(ciphersuite.pointByteCount)) // Deserialize presentationState from remaining bytes. let presentationState = try ARC.PresentationState.deserialize(presentationStateData: bytes) - let ciphersuite = ARC.Ciphersuite(ARCH2G.self) + let ciphersuite = ARC.Ciphersuite(H2G.self) return ARC.Credential(m1: m1, U: U, UPrime: UPrime, X1: X1, ciphersuite: ciphersuite, generatorG: genG, generatorH: genH, presentationState: presentationState) } } diff --git a/Sources/_CryptoExtras/ARC/ARCPrecredential.swift b/Sources/_CryptoExtras/ARC/ARCPrecredential.swift index b1281fa95..4259cb096 100644 --- a/Sources/_CryptoExtras/ARC/ARCPrecredential.swift +++ b/Sources/_CryptoExtras/ARC/ARCPrecredential.swift @@ -44,12 +44,12 @@ extension ARC { let credentialRequest: CredentialRequest init(ciphersuite: Ciphersuite, m1: Group.Scalar = Group.Scalar.random, requestContext: Data, r1: Group.Scalar = Group.Scalar.random, r2: Group.Scalar = Group.Scalar.random, serverPublicKey: ServerPublicKey) throws { - let m2 = try H2G.hashToScalar(requestContext, domainSeparationString: Data((ARC.domain + "requestContext").utf8)) + let m2 = try H2G.hashToScalar(requestContext, domainSeparationString: Data((ciphersuite.domain + "requestContext").utf8)) self.clientSecrets = ClientSecrets(m1: m1, m2: m2, r1: r1, r2: r2) self.serverPublicKey = serverPublicKey self.ciphersuite = ciphersuite (self.generatorG, self.generatorH) = ARC.getGenerators(suite: ciphersuite) - self.credentialRequest = try CredentialRequest(clientSecrets: self.clientSecrets, generatorG: generatorG, generatorH: generatorH) + self.credentialRequest = try CredentialRequest(clientSecrets: self.clientSecrets, generatorG: generatorG, generatorH: generatorH, ciphersuite: ciphersuite) } func makeCredential(credentialResponse: CredentialResponse) throws -> Credential { diff --git a/Sources/_CryptoExtras/ARC/ARCPresentation.swift b/Sources/_CryptoExtras/ARC/ARCPresentation.swift index 5e2272039..6f7105438 100644 --- a/Sources/_CryptoExtras/ARC/ARCPresentation.swift +++ b/Sources/_CryptoExtras/ARC/ARCPresentation.swift @@ -49,9 +49,9 @@ extension ARC { let V = z * credential.X1 - r * generatorG // Create tag: (m1 + nonce)^(-1) * H2G(presentationContext) - let nonceScalar = try Group.Scalar(bytes: I2OSP(value: nonce, outputByteCount: ARCCurve.orderByteCount), reductionIsModOrder: true) + let nonceScalar = try Group.Scalar(bytes: I2OSP(value: nonce, outputByteCount: credential.ciphersuite.scalarByteCount), reductionIsModOrder: true) let inverse = (nonceScalar + credential.m1) ^ (-1) - let T = H2G.hashToGroup(presentationContext, domainSeparationString: Data(("HashToGroup-" + ARC.domain + "Tag").utf8)) + let T = H2G.hashToGroup(presentationContext, domainSeparationString: Data(("HashToGroup-" + credential.ciphersuite.domain + "Tag").utf8)) let tag = inverse * T // m1Tag is a helper element in the ZKP, and is needed to ensure the @@ -59,7 +59,7 @@ extension ARC { let m1Tag = credential.m1 * tag // Create a prover, and allocate variables for the constrained scalars. - var prover = Prover(label: ARC.domain + ARC.domain + "CredentialPresentation") + var prover = Prover(label: credential.ciphersuite.domain + credential.ciphersuite.domain + "CredentialPresentation") let m1Var = prover.appendScalar(label: "m1", assignment: credential.m1) let zVar = prover.appendScalar(label: "z", assignment: z) let rNegVar = prover.appendScalar(label: "-r", assignment: -r) @@ -90,12 +90,10 @@ extension ARC { - nonce: Integer which is used for rate limiting, which should be in `[0, presentationLimit)`. - generatorG: Public generator G - generatorH: Public generator H + - ciphersuite: The ciphersuite for ARC - Returns: a boolean for if the tag is valid and the tag proof verifies correctly. */ - func verify( - serverPrivateKey: ServerPrivateKey, X1: Group.Element, m2: Group.Scalar, presentationContext: Data, presentationLimit: Int, nonce: Int, - generatorG: Group.Element, generatorH: Group.Element - ) throws -> Bool { + func verify(serverPrivateKey: ServerPrivateKey, X1: Group.Element, m2: Group.Scalar, presentationContext: Data, presentationLimit: Int, nonce: Int, generatorG: Group.Element, generatorH: Group.Element, ciphersuite: Ciphersuite) throws -> Bool { if nonce < 0 || nonce >= presentationLimit { return false // nonce is outside of the presentationLimit } @@ -107,14 +105,14 @@ extension ARC { let V = serverPrivateKey.x0 * self.U + serverPrivateKey.x1 * self.m1Commit + serverPrivateKey.x2 * m2 * self.U - self.UPrimeCommit // Recompute T = H2G(presentationContext) - let T = H2G.hashToGroup(presentationContext, domainSeparationString: Data(("HashToGroup-" + ARC.domain + "Tag").utf8)) + let T = H2G.hashToGroup(presentationContext, domainSeparationString: Data(("HashToGroup-" + ciphersuite.domain + "Tag").utf8)) // Recompute m1Tag = H2G(presentationContext) - nonce * tag var m1Tag = T for _ in 0..(label: ARC.domain + ARC.domain + "CredentialPresentation") + var verifier = Verifier(label: ciphersuite.domain + ciphersuite.domain + "CredentialPresentation") let m1Var = verifier.appendScalar(label: "m1") let zVar = verifier.appendScalar(label: "z") let rNegVar = verifier.appendScalar(label: "-r") diff --git a/Sources/_CryptoExtras/ARC/ARCRequest.swift b/Sources/_CryptoExtras/ARC/ARCRequest.swift index 9c9f529b2..b36aacfd9 100644 --- a/Sources/_CryptoExtras/ARC/ARCRequest.swift +++ b/Sources/_CryptoExtras/ARC/ARCRequest.swift @@ -30,12 +30,12 @@ extension ARC { let m2Enc: Group.Element let proof: Proof - init(clientSecrets: ClientSecrets, generatorG: Group.Element, generatorH: Group.Element) throws { + init(clientSecrets: ClientSecrets, generatorG: Group.Element, generatorH: Group.Element, ciphersuite: Ciphersuite) throws { let m1Enc = clientSecrets.m1 * generatorG + clientSecrets.r1 * generatorH let m2Enc = clientSecrets.m2 * generatorG + clientSecrets.r2 * generatorH // Create a prover, and allocate variables for the constrained scalars. - var prover = Prover(label: ARC.domain + ARC.domain + "CredentialRequest") + var prover = Prover(label: ciphersuite.domain + ciphersuite.domain + "CredentialRequest") let m1Var = prover.appendScalar(label: "m1", assignment: clientSecrets.m1) let m2Var = prover.appendScalar(label: "m2", assignment: clientSecrets.m2) let r1Var = prover.appendScalar(label: "r1", assignment: clientSecrets.r1) @@ -54,7 +54,7 @@ extension ARC { self.proof = proof } - func verify(generatorG: Group.Element, generatorH: Group.Element) throws -> Bool { + func verify(generatorG: Group.Element, generatorH: Group.Element, ciphersuite: Ciphersuite) throws -> Bool { // Check that the encrypted attributes were generated with nonzero `m` and `r` values. if (self.m1Enc == generatorG || self.m1Enc == generatorH || self.m1Enc == self.m1Enc + self.m1Enc) || (self.m2Enc == generatorG || self.m2Enc == generatorH || self.m2Enc == self.m2Enc + self.m2Enc) { @@ -62,7 +62,7 @@ extension ARC { } // Create a verifier, and allocate variables for the constrained scalars. - var verifier = Verifier(label: ARC.domain + ARC.domain + "CredentialRequest") + var verifier = Verifier(label: ciphersuite.domain + ciphersuite.domain + "CredentialRequest") let m1Var = verifier.appendScalar(label: "m1") let m2Var = verifier.appendScalar(label: "m2") let r1Var = verifier.appendScalar(label: "r1") diff --git a/Sources/_CryptoExtras/ARC/ARCResponse.swift b/Sources/_CryptoExtras/ARC/ARCResponse.swift index b6202925a..059eefd2b 100644 --- a/Sources/_CryptoExtras/ARC/ARCResponse.swift +++ b/Sources/_CryptoExtras/ARC/ARCResponse.swift @@ -52,7 +52,8 @@ extension ARC { serverPublicKey: ServerPublicKey, generatorG: Group.Element, generatorH: Group.Element, - b: Group.Scalar = Group.Scalar.random + b: Group.Scalar = Group.Scalar.random, + ciphersuite: Ciphersuite ) throws { let U = b * generatorG let X0Aux = b * serverPrivateKey.x0Blinding * generatorH @@ -65,7 +66,7 @@ extension ARC { let encUPrime = b * (serverPublicKey.X0 + serverPrivateKey.x1 * request.m1Enc + serverPrivateKey.x2 * request.m2Enc) // Create a prover, and allocate variables for the constrained scalars. - var prover = Prover(label: ARC.domain + ARC.domain + "CredentialResponse") + var prover = Prover(label: ciphersuite.domain + ciphersuite.domain + "CredentialResponse") let x0Var = prover.appendScalar(label: "x0", assignment: serverPrivateKey.x0) let x1Var = prover.appendScalar(label: "x1", assignment: serverPrivateKey.x1) let x2Var = prover.appendScalar(label: "x2", assignment: serverPrivateKey.x2) @@ -99,15 +100,14 @@ extension ARC { self.proof = proof } - func verify(request: CredentialRequest, serverPublicKey: ServerPublicKey, generatorG: Group.Element, generatorH: Group.Element - ) throws -> Bool { + func verify(request: CredentialRequest, serverPublicKey: ServerPublicKey, generatorG: Group.Element, generatorH: Group.Element, ciphersuite: Ciphersuite) throws -> Bool { // Check that U, encUPrime are not 0 if (self.U == self.U + self.U) || (self.encUPrime == self.encUPrime + self.encUPrime) { return false } // Create a verifier, and allocate variables for the constrained scalars. - var verifier = Verifier(label: ARC.domain + ARC.domain + "CredentialResponse") + var verifier = Verifier(label: ciphersuite.domain + ciphersuite.domain + "CredentialResponse") let x0Var = verifier.appendScalar(label: "x0") let x1Var = verifier.appendScalar(label: "x1") let x2Var = verifier.appendScalar(label: "x2") diff --git a/Sources/_CryptoExtras/ARC/ARCServer.swift b/Sources/_CryptoExtras/ARC/ARCServer.swift index 8d4bef6b0..c39daece2 100644 --- a/Sources/_CryptoExtras/ARC/ARCServer.swift +++ b/Sources/_CryptoExtras/ARC/ARCServer.swift @@ -72,7 +72,7 @@ extension ARC { func respond(credentialRequest: CredentialRequest, b: Group.Scalar = Group.Scalar.random) throws -> CredentialResponse { guard - try credentialRequest.verify(generatorG: generatorG, generatorH: generatorH) + try credentialRequest.verify(generatorG: generatorG, generatorH: generatorH, ciphersuite: self.ciphersuite) else { throw ARC.Errors.invalidProof } @@ -82,12 +82,13 @@ extension ARC { serverPublicKey: self.serverPublicKey, generatorG: generatorG, generatorH: generatorH, - b: b + b: b, + ciphersuite: self.ciphersuite ) } func verify(presentation: Presentation, requestContext: Data, presentationContext: Data, presentationLimit: Int, nonce: Int) throws -> Bool { - let m2 = try H2G.hashToScalar(requestContext, domainSeparationString: Data((ARC.domain + "requestContext").utf8)) + let m2 = try H2G.hashToScalar(requestContext, domainSeparationString: Data((self.ciphersuite.domain + "requestContext").utf8)) return try presentation.verify( serverPrivateKey: self.serverPrivateKey, X1: self.serverPublicKey.X1, @@ -96,7 +97,8 @@ extension ARC { presentationLimit: presentationLimit, nonce: nonce, generatorG: generatorG, - generatorH: generatorH + generatorH: generatorH, + ciphersuite: self.ciphersuite ) } } diff --git a/Sources/_CryptoExtras/CMakeLists.txt b/Sources/_CryptoExtras/CMakeLists.txt index 2ddd0cbe7..f7b2f9ab7 100644 --- a/Sources/_CryptoExtras/CMakeLists.txt +++ b/Sources/_CryptoExtras/CMakeLists.txt @@ -21,6 +21,7 @@ add_library(_CryptoExtras "AES/BoringSSL/AES_CFB_boring.swift" "AES/BoringSSL/AES_CTR_boring.swift" "AES/BoringSSL/AES_GCM_SIV_boring.swift" + "AES/CMAC.swift" "ARC/ARC+API.swift" "ARC/ARC.swift" "ARC/ARCCredential.swift" @@ -32,6 +33,10 @@ add_library(_CryptoExtras "ARC/ARCServer.swift" "ChaCha20CTR/BoringSSL/ChaCha20CTR_boring.swift" "ChaCha20CTR/ChaCha20CTR.swift" + "EC/ObjectIdentifier.swift" + "EC/PKCS8DERRepresentation.swift" + "EC/PKCS8PrivateKey.swift" + "EC/RFC8410AlgorithmIdentifier.swift" "ECToolbox/BoringSSL/ECToolbox_boring.swift" "ECToolbox/ECToolbox.swift" "H2G/HashToField.swift" @@ -50,7 +55,6 @@ add_library(_CryptoExtras "RSA/RSA+BlindSigning.swift" "RSA/RSA.swift" "RSA/RSA_boring.swift" - "RSA/RSA_security.swift" "Reexport.swift" "Util/BoringSSLHelpers.swift" "Util/CryptoKitErrors_boring.swift" @@ -62,6 +66,10 @@ add_library(_CryptoExtras "Util/PEMDocument.swift" "Util/PrettyBytes.swift" "Util/SubjectPublicKeyInfo.swift" + "Util/ThreadSpecific/ThreadOps.swift" + "Util/ThreadSpecific/ThreadPosix.swift" + "Util/ThreadSpecific/ThreadSpecific.swift" + "Util/ThreadSpecific/ThreadWindows.swift" "ZKPs/DLEQ.swift" "ZKPs/Prover.swift" "ZKPs/Verifier.swift" diff --git a/Sources/_CryptoExtras/Docs.docc/index.md b/Sources/_CryptoExtras/Docs.docc/index.md index b38a23dd7..50b5eca56 100644 --- a/Sources/_CryptoExtras/Docs.docc/index.md +++ b/Sources/_CryptoExtras/Docs.docc/index.md @@ -15,10 +15,6 @@ Provides additional cryptographic APIs that are not available in CryptoKit (and ### Public key cryptography - ``_RSA`` -- ``MLKEM768`` -- ``MLKEM1024`` -- ``MLDSA65`` -- ``MLDSA87`` ### Key derivation functions diff --git a/Sources/_CryptoExtras/EC/ObjectIdentifier.swift b/Sources/_CryptoExtras/EC/ObjectIdentifier.swift new file mode 100644 index 000000000..87c79f531 --- /dev/null +++ b/Sources/_CryptoExtras/EC/ObjectIdentifier.swift @@ -0,0 +1,37 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2025 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import SwiftASN1 + +extension ASN1ObjectIdentifier.AlgorithmIdentifier { + // Identifies the key agreement algorithm X25519. + // + // This identifier is defined in RFC 8410 + static let idX25519: ASN1ObjectIdentifier = [1, 3, 101, 110] + + // Identifies the key agreement algorithm X448. + // + // This identifier is defined in RFC 8410 + static let idX448: ASN1ObjectIdentifier = [1, 3, 101, 111] + + // Identifies the signature algorithm Ed25519. + // + // This identifier is defined in RFC 8410 + static let idEd25519: ASN1ObjectIdentifier = [1, 3, 101, 112] + + // Identifies the signature algorithm Ed448. + // + // This identifier is defined in RFC 8410 + static let idEd448: ASN1ObjectIdentifier = [1, 3, 101, 113] +} diff --git a/Sources/_CryptoExtras/EC/PKCS8DERRepresentation.swift b/Sources/_CryptoExtras/EC/PKCS8DERRepresentation.swift new file mode 100644 index 000000000..a3449ca64 --- /dev/null +++ b/Sources/_CryptoExtras/EC/PKCS8DERRepresentation.swift @@ -0,0 +1,76 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2025 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import Crypto +import Foundation +import SwiftASN1 + +@available(iOS 14.0, macOS 11.0, watchOS 7.0, tvOS 14.0, *) +extension Curve25519.Signing.PrivateKey { + /// A Distinguished Encoding Rules (DER) encoded representation of the private key in PKCS#8 format. + public var pkcs8DERRepresentation: Data { + let pkey = ASN1.PKCS8PrivateKey(algorithm: .ed25519, privateKey: Array(self.rawRepresentation)) + var serializer = DER.Serializer() + + // Serializing this key can't throw + try! serializer.serialize(pkey) + return Data(serializer.serializedBytes) + } +} + +@available(iOS 14.0, macOS 11.0, watchOS 7.0, tvOS 14.0, *) +extension Curve25519.KeyAgreement.PrivateKey { + /// A Distinguished Encoding Rules (DER) encoded representation of the private key in PKCS#8 format. + public var pkcs8DERRepresentation: Data { + let pkey = ASN1.PKCS8PrivateKey(algorithm: .x25519, privateKey: Array(self.rawRepresentation)) + var serializer = DER.Serializer() + + // Serializing this key can't throw + try! serializer.serialize(pkey) + return Data(serializer.serializedBytes) + } +} + +@available(iOS 14.0, macOS 11.0, watchOS 7.0, tvOS 14.0, *) +extension P256.Signing.PrivateKey { + /// A Distinguished Encoding Rules (DER) encoded representation of the private key in PKCS#8 format. + /// + /// This property provides the same output as the existing `derRepresentation` property, + /// which already conforms to the PKCS#8 standard. + public var pkcs8DERRepresentation: Data { + self.derRepresentation + } +} + +@available(iOS 14.0, macOS 11.0, watchOS 7.0, tvOS 14.0, *) +extension P384.Signing.PrivateKey { + /// A Distinguished Encoding Rules (DER) encoded representation of the private key in PKCS#8 format. + /// + /// This property provides the same output as the existing `derRepresentation` property, + /// which already conforms to the PKCS#8 standard. + public var pkcs8DERRepresentation: Data { + self.derRepresentation + } +} + +@available(iOS 14.0, macOS 11.0, watchOS 7.0, tvOS 14.0, *) +extension P521.Signing.PrivateKey { + /// A Distinguished Encoding Rules (DER) encoded representation of the private key in PKCS#8 format. + /// + /// This property provides the same output as the existing `derRepresentation` property, + /// which already conforms to the PKCS#8 standard. + public var pkcs8DERRepresentation: Data { + self.derRepresentation + } +} diff --git a/Sources/_CryptoExtras/EC/PKCS8PrivateKey.swift b/Sources/_CryptoExtras/EC/PKCS8PrivateKey.swift new file mode 100644 index 000000000..5de7a11e4 --- /dev/null +++ b/Sources/_CryptoExtras/EC/PKCS8PrivateKey.swift @@ -0,0 +1,93 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2025 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import Crypto +import SwiftASN1 + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension ASN1 { + // A PKCS#8 private key is one of two formats, depending on the version: + // + // For PKCS#8 we need the following for the private key: + // + // PrivateKeyInfo ::= SEQUENCE { + // version Version, + // privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, + // privateKey PrivateKey, + // attributes [0] IMPLICIT Attributes OPTIONAL } + // + // Version ::= INTEGER + // + // PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier + // + // PrivateKey ::= OCTET STRING + // + // Attributes ::= SET OF Attribute + // + // We disregard the attributes because we don't support them anyway. + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) + struct PKCS8PrivateKey: DERImplicitlyTaggable { + static var defaultIdentifier: ASN1Identifier { + .sequence + } + + var algorithm: RFC8410AlgorithmIdentifier + + var privateKey: ASN1OctetString + + init(derEncoded rootNode: ASN1Node, withIdentifier identifier: ASN1Identifier) throws { + self = try DER.sequence(rootNode, identifier: identifier) { nodes in + let version = try Int(derEncoded: &nodes) + guard version == 0 || version == 1 else { + throw ASN1Error.invalidASN1Object(reason: "Version number mismatch") + } + + let algorithm = try ASN1.RFC8410AlgorithmIdentifier(derEncoded: &nodes) + let privateKeyBytes = try ASN1OctetString(derEncoded: &nodes) + + // We ignore the attributes + _ = try DER.optionalExplicitlyTagged(&nodes, tagNumber: 0, tagClass: .contextSpecific) { _ in } + + let privateKeyNode = try DER.parse(privateKeyBytes.bytes) + let privateKey = try ASN1OctetString(derEncoded: privateKeyNode) + + return try .init(algorithm: algorithm, privateKey: privateKey) + } + } + + private init(algorithm: ASN1.RFC8410AlgorithmIdentifier, privateKey: ASN1OctetString) throws { + self.privateKey = privateKey + self.algorithm = algorithm + } + + init(algorithm: ASN1.RFC8410AlgorithmIdentifier, privateKey: [UInt8]) { + self.algorithm = algorithm + self.privateKey = ASN1OctetString(contentBytes: privateKey[...]) + } + + func serialize(into coder: inout DER.Serializer, withIdentifier identifier: ASN1Identifier) throws { + try coder.appendConstructedNode(identifier: identifier) { coder in + try coder.serialize(0) + try coder.serialize(self.algorithm) + + // Here's a weird one: we recursively serialize the private key, and then turn the bytes into an octet string. + var subCoder = DER.Serializer() + try subCoder.serialize(self.privateKey) + let serializedKey = ASN1OctetString(contentBytes: subCoder.serializedBytes[...]) + + try coder.serialize(serializedKey) + } + } + } +} diff --git a/Sources/_CryptoExtras/EC/RFC8410AlgorithmIdentifier.swift b/Sources/_CryptoExtras/EC/RFC8410AlgorithmIdentifier.swift new file mode 100644 index 000000000..b73b4373e --- /dev/null +++ b/Sources/_CryptoExtras/EC/RFC8410AlgorithmIdentifier.swift @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2025 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import SwiftASN1 + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension ASN1 { + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) + struct RFC8410AlgorithmIdentifier: DERImplicitlyTaggable, Hashable { + static var defaultIdentifier: ASN1Identifier { + .sequence + } + + var algorithm: ASN1ObjectIdentifier + + // RFC 8410: For all of these OIDs, the parameters MUST be absent. + // They are still part of the identifer block. + var parameters: ASN1Any? + + init(algorithm: ASN1ObjectIdentifier, parameters: ASN1Any?) { + self.algorithm = algorithm + self.parameters = parameters + } + + init(derEncoded rootNode: ASN1Node, withIdentifier identifier: ASN1Identifier) throws { + // The AlgorithmIdentifier block looks like this. + // + // AlgorithmIdentifier ::= SEQUENCE { + // algorithm OBJECT IDENTIFIER, + // parameters ANY DEFINED BY algorithm OPTIONAL + // } + // + // We don't bother with helpers: we just try to decode it directly. + self = try DER.sequence(rootNode, identifier: identifier) { nodes in + let algorithmOID = try ASN1ObjectIdentifier(berEncoded: &nodes) + + let parameters = nodes.next().map { ASN1Any(berEncoded: $0) } + + return .init(algorithm: algorithmOID, parameters: parameters) + } + } + + func serialize(into coder: inout DER.Serializer, withIdentifier identifier: ASN1Identifier) throws { + try coder.appendConstructedNode(identifier: identifier) { coder in + try coder.serialize(self.algorithm) + if let parameters = self.parameters { + try coder.serialize(parameters) + } + } + } + } +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension ASN1.RFC8410AlgorithmIdentifier { + static let x25519 = ASN1.RFC8410AlgorithmIdentifier(algorithm: .AlgorithmIdentifier.idX25519, parameters: nil) + + static let x448 = ASN1.RFC8410AlgorithmIdentifier(algorithm: .AlgorithmIdentifier.idX448, parameters: nil) + + static let ed25519 = ASN1.RFC8410AlgorithmIdentifier(algorithm: .AlgorithmIdentifier.idEd25519, parameters: nil) + + static let ed448 = ASN1.RFC8410AlgorithmIdentifier(algorithm: .AlgorithmIdentifier.idEd448, parameters: nil) +} diff --git a/Sources/_CryptoExtras/ECToolbox/BoringSSL/ECToolbox_boring.swift b/Sources/_CryptoExtras/ECToolbox/BoringSSL/ECToolbox_boring.swift index 8cde5d034..36cb3d738 100644 --- a/Sources/_CryptoExtras/ECToolbox/BoringSSL/ECToolbox_boring.swift +++ b/Sources/_CryptoExtras/ECToolbox/BoringSSL/ECToolbox_boring.swift @@ -70,10 +70,17 @@ extension P256: OpenSSLSupportedNISTCurve { @inlinable static var hashToFieldByteCount: Int { 48 } - @TaskLocal + private static let __ffacTSV = ThreadSpecificVariable() + @usableFromInline - // NOTE: This could be a let when Swift 6.0 is the minimum supported version. - static var __ffac = try! FiniteFieldArithmeticContext(fieldSize: P256.group.order) + static var __ffac: FiniteFieldArithmeticContext { + if let value = Self.__ffacTSV.currentValue { + return value + } + let value = try! FiniteFieldArithmeticContext(fieldSize: P256.group.order) + Self.__ffacTSV.currentValue = value + return value + } } /// NOTE: This conformance applies to this type from the Crypto module even if it comes from the SDK. @@ -97,10 +104,17 @@ extension P384: OpenSSLSupportedNISTCurve { @inlinable static var hashToFieldByteCount: Int { 72 } - @TaskLocal + private static let __ffacTSV = ThreadSpecificVariable() + @usableFromInline - // NOTE: This could be a let when Swift 6.0 is the minimum supported version. - static var __ffac = try! FiniteFieldArithmeticContext(fieldSize: P384.group.order) + static var __ffac: FiniteFieldArithmeticContext { + if let value = Self.__ffacTSV.currentValue { + return value + } + let value = try! FiniteFieldArithmeticContext(fieldSize: P384.group.order) + Self.__ffacTSV.currentValue = value + return value + } } /// NOTE: This conformance applies to this type from the Crypto module even if it comes from the SDK. @@ -124,10 +138,17 @@ extension P521: OpenSSLSupportedNISTCurve { @inlinable static var hashToFieldByteCount: Int { 98 } - @TaskLocal + private static let __ffacTSV = ThreadSpecificVariable() + @usableFromInline - // NOTE: This could be a let when Swift 6.0 is the minimum supported version. - static var __ffac = try! FiniteFieldArithmeticContext(fieldSize: P521.group.order) + static var __ffac: FiniteFieldArithmeticContext { + if let value = Self.__ffacTSV.currentValue { + return value + } + let value = try! FiniteFieldArithmeticContext(fieldSize: P521.group.order) + Self.__ffacTSV.currentValue = value + return value + } } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) diff --git a/Sources/_CryptoExtras/RSA/RSA+BlindSigning.swift b/Sources/_CryptoExtras/RSA/RSA+BlindSigning.swift index f21f17358..10c7a6e2a 100644 --- a/Sources/_CryptoExtras/RSA/RSA+BlindSigning.swift +++ b/Sources/_CryptoExtras/RSA/RSA+BlindSigning.swift @@ -499,7 +499,7 @@ extension _RSA.BlindSigning.PublicKey { extension _RSA.BlindSigning { /// Errors defined in the RSA Blind Signatures protocol. /// - /// - NOTE: This type does not conform to `Swift.Error`, it is used to construct a `CryptoKitError`. + /// - NOTE: This type does not conform to `Swift.Error`, it is used to construct a `CryptoError`. /// /// - Seealso: [RFC 9474: Errors](https://www.rfc-editor.org/rfc/rfc9474.html#name-errors). @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) @@ -516,7 +516,7 @@ extension _RSA.BlindSigning { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension CryptoKitError { - /// Map an error from the RSA Blind Signatures protocol to a CryptoKitError. + /// Map an error from the RSA Blind Signatures protocol to a CryptoError. init(_ error: _RSA.BlindSigning.ProtocolError) { switch error { case .messageTooLong: diff --git a/Sources/_CryptoExtras/RSA/RSA.swift b/Sources/_CryptoExtras/RSA/RSA.swift index 63e1bcbb3..8942fcebb 100644 --- a/Sources/_CryptoExtras/RSA/RSA.swift +++ b/Sources/_CryptoExtras/RSA/RSA.swift @@ -20,17 +20,10 @@ import Crypto import CryptoBoringWrapper import SwiftASN1 -#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -fileprivate typealias BackingPublicKey = SecurityRSAPublicKey -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -fileprivate typealias BackingPrivateKey = SecurityRSAPrivateKey -#else @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) fileprivate typealias BackingPublicKey = BoringSSLRSAPublicKey @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) fileprivate typealias BackingPrivateKey = BoringSSLRSAPrivateKey -#endif /// Types associated with the RSA algorithm /// @@ -124,14 +117,8 @@ extension _RSA.Signing { } /// Construct an RSA public key with the specified parameters. - /// - /// Only the BoringSSL backend provides APIs to create a key from its parameters so we first create a BoringSSL - /// key, and then pass it to the platform-specific initializer that accepts a BoringSSL key. - /// - /// On Darwin platforms, this will serialize it to PEM format, and then construct a platform-specific key from - /// the PEM representation. public init(n: some ContiguousBytes, e: some ContiguousBytes) throws { - self.backing = try BackingPublicKey(BoringSSLRSAPublicKey(n: n, e: e)) + self.backing = try BackingPublicKey(n: n, e: e) } public var pkcs1DERRepresentation: Data { @@ -222,14 +209,8 @@ extension _RSA.Signing { } /// Construct an RSA private key with the specified parameters. - /// - /// Only the BoringSSL backend provides APIs to create a key from its parameters so we first create a BoringSSL - /// key, and then pass it to the platform-specific initializer that accepts a BoringSSL key. - /// - /// On Darwin platforms, this will serialize it to DER format, and then construct a platform-specific key from - /// the DER representation. public init(n: some ContiguousBytes, e: some ContiguousBytes, d: some ContiguousBytes, p: some ContiguousBytes, q: some ContiguousBytes) throws { - self.backing = try BackingPrivateKey(BoringSSLRSAPrivateKey(n: n, e: e, d: d, p: p, q: q)) + self.backing = try BackingPrivateKey(n: n, e: e, d: d, p: p, q: q) } /// Randomly generate a new RSA private key of a given size. @@ -263,6 +244,11 @@ extension _RSA.Signing { self.backing.pemRepresentation } + /// A Distinguished Encoding Rules (DER) encoded representation of the private key in PKCS#8 format. + public var pkcs8DERRepresentation: Data { + self.backing.pkcs8DERRepresentation + } + public var pkcs8PEMRepresentation: String { self.backing.pkcs8PEMRepresentation } @@ -545,14 +531,8 @@ extension _RSA.Encryption { } /// Construct an RSA public key with the specified parameters. - /// - /// Only the BoringSSL backend provides APIs to create a key from its parameters so we first create a BoringSSL - /// key, and then pass it to the platform-specific initializer that accepts a BoringSSL key. - /// - /// On Darwin platforms, this will serialize it to DER format, and then construct a platform-specific key from - /// the DER representation. public init(n: some ContiguousBytes, e: some ContiguousBytes) throws { - self.backing = try BackingPublicKey(BoringSSLRSAPublicKey(n: n, e: e)) + self.backing = try BackingPublicKey(n: n, e: e) } public var pkcs1DERRepresentation: Data { self.backing.pkcs1DERRepresentation } @@ -613,14 +593,8 @@ extension _RSA.Encryption { /// Construct an RSA private key with the specified parameters. - /// - /// Only the BoringSSL backend provides APIs to create a key from its parameters so we first create a BoringSSL - /// key, and then pass it to the platform-specific initializer that accepts a BoringSSL key. - /// - /// On Darwin platforms, this will serialize it to PEM format, and then construct a platform-specific key from - /// the PEM representation. public init(n: some ContiguousBytes, e: some ContiguousBytes, d: some ContiguousBytes, p: some ContiguousBytes, q: some ContiguousBytes) throws { - self.backing = try BackingPrivateKey(BoringSSLRSAPrivateKey(n: n, e: e, d: d, p: p, q: q)) + self.backing = try BackingPrivateKey(n: n, e: e, d: d, p: p, q: q) } /// Randomly generate a new RSA private key of a given size. diff --git a/Sources/_CryptoExtras/RSA/RSA_boring.swift b/Sources/_CryptoExtras/RSA/RSA_boring.swift index b35743f53..48d6d3c25 100644 --- a/Sources/_CryptoExtras/RSA/RSA_boring.swift +++ b/Sources/_CryptoExtras/RSA/RSA_boring.swift @@ -124,6 +124,10 @@ internal struct BoringSSLRSAPrivateKey: Sendable { self.backing.pemRepresentation } + var pkcs8DERRepresentation: Data { + self.backing.pkcs8DERRepresentation + } + var pkcs8PEMRepresentation: String { self.backing.pkcs8PEMRepresentation } @@ -755,6 +759,15 @@ extension BoringSSLRSAPrivateKey { } } + fileprivate var pkcs8DERRepresentation: Data { + BIOHelper.withWritableMemoryBIO { bio in + let rc = CCryptoBoringSSL_i2d_PKCS8PrivateKeyInfo_bio(bio, self.pointer) + precondition(rc == 1, "Exporting PKCS8 DER key failed") + + return try! Data(copyingMemoryBIO: bio) + } + } + fileprivate var pkcs8PEMRepresentation: String { BIOHelper.withWritableMemoryBIO { bio in let evp = CCryptoBoringSSL_EVP_PKEY_new() diff --git a/Sources/_CryptoExtras/RSA/RSA_security.swift b/Sources/_CryptoExtras/RSA/RSA_security.swift deleted file mode 100644 index db1f9f96e..000000000 --- a/Sources/_CryptoExtras/RSA/RSA_security.swift +++ /dev/null @@ -1,482 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the SwiftCrypto open source project -// -// Copyright (c) 2021 Apple Inc. and the SwiftCrypto project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// -#if canImport(FoundationEssentials) -import FoundationEssentials -#else -import Foundation -#endif -import Crypto - -#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API -@_implementationOnly import Security - -// unchecked sendable until `SecKey` gets sendable annotations -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -internal struct SecurityRSAPublicKey: @unchecked Sendable { - private var backing: SecKey - - init(pemRepresentation: String) throws { - let document = try ASN1.PEMDocument(pemString: pemRepresentation) - self = try .init(derRepresentation: document.derBytes) - } - - init(derRepresentation: Bytes) throws { - let keyAttributes: [CFString: Any] = [ - kSecAttrKeyType: kSecAttrKeyTypeRSA, - kSecAttrKeyClass: kSecAttrKeyClassPublic, - ] - let data = Data(derRepresentation) - var error: Unmanaged? = nil - let key = SecKeyCreateWithData(data as CFData, keyAttributes as CFDictionary, &error) - - guard let unwrappedKey = key else { - // If this returns nil, error must be set. - throw error!.takeRetainedValue() as Error - } - - self.backing = unwrappedKey - } - - init(_ boringSSLKey: BoringSSLRSAPublicKey) throws { - try self.init(derRepresentation: boringSSLKey.derRepresentation) - } - - var pkcs1DERRepresentation: Data { - var error: Unmanaged? = nil - let representation = SecKeyCopyExternalRepresentation(self.backing, &error) - return representation! as Data - } - - var pkcs1PEMRepresentation: String { - return ASN1.PEMDocument(type: _RSA.PKCS1PublicKeyType, derBytes: self.pkcs1DERRepresentation).pemString - } - - var derRepresentation: Data { - return Data(spkiBytesForPKCS1Bytes: self.pkcs1DERRepresentation) - } - - var pemRepresentation: String { - return ASN1.PEMDocument(type: _RSA.SPKIPublicKeyType, derBytes: self.derRepresentation).pemString - } - - var keySizeInBits: Int { - SecKeyGetBlockSize(self.backing) * 8 - } - - fileprivate init(_ backing: SecKey) { - self.backing = backing - } - - func getKeyPrimitives() throws -> (n: Data, e: Data) { - try BoringSSLRSAPublicKey(derRepresentation: self.derRepresentation).getKeyPrimitives() - } -} - -// unchecked sendable until `SecKey` gets sendable annotations -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -internal struct SecurityRSAPrivateKey: @unchecked Sendable { - private var backing: SecKey - - init(pemRepresentation: String) throws { - let document = try ASN1.PEMDocument(pemString: pemRepresentation) - - switch document.type { - case _RSA.PKCS1KeyType: - // This is what is expected by Security.framework - self = try .init(derRepresentation: document.derBytes) - case _RSA.PKCS8KeyType: - guard let pkcs8Bytes = document.derBytes.pkcs8RSAKeyBytes else { - throw _CryptoRSAError.invalidPEMDocument - } - self = try .init(derRepresentation: pkcs8Bytes) - default: - throw _CryptoRSAError.invalidPEMDocument - } - - } - - init(derRepresentation: Bytes) throws { - let keyAttributes: [CFString: Any] = [ - kSecAttrKeyType: kSecAttrKeyTypeRSA, - kSecAttrKeyClass: kSecAttrKeyClassPrivate, - ] - let data = Data(derRepresentation) - var error: Unmanaged? = nil - - // We can't know in DER if this is PKCS8 or PKCS1 without just trying to decode it. - let keyData: Data - if let pkcs8Data = data.pkcs8RSAKeyBytes { - keyData = pkcs8Data - } else { - keyData = data - } - - let key = SecKeyCreateWithData(keyData as CFData, keyAttributes as CFDictionary, &error) - - guard let unwrappedKey = key else { - // If this returns nil, error must be set. - throw error!.takeRetainedValue() as Error - } - - self.backing = unwrappedKey - } - - init(keySize: _RSA.Signing.KeySize) throws { - let keyAttributes: [CFString: Any] = [ - kSecAttrKeyType: kSecAttrKeyTypeRSA, - kSecAttrKeyClass: kSecAttrKeyClassPrivate, - kSecAttrKeySizeInBits: keySize.bitCount - ] - var error: Unmanaged? = nil - let key = SecKeyCreateRandomKey(keyAttributes as CFDictionary, &error) - - guard let unwrappedKey = key else { - // If this returns nil, error must be set. - throw error!.takeRetainedValue() as Error - } - - self.backing = unwrappedKey - } - - init(_ boringSSLKey: BoringSSLRSAPrivateKey) throws { - try self.init(derRepresentation: boringSSLKey.derRepresentation) - } - - var derRepresentation: Data { - var error: Unmanaged? = nil - let representation = SecKeyCopyExternalRepresentation(self.backing, &error) - return representation! as Data - } - - var pemRepresentation: String { - return ASN1.PEMDocument(type: _RSA.PKCS1KeyType, derBytes: self.derRepresentation).pemString - } - - var pkcs8PEMRepresentation: String { - let pkcs1Bytes = self.derRepresentation - let pkcs8Bytes = Data(privateKeyPKCS8BytesForPKCS1Bytes: pkcs1Bytes) - let pemString = ASN1.PEMDocument(type: _RSA.PKCS8KeyType, derBytes: pkcs8Bytes).pemString - - // The BoringSSL implementation returns this string with a trailing newline. For consistency, - // we'll do the same here. - return pemString.appending("\n") - } - - var keySizeInBits: Int { - SecKeyGetBlockSize(self.backing) * 8 - } - - var publicKey: SecurityRSAPublicKey { - SecurityRSAPublicKey(SecKeyCopyPublicKey(self.backing)!) - } -} - -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -extension SecurityRSAPrivateKey { - internal func signature(for digest: D, padding: _RSA.Signing.Padding) throws -> _RSA.Signing.RSASignature { - let algorithm = try SecKeyAlgorithm(digestType: D.self, padding: padding) - let digestToSign = Data(digest) - var error: Unmanaged? = nil - let sig = SecKeyCreateSignature(self.backing, algorithm, digestToSign as CFData, &error) - - guard let signature = sig else { - // If this returns nil, error must be set. - throw error!.takeRetainedValue() as Error - } - - return _RSA.Signing.RSASignature(rawRepresentation: signature as Data) - } - } - -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) - extension SecurityRSAPrivateKey { - internal func decrypt(_ data: D, padding: _RSA.Encryption.Padding) throws -> Data { - let algorithm = try SecKeyAlgorithm(padding: padding) - let dataToDecrypt = Data(data) - var error: Unmanaged? = nil - let dec = SecKeyCreateDecryptedData(self.backing, algorithm, dataToDecrypt as CFData, &error) - - guard let decrypted = dec else { - throw error!.takeRetainedValue() as Error - } - - return decrypted as Data - } -} - -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -extension SecurityRSAPublicKey { - func isValidSignature(_ signature: _RSA.Signing.RSASignature, for digest: D, padding: _RSA.Signing.Padding) -> Bool { - do { - let algorithm = try SecKeyAlgorithm(digestType: D.self, padding: padding) - let digestToValidate = Data(digest) - var error: Unmanaged? = nil - let result = SecKeyVerifySignature(self.backing, - algorithm, - digestToValidate as CFData, - signature.rawRepresentation as CFData, - &error) - - return result - } catch { - return false - } - } -} - -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -extension SecurityRSAPublicKey { - internal func encrypt(_ data: D, padding: _RSA.Encryption.Padding) throws -> Data { - let algorithm = try SecKeyAlgorithm(padding: padding) - let dataToEncrypt = Data(data) - var error: Unmanaged? = nil - let enc = SecKeyCreateEncryptedData(self.backing, algorithm, dataToEncrypt as CFData, &error) - - guard let encrypted = enc else { - throw error!.takeRetainedValue() as Error - } - - return encrypted as Data - } -} - -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -extension SecKeyAlgorithm { - fileprivate init(digestType: D.Type = D.self, padding: _RSA.Signing.Padding) throws { - switch (digestType, padding.backing) { - case (is Insecure.SHA1.Digest.Type, .pss): - self = .rsaSignatureDigestPSSSHA1 - case (is Insecure.SHA1.Digest.Type, .pkcs1v1_5): - self = .rsaSignatureDigestPKCS1v15SHA1 - case (is SHA256.Digest.Type, .pss): - self = .rsaSignatureDigestPSSSHA256 - case (is SHA256.Digest.Type, .pkcs1v1_5): - self = .rsaSignatureDigestPKCS1v15SHA256 - case (is SHA384.Digest.Type, .pss): - self = .rsaSignatureDigestPSSSHA384 - case (is SHA384.Digest.Type, .pkcs1v1_5): - self = .rsaSignatureDigestPKCS1v15SHA384 - case (is SHA512.Digest.Type, .pss): - self = .rsaSignatureDigestPSSSHA512 - case (is SHA512.Digest.Type, .pkcs1v1_5): - self = .rsaSignatureDigestPKCS1v15SHA512 - case (_, .pssZero): - // Explicitly unsupported: only used in RSABSSA, which is implemented using BoringSSL on all platforms. - throw CryptoKitError.incorrectParameterSize - default: - throw CryptoKitError.incorrectParameterSize - } - } - - fileprivate init(padding: _RSA.Encryption.Padding) throws { - switch padding.backing { - case .pkcs1_oaep(let digest): - switch digest { - case .sha1: - self = .rsaEncryptionOAEPSHA1 - case .sha256: - self = .rsaEncryptionOAEPSHA256 - } - } - } -} - -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -extension Data { - init(_ digest: D) { - self = digest.withUnsafeBytes { Data($0) } - } - - /// A partial PKCS8 DER prefix. This specifically is the version and private key algorithm identifier. - private static let partialPKCS8Prefix = Data( - [ - 0x02, 0x01, 0x00, // Version, INTEGER 0 - 0x30, 0x0d, // SEQUENCE, length 13 - 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, // rsaEncryption OID - 0x05, 0x00 // NULL - ] - ) - - var pkcs8RSAKeyBytes: Data? { - // This is PKCS8. A bit awkward now. Rather than bring over the fully-fledged ASN.1 code from - // the main module and all its dependencies, we have a little hand-rolled verifier. To be a proper - // PKCS8 key, this should match: - // - // PrivateKeyInfo ::= SEQUENCE { - // version Version, - // privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, - // privateKey PrivateKey, - // attributes [0] IMPLICIT Attributes OPTIONAL } - // - // Version ::= INTEGER - // - // PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier - // - // PrivateKey ::= OCTET STRING - // - // Attributes ::= SET OF Attribute - // - // We know the version and algorithm identifier, so we can just strip the bytes we'd expect to see here. We do validate - // them though. - precondition(self.startIndex == 0) - - guard self.count >= 4 + Data.partialPKCS8Prefix.count + 4 else { - return nil - } - - // First byte will be the tag for sequence, 0x30. - guard self[0] == 0x30 else { - return nil - } - - // The next few bytes will be a length. We'll expect it to be 3 bytes long, with the first byte telling us - // that it's 3 bytes long. - let lengthLength = Int(self[1]) - guard lengthLength == 0x82 else { - return nil - } - - let length = Int(self[2]) << 8 | Int(self[3]) - guard length == self.count - 4 else { - return nil - } - - // Now we can check the version through the algorithm identifier against the hardcoded values. - guard self.dropFirst(4).prefix(Data.partialPKCS8Prefix.count) == Data.partialPKCS8Prefix else { - return nil - } - - // Ok, the last check are the next 4 bytes, which should now be the tag for OCTET STRING followed by another length. - guard self[4 + Data.partialPKCS8Prefix.count] == 0x04, - self[4 + Data.partialPKCS8Prefix.count + 1] == 0x82 else { - return nil - } - - let octetStringLength = Int(self[4 + Data.partialPKCS8Prefix.count + 2]) << 8 | - Int(self[4 + Data.partialPKCS8Prefix.count + 3]) - guard octetStringLength == self.count - 4 - Data.partialPKCS8Prefix.count - 4 else { - return nil - } - - return self.dropFirst(4 + Data.partialPKCS8Prefix.count + 4) - } - - // Corresponds to the ASN.1 encoding of the RSA AlgorithmIdentifier: - // - // SEQUENCE of OID (:rsaEncryption) and NULL. - static let rsaAlgorithmIdentifierBytes = Data([ - 0x30, 0x0D, // SEQUENCE, Length 13 - 0x06, 0x09, // OID, length 9 - 0x2A, 0x86 , 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, // 1.2.840.113549.1.1.1 :rsaEncryption - 0x05, 0x00, // NULL, length 0 - - ]) - - fileprivate init(spkiBytesForPKCS1Bytes pkcs1Bytes: Data) { - // This does an ad-hoc SPKI encode. Ideally we'd bring over the entire ASN.1 stack, but it's not worth doing - // for just this one use-case. - let keyLength = (pkcs1Bytes.count + 1) - let bitStringOverhead = 1 + keyLength._bytesNeededToEncodeASN1Length // 1 byte for tag. - let totalLengthOfSequencePayload = Self.rsaAlgorithmIdentifierBytes.count + bitStringOverhead + keyLength - - var bytes = Data() - bytes.reserveCapacity(1 + totalLengthOfSequencePayload._bytesNeededToEncodeASN1Length + totalLengthOfSequencePayload) - - bytes.append(0x30) // SEQUENCE marker. - bytes.appendAsASN1NodeLength(totalLengthOfSequencePayload) - bytes.append(Self.rsaAlgorithmIdentifierBytes) - - bytes.append(0x03) // BITSTRING marker - bytes.appendAsASN1NodeLength(keyLength) - bytes.append(UInt8(0)) // No padding bits - bytes.append(contentsOf: pkcs1Bytes) - - self = bytes - } - - static let pkcs8versionIdentifierBytes = Data([ - 0x02, 0x01, 0x00, // Version, INTEGER 0 - ]) - - fileprivate init(privateKeyPKCS8BytesForPKCS1Bytes pkcs1Bytes: Data) { - // The PKCS8 encoding of a private key is very similar to the - // SPKI encoding of a public key, as implemented in `Data(spkiBytesForPKCS1Bytes:)` above. - // The difference is that PKCS 8 includes a VERSION field, and - // uses an OCTET STREAM instead of a BIT STREAM. - let versionLength = Self.pkcs8versionIdentifierBytes.count - let keyLength = (pkcs1Bytes.count) - let octetStringOverhead = keyLength._bytesNeededToEncodeASN1Length + 1 - let totalLengthOfSequencePayload = versionLength + Self.rsaAlgorithmIdentifierBytes.count + octetStringOverhead + keyLength - - var bytes = Data() - bytes.reserveCapacity(1 + totalLengthOfSequencePayload._bytesNeededToEncodeASN1Length + totalLengthOfSequencePayload) - - bytes.append(0x30) // SEQUENCE marker. - bytes.appendAsASN1NodeLength(totalLengthOfSequencePayload) - bytes.append(Self.pkcs8versionIdentifierBytes) - bytes.append(Self.rsaAlgorithmIdentifierBytes) - - bytes.append(0x04) // OCTET STRING marker - bytes.appendAsASN1NodeLength(keyLength) - bytes.append(contentsOf: pkcs1Bytes) - - self = bytes - } - - fileprivate mutating func appendAsASN1NodeLength(_ length: Int) { - let bytesNeeded = length._bytesNeededToEncodeASN1Length - - if bytesNeeded == 1 { - self.append(UInt8(length)) - } else { - // We first write the number of length bytes - // we need, setting the high bit. Then we write the bytes of the length. - self.append(0x80 | UInt8(bytesNeeded - 1)) - - for shift in (0..<(bytesNeeded - 1)).reversed() { - // Shift and mask the integer. - self.append(UInt8(truncatingIfNeeded: (length >> (shift * 8)))) - } - } - } -} - -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -extension Int { - fileprivate var _bytesNeededToEncodeASN1Length: Int { - // ASN.1 lengths are in two forms. If we can store the length in 7 bits, we should: - // that requires only one byte. Otherwise, we need multiple bytes: work out how many, - // plus one for the length of the length bytes. - if self <= 0x7F { - return 1 - } else { - // We need to work out how many bytes we need. There are many fancy bit-twiddling - // ways of doing this, but honestly we don't do this enough to need them, so we'll - // do it the easy way. This math is done on UInt because it makes the shift semantics clean. - // We save a branch here because we can never overflow this addition. - return UInt(self).neededBytes &+ 1 - } - } -} - -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -extension UInt { - // Bytes needed to store a given integer in 7 bit bytes. - fileprivate var neededBytes: Int { - let neededBits = self.bitWidth - self.leadingZeroBitCount - return (neededBits + 7) / 8 - } -} - -#endif diff --git a/Sources/_CryptoExtras/Util/Data+Extensions.swift b/Sources/_CryptoExtras/Util/Data+Extensions.swift index a0ca7f9d6..4276aa6bc 100644 --- a/Sources/_CryptoExtras/Util/Data+Extensions.swift +++ b/Sources/_CryptoExtras/Util/Data+Extensions.swift @@ -19,9 +19,14 @@ import Foundation #endif extension Data { + // This enhancement can only be present on 6.1 or later because of the + // absence of https://github.com/swiftlang/swift/pull/76186 in older + // compilers. + #if compiler(>=6.1) // This overload reduces allocations when used in a chain of infix operations. static func + (lhs: consuming Data, rhs: consuming Data) -> Data { lhs.append(contentsOf: rhs) return lhs } + #endif } diff --git a/Sources/_CryptoExtras/Util/ThreadSpecific/ThreadOps.swift b/Sources/_CryptoExtras/Util/ThreadSpecific/ThreadOps.swift new file mode 100644 index 000000000..0dc4111f4 --- /dev/null +++ b/Sources/_CryptoExtras/Util/ThreadSpecific/ThreadOps.swift @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2025 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2017-2014 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +protocol ThreadOps { + associatedtype ThreadSpecificKey + associatedtype ThreadSpecificKeyDestructor + + static func allocateThreadSpecificValue(destructor: ThreadSpecificKeyDestructor) -> ThreadSpecificKey + static func deallocateThreadSpecificValue(_ key: ThreadSpecificKey) + static func getThreadSpecificValue(_ key: ThreadSpecificKey) -> UnsafeMutableRawPointer? + static func setThreadSpecificValue(key: ThreadSpecificKey, value: UnsafeMutableRawPointer?) +} diff --git a/Sources/_CryptoExtras/Util/ThreadSpecific/ThreadPosix.swift b/Sources/_CryptoExtras/Util/ThreadSpecific/ThreadPosix.swift new file mode 100644 index 000000000..6b2ccdf09 --- /dev/null +++ b/Sources/_CryptoExtras/Util/ThreadSpecific/ThreadPosix.swift @@ -0,0 +1,73 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2025 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2020 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if os(Linux) || os(Android) || os(FreeBSD) || canImport(Darwin) +#if canImport(Glibc) +@preconcurrency import Glibc +#elseif canImport(Bionic) +@preconcurrency import Bionic +#elseif canImport(Musl) +@preconcurrency import Musl +#elseif canImport(Android) +@preconcurrency import Android +#elseif canImport(Darwin) +import Darwin +#endif + +typealias ThreadOpsSystem = ThreadOpsPosix + +enum ThreadOpsPosix: ThreadOps { + typealias ThreadSpecificKey = pthread_key_t + #if canImport(Darwin) + typealias ThreadSpecificKeyDestructor = @convention(c) (UnsafeMutableRawPointer) -> Void + #else + typealias ThreadSpecificKeyDestructor = @convention(c) (UnsafeMutableRawPointer?) -> Void + #endif + + static func allocateThreadSpecificValue(destructor: @escaping ThreadSpecificKeyDestructor) -> ThreadSpecificKey { + var value = pthread_key_t() + let result = pthread_key_create(&value, Optional(destructor)) + precondition(result == 0, "pthread_key_create failed: \(result)") + return value + } + + static func deallocateThreadSpecificValue(_ key: ThreadSpecificKey) { + let result = pthread_key_delete(key) + precondition(result == 0, "pthread_key_delete failed: \(result)") + } + + static func getThreadSpecificValue(_ key: ThreadSpecificKey) -> UnsafeMutableRawPointer? { + pthread_getspecific(key) + } + + static func setThreadSpecificValue(key: ThreadSpecificKey, value: UnsafeMutableRawPointer?) { + let result = pthread_setspecific(key, value) + precondition(result == 0, "pthread_setspecific failed: \(result)") + } +} + +#endif diff --git a/Sources/_CryptoExtras/Util/ThreadSpecific/ThreadSpecific.swift b/Sources/_CryptoExtras/Util/ThreadSpecific/ThreadSpecific.swift new file mode 100644 index 000000000..96eb7100b --- /dev/null +++ b/Sources/_CryptoExtras/Util/ThreadSpecific/ThreadSpecific.swift @@ -0,0 +1,111 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2019-2025 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +// Derived from swift-nio's ThreadSpecificVariable type. + +/// A ``ThreadSpecificVariable`` is a variable that can be read and set like a normal variable except that it holds +/// different variables per thread. +/// +/// ``ThreadSpecificVariable`` is thread-safe so it can be used with multiple threads at the same time but the value +/// returned by ``currentValue`` is defined per thread. +/// +/// - Note: Though ``ThreadSpecificVariable`` is thread-safe, it is not `Sendable` unless `Value` is `Sendable`. +/// If ``ThreadSpecificVariable`` were unconditionally `Sendable`, it could be used to "smuggle" +/// non-`Sendable` state out of an actor or other isolation domain without triggering warnings. If you +/// are attempting to use ``ThreadSpecificVariable`` with non-`Sendable` data, consider using a dynamic +/// enforcement tool like `NIOLoopBoundBox` to police the access. +final class ThreadSpecificVariable { + // the actual type in there is `Box<(ThreadSpecificVariable, T)>` but we can't use that as C functions can't capture (even types) + private typealias BoxedType = Box<(AnyObject, AnyObject)> + + private class Key { + private var underlyingKey: ThreadOpsSystem.ThreadSpecificKey + + internal init(destructor: @escaping ThreadOpsSystem.ThreadSpecificKeyDestructor) { + self.underlyingKey = ThreadOpsSystem.allocateThreadSpecificValue(destructor: destructor) + } + + deinit { + ThreadOpsSystem.deallocateThreadSpecificValue(self.underlyingKey) + } + + func get() -> UnsafeMutableRawPointer? { + ThreadOpsSystem.getThreadSpecificValue(self.underlyingKey) + } + + func set(value: UnsafeMutableRawPointer?) { + ThreadOpsSystem.setThreadSpecificValue(key: self.underlyingKey, value: value) + } + } + + private let key: Key + + /// Initialize a new `ThreadSpecificVariable` without a current value (`currentValue == nil`). + init() { + self.key = Key(destructor: { + Unmanaged.fromOpaque(($0 as UnsafeMutableRawPointer?)!).release() + }) + } + + /// Initialize a new `ThreadSpecificVariable` with `value` for the calling thread. After calling this, the calling + /// thread will see `currentValue == value` but on all other threads `currentValue` will be `nil` until changed. + /// + /// - Parameters: + /// - value: The value to set for the calling thread. + convenience init(value: Value) { + self.init() + self.currentValue = value + } + + /// The value for the current thread. + @available( + *, + noasync, + message: "threads can change between suspension points and therefore the thread specific value too" + ) + var currentValue: Value? { + get { + self.get() + } + set { + self.set(newValue) + } + } + + /// Get the current value for the calling thread. + private func get() -> Value? { + guard let raw = self.key.get() else { return nil } + // parenthesize the return value to silence the cast warning + return + (Unmanaged + .fromOpaque(raw) + .takeUnretainedValue() + .value.1 as! Value) + } + + /// Set the current value for the calling threads. The `currentValue` for all other threads remains unchanged. + private func set(_ newValue: Value?) { + if let raw = self.key.get() { + Unmanaged.fromOpaque(raw).release() + } + self.key.set(value: newValue.map { Unmanaged.passRetained(Box((self, $0))).toOpaque() }) + } +} + +extension ThreadSpecificVariable: @unchecked Sendable where Value: Sendable {} + +final class Box { + let value: T + init(_ value: T) { self.value = value } +} diff --git a/Sources/_CryptoExtras/Util/ThreadSpecific/ThreadWindows.swift b/Sources/_CryptoExtras/Util/ThreadSpecific/ThreadWindows.swift new file mode 100644 index 000000000..6cbacedd7 --- /dev/null +++ b/Sources/_CryptoExtras/Util/ThreadSpecific/ThreadWindows.swift @@ -0,0 +1,56 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2025 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2020 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if os(Windows) + +import WinSDK + +typealias ThreadOpsSystem = ThreadOpsWindows + +enum ThreadOpsWindows: ThreadOps { + typealias ThreadSpecificKey = DWORD + typealias ThreadSpecificKeyDestructor = @convention(c) (UnsafeMutableRawPointer?) -> Void + + static func allocateThreadSpecificValue(destructor: @escaping ThreadSpecificKeyDestructor) -> ThreadSpecificKey { + FlsAlloc(destructor) + } + + static func deallocateThreadSpecificValue(_ key: ThreadSpecificKey) { + let dwResult: Bool = FlsFree(key) + precondition(dwResult, "FlsFree: \(GetLastError())") + } + + static func getThreadSpecificValue(_ key: ThreadSpecificKey) -> UnsafeMutableRawPointer? { + FlsGetValue(key) + } + + static func setThreadSpecificValue(key: ThreadSpecificKey, value: UnsafeMutableRawPointer?) { + FlsSetValue(key, value) + } +} + +#endif diff --git a/Tests/_CryptoExtrasTests/AES_CBCTests.swift b/Tests/_CryptoExtrasTests/AES_CBCTests.swift index b2ba34eaa..c2a9a5eed 100644 --- a/Tests/_CryptoExtrasTests/AES_CBCTests.swift +++ b/Tests/_CryptoExtrasTests/AES_CBCTests.swift @@ -162,6 +162,14 @@ final class CBCTests: XCTestCase { } } } + + func testToDataConversion() throws { + let randomBytes = (0..<16).map { _ in UInt8.random(in: UInt8.min...UInt8.max) } + let dataIn = Data(randomBytes) + let iv = try AES._CBC.IV(ivBytes: dataIn) + let dataOut = Data(iv) + XCTAssertEqual(dataIn, dataOut) + } } diff --git a/Tests/_CryptoExtrasTests/ARC/ARCAPITests.swift b/Tests/_CryptoExtrasTests/ARC/ARCAPITests.swift index ddc22dc56..2a6f0f88b 100644 --- a/Tests/_CryptoExtrasTests/ARC/ARCAPITests.swift +++ b/Tests/_CryptoExtrasTests/ARC/ARCAPITests.swift @@ -18,17 +18,24 @@ import XCTest @available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) final class ARCAPITests: XCTestCase { + @available(*, deprecated, message: "ARC(P-384) has been removed from the IETF draft; use ARC(P-256) instead.") func testVectors() throws { let data = ARCEncodedTestVector.data(using: .utf8)! let decoder = JSONDecoder() - for vector in try decoder.decode([ARCTestVector].self, from: data) { - try testVector(vector) + let vectors = try decoder.decode([ARCTestVector].self, from: data) + XCTAssert(vectors.count > 0, "No test vectors found") + for vector in vectors { + switch vector.suite { + case "ARCV1-P256": try testVector(vector, using: P256.self) + case "ARCV1-P384": try testVector(vector, using: P384.self) + default: XCTFail("Test vector suite not supported: \(vector.suite)") + } } } - func testVector(_ vector: ARCTestVector) throws { + fileprivate func testVector(_ vector: ARCTestVector, using _: Curve.Type = Curve.self) throws { // [Issuer] Create the server secrets. - let privateKey = try P384._ARCV1.PrivateKey(rawRepresentation: Data( + let privateKey = try Curve._ARCV1.PrivateKey(rawRepresentation: Data( hexString: vector.ServerKey.x0 + vector.ServerKey.x1 + vector.ServerKey.x2 + vector.ServerKey.xb )) @@ -52,14 +59,14 @@ final class ARCAPITests: XCTestCase { _ = (publicKeyBytes, requestContext, presentationContext, presentationLimit) // [Client] Obtain public key out of band (other serializations may be available). - let publicKey = try P384._ARCV1.PublicKey(rawRepresentation: publicKeyBytes) + let publicKey = try Curve._ARCV1.PublicKey(rawRepresentation: publicKeyBytes) // [Client] Prepare a credential request using fixed values from test vector. let precredential = try publicKey.prepareCredentialRequest( requestContext: requestContext, - m1: P384._ARCV1.H2G.G.Scalar(bytes: Data(hexString: vector.CredentialRequest.m1)), - r1: P384._ARCV1.H2G.G.Scalar(bytes: Data(hexString: vector.CredentialRequest.r1)), - r2: P384._ARCV1.H2G.G.Scalar(bytes: Data(hexString: vector.CredentialRequest.r2)) + m1: Curve._ARCV1.H2G.G.Scalar(bytes: Data(hexString: vector.CredentialRequest.m1)), + r1: Curve._ARCV1.H2G.G.Scalar(bytes: Data(hexString: vector.CredentialRequest.r1)), + r2: Curve._ARCV1.H2G.G.Scalar(bytes: Data(hexString: vector.CredentialRequest.r2)) ) // [Client -> Issuer] Send the credential request. @@ -67,17 +74,17 @@ final class ARCAPITests: XCTestCase { // [CHECK] Credential request scalars match test vector. XCTAssertEqual( - credentialRequestBytes[..<(2 * P384.compressedx962PointByteCount)].hexString, + credentialRequestBytes[..<(2 * Curve.compressedx962PointByteCount)].hexString, vector.CredentialRequest.m1_enc + vector.CredentialRequest.m2_enc ) // [Issuer] Receive the credential request. - let credentialRequest = try P384._ARCV1.CredentialRequest(rawRepresentation: credentialRequestBytes) + let credentialRequest = try Curve._ARCV1.CredentialRequest(rawRepresentation: credentialRequestBytes) // [Issuer] Generate a credential response with fixed value from test vector. let credentialResponse = try privateKey.issue( credentialRequest, - b: P384._ARCV1.H2G.G.Scalar(bytes: Data(hexString: vector.CredentialResponse.b)) + b: Curve._ARCV1.H2G.G.Scalar(bytes: Data(hexString: vector.CredentialResponse.b)) ) // [Issuer -> Client] Send the credential response. @@ -85,7 +92,7 @@ final class ARCAPITests: XCTestCase { // [CHECK] Credential response scalars match test vector, excluding proof. XCTAssertEqual( - credentialResponseBytes[..<(6 * P384.compressedx962PointByteCount)].hexString, + credentialResponseBytes[..<(6 * Curve.compressedx962PointByteCount)].hexString, vector.CredentialResponse.U + vector.CredentialResponse.enc_U_prime + vector.CredentialResponse.X0_aux @@ -95,7 +102,7 @@ final class ARCAPITests: XCTestCase { ) // [Client] Receive the credential response. - let _ = try P384._ARCV1.CredentialResponse(rawRepresentation: credentialResponseBytes) + let _ = try Curve._ARCV1.CredentialResponse(rawRepresentation: credentialResponseBytes) // [Client] Generate a credential. var credential = try publicKey.finalize(credentialResponse, for: precredential) @@ -111,9 +118,9 @@ final class ARCAPITests: XCTestCase { context: presentationContext, presentationLimit: presentationLimit, fixedNonce: Int(vector.Presentation1.nonce.dropFirst(2), radix: 16)!, - a: P384._ARCV1.H2G.G.Scalar(bytes: Data(hexString: vector.Presentation1.a)), - r: P384._ARCV1.H2G.G.Scalar(bytes: Data(hexString: vector.Presentation1.r)), - z: P384._ARCV1.H2G.G.Scalar(bytes: Data(hexString: vector.Presentation1.z)) + a: Curve._ARCV1.H2G.G.Scalar(bytes: Data(hexString: vector.Presentation1.a)), + r: Curve._ARCV1.H2G.G.Scalar(bytes: Data(hexString: vector.Presentation1.r)), + z: Curve._ARCV1.H2G.G.Scalar(bytes: Data(hexString: vector.Presentation1.z)) ) // NOTE: The presentation proof depends on randomly generated blinding factors. This layer doesn't expose @@ -135,14 +142,14 @@ final class ARCAPITests: XCTestCase { // [CHECK]: Serialization of presentation (ecluding proof) matches spec. XCTAssertEqual( - presentation.rawRepresentation[..<(4 * P384.compressedx962PointByteCount)].hexString, + presentation.rawRepresentation[..<(4 * Curve.compressedx962PointByteCount)].hexString, vector.Presentation1.U + vector.Presentation1.U_prime_commit + vector.Presentation1.m1_commit + vector.Presentation1.tag ) XCTAssertEqual( - presentation.rawRepresentation[(4 * P384.compressedx962PointByteCount)...].hexString.count, + presentation.rawRepresentation[(4 * Curve.compressedx962PointByteCount)...].hexString.count, vector.Presentation1.proof.count ) @@ -155,12 +162,12 @@ final class ARCAPITests: XCTestCase { + vector.Presentation1.proof ) XCTAssertEqual( - try P384._ARCV1.Presentation(rawRepresentation: testVectorPresentationBytes).rawRepresentation.hexString, + try Curve._ARCV1.Presentation(rawRepresentation: testVectorPresentationBytes).rawRepresentation.hexString, testVectorPresentationBytes.hexString ) // [Verifier] Receive the presentation (and the nonce, out of band). - let receivedPresentation = try P384._ARCV1.Presentation(rawRepresentation: testVectorPresentationBytes) + let receivedPresentation = try Curve._ARCV1.Presentation(rawRepresentation: testVectorPresentationBytes) let nonce = Int(vector.Presentation1.nonce.dropFirst(2), radix: 16)! // [Verifier] Verify the presentation. @@ -174,3 +181,172 @@ final class ARCAPITests: XCTestCase { XCTAssertTrue(validPresentation) } } + +// MARK: - Fileprivate protocols to create a unified test over the ARC curves. + +fileprivate protocol ARCCredentialRequest { + init(rawRepresentation: some DataProtocol) throws + var rawRepresentation: Data { get } +} + +fileprivate protocol ARCCredentialResponse { + init(rawRepresentation: some DataProtocol) throws + var rawRepresentation: Data { get } +} + +@available(macOS 10.15, iOS 13.2, tvOS 13.2, watchOS 6.1, macCatalyst 13.2, visionOS 1.2, *) +fileprivate protocol ARCPresentation { + associatedtype H2G: HashToGroup + var backing: ARC.Presentation { get } + init(rawRepresentation: some DataProtocol) throws + var rawRepresentation: Data { get } +} + +@available(macOS 10.15, iOS 13.2, tvOS 13.2, watchOS 6.1, macCatalyst 13.2, visionOS 1.2, *) +fileprivate protocol ARCCredential { + associatedtype H2G: HashToGroup + associatedtype Presentation: ARCPresentation + var backing: ARC.Credential { get } + mutating func makePresentation( + context: some DataProtocol, + presentationLimit: Int, + fixedNonce: Int?, + a: H2G.G.Scalar, + r: H2G.G.Scalar, + z: H2G.G.Scalar + ) throws -> (presentation: Presentation, nonce: Int) + mutating func makePresentation(context: some DataProtocol, presentationLimit: Int) throws -> (presentation: Presentation, nonce: Int) +} + +@available(macOS 10.15, iOS 13.2, tvOS 13.2, watchOS 6.1, macCatalyst 13.2, visionOS 1.2, *) +fileprivate protocol ARCPrivateKey { + associatedtype H2G: HashToGroup + associatedtype Credential + associatedtype PublicKey: ARCPublicKey + associatedtype CredentialRequest: ARCCredentialRequest + associatedtype CredentialResponse: ARCCredentialResponse + associatedtype Presentation: ARCPresentation + init(rawRepresentation: some DataProtocol) throws + var rawRepresentation: Data { get } + var publicKey: PublicKey { get } + func issue(_ credentialRequest: CredentialRequest, b: H2G.G.Scalar) throws -> CredentialResponse + func verify( + _: Presentation, + requestContext: some DataProtocol, + presentationContext: some DataProtocol, + presentationLimit: Int, + nonce: Int + ) throws -> Bool +} + +@available(macOS 10.15, iOS 13.2, tvOS 13.2, watchOS 6.1, macCatalyst 13.2, visionOS 1.2, *) +fileprivate protocol ARCPublicKey { + associatedtype H2G: HashToGroup + associatedtype Precredential: ARCPrecredential + associatedtype CredentialResponse: ARCCredentialResponse + associatedtype Credential: ARCCredential + init(rawRepresentation: some DataProtocol) throws + var rawRepresentation: Data { get } + func prepareCredentialRequest(requestContext: some DataProtocol, m1: H2G.G.Scalar, r1: H2G.G.Scalar, r2: H2G.G.Scalar) throws -> Precredential + func prepareCredentialRequest(requestContext: some DataProtocol) throws -> Precredential + func finalize(_ credentialResponse: CredentialResponse, for precredential: Precredential) throws -> Credential +} + +fileprivate protocol ARCPrecredential { + associatedtype CredentialRequest: ARCCredentialRequest + var credentialRequest: CredentialRequest { get } +} + +@available(macOS 10.15, iOS 13.2, tvOS 13.2, watchOS 6.1, macCatalyst 13.2, visionOS 1.2, *) +fileprivate protocol ARCV1 { + associatedtype H2G: HashToGroup + associatedtype CredentialRequest: ARCCredentialRequest + associatedtype CredentialResponse: ARCCredentialResponse + associatedtype Presentation: ARCPresentation + associatedtype Credential: ARCCredential + associatedtype PrivateKey: ARCPrivateKey + associatedtype PublicKey: ARCPublicKey +} + +@available(macOS 10.15, iOS 13.2, tvOS 13.2, watchOS 6.1, macCatalyst 13.2, visionOS 1.2, *) +fileprivate protocol ARCCurve: OpenSSLSupportedNISTCurve { + associatedtype H2G: HashToGroup where H2G == OpenSSLHashToCurve + associatedtype _ARCV1: ARCV1 +} + +@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) +extension P256._ARCV1.Precredential: ARCPrecredential {} +@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) +extension P256._ARCV1.CredentialRequest: ARCCredentialRequest {} +@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) +extension P256._ARCV1.CredentialResponse: ARCCredentialResponse {} +@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) +extension P256._ARCV1.Credential: ARCCredential {} +@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) +extension P256._ARCV1.Presentation: ARCPresentation {} +@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) +extension P256._ARCV1.PublicKey: ARCPublicKey { + typealias H2G = P256._ARCV1.H2G +} +@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) +extension P256._ARCV1.PrivateKey: ARCPrivateKey {} +@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) +extension P256._ARCV1: ARCV1 {} +@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) +extension P256: ARCCurve {} + + +@available(*, deprecated, message: "ARC(P-384) has been removed from the IETF draft; use ARC(P-256) instead.") +@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) +extension P384._ARCV1.Precredential: ARCPrecredential {} +@available(*, deprecated, message: "ARC(P-384) has been removed from the IETF draft; use ARC(P-256) instead.") +@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) +extension P384._ARCV1.CredentialRequest: ARCCredentialRequest {} +@available(*, deprecated, message: "ARC(P-384) has been removed from the IETF draft; use ARC(P-256) instead.") +@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) +extension P384._ARCV1.CredentialResponse: ARCCredentialResponse {} +@available(*, deprecated, message: "ARC(P-384) has been removed from the IETF draft; use ARC(P-256) instead.") +@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) +extension P384._ARCV1.Credential: ARCCredential {} +@available(*, deprecated, message: "ARC(P-384) has been removed from the IETF draft; use ARC(P-256) instead.") +@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) +extension P384._ARCV1.Presentation: ARCPresentation {} +@available(*, deprecated, message: "ARC(P-384) has been removed from the IETF draft; use ARC(P-256) instead.") +@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) +extension P384._ARCV1.PublicKey: ARCPublicKey { + typealias H2G = P384._ARCV1.H2G +} +@available(*, deprecated, message: "ARC(P-384) has been removed from the IETF draft; use ARC(P-256) instead.") +@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) +extension P384._ARCV1.PrivateKey: ARCPrivateKey {} +@available(*, deprecated, message: "ARC(P-384) has been removed from the IETF draft; use ARC(P-256) instead.") +@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) +extension P384._ARCV1: ARCV1 {} +@available(*, deprecated, message: "ARC(P-384) has been removed from the IETF draft; use ARC(P-256) instead.") +@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) +extension P384: ARCCurve {} + + +// Swift 5.10 compiler needs a little more help to infer the conformances. +#if swift(<6.0) +@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) +fileprivate extension P256._ARCV1.PrivateKey { + typealias H2G = P256._ARCV1.H2G + typealias Credential = P256._ARCV1.Credential + typealias PublicKey = P256._ARCV1.PublicKey + typealias CredentialRequest = P256._ARCV1.CredentialRequest + typealias CredentialResponse = P256._ARCV1.CredentialResponse + typealias Presentation = P256._ARCV1.Presentation +} + +@available(*, deprecated, message: "ARC(P-384) has been removed from the IETF draft; use ARC(P-256) instead.") +@available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) +fileprivate extension P384._ARCV1.PrivateKey { + typealias H2G = P384._ARCV1.H2G + typealias Credential = P384._ARCV1.Credential + typealias PublicKey = P384._ARCV1.PublicKey + typealias CredentialRequest = P384._ARCV1.CredentialRequest + typealias CredentialResponse = P384._ARCV1.CredentialResponse + typealias Presentation = P384._ARCV1.Presentation +} +#endif diff --git a/Tests/_CryptoExtrasTests/ARC/ARCEncodingTests.swift b/Tests/_CryptoExtrasTests/ARC/ARCEncodingTests.swift index a02a84716..c65a6aa24 100644 --- a/Tests/_CryptoExtrasTests/ARC/ARCEncodingTests.swift +++ b/Tests/_CryptoExtrasTests/ARC/ARCEncodingTests.swift @@ -17,30 +17,35 @@ import Crypto @available(macOS 10.15, iOS 13.2, tvOS 13.2, watchOS 6.1, macCatalyst 13.2, visionOS 1.2, *) class ARCEncodingTests: XCTestCase { - func testserverPublicKeyEncoding() throws { - let ciphersuite = ARC.Ciphersuite(HashToCurveImpl.self) + func serverPublicKeyEncoding(CurveType _: Curve.Type) throws { + let ciphersuite = ARC.Ciphersuite(HashToCurveImpl.self) let server = ARC.Server(ciphersuite: ciphersuite) let publicKey = server.serverPublicKey - let publicKeyData = publicKey.serialize() - let publicKey2 = try ARC.ServerPublicKey.deserialize(serverPublicKeyData: publicKeyData) + let publicKeyData = publicKey.serialize(ciphersuite: ciphersuite) + let publicKey2 = try ARC.ServerPublicKey.deserialize(serverPublicKeyData: publicKeyData, ciphersuite: ciphersuite) XCTAssert(publicKey.X0 == publicKey2.X0) XCTAssert(publicKey.X1 == publicKey2.X1) XCTAssert(publicKey.X2 == publicKey2.X2) - let publicKeyData2 = publicKey2.serialize() + let publicKeyData2 = publicKey2.serialize(ciphersuite: ciphersuite) XCTAssertEqual(publicKeyData, publicKeyData2) } - func testRequestEncoding() throws { - let ciphersuite = ARC.Ciphersuite(HashToCurveImpl.self) + func testServerPublicKeyEncoding() throws { + try serverPublicKeyEncoding(CurveType: P256.self) + try serverPublicKeyEncoding(CurveType: P384.self) + } + + func requestEncoding(CurveType _: Curve.Type) throws { + let ciphersuite = ARC.Ciphersuite(HashToCurveImpl.self) let server = ARC.Server(ciphersuite: ciphersuite) let requestContext = Data("test request context".utf8) let precredential = try ARC.Precredential(ciphersuite: ciphersuite, requestContext: requestContext, serverPublicKey: server.serverPublicKey) let request = precredential.credentialRequest - let requestData = request.serialize() - let request2 = try ARC.CredentialRequest.deserialize(requestData: requestData) + let requestData = request.serialize(ciphersuite: ciphersuite) + let request2 = try ARC.CredentialRequest.deserialize(requestData: requestData, ciphersuite: ciphersuite) XCTAssert(request.m1Enc == request2.m1Enc) XCTAssert(request.m2Enc == request2.m2Enc) XCTAssert(request.proof.challenge == request2.proof.challenge) @@ -48,20 +53,25 @@ class ARCEncodingTests: XCTestCase { XCTAssert(response == request2.proof.responses[index]) } - let requestData2 = request2.serialize() + let requestData2 = request2.serialize(ciphersuite: ciphersuite) XCTAssertEqual(requestData, requestData2) } - func testResponseEncoding() throws { - let ciphersuite = ARC.Ciphersuite(HashToCurveImpl.self) + func testRequestEncoding() throws { + try requestEncoding(CurveType: P256.self) + try requestEncoding(CurveType: P384.self) + } + + func responseEncoding(CurveType _: Curve.Type) throws { + let ciphersuite = ARC.Ciphersuite(HashToCurveImpl.self) let server = ARC.Server(ciphersuite: ciphersuite) let requestContext = Data("test request context".utf8) let precredential = try ARC.Precredential(ciphersuite: ciphersuite, requestContext: requestContext, serverPublicKey: server.serverPublicKey) let request = precredential.credentialRequest let response = try server.respond(credentialRequest: request) - let responseData = response.serialize() - let response2 = try ARC.CredentialResponse.deserialize(responseData: responseData) + let responseData = response.serialize(ciphersuite: ciphersuite) + let response2 = try ARC.CredentialResponse.deserialize(responseData: responseData, ciphersuite: ciphersuite) XCTAssert(response.U == response2.U) XCTAssert(response.encUPrime == response2.encUPrime) XCTAssert(response.X0Aux == response2.X0Aux) @@ -73,12 +83,17 @@ class ARCEncodingTests: XCTestCase { XCTAssert(response == response2.proof.responses[index]) } - let responseData2 = response2.serialize() + let responseData2 = response2.serialize(ciphersuite: ciphersuite) XCTAssertEqual(responseData, responseData2) } - func testCredentialEncoding() throws { - let ciphersuite = ARC.Ciphersuite(HashToCurveImpl.self) + func testResponseEncoding() throws { + try responseEncoding(CurveType: P256.self) + try responseEncoding(CurveType: P384.self) + } + + func credentialEncoding(CurveType _: Curve.Type) throws { + let ciphersuite = ARC.Ciphersuite(HashToCurveImpl.self) let server = ARC.Server(ciphersuite: ciphersuite) let requestContext = Data("test request context".utf8) let precredential = try ARC.Precredential(ciphersuite: ciphersuite, requestContext: requestContext, serverPublicKey: server.serverPublicKey) @@ -86,8 +101,8 @@ class ARCEncodingTests: XCTestCase { let response = try server.respond(credentialRequest: request) let credential = try precredential.makeCredential(credentialResponse: response) - let credentialData = try credential.serialize() - let credential2 = try ARC.Credential.deserialize(credentialData: credentialData) + let credentialData = try credential.serialize(ciphersuite: ciphersuite) + let credential2 = try ARC.Credential.deserialize(credentialData: credentialData, ciphersuite: ciphersuite) XCTAssert(credential.m1 == credential2.m1) XCTAssert(credential.U == credential2.U) XCTAssert(credential.UPrime == credential2.UPrime) @@ -99,12 +114,17 @@ class ARCEncodingTests: XCTestCase { XCTAssertEqual(value.1, credential2.presentationState.state[key]?.1) } - let credentialData2 = try credential2.serialize() + let credentialData2 = try credential2.serialize(ciphersuite: ciphersuite) XCTAssertEqual(credentialData, credentialData2) } - func testPresentationEncoding() throws { - let ciphersuite = ARC.Ciphersuite(HashToCurveImpl.self) + func testCredentialEncoding() throws { + try credentialEncoding(CurveType: P256.self) + try credentialEncoding(CurveType: P384.self) + } + + func presentationEncoding(CurveType _: Curve.Type) throws { + let ciphersuite = ARC.Ciphersuite(HashToCurveImpl.self) let server = ARC.Server(ciphersuite: ciphersuite) let requestContext = Data("test request context".utf8) let precredential = try ARC.Precredential(ciphersuite: ciphersuite, requestContext: requestContext, serverPublicKey: server.serverPublicKey) @@ -113,8 +133,8 @@ class ARCEncodingTests: XCTestCase { var credential = try precredential.makeCredential(credentialResponse: response) let (presentation, _) = try credential.makePresentation(presentationContext: Data("test presentation context".utf8), presentationLimit: 1) - let presentationData = presentation.serialize() - let presentation2 = try ARC.Presentation.deserialize(presentationData: presentationData) + let presentationData = presentation.serialize(ciphersuite: ciphersuite) + let presentation2 = try ARC.Presentation.deserialize(presentationData: presentationData, ciphersuite: ciphersuite) XCTAssert(presentation.U == presentation2.U) XCTAssert(presentation.UPrimeCommit == presentation2.UPrimeCommit) XCTAssert(presentation.m1Commit == presentation2.m1Commit) @@ -124,10 +144,15 @@ class ARCEncodingTests: XCTestCase { XCTAssert(response == presentation2.proof.responses[index]) } - let presentationData2 = presentation2.serialize() + let presentationData2 = presentation2.serialize(ciphersuite: ciphersuite) XCTAssertEqual(presentationData, presentationData2) } + func testPresentationEncoding() throws { + try presentationEncoding(CurveType: P256.self) + try presentationEncoding(CurveType: P384.self) + } + func testPresentationStateEncoding() throws { let emptyPresentationState = ARC.PresentationState() let smallPresentationState = ARC.PresentationState(state: [Data("context1".utf8): (4, [1, 2, 3]), Data("context2".utf8): (10, [4, 5, 6])]) diff --git a/Tests/_CryptoExtrasTests/ARC/ARCPublicAPITests.swift b/Tests/_CryptoExtrasTests/ARC/ARCPublicAPITests.swift index 112e4c1e0..411e1066c 100644 --- a/Tests/_CryptoExtrasTests/ARC/ARCPublicAPITests.swift +++ b/Tests/_CryptoExtrasTests/ARC/ARCPublicAPITests.swift @@ -20,7 +20,7 @@ final class ARCPublicAPITests: XCTestCase { func testARCEndToEnd() throws { // [Issuer] Create the server secrets (other initializers will be available). - let privateKey = P384._ARCV1.PrivateKey() + let privateKey = P256._ARCV1.PrivateKey() // [Issuer] Serialize public key to share with client (other serializations may be available). let publicKeyBytes = privateKey.publicKey.rawRepresentation @@ -35,7 +35,7 @@ final class ARCPublicAPITests: XCTestCase { _ = (publicKeyBytes, requestContext, presentationContext, presentationLimit) // [Client] Obtain public key out of band (other serializations may be available). - let publicKey = try P384._ARCV1.PublicKey(rawRepresentation: publicKeyBytes) + let publicKey = try P256._ARCV1.PublicKey(rawRepresentation: publicKeyBytes) // [Client] Prepare a credential request. let precredential = try publicKey.prepareCredentialRequest(requestContext: requestContext) @@ -44,7 +44,7 @@ final class ARCPublicAPITests: XCTestCase { let credentialRequestBytes = precredential.credentialRequest.rawRepresentation // [Issuer] Receive the credential request. - let credentialRequest = try P384._ARCV1.CredentialRequest(rawRepresentation: credentialRequestBytes) + let credentialRequest = try P256._ARCV1.CredentialRequest(rawRepresentation: credentialRequestBytes) // [Issuer] Generate a credential response. let credentialResponse = try privateKey.issue(credentialRequest) @@ -53,7 +53,7 @@ final class ARCPublicAPITests: XCTestCase { let credentialResponseBytes = credentialResponse.rawRepresentation // [Client] Receive the credential response. - let _ = try P384._ARCV1.CredentialResponse(rawRepresentation: credentialResponseBytes) + let _ = try P256._ARCV1.CredentialResponse(rawRepresentation: credentialResponseBytes) // [Client] Generate a credential. // NOTE: This is a var because it enforces the presentation limits for each presentation prefix. @@ -70,7 +70,7 @@ final class ARCPublicAPITests: XCTestCase { let presentationBytes = presentation.rawRepresentation // [Verifier] Receive the presentation. - let _ = try P384._ARCV1.Presentation(rawRepresentation: presentationBytes) + let _ = try P256._ARCV1.Presentation(rawRepresentation: presentationBytes) // [Verifier] Verify the presentation. let validPresentation = try privateKey.verify( @@ -87,7 +87,7 @@ final class ARCPublicAPITests: XCTestCase { } func testCrendentialEnforcesPresentationLimitLocally() throws { - let privateKey = P384._ARCV1.PrivateKey() + let privateKey = P256._ARCV1.PrivateKey() let publicKey = privateKey.publicKey let requestContext = Data("shared request context".utf8) let presentationContext = Data("shared presentation context".utf8) diff --git a/Tests/_CryptoExtrasTests/ARC/ARCTestVectors.swift b/Tests/_CryptoExtrasTests/ARC/ARCTestVectors.swift index d5fefcca8..b8b43556d 100644 --- a/Tests/_CryptoExtrasTests/ARC/ARCTestVectors.swift +++ b/Tests/_CryptoExtrasTests/ARC/ARCTestVectors.swift @@ -17,6 +17,68 @@ import XCTest let ARCEncodedTestVector = """ [ + { + "Credential": { + "U": "033ee1ebbcff622bc26b10932ed1eb147226d832048fb2337dc0ad7722cb07483d", + "U_prime": "02637fe04cc143281ee607bd8f898e670293dce44a2840b9cbb9e0d1fc7a2b29b4", + "X1": "03c413230a9bd956718aa46138a33f774f4c708d61c1d6400d404243049d4a31dc", + "m1": "eedfe7939e2382934ab5b0f76aae44124955d2c5ebf9b41d88786259c34692d2" + }, + "CredentialRequest": { + "m1": "eedfe7939e2382934ab5b0f76aae44124955d2c5ebf9b41d88786259c34692d2", + "m1_enc": "03b8f11506a5302424143573e087fa20195cb5e893a67ef354eae3a78e263c54e4", + "m2": "911fb315257d9ae29d47ecb48c6fa27074dee6860a0489f8db6ac9a486be6a3e", + "m2_enc": "03f1ae4d7b78ba8030bd63859d4f4a909395c52bda34716b6620a2fdd52b336fc9", + "proof": "0f361327abbc724ff0d37db365065bc4bd60e18125842bb4c03a7e5a632a1e95e74dcc440fcb9fb39106922e0d2544e6c82ca710abf35e8b10bf5d61296c9adb7d683eaed9a76a755b73f2b4b6e763a7c7883ce4b5c21bd02cd96b9af18cfb227f1acb4ead77c85049d291ed7841405610843f163e9cc2f6a8869111582324cd32bf13000c129d274ccf5386cb90e839916d5dff7eade18e3eabec415f613911", + "r1": "008035081690bfde3b1e68b91443c22cc791d244340fe957d5aa44d7313740df", + "r2": "d59c5e6ff560cc597c2b8ca25256c720bceca2ab03921492c5e9e4ad3b558002", + "request_context": "74657374207265717565737420636f6e74657874" + }, + "CredentialResponse": { + "H_aux": "03d3cd09eeb8d19716586a49260c69309c495a717a36cad3381f6c02ac80b70e64", + "U": "033ee1ebbcff622bc26b10932ed1eb147226d832048fb2337dc0ad7722cb07483d", + "X0_aux": "02d453c121324114367906bd11ffc3b6e6a77b75382497279b1a60ab8412c1dec6", + "X1_aux": "03b0e4b1f376c6207bf34efda46ce54b132a20b90bc28b9152f3e441fe2b508b63", + "X2_aux": "0327369efcb7577abaeb7b56940e6e042126900bdf8bd8944c0adbb7be3ad98e2a", + "b": "e699140babbe599f7dd8f6e3e8f615e5f201d1c2b0bc2f821f19e80a0a0e1e7b", + "enc_U_prime": "035b8e09ce8776f1a2c7ef8610c9a6a39936c5666ab8b28d6629d3685056716482", + "proof": "dd4596175db0b4273fcdff330370d2b5e7a4bf92bf518141f4553af37ef0e1260cb8312affc2462800adba102117448b449985d1704d8afd0df9ac708231561dca56faae325cb56b0a9e8ad07bdc6ce90f6e7430090e970a7240e289218de7a17672bea9a66187d102ffef976fb01af69d8d3aa3156a5a4223dc6d08b8ce9f1d2639a2edc7052404bf1410adf6c41465bd687e3dfa5372ea71f804b56d947bae9482e5707f42dbe35f8b0e11b4a0d27a5a01e1b9a75b66d82b7945eb0b002ee400bebcdc4c3133f804b22bd2d771762058cc35a5033365d2e15150fe46d3b0e98e18ee55f0451b0b171420f73592292e4ff50603c1f0d7769dbd090936090f63" + }, + "Presentation1": { + "U": "032704f22133d2ec70f9e6f4bbf64c582220b666f2e2c1d37c3f8995a2a5568c7e", + "U_prime_commit": "03533cf1b2fd53a0716e02425eb42e4c55835aa6b2992d364cba70810d0f8aeb51", + "a": "b78e57df8f0a95d102ff12bbb97e15ed35c23e54f9b4483d30b76772ee60d886", + "m1_commit": "03e412408579105213ed10b6447c85bcd672ba73ecae1e21c463d0df4ef7beb814", + "nonce": "0x0", + "presentation_context": "746573742070726573656e746174696f6e20636f6e74657874", + "proof": "a558da5f17c04adcb0898827aaded14be1dc612dcd12b0579c11bb387ce9ae4b7dbcb3bbe413caaaf754d99e5a342abb7e0041458d670f4b58eda37e745a675295d7a7b86248141d6547b53d793e5c77896ec4dc8dd438ab66d9c8b43ef6b060938a1ca793057b154970ebc3c7ec3a23134e0852d0041f9098ce77311e5b5eca0000000000000000000000000000000000000000000000000000000000000004", + "r": "42252210dd60ddbbf1a57e3b144e26dd693b7644a9626a8c36896ede53d12930", + "tag": "031a774fd87a8f18f6420bea43cf5425e7426eec8ba7b8df5c13dc05f10ec652d9", + "z": "f5a4bbcf14e55e357df9f5ccb5ded37b2b14bc2e1a68e31f86416f0606ee75d1" + }, + "Presentation2": { + "U": "035fd233dee2c147155c6008ea64941b6ff7b315aced12531468f2e27bf22e3ef0", + "U_prime_commit": "02434af337b87fd21d1e3d950aebfc8033a3d2e9dd2bb8b9e7953488078754496d", + "a": "95bcf45150a61f5c44a6cfbf343cd9e0f593f127b6f49bec0f9b20f0550504a2", + "m1_commit": "02a578fd3a84eb5b657367b02de39b45fd48ab7781ef8f94efe601274a5ded2a07", + "nonce": "0x1", + "presentation_context": "746573742070726573656e746174696f6e20636f6e74657874", + "proof": "050965cde906fc4723333b100ce0fd9f7b026315f1db16984d4cccb2bc4aa65eb7a17f5b8dfe4f14d40006506ee5fb323e829dd4cb9dc3c455b2e04dd691600aec3cc3f1939198a80acb78b7f90b3bff769cab890f33e4d69b7c302d21ad35ec457d048d3ed7d13ee82c3c0aac2129ad0c8375cf29cd8ea3948a16b9247b1cc5faf69a3116f903b9dcccc4eff31f026041e49797b53c87eca66cfe1040187ef7", + "r": "d7ed72750b6d366ed0febdc539b52d89434f468a578c59d7ca9015b7da240ad6", + "tag": "03084fe6fff0ecc7c33ef5c49b492dda38083f52e9a2b70b88f3d4b4ba7b50afba", + "z": "91eedfb168c556ff5ca3b89d047f482c9279b47f584aab6c7f895f7674251771" + }, + "ServerKey": { + "X0": "0232b5e93dc2ff489c20a986a84757c5cc4512f057e1ea92011a26d3ad2c56288d", + "X1": "03c413230a9bd956718aa46138a33f774f4c708d61c1d6400d404243049d4a31dc", + "X2": "02db00f6f8e6d235786a120017bd356fe1c9d09069d3ac9352cc9be10ef1505a55", + "x0": "3338fa65ec36e0290022b48eb562889d89dbfa691d1cde91517fa222ed7ad364", + "x1": "f9db001266677f62c095021db018cd8cbb55941d4073698ce45c405d1348b7b1", + "x2": "350e8040f828bf6ceca27405420cdf3d63cb3aef005f40ba51943c8026877963", + "xb": "fd293126bb49a6d793cd77d7db960f5692fec3b7ec07602c60cd32aee595dffd" + }, + "suite": "ARCV1-P256", + }, { "Credential": { "U": "02be890d43908e52ed43ae7bc7098f3a7694617fe44a88c33c6fa4eb9e942c0b2bb9d2fd56a44e1d6094fc7b9e8b949055", @@ -179,9 +241,9 @@ class ARCTestVectors: XCTestCase { // Verify request proof, by creating a new request with the // tv.CredentialRequest.proof scalars and verifying it. - let requestProof = try proofFromString(CurveType: Curve.self, value: tv.CredentialRequest.proof, scalarCount: ARC.CredentialRequest.scalarCount) + let requestProof = try proofFromString(CurveType: Curve.self, value: tv.CredentialRequest.proof, scalarCount: ARC.CredentialRequest>.getScalarCount()) let newRequest = ARC.CredentialRequest(m1Enc: precredential.credentialRequest.m1Enc, m2Enc: precredential.credentialRequest.m2Enc, proof: requestProof) - XCTAssert(try newRequest.verify(generatorG: precredential.generatorG, generatorH: precredential.generatorH)) + XCTAssert(try newRequest.verify(generatorG: precredential.generatorG, generatorH: precredential.generatorH, ciphersuite: ciphersuite)) // Make a credential response, passing in randomness b let b = try scalarFromString(CurveType: Curve.self, value: tv.CredentialResponse.b) @@ -195,9 +257,9 @@ class ARCTestVectors: XCTestCase { // Verify response proof, by creating a new response with the // tv.CredentialResponse.proof scalars and verifying it. - let responseProof = try proofFromString(CurveType: Curve.self, value: tv.CredentialResponse.proof, scalarCount: ARC.CredentialResponse.scalarCount) + let responseProof = try proofFromString(CurveType: Curve.self, value: tv.CredentialResponse.proof, scalarCount: ARC.CredentialResponse>.getScalarCount()) let newResponse = ARC.CredentialResponse(U: response.U, encUPrime: response.encUPrime, X0Aux: response.X0Aux, X1Aux: response.X1Aux, X2Aux: response.X2Aux, HAux: response.HAux, proof: responseProof) - XCTAssert(try newResponse.verify(request: precredential.credentialRequest, serverPublicKey: server.serverPublicKey, generatorG: server.generatorG, generatorH: server.generatorH)) + XCTAssert(try newResponse.verify(request: precredential.credentialRequest, serverPublicKey: server.serverPublicKey, generatorG: server.generatorG, generatorH: server.generatorH, ciphersuite: ciphersuite)) // Make a credential from the response var credential = try precredential.makeCredential(credentialResponse: response) @@ -221,9 +283,9 @@ class ARCTestVectors: XCTestCase { // Verify presentation1 proof, by creating a new presentation with the // tv.Presentation1.proof scalars and verifying it. - let presentation1Proof = try proofFromString(CurveType: Curve.self, value: tv.Presentation1.proof, scalarCount: ARC.Presentation.scalarCount) + let presentation1Proof = try proofFromString(CurveType: Curve.self, value: tv.Presentation1.proof, scalarCount: ARC.Presentation>.getScalarCount()) let newPresentation1 = ARC.Presentation(U: presentation1.U, UPrimeCommit: presentation1.UPrimeCommit, m1Commit: presentation1.m1Commit, tag: presentation1.tag, proof: presentation1Proof) - XCTAssert(try newPresentation1.verify(serverPrivateKey: server.serverPrivateKey, X1: server.serverPublicKey.X1, m2: m2, presentationContext: presentationContext1, presentationLimit: 2, nonce: nonce_1, generatorG: credential.generatorG, generatorH: credential.generatorH)) + XCTAssert(try newPresentation1.verify(serverPrivateKey: server.serverPrivateKey, X1: server.serverPublicKey.X1, m2: m2, presentationContext: presentationContext1, presentationLimit: 2, nonce: nonce_1, generatorG: credential.generatorG, generatorH: credential.generatorH, ciphersuite: ciphersuite)) // Make a second presentation from the credential, passing in randomness a, r, z let presentationContext2 = try Data(hexString: tv.Presentation2.presentation_context) @@ -240,9 +302,9 @@ class ARCTestVectors: XCTestCase { // Verify presentation2 proof, by creating a new presentation with the // tv.Presentation2.proof scalars and verifying it. - let presentation2Proof = try proofFromString(CurveType: Curve.self, value: tv.Presentation2.proof, scalarCount: ARC.Presentation.scalarCount) + let presentation2Proof = try proofFromString(CurveType: Curve.self, value: tv.Presentation2.proof, scalarCount: ARC.Presentation>.getScalarCount()) let newPresentation2 = ARC.Presentation(U: presentation2.U, UPrimeCommit: presentation2.UPrimeCommit, m1Commit: presentation2.m1Commit, tag: presentation2.tag, proof: presentation2Proof) - XCTAssert(try newPresentation2.verify(serverPrivateKey: server.serverPrivateKey, X1: server.serverPublicKey.X1, m2: m2, presentationContext: presentationContext2, presentationLimit: 2, nonce: nonce_2, generatorG: credential.generatorG, generatorH: credential.generatorH)) + XCTAssert(try newPresentation2.verify(serverPrivateKey: server.serverPrivateKey, X1: server.serverPublicKey.X1, m2: m2, presentationContext: presentationContext2, presentationLimit: 2, nonce: nonce_2, generatorG: credential.generatorG, generatorH: credential.generatorH, ciphersuite: ciphersuite)) // Verify both presentations XCTAssertTrue(try server.verify(presentation: presentation1, requestContext: requestContext, presentationContext: presentationContext1, presentationLimit: 2, nonce: nonce_1)) @@ -251,7 +313,8 @@ class ARCTestVectors: XCTestCase { func validateTestVector(_ tv: ARCTestVector) { switch tv.suite { - case ARC.domain: XCTAssertNoThrow(try self.validate(curveType: P384.self, tv)) + case "ARCV1-P256": XCTAssertNoThrow(try self.validate(curveType: P256.self, tv)) + case "ARCV1-P384": XCTAssertNoThrow(try self.validate(curveType: P384.self, tv)) default: XCTFail("Unsupported ciphersuite:" + tv.suite) } } diff --git a/Tests/_CryptoExtrasTests/ARC/ARCTests.swift b/Tests/_CryptoExtrasTests/ARC/ARCTests.swift index b254c7272..d2c4dd8bd 100644 --- a/Tests/_CryptoExtrasTests/ARC/ARCTests.swift +++ b/Tests/_CryptoExtrasTests/ARC/ARCTests.swift @@ -47,7 +47,7 @@ class ARCTests: XCTestCase { XCTAssert(m1Decrypted == m1 * generatorG) let m2Decrypted = request.m2Enc - r2 * generatorH XCTAssert(m2Decrypted == precredential.clientSecrets.m2 * generatorG) - XCTAssert(try request.verify(generatorG: generatorG, generatorH: generatorH)) + XCTAssert(try request.verify(generatorG: generatorG, generatorH: generatorH, ciphersuite: ciphersuite)) // Server receives the CredentialRequest, and makes an CredentialResponse with its server keys. let issuance = try server.respond(credentialRequest: request) @@ -84,7 +84,8 @@ class ARCTests: XCTestCase { presentationLimit: presentationLimit, nonce: nonce1, generatorG: generatorG, - generatorH: generatorH)) + generatorH: generatorH, + ciphersuite: ciphersuite)) // Server verifies Presentation2 with its server keys. XCTAssert(try server.verify( @@ -102,7 +103,8 @@ class ARCTests: XCTestCase { presentationLimit: presentationLimit, nonce: nonce2, generatorG: generatorG, - generatorH: generatorH)) + generatorH: generatorH, + ciphersuite: ciphersuite)) // Test that two presentations with the same presentationContext and privateAttribute, // but difference nonces, have different tag elements diff --git a/Tests/_CryptoExtrasTests/CMACTests.swift b/Tests/_CryptoExtrasTests/CMACTests.swift new file mode 100644 index 000000000..b33f13c84 --- /dev/null +++ b/Tests/_CryptoExtrasTests/CMACTests.swift @@ -0,0 +1,197 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2025 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import Crypto +import Foundation +import XCTest +import _CryptoExtras + +final class CMACTests: XCTestCase { + // Borrowed from CryptoKit + func testVector1() throws { + let key = try Array(hexString: "a60269f095ad3c3bafae907c6f215de0") + let mac = try Array(hexString: "172084c3fe99fde4af29aa8e6e5fe1") + let msg = try Array(hexString: "cead1c5af16ca89bc0821775f8cba8c25620a03dfd27d6f1186f75f1c0bcfe4a20") + + var authenticator = try AES.CMAC(key: SymmetricKey(data: key), outputSize: 15) + authenticator.update(data: msg) + XCTAssert(authenticator.finalize() == mac) + } + + // rfc4493 example vectors + // https://datatracker.ietf.org/doc/html/rfc4493#page-11 + let exampleVector1 = "" + + let exampleVector2 = """ + 6bc1bee22e409f96e93d7e117393172a + """ + + let exampleVector3 = """ + 6bc1bee22e409f96e93d7e117393172a\ + ae2d8a571e03ac9c9eb76fac45af8e51\ + 30c81c46a35ce411 + """ + + let exampleVector4 = """ + 6bc1bee22e409f96e93d7e117393172a\ + ae2d8a571e03ac9c9eb76fac45af8e51\ + 30c81c46a35ce411e5fbc1191a0a52ef\ + f69f2445df4f9b17ad2b417be66c3710 + """ + + func testExampleVector1() throws { + let key = try Array(hexString: "2b7e151628aed2a6abf7158809cf4f3c") + let mac = try Array(hexString: "bb1d6929e95937287fa37d129b756746") + let msg = try Array(hexString: exampleVector1) + + var authenticator = try AES.CMAC(key: SymmetricKey(data: key), outputSize: 16) + authenticator.update(data: msg) + XCTAssert(authenticator.finalize() == mac) + } + + func testExampleVector2() throws { + let key = try Array(hexString: "2b7e151628aed2a6abf7158809cf4f3c") + let mac = try Array(hexString: "070a16b46b4d4144f79bdd9dd04a287c") + let msg = try Array(hexString: exampleVector2) + + var authenticator = try AES.CMAC(key: SymmetricKey(data: key), outputSize: 16) + authenticator.update(data: msg) + XCTAssert(authenticator.finalize() == mac) + } + + func testExampleVector2PerByte() throws { + let key = try Array(hexString: "2b7e151628aed2a6abf7158809cf4f3c") + let mac = try Array(hexString: "070a16b46b4d4144f79bdd9dd04a287c") + let msg = try Array(hexString: exampleVector2) + + var authenticator = try AES.CMAC(key: SymmetricKey(data: key), outputSize: 16) + for byte in msg { + authenticator.update(data: [byte]) + } + XCTAssert(authenticator.finalize() == mac) + } + + func testExampleVector3() throws { + let key = try Array(hexString: "2b7e151628aed2a6abf7158809cf4f3c") + let mac = try Array(hexString: "dfa66747de9ae63030ca32611497c827") + let msg = try Array(hexString: exampleVector3) + + var authenticator = try AES.CMAC(key: SymmetricKey(data: key), outputSize: 16) + authenticator.update(data: msg) + XCTAssert(authenticator.finalize() == mac) + } + + func testExampleVector3PerByte() throws { + let key = try Array(hexString: "2b7e151628aed2a6abf7158809cf4f3c") + let mac = try Array(hexString: "dfa66747de9ae63030ca32611497c827") + let msg = try Array(hexString: exampleVector3) + + var authenticator = try AES.CMAC(key: SymmetricKey(data: key), outputSize: 16) + for byte in msg { + authenticator.update(data: [byte]) + } + XCTAssert(authenticator.finalize() == mac) + } + + // rfc4493 example vector 4 + // https://datatracker.ietf.org/doc/html/rfc4493#page-11 + func testExampleVector4() throws { + let key = try Array(hexString: "2b7e151628aed2a6abf7158809cf4f3c") + let mac = try Array(hexString: "51f0bebf7e3b9d92fc49741779363cfe") + let msg = try Array(hexString: exampleVector4) + + var authenticator = try AES.CMAC(key: SymmetricKey(data: key), outputSize: 16) + authenticator.update(data: msg) + XCTAssert(authenticator.finalize() == mac) + } + + // rfc4493 example vector 4 + // https://datatracker.ietf.org/doc/html/rfc4493#page-11 + func testExampleVector4PerByte() throws { + let key = try Array(hexString: "2b7e151628aed2a6abf7158809cf4f3c") + let mac = try Array(hexString: "51f0bebf7e3b9d92fc49741779363cfe") + let msg = try Array(hexString: exampleVector4) + + var authenticator = try AES.CMAC(key: SymmetricKey(data: key), outputSize: 16) + for byte in msg { + authenticator.update(data: [byte]) + } + XCTAssert(authenticator.finalize() == mac) + } + + func testWycheproof() throws { + try wycheproofTest(jsonName: "aes_cmac_test") { (group: TestGroup) in + for test in group.tests { + precondition(test.flags.isEmpty) + + do { + var authenticator = try AES.CMAC(key: test.computedKey, outputSize: test.computedTag.count) + authenticator.update(data: test.computedMsg) + let result = authenticator.finalize() + + switch test.result { + case "valid": + XCTAssertTrue( + result == test.computedTag, + "Unexpected invalid test \(test.tcId) (\(test.comment))" + ) + case "invalid": + XCTAssertFalse( + result == test.computedTag, + "Unexpected valid test \(test.tcId) (\(test.comment))" + ) + default: + fatalError("Unexpected result type") + } + } catch { + XCTAssertTrue(test.result == "invalid", "Unexpected invalid test \(test.tcId) (\(test.comment))") + XCTAssertTrue( + test.comment == "invalid key size", + "Unexpected invalid test \(test.tcId) (\(test.comment))" + ) + } + } + } + } +} + +struct TestGroup: Codable { + var keySize: Int + var tagSize: Int + var type: String + var tests: [Test] +} + +extension TestGroup { + struct Test: Codable { + var tcId: Int + var comment: String + var key: String + var msg: String + var tag: String + var result: String + var flags: [String] + + var computedKey: SymmetricKey { + SymmetricKey(hexEncoded: self.key) + } + + var computedMsg: Data { + try! Data(hexString: self.msg) + } + + var computedTag: Data { + try! Data(hexString: self.tag) + } + } +} diff --git a/Tests/_CryptoExtrasTests/ECToolbox/BoringSSL/ECToolboxBoringSSLTests.swift b/Tests/_CryptoExtrasTests/ECToolbox/BoringSSL/ECToolboxBoringSSLTests.swift new file mode 100644 index 000000000..57d0eb540 --- /dev/null +++ b/Tests/_CryptoExtrasTests/ECToolbox/BoringSSL/ECToolboxBoringSSLTests.swift @@ -0,0 +1,104 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2025 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// +import Foundation +import XCTest + +#if !canImport(Darwin) || canImport(CryptoKit, _version: 241.100.42) +// Corresponds to the CryptoKit in XCode 16.3, which has Sendable annotations +import Crypto +@testable import _CryptoExtras +#else +@preconcurrency import Crypto +@testable import _CryptoExtras +#endif + +final class ECToolboxBoringSSLTests: XCTestCase { + func testThreadLocalFFAC() async { + await testThreadLocalFFAC(P256.self) + await testThreadLocalFFAC(P384.self) + await testThreadLocalFFAC(P521.self) + } + + func testThreadLocalFFAC(_ Curve: (some OpenSSLSupportedNISTCurve & Sendable).Type) async { + let numThreads = 3 + let numReadsPerThread = 2 + + var threads: + [( + thread: Thread, + thisThreadDidReads: XCTestExpectation, + allThreadsDidReads: XCTestExpectation, + thisThreadFinished: XCTestExpectation + )] = [] + + let objectIdentifiers: LockedBox<[(threadID: Int, ffacID: ObjectIdentifier)]> = .init(initialValue: []) + + for i in 1...numThreads { + let thisThreadDidReads = expectation(description: "this thread did its reads") + let allThreadsDidReads = expectation(description: "all threads did their reads") + let thisThreadFinished = expectation(description: "this thread is finished") + let thread = Thread { + for _ in 1...numReadsPerThread { + objectIdentifiers.withLockedValue { + $0.append((i, ObjectIdentifier(Curve.__ffac))) + } + } + thisThreadDidReads.fulfill() + XCTWaiter().wait(for: [allThreadsDidReads], timeout: .greatestFiniteMagnitude) + thisThreadFinished.fulfill() + } + thread.name = "thread-\(i)" + threads.append((thread, thisThreadDidReads, allThreadsDidReads, thisThreadFinished)) + thread.start() + } + await fulfillment(of: threads.map(\.thisThreadDidReads), timeout: 0.5) + for thread in threads { thread.allThreadsDidReads.fulfill() } + await fulfillment(of: threads.map(\.thisThreadFinished), timeout: 0.5) + + objectIdentifiers.withLockedValue { objectIdentifiers in + XCTAssertEqual(objectIdentifiers.count, numThreads * numReadsPerThread) + for threadID in 1...numThreads { + let partitionBoundary = objectIdentifiers.partition(by: { $0.threadID == threadID }) + let otherThreadsObjIDs = objectIdentifiers[..: @unchecked Sendable { + private let lock: NSLock + private var value: Value + + init(initialValue: Value) { + self.value = initialValue + self.lock = NSLock() + } + + func withLockedValue(_ body: (inout Value) throws -> ReturnType) rethrows -> ReturnType { + self.lock.lock() + defer { + self.lock.unlock() + } + return try body(&self.value) + } +} diff --git a/Tests/_CryptoExtrasTests/PKCS8DERRepresentationTests.swift b/Tests/_CryptoExtrasTests/PKCS8DERRepresentationTests.swift new file mode 100644 index 000000000..1cc754c2d --- /dev/null +++ b/Tests/_CryptoExtrasTests/PKCS8DERRepresentationTests.swift @@ -0,0 +1,201 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2025 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import Crypto +import Foundation +import XCTest + +@testable import _CryptoExtras + +final class PKCS8DERRepresentationTests: XCTestCase { + func test_RSA() { + let rsaPrivateKeyPEM = """ + -----BEGIN RSA PRIVATE KEY----- + MIIEpQIBAAKCAQEAxeBrlW1i+gXmqC/4XlTppLCXPpksZbxsc0AufsWzpcIxBAQL + jr4LxXyOenZcyhrdXxksEsCJE/8stJuUZgiFyDMesWjoL5bYyOpWrwPyvCMNaC8F + 15cKe5n7OSVNU312X0ZSxTZAOrCEH0kGrsXoQn5JgHygVXejSPlHw8F1Pwps3pnc + cRYE9vsHZegspUI3DaqWgmewFWz6jSMY0v1DcZv2Xw+pMLeXEpKKMf+eo90mHShh + n8FijsI1tFuYD++LmM/e1TV1z+W2sPL2CaosBO890WeCyL/bFl4j1lmdnXdBNX+l + ub/5HTqI7hxAm/qonzDs3iV5KK1ZWZTVsPyqtwIDAQABAoIBAQCGLBQG8HMKgXHT + XSOWIxGCIFONmKMoIMmQpFZik3+qx7AgvvVvRqIIuNqLYzKrv+eXEiR2WqMYMhCI + Lm5DeUftZexL84xsqGY6Zdt9NLoko8f1et0FQF9VTCWyq/5wvEPFepOpMY3/vaz4 + 4bVsULmaTLNeMiMtkL/hPVZSAB2WLjI7EgOq7JamRBCMY+ivtdtqi12kO8vaA2Ns + dSKuU+e8tvAP4o6cMvuLtcqLy2UeoZzYTI998up0tqn+mGHl0DHx6MSi/TbVv3v8 + gSQGlBvWzUx85vz+1GyjRn+o4hO/tibtP6aKfWYztIyLgkaU8JuDZzT+CwwmCnEH + ge/JmGuRAoGBAPypZ9MuWi1Ms57nVcpHRSHUc+cO/CfoaC4kRzgh99ApDbL+rj78 + 9eXkS10Z8hTLQprcznQr+WZhnhNw13PrvzaGhtOXd/xLBnWlqZ6aIGYrJgKu+JLl + yGVBZByG70yXel8IZt9l4CYctlS4D8iYAtdR+CCn8XGrc8JILnwBbYDNAoGBAMh9 + tiC8hyIc/wBV/WcgtpY6tPkrN4uw6WREH+UkVpvNM2kMMCgn1YLHbYq1vSKN3rKZ + L9Ep4+8umRMg5yTgq9iURMoNjq+qU8NDF0nRljmyJRvgA5Ez2iQErm3y5dYxK+8w + BRvCkDeOiiu1Mnd9chgu0tQhpfo7o+T3XeXB5omTAoGBAKl3IqlVnKxnls6NEVC0 + Tt0q93ZR6bUGv+G6+X3f4qxe7M5S3iJnXrMMVbQjc+iYkJr4YQ0wdX5DGVimxgv9 + Ymo6/vGq1ZKF69Y7ADLd479DT6JbI2S79JZdrr0nkBfKPgzBwOY0GYzWk0Dtl8CO + nNE5LHkSy/HW8rSr32nTN1Q9AoGAOdl8GcoMO92d/pzRN1aLGKHr4hGEP3xWe6Xk + hhuMGfyFnwPzSULlKo0coG98GWJSJbppv7KUoEkTxh8yUsO5Eg8GIj7zMuC0tpy/ + NX+SFye96WMj5FvPz6DCK9twUfNyN9vlPXNQZZdtatsnqq65oxyvnKHw4FkhG0n8 + //SI7p0CgYEA9CoA6/3rRIVKKEOgeCQHDVKIJIauTUskwdrBHLVU7SH+cfQ6VNy6 + zp/M54MpUP5jviSL61HmRoEqqcMWLALJHyZ1yQAZXSpthyMw0ahqTUZ71j1ukIO0 + UUjK3drJJd2jGQ0LfhlDCX7VmURIqJ6kaQ0WBNAJLFhTW4AS8HGYRZk= + -----END RSA PRIVATE KEY----- + """ + + // Same key in PKCS8 DER representation. + let encodedPKCS8DER = + "MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDF4GuVbWL6BeaoL/heVOmksJc+mSxlvGxzQC5+xbOlwjEEBAuOvgvFfI56dlzKGt1fGSwSwIkT/yy0m5RmCIXIMx6xaOgvltjI6lavA/K8Iw1oLwXXlwp7mfs5JU1TfXZfRlLFNkA6sIQfSQauxehCfkmAfKBVd6NI+UfDwXU/CmzemdxxFgT2+wdl6CylQjcNqpaCZ7AVbPqNIxjS/UNxm/ZfD6kwt5cSkoox/56j3SYdKGGfwWKOwjW0W5gP74uYz97VNXXP5baw8vYJqiwE7z3RZ4LIv9sWXiPWWZ2dd0E1f6W5v/kdOojuHECb+qifMOzeJXkorVlZlNWw/Kq3AgMBAAECggEBAIYsFAbwcwqBcdNdI5YjEYIgU42YoyggyZCkVmKTf6rHsCC+9W9Gogi42otjMqu/55cSJHZaoxgyEIgubkN5R+1l7EvzjGyoZjpl2300uiSjx/V63QVAX1VMJbKr/nC8Q8V6k6kxjf+9rPjhtWxQuZpMs14yIy2Qv+E9VlIAHZYuMjsSA6rslqZEEIxj6K+122qLXaQ7y9oDY2x1Iq5T57y28A/ijpwy+4u1yovLZR6hnNhMj33y6nS2qf6YYeXQMfHoxKL9NtW/e/yBJAaUG9bNTHzm/P7UbKNGf6jiE7+2Ju0/pop9ZjO0jIuCRpTwm4NnNP4LDCYKcQeB78mYa5ECgYEA/Kln0y5aLUyznudVykdFIdRz5w78J+hoLiRHOCH30CkNsv6uPvz15eRLXRnyFMtCmtzOdCv5ZmGeE3DXc+u/NoaG05d3/EsGdaWpnpogZismAq74kuXIZUFkHIbvTJd6Xwhm32XgJhy2VLgPyJgC11H4IKfxcatzwkgufAFtgM0CgYEAyH22ILyHIhz/AFX9ZyC2ljq0+Ss3i7DpZEQf5SRWm80zaQwwKCfVgsdtirW9Io3espkv0Snj7y6ZEyDnJOCr2JREyg2Or6pTw0MXSdGWObIlG+ADkTPaJASubfLl1jEr7zAFG8KQN46KK7Uyd31yGC7S1CGl+juj5Pdd5cHmiZMCgYEAqXciqVWcrGeWzo0RULRO3Sr3dlHptQa/4br5fd/irF7szlLeImdeswxVtCNz6JiQmvhhDTB1fkMZWKbGC/1iajr+8arVkoXr1jsAMt3jv0NPolsjZLv0ll2uvSeQF8o+DMHA5jQZjNaTQO2XwI6c0TkseRLL8dbytKvfadM3VD0CgYA52XwZygw73Z3+nNE3VosYoeviEYQ/fFZ7peSGG4wZ/IWfA/NJQuUqjRygb3wZYlIlumm/spSgSRPGHzJSw7kSDwYiPvMy4LS2nL81f5IXJ73pYyPkW8/PoMIr23BR83I32+U9c1Bll21q2yeqrrmjHK+cofDgWSEbSfz/9IjunQKBgQD0KgDr/etEhUooQ6B4JAcNUogkhq5NSyTB2sEctVTtIf5x9DpU3LrOn8zngylQ/mO+JIvrUeZGgSqpwxYsAskfJnXJABldKm2HIzDRqGpNRnvWPW6Qg7RRSMrd2skl3aMZDQt+GUMJftWZREionqRpDRYE0AksWFNbgBLwcZhFmQ==" + let rsaPrivateKeyPKCS8DER = Data(base64Encoded: encodedPKCS8DER)! + + // Create private keys from both representations of the same key + let keyFromPEM = try! _RSA.Signing.PrivateKey(pemRepresentation: rsaPrivateKeyPEM) + let keyFromDER = try! _RSA.Signing.PrivateKey(derRepresentation: rsaPrivateKeyPKCS8DER) + + XCTAssertEqual(keyFromDER.keySizeInBits, 2048) + XCTAssertEqual(keyFromPEM.keySizeInBits, 2048) + + // The keys match + XCTAssertEqual(keyFromPEM.derRepresentation, keyFromDER.derRepresentation) + + // Our property creates the expected representation + XCTAssertEqual(keyFromPEM.pkcs8DERRepresentation, rsaPrivateKeyPKCS8DER) + } + + func test_ed25519() { + let privateKeyPEM = """ + -----BEGIN PRIVATE KEY----- + MC4CAQAwBQYDK2VwBCIEIFSrpkDrDWBMoz/YWjFaW9t4TQaKWyalZ6TRDUS/4+LE + -----END PRIVATE KEY----- + """ + + // Same key in PKCS8 DER representation. + let privateKeyPKCS8DER = Data( + base64Encoded: + "MC4CAQAwBQYDK2VwBCIEIFSrpkDrDWBMoz/YWjFaW9t4TQaKWyalZ6TRDUS/4+LE" + )! + + // We only need the 32 bytes of the key. + let document = try! ASN1.PEMDocument(pemString: privateKeyPEM) + var bytes = document.derBytes + bytes.removeFirst(bytes.count - 32) + + let keyFromDER = try! Curve25519.Signing.PrivateKey(rawRepresentation: bytes) + + let pkcs8 = keyFromDER.pkcs8DERRepresentation + + XCTAssertEqual(pkcs8, privateKeyPKCS8DER) + } + + func test_ed25519_rfc_example() { + // Example key from RFC 8410, Section 10.3. + // Create private key from bytes. + let keyBytes = Data( + base64Encoded: + "1O5y2/kTWErVttjx92n4rTr+fCjL8dT74Jeoj0R1WEI=" + )! + // Same key in PKCS8 DER representation. + let exampleKeyPKCS8DER = Data( + base64Encoded: + "MC4CAQAwBQYDK2VwBCIEINTuctv5E1hK1bbY8fdp+K06/nwoy/HU++CXqI9EdVhC" + )! + + // Create key from the private key bytes and compare our exported representation. + let exampleKey = try! Curve25519.Signing.PrivateKey(rawRepresentation: keyBytes) + + XCTAssertEqual(exampleKey.pkcs8DERRepresentation, exampleKeyPKCS8DER) + } + + func test_x25519() { + let privateKeyPEM = """ + -----BEGIN PRIVATE KEY----- + MC4CAQAwBQYDK2VuBCIEIKBtrFwBvmRtGZjMyj0rXewOQclz/8cdEY981glA/w5a + -----END PRIVATE KEY----- + """ + + // Same key in PKCS8 DER representation. + let privateKeyPKCS8DER = Data( + base64Encoded: + "MC4CAQAwBQYDK2VuBCIEIKBtrFwBvmRtGZjMyj0rXewOQclz/8cdEY981glA/w5a" + )! + + // We only need the 32 bytes of the key. + let document = try! ASN1.PEMDocument(pemString: privateKeyPEM) + var bytes = document.derBytes + bytes.removeFirst(bytes.count - 32) + + // Create key from the private key bytes and compare our exported representation. + let keyFromDER = try! Curve25519.KeyAgreement.PrivateKey(rawRepresentation: bytes) + + XCTAssertEqual(keyFromDER.pkcs8DERRepresentation, privateKeyPKCS8DER) + } + + func test_P256() { + let privateKeyPEM = """ + -----BEGIN PRIVATE KEY----- + MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgO6fz+J/sZqbCki3h + chsrVb69KW8q24pLDwotAtwz/gahRANCAASkBqszxMCGrd8l+xZitPto300blCWk + wRCdoar3UeEEfuH5LsJ3kNjN+oMZmHAmnhHE6cqLHFem/ujsGgrqJ3E8 + -----END PRIVATE KEY----- + """ + let encodedPKCS8DER = + "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgO6fz+J/sZqbCki3hchsrVb69KW8q24pLDwotAtwz/gahRANCAASkBqszxMCGrd8l+xZitPto300blCWkwRCdoar3UeEEfuH5LsJ3kNjN+oMZmHAmnhHE6cqLHFem/ujsGgrqJ3E8" + let privateKeyPKCS8DER = Data(base64Encoded: encodedPKCS8DER)! + + // Create key from PEM and compare our exported representation. + let keyFromPEM = try! P256.Signing.PrivateKey(pemRepresentation: privateKeyPEM) + + XCTAssertEqual(keyFromPEM.pkcs8DERRepresentation, privateKeyPKCS8DER) + } + + func test_P384() { + let privateKeyPEM = """ + -----BEGIN PRIVATE KEY----- + MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDD2qUnvEDviY5Hon7fx + rsJmgWCGQcNlU+nXEWOoFPC49kioBm1hsveCH0q3vk9GjZKhZANiAAQFzxvdG2gI + uWZfkAeMW2BzsKGdUWwybx8MHs8fv48MCPmfvL4kIvkU9T7F7diut41ciSzILv5/ + gb45xx6+dZjlWxIopstQuBu5v/J4oa3fgN1uYQJTSsKksDi3L52TcnY= + -----END PRIVATE KEY----- + """ + + // Same key in PKCS8 DER representation. + let encodedPKCS8DER = + "MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDD2qUnvEDviY5Hon7fxrsJmgWCGQcNlU+nXEWOoFPC49kioBm1hsveCH0q3vk9GjZKhZANiAAQFzxvdG2gIuWZfkAeMW2BzsKGdUWwybx8MHs8fv48MCPmfvL4kIvkU9T7F7diut41ciSzILv5/gb45xx6+dZjlWxIopstQuBu5v/J4oa3fgN1uYQJTSsKksDi3L52TcnY=" + let privateKeyPKCS8DER = Data(base64Encoded: encodedPKCS8DER)! + + // Create key from PEM and compare our exported representation. + let keyFromPEM = try! P384.Signing.PrivateKey(pemRepresentation: privateKeyPEM) + + XCTAssertEqual(keyFromPEM.pkcs8DERRepresentation, privateKeyPKCS8DER) + } + + func test_P521() { + let privateKeyPEM = """ + -----BEGIN PRIVATE KEY----- + MIHuAgEAMBAGByqGSM49AgEGBSuBBAAjBIHWMIHTAgEBBEIBcQv0MVt8xb5teBQJ + Mqn7wnQ2GVzgL+jkMERcMaABU7+UL7uC0ff+15RKEI2RwKLVUVvp3WJigCHBDpwY + qI9OFnyhgYkDgYYABAD7PeX+GFUa99yyhYJ4WReKq2nLUOjo+ZZ+pdepc0EaESj+ + 8o2Sv4mRjIU0s3WFTNx0mh9BKiszBNRu2nq148ZfCwAcAiJu4xcwR2o+L7BqNadJ + 1hCoVItbL61BWxAMITZPegQLMV1K7SMS6NNkYBBIh10Q870tBO26VJ5wMm5K46MA + Cg== + -----END PRIVATE KEY----- + """ + + // Same key in PKCS8 DER representation. + let encodedPKCS8DER = + "MIHuAgEAMBAGByqGSM49AgEGBSuBBAAjBIHWMIHTAgEBBEIBcQv0MVt8xb5teBQJMqn7wnQ2GVzgL+jkMERcMaABU7+UL7uC0ff+15RKEI2RwKLVUVvp3WJigCHBDpwYqI9OFnyhgYkDgYYABAD7PeX+GFUa99yyhYJ4WReKq2nLUOjo+ZZ+pdepc0EaESj+8o2Sv4mRjIU0s3WFTNx0mh9BKiszBNRu2nq148ZfCwAcAiJu4xcwR2o+L7BqNadJ1hCoVItbL61BWxAMITZPegQLMV1K7SMS6NNkYBBIh10Q870tBO26VJ5wMm5K46MACg==" + let privateKeyPKCS8DER = Data(base64Encoded: encodedPKCS8DER) + + // Create key from PEM and compare our exported representation. + let keyFromPEM = try! P521.Signing.PrivateKey(pemRepresentation: privateKeyPEM) + + XCTAssertEqual(keyFromPEM.pkcs8DERRepresentation, privateKeyPKCS8DER) + } +} diff --git a/Tests/_CryptoExtrasTests/Utils/BytesUtil.swift b/Tests/_CryptoExtrasTests/Utils/BytesUtil.swift index 4e774b83a..b92cb49ab 100644 --- a/Tests/_CryptoExtrasTests/Utils/BytesUtil.swift +++ b/Tests/_CryptoExtrasTests/Utils/BytesUtil.swift @@ -45,7 +45,11 @@ extension Array where Element == UInt8 { init(hexString: String) throws { self.init() - guard hexString.count.isMultiple(of: 2), !hexString.isEmpty else { + if hexString.count == 0 { + return + } + + if hexString.count % 2 != 0 { throw ByteHexEncodingErrors.incorrectString } diff --git a/Tests/_CryptoExtrasVectors/aes_cmac_test.json b/Tests/_CryptoExtrasVectors/aes_cmac_test.json new file mode 100644 index 000000000..53494208f --- /dev/null +++ b/Tests/_CryptoExtrasVectors/aes_cmac_test.json @@ -0,0 +1,2842 @@ +{ + "algorithm" : "AES-CMAC", + "generatorVersion" : "0.8r12", + "numberOfTests" : 308, + "header" : [ + "Test vectors of type MacTest are intended for testing the", + "generation and verification of MACs." + ], + "notes" : { + }, + "schema" : "mac_test_schema.json", + "testGroups" : [ + { + "keySize" : 128, + "tagSize" : 128, + "type" : "MacTest", + "tests" : [ + { + "tcId" : 1, + "comment" : "empty message", + "key" : "e34f15c7bd819930fe9d66e0c166e61c", + "msg" : "", + "tag" : "d47afca1d857a5933405b1eb7a5cb7af", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 2, + "comment" : "short message", + "key" : "e1e726677f4893890f8c027f9d8ef80d", + "msg" : "3f", + "tag" : "15f856bbed3b321952a584b3c4437a63", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 3, + "comment" : "short message", + "key" : "b151f491c4c006d1f28214aa3da9a985", + "msg" : "27d9", + "tag" : "bdbbebac982dd62b9f682618a6a604e9", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 4, + "comment" : "short message", + "key" : "c36ff15f72777ee21deec07b63c1a0cd", + "msg" : "50b428", + "tag" : "be0c3ede157568af394023eb9a7cc983", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 5, + "comment" : "short message", + "key" : "32b9c5c78c3a0689a86052420fa1e8fc", + "msg" : "0b9262ec", + "tag" : "57e1506856c55dd32cd9ca821adb6c81", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 6, + "comment" : "short message", + "key" : "43151bbaef367277ebfc97509d0aa49c", + "msg" : "eaa91273e7", + "tag" : "e01adc3be6a7621824232c4285dd35b9", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 7, + "comment" : "short message", + "key" : "481440298525cc261f8159159aedf62d", + "msg" : "6123c556c5cc", + "tag" : "a281e0d2d5378dfdcc1310fd9782ca56", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 8, + "comment" : "short message", + "key" : "9ca26eb88731efbf7f810d5d95e196ac", + "msg" : "7e48f06183aa40", + "tag" : "fc81761f2f7b4ce13b53d36e32677332", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 9, + "comment" : "short message", + "key" : "48f0d03e41cc55c4b58f737b5acdea32", + "msg" : "f4a133aa6d5985a0", + "tag" : "1f1cd0327c02e6d00086915937dd61d9", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 10, + "comment" : "short message", + "key" : "1c958849f31996b28939ce513087d1be", + "msg" : "b0d2fee11b8e2f86b7", + "tag" : "555f462151f7dd16de698d639fb26760", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 11, + "comment" : "short message", + "key" : "39de0ebea97c09b2301a90009a423253", + "msg" : "81e5c33b4c620852f044", + "tag" : "9b004f15b7f6f366374954e64bc58f5f", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 12, + "comment" : "short message", + "key" : "91656d8fc0aced60ddb1c4006d0dde53", + "msg" : "7b3e440fe566790064b2ec", + "tag" : "76672ed16c29be449e0c80785cc38e89", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 13, + "comment" : "short message", + "key" : "af7d5134720b5386158d51ea126e7cf9", + "msg" : "7cc6fcc925c20f3c83b5567c", + "tag" : "2dc5c88cf3b80ab6c0199f40be904abc", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 14, + "comment" : "short message", + "key" : "4ed56753de6f75a032ebabca3ce27971", + "msg" : "0c8c0f5619d9f8da5339281285", + "tag" : "eab4366d97e99a0850f077329ad058c0", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 15, + "comment" : "short message", + "key" : "beba50c936b696c15e25046dffb23a64", + "msg" : "821ea8532fbabffb6e3d212e9b46", + "tag" : "22f33cab09c173f75d3401fe44efeead", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 16, + "comment" : "short message", + "key" : "501d81ebf912ddb87fbe3b7aac1437bc", + "msg" : "2368e3c3636b5e8e94d2081adbf798", + "tag" : "aeb784a3825168ddd61f72d0202125e6", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 17, + "comment" : "", + "key" : "e09eaa5a3f5e56d279d5e7a03373f6ea", + "msg" : "ef4eab37181f98423e53e947e7050fd0", + "tag" : "40facf0e2fb51b73a7472681b033d6dc", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 18, + "comment" : "", + "key" : "831e664c9e3f0c3094c0b27b9d908eb2", + "msg" : "26603bb76dd0a0180791c4ed4d3b058807", + "tag" : "a8144c8b24f2aa47d9c160cff4ab1716", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 19, + "comment" : "", + "key" : "549bd282ee21b4d7c3b1d02e3ee20ef7", + "msg" : "d84bf73c5eecbd38444f1a73556e2fa3253f4c54d6916545", + "tag" : "7ed458afe02f4a513f59715b664b1bbe", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 20, + "comment" : "", + "key" : "9bd3902ed0996c869b572272e76f3889", + "msg" : "a7ba19d49ee1ea02f098aa8e30c740d893a4456ccc294040484ed8a00a55f93e", + "tag" : "45082218c2d05eef32247feb1133d0a3", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 21, + "comment" : "Flipped bit 0 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "", + "tag" : "96dd6e5a882cbd564c39ae7d1c5a31aa", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 22, + "comment" : "Flipped bit 0 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "0001020304050607", + "tag" : "43802eb1931f0032afe984443738cd31", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 23, + "comment" : "Flipped bit 0 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "7acfbbca7a2ea68b966fc5399f74809e", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 24, + "comment" : "Flipped bit 1 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "", + "tag" : "95dd6e5a882cbd564c39ae7d1c5a31aa", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 25, + "comment" : "Flipped bit 1 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "0001020304050607", + "tag" : "40802eb1931f0032afe984443738cd31", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 26, + "comment" : "Flipped bit 1 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "79cfbbca7a2ea68b966fc5399f74809e", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 27, + "comment" : "Flipped bit 7 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "", + "tag" : "17dd6e5a882cbd564c39ae7d1c5a31aa", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 28, + "comment" : "Flipped bit 7 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "0001020304050607", + "tag" : "c2802eb1931f0032afe984443738cd31", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 29, + "comment" : "Flipped bit 7 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "fbcfbbca7a2ea68b966fc5399f74809e", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 30, + "comment" : "Flipped bit 8 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "", + "tag" : "97dc6e5a882cbd564c39ae7d1c5a31aa", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 31, + "comment" : "Flipped bit 8 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "0001020304050607", + "tag" : "42812eb1931f0032afe984443738cd31", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 32, + "comment" : "Flipped bit 8 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "7bcebbca7a2ea68b966fc5399f74809e", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 33, + "comment" : "Flipped bit 31 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "", + "tag" : "97dd6eda882cbd564c39ae7d1c5a31aa", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 34, + "comment" : "Flipped bit 31 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "0001020304050607", + "tag" : "42802e31931f0032afe984443738cd31", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 35, + "comment" : "Flipped bit 31 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "7bcfbb4a7a2ea68b966fc5399f74809e", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 36, + "comment" : "Flipped bit 32 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "", + "tag" : "97dd6e5a892cbd564c39ae7d1c5a31aa", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 37, + "comment" : "Flipped bit 32 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "0001020304050607", + "tag" : "42802eb1921f0032afe984443738cd31", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 38, + "comment" : "Flipped bit 32 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "7bcfbbca7b2ea68b966fc5399f74809e", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 39, + "comment" : "Flipped bit 33 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "", + "tag" : "97dd6e5a8a2cbd564c39ae7d1c5a31aa", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 40, + "comment" : "Flipped bit 33 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "0001020304050607", + "tag" : "42802eb1911f0032afe984443738cd31", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 41, + "comment" : "Flipped bit 33 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "7bcfbbca782ea68b966fc5399f74809e", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 42, + "comment" : "Flipped bit 63 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "", + "tag" : "97dd6e5a882cbdd64c39ae7d1c5a31aa", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 43, + "comment" : "Flipped bit 63 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "0001020304050607", + "tag" : "42802eb1931f00b2afe984443738cd31", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 44, + "comment" : "Flipped bit 63 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "7bcfbbca7a2ea60b966fc5399f74809e", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 45, + "comment" : "Flipped bit 64 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "", + "tag" : "97dd6e5a882cbd564d39ae7d1c5a31aa", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 46, + "comment" : "Flipped bit 64 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "0001020304050607", + "tag" : "42802eb1931f0032aee984443738cd31", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 47, + "comment" : "Flipped bit 64 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "7bcfbbca7a2ea68b976fc5399f74809e", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 48, + "comment" : "Flipped bit 71 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "", + "tag" : "97dd6e5a882cbd56cc39ae7d1c5a31aa", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 49, + "comment" : "Flipped bit 71 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "0001020304050607", + "tag" : "42802eb1931f00322fe984443738cd31", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 50, + "comment" : "Flipped bit 71 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "7bcfbbca7a2ea68b166fc5399f74809e", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 51, + "comment" : "Flipped bit 77 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "", + "tag" : "97dd6e5a882cbd564c19ae7d1c5a31aa", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 52, + "comment" : "Flipped bit 77 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "0001020304050607", + "tag" : "42802eb1931f0032afc984443738cd31", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 53, + "comment" : "Flipped bit 77 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "7bcfbbca7a2ea68b964fc5399f74809e", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 54, + "comment" : "Flipped bit 80 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "", + "tag" : "97dd6e5a882cbd564c39af7d1c5a31aa", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 55, + "comment" : "Flipped bit 80 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "0001020304050607", + "tag" : "42802eb1931f0032afe985443738cd31", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 56, + "comment" : "Flipped bit 80 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "7bcfbbca7a2ea68b966fc4399f74809e", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 57, + "comment" : "Flipped bit 96 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "", + "tag" : "97dd6e5a882cbd564c39ae7d1d5a31aa", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 58, + "comment" : "Flipped bit 96 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "0001020304050607", + "tag" : "42802eb1931f0032afe984443638cd31", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 59, + "comment" : "Flipped bit 96 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "7bcfbbca7a2ea68b966fc5399e74809e", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 60, + "comment" : "Flipped bit 97 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "", + "tag" : "97dd6e5a882cbd564c39ae7d1e5a31aa", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 61, + "comment" : "Flipped bit 97 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "0001020304050607", + "tag" : "42802eb1931f0032afe984443538cd31", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 62, + "comment" : "Flipped bit 97 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "7bcfbbca7a2ea68b966fc5399d74809e", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 63, + "comment" : "Flipped bit 103 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "", + "tag" : "97dd6e5a882cbd564c39ae7d9c5a31aa", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 64, + "comment" : "Flipped bit 103 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "0001020304050607", + "tag" : "42802eb1931f0032afe98444b738cd31", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 65, + "comment" : "Flipped bit 103 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "7bcfbbca7a2ea68b966fc5391f74809e", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 66, + "comment" : "Flipped bit 120 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "", + "tag" : "97dd6e5a882cbd564c39ae7d1c5a31ab", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 67, + "comment" : "Flipped bit 120 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "0001020304050607", + "tag" : "42802eb1931f0032afe984443738cd30", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 68, + "comment" : "Flipped bit 120 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "7bcfbbca7a2ea68b966fc5399f74809f", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 69, + "comment" : "Flipped bit 121 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "", + "tag" : "97dd6e5a882cbd564c39ae7d1c5a31a8", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 70, + "comment" : "Flipped bit 121 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "0001020304050607", + "tag" : "42802eb1931f0032afe984443738cd33", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 71, + "comment" : "Flipped bit 121 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "7bcfbbca7a2ea68b966fc5399f74809c", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 72, + "comment" : "Flipped bit 126 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "", + "tag" : "97dd6e5a882cbd564c39ae7d1c5a31ea", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 73, + "comment" : "Flipped bit 126 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "0001020304050607", + "tag" : "42802eb1931f0032afe984443738cd71", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 74, + "comment" : "Flipped bit 126 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "7bcfbbca7a2ea68b966fc5399f7480de", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 75, + "comment" : "Flipped bit 127 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "", + "tag" : "97dd6e5a882cbd564c39ae7d1c5a312a", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 76, + "comment" : "Flipped bit 127 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "0001020304050607", + "tag" : "42802eb1931f0032afe984443738cdb1", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 77, + "comment" : "Flipped bit 127 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "7bcfbbca7a2ea68b966fc5399f74801e", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 78, + "comment" : "Flipped bits 0 and 64 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "", + "tag" : "96dd6e5a882cbd564d39ae7d1c5a31aa", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 79, + "comment" : "Flipped bits 0 and 64 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "0001020304050607", + "tag" : "43802eb1931f0032aee984443738cd31", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 80, + "comment" : "Flipped bits 0 and 64 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "7acfbbca7a2ea68b976fc5399f74809e", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 81, + "comment" : "Flipped bits 31 and 63 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "", + "tag" : "97dd6eda882cbdd64c39ae7d1c5a31aa", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 82, + "comment" : "Flipped bits 31 and 63 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "0001020304050607", + "tag" : "42802e31931f00b2afe984443738cd31", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 83, + "comment" : "Flipped bits 31 and 63 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "7bcfbb4a7a2ea60b966fc5399f74809e", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 84, + "comment" : "Flipped bits 63 and 127 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "", + "tag" : "97dd6e5a882cbdd64c39ae7d1c5a312a", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 85, + "comment" : "Flipped bits 63 and 127 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "0001020304050607", + "tag" : "42802eb1931f00b2afe984443738cdb1", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 86, + "comment" : "Flipped bits 63 and 127 in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "7bcfbbca7a2ea60b966fc5399f74801e", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 87, + "comment" : "all bits of tag flipped", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "", + "tag" : "682291a577d342a9b3c65182e3a5ce55", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 88, + "comment" : "all bits of tag flipped", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "0001020304050607", + "tag" : "bd7fd14e6ce0ffcd50167bbbc8c732ce", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 89, + "comment" : "all bits of tag flipped", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "8430443585d1597469903ac6608b7f61", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 90, + "comment" : "Tag changed to all zero", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "", + "tag" : "00000000000000000000000000000000", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 91, + "comment" : "Tag changed to all zero", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "0001020304050607", + "tag" : "00000000000000000000000000000000", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 92, + "comment" : "Tag changed to all zero", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "00000000000000000000000000000000", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 93, + "comment" : "tag changed to all 1", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "", + "tag" : "ffffffffffffffffffffffffffffffff", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 94, + "comment" : "tag changed to all 1", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "0001020304050607", + "tag" : "ffffffffffffffffffffffffffffffff", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 95, + "comment" : "tag changed to all 1", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "ffffffffffffffffffffffffffffffff", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 96, + "comment" : "msbs changed in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "", + "tag" : "175deeda08ac3dd6ccb92efd9cdab12a", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 97, + "comment" : "msbs changed in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "0001020304050607", + "tag" : "c200ae31139f80b22f6904c4b7b84db1", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 98, + "comment" : "msbs changed in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "fb4f3b4afaae260b16ef45b91ff4001e", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 99, + "comment" : "lsbs changed in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "", + "tag" : "96dc6f5b892dbc574d38af7c1d5b30ab", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 100, + "comment" : "lsbs changed in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "0001020304050607", + "tag" : "43812fb0921e0133aee885453639cc30", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 101, + "comment" : "lsbs changed in tag", + "key" : "000102030405060708090a0b0c0d0e0f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "7acebacb7b2fa78a976ec4389e75819f", + "result" : "invalid", + "flags" : [] + } + ] + }, + { + "keySize" : 192, + "tagSize" : 128, + "type" : "MacTest", + "tests" : [ + { + "tcId" : 102, + "comment" : "empty message", + "key" : "3d6bf9edae6d881eade0ff8c7076a4835b71320c1f36b631", + "msg" : "", + "tag" : "a8dd15fe2ce3495ec5b666744ec29220", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 103, + "comment" : "short message", + "key" : "915429743435c28997a33b33b6574a953d81dae0e7032e6a", + "msg" : "58", + "tag" : "e13b3f7f7f510c3a059df7a68c7e2ad5", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 104, + "comment" : "short message", + "key" : "f0c288ba26b284f9fb321b444a6517b3cdda1a799d55fdff", + "msg" : "0f7e", + "tag" : "06ef847f5f9dbf03a4f283da8c400220", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 105, + "comment" : "short message", + "key" : "6b55e4d4fd6847a80a6bfb0dcc0aa93f9fd797fc5c50292e", + "msg" : "33f530", + "tag" : "dd135053a47ca8f282c299e83b8c57c4", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 106, + "comment" : "short message", + "key" : "1eb21a9e995a8e45c9e71ecbd6fe615b3e0318007c64b644", + "msg" : "3aa73c48", + "tag" : "1e93fff846934a6eea0575eecb0f0e1f", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 107, + "comment" : "short message", + "key" : "710e2d5d4a9f0bc7e50796655e046a18cc5769d7764355da", + "msg" : "7e4c690a88", + "tag" : "016d4df06c68a6a788a9ea052e1b550d", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 108, + "comment" : "short message", + "key" : "d8c09ea400779b63e774bdacd0cb7b5dd6f736ca23d52acf", + "msg" : "e9520280973b", + "tag" : "8030ae9f98f5d20c6089f6b1bd87c29e", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 109, + "comment" : "short message", + "key" : "8e67e9a0863b55bed408866f1cbc05357abe3f9d79f406f2", + "msg" : "4880b412287a0b", + "tag" : "bcaf50785f062a8fb8dd3c2c4cead2e1", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 110, + "comment" : "short message", + "key" : "28d8da67806410e5565bcc5a9d7ab9fb357413fa0158378c", + "msg" : "004e3f4a4e6db955", + "tag" : "c4c2c0876be9eabeb5a956da53846b08", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 111, + "comment" : "short message", + "key" : "dc968dd89fd602bb7eca6f3a8a13e4f59c08d02a514b1934", + "msg" : "41a25354efeb1bc3b8", + "tag" : "f33a62caf397f9aff71fe42941ba41d8", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 112, + "comment" : "short message", + "key" : "7658951c0f620d82afd92756cc2d7983b79da3e56fdd1b78", + "msg" : "f0e82fb5c5666f4af49f", + "tag" : "4d724d05f3402967eb65ae1e32d5469e", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 113, + "comment" : "short message", + "key" : "d9574c3a221b986690931faac5258d9d3c52362b2cb9b054", + "msg" : "178ea8404ba54ee4e4522c", + "tag" : "64a0e0b6757309ab58d74f72c310e473", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 114, + "comment" : "short message", + "key" : "704409bab28085c44981f28f75dd143a4f747106f63f262e", + "msg" : "cda5709e7f115624e74ab031", + "tag" : "6ab2074334be14a95b6a241f897a43de", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 115, + "comment" : "short message", + "key" : "d8d06ef6a53bbff5c8f12d791b8f4c67e574bf440736d1cc", + "msg" : "a1171eae1979f48345dd9485a0", + "tag" : "7aa57cf98b24897cc9230e3316758e61", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 116, + "comment" : "short message", + "key" : "71129e781613f39d9ac39fbde2628b44c250c14deb5ef9e2", + "msg" : "967593cc64bcbf7f3c58d04cb82b", + "tag" : "6cc488b0a40eadbe4bcee2623239d126", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 117, + "comment" : "short message", + "key" : "850fc859e9f7b89a367611dee6698f33962d8245ca8dc331", + "msg" : "586f4f171af116519061a8e0e77940", + "tag" : "fb11a360c9776991d73d6e41d07710a2", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 118, + "comment" : "", + "key" : "f4bfa5aa4f0f4d62cf736cd2969c43d580fdb92f2753bedb", + "msg" : "0e239f239705b282ce2200fe20de1165", + "tag" : "ab20a6cf60873665b1d6999b05c7f9c6", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 119, + "comment" : "", + "key" : "cfd3f68873d81a27d2bfce876c79f6e609074dec39e34614", + "msg" : "b1973cb25aa87ef9d1a8888b0a0f5c04c6", + "tag" : "b95a016b83a0ae4194023333c8a7345a", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 120, + "comment" : "", + "key" : "648a44468d67bb6744b235ee7a3fcd6ed4bdc29ec5b5fa1a", + "msg" : "c59d0d6981cca1be1d5519fc7881e6d230f39f6c12a9e827", + "tag" : "a1b96272ae7f9aef567271795f21d1d3", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 121, + "comment" : "", + "key" : "9d11abc1fcb248a436598e695be12c3c2ed90a18ba09d62c", + "msg" : "aa5182cae2a8fb068c0b3fb2be3e57ae523d13dffd1a944587707c2b67447f3f", + "tag" : "8597d9a04d1c271d61d42f007b435175", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 122, + "comment" : "Flipped bit 0 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "", + "tag" : "ed12390ea0a7ed15d9d37a6eca1fc990", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 123, + "comment" : "Flipped bit 0 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "0001020304050607", + "tag" : "c81307df60859acb911c7be61be7ca90", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 124, + "comment" : "Flipped bit 0 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "f91bde0069a6e389573bf04e7cde688c", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 125, + "comment" : "Flipped bit 1 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "", + "tag" : "ee12390ea0a7ed15d9d37a6eca1fc990", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 126, + "comment" : "Flipped bit 1 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "0001020304050607", + "tag" : "cb1307df60859acb911c7be61be7ca90", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 127, + "comment" : "Flipped bit 1 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "fa1bde0069a6e389573bf04e7cde688c", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 128, + "comment" : "Flipped bit 7 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "", + "tag" : "6c12390ea0a7ed15d9d37a6eca1fc990", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 129, + "comment" : "Flipped bit 7 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "0001020304050607", + "tag" : "491307df60859acb911c7be61be7ca90", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 130, + "comment" : "Flipped bit 7 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "781bde0069a6e389573bf04e7cde688c", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 131, + "comment" : "Flipped bit 8 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "", + "tag" : "ec13390ea0a7ed15d9d37a6eca1fc990", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 132, + "comment" : "Flipped bit 8 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "0001020304050607", + "tag" : "c91207df60859acb911c7be61be7ca90", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 133, + "comment" : "Flipped bit 8 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "f81ade0069a6e389573bf04e7cde688c", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 134, + "comment" : "Flipped bit 31 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "", + "tag" : "ec12398ea0a7ed15d9d37a6eca1fc990", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 135, + "comment" : "Flipped bit 31 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "0001020304050607", + "tag" : "c913075f60859acb911c7be61be7ca90", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 136, + "comment" : "Flipped bit 31 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "f81bde8069a6e389573bf04e7cde688c", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 137, + "comment" : "Flipped bit 32 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "", + "tag" : "ec12390ea1a7ed15d9d37a6eca1fc990", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 138, + "comment" : "Flipped bit 32 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "0001020304050607", + "tag" : "c91307df61859acb911c7be61be7ca90", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 139, + "comment" : "Flipped bit 32 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "f81bde0068a6e389573bf04e7cde688c", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 140, + "comment" : "Flipped bit 33 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "", + "tag" : "ec12390ea2a7ed15d9d37a6eca1fc990", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 141, + "comment" : "Flipped bit 33 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "0001020304050607", + "tag" : "c91307df62859acb911c7be61be7ca90", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 142, + "comment" : "Flipped bit 33 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "f81bde006ba6e389573bf04e7cde688c", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 143, + "comment" : "Flipped bit 63 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "", + "tag" : "ec12390ea0a7ed95d9d37a6eca1fc990", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 144, + "comment" : "Flipped bit 63 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "0001020304050607", + "tag" : "c91307df60859a4b911c7be61be7ca90", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 145, + "comment" : "Flipped bit 63 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "f81bde0069a6e309573bf04e7cde688c", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 146, + "comment" : "Flipped bit 64 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "", + "tag" : "ec12390ea0a7ed15d8d37a6eca1fc990", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 147, + "comment" : "Flipped bit 64 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "0001020304050607", + "tag" : "c91307df60859acb901c7be61be7ca90", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 148, + "comment" : "Flipped bit 64 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "f81bde0069a6e389563bf04e7cde688c", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 149, + "comment" : "Flipped bit 71 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "", + "tag" : "ec12390ea0a7ed1559d37a6eca1fc990", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 150, + "comment" : "Flipped bit 71 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "0001020304050607", + "tag" : "c91307df60859acb111c7be61be7ca90", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 151, + "comment" : "Flipped bit 71 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "f81bde0069a6e389d73bf04e7cde688c", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 152, + "comment" : "Flipped bit 77 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "", + "tag" : "ec12390ea0a7ed15d9f37a6eca1fc990", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 153, + "comment" : "Flipped bit 77 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "0001020304050607", + "tag" : "c91307df60859acb913c7be61be7ca90", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 154, + "comment" : "Flipped bit 77 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "f81bde0069a6e389571bf04e7cde688c", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 155, + "comment" : "Flipped bit 80 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "", + "tag" : "ec12390ea0a7ed15d9d37b6eca1fc990", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 156, + "comment" : "Flipped bit 80 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "0001020304050607", + "tag" : "c91307df60859acb911c7ae61be7ca90", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 157, + "comment" : "Flipped bit 80 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "f81bde0069a6e389573bf14e7cde688c", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 158, + "comment" : "Flipped bit 96 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "", + "tag" : "ec12390ea0a7ed15d9d37a6ecb1fc990", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 159, + "comment" : "Flipped bit 96 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "0001020304050607", + "tag" : "c91307df60859acb911c7be61ae7ca90", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 160, + "comment" : "Flipped bit 96 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "f81bde0069a6e389573bf04e7dde688c", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 161, + "comment" : "Flipped bit 97 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "", + "tag" : "ec12390ea0a7ed15d9d37a6ec81fc990", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 162, + "comment" : "Flipped bit 97 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "0001020304050607", + "tag" : "c91307df60859acb911c7be619e7ca90", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 163, + "comment" : "Flipped bit 97 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "f81bde0069a6e389573bf04e7ede688c", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 164, + "comment" : "Flipped bit 103 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "", + "tag" : "ec12390ea0a7ed15d9d37a6e4a1fc990", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 165, + "comment" : "Flipped bit 103 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "0001020304050607", + "tag" : "c91307df60859acb911c7be69be7ca90", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 166, + "comment" : "Flipped bit 103 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "f81bde0069a6e389573bf04efcde688c", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 167, + "comment" : "Flipped bit 120 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "", + "tag" : "ec12390ea0a7ed15d9d37a6eca1fc991", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 168, + "comment" : "Flipped bit 120 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "0001020304050607", + "tag" : "c91307df60859acb911c7be61be7ca91", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 169, + "comment" : "Flipped bit 120 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "f81bde0069a6e389573bf04e7cde688d", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 170, + "comment" : "Flipped bit 121 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "", + "tag" : "ec12390ea0a7ed15d9d37a6eca1fc992", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 171, + "comment" : "Flipped bit 121 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "0001020304050607", + "tag" : "c91307df60859acb911c7be61be7ca92", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 172, + "comment" : "Flipped bit 121 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "f81bde0069a6e389573bf04e7cde688e", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 173, + "comment" : "Flipped bit 126 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "", + "tag" : "ec12390ea0a7ed15d9d37a6eca1fc9d0", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 174, + "comment" : "Flipped bit 126 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "0001020304050607", + "tag" : "c91307df60859acb911c7be61be7cad0", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 175, + "comment" : "Flipped bit 126 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "f81bde0069a6e389573bf04e7cde68cc", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 176, + "comment" : "Flipped bit 127 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "", + "tag" : "ec12390ea0a7ed15d9d37a6eca1fc910", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 177, + "comment" : "Flipped bit 127 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "0001020304050607", + "tag" : "c91307df60859acb911c7be61be7ca10", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 178, + "comment" : "Flipped bit 127 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "f81bde0069a6e389573bf04e7cde680c", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 179, + "comment" : "Flipped bits 0 and 64 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "", + "tag" : "ed12390ea0a7ed15d8d37a6eca1fc990", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 180, + "comment" : "Flipped bits 0 and 64 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "0001020304050607", + "tag" : "c81307df60859acb901c7be61be7ca90", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 181, + "comment" : "Flipped bits 0 and 64 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "f91bde0069a6e389563bf04e7cde688c", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 182, + "comment" : "Flipped bits 31 and 63 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "", + "tag" : "ec12398ea0a7ed95d9d37a6eca1fc990", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 183, + "comment" : "Flipped bits 31 and 63 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "0001020304050607", + "tag" : "c913075f60859a4b911c7be61be7ca90", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 184, + "comment" : "Flipped bits 31 and 63 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "f81bde8069a6e309573bf04e7cde688c", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 185, + "comment" : "Flipped bits 63 and 127 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "", + "tag" : "ec12390ea0a7ed95d9d37a6eca1fc910", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 186, + "comment" : "Flipped bits 63 and 127 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "0001020304050607", + "tag" : "c91307df60859a4b911c7be61be7ca10", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 187, + "comment" : "Flipped bits 63 and 127 in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "f81bde0069a6e309573bf04e7cde680c", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 188, + "comment" : "all bits of tag flipped", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "", + "tag" : "13edc6f15f5812ea262c859135e0366f", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 189, + "comment" : "all bits of tag flipped", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "0001020304050607", + "tag" : "36ecf8209f7a65346ee38419e418356f", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 190, + "comment" : "all bits of tag flipped", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "07e421ff96591c76a8c40fb183219773", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 191, + "comment" : "Tag changed to all zero", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "", + "tag" : "00000000000000000000000000000000", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 192, + "comment" : "Tag changed to all zero", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "0001020304050607", + "tag" : "00000000000000000000000000000000", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 193, + "comment" : "Tag changed to all zero", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "00000000000000000000000000000000", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 194, + "comment" : "tag changed to all 1", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "", + "tag" : "ffffffffffffffffffffffffffffffff", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 195, + "comment" : "tag changed to all 1", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "0001020304050607", + "tag" : "ffffffffffffffffffffffffffffffff", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 196, + "comment" : "tag changed to all 1", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "ffffffffffffffffffffffffffffffff", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 197, + "comment" : "msbs changed in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "", + "tag" : "6c92b98e20276d955953faee4a9f4910", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 198, + "comment" : "msbs changed in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "0001020304050607", + "tag" : "4993875fe0051a4b119cfb669b674a10", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 199, + "comment" : "msbs changed in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "789b5e80e9266309d7bb70cefc5ee80c", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 200, + "comment" : "lsbs changed in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "", + "tag" : "ed13380fa1a6ec14d8d27b6fcb1ec891", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 201, + "comment" : "lsbs changed in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "0001020304050607", + "tag" : "c81206de61849bca901d7ae71ae6cb91", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 202, + "comment" : "lsbs changed in tag", + "key" : "000102030405060708090a0b0c0d0e0f1011121314151617", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "f91adf0168a7e288563af14f7ddf698d", + "result" : "invalid", + "flags" : [] + } + ] + }, + { + "keySize" : 256, + "tagSize" : 128, + "type" : "MacTest", + "tests" : [ + { + "tcId" : 203, + "comment" : "empty message", + "key" : "7bf9e536b66a215c22233fe2daaa743a898b9acb9f7802de70b40e3d6e43ef97", + "msg" : "", + "tag" : "736c7b56957db774c5ddf7c7a70ba8a8", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 204, + "comment" : "short message", + "key" : "e754076ceab3fdaf4f9bcab7d4f0df0cbbafbc87731b8f9b7cd2166472e8eebc", + "msg" : "40", + "tag" : "9d47482c2d9252bace43a75a8335b8b8", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 205, + "comment" : "short message", + "key" : "ea3b016bdd387dd64d837c71683808f335dbdc53598a4ea8c5f952473fafaf5f", + "msg" : "6601", + "tag" : "c7c44e31c466334992d6f9de3c771634", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 206, + "comment" : "short message", + "key" : "73d4709637857dafab6ad8b2b0a51b06524717fedf100296644f7cfdaae1805b", + "msg" : "f1d300", + "tag" : "b7086603a85e11fceb8cadea9bd30939", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 207, + "comment" : "short message", + "key" : "d5c81b399d4c0d1583a13da56de6d2dc45a66e7b47c24ab1192e246dc961dd77", + "msg" : "2ae63cbf", + "tag" : "ba383a3a15c9df64bba50d611113a024", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 208, + "comment" : "short message", + "key" : "2521203fa0dddf59d837b2830f87b1aa61f958155df3ca4d1df2457cb4284dc8", + "msg" : "af3a015ea1", + "tag" : "b457137c548908c629f714fe83b1ed90", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 209, + "comment" : "short message", + "key" : "665a02bc265a66d01775091da56726b6668bfd903cb7af66fb1b78a8a062e43c", + "msg" : "3f56935def3f", + "tag" : "b6d6fde93fc85de289b36b446d77b423", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 210, + "comment" : "short message", + "key" : "facd75b22221380047305bc981f570e2a1af38928ea7e2059e3af5fc6b82b493", + "msg" : "57bb86beed156f", + "tag" : "8b1ef72d0a612735b08efef981f213c2", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 211, + "comment" : "short message", + "key" : "505aa98819809ef63b9a368a1e8bc2e922da45b03ce02d9a7966b15006dba2d5", + "msg" : "2e4e7ef728fe11af", + "tag" : "f79606b83a7706a2a19e068bce818898", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 212, + "comment" : "short message", + "key" : "f942093842808ba47f64e427f7351dde6b9546e66de4e7d60aa6f328182712cf", + "msg" : "852a21d92848e627c7", + "tag" : "a5a877f22ac743b7fb9e050d2e3ddb02", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 213, + "comment" : "short message", + "key" : "64be162b39c6e5f1fed9c32d9f674d9a8cde6eaa2443214d86bd4a1fb53b81b4", + "msg" : "195a3b292f93baff0a2c", + "tag" : "6ea172e5c4d2fac075ca602de5757a62", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 214, + "comment" : "short message", + "key" : "b259a555d44b8a20c5489e2f38392ddaa6be9e35b9833b67e1b5fdf6cb3e4c6c", + "msg" : "afd73117330c6e8528a6e4", + "tag" : "68020bfc9bd73fd80d3ce581ba3b1208", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 215, + "comment" : "short message", + "key" : "2c6fc62daa77ba8c6881b3dd6989898fef646663cc7b0a3db8228a707b85f2dc", + "msg" : "0ff54d6b6759120c2e8a51e3", + "tag" : "110edd727a9bf7fa11a6358afe617d9d", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 216, + "comment" : "short message", + "key" : "abab815d51df29f740e4e2079fb798e0152836e6ab57d1536ae8929e52c06eb8", + "msg" : "f0058d412a104e53d820b95a7f", + "tag" : "1fa24c6625a0f8e1fc37827ac84d3cc4", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 217, + "comment" : "short message", + "key" : "3d5da1af83f7287458bff7a7651ea5d8db72259401333f6b82096996dd7eaf19", + "msg" : "aacc36972f183057919ff57b49e1", + "tag" : "868765a8fa6aa898ddec0f4123e996be", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 218, + "comment" : "short message", + "key" : "c19bdf314c6cf64381425467f42aefa17c1cc9358be16ce31b1d214859ce86aa", + "msg" : "5d066a92c300e9b6ddd63a7c13ae33", + "tag" : "b96818b7acaf879c7a7f8271375a6914", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 219, + "comment" : "", + "key" : "612e837843ceae7f61d49625faa7e7494f9253e20cb3adcea686512b043936cd", + "msg" : "cc37fae15f745a2f40e2c8b192f2b38d", + "tag" : "4b88e193000c5a4b23e95c7f2b26530b", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 220, + "comment" : "", + "key" : "73216fafd0022d0d6ee27198b2272578fa8f04dd9f44467fbb6437aa45641bf7", + "msg" : "d5247b8f6c3edcbfb1d591d13ece23d2f5", + "tag" : "86911c7da51dc0823d6e93d4290d1ad4", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 221, + "comment" : "", + "key" : "0427a70e257528f3ab70640bba1a5de12cf3885dd4c8e284fbbb55feb35294a5", + "msg" : "13937f8544f44270d01175a011f7670e93fa6ba7ef02336e", + "tag" : "ccb2c51bfbe2598f9109fc70ed07f0eb", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 222, + "comment" : "", + "key" : "96e1e4896fb2cd05f133a6a100bc5609a7ac3ca6d81721e922dadd69ad07a892", + "msg" : "91a17e4dfcc3166a1add26ff0e7c12056e8a654f28a6de24f4ba739ceb5b5b18", + "tag" : "925f177d85ea297ef14b203fe409f9ab", + "result" : "valid", + "flags" : [] + }, + { + "tcId" : 223, + "comment" : "Flipped bit 0 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "", + "tag" : "6af0a293d8cba0101f0089727691b7fb", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 224, + "comment" : "Flipped bit 0 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "0001020304050607", + "tag" : "d709717c3a4ef8a2ea200b297d2accec", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 225, + "comment" : "Flipped bit 0 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "58ee3f3b5f83e290cae26dad29bba32d", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 226, + "comment" : "Flipped bit 1 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "", + "tag" : "69f0a293d8cba0101f0089727691b7fb", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 227, + "comment" : "Flipped bit 1 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "0001020304050607", + "tag" : "d409717c3a4ef8a2ea200b297d2accec", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 228, + "comment" : "Flipped bit 1 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "5bee3f3b5f83e290cae26dad29bba32d", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 229, + "comment" : "Flipped bit 7 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "", + "tag" : "ebf0a293d8cba0101f0089727691b7fb", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 230, + "comment" : "Flipped bit 7 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "0001020304050607", + "tag" : "5609717c3a4ef8a2ea200b297d2accec", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 231, + "comment" : "Flipped bit 7 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "d9ee3f3b5f83e290cae26dad29bba32d", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 232, + "comment" : "Flipped bit 8 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "", + "tag" : "6bf1a293d8cba0101f0089727691b7fb", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 233, + "comment" : "Flipped bit 8 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "0001020304050607", + "tag" : "d608717c3a4ef8a2ea200b297d2accec", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 234, + "comment" : "Flipped bit 8 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "59ef3f3b5f83e290cae26dad29bba32d", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 235, + "comment" : "Flipped bit 31 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "", + "tag" : "6bf0a213d8cba0101f0089727691b7fb", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 236, + "comment" : "Flipped bit 31 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "0001020304050607", + "tag" : "d60971fc3a4ef8a2ea200b297d2accec", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 237, + "comment" : "Flipped bit 31 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "59ee3fbb5f83e290cae26dad29bba32d", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 238, + "comment" : "Flipped bit 32 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "", + "tag" : "6bf0a293d9cba0101f0089727691b7fb", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 239, + "comment" : "Flipped bit 32 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "0001020304050607", + "tag" : "d609717c3b4ef8a2ea200b297d2accec", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 240, + "comment" : "Flipped bit 32 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "59ee3f3b5e83e290cae26dad29bba32d", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 241, + "comment" : "Flipped bit 33 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "", + "tag" : "6bf0a293dacba0101f0089727691b7fb", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 242, + "comment" : "Flipped bit 33 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "0001020304050607", + "tag" : "d609717c384ef8a2ea200b297d2accec", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 243, + "comment" : "Flipped bit 33 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "59ee3f3b5d83e290cae26dad29bba32d", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 244, + "comment" : "Flipped bit 63 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "", + "tag" : "6bf0a293d8cba0901f0089727691b7fb", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 245, + "comment" : "Flipped bit 63 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "0001020304050607", + "tag" : "d609717c3a4ef822ea200b297d2accec", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 246, + "comment" : "Flipped bit 63 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "59ee3f3b5f83e210cae26dad29bba32d", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 247, + "comment" : "Flipped bit 64 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "", + "tag" : "6bf0a293d8cba0101e0089727691b7fb", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 248, + "comment" : "Flipped bit 64 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "0001020304050607", + "tag" : "d609717c3a4ef8a2eb200b297d2accec", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 249, + "comment" : "Flipped bit 64 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "59ee3f3b5f83e290cbe26dad29bba32d", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 250, + "comment" : "Flipped bit 71 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "", + "tag" : "6bf0a293d8cba0109f0089727691b7fb", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 251, + "comment" : "Flipped bit 71 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "0001020304050607", + "tag" : "d609717c3a4ef8a26a200b297d2accec", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 252, + "comment" : "Flipped bit 71 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "59ee3f3b5f83e2904ae26dad29bba32d", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 253, + "comment" : "Flipped bit 77 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "", + "tag" : "6bf0a293d8cba0101f2089727691b7fb", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 254, + "comment" : "Flipped bit 77 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "0001020304050607", + "tag" : "d609717c3a4ef8a2ea000b297d2accec", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 255, + "comment" : "Flipped bit 77 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "59ee3f3b5f83e290cac26dad29bba32d", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 256, + "comment" : "Flipped bit 80 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "", + "tag" : "6bf0a293d8cba0101f0088727691b7fb", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 257, + "comment" : "Flipped bit 80 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "0001020304050607", + "tag" : "d609717c3a4ef8a2ea200a297d2accec", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 258, + "comment" : "Flipped bit 80 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "59ee3f3b5f83e290cae26cad29bba32d", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 259, + "comment" : "Flipped bit 96 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "", + "tag" : "6bf0a293d8cba0101f0089727791b7fb", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 260, + "comment" : "Flipped bit 96 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "0001020304050607", + "tag" : "d609717c3a4ef8a2ea200b297c2accec", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 261, + "comment" : "Flipped bit 96 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "59ee3f3b5f83e290cae26dad28bba32d", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 262, + "comment" : "Flipped bit 97 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "", + "tag" : "6bf0a293d8cba0101f0089727491b7fb", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 263, + "comment" : "Flipped bit 97 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "0001020304050607", + "tag" : "d609717c3a4ef8a2ea200b297f2accec", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 264, + "comment" : "Flipped bit 97 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "59ee3f3b5f83e290cae26dad2bbba32d", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 265, + "comment" : "Flipped bit 103 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "", + "tag" : "6bf0a293d8cba0101f008972f691b7fb", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 266, + "comment" : "Flipped bit 103 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "0001020304050607", + "tag" : "d609717c3a4ef8a2ea200b29fd2accec", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 267, + "comment" : "Flipped bit 103 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "59ee3f3b5f83e290cae26dada9bba32d", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 268, + "comment" : "Flipped bit 120 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "", + "tag" : "6bf0a293d8cba0101f0089727691b7fa", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 269, + "comment" : "Flipped bit 120 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "0001020304050607", + "tag" : "d609717c3a4ef8a2ea200b297d2acced", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 270, + "comment" : "Flipped bit 120 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "59ee3f3b5f83e290cae26dad29bba32c", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 271, + "comment" : "Flipped bit 121 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "", + "tag" : "6bf0a293d8cba0101f0089727691b7f9", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 272, + "comment" : "Flipped bit 121 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "0001020304050607", + "tag" : "d609717c3a4ef8a2ea200b297d2accee", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 273, + "comment" : "Flipped bit 121 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "59ee3f3b5f83e290cae26dad29bba32f", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 274, + "comment" : "Flipped bit 126 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "", + "tag" : "6bf0a293d8cba0101f0089727691b7bb", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 275, + "comment" : "Flipped bit 126 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "0001020304050607", + "tag" : "d609717c3a4ef8a2ea200b297d2accac", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 276, + "comment" : "Flipped bit 126 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "59ee3f3b5f83e290cae26dad29bba36d", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 277, + "comment" : "Flipped bit 127 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "", + "tag" : "6bf0a293d8cba0101f0089727691b77b", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 278, + "comment" : "Flipped bit 127 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "0001020304050607", + "tag" : "d609717c3a4ef8a2ea200b297d2acc6c", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 279, + "comment" : "Flipped bit 127 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "59ee3f3b5f83e290cae26dad29bba3ad", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 280, + "comment" : "Flipped bits 0 and 64 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "", + "tag" : "6af0a293d8cba0101e0089727691b7fb", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 281, + "comment" : "Flipped bits 0 and 64 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "0001020304050607", + "tag" : "d709717c3a4ef8a2eb200b297d2accec", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 282, + "comment" : "Flipped bits 0 and 64 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "58ee3f3b5f83e290cbe26dad29bba32d", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 283, + "comment" : "Flipped bits 31 and 63 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "", + "tag" : "6bf0a213d8cba0901f0089727691b7fb", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 284, + "comment" : "Flipped bits 31 and 63 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "0001020304050607", + "tag" : "d60971fc3a4ef822ea200b297d2accec", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 285, + "comment" : "Flipped bits 31 and 63 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "59ee3fbb5f83e210cae26dad29bba32d", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 286, + "comment" : "Flipped bits 63 and 127 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "", + "tag" : "6bf0a293d8cba0901f0089727691b77b", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 287, + "comment" : "Flipped bits 63 and 127 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "0001020304050607", + "tag" : "d609717c3a4ef822ea200b297d2acc6c", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 288, + "comment" : "Flipped bits 63 and 127 in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "59ee3f3b5f83e210cae26dad29bba3ad", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 289, + "comment" : "all bits of tag flipped", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "", + "tag" : "940f5d6c27345fefe0ff768d896e4804", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 290, + "comment" : "all bits of tag flipped", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "0001020304050607", + "tag" : "29f68e83c5b1075d15dff4d682d53313", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 291, + "comment" : "all bits of tag flipped", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "a611c0c4a07c1d6f351d9252d6445cd2", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 292, + "comment" : "Tag changed to all zero", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "", + "tag" : "00000000000000000000000000000000", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 293, + "comment" : "Tag changed to all zero", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "0001020304050607", + "tag" : "00000000000000000000000000000000", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 294, + "comment" : "Tag changed to all zero", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "00000000000000000000000000000000", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 295, + "comment" : "tag changed to all 1", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "", + "tag" : "ffffffffffffffffffffffffffffffff", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 296, + "comment" : "tag changed to all 1", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "0001020304050607", + "tag" : "ffffffffffffffffffffffffffffffff", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 297, + "comment" : "tag changed to all 1", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "ffffffffffffffffffffffffffffffff", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 298, + "comment" : "msbs changed in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "", + "tag" : "eb702213584b20909f8009f2f611377b", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 299, + "comment" : "msbs changed in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "0001020304050607", + "tag" : "5689f1fcbace78226aa08ba9fdaa4c6c", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 300, + "comment" : "msbs changed in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "d96ebfbbdf0362104a62ed2da93b23ad", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 301, + "comment" : "lsbs changed in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "", + "tag" : "6af1a392d9caa1111e0188737790b6fa", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 302, + "comment" : "lsbs changed in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "0001020304050607", + "tag" : "d708707d3b4ff9a3eb210a287c2bcded", + "result" : "invalid", + "flags" : [] + }, + { + "tcId" : 303, + "comment" : "lsbs changed in tag", + "key" : "000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f", + "msg" : "000102030405060708090a0b0c0d0e0f", + "tag" : "58ef3e3a5e82e391cbe36cac28baa22c", + "result" : "invalid", + "flags" : [] + } + ] + }, + { + "keySize" : 0, + "tagSize" : 128, + "type" : "MacTest", + "tests" : [ + { + "tcId" : 304, + "comment" : "invalid key size", + "key" : "", + "msg" : "00b9449326d39416", + "tag" : "", + "result" : "invalid", + "flags" : [] + } + ] + }, + { + "keySize" : 8, + "tagSize" : 128, + "type" : "MacTest", + "tests" : [ + { + "tcId" : 305, + "comment" : "invalid key size", + "key" : "0f", + "msg" : "4538b79a1397e2aa", + "tag" : "", + "result" : "invalid", + "flags" : [] + } + ] + }, + { + "keySize" : 64, + "tagSize" : 128, + "type" : "MacTest", + "tests" : [ + { + "tcId" : 306, + "comment" : "invalid key size", + "key" : "a88e385af7185148", + "msg" : "dc63b7ef08096e4f", + "tag" : "", + "result" : "invalid", + "flags" : [] + } + ] + }, + { + "keySize" : 160, + "tagSize" : 128, + "type" : "MacTest", + "tests" : [ + { + "tcId" : 307, + "comment" : "invalid key size", + "key" : "003a228008d390b645929df73a2b2bdd8298918d", + "msg" : "ad1d3c3122ab7ac6", + "tag" : "", + "result" : "invalid", + "flags" : [] + } + ] + }, + { + "keySize" : 320, + "tagSize" : 128, + "type" : "MacTest", + "tests" : [ + { + "tcId" : 308, + "comment" : "invalid key size", + "key" : "94baaac150e2645ae1ec1939c7bcefb73f6edb146fae02289b6c6326ff39bc265d612bef2727fa72", + "msg" : "e3f75a886c4a5591", + "tag" : "", + "result" : "invalid", + "flags" : [] + } + ] + } + ] +} diff --git a/cmake/modules/SwiftCryptoConfig.cmake.in b/cmake/modules/SwiftCryptoConfig.cmake.in index 353de7b15..97e65bd6e 100644 --- a/cmake/modules/SwiftCryptoConfig.cmake.in +++ b/cmake/modules/SwiftCryptoConfig.cmake.in @@ -13,5 +13,7 @@ ##===----------------------------------------------------------------------===## if(NOT TARGET SwiftCrypto) + include(CMakeFindDependencyMacro) + find_dependency(SwiftASN1) include(@SWIFT_CRYPTO_EXPORTS_FILE@) endif() diff --git a/scripts/generate-linux-sdks.sh b/scripts/generate-linux-sdks.sh new file mode 100755 index 000000000..65cd7bfcb --- /dev/null +++ b/scripts/generate-linux-sdks.sh @@ -0,0 +1,78 @@ +#!/bin/bash +##===----------------------------------------------------------------------===## +## +## This source file is part of the SwiftCrypto open source project +## +## Copyright (c) 2019-2025 Apple Inc. and the SwiftCrypto project authors +## Licensed under Apache License v2.0 +## +## See LICENSE.txt for license information +## See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +## +## SPDX-License-Identifier: Apache-2.0 +## +##===----------------------------------------------------------------------===## +# +# This script generates Swift SDKs for Linux targets using the swift-sdk-generator. +# It should be run once before running the `vendor-boringssl.sh` script, which requires +# the Linux Swift SDKs to be installed. +# +# Usage: +# 1. Run this script to generate and install the Swift SDKs. This script can be re-run to +# re-generate Swift SDKs if needed. Old SDKs will be removed before installing newly +# generated ones. +# + +set -e + +SWIFT_VERSION=5.10 +DISTRO_NAME=ubuntu +DISTRO_VERSION=jammy +DISTRO_VERSION_GENERATOR=22.04 +TMPDIR=$(mktemp -d /tmp/.workingXXXXXX) + +function generate_swift_sdk { + TARGET_ARCH=$1 + SDK_NAME="${SWIFT_VERSION}-RELEASE_${DISTRO_NAME}_${DISTRO_VERSION}_${TARGET_ARCH}" + + cd "$TMPDIR" + if [ ! -d swift-sdk-generator ]; then + echo "Cloning SDK generator..." + git clone https://github.com/swiftlang/swift-sdk-generator.git + fi + + cd swift-sdk-generator + + if [ "$TARGET_ARCH" = "armv7" ]; then + DOWNLOAD_FILE=swift-${SWIFT_VERSION}-RELEASE-${DISTRO_NAME}-${DISTRO_VERSION}-armv7-install + DOWNLOAD_PATH="${TMPDIR}/${DOWNLOAD_FILE}" + echo "Downloading armv7 runtime..." + wget -nc https://github.com/swift-embedded-linux/armhf-debian/releases/download/${SWIFT_VERSION}/${DOWNLOAD_FILE}.tar.gz && \ + echo "Extracting armv7 runtime..." && \ + mkdir "${DOWNLOAD_PATH}" && true && \ + tar -xf ${DOWNLOAD_FILE}.tar.gz -C "${DOWNLOAD_PATH}" + + echo "Creating Swift SDK for ${TARGET_ARCH}..." + swift run swift-sdk-generator make-linux-sdk \ + --swift-version ${SWIFT_VERSION}-RELEASE \ + --distribution-name ${DISTRO_NAME} \ + --distribution-version ${DISTRO_VERSION_GENERATOR} \ + --target armv7-unknown-linux-gnueabihf \ + --target-swift-package-path "${DOWNLOAD_PATH}" + else + echo "Creating Swift SDK for ${TARGET_ARCH}..." + swift run swift-sdk-generator make-linux-sdk \ + --swift-version ${SWIFT_VERSION}-RELEASE \ + --distribution-name ${DISTRO_NAME} \ + --distribution-version ${DISTRO_VERSION_GENERATOR} \ + --target "${TARGET_ARCH}-unknown-linux-gnu" + fi + + swift sdk remove "${SDK_NAME}" || true # ignore error if it doesn't exist + swift sdk install "Bundles/${SDK_NAME}.artifactbundle" +} + +echo "Generating Swift SDKs for Linux targets..." +generate_swift_sdk "x86_64" +generate_swift_sdk "aarch64" +generate_swift_sdk "armv7" diff --git a/scripts/vendor-boringssl.sh b/scripts/vendor-boringssl.sh index 5af684aab..5727749ad 100755 --- a/scripts/vendor-boringssl.sh +++ b/scripts/vendor-boringssl.sh @@ -45,6 +45,11 @@ DSTROOT=Sources/CCryptoBoringSSL TMPDIR=$(mktemp -d /tmp/.workingXXXXXX) SRCROOT="${TMPDIR}/src/boringssl.googlesource.com/boringssl" +# BoringSSL revision can be passed as the first argument to this script. +if [ "$#" -gt 0 ]; then + BORINGSSL_REVISION="$1" +fi + # This function namespaces the awkward inline functions declared in OpenSSL # and BoringSSL. function namespace_inlines { @@ -101,16 +106,16 @@ function mangle_symbols { ) # Now cross compile for our targets. - docker run -t -i --rm --privileged -v"$(pwd)":/src -w/src --platform linux/arm64 swift:5.10-jammy \ - swift build --product CCryptoBoringSSL - docker run -t -i --rm --privileged -v"$(pwd)":/src -w/src --platform linux/amd64 swift:5.10-jammy \ - swift build --product CCryptoBoringSSL + # NOTE: This requires running the `generate-linux-sdks.sh` script first to generate the Swift SDKs. + swift build --swift-sdk 5.10-RELEASE_ubuntu_jammy_x86_64 --product CCryptoBoringSSL + swift build --swift-sdk 5.10-RELEASE_ubuntu_jammy_aarch64 --product CCryptoBoringSSL + swift build --swift-sdk 5.10-RELEASE_ubuntu_jammy_armv7 --product CCryptoBoringSSL # Now we need to generate symbol mangles for Linux. We can do this in # one go for all of them. ( cd "${SRCROOT}" - go run "util/read_symbols.go" -obj-file-format elf -out "${TMPDIR}/symbols-linux-all.txt" "${HERE}"/.build/*-unknown-linux-gnu/debug/libCCryptoBoringSSL.a + go run "util/read_symbols.go" -obj-file-format elf -out "${TMPDIR}/symbols-linux-all.txt" "${HERE}"/.build/*-unknown-linux-*/debug/libCCryptoBoringSSL.a ) # Now we concatenate all the symbols together and uniquify it. At this stage remove anything that @@ -170,9 +175,14 @@ echo "CLONING boringssl" mkdir -p "$SRCROOT" git clone https://boringssl.googlesource.com/boringssl "$SRCROOT" cd "$SRCROOT" -BORINGSSL_REVISION=$(git rev-parse HEAD) +if [ "$BORINGSSL_REVISION" ]; then + echo "CHECKING OUT boringssl@${BORINGSSL_REVISION}" + git checkout "$BORINGSSL_REVISION" +else + BORINGSSL_REVISION=$(git rev-parse HEAD) + echo "CLONED boringssl@${BORINGSSL_REVISION}" +fi cd "$HERE" -echo "CLONED boringssl@${BORINGSSL_REVISION}" echo "OBTAINING submodules" ( @@ -248,7 +258,7 @@ echo "DISABLING assembly on x86 Windows" # x86 Windows builds require nasm for acceleration. SwiftPM can't do that right now, # so we disable the assembly. cd "$DSTROOT" - gsed -i "/#define OPENSSL_HEADER_BASE_H/a#if defined(_WIN32) && (defined(__x86_64) || defined(_M_AMD64) || defined(_M_X64) || defined(__x86) || defined(__i386) || defined(__i386__) || defined(_M_IX86))\n#define OPENSSL_NO_ASM\n#endif" "include/openssl/base.h" + $sed -i "/#define OPENSSL_HEADER_BASE_H/a#if defined(_WIN32) && (defined(__x86_64) || defined(_M_AMD64) || defined(_M_X64) || defined(__x86) || defined(__i386) || defined(__i386__) || defined(_M_IX86))\n#define OPENSSL_NO_ASM\n#endif" "include/openssl/base.h" ) @@ -347,8 +357,6 @@ cat << EOF > "$DSTROOT/include/CCryptoBoringSSL.h" #include "CCryptoBoringSSL_hrss.h" #include "CCryptoBoringSSL_md4.h" #include "CCryptoBoringSSL_md5.h" -#include "CCryptoBoringSSL_mldsa.h" -#include "CCryptoBoringSSL_mlkem.h" #include "CCryptoBoringSSL_obj_mac.h" #include "CCryptoBoringSSL_objects.h" #include "CCryptoBoringSSL_opensslv.h" From ea7f8fbce1ac1726885d16e9511bbf62ef51db25 Mon Sep 17 00:00:00 2001 From: Cory Benfield Date: Wed, 10 Sep 2025 05:26:24 -0400 Subject: [PATCH 25/47] Update to RC SDK (#410) This patch brings us up-to-date with the RC SDK. There are a couple of tweaks to the MLDSA code and the XWing code, mostly a few minor interface changes. I've adopted those in the backing code, and also wired up the SHA3 integrity checks. --- .../Crypto/KEM/BoringSSL/MLKEM_wrapper.swift | 34 ++- .../Crypto/KEM/BoringSSL/XWing_boring.swift | 24 +- Sources/Crypto/KEM/XWing.swift | 35 +-- .../Signatures/BoringSSL/MLDSA_boring.swift | 2 +- .../BoringSSL/MLDSA_boring.swift.gyb | 2 +- .../Signatures/BoringSSL/MLDSA_wrapper.swift | 36 ++- Sources/Crypto/Signatures/MLDSA.swift | 254 ++++++++++-------- Sources/Crypto/Signatures/MLDSA.swift.gyb | 133 ++++----- .../KEM/Boring/XWingTests_boring.swift | 8 +- Tests/CryptoTests/KEM/MLKEMKeyGenTests.swift | 17 -- Tests/CryptoTests/KEM/MLKEMTests.swift | 27 +- Tests/CryptoTests/KEM/XWingTests.swift | 20 +- .../Signatures/MLDSA/MLDSAKeyGenTests.swift | 17 -- .../Signatures/MLDSA/MLDSATests.swift | 21 +- Tests/_CryptoExtrasTests/MLDSATests.swift | 32 +-- 15 files changed, 345 insertions(+), 317 deletions(-) diff --git a/Sources/Crypto/KEM/BoringSSL/MLKEM_wrapper.swift b/Sources/Crypto/KEM/BoringSSL/MLKEM_wrapper.swift index 3306cedd6..4400dbd79 100644 --- a/Sources/Crypto/KEM/BoringSSL/MLKEM_wrapper.swift +++ b/Sources/Crypto/KEM/BoringSSL/MLKEM_wrapper.swift @@ -102,17 +102,26 @@ extension MLKEM768.InternalPrivateKey: BoringSSLBackedMLKEMPrivateKey { } init(seedRepresentation: Bytes, publicKeyRawRepresentation: Data?) throws where Bytes: DataProtocol { - precondition(publicKeyRawRepresentation == nil) - self = try .init(seedRepresentation: seedRepresentation) + let publicKeyHash = publicKeyRawRepresentation.map { + SHA3_256.hash(data: $0) + } + self = try .init(seedRepresentation: seedRepresentation, publicKeyHash: publicKeyHash) } init(seedRepresentation: Bytes, publicKeyHash: SHA3_256Digest?) throws { - precondition(publicKeyHash == nil) self = try .init(seedRepresentation: seedRepresentation) + let generatedHash = SHA3_256.hash(data: self.publicKey.rawRepresentation) + if let publicKeyHash, generatedHash != publicKeyHash { + throw KEM.Errors.publicKeyMismatchDuringInitialization + } } var integrityCheckedRepresentation: Data { - fatalError() + var representation = self.seedRepresentation + SHA3_256.hash(data: self.publicKey.rawRepresentation).withUnsafeBytes { + representation.append(contentsOf: $0) + } + return representation } var interiorPublicKey: MLKEM768.InternalPublicKey { @@ -155,17 +164,26 @@ extension MLKEM1024.InternalPrivateKey: BoringSSLBackedMLKEMPrivateKey { } init(seedRepresentation: Bytes, publicKeyRawRepresentation: Data?) throws where Bytes: DataProtocol { - precondition(publicKeyRawRepresentation == nil) - self = try .init(seedRepresentation: seedRepresentation) + let publicKeyHash = publicKeyRawRepresentation.map { + SHA3_256.hash(data: $0) + } + self = try .init(seedRepresentation: seedRepresentation, publicKeyHash: publicKeyHash) } init(seedRepresentation: Bytes, publicKeyHash: SHA3_256Digest?) throws { - precondition(publicKeyHash == nil) self = try .init(seedRepresentation: seedRepresentation) + let generatedHash = SHA3_256.hash(data: self.publicKey.rawRepresentation) + if let publicKeyHash, generatedHash != publicKeyHash { + throw KEM.Errors.publicKeyMismatchDuringInitialization + } } var integrityCheckedRepresentation: Data { - fatalError() + var representation = self.seedRepresentation + SHA3_256.hash(data: self.publicKey.rawRepresentation).withUnsafeBytes { + representation.append(contentsOf: $0) + } + return representation } var interiorPublicKey: MLKEM1024.InternalPublicKey { diff --git a/Sources/Crypto/KEM/BoringSSL/XWing_boring.swift b/Sources/Crypto/KEM/BoringSSL/XWing_boring.swift index 6d6aa724b..c9315c77d 100644 --- a/Sources/Crypto/KEM/BoringSSL/XWing_boring.swift +++ b/Sources/Crypto/KEM/BoringSSL/XWing_boring.swift @@ -30,8 +30,8 @@ struct OpenSSLXWingPublicKeyImpl: Sendable { self.publicKeyBytes = publicKeyBytes } - init(dataRepresentation: D) throws { - self.publicKeyBytes = try dataRepresentation.withUnsafeBytes { + init(rawRepresentation: D) throws { + self.publicKeyBytes = try rawRepresentation.withUnsafeBytes { guard $0.count == XWING_PUBLIC_KEY_BYTES else { throw CryptoKitError.incorrectKeySize } @@ -164,7 +164,7 @@ extension OpenSSLXWingPrivateKeyImpl { } // Matching CryptoKit, we only care that this _is_ a public key, not that it matches. - let _ = try OpenSSLXWingPublicKeyImpl(dataRepresentation: publicKeyBytes) + let _ = try OpenSSLXWingPublicKeyImpl(rawRepresentation: publicKeyBytes) } } @@ -187,6 +187,10 @@ extension OpenSSLXWingPrivateKeyImpl { throw CryptoKitError.internalBoringSSLError() } } + + if let publicKeyHash, publicKeyHash != self.publicKeyDigest { + throw KEM.Errors.publicKeyMismatchDuringInitialization + } } var seedRepresentation: Data { @@ -200,7 +204,11 @@ extension OpenSSLXWingPrivateKeyImpl { } var integrityCheckedRepresentation: Data { - fatalError() + var representation = self.seedRepresentation + self.publicKeyDigest.withUnsafeBytes { + representation.append(contentsOf: $0) + } + return representation } var dataRepresentation: Data { @@ -215,6 +223,14 @@ extension OpenSSLXWingPrivateKeyImpl { } } + private var publicKeyDigest: SHA3_256Digest { + withUnsafeTemporaryAllocation(byteCount: Int(XWING_PUBLIC_KEY_BYTES), alignment: 1) { + let rc = CCryptoBoringSSL_XWING_public_from_private($0.baseAddress, &self.privateKey) + precondition(rc == 1) + return SHA3_256.hash(bufferPointer: UnsafeRawBufferPointer($0)) + } + } + static func generate() throws -> Self { try Self() } diff --git a/Sources/Crypto/KEM/XWing.swift b/Sources/Crypto/KEM/XWing.swift index dad3f5127..2a368fce9 100644 --- a/Sources/Crypto/KEM/XWing.swift +++ b/Sources/Crypto/KEM/XWing.swift @@ -14,25 +14,12 @@ #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else -#if canImport(FoundationEssentials) -public import FoundationEssentials -#else -public import Foundation -#endif - -#if _runtime(_ObjC) && CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API -@_exported import CryptoKit -#else -#if CRYPTOKIT_NO_ACCESS_TO_FOUNDATION -import SwiftSystem -#else #if canImport(FoundationEssentials) import FoundationEssentials #else import Foundation #endif -#endif #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) @@ -61,8 +48,8 @@ extension XWingMLKEM768X25519 { self.impl = impl } - public init(dataRepresentation: D) throws { - self.impl = try .init(dataRepresentation: dataRepresentation) + public init(rawRepresentation: D) throws { + self.impl = try .init(rawRepresentation: rawRepresentation) } public var rawRepresentation: Data { @@ -96,20 +83,10 @@ extension XWingMLKEM768X25519 { self.impl = impl } - public init(bytes: D) throws { - self.impl = try .init(bytes: bytes) - } - internal init(seedRepresentation: D, publicKeyHash: SHA3_256Digest?) throws { self.impl = try .init(seedRepresentation: seedRepresentation, publicKeyHash: publicKeyHash) } - public var dataRepresentation: Data { - get { - self.impl.dataRepresentation - } - } - public static func generate() throws -> XWingMLKEM768X25519.PrivateKey { return try Self(impl: XWingPrivateKeyImpl.generate()) } @@ -133,17 +110,12 @@ extension XWingMLKEM768X25519.PrivateKey: HPKEKEMPrivateKeyGeneration { } public init(seedRepresentation: D, publicKey: XWingMLKEM768X25519.PublicKey?) throws { - #if false var publicKeyHash: SHA3_256Digest? = nil if publicKey != nil { publicKeyHash = SHA3_256.hash(data: publicKey!.rawRepresentation) } self = try XWingMLKEM768X25519.PrivateKey.init(seedRepresentation: seedRepresentation, publicKeyHash: publicKeyHash) - #else - precondition(publicKey == nil) - self = try XWingMLKEM768X25519.PrivateKey.init(seedRepresentation: seedRepresentation, publicKeyHash: nil) - #endif } public init(integrityCheckedRepresentation: D) throws { @@ -178,7 +150,7 @@ extension XWingMLKEM768X25519.PublicKey: HPKEKEMPublicKey { /// - Throws: ``CryptoKit/HPKE/Errors/inconsistentCiphersuiteAndKey`` if the key encapsulation mechanism requested is incompatible with this public key. public init(_ serialization: D, kem: HPKE.KEM) throws where D: ContiguousBytes { try Self.validateCiphersuite(kem) - try self.init(dataRepresentation: serialization) + try self.init(rawRepresentation: serialization) } /// Creates a serialized representation of the public key. @@ -197,5 +169,4 @@ extension XWingMLKEM768X25519.PublicKey: HPKEKEMPublicKey { /// The type of the ephemeral private key associated with this public key. public typealias HPKEEphemeralPrivateKey = XWingMLKEM768X25519.PrivateKey } -#endif #endif // Linux or !SwiftPM diff --git a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift index bfba93044..05150b49f 100644 --- a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift +++ b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift @@ -639,7 +639,7 @@ extension MLDSA87 { enum MLDSA { /// The size of the seed in bytes. - fileprivate static let seedByteCount = 32 + static let seedByteCount = 32 } #endif // CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API diff --git a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb index ee0b1f0c8..27aaa2396 100644 --- a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb +++ b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb @@ -342,7 +342,7 @@ extension MLDSA${parameter_set} { enum MLDSA { /// The size of the seed in bytes. - fileprivate static let seedByteCount = 32 + static let seedByteCount = 32 } #endif // CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API diff --git a/Sources/Crypto/Signatures/BoringSSL/MLDSA_wrapper.swift b/Sources/Crypto/Signatures/BoringSSL/MLDSA_wrapper.swift index 671847b3e..a02db5076 100644 --- a/Sources/Crypto/Signatures/BoringSSL/MLDSA_wrapper.swift +++ b/Sources/Crypto/Signatures/BoringSSL/MLDSA_wrapper.swift @@ -84,18 +84,29 @@ extension MLDSA87.InternalPublicKey: BoringSSLBackedMLDSAPublicKey {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) struct OpenSSLMLDSAPrivateKeyImpl { private var backing: Parameters.BackingPrivateKey + private let publicKeyHash: SHA3_256Digest init() throws { self.backing = try .init() + self.publicKeyHash = SHA3_256.hash(data: self.backing.publicKey.rawRepresentation) } - init(seedRepresentation: D, publicKey: OpenSSLMLDSAPublicKeyImpl?) throws { - precondition(publicKey == nil) - self.backing = try .init(seedRepresentation: seedRepresentation) + init(seedRepresentation: D, publicKeyRawRepresentation: Data?) throws { + let publicKeyHash = publicKeyRawRepresentation.map { + SHA3_256.hash(data: $0) + } + self = try Self(seedRepresentation: seedRepresentation, publicKeyHash: publicKeyHash) } - init(integrityCheckedRepresentation: D) throws { - fatalError() + init(seedRepresentation: D, publicKeyHash: SHA3_256Digest?) throws { + self.backing = try .init(seedRepresentation: seedRepresentation) + let generatedHash = SHA3_256.hash(data: self.backing.publicKey.rawRepresentation) + + if let publicKeyHash, generatedHash != publicKeyHash { + throw CryptoKitError.unwrapFailure + } + + self.publicKeyHash = generatedHash } func signature(for data: D) throws -> Data { @@ -115,7 +126,16 @@ struct OpenSSLMLDSAPrivateKeyImpl { } var integrityCheckedRepresentation: Data { - fatalError() + var representation = self.seedRepresentation + representation.reserveCapacity(SHA3_256Digest.byteCount) + self.publicKeyHash.withUnsafeBytes { + representation.append(contentsOf: $0) + } + return representation + } + + static var seedSize: Int { + MLDSA.seedByteCount } } @@ -132,14 +152,14 @@ struct OpenSSLMLDSAPublicKeyImpl { } func isValidSignature( - signature: S, + _ signature: S, for data: D ) -> Bool { self.backing.isValidSignature(signature, for: data) } func isValidSignature( - signature: S, + _ signature: S, for data: D, context: C ) -> Bool { diff --git a/Sources/Crypto/Signatures/MLDSA.swift b/Sources/Crypto/Signatures/MLDSA.swift index 9f5842dff..b3f2cce07 100644 --- a/Sources/Crypto/Signatures/MLDSA.swift +++ b/Sources/Crypto/Signatures/MLDSA.swift @@ -21,8 +21,10 @@ public import Foundation #endif #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION -typealias MLDSAPublicKeyImpl = CoreCryptoMLDSAPublicKeyImpl -typealias MLDSAPrivateKeyImpl = CoreCryptoMLDSAPrivateKeyImpl +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +typealias MLDSAPublicKeyImpl = CorecryptoMLDSAPublicKeyImpl +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +typealias MLDSAPrivateKeyImpl = CorecryptoMLDSAPrivateKeyImpl #else @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) typealias MLDSAPublicKeyImpl = OpenSSLMLDSAPublicKeyImpl @@ -38,83 +40,64 @@ public enum MLDSA65: Sendable {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLDSA65 { /// The public key for MLDSA65. + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) public struct PublicKey: Sendable { var impl: MLDSAPublicKeyImpl - /// Verifies a MLDSA65 signature. - /// - Parameters: - /// - signature: The MLDSA65 signature to verify. - /// - data: The signed data. - /// - Returns: `true` if the signature is valid, `false` otherwise. - public func isValidSignature(signature: S, for data: D) -> Bool { - self.impl.isValidSignature(signature: signature, for: data) - } - - /// Verifies a MLDSA65 signature, in a specific context. - /// - Parameters: - /// - signature: The MLDSA65 signature to verify. - /// - data: The signed data. - /// - context: Context for the signature. - /// - Returns: `true` if the signature is valid in the specified context, `false` otherwise. - public func isValidSignature(signature: S, for data: D, context: C) -> Bool { - self.impl.isValidSignature(signature: signature, for: data, context: context) + internal init(_ impl: MLDSAPublicKeyImpl) { + self.impl = impl } - + /// Parses a public key from a serialized representation. /// /// - Parameter rawRepresentation: The public key, in the FIPS 204 standard serialization format. /// - Returns: The deserialized public key. public init(rawRepresentation: D) throws { - self.impl = try .init(rawRepresentation: rawRepresentation) + self.impl = try MLDSAPublicKeyImpl(rawRepresentation: rawRepresentation) } - + /// A serialized representation of the public key. /// /// This property provides a representation of the public key in the FIPS 204 standard serialization format. public var rawRepresentation: Data { get { - self.impl.rawRepresentation + return self.impl.rawRepresentation } } - fileprivate init(impl: MLDSAPublicKeyImpl) { - self.impl = impl - } - } - - /// The private key for MLDSA65. - public struct PrivateKey: Signer, Sendable { - var impl: MLDSAPrivateKeyImpl - - /// Generates a MLDSA65 signature. + /// Verifies a MLDSA65 signature. /// - Parameters: - /// - data: The data to sign. - /// - Returns: The MLDSA65 signature. - /// This method throws if CryptoKit encounters an error producing the signature. - public func signature(for data: D) throws -> Data { - try self.impl.signature(for: data) + /// - signature: The MLDSA65 signature to verify. + /// - data: The signed data. + /// - Returns: `true` if the signature is valid, `false` otherwise. + public func isValidSignature(_ signature: S, for data: D) -> Bool { + return self.impl.isValidSignature(signature, for: data) } - /// Generates a MLDSA65 signature, with context. + /// Verifies a MLDSA65 signature, in a specific context. /// - Parameters: - /// - data: The data to sign. + /// - signature: The MLDSA65 signature to verify. + /// - data: The signed data. /// - context: Context for the signature. - /// - Returns: The MLDSA65 signature. - /// This method throws if CryptoKit encounters an error producing the signature. - public func signature(for data: D, context: C) throws -> Data { - try self.impl.signature(for: data, context: context) + /// - Returns: `true` if the signature is valid in the specified context, `false` otherwise. + public func isValidSignature(_ signature: S, for data: D, context: C) -> Bool { + return self.impl.isValidSignature(signature, for: data, context: context) } + } - /// The associated public key. - public var publicKey: PublicKey { - get { - PublicKey(impl: self.impl.publicKey) - } + /// The private key for MLDSA65. + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) + public struct PrivateKey: Signer, Sendable { + internal let impl: MLDSAPrivateKeyImpl + + internal init(_ impl: MLDSAPrivateKeyImpl) { + self.impl = impl } - + /// Initializes a new random private key. public init() throws { - self.impl = try .init() + let impl = try MLDSAPrivateKeyImpl() + self = PrivateKey(impl) } /// Initializes a private key from the seed representation. @@ -126,9 +109,13 @@ extension MLDSA65 { /// /// If a public key is provided, a consistency check is performed between it and the derived public key. public init(seedRepresentation: D, publicKey: MLDSA65.PublicKey?) throws { - self.impl = try .init(seedRepresentation: seedRepresentation, publicKey: publicKey?.impl) + var publicKeyRawRepresentation: Data? = nil + if publicKey != nil { + publicKeyRawRepresentation = publicKey!.rawRepresentation + } + self.impl = try MLDSAPrivateKeyImpl(seedRepresentation: seedRepresentation, publicKeyRawRepresentation: publicKeyRawRepresentation) } - + /// The seed representation of the private key. /// /// The seed representation is 32 bytes long, and is the parameter @@ -139,12 +126,47 @@ extension MLDSA65 { } } + /// Generates a MLDSA65 signature. + /// - Parameters: + /// - data: The data to sign. + /// - Returns: The MLDSA65 signature. + /// This method throws if CryptoKit encounters an error producing the signature. + public func signature(for data: D) throws -> Data { + return try impl.signature(for: data) + } + + /// Generates a MLDSA65 signature, with context. + /// - Parameters: + /// - data: The data to sign. + /// - context: Context for the signature. + /// - Returns: The MLDSA65 signature. + /// This method throws if CryptoKit encounters an error producing the signature. + public func signature(for data: D, context: C) throws -> Data { + return try impl.signature(for: data, context: context) + } + + /// The associated public key. + public var publicKey: PublicKey { + get { + PublicKey(impl.publicKey) + } + } + /// Initializes a private key from an integrity-checked data representation. /// /// - Parameter integrityCheckedRepresentation: The integrity-checked data representation of the private key. /// The parameter needs to be 64 bytes long, and contain the seed and a hash of the public key. public init(integrityCheckedRepresentation: D) throws { - self.impl = try .init(integrityCheckedRepresentation: integrityCheckedRepresentation) + let seedSize = MLDSAPrivateKeyImpl.seedSize + guard integrityCheckedRepresentation.count == seedSize + 32 else { + throw CryptoKitError.incorrectParameterSize + } + + let seed = Data(integrityCheckedRepresentation).subdata(in: 0..(seedRepresentation: seed, publicKeyHash: publicKeyHash) } /// The integrity-checked data representation of the private key. @@ -166,83 +188,64 @@ public enum MLDSA87: Sendable {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLDSA87 { /// The public key for MLDSA87. + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) public struct PublicKey: Sendable { var impl: MLDSAPublicKeyImpl - /// Verifies a MLDSA87 signature. - /// - Parameters: - /// - signature: The MLDSA87 signature to verify. - /// - data: The signed data. - /// - Returns: `true` if the signature is valid, `false` otherwise. - public func isValidSignature(signature: S, for data: D) -> Bool { - self.impl.isValidSignature(signature: signature, for: data) - } - - /// Verifies a MLDSA87 signature, in a specific context. - /// - Parameters: - /// - signature: The MLDSA87 signature to verify. - /// - data: The signed data. - /// - context: Context for the signature. - /// - Returns: `true` if the signature is valid in the specified context, `false` otherwise. - public func isValidSignature(signature: S, for data: D, context: C) -> Bool { - self.impl.isValidSignature(signature: signature, for: data, context: context) + internal init(_ impl: MLDSAPublicKeyImpl) { + self.impl = impl } - + /// Parses a public key from a serialized representation. /// /// - Parameter rawRepresentation: The public key, in the FIPS 204 standard serialization format. /// - Returns: The deserialized public key. public init(rawRepresentation: D) throws { - self.impl = try .init(rawRepresentation: rawRepresentation) + self.impl = try MLDSAPublicKeyImpl(rawRepresentation: rawRepresentation) } - + /// A serialized representation of the public key. /// /// This property provides a representation of the public key in the FIPS 204 standard serialization format. public var rawRepresentation: Data { get { - self.impl.rawRepresentation + return self.impl.rawRepresentation } } - fileprivate init(impl: MLDSAPublicKeyImpl) { - self.impl = impl - } - } - - /// The private key for MLDSA87. - public struct PrivateKey: Signer, Sendable { - var impl: MLDSAPrivateKeyImpl - - /// Generates a MLDSA87 signature. + /// Verifies a MLDSA87 signature. /// - Parameters: - /// - data: The data to sign. - /// - Returns: The MLDSA87 signature. - /// This method throws if CryptoKit encounters an error producing the signature. - public func signature(for data: D) throws -> Data { - try self.impl.signature(for: data) + /// - signature: The MLDSA87 signature to verify. + /// - data: The signed data. + /// - Returns: `true` if the signature is valid, `false` otherwise. + public func isValidSignature(_ signature: S, for data: D) -> Bool { + return self.impl.isValidSignature(signature, for: data) } - /// Generates a MLDSA87 signature, with context. + /// Verifies a MLDSA87 signature, in a specific context. /// - Parameters: - /// - data: The data to sign. + /// - signature: The MLDSA87 signature to verify. + /// - data: The signed data. /// - context: Context for the signature. - /// - Returns: The MLDSA87 signature. - /// This method throws if CryptoKit encounters an error producing the signature. - public func signature(for data: D, context: C) throws -> Data { - try self.impl.signature(for: data, context: context) + /// - Returns: `true` if the signature is valid in the specified context, `false` otherwise. + public func isValidSignature(_ signature: S, for data: D, context: C) -> Bool { + return self.impl.isValidSignature(signature, for: data, context: context) } + } - /// The associated public key. - public var publicKey: PublicKey { - get { - PublicKey(impl: self.impl.publicKey) - } + /// The private key for MLDSA87. + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) + public struct PrivateKey: Signer, Sendable { + internal let impl: MLDSAPrivateKeyImpl + + internal init(_ impl: MLDSAPrivateKeyImpl) { + self.impl = impl } - + /// Initializes a new random private key. public init() throws { - self.impl = try .init() + let impl = try MLDSAPrivateKeyImpl() + self = PrivateKey(impl) } /// Initializes a private key from the seed representation. @@ -254,9 +257,13 @@ extension MLDSA87 { /// /// If a public key is provided, a consistency check is performed between it and the derived public key. public init(seedRepresentation: D, publicKey: MLDSA87.PublicKey?) throws { - self.impl = try .init(seedRepresentation: seedRepresentation, publicKey: publicKey?.impl) + var publicKeyRawRepresentation: Data? = nil + if publicKey != nil { + publicKeyRawRepresentation = publicKey!.rawRepresentation + } + self.impl = try MLDSAPrivateKeyImpl(seedRepresentation: seedRepresentation, publicKeyRawRepresentation: publicKeyRawRepresentation) } - + /// The seed representation of the private key. /// /// The seed representation is 32 bytes long, and is the parameter @@ -267,12 +274,47 @@ extension MLDSA87 { } } + /// Generates a MLDSA87 signature. + /// - Parameters: + /// - data: The data to sign. + /// - Returns: The MLDSA87 signature. + /// This method throws if CryptoKit encounters an error producing the signature. + public func signature(for data: D) throws -> Data { + return try impl.signature(for: data) + } + + /// Generates a MLDSA87 signature, with context. + /// - Parameters: + /// - data: The data to sign. + /// - context: Context for the signature. + /// - Returns: The MLDSA87 signature. + /// This method throws if CryptoKit encounters an error producing the signature. + public func signature(for data: D, context: C) throws -> Data { + return try impl.signature(for: data, context: context) + } + + /// The associated public key. + public var publicKey: PublicKey { + get { + PublicKey(impl.publicKey) + } + } + /// Initializes a private key from an integrity-checked data representation. /// /// - Parameter integrityCheckedRepresentation: The integrity-checked data representation of the private key. /// The parameter needs to be 64 bytes long, and contain the seed and a hash of the public key. public init(integrityCheckedRepresentation: D) throws { - self.impl = try .init(integrityCheckedRepresentation: integrityCheckedRepresentation) + let seedSize = MLDSAPrivateKeyImpl.seedSize + guard integrityCheckedRepresentation.count == seedSize + 32 else { + throw CryptoKitError.incorrectParameterSize + } + + let seed = Data(integrityCheckedRepresentation).subdata(in: 0..(seedRepresentation: seed, publicKeyHash: publicKeyHash) } /// The integrity-checked data representation of the private key. diff --git a/Sources/Crypto/Signatures/MLDSA.swift.gyb b/Sources/Crypto/Signatures/MLDSA.swift.gyb index a0cab6fe4..5378503a1 100644 --- a/Sources/Crypto/Signatures/MLDSA.swift.gyb +++ b/Sources/Crypto/Signatures/MLDSA.swift.gyb @@ -19,22 +19,21 @@ public import FoundationEssentials #else public import Foundation #endif +%{ + MLDSA_VARIANTS = [{"name": "MLDSA65"}, {"name": "MLDSA87"}] +}% #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION -typealias MLDSAPublicKeyImpl = CoreCryptoMLDSAPublicKeyImpl -typealias MLDSAPrivateKeyImpl = CoreCryptoMLDSAPrivateKeyImpl +typealias MLDSAPublicKeyImpl = CorecryptoMLDSAPublicKeyImpl +typealias MLDSAPrivateKeyImpl = CorecryptoMLDSAPrivateKeyImpl #else typealias MLDSAPublicKeyImpl = OpenSSLMLDSAPublicKeyImpl typealias MLDSAPrivateKeyImpl = OpenSSLMLDSAPrivateKeyImpl #endif -%{ - MLDSA_VARIANTS = [{"name": "MLDSA65", "ccinfo": "ccmldsa65()!"}, {"name": "MLDSA87", "ccinfo": "ccmldsa87()!"}] -}% % for MLDSA_VARIANT in MLDSA_VARIANTS: %{ NAME = MLDSA_VARIANT["name"] - INFO = MLDSA_VARIANT["ccinfo"] }% /// The ${NAME} Digital Signature Algorithm @@ -44,81 +43,56 @@ extension ${NAME} { /// The public key for ${NAME}. public struct PublicKey: Sendable { var impl: MLDSAPublicKeyImpl<${NAME}> - - /// Verifies a ${NAME} signature. - /// - Parameters: - /// - signature: The ${NAME} signature to verify. - /// - data: The signed data. - /// - Returns: `true` if the signature is valid, `false` otherwise. - public func isValidSignature(signature: S, for data: D) -> Bool { - self.impl.isValidSignature(signature: signature, for: data) - } - - /// Verifies a ${NAME} signature, in a specific context. - /// - Parameters: - /// - signature: The ${NAME} signature to verify. - /// - data: The signed data. - /// - context: Context for the signature. - /// - Returns: `true` if the signature is valid in the specified context, `false` otherwise. - public func isValidSignature(signature: S, for data: D, context: C) -> Bool { - self.impl.isValidSignature(signature: signature, for: data, context: context) - } - + /// Parses a public key from a serialized representation. /// /// - Parameter rawRepresentation: The public key, in the FIPS 204 standard serialization format. /// - Returns: The deserialized public key. public init(rawRepresentation: D) throws { - self.impl = try .init(rawRepresentation: rawRepresentation) + self.impl = try MLDSAPublicKeyImpl(rawRepresentation: rawRepresentation) } - + /// A serialized representation of the public key. /// /// This property provides a representation of the public key in the FIPS 204 standard serialization format. public var rawRepresentation: Data { get { - self.impl.rawRepresentation + return self.impl.rawRepresentation } } - fileprivate init(impl: MLDSAPublicKeyImpl<${NAME}>) { - self.impl = impl - } - } - - /// The private key for ${NAME}. - public struct PrivateKey: Signer, Sendable { - var impl: MLDSAPrivateKeyImpl<${NAME}> - - /// Generates a ${NAME} signature. + /// Verifies a ${NAME} signature. /// - Parameters: - /// - data: The data to sign. - /// - Returns: The ${NAME} signature. - /// This method throws if CryptoKit encounters an error producing the signature. - public func signature(for data: D) throws -> Data { - try self.impl.signature(for: data) + /// - signature: The ${NAME} signature to verify. + /// - data: The signed data. + /// - Returns: `true` if the signature is valid, `false` otherwise. + public func isValidSignature(_ signature: S, for data: D) -> Bool { + return self.impl.isValidSignature(signature, for: data) } - /// Generates a ${NAME} signature, with context. + /// Verifies a ${NAME} signature, in a specific context. /// - Parameters: - /// - data: The data to sign. + /// - signature: The ${NAME} signature to verify. + /// - data: The signed data. /// - context: Context for the signature. - /// - Returns: The ${NAME} signature. - /// This method throws if CryptoKit encounters an error producing the signature. - public func signature(for data: D, context: C) throws -> Data { - try self.impl.signature(for: data, context: context) + /// - Returns: `true` if the signature is valid in the specified context, `false` otherwise. + public func isValidSignature(_ signature: S, for data: D, context: C) -> Bool { + return self.impl.isValidSignature(signature, for: data, context: context) } + } - /// The associated public key. - public var publicKey: PublicKey { - get { - PublicKey(impl: self.impl.publicKey) - } + /// The private key for ${NAME}. + public struct PrivateKey: Signer, Sendable { + internal let impl: MLDSAPrivateKeyImpl<${NAME}> + + internal init(_ impl: MLDSAPrivateKeyImpl<${NAME}>) { + self.impl = impl } - + /// Initializes a new random private key. public init() throws { - self.impl = try .init() + let impl = try MLDSAPrivateKeyImpl<${NAME}>() + self = PrivateKey(impl) } /// Initializes a private key from the seed representation. @@ -130,9 +104,13 @@ extension ${NAME} { /// /// If a public key is provided, a consistency check is performed between it and the derived public key. public init(seedRepresentation: D, publicKey: ${NAME}.PublicKey?) throws { - self.impl = try .init(seedRepresentation: seedRepresentation, publicKey: publicKey?.impl) + var publicKeyRawRepresentation: Data? = nil + if publicKey != nil { + publicKeyRawRepresentation = publicKey!.rawRepresentation + } + self.impl = try MLDSAPrivateKeyImpl<${NAME}>(seedRepresentation: seedRepresentation, publicKeyRawRepresentation: publicKeyRawRepresentation) } - + /// The seed representation of the private key. /// /// The seed representation is 32 bytes long, and is the parameter @@ -143,12 +121,47 @@ extension ${NAME} { } } + /// Generates a ${NAME} signature. + /// - Parameters: + /// - data: The data to sign. + /// - Returns: The ${NAME} signature. + /// This method throws if CryptoKit encounters an error producing the signature. + public func signature(for data: D) throws -> Data { + return try impl.signature(for: data) + } + + /// Generates a ${NAME} signature, with context. + /// - Parameters: + /// - data: The data to sign. + /// - context: Context for the signature. + /// - Returns: The ${NAME} signature. + /// This method throws if CryptoKit encounters an error producing the signature. + public func signature(for data: D, context: C) throws -> Data { + return try impl.signature(for: data, context: context) + } + + /// The associated public key. + public var publicKey: PublicKey { + get { + PublicKey(impl.publicKey) + } + } + /// Initializes a private key from an integrity-checked data representation. /// /// - Parameter integrityCheckedRepresentation: The integrity-checked data representation of the private key. /// The parameter needs to be 64 bytes long, and contain the seed and a hash of the public key. public init(integrityCheckedRepresentation: D) throws { - self.impl = try .init(integrityCheckedRepresentation: integrityCheckedRepresentation) + let seedSize = MLDSAPrivateKeyImpl<${NAME}>.seedSize + guard integrityCheckedRepresentation.count == seedSize + 32 else { + throw CryptoKitError.incorrectParameterSize + } + + let seed = Data(integrityCheckedRepresentation).subdata(in: 0..(seedRepresentation: seed, publicKeyHash: publicKeyHash) } /// The integrity-checked data representation of the private key. diff --git a/Tests/CryptoTests/KEM/Boring/XWingTests_boring.swift b/Tests/CryptoTests/KEM/Boring/XWingTests_boring.swift index 07180137d..ea3890f72 100644 --- a/Tests/CryptoTests/KEM/Boring/XWingTests_boring.swift +++ b/Tests/CryptoTests/KEM/Boring/XWingTests_boring.swift @@ -22,13 +22,13 @@ #endif extension XWingMLKEM768X25519.PrivateKey { - static func generateWithRng(ccrngState: SequenceDrbg) throws -> Self { + static func generateWithRng(rngState: SequenceDrbg) throws -> Self { // We're going to generate a "random" seed. var seed: [UInt8] = [] seed.reserveCapacity(32) for i in 0..<32 { - seed.append(ccrngState.state[i % ccrngState.state.count]) + seed.append(rngState.state[i % rngState.state.count]) } return try Self(seedRepresentation: seed, publicKey: nil) @@ -36,13 +36,13 @@ extension XWingMLKEM768X25519.PrivateKey { } extension XWingMLKEM768X25519.PublicKey { - func encapsulateWithRng(ccrngState: SequenceDrbg) throws -> KEM.EncapsulationResult { + func encapsulateWithRng(rngState: SequenceDrbg) throws -> KEM.EncapsulationResult { // We're going to generate "random" entropy var seed: [UInt8] = [] seed.reserveCapacity(64) for i in 0..<64 { - seed.append(ccrngState.state[i % ccrngState.state.count]) + seed.append(rngState.state[i % rngState.state.count]) } return try self.impl.encapsulateWithOptionalEntropy(entropy: seed) diff --git a/Tests/CryptoTests/KEM/MLKEMKeyGenTests.swift b/Tests/CryptoTests/KEM/MLKEMKeyGenTests.swift index a2a4d194a..6eec1c6f9 100644 --- a/Tests/CryptoTests/KEM/MLKEMKeyGenTests.swift +++ b/Tests/CryptoTests/KEM/MLKEMKeyGenTests.swift @@ -12,7 +12,6 @@ // //===----------------------------------------------------------------------===// import XCTest - #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API // Skip tests that require @testable imports of CryptoKit. #else @@ -40,28 +39,20 @@ final class MLKEMKeyGenTests: XCTestCase { let katTests = try processKeyGenKATFile(filename:"MLKEM768_BSSLKAT") for katTest in katTests { let publicKey = try MLKEM768.PublicKey(rawRepresentation: katTest.pk) - #if false let privateKey = try MLKEM768.PrivateKey(seedRepresentation: katTest.dz, publicKey: publicKey) let publicKeyHash = Data(SHA3_256.hash(data: privateKey.publicKey.rawRepresentation)) - #else - let privateKey = try MLKEM768.PrivateKey(seedRepresentation: katTest.dz, publicKey: nil) - #endif XCTAssert(privateKey.seedRepresentation == katTest.dz) - #if false XCTAssert(privateKey.integrityCheckedRepresentation == katTest.dz + publicKeyHash) - #endif XCTAssert(privateKey.publicKey.rawRepresentation == katTest.pk) // Try initializing keys with incorrect integrity checks - #if false let randomPrivateKey = try MLKEM768.PrivateKey.generate() let randomPublicKeyHash = Data(SHA3_256.hash(data: randomPrivateKey.publicKey.rawRepresentation)) XCTAssertThrowsError(try MLKEM768.PrivateKey(seedRepresentation: privateKey.seedRepresentation, publicKey: randomPrivateKey.publicKey), error: KEM.Errors.publicKeyMismatchDuringInitialization) XCTAssertThrowsError(try MLKEM768.PrivateKey(seedRepresentation: randomPrivateKey.seedRepresentation, publicKey: publicKey), error: KEM.Errors.publicKeyMismatchDuringInitialization) XCTAssertThrowsError(try MLKEM768.PrivateKey(integrityCheckedRepresentation: privateKey.seedRepresentation + randomPublicKeyHash), error: KEM.Errors.publicKeyMismatchDuringInitialization) XCTAssertThrowsError(try MLKEM768.PrivateKey(integrityCheckedRepresentation: randomPrivateKey.seedRepresentation + publicKeyHash), error: KEM.Errors.publicKeyMismatchDuringInitialization) - #endif } } @@ -70,28 +61,20 @@ final class MLKEMKeyGenTests: XCTestCase { let katTests = try processKeyGenKATFile(filename:"MLKEM1024_BSSLKAT") for katTest in katTests { let publicKey = try MLKEM1024.PublicKey(rawRepresentation: katTest.pk) - #if false let privateKey = try MLKEM1024.PrivateKey(seedRepresentation: katTest.dz, publicKey: publicKey) let publicKeyHash = Data(SHA3_256.hash(data: privateKey.publicKey.rawRepresentation)) - #else - let privateKey = try MLKEM1024.PrivateKey(seedRepresentation: katTest.dz, publicKey: nil) - #endif XCTAssert(privateKey.seedRepresentation == katTest.dz) - #if false XCTAssert(privateKey.integrityCheckedRepresentation == katTest.dz + publicKeyHash) - #endif XCTAssert(privateKey.publicKey.rawRepresentation == katTest.pk) // Try initializing keys with incorrect integrity checks - #if false let randomPrivateKey = try MLKEM1024.PrivateKey.generate() let randomPublicKeyHash = Data(SHA3_256.hash(data: randomPrivateKey.publicKey.rawRepresentation)) XCTAssertThrowsError(try MLKEM1024.PrivateKey(seedRepresentation: privateKey.seedRepresentation, publicKey: randomPrivateKey.publicKey), error: KEM.Errors.publicKeyMismatchDuringInitialization) XCTAssertThrowsError(try MLKEM1024.PrivateKey(seedRepresentation: randomPrivateKey.seedRepresentation, publicKey: publicKey), error: KEM.Errors.publicKeyMismatchDuringInitialization) XCTAssertThrowsError(try MLKEM1024.PrivateKey(integrityCheckedRepresentation: privateKey.seedRepresentation + randomPublicKeyHash), error: KEM.Errors.publicKeyMismatchDuringInitialization) XCTAssertThrowsError(try MLKEM1024.PrivateKey(integrityCheckedRepresentation: randomPrivateKey.seedRepresentation + publicKeyHash), error: KEM.Errors.publicKeyMismatchDuringInitialization) - #endif } } } diff --git a/Tests/CryptoTests/KEM/MLKEMTests.swift b/Tests/CryptoTests/KEM/MLKEMTests.swift index c5a22935c..4126a05d6 100644 --- a/Tests/CryptoTests/KEM/MLKEMTests.swift +++ b/Tests/CryptoTests/KEM/MLKEMTests.swift @@ -12,7 +12,6 @@ // //===----------------------------------------------------------------------===// import XCTest - #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API // Skip tests that require @testable imports of CryptoKit. #else @@ -31,12 +30,8 @@ final class MLKEMTests: XCTestCase { try XCTAssert(publicKey.rawRepresentation == MLKEM768.PublicKey(rawRepresentation: publicKey.rawRepresentation).rawRepresentation) // Test Private Key serialization - #if false try XCTAssert(privateKey.seedRepresentation == MLKEM768.PrivateKey(seedRepresentation: privateKey.seedRepresentation, publicKey: publicKey).seedRepresentation) try XCTAssert(privateKey.integrityCheckedRepresentation == MLKEM768.PrivateKey(integrityCheckedRepresentation: privateKey.integrityCheckedRepresentation).integrityCheckedRepresentation) - #else - try XCTAssert(privateKey.seedRepresentation == MLKEM768.PrivateKey(seedRepresentation: privateKey.seedRepresentation, publicKey: nil).seedRepresentation) - #endif let er = try publicKey.encapsulate() let ss = try privateKey.decapsulate(er.encapsulated) @@ -52,12 +47,8 @@ final class MLKEMTests: XCTestCase { try XCTAssert(publicKey.rawRepresentation == MLKEM1024.PublicKey(rawRepresentation: publicKey.rawRepresentation).rawRepresentation) // Test Private Key serialization - #if false try XCTAssert(privateKey.seedRepresentation == MLKEM1024.PrivateKey(seedRepresentation: privateKey.seedRepresentation, publicKey: publicKey).seedRepresentation) try XCTAssert(privateKey.integrityCheckedRepresentation == MLKEM1024.PrivateKey(integrityCheckedRepresentation: privateKey.integrityCheckedRepresentation).integrityCheckedRepresentation) - #else - try XCTAssert(privateKey.seedRepresentation == MLKEM1024.PrivateKey(seedRepresentation: privateKey.seedRepresentation, publicKey: nil).seedRepresentation) - #endif let er = try publicKey.encapsulate() let ss = try privateKey.decapsulate(er.encapsulated) @@ -80,6 +71,7 @@ final class MLKEMTests: XCTestCase { func test768KAT() throws { #if CRYPTO_IN_SWIFTPM + // No support for encapsulateWithSeed in BoringSSL. throw XCTSkip() #else let katTests = try processKATFile(filename:"MLKEM768KAT") @@ -87,12 +79,12 @@ final class MLKEMTests: XCTestCase { let rndGen = try Drbg(katTest.rngSeed) var keyGenSeed = Data(count: 64) - keyGenSeed.withUnsafeMutableBytes { buffer in - buffer.initializeWithRandomBytes(count: buffer.count, ccrngState: rndGen.detRngPtr) + try keyGenSeed.withUnsafeMutableBytes { buffer in + try buffer.initializeWithRandomBytes(count: buffer.count, rngState: rndGen) } var encapSeed = Data(count: 32) - encapSeed.withUnsafeMutableBytes { buffer in - buffer.initializeWithRandomBytes(count: buffer.count, ccrngState: rndGen.detRngPtr) + try encapSeed.withUnsafeMutableBytes { buffer in + try buffer.initializeWithRandomBytes(count: buffer.count, rngState: rndGen) } let privateKey = try MLKEM768.PrivateKey.generateWithSeed(keyGenSeed) // 2 * 32 bytes @@ -110,6 +102,7 @@ final class MLKEMTests: XCTestCase { func test1024KAT() throws { #if CRYPTO_IN_SWIFTPM + // No support for encapsulateWithSeed in BoringSSL. throw XCTSkip() #else let katTests = try processKATFile(filename:"MLKEM1024KAT") @@ -117,12 +110,12 @@ final class MLKEMTests: XCTestCase { let rndGen = try Drbg(katTest.rngSeed) var keyGenSeed = Data(count: 64) - keyGenSeed.withUnsafeMutableBytes { buffer in - buffer.initializeWithRandomBytes(count: buffer.count, ccrngState: rndGen.detRngPtr) + try keyGenSeed.withUnsafeMutableBytes { buffer in + try buffer.initializeWithRandomBytes(count: buffer.count, rngState: rndGen) } var encapSeed = Data(count: 32) - encapSeed.withUnsafeMutableBytes { buffer in - buffer.initializeWithRandomBytes(count: buffer.count, ccrngState: rndGen.detRngPtr) + try encapSeed.withUnsafeMutableBytes { buffer in + try buffer.initializeWithRandomBytes(count: buffer.count, rngState: rndGen) } let privateKey = try MLKEM1024.PrivateKey.generateWithSeed(keyGenSeed) diff --git a/Tests/CryptoTests/KEM/XWingTests.swift b/Tests/CryptoTests/KEM/XWingTests.swift index 32a34f019..22e5e19b0 100644 --- a/Tests/CryptoTests/KEM/XWingTests.swift +++ b/Tests/CryptoTests/KEM/XWingTests.swift @@ -12,7 +12,6 @@ // //===----------------------------------------------------------------------===// import XCTest - #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API // Skip tests that require @testable imports of CryptoKit. #else @@ -28,10 +27,12 @@ final class XWingTests: XCTestCase { let publicKey = privateKey.publicKey - try XCTAssert(publicKey.rawRepresentation == XWingMLKEM768X25519.PublicKey(dataRepresentation: publicKey.rawRepresentation).rawRepresentation) - try XCTAssert(privateKey.dataRepresentation == XWingMLKEM768X25519.PrivateKey(bytes: privateKey.dataRepresentation).dataRepresentation) + try XCTAssert(publicKey.rawRepresentation == XWingMLKEM768X25519.PublicKey(rawRepresentation: publicKey.rawRepresentation).rawRepresentation) + try XCTAssert(privateKey.seedRepresentation == XWingMLKEM768X25519.PrivateKey(seedRepresentation: privateKey.seedRepresentation, publicKey: nil).seedRepresentation) + try XCTAssert(privateKey.seedRepresentation == XWingMLKEM768X25519.PrivateKey(seedRepresentation: privateKey.seedRepresentation, publicKey: publicKey).seedRepresentation) + try XCTAssert(privateKey.integrityCheckedRepresentation == XWingMLKEM768X25519.PrivateKey(integrityCheckedRepresentation: privateKey.integrityCheckedRepresentation).integrityCheckedRepresentation) - let er = try publicKey.encapsulate() + let er = try privateKey.publicKey.encapsulate() let ss = try privateKey.decapsulate(er.encapsulated) XCTAssert(er.sharedSecret == ss) @@ -54,12 +55,11 @@ final class XWingTests: XCTestCase { let katTests = try processKATFile(filename:"test-vectors") for katTest in katTests { let privateKeyDrbg = try SequenceDrbg(katTest.seed) - let privateKey = try XWingMLKEM768X25519.PrivateKey.generateWithRng(ccrngState: privateKeyDrbg.detRngPtr) - XCTAssertEqual(privateKey.dataRepresentation, katTest.sk + katTest.pk) + let privateKey = try XWingMLKEM768X25519.PrivateKey.generateWithRng(rngState: privateKeyDrbg) XCTAssertEqual(privateKey.publicKey.rawRepresentation, katTest.pk) let encapDrbg = try SequenceDrbg(katTest.eseed) - let encapsulatedKey = try privateKey.publicKey.encapsulateWithRng(ccrngState: encapDrbg.detRngPtr) + let encapsulatedKey = try privateKey.publicKey.encapsulateWithRng(rngState: encapDrbg) XCTAssertEqual(encapsulatedKey.encapsulated, katTest.ct) XCTAssertEqual(encapsulatedKey.sharedSecret.dataRepresentation, katTest.ss) let retrievedSharedSecret = try privateKey.decapsulate(encapsulatedKey.encapsulated) @@ -70,25 +70,19 @@ final class XWingTests: XCTestCase { func testPrivateKeyRepresentations() throws { let privateKey = try XWingMLKEM768X25519.PrivateKey.generate() XCTAssertEqual(privateKey.seedRepresentation.count, 32) - #if false XCTAssertEqual(privateKey.integrityCheckedRepresentation.count, 64) XCTAssertEqual(privateKey.integrityCheckedRepresentation.dropLast(32), privateKey.seedRepresentation) - #endif let recoveredPrivateKey = try XWingMLKEM768X25519.PrivateKey(seedRepresentation: privateKey.seedRepresentation, publicKeyHash: nil) XCTAssertNotNil(recoveredPrivateKey) - #if false XCTAssertEqual(recoveredPrivateKey.integrityCheckedRepresentation, privateKey.integrityCheckedRepresentation) - #endif - #if false let otherKey = try XWingMLKEM768X25519.PrivateKey.generate() XCTAssertThrowsError(try XWingMLKEM768X25519.PrivateKey(seedRepresentation: privateKey.seedRepresentation, publicKeyHash: SHA3_256.hash(data: otherKey.publicKey.rawRepresentation)), error: KEM.Errors.publicKeyMismatchDuringInitialization) let exportedFormat = privateKey.integrityCheckedRepresentation let importedKey = try XWingMLKEM768X25519.PrivateKey.init(integrityCheckedRepresentation: exportedFormat) XCTAssertEqual(importedKey.seedRepresentation, privateKey.seedRepresentation) - #endif } } diff --git a/Tests/CryptoTests/Signatures/MLDSA/MLDSAKeyGenTests.swift b/Tests/CryptoTests/Signatures/MLDSA/MLDSAKeyGenTests.swift index 6ab3a8354..6d0add318 100644 --- a/Tests/CryptoTests/Signatures/MLDSA/MLDSAKeyGenTests.swift +++ b/Tests/CryptoTests/Signatures/MLDSA/MLDSAKeyGenTests.swift @@ -12,7 +12,6 @@ // //===----------------------------------------------------------------------===// import XCTest - #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API // Skip tests that require @testable imports of CryptoKit. #else @@ -40,28 +39,20 @@ final class MLDSAKeyGenTests: XCTestCase { let katTests = try processKeyGenKATFile(filename: "MLDSA65_KeyGen_KAT") for katTest in katTests { let publicKey = try MLDSA65.PublicKey(rawRepresentation: katTest.pk) - #if false let privateKey = try MLDSA65.PrivateKey(seedRepresentation: katTest.seed, publicKey: publicKey) let publicKeyHash = Data(SHA3_256.hash(data: privateKey.publicKey.rawRepresentation)) - #else - let privateKey = try MLDSA65.PrivateKey(seedRepresentation: katTest.seed, publicKey: nil) - #endif XCTAssert(privateKey.seedRepresentation == katTest.seed) - #if false XCTAssert(privateKey.integrityCheckedRepresentation == katTest.seed + publicKeyHash) - #endif XCTAssert(privateKey.publicKey.rawRepresentation == katTest.pk) // Try initializing keys with incorrect integrity checks let randomPrivateKey = try MLDSA65.PrivateKey() - #if false let randomPublicKeyHash = Data(SHA3_256.hash(data: randomPrivateKey.publicKey.rawRepresentation)) XCTAssertThrowsError(try MLDSA65.PrivateKey(seedRepresentation: privateKey.seedRepresentation, publicKey: randomPrivateKey.publicKey), error: CryptoKitError.unwrapFailure) XCTAssertThrowsError(try MLDSA65.PrivateKey(seedRepresentation: randomPrivateKey.seedRepresentation, publicKey: publicKey), error: CryptoKitError.unwrapFailure) XCTAssertThrowsError(try MLDSA65.PrivateKey(integrityCheckedRepresentation: privateKey.seedRepresentation + randomPublicKeyHash), error: CryptoKitError.unwrapFailure) XCTAssertThrowsError(try MLDSA65.PrivateKey(integrityCheckedRepresentation: randomPrivateKey.seedRepresentation + publicKeyHash), error: CryptoKitError.unwrapFailure) - #endif } } @@ -69,28 +60,20 @@ final class MLDSAKeyGenTests: XCTestCase { let katTests = try processKeyGenKATFile(filename: "MLDSA87_KeyGen_KAT") for katTest in katTests { let publicKey = try MLDSA87.PublicKey(rawRepresentation: katTest.pk) - #if false let privateKey = try MLDSA87.PrivateKey(seedRepresentation: katTest.seed, publicKey: publicKey) let publicKeyHash = Data(SHA3_256.hash(data: privateKey.publicKey.rawRepresentation)) - #else - let privateKey = try MLDSA87.PrivateKey(seedRepresentation: katTest.seed, publicKey: nil) - #endif XCTAssert(privateKey.seedRepresentation == katTest.seed) - #if false XCTAssert(privateKey.integrityCheckedRepresentation == katTest.seed + publicKeyHash) - #endif XCTAssert(privateKey.publicKey.rawRepresentation == katTest.pk) // Try initializing keys with incorrect integrity checks let randomPrivateKey = try MLDSA87.PrivateKey() - #if false let randomPublicKeyHash = Data(SHA3_256.hash(data: randomPrivateKey.publicKey.rawRepresentation)) XCTAssertThrowsError(try MLDSA87.PrivateKey(seedRepresentation: privateKey.seedRepresentation, publicKey: randomPrivateKey.publicKey), error: CryptoKitError.unwrapFailure) XCTAssertThrowsError(try MLDSA87.PrivateKey(seedRepresentation: randomPrivateKey.seedRepresentation, publicKey: publicKey), error: CryptoKitError.unwrapFailure) XCTAssertThrowsError(try MLDSA87.PrivateKey(integrityCheckedRepresentation: privateKey.seedRepresentation + randomPublicKeyHash), error: CryptoKitError.unwrapFailure) XCTAssertThrowsError(try MLDSA87.PrivateKey(integrityCheckedRepresentation: randomPrivateKey.seedRepresentation + publicKeyHash), error: CryptoKitError.unwrapFailure) - #endif } } } diff --git a/Tests/CryptoTests/Signatures/MLDSA/MLDSATests.swift b/Tests/CryptoTests/Signatures/MLDSA/MLDSATests.swift index f833e3355..443981da4 100644 --- a/Tests/CryptoTests/Signatures/MLDSA/MLDSATests.swift +++ b/Tests/CryptoTests/Signatures/MLDSA/MLDSATests.swift @@ -12,7 +12,6 @@ // //===----------------------------------------------------------------------===// import XCTest - #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API // Skip tests that require @testable imports of CryptoKit. #else @@ -31,27 +30,25 @@ final class MLDSATests: XCTestCase { try XCTAssert(publicKey.rawRepresentation == MLDSA65.PublicKey(rawRepresentation: publicKey.rawRepresentation).rawRepresentation) // Test Private Key serialization - #if false try XCTAssert(privateKey.seedRepresentation == MLDSA65.PrivateKey(seedRepresentation: privateKey.seedRepresentation, publicKey: publicKey).seedRepresentation) try XCTAssert(privateKey.integrityCheckedRepresentation == MLDSA65.PrivateKey(integrityCheckedRepresentation: privateKey.integrityCheckedRepresentation).integrityCheckedRepresentation) - #endif // Test signing without a context let message = Data("ML-DSA test message".utf8) let signature = try privateKey.signature(for: message) XCTAssertNotNil(signature) - let isValid = publicKey.isValidSignature(signature: signature, for: message) + let isValid = publicKey.isValidSignature(signature, for: message) XCTAssertTrue(isValid) // Test signing with a context let context = Data("ML-DSA test context".utf8) let signatureWithContext = try privateKey.signature(for: message, context: context) - let isValidWithContext = publicKey.isValidSignature(signature: signatureWithContext, for: message, context: context) + let isValidWithContext = publicKey.isValidSignature(signatureWithContext, for: message, context: context) XCTAssertTrue(isValidWithContext) // Check that invalid signatures (mismatching contexts) fail - XCTAssertFalse(publicKey.isValidSignature(signature: signature, for: message, context: context)) - XCTAssertFalse(publicKey.isValidSignature(signature: signatureWithContext, for: message)) + XCTAssertFalse(publicKey.isValidSignature(signature, for: message, context: context)) + XCTAssertFalse(publicKey.isValidSignature(signatureWithContext, for: message)) } func testMLDSA87() throws { @@ -62,27 +59,25 @@ final class MLDSATests: XCTestCase { try XCTAssert(publicKey.rawRepresentation == MLDSA87.PublicKey(rawRepresentation: publicKey.rawRepresentation).rawRepresentation) // Test Private Key serialization - #if false try XCTAssert(privateKey.seedRepresentation == MLDSA87.PrivateKey(seedRepresentation: privateKey.seedRepresentation, publicKey: publicKey).seedRepresentation) try XCTAssert(privateKey.integrityCheckedRepresentation == MLDSA87.PrivateKey(integrityCheckedRepresentation: privateKey.integrityCheckedRepresentation).integrityCheckedRepresentation) - #endif // Test signing without a context let message = Data("ML-DSA test message".utf8) let signature = try privateKey.signature(for: message) XCTAssertNotNil(signature) - let isValid = publicKey.isValidSignature(signature: signature, for: message) + let isValid = publicKey.isValidSignature(signature, for: message) XCTAssertTrue(isValid) // Test signing with a context let context = Data("ML-DSA test context".utf8) let signatureWithContext = try privateKey.signature(for: message, context: context) - let isValidWithContext = publicKey.isValidSignature(signature: signatureWithContext, for: message, context: context) + let isValidWithContext = publicKey.isValidSignature(signatureWithContext, for: message, context: context) XCTAssertTrue(isValidWithContext) // Check that invalid signatures (mismatching contexts) fail - XCTAssertFalse(publicKey.isValidSignature(signature: signature, for: message, context: context)) - XCTAssertFalse(publicKey.isValidSignature(signature: signatureWithContext, for: message)) + XCTAssertFalse(publicKey.isValidSignature(signature, for: message, context: context)) + XCTAssertFalse(publicKey.isValidSignature(signatureWithContext, for: message)) } } diff --git a/Tests/_CryptoExtrasTests/MLDSATests.swift b/Tests/_CryptoExtrasTests/MLDSATests.swift index 42edd033d..87e2b765d 100644 --- a/Tests/_CryptoExtrasTests/MLDSATests.swift +++ b/Tests/_CryptoExtrasTests/MLDSATests.swift @@ -33,7 +33,7 @@ final class MLDSATests: XCTestCase { let test = "Hello, world!".data(using: .utf8)! try XCTAssertTrue( key.publicKey.isValidSignature( - signature: key.signature(for: test), + key.signature(for: test), for: test ) ) @@ -41,7 +41,7 @@ final class MLDSATests: XCTestCase { let context = "ctx".data(using: .utf8)! try XCTAssertTrue( key.publicKey.isValidSignature( - signature: key.signature(for: test, context: context), + key.signature(for: test, context: context), for: test, context: context ) @@ -62,7 +62,7 @@ final class MLDSATests: XCTestCase { let test = "Hello, world!".data(using: .utf8)! try XCTAssertTrue( key.publicKey.isValidSignature( - signature: key.signature(for: test), + key.signature(for: test), for: test ) ) @@ -70,7 +70,7 @@ final class MLDSATests: XCTestCase { let context = "ctx".data(using: .utf8)! try XCTAssertTrue( key.publicKey.isValidSignature( - signature: key.signature(for: test, context: context), + key.signature(for: test, context: context), for: test, context: context ) @@ -115,8 +115,8 @@ final class MLDSATests: XCTestCase { XCTAssertNotEqual(signature1, signature2) // Even though the signatures are different, they both verify. - XCTAssertTrue(publicKey.isValidSignature(signature: signature1, for: message)) - XCTAssertTrue(publicKey.isValidSignature(signature: signature2, for: message)) + XCTAssertTrue(publicKey.isValidSignature(signature1, for: message)) + XCTAssertTrue(publicKey.isValidSignature(signature2, for: message)) } func testMLDSA87SignatureIsRandomized() throws { @@ -135,8 +135,8 @@ final class MLDSATests: XCTestCase { XCTAssertNotEqual(signature1, signature2) // Even though the signatures are different, they both verify. - XCTAssertTrue(publicKey.isValidSignature(signature: signature1, for: message)) - XCTAssertTrue(publicKey.isValidSignature(signature: signature2, for: message)) + XCTAssertTrue(publicKey.isValidSignature(signature1, for: message)) + XCTAssertTrue(publicKey.isValidSignature(signature2, for: message)) } func testInvalidMLDSA65PublicKeyEncodingLength() throws { @@ -264,15 +264,15 @@ final class MLDSATests: XCTestCase { switch test.result { case .valid: if let context { - XCTAssertTrue(publicKey.isValidSignature(signature: signature, for: message, context: context)) + XCTAssertTrue(publicKey.isValidSignature(signature, for: message, context: context)) } else { - XCTAssertTrue(publicKey.isValidSignature(signature: signature, for: message)) + XCTAssertTrue(publicKey.isValidSignature(signature, for: message)) } case .invalid: if let context { - XCTAssertFalse(publicKey.isValidSignature(signature: signature, for: message, context: context)) + XCTAssertFalse(publicKey.isValidSignature(signature, for: message, context: context)) } else { - XCTAssertFalse(publicKey.isValidSignature(signature: signature, for: message)) + XCTAssertFalse(publicKey.isValidSignature(signature, for: message)) } } } @@ -299,15 +299,15 @@ final class MLDSATests: XCTestCase { switch test.result { case .valid: if let context { - XCTAssertTrue(publicKey.isValidSignature(signature: signature, for: message, context: context)) + XCTAssertTrue(publicKey.isValidSignature(signature, for: message, context: context)) } else { - XCTAssertTrue(publicKey.isValidSignature(signature: signature, for: message)) + XCTAssertTrue(publicKey.isValidSignature(signature, for: message)) } case .invalid: if let context { - XCTAssertFalse(publicKey.isValidSignature(signature: signature, for: message, context: context)) + XCTAssertFalse(publicKey.isValidSignature(signature, for: message, context: context)) } else { - XCTAssertFalse(publicKey.isValidSignature(signature: signature, for: message)) + XCTAssertFalse(publicKey.isValidSignature(signature, for: message)) } } } From d9638b0bfa2fc48730c7374c248f4c19affd9c4c Mon Sep 17 00:00:00 2001 From: Francesco Paolo Severino Date: Wed, 10 Sep 2025 12:01:21 +0200 Subject: [PATCH 26/47] Fix conflicts --- Sources/Crypto/Signatures/MLDSA.swift | 106 ++++++++++++++++++---- Sources/Crypto/Signatures/MLDSA.swift.gyb | 12 ++- 2 files changed, 100 insertions(+), 18 deletions(-) diff --git a/Sources/Crypto/Signatures/MLDSA.swift b/Sources/Crypto/Signatures/MLDSA.swift index f83eeda14..031759fea 100644 --- a/Sources/Crypto/Signatures/MLDSA.swift +++ b/Sources/Crypto/Signatures/MLDSA.swift @@ -46,7 +46,7 @@ extension MLDSA65 { internal init(_ impl: MLDSAPublicKeyImpl) { self.impl = impl } - + /// Parses a public key from a serialized representation. /// /// - Parameter rawRepresentation: The public key, in the FIPS 204 standard serialization format. @@ -64,6 +64,36 @@ extension MLDSA65 { } } + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameter data: The message to prehash. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + package func prehash_boring(for data: D) throws -> Data { + try self.boringSSLKey.prehash_boring(for: data) + } + + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameters: + /// - data: The message to prehash. + /// - context: The context of the message. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + package func prehash_boring(for data: D, context: C) throws -> Data { + try self.boringSSLKey.prehash_boring(for: data, context: context) + } + + private var boringSSLKey: OpenSSLMLDSAPublicKeyImpl { + get throws { + #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION + try OpenSSLMLDSAPublicKeyImpl(rawRepresentation: self.rawRepresentation) + #else + self.impl + #endif + } + } + /// Verifies a MLDSA65 signature. /// - Parameters: /// - signature: The MLDSA65 signature to verify. @@ -121,7 +151,7 @@ extension MLDSA65 { /// for the `ML-DSA.KeyGen_internal` algorithm (Algorithm 16) of FIPS 204. public var seedRepresentation: Data { get { - self.impl.seedRepresentation + return self.impl.seedRepresentation } } @@ -143,7 +173,18 @@ extension MLDSA65 { public func signature(for data: D, context: C) throws -> Data { return try impl.signature(for: data, context: context) } - + + /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). + /// + /// > Note: The message representative should be obtained via calls to ``MLDSA87/PublicKey/prehash(for:context:)``. + /// + /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). + /// + /// - Returns: The signature of the prehashed message representative. + package func signature_boring(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { + try self.boringSSLKey.signature_boring(forPrehashedMessageRepresentative: mu) + } + /// The associated public key. public var publicKey: PublicKey { get { @@ -173,14 +214,10 @@ extension MLDSA65 { /// This representation is 64 bytes long, and contains the seed and a hash of the public key. public var integrityCheckedRepresentation: Data { get { - self.impl.integrityCheckedRepresentation + return self.impl.integrityCheckedRepresentation } } - private init(impl: MLDSAPrivateKeyImpl) { - self.impl = impl - } - private var boringSSLKey: OpenSSLMLDSAPrivateKeyImpl { get throws { #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION @@ -210,7 +247,7 @@ extension MLDSA87 { internal init(_ impl: MLDSAPublicKeyImpl) { self.impl = impl } - + /// Parses a public key from a serialized representation. /// /// - Parameter rawRepresentation: The public key, in the FIPS 204 standard serialization format. @@ -228,6 +265,36 @@ extension MLDSA87 { } } + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameter data: The message to prehash. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + package func prehash_boring(for data: D) throws -> Data { + try self.boringSSLKey.prehash_boring(for: data) + } + + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameters: + /// - data: The message to prehash. + /// - context: The context of the message. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + package func prehash_boring(for data: D, context: C) throws -> Data { + try self.boringSSLKey.prehash_boring(for: data, context: context) + } + + private var boringSSLKey: OpenSSLMLDSAPublicKeyImpl { + get throws { + #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION + try OpenSSLMLDSAPublicKeyImpl(rawRepresentation: self.rawRepresentation) + #else + self.impl + #endif + } + } + /// Verifies a MLDSA87 signature. /// - Parameters: /// - signature: The MLDSA87 signature to verify. @@ -285,7 +352,7 @@ extension MLDSA87 { /// for the `ML-DSA.KeyGen_internal` algorithm (Algorithm 16) of FIPS 204. public var seedRepresentation: Data { get { - self.impl.seedRepresentation + return self.impl.seedRepresentation } } @@ -307,7 +374,18 @@ extension MLDSA87 { public func signature(for data: D, context: C) throws -> Data { return try impl.signature(for: data, context: context) } - + + /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). + /// + /// > Note: The message representative should be obtained via calls to ``MLDSA87/PublicKey/prehash(for:context:)``. + /// + /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). + /// + /// - Returns: The signature of the prehashed message representative. + package func signature_boring(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { + try self.boringSSLKey.signature_boring(forPrehashedMessageRepresentative: mu) + } + /// The associated public key. public var publicKey: PublicKey { get { @@ -337,14 +415,10 @@ extension MLDSA87 { /// This representation is 64 bytes long, and contains the seed and a hash of the public key. public var integrityCheckedRepresentation: Data { get { - self.impl.integrityCheckedRepresentation + return self.impl.integrityCheckedRepresentation } } - private init(impl: MLDSAPrivateKeyImpl) { - self.impl = impl - } - private var boringSSLKey: OpenSSLMLDSAPrivateKeyImpl { get throws { #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION diff --git a/Sources/Crypto/Signatures/MLDSA.swift.gyb b/Sources/Crypto/Signatures/MLDSA.swift.gyb index 00fbf7896..b4b49fbd5 100644 --- a/Sources/Crypto/Signatures/MLDSA.swift.gyb +++ b/Sources/Crypto/Signatures/MLDSA.swift.gyb @@ -24,7 +24,9 @@ public import Foundation }% #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) typealias MLDSAPublicKeyImpl = CorecryptoMLDSAPublicKeyImpl +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) typealias MLDSAPrivateKeyImpl = CorecryptoMLDSAPrivateKeyImpl #else @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) @@ -44,9 +46,14 @@ public enum ${NAME}: Sendable {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ${NAME} { /// The public key for ${NAME}. + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) public struct PublicKey: Sendable { var impl: MLDSAPublicKeyImpl<${NAME}> + internal init(_ impl: MLDSAPublicKeyImpl<${NAME}>) { + self.impl = impl + } + /// Parses a public key from a serialized representation. /// /// - Parameter rawRepresentation: The public key, in the FIPS 204 standard serialization format. @@ -115,6 +122,7 @@ extension ${NAME} { } /// The private key for ${NAME}. + @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) public struct PrivateKey: Signer, Sendable { internal let impl: MLDSAPrivateKeyImpl<${NAME}> @@ -150,7 +158,7 @@ extension ${NAME} { /// for the `ML-DSA.KeyGen_internal` algorithm (Algorithm 16) of FIPS 204. public var seedRepresentation: Data { get { - self.impl.seedRepresentation + return self.impl.seedRepresentation } } @@ -213,7 +221,7 @@ extension ${NAME} { /// This representation is 64 bytes long, and contains the seed and a hash of the public key. public var integrityCheckedRepresentation: Data { get { - self.impl.integrityCheckedRepresentation + return self.impl.integrityCheckedRepresentation } } From 4a6a2549a1972b402bef1b59f693454cae3425dc Mon Sep 17 00:00:00 2001 From: Francesco Paolo Severino Date: Wed, 10 Sep 2025 12:04:32 +0200 Subject: [PATCH 27/47] Remove unreleated stuff --- Sources/Crypto/KEM/MLKEM.swift | 49 ++++++++++++++---------------- Sources/Crypto/KEM/MLKEM.swift.gyb | 34 ++++++++------------- 2 files changed, 34 insertions(+), 49 deletions(-) diff --git a/Sources/Crypto/KEM/MLKEM.swift b/Sources/Crypto/KEM/MLKEM.swift index 248439f88..e845dd7b0 100644 --- a/Sources/Crypto/KEM/MLKEM.swift +++ b/Sources/Crypto/KEM/MLKEM.swift @@ -32,6 +32,7 @@ typealias MLKEMPublicKeyImpl = OpenSSLMLKEMPublicKeyImpl typealias MLKEMPrivateKeyImpl = OpenSSLMLKEMPrivateKeyImpl #endif + /// The Module-Lattice key encapsulation mechanism (KEM). @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) public enum MLKEM768: Sendable {} @@ -52,7 +53,7 @@ extension MLKEM768 { /// A serialized representation of the public key. public var rawRepresentation: Data { get { - self.impl.rawRepresentation + return self.impl.rawRepresentation } } @@ -60,11 +61,11 @@ extension MLKEM768 { /// /// - Returns: an encapsulated shared secret, that you decapsulate by calling ``MLKEM768/PrivateKey/decapsulate(_:)`` on the corresponding private key. public func encapsulate() throws -> KEM.EncapsulationResult { - try self.impl.encapsulate() + return try self.impl.encapsulate() } func encapsulateWithSeed(encapSeed: Data) throws -> KEM.EncapsulationResult { - try self.impl.encapsulateWithSeed(encapSeed) + return try self.impl.encapsulateWithSeed(encapSeed) } } @@ -103,10 +104,7 @@ extension MLKEM768 { if publicKey != nil { publicKeyRawRepresentation = publicKey!.rawRepresentation } - self.impl = try MLKEMPrivateKeyImpl( - seedRepresentation: seedRepresentation, - publicKeyRawRepresentation: publicKeyRawRepresentation - ) + self.impl = try MLKEMPrivateKeyImpl(seedRepresentation: seedRepresentation, publicKeyRawRepresentation: publicKeyRawRepresentation) } /// The private key's seed representation. @@ -114,7 +112,7 @@ extension MLKEM768 { /// The seed is `d||z`, as specified in the algorithm `ML-KEM.KeyGen_internal(d,z)` (Algorithm 16) of FIPS 203. public var seedRepresentation: Data { get { - self.impl.seedRepresentation + return self.impl.seedRepresentation } } @@ -124,13 +122,13 @@ extension MLKEM768 { /// - encapsulated: An encapsulated shared secret, that you get by calling ``MLKEM768/PublicKey/encapsulate()`` on the corresponding public key. /// - Returns: The shared secret. public func decapsulate(_ encapsulated: D) throws -> SymmetricKey { - try impl.decapsulate(encapsulated: encapsulated) + return try impl.decapsulate(encapsulated: encapsulated) } /// The corresponding public key. public var publicKey: MLKEM768.PublicKey { get { - self.impl.publicKey + try self.impl.publicKey } } @@ -142,8 +140,7 @@ extension MLKEM768 { throw KEM.Errors.invalidSeed } let seed = Data(integrityCheckedRepresentation).subdata(in: 0...seedSize) - let publicKeyHashData = Data(integrityCheckedRepresentation) - .subdata(in: MLKEMPrivateKeyImpl.seedSize...seedSize..(seedRepresentation: seed, publicKeyHash: publicKeyHash) @@ -154,12 +151,13 @@ extension MLKEM768 { /// This representation includes the seed value, and a hash of the corresponding public key. public var integrityCheckedRepresentation: Data { get { - self.impl.integrityCheckedRepresentation + return self.impl.integrityCheckedRepresentation } } } } + /// The Module-Lattice key encapsulation mechanism (KEM). @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) public enum MLKEM1024: Sendable {} @@ -180,7 +178,7 @@ extension MLKEM1024 { /// A serialized representation of the public key. public var rawRepresentation: Data { get { - self.impl.rawRepresentation + return self.impl.rawRepresentation } } @@ -188,11 +186,11 @@ extension MLKEM1024 { /// /// - Returns: an encapsulated shared secret, that you decapsulate by calling ``MLKEM1024/PrivateKey/decapsulate(_:)`` on the corresponding private key. public func encapsulate() throws -> KEM.EncapsulationResult { - try self.impl.encapsulate() + return try self.impl.encapsulate() } func encapsulateWithSeed(encapSeed: Data) throws -> KEM.EncapsulationResult { - try self.impl.encapsulateWithSeed(encapSeed) + return try self.impl.encapsulateWithSeed(encapSeed) } } @@ -231,10 +229,7 @@ extension MLKEM1024 { if publicKey != nil { publicKeyRawRepresentation = publicKey!.rawRepresentation } - self.impl = try MLKEMPrivateKeyImpl( - seedRepresentation: seedRepresentation, - publicKeyRawRepresentation: publicKeyRawRepresentation - ) + self.impl = try MLKEMPrivateKeyImpl(seedRepresentation: seedRepresentation, publicKeyRawRepresentation: publicKeyRawRepresentation) } /// The private key's seed representation. @@ -242,7 +237,7 @@ extension MLKEM1024 { /// The seed is `d||z`, as specified in the algorithm `ML-KEM.KeyGen_internal(d,z)` (Algorithm 16) of FIPS 203. public var seedRepresentation: Data { get { - self.impl.seedRepresentation + return self.impl.seedRepresentation } } @@ -252,13 +247,13 @@ extension MLKEM1024 { /// - encapsulated: An encapsulated shared secret, that you get by calling ``MLKEM1024/PublicKey/encapsulate()`` on the corresponding public key. /// - Returns: The shared secret. public func decapsulate(_ encapsulated: D) throws -> SymmetricKey { - try impl.decapsulate(encapsulated: encapsulated) + return try impl.decapsulate(encapsulated: encapsulated) } /// The corresponding public key. public var publicKey: MLKEM1024.PublicKey { get { - self.impl.publicKey + try self.impl.publicKey } } @@ -270,8 +265,7 @@ extension MLKEM1024 { throw KEM.Errors.invalidSeed } let seed = Data(integrityCheckedRepresentation).subdata(in: 0...seedSize) - let publicKeyHashData = Data(integrityCheckedRepresentation) - .subdata(in: MLKEMPrivateKeyImpl.seedSize...seedSize..(seedRepresentation: seed, publicKeyHash: publicKeyHash) @@ -282,10 +276,11 @@ extension MLKEM1024 { /// This representation includes the seed value, and a hash of the corresponding public key. public var integrityCheckedRepresentation: Data { get { - self.impl.integrityCheckedRepresentation + return self.impl.integrityCheckedRepresentation } } } } -#endif // Linux or !SwiftPM + +#endif // Linux or !SwiftPM \ No newline at end of file diff --git a/Sources/Crypto/KEM/MLKEM.swift.gyb b/Sources/Crypto/KEM/MLKEM.swift.gyb index a5d5417f0..3a1719437 100644 --- a/Sources/Crypto/KEM/MLKEM.swift.gyb +++ b/Sources/Crypto/KEM/MLKEM.swift.gyb @@ -24,14 +24,10 @@ public import Foundation }% #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) typealias MLKEMPublicKeyImpl = CoreCryptoMLKEMPublicKeyImpl -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) typealias MLKEMPrivateKeyImpl = CoreCryptoMLKEMPrivateKeyImpl #else -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) typealias MLKEMPublicKeyImpl = OpenSSLMLKEMPublicKeyImpl -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) typealias MLKEMPrivateKeyImpl = OpenSSLMLKEMPrivateKeyImpl #endif @@ -40,14 +36,12 @@ typealias MLKEMPrivateKeyImpl = OpenSSLMLKEMPrivateKeyImpl NAME = MLKEM_VARIANT["name"] INFO = MLKEM_VARIANT["ccinfo"] }% + /// The Module-Lattice key encapsulation mechanism (KEM). -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) public enum ${NAME}: Sendable {} -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension ${NAME} { /// A public key you use to encapsulate shared secrets with the Module-Lattice key encapsulation mechanism. - @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) public struct PublicKey: KEMPublicKey, Sendable { var impl: MLKEMPublicKeyImpl<${NAME}> @@ -60,7 +54,7 @@ extension ${NAME} { /// A serialized representation of the public key. public var rawRepresentation: Data { get { - self.impl.rawRepresentation + return self.impl.rawRepresentation } } @@ -68,16 +62,15 @@ extension ${NAME} { /// /// - Returns: an encapsulated shared secret, that you decapsulate by calling ``${NAME}/PrivateKey/decapsulate(_:)`` on the corresponding private key. public func encapsulate() throws -> KEM.EncapsulationResult { - try self.impl.encapsulate() + return try self.impl.encapsulate() } func encapsulateWithSeed(encapSeed: Data) throws -> KEM.EncapsulationResult { - try self.impl.encapsulateWithSeed(encapSeed) + return try self.impl.encapsulateWithSeed(encapSeed) } } /// A private key you use to decapsulate shared secrets with the Module-Lattice key encapsulation mechanism. - @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) public struct PrivateKey: KEMPrivateKey { internal let impl: MLKEMPrivateKeyImpl<${NAME}> @@ -111,10 +104,7 @@ extension ${NAME} { if publicKey != nil { publicKeyRawRepresentation = publicKey!.rawRepresentation } - self.impl = try MLKEMPrivateKeyImpl<${NAME}>( - seedRepresentation: seedRepresentation, - publicKeyRawRepresentation: publicKeyRawRepresentation - ) + self.impl = try MLKEMPrivateKeyImpl<${NAME}>(seedRepresentation: seedRepresentation, publicKeyRawRepresentation: publicKeyRawRepresentation) } /// The private key's seed representation. @@ -122,7 +112,7 @@ extension ${NAME} { /// The seed is `d||z`, as specified in the algorithm `ML-KEM.KeyGen_internal(d,z)` (Algorithm 16) of FIPS 203. public var seedRepresentation: Data { get { - self.impl.seedRepresentation + return self.impl.seedRepresentation } } @@ -132,13 +122,13 @@ extension ${NAME} { /// - encapsulated: An encapsulated shared secret, that you get by calling ``${NAME}/PublicKey/encapsulate()`` on the corresponding public key. /// - Returns: The shared secret. public func decapsulate(_ encapsulated: D) throws -> SymmetricKey { - try impl.decapsulate(encapsulated: encapsulated) + return try impl.decapsulate(encapsulated: encapsulated) } /// The corresponding public key. public var publicKey: ${NAME}.PublicKey { get { - self.impl.publicKey + try self.impl.publicKey } } @@ -150,8 +140,7 @@ extension ${NAME} { throw KEM.Errors.invalidSeed } let seed = Data(integrityCheckedRepresentation).subdata(in: 0...seedSize) - let publicKeyHashData = Data(integrityCheckedRepresentation) - .subdata(in: MLKEMPrivateKeyImpl<${NAME}>.seedSize...seedSize..(seedRepresentation: seed, publicKeyHash: publicKeyHash) @@ -162,11 +151,12 @@ extension ${NAME} { /// This representation includes the seed value, and a hash of the corresponding public key. public var integrityCheckedRepresentation: Data { get { - self.impl.integrityCheckedRepresentation + return self.impl.integrityCheckedRepresentation } } } } % end -#endif // Linux or !SwiftPM + +#endif // Linux or !SwiftPM From f9fa5630d6784670a5d825e195db29ff0d9a6e9c Mon Sep 17 00:00:00 2001 From: Francesco Paolo Severino Date: Wed, 10 Sep 2025 12:07:23 +0200 Subject: [PATCH 28/47] Fix conflicts --- Sources/Crypto/KEM/MLKEM.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Crypto/KEM/MLKEM.swift b/Sources/Crypto/KEM/MLKEM.swift index e845dd7b0..3883fbd40 100644 --- a/Sources/Crypto/KEM/MLKEM.swift +++ b/Sources/Crypto/KEM/MLKEM.swift @@ -283,4 +283,4 @@ extension MLKEM1024 { } -#endif // Linux or !SwiftPM \ No newline at end of file +#endif // Linux or !SwiftPM From 1d62dfaf2c82f1405de80fd01e75dd725e705fbf Mon Sep 17 00:00:00 2001 From: Francesco Paolo Severino Date: Fri, 12 Sep 2025 16:33:04 +0200 Subject: [PATCH 29/47] Move external mu methods to separate file --- Package.swift | 1 + .../BoringSSL/MLDSA+externalMu_boring.swift | 145 ++++++++++++++++++ .../MLDSA+externalMu_boring.swift.gyb | 90 +++++++++++ Sources/Crypto/Signatures/MLDSA.swift | 113 +------------- Sources/Crypto/Signatures/MLDSA.swift.gyb | 59 +------ .../MLDSA/MLDSA+externalMu.swift | 8 +- .../MLDSA/MLDSA+externalMu.swift.gyb | 6 +- Tests/_CryptoExtrasTests/MLDSATests.swift | 2 +- 8 files changed, 254 insertions(+), 170 deletions(-) create mode 100644 Sources/Crypto/Signatures/BoringSSL/MLDSA+externalMu_boring.swift create mode 100644 Sources/Crypto/Signatures/BoringSSL/MLDSA+externalMu_boring.swift.gyb diff --git a/Package.swift b/Package.swift index 6a9f4788f..e9b43c67b 100644 --- a/Package.swift +++ b/Package.swift @@ -170,6 +170,7 @@ let package = Package( "Signatures/ECDSA.swift.gyb", "Signatures/MLDSA.swift.gyb", "Signatures/BoringSSL/MLDSA_boring.swift.gyb", + "Signatures/BoringSSL/MLDSA+externalMu_boring.swift.gyb", "KEM/MLKEM.swift.gyb", "KEM/BoringSSL/MLKEM_boring.swift.gyb", ], diff --git a/Sources/Crypto/Signatures/BoringSSL/MLDSA+externalMu_boring.swift b/Sources/Crypto/Signatures/BoringSSL/MLDSA+externalMu_boring.swift new file mode 100644 index 000000000..73060c04d --- /dev/null +++ b/Sources/Crypto/Signatures/BoringSSL/MLDSA+externalMu_boring.swift @@ -0,0 +1,145 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2025 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +// MARK: - Generated file, do NOT edit +// any edits of this file WILL be overwritten and thus discarded +// see section `gyb` in `README` for details. + +#if (!CRYPTO_IN_SWIFTPM) || CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +#if canImport(FoundationEssentials) +import FoundationEssentials +#else +import Foundation +#endif + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension MLDSA65.PublicKey { + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameter data: The message to prehash. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + package func prehash_boring(for data: D) throws -> Data { + try self.boringSSLKey.prehash_boring(for: data) + } + + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameters: + /// - data: The message to prehash. + /// - context: The context of the message. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + package func prehash_boring(for data: D, context: C) throws -> Data { + try self.boringSSLKey.prehash_boring(for: data, context: context) + } + + private var boringSSLKey: OpenSSLMLDSAPublicKeyImpl { + get throws { + #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION + try OpenSSLMLDSAPublicKeyImpl(rawRepresentation: self.rawRepresentation) + #else + self.impl + #endif + } + } +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension MLDSA65.PrivateKey { + /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). + /// + /// > Note: The message representative should be obtained via calls to ``MLDSA87/PublicKey/prehash(for:context:)``. + /// + /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). + /// + /// - Returns: The signature of the prehashed message representative. + package func signature_boring(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { + try self.boringSSLKey.signature_boring(forPrehashedMessageRepresentative: mu) + } + + private var boringSSLKey: OpenSSLMLDSAPrivateKeyImpl { + get throws { + #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION + try OpenSSLMLDSAPrivateKeyImpl( + seedRepresentation: self.seedRepresentation, + publicKey: nil + ) + #else + self.impl + #endif + } + } +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension MLDSA87.PublicKey { + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameter data: The message to prehash. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + package func prehash_boring(for data: D) throws -> Data { + try self.boringSSLKey.prehash_boring(for: data) + } + + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameters: + /// - data: The message to prehash. + /// - context: The context of the message. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + package func prehash_boring(for data: D, context: C) throws -> Data { + try self.boringSSLKey.prehash_boring(for: data, context: context) + } + + private var boringSSLKey: OpenSSLMLDSAPublicKeyImpl { + get throws { + #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION + try OpenSSLMLDSAPublicKeyImpl(rawRepresentation: self.rawRepresentation) + #else + self.impl + #endif + } + } +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension MLDSA87.PrivateKey { + /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). + /// + /// > Note: The message representative should be obtained via calls to ``MLDSA87/PublicKey/prehash(for:context:)``. + /// + /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). + /// + /// - Returns: The signature of the prehashed message representative. + package func signature_boring(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { + try self.boringSSLKey.signature_boring(forPrehashedMessageRepresentative: mu) + } + + private var boringSSLKey: OpenSSLMLDSAPrivateKeyImpl { + get throws { + #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION + try OpenSSLMLDSAPrivateKeyImpl( + seedRepresentation: self.seedRepresentation, + publicKey: nil + ) + #else + self.impl + #endif + } + } +} +#endif // Linux or !SwiftPM diff --git a/Sources/Crypto/Signatures/BoringSSL/MLDSA+externalMu_boring.swift.gyb b/Sources/Crypto/Signatures/BoringSSL/MLDSA+externalMu_boring.swift.gyb new file mode 100644 index 000000000..1752561f6 --- /dev/null +++ b/Sources/Crypto/Signatures/BoringSSL/MLDSA+externalMu_boring.swift.gyb @@ -0,0 +1,90 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2025 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +// MARK: - Generated file, do NOT edit +// any edits of this file WILL be overwritten and thus discarded +// see section `gyb` in `README` for details. + +#if (!CRYPTO_IN_SWIFTPM) || CRYPTO_IN_SWIFTPM_FORCE_BUILD_API +#if canImport(FoundationEssentials) +import FoundationEssentials +#else +import Foundation +#endif +%{ + parameter_sets = ["65", "87"] +}% +% for parameter_set in parameter_sets: + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension MLDSA${parameter_set}.PublicKey { + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameter data: The message to prehash. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + package func prehash_boring(for data: D) throws -> Data { + try self.boringSSLKey.prehash_boring(for: data) + } + + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameters: + /// - data: The message to prehash. + /// - context: The context of the message. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + package func prehash_boring(for data: D, context: C) throws -> Data { + try self.boringSSLKey.prehash_boring(for: data, context: context) + } + + private var boringSSLKey: OpenSSLMLDSAPublicKeyImpl { + get throws { + #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION + try OpenSSLMLDSAPublicKeyImpl(rawRepresentation: self.rawRepresentation) + #else + self.impl + #endif + } + } +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension MLDSA${parameter_set}.PrivateKey { + /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). + /// + /// > Note: The message representative should be obtained via calls to ``MLDSA87/PublicKey/prehash(for:context:)``. + /// + /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). + /// + /// - Returns: The signature of the prehashed message representative. + package func signature_boring(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { + try self.boringSSLKey.signature_boring(forPrehashedMessageRepresentative: mu) + } + + private var boringSSLKey: OpenSSLMLDSAPrivateKeyImpl { + get throws { + #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION + try OpenSSLMLDSAPrivateKeyImpl( + seedRepresentation: self.seedRepresentation, + publicKey: nil + ) + #else + self.impl + #endif + } + } +} +% end +#endif // Linux or !SwiftPM diff --git a/Sources/Crypto/Signatures/MLDSA.swift b/Sources/Crypto/Signatures/MLDSA.swift index 031759fea..17c7a78dd 100644 --- a/Sources/Crypto/Signatures/MLDSA.swift +++ b/Sources/Crypto/Signatures/MLDSA.swift @@ -11,6 +11,11 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// + +// MARK: - Generated file, do NOT edit +// any edits of this file WILL be overwritten and thus discarded +// see section `gyb` in `README` for details. + #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else @@ -64,36 +69,6 @@ extension MLDSA65 { } } - /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. - /// - /// - Parameter data: The message to prehash. - /// - /// - Returns: The prehashed message representative (a.k.a. "external mu"). - package func prehash_boring(for data: D) throws -> Data { - try self.boringSSLKey.prehash_boring(for: data) - } - - /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. - /// - /// - Parameters: - /// - data: The message to prehash. - /// - context: The context of the message. - /// - /// - Returns: The prehashed message representative (a.k.a. "external mu"). - package func prehash_boring(for data: D, context: C) throws -> Data { - try self.boringSSLKey.prehash_boring(for: data, context: context) - } - - private var boringSSLKey: OpenSSLMLDSAPublicKeyImpl { - get throws { - #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION - try OpenSSLMLDSAPublicKeyImpl(rawRepresentation: self.rawRepresentation) - #else - self.impl - #endif - } - } - /// Verifies a MLDSA65 signature. /// - Parameters: /// - signature: The MLDSA65 signature to verify. @@ -174,17 +149,6 @@ extension MLDSA65 { return try impl.signature(for: data, context: context) } - /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). - /// - /// > Note: The message representative should be obtained via calls to ``MLDSA87/PublicKey/prehash(for:context:)``. - /// - /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). - /// - /// - Returns: The signature of the prehashed message representative. - package func signature_boring(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { - try self.boringSSLKey.signature_boring(forPrehashedMessageRepresentative: mu) - } - /// The associated public key. public var publicKey: PublicKey { get { @@ -217,19 +181,6 @@ extension MLDSA65 { return self.impl.integrityCheckedRepresentation } } - - private var boringSSLKey: OpenSSLMLDSAPrivateKeyImpl { - get throws { - #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION - try OpenSSLMLDSAPrivateKeyImpl( - seedRepresentation: self.seedRepresentation, - publicKey: nil - ) - #else - self.impl - #endif - } - } } } @@ -265,36 +216,6 @@ extension MLDSA87 { } } - /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. - /// - /// - Parameter data: The message to prehash. - /// - /// - Returns: The prehashed message representative (a.k.a. "external mu"). - package func prehash_boring(for data: D) throws -> Data { - try self.boringSSLKey.prehash_boring(for: data) - } - - /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. - /// - /// - Parameters: - /// - data: The message to prehash. - /// - context: The context of the message. - /// - /// - Returns: The prehashed message representative (a.k.a. "external mu"). - package func prehash_boring(for data: D, context: C) throws -> Data { - try self.boringSSLKey.prehash_boring(for: data, context: context) - } - - private var boringSSLKey: OpenSSLMLDSAPublicKeyImpl { - get throws { - #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION - try OpenSSLMLDSAPublicKeyImpl(rawRepresentation: self.rawRepresentation) - #else - self.impl - #endif - } - } - /// Verifies a MLDSA87 signature. /// - Parameters: /// - signature: The MLDSA87 signature to verify. @@ -375,17 +296,6 @@ extension MLDSA87 { return try impl.signature(for: data, context: context) } - /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). - /// - /// > Note: The message representative should be obtained via calls to ``MLDSA87/PublicKey/prehash(for:context:)``. - /// - /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). - /// - /// - Returns: The signature of the prehashed message representative. - package func signature_boring(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { - try self.boringSSLKey.signature_boring(forPrehashedMessageRepresentative: mu) - } - /// The associated public key. public var publicKey: PublicKey { get { @@ -418,19 +328,6 @@ extension MLDSA87 { return self.impl.integrityCheckedRepresentation } } - - private var boringSSLKey: OpenSSLMLDSAPrivateKeyImpl { - get throws { - #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION - try OpenSSLMLDSAPrivateKeyImpl( - seedRepresentation: self.seedRepresentation, - publicKey: nil - ) - #else - self.impl - #endif - } - } } } diff --git a/Sources/Crypto/Signatures/MLDSA.swift.gyb b/Sources/Crypto/Signatures/MLDSA.swift.gyb index b4b49fbd5..368850957 100644 --- a/Sources/Crypto/Signatures/MLDSA.swift.gyb +++ b/Sources/Crypto/Signatures/MLDSA.swift.gyb @@ -11,6 +11,11 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// + +// MARK: - Generated file, do NOT edit +// any edits of this file WILL be overwritten and thus discarded +// see section `gyb` in `README` for details. + #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API @_exported import CryptoKit #else @@ -71,36 +76,6 @@ extension ${NAME} { } } - /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. - /// - /// - Parameter data: The message to prehash. - /// - /// - Returns: The prehashed message representative (a.k.a. "external mu"). - package func prehash_boring(for data: D) throws -> Data { - try self.boringSSLKey.prehash_boring(for: data) - } - - /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. - /// - /// - Parameters: - /// - data: The message to prehash. - /// - context: The context of the message. - /// - /// - Returns: The prehashed message representative (a.k.a. "external mu"). - package func prehash_boring(for data: D, context: C) throws -> Data { - try self.boringSSLKey.prehash_boring(for: data, context: context) - } - - private var boringSSLKey: OpenSSLMLDSAPublicKeyImpl<${NAME}> { - get throws { - #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION - try OpenSSLMLDSAPublicKeyImpl<${NAME}>(rawRepresentation: self.rawRepresentation) - #else - self.impl - #endif - } - } - /// Verifies a ${NAME} signature. /// - Parameters: /// - signature: The ${NAME} signature to verify. @@ -181,17 +156,6 @@ extension ${NAME} { return try impl.signature(for: data, context: context) } - /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). - /// - /// > Note: The message representative should be obtained via calls to ``MLDSA87/PublicKey/prehash(for:context:)``. - /// - /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). - /// - /// - Returns: The signature of the prehashed message representative. - package func signature_boring(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { - try self.boringSSLKey.signature_boring(forPrehashedMessageRepresentative: mu) - } - /// The associated public key. public var publicKey: PublicKey { get { @@ -224,19 +188,6 @@ extension ${NAME} { return self.impl.integrityCheckedRepresentation } } - - private var boringSSLKey: OpenSSLMLDSAPrivateKeyImpl<${NAME}> { - get throws { - #if (!CRYPTO_IN_SWIFTPM_FORCE_BUILD_API) || CRYPTOKIT_NO_ACCESS_TO_FOUNDATION - try OpenSSLMLDSAPrivateKeyImpl<${NAME}>( - seedRepresentation: self.seedRepresentation, - publicKey: nil - ) - #else - self.impl - #endif - } - } } } diff --git a/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift b/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift index 76ef02ee7..328081068 100644 --- a/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift +++ b/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift @@ -23,7 +23,7 @@ import FoundationEssentials import Foundation #endif -@available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLDSA65.PrivateKey { /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). /// @@ -37,7 +37,7 @@ extension MLDSA65.PrivateKey { } } -@available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLDSA65.PublicKey { /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. /// @@ -60,7 +60,7 @@ extension MLDSA65.PublicKey { } } -@available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLDSA87.PrivateKey { /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). /// @@ -74,7 +74,7 @@ extension MLDSA87.PrivateKey { } } -@available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLDSA87.PublicKey { /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. /// diff --git a/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb b/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb index 899df5063..13f9c3028 100644 --- a/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb +++ b/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb @@ -27,7 +27,7 @@ import Foundation }% % for parameter_set in parameter_sets: -@available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLDSA${parameter_set}.PrivateKey { /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). /// @@ -41,7 +41,7 @@ extension MLDSA${parameter_set}.PrivateKey { } } -@available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLDSA${parameter_set}.PublicKey { /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. /// @@ -63,4 +63,4 @@ extension MLDSA${parameter_set}.PublicKey { try self.prehash_boring(for: data, context: context) } } -%end +% end diff --git a/Tests/_CryptoExtrasTests/MLDSATests.swift b/Tests/_CryptoExtrasTests/MLDSATests.swift index 034e6be00..f35708d3f 100644 --- a/Tests/_CryptoExtrasTests/MLDSATests.swift +++ b/Tests/_CryptoExtrasTests/MLDSATests.swift @@ -356,7 +356,7 @@ extension MLDSA87.PublicKey { #endif // SDK has MLDSA -@available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) final class MLDSAExternalMuTests: XCTestCase { func testMLDSA65PrehashedSigning() throws { let message = "Hello, world!".data(using: .utf8)! From 47da0e2e885d628f48acefc03540f3cd22caee3f Mon Sep 17 00:00:00 2001 From: Francesco Paolo Severino Date: Fri, 12 Sep 2025 16:37:07 +0200 Subject: [PATCH 30/47] Formatting --- Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift | 1 + Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb | 1 + 2 files changed, 2 insertions(+) diff --git a/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift b/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift index 328081068..7590c27ad 100644 --- a/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift +++ b/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift @@ -17,6 +17,7 @@ // see section `gyb` in `README` for details. import Crypto + #if canImport(FoundationEssentials) import FoundationEssentials #else diff --git a/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb b/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb index 13f9c3028..710e1fa89 100644 --- a/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb +++ b/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb @@ -17,6 +17,7 @@ // see section `gyb` in `README` for details. import Crypto + #if canImport(FoundationEssentials) import FoundationEssentials #else From 3a8c300c7e1a2cc989f0643486237a4151b6465a Mon Sep 17 00:00:00 2001 From: Francesco Paolo Severino Date: Fri, 12 Sep 2025 16:39:09 +0200 Subject: [PATCH 31/47] Update CMakeLists.txt --- Sources/Crypto/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Sources/Crypto/CMakeLists.txt b/Sources/Crypto/CMakeLists.txt index 1b560e783..c8d9df809 100644 --- a/Sources/Crypto/CMakeLists.txt +++ b/Sources/Crypto/CMakeLists.txt @@ -91,6 +91,7 @@ add_library(Crypto "Signatures/BoringSSL/ECDSASignature_boring.swift" "Signatures/BoringSSL/ECDSA_boring.swift" "Signatures/BoringSSL/EdDSA_boring.swift" + "Signatures/BoringSSL/MLDSA+externalMu_boring.swift" "Signatures/BoringSSL/MLDSA_boring.swift" "Signatures/BoringSSL/MLDSA_wrapper.swift" "Signatures/ECDSA.swift" From 4e662b89da816cd60b032389bc9adaba61d71901 Mon Sep 17 00:00:00 2001 From: Tim Condon <0xTim@users.noreply.github.com> Date: Mon, 15 Sep 2025 15:07:07 +0100 Subject: [PATCH 32/47] Rename _CryptoExtras Take 2 (#407) Following on from #281, opened as a new PR as the conflicts were too many ### Checklist - [x] I've run tests to see all new and existing tests pass - [x] I've followed the code style of the rest of the project - [x] I've read the [Contribution Guidelines](CONTRIBUTING.md) - [x] I've updated the documentation if necessary #### If you've made changes to `gyb` files - [ ] I've run `.script/generate_boilerplate_files_with_gyb` and included updated generated files in a commit of this pull request ### Motivation: _[Explain here the context, and why you're making that change. What is the problem you're trying to solve.]_ ### Modifications: _[Describe the modifications you've done.]_ ### Result: _[After your change, what will change.]_ --- .github/workflows/pull_request.yml | 2 +- .gitignore | 3 +- .spi.yml | 2 +- .swiftformatignore | 136 +++++++++--------- Benchmarks/Benchmarks/Benchmarks.swift | 2 +- Benchmarks/Package.swift | 2 +- CONTRIBUTING.md | 2 +- Package.swift | 15 +- README.md | 2 +- Sources/CMakeLists.txt | 2 +- .../AES/AES_CBC.swift | 0 .../AES/AES_CFB.swift | 0 .../AES/AES_CTR.swift | 0 .../AES/AES_GCM_SIV.swift | 0 .../AES/Block Function.swift | 0 .../AES/BoringSSL/AES_CFB_boring.swift | 0 .../AES/BoringSSL/AES_CTR_boring.swift | 0 .../AES/BoringSSL/AES_GCM_SIV_boring.swift | 0 .../AES/CMAC.swift | 0 .../ARC/ARC+API.swift | 0 .../ARC/ARC.swift | 0 .../ARC/ARCCredential.swift | 0 .../ARC/ARCEncoding.swift | 0 .../ARC/ARCPrecredential.swift | 0 .../ARC/ARCPresentation.swift | 0 .../ARC/ARCRequest.swift | 0 .../ARC/ARCResponse.swift | 0 .../ARC/ARCServer.swift | 0 .../CMakeLists.txt | 18 +-- .../BoringSSL/ChaCha20CTR_boring.swift | 0 .../ChaCha20CTR/ChaCha20CTR.swift | 0 .../Docs.docc/index.md | 6 +- .../EC/ObjectIdentifier.swift | 0 .../EC/PKCS8DERRepresentation.swift | 0 .../EC/PKCS8PrivateKey.swift | 0 .../EC/RFC8410AlgorithmIdentifier.swift | 0 .../BoringSSL/ECToolbox_boring.swift | 0 .../ECToolbox/ECToolbox.swift | 0 .../H2G/HashToField.swift | 0 .../Key Derivation/KDF.swift | 0 .../PBKDF2/BoringSSL/PBKDF2_boring.swift | 0 .../BoringSSL/PBKDF2_commoncrypto.swift | 0 .../Key Derivation/PBKDF2/PBKDF2.swift | 0 .../Scrypt/BoringSSL/Scrypt_boring.swift | 0 .../Key Derivation/Scrypt/Scrypt.swift | 0 .../OPRFs/OPRF.swift | 0 .../OPRFs/OPRFClient.swift | 0 .../OPRFs/OPRFServer.swift | 0 .../OPRFs/VOPRF+API.swift | 0 .../OPRFs/VOPRFClient.swift | 0 .../OPRFs/VOPRFServer.swift | 0 .../PrivacyInfo.xcprivacy | 0 .../RSA/RSA+BlindSigning.swift | 0 .../RSA/RSA.swift | 0 .../RSA/RSA_boring.swift | 0 .../Reexport.swift | 0 .../Util/BoringSSLHelpers.swift | 0 .../Util/CryptoKitErrors_boring.swift | 0 .../Util/Data+Extensions.swift | 0 .../Util/DigestType.swift | 0 .../Util/Error.swift | 0 .../Util/I2OSP.swift | 0 .../Util/IntegerEncoding.swift | 0 .../Util/PEMDocument.swift | 0 .../Util/PrettyBytes.swift | 0 .../Util/SubjectPublicKeyInfo.swift | 0 .../Util/ThreadSpecific/ThreadOps.swift | 0 .../Util/ThreadSpecific/ThreadPosix.swift | 0 .../Util/ThreadSpecific/ThreadSpecific.swift | 0 .../Util/ThreadSpecific/ThreadWindows.swift | 0 .../ZKPs/DLEQ.swift | 0 .../ZKPs/Prover.swift | 0 .../ZKPs/Verifier.swift | 0 .../ZKPs/ZKPToolbox.swift | 0 Sources/_CryptoExtras/Exports.swift | 15 ++ .../AES Block Function Tests.swift | 2 +- .../AES-GCM-SIV-Runner.swift | 2 +- .../AES_CBCTests.swift | 4 +- .../AES_CFBTests.swift | 2 +- .../AES_CTRTests.swift | 2 +- .../ARC/ARCAPITests.swift | 2 +- .../ARC/ARCEncodingTests.swift | 2 +- .../ARC/ARCPublicAPITests.swift | 2 +- .../ARC/ARCTestVectors.swift | 2 +- .../ARC/ARCTests.swift | 2 +- .../CMACTests.swift | 2 +- .../ChaCha20CTRTests.swift | 2 +- .../BoringSSL/ECToolboxBoringSSLTests.swift | 4 +- .../H2CVectors/P256_XMD-SHA-256_SSWU_RO_.json | 0 .../H2CVectors/P384_XMD-SHA-384_SSWU_RO_.json | 0 .../ECToolbox/HashToCurveTests.swift | 18 +-- .../MLDSATests.swift | 4 +- .../MLKEMTests.swift | 2 +- .../OPRFs/ECVOPRFTests.swift | 88 ++++++------ .../OPRFVectors/OPRFVectors-VOPRFDraft19.json | 0 .../OPRFVectors/OPRFVectors-VOPRFDraft8.json | 0 .../OPRFVectors/OPRFVectors-edgecases.json | 0 .../OPRFs/VOPRFAPITests.swift | 2 +- .../OPRFs/VOPRFPublicAPITests.swift | 2 +- .../PBKDF2Tests.swift | 30 ++-- .../PKCS8DERRepresentationTests.swift | 2 +- .../ScryptTests.swift | 22 +-- .../TestRSABlindSigning.swift | 4 +- .../TestRSABlindSigningAPI.swift | 2 +- .../TestRSAEncryption.swift | 14 +- .../TestRSASigning.swift | 16 +-- .../Util/IntegerEncodingTests.swift | 2 +- .../Utils/BytesUtil.swift | 0 .../Utils/RFCVector.swift | 8 +- .../Utils/SplitData.swift | 0 .../Utils/Wycheproof.swift | 6 +- .../Utils/XCTestUtils.swift | 0 .../ZKPs/ZKPToolbox.swift | 2 +- .../AESCFB128GFSbox128.txt | 0 .../AESCFB128GFSbox192.txt | 0 .../AESCFB128GFSbox256.txt | 0 .../AESCFB128KeySbox128.txt | 0 .../AESCFB128KeySbox192.txt | 0 .../AESCFB128KeySbox256.txt | 0 .../AESCFB128VarKey128.txt | 0 .../AESCFB128VarKey192.txt | 0 .../AESCFB128VarKey256.txt | 0 .../AESCFB128VarTxt128.txt | 0 .../AESCFB128VarTxt192.txt | 0 .../AESCFB128VarTxt256.txt | 0 .../aes_cbc_pkcs5_test.json | 0 .../aes_cmac_test.json | 0 .../aes_gcm_siv_test.json | 0 .../mldsa_65_verify_test.json | 0 .../mldsa_87_verify_test.json | 0 .../mldsa_nist_keygen_65_tests.json | 0 .../mldsa_nist_keygen_87_tests.json | 0 .../rfc-6070-PBKDF2-SHA1.txt | 0 .../rfc-7914-scrypt.txt | 0 .../rfc9474.json | 0 .../rsa_oaep_2048_sha1_mgf1sha1_test.json | 0 .../rsa_oaep_2048_sha256_mgf1sha256_test.json | 0 .../rsa_oaep_misc_test.json | 0 .../rsa_pss_2048_sha1_mgf1_20_test.json | 0 .../rsa_pss_2048_sha256_mgf1_0_test.json | 0 .../rsa_pss_2048_sha256_mgf1_32_test.json | 0 .../rsa_pss_3072_sha256_mgf1_32_test.json | 0 .../rsa_pss_4096_sha256_mgf1_32_test.json | 0 .../rsa_pss_4096_sha512_mgf1_32_test.json | 0 .../rsa_pss_misc_test.json | 0 .../rsa_signature_2048_sha256_test.json | 0 .../rsa_signature_2048_sha512_test.json | 0 .../rsa_signature_3072_sha256_test.json | 0 .../rsa_signature_3072_sha512_test.json | 0 .../rsa_signature_4096_sha512_test.json | 0 .../rsa_signature_test.json | 0 scripts/gyb | 2 +- 152 files changed, 244 insertions(+), 219 deletions(-) rename Sources/{_CryptoExtras => CryptoExtras}/AES/AES_CBC.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/AES/AES_CFB.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/AES/AES_CTR.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/AES/AES_GCM_SIV.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/AES/Block Function.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/AES/BoringSSL/AES_CFB_boring.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/AES/BoringSSL/AES_CTR_boring.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/AES/BoringSSL/AES_GCM_SIV_boring.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/AES/CMAC.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/ARC/ARC+API.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/ARC/ARC.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/ARC/ARCCredential.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/ARC/ARCEncoding.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/ARC/ARCPrecredential.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/ARC/ARCPresentation.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/ARC/ARCRequest.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/ARC/ARCResponse.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/ARC/ARCServer.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/CMakeLists.txt (84%) rename Sources/{_CryptoExtras => CryptoExtras}/ChaCha20CTR/BoringSSL/ChaCha20CTR_boring.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/ChaCha20CTR/ChaCha20CTR.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/Docs.docc/index.md (82%) rename Sources/{_CryptoExtras => CryptoExtras}/EC/ObjectIdentifier.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/EC/PKCS8DERRepresentation.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/EC/PKCS8PrivateKey.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/EC/RFC8410AlgorithmIdentifier.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/ECToolbox/BoringSSL/ECToolbox_boring.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/ECToolbox/ECToolbox.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/H2G/HashToField.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/Key Derivation/KDF.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/Key Derivation/PBKDF2/BoringSSL/PBKDF2_boring.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/Key Derivation/PBKDF2/BoringSSL/PBKDF2_commoncrypto.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/Key Derivation/PBKDF2/PBKDF2.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/Key Derivation/Scrypt/BoringSSL/Scrypt_boring.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/Key Derivation/Scrypt/Scrypt.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/OPRFs/OPRF.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/OPRFs/OPRFClient.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/OPRFs/OPRFServer.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/OPRFs/VOPRF+API.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/OPRFs/VOPRFClient.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/OPRFs/VOPRFServer.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/PrivacyInfo.xcprivacy (100%) rename Sources/{_CryptoExtras => CryptoExtras}/RSA/RSA+BlindSigning.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/RSA/RSA.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/RSA/RSA_boring.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/Reexport.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/Util/BoringSSLHelpers.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/Util/CryptoKitErrors_boring.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/Util/Data+Extensions.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/Util/DigestType.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/Util/Error.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/Util/I2OSP.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/Util/IntegerEncoding.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/Util/PEMDocument.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/Util/PrettyBytes.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/Util/SubjectPublicKeyInfo.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/Util/ThreadSpecific/ThreadOps.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/Util/ThreadSpecific/ThreadPosix.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/Util/ThreadSpecific/ThreadSpecific.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/Util/ThreadSpecific/ThreadWindows.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/ZKPs/DLEQ.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/ZKPs/Prover.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/ZKPs/Verifier.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/ZKPs/ZKPToolbox.swift (100%) create mode 100644 Sources/_CryptoExtras/Exports.swift rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/AES Block Function Tests.swift (99%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/AES-GCM-SIV-Runner.swift (99%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/AES_CBCTests.swift (99%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/AES_CFBTests.swift (99%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/AES_CTRTests.swift (99%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/ARC/ARCAPITests.swift (99%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/ARC/ARCEncodingTests.swift (99%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/ARC/ARCPublicAPITests.swift (98%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/ARC/ARCTestVectors.swift (99%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/ARC/ARCTests.swift (99%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/CMACTests.swift (99%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/ChaCha20CTRTests.swift (99%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/ECToolbox/BoringSSL/ECToolboxBoringSSLTests.swift (98%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/ECToolbox/H2CVectors/P256_XMD-SHA-256_SSWU_RO_.json (100%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/ECToolbox/H2CVectors/P384_XMD-SHA-384_SSWU_RO_.json (100%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/ECToolbox/HashToCurveTests.swift (98%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/MLDSATests.swift (99%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/MLKEMTests.swift (99%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/OPRFs/ECVOPRFTests.swift (96%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/OPRFs/OPRFVectors/OPRFVectors-VOPRFDraft19.json (100%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/OPRFs/OPRFVectors/OPRFVectors-VOPRFDraft8.json (100%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/OPRFs/OPRFVectors/OPRFVectors-edgecases.json (100%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/OPRFs/VOPRFAPITests.swift (97%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/OPRFs/VOPRFPublicAPITests.swift (97%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/PBKDF2Tests.swift (96%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/PKCS8DERRepresentationTests.swift (99%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/ScryptTests.swift (97%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/TestRSABlindSigning.swift (99%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/TestRSABlindSigningAPI.swift (96%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/TestRSAEncryption.swift (99%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/TestRSASigning.swift (99%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/Util/IntegerEncodingTests.swift (99%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/Utils/BytesUtil.swift (100%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/Utils/RFCVector.swift (97%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/Utils/SplitData.swift (100%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/Utils/Wycheproof.swift (85%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/Utils/XCTestUtils.swift (100%) rename Tests/{_CryptoExtrasTests => CryptoExtrasTests}/ZKPs/ZKPToolbox.swift (99%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/AESCFB128GFSbox128.txt (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/AESCFB128GFSbox192.txt (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/AESCFB128GFSbox256.txt (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/AESCFB128KeySbox128.txt (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/AESCFB128KeySbox192.txt (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/AESCFB128KeySbox256.txt (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/AESCFB128VarKey128.txt (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/AESCFB128VarKey192.txt (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/AESCFB128VarKey256.txt (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/AESCFB128VarTxt128.txt (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/AESCFB128VarTxt192.txt (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/AESCFB128VarTxt256.txt (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/aes_cbc_pkcs5_test.json (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/aes_cmac_test.json (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/aes_gcm_siv_test.json (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/mldsa_65_verify_test.json (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/mldsa_87_verify_test.json (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/mldsa_nist_keygen_65_tests.json (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/mldsa_nist_keygen_87_tests.json (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/rfc-6070-PBKDF2-SHA1.txt (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/rfc-7914-scrypt.txt (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/rfc9474.json (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/rsa_oaep_2048_sha1_mgf1sha1_test.json (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/rsa_oaep_2048_sha256_mgf1sha256_test.json (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/rsa_oaep_misc_test.json (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/rsa_pss_2048_sha1_mgf1_20_test.json (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/rsa_pss_2048_sha256_mgf1_0_test.json (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/rsa_pss_2048_sha256_mgf1_32_test.json (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/rsa_pss_3072_sha256_mgf1_32_test.json (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/rsa_pss_4096_sha256_mgf1_32_test.json (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/rsa_pss_4096_sha512_mgf1_32_test.json (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/rsa_pss_misc_test.json (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/rsa_signature_2048_sha256_test.json (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/rsa_signature_2048_sha512_test.json (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/rsa_signature_3072_sha256_test.json (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/rsa_signature_3072_sha512_test.json (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/rsa_signature_4096_sha512_test.json (100%) rename Tests/{_CryptoExtrasVectors => CryptoExtrasVectors}/rsa_signature_test.json (100%) diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 34d248012..3ff06facc 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -56,7 +56,7 @@ jobs: { "name": "CXKCP", "type": "source", "exceptions": [] }, { "name": "CXKCPShims", "type": "source", "exceptions": [] }, { "name": "Crypto", "type": "source", "exceptions": [] }, - { "name": "_CryptoExtras", "type": "source", "exceptions": [] }, + { "name": "CryptoExtras", "type": "source", "exceptions": [] }, { "name": "CCryptoBoringSSL", "type": "assembly", "exceptions": [ "*/AES/*.swift" ] } ] } diff --git a/.gitignore b/.gitignore index 9b3fae344..98fffc86e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ .DS_Store -/.build +.build /out /Packages /*.xcodeproj @@ -12,6 +12,7 @@ Package.resolved DerivedData .swiftpm **/gyb.pyc +scripts/__pycache__/ .*.sw[nop] diff --git a/.spi.yml b/.spi.yml index f26c856c9..f432bfa46 100644 --- a/.spi.yml +++ b/.spi.yml @@ -1,5 +1,5 @@ version: 1 builder: configs: - - documentation_targets: [Crypto, _CryptoExtras] + - documentation_targets: [Crypto, CryptoExtras] platform: linux diff --git a/.swiftformatignore b/.swiftformatignore index 13def9f5f..730c28aba 100644 --- a/.swiftformatignore +++ b/.swiftformatignore @@ -69,46 +69,46 @@ Sources/Crypto/Util/PrettyBytes.swift Sources/Crypto/Util/SafeCompare.swift Sources/Crypto/Util/SecureBytes.swift Sources/Crypto/Util/Zeroization.swift -Sources/_CryptoExtras/AES/AES_CBC.swift -Sources/_CryptoExtras/AES/AES_CFB.swift -Sources/_CryptoExtras/AES/AES_CTR.swift -Sources/_CryptoExtras/AES/AES_GCM_SIV.swift -Sources/_CryptoExtras/AES/Block Function.swift -Sources/_CryptoExtras/ARC/ARC+API.swift -Sources/_CryptoExtras/ARC/ARC.swift -Sources/_CryptoExtras/ARC/ARCCredential.swift -Sources/_CryptoExtras/ARC/ARCEncoding.swift -Sources/_CryptoExtras/ARC/ARCPrecredential.swift -Sources/_CryptoExtras/ARC/ARCPresentation.swift -Sources/_CryptoExtras/ARC/ARCRequest.swift -Sources/_CryptoExtras/ARC/ARCResponse.swift -Sources/_CryptoExtras/ARC/ARCServer.swift -Sources/_CryptoExtras/ZKPs/Prover.swift -Sources/_CryptoExtras/ZKPs/Verifier.swift -Sources/_CryptoExtras/ZKPs/ZKPToolbox.swift -Sources/_CryptoExtras/ChaCha20CTR/ChaCha20CTR.swift -Sources/_CryptoExtras/ECToolbox/ECToolbox.swift -Sources/_CryptoExtras/H2G/HashToField.swift -Sources/_CryptoExtras/Key Derivation/KDF.swift -Sources/_CryptoExtras/Key Derivation/PBKDF2/PBKDF2.swift -Sources/_CryptoExtras/Key Derivation/Scrypt/Scrypt.swift -Sources/_CryptoExtras/OPRFs/OPRF.swift -Sources/_CryptoExtras/OPRFs/OPRFClient.swift -Sources/_CryptoExtras/OPRFs/OPRFServer.swift -Sources/_CryptoExtras/OPRFs/VOPRF+API.swift -Sources/_CryptoExtras/OPRFs/VOPRFClient.swift -Sources/_CryptoExtras/OPRFs/VOPRFServer.swift -Sources/_CryptoExtras/RSA/RSA+BlindSigning.swift -Sources/_CryptoExtras/RSA/RSA.swift -Sources/_CryptoExtras/Util/BoringSSLHelpers.swift -Sources/_CryptoExtras/Util/DigestType.swift -Sources/_CryptoExtras/Util/Error.swift -Sources/_CryptoExtras/Util/I2OSP.swift -Sources/_CryptoExtras/Util/IntegerEncoding.swift -Sources/_CryptoExtras/Util/PEMDocument.swift -Sources/_CryptoExtras/Util/PrettyBytes.swift -Sources/_CryptoExtras/Util/SubjectPublicKeyInfo.swift -Sources/_CryptoExtras/ZKPs/DLEQ.swift +Sources/CryptoExtras/AES/AES_CBC.swift +Sources/CryptoExtras/AES/AES_CFB.swift +Sources/CryptoExtras/AES/AES_CTR.swift +Sources/CryptoExtras/AES/AES_GCM_SIV.swift +Sources/CryptoExtras/AES/Block Function.swift +Sources/CryptoExtras/ARC/ARC+API.swift +Sources/CryptoExtras/ARC/ARC.swift +Sources/CryptoExtras/ARC/ARCCredential.swift +Sources/CryptoExtras/ARC/ARCEncoding.swift +Sources/CryptoExtras/ARC/ARCPrecredential.swift +Sources/CryptoExtras/ARC/ARCPresentation.swift +Sources/CryptoExtras/ARC/ARCRequest.swift +Sources/CryptoExtras/ARC/ARCResponse.swift +Sources/CryptoExtras/ARC/ARCServer.swift +Sources/CryptoExtras/ZKPs/Prover.swift +Sources/CryptoExtras/ZKPs/Verifier.swift +Sources/CryptoExtras/ZKPs/ZKPToolbox.swift +Sources/CryptoExtras/ChaCha20CTR/ChaCha20CTR.swift +Sources/CryptoExtras/ECToolbox/ECToolbox.swift +Sources/CryptoExtras/H2G/HashToField.swift +Sources/CryptoExtras/Key Derivation/KDF.swift +Sources/CryptoExtras/Key Derivation/PBKDF2/PBKDF2.swift +Sources/CryptoExtras/Key Derivation/Scrypt/Scrypt.swift +Sources/CryptoExtras/OPRFs/OPRF.swift +Sources/CryptoExtras/OPRFs/OPRFClient.swift +Sources/CryptoExtras/OPRFs/OPRFServer.swift +Sources/CryptoExtras/OPRFs/VOPRF+API.swift +Sources/CryptoExtras/OPRFs/VOPRFClient.swift +Sources/CryptoExtras/OPRFs/VOPRFServer.swift +Sources/CryptoExtras/RSA/RSA+BlindSigning.swift +Sources/CryptoExtras/RSA/RSA.swift +Sources/CryptoExtras/Util/BoringSSLHelpers.swift +Sources/CryptoExtras/Util/DigestType.swift +Sources/CryptoExtras/Util/Error.swift +Sources/CryptoExtras/Util/I2OSP.swift +Sources/CryptoExtras/Util/IntegerEncoding.swift +Sources/CryptoExtras/Util/PEMDocument.swift +Sources/CryptoExtras/Util/PrettyBytes.swift +Sources/CryptoExtras/Util/SubjectPublicKeyInfo.swift +Sources/CryptoExtras/ZKPs/DLEQ.swift Sources/crypto-shasum/main.swift Tests/CryptoTests/ASN1/ASN1Tests.swift Tests/CryptoTests/ASN1/GeneralizedTimeTests.swift @@ -141,31 +141,31 @@ Tests/CryptoTests/Utils/RFCVector.swift Tests/CryptoTests/Utils/SplitData.swift Tests/CryptoTests/Utils/Wycheproof.swift Tests/CryptoTests/Utils/XCTestUtils.swift -Tests/_CryptoExtrasTests/AES Block Function Tests.swift -Tests/_CryptoExtrasTests/AES-GCM-SIV-Runner.swift -Tests/_CryptoExtrasTests/AES_CBCTests.swift -Tests/_CryptoExtrasTests/AES_CFBTests.swift -Tests/_CryptoExtrasTests/AES_CTRTests.swift -Tests/_CryptoExtrasTests/ARC/ARCAPITests.swift -Tests/_CryptoExtrasTests/ARC/ARCEncodingTests.swift -Tests/_CryptoExtrasTests/ARC/ARCPublicAPITests.swift -Tests/_CryptoExtrasTests/ARC/ARCTestVectors.swift -Tests/_CryptoExtrasTests/ARC/ARCTests.swift -Tests/_CryptoExtrasTests/ChaCha20CTRTests.swift -Tests/_CryptoExtrasTests/ECToolbox/HashToCurveTests.swift -Tests/_CryptoExtrasTests/OPRFs/ECVOPRFTests.swift -Tests/_CryptoExtrasTests/OPRFs/VOPRFAPITests.swift -Tests/_CryptoExtrasTests/OPRFs/VOPRFPublicAPITests.swift -Tests/_CryptoExtrasTests/PBKDF2Tests.swift -Tests/_CryptoExtrasTests/ScryptTests.swift -Tests/_CryptoExtrasTests/TestRSABlindSigning.swift -Tests/_CryptoExtrasTests/TestRSABlindSigningAPI.swift -Tests/_CryptoExtrasTests/TestRSAEncryption.swift -Tests/_CryptoExtrasTests/TestRSASigning.swift -Tests/_CryptoExtrasTests/Util/IntegerEncodingTests.swift -Tests/_CryptoExtrasTests/Utils/BytesUtil.swift -Tests/_CryptoExtrasTests/Utils/RFCVector.swift -Tests/_CryptoExtrasTests/Utils/SplitData.swift -Tests/_CryptoExtrasTests/Utils/Wycheproof.swift -Tests/_CryptoExtrasTests/Utils/XCTestUtils.swift -Tests/_CryptoExtrasTests/ZKPs/ZKPToolbox.swift +Tests/CryptoExtrasTests/AES Block Function Tests.swift +Tests/CryptoExtrasTests/AES-GCM-SIV-Runner.swift +Tests/CryptoExtrasTests/AES_CBCTests.swift +Tests/CryptoExtrasTests/AES_CFBTests.swift +Tests/CryptoExtrasTests/AES_CTRTests.swift +Tests/CryptoExtrasTests/ARC/ARCAPITests.swift +Tests/CryptoExtrasTests/ARC/ARCEncodingTests.swift +Tests/CryptoExtrasTests/ARC/ARCPublicAPITests.swift +Tests/CryptoExtrasTests/ARC/ARCTestVectors.swift +Tests/CryptoExtrasTests/ARC/ARCTests.swift +Tests/CryptoExtrasTests/ChaCha20CTRTests.swift +Tests/CryptoExtrasTests/ECToolbox/HashToCurveTests.swift +Tests/CryptoExtrasTests/OPRFs/ECVOPRFTests.swift +Tests/CryptoExtrasTests/OPRFs/VOPRFAPITests.swift +Tests/CryptoExtrasTests/OPRFs/VOPRFPublicAPITests.swift +Tests/CryptoExtrasTests/PBKDF2Tests.swift +Tests/CryptoExtrasTests/ScryptTests.swift +Tests/CryptoExtrasTests/TestRSABlindSigning.swift +Tests/CryptoExtrasTests/TestRSABlindSigningAPI.swift +Tests/CryptoExtrasTests/TestRSAEncryption.swift +Tests/CryptoExtrasTests/TestRSASigning.swift +Tests/CryptoExtrasTests/Util/IntegerEncodingTests.swift +Tests/CryptoExtrasTests/Utils/BytesUtil.swift +Tests/CryptoExtrasTests/Utils/RFCVector.swift +Tests/CryptoExtrasTests/Utils/SplitData.swift +Tests/CryptoExtrasTests/Utils/Wycheproof.swift +Tests/CryptoExtrasTests/Utils/XCTestUtils.swift +Tests/CryptoExtrasTests/ZKPs/ZKPToolbox.swift diff --git a/Benchmarks/Benchmarks/Benchmarks.swift b/Benchmarks/Benchmarks/Benchmarks.swift index 155fe1416..dffc12aea 100644 --- a/Benchmarks/Benchmarks/Benchmarks.swift +++ b/Benchmarks/Benchmarks/Benchmarks.swift @@ -13,7 +13,7 @@ //===----------------------------------------------------------------------===// import Benchmark import Crypto -import _CryptoExtras +import CryptoExtras #if canImport(FoundationEssentials) import FoundationEssentials diff --git a/Benchmarks/Package.swift b/Benchmarks/Package.swift index 6b93c2d17..02e116ec0 100644 --- a/Benchmarks/Package.swift +++ b/Benchmarks/Package.swift @@ -14,7 +14,7 @@ let package = Package( dependencies: [ .product(name: "Benchmark", package: "package-benchmark"), .product(name: "Crypto", package: "swift-crypto"), - .product(name: "_CryptoExtras", package: "swift-crypto"), + .product(name: "CryptoExtras", package: "swift-crypto"), ], path: "Benchmarks/", plugins: [ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index eef6b8b79..9b4c6ded7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -69,7 +69,7 @@ act --container-architecture linux/amd64 pull_request -j cmake-lists -W ./.githu You can find the underlying script at https://github.com/apple/swift-nio/blob/main/scripts/update-cmake-lists.sh . Using the script directly is less straightforwards because it requires you to pass the JSON config from the `pull_request.yml` file into the script, such as: ``` -curl -s https://raw.githubusercontent.com/apple/swift-nio/main/scripts/update-cmake-lists.sh | CONFIG_JSON='{"targets":[{"name":"CCryptoBoringSSL","type":"source","exceptions":[]},{"name":"CCryptoBoringSSLShims","type":"source","exceptions":[]},{"name":"CryptoBoringWrapper","type":"source","exceptions":[]},{"name":"Crypto","type":"source","exceptions":[]},{"name":"_CryptoExtras","type":"source","exceptions":[]},{"name":"CCryptoBoringSSL","type":"assembly","exceptions":["*/AES/*.swift"]}]}' bash +curl -s https://raw.githubusercontent.com/apple/swift-nio/main/scripts/update-cmake-lists.sh | CONFIG_JSON='{"targets":[{"name":"CCryptoBoringSSL","type":"source","exceptions":[]},{"name":"CCryptoBoringSSLShims","type":"source","exceptions":[]},{"name":"CryptoBoringWrapper","type":"source","exceptions":[]},{"name":"Crypto","type":"source","exceptions":[]},{"name":"CryptoExtras","type":"source","exceptions":[]},{"name":"CCryptoBoringSSL","type":"assembly","exceptions":["*/AES/*.swift"]}]}' bash ``` ## API Evolution diff --git a/Package.swift b/Package.swift index ddfe1277b..596beb7ec 100644 --- a/Package.swift +++ b/Package.swift @@ -89,7 +89,9 @@ let package = Package( name: "swift-crypto", products: [ .library(name: "Crypto", targets: ["Crypto"]), + // Kept for backward compatibility .library(name: "_CryptoExtras", targets: ["_CryptoExtras"]), + .library(name: "CryptoExtras", targets: ["CryptoExtras"]), /* This target is used only for symbol mangling. It's added and removed automatically because it emits build warnings. MANGLE_START .library(name: "CCryptoBoringSSL", type: .static, targets: ["CCryptoBoringSSL"]), MANGLE_END */ @@ -177,7 +179,7 @@ let package = Package( swiftSettings: swiftSettings ), .target( - name: "_CryptoExtras", + name: "CryptoExtras", dependencies: [ "CCryptoBoringSSL", "CCryptoBoringSSLShims", @@ -191,6 +193,13 @@ let package = Package( resources: privacyManifestResource, swiftSettings: swiftSettings ), + .target( + name: "_CryptoExtras", + dependencies: [ + "CryptoExtras", + ], + swiftSettings: swiftSettings + ), .target( name: "CryptoBoringWrapper", dependencies: [ @@ -219,8 +228,8 @@ let package = Package( swiftSettings: swiftSettings ), .testTarget( - name: "_CryptoExtrasTests", - dependencies: ["_CryptoExtras"], + name: "CryptoExtrasTests", + dependencies: ["CryptoExtras"], resources: [ .copy("ECToolbox/H2CVectors/P256_XMD-SHA-256_SSWU_RO_.json"), .copy("ECToolbox/H2CVectors/P384_XMD-SHA-384_SSWU_RO_.json"), diff --git a/README.md b/README.md index ec5134552..33c5f8686 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ When building Swift Crypto for use on Linux or Windows, Swift Crypto builds subs 2. The common API of Swift Crypto and CryptoKit. 3. The backing implementation of this common API, which calls into BoringSSL. -The API code, and some cryptographic primitives which are directly implemented in Swift, are exactly the same for both Apple CryptoKit and Swift Crypto. The backing BoringSSL-based implementation is unique to Swift Crypto. +The API code, and some cryptographic primitives which are directly implemented in Swift, are exactly the same for both Apple CryptoKit and Swift Crypto. The backing BoringSSL-based implementation is unique to Swift Crypto. In addition, there is another product, `CryptoExtras`, which provides additional functionality that is not offered in CryptoKit, which contains cryptographic APIS predominantly useful in the server ecosystem. **Note**: if you depend on CryptoExtras you'll bundle the BoringSSL implementation of the library in your application, no matter the platform. ## Evolution diff --git a/Sources/CMakeLists.txt b/Sources/CMakeLists.txt index 55ee7d73b..4616a1f1e 100644 --- a/Sources/CMakeLists.txt +++ b/Sources/CMakeLists.txt @@ -18,4 +18,4 @@ add_subdirectory(CXKCP) add_subdirectory(CXKCPShims) add_subdirectory(CryptoBoringWrapper) add_subdirectory(Crypto) -add_subdirectory(_CryptoExtras) +add_subdirectory(CryptoExtras) diff --git a/Sources/_CryptoExtras/AES/AES_CBC.swift b/Sources/CryptoExtras/AES/AES_CBC.swift similarity index 100% rename from Sources/_CryptoExtras/AES/AES_CBC.swift rename to Sources/CryptoExtras/AES/AES_CBC.swift diff --git a/Sources/_CryptoExtras/AES/AES_CFB.swift b/Sources/CryptoExtras/AES/AES_CFB.swift similarity index 100% rename from Sources/_CryptoExtras/AES/AES_CFB.swift rename to Sources/CryptoExtras/AES/AES_CFB.swift diff --git a/Sources/_CryptoExtras/AES/AES_CTR.swift b/Sources/CryptoExtras/AES/AES_CTR.swift similarity index 100% rename from Sources/_CryptoExtras/AES/AES_CTR.swift rename to Sources/CryptoExtras/AES/AES_CTR.swift diff --git a/Sources/_CryptoExtras/AES/AES_GCM_SIV.swift b/Sources/CryptoExtras/AES/AES_GCM_SIV.swift similarity index 100% rename from Sources/_CryptoExtras/AES/AES_GCM_SIV.swift rename to Sources/CryptoExtras/AES/AES_GCM_SIV.swift diff --git a/Sources/_CryptoExtras/AES/Block Function.swift b/Sources/CryptoExtras/AES/Block Function.swift similarity index 100% rename from Sources/_CryptoExtras/AES/Block Function.swift rename to Sources/CryptoExtras/AES/Block Function.swift diff --git a/Sources/_CryptoExtras/AES/BoringSSL/AES_CFB_boring.swift b/Sources/CryptoExtras/AES/BoringSSL/AES_CFB_boring.swift similarity index 100% rename from Sources/_CryptoExtras/AES/BoringSSL/AES_CFB_boring.swift rename to Sources/CryptoExtras/AES/BoringSSL/AES_CFB_boring.swift diff --git a/Sources/_CryptoExtras/AES/BoringSSL/AES_CTR_boring.swift b/Sources/CryptoExtras/AES/BoringSSL/AES_CTR_boring.swift similarity index 100% rename from Sources/_CryptoExtras/AES/BoringSSL/AES_CTR_boring.swift rename to Sources/CryptoExtras/AES/BoringSSL/AES_CTR_boring.swift diff --git a/Sources/_CryptoExtras/AES/BoringSSL/AES_GCM_SIV_boring.swift b/Sources/CryptoExtras/AES/BoringSSL/AES_GCM_SIV_boring.swift similarity index 100% rename from Sources/_CryptoExtras/AES/BoringSSL/AES_GCM_SIV_boring.swift rename to Sources/CryptoExtras/AES/BoringSSL/AES_GCM_SIV_boring.swift diff --git a/Sources/_CryptoExtras/AES/CMAC.swift b/Sources/CryptoExtras/AES/CMAC.swift similarity index 100% rename from Sources/_CryptoExtras/AES/CMAC.swift rename to Sources/CryptoExtras/AES/CMAC.swift diff --git a/Sources/_CryptoExtras/ARC/ARC+API.swift b/Sources/CryptoExtras/ARC/ARC+API.swift similarity index 100% rename from Sources/_CryptoExtras/ARC/ARC+API.swift rename to Sources/CryptoExtras/ARC/ARC+API.swift diff --git a/Sources/_CryptoExtras/ARC/ARC.swift b/Sources/CryptoExtras/ARC/ARC.swift similarity index 100% rename from Sources/_CryptoExtras/ARC/ARC.swift rename to Sources/CryptoExtras/ARC/ARC.swift diff --git a/Sources/_CryptoExtras/ARC/ARCCredential.swift b/Sources/CryptoExtras/ARC/ARCCredential.swift similarity index 100% rename from Sources/_CryptoExtras/ARC/ARCCredential.swift rename to Sources/CryptoExtras/ARC/ARCCredential.swift diff --git a/Sources/_CryptoExtras/ARC/ARCEncoding.swift b/Sources/CryptoExtras/ARC/ARCEncoding.swift similarity index 100% rename from Sources/_CryptoExtras/ARC/ARCEncoding.swift rename to Sources/CryptoExtras/ARC/ARCEncoding.swift diff --git a/Sources/_CryptoExtras/ARC/ARCPrecredential.swift b/Sources/CryptoExtras/ARC/ARCPrecredential.swift similarity index 100% rename from Sources/_CryptoExtras/ARC/ARCPrecredential.swift rename to Sources/CryptoExtras/ARC/ARCPrecredential.swift diff --git a/Sources/_CryptoExtras/ARC/ARCPresentation.swift b/Sources/CryptoExtras/ARC/ARCPresentation.swift similarity index 100% rename from Sources/_CryptoExtras/ARC/ARCPresentation.swift rename to Sources/CryptoExtras/ARC/ARCPresentation.swift diff --git a/Sources/_CryptoExtras/ARC/ARCRequest.swift b/Sources/CryptoExtras/ARC/ARCRequest.swift similarity index 100% rename from Sources/_CryptoExtras/ARC/ARCRequest.swift rename to Sources/CryptoExtras/ARC/ARCRequest.swift diff --git a/Sources/_CryptoExtras/ARC/ARCResponse.swift b/Sources/CryptoExtras/ARC/ARCResponse.swift similarity index 100% rename from Sources/_CryptoExtras/ARC/ARCResponse.swift rename to Sources/CryptoExtras/ARC/ARCResponse.swift diff --git a/Sources/_CryptoExtras/ARC/ARCServer.swift b/Sources/CryptoExtras/ARC/ARCServer.swift similarity index 100% rename from Sources/_CryptoExtras/ARC/ARCServer.swift rename to Sources/CryptoExtras/ARC/ARCServer.swift diff --git a/Sources/_CryptoExtras/CMakeLists.txt b/Sources/CryptoExtras/CMakeLists.txt similarity index 84% rename from Sources/_CryptoExtras/CMakeLists.txt rename to Sources/CryptoExtras/CMakeLists.txt index f7b2f9ab7..8498dc443 100644 --- a/Sources/_CryptoExtras/CMakeLists.txt +++ b/Sources/CryptoExtras/CMakeLists.txt @@ -12,7 +12,7 @@ ## ##===----------------------------------------------------------------------===## -add_library(_CryptoExtras +add_library(CryptoExtras "AES/AES_CBC.swift" "AES/AES_CFB.swift" "AES/AES_CTR.swift" @@ -76,29 +76,29 @@ add_library(_CryptoExtras "ZKPs/ZKPToolbox.swift" ) -target_compile_options(_CryptoExtras PRIVATE -DCRYPTO_IN_SWIFTPM) +target_compile_options(CryptoExtras PRIVATE -DCRYPTO_IN_SWIFTPM) if(NOT CMAKE_SYSTEM_NAME STREQUAL "Darwin") - target_compile_options(_CryptoExtras PRIVATE -DCRYPTO_IN_SWIFTPM_FORCE_BUILD_API) + target_compile_options(CryptoExtras PRIVATE -DCRYPTO_IN_SWIFTPM_FORCE_BUILD_API) endif() -target_include_directories(_CryptoExtras PRIVATE +target_include_directories(CryptoExtras PRIVATE $ $) -target_link_libraries(_CryptoExtras PUBLIC +target_link_libraries(CryptoExtras PUBLIC $<$>:Foundation> Crypto CryptoBoringWrapper CCryptoBoringSSL CCryptoBoringSSLShims) -target_compile_options(_CryptoExtras PRIVATE ${SWIFT_CRYPTO_COMPILE_OPTIONS}) +target_compile_options(CryptoExtras PRIVATE ${SWIFT_CRYPTO_COMPILE_OPTIONS}) -target_link_options(_CryptoExtras PRIVATE +target_link_options(CryptoExtras PRIVATE "$<$:SHELL:-Xlinker -framework -Xlinker Security>") -set_target_properties(_CryptoExtras PROPERTIES +set_target_properties(CryptoExtras PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY}) -set_property(GLOBAL APPEND PROPERTY SWIFT_CRYPTO_EXPORTS _CryptoExtras) +set_property(GLOBAL APPEND PROPERTY SWIFT_CRYPTO_EXPORTS CryptoExtras) diff --git a/Sources/_CryptoExtras/ChaCha20CTR/BoringSSL/ChaCha20CTR_boring.swift b/Sources/CryptoExtras/ChaCha20CTR/BoringSSL/ChaCha20CTR_boring.swift similarity index 100% rename from Sources/_CryptoExtras/ChaCha20CTR/BoringSSL/ChaCha20CTR_boring.swift rename to Sources/CryptoExtras/ChaCha20CTR/BoringSSL/ChaCha20CTR_boring.swift diff --git a/Sources/_CryptoExtras/ChaCha20CTR/ChaCha20CTR.swift b/Sources/CryptoExtras/ChaCha20CTR/ChaCha20CTR.swift similarity index 100% rename from Sources/_CryptoExtras/ChaCha20CTR/ChaCha20CTR.swift rename to Sources/CryptoExtras/ChaCha20CTR/ChaCha20CTR.swift diff --git a/Sources/_CryptoExtras/Docs.docc/index.md b/Sources/CryptoExtras/Docs.docc/index.md similarity index 82% rename from Sources/_CryptoExtras/Docs.docc/index.md rename to Sources/CryptoExtras/Docs.docc/index.md index 50b5eca56..9bda3af77 100644 --- a/Sources/_CryptoExtras/Docs.docc/index.md +++ b/Sources/CryptoExtras/Docs.docc/index.md @@ -1,4 +1,4 @@ -# ``_CryptoExtras`` +# ``CryptoExtras`` Provides additional cryptographic APIs that are not available in CryptoKit (and therefore the core Crypto library). @@ -10,7 +10,7 @@ Provides additional cryptographic APIs that are not available in CryptoKit (and ### Ciphers -- ``_CryptoExtras/Crypto/AES`` +- ``CryptoExtras/Crypto/AES`` ### Public key cryptography @@ -22,4 +22,4 @@ Provides additional cryptographic APIs that are not available in CryptoKit (and ### Legacy algorithms -- ``_CryptoExtras/Crypto/Insecure`` +- ``CryptoExtras/Crypto/Insecure`` diff --git a/Sources/_CryptoExtras/EC/ObjectIdentifier.swift b/Sources/CryptoExtras/EC/ObjectIdentifier.swift similarity index 100% rename from Sources/_CryptoExtras/EC/ObjectIdentifier.swift rename to Sources/CryptoExtras/EC/ObjectIdentifier.swift diff --git a/Sources/_CryptoExtras/EC/PKCS8DERRepresentation.swift b/Sources/CryptoExtras/EC/PKCS8DERRepresentation.swift similarity index 100% rename from Sources/_CryptoExtras/EC/PKCS8DERRepresentation.swift rename to Sources/CryptoExtras/EC/PKCS8DERRepresentation.swift diff --git a/Sources/_CryptoExtras/EC/PKCS8PrivateKey.swift b/Sources/CryptoExtras/EC/PKCS8PrivateKey.swift similarity index 100% rename from Sources/_CryptoExtras/EC/PKCS8PrivateKey.swift rename to Sources/CryptoExtras/EC/PKCS8PrivateKey.swift diff --git a/Sources/_CryptoExtras/EC/RFC8410AlgorithmIdentifier.swift b/Sources/CryptoExtras/EC/RFC8410AlgorithmIdentifier.swift similarity index 100% rename from Sources/_CryptoExtras/EC/RFC8410AlgorithmIdentifier.swift rename to Sources/CryptoExtras/EC/RFC8410AlgorithmIdentifier.swift diff --git a/Sources/_CryptoExtras/ECToolbox/BoringSSL/ECToolbox_boring.swift b/Sources/CryptoExtras/ECToolbox/BoringSSL/ECToolbox_boring.swift similarity index 100% rename from Sources/_CryptoExtras/ECToolbox/BoringSSL/ECToolbox_boring.swift rename to Sources/CryptoExtras/ECToolbox/BoringSSL/ECToolbox_boring.swift diff --git a/Sources/_CryptoExtras/ECToolbox/ECToolbox.swift b/Sources/CryptoExtras/ECToolbox/ECToolbox.swift similarity index 100% rename from Sources/_CryptoExtras/ECToolbox/ECToolbox.swift rename to Sources/CryptoExtras/ECToolbox/ECToolbox.swift diff --git a/Sources/_CryptoExtras/H2G/HashToField.swift b/Sources/CryptoExtras/H2G/HashToField.swift similarity index 100% rename from Sources/_CryptoExtras/H2G/HashToField.swift rename to Sources/CryptoExtras/H2G/HashToField.swift diff --git a/Sources/_CryptoExtras/Key Derivation/KDF.swift b/Sources/CryptoExtras/Key Derivation/KDF.swift similarity index 100% rename from Sources/_CryptoExtras/Key Derivation/KDF.swift rename to Sources/CryptoExtras/Key Derivation/KDF.swift diff --git a/Sources/_CryptoExtras/Key Derivation/PBKDF2/BoringSSL/PBKDF2_boring.swift b/Sources/CryptoExtras/Key Derivation/PBKDF2/BoringSSL/PBKDF2_boring.swift similarity index 100% rename from Sources/_CryptoExtras/Key Derivation/PBKDF2/BoringSSL/PBKDF2_boring.swift rename to Sources/CryptoExtras/Key Derivation/PBKDF2/BoringSSL/PBKDF2_boring.swift diff --git a/Sources/_CryptoExtras/Key Derivation/PBKDF2/BoringSSL/PBKDF2_commoncrypto.swift b/Sources/CryptoExtras/Key Derivation/PBKDF2/BoringSSL/PBKDF2_commoncrypto.swift similarity index 100% rename from Sources/_CryptoExtras/Key Derivation/PBKDF2/BoringSSL/PBKDF2_commoncrypto.swift rename to Sources/CryptoExtras/Key Derivation/PBKDF2/BoringSSL/PBKDF2_commoncrypto.swift diff --git a/Sources/_CryptoExtras/Key Derivation/PBKDF2/PBKDF2.swift b/Sources/CryptoExtras/Key Derivation/PBKDF2/PBKDF2.swift similarity index 100% rename from Sources/_CryptoExtras/Key Derivation/PBKDF2/PBKDF2.swift rename to Sources/CryptoExtras/Key Derivation/PBKDF2/PBKDF2.swift diff --git a/Sources/_CryptoExtras/Key Derivation/Scrypt/BoringSSL/Scrypt_boring.swift b/Sources/CryptoExtras/Key Derivation/Scrypt/BoringSSL/Scrypt_boring.swift similarity index 100% rename from Sources/_CryptoExtras/Key Derivation/Scrypt/BoringSSL/Scrypt_boring.swift rename to Sources/CryptoExtras/Key Derivation/Scrypt/BoringSSL/Scrypt_boring.swift diff --git a/Sources/_CryptoExtras/Key Derivation/Scrypt/Scrypt.swift b/Sources/CryptoExtras/Key Derivation/Scrypt/Scrypt.swift similarity index 100% rename from Sources/_CryptoExtras/Key Derivation/Scrypt/Scrypt.swift rename to Sources/CryptoExtras/Key Derivation/Scrypt/Scrypt.swift diff --git a/Sources/_CryptoExtras/OPRFs/OPRF.swift b/Sources/CryptoExtras/OPRFs/OPRF.swift similarity index 100% rename from Sources/_CryptoExtras/OPRFs/OPRF.swift rename to Sources/CryptoExtras/OPRFs/OPRF.swift diff --git a/Sources/_CryptoExtras/OPRFs/OPRFClient.swift b/Sources/CryptoExtras/OPRFs/OPRFClient.swift similarity index 100% rename from Sources/_CryptoExtras/OPRFs/OPRFClient.swift rename to Sources/CryptoExtras/OPRFs/OPRFClient.swift diff --git a/Sources/_CryptoExtras/OPRFs/OPRFServer.swift b/Sources/CryptoExtras/OPRFs/OPRFServer.swift similarity index 100% rename from Sources/_CryptoExtras/OPRFs/OPRFServer.swift rename to Sources/CryptoExtras/OPRFs/OPRFServer.swift diff --git a/Sources/_CryptoExtras/OPRFs/VOPRF+API.swift b/Sources/CryptoExtras/OPRFs/VOPRF+API.swift similarity index 100% rename from Sources/_CryptoExtras/OPRFs/VOPRF+API.swift rename to Sources/CryptoExtras/OPRFs/VOPRF+API.swift diff --git a/Sources/_CryptoExtras/OPRFs/VOPRFClient.swift b/Sources/CryptoExtras/OPRFs/VOPRFClient.swift similarity index 100% rename from Sources/_CryptoExtras/OPRFs/VOPRFClient.swift rename to Sources/CryptoExtras/OPRFs/VOPRFClient.swift diff --git a/Sources/_CryptoExtras/OPRFs/VOPRFServer.swift b/Sources/CryptoExtras/OPRFs/VOPRFServer.swift similarity index 100% rename from Sources/_CryptoExtras/OPRFs/VOPRFServer.swift rename to Sources/CryptoExtras/OPRFs/VOPRFServer.swift diff --git a/Sources/_CryptoExtras/PrivacyInfo.xcprivacy b/Sources/CryptoExtras/PrivacyInfo.xcprivacy similarity index 100% rename from Sources/_CryptoExtras/PrivacyInfo.xcprivacy rename to Sources/CryptoExtras/PrivacyInfo.xcprivacy diff --git a/Sources/_CryptoExtras/RSA/RSA+BlindSigning.swift b/Sources/CryptoExtras/RSA/RSA+BlindSigning.swift similarity index 100% rename from Sources/_CryptoExtras/RSA/RSA+BlindSigning.swift rename to Sources/CryptoExtras/RSA/RSA+BlindSigning.swift diff --git a/Sources/_CryptoExtras/RSA/RSA.swift b/Sources/CryptoExtras/RSA/RSA.swift similarity index 100% rename from Sources/_CryptoExtras/RSA/RSA.swift rename to Sources/CryptoExtras/RSA/RSA.swift diff --git a/Sources/_CryptoExtras/RSA/RSA_boring.swift b/Sources/CryptoExtras/RSA/RSA_boring.swift similarity index 100% rename from Sources/_CryptoExtras/RSA/RSA_boring.swift rename to Sources/CryptoExtras/RSA/RSA_boring.swift diff --git a/Sources/_CryptoExtras/Reexport.swift b/Sources/CryptoExtras/Reexport.swift similarity index 100% rename from Sources/_CryptoExtras/Reexport.swift rename to Sources/CryptoExtras/Reexport.swift diff --git a/Sources/_CryptoExtras/Util/BoringSSLHelpers.swift b/Sources/CryptoExtras/Util/BoringSSLHelpers.swift similarity index 100% rename from Sources/_CryptoExtras/Util/BoringSSLHelpers.swift rename to Sources/CryptoExtras/Util/BoringSSLHelpers.swift diff --git a/Sources/_CryptoExtras/Util/CryptoKitErrors_boring.swift b/Sources/CryptoExtras/Util/CryptoKitErrors_boring.swift similarity index 100% rename from Sources/_CryptoExtras/Util/CryptoKitErrors_boring.swift rename to Sources/CryptoExtras/Util/CryptoKitErrors_boring.swift diff --git a/Sources/_CryptoExtras/Util/Data+Extensions.swift b/Sources/CryptoExtras/Util/Data+Extensions.swift similarity index 100% rename from Sources/_CryptoExtras/Util/Data+Extensions.swift rename to Sources/CryptoExtras/Util/Data+Extensions.swift diff --git a/Sources/_CryptoExtras/Util/DigestType.swift b/Sources/CryptoExtras/Util/DigestType.swift similarity index 100% rename from Sources/_CryptoExtras/Util/DigestType.swift rename to Sources/CryptoExtras/Util/DigestType.swift diff --git a/Sources/_CryptoExtras/Util/Error.swift b/Sources/CryptoExtras/Util/Error.swift similarity index 100% rename from Sources/_CryptoExtras/Util/Error.swift rename to Sources/CryptoExtras/Util/Error.swift diff --git a/Sources/_CryptoExtras/Util/I2OSP.swift b/Sources/CryptoExtras/Util/I2OSP.swift similarity index 100% rename from Sources/_CryptoExtras/Util/I2OSP.swift rename to Sources/CryptoExtras/Util/I2OSP.swift diff --git a/Sources/_CryptoExtras/Util/IntegerEncoding.swift b/Sources/CryptoExtras/Util/IntegerEncoding.swift similarity index 100% rename from Sources/_CryptoExtras/Util/IntegerEncoding.swift rename to Sources/CryptoExtras/Util/IntegerEncoding.swift diff --git a/Sources/_CryptoExtras/Util/PEMDocument.swift b/Sources/CryptoExtras/Util/PEMDocument.swift similarity index 100% rename from Sources/_CryptoExtras/Util/PEMDocument.swift rename to Sources/CryptoExtras/Util/PEMDocument.swift diff --git a/Sources/_CryptoExtras/Util/PrettyBytes.swift b/Sources/CryptoExtras/Util/PrettyBytes.swift similarity index 100% rename from Sources/_CryptoExtras/Util/PrettyBytes.swift rename to Sources/CryptoExtras/Util/PrettyBytes.swift diff --git a/Sources/_CryptoExtras/Util/SubjectPublicKeyInfo.swift b/Sources/CryptoExtras/Util/SubjectPublicKeyInfo.swift similarity index 100% rename from Sources/_CryptoExtras/Util/SubjectPublicKeyInfo.swift rename to Sources/CryptoExtras/Util/SubjectPublicKeyInfo.swift diff --git a/Sources/_CryptoExtras/Util/ThreadSpecific/ThreadOps.swift b/Sources/CryptoExtras/Util/ThreadSpecific/ThreadOps.swift similarity index 100% rename from Sources/_CryptoExtras/Util/ThreadSpecific/ThreadOps.swift rename to Sources/CryptoExtras/Util/ThreadSpecific/ThreadOps.swift diff --git a/Sources/_CryptoExtras/Util/ThreadSpecific/ThreadPosix.swift b/Sources/CryptoExtras/Util/ThreadSpecific/ThreadPosix.swift similarity index 100% rename from Sources/_CryptoExtras/Util/ThreadSpecific/ThreadPosix.swift rename to Sources/CryptoExtras/Util/ThreadSpecific/ThreadPosix.swift diff --git a/Sources/_CryptoExtras/Util/ThreadSpecific/ThreadSpecific.swift b/Sources/CryptoExtras/Util/ThreadSpecific/ThreadSpecific.swift similarity index 100% rename from Sources/_CryptoExtras/Util/ThreadSpecific/ThreadSpecific.swift rename to Sources/CryptoExtras/Util/ThreadSpecific/ThreadSpecific.swift diff --git a/Sources/_CryptoExtras/Util/ThreadSpecific/ThreadWindows.swift b/Sources/CryptoExtras/Util/ThreadSpecific/ThreadWindows.swift similarity index 100% rename from Sources/_CryptoExtras/Util/ThreadSpecific/ThreadWindows.swift rename to Sources/CryptoExtras/Util/ThreadSpecific/ThreadWindows.swift diff --git a/Sources/_CryptoExtras/ZKPs/DLEQ.swift b/Sources/CryptoExtras/ZKPs/DLEQ.swift similarity index 100% rename from Sources/_CryptoExtras/ZKPs/DLEQ.swift rename to Sources/CryptoExtras/ZKPs/DLEQ.swift diff --git a/Sources/_CryptoExtras/ZKPs/Prover.swift b/Sources/CryptoExtras/ZKPs/Prover.swift similarity index 100% rename from Sources/_CryptoExtras/ZKPs/Prover.swift rename to Sources/CryptoExtras/ZKPs/Prover.swift diff --git a/Sources/_CryptoExtras/ZKPs/Verifier.swift b/Sources/CryptoExtras/ZKPs/Verifier.swift similarity index 100% rename from Sources/_CryptoExtras/ZKPs/Verifier.swift rename to Sources/CryptoExtras/ZKPs/Verifier.swift diff --git a/Sources/_CryptoExtras/ZKPs/ZKPToolbox.swift b/Sources/CryptoExtras/ZKPs/ZKPToolbox.swift similarity index 100% rename from Sources/_CryptoExtras/ZKPs/ZKPToolbox.swift rename to Sources/CryptoExtras/ZKPs/ZKPToolbox.swift diff --git a/Sources/_CryptoExtras/Exports.swift b/Sources/_CryptoExtras/Exports.swift new file mode 100644 index 000000000..8423e7c02 --- /dev/null +++ b/Sources/_CryptoExtras/Exports.swift @@ -0,0 +1,15 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2019 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +@_exported import CryptoExtras diff --git a/Tests/_CryptoExtrasTests/AES Block Function Tests.swift b/Tests/CryptoExtrasTests/AES Block Function Tests.swift similarity index 99% rename from Tests/_CryptoExtrasTests/AES Block Function Tests.swift rename to Tests/CryptoExtrasTests/AES Block Function Tests.swift index 926cc04fc..f895a23c1 100644 --- a/Tests/_CryptoExtrasTests/AES Block Function Tests.swift +++ b/Tests/CryptoExtrasTests/AES Block Function Tests.swift @@ -18,7 +18,7 @@ import Foundation #endif import XCTest import Crypto -import _CryptoExtras +import CryptoExtras final class AESBlockFunctionTests: XCTestCase { static let nistPlaintextChunks: [[UInt8]] = [ diff --git a/Tests/_CryptoExtrasTests/AES-GCM-SIV-Runner.swift b/Tests/CryptoExtrasTests/AES-GCM-SIV-Runner.swift similarity index 99% rename from Tests/_CryptoExtrasTests/AES-GCM-SIV-Runner.swift rename to Tests/CryptoExtrasTests/AES-GCM-SIV-Runner.swift index 3d5ddea5b..8f3c68880 100644 --- a/Tests/_CryptoExtrasTests/AES-GCM-SIV-Runner.swift +++ b/Tests/CryptoExtrasTests/AES-GCM-SIV-Runner.swift @@ -18,7 +18,7 @@ import Foundation #endif import XCTest import Crypto -import _CryptoExtras +import CryptoExtras struct AEADTestGroup: Codable { let ivSize: Int diff --git a/Tests/_CryptoExtrasTests/AES_CBCTests.swift b/Tests/CryptoExtrasTests/AES_CBCTests.swift similarity index 99% rename from Tests/_CryptoExtrasTests/AES_CBCTests.swift rename to Tests/CryptoExtrasTests/AES_CBCTests.swift index c2a9a5eed..11fa7ec45 100644 --- a/Tests/_CryptoExtrasTests/AES_CBCTests.swift +++ b/Tests/CryptoExtrasTests/AES_CBCTests.swift @@ -18,7 +18,7 @@ import FoundationEssentials #else import Foundation #endif -import _CryptoExtras +import CryptoExtras import XCTest final class CBCTests: XCTestCase { @@ -162,7 +162,7 @@ final class CBCTests: XCTestCase { } } } - + func testToDataConversion() throws { let randomBytes = (0..<16).map { _ in UInt8.random(in: UInt8.min...UInt8.max) } let dataIn = Data(randomBytes) diff --git a/Tests/_CryptoExtrasTests/AES_CFBTests.swift b/Tests/CryptoExtrasTests/AES_CFBTests.swift similarity index 99% rename from Tests/_CryptoExtrasTests/AES_CFBTests.swift rename to Tests/CryptoExtrasTests/AES_CFBTests.swift index 8f23bc6d9..207a4d33e 100644 --- a/Tests/_CryptoExtrasTests/AES_CFBTests.swift +++ b/Tests/CryptoExtrasTests/AES_CFBTests.swift @@ -14,7 +14,7 @@ import Crypto import CryptoBoringWrapper -@testable import _CryptoExtras +@testable import CryptoExtras import XCTest final class AES_CFBTests: XCTestCase { diff --git a/Tests/_CryptoExtrasTests/AES_CTRTests.swift b/Tests/CryptoExtrasTests/AES_CTRTests.swift similarity index 99% rename from Tests/_CryptoExtrasTests/AES_CTRTests.swift rename to Tests/CryptoExtrasTests/AES_CTRTests.swift index 2206967f9..b2842a242 100644 --- a/Tests/_CryptoExtrasTests/AES_CTRTests.swift +++ b/Tests/CryptoExtrasTests/AES_CTRTests.swift @@ -18,7 +18,7 @@ import FoundationEssentials #else import Foundation #endif -@testable import _CryptoExtras +@testable import CryptoExtras import XCTest final class AESCTRTests: XCTestCase { diff --git a/Tests/_CryptoExtrasTests/ARC/ARCAPITests.swift b/Tests/CryptoExtrasTests/ARC/ARCAPITests.swift similarity index 99% rename from Tests/_CryptoExtrasTests/ARC/ARCAPITests.swift rename to Tests/CryptoExtrasTests/ARC/ARCAPITests.swift index 2a6f0f88b..9e71f6279 100644 --- a/Tests/_CryptoExtrasTests/ARC/ARCAPITests.swift +++ b/Tests/CryptoExtrasTests/ARC/ARCAPITests.swift @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// import Crypto -@testable import _CryptoExtras +@testable import CryptoExtras import XCTest @available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) diff --git a/Tests/_CryptoExtrasTests/ARC/ARCEncodingTests.swift b/Tests/CryptoExtrasTests/ARC/ARCEncodingTests.swift similarity index 99% rename from Tests/_CryptoExtrasTests/ARC/ARCEncodingTests.swift rename to Tests/CryptoExtrasTests/ARC/ARCEncodingTests.swift index c65a6aa24..e9516c5ec 100644 --- a/Tests/_CryptoExtrasTests/ARC/ARCEncodingTests.swift +++ b/Tests/CryptoExtrasTests/ARC/ARCEncodingTests.swift @@ -11,7 +11,7 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// -@testable import _CryptoExtras +@testable import CryptoExtras import XCTest import Crypto diff --git a/Tests/_CryptoExtrasTests/ARC/ARCPublicAPITests.swift b/Tests/CryptoExtrasTests/ARC/ARCPublicAPITests.swift similarity index 98% rename from Tests/_CryptoExtrasTests/ARC/ARCPublicAPITests.swift rename to Tests/CryptoExtrasTests/ARC/ARCPublicAPITests.swift index 411e1066c..a54b4a11b 100644 --- a/Tests/_CryptoExtrasTests/ARC/ARCPublicAPITests.swift +++ b/Tests/CryptoExtrasTests/ARC/ARCPublicAPITests.swift @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// import Crypto -import _CryptoExtras // NOTE: No @testable import, because we want to test the public API. +import CryptoExtras // NOTE: No @testable import, because we want to test the public API. import XCTest @available(iOS 16.0, macOS 13.0, watchOS 9.0, tvOS 16.0, macCatalyst 16.0, visionOS 2.0, *) diff --git a/Tests/_CryptoExtrasTests/ARC/ARCTestVectors.swift b/Tests/CryptoExtrasTests/ARC/ARCTestVectors.swift similarity index 99% rename from Tests/_CryptoExtrasTests/ARC/ARCTestVectors.swift rename to Tests/CryptoExtrasTests/ARC/ARCTestVectors.swift index b8b43556d..1dc00aed7 100644 --- a/Tests/_CryptoExtrasTests/ARC/ARCTestVectors.swift +++ b/Tests/CryptoExtrasTests/ARC/ARCTestVectors.swift @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// import Crypto -@testable import _CryptoExtras +@testable import CryptoExtras import XCTest let ARCEncodedTestVector = """ diff --git a/Tests/_CryptoExtrasTests/ARC/ARCTests.swift b/Tests/CryptoExtrasTests/ARC/ARCTests.swift similarity index 99% rename from Tests/_CryptoExtrasTests/ARC/ARCTests.swift rename to Tests/CryptoExtrasTests/ARC/ARCTests.swift index d2c4dd8bd..5db48770b 100644 --- a/Tests/_CryptoExtrasTests/ARC/ARCTests.swift +++ b/Tests/CryptoExtrasTests/ARC/ARCTests.swift @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// import Crypto -@testable import _CryptoExtras +@testable import CryptoExtras import XCTest @available(macOS 10.15, iOS 13.2, tvOS 13.2, watchOS 6.1, macCatalyst 13.2, visionOS 1.2, *) diff --git a/Tests/_CryptoExtrasTests/CMACTests.swift b/Tests/CryptoExtrasTests/CMACTests.swift similarity index 99% rename from Tests/_CryptoExtrasTests/CMACTests.swift rename to Tests/CryptoExtrasTests/CMACTests.swift index b33f13c84..386d906ec 100644 --- a/Tests/_CryptoExtrasTests/CMACTests.swift +++ b/Tests/CryptoExtrasTests/CMACTests.swift @@ -12,9 +12,9 @@ // //===----------------------------------------------------------------------===// import Crypto +import CryptoExtras import Foundation import XCTest -import _CryptoExtras final class CMACTests: XCTestCase { // Borrowed from CryptoKit diff --git a/Tests/_CryptoExtrasTests/ChaCha20CTRTests.swift b/Tests/CryptoExtrasTests/ChaCha20CTRTests.swift similarity index 99% rename from Tests/_CryptoExtrasTests/ChaCha20CTRTests.swift rename to Tests/CryptoExtrasTests/ChaCha20CTRTests.swift index fde4a79fc..175645680 100644 --- a/Tests/_CryptoExtrasTests/ChaCha20CTRTests.swift +++ b/Tests/CryptoExtrasTests/ChaCha20CTRTests.swift @@ -18,7 +18,7 @@ import Foundation #endif import XCTest import Crypto -import _CryptoExtras +import CryptoExtras class ChaCha20CTRTests: XCTestCase { diff --git a/Tests/_CryptoExtrasTests/ECToolbox/BoringSSL/ECToolboxBoringSSLTests.swift b/Tests/CryptoExtrasTests/ECToolbox/BoringSSL/ECToolboxBoringSSLTests.swift similarity index 98% rename from Tests/_CryptoExtrasTests/ECToolbox/BoringSSL/ECToolboxBoringSSLTests.swift rename to Tests/CryptoExtrasTests/ECToolbox/BoringSSL/ECToolboxBoringSSLTests.swift index 57d0eb540..0bb98375c 100644 --- a/Tests/_CryptoExtrasTests/ECToolbox/BoringSSL/ECToolboxBoringSSLTests.swift +++ b/Tests/CryptoExtrasTests/ECToolbox/BoringSSL/ECToolboxBoringSSLTests.swift @@ -17,10 +17,10 @@ import XCTest #if !canImport(Darwin) || canImport(CryptoKit, _version: 241.100.42) // Corresponds to the CryptoKit in XCode 16.3, which has Sendable annotations import Crypto -@testable import _CryptoExtras +@testable import CryptoExtras #else @preconcurrency import Crypto -@testable import _CryptoExtras +@testable import CryptoExtras #endif final class ECToolboxBoringSSLTests: XCTestCase { diff --git a/Tests/_CryptoExtrasTests/ECToolbox/H2CVectors/P256_XMD-SHA-256_SSWU_RO_.json b/Tests/CryptoExtrasTests/ECToolbox/H2CVectors/P256_XMD-SHA-256_SSWU_RO_.json similarity index 100% rename from Tests/_CryptoExtrasTests/ECToolbox/H2CVectors/P256_XMD-SHA-256_SSWU_RO_.json rename to Tests/CryptoExtrasTests/ECToolbox/H2CVectors/P256_XMD-SHA-256_SSWU_RO_.json diff --git a/Tests/_CryptoExtrasTests/ECToolbox/H2CVectors/P384_XMD-SHA-384_SSWU_RO_.json b/Tests/CryptoExtrasTests/ECToolbox/H2CVectors/P384_XMD-SHA-384_SSWU_RO_.json similarity index 100% rename from Tests/_CryptoExtrasTests/ECToolbox/H2CVectors/P384_XMD-SHA-384_SSWU_RO_.json rename to Tests/CryptoExtrasTests/ECToolbox/H2CVectors/P384_XMD-SHA-384_SSWU_RO_.json diff --git a/Tests/_CryptoExtrasTests/ECToolbox/HashToCurveTests.swift b/Tests/CryptoExtrasTests/ECToolbox/HashToCurveTests.swift similarity index 98% rename from Tests/_CryptoExtrasTests/ECToolbox/HashToCurveTests.swift rename to Tests/CryptoExtrasTests/ECToolbox/HashToCurveTests.swift index 88efc4e3a..4e1179a54 100644 --- a/Tests/_CryptoExtrasTests/ECToolbox/HashToCurveTests.swift +++ b/Tests/CryptoExtrasTests/ECToolbox/HashToCurveTests.swift @@ -12,13 +12,13 @@ // //===----------------------------------------------------------------------===// import Crypto -@testable import _CryptoExtras +@testable import CryptoExtras import XCTest struct HashToCurveTestVectorCurvePoint: Codable { let x: String let y: String - + var rawRepresentation: Data { return try! Data(hexString: String(x.dropFirst(2))) + Data(hexString: String(y.dropFirst(2))) } @@ -44,28 +44,28 @@ class HashToCurveTests: XCTestCase { let bundle = Bundle(for: type(of: self)) #endif let fileURL = bundle.url(forResource: file, withExtension: "json") - + let data = try Data(contentsOf: fileURL!) let decoder = JSONDecoder() let testVectorFile = try decoder.decode(HashToCurveTestVectorFile.self, from: data) - + let dst = testVectorFile.dst - + for vector in testVectorFile.vectors { let msg = vector.msg.data(using: .ascii)! - + let point = h2c.hashToGroup(msg, domainSeparationString: Data(dst.utf8)) - + XCTAssert(point.oprfRepresentation.hexString.dropFirst(2) == vector.P.x.dropFirst(2)) } } - + func testVectors() throws { try testVector(vectorFileName: "P256_XMD-SHA-256_SSWU_RO_", with: HashToCurveImpl.self) try testVector(vectorFileName: "P384_XMD-SHA-384_SSWU_RO_", with: HashToCurveImpl.self) // try testVector(vectorFileName: "P521_XMD-SHA-512_SSWU_RO_", with: HashToCurveImpl.self) } - + func testH2F() throws { let data = try! Data(hexString: "436f6e746578742d564f50524630372d00000300097465737420696e666f") let dst = try! Data(hexString: "48617368546f5363616c61722d564f50524630372d000003") diff --git a/Tests/_CryptoExtrasTests/MLDSATests.swift b/Tests/CryptoExtrasTests/MLDSATests.swift similarity index 99% rename from Tests/_CryptoExtrasTests/MLDSATests.swift rename to Tests/CryptoExtrasTests/MLDSATests.swift index 87e2b765d..cbf49a809 100644 --- a/Tests/_CryptoExtrasTests/MLDSATests.swift +++ b/Tests/CryptoExtrasTests/MLDSATests.swift @@ -16,7 +16,7 @@ import XCTest -@testable import _CryptoExtras +@testable import CryptoExtras final class MLDSATests: XCTestCase { func testMLDSA65Signing() throws { @@ -232,7 +232,7 @@ final class MLDSATests: XCTestCase { for _ in 0..<2 { fileURL.deleteLastPathComponent() } - fileURL = fileURL.appendingPathComponent("_CryptoExtrasVectors", isDirectory: true) + fileURL = fileURL.appendingPathComponent("CryptoExtrasVectors", isDirectory: true) fileURL = fileURL.appendingPathComponent("\(jsonName).json", isDirectory: false) let data = try Data(contentsOf: fileURL) diff --git a/Tests/_CryptoExtrasTests/MLKEMTests.swift b/Tests/CryptoExtrasTests/MLKEMTests.swift similarity index 99% rename from Tests/_CryptoExtrasTests/MLKEMTests.swift rename to Tests/CryptoExtrasTests/MLKEMTests.swift index ae6351ca3..21fd730ee 100644 --- a/Tests/_CryptoExtrasTests/MLKEMTests.swift +++ b/Tests/CryptoExtrasTests/MLKEMTests.swift @@ -16,7 +16,7 @@ import Crypto import XCTest -@testable import _CryptoExtras +@testable import CryptoExtras final class MLKEMTests: XCTestCase { func testMLKEM768() throws { diff --git a/Tests/_CryptoExtrasTests/OPRFs/ECVOPRFTests.swift b/Tests/CryptoExtrasTests/OPRFs/ECVOPRFTests.swift similarity index 96% rename from Tests/_CryptoExtrasTests/OPRFs/ECVOPRFTests.swift rename to Tests/CryptoExtrasTests/OPRFs/ECVOPRFTests.swift index cb0c4216c..7fd919c49 100644 --- a/Tests/_CryptoExtrasTests/OPRFs/ECVOPRFTests.swift +++ b/Tests/CryptoExtrasTests/OPRFs/ECVOPRFTests.swift @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// import Crypto -@testable import _CryptoExtras +@testable import CryptoExtras import XCTest struct OPRFSuite: Codable { @@ -64,50 +64,50 @@ class ECVOPRFTests: XCTestCase { fatalError("Unknown mode") } } - + func testBaseSuite(suite: OPRFSuite, C: G.Type, v8DraftCompatible: Bool) throws { print("Testing \(suite.suiteName ?? suite.identifier!) in base mode.") - + let privateKey = try GroupImpl.Scalar(bytes: Data(hexString: suite.skSm)) let ciphersuite = OPRF.Ciphersuite(HashToCurveImpl.self) - + for vector in suite.vectors { if vector.Batch != 1 { continue } - + let client = OPRF.Client(mode: .base, ciphersuite: ciphersuite, v8CompatibilityMode: v8DraftCompatible) let blindTestVector = try GroupImpl.Scalar(bytes: Data(hexString: vector.Blind)) let input = try Data(hexString: vector.Input) - + let (blind, blindedElement) = client.blindMessage(input, blind: blindTestVector) - + XCTAssert(blindTestVector == blind) XCTAssert(blindedElement.oprfRepresentation.hexString == vector.BlindedElement) - + let server = OPRF.Server(mode: .base, ciphersuite: ciphersuite, privateKey: privateKey, v8CompatibilityMode: v8DraftCompatible) - + var info = Data() if vector.Info != nil { info = try Data(hexString: vector.Info!) } - + let evaluate = try server.evaluate(blindedElement: blindedElement, info: info) - + let evaluatedElementTv = try GroupImpl.Element(oprfRepresentation: Data(hexString: vector.EvaluationElement)) XCTAssert(evaluate.0 == evaluatedElementTv) - + let finalized = try client.finalize(message: input, info: info, blind: blind, evaluatedElement: evaluate.0) - + XCTAssert(finalized.hexString == vector.Output) XCTAssert(try server.verifyFinalize(msg: input, output: finalized, info: info)) } } - + func testVerifiableSuite(suite: OPRFSuite, C: G.Type, v8DraftCompatible: Bool, mode: OPRF.Mode) throws { print("Testing \(suite.suiteName ?? suite.identifier!) in \(mode) mode.") - + let privateKey = try GroupImpl.Scalar(bytes: Data(hexString: suite.skSm)) let ciphersuite = OPRF.Ciphersuite(HashToCurveImpl.self) @@ -119,23 +119,23 @@ class ECVOPRFTests: XCTestCase { let client = try! OPRF.VerifiableClient(ciphersuite: ciphersuite, v8CompatibilityMode: v8DraftCompatible, mode: mode) let blindTestVector = try GroupImpl.Scalar(bytes: Data(hexString: vector.Blind)) let input = try Data(hexString: vector.Input) - + let (blind, blindedElement) = client.blindMessage(input, blind: blindTestVector) - + XCTAssert(blindTestVector == blind) XCTAssert(blindedElement.oprfRepresentation.hexString == vector.BlindedElement) - + let server = try! OPRF.VerifiableServer(ciphersuite: ciphersuite, privateKey: privateKey, v8CompatibilityMode: v8DraftCompatible, mode: mode) let proofBlind = try GroupImpl.Scalar(bytes: Data(hexString: vector.Proof!.r)) - + var info: Data? if (vector.Info?.count ?? 0) > 0 { info = try Data(hexString: vector.Info!) } let evaluate = try server.evaluate(blindedElement: blindedElement, info: info, proofScalar: proofBlind) - + let evaluatedElementTv = try GroupImpl.Element(oprfRepresentation: Data(hexString: vector.EvaluationElement)) XCTAssert(evaluate.0 == evaluatedElementTv) - + let proof_tv = vector.Proof!.proof let c_tv = try GroupImpl.Scalar(bytes: Data(hexString: String(proof_tv.prefix(proof_tv.count / 2)))) let s_tv = try GroupImpl.Scalar(bytes: Data(hexString: String(proof_tv.suffix(proof_tv.count / 2)))) @@ -169,7 +169,7 @@ class ECVOPRFTests: XCTestCase { } } } - + func testVectors() throws { print("Testing VOPRF Draft8 vectors.") try testVectors(filename: "OPRFVectors-VOPRFDraft8", v8DraftCompatible: true) @@ -178,7 +178,7 @@ class ECVOPRFTests: XCTestCase { print("Testing VOPRF edge case vectors.") try testVectors(filename: "OPRFVectors-edgecases", v8DraftCompatible: false) } - + func testVectors(filename: String, v8DraftCompatible: Bool) throws { #if CRYPTO_IN_SWIFTPM let bundle = Bundle.module @@ -187,11 +187,11 @@ class ECVOPRFTests: XCTestCase { #endif let fileURL = bundle.url(forResource: filename, withExtension: "json") - + let data = try Data(contentsOf: fileURL!) let decoder = JSONDecoder() let suites = try decoder.decode([OPRFSuite].self, from: data) - + if v8DraftCompatible { for suite in suites { switch (suite.suiteID, suite.mode) { @@ -204,7 +204,7 @@ class ECVOPRFTests: XCTestCase { // case (OPRF.Ciphersuite(HashToCurveImpl.self).suiteID, let modeValue): do { // try testSuite(suite: suite, C: P521.self, modeValue: modeValue, v8DraftCompatible: v8DraftCompatible) // } - + default: print("Unsupported Ciphersuite: \(suite.suiteName ?? suite.identifier!)") } @@ -221,67 +221,67 @@ class ECVOPRFTests: XCTestCase { // case (OPRF.Ciphersuite(HashToCurveImpl.self).stringIdentifier, let modeValue): do { // try testSuite(suite: suite, C: P521.self, modeValue: modeValue, v8DraftCompatible: v8DraftCompatible) // } - + default: print("Unsupported Ciphersuite: \(suite.suiteName ?? suite.identifier!)") } } } } - + func testDistributivity() throws { let r = GroupImpl.Scalar.random - + let a = GroupImpl.Scalar.random let b = GroupImpl.Scalar.random - + let ab = (a + b) let ar = a * r let br = b * r - + XCTAssert(ab - b == a) XCTAssert(ab - a == b) - + let arbr = (ab) * r - + XCTAssert(arbr - br == ar) XCTAssert(arbr - ar == br) } - + func testMath() throws { let r = GroupImpl.Scalar.random let k = GroupImpl.Scalar.random let c = GroupImpl.Scalar.random - + let A = GroupImpl.Element.generator let B = k * A - + let m = GroupImpl.Scalar.random let z = k * m - + let t2 = r * A let t3 = r * m - + let s = (r - c * k) let t2_recontructed = (s * A) + (c * B) let t3_reconstructed = ((s * m) + (c * z)) - + XCTAssert(t2 == t2_recontructed) XCTAssert(t3.rawRepresentation == t3_reconstructed.rawRepresentation) } - + func testDLEQProver() throws { let k = GroupImpl.Scalar.random let A = GroupImpl.Element.generator let B = k * A - + let C = GroupImpl.Element.random let D = k * C - + let CDs = [(C: C, D: D)] - + let proof = try DLEQ>.proveEquivalenceBetween(k: k, A: A, B: B, CDs: CDs, dst: Data(), proofScalar: .random, v8CompatibilityMode: false) - + XCTAssert(try DLEQ>.verifyProof(A: A, B: B, CDs: CDs, proof: proof, dst: Data(), v8CompatibilityMode: false)) } } diff --git a/Tests/_CryptoExtrasTests/OPRFs/OPRFVectors/OPRFVectors-VOPRFDraft19.json b/Tests/CryptoExtrasTests/OPRFs/OPRFVectors/OPRFVectors-VOPRFDraft19.json similarity index 100% rename from Tests/_CryptoExtrasTests/OPRFs/OPRFVectors/OPRFVectors-VOPRFDraft19.json rename to Tests/CryptoExtrasTests/OPRFs/OPRFVectors/OPRFVectors-VOPRFDraft19.json diff --git a/Tests/_CryptoExtrasTests/OPRFs/OPRFVectors/OPRFVectors-VOPRFDraft8.json b/Tests/CryptoExtrasTests/OPRFs/OPRFVectors/OPRFVectors-VOPRFDraft8.json similarity index 100% rename from Tests/_CryptoExtrasTests/OPRFs/OPRFVectors/OPRFVectors-VOPRFDraft8.json rename to Tests/CryptoExtrasTests/OPRFs/OPRFVectors/OPRFVectors-VOPRFDraft8.json diff --git a/Tests/_CryptoExtrasTests/OPRFs/OPRFVectors/OPRFVectors-edgecases.json b/Tests/CryptoExtrasTests/OPRFs/OPRFVectors/OPRFVectors-edgecases.json similarity index 100% rename from Tests/_CryptoExtrasTests/OPRFs/OPRFVectors/OPRFVectors-edgecases.json rename to Tests/CryptoExtrasTests/OPRFs/OPRFVectors/OPRFVectors-edgecases.json diff --git a/Tests/_CryptoExtrasTests/OPRFs/VOPRFAPITests.swift b/Tests/CryptoExtrasTests/OPRFs/VOPRFAPITests.swift similarity index 97% rename from Tests/_CryptoExtrasTests/OPRFs/VOPRFAPITests.swift rename to Tests/CryptoExtrasTests/OPRFs/VOPRFAPITests.swift index cf4582c23..9a34599bd 100644 --- a/Tests/_CryptoExtrasTests/OPRFs/VOPRFAPITests.swift +++ b/Tests/CryptoExtrasTests/OPRFs/VOPRFAPITests.swift @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// import Crypto -@testable import _CryptoExtras // NOTE: @testable import, to inject fixed values from test vectors. +@testable import CryptoExtras // NOTE: @testable import, to inject fixed values from test vectors. import XCTest extension OPRFSuite { diff --git a/Tests/_CryptoExtrasTests/OPRFs/VOPRFPublicAPITests.swift b/Tests/CryptoExtrasTests/OPRFs/VOPRFPublicAPITests.swift similarity index 97% rename from Tests/_CryptoExtrasTests/OPRFs/VOPRFPublicAPITests.swift rename to Tests/CryptoExtrasTests/OPRFs/VOPRFPublicAPITests.swift index 1ec31835a..0fae0be60 100644 --- a/Tests/_CryptoExtrasTests/OPRFs/VOPRFPublicAPITests.swift +++ b/Tests/CryptoExtrasTests/OPRFs/VOPRFPublicAPITests.swift @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// import Crypto -import _CryptoExtras // NOTE: No @testable import, because we want to test the public API. +import CryptoExtras // NOTE: No @testable import, because we want to test the public API. import XCTest @available(macOS 13.0, iOS 16.0, tvOS 16.0, watchOS 9.0, *) diff --git a/Tests/_CryptoExtrasTests/PBKDF2Tests.swift b/Tests/CryptoExtrasTests/PBKDF2Tests.swift similarity index 96% rename from Tests/_CryptoExtrasTests/PBKDF2Tests.swift rename to Tests/CryptoExtrasTests/PBKDF2Tests.swift index 7fae61a00..05b2fa3af 100644 --- a/Tests/_CryptoExtrasTests/PBKDF2Tests.swift +++ b/Tests/CryptoExtrasTests/PBKDF2Tests.swift @@ -13,7 +13,7 @@ //===----------------------------------------------------------------------===// import XCTest import Crypto -@testable import _CryptoExtras +@testable import CryptoExtras // Test Vectors are coming from https://tools.ietf.org/html/rfc6070 class PBKDF2Tests: XCTestCase { @@ -24,7 +24,7 @@ class PBKDF2Tests: XCTestCase { var rounds: Int var outputLength: Int var derivedKey: [UInt8] - + enum CodingKeys: String, CodingKey { case hash = "Hash" case inputSecret = "P" @@ -34,57 +34,57 @@ class PBKDF2Tests: XCTestCase { case derivedKey = "DK" } } - + func oneshotTesting(_ vector: RFCTestVector, hash: KDF.Insecure.PBKDF2.HashFunction) throws { let (contiguousInput, discontiguousInput) = vector.inputSecret.asDataProtocols() let (contiguousSalt, discontiguousSalt) = vector.salt.asDataProtocols() - + let DK1 = try KDF.Insecure.PBKDF2.deriveKey(from: contiguousInput, salt: contiguousSalt, using: hash, outputByteCount: vector.outputLength, unsafeUncheckedRounds: vector.rounds) - + let DK2 = try KDF.Insecure.PBKDF2.deriveKey(from: discontiguousInput, salt: contiguousSalt, using: hash, outputByteCount: vector.outputLength, unsafeUncheckedRounds: vector.rounds) - + let DK3 = try KDF.Insecure.PBKDF2.deriveKey(from: contiguousInput, salt: discontiguousSalt, using: hash, outputByteCount: vector.outputLength, unsafeUncheckedRounds: vector.rounds) - + let DK4 = try KDF.Insecure.PBKDF2.deriveKey(from: discontiguousInput, salt: discontiguousSalt, using: hash, outputByteCount: vector.outputLength, unsafeUncheckedRounds: vector.rounds) - + let expectedDK = SymmetricKey(data: vector.derivedKey) XCTAssertEqual(DK1, expectedDK) XCTAssertEqual(DK2, expectedDK) XCTAssertEqual(DK3, expectedDK) XCTAssertEqual(DK4, expectedDK) } - + func testRFCVector(_ vector: RFCTestVector, hash: KDF.Insecure.PBKDF2.HashFunction) throws { try oneshotTesting(vector, hash: hash) } - + func testRfcTestVectorsSHA1() throws { var decoder = try orFail { try RFCVectorDecoder(bundleType: self, fileName: "rfc-6070-PBKDF2-SHA1") } let vectors = try orFail { try decoder.decode([RFCTestVector].self) } - + for vector in vectors { precondition(vector.hash == "SHA-1") try orFail { try self.testRFCVector(vector, hash: .insecureSHA1) } } } - + func testRoundsParameterCheck() { let (contiguousInput, contiguousSalt) = (Data("password".utf8), Data("salt".utf8)) - + XCTAssertThrowsError(try KDF.Insecure.PBKDF2.deriveKey(from: contiguousInput, salt: contiguousSalt, using: .insecureSHA1, outputByteCount: 20, rounds: 209_999)) - + XCTAssertNoThrow(try KDF.Insecure.PBKDF2.deriveKey(from: contiguousInput, salt: contiguousSalt, using: .insecureSHA1, outputByteCount: 20, unsafeUncheckedRounds: 209_999)) - + XCTAssertNoThrow(try KDF.Insecure.PBKDF2.deriveKey(from: contiguousInput, salt: contiguousSalt, using: .insecureSHA1, outputByteCount: 20, rounds: 210_000)) } diff --git a/Tests/_CryptoExtrasTests/PKCS8DERRepresentationTests.swift b/Tests/CryptoExtrasTests/PKCS8DERRepresentationTests.swift similarity index 99% rename from Tests/_CryptoExtrasTests/PKCS8DERRepresentationTests.swift rename to Tests/CryptoExtrasTests/PKCS8DERRepresentationTests.swift index 1cc754c2d..f464e13bf 100644 --- a/Tests/_CryptoExtrasTests/PKCS8DERRepresentationTests.swift +++ b/Tests/CryptoExtrasTests/PKCS8DERRepresentationTests.swift @@ -16,7 +16,7 @@ import Crypto import Foundation import XCTest -@testable import _CryptoExtras +@testable import CryptoExtras final class PKCS8DERRepresentationTests: XCTestCase { func test_RSA() { diff --git a/Tests/_CryptoExtrasTests/ScryptTests.swift b/Tests/CryptoExtrasTests/ScryptTests.swift similarity index 97% rename from Tests/_CryptoExtrasTests/ScryptTests.swift rename to Tests/CryptoExtrasTests/ScryptTests.swift index 28f828812..40308dab2 100644 --- a/Tests/_CryptoExtrasTests/ScryptTests.swift +++ b/Tests/CryptoExtrasTests/ScryptTests.swift @@ -13,7 +13,7 @@ //===----------------------------------------------------------------------===// import XCTest import Crypto -@testable import _CryptoExtras +@testable import CryptoExtras // Test Vectors are coming from https://tools.ietf.org/html/rfc7914 class ScryptTests: XCTestCase { @@ -25,7 +25,7 @@ class ScryptTests: XCTestCase { var parallelism: Int var outputLength: Int var derivedKey: [UInt8] - + enum CodingKeys: String, CodingKey { case inputSecret = "P" case salt = "S" @@ -36,50 +36,50 @@ class ScryptTests: XCTestCase { case derivedKey = "DK" } } - + func oneshotTesting(_ vector: RFCTestVector) throws { let (contiguousInput, discontiguousInput) = vector.inputSecret.asDataProtocols() let (contiguousSalt, discontiguousSalt) = vector.salt.asDataProtocols() - + let DK1 = try KDF.Scrypt.deriveKey(from: contiguousInput, salt: contiguousSalt, outputByteCount: vector.outputLength, rounds: vector.rounds, blockSize: vector.blockSize, parallelism: vector.parallelism) - + let DK2 = try KDF.Scrypt.deriveKey(from: discontiguousInput, salt: contiguousSalt, outputByteCount: vector.outputLength, rounds: vector.rounds, blockSize: vector.blockSize, parallelism: vector.parallelism) - + let DK3 = try KDF.Scrypt.deriveKey(from: contiguousInput, salt: discontiguousSalt, outputByteCount: vector.outputLength, rounds: vector.rounds, blockSize: vector.blockSize, parallelism: vector.parallelism) - + let DK4 = try KDF.Scrypt.deriveKey(from: discontiguousInput, salt: discontiguousSalt, outputByteCount: vector.outputLength, rounds: vector.rounds, blockSize: vector.blockSize, parallelism: vector.parallelism) - + let expectedDK = SymmetricKey(data: vector.derivedKey) XCTAssertEqual(DK1, expectedDK) XCTAssertEqual(DK2, expectedDK) XCTAssertEqual(DK3, expectedDK) XCTAssertEqual(DK4, expectedDK) } - + func testRFCVector(_ vector: RFCTestVector) throws { try oneshotTesting(vector) } - + func testRfcTestVectors() throws { var decoder = try orFail { try RFCVectorDecoder(bundleType: self, fileName: "rfc-7914-scrypt") } let vectors = try orFail { try decoder.decode([RFCTestVector].self) } - + for vector in vectors { try orFail { try self.testRFCVector(vector) } } diff --git a/Tests/_CryptoExtrasTests/TestRSABlindSigning.swift b/Tests/CryptoExtrasTests/TestRSABlindSigning.swift similarity index 99% rename from Tests/_CryptoExtrasTests/TestRSABlindSigning.swift rename to Tests/CryptoExtrasTests/TestRSABlindSigning.swift index fb6a9c32e..ceaca2d71 100644 --- a/Tests/_CryptoExtrasTests/TestRSABlindSigning.swift +++ b/Tests/CryptoExtrasTests/TestRSABlindSigning.swift @@ -13,7 +13,7 @@ //===----------------------------------------------------------------------===// import XCTest import Crypto -@testable import _CryptoExtras +@testable import CryptoExtras struct RFC9474TestVector: Codable { var name, p, q, n, e, d, msg, msg_prefix, prepared_msg, salt, inv, blinded_msg, blind_sig, sig: String @@ -42,7 +42,7 @@ struct RFC9474TestVector: Codable { } static let allValues: [Self] = try! RFC9474TestVector.load(from: URL( - fileURLWithPath: "../_CryptoExtrasVectors/rfc9474.json", + fileURLWithPath: "../CryptoExtrasVectors/rfc9474.json", relativeTo: URL(fileURLWithPath: #filePath) )) } diff --git a/Tests/_CryptoExtrasTests/TestRSABlindSigningAPI.swift b/Tests/CryptoExtrasTests/TestRSABlindSigningAPI.swift similarity index 96% rename from Tests/_CryptoExtrasTests/TestRSABlindSigningAPI.swift rename to Tests/CryptoExtrasTests/TestRSABlindSigningAPI.swift index 413d1855f..506999347 100644 --- a/Tests/_CryptoExtrasTests/TestRSABlindSigningAPI.swift +++ b/Tests/CryptoExtrasTests/TestRSABlindSigningAPI.swift @@ -13,7 +13,7 @@ //===----------------------------------------------------------------------===// import XCTest import Crypto -import _CryptoExtras // NOTE: No @testable import, because we want to test the public API. +import CryptoExtras // NOTE: No @testable import, because we want to test the public API. final class TestRSABlindSigningAPI: XCTestCase { func testEndToEnd() throws { diff --git a/Tests/_CryptoExtrasTests/TestRSAEncryption.swift b/Tests/CryptoExtrasTests/TestRSAEncryption.swift similarity index 99% rename from Tests/_CryptoExtrasTests/TestRSAEncryption.swift rename to Tests/CryptoExtrasTests/TestRSAEncryption.swift index b6d45c3b6..9a6325fad 100644 --- a/Tests/_CryptoExtrasTests/TestRSAEncryption.swift +++ b/Tests/CryptoExtrasTests/TestRSAEncryption.swift @@ -18,10 +18,10 @@ import Foundation #endif import XCTest import Crypto -import _CryptoExtras +import CryptoExtras final class TestRSAEncryption: XCTestCase { - + func test_wycheproofOAEPVectors() throws { try wycheproofTest( jsonName: "rsa_oaep_misc_test", @@ -33,11 +33,11 @@ final class TestRSAEncryption: XCTestCase { jsonName: "rsa_oaep_2048_sha256_mgf1sha256_test", testFunction: self.testOAEPGroup) } - + private func testOAEPGroup(_ group: RSAEncryptionOAEPTestGroup) throws { let derPrivKey: _RSA.Encryption.PrivateKey let pemPrivKey: _RSA.Encryption.PrivateKey - + if group.keysize < 2048 { derPrivKey = try _RSA.Encryption.PrivateKey(unsafeDERRepresentation: group.privateKeyDerBytes) pemPrivKey = try _RSA.Encryption.PrivateKey(unsafePEMRepresentation: group.privateKeyPem) @@ -60,7 +60,7 @@ final class TestRSAEncryption: XCTestCase { // We currently only support SHA-1, SHA-256. return } - + for test in group.tests { guard test.label?.isEmpty ?? true else { // We currently have no support for OAEP labels. @@ -77,7 +77,7 @@ final class TestRSAEncryption: XCTestCase { } catch { valid = false } - + XCTAssertEqual(valid, test.expectedValidity, "test number \(test.tcId) failed, expected \(test.result) but got \(valid)") } } @@ -129,7 +129,7 @@ final class TestRSAEncryption: XCTestCase { XCTAssertEqual(Data(data), decrypted) } } - + func testGetKeyPrimitives() throws { for testVector in RFC9474TestVector.allValues { let n = try Data(hexString: testVector.n) diff --git a/Tests/_CryptoExtrasTests/TestRSASigning.swift b/Tests/CryptoExtrasTests/TestRSASigning.swift similarity index 99% rename from Tests/_CryptoExtrasTests/TestRSASigning.swift rename to Tests/CryptoExtrasTests/TestRSASigning.swift index 7bbb2cf1a..64ca65f75 100644 --- a/Tests/_CryptoExtrasTests/TestRSASigning.swift +++ b/Tests/CryptoExtrasTests/TestRSASigning.swift @@ -19,7 +19,7 @@ import Foundation import XCTest import Crypto import CryptoBoringWrapper -@testable import _CryptoExtras +@testable import CryptoExtras final class TestRSASigning: XCTestCase { @@ -76,7 +76,7 @@ final class TestRSASigning: XCTestCase { try wycheproofTest( jsonName: "rsa_signature_test", testFunction: self.testPKCS1Group) - + try wycheproofTest( jsonName: "rsa_signature_2048_sha256_test", testFunction: self.testPKCS1Group) @@ -130,10 +130,10 @@ final class TestRSASigning: XCTestCase { func test_wycheproofPrimitives() throws { try wycheproofTest( - jsonName: "rsa_oaep_2048_sha1_mgf1sha1_test", + jsonName: "rsa_oaep_2048_sha1_mgf1sha1_test", testFunction: self.testPrimeFactors) try wycheproofTest( - jsonName: "rsa_oaep_2048_sha256_mgf1sha256_test", + jsonName: "rsa_oaep_2048_sha256_mgf1sha256_test", testFunction: self.testPrimeFactors) } @@ -352,12 +352,12 @@ final class TestRSASigning: XCTestCase { (_RSA.Signing.PrivateKey(keySize: .bits4096), 4096), (_RSA.Signing.PrivateKey(unsafeKeySize: .init(bitCount: 1024)), 1024), ] - + for (key, size) in keysAndSizes { XCTAssertEqual(size, key.keySizeInBits) XCTAssertEqual(size, key.publicKey.keySizeInBits) } - + try XCTAssertThrowsError((_RSA.Signing.PrivateKey(keySize: .init(bitCount: 1024)), 1024)) } @@ -734,7 +734,7 @@ final class TestRSASigning: XCTestCase { K8TpFCFPBP/Yv1Kngovn4O1MskoxTQraRBDjfC6O7OfcSCSMuVgB0Oofcp9iQjLA HV3KOnbYqvzmFv7OWnAszkTh -----END PRIVATE KEY----- - + """ let key = try _RSA.Signing.PrivateKey(pemRepresentation: pemKey) @@ -803,7 +803,7 @@ final class TestRSASigning: XCTestCase { private func testPKCS1Group(_ group: RSAPKCS1TestGroup) throws { let derKey: _RSA.Signing.PublicKey let pemKey: _RSA.Signing.PublicKey - + if group.keysize < 2048 { derKey = try _RSA.Signing.PublicKey(unsafeDERRepresentation: group.keyDerBytes) pemKey = try _RSA.Signing.PublicKey(unsafePEMRepresentation: group.keyPem) diff --git a/Tests/_CryptoExtrasTests/Util/IntegerEncodingTests.swift b/Tests/CryptoExtrasTests/Util/IntegerEncodingTests.swift similarity index 99% rename from Tests/_CryptoExtrasTests/Util/IntegerEncodingTests.swift rename to Tests/CryptoExtrasTests/Util/IntegerEncodingTests.swift index 1d161300e..c90360dba 100644 --- a/Tests/_CryptoExtrasTests/Util/IntegerEncodingTests.swift +++ b/Tests/CryptoExtrasTests/Util/IntegerEncodingTests.swift @@ -11,7 +11,7 @@ // SPDX-License-Identifier: Apache-2.0 // //===----------------------------------------------------------------------===// -@testable import _CryptoExtras +@testable import CryptoExtras import XCTest final class IntegerEncodingTests: XCTestCase { diff --git a/Tests/_CryptoExtrasTests/Utils/BytesUtil.swift b/Tests/CryptoExtrasTests/Utils/BytesUtil.swift similarity index 100% rename from Tests/_CryptoExtrasTests/Utils/BytesUtil.swift rename to Tests/CryptoExtrasTests/Utils/BytesUtil.swift diff --git a/Tests/_CryptoExtrasTests/Utils/RFCVector.swift b/Tests/CryptoExtrasTests/Utils/RFCVector.swift similarity index 97% rename from Tests/_CryptoExtrasTests/Utils/RFCVector.swift rename to Tests/CryptoExtrasTests/Utils/RFCVector.swift index bc6748989..e7701f85d 100644 --- a/Tests/_CryptoExtrasTests/Utils/RFCVector.swift +++ b/Tests/CryptoExtrasTests/Utils/RFCVector.swift @@ -31,14 +31,14 @@ struct RFCVectorDecoder { } #if compiler(>=6.0) if #available(macOS 13, iOS 16, watchOS 9, tvOS 16, visionOS 1, macCatalyst 16, *) { - fileURL!.append(path: "_CryptoExtrasVectors", directoryHint: .isDirectory) + fileURL!.append(path: "CryptoExtrasVectors", directoryHint: .isDirectory) fileURL!.append(path: "\(fileName).txt", directoryHint: .notDirectory) } else { - fileURL! = fileURL!.appendingPathComponent("_CryptoExtrasVectors", isDirectory: true) + fileURL! = fileURL!.appendingPathComponent("CryptoExtrasVectors", isDirectory: true) fileURL! = fileURL!.appendingPathComponent("\(fileName).txt", isDirectory: false) } #else - fileURL! = fileURL!.appendingPathComponent("_CryptoExtrasVectors", isDirectory: true) + fileURL! = fileURL!.appendingPathComponent("CryptoExtrasVectors", isDirectory: true) fileURL! = fileURL!.appendingPathComponent("\(fileName).txt", isDirectory: false) #endif @@ -82,7 +82,7 @@ extension RFCVectorDecoder: Decoder { return [] } - + var userInfo: [CodingUserInfoKey: Any] { return [:] } func container(keyedBy type: Key.Type) throws -> KeyedDecodingContainer where Key: CodingKey { diff --git a/Tests/_CryptoExtrasTests/Utils/SplitData.swift b/Tests/CryptoExtrasTests/Utils/SplitData.swift similarity index 100% rename from Tests/_CryptoExtrasTests/Utils/SplitData.swift rename to Tests/CryptoExtrasTests/Utils/SplitData.swift diff --git a/Tests/_CryptoExtrasTests/Utils/Wycheproof.swift b/Tests/CryptoExtrasTests/Utils/Wycheproof.swift similarity index 85% rename from Tests/_CryptoExtrasTests/Utils/Wycheproof.swift rename to Tests/CryptoExtrasTests/Utils/Wycheproof.swift index 9c7025617..065f8ff6a 100644 --- a/Tests/_CryptoExtrasTests/Utils/Wycheproof.swift +++ b/Tests/CryptoExtrasTests/Utils/Wycheproof.swift @@ -27,14 +27,14 @@ extension XCTestCase { } #if compiler(>=6.0) if #available(macOS 13, iOS 16, watchOS 9, tvOS 16, visionOS 1, macCatalyst 16, *) { - fileURL.append(path: "_CryptoExtrasVectors", directoryHint: .isDirectory) + fileURL.append(path: "CryptoExtrasVectors", directoryHint: .isDirectory) fileURL.append(path: "\(jsonName).json", directoryHint: .notDirectory) } else { - fileURL = fileURL.appendingPathComponent("_CryptoExtrasVectors", isDirectory: true) + fileURL = fileURL.appendingPathComponent("CryptoExtrasVectors", isDirectory: true) fileURL = fileURL.appendingPathComponent("\(jsonName).json", isDirectory: false) } #else - fileURL = fileURL.appendingPathComponent("_CryptoExtrasVectors", isDirectory: true) + fileURL = fileURL.appendingPathComponent("CryptoExtrasVectors", isDirectory: true) fileURL = fileURL.appendingPathComponent("\(jsonName).json", isDirectory: false) #endif diff --git a/Tests/_CryptoExtrasTests/Utils/XCTestUtils.swift b/Tests/CryptoExtrasTests/Utils/XCTestUtils.swift similarity index 100% rename from Tests/_CryptoExtrasTests/Utils/XCTestUtils.swift rename to Tests/CryptoExtrasTests/Utils/XCTestUtils.swift diff --git a/Tests/_CryptoExtrasTests/ZKPs/ZKPToolbox.swift b/Tests/CryptoExtrasTests/ZKPs/ZKPToolbox.swift similarity index 99% rename from Tests/_CryptoExtrasTests/ZKPs/ZKPToolbox.swift rename to Tests/CryptoExtrasTests/ZKPs/ZKPToolbox.swift index 67a767606..d391006de 100644 --- a/Tests/_CryptoExtrasTests/ZKPs/ZKPToolbox.swift +++ b/Tests/CryptoExtrasTests/ZKPs/ZKPToolbox.swift @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// import Crypto -@testable import _CryptoExtras +@testable import CryptoExtras import XCTest @available(macOS 10.15, iOS 13.2, tvOS 13.2, watchOS 6.1, macCatalyst 13.2, visionOS 1.2, *) diff --git a/Tests/_CryptoExtrasVectors/AESCFB128GFSbox128.txt b/Tests/CryptoExtrasVectors/AESCFB128GFSbox128.txt similarity index 100% rename from Tests/_CryptoExtrasVectors/AESCFB128GFSbox128.txt rename to Tests/CryptoExtrasVectors/AESCFB128GFSbox128.txt diff --git a/Tests/_CryptoExtrasVectors/AESCFB128GFSbox192.txt b/Tests/CryptoExtrasVectors/AESCFB128GFSbox192.txt similarity index 100% rename from Tests/_CryptoExtrasVectors/AESCFB128GFSbox192.txt rename to Tests/CryptoExtrasVectors/AESCFB128GFSbox192.txt diff --git a/Tests/_CryptoExtrasVectors/AESCFB128GFSbox256.txt b/Tests/CryptoExtrasVectors/AESCFB128GFSbox256.txt similarity index 100% rename from Tests/_CryptoExtrasVectors/AESCFB128GFSbox256.txt rename to Tests/CryptoExtrasVectors/AESCFB128GFSbox256.txt diff --git a/Tests/_CryptoExtrasVectors/AESCFB128KeySbox128.txt b/Tests/CryptoExtrasVectors/AESCFB128KeySbox128.txt similarity index 100% rename from Tests/_CryptoExtrasVectors/AESCFB128KeySbox128.txt rename to Tests/CryptoExtrasVectors/AESCFB128KeySbox128.txt diff --git a/Tests/_CryptoExtrasVectors/AESCFB128KeySbox192.txt b/Tests/CryptoExtrasVectors/AESCFB128KeySbox192.txt similarity index 100% rename from Tests/_CryptoExtrasVectors/AESCFB128KeySbox192.txt rename to Tests/CryptoExtrasVectors/AESCFB128KeySbox192.txt diff --git a/Tests/_CryptoExtrasVectors/AESCFB128KeySbox256.txt b/Tests/CryptoExtrasVectors/AESCFB128KeySbox256.txt similarity index 100% rename from Tests/_CryptoExtrasVectors/AESCFB128KeySbox256.txt rename to Tests/CryptoExtrasVectors/AESCFB128KeySbox256.txt diff --git a/Tests/_CryptoExtrasVectors/AESCFB128VarKey128.txt b/Tests/CryptoExtrasVectors/AESCFB128VarKey128.txt similarity index 100% rename from Tests/_CryptoExtrasVectors/AESCFB128VarKey128.txt rename to Tests/CryptoExtrasVectors/AESCFB128VarKey128.txt diff --git a/Tests/_CryptoExtrasVectors/AESCFB128VarKey192.txt b/Tests/CryptoExtrasVectors/AESCFB128VarKey192.txt similarity index 100% rename from Tests/_CryptoExtrasVectors/AESCFB128VarKey192.txt rename to Tests/CryptoExtrasVectors/AESCFB128VarKey192.txt diff --git a/Tests/_CryptoExtrasVectors/AESCFB128VarKey256.txt b/Tests/CryptoExtrasVectors/AESCFB128VarKey256.txt similarity index 100% rename from Tests/_CryptoExtrasVectors/AESCFB128VarKey256.txt rename to Tests/CryptoExtrasVectors/AESCFB128VarKey256.txt diff --git a/Tests/_CryptoExtrasVectors/AESCFB128VarTxt128.txt b/Tests/CryptoExtrasVectors/AESCFB128VarTxt128.txt similarity index 100% rename from Tests/_CryptoExtrasVectors/AESCFB128VarTxt128.txt rename to Tests/CryptoExtrasVectors/AESCFB128VarTxt128.txt diff --git a/Tests/_CryptoExtrasVectors/AESCFB128VarTxt192.txt b/Tests/CryptoExtrasVectors/AESCFB128VarTxt192.txt similarity index 100% rename from Tests/_CryptoExtrasVectors/AESCFB128VarTxt192.txt rename to Tests/CryptoExtrasVectors/AESCFB128VarTxt192.txt diff --git a/Tests/_CryptoExtrasVectors/AESCFB128VarTxt256.txt b/Tests/CryptoExtrasVectors/AESCFB128VarTxt256.txt similarity index 100% rename from Tests/_CryptoExtrasVectors/AESCFB128VarTxt256.txt rename to Tests/CryptoExtrasVectors/AESCFB128VarTxt256.txt diff --git a/Tests/_CryptoExtrasVectors/aes_cbc_pkcs5_test.json b/Tests/CryptoExtrasVectors/aes_cbc_pkcs5_test.json similarity index 100% rename from Tests/_CryptoExtrasVectors/aes_cbc_pkcs5_test.json rename to Tests/CryptoExtrasVectors/aes_cbc_pkcs5_test.json diff --git a/Tests/_CryptoExtrasVectors/aes_cmac_test.json b/Tests/CryptoExtrasVectors/aes_cmac_test.json similarity index 100% rename from Tests/_CryptoExtrasVectors/aes_cmac_test.json rename to Tests/CryptoExtrasVectors/aes_cmac_test.json diff --git a/Tests/_CryptoExtrasVectors/aes_gcm_siv_test.json b/Tests/CryptoExtrasVectors/aes_gcm_siv_test.json similarity index 100% rename from Tests/_CryptoExtrasVectors/aes_gcm_siv_test.json rename to Tests/CryptoExtrasVectors/aes_gcm_siv_test.json diff --git a/Tests/_CryptoExtrasVectors/mldsa_65_verify_test.json b/Tests/CryptoExtrasVectors/mldsa_65_verify_test.json similarity index 100% rename from Tests/_CryptoExtrasVectors/mldsa_65_verify_test.json rename to Tests/CryptoExtrasVectors/mldsa_65_verify_test.json diff --git a/Tests/_CryptoExtrasVectors/mldsa_87_verify_test.json b/Tests/CryptoExtrasVectors/mldsa_87_verify_test.json similarity index 100% rename from Tests/_CryptoExtrasVectors/mldsa_87_verify_test.json rename to Tests/CryptoExtrasVectors/mldsa_87_verify_test.json diff --git a/Tests/_CryptoExtrasVectors/mldsa_nist_keygen_65_tests.json b/Tests/CryptoExtrasVectors/mldsa_nist_keygen_65_tests.json similarity index 100% rename from Tests/_CryptoExtrasVectors/mldsa_nist_keygen_65_tests.json rename to Tests/CryptoExtrasVectors/mldsa_nist_keygen_65_tests.json diff --git a/Tests/_CryptoExtrasVectors/mldsa_nist_keygen_87_tests.json b/Tests/CryptoExtrasVectors/mldsa_nist_keygen_87_tests.json similarity index 100% rename from Tests/_CryptoExtrasVectors/mldsa_nist_keygen_87_tests.json rename to Tests/CryptoExtrasVectors/mldsa_nist_keygen_87_tests.json diff --git a/Tests/_CryptoExtrasVectors/rfc-6070-PBKDF2-SHA1.txt b/Tests/CryptoExtrasVectors/rfc-6070-PBKDF2-SHA1.txt similarity index 100% rename from Tests/_CryptoExtrasVectors/rfc-6070-PBKDF2-SHA1.txt rename to Tests/CryptoExtrasVectors/rfc-6070-PBKDF2-SHA1.txt diff --git a/Tests/_CryptoExtrasVectors/rfc-7914-scrypt.txt b/Tests/CryptoExtrasVectors/rfc-7914-scrypt.txt similarity index 100% rename from Tests/_CryptoExtrasVectors/rfc-7914-scrypt.txt rename to Tests/CryptoExtrasVectors/rfc-7914-scrypt.txt diff --git a/Tests/_CryptoExtrasVectors/rfc9474.json b/Tests/CryptoExtrasVectors/rfc9474.json similarity index 100% rename from Tests/_CryptoExtrasVectors/rfc9474.json rename to Tests/CryptoExtrasVectors/rfc9474.json diff --git a/Tests/_CryptoExtrasVectors/rsa_oaep_2048_sha1_mgf1sha1_test.json b/Tests/CryptoExtrasVectors/rsa_oaep_2048_sha1_mgf1sha1_test.json similarity index 100% rename from Tests/_CryptoExtrasVectors/rsa_oaep_2048_sha1_mgf1sha1_test.json rename to Tests/CryptoExtrasVectors/rsa_oaep_2048_sha1_mgf1sha1_test.json diff --git a/Tests/_CryptoExtrasVectors/rsa_oaep_2048_sha256_mgf1sha256_test.json b/Tests/CryptoExtrasVectors/rsa_oaep_2048_sha256_mgf1sha256_test.json similarity index 100% rename from Tests/_CryptoExtrasVectors/rsa_oaep_2048_sha256_mgf1sha256_test.json rename to Tests/CryptoExtrasVectors/rsa_oaep_2048_sha256_mgf1sha256_test.json diff --git a/Tests/_CryptoExtrasVectors/rsa_oaep_misc_test.json b/Tests/CryptoExtrasVectors/rsa_oaep_misc_test.json similarity index 100% rename from Tests/_CryptoExtrasVectors/rsa_oaep_misc_test.json rename to Tests/CryptoExtrasVectors/rsa_oaep_misc_test.json diff --git a/Tests/_CryptoExtrasVectors/rsa_pss_2048_sha1_mgf1_20_test.json b/Tests/CryptoExtrasVectors/rsa_pss_2048_sha1_mgf1_20_test.json similarity index 100% rename from Tests/_CryptoExtrasVectors/rsa_pss_2048_sha1_mgf1_20_test.json rename to Tests/CryptoExtrasVectors/rsa_pss_2048_sha1_mgf1_20_test.json diff --git a/Tests/_CryptoExtrasVectors/rsa_pss_2048_sha256_mgf1_0_test.json b/Tests/CryptoExtrasVectors/rsa_pss_2048_sha256_mgf1_0_test.json similarity index 100% rename from Tests/_CryptoExtrasVectors/rsa_pss_2048_sha256_mgf1_0_test.json rename to Tests/CryptoExtrasVectors/rsa_pss_2048_sha256_mgf1_0_test.json diff --git a/Tests/_CryptoExtrasVectors/rsa_pss_2048_sha256_mgf1_32_test.json b/Tests/CryptoExtrasVectors/rsa_pss_2048_sha256_mgf1_32_test.json similarity index 100% rename from Tests/_CryptoExtrasVectors/rsa_pss_2048_sha256_mgf1_32_test.json rename to Tests/CryptoExtrasVectors/rsa_pss_2048_sha256_mgf1_32_test.json diff --git a/Tests/_CryptoExtrasVectors/rsa_pss_3072_sha256_mgf1_32_test.json b/Tests/CryptoExtrasVectors/rsa_pss_3072_sha256_mgf1_32_test.json similarity index 100% rename from Tests/_CryptoExtrasVectors/rsa_pss_3072_sha256_mgf1_32_test.json rename to Tests/CryptoExtrasVectors/rsa_pss_3072_sha256_mgf1_32_test.json diff --git a/Tests/_CryptoExtrasVectors/rsa_pss_4096_sha256_mgf1_32_test.json b/Tests/CryptoExtrasVectors/rsa_pss_4096_sha256_mgf1_32_test.json similarity index 100% rename from Tests/_CryptoExtrasVectors/rsa_pss_4096_sha256_mgf1_32_test.json rename to Tests/CryptoExtrasVectors/rsa_pss_4096_sha256_mgf1_32_test.json diff --git a/Tests/_CryptoExtrasVectors/rsa_pss_4096_sha512_mgf1_32_test.json b/Tests/CryptoExtrasVectors/rsa_pss_4096_sha512_mgf1_32_test.json similarity index 100% rename from Tests/_CryptoExtrasVectors/rsa_pss_4096_sha512_mgf1_32_test.json rename to Tests/CryptoExtrasVectors/rsa_pss_4096_sha512_mgf1_32_test.json diff --git a/Tests/_CryptoExtrasVectors/rsa_pss_misc_test.json b/Tests/CryptoExtrasVectors/rsa_pss_misc_test.json similarity index 100% rename from Tests/_CryptoExtrasVectors/rsa_pss_misc_test.json rename to Tests/CryptoExtrasVectors/rsa_pss_misc_test.json diff --git a/Tests/_CryptoExtrasVectors/rsa_signature_2048_sha256_test.json b/Tests/CryptoExtrasVectors/rsa_signature_2048_sha256_test.json similarity index 100% rename from Tests/_CryptoExtrasVectors/rsa_signature_2048_sha256_test.json rename to Tests/CryptoExtrasVectors/rsa_signature_2048_sha256_test.json diff --git a/Tests/_CryptoExtrasVectors/rsa_signature_2048_sha512_test.json b/Tests/CryptoExtrasVectors/rsa_signature_2048_sha512_test.json similarity index 100% rename from Tests/_CryptoExtrasVectors/rsa_signature_2048_sha512_test.json rename to Tests/CryptoExtrasVectors/rsa_signature_2048_sha512_test.json diff --git a/Tests/_CryptoExtrasVectors/rsa_signature_3072_sha256_test.json b/Tests/CryptoExtrasVectors/rsa_signature_3072_sha256_test.json similarity index 100% rename from Tests/_CryptoExtrasVectors/rsa_signature_3072_sha256_test.json rename to Tests/CryptoExtrasVectors/rsa_signature_3072_sha256_test.json diff --git a/Tests/_CryptoExtrasVectors/rsa_signature_3072_sha512_test.json b/Tests/CryptoExtrasVectors/rsa_signature_3072_sha512_test.json similarity index 100% rename from Tests/_CryptoExtrasVectors/rsa_signature_3072_sha512_test.json rename to Tests/CryptoExtrasVectors/rsa_signature_3072_sha512_test.json diff --git a/Tests/_CryptoExtrasVectors/rsa_signature_4096_sha512_test.json b/Tests/CryptoExtrasVectors/rsa_signature_4096_sha512_test.json similarity index 100% rename from Tests/_CryptoExtrasVectors/rsa_signature_4096_sha512_test.json rename to Tests/CryptoExtrasVectors/rsa_signature_4096_sha512_test.json diff --git a/Tests/_CryptoExtrasVectors/rsa_signature_test.json b/Tests/CryptoExtrasVectors/rsa_signature_test.json similarity index 100% rename from Tests/_CryptoExtrasVectors/rsa_signature_test.json rename to Tests/CryptoExtrasVectors/rsa_signature_test.json diff --git a/scripts/gyb b/scripts/gyb index ef8021ad4..3c5129632 100755 --- a/scripts/gyb +++ b/scripts/gyb @@ -1,4 +1,4 @@ -#!/usr/bin/env python2.7 +#!/usr/bin/env python import gyb gyb.main() From 46d7ce0482baefc713478ada071a6db99a1f4785 Mon Sep 17 00:00:00 2001 From: Francesco Paolo Severino Date: Mon, 15 Sep 2025 17:17:16 +0200 Subject: [PATCH 33/47] Move external mu files to new CryptoExtras module --- .../{_CryptoExtras => CryptoExtras}/MLDSA/MLDSA+externalMu.swift | 0 .../MLDSA/MLDSA+externalMu.swift.gyb | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename Sources/{_CryptoExtras => CryptoExtras}/MLDSA/MLDSA+externalMu.swift (100%) rename Sources/{_CryptoExtras => CryptoExtras}/MLDSA/MLDSA+externalMu.swift.gyb (100%) diff --git a/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift b/Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift similarity index 100% rename from Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift rename to Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift diff --git a/Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb b/Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb similarity index 100% rename from Sources/_CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb rename to Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb From 8ec37c763b024a818ae6dcef57e21ee5bd0fd0ee Mon Sep 17 00:00:00 2001 From: Francesco Paolo Severino Date: Mon, 15 Sep 2025 17:33:40 +0200 Subject: [PATCH 34/47] Update `withUnsafeBytes` to `package` access level This convinience method will be used by SLHDSA, which will be located in `CryptoExtras`, and could also be used by `MLDSA44`, also to be located in `CryptoExtras` --- .../Crypto/Util/BoringSSL/Optional+withUnsafeBytes_boring.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Crypto/Util/BoringSSL/Optional+withUnsafeBytes_boring.swift b/Sources/Crypto/Util/BoringSSL/Optional+withUnsafeBytes_boring.swift index 8d8aabaca..d360cf1ef 100644 --- a/Sources/Crypto/Util/BoringSSL/Optional+withUnsafeBytes_boring.swift +++ b/Sources/Crypto/Util/BoringSSL/Optional+withUnsafeBytes_boring.swift @@ -19,7 +19,7 @@ import Foundation #endif extension Optional where Wrapped: DataProtocol { - func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> ReturnValue) rethrows -> ReturnValue { + package func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> ReturnValue) rethrows -> ReturnValue { if let self { let bytes: ContiguousBytes = self.regions.count == 1 ? self.regions.first! : Array(self) return try bytes.withUnsafeBytes { try body($0) } From a34d9fbeb6d3092bb8d8ab7c49f4cf19d3ae80a4 Mon Sep 17 00:00:00 2001 From: Francesco Paolo Severino Date: Mon, 15 Sep 2025 17:35:08 +0200 Subject: [PATCH 35/47] Formatting --- .../Util/BoringSSL/Optional+withUnsafeBytes_boring.swift | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Sources/Crypto/Util/BoringSSL/Optional+withUnsafeBytes_boring.swift b/Sources/Crypto/Util/BoringSSL/Optional+withUnsafeBytes_boring.swift index d360cf1ef..e06f884fa 100644 --- a/Sources/Crypto/Util/BoringSSL/Optional+withUnsafeBytes_boring.swift +++ b/Sources/Crypto/Util/BoringSSL/Optional+withUnsafeBytes_boring.swift @@ -19,7 +19,9 @@ import Foundation #endif extension Optional where Wrapped: DataProtocol { - package func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> ReturnValue) rethrows -> ReturnValue { + package func withUnsafeBytes( + _ body: (UnsafeRawBufferPointer) throws -> ReturnValue + ) rethrows -> ReturnValue { if let self { let bytes: ContiguousBytes = self.regions.count == 1 ? self.regions.first! : Array(self) return try bytes.withUnsafeBytes { try body($0) } From 2febca73238f791e1f3996603c4bfdcf5c1b6a7b Mon Sep 17 00:00:00 2001 From: Francesco Paolo Severino Date: Tue, 16 Sep 2025 12:05:07 +0200 Subject: [PATCH 36/47] Update for macOS 26 --- Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift | 8 ++++---- Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb | 4 ++-- Tests/CryptoExtrasTests/MLDSATests.swift | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift b/Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift index 7590c27ad..47cb53d78 100644 --- a/Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift +++ b/Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift @@ -24,7 +24,7 @@ import FoundationEssentials import Foundation #endif -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, macCatalyst 26.0, visionOS 26.0, *) extension MLDSA65.PrivateKey { /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). /// @@ -38,7 +38,7 @@ extension MLDSA65.PrivateKey { } } -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, macCatalyst 26.0, visionOS 26.0, *) extension MLDSA65.PublicKey { /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. /// @@ -61,7 +61,7 @@ extension MLDSA65.PublicKey { } } -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, macCatalyst 26.0, visionOS 26.0, *) extension MLDSA87.PrivateKey { /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). /// @@ -75,7 +75,7 @@ extension MLDSA87.PrivateKey { } } -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, macCatalyst 26.0, visionOS 26.0, *) extension MLDSA87.PublicKey { /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. /// diff --git a/Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb b/Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb index 710e1fa89..1be40ed32 100644 --- a/Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb +++ b/Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb @@ -28,7 +28,7 @@ import Foundation }% % for parameter_set in parameter_sets: -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, macCatalyst 26.0, visionOS 26.0, *) extension MLDSA${parameter_set}.PrivateKey { /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). /// @@ -42,7 +42,7 @@ extension MLDSA${parameter_set}.PrivateKey { } } -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, macCatalyst 26.0, visionOS 26.0, *) extension MLDSA${parameter_set}.PublicKey { /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. /// diff --git a/Tests/CryptoExtrasTests/MLDSATests.swift b/Tests/CryptoExtrasTests/MLDSATests.swift index a7c224cb2..f1394edad 100644 --- a/Tests/CryptoExtrasTests/MLDSATests.swift +++ b/Tests/CryptoExtrasTests/MLDSATests.swift @@ -356,7 +356,7 @@ extension MLDSA87.PublicKey { #endif // SDK has MLDSA -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, macCatalyst 26.0, visionOS 26.0, *) final class MLDSAExternalMuTests: XCTestCase { func testMLDSA65PrehashedSigning() throws { let message = "Hello, world!".data(using: .utf8)! From 788c399cc02008258a397b5a3d66f55603a3064e Mon Sep 17 00:00:00 2001 From: Francesco Paolo Severino Date: Tue, 16 Sep 2025 15:07:50 +0200 Subject: [PATCH 37/47] Make external mu work when `let development = false` --- .../MLDSA+ExternalMuKey_boring.swift | 316 ++++++++++++++++++ .../MLDSA+ExternalMuKey_boring.swift.gyb | 182 ++++++++++ .../CryptoExtras/MLDSA/MLDSA+externalMu.swift | 30 ++ .../MLDSA/MLDSA+externalMu.swift.gyb | 15 + 4 files changed, 543 insertions(+) create mode 100644 Sources/CryptoExtras/MLDSA/BoringSSL/MLDSA+ExternalMuKey_boring.swift create mode 100644 Sources/CryptoExtras/MLDSA/BoringSSL/MLDSA+ExternalMuKey_boring.swift.gyb diff --git a/Sources/CryptoExtras/MLDSA/BoringSSL/MLDSA+ExternalMuKey_boring.swift b/Sources/CryptoExtras/MLDSA/BoringSSL/MLDSA+ExternalMuKey_boring.swift new file mode 100644 index 000000000..aecf09513 --- /dev/null +++ b/Sources/CryptoExtras/MLDSA/BoringSSL/MLDSA+ExternalMuKey_boring.swift @@ -0,0 +1,316 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2025 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +// MARK: - Generated file, do NOT edit +// any edits of this file WILL be overwritten and thus discarded +// see section `gyb` in `README` for details. + +#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API + +@_implementationOnly import CCryptoBoringSSL +import Crypto + +#if canImport(FoundationEssentials) +import FoundationEssentials +#else +import Foundation +#endif + +@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, macCatalyst 26.0, visionOS 26.0, *) +extension MLDSA65.PrivateKey { + struct ExternalMuPrivateKey: @unchecked Sendable { + private var backing: Backing + + init(seedRepresentation: some DataProtocol) throws { + self.backing = try Backing(seedRepresentation: seedRepresentation) + } + + func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { + try self.backing.signature(forPrehashedMessageRepresentative: mu) + } + + fileprivate final class Backing { + fileprivate var key: MLDSA65_private_key + + init(seedRepresentation: some DataProtocol) throws { + guard seedRepresentation.count == MLDSA.seedByteCount else { + throw CryptoKitError.incorrectKeySize + } + + self.key = .init() + + guard + Data(seedRepresentation).withUnsafeBytes({ seedPtr in + CCryptoBoringSSL_MLDSA65_private_key_from_seed( + &self.key, + seedPtr.baseAddress, + MLDSA.seedByteCount + ) + }) == 1 + else { + throw CryptoKitError.internalBoringSSLError() + } + } + + func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { + guard mu.count == MLDSA.muByteCount else { + throw CryptoKitError.incorrectParameterSize + } + + var signature = Data(repeating: 0, count: Int(MLDSA65_SIGNATURE_BYTES)) + + let rc: CInt = signature.withUnsafeMutableBytes { signaturePtr in + let muBytes: ContiguousBytes = mu.regions.count == 1 ? mu.regions.first! : Array(mu) + return muBytes.withUnsafeBytes { muPtr in + CCryptoBoringSSL_MLDSA65_sign_message_representative( + signaturePtr.baseAddress, + &self.key, + muPtr.baseAddress + ) + } + } + + guard rc == 1 else { + throw CryptoKitError.internalBoringSSLError() + } + + return signature + } + } + } +} + +@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, macCatalyst 26.0, visionOS 26.0, *) +extension MLDSA65.PublicKey { + struct ExternalMuPublicKey: @unchecked Sendable { + private var backing: Backing + + init(rawRepresentation: some DataProtocol) throws { + self.backing = try Backing(rawRepresentation: rawRepresentation) + } + + func prehash(for data: D) throws -> Data { + let context: Data? = nil + return try self.backing.prehash(for: data, context: context) + } + + func prehash(for data: D, context: C) throws -> Data { + try self.backing.prehash(for: data, context: context) + } + + fileprivate final class Backing { + private var key: MLDSA65_public_key + + init(rawRepresentation: some DataProtocol) throws { + guard rawRepresentation.count == Self.byteCount else { + throw CryptoKitError.incorrectKeySize + } + + self.key = .init() + + let bytes: ContiguousBytes = + rawRepresentation.regions.count == 1 + ? rawRepresentation.regions.first! + : Array(rawRepresentation) + try bytes.withUnsafeBytes { rawBuffer in + try rawBuffer.withMemoryRebound(to: UInt8.self) { buffer in + var cbs = CBS(data: buffer.baseAddress, len: buffer.count) + guard CCryptoBoringSSL_MLDSA65_parse_public_key(&self.key, &cbs) == 1 else { + throw CryptoKitError.internalBoringSSLError() + } + } + } + } + + func prehash(for data: D, context: C?) throws -> Data { + var mu = Data(repeating: 0, count: MLDSA.muByteCount) + + let dataBytes: ContiguousBytes = data.regions.count == 1 ? data.regions.first! : Array(data) + let rc: CInt = mu.withUnsafeMutableBytes { muPtr in + dataBytes.withUnsafeBytes { dataPtr in + context.withUnsafeBytes { contextPtr in + var prehash = MLDSA65_prehash() + let rc = CCryptoBoringSSL_MLDSA65_prehash_init( + &prehash, + &key, + contextPtr.baseAddress, + contextPtr.count + ) + CCryptoBoringSSL_MLDSA65_prehash_update(&prehash, dataPtr.baseAddress, dataPtr.count) + CCryptoBoringSSL_MLDSA65_prehash_finalize(muPtr.baseAddress, &prehash) + return rc + } + } + } + + guard rc == 1 else { + throw CryptoKitError.internalBoringSSLError() + } + + return mu + } + + static let byteCount = Int(MLDSA65_PUBLIC_KEY_BYTES) + } + } +} + +@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, macCatalyst 26.0, visionOS 26.0, *) +extension MLDSA87.PrivateKey { + struct ExternalMuPrivateKey: @unchecked Sendable { + private var backing: Backing + + init(seedRepresentation: some DataProtocol) throws { + self.backing = try Backing(seedRepresentation: seedRepresentation) + } + + func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { + try self.backing.signature(forPrehashedMessageRepresentative: mu) + } + + fileprivate final class Backing { + fileprivate var key: MLDSA87_private_key + + init(seedRepresentation: some DataProtocol) throws { + guard seedRepresentation.count == MLDSA.seedByteCount else { + throw CryptoKitError.incorrectKeySize + } + + self.key = .init() + + guard + Data(seedRepresentation).withUnsafeBytes({ seedPtr in + CCryptoBoringSSL_MLDSA87_private_key_from_seed( + &self.key, + seedPtr.baseAddress, + MLDSA.seedByteCount + ) + }) == 1 + else { + throw CryptoKitError.internalBoringSSLError() + } + } + + func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { + guard mu.count == MLDSA.muByteCount else { + throw CryptoKitError.incorrectParameterSize + } + + var signature = Data(repeating: 0, count: Int(MLDSA87_SIGNATURE_BYTES)) + + let rc: CInt = signature.withUnsafeMutableBytes { signaturePtr in + let muBytes: ContiguousBytes = mu.regions.count == 1 ? mu.regions.first! : Array(mu) + return muBytes.withUnsafeBytes { muPtr in + CCryptoBoringSSL_MLDSA87_sign_message_representative( + signaturePtr.baseAddress, + &self.key, + muPtr.baseAddress + ) + } + } + + guard rc == 1 else { + throw CryptoKitError.internalBoringSSLError() + } + + return signature + } + } + } +} + +@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, macCatalyst 26.0, visionOS 26.0, *) +extension MLDSA87.PublicKey { + struct ExternalMuPublicKey: @unchecked Sendable { + private var backing: Backing + + init(rawRepresentation: some DataProtocol) throws { + self.backing = try Backing(rawRepresentation: rawRepresentation) + } + + func prehash(for data: D) throws -> Data { + let context: Data? = nil + return try self.backing.prehash(for: data, context: context) + } + + func prehash(for data: D, context: C) throws -> Data { + try self.backing.prehash(for: data, context: context) + } + + fileprivate final class Backing { + private var key: MLDSA87_public_key + + init(rawRepresentation: some DataProtocol) throws { + guard rawRepresentation.count == Self.byteCount else { + throw CryptoKitError.incorrectKeySize + } + + self.key = .init() + + let bytes: ContiguousBytes = + rawRepresentation.regions.count == 1 + ? rawRepresentation.regions.first! + : Array(rawRepresentation) + try bytes.withUnsafeBytes { rawBuffer in + try rawBuffer.withMemoryRebound(to: UInt8.self) { buffer in + var cbs = CBS(data: buffer.baseAddress, len: buffer.count) + guard CCryptoBoringSSL_MLDSA87_parse_public_key(&self.key, &cbs) == 1 else { + throw CryptoKitError.internalBoringSSLError() + } + } + } + } + + func prehash(for data: D, context: C?) throws -> Data { + var mu = Data(repeating: 0, count: MLDSA.muByteCount) + + let dataBytes: ContiguousBytes = data.regions.count == 1 ? data.regions.first! : Array(data) + let rc: CInt = mu.withUnsafeMutableBytes { muPtr in + dataBytes.withUnsafeBytes { dataPtr in + context.withUnsafeBytes { contextPtr in + var prehash = MLDSA87_prehash() + let rc = CCryptoBoringSSL_MLDSA87_prehash_init( + &prehash, + &key, + contextPtr.baseAddress, + contextPtr.count + ) + CCryptoBoringSSL_MLDSA87_prehash_update(&prehash, dataPtr.baseAddress, dataPtr.count) + CCryptoBoringSSL_MLDSA87_prehash_finalize(muPtr.baseAddress, &prehash) + return rc + } + } + } + + guard rc == 1 else { + throw CryptoKitError.internalBoringSSLError() + } + + return mu + } + + static let byteCount = Int(MLDSA87_PUBLIC_KEY_BYTES) + } + } +} + +enum MLDSA { + /// The size of the seed in bytes. + static let seedByteCount = 32 + + /// The size of the "mu" value in bytes. + fileprivate static let muByteCount = 64 +} + +#endif diff --git a/Sources/CryptoExtras/MLDSA/BoringSSL/MLDSA+ExternalMuKey_boring.swift.gyb b/Sources/CryptoExtras/MLDSA/BoringSSL/MLDSA+ExternalMuKey_boring.swift.gyb new file mode 100644 index 000000000..6e1738512 --- /dev/null +++ b/Sources/CryptoExtras/MLDSA/BoringSSL/MLDSA+ExternalMuKey_boring.swift.gyb @@ -0,0 +1,182 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2025 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +// MARK: - Generated file, do NOT edit +// any edits of this file WILL be overwritten and thus discarded +// see section `gyb` in `README` for details. + +#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API + +@_implementationOnly import CCryptoBoringSSL +import Crypto + +#if canImport(FoundationEssentials) +import FoundationEssentials +#else +import Foundation +#endif +%{ + parameter_sets = ["65", "87"] +}% +% for parameter_set in parameter_sets: + +@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, macCatalyst 26.0, visionOS 26.0, *) +extension MLDSA${parameter_set}.PrivateKey { + struct ExternalMuPrivateKey: @unchecked Sendable { + private var backing: Backing + + init(seedRepresentation: some DataProtocol) throws { + self.backing = try Backing(seedRepresentation: seedRepresentation) + } + + func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { + try self.backing.signature(forPrehashedMessageRepresentative: mu) + } + + fileprivate final class Backing { + fileprivate var key: MLDSA${parameter_set}_private_key + + init(seedRepresentation: some DataProtocol) throws { + guard seedRepresentation.count == MLDSA.seedByteCount else { + throw CryptoKitError.incorrectKeySize + } + + self.key = .init() + + guard + Data(seedRepresentation).withUnsafeBytes({ seedPtr in + CCryptoBoringSSL_MLDSA${parameter_set}_private_key_from_seed( + &self.key, + seedPtr.baseAddress, + MLDSA.seedByteCount + ) + }) == 1 + else { + throw CryptoKitError.internalBoringSSLError() + } + } + + func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { + guard mu.count == MLDSA.muByteCount else { + throw CryptoKitError.incorrectParameterSize + } + + var signature = Data(repeating: 0, count: Int(MLDSA${parameter_set}_SIGNATURE_BYTES)) + + let rc: CInt = signature.withUnsafeMutableBytes { signaturePtr in + let muBytes: ContiguousBytes = mu.regions.count == 1 ? mu.regions.first! : Array(mu) + return muBytes.withUnsafeBytes { muPtr in + CCryptoBoringSSL_MLDSA${parameter_set}_sign_message_representative( + signaturePtr.baseAddress, + &self.key, + muPtr.baseAddress + ) + } + } + + guard rc == 1 else { + throw CryptoKitError.internalBoringSSLError() + } + + return signature + } + } + } +} + +@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, macCatalyst 26.0, visionOS 26.0, *) +extension MLDSA${parameter_set}.PublicKey { + struct ExternalMuPublicKey: @unchecked Sendable { + private var backing: Backing + + init(rawRepresentation: some DataProtocol) throws { + self.backing = try Backing(rawRepresentation: rawRepresentation) + } + + func prehash(for data: D) throws -> Data { + let context: Data? = nil + return try self.backing.prehash(for: data, context: context) + } + + func prehash(for data: D, context: C) throws -> Data { + try self.backing.prehash(for: data, context: context) + } + + fileprivate final class Backing { + private var key: MLDSA${parameter_set}_public_key + + init(rawRepresentation: some DataProtocol) throws { + guard rawRepresentation.count == Self.byteCount else { + throw CryptoKitError.incorrectKeySize + } + + self.key = .init() + + let bytes: ContiguousBytes = + rawRepresentation.regions.count == 1 + ? rawRepresentation.regions.first! + : Array(rawRepresentation) + try bytes.withUnsafeBytes { rawBuffer in + try rawBuffer.withMemoryRebound(to: UInt8.self) { buffer in + var cbs = CBS(data: buffer.baseAddress, len: buffer.count) + guard CCryptoBoringSSL_MLDSA${parameter_set}_parse_public_key(&self.key, &cbs) == 1 else { + throw CryptoKitError.internalBoringSSLError() + } + } + } + } + + func prehash(for data: D, context: C?) throws -> Data { + var mu = Data(repeating: 0, count: MLDSA.muByteCount) + + let dataBytes: ContiguousBytes = data.regions.count == 1 ? data.regions.first! : Array(data) + let rc: CInt = mu.withUnsafeMutableBytes { muPtr in + dataBytes.withUnsafeBytes { dataPtr in + context.withUnsafeBytes { contextPtr in + var prehash = MLDSA${parameter_set}_prehash() + let rc = CCryptoBoringSSL_MLDSA${parameter_set}_prehash_init( + &prehash, + &key, + contextPtr.baseAddress, + contextPtr.count + ) + CCryptoBoringSSL_MLDSA${parameter_set}_prehash_update(&prehash, dataPtr.baseAddress, dataPtr.count) + CCryptoBoringSSL_MLDSA${parameter_set}_prehash_finalize(muPtr.baseAddress, &prehash) + return rc + } + } + } + + guard rc == 1 else { + throw CryptoKitError.internalBoringSSLError() + } + + return mu + } + + static let byteCount = Int(MLDSA${parameter_set}_PUBLIC_KEY_BYTES) + } + } +} +% end + +enum MLDSA { + /// The size of the seed in bytes. + static let seedByteCount = 32 + + /// The size of the "mu" value in bytes. + fileprivate static let muByteCount = 64 +} + +#endif diff --git a/Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift b/Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift index 47cb53d78..67d9984a4 100644 --- a/Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift +++ b/Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift @@ -34,7 +34,12 @@ extension MLDSA65.PrivateKey { /// /// - Returns: The signature of the prehashed message representative. public func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { + #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API + try ExternalMuPrivateKey(seedRepresentation: self.seedRepresentation) + .signature(forPrehashedMessageRepresentative: mu) + #else try self.signature_boring(forPrehashedMessageRepresentative: mu) + #endif } } @@ -46,7 +51,12 @@ extension MLDSA65.PublicKey { /// /// - Returns: The prehashed message representative (a.k.a. "external mu"). public func prehash(for data: D) throws -> Data { + #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API + try ExternalMuPublicKey(rawRepresentation: self.rawRepresentation) + .prehash(for: data) + #else try self.prehash_boring(for: data) + #endif } /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. @@ -57,7 +67,12 @@ extension MLDSA65.PublicKey { /// /// - Returns: The prehashed message representative (a.k.a. "external mu"). public func prehash(for data: D, context: C) throws -> Data { + #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API + try ExternalMuPublicKey(rawRepresentation: self.rawRepresentation) + .prehash(for: data, context: context) + #else try self.prehash_boring(for: data, context: context) + #endif } } @@ -71,7 +86,12 @@ extension MLDSA87.PrivateKey { /// /// - Returns: The signature of the prehashed message representative. public func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { + #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API + try ExternalMuPrivateKey(seedRepresentation: self.seedRepresentation) + .signature(forPrehashedMessageRepresentative: mu) + #else try self.signature_boring(forPrehashedMessageRepresentative: mu) + #endif } } @@ -83,7 +103,12 @@ extension MLDSA87.PublicKey { /// /// - Returns: The prehashed message representative (a.k.a. "external mu"). public func prehash(for data: D) throws -> Data { + #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API + try ExternalMuPublicKey(rawRepresentation: self.rawRepresentation) + .prehash(for: data) + #else try self.prehash_boring(for: data) + #endif } /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. @@ -94,6 +119,11 @@ extension MLDSA87.PublicKey { /// /// - Returns: The prehashed message representative (a.k.a. "external mu"). public func prehash(for data: D, context: C) throws -> Data { + #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API + try ExternalMuPublicKey(rawRepresentation: self.rawRepresentation) + .prehash(for: data, context: context) + #else try self.prehash_boring(for: data, context: context) + #endif } } diff --git a/Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb b/Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb index 1be40ed32..892cec6b7 100644 --- a/Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb +++ b/Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb @@ -38,7 +38,12 @@ extension MLDSA${parameter_set}.PrivateKey { /// /// - Returns: The signature of the prehashed message representative. public func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { + #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API + try ExternalMuPrivateKey(seedRepresentation: self.seedRepresentation) + .signature(forPrehashedMessageRepresentative: mu) + #else try self.signature_boring(forPrehashedMessageRepresentative: mu) + #endif } } @@ -50,7 +55,12 @@ extension MLDSA${parameter_set}.PublicKey { /// /// - Returns: The prehashed message representative (a.k.a. "external mu"). public func prehash(for data: D) throws -> Data { + #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API + try ExternalMuPublicKey(rawRepresentation: self.rawRepresentation) + .prehash(for: data) + #else try self.prehash_boring(for: data) + #endif } /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. @@ -61,7 +71,12 @@ extension MLDSA${parameter_set}.PublicKey { /// /// - Returns: The prehashed message representative (a.k.a. "external mu"). public func prehash(for data: D, context: C) throws -> Data { + #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API + try ExternalMuPublicKey(rawRepresentation: self.rawRepresentation) + .prehash(for: data, context: context) + #else try self.prehash_boring(for: data, context: context) + #endif } } % end From 981d583fbbadb569b67ffaa2d54143d3123081d3 Mon Sep 17 00:00:00 2001 From: Francesco Paolo Severino Date: Tue, 16 Sep 2025 18:41:53 +0200 Subject: [PATCH 38/47] Move MLDSA implementation to CryptoBoringWrapper --- Package.swift | 4 +- .../Signatures/BoringSSL/MLDSA_wrapper.swift | 19 +- .../MLDSA/BoringSSLMLDSA.swift} | 186 ++++++----- .../MLDSA/BoringSSLMLDSA.swift.gyb} | 95 +++--- .../Util/Optional+withUnsafeBytes.swift} | 0 .../MLDSA+ExternalMuKey_boring.swift | 316 ------------------ .../MLDSA+ExternalMuKey_boring.swift.gyb | 182 ---------- .../CryptoExtras/MLDSA/MLDSA+externalMu.swift | 13 +- .../MLDSA/MLDSA+externalMu.swift.gyb | 7 +- 9 files changed, 168 insertions(+), 654 deletions(-) rename Sources/{Crypto/Signatures/BoringSSL/MLDSA_boring.swift => CryptoBoringWrapper/MLDSA/BoringSSLMLDSA.swift} (80%) rename Sources/{Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb => CryptoBoringWrapper/MLDSA/BoringSSLMLDSA.swift.gyb} (81%) rename Sources/{Crypto/Util/BoringSSL/Optional+withUnsafeBytes_boring.swift => CryptoBoringWrapper/Util/Optional+withUnsafeBytes.swift} (100%) delete mode 100644 Sources/CryptoExtras/MLDSA/BoringSSL/MLDSA+ExternalMuKey_boring.swift delete mode 100644 Sources/CryptoExtras/MLDSA/BoringSSL/MLDSA+ExternalMuKey_boring.swift.gyb diff --git a/Package.swift b/Package.swift index dc95be1f2..c4660c34f 100644 --- a/Package.swift +++ b/Package.swift @@ -171,7 +171,6 @@ let package = Package( "Key Agreement/ECDH.swift.gyb", "Signatures/ECDSA.swift.gyb", "Signatures/MLDSA.swift.gyb", - "Signatures/BoringSSL/MLDSA_boring.swift.gyb", "Signatures/BoringSSL/MLDSA+externalMu_boring.swift.gyb", "KEM/MLKEM.swift.gyb", "KEM/BoringSSL/MLKEM_boring.swift.gyb", @@ -209,7 +208,8 @@ let package = Package( "CCryptoBoringSSLShims", ], exclude: privacyManifestExclude + [ - "CMakeLists.txt" + "CMakeLists.txt", + "MLDSA/BoringSSLMLDSA.swift.gyb", ], resources: privacyManifestResource ), diff --git a/Sources/Crypto/Signatures/BoringSSL/MLDSA_wrapper.swift b/Sources/Crypto/Signatures/BoringSSL/MLDSA_wrapper.swift index 0860119e8..1ab91610e 100644 --- a/Sources/Crypto/Signatures/BoringSSL/MLDSA_wrapper.swift +++ b/Sources/Crypto/Signatures/BoringSSL/MLDSA_wrapper.swift @@ -16,6 +16,7 @@ @_exported import CryptoKit #else @_implementationOnly import CCryptoBoringSSL +import CryptoBoringWrapper #if canImport(FoundationEssentials) import FoundationEssentials #else @@ -65,27 +66,27 @@ protocol BoringSSLBackedMLDSAParameters { @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLDSA65: BoringSSLBackedMLDSAParameters { - typealias BackingPrivateKey = MLDSA65.InternalPrivateKey - typealias BackingPublicKey = MLDSA65.InternalPublicKey + typealias BackingPrivateKey = BoringSSLMLDSA65.InternalPrivateKey + typealias BackingPublicKey = BoringSSLMLDSA65.InternalPublicKey } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) extension MLDSA87: BoringSSLBackedMLDSAParameters { - typealias BackingPrivateKey = MLDSA87.InternalPrivateKey - typealias BackingPublicKey = MLDSA87.InternalPublicKey + typealias BackingPrivateKey = BoringSSLMLDSA87.InternalPrivateKey + typealias BackingPublicKey = BoringSSLMLDSA87.InternalPublicKey } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -extension MLDSA65.InternalPrivateKey: BoringSSLBackedMLDSAPrivateKey {} +extension BoringSSLMLDSA65.InternalPrivateKey: BoringSSLBackedMLDSAPrivateKey {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -extension MLDSA65.InternalPublicKey: BoringSSLBackedMLDSAPublicKey {} +extension BoringSSLMLDSA65.InternalPublicKey: BoringSSLBackedMLDSAPublicKey {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -extension MLDSA87.InternalPrivateKey: BoringSSLBackedMLDSAPrivateKey {} +extension BoringSSLMLDSA87.InternalPrivateKey: BoringSSLBackedMLDSAPrivateKey {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -extension MLDSA87.InternalPublicKey: BoringSSLBackedMLDSAPublicKey {} +extension BoringSSLMLDSA87.InternalPublicKey: BoringSSLBackedMLDSAPublicKey {} @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) struct OpenSSLMLDSAPrivateKeyImpl { @@ -145,7 +146,7 @@ struct OpenSSLMLDSAPrivateKeyImpl { } static var seedSize: Int { - MLDSA.seedByteCount + BoringSSLMLDSA.seedByteCount } } diff --git a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift b/Sources/CryptoBoringWrapper/MLDSA/BoringSSLMLDSA.swift similarity index 80% rename from Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift rename to Sources/CryptoBoringWrapper/MLDSA/BoringSSLMLDSA.swift index 77e16845e..d4ed3ed7e 100644 --- a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift +++ b/Sources/CryptoBoringWrapper/MLDSA/BoringSSLMLDSA.swift @@ -27,13 +27,16 @@ import Foundation // see section `gyb` in `README` for details. @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -extension MLDSA65 { +package enum BoringSSLMLDSA65: Sendable {} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension BoringSSLMLDSA65 { /// A ML-DSA-65 private key. - struct InternalPrivateKey: @unchecked Sendable { + package struct InternalPrivateKey: @unchecked Sendable { private var backing: Backing /// Initialize a ML-DSA-65 private key from a random seed. - init() throws { + package init() throws { self.backing = try Backing() } @@ -41,18 +44,18 @@ extension MLDSA65 { /// /// - Parameter seedRepresentation: The seed to use to generate the private key. /// - /// - Throws: `CryptoKitError.incorrectKeySize` if the seed is not 32 bytes long. - init(seedRepresentation: some DataProtocol) throws { + /// - Throws: `CryptoBoringWrapperError.incorrectKeySize` if the seed is not 32 bytes long. + package init(seedRepresentation: some DataProtocol) throws { self.backing = try Backing(seedRepresentation: seedRepresentation) } /// The seed from which this private key was generated. - var seedRepresentation: Data { + package var seedRepresentation: Data { self.backing.seed } /// The public key associated with this private key. - var publicKey: InternalPublicKey { + package var publicKey: InternalPublicKey { self.backing.publicKey } @@ -61,7 +64,7 @@ extension MLDSA65 { /// - Parameter data: The message to sign. /// /// - Returns: The signature of the message. - func signature(for data: D) throws -> Data { + package func signature(for data: D) throws -> Data { let context: Data? = nil return try self.backing.signature(for: data, context: context) } @@ -73,18 +76,18 @@ extension MLDSA65 { /// - context: The context to use for the signature. /// /// - Returns: The signature of the message. - func signature(for data: D, context: C) throws -> Data { + package func signature(for data: D, context: C) throws -> Data { try self.backing.signature(for: data, context: context) } /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). /// - /// > Note: The message representative should be obtained via calls to ``MLDSA65/PublicKey/prehash(for:context:)``. + /// > Note: The message representative should be obtained via calls to ``BoringSSLMLDSA65/PublicKey/prehash(for:context:)``. /// /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). /// /// - Returns: The signature of the prehashed message representative. - func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { + package func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { try self.backing.signature(forPrehashedMessageRepresentative: mu) } @@ -103,11 +106,11 @@ extension MLDSA65 { self.seed = try withUnsafeTemporaryAllocation( of: UInt8.self, - capacity: MLDSA.seedByteCount + capacity: BoringSSLMLDSA.seedByteCount ) { seedPtr in try withUnsafeTemporaryAllocation( of: UInt8.self, - capacity: MLDSA65.InternalPublicKey.Backing.byteCount + capacity: BoringSSLMLDSA65.InternalPublicKey.Backing.byteCount ) { publicKeyPtr in guard CCryptoBoringSSL_MLDSA65_generate_key( @@ -116,10 +119,10 @@ extension MLDSA65 { &self.key ) == 1 else { - throw CryptoKitError.internalBoringSSLError() + throw CryptoBoringWrapperError.internalBoringSSLError() } - return Data(bytes: seedPtr.baseAddress!, count: MLDSA.seedByteCount) + return Data(bytes: seedPtr.baseAddress!, count: BoringSSLMLDSA.seedByteCount) } } } @@ -128,10 +131,10 @@ extension MLDSA65 { /// /// - Parameter seedRepresentation: The seed to use to generate the private key. /// - /// - Throws: `CryptoKitError.incorrectKeySize` if the seed is not 32 bytes long. + /// - Throws: `CryptoBoringWrapperError.incorrectKeySize` if the seed is not 32 bytes long. init(seedRepresentation: some DataProtocol) throws { - guard seedRepresentation.count == MLDSA.seedByteCount else { - throw CryptoKitError.incorrectKeySize + guard seedRepresentation.count == BoringSSLMLDSA.seedByteCount else { + throw CryptoBoringWrapperError.incorrectKeySize } self.key = .init() @@ -142,11 +145,11 @@ extension MLDSA65 { CCryptoBoringSSL_MLDSA65_private_key_from_seed( &self.key, seedPtr.baseAddress, - MLDSA.seedByteCount + BoringSSLMLDSA.seedByteCount ) }) == 1 else { - throw CryptoKitError.internalBoringSSLError() + throw CryptoBoringWrapperError.internalBoringSSLError() } } @@ -163,7 +166,7 @@ extension MLDSA65 { /// /// - Returns: The signature of the message. func signature(for data: D, context: C?) throws -> Data { - var signature = Data(repeating: 0, count: MLDSA65.signatureByteCount) + var signature = Data(repeating: 0, count: BoringSSLMLDSA65.signatureByteCount) let rc: CInt = signature.withUnsafeMutableBytes { signaturePtr in let bytes: ContiguousBytes = data.regions.count == 1 ? data.regions.first! : Array(data) @@ -182,7 +185,7 @@ extension MLDSA65 { } guard rc == 1 else { - throw CryptoKitError.internalBoringSSLError() + throw CryptoBoringWrapperError.internalBoringSSLError() } return signature @@ -190,17 +193,17 @@ extension MLDSA65 { /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). /// - /// > Note: The message representative should be obtained via calls to ``MLDSA65/PublicKey/prehash(for:context:)``. + /// > Note: The message representative should be obtained via calls to ``BoringSSLMLDSA65/PublicKey/prehash(for:context:)``. /// /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). /// /// - Returns: The signature of the prehashed message representative. func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { - guard mu.count == MLDSA.muByteCount else { - throw CryptoKitError.incorrectParameterSize + guard mu.count == BoringSSLMLDSA.muByteCount else { + throw CryptoBoringWrapperError.incorrectParameterSize } - var signature = Data(repeating: 0, count: MLDSA65.signatureByteCount) + var signature = Data(repeating: 0, count: BoringSSLMLDSA65.signatureByteCount) let rc: CInt = signature.withUnsafeMutableBytes { signaturePtr in let muBytes: ContiguousBytes = mu.regions.count == 1 ? mu.regions.first! : Array(mu) @@ -214,7 +217,7 @@ extension MLDSA65 { } guard rc == 1 else { - throw CryptoKitError.internalBoringSSLError() + throw CryptoBoringWrapperError.internalBoringSSLError() } return signature @@ -227,9 +230,9 @@ extension MLDSA65 { } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -extension MLDSA65 { +extension BoringSSLMLDSA65 { /// A ML-DSA-65 public key. - struct InternalPublicKey: @unchecked Sendable { + package struct InternalPublicKey: @unchecked Sendable { private var backing: Backing fileprivate init(privateKeyBacking: InternalPrivateKey.Backing) { @@ -240,13 +243,13 @@ extension MLDSA65 { /// /// - Parameter rawRepresentation: The public key bytes. /// - /// - Throws: `CryptoKitError.incorrectKeySize` if the raw representation is not the correct size. - init(rawRepresentation: some DataProtocol) throws { + /// - Throws: `CryptoBoringWrapperError.incorrectKeySize` if the raw representation is not the correct size. + package init(rawRepresentation: some DataProtocol) throws { self.backing = try Backing(rawRepresentation: rawRepresentation) } /// The raw binary representation of the public key. - var rawRepresentation: Data { + package var rawRepresentation: Data { self.backing.rawRepresentation } @@ -257,7 +260,7 @@ extension MLDSA65 { /// - data: The message to verify the signature against. /// /// - Returns: `true` if the signature is valid, `false` otherwise. - func isValidSignature(_ signature: S, for data: D) -> Bool { + package func isValidSignature(_ signature: S, for data: D) -> Bool { let context: Data? = nil return self.backing.isValidSignature(signature, for: data, context: context) } @@ -270,7 +273,7 @@ extension MLDSA65 { /// - context: The context to use for the signature verification. /// /// - Returns: `true` if the signature is valid, `false` otherwise. - func isValidSignature( + package func isValidSignature( _ signature: S, for data: D, context: C @@ -283,7 +286,7 @@ extension MLDSA65 { /// - Parameter data: The message to prehash. /// /// - Returns: The prehashed message representative (a.k.a. "external mu"). - func prehash(for data: D) throws -> Data { + package func prehash(for data: D) throws -> Data { let context: Data? = nil return try self.backing.prehash(for: data, context: context) } @@ -295,7 +298,7 @@ extension MLDSA65 { /// - context: The context of the message. /// /// - Returns: The prehashed message representative (a.k.a. "external mu"). - func prehash(for data: D, context: C) throws -> Data { + package func prehash(for data: D, context: C) throws -> Data { try self.backing.prehash(for: data, context: context) } @@ -314,10 +317,10 @@ extension MLDSA65 { /// /// - Parameter rawRepresentation: The public key bytes. /// - /// - Throws: `CryptoKitError.incorrectKeySize` if the raw representation is not the correct size. + /// - Throws: `CryptoBoringWrapperError.incorrectKeySize` if the raw representation is not the correct size. init(rawRepresentation: some DataProtocol) throws { - guard rawRepresentation.count == MLDSA65.InternalPublicKey.Backing.byteCount else { - throw CryptoKitError.incorrectKeySize + guard rawRepresentation.count == BoringSSLMLDSA65.InternalPublicKey.Backing.byteCount else { + throw CryptoBoringWrapperError.incorrectKeySize } self.key = .init() @@ -330,7 +333,7 @@ extension MLDSA65 { try rawBuffer.withMemoryRebound(to: UInt8.self) { buffer in var cbs = CBS(data: buffer.baseAddress, len: buffer.count) guard CCryptoBoringSSL_MLDSA65_parse_public_key(&self.key, &cbs) == 1 else { - throw CryptoKitError.internalBoringSSLError() + throw CryptoBoringWrapperError.internalBoringSSLError() } } } @@ -340,7 +343,7 @@ extension MLDSA65 { var rawRepresentation: Data { var cbb = CBB() // The following BoringSSL functions can only fail on allocation failure, which we define as impossible. - CCryptoBoringSSL_CBB_init(&cbb, MLDSA65.InternalPublicKey.Backing.byteCount) + CCryptoBoringSSL_CBB_init(&cbb, BoringSSLMLDSA65.InternalPublicKey.Backing.byteCount) defer { CCryptoBoringSSL_CBB_cleanup(&cbb) } CCryptoBoringSSL_MLDSA65_marshal_public_key(&cbb, &self.key) return Data(bytes: CCryptoBoringSSL_CBB_data(&cbb), count: CCryptoBoringSSL_CBB_len(&cbb)) @@ -388,7 +391,7 @@ extension MLDSA65 { /// /// - Returns: The prehashed message representative (a.k.a. "external mu"). func prehash(for data: D, context: C?) throws -> Data { - var mu = Data(repeating: 0, count: MLDSA.muByteCount) + var mu = Data(repeating: 0, count: BoringSSLMLDSA.muByteCount) let dataBytes: ContiguousBytes = data.regions.count == 1 ? data.regions.first! : Array(data) let rc: CInt = mu.withUnsafeMutableBytes { muPtr in @@ -409,7 +412,7 @@ extension MLDSA65 { } guard rc == 1 else { - throw CryptoKitError.internalBoringSSLError() + throw CryptoBoringWrapperError.internalBoringSSLError() } return mu @@ -422,19 +425,22 @@ extension MLDSA65 { } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -extension MLDSA65 { +extension BoringSSLMLDSA65 { /// The size of the signature in bytes. private static let signatureByteCount = Int(MLDSA65_SIGNATURE_BYTES) } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -extension MLDSA87 { +package enum BoringSSLMLDSA87: Sendable {} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension BoringSSLMLDSA87 { /// A ML-DSA-87 private key. - struct InternalPrivateKey: @unchecked Sendable { + package struct InternalPrivateKey: @unchecked Sendable { private var backing: Backing /// Initialize a ML-DSA-87 private key from a random seed. - init() throws { + package init() throws { self.backing = try Backing() } @@ -442,18 +448,18 @@ extension MLDSA87 { /// /// - Parameter seedRepresentation: The seed to use to generate the private key. /// - /// - Throws: `CryptoKitError.incorrectKeySize` if the seed is not 32 bytes long. - init(seedRepresentation: some DataProtocol) throws { + /// - Throws: `CryptoBoringWrapperError.incorrectKeySize` if the seed is not 32 bytes long. + package init(seedRepresentation: some DataProtocol) throws { self.backing = try Backing(seedRepresentation: seedRepresentation) } /// The seed from which this private key was generated. - var seedRepresentation: Data { + package var seedRepresentation: Data { self.backing.seed } /// The public key associated with this private key. - var publicKey: InternalPublicKey { + package var publicKey: InternalPublicKey { self.backing.publicKey } @@ -462,7 +468,7 @@ extension MLDSA87 { /// - Parameter data: The message to sign. /// /// - Returns: The signature of the message. - func signature(for data: D) throws -> Data { + package func signature(for data: D) throws -> Data { let context: Data? = nil return try self.backing.signature(for: data, context: context) } @@ -474,18 +480,18 @@ extension MLDSA87 { /// - context: The context to use for the signature. /// /// - Returns: The signature of the message. - func signature(for data: D, context: C) throws -> Data { + package func signature(for data: D, context: C) throws -> Data { try self.backing.signature(for: data, context: context) } /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). /// - /// > Note: The message representative should be obtained via calls to ``MLDSA87/PublicKey/prehash(for:context:)``. + /// > Note: The message representative should be obtained via calls to ``BoringSSLMLDSA87/PublicKey/prehash(for:context:)``. /// /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). /// /// - Returns: The signature of the prehashed message representative. - func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { + package func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { try self.backing.signature(forPrehashedMessageRepresentative: mu) } @@ -504,11 +510,11 @@ extension MLDSA87 { self.seed = try withUnsafeTemporaryAllocation( of: UInt8.self, - capacity: MLDSA.seedByteCount + capacity: BoringSSLMLDSA.seedByteCount ) { seedPtr in try withUnsafeTemporaryAllocation( of: UInt8.self, - capacity: MLDSA87.InternalPublicKey.Backing.byteCount + capacity: BoringSSLMLDSA87.InternalPublicKey.Backing.byteCount ) { publicKeyPtr in guard CCryptoBoringSSL_MLDSA87_generate_key( @@ -517,10 +523,10 @@ extension MLDSA87 { &self.key ) == 1 else { - throw CryptoKitError.internalBoringSSLError() + throw CryptoBoringWrapperError.internalBoringSSLError() } - return Data(bytes: seedPtr.baseAddress!, count: MLDSA.seedByteCount) + return Data(bytes: seedPtr.baseAddress!, count: BoringSSLMLDSA.seedByteCount) } } } @@ -529,10 +535,10 @@ extension MLDSA87 { /// /// - Parameter seedRepresentation: The seed to use to generate the private key. /// - /// - Throws: `CryptoKitError.incorrectKeySize` if the seed is not 32 bytes long. + /// - Throws: `CryptoBoringWrapperError.incorrectKeySize` if the seed is not 32 bytes long. init(seedRepresentation: some DataProtocol) throws { - guard seedRepresentation.count == MLDSA.seedByteCount else { - throw CryptoKitError.incorrectKeySize + guard seedRepresentation.count == BoringSSLMLDSA.seedByteCount else { + throw CryptoBoringWrapperError.incorrectKeySize } self.key = .init() @@ -543,11 +549,11 @@ extension MLDSA87 { CCryptoBoringSSL_MLDSA87_private_key_from_seed( &self.key, seedPtr.baseAddress, - MLDSA.seedByteCount + BoringSSLMLDSA.seedByteCount ) }) == 1 else { - throw CryptoKitError.internalBoringSSLError() + throw CryptoBoringWrapperError.internalBoringSSLError() } } @@ -564,7 +570,7 @@ extension MLDSA87 { /// /// - Returns: The signature of the message. func signature(for data: D, context: C?) throws -> Data { - var signature = Data(repeating: 0, count: MLDSA87.signatureByteCount) + var signature = Data(repeating: 0, count: BoringSSLMLDSA87.signatureByteCount) let rc: CInt = signature.withUnsafeMutableBytes { signaturePtr in let bytes: ContiguousBytes = data.regions.count == 1 ? data.regions.first! : Array(data) @@ -583,7 +589,7 @@ extension MLDSA87 { } guard rc == 1 else { - throw CryptoKitError.internalBoringSSLError() + throw CryptoBoringWrapperError.internalBoringSSLError() } return signature @@ -591,17 +597,17 @@ extension MLDSA87 { /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). /// - /// > Note: The message representative should be obtained via calls to ``MLDSA87/PublicKey/prehash(for:context:)``. + /// > Note: The message representative should be obtained via calls to ``BoringSSLMLDSA87/PublicKey/prehash(for:context:)``. /// /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). /// /// - Returns: The signature of the prehashed message representative. func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { - guard mu.count == MLDSA.muByteCount else { - throw CryptoKitError.incorrectParameterSize + guard mu.count == BoringSSLMLDSA.muByteCount else { + throw CryptoBoringWrapperError.incorrectParameterSize } - var signature = Data(repeating: 0, count: MLDSA87.signatureByteCount) + var signature = Data(repeating: 0, count: BoringSSLMLDSA87.signatureByteCount) let rc: CInt = signature.withUnsafeMutableBytes { signaturePtr in let muBytes: ContiguousBytes = mu.regions.count == 1 ? mu.regions.first! : Array(mu) @@ -615,7 +621,7 @@ extension MLDSA87 { } guard rc == 1 else { - throw CryptoKitError.internalBoringSSLError() + throw CryptoBoringWrapperError.internalBoringSSLError() } return signature @@ -628,9 +634,9 @@ extension MLDSA87 { } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -extension MLDSA87 { +extension BoringSSLMLDSA87 { /// A ML-DSA-87 public key. - struct InternalPublicKey: @unchecked Sendable { + package struct InternalPublicKey: @unchecked Sendable { private var backing: Backing fileprivate init(privateKeyBacking: InternalPrivateKey.Backing) { @@ -641,13 +647,13 @@ extension MLDSA87 { /// /// - Parameter rawRepresentation: The public key bytes. /// - /// - Throws: `CryptoKitError.incorrectKeySize` if the raw representation is not the correct size. - init(rawRepresentation: some DataProtocol) throws { + /// - Throws: `CryptoBoringWrapperError.incorrectKeySize` if the raw representation is not the correct size. + package init(rawRepresentation: some DataProtocol) throws { self.backing = try Backing(rawRepresentation: rawRepresentation) } /// The raw binary representation of the public key. - var rawRepresentation: Data { + package var rawRepresentation: Data { self.backing.rawRepresentation } @@ -658,7 +664,7 @@ extension MLDSA87 { /// - data: The message to verify the signature against. /// /// - Returns: `true` if the signature is valid, `false` otherwise. - func isValidSignature(_ signature: S, for data: D) -> Bool { + package func isValidSignature(_ signature: S, for data: D) -> Bool { let context: Data? = nil return self.backing.isValidSignature(signature, for: data, context: context) } @@ -671,7 +677,7 @@ extension MLDSA87 { /// - context: The context to use for the signature verification. /// /// - Returns: `true` if the signature is valid, `false` otherwise. - func isValidSignature( + package func isValidSignature( _ signature: S, for data: D, context: C @@ -684,7 +690,7 @@ extension MLDSA87 { /// - Parameter data: The message to prehash. /// /// - Returns: The prehashed message representative (a.k.a. "external mu"). - func prehash(for data: D) throws -> Data { + package func prehash(for data: D) throws -> Data { let context: Data? = nil return try self.backing.prehash(for: data, context: context) } @@ -696,7 +702,7 @@ extension MLDSA87 { /// - context: The context of the message. /// /// - Returns: The prehashed message representative (a.k.a. "external mu"). - func prehash(for data: D, context: C) throws -> Data { + package func prehash(for data: D, context: C) throws -> Data { try self.backing.prehash(for: data, context: context) } @@ -715,10 +721,10 @@ extension MLDSA87 { /// /// - Parameter rawRepresentation: The public key bytes. /// - /// - Throws: `CryptoKitError.incorrectKeySize` if the raw representation is not the correct size. + /// - Throws: `CryptoBoringWrapperError.incorrectKeySize` if the raw representation is not the correct size. init(rawRepresentation: some DataProtocol) throws { - guard rawRepresentation.count == MLDSA87.InternalPublicKey.Backing.byteCount else { - throw CryptoKitError.incorrectKeySize + guard rawRepresentation.count == BoringSSLMLDSA87.InternalPublicKey.Backing.byteCount else { + throw CryptoBoringWrapperError.incorrectKeySize } self.key = .init() @@ -731,7 +737,7 @@ extension MLDSA87 { try rawBuffer.withMemoryRebound(to: UInt8.self) { buffer in var cbs = CBS(data: buffer.baseAddress, len: buffer.count) guard CCryptoBoringSSL_MLDSA87_parse_public_key(&self.key, &cbs) == 1 else { - throw CryptoKitError.internalBoringSSLError() + throw CryptoBoringWrapperError.internalBoringSSLError() } } } @@ -741,7 +747,7 @@ extension MLDSA87 { var rawRepresentation: Data { var cbb = CBB() // The following BoringSSL functions can only fail on allocation failure, which we define as impossible. - CCryptoBoringSSL_CBB_init(&cbb, MLDSA87.InternalPublicKey.Backing.byteCount) + CCryptoBoringSSL_CBB_init(&cbb, BoringSSLMLDSA87.InternalPublicKey.Backing.byteCount) defer { CCryptoBoringSSL_CBB_cleanup(&cbb) } CCryptoBoringSSL_MLDSA87_marshal_public_key(&cbb, &self.key) return Data(bytes: CCryptoBoringSSL_CBB_data(&cbb), count: CCryptoBoringSSL_CBB_len(&cbb)) @@ -789,7 +795,7 @@ extension MLDSA87 { /// /// - Returns: The prehashed message representative (a.k.a. "external mu"). func prehash(for data: D, context: C?) throws -> Data { - var mu = Data(repeating: 0, count: MLDSA.muByteCount) + var mu = Data(repeating: 0, count: BoringSSLMLDSA.muByteCount) let dataBytes: ContiguousBytes = data.regions.count == 1 ? data.regions.first! : Array(data) let rc: CInt = mu.withUnsafeMutableBytes { muPtr in @@ -810,7 +816,7 @@ extension MLDSA87 { } guard rc == 1 else { - throw CryptoKitError.internalBoringSSLError() + throw CryptoBoringWrapperError.internalBoringSSLError() } return mu @@ -823,14 +829,14 @@ extension MLDSA87 { } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -extension MLDSA87 { +extension BoringSSLMLDSA87 { /// The size of the signature in bytes. private static let signatureByteCount = Int(MLDSA87_SIGNATURE_BYTES) } -enum MLDSA { +package enum BoringSSLMLDSA { /// The size of the seed in bytes. - static let seedByteCount = 32 + package static let seedByteCount = 32 /// The size of the "mu" value in bytes. fileprivate static let muByteCount = 64 diff --git a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb b/Sources/CryptoBoringWrapper/MLDSA/BoringSSLMLDSA.swift.gyb similarity index 81% rename from Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb rename to Sources/CryptoBoringWrapper/MLDSA/BoringSSLMLDSA.swift.gyb index f59b32db0..0efa28fad 100644 --- a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb +++ b/Sources/CryptoBoringWrapper/MLDSA/BoringSSLMLDSA.swift.gyb @@ -31,13 +31,16 @@ import Foundation % for parameter_set in parameter_sets: @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -extension MLDSA${parameter_set} { +package enum BoringSSLMLDSA${parameter_set}: Sendable {} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension BoringSSLMLDSA${parameter_set} { /// A ML-DSA-${parameter_set} private key. - struct InternalPrivateKey: @unchecked Sendable { + package struct InternalPrivateKey: @unchecked Sendable { private var backing: Backing /// Initialize a ML-DSA-${parameter_set} private key from a random seed. - init() throws { + package init() throws { self.backing = try Backing() } @@ -45,18 +48,18 @@ extension MLDSA${parameter_set} { /// /// - Parameter seedRepresentation: The seed to use to generate the private key. /// - /// - Throws: `CryptoKitError.incorrectKeySize` if the seed is not 32 bytes long. - init(seedRepresentation: some DataProtocol) throws { + /// - Throws: `CryptoBoringWrapperError.incorrectKeySize` if the seed is not 32 bytes long. + package init(seedRepresentation: some DataProtocol) throws { self.backing = try Backing(seedRepresentation: seedRepresentation) } /// The seed from which this private key was generated. - var seedRepresentation: Data { + package var seedRepresentation: Data { self.backing.seed } /// The public key associated with this private key. - var publicKey: InternalPublicKey { + package var publicKey: InternalPublicKey { self.backing.publicKey } @@ -65,7 +68,7 @@ extension MLDSA${parameter_set} { /// - Parameter data: The message to sign. /// /// - Returns: The signature of the message. - func signature(for data: D) throws -> Data { + package func signature(for data: D) throws -> Data { let context: Data? = nil return try self.backing.signature(for: data, context: context) } @@ -77,18 +80,18 @@ extension MLDSA${parameter_set} { /// - context: The context to use for the signature. /// /// - Returns: The signature of the message. - func signature(for data: D, context: C) throws -> Data { + package func signature(for data: D, context: C) throws -> Data { try self.backing.signature(for: data, context: context) } /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). /// - /// > Note: The message representative should be obtained via calls to ``MLDSA${parameter_set}/PublicKey/prehash(for:context:)``. + /// > Note: The message representative should be obtained via calls to ``BoringSSLMLDSA${parameter_set}/PublicKey/prehash(for:context:)``. /// /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). /// /// - Returns: The signature of the prehashed message representative. - func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { + package func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { try self.backing.signature(forPrehashedMessageRepresentative: mu) } @@ -107,11 +110,11 @@ extension MLDSA${parameter_set} { self.seed = try withUnsafeTemporaryAllocation( of: UInt8.self, - capacity: MLDSA.seedByteCount + capacity: BoringSSLMLDSA.seedByteCount ) { seedPtr in try withUnsafeTemporaryAllocation( of: UInt8.self, - capacity: MLDSA${parameter_set}.InternalPublicKey.Backing.byteCount + capacity: BoringSSLMLDSA${parameter_set}.InternalPublicKey.Backing.byteCount ) { publicKeyPtr in guard CCryptoBoringSSL_MLDSA${parameter_set}_generate_key( @@ -120,10 +123,10 @@ extension MLDSA${parameter_set} { &self.key ) == 1 else { - throw CryptoKitError.internalBoringSSLError() + throw CryptoBoringWrapperError.internalBoringSSLError() } - return Data(bytes: seedPtr.baseAddress!, count: MLDSA.seedByteCount) + return Data(bytes: seedPtr.baseAddress!, count: BoringSSLMLDSA.seedByteCount) } } } @@ -132,10 +135,10 @@ extension MLDSA${parameter_set} { /// /// - Parameter seedRepresentation: The seed to use to generate the private key. /// - /// - Throws: `CryptoKitError.incorrectKeySize` if the seed is not 32 bytes long. + /// - Throws: `CryptoBoringWrapperError.incorrectKeySize` if the seed is not 32 bytes long. init(seedRepresentation: some DataProtocol) throws { - guard seedRepresentation.count == MLDSA.seedByteCount else { - throw CryptoKitError.incorrectKeySize + guard seedRepresentation.count == BoringSSLMLDSA.seedByteCount else { + throw CryptoBoringWrapperError.incorrectKeySize } self.key = .init() @@ -146,11 +149,11 @@ extension MLDSA${parameter_set} { CCryptoBoringSSL_MLDSA${parameter_set}_private_key_from_seed( &self.key, seedPtr.baseAddress, - MLDSA.seedByteCount + BoringSSLMLDSA.seedByteCount ) }) == 1 else { - throw CryptoKitError.internalBoringSSLError() + throw CryptoBoringWrapperError.internalBoringSSLError() } } @@ -167,7 +170,7 @@ extension MLDSA${parameter_set} { /// /// - Returns: The signature of the message. func signature(for data: D, context: C?) throws -> Data { - var signature = Data(repeating: 0, count: MLDSA${parameter_set}.signatureByteCount) + var signature = Data(repeating: 0, count: BoringSSLMLDSA${parameter_set}.signatureByteCount) let rc: CInt = signature.withUnsafeMutableBytes { signaturePtr in let bytes: ContiguousBytes = data.regions.count == 1 ? data.regions.first! : Array(data) @@ -186,7 +189,7 @@ extension MLDSA${parameter_set} { } guard rc == 1 else { - throw CryptoKitError.internalBoringSSLError() + throw CryptoBoringWrapperError.internalBoringSSLError() } return signature @@ -194,17 +197,17 @@ extension MLDSA${parameter_set} { /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). /// - /// > Note: The message representative should be obtained via calls to ``MLDSA${parameter_set}/PublicKey/prehash(for:context:)``. + /// > Note: The message representative should be obtained via calls to ``BoringSSLMLDSA${parameter_set}/PublicKey/prehash(for:context:)``. /// /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). /// /// - Returns: The signature of the prehashed message representative. func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { - guard mu.count == MLDSA.muByteCount else { - throw CryptoKitError.incorrectParameterSize + guard mu.count == BoringSSLMLDSA.muByteCount else { + throw CryptoBoringWrapperError.incorrectParameterSize } - var signature = Data(repeating: 0, count: MLDSA${parameter_set}.signatureByteCount) + var signature = Data(repeating: 0, count: BoringSSLMLDSA${parameter_set}.signatureByteCount) let rc: CInt = signature.withUnsafeMutableBytes { signaturePtr in let muBytes: ContiguousBytes = mu.regions.count == 1 ? mu.regions.first! : Array(mu) @@ -218,7 +221,7 @@ extension MLDSA${parameter_set} { } guard rc == 1 else { - throw CryptoKitError.internalBoringSSLError() + throw CryptoBoringWrapperError.internalBoringSSLError() } return signature @@ -231,9 +234,9 @@ extension MLDSA${parameter_set} { } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -extension MLDSA${parameter_set} { +extension BoringSSLMLDSA${parameter_set} { /// A ML-DSA-${parameter_set} public key. - struct InternalPublicKey: @unchecked Sendable { + package struct InternalPublicKey: @unchecked Sendable { private var backing: Backing fileprivate init(privateKeyBacking: InternalPrivateKey.Backing) { @@ -244,13 +247,13 @@ extension MLDSA${parameter_set} { /// /// - Parameter rawRepresentation: The public key bytes. /// - /// - Throws: `CryptoKitError.incorrectKeySize` if the raw representation is not the correct size. - init(rawRepresentation: some DataProtocol) throws { + /// - Throws: `CryptoBoringWrapperError.incorrectKeySize` if the raw representation is not the correct size. + package init(rawRepresentation: some DataProtocol) throws { self.backing = try Backing(rawRepresentation: rawRepresentation) } /// The raw binary representation of the public key. - var rawRepresentation: Data { + package var rawRepresentation: Data { self.backing.rawRepresentation } @@ -261,7 +264,7 @@ extension MLDSA${parameter_set} { /// - data: The message to verify the signature against. /// /// - Returns: `true` if the signature is valid, `false` otherwise. - func isValidSignature(_ signature: S, for data: D) -> Bool { + package func isValidSignature(_ signature: S, for data: D) -> Bool { let context: Data? = nil return self.backing.isValidSignature(signature, for: data, context: context) } @@ -274,7 +277,7 @@ extension MLDSA${parameter_set} { /// - context: The context to use for the signature verification. /// /// - Returns: `true` if the signature is valid, `false` otherwise. - func isValidSignature( + package func isValidSignature( _ signature: S, for data: D, context: C @@ -287,7 +290,7 @@ extension MLDSA${parameter_set} { /// - Parameter data: The message to prehash. /// /// - Returns: The prehashed message representative (a.k.a. "external mu"). - func prehash(for data: D) throws -> Data { + package func prehash(for data: D) throws -> Data { let context: Data? = nil return try self.backing.prehash(for: data, context: context) } @@ -299,7 +302,7 @@ extension MLDSA${parameter_set} { /// - context: The context of the message. /// /// - Returns: The prehashed message representative (a.k.a. "external mu"). - func prehash(for data: D, context: C) throws -> Data { + package func prehash(for data: D, context: C) throws -> Data { try self.backing.prehash(for: data, context: context) } @@ -318,10 +321,10 @@ extension MLDSA${parameter_set} { /// /// - Parameter rawRepresentation: The public key bytes. /// - /// - Throws: `CryptoKitError.incorrectKeySize` if the raw representation is not the correct size. + /// - Throws: `CryptoBoringWrapperError.incorrectKeySize` if the raw representation is not the correct size. init(rawRepresentation: some DataProtocol) throws { - guard rawRepresentation.count == MLDSA${parameter_set}.InternalPublicKey.Backing.byteCount else { - throw CryptoKitError.incorrectKeySize + guard rawRepresentation.count == BoringSSLMLDSA${parameter_set}.InternalPublicKey.Backing.byteCount else { + throw CryptoBoringWrapperError.incorrectKeySize } self.key = .init() @@ -334,7 +337,7 @@ extension MLDSA${parameter_set} { try rawBuffer.withMemoryRebound(to: UInt8.self) { buffer in var cbs = CBS(data: buffer.baseAddress, len: buffer.count) guard CCryptoBoringSSL_MLDSA${parameter_set}_parse_public_key(&self.key, &cbs) == 1 else { - throw CryptoKitError.internalBoringSSLError() + throw CryptoBoringWrapperError.internalBoringSSLError() } } } @@ -344,7 +347,7 @@ extension MLDSA${parameter_set} { var rawRepresentation: Data { var cbb = CBB() // The following BoringSSL functions can only fail on allocation failure, which we define as impossible. - CCryptoBoringSSL_CBB_init(&cbb, MLDSA${parameter_set}.InternalPublicKey.Backing.byteCount) + CCryptoBoringSSL_CBB_init(&cbb, BoringSSLMLDSA${parameter_set}.InternalPublicKey.Backing.byteCount) defer { CCryptoBoringSSL_CBB_cleanup(&cbb) } CCryptoBoringSSL_MLDSA${parameter_set}_marshal_public_key(&cbb, &self.key) return Data(bytes: CCryptoBoringSSL_CBB_data(&cbb), count: CCryptoBoringSSL_CBB_len(&cbb)) @@ -392,7 +395,7 @@ extension MLDSA${parameter_set} { /// /// - Returns: The prehashed message representative (a.k.a. "external mu"). func prehash(for data: D, context: C?) throws -> Data { - var mu = Data(repeating: 0, count: MLDSA.muByteCount) + var mu = Data(repeating: 0, count: BoringSSLMLDSA.muByteCount) let dataBytes: ContiguousBytes = data.regions.count == 1 ? data.regions.first! : Array(data) let rc: CInt = mu.withUnsafeMutableBytes { muPtr in @@ -413,7 +416,7 @@ extension MLDSA${parameter_set} { } guard rc == 1 else { - throw CryptoKitError.internalBoringSSLError() + throw CryptoBoringWrapperError.internalBoringSSLError() } return mu @@ -426,15 +429,15 @@ extension MLDSA${parameter_set} { } @available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -extension MLDSA${parameter_set} { +extension BoringSSLMLDSA${parameter_set} { /// The size of the signature in bytes. private static let signatureByteCount = Int(MLDSA${parameter_set}_SIGNATURE_BYTES) } % end -enum MLDSA { +package enum BoringSSLMLDSA { /// The size of the seed in bytes. - static let seedByteCount = 32 + package static let seedByteCount = 32 /// The size of the "mu" value in bytes. fileprivate static let muByteCount = 64 diff --git a/Sources/Crypto/Util/BoringSSL/Optional+withUnsafeBytes_boring.swift b/Sources/CryptoBoringWrapper/Util/Optional+withUnsafeBytes.swift similarity index 100% rename from Sources/Crypto/Util/BoringSSL/Optional+withUnsafeBytes_boring.swift rename to Sources/CryptoBoringWrapper/Util/Optional+withUnsafeBytes.swift diff --git a/Sources/CryptoExtras/MLDSA/BoringSSL/MLDSA+ExternalMuKey_boring.swift b/Sources/CryptoExtras/MLDSA/BoringSSL/MLDSA+ExternalMuKey_boring.swift deleted file mode 100644 index aecf09513..000000000 --- a/Sources/CryptoExtras/MLDSA/BoringSSL/MLDSA+ExternalMuKey_boring.swift +++ /dev/null @@ -1,316 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the SwiftCrypto open source project -// -// Copyright (c) 2025 Apple Inc. and the SwiftCrypto project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -// MARK: - Generated file, do NOT edit -// any edits of this file WILL be overwritten and thus discarded -// see section `gyb` in `README` for details. - -#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API - -@_implementationOnly import CCryptoBoringSSL -import Crypto - -#if canImport(FoundationEssentials) -import FoundationEssentials -#else -import Foundation -#endif - -@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, macCatalyst 26.0, visionOS 26.0, *) -extension MLDSA65.PrivateKey { - struct ExternalMuPrivateKey: @unchecked Sendable { - private var backing: Backing - - init(seedRepresentation: some DataProtocol) throws { - self.backing = try Backing(seedRepresentation: seedRepresentation) - } - - func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { - try self.backing.signature(forPrehashedMessageRepresentative: mu) - } - - fileprivate final class Backing { - fileprivate var key: MLDSA65_private_key - - init(seedRepresentation: some DataProtocol) throws { - guard seedRepresentation.count == MLDSA.seedByteCount else { - throw CryptoKitError.incorrectKeySize - } - - self.key = .init() - - guard - Data(seedRepresentation).withUnsafeBytes({ seedPtr in - CCryptoBoringSSL_MLDSA65_private_key_from_seed( - &self.key, - seedPtr.baseAddress, - MLDSA.seedByteCount - ) - }) == 1 - else { - throw CryptoKitError.internalBoringSSLError() - } - } - - func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { - guard mu.count == MLDSA.muByteCount else { - throw CryptoKitError.incorrectParameterSize - } - - var signature = Data(repeating: 0, count: Int(MLDSA65_SIGNATURE_BYTES)) - - let rc: CInt = signature.withUnsafeMutableBytes { signaturePtr in - let muBytes: ContiguousBytes = mu.regions.count == 1 ? mu.regions.first! : Array(mu) - return muBytes.withUnsafeBytes { muPtr in - CCryptoBoringSSL_MLDSA65_sign_message_representative( - signaturePtr.baseAddress, - &self.key, - muPtr.baseAddress - ) - } - } - - guard rc == 1 else { - throw CryptoKitError.internalBoringSSLError() - } - - return signature - } - } - } -} - -@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, macCatalyst 26.0, visionOS 26.0, *) -extension MLDSA65.PublicKey { - struct ExternalMuPublicKey: @unchecked Sendable { - private var backing: Backing - - init(rawRepresentation: some DataProtocol) throws { - self.backing = try Backing(rawRepresentation: rawRepresentation) - } - - func prehash(for data: D) throws -> Data { - let context: Data? = nil - return try self.backing.prehash(for: data, context: context) - } - - func prehash(for data: D, context: C) throws -> Data { - try self.backing.prehash(for: data, context: context) - } - - fileprivate final class Backing { - private var key: MLDSA65_public_key - - init(rawRepresentation: some DataProtocol) throws { - guard rawRepresentation.count == Self.byteCount else { - throw CryptoKitError.incorrectKeySize - } - - self.key = .init() - - let bytes: ContiguousBytes = - rawRepresentation.regions.count == 1 - ? rawRepresentation.regions.first! - : Array(rawRepresentation) - try bytes.withUnsafeBytes { rawBuffer in - try rawBuffer.withMemoryRebound(to: UInt8.self) { buffer in - var cbs = CBS(data: buffer.baseAddress, len: buffer.count) - guard CCryptoBoringSSL_MLDSA65_parse_public_key(&self.key, &cbs) == 1 else { - throw CryptoKitError.internalBoringSSLError() - } - } - } - } - - func prehash(for data: D, context: C?) throws -> Data { - var mu = Data(repeating: 0, count: MLDSA.muByteCount) - - let dataBytes: ContiguousBytes = data.regions.count == 1 ? data.regions.first! : Array(data) - let rc: CInt = mu.withUnsafeMutableBytes { muPtr in - dataBytes.withUnsafeBytes { dataPtr in - context.withUnsafeBytes { contextPtr in - var prehash = MLDSA65_prehash() - let rc = CCryptoBoringSSL_MLDSA65_prehash_init( - &prehash, - &key, - contextPtr.baseAddress, - contextPtr.count - ) - CCryptoBoringSSL_MLDSA65_prehash_update(&prehash, dataPtr.baseAddress, dataPtr.count) - CCryptoBoringSSL_MLDSA65_prehash_finalize(muPtr.baseAddress, &prehash) - return rc - } - } - } - - guard rc == 1 else { - throw CryptoKitError.internalBoringSSLError() - } - - return mu - } - - static let byteCount = Int(MLDSA65_PUBLIC_KEY_BYTES) - } - } -} - -@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, macCatalyst 26.0, visionOS 26.0, *) -extension MLDSA87.PrivateKey { - struct ExternalMuPrivateKey: @unchecked Sendable { - private var backing: Backing - - init(seedRepresentation: some DataProtocol) throws { - self.backing = try Backing(seedRepresentation: seedRepresentation) - } - - func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { - try self.backing.signature(forPrehashedMessageRepresentative: mu) - } - - fileprivate final class Backing { - fileprivate var key: MLDSA87_private_key - - init(seedRepresentation: some DataProtocol) throws { - guard seedRepresentation.count == MLDSA.seedByteCount else { - throw CryptoKitError.incorrectKeySize - } - - self.key = .init() - - guard - Data(seedRepresentation).withUnsafeBytes({ seedPtr in - CCryptoBoringSSL_MLDSA87_private_key_from_seed( - &self.key, - seedPtr.baseAddress, - MLDSA.seedByteCount - ) - }) == 1 - else { - throw CryptoKitError.internalBoringSSLError() - } - } - - func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { - guard mu.count == MLDSA.muByteCount else { - throw CryptoKitError.incorrectParameterSize - } - - var signature = Data(repeating: 0, count: Int(MLDSA87_SIGNATURE_BYTES)) - - let rc: CInt = signature.withUnsafeMutableBytes { signaturePtr in - let muBytes: ContiguousBytes = mu.regions.count == 1 ? mu.regions.first! : Array(mu) - return muBytes.withUnsafeBytes { muPtr in - CCryptoBoringSSL_MLDSA87_sign_message_representative( - signaturePtr.baseAddress, - &self.key, - muPtr.baseAddress - ) - } - } - - guard rc == 1 else { - throw CryptoKitError.internalBoringSSLError() - } - - return signature - } - } - } -} - -@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, macCatalyst 26.0, visionOS 26.0, *) -extension MLDSA87.PublicKey { - struct ExternalMuPublicKey: @unchecked Sendable { - private var backing: Backing - - init(rawRepresentation: some DataProtocol) throws { - self.backing = try Backing(rawRepresentation: rawRepresentation) - } - - func prehash(for data: D) throws -> Data { - let context: Data? = nil - return try self.backing.prehash(for: data, context: context) - } - - func prehash(for data: D, context: C) throws -> Data { - try self.backing.prehash(for: data, context: context) - } - - fileprivate final class Backing { - private var key: MLDSA87_public_key - - init(rawRepresentation: some DataProtocol) throws { - guard rawRepresentation.count == Self.byteCount else { - throw CryptoKitError.incorrectKeySize - } - - self.key = .init() - - let bytes: ContiguousBytes = - rawRepresentation.regions.count == 1 - ? rawRepresentation.regions.first! - : Array(rawRepresentation) - try bytes.withUnsafeBytes { rawBuffer in - try rawBuffer.withMemoryRebound(to: UInt8.self) { buffer in - var cbs = CBS(data: buffer.baseAddress, len: buffer.count) - guard CCryptoBoringSSL_MLDSA87_parse_public_key(&self.key, &cbs) == 1 else { - throw CryptoKitError.internalBoringSSLError() - } - } - } - } - - func prehash(for data: D, context: C?) throws -> Data { - var mu = Data(repeating: 0, count: MLDSA.muByteCount) - - let dataBytes: ContiguousBytes = data.regions.count == 1 ? data.regions.first! : Array(data) - let rc: CInt = mu.withUnsafeMutableBytes { muPtr in - dataBytes.withUnsafeBytes { dataPtr in - context.withUnsafeBytes { contextPtr in - var prehash = MLDSA87_prehash() - let rc = CCryptoBoringSSL_MLDSA87_prehash_init( - &prehash, - &key, - contextPtr.baseAddress, - contextPtr.count - ) - CCryptoBoringSSL_MLDSA87_prehash_update(&prehash, dataPtr.baseAddress, dataPtr.count) - CCryptoBoringSSL_MLDSA87_prehash_finalize(muPtr.baseAddress, &prehash) - return rc - } - } - } - - guard rc == 1 else { - throw CryptoKitError.internalBoringSSLError() - } - - return mu - } - - static let byteCount = Int(MLDSA87_PUBLIC_KEY_BYTES) - } - } -} - -enum MLDSA { - /// The size of the seed in bytes. - static let seedByteCount = 32 - - /// The size of the "mu" value in bytes. - fileprivate static let muByteCount = 64 -} - -#endif diff --git a/Sources/CryptoExtras/MLDSA/BoringSSL/MLDSA+ExternalMuKey_boring.swift.gyb b/Sources/CryptoExtras/MLDSA/BoringSSL/MLDSA+ExternalMuKey_boring.swift.gyb deleted file mode 100644 index 6e1738512..000000000 --- a/Sources/CryptoExtras/MLDSA/BoringSSL/MLDSA+ExternalMuKey_boring.swift.gyb +++ /dev/null @@ -1,182 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the SwiftCrypto open source project -// -// Copyright (c) 2025 Apple Inc. and the SwiftCrypto project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -// MARK: - Generated file, do NOT edit -// any edits of this file WILL be overwritten and thus discarded -// see section `gyb` in `README` for details. - -#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API - -@_implementationOnly import CCryptoBoringSSL -import Crypto - -#if canImport(FoundationEssentials) -import FoundationEssentials -#else -import Foundation -#endif -%{ - parameter_sets = ["65", "87"] -}% -% for parameter_set in parameter_sets: - -@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, macCatalyst 26.0, visionOS 26.0, *) -extension MLDSA${parameter_set}.PrivateKey { - struct ExternalMuPrivateKey: @unchecked Sendable { - private var backing: Backing - - init(seedRepresentation: some DataProtocol) throws { - self.backing = try Backing(seedRepresentation: seedRepresentation) - } - - func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { - try self.backing.signature(forPrehashedMessageRepresentative: mu) - } - - fileprivate final class Backing { - fileprivate var key: MLDSA${parameter_set}_private_key - - init(seedRepresentation: some DataProtocol) throws { - guard seedRepresentation.count == MLDSA.seedByteCount else { - throw CryptoKitError.incorrectKeySize - } - - self.key = .init() - - guard - Data(seedRepresentation).withUnsafeBytes({ seedPtr in - CCryptoBoringSSL_MLDSA${parameter_set}_private_key_from_seed( - &self.key, - seedPtr.baseAddress, - MLDSA.seedByteCount - ) - }) == 1 - else { - throw CryptoKitError.internalBoringSSLError() - } - } - - func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { - guard mu.count == MLDSA.muByteCount else { - throw CryptoKitError.incorrectParameterSize - } - - var signature = Data(repeating: 0, count: Int(MLDSA${parameter_set}_SIGNATURE_BYTES)) - - let rc: CInt = signature.withUnsafeMutableBytes { signaturePtr in - let muBytes: ContiguousBytes = mu.regions.count == 1 ? mu.regions.first! : Array(mu) - return muBytes.withUnsafeBytes { muPtr in - CCryptoBoringSSL_MLDSA${parameter_set}_sign_message_representative( - signaturePtr.baseAddress, - &self.key, - muPtr.baseAddress - ) - } - } - - guard rc == 1 else { - throw CryptoKitError.internalBoringSSLError() - } - - return signature - } - } - } -} - -@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, macCatalyst 26.0, visionOS 26.0, *) -extension MLDSA${parameter_set}.PublicKey { - struct ExternalMuPublicKey: @unchecked Sendable { - private var backing: Backing - - init(rawRepresentation: some DataProtocol) throws { - self.backing = try Backing(rawRepresentation: rawRepresentation) - } - - func prehash(for data: D) throws -> Data { - let context: Data? = nil - return try self.backing.prehash(for: data, context: context) - } - - func prehash(for data: D, context: C) throws -> Data { - try self.backing.prehash(for: data, context: context) - } - - fileprivate final class Backing { - private var key: MLDSA${parameter_set}_public_key - - init(rawRepresentation: some DataProtocol) throws { - guard rawRepresentation.count == Self.byteCount else { - throw CryptoKitError.incorrectKeySize - } - - self.key = .init() - - let bytes: ContiguousBytes = - rawRepresentation.regions.count == 1 - ? rawRepresentation.regions.first! - : Array(rawRepresentation) - try bytes.withUnsafeBytes { rawBuffer in - try rawBuffer.withMemoryRebound(to: UInt8.self) { buffer in - var cbs = CBS(data: buffer.baseAddress, len: buffer.count) - guard CCryptoBoringSSL_MLDSA${parameter_set}_parse_public_key(&self.key, &cbs) == 1 else { - throw CryptoKitError.internalBoringSSLError() - } - } - } - } - - func prehash(for data: D, context: C?) throws -> Data { - var mu = Data(repeating: 0, count: MLDSA.muByteCount) - - let dataBytes: ContiguousBytes = data.regions.count == 1 ? data.regions.first! : Array(data) - let rc: CInt = mu.withUnsafeMutableBytes { muPtr in - dataBytes.withUnsafeBytes { dataPtr in - context.withUnsafeBytes { contextPtr in - var prehash = MLDSA${parameter_set}_prehash() - let rc = CCryptoBoringSSL_MLDSA${parameter_set}_prehash_init( - &prehash, - &key, - contextPtr.baseAddress, - contextPtr.count - ) - CCryptoBoringSSL_MLDSA${parameter_set}_prehash_update(&prehash, dataPtr.baseAddress, dataPtr.count) - CCryptoBoringSSL_MLDSA${parameter_set}_prehash_finalize(muPtr.baseAddress, &prehash) - return rc - } - } - } - - guard rc == 1 else { - throw CryptoKitError.internalBoringSSLError() - } - - return mu - } - - static let byteCount = Int(MLDSA${parameter_set}_PUBLIC_KEY_BYTES) - } - } -} -% end - -enum MLDSA { - /// The size of the seed in bytes. - static let seedByteCount = 32 - - /// The size of the "mu" value in bytes. - fileprivate static let muByteCount = 64 -} - -#endif diff --git a/Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift b/Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift index 67d9984a4..ba0d555ba 100644 --- a/Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift +++ b/Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift @@ -17,6 +17,7 @@ // see section `gyb` in `README` for details. import Crypto +import CryptoBoringWrapper #if canImport(FoundationEssentials) import FoundationEssentials @@ -35,7 +36,7 @@ extension MLDSA65.PrivateKey { /// - Returns: The signature of the prehashed message representative. public func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API - try ExternalMuPrivateKey(seedRepresentation: self.seedRepresentation) + try BoringSSLMLDSA65.InternalPrivateKey(seedRepresentation: self.seedRepresentation) .signature(forPrehashedMessageRepresentative: mu) #else try self.signature_boring(forPrehashedMessageRepresentative: mu) @@ -52,7 +53,7 @@ extension MLDSA65.PublicKey { /// - Returns: The prehashed message representative (a.k.a. "external mu"). public func prehash(for data: D) throws -> Data { #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API - try ExternalMuPublicKey(rawRepresentation: self.rawRepresentation) + try BoringSSLMLDSA65.InternalPublicKey(rawRepresentation: self.rawRepresentation) .prehash(for: data) #else try self.prehash_boring(for: data) @@ -68,7 +69,7 @@ extension MLDSA65.PublicKey { /// - Returns: The prehashed message representative (a.k.a. "external mu"). public func prehash(for data: D, context: C) throws -> Data { #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API - try ExternalMuPublicKey(rawRepresentation: self.rawRepresentation) + try BoringSSLMLDSA65.InternalPublicKey(rawRepresentation: self.rawRepresentation) .prehash(for: data, context: context) #else try self.prehash_boring(for: data, context: context) @@ -87,7 +88,7 @@ extension MLDSA87.PrivateKey { /// - Returns: The signature of the prehashed message representative. public func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API - try ExternalMuPrivateKey(seedRepresentation: self.seedRepresentation) + try BoringSSLMLDSA87.InternalPrivateKey(seedRepresentation: self.seedRepresentation) .signature(forPrehashedMessageRepresentative: mu) #else try self.signature_boring(forPrehashedMessageRepresentative: mu) @@ -104,7 +105,7 @@ extension MLDSA87.PublicKey { /// - Returns: The prehashed message representative (a.k.a. "external mu"). public func prehash(for data: D) throws -> Data { #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API - try ExternalMuPublicKey(rawRepresentation: self.rawRepresentation) + try BoringSSLMLDSA87.InternalPublicKey(rawRepresentation: self.rawRepresentation) .prehash(for: data) #else try self.prehash_boring(for: data) @@ -120,7 +121,7 @@ extension MLDSA87.PublicKey { /// - Returns: The prehashed message representative (a.k.a. "external mu"). public func prehash(for data: D, context: C) throws -> Data { #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API - try ExternalMuPublicKey(rawRepresentation: self.rawRepresentation) + try BoringSSLMLDSA87.InternalPublicKey(rawRepresentation: self.rawRepresentation) .prehash(for: data, context: context) #else try self.prehash_boring(for: data, context: context) diff --git a/Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb b/Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb index 892cec6b7..daa9a4d6a 100644 --- a/Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb +++ b/Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb @@ -17,6 +17,7 @@ // see section `gyb` in `README` for details. import Crypto +import CryptoBoringWrapper #if canImport(FoundationEssentials) import FoundationEssentials @@ -39,7 +40,7 @@ extension MLDSA${parameter_set}.PrivateKey { /// - Returns: The signature of the prehashed message representative. public func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API - try ExternalMuPrivateKey(seedRepresentation: self.seedRepresentation) + try BoringSSLMLDSA${parameter_set}.InternalPrivateKey(seedRepresentation: self.seedRepresentation) .signature(forPrehashedMessageRepresentative: mu) #else try self.signature_boring(forPrehashedMessageRepresentative: mu) @@ -56,7 +57,7 @@ extension MLDSA${parameter_set}.PublicKey { /// - Returns: The prehashed message representative (a.k.a. "external mu"). public func prehash(for data: D) throws -> Data { #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API - try ExternalMuPublicKey(rawRepresentation: self.rawRepresentation) + try BoringSSLMLDSA${parameter_set}.InternalPublicKey(rawRepresentation: self.rawRepresentation) .prehash(for: data) #else try self.prehash_boring(for: data) @@ -72,7 +73,7 @@ extension MLDSA${parameter_set}.PublicKey { /// - Returns: The prehashed message representative (a.k.a. "external mu"). public func prehash(for data: D, context: C) throws -> Data { #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API - try ExternalMuPublicKey(rawRepresentation: self.rawRepresentation) + try BoringSSLMLDSA${parameter_set}.InternalPublicKey(rawRepresentation: self.rawRepresentation) .prehash(for: data, context: context) #else try self.prehash_boring(for: data, context: context) From 97f7ce6de4b7b8cccfa001feb4ce5b4589838207 Mon Sep 17 00:00:00 2001 From: Francesco Paolo Severino Date: Tue, 16 Sep 2025 18:49:09 +0200 Subject: [PATCH 39/47] Update CMakeLists --- Sources/Crypto/CMakeLists.txt | 2 -- Sources/CryptoBoringWrapper/CMakeLists.txt | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/Crypto/CMakeLists.txt b/Sources/Crypto/CMakeLists.txt index c8d9df809..f8bc0fc52 100644 --- a/Sources/Crypto/CMakeLists.txt +++ b/Sources/Crypto/CMakeLists.txt @@ -92,14 +92,12 @@ add_library(Crypto "Signatures/BoringSSL/ECDSA_boring.swift" "Signatures/BoringSSL/EdDSA_boring.swift" "Signatures/BoringSSL/MLDSA+externalMu_boring.swift" - "Signatures/BoringSSL/MLDSA_boring.swift" "Signatures/BoringSSL/MLDSA_wrapper.swift" "Signatures/ECDSA.swift" "Signatures/Ed25519.swift" "Signatures/MLDSA.swift" "Signatures/Signature.swift" "Util/BoringSSL/CryptoKitErrors_boring.swift" - "Util/BoringSSL/Optional+withUnsafeBytes_boring.swift" "Util/BoringSSL/RNG_boring.swift" "Util/BoringSSL/SafeCompare_boring.swift" "Util/BoringSSL/Zeroization_boring.swift" diff --git a/Sources/CryptoBoringWrapper/CMakeLists.txt b/Sources/CryptoBoringWrapper/CMakeLists.txt index 980f33c4d..201a0357d 100644 --- a/Sources/CryptoBoringWrapper/CMakeLists.txt +++ b/Sources/CryptoBoringWrapper/CMakeLists.txt @@ -17,8 +17,10 @@ add_library(CryptoBoringWrapper STATIC "CryptoKitErrors_boring.swift" "EC/EllipticCurve.swift" "EC/EllipticCurvePoint.swift" + "MLDSA/BoringSSLMLDSA.swift" "Util/ArbitraryPrecisionInteger.swift" "Util/FiniteFieldArithmeticContext.swift" + "Util/Optional+withUnsafeBytes.swift" "Util/RandomBytes.swift" ) From 1d8298356ae82f8c67ba0775e949a4d4afce7ba7 Mon Sep 17 00:00:00 2001 From: Francesco Paolo Severino Date: Wed, 17 Sep 2025 11:06:27 +0200 Subject: [PATCH 40/47] Remove flag checks in CryptoBoringWrapper --- Sources/CryptoBoringWrapper/MLDSA/BoringSSLMLDSA.swift | 6 +----- Sources/CryptoBoringWrapper/MLDSA/BoringSSLMLDSA.swift.gyb | 6 +----- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/Sources/CryptoBoringWrapper/MLDSA/BoringSSLMLDSA.swift b/Sources/CryptoBoringWrapper/MLDSA/BoringSSLMLDSA.swift index d4ed3ed7e..a342a06aa 100644 --- a/Sources/CryptoBoringWrapper/MLDSA/BoringSSLMLDSA.swift +++ b/Sources/CryptoBoringWrapper/MLDSA/BoringSSLMLDSA.swift @@ -12,10 +12,8 @@ // //===----------------------------------------------------------------------===// -#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API -@_exported import CryptoKit -#else @_implementationOnly import CCryptoBoringSSL + #if canImport(FoundationEssentials) import FoundationEssentials #else @@ -841,5 +839,3 @@ package enum BoringSSLMLDSA { /// The size of the "mu" value in bytes. fileprivate static let muByteCount = 64 } - -#endif // CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API diff --git a/Sources/CryptoBoringWrapper/MLDSA/BoringSSLMLDSA.swift.gyb b/Sources/CryptoBoringWrapper/MLDSA/BoringSSLMLDSA.swift.gyb index 0efa28fad..ce60b7da5 100644 --- a/Sources/CryptoBoringWrapper/MLDSA/BoringSSLMLDSA.swift.gyb +++ b/Sources/CryptoBoringWrapper/MLDSA/BoringSSLMLDSA.swift.gyb @@ -12,10 +12,8 @@ // //===----------------------------------------------------------------------===// -#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API -@_exported import CryptoKit -#else @_implementationOnly import CCryptoBoringSSL + #if canImport(FoundationEssentials) import FoundationEssentials #else @@ -442,5 +440,3 @@ package enum BoringSSLMLDSA { /// The size of the "mu" value in bytes. fileprivate static let muByteCount = 64 } - -#endif // CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API From 459adb9e071bad726e3f3595cd61e7912b345cf0 Mon Sep 17 00:00:00 2001 From: Si Beaumont Date: Mon, 22 Sep 2025 14:40:32 +0100 Subject: [PATCH 41/47] Fix compiler guard for SHA-3 tests (#401) --- Tests/CryptoTests/Digests/DigestsTests.swift | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/Tests/CryptoTests/Digests/DigestsTests.swift b/Tests/CryptoTests/Digests/DigestsTests.swift index d65b4acd6..bc9e03d14 100644 --- a/Tests/CryptoTests/Digests/DigestsTests.swift +++ b/Tests/CryptoTests/Digests/DigestsTests.swift @@ -27,7 +27,7 @@ enum TestError: Error { func nullTestVectorForAlgorithm(hashFunction: H.Type) throws -> String { #if !CRYPTOKIT_IN_SEP -#if !canImport(Darwin) || canImport(CryptoKit, _version: 324.0.4) +#if !CRYPTO_IN_SWIFTPM || canImport(CryptoKit, _version: 324.0.4) if #available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, macCatalyst 19.0, visionOS 2.0, *) { switch H.self { case is SHA3_256.Type: return "a7ffc6f8bf1ed76651c14756a061d662f580ff4de43b49fa82d80a4b80f8434a" @@ -37,7 +37,7 @@ func nullTestVectorForAlgorithm(hashFunction: H.Type) throws -> break } } -#endif // !canImport(Darwin) || canImport(CryptoKit, _version: 324.0.4) +#endif // !CRYPTO_IN_SWIFTPM || canImport(CryptoKit, _version: 324.0.4) #endif // !CRYPTOKIT_IN_SEP switch H.self { @@ -53,7 +53,7 @@ func nullTestVectorForAlgorithm(hashFunction: H.Type) throws -> func testVectorForAlgorithm(hashFunction: H.Type) throws -> String { #if !CRYPTOKIT_IN_SEP -#if !canImport(Darwin) || canImport(CryptoKit, _version: 324.0.4) +#if !CRYPTO_IN_SWIFTPM || canImport(CryptoKit, _version: 324.0.4) if #available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, macCatalyst 19.0, visionOS 2.0, *) { switch H.self { case is SHA3_256.Type: return "916f6061fe879741ca6469b43971dfdb28b1a32dc36cb3254e812be27aad1d18" @@ -63,7 +63,7 @@ func testVectorForAlgorithm(hashFunction: H.Type) throws -> Str break } } -#endif // !canImport(Darwin) || canImport(CryptoKit, _version: 324.0.4) +#endif // !CRYPTO_IN_SWIFTPM || canImport(CryptoKit, _version: 324.0.4) #endif // !CRYPTOKIT_IN_SEP switch H.self { @@ -118,13 +118,13 @@ class DigestsTests: XCTestCase { try orFail { try testHashFunction(hf: SHA384.self) } try orFail { try testHashFunction(hf: SHA512.self) } #if !CRYPTOKIT_IN_SEP -#if !canImport(Darwin) || canImport(CryptoKit, _version: 324.0.4) +#if !CRYPTO_IN_SWIFTPM || canImport(CryptoKit, _version: 324.0.4) if #available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, macCatalyst 19.0, visionOS 2.0, *) { try orFail { try testHashFunction(hf: SHA3_256.self) } try orFail { try testHashFunction(hf: SHA3_384.self) } try orFail { try testHashFunction(hf: SHA3_512.self) } } -#endif // !canImport(Darwin) || canImport(CryptoKit, _version: 324.0.4) +#endif // !CRYPTO_IN_SWIFTPM || canImport(CryptoKit, _version: 324.0.4) #endif // !CRYPTOKIT_IN_SEP } @@ -149,13 +149,13 @@ class DigestsTests: XCTestCase { try orFail { try testHashFunctionImplementsCoW(hf: SHA384.self) } try orFail { try testHashFunctionImplementsCoW(hf: SHA512.self) } #if !CRYPTOKIT_IN_SEP -#if !canImport(Darwin) || canImport(CryptoKit, _version: 324.0.4) +#if !CRYPTO_IN_SWIFTPM || canImport(CryptoKit, _version: 324.0.4) if #available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, macCatalyst 19.0, visionOS 2.0, *) { try orFail { try testHashFunctionImplementsCoW(hf: SHA3_256.self) } try orFail { try testHashFunctionImplementsCoW(hf: SHA3_384.self) } try orFail { try testHashFunctionImplementsCoW(hf: SHA3_512.self) } } -#endif // !canImport(Darwin) || canImport(CryptoKit, _version: 324.0.4) +#endif // !CRYPTO_IN_SWIFTPM || canImport(CryptoKit, _version: 324.0.4) #endif // !CRYPTOKIT_IN_SEP } @@ -168,13 +168,13 @@ class DigestsTests: XCTestCase { XCTAssertEqual(SHA512.blockByteCount, 128) #if !CRYPTOKIT_IN_SEP -#if !canImport(Darwin) || canImport(CryptoKit, _version: 324.0.4) +#if !CRYPTO_IN_SWIFTPM || canImport(CryptoKit, _version: 324.0.4) if #available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, macCatalyst 19.0, visionOS 2.0, *) { XCTAssertEqual(SHA3_256.blockByteCount, 136) XCTAssertEqual(SHA3_384.blockByteCount, 104) XCTAssertEqual(SHA3_512.blockByteCount, 72) } -#endif // !canImport(Darwin) || canImport(CryptoKit, _version: 324.0.4) +#endif // !CRYPTO_IN_SWIFTPM || canImport(CryptoKit, _version: 324.0.4) #endif // !CRYPTOKIT_IN_SEP } } From e0883b430c67ade136243fcbf7a97cb730f0524e Mon Sep 17 00:00:00 2001 From: Cory Benfield Date: Wed, 24 Sep 2025 12:22:11 -0400 Subject: [PATCH 42/47] Final catchup merge (#415) This is the last catchup merge into the WWDC-25 branch required to get the two branches to line up. From here, it's a straightforward merge to `main` to get the WWDC-25 branch in. --------- Co-authored-by: YourMJK <37852512+YourMJK@users.noreply.github.com> Co-authored-by: Rick Newton-Rogers Co-authored-by: Raphael Co-authored-by: Si Beaumont Co-authored-by: Evan Wilde Co-authored-by: Tim Condon <0xTim@users.noreply.github.com> Co-authored-by: Gus Cairo Co-authored-by: George Barnett Co-authored-by: Fabrice de Gans Co-authored-by: Wojciech Nagrodzki <278594+wnagrodzki@users.noreply.github.com> Co-authored-by: Jesse L. Zamora Co-authored-by: aryan-25 Co-authored-by: Gwynne Raskind Co-authored-by: 3405691582 Co-authored-by: Paul Toffoloni <69189821+ptoffy@users.noreply.github.com> --- .github/workflows/main.yml | 4 + .github/workflows/pull_request.yml | 4 + Package.swift | 2 +- Sources/CCryptoBoringSSL/CMakeLists.txt | 1 - .../CCryptoBoringSSL/crypto/asn1/a_bitstr.cc | 123 ++- .../CCryptoBoringSSL/crypto/asn1/a_bool.cc | 11 +- .../CCryptoBoringSSL/crypto/asn1/a_gentm.cc | 17 + Sources/CCryptoBoringSSL/crypto/asn1/a_int.cc | 96 +- .../CCryptoBoringSSL/crypto/asn1/a_object.cc | 98 +- .../CCryptoBoringSSL/crypto/asn1/a_strnid.cc | 6 +- .../CCryptoBoringSSL/crypto/asn1/a_time.cc | 16 + .../CCryptoBoringSSL/crypto/asn1/a_type.cc | 218 ++++ .../CCryptoBoringSSL/crypto/asn1/a_utctm.cc | 16 + .../CCryptoBoringSSL/crypto/asn1/asn1_lib.cc | 79 +- .../CCryptoBoringSSL/crypto/asn1/internal.h | 242 ++++- .../CCryptoBoringSSL/crypto/asn1/tasn_dec.cc | 469 ++++----- .../CCryptoBoringSSL/crypto/asn1/tasn_typ.cc | 3 + .../CCryptoBoringSSL/crypto/asn1/tasn_utl.cc | 24 +- .../CCryptoBoringSSL/crypto/blake2/blake2.cc | 4 +- .../crypto/bytestring/internal.h | 60 +- .../crypto/cipher/e_aesctrhmac.cc | 2 +- .../CCryptoBoringSSL/crypto/cipher/e_tls.cc | 56 +- .../crypto/cipher/get_cipher.cc | 20 +- .../CCryptoBoringSSL/crypto/cipher/internal.h | 3 +- Sources/CCryptoBoringSSL/crypto/conf/conf.cc | 2 + Sources/CCryptoBoringSSL/crypto/crypto.cc | 2 + .../crypto/curve25519/curve25519.cc | 2 +- .../crypto/curve25519/spake25519.cc | 11 +- Sources/CCryptoBoringSSL/crypto/dh/dh_asn1.cc | 26 +- Sources/CCryptoBoringSSL/crypto/dh/params.cc | 18 +- .../crypto/digest/digest_extra.cc | 77 +- Sources/CCryptoBoringSSL/crypto/dsa/dsa.cc | 2 +- .../CCryptoBoringSSL/crypto/dsa/dsa_asn1.cc | 104 +- Sources/CCryptoBoringSSL/crypto/ec/ec_asn1.cc | 224 ++-- Sources/CCryptoBoringSSL/crypto/ec/internal.h | 27 + .../crypto/ecdsa/ecdsa_asn1.cc | 25 +- Sources/CCryptoBoringSSL/crypto/evp/evp.cc | 144 ++- .../CCryptoBoringSSL/crypto/evp/evp_asn1.cc | 400 ++++--- .../CCryptoBoringSSL/crypto/evp/evp_ctx.cc | 31 +- .../CCryptoBoringSSL/crypto/evp/internal.h | 127 ++- Sources/CCryptoBoringSSL/crypto/evp/p_dh.cc | 2 +- .../CCryptoBoringSSL/crypto/evp/p_dh_asn1.cc | 10 +- .../CCryptoBoringSSL/crypto/evp/p_dsa_asn1.cc | 64 +- Sources/CCryptoBoringSSL/crypto/evp/p_ec.cc | 17 +- .../CCryptoBoringSSL/crypto/evp/p_ec_asn1.cc | 121 ++- .../CCryptoBoringSSL/crypto/evp/p_ed25519.cc | 7 +- .../crypto/evp/p_ed25519_asn1.cc | 36 +- Sources/CCryptoBoringSSL/crypto/evp/p_hkdf.cc | 2 +- Sources/CCryptoBoringSSL/crypto/evp/p_rsa.cc | 315 +++--- .../CCryptoBoringSSL/crypto/evp/p_rsa_asn1.cc | 212 +++- .../CCryptoBoringSSL/crypto/evp/p_x25519.cc | 8 +- .../crypto/evp/p_x25519_asn1.cc | 34 +- Sources/CCryptoBoringSSL/crypto/evp/print.cc | 77 +- .../CCryptoBoringSSL/crypto/fipsmodule/bcm.cc | 7 +- .../crypto/fipsmodule/bcm_interface.h | 134 +++ .../fipsmodule/bn/exponentiation.cc.inc | 22 +- .../crypto/fipsmodule/bn/generic.cc.inc | 44 +- .../crypto/fipsmodule/bn/internal.h | 64 +- .../crypto/fipsmodule/bn/montgomery.cc.inc | 25 +- .../crypto/fipsmodule/bn/prime.cc.inc | 6 +- .../crypto/fipsmodule/dh/dh.cc.inc | 4 +- .../crypto/fipsmodule/digest/digest.cc.inc | 43 +- .../crypto/fipsmodule/digest/digests.cc.inc | 4 + .../crypto/fipsmodule/ec/ec.cc.inc | 36 +- .../crypto/fipsmodule/ec/oct.cc.inc | 4 +- .../crypto/fipsmodule/ec/p256-nistz.cc.inc | 6 +- .../crypto/fipsmodule/ec/p256.cc.inc | 256 +---- .../crypto/fipsmodule/ec/simple_mul.cc.inc | 17 +- .../crypto/fipsmodule/ec/wnaf.cc.inc | 6 +- .../crypto/fipsmodule/entropy/internal.h | 38 + .../crypto/fipsmodule/entropy/jitter.cc.inc | 463 ++++++++ .../crypto/fipsmodule/entropy/sha512.cc.inc | 324 ++++++ .../crypto/fipsmodule/mldsa/mldsa.cc.inc | 574 ++++++++-- .../crypto/fipsmodule/rand/ctrdrbg.cc.inc | 271 ++++- .../crypto/fipsmodule/rand/internal.h | 17 +- .../crypto/fipsmodule/rand/rand.cc.inc | 44 +- .../crypto/fipsmodule/rsa/padding.cc.inc | 26 +- .../crypto/fipsmodule/rsa/rsa.cc.inc | 12 +- .../crypto/fipsmodule/rsa/rsa_impl.cc.inc | 34 +- .../crypto/fipsmodule/self_check/fips.cc.inc | 4 +- .../fipsmodule/self_check/self_check.cc.inc | 49 +- .../fipsmodule/service_indicator/internal.h | 7 + .../service_indicator.cc.inc | 3 +- .../crypto/fipsmodule/sha/sha512.cc.inc | 30 +- .../crypto/fipsmodule/slhdsa/thash.cc.inc | 2 +- Sources/CCryptoBoringSSL/crypto/hpke/hpke.cc | 121 ++- Sources/CCryptoBoringSSL/crypto/hrss/hrss.cc | 6 +- Sources/CCryptoBoringSSL/crypto/internal.h | 77 +- .../CCryptoBoringSSL/crypto/kyber/internal.h | 111 +- .../CCryptoBoringSSL/crypto/kyber/kyber.cc | 3 - .../CCryptoBoringSSL/crypto/mldsa/mldsa.cc | 104 ++ Sources/CCryptoBoringSSL/crypto/obj/obj.cc | 17 +- Sources/CCryptoBoringSSL/crypto/obj/obj_dat.h | 5 +- .../CCryptoBoringSSL/crypto/obj/obj_xref.cc | 16 +- .../CCryptoBoringSSL/crypto/pem/pem_all.cc | 23 +- .../CCryptoBoringSSL/crypto/pem/pem_info.cc | 4 +- .../CCryptoBoringSSL/crypto/pem/pem_lib.cc | 4 +- .../CCryptoBoringSSL/crypto/pkcs8/p5_pbev2.cc | 1 + .../CCryptoBoringSSL/crypto/pkcs8/pkcs8.cc | 16 +- .../crypto/pkcs8/pkcs8_x509.cc | 1 + .../CCryptoBoringSSL/crypto/rand/passive.cc | 2 +- .../CCryptoBoringSSL/crypto/rsa/internal.h | 25 + .../CCryptoBoringSSL/crypto/rsa/rsa_asn1.cc | 204 +++- .../CCryptoBoringSSL/crypto/rsa/rsa_extra.cc | 11 + Sources/CCryptoBoringSSL/crypto/sha/sha256.cc | 2 +- Sources/CCryptoBoringSSL/crypto/sha/sha512.cc | 2 +- .../crypto/spake2plus/internal.h | 2 +- .../crypto/spake2plus/spake2plus.cc | 2 +- .../crypto/trust_token/pmbtoken.cc | 11 +- .../crypto/trust_token/trust_token.cc | 11 +- .../crypto/trust_token/voprf.cc | 2 +- .../CCryptoBoringSSL/crypto/x509/a_sign.cc | 91 +- .../CCryptoBoringSSL/crypto/x509/a_verify.cc | 52 +- .../CCryptoBoringSSL/crypto/x509/algorithm.cc | 14 +- .../CCryptoBoringSSL/crypto/x509/asn1_gen.cc | 6 +- .../CCryptoBoringSSL/crypto/x509/by_file.cc | 12 +- .../CCryptoBoringSSL/crypto/x509/internal.h | 79 +- .../CCryptoBoringSSL/crypto/x509/rsa_pss.cc | 350 ++---- Sources/CCryptoBoringSSL/crypto/x509/t_req.cc | 2 +- .../CCryptoBoringSSL/crypto/x509/t_x509.cc | 17 +- .../CCryptoBoringSSL/crypto/x509/v3_conf.cc | 2 +- .../CCryptoBoringSSL/crypto/x509/v3_purp.cc | 12 +- .../CCryptoBoringSSL/crypto/x509/v3_skey.cc | 11 +- .../CCryptoBoringSSL/crypto/x509/x509_cmp.cc | 37 +- .../CCryptoBoringSSL/crypto/x509/x509_ext.cc | 57 +- .../CCryptoBoringSSL/crypto/x509/x509_lu.cc | 4 +- .../CCryptoBoringSSL/crypto/x509/x509_set.cc | 111 +- .../CCryptoBoringSSL/crypto/x509/x509_trs.cc | 6 +- .../CCryptoBoringSSL/crypto/x509/x509cset.cc | 15 +- .../CCryptoBoringSSL/crypto/x509/x509rset.cc | 9 +- .../CCryptoBoringSSL/crypto/x509/x_algor.cc | 132 ++- Sources/CCryptoBoringSSL/crypto/x509/x_all.cc | 63 +- .../CCryptoBoringSSL/crypto/x509/x_name.cc | 72 +- .../CCryptoBoringSSL/crypto/x509/x_pubkey.cc | 189 ++-- Sources/CCryptoBoringSSL/crypto/x509/x_val.cc | 28 - .../CCryptoBoringSSL/crypto/x509/x_x509.cc | 449 ++++---- .../gen/bcm/armv8-mont-apple.S | 10 +- .../gen/bcm/armv8-mont-linux.S | 14 +- .../CCryptoBoringSSL/gen/bcm/armv8-mont-win.S | 10 +- .../CCryptoBoringSSL/gen/bcm/x86-mont-apple.S | 8 +- .../CCryptoBoringSSL/gen/bcm/x86-mont-linux.S | 12 +- .../CCryptoBoringSSL/gen/crypto/err_data.cc | 992 +++++++++--------- Sources/CCryptoBoringSSL/hash.txt | 2 +- .../include/CCryptoBoringSSL_asn1.h | 12 - .../include/CCryptoBoringSSL_asn1t.h | 4 +- .../include/CCryptoBoringSSL_base.h | 1 + .../include/CCryptoBoringSSL_bcm_public.h | 7 +- .../include/CCryptoBoringSSL_blake2.h | 7 +- .../include/CCryptoBoringSSL_bn.h | 10 - ...CryptoBoringSSL_boringssl_prefix_symbols.h | 112 +- ...toBoringSSL_boringssl_prefix_symbols_asm.h | 110 +- .../include/CCryptoBoringSSL_conf.h | 3 + .../include/CCryptoBoringSSL_crypto.h | 8 +- .../include/CCryptoBoringSSL_ctrdrbg.h | 48 +- .../include/CCryptoBoringSSL_dh.h | 20 +- .../include/CCryptoBoringSSL_digest.h | 21 +- .../include/CCryptoBoringSSL_dsa.h | 2 +- .../include/CCryptoBoringSSL_ec.h | 46 +- .../include/CCryptoBoringSSL_ec_key.h | 4 +- .../include/CCryptoBoringSSL_err.h | 7 + .../include/CCryptoBoringSSL_evp.h | 341 ++++-- .../include/CCryptoBoringSSL_evp_errors.h | 2 +- .../include/CCryptoBoringSSL_hpke.h | 8 +- .../include/CCryptoBoringSSL_mldsa.h | 140 +++ .../include/CCryptoBoringSSL_nid.h | 5 +- .../include/CCryptoBoringSSL_rsa.h | 57 +- .../include/CCryptoBoringSSL_sha.h | 163 +-- .../include/CCryptoBoringSSL_sha2.h | 184 ++++ .../include/CCryptoBoringSSL_x509.h | 156 +-- .../include/boringssl_prefix_symbols_nasm.inc | 220 +++- .../experimental/CCryptoBoringSSL_kyber.h | 146 --- .../fiat/bedrock_polyfill_platform.c.inc | 66 ++ .../fiat/bedrock_unverified_bareminimum.c.inc | 47 + .../fiat/bedrock_unverified_platform.c.inc | 125 +++ .../third_party/fiat/p256_64.h | 77 +- .../third_party/fiat/p256_64_msvc.h | 75 +- .../third_party/fiat/p256_field.c.inc | 26 + .../third_party/fiat/p256_field_32.br.c.inc | 71 ++ .../third_party/fiat/p256_field_64.br.c.inc | 84 ++ .../third_party/fiat/p256_point.br.c.inc | 112 ++ .../Util/FiniteFieldArithmeticContext.swift | 4 +- .../CryptoExtras/RSA/RSA+BlindSigning.swift | 2 +- Sources/CryptoExtras/RSA/RSA.swift | 4 +- Sources/CryptoExtras/RSA/RSA_boring.swift | 4 +- .../Util/ThreadSpecific/ThreadPosix.swift | 2 +- scripts/generate-linux-sdks.sh | 6 +- scripts/patch-3-missing-extern-c.patch | 25 + scripts/vendor-boringssl.sh | 60 +- 188 files changed, 8136 insertions(+), 4426 deletions(-) create mode 100644 Sources/CCryptoBoringSSL/crypto/fipsmodule/entropy/internal.h create mode 100644 Sources/CCryptoBoringSSL/crypto/fipsmodule/entropy/jitter.cc.inc create mode 100644 Sources/CCryptoBoringSSL/crypto/fipsmodule/entropy/sha512.cc.inc delete mode 100644 Sources/CCryptoBoringSSL/crypto/x509/x_val.cc create mode 100644 Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_sha2.h delete mode 100644 Sources/CCryptoBoringSSL/include/experimental/CCryptoBoringSSL_kyber.h create mode 100644 Sources/CCryptoBoringSSL/third_party/fiat/bedrock_polyfill_platform.c.inc create mode 100644 Sources/CCryptoBoringSSL/third_party/fiat/bedrock_unverified_bareminimum.c.inc create mode 100644 Sources/CCryptoBoringSSL/third_party/fiat/bedrock_unverified_platform.c.inc create mode 100644 Sources/CCryptoBoringSSL/third_party/fiat/p256_field.c.inc create mode 100644 Sources/CCryptoBoringSSL/third_party/fiat/p256_field_32.br.c.inc create mode 100644 Sources/CCryptoBoringSSL/third_party/fiat/p256_field_64.br.c.inc create mode 100644 Sources/CCryptoBoringSSL/third_party/fiat/p256_point.br.c.inc create mode 100644 scripts/patch-3-missing-extern-c.patch diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9e537d8b8..4559640ed 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -14,14 +14,17 @@ jobs: linux_5_10_arguments_override: "--explicit-target-dependency-import-check error" linux_6_0_arguments_override: "--explicit-target-dependency-import-check error" linux_6_1_arguments_override: "--explicit-target-dependency-import-check error" + linux_6_2_arguments_override: "--explicit-target-dependency-import-check error" linux_nightly_next_arguments_override: "--explicit-target-dependency-import-check error" linux_nightly_main_arguments_override: "--explicit-target-dependency-import-check error" windows_6_0_enabled: true windows_6_1_enabled: true + windows_6_2_enabled: true windows_nightly_next_enabled: true windows_nightly_main_enabled: true windows_6_0_arguments_override: "--explicit-target-dependency-import-check error" windows_6_1_arguments_override: "--explicit-target-dependency-import-check error" + windows_6_2_arguments_override: "--explicit-target-dependency-import-check error" windows_nightly_next_arguments_override: "--explicit-target-dependency-import-check error" windows_nightly_main_arguments_override: "--explicit-target-dependency-import-check error" @@ -31,6 +34,7 @@ jobs: with: windows_6_0_enabled: true windows_6_1_enabled: true + windows_6_2_enabled: true windows_nightly_next_enabled: true windows_nightly_main_enabled: true diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index 3ff06facc..6af47aa05 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -19,14 +19,17 @@ jobs: linux_5_10_arguments_override: "--explicit-target-dependency-import-check error" linux_6_0_arguments_override: "--explicit-target-dependency-import-check error" linux_6_1_arguments_override: "--explicit-target-dependency-import-check error" + linux_6_2_arguments_override: "--explicit-target-dependency-import-check error" linux_nightly_next_arguments_override: "--explicit-target-dependency-import-check error" linux_nightly_main_arguments_override: "--explicit-target-dependency-import-check error" windows_6_0_enabled: true windows_6_1_enabled: true + windows_6_2_enabled: true windows_nightly_next_enabled: true windows_nightly_main_enabled: true windows_6_0_arguments_override: "--explicit-target-dependency-import-check error" windows_6_1_arguments_override: "--explicit-target-dependency-import-check error" + windows_6_2_arguments_override: "--explicit-target-dependency-import-check error" windows_nightly_next_arguments_override: "--explicit-target-dependency-import-check error" windows_nightly_main_arguments_override: "--explicit-target-dependency-import-check error" @@ -36,6 +39,7 @@ jobs: with: windows_6_0_enabled: true windows_6_1_enabled: true + windows_6_2_enabled: true windows_nightly_next_enabled: true windows_nightly_main_enabled: true diff --git a/Package.swift b/Package.swift index 596beb7ec..04b795686 100644 --- a/Package.swift +++ b/Package.swift @@ -20,7 +20,7 @@ // Sources/CCryptoBoringSSL directory. The source repository is at // https://boringssl.googlesource.com/boringssl. // -// BoringSSL Commit: 035e720641f385e82c72b7b0a9e1d89e58cb5ed5 +// BoringSSL Commit: 0226f30467f540a3f62ef48d453f93927da199b6 import PackageDescription diff --git a/Sources/CCryptoBoringSSL/CMakeLists.txt b/Sources/CCryptoBoringSSL/CMakeLists.txt index 9da329bd4..7e58e0d86 100644 --- a/Sources/CCryptoBoringSSL/CMakeLists.txt +++ b/Sources/CCryptoBoringSSL/CMakeLists.txt @@ -255,7 +255,6 @@ add_library(CCryptoBoringSSL STATIC "crypto/x509/x_req.cc" "crypto/x509/x_sig.cc" "crypto/x509/x_spki.cc" - "crypto/x509/x_val.cc" "crypto/x509/x_x509.cc" "crypto/x509/x_x509a.cc" "crypto/xwing/xwing.cc" diff --git a/Sources/CCryptoBoringSSL/crypto/asn1/a_bitstr.cc b/Sources/CCryptoBoringSSL/crypto/asn1/a_bitstr.cc index dcfc1fe09..4f26f2250 100644 --- a/Sources/CCryptoBoringSSL/crypto/asn1/a_bitstr.cc +++ b/Sources/CCryptoBoringSSL/crypto/asn1/a_bitstr.cc @@ -20,6 +20,7 @@ #include #include #include +#include #include "../internal.h" #include "internal.h" @@ -110,76 +111,96 @@ int asn1_marshal_bit_string(CBB *out, const ASN1_BIT_STRING *in, CBB_flush(out); } -ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, - const unsigned char **pp, long len) { - ASN1_BIT_STRING *ret = NULL; - const unsigned char *p; - unsigned char *s; - int padding; - uint8_t padding_mask; - - if (len < 1) { +static int asn1_parse_bit_string_contents(bssl::Span in, + ASN1_BIT_STRING *out) { + CBS cbs = in; + uint8_t padding; + if (!CBS_get_u8(&cbs, &padding)) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT); - goto err; + return 0; } - if (len > INT_MAX) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_LONG); - goto err; + if (padding > 7) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BIT_STRING_BITS_LEFT); + return 0; } - if ((a == NULL) || ((*a) == NULL)) { - if ((ret = ASN1_BIT_STRING_new()) == NULL) { - return NULL; + // Unused bits in a BIT STRING must be zero. + uint8_t padding_mask = (1 << padding) - 1; + if (padding != 0) { + CBS copy = cbs; + uint8_t last; + if (!CBS_get_last_u8(©, &last) || (last & padding_mask) != 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BIT_STRING_PADDING); + return 0; } - } else { - ret = (*a); } - p = *pp; - padding = *(p++); - len--; - if (padding > 7) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BIT_STRING_BITS_LEFT); - goto err; + if (!ASN1_STRING_set(out, CBS_data(&cbs), CBS_len(&cbs))) { + return 0; } - // Unused bits in a BIT STRING must be zero. - padding_mask = (1 << padding) - 1; - if (padding != 0 && (len < 1 || (p[len - 1] & padding_mask) != 0)) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BIT_STRING_PADDING); - goto err; - } + out->type = V_ASN1_BIT_STRING; + // |ASN1_STRING_FLAG_BITS_LEFT| and the bottom 3 bits encode |padding|. + out->flags &= ~0x07; + out->flags |= ASN1_STRING_FLAG_BITS_LEFT | padding; + return 1; +} - // We do this to preserve the settings. If we modify the settings, via - // the _set_bit function, we will recalculate on output - ret->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); // clear - ret->flags |= (ASN1_STRING_FLAG_BITS_LEFT | padding); // set +ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, + const unsigned char **pp, long len) { + if (len < 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT); + return nullptr; + } - if (len > 0) { - s = reinterpret_cast(OPENSSL_memdup(p, len)); - if (s == NULL) { - goto err; + ASN1_BIT_STRING *ret = nullptr; + if (a == nullptr || *a == nullptr) { + if ((ret = ASN1_BIT_STRING_new()) == nullptr) { + return nullptr; } - p += len; } else { - s = NULL; + ret = *a; } - ret->length = (int)len; - OPENSSL_free(ret->data); - ret->data = s; - ret->type = V_ASN1_BIT_STRING; - if (a != NULL) { - (*a) = ret; + if (!asn1_parse_bit_string_contents(bssl::Span(*pp, len), ret)) { + if (ret != nullptr && (a == nullptr || *a != ret)) { + ASN1_BIT_STRING_free(ret); + } + return nullptr; } - *pp = p; + + if (a != nullptr) { + *a = ret; + } + *pp += len; return ret; -err: - if ((ret != NULL) && ((a == NULL) || (*a != ret))) { - ASN1_BIT_STRING_free(ret); +} + +int asn1_parse_bit_string(CBS *cbs, ASN1_BIT_STRING *out, CBS_ASN1_TAG tag) { + tag = tag == 0 ? CBS_ASN1_BITSTRING : tag; + CBS child; + if (!CBS_get_asn1(cbs, &child, tag)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + return asn1_parse_bit_string_contents(child, out); +} + +int asn1_parse_bit_string_with_bad_length(CBS *cbs, ASN1_BIT_STRING *out) { + CBS child; + CBS_ASN1_TAG tag; + size_t header_len; + int indefinite; + if (!CBS_get_any_ber_asn1_element(cbs, &child, &tag, &header_len, + /*out_ber_found=*/nullptr, + &indefinite) || + tag != CBS_ASN1_BITSTRING || indefinite || // + !CBS_skip(&child, header_len)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; } - return NULL; + return asn1_parse_bit_string_contents(child, out); } // These next 2 functions from Goetz Babin-Ebell diff --git a/Sources/CCryptoBoringSSL/crypto/asn1/a_bool.cc b/Sources/CCryptoBoringSSL/crypto/asn1/a_bool.cc index 5a52ac477..ea18ba964 100644 --- a/Sources/CCryptoBoringSSL/crypto/asn1/a_bool.cc +++ b/Sources/CCryptoBoringSSL/crypto/asn1/a_bool.cc @@ -21,13 +21,10 @@ int i2d_ASN1_BOOLEAN(ASN1_BOOLEAN a, unsigned char **outp) { - CBB cbb; - if (!CBB_init(&cbb, 3) || // - !CBB_add_asn1_bool(&cbb, a != ASN1_BOOLEAN_FALSE)) { - CBB_cleanup(&cbb); - return -1; - } - return CBB_finish_i2d(&cbb, outp); + return bssl::I2DFromCBB( + /*initial_capacity=*/3, outp, [&](CBB *cbb) -> bool { + return CBB_add_asn1_bool(cbb, a != ASN1_BOOLEAN_FALSE); + }); } ASN1_BOOLEAN d2i_ASN1_BOOLEAN(ASN1_BOOLEAN *out, const unsigned char **inp, diff --git a/Sources/CCryptoBoringSSL/crypto/asn1/a_gentm.cc b/Sources/CCryptoBoringSSL/crypto/asn1/a_gentm.cc index dbbbf99e9..645b136a1 100644 --- a/Sources/CCryptoBoringSSL/crypto/asn1/a_gentm.cc +++ b/Sources/CCryptoBoringSSL/crypto/asn1/a_gentm.cc @@ -36,6 +36,23 @@ int asn1_generalizedtime_to_tm(struct tm *tm, const ASN1_GENERALIZEDTIME *d) { return 1; } +int asn1_parse_generalized_time(CBS *cbs, ASN1_GENERALIZEDTIME *out, + CBS_ASN1_TAG tag) { + tag = tag == 0 ? CBS_ASN1_GENERALIZEDTIME : tag; + CBS child; + if (!CBS_get_asn1(cbs, &child, tag) || + !CBS_parse_generalized_time(&child, nullptr, + /*allow_timezone_offset=*/0)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + if (!ASN1_STRING_set(out, CBS_data(&child), CBS_len(&child))) { + return 0; + } + out->type = V_ASN1_GENERALIZEDTIME; + return 1; +} + int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *d) { return asn1_generalizedtime_to_tm(NULL, d); } diff --git a/Sources/CCryptoBoringSSL/crypto/asn1/a_int.cc b/Sources/CCryptoBoringSSL/crypto/asn1/a_int.cc index 53a28aedf..5a3eaf07e 100644 --- a/Sources/CCryptoBoringSSL/crypto/asn1/a_int.cc +++ b/Sources/CCryptoBoringSSL/crypto/asn1/a_int.cc @@ -21,6 +21,7 @@ #include #include #include +#include #include "../internal.h" #include "internal.h" @@ -146,32 +147,13 @@ int i2c_ASN1_INTEGER(const ASN1_INTEGER *in, unsigned char **outp) { return len; } -ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **out, const unsigned char **inp, - long len) { - // This function can handle lengths up to INT_MAX - 1, but the rest of the - // legacy ASN.1 code mixes integer types, so avoid exposing it to - // ASN1_INTEGERS with larger lengths. - if (len < 0 || len > INT_MAX / 2) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG); - return NULL; - } - - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); +static int asn1_parse_integer_contents(bssl::Span in, + ASN1_INTEGER *out) { + CBS cbs = in; int is_negative; if (!CBS_is_valid_asn1_integer(&cbs, &is_negative)) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_INTEGER); - return NULL; - } - - ASN1_INTEGER *ret = NULL; - if (out == NULL || *out == NULL) { - ret = ASN1_INTEGER_new(); - if (ret == NULL) { - return NULL; - } - } else { - ret = *out; + return 0; } // Convert to |ASN1_INTEGER|'s sign-and-magnitude representation. First, @@ -192,33 +174,75 @@ ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **out, const unsigned char **inp, } } - if (!ASN1_STRING_set(ret, CBS_data(&cbs), CBS_len(&cbs))) { - goto err; + if (!ASN1_STRING_set(out, CBS_data(&cbs), CBS_len(&cbs))) { + return 0; } if (is_negative) { - ret->type = V_ASN1_NEG_INTEGER; - negate_twos_complement(ret->data, ret->length); + out->type = V_ASN1_NEG_INTEGER; + negate_twos_complement(out->data, out->length); } else { - ret->type = V_ASN1_INTEGER; + out->type = V_ASN1_INTEGER; } // The value should be minimally-encoded. - assert(ret->length == 0 || ret->data[0] != 0); + assert(out->length == 0 || out->data[0] != 0); // Zero is not negative. - assert(!is_negative || ret->length > 0); + assert(!is_negative || out->length > 0); + return 1; +} + +int asn1_parse_integer(CBS *cbs, ASN1_INTEGER *out, CBS_ASN1_TAG tag) { + tag = tag == 0 ? CBS_ASN1_INTEGER : tag; + CBS child; + if (!CBS_get_asn1(cbs, &child, tag)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + return asn1_parse_integer_contents(child, out); +} + +int asn1_parse_enumerated(CBS *cbs, ASN1_ENUMERATED *out, CBS_ASN1_TAG tag) { + tag = tag == 0 ? CBS_ASN1_ENUMERATED : tag; + if (!asn1_parse_integer(cbs, out, tag)) { + return 0; + } + // Fix the type value. + out->type = + (out->type & V_ASN1_NEG) ? V_ASN1_NEG_ENUMERATED : V_ASN1_ENUMERATED; + return 1; +} + +ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **out, const unsigned char **inp, + long len) { + if (len < 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT); + return nullptr; + } + + ASN1_INTEGER *ret = nullptr; + if (out == nullptr || *out == nullptr) { + ret = ASN1_INTEGER_new(); + if (ret == nullptr) { + return nullptr; + } + } else { + ret = *out; + } + + if (!asn1_parse_integer_contents(bssl::Span(*inp, len), ret)) { + if (ret != nullptr && (out == nullptr || *out != ret)) { + ASN1_INTEGER_free(ret); + } + return nullptr; + } *inp += len; - if (out != NULL) { + if (out != nullptr) { *out = ret; } return ret; -err: - if (ret != NULL && (out == NULL || *out != ret)) { - ASN1_INTEGER_free(ret); - } - return NULL; } int ASN1_INTEGER_set_int64(ASN1_INTEGER *a, int64_t v) { diff --git a/Sources/CCryptoBoringSSL/crypto/asn1/a_object.cc b/Sources/CCryptoBoringSSL/crypto/asn1/a_object.cc index e6e97d6d5..3ed780276 100644 --- a/Sources/CCryptoBoringSSL/crypto/asn1/a_object.cc +++ b/Sources/CCryptoBoringSSL/crypto/asn1/a_object.cc @@ -27,26 +27,27 @@ #include "internal.h" -int i2d_ASN1_OBJECT(const ASN1_OBJECT *in, unsigned char **outp) { +int asn1_marshal_object(CBB *out, const ASN1_OBJECT *in, CBS_ASN1_TAG tag) { if (in == NULL) { OPENSSL_PUT_ERROR(ASN1, ERR_R_PASSED_NULL_PARAMETER); - return -1; + return 0; } if (in->length <= 0) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OBJECT); - return -1; + return 0; } - CBB cbb, child; - if (!CBB_init(&cbb, (size_t)in->length + 2) || - !CBB_add_asn1(&cbb, &child, CBS_ASN1_OBJECT) || - !CBB_add_bytes(&child, in->data, in->length)) { - CBB_cleanup(&cbb); - return -1; - } + tag = tag == 0 ? CBS_ASN1_OBJECT : tag; + return CBB_add_asn1_element(out, tag, in->data, in->length); +} - return CBB_finish_i2d(&cbb, outp); +int i2d_ASN1_OBJECT(const ASN1_OBJECT *in, unsigned char **outp) { + return bssl::I2DFromCBB( + /*initial_capacity=*/static_cast(in->length) + 2, outp, + [&](CBB *cbb) -> bool { + return asn1_marshal_object(cbb, in, /*tag=*/0); + }); } int i2t_ASN1_OBJECT(char *buf, int buf_len, const ASN1_OBJECT *a) { @@ -90,53 +91,48 @@ int i2a_ASN1_OBJECT(BIO *bp, const ASN1_OBJECT *a) { ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **out, const unsigned char **inp, long len) { - if (len < 0) { - return NULL; - } - - CBS cbs, child; - CBS_init(&cbs, *inp, (size_t)len); - if (!CBS_get_asn1(&cbs, &child, CBS_ASN1_OBJECT)) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); - return NULL; - } - - const uint8_t *contents = CBS_data(&child); - ASN1_OBJECT *ret = c2i_ASN1_OBJECT(out, &contents, CBS_len(&child)); - if (ret != NULL) { - // |c2i_ASN1_OBJECT| should have consumed the entire input. - assert(CBS_data(&cbs) == contents); - *inp = CBS_data(&cbs); - } - return ret; + return bssl::D2IFromCBS(out, inp, len, [](CBS *cbs) -> ASN1_OBJECT * { + CBS child; + if (!CBS_get_asn1(cbs, &child, CBS_ASN1_OBJECT)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return nullptr; + } + const uint8_t *contents = CBS_data(&child); + return c2i_ASN1_OBJECT(nullptr, &contents, CBS_len(&child)); + }); } ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **out, const unsigned char **inp, long len) { - if (len < 0) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING); - return NULL; - } - - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); - if (!CBS_is_valid_asn1_oid(&cbs)) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING); - return NULL; - } + return bssl::D2IFromCBS(out, inp, len, [](CBS *cbs) -> ASN1_OBJECT * { + if (!CBS_is_valid_asn1_oid(cbs)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING); + return nullptr; + } + ASN1_OBJECT *ret = + ASN1_OBJECT_create(NID_undef, CBS_data(cbs), CBS_len(cbs), + /*sn=*/nullptr, /*ln=*/nullptr); + if (ret != nullptr) { + // |c2i_ASN1_OBJECT| consumes its whole input on success. + BSSL_CHECK(CBS_skip(cbs, CBS_len(cbs))); + } + return ret; + }); +} - ASN1_OBJECT *ret = ASN1_OBJECT_create(NID_undef, *inp, (size_t)len, - /*sn=*/NULL, /*ln=*/NULL); - if (ret == NULL) { - return NULL; +ASN1_OBJECT *asn1_parse_object(CBS *cbs, CBS_ASN1_TAG tag) { + tag = tag == 0 ? CBS_ASN1_OBJECT : tag; + CBS child; + if (!CBS_get_asn1(cbs, &child, tag)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return nullptr; } - - if (out != NULL) { - ASN1_OBJECT_free(*out); - *out = ret; + if (!CBS_is_valid_asn1_oid(&child)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING); + return nullptr; } - *inp += len; // All bytes were consumed. - return ret; + return ASN1_OBJECT_create(NID_undef, CBS_data(&child), CBS_len(&child), + /*sn=*/nullptr, /*ln=*/nullptr); } ASN1_OBJECT *ASN1_OBJECT_new(void) { diff --git a/Sources/CCryptoBoringSSL/crypto/asn1/a_strnid.cc b/Sources/CCryptoBoringSSL/crypto/asn1/a_strnid.cc index 0cd7663f4..61007f3a4 100644 --- a/Sources/CCryptoBoringSSL/crypto/asn1/a_strnid.cc +++ b/Sources/CCryptoBoringSSL/crypto/asn1/a_strnid.cc @@ -18,6 +18,8 @@ #include #include +#include + #include #include #include @@ -129,7 +131,7 @@ static const ASN1_STRING_TABLE *asn1_string_table_get(int nid) { ASN1_STRING_TABLE key; key.nid = nid; const ASN1_STRING_TABLE *tbl = reinterpret_cast( - bsearch(&key, tbl_standard, OPENSSL_ARRAY_SIZE(tbl_standard), + bsearch(&key, tbl_standard, std::size(tbl_standard), sizeof(ASN1_STRING_TABLE), table_cmp_void)); if (tbl != NULL) { return tbl; @@ -202,5 +204,5 @@ void ASN1_STRING_TABLE_cleanup(void) {} void asn1_get_string_table_for_testing(const ASN1_STRING_TABLE **out_ptr, size_t *out_len) { *out_ptr = tbl_standard; - *out_len = OPENSSL_ARRAY_SIZE(tbl_standard); + *out_len = std::size(tbl_standard); } diff --git a/Sources/CCryptoBoringSSL/crypto/asn1/a_time.cc b/Sources/CCryptoBoringSSL/crypto/asn1/a_time.cc index a0ac63462..2d9db622b 100644 --- a/Sources/CCryptoBoringSSL/crypto/asn1/a_time.cc +++ b/Sources/CCryptoBoringSSL/crypto/asn1/a_time.cc @@ -222,3 +222,19 @@ int ASN1_TIME_to_posix(const ASN1_TIME *t, int64_t *out_time) { } return OPENSSL_tm_to_posix(&tm, out_time); } + +int asn1_parse_time(CBS *cbs, ASN1_TIME *out, int allow_utc_timezone_offset) { + if (CBS_peek_asn1_tag(cbs, CBS_ASN1_UTCTIME)) { + return asn1_parse_utc_time(cbs, out, /*tag=*/0, allow_utc_timezone_offset); + } + return asn1_parse_generalized_time(cbs, out, /*tag=*/0); +} + +int asn1_marshal_time(CBB *cbb, const ASN1_TIME *in) { + if (in->type != V_ASN1_UTCTIME && in->type != V_ASN1_GENERALIZEDTIME) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TYPE); + return 0; + } + return asn1_marshal_octet_string(cbb, in, + static_cast(in->type)); +} diff --git a/Sources/CCryptoBoringSSL/crypto/asn1/a_type.cc b/Sources/CCryptoBoringSSL/crypto/asn1/a_type.cc index bebe0f906..9423ed0e1 100644 --- a/Sources/CCryptoBoringSSL/crypto/asn1/a_type.cc +++ b/Sources/CCryptoBoringSSL/crypto/asn1/a_type.cc @@ -16,6 +16,7 @@ #include +#include #include #include #include @@ -170,3 +171,220 @@ int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b) { return result; } + +int asn1_parse_any(CBS *cbs, ASN1_TYPE *out) { + CBS_ASN1_TAG tag; + CBS elem; + size_t header_len; + if (!CBS_get_any_asn1_element(cbs, &elem, &tag, &header_len)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + + // Handle the non-string types. + if (tag == CBS_ASN1_OBJECT) { + bssl::UniquePtr obj(asn1_parse_object(&elem, /*tag=*/0)); + if (obj == nullptr) { + return 0; + } + ASN1_TYPE_set(out, V_ASN1_OBJECT, obj.release()); + return 1; + } + if (tag == CBS_ASN1_NULL) { + if (CBS_len(&elem) != header_len) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + ASN1_TYPE_set(out, V_ASN1_NULL, nullptr); + return 1; + } + if (tag == CBS_ASN1_BOOLEAN) { + int b; + if (!CBS_get_asn1_bool(&elem, &b)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + // V_ASN1_BOOLEAN will interpret the pointer as null for false and any + // arbitrary non-null pointer for true. + ASN1_TYPE_set(out, V_ASN1_BOOLEAN, b ? out : nullptr); + return 1; + } + + // All other cases are handled identically to the string-based ANY parser. + bssl::UniquePtr str(ASN1_STRING_new()); + if (str == nullptr || !asn1_parse_any_as_string(&elem, str.get())) { + return 0; + } + asn1_type_set0_string(out, str.release()); + return 1; +} + +int asn1_parse_any_as_string(CBS *cbs, ASN1_STRING *out) { + CBS_ASN1_TAG tag; + CBS elem; + size_t header_len; + if (!CBS_get_any_asn1_element(cbs, &elem, &tag, &header_len)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + + // Reject unexpectedly constructed or primitive universal types, rather than + // encoding them as an opaque |V_ASN1_OTHER|. As of X.680 (02/2021), tag + // numbers 0-36 have been allocated, except 15. Of these, only 8 (EXTERNAL), + // 11 (EMBEDDED PDV), 16 (SEQUENCE), 17 (SET), and 29 (CHARACTER STRING) are + // constructed. + const CBS_ASN1_TAG tag_class = (tag & CBS_ASN1_CLASS_MASK); + const CBS_ASN1_TAG number = tag & CBS_ASN1_TAG_NUMBER_MASK; + if (tag_class == CBS_ASN1_UNIVERSAL && number <= 36 && number != 15) { + const bool is_constructed = (tag & CBS_ASN1_CONSTRUCTED) != 0; + if (number == V_ASN1_EXTERNAL || number == 11 /* EMBEDDED PDV */ || + number == V_ASN1_SEQUENCE || number == V_ASN1_SET || + number == 29 /* CHARACTER STRING*/) { + if (!is_constructed) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_CONSTRUCTED); + return 0; + } + } else { + if (is_constructed) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_PRIMITIVE); + return 0; + } + } + } + + // Historically, parsing high universal tag numbers made OpenSSL's + // |ASN1_STRING| representation ambiguous. We've since fixed this with + // |V_ASN1_OTHER| but, for now, continue to enforce the limit. + if (tag_class == CBS_ASN1_UNIVERSAL && number > V_ASN1_MAX_UNIVERSAL) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + + // These types are just parsed as |V_ASN1_OTHER| here. Check the contents + // before the generic |V_ASN1_OTHER| path. + CBS body = elem; + BSSL_CHECK(CBS_skip(&body, header_len)); + switch (tag) { + case CBS_ASN1_OBJECT: + if (!CBS_is_valid_asn1_oid(&body)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING); + return 0; + } + break; + case CBS_ASN1_NULL: + if (CBS_len(&body) != 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NULL_IS_WRONG_LENGTH); + return 0; + } + break; + case CBS_ASN1_BOOLEAN: { + uint8_t v; + if (!CBS_get_u8(&body, &v) || CBS_len(&body) != 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BOOLEAN_IS_WRONG_LENGTH); + return 0; + } + if (v != 0 && v != 0xff) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + break; + } + } + + switch (tag) { + case CBS_ASN1_INTEGER: + return asn1_parse_integer(&elem, out, tag); + case CBS_ASN1_ENUMERATED: + return asn1_parse_enumerated(&elem, out, tag); + case CBS_ASN1_BITSTRING: + return asn1_parse_bit_string(&elem, out, tag); + case CBS_ASN1_UNIVERSALSTRING: + return asn1_parse_universal_string(&elem, out, tag); + case CBS_ASN1_BMPSTRING: + return asn1_parse_bmp_string(&elem, out, tag); + case CBS_ASN1_UTF8STRING: + return asn1_parse_utf8_string(&elem, out, tag); + case CBS_ASN1_UTCTIME: + // TODO(crbug.com/42290221): Reject timezone offsets here. We have no + // known cases where UTCTime inside ANY needs accept invalid timezones. + return asn1_parse_utc_time(&elem, out, tag, /*allow_timezone_offset=*/1); + case CBS_ASN1_GENERALIZEDTIME: + return asn1_parse_generalized_time(&elem, out, tag); + case CBS_ASN1_OCTETSTRING: + case CBS_ASN1_T61STRING: + case CBS_ASN1_IA5STRING: + case CBS_ASN1_NUMERICSTRING: + case CBS_ASN1_PRINTABLESTRING: + case CBS_ASN1_VIDEOTEXSTRING: + case CBS_ASN1_GRAPHICSTRING: + case CBS_ASN1_VISIBLESTRING: + case CBS_ASN1_GENERALSTRING: + // T61String is parsed as Latin-1, so all byte strings are valid. The + // others we currently do not enforce. + // + // TODO(crbug.com/42290290): Enforce the encoding of the other string + // types. + if (!asn1_parse_octet_string(&elem, out, tag)) { + return 0; + } + out->type = static_cast(tag); + return 1; + default: + // All unrecognized types, or types that cannot be represented as + // |ASN1_STRING|, are represented as the whole element. + if (!ASN1_STRING_set(out, CBS_data(&elem), CBS_len(&elem))) { + return 0; + } + if (tag == CBS_ASN1_SEQUENCE) { + out->type = V_ASN1_SEQUENCE; + } else if (tag == CBS_ASN1_SET) { + out->type = V_ASN1_SET; + } else { + out->type = V_ASN1_OTHER; + } + return 1; + } +} + +int asn1_marshal_any(CBB *out, const ASN1_TYPE *in) { + switch (in->type) { + case V_ASN1_OBJECT: + return asn1_marshal_object(out, in->value.object, /*tag=*/0); + case V_ASN1_NULL: + return CBB_add_asn1_element(out, CBS_ASN1_NULL, nullptr, 0); + case V_ASN1_BOOLEAN: + return CBB_add_asn1_bool(out, in->value.boolean != ASN1_BOOLEAN_FALSE); + case V_ASN1_INTEGER: + case V_ASN1_ENUMERATED: + return asn1_marshal_integer(out, in->value.integer, + static_cast(in->type)); + case V_ASN1_BIT_STRING: + return asn1_marshal_bit_string(out, in->value.bit_string, /*tag=*/0); + case V_ASN1_OCTET_STRING: + case V_ASN1_NUMERICSTRING: + case V_ASN1_PRINTABLESTRING: + case V_ASN1_T61STRING: + case V_ASN1_VIDEOTEXSTRING: + case V_ASN1_IA5STRING: + case V_ASN1_UTCTIME: + case V_ASN1_GENERALIZEDTIME: + case V_ASN1_GRAPHICSTRING: + case V_ASN1_VISIBLESTRING: + case V_ASN1_GENERALSTRING: + case V_ASN1_UNIVERSALSTRING: + case V_ASN1_BMPSTRING: + case V_ASN1_UTF8STRING: + return asn1_marshal_octet_string(out, in->value.asn1_string, + static_cast(in->type)); + case V_ASN1_SEQUENCE: + case V_ASN1_SET: + case V_ASN1_OTHER: + // These three types store the whole TLV as contents. + return CBB_add_bytes(out, ASN1_STRING_get0_data(in->value.asn1_string), + ASN1_STRING_length(in->value.asn1_string)); + default: + // |ASN1_TYPE|s can have type -1 when default-constructed. + OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TYPE); + return 0; + } +} diff --git a/Sources/CCryptoBoringSSL/crypto/asn1/a_utctm.cc b/Sources/CCryptoBoringSSL/crypto/asn1/a_utctm.cc index bedf96fe2..b2452116d 100644 --- a/Sources/CCryptoBoringSSL/crypto/asn1/a_utctm.cc +++ b/Sources/CCryptoBoringSSL/crypto/asn1/a_utctm.cc @@ -37,6 +37,22 @@ int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d, return 1; } +int asn1_parse_utc_time(CBS *cbs, ASN1_UTCTIME *out, CBS_ASN1_TAG tag, + int allow_timezone_offset) { + tag = tag == 0 ? CBS_ASN1_UTCTIME : tag; + CBS child; + if (!CBS_get_asn1(cbs, &child, tag) || + !CBS_parse_utc_time(&child, nullptr, allow_timezone_offset)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + if (!ASN1_STRING_set(out, CBS_data(&child), CBS_len(&child))) { + return 0; + } + out->type = V_ASN1_UTCTIME; + return 1; +} + int ASN1_UTCTIME_check(const ASN1_UTCTIME *d) { return asn1_utctime_to_tm(NULL, d, /*allow_timezone_offset=*/1); } diff --git a/Sources/CCryptoBoringSSL/crypto/asn1/asn1_lib.cc b/Sources/CCryptoBoringSSL/crypto/asn1/asn1_lib.cc index aeb3660b3..6efa45028 100644 --- a/Sources/CCryptoBoringSSL/crypto/asn1/asn1_lib.cc +++ b/Sources/CCryptoBoringSSL/crypto/asn1/asn1_lib.cc @@ -295,11 +295,21 @@ ASN1_STRING *ASN1_STRING_type_new(int type) { return ret; } +void asn1_string_init(ASN1_STRING *str, int type) { + OPENSSL_memset(str, 0, sizeof(ASN1_STRING)); + str->type = type; +} + +void asn1_string_cleanup(ASN1_STRING *str) { + OPENSSL_free(str->data); + str->data = nullptr; +} + void ASN1_STRING_free(ASN1_STRING *str) { if (str == NULL) { return; } - OPENSSL_free(str->data); + asn1_string_cleanup(str); OPENSSL_free(str); } @@ -353,3 +363,70 @@ unsigned char *ASN1_STRING_data(ASN1_STRING *str) { return str->data; } const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *str) { return str->data; } + +int asn1_parse_octet_string(CBS *cbs, ASN1_STRING *out, CBS_ASN1_TAG tag) { + tag = tag == 0 ? CBS_ASN1_OCTETSTRING : tag; + CBS child; + if (!CBS_get_asn1(cbs, &child, tag)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + if (!ASN1_STRING_set(out, CBS_data(&child), CBS_len(&child))) { + return 0; + } + out->type = V_ASN1_OCTET_STRING; + return 1; +} + +int asn1_marshal_octet_string(CBB *out, const ASN1_STRING *in, + CBS_ASN1_TAG tag) { + tag = tag == 0 ? CBS_ASN1_OCTETSTRING : tag; + return CBB_add_asn1_element(out, tag, ASN1_STRING_get0_data(in), + ASN1_STRING_length(in)); +} + +static int asn1_parse_character_string(CBS *cbs, ASN1_STRING *out, + CBS_ASN1_TAG tag, int str_type, + int (*get_char)(CBS *cbs, uint32_t *), + int bad_char_err) { + CBS child; + if (!CBS_get_asn1(cbs, &child, tag)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + CBS copy = child; + while (CBS_len(©) != 0) { + uint32_t c; + if (!get_char(©, &c)) { + OPENSSL_PUT_ERROR(ASN1, bad_char_err); + return 0; + } + } + if (!ASN1_STRING_set(out, CBS_data(&child), CBS_len(&child))) { + return 0; + } + out->type = str_type; + return 1; +} + +int asn1_parse_bmp_string(CBS *cbs, ASN1_BMPSTRING *out, CBS_ASN1_TAG tag) { + tag = tag == 0 ? CBS_ASN1_BMPSTRING : tag; + return asn1_parse_character_string(cbs, out, tag, V_ASN1_BMPSTRING, + &CBS_get_ucs2_be, + ASN1_R_INVALID_BMPSTRING); +} + +int asn1_parse_universal_string(CBS *cbs, ASN1_UNIVERSALSTRING *out, + CBS_ASN1_TAG tag) { + tag = tag == 0 ? CBS_ASN1_UNIVERSALSTRING : tag; + return asn1_parse_character_string(cbs, out, tag, V_ASN1_UNIVERSALSTRING, + &CBS_get_utf32_be, + ASN1_R_INVALID_UNIVERSALSTRING); +} + +int asn1_parse_utf8_string(CBS *cbs, ASN1_UNIVERSALSTRING *out, + CBS_ASN1_TAG tag) { + tag = tag == 0 ? CBS_ASN1_UTF8STRING : tag; + return asn1_parse_character_string(cbs, out, tag, V_ASN1_UTF8STRING, + &CBS_get_utf8, ASN1_R_INVALID_UTF8STRING); +} diff --git a/Sources/CCryptoBoringSSL/crypto/asn1/internal.h b/Sources/CCryptoBoringSSL/crypto/asn1/internal.h index 7c1576b51..5b8c63b50 100644 --- a/Sources/CCryptoBoringSSL/crypto/asn1/internal.h +++ b/Sources/CCryptoBoringSSL/crypto/asn1/internal.h @@ -48,7 +48,8 @@ OPENSSL_EXPORT int OPENSSL_gmtime_diff(int *out_days, int *out_secs, const struct tm *from, const struct tm *to); -// Internal ASN1 structures and functions: not for application use + +// Object identifiers. // These are used internally in the ASN1_OBJECT to keep track of // whether the names and data need to be free()ed @@ -72,6 +73,130 @@ struct asn1_object_st { ASN1_OBJECT *ASN1_OBJECT_new(void); +// asn1_parse_object parses a DER-encoded ASN.1 OBJECT IDENTIFIER from |cbs| and +// write the result to |out|. If |tag| is non-zero, the value is implicitly +// tagged with |tag|. On success, it returns a newly-allocated |ASN1_OBJECT| +// with the result and advances |cbs| past the parsed element. +// +// TODO(crbug.com/boringssl/414361735): This should return a bssl::UniquePtr, +// but cannot until it is made C++ linkage. +ASN1_OBJECT *asn1_parse_object(CBS *cbs, CBS_ASN1_TAG tag); + +// asn1_marshal_object marshals |in| as a DER-encoded, ASN.1 OBJECT IDENTIFIER +// and writes the result to |out|. It returns one on success and zero on error. +// If |tag| is non-zero, the tag is replaced with |tag|. +int asn1_marshal_object(CBB *out, const ASN1_OBJECT *in, CBS_ASN1_TAG tag); + + +// Strings. + +// asn1_is_printable returns one if |value| is a valid Unicode codepoint for an +// ASN.1 PrintableString, and zero otherwise. +int asn1_is_printable(uint32_t value); + +// asn1_string_init initializes |str|, which may be uninitialized, with type +// |type|. +void asn1_string_init(ASN1_STRING *str, int type); + +// asn1_string_cleanup releases memory associated with |str|'s value, without +// freeing |str| itself. +void asn1_string_cleanup(ASN1_STRING *str); + +// asn1_bit_string_length returns the number of bytes in |str| and sets +// |*out_padding_bits| to the number of padding bits. +// +// This function should be used instead of |ASN1_STRING_length| to correctly +// handle the non-|ASN1_STRING_FLAG_BITS_LEFT| case. +int asn1_bit_string_length(const ASN1_BIT_STRING *str, + uint8_t *out_padding_bits); + +// The following functions parse a DER-encoded ASN.1 value of the specified +// type from |cbs| and write the result to |*out|. If |tag| is non-zero, the +// value is implicitly tagged with |tag|. On success, they return one and +// advance |cbs| past the parsed element. On entry, |*out| must contain an +// |ASN1_STRING| in some valid state. +int asn1_parse_bit_string(CBS *cbs, ASN1_BIT_STRING *out, CBS_ASN1_TAG tag); +int asn1_parse_integer(CBS *cbs, ASN1_INTEGER *out, CBS_ASN1_TAG tag); +int asn1_parse_enumerated(CBS *cbs, ASN1_ENUMERATED *out, CBS_ASN1_TAG tag); +int asn1_parse_octet_string(CBS *cbs, ASN1_STRING *out, CBS_ASN1_TAG tag); +int asn1_parse_bmp_string(CBS *cbs, ASN1_BMPSTRING *out, CBS_ASN1_TAG tag); +int asn1_parse_universal_string(CBS *cbs, ASN1_UNIVERSALSTRING *out, + CBS_ASN1_TAG tag); +int asn1_parse_utf8_string(CBS *cbs, ASN1_UNIVERSALSTRING *out, + CBS_ASN1_TAG tag); +int asn1_parse_generalized_time(CBS *cbs, ASN1_GENERALIZEDTIME *out, + CBS_ASN1_TAG tag); +int asn1_parse_utc_time(CBS *cbs, ASN1_UTCTIME *out, CBS_ASN1_TAG tag, + int allow_timezone_offset); + +// asn1_parse_bit_string_with_bad_length behaves like |asn1_parse_bit_string| +// but tolerates BER non-minimal, definite lengths. +int asn1_parse_bit_string_with_bad_length(CBS *cbs, ASN1_BIT_STRING *out); + +// asn1_marshal_bit_string marshals |in| as a DER-encoded, ASN.1 BIT STRING and +// writes the result to |out|. It returns one on success and zero on error. If +// |tag| is non-zero, the tag is replaced with |tag|. +int asn1_marshal_bit_string(CBB *out, const ASN1_BIT_STRING *in, + CBS_ASN1_TAG tag); + +// asn1_marshal_integer marshals |in| as a DER-encoded, ASN.1 INTEGER and writes +// the result to |out|. It returns one on success and zero on error. If |tag| is +// non-zero, the tag is replaced with |tag|. This can also be used to marshal an +// ASN.1 ENUMERATED value by overriding the tag. +int asn1_marshal_integer(CBB *out, const ASN1_INTEGER *in, CBS_ASN1_TAG tag); + +// asn1_marshal_octet_string marshals |in| as a DER-encoded, ASN.1 OCTET STRING +// and writes the result to |out|. It returns one on success and zero on error. +// If |tag| is non-zero, the tag is replaced with |tag|. +// +// This function may be used to marshal other string-based universal types whose +// encoding is that of an implicitly-tagged OCTET STRING, e.g. UTF8String. +int asn1_marshal_octet_string(CBB *out, const ASN1_STRING *in, + CBS_ASN1_TAG tag); + +OPENSSL_EXPORT int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d, + int allow_timezone_offset); +OPENSSL_EXPORT int asn1_generalizedtime_to_tm(struct tm *tm, + const ASN1_GENERALIZEDTIME *d); + +int asn1_parse_time(CBS *cbs, ASN1_TIME *out, int allow_utc_timezone_offset); +int asn1_marshal_time(CBB *cbb, const ASN1_TIME *in); + + +// The ASN.1 ANY type. + +// asn1_type_value_as_pointer returns |a|'s value in pointer form. This is +// usually the value object but, for BOOLEAN values, is 0 or 0xff cast to +// a pointer. +const void *asn1_type_value_as_pointer(const ASN1_TYPE *a); + +// asn1_type_set0_string sets |a|'s value to the object represented by |str| and +// takes ownership of |str|. +void asn1_type_set0_string(ASN1_TYPE *a, ASN1_STRING *str); + +// asn1_type_cleanup releases memory associated with |a|'s value, without +// freeing |a| itself. +void asn1_type_cleanup(ASN1_TYPE *a); + +// asn1_parse_any parses a DER-encoded ASN.1 value of any type from |cbs| and +// writes the result to |*out|. On success, it advances |cbs| past the parsed +// element and returns one. On entry, |*out| must contain an |ASN1_TYPE| in some +// valid state. +int asn1_parse_any(CBS *cbs, ASN1_TYPE *out); + +// asn1_parse_any_as_string behaves like |asn1_parse_any| but represents the +// value as an |ASN1_STRING|. Types which are not represented with +// |ASN1_STRING|, such as |ASN1_OBJECT|, are represented with type +// |V_ASN1_OTHER|. +int asn1_parse_any_as_string(CBS *cbs, ASN1_STRING *out); + +// asn1_marshal_any marshals |in| as a DER-encoded ASN.1 value and writes the +// result to |out|. It returns one on success and zeron on error. +int asn1_marshal_any(CBB *out, const ASN1_TYPE *in); + + +// Support structures for the template-based encoder. + // ASN1_ENCODING is used to save the received encoding of an ASN.1 type. This // avoids problems with invalid encodings that break signatures. typedef struct ASN1_ENCODING_st { @@ -79,16 +204,8 @@ typedef struct ASN1_ENCODING_st { uint8_t *enc; // len is the length of |enc|. If zero, there is no saved encoding. size_t len; - // buf, if non-NULL, is the |CRYPTO_BUFFER| that |enc| points into. If NULL, - // |enc| must be released with |OPENSSL_free|. - CRYPTO_BUFFER *buf; } ASN1_ENCODING; -OPENSSL_EXPORT int asn1_utctime_to_tm(struct tm *tm, const ASN1_UTCTIME *d, - int allow_timezone_offset); -OPENSSL_EXPORT int asn1_generalizedtime_to_tm(struct tm *tm, - const ASN1_GENERALIZEDTIME *d); - int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it); void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it); @@ -97,14 +214,12 @@ void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); // ASN1_item_ex_d2i parses |len| bytes from |*in| as a structure of type |it| // and writes the result to |*pval|. If |tag| is non-negative, |it| is // implicitly tagged with the tag specified by |tag| and |aclass|. If |opt| is -// non-zero, the value is optional. If |buf| is non-NULL, |*in| must point into -// |buf|. +// non-zero, the value is optional. // // This function returns one and advances |*in| if an object was successfully // parsed, -1 if an optional value was successfully skipped, and zero on error. int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, - const ASN1_ITEM *it, int tag, int aclass, char opt, - CRYPTO_BUFFER *buf); + const ASN1_ITEM *it, int tag, int aclass, char opt); // ASN1_item_ex_i2d encodes |*pval| as a value of type |it| to |out| under the // i2d output convention. It returns a non-zero length on success and -1 on @@ -150,47 +265,11 @@ int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, // returns one on success and zero on error. If |buf| is non-NULL, |in| must // point into |buf|. int asn1_enc_save(ASN1_VALUE **pval, const uint8_t *in, size_t inlen, - const ASN1_ITEM *it, CRYPTO_BUFFER *buf); + const ASN1_ITEM *it); // asn1_encoding_clear clears the cached encoding in |enc|. void asn1_encoding_clear(ASN1_ENCODING *enc); -// asn1_type_value_as_pointer returns |a|'s value in pointer form. This is -// usually the value object but, for BOOLEAN values, is 0 or 0xff cast to -// a pointer. -const void *asn1_type_value_as_pointer(const ASN1_TYPE *a); - -// asn1_type_set0_string sets |a|'s value to the object represented by |str| and -// takes ownership of |str|. -void asn1_type_set0_string(ASN1_TYPE *a, ASN1_STRING *str); - -// asn1_type_cleanup releases memory associated with |a|'s value, without -// freeing |a| itself. -void asn1_type_cleanup(ASN1_TYPE *a); - -// asn1_is_printable returns one if |value| is a valid Unicode codepoint for an -// ASN.1 PrintableString, and zero otherwise. -int asn1_is_printable(uint32_t value); - -// asn1_bit_string_length returns the number of bytes in |str| and sets -// |*out_padding_bits| to the number of padding bits. -// -// This function should be used instead of |ASN1_STRING_length| to correctly -// handle the non-|ASN1_STRING_FLAG_BITS_LEFT| case. -int asn1_bit_string_length(const ASN1_BIT_STRING *str, - uint8_t *out_padding_bits); - -// asn1_marshal_bit_string marshals |in| as a DER-encoded, ASN.1 BIT STRING and -// writes the result to |out|. It returns one on success and zero on error. If -// |tag| is non-zero, the tag is replaced with |tag|. -int asn1_marshal_bit_string(CBB *out, const ASN1_BIT_STRING *in, - CBS_ASN1_TAG tag); - -// asn1_marshal_integer marshals |in| as a DER-encoded, ASN.1 INTEGER and writes -// the result to |out|. It returns one on success and zero on error. If |tag| is -// non-zero, the tag is replaced with |tag|. -int asn1_marshal_integer(CBB *out, const ASN1_INTEGER *in, CBS_ASN1_TAG tag); - typedef struct { int nid; long minsize; @@ -210,8 +289,18 @@ typedef ASN1_VALUE *ASN1_d2i_func(ASN1_VALUE **a, const unsigned char **in, long length); typedef int ASN1_i2d_func(ASN1_VALUE *a, unsigned char **in); -typedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, - const ASN1_ITEM *it, int opt, ASN1_TLC *ctx); +// An ASN1_ex_parse function should parse a value from |cbs| and set |*pval| to +// the result. It should return one on success and zero on failure. If |opt| is +// non-zero, the field may be optional. If an optional element is missing, the +// function should return one and consume zero bytes from |cbs|. +// +// If |opt| is non-zero, the function can assume that |*pval| is nullptr on +// entry. Otherwise, |*pval| may either be nullptr, or the result of +// |ASN1_ex_new_func|. The function may either write into the existing object, +// if any, or unconditionally make a new one. (The existing object comes from +// tasn_new.cc recursively filling in objects before parsing into them.) +typedef int ASN1_ex_parse(ASN1_VALUE **pval, CBS *cbs, const ASN1_ITEM *it, + int opt); typedef int ASN1_ex_i2d(ASN1_VALUE **pval, unsigned char **out, const ASN1_ITEM *it); @@ -221,10 +310,57 @@ typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it); typedef struct ASN1_EXTERN_FUNCS_st { ASN1_ex_new_func *asn1_ex_new; ASN1_ex_free_func *asn1_ex_free; - ASN1_ex_d2i *asn1_ex_d2i; + ASN1_ex_parse *asn1_ex_parse; ASN1_ex_i2d *asn1_ex_i2d; } ASN1_EXTERN_FUNCS; +#define IMPLEMENT_EXTERN_ASN1_SIMPLE(name, new_func, free_func, parse_func, \ + i2d_func) \ + static int name##_new_cb(ASN1_VALUE **pval, const ASN1_ITEM *it) { \ + *pval = (ASN1_VALUE *)new_func(); \ + return *pval != nullptr; \ + } \ + \ + static void name##_free_cb(ASN1_VALUE **pval, const ASN1_ITEM *it) { \ + free_func((name *)*pval); \ + *pval = nullptr; \ + } \ + \ + static int name##_parse_cb(ASN1_VALUE **pval, CBS *cbs, const ASN1_ITEM *it, \ + int opt) { \ + if (opt && !CBS_peek_asn1_tag(cbs, CBS_ASN1_SEQUENCE)) { \ + return 1; \ + } \ + \ + if ((*pval == nullptr && !name##_new_cb(pval, it)) || \ + !parse_func(cbs, (name *)*pval)) { \ + return 0; \ + } \ + return 1; \ + } \ + \ + static int name##_i2d_cb(ASN1_VALUE **pval, unsigned char **out, \ + const ASN1_ITEM *it) { \ + return i2d_func((name *)*pval, out); \ + } \ + \ + static const ASN1_EXTERN_FUNCS name##_extern_funcs = { \ + name##_new_cb, name##_free_cb, name##_parse_cb, name##_i2d_cb}; \ + \ + IMPLEMENT_EXTERN_ASN1(name, name##_extern_funcs) + +// ASN1_TIME is an |ASN1_ITEM| whose ASN.1 type is X.509 Time (RFC 5280) and C +// type is |ASN1_TIME*|. +DECLARE_ASN1_ITEM(ASN1_TIME) + +// DIRECTORYSTRING is an |ASN1_ITEM| whose ASN.1 type is X.509 DirectoryString +// (RFC 5280) and C type is |ASN1_STRING*|. +DECLARE_ASN1_ITEM(DIRECTORYSTRING) + +// DISPLAYTEXT is an |ASN1_ITEM| whose ASN.1 type is X.509 DisplayText (RFC +// 5280) and C type is |ASN1_STRING*|. +DECLARE_ASN1_ITEM(DISPLAYTEXT) + // ASN1_ANY_AS_STRING is an |ASN1_ITEM| with ASN.1 type ANY and C type // |ASN1_STRING*|. Types which are not represented with |ASN1_STRING|, such as // |ASN1_OBJECT|, are represented with type |V_ASN1_OTHER|. diff --git a/Sources/CCryptoBoringSSL/crypto/asn1/tasn_dec.cc b/Sources/CCryptoBoringSSL/crypto/asn1/tasn_dec.cc index 690083665..acc3cf661 100644 --- a/Sources/CCryptoBoringSSL/crypto/asn1/tasn_dec.cc +++ b/Sources/CCryptoBoringSSL/crypto/asn1/tasn_dec.cc @@ -39,18 +39,16 @@ static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, static int asn1_template_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, - CRYPTO_BUFFER *buf, int depth); + int depth); static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, - CRYPTO_BUFFER *buf, int depth); -static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, long len, - int utype, const ASN1_ITEM *it); + int depth); static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it, int tag, int aclass, char opt); static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it, int tag, int aclass, - char opt, CRYPTO_BUFFER *buf, int depth); + char opt, int depth); unsigned long ASN1_tag2bit(int tag) { switch (tag) { @@ -91,25 +89,6 @@ unsigned long ASN1_tag2bit(int tag) { } } -static int is_supported_universal_type(int tag, int aclass) { - if (aclass != V_ASN1_UNIVERSAL) { - return 0; - } - return tag == V_ASN1_OBJECT || tag == V_ASN1_NULL || tag == V_ASN1_BOOLEAN || - tag == V_ASN1_BIT_STRING || tag == V_ASN1_INTEGER || - tag == V_ASN1_ENUMERATED || tag == V_ASN1_OCTET_STRING || - tag == V_ASN1_NUMERICSTRING || tag == V_ASN1_PRINTABLESTRING || - tag == V_ASN1_T61STRING || tag == V_ASN1_VIDEOTEXSTRING || - tag == V_ASN1_IA5STRING || tag == V_ASN1_UTCTIME || - tag == V_ASN1_GENERALIZEDTIME || tag == V_ASN1_GRAPHICSTRING || - tag == V_ASN1_VISIBLESTRING || tag == V_ASN1_GENERALSTRING || - tag == V_ASN1_UNIVERSALSTRING || tag == V_ASN1_BMPSTRING || - tag == V_ASN1_UTF8STRING || tag == V_ASN1_SET || - tag == V_ASN1_SEQUENCE; -} - -// Macro to initialize and invalidate the cache - // Decode an ASN1 item, this currently behaves just like a standard 'd2i' // function. 'in' points to a buffer to read the data from, in future we // will have more advanced versions that can input data a piece at a time and @@ -119,7 +98,7 @@ ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it) { ASN1_VALUE *ret = NULL; if (asn1_item_ex_d2i(&ret, in, len, it, /*tag=*/-1, /*aclass=*/0, /*opt=*/0, - /*buf=*/NULL, /*depth=*/0) <= 0) { + /*depth=*/0) <= 0) { // Clean up, in case the caller left a partial object. // // TODO(davidben): I don't think it can leave one, but the codepaths below @@ -149,7 +128,7 @@ ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, const ASN1_ITEM *it, int tag, int aclass, - char opt, CRYPTO_BUFFER *buf, int depth) { + char opt, int depth) { const ASN1_TEMPLATE *tt, *errtt = NULL; const unsigned char *p = NULL, *q; unsigned char oclass; @@ -161,10 +140,9 @@ static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, if (!pval) { return 0; } - - if (buf != NULL) { - assert(CRYPTO_BUFFER_data(buf) <= *in && - *in + len <= CRYPTO_BUFFER_data(buf) + CRYPTO_BUFFER_len(buf)); + if (len < 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BUFFER_TOO_SMALL); + goto err; } // Bound |len| to comfortably fit in an int. Lengths in this module often @@ -189,11 +167,9 @@ static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE); goto err; } - return asn1_template_ex_d2i(pval, in, len, it->templates, opt, buf, - depth); + return asn1_template_ex_d2i(pval, in, len, it->templates, opt, depth); } return asn1_d2i_ex_primitive(pval, in, len, it, tag, aclass, opt); - break; case ASN1_ITYPE_MSTRING: // It never makes sense for multi-strings to have implicit tagging, so @@ -239,7 +215,18 @@ static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, } const ASN1_EXTERN_FUNCS *ef = reinterpret_cast(it->funcs); - return ef->asn1_ex_d2i(pval, in, len, it, opt, NULL); + CBS cbs; + CBS_init(&cbs, *in, len); + CBS copy = cbs; + if (!ef->asn1_ex_parse(pval, &cbs, it, opt)) { + goto err; + } + *in = CBS_data(&cbs); + // Check whether the function skipped an optional element. + // + // TODO(crbug.com/42290418): Switch the rest of this function to + // |asn1_ex_parse|'s calling convention. + return CBS_len(&cbs) == CBS_len(©) ? -1 : 1; } case ASN1_ITYPE_CHOICE: { @@ -274,7 +261,7 @@ static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { pchptr = asn1_get_field_ptr(pval, tt); // We mark field as OPTIONAL so its absence can be recognised. - ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, buf, depth); + ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, depth); // If field not present, try the next one if (ret == -1) { continue; @@ -380,7 +367,7 @@ static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, } // attempt to read in field, allowing each to be OPTIONAL - ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, buf, depth); + ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, depth); if (!ret) { errtt = seqtt; goto err; @@ -419,7 +406,7 @@ static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, } } // Save encoding - if (!asn1_enc_save(pval, *in, p - *in, it, buf)) { + if (!asn1_enc_save(pval, *in, p - *in, it)) { goto auxerr; } if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL)) { @@ -445,10 +432,8 @@ static int asn1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, } int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, - const ASN1_ITEM *it, int tag, int aclass, char opt, - CRYPTO_BUFFER *buf) { - return asn1_item_ex_d2i(pval, in, len, it, tag, aclass, opt, buf, - /*depth=*/0); + const ASN1_ITEM *it, int tag, int aclass, char opt) { + return asn1_item_ex_d2i(pval, in, len, it, tag, aclass, opt, /*depth=*/0); } // Templates are handled with two separate functions. One handles any @@ -456,7 +441,7 @@ int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, static int asn1_template_ex_d2i(ASN1_VALUE **val, const unsigned char **in, long inlen, const ASN1_TEMPLATE *tt, char opt, - CRYPTO_BUFFER *buf, int depth) { + int depth) { int aclass; int ret; long len; @@ -488,7 +473,7 @@ static int asn1_template_ex_d2i(ASN1_VALUE **val, const unsigned char **in, return 0; } // We've found the field so it can't be OPTIONAL now - ret = asn1_template_noexp_d2i(val, &p, len, tt, /*opt=*/0, buf, depth); + ret = asn1_template_noexp_d2i(val, &p, len, tt, /*opt=*/0, depth); if (!ret) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); return 0; @@ -501,7 +486,7 @@ static int asn1_template_ex_d2i(ASN1_VALUE **val, const unsigned char **in, goto err; } } else { - return asn1_template_noexp_d2i(val, in, inlen, tt, opt, buf, depth); + return asn1_template_noexp_d2i(val, in, inlen, tt, opt, depth); } *in = p; @@ -514,7 +499,7 @@ static int asn1_template_ex_d2i(ASN1_VALUE **val, const unsigned char **in, static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_TEMPLATE *tt, char opt, - CRYPTO_BUFFER *buf, int depth) { + int depth) { int aclass; int ret; const unsigned char *p; @@ -572,7 +557,8 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, const unsigned char *q = p; skfield = NULL; if (!asn1_item_ex_d2i(&skfield, &p, len, ASN1_ITEM_ptr(tt->item), - /*tag=*/-1, /*aclass=*/0, /*opt=*/0, buf, depth)) { + /*tag=*/-1, /*aclass=*/0, /*opt=*/0, depth)) { + ASN1_item_ex_free(&skfield, ASN1_ITEM_ptr(tt->item)); OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); goto err; } @@ -585,7 +571,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, } else if (flags & ASN1_TFLG_IMPTAG) { // IMPLICIT tagging ret = asn1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), tt->tag, - aclass, opt, buf, depth); + aclass, opt, depth); if (!ret) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); goto err; @@ -595,7 +581,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, } else { // Nothing special ret = asn1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), /*tag=*/-1, - /*aclass=*/0, opt, buf, depth); + /*aclass=*/0, opt, depth); if (!ret) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); goto err; @@ -612,306 +598,211 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val, const unsigned char **in, return 0; } +// TODO(crbug.com/42290418): Switch the whole file to use a CBS-based calling +// convention. +static int asn1_d2i_ex_primitive_cbs(ASN1_VALUE **pval, CBS *cbs, + const ASN1_ITEM *it, int tag, int aclass, + char opt); + +// asn1_d2i_ex_primitive returns one on success, zero on error, and -1 if an +// optional value was skipped. static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, const unsigned char **in, long inlen, const ASN1_ITEM *it, int tag, int aclass, char opt) { - int ret = 0, utype; - long plen; - char cst; - const unsigned char *p; - const unsigned char *cont = NULL; - long len; - if (!pval) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NULL); - return 0; // Should never happen + CBS cbs; + CBS_init(&cbs, *in, inlen); + int ret = asn1_d2i_ex_primitive_cbs(pval, &cbs, it, tag, aclass, opt); + if (ret <= 0) { + return ret; + } + *in = CBS_data(&cbs); + return 1; +} + +static ASN1_STRING *ensure_string(ASN1_VALUE **pval) { + if (*pval) { + return (ASN1_STRING *)*pval; } + ASN1_STRING *str = ASN1_STRING_new(); + if (str == nullptr) { + return nullptr; + } + *pval = (ASN1_VALUE *)str; + return str; +} + +static int asn1_d2i_ex_primitive_cbs(ASN1_VALUE **pval, CBS *cbs, + const ASN1_ITEM *it, int tag, int aclass, + char opt) { + // Historically, |it->funcs| for primitive types contained an + // |ASN1_PRIMITIVE_FUNCS| table of callbacks. + assert(it->funcs == NULL); + int utype; assert(it->itype == ASN1_ITYPE_PRIMITIVE || it->itype == ASN1_ITYPE_MSTRING); if (it->itype == ASN1_ITYPE_MSTRING) { + // MSTRING passes utype in |tag|, normally used for implicit tagging. utype = tag; tag = -1; } else { utype = it->utype; } + // Handle ANY types. if (utype == V_ASN1_ANY || utype == V_ASN1_ANY_AS_STRING) { - // If type is ANY need to figure out type from tag - unsigned char oclass; if (tag >= 0) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_TAGGED_ANY); return 0; } - if (opt) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OPTIONAL_ANY); - return 0; - } - const int is_string = utype == V_ASN1_ANY_AS_STRING; - p = *in; - ret = asn1_check_tlen(&plen, &utype, &oclass, &cst, &p, inlen, -1, 0, 0); - if (!ret) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); - return 0; - } - if (!is_supported_universal_type(utype, oclass)) { - utype = V_ASN1_OTHER; + if (opt && CBS_len(cbs) == 0) { + return -1; // Omitted OPTIONAL value. } - // These three types are not represented as |ASN1_STRING|, so they must be - // parsed separately and then treated as an opaque |V_ASN1_OTHER|. - if (is_string && (utype == V_ASN1_OBJECT || utype == V_ASN1_NULL || - utype == V_ASN1_BOOLEAN)) { - if (cst) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_PRIMITIVE); - return 0; - } - CBS cbs; - CBS_init(&cbs, p, plen); - if (utype == V_ASN1_OBJECT && !CBS_is_valid_asn1_oid(&cbs)) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_OBJECT_ENCODING); - return 0; - } - if (utype == V_ASN1_NULL && CBS_len(&cbs) != 0) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_NULL_IS_WRONG_LENGTH); + } + if (utype == V_ASN1_ANY) { + ASN1_TYPE *typ; + if (!*pval) { + typ = ASN1_TYPE_new(); + if (typ == NULL) { return 0; } - if (utype == V_ASN1_BOOLEAN) { - if (CBS_len(&cbs) != 1) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_BOOLEAN_IS_WRONG_LENGTH); - return 0; - } - uint8_t v = CBS_data(&cbs)[0]; - if (v != 0 && v != 0xff) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); - return 0; - } - } - utype = V_ASN1_OTHER; + *pval = (ASN1_VALUE *)typ; + } else { + typ = (ASN1_TYPE *)*pval; + } + return asn1_parse_any(cbs, typ); + } + if (utype == V_ASN1_ANY_AS_STRING) { + ASN1_STRING *str = ensure_string(pval); + if (str == nullptr) { + return 0; } + return asn1_parse_any_as_string(cbs, str); } + + // Convert the crypto/asn1 tag into a CBS one. if (tag == -1) { tag = utype; aclass = V_ASN1_UNIVERSAL; } - p = *in; - // Check header - ret = asn1_check_tlen(&plen, NULL, NULL, &cst, &p, inlen, tag, aclass, opt); - if (!ret) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); - return 0; - } else if (ret == -1) { - return -1; - } - ret = 0; - // SEQUENCE, SET and "OTHER" are left in encoded form - if ((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) || - (utype == V_ASN1_OTHER)) { - // SEQUENCE and SET must be constructed - if (utype != V_ASN1_OTHER && !cst) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_CONSTRUCTED); - return 0; - } - cont = *in; - len = p - cont + plen; - p += plen; - } else if (cst) { - // This parser historically supported BER constructed strings. We no - // longer do and will gradually tighten this parser into a DER - // parser. BER types should use |CBS_asn1_ber_to_der|. - OPENSSL_PUT_ERROR(ASN1, ASN1_R_TYPE_NOT_PRIMITIVE); - return 0; - } else { - cont = p; - len = plen; - p += plen; + // All edge cases of |utype| should have been handled already. |utype| is now + // either a primitive |ASN1_ITEM|, handled by |DECLARE_ASN1_ITEM|, or a + // multistring option with a corresponding |B_ASN1_*| constant. + assert(utype >= 0 && utype <= V_ASN1_MAX_UNIVERSAL); + CBS_ASN1_TAG cbs_tag = + (static_cast(aclass) << CBS_ASN1_TAG_SHIFT) | + static_cast(tag); + if (utype == V_ASN1_SEQUENCE || utype == V_ASN1_SET) { + cbs_tag |= CBS_ASN1_CONSTRUCTED; } - // We now have content length and type: translate into a structure - if (!asn1_ex_c2i(pval, cont, len, utype, it)) { - goto err; + if (opt && !CBS_peek_asn1_tag(cbs, cbs_tag)) { + return -1; // Omitted OPTIONAL value. } - *in = p; - ret = 1; -err: - return ret; -} - -// Translate ASN1 content octets into a structure - -static int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, long len, - int utype, const ASN1_ITEM *it) { - ASN1_VALUE **opval = NULL; - ASN1_STRING *stmp; - ASN1_TYPE *typ = NULL; - int ret = 0; - ASN1_INTEGER **tint; - - // Historically, |it->funcs| for primitive types contained an - // |ASN1_PRIMITIVE_FUNCS| table of callbacks. - assert(it->funcs == NULL); - - // If ANY type clear type and set pointer to internal value - if (it->utype == V_ASN1_ANY) { - if (!*pval) { - typ = ASN1_TYPE_new(); - if (typ == NULL) { - goto err; + // Handle non-|ASN1_STRING| types. + switch (utype) { + case V_ASN1_OBJECT: { + bssl::UniquePtr obj(asn1_parse_object(cbs, cbs_tag)); + if (obj == nullptr) { + return 0; } - *pval = (ASN1_VALUE *)typ; - } else { - typ = (ASN1_TYPE *)*pval; - } - - if (utype != typ->type) { - ASN1_TYPE_set(typ, utype, NULL); + ASN1_OBJECT_free((ASN1_OBJECT *)*pval); + *pval = (ASN1_VALUE *)obj.release(); + return 1; } - opval = pval; - pval = &typ->value.asn1_value; - } - - // If implementing a type that is not represented in |ASN1_STRING|, the - // |V_ASN1_ANY_AS_STRING| logic must be modified to redirect it to - // |V_ASN1_OTHER|. - switch (utype) { - case V_ASN1_OBJECT: - if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len)) { - goto err; + case V_ASN1_NULL: { + CBS null; + if (!CBS_get_asn1(cbs, &null, cbs_tag)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; } - break; - - case V_ASN1_NULL: - if (len) { + if (CBS_len(&null) != 0) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_NULL_IS_WRONG_LENGTH); - goto err; + return 0; } *pval = (ASN1_VALUE *)1; - break; - - case V_ASN1_BOOLEAN: - if (len != 1) { + return 1; + } + case V_ASN1_BOOLEAN: { + CBS child; + if (!CBS_get_asn1(cbs, &child, cbs_tag)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + // TODO(crbug.com/42290221): Reject invalid BOOLEAN encodings and just + // call |CBS_get_asn1_bool|. + if (CBS_len(&child) != 1) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_BOOLEAN_IS_WRONG_LENGTH); - goto err; - } else { - ASN1_BOOLEAN *tbool; - tbool = (ASN1_BOOLEAN *)pval; - *tbool = *cont; + return 0; } - break; + ASN1_BOOLEAN *tbool; + tbool = (ASN1_BOOLEAN *)pval; + *tbool = CBS_data(&child)[0]; + return 1; + } + } - case V_ASN1_BIT_STRING: - if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len)) { - goto err; - } - break; + // All other types as an |ASN1_STRING| representation. + ASN1_STRING *str = ensure_string(pval); + if (str == nullptr) { + return 0; + } + switch (utype) { + case V_ASN1_BIT_STRING: + return asn1_parse_bit_string(cbs, str, cbs_tag); case V_ASN1_INTEGER: + return asn1_parse_integer(cbs, str, cbs_tag); case V_ASN1_ENUMERATED: - tint = (ASN1_INTEGER **)pval; - if (!c2i_ASN1_INTEGER(tint, &cont, len)) { - goto err; - } - // Fixup type to match the expected form - (*tint)->type = utype | ((*tint)->type & V_ASN1_NEG); - break; - + return asn1_parse_enumerated(cbs, str, cbs_tag); + case V_ASN1_UNIVERSALSTRING: + return asn1_parse_universal_string(cbs, str, cbs_tag); + case V_ASN1_BMPSTRING: + return asn1_parse_bmp_string(cbs, str, cbs_tag); + case V_ASN1_UTF8STRING: + return asn1_parse_utf8_string(cbs, str, cbs_tag); + case V_ASN1_UTCTIME: + // TODO(crbug.com/42290221): Reject timezone offsets. We need to parse + // invalid timestamps in |X509| objects, but that parser no longer uses + // this code. + return asn1_parse_utc_time(cbs, str, cbs_tag, + /*allow_timezone_offset=*/1); + case V_ASN1_GENERALIZEDTIME: + return asn1_parse_generalized_time(cbs, str, cbs_tag); case V_ASN1_OCTET_STRING: case V_ASN1_NUMERICSTRING: case V_ASN1_PRINTABLESTRING: case V_ASN1_T61STRING: case V_ASN1_VIDEOTEXSTRING: case V_ASN1_IA5STRING: - case V_ASN1_UTCTIME: - case V_ASN1_GENERALIZEDTIME: case V_ASN1_GRAPHICSTRING: case V_ASN1_VISIBLESTRING: case V_ASN1_GENERALSTRING: - case V_ASN1_UNIVERSALSTRING: - case V_ASN1_BMPSTRING: - case V_ASN1_UTF8STRING: - case V_ASN1_OTHER: - case V_ASN1_SET: - case V_ASN1_SEQUENCE: { - CBS cbs; - CBS_init(&cbs, cont, (size_t)len); - if (utype == V_ASN1_BMPSTRING) { - while (CBS_len(&cbs) != 0) { - uint32_t c; - if (!CBS_get_ucs2_be(&cbs, &c)) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BMPSTRING); - goto err; - } - } - } - if (utype == V_ASN1_UNIVERSALSTRING) { - while (CBS_len(&cbs) != 0) { - uint32_t c; - if (!CBS_get_utf32_be(&cbs, &c)) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_UNIVERSALSTRING); - goto err; - } - } - } - if (utype == V_ASN1_UTF8STRING) { - while (CBS_len(&cbs) != 0) { - uint32_t c; - if (!CBS_get_utf8(&cbs, &c)) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_UTF8STRING); - goto err; - } - } - } - if (utype == V_ASN1_UTCTIME) { - if (!CBS_parse_utc_time(&cbs, NULL, /*allow_timezone_offset=*/1)) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_TIME_FORMAT); - goto err; - } - } - if (utype == V_ASN1_GENERALIZEDTIME) { - if (!CBS_parse_generalized_time(&cbs, NULL, - /*allow_timezone_offset=*/0)) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_TIME_FORMAT); - goto err; - } - } - // TODO(https://crbug.com/boringssl/427): Check other string types. - - // All based on ASN1_STRING and handled the same - if (!*pval) { - stmp = ASN1_STRING_type_new(utype); - if (!stmp) { - goto err; - } - *pval = (ASN1_VALUE *)stmp; - } else { - stmp = (ASN1_STRING *)*pval; - stmp->type = utype; + // T61String is parsed as Latin-1, so all byte strings are valid. The + // others we currently do not enforce. + // + // TODO(crbug.com/42290290): Enforce the encoding of the other string + // types. + if (!asn1_parse_octet_string(cbs, str, cbs_tag)) { + return 0; } - if (!ASN1_STRING_set(stmp, cont, len)) { - ASN1_STRING_free(stmp); - *pval = NULL; - goto err; + str->type = utype; + return 1; + case V_ASN1_SEQUENCE: { + // Save the entire element in the string. + CBS elem; + if (!CBS_get_asn1_element(cbs, &elem, cbs_tag)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; } - break; + str->type = V_ASN1_SEQUENCE; + return ASN1_STRING_set(str, CBS_data(&elem), CBS_len(&elem)); } - default: OPENSSL_PUT_ERROR(ASN1, ASN1_R_BAD_TEMPLATE); - goto err; - } - // If ASN1_ANY and NULL type fix up value - if (typ && (utype == V_ASN1_NULL)) { - typ->value.ptr = NULL; - } - - ret = 1; -err: - if (!ret) { - ASN1_TYPE_free(typ); - if (opval) { - *opval = NULL; + return 0; } - } - return ret; } // Check an ASN1 tag and length: a bit like ASN1_get_object but it diff --git a/Sources/CCryptoBoringSSL/crypto/asn1/tasn_typ.cc b/Sources/CCryptoBoringSSL/crypto/asn1/tasn_typ.cc index 313abb814..05526b5f7 100644 --- a/Sources/CCryptoBoringSSL/crypto/asn1/tasn_typ.cc +++ b/Sources/CCryptoBoringSSL/crypto/asn1/tasn_typ.cc @@ -19,6 +19,9 @@ #include "internal.h" +// TODO(crbug.com/42290417): While we need |ASN1_ITEM|s, the exposed new, free, +// i2d, and d2i functions should call the underlying implementations directly. + #define IMPLEMENT_ASN1_STRING_FUNCTIONS(sname) \ IMPLEMENT_ASN1_TYPE(sname) \ IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(sname, sname, sname) \ diff --git a/Sources/CCryptoBoringSSL/crypto/asn1/tasn_utl.cc b/Sources/CCryptoBoringSSL/crypto/asn1/tasn_utl.cc index ebdbe7362..12e9d195a 100644 --- a/Sources/CCryptoBoringSSL/crypto/asn1/tasn_utl.cc +++ b/Sources/CCryptoBoringSSL/crypto/asn1/tasn_utl.cc @@ -94,7 +94,6 @@ void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it) { if (enc) { enc->enc = NULL; enc->len = 0; - enc->buf = NULL; } } @@ -106,7 +105,7 @@ void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it) { } int asn1_enc_save(ASN1_VALUE **pval, const uint8_t *in, size_t in_len, - const ASN1_ITEM *it, CRYPTO_BUFFER *buf) { + const ASN1_ITEM *it) { ASN1_ENCODING *enc; enc = asn1_get_enc_ptr(pval, it); if (!enc) { @@ -114,17 +113,9 @@ int asn1_enc_save(ASN1_VALUE **pval, const uint8_t *in, size_t in_len, } asn1_encoding_clear(enc); - if (buf != NULL) { - assert(CRYPTO_BUFFER_data(buf) <= in && - in + in_len <= CRYPTO_BUFFER_data(buf) + CRYPTO_BUFFER_len(buf)); - CRYPTO_BUFFER_up_ref(buf); - enc->buf = buf; - enc->enc = (uint8_t *)in; - } else { - enc->enc = reinterpret_cast(OPENSSL_memdup(in, in_len)); - if (!enc->enc) { - return 0; - } + enc->enc = reinterpret_cast(OPENSSL_memdup(in, in_len)); + if (!enc->enc) { + return 0; } enc->len = in_len; @@ -132,14 +123,9 @@ int asn1_enc_save(ASN1_VALUE **pval, const uint8_t *in, size_t in_len, } void asn1_encoding_clear(ASN1_ENCODING *enc) { - if (enc->buf != NULL) { - CRYPTO_BUFFER_free(enc->buf); - } else { - OPENSSL_free(enc->enc); - } + OPENSSL_free(enc->enc); enc->enc = NULL; enc->len = 0; - enc->buf = NULL; } int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, diff --git a/Sources/CCryptoBoringSSL/crypto/blake2/blake2.cc b/Sources/CCryptoBoringSSL/crypto/blake2/blake2.cc index 71125f7b4..fd9e3995c 100644 --- a/Sources/CCryptoBoringSSL/crypto/blake2/blake2.cc +++ b/Sources/CCryptoBoringSSL/crypto/blake2/blake2.cc @@ -16,6 +16,8 @@ #include +#include + #include "../internal.h" // https://tools.ietf.org/html/rfc7693#section-2.6 @@ -99,7 +101,7 @@ static void blake2b_transform(BLAKE2B_CTX *b2b, blake2b_load(block, s[15])); } - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(b2b->h); i++) { + for (size_t i = 0; i < std::size(b2b->h); i++) { b2b->h[i] ^= v[i]; b2b->h[i] ^= v[i + 8]; } diff --git a/Sources/CCryptoBoringSSL/crypto/bytestring/internal.h b/Sources/CCryptoBoringSSL/crypto/bytestring/internal.h index b0d55f018..19b76ab51 100644 --- a/Sources/CCryptoBoringSSL/crypto/bytestring/internal.h +++ b/Sources/CCryptoBoringSSL/crypto/bytestring/internal.h @@ -15,12 +15,14 @@ #ifndef OPENSSL_HEADER_CRYPTO_BYTESTRING_INTERNAL_H #define OPENSSL_HEADER_CRYPTO_BYTESTRING_INTERNAL_H -#include +#include +#include +#include + +#include -#if defined(__cplusplus) -extern "C" { -#endif +extern "C" { // CBS_asn1_ber_to_der reads a BER element from |in|. If it finds // indefinite-length elements or constructed strings then it converts the BER @@ -66,9 +68,53 @@ OPENSSL_EXPORT int CBS_get_asn1_implicit_string(CBS *in, CBS *out, // This function may be used to help implement legacy i2d ASN.1 functions. int CBB_finish_i2d(CBB *cbb, uint8_t **outp); - -#if defined(__cplusplus) } // extern C -#endif + +BSSL_NAMESPACE_BEGIN + +// D2IFromCBS takes a functor of type |Unique(CBS*)| and implements the d2i +// calling convention. For compatibility with functions that don't tag their +// return value (e.g. public APIs), |T*(CBS)| is also accepted. The callback can +// assume that the |CBS|'s length fits in |long|. The callback should not access +// |out|, |inp|, or |len| directly. +template +inline T *D2IFromCBS(T **out, const uint8_t **inp, long len, CBSFunc func) { + static_assert(std::is_invocable_v); + static_assert( + std::is_same_v, UniquePtr> || + std::is_same_v, T *>); + if (len < 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BUFFER_TOO_SMALL); + return nullptr; + } + CBS cbs; + CBS_init(&cbs, *inp, len); + UniquePtr ret(func(&cbs)); + if (ret == nullptr) { + return nullptr; + } + if (out != nullptr) { + UniquePtr free_out(*out); + *out = ret.get(); + } + *inp = CBS_data(&cbs); + return ret.release(); +} + +// I2DFromCBB takes a functor of type |bool(CBB*)| and implements the i2d +// calling convention. It internally makes a |CBB| with the specified initial +// capacity. The callback should not access |outp| directly. +template +inline int I2DFromCBB(size_t initial_capacity, uint8_t **outp, CBBFunc func) { + static_assert(std::is_invocable_v); + static_assert(std::is_same_v, bool>); + ScopedCBB cbb; + if (!CBB_init(cbb.get(), initial_capacity) || !func(cbb.get())) { + return -1; + } + return CBB_finish_i2d(cbb.get(), outp); +} + +BSSL_NAMESPACE_END #endif // OPENSSL_HEADER_CRYPTO_BYTESTRING_INTERNAL_H diff --git a/Sources/CCryptoBoringSSL/crypto/cipher/e_aesctrhmac.cc b/Sources/CCryptoBoringSSL/crypto/cipher/e_aesctrhmac.cc index 2ff4614a7..1a3ec9694 100644 --- a/Sources/CCryptoBoringSSL/crypto/cipher/e_aesctrhmac.cc +++ b/Sources/CCryptoBoringSSL/crypto/cipher/e_aesctrhmac.cc @@ -19,7 +19,7 @@ #include #include #include -#include +#include #include "../fipsmodule/aes/internal.h" #include "../fipsmodule/cipher/internal.h" diff --git a/Sources/CCryptoBoringSSL/crypto/cipher/e_tls.cc b/Sources/CCryptoBoringSSL/crypto/cipher/e_tls.cc index a418df43f..3c18c91cd 100644 --- a/Sources/CCryptoBoringSSL/crypto/cipher/e_tls.cc +++ b/Sources/CCryptoBoringSSL/crypto/cipher/e_tls.cc @@ -31,7 +31,7 @@ typedef struct { EVP_CIPHER_CTX cipher_ctx; - HMAC_CTX hmac_ctx; + HMAC_CTX *hmac_ctx; // mac_key is the portion of the key used for the MAC. It is retained // separately for the constant-time CBC code. uint8_t mac_key[EVP_MAX_MD_SIZE]; @@ -51,15 +51,14 @@ static_assert(alignof(union evp_aead_ctx_st_state) >= alignof(AEAD_TLS_CTX), static void aead_tls_cleanup(EVP_AEAD_CTX *ctx) { AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)&ctx->state; EVP_CIPHER_CTX_cleanup(&tls_ctx->cipher_ctx); - HMAC_CTX_cleanup(&tls_ctx->hmac_ctx); + HMAC_CTX_free(tls_ctx->hmac_ctx); } static int aead_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, size_t tag_len, enum evp_aead_direction_t dir, const EVP_CIPHER *cipher, const EVP_MD *md, char implicit_iv) { - if (tag_len != EVP_AEAD_DEFAULT_TAG_LENGTH && - tag_len != EVP_MD_size(md)) { + if (tag_len != EVP_AEAD_DEFAULT_TAG_LENGTH && tag_len != EVP_MD_size(md)) { OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_TAG_SIZE); return 0; } @@ -72,11 +71,15 @@ static int aead_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, size_t mac_key_len = EVP_MD_size(md); size_t enc_key_len = EVP_CIPHER_key_length(cipher); assert(mac_key_len + enc_key_len + - (implicit_iv ? EVP_CIPHER_iv_length(cipher) : 0) == key_len); + (implicit_iv ? EVP_CIPHER_iv_length(cipher) : 0) == + key_len); AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)&ctx->state; + tls_ctx->hmac_ctx = HMAC_CTX_new(); + if (!tls_ctx->hmac_ctx) { + return 0; + } EVP_CIPHER_CTX_init(&tls_ctx->cipher_ctx); - HMAC_CTX_init(&tls_ctx->hmac_ctx); assert(mac_key_len <= EVP_MAX_MD_SIZE); OPENSSL_memcpy(tls_ctx->mac_key, key, mac_key_len); tls_ctx->mac_key_len = (uint8_t)mac_key_len; @@ -85,7 +88,7 @@ static int aead_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, if (!EVP_CipherInit_ex(&tls_ctx->cipher_ctx, cipher, NULL, &key[mac_key_len], implicit_iv ? &key[mac_key_len + enc_key_len] : NULL, dir == evp_aead_seal) || - !HMAC_Init_ex(&tls_ctx->hmac_ctx, key, mac_key_len, md, NULL)) { + !HMAC_Init_ex(tls_ctx->hmac_ctx, key, mac_key_len, md, NULL)) { aead_tls_cleanup(ctx); return 0; } @@ -99,7 +102,7 @@ static size_t aead_tls_tag_len(const EVP_AEAD_CTX *ctx, const size_t in_len, assert(extra_in_len == 0); const AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)&ctx->state; - const size_t hmac_len = HMAC_size(&tls_ctx->hmac_ctx); + const size_t hmac_len = HMAC_size(tls_ctx->hmac_ctx); if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) != EVP_CIPH_CBC_MODE) { // The NULL cipher. return hmac_len; @@ -160,11 +163,11 @@ static int aead_tls_seal_scatter(const EVP_AEAD_CTX *ctx, uint8_t *out, // in-place. uint8_t mac[EVP_MAX_MD_SIZE]; unsigned mac_len; - if (!HMAC_Init_ex(&tls_ctx->hmac_ctx, NULL, 0, NULL, NULL) || - !HMAC_Update(&tls_ctx->hmac_ctx, ad, ad_len) || - !HMAC_Update(&tls_ctx->hmac_ctx, ad_extra, sizeof(ad_extra)) || - !HMAC_Update(&tls_ctx->hmac_ctx, in, in_len) || - !HMAC_Final(&tls_ctx->hmac_ctx, mac, &mac_len)) { + if (!HMAC_Init_ex(tls_ctx->hmac_ctx, NULL, 0, NULL, NULL) || + !HMAC_Update(tls_ctx->hmac_ctx, ad, ad_len) || + !HMAC_Update(tls_ctx->hmac_ctx, ad_extra, sizeof(ad_extra)) || + !HMAC_Update(tls_ctx->hmac_ctx, in, in_len) || + !HMAC_Final(tls_ctx->hmac_ctx, mac, &mac_len)) { return 0; } @@ -187,7 +190,8 @@ static int aead_tls_seal_scatter(const EVP_AEAD_CTX *ctx, uint8_t *out, // block from encrypting the input and split the result between |out| and // |out_tag|. Then feed the rest. - const size_t early_mac_len = (block_size - (in_len % block_size)) % block_size; + const size_t early_mac_len = + (block_size - (in_len % block_size)) % block_size; if (early_mac_len != 0) { assert(len + block_size - early_mac_len == in_len); uint8_t buf[EVP_MAX_BLOCK_LENGTH]; @@ -245,7 +249,7 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len, return 0; } - if (in_len < HMAC_size(&tls_ctx->hmac_ctx)) { + if (in_len < HMAC_size(tls_ctx->hmac_ctx)) { OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); return 0; } @@ -303,7 +307,7 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len, if (!EVP_tls_cbc_remove_padding( &padding_ok, &data_plus_mac_len, out, total, EVP_CIPHER_CTX_block_size(&tls_ctx->cipher_ctx), - HMAC_size(&tls_ctx->hmac_ctx))) { + HMAC_size(tls_ctx->hmac_ctx))) { // Publicly invalid. This can be rejected in non-constant time. OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); return 0; @@ -313,9 +317,9 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len, data_plus_mac_len = total; // |data_plus_mac_len| = |total| = |in_len| at this point. |in_len| has // already been checked against the MAC size at the top of the function. - assert(data_plus_mac_len >= HMAC_size(&tls_ctx->hmac_ctx)); + assert(data_plus_mac_len >= HMAC_size(tls_ctx->hmac_ctx)); } - size_t data_len = data_plus_mac_len - HMAC_size(&tls_ctx->hmac_ctx); + size_t data_len = data_plus_mac_len - HMAC_size(tls_ctx->hmac_ctx); // At this point, if the padding is valid, the first |data_plus_mac_len| bytes // after |out| are the plaintext and MAC. Otherwise, |data_plus_mac_len| is @@ -335,14 +339,14 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len, uint8_t record_mac_tmp[EVP_MAX_MD_SIZE]; uint8_t *record_mac; if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE && - EVP_tls_cbc_record_digest_supported(tls_ctx->hmac_ctx.md)) { - if (!EVP_tls_cbc_digest_record(tls_ctx->hmac_ctx.md, mac, &mac_len, + EVP_tls_cbc_record_digest_supported(tls_ctx->hmac_ctx->md)) { + if (!EVP_tls_cbc_digest_record(tls_ctx->hmac_ctx->md, mac, &mac_len, ad_fixed, out, data_len, total, tls_ctx->mac_key, tls_ctx->mac_key_len)) { OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); return 0; } - assert(mac_len == HMAC_size(&tls_ctx->hmac_ctx)); + assert(mac_len == HMAC_size(tls_ctx->hmac_ctx)); record_mac = record_mac_tmp; EVP_tls_cbc_copy_mac(record_mac, mac_len, out, data_plus_mac_len, total); @@ -352,15 +356,15 @@ static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len, assert(EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) != EVP_CIPH_CBC_MODE); unsigned mac_len_u; - if (!HMAC_Init_ex(&tls_ctx->hmac_ctx, NULL, 0, NULL, NULL) || - !HMAC_Update(&tls_ctx->hmac_ctx, ad_fixed, ad_len) || - !HMAC_Update(&tls_ctx->hmac_ctx, out, data_len) || - !HMAC_Final(&tls_ctx->hmac_ctx, mac, &mac_len_u)) { + if (!HMAC_Init_ex(tls_ctx->hmac_ctx, NULL, 0, NULL, NULL) || + !HMAC_Update(tls_ctx->hmac_ctx, ad_fixed, ad_len) || + !HMAC_Update(tls_ctx->hmac_ctx, out, data_len) || + !HMAC_Final(tls_ctx->hmac_ctx, mac, &mac_len_u)) { return 0; } mac_len = mac_len_u; - assert(mac_len == HMAC_size(&tls_ctx->hmac_ctx)); + assert(mac_len == HMAC_size(tls_ctx->hmac_ctx)); record_mac = &out[data_len]; } diff --git a/Sources/CCryptoBoringSSL/crypto/cipher/get_cipher.cc b/Sources/CCryptoBoringSSL/crypto/cipher/get_cipher.cc index 24a6e3183..43934b950 100644 --- a/Sources/CCryptoBoringSSL/crypto/cipher/get_cipher.cc +++ b/Sources/CCryptoBoringSSL/crypto/cipher/get_cipher.cc @@ -55,17 +55,17 @@ static const struct { }; const EVP_CIPHER *EVP_get_cipherbynid(int nid) { - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kCiphers); i++) { - if (kCiphers[i].nid == nid) { - return kCiphers[i].func(); + for (const auto &cipher : kCiphers) { + if (cipher.nid == nid) { + return cipher.func(); } } - return NULL; + return nullptr; } const EVP_CIPHER *EVP_get_cipherbyname(const char *name) { - if (name == NULL) { - return NULL; + if (name == nullptr) { + return nullptr; } // This is not a name used by OpenSSL, but tcpdump registers it with @@ -75,11 +75,11 @@ const EVP_CIPHER *EVP_get_cipherbyname(const char *name) { name = "des-ede3-cbc"; } - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kCiphers); i++) { - if (OPENSSL_strcasecmp(kCiphers[i].name, name) == 0) { - return kCiphers[i].func(); + for (const auto &cipher : kCiphers) { + if (OPENSSL_strcasecmp(cipher.name, name) == 0) { + return cipher.func(); } } - return NULL; + return nullptr; } diff --git a/Sources/CCryptoBoringSSL/crypto/cipher/internal.h b/Sources/CCryptoBoringSSL/crypto/cipher/internal.h index a4106a4f1..6fde1487e 100644 --- a/Sources/CCryptoBoringSSL/crypto/cipher/internal.h +++ b/Sources/CCryptoBoringSSL/crypto/cipher/internal.h @@ -19,6 +19,7 @@ #include #include +#include #include "../internal.h" @@ -129,7 +130,7 @@ union chacha20_poly1305_seal_data { } out; }; -#if (defined(OPENSSL_X86_64) || defined(OPENSSL_AARCH64)) && \ +#if (defined(OPENSSL_X86_64) || defined(OPENSSL_AARCH64)) && \ !defined(OPENSSL_NO_ASM) static_assert(sizeof(union chacha20_poly1305_open_data) == 48, diff --git a/Sources/CCryptoBoringSSL/crypto/conf/conf.cc b/Sources/CCryptoBoringSSL/crypto/conf/conf.cc index f29418e98..94931bf7c 100644 --- a/Sources/CCryptoBoringSSL/crypto/conf/conf.cc +++ b/Sources/CCryptoBoringSSL/crypto/conf/conf.cc @@ -623,6 +623,8 @@ int CONF_modules_load_file(const char *filename, const char *appname, return 1; } +void CONF_modules_unload(int all) {} + void CONF_modules_free(void) {} void OPENSSL_config(const char *config_name) {} diff --git a/Sources/CCryptoBoringSSL/crypto/crypto.cc b/Sources/CCryptoBoringSSL/crypto/crypto.cc index 773e351d0..d94b6f810 100644 --- a/Sources/CCryptoBoringSSL/crypto/crypto.cc +++ b/Sources/CCryptoBoringSSL/crypto/crypto.cc @@ -137,6 +137,8 @@ void ENGINE_load_builtin_engines(void) {} int ENGINE_register_all_complete(void) { return 1; } +void ENGINE_cleanup(void) {} + void OPENSSL_load_builtin_modules(void) {} int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) { diff --git a/Sources/CCryptoBoringSSL/crypto/curve25519/curve25519.cc b/Sources/CCryptoBoringSSL/crypto/curve25519/curve25519.cc index 5a2bdf65b..c61e31361 100644 --- a/Sources/CCryptoBoringSSL/crypto/curve25519/curve25519.cc +++ b/Sources/CCryptoBoringSSL/crypto/curve25519/curve25519.cc @@ -24,7 +24,7 @@ #include #include -#include +#include #include "../internal.h" #include "internal.h" diff --git a/Sources/CCryptoBoringSSL/crypto/curve25519/spake25519.cc b/Sources/CCryptoBoringSSL/crypto/curve25519/spake25519.cc index b04f875f4..8f890faea 100644 --- a/Sources/CCryptoBoringSSL/crypto/curve25519/spake25519.cc +++ b/Sources/CCryptoBoringSSL/crypto/curve25519/spake25519.cc @@ -17,10 +17,12 @@ #include #include +#include + #include #include #include -#include +#include #include "../fipsmodule/bn/internal.h" #include "../internal.h" @@ -333,18 +335,17 @@ static const scalar kOrder = { // scalar_cmov copies |src| to |dest| if |mask| is all ones. static void scalar_cmov(scalar *dest, const scalar *src, crypto_word_t mask) { bn_select_words(dest->words, mask, src->words, dest->words, - OPENSSL_ARRAY_SIZE(dest->words)); + std::size(dest->words)); } // scalar_double sets |s| to |2×s|. static void scalar_double(scalar *s) { - bn_add_words(s->words, s->words, s->words, OPENSSL_ARRAY_SIZE(s->words)); + bn_add_words(s->words, s->words, s->words, std::size(s->words)); } // scalar_add sets |dest| to |dest| plus |src|. static void scalar_add(scalar *dest, const scalar *src) { - bn_add_words(dest->words, dest->words, src->words, - OPENSSL_ARRAY_SIZE(dest->words)); + bn_add_words(dest->words, dest->words, src->words, std::size(dest->words)); } int SPAKE2_generate_msg(SPAKE2_CTX *ctx, uint8_t *out, size_t *out_len, diff --git a/Sources/CCryptoBoringSSL/crypto/dh/dh_asn1.cc b/Sources/CCryptoBoringSSL/crypto/dh/dh_asn1.cc index 60fe212c7..3c44926d1 100644 --- a/Sources/CCryptoBoringSSL/crypto/dh/dh_asn1.cc +++ b/Sources/CCryptoBoringSSL/crypto/dh/dh_asn1.cc @@ -95,29 +95,11 @@ int DH_marshal_parameters(CBB *cbb, const DH *dh) { } DH *d2i_DHparams(DH **out, const uint8_t **inp, long len) { - if (len < 0) { - return NULL; - } - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); - DH *ret = DH_parse_parameters(&cbs); - if (ret == NULL) { - return NULL; - } - if (out != NULL) { - DH_free(*out); - *out = ret; - } - *inp = CBS_data(&cbs); - return ret; + return bssl::D2IFromCBS(out, inp, len, DH_parse_parameters); } int i2d_DHparams(const DH *in, uint8_t **outp) { - CBB cbb; - if (!CBB_init(&cbb, 0) || - !DH_marshal_parameters(&cbb, in)) { - CBB_cleanup(&cbb); - return -1; - } - return CBB_finish_i2d(&cbb, outp); + return bssl::I2DFromCBB( + /*initial_capacity=*/256, outp, + [&](CBB *cbb) -> bool { return DH_marshal_parameters(cbb, in); }); } diff --git a/Sources/CCryptoBoringSSL/crypto/dh/params.cc b/Sources/CCryptoBoringSSL/crypto/dh/params.cc index 02287926f..35fcf9a09 100644 --- a/Sources/CCryptoBoringSSL/crypto/dh/params.cc +++ b/Sources/CCryptoBoringSSL/crypto/dh/params.cc @@ -17,13 +17,13 @@ #include #include #include +#include #include "../fipsmodule/bn/internal.h" #include "../fipsmodule/dh/internal.h" -static BIGNUM *get_params(BIGNUM *ret, const BN_ULONG *words, - size_t num_words) { +static BIGNUM *get_params(BIGNUM *ret, bssl::Span words) { BIGNUM *alloc = NULL; if (ret == NULL) { alloc = BN_new(); @@ -33,7 +33,7 @@ static BIGNUM *get_params(BIGNUM *ret, const BN_ULONG *words, ret = alloc; } - if (!bn_set_words(ret, words, num_words)) { + if (!bn_set_words(ret, words.data(), words.size())) { BN_free(alloc); return NULL; } @@ -56,7 +56,7 @@ BIGNUM *BN_get_rfc3526_prime_1536(BIGNUM *ret) { TOBN(0x29024e08, 0x8a67cc74), TOBN(0xc4c6628b, 0x80dc1cd1), TOBN(0xc90fdaa2, 0x2168c234), TOBN(0xffffffff, 0xffffffff), }; - return get_params(ret, kWords, OPENSSL_ARRAY_SIZE(kWords)); + return get_params(ret, kWords); } BIGNUM *BN_get_rfc3526_prime_2048(BIGNUM *ret) { @@ -78,7 +78,7 @@ BIGNUM *BN_get_rfc3526_prime_2048(BIGNUM *ret) { TOBN(0x29024e08, 0x8a67cc74), TOBN(0xc4c6628b, 0x80dc1cd1), TOBN(0xc90fdaa2, 0x2168c234), TOBN(0xffffffff, 0xffffffff), }; - return get_params(ret, kWords, OPENSSL_ARRAY_SIZE(kWords)); + return get_params(ret, kWords); } BIGNUM *BN_get_rfc3526_prime_3072(BIGNUM *ret) { @@ -108,7 +108,7 @@ BIGNUM *BN_get_rfc3526_prime_3072(BIGNUM *ret) { TOBN(0x29024e08, 0x8a67cc74), TOBN(0xc4c6628b, 0x80dc1cd1), TOBN(0xc90fdaa2, 0x2168c234), TOBN(0xffffffff, 0xffffffff), }; - return get_params(ret, kWords, OPENSSL_ARRAY_SIZE(kWords)); + return get_params(ret, kWords); } BIGNUM *BN_get_rfc3526_prime_4096(BIGNUM *ret) { @@ -146,7 +146,7 @@ BIGNUM *BN_get_rfc3526_prime_4096(BIGNUM *ret) { TOBN(0x29024e08, 0x8a67cc74), TOBN(0xc4c6628b, 0x80dc1cd1), TOBN(0xc90fdaa2, 0x2168c234), TOBN(0xffffffff, 0xffffffff), }; - return get_params(ret, kWords, OPENSSL_ARRAY_SIZE(kWords)); + return get_params(ret, kWords); } BIGNUM *BN_get_rfc3526_prime_6144(BIGNUM *ret) { @@ -200,7 +200,7 @@ BIGNUM *BN_get_rfc3526_prime_6144(BIGNUM *ret) { TOBN(0x29024e08, 0x8a67cc74), TOBN(0xc4c6628b, 0x80dc1cd1), TOBN(0xc90fdaa2, 0x2168c234), TOBN(0xffffffff, 0xffffffff), }; - return get_params(ret, kWords, OPENSSL_ARRAY_SIZE(kWords)); + return get_params(ret, kWords); } BIGNUM *BN_get_rfc3526_prime_8192(BIGNUM *ret) { @@ -270,7 +270,7 @@ BIGNUM *BN_get_rfc3526_prime_8192(BIGNUM *ret) { TOBN(0x29024e08, 0x8a67cc74), TOBN(0xc4c6628b, 0x80dc1cd1), TOBN(0xc90fdaa2, 0x2168c234), TOBN(0xffffffff, 0xffffffff), }; - return get_params(ret, kWords, OPENSSL_ARRAY_SIZE(kWords)); + return get_params(ret, kWords); } int DH_generate_parameters_ex(DH *dh, int prime_bits, int generator, diff --git a/Sources/CCryptoBoringSSL/crypto/digest/digest_extra.cc b/Sources/CCryptoBoringSSL/crypto/digest/digest_extra.cc index d7b0c1a06..ab46cd9d7 100644 --- a/Sources/CCryptoBoringSSL/crypto/digest/digest_extra.cc +++ b/Sources/CCryptoBoringSSL/crypto/digest/digest_extra.cc @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include "../asn1/internal.h" #include "../fipsmodule/digest/internal.h" @@ -71,9 +73,9 @@ const EVP_MD *EVP_get_digestbynid(int nid) { return NULL; } - for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(nid_to_digest_mapping); i++) { - if (nid_to_digest_mapping[i].nid == nid) { - return nid_to_digest_mapping[i].md_func(); + for (const auto &mapping : nid_to_digest_mapping) { + if (mapping.nid == nid) { + return mapping.md_func(); } } @@ -101,42 +103,41 @@ static const struct { {{0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04}, 9, NID_sha224}, }; -static const EVP_MD *cbs_to_md(const CBS *cbs) { - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kMDOIDs); i++) { - if (CBS_len(cbs) == kMDOIDs[i].oid_len && - OPENSSL_memcmp(CBS_data(cbs), kMDOIDs[i].oid, kMDOIDs[i].oid_len) == - 0) { - return EVP_get_digestbynid(kMDOIDs[i].nid); +static int cbs_to_digest_nid(const CBS *cbs) { + for (const auto &md : kMDOIDs) { + if (bssl::Span(*cbs) == + bssl::Span(md.oid).first(md.oid_len)) { + return md.nid; } } - - return NULL; + return NID_undef; } const EVP_MD *EVP_get_digestbyobj(const ASN1_OBJECT *obj) { - // Handle objects with no corresponding OID. Note we don't use |OBJ_obj2nid| - // here to avoid pulling in the OID table. - if (obj->nid != NID_undef) { - return EVP_get_digestbynid(obj->nid); + int nid = obj->nid; + if (nid == NID_undef) { + // Handle objects with no saved NID. Note we don't use |OBJ_obj2nid| here to + // avoid pulling in the OID table. + CBS cbs; + CBS_init(&cbs, OBJ_get0_data(obj), OBJ_length(obj)); + nid = cbs_to_digest_nid(&cbs); } - CBS cbs; - CBS_init(&cbs, OBJ_get0_data(obj), OBJ_length(obj)); - return cbs_to_md(&cbs); + return nid == NID_undef ? nullptr : EVP_get_digestbynid(nid); } -const EVP_MD *EVP_parse_digest_algorithm(CBS *cbs) { +int EVP_parse_digest_algorithm_nid(CBS *cbs) { CBS algorithm, oid; if (!CBS_get_asn1(cbs, &algorithm, CBS_ASN1_SEQUENCE) || !CBS_get_asn1(&algorithm, &oid, CBS_ASN1_OBJECT)) { OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_DECODE_ERROR); - return NULL; + return NID_undef; } - const EVP_MD *ret = cbs_to_md(&oid); - if (ret == NULL) { + int ret = cbs_to_digest_nid(&oid); + if (ret == NID_undef) { OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_UNKNOWN_HASH); - return NULL; + return NID_undef; } // The parameters, if present, must be NULL. Historically, whether the NULL @@ -149,13 +150,21 @@ const EVP_MD *EVP_parse_digest_algorithm(CBS *cbs) { CBS_len(¶m) != 0 || // CBS_len(&algorithm) != 0) { OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_DECODE_ERROR); - return NULL; + return NID_undef; } } return ret; } +const EVP_MD *EVP_parse_digest_algorithm(CBS *cbs) { + int nid = EVP_parse_digest_algorithm_nid(cbs); + if (nid == NID_undef) { + return nullptr; + } + return EVP_get_digestbynid(nid); +} + static int marshal_digest_algorithm(CBB *cbb, const EVP_MD *md, bool with_null) { CBB algorithm, oid, null; @@ -198,16 +207,16 @@ int EVP_marshal_digest_algorithm_no_params(CBB *cbb, const EVP_MD *md) { } const EVP_MD *EVP_get_digestbyname(const char *name) { - for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(nid_to_digest_mapping); i++) { - const char *short_name = nid_to_digest_mapping[i].short_name; - const char *long_name = nid_to_digest_mapping[i].long_name; + for (const auto &mapping : nid_to_digest_mapping) { + const char *short_name = mapping.short_name; + const char *long_name = mapping.long_name; if ((short_name && strcmp(short_name, name) == 0) || (long_name && strcmp(long_name, name) == 0)) { - return nid_to_digest_mapping[i].md_func(); + return mapping.md_func(); } } - return NULL; + return nullptr; } static void blake2b256_init(EVP_MD_CTX *ctx) { @@ -230,6 +239,8 @@ static const EVP_MD evp_md_blake2b256 = { const EVP_MD *EVP_blake2b256(void) { return &evp_md_blake2b256; } +static_assert(sizeof(BLAKE2B_CTX) <= EVP_MAX_MD_DATA_SIZE); + static void md4_init(EVP_MD_CTX *ctx) { BSSL_CHECK(MD4_Init(reinterpret_cast(ctx->md_data))); @@ -257,6 +268,9 @@ static const EVP_MD evp_md_md4 = { const EVP_MD *EVP_md4(void) { return &evp_md_md4; } +static_assert(sizeof(MD4_CTX) <= EVP_MAX_MD_DATA_SIZE); + + static void md5_init(EVP_MD_CTX *ctx) { BSSL_CHECK(MD5_Init(reinterpret_cast(ctx->md_data))); } @@ -277,6 +291,9 @@ static const EVP_MD evp_md_md5 = { const EVP_MD *EVP_md5(void) { return &evp_md_md5; } +static_assert(sizeof(MD5_CTX) <= EVP_MAX_MD_DATA_SIZE); + + typedef struct { MD5_CTX md5; SHA_CTX sha1; @@ -312,3 +329,5 @@ const EVP_MD evp_md_md5_sha1 = { }; const EVP_MD *EVP_md5_sha1(void) { return &evp_md_md5_sha1; } + +static_assert(sizeof(MD5_SHA1_CTX) <= EVP_MAX_MD_DATA_SIZE); diff --git a/Sources/CCryptoBoringSSL/crypto/dsa/dsa.cc b/Sources/CCryptoBoringSSL/crypto/dsa/dsa.cc index 778237d3e..cbc382731 100644 --- a/Sources/CCryptoBoringSSL/crypto/dsa/dsa.cc +++ b/Sources/CCryptoBoringSSL/crypto/dsa/dsa.cc @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include "../fipsmodule/bn/internal.h" #include "../fipsmodule/dh/internal.h" diff --git a/Sources/CCryptoBoringSSL/crypto/dsa/dsa_asn1.cc b/Sources/CCryptoBoringSSL/crypto/dsa/dsa_asn1.cc index 743f21fdf..08a63413d 100644 --- a/Sources/CCryptoBoringSSL/crypto/dsa/dsa_asn1.cc +++ b/Sources/CCryptoBoringSSL/crypto/dsa/dsa_asn1.cc @@ -255,113 +255,41 @@ int DSA_marshal_private_key(CBB *cbb, const DSA *dsa) { } DSA_SIG *d2i_DSA_SIG(DSA_SIG **out_sig, const uint8_t **inp, long len) { - if (len < 0) { - return NULL; - } - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); - DSA_SIG *ret = DSA_SIG_parse(&cbs); - if (ret == NULL) { - return NULL; - } - if (out_sig != NULL) { - DSA_SIG_free(*out_sig); - *out_sig = ret; - } - *inp = CBS_data(&cbs); - return ret; + return bssl::D2IFromCBS(out_sig, inp, len, DSA_SIG_parse); } int i2d_DSA_SIG(const DSA_SIG *in, uint8_t **outp) { - CBB cbb; - if (!CBB_init(&cbb, 0) || - !DSA_SIG_marshal(&cbb, in)) { - CBB_cleanup(&cbb); - return -1; - } - return CBB_finish_i2d(&cbb, outp); + return bssl::I2DFromCBB( + /*initial_capacity=*/256, outp, + [&](CBB *cbb) -> bool { return DSA_SIG_marshal(cbb, in); }); } DSA *d2i_DSAPublicKey(DSA **out, const uint8_t **inp, long len) { - if (len < 0) { - return NULL; - } - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); - DSA *ret = DSA_parse_public_key(&cbs); - if (ret == NULL) { - return NULL; - } - if (out != NULL) { - DSA_free(*out); - *out = ret; - } - *inp = CBS_data(&cbs); - return ret; + return bssl::D2IFromCBS(out, inp, len, DSA_parse_public_key); } int i2d_DSAPublicKey(const DSA *in, uint8_t **outp) { - CBB cbb; - if (!CBB_init(&cbb, 0) || - !DSA_marshal_public_key(&cbb, in)) { - CBB_cleanup(&cbb); - return -1; - } - return CBB_finish_i2d(&cbb, outp); + return bssl::I2DFromCBB( + /*initial_capacity=*/256, outp, + [&](CBB *cbb) -> bool { return DSA_marshal_public_key(cbb, in); }); } DSA *d2i_DSAPrivateKey(DSA **out, const uint8_t **inp, long len) { - if (len < 0) { - return NULL; - } - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); - DSA *ret = DSA_parse_private_key(&cbs); - if (ret == NULL) { - return NULL; - } - if (out != NULL) { - DSA_free(*out); - *out = ret; - } - *inp = CBS_data(&cbs); - return ret; + return bssl::D2IFromCBS(out, inp, len, DSA_parse_private_key); } int i2d_DSAPrivateKey(const DSA *in, uint8_t **outp) { - CBB cbb; - if (!CBB_init(&cbb, 0) || - !DSA_marshal_private_key(&cbb, in)) { - CBB_cleanup(&cbb); - return -1; - } - return CBB_finish_i2d(&cbb, outp); + return bssl::I2DFromCBB( + /*initial_capacity=*/256, outp, + [&](CBB *cbb) -> bool { return DSA_marshal_private_key(cbb, in); }); } DSA *d2i_DSAparams(DSA **out, const uint8_t **inp, long len) { - if (len < 0) { - return NULL; - } - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); - DSA *ret = DSA_parse_parameters(&cbs); - if (ret == NULL) { - return NULL; - } - if (out != NULL) { - DSA_free(*out); - *out = ret; - } - *inp = CBS_data(&cbs); - return ret; + return bssl::D2IFromCBS(out, inp, len, DSA_parse_parameters); } int i2d_DSAparams(const DSA *in, uint8_t **outp) { - CBB cbb; - if (!CBB_init(&cbb, 0) || - !DSA_marshal_parameters(&cbb, in)) { - CBB_cleanup(&cbb); - return -1; - } - return CBB_finish_i2d(&cbb, outp); + return bssl::I2DFromCBB( + /*initial_capacity=*/256, outp, + [&](CBB *cbb) -> bool { return DSA_marshal_parameters(cbb, in); }); } diff --git a/Sources/CCryptoBoringSSL/crypto/ec/ec_asn1.cc b/Sources/CCryptoBoringSSL/crypto/ec/ec_asn1.cc index e7e4ff339..092e8845b 100644 --- a/Sources/CCryptoBoringSSL/crypto/ec/ec_asn1.cc +++ b/Sources/CCryptoBoringSSL/crypto/ec/ec_asn1.cc @@ -17,6 +17,9 @@ #include #include +#include +#include + #include #include #include @@ -27,6 +30,7 @@ #include "../bytestring/internal.h" #include "../fipsmodule/ec/internal.h" #include "../internal.h" +#include "internal.h" static const CBS_ASN1_TAG kParametersTag = @@ -34,17 +38,23 @@ static const CBS_ASN1_TAG kParametersTag = static const CBS_ASN1_TAG kPublicKeyTag = CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 1; -// TODO(https://crbug.com/boringssl/497): Allow parsers to specify a list of -// acceptable groups, so parsers don't have to pull in all four. -typedef const EC_GROUP *(*ec_group_func)(void); -static const ec_group_func kAllGroups[] = { - &EC_group_p224, - &EC_group_p256, - &EC_group_p384, - &EC_group_p521, -}; +static auto get_all_groups() { + return std::array{ + EC_group_p224(), + EC_group_p256(), + EC_group_p384(), + EC_group_p521(), + }; +} + +EC_KEY *ec_key_parse_private_key( + CBS *cbs, const EC_GROUP *group, + bssl::Span allowed_groups) { + // If a group was supplied externally, no other groups can be parsed. + if (group != nullptr) { + allowed_groups = bssl::Span(&group, 1); + } -EC_KEY *EC_KEY_parse_private_key(CBS *cbs, const EC_GROUP *group) { CBS ec_private_key, private_key; uint64_t version; if (!CBS_get_asn1(cbs, &ec_private_key, CBS_ASN1_SEQUENCE) || @@ -66,23 +76,31 @@ EC_KEY *EC_KEY_parse_private_key(CBS *cbs, const EC_GROUP *group) { OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); return nullptr; } - const EC_GROUP *inner_group = EC_KEY_parse_parameters(&child); + const EC_GROUP *inner_group = + ec_key_parse_parameters(&child, allowed_groups); if (inner_group == nullptr) { + // If the caller already supplied a group, any explicit group is required + // to match. On mismatch, |ec_key_parse_parameters| will fail to recognize + // any other groups, so remap the error. + if (group != nullptr && + ERR_equals(ERR_peek_last_error(), ERR_LIB_EC, EC_R_UNKNOWN_GROUP)) { + ERR_clear_error(); + OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH); + } return nullptr; } - if (group == nullptr) { - group = inner_group; - } else if (EC_GROUP_cmp(group, inner_group, nullptr) != 0) { - // If a group was supplied externally, it must match. - OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH); - return nullptr; - } + // Overriding |allowed_groups| above ensures the only returned group will be + // the matching one. + assert(group == nullptr || inner_group == group); + group = inner_group; if (CBS_len(&child) != 0) { OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); return nullptr; } } + // The group must have been specified either externally, or explicitly in the + // structure. if (group == nullptr) { OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS); return nullptr; @@ -151,6 +169,10 @@ EC_KEY *EC_KEY_parse_private_key(CBS *cbs, const EC_GROUP *group) { return ret.release(); } +EC_KEY *EC_KEY_parse_private_key(CBS *cbs, const EC_GROUP *group) { + return ec_key_parse_private_key(cbs, group, get_all_groups()); +} + int EC_KEY_marshal_private_key(CBB *cbb, const EC_KEY *key, unsigned enc_flags) { if (key == NULL || key->group == NULL || key->priv_key == NULL) { @@ -296,23 +318,29 @@ static int integers_equal(const CBS *bytes, const BIGNUM *bn) { return CBS_mem_equal(©, buf, CBS_len(©)); } -EC_GROUP *EC_KEY_parse_curve_name(CBS *cbs) { +const EC_GROUP *ec_key_parse_curve_name( + CBS *cbs, bssl::Span allowed_groups) { CBS named_curve; if (!CBS_get_asn1(cbs, &named_curve, CBS_ASN1_OBJECT)) { OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); - return NULL; + return nullptr; } // Look for a matching curve. - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kAllGroups); i++) { - const EC_GROUP *group = kAllGroups[i](); - if (CBS_mem_equal(&named_curve, group->oid, group->oid_len)) { - return (EC_GROUP *)group; + for (const EC_GROUP *group : allowed_groups) { + if (named_curve == bssl::Span(group->oid, group->oid_len)) { + return group; } } OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP); - return NULL; + return nullptr; +} + +EC_GROUP *EC_KEY_parse_curve_name(CBS *cbs) { + // This function only ever returns a static |EC_GROUP|, but currently returns + // a non-const pointer for historical reasons. + return const_cast(ec_key_parse_curve_name(cbs, get_all_groups())); } int EC_KEY_marshal_curve_name(CBB *cbb, const EC_GROUP *group) { @@ -324,9 +352,10 @@ int EC_KEY_marshal_curve_name(CBB *cbb, const EC_GROUP *group) { return CBB_add_asn1_element(cbb, CBS_ASN1_OBJECT, group->oid, group->oid_len); } -EC_GROUP *EC_KEY_parse_parameters(CBS *cbs) { +const EC_GROUP *ec_key_parse_parameters( + CBS *cbs, bssl::Span allowed_groups) { if (!CBS_peek_asn1_tag(cbs, CBS_ASN1_SEQUENCE)) { - return EC_KEY_parse_curve_name(cbs); + return ec_key_parse_curve_name(cbs, allowed_groups); } // OpenSSL sometimes produces ECPrivateKeys with explicitly-encoded versions @@ -348,8 +377,7 @@ EC_GROUP *EC_KEY_parse_parameters(CBS *cbs) { return nullptr; } - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kAllGroups); i++) { - const EC_GROUP *group = kAllGroups[i](); + for (const EC_GROUP *group : allowed_groups) { if (!integers_equal(&curve.order, EC_GROUP_get0_order(group))) { continue; } @@ -372,13 +400,19 @@ EC_GROUP *EC_KEY_parse_parameters(CBS *cbs) { !integers_equal(&curve.base_y, y.get())) { break; } - return const_cast(group); + return group; } OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP); return nullptr; } +EC_GROUP *EC_KEY_parse_parameters(CBS *cbs) { + // This function only ever returns a static |EC_GROUP|, but currently returns + // a non-const pointer for historical reasons. + return const_cast(ec_key_parse_parameters(cbs, get_all_groups())); +} + int EC_POINT_point2cbb(CBB *out, const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form, BN_CTX *ctx) { size_t len = EC_POINT_point2oct(group, point, form, NULL, 0, ctx); @@ -398,52 +432,20 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **out, const uint8_t **inp, long len) { group = EC_KEY_get0_group(*out); } - if (len < 0) { - OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); - return NULL; - } - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); - EC_KEY *ret = EC_KEY_parse_private_key(&cbs, group); - if (ret == NULL) { - return NULL; - } - if (out != NULL) { - EC_KEY_free(*out); - *out = ret; - } - *inp = CBS_data(&cbs); - return ret; + return bssl::D2IFromCBS(out, inp, len, [&](CBS *cbs) { + return EC_KEY_parse_private_key(cbs, group); + }); } int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp) { - CBB cbb; - if (!CBB_init(&cbb, 0) || - !EC_KEY_marshal_private_key(&cbb, key, EC_KEY_get_enc_flags(key))) { - CBB_cleanup(&cbb); - return -1; - } - return CBB_finish_i2d(&cbb, outp); + return bssl::I2DFromCBB( + /*initial_capacity=*/64, outp, [&](CBB *cbb) -> bool { + return EC_KEY_marshal_private_key(cbb, key, EC_KEY_get_enc_flags(key)); + }); } EC_GROUP *d2i_ECPKParameters(EC_GROUP **out, const uint8_t **inp, long len) { - if (len < 0) { - return NULL; - } - - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); - EC_GROUP *ret = EC_KEY_parse_parameters(&cbs); - if (ret == NULL) { - return NULL; - } - - if (out != NULL) { - EC_GROUP_free(*out); - *out = ret; - } - *inp = CBS_data(&cbs); - return ret; + return bssl::D2IFromCBS(out, inp, len, EC_KEY_parse_parameters); } int i2d_ECPKParameters(const EC_GROUP *group, uint8_t **outp) { @@ -451,40 +453,24 @@ int i2d_ECPKParameters(const EC_GROUP *group, uint8_t **outp) { OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); return -1; } - - CBB cbb; - if (!CBB_init(&cbb, 0) || // - !EC_KEY_marshal_curve_name(&cbb, group)) { - CBB_cleanup(&cbb); - return -1; - } - return CBB_finish_i2d(&cbb, outp); + return bssl::I2DFromCBB( + /*initial_capacity=*/16, outp, + [&](CBB *cbb) -> bool { return EC_KEY_marshal_curve_name(cbb, group); }); } EC_KEY *d2i_ECParameters(EC_KEY **out_key, const uint8_t **inp, long len) { - if (len < 0) { - return NULL; - } - - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); - const EC_GROUP *group = EC_KEY_parse_parameters(&cbs); - if (group == NULL) { - return NULL; - } - - EC_KEY *ret = EC_KEY_new(); - if (ret == NULL || !EC_KEY_set_group(ret, group)) { - EC_KEY_free(ret); - return NULL; - } - - if (out_key != NULL) { - EC_KEY_free(*out_key); - *out_key = ret; - } - *inp = CBS_data(&cbs); - return ret; + return bssl::D2IFromCBS( + out_key, inp, len, [](CBS *cbs) -> bssl::UniquePtr { + const EC_GROUP *group = EC_KEY_parse_parameters(cbs); + if (group == nullptr) { + return nullptr; + } + bssl::UniquePtr ret(EC_KEY_new()); + if (ret == nullptr || !EC_KEY_set_group(ret.get(), group)) { + return nullptr; + } + return ret; + }); } int i2d_ECParameters(const EC_KEY *key, uint8_t **outp) { @@ -492,14 +478,10 @@ int i2d_ECParameters(const EC_KEY *key, uint8_t **outp) { OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); return -1; } - - CBB cbb; - if (!CBB_init(&cbb, 0) || // - !EC_KEY_marshal_curve_name(&cbb, key->group)) { - CBB_cleanup(&cbb); - return -1; - } - return CBB_finish_i2d(&cbb, outp); + return bssl::I2DFromCBB( + /*initial_capacity=*/16, outp, [&](CBB *cbb) -> bool { + return EC_KEY_marshal_curve_name(cbb, key->group); + }); } EC_KEY *o2i_ECPublicKey(EC_KEY **keyp, const uint8_t **inp, long len) { @@ -529,27 +511,25 @@ int i2o_ECPublicKey(const EC_KEY *key, uint8_t **outp) { OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); return 0; } - CBB cbb; - if (!CBB_init(&cbb, 0) || // - !EC_POINT_point2cbb(&cbb, key->group, key->pub_key, key->conv_form, - NULL)) { - CBB_cleanup(&cbb); - return -1; - } - int ret = CBB_finish_i2d(&cbb, outp); + // No initial capacity because |EC_POINT_point2cbb| will internally reserve + // the right size in one shot, so it's best to leave this at zero. + int ret = bssl::I2DFromCBB( + /*initial_capacity=*/0, outp, [&](CBB *cbb) -> bool { + return EC_POINT_point2cbb(cbb, key->group, key->pub_key, key->conv_form, + nullptr); + }); // Historically, this function used the wrong return value on error. return ret > 0 ? ret : 0; } size_t EC_get_builtin_curves(EC_builtin_curve *out_curves, size_t max_num_curves) { - if (max_num_curves > OPENSSL_ARRAY_SIZE(kAllGroups)) { - max_num_curves = OPENSSL_ARRAY_SIZE(kAllGroups); - } + auto all = get_all_groups(); + max_num_curves = std::min(all.size(), max_num_curves); for (size_t i = 0; i < max_num_curves; i++) { - const EC_GROUP *group = kAllGroups[i](); + const EC_GROUP *group = all[i]; out_curves[i].nid = group->curve_name; out_curves[i].comment = group->comment; } - return OPENSSL_ARRAY_SIZE(kAllGroups); + return all.size(); } diff --git a/Sources/CCryptoBoringSSL/crypto/ec/internal.h b/Sources/CCryptoBoringSSL/crypto/ec/internal.h index 336c3f298..7409e888b 100644 --- a/Sources/CCryptoBoringSSL/crypto/ec/internal.h +++ b/Sources/CCryptoBoringSSL/crypto/ec/internal.h @@ -17,6 +17,8 @@ #include +#include + #include "../fipsmodule/ec/internal.h" #if defined(__cplusplus) @@ -24,6 +26,31 @@ extern "C" { #endif +// Parsing functions. + +// ec_key_parse_curve_name behaves like |EC_KEY_parse_curve_name| but only +// supports the groups in |allowed_groups|. If no syntax errors were found but +// the group is unknown, it will fail with an error of |EC_R_UNKNOWN_GROUP|. +const EC_GROUP *ec_key_parse_curve_name( + CBS *cbs, bssl::Span allowed_groups); + +// ec_key_parse_parameters behaves like |EC_KEY_parse_parameters| but only +// supports the groups in |allowed_groups|. If no syntax errors were found but +// the group is unknown, it will fail with an error of |EC_R_UNKNOWN_GROUP|. +const EC_GROUP *ec_key_parse_parameters( + CBS *cbs, bssl::Span allowed_groups); + +// ec_key_parse_private_key behaves like |EC_KEY_parse_private_key| but only +// supports the groups in |allowed_groups|. If |group| is non-NULL, +// |allowed_groups| is ignored and instead only |group| is supported. +// +// TODO(crbug.com/boringssl/414361735): This should return a bssl::UniquePtr, +// but cannot until it is made C++ linkage. +EC_KEY *ec_key_parse_private_key( + CBS *cbs, const EC_GROUP *group, + bssl::Span allowed_groups); + + // Hash-to-curve. // // Internal |EC_JACOBIAN| versions of the corresponding public APIs. diff --git a/Sources/CCryptoBoringSSL/crypto/ecdsa/ecdsa_asn1.cc b/Sources/CCryptoBoringSSL/crypto/ecdsa/ecdsa_asn1.cc index b2dd3b259..8c06fcea3 100644 --- a/Sources/CCryptoBoringSSL/crypto/ecdsa/ecdsa_asn1.cc +++ b/Sources/CCryptoBoringSSL/crypto/ecdsa/ecdsa_asn1.cc @@ -324,28 +324,11 @@ size_t ECDSA_SIG_max_len(size_t order_len) { } ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **out, const uint8_t **inp, long len) { - if (len < 0) { - return NULL; - } - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); - ECDSA_SIG *ret = ECDSA_SIG_parse(&cbs); - if (ret == NULL) { - return NULL; - } - if (out != NULL) { - ECDSA_SIG_free(*out); - *out = ret; - } - *inp = CBS_data(&cbs); - return ret; + return bssl::D2IFromCBS(out, inp, len, ECDSA_SIG_parse); } int i2d_ECDSA_SIG(const ECDSA_SIG *sig, uint8_t **outp) { - CBB cbb; - if (!CBB_init(&cbb, 0) || !ECDSA_SIG_marshal(&cbb, sig)) { - CBB_cleanup(&cbb); - return -1; - } - return CBB_finish_i2d(&cbb, outp); + return bssl::I2DFromCBB( + /*initial_capacity=*/64, outp, + [&](CBB *cbb) -> bool { return ECDSA_SIG_marshal(cbb, sig); }); } diff --git a/Sources/CCryptoBoringSSL/crypto/evp/evp.cc b/Sources/CCryptoBoringSSL/crypto/evp/evp.cc index c14565da1..9afa1ff6f 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/evp.cc +++ b/Sources/CCryptoBoringSSL/crypto/evp/evp.cc @@ -41,19 +41,10 @@ EVP_PKEY *EVP_PKEY_new(void) { return NULL; } - ret->type = EVP_PKEY_NONE; ret->references = 1; return ret; } -static void free_it(EVP_PKEY *pkey) { - if (pkey->ameth && pkey->ameth->pkey_free) { - pkey->ameth->pkey_free(pkey); - pkey->pkey = NULL; - pkey->type = EVP_PKEY_NONE; - } -} - void EVP_PKEY_free(EVP_PKEY *pkey) { if (pkey == NULL) { return; @@ -63,7 +54,7 @@ void EVP_PKEY_free(EVP_PKEY *pkey) { return; } - free_it(pkey); + evp_pkey_set0(pkey, nullptr, nullptr); OPENSSL_free(pkey); } @@ -80,7 +71,7 @@ int EVP_PKEY_is_opaque(const EVP_PKEY *pkey) { } int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { - if (a->type != b->type) { + if (EVP_PKEY_id(a) != EVP_PKEY_id(b)) { return -1; } @@ -103,9 +94,13 @@ int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { } int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) { - if (to->type == EVP_PKEY_NONE) { - evp_pkey_set_method(to, from->ameth); - } else if (to->type != from->type) { + if (EVP_PKEY_id(to) == EVP_PKEY_NONE) { + // TODO(crbug.com/42290409): This shouldn't leave |to| in a half-empty state + // on error. The complexity here largely comes from parameterless DSA keys, + // which we no longer support, so this function can probably be trimmed + // down. + evp_pkey_set0(to, from->ameth, nullptr); + } else if (EVP_PKEY_id(to) != EVP_PKEY_id(from)) { OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES); return 0; } @@ -128,8 +123,9 @@ int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) { return from->ameth->param_copy(to, from); } - // TODO(https://crbug.com/boringssl/536): If the algorithm takes no - // parameters, copying them should vacuously succeed. + // TODO(https://crbug.com/42290406): If the algorithm takes no parameters, + // copying them should vacuously succeed. Better yet, simplify this whole + // notion of parameter copying above. return 0; } @@ -154,32 +150,17 @@ int EVP_PKEY_bits(const EVP_PKEY *pkey) { return 0; } -int EVP_PKEY_id(const EVP_PKEY *pkey) { return pkey->type; } - -// evp_pkey_asn1_find returns the ASN.1 method table for the given |nid|, which -// should be one of the |EVP_PKEY_*| values. It returns NULL if |nid| is -// unknown. -static const EVP_PKEY_ASN1_METHOD *evp_pkey_asn1_find(int nid) { - switch (nid) { - case EVP_PKEY_RSA: - return &rsa_asn1_meth; - case EVP_PKEY_EC: - return &ec_asn1_meth; - case EVP_PKEY_DSA: - return &dsa_asn1_meth; - case EVP_PKEY_ED25519: - return &ed25519_asn1_meth; - case EVP_PKEY_X25519: - return &x25519_asn1_meth; - default: - return NULL; - } +int EVP_PKEY_id(const EVP_PKEY *pkey) { + return pkey->ameth != nullptr ? pkey->ameth->pkey_id : EVP_PKEY_NONE; } -void evp_pkey_set_method(EVP_PKEY *pkey, const EVP_PKEY_ASN1_METHOD *method) { - free_it(pkey); +void evp_pkey_set0(EVP_PKEY *pkey, const EVP_PKEY_ASN1_METHOD *method, + void *pkey_data) { + if (pkey->ameth && pkey->ameth->pkey_free) { + pkey->ameth->pkey_free(pkey); + } pkey->ameth = method; - pkey->type = pkey->ameth->pkey_id; + pkey->pkey = pkey_data; } int EVP_PKEY_type(int nid) { @@ -210,84 +191,85 @@ int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) { int EVP_PKEY_set_type(EVP_PKEY *pkey, int type) { if (pkey && pkey->pkey) { - // This isn't strictly necessary, but historically |EVP_PKEY_set_type| would - // clear |pkey| even if |evp_pkey_asn1_find| failed, so we preserve that - // behavior. - free_it(pkey); + // Some callers rely on |pkey| getting cleared even if |type| is + // unsupported, usually setting |type| to |EVP_PKEY_NONE|. + evp_pkey_set0(pkey, nullptr, nullptr); } - const EVP_PKEY_ASN1_METHOD *ameth = evp_pkey_asn1_find(type); - if (ameth == NULL) { + // This function broadly isn't useful. It initializes |EVP_PKEY| for a type, + // but forgets to put anything in the |pkey|. The one pattern where it does + // anything is |EVP_PKEY_X25519|, where it's needed to make + // |EVP_PKEY_set1_tls_encodedpoint| work, so we support only that. + const EVP_PKEY_ASN1_METHOD *ameth; + if (type == EVP_PKEY_X25519) { + ameth = &x25519_asn1_meth; + } else { OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); ERR_add_error_dataf("algorithm %d", type); return 0; } if (pkey) { - evp_pkey_set_method(pkey, ameth); + evp_pkey_set0(pkey, ameth, nullptr); } return 1; } +EVP_PKEY *EVP_PKEY_from_raw_private_key(const EVP_PKEY_ALG *alg, + const uint8_t *in, size_t len) { + if (alg->method->set_priv_raw == nullptr) { + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); + return nullptr; + } + bssl::UniquePtr ret(EVP_PKEY_new()); + if (ret == nullptr || !alg->method->set_priv_raw(ret.get(), in, len)) { + return nullptr; + } + return ret.release(); +} + +EVP_PKEY *EVP_PKEY_from_raw_public_key(const EVP_PKEY_ALG *alg, + const uint8_t *in, size_t len) { + if (alg->method->set_pub_raw == nullptr) { + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); + return nullptr; + } + bssl::UniquePtr ret(EVP_PKEY_new()); + if (ret == nullptr || !alg->method->set_pub_raw(ret.get(), in, len)) { + return nullptr; + } + return ret.release(); +} + EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *unused, const uint8_t *in, size_t len) { // To avoid pulling in all key types, look for specifically the key types that // support |set_priv_raw|. - const EVP_PKEY_ASN1_METHOD *method; switch (type) { case EVP_PKEY_X25519: - method = &x25519_asn1_meth; - break; + return EVP_PKEY_from_raw_private_key(EVP_pkey_x25519(), in, len); case EVP_PKEY_ED25519: - method = &ed25519_asn1_meth; - break; + return EVP_PKEY_from_raw_private_key(EVP_pkey_ed25519(), in, len); default: OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); return nullptr; } - - bssl::UniquePtr ret(EVP_PKEY_new()); - if (ret == nullptr) { - return nullptr; - } - evp_pkey_set_method(ret.get(), method); - - if (!ret->ameth->set_priv_raw(ret.get(), in, len)) { - return nullptr; - } - - return ret.release(); } EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *unused, const uint8_t *in, size_t len) { // To avoid pulling in all key types, look for specifically the key types that // support |set_pub_raw|. - const EVP_PKEY_ASN1_METHOD *method; switch (type) { case EVP_PKEY_X25519: - method = &x25519_asn1_meth; - break; + return EVP_PKEY_from_raw_public_key(EVP_pkey_x25519(), in, len); case EVP_PKEY_ED25519: - method = &ed25519_asn1_meth; - break; + return EVP_PKEY_from_raw_public_key(EVP_pkey_ed25519(), in, len); default: OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); return nullptr; } - - bssl::UniquePtr ret(EVP_PKEY_new()); - if (ret == nullptr) { - return nullptr; - } - evp_pkey_set_method(ret.get(), method); - - if (!ret->ameth->set_pub_raw(ret.get(), in, len)) { - return nullptr; - } - - return ret.release(); } int EVP_PKEY_get_raw_private_key(const EVP_PKEY *pkey, uint8_t *out, @@ -311,7 +293,7 @@ int EVP_PKEY_get_raw_public_key(const EVP_PKEY *pkey, uint8_t *out, } int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) { - if (a->type != b->type) { + if (EVP_PKEY_id(a) != EVP_PKEY_id(b)) { return -1; } if (a->ameth && a->ameth->param_cmp) { diff --git a/Sources/CCryptoBoringSSL/crypto/evp/evp_asn1.cc b/Sources/CCryptoBoringSSL/crypto/evp/evp_asn1.cc index 6740d4a2b..26c4b29dd 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/evp_asn1.cc +++ b/Sources/CCryptoBoringSSL/crypto/evp/evp_asn1.cc @@ -16,84 +16,68 @@ #include +#include + #include #include #include #include #include +#include #include "internal.h" #include "../bytestring/internal.h" #include "../internal.h" -// We intentionally omit |dh_asn1_meth| from this list. It is not serializable. -static const EVP_PKEY_ASN1_METHOD *const kASN1Methods[] = { - &rsa_asn1_meth, - &ec_asn1_meth, - &dsa_asn1_meth, - &ed25519_asn1_meth, - &x25519_asn1_meth, -}; - -static const EVP_PKEY_ASN1_METHOD *parse_key_type(CBS *cbs) { - CBS oid; - if (!CBS_get_asn1(cbs, &oid, CBS_ASN1_OBJECT)) { - return NULL; - } - - for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(kASN1Methods); i++) { - const EVP_PKEY_ASN1_METHOD *method = kASN1Methods[i]; - if (CBS_len(&oid) == method->oid_len && - OPENSSL_memcmp(CBS_data(&oid), method->oid, method->oid_len) == 0) { - return method; - } - } - - return NULL; -} - -EVP_PKEY *EVP_parse_public_key(CBS *cbs) { +EVP_PKEY *EVP_PKEY_from_subject_public_key_info(const uint8_t *in, size_t len, + const EVP_PKEY_ALG *const *algs, + size_t num_algs) { // Parse the SubjectPublicKeyInfo. - CBS spki, algorithm, key; - uint8_t padding; - if (!CBS_get_asn1(cbs, &spki, CBS_ASN1_SEQUENCE) || + CBS cbs, spki, algorithm, oid, key; + CBS_init(&cbs, in, len); + if (!CBS_get_asn1(&cbs, &spki, CBS_ASN1_SEQUENCE) || !CBS_get_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || !CBS_get_asn1(&spki, &key, CBS_ASN1_BITSTRING) || - CBS_len(&spki) != 0) { - OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); - return nullptr; - } - const EVP_PKEY_ASN1_METHOD *method = parse_key_type(&algorithm); - if (method == nullptr) { - OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); - return nullptr; - } - if (// Every key type defined encodes the key as a byte string with the same - // conversion to BIT STRING. - !CBS_get_u8(&key, &padding) || - padding != 0) { + CBS_len(&spki) != 0 || // + CBS_len(&cbs) != 0) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); return nullptr; } - // Set up an |EVP_PKEY| of the appropriate type. bssl::UniquePtr ret(EVP_PKEY_new()); if (ret == nullptr) { return nullptr; } - evp_pkey_set_method(ret.get(), method); - - // Call into the type-specific SPKI decoding function. - if (ret->ameth->pub_decode == nullptr) { - OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); - return nullptr; - } - if (!ret->ameth->pub_decode(ret.get(), &algorithm, &key)) { - return nullptr; + for (const EVP_PKEY_ALG *alg : bssl::Span(algs, num_algs)) { + if (alg->method->pub_decode == nullptr || + bssl::Span(alg->method->oid, alg->method->oid_len) != oid) { + continue; + } + // Every key type we support encodes the key as a byte string with the same + // conversion to BIT STRING, so perform that common conversion ahead of + // time, but only after the OID is recognized as supported. + CBS key_bytes = key; + uint8_t padding; + if (!CBS_get_u8(&key_bytes, &padding) || padding != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return nullptr; + } + CBS params = algorithm; + switch (alg->method->pub_decode(alg, ret.get(), ¶ms, &key_bytes)) { + case evp_decode_error: + return nullptr; + case evp_decode_ok: + return ret.release(); + case evp_decode_unsupported: + // Continue trying other algorithms. + break; + } } - return ret.release(); + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); + return nullptr; } int EVP_marshal_public_key(CBB *cbb, const EVP_PKEY *key) { @@ -105,43 +89,47 @@ int EVP_marshal_public_key(CBB *cbb, const EVP_PKEY *key) { return key->ameth->pub_encode(cbb, key); } -EVP_PKEY *EVP_parse_private_key(CBS *cbs) { +EVP_PKEY *EVP_PKEY_from_private_key_info(const uint8_t *in, size_t len, + const EVP_PKEY_ALG *const *algs, + size_t num_algs) { // Parse the PrivateKeyInfo. - CBS pkcs8, algorithm, key; + CBS cbs, pkcs8, oid, algorithm, key; uint64_t version; - if (!CBS_get_asn1(cbs, &pkcs8, CBS_ASN1_SEQUENCE) || - !CBS_get_asn1_uint64(&pkcs8, &version) || - version != 0 || + CBS_init(&cbs, in, len); + if (!CBS_get_asn1(&cbs, &pkcs8, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_uint64(&pkcs8, &version) || version != 0 || !CBS_get_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) || - !CBS_get_asn1(&pkcs8, &key, CBS_ASN1_OCTETSTRING)) { + !CBS_get_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || + !CBS_get_asn1(&pkcs8, &key, CBS_ASN1_OCTETSTRING) || + // A PrivateKeyInfo ends with a SET of Attributes which we ignore. + CBS_len(&cbs) != 0) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); return nullptr; } - const EVP_PKEY_ASN1_METHOD *method = parse_key_type(&algorithm); - if (method == nullptr) { - OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); - return nullptr; - } - - // A PrivateKeyInfo ends with a SET of Attributes which we ignore. - // Set up an |EVP_PKEY| of the appropriate type. bssl::UniquePtr ret(EVP_PKEY_new()); if (ret == nullptr) { return nullptr; } - evp_pkey_set_method(ret.get(), method); - - // Call into the type-specific PrivateKeyInfo decoding function. - if (ret->ameth->priv_decode == nullptr) { - OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); - return nullptr; - } - if (!ret->ameth->priv_decode(ret.get(), &algorithm, &key)) { - return nullptr; + for (const EVP_PKEY_ALG *alg : bssl::Span(algs, num_algs)) { + if (alg->method->priv_decode == nullptr || + bssl::Span(alg->method->oid, alg->method->oid_len) != oid) { + continue; + } + CBS params = algorithm, key_copy = key; + switch (alg->method->priv_decode(alg, ret.get(), ¶ms, &key_copy)) { + case evp_decode_error: + return nullptr; + case evp_decode_ok: + return ret.release(); + case evp_decode_unsupported: + // Continue trying other algorithms. + break; + } } - return ret.release(); + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); + return nullptr; } int EVP_marshal_private_key(CBB *cbb, const EVP_PKEY *key) { @@ -153,6 +141,30 @@ int EVP_marshal_private_key(CBB *cbb, const EVP_PKEY *key) { return key->ameth->priv_encode(cbb, key); } +EVP_PKEY *EVP_parse_public_key(CBS *cbs) { + CBS elem; + if (!CBS_get_asn1_element(cbs, &elem, CBS_ASN1_SEQUENCE)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return nullptr; + } + + auto algs = bssl::GetDefaultEVPAlgorithms(); + return EVP_PKEY_from_subject_public_key_info(CBS_data(&elem), CBS_len(&elem), + algs.data(), algs.size()); +} + +EVP_PKEY *EVP_parse_private_key(CBS *cbs) { + CBS elem; + if (!CBS_get_asn1_element(cbs, &elem, CBS_ASN1_SEQUENCE)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return nullptr; + } + + auto algs = bssl::GetDefaultEVPAlgorithms(); + return EVP_PKEY_from_private_key_info(CBS_data(&elem), CBS_len(&elem), + algs.data(), algs.size()); +} + static bssl::UniquePtr old_priv_decode(CBS *cbs, int type) { bssl::UniquePtr ret(EVP_PKEY_new()); if (ret == nullptr) { @@ -192,35 +204,26 @@ static bssl::UniquePtr old_priv_decode(CBS *cbs, int type) { EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out, const uint8_t **inp, long len) { - if (len < 0) { - OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); - return nullptr; - } - - // Parse with the legacy format. - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); - bssl::UniquePtr ret = old_priv_decode(&cbs, type); - if (ret == nullptr) { - // Try again with PKCS#8. - ERR_clear_error(); - CBS_init(&cbs, *inp, (size_t)len); - ret.reset(EVP_parse_private_key(&cbs)); - if (ret == nullptr) { - return nullptr; - } - if (ret->type != type) { - OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES); - return nullptr; - } - } - - if (out != nullptr) { - EVP_PKEY_free(*out); - *out = ret.get(); - } - *inp = CBS_data(&cbs); - return ret.release(); + return bssl::D2IFromCBS( + out, inp, len, [&](CBS *cbs) -> bssl::UniquePtr { + // Parse with the legacy format. + CBS copy = *cbs; + bssl::UniquePtr ret = old_priv_decode(cbs, type); + if (ret == nullptr) { + // Try again with PKCS#8. + ERR_clear_error(); + *cbs = copy; + ret.reset(EVP_parse_private_key(cbs)); + if (ret == nullptr) { + return nullptr; + } + if (EVP_PKEY_id(ret.get()) != type) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES); + return nullptr; + } + } + return ret; + }); } // num_elements parses one SEQUENCE from |in| and returns the number of elements @@ -279,7 +282,7 @@ EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **out, const uint8_t **inp, long len) { } int i2d_PublicKey(const EVP_PKEY *key, uint8_t **outp) { - switch (key->type) { + switch (EVP_PKEY_id(key)) { case EVP_PKEY_RSA: return i2d_RSAPublicKey(EVP_PKEY_get0_RSA(key), outp); case EVP_PKEY_DSA: @@ -294,93 +297,70 @@ int i2d_PublicKey(const EVP_PKEY *key, uint8_t **outp) { EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **out, const uint8_t **inp, long len) { - bssl::UniquePtr ret(EVP_PKEY_new()); - if (ret == nullptr) { - return nullptr; - } - - CBS cbs; - CBS_init(&cbs, *inp, len < 0 ? 0 : (size_t)len); - switch (type) { - case EVP_PKEY_RSA: { - bssl::UniquePtr rsa(RSA_parse_public_key(&cbs)); - if (rsa == nullptr) { - return nullptr; - } - EVP_PKEY_assign_RSA(ret.get(), rsa.release()); - break; - } - - // Unlike OpenSSL, we do not support EC keys with this API. The raw EC - // public key serialization requires knowing the group. In OpenSSL, calling - // this function with |EVP_PKEY_EC| and setting |out| to nullptr does not - // work. It requires |*out| to include a partially-initialized |EVP_PKEY| to - // extract the group. - default: - OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE); - return nullptr; - } - - *inp = CBS_data(&cbs); - if (out != nullptr) { - EVP_PKEY_free(*out); - *out = ret.get(); - } - return ret.release(); + return bssl::D2IFromCBS( + out, inp, len, [&](CBS *cbs) -> bssl::UniquePtr { + bssl::UniquePtr ret(EVP_PKEY_new()); + if (ret == nullptr) { + return nullptr; + } + switch (type) { + case EVP_PKEY_RSA: { + bssl::UniquePtr rsa(RSA_parse_public_key(cbs)); + if (rsa == nullptr) { + return nullptr; + } + EVP_PKEY_assign_RSA(ret.get(), rsa.release()); + return ret; + } + + // Unlike OpenSSL, we do not support EC keys with this API. The raw EC + // public key serialization requires knowing the group. In OpenSSL, + // calling this function with |EVP_PKEY_EC| and setting |out| to + // nullptr does not work. It requires |*out| to include a + // partially-initialized |EVP_PKEY| to extract the group. + default: + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE); + return nullptr; + } + }); } EVP_PKEY *d2i_PUBKEY(EVP_PKEY **out, const uint8_t **inp, long len) { - if (len < 0) { - return nullptr; - } - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); - bssl::UniquePtr ret(EVP_parse_public_key(&cbs)); - if (ret == nullptr) { - return nullptr; - } - if (out != nullptr) { - EVP_PKEY_free(*out); - *out = ret.get(); - } - *inp = CBS_data(&cbs); - return ret.release(); + return bssl::D2IFromCBS(out, inp, len, EVP_parse_public_key); } int i2d_PUBKEY(const EVP_PKEY *pkey, uint8_t **outp) { - if (pkey == NULL) { + if (pkey == nullptr) { return 0; } + return bssl::I2DFromCBB( + /*initial_capacity=*/128, outp, + [&](CBB *cbb) -> bool { return EVP_marshal_public_key(cbb, pkey); }); +} - CBB cbb; - if (!CBB_init(&cbb, 128) || - !EVP_marshal_public_key(&cbb, pkey)) { - CBB_cleanup(&cbb); - return -1; +static bssl::UniquePtr parse_spki( + CBS *cbs, bssl::Span algs) { + CBS spki; + if (!CBS_get_asn1_element(cbs, &spki, CBS_ASN1_SEQUENCE)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return nullptr; } - return CBB_finish_i2d(&cbb, outp); + return bssl::UniquePtr(EVP_PKEY_from_subject_public_key_info( + CBS_data(&spki), CBS_len(&spki), algs.data(), algs.size())); +} + +static bssl::UniquePtr parse_spki(CBS *cbs, const EVP_PKEY_ALG *alg) { + return parse_spki(cbs, bssl::Span(&alg, 1)); } RSA *d2i_RSA_PUBKEY(RSA **out, const uint8_t **inp, long len) { - if (len < 0) { - return nullptr; - } - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); - bssl::UniquePtr pkey(EVP_parse_public_key(&cbs)); - if (pkey == nullptr) { - return nullptr; - } - bssl::UniquePtr rsa(EVP_PKEY_get1_RSA(pkey.get())); - if (rsa == nullptr) { - return nullptr; - } - if (out != nullptr) { - RSA_free(*out); - *out = rsa.get(); - } - *inp = CBS_data(&cbs); - return rsa.release(); + return bssl::D2IFromCBS(out, inp, len, [](CBS *cbs) -> bssl::UniquePtr { + bssl::UniquePtr pkey = parse_spki(cbs, EVP_pkey_rsa()); + if (pkey == nullptr) { + return nullptr; + } + return bssl::UniquePtr(EVP_PKEY_get1_RSA(pkey.get())); + }); } int i2d_RSA_PUBKEY(const RSA *rsa, uint8_t **outp) { @@ -398,25 +378,13 @@ int i2d_RSA_PUBKEY(const RSA *rsa, uint8_t **outp) { } DSA *d2i_DSA_PUBKEY(DSA **out, const uint8_t **inp, long len) { - if (len < 0) { - return nullptr; - } - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); - bssl::UniquePtr pkey(EVP_parse_public_key(&cbs)); - if (pkey == nullptr) { - return nullptr; - } - bssl::UniquePtr dsa(EVP_PKEY_get1_DSA(pkey.get())); - if (dsa == nullptr) { - return nullptr; - } - if (out != nullptr) { - DSA_free(*out); - *out = dsa.get(); - } - *inp = CBS_data(&cbs); - return dsa.release(); + return bssl::D2IFromCBS(out, inp, len, [](CBS *cbs) -> bssl::UniquePtr { + bssl::UniquePtr pkey = parse_spki(cbs, EVP_pkey_dsa()); + if (pkey == nullptr) { + return nullptr; + } + return bssl::UniquePtr(EVP_PKEY_get1_DSA(pkey.get())); + }); } int i2d_DSA_PUBKEY(const DSA *dsa, uint8_t **outp) { @@ -434,25 +402,17 @@ int i2d_DSA_PUBKEY(const DSA *dsa, uint8_t **outp) { } EC_KEY *d2i_EC_PUBKEY(EC_KEY **out, const uint8_t **inp, long len) { - if (len < 0) { - return nullptr; - } - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); - bssl::UniquePtr pkey(EVP_parse_public_key(&cbs)); - if (pkey == nullptr) { - return nullptr; - } - bssl::UniquePtr ec_key(EVP_PKEY_get1_EC_KEY(pkey.get())); - if (ec_key == nullptr) { - return nullptr; - } - if (out != nullptr) { - EC_KEY_free(*out); - *out = ec_key.get(); - } - *inp = CBS_data(&cbs); - return ec_key.release(); + return bssl::D2IFromCBS( + out, inp, len, [](CBS *cbs) -> bssl::UniquePtr { + const EVP_PKEY_ALG *const algs[] = { + EVP_pkey_ec_p224(), EVP_pkey_ec_p256(), EVP_pkey_ec_p384(), + EVP_pkey_ec_p521()}; + bssl::UniquePtr pkey = parse_spki(cbs, algs); + if (pkey == nullptr) { + return nullptr; + } + return bssl::UniquePtr(EVP_PKEY_get1_EC_KEY(pkey.get())); + }); } int i2d_EC_PUBKEY(const EC_KEY *ec_key, uint8_t **outp) { diff --git a/Sources/CCryptoBoringSSL/crypto/evp/evp_ctx.cc b/Sources/CCryptoBoringSSL/crypto/evp/evp_ctx.cc index ebf9034f6..f9ff9b94c 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/evp_ctx.cc +++ b/Sources/CCryptoBoringSSL/crypto/evp/evp_ctx.cc @@ -25,29 +25,31 @@ #include "internal.h" -static const EVP_PKEY_METHOD *const evp_methods[] = { +// |EVP_PKEY_RSA_PSS| is intentionally omitted from this list. These are types +// that can be created without an |EVP_PKEY|, and we do not support +// |EVP_PKEY_RSA_PSS| keygen. +static const EVP_PKEY_CTX_METHOD *const evp_methods[] = { &rsa_pkey_meth, &ec_pkey_meth, &ed25519_pkey_meth, &x25519_pkey_meth, &hkdf_pkey_meth, }; -static const EVP_PKEY_METHOD *evp_pkey_meth_find(int type) { - for (size_t i = 0; i < sizeof(evp_methods) / sizeof(EVP_PKEY_METHOD *); i++) { - if (evp_methods[i]->pkey_id == type) { - return evp_methods[i]; +static const EVP_PKEY_CTX_METHOD *evp_pkey_meth_find(int type) { + for (auto method : evp_methods) { + if (method->pkey_id == type) { + return method; } } - return NULL; + return nullptr; } -static EVP_PKEY_CTX *evp_pkey_ctx_new(EVP_PKEY *pkey, ENGINE *e, - const EVP_PKEY_METHOD *pmeth) { +static EVP_PKEY_CTX *evp_pkey_ctx_new(EVP_PKEY *pkey, + const EVP_PKEY_CTX_METHOD *pmeth) { bssl::UniquePtr ret = bssl::MakeUnique(); if (!ret) { return nullptr; } - ret->engine = e; ret->pmeth = pmeth; ret->operation = EVP_PKEY_OP_UNDEFINED; ret->pkey = bssl::UpRef(pkey); @@ -66,25 +68,25 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e) { return NULL; } - const EVP_PKEY_METHOD *pkey_method = pkey->ameth->pkey_method; + const EVP_PKEY_CTX_METHOD *pkey_method = pkey->ameth->pkey_method; if (pkey_method == NULL) { OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); ERR_add_error_dataf("algorithm %d", pkey->ameth->pkey_id); return NULL; } - return evp_pkey_ctx_new(pkey, e, pkey_method); + return evp_pkey_ctx_new(pkey, pkey_method); } EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e) { - const EVP_PKEY_METHOD *pkey_method = evp_pkey_meth_find(id); + const EVP_PKEY_CTX_METHOD *pkey_method = evp_pkey_meth_find(id); if (pkey_method == NULL) { OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); ERR_add_error_dataf("algorithm %d", id); return NULL; } - return evp_pkey_ctx_new(NULL, e, pkey_method); + return evp_pkey_ctx_new(NULL, pkey_method); } evp_pkey_ctx_st::~evp_pkey_ctx_st() { @@ -106,7 +108,6 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx) { } ret->pmeth = ctx->pmeth; - ret->engine = ctx->engine; ret->operation = ctx->operation; ret->pkey = bssl::UpRef(ctx->pkey); ret->peerkey = bssl::UpRef(ctx->peerkey); @@ -297,7 +298,7 @@ int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) { return 0; } - if (ctx->pkey->type != peer->type) { + if (EVP_PKEY_id(ctx->pkey.get()) != EVP_PKEY_id(peer)) { OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES); return 0; } diff --git a/Sources/CCryptoBoringSSL/crypto/evp/internal.h b/Sources/CCryptoBoringSSL/crypto/evp/internal.h index 913fe3888..baf4c29a0 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/internal.h +++ b/Sources/CCryptoBoringSSL/crypto/evp/internal.h @@ -15,9 +15,11 @@ #ifndef OPENSSL_HEADER_CRYPTO_EVP_INTERNAL_H #define OPENSSL_HEADER_CRYPTO_EVP_INTERNAL_H -#include +#include -#include +#include + +#include #include "../internal.h" @@ -27,23 +29,46 @@ extern "C" { typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD; -typedef struct evp_pkey_method_st EVP_PKEY_METHOD; +typedef struct evp_pkey_ctx_method_st EVP_PKEY_CTX_METHOD; + +struct evp_pkey_alg_st { + // method implements operations for this |EVP_PKEY_ALG|. + const EVP_PKEY_ASN1_METHOD *method; + + // ec_group returns the |EC_GROUP| for this algorithm, if |method| is for + // |EVP_PKEY_EC|. + const EC_GROUP *(*ec_group)(); +}; + +enum evp_decode_result_t { + evp_decode_error = 0, + evp_decode_ok = 1, + evp_decode_unsupported = 2, +}; struct evp_pkey_asn1_method_st { + // pkey_id contains one of the |EVP_PKEY_*| values and corresponds to the OID + // in the key type's AlgorithmIdentifier. int pkey_id; uint8_t oid[9]; uint8_t oid_len; - const EVP_PKEY_METHOD *pkey_method; + const EVP_PKEY_CTX_METHOD *pkey_method; // pub_decode decodes |params| and |key| as a SubjectPublicKeyInfo - // and writes the result into |out|. It returns one on success and zero on - // error. |params| is the AlgorithmIdentifier after the OBJECT IDENTIFIER - // type field, and |key| is the contents of the subjectPublicKey with the - // leading padding byte checked and removed. Although X.509 uses BIT STRINGs - // to represent SubjectPublicKeyInfo, every key type defined encodes the key - // as a byte string with the same conversion to BIT STRING. - int (*pub_decode)(EVP_PKEY *out, CBS *params, CBS *key); + // and writes the result into |out|. It returns |evp_decode_ok| on success, + // and |evp_decode_error| on error, and |evp_decode_unsupported| if the input + // was not supported by this |EVP_PKEY_ALG|. In case of + // |evp_decode_unsupported|, it does not add an error to the error queue. May + // modify |params| and |key|. Callers must make a copy if calling in a loop. + // + // |params| is the AlgorithmIdentifier after the OBJECT IDENTIFIER type field, + // and |key| is the contents of the subjectPublicKey with the leading padding + // byte checked and removed. Although X.509 uses BIT STRINGs to represent + // SubjectPublicKeyInfo, every key type defined encodes the key as a byte + // string with the same conversion to BIT STRING. + evp_decode_result_t (*pub_decode)(const EVP_PKEY_ALG *alg, EVP_PKEY *out, + CBS *params, CBS *key); // pub_encode encodes |key| as a SubjectPublicKeyInfo and appends the result // to |out|. It returns one on success and zero on error. @@ -52,10 +77,16 @@ struct evp_pkey_asn1_method_st { int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b); // priv_decode decodes |params| and |key| as a PrivateKeyInfo and writes the - // result into |out|. It returns one on success and zero on error. |params| is - // the AlgorithmIdentifier after the OBJECT IDENTIFIER type field, and |key| - // is the contents of the OCTET STRING privateKey field. - int (*priv_decode)(EVP_PKEY *out, CBS *params, CBS *key); + // result into |out|. It returns |evp_decode_ok| on success, and + // |evp_decode_error| on error, and |evp_decode_unsupported| if the key type + // was not supported by this |EVP_PKEY_ALG|. In case of + // |evp_decode_unsupported|, it does not add an error to the error queue. May + // modify |params| and |key|. Callers must make a copy if calling in a loop. + // + // |params| is the AlgorithmIdentifier after the OBJECT IDENTIFIER type field, + // and |key| is the contents of the OCTET STRING privateKey field. + evp_decode_result_t (*priv_decode)(const EVP_PKEY_ALG *alg, EVP_PKEY *out, + CBS *params, CBS *key); // priv_encode encodes |key| as a PrivateKeyInfo and appends the result to // |out|. It returns one on success and zero on error. @@ -94,15 +125,11 @@ struct evp_pkey_asn1_method_st { struct evp_pkey_st { CRYPTO_refcount_t references; - // type contains one of the EVP_PKEY_* values or NID_undef and determines - // the type of |pkey|. - int type; - - // pkey contains a pointer to a structure dependent on |type|. + // pkey contains a pointer to a structure dependent on |ameth|. void *pkey; - // ameth contains a pointer to a method table that contains many ASN.1 - // methods for the key type. + // ameth contains a pointer to a method table that determines the key type, or + // nullptr if the key is empty. const EVP_PKEY_ASN1_METHOD *ameth; } /* EVP_PKEY */; @@ -167,7 +194,7 @@ OPENSSL_EXPORT int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, #define EVP_PKEY_CTRL_GET_RSA_MGF1_MD (EVP_PKEY_ALG_CTRL + 10) #define EVP_PKEY_CTRL_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 11) #define EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 12) -#define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID (EVP_PKEY_ALG_CTRL + 13) +#define EVP_PKEY_CTRL_EC_PARAMGEN_GROUP (EVP_PKEY_ALG_CTRL + 13) #define EVP_PKEY_CTRL_HKDF_MODE (EVP_PKEY_ALG_CTRL + 14) #define EVP_PKEY_CTRL_HKDF_MD (EVP_PKEY_ALG_CTRL + 15) #define EVP_PKEY_CTRL_HKDF_KEY (EVP_PKEY_ALG_CTRL + 16) @@ -179,20 +206,21 @@ struct evp_pkey_ctx_st { ~evp_pkey_ctx_st(); // Method associated with this operation - const EVP_PKEY_METHOD *pmeth = nullptr; - // Engine that implements this method or nullptr if builtin - ENGINE *engine = nullptr; + const EVP_PKEY_CTX_METHOD *pmeth = nullptr; // Key: may be nullptr bssl::UniquePtr pkey; // Peer key for key agreement, may be nullptr bssl::UniquePtr peerkey; // operation contains one of the |EVP_PKEY_OP_*| values. int operation = EVP_PKEY_OP_UNDEFINED; - // Algorithm specific data + // Algorithm specific data. + // TODO(davidben): Since a |EVP_PKEY_CTX| never has its type change after + // creation, this should instead be a base class, with the algorithm-specific + // data on the subclass, coming from the same allocation. void *data = nullptr; } /* EVP_PKEY_CTX */; -struct evp_pkey_method_st { +struct evp_pkey_ctx_method_st { int pkey_id; int (*init)(EVP_PKEY_CTX *ctx); @@ -227,7 +255,7 @@ struct evp_pkey_method_st { int (*paramgen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey); int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2); -} /* EVP_PKEY_METHOD */; +} /* EVP_PKEY_CTX_METHOD */; typedef struct { // key is the concatenation of the private seed and public key. It is stored @@ -249,24 +277,47 @@ typedef struct { extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meth; extern const EVP_PKEY_ASN1_METHOD ec_asn1_meth; extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD rsa_pss_sha256_asn1_meth; extern const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth; extern const EVP_PKEY_ASN1_METHOD x25519_asn1_meth; extern const EVP_PKEY_ASN1_METHOD dh_asn1_meth; -extern const EVP_PKEY_METHOD rsa_pkey_meth; -extern const EVP_PKEY_METHOD ec_pkey_meth; -extern const EVP_PKEY_METHOD ed25519_pkey_meth; -extern const EVP_PKEY_METHOD x25519_pkey_meth; -extern const EVP_PKEY_METHOD hkdf_pkey_meth; -extern const EVP_PKEY_METHOD dh_pkey_meth; +extern const EVP_PKEY_CTX_METHOD rsa_pkey_meth; +extern const EVP_PKEY_CTX_METHOD rsa_pss_sha256_pkey_meth; +extern const EVP_PKEY_CTX_METHOD ec_pkey_meth; +extern const EVP_PKEY_CTX_METHOD ed25519_pkey_meth; +extern const EVP_PKEY_CTX_METHOD x25519_pkey_meth; +extern const EVP_PKEY_CTX_METHOD hkdf_pkey_meth; +extern const EVP_PKEY_CTX_METHOD dh_pkey_meth; -// evp_pkey_set_method behaves like |EVP_PKEY_set_type|, but takes a pointer to -// a method table. This avoids depending on every |EVP_PKEY_ASN1_METHOD|. -void evp_pkey_set_method(EVP_PKEY *pkey, const EVP_PKEY_ASN1_METHOD *method); +// evp_pkey_set0 sets |pkey|'s method to |method| and data to |pkey_data|, +// freeing any key that may previously have been configured. This function takes +// ownership of |pkey_data|, which must be of the type expected by |method|. +void evp_pkey_set0(EVP_PKEY *pkey, const EVP_PKEY_ASN1_METHOD *method, + void *pkey_data); #if defined(__cplusplus) } // extern C #endif +BSSL_NAMESPACE_BEGIN +inline auto GetDefaultEVPAlgorithms() { + // A set of algorithms to use by default in |EVP_parse_public_key| and + // |EVP_parse_private_key|. + return std::array{ + EVP_pkey_ec_p224(), + EVP_pkey_ec_p256(), + EVP_pkey_ec_p384(), + EVP_pkey_ec_p521(), + EVP_pkey_ed25519(), + EVP_pkey_rsa(), + EVP_pkey_x25519(), + // TODO(crbug.com/438761503): Remove DSA from this set, after callers that + // need DSA pass in |EVP_pkey_dsa| explicitly. + EVP_pkey_dsa(), + }; +} +BSSL_NAMESPACE_END + #endif // OPENSSL_HEADER_CRYPTO_EVP_INTERNAL_H diff --git a/Sources/CCryptoBoringSSL/crypto/evp/p_dh.cc b/Sources/CCryptoBoringSSL/crypto/evp/p_dh.cc index dcf4e7c81..b70d92fd6 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/p_dh.cc +++ b/Sources/CCryptoBoringSSL/crypto/evp/p_dh.cc @@ -129,7 +129,7 @@ static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { } } -const EVP_PKEY_METHOD dh_pkey_meth = { +const EVP_PKEY_CTX_METHOD dh_pkey_meth = { /*pkey_id=*/EVP_PKEY_DH, /*init=*/pkey_dh_init, /*copy=*/pkey_dh_copy, diff --git a/Sources/CCryptoBoringSSL/crypto/evp/p_dh_asn1.cc b/Sources/CCryptoBoringSSL/crypto/evp/p_dh_asn1.cc index f600f43c6..55fbca3e9 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/p_dh_asn1.cc +++ b/Sources/CCryptoBoringSSL/crypto/evp/p_dh_asn1.cc @@ -120,13 +120,15 @@ int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key) { } int EVP_PKEY_assign_DH(EVP_PKEY *pkey, DH *key) { - evp_pkey_set_method(pkey, &dh_asn1_meth); - pkey->pkey = key; - return key != NULL; + if (key == nullptr) { + return 0; + } + evp_pkey_set0(pkey, &dh_asn1_meth, key); + return 1; } DH *EVP_PKEY_get0_DH(const EVP_PKEY *pkey) { - if (pkey->type != EVP_PKEY_DH) { + if (EVP_PKEY_id(pkey) != EVP_PKEY_DH) { OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_A_DH_KEY); return NULL; } diff --git a/Sources/CCryptoBoringSSL/crypto/evp/p_dsa_asn1.cc b/Sources/CCryptoBoringSSL/crypto/evp/p_dsa_asn1.cc index c8e40ad97..c4df801d4 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/p_dsa_asn1.cc +++ b/Sources/CCryptoBoringSSL/crypto/evp/p_dsa_asn1.cc @@ -24,36 +24,32 @@ #include "internal.h" -static int dsa_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { +static evp_decode_result_t dsa_pub_decode(const EVP_PKEY_ALG *alg, + EVP_PKEY *out, CBS *params, + CBS *key) { // See RFC 3279, section 2.3.2. - // Parameters may or may not be present. - bssl::UniquePtr dsa; - if (CBS_len(params) == 0) { - dsa.reset(DSA_new()); - if (dsa == nullptr) { - return 0; - } - } else { - dsa.reset(DSA_parse_parameters(params)); - if (dsa == nullptr || CBS_len(params) != 0) { - OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); - return 0; - } + // Decode parameters. RFC 3279 permits DSA parameters to be omitted, in which + // case they are implicitly determined from the issuing certificate, or + // somewhere unspecified and out-of-band. We do not support this mode. + bssl::UniquePtr dsa(DSA_parse_parameters(params)); + if (dsa == nullptr || CBS_len(params) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return evp_decode_error; } dsa->pub_key = BN_new(); if (dsa->pub_key == nullptr) { - return 0; + return evp_decode_error; } if (!BN_parse_asn1_unsigned(key, dsa->pub_key) || CBS_len(key) != 0) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); - return 0; + return evp_decode_error; } EVP_PKEY_assign_DSA(out, dsa.release()); - return 1; + return evp_decode_ok; } static int dsa_pub_encode(CBB *out, const EVP_PKEY *key) { @@ -78,23 +74,25 @@ static int dsa_pub_encode(CBB *out, const EVP_PKEY *key) { return 1; } -static int dsa_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { +static evp_decode_result_t dsa_priv_decode(const EVP_PKEY_ALG *alg, + EVP_PKEY *out, CBS *params, + CBS *key) { // See PKCS#11, v2.40, section 2.5. // Decode parameters. bssl::UniquePtr dsa(DSA_parse_parameters(params)); if (dsa == nullptr || CBS_len(params) != 0) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); - return 0; + return evp_decode_error; } dsa->priv_key = BN_new(); if (dsa->priv_key == nullptr) { - return 0; + return evp_decode_error; } if (!BN_parse_asn1_unsigned(key, dsa->priv_key) || CBS_len(key) != 0) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); - return 0; + return evp_decode_error; } // To avoid DoS attacks when importing private keys, check bounds on |dsa|. @@ -102,7 +100,7 @@ static int dsa_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { // width. if (!dsa_check_key(dsa.get())) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); - return 0; + return evp_decode_error; } // Calculate the public key. @@ -111,11 +109,11 @@ static int dsa_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { if (ctx == nullptr || dsa->pub_key == nullptr || !BN_mod_exp_mont_consttime(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx.get(), nullptr)) { - return 0; + return evp_decode_error; } EVP_PKEY_assign_DSA(out, dsa.release()); - return 1; + return evp_decode_ok; } static int dsa_priv_encode(CBB *out, const EVP_PKEY *key) { @@ -236,6 +234,14 @@ const EVP_PKEY_ASN1_METHOD dsa_asn1_meth = { int_dsa_free, }; +const EVP_PKEY_ALG *EVP_pkey_dsa(void) { + static const EVP_PKEY_ALG kAlg = { + /*method=*/&dsa_asn1_meth, + /*ec_group=*/nullptr, + }; + return &kAlg; +} + int EVP_PKEY_CTX_set_dsa_paramgen_bits(EVP_PKEY_CTX *ctx, int nbits) { // BoringSSL does not support DSA in |EVP_PKEY_CTX|. OPENSSL_PUT_ERROR(EVP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); @@ -257,13 +263,15 @@ int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key) { } int EVP_PKEY_assign_DSA(EVP_PKEY *pkey, DSA *key) { - evp_pkey_set_method(pkey, &dsa_asn1_meth); - pkey->pkey = key; - return key != nullptr; + if (key == nullptr) { + return 0; + } + evp_pkey_set0(pkey, &dsa_asn1_meth, key); + return 1; } DSA *EVP_PKEY_get0_DSA(const EVP_PKEY *pkey) { - if (pkey->type != EVP_PKEY_DSA) { + if (EVP_PKEY_id(pkey) != EVP_PKEY_DSA) { OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_A_DSA_KEY); return nullptr; } diff --git a/Sources/CCryptoBoringSSL/crypto/evp/p_ec.cc b/Sources/CCryptoBoringSSL/crypto/evp/p_ec.cc index a19b97bfb..9bd2396f7 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/p_ec.cc +++ b/Sources/CCryptoBoringSSL/crypto/evp/p_ec.cc @@ -148,12 +148,8 @@ static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { // Default behaviour is OK return 1; - case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID: { - const EC_GROUP *group = EC_GROUP_new_by_curve_name(p1); - if (group == NULL) { - return 0; - } - dctx->gen_group = group; + case EVP_PKEY_CTRL_EC_PARAMGEN_GROUP: { + dctx->gen_group = static_cast(p2); return 1; } @@ -197,7 +193,7 @@ static int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { return 1; } -const EVP_PKEY_METHOD ec_pkey_meth = { +const EVP_PKEY_CTX_METHOD ec_pkey_meth = { EVP_PKEY_EC, pkey_ec_init, pkey_ec_copy, @@ -216,8 +212,13 @@ const EVP_PKEY_METHOD ec_pkey_meth = { }; int EVP_PKEY_CTX_set_ec_paramgen_curve_nid(EVP_PKEY_CTX *ctx, int nid) { + const EC_GROUP *group = EC_GROUP_new_by_curve_name(nid); + if (group == nullptr) { + return 0; + } return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, EVP_PKEY_OP_TYPE_GEN, - EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, NULL); + EVP_PKEY_CTRL_EC_PARAMGEN_GROUP, 0, + const_cast(group)); } int EVP_PKEY_CTX_set_ec_param_enc(EVP_PKEY_CTX *ctx, int encoding) { diff --git a/Sources/CCryptoBoringSSL/crypto/evp/p_ec_asn1.cc b/Sources/CCryptoBoringSSL/crypto/evp/p_ec_asn1.cc index 942769b1b..812d3deba 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/p_ec_asn1.cc +++ b/Sources/CCryptoBoringSSL/crypto/evp/p_ec_asn1.cc @@ -20,7 +20,10 @@ #include #include #include +#include +#include +#include "../ec/internal.h" #include "internal.h" @@ -48,25 +51,35 @@ static int eckey_pub_encode(CBB *out, const EVP_PKEY *key) { return 1; } -static int eckey_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { +static evp_decode_result_t eckey_pub_decode(const EVP_PKEY_ALG *alg, + EVP_PKEY *out, CBS *params, + CBS *key) { // See RFC 5480, section 2. - // The parameters are a named curve. - const EC_GROUP *group = EC_KEY_parse_curve_name(params); - if (group == NULL || CBS_len(params) != 0) { + // Check that |params| matches |alg|. Only the namedCurve form is allowed. + const EC_GROUP *group = alg->ec_group(); + if (ec_key_parse_curve_name(params, bssl::Span(&group, 1)) == nullptr) { + if (ERR_equals(ERR_peek_last_error(), ERR_LIB_EC, EC_R_UNKNOWN_GROUP)) { + ERR_clear_error(); + return evp_decode_unsupported; + } OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); - return 0; + return evp_decode_error; + } + if (CBS_len(params) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return evp_decode_error; } bssl::UniquePtr eckey(EC_KEY_new()); if (eckey == nullptr || // !EC_KEY_set_group(eckey.get(), group) || !EC_KEY_oct2key(eckey.get(), CBS_data(key), CBS_len(key), nullptr)) { - return 0; + return evp_decode_error; } EVP_PKEY_assign_EC_KEY(out, eckey.release()); - return 1; + return evp_decode_ok; } static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { @@ -85,23 +98,32 @@ static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { } } -static int eckey_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { +static evp_decode_result_t eckey_priv_decode(const EVP_PKEY_ALG *alg, + EVP_PKEY *out, CBS *params, + CBS *key) { // See RFC 5915. - const EC_GROUP *group = EC_KEY_parse_parameters(params); - if (group == NULL || CBS_len(params) != 0) { + const EC_GROUP *group = alg->ec_group(); + if (ec_key_parse_parameters(params, bssl::Span(&group, 1)) == nullptr) { + if (ERR_equals(ERR_peek_last_error(), ERR_LIB_EC, EC_R_UNKNOWN_GROUP)) { + ERR_clear_error(); + return evp_decode_unsupported; + } OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); - return 0; + return evp_decode_error; + } + if (CBS_len(params) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return evp_decode_error; } - EC_KEY *ec_key = EC_KEY_parse_private_key(key, group); - if (ec_key == NULL || CBS_len(key) != 0) { + bssl::UniquePtr ec_key(ec_key_parse_private_key(key, group, {})); + if (ec_key == nullptr || CBS_len(key) != 0) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); - EC_KEY_free(ec_key); - return 0; + return evp_decode_error; } - EVP_PKEY_assign_EC_KEY(out, ec_key); - return 1; + EVP_PKEY_assign_EC_KEY(out, ec_key.release()); + return evp_decode_ok; } static int eckey_priv_encode(CBB *out, const EVP_PKEY *key) { @@ -255,6 +277,39 @@ const EVP_PKEY_ASN1_METHOD ec_asn1_meth = { int_ec_free, }; +const EVP_PKEY_ALG *EVP_pkey_ec_p224(void) { + static const EVP_PKEY_ALG kAlg = { + /*method=*/&ec_asn1_meth, + /*ec_group=*/&EC_group_p224, + }; + return &kAlg; +} + +const EVP_PKEY_ALG *EVP_pkey_ec_p256(void) { + static const EVP_PKEY_ALG kAlg = { + /*method=*/&ec_asn1_meth, + /*ec_group=*/&EC_group_p256, + }; + return &kAlg; +} + +const EVP_PKEY_ALG *EVP_pkey_ec_p384(void) { + static const EVP_PKEY_ALG kAlg = { + /*method=*/&ec_asn1_meth, + /*ec_group=*/&EC_group_p384, + }; + return &kAlg; +} + +const EVP_PKEY_ALG *EVP_pkey_ec_p521(void) { + static const EVP_PKEY_ALG kAlg = { + /*method=*/&ec_asn1_meth, + /*ec_group=*/&EC_group_p521, + }; + return &kAlg; +} + + int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) { if (EVP_PKEY_assign_EC_KEY(pkey, key)) { EC_KEY_up_ref(key); @@ -264,14 +319,16 @@ int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) { } int EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) { - evp_pkey_set_method(pkey, &ec_asn1_meth); - pkey->pkey = key; - return key != NULL; + if (key == nullptr) { + return 0; + } + evp_pkey_set0(pkey, &ec_asn1_meth, key); + return 1; } EC_KEY *EVP_PKEY_get0_EC_KEY(const EVP_PKEY *pkey) { - if (pkey->type != EVP_PKEY_EC) { - OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_AN_EC_KEY_KEY); + if (EVP_PKEY_id(pkey) != EVP_PKEY_EC) { + OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_A_EC_KEY); return NULL; } return reinterpret_cast(pkey->pkey); @@ -284,3 +341,23 @@ EC_KEY *EVP_PKEY_get1_EC_KEY(const EVP_PKEY *pkey) { } return ec_key; } + +int EVP_PKEY_get_ec_curve_nid(const EVP_PKEY *pkey) { + const EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey); + if (ec_key == nullptr) { + return NID_undef; + } + const EC_GROUP *group = EC_KEY_get0_group(ec_key); + if (group == nullptr) { + return NID_undef; + } + return EC_GROUP_get_curve_name(group); +} + +int EVP_PKEY_get_ec_point_conv_form(const EVP_PKEY *pkey) { + const EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey); + if (ec_key == nullptr) { + return 0; + } + return EC_KEY_get_conv_form(ec_key); +} diff --git a/Sources/CCryptoBoringSSL/crypto/evp/p_ed25519.cc b/Sources/CCryptoBoringSSL/crypto/evp/p_ed25519.cc index a8d19912f..5bfc553a6 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/p_ed25519.cc +++ b/Sources/CCryptoBoringSSL/crypto/evp/p_ed25519.cc @@ -31,14 +31,11 @@ static int pkey_ed25519_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { return 0; } - evp_pkey_set_method(pkey, &ed25519_asn1_meth); - uint8_t pubkey_unused[32]; ED25519_keypair(pubkey_unused, key->key); key->has_private = 1; - OPENSSL_free(pkey->pkey); - pkey->pkey = key; + evp_pkey_set0(pkey, &ed25519_asn1_meth, key); return 1; } @@ -84,7 +81,7 @@ static int pkey_ed25519_verify_message(EVP_PKEY_CTX *ctx, const uint8_t *sig, return 1; } -const EVP_PKEY_METHOD ed25519_pkey_meth = { +const EVP_PKEY_CTX_METHOD ed25519_pkey_meth = { /*pkey_id=*/EVP_PKEY_ED25519, /*init=*/nullptr, /*copy=*/pkey_ed25519_copy, diff --git a/Sources/CCryptoBoringSSL/crypto/evp/p_ed25519_asn1.cc b/Sources/CCryptoBoringSSL/crypto/evp/p_ed25519_asn1.cc index 6b2f7b9b2..6625fe68a 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/p_ed25519_asn1.cc +++ b/Sources/CCryptoBoringSSL/crypto/evp/p_ed25519_asn1.cc @@ -45,9 +45,7 @@ static int ed25519_set_priv_raw(EVP_PKEY *pkey, const uint8_t *in, size_t len) { uint8_t pubkey_unused[32]; ED25519_keypair_from_seed(pubkey_unused, key->key, in); key->has_private = 1; - - ed25519_free(pkey); - pkey->pkey = key; + evp_pkey_set0(pkey, &ed25519_asn1_meth, key); return 1; } @@ -65,9 +63,7 @@ static int ed25519_set_pub_raw(EVP_PKEY *pkey, const uint8_t *in, size_t len) { OPENSSL_memcpy(key->key + ED25519_PUBLIC_KEY_OFFSET, in, 32); key->has_private = 0; - - ed25519_free(pkey); - pkey->pkey = key; + evp_pkey_set0(pkey, &ed25519_asn1_meth, key); return 1; } @@ -113,16 +109,20 @@ static int ed25519_get_pub_raw(const EVP_PKEY *pkey, uint8_t *out, return 1; } -static int ed25519_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { +static evp_decode_result_t ed25519_pub_decode(const EVP_PKEY_ALG *alg, + EVP_PKEY *out, CBS *params, + CBS *key) { // See RFC 8410, section 4. // The parameters must be omitted. Public keys have length 32. if (CBS_len(params) != 0) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); - return 0; + return evp_decode_error; } - return ed25519_set_pub_raw(out, CBS_data(key), CBS_len(key)); + return ed25519_set_pub_raw(out, CBS_data(key), CBS_len(key)) + ? evp_decode_ok + : evp_decode_error; } static int ed25519_pub_encode(CBB *out, const EVP_PKEY *pkey) { @@ -153,7 +153,9 @@ static int ed25519_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { b_key->key + ED25519_PUBLIC_KEY_OFFSET, 32) == 0; } -static int ed25519_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { +static evp_decode_result_t ed25519_priv_decode(const EVP_PKEY_ALG *alg, + EVP_PKEY *out, CBS *params, + CBS *key) { // See RFC 8410, section 7. // Parameters must be empty. The key is a 32-byte value wrapped in an extra @@ -162,10 +164,12 @@ static int ed25519_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { if (CBS_len(params) != 0 || !CBS_get_asn1(key, &inner, CBS_ASN1_OCTETSTRING) || CBS_len(key) != 0) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); - return 0; + return evp_decode_error; } - return ed25519_set_priv_raw(out, CBS_data(&inner), CBS_len(&inner)); + return ed25519_set_priv_raw(out, CBS_data(&inner), CBS_len(&inner)) + ? evp_decode_ok + : evp_decode_error; } static int ed25519_priv_encode(CBB *out, const EVP_PKEY *pkey) { @@ -223,3 +227,11 @@ const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = { /*param_cmp=*/NULL, ed25519_free, }; + +const EVP_PKEY_ALG *EVP_pkey_ed25519(void) { + static const EVP_PKEY_ALG kAlg = { + /*method=*/&ed25519_asn1_meth, + /*ec_group=*/nullptr, + }; + return &kAlg; +} diff --git a/Sources/CCryptoBoringSSL/crypto/evp/p_hkdf.cc b/Sources/CCryptoBoringSSL/crypto/evp/p_hkdf.cc index 00af6034a..1e917fe7f 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/p_hkdf.cc +++ b/Sources/CCryptoBoringSSL/crypto/evp/p_hkdf.cc @@ -183,7 +183,7 @@ static int pkey_hkdf_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { } } -const EVP_PKEY_METHOD hkdf_pkey_meth = { +const EVP_PKEY_CTX_METHOD hkdf_pkey_meth = { /*pkey_id=*/EVP_PKEY_HKDF, pkey_hkdf_init, pkey_hkdf_copy, diff --git a/Sources/CCryptoBoringSSL/crypto/evp/p_rsa.cc b/Sources/CCryptoBoringSSL/crypto/evp/p_rsa.cc index a55dd4c8a..0d5912493 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/p_rsa.cc +++ b/Sources/CCryptoBoringSSL/crypto/evp/p_rsa.cc @@ -24,50 +24,59 @@ #include #include #include +#include #include "../internal.h" +#include "../mem_internal.h" #include "../rsa/internal.h" #include "internal.h" -typedef struct { +namespace { + +struct RSA_PKEY_CTX { // Key gen parameters - int nbits; - BIGNUM *pub_exp; + int nbits = 2048; + bssl::UniquePtr pub_exp; // RSA padding mode - int pad_mode; + int pad_mode = RSA_PKCS1_PADDING; // message digest - const EVP_MD *md; + const EVP_MD *md = nullptr; // message digest for MGF1 - const EVP_MD *mgf1md; + const EVP_MD *mgf1md = nullptr; // PSS salt length - int saltlen; - // tbuf is a buffer which is either NULL, or is the size of the RSA modulus. - // It's used to store the output of RSA operations. - uint8_t *tbuf; - // OAEP label - uint8_t *oaep_label; - size_t oaep_labellen; -} RSA_PKEY_CTX; - -typedef struct { - uint8_t *data; - size_t len; -} RSA_OAEP_LABEL_PARAMS; + int saltlen = RSA_PSS_SALTLEN_DIGEST; + // restrict_pss_params, if true, indicates that the PSS signing/verifying + // parameters are restricted by the key's parameters. |md| and |mgf1md| may + // not change, and |saltlen| must be at least |md|'s hash length. + bool restrict_pss_params = false; + bssl::Array oaep_label; +}; + +static bool is_pss_only(const EVP_PKEY_CTX *ctx) { + return ctx->pmeth->pkey_id == EVP_PKEY_RSA_PSS; +} static int pkey_rsa_init(EVP_PKEY_CTX *ctx) { - RSA_PKEY_CTX *rctx = - reinterpret_cast(OPENSSL_zalloc(sizeof(RSA_PKEY_CTX))); + RSA_PKEY_CTX *rctx = bssl::New(); if (!rctx) { return 0; } - rctx->nbits = 2048; - rctx->pad_mode = RSA_PKCS1_PADDING; - rctx->saltlen = -2; + if (is_pss_only(ctx)) { + rctx->pad_mode = RSA_PKCS1_PSS_PADDING; + // Pick up PSS parameters from the key. For now, we only support the SHA-256 + // parameter set, so every key is necessarily SHA-256. If we ever support + // other parameters, we will need more state in |EVP_PKEY| and to translate + // that state into defaults here. + if (ctx->pkey != nullptr) { + rctx->md = rctx->mgf1md = EVP_sha256(); + rctx->saltlen = EVP_MD_size(rctx->md); + rctx->restrict_pss_params = true; + } + } ctx->data = rctx; - return 1; } @@ -80,7 +89,7 @@ static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) { dctx = reinterpret_cast(dst->data); dctx->nbits = sctx->nbits; if (sctx->pub_exp) { - dctx->pub_exp = BN_dup(sctx->pub_exp); + dctx->pub_exp.reset(BN_dup(sctx->pub_exp.get())); if (!dctx->pub_exp) { return 0; } @@ -90,42 +99,16 @@ static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) { dctx->md = sctx->md; dctx->mgf1md = sctx->mgf1md; dctx->saltlen = sctx->saltlen; - if (sctx->oaep_label) { - OPENSSL_free(dctx->oaep_label); - dctx->oaep_label = reinterpret_cast( - OPENSSL_memdup(sctx->oaep_label, sctx->oaep_labellen)); - if (!dctx->oaep_label) { - return 0; - } - dctx->oaep_labellen = sctx->oaep_labellen; + dctx->restrict_pss_params = sctx->restrict_pss_params; + if (!dctx->oaep_label.CopyFrom(sctx->oaep_label)) { + return 0; } return 1; } static void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx) { - RSA_PKEY_CTX *rctx = reinterpret_cast(ctx->data); - - if (rctx == NULL) { - return; - } - - BN_free(rctx->pub_exp); - OPENSSL_free(rctx->tbuf); - OPENSSL_free(rctx->oaep_label); - OPENSSL_free(rctx); -} - -static int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk) { - if (ctx->tbuf) { - return 1; - } - ctx->tbuf = reinterpret_cast( - OPENSSL_malloc(EVP_PKEY_size(pk->pkey.get()))); - if (!ctx->tbuf) { - return 0; - } - return 1; + bssl::Delete(reinterpret_cast(ctx->data)); } static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen, @@ -187,12 +170,13 @@ static int pkey_rsa_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t siglen, size_t rslen; const size_t key_len = EVP_PKEY_size(ctx->pkey.get()); - if (!setup_tbuf(rctx, ctx) || - !RSA_verify_raw(rsa, &rslen, rctx->tbuf, key_len, sig, siglen, + bssl::Array tbuf; + if (!tbuf.InitForOverwrite(key_len) || + !RSA_verify_raw(rsa, &rslen, tbuf.data(), tbuf.size(), sig, siglen, rctx->pad_mode)) { return 0; } - if (rslen != tbslen || CRYPTO_memcmp(tbs, rctx->tbuf, rslen) != 0) { + if (rslen != tbslen || CRYPTO_memcmp(tbs, tbuf.data(), rslen) != 0) { OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_SIGNATURE); return 0; } @@ -232,33 +216,28 @@ static int pkey_rsa_verify_recover(EVP_PKEY_CTX *ctx, uint8_t *out, uint8_t *asn1_prefix; size_t asn1_prefix_len; int asn1_prefix_allocated; - if (!setup_tbuf(rctx, ctx) || - !RSA_add_pkcs1_prefix(&asn1_prefix, &asn1_prefix_len, + if (!RSA_add_pkcs1_prefix(&asn1_prefix, &asn1_prefix_len, &asn1_prefix_allocated, EVP_MD_type(rctx->md), kDummyHash, hash_len)) { return 0; } + bssl::UniquePtr free_asn1_prefix(asn1_prefix_allocated ? asn1_prefix + : nullptr); + bssl::Array tbuf; size_t rslen; - int ok = 1; - if (!RSA_verify_raw(rsa, &rslen, rctx->tbuf, key_len, sig, sig_len, + if (!tbuf.InitForOverwrite(key_len) || + !RSA_verify_raw(rsa, &rslen, tbuf.data(), tbuf.size(), sig, sig_len, RSA_PKCS1_PADDING) || rslen != asn1_prefix_len || // Compare all but the hash suffix. - CRYPTO_memcmp(rctx->tbuf, asn1_prefix, asn1_prefix_len - hash_len) != 0) { - ok = 0; - } - - if (asn1_prefix_allocated) { - OPENSSL_free(asn1_prefix); - } - - if (!ok) { + CRYPTO_memcmp(tbuf.data(), asn1_prefix, asn1_prefix_len - hash_len) != + 0) { return 0; } if (out != NULL) { - OPENSSL_memcpy(out, rctx->tbuf + rslen - hash_len, hash_len); + OPENSSL_memcpy(out, tbuf.data() + rslen - hash_len, hash_len); } *out_len = hash_len; @@ -282,11 +261,12 @@ static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, } if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) { - if (!setup_tbuf(rctx, ctx) || - !RSA_padding_add_PKCS1_OAEP_mgf1(rctx->tbuf, key_len, in, inlen, - rctx->oaep_label, rctx->oaep_labellen, - rctx->md, rctx->mgf1md) || - !RSA_encrypt(rsa, outlen, out, *outlen, rctx->tbuf, key_len, + bssl::Array tbuf; + if (!tbuf.InitForOverwrite(key_len) || + !RSA_padding_add_PKCS1_OAEP_mgf1( + tbuf.data(), tbuf.size(), in, inlen, rctx->oaep_label.data(), + rctx->oaep_label.size(), rctx->md, rctx->mgf1md) || + !RSA_encrypt(rsa, outlen, out, *outlen, tbuf.data(), tbuf.size(), RSA_NO_PADDING)) { return 0; } @@ -313,13 +293,15 @@ static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, } if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) { + bssl::Array tbuf; size_t padded_len; - if (!setup_tbuf(rctx, ctx) || - !RSA_decrypt(rsa, &padded_len, rctx->tbuf, key_len, in, inlen, + if (!tbuf.InitForOverwrite(key_len) || + !RSA_decrypt(rsa, &padded_len, tbuf.data(), tbuf.size(), in, inlen, RSA_NO_PADDING) || - !RSA_padding_check_PKCS1_OAEP_mgf1( - out, outlen, key_len, rctx->tbuf, padded_len, rctx->oaep_label, - rctx->oaep_labellen, rctx->md, rctx->mgf1md)) { + !RSA_padding_check_PKCS1_OAEP_mgf1(out, outlen, key_len, tbuf.data(), + padded_len, rctx->oaep_label.data(), + rctx->oaep_label.size(), rctx->md, + rctx->mgf1md)) { return 0; } return 1; @@ -357,6 +339,11 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { RSA_PKEY_CTX *rctx = reinterpret_cast(ctx->data); switch (type) { case EVP_PKEY_CTRL_RSA_PADDING: + // PSS keys cannot be switched to other padding types. + if (is_pss_only(ctx) && p1 != RSA_PKCS1_PSS_PADDING) { + OPENSSL_PUT_ERROR(EVP, EVP_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); + return 0; + } if (!is_known_padding(p1) || !check_padding_md(rctx->md, p1) || (p1 == RSA_PKCS1_PSS_PADDING && 0 == (ctx->operation & (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY))) || @@ -365,8 +352,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { OPENSSL_PUT_ERROR(EVP, EVP_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); return 0; } - if ((p1 == RSA_PKCS1_PSS_PADDING || p1 == RSA_PKCS1_OAEP_PADDING) && - rctx->md == NULL) { + if (p1 == RSA_PKCS1_OAEP_PADDING && rctx->md == NULL) { rctx->md = EVP_sha1(); } rctx->pad_mode = p1; @@ -385,7 +371,21 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN) { *(int *)p2 = rctx->saltlen; } else { - if (p1 < -2) { + // Negative salt lengths are special values. + if (p1 < 0) { + if (p1 != RSA_PSS_SALTLEN_DIGEST && p1 != RSA_PSS_SALTLEN_AUTO) { + return 0; + } + // All our PSS restrictions accept saltlen == hashlen, so allow + // |RSA_PSS_SALTLEN_DIGEST|. Reject |RSA_PSS_SALTLEN_AUTO| for + // simplicity. + if (rctx->restrict_pss_params && p1 != RSA_PSS_SALTLEN_DIGEST) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PSS_SALTLEN); + return 0; + } + } else if (rctx->restrict_pss_params && + static_cast(p1) < EVP_MD_size(rctx->md)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PSS_SALTLEN); return 0; } rctx->saltlen = p1; @@ -404,8 +404,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { if (!p2) { return 0; } - BN_free(rctx->pub_exp); - rctx->pub_exp = reinterpret_cast(p2); + rctx->pub_exp.reset(reinterpret_cast(p2)); return 1; case EVP_PKEY_CTRL_RSA_OAEP_MD: @@ -421,12 +420,19 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { } return 1; - case EVP_PKEY_CTRL_MD: - if (!check_padding_md(reinterpret_cast(p2), rctx->pad_mode)) { + case EVP_PKEY_CTRL_MD: { + const EVP_MD *md = reinterpret_cast(p2); + if (!check_padding_md(md, rctx->pad_mode)) { return 0; } - rctx->md = reinterpret_cast(p2); + if (rctx->restrict_pss_params && + EVP_MD_type(rctx->md) != EVP_MD_type(md)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_DIGEST_TYPE); + return 0; + } + rctx->md = md; return 1; + } case EVP_PKEY_CTRL_GET_MD: *(const EVP_MD **)p2 = rctx->md; @@ -446,7 +452,13 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { *(const EVP_MD **)p2 = rctx->md; } } else { - rctx->mgf1md = reinterpret_cast(p2); + const EVP_MD *md = reinterpret_cast(p2); + if (rctx->restrict_pss_params && + EVP_MD_type(rctx->mgf1md) != EVP_MD_type(md)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_MGF1_MD); + return 0; + } + rctx->mgf1md = md; } return 1; @@ -455,11 +467,10 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PADDING_MODE); return 0; } - OPENSSL_free(rctx->oaep_label); - RSA_OAEP_LABEL_PARAMS *params = - reinterpret_cast(p2); - rctx->oaep_label = params->data; - rctx->oaep_labellen = params->len; + // |EVP_PKEY_CTRL_RSA_OAEP_LABEL| takes ownership of |label|'s underlying + // buffer (via |Reset|), but only on success. + auto *label = reinterpret_cast *>(p2); + rctx->oaep_label.Reset(label->data(), label->size()); return 1; } @@ -468,7 +479,7 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PADDING_MODE); return 0; } - CBS_init((CBS *)p2, rctx->oaep_label, rctx->oaep_labellen); + *reinterpret_cast(p2) = CBS(rctx->oaep_label); return 1; default: @@ -478,90 +489,130 @@ static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { } static int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { - RSA *rsa = NULL; RSA_PKEY_CTX *rctx = reinterpret_cast(ctx->data); - if (!rctx->pub_exp) { - rctx->pub_exp = BN_new(); - if (!rctx->pub_exp || !BN_set_word(rctx->pub_exp, RSA_F4)) { + rctx->pub_exp.reset(BN_new()); + if (!rctx->pub_exp || !BN_set_word(rctx->pub_exp.get(), RSA_F4)) { return 0; } } - rsa = RSA_new(); + bssl::UniquePtr rsa(RSA_new()); if (!rsa) { return 0; } - if (!RSA_generate_key_ex(rsa, rctx->nbits, rctx->pub_exp, NULL)) { - RSA_free(rsa); + if (!RSA_generate_key_ex(rsa.get(), rctx->nbits, rctx->pub_exp.get(), + nullptr)) { return 0; } - EVP_PKEY_assign_RSA(pkey, rsa); + EVP_PKEY_assign_RSA(pkey, rsa.release()); return 1; } -const EVP_PKEY_METHOD rsa_pkey_meth = { +} // namespace + +const EVP_PKEY_CTX_METHOD rsa_pkey_meth = { EVP_PKEY_RSA, pkey_rsa_init, pkey_rsa_copy, pkey_rsa_cleanup, pkey_rsa_keygen, pkey_rsa_sign, - NULL /* sign_message */, + /*sign_message=*/nullptr, pkey_rsa_verify, - NULL /* verify_message */, + /*verify_message=*/nullptr, pkey_rsa_verify_recover, pkey_rsa_encrypt, pkey_rsa_decrypt, - NULL /* derive */, - NULL /* paramgen */, + /*derive=*/nullptr, + /*paramgen=*/nullptr, + pkey_rsa_ctrl, +}; + +const EVP_PKEY_CTX_METHOD rsa_pss_sha256_pkey_meth = { + EVP_PKEY_RSA_PSS, + pkey_rsa_init, + pkey_rsa_copy, + pkey_rsa_cleanup, + // In OpenSSL, |EVP_PKEY_RSA_PSS| supports key generation and fills in PSS + // parameters based on a separate set of keygen-targetted setters: + // |EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen|, + // |EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md|, and + // |EVP_PKEY_CTX_rsa_pss_key_digest|. We do not currently implement this + // because we only support one parameter set. + /*keygen=*/nullptr, + pkey_rsa_sign, + /*sign_message=*/nullptr, + pkey_rsa_verify, + /*verify_message=*/nullptr, + /*verify_recover=*/nullptr, + /*encrypt=*/nullptr, + /*decrypt=*/nullptr, + /*derive=*/nullptr, + /*paramgen=*/nullptr, pkey_rsa_ctrl, }; +static int rsa_or_rsa_pss_ctrl(EVP_PKEY_CTX *ctx, int optype, int cmd, int p1, + void *p2) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl) { + OPENSSL_PUT_ERROR(EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return 0; + } + if (ctx->pmeth->pkey_id != EVP_PKEY_RSA && + ctx->pmeth->pkey_id != EVP_PKEY_RSA_PSS) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + return EVP_PKEY_CTX_ctrl(ctx, /*keytype=*/-1, optype, cmd, p1, p2); +} + int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int padding) { - return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING, - padding, NULL); + return rsa_or_rsa_pss_ctrl(ctx, -1, EVP_PKEY_CTRL_RSA_PADDING, padding, + nullptr); } int EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx, int *out_padding) { - return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_GET_RSA_PADDING, - 0, out_padding); + return rsa_or_rsa_pss_ctrl(ctx, -1, EVP_PKEY_CTRL_GET_RSA_PADDING, 0, + out_padding); } int EVP_PKEY_CTX_set_rsa_pss_keygen_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) { + // We currently do not support keygen with |EVP_PKEY_RSA_PSS|. return 0; } int EVP_PKEY_CTX_set_rsa_pss_keygen_saltlen(EVP_PKEY_CTX *ctx, int salt_len) { + // We currently do not support keygen with |EVP_PKEY_RSA_PSS|. return 0; } int EVP_PKEY_CTX_set_rsa_pss_keygen_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) { + // We currently do not support keygen with |EVP_PKEY_RSA_PSS|. return 0; } int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int salt_len) { - return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, - (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY), - EVP_PKEY_CTRL_RSA_PSS_SALTLEN, salt_len, NULL); + return rsa_or_rsa_pss_ctrl(ctx, (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY), + EVP_PKEY_CTRL_RSA_PSS_SALTLEN, salt_len, nullptr); } int EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int *out_salt_len) { - return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, - (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY), - EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN, 0, out_salt_len); + return rsa_or_rsa_pss_ctrl(ctx, (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY), + EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN, 0, + out_salt_len); } int EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX *ctx, int bits) { - return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, - EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL); + return rsa_or_rsa_pss_ctrl(ctx, EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, nullptr); } int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *e) { - return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, - EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, e); + return rsa_or_rsa_pss_ctrl(ctx, EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, e); } int EVP_PKEY_CTX_set_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) { @@ -575,22 +626,20 @@ int EVP_PKEY_CTX_get_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md) { } int EVP_PKEY_CTX_set_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) { - return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, - EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, - EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void *)md); + return rsa_or_rsa_pss_ctrl(ctx, EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void *)md); } int EVP_PKEY_CTX_get_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md) { - return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, - EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, - EVP_PKEY_CTRL_GET_RSA_MGF1_MD, 0, (void *)out_md); + return rsa_or_rsa_pss_ctrl(ctx, EVP_PKEY_OP_TYPE_SIG | EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_GET_RSA_MGF1_MD, 0, (void *)out_md); } int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, uint8_t *label, size_t label_len) { - RSA_OAEP_LABEL_PARAMS params = {label, label_len}; + bssl::Span span(label, label_len); return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, - EVP_PKEY_CTRL_RSA_OAEP_LABEL, 0, ¶ms); + EVP_PKEY_CTRL_RSA_OAEP_LABEL, 0, &span); } int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx, diff --git a/Sources/CCryptoBoringSSL/crypto/evp/p_rsa_asn1.cc b/Sources/CCryptoBoringSSL/crypto/evp/p_rsa_asn1.cc index 682967835..8865b68a9 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/p_rsa_asn1.cc +++ b/Sources/CCryptoBoringSSL/crypto/evp/p_rsa_asn1.cc @@ -20,8 +20,10 @@ #include #include #include +#include #include "../fipsmodule/rsa/internal.h" +#include "../rsa/internal.h" #include "internal.h" @@ -45,7 +47,9 @@ static int rsa_pub_encode(CBB *out, const EVP_PKEY *key) { return 1; } -static int rsa_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { +static evp_decode_result_t rsa_pub_decode(const EVP_PKEY_ALG *alg, + EVP_PKEY *out, CBS *params, + CBS *key) { // See RFC 3279, section 2.3.1. // The parameters must be NULL. @@ -53,21 +57,25 @@ static int rsa_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { if (!CBS_get_asn1(params, &null, CBS_ASN1_NULL) || CBS_len(&null) != 0 || CBS_len(params) != 0) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); - return 0; + return evp_decode_error; } - RSA *rsa = RSA_parse_public_key(key); - if (rsa == NULL || CBS_len(key) != 0) { + bssl::UniquePtr rsa( + RSA_public_key_from_bytes(CBS_data(key), CBS_len(key))); + if (rsa == nullptr) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); - RSA_free(rsa); - return 0; + return evp_decode_error; } - EVP_PKEY_assign_RSA(out, rsa); - return 1; + EVP_PKEY_assign_RSA(out, rsa.release()); + return evp_decode_ok; } static int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { + // We currently assume that all |EVP_PKEY_RSA_PSS| keys have the same + // parameters, so this vacuously compares parameters. If we ever support + // multiple PSS parameter sets, we probably should compare them too. Note, + // however, that OpenSSL does not compare parameters here. const RSA *a_rsa = reinterpret_cast(a->pkey); const RSA *b_rsa = reinterpret_cast(b->pkey); return BN_cmp(RSA_get0_n(b_rsa), RSA_get0_n(a_rsa)) == 0 && @@ -93,26 +101,122 @@ static int rsa_priv_encode(CBB *out, const EVP_PKEY *key) { return 1; } -static int rsa_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { - // Per RFC 3447, A.1, the parameters have type NULL. +static evp_decode_result_t rsa_priv_decode(const EVP_PKEY_ALG *alg, + EVP_PKEY *out, CBS *params, + CBS *key) { + // Per RFC 8017, A.1, the parameters have type NULL. CBS null; if (!CBS_get_asn1(params, &null, CBS_ASN1_NULL) || CBS_len(&null) != 0 || CBS_len(params) != 0) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return evp_decode_error; + } + + bssl::UniquePtr rsa( + RSA_private_key_from_bytes(CBS_data(key), CBS_len(key))); + if (rsa == nullptr) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return evp_decode_error; + } + + EVP_PKEY_assign_RSA(out, rsa.release()); + return evp_decode_ok; +} + +static evp_decode_result_t rsa_decode_pss_params_sha256(CBS *params) { + // For now, we only support the SHA-256 parameter set. If we want to support + // more, we'll need to record a little more state in the |EVP_PKEY|. + if (CBS_len(params) == 0) { + return evp_decode_unsupported; + } + rsa_pss_params_t pss_params; + if (!rsa_parse_pss_params(params, &pss_params, + /*allow_explicit_trailer=*/false) || + CBS_len(params) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return evp_decode_error; + } + return pss_params == rsa_pss_sha256 ? evp_decode_ok : evp_decode_unsupported; +} + +static int rsa_pub_encode_pss_sha256(CBB *out, const EVP_PKEY *key) { + const RSA *rsa = reinterpret_cast(key->pkey); + CBB spki, algorithm, key_bitstring; + if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_element(&algorithm, CBS_ASN1_OBJECT, + rsa_pss_sha256_asn1_meth.oid, + rsa_pss_sha256_asn1_meth.oid_len) || + !rsa_marshal_pss_params(&algorithm, rsa_pss_sha256) || + !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) || + !CBB_add_u8(&key_bitstring, 0 /* padding */) || + !RSA_marshal_public_key(&key_bitstring, rsa) || // + !CBB_flush(out)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); return 0; } - RSA *rsa = RSA_parse_private_key(key); - if (rsa == NULL || CBS_len(key) != 0) { + return 1; +} + +static evp_decode_result_t rsa_pub_decode_pss_sha256(const EVP_PKEY_ALG *alg, + EVP_PKEY *out, CBS *params, + CBS *key) { + evp_decode_result_t ret = rsa_decode_pss_params_sha256(params); + if (ret != evp_decode_ok) { + return ret; + } + + bssl::UniquePtr rsa( + RSA_public_key_from_bytes(CBS_data(key), CBS_len(key))); + if (rsa == nullptr) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); - RSA_free(rsa); + return evp_decode_error; + } + + evp_pkey_set0(out, &rsa_pss_sha256_asn1_meth, rsa.release()); + return evp_decode_ok; +} + +static int rsa_priv_encode_pss_sha256(CBB *out, const EVP_PKEY *key) { + const RSA *rsa = reinterpret_cast(key->pkey); + CBB pkcs8, algorithm, private_key; + if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) || + !CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_element(&algorithm, CBS_ASN1_OBJECT, + rsa_pss_sha256_asn1_meth.oid, + rsa_pss_sha256_asn1_meth.oid_len) || + !rsa_marshal_pss_params(&algorithm, rsa_pss_sha256) || + !CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) || + !RSA_marshal_private_key(&private_key, rsa) || // + !CBB_flush(out)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); return 0; } - EVP_PKEY_assign_RSA(out, rsa); return 1; } +static evp_decode_result_t rsa_priv_decode_pss_sha256(const EVP_PKEY_ALG *alg, + EVP_PKEY *out, + CBS *params, CBS *key) { + evp_decode_result_t ret = rsa_decode_pss_params_sha256(params); + if (ret != evp_decode_ok) { + return ret; + } + + bssl::UniquePtr rsa( + RSA_private_key_from_bytes(CBS_data(key), CBS_len(key))); + if (rsa == nullptr) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return evp_decode_error; + } + + evp_pkey_set0(out, &rsa_pss_sha256_asn1_meth, rsa.release()); + return evp_decode_ok; +} + static int rsa_opaque(const EVP_PKEY *pkey) { const RSA *rsa = reinterpret_cast(pkey->pkey); return RSA_is_opaque(rsa); @@ -148,25 +252,76 @@ const EVP_PKEY_ASN1_METHOD rsa_asn1_meth = { rsa_priv_decode, rsa_priv_encode, - /*set_priv_raw=*/NULL, - /*set_pub_raw=*/NULL, - /*get_priv_raw=*/NULL, - /*get_pub_raw=*/NULL, - /*set1_tls_encodedpoint=*/NULL, - /*get1_tls_encodedpoint=*/NULL, + /*set_priv_raw=*/nullptr, + /*set_pub_raw=*/nullptr, + /*get_priv_raw=*/nullptr, + /*get_pub_raw=*/nullptr, + /*set1_tls_encodedpoint=*/nullptr, + /*get1_tls_encodedpoint=*/nullptr, + + rsa_opaque, + + int_rsa_size, + rsa_bits, + + /*param_missing=*/nullptr, + /*param_copy=*/nullptr, + /*param_cmp=*/nullptr, + + int_rsa_free, +}; + +const EVP_PKEY_ASN1_METHOD rsa_pss_sha256_asn1_meth = { + EVP_PKEY_RSA_PSS, + // 1.2.840.113549.1.1.10 + {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a}, + 9, + + &rsa_pss_sha256_pkey_meth, + + rsa_pub_decode_pss_sha256, + rsa_pub_encode_pss_sha256, + rsa_pub_cmp, + + rsa_priv_decode_pss_sha256, + rsa_priv_encode_pss_sha256, + + /*set_priv_raw=*/nullptr, + /*set_pub_raw=*/nullptr, + /*get_priv_raw=*/nullptr, + /*get_pub_raw=*/nullptr, + /*set1_tls_encodedpoint=*/nullptr, + /*get1_tls_encodedpoint=*/nullptr, rsa_opaque, int_rsa_size, rsa_bits, - 0, - 0, - 0, + /*param_missing=*/nullptr, + /*param_copy=*/nullptr, + /*param_cmp=*/nullptr, int_rsa_free, }; + +const EVP_PKEY_ALG *EVP_pkey_rsa(void) { + static const EVP_PKEY_ALG kAlg = { + /*method=*/&rsa_asn1_meth, + /*ec_group=*/nullptr, + }; + return &kAlg; +} + +const EVP_PKEY_ALG *EVP_pkey_rsa_pss_sha256(void) { + static const EVP_PKEY_ALG kAlg = { + /*method=*/&rsa_pss_sha256_asn1_meth, + /*ec_group=*/nullptr, + }; + return &kAlg; +} + int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key) { if (EVP_PKEY_assign_RSA(pkey, key)) { RSA_up_ref(key); @@ -176,13 +331,16 @@ int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key) { } int EVP_PKEY_assign_RSA(EVP_PKEY *pkey, RSA *key) { - evp_pkey_set_method(pkey, &rsa_asn1_meth); - pkey->pkey = key; - return key != NULL; + if (key == nullptr) { + return 0; + } + evp_pkey_set0(pkey, &rsa_asn1_meth, key); + return 1; } RSA *EVP_PKEY_get0_RSA(const EVP_PKEY *pkey) { - if (pkey->type != EVP_PKEY_RSA) { + int pkey_id = EVP_PKEY_id(pkey); + if (pkey_id != EVP_PKEY_RSA && pkey_id != EVP_PKEY_RSA_PSS) { OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_AN_RSA_KEY); return NULL; } diff --git a/Sources/CCryptoBoringSSL/crypto/evp/p_x25519.cc b/Sources/CCryptoBoringSSL/crypto/evp/p_x25519.cc index da526bc96..6e3d23b35 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/p_x25519.cc +++ b/Sources/CCryptoBoringSSL/crypto/evp/p_x25519.cc @@ -31,13 +31,9 @@ static int pkey_x25519_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { return 0; } - evp_pkey_set_method(pkey, &x25519_asn1_meth); - X25519_keypair(key->pub, key->priv); key->has_private = 1; - - OPENSSL_free(pkey->pkey); - pkey->pkey = key; + evp_pkey_set0(pkey, &x25519_asn1_meth, key); return 1; } @@ -90,7 +86,7 @@ static int pkey_x25519_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { } } -const EVP_PKEY_METHOD x25519_pkey_meth = { +const EVP_PKEY_CTX_METHOD x25519_pkey_meth = { /*pkey_id=*/EVP_PKEY_X25519, /*init=*/NULL, /*copy=*/pkey_x25519_copy, diff --git a/Sources/CCryptoBoringSSL/crypto/evp/p_x25519_asn1.cc b/Sources/CCryptoBoringSSL/crypto/evp/p_x25519_asn1.cc index ced00a586..ed43ce3c3 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/p_x25519_asn1.cc +++ b/Sources/CCryptoBoringSSL/crypto/evp/p_x25519_asn1.cc @@ -44,8 +44,7 @@ static int x25519_set_priv_raw(EVP_PKEY *pkey, const uint8_t *in, size_t len) { X25519_public_from_private(key->pub, key->priv); key->has_private = 1; - x25519_free(pkey); - pkey->pkey = key; + evp_pkey_set0(pkey, &x25519_asn1_meth, key); return 1; } @@ -64,8 +63,7 @@ static int x25519_set_pub_raw(EVP_PKEY *pkey, const uint8_t *in, size_t len) { OPENSSL_memcpy(key->pub, in, 32); key->has_private = 0; - x25519_free(pkey); - pkey->pkey = key; + evp_pkey_set0(pkey, &x25519_asn1_meth, key); return 1; } @@ -127,16 +125,20 @@ static size_t x25519_get1_tls_encodedpoint(const EVP_PKEY *pkey, return *out_ptr == NULL ? 0 : 32; } -static int x25519_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { +static evp_decode_result_t x25519_pub_decode(const EVP_PKEY_ALG *alg, + EVP_PKEY *out, CBS *params, + CBS *key) { // See RFC 8410, section 4. // The parameters must be omitted. Public keys have length 32. if (CBS_len(params) != 0) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); - return 0; + return evp_decode_error; } - return x25519_set_pub_raw(out, CBS_data(key), CBS_len(key)); + return x25519_set_pub_raw(out, CBS_data(key), CBS_len(key)) + ? evp_decode_ok + : evp_decode_error; } static int x25519_pub_encode(CBB *out, const EVP_PKEY *pkey) { @@ -165,7 +167,9 @@ static int x25519_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { return OPENSSL_memcmp(a_key->pub, b_key->pub, 32) == 0; } -static int x25519_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { +static evp_decode_result_t x25519_priv_decode(const EVP_PKEY_ALG *alg, + EVP_PKEY *out, CBS *params, + CBS *key) { // See RFC 8410, section 7. // Parameters must be empty. The key is a 32-byte value wrapped in an extra @@ -174,10 +178,12 @@ static int x25519_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { if (CBS_len(params) != 0 || !CBS_get_asn1(key, &inner, CBS_ASN1_OCTETSTRING) || CBS_len(key) != 0) { OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); - return 0; + return evp_decode_error; } - return x25519_set_priv_raw(out, CBS_data(&inner), CBS_len(&inner)); + return x25519_set_priv_raw(out, CBS_data(&inner), CBS_len(&inner)) + ? evp_decode_ok + : evp_decode_error; } static int x25519_priv_encode(CBB *out, const EVP_PKEY *pkey) { @@ -235,3 +241,11 @@ const EVP_PKEY_ASN1_METHOD x25519_asn1_meth = { /*param_cmp=*/NULL, x25519_free, }; + +const EVP_PKEY_ALG *EVP_pkey_x25519(void) { + static const EVP_PKEY_ALG kAlg = { + /*method=*/&x25519_asn1_meth, + /*ec_group=*/nullptr, + }; + return &kAlg; +} diff --git a/Sources/CCryptoBoringSSL/crypto/evp/print.cc b/Sources/CCryptoBoringSSL/crypto/evp/print.cc index f052f89a7..718d8c79d 100644 --- a/Sources/CCryptoBoringSSL/crypto/evp/print.cc +++ b/Sources/CCryptoBoringSSL/crypto/evp/print.cc @@ -152,55 +152,6 @@ static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent) { } -// DSA keys. - -static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) { - const BIGNUM *priv_key = NULL; - if (ptype == 2) { - priv_key = DSA_get0_priv_key(x); - } - - const BIGNUM *pub_key = NULL; - if (ptype > 0) { - pub_key = DSA_get0_pub_key(x); - } - - const char *ktype = "DSA-Parameters"; - if (ptype == 2) { - ktype = "Private-Key"; - } else if (ptype == 1) { - ktype = "Public-Key"; - } - - if (!BIO_indent(bp, off, 128) || - BIO_printf(bp, "%s: (%u bit)\n", ktype, BN_num_bits(DSA_get0_p(x))) <= - 0 || - // |priv_key| and |pub_key| may be NULL, in which case |bn_print| will - // silently skip them. - !bn_print(bp, "priv:", priv_key, off) || - !bn_print(bp, "pub:", pub_key, off) || - !bn_print(bp, "P:", DSA_get0_p(x), off) || - !bn_print(bp, "Q:", DSA_get0_q(x), off) || - !bn_print(bp, "G:", DSA_get0_g(x), off)) { - return 0; - } - - return 1; -} - -static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent) { - return do_dsa_print(bp, EVP_PKEY_get0_DSA(pkey), indent, 0); -} - -static int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent) { - return do_dsa_print(bp, EVP_PKEY_get0_DSA(pkey), indent, 1); -} - -static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent) { - return do_dsa_print(bp, EVP_PKEY_get0_DSA(pkey), indent, 2); -} - - // EC keys. static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) { @@ -277,18 +228,12 @@ typedef struct { int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent); } EVP_PKEY_PRINT_METHOD; -static EVP_PKEY_PRINT_METHOD kPrintMethods[] = { +static const EVP_PKEY_PRINT_METHOD kPrintMethods[] = { { EVP_PKEY_RSA, rsa_pub_print, rsa_priv_print, - NULL /* param_print */, - }, - { - EVP_PKEY_DSA, - dsa_pub_print, - dsa_priv_print, - dsa_param_print, + /*param_print=*/nullptr, }, { EVP_PKEY_EC, @@ -298,15 +243,13 @@ static EVP_PKEY_PRINT_METHOD kPrintMethods[] = { }, }; -static size_t kPrintMethodsLen = OPENSSL_ARRAY_SIZE(kPrintMethods); - -static EVP_PKEY_PRINT_METHOD *find_method(int type) { - for (size_t i = 0; i < kPrintMethodsLen; i++) { - if (kPrintMethods[i].type == type) { - return &kPrintMethods[i]; +static const EVP_PKEY_PRINT_METHOD *find_method(int type) { + for (const auto &p : kPrintMethods) { + if (p.type == type) { + return &p; } } - return NULL; + return nullptr; } static int print_unsupported(BIO *out, const EVP_PKEY *pkey, int indent, @@ -318,7 +261,7 @@ static int print_unsupported(BIO *out, const EVP_PKEY *pkey, int indent, int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) { - EVP_PKEY_PRINT_METHOD *method = find_method(EVP_PKEY_id(pkey)); + const EVP_PKEY_PRINT_METHOD *method = find_method(EVP_PKEY_id(pkey)); if (method != NULL && method->pub_print != NULL) { return method->pub_print(out, pkey, indent); } @@ -327,7 +270,7 @@ int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent, int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) { - EVP_PKEY_PRINT_METHOD *method = find_method(EVP_PKEY_id(pkey)); + const EVP_PKEY_PRINT_METHOD *method = find_method(EVP_PKEY_id(pkey)); if (method != NULL && method->priv_print != NULL) { return method->priv_print(out, pkey, indent); } @@ -336,7 +279,7 @@ int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent, int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx) { - EVP_PKEY_PRINT_METHOD *method = find_method(EVP_PKEY_id(pkey)); + const EVP_PKEY_PRINT_METHOD *method = find_method(EVP_PKEY_id(pkey)); if (method != NULL && method->param_print != NULL) { return method->param_print(out, pkey, indent); } diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/bcm.cc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/bcm.cc index 6863c5535..257b2a260 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/bcm.cc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/bcm.cc @@ -26,7 +26,7 @@ #include #include -#include +#include #include "../bcm_support.h" #include "../internal.h" @@ -90,6 +90,7 @@ #include "ec/wnaf.cc.inc" #include "ecdh/ecdh.cc.inc" #include "ecdsa/ecdsa.cc.inc" +#include "entropy/jitter.cc.inc" #include "hkdf/hkdf.cc.inc" #include "hmac/hmac.cc.inc" #include "keccak/keccak.cc.inc" @@ -172,8 +173,8 @@ static void BORINGSSL_maybe_set_module_text_permissions(int permission) {} #endif // !ASAN -static void __attribute__((constructor)) -BORINGSSL_bcm_power_on_self_test(void) { +static void __attribute__((constructor)) BORINGSSL_bcm_power_on_self_test( + void) { #if !defined(OPENSSL_ASAN) // Integrity tests cannot run under ASAN because it involves reading the full // .text section, which triggers the global-buffer overflow detection. diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/bcm_interface.h b/Sources/CCryptoBoringSSL/crypto/fipsmodule/bcm_interface.h index d746fd8b7..14d64cb8c 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/bcm_interface.h +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/bcm_interface.h @@ -529,6 +529,140 @@ OPENSSL_EXPORT bcm_status BCM_mldsa87_verify_internal( OPENSSL_EXPORT bcm_status BCM_mldsa87_marshal_private_key( CBB *out, const struct BCM_mldsa87_private_key *private_key); +// BCM_MLDSA44_PRIVATE_KEY_BYTES is the number of bytes in an encoded ML-DSA-44 +// private key. +#define BCM_MLDSA44_PRIVATE_KEY_BYTES 2560 + +// BCM_MLDSA44_PUBLIC_KEY_BYTES is the number of bytes in an encoded ML-DSA-44 +// public key. +#define BCM_MLDSA44_PUBLIC_KEY_BYTES 1312 + +// BCM_MLDSA44_SIGNATURE_BYTES is the number of bytes in an encoded ML-DSA-44 +// signature. +#define BCM_MLDSA44_SIGNATURE_BYTES 2420 + +struct BCM_mldsa44_private_key { + union { + uint8_t bytes[32 + 32 + 64 + 256 * 4 * (4 + 4 + 4)]; + uint32_t alignment; + } opaque; +}; + +struct BCM_mldsa44_public_key { + union { + uint8_t bytes[32 + 64 + 256 * 4 * 4]; + uint32_t alignment; + } opaque; +}; + +struct BCM_mldsa44_prehash { + union { + uint8_t bytes[200 + 4 + 4 + 4 * sizeof(size_t)]; + uint64_t alignment; + } opaque; +}; + +OPENSSL_EXPORT bcm_status BCM_mldsa44_generate_key( + uint8_t out_encoded_public_key[BCM_MLDSA44_PUBLIC_KEY_BYTES], + uint8_t out_seed[BCM_MLDSA_SEED_BYTES], + struct BCM_mldsa44_private_key *out_private_key); + +OPENSSL_EXPORT bcm_status BCM_mldsa44_private_key_from_seed( + struct BCM_mldsa44_private_key *out_private_key, + const uint8_t seed[BCM_MLDSA_SEED_BYTES]); + +OPENSSL_EXPORT bcm_status BCM_mldsa44_public_from_private( + struct BCM_mldsa44_public_key *out_public_key, + const struct BCM_mldsa44_private_key *private_key); + +OPENSSL_EXPORT bcm_status +BCM_mldsa44_check_key_fips(struct BCM_mldsa44_private_key *private_key); + +OPENSSL_EXPORT bcm_status BCM_mldsa44_generate_key_fips( + uint8_t out_encoded_public_key[BCM_MLDSA44_PUBLIC_KEY_BYTES], + uint8_t out_seed[BCM_MLDSA_SEED_BYTES], + struct BCM_mldsa44_private_key *out_private_key); + +OPENSSL_EXPORT bcm_status BCM_mldsa44_private_key_from_seed_fips( + struct BCM_mldsa44_private_key *out_private_key, + const uint8_t seed[BCM_MLDSA_SEED_BYTES]); + +OPENSSL_EXPORT bcm_status BCM_mldsa44_sign( + uint8_t out_encoded_signature[BCM_MLDSA44_SIGNATURE_BYTES], + const struct BCM_mldsa44_private_key *private_key, const uint8_t *msg, + size_t msg_len, const uint8_t *context, size_t context_len); + +OPENSSL_EXPORT bcm_status +BCM_mldsa44_verify(const struct BCM_mldsa44_public_key *public_key, + const uint8_t *signature, const uint8_t *msg, size_t msg_len, + const uint8_t *context, size_t context_len); + +OPENSSL_EXPORT void BCM_mldsa44_prehash_init( + struct BCM_mldsa44_prehash *out_prehash_ctx, + const struct BCM_mldsa44_public_key *public_key, const uint8_t *context, + size_t context_len); + +OPENSSL_EXPORT void BCM_mldsa44_prehash_update( + struct BCM_mldsa44_prehash *inout_prehash_ctx, const uint8_t *msg, + size_t msg_len); + +OPENSSL_EXPORT void BCM_mldsa44_prehash_finalize( + uint8_t out_msg_rep[BCM_MLDSA_MU_BYTES], + struct BCM_mldsa44_prehash *inout_prehash_ctx); + +OPENSSL_EXPORT bcm_status BCM_mldsa44_sign_message_representative( + uint8_t out_encoded_signature[BCM_MLDSA44_SIGNATURE_BYTES], + const struct BCM_mldsa44_private_key *private_key, + const uint8_t msg_rep[BCM_MLDSA_MU_BYTES]); + +OPENSSL_EXPORT bcm_status BCM_mldsa44_marshal_public_key( + CBB *out, const struct BCM_mldsa44_public_key *public_key); + +OPENSSL_EXPORT bcm_status BCM_mldsa44_parse_public_key( + struct BCM_mldsa44_public_key *public_key, CBS *in); + +OPENSSL_EXPORT bcm_status BCM_mldsa44_parse_private_key( + struct BCM_mldsa44_private_key *private_key, CBS *in); + +// BCM_mldsa44_generate_key_external_entropy generates a public/private key pair +// using the given seed, writes the encoded public key to +// |out_encoded_public_key| and sets |out_private_key| to the private key. +OPENSSL_EXPORT bcm_status BCM_mldsa44_generate_key_external_entropy( + uint8_t out_encoded_public_key[BCM_MLDSA44_PUBLIC_KEY_BYTES], + struct BCM_mldsa44_private_key *out_private_key, + const uint8_t entropy[BCM_MLDSA_SEED_BYTES]); + +OPENSSL_EXPORT bcm_status BCM_mldsa44_generate_key_external_entropy_fips( + uint8_t out_encoded_public_key[BCM_MLDSA44_PUBLIC_KEY_BYTES], + struct BCM_mldsa44_private_key *out_private_key, + const uint8_t entropy[BCM_MLDSA_SEED_BYTES]); + +// BCM_mldsa44_sign_internal signs |msg| using |private_key| and writes the +// signature to |out_encoded_signature|. The |context_prefix| and |context| are +// prefixed to the message, in that order, before signing. The |randomizer| +// value can be set to zero bytes in order to make a deterministic signature, or +// else filled with entropy for the usual |MLDSA_sign| behavior. +OPENSSL_EXPORT bcm_status BCM_mldsa44_sign_internal( + uint8_t out_encoded_signature[BCM_MLDSA44_SIGNATURE_BYTES], + const struct BCM_mldsa44_private_key *private_key, const uint8_t *msg, + size_t msg_len, const uint8_t *context_prefix, size_t context_prefix_len, + const uint8_t *context, size_t context_len, + const uint8_t randomizer[BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES]); + +// BCM_mldsa44_verify_internal verifies that |encoded_signature| is a valid +// signature of |msg| by |public_key|. The |context_prefix| and |context| are +// prefixed to the message before verification, in that order. +OPENSSL_EXPORT bcm_status BCM_mldsa44_verify_internal( + const struct BCM_mldsa44_public_key *public_key, + const uint8_t encoded_signature[BCM_MLDSA44_SIGNATURE_BYTES], + const uint8_t *msg, size_t msg_len, const uint8_t *context_prefix, + size_t context_prefix_len, const uint8_t *context, size_t context_len); + +// BCM_mldsa44_marshal_private_key serializes |private_key| to |out| in the +// NIST format for ML-DSA-44 private keys. +OPENSSL_EXPORT bcm_status BCM_mldsa44_marshal_private_key( + CBB *out, const struct BCM_mldsa44_private_key *private_key); + // ML-KEM // diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/exponentiation.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/exponentiation.cc.inc index ffcea64b6..3206708c0 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/exponentiation.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/exponentiation.cc.inc @@ -560,9 +560,9 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, // |bn_mul_mont_gather5| and |bn_power5| implement the "almost" reduction // variant, so the values here may not be fully reduced. They are bounded by R // (i.e. they fit in |top| words), not |m|. Additionally, we pass these - // "almost" reduced inputs into |bn_mul_mont|, which implements the normal - // reduction variant. Given those inputs, |bn_mul_mont| may not give reduced - // output, but it will still produce "almost" reduced output. + // "almost" reduced inputs into |bn_mul_mont_words|, which implements the + // normal reduction variant. Given those inputs, |bn_mul_mont_words| may not + // give reduced output, but it will still produce "almost" reduced output. // // TODO(davidben): Using "almost" reduction complicates analysis of this code, // and its interaction with other parts of the project. Determine whether this @@ -578,12 +578,12 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, const BN_ULONG *n0 = mont->n0; bn_scatter5(tmp.d, top, powerbuf, 0); bn_scatter5(am.d, am.width, powerbuf, 1); - bn_mul_mont(tmp.d, am.d, am.d, np, n0, top); + bn_mul_mont_words(tmp.d, am.d, am.d, np, n0, top); bn_scatter5(tmp.d, top, powerbuf, 2); // Square to compute powers of two. for (i = 4; i < 32; i *= 2) { - bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont_words(tmp.d, tmp.d, tmp.d, np, n0, top); bn_scatter5(tmp.d, top, powerbuf, i); } // Compute odd powers |i| based on |i - 1|, then all powers |i * 2^j|. @@ -591,7 +591,7 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1); bn_scatter5(tmp.d, top, powerbuf, i); for (int j = 2 * i; j < 32; j *= 2) { - bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont_words(tmp.d, tmp.d, tmp.d, np, n0, top); bn_scatter5(tmp.d, top, powerbuf, j); } } @@ -614,11 +614,11 @@ int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); } - bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); - bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); - bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); - bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); - bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont_words(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont_words(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont_words(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont_words(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont_words(tmp.d, tmp.d, tmp.d, np, n0, top); bn_mul_mont_gather5(tmp.d, tmp.d, powerbuf, np, n0, top, wvalue); } } else { diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/generic.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/generic.cc.inc index 54d22f65f..90ee6acb1 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/generic.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/generic.cc.inc @@ -44,24 +44,24 @@ do { \ BN_ULLONG t; \ t = (BN_ULLONG)(w) * (a) + (r) + (c); \ - (r) = Lw(t); \ - (c) = Hw(t); \ + (r) = (BN_ULONG)(t); \ + (c) = (BN_ULONG)((t) >> BN_BITS2); \ } while (0) -#define mul(r, a, w, c) \ - do { \ - BN_ULLONG t; \ - t = (BN_ULLONG)(w) * (a) + (c); \ - (r) = Lw(t); \ - (c) = Hw(t); \ +#define mul(r, a, w, c) \ + do { \ + BN_ULLONG t; \ + t = (BN_ULLONG)(w) * (a) + (c); \ + (r) = (BN_ULONG)(t); \ + (c) = (BN_ULONG)((t) >> BN_BITS2); \ } while (0) -#define sqr(r0, r1, a) \ - do { \ - BN_ULLONG t; \ - t = (BN_ULLONG)(a) * (a); \ - (r0) = Lw(t); \ - (r1) = Hw(t); \ +#define sqr(r0, r1, a) \ + do { \ + BN_ULLONG t; \ + t = (BN_ULLONG)(a) * (a); \ + (r0) = (BN_ULONG)(t); \ + (r1) = (BN_ULONG)((t) >> BN_BITS2); \ } while (0) #else @@ -198,8 +198,8 @@ void bn_sqr_add_words(BN_ULONG *r, const BN_ULONG *a, size_t n) { BN_ULONG hi; \ BN_ULLONG t = (BN_ULLONG)(a) * (b); \ t += (c0); /* no carry */ \ - (c0) = (BN_ULONG)Lw(t); \ - hi = (BN_ULONG)Hw(t); \ + (c0) = (BN_ULONG)(t); \ + hi = (BN_ULONG)((t) >> BN_BITS2); \ (c1) += (hi); \ (c2) += (c1) < hi; \ } while (0) @@ -209,13 +209,13 @@ void bn_sqr_add_words(BN_ULONG *r, const BN_ULONG *a, size_t n) { BN_ULONG hi; \ BN_ULLONG t = (BN_ULLONG)(a) * (b); \ BN_ULLONG tt = t + (c0); /* no carry */ \ - (c0) = (BN_ULONG)Lw(tt); \ - hi = (BN_ULONG)Hw(tt); \ + (c0) = (BN_ULONG)(tt); \ + hi = (BN_ULONG)((tt) >> BN_BITS2); \ (c1) += hi; \ (c2) += (c1) < hi; \ t += (c0); /* no carry */ \ - (c0) = (BN_ULONG)Lw(t); \ - hi = (BN_ULONG)Hw(t); \ + (c0) = (BN_ULONG)(t); \ + hi = (BN_ULONG)((t) >> BN_BITS2); \ (c1) += hi; \ (c2) += (c1) < hi; \ } while (0) @@ -225,8 +225,8 @@ void bn_sqr_add_words(BN_ULONG *r, const BN_ULONG *a, size_t n) { BN_ULONG hi; \ BN_ULLONG t = (BN_ULLONG)(a)[i] * (a)[i]; \ t += (c0); /* no carry */ \ - (c0) = (BN_ULONG)Lw(t); \ - hi = (BN_ULONG)Hw(t); \ + (c0) = (BN_ULONG)(t); \ + hi = (BN_ULONG)((t) >> BN_BITS2); \ (c1) += hi; \ (c2) += (c1) < hi; \ } while (0) diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/internal.h b/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/internal.h index 289f86f53..a68a7d1af 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/internal.h +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/internal.h @@ -105,11 +105,6 @@ extern "C" { sizeof(x) / sizeof(BN_ULONG), 0, BN_FLG_STATIC_DATA \ } -#if defined(BN_ULLONG) -#define Lw(t) ((BN_ULONG)(t)) -#define Hw(t) ((BN_ULONG)((t) >> BN_BITS2)) -#endif - // bn_minimal_width returns the minimal number of words needed to represent // |bn|. int bn_minimal_width(const BIGNUM *bn); @@ -268,16 +263,27 @@ int bn_rand_secret_range(BIGNUM *r, int *out_is_uniform, BN_ULONG min_inclusive, // |BIGNUM|s, in |bn_wexpand|, but the exactfloat library needs to create 8 MiB // values for other operations. // -// TODO(crbug.com/402677800): This is not quite tight enough to limit the -// |bn_mul_mont| allocation to under a page. Lower the maximum RSA key and then -// lower this to match. -#define BN_MONTGOMERY_MAX_WORDS (16384 / BN_BITS2) +// This limit is set so that one number fits within 1 KiB, giving room to +// allocate a few of them on the stack in |bn_mul_mont_words| without exceeding +// a page (4 KiB). It is also set to limit the DoS impact of large RSA, DH, and +// DSA keys, which scale cubically. +#define BN_MONTGOMERY_MAX_WORDS (8192 / BN_BITS2) + +struct bn_mont_ctx_st { + // RR is R^2, reduced modulo |N|. It is used to convert to Montgomery form. It + // is guaranteed to have the same width as |N|. + BIGNUM RR; + // N is the modulus. It is always stored in minimal form, so |N.width| + // determines R. + BIGNUM N; + BN_ULONG n0[BN_MONT_CTX_N0_LIMBS]; // least significant words of (R*Ri-1)/N +}; #if !defined(OPENSSL_NO_ASM) && \ (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \ defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) #define OPENSSL_BN_ASM_MONT -// bn_mul_mont writes |ap| * |bp| mod |np| to |rp|, each |num| words +// bn_mul_mont_words writes |ap| * |bp| mod |np| to |rp|, each |num| words // long. Inputs and outputs are in Montgomery form. |n0| is a pointer to the // corresponding field in |BN_MONT_CTX|. // @@ -295,8 +301,9 @@ int bn_rand_secret_range(BIGNUM *r, int *out_is_uniform, BN_ULONG min_inclusive, // // See also discussion in |ToWord| in abi_test.h for notes on smaller-than-word // inputs. -void bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, - const BN_ULONG *np, const BN_ULONG *n0, size_t num); +void bn_mul_mont_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, + const BN_ULONG n0[BN_MONT_CTX_N0_LIMBS], size_t num); #if defined(OPENSSL_X86_64) inline int bn_mulx_adx_capable(void) { @@ -304,30 +311,36 @@ inline int bn_mulx_adx_capable(void) { return CRYPTO_is_BMI2_capable() && CRYPTO_is_ADX_capable(); } void bn_mul_mont_nohw(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, - const BN_ULONG *np, const BN_ULONG *n0, size_t num); + const BN_ULONG *np, + const BN_ULONG n0[BN_MONT_CTX_N0_LIMBS], size_t num); inline int bn_mul4x_mont_capable(size_t num) { return num >= 8 && (num & 3) == 0; } void bn_mul4x_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, - const BN_ULONG *np, const BN_ULONG *n0, size_t num); + const BN_ULONG *np, const BN_ULONG n0[BN_MONT_CTX_N0_LIMBS], + size_t num); inline int bn_mulx4x_mont_capable(size_t num) { return bn_mul4x_mont_capable(num) && bn_mulx_adx_capable(); } void bn_mulx4x_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, - const BN_ULONG *np, const BN_ULONG *n0, size_t num); + const BN_ULONG *np, const BN_ULONG n0[BN_MONT_CTX_N0_LIMBS], + size_t num); inline int bn_sqr8x_mont_capable(size_t num) { return num >= 8 && (num & 7) == 0; } void bn_sqr8x_mont(BN_ULONG *rp, const BN_ULONG *ap, BN_ULONG mulx_adx_capable, - const BN_ULONG *np, const BN_ULONG *n0, size_t num); + const BN_ULONG *np, const BN_ULONG n0[BN_MONT_CTX_N0_LIMBS], + size_t num); #elif defined(OPENSSL_ARM) inline int bn_mul8x_mont_neon_capable(size_t num) { return (num & 7) == 0 && CRYPTO_is_NEON_capable(); } void bn_mul8x_mont_neon(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, - const BN_ULONG *np, const BN_ULONG *n0, size_t num); + const BN_ULONG *np, + const BN_ULONG n0[BN_MONT_CTX_N0_LIMBS], size_t num); void bn_mul_mont_nohw(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, - const BN_ULONG *np, const BN_ULONG *n0, size_t num); + const BN_ULONG *np, + const BN_ULONG n0[BN_MONT_CTX_N0_LIMBS], size_t num); #endif #endif // OPENSSL_BN_ASM_MONT @@ -340,7 +353,8 @@ void bn_mul_mont_nohw(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, inline int bn_mul4x_mont_gather5_capable(int num) { return (num & 7) == 0; } void bn_mul4x_mont_gather5(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *table, const BN_ULONG *np, - const BN_ULONG *n0, int num, int power); + const BN_ULONG n0[BN_MONT_CTX_N0_LIMBS], int num, + int power); inline int bn_mulx4x_mont_gather5_capable(int num) { return bn_mul4x_mont_gather5_capable(num) && CRYPTO_is_ADX_capable() && @@ -348,11 +362,13 @@ inline int bn_mulx4x_mont_gather5_capable(int num) { } void bn_mulx4x_mont_gather5(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *table, const BN_ULONG *np, - const BN_ULONG *n0, int num, int power); + const BN_ULONG n0[BN_MONT_CTX_N0_LIMBS], int num, + int power); void bn_mul_mont_gather5_nohw(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *table, const BN_ULONG *np, - const BN_ULONG *n0, int num, int power); + const BN_ULONG n0[BN_MONT_CTX_N0_LIMBS], int num, + int power); // bn_scatter5 stores |inp| to index |power| of |table|. |inp| and each entry of // |table| are |num| words long. |power| must be less than 32 and is treated as @@ -368,7 +384,8 @@ void bn_gather5(BN_ULONG *out, size_t num, const BN_ULONG *table, size_t power); // The following functions implement |bn_power5|. See |bn_power5| for details. void bn_power5_nohw(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *table, - const BN_ULONG *np, const BN_ULONG *n0, int num, int power); + const BN_ULONG *np, const BN_ULONG n0[BN_MONT_CTX_N0_LIMBS], + int num, int power); inline int bn_power5_capable(int num) { return (num & 7) == 0; } @@ -377,7 +394,8 @@ inline int bn_powerx5_capable(int num) { CRYPTO_is_BMI1_capable() && CRYPTO_is_BMI2_capable(); } void bn_powerx5(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *table, - const BN_ULONG *np, const BN_ULONG *n0, int num, int power); + const BN_ULONG *np, const BN_ULONG n0[BN_MONT_CTX_N0_LIMBS], + int num, int power); #endif // !OPENSSL_NO_ASM && OPENSSL_X86_64 diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/montgomery.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/montgomery.cc.inc index 2746c060f..120ee218e 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/montgomery.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/montgomery.cc.inc @@ -64,8 +64,9 @@ BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, const BN_MONT_CTX *from) { if (!BN_copy(&to->RR, &from->RR) || !BN_copy(&to->N, &from->N)) { return NULL; } - to->n0[0] = from->n0[0]; - to->n0[1] = from->n0[1]; + for (size_t i = 0; i < BN_MONT_CTX_N0_LIMBS; i++) { + to->n0[i] = from->n0[i]; + } return to; } @@ -111,8 +112,6 @@ static int bn_mont_ctx_set_N_and_n0(BN_MONT_CTX *mont, const BIGNUM *mod) { mont->n0[0] = (BN_ULONG)n0; #if BN_MONT_CTX_N0_LIMBS == 2 mont->n0[1] = (BN_ULONG)(n0 >> BN_BITS2); -#else - mont->n0[1] = 0; #endif return 1; } @@ -309,16 +308,16 @@ int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, } #if defined(OPENSSL_BN_ASM_MONT) - // |bn_mul_mont| requires at least 128 bits of limbs. + // |bn_mul_mont_words| requires at least 128 bits of limbs. int num = mont->N.width; if (num >= (128 / BN_BITS2) && a->width == num && b->width == num) { if (!bn_wexpand(r, num)) { return 0; } - // This bound is implied by |bn_mont_ctx_set_N_and_n0|. |bn_mul_mont| + // This bound is implied by |bn_mont_ctx_set_N_and_n0|. |bn_mul_mont_words| // allocates |num| words on the stack, so |num| cannot be too large. assert((size_t)num <= BN_MONTGOMERY_MAX_WORDS); - bn_mul_mont(r->d, a->d, b->d, mont->N.d, mont->n0, num); + bn_mul_mont_words(r->d, a->d, b->d, mont->N.d, mont->n0, num); r->neg = 0; r->width = num; return 1; @@ -359,9 +358,9 @@ void bn_mod_mul_montgomery_small(BN_ULONG *r, const BN_ULONG *a, } #if defined(OPENSSL_BN_ASM_MONT) - // |bn_mul_mont| requires at least 128 bits of limbs. + // |bn_mul_mont_words| requires at least 128 bits of limbs. if (num >= (128 / BN_BITS2)) { - bn_mul_mont(r, a, b, mont->N.d, mont->n0, num); + bn_mul_mont_words(r, a, b, mont->N.d, mont->n0, num); return; } #endif @@ -382,8 +381,8 @@ void bn_mod_mul_montgomery_small(BN_ULONG *r, const BN_ULONG *a, } #if defined(OPENSSL_BN_ASM_MONT) && defined(OPENSSL_X86_64) -void bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, - const BN_ULONG *np, const BN_ULONG *n0, size_t num) { +void bn_mul_mont_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, const BN_ULONG *n0, size_t num) { if (ap == bp && bn_sqr8x_mont_capable(num)) { bn_sqr8x_mont(rp, ap, bn_mulx_adx_capable(), np, n0, num); } else if (bn_mulx4x_mont_capable(num)) { @@ -397,8 +396,8 @@ void bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, #endif #if defined(OPENSSL_BN_ASM_MONT) && defined(OPENSSL_ARM) -void bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, - const BN_ULONG *np, const BN_ULONG *n0, size_t num) { +void bn_mul_mont_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, const BN_ULONG *n0, size_t num) { if (bn_mul8x_mont_neon_capable(num)) { bn_mul8x_mont_neon(rp, ap, bp, np, n0, num); } else { diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/prime.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/prime.cc.inc index 4c8d440c9..1ba28018c 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/prime.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/bn/prime.cc.inc @@ -14,6 +14,8 @@ #include +#include + #include #include @@ -193,9 +195,9 @@ static int BN_prime_checks_for_size(int bits) { // of excluding a candidate with trial division is larger. static size_t num_trial_division_primes(const BIGNUM *n) { if (n->width * BN_BITS2 > 1024) { - return OPENSSL_ARRAY_SIZE(kPrimes); + return std::size(kPrimes); } - return OPENSSL_ARRAY_SIZE(kPrimes) / 2; + return std::size(kPrimes) / 2; } // BN_PRIME_CHECKS_BLINDED is the iteration count for blinding the constant-time diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/dh/dh.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/dh/dh.cc.inc index b7a883548..05ede8e07 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/dh/dh.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/dh/dh.cc.inc @@ -16,6 +16,8 @@ #include +#include + #include #include #include @@ -406,7 +408,7 @@ DH *DH_get_rfc7919_2048(void) { } bn_set_static_words(ffdhe2048_p.get(), kFFDHE2048Data, - OPENSSL_ARRAY_SIZE(kFFDHE2048Data)); + std::size(kFFDHE2048Data)); if (!BN_rshift1(ffdhe2048_q.get(), ffdhe2048_p.get()) || !BN_set_word(ffdhe2048_g.get(), 2) || diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/digest/digest.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/digest/digest.cc.inc index 622efd3f5..99c75b803 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/digest/digest.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/digest/digest.cc.inc @@ -36,7 +36,9 @@ size_t EVP_MD_block_size(const EVP_MD *md) { return md->block_size; } void EVP_MD_CTX_init(EVP_MD_CTX *ctx) { - OPENSSL_memset(ctx, 0, sizeof(EVP_MD_CTX)); + ctx->digest = nullptr; + ctx->pctx = nullptr; + ctx->pctx_ops = nullptr; } EVP_MD_CTX *EVP_MD_CTX_new(void) { @@ -53,8 +55,6 @@ EVP_MD_CTX *EVP_MD_CTX_new(void) { EVP_MD_CTX *EVP_MD_CTX_create(void) { return EVP_MD_CTX_new(); } int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) { - OPENSSL_free(ctx->md_data); - assert(ctx->pctx == NULL || ctx->pctx_ops != NULL); if (ctx->pctx_ops) { ctx->pctx_ops->free(ctx->pctx); @@ -66,7 +66,7 @@ int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) { } void EVP_MD_CTX_cleanse(EVP_MD_CTX *ctx) { - OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size); + OPENSSL_cleanse(ctx->md_data, sizeof(ctx->md_data)); EVP_MD_CTX_cleanup(ctx); } @@ -97,6 +97,10 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) { OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_INPUT_NOT_INITIALIZED); return 0; } + if (out == in) { + OPENSSL_PUT_ERROR(DIGEST, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } EVP_PKEY_CTX *pctx = NULL; assert(in->pctx == NULL || in->pctx_ops != NULL); @@ -107,31 +111,9 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) { } } - uint8_t *tmp_buf = NULL; - if (in->digest != NULL) { - if (out->digest != in->digest) { - assert(in->digest->ctx_size != 0); - tmp_buf = - reinterpret_cast(OPENSSL_malloc(in->digest->ctx_size)); - if (tmp_buf == NULL) { - if (pctx) { - in->pctx_ops->free(pctx); - } - return 0; - } - } else { - // |md_data| will be the correct size in this case. It's removed from - // |out| so that |EVP_MD_CTX_cleanup| doesn't free it, and then it's - // reused. - tmp_buf = reinterpret_cast(out->md_data); - out->md_data = NULL; - } - } - EVP_MD_CTX_cleanup(out); out->digest = in->digest; - out->md_data = tmp_buf; if (in->digest != NULL) { OPENSSL_memcpy(out->md_data, in->md_data, in->digest->ctx_size); } @@ -167,14 +149,7 @@ int EVP_MD_CTX_reset(EVP_MD_CTX *ctx) { int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *engine) { if (ctx->digest != type) { assert(type->ctx_size != 0); - uint8_t *md_data = - reinterpret_cast(OPENSSL_malloc(type->ctx_size)); - if (md_data == NULL) { - return 0; - } - - OPENSSL_free(ctx->md_data); - ctx->md_data = md_data; + assert(type->ctx_size <= sizeof(ctx->md_data)); ctx->digest = type; } diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/digest/digests.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/digest/digests.cc.inc index 98bd7726f..40cc2263f 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/digest/digests.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/digest/digests.cc.inc @@ -54,6 +54,8 @@ DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha1) { out->ctx_size = sizeof(SHA_CTX); } +static_assert(sizeof(SHA_CTX) <= EVP_MAX_MD_DATA_SIZE); + static void sha224_init(EVP_MD_CTX *ctx) { BCM_sha224_init(reinterpret_cast(ctx->md_data)); @@ -78,6 +80,7 @@ DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha224) { out->ctx_size = sizeof(SHA256_CTX); } +static_assert(sizeof(SHA256_CTX) <= EVP_MAX_MD_DATA_SIZE); static void sha256_init(EVP_MD_CTX *ctx) { BCM_sha256_init(reinterpret_cast(ctx->md_data)); @@ -126,6 +129,7 @@ DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha384) { out->ctx_size = sizeof(SHA512_CTX); } +static_assert(sizeof(SHA512_CTX) <= EVP_MAX_MD_DATA_SIZE); static void sha512_init(EVP_MD_CTX *ctx) { BCM_sha512_init(reinterpret_cast(ctx->md_data)); diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/ec.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/ec.cc.inc index 4b5ff980c..aa3cb4309 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/ec.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/ec.cc.inc @@ -18,6 +18,8 @@ #include #include +#include + #include #include #include @@ -64,10 +66,10 @@ DEFINE_METHOD_FUNCTION(EC_GROUP, EC_group_p224) { OPENSSL_memcpy(out->oid, kOIDP224, sizeof(kOIDP224)); out->oid_len = sizeof(kOIDP224); - ec_group_init_static_mont(&out->field, OPENSSL_ARRAY_SIZE(kP224Field), - kP224Field, kP224FieldRR, kP224FieldN0); - ec_group_init_static_mont(&out->order, OPENSSL_ARRAY_SIZE(kP224Order), - kP224Order, kP224OrderRR, kP224OrderN0); + ec_group_init_static_mont(&out->field, std::size(kP224Field), kP224Field, + kP224FieldRR, kP224FieldN0); + ec_group_init_static_mont(&out->order, std::size(kP224Order), kP224Order, + kP224OrderRR, kP224OrderN0); #if defined(BORINGSSL_HAS_UINT128) && !defined(OPENSSL_SMALL) out->meth = EC_GFp_nistp224_method(); @@ -98,10 +100,10 @@ DEFINE_METHOD_FUNCTION(EC_GROUP, EC_group_p256) { OPENSSL_memcpy(out->oid, kOIDP256, sizeof(kOIDP256)); out->oid_len = sizeof(kOIDP256); - ec_group_init_static_mont(&out->field, OPENSSL_ARRAY_SIZE(kP256Field), - kP256Field, kP256FieldRR, kP256FieldN0); - ec_group_init_static_mont(&out->order, OPENSSL_ARRAY_SIZE(kP256Order), - kP256Order, kP256OrderRR, kP256OrderN0); + ec_group_init_static_mont(&out->field, std::size(kP256Field), kP256Field, + kP256FieldRR, kP256FieldN0); + ec_group_init_static_mont(&out->order, std::size(kP256Order), kP256Order, + kP256OrderRR, kP256OrderN0); #if !defined(OPENSSL_NO_ASM) && \ (defined(OPENSSL_X86_64) || defined(OPENSSL_AARCH64)) && \ @@ -129,10 +131,10 @@ DEFINE_METHOD_FUNCTION(EC_GROUP, EC_group_p384) { OPENSSL_memcpy(out->oid, kOIDP384, sizeof(kOIDP384)); out->oid_len = sizeof(kOIDP384); - ec_group_init_static_mont(&out->field, OPENSSL_ARRAY_SIZE(kP384Field), - kP384Field, kP384FieldRR, kP384FieldN0); - ec_group_init_static_mont(&out->order, OPENSSL_ARRAY_SIZE(kP384Order), - kP384Order, kP384OrderRR, kP384OrderN0); + ec_group_init_static_mont(&out->field, std::size(kP384Field), kP384Field, + kP384FieldRR, kP384FieldN0); + ec_group_init_static_mont(&out->order, std::size(kP384Order), kP384Order, + kP384OrderRR, kP384OrderN0); out->meth = EC_GFp_mont_method(); out->generator.group = out; @@ -154,10 +156,10 @@ DEFINE_METHOD_FUNCTION(EC_GROUP, EC_group_p521) { OPENSSL_memcpy(out->oid, kOIDP521, sizeof(kOIDP521)); out->oid_len = sizeof(kOIDP521); - ec_group_init_static_mont(&out->field, OPENSSL_ARRAY_SIZE(kP521Field), - kP521Field, kP521FieldRR, kP521FieldN0); - ec_group_init_static_mont(&out->order, OPENSSL_ARRAY_SIZE(kP521Order), - kP521Order, kP521OrderRR, kP521OrderN0); + ec_group_init_static_mont(&out->field, std::size(kP521Field), kP521Field, + kP521FieldRR, kP521FieldN0); + ec_group_init_static_mont(&out->order, std::size(kP521Order), kP521Order, + kP521OrderRR, kP521OrderN0); out->meth = EC_GFp_mont_method(); out->generator.group = out; @@ -870,7 +872,7 @@ void ec_precomp_select(const EC_GROUP *group, EC_PRECOMP *out, BN_ULONG mask, const EC_PRECOMP *a, const EC_PRECOMP *b) { static_assert(sizeof(out->comb) == sizeof(*out), "out->comb does not span the entire structure"); - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(out->comb); i++) { + for (size_t i = 0; i < std::size(out->comb); i++) { ec_affine_select(group, &out->comb[i], mask, &a->comb[i], &b->comb[i]); } } diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/oct.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/oct.cc.inc index 8bb562055..27b46ec76 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/oct.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/oct.cc.inc @@ -262,9 +262,7 @@ int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, } if (!BN_mod_sqrt(y, tmp1, field, ctx)) { - uint32_t err = ERR_peek_last_error(); - if (ERR_GET_LIB(err) == ERR_LIB_BN && - ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) { + if (ERR_equals(ERR_peek_last_error(), ERR_LIB_BN, BN_R_NOT_A_SQUARE)) { ERR_clear_error(); OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COMPRESSED_POINT); } else { diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/p256-nistz.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/p256-nistz.cc.inc index 9b1ffc44a..5a29419e6 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/p256-nistz.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/p256-nistz.cc.inc @@ -651,9 +651,9 @@ static void ecp_nistz256_inv0_mod_ord(const EC_GROUP *group, EC_SCALAR *out, {4, i_111}, {5, i_111}, {5, i_101}, {3, i_11}, {10, i_101111}, {2, i_11}, {5, i_11}, {5, i_11}, {3, i_1}, {7, i_10101}, {6, i_1111}}; - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kChain); i++) { - ecp_nistz256_ord_sqr_mont(out->words, out->words, kChain[i].p); - ecp_nistz256_ord_mul_mont(out->words, out->words, table[kChain[i].i]); + for (const auto &step : kChain) { + ecp_nistz256_ord_sqr_mont(out->words, out->words, step.p); + ecp_nistz256_ord_mul_mont(out->words, out->words, table[step.i]); } } diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/p256.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/p256.cc.inc index 71a6fe18d..cdbff6268 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/p256.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/p256.cc.inc @@ -26,18 +26,14 @@ #include #include +#include + #include "../../internal.h" #include "../delocate.h" #include "./internal.h" -#if defined(BORINGSSL_HAS_UINT128) -#include "../../../third_party/fiat/p256_64.h" -#elif defined(OPENSSL_64_BIT) -#include "../../../third_party/fiat/p256_64_msvc.h" -#else -#include "../../../third_party/fiat/p256_32.h" -#endif - +#include "../../../third_party/fiat/p256_field.c.inc" +#include "../../../third_party/fiat/p256_point.br.c.inc" // utility functions, handwritten @@ -56,13 +52,6 @@ static const fiat_p256_felem fiat_p256_one = { #endif // 64BIT -static fiat_p256_limb_t fiat_p256_nz( - const fiat_p256_limb_t in1[FIAT_P256_NLIMBS]) { - fiat_p256_limb_t ret; - fiat_p256_nonzero(&ret, in1); - return ret; -} - static void fiat_p256_copy(fiat_p256_limb_t out[FIAT_P256_NLIMBS], const fiat_p256_limb_t in1[FIAT_P256_NLIMBS]) { for (size_t i = 0; i < FIAT_P256_NLIMBS; i++) { @@ -172,198 +161,44 @@ static void fiat_p256_inv_square(fiat_p256_felem out, // Building on top of the field operations we have the operations on the // elliptic curve group itself. Points on the curve are represented in Jacobian // coordinates. -// -// Both operations were transcribed to Coq and proven to correspond to naive -// implementations using Affine coordinates, for all suitable fields. In the -// Coq proofs, issues of constant-time execution and memory layout (aliasing) -// conventions were not considered. Specification of affine coordinates: -// -// As a sanity check, a proof that these points form a commutative group: -// - -// fiat_p256_point_double calculates 2*(x_in, y_in, z_in) -// -// The method is taken from: -// http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b -// -// Coq transcription and correctness proof: -// -// -// -// Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed. -// while x_out == y_in is not (maybe this works, but it's not tested). + static void fiat_p256_point_double(fiat_p256_felem x_out, fiat_p256_felem y_out, fiat_p256_felem z_out, const fiat_p256_felem x_in, const fiat_p256_felem y_in, const fiat_p256_felem z_in) { - fiat_p256_felem delta, gamma, beta, ftmp, ftmp2, tmptmp, alpha, fourbeta; - // delta = z^2 - fiat_p256_square(delta, z_in); - // gamma = y^2 - fiat_p256_square(gamma, y_in); - // beta = x*gamma - fiat_p256_mul(beta, x_in, gamma); - - // alpha = 3*(x-delta)*(x+delta) - fiat_p256_sub(ftmp, x_in, delta); - fiat_p256_add(ftmp2, x_in, delta); - - fiat_p256_add(tmptmp, ftmp2, ftmp2); - fiat_p256_add(ftmp2, ftmp2, tmptmp); - fiat_p256_mul(alpha, ftmp, ftmp2); - - // x' = alpha^2 - 8*beta - fiat_p256_square(x_out, alpha); - fiat_p256_add(fourbeta, beta, beta); - fiat_p256_add(fourbeta, fourbeta, fourbeta); - fiat_p256_add(tmptmp, fourbeta, fourbeta); - fiat_p256_sub(x_out, x_out, tmptmp); - - // z' = (y + z)^2 - gamma - delta - fiat_p256_add(delta, gamma, delta); - fiat_p256_add(ftmp, y_in, z_in); - fiat_p256_square(z_out, ftmp); - fiat_p256_sub(z_out, z_out, delta); - - // y' = alpha*(4*beta - x') - 8*gamma^2 - fiat_p256_sub(y_out, fourbeta, x_out); - fiat_p256_add(gamma, gamma, gamma); - fiat_p256_square(gamma, gamma); - fiat_p256_mul(y_out, alpha, y_out); - fiat_p256_add(gamma, gamma, gamma); - fiat_p256_sub(y_out, y_out, gamma); + uint8_t out[3*32], in[3*32]; + static_assert(sizeof(fiat_p256_felem) == 32); + OPENSSL_memcpy(&in[0], x_in, 32); + OPENSSL_memcpy(&in[32], y_in, 32); + OPENSSL_memcpy(&in[64], z_in, 32); + p256_point_double((br_word_t)out, (br_word_t)in); + OPENSSL_memcpy(x_out, &out[0], 32); + OPENSSL_memcpy(y_out, &out[32], 32); + OPENSSL_memcpy(z_out, &out[64], 32); } -// fiat_p256_point_add calculates (x1, y1, z1) + (x2, y2, z2) -// -// The method is taken from: -// http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl, -// adapted for mixed addition (z2 = 1, or z2 = 0 for the point at infinity). -// -// Coq transcription and correctness proof: -// -// -// -// This function includes a branch for checking whether the two input points -// are equal, (while not equal to the point at infinity). This case never -// happens during single point multiplication, so there is no timing leak for -// ECDH or ECDSA signing. static void fiat_p256_point_add(fiat_p256_felem x3, fiat_p256_felem y3, fiat_p256_felem z3, const fiat_p256_felem x1, const fiat_p256_felem y1, - const fiat_p256_felem z1, const int mixed, + const fiat_p256_felem z1, const fiat_p256_felem x2, const fiat_p256_felem y2, const fiat_p256_felem z2) { - fiat_p256_felem x_out, y_out, z_out; - fiat_p256_limb_t z1nz = fiat_p256_nz(z1); - fiat_p256_limb_t z2nz = fiat_p256_nz(z2); - - // z1z1 = z1z1 = z1**2 - fiat_p256_felem z1z1; - fiat_p256_square(z1z1, z1); - - fiat_p256_felem u1, s1, two_z1z2; - if (!mixed) { - // z2z2 = z2**2 - fiat_p256_felem z2z2; - fiat_p256_square(z2z2, z2); - - // u1 = x1*z2z2 - fiat_p256_mul(u1, x1, z2z2); - - // two_z1z2 = (z1 + z2)**2 - (z1z1 + z2z2) = 2z1z2 - fiat_p256_add(two_z1z2, z1, z2); - fiat_p256_square(two_z1z2, two_z1z2); - fiat_p256_sub(two_z1z2, two_z1z2, z1z1); - fiat_p256_sub(two_z1z2, two_z1z2, z2z2); - - // s1 = y1 * z2**3 - fiat_p256_mul(s1, z2, z2z2); - fiat_p256_mul(s1, s1, y1); - } else { - // We'll assume z2 = 1 (special case z2 = 0 is handled later). - - // u1 = x1*z2z2 - fiat_p256_copy(u1, x1); - // two_z1z2 = 2z1z2 - fiat_p256_add(two_z1z2, z1, z1); - // s1 = y1 * z2**3 - fiat_p256_copy(s1, y1); - } - - // u2 = x2*z1z1 - fiat_p256_felem u2; - fiat_p256_mul(u2, x2, z1z1); - - // h = u2 - u1 - fiat_p256_felem h; - fiat_p256_sub(h, u2, u1); - - fiat_p256_limb_t xneq = fiat_p256_nz(h); - - // z_out = two_z1z2 * h - fiat_p256_mul(z_out, h, two_z1z2); - - // z1z1z1 = z1 * z1z1 - fiat_p256_felem z1z1z1; - fiat_p256_mul(z1z1z1, z1, z1z1); - - // s2 = y2 * z1**3 - fiat_p256_felem s2; - fiat_p256_mul(s2, y2, z1z1z1); - - // r = (s2 - s1)*2 - fiat_p256_felem r; - fiat_p256_sub(r, s2, s1); - fiat_p256_add(r, r, r); - - fiat_p256_limb_t yneq = fiat_p256_nz(r); - - fiat_p256_limb_t is_nontrivial_double = constant_time_is_zero_w(xneq | yneq) & - ~constant_time_is_zero_w(z1nz) & - ~constant_time_is_zero_w(z2nz); - if (constant_time_declassify_w(is_nontrivial_double)) { - fiat_p256_point_double(x3, y3, z3, x1, y1, z1); - return; - } - - // I = (2h)**2 - fiat_p256_felem i; - fiat_p256_add(i, h, h); - fiat_p256_square(i, i); - - // J = h * I - fiat_p256_felem j; - fiat_p256_mul(j, h, i); - - // V = U1 * I - fiat_p256_felem v; - fiat_p256_mul(v, u1, i); - - // x_out = r**2 - J - 2V - fiat_p256_square(x_out, r); - fiat_p256_sub(x_out, x_out, j); - fiat_p256_sub(x_out, x_out, v); - fiat_p256_sub(x_out, x_out, v); - - // y_out = r(V-x_out) - 2 * s1 * J - fiat_p256_sub(y_out, v, x_out); - fiat_p256_mul(y_out, y_out, r); - fiat_p256_felem s1j; - fiat_p256_mul(s1j, s1, j); - fiat_p256_sub(y_out, y_out, s1j); - fiat_p256_sub(y_out, y_out, s1j); - - fiat_p256_cmovznz(x_out, z1nz, x2, x_out); - fiat_p256_cmovznz(x3, z2nz, x1, x_out); - fiat_p256_cmovznz(y_out, z1nz, y2, y_out); - fiat_p256_cmovznz(y3, z2nz, y1, y_out); - fiat_p256_cmovznz(z_out, z1nz, z2, z_out); - fiat_p256_cmovznz(z3, z2nz, z1, z_out); + uint8_t out[3 * 32], in1[3 * 32], in2[3 * 32]; + static_assert(sizeof(fiat_p256_felem) == 32); + OPENSSL_memcpy(&in1[0], x1, 32); + OPENSSL_memcpy(&in1[32], y1, 32); + OPENSSL_memcpy(&in1[64], z1, 32); + OPENSSL_memcpy(&in2[0], x2, 32); + OPENSSL_memcpy(&in2[32], y2, 32); + OPENSSL_memcpy(&in2[64], z2, 32); + p256_point_add_vartime_if_doubling((br_word_t)out, (br_word_t)in1, + (br_word_t)in2); + OPENSSL_memcpy(x3, &out[0], 32); + OPENSSL_memcpy(y3, &out[32], 32); + OPENSSL_memcpy(z3, &out[64], 32); } - #include "./p256_table.h" // fiat_p256_select_point_affine selects the |idx-1|th point from a @@ -454,8 +289,7 @@ static void ec_GFp_nistp256_add(const EC_GROUP *group, EC_JACOBIAN *r, fiat_p256_from_generic(x2, &b->X); fiat_p256_from_generic(y2, &b->Y); fiat_p256_from_generic(z2, &b->Z); - fiat_p256_point_add(x1, y1, z1, x1, y1, z1, 0 /* both Jacobian */, x2, y2, - z2); + fiat_p256_point_add(x1, y1, z1, x1, y1, z1, x2, y2, z2); fiat_p256_to_generic(&r->X, x1); fiat_p256_to_generic(&r->Y, y1); fiat_p256_to_generic(&r->Z, z1); @@ -486,7 +320,7 @@ static void ec_GFp_nistp256_point_mul(const EC_GROUP *group, EC_JACOBIAN *r, if (j & 1) { fiat_p256_point_add(p_pre_comp[j][0], p_pre_comp[j][1], p_pre_comp[j][2], p_pre_comp[1][0], p_pre_comp[1][1], p_pre_comp[1][2], - 0, p_pre_comp[j - 1][0], p_pre_comp[j - 1][1], + p_pre_comp[j - 1][0], p_pre_comp[j - 1][1], p_pre_comp[j - 1][2]); } else { fiat_p256_point_double(p_pre_comp[j][0], p_pre_comp[j][1], @@ -524,8 +358,8 @@ static void ec_GFp_nistp256_point_mul(const EC_GROUP *group, EC_JACOBIAN *r, fiat_p256_cmovznz(tmp[1], (fiat_p256_limb_t)sign, tmp[1], ftmp); if (!skip) { - fiat_p256_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], - 0 /* mixed */, tmp[0], tmp[1], tmp[2]); + fiat_p256_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], tmp[0], + tmp[1], tmp[2]); } else { fiat_p256_copy(nq[0], tmp[0]); fiat_p256_copy(nq[1], tmp[1]); @@ -562,8 +396,8 @@ static void ec_GFp_nistp256_point_mul_base(const EC_GROUP *group, fiat_p256_g_pre_comp[1], tmp); if (!skip) { - fiat_p256_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], - 1 /* mixed */, tmp[0], tmp[1], tmp[2]); + fiat_p256_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], tmp[0], + tmp[1], tmp[2]); } else { fiat_p256_copy(nq[0], tmp[0]); fiat_p256_copy(nq[1], tmp[1]); @@ -579,8 +413,8 @@ static void ec_GFp_nistp256_point_mul_base(const EC_GROUP *group, // Select the point to add, in constant time. fiat_p256_select_point_affine((fiat_p256_limb_t)bits, 15, fiat_p256_g_pre_comp[0], tmp); - fiat_p256_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */, - tmp[0], tmp[1], tmp[2]); + fiat_p256_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], tmp[0], + tmp[1], tmp[2]); } fiat_p256_to_generic(&r->X, nq[0]); @@ -602,11 +436,10 @@ static void ec_GFp_nistp256_point_mul_public(const EC_GROUP *group, fiat_p256_felem p2[3]; fiat_p256_point_double(p2[0], p2[1], p2[2], p_pre_comp[0][0], p_pre_comp[0][1], p_pre_comp[0][2]); - for (size_t i = 1; i < OPENSSL_ARRAY_SIZE(p_pre_comp); i++) { + for (size_t i = 1; i < std::size(p_pre_comp); i++) { fiat_p256_point_add(p_pre_comp[i][0], p_pre_comp[i][1], p_pre_comp[i][2], p_pre_comp[i - 1][0], p_pre_comp[i - 1][1], - p_pre_comp[i - 1][2], 0 /* not mixed */, p2[0], p2[1], - p2[2]); + p_pre_comp[i - 1][2], p2[0], p2[1], p2[2]); } // Set up the coefficients for |p_scalar|. @@ -632,9 +465,8 @@ static void ec_GFp_nistp256_point_mul_public(const EC_GROUP *group, if (bits != 0) { size_t index = (size_t)(bits - 1); fiat_p256_point_add(ret[0], ret[1], ret[2], ret[0], ret[1], ret[2], - 1 /* mixed */, fiat_p256_g_pre_comp[1][index][0], - fiat_p256_g_pre_comp[1][index][1], - fiat_p256_one); + fiat_p256_g_pre_comp[1][index][0], + fiat_p256_g_pre_comp[1][index][1], fiat_p256_one); skip = 0; } @@ -646,9 +478,8 @@ static void ec_GFp_nistp256_point_mul_public(const EC_GROUP *group, if (bits != 0) { size_t index = (size_t)(bits - 1); fiat_p256_point_add(ret[0], ret[1], ret[2], ret[0], ret[1], ret[2], - 1 /* mixed */, fiat_p256_g_pre_comp[0][index][0], - fiat_p256_g_pre_comp[0][index][1], - fiat_p256_one); + fiat_p256_g_pre_comp[0][index][0], + fiat_p256_g_pre_comp[0][index][1], fiat_p256_one); skip = 0; } } @@ -664,8 +495,7 @@ static void ec_GFp_nistp256_point_mul_public(const EC_GROUP *group, } if (!skip) { fiat_p256_point_add(ret[0], ret[1], ret[2], ret[0], ret[1], ret[2], - 0 /* not mixed */, p_pre_comp[idx][0], *y, - p_pre_comp[idx][2]); + p_pre_comp[idx][0], *y, p_pre_comp[idx][2]); } else { fiat_p256_copy(ret[0], p_pre_comp[idx][0]); fiat_p256_copy(ret[1], *y); diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/simple_mul.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/simple_mul.cc.inc index 2b659e205..cbe12bce6 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/simple_mul.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/simple_mul.cc.inc @@ -16,6 +16,9 @@ #include +#include +#include + #include "internal.h" #include "../bn/internal.h" #include "../../internal.h" @@ -31,7 +34,7 @@ void ec_GFp_mont_mul(const EC_GROUP *group, EC_JACOBIAN *r, EC_JACOBIAN precomp[32]; ec_GFp_simple_point_set_to_infinity(group, &precomp[0]); ec_GFp_simple_point_copy(&precomp[1], p); - for (size_t j = 2; j < OPENSSL_ARRAY_SIZE(precomp); j++) { + for (size_t j = 2; j < std::size(precomp); j++) { if (j & 1) { ec_GFp_mont_add(group, &precomp[j], &precomp[1], &precomp[j - 1]); } else { @@ -58,7 +61,7 @@ void ec_GFp_mont_mul(const EC_GROUP *group, EC_JACOBIAN *r, // Select the entry in constant-time. EC_JACOBIAN tmp; OPENSSL_memset(&tmp, 0, sizeof(EC_JACOBIAN)); - for (size_t j = 0; j < OPENSSL_ARRAY_SIZE(precomp); j++) { + for (size_t j = 0; j < std::size(precomp); j++) { BN_ULONG mask = constant_time_eq_w(j, window); ec_point_select(group, &tmp, mask, &precomp[j], &tmp); } @@ -202,10 +205,10 @@ int ec_GFp_mont_init_precomp(const EC_GROUP *group, EC_PRECOMP *out, // Store the comb in affine coordinates to shrink the table. (This reduces // cache pressure and makes the constant-time selects faster.) - static_assert(OPENSSL_ARRAY_SIZE(comb) == OPENSSL_ARRAY_SIZE(out->comb), - "comb sizes did not match"); - return ec_jacobian_to_affine_batch(group, out->comb, comb, - OPENSSL_ARRAY_SIZE(comb)); + static_assert( + std::extent_v == std::extent_vcomb)>, + "comb sizes did not match"); + return ec_jacobian_to_affine_batch(group, out->comb, comb, std::size(comb)); } static void ec_GFp_mont_get_comb_window(const EC_GROUP *group, @@ -224,7 +227,7 @@ static void ec_GFp_mont_get_comb_window(const EC_GROUP *group, // Select precomp->comb[window - 1]. If |window| is zero, |match| will always // be zero, which will leave |out| at infinity. OPENSSL_memset(out, 0, sizeof(EC_JACOBIAN)); - for (unsigned j = 0; j < OPENSSL_ARRAY_SIZE(precomp->comb); j++) { + for (unsigned j = 0; j < std::size(precomp->comb); j++) { BN_ULONG match = constant_time_eq_w(window, j + 1); ec_felem_select(group, &out->X, match, &precomp->comb[j].X, &out->X); ec_felem_select(group, &out->Y, match, &precomp->comb[j].Y, &out->Y); diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/wnaf.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/wnaf.cc.inc index c3cc06d42..e8e1575e3 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/wnaf.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/ec/wnaf.cc.inc @@ -18,6 +18,8 @@ #include #include +#include + #include #include #include @@ -167,7 +169,7 @@ int ec_GFp_mont_mul_public_batch(const EC_GROUP *group, EC_JACOBIAN *r, int8_t g_wNAF[EC_MAX_BYTES * 8 + 1]; EC_JACOBIAN g_precomp[EC_WNAF_TABLE_SIZE]; - assert(wNAF_len <= OPENSSL_ARRAY_SIZE(g_wNAF)); + assert(wNAF_len <= std::size(g_wNAF)); const EC_JACOBIAN *g = &group->generator.raw; if (g_scalar != NULL) { ec_compute_wNAF(group, g_wNAF, g_scalar, bits, EC_WNAF_WINDOW_BITS); @@ -175,7 +177,7 @@ int ec_GFp_mont_mul_public_batch(const EC_GROUP *group, EC_JACOBIAN *r, } for (size_t i = 0; i < num; i++) { - assert(wNAF_len <= OPENSSL_ARRAY_SIZE(wNAF[i])); + assert(wNAF_len <= std::size(wNAF[i])); ec_compute_wNAF(group, wNAF[i], &scalars[i], bits, EC_WNAF_WINDOW_BITS); compute_precomp(group, precomp[i], &points[i], EC_WNAF_TABLE_SIZE); } diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/entropy/internal.h b/Sources/CCryptoBoringSSL/crypto/fipsmodule/entropy/internal.h new file mode 100644 index 000000000..27affb47d --- /dev/null +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/entropy/internal.h @@ -0,0 +1,38 @@ +// Copyright 2025 The BoringSSL Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OPENSSL_HEADER_CRYPTO_FIPSMODULE_ENTROPY_INTERNAL_H +#define OPENSSL_HEADER_CRYPTO_FIPSMODULE_ENTROPY_INTERNAL_H + +#include + +#if defined(OPENSSL_LINUX) || defined(OPENSSL_MACOS) + +BSSL_NAMESPACE_BEGIN +namespace entropy { + +// GetSeed fills `out` with random bytes from the jitter source. +OPENSSL_EXPORT bool GetSeed(uint8_t out[48]); + +// GetSamples fetches `n` raw delta time samples. +OPENSSL_EXPORT bool GetSamples(uint64_t *out, size_t n); + +// GetVersion returns the version of the entropy module. +int GetVersion(); + +} // namespace entropy +BSSL_NAMESPACE_END + +#endif // LINUX || MACOS +#endif // OPENSSL_HEADER_CRYPTO_FIPSMODULE_ENTROPY_INTERNAL_H diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/entropy/jitter.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/entropy/jitter.cc.inc new file mode 100644 index 000000000..4b94acf18 --- /dev/null +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/entropy/jitter.cc.inc @@ -0,0 +1,463 @@ +// Copyright 2025 The BoringSSL Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// BoringCrypto Jitter Entropy version 20250725. + +#include + +#if defined(OPENSSL_LINUX) || defined(OPENSSL_MACOS) + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "internal.h" +#include "sha512.cc.inc" + +#if defined(__x86_64__) +#include +#endif + + +BSSL_NAMESPACE_BEGIN +namespace entropy { +namespace { + +#if defined(__x86_64__) +static inline uint64_t GetTimestamp() { return _rdtsc(); } +#elif defined(__aarch64__) +static inline uint64_t GetTimestamp() { + // Ideally this would use __arm_rsr64 from . Clang has supported + // it Clang 3.7 (2016), but GCC did not add it until GCC 14.1.0 (2024). See + // https://crbug.com/440670941. When our minimum GCC is past that point, + // switch this back to __arm_rsr64. + uint64_t ret; + __asm__ volatile("mrs %0, cntvct_el0" : "=r"(ret)); + return ret; +} +#else +static inline uint64_t GetTimestamp() { + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC_RAW, &ts); + return ts.tv_sec * 1000000000ULL + ts.tv_nsec; +} +#endif + +class MemoryOffsetLCG { + public: + MemoryOffsetLCG() : state(GetTimestamp() & 0xFFFFFFFF) {} + uint32_t Next() { + state = state * 1664525 + 1013904223; + return state; + } + + private: + uint32_t state; +}; + +class MemoryAccessSampler { + public: + MemoryAccessSampler(size_t array_size, unsigned num_samples) + : array_size_(array_size), + num_samples_(num_samples), + array_(reinterpret_cast(OPENSSL_malloc(array_size_))) { + if (array_ == nullptr || // + array_size_ == 0 || // + array_size_ > (1u << 26) || // + array_size_ & (array_size_ - 1)) { + abort(); + } + } + + ~MemoryAccessSampler() { OPENSSL_free(const_cast(array_)); } + + MemoryAccessSampler(const MemoryAccessSampler &) = delete; + MemoryAccessSampler &operator=(const MemoryAccessSampler &) = delete; + + MemoryAccessSampler(MemoryAccessSampler &&other) + : array_size_(other.array_size_), + num_samples_(other.num_samples_), + lcg_(other.lcg_), + array_(other.array_) { + other.array_ = nullptr; + } + + bool Next(uint64_t *out) { + // Perform some memory accesses and measure how long it took. The LCG is + // intended to defeat any CPU predictors and thus expose this code to as + // much system entropy as possible. + for (unsigned i = 0; i < num_samples_; i++) { + // The lower bits of an LCG tend to fall into short cycles and so are + // discarded here. + array_[(lcg_.Next() >> 6) & (array_size_ - 1)] += 1; + } + + *out = GetTimestamp(); + return true; + } + + private: + const size_t array_size_; + const unsigned num_samples_; + MemoryOffsetLCG lcg_; + volatile uint8_t *array_; +}; + +template +class DeltaSampler { + public: + explicit DeltaSampler(T &&sub_sampler) + : sub_sampler_(std::forward(sub_sampler)) {} + + // Next function to return the delta between two subsequent samples + bool Next(uint64_t *out) { + uint64_t sample; + if (!sub_sampler_.Next(&sample)) { + return false; + } + + if (!initialized_) { + last_sample_ = sample; + if (!sub_sampler_.Next(&sample)) { + return false; + } + initialized_ = true; + } + + *out = sample - last_sample_; + last_sample_ = sample; + return true; + } + + private: + bool initialized_ = false; + T sub_sampler_; + uint64_t last_sample_; +}; + +template +DeltaSampler(U &&sub_sampler) -> DeltaSampler>; + +template +class MaskSampler { + public: + explicit MaskSampler(uint8_t mask, T &&sub_sampler) + : mask_(mask), sub_sampler_(std::forward(sub_sampler)) {} + + bool Next(uint8_t *out) { + uint64_t sample; + if (!sub_sampler_.Next(&sample)) { + return false; + } + + *out = sample & mask_; + return true; + } + + private: + const uint8_t mask_; + T sub_sampler_; +}; + +template +MaskSampler(uint8_t mask, U &&sub_sampler) -> MaskSampler>; + +// The estimated entropy per sample from MaskSampler. +constexpr float kH = 0.8; + +// kAlphaLog2 is log_2(alpha), where alpha is the standard false-positive +// probability from SP 800-90B. +static constexpr float kAlphaLog2 = -20; +// kAlpha is the variable of the same name from section 4.4.1 of SP 800-90B. +constexpr float kAlpha = 1.0 / (1 << static_cast(-kAlphaLog2)); + +// Ceil rounds up its non-negative argument to the next integer. (std::ceil +// isn't constexpr until C++23.) +constexpr unsigned Ceil(float val) { + auto truncated = static_cast(val); + if (val == static_cast(truncated)) { + return truncated; + } + if (val > 0) { + return truncated + 1; + } + __builtin_unreachable(); +} + +template +class RepetitionCountTest { + public: + static constexpr unsigned kThreshold = 1 + Ceil(-kAlphaLog2 / kH); + static_assert(kThreshold == 26); + + explicit RepetitionCountTest(T &&sub_sampler) + : sub_sampler_(std::forward(sub_sampler)) {} + + bool Next(uint8_t *out) { + uint8_t sample; + if (!sub_sampler_.Next(&sample)) { + return false; + } + if (sample == last_sample_) { + count_++; + } else { + count_ = 1; + last_sample_ = sample; + } + if (count_ >= kThreshold) { + return false; + } + *out = sample; + return true; + } + + private: + T sub_sampler_; + unsigned count_ = 0; + uint8_t last_sample_ = 0; +}; + +template +RepetitionCountTest(U &&sub_sampler) -> RepetitionCountTest>; + +constexpr double BinomialPMF(int64_t k, int64_t n, double p) { + if (k < 0 || k > n) { + return 0.0; + } + + double result = 1.0; + for (int64_t i = 0; i < k; ++i) { + result *= (n - i); + result /= (i + 1); + } + + for (int64_t i = 0; i < k; ++i) { + result *= p; + } + for (int64_t i = 0; i < n - k; ++i) { + result *= (1 - p); + } + + return result; +} + +// CritBinom implements the Excel function of the same name. +constexpr unsigned CritBinom(unsigned trials, double probability_s, + double alpha) { + if (probability_s < 0.0 || probability_s > 1.0 || alpha < 0.0 || + alpha > 1.0) { + __builtin_unreachable(); + } + + double cumulative = 0.0; + for (unsigned k = 0; k <= trials; ++k) { + cumulative += BinomialPMF(k, trials, probability_s); + if (cumulative >= alpha) { + return k; + } + } + + return trials; +} + +// ExpTaylor calculates e^x using the Taylor series: e^x = 1 + x + x²/2! + +// x³/3! + ... +constexpr double ExpTaylor(double x) { + double sum = 1.0; + double term = 1.0; + + for (int i = 1; i < 25; ++i) { + term *= x / i; + sum += term; + } + + return sum; +} + +// Power2 calculates 2^exp by calculating e^(ln(2) * exp) = e^(ln(2)) ^ exp = +// 2^exp. (std::pow isn't constexpr until C++26.) +constexpr double Power2(double exp) { + constexpr double ln2 = 0.693147180559945309417232121458; + return ExpTaylor(exp * ln2); +} + +// AdaptiveProportionTestCutoff implements the function from the footnote on +// page 27 of SP 800-90B. +constexpr unsigned AdaptiveProportionTestCutoff(unsigned W, float H, + float alpha) { + return 1 + CritBinom(W, Power2(-H), 1.0 - alpha); +} + +// These are the example values from table 2 of SP 800-90B, to show that +// we're calculating the values correctly. +static_assert(AdaptiveProportionTestCutoff(512, 0.5, kAlpha) == 410); +static_assert(AdaptiveProportionTestCutoff(512, 1, kAlpha) == 311); +static_assert(AdaptiveProportionTestCutoff(512, 2, kAlpha) == 177); +static_assert(AdaptiveProportionTestCutoff(512, 4, kAlpha) == 62); +static_assert(AdaptiveProportionTestCutoff(512, 8, kAlpha) == 13); + +template +class AdaptiveProportionTest { + public: + // The size of the sliding window, representing the number of recent samples + // to analyze. + static constexpr unsigned kWindowSize = 512; + + // The maximum number of times any single byte value is allowed to appear + // within the sliding window. + static constexpr unsigned kThreshold = + AdaptiveProportionTestCutoff(kWindowSize, kH, kAlpha); + static_assert(kThreshold == 348); + + explicit AdaptiveProportionTest(T &&sub_sampler) + : sub_sampler_(std::forward(sub_sampler)) { + counts_.fill(0); + } + + bool Next(uint8_t *out) { + uint8_t sample; + if (!sub_sampler_.Next(&sample)) { + return false; + } + *out = sample; + + if (samples_processed_ >= kWindowSize) { + const uint8_t evicted_sample = buffer_[buffer_idx_]; + counts_[evicted_sample]--; + } + + buffer_[buffer_idx_] = sample; + const uint16_t new_count = ++counts_[sample]; + + if (new_count > kThreshold) { + return false; + } + + buffer_idx_ = (buffer_idx_ + 1) % kWindowSize; + samples_processed_++; + + return true; + } + + private: + T sub_sampler_; + + // A circular buffer to store the most recent `kWindowSize` samples. + std::array buffer_{}; + + // An array to store the frequency counts of each possible byte value (0-255) + // within the current window. + std::array counts_{}; + + // The current index for writing into the circular buffer. + size_t buffer_idx_ = 0; + + // The total number of samples processed. Used to determine when the buffer + // is full and eviction should begin. + size_t samples_processed_ = 0; +}; + +template +AdaptiveProportionTest(U &&sub_sampler) + -> AdaptiveProportionTest>; + +template +class SeedSampler { + public: + // NIST requires 1024 samples at start-up time. This code is structured so + // that the entropy generator is considered to be starting afresh for each + // seed. + static constexpr unsigned kNumSamples = 1024; + + explicit SeedSampler(T &&sub_sampler) + : sub_sampler_(std::forward(sub_sampler)) {} + + bool Next(uint8_t out_seed[48]) { + // HMAC-SHA384 `kNumSamples` samples with an all-zero key: + SHA512_CTX ctx; + SHA384_Init(&ctx); + + uint8_t block[kSHA384Block]; + memset(block, 0x36, sizeof(block)); + SHA384_Update(&ctx, block, sizeof(block)); + + static_assert(kNumSamples % sizeof(block) == 0); + for (unsigned i = 0; i < kNumSamples / sizeof(block); i++) { + for (unsigned j = 0; j < sizeof(block); j++) { + if (!sub_sampler_.Next(&block[j])) { + return false; + } + } + SHA384_Update(&ctx, block, sizeof(block)); + } + + SHA384_Final(out_seed, &ctx); + + SHA384_Init(&ctx); + memset(block, 0x5c, sizeof(block)); + SHA384_Update(&ctx, block, sizeof(block)); + SHA384_Update(&ctx, out_seed, kSHA384DigestLength); + SHA384_Final(out_seed, &ctx); + + return true; + } + + private: + T sub_sampler_; +}; + +template +SeedSampler(U &&sub_sampler) -> SeedSampler>; + +constexpr size_t kMemorySize = 1u << 25; +constexpr size_t kMemoryAccessesPerSample = 16; +constexpr size_t kBitsPerSample = 8; +constexpr uint8_t kMask = (1u << kBitsPerSample) - 1; + +} // namespace + +int GetVersion() { return 20250725; } + +bool GetSeed(uint8_t out[48]) { + auto sampler(SeedSampler(AdaptiveProportionTest(RepetitionCountTest( + MaskSampler(kMask, DeltaSampler(MemoryAccessSampler( + kMemorySize, kMemoryAccessesPerSample))))))); + return sampler.Next(out); +} + +bool GetSamples(uint64_t *out, size_t n) { + auto sampler( + DeltaSampler(MemoryAccessSampler(kMemorySize, kMemoryAccessesPerSample))); + for (size_t i = 0; i < n; i++) { + if (!sampler.Next(&out[i])) { + return false; + } + } + return true; +} + +} // namespace entropy +BSSL_NAMESPACE_END + +#endif // LINUX || MACOS diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/entropy/sha512.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/entropy/sha512.cc.inc new file mode 100644 index 000000000..14e2975bc --- /dev/null +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/entropy/sha512.cc.inc @@ -0,0 +1,324 @@ +// Copyright 2004-2016 The OpenSSL Project Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include +#include + + +// This is a copy of the SHA-384 code for the purpose of isolating the jitter +// entropy source certification from any changes to the normal implementation. + +namespace bssl::entropy { +namespace { + +constexpr size_t kSHA384Block = 128; +constexpr size_t kSHA384DigestLength = (384 / 8); + +struct SHA512_CTX { + uint64_t h[8]; + uint64_t Nl, Nh; + uint8_t p[kSHA384Block]; + unsigned num, md_len; +}; + +uint64_t CRYPTO_bswap8(uint64_t x) { return __builtin_bswap64(x); } + +uint64_t CRYPTO_load_u64_be(const void *ptr) { + uint64_t ret; + memcpy(&ret, ptr, sizeof(ret)); + return CRYPTO_bswap8(ret); +} + +void CRYPTO_store_u64_be(void *out, uint64_t v) { + v = CRYPTO_bswap8(v); + memcpy(out, &v, sizeof(v)); +} + +uint64_t CRYPTO_rotr_u64(uint64_t value, int shift) { + return (value >> shift) | (value << ((-shift) & 63)); +} + +void sha512_update(SHA512_CTX *c, const void *in_data, size_t len); +void sha512_final_impl(uint8_t *out, size_t md_len, SHA512_CTX *sha); + +void SHA384_Init(SHA512_CTX *sha) { + sha->h[0] = UINT64_C(0xcbbb9d5dc1059ed8); + sha->h[1] = UINT64_C(0x629a292a367cd507); + sha->h[2] = UINT64_C(0x9159015a3070dd17); + sha->h[3] = UINT64_C(0x152fecd8f70e5939); + sha->h[4] = UINT64_C(0x67332667ffc00b31); + sha->h[5] = UINT64_C(0x8eb44a8768581511); + sha->h[6] = UINT64_C(0xdb0c2e0d64f98fa7); + sha->h[7] = UINT64_C(0x47b5481dbefa4fa4); + + sha->Nl = 0; + sha->Nh = 0; + sha->num = 0; + sha->md_len = kSHA384DigestLength; + return; +} + +void SHA384_Final(uint8_t out[kSHA384DigestLength], SHA512_CTX *sha) { + // This function must be paired with |SHA384_Init|, which sets + // |sha->md_len| to |kSHA384DigestLength|. + sha512_final_impl(out, kSHA384DigestLength, sha); + return; +} + +void SHA384_Update(SHA512_CTX *sha, const void *data, size_t len) { + return sha512_update(sha, data, len); +} + +void sha512_block_data_order(uint64_t state[8], const uint8_t *in, + size_t num_blocks); + +void sha512_final_impl(uint8_t *out, size_t md_len, SHA512_CTX *sha) { + uint8_t *p = sha->p; + size_t n = sha->num; + + p[n] = 0x80; // There always is a room for one + n++; + if (n > (sizeof(sha->p) - 16)) { + memset(p + n, 0, sizeof(sha->p) - n); + n = 0; + sha512_block_data_order(sha->h, p, 1); + } + + memset(p + n, 0, sizeof(sha->p) - 16 - n); + CRYPTO_store_u64_be(p + sizeof(sha->p) - 16, sha->Nh); + CRYPTO_store_u64_be(p + sizeof(sha->p) - 8, sha->Nl); + + sha512_block_data_order(sha->h, p, 1); + + const size_t out_words = md_len / 8; + for (size_t i = 0; i < out_words; i++) { + CRYPTO_store_u64_be(out, sha->h[i]); + out += 8; + } +} + +const uint64_t K512[80] = { + UINT64_C(0x428a2f98d728ae22), UINT64_C(0x7137449123ef65cd), + UINT64_C(0xb5c0fbcfec4d3b2f), UINT64_C(0xe9b5dba58189dbbc), + UINT64_C(0x3956c25bf348b538), UINT64_C(0x59f111f1b605d019), + UINT64_C(0x923f82a4af194f9b), UINT64_C(0xab1c5ed5da6d8118), + UINT64_C(0xd807aa98a3030242), UINT64_C(0x12835b0145706fbe), + UINT64_C(0x243185be4ee4b28c), UINT64_C(0x550c7dc3d5ffb4e2), + UINT64_C(0x72be5d74f27b896f), UINT64_C(0x80deb1fe3b1696b1), + UINT64_C(0x9bdc06a725c71235), UINT64_C(0xc19bf174cf692694), + UINT64_C(0xe49b69c19ef14ad2), UINT64_C(0xefbe4786384f25e3), + UINT64_C(0x0fc19dc68b8cd5b5), UINT64_C(0x240ca1cc77ac9c65), + UINT64_C(0x2de92c6f592b0275), UINT64_C(0x4a7484aa6ea6e483), + UINT64_C(0x5cb0a9dcbd41fbd4), UINT64_C(0x76f988da831153b5), + UINT64_C(0x983e5152ee66dfab), UINT64_C(0xa831c66d2db43210), + UINT64_C(0xb00327c898fb213f), UINT64_C(0xbf597fc7beef0ee4), + UINT64_C(0xc6e00bf33da88fc2), UINT64_C(0xd5a79147930aa725), + UINT64_C(0x06ca6351e003826f), UINT64_C(0x142929670a0e6e70), + UINT64_C(0x27b70a8546d22ffc), UINT64_C(0x2e1b21385c26c926), + UINT64_C(0x4d2c6dfc5ac42aed), UINT64_C(0x53380d139d95b3df), + UINT64_C(0x650a73548baf63de), UINT64_C(0x766a0abb3c77b2a8), + UINT64_C(0x81c2c92e47edaee6), UINT64_C(0x92722c851482353b), + UINT64_C(0xa2bfe8a14cf10364), UINT64_C(0xa81a664bbc423001), + UINT64_C(0xc24b8b70d0f89791), UINT64_C(0xc76c51a30654be30), + UINT64_C(0xd192e819d6ef5218), UINT64_C(0xd69906245565a910), + UINT64_C(0xf40e35855771202a), UINT64_C(0x106aa07032bbd1b8), + UINT64_C(0x19a4c116b8d2d0c8), UINT64_C(0x1e376c085141ab53), + UINT64_C(0x2748774cdf8eeb99), UINT64_C(0x34b0bcb5e19b48a8), + UINT64_C(0x391c0cb3c5c95a63), UINT64_C(0x4ed8aa4ae3418acb), + UINT64_C(0x5b9cca4f7763e373), UINT64_C(0x682e6ff3d6b2b8a3), + UINT64_C(0x748f82ee5defb2fc), UINT64_C(0x78a5636f43172f60), + UINT64_C(0x84c87814a1f0ab72), UINT64_C(0x8cc702081a6439ec), + UINT64_C(0x90befffa23631e28), UINT64_C(0xa4506cebde82bde9), + UINT64_C(0xbef9a3f7b2c67915), UINT64_C(0xc67178f2e372532b), + UINT64_C(0xca273eceea26619c), UINT64_C(0xd186b8c721c0c207), + UINT64_C(0xeada7dd6cde0eb1e), UINT64_C(0xf57d4f7fee6ed178), + UINT64_C(0x06f067aa72176fba), UINT64_C(0x0a637dc5a2c898a6), + UINT64_C(0x113f9804bef90dae), UINT64_C(0x1b710b35131c471b), + UINT64_C(0x28db77f523047d84), UINT64_C(0x32caab7b40c72493), + UINT64_C(0x3c9ebe0a15c9bebc), UINT64_C(0x431d67c49c100d4c), + UINT64_C(0x4cc5d4becb3e42b6), UINT64_C(0x597f299cfc657e2a), + UINT64_C(0x5fcb6fab3ad6faec), UINT64_C(0x6c44198c4a475817), +}; + +#define Sigma0(x) \ + (CRYPTO_rotr_u64((x), 28) ^ CRYPTO_rotr_u64((x), 34) ^ \ + CRYPTO_rotr_u64((x), 39)) +#define Sigma1(x) \ + (CRYPTO_rotr_u64((x), 14) ^ CRYPTO_rotr_u64((x), 18) ^ \ + CRYPTO_rotr_u64((x), 41)) +#define sigma0(x) \ + (CRYPTO_rotr_u64((x), 1) ^ CRYPTO_rotr_u64((x), 8) ^ ((x) >> 7)) +#define sigma1(x) \ + (CRYPTO_rotr_u64((x), 19) ^ CRYPTO_rotr_u64((x), 61) ^ ((x) >> 6)) + +#define Ch(x, y, z) (((x) & (y)) ^ ((~(x)) & (z))) +#define Maj(x, y, z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + +#define ROUND_00_15(i, a, b, c, d, e, f, g, h) \ + do { \ + T1 += h + Sigma1(e) + Ch(e, f, g) + K512[i]; \ + h = Sigma0(a) + Maj(a, b, c); \ + d += T1; \ + h += T1; \ + } while (0) + +#define ROUND_16_80(i, j, a, b, c, d, e, f, g, h, X) \ + do { \ + s0 = X[(j + 1) & 0x0f]; \ + s0 = sigma0(s0); \ + s1 = X[(j + 14) & 0x0f]; \ + s1 = sigma1(s1); \ + T1 = X[(j) & 0x0f] += s0 + s1 + X[(j + 9) & 0x0f]; \ + ROUND_00_15(i + j, a, b, c, d, e, f, g, h); \ + } while (0) + +void sha512_block_data_order(uint64_t state[8], const uint8_t *in, size_t num) { + uint64_t a, b, c, d, e, f, g, h, s0, s1, T1; + uint64_t X[16]; + int i; + + while (num--) { + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + f = state[5]; + g = state[6]; + h = state[7]; + + T1 = X[0] = CRYPTO_load_u64_be(in); + ROUND_00_15(0, a, b, c, d, e, f, g, h); + T1 = X[1] = CRYPTO_load_u64_be(in + 8); + ROUND_00_15(1, h, a, b, c, d, e, f, g); + T1 = X[2] = CRYPTO_load_u64_be(in + 2 * 8); + ROUND_00_15(2, g, h, a, b, c, d, e, f); + T1 = X[3] = CRYPTO_load_u64_be(in + 3 * 8); + ROUND_00_15(3, f, g, h, a, b, c, d, e); + T1 = X[4] = CRYPTO_load_u64_be(in + 4 * 8); + ROUND_00_15(4, e, f, g, h, a, b, c, d); + T1 = X[5] = CRYPTO_load_u64_be(in + 5 * 8); + ROUND_00_15(5, d, e, f, g, h, a, b, c); + T1 = X[6] = CRYPTO_load_u64_be(in + 6 * 8); + ROUND_00_15(6, c, d, e, f, g, h, a, b); + T1 = X[7] = CRYPTO_load_u64_be(in + 7 * 8); + ROUND_00_15(7, b, c, d, e, f, g, h, a); + T1 = X[8] = CRYPTO_load_u64_be(in + 8 * 8); + ROUND_00_15(8, a, b, c, d, e, f, g, h); + T1 = X[9] = CRYPTO_load_u64_be(in + 9 * 8); + ROUND_00_15(9, h, a, b, c, d, e, f, g); + T1 = X[10] = CRYPTO_load_u64_be(in + 10 * 8); + ROUND_00_15(10, g, h, a, b, c, d, e, f); + T1 = X[11] = CRYPTO_load_u64_be(in + 11 * 8); + ROUND_00_15(11, f, g, h, a, b, c, d, e); + T1 = X[12] = CRYPTO_load_u64_be(in + 12 * 8); + ROUND_00_15(12, e, f, g, h, a, b, c, d); + T1 = X[13] = CRYPTO_load_u64_be(in + 13 * 8); + ROUND_00_15(13, d, e, f, g, h, a, b, c); + T1 = X[14] = CRYPTO_load_u64_be(in + 14 * 8); + ROUND_00_15(14, c, d, e, f, g, h, a, b); + T1 = X[15] = CRYPTO_load_u64_be(in + 15 * 8); + ROUND_00_15(15, b, c, d, e, f, g, h, a); + + for (i = 16; i < 80; i += 16) { + ROUND_16_80(i, 0, a, b, c, d, e, f, g, h, X); + ROUND_16_80(i, 1, h, a, b, c, d, e, f, g, X); + ROUND_16_80(i, 2, g, h, a, b, c, d, e, f, X); + ROUND_16_80(i, 3, f, g, h, a, b, c, d, e, X); + ROUND_16_80(i, 4, e, f, g, h, a, b, c, d, X); + ROUND_16_80(i, 5, d, e, f, g, h, a, b, c, X); + ROUND_16_80(i, 6, c, d, e, f, g, h, a, b, X); + ROUND_16_80(i, 7, b, c, d, e, f, g, h, a, X); + ROUND_16_80(i, 8, a, b, c, d, e, f, g, h, X); + ROUND_16_80(i, 9, h, a, b, c, d, e, f, g, X); + ROUND_16_80(i, 10, g, h, a, b, c, d, e, f, X); + ROUND_16_80(i, 11, f, g, h, a, b, c, d, e, X); + ROUND_16_80(i, 12, e, f, g, h, a, b, c, d, X); + ROUND_16_80(i, 13, d, e, f, g, h, a, b, c, X); + ROUND_16_80(i, 14, c, d, e, f, g, h, a, b, X); + ROUND_16_80(i, 15, b, c, d, e, f, g, h, a, X); + } + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + state[5] += f; + state[6] += g; + state[7] += h; + + in += 16 * 8; + } +} + +#undef Sigma0 +#undef Sigma1 +#undef sigma0 +#undef sigma1 +#undef Ch +#undef Maj +#undef ROUND_00_15 +#undef ROUND_16_80 + +void sha512_update(SHA512_CTX *c, const void *in_data, size_t len) { + uint64_t l; + uint8_t *p = c->p; + const uint8_t *data = reinterpret_cast(in_data); + + if (len == 0) { + return; + } + + l = (c->Nl + (((uint64_t)len) << 3)) & UINT64_C(0xffffffffffffffff); + if (l < c->Nl) { + c->Nh++; + } + if (sizeof(len) >= 8) { + c->Nh += (((uint64_t)len) >> 61); + } + c->Nl = l; + + if (c->num != 0) { + size_t n = sizeof(c->p) - c->num; + + if (len < n) { + memcpy(p + c->num, data, len); + c->num += (unsigned int)len; + return; + } else { + memcpy(p + c->num, data, n), c->num = 0; + len -= n; + data += n; + sha512_block_data_order(c->h, p, 1); + } + } + + if (len >= sizeof(c->p)) { + sha512_block_data_order(c->h, data, len / sizeof(c->p)); + data += len; + len %= sizeof(c->p); + data -= len; + } + + if (len != 0) { + memcpy(p, data, len); + c->num = (int)len; + } + + return; +} + +} // namespace +} // namespace bssl::entropy diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/mldsa/mldsa.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/mldsa/mldsa.cc.inc index 20c99193a..4b1007bba 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/mldsa/mldsa.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/mldsa/mldsa.cc.inc @@ -50,7 +50,6 @@ constexpr uint32_t kPrime = 8380417; constexpr uint32_t kPrimeNegInverse = 4236238847; constexpr int kDroppedBits = 13; constexpr uint32_t kHalfPrime = (kPrime - 1) / 2; -constexpr uint32_t kGamma2 = (kPrime - 1) / 32; // 256^-1 mod kPrime, in Montgomery form. constexpr uint32_t kInverseDegreeMontgomery = 41978; @@ -65,6 +64,8 @@ constexpr size_t public_key_bytes() { return BCM_MLDSA65_PUBLIC_KEY_BYTES; } else if constexpr (K == 8) { return BCM_MLDSA87_PUBLIC_KEY_BYTES; + } else if constexpr (K == 4) { + return BCM_MLDSA44_PUBLIC_KEY_BYTES; } } @@ -74,6 +75,8 @@ constexpr size_t signature_bytes() { return BCM_MLDSA65_SIGNATURE_BYTES; } else if constexpr (K == 8) { return BCM_MLDSA87_SIGNATURE_BYTES; + } else if constexpr (K == 4) { + return BCM_MLDSA44_SIGNATURE_BYTES; } } @@ -83,6 +86,8 @@ constexpr int tau() { return 49; } else if constexpr (K == 8) { return 60; + } else if constexpr (K == 4) { + return 39; } } @@ -92,22 +97,71 @@ constexpr int lambda_bytes() { return 192 / 8; } else if constexpr (K == 8) { return 256 / 8; + } else if constexpr (K == 4) { + return 128 / 8; + } +} + +template +constexpr int gamma1_bits() { + if constexpr (K == 6 || K == 8) { + return 19; + } else if constexpr (K == 4) { + return 17; } } template constexpr int gamma1() { + return 1 << gamma1_bits(); +} + +template +constexpr int scalar_le_gamma1_bytes() { + return ((gamma1_bits() + 1) * kDegree) / 8; +} + +template +constexpr uint32_t w1_coeffs_bits() { if constexpr (K == 6 || K == 8) { - return 1 << 19; + return 4; + } else if constexpr (K == 4) { + return 6; } } +template +constexpr uint32_t w1_scalar_bytes() { + return (w1_coeffs_bits() * kDegree) / 8; +} + +template +constexpr uint32_t w1_bytes() { + return w1_scalar_bytes() * K; +} + +template +constexpr uint32_t prime_minus_one_over_gamma2() { + if constexpr (K == 6 || K == 8) { + return 32; + } else if constexpr (K == 4) { + return 88; + } +} + +template +constexpr uint32_t gamma2() { + return (kPrime - 1) / prime_minus_one_over_gamma2(); +} + template constexpr int beta() { if constexpr (K == 6) { return 196; } else if constexpr (K == 8) { return 120; + } else if constexpr (K == 4) { + return 78; } } @@ -117,6 +171,8 @@ constexpr int omega() { return 55; } else if constexpr (K == 8) { return 75; + } else if constexpr (K == 4) { + return 80; } } @@ -124,7 +180,7 @@ template constexpr int eta() { if constexpr (K == 6) { return 4; - } else if constexpr (K == 8) { + } else if constexpr (K == 8 || K == 4) { return 2; } } @@ -133,7 +189,7 @@ template constexpr int plus_minus_eta_bitlen() { if constexpr (K == 6) { return 4; - } else if constexpr (K == 8) { + } else if constexpr (K == 8 || K == 4) { return 3; } } @@ -433,42 +489,54 @@ void scale_power2_round(uint32_t *out, uint32_t r1) { } // FIPS 204, Algorithm 37 (`HighBits`). +template uint32_t high_bits(uint32_t x) { // Reference description (given 0 <= x < q): // // ``` - // int32_t r0 = x mod+- (2 * kGamma2); + // int32_t r0 = x mod+- (2 * gamma2); // if (x - r0 == q - 1) { // return 0; // } else { - // return (x - r0) / (2 * kGamma2); + // return (x - r0) / (2 * gamma2); // } // ``` // - // Below is the formula taken from the reference implementation. - // - // Here, kGamma2 == 2^18 - 2^8 - // This returns ((ceil(x / 2^7) * (2^10 + 1) + 2^21) / 2^22) mod 2^4 uint32_t r1 = (x + 127) >> 7; - r1 = (r1 * 1025 + (1 << 21)) >> 22; - r1 &= 15; + if constexpr (prime_minus_one_over_gamma2() == 32) { + // Below is the formula taken from the reference implementation. + // + // Here, Gamma2 == 2^18 - 2^8 + // This returns ((ceil(x / 2^7) * (2^10 + 1) + 2^21) / 2^22) mod 2^4 + r1 = (r1 * 1025 + (1 << 21)) >> 22; + r1 &= 15; + } else if constexpr (prime_minus_one_over_gamma2() == 88) { + // 1488/2^24 is close enough to 1/1488 so that r1 becomes x/(2 gamma2) + // rounded down. + r1 = (r1 * 11275 + (1 << 23)) >> 24; + + // For corner-case r1 = (Q-1)/(2 gamma2) = 44, we have to set r1=0. + r1 ^= ((uint32_t)(((int32_t)(43 - r1)) >> 31)) & r1; + } return r1; } // FIPS 204, Algorithm 36 (`Decompose`). +template void decompose(uint32_t *r1, int32_t *r0, uint32_t r) { - *r1 = high_bits(r); + *r1 = high_bits(r); *r0 = r; - *r0 -= *r1 * 2 * (int32_t)kGamma2; + *r0 -= *r1 * 2 * (int32_t)gamma2(); *r0 -= (((int32_t)kHalfPrime - *r0) >> 31) & (int32_t)kPrime; } // FIPS 204, Algorithm 38 (`LowBits`). +template int32_t low_bits(uint32_t x) { uint32_t r1; int32_t r0; - decompose(&r1, &r0, x); + decompose(&r1, &r0, x); return r0; } @@ -480,24 +548,45 @@ int32_t low_bits(uint32_t x) { // // It then computes HighBits (algorithm 37) of z and z+r. But z+r is just w - // cs2, so this takes three arguments and saves an addition. +template int32_t make_hint(uint32_t ct0, uint32_t cs2, uint32_t w) { uint32_t r_plus_z = mod_sub(w, cs2); uint32_t r = reduce_once(r_plus_z + ct0); - return high_bits(r) != high_bits(r_plus_z); + return high_bits(r) != high_bits(r_plus_z); } // FIPS 204, Algorithm 40 (`UseHint`). +template uint32_t use_hint_vartime(uint32_t h, uint32_t r) { uint32_t r1; int32_t r0; - decompose(&r1, &r0, r); + decompose(&r1, &r0, r); if (h) { - if (r0 > 0) { - // m = 16, thus |mod m| in the spec turns into |& 15|. - return (r1 + 1) & 15; + if constexpr (prime_minus_one_over_gamma2() == 32) { + if (r0 > 0) { + // (Q-1)/(2 gamma2) = m = 16, thus |mod m| in the spec turns into |& + // 15|. + return (r1 + 1) & 15; + } else { + return (r1 - 1) & 15; + } } else { - return (r1 - 1) & 15; + // m = 44 + static_assert(prime_minus_one_over_gamma2() == 88); + if (r0 > 0) { + if (r1 == 43) { + return 0; + } else { + return r1 + 1; + } + } else { + if (r1 == 0) { + return 43; + } else { + return r1 - 1; + } + } } } return r1; @@ -515,15 +604,17 @@ void scalar_scale_power2_round(scalar *out, const scalar *in) { } } +template void scalar_high_bits(scalar *out, const scalar *in) { for (int i = 0; i < kDegree; i++) { - out->c[i] = high_bits(in->c[i]); + out->c[i] = high_bits(in->c[i]); } } +template void scalar_low_bits(scalar *out, const scalar *in) { for (int i = 0; i < kDegree; i++) { - out->c[i] = low_bits(in->c[i]); + out->c[i] = low_bits(in->c[i]); } } @@ -541,16 +632,18 @@ void scalar_max_signed(uint32_t *max, const scalar *s) { } } +template void scalar_make_hint(scalar *out, const scalar *ct0, const scalar *cs2, const scalar *w) { for (int i = 0; i < kDegree; i++) { - out->c[i] = make_hint(ct0->c[i], cs2->c[i], w->c[i]); + out->c[i] = make_hint(ct0->c[i], cs2->c[i], w->c[i]); } } +template void scalar_use_hint_vartime(scalar *out, const scalar *h, const scalar *r) { for (int i = 0; i < kDegree; i++) { - out->c[i] = use_hint_vartime(h->c[i], r->c[i]); + out->c[i] = use_hint_vartime(h->c[i], r->c[i]); } } @@ -568,17 +661,17 @@ void vector_scale_power2_round(vector *out, const vector *in) { } } -template -void vector_high_bits(vector *out, const vector *in) { - for (int i = 0; i < X; i++) { - scalar_high_bits(&out->v[i], &in->v[i]); +template +void vector_high_bits(vector *out, const vector *in) { + for (int i = 0; i < K; i++) { + scalar_high_bits(&out->v[i], &in->v[i]); } } -template -void vector_low_bits(vector *out, const vector *in) { - for (int i = 0; i < X; i++) { - scalar_low_bits(&out->v[i], &in->v[i]); +template +void vector_low_bits(vector *out, const vector *in) { + for (int i = 0; i < K; i++) { + scalar_low_bits(&out->v[i], &in->v[i]); } } @@ -612,19 +705,19 @@ size_t vector_count_ones(const vector *a) { return count; } -template -void vector_make_hint(vector *out, const vector *ct0, - const vector *cs2, const vector *w) { - for (int i = 0; i < X; i++) { - scalar_make_hint(&out->v[i], &ct0->v[i], &cs2->v[i], &w->v[i]); +template +void vector_make_hint(vector *out, const vector *ct0, + const vector *cs2, const vector *w) { + for (int i = 0; i < K; i++) { + scalar_make_hint(&out->v[i], &ct0->v[i], &cs2->v[i], &w->v[i]); } } -template -void vector_use_hint_vartime(vector *out, const vector *h, - const vector *r) { - for (int i = 0; i < X; i++) { - scalar_use_hint_vartime(&out->v[i], &h->v[i], &r->v[i]); +template +void vector_use_hint_vartime(vector *out, const vector *h, + const vector *r) { + for (int i = 0; i < K; i++) { + scalar_use_hint_vartime(&out->v[i], &h->v[i], &r->v[i]); } } @@ -643,6 +736,25 @@ static void scalar_encode_4(uint8_t out[128], const scalar *s) { } } +// FIPS 204, Algorithm 16 (`SimpleBitPack`). Specialized to bitlen(b) = 6. +void scalar_encode_6(uint8_t out[192], const scalar *s) { + // Every four elements lands on a byte boundary. + static_assert(kDegree % 4 == 0, "kDegree must be a multiple of 4"); + for (int i = 0; i < kDegree / 4; i++) { + uint32_t a = s->c[4 * i]; + uint32_t b = s->c[4 * i + 1]; + uint32_t c = s->c[4 * i + 2]; + uint32_t d = s->c[4 * i + 3]; + declassify_assert(a < 64); + declassify_assert(b < 64); + declassify_assert(c < 64); + declassify_assert(d < 64); + out[3 * i] = a | (b << 6); + out[3 * i + 1] = (b >> 2) | (c << 4); + out[3 * i + 2] = (c >> 4) | (d << 2); + } +} + // FIPS 204, Algorithm 16 (`SimpleBitPack`). Specialized to bitlen(b) = 10. void scalar_encode_10(uint8_t out[320], const scalar *s) { // Every four elements lands on a byte boundary. @@ -730,10 +842,10 @@ void scalar_encode_signed_13_12(uint8_t out[416], const scalar *s) { e |= g << 14; e |= h << 27; h >>= 5; - OPENSSL_memcpy(&out[13 * i], &a, sizeof(a)); - OPENSSL_memcpy(&out[13 * i + 4], &c, sizeof(c)); - OPENSSL_memcpy(&out[13 * i + 8], &e, sizeof(e)); - OPENSSL_memcpy(&out[13 * i + 12], &h, 1); + CRYPTO_store_u32_le(&out[13 * i], a); + CRYPTO_store_u32_le(&out[13 * i + 4], c); + CRYPTO_store_u32_le(&out[13 * i + 8], e); + out[13 * i + 12] = static_cast(h); } } @@ -757,9 +869,35 @@ void scalar_encode_signed_20_19(uint8_t out[640], const scalar *s) { b |= c << 8; b |= d << 28; d >>= 4; - OPENSSL_memcpy(&out[10 * i], &a, sizeof(a)); - OPENSSL_memcpy(&out[10 * i + 4], &b, sizeof(b)); - OPENSSL_memcpy(&out[10 * i + 8], &d, 2); + CRYPTO_store_u32_le(&out[10 * i], a); + CRYPTO_store_u32_le(&out[10 * i + 4], b); + CRYPTO_store_u16_le(&out[10 * i + 8], static_cast(d)); + } +} + +// FIPS 204, Algorithm 17 (`BitPack`). Specialized to bitlen(a+b) = 18 and b = +// 2^17. +void scalar_encode_signed_18_17(uint8_t out[576], const scalar *s) { + static const uint32_t kMax = 1u << 17; + static_assert(kDegree % 4 == 0, "kDegree must be a multiple of 4"); + for (int i = 0; i < kDegree / 4; i++) { + uint32_t a = mod_sub(kMax, s->c[4 * i]); + uint32_t b = mod_sub(kMax, s->c[4 * i + 1]); + uint32_t c = mod_sub(kMax, s->c[4 * i + 2]); + uint32_t d = mod_sub(kMax, s->c[4 * i + 3]); + declassify_assert(a < (1u << 18)); + declassify_assert(b < (1u << 18)); + declassify_assert(c < (1u << 18)); + declassify_assert(d < (1u << 18)); + out[9 * i] = (uint8_t)a; + out[9 * i + 1] = (uint8_t)(a >> 8); + out[9 * i + 2] = (uint8_t)(a >> 16) | (uint8_t)(b << 2); + out[9 * i + 3] = (uint8_t)(b >> 6); + out[9 * i + 4] = (uint8_t)(b >> 14) | (uint8_t)(c << 4); + out[9 * i + 5] = (uint8_t)(c >> 4); + out[9 * i + 6] = (uint8_t)(c >> 12) | (uint8_t)(d << 6); + out[9 * i + 7] = (uint8_t)(d >> 2); + out[9 * i + 8] = (uint8_t)(d >> 10); } } @@ -775,6 +913,9 @@ void scalar_encode_signed(uint8_t *out, const scalar *s, int bits, } else if (bits == 20) { assert(max == 1u << 19); scalar_encode_signed_20_19(out, s); + } else if (bits == 18) { + assert(max == 1u << 17); + scalar_encode_signed_18_17(out, s); } else { assert(bits == 13); assert(max == 1u << 12); @@ -784,10 +925,9 @@ void scalar_encode_signed(uint8_t *out, const scalar *s, int bits, // FIPS 204, Algorithm 18 (`SimpleBitUnpack`). Specialized for bitlen(b) == 10. void scalar_decode_10(scalar *out, const uint8_t in[320]) { - uint32_t v; static_assert(kDegree % 4 == 0, "kDegree must be a multiple of 4"); for (int i = 0; i < kDegree / 4; i++) { - OPENSSL_memcpy(&v, &in[5 * i], sizeof(v)); + uint32_t v = CRYPTO_load_u32_le(&in[5 * i]); out->c[4 * i] = v & 0x3ff; out->c[4 * i + 1] = (v >> 10) & 0x3ff; out->c[4 * i + 2] = (v >> 20) & 0x3ff; @@ -798,10 +938,9 @@ void scalar_decode_10(scalar *out, const uint8_t in[320]) { // FIPS 204, Algorithm 19 (`BitUnpack`). Specialized to bitlen(a+b) = 4 and b = // 4. int scalar_decode_signed_4_4(scalar *out, const uint8_t in[128]) { - uint32_t v; static_assert(kDegree % 8 == 0, "kDegree must be a multiple of 8"); for (int i = 0; i < kDegree / 8; i++) { - OPENSSL_memcpy(&v, &in[4 * i], sizeof(v)); + uint32_t v = CRYPTO_load_u32_le(&in[4 * i]); // None of the nibbles may be >= 9. So if the MSB of any nibble is set, none // of the other bits may be set. First, select all the MSBs. const uint32_t msbs = v & 0x88888888u; @@ -865,14 +1004,12 @@ void scalar_decode_signed_13_12(scalar *out, const uint8_t in[416]) { static const uint32_t k13Bits = (1u << 13) - 1; static const uint32_t k7Bits = (1u << 7) - 1; - uint32_t a, b, c; - uint8_t d; static_assert(kDegree % 8 == 0, "kDegree must be a multiple of 8"); for (int i = 0; i < kDegree / 8; i++) { - OPENSSL_memcpy(&a, &in[13 * i], sizeof(a)); - OPENSSL_memcpy(&b, &in[13 * i + 4], sizeof(b)); - OPENSSL_memcpy(&c, &in[13 * i + 8], sizeof(c)); - d = in[13 * i + 12]; + uint32_t a = CRYPTO_load_u32_le(&in[13 * i]); + uint32_t b = CRYPTO_load_u32_le(&in[13 * i + 4]); + uint32_t c = CRYPTO_load_u32_le(&in[13 * i + 8]); + uint8_t d = in[13 * i + 12]; // It's not possible for a 13-bit number to be out of range when the max is // 2^12. @@ -887,19 +1024,43 @@ void scalar_decode_signed_13_12(scalar *out, const uint8_t in[416]) { } } +// FIPS 204, Algorithm 19 (`BitUnpack`). Specialized to bitlen(a+b) = 18 and b = +// 2^17. +void scalar_decode_signed_18_17(scalar *out, const uint8_t in[576]) { + static const uint32_t kMax = 1u << 17; + + static_assert(kDegree % 4 == 0, "kDegree must be a multiple of 4"); + for (int i = 0; i < kDegree / 4; i++) { + uint32_t a = uint32_t{in[9 * i]} | (uint32_t{in[9 * i + 1]} << 8) | + ((uint32_t{in[9 * i + 2]} & 0x3) << 16); + uint32_t b = (uint32_t{in[9 * i + 2]} >> 2) | + (uint32_t{in[9 * i + 3]} << 6) | + ((uint32_t{in[9 * i + 4]} & 0xf) << 14); + uint32_t c = (uint32_t{in[9 * i + 4]} >> 4) | + (uint32_t{in[9 * i + 5]} << 4) | + ((uint32_t{in[9 * i + 6]} & 0x3f) << 12); + uint32_t d = (uint32_t{in[9 * i + 6]} >> 6) | + (uint32_t{in[9 * i + 7]} << 2) | + (uint32_t{in[9 * i + 8]} << 10); + + out->c[i * 4] = mod_sub(kMax, a); + out->c[i * 4 + 1] = mod_sub(kMax, b); + out->c[i * 4 + 2] = mod_sub(kMax, c); + out->c[i * 4 + 3] = mod_sub(kMax, d); + } +} + // FIPS 204, Algorithm 19 (`BitUnpack`). Specialized to bitlen(a+b) = 20 and b = // 2^19. void scalar_decode_signed_20_19(scalar *out, const uint8_t in[640]) { static const uint32_t kMax = 1u << 19; static const uint32_t k20Bits = (1u << 20) - 1; - uint32_t a, b; - uint16_t c; static_assert(kDegree % 4 == 0, "kDegree must be a multiple of 4"); for (int i = 0; i < kDegree / 4; i++) { - OPENSSL_memcpy(&a, &in[10 * i], sizeof(a)); - OPENSSL_memcpy(&b, &in[10 * i + 4], sizeof(b)); - OPENSSL_memcpy(&c, &in[10 * i + 8], sizeof(c)); + uint32_t a = CRYPTO_load_u32_le(&in[10 * i]); + uint32_t b = CRYPTO_load_u32_le(&in[10 * i + 4]); + uint16_t c = CRYPTO_load_u16_le(&in[10 * i + 8]); // It's not possible for a 20-bit number to be out of range when the max is // 2^19. @@ -923,6 +1084,10 @@ int scalar_decode_signed(scalar *out, const uint8_t *in, int bits, assert(max == (1u << 12)); scalar_decode_signed_13_12(out, in); return 1; + } else if (bits == 18) { + assert(max == (1u << 17)); + scalar_decode_signed_18_17(out, in); + return 1; } else if (bits == 20) { assert(max == (1u << 19)); scalar_decode_signed_20_19(out, in); @@ -1016,13 +1181,14 @@ void scalar_uniform(scalar *out, const uint8_t derived_seed[kSigmaBytes + 2]) { } // FIPS 204, Algorithm 34 (`ExpandMask`), but just a single step. +template void scalar_sample_mask(scalar *out, const uint8_t derived_seed[kRhoPrimeBytes + 2]) { - uint8_t buf[640]; + uint8_t buf[scalar_le_gamma1_bytes()]; BORINGSSL_keccak(buf, sizeof(buf), derived_seed, kRhoPrimeBytes + 2, boringssl_shake256); - scalar_decode_signed_20_19(out, buf); + scalar_decode_signed(out, buf, gamma1_bits() + 1, gamma1()); } // FIPS 204, Algorithm 29 (`SampleInBall`). @@ -1108,7 +1274,7 @@ void vector_expand_short(vector *s1, vector *s2, } // FIPS 204, Algorithm 34 (`ExpandMask`). -template +template void vector_expand_mask(vector *out, const uint8_t seed[kRhoPrimeBytes], size_t kappa) { assert(kappa + L <= 0x10000); @@ -1119,7 +1285,7 @@ void vector_expand_mask(vector *out, const uint8_t seed[kRhoPrimeBytes], size_t index = kappa + i; derived_seed[kRhoPrimeBytes] = index & 0xFF; derived_seed[kRhoPrimeBytes + 1] = (index >> 8) & 0xFF; - scalar_sample_mask(&out->v[i], derived_seed); + scalar_sample_mask(&out->v[i], derived_seed); } } @@ -1136,6 +1302,10 @@ void vector_encode(uint8_t *out, const vector *a, int bits) { for (int i = 0; i < K; i++) { scalar_encode_4(out + i * bits * kDegree / 8, &a->v[i]); } + } else if (bits == 6) { + for (int i = 0; i < K; i++) { + scalar_encode_6(out + i * bits * kDegree / 8, &a->v[i]); + } } else { assert(bits == 10); for (int i = 0; i < K; i++) { @@ -1179,8 +1349,8 @@ int vector_decode_signed(vector *out, const uint8_t *in, int bits, // FIPS 204, Algorithm 28 (`w1Encode`). template -void w1_encode(uint8_t out[128 * K], const vector *w1) { - vector_encode(out, w1, 4); +void w1_encode(uint8_t out[w1_bytes()], const vector *w1) { + vector_encode(out, w1, w1_coeffs_bits()); } // FIPS 204, Algorithm 20 (`HintBitPack`). @@ -1364,10 +1534,11 @@ int mldsa_marshal_signature(CBB *out, const struct signature *sign) { } uint8_t *vectorl_output; - if (!CBB_add_space(out, &vectorl_output, 640 * L)) { + if (!CBB_add_space(out, &vectorl_output, scalar_le_gamma1_bytes() * L)) { return 0; } - vector_encode_signed(vectorl_output, &sign->z, 20, 1 << 19); + vector_encode_signed(vectorl_output, &sign->z, gamma1_bits() + 1, + gamma1()); uint8_t *hint_output; if (!CBB_add_space(out, &hint_output, omega() + K)) { @@ -1384,9 +1555,10 @@ int mldsa_parse_signature(struct signature *sign, CBS *in) { CBS z_bytes; CBS hint_bytes; if (!CBS_copy_bytes(in, sign->c_tilde, sizeof(sign->c_tilde)) || - !CBS_get_bytes(in, &z_bytes, 640 * L) || - // Note: Decoding 20 bits into (-2^19, 2^19] cannot fail. - !vector_decode_signed(&sign->z, CBS_data(&z_bytes), 20, 1 << 19) || + !CBS_get_bytes(in, &z_bytes, scalar_le_gamma1_bytes() * L) || + // Note: Decoding b+1 bits into (-2^b, 2^b] cannot fail. + !vector_decode_signed(&sign->z, CBS_data(&z_bytes), gamma1_bits() + 1, + gamma1()) || !CBS_get_bytes(in, &hint_bytes, omega() + K) || !hint_bit_unpack(&sign->h, CBS_data(&hint_bytes))) { return 0; @@ -1561,7 +1733,7 @@ int mldsa_sign_mu( // kappa must not exceed 2**16/L = 13107. But the probability of it // exceeding even 1000 iterations is vanishingly small. for (size_t kappa = 0;; kappa += L) { - vector_expand_mask(&values->y, rho_prime, kappa); + vector_expand_mask(&values->y, rho_prime, kappa); vector *y_ntt = &values->cs1; OPENSSL_memcpy(y_ntt, &values->y, sizeof(*y_ntt)); @@ -1571,12 +1743,12 @@ int mldsa_sign_mu( vector_inverse_ntt(&values->w); vector_high_bits(&values->w1, &values->w); - uint8_t w1_encoded[128 * K]; + uint8_t w1_encoded[w1_bytes()]; w1_encode(w1_encoded, &values->w1); BORINGSSL_keccak_init(&keccak_ctx, boringssl_shake256); BORINGSSL_keccak_absorb(&keccak_ctx, mu, kMuBytes); - BORINGSSL_keccak_absorb(&keccak_ctx, w1_encoded, 128 * K); + BORINGSSL_keccak_absorb(&keccak_ctx, w1_encoded, w1_bytes()); BORINGSSL_keccak_squeeze(&keccak_ctx, values->sign.c_tilde, 2 * lambda_bytes()); @@ -1609,7 +1781,7 @@ int mldsa_sign_mu( uint32_t r0_max = vector_max_signed(r0); if (constant_time_declassify_w( constant_time_ge_w(z_max, gamma1() - beta()) | - constant_time_ge_w(r0_max, kGamma2 - beta()))) { + constant_time_ge_w(r0_max, gamma2() - beta()))) { #if defined(BORINGSSL_FIPS_BREAK_TESTS) // In order to show that our self-tests trigger both restart cases in // this loop, printf-logging is added when built in break-test mode. @@ -1626,7 +1798,7 @@ int mldsa_sign_mu( // See above. uint32_t ct0_max = vector_max(ct0); size_t h_ones = vector_count_ones(&values->sign.h); - if (constant_time_declassify_w(constant_time_ge_w(ct0_max, kGamma2) | + if (constant_time_declassify_w(constant_time_ge_w(ct0_max, gamma2()) | constant_time_lt_w(omega(), h_ones))) { #if defined(BORINGSSL_FIPS_BREAK_TESTS) // In order to show that our self-tests trigger both restart cases in @@ -1778,13 +1950,13 @@ int mldsa_verify_internal_no_self_test( vector_inverse_ntt(w1); vector_use_hint_vartime(w1, &values->sign.h, w1); - uint8_t w1_encoded[128 * K]; + uint8_t w1_encoded[w1_bytes()]; w1_encode(w1_encoded, w1); uint8_t c_tilde[2 * lambda_bytes()]; BORINGSSL_keccak_init(&keccak_ctx, boringssl_shake256); BORINGSSL_keccak_absorb(&keccak_ctx, mu, kMuBytes); - BORINGSSL_keccak_absorb(&keccak_ctx, w1_encoded, 128 * K); + BORINGSSL_keccak_absorb(&keccak_ctx, w1_encoded, w1_bytes()); BORINGSSL_keccak_squeeze(&keccak_ctx, c_tilde, 2 * lambda_bytes()); uint32_t z_max = vector_max(&values->sign.z); @@ -1871,6 +2043,39 @@ struct prehash_context *prehash_context_from_external_87( return reinterpret_cast(external); } +struct private_key<4, 4> *private_key_from_external_44( + const struct BCM_mldsa44_private_key *external) { + static_assert(sizeof(struct BCM_mldsa44_private_key) == + sizeof(struct private_key<4, 4>), + "MLDSA44 private key size incorrect"); + static_assert(alignof(struct BCM_mldsa44_private_key) == + alignof(struct private_key<4, 4>), + "MLDSA44 private key alignment incorrect"); + return (struct private_key<4, 4> *)external; +} + +struct public_key<4> *public_key_from_external_44( + const struct BCM_mldsa44_public_key *external) { + static_assert( + sizeof(struct BCM_mldsa44_public_key) == sizeof(struct public_key<4>), + "MLDSA44 public key size incorrect"); + static_assert( + alignof(struct BCM_mldsa44_public_key) == alignof(struct public_key<4>), + "MLDSA44 public key alignment incorrect"); + return (struct public_key<4> *)external; +} + +struct prehash_context *prehash_context_from_external_44( + struct BCM_mldsa44_prehash *external) { + static_assert( + sizeof(struct BCM_mldsa44_prehash) == sizeof(struct prehash_context), + "MLDSA pre-hash context size incorrect"); + static_assert( + alignof(struct BCM_mldsa44_prehash) == alignof(struct prehash_context), + "MLDSA pre-hash context alignment incorrect"); + return reinterpret_cast(external); +} + namespace fips { #include "fips_known_values.inc" @@ -2442,6 +2647,209 @@ bcm_status BCM_mldsa87_marshal_public_key( out, mldsa::public_key_from_external_87(public_key))); } + +// ML-DSA-44 specific wrappers. + +bcm_status BCM_mldsa44_parse_public_key( + struct BCM_mldsa44_public_key *public_key, CBS *in) { + return bcm_as_approved_status(mldsa_parse_public_key( + mldsa::public_key_from_external_44(public_key), in)); +} + +bcm_status BCM_mldsa44_marshal_private_key( + CBB *out, const struct BCM_mldsa44_private_key *private_key) { + return bcm_as_approved_status(mldsa_marshal_private_key( + out, mldsa::private_key_from_external_44(private_key))); +} + +bcm_status BCM_mldsa44_parse_private_key( + struct BCM_mldsa44_private_key *private_key, CBS *in) { + return bcm_as_approved_status( + mldsa_parse_private_key(mldsa::private_key_from_external_44(private_key), + in) && + CBS_len(in) == 0); +} + +bcm_status BCM_mldsa44_check_key_fips( + struct BCM_mldsa44_private_key *private_key) { + return bcm_as_approved_status( + mldsa::fips::check_key(mldsa::private_key_from_external_44(private_key))); +} + +// Calls |MLDSA_generate_key_external_entropy| with random bytes from +// |BCM_rand_bytes|. +bcm_status BCM_mldsa44_generate_key( + uint8_t out_encoded_public_key[BCM_MLDSA44_PUBLIC_KEY_BYTES], + uint8_t out_seed[BCM_MLDSA_SEED_BYTES], + struct BCM_mldsa44_private_key *out_private_key) { + BCM_rand_bytes(out_seed, BCM_MLDSA_SEED_BYTES); + return BCM_mldsa44_generate_key_external_entropy(out_encoded_public_key, + out_private_key, out_seed); +} + +bcm_status BCM_mldsa44_private_key_from_seed( + struct BCM_mldsa44_private_key *out_private_key, + const uint8_t seed[BCM_MLDSA_SEED_BYTES]) { + uint8_t public_key[BCM_MLDSA44_PUBLIC_KEY_BYTES]; + return BCM_mldsa44_generate_key_external_entropy(public_key, out_private_key, + seed); +} + +bcm_status BCM_mldsa44_generate_key_external_entropy( + uint8_t out_encoded_public_key[BCM_MLDSA44_PUBLIC_KEY_BYTES], + struct BCM_mldsa44_private_key *out_private_key, + const uint8_t entropy[BCM_MLDSA_SEED_BYTES]) { + return bcm_as_not_approved_status(mldsa_generate_key_external_entropy( + out_encoded_public_key, + mldsa::private_key_from_external_44(out_private_key), entropy)); +} + +bcm_status BCM_mldsa44_generate_key_fips( + uint8_t out_encoded_public_key[BCM_MLDSA44_PUBLIC_KEY_BYTES], + uint8_t out_seed[BCM_MLDSA_SEED_BYTES], + struct BCM_mldsa44_private_key *out_private_key) { + if (out_encoded_public_key == nullptr || out_private_key == nullptr) { + return bcm_status::failure; + } + if (BCM_mldsa44_generate_key(out_encoded_public_key, out_seed, + out_private_key) == bcm_status::failure) { + return bcm_status::failure; + } + return BCM_mldsa44_check_key_fips(out_private_key); +} + +bcm_status BCM_mldsa44_generate_key_external_entropy_fips( + uint8_t out_encoded_public_key[BCM_MLDSA44_PUBLIC_KEY_BYTES], + struct BCM_mldsa44_private_key *out_private_key, + const uint8_t entropy[BCM_MLDSA_SEED_BYTES]) { + if (out_encoded_public_key == nullptr || out_private_key == nullptr) { + return bcm_status::failure; + } + if (BCM_mldsa44_generate_key_external_entropy(out_encoded_public_key, + out_private_key, entropy) == + bcm_status::failure) { + return bcm_status::failure; + } + return BCM_mldsa44_check_key_fips(out_private_key); +} + +bcm_status BCM_mldsa44_private_key_from_seed_fips( + struct BCM_mldsa44_private_key *out_private_key, + const uint8_t seed[BCM_MLDSA_SEED_BYTES]) { + uint8_t public_key[BCM_MLDSA44_PUBLIC_KEY_BYTES]; + if (BCM_mldsa44_generate_key_external_entropy(public_key, out_private_key, + seed) == bcm_status::failure) { + return bcm_status::failure; + } + return BCM_mldsa44_check_key_fips(out_private_key); +} + +bcm_status BCM_mldsa44_public_from_private( + struct BCM_mldsa44_public_key *out_public_key, + const struct BCM_mldsa44_private_key *private_key) { + return bcm_as_approved_status(mldsa_public_from_private( + mldsa::public_key_from_external_44(out_public_key), + mldsa::private_key_from_external_44(private_key))); +} + +bcm_status BCM_mldsa44_sign_internal( + uint8_t out_encoded_signature[BCM_MLDSA44_SIGNATURE_BYTES], + const struct BCM_mldsa44_private_key *private_key, const uint8_t *msg, + size_t msg_len, const uint8_t *context_prefix, size_t context_prefix_len, + const uint8_t *context, size_t context_len, + const uint8_t randomizer[BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES]) { + return bcm_as_approved_status(mldsa_sign_internal( + out_encoded_signature, mldsa::private_key_from_external_44(private_key), + msg, msg_len, context_prefix, context_prefix_len, context, context_len, + randomizer)); +} + +// ML-DSA signature in randomized mode, filling the random bytes with +// |BCM_rand_bytes|. +bcm_status BCM_mldsa44_sign( + uint8_t out_encoded_signature[BCM_MLDSA44_SIGNATURE_BYTES], + const struct BCM_mldsa44_private_key *private_key, const uint8_t *msg, + size_t msg_len, const uint8_t *context, size_t context_len) { + BSSL_CHECK(context_len <= 255); + uint8_t randomizer[BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES]; + BCM_rand_bytes(randomizer, sizeof(randomizer)); + + const uint8_t context_prefix[2] = {0, static_cast(context_len)}; + return BCM_mldsa44_sign_internal( + out_encoded_signature, private_key, msg, msg_len, context_prefix, + sizeof(context_prefix), context, context_len, randomizer); +} + +// ML-DSA pre-hashed API: initializing a pre-hashing context. +void BCM_mldsa44_prehash_init(struct BCM_mldsa44_prehash *out_prehash_ctx, + const struct BCM_mldsa44_public_key *public_key, + const uint8_t *context, size_t context_len) { + BSSL_CHECK(context_len <= 255); + + const uint8_t context_prefix[2] = {0, static_cast(context_len)}; + mldsa_prehash_init(mldsa::prehash_context_from_external_44(out_prehash_ctx), + mldsa::public_key_from_external_44(public_key), + context_prefix, sizeof(context_prefix), context, + context_len); +} + +// ML-DSA pre-hashed API: updating a pre-hashing context with a message chunk. +void BCM_mldsa44_prehash_update(struct BCM_mldsa44_prehash *inout_prehash_ctx, + const uint8_t *msg, size_t msg_len) { + mldsa_prehash_update( + mldsa::prehash_context_from_external_44(inout_prehash_ctx), msg, msg_len); +} + +// ML-DSA pre-hashed API: obtaining a message representative to sign. +void BCM_mldsa44_prehash_finalize( + uint8_t out_msg_rep[BCM_MLDSA_MU_BYTES], + struct BCM_mldsa44_prehash *inout_prehash_ctx) { + mldsa_prehash_finalize( + out_msg_rep, mldsa::prehash_context_from_external_44(inout_prehash_ctx)); +} + +// ML-DSA pre-hashed API: signing a message representative. +bcm_status BCM_mldsa44_sign_message_representative( + uint8_t out_encoded_signature[BCM_MLDSA44_SIGNATURE_BYTES], + const struct BCM_mldsa44_private_key *private_key, + const uint8_t msg_rep[BCM_MLDSA_MU_BYTES]) { + uint8_t randomizer[BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES]; + BCM_rand_bytes(randomizer, sizeof(randomizer)); + CONSTTIME_SECRET(randomizer, sizeof(randomizer)); + + return bcm_as_approved_status(mldsa_sign_mu( + out_encoded_signature, mldsa::private_key_from_external_44(private_key), + msg_rep, randomizer)); +} + +// FIPS 204, Algorithm 3 (`ML-DSA.Verify`). +bcm_status BCM_mldsa44_verify(const struct BCM_mldsa44_public_key *public_key, + const uint8_t *signature, const uint8_t *msg, + size_t msg_len, const uint8_t *context, + size_t context_len) { + BSSL_CHECK(context_len <= 255); + const uint8_t context_prefix[2] = {0, static_cast(context_len)}; + return BCM_mldsa44_verify_internal(public_key, signature, msg, msg_len, + context_prefix, sizeof(context_prefix), + context, context_len); +} + +bcm_status BCM_mldsa44_verify_internal( + const struct BCM_mldsa44_public_key *public_key, + const uint8_t encoded_signature[BCM_MLDSA44_SIGNATURE_BYTES], + const uint8_t *msg, size_t msg_len, const uint8_t *context_prefix, + size_t context_prefix_len, const uint8_t *context, size_t context_len) { + return bcm_as_approved_status(mldsa::mldsa_verify_internal<4, 4>( + mldsa::public_key_from_external_44(public_key), encoded_signature, msg, + msg_len, context_prefix, context_prefix_len, context, context_len)); +} + +bcm_status BCM_mldsa44_marshal_public_key( + CBB *out, const struct BCM_mldsa44_public_key *public_key) { + return bcm_as_approved_status(mldsa_marshal_public_key( + out, mldsa::public_key_from_external_44(public_key))); +} + int boringssl_self_test_mldsa() { return mldsa::fips::keygen_self_test() && mldsa::fips::sign_self_test() && mldsa::fips::verify_self_test(); diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/rand/ctrdrbg.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/rand/ctrdrbg.cc.inc index 72590382f..231c0bb46 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/rand/ctrdrbg.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/rand/ctrdrbg.cc.inc @@ -17,6 +17,7 @@ #include #include +#include #include "../aes/internal.h" #include "../service_indicator/internal.h" @@ -26,8 +27,122 @@ // Section references in this file refer to SP 800-90Ar1: // http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf -// See table 3. -static const uint64_t kMaxReseedCount = UINT64_C(1) << 48; +// Also see table 3. +constexpr uint64_t kMaxReseedCount = UINT64_C(1) << 48; + +// Implements the BCC function as described in Section 10.3.3. +static void bcc(uint8_t out[AES_BLOCK_SIZE], const AES_KEY *aes_key, + const uint8_t *data, size_t data_len) { + // 1. chaining_value = 0^outlen. + uint8_t *chaining_value = out; + OPENSSL_memset(chaining_value, 0, AES_BLOCK_SIZE); + + // 2. n = len (data)/outlen. + BSSL_CHECK(data_len % AES_BLOCK_SIZE == 0); + const size_t n = data_len / AES_BLOCK_SIZE; + + for (size_t i = 0; i < n; i++) { + const uint8_t *block = data + (i * AES_BLOCK_SIZE); + uint8_t input_block[AES_BLOCK_SIZE]; + + // 4.1: input_block = chaining_value ⊕ block_i. + CRYPTO_xor16(input_block, chaining_value, block); + + // 4.2: chaining_value = Block_Encrypt (Key, input_block). + BCM_aes_encrypt(input_block, chaining_value, aes_key); + } + + // 5. output_block = chaining_value. +} + +// Implements the derivation function as described in Section 10.3.2. +static int block_cipher_df(uint8_t *out, size_t out_len, const uint8_t *input, + size_t input_len) { + // Constants for AES-256 + constexpr size_t kAESKeyLen = 32; + constexpr size_t kAESOutLen = AES_BLOCK_SIZE; + constexpr size_t kMaxNumBits = 512; + + if (out_len > kMaxNumBits / 8 || input_len > (1u << 30)) { + return 0; + } + + // 4. S = L || N || input_string || 0x80. + const size_t s_rawlen = sizeof(uint32_t) + sizeof(uint32_t) + input_len + 1; + // S is padded up to a block size. + const size_t s_len = (s_rawlen + kAESOutLen - 1) & ~(kAESOutLen - 1); + uint8_t iv_plus_s[/* space used below */ kAESOutLen + 4 + 4 + + CTR_DRBG_MAX_ENTROPY_LEN + CTR_DRBG_NONCE_LEN + + CTR_DRBG_SEED_LEN + 1 + + /* padding */ 7]; + if (kAESOutLen + s_len > sizeof(iv_plus_s)) { + return 0; + } + OPENSSL_memset(iv_plus_s, 0, sizeof(iv_plus_s)); + uint8_t *s_ptr = iv_plus_s + kAESOutLen; + // 2. L = len (input_string)/8. + CRYPTO_store_u32_be(s_ptr, (uint32_t)input_len); + s_ptr += sizeof(uint32_t); + // 3. N = number_of_bits_to_return/8. + CRYPTO_store_u32_be(s_ptr, (uint32_t)out_len); + s_ptr += sizeof(uint32_t); + OPENSSL_memcpy(s_ptr, input, input_len); + s_ptr += input_len; + *s_ptr = 0x80; + + uint8_t temp[kAESKeyLen + kAESOutLen]; + size_t temp_len = 0; + + // 8. K = leftmost (0x00010203...1D1E1F, keylen). + static const uint8_t kInitialKey[kAESKeyLen] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, + 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f}; + AES_KEY aes_key; + bcm_status status = + BCM_aes_set_encrypt_key(kInitialKey, 8 * sizeof(kInitialKey), &aes_key); + BSSL_CHECK(status != bcm_status::failure); + + // 7. i = 0. + uint32_t i = 0; + while (temp_len < sizeof(temp)) { + // 9.1 IV = i || 0^(outlen - len(i)). + CRYPTO_store_u32_be(iv_plus_s, i); + + // 9.2 temp = temp || BCC (K, (IV || S)). + bcc(temp + temp_len, &aes_key, iv_plus_s, kAESOutLen + s_len); + temp_len += kAESOutLen; + + // 9.3 i = i + 1. + i++; + } + + // 10. K = leftmost (temp, keylen). + uint8_t *const k = temp; + + // 11. X = select (temp, keylen+1, keylen+outlen). + uint8_t *const x = temp + kAESKeyLen; + + // 12. temp = the Null string. + temp_len = 0; + + // Create an AES key schedule for the final encryption steps. + status = BCM_aes_set_encrypt_key(k, kAESKeyLen * 8, &aes_key); + BSSL_CHECK(status != bcm_status::failure); + + // 13. While len (temp) < number_of_bits_to_return, do: + while (temp_len < out_len) { + // 13.1 X = Block_Encrypt (K, X). + BCM_aes_encrypt(x, x, &aes_key); + + // 13.2 temp = temp || X. + size_t to_copy = std::min(kAESOutLen, out_len - temp_len); + OPENSSL_memcpy(out + temp_len, x, to_copy); + temp_len += to_copy; + } + + return 1; +} CTR_DRBG_STATE *CTR_DRBG_new(const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], const uint8_t *personalization, @@ -35,7 +150,24 @@ CTR_DRBG_STATE *CTR_DRBG_new(const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], CTR_DRBG_STATE *drbg = reinterpret_cast( OPENSSL_malloc(sizeof(CTR_DRBG_STATE))); if (drbg == NULL || - !CTR_DRBG_init(drbg, entropy, personalization, personalization_len)) { + !CTR_DRBG_init(drbg, /*df=*/false, entropy, CTR_DRBG_ENTROPY_LEN, + /*nonce=*/nullptr, personalization, personalization_len)) { + CTR_DRBG_free(drbg); + return NULL; + } + + return drbg; +} + +CTR_DRBG_STATE *CTR_DRBG_new_df(const uint8_t *entropy, size_t entropy_len, + const uint8_t nonce[CTR_DRBG_NONCE_LEN], + const uint8_t *personalization, + size_t personalization_len) { + CTR_DRBG_STATE *drbg = reinterpret_cast( + OPENSSL_malloc(sizeof(CTR_DRBG_STATE))); + if (drbg == NULL || + !CTR_DRBG_init(drbg, /*df=*/true, entropy, entropy_len, nonce, + personalization, personalization_len)) { CTR_DRBG_free(drbg); return NULL; } @@ -45,26 +177,45 @@ CTR_DRBG_STATE *CTR_DRBG_new(const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], void CTR_DRBG_free(CTR_DRBG_STATE *state) { OPENSSL_free(state); } -int CTR_DRBG_init(CTR_DRBG_STATE *drbg, - const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], +int CTR_DRBG_init(CTR_DRBG_STATE *drbg, int df, const uint8_t *entropy, + size_t entropy_len, const uint8_t nonce[CTR_DRBG_NONCE_LEN], const uint8_t *personalization, size_t personalization_len) { - // Section 10.2.1.3.1 - if (personalization_len > CTR_DRBG_ENTROPY_LEN) { + // Section 10.2.1.3.1 and 10.2.1.3.2 + if (personalization_len > CTR_DRBG_SEED_LEN || + (!df && entropy_len != CTR_DRBG_ENTROPY_LEN) || + (df && (entropy_len < CTR_DRBG_MIN_ENTROPY_LEN || + entropy_len > CTR_DRBG_MAX_ENTROPY_LEN)) || // + (df != (nonce != nullptr))) { return 0; } - uint8_t seed_material[CTR_DRBG_ENTROPY_LEN]; - OPENSSL_memcpy(seed_material, entropy, CTR_DRBG_ENTROPY_LEN); - - for (size_t i = 0; i < personalization_len; i++) { - seed_material[i] ^= personalization[i]; + uint8_t seed_material[CTR_DRBG_SEED_LEN]; + if (df) { + uint8_t pre_seed_material[CTR_DRBG_MAX_ENTROPY_LEN + CTR_DRBG_NONCE_LEN + + CTR_DRBG_SEED_LEN]; + OPENSSL_memcpy(pre_seed_material, entropy, entropy_len); + OPENSSL_memcpy(pre_seed_material + entropy_len, nonce, CTR_DRBG_NONCE_LEN); + OPENSSL_memcpy(pre_seed_material + entropy_len + CTR_DRBG_NONCE_LEN, + personalization, personalization_len); + const size_t pre_seed_material_length = + entropy_len + CTR_DRBG_NONCE_LEN + personalization_len; + + if (!block_cipher_df(seed_material, sizeof(seed_material), + pre_seed_material, pre_seed_material_length)) { + return 0; + } + } else { + OPENSSL_memcpy(seed_material, entropy, CTR_DRBG_ENTROPY_LEN); + for (size_t i = 0; i < personalization_len; i++) { + seed_material[i] ^= personalization[i]; + } } // Section 10.2.1.2 // kInitMask is the result of encrypting blocks with big-endian value 1, 2 // and 3 with the all-zero AES-256 key. - static const uint8_t kInitMask[CTR_DRBG_ENTROPY_LEN] = { + static const uint8_t kInitMask[CTR_DRBG_SEED_LEN] = { 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9, 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b, 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e, 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18, 0x72, 0x60, 0x03, 0xca, @@ -75,6 +226,7 @@ int CTR_DRBG_init(CTR_DRBG_STATE *drbg, seed_material[i] ^= kInitMask[i]; } + drbg->df = df; drbg->ctr = aes_ctr_set_key(&drbg->ks, NULL, &drbg->block, seed_material, 32); OPENSSL_memcpy(drbg->counter, seed_material + 32, 16); drbg->reseed_counter = 1; @@ -82,7 +234,7 @@ int CTR_DRBG_init(CTR_DRBG_STATE *drbg, return 1; } -static_assert(CTR_DRBG_ENTROPY_LEN % AES_BLOCK_SIZE == 0, +static_assert(CTR_DRBG_SEED_LEN % AES_BLOCK_SIZE == 0, "not a multiple of AES block size"); // ctr_inc adds |n| to the last four bytes of |drbg->counter|, treated as a @@ -92,22 +244,15 @@ static void ctr32_add(CTR_DRBG_STATE *drbg, uint32_t n) { CRYPTO_store_u32_be(drbg->counter + 12, ctr + n); } -static int ctr_drbg_update(CTR_DRBG_STATE *drbg, const uint8_t *data, - size_t data_len) { - // Per section 10.2.1.2, |data_len| must be |CTR_DRBG_ENTROPY_LEN|. Here, we - // allow shorter inputs and right-pad them with zeros. This is equivalent to - // the specified algorithm but saves a copy in |CTR_DRBG_generate|. - if (data_len > CTR_DRBG_ENTROPY_LEN) { - return 0; - } - - uint8_t temp[CTR_DRBG_ENTROPY_LEN]; - for (size_t i = 0; i < CTR_DRBG_ENTROPY_LEN; i += AES_BLOCK_SIZE) { +static int ctr_drbg_update(CTR_DRBG_STATE *drbg, + const uint8_t data[CTR_DRBG_SEED_LEN]) { + uint8_t temp[CTR_DRBG_SEED_LEN]; + for (size_t i = 0; i < CTR_DRBG_SEED_LEN; i += AES_BLOCK_SIZE) { ctr32_add(drbg, 1); drbg->block(drbg->counter, temp + i, &drbg->ks); } - for (size_t i = 0; i < data_len; i++) { + for (size_t i = 0; i < CTR_DRBG_SEED_LEN; i++) { temp[i] ^= data[i]; } @@ -121,23 +266,46 @@ int CTR_DRBG_reseed(CTR_DRBG_STATE *drbg, const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], const uint8_t *additional_data, size_t additional_data_len) { - // Section 10.2.1.4 - uint8_t entropy_copy[CTR_DRBG_ENTROPY_LEN]; + return CTR_DRBG_reseed_ex(drbg, entropy, CTR_DRBG_ENTROPY_LEN, + additional_data, additional_data_len); +} + +int CTR_DRBG_reseed_ex(CTR_DRBG_STATE *drbg, const uint8_t *entropy, + size_t entropy_len, const uint8_t *additional_data, + size_t additional_data_len) { + if (additional_data_len > CTR_DRBG_SEED_LEN || + (drbg->df && (entropy_len > CTR_DRBG_MAX_ENTROPY_LEN || + entropy_len < CTR_DRBG_MIN_ENTROPY_LEN)) || + (!drbg->df && entropy_len != CTR_DRBG_ENTROPY_LEN)) { + return 0; + } - if (additional_data_len > 0) { - if (additional_data_len > CTR_DRBG_ENTROPY_LEN) { + uint8_t seed_material[CTR_DRBG_SEED_LEN]; + if (drbg->df) { + // Section 10.2.1.4.2 + uint8_t pre_seed_material[CTR_DRBG_MAX_ENTROPY_LEN + CTR_DRBG_SEED_LEN]; + static_assert(CTR_DRBG_MAX_ENTROPY_LEN <= sizeof(pre_seed_material)); + OPENSSL_memcpy(pre_seed_material, entropy, entropy_len); + OPENSSL_memcpy(pre_seed_material + entropy_len, additional_data, + additional_data_len); + const size_t pre_seed_material_len = entropy_len + additional_data_len; + + if (!block_cipher_df(seed_material, sizeof(seed_material), + pre_seed_material, pre_seed_material_len)) { return 0; } - - OPENSSL_memcpy(entropy_copy, entropy, CTR_DRBG_ENTROPY_LEN); - for (size_t i = 0; i < additional_data_len; i++) { - entropy_copy[i] ^= additional_data[i]; + } else { + // Section 10.2.1.4 + static_assert(CTR_DRBG_ENTROPY_LEN == sizeof(seed_material)); + OPENSSL_memcpy(seed_material, entropy, CTR_DRBG_ENTROPY_LEN); + if (additional_data_len > 0) { + for (size_t i = 0; i < additional_data_len; i++) { + seed_material[i] ^= additional_data[i]; + } } - - entropy = entropy_copy; } - if (!ctr_drbg_update(drbg, entropy, CTR_DRBG_ENTROPY_LEN)) { + if (!ctr_drbg_update(drbg, seed_material)) { return 0; } @@ -159,9 +327,26 @@ int CTR_DRBG_generate(CTR_DRBG_STATE *drbg, uint8_t *out, size_t out_len, return 0; } - if (additional_data_len != 0 && - !ctr_drbg_update(drbg, additional_data, additional_data_len)) { - return 0; + uint8_t processed_additional_data[CTR_DRBG_SEED_LEN]; + OPENSSL_memset(processed_additional_data, 0, + sizeof(processed_additional_data)); + if (additional_data_len != 0) { + if (drbg->df) { + if (!block_cipher_df(processed_additional_data, + sizeof(processed_additional_data), additional_data, + additional_data_len)) { + return 0; + } + } else { + if (additional_data_len > sizeof(processed_additional_data)) { + return 0; + } + OPENSSL_memcpy(processed_additional_data, additional_data, + additional_data_len); + } + if (!ctr_drbg_update(drbg, processed_additional_data)) { + return 0; + } } // kChunkSize is used to interact better with the cache. Since the AES-CTR @@ -170,7 +355,7 @@ int CTR_DRBG_generate(CTR_DRBG_STATE *drbg, uint8_t *out, size_t out_len, // the whole buffer, flushing the L1 cache, and then do another pass (missing // the cache every time) to “encrypt” it. The code can avoid this by // chunking. - static const size_t kChunkSize = 8 * 1024; + constexpr size_t kChunkSize = 8 * 1024; while (out_len >= AES_BLOCK_SIZE) { size_t todo = kChunkSize; @@ -198,9 +383,7 @@ int CTR_DRBG_generate(CTR_DRBG_STATE *drbg, uint8_t *out, size_t out_len, OPENSSL_memcpy(out, block, out_len); } - // Right-padding |additional_data| in step 2.2 is handled implicitly by - // |ctr_drbg_update|, to save a copy. - if (!ctr_drbg_update(drbg, additional_data, additional_data_len)) { + if (!ctr_drbg_update(drbg, processed_additional_data)) { return 0; } diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/rand/internal.h b/Sources/CCryptoBoringSSL/crypto/fipsmodule/rand/internal.h index 2d2262939..3913ff8df 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/rand/internal.h +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/rand/internal.h @@ -37,14 +37,19 @@ struct ctr_drbg_state_st { ctr128_f ctr; uint8_t counter[16]; uint64_t reseed_counter; + int df; }; -// CTR_DRBG_init initialises |*drbg| given |CTR_DRBG_ENTROPY_LEN| bytes of -// entropy in |entropy| and, optionally, a personalization string up to -// |CTR_DRBG_ENTROPY_LEN| bytes in length. It returns one on success and zero -// on error. -OPENSSL_EXPORT int CTR_DRBG_init(CTR_DRBG_STATE *drbg, - const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], +// CTR_DRBG_init initialises |*drbg| given |entropy_len| bytes of entropy in +// |entropy| and, optionally, a personalization string up to +// |CTR_DRBG_SEED_LEN| bytes in length. It returns one on success and zero on +// error. +// +// If `df` is false then `entropy_len` must be |CTR_DRBG_ENTROPY_LEN| and +// |nonce| must be nullptr. +OPENSSL_EXPORT int CTR_DRBG_init(CTR_DRBG_STATE *drbg, int df, + const uint8_t *entropy, size_t entropy_len, + const uint8_t nonce[CTR_DRBG_NONCE_LEN], const uint8_t *personalization, size_t personalization_len); diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/rand/rand.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/rand/rand.cc.inc index 96e7381e6..82cc41c42 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/rand/rand.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/rand/rand.cc.inc @@ -187,8 +187,7 @@ bcm_status BCM_rand_bytes_hwrng(uint8_t *buf, const size_t len) { struct entropy_buffer { // bytes contains entropy suitable for seeding a DRBG. - uint8_t - bytes[CRNGT_BLOCK_SIZE + CTR_DRBG_ENTROPY_LEN * BORINGSSL_FIPS_OVERREAD]; + uint8_t bytes[CRNGT_BLOCK_SIZE + CTR_DRBG_SEED_LEN * BORINGSSL_FIPS_OVERREAD]; // bytes_valid indicates the number of bytes of |bytes| that contain valid // data. size_t bytes_valid; @@ -250,11 +249,11 @@ static void get_seed_entropy(uint8_t *out_entropy, size_t out_entropy_len, // fill |additional_input| with entropy to supplement |seed|. It sets // |*out_additional_input_len| to the number of extra bytes. static void rand_get_seed(struct rand_thread_state *state, - uint8_t seed[CTR_DRBG_ENTROPY_LEN], - uint8_t additional_input[CTR_DRBG_ENTROPY_LEN], + uint8_t seed[CTR_DRBG_SEED_LEN], + uint8_t additional_input[CTR_DRBG_SEED_LEN], size_t *out_additional_input_len) { uint8_t entropy_bytes[sizeof(state->last_block) + - CTR_DRBG_ENTROPY_LEN * BORINGSSL_FIPS_OVERREAD]; + CTR_DRBG_SEED_LEN * BORINGSSL_FIPS_OVERREAD]; uint8_t *entropy = entropy_bytes; size_t entropy_len = sizeof(entropy_bytes); @@ -293,12 +292,12 @@ static void rand_get_seed(struct rand_thread_state *state, OPENSSL_memcpy(state->last_block, entropy + entropy_len - CRNGT_BLOCK_SIZE, CRNGT_BLOCK_SIZE); - assert(entropy_len == BORINGSSL_FIPS_OVERREAD * CTR_DRBG_ENTROPY_LEN); - OPENSSL_memcpy(seed, entropy, CTR_DRBG_ENTROPY_LEN); + assert(entropy_len == BORINGSSL_FIPS_OVERREAD * CTR_DRBG_SEED_LEN); + OPENSSL_memcpy(seed, entropy, CTR_DRBG_SEED_LEN); for (size_t i = 1; i < BORINGSSL_FIPS_OVERREAD; i++) { - for (size_t j = 0; j < CTR_DRBG_ENTROPY_LEN; j++) { - seed[j] ^= entropy[CTR_DRBG_ENTROPY_LEN * i + j]; + for (size_t j = 0; j < CTR_DRBG_SEED_LEN; j++) { + seed[j] ^= entropy[CTR_DRBG_SEED_LEN * i + j]; } } @@ -307,8 +306,8 @@ static void rand_get_seed(struct rand_thread_state *state, // hardware once the entropy pool has been initialized. *out_additional_input_len = 0; if (want_additional_input && - CRYPTO_sysrand_if_available(additional_input, CTR_DRBG_ENTROPY_LEN)) { - *out_additional_input_len = CTR_DRBG_ENTROPY_LEN; + CRYPTO_sysrand_if_available(additional_input, CTR_DRBG_SEED_LEN)) { + *out_additional_input_len = CTR_DRBG_SEED_LEN; } } @@ -318,12 +317,12 @@ static void rand_get_seed(struct rand_thread_state *state, // fill |additional_input| with entropy to supplement |seed|. It sets // |*out_additional_input_len| to the number of extra bytes. static void rand_get_seed(struct rand_thread_state *state, - uint8_t seed[CTR_DRBG_ENTROPY_LEN], - uint8_t additional_input[CTR_DRBG_ENTROPY_LEN], + uint8_t seed[CTR_DRBG_SEED_LEN], + uint8_t additional_input[CTR_DRBG_SEED_LEN], size_t *out_additional_input_len) { // If not in FIPS mode, we don't overread from the system entropy source and // we don't depend only on the hardware RDRAND. - CRYPTO_sysrand_for_seed(seed, CTR_DRBG_ENTROPY_LEN); + CRYPTO_sysrand_for_seed(seed, CTR_DRBG_SEED_LEN); *out_additional_input_len = 0; } @@ -384,13 +383,13 @@ bcm_infallible BCM_rand_bytes_with_additional_data( } state->last_block_valid = 0; - uint8_t seed[CTR_DRBG_ENTROPY_LEN]; - uint8_t personalization[CTR_DRBG_ENTROPY_LEN] = {0}; + uint8_t seed[CTR_DRBG_SEED_LEN]; + uint8_t personalization[CTR_DRBG_SEED_LEN] = {0}; size_t personalization_len = 0; rand_get_seed(state, seed, personalization, &personalization_len); - if (!CTR_DRBG_init(&state->drbg, seed, personalization, - personalization_len)) { + if (!CTR_DRBG_init(&state->drbg, /*df=*/true, seed, 32u, seed + 32, + personalization, personalization_len)) { abort(); } state->calls = 0; @@ -422,8 +421,8 @@ bcm_infallible BCM_rand_bytes_with_additional_data( // safety. The children must reseed to avoid working from the same PRNG // state. state->fork_unsafe_buffering != fork_unsafe_buffering) { - uint8_t seed[CTR_DRBG_ENTROPY_LEN]; - uint8_t reseed_additional_data[CTR_DRBG_ENTROPY_LEN] = {0}; + uint8_t seed[CTR_DRBG_SEED_LEN]; + uint8_t reseed_additional_data[CTR_DRBG_SEED_LEN] = {0}; size_t reseed_additional_data_len = 0; rand_get_seed(state, seed, reseed_additional_data, &reseed_additional_data_len); @@ -433,8 +432,9 @@ bcm_infallible BCM_rand_bytes_with_additional_data( // |rand_thread_state_clear_all|. CRYPTO_MUTEX_lock_read(&state->clear_drbg_lock); #endif - if (!CTR_DRBG_reseed(&state->drbg, seed, reseed_additional_data, - reseed_additional_data_len)) { + if (!CTR_DRBG_reseed_ex(&state->drbg, seed, sizeof(seed), + reseed_additional_data, + reseed_additional_data_len)) { abort(); } state->calls = 0; diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/padding.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/padding.cc.inc index 2bd0ba9c7..c796122e6 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/padding.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/padding.cc.inc @@ -178,16 +178,14 @@ int RSA_verify_PKCS1_PSS_mgf1(const RSA *rsa, const uint8_t *mHash, size_t emLen, maskedDBLen, salt_start; FIPS_service_indicator_lock_state(); - // Negative sLen has special meanings: - // -1 sLen == hLen - // -2 salt length is autorecovered from signature - // -N reserved size_t hLen = EVP_MD_size(Hash); - if (sLen == -1) { + if (sLen == RSA_PSS_SALTLEN_DIGEST) { sLen = (int)hLen; - } else if (sLen == -2) { - sLen = -2; - } else if (sLen < -2) { + } else if (sLen == RSA_PSS_SALTLEN_AUTO) { + // Leave |sLen| negative, which will trigger the logic below to recover and + // allow any salt length. + } else if (sLen < 0) { + // Other negative values are reserved. OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_CHECK_FAILED); goto err; } @@ -202,7 +200,7 @@ int RSA_verify_PKCS1_PSS_mgf1(const RSA *rsa, const uint8_t *mHash, EM++; emLen--; } - // |sLen| may be -2 for the non-standard salt length recovery mode. + // |sLen| may be negative for the non-standard salt length recovery mode. if (emLen < hLen + 2 || (sLen >= 0 && emLen < hLen + (size_t)sLen + 2)) { OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); goto err; @@ -299,16 +297,14 @@ int RSA_padding_add_PKCS1_PSS_mgf1(const RSA *rsa, unsigned char *EM, goto err; } - // Negative sLenRequested has special meanings: - // -1 sLen == hLen - // -2 salt length is maximized - // -N reserved size_t sLen; - if (sLenRequested == -1) { + if (sLenRequested == RSA_PSS_SALTLEN_DIGEST) { sLen = hLen; - } else if (sLenRequested == -2) { + } else if (sLenRequested == RSA_PSS_SALTLEN_AUTO) { + // Use the maximum possible salt length. sLen = emLen - hLen - 2; } else if (sLenRequested < 0) { + // Other negative values are reserved. OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_CHECK_FAILED); goto err; } else { diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/rsa.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/rsa.cc.inc index 3187658f1..0884e7d00 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/rsa.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/rsa.cc.inc @@ -18,6 +18,8 @@ #include #include +#include + #include #include #include @@ -276,12 +278,6 @@ void RSA_get0_factors(const RSA *rsa, const BIGNUM **out_p, } } -const RSA_PSS_PARAMS *RSA_get0_pss_params(const RSA *rsa) { - // We do not support the id-RSASSA-PSS key encoding. If we add support later, - // the |maskHash| field should be filled in for OpenSSL compatibility. - return NULL; -} - void RSA_get0_crt_params(const RSA *rsa, const BIGNUM **out_dmp1, const BIGNUM **out_dmq1, const BIGNUM **out_iqmp) { if (out_dmp1 != NULL) { @@ -875,8 +871,8 @@ static const BN_ULONG kSmallFactorsLimbs[] = {TOBN(0xc4309333, 0x3ef4e3e1), 0x000017b1}; DEFINE_LOCAL_DATA(BIGNUM, g_small_factors) { - out->d = (BN_ULONG *)kSmallFactorsLimbs; - out->width = OPENSSL_ARRAY_SIZE(kSmallFactorsLimbs); + out->d = const_cast(kSmallFactorsLimbs); + out->width = std::size(kSmallFactorsLimbs); out->dmax = out->width; out->neg = 0; out->flags = BN_FLG_STATIC_DATA; diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/rsa_impl.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/rsa_impl.cc.inc index 29c388970..8689e09b2 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/rsa_impl.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/rsa/rsa_impl.cc.inc @@ -18,6 +18,8 @@ #include #include +#include + #include #include #include @@ -840,7 +842,7 @@ const BN_ULONG kBoringSSLRSASqrtTwo[] = { TOBN(0xed17ac85, 0x83339915), TOBN(0x1d6f60ba, 0x893ba84c), TOBN(0x597d89b3, 0x754abe9f), TOBN(0xb504f333, 0xf9de6484), }; -const size_t kBoringSSLRSASqrtTwoLen = OPENSSL_ARRAY_SIZE(kBoringSSLRSASqrtTwo); +const size_t kBoringSSLRSASqrtTwoLen = std::size(kBoringSSLRSASqrtTwo); // generate_prime sets |out| to a prime with length |bits| such that |out|-1 is // relatively prime to |e|. If |p| is non-NULL, |out| will also not be close to @@ -1183,9 +1185,7 @@ static int RSA_generate_key_ex_maybe_fips(RSA *rsa, int bits, return 0; } - RSA *tmp = NULL; - uint32_t err; - int ret = 0; + bssl::UniquePtr tmp; // |rsa_generate_key_impl|'s 2^-20 failure probability is too high at scale, // so we run the FIPS algorithm four times, bringing it down to 2^-80. We @@ -1195,27 +1195,25 @@ static int RSA_generate_key_ex_maybe_fips(RSA *rsa, int bits, do { ERR_clear_error(); // Generate into scratch space, to avoid leaving partial work on failure. - tmp = RSA_new(); - if (tmp == NULL) { - goto out; + tmp.reset(RSA_new()); + if (tmp == nullptr) { + return 0; } - if (rsa_generate_key_impl(tmp, bits, e_value, cb)) { + if (rsa_generate_key_impl(tmp.get(), bits, e_value, cb)) { break; } - err = ERR_peek_error(); - RSA_free(tmp); - tmp = NULL; + tmp = nullptr; failures++; // Only retry on |RSA_R_TOO_MANY_ITERATIONS|. This is so a caller-induced // failure in |BN_GENCB_call| is still fatal. - } while (failures < 4 && ERR_GET_LIB(err) == ERR_LIB_RSA && - ERR_GET_REASON(err) == RSA_R_TOO_MANY_ITERATIONS); + } while (failures < 4 && ERR_equals(ERR_peek_error(), ERR_LIB_RSA, + RSA_R_TOO_MANY_ITERATIONS)); - if (tmp == NULL || (check_fips && !RSA_check_fips(tmp))) { - goto out; + if (tmp == nullptr || (check_fips && !RSA_check_fips(tmp.get()))) { + return 0; } rsa_invalidate_key(rsa); @@ -1235,11 +1233,7 @@ static int RSA_generate_key_ex_maybe_fips(RSA *rsa, int bits, replace_bignum(&rsa->dmq1_fixed, &tmp->dmq1_fixed); replace_bignum(&rsa->iqmp_mont, &tmp->iqmp_mont); rsa->private_key_frozen = tmp->private_key_frozen; - ret = 1; - -out: - RSA_free(tmp); - return ret; + return 1; } int RSA_generate_key_ex(RSA *rsa, int bits, const BIGNUM *e_value, diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/self_check/fips.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/self_check/fips.cc.inc index 187c38556..56f7e4b0b 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/self_check/fips.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/self_check/fips.cc.inc @@ -67,8 +67,8 @@ int FIPS_query_algorithm_status(const char *algorithm) { "SHA2-512", "SHA2-512/256", }; - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kApprovedAlgorithms); i++) { - if (strcmp(algorithm, kApprovedAlgorithms[i]) == 0) { + for (const char *approved : kApprovedAlgorithms) { + if (strcmp(algorithm, approved) == 0) { return 1; } } diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/self_check/self_check.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/self_check/self_check.cc.inc index 2184d3ec2..6ab9abe98 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/self_check/self_check.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/self_check/self_check.cc.inc @@ -17,6 +17,8 @@ #include #include +#include + #include #include #include @@ -269,7 +271,7 @@ static DH *self_test_dh(void) { }; bn_set_static_words(priv, kFFDHE2048PrivateKeyData, - OPENSSL_ARRAY_SIZE(kFFDHE2048PrivateKeyData)); + std::size(kFFDHE2048PrivateKeyData)); if (!DH_set0_key(dh, NULL, priv)) { goto err; @@ -569,7 +571,7 @@ static int boringssl_self_test_ffdh(void) { ffdhe2048_value = BN_new(); if (ffdhe2048_value) { bn_set_static_words(ffdhe2048_value, kFFDHE2048PublicValueData, - OPENSSL_ARRAY_SIZE(kFFDHE2048PublicValueData)); + std::size(kFFDHE2048PublicValueData)); } dh = self_test_dh(); @@ -840,11 +842,14 @@ static int boringssl_self_test_fast(void) { } // DBRG KAT - static const uint8_t kDRBGEntropy[48] = { - 0xc4, 0xda, 0x07, 0x40, 0xd5, 0x05, 0xf1, 0xee, 0x28, 0x0b, 0x95, 0xe5, - 0x8c, 0x49, 0x31, 0xac, 0x6d, 0xe8, 0x46, 0xa0, 0x15, 0x2f, 0xbb, 0x4a, - 0x3f, 0x17, 0x4c, 0xf4, 0x78, 0x7a, 0x4f, 0x1a, 0x40, 0xc2, 0xb5, 0x0b, - 0xab, 0xe1, 0x4a, 0xae, 0x53, 0x0b, 0xe5, 0x88, 0x6d, 0x91, 0x0a, 0x27, + static const uint8_t kDRBGEntropy[32] = { + 0xc4, 0xda, 0x07, 0x40, 0xd5, 0x05, 0xf1, 0xee, 0x28, 0x0b, 0x95, + 0xe5, 0x8c, 0x49, 0x31, 0xac, 0x6d, 0xe8, 0x46, 0xa0, 0x15, 0x2f, + 0xbb, 0x4a, 0x3f, 0x17, 0x4c, 0xf4, 0x78, 0x7a, 0x4f, 0x1a, + }; + static const uint8_t kDRBGNonce[CTR_DRBG_NONCE_LEN] = { + 0x40, 0xc2, 0xb5, 0x0b, 0xab, 0xe1, 0x4a, 0xae, + 0x53, 0x0b, 0xe5, 0x88, 0x6d, 0x91, 0x0a, 0x27, }; static const uint8_t kDRBGPersonalization[18] = { 'B', 'C', 'M', 'P', 'e', 'r', 's', 'o', 'n', @@ -852,12 +857,12 @@ static int boringssl_self_test_fast(void) { static const uint8_t kDRBGAD[16] = {'B', 'C', 'M', ' ', 'D', 'R', 'B', 'G', ' ', 'K', 'A', 'T', ' ', 'A', 'D', ' '}; static const uint8_t kDRBGOutput[64] = { - 0x19, 0x1f, 0x2b, 0x49, 0x76, 0x85, 0xfd, 0x51, 0xb6, 0x56, 0xbc, - 0x1c, 0x7d, 0xd5, 0xdd, 0x44, 0x76, 0xa3, 0x5e, 0x17, 0x9b, 0x8e, - 0xb8, 0x98, 0x65, 0x12, 0xca, 0x35, 0x6c, 0xa0, 0x6f, 0xa0, 0x22, - 0xe4, 0xf6, 0xd8, 0x43, 0xed, 0x4e, 0x2d, 0x97, 0x39, 0x43, 0x3b, - 0x57, 0xfc, 0x23, 0x3f, 0x71, 0x0a, 0xe0, 0xed, 0xfe, 0xd5, 0xb8, - 0x67, 0x7a, 0x00, 0x39, 0xb2, 0x6e, 0xa9, 0x25, 0x97, + 0x55, 0x88, 0x81, 0x88, 0x16, 0x49, 0x68, 0xd8, 0x23, 0xc8, 0x18, + 0x57, 0x5d, 0x06, 0xc3, 0x5f, 0x60, 0x3a, 0xe8, 0xfe, 0x7c, 0x7e, + 0x1c, 0x4a, 0x6a, 0xa8, 0x91, 0x07, 0xc0, 0x0d, 0x1f, 0x70, 0x4a, + 0xbb, 0x20, 0x42, 0xd3, 0x3f, 0x19, 0xf1, 0xb1, 0xfc, 0xef, 0xa1, + 0x71, 0xfd, 0xf7, 0xaf, 0xc5, 0x12, 0x7a, 0x98, 0xad, 0x42, 0xbc, + 0x01, 0xe6, 0xa2, 0x83, 0xbc, 0x73, 0xb5, 0xba, 0x84, }; static const uint8_t kDRBGEntropy2[48] = { 0xc7, 0x16, 0x1c, 0xa3, 0x6c, 0x23, 0x09, 0xb7, 0x16, 0xe9, 0x85, 0x9b, @@ -866,21 +871,23 @@ static int boringssl_self_test_fast(void) { 0x76, 0xc1, 0x86, 0xe9, 0x35, 0x18, 0x03, 0x76, 0x3a, 0x79, 0x12, 0xfe, }; static const uint8_t kDRBGReseedOutput[64] = { - 0x00, 0xf2, 0x05, 0xaa, 0xfd, 0x11, 0x6c, 0x77, 0xbc, 0x81, 0x86, - 0x99, 0xca, 0x51, 0xcf, 0x80, 0x15, 0x9f, 0x02, 0x9e, 0x0b, 0xcd, - 0x26, 0xc8, 0x4b, 0x87, 0x8a, 0x15, 0x1a, 0xdd, 0xf2, 0xf3, 0xeb, - 0x94, 0x0b, 0x08, 0xc8, 0xc9, 0x57, 0xa4, 0x0b, 0x4b, 0x0f, 0x13, - 0xde, 0x7c, 0x0c, 0x6a, 0xac, 0x34, 0x4a, 0x9a, 0xf2, 0xd0, 0x83, - 0x02, 0x05, 0x17, 0xc9, 0x81, 0x8f, 0x2a, 0x81, 0x92, + 0xda, 0x49, 0xa1, 0x01, 0x31, 0x71, 0x77, 0xde, 0xf6, 0x8d, 0xb5, + 0x4f, 0x86, 0x0d, 0xc8, 0xd6, 0x3c, 0xaa, 0xbc, 0x72, 0x0a, 0x9c, + 0x8b, 0x68, 0xa9, 0x70, 0xf1, 0x21, 0x13, 0xce, 0xc6, 0xbc, 0xff, + 0xaf, 0xa8, 0xd5, 0x26, 0x76, 0x26, 0xcc, 0x0d, 0x89, 0x66, 0xab, + 0xc2, 0x11, 0xa8, 0x2f, 0xf1, 0x36, 0xa3, 0x2b, 0x52, 0xcd, 0x1a, + 0x2d, 0xe4, 0x82, 0xac, 0x3c, 0xbb, 0xa9, 0x17, 0x90, }; CTR_DRBG_STATE drbg; - if (!CTR_DRBG_init(&drbg, kDRBGEntropy, kDRBGPersonalization, + if (!CTR_DRBG_init(&drbg, /*df=*/true, kDRBGEntropy, sizeof(kDRBGEntropy), + kDRBGNonce, kDRBGPersonalization, sizeof(kDRBGPersonalization)) || !CTR_DRBG_generate(&drbg, output, sizeof(kDRBGOutput), kDRBGAD, sizeof(kDRBGAD)) || !BORINGSSL_check_test(kDRBGOutput, output, sizeof(kDRBGOutput), "DRBG Generate KAT") || - !CTR_DRBG_reseed(&drbg, kDRBGEntropy2, kDRBGAD, sizeof(kDRBGAD)) || + !CTR_DRBG_reseed_ex(&drbg, kDRBGEntropy2, sizeof(kDRBGEntropy2), kDRBGAD, + sizeof(kDRBGAD)) || !CTR_DRBG_generate(&drbg, output, sizeof(kDRBGReseedOutput), kDRBGAD, sizeof(kDRBGAD)) || !BORINGSSL_check_test(kDRBGReseedOutput, output, diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/service_indicator/internal.h b/Sources/CCryptoBoringSSL/crypto/fipsmodule/service_indicator/internal.h index c5a8113c8..27f806036 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/service_indicator/internal.h +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/service_indicator/internal.h @@ -17,6 +17,9 @@ #include +#if defined(__cplusplus) +extern "C" { +#endif // FIPS_service_indicator_before_call and |FIPS_service_indicator_after_call| // both currently return the same local thread counter which is slowly @@ -37,6 +40,10 @@ OPENSSL_EXPORT uint64_t FIPS_service_indicator_before_call(void); OPENSSL_EXPORT uint64_t FIPS_service_indicator_after_call(void); +#if defined(__cplusplus) +} +#endif + #if defined(BORINGSSL_FIPS) // FIPS_service_indicator_update_state records that an approved service has been diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/service_indicator/service_indicator.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/service_indicator/service_indicator.cc.inc index 6f2e6c285..aed88be7a 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/service_indicator/service_indicator.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/service_indicator/service_indicator.cc.inc @@ -217,7 +217,8 @@ static void evp_md_ctx_verify_service_indicator(const EVP_MD_CTX *ctx, const EVP_MD *mgf1_md; if (!EVP_PKEY_CTX_get_rsa_pss_saltlen(pctx, &salt_len) || !EVP_PKEY_CTX_get_rsa_mgf1_md(pctx, &mgf1_md) || - (salt_len != -1 && salt_len != (int)EVP_MD_size(pctx_md)) || + (salt_len != RSA_PSS_SALTLEN_DIGEST && + salt_len != (int)EVP_MD_size(pctx_md)) || EVP_MD_type(mgf1_md) != md_type) { // Only PSS where saltLen == hashLen is tested with ACVP. Cases with // non-standard padding functions are also excluded. diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/sha/sha512.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/sha/sha512.cc.inc index b11f39824..8cbf88590 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/sha/sha512.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/sha/sha512.cc.inc @@ -40,8 +40,8 @@ bcm_infallible BCM_sha384_init(SHA512_CTX *sha) { sha->h[6] = UINT64_C(0xdb0c2e0d64f98fa7); sha->h[7] = UINT64_C(0x47b5481dbefa4fa4); - sha->Nl = 0; - sha->Nh = 0; + sha->bytes_so_far_low = 0; + sha->bytes_so_far_high = 0; sha->num = 0; sha->md_len = BCM_SHA384_DIGEST_LENGTH; return bcm_infallible::approved; @@ -58,8 +58,8 @@ bcm_infallible BCM_sha512_init(SHA512_CTX *sha) { sha->h[6] = UINT64_C(0x1f83d9abfb41bd6b); sha->h[7] = UINT64_C(0x5be0cd19137e2179); - sha->Nl = 0; - sha->Nh = 0; + sha->bytes_so_far_low = 0; + sha->bytes_so_far_high = 0; sha->num = 0; sha->md_len = BCM_SHA512_DIGEST_LENGTH; return bcm_infallible::approved; @@ -75,8 +75,8 @@ bcm_infallible BCM_sha512_256_init(SHA512_CTX *sha) { sha->h[6] = UINT64_C(0x2b0199fc2c85b8aa); sha->h[7] = UINT64_C(0x0eb72ddc81c52ca2); - sha->Nl = 0; - sha->Nh = 0; + sha->bytes_so_far_low = 0; + sha->bytes_so_far_high = 0; sha->num = 0; sha->md_len = BCM_SHA512_256_DIGEST_LENGTH; return bcm_infallible::approved; @@ -124,7 +124,6 @@ bcm_infallible BCM_sha512_transform(SHA512_CTX *c, bcm_infallible BCM_sha512_update(SHA512_CTX *c, const void *in_data, size_t len) { - uint64_t l; uint8_t *p = c->p; const uint8_t *data = reinterpret_cast(in_data); @@ -132,14 +131,10 @@ bcm_infallible BCM_sha512_update(SHA512_CTX *c, const void *in_data, return bcm_infallible::approved; } - l = (c->Nl + (((uint64_t)len) << 3)) & UINT64_C(0xffffffffffffffff); - if (l < c->Nl) { - c->Nh++; + c->bytes_so_far_low += len; + if (c->bytes_so_far_low < len) { + c->bytes_so_far_high++; } - if (sizeof(len) >= 8) { - c->Nh += (((uint64_t)len) >> 61); - } - c->Nl = l; if (c->num != 0) { size_t n = sizeof(c->p) - c->num; @@ -195,8 +190,11 @@ static void sha512_final_impl(uint8_t *out, size_t md_len, SHA512_CTX *sha) { } OPENSSL_memset(p + n, 0, sizeof(sha->p) - 16 - n); - CRYPTO_store_u64_be(p + sizeof(sha->p) - 16, sha->Nh); - CRYPTO_store_u64_be(p + sizeof(sha->p) - 8, sha->Nl); + const uint64_t Nh = (uint64_t{sha->bytes_so_far_high} << 3) | + (sha->bytes_so_far_low >> (64 - 3)); + const uint64_t Nl = sha->bytes_so_far_low << 3; + CRYPTO_store_u64_be(p + sizeof(sha->p) - 16, Nh); + CRYPTO_store_u64_be(p + sizeof(sha->p) - 8, Nl); sha512_block_data_order(sha->h, p, 1); diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/slhdsa/thash.cc.inc b/Sources/CCryptoBoringSSL/crypto/fipsmodule/slhdsa/thash.cc.inc index ec3084d12..3183061bd 100644 --- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/slhdsa/thash.cc.inc +++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/slhdsa/thash.cc.inc @@ -17,7 +17,7 @@ #include #include -#include +#include #include "../../internal.h" #include "./params.h" diff --git a/Sources/CCryptoBoringSSL/crypto/hpke/hpke.cc b/Sources/CCryptoBoringSSL/crypto/hpke/hpke.cc index 63a360d02..684c27963 100644 --- a/Sources/CCryptoBoringSSL/crypto/hpke/hpke.cc +++ b/Sources/CCryptoBoringSSL/crypto/hpke/hpke.cc @@ -27,7 +27,8 @@ #include #include #include -#include +#include +#include #include "../fipsmodule/ec/internal.h" #include "../internal.h" @@ -35,7 +36,7 @@ // This file implements RFC 9180. -#define MAX_SEED_LEN X25519_PRIVATE_KEY_LEN +#define MAX_SEED_LEN XWING_SEED_LEN #define MAX_SHARED_SECRET_LEN SHA256_DIGEST_LENGTH struct evp_hpke_kem_st { @@ -601,6 +602,122 @@ const EVP_HPKE_KEM *EVP_hpke_p256_hkdf_sha256(void) { return &kKEM; } +#define XWING_PRIVATE_KEY_LEN 32 +#define XWING_PUBLIC_KEY_LEN 1216 +#define XWING_PUBLIC_VALUE_LEN 1120 +#define XWING_SEED_LEN 64 +#define XWING_SHARED_KEY_LEN 32 + +static int xwing_init_key(EVP_HPKE_KEY *key, const uint8_t *priv_key, + size_t priv_key_len) { + CBS cbs; + CBS_init(&cbs, priv_key, priv_key_len); + XWING_private_key private_key; + if (!XWING_parse_private_key(&private_key, &cbs) || CBS_len(&cbs) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return 0; + } + + if (!XWING_public_from_private(key->public_key, &private_key)) { + return 0; + } + + if (priv_key_len > sizeof(key->private_key)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return 0; + } + OPENSSL_memcpy(key->private_key, priv_key, priv_key_len); + return 1; +} + +static int xwing_generate_key(EVP_HPKE_KEY *key) { + XWING_private_key private_key; + if (!XWING_generate_key(key->public_key, &private_key)) { + return 0; + } + + CBB cbb; + CBB_init_fixed(&cbb, key->private_key, XWING_PRIVATE_KEY_LEN); + if (!XWING_marshal_private_key(&cbb, &private_key) || + CBB_len(&cbb) != XWING_PRIVATE_KEY_LEN) { + return 0; + } + + return 1; +} + +static int xwing_encap_with_seed(const EVP_HPKE_KEM *kem, + uint8_t *out_shared_secret, + size_t *out_shared_secret_len, + uint8_t *out_enc, size_t *out_enc_len, + size_t max_enc, const uint8_t *peer_public_key, + size_t peer_public_key_len, + const uint8_t *seed, size_t seed_len) { + if (max_enc < XWING_PUBLIC_VALUE_LEN) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_BUFFER_SIZE); + return 0; + } + if (peer_public_key_len != XWING_PUBLIC_KEY_LEN || + seed_len != XWING_SEED_LEN) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return 0; + } + + if (!XWING_encap_external_entropy(out_enc, out_shared_secret, peer_public_key, + seed)) { + OPENSSL_PUT_ERROR(EVP, ERR_R_INTERNAL_ERROR); + return 0; + } + + *out_enc_len = XWING_PUBLIC_VALUE_LEN; + *out_shared_secret_len = XWING_SHARED_KEY_LEN; + return 1; +} + +static int xwing_decap(const EVP_HPKE_KEY *key, uint8_t *out_shared_secret, + size_t *out_shared_secret_len, const uint8_t *enc, + size_t enc_len) { + if (enc_len != XWING_PUBLIC_VALUE_LEN) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return 0; + } + + CBS cbs; + CBS_init(&cbs, key->private_key, XWING_PRIVATE_KEY_LEN); + XWING_private_key private_key; + if (!XWING_parse_private_key(&private_key, &cbs)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return 0; + } + + if (!XWING_decap(out_shared_secret, enc, &private_key)) { + OPENSSL_PUT_ERROR(EVP, ERR_R_INTERNAL_ERROR); + return 0; + } + + *out_shared_secret_len = XWING_SHARED_KEY_LEN; + return 1; +} + +const EVP_HPKE_KEM *EVP_hpke_xwing(void) { + static const EVP_HPKE_KEM kKEM = { + /*id=*/EVP_HPKE_XWING, + /*public_key_len=*/XWING_PUBLIC_KEY_LEN, + /*private_key_len=*/XWING_PRIVATE_KEY_LEN, + /*seed_len=*/XWING_SEED_LEN, + /*enc_len=*/XWING_PUBLIC_VALUE_LEN, + xwing_init_key, + xwing_generate_key, + xwing_encap_with_seed, + xwing_decap, + // X-Wing doesn't support authenticated encapsulation/decapsulation: + // https://datatracker.ietf.org/doc/html/draft-connolly-cfrg-xwing-kem-08#name-use-in-hpke + /* auth_encap_with_seed= */ nullptr, + /* auth_decap= */ nullptr, + }; + return &kKEM; +} + uint16_t EVP_HPKE_KEM_id(const EVP_HPKE_KEM *kem) { return kem->id; } size_t EVP_HPKE_KEM_public_key_len(const EVP_HPKE_KEM *kem) { diff --git a/Sources/CCryptoBoringSSL/crypto/hrss/hrss.cc b/Sources/CCryptoBoringSSL/crypto/hrss/hrss.cc index 457bdb663..3b2031e5a 100644 --- a/Sources/CCryptoBoringSSL/crypto/hrss/hrss.cc +++ b/Sources/CCryptoBoringSSL/crypto/hrss/hrss.cc @@ -17,13 +17,15 @@ #include #include #include + +#include #include #include #include #include #include -#include +#include #include "../internal.h" #include "internal.h" @@ -309,7 +311,7 @@ static crypto_word_t word_reverse(crypto_word_t in) { }; #endif - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kMasks); i++) { + for (size_t i = 0; i < std::size(kMasks); i++) { in = ((in >> (1 << i)) & kMasks[i]) | ((in & kMasks[i]) << (1 << i)); } diff --git a/Sources/CCryptoBoringSSL/crypto/internal.h b/Sources/CCryptoBoringSSL/crypto/internal.h index 90d70645f..f371bcb5c 100644 --- a/Sources/CCryptoBoringSSL/crypto/internal.h +++ b/Sources/CCryptoBoringSSL/crypto/internal.h @@ -23,6 +23,8 @@ #include #include +#include + #if defined(BORINGSSL_CONSTANT_TIME_VALIDATION) #include #endif @@ -50,6 +52,10 @@ #include #endif +#if defined(_M_X64) || defined(_M_IX86) +#include "intrin.h" +#endif + #if defined(__cplusplus) extern "C" { #endif @@ -100,8 +106,6 @@ typedef __uint128_t uint128_t; #endif #endif -#define OPENSSL_ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) - // GCC-like compilers indicate SSE2 with |__SSE2__|. MSVC leaves the caller to // know that x86_64 has SSE2, and uses _M_IX86_FP to indicate SSE2 on x86. // https://learn.microsoft.com/en-us/cpp/preprocessor/predefined-macros?view=msvc-170 @@ -527,8 +531,6 @@ OPENSSL_EXPORT void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void)); using CRYPTO_atomic_u32 = std::atomic; -static_assert(sizeof(CRYPTO_atomic_u32) == sizeof(uint32_t)); - inline uint32_t CRYPTO_atomic_load_u32(const CRYPTO_atomic_u32 *val) { return val->load(std::memory_order_seq_cst); } @@ -567,12 +569,6 @@ inline void CRYPTO_atomic_store_u32(CRYPTO_atomic_u32 *val, uint32_t desired) { #endif -// See the comment in the |__cplusplus| section above. -static_assert(sizeof(CRYPTO_atomic_u32) == sizeof(uint32_t), - "CRYPTO_atomic_u32 does not match uint32_t size"); -static_assert(alignof(CRYPTO_atomic_u32) == alignof(uint32_t), - "CRYPTO_atomic_u32 does not match uint32_t alignment"); - // Reference counting. @@ -886,6 +882,16 @@ static inline void *OPENSSL_memset(void *dst, int c, size_t n) { // endianness. They use |memcpy|, and so avoid alignment or strict aliasing // requirements on the input and output pointers. +static inline uint16_t CRYPTO_load_u16_le(const void *in) { + uint16_t v; + OPENSSL_memcpy(&v, in, sizeof(v)); + return v; +} + +static inline void CRYPTO_store_u16_le(void *out, uint16_t v) { + OPENSSL_memcpy(out, &v, sizeof(v)); +} + static inline uint16_t CRYPTO_load_u16_be(const void *in) { uint16_t v; OPENSSL_memcpy(&v, in, sizeof(v)); @@ -1444,6 +1450,9 @@ inline int CRYPTO_fuzzer_mode_enabled(void) { return 0; } // CRYPTO_addc_* returns |x + y + carry|, and sets |*out_carry| to the carry // bit. |carry| must be zero or one. + +// NOTE: Unoptimized GCC builds may compile these builtins to non-constant-time +// code. For correct constant-time behavior, ensure builds are optimized. #if OPENSSL_HAS_BUILTIN(__builtin_addc) inline unsigned int CRYPTO_addc_impl(unsigned int x, unsigned int y, @@ -1480,16 +1489,26 @@ inline uint64_t CRYPTO_addc_u64(uint64_t x, uint64_t y, uint64_t carry, static inline uint32_t CRYPTO_addc_u32(uint32_t x, uint32_t y, uint32_t carry, uint32_t *out_carry) { declassify_assert(carry <= 1); +#if defined(_M_IX86) + uint32_t sum = 0; + *out_carry = _addcarry_u32(carry, x, y, &sum); + return sum; +#else uint64_t ret = carry; ret += (uint64_t)x + y; *out_carry = (uint32_t)(ret >> 32); return (uint32_t)ret; +#endif } static inline uint64_t CRYPTO_addc_u64(uint64_t x, uint64_t y, uint64_t carry, uint64_t *out_carry) { declassify_assert(carry <= 1); -#if defined(BORINGSSL_HAS_UINT128) +#if defined(_M_X64) + uint64_t sum = 0; + *out_carry = _addcarry_u64(carry, x, y, &sum); + return sum; +#elif defined(BORINGSSL_HAS_UINT128) uint128_t ret = carry; ret += (uint128_t)x + y; *out_carry = (uint64_t)(ret >> 64); @@ -1544,17 +1563,29 @@ inline uint64_t CRYPTO_subc_u64(uint64_t x, uint64_t y, uint64_t borrow, static inline uint32_t CRYPTO_subc_u32(uint32_t x, uint32_t y, uint32_t borrow, uint32_t *out_borrow) { declassify_assert(borrow <= 1); +#if defined(_M_IX86) + uint32_t diff = 0; + *out_borrow = _subborrow_u32(borrow, x, y, &diff); + return diff; +#else uint32_t ret = x - y - borrow; *out_borrow = (x < y) | ((x == y) & borrow); return ret; +#endif } static inline uint64_t CRYPTO_subc_u64(uint64_t x, uint64_t y, uint64_t borrow, uint64_t *out_borrow) { declassify_assert(borrow <= 1); +#if defined(_M_X64) + uint64_t diff = 0; + *out_borrow = _subborrow_u64(borrow, x, y, &diff); + return diff; +#else uint64_t ret = x - y - borrow; *out_borrow = (x < y) | ((x == y) & borrow); return ret; +#endif } #endif @@ -1567,4 +1598,28 @@ static inline uint64_t CRYPTO_subc_u64(uint64_t x, uint64_t y, uint64_t borrow, #endif +BSSL_NAMESPACE_BEGIN +// Cleanup implements a custom scope guard, when the cleanup logic does not fit +// in a destructor. Usage: +// +// bssl::Cleanup cleanup = [&] { SomeCleanupWork(local_var); }; +template +class Cleanup { + public: + static_assert(std::is_invocable_v); + static_assert(std::is_same_v, void>); + + Cleanup(F func) : func_(func) {} + Cleanup(const Cleanup &) = delete; + Cleanup &operator=(const Cleanup &) = delete; + ~Cleanup() { func_(); } + + private: + F func_; +}; +template +Cleanup(F func) -> Cleanup; +BSSL_NAMESPACE_END + + #endif // OPENSSL_HEADER_CRYPTO_INTERNAL_H diff --git a/Sources/CCryptoBoringSSL/crypto/kyber/internal.h b/Sources/CCryptoBoringSSL/crypto/kyber/internal.h index 0d8dc06dc..c7a8d42d6 100644 --- a/Sources/CCryptoBoringSSL/crypto/kyber/internal.h +++ b/Sources/CCryptoBoringSSL/crypto/kyber/internal.h @@ -16,13 +16,122 @@ #define OPENSSL_HEADER_CRYPTO_KYBER_INTERNAL_H #include -#include #if defined(__cplusplus) extern "C" { #endif +// Kyber is the pre-standard version of ML-KEM. This was once exported as public +// API, but is now internal and only used by libssl. It will be removed entirely +// in the future. +// +// This implements the round-3 specification of Kyber, defined at +// https://pq-crystals.org/kyber/data/kyber-specification-round3-20210804.pdf + +// KYBER_public_key contains a Kyber768 public key. The contents of this +// object should never leave the address space since the format is unstable. +struct KYBER_public_key { + union { + uint8_t bytes[512 * (3 + 9) + 32 + 32]; + uint16_t alignment; + } opaque; +}; + +// KYBER_private_key contains a Kyber768 private key. The contents of this +// object should never leave the address space since the format is unstable. +struct KYBER_private_key { + union { + uint8_t bytes[512 * (3 + 3 + 9) + 32 + 32 + 32]; + uint16_t alignment; + } opaque; +}; + +// KYBER_PUBLIC_KEY_BYTES is the number of bytes in an encoded Kyber768 public +// key. +#define KYBER_PUBLIC_KEY_BYTES 1184 + +// KYBER_SHARED_SECRET_BYTES is the number of bytes in the Kyber768 shared +// secret. Although the round-3 specification has a variable-length output, the +// final ML-KEM construction is expected to use a fixed 32-byte output. To +// simplify the future transition, we apply the same restriction. +#define KYBER_SHARED_SECRET_BYTES 32 + +// KYBER_generate_key generates a random public/private key pair, writes the +// encoded public key to |out_encoded_public_key| and sets |out_private_key| to +// the private key. +OPENSSL_EXPORT void KYBER_generate_key( + uint8_t out_encoded_public_key[KYBER_PUBLIC_KEY_BYTES], + struct KYBER_private_key *out_private_key); + +// KYBER_public_from_private sets |*out_public_key| to the public key that +// corresponds to |private_key|. (This is faster than parsing the output of +// |KYBER_generate_key| if, for some reason, you need to encapsulate to a key +// that was just generated.) +OPENSSL_EXPORT void KYBER_public_from_private( + struct KYBER_public_key *out_public_key, + const struct KYBER_private_key *private_key); + +// KYBER_CIPHERTEXT_BYTES is number of bytes in the Kyber768 ciphertext. +#define KYBER_CIPHERTEXT_BYTES 1088 + +// KYBER_encap encrypts a random shared secret for |public_key|, writes the +// ciphertext to |out_ciphertext|, and writes the random shared secret to +// |out_shared_secret|. +OPENSSL_EXPORT void KYBER_encap( + uint8_t out_ciphertext[KYBER_CIPHERTEXT_BYTES], + uint8_t out_shared_secret[KYBER_SHARED_SECRET_BYTES], + const struct KYBER_public_key *public_key); + +// KYBER_decap decrypts a shared secret from |ciphertext| using |private_key| +// and writes it to |out_shared_secret|. If |ciphertext| is invalid, +// |out_shared_secret| is filled with a key that will always be the same for the +// same |ciphertext| and |private_key|, but which appears to be random unless +// one has access to |private_key|. These alternatives occur in constant time. +// Any subsequent symmetric encryption using |out_shared_secret| must use an +// authenticated encryption scheme in order to discover the decapsulation +// failure. +OPENSSL_EXPORT void KYBER_decap( + uint8_t out_shared_secret[KYBER_SHARED_SECRET_BYTES], + const uint8_t ciphertext[KYBER_CIPHERTEXT_BYTES], + const struct KYBER_private_key *private_key); + + +// Serialisation of keys. + +// KYBER_marshal_public_key serializes |public_key| to |out| in the standard +// format for Kyber public keys. It returns one on success or zero on allocation +// error. +OPENSSL_EXPORT int KYBER_marshal_public_key( + CBB *out, const struct KYBER_public_key *public_key); + +// KYBER_parse_public_key parses a public key, in the format generated by +// |KYBER_marshal_public_key|, from |in| and writes the result to +// |out_public_key|. It returns one on success or zero on parse error or if +// there are trailing bytes in |in|. +OPENSSL_EXPORT int KYBER_parse_public_key( + struct KYBER_public_key *out_public_key, CBS *in); + +// KYBER_marshal_private_key serializes |private_key| to |out| in the standard +// format for Kyber private keys. It returns one on success or zero on +// allocation error. +OPENSSL_EXPORT int KYBER_marshal_private_key( + CBB *out, const struct KYBER_private_key *private_key); + +// KYBER_PRIVATE_KEY_BYTES is the length of the data produced by +// |KYBER_marshal_private_key|. +#define KYBER_PRIVATE_KEY_BYTES 2400 + +// KYBER_parse_private_key parses a private key, in the format generated by +// |KYBER_marshal_private_key|, from |in| and writes the result to +// |out_private_key|. It returns one on success or zero on parse error or if +// there are trailing bytes in |in|. +OPENSSL_EXPORT int KYBER_parse_private_key( + struct KYBER_private_key *out_private_key, CBS *in); + + +// Internal symbols. + // KYBER_ENCAP_ENTROPY is the number of bytes of uniformly random entropy // necessary to encapsulate a secret. The entropy will be leaked to the // decapsulating party. diff --git a/Sources/CCryptoBoringSSL/crypto/kyber/kyber.cc b/Sources/CCryptoBoringSSL/crypto/kyber/kyber.cc index 4af369604..581e701f9 100644 --- a/Sources/CCryptoBoringSSL/crypto/kyber/kyber.cc +++ b/Sources/CCryptoBoringSSL/crypto/kyber/kyber.cc @@ -12,9 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -#define OPENSSL_UNSTABLE_EXPERIMENTAL_KYBER -#include - #include #include diff --git a/Sources/CCryptoBoringSSL/crypto/mldsa/mldsa.cc b/Sources/CCryptoBoringSSL/crypto/mldsa/mldsa.cc index 0e4d847bf..d18fc9ea3 100644 --- a/Sources/CCryptoBoringSSL/crypto/mldsa/mldsa.cc +++ b/Sources/CCryptoBoringSSL/crypto/mldsa/mldsa.cc @@ -28,6 +28,12 @@ static_assert(sizeof(BCM_mldsa87_public_key) == sizeof(MLDSA87_public_key)); static_assert(alignof(BCM_mldsa87_public_key) == alignof(MLDSA87_public_key)); static_assert(sizeof(BCM_mldsa87_prehash) == sizeof(MLDSA87_prehash)); static_assert(alignof(BCM_mldsa87_prehash) == alignof(MLDSA87_prehash)); +static_assert(sizeof(BCM_mldsa44_private_key) == sizeof(MLDSA44_private_key)); +static_assert(alignof(BCM_mldsa44_private_key) == alignof(MLDSA44_private_key)); +static_assert(sizeof(BCM_mldsa44_public_key) == sizeof(MLDSA44_public_key)); +static_assert(alignof(BCM_mldsa44_public_key) == alignof(MLDSA44_public_key)); +static_assert(sizeof(BCM_mldsa44_prehash) == sizeof(MLDSA44_prehash)); +static_assert(alignof(BCM_mldsa44_prehash) == alignof(MLDSA44_prehash)); static_assert(MLDSA_SEED_BYTES == BCM_MLDSA_SEED_BYTES); static_assert(MLDSA_MU_BYTES == BCM_MLDSA_MU_BYTES); static_assert(MLDSA65_PRIVATE_KEY_BYTES == BCM_MLDSA65_PRIVATE_KEY_BYTES); @@ -36,6 +42,9 @@ static_assert(MLDSA65_SIGNATURE_BYTES == BCM_MLDSA65_SIGNATURE_BYTES); static_assert(MLDSA87_PRIVATE_KEY_BYTES == BCM_MLDSA87_PRIVATE_KEY_BYTES); static_assert(MLDSA87_PUBLIC_KEY_BYTES == BCM_MLDSA87_PUBLIC_KEY_BYTES); static_assert(MLDSA87_SIGNATURE_BYTES == BCM_MLDSA87_SIGNATURE_BYTES); +static_assert(MLDSA44_PRIVATE_KEY_BYTES == BCM_MLDSA44_PRIVATE_KEY_BYTES); +static_assert(MLDSA44_PUBLIC_KEY_BYTES == BCM_MLDSA44_PUBLIC_KEY_BYTES); +static_assert(MLDSA44_SIGNATURE_BYTES == BCM_MLDSA44_SIGNATURE_BYTES); int MLDSA65_generate_key( uint8_t out_encoded_public_key[MLDSA65_PUBLIC_KEY_BYTES], @@ -226,3 +235,98 @@ int MLDSA87_parse_public_key(struct MLDSA87_public_key *public_key, CBS *in) { return bcm_success(BCM_mldsa87_parse_public_key( reinterpret_cast(public_key), in)); } + +int MLDSA44_generate_key( + uint8_t out_encoded_public_key[MLDSA44_PUBLIC_KEY_BYTES], + uint8_t out_seed[MLDSA_SEED_BYTES], + struct MLDSA44_private_key *out_private_key) { + return bcm_success(BCM_mldsa44_generate_key( + out_encoded_public_key, out_seed, + reinterpret_cast(out_private_key))); +} + +int MLDSA44_private_key_from_seed(struct MLDSA44_private_key *out_private_key, + const uint8_t *seed, size_t seed_len) { + if (seed_len != BCM_MLDSA_SEED_BYTES) { + return 0; + } + return bcm_success(BCM_mldsa44_private_key_from_seed( + reinterpret_cast(out_private_key), seed)); +} + +int MLDSA44_public_from_private(struct MLDSA44_public_key *out_public_key, + const struct MLDSA44_private_key *private_key) { + return bcm_success(BCM_mldsa44_public_from_private( + reinterpret_cast(out_public_key), + reinterpret_cast(private_key))); +} + +int MLDSA44_sign(uint8_t out_encoded_signature[MLDSA44_SIGNATURE_BYTES], + const struct MLDSA44_private_key *private_key, + const uint8_t *msg, size_t msg_len, const uint8_t *context, + size_t context_len) { + if (context_len > 255) { + return 0; + } + return bcm_success(BCM_mldsa44_sign( + out_encoded_signature, + reinterpret_cast(private_key), msg, + msg_len, context, context_len)); +} + +int MLDSA44_verify(const struct MLDSA44_public_key *public_key, + const uint8_t *signature, size_t signature_len, + const uint8_t *msg, size_t msg_len, const uint8_t *context, + size_t context_len) { + if (context_len > 255 || signature_len != BCM_MLDSA44_SIGNATURE_BYTES) { + return 0; + } + return bcm_success(BCM_mldsa44_verify( + reinterpret_cast(public_key), signature, + msg, msg_len, context, context_len)); +} + +int MLDSA44_prehash_init(struct MLDSA44_prehash *out_state, + const struct MLDSA44_public_key *public_key, + const uint8_t *context, size_t context_len) { + if (context_len > 255) { + return 0; + } + BCM_mldsa44_prehash_init( + reinterpret_cast(out_state), + reinterpret_cast(public_key), context, + context_len); + return 1; +} + +void MLDSA44_prehash_update(struct MLDSA44_prehash *inout_state, + const uint8_t *msg, size_t msg_len) { + BCM_mldsa44_prehash_update( + reinterpret_cast(inout_state), msg, msg_len); +} + +void MLDSA44_prehash_finalize(uint8_t out_msg_rep[MLDSA_MU_BYTES], + struct MLDSA44_prehash *inout_state) { + BCM_mldsa44_prehash_finalize( + out_msg_rep, reinterpret_cast(inout_state)); +} + +int MLDSA44_sign_message_representative( + uint8_t out_encoded_signature[MLDSA44_SIGNATURE_BYTES], + const struct MLDSA44_private_key *private_key, + const uint8_t msg_rep[MLDSA_MU_BYTES]) { + return bcm_success(BCM_mldsa44_sign_message_representative( + out_encoded_signature, + reinterpret_cast(private_key), msg_rep)); +} + +int MLDSA44_marshal_public_key(CBB *out, + const struct MLDSA44_public_key *public_key) { + return bcm_success(BCM_mldsa44_marshal_public_key( + out, reinterpret_cast(public_key))); +} + +int MLDSA44_parse_public_key(struct MLDSA44_public_key *public_key, CBS *in) { + return bcm_success(BCM_mldsa44_parse_public_key( + reinterpret_cast(public_key), in)); +} diff --git a/Sources/CCryptoBoringSSL/crypto/obj/obj.cc b/Sources/CCryptoBoringSSL/crypto/obj/obj.cc index aba6f2db0..28ef9f0bc 100644 --- a/Sources/CCryptoBoringSSL/crypto/obj/obj.cc +++ b/Sources/CCryptoBoringSSL/crypto/obj/obj.cc @@ -18,6 +18,8 @@ #include #include +#include + #include #include #include @@ -173,7 +175,7 @@ int OBJ_obj2nid(const ASN1_OBJECT *obj) { CRYPTO_MUTEX_unlock_read(&global_added_lock); const uint16_t *nid_ptr = reinterpret_cast( - bsearch(obj, kNIDsInOIDOrder, OPENSSL_ARRAY_SIZE(kNIDsInOIDOrder), + bsearch(obj, kNIDsInOIDOrder, std::size(kNIDsInOIDOrder), sizeof(kNIDsInOIDOrder[0]), obj_cmp)); if (nid_ptr == NULL) { return NID_undef; @@ -219,10 +221,9 @@ int OBJ_sn2nid(const char *short_name) { } CRYPTO_MUTEX_unlock_read(&global_added_lock); - const uint16_t *nid_ptr = reinterpret_cast( - bsearch(short_name, kNIDsInShortNameOrder, - OPENSSL_ARRAY_SIZE(kNIDsInShortNameOrder), - sizeof(kNIDsInShortNameOrder[0]), short_name_cmp)); + const uint16_t *nid_ptr = reinterpret_cast(bsearch( + short_name, kNIDsInShortNameOrder, std::size(kNIDsInShortNameOrder), + sizeof(kNIDsInShortNameOrder[0]), short_name_cmp)); if (nid_ptr == NULL) { return NID_undef; } @@ -254,9 +255,9 @@ int OBJ_ln2nid(const char *long_name) { } CRYPTO_MUTEX_unlock_read(&global_added_lock); - const uint16_t *nid_ptr = reinterpret_cast(bsearch( - long_name, kNIDsInLongNameOrder, OPENSSL_ARRAY_SIZE(kNIDsInLongNameOrder), - sizeof(kNIDsInLongNameOrder[0]), long_name_cmp)); + const uint16_t *nid_ptr = reinterpret_cast( + bsearch(long_name, kNIDsInLongNameOrder, std::size(kNIDsInLongNameOrder), + sizeof(kNIDsInLongNameOrder[0]), long_name_cmp)); if (nid_ptr == NULL) { return NID_undef; } diff --git a/Sources/CCryptoBoringSSL/crypto/obj/obj_dat.h b/Sources/CCryptoBoringSSL/crypto/obj/obj_dat.h index a857d535c..344e7f2ea 100644 --- a/Sources/CCryptoBoringSSL/crypto/obj/obj_dat.h +++ b/Sources/CCryptoBoringSSL/crypto/obj/obj_dat.h @@ -15,7 +15,7 @@ // This file is generated by crypto/obj/objects.go. -#define NUM_NID 966 +#define NUM_NID 967 static const uint8_t kObjectData[] = { /* NID_rsadsi */ @@ -8742,6 +8742,7 @@ static const ASN1_OBJECT kObjects[NUM_NID] = { {"X25519Kyber768Draft00", "X25519Kyber768Draft00", NID_X25519Kyber768Draft00, 0, NULL, 0}, {"X25519MLKEM768", "X25519MLKEM768", NID_X25519MLKEM768, 0, NULL, 0}, + {"MLKEM1024", "MLKEM1024", NID_MLKEM1024, 0, NULL, 0}, }; static const uint16_t kNIDsInShortNameOrder[] = { @@ -8864,6 +8865,7 @@ static const uint16_t kNIDsInShortNameOrder[] = { 114 /* MD5-SHA1 */, 95 /* MDC2 */, 911 /* MGF1 */, + 966 /* MLKEM1024 */, 388 /* Mail */, 57 /* Netscape */, 366 /* Nonce */, @@ -9755,6 +9757,7 @@ static const uint16_t kNIDsInLongNameOrder[] = { 647 /* International Organizations */, 142 /* Invalidity Date */, 504 /* MIME MHS */, + 966 /* MLKEM1024 */, 388 /* Mail */, 383 /* Management */, 417 /* Microsoft CSP Name */, diff --git a/Sources/CCryptoBoringSSL/crypto/obj/obj_xref.cc b/Sources/CCryptoBoringSSL/crypto/obj/obj_xref.cc index 5715bb841..7d65724bc 100644 --- a/Sources/CCryptoBoringSSL/crypto/obj/obj_xref.cc +++ b/Sources/CCryptoBoringSSL/crypto/obj/obj_xref.cc @@ -50,13 +50,13 @@ static const nid_triple kTriples[] = { }; int OBJ_find_sigid_algs(int sign_nid, int *out_digest_nid, int *out_pkey_nid) { - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kTriples); i++) { - if (kTriples[i].sign_nid == sign_nid) { + for (const auto &triple : kTriples) { + if (triple.sign_nid == sign_nid) { if (out_digest_nid != NULL) { - *out_digest_nid = kTriples[i].digest_nid; + *out_digest_nid = triple.digest_nid; } if (out_pkey_nid != NULL) { - *out_pkey_nid = kTriples[i].pkey_nid; + *out_pkey_nid = triple.pkey_nid; } return 1; } @@ -66,11 +66,11 @@ int OBJ_find_sigid_algs(int sign_nid, int *out_digest_nid, int *out_pkey_nid) { } int OBJ_find_sigid_by_algs(int *out_sign_nid, int digest_nid, int pkey_nid) { - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kTriples); i++) { - if (kTriples[i].digest_nid == digest_nid && - kTriples[i].pkey_nid == pkey_nid) { + for (const auto &triple : kTriples) { + if (triple.digest_nid == digest_nid && + triple.pkey_nid == pkey_nid) { if (out_sign_nid != NULL) { - *out_sign_nid = kTriples[i].sign_nid; + *out_sign_nid = triple.sign_nid; } return 1; } diff --git a/Sources/CCryptoBoringSSL/crypto/pem/pem_all.cc b/Sources/CCryptoBoringSSL/crypto/pem/pem_all.cc index ced7c76b0..832105b72 100644 --- a/Sources/CCryptoBoringSSL/crypto/pem/pem_all.cc +++ b/Sources/CCryptoBoringSSL/crypto/pem/pem_all.cc @@ -38,14 +38,17 @@ IMPLEMENT_PEM_rw(PKCS7, PKCS7, PEM_STRING_PKCS7, PKCS7) // the relevant private key: this means can handle "traditional" and PKCS#8 // formats transparently. static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa) { - RSA *rtmp; if (!key) { - return NULL; + return nullptr; } - rtmp = EVP_PKEY_get1_RSA(key); - EVP_PKEY_free(key); + if (EVP_PKEY_id(key) != EVP_PKEY_RSA) { + // Don't accept RSA-PSS keys in this function. + OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_AN_RSA_KEY); + return nullptr; + } + RSA *rtmp = EVP_PKEY_get1_RSA(key); if (!rtmp) { - return NULL; + return nullptr; } if (rsa) { RSA_free(*rsa); @@ -56,15 +59,13 @@ static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa) { RSA *PEM_read_bio_RSAPrivateKey(BIO *bp, RSA **rsa, pem_password_cb *cb, void *u) { - EVP_PKEY *pktmp; - pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u); - return pkey_get_rsa(pktmp, rsa); + bssl::UniquePtr pkey(PEM_read_bio_PrivateKey(bp, nullptr, cb, u)); + return pkey_get_rsa(pkey.get(), rsa); } RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **rsa, pem_password_cb *cb, void *u) { - EVP_PKEY *pktmp; - pktmp = PEM_read_PrivateKey(fp, NULL, cb, u); - return pkey_get_rsa(pktmp, rsa); + bssl::UniquePtr pkey(PEM_read_PrivateKey(fp, nullptr, cb, u)); + return pkey_get_rsa(pkey.get(), rsa); } IMPLEMENT_PEM_write_cb_const(RSAPrivateKey, RSA, PEM_STRING_RSA, RSAPrivateKey) diff --git a/Sources/CCryptoBoringSSL/crypto/pem/pem_info.cc b/Sources/CCryptoBoringSSL/crypto/pem/pem_info.cc index 1ea9b8214..1f80787f7 100644 --- a/Sources/CCryptoBoringSSL/crypto/pem/pem_info.cc +++ b/Sources/CCryptoBoringSSL/crypto/pem/pem_info.cc @@ -143,9 +143,7 @@ STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, for (;;) { if (!PEM_read_bio(bp, &name, &header, &data, &len)) { - uint32_t error = ERR_peek_last_error(); - if (ERR_GET_LIB(error) == ERR_LIB_PEM && - ERR_GET_REASON(error) == PEM_R_NO_START_LINE) { + if (ERR_equals(ERR_peek_last_error(), ERR_LIB_PEM, PEM_R_NO_START_LINE)) { ERR_clear_error(); break; } diff --git a/Sources/CCryptoBoringSSL/crypto/pem/pem_lib.cc b/Sources/CCryptoBoringSSL/crypto/pem/pem_lib.cc index 60aafc1b5..028147a4b 100644 --- a/Sources/CCryptoBoringSSL/crypto/pem/pem_lib.cc +++ b/Sources/CCryptoBoringSSL/crypto/pem/pem_lib.cc @@ -182,9 +182,7 @@ int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, for (;;) { if (!PEM_read_bio(bp, &nm, &header, &data, &len)) { - uint32_t error = ERR_peek_error(); - if (ERR_GET_LIB(error) == ERR_LIB_PEM && - ERR_GET_REASON(error) == PEM_R_NO_START_LINE) { + if (ERR_equals(ERR_peek_error(), ERR_LIB_PEM, PEM_R_NO_START_LINE)) { ERR_add_error_data(2, "Expecting: ", name); } return 0; diff --git a/Sources/CCryptoBoringSSL/crypto/pkcs8/p5_pbev2.cc b/Sources/CCryptoBoringSSL/crypto/pkcs8/p5_pbev2.cc index d06855706..32a5edf58 100644 --- a/Sources/CCryptoBoringSSL/crypto/pkcs8/p5_pbev2.cc +++ b/Sources/CCryptoBoringSSL/crypto/pkcs8/p5_pbev2.cc @@ -19,6 +19,7 @@ #include #include +#include #include #include #include diff --git a/Sources/CCryptoBoringSSL/crypto/pkcs8/pkcs8.cc b/Sources/CCryptoBoringSSL/crypto/pkcs8/pkcs8.cc index 0e4f8c581..facc5bb56 100644 --- a/Sources/CCryptoBoringSSL/crypto/pkcs8/pkcs8.cc +++ b/Sources/CCryptoBoringSSL/crypto/pkcs8/pkcs8.cc @@ -271,15 +271,15 @@ static const struct pbe_suite kBuiltinPBE[] = { }; static const struct pbe_suite *get_pkcs12_pbe_suite(int pbe_nid) { - for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(kBuiltinPBE); i++) { - if (kBuiltinPBE[i].pbe_nid == pbe_nid && + for (const auto &pbe : kBuiltinPBE) { + if (pbe.pbe_nid == pbe_nid && // If |cipher_func| or |md_func| are missing, this is a PBES2 scheme. - kBuiltinPBE[i].cipher_func != NULL && kBuiltinPBE[i].md_func != NULL) { - return &kBuiltinPBE[i]; + pbe.cipher_func != nullptr && pbe.md_func != nullptr) { + return &pbe; } } - return NULL; + return nullptr; } int pkcs12_pbe_encrypt_init(CBB *out, EVP_CIPHER_CTX *ctx, int alg_nid, @@ -333,9 +333,9 @@ int pkcs8_pbe_decrypt(uint8_t **out, size_t *out_len, CBS *algorithm, goto err; } - for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(kBuiltinPBE); i++) { - if (CBS_mem_equal(&obj, kBuiltinPBE[i].oid, kBuiltinPBE[i].oid_len)) { - suite = &kBuiltinPBE[i]; + for (const auto &pbe : kBuiltinPBE) { + if (CBS_mem_equal(&obj, pbe.oid, pbe.oid_len)) { + suite = &pbe; break; } } diff --git a/Sources/CCryptoBoringSSL/crypto/pkcs8/pkcs8_x509.cc b/Sources/CCryptoBoringSSL/crypto/pkcs8/pkcs8_x509.cc index 9f4f92a91..19a8bf43d 100644 --- a/Sources/CCryptoBoringSSL/crypto/pkcs8/pkcs8_x509.cc +++ b/Sources/CCryptoBoringSSL/crypto/pkcs8/pkcs8_x509.cc @@ -26,6 +26,7 @@ #include #include #include +#include #include #include diff --git a/Sources/CCryptoBoringSSL/crypto/rand/passive.cc b/Sources/CCryptoBoringSSL/crypto/rand/passive.cc index c74ca369a..c73d0d9a1 100644 --- a/Sources/CCryptoBoringSSL/crypto/rand/passive.cc +++ b/Sources/CCryptoBoringSSL/crypto/rand/passive.cc @@ -38,7 +38,7 @@ static void passive_get_seed_entropy(uint8_t *out_entropy, } #define ENTROPY_READ_LEN \ - (/* last_block size */ 16 + CTR_DRBG_ENTROPY_LEN * BORINGSSL_FIPS_OVERREAD) + (/* last_block size */ 16 + CTR_DRBG_SEED_LEN * BORINGSSL_FIPS_OVERREAD) #if defined(OPENSSL_ANDROID) diff --git a/Sources/CCryptoBoringSSL/crypto/rsa/internal.h b/Sources/CCryptoBoringSSL/crypto/rsa/internal.h index d1702687a..297c90914 100644 --- a/Sources/CCryptoBoringSSL/crypto/rsa/internal.h +++ b/Sources/CCryptoBoringSSL/crypto/rsa/internal.h @@ -28,6 +28,31 @@ int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *out, size_t *out_len, size_t param_len, const EVP_MD *md, const EVP_MD *mgf1md); +enum rsa_pss_params_t { + // RSA-PSS using SHA-256, MGF1 with SHA-256, salt length 32. + rsa_pss_sha256, + // RSA-PSS using SHA-384, MGF1 with SHA-384, salt length 48. + rsa_pss_sha384, + // RSA-PSS using SHA-512, MGF1 with SHA-512, salt length 64. + rsa_pss_sha512, +}; + +// rsa_pss_params_get_md returns the hash function used with |params|. This also +// specifies the MGF-1 hash and the salt length because we do not support other +// configurations. +const EVP_MD *rsa_pss_params_get_md(rsa_pss_params_t params); + +// rsa_marshal_pss_params marshals |params| as a DER-encoded RSASSA-PSS-params +// (RFC 4055). It returns one on success and zero on error. +int rsa_marshal_pss_params(CBB *cbb, rsa_pss_params_t params); + +// rsa_marshal_pss_params decodes a DER-encoded RSASSA-PSS-params +// (RFC 4055). It returns one on success and zero on error. On success, it sets +// |*out| to the result. If |allow_explicit_trailer| is non-zero, an explicit +// encoding of the trailerField is allowed, although it is not valid DER. +int rsa_parse_pss_params(CBS *cbs, rsa_pss_params_t *out, + int allow_explicit_trailer); + #if defined(__cplusplus) } // extern C diff --git a/Sources/CCryptoBoringSSL/crypto/rsa/rsa_asn1.cc b/Sources/CCryptoBoringSSL/crypto/rsa/rsa_asn1.cc index 3f66fd77d..f01ed4a3b 100644 --- a/Sources/CCryptoBoringSSL/crypto/rsa/rsa_asn1.cc +++ b/Sources/CCryptoBoringSSL/crypto/rsa/rsa_asn1.cc @@ -20,12 +20,17 @@ #include #include +#include #include #include +#include +#include +#include -#include "../fipsmodule/rsa/internal.h" #include "../bytestring/internal.h" +#include "../fipsmodule/rsa/internal.h" #include "../internal.h" +#include "internal.h" static int parse_integer(CBS *cbs, BIGNUM **out) { @@ -109,7 +114,7 @@ int RSA_public_key_to_bytes(uint8_t **out_bytes, size_t *out_len, } // kVersionTwoPrime is the value of the version field for a two-prime -// RSAPrivateKey structure (RFC 3447). +// RSAPrivateKey structure (RFC 8017). static const uint64_t kVersionTwoPrime = 0; RSA *RSA_parse_private_key(CBS *cbs) { @@ -205,59 +210,23 @@ int RSA_private_key_to_bytes(uint8_t **out_bytes, size_t *out_len, } RSA *d2i_RSAPublicKey(RSA **out, const uint8_t **inp, long len) { - if (len < 0) { - return NULL; - } - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); - RSA *ret = RSA_parse_public_key(&cbs); - if (ret == NULL) { - return NULL; - } - if (out != NULL) { - RSA_free(*out); - *out = ret; - } - *inp = CBS_data(&cbs); - return ret; + return bssl::D2IFromCBS(out, inp, len, RSA_parse_public_key); } int i2d_RSAPublicKey(const RSA *in, uint8_t **outp) { - CBB cbb; - if (!CBB_init(&cbb, 0) || - !RSA_marshal_public_key(&cbb, in)) { - CBB_cleanup(&cbb); - return -1; - } - return CBB_finish_i2d(&cbb, outp); + return bssl::I2DFromCBB( + /*initial_capacity=*/256, outp, + [&](CBB *cbb) -> bool { return RSA_marshal_public_key(cbb, in); }); } RSA *d2i_RSAPrivateKey(RSA **out, const uint8_t **inp, long len) { - if (len < 0) { - return NULL; - } - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); - RSA *ret = RSA_parse_private_key(&cbs); - if (ret == NULL) { - return NULL; - } - if (out != NULL) { - RSA_free(*out); - *out = ret; - } - *inp = CBS_data(&cbs); - return ret; + return bssl::D2IFromCBS(out, inp, len, RSA_parse_private_key); } int i2d_RSAPrivateKey(const RSA *in, uint8_t **outp) { - CBB cbb; - if (!CBB_init(&cbb, 0) || - !RSA_marshal_private_key(&cbb, in)) { - CBB_cleanup(&cbb); - return -1; - } - return CBB_finish_i2d(&cbb, outp); + return bssl::I2DFromCBB( + /*initial_capacity=*/512, outp, + [&](CBB *cbb) -> bool { return RSA_marshal_private_key(cbb, in); }); } RSA *RSAPublicKey_dup(const RSA *rsa) { @@ -281,3 +250,146 @@ RSA *RSAPrivateKey_dup(const RSA *rsa) { OPENSSL_free(der); return ret; } + +static const uint8_t kPSSParamsSHA256[] = { + 0x30, 0x34, 0xa0, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, + 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0xa1, 0x1c, 0x30, + 0x1a, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x08, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x01, 0x05, 0x00, 0xa2, 0x03, 0x02, 0x01, 0x20}; + +static const uint8_t kPSSParamsSHA384[] = { + 0x30, 0x34, 0xa0, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, + 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, 0x05, 0x00, 0xa1, 0x1c, 0x30, + 0x1a, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x08, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x02, 0x05, 0x00, 0xa2, 0x03, 0x02, 0x01, 0x30}; + +static const uint8_t kPSSParamsSHA512[] = { + 0x30, 0x34, 0xa0, 0x0f, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, + 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0xa1, 0x1c, 0x30, + 0x1a, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + 0x08, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x03, 0x05, 0x00, 0xa2, 0x03, 0x02, 0x01, 0x40}; + +const EVP_MD *rsa_pss_params_get_md(rsa_pss_params_t params) { + switch (params) { + case rsa_pss_sha256: + return EVP_sha256(); + case rsa_pss_sha384: + return EVP_sha384(); + case rsa_pss_sha512: + return EVP_sha512(); + } + abort(); +} + +int rsa_marshal_pss_params(CBB *cbb, rsa_pss_params_t params) { + bssl::Span bytes; + switch (params) { + case rsa_pss_sha256: + bytes = kPSSParamsSHA256; + break; + case rsa_pss_sha384: + bytes = kPSSParamsSHA384; + break; + case rsa_pss_sha512: + bytes = kPSSParamsSHA512; + break; + } + + return CBB_add_bytes(cbb, bytes.data(), bytes.size()); +} + +// 1.2.840.113549.1.1.8 +static const uint8_t kMGF1OID[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x01, 0x08}; + +int rsa_parse_pss_params(CBS *cbs, rsa_pss_params_t *out, + int allow_explicit_trailer) { + // See RFC 4055, section 3.1. + // + // hashAlgorithm, maskGenAlgorithm, and saltLength all have DEFAULTs + // corresponding to SHA-1. We do not support SHA-1 with PSS, so we do not + // bother recognizing the omitted versions. + CBS params, hash_wrapper, mask_wrapper, mask_alg, mask_oid, salt_wrapper; + uint64_t salt_len; + if (!CBS_get_asn1(cbs, ¶ms, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(¶ms, &hash_wrapper, + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) || + // |hash_wrapper| will be parsed below. + !CBS_get_asn1(¶ms, &mask_wrapper, + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 1) || + !CBS_get_asn1(&mask_wrapper, &mask_alg, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&mask_alg, &mask_oid, CBS_ASN1_OBJECT) || + // We only support MGF-1. + bssl::Span(mask_oid) != kMGF1OID || + // The remainder of |mask_alg| will be parsed below. + CBS_len(&mask_wrapper) != 0 || + !CBS_get_asn1(¶ms, &salt_wrapper, + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 2) || + !CBS_get_asn1_uint64(&salt_wrapper, &salt_len) || + CBS_len(&salt_wrapper) != 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING); + return 0; + } + + // The trailer field must be 1 (0xbc). This value is DEFAULT, so the structure + // is required to omit it in DER. + if (CBS_len(¶ms) != 0 && allow_explicit_trailer) { + CBS trailer_wrapper; + uint64_t trailer; + if (!CBS_get_asn1(¶ms, &trailer_wrapper, + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 3) || + !CBS_get_asn1_uint64(&trailer_wrapper, &trailer) || // + trailer != 1) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING); + return 0; + } + } + if (CBS_len(¶ms) != 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING); + return 0; + } + + int hash_nid = EVP_parse_digest_algorithm_nid(&hash_wrapper); + if (hash_nid == NID_undef || CBS_len(&hash_wrapper) != 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING); + return 0; + } + + // We only support combinations where the MGF-1 hash matches the overall hash. + int mgf1_hash_nid = EVP_parse_digest_algorithm_nid(&mask_alg); + if (mgf1_hash_nid != hash_nid || CBS_len(&mask_alg) != 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING); + return 0; + } + + // We only support salt lengths that match the hash length. + rsa_pss_params_t ret; + uint64_t hash_len; + switch (hash_nid) { + case NID_sha256: + ret = rsa_pss_sha256; + hash_len = 32; + break; + case NID_sha384: + ret = rsa_pss_sha384; + hash_len = 48; + break; + case NID_sha512: + ret = rsa_pss_sha512; + hash_len = 64; + break; + default: + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING); + return 0; + } + if (salt_len != hash_len) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING); + return 0; + } + + *out = ret; + return 1; +} diff --git a/Sources/CCryptoBoringSSL/crypto/rsa/rsa_extra.cc b/Sources/CCryptoBoringSSL/crypto/rsa/rsa_extra.cc index f7f9bbbb7..64009a333 100644 --- a/Sources/CCryptoBoringSSL/crypto/rsa/rsa_extra.cc +++ b/Sources/CCryptoBoringSSL/crypto/rsa/rsa_extra.cc @@ -17,3 +17,14 @@ int RSA_blinding_on(RSA *rsa, BN_CTX *ctx) { return 1; } void RSA_blinding_off(RSA *rsa) {} + +const RSA_PSS_PARAMS *RSA_get0_pss_params(const RSA *rsa) { + // We do not currently implement this function. By default, we will not parse + // |EVP_PKEY_RSA_PSS|. Callers that opt in with a BoringSSL-specific API are + // currently assumed to not need this function. Callers that need that opt-in + // and this functionality should contact the BoringSSL team. + // + // If we do add support later, the |maskHash| field should be filled in for + // OpenSSL compatibility. + return nullptr; +} diff --git a/Sources/CCryptoBoringSSL/crypto/sha/sha256.cc b/Sources/CCryptoBoringSSL/crypto/sha/sha256.cc index 7d2f14629..85ecd0e99 100644 --- a/Sources/CCryptoBoringSSL/crypto/sha/sha256.cc +++ b/Sources/CCryptoBoringSSL/crypto/sha/sha256.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include +#include #include diff --git a/Sources/CCryptoBoringSSL/crypto/sha/sha512.cc b/Sources/CCryptoBoringSSL/crypto/sha/sha512.cc index cd138db20..58702fc68 100644 --- a/Sources/CCryptoBoringSSL/crypto/sha/sha512.cc +++ b/Sources/CCryptoBoringSSL/crypto/sha/sha512.cc @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -#include +#include #include diff --git a/Sources/CCryptoBoringSSL/crypto/spake2plus/internal.h b/Sources/CCryptoBoringSSL/crypto/spake2plus/internal.h index 3d462cffc..69cf97ba6 100644 --- a/Sources/CCryptoBoringSSL/crypto/spake2plus/internal.h +++ b/Sources/CCryptoBoringSSL/crypto/spake2plus/internal.h @@ -19,7 +19,7 @@ #include -#include +#include #include #include "../fipsmodule/ec/internal.h" diff --git a/Sources/CCryptoBoringSSL/crypto/spake2plus/spake2plus.cc b/Sources/CCryptoBoringSSL/crypto/spake2plus/spake2plus.cc index 83e31b272..def70f5cf 100644 --- a/Sources/CCryptoBoringSSL/crypto/spake2plus/spake2plus.cc +++ b/Sources/CCryptoBoringSSL/crypto/spake2plus/spake2plus.cc @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include "../fipsmodule/bn/internal.h" #include "../fipsmodule/ec/internal.h" diff --git a/Sources/CCryptoBoringSSL/crypto/trust_token/pmbtoken.cc b/Sources/CCryptoBoringSSL/crypto/trust_token/pmbtoken.cc index 47328b602..ff0fcf2a9 100644 --- a/Sources/CCryptoBoringSSL/crypto/trust_token/pmbtoken.cc +++ b/Sources/CCryptoBoringSSL/crypto/trust_token/pmbtoken.cc @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include "../ec/internal.h" #include "../fipsmodule/bn/internal.h" @@ -196,13 +196,13 @@ static int pmbtoken_compute_keys(const PMBTOKEN_METHOD *method, const EC_SCALAR *scalars[] = {x0, y0, x1, y1, xs, ys}; size_t scalar_len = BN_num_bytes(EC_GROUP_get0_order(group)); - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(scalars); i++) { + for (const EC_SCALAR *scalar : scalars) { uint8_t *buf; if (!CBB_add_space(out_private, &buf, scalar_len)) { OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_BUFFER_TOO_SMALL); return 0; } - ec_scalar_to_bytes(group, buf, &scalar_len, scalars[i]); + ec_scalar_to_bytes(group, buf, &scalar_len, scalar); } EC_AFFINE pub_affine[3]; @@ -287,10 +287,9 @@ static int pmbtoken_issuer_key_from_bytes(const PMBTOKEN_METHOD *method, size_t scalar_len = BN_num_bytes(EC_GROUP_get0_order(group)); EC_SCALAR *scalars[] = {&key->x0, &key->y0, &key->x1, &key->y1, &key->xs, &key->ys}; - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(scalars); i++) { + for (EC_SCALAR *scalar : scalars) { if (!CBS_get_bytes(&cbs, &tmp, scalar_len) || - !ec_scalar_from_bytes(group, scalars[i], CBS_data(&tmp), - CBS_len(&tmp))) { + !ec_scalar_from_bytes(group, scalar, CBS_data(&tmp), CBS_len(&tmp))) { OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_DECODE_FAILURE); return 0; } diff --git a/Sources/CCryptoBoringSSL/crypto/trust_token/trust_token.cc b/Sources/CCryptoBoringSSL/crypto/trust_token/trust_token.cc index 3d2ef5219..b4cd9a165 100644 --- a/Sources/CCryptoBoringSSL/crypto/trust_token/trust_token.cc +++ b/Sources/CCryptoBoringSSL/crypto/trust_token/trust_token.cc @@ -12,12 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. +#include + +#include + #include #include #include #include -#include -#include +#include #include "internal.h" @@ -226,7 +229,7 @@ void TRUST_TOKEN_CLIENT_free(TRUST_TOKEN_CLIENT *ctx) { int TRUST_TOKEN_CLIENT_add_key(TRUST_TOKEN_CLIENT *ctx, size_t *out_key_index, const uint8_t *key, size_t key_len) { - if (ctx->num_keys == OPENSSL_ARRAY_SIZE(ctx->keys) || + if (ctx->num_keys == std::size(ctx->keys) || ctx->num_keys >= ctx->method->max_keys) { OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_TOO_MANY_KEYS); return 0; @@ -462,7 +465,7 @@ void TRUST_TOKEN_ISSUER_free(TRUST_TOKEN_ISSUER *ctx) { int TRUST_TOKEN_ISSUER_add_key(TRUST_TOKEN_ISSUER *ctx, const uint8_t *key, size_t key_len) { - if (ctx->num_keys == OPENSSL_ARRAY_SIZE(ctx->keys) || + if (ctx->num_keys == std::size(ctx->keys) || ctx->num_keys >= ctx->method->max_keys) { OPENSSL_PUT_ERROR(TRUST_TOKEN, TRUST_TOKEN_R_TOO_MANY_KEYS); return 0; diff --git a/Sources/CCryptoBoringSSL/crypto/trust_token/voprf.cc b/Sources/CCryptoBoringSSL/crypto/trust_token/voprf.cc index 7e68d9e71..c91e390b4 100644 --- a/Sources/CCryptoBoringSSL/crypto/trust_token/voprf.cc +++ b/Sources/CCryptoBoringSSL/crypto/trust_token/voprf.cc @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include "../ec/internal.h" #include "../fipsmodule/ec/internal.h" diff --git a/Sources/CCryptoBoringSSL/crypto/x509/a_sign.cc b/Sources/CCryptoBoringSSL/crypto/x509/a_sign.cc index 9004fb431..55c8d790a 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/a_sign.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/a_sign.cc @@ -18,12 +18,16 @@ #include #include #include +#include #include #include +#include "../internal.h" +#include "../mem_internal.h" #include "internal.h" + int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey, const EVP_MD *type) { @@ -41,55 +45,56 @@ int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx) { - int ret = 0; - uint8_t *in = NULL, *out = NULL; - - { - if (signature->type != V_ASN1_BIT_STRING) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TYPE); - goto err; - } + // Historically, this function called |EVP_MD_CTX_cleanup| on return. Some + // callers rely on this to avoid memory leaks. + bssl::Cleanup cleanup = [&] { EVP_MD_CTX_cleanup(ctx); }; - // Write out the requested copies of the AlgorithmIdentifier. - if (algor1 && !x509_digest_sign_algorithm(ctx, algor1)) { - goto err; - } - if (algor2 && !x509_digest_sign_algorithm(ctx, algor2)) { - goto err; - } + // Write out the requested copies of the AlgorithmIdentifier. This may modify + // |asn|, so we must do it first. + if ((algor1 != nullptr && !x509_digest_sign_algorithm(ctx, algor1)) || + (algor2 != nullptr && !x509_digest_sign_algorithm(ctx, algor2))) { + return 0; + } - int in_len = ASN1_item_i2d(reinterpret_cast(asn), &in, it); - if (in_len < 0) { - goto err; - } + uint8_t *in = nullptr; + int in_len = ASN1_item_i2d(reinterpret_cast(asn), &in, it); + if (in_len < 0) { + return 0; + } + bssl::UniquePtr free_in(in); - EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx); - size_t out_len = EVP_PKEY_size(pkey); - if (out_len > INT_MAX) { - OPENSSL_PUT_ERROR(X509, ERR_R_OVERFLOW); - goto err; - } + return x509_sign_to_bit_string(ctx, signature, bssl::Span(in, in_len)); +} - out = reinterpret_cast(OPENSSL_malloc(out_len)); - if (out == NULL) { - goto err; - } +int x509_sign_to_bit_string(EVP_MD_CTX *ctx, ASN1_BIT_STRING *out, + bssl::Span in) { + if (out->type != V_ASN1_BIT_STRING) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_TYPE); + return 0; + } - if (!EVP_DigestSign(ctx, out, &out_len, in, in_len)) { - OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB); - goto err; - } + EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx); + size_t sig_len = EVP_PKEY_size(pkey); + if (sig_len > INT_MAX) { + // Ensure the signature will fit in |out|. + OPENSSL_PUT_ERROR(X509, ERR_R_OVERFLOW); + return 0; + } + bssl::Array sig; + if (!sig.Init(sig_len)) { + return 0; + } - ASN1_STRING_set0(signature, out, (int)out_len); - out = NULL; - signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); - signature->flags |= ASN1_STRING_FLAG_BITS_LEFT; - ret = (int)out_len; + if (!EVP_DigestSign(ctx, sig.data(), &sig_len, in.data(), in.size())) { + OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB); + return 0; } + sig.Shrink(sig_len); -err: - EVP_MD_CTX_cleanup(ctx); - OPENSSL_free(in); - OPENSSL_free(out); - return ret; + uint8_t *sig_data; + sig.Release(&sig_data, &sig_len); + ASN1_STRING_set0(out, sig_data, static_cast(sig_len)); + out->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + out->flags |= ASN1_STRING_FLAG_BITS_LEFT; + return static_cast(sig_len); } diff --git a/Sources/CCryptoBoringSSL/crypto/x509/a_verify.cc b/Sources/CCryptoBoringSSL/crypto/x509/a_verify.cc index 0e15194b8..5b5f881d3 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/a_verify.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/a_verify.cc @@ -17,18 +17,21 @@ #include #include +#include #include #include #include #include #include #include +#include #include "internal.h" -int ASN1_item_verify(const ASN1_ITEM *it, const X509_ALGOR *a, - const ASN1_BIT_STRING *signature, void *asn, - EVP_PKEY *pkey) { + +int x509_verify_signature(const X509_ALGOR *sigalg, + const ASN1_BIT_STRING *signature, + bssl::Span in, EVP_PKEY *pkey) { if (!pkey) { OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER); return 0; @@ -41,34 +44,29 @@ int ASN1_item_verify(const ASN1_ITEM *it, const X509_ALGOR *a, return 0; } } else { - sig_len = (size_t)ASN1_STRING_length(signature); - } - - EVP_MD_CTX ctx; - uint8_t *buf_in = NULL; - int ret = 0, inl = 0; - EVP_MD_CTX_init(&ctx); - - if (!x509_digest_verify_init(&ctx, a, pkey)) { - goto err; + sig_len = static_cast(ASN1_STRING_length(signature)); } - inl = ASN1_item_i2d(reinterpret_cast(asn), &buf_in, it); - - if (buf_in == NULL) { - goto err; + bssl::ScopedEVP_MD_CTX ctx; + if (!x509_digest_verify_init(ctx.get(), sigalg, pkey)) { + return 0; } - - if (!EVP_DigestVerify(&ctx, ASN1_STRING_get0_data(signature), sig_len, buf_in, - inl)) { + if (!EVP_DigestVerify(ctx.get(), ASN1_STRING_get0_data(signature), sig_len, + in.data(), in.size())) { OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB); - goto err; + return 0; } + return 1; +} - ret = 1; - -err: - OPENSSL_free(buf_in); - EVP_MD_CTX_cleanup(&ctx); - return ret; +int ASN1_item_verify(const ASN1_ITEM *it, const X509_ALGOR *sigalg, + const ASN1_BIT_STRING *signature, void *asn, + EVP_PKEY *pkey) { + uint8_t *in = nullptr; + int in_len = ASN1_item_i2d(reinterpret_cast(asn), &in, it); + if (in_len < 0) { + return 0; + } + bssl::UniquePtr free_in(in); + return x509_verify_signature(sigalg, signature, bssl::Span(in, in_len), pkey); } diff --git a/Sources/CCryptoBoringSSL/crypto/x509/algorithm.cc b/Sources/CCryptoBoringSSL/crypto/x509/algorithm.cc index ff68574ab..602d1b675 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/algorithm.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/algorithm.cc @@ -22,6 +22,12 @@ #include "internal.h" + +// TODO(crbug.com/42290422): Rewrite this logic to recognize signature +// algorithms without pulling in the OID table. We can enumerate every supported +// signature algorithm into a small enum and convert them to/from |EVP_PKEY_CTX| +// and |X509_ALGOR|. + // Restrict the digests that are allowed in X509 certificates static int x509_digest_nid_ok(const int digest_nid) { switch (digest_nid) { @@ -39,7 +45,8 @@ int x509_digest_sign_algorithm(EVP_MD_CTX *ctx, X509_ALGOR *algor) { return 0; } - if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) { + if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA || + EVP_PKEY_id(pkey) == EVP_PKEY_RSA_PSS) { int pad_mode; if (!EVP_PKEY_CTX_get_rsa_padding(ctx->pctx, &pad_mode)) { return 0; @@ -88,7 +95,10 @@ int x509_digest_verify_init(EVP_MD_CTX *ctx, const X509_ALGOR *sigalg, } // Check the public key OID matches the public key type. - if (pkey_nid != EVP_PKEY_id(pkey)) { + const bool pkey_matches = + pkey_nid == EVP_PKEY_id(pkey) || + (sigalg_nid == NID_rsassaPss && EVP_PKEY_id(pkey) == EVP_PKEY_RSA_PSS); + if (!pkey_matches) { OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_PUBLIC_KEY_TYPE); return 0; } diff --git a/Sources/CCryptoBoringSSL/crypto/x509/asn1_gen.cc b/Sources/CCryptoBoringSSL/crypto/x509/asn1_gen.cc index 8375f27cc..edec46633 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/asn1_gen.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/asn1_gen.cc @@ -299,9 +299,9 @@ static int generate_v3(CBB *cbb, const char *str, const X509V3_CTX *cnf, {"SET", CBS_ASN1_SET}, }; CBS_ASN1_TAG type = 0; - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kTypes); i++) { - if (cbs_str_equal(&name, kTypes[i].name)) { - type = kTypes[i].type; + for (const auto &t : kTypes) { + if (cbs_str_equal(&name, t.name)) { + type = t.type; break; } } diff --git a/Sources/CCryptoBoringSSL/crypto/x509/by_file.cc b/Sources/CCryptoBoringSSL/crypto/x509/by_file.cc index 491d60b4e..3916fa568 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/by_file.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/by_file.cc @@ -70,9 +70,9 @@ int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type) { for (;;) { x = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL); if (x == NULL) { - uint32_t error = ERR_peek_last_error(); - if (ERR_GET_LIB(error) == ERR_LIB_PEM && - ERR_GET_REASON(error) == PEM_R_NO_START_LINE && count > 0) { + if (ERR_equals(ERR_peek_last_error(), ERR_LIB_PEM, + PEM_R_NO_START_LINE) && + count > 0) { ERR_clear_error(); break; } @@ -131,9 +131,9 @@ int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type) { for (;;) { x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); if (x == NULL) { - uint32_t error = ERR_peek_last_error(); - if (ERR_GET_LIB(error) == ERR_LIB_PEM && - ERR_GET_REASON(error) == PEM_R_NO_START_LINE && count > 0) { + if (ERR_equals(ERR_peek_last_error(), ERR_LIB_PEM, + PEM_R_NO_START_LINE) && + count > 0) { ERR_clear_error(); break; } diff --git a/Sources/CCryptoBoringSSL/crypto/x509/internal.h b/Sources/CCryptoBoringSSL/crypto/x509/internal.h index 955143afb..a4f3be1ee 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/internal.h +++ b/Sources/CCryptoBoringSSL/crypto/x509/internal.h @@ -17,6 +17,7 @@ #include #include +#include #include #include "../asn1/internal.h" @@ -29,21 +30,24 @@ extern "C" { // Internal structures. -typedef struct X509_val_st { - ASN1_TIME *notBefore; - ASN1_TIME *notAfter; -} X509_VAL; - -DECLARE_ASN1_FUNCTIONS_const(X509_VAL) - struct X509_pubkey_st { - X509_ALGOR *algor; - ASN1_BIT_STRING *public_key; + X509_ALGOR algor; + ASN1_BIT_STRING public_key; EVP_PKEY *pkey; } /* X509_PUBKEY */; +void x509_pubkey_init(X509_PUBKEY *key); +void x509_pubkey_cleanup(X509_PUBKEY *key); + +int x509_parse_public_key(CBS *cbs, X509_PUBKEY *out, + bssl::Span algs); +int x509_marshal_public_key(CBB *cbb, const X509_PUBKEY *in); +int x509_pubkey_set1(X509_PUBKEY *key, EVP_PKEY *pkey); + // X509_PUBKEY is an |ASN1_ITEM| whose ASN.1 type is SubjectPublicKeyInfo and C // type is |X509_PUBKEY*|. +// TODO(crbug.com/42290417): Remove this when |X509| and |X509_REQ| no longer +// depend on the tables. DECLARE_ASN1_ITEM(X509_PUBKEY) struct X509_name_entry_st { @@ -97,28 +101,31 @@ DECLARE_ASN1_ITEM(X509_EXTENSION) // (RFC 5280) and C type is |STACK_OF(X509_EXTENSION)*|. DECLARE_ASN1_ITEM(X509_EXTENSIONS) -typedef struct { - ASN1_INTEGER *version; // [ 0 ] default of v1 - ASN1_INTEGER *serialNumber; - X509_ALGOR *signature; +struct x509_st { + // TBSCertificate fields: + uint8_t version; // One of the |X509_VERSION_*| constants. + ASN1_INTEGER serialNumber; + X509_ALGOR tbs_sig_alg; + // TODO(crbug.com/42290417): When |X509_NAME| no longer uses the macro system, + // try to embed this struct. X509_NAME *issuer; - X509_VAL *validity; + ASN1_TIME notBefore; + ASN1_TIME notAfter; + // TODO(crbug.com/42290417): When |X509_NAME| no longer uses the macro system, + // try to embed this struct. X509_NAME *subject; - X509_PUBKEY *key; + X509_PUBKEY key; ASN1_BIT_STRING *issuerUID; // [ 1 ] optional in v2 ASN1_BIT_STRING *subjectUID; // [ 2 ] optional in v2 STACK_OF(X509_EXTENSION) *extensions; // [ 3 ] optional in v3 - ASN1_ENCODING enc; -} X509_CINF; - -// TODO(https://crbug.com/boringssl/407): This is not const because it contains -// an |X509_NAME|. -DECLARE_ASN1_FUNCTIONS(X509_CINF) - -struct x509_st { - X509_CINF *cert_info; - X509_ALGOR *sig_alg; - ASN1_BIT_STRING *signature; + // Certificate fields: + X509_ALGOR sig_alg; + ASN1_BIT_STRING signature; + // Other state: + // buf, if not nullptr, contains a copy of the serialized Certificate. + // TODO(davidben): Now every parsed |X509| has an underlying |CRYPTO_BUFFER|, + // but |X509|s created peacemeal do not. Can we make this more uniform? + CRYPTO_BUFFER *buf; CRYPTO_refcount_t references; CRYPTO_EX_DATA ex_data; // These contain copies of various extension values @@ -136,6 +143,8 @@ struct x509_st { CRYPTO_MUTEX lock; } /* X509 */; +int x509_marshal_tbs_cert(CBB *cbb, X509 *x509); + // X509 is an |ASN1_ITEM| whose ASN.1 type is X.509 Certificate (RFC 5280) and C // type is |X509*|. DECLARE_ASN1_ITEM(X509) @@ -385,6 +394,17 @@ int x509_digest_sign_algorithm(EVP_MD_CTX *ctx, X509_ALGOR *algor); int x509_digest_verify_init(EVP_MD_CTX *ctx, const X509_ALGOR *sigalg, EVP_PKEY *pkey); +// x509_verify_signature verifies a |signature| using |sigalg| and |pkey| over +// |in|. It returns one if the signature is valid and zero on error. +int x509_verify_signature(const X509_ALGOR *sigalg, + const ASN1_BIT_STRING *signature, + bssl::Span in, EVP_PKEY *pkey); + +// x509_sign_to_bit_string signs |in| using |ctx| and saves the result in |out|. +// It returns the length of the signature on success and zero on error. +int x509_sign_to_bit_string(EVP_MD_CTX *ctx, ASN1_BIT_STRING *out, + bssl::Span in); + // Path-building functions. @@ -555,6 +575,13 @@ int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname); // mutated. int x509_marshal_name(CBB *out, X509_NAME *in); +void x509_algor_init(X509_ALGOR *alg); +void x509_algor_cleanup(X509_ALGOR *alg); + +// x509_parse_algorithm parses a DER-encoded, AlgorithmIdentifier from |cbs| and +// writes the result to |*out|. It returns one on success and zero on error. +int x509_parse_algorithm(CBS *cbs, X509_ALGOR *out); + // x509_marshal_algorithm marshals |in| as a DER-encoded, AlgorithmIdentifier // and writes the result to |out|. It returns one on success and zero on error. int x509_marshal_algorithm(CBB *out, const X509_ALGOR *in); diff --git a/Sources/CCryptoBoringSSL/crypto/x509/rsa_pss.cc b/Sources/CCryptoBoringSSL/crypto/x509/rsa_pss.cc index 663476480..395e210d3 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/rsa_pss.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/rsa_pss.cc @@ -19,11 +19,14 @@ #include #include +#include #include #include #include #include +#include +#include "../rsa/internal.h" #include "internal.h" @@ -46,111 +49,18 @@ ASN1_SEQUENCE_cb(RSA_PSS_PARAMS, rsa_pss_cb) = { IMPLEMENT_ASN1_FUNCTIONS_const(RSA_PSS_PARAMS) -// Given an MGF1 Algorithm ID decode to an Algorithm Identifier -static X509_ALGOR *rsa_mgf1_decode(const X509_ALGOR *alg) { - if (OBJ_obj2nid(alg->algorithm) != NID_mgf1 || alg->parameter == NULL || - alg->parameter->type != V_ASN1_SEQUENCE) { - return NULL; - } - - const uint8_t *p = alg->parameter->value.sequence->data; - int plen = alg->parameter->value.sequence->length; - return d2i_X509_ALGOR(NULL, &p, plen); -} - -static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg) { - if (alg->parameter == NULL || alg->parameter->type != V_ASN1_SEQUENCE) { - return NULL; - } - - const uint8_t *p = alg->parameter->value.sequence->data; - int plen = alg->parameter->value.sequence->length; - return d2i_RSA_PSS_PARAMS(NULL, &p, plen); -} - -static int is_allowed_pss_md(const EVP_MD *md) { - int md_type = EVP_MD_type(md); - return md_type == NID_sha256 || md_type == NID_sha384 || - md_type == NID_sha512; -} - -// rsa_md_to_algor sets |*palg| to an |X509_ALGOR| describing the digest |md|, -// which must be an allowed PSS digest. -static int rsa_md_to_algor(X509_ALGOR **palg, const EVP_MD *md) { - // SHA-1 should be omitted (DEFAULT), but we do not allow SHA-1. - assert(is_allowed_pss_md(md)); - *palg = X509_ALGOR_new(); - if (*palg == NULL) { +static int rsa_pss_decode(const X509_ALGOR *alg, rsa_pss_params_t *out) { + if (alg->parameter == nullptr || alg->parameter->type != V_ASN1_SEQUENCE) { return 0; } - if (!X509_ALGOR_set_md(*palg, md)) { - X509_ALGOR_free(*palg); - *palg = NULL; - return 0; - } - return 1; -} - -// rsa_md_to_mgf1 sets |*palg| to an |X509_ALGOR| describing MGF-1 with the -// digest |mgf1md|, which must be an allowed PSS digest. -static int rsa_md_to_mgf1(X509_ALGOR **palg, const EVP_MD *mgf1md) { - // SHA-1 should be omitted (DEFAULT), but we do not allow SHA-1. - assert(is_allowed_pss_md(mgf1md)); - X509_ALGOR *algtmp = NULL; - ASN1_STRING *stmp = NULL; - // need to embed algorithm ID inside another - if (!rsa_md_to_algor(&algtmp, mgf1md) || - !ASN1_item_pack(algtmp, ASN1_ITEM_rptr(X509_ALGOR), &stmp)) { - goto err; - } - *palg = X509_ALGOR_new(); - if (!*palg) { - goto err; - } - if (!X509_ALGOR_set0(*palg, OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, stmp)) { - goto err; - } - stmp = NULL; - -err: - ASN1_STRING_free(stmp); - X509_ALGOR_free(algtmp); - if (*palg) { - return 1; - } - return 0; -} - -static const EVP_MD *rsa_algor_to_md(const X509_ALGOR *alg) { - if (!alg) { - // If omitted, PSS defaults to SHA-1, which we do not allow. - OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); - return NULL; - } - const EVP_MD *md = EVP_get_digestbyobj(alg->algorithm); - if (md == NULL || !is_allowed_pss_md(md)) { - OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); - return NULL; - } - return md; -} - -static const EVP_MD *rsa_mgf1_to_md(const X509_ALGOR *alg) { - if (!alg) { - // If omitted, PSS defaults to MGF-1 with SHA-1, which we do not allow. - OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); - return NULL; - } - // Check mask and lookup mask hash algorithm. - X509_ALGOR *maskHash = rsa_mgf1_decode(alg); - if (maskHash == NULL) { - OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); - return NULL; - } - const EVP_MD *ret = rsa_algor_to_md(maskHash); - X509_ALGOR_free(maskHash); - return ret; + // Although a syntax error in DER, we tolerate an explicitly-encoded trailer. + // See the certificates in cl/362617931. + CBS cbs; + CBS_init(&cbs, alg->parameter->value.sequence->data, + alg->parameter->value.sequence->length); + return rsa_parse_pss_params(&cbs, out, /*allow_explicit_trailer=*/true) && + CBS_len(&cbs) == 0; } int x509_rsa_ctx_to_pss(EVP_MD_CTX *ctx, X509_ALGOR *algor) { @@ -162,203 +72,111 @@ int x509_rsa_ctx_to_pss(EVP_MD_CTX *ctx, X509_ALGOR *algor) { return 0; } - if (sigmd != mgf1md || !is_allowed_pss_md(sigmd)) { + if (sigmd != mgf1md) { OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); return 0; } int md_len = (int)EVP_MD_size(sigmd); - if (saltlen == -1) { - saltlen = md_len; - } else if (saltlen != md_len) { + if (saltlen != RSA_PSS_SALTLEN_DIGEST && saltlen != md_len) { OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); return 0; } - int ret = 0; - ASN1_STRING *os = NULL; - RSA_PSS_PARAMS *pss = RSA_PSS_PARAMS_new(); - if (!pss) { - goto err; - } - - // The DEFAULT value is 20, but this does not match any supported digest. - assert(saltlen != 20); - pss->saltLength = ASN1_INTEGER_new(); - if (!pss->saltLength || // - !ASN1_INTEGER_set_int64(pss->saltLength, saltlen)) { - goto err; + rsa_pss_params_t params; + switch (EVP_MD_type(sigmd)) { + case NID_sha256: + params = rsa_pss_sha256; + break; + case NID_sha384: + params = rsa_pss_sha384; + break; + case NID_sha512: + params = rsa_pss_sha512; + break; + default: + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); + return 0; } - if (!rsa_md_to_algor(&pss->hashAlgorithm, sigmd) || - !rsa_md_to_mgf1(&pss->maskGenAlgorithm, mgf1md)) { - goto err; + // Encode |params| to an |ASN1_STRING|. + uint8_t buf[128]; // The largest param fits comfortably in 128 bytes. + CBB cbb; + CBB_init_fixed(&cbb, buf, sizeof(buf)); + if (!rsa_marshal_pss_params(&cbb, params)) { + return 0; } - - // Finally create string with pss parameter encoding. - if (!ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), &os)) { - goto err; + bssl::UniquePtr params_str( + ASN1_STRING_type_new(V_ASN1_SEQUENCE)); + if (params_str == nullptr || + !ASN1_STRING_set(params_str.get(), CBB_data(&cbb), CBB_len(&cbb))) { + return 0; } if (!X509_ALGOR_set0(algor, OBJ_nid2obj(NID_rsassaPss), V_ASN1_SEQUENCE, - os)) { - goto err; + params_str.get())) { + return 0; } - os = NULL; - ret = 1; - -err: - RSA_PSS_PARAMS_free(pss); - ASN1_STRING_free(os); - return ret; + params_str.release(); // |X509_ALGOR_set0| took ownership. + return 1; } int x509_rsa_pss_to_ctx(EVP_MD_CTX *ctx, const X509_ALGOR *sigalg, EVP_PKEY *pkey) { assert(OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss); + rsa_pss_params_t params; + if (!rsa_pss_decode(sigalg, ¶ms)) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); + return 0; + } - // Decode PSS parameters - int ret = 0; - RSA_PSS_PARAMS *pss = rsa_pss_decode(sigalg); - - { - if (pss == NULL) { - OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); - goto err; - } - - const EVP_MD *mgf1md = rsa_mgf1_to_md(pss->maskGenAlgorithm); - const EVP_MD *md = rsa_algor_to_md(pss->hashAlgorithm); - if (mgf1md == NULL || md == NULL) { - goto err; - } - - // We require the MGF-1 and signing hashes to match. - if (mgf1md != md) { - OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); - goto err; - } - - // We require the salt length be the hash length. The DEFAULT value is 20, - // but this does not match any supported salt length. - uint64_t salt_len = 0; - if (pss->saltLength == NULL || - !ASN1_INTEGER_get_uint64(&salt_len, pss->saltLength) || - salt_len != EVP_MD_size(md)) { - OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); - goto err; - } - assert(salt_len <= INT_MAX); - - // The trailer field must be 1 (0xbc). This value is DEFAULT, so the - // structure is required to omit it in DER. Although a syntax error, we also - // tolerate an explicitly-encoded value. See the certificates in - // cl/362617931. - if (pss->trailerField != NULL && ASN1_INTEGER_get(pss->trailerField) != 1) { - OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); - goto err; - } - - EVP_PKEY_CTX *pctx; - if (!EVP_DigestVerifyInit(ctx, &pctx, md, NULL, pkey) || - !EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) || - !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, (int)salt_len) || - !EVP_PKEY_CTX_set_rsa_mgf1_md(pctx, mgf1md)) { - goto err; - } - - ret = 1; + const EVP_MD *md = rsa_pss_params_get_md(params); + EVP_PKEY_CTX *pctx; + if (!EVP_DigestVerifyInit(ctx, &pctx, md, nullptr, pkey) || + !EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) || + !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, RSA_PSS_SALTLEN_DIGEST) || + !EVP_PKEY_CTX_set_rsa_mgf1_md(pctx, md)) { + return 0; } -err: - RSA_PSS_PARAMS_free(pss); - return ret; + return 1; } int x509_print_rsa_pss_params(BIO *bp, const X509_ALGOR *sigalg, int indent, ASN1_PCTX *pctx) { assert(OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss); - - int rv = 0; - X509_ALGOR *maskHash = NULL; - RSA_PSS_PARAMS *pss = rsa_pss_decode(sigalg); - if (!pss) { - if (BIO_puts(bp, " (INVALID PSS PARAMETERS)\n") <= 0) { - goto err; - } - rv = 1; - goto err; + rsa_pss_params_t params; + if (!rsa_pss_decode(sigalg, ¶ms)) { + return BIO_puts(bp, " (INVALID PSS PARAMETERS)\n") <= 0; + } + + const char *hash_str = nullptr; + uint32_t salt_len = 0; + switch (params) { + case rsa_pss_sha256: + hash_str = "sha256"; + salt_len = 32; + break; + case rsa_pss_sha384: + hash_str = "sha384"; + salt_len = 48; + break; + case rsa_pss_sha512: + hash_str = "sha512"; + salt_len = 64; + break; } if (BIO_puts(bp, "\n") <= 0 || // !BIO_indent(bp, indent, 128) || // - BIO_puts(bp, "Hash Algorithm: ") <= 0) { - goto err; - } - - if (pss->hashAlgorithm) { - if (i2a_ASN1_OBJECT(bp, pss->hashAlgorithm->algorithm) <= 0) { - goto err; - } - } else if (BIO_puts(bp, "sha1 (default)") <= 0) { - goto err; - } - - if (BIO_puts(bp, "\n") <= 0 || // + BIO_printf(bp, "Hash Algorithm: %s\n", hash_str) <= 0 || !BIO_indent(bp, indent, 128) || // - BIO_puts(bp, "Mask Algorithm: ") <= 0) { - goto err; - } - - if (pss->maskGenAlgorithm) { - maskHash = rsa_mgf1_decode(pss->maskGenAlgorithm); - if (maskHash == NULL) { - if (BIO_puts(bp, "INVALID") <= 0) { - goto err; - } - } else { - if (i2a_ASN1_OBJECT(bp, pss->maskGenAlgorithm->algorithm) <= 0 || - BIO_puts(bp, " with ") <= 0 || - i2a_ASN1_OBJECT(bp, maskHash->algorithm) <= 0) { - goto err; - } - } - } else if (BIO_puts(bp, "mgf1 with sha1 (default)") <= 0) { - goto err; - } - BIO_puts(bp, "\n"); - - if (!BIO_indent(bp, indent, 128) || // - BIO_puts(bp, "Salt Length: 0x") <= 0) { - goto err; - } - - if (pss->saltLength) { - if (i2a_ASN1_INTEGER(bp, pss->saltLength) <= 0) { - goto err; - } - } else if (BIO_puts(bp, "14 (default)") <= 0) { - goto err; - } - BIO_puts(bp, "\n"); - - if (!BIO_indent(bp, indent, 128) || // - BIO_puts(bp, "Trailer Field: 0x") <= 0) { - goto err; - } - - if (pss->trailerField) { - if (i2a_ASN1_INTEGER(bp, pss->trailerField) <= 0) { - goto err; - } - } else if (BIO_puts(bp, "BC (default)") <= 0) { - goto err; + BIO_printf(bp, "Mask Algorithm: mgf1 with %s\n", hash_str) <= 0 || + !BIO_indent(bp, indent, 128) || // + BIO_printf(bp, "Salt Length: 0x%x\n", salt_len) <= 0 || + !BIO_indent(bp, indent, 128) || // + BIO_puts(bp, "Trailer Field: 0xBC (default)\n") <= 0) { + return 0; } - BIO_puts(bp, "\n"); - rv = 1; - -err: - RSA_PSS_PARAMS_free(pss); - X509_ALGOR_free(maskHash); - return rv; + return 1; } diff --git a/Sources/CCryptoBoringSSL/crypto/x509/t_req.cc b/Sources/CCryptoBoringSSL/crypto/x509/t_req.cc index a7c62e019..8a778ba69 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/t_req.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/t_req.cc @@ -79,7 +79,7 @@ int X509_REQ_print_ex(BIO *bio, X509_REQ *x, unsigned long nmflags, if (!(cflag & X509_FLAG_NO_PUBKEY)) { if (BIO_write(bio, " Subject Public Key Info:\n", 33) <= 0 || BIO_printf(bio, "%12sPublic Key Algorithm: ", "") <= 0 || - i2a_ASN1_OBJECT(bio, ri->pubkey->algor->algorithm) <= 0 || + i2a_ASN1_OBJECT(bio, ri->pubkey->algor.algorithm) <= 0 || BIO_puts(bio, "\n") <= 0) { goto err; } diff --git a/Sources/CCryptoBoringSSL/crypto/x509/t_x509.cc b/Sources/CCryptoBoringSSL/crypto/x509/t_x509.cc index 6f8be6c22..97fb41435 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/t_x509.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/t_x509.cc @@ -60,7 +60,6 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, nmindent = 16; } - const X509_CINF *ci = x->cert_info; if (!(cflag & X509_FLAG_NO_HEADER)) { if (BIO_write(bp, "Certificate:\n", 13) <= 0) { return 0; @@ -108,7 +107,7 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, } if (!(cflag & X509_FLAG_NO_SIGNAME)) { - if (X509_signature_print(bp, ci->signature, NULL) <= 0) { + if (X509_signature_print(bp, &x->tbs_sig_alg, NULL) <= 0) { return 0; } } @@ -164,7 +163,7 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0) { return 0; } - if (i2a_ASN1_OBJECT(bp, ci->key->algor->algorithm) <= 0) { + if (i2a_ASN1_OBJECT(bp, x->key.algor.algorithm) <= 0) { return 0; } if (BIO_puts(bp, "\n") <= 0) { @@ -181,30 +180,30 @@ int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, } if (!(cflag & X509_FLAG_NO_IDS)) { - if (ci->issuerUID) { + if (x->issuerUID) { if (BIO_printf(bp, "%8sIssuer Unique ID: ", "") <= 0) { return 0; } - if (!X509_signature_dump(bp, ci->issuerUID, 12)) { + if (!X509_signature_dump(bp, x->issuerUID, 12)) { return 0; } } - if (ci->subjectUID) { + if (x->subjectUID) { if (BIO_printf(bp, "%8sSubject Unique ID: ", "") <= 0) { return 0; } - if (!X509_signature_dump(bp, ci->subjectUID, 12)) { + if (!X509_signature_dump(bp, x->subjectUID, 12)) { return 0; } } } if (!(cflag & X509_FLAG_NO_EXTENSIONS)) { - X509V3_extensions_print(bp, "X509v3 extensions", ci->extensions, cflag, 8); + X509V3_extensions_print(bp, "X509v3 extensions", x->extensions, cflag, 8); } if (!(cflag & X509_FLAG_NO_SIGDUMP)) { - if (X509_signature_print(bp, x->sig_alg, x->signature) <= 0) { + if (X509_signature_print(bp, &x->sig_alg, &x->signature) <= 0) { return 0; } } diff --git a/Sources/CCryptoBoringSSL/crypto/x509/v3_conf.cc b/Sources/CCryptoBoringSSL/crypto/x509/v3_conf.cc index 80588dad7..1e8c47703 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/v3_conf.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/v3_conf.cc @@ -308,7 +308,7 @@ int X509V3_EXT_add_nconf(const CONF *conf, const X509V3_CTX *ctx, const char *section, X509 *cert) { STACK_OF(X509_EXTENSION) **sk = NULL; if (cert) { - sk = &cert->cert_info->extensions; + sk = &cert->extensions; } return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); } diff --git a/Sources/CCryptoBoringSSL/crypto/x509/v3_purp.cc b/Sources/CCryptoBoringSSL/crypto/x509/v3_purp.cc index 4ab83a75e..fbe08767b 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/v3_purp.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/v3_purp.cc @@ -105,18 +105,18 @@ int X509_check_purpose(X509 *x, int id, int ca) { } const X509_PURPOSE *X509_PURPOSE_get0(int id) { - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(xstandard); i++) { - if (xstandard[i].purpose == id) { - return &xstandard[i]; + for (const auto &p : xstandard) { + if (p.purpose == id) { + return &p; } } return NULL; } int X509_PURPOSE_get_by_sname(const char *sname) { - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(xstandard); i++) { - if (strcmp(xstandard[i].sname, sname) == 0) { - return xstandard[i].purpose; + for (const auto &p : xstandard) { + if (strcmp(p.sname, sname) == 0) { + return p.purpose; } } return -1; diff --git a/Sources/CCryptoBoringSSL/crypto/x509/v3_skey.cc b/Sources/CCryptoBoringSSL/crypto/x509/v3_skey.cc index 3dd128908..704c0613f 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/v3_skey.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/v3_skey.cc @@ -65,7 +65,7 @@ static char *i2s_ASN1_OCTET_STRING_cb(const X509V3_EXT_METHOD *method, static void *s2i_skey_id(const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx, const char *str) { ASN1_OCTET_STRING *oct; - ASN1_BIT_STRING *pk; + const ASN1_BIT_STRING *pk; unsigned char pkey_dig[EVP_MAX_MD_SIZE]; unsigned int diglen; @@ -87,14 +87,9 @@ static void *s2i_skey_id(const X509V3_EXT_METHOD *method, const X509V3_CTX *ctx, } if (ctx->subject_req) { - pk = ctx->subject_req->req_info->pubkey->public_key; + pk = &ctx->subject_req->req_info->pubkey->public_key; } else { - pk = ctx->subject_cert->cert_info->key->public_key; - } - - if (!pk) { - OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_PUBLIC_KEY); - goto err; + pk = &ctx->subject_cert->key.public_key; } if (!EVP_Digest(pk->data, pk->length, pkey_dig, &diglen, EVP_sha1(), NULL)) { diff --git a/Sources/CCryptoBoringSSL/crypto/x509/x509_cmp.cc b/Sources/CCryptoBoringSSL/crypto/x509/x509_cmp.cc index a857d0f7e..fcfdf81fa 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/x509_cmp.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/x509_cmp.cc @@ -29,15 +29,15 @@ int X509_issuer_name_cmp(const X509 *a, const X509 *b) { - return (X509_NAME_cmp(a->cert_info->issuer, b->cert_info->issuer)); + return X509_NAME_cmp(a->issuer, b->issuer); } int X509_subject_name_cmp(const X509 *a, const X509 *b) { - return (X509_NAME_cmp(a->cert_info->subject, b->cert_info->subject)); + return X509_NAME_cmp(a->subject, b->subject); } int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b) { - return (X509_NAME_cmp(a->crl->issuer, b->crl->issuer)); + return X509_NAME_cmp(a->crl->issuer, b->crl->issuer); } int X509_CRL_match(const X509_CRL *a, const X509_CRL *b) { @@ -45,35 +45,31 @@ int X509_CRL_match(const X509_CRL *a, const X509_CRL *b) { } X509_NAME *X509_get_issuer_name(const X509 *a) { - return a->cert_info->issuer; + // This function is not const-correct for OpenSSL compatibility. + return a->issuer; } -uint32_t X509_issuer_name_hash(X509 *x) { - return X509_NAME_hash(x->cert_info->issuer); -} +uint32_t X509_issuer_name_hash(X509 *x) { return X509_NAME_hash(x->issuer); } uint32_t X509_issuer_name_hash_old(X509 *x) { - return (X509_NAME_hash_old(x->cert_info->issuer)); + return X509_NAME_hash_old(x->issuer); } X509_NAME *X509_get_subject_name(const X509 *a) { - return a->cert_info->subject; + // This function is not const-correct for OpenSSL compatibility. + return a->subject; } -ASN1_INTEGER *X509_get_serialNumber(X509 *a) { - return a->cert_info->serialNumber; -} +ASN1_INTEGER *X509_get_serialNumber(X509 *a) { return &a->serialNumber; } const ASN1_INTEGER *X509_get0_serialNumber(const X509 *x509) { - return x509->cert_info->serialNumber; + return &x509->serialNumber; } -uint32_t X509_subject_name_hash(X509 *x) { - return X509_NAME_hash(x->cert_info->subject); -} +uint32_t X509_subject_name_hash(X509 *x) { return X509_NAME_hash(x->subject); } uint32_t X509_subject_name_hash_old(X509 *x) { - return X509_NAME_hash_old(x->cert_info->subject); + return X509_NAME_hash_old(x->subject); } // Compare two certificates: they must be identical for this to work. NB: @@ -180,21 +176,22 @@ EVP_PKEY *X509_get0_pubkey(const X509 *x) { if (x == NULL) { return NULL; } - return X509_PUBKEY_get0(x->cert_info->key); + return X509_PUBKEY_get0(&x->key); } EVP_PKEY *X509_get_pubkey(const X509 *x) { if (x == NULL) { return NULL; } - return X509_PUBKEY_get(x->cert_info->key); + return X509_PUBKEY_get(&x->key); } ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x) { if (!x) { return NULL; } - return x->cert_info->key->public_key; + // This function is not const-correct for OpenSSL compatibility. + return const_cast(&x->key.public_key); } int X509_check_private_key(const X509 *x, const EVP_PKEY *k) { diff --git a/Sources/CCryptoBoringSSL/crypto/x509/x509_ext.cc b/Sources/CCryptoBoringSSL/crypto/x509/x509_ext.cc index 76f8591ce..8de88f08c 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/x509_ext.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/x509_ext.cc @@ -21,28 +21,38 @@ #include "internal.h" int X509_CRL_get_ext_count(const X509_CRL *x) { - return (X509v3_get_ext_count(x->crl->extensions)); + return X509v3_get_ext_count(x->crl->extensions); } int X509_CRL_get_ext_by_NID(const X509_CRL *x, int nid, int lastpos) { - return (X509v3_get_ext_by_NID(x->crl->extensions, nid, lastpos)); + return X509v3_get_ext_by_NID(x->crl->extensions, nid, lastpos); } int X509_CRL_get_ext_by_OBJ(const X509_CRL *x, const ASN1_OBJECT *obj, int lastpos) { - return (X509v3_get_ext_by_OBJ(x->crl->extensions, obj, lastpos)); + return X509v3_get_ext_by_OBJ(x->crl->extensions, obj, lastpos); } int X509_CRL_get_ext_by_critical(const X509_CRL *x, int crit, int lastpos) { - return (X509v3_get_ext_by_critical(x->crl->extensions, crit, lastpos)); + return X509v3_get_ext_by_critical(x->crl->extensions, crit, lastpos); } X509_EXTENSION *X509_CRL_get_ext(const X509_CRL *x, int loc) { - return (X509v3_get_ext(x->crl->extensions, loc)); + return X509v3_get_ext(x->crl->extensions, loc); +} + +static X509_EXTENSION *delete_ext(STACK_OF(X509_EXTENSION) **exts, int loc) { + X509_EXTENSION *ext = X509v3_delete_ext(*exts, loc); + // Empty extension lists are omitted. + if (*exts != nullptr && sk_X509_EXTENSION_num(*exts) == 0) { + sk_X509_EXTENSION_pop_free(*exts, X509_EXTENSION_free); + *exts = nullptr; + } + return ext; } X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc) { - return (X509v3_delete_ext(x->crl->extensions, loc)); + return delete_ext(&x->crl->extensions, loc); } void *X509_CRL_get_ext_d2i(const X509_CRL *crl, int nid, int *out_critical, @@ -56,76 +66,75 @@ int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit, } int X509_CRL_add_ext(X509_CRL *x, const X509_EXTENSION *ex, int loc) { - return (X509v3_add_ext(&(x->crl->extensions), ex, loc) != NULL); + return X509v3_add_ext(&x->crl->extensions, ex, loc) != NULL; } int X509_get_ext_count(const X509 *x) { - return (X509v3_get_ext_count(x->cert_info->extensions)); + return X509v3_get_ext_count(x->extensions); } int X509_get_ext_by_NID(const X509 *x, int nid, int lastpos) { - return (X509v3_get_ext_by_NID(x->cert_info->extensions, nid, lastpos)); + return X509v3_get_ext_by_NID(x->extensions, nid, lastpos); } int X509_get_ext_by_OBJ(const X509 *x, const ASN1_OBJECT *obj, int lastpos) { - return (X509v3_get_ext_by_OBJ(x->cert_info->extensions, obj, lastpos)); + return X509v3_get_ext_by_OBJ(x->extensions, obj, lastpos); } int X509_get_ext_by_critical(const X509 *x, int crit, int lastpos) { - return (X509v3_get_ext_by_critical(x->cert_info->extensions, crit, lastpos)); + return X509v3_get_ext_by_critical(x->extensions, crit, lastpos); } X509_EXTENSION *X509_get_ext(const X509 *x, int loc) { - return (X509v3_get_ext(x->cert_info->extensions, loc)); + return X509v3_get_ext(x->extensions, loc); } X509_EXTENSION *X509_delete_ext(X509 *x, int loc) { - return (X509v3_delete_ext(x->cert_info->extensions, loc)); + return delete_ext(&x->extensions, loc); } int X509_add_ext(X509 *x, const X509_EXTENSION *ex, int loc) { - return (X509v3_add_ext(&(x->cert_info->extensions), ex, loc) != NULL); + return X509v3_add_ext(&x->extensions, ex, loc) != NULL; } void *X509_get_ext_d2i(const X509 *x509, int nid, int *out_critical, int *out_idx) { - return X509V3_get_d2i(x509->cert_info->extensions, nid, out_critical, - out_idx); + return X509V3_get_d2i(x509->extensions, nid, out_critical, out_idx); } int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit, unsigned long flags) { - return X509V3_add1_i2d(&x->cert_info->extensions, nid, value, crit, flags); + return X509V3_add1_i2d(&x->extensions, nid, value, crit, flags); } int X509_REVOKED_get_ext_count(const X509_REVOKED *x) { - return (X509v3_get_ext_count(x->extensions)); + return X509v3_get_ext_count(x->extensions); } int X509_REVOKED_get_ext_by_NID(const X509_REVOKED *x, int nid, int lastpos) { - return (X509v3_get_ext_by_NID(x->extensions, nid, lastpos)); + return X509v3_get_ext_by_NID(x->extensions, nid, lastpos); } int X509_REVOKED_get_ext_by_OBJ(const X509_REVOKED *x, const ASN1_OBJECT *obj, int lastpos) { - return (X509v3_get_ext_by_OBJ(x->extensions, obj, lastpos)); + return X509v3_get_ext_by_OBJ(x->extensions, obj, lastpos); } int X509_REVOKED_get_ext_by_critical(const X509_REVOKED *x, int crit, int lastpos) { - return (X509v3_get_ext_by_critical(x->extensions, crit, lastpos)); + return X509v3_get_ext_by_critical(x->extensions, crit, lastpos); } X509_EXTENSION *X509_REVOKED_get_ext(const X509_REVOKED *x, int loc) { - return (X509v3_get_ext(x->extensions, loc)); + return X509v3_get_ext(x->extensions, loc); } X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc) { - return (X509v3_delete_ext(x->extensions, loc)); + return delete_ext(&x->extensions, loc); } int X509_REVOKED_add_ext(X509_REVOKED *x, const X509_EXTENSION *ex, int loc) { - return (X509v3_add_ext(&(x->extensions), ex, loc) != NULL); + return X509v3_add_ext(&x->extensions, ex, loc) != NULL; } void *X509_REVOKED_get_ext_d2i(const X509_REVOKED *revoked, int nid, diff --git a/Sources/CCryptoBoringSSL/crypto/x509/x509_lu.cc b/Sources/CCryptoBoringSSL/crypto/x509/x509_lu.cc index d8761324a..6a9173b1b 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/x509_lu.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/x509_lu.cc @@ -287,7 +287,6 @@ static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type, X509_NAME *name, int *pnmatch) { X509_OBJECT stmp; X509 x509_s; - X509_CINF cinf_s; X509_CRL crl_s; X509_CRL_INFO crl_info_s; @@ -295,8 +294,7 @@ static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type, switch (type) { case X509_LU_X509: stmp.data.x509 = &x509_s; - x509_s.cert_info = &cinf_s; - cinf_s.subject = name; + x509_s.subject = name; break; case X509_LU_CRL: stmp.data.crl = &crl_s; diff --git a/Sources/CCryptoBoringSSL/crypto/x509/x509_set.cc b/Sources/CCryptoBoringSSL/crypto/x509/x509_set.cc index eb35621fd..22679acf0 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/x509_set.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/x509_set.cc @@ -21,13 +21,7 @@ #include "internal.h" -long X509_get_version(const X509 *x509) { - // The default version is v1(0). - if (x509->cert_info->version == NULL) { - return X509_VERSION_1; - } - return ASN1_INTEGER_get(x509->cert_info->version); -} +long X509_get_version(const X509 *x509) { return x509->version; } int X509_set_version(X509 *x, long version) { if (x == NULL) { @@ -39,20 +33,8 @@ int X509_set_version(X509 *x, long version) { return 0; } - // v1(0) is default and is represented by omitting the version. - if (version == X509_VERSION_1) { - ASN1_INTEGER_free(x->cert_info->version); - x->cert_info->version = NULL; - return 1; - } - - if (x->cert_info->version == NULL) { - x->cert_info->version = ASN1_INTEGER_new(); - if (x->cert_info->version == NULL) { - return 0; - } - } - return ASN1_INTEGER_set_int64(x->cert_info->version, version); + x->version = static_cast(version); + return 1; } int X509_set_serialNumber(X509 *x, const ASN1_INTEGER *serial) { @@ -61,138 +43,99 @@ int X509_set_serialNumber(X509 *x, const ASN1_INTEGER *serial) { return 0; } - ASN1_INTEGER *in; - if (x == NULL) { - return 0; - } - in = x->cert_info->serialNumber; - if (in != serial) { - in = ASN1_INTEGER_dup(serial); - if (in != NULL) { - ASN1_INTEGER_free(x->cert_info->serialNumber); - x->cert_info->serialNumber = in; - } - } - return in != NULL; + return ASN1_STRING_copy(&x->serialNumber, serial); } int X509_set_issuer_name(X509 *x, X509_NAME *name) { - if ((x == NULL) || (x->cert_info == NULL)) { + if (x == NULL) { return 0; } - return (X509_NAME_set(&x->cert_info->issuer, name)); + return (X509_NAME_set(&x->issuer, name)); } int X509_set_subject_name(X509 *x, X509_NAME *name) { - if ((x == NULL) || (x->cert_info == NULL)) { + if (x == NULL) { return 0; } - return (X509_NAME_set(&x->cert_info->subject, name)); + return (X509_NAME_set(&x->subject, name)); } int X509_set1_notBefore(X509 *x, const ASN1_TIME *tm) { - ASN1_TIME *in; - - if ((x == NULL) || (x->cert_info->validity == NULL)) { - return 0; - } - in = x->cert_info->validity->notBefore; - if (in != tm) { - in = ASN1_STRING_dup(tm); - if (in != NULL) { - ASN1_TIME_free(x->cert_info->validity->notBefore); - x->cert_info->validity->notBefore = in; - } - } - return in != NULL; + // TODO(crbug.com/42290309): Check that |tm->type| is correct. + return ASN1_STRING_copy(&x->notBefore, tm); } int X509_set_notBefore(X509 *x, const ASN1_TIME *tm) { return X509_set1_notBefore(x, tm); } -const ASN1_TIME *X509_get0_notBefore(const X509 *x) { - return x->cert_info->validity->notBefore; -} +const ASN1_TIME *X509_get0_notBefore(const X509 *x) { return &x->notBefore; } ASN1_TIME *X509_getm_notBefore(X509 *x) { // Note this function takes a const |X509| pointer in OpenSSL. We require // non-const as this allows mutating |x|. If it comes up for compatibility, // we can relax this. - return x->cert_info->validity->notBefore; + return &x->notBefore; } ASN1_TIME *X509_get_notBefore(const X509 *x509) { // In OpenSSL, this function is an alias for |X509_getm_notBefore|, but our // |X509_getm_notBefore| is const-correct. |X509_get_notBefore| was // originally a macro, so it needs to capture both get0 and getm use cases. - return x509->cert_info->validity->notBefore; + return const_cast(&x509->notBefore); } int X509_set1_notAfter(X509 *x, const ASN1_TIME *tm) { - ASN1_TIME *in; - - if ((x == NULL) || (x->cert_info->validity == NULL)) { - return 0; - } - in = x->cert_info->validity->notAfter; - if (in != tm) { - in = ASN1_STRING_dup(tm); - if (in != NULL) { - ASN1_TIME_free(x->cert_info->validity->notAfter); - x->cert_info->validity->notAfter = in; - } - } - return in != NULL; + // TODO(crbug.com/42290309): Check that |tm->type| is correct. + return ASN1_STRING_copy(&x->notAfter, tm); } int X509_set_notAfter(X509 *x, const ASN1_TIME *tm) { return X509_set1_notAfter(x, tm); } -const ASN1_TIME *X509_get0_notAfter(const X509 *x) { - return x->cert_info->validity->notAfter; -} +const ASN1_TIME *X509_get0_notAfter(const X509 *x) { return &x->notAfter; } ASN1_TIME *X509_getm_notAfter(X509 *x) { // Note this function takes a const |X509| pointer in OpenSSL. We require // non-const as this allows mutating |x|. If it comes up for compatibility, // we can relax this. - return x->cert_info->validity->notAfter; + return &x->notAfter; } ASN1_TIME *X509_get_notAfter(const X509 *x509) { // In OpenSSL, this function is an alias for |X509_getm_notAfter|, but our // |X509_getm_notAfter| is const-correct. |X509_get_notAfter| was // originally a macro, so it needs to capture both get0 and getm use cases. - return x509->cert_info->validity->notAfter; -} + return const_cast(&x509->notAfter); + } void X509_get0_uids(const X509 *x509, const ASN1_BIT_STRING **out_issuer_uid, const ASN1_BIT_STRING **out_subject_uid) { if (out_issuer_uid != NULL) { - *out_issuer_uid = x509->cert_info->issuerUID; + *out_issuer_uid = x509->issuerUID; } if (out_subject_uid != NULL) { - *out_subject_uid = x509->cert_info->subjectUID; + *out_subject_uid = x509->subjectUID; } } int X509_set_pubkey(X509 *x, EVP_PKEY *pkey) { - if ((x == NULL) || (x->cert_info == NULL)) { + if (x == nullptr) { return 0; } - return (X509_PUBKEY_set(&(x->cert_info->key), pkey)); + return x509_pubkey_set1(&x->key, pkey); } const STACK_OF(X509_EXTENSION) *X509_get0_extensions(const X509 *x) { - return x->cert_info->extensions; + return x->extensions; } const X509_ALGOR *X509_get0_tbs_sigalg(const X509 *x) { - return x->cert_info->signature; + return &x->tbs_sig_alg; } X509_PUBKEY *X509_get_X509_PUBKEY(const X509 *x509) { - return x509->cert_info->key; + // This function is not const-correct for OpenSSL compatibility. + return const_cast(&x509->key); } diff --git a/Sources/CCryptoBoringSSL/crypto/x509/x509_trs.cc b/Sources/CCryptoBoringSSL/crypto/x509/x509_trs.cc index 0539d14db..3ac5b692d 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/x509_trs.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/x509_trs.cc @@ -43,9 +43,9 @@ static const X509_TRUST trstandard[] = { {X509_TRUST_TSA, trust_1oidany, NID_time_stamp}}; static const X509_TRUST *X509_TRUST_get0(int id) { - for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(trstandard); i++) { - if (trstandard[i].trust == id) { - return &trstandard[i]; + for (const auto &t : trstandard) { + if (t.trust == id) { + return &t; } } return NULL; diff --git a/Sources/CCryptoBoringSSL/crypto/x509/x509cset.cc b/Sources/CCryptoBoringSSL/crypto/x509/x509cset.cc index 509705f18..7a3a5f1bb 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/x509cset.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/x509cset.cc @@ -209,19 +209,8 @@ int i2d_X509_CRL_tbs(X509_CRL *crl, unsigned char **outp) { } int X509_CRL_set1_signature_algo(X509_CRL *crl, const X509_ALGOR *algo) { - X509_ALGOR *copy1 = X509_ALGOR_dup(algo); - X509_ALGOR *copy2 = X509_ALGOR_dup(algo); - if (copy1 == NULL || copy2 == NULL) { - X509_ALGOR_free(copy1); - X509_ALGOR_free(copy2); - return 0; - } - - X509_ALGOR_free(crl->sig_alg); - crl->sig_alg = copy1; - X509_ALGOR_free(crl->crl->sig_alg); - crl->crl->sig_alg = copy2; - return 1; + return X509_ALGOR_copy(crl->sig_alg, algo) && + X509_ALGOR_copy(crl->crl->sig_alg, algo); } int X509_CRL_set1_signature_value(X509_CRL *crl, const uint8_t *sig, diff --git a/Sources/CCryptoBoringSSL/crypto/x509/x509rset.cc b/Sources/CCryptoBoringSSL/crypto/x509/x509rset.cc index 49837e740..616e5ada4 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/x509rset.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/x509rset.cc @@ -46,14 +46,7 @@ int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey) { } int X509_REQ_set1_signature_algo(X509_REQ *req, const X509_ALGOR *algo) { - X509_ALGOR *copy = X509_ALGOR_dup(algo); - if (copy == NULL) { - return 0; - } - - X509_ALGOR_free(req->sig_alg); - req->sig_alg = copy; - return 1; + return X509_ALGOR_copy(req->sig_alg, algo); } int X509_REQ_set1_signature_value(X509_REQ *req, const uint8_t *sig, diff --git a/Sources/CCryptoBoringSSL/crypto/x509/x_algor.cc b/Sources/CCryptoBoringSSL/crypto/x509/x_algor.cc index f4d8ec38a..0d0623c1e 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/x_algor.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/x_algor.cc @@ -17,19 +17,131 @@ #include #include #include +#include #include +#include #include "../asn1/internal.h" +#include "../bytestring/internal.h" +#include "../internal.h" +#include "../mem_internal.h" #include "internal.h" -ASN1_SEQUENCE(X509_ALGOR) = { - ASN1_SIMPLE(X509_ALGOR, algorithm, ASN1_OBJECT), - ASN1_OPT(X509_ALGOR, parameter, ASN1_ANY), -} ASN1_SEQUENCE_END(X509_ALGOR) +void x509_algor_init(X509_ALGOR *alg) { + OPENSSL_memset(alg, 0, sizeof(X509_ALGOR)); + alg->algorithm = const_cast(OBJ_get_undef()); +} + +void x509_algor_cleanup(X509_ALGOR *alg) { + ASN1_OBJECT_free(alg->algorithm); + ASN1_TYPE_free(alg->parameter); +} + +X509_ALGOR *X509_ALGOR_new(void) { + bssl::UniquePtr ret = bssl::MakeUnique(); + if (ret == nullptr) { + return nullptr; + } + x509_algor_init(ret.get()); + return ret.release(); +} + +void X509_ALGOR_free(X509_ALGOR *alg) { + if (alg != nullptr) { + x509_algor_cleanup(alg); + OPENSSL_free(alg); + } +} + +int x509_parse_algorithm(CBS *cbs, X509_ALGOR *out) { + CBS seq; + if (!CBS_get_asn1(cbs, &seq, CBS_ASN1_SEQUENCE)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } -IMPLEMENT_ASN1_FUNCTIONS_const(X509_ALGOR) -IMPLEMENT_ASN1_DUP_FUNCTION_const(X509_ALGOR) + bssl::UniquePtr obj(asn1_parse_object(&seq, /*tag=*/0)); + if (obj == nullptr) { + return 0; + } + ASN1_OBJECT_free(out->algorithm); + out->algorithm = obj.release(); + if (CBS_len(&seq) == 0) { + ASN1_TYPE_free(out->parameter); + out->parameter = nullptr; + } else { + if (out->parameter == nullptr) { + out->parameter = ASN1_TYPE_new(); + } + if (out->parameter == nullptr || // + !asn1_parse_any(&seq, out->parameter)) { + return 0; + } + } + if (CBS_len(&seq) != 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + return 1; +} + +int x509_marshal_algorithm(CBB *out, const X509_ALGOR *in) { + CBB seq; + return CBB_add_asn1(out, &seq, CBS_ASN1_SEQUENCE) && + asn1_marshal_object(&seq, in->algorithm, /*tag=*/0) && + (in->parameter == nullptr || asn1_marshal_any(&seq, in->parameter)) && + CBB_flush(out); +} + +X509_ALGOR *d2i_X509_ALGOR(X509_ALGOR **out, const uint8_t **inp, long len) { + return bssl::D2IFromCBS( + out, inp, len, [](CBS *cbs) -> bssl::UniquePtr { + bssl::UniquePtr ret(X509_ALGOR_new()); + if (ret == nullptr || !x509_parse_algorithm(cbs, ret.get())) { + return nullptr; + } + return ret; + }); +} + +int i2d_X509_ALGOR(const X509_ALGOR *in, uint8_t **outp) { + return bssl::I2DFromCBB(/*initial_capacity=*/32, outp, [&](CBB *cbb) -> bool { + return x509_marshal_algorithm(cbb, in); + }); +} + +IMPLEMENT_EXTERN_ASN1_SIMPLE(X509_ALGOR, X509_ALGOR_new, X509_ALGOR_free, + x509_parse_algorithm, i2d_X509_ALGOR) + +X509_ALGOR *X509_ALGOR_dup(const X509_ALGOR *alg) { + bssl::UniquePtr copy(X509_ALGOR_new()); + if (copy == nullptr || !X509_ALGOR_copy(copy.get(), alg)) { + return nullptr; + } + return copy.release(); +} + +int X509_ALGOR_copy(X509_ALGOR *dst, const X509_ALGOR *src) { + bssl::UniquePtr algorithm(OBJ_dup(src->algorithm)); + if (algorithm == nullptr) { + return 0; + } + bssl::UniquePtr parameter; + if (src->parameter != nullptr) { + parameter.reset(ASN1_TYPE_new()); + if (parameter == nullptr || + !ASN1_TYPE_set1(parameter.get(), src->parameter->type, + asn1_type_value_as_pointer(src->parameter))) { + return 0; + } + } + ASN1_OBJECT_free(dst->algorithm); + dst->algorithm = algorithm.release(); + ASN1_TYPE_free(dst->parameter); + dst->parameter = parameter.release(); + return 1; +} int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval) { if (!alg) { @@ -106,11 +218,3 @@ int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b) { } return ASN1_TYPE_cmp(a->parameter, b->parameter); } - -int x509_marshal_algorithm(CBB *out, const X509_ALGOR *in) { - uint8_t *ptr; - int len = i2d_X509_ALGOR(in, NULL); - return len > 0 && // - CBB_add_space(out, &ptr, static_cast(len)) && - i2d_X509_ALGOR(in, &ptr) == len; -} diff --git a/Sources/CCryptoBoringSSL/crypto/x509/x_all.cc b/Sources/CCryptoBoringSSL/crypto/x509/x_all.cc index d4dd7a4a4..ee6f7ae9a 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/x_all.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/x_all.cc @@ -17,24 +17,33 @@ #include #include +#include #include #include #include #include #include +#include #include #include "../asn1/internal.h" +#include "../internal.h" #include "internal.h" int X509_verify(X509 *x509, EVP_PKEY *pkey) { - if (X509_ALGOR_cmp(x509->sig_alg, x509->cert_info->signature)) { + if (X509_ALGOR_cmp(&x509->sig_alg, &x509->tbs_sig_alg)) { OPENSSL_PUT_ERROR(X509, X509_R_SIGNATURE_ALGORITHM_MISMATCH); return 0; } - return ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF), x509->sig_alg, - x509->signature, x509->cert_info, pkey); + // This uses the cached TBSCertificate encoding, if any. + bssl::ScopedCBB cbb; + if (!CBB_init(cbb.get(), 128) || !x509_marshal_tbs_cert(cbb.get(), x509)) { + return 0; + } + return x509_verify_signature( + &x509->sig_alg, &x509->signature, + bssl::Span(CBB_data(cbb.get()), CBB_len(cbb.get())), pkey); } int X509_REQ_verify(X509_REQ *req, EVP_PKEY *pkey) { @@ -43,21 +52,41 @@ int X509_REQ_verify(X509_REQ *req, EVP_PKEY *pkey) { } int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md) { - asn1_encoding_clear(&x->cert_info->enc); - return (ASN1_item_sign(ASN1_ITEM_rptr(X509_CINF), x->cert_info->signature, - x->sig_alg, x->signature, x->cert_info, pkey, md)); + bssl::ScopedEVP_MD_CTX ctx; + if (!EVP_DigestSignInit(ctx.get(), nullptr, md, nullptr, pkey)) { + return 0; + } + return X509_sign_ctx(x, ctx.get()); } int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx) { - asn1_encoding_clear(&x->cert_info->enc); - return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CINF), x->cert_info->signature, - x->sig_alg, x->signature, x->cert_info, ctx); + // Historically, this function called |EVP_MD_CTX_cleanup| on return. Some + // callers rely on this to avoid memory leaks. + bssl::Cleanup cleanup = [&] { EVP_MD_CTX_cleanup(ctx); }; + + // Fill in the two copies of AlgorithmIdentifier. Note one of these modifies + // the TBSCertificate. + if (!x509_digest_sign_algorithm(ctx, &x->tbs_sig_alg) || + !x509_digest_sign_algorithm(ctx, &x->sig_alg)) { + return 0; + } + + // Discard the cached encoding. (We just modified it.) + CRYPTO_BUFFER_free(x->buf); + x->buf = nullptr; + + bssl::ScopedCBB cbb; + if (!CBB_init(cbb.get(), 128) || !x509_marshal_tbs_cert(cbb.get(), x)) { + return 0; + } + return x509_sign_to_bit_string( + ctx, &x->signature, bssl::Span(CBB_data(cbb.get()), CBB_len(cbb.get()))); } int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md) { asn1_encoding_clear(&x->req_info->enc); - return (ASN1_item_sign(ASN1_ITEM_rptr(X509_REQ_INFO), x->sig_alg, NULL, - x->signature, x->req_info, pkey, md)); + return ASN1_item_sign(ASN1_ITEM_rptr(X509_REQ_INFO), x->sig_alg, NULL, + x->signature, x->req_info, pkey, md); } int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx) { @@ -68,8 +97,8 @@ int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx) { int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md) { asn1_encoding_clear(&x->crl->enc); - return (ASN1_item_sign(ASN1_ITEM_rptr(X509_CRL_INFO), x->crl->sig_alg, - x->sig_alg, x->signature, x->crl, pkey, md)); + return ASN1_item_sign(ASN1_ITEM_rptr(X509_CRL_INFO), x->crl->sig_alg, + x->sig_alg, x->signature, x->crl, pkey, md); } int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx) { @@ -79,13 +108,13 @@ int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx) { } int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md) { - return (ASN1_item_sign(ASN1_ITEM_rptr(NETSCAPE_SPKAC), x->sig_algor, NULL, - x->signature, x->spkac, pkey, md)); + return ASN1_item_sign(ASN1_ITEM_rptr(NETSCAPE_SPKAC), x->sig_algor, NULL, + x->signature, x->spkac, pkey, md); } int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *spki, EVP_PKEY *pkey) { - return (ASN1_item_verify(ASN1_ITEM_rptr(NETSCAPE_SPKAC), spki->sig_algor, - spki->signature, spki->spkac, pkey)); + return ASN1_item_verify(ASN1_ITEM_rptr(NETSCAPE_SPKAC), spki->sig_algor, + spki->signature, spki->spkac, pkey); } X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl) { diff --git a/Sources/CCryptoBoringSSL/crypto/x509/x_name.cc b/Sources/CCryptoBoringSSL/crypto/x509/x_name.cc index a5fae0458..5f6da5ae7 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/x_name.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/x_name.cc @@ -38,15 +38,6 @@ DEFINE_STACK_OF(STACK_OF_X509_NAME_ENTRY) #define X509_NAME_MAX (1024 * 1024) -static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, - long len, const ASN1_ITEM *it, int opt, - ASN1_TLC *ctx); - -static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, - const ASN1_ITEM *it); -static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it); -static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it); - static int x509_name_encode(X509_NAME *a); static int x509_name_canon(X509_NAME *a); static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in); @@ -77,19 +68,8 @@ ASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL) // representing the ASN1. Unfortunately X509_NAME uses a completely different // form and caches encodings so we have to process the internal form and // convert to the external form. - -static const ASN1_EXTERN_FUNCS x509_name_ff = { - x509_name_ex_new, - x509_name_ex_free, - x509_name_ex_d2i, - x509_name_ex_i2d, -}; - -IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff) - -IMPLEMENT_ASN1_FUNCTIONS(X509_NAME) - -IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME) +// +// TODO(crbug.com/42290417): Rewrite all this with |CBS| and |CBB|. static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it) { X509_NAME *ret = NULL; @@ -143,29 +123,37 @@ static void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne) { sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free); } -static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, - long len, const ASN1_ITEM *it, int opt, - ASN1_TLC *ctx) { - const unsigned char *p = *in, *q; +static int x509_name_ex_parse(ASN1_VALUE **val, CBS *cbs, const ASN1_ITEM *it, + int opt) { + if (opt && !CBS_peek_asn1_tag(cbs, CBS_ASN1_SEQUENCE)) { + return 1; + } + + CBS elem; + if (!CBS_get_asn1_element(cbs, &elem, CBS_ASN1_SEQUENCE) || + // Bound the size of an X509_NAME we are willing to parse. + CBS_len(&elem) > X509_NAME_MAX) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; + } + + // TODO(crbug.com/42290417): Rewrite the parser and canonicalization code with + // CBS and CBB. For now this calls into the original two-layer d2i code. + long len = static_cast(CBS_len(&elem)); + const unsigned char *p = CBS_data(&elem), *q; STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL; X509_NAME *nm = NULL; size_t i, j; - int ret; STACK_OF(X509_NAME_ENTRY) *entries; X509_NAME_ENTRY *entry; - // Bound the size of an X509_NAME we are willing to parse. - if (len > X509_NAME_MAX) { - len = X509_NAME_MAX; - } q = p; // Get internal representation of Name ASN1_VALUE *intname_val = NULL; - ret = ASN1_item_ex_d2i(&intname_val, &p, len, - ASN1_ITEM_rptr(X509_NAME_INTERNAL), /*tag=*/-1, - /*aclass=*/0, opt, /*buf=*/NULL); - if (ret <= 0) { - return ret; + if (ASN1_item_ex_d2i(&intname_val, &p, len, + ASN1_ITEM_rptr(X509_NAME_INTERNAL), /*tag=*/-1, + /*aclass=*/0, /*opt=*/0) <= 0) { + return 0; } intname = (STACK_OF(STACK_OF_X509_NAME_ENTRY) *)intname_val; @@ -195,15 +183,13 @@ static int x509_name_ex_d2i(ASN1_VALUE **val, const unsigned char **in, (void)sk_X509_NAME_ENTRY_set(entries, j, NULL); } } - ret = x509_name_canon(nm); - if (!ret) { + if (!x509_name_canon(nm)) { goto err; } sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname, local_sk_X509_NAME_ENTRY_free); nm->modified = 0; *val = (ASN1_VALUE *)nm; - *in = p; - return ret; + return 1; err: X509_NAME_free(nm); sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname, @@ -226,6 +212,12 @@ static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, return ret; } +static const ASN1_EXTERN_FUNCS x509_name_ff = { + x509_name_ex_new, x509_name_ex_free, x509_name_ex_parse, x509_name_ex_i2d}; +IMPLEMENT_EXTERN_ASN1(X509_NAME, x509_name_ff) +IMPLEMENT_ASN1_FUNCTIONS(X509_NAME) +IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME) + static int x509_name_encode(X509_NAME *a) { int len; unsigned char *p; diff --git a/Sources/CCryptoBoringSSL/crypto/x509/x_pubkey.cc b/Sources/CCryptoBoringSSL/crypto/x509/x_pubkey.cc index 07dc78157..ca19d9a32 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/x_pubkey.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/x_pubkey.cc @@ -23,94 +23,139 @@ #include #include #include +#include +#include "../asn1/internal.h" +#include "../bytestring/internal.h" +#include "../evp/internal.h" #include "../internal.h" +#include "../mem_internal.h" #include "internal.h" -static void x509_pubkey_changed(X509_PUBKEY *pub) { - EVP_PKEY_free(pub->pkey); - pub->pkey = NULL; - - // Re-encode the |X509_PUBKEY| to DER and parse it with EVP's APIs. - uint8_t *spki = NULL; - int spki_len = i2d_X509_PUBKEY(pub, &spki); - EVP_PKEY *pkey; - if (spki_len < 0) { - goto err; +void x509_pubkey_init(X509_PUBKEY *key) { + OPENSSL_memset(key, 0, sizeof(X509_PUBKEY)); + x509_algor_init(&key->algor); + asn1_string_init(&key->public_key, V_ASN1_BIT_STRING); +} + +X509_PUBKEY *X509_PUBKEY_new(void) { + bssl::UniquePtr ret = bssl::MakeUnique(); + if (ret == nullptr) { + return nullptr; } + x509_pubkey_init(ret.get()); + return ret.release(); +} - CBS cbs; - CBS_init(&cbs, spki, (size_t)spki_len); - pkey = EVP_parse_public_key(&cbs); - if (pkey == NULL || CBS_len(&cbs) != 0) { - EVP_PKEY_free(pkey); - goto err; +void x509_pubkey_cleanup(X509_PUBKEY *key) { + x509_algor_cleanup(&key->algor); + asn1_string_cleanup(&key->public_key); + EVP_PKEY_free(key->pkey); +} + +void X509_PUBKEY_free(X509_PUBKEY *key) { + if (key != nullptr) { + x509_pubkey_cleanup(key); + OPENSSL_free(key); } +} - pub->pkey = pkey; +static void x509_pubkey_changed(X509_PUBKEY *pub, + bssl::Span algs) { + EVP_PKEY_free(pub->pkey); + pub->pkey = nullptr; + + // Re-encode the |X509_PUBKEY| to DER and parse it with EVP's APIs. If the + // operation fails, clear errors. An |X509_PUBKEY| whose key we cannot parse + // is still a valid SPKI. It just cannot be converted to an |EVP_PKEY|. + bssl::ScopedCBB cbb; + if (!CBB_init(cbb.get(), 64) || !x509_marshal_public_key(cbb.get(), pub)) { + ERR_clear_error(); + return; + } + bssl::UniquePtr pkey(EVP_PKEY_from_subject_public_key_info( + CBB_data(cbb.get()), CBB_len(cbb.get()), algs.data(), algs.size())); + if (pkey == nullptr) { + ERR_clear_error(); + return; + } -err: - OPENSSL_free(spki); - // If the operation failed, clear errors. An |X509_PUBKEY| whose key we cannot - // parse is still a valid SPKI. It just cannot be converted to an |EVP_PKEY|. - ERR_clear_error(); + pub->pkey = pkey.release(); } -static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, - void *exarg) { - X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval; - if (operation == ASN1_OP_FREE_POST) { - EVP_PKEY_free(pubkey->pkey); - } else if (operation == ASN1_OP_D2I_POST) { - x509_pubkey_changed(pubkey); +int x509_parse_public_key(CBS *cbs, X509_PUBKEY *out, + bssl::Span algs) { + CBS seq; + if (!CBS_get_asn1(cbs, &seq, CBS_ASN1_SEQUENCE) || + !x509_parse_algorithm(&seq, &out->algor) || + !asn1_parse_bit_string(&seq, &out->public_key, /*tag=*/0) || + CBS_len(&seq) != 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return 0; } + x509_pubkey_changed(out, algs); return 1; } -ASN1_SEQUENCE_cb(X509_PUBKEY, pubkey_cb) = { - ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR), - ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING), -} ASN1_SEQUENCE_END_cb(X509_PUBKEY, X509_PUBKEY) +static int x509_parse_public_key_default(CBS *cbs, X509_PUBKEY *out) { + return x509_parse_public_key(cbs, out, bssl::GetDefaultEVPAlgorithms()); +} -IMPLEMENT_ASN1_FUNCTIONS_const(X509_PUBKEY) +int x509_marshal_public_key(CBB *cbb, const X509_PUBKEY *in) { + CBB seq; + return CBB_add_asn1(cbb, &seq, CBS_ASN1_SEQUENCE) && + x509_marshal_algorithm(&seq, &in->algor) && + asn1_marshal_bit_string(&seq, &in->public_key, /*tag=*/0) && + CBB_flush(cbb); +} -int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey) { - X509_PUBKEY *pk = NULL; - uint8_t *spki = NULL; - size_t spki_len; +X509_PUBKEY *d2i_X509_PUBKEY(X509_PUBKEY **out, const uint8_t **inp, long len) { + return bssl::D2IFromCBS( + out, inp, len, [](CBS *cbs) -> bssl::UniquePtr { + bssl::UniquePtr ret(X509_PUBKEY_new()); + if (ret == nullptr || !x509_parse_public_key_default(cbs, ret.get())) { + return nullptr; + } + return ret; + }); +} - if (x == NULL) { - return 0; - } +int i2d_X509_PUBKEY(const X509_PUBKEY *key, uint8_t **outp) { + return bssl::I2DFromCBB(/*initial_capacity=*/32, outp, [&](CBB *cbb) -> bool { + return x509_marshal_public_key(cbb, key); + }); +} - CBB cbb; - const uint8_t *p; - if (!CBB_init(&cbb, 0) || // - !EVP_marshal_public_key(&cbb, pkey) || - !CBB_finish(&cbb, &spki, &spki_len) || // - spki_len > LONG_MAX) { - CBB_cleanup(&cbb); +// TODO(crbug.com/42290417): Remove this when |X509| and |X509_REQ| no longer +// depend on the tables. +IMPLEMENT_EXTERN_ASN1_SIMPLE(X509_PUBKEY, X509_PUBKEY_new, X509_PUBKEY_free, + x509_parse_public_key_default, i2d_X509_PUBKEY) + +int x509_pubkey_set1(X509_PUBKEY *key, EVP_PKEY *pkey) { + bssl::ScopedCBB cbb; + if (!CBB_init(cbb.get(), 64) || + !EVP_marshal_public_key(cbb.get(), pkey)) { OPENSSL_PUT_ERROR(X509, X509_R_PUBLIC_KEY_ENCODE_ERROR); - goto error; + return 0; } - p = spki; - pk = d2i_X509_PUBKEY(NULL, &p, (long)spki_len); - if (pk == NULL || p != spki + spki_len) { - OPENSSL_PUT_ERROR(X509, X509_R_PUBLIC_KEY_DECODE_ERROR); - goto error; - } + CBS cbs; + CBS_init(&cbs, CBB_data(cbb.get()), CBB_len(cbb.get())); + // TODO(crbug.com/42290364): Use an |EVP_PKEY_ALG| derived from |pkey|. + // |X509_PUBKEY_get0| does not currently work when setting, say, an + // |EVP_PKEY_RSA_PSS| key. + return x509_parse_public_key(&cbs, key, bssl::GetDefaultEVPAlgorithms()); +} - OPENSSL_free(spki); +int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey) { + bssl::UniquePtr new_key(X509_PUBKEY_new()); + if (new_key == nullptr || !x509_pubkey_set1(new_key.get(), pkey)) { + return 0; + } X509_PUBKEY_free(*x); - *x = pk; - + *x = new_key.release(); return 1; -error: - X509_PUBKEY_free(pk); - OPENSSL_free(spki); - return 0; } EVP_PKEY *X509_PUBKEY_get0(const X509_PUBKEY *key) { @@ -136,16 +181,16 @@ EVP_PKEY *X509_PUBKEY_get(const X509_PUBKEY *key) { int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *obj, int param_type, void *param_value, uint8_t *key, int key_len) { - if (!X509_ALGOR_set0(pub->algor, obj, param_type, param_value)) { + if (!X509_ALGOR_set0(&pub->algor, obj, param_type, param_value)) { return 0; } - ASN1_STRING_set0(pub->public_key, key, key_len); + ASN1_STRING_set0(&pub->public_key, key, key_len); // Set the number of unused bits to zero. - pub->public_key->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); - pub->public_key->flags |= ASN1_STRING_FLAG_BITS_LEFT; + pub->public_key.flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + pub->public_key.flags |= ASN1_STRING_FLAG_BITS_LEFT; - x509_pubkey_changed(pub); + x509_pubkey_changed(pub, bssl::GetDefaultEVPAlgorithms()); return 1; } @@ -153,18 +198,18 @@ int X509_PUBKEY_get0_param(ASN1_OBJECT **out_obj, const uint8_t **out_key, int *out_key_len, X509_ALGOR **out_alg, X509_PUBKEY *pub) { if (out_obj != NULL) { - *out_obj = pub->algor->algorithm; + *out_obj = pub->algor.algorithm; } if (out_key != NULL) { - *out_key = pub->public_key->data; - *out_key_len = pub->public_key->length; + *out_key = pub->public_key.data; + *out_key_len = pub->public_key.length; } if (out_alg != NULL) { - *out_alg = pub->algor; + *out_alg = &pub->algor; } return 1; } const ASN1_BIT_STRING *X509_PUBKEY_get0_public_key(const X509_PUBKEY *pub) { - return pub->public_key; + return &pub->public_key; } diff --git a/Sources/CCryptoBoringSSL/crypto/x509/x_val.cc b/Sources/CCryptoBoringSSL/crypto/x509/x_val.cc deleted file mode 100644 index 188df6977..000000000 --- a/Sources/CCryptoBoringSSL/crypto/x509/x_val.cc +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include - -#include -#include - -#include "internal.h" - - -ASN1_SEQUENCE(X509_VAL) = { - ASN1_SIMPLE(X509_VAL, notBefore, ASN1_TIME), - ASN1_SIMPLE(X509_VAL, notAfter, ASN1_TIME), -} ASN1_SEQUENCE_END(X509_VAL) - -IMPLEMENT_ASN1_FUNCTIONS_const(X509_VAL) diff --git a/Sources/CCryptoBoringSSL/crypto/x509/x_x509.cc b/Sources/CCryptoBoringSSL/crypto/x509/x_x509.cc index ec1037cc4..0e570801c 100644 --- a/Sources/CCryptoBoringSSL/crypto/x509/x_x509.cc +++ b/Sources/CCryptoBoringSSL/crypto/x509/x_x509.cc @@ -27,57 +27,57 @@ #include "../asn1/internal.h" #include "../bytestring/internal.h" +#include "../evp/internal.h" #include "../internal.h" #include "internal.h" static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT; -ASN1_SEQUENCE_enc(X509_CINF, enc, 0) = { - ASN1_EXP_OPT(X509_CINF, version, ASN1_INTEGER, 0), - ASN1_SIMPLE(X509_CINF, serialNumber, ASN1_INTEGER), - ASN1_SIMPLE(X509_CINF, signature, X509_ALGOR), - ASN1_SIMPLE(X509_CINF, issuer, X509_NAME), - ASN1_SIMPLE(X509_CINF, validity, X509_VAL), - ASN1_SIMPLE(X509_CINF, subject, X509_NAME), - ASN1_SIMPLE(X509_CINF, key, X509_PUBKEY), - ASN1_IMP_OPT(X509_CINF, issuerUID, ASN1_BIT_STRING, 1), - ASN1_IMP_OPT(X509_CINF, subjectUID, ASN1_BIT_STRING, 2), - ASN1_EXP_SEQUENCE_OF_OPT(X509_CINF, extensions, X509_EXTENSION, 3), -} ASN1_SEQUENCE_END_enc(X509_CINF, X509_CINF) - -IMPLEMENT_ASN1_FUNCTIONS(X509_CINF) - -// x509_new_null returns a new |X509| object where the |cert_info|, |sig_alg|, -// and |signature| fields are not yet filled in. -static X509 *x509_new_null(void) { - X509 *ret = reinterpret_cast(OPENSSL_zalloc(sizeof(X509))); - if (ret == NULL) { - return NULL; +static constexpr CBS_ASN1_TAG kVersionTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0; +static constexpr CBS_ASN1_TAG kIssuerUIDTag = CBS_ASN1_CONTEXT_SPECIFIC | 1; +static constexpr CBS_ASN1_TAG kSubjectUIDTag = CBS_ASN1_CONTEXT_SPECIFIC | 2; +static constexpr CBS_ASN1_TAG kExtensionsTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 3; + +// x509_new_null returns a new |X509| object where the |issuer| and |subject| +// fields are not yet filled in. +static bssl::UniquePtr x509_new_null(void) { + bssl::UniquePtr ret( + reinterpret_cast(OPENSSL_zalloc(sizeof(X509)))); + if (ret == nullptr) { + return nullptr; } ret->references = 1; ret->ex_pathlen = -1; + ret->version = X509_VERSION_1; + asn1_string_init(&ret->serialNumber, V_ASN1_INTEGER); + x509_algor_init(&ret->tbs_sig_alg); + asn1_string_init(&ret->notBefore, -1); + asn1_string_init(&ret->notAfter, -1); + x509_pubkey_init(&ret->key); + x509_algor_init(&ret->sig_alg); + asn1_string_init(&ret->signature, V_ASN1_BIT_STRING); CRYPTO_new_ex_data(&ret->ex_data); CRYPTO_MUTEX_init(&ret->lock); return ret; } X509 *X509_new(void) { - X509 *ret = x509_new_null(); - if (ret == NULL) { - return NULL; + bssl::UniquePtr ret = x509_new_null(); + if (ret == nullptr) { + return nullptr; } - - ret->cert_info = X509_CINF_new(); - ret->sig_alg = X509_ALGOR_new(); - ret->signature = ASN1_BIT_STRING_new(); - if (ret->cert_info == NULL || ret->sig_alg == NULL || - ret->signature == NULL) { - X509_free(ret); - return NULL; + // TODO(crbug.com/42290417): When the |X509_NAME| parser is CBS-based and + // writes into a pre-existing |X509_NAME|, we will no longer need the + // |X509_new| and |x509_new_null| split. + ret->issuer = X509_NAME_new(); + ret->subject = X509_NAME_new(); + if (ret->issuer == nullptr || ret->subject == nullptr) { + return nullptr; } - - return ret; + return ret.release(); } void X509_free(X509 *x509) { @@ -87,9 +87,19 @@ void X509_free(X509 *x509) { CRYPTO_free_ex_data(&g_ex_data_class, &x509->ex_data); - X509_CINF_free(x509->cert_info); - X509_ALGOR_free(x509->sig_alg); - ASN1_BIT_STRING_free(x509->signature); + asn1_string_cleanup(&x509->serialNumber); + x509_algor_cleanup(&x509->tbs_sig_alg); + X509_NAME_free(x509->issuer); + asn1_string_cleanup(&x509->notBefore); + asn1_string_cleanup(&x509->notAfter); + X509_NAME_free(x509->subject); + x509_pubkey_cleanup(&x509->key); + ASN1_BIT_STRING_free(x509->issuerUID); + ASN1_BIT_STRING_free(x509->subjectUID); + sk_X509_EXTENSION_pop_free(x509->extensions, X509_EXTENSION_free); + x509_algor_cleanup(&x509->sig_alg); + asn1_string_cleanup(&x509->signature); + CRYPTO_BUFFER_free(x509->buf); ASN1_OCTET_STRING_free(x509->skid); AUTHORITY_KEYID_free(x509->akid); CRL_DIST_POINTS_free(x509->crldp); @@ -101,115 +111,216 @@ void X509_free(X509 *x509) { OPENSSL_free(x509); } -static X509 *x509_parse(CBS *cbs, CRYPTO_BUFFER *buf) { - CBS cert, tbs, sigalg, sig; - if (!CBS_get_asn1(cbs, &cert, CBS_ASN1_SEQUENCE) || - // Bound the length to comfortably fit in an int. Lengths in this - // module often omit overflow checks. - CBS_len(&cert) > INT_MAX / 2 || - !CBS_get_asn1_element(&cert, &tbs, CBS_ASN1_SEQUENCE) || - !CBS_get_asn1_element(&cert, &sigalg, CBS_ASN1_SEQUENCE)) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); - return nullptr; - } - - // For just the signature field, we accept non-minimal BER lengths, though not - // indefinite-length encoding. See b/18228011. - // - // TODO(crbug.com/boringssl/354): Switch the affected callers to convert the - // certificate before parsing and then remove this workaround. - CBS_ASN1_TAG tag; - size_t header_len; - int indefinite; - if (!CBS_get_any_ber_asn1_element(&cert, &sig, &tag, &header_len, - /*out_ber_found=*/nullptr, - &indefinite) || - tag != CBS_ASN1_BITSTRING || indefinite || // - !CBS_skip(&sig, header_len) || // - CBS_len(&cert) != 0) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); - return nullptr; +static int parse_name(CBS *cbs, X509_NAME **out) { + // TODO(crbug.com/42290417): Make the |X509_NAME| parser CBS-based and avoid + // this awkward conversion. + const uint8_t *p = CBS_data(cbs); + X509_NAME_free(*out); + *out = d2i_X509_NAME(nullptr, &p, CBS_len(cbs)); + if (*out == nullptr) { + return 0; } + BSSL_CHECK(CBS_skip(cbs, p - CBS_data(cbs))); + return 1; +} +X509 *X509_parse_with_algorithms(CRYPTO_BUFFER *buf, + const EVP_PKEY_ALG *const *algs, + size_t num_algs) { bssl::UniquePtr ret(x509_new_null()); if (ret == nullptr) { return nullptr; } - // TODO(crbug.com/boringssl/443): When the rest of the library is decoupled - // from the tasn_*.c implementation, replace this with |CBS|-based - // functions. - const uint8_t *inp = CBS_data(&tbs); - if (ASN1_item_ex_d2i((ASN1_VALUE **)&ret->cert_info, &inp, CBS_len(&tbs), - ASN1_ITEM_rptr(X509_CINF), /*tag=*/-1, - /*aclass=*/0, /*opt=*/0, buf) <= 0 || - inp != CBS_data(&tbs) + CBS_len(&tbs)) { - return nullptr; - } + // Save the buffer to cache the original encoding. + ret->buf = bssl::UpRef(buf).release(); - inp = CBS_data(&sigalg); - ret->sig_alg = d2i_X509_ALGOR(nullptr, &inp, CBS_len(&sigalg)); - if (ret->sig_alg == nullptr || inp != CBS_data(&sigalg) + CBS_len(&sigalg)) { + // Parse the Certificate. + CBS cbs, cert, tbs; + CRYPTO_BUFFER_init_CBS(buf, &cbs); + if (!CBS_get_asn1(&cbs, &cert, CBS_ASN1_SEQUENCE) || // + CBS_len(&cbs) != 0 || + // Bound the length to comfortably fit in an int. Lengths in this + // module often omit overflow checks. + CBS_len(&cert) > INT_MAX / 2 || + !CBS_get_asn1(&cert, &tbs, CBS_ASN1_SEQUENCE) || + !x509_parse_algorithm(&cert, &ret->sig_alg) || + // For just the signature field, we accept non-minimal BER lengths, though + // not indefinite-length encoding. See b/18228011. + // + // TODO(crbug.com/boringssl/354): Switch the affected callers to convert + // the certificate before parsing and then remove this workaround. + !asn1_parse_bit_string_with_bad_length(&cert, &ret->signature) || + CBS_len(&cert) != 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); return nullptr; } - inp = CBS_data(&sig); - ret->signature = c2i_ASN1_BIT_STRING(nullptr, &inp, CBS_len(&sig)); - if (ret->signature == nullptr || inp != CBS_data(&sig) + CBS_len(&sig)) { + // Parse the TBSCertificate. + if (CBS_peek_asn1_tag(&tbs, kVersionTag)) { + CBS wrapper; + uint64_t version; + if (!CBS_get_asn1(&tbs, &wrapper, kVersionTag) || + !CBS_get_asn1_uint64(&wrapper, &version) || // + CBS_len(&wrapper) != 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return nullptr; + } + // The version must be one of v1(0), v2(1), or v3(2). + // TODO(https://crbug.com/42290225): Also reject |X509_VERSION_1|. v1 is + // DEFAULT, so DER requires it be omitted. + if (version != X509_VERSION_1 && version != X509_VERSION_2 && + version != X509_VERSION_3) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_VERSION); + return nullptr; + } + ret->version = static_cast(version); + } else { + ret->version = X509_VERSION_1; + } + CBS validity; + if (!asn1_parse_integer(&tbs, &ret->serialNumber, /*tag=*/0) || + !x509_parse_algorithm(&tbs, &ret->tbs_sig_alg) || + !parse_name(&tbs, &ret->issuer) || + !CBS_get_asn1(&tbs, &validity, CBS_ASN1_SEQUENCE) || + !asn1_parse_time(&validity, &ret->notBefore, + /*allow_utc_timezone_offset=*/1) || + !asn1_parse_time(&validity, &ret->notAfter, + /*allow_utc_timezone_offset=*/1) || + CBS_len(&validity) != 0 || // + !parse_name(&tbs, &ret->subject) || + !x509_parse_public_key(&tbs, &ret->key, bssl::Span(algs, num_algs))) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); return nullptr; } - - // The version must be one of v1(0), v2(1), or v3(2). - long version = X509_VERSION_1; - if (ret->cert_info->version != nullptr) { - version = ASN1_INTEGER_get(ret->cert_info->version); - // TODO(https://crbug.com/boringssl/364): |X509_VERSION_1| should - // also be rejected here. This means an explicitly-encoded X.509v1 - // version. v1 is DEFAULT, so DER requires it be omitted. - if (version < X509_VERSION_1 || version > X509_VERSION_3) { - OPENSSL_PUT_ERROR(X509, X509_R_INVALID_VERSION); + // Per RFC 5280, section 4.1.2.8, these fields require v2 or v3: + if (ret->version >= X509_VERSION_2 && + CBS_peek_asn1_tag(&tbs, kIssuerUIDTag)) { + ret->issuerUID = ASN1_BIT_STRING_new(); + if (ret->issuerUID == nullptr || + !asn1_parse_bit_string(&tbs, ret->issuerUID, kIssuerUIDTag)) { return nullptr; } } - - // Per RFC 5280, section 4.1.2.8, these fields require v2 or v3. - if (version == X509_VERSION_1 && (ret->cert_info->issuerUID != nullptr || - ret->cert_info->subjectUID != nullptr)) { - OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_FOR_VERSION); - return nullptr; + if (ret->version >= X509_VERSION_2 && + CBS_peek_asn1_tag(&tbs, kSubjectUIDTag)) { + ret->subjectUID = ASN1_BIT_STRING_new(); + if (ret->subjectUID == nullptr || + !asn1_parse_bit_string(&tbs, ret->subjectUID, kSubjectUIDTag)) { + return nullptr; + } } - - // Per RFC 5280, section 4.1.2.9, extensions require v3. - if (version != X509_VERSION_3 && ret->cert_info->extensions != nullptr) { - OPENSSL_PUT_ERROR(X509, X509_R_INVALID_FIELD_FOR_VERSION); + // Per RFC 5280, section 4.1.2.9, extensions require v3: + if (ret->version >= X509_VERSION_3 && + CBS_peek_asn1_tag(&tbs, kExtensionsTag)) { + CBS wrapper; + if (!CBS_get_asn1(&tbs, &wrapper, kExtensionsTag)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return nullptr; + } + // TODO(crbug.com/42290219): Empty extension lists should be rejected. An + // empty extensions list is encoded by omitting the field altogether. libpki + // already rejects this. + const uint8_t *p = CBS_data(&wrapper); + ret->extensions = d2i_X509_EXTENSIONS(nullptr, &p, CBS_len(&wrapper)); + if (ret->extensions == nullptr || + p != CBS_data(&wrapper) + CBS_len(&wrapper)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return nullptr; + } + } + if (CBS_len(&tbs) != 0) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); return nullptr; } return ret.release(); } -X509 *d2i_X509(X509 **out, const uint8_t **inp, long len) { - X509 *ret = NULL; - if (len < 0) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_BUFFER_TOO_SMALL); - goto err; +X509 *X509_parse_from_buffer(CRYPTO_BUFFER *buf) { + auto algs = bssl::GetDefaultEVPAlgorithms(); + return X509_parse_with_algorithms(buf, algs.data(), algs.size()); +} + +static bssl::UniquePtr x509_parse(CBS *cbs) { + CBS cert; + if (!CBS_get_asn1_element(cbs, &cert, CBS_ASN1_SEQUENCE)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return nullptr; } - CBS cbs; - CBS_init(&cbs, *inp, (size_t)len); - ret = x509_parse(&cbs, NULL); - if (ret == NULL) { - goto err; + bssl::UniquePtr buf(CRYPTO_BUFFER_new_from_CBS(&cert, nullptr)); + if (buf == nullptr) { + return nullptr; } + return bssl::UniquePtr(X509_parse_from_buffer(buf.get())); +} - *inp = CBS_data(&cbs); +int x509_marshal_tbs_cert(CBB *cbb, X509 *x509) { + if (x509->buf != nullptr) { + // Replay the saved TBSCertificate from the |CRYPTO_BUFFER|, to verify + // exactly what we parsed. The |CRYPTO_BUFFER| contains the full + // Certificate, so we need to find the TBSCertificate portion. + CBS cbs, cert, tbs; + CRYPTO_BUFFER_init_CBS(x509->buf, &cbs); + if (!CBS_get_asn1(&cbs, &cert, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_element(&cert, &tbs, CBS_ASN1_SEQUENCE)) { + // This should be impossible. + OPENSSL_PUT_ERROR(X509, ERR_R_INTERNAL_ERROR); + return 0; + } + return CBB_add_bytes(cbb, CBS_data(&tbs), CBS_len(&tbs)); + } -err: - if (out != NULL) { - X509_free(*out); - *out = ret; + // No saved TBSCertificate encoding. Encode it anew. + CBB tbs, version, validity, extensions; + if (!CBB_add_asn1(cbb, &tbs, CBS_ASN1_SEQUENCE)) { + return 0; } - return ret; + if (x509->version != X509_VERSION_1) { + if (!CBB_add_asn1(&tbs, &version, kVersionTag) || + !CBB_add_asn1_uint64(&version, x509->version)) { + return 0; + } + } + if (!asn1_marshal_integer(&tbs, &x509->serialNumber, /*tag=*/0) || + !x509_marshal_algorithm(&tbs, &x509->tbs_sig_alg) || + !x509_marshal_name(&tbs, x509->issuer) || + !CBB_add_asn1(&tbs, &validity, CBS_ASN1_SEQUENCE) || + !asn1_marshal_time(&validity, &x509->notBefore) || + !asn1_marshal_time(&validity, &x509->notAfter) || + !x509_marshal_name(&tbs, x509->subject) || + !x509_marshal_public_key(&tbs, &x509->key) || + (x509->issuerUID != nullptr && + !asn1_marshal_bit_string(&tbs, x509->issuerUID, kIssuerUIDTag)) || + (x509->subjectUID != nullptr && + !asn1_marshal_bit_string(&tbs, x509->subjectUID, kSubjectUIDTag))) { + return 0; + } + if (x509->extensions != nullptr) { + int len = i2d_X509_EXTENSIONS(x509->extensions, nullptr); + uint8_t *out; + if (len <= 0 || // + !CBB_add_asn1(&tbs, &extensions, kExtensionsTag) || + !CBB_add_space(&extensions, &out, len) || + i2d_X509_EXTENSIONS(x509->extensions, &out) != len) { + return 0; + } + } + return CBB_flush(cbb); +} + +static int x509_marshal(CBB *cbb, X509 *x509) { + CBB cert; + return CBB_add_asn1(cbb, &cert, CBS_ASN1_SEQUENCE) && + x509_marshal_tbs_cert(&cert, x509) && + x509_marshal_algorithm(&cert, &x509->sig_alg) && + asn1_marshal_bit_string(&cert, &x509->signature, /*tag=*/0) && + CBB_flush(cbb); +} + +X509 *d2i_X509(X509 **out, const uint8_t **inp, long len) { + return bssl::D2IFromCBS(out, inp, len, x509_parse); } int i2d_X509(X509 *x509, uint8_t **outp) { @@ -218,26 +329,9 @@ int i2d_X509(X509 *x509, uint8_t **outp) { return -1; } - bssl::ScopedCBB cbb; - CBB cert; - if (!CBB_init(cbb.get(), 64) || // - !CBB_add_asn1(cbb.get(), &cert, CBS_ASN1_SEQUENCE)) { - return -1; - } - - // TODO(crbug.com/boringssl/443): When the rest of the library is decoupled - // from the tasn_*.c implementation, replace this with |CBS|-based functions. - uint8_t *out; - int len = i2d_X509_CINF(x509->cert_info, NULL); - if (len < 0 || // - !CBB_add_space(&cert, &out, static_cast(len)) || - i2d_X509_CINF(x509->cert_info, &out) != len || - !x509_marshal_algorithm(&cert, x509->sig_alg) || - !asn1_marshal_bit_string(&cert, x509->signature, /*tag=*/0)) { - return -1; - } - - return CBB_finish_i2d(cbb.get(), outp); + return bssl::I2DFromCBB( + /*initial_capacity=*/256, outp, + [&](CBB *cbb) -> bool { return x509_marshal(cbb, x509); }); } static int x509_new_cb(ASN1_VALUE **pval, const ASN1_ITEM *it) { @@ -250,27 +344,19 @@ static void x509_free_cb(ASN1_VALUE **pval, const ASN1_ITEM *it) { *pval = NULL; } -static int x509_d2i_cb(ASN1_VALUE **pval, const unsigned char **in, long len, - const ASN1_ITEM *it, int opt, ASN1_TLC *ctx) { - if (len < 0) { - OPENSSL_PUT_ERROR(ASN1, ASN1_R_BUFFER_TOO_SMALL); - return 0; - } - - CBS cbs; - CBS_init(&cbs, *in, len); - if (opt && !CBS_peek_asn1_tag(&cbs, CBS_ASN1_SEQUENCE)) { - return -1; +static int x509_parse_cb(ASN1_VALUE **pval, CBS *cbs, const ASN1_ITEM *it, + int opt) { + if (opt && !CBS_peek_asn1_tag(cbs, CBS_ASN1_SEQUENCE)) { + return 1; } - X509 *ret = x509_parse(&cbs, NULL); - if (ret == NULL) { + bssl::UniquePtr ret = x509_parse(cbs); + if (ret == nullptr) { return 0; } - *in = CBS_data(&cbs); X509_free((X509 *)*pval); - *pval = (ASN1_VALUE *)ret; + *pval = (ASN1_VALUE *)ret.release(); return 1; } @@ -279,14 +365,9 @@ static int x509_i2d_cb(ASN1_VALUE **pval, unsigned char **out, return i2d_X509((X509 *)*pval, out); } -static const ASN1_EXTERN_FUNCS x509_extern_funcs = { - x509_new_cb, - x509_free_cb, - x509_d2i_cb, - x509_i2d_cb, -}; - -IMPLEMENT_EXTERN_ASN1(X509, V_ASN1_SEQUENCE, x509_extern_funcs) +static const ASN1_EXTERN_FUNCS x509_extern_funcs = {x509_new_cb, x509_free_cb, + x509_parse_cb, x509_i2d_cb}; +IMPLEMENT_EXTERN_ASN1(X509, x509_extern_funcs) X509 *X509_dup(X509 *x509) { uint8_t *der = NULL; @@ -301,18 +382,6 @@ X509 *X509_dup(X509 *x509) { return ret; } -X509 *X509_parse_from_buffer(CRYPTO_BUFFER *buf) { - CBS cbs; - CBS_init(&cbs, CRYPTO_BUFFER_data(buf), CRYPTO_BUFFER_len(buf)); - X509 *ret = x509_parse(&cbs, buf); - if (ret == NULL || CBS_len(&cbs) != 0) { - X509_free(ret); - return NULL; - } - - return ret; -} - int X509_up_ref(X509 *x) { CRYPTO_refcount_inc(&x->references); return 1; @@ -437,49 +506,41 @@ int i2d_X509_AUX(X509 *a, unsigned char **pp) { } int i2d_re_X509_tbs(X509 *x509, unsigned char **outp) { - asn1_encoding_clear(&x509->cert_info->enc); - return i2d_X509_CINF(x509->cert_info, outp); + CRYPTO_BUFFER_free(x509->buf); + x509->buf = nullptr; + return i2d_X509_tbs(x509, outp); } int i2d_X509_tbs(X509 *x509, unsigned char **outp) { - return i2d_X509_CINF(x509->cert_info, outp); + return bssl::I2DFromCBB(/*initial_capacity=*/128, outp, [&](CBB *cbb) -> bool { + return x509_marshal_tbs_cert(cbb, x509); + }); } int X509_set1_signature_algo(X509 *x509, const X509_ALGOR *algo) { - X509_ALGOR *copy1 = X509_ALGOR_dup(algo); - X509_ALGOR *copy2 = X509_ALGOR_dup(algo); - if (copy1 == NULL || copy2 == NULL) { - X509_ALGOR_free(copy1); - X509_ALGOR_free(copy2); - return 0; - } - - X509_ALGOR_free(x509->sig_alg); - x509->sig_alg = copy1; - X509_ALGOR_free(x509->cert_info->signature); - x509->cert_info->signature = copy2; - return 1; + return X509_ALGOR_copy(&x509->sig_alg, algo) && + X509_ALGOR_copy(&x509->tbs_sig_alg, algo); } int X509_set1_signature_value(X509 *x509, const uint8_t *sig, size_t sig_len) { - if (!ASN1_STRING_set(x509->signature, sig, sig_len)) { + if (!ASN1_STRING_set(&x509->signature, sig, sig_len)) { return 0; } - x509->signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); - x509->signature->flags |= ASN1_STRING_FLAG_BITS_LEFT; + x509->signature.flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + x509->signature.flags |= ASN1_STRING_FLAG_BITS_LEFT; return 1; } void X509_get0_signature(const ASN1_BIT_STRING **psig, const X509_ALGOR **palg, const X509 *x) { if (psig) { - *psig = x->signature; + *psig = &x->signature; } if (palg) { - *palg = x->sig_alg; + *palg = &x->sig_alg; } } int X509_get_signature_nid(const X509 *x) { - return OBJ_obj2nid(x->sig_alg->algorithm); + return OBJ_obj2nid(x->sig_alg.algorithm); } diff --git a/Sources/CCryptoBoringSSL/gen/bcm/armv8-mont-apple.S b/Sources/CCryptoBoringSSL/gen/bcm/armv8-mont-apple.S index a79430850..2131b9006 100644 --- a/Sources/CCryptoBoringSSL/gen/bcm/armv8-mont-apple.S +++ b/Sources/CCryptoBoringSSL/gen/bcm/armv8-mont-apple.S @@ -7,11 +7,11 @@ #if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_AARCH64) && defined(__APPLE__) .text -.globl _bn_mul_mont -.private_extern _bn_mul_mont +.globl _bn_mul_mont_words +.private_extern _bn_mul_mont_words .align 5 -_bn_mul_mont: +_bn_mul_mont_words: AARCH64_SIGN_LINK_REGISTER tst x5,#7 b.eq __bn_sqr8x_mont @@ -217,7 +217,7 @@ Lcond_copy: .align 5 __bn_sqr8x_mont: // Not adding AARCH64_SIGN_LINK_REGISTER here because __bn_sqr8x_mont is jumped to - // only from bn_mul_mont which has already signed the return address. + // only from bn_mul_mont_words which has already signed the return address. cmp x1,x2 b.ne __bn_mul4x_mont Lsqr8x_mont: @@ -979,7 +979,7 @@ Lsqr8x_done: .align 5 __bn_mul4x_mont: // Not adding AARCH64_SIGN_LINK_REGISTER here because __bn_mul4x_mont is jumped to - // only from bn_mul_mont or __bn_mul8x_mont which have already signed the + // only from bn_mul_mont_words or __bn_mul8x_mont which have already signed the // return address. stp x29,x30,[sp,#-128]! add x29,sp,#0 diff --git a/Sources/CCryptoBoringSSL/gen/bcm/armv8-mont-linux.S b/Sources/CCryptoBoringSSL/gen/bcm/armv8-mont-linux.S index ab46c5b69..49281dbcf 100644 --- a/Sources/CCryptoBoringSSL/gen/bcm/armv8-mont-linux.S +++ b/Sources/CCryptoBoringSSL/gen/bcm/armv8-mont-linux.S @@ -7,11 +7,11 @@ #if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_AARCH64) && defined(__ELF__) .text -.globl bn_mul_mont -.hidden bn_mul_mont -.type bn_mul_mont,%function +.globl bn_mul_mont_words +.hidden bn_mul_mont_words +.type bn_mul_mont_words,%function .align 5 -bn_mul_mont: +bn_mul_mont_words: AARCH64_SIGN_LINK_REGISTER tst x5,#7 b.eq __bn_sqr8x_mont @@ -212,12 +212,12 @@ bn_mul_mont: ldr x29,[sp],#64 AARCH64_VALIDATE_LINK_REGISTER ret -.size bn_mul_mont,.-bn_mul_mont +.size bn_mul_mont_words,.-bn_mul_mont_words .type __bn_sqr8x_mont,%function .align 5 __bn_sqr8x_mont: // Not adding AARCH64_SIGN_LINK_REGISTER here because __bn_sqr8x_mont is jumped to - // only from bn_mul_mont which has already signed the return address. + // only from bn_mul_mont_words which has already signed the return address. cmp x1,x2 b.ne __bn_mul4x_mont .Lsqr8x_mont: @@ -979,7 +979,7 @@ __bn_sqr8x_mont: .align 5 __bn_mul4x_mont: // Not adding AARCH64_SIGN_LINK_REGISTER here because __bn_mul4x_mont is jumped to - // only from bn_mul_mont or __bn_mul8x_mont which have already signed the + // only from bn_mul_mont_words or __bn_mul8x_mont which have already signed the // return address. stp x29,x30,[sp,#-128]! add x29,sp,#0 diff --git a/Sources/CCryptoBoringSSL/gen/bcm/armv8-mont-win.S b/Sources/CCryptoBoringSSL/gen/bcm/armv8-mont-win.S index def7a92d9..c2b45f137 100644 --- a/Sources/CCryptoBoringSSL/gen/bcm/armv8-mont-win.S +++ b/Sources/CCryptoBoringSSL/gen/bcm/armv8-mont-win.S @@ -7,13 +7,13 @@ #if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_AARCH64) && defined(_WIN32) .text -.globl bn_mul_mont +.globl bn_mul_mont_words -.def bn_mul_mont +.def bn_mul_mont_words .type 32 .endef .align 5 -bn_mul_mont: +bn_mul_mont_words: AARCH64_SIGN_LINK_REGISTER tst x5,#7 b.eq __bn_sqr8x_mont @@ -221,7 +221,7 @@ Lcond_copy: .align 5 __bn_sqr8x_mont: // Not adding AARCH64_SIGN_LINK_REGISTER here because __bn_sqr8x_mont is jumped to - // only from bn_mul_mont which has already signed the return address. + // only from bn_mul_mont_words which has already signed the return address. cmp x1,x2 b.ne __bn_mul4x_mont Lsqr8x_mont: @@ -985,7 +985,7 @@ Lsqr8x_done: .align 5 __bn_mul4x_mont: // Not adding AARCH64_SIGN_LINK_REGISTER here because __bn_mul4x_mont is jumped to - // only from bn_mul_mont or __bn_mul8x_mont which have already signed the + // only from bn_mul_mont_words or __bn_mul8x_mont which have already signed the // return address. stp x29,x30,[sp,#-128]! add x29,sp,#0 diff --git a/Sources/CCryptoBoringSSL/gen/bcm/x86-mont-apple.S b/Sources/CCryptoBoringSSL/gen/bcm/x86-mont-apple.S index 03b00eee5..8a05634e6 100644 --- a/Sources/CCryptoBoringSSL/gen/bcm/x86-mont-apple.S +++ b/Sources/CCryptoBoringSSL/gen/bcm/x86-mont-apple.S @@ -6,11 +6,11 @@ #if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86) && defined(__APPLE__) .text -.globl _bn_mul_mont -.private_extern _bn_mul_mont +.globl _bn_mul_mont_words +.private_extern _bn_mul_mont_words .align 4 -_bn_mul_mont: -L_bn_mul_mont_begin: +_bn_mul_mont_words: +L_bn_mul_mont_words_begin: pushl %ebp pushl %ebx pushl %esi diff --git a/Sources/CCryptoBoringSSL/gen/bcm/x86-mont-linux.S b/Sources/CCryptoBoringSSL/gen/bcm/x86-mont-linux.S index 81cc896dc..37d96f457 100644 --- a/Sources/CCryptoBoringSSL/gen/bcm/x86-mont-linux.S +++ b/Sources/CCryptoBoringSSL/gen/bcm/x86-mont-linux.S @@ -6,12 +6,12 @@ #if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86) && defined(__ELF__) .text -.globl bn_mul_mont -.hidden bn_mul_mont -.type bn_mul_mont,@function +.globl bn_mul_mont_words +.hidden bn_mul_mont_words +.type bn_mul_mont_words,@function .align 16 -bn_mul_mont: -.L_bn_mul_mont_begin: +bn_mul_mont_words: +.L_bn_mul_mont_words_begin: pushl %ebp pushl %ebx pushl %esi @@ -210,7 +210,7 @@ bn_mul_mont: popl %ebx popl %ebp ret -.size bn_mul_mont,.-.L_bn_mul_mont_begin +.size bn_mul_mont_words,.-.L_bn_mul_mont_words_begin .byte 77,111,110,116,103,111,109,101,114,121,32,77,117,108,116,105 .byte 112,108,105,99,97,116,105,111,110,32,102,111,114,32,120,56 .byte 54,44,32,67,82,89,80,84,79,71,65,77,83,32,98,121 diff --git a/Sources/CCryptoBoringSSL/gen/crypto/err_data.cc b/Sources/CCryptoBoringSSL/gen/crypto/err_data.cc index 2e00d9193..f14c40fc8 100644 --- a/Sources/CCryptoBoringSSL/gen/crypto/err_data.cc +++ b/Sources/CCryptoBoringSSL/gen/crypto/err_data.cc @@ -78,54 +78,54 @@ const uint32_t kOpenSSLReasonValues[] = { 0xc3b00f7, 0xc3b8921, 0x10320892, - 0x103296b2, - 0x103316be, - 0x103396d7, - 0x103416ea, + 0x103296ad, + 0x103316b9, + 0x103396d2, + 0x103416e5, 0x10348fd3, 0x10350d1f, - 0x103596fd, - 0x10361727, - 0x1036973a, - 0x10371759, - 0x10379772, - 0x10381787, - 0x103897a5, - 0x103917b4, - 0x103997d0, - 0x103a17eb, - 0x103a97fa, - 0x103b1816, - 0x103b9831, - 0x103c1857, + 0x103596f8, + 0x10361722, + 0x10369735, + 0x10371754, + 0x1037976d, + 0x10381782, + 0x103897a0, + 0x103917af, + 0x103997cb, + 0x103a17e6, + 0x103a97f5, + 0x103b1811, + 0x103b982c, + 0x103c1852, 0x103c80f7, - 0x103d1868, - 0x103d987c, - 0x103e189b, - 0x103e98aa, - 0x103f18c1, - 0x103f98d4, + 0x103d1863, + 0x103d9877, + 0x103e1896, + 0x103e98a5, + 0x103f18bc, + 0x103f98cf, 0x10400ce3, - 0x104098e7, - 0x10411905, - 0x10419918, - 0x10421932, - 0x10429942, - 0x10431956, - 0x1043996c, - 0x10441984, - 0x10449999, - 0x104519ad, - 0x104599bf, + 0x104098e2, + 0x10411900, + 0x10419913, + 0x1042192d, + 0x1042993d, + 0x10431951, + 0x10439967, + 0x1044197f, + 0x10449994, + 0x104519a8, + 0x104599ba, 0x10460635, 0x1046899a, - 0x104719d4, - 0x104799eb, - 0x10481a00, - 0x10489a0e, + 0x104719cf, + 0x104799e6, + 0x104819fb, + 0x10489a09, 0x10490f1f, - 0x10499848, - 0x104a1712, + 0x10499843, + 0x104a170d, 0x14320cb3, 0x14328cd4, 0x14330ce3, @@ -139,57 +139,57 @@ const uint32_t kOpenSSLReasonValues[] = { 0x1833903f, 0x18341053, 0x183480f7, - 0x18351072, - 0x1835908a, - 0x183610b2, - 0x183690c6, - 0x183710fe, - 0x18379114, - 0x18381128, - 0x18389138, + 0x183510ae, + 0x18359072, + 0x1836109a, + 0x183690c1, + 0x183710f9, + 0x1837910f, + 0x18381123, + 0x18389133, 0x18390ac0, - 0x18399148, - 0x183a116e, - 0x183a9194, + 0x18399143, + 0x183a1169, + 0x183a918f, 0x183b0d2b, - 0x183b91e3, - 0x183c11f5, - 0x183c9200, - 0x183d1210, - 0x183d9221, - 0x183e1232, - 0x183e9244, - 0x183f126d, - 0x183f9286, - 0x1840129e, + 0x183b91de, + 0x183c11f0, + 0x183c91fb, + 0x183d120b, + 0x183d921c, + 0x183e122d, + 0x183e923f, + 0x183f1268, + 0x183f9281, + 0x18401299, 0x1840870d, - 0x184111b7, - 0x18419182, - 0x184211a1, + 0x184111b2, + 0x1841917d, + 0x1842119c, 0x18428cc1, - 0x1843115d, - 0x184391c9, + 0x18431158, + 0x184391c4, 0x18441068, - 0x184490ea, - 0x1845109f, - 0x203212d8, - 0x203292c5, - 0x243212e4, + 0x184490e5, + 0x18451087, + 0x203212d3, + 0x203292c0, + 0x243212df, 0x243289e0, - 0x243312f6, - 0x24339303, - 0x24341310, - 0x24349322, - 0x24351331, - 0x2435934e, - 0x2436135b, - 0x24369369, - 0x24371377, - 0x24379385, - 0x2438138e, - 0x2438939b, - 0x243913ae, - 0x243993c5, + 0x243312f1, + 0x243392fe, + 0x2434130b, + 0x2434931d, + 0x2435132c, + 0x24359349, + 0x24361356, + 0x24369364, + 0x24371372, + 0x24379380, + 0x24381389, + 0x24389396, + 0x243913a9, + 0x243993c0, 0x28320d13, 0x28328d2b, 0x28330ce3, @@ -199,51 +199,51 @@ const uint32_t kOpenSSLReasonValues[] = { 0x283500f7, 0x28358cc1, 0x2836099a, - 0x2c3233f9, - 0x2c3293e3, - 0x2c333407, - 0x2c33b419, - 0x2c34342d, - 0x2c34b43f, - 0x2c35345a, - 0x2c35b46c, - 0x2c36349c, + 0x2c3233f4, + 0x2c3293de, + 0x2c333402, + 0x2c33b414, + 0x2c343428, + 0x2c34b43a, + 0x2c353455, + 0x2c35b467, + 0x2c363497, 0x2c36833a, - 0x2c3734a9, - 0x2c37b4d5, - 0x2c383513, - 0x2c38b52a, - 0x2c393548, - 0x2c39b558, - 0x2c3a356a, - 0x2c3ab57e, - 0x2c3b358f, - 0x2c3bb5ae, - 0x2c3c13f5, - 0x2c3c940b, - 0x2c3d35f3, - 0x2c3d9424, - 0x2c3e361d, - 0x2c3eb62b, - 0x2c3f3643, - 0x2c3fb65b, - 0x2c403685, - 0x2c4092d8, - 0x2c413696, - 0x2c41b6a9, - 0x2c42129e, - 0x2c42b6ba, + 0x2c3734a4, + 0x2c37b4d0, + 0x2c38350e, + 0x2c38b525, + 0x2c393543, + 0x2c39b553, + 0x2c3a3565, + 0x2c3ab579, + 0x2c3b358a, + 0x2c3bb5a9, + 0x2c3c13f0, + 0x2c3c9406, + 0x2c3d35ee, + 0x2c3d941f, + 0x2c3e3618, + 0x2c3eb626, + 0x2c3f363e, + 0x2c3fb656, + 0x2c403680, + 0x2c4092d3, + 0x2c413691, + 0x2c41b6a4, + 0x2c421299, + 0x2c42b6b5, 0x2c43076d, - 0x2c43b5a0, - 0x2c4434e8, - 0x2c44b668, - 0x2c45347f, - 0x2c45b4bb, - 0x2c463538, - 0x2c46b5c2, - 0x2c4735d7, - 0x2c47b610, - 0x2c4834fa, + 0x2c43b59b, + 0x2c4434e3, + 0x2c44b663, + 0x2c45347a, + 0x2c45b4b6, + 0x2c463533, + 0x2c46b5bd, + 0x2c4735d2, + 0x2c47b60b, + 0x2c4834f5, 0x30320000, 0x30328015, 0x3033001f, @@ -383,268 +383,268 @@ const uint32_t kOpenSSLReasonValues[] = { 0x3c418e13, 0x3c420f1f, 0x3c428ea9, - 0x40321a7a, - 0x40329a90, - 0x40331abe, - 0x40339ac8, - 0x40341adf, - 0x40349afd, - 0x40351b0d, - 0x40359b1f, - 0x40361b2c, - 0x40369b38, - 0x40371b4d, - 0x40379b5f, - 0x40381b6a, - 0x40389b7c, + 0x40321a75, + 0x40329a8b, + 0x40331ab9, + 0x40339ac3, + 0x40341ada, + 0x40349af8, + 0x40351b08, + 0x40359b1a, + 0x40361b27, + 0x40369b33, + 0x40371b48, + 0x40379b5a, + 0x40381b65, + 0x40389b77, 0x40390fd3, - 0x40399b8c, - 0x403a1b9f, - 0x403a9bc0, - 0x403b1bd1, - 0x403b9be1, + 0x40399b87, + 0x403a1b9a, + 0x403a9bbb, + 0x403b1bcc, + 0x403b9bdc, 0x403c0071, 0x403c8090, - 0x403d1c42, - 0x403d9c58, - 0x403e1c67, - 0x403e9c9f, - 0x403f1cb9, - 0x403f9ce1, - 0x40401cf6, - 0x40409d0a, - 0x40411d45, - 0x40419d60, - 0x40421d79, - 0x40429d8c, - 0x40431da0, - 0x40439dce, - 0x40441de5, + 0x403d1c3d, + 0x403d9c53, + 0x403e1c62, + 0x403e9c9a, + 0x403f1cb4, + 0x403f9cdc, + 0x40401cf1, + 0x40409d05, + 0x40411d40, + 0x40419d5b, + 0x40421d74, + 0x40429d87, + 0x40431d9b, + 0x40439dc9, + 0x40441de0, 0x404480b9, - 0x40451dfa, - 0x40459e0c, - 0x40461e30, - 0x40469e50, - 0x40471e5e, - 0x40479e85, - 0x40481ef6, - 0x40489fb0, - 0x40491fc7, - 0x40499fe1, - 0x404a1ff8, - 0x404aa016, - 0x404b202e, - 0x404ba05b, - 0x404c2071, - 0x404ca083, - 0x404d20a4, - 0x404da0dd, - 0x404e20f1, - 0x404ea0fe, - 0x404f21af, - 0x404fa225, - 0x405022af, - 0x4050a2c3, - 0x405122f6, - 0x40522306, - 0x4052a32a, - 0x40532342, - 0x4053a355, - 0x4054236a, - 0x4054a38d, - 0x405523b8, - 0x4055a3f5, - 0x4056241a, - 0x4056a433, - 0x4057244b, - 0x4057a45e, - 0x40582473, - 0x4058a49a, - 0x405924c9, - 0x4059a509, - 0x405aa51d, - 0x405b2535, - 0x405ba546, - 0x405c2559, - 0x405ca598, - 0x405d25a5, - 0x405da5ca, - 0x405e2608, + 0x40451df5, + 0x40459e07, + 0x40461e2b, + 0x40469e4b, + 0x40471e59, + 0x40479e80, + 0x40481ef1, + 0x40489fab, + 0x40491fc2, + 0x40499fdc, + 0x404a1ff3, + 0x404aa011, + 0x404b2029, + 0x404ba056, + 0x404c206c, + 0x404ca07e, + 0x404d209f, + 0x404da0d8, + 0x404e20ec, + 0x404ea0f9, + 0x404f21aa, + 0x404fa220, + 0x405022aa, + 0x4050a2be, + 0x405122f1, + 0x40522301, + 0x4052a325, + 0x4053233d, + 0x4053a350, + 0x40542365, + 0x4054a388, + 0x405523b3, + 0x4055a3f0, + 0x40562415, + 0x4056a42e, + 0x40572446, + 0x4057a459, + 0x4058246e, + 0x4058a495, + 0x405924c4, + 0x4059a504, + 0x405aa518, + 0x405b2530, + 0x405ba541, + 0x405c2554, + 0x405ca593, + 0x405d25a0, + 0x405da5c5, + 0x405e2603, 0x405e8afe, - 0x405f2657, - 0x405fa664, - 0x40602672, - 0x4060a694, - 0x40612708, - 0x4061a740, - 0x40622757, - 0x4062a768, - 0x406327b5, - 0x4063a7ca, - 0x406427e1, - 0x4064a80d, - 0x40652828, - 0x4065a83f, - 0x40662857, - 0x4066a881, - 0x406728ac, - 0x4067a8f1, - 0x40682939, - 0x4068a95a, - 0x4069298c, - 0x4069a9ba, - 0x406a29db, - 0x406aa9fb, - 0x406b2b83, - 0x406baba6, - 0x406c2bbc, - 0x406caec6, - 0x406d2ef5, - 0x406daf1d, - 0x406e2f4b, - 0x406eaf98, - 0x406f2ff1, - 0x406fb029, - 0x4070303c, - 0x4070b059, + 0x405f2652, + 0x405fa65f, + 0x4060266d, + 0x4060a68f, + 0x40612703, + 0x4061a73b, + 0x40622752, + 0x4062a763, + 0x406327b0, + 0x4063a7c5, + 0x406427dc, + 0x4064a808, + 0x40652823, + 0x4065a83a, + 0x40662852, + 0x4066a87c, + 0x406728a7, + 0x4067a8ec, + 0x40682934, + 0x4068a955, + 0x40692987, + 0x4069a9b5, + 0x406a29d6, + 0x406aa9f6, + 0x406b2b7e, + 0x406baba1, + 0x406c2bb7, + 0x406caec1, + 0x406d2ef0, + 0x406daf18, + 0x406e2f46, + 0x406eaf93, + 0x406f2fec, + 0x406fb024, + 0x40703037, + 0x4070b054, 0x4071084d, - 0x4071b06b, - 0x4072307e, - 0x4072b0b4, - 0x407330cc, - 0x4073960d, - 0x407430e0, - 0x4074b0fa, - 0x4075310b, - 0x4075b11f, - 0x4076312d, - 0x4076939b, - 0x40773152, - 0x4077b1ea, - 0x40783205, - 0x4078b23e, - 0x40793255, - 0x4079b26b, - 0x407a3297, - 0x407ab2aa, - 0x407b32bf, - 0x407bb2d1, - 0x407c3302, - 0x407cb30b, - 0x407d2975, - 0x407da24d, - 0x407e321a, - 0x407ea4aa, - 0x407f1e72, - 0x407fa045, - 0x408021bf, - 0x40809e9a, - 0x40812318, - 0x4081a14c, - 0x40822f36, - 0x40829bed, - 0x40832485, - 0x4083a7f2, - 0x40841eae, - 0x4084a4e2, - 0x4085256a, - 0x4085a6cf, - 0x408625ea, - 0x4086a267, - 0x40872f7c, - 0x4087a71d, - 0x40881c2b, - 0x4088a904, - 0x40891c7a, - 0x40899c07, - 0x408a2bf4, - 0x408a9a25, - 0x408b32e6, - 0x408bb006, - 0x408c257a, - 0x408d1f96, - 0x408d9ee0, - 0x408e20c6, - 0x408ea3d5, - 0x408f2918, - 0x408fa6eb, - 0x409028cd, - 0x4090a5bc, - 0x40912bdc, - 0x40919a5d, - 0x40921cc7, - 0x4092afb7, - 0x40933097, - 0x4093a278, - 0x40941ec2, - 0x4094ac0d, - 0x40952779, - 0x4095b277, - 0x40962f63, - 0x4096a1d8, - 0x409722de, - 0x4097a115, - 0x40981d27, - 0x4098a78d, - 0x40992fd3, - 0x4099a402, - 0x409a239b, - 0x409a9a41, - 0x409b1f1c, - 0x409b9f47, - 0x409c31cc, - 0x409c9f6f, - 0x409d2194, - 0x409da162, - 0x409e1db8, - 0x409ea20d, - 0x409f21f5, - 0x409f9f0f, - 0x40a02235, - 0x40a0a12f, - 0x40a1217d, - 0x40a1a4f6, - 0x40a22294, - 0x40a2a648, - 0x40a326bc, - 0x40a3b174, - 0x40a43190, - 0x40a4b1aa, - 0x41f42aae, - 0x41f92b40, - 0x41fe2a33, - 0x41feace9, - 0x41ff2e17, - 0x42032ac7, - 0x42082ae9, - 0x4208ab25, - 0x42092a17, - 0x4209ab5f, - 0x420a2a6e, - 0x420aaa4e, - 0x420b2a8e, - 0x420bab07, - 0x420c2e33, - 0x420cac1d, - 0x420d2cd0, - 0x420dad07, - 0x42122d3a, - 0x42172dfa, - 0x4217ad7c, - 0x421c2d9e, - 0x421f2d59, - 0x42212eab, - 0x42262ddd, - 0x422b2e89, - 0x422bacab, - 0x422c2e6b, - 0x422cac5e, - 0x422d2c37, - 0x422dae4a, - 0x422e2c8a, - 0x42302db9, - 0x4230ad21, - 0x42312629, + 0x4071b066, + 0x40723079, + 0x4072b0af, + 0x407330c7, + 0x40739608, + 0x407430db, + 0x4074b0f5, + 0x40753106, + 0x4075b11a, + 0x40763128, + 0x40769396, + 0x4077314d, + 0x4077b1e5, + 0x40783200, + 0x4078b239, + 0x40793250, + 0x4079b266, + 0x407a3292, + 0x407ab2a5, + 0x407b32ba, + 0x407bb2cc, + 0x407c32fd, + 0x407cb306, + 0x407d2970, + 0x407da248, + 0x407e3215, + 0x407ea4a5, + 0x407f1e6d, + 0x407fa040, + 0x408021ba, + 0x40809e95, + 0x40812313, + 0x4081a147, + 0x40822f31, + 0x40829be8, + 0x40832480, + 0x4083a7ed, + 0x40841ea9, + 0x4084a4dd, + 0x40852565, + 0x4085a6ca, + 0x408625e5, + 0x4086a262, + 0x40872f77, + 0x4087a718, + 0x40881c26, + 0x4088a8ff, + 0x40891c75, + 0x40899c02, + 0x408a2bef, + 0x408a9a20, + 0x408b32e1, + 0x408bb001, + 0x408c2575, + 0x408d1f91, + 0x408d9edb, + 0x408e20c1, + 0x408ea3d0, + 0x408f2913, + 0x408fa6e6, + 0x409028c8, + 0x4090a5b7, + 0x40912bd7, + 0x40919a58, + 0x40921cc2, + 0x4092afb2, + 0x40933092, + 0x4093a273, + 0x40941ebd, + 0x4094ac08, + 0x40952774, + 0x4095b272, + 0x40962f5e, + 0x4096a1d3, + 0x409722d9, + 0x4097a110, + 0x40981d22, + 0x4098a788, + 0x40992fce, + 0x4099a3fd, + 0x409a2396, + 0x409a9a3c, + 0x409b1f17, + 0x409b9f42, + 0x409c31c7, + 0x409c9f6a, + 0x409d218f, + 0x409da15d, + 0x409e1db3, + 0x409ea208, + 0x409f21f0, + 0x409f9f0a, + 0x40a02230, + 0x40a0a12a, + 0x40a12178, + 0x40a1a4f1, + 0x40a2228f, + 0x40a2a643, + 0x40a326b7, + 0x40a3b16f, + 0x40a4318b, + 0x40a4b1a5, + 0x41f42aa9, + 0x41f92b3b, + 0x41fe2a2e, + 0x41feace4, + 0x41ff2e12, + 0x42032ac2, + 0x42082ae4, + 0x4208ab20, + 0x42092a12, + 0x4209ab5a, + 0x420a2a69, + 0x420aaa49, + 0x420b2a89, + 0x420bab02, + 0x420c2e2e, + 0x420cac18, + 0x420d2ccb, + 0x420dad02, + 0x42122d35, + 0x42172df5, + 0x4217ad77, + 0x421c2d99, + 0x421f2d54, + 0x42212ea6, + 0x42262dd8, + 0x422b2e84, + 0x422baca6, + 0x422c2e66, + 0x422cac59, + 0x422d2c32, + 0x422dae45, + 0x422e2c85, + 0x42302db4, + 0x4230ad1c, + 0x42312624, 0x44320778, 0x44328787, 0x44330793, @@ -662,109 +662,109 @@ const uint32_t kOpenSSLReasonValues[] = { 0x4439084d, 0x4439885b, 0x443a086e, - 0x483213e3, - 0x483293f5, - 0x4833140b, - 0x48339424, - 0x4c321461, - 0x4c329471, - 0x4c331484, - 0x4c3394a4, + 0x483213de, + 0x483293f0, + 0x48331406, + 0x4833941f, + 0x4c32145c, + 0x4c32946c, + 0x4c33147f, + 0x4c33949f, 0x4c3400b9, 0x4c3480f7, - 0x4c3514b0, - 0x4c3594be, - 0x4c3614da, - 0x4c369500, - 0x4c37150f, - 0x4c37951d, - 0x4c381532, - 0x4c38953e, - 0x4c39155e, - 0x4c399588, - 0x4c3a15a1, - 0x4c3a95ba, + 0x4c3514ab, + 0x4c3594b9, + 0x4c3614d5, + 0x4c3694fb, + 0x4c37150a, + 0x4c379518, + 0x4c38152d, + 0x4c389539, + 0x4c391559, + 0x4c399583, + 0x4c3a159c, + 0x4c3a95b5, 0x4c3b0635, - 0x4c3b95d3, - 0x4c3c15e5, - 0x4c3c95f4, - 0x4c3d160d, + 0x4c3b95ce, + 0x4c3c15e0, + 0x4c3c95ef, + 0x4c3d1608, 0x4c3d8d06, - 0x4c3e167a, - 0x4c3e961c, - 0x4c3f169c, - 0x4c3f939b, - 0x4c401632, - 0x4c40944d, - 0x4c41166a, - 0x4c4194ed, - 0x4c421656, - 0x4c429435, - 0x503236cc, - 0x5032b6db, - 0x503336e6, - 0x5033b6f6, - 0x5034370f, - 0x5034b729, - 0x50353737, - 0x5035b74d, - 0x5036375f, - 0x5036b775, - 0x5037378e, - 0x5037b7a1, - 0x503837b9, - 0x5038b7ca, - 0x503937df, - 0x5039b7f3, - 0x503a3813, - 0x503ab829, - 0x503b3841, - 0x503bb853, - 0x503c386f, - 0x503cb886, - 0x503d389f, - 0x503db8b5, - 0x503e38c2, - 0x503eb8d8, - 0x503f38ea, + 0x4c3e1675, + 0x4c3e9617, + 0x4c3f1697, + 0x4c3f9396, + 0x4c40162d, + 0x4c409448, + 0x4c411665, + 0x4c4194e8, + 0x4c421651, + 0x4c429430, + 0x503236c7, + 0x5032b6d6, + 0x503336e1, + 0x5033b6f1, + 0x5034370a, + 0x5034b724, + 0x50353732, + 0x5035b748, + 0x5036375a, + 0x5036b770, + 0x50373789, + 0x5037b79c, + 0x503837b4, + 0x5038b7c5, + 0x503937da, + 0x5039b7ee, + 0x503a380e, + 0x503ab824, + 0x503b383c, + 0x503bb84e, + 0x503c386a, + 0x503cb881, + 0x503d389a, + 0x503db8b0, + 0x503e38bd, + 0x503eb8d3, + 0x503f38e5, 0x503f83b3, - 0x504038fd, - 0x5040b90d, - 0x50413927, - 0x5041b936, - 0x50423950, - 0x5042b96d, - 0x5043397d, - 0x5043b98d, - 0x504439aa, + 0x504038f8, + 0x5040b908, + 0x50413922, + 0x5041b931, + 0x5042394b, + 0x5042b968, + 0x50433978, + 0x5043b988, + 0x504439a5, 0x50448469, - 0x504539be, - 0x5045b9dc, - 0x504639ef, - 0x5046ba05, - 0x50473a17, - 0x5047ba2c, - 0x50483a52, - 0x5048ba60, - 0x50493a73, - 0x5049ba88, - 0x504a3a9e, - 0x504abaae, - 0x504b3ace, - 0x504bbae1, - 0x504c3b04, - 0x504cbb32, - 0x504d3b5f, - 0x504dbb7c, - 0x504e3b97, - 0x504ebbb3, - 0x504f3bc5, - 0x504fbbdc, - 0x50503beb, + 0x504539b9, + 0x5045b9d7, + 0x504639ea, + 0x5046ba00, + 0x50473a12, + 0x5047ba27, + 0x50483a4d, + 0x5048ba5b, + 0x50493a6e, + 0x5049ba83, + 0x504a3a99, + 0x504abaa9, + 0x504b3ac9, + 0x504bbadc, + 0x504c3aff, + 0x504cbb2d, + 0x504d3b5a, + 0x504dbb77, + 0x504e3b92, + 0x504ebbae, + 0x504f3bc0, + 0x504fbbd7, + 0x50503be6, 0x50508729, - 0x50513bfe, - 0x5051b99c, - 0x50523b44, + 0x50513bf9, + 0x5051b997, + 0x50523b3f, 0x58321011, 0x68320fd3, 0x68328d2b, @@ -806,22 +806,22 @@ const uint32_t kOpenSSLReasonValues[] = { 0x783d8b97, 0x783e0aed, 0x783e8a9f, - 0x7c3212b4, - 0x80321500, + 0x7c3212af, + 0x803214fb, 0x80328090, - 0x803333c8, + 0x803333c3, 0x803380b9, - 0x803433d7, - 0x8034b33f, - 0x8035335d, - 0x8035b3eb, - 0x8036339f, - 0x8036b34e, - 0x80373391, - 0x8037b32c, - 0x803833b2, - 0x8038b36e, - 0x80393383, + 0x803433d2, + 0x8034b33a, + 0x80353358, + 0x8035b3e6, + 0x8036339a, + 0x8036b349, + 0x8037338c, + 0x8037b327, + 0x803833ad, + 0x8038b369, + 0x8039337e, 0x84320bb0, 0x84328bc9, }; @@ -1049,10 +1049,10 @@ const char kOpenSSLReasonStringData[] = "DIFFERENT_KEY_TYPES\0" "DIFFERENT_PARAMETERS\0" "EMPTY_PSK\0" - "EXPECTING_AN_EC_KEY_KEY\0" "EXPECTING_AN_RSA_KEY\0" "EXPECTING_A_DH_KEY\0" "EXPECTING_A_DSA_KEY\0" + "EXPECTING_A_EC_KEY\0" "ILLEGAL_OR_UNSUPPORTED_PADDING_MODE\0" "INVALID_BUFFER_SIZE\0" "INVALID_DIGEST_LENGTH\0" diff --git a/Sources/CCryptoBoringSSL/hash.txt b/Sources/CCryptoBoringSSL/hash.txt index 60ae1b489..d3430aebc 100644 --- a/Sources/CCryptoBoringSSL/hash.txt +++ b/Sources/CCryptoBoringSSL/hash.txt @@ -1 +1 @@ -This directory is derived from BoringSSL cloned from https://boringssl.googlesource.com/boringssl at revision 035e720641f385e82c72b7b0a9e1d89e58cb5ed5 +This directory is derived from BoringSSL cloned from https://boringssl.googlesource.com/boringssl at revision 0226f30467f540a3f62ef48d453f93927da199b6 diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_asn1.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_asn1.h index a5791995a..b9368dcc8 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_asn1.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_asn1.h @@ -801,10 +801,6 @@ OPENSSL_EXPORT ASN1_STRING *d2i_DIRECTORYSTRING(ASN1_STRING **out, // 5280), as described in |i2d_SAMPLE|. OPENSSL_EXPORT int i2d_DIRECTORYSTRING(const ASN1_STRING *in, uint8_t **outp); -// DIRECTORYSTRING is an |ASN1_ITEM| whose ASN.1 type is X.509 DirectoryString -// (RFC 5280) and C type is |ASN1_STRING*|. -DECLARE_ASN1_ITEM(DIRECTORYSTRING) - // B_ASN1_DISPLAYTEXT is a bitmask of types allowed in an X.509 DisplayText (RFC // 5280). #define B_ASN1_DISPLAYTEXT \ @@ -834,10 +830,6 @@ OPENSSL_EXPORT ASN1_STRING *d2i_DISPLAYTEXT(ASN1_STRING **out, // as described in |i2d_SAMPLE|. OPENSSL_EXPORT int i2d_DISPLAYTEXT(const ASN1_STRING *in, uint8_t **outp); -// DISPLAYTEXT is an |ASN1_ITEM| whose ASN.1 type is X.509 DisplayText (RFC -// 5280) and C type is |ASN1_STRING*|. -DECLARE_ASN1_ITEM(DISPLAYTEXT) - // Bit strings. // @@ -1258,10 +1250,6 @@ OPENSSL_EXPORT ASN1_TIME *d2i_ASN1_TIME(ASN1_TIME **out, const uint8_t **inp, // described in |i2d_SAMPLE|. OPENSSL_EXPORT int i2d_ASN1_TIME(const ASN1_TIME *in, uint8_t **outp); -// ASN1_TIME is an |ASN1_ITEM| whose ASN.1 type is X.509 Time (RFC 5280) and C -// type is |ASN1_TIME*|. -DECLARE_ASN1_ITEM(ASN1_TIME) - // ASN1_TIME_diff computes |to| - |from|. On success, it sets |*out_days| to the // difference in days, rounded towards zero, sets |*out_seconds| to the // remainder, and returns one. On error, it returns zero. diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_asn1t.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_asn1t.h index 92f1d66d6..24c7860b6 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_asn1t.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_asn1t.h @@ -491,8 +491,8 @@ typedef struct ASN1_AUX_st { ASN1_ITEM_start(itname) ASN1_ITYPE_MSTRING, mask, NULL, 0, NULL, \ sizeof(ASN1_STRING), #itname ASN1_ITEM_end(itname) -#define IMPLEMENT_EXTERN_ASN1(sname, tag, fptrs) \ - ASN1_ITEM_start(sname) ASN1_ITYPE_EXTERN, tag, NULL, 0, &fptrs, 0, \ +#define IMPLEMENT_EXTERN_ASN1(sname, fptrs) \ + ASN1_ITEM_start(sname) ASN1_ITYPE_EXTERN, -1, NULL, 0, &fptrs, 0, \ #sname ASN1_ITEM_end(sname) /* Macro to implement standard functions in terms of ASN1_ITEM structures */ diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_base.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_base.h index 66f2c2eae..676d7868e 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_base.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_base.h @@ -335,6 +335,7 @@ typedef struct evp_hpke_ctx_st EVP_HPKE_CTX; typedef struct evp_hpke_kdf_st EVP_HPKE_KDF; typedef struct evp_hpke_kem_st EVP_HPKE_KEM; typedef struct evp_hpke_key_st EVP_HPKE_KEY; +typedef struct evp_pkey_alg_st EVP_PKEY_ALG; typedef struct evp_pkey_ctx_st EVP_PKEY_CTX; typedef struct evp_pkey_st EVP_PKEY; typedef struct hmac_ctx_st HMAC_CTX; diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_bcm_public.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_bcm_public.h index 0b0d62edd..4b6db8b8f 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_bcm_public.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_bcm_public.h @@ -15,7 +15,7 @@ #ifndef OPENSSL_HEADER_BCM_PUBLIC_H_ #define OPENSSL_HEADER_BCM_PUBLIC_H_ -#include "CCryptoBoringSSL_base.h" // IWYU pragma: export +#include "CCryptoBoringSSL_base.h" // IWYU pragma: export #if defined(__cplusplus) extern "C" { @@ -69,9 +69,10 @@ struct sha256_state_st { struct sha512_state_st { uint64_t h[8]; - uint64_t Nl, Nh; + uint16_t num, md_len; + uint32_t bytes_so_far_high; + uint64_t bytes_so_far_low; uint8_t p[BCM_SHA512_CBLOCK]; - unsigned num, md_len; }; diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_blake2.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_blake2.h index fa549e307..c0fe056cb 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_blake2.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_blake2.h @@ -15,7 +15,7 @@ #ifndef OPENSSL_HEADER_BLAKE2_H #define OPENSSL_HEADER_BLAKE2_H -#include "CCryptoBoringSSL_base.h" // IWYU pragma: export +#include "CCryptoBoringSSL_base.h" // IWYU pragma: export #if defined(__cplusplus) extern "C" { @@ -27,9 +27,10 @@ extern "C" { struct blake2b_state_st { uint64_t h[8]; - uint64_t t_low, t_high; + uint64_t t_low; + uint32_t t_high; + uint32_t block_used; uint8_t block[BLAKE2B_CBLOCK]; - size_t block_used; }; // BLAKE2B256_Init initialises |b2b| to perform a BLAKE2b-256 hash. There are no diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_bn.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_bn.h index b5a165860..87fc5f7f0 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_bn.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_bn.h @@ -916,16 +916,6 @@ struct bignum_st { int flags; }; -struct bn_mont_ctx_st { - // RR is R^2, reduced modulo |N|. It is used to convert to Montgomery form. It - // is guaranteed to have the same width as |N|. - BIGNUM RR; - // N is the modulus. It is always stored in minimal form, so |N.width| - // determines R. - BIGNUM N; - BN_ULONG n0[2]; // least significant words of (R*Ri-1)/N -}; - OPENSSL_EXPORT unsigned BN_num_bits_word(BN_ULONG l); #define BN_FLG_MALLOCED 0x01 diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols.h index 8b97b726b..bda146a92 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols.h @@ -165,8 +165,12 @@ #define ASN1_item_sign_ctx BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_item_sign_ctx) #define ASN1_item_unpack BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_item_unpack) #define ASN1_item_verify BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_item_verify) +#define asn1_marshal_any BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_marshal_any) #define asn1_marshal_bit_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_marshal_bit_string) #define asn1_marshal_integer BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_marshal_integer) +#define asn1_marshal_object BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_marshal_object) +#define asn1_marshal_octet_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_marshal_octet_string) +#define asn1_marshal_time BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_marshal_time) #define ASN1_mbstring_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_mbstring_copy) #define ASN1_mbstring_ncopy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_mbstring_ncopy) #define ASN1_NULL_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_NULL_free) @@ -183,6 +187,20 @@ #define ASN1_OCTET_STRING_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_OCTET_STRING_it) #define ASN1_OCTET_STRING_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_OCTET_STRING_new) #define ASN1_OCTET_STRING_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_OCTET_STRING_set) +#define asn1_parse_any BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_parse_any) +#define asn1_parse_any_as_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_parse_any_as_string) +#define asn1_parse_bit_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_parse_bit_string) +#define asn1_parse_bit_string_with_bad_length BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_parse_bit_string_with_bad_length) +#define asn1_parse_bmp_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_parse_bmp_string) +#define asn1_parse_enumerated BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_parse_enumerated) +#define asn1_parse_generalized_time BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_parse_generalized_time) +#define asn1_parse_integer BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_parse_integer) +#define asn1_parse_object BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_parse_object) +#define asn1_parse_octet_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_parse_octet_string) +#define asn1_parse_time BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_parse_time) +#define asn1_parse_universal_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_parse_universal_string) +#define asn1_parse_utc_time BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_parse_utc_time) +#define asn1_parse_utf8_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_parse_utf8_string) #define ASN1_primitive_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_primitive_free) #define ASN1_PRINTABLESTRING_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_PRINTABLESTRING_free) #define ASN1_PRINTABLESTRING_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_PRINTABLESTRING_it) @@ -193,6 +211,7 @@ #define asn1_refcount_set_one BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_refcount_set_one) #define ASN1_SEQUENCE_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_SEQUENCE_it) #define asn1_set_choice_selector BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_set_choice_selector) +#define asn1_string_cleanup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_string_cleanup) #define ASN1_STRING_cmp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_cmp) #define ASN1_STRING_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_copy) #define ASN1_STRING_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_data) @@ -200,6 +219,7 @@ #define ASN1_STRING_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_free) #define ASN1_STRING_get_default_mask BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_get_default_mask) #define ASN1_STRING_get0_data BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_get0_data) +#define asn1_string_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, asn1_string_init) #define ASN1_STRING_length BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_length) #define ASN1_STRING_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_new) #define ASN1_STRING_print BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ASN1_STRING_print) @@ -280,6 +300,26 @@ #define bcm_as_approved_status BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bcm_as_approved_status) #define bcm_as_not_approved_status BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bcm_as_not_approved_status) #define BCM_fips_186_2_prf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_fips_186_2_prf) +#define BCM_mldsa44_check_key_fips BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_check_key_fips) +#define BCM_mldsa44_generate_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_generate_key) +#define BCM_mldsa44_generate_key_external_entropy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_generate_key_external_entropy) +#define BCM_mldsa44_generate_key_external_entropy_fips BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_generate_key_external_entropy_fips) +#define BCM_mldsa44_generate_key_fips BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_generate_key_fips) +#define BCM_mldsa44_marshal_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_marshal_private_key) +#define BCM_mldsa44_marshal_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_marshal_public_key) +#define BCM_mldsa44_parse_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_parse_private_key) +#define BCM_mldsa44_parse_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_parse_public_key) +#define BCM_mldsa44_prehash_finalize BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_prehash_finalize) +#define BCM_mldsa44_prehash_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_prehash_init) +#define BCM_mldsa44_prehash_update BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_prehash_update) +#define BCM_mldsa44_private_key_from_seed BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_private_key_from_seed) +#define BCM_mldsa44_private_key_from_seed_fips BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_private_key_from_seed_fips) +#define BCM_mldsa44_public_from_private BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_public_from_private) +#define BCM_mldsa44_sign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_sign) +#define BCM_mldsa44_sign_internal BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_sign_internal) +#define BCM_mldsa44_sign_message_representative BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_sign_message_representative) +#define BCM_mldsa44_verify BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_verify) +#define BCM_mldsa44_verify_internal BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa44_verify_internal) #define BCM_mldsa65_check_key_fips BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa65_check_key_fips) #define BCM_mldsa65_generate_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa65_generate_key) #define BCM_mldsa65_generate_key_external_entropy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BCM_mldsa65_generate_key_external_entropy) @@ -630,9 +670,9 @@ #define bn_mul_comba4 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mul_comba4) #define bn_mul_comba8 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mul_comba8) #define bn_mul_consttime BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mul_consttime) -#define bn_mul_mont BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mul_mont) #define bn_mul_mont_gather5_nohw BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mul_mont_gather5_nohw) #define bn_mul_mont_nohw BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mul_mont_nohw) +#define bn_mul_mont_words BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mul_mont_words) #define bn_mul_small BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mul_small) #define BN_mul_word BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, BN_mul_word) #define bn_mul_words BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bn_mul_words) @@ -880,6 +920,7 @@ #define CMS_sign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CMS_sign) #define CONF_modules_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CONF_modules_free) #define CONF_modules_load_file BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CONF_modules_load_file) +#define CONF_modules_unload BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CONF_modules_unload) #define CONF_parse_list BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CONF_parse_list) #define CONF_VALUE_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CONF_VALUE_new) #define CRL_DIST_POINTS_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CRL_DIST_POINTS_free) @@ -1014,7 +1055,9 @@ #define CTR_DRBG_generate BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CTR_DRBG_generate) #define CTR_DRBG_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CTR_DRBG_init) #define CTR_DRBG_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CTR_DRBG_new) +#define CTR_DRBG_new_df BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CTR_DRBG_new_df) #define CTR_DRBG_reseed BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CTR_DRBG_reseed) +#define CTR_DRBG_reseed_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, CTR_DRBG_reseed_ex) #define d2i_ASN1_BIT_STRING BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ASN1_BIT_STRING) #define d2i_ASN1_BMPSTRING BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ASN1_BMPSTRING) #define d2i_ASN1_BOOLEAN BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_ASN1_BOOLEAN) @@ -1105,7 +1148,6 @@ #define d2i_X509_AUX BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_AUX) #define d2i_X509_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_bio) #define d2i_X509_CERT_AUX BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_CERT_AUX) -#define d2i_X509_CINF BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_CINF) #define d2i_X509_CRL BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_CRL) #define d2i_X509_CRL_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_CRL_bio) #define d2i_X509_CRL_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_CRL_fp) @@ -1121,7 +1163,6 @@ #define d2i_X509_REQ_INFO BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_REQ_INFO) #define d2i_X509_REVOKED BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_REVOKED) #define d2i_X509_SIG BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_SIG) -#define d2i_X509_VAL BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, d2i_X509_VAL) #define DES_decrypt3 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DES_decrypt3) #define DES_ecb_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DES_ecb_encrypt) #define DES_ecb_encrypt_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, DES_ecb_encrypt_ex) @@ -1329,8 +1370,11 @@ #define EC_KEY_new_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_new_method) #define EC_KEY_oct2key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_oct2key) #define EC_KEY_oct2priv BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_oct2priv) +#define ec_key_parse_curve_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_key_parse_curve_name) #define EC_KEY_parse_curve_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_parse_curve_name) +#define ec_key_parse_parameters BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_key_parse_parameters) #define EC_KEY_parse_parameters BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_parse_parameters) +#define ec_key_parse_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ec_key_parse_private_key) #define EC_KEY_parse_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_parse_private_key) #define EC_KEY_priv2buf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_priv2buf) #define EC_KEY_priv2oct BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EC_KEY_priv2oct) @@ -1465,6 +1509,7 @@ #define ED25519_verify BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ED25519_verify) #define EDIPARTYNAME_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EDIPARTYNAME_free) #define EDIPARTYNAME_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EDIPARTYNAME_new) +#define ENGINE_cleanup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ENGINE_cleanup) #define ENGINE_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ENGINE_free) #define ENGINE_get_ECDSA_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ENGINE_get_ECDSA_method) #define ENGINE_get_RSA_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ENGINE_get_RSA_method) @@ -1477,6 +1522,7 @@ #define ERR_add_error_dataf BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_add_error_dataf) #define ERR_clear_error BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_clear_error) #define ERR_clear_system_error BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_clear_system_error) +#define ERR_equals BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_equals) #define ERR_error_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_error_string) #define ERR_error_string_n BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_error_string_n) #define ERR_free_strings BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ERR_free_strings) @@ -1703,6 +1749,7 @@ #define EVP_HPKE_KEY_zero BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_HPKE_KEY_zero) #define EVP_hpke_p256_hkdf_sha256 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_hpke_p256_hkdf_sha256) #define EVP_hpke_x25519_hkdf_sha256 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_hpke_x25519_hkdf_sha256) +#define EVP_hpke_xwing BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_hpke_xwing) #define EVP_marshal_digest_algorithm BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_marshal_digest_algorithm) #define EVP_marshal_digest_algorithm_no_params BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_marshal_digest_algorithm_no_params) #define EVP_marshal_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_marshal_private_key) @@ -1734,6 +1781,7 @@ #define EVP_md5 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_md5) #define EVP_md5_sha1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_md5_sha1) #define EVP_parse_digest_algorithm BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_parse_digest_algorithm) +#define EVP_parse_digest_algorithm_nid BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_parse_digest_algorithm_nid) #define EVP_parse_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_parse_private_key) #define EVP_parse_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_parse_public_key) #define EVP_PBE_scrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PBE_scrypt) @@ -1786,9 +1834,21 @@ #define EVP_PKEY_derive BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_derive) #define EVP_PKEY_derive_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_derive_init) #define EVP_PKEY_derive_set_peer BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_derive_set_peer) +#define EVP_pkey_dsa BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_pkey_dsa) +#define EVP_pkey_ec_p224 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_pkey_ec_p224) +#define EVP_pkey_ec_p256 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_pkey_ec_p256) +#define EVP_pkey_ec_p384 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_pkey_ec_p384) +#define EVP_pkey_ec_p521 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_pkey_ec_p521) +#define EVP_pkey_ed25519 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_pkey_ed25519) #define EVP_PKEY_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_encrypt) #define EVP_PKEY_encrypt_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_encrypt_init) #define EVP_PKEY_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_free) +#define EVP_PKEY_from_private_key_info BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_from_private_key_info) +#define EVP_PKEY_from_raw_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_from_raw_private_key) +#define EVP_PKEY_from_raw_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_from_raw_public_key) +#define EVP_PKEY_from_subject_public_key_info BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_from_subject_public_key_info) +#define EVP_PKEY_get_ec_curve_nid BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_get_ec_curve_nid) +#define EVP_PKEY_get_ec_point_conv_form BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_get_ec_point_conv_form) #define EVP_PKEY_get_raw_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_get_raw_private_key) #define EVP_PKEY_get_raw_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_get_raw_public_key) #define EVP_PKEY_get0 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_get0) @@ -1814,8 +1874,10 @@ #define EVP_PKEY_print_params BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_print_params) #define EVP_PKEY_print_private BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_print_private) #define EVP_PKEY_print_public BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_print_public) -#define evp_pkey_set_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, evp_pkey_set_method) +#define EVP_pkey_rsa BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_pkey_rsa) +#define EVP_pkey_rsa_pss_sha256 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_pkey_rsa_pss_sha256) #define EVP_PKEY_set_type BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_set_type) +#define evp_pkey_set0 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, evp_pkey_set0) #define EVP_PKEY_set1_DH BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_set1_DH) #define EVP_PKEY_set1_DSA BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_set1_DSA) #define EVP_PKEY_set1_EC_KEY BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_set1_EC_KEY) @@ -1830,6 +1892,7 @@ #define EVP_PKEY_verify_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_verify_init) #define EVP_PKEY_verify_recover BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_verify_recover) #define EVP_PKEY_verify_recover_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY_verify_recover_init) +#define EVP_pkey_x25519 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_pkey_x25519) #define EVP_PKEY2PKCS8 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_PKEY2PKCS8) #define EVP_rc2_40_cbc BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_rc2_40_cbc) #define EVP_rc2_cbc BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, EVP_rc2_cbc) @@ -1866,6 +1929,8 @@ #define FIPS_module_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, FIPS_module_name) #define FIPS_query_algorithm_status BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, FIPS_query_algorithm_status) #define FIPS_read_counter BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, FIPS_read_counter) +#define FIPS_service_indicator_after_call BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, FIPS_service_indicator_after_call) +#define FIPS_service_indicator_before_call BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, FIPS_service_indicator_before_call) #define FIPS_version BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, FIPS_version) #define gcm_ghash_avx BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, gcm_ghash_avx) #define gcm_ghash_clmul BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, gcm_ghash_clmul) @@ -2041,7 +2106,6 @@ #define i2d_X509_AUX BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_AUX) #define i2d_X509_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_bio) #define i2d_X509_CERT_AUX BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_CERT_AUX) -#define i2d_X509_CINF BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_CINF) #define i2d_X509_CRL BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_CRL) #define i2d_X509_CRL_bio BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_CRL_bio) #define i2d_X509_CRL_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_CRL_fp) @@ -2059,7 +2123,6 @@ #define i2d_X509_REVOKED BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_REVOKED) #define i2d_X509_SIG BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_SIG) #define i2d_X509_tbs BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_tbs) -#define i2d_X509_VAL BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2d_X509_VAL) #define i2o_ECPublicKey BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2o_ECPublicKey) #define i2s_ASN1_ENUMERATED BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2s_ASN1_ENUMERATED) #define i2s_ASN1_INTEGER BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, i2s_ASN1_INTEGER) @@ -2123,6 +2186,17 @@ #define MD5_Update BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MD5_Update) #define METHOD_ref BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, METHOD_ref) #define METHOD_unref BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, METHOD_unref) +#define MLDSA44_generate_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA44_generate_key) +#define MLDSA44_marshal_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA44_marshal_public_key) +#define MLDSA44_parse_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA44_parse_public_key) +#define MLDSA44_prehash_finalize BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA44_prehash_finalize) +#define MLDSA44_prehash_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA44_prehash_init) +#define MLDSA44_prehash_update BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA44_prehash_update) +#define MLDSA44_private_key_from_seed BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA44_private_key_from_seed) +#define MLDSA44_public_from_private BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA44_public_from_private) +#define MLDSA44_sign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA44_sign) +#define MLDSA44_sign_message_representative BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA44_sign_message_representative) +#define MLDSA44_verify BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA44_verify) #define MLDSA65_generate_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA65_generate_key) #define MLDSA65_marshal_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA65_marshal_public_key) #define MLDSA65_parse_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, MLDSA65_parse_public_key) @@ -2520,6 +2594,7 @@ #define rsa_invalidate_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_invalidate_key) #define RSA_is_opaque BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_is_opaque) #define RSA_marshal_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_marshal_private_key) +#define rsa_marshal_pss_params BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_marshal_pss_params) #define RSA_marshal_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_marshal_public_key) #define RSA_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_new) #define RSA_new_method BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_new_method) @@ -2537,6 +2612,7 @@ #define RSA_padding_check_PKCS1_OAEP_mgf1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_padding_check_PKCS1_OAEP_mgf1) #define RSA_padding_check_PKCS1_type_1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_padding_check_PKCS1_type_1) #define RSA_parse_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_parse_private_key) +#define rsa_parse_pss_params BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_parse_pss_params) #define RSA_parse_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_parse_public_key) #define rsa_pkey_meth BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_pkey_meth) #define RSA_print BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_print) @@ -2547,8 +2623,11 @@ #define rsa_private_transform BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_private_transform) #define rsa_private_transform_no_self_test BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_private_transform_no_self_test) #define RSA_PSS_PARAMS_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_PSS_PARAMS_free) +#define rsa_pss_params_get_md BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_pss_params_get_md) #define RSA_PSS_PARAMS_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_PSS_PARAMS_it) #define RSA_PSS_PARAMS_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_PSS_PARAMS_new) +#define rsa_pss_sha256_asn1_meth BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_pss_sha256_asn1_meth) +#define rsa_pss_sha256_pkey_meth BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, rsa_pss_sha256_pkey_meth) #define RSA_public_decrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_public_decrypt) #define RSA_public_encrypt BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_public_encrypt) #define RSA_public_key_from_bytes BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, RSA_public_key_from_bytes) @@ -2998,10 +3077,13 @@ #define X509_add1_ext_i2d BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_add1_ext_i2d) #define X509_add1_reject_object BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_add1_reject_object) #define X509_add1_trust_object BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_add1_trust_object) +#define x509_algor_cleanup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509_algor_cleanup) #define X509_ALGOR_cmp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ALGOR_cmp) +#define X509_ALGOR_copy BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ALGOR_copy) #define X509_ALGOR_dup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ALGOR_dup) #define X509_ALGOR_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ALGOR_free) #define X509_ALGOR_get0 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ALGOR_get0) +#define x509_algor_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509_algor_init) #define X509_ALGOR_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ALGOR_it) #define X509_ALGOR_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ALGOR_new) #define X509_ALGOR_set_md BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_ALGOR_set_md) @@ -3038,9 +3120,6 @@ #define X509_check_private_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_check_private_key) #define X509_check_purpose BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_check_purpose) #define X509_check_trust BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_check_trust) -#define X509_CINF_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CINF_free) -#define X509_CINF_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CINF_it) -#define X509_CINF_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_CINF_new) #define X509_cmp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_cmp) #define X509_cmp_current_time BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_cmp_current_time) #define X509_cmp_time BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_cmp_time) @@ -3176,6 +3255,8 @@ #define X509_LOOKUP_load_file BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_LOOKUP_load_file) #define x509_marshal_algorithm BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509_marshal_algorithm) #define x509_marshal_name BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509_marshal_name) +#define x509_marshal_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509_marshal_public_key) +#define x509_marshal_tbs_cert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509_marshal_tbs_cert) #define X509_NAME_add_entry BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_add_entry) #define X509_NAME_add_entry_by_NID BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_add_entry_by_NID) #define X509_NAME_add_entry_by_OBJ BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_NAME_add_entry_by_OBJ) @@ -3219,23 +3300,29 @@ #define X509_OBJECT_get_type BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_OBJECT_get_type) #define X509_OBJECT_get0_X509 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_OBJECT_get0_X509) #define X509_OBJECT_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_OBJECT_new) +#define x509_parse_algorithm BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509_parse_algorithm) #define X509_parse_from_buffer BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_parse_from_buffer) +#define x509_parse_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509_parse_public_key) +#define X509_parse_with_algorithms BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_parse_with_algorithms) #define X509_policy_check BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_policy_check) #define X509_print BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_print) #define X509_print_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_print_ex) #define X509_print_ex_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_print_ex_fp) #define X509_print_fp BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_print_fp) #define x509_print_rsa_pss_params BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509_print_rsa_pss_params) +#define x509_pubkey_cleanup BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509_pubkey_cleanup) #define X509_pubkey_digest BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_pubkey_digest) #define X509_PUBKEY_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PUBKEY_free) #define X509_PUBKEY_get BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PUBKEY_get) #define X509_PUBKEY_get0 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PUBKEY_get0) #define X509_PUBKEY_get0_param BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PUBKEY_get0_param) #define X509_PUBKEY_get0_public_key BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PUBKEY_get0_public_key) +#define x509_pubkey_init BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509_pubkey_init) #define X509_PUBKEY_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PUBKEY_it) #define X509_PUBKEY_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PUBKEY_new) #define X509_PUBKEY_set BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PUBKEY_set) #define X509_PUBKEY_set0_param BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PUBKEY_set0_param) +#define x509_pubkey_set1 BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509_pubkey_set1) #define X509_PURPOSE_get_by_sname BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PURPOSE_get_by_sname) #define X509_PURPOSE_get_id BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PURPOSE_get_id) #define X509_PURPOSE_get_trust BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_PURPOSE_get_trust) @@ -3319,6 +3406,7 @@ #define X509_SIG_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_SIG_new) #define X509_sign BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_sign) #define X509_sign_ctx BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_sign_ctx) +#define x509_sign_to_bit_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509_sign_to_bit_string) #define X509_signature_dump BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_signature_dump) #define X509_signature_print BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_signature_print) #define X509_STORE_add_cert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_STORE_add_cert) @@ -3383,9 +3471,6 @@ #define X509_time_adj_ex BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_time_adj_ex) #define X509_trust_clear BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_trust_clear) #define X509_up_ref BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_up_ref) -#define X509_VAL_free BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VAL_free) -#define X509_VAL_it BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VAL_it) -#define X509_VAL_new BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VAL_new) #define X509_verify BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_verify) #define X509_verify_cert BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_verify_cert) #define X509_verify_cert_error_string BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_verify_cert_error_string) @@ -3411,6 +3496,7 @@ #define X509_VERIFY_PARAM_set1_ip BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set1_ip) #define X509_VERIFY_PARAM_set1_ip_asc BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set1_ip_asc) #define X509_VERIFY_PARAM_set1_policies BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set1_policies) +#define x509_verify_signature BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509_verify_signature) #define x509v3_a2i_ipadd BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, x509v3_a2i_ipadd) #define X509v3_add_ext BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509v3_add_ext) #define X509V3_add_standard_extensions BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, X509V3_add_standard_extensions) @@ -4373,3 +4459,5 @@ #define lh_CRYPTO_BUFFER_call_doall_arg BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_CRYPTO_BUFFER_call_doall_arg) #define lh_CRYPTO_BUFFER_doall BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_CRYPTO_BUFFER_doall) #define lh_CRYPTO_BUFFER_doall_arg BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, lh_CRYPTO_BUFFER_doall_arg) +#define bignum_ctx BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, bignum_ctx) +#define evp_pkey_ctx_st BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, evp_pkey_ctx_st) diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols_asm.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols_asm.h index 8fc7f8451..b23a01e7c 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols_asm.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_boringssl_prefix_symbols_asm.h @@ -170,8 +170,12 @@ #define _ASN1_item_sign_ctx BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_item_sign_ctx) #define _ASN1_item_unpack BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_item_unpack) #define _ASN1_item_verify BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_item_verify) +#define _asn1_marshal_any BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_marshal_any) #define _asn1_marshal_bit_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_marshal_bit_string) #define _asn1_marshal_integer BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_marshal_integer) +#define _asn1_marshal_object BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_marshal_object) +#define _asn1_marshal_octet_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_marshal_octet_string) +#define _asn1_marshal_time BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_marshal_time) #define _ASN1_mbstring_copy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_mbstring_copy) #define _ASN1_mbstring_ncopy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_mbstring_ncopy) #define _ASN1_NULL_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_NULL_free) @@ -188,6 +192,20 @@ #define _ASN1_OCTET_STRING_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_OCTET_STRING_it) #define _ASN1_OCTET_STRING_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_OCTET_STRING_new) #define _ASN1_OCTET_STRING_set BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_OCTET_STRING_set) +#define _asn1_parse_any BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_parse_any) +#define _asn1_parse_any_as_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_parse_any_as_string) +#define _asn1_parse_bit_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_parse_bit_string) +#define _asn1_parse_bit_string_with_bad_length BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_parse_bit_string_with_bad_length) +#define _asn1_parse_bmp_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_parse_bmp_string) +#define _asn1_parse_enumerated BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_parse_enumerated) +#define _asn1_parse_generalized_time BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_parse_generalized_time) +#define _asn1_parse_integer BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_parse_integer) +#define _asn1_parse_object BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_parse_object) +#define _asn1_parse_octet_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_parse_octet_string) +#define _asn1_parse_time BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_parse_time) +#define _asn1_parse_universal_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_parse_universal_string) +#define _asn1_parse_utc_time BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_parse_utc_time) +#define _asn1_parse_utf8_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_parse_utf8_string) #define _ASN1_primitive_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_primitive_free) #define _ASN1_PRINTABLESTRING_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_PRINTABLESTRING_free) #define _ASN1_PRINTABLESTRING_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_PRINTABLESTRING_it) @@ -198,6 +216,7 @@ #define _asn1_refcount_set_one BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_refcount_set_one) #define _ASN1_SEQUENCE_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_SEQUENCE_it) #define _asn1_set_choice_selector BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_set_choice_selector) +#define _asn1_string_cleanup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_string_cleanup) #define _ASN1_STRING_cmp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_cmp) #define _ASN1_STRING_copy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_copy) #define _ASN1_STRING_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_data) @@ -205,6 +224,7 @@ #define _ASN1_STRING_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_free) #define _ASN1_STRING_get_default_mask BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_get_default_mask) #define _ASN1_STRING_get0_data BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_get0_data) +#define _asn1_string_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, asn1_string_init) #define _ASN1_STRING_length BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_length) #define _ASN1_STRING_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_new) #define _ASN1_STRING_print BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ASN1_STRING_print) @@ -285,6 +305,26 @@ #define _bcm_as_approved_status BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bcm_as_approved_status) #define _bcm_as_not_approved_status BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bcm_as_not_approved_status) #define _BCM_fips_186_2_prf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_fips_186_2_prf) +#define _BCM_mldsa44_check_key_fips BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_check_key_fips) +#define _BCM_mldsa44_generate_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_generate_key) +#define _BCM_mldsa44_generate_key_external_entropy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_generate_key_external_entropy) +#define _BCM_mldsa44_generate_key_external_entropy_fips BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_generate_key_external_entropy_fips) +#define _BCM_mldsa44_generate_key_fips BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_generate_key_fips) +#define _BCM_mldsa44_marshal_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_marshal_private_key) +#define _BCM_mldsa44_marshal_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_marshal_public_key) +#define _BCM_mldsa44_parse_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_parse_private_key) +#define _BCM_mldsa44_parse_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_parse_public_key) +#define _BCM_mldsa44_prehash_finalize BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_prehash_finalize) +#define _BCM_mldsa44_prehash_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_prehash_init) +#define _BCM_mldsa44_prehash_update BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_prehash_update) +#define _BCM_mldsa44_private_key_from_seed BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_private_key_from_seed) +#define _BCM_mldsa44_private_key_from_seed_fips BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_private_key_from_seed_fips) +#define _BCM_mldsa44_public_from_private BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_public_from_private) +#define _BCM_mldsa44_sign BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_sign) +#define _BCM_mldsa44_sign_internal BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_sign_internal) +#define _BCM_mldsa44_sign_message_representative BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_sign_message_representative) +#define _BCM_mldsa44_verify BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_verify) +#define _BCM_mldsa44_verify_internal BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa44_verify_internal) #define _BCM_mldsa65_check_key_fips BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa65_check_key_fips) #define _BCM_mldsa65_generate_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa65_generate_key) #define _BCM_mldsa65_generate_key_external_entropy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BCM_mldsa65_generate_key_external_entropy) @@ -635,9 +675,9 @@ #define _bn_mul_comba4 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mul_comba4) #define _bn_mul_comba8 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mul_comba8) #define _bn_mul_consttime BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mul_consttime) -#define _bn_mul_mont BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mul_mont) #define _bn_mul_mont_gather5_nohw BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mul_mont_gather5_nohw) #define _bn_mul_mont_nohw BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mul_mont_nohw) +#define _bn_mul_mont_words BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mul_mont_words) #define _bn_mul_small BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mul_small) #define _BN_mul_word BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, BN_mul_word) #define _bn_mul_words BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, bn_mul_words) @@ -885,6 +925,7 @@ #define _CMS_sign BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CMS_sign) #define _CONF_modules_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CONF_modules_free) #define _CONF_modules_load_file BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CONF_modules_load_file) +#define _CONF_modules_unload BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CONF_modules_unload) #define _CONF_parse_list BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CONF_parse_list) #define _CONF_VALUE_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CONF_VALUE_new) #define _CRL_DIST_POINTS_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CRL_DIST_POINTS_free) @@ -1019,7 +1060,9 @@ #define _CTR_DRBG_generate BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CTR_DRBG_generate) #define _CTR_DRBG_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CTR_DRBG_init) #define _CTR_DRBG_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CTR_DRBG_new) +#define _CTR_DRBG_new_df BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CTR_DRBG_new_df) #define _CTR_DRBG_reseed BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CTR_DRBG_reseed) +#define _CTR_DRBG_reseed_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, CTR_DRBG_reseed_ex) #define _d2i_ASN1_BIT_STRING BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ASN1_BIT_STRING) #define _d2i_ASN1_BMPSTRING BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ASN1_BMPSTRING) #define _d2i_ASN1_BOOLEAN BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_ASN1_BOOLEAN) @@ -1110,7 +1153,6 @@ #define _d2i_X509_AUX BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_AUX) #define _d2i_X509_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_bio) #define _d2i_X509_CERT_AUX BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_CERT_AUX) -#define _d2i_X509_CINF BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_CINF) #define _d2i_X509_CRL BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_CRL) #define _d2i_X509_CRL_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_CRL_bio) #define _d2i_X509_CRL_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_CRL_fp) @@ -1126,7 +1168,6 @@ #define _d2i_X509_REQ_INFO BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_REQ_INFO) #define _d2i_X509_REVOKED BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_REVOKED) #define _d2i_X509_SIG BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_SIG) -#define _d2i_X509_VAL BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, d2i_X509_VAL) #define _DES_decrypt3 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DES_decrypt3) #define _DES_ecb_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DES_ecb_encrypt) #define _DES_ecb_encrypt_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, DES_ecb_encrypt_ex) @@ -1334,8 +1375,11 @@ #define _EC_KEY_new_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_new_method) #define _EC_KEY_oct2key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_oct2key) #define _EC_KEY_oct2priv BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_oct2priv) +#define _ec_key_parse_curve_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_key_parse_curve_name) #define _EC_KEY_parse_curve_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_parse_curve_name) +#define _ec_key_parse_parameters BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_key_parse_parameters) #define _EC_KEY_parse_parameters BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_parse_parameters) +#define _ec_key_parse_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ec_key_parse_private_key) #define _EC_KEY_parse_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_parse_private_key) #define _EC_KEY_priv2buf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_priv2buf) #define _EC_KEY_priv2oct BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EC_KEY_priv2oct) @@ -1470,6 +1514,7 @@ #define _ED25519_verify BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ED25519_verify) #define _EDIPARTYNAME_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EDIPARTYNAME_free) #define _EDIPARTYNAME_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EDIPARTYNAME_new) +#define _ENGINE_cleanup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ENGINE_cleanup) #define _ENGINE_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ENGINE_free) #define _ENGINE_get_ECDSA_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ENGINE_get_ECDSA_method) #define _ENGINE_get_RSA_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ENGINE_get_RSA_method) @@ -1482,6 +1527,7 @@ #define _ERR_add_error_dataf BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_add_error_dataf) #define _ERR_clear_error BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_clear_error) #define _ERR_clear_system_error BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_clear_system_error) +#define _ERR_equals BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_equals) #define _ERR_error_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_error_string) #define _ERR_error_string_n BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_error_string_n) #define _ERR_free_strings BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, ERR_free_strings) @@ -1708,6 +1754,7 @@ #define _EVP_HPKE_KEY_zero BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_HPKE_KEY_zero) #define _EVP_hpke_p256_hkdf_sha256 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_hpke_p256_hkdf_sha256) #define _EVP_hpke_x25519_hkdf_sha256 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_hpke_x25519_hkdf_sha256) +#define _EVP_hpke_xwing BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_hpke_xwing) #define _EVP_marshal_digest_algorithm BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_marshal_digest_algorithm) #define _EVP_marshal_digest_algorithm_no_params BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_marshal_digest_algorithm_no_params) #define _EVP_marshal_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_marshal_private_key) @@ -1739,6 +1786,7 @@ #define _EVP_md5 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_md5) #define _EVP_md5_sha1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_md5_sha1) #define _EVP_parse_digest_algorithm BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_parse_digest_algorithm) +#define _EVP_parse_digest_algorithm_nid BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_parse_digest_algorithm_nid) #define _EVP_parse_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_parse_private_key) #define _EVP_parse_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_parse_public_key) #define _EVP_PBE_scrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PBE_scrypt) @@ -1791,9 +1839,21 @@ #define _EVP_PKEY_derive BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_derive) #define _EVP_PKEY_derive_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_derive_init) #define _EVP_PKEY_derive_set_peer BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_derive_set_peer) +#define _EVP_pkey_dsa BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_pkey_dsa) +#define _EVP_pkey_ec_p224 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_pkey_ec_p224) +#define _EVP_pkey_ec_p256 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_pkey_ec_p256) +#define _EVP_pkey_ec_p384 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_pkey_ec_p384) +#define _EVP_pkey_ec_p521 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_pkey_ec_p521) +#define _EVP_pkey_ed25519 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_pkey_ed25519) #define _EVP_PKEY_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_encrypt) #define _EVP_PKEY_encrypt_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_encrypt_init) #define _EVP_PKEY_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_free) +#define _EVP_PKEY_from_private_key_info BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_from_private_key_info) +#define _EVP_PKEY_from_raw_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_from_raw_private_key) +#define _EVP_PKEY_from_raw_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_from_raw_public_key) +#define _EVP_PKEY_from_subject_public_key_info BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_from_subject_public_key_info) +#define _EVP_PKEY_get_ec_curve_nid BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_get_ec_curve_nid) +#define _EVP_PKEY_get_ec_point_conv_form BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_get_ec_point_conv_form) #define _EVP_PKEY_get_raw_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_get_raw_private_key) #define _EVP_PKEY_get_raw_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_get_raw_public_key) #define _EVP_PKEY_get0 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_get0) @@ -1819,8 +1879,10 @@ #define _EVP_PKEY_print_params BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_print_params) #define _EVP_PKEY_print_private BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_print_private) #define _EVP_PKEY_print_public BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_print_public) -#define _evp_pkey_set_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, evp_pkey_set_method) +#define _EVP_pkey_rsa BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_pkey_rsa) +#define _EVP_pkey_rsa_pss_sha256 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_pkey_rsa_pss_sha256) #define _EVP_PKEY_set_type BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_set_type) +#define _evp_pkey_set0 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, evp_pkey_set0) #define _EVP_PKEY_set1_DH BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_set1_DH) #define _EVP_PKEY_set1_DSA BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_set1_DSA) #define _EVP_PKEY_set1_EC_KEY BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_set1_EC_KEY) @@ -1835,6 +1897,7 @@ #define _EVP_PKEY_verify_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_verify_init) #define _EVP_PKEY_verify_recover BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_verify_recover) #define _EVP_PKEY_verify_recover_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY_verify_recover_init) +#define _EVP_pkey_x25519 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_pkey_x25519) #define _EVP_PKEY2PKCS8 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_PKEY2PKCS8) #define _EVP_rc2_40_cbc BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_rc2_40_cbc) #define _EVP_rc2_cbc BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, EVP_rc2_cbc) @@ -1871,6 +1934,8 @@ #define _FIPS_module_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, FIPS_module_name) #define _FIPS_query_algorithm_status BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, FIPS_query_algorithm_status) #define _FIPS_read_counter BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, FIPS_read_counter) +#define _FIPS_service_indicator_after_call BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, FIPS_service_indicator_after_call) +#define _FIPS_service_indicator_before_call BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, FIPS_service_indicator_before_call) #define _FIPS_version BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, FIPS_version) #define _gcm_ghash_avx BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, gcm_ghash_avx) #define _gcm_ghash_clmul BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, gcm_ghash_clmul) @@ -2046,7 +2111,6 @@ #define _i2d_X509_AUX BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_AUX) #define _i2d_X509_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_bio) #define _i2d_X509_CERT_AUX BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_CERT_AUX) -#define _i2d_X509_CINF BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_CINF) #define _i2d_X509_CRL BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_CRL) #define _i2d_X509_CRL_bio BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_CRL_bio) #define _i2d_X509_CRL_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_CRL_fp) @@ -2064,7 +2128,6 @@ #define _i2d_X509_REVOKED BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_REVOKED) #define _i2d_X509_SIG BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_SIG) #define _i2d_X509_tbs BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_tbs) -#define _i2d_X509_VAL BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2d_X509_VAL) #define _i2o_ECPublicKey BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2o_ECPublicKey) #define _i2s_ASN1_ENUMERATED BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2s_ASN1_ENUMERATED) #define _i2s_ASN1_INTEGER BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, i2s_ASN1_INTEGER) @@ -2128,6 +2191,17 @@ #define _MD5_Update BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MD5_Update) #define _METHOD_ref BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, METHOD_ref) #define _METHOD_unref BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, METHOD_unref) +#define _MLDSA44_generate_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MLDSA44_generate_key) +#define _MLDSA44_marshal_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MLDSA44_marshal_public_key) +#define _MLDSA44_parse_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MLDSA44_parse_public_key) +#define _MLDSA44_prehash_finalize BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MLDSA44_prehash_finalize) +#define _MLDSA44_prehash_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MLDSA44_prehash_init) +#define _MLDSA44_prehash_update BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MLDSA44_prehash_update) +#define _MLDSA44_private_key_from_seed BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MLDSA44_private_key_from_seed) +#define _MLDSA44_public_from_private BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MLDSA44_public_from_private) +#define _MLDSA44_sign BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MLDSA44_sign) +#define _MLDSA44_sign_message_representative BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MLDSA44_sign_message_representative) +#define _MLDSA44_verify BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MLDSA44_verify) #define _MLDSA65_generate_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MLDSA65_generate_key) #define _MLDSA65_marshal_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MLDSA65_marshal_public_key) #define _MLDSA65_parse_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, MLDSA65_parse_public_key) @@ -2525,6 +2599,7 @@ #define _rsa_invalidate_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_invalidate_key) #define _RSA_is_opaque BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_is_opaque) #define _RSA_marshal_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_marshal_private_key) +#define _rsa_marshal_pss_params BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_marshal_pss_params) #define _RSA_marshal_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_marshal_public_key) #define _RSA_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_new) #define _RSA_new_method BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_new_method) @@ -2542,6 +2617,7 @@ #define _RSA_padding_check_PKCS1_OAEP_mgf1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_padding_check_PKCS1_OAEP_mgf1) #define _RSA_padding_check_PKCS1_type_1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_padding_check_PKCS1_type_1) #define _RSA_parse_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_parse_private_key) +#define _rsa_parse_pss_params BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_parse_pss_params) #define _RSA_parse_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_parse_public_key) #define _rsa_pkey_meth BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_pkey_meth) #define _RSA_print BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_print) @@ -2552,8 +2628,11 @@ #define _rsa_private_transform BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_private_transform) #define _rsa_private_transform_no_self_test BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_private_transform_no_self_test) #define _RSA_PSS_PARAMS_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_PSS_PARAMS_free) +#define _rsa_pss_params_get_md BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_pss_params_get_md) #define _RSA_PSS_PARAMS_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_PSS_PARAMS_it) #define _RSA_PSS_PARAMS_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_PSS_PARAMS_new) +#define _rsa_pss_sha256_asn1_meth BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_pss_sha256_asn1_meth) +#define _rsa_pss_sha256_pkey_meth BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, rsa_pss_sha256_pkey_meth) #define _RSA_public_decrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_public_decrypt) #define _RSA_public_encrypt BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_public_encrypt) #define _RSA_public_key_from_bytes BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, RSA_public_key_from_bytes) @@ -3003,10 +3082,13 @@ #define _X509_add1_ext_i2d BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_add1_ext_i2d) #define _X509_add1_reject_object BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_add1_reject_object) #define _X509_add1_trust_object BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_add1_trust_object) +#define _x509_algor_cleanup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509_algor_cleanup) #define _X509_ALGOR_cmp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ALGOR_cmp) +#define _X509_ALGOR_copy BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ALGOR_copy) #define _X509_ALGOR_dup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ALGOR_dup) #define _X509_ALGOR_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ALGOR_free) #define _X509_ALGOR_get0 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ALGOR_get0) +#define _x509_algor_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509_algor_init) #define _X509_ALGOR_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ALGOR_it) #define _X509_ALGOR_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ALGOR_new) #define _X509_ALGOR_set_md BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_ALGOR_set_md) @@ -3043,9 +3125,6 @@ #define _X509_check_private_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_check_private_key) #define _X509_check_purpose BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_check_purpose) #define _X509_check_trust BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_check_trust) -#define _X509_CINF_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CINF_free) -#define _X509_CINF_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CINF_it) -#define _X509_CINF_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_CINF_new) #define _X509_cmp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_cmp) #define _X509_cmp_current_time BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_cmp_current_time) #define _X509_cmp_time BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_cmp_time) @@ -3181,6 +3260,8 @@ #define _X509_LOOKUP_load_file BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_LOOKUP_load_file) #define _x509_marshal_algorithm BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509_marshal_algorithm) #define _x509_marshal_name BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509_marshal_name) +#define _x509_marshal_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509_marshal_public_key) +#define _x509_marshal_tbs_cert BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509_marshal_tbs_cert) #define _X509_NAME_add_entry BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_add_entry) #define _X509_NAME_add_entry_by_NID BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_add_entry_by_NID) #define _X509_NAME_add_entry_by_OBJ BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_NAME_add_entry_by_OBJ) @@ -3224,23 +3305,29 @@ #define _X509_OBJECT_get_type BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_OBJECT_get_type) #define _X509_OBJECT_get0_X509 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_OBJECT_get0_X509) #define _X509_OBJECT_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_OBJECT_new) +#define _x509_parse_algorithm BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509_parse_algorithm) #define _X509_parse_from_buffer BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_parse_from_buffer) +#define _x509_parse_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509_parse_public_key) +#define _X509_parse_with_algorithms BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_parse_with_algorithms) #define _X509_policy_check BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_policy_check) #define _X509_print BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_print) #define _X509_print_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_print_ex) #define _X509_print_ex_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_print_ex_fp) #define _X509_print_fp BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_print_fp) #define _x509_print_rsa_pss_params BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509_print_rsa_pss_params) +#define _x509_pubkey_cleanup BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509_pubkey_cleanup) #define _X509_pubkey_digest BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_pubkey_digest) #define _X509_PUBKEY_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PUBKEY_free) #define _X509_PUBKEY_get BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PUBKEY_get) #define _X509_PUBKEY_get0 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PUBKEY_get0) #define _X509_PUBKEY_get0_param BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PUBKEY_get0_param) #define _X509_PUBKEY_get0_public_key BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PUBKEY_get0_public_key) +#define _x509_pubkey_init BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509_pubkey_init) #define _X509_PUBKEY_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PUBKEY_it) #define _X509_PUBKEY_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PUBKEY_new) #define _X509_PUBKEY_set BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PUBKEY_set) #define _X509_PUBKEY_set0_param BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PUBKEY_set0_param) +#define _x509_pubkey_set1 BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509_pubkey_set1) #define _X509_PURPOSE_get_by_sname BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PURPOSE_get_by_sname) #define _X509_PURPOSE_get_id BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PURPOSE_get_id) #define _X509_PURPOSE_get_trust BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_PURPOSE_get_trust) @@ -3324,6 +3411,7 @@ #define _X509_SIG_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_SIG_new) #define _X509_sign BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_sign) #define _X509_sign_ctx BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_sign_ctx) +#define _x509_sign_to_bit_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509_sign_to_bit_string) #define _X509_signature_dump BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_signature_dump) #define _X509_signature_print BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_signature_print) #define _X509_STORE_add_cert BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_STORE_add_cert) @@ -3388,9 +3476,6 @@ #define _X509_time_adj_ex BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_time_adj_ex) #define _X509_trust_clear BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_trust_clear) #define _X509_up_ref BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_up_ref) -#define _X509_VAL_free BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VAL_free) -#define _X509_VAL_it BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VAL_it) -#define _X509_VAL_new BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VAL_new) #define _X509_verify BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_verify) #define _X509_verify_cert BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_verify_cert) #define _X509_verify_cert_error_string BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_verify_cert_error_string) @@ -3416,6 +3501,7 @@ #define _X509_VERIFY_PARAM_set1_ip BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set1_ip) #define _X509_VERIFY_PARAM_set1_ip_asc BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set1_ip_asc) #define _X509_VERIFY_PARAM_set1_policies BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509_VERIFY_PARAM_set1_policies) +#define _x509_verify_signature BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509_verify_signature) #define _x509v3_a2i_ipadd BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, x509v3_a2i_ipadd) #define _X509v3_add_ext BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509v3_add_ext) #define _X509V3_add_standard_extensions BORINGSSL_ADD_PREFIX_MAC_ASM(BORINGSSL_PREFIX, X509V3_add_standard_extensions) diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_conf.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_conf.h index 3be4e1de6..c5f0af94f 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_conf.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_conf.h @@ -96,6 +96,9 @@ OPENSSL_EXPORT int CONF_modules_load_file(const char *filename, const char *appname, unsigned long flags); +// CONF_modules_unload does nothing. +OPENSSL_EXPORT void CONF_modules_unload(int all); + // CONF_modules_free does nothing. OPENSSL_EXPORT void CONF_modules_free(void); diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_crypto.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_crypto.h index 81a8a8a3c..f7931bd35 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_crypto.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_crypto.h @@ -15,7 +15,7 @@ #ifndef OPENSSL_HEADER_CRYPTO_H #define OPENSSL_HEADER_CRYPTO_H -#include "CCryptoBoringSSL_base.h" // IWYU pragma: export +#include "CCryptoBoringSSL_base.h" // IWYU pragma: export #include "CCryptoBoringSSL_sha.h" // Upstream OpenSSL defines |OPENSSL_malloc|, etc., in crypto.h rather than @@ -162,6 +162,9 @@ OPENSSL_EXPORT void ENGINE_load_builtin_engines(void); // ENGINE_register_all_complete returns one. OPENSSL_EXPORT int ENGINE_register_all_complete(void); +// ENGINE_cleanup does nothing. +OPENSSL_EXPORT void ENGINE_cleanup(void); + // OPENSSL_load_builtin_modules does nothing. OPENSSL_EXPORT void OPENSSL_load_builtin_modules(void); @@ -205,8 +208,7 @@ OPENSSL_EXPORT const uint8_t *FIPS_module_hash(void); // FIPS_version returns the version of the FIPS module, or zero if the build // isn't exactly at a verified version. The version, expressed in base 10, will -// be a date in the form yyyymmddXX where XX is often "00", but can be -// incremented if multiple versions are defined on a single day. +// be a date in the form yyyymmdd. // // (This format exceeds a |uint32_t| in the year 4294.) OPENSSL_EXPORT uint32_t FIPS_version(void); diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_ctrdrbg.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_ctrdrbg.h index fb3336d69..8aa56a983 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_ctrdrbg.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_ctrdrbg.h @@ -15,7 +15,7 @@ #ifndef OPENSSL_HEADER_CTRDRBG_H #define OPENSSL_HEADER_CTRDRBG_H -#include "CCryptoBoringSSL_base.h" // IWYU pragma: export +#include "CCryptoBoringSSL_base.h" // IWYU pragma: export #if defined(__cplusplus) extern "C" { @@ -29,33 +29,67 @@ extern "C" { // // CTR_DRBG_STATE contains the state of a FIPS AES-CTR-based pseudo-random // number generator. If BoringSSL was built in FIPS mode then this is a FIPS -// Approved algorithm. +// Approved algorithm. BoringSSL supports CTR-DRBG both with, and without, a +// derivation function. -// CTR_DRBG_ENTROPY_LEN is the number of bytes of input entropy. See SP -// 800-90Ar1, table 3. +// CTR_DRBG_MIN_ENTROPY_LEN is the minimum number of bytes of input entropy +// when using a derivation function. See SP 800-90Ar1, table 3. +#define CTR_DRBG_MIN_ENTROPY_LEN 32 + +// CTR_DRBG_MAX_ENTROPY_LEN is the maximum number of bytes of input entropy +// when using a derivation function. This is an implementation limitation. +#define CTR_DRBG_MAX_ENTROPY_LEN 64 + +// CTR_DRBG_ENTROPY_LEN is a fixed amount of entropy required when not using a +// derivation function. #define CTR_DRBG_ENTROPY_LEN 48 +// The length of a seed, when using a derivation function. See SP 800-90Ar1, +// table 3. +#define CTR_DRBG_SEED_LEN (32 + CTR_DRBG_NONCE_LEN) + +// CTR_DRBG_NONCE_LEN is the number of bytes of input nonce. This only applies +// when using a derivation function. +#define CTR_DRBG_NONCE_LEN 16 + // CTR_DRBG_MAX_GENERATE_LENGTH is the maximum number of bytes that can be // generated in a single call to |CTR_DRBG_generate|. #define CTR_DRBG_MAX_GENERATE_LENGTH 65536 // CTR_DRBG_new returns an initialized |CTR_DRBG_STATE|, or NULL if either -// allocation failed or if |personalization_len| is invalid. +// allocation failed or if |personalization_len| is invalid. This DRBG will not +// use a derivation function. OPENSSL_EXPORT CTR_DRBG_STATE *CTR_DRBG_new( const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], const uint8_t *personalization, size_t personalization_len); +// CTR_DRBG_new_df returns an initialized |CTR_DRBG_STATE|, or NULL if either +// allocation failed or if an argument is invalid. This DRBG will use a +// derivation function. +OPENSSL_EXPORT CTR_DRBG_STATE *CTR_DRBG_new_df( + const uint8_t *entropy, size_t entropy_len, + const uint8_t nonce[CTR_DRBG_NONCE_LEN], const uint8_t *personalization, + size_t personalization_len); + // CTR_DRBG_free frees |state| if non-NULL, or else does nothing. -OPENSSL_EXPORT void CTR_DRBG_free(CTR_DRBG_STATE* state); +OPENSSL_EXPORT void CTR_DRBG_free(CTR_DRBG_STATE *state); // CTR_DRBG_reseed reseeds |drbg| given |CTR_DRBG_ENTROPY_LEN| bytes of entropy -// in |entropy| and, optionally, up to |CTR_DRBG_ENTROPY_LEN| bytes of +// in |entropy| and, optionally, up to |CTR_DRBG_SEED_LEN| bytes of // additional data. It returns one on success or zero on error. OPENSSL_EXPORT int CTR_DRBG_reseed(CTR_DRBG_STATE *drbg, const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], const uint8_t *additional_data, size_t additional_data_len); +// CTR_DRBG_reseed_ex acts like `CTR_DRBG_reseed` but with variable-length +// entropy input, up to |CTR_DRBG_MAX_ENTROPY_LEN|. +OPENSSL_EXPORT int CTR_DRBG_reseed_ex(CTR_DRBG_STATE *drbg, + const uint8_t *entropy, + size_t entropy_len, + const uint8_t *additional_data, + size_t additional_data_len); + // CTR_DRBG_generate processes to up |CTR_DRBG_ENTROPY_LEN| bytes of additional // data (if any) and then writes |out_len| random bytes to |out|, where // |out_len| <= |CTR_DRBG_MAX_GENERATE_LENGTH|. It returns one on success or diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_dh.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_dh.h index f7db3d8e9..ce6057ed6 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_dh.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_dh.h @@ -54,7 +54,7 @@ OPENSSL_EXPORT int DH_up_ref(DH *dh); // OPENSSL_DH_MAX_MODULUS_BITS is the maximum supported Diffie-Hellman group // modulus, in bits. -#define OPENSSL_DH_MAX_MODULUS_BITS 10000 +#define OPENSSL_DH_MAX_MODULUS_BITS 8192 // DH_bits returns the size of |dh|'s group modulus, in bits. OPENSSL_EXPORT unsigned DH_bits(const DH *dh); @@ -111,32 +111,38 @@ OPENSSL_EXPORT DH *DH_get_rfc7919_2048(void); // BN_get_rfc3526_prime_1536 sets |*ret| to the 1536-bit MODP group from RFC // 3526 and returns |ret|. If |ret| is NULL then a fresh |BIGNUM| is allocated -// and returned. It returns NULL on allocation failure. +// and returned. It returns NULL on allocation failure. The generator for this +// group is 2. OPENSSL_EXPORT BIGNUM *BN_get_rfc3526_prime_1536(BIGNUM *ret); // BN_get_rfc3526_prime_2048 sets |*ret| to the 2048-bit MODP group from RFC // 3526 and returns |ret|. If |ret| is NULL then a fresh |BIGNUM| is allocated -// and returned. It returns NULL on allocation failure. +// and returned. It returns NULL on allocation failure. The generator for this +// group is 2. OPENSSL_EXPORT BIGNUM *BN_get_rfc3526_prime_2048(BIGNUM *ret); // BN_get_rfc3526_prime_3072 sets |*ret| to the 3072-bit MODP group from RFC // 3526 and returns |ret|. If |ret| is NULL then a fresh |BIGNUM| is allocated -// and returned. It returns NULL on allocation failure. +// and returned. It returns NULL on allocation failure. The generator for this +// group is 2. OPENSSL_EXPORT BIGNUM *BN_get_rfc3526_prime_3072(BIGNUM *ret); // BN_get_rfc3526_prime_4096 sets |*ret| to the 4096-bit MODP group from RFC // 3526 and returns |ret|. If |ret| is NULL then a fresh |BIGNUM| is allocated -// and returned. It returns NULL on allocation failure. +// and returned. It returns NULL on allocation failure. The generator for this +// group is 2. OPENSSL_EXPORT BIGNUM *BN_get_rfc3526_prime_4096(BIGNUM *ret); // BN_get_rfc3526_prime_6144 sets |*ret| to the 6144-bit MODP group from RFC // 3526 and returns |ret|. If |ret| is NULL then a fresh |BIGNUM| is allocated -// and returned. It returns NULL on allocation failure. +// and returned. It returns NULL on allocation failure. The generator for this +// group is 2. OPENSSL_EXPORT BIGNUM *BN_get_rfc3526_prime_6144(BIGNUM *ret); // BN_get_rfc3526_prime_8192 sets |*ret| to the 8192-bit MODP group from RFC // 3526 and returns |ret|. If |ret| is NULL then a fresh |BIGNUM| is allocated -// and returned. It returns NULL on allocation failure. +// and returned. It returns NULL on allocation failure. The generator for this +// group is 2. OPENSSL_EXPORT BIGNUM *BN_get_rfc3526_prime_8192(BIGNUM *ret); diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_digest.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_digest.h index 7fb79e1a6..179f92a7d 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_digest.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_digest.h @@ -213,6 +213,11 @@ OPENSSL_EXPORT int EVP_MD_CTX_type(const EVP_MD_CTX *ctx); // returns the digest function or NULL on error. OPENSSL_EXPORT const EVP_MD *EVP_parse_digest_algorithm(CBS *cbs); +// EVP_parse_digest_algorithm_nid behaves like |EVP_parse_digest_algorithm| +// except it returns |NID_undef| on error and some other value on success. This +// may be used to avoid depending on every digest algorithm in the library. +OPENSSL_EXPORT int EVP_parse_digest_algorithm_nid(CBS *cbs); + // EVP_marshal_digest_algorithm marshals |md| as an AlgorithmIdentifier // structure and appends the result to |cbb|. It returns one on success and zero // on error. It sets the parameters field to NULL. Use @@ -283,17 +288,27 @@ OPENSSL_EXPORT void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags); OPENSSL_EXPORT int EVP_MD_nid(const EVP_MD *md); +// Internal constants and structures (hidden). + struct evp_md_pctx_ops; +// EVP_MAX_MD_DATA_SIZE is a private constant which specifies the size of the +// largest digest state. SHA-512 and BLAKE2b are joint-largest. Consuming code +// only uses this via the `EVP_MD_CTX` type. +#define EVP_MAX_MD_DATA_SIZE 208 + // env_md_ctx_st is typoed ("evp" -> "env"), but the typo comes from OpenSSL // and some consumers forward-declare these structures so we're leaving it // alone. struct env_md_ctx_st { + // md_data contains the hash-specific context. + union { + uint8_t md_data[EVP_MAX_MD_DATA_SIZE]; + uint64_t alignment; + }; + // digest is the underlying digest function, or NULL if not set. const EVP_MD *digest; - // md_data points to a block of memory that contains the hash-specific - // context. - void *md_data; // pctx is an opaque (at this layer) pointer to additional context that // EVP_PKEY functions may store in this object. diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_dsa.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_dsa.h index e7e0e3b7a..07c716975 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_dsa.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_dsa.h @@ -56,7 +56,7 @@ OPENSSL_EXPORT int DSA_up_ref(DSA *dsa); // OPENSSL_DSA_MAX_MODULUS_BITS is the maximum supported DSA group modulus, in // bits. -#define OPENSSL_DSA_MAX_MODULUS_BITS 10000 +#define OPENSSL_DSA_MAX_MODULUS_BITS 8192 // DSA_bits returns the size of |dsa|'s group modulus, in bits. OPENSSL_EXPORT unsigned DSA_bits(const DSA *dsa); diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_ec.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_ec.h index e1f997101..e43aefd97 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_ec.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_ec.h @@ -107,8 +107,8 @@ OPENSSL_EXPORT const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group); // EC_GROUP_order_bits returns the number of bits of the order of |group|. OPENSSL_EXPORT int EC_GROUP_order_bits(const EC_GROUP *group); -// EC_GROUP_get_cofactor sets |*cofactor| to the cofactor of |group| using -// |ctx|, if it's not NULL. It returns one on success and zero otherwise. +// EC_GROUP_get_cofactor sets |*cofactor| to the cofactor of |group|. It returns +// one on success and zero otherwise. |ctx| is ignored and may be NULL. OPENSSL_EXPORT int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, BN_CTX *ctx); @@ -116,7 +116,7 @@ OPENSSL_EXPORT int EC_GROUP_get_cofactor(const EC_GROUP *group, // |*out_p| to the order of the coordinate field and |*out_a| and |*out_b| to // the parameters of the curve when expressed as y² = x³ + ax + b. Any of the // output parameters can be NULL. It returns one on success and zero on -// error. +// error. |ctx| is ignored and may be NULL. OPENSSL_EXPORT int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *out_p, BIGNUM *out_a, BIGNUM *out_b, BN_CTX *ctx); @@ -169,12 +169,12 @@ OPENSSL_EXPORT int EC_POINT_is_at_infinity(const EC_GROUP *group, // EC_POINT_is_on_curve returns one if |point| is an element of |group| and // and zero otherwise or when an error occurs. This is different from OpenSSL, -// which returns -1 on error. If |ctx| is non-NULL, it may be used. +// which returns -1 on error. |ctx| is ignored and may be NULL. OPENSSL_EXPORT int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx); // EC_POINT_cmp returns zero if |a| is equal to |b|, greater than zero if -// not equal and -1 on error. If |ctx| is not NULL, it may be used. +// not equal and -1 on error. |ctx| is ignored and may be NULL. OPENSSL_EXPORT int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx); @@ -182,8 +182,8 @@ OPENSSL_EXPORT int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, // Point conversion. // EC_POINT_get_affine_coordinates_GFp sets |x| and |y| to the affine value of -// |point| using |ctx|, if it's not NULL. It returns one on success and zero -// otherwise. +// |point|. It returns one on success and zero otherwise. |ctx| is ignored and +// may be NULL. // // Either |x| or |y| may be NULL to skip computing that coordinate. This is // slightly faster in the common case where only the x-coordinate is needed. @@ -200,9 +200,8 @@ OPENSSL_EXPORT int EC_POINT_get_affine_coordinates(const EC_GROUP *group, BN_CTX *ctx); // EC_POINT_set_affine_coordinates_GFp sets the value of |point| to be -// (|x|, |y|). The |ctx| argument may be used if not NULL. It returns one -// on success or zero on error. It's considered an error if the point is not on -// the curve. +// (|x|, |y|). |ctx| is ignored and may be NULL. It returns one on success or +// zero on error. It's considered an error if the point is not on the curve. // // Note that the corresponding function in OpenSSL versions prior to 1.0.2s does // not check if the point is on the curve. This is a security-critical check, so @@ -226,7 +225,7 @@ OPENSSL_EXPORT int EC_POINT_set_affine_coordinates(const EC_GROUP *group, // EC_POINT_point2oct serialises |point| into the X9.62 form given by |form| // into, at most, |max_out| bytes at |buf|. It returns the number of bytes // written or zero on error if |buf| is non-NULL, else the number of bytes -// needed. The |ctx| argument may be used if not NULL. +// needed. |ctx| is ignored and may be NULL. OPENSSL_EXPORT size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form, @@ -236,30 +235,31 @@ OPENSSL_EXPORT size_t EC_POINT_point2oct(const EC_GROUP *group, // EC_POINT_point2buf serialises |point| into the X9.62 form given by |form| to // a newly-allocated buffer and sets |*out_buf| to point to it. It returns the // length of the result on success or zero on error. The caller must release -// |*out_buf| with |OPENSSL_free| when done. +// |*out_buf| with |OPENSSL_free| when done. |ctx| is ignored and may be NULL. OPENSSL_EXPORT size_t EC_POINT_point2buf(const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form, uint8_t **out_buf, BN_CTX *ctx); // EC_POINT_point2cbb behaves like |EC_POINT_point2oct| but appends the -// serialised point to |cbb|. It returns one on success and zero on error. +// serialised point to |cbb|. It returns one on success and zero on error. |ctx| +// is ignored and may be NULL. OPENSSL_EXPORT int EC_POINT_point2cbb(CBB *out, const EC_GROUP *group, const EC_POINT *point, point_conversion_form_t form, BN_CTX *ctx); // EC_POINT_oct2point sets |point| from |len| bytes of X9.62 format -// serialisation in |buf|. It returns one on success and zero on error. The -// |ctx| argument may be used if not NULL. It's considered an error if |buf| -// does not represent a point on the curve. +// serialisation in |buf|. It returns one on success and zero on error. |ctx| +// may be NULL. It's considered an error if |buf| does not represent a point on +// the curve. OPENSSL_EXPORT int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point, const uint8_t *buf, size_t len, BN_CTX *ctx); // EC_POINT_set_compressed_coordinates_GFp sets |point| to equal the point with // the given |x| coordinate and the y coordinate specified by |y_bit| (see -// X9.62). It returns one on success and zero otherwise. +// X9.62). It returns one on success and zero otherwise. |ctx| may be NULL. OPENSSL_EXPORT int EC_POINT_set_compressed_coordinates_GFp( const EC_GROUP *group, EC_POINT *point, const BIGNUM *x, int y_bit, BN_CTX *ctx); @@ -268,23 +268,23 @@ OPENSSL_EXPORT int EC_POINT_set_compressed_coordinates_GFp( // Group operations. // EC_POINT_add sets |r| equal to |a| plus |b|. It returns one on success and -// zero otherwise. If |ctx| is not NULL, it may be used. +// zero otherwise. |ctx| is ignored and may be NULL. OPENSSL_EXPORT int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, const EC_POINT *b, BN_CTX *ctx); // EC_POINT_dbl sets |r| equal to |a| plus |a|. It returns one on success and -// zero otherwise. If |ctx| is not NULL, it may be used. +// zero otherwise. |ctx| is ignored and may be NULL. OPENSSL_EXPORT int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, BN_CTX *ctx); // EC_POINT_invert sets |a| equal to minus |a|. It returns one on success and -// zero otherwise. If |ctx| is not NULL, it may be used. +// zero otherwise. |ctx| is ignored and may be NULL. OPENSSL_EXPORT int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx); // EC_POINT_mul sets r = generator*n + q*m. It returns one on success and zero -// otherwise. If |ctx| is not NULL, it may be used. +// otherwise. |ctx| may be NULL. OPENSSL_EXPORT int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx); @@ -368,8 +368,8 @@ OPENSSL_EXPORT int EC_GROUP_set_generator(EC_GROUP *group, const BIGNUM *cofactor); // EC_GROUP_get_order sets |*order| to the order of |group|, if it's not -// NULL. It returns one on success and zero otherwise. |ctx| is ignored. Use -// |EC_GROUP_get0_order| instead. +// NULL. It returns one on success and zero otherwise. |ctx| is ignored and may +// be NULL. Use |EC_GROUP_get0_order| instead. OPENSSL_EXPORT int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx); diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_ec_key.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_ec_key.h index 8dc963143..45a1c2216 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_ec_key.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_ec_key.h @@ -130,12 +130,12 @@ OPENSSL_EXPORT int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, // EC_KEY_oct2key decodes |len| bytes from |in| as an EC public key in X9.62 // form. |key| must already have a group configured. On success, it sets the // public key in |key| to the result and returns one. Otherwise, it returns -// zero. +// zero. |ctx| may be NULL. OPENSSL_EXPORT int EC_KEY_oct2key(EC_KEY *key, const uint8_t *in, size_t len, BN_CTX *ctx); // EC_KEY_key2buf behaves like |EC_POINT_point2buf|, except it encodes the -// public key in |key|. +// public key in |key|. |ctx| is ignored and may be NULL. OPENSSL_EXPORT size_t EC_KEY_key2buf(const EC_KEY *key, point_conversion_form_t form, uint8_t **out_buf, BN_CTX *ctx); diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_err.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_err.h index b58ba1c4e..26d802b93 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_err.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_err.h @@ -80,6 +80,13 @@ OPENSSL_INLINE int ERR_GET_REASON(uint32_t packed_error) { return (int)(packed_error & 0xfff); } +// ERR_equals returns one if |packed_error|'s library and reason code are |lib| +// and |reason|, respectively, and zero otherwise. +OPENSSL_INLINE int ERR_equals(uint32_t packed_error, int lib, int reason) { + return ERR_GET_LIB(packed_error) == lib && + ERR_GET_REASON(packed_error) == reason; +} + // ERR_get_error gets the packed error code for the least recent error and // removes that error from the queue. If there are no errors in the queue then // it returns zero. diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_evp.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_evp.h index 115185a64..48ebc93dd 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_evp.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_evp.h @@ -21,8 +21,6 @@ // OpenSSL included digest and cipher functions in this header so we include // them for users that still expect that. -// -// TODO(fork): clean up callers so that they include what they use. #include "CCryptoBoringSSL_aead.h" #include "CCryptoBoringSSL_base64.h" #include "CCryptoBoringSSL_cipher.h" @@ -37,7 +35,7 @@ extern "C" { // EVP abstracts over public/private key algorithms. -// Public key objects. +// Public/private key objects. // // An |EVP_PKEY| object represents a public or private key. A given object may // be used concurrently on multiple threads by non-mutating functions, provided @@ -78,6 +76,13 @@ OPENSSL_EXPORT int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from); // parameters or zero if not, or if the algorithm doesn't take parameters. OPENSSL_EXPORT int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey); +// EVP_PKEY_cmp_parameters compares the parameters of |a| and |b|. It returns +// one if they match, zero if not, or a negative number on error. +// +// WARNING: the return value differs from the usual return value convention. +OPENSSL_EXPORT int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, + const EVP_PKEY *b); + // EVP_PKEY_size returns the maximum size, in bytes, of a signature signed by // |pkey|. For an RSA key, this returns the number of bytes needed to represent // the modulus. For an EC key, this returns the maximum size of a DER-encoded @@ -89,14 +94,125 @@ OPENSSL_EXPORT int EVP_PKEY_size(const EVP_PKEY *pkey); // length of the group order. OPENSSL_EXPORT int EVP_PKEY_bits(const EVP_PKEY *pkey); +// The following constants are returned by |EVP_PKEY_id| and specify the type of +// key. +#define EVP_PKEY_NONE NID_undef +#define EVP_PKEY_RSA NID_rsaEncryption +#define EVP_PKEY_RSA_PSS NID_rsassaPss +#define EVP_PKEY_DSA NID_dsa +#define EVP_PKEY_EC NID_X9_62_id_ecPublicKey +#define EVP_PKEY_ED25519 NID_ED25519 +#define EVP_PKEY_X25519 NID_X25519 +#define EVP_PKEY_HKDF NID_hkdf +#define EVP_PKEY_DH NID_dhKeyAgreement + // EVP_PKEY_id returns the type of |pkey|, which is one of the |EVP_PKEY_*| -// values. +// values above. These type values generally corresond to the algorithm OID, but +// not the parameters, of a SubjectPublicKeyInfo (RFC 5280) or PrivateKeyInfo +// (RFC 5208) AlgorithmIdentifier. Algorithm parameters can be inspected with +// algorithm-specific accessors, e.g. |EVP_PKEY_get_ec_curve_nid|. OPENSSL_EXPORT int EVP_PKEY_id(const EVP_PKEY *pkey); -// Getting and setting concrete public key types. -// -// The following functions get and set the underlying public key in an +// Algorithms. +// +// An |EVP_PKEY| may carry a key from one of several algorithms, represented by +// |EVP_PKEY_ALG|. |EVP_PKEY_ALG|s are used by functions that construct +// |EVP_PKEY|s, such as parsing, so that callers can specify the algorithm(s) to +// use. +// +// Each |EVP_PKEY_ALG| generally corresponds to the AlgorithmIdentifier of a +// SubjectPublicKeyInfo (RFC 5280) or PrivateKeyInfo (RFC 5208), but some may +// support multiple sets of AlgorithmIdentifier parameters, while others may be +// specific to one parameter. + +// EVP_pkey_rsa implements RSA keys (RFC 8017), encoded as rsaEncryption (RFC +// 3279, Section 2.3.1). The rsaEncryption encoding is confusingly named: these +// keys are used for all RSA operations, including signing. The |EVP_PKEY_id| +// value is |EVP_PKEY_RSA|. +// +// WARNING: This |EVP_PKEY_ALG| accepts all RSA key sizes supported by +// BoringSSL. When parsing RSA keys, callers should check the size is within +// their desired bounds with |EVP_PKEY_bits|. RSA public key operations scale +// quadratically and RSA private key operations scale cubicly, so key sizes may +// be a DoS vector. +OPENSSL_EXPORT const EVP_PKEY_ALG *EVP_pkey_rsa(void); + +// EVP_pkey_ec_* implement EC keys, encoded as id-ecPublicKey (RFC 5480, +// Section 2.1.1). The id-ecPublicKey encoding is confusingly named: it is also +// used for private keys (RFC 5915). The |EVP_PKEY_id| value is |EVP_PKEY_EC|. +// +// Each function only supports the specified curve, but curves are not reflected +// in |EVP_PKEY_id|. The curve can be inspected with +// |EVP_PKEY_get_ec_curve_nid|. +OPENSSL_EXPORT const EVP_PKEY_ALG *EVP_pkey_ec_p224(void); +OPENSSL_EXPORT const EVP_PKEY_ALG *EVP_pkey_ec_p256(void); +OPENSSL_EXPORT const EVP_PKEY_ALG *EVP_pkey_ec_p384(void); +OPENSSL_EXPORT const EVP_PKEY_ALG *EVP_pkey_ec_p521(void); + +// EVP_pkey_x25519 implements X25519 keys (RFC 7748), encoded as in RFC 8410. +// The |EVP_PKEY_id| value is |EVP_PKEY_X25519|. +OPENSSL_EXPORT const EVP_PKEY_ALG *EVP_pkey_x25519(void); + +// EVP_pkey_ed25519 implements Ed25519 keys (RFC 8032), encoded as in RFC 8410. +// The |EVP_PKEY_id| value is |EVP_PKEY_ED25519|. +OPENSSL_EXPORT const EVP_PKEY_ALG *EVP_pkey_ed25519(void); + +// EVP_pkey_dsa implements DSA keys, encoded as in RFC 3279, Section 2.3.2. The +// |EVP_PKEY_id| value is |EVP_PKEY_DSA|. This |EVP_PKEY_ALG| accepts all DSA +// parameters supported by BoringSSL. +// +// Keys of this type are not usable with any operations, though the underlying +// |DSA| object can be extracted with |EVP_PKEY_get0_DSA|. This key type is +// deprecated and only implemented for compatibility with legacy applications. +// +// TODO(crbug.com/42290364): We didn't wire up |EVP_PKEY_sign| and +// |EVP_PKEY_verify| just so it was auditable which callers used DSA. Once DSA +// is removed from the default SPKI and PKCS#8 parser and DSA users explicitly +// request |EVP_pkey_dsa|, we could change that. +OPENSSL_EXPORT const EVP_PKEY_ALG *EVP_pkey_dsa(void); + +// EVP_pkey_rsa_pss_sha256 implements RSASSA-PSS keys, encoded as id-RSASSA-PSS +// (RFC 4055, Section 3.1). The |EVP_PKEY_id| value is |EVP_PKEY_RSA_PSS|. This +// |EVP_PKEY_ALG| only accepts keys whose parameters specify: +// +// - A hashAlgorithm of SHA-256 +// - A maskGenAlgorithm of MGF1 with SHA-256 +// - A minimum saltLength of 32 +// - A trailerField of one (must be omitted in the encoding) +// +// Keys of this type will only be usable with RSASSA-PSS with matching signature +// parameters. +// +// This algorithm type is not recommended. The id-RSASSA-PSS key type is not +// widely implemented. Using it negates any compatibility benefits of using RSA. +// More modern algorithms like ECDSA are more performant and more compatible +// than id-RSASSA-PSS keys. This key type also adds significant complexity to a +// system. It has a wide range of possible parameter sets, so any uses must +// ensure all components not only support id-RSASSA-PSS, but also the specific +// parameters chosen. +// +// Note the id-RSASSA-PSS key type is distinct from the RSASSA-PSS signature +// algorithm. The widely implemented id-rsaEncryption key type (|EVP_pkey_rsa| +// and |EVP_PKEY_RSA|) also supports RSASSA-PSS signatures. +// +// WARNING: Any |EVP_PKEY|s produced by this algorithm will return a non-NULL +// |RSA| object through |EVP_PKEY_get1_RSA| and |EVP_PKEY_get0_RSA|. This is +// dangerous as existing code may assume a non-NULL return implies the more +// common id-rsaEncryption key. Additionally, the operations on the underlying +// |RSA| object will not capture the RSA-PSS constraints, so callers risk +// misusing the key by calling these functions. Callers using this algorithm +// must use |EVP_PKEY_id| to distinguish |EVP_PKEY_RSA| and |EVP_PKEY_RSA_PSS|. +// +// WARNING: BoringSSL does not currently implement |RSA_get0_pss_params| with +// these keys. Callers that require this functionality should contact the +// BoringSSL team. +OPENSSL_EXPORT const EVP_PKEY_ALG *EVP_pkey_rsa_pss_sha256(void); + + +// Getting and setting concrete key types. +// +// The following functions get and set the underlying key representation in an // |EVP_PKEY| object. The |set1| functions take an additional reference to the // underlying key and return one on success or zero if |key| is NULL. The // |assign| functions adopt the caller's reference and return one on success or @@ -108,6 +224,18 @@ OPENSSL_EXPORT int EVP_PKEY_id(const EVP_PKEY *pkey); // non-mutating for thread-safety purposes, but mutating functions on the // returned lower-level objects are considered to also mutate the |EVP_PKEY| and // may not be called concurrently with other operations on the |EVP_PKEY|. +// +// WARNING: Matching OpenSSL, the RSA functions behave non-uniformly. +// |EVP_PKEY_set1_RSA| and |EVP_PKEY_assign_RSA| construct an |EVP_PKEY_RSA| +// key, while the |EVP_PKEY_get0_RSA| and |EVP_PKEY_get1_RSA| will return +// non-NULL for both |EVP_PKEY_RSA| and |EVP_PKEY_RSA_PSS|. +// +// This means callers risk misusing a key if they assume a non-NULL return from +// |EVP_PKEY_get0_RSA| or |EVP_PKEY_get1_RSA| implies |EVP_PKEY_RSA|. Prefer +// |EVP_PKEY_id| to check the type of a key. To reduce this risk, BoringSSL does +// not make |EVP_PKEY_RSA_PSS| available by default, only when callers opt in +// via |EVP_pkey_rsa_pss_sha256|. This differs from upstream OpenSSL, where +// callers are exposed to |EVP_PKEY_RSA_PSS| by default. OPENSSL_EXPORT int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key); OPENSSL_EXPORT int EVP_PKEY_assign_RSA(EVP_PKEY *pkey, RSA *key); @@ -129,39 +257,36 @@ OPENSSL_EXPORT int EVP_PKEY_assign_DH(EVP_PKEY *pkey, DH *key); OPENSSL_EXPORT DH *EVP_PKEY_get0_DH(const EVP_PKEY *pkey); OPENSSL_EXPORT DH *EVP_PKEY_get1_DH(const EVP_PKEY *pkey); -#define EVP_PKEY_NONE NID_undef -#define EVP_PKEY_RSA NID_rsaEncryption -#define EVP_PKEY_RSA_PSS NID_rsassaPss -#define EVP_PKEY_DSA NID_dsa -#define EVP_PKEY_EC NID_X9_62_id_ecPublicKey -#define EVP_PKEY_ED25519 NID_ED25519 -#define EVP_PKEY_X25519 NID_X25519 -#define EVP_PKEY_HKDF NID_hkdf -#define EVP_PKEY_DH NID_dhKeyAgreement - -// EVP_PKEY_set_type sets the type of |pkey| to |type|. It returns one if -// successful or zero if the |type| argument is not one of the |EVP_PKEY_*| -// values. If |pkey| is NULL, it simply reports whether the type is known. -OPENSSL_EXPORT int EVP_PKEY_set_type(EVP_PKEY *pkey, int type); - -// EVP_PKEY_cmp_parameters compares the parameters of |a| and |b|. It returns -// one if they match, zero if not, or a negative number of on error. -// -// WARNING: the return value differs from the usual return value convention. -OPENSSL_EXPORT int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, - const EVP_PKEY *b); - // ASN.1 functions +// EVP_PKEY_from_subject_public_key_info decodes a DER-encoded +// SubjectPublicKeyInfo structure (RFC 5280) from |in|. It returns a +// newly-allocated |EVP_PKEY| or NULL on error. Only the |num_algs| algorithms +// in |algs| will be considered when parsing. +OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_from_subject_public_key_info( + const uint8_t *in, size_t len, const EVP_PKEY_ALG *const *algs, + size_t num_algs); + // EVP_parse_public_key decodes a DER-encoded SubjectPublicKeyInfo structure // (RFC 5280) from |cbs| and advances |cbs|. It returns a newly-allocated -// |EVP_PKEY| or NULL on error. If the key is an EC key, the curve is guaranteed -// to be set. +// |EVP_PKEY| or NULL on error. +// +// Prefer |EVP_PKEY_from_subject_public_key_info| instead. This function has +// several pitfalls: +// +// Callers are expected to handle trailing data retuned from |cbs|, making more +// common cases error-prone. // -// The caller must check the type of the parsed public key to ensure it is -// suitable and validate other desired key properties such as RSA modulus size -// or EC curve. +// There is also no way to pass in supported algorithms. This function instead +// supports some default set of algorithms. Future versions of BoringSSL may add +// to this list, based on the needs of the other callers. Conversely, some +// algorithms may be intentionally omitted, if they cause too much risk to +// existing callers. +// +// This means callers must check the type of the parsed public key to ensure it +// is suitable and validate other desired key properties such as RSA modulus +// size or EC curve. OPENSSL_EXPORT EVP_PKEY *EVP_parse_public_key(CBS *cbs); // EVP_marshal_public_key marshals |key| as a DER-encoded SubjectPublicKeyInfo @@ -169,19 +294,41 @@ OPENSSL_EXPORT EVP_PKEY *EVP_parse_public_key(CBS *cbs); // success and zero on error. OPENSSL_EXPORT int EVP_marshal_public_key(CBB *cbb, const EVP_PKEY *key); +// EVP_PKEY_from_private_key_info decodes a DER-encoded PrivateKeyInfo structure +// (RFC 5208) from |in|. It returns a newly-allocated |EVP_PKEY| or NULL on +// error. Only the |num_algs| algorithms in |algs| will be considered when +// parsing. +// +// A PrivateKeyInfo ends with an optional set of attributes. These are silently +// ignored. +OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_from_private_key_info( + const uint8_t *in, size_t len, const EVP_PKEY_ALG *const *algs, + size_t num_algs); + // EVP_parse_private_key decodes a DER-encoded PrivateKeyInfo structure (RFC // 5208) from |cbs| and advances |cbs|. It returns a newly-allocated |EVP_PKEY| // or NULL on error. // -// The caller must check the type of the parsed private key to ensure it is -// suitable and validate other desired key properties such as RSA modulus size -// or EC curve. In particular, RSA private key operations scale cubicly, so +// Prefer |EVP_PKEY_from_private_key_info| instead. This function has +// several pitfalls: +// +// Callers are expected to handle trailing data retuned from |cbs|, making more +// common cases error-prone. +// +// There is also no way to pass in supported algorithms. This function instead +// supports some default set of algorithms. Future versions of BoringSSL may add +// to this list, based on the needs of the other callers. Conversely, some +// algorithms may be intentionally omitted, if they cause too much risk to +// existing callers. +// +// This means the caller must check the type of the parsed private key to ensure +// it is suitable and validate other desired key properties such as RSA modulus +// size or EC curve. In particular, RSA private key operations scale cubicly, so // applications accepting RSA private keys from external sources may need to // bound key sizes (use |EVP_PKEY_bits| or |RSA_bits|) to avoid a DoS vector. // -// A PrivateKeyInfo ends with an optional set of attributes. These are not -// processed and so this function will silently ignore any trailing data in the -// structure. +// A PrivateKeyInfo ends with an optional set of attributes. These are silently +// ignored. OPENSSL_EXPORT EVP_PKEY *EVP_parse_private_key(CBS *cbs); // EVP_marshal_private_key marshals |key| as a DER-encoded PrivateKeyInfo @@ -197,20 +344,18 @@ OPENSSL_EXPORT int EVP_marshal_private_key(CBB *cbb, const EVP_PKEY *key); // RFC 7748 and RFC 8032, respectively. Note the RFC 8032 private key format is // the 32-byte prefix of |ED25519_sign|'s 64-byte private key. -// EVP_PKEY_new_raw_private_key returns a newly allocated |EVP_PKEY| wrapping a -// private key of the specified type. It returns one on success and zero on -// error. -OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *unused, +// EVP_PKEY_from_raw_private_key interprets |in| as a raw private key of type +// |alg| and returns a newly-allocated |EVP_PKEY|, or nullptr on error. +OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_from_raw_private_key(const EVP_PKEY_ALG *alg, + const uint8_t *in, + size_t len); + +// EVP_PKEY_from_raw_public_key interprets |in| as a raw public key of type +// |alg| and returns a newly-allocated |EVP_PKEY|, or nullptr on error. +OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_from_raw_public_key(const EVP_PKEY_ALG *alg, const uint8_t *in, size_t len); -// EVP_PKEY_new_raw_public_key returns a newly allocated |EVP_PKEY| wrapping a -// public key of the specified type. It returns one on success and zero on -// error. -OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *unused, - const uint8_t *in, - size_t len); - // EVP_PKEY_get_raw_private_key outputs the private key for |pkey| in raw form. // If |out| is NULL, it sets |*out_len| to the size of the raw private key. // Otherwise, it writes at most |*out_len| bytes to |out| and sets |*out_len| to @@ -468,10 +613,33 @@ OPENSSL_EXPORT int EVP_PBE_scrypt(const char *password, size_t password_len, size_t key_len); -// Public key contexts. +// Operations. +// +// |EVP_PKEY_CTX| objects hold the context for an operation (e.g. signing or +// encrypting) that uses an |EVP_PKEY|. They are used to configure +// algorithm-specific parameters for the operation before performing the +// operation. The general pattern for performing an operation in EVP is: +// +// 1. Construct an |EVP_PKEY_CTX|, either with |EVP_PKEY_CTX_new| (operations +// using a key, like signing) or |EVP_PKEY_CTX_new_id| (operations not using +// an existing key, like key generation). +// +// 2. Initialize it for an operation. For example, |EVP_PKEY_sign_init| +// initializes an |EVP_PKEY_CTX| for signing. // -// |EVP_PKEY_CTX| objects hold the context of an operation (e.g. signing or -// encrypting) that uses a public key. +// 3. Configure algorithm-specific parameters for the operation by calling +// control functions on the |EVP_PKEY_CTX|. Some functions are generic, such +// as |EVP_PKEY_CTX_set_signature_md|, and some are specific to an algorithm, +// such as |EVP_PKEY_CTX_set_rsa_padding|. +// +// 4. Perform the operation. For example, |EVP_PKEY_sign| signs with the +// corresponding parameters. +// +// 5. Release the |EVP_PKEY_CTX| with |EVP_PKEY_CTX_free|. +// +// Each |EVP_PKEY| algorithm interprets operations and parameters differently. +// Not all algorithms support all operations. Functions will fail if the +// algorithm does not support the parameter or operation. // EVP_PKEY_CTX_new allocates a fresh |EVP_PKEY_CTX| for use with |pkey|. It // returns the context or NULL on error. @@ -686,16 +854,16 @@ OPENSSL_EXPORT int EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx, int *out_padding); // EVP_PKEY_CTX_set_rsa_pss_saltlen sets the length of the salt in a PSS-padded -// signature. A value of -1 cause the salt to be the same length as the digest -// in the signature. A value of -2 causes the salt to be the maximum length -// that will fit when signing and recovered from the signature when verifying. -// Otherwise the value gives the size of the salt in bytes. +// signature. A value of |RSA_PSS_SALTLEN_DIGEST| causes the salt to be the same +// length as the digest in the signature. A value of |RSA_PSS_SALTLEN_AUTO| +// causes the salt to be the maximum length that will fit when signing and +// recovered from the signature when verifying. Otherwise the value gives the +// size of the salt in bytes. // -// If unsure, use -1. +// If unsure, use |RSA_PSS_SALTLEN_DIGEST|, which is the default. Note this +// differs from OpenSSL, which defaults to |RSA_PSS_SALTLEN_AUTO|. // // Returns one on success or zero on error. -// -// TODO(davidben): The default is currently -2. Switch it to -1. OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int salt_len); @@ -715,7 +883,9 @@ OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX *ctx, int bits); // EVP_PKEY_CTX_set_rsa_keygen_pubexp sets |e| as the public exponent for key -// generation. Returns one on success or zero on error. +// generation. Returns one on success or zero on error. On success, |ctx| takes +// ownership of |e|. The library will then call |BN_free| on |e| when |ctx| is +// destroyed. OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *e); @@ -766,6 +936,14 @@ OPENSSL_EXPORT int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx, // EC specific control functions. +// EVP_PKEY_get_ec_curve_nid returns |pkey|'s curve as a NID constant, such as +// |NID_X9_62_prime256v1|, or |NID_undef| if |pkey| is not an EC key. +OPENSSL_EXPORT int EVP_PKEY_get_ec_curve_nid(const EVP_PKEY *pkey); + +// EVP_PKEY_get_ec_point_conv_form returns |pkey|'s point conversion form as a +// |POINT_CONVERSION_*| constant, or zero if |pkey| is not an EC key. +OPENSSL_EXPORT int EVP_PKEY_get_ec_point_conv_form(const EVP_PKEY *pkey); + // EVP_PKEY_CTX_set_ec_paramgen_curve_nid sets the curve used for // |EVP_PKEY_keygen| or |EVP_PKEY_paramgen| operations to |nid|. It returns one // on success and zero on error. @@ -893,6 +1071,25 @@ OPENSSL_EXPORT EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **out, OPENSSL_EXPORT int EVP_PKEY_CTX_set_ec_param_enc(EVP_PKEY_CTX *ctx, int encoding); +// EVP_PKEY_set_type sets the type of |pkey| to |type|. It returns one if +// successful or zero if the |type| argument is not one of the |EVP_PKEY_*| +// values supported for use with this function. If |pkey| is NULL, it simply +// reports whether the type is known. +// +// There are very few cases where this function is useful. Changing |pkey|'s +// type clears any previously stored keys, so there is no benefit to loading a +// key and then changing its type. Although |pkey| is left with a type +// configured, it has no key, and functions which set a key, such as +// |EVP_PKEY_set1_RSA|, will configure a type anyway. If writing unit tests that +// are only sensitive to the type of a key, it is preferable to construct a real +// key, so that tests are more representative of production code. +// +// The only API pattern which requires this function is +// |EVP_PKEY_set1_tls_encodedpoint| with X25519, which requires a half-empty +// |EVP_PKEY| that was first configured with |EVP_PKEY_X25519|. Currently, all +// other values of |type| will result in an error. +OPENSSL_EXPORT int EVP_PKEY_set_type(EVP_PKEY *pkey, int type); + // EVP_PKEY_set1_tls_encodedpoint replaces |pkey| with a public key encoded by // |in|. It returns one on success and zero on error. // @@ -1004,6 +1201,26 @@ OPENSSL_EXPORT int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key); // EVP_PKEY_type returns |nid|. OPENSSL_EXPORT int EVP_PKEY_type(int nid); +// EVP_PKEY_new_raw_private_key interprets |in| as a raw private key of type +// |type|, which must be an |EVP_PKEY_*| constant, such as |EVP_PKEY_X25519|, +// and returns a newly-allocated |EVP_PKEY|, or nullptr on error. +// +// Prefer |EVP_PKEY_from_raw_private_key|, which allows dead code elimination to +// discard algorithms that aren't reachable from the caller. +OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_new_raw_private_key(int type, ENGINE *unused, + const uint8_t *in, + size_t len); + +// EVP_PKEY_new_raw_public_key interprets |in| as a raw public key of type +// |type|, which must be an |EVP_PKEY_*| constant, such as |EVP_PKEY_X25519|, +// and returns a newly-allocated |EVP_PKEY|, or nullptr on error. +// +// Prefer |EVP_PKEY_from_raw_private_key|, which allows dead code elimination to +// discard algorithms that aren't reachable from the caller. +OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_new_raw_public_key(int type, ENGINE *unused, + const uint8_t *in, + size_t len); + // Preprocessor compatibility section (hidden). // diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_evp_errors.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_evp_errors.h index c7fa18055..9626caff0 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_evp_errors.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_evp_errors.h @@ -21,7 +21,7 @@ #define EVP_R_DIFFERENT_KEY_TYPES 103 #define EVP_R_DIFFERENT_PARAMETERS 104 #define EVP_R_ENCODE_ERROR 105 -#define EVP_R_EXPECTING_AN_EC_KEY_KEY 106 +#define EVP_R_EXPECTING_A_EC_KEY 106 #define EVP_R_EXPECTING_AN_RSA_KEY 107 #define EVP_R_EXPECTING_A_DSA_KEY 108 #define EVP_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE 109 diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_hpke.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_hpke.h index ae7db6db5..739653015 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_hpke.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_hpke.h @@ -16,7 +16,7 @@ #define OPENSSL_HEADER_HPKE_H #include "CCryptoBoringSSL_aead.h" -#include "CCryptoBoringSSL_base.h" // IWYU pragma: export +#include "CCryptoBoringSSL_base.h" // IWYU pragma: export #include "CCryptoBoringSSL_curve25519.h" #include "CCryptoBoringSSL_digest.h" @@ -42,12 +42,14 @@ extern "C" { // The following constants are KEM identifiers. #define EVP_HPKE_DHKEM_P256_HKDF_SHA256 0x0010 #define EVP_HPKE_DHKEM_X25519_HKDF_SHA256 0x0020 +#define EVP_HPKE_XWING 0x647a // The following functions are KEM algorithms which may be used with HPKE. Note // that, while some HPKE KEMs use KDFs internally, this is separate from the // |EVP_HPKE_KDF| selection. OPENSSL_EXPORT const EVP_HPKE_KEM *EVP_hpke_x25519_hkdf_sha256(void); OPENSSL_EXPORT const EVP_HPKE_KEM *EVP_hpke_p256_hkdf_sha256(void); +OPENSSL_EXPORT const EVP_HPKE_KEM *EVP_hpke_xwing(void); // EVP_HPKE_KEM_id returns the HPKE KEM identifier for |kem|, which // will be one of the |EVP_HPKE_KEM_*| constants. @@ -55,7 +57,7 @@ OPENSSL_EXPORT uint16_t EVP_HPKE_KEM_id(const EVP_HPKE_KEM *kem); // EVP_HPKE_MAX_PUBLIC_KEY_LENGTH is the maximum length of an encoded public key // for all KEMs currently supported by this library. -#define EVP_HPKE_MAX_PUBLIC_KEY_LENGTH 65 +#define EVP_HPKE_MAX_PUBLIC_KEY_LENGTH 1216 // EVP_HPKE_KEM_public_key_len returns the length of a public key for |kem|. // This value will be at most |EVP_HPKE_MAX_PUBLIC_KEY_LENGTH|. @@ -71,7 +73,7 @@ OPENSSL_EXPORT size_t EVP_HPKE_KEM_private_key_len(const EVP_HPKE_KEM *kem); // EVP_HPKE_MAX_ENC_LENGTH is the maximum length of "enc", the encapsulated // shared secret, for all KEMs currently supported by this library. -#define EVP_HPKE_MAX_ENC_LENGTH 65 +#define EVP_HPKE_MAX_ENC_LENGTH 1120 // EVP_HPKE_KEM_enc_len returns the length of the "enc", the encapsulated shared // secret, for |kem|. This value will be at most |EVP_HPKE_MAX_ENC_LENGTH|. diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_mldsa.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_mldsa.h index 88b12927d..f2b906741 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_mldsa.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_mldsa.h @@ -318,6 +318,146 @@ OPENSSL_EXPORT int MLDSA87_parse_public_key( struct MLDSA87_public_key *public_key, CBS *in); +// ML-DSA-44. + +// MLDSA44_private_key contains an ML-DSA-44 private key. The contents of this +// object should never leave the address space since the format is unstable. +struct MLDSA44_private_key { + union { + uint8_t bytes[32 + 32 + 64 + 256 * 4 * (4 + 4 + 4)]; + uint32_t alignment; + } opaque; +}; + +// MLDSA44_public_key contains an ML-DSA-44 public key. The contents of this +// object should never leave the address space since the format is unstable. +struct MLDSA44_public_key { + union { + uint8_t bytes[32 + 64 + 256 * 4 * 4]; + uint32_t alignment; + } opaque; +}; + +// MLDSA44_prehash contains a pre-hash context for ML-DSA-44. The contents of +// this object should never leave the address space since the format is +// unstable. +struct MLDSA44_prehash { + union { + uint8_t bytes[200 + 4 + 4 + 4 * sizeof(size_t)]; + uint64_t alignment; + } opaque; +}; + +// MLDSA44_PRIVATE_KEY_BYTES is the number of bytes in an encoded ML-DSA-44 +// private key. +#define MLDSA44_PRIVATE_KEY_BYTES 2560 + +// MLDSA44_PUBLIC_KEY_BYTES is the number of bytes in an encoded ML-DSA-44 +// public key. +#define MLDSA44_PUBLIC_KEY_BYTES 1312 + +// MLDSA44_SIGNATURE_BYTES is the number of bytes in an encoded ML-DSA-44 +// signature. +#define MLDSA44_SIGNATURE_BYTES 2420 + +// MLDSA44_generate_key generates a random public/private key pair, writes the +// encoded public key to |out_encoded_public_key|, writes the seed to +// |out_seed|, and sets |out_private_key| to the private key. Returns 1 on +// success and 0 on allocation failure. +OPENSSL_EXPORT int MLDSA44_generate_key( + uint8_t out_encoded_public_key[MLDSA44_PUBLIC_KEY_BYTES], + uint8_t out_seed[MLDSA_SEED_BYTES], + struct MLDSA44_private_key *out_private_key); + +// MLDSA44_private_key_from_seed regenerates a private key from a seed value +// that was generated by |MLDSA44_generate_key|. Returns 1 on success and 0 on +// allocation failure or if |seed_len| is incorrect. +OPENSSL_EXPORT int MLDSA44_private_key_from_seed( + struct MLDSA44_private_key *out_private_key, const uint8_t *seed, + size_t seed_len); + +// MLDSA44_public_from_private sets |*out_public_key| to the public key that +// corresponds to |private_key|. Returns 1 on success and 0 on failure. +OPENSSL_EXPORT int MLDSA44_public_from_private( + struct MLDSA44_public_key *out_public_key, + const struct MLDSA44_private_key *private_key); + +// MLDSA44_sign generates a signature for the message |msg| of length +// |msg_len| using |private_key| (following the randomized algorithm), and +// writes the encoded signature to |out_encoded_signature|. The |context| +// argument is also signed over and can be used to include implicit contextual +// information that isn't included in |msg|. The same value of |context| must be +// presented to |MLDSA44_verify| in order for the generated signature to be +// considered valid. |context| and |context_len| may be |NULL| and 0 to use an +// empty context (this is common). Returns 1 on success and 0 on failure. +OPENSSL_EXPORT int MLDSA44_sign( + uint8_t out_encoded_signature[MLDSA44_SIGNATURE_BYTES], + const struct MLDSA44_private_key *private_key, const uint8_t *msg, + size_t msg_len, const uint8_t *context, size_t context_len); + +// MLDSA44_verify verifies that |signature| constitutes a valid +// signature for the message |msg| of length |msg_len| using |public_key|. The +// value of |context| must equal the value that was passed to |MLDSA44_sign| +// when the signature was generated. Returns 1 on success or 0 on error. +OPENSSL_EXPORT int MLDSA44_verify(const struct MLDSA44_public_key *public_key, + const uint8_t *signature, + size_t signature_len, const uint8_t *msg, + size_t msg_len, const uint8_t *context, + size_t context_len); + +// MLDSA44_prehash_init initializes a pre-hashing state using |public_key|. The +// |context| argument can be used to include implicit contextual information +// that isn't included in the message. The same value of |context| must be +// presented to |MLDSA44_verify| in order for the generated signature to be +// considered valid. |context| and |context_len| may be |NULL| and 0 to use an +// empty context (this is common). Returns 1 on success and 0 on failure (if the +// context is too long). +OPENSSL_EXPORT int MLDSA44_prehash_init( + struct MLDSA44_prehash *out_state, + const struct MLDSA44_public_key *public_key, const uint8_t *context, + size_t context_len); + +// MLDSA44_prehash_update incorporates the given |msg| of length |msg_len| into +// the pre-hashing state. This can be called multiple times on successive chunks +// of the message. This should be called after |MLDSA44_prehash_init| and before +// |MLDSA44_prehash_finalize|. +OPENSSL_EXPORT void MLDSA44_prehash_update(struct MLDSA44_prehash *inout_state, + const uint8_t *msg, size_t msg_len); + +// MLDSA44_prehash_finalize extracts a pre-hashed message representative from +// the given pre-hashing state. This should be called after +// |MLDSA44_prehash_init| and |MLDSA44_prehash_update|. The resulting +// |out_msg_rep| should then be passed to |MLDSA44_sign_message_representative| +// to obtain a signature. +OPENSSL_EXPORT void MLDSA44_prehash_finalize( + uint8_t out_msg_rep[MLDSA_MU_BYTES], struct MLDSA44_prehash *inout_state); + +// MLDSA44_sign_message_representative generates a signature for the pre-hashed +// message |msg_rep| using |private_key| (following the randomized algorithm), +// and writes the encoded signature to |out_encoded_signature|. The |msg_rep| +// should be obtained via calls to |MLDSA44_prehash_init|, +// |MLDSA44_prehash_update| and |MLDSA44_prehash_finalize| using the public key +// from the same key pair, otherwise the signature will not verify. Returns 1 on +// success and 0 on failure. +OPENSSL_EXPORT int MLDSA44_sign_message_representative( + uint8_t out_encoded_signature[MLDSA44_SIGNATURE_BYTES], + const struct MLDSA44_private_key *private_key, + const uint8_t msg_rep[MLDSA_MU_BYTES]); + +// MLDSA44_marshal_public_key serializes |public_key| to |out| in the standard +// format for ML-DSA-44 public keys. It returns 1 on success or 0 on +// allocation error. +OPENSSL_EXPORT int MLDSA44_marshal_public_key( + CBB *out, const struct MLDSA44_public_key *public_key); + +// MLDSA44_parse_public_key parses a public key, in the format generated by +// |MLDSA44_marshal_public_key|, from |in| and writes the result to +// |out_public_key|. It returns 1 on success or 0 on parse error or if +// there are trailing bytes in |in|. +OPENSSL_EXPORT int MLDSA44_parse_public_key( + struct MLDSA44_public_key *public_key, CBS *in); + + #if defined(__cplusplus) } // extern C #endif diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_nid.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_nid.h index 415556daf..f7fc5ab29 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_nid.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_nid.h @@ -17,7 +17,7 @@ #ifndef OPENSSL_HEADER_NID_H #define OPENSSL_HEADER_NID_H -#include "CCryptoBoringSSL_base.h" // IWYU pragma: export +#include "CCryptoBoringSSL_base.h" // IWYU pragma: export #if defined(__cplusplus) extern "C" { @@ -4216,6 +4216,9 @@ extern "C" { #define SN_X25519MLKEM768 "X25519MLKEM768" #define NID_X25519MLKEM768 965 +#define SN_MLKEM1024 "MLKEM1024" +#define NID_MLKEM1024 966 + #if defined(__cplusplus) } /* extern C */ diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_rsa.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_rsa.h index e7516e0f7..a6f8425d8 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_rsa.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_rsa.h @@ -69,9 +69,7 @@ OPENSSL_EXPORT int RSA_up_ref(RSA *rsa); // Properties. // OPENSSL_RSA_MAX_MODULUS_BITS is the maximum supported RSA modulus, in bits. -// -// TODO(crbug.com/402677800): Reduce this to 8192. -#define OPENSSL_RSA_MAX_MODULUS_BITS 16384 +#define OPENSSL_RSA_MAX_MODULUS_BITS 8192 // RSA_bits returns the size of |rsa|, in bits. OPENSSL_EXPORT unsigned RSA_bits(const RSA *rsa); @@ -225,7 +223,11 @@ OPENSSL_EXPORT int RSA_generate_key_fips(RSA *rsa, int bits, BN_GENCB *cb); // It returns 1 on success or zero on error. // // The |padding| argument must be one of the |RSA_*_PADDING| values. If in -// doubt, use |RSA_PKCS1_OAEP_PADDING| for new protocols. +// doubt, use |RSA_PKCS1_OAEP_PADDING| for new protocols. When |padding| is +// |RSA_PKCS1_OAEP_PADDING|, this function has no way to set the OAEP or MGF-1 +// digest, so it is always SHA-1. For other OAEP parameters, wrap |rsa| in an +// |EVP_PKEY| and use |EVP_PKEY_encrypt| with |EVP_PKEY_CTX_set_rsa_padding| and +// related functions. OPENSSL_EXPORT int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, const uint8_t *in, size_t in_len, int padding); @@ -237,7 +239,11 @@ OPENSSL_EXPORT int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, // It returns 1 on success or zero on error. // // The |padding| argument must be one of the |RSA_*_PADDING| values. If in -// doubt, use |RSA_PKCS1_OAEP_PADDING| for new protocols. +// doubt, use |RSA_PKCS1_OAEP_PADDING| for new protocols. When |padding| is +// |RSA_PKCS1_OAEP_PADDING|, this function has no way to set the OAEP or MGF-1 +// digest, so it is always SHA-1. For other OAEP parameters, wrap |rsa| in an +// |EVP_PKEY| and use |EVP_PKEY_decrypt| with |EVP_PKEY_CTX_set_rsa_padding| and +// related functions. // // WARNING: Passing |RSA_PKCS1_PADDING| into this function is deprecated and // insecure. RSAES-PKCS1-v1_5 is vulnerable to a chosen-ciphertext attack. @@ -259,6 +265,11 @@ OPENSSL_EXPORT int RSA_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, // -1 on error. The |padding| argument must be one of the |RSA_*_PADDING| // values. If in doubt, use |RSA_PKCS1_OAEP_PADDING| for new protocols. // +// When |padding| is |RSA_PKCS1_OAEP_PADDING|, this function has no way to set +// the OAEP or MGF-1 digest, so it is always SHA-1. For other OAEP parameters, +// wrap |rsa| in an |EVP_PKEY| and use |EVP_PKEY_encrypt| with +// |EVP_PKEY_CTX_set_rsa_padding| and related functions. +// // WARNING: this function is dangerous because it breaks the usual return value // convention. Use |RSA_encrypt| instead. OPENSSL_EXPORT int RSA_public_encrypt(size_t flen, const uint8_t *from, @@ -272,6 +283,11 @@ OPENSSL_EXPORT int RSA_public_encrypt(size_t flen, const uint8_t *from, // |RSA_PKCS1_PADDING| into this function is deprecated and insecure. See // |RSA_decrypt|. // +// When |padding| is |RSA_PKCS1_OAEP_PADDING|, this function has no way to set +// the OAEP or MGF-1 digest, so it is always SHA-1. For other OAEP parameters, +// wrap |rsa| in an |EVP_PKEY| and use |EVP_PKEY_decrypt| with +// |EVP_PKEY_CTX_set_rsa_padding| and related functions. +// // WARNING: this function is dangerous because it breaks the usual return value // convention. Use |RSA_decrypt| instead. OPENSSL_EXPORT int RSA_private_decrypt(size_t flen, const uint8_t *from, @@ -301,6 +317,15 @@ OPENSSL_EXPORT int RSA_sign(int hash_nid, const uint8_t *digest, size_t digest_len, uint8_t *out, unsigned *out_len, RSA *rsa); +// RSA_PSS_SALTLEN_DIGEST indicates a PSS salt length that matches the digest +// length. This is recommended. +#define RSA_PSS_SALTLEN_DIGEST (-1) +// RSA_PSS_SALTLEN_AUTO indicates a maximum possible PSS salt length when +// signing, and automatically detecting the salt length when verifying. This is +// not recommended. Neither the signing nor verifying behaviors are compliant +// with FIPS 186-5. +#define RSA_PSS_SALTLEN_AUTO (-2) + // RSA_sign_pss_mgf1 signs |digest_len| bytes from |digest| with the public key // from |rsa| using RSASSA-PSS with MGF1 as the mask generation function. It // writes, at most, |max_out| bytes of signature data to |out|. The |max_out| @@ -311,9 +336,10 @@ OPENSSL_EXPORT int RSA_sign(int hash_nid, const uint8_t *digest, // and the MGF1 hash, respectively. If |mgf1_md| is NULL, |md| is // used. // -// |salt_len| specifies the expected salt length in bytes. If |salt_len| is -1, -// then the salt length is the same as the hash length. If -2, then the salt -// length is maximal given the size of |rsa|. If unsure, use -1. +// |salt_len| specifies the expected salt length in bytes. If |salt_len| is +// |RSA_PSS_SALTLEN_DIGEST|, then the salt length is the same as the hash +// length. If |RSA_PSS_SALTLEN_AUTO|, then the salt length is maximal given the +// size of |rsa|. If unsure, use |RSA_PSS_SALTLEN_DIGEST|. // // WARNING: |digest| must be the result of hashing the data to be signed with // |md|. Passing unhashed inputs will not result in a secure signature scheme. @@ -373,9 +399,9 @@ OPENSSL_EXPORT int RSA_verify(int hash_nid, const uint8_t *digest, // and the MGF1 hash, respectively. If |mgf1_md| is NULL, |md| is // used. |salt_len| specifies the expected salt length in bytes. // -// If |salt_len| is -1, then the salt length is the same as the hash length. If -// -2, then the salt length is recovered and all values accepted. If unsure, use -// -1. +// If |salt_len| is |RSA_PSS_SALTLEN_DIGEST|, then the salt length is the same +// as the hash length. If |RSA_PSS_SALTLEN_AUTO|, then the salt length is +// recovered and all values accepted. If unsure, use |RSA_PSS_SALTLEN_DIGEST|. // // WARNING: |digest| must be the result of hashing the data to be verified with // |md|. Passing unhashed input will not result in a secure signature scheme. @@ -737,8 +763,13 @@ OPENSSL_EXPORT int RSA_padding_add_PKCS1_OAEP(uint8_t *to, size_t to_len, OPENSSL_EXPORT int RSA_print(BIO *bio, const RSA *rsa, int indent); // RSA_get0_pss_params returns NULL. In OpenSSL, this function retries RSA-PSS -// parameters associated with |RSA| objects, but BoringSSL does not support -// the id-RSASSA-PSS key encoding. +// parameters associated with |RSA| objects, but BoringSSL does not enable the +// id-RSASSA-PSS key encoding by default. +// +// WARNING: BoringSSL does support id-RSASSA-PSS parameters when callers opt in +// (see |EVP_pkey_rsa_pss_sha256|). We currently assume such callers do not need +// this function. Callers that opt into id-RSASSA-PSS support and require this +// functionality should contact the BoringSSL team. OPENSSL_EXPORT const RSA_PSS_PARAMS *RSA_get0_pss_params(const RSA *rsa); // RSA_new_method_no_e returns a newly-allocated |RSA| object backed by diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_sha.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_sha.h index 33a8a76ca..2b1f6b40d 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_sha.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_sha.h @@ -15,8 +15,13 @@ #ifndef OPENSSL_HEADER_SHA_H #define OPENSSL_HEADER_SHA_H -#include "CCryptoBoringSSL_base.h" // IWYU pragma: export -#include "CCryptoBoringSSL_bcm_public.h" // IWYU pragma: export +#include "CCryptoBoringSSL_base.h" // IWYU pragma: export +#include "CCryptoBoringSSL_bcm_public.h" // IWYU pragma: export + +// `sha.h` historically included SHA-1 and SHA-2 hash functions. So, for +// backward compatibility `sha2.h` is included here. New uses of this header +// should include sha2.h unless SHA-1 family functions are required. +#include "CCryptoBoringSSL_sha2.h" // IWYU pragma: export #if defined(__cplusplus) extern "C" { @@ -74,160 +79,6 @@ OPENSSL_EXPORT void CRYPTO_fips_186_2_prf( uint8_t *out, size_t out_len, const uint8_t xkey[SHA_DIGEST_LENGTH]); -// SHA-224. - -// SHA224_CBLOCK is the block size of SHA-224. -#define SHA224_CBLOCK 64 - -// SHA224_DIGEST_LENGTH is the length of a SHA-224 digest. -#define SHA224_DIGEST_LENGTH 28 - -// SHA224_Init initialises |sha| and returns 1. -OPENSSL_EXPORT int SHA224_Init(SHA256_CTX *sha); - -// SHA224_Update adds |len| bytes from |data| to |sha| and returns 1. -OPENSSL_EXPORT int SHA224_Update(SHA256_CTX *sha, const void *data, size_t len); - -// SHA224_Final adds the final padding to |sha| and writes the resulting digest -// to |out|, which must have at least |SHA224_DIGEST_LENGTH| bytes of space. It -// returns 1. -OPENSSL_EXPORT int SHA224_Final(uint8_t out[SHA224_DIGEST_LENGTH], - SHA256_CTX *sha); - -// SHA224 writes the digest of |len| bytes from |data| to |out| and returns -// |out|. There must be at least |SHA224_DIGEST_LENGTH| bytes of space in -// |out|. -OPENSSL_EXPORT uint8_t *SHA224(const uint8_t *data, size_t len, - uint8_t out[SHA224_DIGEST_LENGTH]); - - -// SHA-256. - -// SHA256_CBLOCK is the block size of SHA-256. -#define SHA256_CBLOCK 64 - -// SHA256_DIGEST_LENGTH is the length of a SHA-256 digest. -#define SHA256_DIGEST_LENGTH 32 - -// SHA256_Init initialises |sha| and returns 1. -OPENSSL_EXPORT int SHA256_Init(SHA256_CTX *sha); - -// SHA256_Update adds |len| bytes from |data| to |sha| and returns 1. -OPENSSL_EXPORT int SHA256_Update(SHA256_CTX *sha, const void *data, size_t len); - -// SHA256_Final adds the final padding to |sha| and writes the resulting digest -// to |out|, which must have at least |SHA256_DIGEST_LENGTH| bytes of space. It -// returns one on success and zero on programmer error. -OPENSSL_EXPORT int SHA256_Final(uint8_t out[SHA256_DIGEST_LENGTH], - SHA256_CTX *sha); - -// SHA256 writes the digest of |len| bytes from |data| to |out| and returns -// |out|. There must be at least |SHA256_DIGEST_LENGTH| bytes of space in -// |out|. -OPENSSL_EXPORT uint8_t *SHA256(const uint8_t *data, size_t len, - uint8_t out[SHA256_DIGEST_LENGTH]); - -// SHA256_Transform is a low-level function that performs a single, SHA-256 -// block transformation using the state from |sha| and |SHA256_CBLOCK| bytes -// from |block|. -OPENSSL_EXPORT void SHA256_Transform(SHA256_CTX *sha, - const uint8_t block[SHA256_CBLOCK]); - -// SHA256_TransformBlocks is a low-level function that takes |num_blocks| * -// |SHA256_CBLOCK| bytes of data and performs SHA-256 transforms on it to update -// |state|. You should not use this function unless you are implementing a -// derivative of SHA-256. -OPENSSL_EXPORT void SHA256_TransformBlocks(uint32_t state[8], - const uint8_t *data, - size_t num_blocks); - - -// SHA-384. - -// SHA384_CBLOCK is the block size of SHA-384. -#define SHA384_CBLOCK 128 - -// SHA384_DIGEST_LENGTH is the length of a SHA-384 digest. -#define SHA384_DIGEST_LENGTH 48 - -// SHA384_Init initialises |sha| and returns 1. -OPENSSL_EXPORT int SHA384_Init(SHA512_CTX *sha); - -// SHA384_Update adds |len| bytes from |data| to |sha| and returns 1. -OPENSSL_EXPORT int SHA384_Update(SHA512_CTX *sha, const void *data, size_t len); - -// SHA384_Final adds the final padding to |sha| and writes the resulting digest -// to |out|, which must have at least |SHA384_DIGEST_LENGTH| bytes of space. It -// returns one on success and zero on programmer error. -OPENSSL_EXPORT int SHA384_Final(uint8_t out[SHA384_DIGEST_LENGTH], - SHA512_CTX *sha); - -// SHA384 writes the digest of |len| bytes from |data| to |out| and returns -// |out|. There must be at least |SHA384_DIGEST_LENGTH| bytes of space in -// |out|. -OPENSSL_EXPORT uint8_t *SHA384(const uint8_t *data, size_t len, - uint8_t out[SHA384_DIGEST_LENGTH]); - - -// SHA-512. - -// SHA512_CBLOCK is the block size of SHA-512. -#define SHA512_CBLOCK 128 - -// SHA512_DIGEST_LENGTH is the length of a SHA-512 digest. -#define SHA512_DIGEST_LENGTH 64 - -// SHA512_Init initialises |sha| and returns 1. -OPENSSL_EXPORT int SHA512_Init(SHA512_CTX *sha); - -// SHA512_Update adds |len| bytes from |data| to |sha| and returns 1. -OPENSSL_EXPORT int SHA512_Update(SHA512_CTX *sha, const void *data, size_t len); - -// SHA512_Final adds the final padding to |sha| and writes the resulting digest -// to |out|, which must have at least |SHA512_DIGEST_LENGTH| bytes of space. It -// returns one on success and zero on programmer error. -OPENSSL_EXPORT int SHA512_Final(uint8_t out[SHA512_DIGEST_LENGTH], - SHA512_CTX *sha); - -// SHA512 writes the digest of |len| bytes from |data| to |out| and returns -// |out|. There must be at least |SHA512_DIGEST_LENGTH| bytes of space in -// |out|. -OPENSSL_EXPORT uint8_t *SHA512(const uint8_t *data, size_t len, - uint8_t out[SHA512_DIGEST_LENGTH]); - -// SHA512_Transform is a low-level function that performs a single, SHA-512 -// block transformation using the state from |sha| and |SHA512_CBLOCK| bytes -// from |block|. -OPENSSL_EXPORT void SHA512_Transform(SHA512_CTX *sha, - const uint8_t block[SHA512_CBLOCK]); - - -// SHA-512-256 -// -// See https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf section 5.3.6 - -#define SHA512_256_DIGEST_LENGTH 32 - -// SHA512_256_Init initialises |sha| and returns 1. -OPENSSL_EXPORT int SHA512_256_Init(SHA512_CTX *sha); - -// SHA512_256_Update adds |len| bytes from |data| to |sha| and returns 1. -OPENSSL_EXPORT int SHA512_256_Update(SHA512_CTX *sha, const void *data, - size_t len); - -// SHA512_256_Final adds the final padding to |sha| and writes the resulting -// digest to |out|, which must have at least |SHA512_256_DIGEST_LENGTH| bytes of -// space. It returns one on success and zero on programmer error. -OPENSSL_EXPORT int SHA512_256_Final(uint8_t out[SHA512_256_DIGEST_LENGTH], - SHA512_CTX *sha); - -// SHA512_256 writes the digest of |len| bytes from |data| to |out| and returns -// |out|. There must be at least |SHA512_256_DIGEST_LENGTH| bytes of space in -// |out|. -OPENSSL_EXPORT uint8_t *SHA512_256(const uint8_t *data, size_t len, - uint8_t out[SHA512_256_DIGEST_LENGTH]); - - #if defined(__cplusplus) } // extern C #endif diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_sha2.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_sha2.h new file mode 100644 index 000000000..e05626055 --- /dev/null +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_sha2.h @@ -0,0 +1,184 @@ +// Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef OPENSSL_HEADER_SHA2_H +#define OPENSSL_HEADER_SHA2_H + +#include "CCryptoBoringSSL_base.h" // IWYU pragma: export +#include "CCryptoBoringSSL_bcm_public.h" // IWYU pragma: export + +#if defined(__cplusplus) +extern "C" { +#endif + + +// SHA-224. + +// SHA224_CBLOCK is the block size of SHA-224. +#define SHA224_CBLOCK 64 + +// SHA224_DIGEST_LENGTH is the length of a SHA-224 digest. +#define SHA224_DIGEST_LENGTH 28 + +// SHA224_Init initialises |sha| and returns 1. +OPENSSL_EXPORT int SHA224_Init(SHA256_CTX *sha); + +// SHA224_Update adds |len| bytes from |data| to |sha| and returns 1. +OPENSSL_EXPORT int SHA224_Update(SHA256_CTX *sha, const void *data, size_t len); + +// SHA224_Final adds the final padding to |sha| and writes the resulting digest +// to |out|, which must have at least |SHA224_DIGEST_LENGTH| bytes of space. It +// returns 1. +OPENSSL_EXPORT int SHA224_Final(uint8_t out[SHA224_DIGEST_LENGTH], + SHA256_CTX *sha); + +// SHA224 writes the digest of |len| bytes from |data| to |out| and returns +// |out|. There must be at least |SHA224_DIGEST_LENGTH| bytes of space in +// |out|. +OPENSSL_EXPORT uint8_t *SHA224(const uint8_t *data, size_t len, + uint8_t out[SHA224_DIGEST_LENGTH]); + + +// SHA-256. + +// SHA256_CBLOCK is the block size of SHA-256. +#define SHA256_CBLOCK 64 + +// SHA256_DIGEST_LENGTH is the length of a SHA-256 digest. +#define SHA256_DIGEST_LENGTH 32 + +// SHA256_Init initialises |sha| and returns 1. +OPENSSL_EXPORT int SHA256_Init(SHA256_CTX *sha); + +// SHA256_Update adds |len| bytes from |data| to |sha| and returns 1. +OPENSSL_EXPORT int SHA256_Update(SHA256_CTX *sha, const void *data, size_t len); + +// SHA256_Final adds the final padding to |sha| and writes the resulting digest +// to |out|, which must have at least |SHA256_DIGEST_LENGTH| bytes of space. It +// returns one on success and zero on programmer error. +OPENSSL_EXPORT int SHA256_Final(uint8_t out[SHA256_DIGEST_LENGTH], + SHA256_CTX *sha); + +// SHA256 writes the digest of |len| bytes from |data| to |out| and returns +// |out|. There must be at least |SHA256_DIGEST_LENGTH| bytes of space in +// |out|. +OPENSSL_EXPORT uint8_t *SHA256(const uint8_t *data, size_t len, + uint8_t out[SHA256_DIGEST_LENGTH]); + +// SHA256_Transform is a low-level function that performs a single, SHA-256 +// block transformation using the state from |sha| and |SHA256_CBLOCK| bytes +// from |block|. +OPENSSL_EXPORT void SHA256_Transform(SHA256_CTX *sha, + const uint8_t block[SHA256_CBLOCK]); + +// SHA256_TransformBlocks is a low-level function that takes |num_blocks| * +// |SHA256_CBLOCK| bytes of data and performs SHA-256 transforms on it to update +// |state|. You should not use this function unless you are implementing a +// derivative of SHA-256. +OPENSSL_EXPORT void SHA256_TransformBlocks(uint32_t state[8], + const uint8_t *data, + size_t num_blocks); + + +// SHA-384. + +// SHA384_CBLOCK is the block size of SHA-384. +#define SHA384_CBLOCK 128 + +// SHA384_DIGEST_LENGTH is the length of a SHA-384 digest. +#define SHA384_DIGEST_LENGTH 48 + +// SHA384_Init initialises |sha| and returns 1. +OPENSSL_EXPORT int SHA384_Init(SHA512_CTX *sha); + +// SHA384_Update adds |len| bytes from |data| to |sha| and returns 1. +OPENSSL_EXPORT int SHA384_Update(SHA512_CTX *sha, const void *data, size_t len); + +// SHA384_Final adds the final padding to |sha| and writes the resulting digest +// to |out|, which must have at least |SHA384_DIGEST_LENGTH| bytes of space. It +// returns one on success and zero on programmer error. +OPENSSL_EXPORT int SHA384_Final(uint8_t out[SHA384_DIGEST_LENGTH], + SHA512_CTX *sha); + +// SHA384 writes the digest of |len| bytes from |data| to |out| and returns +// |out|. There must be at least |SHA384_DIGEST_LENGTH| bytes of space in +// |out|. +OPENSSL_EXPORT uint8_t *SHA384(const uint8_t *data, size_t len, + uint8_t out[SHA384_DIGEST_LENGTH]); + + +// SHA-512. + +// SHA512_CBLOCK is the block size of SHA-512. +#define SHA512_CBLOCK 128 + +// SHA512_DIGEST_LENGTH is the length of a SHA-512 digest. +#define SHA512_DIGEST_LENGTH 64 + +// SHA512_Init initialises |sha| and returns 1. +OPENSSL_EXPORT int SHA512_Init(SHA512_CTX *sha); + +// SHA512_Update adds |len| bytes from |data| to |sha| and returns 1. +OPENSSL_EXPORT int SHA512_Update(SHA512_CTX *sha, const void *data, size_t len); + +// SHA512_Final adds the final padding to |sha| and writes the resulting digest +// to |out|, which must have at least |SHA512_DIGEST_LENGTH| bytes of space. It +// returns one on success and zero on programmer error. +OPENSSL_EXPORT int SHA512_Final(uint8_t out[SHA512_DIGEST_LENGTH], + SHA512_CTX *sha); + +// SHA512 writes the digest of |len| bytes from |data| to |out| and returns +// |out|. There must be at least |SHA512_DIGEST_LENGTH| bytes of space in +// |out|. +OPENSSL_EXPORT uint8_t *SHA512(const uint8_t *data, size_t len, + uint8_t out[SHA512_DIGEST_LENGTH]); + +// SHA512_Transform is a low-level function that performs a single, SHA-512 +// block transformation using the state from |sha| and |SHA512_CBLOCK| bytes +// from |block|. +OPENSSL_EXPORT void SHA512_Transform(SHA512_CTX *sha, + const uint8_t block[SHA512_CBLOCK]); + + +// SHA-512-256 +// +// See https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf section 5.3.6 + +#define SHA512_256_DIGEST_LENGTH 32 + +// SHA512_256_Init initialises |sha| and returns 1. +OPENSSL_EXPORT int SHA512_256_Init(SHA512_CTX *sha); + +// SHA512_256_Update adds |len| bytes from |data| to |sha| and returns 1. +OPENSSL_EXPORT int SHA512_256_Update(SHA512_CTX *sha, const void *data, + size_t len); + +// SHA512_256_Final adds the final padding to |sha| and writes the resulting +// digest to |out|, which must have at least |SHA512_256_DIGEST_LENGTH| bytes of +// space. It returns one on success and zero on programmer error. +OPENSSL_EXPORT int SHA512_256_Final(uint8_t out[SHA512_256_DIGEST_LENGTH], + SHA512_CTX *sha); + +// SHA512_256 writes the digest of |len| bytes from |data| to |out| and returns +// |out|. There must be at least |SHA512_256_DIGEST_LENGTH| bytes of space in +// |out|. +OPENSSL_EXPORT uint8_t *SHA512_256(const uint8_t *data, size_t len, + uint8_t out[SHA512_256_DIGEST_LENGTH]); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_SHA2_H diff --git a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_x509.h b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_x509.h index 42f385cab..21cba29e1 100644 --- a/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_x509.h +++ b/Sources/CCryptoBoringSSL/include/CCryptoBoringSSL_x509.h @@ -34,7 +34,7 @@ #include "CCryptoBoringSSL_pkcs7.h" #include "CCryptoBoringSSL_pool.h" #include "CCryptoBoringSSL_rsa.h" -#include "CCryptoBoringSSL_sha.h" +#include "CCryptoBoringSSL_sha2.h" #include "CCryptoBoringSSL_stack.h" #include "CCryptoBoringSSL_x509v3_errors.h" // IWYU pragma: export @@ -88,9 +88,8 @@ OPENSSL_EXPORT STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain); // |i2d_X509_AUX|) are not preserved. Additionally, if |x509| is incomplete, // this function may fail. // -// TODO(https://crbug.com/boringssl/407): This function should be const and -// thread-safe but is currently neither in some cases, notably if |crl| was -// mutated. +// TODO(crbug.com/42290269): This function should be const and thread-safe but +// is currently neither in some cases, notably if |crl| was mutated. OPENSSL_EXPORT X509 *X509_dup(X509 *x509); // X509_free decrements |x509|'s reference count and, if zero, releases memory @@ -101,18 +100,27 @@ OPENSSL_EXPORT void X509_free(X509 *x509); // Certificate (RFC 5280), as described in |d2i_SAMPLE|. OPENSSL_EXPORT X509 *d2i_X509(X509 **out, const uint8_t **inp, long len); -// X509_parse_from_buffer parses an X.509 structure from |buf| and returns a +// X509_parse_with_algorithms parses an X.509 structure from |buf| and returns a // fresh X509 or NULL on error. There must not be any trailing data in |buf|. -// The returned structure (if any) holds a reference to |buf| rather than -// copying parts of it as a normal |d2i_X509| call would do. +// The returned structure (if any) increment's |buf|'s reference count and +// retains a reference to it. +// +// Only the |num_algs| algorithms from |algs| will be considered when parsing +// the certificate's public key. If the certificate uses a different algorithm, +// it will still be parsed, but |X509_get0_pubkey| will return NULL. +OPENSSL_EXPORT X509 *X509_parse_with_algorithms(CRYPTO_BUFFER *buf, + const EVP_PKEY_ALG *const *algs, + size_t num_algs); + +// X509_parse_from_buffer behaves like |X509_parse_with_algorithms| but uses a +// default algorithm list. OPENSSL_EXPORT X509 *X509_parse_from_buffer(CRYPTO_BUFFER *buf); // i2d_X509 marshals |x509| as a DER-encoded X.509 Certificate (RFC 5280), as // described in |i2d_SAMPLE|. // -// TODO(https://crbug.com/boringssl/407): This function should be const and -// thread-safe but is currently neither in some cases, notably if |x509| was -// mutated. +// TODO(crbug.com/42290269): This function should be const and thread-safe but +// is currently neither in some cases, notably if |x509| was mutated. OPENSSL_EXPORT int i2d_X509(X509 *x509, uint8_t **outp); // X509_VERSION_* are X.509 version numbers. Note the numerical values of all @@ -429,8 +437,8 @@ OPENSSL_EXPORT void X509_email_free(STACK_OF(OPENSSL_STRING) *sk); // as equal. This function should only be used with |X509| objects that were // parsed from bytes and never mutated. // -// TODO(https://crbug.com/boringssl/407): This function is const, but it is not -// always thread-safe, notably if |a| and |b| were mutated. +// TODO(crbug.com/42290269): This function is const, but it is not always +// thread-safe, notably if |a| and |b| were mutated. OPENSSL_EXPORT int X509_cmp(const X509 *a, const X509 *b); @@ -564,7 +572,7 @@ OPENSSL_EXPORT int X509_set1_signature_value(X509 *x509, const uint8_t *sig, // ASN.1 element. Directly embedding the output in a larger ASN.1 structure will // not behave correctly. // -// TODO(crbug.com/boringssl/407): |x509| should be const. +// TODO(crbug.com/42290269): |x509| should be const. OPENSSL_EXPORT int i2d_X509_AUX(X509 *x509, uint8_t **outp); // d2i_X509_AUX parses up to |length| bytes from |*inp| as a DER-encoded X.509 @@ -675,9 +683,8 @@ OPENSSL_EXPORT int X509_CRL_up_ref(X509_CRL *crl); // function works by serializing the structure, so if |crl| is incomplete, it // may fail. // -// TODO(https://crbug.com/boringssl/407): This function should be const and -// thread-safe but is currently neither in some cases, notably if |crl| was -// mutated. +// TODO(crbug.com/42290269): This function should be const and thread-safe but +// is currently neither in some cases, notably if |crl| was mutated. OPENSSL_EXPORT X509_CRL *X509_CRL_dup(X509_CRL *crl); // X509_CRL_free decrements |crl|'s reference count and, if zero, releases @@ -692,9 +699,8 @@ OPENSSL_EXPORT X509_CRL *d2i_X509_CRL(X509_CRL **out, const uint8_t **inp, // i2d_X509_CRL marshals |crl| as a X.509 CertificateList (RFC 5280), as // described in |i2d_SAMPLE|. // -// TODO(https://crbug.com/boringssl/407): This function should be const and -// thread-safe but is currently neither in some cases, notably if |crl| was -// mutated. +// TODO(crbug.com/42290269): This function should be const and thread-safe but +// is currently neither in some cases, notably if |crl| was mutated. OPENSSL_EXPORT int i2d_X509_CRL(X509_CRL *crl, uint8_t **outp); // X509_CRL_match compares |a| and |b| and returns zero if they are equal, a @@ -1068,9 +1074,8 @@ OPENSSL_EXPORT int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, // function works by serializing the structure, so if |req| is incomplete, it // may fail. // -// TODO(https://crbug.com/boringssl/407): This function should be const and -// thread-safe but is currently neither in some cases, notably if |req| was -// mutated. +// TODO(crbug.com/42290269): This function should be const and thread-safe but +// is currently neither in some cases, notably if |req| was mutated. OPENSSL_EXPORT X509_REQ *X509_REQ_dup(X509_REQ *req); // X509_REQ_free releases memory associated with |req|. @@ -1084,9 +1089,8 @@ OPENSSL_EXPORT X509_REQ *d2i_X509_REQ(X509_REQ **out, const uint8_t **inp, // i2d_X509_REQ marshals |req| as a CertificateRequest (RFC 2986), as described // in |i2d_SAMPLE|. // -// TODO(https://crbug.com/boringssl/407): This function should be const and -// thread-safe but is currently neither in some cases, notably if |req| was -// mutated. +// TODO(crbug.com/42290269): This function should be const and thread-safe but +// is currently neither in some cases, notably if |req| was mutated. OPENSSL_EXPORT int i2d_X509_REQ(X509_REQ *req, uint8_t **outp); // X509_REQ_VERSION_1 is the version constant for |X509_REQ| objects. No other @@ -1352,24 +1356,22 @@ OPENSSL_EXPORT X509_NAME *d2i_X509_NAME(X509_NAME **out, const uint8_t **inp, // i2d_X509_NAME marshals |in| as a DER-encoded X.509 Name (RFC 5280), as // described in |i2d_SAMPLE|. // -// TODO(https://crbug.com/boringssl/407): This function should be const and -// thread-safe but is currently neither in some cases, notably if |in| was -// mutated. +// TODO(crbug.com/42290269): This function should be const and thread-safe but +// is currently neither in some cases, notably if |in| was mutated. OPENSSL_EXPORT int i2d_X509_NAME(X509_NAME *in, uint8_t **outp); // X509_NAME_dup returns a newly-allocated copy of |name|, or NULL on error. // -// TODO(https://crbug.com/boringssl/407): This function should be const and -// thread-safe but is currently neither in some cases, notably if |name| was -// mutated. +// TODO(crbug.com/42290269): This function should be const and thread-safe but +// is currently neither in some cases, notably if |name| was mutated. OPENSSL_EXPORT X509_NAME *X509_NAME_dup(X509_NAME *name); // X509_NAME_cmp compares |a| and |b|'s canonicalized forms. It returns zero if // they are equal, one if |a| sorts after |b|, -1 if |b| sorts after |a|, and -2 // on error. // -// TODO(https://crbug.com/boringssl/407): This function is const, but it is not -// always thread-safe, notably if |name| was mutated. +// TODO(crbug.com/42290269): This function is const, but it is not always +// thread-safe, notably if |name| was mutated. // // TODO(https://crbug.com/boringssl/355): The -2 return is very inconvenient to // pass to a sorting function. Can we make this infallible? In the meantime, @@ -1386,17 +1388,15 @@ OPENSSL_EXPORT int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b); // Avoid this function and prefer |i2d_X509_NAME|. It is one of the reasons // |X509_NAME| functions, including this one, are not consistently thread-safe // or const-correct. Depending on the resolution of -// https://crbug.com/boringssl/407, this function may be removed or cause poor -// performance. +// crbug.com/42290269, this function may be removed or cause poor performance. OPENSSL_EXPORT int X509_NAME_get0_der(X509_NAME *name, const uint8_t **out_der, size_t *out_der_len); // X509_NAME_set makes a copy of |name|. On success, it frees |*xn|, sets |*xn| // to the copy, and returns one. Otherwise, it returns zero. // -// TODO(https://crbug.com/boringssl/407): This function should be const and -// thread-safe but is currently neither in some cases, notably if |name| was -// mutated. +// TODO(crbug.com/42290269): This function should be const and thread-safe but +// is currently neither in some cases, notably if |name| was mutated. OPENSSL_EXPORT int X509_NAME_set(X509_NAME **xn, X509_NAME *name); // X509_NAME_entry_count returns the number of entries in |name|. @@ -2093,18 +2093,18 @@ OPENSSL_EXPORT GENERAL_NAME *d2i_GENERAL_NAME(GENERAL_NAME **out, // i2d_GENERAL_NAME marshals |in| as a DER-encoded X.509 GeneralName (RFC 5280), // as described in |i2d_SAMPLE|. // -// TODO(https://crbug.com/boringssl/407): This function should be const and -// thread-safe but is currently neither in some cases, notably if |in| is an -// directoryName and the |X509_NAME| has been modified. +// TODO(crbug.com/42290269): This function should be const and thread-safe but +// is currently neither in some cases, notably if |in| is an directoryName and +// the |X509_NAME| has been modified. OPENSSL_EXPORT int i2d_GENERAL_NAME(GENERAL_NAME *in, uint8_t **outp); // GENERAL_NAME_dup returns a newly-allocated copy of |gen|, or NULL on error. // This function works by serializing the structure, so it will fail if |gen| is // empty. // -// TODO(https://crbug.com/boringssl/407): This function should be const and -// thread-safe but is currently neither in some cases, notably if |gen| is an -// directoryName and the |X509_NAME| has been modified. +// TODO(crbug.com/42290269): This function should be const and thread-safe but +// is currently neither in some cases, notably if |gen| is an directoryName and +// the |X509_NAME| has been modified. OPENSSL_EXPORT GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *gen); // GENERAL_NAMES_new returns a new, empty |GENERAL_NAMES|, or NULL on error. @@ -2121,9 +2121,9 @@ OPENSSL_EXPORT GENERAL_NAMES *d2i_GENERAL_NAMES(GENERAL_NAMES **out, // i2d_GENERAL_NAMES marshals |in| as a DER-encoded SEQUENCE OF GeneralName, as // described in |i2d_SAMPLE|. // -// TODO(https://crbug.com/boringssl/407): This function should be const and -// thread-safe but is currently neither in some cases, notably if some element -// of |in| is an directoryName and the |X509_NAME| has been modified. +// TODO(crbug.com/42290269): This function should be const and thread-safe but +// is currently neither in some cases, notably if some element of |in| is an +// directoryName and the |X509_NAME| has been modified. OPENSSL_EXPORT int i2d_GENERAL_NAMES(GENERAL_NAMES *in, uint8_t **outp); // OTHERNAME_new returns a new, empty |OTHERNAME|, or NULL on error. @@ -2229,8 +2229,8 @@ OPENSSL_EXPORT AUTHORITY_KEYID *d2i_AUTHORITY_KEYID(AUTHORITY_KEYID **out, // i2d_AUTHORITY_KEYID marshals |akid| as a DER-encoded AuthorityKeyIdentifier // (RFC 5280), as described in |i2d_SAMPLE|. // -// TODO(https://crbug.com/boringssl/407): |akid| is not const because it -// contains an |X509_NAME|. +// TODO(crbug.com/42290269): |akid| is not const because it contains an +// |X509_NAME|. OPENSSL_EXPORT int i2d_AUTHORITY_KEYID(AUTHORITY_KEYID *akid, uint8_t **outp); @@ -2322,8 +2322,8 @@ OPENSSL_EXPORT AUTHORITY_INFO_ACCESS *d2i_AUTHORITY_INFO_ACCESS( // i2d_AUTHORITY_INFO_ACCESS marshals |aia| as a DER-encoded // AuthorityInfoAccessSyntax (RFC 5280), as described in |i2d_SAMPLE|. // -// TODO(https://crbug.com/boringssl/407): |aia| is not const because it -// contains an |X509_NAME|. +// TODO(crbug.com/42290269): |aia| is not const because it contains an +// |X509_NAME|. OPENSSL_EXPORT int i2d_AUTHORITY_INFO_ACCESS(AUTHORITY_INFO_ACCESS *aia, uint8_t **outp); @@ -2397,8 +2397,8 @@ OPENSSL_EXPORT CRL_DIST_POINTS *d2i_CRL_DIST_POINTS(CRL_DIST_POINTS **out, // i2d_CRL_DIST_POINTS marshals |crldp| as a DER-encoded CRLDistributionPoints // (RFC 5280), as described in |i2d_SAMPLE|. // -// TODO(https://crbug.com/boringssl/407): |crldp| is not const because it -// contains an |X509_NAME|. +// TODO(crbug.com/42290269): |crldp| is not const because it contains an +// |X509_NAME|. OPENSSL_EXPORT int i2d_CRL_DIST_POINTS(CRL_DIST_POINTS *crldp, uint8_t **outp); // A ISSUING_DIST_POINT_st, aka |ISSUING_DIST_POINT|, represents a @@ -2431,8 +2431,8 @@ OPENSSL_EXPORT ISSUING_DIST_POINT *d2i_ISSUING_DIST_POINT( // i2d_ISSUING_DIST_POINT marshals |idp| as a DER-encoded // IssuingDistributionPoint (RFC 5280), as described in |i2d_SAMPLE|. // -// TODO(https://crbug.com/boringssl/407): |idp| is not const because it -// contains an |X509_NAME|. +// TODO(crbug.com/42290269): |idp| is not const because it contains an +// |X509_NAME|. OPENSSL_EXPORT int i2d_ISSUING_DIST_POINT(ISSUING_DIST_POINT *idp, uint8_t **outp); @@ -2597,6 +2597,10 @@ OPENSSL_EXPORT X509_ALGOR *X509_ALGOR_new(void); // it may fail. OPENSSL_EXPORT X509_ALGOR *X509_ALGOR_dup(const X509_ALGOR *alg); +// X509_ALGOR_copy sets |dst| to a copy of the contents of |src|. It returns one +// on success and zero on error. +OPENSSL_EXPORT int X509_ALGOR_copy(X509_ALGOR *dst, const X509_ALGOR *src); + // X509_ALGOR_free releases memory associated with |alg|. OPENSSL_EXPORT void X509_ALGOR_free(X509_ALGOR *alg); @@ -3705,9 +3709,8 @@ OPENSSL_EXPORT int X509_load_cert_crl_file(X509_LOOKUP *lookup, // there will be hash collisions. It also depends on an OpenSSL-specific // canonicalization process. // -// TODO(https://crbug.com/boringssl/407): This should be const and thread-safe -// but currently is neither, notably if |name| was modified from its parsed -// value. +// TODO(crbug.com/42290269): This should be const and thread-safe but currently +// is neither, notably if |name| was modified from its parsed value. OPENSSL_EXPORT uint32_t X509_NAME_hash(X509_NAME *name); // X509_NAME_hash_old returns a hash of |name|, or zero on error. This is the @@ -3718,9 +3721,8 @@ OPENSSL_EXPORT uint32_t X509_NAME_hash(X509_NAME *name); // not suitable for general-purpose X.509 name processing. It is very short, so // there will be hash collisions. // -// TODO(https://crbug.com/boringssl/407): This should be const and thread-safe -// but currently is neither, notably if |name| was modified from its parsed -// value. +// TODO(crbug.com/42290269): This should be const and thread-safe but currently +// is neither, notably if |name| was modified from its parsed value. OPENSSL_EXPORT uint32_t X509_NAME_hash_old(X509_NAME *name); // X509_STORE_set_default_paths configures |store| to read from some "default" @@ -4439,6 +4441,9 @@ OPENSSL_EXPORT int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b); // not suitable for general-purpose X.509 name processing. It is very short, so // there will be hash collisions. It also depends on an OpenSSL-specific // canonicalization process. +// +// TODO(crbug.com/42290269): This should be const and thread-safe but currently +// is neither, notably if |x509| was modified from its parsed value. OPENSSL_EXPORT uint32_t X509_issuer_name_hash(X509 *x509); // X509_subject_name_hash returns the hash of |x509|'s subject name with @@ -4448,6 +4453,9 @@ OPENSSL_EXPORT uint32_t X509_issuer_name_hash(X509 *x509); // not suitable for general-purpose X.509 name processing. It is very short, so // there will be hash collisions. It also depends on an OpenSSL-specific // canonicalization process. +// +// TODO(crbug.com/42290269): This should be const and thread-safe but currently +// is neither, notably if |x509| was modified from its parsed value. OPENSSL_EXPORT uint32_t X509_subject_name_hash(X509 *x509); // X509_issuer_name_hash_old returns the hash of |x509|'s issuer name with @@ -4456,6 +4464,9 @@ OPENSSL_EXPORT uint32_t X509_subject_name_hash(X509 *x509); // This hash is specific to the |X509_LOOKUP_add_dir| filesystem format and is // not suitable for general-purpose X.509 name processing. It is very short, so // there will be hash collisions. +// +// TODO(crbug.com/42290269): This should be const and thread-safe but currently +// is neither, notably if |x509| was modified from its parsed value. OPENSSL_EXPORT uint32_t X509_issuer_name_hash_old(X509 *x509); // X509_subject_name_hash_old returns the hash of |x509|'s usjbect name with @@ -4464,6 +4475,9 @@ OPENSSL_EXPORT uint32_t X509_issuer_name_hash_old(X509 *x509); // This hash is specific to the |X509_LOOKUP_add_dir| filesystem format and is // not suitable for general-purpose X.509 name processing. It is very short, so // there will be hash collisions. +// +// TODO(crbug.com/42290269): This should be const and thread-safe but currently +// is neither, notably if |x509| was modified from its parsed value. OPENSSL_EXPORT uint32_t X509_subject_name_hash_old(X509 *x509); @@ -4535,6 +4549,9 @@ OPENSSL_EXPORT int ASN1_item_verify(const ASN1_ITEM *it, // |md|, or |pkey|'s default if NULL. Other signing parameters use |pkey|'s // defaults. To customize them, use |ASN1_item_sign_ctx|. // +// |algor1| and |algor2| may point into part of |asn| and will be updated before +// |asn| is serialized. +// // WARNING: |data| must be a pointer with the same type as |it|'s corresponding // C type. Using the wrong type is a potentially exploitable memory error. OPENSSL_EXPORT int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, @@ -4550,6 +4567,9 @@ OPENSSL_EXPORT int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, // On success or failure, this function mutates |ctx| and resets it to the empty // state. Caller should not rely on its contents after the function returns. // +// |algor1| and |algor2| may point into part of |asn| and will be updated before +// |asn| is serialized. +// // WARNING: |data| must be a pointer with the same type as |it|'s corresponding // C type. Using the wrong type is a potentially exploitable memory error. OPENSSL_EXPORT int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, @@ -4582,7 +4602,7 @@ OPENSSL_EXPORT int X509_supported_extension(const X509_EXTENSION *ex); // This function returning one does not indicate that |x509| is trusted, only // that it is eligible to be a CA. // -// TODO(crbug.com/boringssl/407): |x509| should be const. +// TODO(crbug.com/42290269): |x509| should be const. OPENSSL_EXPORT int X509_check_ca(X509 *x509); // X509_check_issued checks if |issuer| and |subject|'s name, authority key @@ -4593,13 +4613,13 @@ OPENSSL_EXPORT int X509_check_ca(X509 *x509); // intended to prune the set of possible issuer certificates during // path-building. // -// TODO(crbug.com/boringssl/407): Both parameters should be const. +// TODO(crbug.com/42290269): Both parameters should be const. OPENSSL_EXPORT int X509_check_issued(X509 *issuer, X509 *subject); // NAME_CONSTRAINTS_check checks if |x509| satisfies name constraints in |nc|. // It returns |X509_V_OK| on success and some |X509_V_ERR_*| constant on error. // -// TODO(crbug.com/boringssl/407): Both parameters should be const. +// TODO(crbug.com/42290269): Both parameters should be const. OPENSSL_EXPORT int NAME_CONSTRAINTS_check(X509 *x509, NAME_CONSTRAINTS *nc); // X509_check_host checks if |x509| matches the DNS name |chk|. It returns one @@ -4679,7 +4699,7 @@ OPENSSL_EXPORT int X509_check_ip_asc(const X509 *x509, const char *ipasc, // This function only searches for trusted issuers. It does not consider // untrusted intermediates passed in to |X509_STORE_CTX_init|. // -// TODO(crbug.com/boringssl/407): |x509| should be const. +// TODO(crbug.com/42290269): |x509| should be const. OPENSSL_EXPORT int X509_STORE_CTX_get1_issuer(X509 **out_issuer, X509_STORE_CTX *ctx, X509 *x509); @@ -4713,7 +4733,7 @@ OPENSSL_EXPORT int X509_check_trust(X509 *x509, int id, int flags); // NULL on error. The caller must release the result with |sk_X509_pop_free| and // |X509_free| when done. // -// TODO(crbug.com/boringssl/407): |name| should be const. +// TODO(crbug.com/42290269): |name| should be const. OPENSSL_EXPORT STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *ctx, X509_NAME *name); @@ -4722,7 +4742,7 @@ OPENSSL_EXPORT STACK_OF(X509) *X509_STORE_CTX_get1_certs(X509_STORE_CTX *ctx, // The caller must release the result with |sk_X509_CRL_pop_free| and // |X509_CRL_free| when done. // -// TODO(crbug.com/boringssl/407): |name| should be const. +// TODO(crbug.com/42290269): |name| should be const. OPENSSL_EXPORT STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(X509_STORE_CTX *ctx, X509_NAME *name); @@ -4740,7 +4760,7 @@ OPENSSL_EXPORT STACK_OF(X509_CRL) *X509_STORE_CTX_get1_crls(X509_STORE_CTX *ctx, // case, this function returns an arbitrary match. Use // |X509_STORE_CTX_get1_certs| or |X509_STORE_CTX_get1_crls| instead. // -// TODO(crbug.com/boringssl/407): |name| should be const. +// TODO(crbug.com/42290269): |name| should be const. OPENSSL_EXPORT int X509_STORE_CTX_get_by_subject(X509_STORE_CTX *ctx, int type, X509_NAME *name, X509_OBJECT *ret); diff --git a/Sources/CCryptoBoringSSL/include/boringssl_prefix_symbols_nasm.inc b/Sources/CCryptoBoringSSL/include/boringssl_prefix_symbols_nasm.inc index cf0a13e6f..5368abb76 100644 --- a/Sources/CCryptoBoringSSL/include/boringssl_prefix_symbols_nasm.inc +++ b/Sources/CCryptoBoringSSL/include/boringssl_prefix_symbols_nasm.inc @@ -162,8 +162,12 @@ %xdefine _ASN1_item_sign_ctx _ %+ BORINGSSL_PREFIX %+ _ASN1_item_sign_ctx %xdefine _ASN1_item_unpack _ %+ BORINGSSL_PREFIX %+ _ASN1_item_unpack %xdefine _ASN1_item_verify _ %+ BORINGSSL_PREFIX %+ _ASN1_item_verify +%xdefine _asn1_marshal_any _ %+ BORINGSSL_PREFIX %+ _asn1_marshal_any %xdefine _asn1_marshal_bit_string _ %+ BORINGSSL_PREFIX %+ _asn1_marshal_bit_string %xdefine _asn1_marshal_integer _ %+ BORINGSSL_PREFIX %+ _asn1_marshal_integer +%xdefine _asn1_marshal_object _ %+ BORINGSSL_PREFIX %+ _asn1_marshal_object +%xdefine _asn1_marshal_octet_string _ %+ BORINGSSL_PREFIX %+ _asn1_marshal_octet_string +%xdefine _asn1_marshal_time _ %+ BORINGSSL_PREFIX %+ _asn1_marshal_time %xdefine _ASN1_mbstring_copy _ %+ BORINGSSL_PREFIX %+ _ASN1_mbstring_copy %xdefine _ASN1_mbstring_ncopy _ %+ BORINGSSL_PREFIX %+ _ASN1_mbstring_ncopy %xdefine _ASN1_NULL_free _ %+ BORINGSSL_PREFIX %+ _ASN1_NULL_free @@ -180,6 +184,20 @@ %xdefine _ASN1_OCTET_STRING_it _ %+ BORINGSSL_PREFIX %+ _ASN1_OCTET_STRING_it %xdefine _ASN1_OCTET_STRING_new _ %+ BORINGSSL_PREFIX %+ _ASN1_OCTET_STRING_new %xdefine _ASN1_OCTET_STRING_set _ %+ BORINGSSL_PREFIX %+ _ASN1_OCTET_STRING_set +%xdefine _asn1_parse_any _ %+ BORINGSSL_PREFIX %+ _asn1_parse_any +%xdefine _asn1_parse_any_as_string _ %+ BORINGSSL_PREFIX %+ _asn1_parse_any_as_string +%xdefine _asn1_parse_bit_string _ %+ BORINGSSL_PREFIX %+ _asn1_parse_bit_string +%xdefine _asn1_parse_bit_string_with_bad_length _ %+ BORINGSSL_PREFIX %+ _asn1_parse_bit_string_with_bad_length +%xdefine _asn1_parse_bmp_string _ %+ BORINGSSL_PREFIX %+ _asn1_parse_bmp_string +%xdefine _asn1_parse_enumerated _ %+ BORINGSSL_PREFIX %+ _asn1_parse_enumerated +%xdefine _asn1_parse_generalized_time _ %+ BORINGSSL_PREFIX %+ _asn1_parse_generalized_time +%xdefine _asn1_parse_integer _ %+ BORINGSSL_PREFIX %+ _asn1_parse_integer +%xdefine _asn1_parse_object _ %+ BORINGSSL_PREFIX %+ _asn1_parse_object +%xdefine _asn1_parse_octet_string _ %+ BORINGSSL_PREFIX %+ _asn1_parse_octet_string +%xdefine _asn1_parse_time _ %+ BORINGSSL_PREFIX %+ _asn1_parse_time +%xdefine _asn1_parse_universal_string _ %+ BORINGSSL_PREFIX %+ _asn1_parse_universal_string +%xdefine _asn1_parse_utc_time _ %+ BORINGSSL_PREFIX %+ _asn1_parse_utc_time +%xdefine _asn1_parse_utf8_string _ %+ BORINGSSL_PREFIX %+ _asn1_parse_utf8_string %xdefine _ASN1_primitive_free _ %+ BORINGSSL_PREFIX %+ _ASN1_primitive_free %xdefine _ASN1_PRINTABLESTRING_free _ %+ BORINGSSL_PREFIX %+ _ASN1_PRINTABLESTRING_free %xdefine _ASN1_PRINTABLESTRING_it _ %+ BORINGSSL_PREFIX %+ _ASN1_PRINTABLESTRING_it @@ -190,6 +208,7 @@ %xdefine _asn1_refcount_set_one _ %+ BORINGSSL_PREFIX %+ _asn1_refcount_set_one %xdefine _ASN1_SEQUENCE_it _ %+ BORINGSSL_PREFIX %+ _ASN1_SEQUENCE_it %xdefine _asn1_set_choice_selector _ %+ BORINGSSL_PREFIX %+ _asn1_set_choice_selector +%xdefine _asn1_string_cleanup _ %+ BORINGSSL_PREFIX %+ _asn1_string_cleanup %xdefine _ASN1_STRING_cmp _ %+ BORINGSSL_PREFIX %+ _ASN1_STRING_cmp %xdefine _ASN1_STRING_copy _ %+ BORINGSSL_PREFIX %+ _ASN1_STRING_copy %xdefine _ASN1_STRING_data _ %+ BORINGSSL_PREFIX %+ _ASN1_STRING_data @@ -197,6 +216,7 @@ %xdefine _ASN1_STRING_free _ %+ BORINGSSL_PREFIX %+ _ASN1_STRING_free %xdefine _ASN1_STRING_get_default_mask _ %+ BORINGSSL_PREFIX %+ _ASN1_STRING_get_default_mask %xdefine _ASN1_STRING_get0_data _ %+ BORINGSSL_PREFIX %+ _ASN1_STRING_get0_data +%xdefine _asn1_string_init _ %+ BORINGSSL_PREFIX %+ _asn1_string_init %xdefine _ASN1_STRING_length _ %+ BORINGSSL_PREFIX %+ _ASN1_STRING_length %xdefine _ASN1_STRING_new _ %+ BORINGSSL_PREFIX %+ _ASN1_STRING_new %xdefine _ASN1_STRING_print _ %+ BORINGSSL_PREFIX %+ _ASN1_STRING_print @@ -277,6 +297,26 @@ %xdefine _bcm_as_approved_status _ %+ BORINGSSL_PREFIX %+ _bcm_as_approved_status %xdefine _bcm_as_not_approved_status _ %+ BORINGSSL_PREFIX %+ _bcm_as_not_approved_status %xdefine _BCM_fips_186_2_prf _ %+ BORINGSSL_PREFIX %+ _BCM_fips_186_2_prf +%xdefine _BCM_mldsa44_check_key_fips _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_check_key_fips +%xdefine _BCM_mldsa44_generate_key _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_generate_key +%xdefine _BCM_mldsa44_generate_key_external_entropy _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_generate_key_external_entropy +%xdefine _BCM_mldsa44_generate_key_external_entropy_fips _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_generate_key_external_entropy_fips +%xdefine _BCM_mldsa44_generate_key_fips _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_generate_key_fips +%xdefine _BCM_mldsa44_marshal_private_key _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_marshal_private_key +%xdefine _BCM_mldsa44_marshal_public_key _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_marshal_public_key +%xdefine _BCM_mldsa44_parse_private_key _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_parse_private_key +%xdefine _BCM_mldsa44_parse_public_key _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_parse_public_key +%xdefine _BCM_mldsa44_prehash_finalize _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_prehash_finalize +%xdefine _BCM_mldsa44_prehash_init _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_prehash_init +%xdefine _BCM_mldsa44_prehash_update _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_prehash_update +%xdefine _BCM_mldsa44_private_key_from_seed _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_private_key_from_seed +%xdefine _BCM_mldsa44_private_key_from_seed_fips _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_private_key_from_seed_fips +%xdefine _BCM_mldsa44_public_from_private _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_public_from_private +%xdefine _BCM_mldsa44_sign _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_sign +%xdefine _BCM_mldsa44_sign_internal _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_sign_internal +%xdefine _BCM_mldsa44_sign_message_representative _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_sign_message_representative +%xdefine _BCM_mldsa44_verify _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_verify +%xdefine _BCM_mldsa44_verify_internal _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa44_verify_internal %xdefine _BCM_mldsa65_check_key_fips _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa65_check_key_fips %xdefine _BCM_mldsa65_generate_key _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa65_generate_key %xdefine _BCM_mldsa65_generate_key_external_entropy _ %+ BORINGSSL_PREFIX %+ _BCM_mldsa65_generate_key_external_entropy @@ -627,9 +667,9 @@ %xdefine _bn_mul_comba4 _ %+ BORINGSSL_PREFIX %+ _bn_mul_comba4 %xdefine _bn_mul_comba8 _ %+ BORINGSSL_PREFIX %+ _bn_mul_comba8 %xdefine _bn_mul_consttime _ %+ BORINGSSL_PREFIX %+ _bn_mul_consttime -%xdefine _bn_mul_mont _ %+ BORINGSSL_PREFIX %+ _bn_mul_mont %xdefine _bn_mul_mont_gather5_nohw _ %+ BORINGSSL_PREFIX %+ _bn_mul_mont_gather5_nohw %xdefine _bn_mul_mont_nohw _ %+ BORINGSSL_PREFIX %+ _bn_mul_mont_nohw +%xdefine _bn_mul_mont_words _ %+ BORINGSSL_PREFIX %+ _bn_mul_mont_words %xdefine _bn_mul_small _ %+ BORINGSSL_PREFIX %+ _bn_mul_small %xdefine _BN_mul_word _ %+ BORINGSSL_PREFIX %+ _BN_mul_word %xdefine _bn_mul_words _ %+ BORINGSSL_PREFIX %+ _bn_mul_words @@ -877,6 +917,7 @@ %xdefine _CMS_sign _ %+ BORINGSSL_PREFIX %+ _CMS_sign %xdefine _CONF_modules_free _ %+ BORINGSSL_PREFIX %+ _CONF_modules_free %xdefine _CONF_modules_load_file _ %+ BORINGSSL_PREFIX %+ _CONF_modules_load_file +%xdefine _CONF_modules_unload _ %+ BORINGSSL_PREFIX %+ _CONF_modules_unload %xdefine _CONF_parse_list _ %+ BORINGSSL_PREFIX %+ _CONF_parse_list %xdefine _CONF_VALUE_new _ %+ BORINGSSL_PREFIX %+ _CONF_VALUE_new %xdefine _CRL_DIST_POINTS_free _ %+ BORINGSSL_PREFIX %+ _CRL_DIST_POINTS_free @@ -1011,7 +1052,9 @@ %xdefine _CTR_DRBG_generate _ %+ BORINGSSL_PREFIX %+ _CTR_DRBG_generate %xdefine _CTR_DRBG_init _ %+ BORINGSSL_PREFIX %+ _CTR_DRBG_init %xdefine _CTR_DRBG_new _ %+ BORINGSSL_PREFIX %+ _CTR_DRBG_new +%xdefine _CTR_DRBG_new_df _ %+ BORINGSSL_PREFIX %+ _CTR_DRBG_new_df %xdefine _CTR_DRBG_reseed _ %+ BORINGSSL_PREFIX %+ _CTR_DRBG_reseed +%xdefine _CTR_DRBG_reseed_ex _ %+ BORINGSSL_PREFIX %+ _CTR_DRBG_reseed_ex %xdefine _d2i_ASN1_BIT_STRING _ %+ BORINGSSL_PREFIX %+ _d2i_ASN1_BIT_STRING %xdefine _d2i_ASN1_BMPSTRING _ %+ BORINGSSL_PREFIX %+ _d2i_ASN1_BMPSTRING %xdefine _d2i_ASN1_BOOLEAN _ %+ BORINGSSL_PREFIX %+ _d2i_ASN1_BOOLEAN @@ -1102,7 +1145,6 @@ %xdefine _d2i_X509_AUX _ %+ BORINGSSL_PREFIX %+ _d2i_X509_AUX %xdefine _d2i_X509_bio _ %+ BORINGSSL_PREFIX %+ _d2i_X509_bio %xdefine _d2i_X509_CERT_AUX _ %+ BORINGSSL_PREFIX %+ _d2i_X509_CERT_AUX -%xdefine _d2i_X509_CINF _ %+ BORINGSSL_PREFIX %+ _d2i_X509_CINF %xdefine _d2i_X509_CRL _ %+ BORINGSSL_PREFIX %+ _d2i_X509_CRL %xdefine _d2i_X509_CRL_bio _ %+ BORINGSSL_PREFIX %+ _d2i_X509_CRL_bio %xdefine _d2i_X509_CRL_fp _ %+ BORINGSSL_PREFIX %+ _d2i_X509_CRL_fp @@ -1118,7 +1160,6 @@ %xdefine _d2i_X509_REQ_INFO _ %+ BORINGSSL_PREFIX %+ _d2i_X509_REQ_INFO %xdefine _d2i_X509_REVOKED _ %+ BORINGSSL_PREFIX %+ _d2i_X509_REVOKED %xdefine _d2i_X509_SIG _ %+ BORINGSSL_PREFIX %+ _d2i_X509_SIG -%xdefine _d2i_X509_VAL _ %+ BORINGSSL_PREFIX %+ _d2i_X509_VAL %xdefine _DES_decrypt3 _ %+ BORINGSSL_PREFIX %+ _DES_decrypt3 %xdefine _DES_ecb_encrypt _ %+ BORINGSSL_PREFIX %+ _DES_ecb_encrypt %xdefine _DES_ecb_encrypt_ex _ %+ BORINGSSL_PREFIX %+ _DES_ecb_encrypt_ex @@ -1326,8 +1367,11 @@ %xdefine _EC_KEY_new_method _ %+ BORINGSSL_PREFIX %+ _EC_KEY_new_method %xdefine _EC_KEY_oct2key _ %+ BORINGSSL_PREFIX %+ _EC_KEY_oct2key %xdefine _EC_KEY_oct2priv _ %+ BORINGSSL_PREFIX %+ _EC_KEY_oct2priv +%xdefine _ec_key_parse_curve_name _ %+ BORINGSSL_PREFIX %+ _ec_key_parse_curve_name %xdefine _EC_KEY_parse_curve_name _ %+ BORINGSSL_PREFIX %+ _EC_KEY_parse_curve_name +%xdefine _ec_key_parse_parameters _ %+ BORINGSSL_PREFIX %+ _ec_key_parse_parameters %xdefine _EC_KEY_parse_parameters _ %+ BORINGSSL_PREFIX %+ _EC_KEY_parse_parameters +%xdefine _ec_key_parse_private_key _ %+ BORINGSSL_PREFIX %+ _ec_key_parse_private_key %xdefine _EC_KEY_parse_private_key _ %+ BORINGSSL_PREFIX %+ _EC_KEY_parse_private_key %xdefine _EC_KEY_priv2buf _ %+ BORINGSSL_PREFIX %+ _EC_KEY_priv2buf %xdefine _EC_KEY_priv2oct _ %+ BORINGSSL_PREFIX %+ _EC_KEY_priv2oct @@ -1462,6 +1506,7 @@ %xdefine _ED25519_verify _ %+ BORINGSSL_PREFIX %+ _ED25519_verify %xdefine _EDIPARTYNAME_free _ %+ BORINGSSL_PREFIX %+ _EDIPARTYNAME_free %xdefine _EDIPARTYNAME_new _ %+ BORINGSSL_PREFIX %+ _EDIPARTYNAME_new +%xdefine _ENGINE_cleanup _ %+ BORINGSSL_PREFIX %+ _ENGINE_cleanup %xdefine _ENGINE_free _ %+ BORINGSSL_PREFIX %+ _ENGINE_free %xdefine _ENGINE_get_ECDSA_method _ %+ BORINGSSL_PREFIX %+ _ENGINE_get_ECDSA_method %xdefine _ENGINE_get_RSA_method _ %+ BORINGSSL_PREFIX %+ _ENGINE_get_RSA_method @@ -1474,6 +1519,7 @@ %xdefine _ERR_add_error_dataf _ %+ BORINGSSL_PREFIX %+ _ERR_add_error_dataf %xdefine _ERR_clear_error _ %+ BORINGSSL_PREFIX %+ _ERR_clear_error %xdefine _ERR_clear_system_error _ %+ BORINGSSL_PREFIX %+ _ERR_clear_system_error +%xdefine _ERR_equals _ %+ BORINGSSL_PREFIX %+ _ERR_equals %xdefine _ERR_error_string _ %+ BORINGSSL_PREFIX %+ _ERR_error_string %xdefine _ERR_error_string_n _ %+ BORINGSSL_PREFIX %+ _ERR_error_string_n %xdefine _ERR_free_strings _ %+ BORINGSSL_PREFIX %+ _ERR_free_strings @@ -1700,6 +1746,7 @@ %xdefine _EVP_HPKE_KEY_zero _ %+ BORINGSSL_PREFIX %+ _EVP_HPKE_KEY_zero %xdefine _EVP_hpke_p256_hkdf_sha256 _ %+ BORINGSSL_PREFIX %+ _EVP_hpke_p256_hkdf_sha256 %xdefine _EVP_hpke_x25519_hkdf_sha256 _ %+ BORINGSSL_PREFIX %+ _EVP_hpke_x25519_hkdf_sha256 +%xdefine _EVP_hpke_xwing _ %+ BORINGSSL_PREFIX %+ _EVP_hpke_xwing %xdefine _EVP_marshal_digest_algorithm _ %+ BORINGSSL_PREFIX %+ _EVP_marshal_digest_algorithm %xdefine _EVP_marshal_digest_algorithm_no_params _ %+ BORINGSSL_PREFIX %+ _EVP_marshal_digest_algorithm_no_params %xdefine _EVP_marshal_private_key _ %+ BORINGSSL_PREFIX %+ _EVP_marshal_private_key @@ -1731,6 +1778,7 @@ %xdefine _EVP_md5 _ %+ BORINGSSL_PREFIX %+ _EVP_md5 %xdefine _EVP_md5_sha1 _ %+ BORINGSSL_PREFIX %+ _EVP_md5_sha1 %xdefine _EVP_parse_digest_algorithm _ %+ BORINGSSL_PREFIX %+ _EVP_parse_digest_algorithm +%xdefine _EVP_parse_digest_algorithm_nid _ %+ BORINGSSL_PREFIX %+ _EVP_parse_digest_algorithm_nid %xdefine _EVP_parse_private_key _ %+ BORINGSSL_PREFIX %+ _EVP_parse_private_key %xdefine _EVP_parse_public_key _ %+ BORINGSSL_PREFIX %+ _EVP_parse_public_key %xdefine _EVP_PBE_scrypt _ %+ BORINGSSL_PREFIX %+ _EVP_PBE_scrypt @@ -1783,9 +1831,21 @@ %xdefine _EVP_PKEY_derive _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_derive %xdefine _EVP_PKEY_derive_init _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_derive_init %xdefine _EVP_PKEY_derive_set_peer _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_derive_set_peer +%xdefine _EVP_pkey_dsa _ %+ BORINGSSL_PREFIX %+ _EVP_pkey_dsa +%xdefine _EVP_pkey_ec_p224 _ %+ BORINGSSL_PREFIX %+ _EVP_pkey_ec_p224 +%xdefine _EVP_pkey_ec_p256 _ %+ BORINGSSL_PREFIX %+ _EVP_pkey_ec_p256 +%xdefine _EVP_pkey_ec_p384 _ %+ BORINGSSL_PREFIX %+ _EVP_pkey_ec_p384 +%xdefine _EVP_pkey_ec_p521 _ %+ BORINGSSL_PREFIX %+ _EVP_pkey_ec_p521 +%xdefine _EVP_pkey_ed25519 _ %+ BORINGSSL_PREFIX %+ _EVP_pkey_ed25519 %xdefine _EVP_PKEY_encrypt _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_encrypt %xdefine _EVP_PKEY_encrypt_init _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_encrypt_init %xdefine _EVP_PKEY_free _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_free +%xdefine _EVP_PKEY_from_private_key_info _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_from_private_key_info +%xdefine _EVP_PKEY_from_raw_private_key _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_from_raw_private_key +%xdefine _EVP_PKEY_from_raw_public_key _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_from_raw_public_key +%xdefine _EVP_PKEY_from_subject_public_key_info _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_from_subject_public_key_info +%xdefine _EVP_PKEY_get_ec_curve_nid _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_get_ec_curve_nid +%xdefine _EVP_PKEY_get_ec_point_conv_form _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_get_ec_point_conv_form %xdefine _EVP_PKEY_get_raw_private_key _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_get_raw_private_key %xdefine _EVP_PKEY_get_raw_public_key _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_get_raw_public_key %xdefine _EVP_PKEY_get0 _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_get0 @@ -1811,8 +1871,10 @@ %xdefine _EVP_PKEY_print_params _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_print_params %xdefine _EVP_PKEY_print_private _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_print_private %xdefine _EVP_PKEY_print_public _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_print_public -%xdefine _evp_pkey_set_method _ %+ BORINGSSL_PREFIX %+ _evp_pkey_set_method +%xdefine _EVP_pkey_rsa _ %+ BORINGSSL_PREFIX %+ _EVP_pkey_rsa +%xdefine _EVP_pkey_rsa_pss_sha256 _ %+ BORINGSSL_PREFIX %+ _EVP_pkey_rsa_pss_sha256 %xdefine _EVP_PKEY_set_type _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_set_type +%xdefine _evp_pkey_set0 _ %+ BORINGSSL_PREFIX %+ _evp_pkey_set0 %xdefine _EVP_PKEY_set1_DH _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_set1_DH %xdefine _EVP_PKEY_set1_DSA _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_set1_DSA %xdefine _EVP_PKEY_set1_EC_KEY _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_set1_EC_KEY @@ -1827,6 +1889,7 @@ %xdefine _EVP_PKEY_verify_init _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_verify_init %xdefine _EVP_PKEY_verify_recover _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_verify_recover %xdefine _EVP_PKEY_verify_recover_init _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY_verify_recover_init +%xdefine _EVP_pkey_x25519 _ %+ BORINGSSL_PREFIX %+ _EVP_pkey_x25519 %xdefine _EVP_PKEY2PKCS8 _ %+ BORINGSSL_PREFIX %+ _EVP_PKEY2PKCS8 %xdefine _EVP_rc2_40_cbc _ %+ BORINGSSL_PREFIX %+ _EVP_rc2_40_cbc %xdefine _EVP_rc2_cbc _ %+ BORINGSSL_PREFIX %+ _EVP_rc2_cbc @@ -1863,6 +1926,8 @@ %xdefine _FIPS_module_name _ %+ BORINGSSL_PREFIX %+ _FIPS_module_name %xdefine _FIPS_query_algorithm_status _ %+ BORINGSSL_PREFIX %+ _FIPS_query_algorithm_status %xdefine _FIPS_read_counter _ %+ BORINGSSL_PREFIX %+ _FIPS_read_counter +%xdefine _FIPS_service_indicator_after_call _ %+ BORINGSSL_PREFIX %+ _FIPS_service_indicator_after_call +%xdefine _FIPS_service_indicator_before_call _ %+ BORINGSSL_PREFIX %+ _FIPS_service_indicator_before_call %xdefine _FIPS_version _ %+ BORINGSSL_PREFIX %+ _FIPS_version %xdefine _gcm_ghash_avx _ %+ BORINGSSL_PREFIX %+ _gcm_ghash_avx %xdefine _gcm_ghash_clmul _ %+ BORINGSSL_PREFIX %+ _gcm_ghash_clmul @@ -2038,7 +2103,6 @@ %xdefine _i2d_X509_AUX _ %+ BORINGSSL_PREFIX %+ _i2d_X509_AUX %xdefine _i2d_X509_bio _ %+ BORINGSSL_PREFIX %+ _i2d_X509_bio %xdefine _i2d_X509_CERT_AUX _ %+ BORINGSSL_PREFIX %+ _i2d_X509_CERT_AUX -%xdefine _i2d_X509_CINF _ %+ BORINGSSL_PREFIX %+ _i2d_X509_CINF %xdefine _i2d_X509_CRL _ %+ BORINGSSL_PREFIX %+ _i2d_X509_CRL %xdefine _i2d_X509_CRL_bio _ %+ BORINGSSL_PREFIX %+ _i2d_X509_CRL_bio %xdefine _i2d_X509_CRL_fp _ %+ BORINGSSL_PREFIX %+ _i2d_X509_CRL_fp @@ -2056,7 +2120,6 @@ %xdefine _i2d_X509_REVOKED _ %+ BORINGSSL_PREFIX %+ _i2d_X509_REVOKED %xdefine _i2d_X509_SIG _ %+ BORINGSSL_PREFIX %+ _i2d_X509_SIG %xdefine _i2d_X509_tbs _ %+ BORINGSSL_PREFIX %+ _i2d_X509_tbs -%xdefine _i2d_X509_VAL _ %+ BORINGSSL_PREFIX %+ _i2d_X509_VAL %xdefine _i2o_ECPublicKey _ %+ BORINGSSL_PREFIX %+ _i2o_ECPublicKey %xdefine _i2s_ASN1_ENUMERATED _ %+ BORINGSSL_PREFIX %+ _i2s_ASN1_ENUMERATED %xdefine _i2s_ASN1_INTEGER _ %+ BORINGSSL_PREFIX %+ _i2s_ASN1_INTEGER @@ -2120,6 +2183,17 @@ %xdefine _MD5_Update _ %+ BORINGSSL_PREFIX %+ _MD5_Update %xdefine _METHOD_ref _ %+ BORINGSSL_PREFIX %+ _METHOD_ref %xdefine _METHOD_unref _ %+ BORINGSSL_PREFIX %+ _METHOD_unref +%xdefine _MLDSA44_generate_key _ %+ BORINGSSL_PREFIX %+ _MLDSA44_generate_key +%xdefine _MLDSA44_marshal_public_key _ %+ BORINGSSL_PREFIX %+ _MLDSA44_marshal_public_key +%xdefine _MLDSA44_parse_public_key _ %+ BORINGSSL_PREFIX %+ _MLDSA44_parse_public_key +%xdefine _MLDSA44_prehash_finalize _ %+ BORINGSSL_PREFIX %+ _MLDSA44_prehash_finalize +%xdefine _MLDSA44_prehash_init _ %+ BORINGSSL_PREFIX %+ _MLDSA44_prehash_init +%xdefine _MLDSA44_prehash_update _ %+ BORINGSSL_PREFIX %+ _MLDSA44_prehash_update +%xdefine _MLDSA44_private_key_from_seed _ %+ BORINGSSL_PREFIX %+ _MLDSA44_private_key_from_seed +%xdefine _MLDSA44_public_from_private _ %+ BORINGSSL_PREFIX %+ _MLDSA44_public_from_private +%xdefine _MLDSA44_sign _ %+ BORINGSSL_PREFIX %+ _MLDSA44_sign +%xdefine _MLDSA44_sign_message_representative _ %+ BORINGSSL_PREFIX %+ _MLDSA44_sign_message_representative +%xdefine _MLDSA44_verify _ %+ BORINGSSL_PREFIX %+ _MLDSA44_verify %xdefine _MLDSA65_generate_key _ %+ BORINGSSL_PREFIX %+ _MLDSA65_generate_key %xdefine _MLDSA65_marshal_public_key _ %+ BORINGSSL_PREFIX %+ _MLDSA65_marshal_public_key %xdefine _MLDSA65_parse_public_key _ %+ BORINGSSL_PREFIX %+ _MLDSA65_parse_public_key @@ -2517,6 +2591,7 @@ %xdefine _rsa_invalidate_key _ %+ BORINGSSL_PREFIX %+ _rsa_invalidate_key %xdefine _RSA_is_opaque _ %+ BORINGSSL_PREFIX %+ _RSA_is_opaque %xdefine _RSA_marshal_private_key _ %+ BORINGSSL_PREFIX %+ _RSA_marshal_private_key +%xdefine _rsa_marshal_pss_params _ %+ BORINGSSL_PREFIX %+ _rsa_marshal_pss_params %xdefine _RSA_marshal_public_key _ %+ BORINGSSL_PREFIX %+ _RSA_marshal_public_key %xdefine _RSA_new _ %+ BORINGSSL_PREFIX %+ _RSA_new %xdefine _RSA_new_method _ %+ BORINGSSL_PREFIX %+ _RSA_new_method @@ -2534,6 +2609,7 @@ %xdefine _RSA_padding_check_PKCS1_OAEP_mgf1 _ %+ BORINGSSL_PREFIX %+ _RSA_padding_check_PKCS1_OAEP_mgf1 %xdefine _RSA_padding_check_PKCS1_type_1 _ %+ BORINGSSL_PREFIX %+ _RSA_padding_check_PKCS1_type_1 %xdefine _RSA_parse_private_key _ %+ BORINGSSL_PREFIX %+ _RSA_parse_private_key +%xdefine _rsa_parse_pss_params _ %+ BORINGSSL_PREFIX %+ _rsa_parse_pss_params %xdefine _RSA_parse_public_key _ %+ BORINGSSL_PREFIX %+ _RSA_parse_public_key %xdefine _rsa_pkey_meth _ %+ BORINGSSL_PREFIX %+ _rsa_pkey_meth %xdefine _RSA_print _ %+ BORINGSSL_PREFIX %+ _RSA_print @@ -2544,8 +2620,11 @@ %xdefine _rsa_private_transform _ %+ BORINGSSL_PREFIX %+ _rsa_private_transform %xdefine _rsa_private_transform_no_self_test _ %+ BORINGSSL_PREFIX %+ _rsa_private_transform_no_self_test %xdefine _RSA_PSS_PARAMS_free _ %+ BORINGSSL_PREFIX %+ _RSA_PSS_PARAMS_free +%xdefine _rsa_pss_params_get_md _ %+ BORINGSSL_PREFIX %+ _rsa_pss_params_get_md %xdefine _RSA_PSS_PARAMS_it _ %+ BORINGSSL_PREFIX %+ _RSA_PSS_PARAMS_it %xdefine _RSA_PSS_PARAMS_new _ %+ BORINGSSL_PREFIX %+ _RSA_PSS_PARAMS_new +%xdefine _rsa_pss_sha256_asn1_meth _ %+ BORINGSSL_PREFIX %+ _rsa_pss_sha256_asn1_meth +%xdefine _rsa_pss_sha256_pkey_meth _ %+ BORINGSSL_PREFIX %+ _rsa_pss_sha256_pkey_meth %xdefine _RSA_public_decrypt _ %+ BORINGSSL_PREFIX %+ _RSA_public_decrypt %xdefine _RSA_public_encrypt _ %+ BORINGSSL_PREFIX %+ _RSA_public_encrypt %xdefine _RSA_public_key_from_bytes _ %+ BORINGSSL_PREFIX %+ _RSA_public_key_from_bytes @@ -2995,10 +3074,13 @@ %xdefine _X509_add1_ext_i2d _ %+ BORINGSSL_PREFIX %+ _X509_add1_ext_i2d %xdefine _X509_add1_reject_object _ %+ BORINGSSL_PREFIX %+ _X509_add1_reject_object %xdefine _X509_add1_trust_object _ %+ BORINGSSL_PREFIX %+ _X509_add1_trust_object +%xdefine _x509_algor_cleanup _ %+ BORINGSSL_PREFIX %+ _x509_algor_cleanup %xdefine _X509_ALGOR_cmp _ %+ BORINGSSL_PREFIX %+ _X509_ALGOR_cmp +%xdefine _X509_ALGOR_copy _ %+ BORINGSSL_PREFIX %+ _X509_ALGOR_copy %xdefine _X509_ALGOR_dup _ %+ BORINGSSL_PREFIX %+ _X509_ALGOR_dup %xdefine _X509_ALGOR_free _ %+ BORINGSSL_PREFIX %+ _X509_ALGOR_free %xdefine _X509_ALGOR_get0 _ %+ BORINGSSL_PREFIX %+ _X509_ALGOR_get0 +%xdefine _x509_algor_init _ %+ BORINGSSL_PREFIX %+ _x509_algor_init %xdefine _X509_ALGOR_it _ %+ BORINGSSL_PREFIX %+ _X509_ALGOR_it %xdefine _X509_ALGOR_new _ %+ BORINGSSL_PREFIX %+ _X509_ALGOR_new %xdefine _X509_ALGOR_set_md _ %+ BORINGSSL_PREFIX %+ _X509_ALGOR_set_md @@ -3035,9 +3117,6 @@ %xdefine _X509_check_private_key _ %+ BORINGSSL_PREFIX %+ _X509_check_private_key %xdefine _X509_check_purpose _ %+ BORINGSSL_PREFIX %+ _X509_check_purpose %xdefine _X509_check_trust _ %+ BORINGSSL_PREFIX %+ _X509_check_trust -%xdefine _X509_CINF_free _ %+ BORINGSSL_PREFIX %+ _X509_CINF_free -%xdefine _X509_CINF_it _ %+ BORINGSSL_PREFIX %+ _X509_CINF_it -%xdefine _X509_CINF_new _ %+ BORINGSSL_PREFIX %+ _X509_CINF_new %xdefine _X509_cmp _ %+ BORINGSSL_PREFIX %+ _X509_cmp %xdefine _X509_cmp_current_time _ %+ BORINGSSL_PREFIX %+ _X509_cmp_current_time %xdefine _X509_cmp_time _ %+ BORINGSSL_PREFIX %+ _X509_cmp_time @@ -3173,6 +3252,8 @@ %xdefine _X509_LOOKUP_load_file _ %+ BORINGSSL_PREFIX %+ _X509_LOOKUP_load_file %xdefine _x509_marshal_algorithm _ %+ BORINGSSL_PREFIX %+ _x509_marshal_algorithm %xdefine _x509_marshal_name _ %+ BORINGSSL_PREFIX %+ _x509_marshal_name +%xdefine _x509_marshal_public_key _ %+ BORINGSSL_PREFIX %+ _x509_marshal_public_key +%xdefine _x509_marshal_tbs_cert _ %+ BORINGSSL_PREFIX %+ _x509_marshal_tbs_cert %xdefine _X509_NAME_add_entry _ %+ BORINGSSL_PREFIX %+ _X509_NAME_add_entry %xdefine _X509_NAME_add_entry_by_NID _ %+ BORINGSSL_PREFIX %+ _X509_NAME_add_entry_by_NID %xdefine _X509_NAME_add_entry_by_OBJ _ %+ BORINGSSL_PREFIX %+ _X509_NAME_add_entry_by_OBJ @@ -3216,23 +3297,29 @@ %xdefine _X509_OBJECT_get_type _ %+ BORINGSSL_PREFIX %+ _X509_OBJECT_get_type %xdefine _X509_OBJECT_get0_X509 _ %+ BORINGSSL_PREFIX %+ _X509_OBJECT_get0_X509 %xdefine _X509_OBJECT_new _ %+ BORINGSSL_PREFIX %+ _X509_OBJECT_new +%xdefine _x509_parse_algorithm _ %+ BORINGSSL_PREFIX %+ _x509_parse_algorithm %xdefine _X509_parse_from_buffer _ %+ BORINGSSL_PREFIX %+ _X509_parse_from_buffer +%xdefine _x509_parse_public_key _ %+ BORINGSSL_PREFIX %+ _x509_parse_public_key +%xdefine _X509_parse_with_algorithms _ %+ BORINGSSL_PREFIX %+ _X509_parse_with_algorithms %xdefine _X509_policy_check _ %+ BORINGSSL_PREFIX %+ _X509_policy_check %xdefine _X509_print _ %+ BORINGSSL_PREFIX %+ _X509_print %xdefine _X509_print_ex _ %+ BORINGSSL_PREFIX %+ _X509_print_ex %xdefine _X509_print_ex_fp _ %+ BORINGSSL_PREFIX %+ _X509_print_ex_fp %xdefine _X509_print_fp _ %+ BORINGSSL_PREFIX %+ _X509_print_fp %xdefine _x509_print_rsa_pss_params _ %+ BORINGSSL_PREFIX %+ _x509_print_rsa_pss_params +%xdefine _x509_pubkey_cleanup _ %+ BORINGSSL_PREFIX %+ _x509_pubkey_cleanup %xdefine _X509_pubkey_digest _ %+ BORINGSSL_PREFIX %+ _X509_pubkey_digest %xdefine _X509_PUBKEY_free _ %+ BORINGSSL_PREFIX %+ _X509_PUBKEY_free %xdefine _X509_PUBKEY_get _ %+ BORINGSSL_PREFIX %+ _X509_PUBKEY_get %xdefine _X509_PUBKEY_get0 _ %+ BORINGSSL_PREFIX %+ _X509_PUBKEY_get0 %xdefine _X509_PUBKEY_get0_param _ %+ BORINGSSL_PREFIX %+ _X509_PUBKEY_get0_param %xdefine _X509_PUBKEY_get0_public_key _ %+ BORINGSSL_PREFIX %+ _X509_PUBKEY_get0_public_key +%xdefine _x509_pubkey_init _ %+ BORINGSSL_PREFIX %+ _x509_pubkey_init %xdefine _X509_PUBKEY_it _ %+ BORINGSSL_PREFIX %+ _X509_PUBKEY_it %xdefine _X509_PUBKEY_new _ %+ BORINGSSL_PREFIX %+ _X509_PUBKEY_new %xdefine _X509_PUBKEY_set _ %+ BORINGSSL_PREFIX %+ _X509_PUBKEY_set %xdefine _X509_PUBKEY_set0_param _ %+ BORINGSSL_PREFIX %+ _X509_PUBKEY_set0_param +%xdefine _x509_pubkey_set1 _ %+ BORINGSSL_PREFIX %+ _x509_pubkey_set1 %xdefine _X509_PURPOSE_get_by_sname _ %+ BORINGSSL_PREFIX %+ _X509_PURPOSE_get_by_sname %xdefine _X509_PURPOSE_get_id _ %+ BORINGSSL_PREFIX %+ _X509_PURPOSE_get_id %xdefine _X509_PURPOSE_get_trust _ %+ BORINGSSL_PREFIX %+ _X509_PURPOSE_get_trust @@ -3316,6 +3403,7 @@ %xdefine _X509_SIG_new _ %+ BORINGSSL_PREFIX %+ _X509_SIG_new %xdefine _X509_sign _ %+ BORINGSSL_PREFIX %+ _X509_sign %xdefine _X509_sign_ctx _ %+ BORINGSSL_PREFIX %+ _X509_sign_ctx +%xdefine _x509_sign_to_bit_string _ %+ BORINGSSL_PREFIX %+ _x509_sign_to_bit_string %xdefine _X509_signature_dump _ %+ BORINGSSL_PREFIX %+ _X509_signature_dump %xdefine _X509_signature_print _ %+ BORINGSSL_PREFIX %+ _X509_signature_print %xdefine _X509_STORE_add_cert _ %+ BORINGSSL_PREFIX %+ _X509_STORE_add_cert @@ -3380,9 +3468,6 @@ %xdefine _X509_time_adj_ex _ %+ BORINGSSL_PREFIX %+ _X509_time_adj_ex %xdefine _X509_trust_clear _ %+ BORINGSSL_PREFIX %+ _X509_trust_clear %xdefine _X509_up_ref _ %+ BORINGSSL_PREFIX %+ _X509_up_ref -%xdefine _X509_VAL_free _ %+ BORINGSSL_PREFIX %+ _X509_VAL_free -%xdefine _X509_VAL_it _ %+ BORINGSSL_PREFIX %+ _X509_VAL_it -%xdefine _X509_VAL_new _ %+ BORINGSSL_PREFIX %+ _X509_VAL_new %xdefine _X509_verify _ %+ BORINGSSL_PREFIX %+ _X509_verify %xdefine _X509_verify_cert _ %+ BORINGSSL_PREFIX %+ _X509_verify_cert %xdefine _X509_verify_cert_error_string _ %+ BORINGSSL_PREFIX %+ _X509_verify_cert_error_string @@ -3408,6 +3493,7 @@ %xdefine _X509_VERIFY_PARAM_set1_ip _ %+ BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_set1_ip %xdefine _X509_VERIFY_PARAM_set1_ip_asc _ %+ BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_set1_ip_asc %xdefine _X509_VERIFY_PARAM_set1_policies _ %+ BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_set1_policies +%xdefine _x509_verify_signature _ %+ BORINGSSL_PREFIX %+ _x509_verify_signature %xdefine _x509v3_a2i_ipadd _ %+ BORINGSSL_PREFIX %+ _x509v3_a2i_ipadd %xdefine _X509v3_add_ext _ %+ BORINGSSL_PREFIX %+ _X509v3_add_ext %xdefine _X509V3_add_standard_extensions _ %+ BORINGSSL_PREFIX %+ _X509V3_add_standard_extensions @@ -3609,8 +3695,12 @@ %xdefine ASN1_item_sign_ctx BORINGSSL_PREFIX %+ _ASN1_item_sign_ctx %xdefine ASN1_item_unpack BORINGSSL_PREFIX %+ _ASN1_item_unpack %xdefine ASN1_item_verify BORINGSSL_PREFIX %+ _ASN1_item_verify +%xdefine asn1_marshal_any BORINGSSL_PREFIX %+ _asn1_marshal_any %xdefine asn1_marshal_bit_string BORINGSSL_PREFIX %+ _asn1_marshal_bit_string %xdefine asn1_marshal_integer BORINGSSL_PREFIX %+ _asn1_marshal_integer +%xdefine asn1_marshal_object BORINGSSL_PREFIX %+ _asn1_marshal_object +%xdefine asn1_marshal_octet_string BORINGSSL_PREFIX %+ _asn1_marshal_octet_string +%xdefine asn1_marshal_time BORINGSSL_PREFIX %+ _asn1_marshal_time %xdefine ASN1_mbstring_copy BORINGSSL_PREFIX %+ _ASN1_mbstring_copy %xdefine ASN1_mbstring_ncopy BORINGSSL_PREFIX %+ _ASN1_mbstring_ncopy %xdefine ASN1_NULL_free BORINGSSL_PREFIX %+ _ASN1_NULL_free @@ -3627,6 +3717,20 @@ %xdefine ASN1_OCTET_STRING_it BORINGSSL_PREFIX %+ _ASN1_OCTET_STRING_it %xdefine ASN1_OCTET_STRING_new BORINGSSL_PREFIX %+ _ASN1_OCTET_STRING_new %xdefine ASN1_OCTET_STRING_set BORINGSSL_PREFIX %+ _ASN1_OCTET_STRING_set +%xdefine asn1_parse_any BORINGSSL_PREFIX %+ _asn1_parse_any +%xdefine asn1_parse_any_as_string BORINGSSL_PREFIX %+ _asn1_parse_any_as_string +%xdefine asn1_parse_bit_string BORINGSSL_PREFIX %+ _asn1_parse_bit_string +%xdefine asn1_parse_bit_string_with_bad_length BORINGSSL_PREFIX %+ _asn1_parse_bit_string_with_bad_length +%xdefine asn1_parse_bmp_string BORINGSSL_PREFIX %+ _asn1_parse_bmp_string +%xdefine asn1_parse_enumerated BORINGSSL_PREFIX %+ _asn1_parse_enumerated +%xdefine asn1_parse_generalized_time BORINGSSL_PREFIX %+ _asn1_parse_generalized_time +%xdefine asn1_parse_integer BORINGSSL_PREFIX %+ _asn1_parse_integer +%xdefine asn1_parse_object BORINGSSL_PREFIX %+ _asn1_parse_object +%xdefine asn1_parse_octet_string BORINGSSL_PREFIX %+ _asn1_parse_octet_string +%xdefine asn1_parse_time BORINGSSL_PREFIX %+ _asn1_parse_time +%xdefine asn1_parse_universal_string BORINGSSL_PREFIX %+ _asn1_parse_universal_string +%xdefine asn1_parse_utc_time BORINGSSL_PREFIX %+ _asn1_parse_utc_time +%xdefine asn1_parse_utf8_string BORINGSSL_PREFIX %+ _asn1_parse_utf8_string %xdefine ASN1_primitive_free BORINGSSL_PREFIX %+ _ASN1_primitive_free %xdefine ASN1_PRINTABLESTRING_free BORINGSSL_PREFIX %+ _ASN1_PRINTABLESTRING_free %xdefine ASN1_PRINTABLESTRING_it BORINGSSL_PREFIX %+ _ASN1_PRINTABLESTRING_it @@ -3637,6 +3741,7 @@ %xdefine asn1_refcount_set_one BORINGSSL_PREFIX %+ _asn1_refcount_set_one %xdefine ASN1_SEQUENCE_it BORINGSSL_PREFIX %+ _ASN1_SEQUENCE_it %xdefine asn1_set_choice_selector BORINGSSL_PREFIX %+ _asn1_set_choice_selector +%xdefine asn1_string_cleanup BORINGSSL_PREFIX %+ _asn1_string_cleanup %xdefine ASN1_STRING_cmp BORINGSSL_PREFIX %+ _ASN1_STRING_cmp %xdefine ASN1_STRING_copy BORINGSSL_PREFIX %+ _ASN1_STRING_copy %xdefine ASN1_STRING_data BORINGSSL_PREFIX %+ _ASN1_STRING_data @@ -3644,6 +3749,7 @@ %xdefine ASN1_STRING_free BORINGSSL_PREFIX %+ _ASN1_STRING_free %xdefine ASN1_STRING_get_default_mask BORINGSSL_PREFIX %+ _ASN1_STRING_get_default_mask %xdefine ASN1_STRING_get0_data BORINGSSL_PREFIX %+ _ASN1_STRING_get0_data +%xdefine asn1_string_init BORINGSSL_PREFIX %+ _asn1_string_init %xdefine ASN1_STRING_length BORINGSSL_PREFIX %+ _ASN1_STRING_length %xdefine ASN1_STRING_new BORINGSSL_PREFIX %+ _ASN1_STRING_new %xdefine ASN1_STRING_print BORINGSSL_PREFIX %+ _ASN1_STRING_print @@ -3724,6 +3830,26 @@ %xdefine bcm_as_approved_status BORINGSSL_PREFIX %+ _bcm_as_approved_status %xdefine bcm_as_not_approved_status BORINGSSL_PREFIX %+ _bcm_as_not_approved_status %xdefine BCM_fips_186_2_prf BORINGSSL_PREFIX %+ _BCM_fips_186_2_prf +%xdefine BCM_mldsa44_check_key_fips BORINGSSL_PREFIX %+ _BCM_mldsa44_check_key_fips +%xdefine BCM_mldsa44_generate_key BORINGSSL_PREFIX %+ _BCM_mldsa44_generate_key +%xdefine BCM_mldsa44_generate_key_external_entropy BORINGSSL_PREFIX %+ _BCM_mldsa44_generate_key_external_entropy +%xdefine BCM_mldsa44_generate_key_external_entropy_fips BORINGSSL_PREFIX %+ _BCM_mldsa44_generate_key_external_entropy_fips +%xdefine BCM_mldsa44_generate_key_fips BORINGSSL_PREFIX %+ _BCM_mldsa44_generate_key_fips +%xdefine BCM_mldsa44_marshal_private_key BORINGSSL_PREFIX %+ _BCM_mldsa44_marshal_private_key +%xdefine BCM_mldsa44_marshal_public_key BORINGSSL_PREFIX %+ _BCM_mldsa44_marshal_public_key +%xdefine BCM_mldsa44_parse_private_key BORINGSSL_PREFIX %+ _BCM_mldsa44_parse_private_key +%xdefine BCM_mldsa44_parse_public_key BORINGSSL_PREFIX %+ _BCM_mldsa44_parse_public_key +%xdefine BCM_mldsa44_prehash_finalize BORINGSSL_PREFIX %+ _BCM_mldsa44_prehash_finalize +%xdefine BCM_mldsa44_prehash_init BORINGSSL_PREFIX %+ _BCM_mldsa44_prehash_init +%xdefine BCM_mldsa44_prehash_update BORINGSSL_PREFIX %+ _BCM_mldsa44_prehash_update +%xdefine BCM_mldsa44_private_key_from_seed BORINGSSL_PREFIX %+ _BCM_mldsa44_private_key_from_seed +%xdefine BCM_mldsa44_private_key_from_seed_fips BORINGSSL_PREFIX %+ _BCM_mldsa44_private_key_from_seed_fips +%xdefine BCM_mldsa44_public_from_private BORINGSSL_PREFIX %+ _BCM_mldsa44_public_from_private +%xdefine BCM_mldsa44_sign BORINGSSL_PREFIX %+ _BCM_mldsa44_sign +%xdefine BCM_mldsa44_sign_internal BORINGSSL_PREFIX %+ _BCM_mldsa44_sign_internal +%xdefine BCM_mldsa44_sign_message_representative BORINGSSL_PREFIX %+ _BCM_mldsa44_sign_message_representative +%xdefine BCM_mldsa44_verify BORINGSSL_PREFIX %+ _BCM_mldsa44_verify +%xdefine BCM_mldsa44_verify_internal BORINGSSL_PREFIX %+ _BCM_mldsa44_verify_internal %xdefine BCM_mldsa65_check_key_fips BORINGSSL_PREFIX %+ _BCM_mldsa65_check_key_fips %xdefine BCM_mldsa65_generate_key BORINGSSL_PREFIX %+ _BCM_mldsa65_generate_key %xdefine BCM_mldsa65_generate_key_external_entropy BORINGSSL_PREFIX %+ _BCM_mldsa65_generate_key_external_entropy @@ -4074,9 +4200,9 @@ %xdefine bn_mul_comba4 BORINGSSL_PREFIX %+ _bn_mul_comba4 %xdefine bn_mul_comba8 BORINGSSL_PREFIX %+ _bn_mul_comba8 %xdefine bn_mul_consttime BORINGSSL_PREFIX %+ _bn_mul_consttime -%xdefine bn_mul_mont BORINGSSL_PREFIX %+ _bn_mul_mont %xdefine bn_mul_mont_gather5_nohw BORINGSSL_PREFIX %+ _bn_mul_mont_gather5_nohw %xdefine bn_mul_mont_nohw BORINGSSL_PREFIX %+ _bn_mul_mont_nohw +%xdefine bn_mul_mont_words BORINGSSL_PREFIX %+ _bn_mul_mont_words %xdefine bn_mul_small BORINGSSL_PREFIX %+ _bn_mul_small %xdefine BN_mul_word BORINGSSL_PREFIX %+ _BN_mul_word %xdefine bn_mul_words BORINGSSL_PREFIX %+ _bn_mul_words @@ -4324,6 +4450,7 @@ %xdefine CMS_sign BORINGSSL_PREFIX %+ _CMS_sign %xdefine CONF_modules_free BORINGSSL_PREFIX %+ _CONF_modules_free %xdefine CONF_modules_load_file BORINGSSL_PREFIX %+ _CONF_modules_load_file +%xdefine CONF_modules_unload BORINGSSL_PREFIX %+ _CONF_modules_unload %xdefine CONF_parse_list BORINGSSL_PREFIX %+ _CONF_parse_list %xdefine CONF_VALUE_new BORINGSSL_PREFIX %+ _CONF_VALUE_new %xdefine CRL_DIST_POINTS_free BORINGSSL_PREFIX %+ _CRL_DIST_POINTS_free @@ -4458,7 +4585,9 @@ %xdefine CTR_DRBG_generate BORINGSSL_PREFIX %+ _CTR_DRBG_generate %xdefine CTR_DRBG_init BORINGSSL_PREFIX %+ _CTR_DRBG_init %xdefine CTR_DRBG_new BORINGSSL_PREFIX %+ _CTR_DRBG_new +%xdefine CTR_DRBG_new_df BORINGSSL_PREFIX %+ _CTR_DRBG_new_df %xdefine CTR_DRBG_reseed BORINGSSL_PREFIX %+ _CTR_DRBG_reseed +%xdefine CTR_DRBG_reseed_ex BORINGSSL_PREFIX %+ _CTR_DRBG_reseed_ex %xdefine d2i_ASN1_BIT_STRING BORINGSSL_PREFIX %+ _d2i_ASN1_BIT_STRING %xdefine d2i_ASN1_BMPSTRING BORINGSSL_PREFIX %+ _d2i_ASN1_BMPSTRING %xdefine d2i_ASN1_BOOLEAN BORINGSSL_PREFIX %+ _d2i_ASN1_BOOLEAN @@ -4549,7 +4678,6 @@ %xdefine d2i_X509_AUX BORINGSSL_PREFIX %+ _d2i_X509_AUX %xdefine d2i_X509_bio BORINGSSL_PREFIX %+ _d2i_X509_bio %xdefine d2i_X509_CERT_AUX BORINGSSL_PREFIX %+ _d2i_X509_CERT_AUX -%xdefine d2i_X509_CINF BORINGSSL_PREFIX %+ _d2i_X509_CINF %xdefine d2i_X509_CRL BORINGSSL_PREFIX %+ _d2i_X509_CRL %xdefine d2i_X509_CRL_bio BORINGSSL_PREFIX %+ _d2i_X509_CRL_bio %xdefine d2i_X509_CRL_fp BORINGSSL_PREFIX %+ _d2i_X509_CRL_fp @@ -4565,7 +4693,6 @@ %xdefine d2i_X509_REQ_INFO BORINGSSL_PREFIX %+ _d2i_X509_REQ_INFO %xdefine d2i_X509_REVOKED BORINGSSL_PREFIX %+ _d2i_X509_REVOKED %xdefine d2i_X509_SIG BORINGSSL_PREFIX %+ _d2i_X509_SIG -%xdefine d2i_X509_VAL BORINGSSL_PREFIX %+ _d2i_X509_VAL %xdefine DES_decrypt3 BORINGSSL_PREFIX %+ _DES_decrypt3 %xdefine DES_ecb_encrypt BORINGSSL_PREFIX %+ _DES_ecb_encrypt %xdefine DES_ecb_encrypt_ex BORINGSSL_PREFIX %+ _DES_ecb_encrypt_ex @@ -4773,8 +4900,11 @@ %xdefine EC_KEY_new_method BORINGSSL_PREFIX %+ _EC_KEY_new_method %xdefine EC_KEY_oct2key BORINGSSL_PREFIX %+ _EC_KEY_oct2key %xdefine EC_KEY_oct2priv BORINGSSL_PREFIX %+ _EC_KEY_oct2priv +%xdefine ec_key_parse_curve_name BORINGSSL_PREFIX %+ _ec_key_parse_curve_name %xdefine EC_KEY_parse_curve_name BORINGSSL_PREFIX %+ _EC_KEY_parse_curve_name +%xdefine ec_key_parse_parameters BORINGSSL_PREFIX %+ _ec_key_parse_parameters %xdefine EC_KEY_parse_parameters BORINGSSL_PREFIX %+ _EC_KEY_parse_parameters +%xdefine ec_key_parse_private_key BORINGSSL_PREFIX %+ _ec_key_parse_private_key %xdefine EC_KEY_parse_private_key BORINGSSL_PREFIX %+ _EC_KEY_parse_private_key %xdefine EC_KEY_priv2buf BORINGSSL_PREFIX %+ _EC_KEY_priv2buf %xdefine EC_KEY_priv2oct BORINGSSL_PREFIX %+ _EC_KEY_priv2oct @@ -4909,6 +5039,7 @@ %xdefine ED25519_verify BORINGSSL_PREFIX %+ _ED25519_verify %xdefine EDIPARTYNAME_free BORINGSSL_PREFIX %+ _EDIPARTYNAME_free %xdefine EDIPARTYNAME_new BORINGSSL_PREFIX %+ _EDIPARTYNAME_new +%xdefine ENGINE_cleanup BORINGSSL_PREFIX %+ _ENGINE_cleanup %xdefine ENGINE_free BORINGSSL_PREFIX %+ _ENGINE_free %xdefine ENGINE_get_ECDSA_method BORINGSSL_PREFIX %+ _ENGINE_get_ECDSA_method %xdefine ENGINE_get_RSA_method BORINGSSL_PREFIX %+ _ENGINE_get_RSA_method @@ -4921,6 +5052,7 @@ %xdefine ERR_add_error_dataf BORINGSSL_PREFIX %+ _ERR_add_error_dataf %xdefine ERR_clear_error BORINGSSL_PREFIX %+ _ERR_clear_error %xdefine ERR_clear_system_error BORINGSSL_PREFIX %+ _ERR_clear_system_error +%xdefine ERR_equals BORINGSSL_PREFIX %+ _ERR_equals %xdefine ERR_error_string BORINGSSL_PREFIX %+ _ERR_error_string %xdefine ERR_error_string_n BORINGSSL_PREFIX %+ _ERR_error_string_n %xdefine ERR_free_strings BORINGSSL_PREFIX %+ _ERR_free_strings @@ -5147,6 +5279,7 @@ %xdefine EVP_HPKE_KEY_zero BORINGSSL_PREFIX %+ _EVP_HPKE_KEY_zero %xdefine EVP_hpke_p256_hkdf_sha256 BORINGSSL_PREFIX %+ _EVP_hpke_p256_hkdf_sha256 %xdefine EVP_hpke_x25519_hkdf_sha256 BORINGSSL_PREFIX %+ _EVP_hpke_x25519_hkdf_sha256 +%xdefine EVP_hpke_xwing BORINGSSL_PREFIX %+ _EVP_hpke_xwing %xdefine EVP_marshal_digest_algorithm BORINGSSL_PREFIX %+ _EVP_marshal_digest_algorithm %xdefine EVP_marshal_digest_algorithm_no_params BORINGSSL_PREFIX %+ _EVP_marshal_digest_algorithm_no_params %xdefine EVP_marshal_private_key BORINGSSL_PREFIX %+ _EVP_marshal_private_key @@ -5178,6 +5311,7 @@ %xdefine EVP_md5 BORINGSSL_PREFIX %+ _EVP_md5 %xdefine EVP_md5_sha1 BORINGSSL_PREFIX %+ _EVP_md5_sha1 %xdefine EVP_parse_digest_algorithm BORINGSSL_PREFIX %+ _EVP_parse_digest_algorithm +%xdefine EVP_parse_digest_algorithm_nid BORINGSSL_PREFIX %+ _EVP_parse_digest_algorithm_nid %xdefine EVP_parse_private_key BORINGSSL_PREFIX %+ _EVP_parse_private_key %xdefine EVP_parse_public_key BORINGSSL_PREFIX %+ _EVP_parse_public_key %xdefine EVP_PBE_scrypt BORINGSSL_PREFIX %+ _EVP_PBE_scrypt @@ -5230,9 +5364,21 @@ %xdefine EVP_PKEY_derive BORINGSSL_PREFIX %+ _EVP_PKEY_derive %xdefine EVP_PKEY_derive_init BORINGSSL_PREFIX %+ _EVP_PKEY_derive_init %xdefine EVP_PKEY_derive_set_peer BORINGSSL_PREFIX %+ _EVP_PKEY_derive_set_peer +%xdefine EVP_pkey_dsa BORINGSSL_PREFIX %+ _EVP_pkey_dsa +%xdefine EVP_pkey_ec_p224 BORINGSSL_PREFIX %+ _EVP_pkey_ec_p224 +%xdefine EVP_pkey_ec_p256 BORINGSSL_PREFIX %+ _EVP_pkey_ec_p256 +%xdefine EVP_pkey_ec_p384 BORINGSSL_PREFIX %+ _EVP_pkey_ec_p384 +%xdefine EVP_pkey_ec_p521 BORINGSSL_PREFIX %+ _EVP_pkey_ec_p521 +%xdefine EVP_pkey_ed25519 BORINGSSL_PREFIX %+ _EVP_pkey_ed25519 %xdefine EVP_PKEY_encrypt BORINGSSL_PREFIX %+ _EVP_PKEY_encrypt %xdefine EVP_PKEY_encrypt_init BORINGSSL_PREFIX %+ _EVP_PKEY_encrypt_init %xdefine EVP_PKEY_free BORINGSSL_PREFIX %+ _EVP_PKEY_free +%xdefine EVP_PKEY_from_private_key_info BORINGSSL_PREFIX %+ _EVP_PKEY_from_private_key_info +%xdefine EVP_PKEY_from_raw_private_key BORINGSSL_PREFIX %+ _EVP_PKEY_from_raw_private_key +%xdefine EVP_PKEY_from_raw_public_key BORINGSSL_PREFIX %+ _EVP_PKEY_from_raw_public_key +%xdefine EVP_PKEY_from_subject_public_key_info BORINGSSL_PREFIX %+ _EVP_PKEY_from_subject_public_key_info +%xdefine EVP_PKEY_get_ec_curve_nid BORINGSSL_PREFIX %+ _EVP_PKEY_get_ec_curve_nid +%xdefine EVP_PKEY_get_ec_point_conv_form BORINGSSL_PREFIX %+ _EVP_PKEY_get_ec_point_conv_form %xdefine EVP_PKEY_get_raw_private_key BORINGSSL_PREFIX %+ _EVP_PKEY_get_raw_private_key %xdefine EVP_PKEY_get_raw_public_key BORINGSSL_PREFIX %+ _EVP_PKEY_get_raw_public_key %xdefine EVP_PKEY_get0 BORINGSSL_PREFIX %+ _EVP_PKEY_get0 @@ -5258,8 +5404,10 @@ %xdefine EVP_PKEY_print_params BORINGSSL_PREFIX %+ _EVP_PKEY_print_params %xdefine EVP_PKEY_print_private BORINGSSL_PREFIX %+ _EVP_PKEY_print_private %xdefine EVP_PKEY_print_public BORINGSSL_PREFIX %+ _EVP_PKEY_print_public -%xdefine evp_pkey_set_method BORINGSSL_PREFIX %+ _evp_pkey_set_method +%xdefine EVP_pkey_rsa BORINGSSL_PREFIX %+ _EVP_pkey_rsa +%xdefine EVP_pkey_rsa_pss_sha256 BORINGSSL_PREFIX %+ _EVP_pkey_rsa_pss_sha256 %xdefine EVP_PKEY_set_type BORINGSSL_PREFIX %+ _EVP_PKEY_set_type +%xdefine evp_pkey_set0 BORINGSSL_PREFIX %+ _evp_pkey_set0 %xdefine EVP_PKEY_set1_DH BORINGSSL_PREFIX %+ _EVP_PKEY_set1_DH %xdefine EVP_PKEY_set1_DSA BORINGSSL_PREFIX %+ _EVP_PKEY_set1_DSA %xdefine EVP_PKEY_set1_EC_KEY BORINGSSL_PREFIX %+ _EVP_PKEY_set1_EC_KEY @@ -5274,6 +5422,7 @@ %xdefine EVP_PKEY_verify_init BORINGSSL_PREFIX %+ _EVP_PKEY_verify_init %xdefine EVP_PKEY_verify_recover BORINGSSL_PREFIX %+ _EVP_PKEY_verify_recover %xdefine EVP_PKEY_verify_recover_init BORINGSSL_PREFIX %+ _EVP_PKEY_verify_recover_init +%xdefine EVP_pkey_x25519 BORINGSSL_PREFIX %+ _EVP_pkey_x25519 %xdefine EVP_PKEY2PKCS8 BORINGSSL_PREFIX %+ _EVP_PKEY2PKCS8 %xdefine EVP_rc2_40_cbc BORINGSSL_PREFIX %+ _EVP_rc2_40_cbc %xdefine EVP_rc2_cbc BORINGSSL_PREFIX %+ _EVP_rc2_cbc @@ -5310,6 +5459,8 @@ %xdefine FIPS_module_name BORINGSSL_PREFIX %+ _FIPS_module_name %xdefine FIPS_query_algorithm_status BORINGSSL_PREFIX %+ _FIPS_query_algorithm_status %xdefine FIPS_read_counter BORINGSSL_PREFIX %+ _FIPS_read_counter +%xdefine FIPS_service_indicator_after_call BORINGSSL_PREFIX %+ _FIPS_service_indicator_after_call +%xdefine FIPS_service_indicator_before_call BORINGSSL_PREFIX %+ _FIPS_service_indicator_before_call %xdefine FIPS_version BORINGSSL_PREFIX %+ _FIPS_version %xdefine gcm_ghash_avx BORINGSSL_PREFIX %+ _gcm_ghash_avx %xdefine gcm_ghash_clmul BORINGSSL_PREFIX %+ _gcm_ghash_clmul @@ -5485,7 +5636,6 @@ %xdefine i2d_X509_AUX BORINGSSL_PREFIX %+ _i2d_X509_AUX %xdefine i2d_X509_bio BORINGSSL_PREFIX %+ _i2d_X509_bio %xdefine i2d_X509_CERT_AUX BORINGSSL_PREFIX %+ _i2d_X509_CERT_AUX -%xdefine i2d_X509_CINF BORINGSSL_PREFIX %+ _i2d_X509_CINF %xdefine i2d_X509_CRL BORINGSSL_PREFIX %+ _i2d_X509_CRL %xdefine i2d_X509_CRL_bio BORINGSSL_PREFIX %+ _i2d_X509_CRL_bio %xdefine i2d_X509_CRL_fp BORINGSSL_PREFIX %+ _i2d_X509_CRL_fp @@ -5503,7 +5653,6 @@ %xdefine i2d_X509_REVOKED BORINGSSL_PREFIX %+ _i2d_X509_REVOKED %xdefine i2d_X509_SIG BORINGSSL_PREFIX %+ _i2d_X509_SIG %xdefine i2d_X509_tbs BORINGSSL_PREFIX %+ _i2d_X509_tbs -%xdefine i2d_X509_VAL BORINGSSL_PREFIX %+ _i2d_X509_VAL %xdefine i2o_ECPublicKey BORINGSSL_PREFIX %+ _i2o_ECPublicKey %xdefine i2s_ASN1_ENUMERATED BORINGSSL_PREFIX %+ _i2s_ASN1_ENUMERATED %xdefine i2s_ASN1_INTEGER BORINGSSL_PREFIX %+ _i2s_ASN1_INTEGER @@ -5567,6 +5716,17 @@ %xdefine MD5_Update BORINGSSL_PREFIX %+ _MD5_Update %xdefine METHOD_ref BORINGSSL_PREFIX %+ _METHOD_ref %xdefine METHOD_unref BORINGSSL_PREFIX %+ _METHOD_unref +%xdefine MLDSA44_generate_key BORINGSSL_PREFIX %+ _MLDSA44_generate_key +%xdefine MLDSA44_marshal_public_key BORINGSSL_PREFIX %+ _MLDSA44_marshal_public_key +%xdefine MLDSA44_parse_public_key BORINGSSL_PREFIX %+ _MLDSA44_parse_public_key +%xdefine MLDSA44_prehash_finalize BORINGSSL_PREFIX %+ _MLDSA44_prehash_finalize +%xdefine MLDSA44_prehash_init BORINGSSL_PREFIX %+ _MLDSA44_prehash_init +%xdefine MLDSA44_prehash_update BORINGSSL_PREFIX %+ _MLDSA44_prehash_update +%xdefine MLDSA44_private_key_from_seed BORINGSSL_PREFIX %+ _MLDSA44_private_key_from_seed +%xdefine MLDSA44_public_from_private BORINGSSL_PREFIX %+ _MLDSA44_public_from_private +%xdefine MLDSA44_sign BORINGSSL_PREFIX %+ _MLDSA44_sign +%xdefine MLDSA44_sign_message_representative BORINGSSL_PREFIX %+ _MLDSA44_sign_message_representative +%xdefine MLDSA44_verify BORINGSSL_PREFIX %+ _MLDSA44_verify %xdefine MLDSA65_generate_key BORINGSSL_PREFIX %+ _MLDSA65_generate_key %xdefine MLDSA65_marshal_public_key BORINGSSL_PREFIX %+ _MLDSA65_marshal_public_key %xdefine MLDSA65_parse_public_key BORINGSSL_PREFIX %+ _MLDSA65_parse_public_key @@ -5964,6 +6124,7 @@ %xdefine rsa_invalidate_key BORINGSSL_PREFIX %+ _rsa_invalidate_key %xdefine RSA_is_opaque BORINGSSL_PREFIX %+ _RSA_is_opaque %xdefine RSA_marshal_private_key BORINGSSL_PREFIX %+ _RSA_marshal_private_key +%xdefine rsa_marshal_pss_params BORINGSSL_PREFIX %+ _rsa_marshal_pss_params %xdefine RSA_marshal_public_key BORINGSSL_PREFIX %+ _RSA_marshal_public_key %xdefine RSA_new BORINGSSL_PREFIX %+ _RSA_new %xdefine RSA_new_method BORINGSSL_PREFIX %+ _RSA_new_method @@ -5981,6 +6142,7 @@ %xdefine RSA_padding_check_PKCS1_OAEP_mgf1 BORINGSSL_PREFIX %+ _RSA_padding_check_PKCS1_OAEP_mgf1 %xdefine RSA_padding_check_PKCS1_type_1 BORINGSSL_PREFIX %+ _RSA_padding_check_PKCS1_type_1 %xdefine RSA_parse_private_key BORINGSSL_PREFIX %+ _RSA_parse_private_key +%xdefine rsa_parse_pss_params BORINGSSL_PREFIX %+ _rsa_parse_pss_params %xdefine RSA_parse_public_key BORINGSSL_PREFIX %+ _RSA_parse_public_key %xdefine rsa_pkey_meth BORINGSSL_PREFIX %+ _rsa_pkey_meth %xdefine RSA_print BORINGSSL_PREFIX %+ _RSA_print @@ -5991,8 +6153,11 @@ %xdefine rsa_private_transform BORINGSSL_PREFIX %+ _rsa_private_transform %xdefine rsa_private_transform_no_self_test BORINGSSL_PREFIX %+ _rsa_private_transform_no_self_test %xdefine RSA_PSS_PARAMS_free BORINGSSL_PREFIX %+ _RSA_PSS_PARAMS_free +%xdefine rsa_pss_params_get_md BORINGSSL_PREFIX %+ _rsa_pss_params_get_md %xdefine RSA_PSS_PARAMS_it BORINGSSL_PREFIX %+ _RSA_PSS_PARAMS_it %xdefine RSA_PSS_PARAMS_new BORINGSSL_PREFIX %+ _RSA_PSS_PARAMS_new +%xdefine rsa_pss_sha256_asn1_meth BORINGSSL_PREFIX %+ _rsa_pss_sha256_asn1_meth +%xdefine rsa_pss_sha256_pkey_meth BORINGSSL_PREFIX %+ _rsa_pss_sha256_pkey_meth %xdefine RSA_public_decrypt BORINGSSL_PREFIX %+ _RSA_public_decrypt %xdefine RSA_public_encrypt BORINGSSL_PREFIX %+ _RSA_public_encrypt %xdefine RSA_public_key_from_bytes BORINGSSL_PREFIX %+ _RSA_public_key_from_bytes @@ -6442,10 +6607,13 @@ %xdefine X509_add1_ext_i2d BORINGSSL_PREFIX %+ _X509_add1_ext_i2d %xdefine X509_add1_reject_object BORINGSSL_PREFIX %+ _X509_add1_reject_object %xdefine X509_add1_trust_object BORINGSSL_PREFIX %+ _X509_add1_trust_object +%xdefine x509_algor_cleanup BORINGSSL_PREFIX %+ _x509_algor_cleanup %xdefine X509_ALGOR_cmp BORINGSSL_PREFIX %+ _X509_ALGOR_cmp +%xdefine X509_ALGOR_copy BORINGSSL_PREFIX %+ _X509_ALGOR_copy %xdefine X509_ALGOR_dup BORINGSSL_PREFIX %+ _X509_ALGOR_dup %xdefine X509_ALGOR_free BORINGSSL_PREFIX %+ _X509_ALGOR_free %xdefine X509_ALGOR_get0 BORINGSSL_PREFIX %+ _X509_ALGOR_get0 +%xdefine x509_algor_init BORINGSSL_PREFIX %+ _x509_algor_init %xdefine X509_ALGOR_it BORINGSSL_PREFIX %+ _X509_ALGOR_it %xdefine X509_ALGOR_new BORINGSSL_PREFIX %+ _X509_ALGOR_new %xdefine X509_ALGOR_set_md BORINGSSL_PREFIX %+ _X509_ALGOR_set_md @@ -6482,9 +6650,6 @@ %xdefine X509_check_private_key BORINGSSL_PREFIX %+ _X509_check_private_key %xdefine X509_check_purpose BORINGSSL_PREFIX %+ _X509_check_purpose %xdefine X509_check_trust BORINGSSL_PREFIX %+ _X509_check_trust -%xdefine X509_CINF_free BORINGSSL_PREFIX %+ _X509_CINF_free -%xdefine X509_CINF_it BORINGSSL_PREFIX %+ _X509_CINF_it -%xdefine X509_CINF_new BORINGSSL_PREFIX %+ _X509_CINF_new %xdefine X509_cmp BORINGSSL_PREFIX %+ _X509_cmp %xdefine X509_cmp_current_time BORINGSSL_PREFIX %+ _X509_cmp_current_time %xdefine X509_cmp_time BORINGSSL_PREFIX %+ _X509_cmp_time @@ -6620,6 +6785,8 @@ %xdefine X509_LOOKUP_load_file BORINGSSL_PREFIX %+ _X509_LOOKUP_load_file %xdefine x509_marshal_algorithm BORINGSSL_PREFIX %+ _x509_marshal_algorithm %xdefine x509_marshal_name BORINGSSL_PREFIX %+ _x509_marshal_name +%xdefine x509_marshal_public_key BORINGSSL_PREFIX %+ _x509_marshal_public_key +%xdefine x509_marshal_tbs_cert BORINGSSL_PREFIX %+ _x509_marshal_tbs_cert %xdefine X509_NAME_add_entry BORINGSSL_PREFIX %+ _X509_NAME_add_entry %xdefine X509_NAME_add_entry_by_NID BORINGSSL_PREFIX %+ _X509_NAME_add_entry_by_NID %xdefine X509_NAME_add_entry_by_OBJ BORINGSSL_PREFIX %+ _X509_NAME_add_entry_by_OBJ @@ -6663,23 +6830,29 @@ %xdefine X509_OBJECT_get_type BORINGSSL_PREFIX %+ _X509_OBJECT_get_type %xdefine X509_OBJECT_get0_X509 BORINGSSL_PREFIX %+ _X509_OBJECT_get0_X509 %xdefine X509_OBJECT_new BORINGSSL_PREFIX %+ _X509_OBJECT_new +%xdefine x509_parse_algorithm BORINGSSL_PREFIX %+ _x509_parse_algorithm %xdefine X509_parse_from_buffer BORINGSSL_PREFIX %+ _X509_parse_from_buffer +%xdefine x509_parse_public_key BORINGSSL_PREFIX %+ _x509_parse_public_key +%xdefine X509_parse_with_algorithms BORINGSSL_PREFIX %+ _X509_parse_with_algorithms %xdefine X509_policy_check BORINGSSL_PREFIX %+ _X509_policy_check %xdefine X509_print BORINGSSL_PREFIX %+ _X509_print %xdefine X509_print_ex BORINGSSL_PREFIX %+ _X509_print_ex %xdefine X509_print_ex_fp BORINGSSL_PREFIX %+ _X509_print_ex_fp %xdefine X509_print_fp BORINGSSL_PREFIX %+ _X509_print_fp %xdefine x509_print_rsa_pss_params BORINGSSL_PREFIX %+ _x509_print_rsa_pss_params +%xdefine x509_pubkey_cleanup BORINGSSL_PREFIX %+ _x509_pubkey_cleanup %xdefine X509_pubkey_digest BORINGSSL_PREFIX %+ _X509_pubkey_digest %xdefine X509_PUBKEY_free BORINGSSL_PREFIX %+ _X509_PUBKEY_free %xdefine X509_PUBKEY_get BORINGSSL_PREFIX %+ _X509_PUBKEY_get %xdefine X509_PUBKEY_get0 BORINGSSL_PREFIX %+ _X509_PUBKEY_get0 %xdefine X509_PUBKEY_get0_param BORINGSSL_PREFIX %+ _X509_PUBKEY_get0_param %xdefine X509_PUBKEY_get0_public_key BORINGSSL_PREFIX %+ _X509_PUBKEY_get0_public_key +%xdefine x509_pubkey_init BORINGSSL_PREFIX %+ _x509_pubkey_init %xdefine X509_PUBKEY_it BORINGSSL_PREFIX %+ _X509_PUBKEY_it %xdefine X509_PUBKEY_new BORINGSSL_PREFIX %+ _X509_PUBKEY_new %xdefine X509_PUBKEY_set BORINGSSL_PREFIX %+ _X509_PUBKEY_set %xdefine X509_PUBKEY_set0_param BORINGSSL_PREFIX %+ _X509_PUBKEY_set0_param +%xdefine x509_pubkey_set1 BORINGSSL_PREFIX %+ _x509_pubkey_set1 %xdefine X509_PURPOSE_get_by_sname BORINGSSL_PREFIX %+ _X509_PURPOSE_get_by_sname %xdefine X509_PURPOSE_get_id BORINGSSL_PREFIX %+ _X509_PURPOSE_get_id %xdefine X509_PURPOSE_get_trust BORINGSSL_PREFIX %+ _X509_PURPOSE_get_trust @@ -6763,6 +6936,7 @@ %xdefine X509_SIG_new BORINGSSL_PREFIX %+ _X509_SIG_new %xdefine X509_sign BORINGSSL_PREFIX %+ _X509_sign %xdefine X509_sign_ctx BORINGSSL_PREFIX %+ _X509_sign_ctx +%xdefine x509_sign_to_bit_string BORINGSSL_PREFIX %+ _x509_sign_to_bit_string %xdefine X509_signature_dump BORINGSSL_PREFIX %+ _X509_signature_dump %xdefine X509_signature_print BORINGSSL_PREFIX %+ _X509_signature_print %xdefine X509_STORE_add_cert BORINGSSL_PREFIX %+ _X509_STORE_add_cert @@ -6827,9 +7001,6 @@ %xdefine X509_time_adj_ex BORINGSSL_PREFIX %+ _X509_time_adj_ex %xdefine X509_trust_clear BORINGSSL_PREFIX %+ _X509_trust_clear %xdefine X509_up_ref BORINGSSL_PREFIX %+ _X509_up_ref -%xdefine X509_VAL_free BORINGSSL_PREFIX %+ _X509_VAL_free -%xdefine X509_VAL_it BORINGSSL_PREFIX %+ _X509_VAL_it -%xdefine X509_VAL_new BORINGSSL_PREFIX %+ _X509_VAL_new %xdefine X509_verify BORINGSSL_PREFIX %+ _X509_verify %xdefine X509_verify_cert BORINGSSL_PREFIX %+ _X509_verify_cert %xdefine X509_verify_cert_error_string BORINGSSL_PREFIX %+ _X509_verify_cert_error_string @@ -6855,6 +7026,7 @@ %xdefine X509_VERIFY_PARAM_set1_ip BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_set1_ip %xdefine X509_VERIFY_PARAM_set1_ip_asc BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_set1_ip_asc %xdefine X509_VERIFY_PARAM_set1_policies BORINGSSL_PREFIX %+ _X509_VERIFY_PARAM_set1_policies +%xdefine x509_verify_signature BORINGSSL_PREFIX %+ _x509_verify_signature %xdefine x509v3_a2i_ipadd BORINGSSL_PREFIX %+ _x509v3_a2i_ipadd %xdefine X509v3_add_ext BORINGSSL_PREFIX %+ _X509v3_add_ext %xdefine X509V3_add_standard_extensions BORINGSSL_PREFIX %+ _X509V3_add_standard_extensions diff --git a/Sources/CCryptoBoringSSL/include/experimental/CCryptoBoringSSL_kyber.h b/Sources/CCryptoBoringSSL/include/experimental/CCryptoBoringSSL_kyber.h deleted file mode 100644 index 43aaaa4de..000000000 --- a/Sources/CCryptoBoringSSL/include/experimental/CCryptoBoringSSL_kyber.h +++ /dev/null @@ -1,146 +0,0 @@ -// Copyright 2023 The BoringSSL Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef OPENSSL_HEADER_KYBER_H -#define OPENSSL_HEADER_KYBER_H - -#include "CCryptoBoringSSL_base.h" // IWYU pragma: export - -#if defined(__cplusplus) -extern "C" { -#endif - - -#if defined(OPENSSL_UNSTABLE_EXPERIMENTAL_KYBER) -// This header implements experimental, draft versions of not-yet-standardized -// primitives. When the standard is complete, these functions will be removed -// and replaced with the final, incompatible standard version. They are -// available now for short-lived experiments, but must not be deployed anywhere -// durable, such as a long-lived key store. To use these functions define -// OPENSSL_UNSTABLE_EXPERIMENTAL_KYBER - -// Kyber768. -// -// This implements the round-3 specification of Kyber, defined at -// https://pq-crystals.org/kyber/data/kyber-specification-round3-20210804.pdf - - -// KYBER_public_key contains a Kyber768 public key. The contents of this -// object should never leave the address space since the format is unstable. -struct KYBER_public_key { - union { - uint8_t bytes[512 * (3 + 9) + 32 + 32]; - uint16_t alignment; - } opaque; -}; - -// KYBER_private_key contains a Kyber768 private key. The contents of this -// object should never leave the address space since the format is unstable. -struct KYBER_private_key { - union { - uint8_t bytes[512 * (3 + 3 + 9) + 32 + 32 + 32]; - uint16_t alignment; - } opaque; -}; - -// KYBER_PUBLIC_KEY_BYTES is the number of bytes in an encoded Kyber768 public -// key. -#define KYBER_PUBLIC_KEY_BYTES 1184 - -// KYBER_SHARED_SECRET_BYTES is the number of bytes in the Kyber768 shared -// secret. Although the round-3 specification has a variable-length output, the -// final ML-KEM construction is expected to use a fixed 32-byte output. To -// simplify the future transition, we apply the same restriction. -#define KYBER_SHARED_SECRET_BYTES 32 - -// KYBER_generate_key generates a random public/private key pair, writes the -// encoded public key to |out_encoded_public_key| and sets |out_private_key| to -// the private key. -OPENSSL_EXPORT void KYBER_generate_key( - uint8_t out_encoded_public_key[KYBER_PUBLIC_KEY_BYTES], - struct KYBER_private_key *out_private_key); - -// KYBER_public_from_private sets |*out_public_key| to the public key that -// corresponds to |private_key|. (This is faster than parsing the output of -// |KYBER_generate_key| if, for some reason, you need to encapsulate to a key -// that was just generated.) -OPENSSL_EXPORT void KYBER_public_from_private( - struct KYBER_public_key *out_public_key, - const struct KYBER_private_key *private_key); - -// KYBER_CIPHERTEXT_BYTES is number of bytes in the Kyber768 ciphertext. -#define KYBER_CIPHERTEXT_BYTES 1088 - -// KYBER_encap encrypts a random shared secret for |public_key|, writes the -// ciphertext to |out_ciphertext|, and writes the random shared secret to -// |out_shared_secret|. -OPENSSL_EXPORT void KYBER_encap( - uint8_t out_ciphertext[KYBER_CIPHERTEXT_BYTES], - uint8_t out_shared_secret[KYBER_SHARED_SECRET_BYTES], - const struct KYBER_public_key *public_key); - -// KYBER_decap decrypts a shared secret from |ciphertext| using |private_key| -// and writes it to |out_shared_secret|. If |ciphertext| is invalid, -// |out_shared_secret| is filled with a key that will always be the same for the -// same |ciphertext| and |private_key|, but which appears to be random unless -// one has access to |private_key|. These alternatives occur in constant time. -// Any subsequent symmetric encryption using |out_shared_secret| must use an -// authenticated encryption scheme in order to discover the decapsulation -// failure. -OPENSSL_EXPORT void KYBER_decap( - uint8_t out_shared_secret[KYBER_SHARED_SECRET_BYTES], - const uint8_t ciphertext[KYBER_CIPHERTEXT_BYTES], - const struct KYBER_private_key *private_key); - - -// Serialisation of keys. - -// KYBER_marshal_public_key serializes |public_key| to |out| in the standard -// format for Kyber public keys. It returns one on success or zero on allocation -// error. -OPENSSL_EXPORT int KYBER_marshal_public_key( - CBB *out, const struct KYBER_public_key *public_key); - -// KYBER_parse_public_key parses a public key, in the format generated by -// |KYBER_marshal_public_key|, from |in| and writes the result to -// |out_public_key|. It returns one on success or zero on parse error or if -// there are trailing bytes in |in|. -OPENSSL_EXPORT int KYBER_parse_public_key( - struct KYBER_public_key *out_public_key, CBS *in); - -// KYBER_marshal_private_key serializes |private_key| to |out| in the standard -// format for Kyber private keys. It returns one on success or zero on -// allocation error. -OPENSSL_EXPORT int KYBER_marshal_private_key( - CBB *out, const struct KYBER_private_key *private_key); - -// KYBER_PRIVATE_KEY_BYTES is the length of the data produced by -// |KYBER_marshal_private_key|. -#define KYBER_PRIVATE_KEY_BYTES 2400 - -// KYBER_parse_private_key parses a private key, in the format generated by -// |KYBER_marshal_private_key|, from |in| and writes the result to -// |out_private_key|. It returns one on success or zero on parse error or if -// there are trailing bytes in |in|. -OPENSSL_EXPORT int KYBER_parse_private_key( - struct KYBER_private_key *out_private_key, CBS *in); - -#endif // OPENSSL_UNSTABLE_EXPERIMENTAL_KYBER - - -#if defined(__cplusplus) -} // extern C -#endif - -#endif // OPENSSL_HEADER_KYBER_H diff --git a/Sources/CCryptoBoringSSL/third_party/fiat/bedrock_polyfill_platform.c.inc b/Sources/CCryptoBoringSSL/third_party/fiat/bedrock_polyfill_platform.c.inc new file mode 100644 index 000000000..ec6c3a55d --- /dev/null +++ b/Sources/CCryptoBoringSSL/third_party/fiat/bedrock_polyfill_platform.c.inc @@ -0,0 +1,66 @@ +// Generated from Bedrock code in Fiat Cryptogrpahy. Avoid editing directly. + +static inline br_word_t br_full_add(br_word_t x, br_word_t y, br_word_t carry, br_word_t* _sum) { + br_word_t carry_out, sum; + x = x+carry; + carry_out = (br_word_t)(x>27)&63)+1)>>1; + M = ((br_word_t)1<<(n&(sizeof(br_word_t)*8-1)))-1; + ll = (a&M)*(b&M); + lh = (a&M)*(b>>(n&(sizeof(br_word_t)*8-1))); + hl = (a>>(n&(sizeof(br_word_t)*8-1)))*(b&M); + hh = (a>>(n&(sizeof(br_word_t)*8-1)))*(b>>(n&(sizeof(br_word_t)*8-1))); + second_halfword_w_oflow = ((ll>>(n&(sizeof(br_word_t)*8-1)))+(lh&M))+(hl&M); + high = ((hh+(lh>>(n&(sizeof(br_word_t)*8-1))))+(hl>>(n&(sizeof(br_word_t)*8-1))))+(second_halfword_w_oflow>>(n&(sizeof(br_word_t)*8-1))); + low = (second_halfword_w_oflow<<(n&(sizeof(br_word_t)*8-1)))+(ll&M); + *_low = low; + return high; +} + +static inline br_word_t br_value_barrier(br_word_t a) { + /*skip*/ + return a; +} + +static inline br_word_t br_declassify(br_word_t a) { + /*skip*/ + return a; +} + +static inline br_word_t br_broadcast_negative(br_word_t x) { + br_word_t y; + y = (br_word_t)((br_signed_t)x>>((((0u-(br_word_t)1)>>27)&63)&(sizeof(br_word_t)*8-1))); + y = br_value_barrier(y); + return y; +} + +static inline br_word_t br_broadcast_nonzero(br_word_t x) { + br_word_t y; + y = br_broadcast_negative(x|(0u-x)); + return y; +} + +static inline br_word_t br_cmov(br_word_t c, br_word_t vnz, br_word_t vz) { + br_word_t r, m; + m = br_broadcast_nonzero(c); + r = (m&vnz)|((~m)&vz); + return r; +} diff --git a/Sources/CCryptoBoringSSL/third_party/fiat/bedrock_unverified_bareminimum.c.inc b/Sources/CCryptoBoringSSL/third_party/fiat/bedrock_unverified_bareminimum.c.inc new file mode 100644 index 000000000..a03388bd0 --- /dev/null +++ b/Sources/CCryptoBoringSSL/third_party/fiat/bedrock_unverified_bareminimum.c.inc @@ -0,0 +1,47 @@ +#ifndef BEDROCK_UNVERIFIED_BAREMINIMUM_INC_H_ +#define BEDROCK_UNVERIFIED_BAREMINIMUM_INC_H_ + +static_assert(sizeof(br_word_t) == sizeof(br_signed_t), ""); +static_assert(UINTPTR_MAX <= BR_WORD_MAX, ""); + +// "An object shall have its stored value accessed only ... a character type." + +static inline br_word_t _br_load1(br_word_t a) { + return *((uint8_t *)a); +} + +static inline br_word_t _br_load2(br_word_t a) { + uint16_t r = 0; + memcpy(&r, (void *)a, sizeof(r)); + return r; +} + +static inline br_word_t _br_load4(br_word_t a) { + uint32_t r = 0; + memcpy(&r, (void *)a, sizeof(r)); + return r; +} + +static inline br_word_t _br_load(br_word_t a) { + br_word_t r = 0; + memcpy(&r, (void *)a, sizeof(r)); + return r; +} + +static inline void _br_store1(br_word_t a, uint8_t v) { + *((uint8_t *)a) = v; +} + +static inline void _br_store2(br_word_t a, uint16_t v) { + memcpy((void *)a, &v, sizeof(v)); +} + +static inline void _br_store4(br_word_t a, uint32_t v) { + memcpy((void *)a, &v, sizeof(v)); +} + +static inline void _br_store(br_word_t a, br_word_t v) { + memcpy((void *)a, &v, sizeof(v)); +} + +#endif // BEDROCK_UNVERIFIED_BAREMINIMUM_INC_H_ diff --git a/Sources/CCryptoBoringSSL/third_party/fiat/bedrock_unverified_platform.c.inc b/Sources/CCryptoBoringSSL/third_party/fiat/bedrock_unverified_platform.c.inc new file mode 100644 index 000000000..89fe7d05d --- /dev/null +++ b/Sources/CCryptoBoringSSL/third_party/fiat/bedrock_unverified_platform.c.inc @@ -0,0 +1,125 @@ +#ifndef BEDROCK_UNVERIFIED_PLATFORM_INC_H_ +#define BEDROCK_UNVERIFIED_PLATFORM_INC_H_ + +// This file is a manually maintained and audited replacement for +// bedrock_polyfill_platform.c.inc with tests in bedrock_platform_test.cc + +#include "../../crypto/internal.h" + +#if defined(OPENSSL_64_BIT) +#define BR_WORD_MAX UINT64_MAX +typedef uint64_t br_word_t; +typedef int64_t br_signed_t; +#elif defined(OPENSSL_32_BIT) +#define BR_WORD_MAX UINT32_MAX +typedef uint32_t br_word_t; +typedef int32_t br_signed_t; +#else +#error "Must define either OPENSSL_32_BIT or OPENSSL_64_BIT" +#endif + +static_assert(sizeof(br_word_t) == sizeof(crypto_word_t)); + +// Scalar memory operations + +#include "../../third_party/fiat/bedrock_unverified_bareminimum.c.inc" + +// Bulk memory operations + +static inline void br_memcpy(br_word_t d, br_word_t s, br_word_t n) { + OPENSSL_memcpy((void *)d, (const void *)s, n); +} + +static inline void br_memset(br_word_t d, br_word_t v, br_word_t n) { + OPENSSL_memset((void *)d, v, n); +} + +static inline void br_memcxor(uintptr_t d, uintptr_t s, uintptr_t n, uintptr_t mask) { + constant_time_conditional_memxor((void*)d, (void*)s, n, mask); +} + +// CPU Arithmetic + +static inline br_word_t br_full_add(br_word_t x, br_word_t y, br_word_t carry, + br_word_t *_sum) { + br_word_t carry_out = 0; + static_assert(sizeof(br_word_t) == sizeof(crypto_word_t)); + *_sum = CRYPTO_addc_w(x, y, carry, &carry_out); + return carry_out; +} + +static inline br_word_t br_full_sub(br_word_t x, br_word_t y, br_word_t borrow, + br_word_t *_diff) { + br_word_t borrow_out = 0; + static_assert(sizeof(br_word_t) == sizeof(crypto_word_t)); + *_diff = CRYPTO_subc_w(x, y, borrow, &borrow_out); + return borrow_out; +} + +static inline br_word_t br_full_mul(br_word_t a, br_word_t b, br_word_t *_low) { +#if BR_WORD_MAX == UINT32_MAX + uint64_t r = (uint64_t)a * b; + *_low = r; + return r >> 32; +#elif defined(BORINGSSL_HAS_UINT128) + uint128_t r = (uint128_t)a * b; + *_low = r; + return r >> 64; +#elif defined(_M_X64) + uint64_t hi; + *_low = _umul128(a, b, &hi); + return hi; +#elif defined(_M_ARM64) + *_low = a * b; + return __umulh(a, b); +#else +#error "need 64 x 64 -> 128 multiplication" +#endif +} + +// Constant-time computations + +static inline br_word_t br_value_barrier(br_word_t a) { + static_assert(sizeof(br_word_t) == sizeof(crypto_word_t)); + return value_barrier_w(a); +} + +static inline br_word_t br_declassify(br_word_t a) { + static_assert(sizeof(br_word_t) == sizeof(crypto_word_t)); + return constant_time_declassify_w(a); +} + +static inline br_word_t br_broadcast_negative(br_word_t x) { + return br_value_barrier((br_signed_t)x >> (sizeof(br_word_t) * 8 - 1)); +} + +static inline br_word_t br_broadcast_nonzero(br_word_t x) { + return br_broadcast_negative(x | (0u - x)); +} + +static inline br_word_t br_cmov(br_word_t c, br_word_t vnz, br_word_t vz) { +#if !defined(OPENSSL_NO_ASM) && (defined(__GNUC__) || defined(__clang__)) && \ + defined(__x86_64__) + __asm__( + "testq %[c], %[c]\n" + "cmovzq %[vz], %[vnz]" + : [vnz] "+r"(vnz) + : [vz] "r"(vz), [c] "r"(c) + : "cc"); + return vnz; +#elif !defined(OPENSSL_NO_ASM) && (defined(__GNUC__) || defined(__clang__)) && \ + defined(__i386__) + __asm__( + "testl %[c], %[c]\n" // test%z[c] gives "invalid operand" on clang 16.0.6 + "cmovzl %[vz], %[vnz]" + : [vnz] "+r"(vnz) + : [vz] "r"(vz), [c] "r"(c) + : "cc"); + return vnz; +#else + br_word_t m = br_broadcast_nonzero(c); + return (m & vnz) | (~m & vz); +#endif +} + +#endif // BEDROCK_UNVERIFIED_PLATFORM_INC_H_ diff --git a/Sources/CCryptoBoringSSL/third_party/fiat/p256_64.h b/Sources/CCryptoBoringSSL/third_party/fiat/p256_64.h index 0aaac28c5..ddb73ae70 100644 --- a/Sources/CCryptoBoringSSL/third_party/fiat/p256_64.h +++ b/Sources/CCryptoBoringSSL/third_party/fiat/p256_64.h @@ -1,4 +1,6 @@ #include +#include "bedrock_unverified_platform.c.inc" +#include "p256_field_64.br.c.inc" #include "../../crypto/internal.h" #if !defined(OPENSSL_NO_ASM) && defined(__GNUC__) && defined(__x86_64__) @@ -175,6 +177,7 @@ static FIAT_P256_FIAT_INLINE void fiat_p256_cmovznz_u64(uint64_t* out1, fiat_p25 * */ static FIAT_P256_FIAT_INLINE void fiat_p256_mul(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1, const fiat_p256_montgomery_domain_field_element arg2) { + // NOTE: edited by hand, see third_party/fiat/README.md #if !defined(OPENSSL_NO_ASM) && defined(__GNUC__) && defined(__x86_64__) if (CRYPTO_is_BMI1_capable() && CRYPTO_is_BMI2_capable() && CRYPTO_is_ADX_capable()) { @@ -489,6 +492,7 @@ static FIAT_P256_FIAT_INLINE void fiat_p256_mul(fiat_p256_montgomery_domain_fiel * */ static FIAT_P256_FIAT_INLINE void fiat_p256_square(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1) { + // NOTE: edited by hand, see third_party/fiat/README.md #if !defined(OPENSSL_NO_ASM) && defined(__GNUC__) && defined(__x86_64__) if (CRYPTO_is_BMI1_capable() && CRYPTO_is_BMI2_capable() && CRYPTO_is_ADX_capable()) { @@ -804,45 +808,8 @@ static FIAT_P256_FIAT_INLINE void fiat_p256_square(fiat_p256_montgomery_domain_f * */ static FIAT_P256_FIAT_INLINE void fiat_p256_add(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1, const fiat_p256_montgomery_domain_field_element arg2) { - uint64_t x1; - fiat_p256_uint1 x2; - uint64_t x3; - fiat_p256_uint1 x4; - uint64_t x5; - fiat_p256_uint1 x6; - uint64_t x7; - fiat_p256_uint1 x8; - uint64_t x9; - fiat_p256_uint1 x10; - uint64_t x11; - fiat_p256_uint1 x12; - uint64_t x13; - fiat_p256_uint1 x14; - uint64_t x15; - fiat_p256_uint1 x16; - uint64_t x17; - fiat_p256_uint1 x18; - uint64_t x19; - uint64_t x20; - uint64_t x21; - uint64_t x22; - fiat_p256_addcarryx_u64(&x1, &x2, 0x0, (arg1[0]), (arg2[0])); - fiat_p256_addcarryx_u64(&x3, &x4, x2, (arg1[1]), (arg2[1])); - fiat_p256_addcarryx_u64(&x5, &x6, x4, (arg1[2]), (arg2[2])); - fiat_p256_addcarryx_u64(&x7, &x8, x6, (arg1[3]), (arg2[3])); - fiat_p256_subborrowx_u64(&x9, &x10, 0x0, x1, UINT64_C(0xffffffffffffffff)); - fiat_p256_subborrowx_u64(&x11, &x12, x10, x3, UINT32_C(0xffffffff)); - fiat_p256_subborrowx_u64(&x13, &x14, x12, x5, 0x0); - fiat_p256_subborrowx_u64(&x15, &x16, x14, x7, UINT64_C(0xffffffff00000001)); - fiat_p256_subborrowx_u64(&x17, &x18, x16, x8, 0x0); - fiat_p256_cmovznz_u64(&x19, x18, x9, x1); - fiat_p256_cmovznz_u64(&x20, x18, x11, x3); - fiat_p256_cmovznz_u64(&x21, x18, x13, x5); - fiat_p256_cmovznz_u64(&x22, x18, x15, x7); - out1[0] = x19; - out1[1] = x20; - out1[2] = x21; - out1[3] = x22; + // NOTE: edited by hand, see third_party/fiat/README.md + p256_coord_add((br_word_t)out1, (br_word_t)arg1, (br_word_t)arg2); } /* @@ -857,36 +824,8 @@ static FIAT_P256_FIAT_INLINE void fiat_p256_add(fiat_p256_montgomery_domain_fiel * */ static FIAT_P256_FIAT_INLINE void fiat_p256_sub(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1, const fiat_p256_montgomery_domain_field_element arg2) { - uint64_t x1; - fiat_p256_uint1 x2; - uint64_t x3; - fiat_p256_uint1 x4; - uint64_t x5; - fiat_p256_uint1 x6; - uint64_t x7; - fiat_p256_uint1 x8; - uint64_t x9; - uint64_t x10; - fiat_p256_uint1 x11; - uint64_t x12; - fiat_p256_uint1 x13; - uint64_t x14; - fiat_p256_uint1 x15; - uint64_t x16; - fiat_p256_uint1 x17; - fiat_p256_subborrowx_u64(&x1, &x2, 0x0, (arg1[0]), (arg2[0])); - fiat_p256_subborrowx_u64(&x3, &x4, x2, (arg1[1]), (arg2[1])); - fiat_p256_subborrowx_u64(&x5, &x6, x4, (arg1[2]), (arg2[2])); - fiat_p256_subborrowx_u64(&x7, &x8, x6, (arg1[3]), (arg2[3])); - fiat_p256_cmovznz_u64(&x9, x8, 0x0, UINT64_C(0xffffffffffffffff)); - fiat_p256_addcarryx_u64(&x10, &x11, 0x0, x1, x9); - fiat_p256_addcarryx_u64(&x12, &x13, x11, x3, (x9 & UINT32_C(0xffffffff))); - fiat_p256_addcarryx_u64(&x14, &x15, x13, x5, 0x0); - fiat_p256_addcarryx_u64(&x16, &x17, x15, x7, (x9 & UINT64_C(0xffffffff00000001))); - out1[0] = x10; - out1[1] = x12; - out1[2] = x14; - out1[3] = x16; + // NOTE: edited by hand, see third_party/fiat/README.md + p256_coord_sub((br_word_t)out1, (br_word_t)arg1, (br_word_t)arg2); } /* diff --git a/Sources/CCryptoBoringSSL/third_party/fiat/p256_64_msvc.h b/Sources/CCryptoBoringSSL/third_party/fiat/p256_64_msvc.h index 8b65a3734..aff43d359 100644 --- a/Sources/CCryptoBoringSSL/third_party/fiat/p256_64_msvc.h +++ b/Sources/CCryptoBoringSSL/third_party/fiat/p256_64_msvc.h @@ -17,6 +17,8 @@ /* twos_complement_eval z = let x1 := z[0] + (z[1] << 64) + (z[2] << 128) + (z[3] << 192) in */ /* if x1 & (2^256-1) < 2^255 then x1 & (2^256-1) else (x1 & (2^256-1)) - 2^256 */ +#include "bedrock_unverified_platform.c.inc" +#include "p256_field_64.br.c.inc" #include #include #if defined(_M_X64) @@ -771,45 +773,8 @@ static FIAT_P256_FIAT_INLINE void fiat_p256_square(fiat_p256_montgomery_domain_f * */ static FIAT_P256_FIAT_INLINE void fiat_p256_add(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1, const fiat_p256_montgomery_domain_field_element arg2) { - uint64_t x1; - fiat_p256_uint1 x2; - uint64_t x3; - fiat_p256_uint1 x4; - uint64_t x5; - fiat_p256_uint1 x6; - uint64_t x7; - fiat_p256_uint1 x8; - uint64_t x9; - fiat_p256_uint1 x10; - uint64_t x11; - fiat_p256_uint1 x12; - uint64_t x13; - fiat_p256_uint1 x14; - uint64_t x15; - fiat_p256_uint1 x16; - uint64_t x17; - fiat_p256_uint1 x18; - uint64_t x19; - uint64_t x20; - uint64_t x21; - uint64_t x22; - fiat_p256_addcarryx_u64(&x1, &x2, 0x0, (arg1[0]), (arg2[0])); - fiat_p256_addcarryx_u64(&x3, &x4, x2, (arg1[1]), (arg2[1])); - fiat_p256_addcarryx_u64(&x5, &x6, x4, (arg1[2]), (arg2[2])); - fiat_p256_addcarryx_u64(&x7, &x8, x6, (arg1[3]), (arg2[3])); - fiat_p256_subborrowx_u64(&x9, &x10, 0x0, x1, UINT64_C(0xffffffffffffffff)); - fiat_p256_subborrowx_u64(&x11, &x12, x10, x3, UINT32_C(0xffffffff)); - fiat_p256_subborrowx_u64(&x13, &x14, x12, x5, 0x0); - fiat_p256_subborrowx_u64(&x15, &x16, x14, x7, UINT64_C(0xffffffff00000001)); - fiat_p256_subborrowx_u64(&x17, &x18, x16, x8, 0x0); - fiat_p256_cmovznz_u64(&x19, x18, x9, x1); - fiat_p256_cmovznz_u64(&x20, x18, x11, x3); - fiat_p256_cmovznz_u64(&x21, x18, x13, x5); - fiat_p256_cmovznz_u64(&x22, x18, x15, x7); - out1[0] = x19; - out1[1] = x20; - out1[2] = x21; - out1[3] = x22; + // NOTE: edited by hand, see third_party/fiat/README.md + p256_coord_add((br_word_t)out1, (br_word_t)arg1, (br_word_t)arg2); } /* @@ -824,36 +789,8 @@ static FIAT_P256_FIAT_INLINE void fiat_p256_add(fiat_p256_montgomery_domain_fiel * */ static FIAT_P256_FIAT_INLINE void fiat_p256_sub(fiat_p256_montgomery_domain_field_element out1, const fiat_p256_montgomery_domain_field_element arg1, const fiat_p256_montgomery_domain_field_element arg2) { - uint64_t x1; - fiat_p256_uint1 x2; - uint64_t x3; - fiat_p256_uint1 x4; - uint64_t x5; - fiat_p256_uint1 x6; - uint64_t x7; - fiat_p256_uint1 x8; - uint64_t x9; - uint64_t x10; - fiat_p256_uint1 x11; - uint64_t x12; - fiat_p256_uint1 x13; - uint64_t x14; - fiat_p256_uint1 x15; - uint64_t x16; - fiat_p256_uint1 x17; - fiat_p256_subborrowx_u64(&x1, &x2, 0x0, (arg1[0]), (arg2[0])); - fiat_p256_subborrowx_u64(&x3, &x4, x2, (arg1[1]), (arg2[1])); - fiat_p256_subborrowx_u64(&x5, &x6, x4, (arg1[2]), (arg2[2])); - fiat_p256_subborrowx_u64(&x7, &x8, x6, (arg1[3]), (arg2[3])); - fiat_p256_cmovznz_u64(&x9, x8, 0x0, UINT64_C(0xffffffffffffffff)); - fiat_p256_addcarryx_u64(&x10, &x11, 0x0, x1, x9); - fiat_p256_addcarryx_u64(&x12, &x13, x11, x3, (x9 & UINT32_C(0xffffffff))); - fiat_p256_addcarryx_u64(&x14, &x15, x13, x5, 0x0); - fiat_p256_addcarryx_u64(&x16, &x17, x15, x7, (x9 & UINT64_C(0xffffffff00000001))); - out1[0] = x10; - out1[1] = x12; - out1[2] = x14; - out1[3] = x16; + // NOTE: edited by hand, see third_party/fiat/README.md + p256_coord_sub((br_word_t)out1, (br_word_t)arg1, (br_word_t)arg2); } /* diff --git a/Sources/CCryptoBoringSSL/third_party/fiat/p256_field.c.inc b/Sources/CCryptoBoringSSL/third_party/fiat/p256_field.c.inc new file mode 100644 index 000000000..047d61bf7 --- /dev/null +++ b/Sources/CCryptoBoringSSL/third_party/fiat/p256_field.c.inc @@ -0,0 +1,26 @@ +#include +#include "bedrock_unverified_platform.c.inc" + +#if defined(BORINGSSL_HAS_UINT128) +#include "p256_64.h" +#elif defined(OPENSSL_64_BIT) +#include "p256_64_msvc.h" +#else +#include "p256_field_32.br.c.inc" +#include "p256_32.h" +// the 32-bit Bedrock-generated field halving calls Fiat-C code for add, sub +static inline void p256_coord_add(br_word_t out, br_word_t x, br_word_t y) { + fiat_p256_add((uint32_t*)out, (const uint32_t*)x, (const uint32_t*)y); +} +static inline void p256_coord_sub(br_word_t out, br_word_t x, br_word_t y) { + fiat_p256_sub((uint32_t*)out, (const uint32_t*)x, (const uint32_t*)y); +} +#endif + +// the Bedrock-generated point operations call Fiat-C or Fiat-x86 mul, sqr +static inline void p256_coord_mul(br_word_t out, br_word_t x, br_word_t y) { + fiat_p256_mul((br_word_t*)out, (const br_word_t*)x, (const br_word_t*)y); +} +static inline void p256_coord_sqr(br_word_t out, br_word_t x) { + fiat_p256_square((br_word_t*)out, (const br_word_t*)x); +} diff --git a/Sources/CCryptoBoringSSL/third_party/fiat/p256_field_32.br.c.inc b/Sources/CCryptoBoringSSL/third_party/fiat/p256_field_32.br.c.inc new file mode 100644 index 000000000..e681dcb55 --- /dev/null +++ b/Sources/CCryptoBoringSSL/third_party/fiat/p256_field_32.br.c.inc @@ -0,0 +1,71 @@ +// Generated from Bedrock code in Fiat Cryptography. Avoid editing directly. + +static inline br_word_t shrd(br_word_t lo, br_word_t hi, br_word_t n) { + br_word_t res; + res = lo>>(n&(sizeof(br_word_t)*8-1)); + if (n) { + res = (hi<<((((((0u-(br_word_t)1)>>27)&63)+1)-n)&(sizeof(br_word_t)*8-1)))|res; + } else { + /*skip*/ + } + return res; +} + +static inline br_word_t p256_coord_nonzero(br_word_t p_x) { + br_word_t nz; + nz = (((_br_load(p_x))|(_br_load(p_x+4)))|(_br_load((p_x+4)+4)))|(_br_load(((p_x+4)+4)+4)); + nz = nz|(_br_load((((p_x+4)+4)+4)+4)); + nz = nz|(_br_load(((((p_x+4)+4)+4)+4)+4)); + nz = nz|(_br_load((((((p_x+4)+4)+4)+4)+4)+4)); + nz = nz|(_br_load(((((((p_x+4)+4)+4)+4)+4)+4)+4)); + nz = br_broadcast_nonzero(nz); + return nz; +} + +static inline void u256_shr(br_word_t p_out, br_word_t p_x, br_word_t n) { + br_word_t x0, x1, x2, x3, x4, x5, x6, x7, y0, y1, y2, y3, y4, y5, y6, y7; + x0 = _br_load(p_x); + x1 = _br_load(p_x+4); + x2 = _br_load((p_x+4)+4); + x3 = _br_load(((p_x+4)+4)+4); + x4 = _br_load((((p_x+4)+4)+4)+4); + x5 = _br_load(((((p_x+4)+4)+4)+4)+4); + x6 = _br_load((((((p_x+4)+4)+4)+4)+4)+4); + x7 = _br_load(((((((p_x+4)+4)+4)+4)+4)+4)+4); + y0 = shrd(x0, x1, n); + y1 = shrd(x1, x2, n); + y2 = shrd(x2, x3, n); + y3 = shrd(x3, x4, n); + y4 = shrd(x4, x5, n); + y5 = shrd(x5, x6, n); + y6 = shrd(x6, x7, n); + y7 = x7>>(n&(sizeof(br_word_t)*8-1)); + _br_store(p_out, y0); + _br_store(p_out+4, y1); + _br_store((p_out+4)+4, y2); + _br_store(((p_out+4)+4)+4, y3); + _br_store((((p_out+4)+4)+4)+4, y4); + _br_store(((((p_out+4)+4)+4)+4)+4, y5); + _br_store((((((p_out+4)+4)+4)+4)+4)+4, y6); + _br_store(((((((p_out+4)+4)+4)+4)+4)+4)+4, y7); +} + +static inline void u256_set_p256_minushalf_conditional(br_word_t p_out, br_word_t mask) { + br_word_t mh0, mh1, mh2, mh3, mh4, mh5, mh6, mh7; + mh0 = 0u-(br_word_t)1; + mh1 = mh0; + mh2 = mh0>>1; + mh3 = (br_word_t)0; + mh4 = (br_word_t)0; + mh5 = (br_word_t)1<<31; + mh6 = mh5; + mh7 = mh2; + _br_store(p_out, mask&mh0); + _br_store(p_out+4, mask&mh1); + _br_store((p_out+4)+4, mask&mh2); + _br_store(((p_out+4)+4)+4, mask&mh3); + _br_store((((p_out+4)+4)+4)+4, mask&mh4); + _br_store(((((p_out+4)+4)+4)+4)+4, mask&mh5); + _br_store((((((p_out+4)+4)+4)+4)+4)+4, mask&mh6); + _br_store(((((((p_out+4)+4)+4)+4)+4)+4)+4, mask&mh7); +} diff --git a/Sources/CCryptoBoringSSL/third_party/fiat/p256_field_64.br.c.inc b/Sources/CCryptoBoringSSL/third_party/fiat/p256_field_64.br.c.inc new file mode 100644 index 000000000..b23246b1c --- /dev/null +++ b/Sources/CCryptoBoringSSL/third_party/fiat/p256_field_64.br.c.inc @@ -0,0 +1,84 @@ +// Generated from Bedrock code in Fiat Cryptography. Avoid editing directly. + +static inline br_word_t shrd(br_word_t lo, br_word_t hi, br_word_t n) { + br_word_t res; + res = lo>>(n&(sizeof(br_word_t)*8-1)); + if (n) { + res = (hi<<((((((0u-(br_word_t)1)>>27)&63)+1)-n)&(sizeof(br_word_t)*8-1)))|res; + } else { + /*skip*/ + } + return res; +} + +static inline void p256_coord_add(br_word_t p_out, br_word_t p_x, br_word_t p_y) { + br_word_t r4, carry, t0, t1, t2, borrow, t3, r0, r1, r2, r3; + carry = br_full_add(_br_load(p_x), _br_load(p_y), (br_word_t)0, &t0); + carry = br_full_add(_br_load(p_x+8), _br_load(p_y+8), carry, &t1); + carry = br_full_add(_br_load((p_x+8)+8), _br_load((p_y+8)+8), carry, &t2); + carry = br_full_add(_br_load(((p_x+8)+8)+8), _br_load(((p_y+8)+8)+8), carry, &t3); + borrow = br_full_sub(t0, (br_word_t)0xffffffffffffffff, (br_word_t)0, &r0); + borrow = br_full_sub(t1, (br_word_t)0xffffffff, borrow, &r1); + borrow = br_full_sub(t2, (br_word_t)0, borrow, &r2); + borrow = br_full_sub(t3, (br_word_t)0xffffffff00000001, borrow, &r3); + borrow = br_full_sub(carry, (br_word_t)0, borrow, &r4); + r0 = br_cmov(borrow, t0, r0); + r1 = br_cmov(borrow, t1, r1); + r2 = br_cmov(borrow, t2, r2); + r3 = br_cmov(borrow, t3, r3); + _br_store(p_out, r0); + _br_store(p_out+8, r1); + _br_store((p_out+8)+8, r2); + _br_store(((p_out+8)+8)+8, r3); +} + +static inline void p256_coord_sub(br_word_t out, br_word_t x, br_word_t y) { + br_word_t borrow, t0, t1, t2, t3, mask, carry, r0, r1, r2, r3; + borrow = br_full_sub(_br_load(x), _br_load(y), (br_word_t)0, &t0); + borrow = br_full_sub(_br_load(x+8), _br_load(y+8), borrow, &t1); + borrow = br_full_sub(_br_load((x+8)+8), _br_load((y+8)+8), borrow, &t2); + borrow = br_full_sub(_br_load(((x+8)+8)+8), _br_load(((y+8)+8)+8), borrow, &t3); + mask = br_value_barrier(0u-borrow); + carry = br_full_add(t0, mask, (br_word_t)0, &r0); + carry = br_full_add(t1, mask&0xffffffff, carry, &r1); + carry = br_full_add(t2, (br_word_t)0, carry, &r2); + carry = br_full_add(t3, mask&0xffffffff00000001, carry, &r3); + _br_store(out, r0); + _br_store(out+8, r1); + _br_store((out+8)+8, r2); + _br_store(((out+8)+8)+8, r3); +} + +static inline br_word_t p256_coord_nonzero(br_word_t p_x) { + br_word_t nz; + nz = br_broadcast_nonzero((((_br_load(p_x))|(_br_load(p_x+8)))|(_br_load((p_x+8)+8)))|(_br_load(((p_x+8)+8)+8))); + return nz; +} + +static inline void u256_shr(br_word_t p_out, br_word_t p_x, br_word_t n) { + br_word_t x0, x1, x2, x3, y0, y1, y2, y3; + x0 = _br_load(p_x); + x1 = _br_load(p_x+8); + x2 = _br_load((p_x+8)+8); + x3 = _br_load(((p_x+8)+8)+8); + y0 = shrd(x0, x1, n); + y1 = shrd(x1, x2, n); + y2 = shrd(x2, x3, n); + y3 = x3>>(n&(sizeof(br_word_t)*8-1)); + _br_store(p_out, y0); + _br_store(p_out+8, y1); + _br_store((p_out+8)+8, y2); + _br_store(((p_out+8)+8)+8, y3); +} + +static inline void u256_set_p256_minushalf_conditional(br_word_t p_out, br_word_t mask) { + br_word_t mh0, mh1, mh2, mh3; + mh0 = 0u-(br_word_t)1; + mh1 = mh0>>((br_word_t)33&(sizeof(br_word_t)*8-1)); + mh2 = mh0<<((br_word_t)63&(sizeof(br_word_t)*8-1)); + mh3 = (mh0<<((br_word_t)32&(sizeof(br_word_t)*8-1)))>>1; + _br_store(p_out, mask&mh0); + _br_store(p_out+8, mask&mh1); + _br_store((p_out+8)+8, mask&mh2); + _br_store(((p_out+8)+8)+8, mask&mh3); +} diff --git a/Sources/CCryptoBoringSSL/third_party/fiat/p256_point.br.c.inc b/Sources/CCryptoBoringSSL/third_party/fiat/p256_point.br.c.inc new file mode 100644 index 000000000..117547bdf --- /dev/null +++ b/Sources/CCryptoBoringSSL/third_party/fiat/p256_point.br.c.inc @@ -0,0 +1,112 @@ +// Generated from Bedrock code in Fiat Cryptography. Avoid editing directly. + +static inline br_word_t br_broadcast_odd(br_word_t x) { + br_word_t y; + x = br_value_barrier(x&1); + y = 0u-x; + return y; +} + +static inline void p256_coord_halve(br_word_t y, br_word_t x) { + br_word_t m, mmh; + uint8_t _br_stackalloc_mmh[32] = {0}; mmh = (br_word_t)&_br_stackalloc_mmh; + m = br_broadcast_odd(_br_load(x)); + u256_set_p256_minushalf_conditional(mmh, m); + u256_shr(y, x, (br_word_t)1); + p256_coord_sub(y, y, mmh); +} + +static inline br_word_t p256_point_iszero(br_word_t p_P) { + br_word_t z, nz; + nz = p256_coord_nonzero((p_P+32)+32); + z = ~nz; + return z; +} + +static inline void p256_point_double(br_word_t out, br_word_t in1) { + br_word_t t2, tmp, A, D; + uint8_t _br_stackalloc_D[32] = {0}; D = (br_word_t)&_br_stackalloc_D; + uint8_t _br_stackalloc_A[32] = {0}; A = (br_word_t)&_br_stackalloc_A; + uint8_t _br_stackalloc_tmp[32] = {0}; tmp = (br_word_t)&_br_stackalloc_tmp; + p256_coord_add(D, in1+32, in1+32); + p256_coord_sqr(tmp, (in1+32)+32); + p256_coord_sqr(D, D); + p256_coord_mul((out+32)+32, (in1+32)+32, in1+32); + p256_coord_add((out+32)+32, (out+32)+32, (out+32)+32); + p256_coord_add(A, in1, tmp); + p256_coord_sub(tmp, in1, tmp); + uint8_t _br_stackalloc_t2[32] = {0}; t2 = (br_word_t)&_br_stackalloc_t2; + p256_coord_add(t2, tmp, tmp); + p256_coord_add(tmp, t2, tmp); + p256_coord_sqr(out+32, D); + p256_coord_mul(A, A, tmp); + p256_coord_mul(D, D, in1); + p256_coord_sqr(out, A); + p256_coord_add(tmp, D, D); + p256_coord_sub(out, out, tmp); + p256_coord_sub(D, D, out); + p256_coord_mul(D, D, A); + p256_coord_halve(out+32, out+32); + p256_coord_sub(out+32, D, out+32); +} + +static inline br_word_t p256_point_add_nz_nz_neq(br_word_t p_out, br_word_t p_P, br_word_t p_Q) { + br_word_t z1z1, z2z2, u1, Hsqr, ok, different_x, different_y, u2, Hcub, s1, r, h, s2; + uint8_t _br_stackalloc_z1z1[32] = {0}; z1z1 = (br_word_t)&_br_stackalloc_z1z1; + uint8_t _br_stackalloc_z2z2[32] = {0}; z2z2 = (br_word_t)&_br_stackalloc_z2z2; + uint8_t _br_stackalloc_u1[32] = {0}; u1 = (br_word_t)&_br_stackalloc_u1; + uint8_t _br_stackalloc_u2[32] = {0}; u2 = (br_word_t)&_br_stackalloc_u2; + uint8_t _br_stackalloc_h[32] = {0}; h = (br_word_t)&_br_stackalloc_h; + uint8_t _br_stackalloc_s1[32] = {0}; s1 = (br_word_t)&_br_stackalloc_s1; + uint8_t _br_stackalloc_s2[32] = {0}; s2 = (br_word_t)&_br_stackalloc_s2; + uint8_t _br_stackalloc_r[32] = {0}; r = (br_word_t)&_br_stackalloc_r; + uint8_t _br_stackalloc_Hsqr[32] = {0}; Hsqr = (br_word_t)&_br_stackalloc_Hsqr; + uint8_t _br_stackalloc_Hcub[32] = {0}; Hcub = (br_word_t)&_br_stackalloc_Hcub; + p256_coord_sqr(z1z1, (p_P+32)+32); + p256_coord_mul(u2, p_Q, z1z1); + p256_coord_sqr(z2z2, (p_Q+32)+32); + p256_coord_mul(u1, p_P, z2z2); + p256_coord_sub(h, u2, u1); + p256_coord_mul(s2, (p_P+32)+32, z1z1); + p256_coord_mul((p_out+32)+32, h, (p_P+32)+32); + p256_coord_mul((p_out+32)+32, (p_out+32)+32, (p_Q+32)+32); + p256_coord_mul(s2, s2, p_Q+32); + p256_coord_mul(s1, (p_Q+32)+32, z2z2); + p256_coord_mul(s1, s1, p_P+32); + p256_coord_sub(r, s2, s1); + p256_coord_sqr(Hsqr, h); + p256_coord_sqr(p_out, r); + p256_coord_mul(Hcub, Hsqr, h); + p256_coord_mul(u2, u1, Hsqr); + different_x = p256_coord_nonzero(Hcub); + different_y = p256_coord_nonzero(p_out); + ok = br_value_barrier(different_x|different_y); + p256_coord_sub(p_out, p_out, Hcub); + p256_coord_sub(p_out, p_out, u2); + p256_coord_sub(p_out, p_out, u2); + p256_coord_sub(h, u2, p_out); + p256_coord_mul(s2, Hcub, s1); + p256_coord_mul(h, h, r); + p256_coord_sub(p_out+32, h, s2); + return ok; +} + +static inline void p256_point_add_vartime_if_doubling(br_word_t p_out, br_word_t p_P, br_word_t p_Q) { + br_word_t p_tmp, zeroP, zeroQ, ok, p_sel; + zeroP = p256_point_iszero(p_P); + zeroQ = p256_point_iszero(p_Q); + uint8_t _br_stackalloc_p_tmp[96] = {0}; p_tmp = (br_word_t)&_br_stackalloc_p_tmp; + ok = p256_point_add_nz_nz_neq(p_tmp, p_P, p_Q); + ok = br_declassify((zeroP|zeroQ)|ok); + uint8_t _br_stackalloc_p_sel[96] = {0}; p_sel = (br_word_t)&_br_stackalloc_p_sel; + br_memset(p_sel, (br_word_t)0, (br_word_t)96); + br_memcxor(p_sel, p_tmp, (br_word_t)96, (~zeroP)&(~zeroQ)); + br_memcxor(p_sel, p_P, (br_word_t)96, (~zeroP)&zeroQ); + br_memcxor(p_sel, p_Q, (br_word_t)96, zeroP&(~zeroQ)); + if (ok) { + /*skip*/ + } else { + p256_point_double(p_sel, p_P); + } + br_memcpy(p_out, p_sel, (br_word_t)96); +} diff --git a/Sources/CryptoBoringWrapper/Util/FiniteFieldArithmeticContext.swift b/Sources/CryptoBoringWrapper/Util/FiniteFieldArithmeticContext.swift index 39e62b2d9..825932382 100644 --- a/Sources/CryptoBoringWrapper/Util/FiniteFieldArithmeticContext.swift +++ b/Sources/CryptoBoringWrapper/Util/FiniteFieldArithmeticContext.swift @@ -276,7 +276,7 @@ extension FiniteFieldArithmeticContext { _ p: UnsafePointer?, _ m: UnsafePointer?, _ ctx: OpaquePointer?, - _ mont: UnsafePointer? + _ mont: OpaquePointer? ) -> Int32 ) throws -> ArbitraryPrecisionInteger { var result = ArbitraryPrecisionInteger() @@ -302,7 +302,7 @@ extension FiniteFieldArithmeticContext { /// Some functions require a `BN_MONT_CTX` parameter: this obtains one for the field modulus with a scoped lifetime. fileprivate func withUnsafeBN_MONT_CTX( - _ body: (UnsafePointer) throws -> T + _ body: (OpaquePointer) throws -> T ) rethrows -> T { diff --git a/Sources/CryptoExtras/RSA/RSA+BlindSigning.swift b/Sources/CryptoExtras/RSA/RSA+BlindSigning.swift index 10c7a6e2a..3f14da321 100644 --- a/Sources/CryptoExtras/RSA/RSA+BlindSigning.swift +++ b/Sources/CryptoExtras/RSA/RSA+BlindSigning.swift @@ -136,7 +136,7 @@ extension _RSA.BlindSigning { } public func getKeyPrimitives() throws -> Primitives { - let (n, e) = try self.backing.getKeyPrimitives() + let (n, e) = self.backing.getKeyPrimitives() return Primitives(modulus: n, publicExponent: e) } } diff --git a/Sources/CryptoExtras/RSA/RSA.swift b/Sources/CryptoExtras/RSA/RSA.swift index 8942fcebb..180cecabc 100644 --- a/Sources/CryptoExtras/RSA/RSA.swift +++ b/Sources/CryptoExtras/RSA/RSA.swift @@ -146,7 +146,7 @@ extension _RSA.Signing { } public func getKeyPrimitives() throws -> Primitives { - let (n, e) = try self.backing.getKeyPrimitives() + let (n, e) = self.backing.getKeyPrimitives() return Primitives(modulus: n, publicExponent: e) } } @@ -543,7 +543,7 @@ extension _RSA.Encryption { fileprivate init(_ backing: BackingPublicKey) { self.backing = backing } public func getKeyPrimitives() throws -> Primitives { - let (n, e) = try self.backing.getKeyPrimitives() + let (n, e) = self.backing.getKeyPrimitives() return Primitives(modulus: n, publicExponent: e) } } diff --git a/Sources/CryptoExtras/RSA/RSA_boring.swift b/Sources/CryptoExtras/RSA/RSA_boring.swift index 48d6d3c25..c0f3be1ac 100644 --- a/Sources/CryptoExtras/RSA/RSA_boring.swift +++ b/Sources/CryptoExtras/RSA/RSA_boring.swift @@ -81,8 +81,8 @@ internal struct BoringSSLRSAPublicKey: Sendable { self.backing = backing } - func getKeyPrimitives() throws -> (n: Data, e: Data) { - try self.backing.getKeyPrimitives() + func getKeyPrimitives() -> (n: Data, e: Data) { + self.backing.getKeyPrimitives() } } diff --git a/Sources/CryptoExtras/Util/ThreadSpecific/ThreadPosix.swift b/Sources/CryptoExtras/Util/ThreadSpecific/ThreadPosix.swift index 6b2ccdf09..07051a672 100644 --- a/Sources/CryptoExtras/Util/ThreadSpecific/ThreadPosix.swift +++ b/Sources/CryptoExtras/Util/ThreadSpecific/ThreadPosix.swift @@ -25,7 +25,7 @@ // //===----------------------------------------------------------------------===// -#if os(Linux) || os(Android) || os(FreeBSD) || canImport(Darwin) +#if os(Linux) || os(Android) || os(FreeBSD) || os(OpenBSD) || canImport(Darwin) #if canImport(Glibc) @preconcurrency import Glibc #elseif canImport(Bionic) diff --git a/scripts/generate-linux-sdks.sh b/scripts/generate-linux-sdks.sh index 65cd7bfcb..959bc1197 100755 --- a/scripts/generate-linux-sdks.sh +++ b/scripts/generate-linux-sdks.sh @@ -25,10 +25,10 @@ set -e -SWIFT_VERSION=5.10 +SWIFT_VERSION=6.1.2 DISTRO_NAME=ubuntu -DISTRO_VERSION=jammy -DISTRO_VERSION_GENERATOR=22.04 +DISTRO_VERSION=noble +DISTRO_VERSION_GENERATOR=24.04 TMPDIR=$(mktemp -d /tmp/.workingXXXXXX) function generate_swift_sdk { diff --git a/scripts/patch-3-missing-extern-c.patch b/scripts/patch-3-missing-extern-c.patch new file mode 100644 index 000000000..aeda6890e --- /dev/null +++ b/scripts/patch-3-missing-extern-c.patch @@ -0,0 +1,25 @@ +diff --git a/Sources/CCryptoBoringSSL/crypto/fipsmodule/service_indicator/internal.h b/Sources/CCryptoBoringSSL/crypto/fipsmodule/service_indicator/internal.h +index c5a8113..27f8060 100644 +--- a/Sources/CCryptoBoringSSL/crypto/fipsmodule/service_indicator/internal.h ++++ b/Sources/CCryptoBoringSSL/crypto/fipsmodule/service_indicator/internal.h +@@ -17,6 +17,9 @@ + + #include + ++#if defined(__cplusplus) ++extern "C" { ++#endif + + // FIPS_service_indicator_before_call and |FIPS_service_indicator_after_call| + // both currently return the same local thread counter which is slowly +@@ -37,6 +40,10 @@ + OPENSSL_EXPORT uint64_t FIPS_service_indicator_before_call(void); + OPENSSL_EXPORT uint64_t FIPS_service_indicator_after_call(void); + ++#if defined(__cplusplus) ++} ++#endif ++ + #if defined(BORINGSSL_FIPS) + + // FIPS_service_indicator_update_state records that an approved service has been diff --git a/scripts/vendor-boringssl.sh b/scripts/vendor-boringssl.sh index 5727749ad..324099fe8 100755 --- a/scripts/vendor-boringssl.sh +++ b/scripts/vendor-boringssl.sh @@ -87,8 +87,8 @@ function mangle_symbols { # Begin by building for macOS. We build for two target triples, Intel # and Apple Silicon. - swift build --triple "x86_64-apple-macosx" --product CCryptoBoringSSL --enable-test-discovery - swift build --triple "arm64-apple-macosx" --product CCryptoBoringSSL --enable-test-discovery + swift build --triple "x86_64-apple-macosx" --product CCryptoBoringSSL + swift build --triple "arm64-apple-macosx" --product CCryptoBoringSSL ( cd "${SRCROOT}" go mod tidy -modcacherw @@ -107,9 +107,9 @@ function mangle_symbols { # Now cross compile for our targets. # NOTE: This requires running the `generate-linux-sdks.sh` script first to generate the Swift SDKs. - swift build --swift-sdk 5.10-RELEASE_ubuntu_jammy_x86_64 --product CCryptoBoringSSL - swift build --swift-sdk 5.10-RELEASE_ubuntu_jammy_aarch64 --product CCryptoBoringSSL - swift build --swift-sdk 5.10-RELEASE_ubuntu_jammy_armv7 --product CCryptoBoringSSL + swift build --swift-sdk 6.1.2-RELEASE_ubuntu_noble_x86_64 --product CCryptoBoringSSL + swift build --swift-sdk 6.1.2-RELEASE_ubuntu_noble_aarch64 --product CCryptoBoringSSL + swift build --swift-sdk 6.1.2-RELEASE_ubuntu_noble_armv7 --product CCryptoBoringSSL # Now we need to generate symbol mangles for Linux. We can do this in # one go for all of them. @@ -147,6 +147,34 @@ function mangle_symbols { namespace_inlines "$DSTROOT" } +function mangle_cpp_structures { + echo "MANGLING C++ structures" + ( + # We need a .a: may as well get SwiftPM to give it to us. + # Temporarily enable the product we need. + $sed -i -e 's/MANGLE_START/MANGLE_START*\//' -e 's/MANGLE_END/\/*MANGLE_END/' "${HERE}/Package.swift" + + # Build for macOS. + swift build --product CCryptoBoringSSL + + # Woah, this is a hell of a command! What does it do? + # + # The nm command grabs all global defined symbols. We then run the C++ demangler over them and look for methods with '::' in them: + # these are C++ methods. We then exclude any that contain CCryptoBoringSSL (as those are already namespaced!) and any that contain swift + # (as those were put there by the Swift runtime, not us). This gives us a list of symbols. The following cut command + # grabs the type name from each of those (the bit preceding the '::'). Then, we sort and uniqify that list. + # Finally, we remove any symbol that ends in std. This gives us all the structures that need to be renamed. + structures=$(nm -gUj "$(swift build --show-bin-path)/libCCryptoBoringSSL.a" | c++filt | grep "::" | grep -v -e "CCryptoBoringSSL" -e "swift" | cut -d : -f1 | grep -v "std$" | $sed -E -e 's/([^<>]*)(<[^<>]*>)?/\1/' | sort | uniq) + + for struct in ${structures}; do + echo "#define ${struct} BORINGSSL_ADD_PREFIX(BORINGSSL_PREFIX, ${struct})" >> "${DSTROOT}/include/CCryptoBoringSSL_boringssl_prefix_symbols.h" + done + + # Remove the product, as we no longer need it. + $sed -i -e 's/MANGLE_START\*\//MANGLE_START/' -e 's/\/\*MANGLE_END/MANGLE_END/' "${HERE}/Package.swift" + ) +} + case "$(uname -s)" in Darwin) sed=gsed @@ -175,10 +203,10 @@ echo "CLONING boringssl" mkdir -p "$SRCROOT" git clone https://boringssl.googlesource.com/boringssl "$SRCROOT" cd "$SRCROOT" -if [ "$BORINGSSL_REVISION" ]; then +if [ "${BORINGSSL_REVISION:-}" ]; then echo "CHECKING OUT boringssl@${BORINGSSL_REVISION}" git checkout "$BORINGSSL_REVISION" -else +else BORINGSSL_REVISION=$(git rev-parse HEAD) echo "CLONED boringssl@${BORINGSSL_REVISION}" fi @@ -200,7 +228,6 @@ echo "GENERATING assembly helpers" PATTERNS=( 'include/openssl/*.h' -'include/openssl/experimental/*.h' 'ssl/*.h' 'ssl/*.cc' 'crypto/*.h' @@ -218,7 +245,7 @@ PATTERNS=( 'gen/bcm/*.S' 'third_party/fiat/*.h' 'third_party/fiat/asm/*.S' -#'third_party/fiat/*.c' +'third_party/fiat/*.c.inc' ) EXCLUDES=( @@ -262,6 +289,11 @@ echo "DISABLING assembly on x86 Windows" ) +# Unfortunately, this patch for an upstream bug which incorrectly leaves C symbol using C++ mangling must be +# applied before we mangle symbols, so we can't place it with the others below. +echo "PATCHING BoringSSL (early)" +git apply "${HERE}/scripts/patch-3-missing-extern-c.patch" + mangle_symbols echo "RENAMING header files" @@ -295,6 +327,10 @@ echo "RENAMING header files" popd ) +echo "PATCHING BoringSSL" +git apply "${HERE}/scripts/patch-1-inttypes.patch" +git apply "${HERE}/scripts/patch-2-more-inttypes.patch" + # We need to avoid having the stack be executable. BoringSSL does this in its build system, but we can't. echo "PROTECTING against executable stacks" ( @@ -303,9 +339,7 @@ echo "PROTECTING against executable stacks" find . -name "*.S" | xargs $sed -i '$ a #if defined(__linux__) && defined(__ELF__)\n.section .note.GNU-stack,"",%progbits\n#endif\n' ) -echo "PATCHING BoringSSL" -git apply "${HERE}/scripts/patch-1-inttypes.patch" -git apply "${HERE}/scripts/patch-2-more-inttypes.patch" +mangle_cpp_structures # We need BoringSSL to be modularised echo "MODULARISING BoringSSL" @@ -357,6 +391,8 @@ cat << EOF > "$DSTROOT/include/CCryptoBoringSSL.h" #include "CCryptoBoringSSL_hrss.h" #include "CCryptoBoringSSL_md4.h" #include "CCryptoBoringSSL_md5.h" +#include "CCryptoBoringSSL_mldsa.h" +#include "CCryptoBoringSSL_mlkem.h" #include "CCryptoBoringSSL_obj_mac.h" #include "CCryptoBoringSSL_objects.h" #include "CCryptoBoringSSL_opensslv.h" From 6ebab68ef5337828b413dbb05ee4834712ad7a99 Mon Sep 17 00:00:00 2001 From: Francesco Paolo Severino Date: Mon, 29 Sep 2025 16:16:07 +0200 Subject: [PATCH 43/47] Remove `MLDSA_boring.swift` --- .../Signatures/BoringSSL/MLDSA_boring.swift | 645 ------------------ .../BoringSSL/MLDSA_boring.swift.gyb | 348 ---------- 2 files changed, 993 deletions(-) delete mode 100644 Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift delete mode 100644 Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb diff --git a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift deleted file mode 100644 index 05150b49f..000000000 --- a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift +++ /dev/null @@ -1,645 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the SwiftCrypto open source project -// -// Copyright (c) 2024 Apple Inc. and the SwiftCrypto project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API -@_exported import CryptoKit -#else -@_implementationOnly import CCryptoBoringSSL -#if canImport(FoundationEssentials) -import FoundationEssentials -#else -import Foundation -#endif - -// MARK: - Generated file, do NOT edit -// any edits of this file WILL be overwritten and thus discarded -// see section `gyb` in `README` for details. - -@_implementationOnly import CCryptoBoringSSL -#if canImport(FoundationEssentials) -import FoundationEssentials -#else -import Foundation -#endif - -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -extension MLDSA65 { - /// A ML-DSA-65 private key. - struct InternalPrivateKey: @unchecked Sendable { - private var backing: Backing - - /// Initialize a ML-DSA-65 private key from a random seed. - init() throws { - self.backing = try Backing() - } - - /// Initialize a ML-DSA-65 private key from a seed. - /// - /// - Parameter seedRepresentation: The seed to use to generate the private key. - /// - /// - Throws: `CryptoKitError.incorrectKeySize` if the seed is not 32 bytes long. - init(seedRepresentation: some DataProtocol) throws { - self.backing = try Backing(seedRepresentation: seedRepresentation) - } - - /// The seed from which this private key was generated. - var seedRepresentation: Data { - self.backing.seed - } - - /// The public key associated with this private key. - var publicKey: InternalPublicKey { - self.backing.publicKey - } - - /// Generate a signature for the given data. - /// - /// - Parameter data: The message to sign. - /// - /// - Returns: The signature of the message. - func signature(for data: D) throws -> Data { - let context: Data? = nil - return try self.backing.signature(for: data, context: context) - } - - /// Generate a signature for the given data. - /// - /// - Parameters: - /// - data: The message to sign. - /// - context: The context to use for the signature. - /// - /// - Returns: The signature of the message. - func signature(for data: D, context: C) throws -> Data { - try self.backing.signature(for: data, context: context) - } - - /// The size of the private key in bytes. - static let byteCount = Backing.byteCount - - fileprivate final class Backing { - fileprivate var key: MLDSA65_private_key - var seed: Data - - /// Initialize a ML-DSA-65 private key from a random seed. - init() throws { - // We have to initialize all members before `self` is captured by the closure - self.key = .init() - self.seed = Data() - - self.seed = try withUnsafeTemporaryAllocation( - of: UInt8.self, - capacity: MLDSA.seedByteCount - ) { seedPtr in - try withUnsafeTemporaryAllocation( - of: UInt8.self, - capacity: MLDSA65.InternalPublicKey.Backing.byteCount - ) { publicKeyPtr in - guard - CCryptoBoringSSL_MLDSA65_generate_key( - publicKeyPtr.baseAddress, - seedPtr.baseAddress, - &self.key - ) == 1 - else { - throw CryptoKitError.internalBoringSSLError() - } - - return Data(bytes: seedPtr.baseAddress!, count: MLDSA.seedByteCount) - } - } - } - - /// Initialize a ML-DSA-65 private key from a seed. - /// - /// - Parameter seedRepresentation: The seed to use to generate the private key. - /// - /// - Throws: `CryptoKitError.incorrectKeySize` if the seed is not 32 bytes long. - init(seedRepresentation: some DataProtocol) throws { - guard seedRepresentation.count == MLDSA.seedByteCount else { - throw CryptoKitError.incorrectKeySize - } - - self.key = .init() - self.seed = Data(seedRepresentation) - - guard - self.seed.withUnsafeBytes({ seedPtr in - CCryptoBoringSSL_MLDSA65_private_key_from_seed( - &self.key, - seedPtr.baseAddress, - MLDSA.seedByteCount - ) - }) == 1 - else { - throw CryptoKitError.internalBoringSSLError() - } - } - - /// The public key associated with this private key. - var publicKey: InternalPublicKey { - InternalPublicKey(privateKeyBacking: self) - } - - /// Generate a signature for the given data. - /// - /// - Parameters: - /// - data: The message to sign. - /// - context: The context to use for the signature. - /// - /// - Returns: The signature of the message. - func signature(for data: D, context: C?) throws -> Data { - var signature = Data(repeating: 0, count: MLDSA65.signatureByteCount) - - let rc: CInt = signature.withUnsafeMutableBytes { signaturePtr in - let bytes: ContiguousBytes = data.regions.count == 1 ? data.regions.first! : Array(data) - return bytes.withUnsafeBytes { dataPtr in - context.withUnsafeBytes { contextPtr in - CCryptoBoringSSL_MLDSA65_sign( - signaturePtr.baseAddress, - &self.key, - dataPtr.baseAddress, - dataPtr.count, - contextPtr.baseAddress, - contextPtr.count - ) - } - } - } - - guard rc == 1 else { - throw CryptoKitError.internalBoringSSLError() - } - - return signature - } - - /// The size of the private key in bytes. - static let byteCount = Int(MLDSA65_PRIVATE_KEY_BYTES) - } - } -} - -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -extension MLDSA65 { - /// A ML-DSA-65 public key. - struct InternalPublicKey: @unchecked Sendable { - private var backing: Backing - - fileprivate init(privateKeyBacking: InternalPrivateKey.Backing) { - self.backing = Backing(privateKeyBacking: privateKeyBacking) - } - - /// Initialize a ML-DSA-65 public key from a raw representation. - /// - /// - Parameter rawRepresentation: The public key bytes. - /// - /// - Throws: `CryptoKitError.incorrectKeySize` if the raw representation is not the correct size. - init(rawRepresentation: some DataProtocol) throws { - self.backing = try Backing(rawRepresentation: rawRepresentation) - } - - /// The raw binary representation of the public key. - var rawRepresentation: Data { - self.backing.rawRepresentation - } - - /// Verify a signature for the given data. - /// - /// - Parameters: - /// - signature: The signature to verify. - /// - data: The message to verify the signature against. - /// - /// - Returns: `true` if the signature is valid, `false` otherwise. - func isValidSignature(_ signature: S, for data: D) -> Bool { - let context: Data? = nil - return self.backing.isValidSignature(signature, for: data, context: context) - } - - /// Verify a signature for the given data. - /// - /// - Parameters: - /// - signature: The signature to verify. - /// - data: The message to verify the signature against. - /// - context: The context to use for the signature verification. - /// - /// - Returns: `true` if the signature is valid, `false` otherwise. - func isValidSignature( - _ signature: S, - for data: D, - context: C - ) -> Bool { - self.backing.isValidSignature(signature, for: data, context: context) - } - - /// The size of the public key in bytes. - static let byteCount = Backing.byteCount - - fileprivate final class Backing { - private var key: MLDSA65_public_key - - init(privateKeyBacking: InternalPrivateKey.Backing) { - self.key = .init() - CCryptoBoringSSL_MLDSA65_public_from_private(&self.key, &privateKeyBacking.key) - } - - /// Initialize a ML-DSA-65 public key from a raw representation. - /// - /// - Parameter rawRepresentation: The public key bytes. - /// - /// - Throws: `CryptoKitError.incorrectKeySize` if the raw representation is not the correct size. - init(rawRepresentation: some DataProtocol) throws { - guard rawRepresentation.count == MLDSA65.InternalPublicKey.Backing.byteCount else { - throw CryptoKitError.incorrectKeySize - } - - self.key = .init() - - let bytes: ContiguousBytes = - rawRepresentation.regions.count == 1 - ? rawRepresentation.regions.first! - : Array(rawRepresentation) - try bytes.withUnsafeBytes { rawBuffer in - try rawBuffer.withMemoryRebound(to: UInt8.self) { buffer in - var cbs = CBS(data: buffer.baseAddress, len: buffer.count) - guard CCryptoBoringSSL_MLDSA65_parse_public_key(&self.key, &cbs) == 1 else { - throw CryptoKitError.internalBoringSSLError() - } - } - } - } - - /// The raw binary representation of the public key. - var rawRepresentation: Data { - var cbb = CBB() - // The following BoringSSL functions can only fail on allocation failure, which we define as impossible. - CCryptoBoringSSL_CBB_init(&cbb, MLDSA65.InternalPublicKey.Backing.byteCount) - defer { CCryptoBoringSSL_CBB_cleanup(&cbb) } - CCryptoBoringSSL_MLDSA65_marshal_public_key(&cbb, &self.key) - return Data(bytes: CCryptoBoringSSL_CBB_data(&cbb), count: CCryptoBoringSSL_CBB_len(&cbb)) - } - - /// Verify a signature for the given data. - /// - /// - Parameters: - /// - signature: The signature to verify. - /// - data: The message to verify the signature against. - /// - context: The context to use for the signature verification. - /// - /// - Returns: `true` if the signature is valid, `false` otherwise. - func isValidSignature( - _ signature: S, - for data: D, - context: C? - ) -> Bool { - let signatureBytes: ContiguousBytes = - signature.regions.count == 1 ? signature.regions.first! : Array(signature) - return signatureBytes.withUnsafeBytes { signaturePtr in - let dataBytes: ContiguousBytes = data.regions.count == 1 ? data.regions.first! : Array(data) - let rc: CInt = dataBytes.withUnsafeBytes { dataPtr in - context.withUnsafeBytes { contextPtr in - CCryptoBoringSSL_MLDSA65_verify( - &self.key, - signaturePtr.baseAddress, - signaturePtr.count, - dataPtr.baseAddress, - dataPtr.count, - contextPtr.baseAddress, - contextPtr.count - ) - } - } - return rc == 1 - } - } - - /// The size of the public key in bytes. - static let byteCount = Int(MLDSA65_PUBLIC_KEY_BYTES) - } - } -} - -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -extension MLDSA65 { - /// The size of the signature in bytes. - private static let signatureByteCount = Int(MLDSA65_SIGNATURE_BYTES) -} - -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -extension MLDSA87 { - /// A ML-DSA-87 private key. - struct InternalPrivateKey: @unchecked Sendable { - private var backing: Backing - - /// Initialize a ML-DSA-87 private key from a random seed. - init() throws { - self.backing = try Backing() - } - - /// Initialize a ML-DSA-87 private key from a seed. - /// - /// - Parameter seedRepresentation: The seed to use to generate the private key. - /// - /// - Throws: `CryptoKitError.incorrectKeySize` if the seed is not 32 bytes long. - init(seedRepresentation: some DataProtocol) throws { - self.backing = try Backing(seedRepresentation: seedRepresentation) - } - - /// The seed from which this private key was generated. - var seedRepresentation: Data { - self.backing.seed - } - - /// The public key associated with this private key. - var publicKey: InternalPublicKey { - self.backing.publicKey - } - - /// Generate a signature for the given data. - /// - /// - Parameter data: The message to sign. - /// - /// - Returns: The signature of the message. - func signature(for data: D) throws -> Data { - let context: Data? = nil - return try self.backing.signature(for: data, context: context) - } - - /// Generate a signature for the given data. - /// - /// - Parameters: - /// - data: The message to sign. - /// - context: The context to use for the signature. - /// - /// - Returns: The signature of the message. - func signature(for data: D, context: C) throws -> Data { - try self.backing.signature(for: data, context: context) - } - - /// The size of the private key in bytes. - static let byteCount = Backing.byteCount - - fileprivate final class Backing { - fileprivate var key: MLDSA87_private_key - var seed: Data - - /// Initialize a ML-DSA-87 private key from a random seed. - init() throws { - // We have to initialize all members before `self` is captured by the closure - self.key = .init() - self.seed = Data() - - self.seed = try withUnsafeTemporaryAllocation( - of: UInt8.self, - capacity: MLDSA.seedByteCount - ) { seedPtr in - try withUnsafeTemporaryAllocation( - of: UInt8.self, - capacity: MLDSA87.InternalPublicKey.Backing.byteCount - ) { publicKeyPtr in - guard - CCryptoBoringSSL_MLDSA87_generate_key( - publicKeyPtr.baseAddress, - seedPtr.baseAddress, - &self.key - ) == 1 - else { - throw CryptoKitError.internalBoringSSLError() - } - - return Data(bytes: seedPtr.baseAddress!, count: MLDSA.seedByteCount) - } - } - } - - /// Initialize a ML-DSA-87 private key from a seed. - /// - /// - Parameter seedRepresentation: The seed to use to generate the private key. - /// - /// - Throws: `CryptoKitError.incorrectKeySize` if the seed is not 32 bytes long. - init(seedRepresentation: some DataProtocol) throws { - guard seedRepresentation.count == MLDSA.seedByteCount else { - throw CryptoKitError.incorrectKeySize - } - - self.key = .init() - self.seed = Data(seedRepresentation) - - guard - self.seed.withUnsafeBytes({ seedPtr in - CCryptoBoringSSL_MLDSA87_private_key_from_seed( - &self.key, - seedPtr.baseAddress, - MLDSA.seedByteCount - ) - }) == 1 - else { - throw CryptoKitError.internalBoringSSLError() - } - } - - /// The public key associated with this private key. - var publicKey: InternalPublicKey { - InternalPublicKey(privateKeyBacking: self) - } - - /// Generate a signature for the given data. - /// - /// - Parameters: - /// - data: The message to sign. - /// - context: The context to use for the signature. - /// - /// - Returns: The signature of the message. - func signature(for data: D, context: C?) throws -> Data { - var signature = Data(repeating: 0, count: MLDSA87.signatureByteCount) - - let rc: CInt = signature.withUnsafeMutableBytes { signaturePtr in - let bytes: ContiguousBytes = data.regions.count == 1 ? data.regions.first! : Array(data) - return bytes.withUnsafeBytes { dataPtr in - context.withUnsafeBytes { contextPtr in - CCryptoBoringSSL_MLDSA87_sign( - signaturePtr.baseAddress, - &self.key, - dataPtr.baseAddress, - dataPtr.count, - contextPtr.baseAddress, - contextPtr.count - ) - } - } - } - - guard rc == 1 else { - throw CryptoKitError.internalBoringSSLError() - } - - return signature - } - - /// The size of the private key in bytes. - static let byteCount = Int(MLDSA87_PRIVATE_KEY_BYTES) - } - } -} - -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -extension MLDSA87 { - /// A ML-DSA-87 public key. - struct InternalPublicKey: @unchecked Sendable { - private var backing: Backing - - fileprivate init(privateKeyBacking: InternalPrivateKey.Backing) { - self.backing = Backing(privateKeyBacking: privateKeyBacking) - } - - /// Initialize a ML-DSA-87 public key from a raw representation. - /// - /// - Parameter rawRepresentation: The public key bytes. - /// - /// - Throws: `CryptoKitError.incorrectKeySize` if the raw representation is not the correct size. - init(rawRepresentation: some DataProtocol) throws { - self.backing = try Backing(rawRepresentation: rawRepresentation) - } - - /// The raw binary representation of the public key. - var rawRepresentation: Data { - self.backing.rawRepresentation - } - - /// Verify a signature for the given data. - /// - /// - Parameters: - /// - signature: The signature to verify. - /// - data: The message to verify the signature against. - /// - /// - Returns: `true` if the signature is valid, `false` otherwise. - func isValidSignature(_ signature: S, for data: D) -> Bool { - let context: Data? = nil - return self.backing.isValidSignature(signature, for: data, context: context) - } - - /// Verify a signature for the given data. - /// - /// - Parameters: - /// - signature: The signature to verify. - /// - data: The message to verify the signature against. - /// - context: The context to use for the signature verification. - /// - /// - Returns: `true` if the signature is valid, `false` otherwise. - func isValidSignature( - _ signature: S, - for data: D, - context: C - ) -> Bool { - self.backing.isValidSignature(signature, for: data, context: context) - } - - /// The size of the public key in bytes. - static let byteCount = Backing.byteCount - - fileprivate final class Backing { - private var key: MLDSA87_public_key - - init(privateKeyBacking: InternalPrivateKey.Backing) { - self.key = .init() - CCryptoBoringSSL_MLDSA87_public_from_private(&self.key, &privateKeyBacking.key) - } - - /// Initialize a ML-DSA-87 public key from a raw representation. - /// - /// - Parameter rawRepresentation: The public key bytes. - /// - /// - Throws: `CryptoKitError.incorrectKeySize` if the raw representation is not the correct size. - init(rawRepresentation: some DataProtocol) throws { - guard rawRepresentation.count == MLDSA87.InternalPublicKey.Backing.byteCount else { - throw CryptoKitError.incorrectKeySize - } - - self.key = .init() - - let bytes: ContiguousBytes = - rawRepresentation.regions.count == 1 - ? rawRepresentation.regions.first! - : Array(rawRepresentation) - try bytes.withUnsafeBytes { rawBuffer in - try rawBuffer.withMemoryRebound(to: UInt8.self) { buffer in - var cbs = CBS(data: buffer.baseAddress, len: buffer.count) - guard CCryptoBoringSSL_MLDSA87_parse_public_key(&self.key, &cbs) == 1 else { - throw CryptoKitError.internalBoringSSLError() - } - } - } - } - - /// The raw binary representation of the public key. - var rawRepresentation: Data { - var cbb = CBB() - // The following BoringSSL functions can only fail on allocation failure, which we define as impossible. - CCryptoBoringSSL_CBB_init(&cbb, MLDSA87.InternalPublicKey.Backing.byteCount) - defer { CCryptoBoringSSL_CBB_cleanup(&cbb) } - CCryptoBoringSSL_MLDSA87_marshal_public_key(&cbb, &self.key) - return Data(bytes: CCryptoBoringSSL_CBB_data(&cbb), count: CCryptoBoringSSL_CBB_len(&cbb)) - } - - /// Verify a signature for the given data. - /// - /// - Parameters: - /// - signature: The signature to verify. - /// - data: The message to verify the signature against. - /// - context: The context to use for the signature verification. - /// - /// - Returns: `true` if the signature is valid, `false` otherwise. - func isValidSignature( - _ signature: S, - for data: D, - context: C? - ) -> Bool { - let signatureBytes: ContiguousBytes = - signature.regions.count == 1 ? signature.regions.first! : Array(signature) - return signatureBytes.withUnsafeBytes { signaturePtr in - let dataBytes: ContiguousBytes = data.regions.count == 1 ? data.regions.first! : Array(data) - let rc: CInt = dataBytes.withUnsafeBytes { dataPtr in - context.withUnsafeBytes { contextPtr in - CCryptoBoringSSL_MLDSA87_verify( - &self.key, - signaturePtr.baseAddress, - signaturePtr.count, - dataPtr.baseAddress, - dataPtr.count, - contextPtr.baseAddress, - contextPtr.count - ) - } - } - return rc == 1 - } - } - - /// The size of the public key in bytes. - static let byteCount = Int(MLDSA87_PUBLIC_KEY_BYTES) - } - } -} - -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -extension MLDSA87 { - /// The size of the signature in bytes. - private static let signatureByteCount = Int(MLDSA87_SIGNATURE_BYTES) -} - -enum MLDSA { - /// The size of the seed in bytes. - static let seedByteCount = 32 -} - -#endif // CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API diff --git a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb b/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb deleted file mode 100644 index 27aaa2396..000000000 --- a/Sources/Crypto/Signatures/BoringSSL/MLDSA_boring.swift.gyb +++ /dev/null @@ -1,348 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the SwiftCrypto open source project -// -// Copyright (c) 2024 Apple Inc. and the SwiftCrypto project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -#if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API -@_exported import CryptoKit -#else -@_implementationOnly import CCryptoBoringSSL -#if canImport(FoundationEssentials) -import FoundationEssentials -#else -import Foundation -#endif - -// MARK: - Generated file, do NOT edit -// any edits of this file WILL be overwritten and thus discarded -// see section `gyb` in `README` for details. - -@_implementationOnly import CCryptoBoringSSL -#if canImport(FoundationEssentials) -import FoundationEssentials -#else -import Foundation -#endif -%{ - parameter_sets = ["65", "87"] -}% -% for parameter_set in parameter_sets: - -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -extension MLDSA${parameter_set} { - /// A ML-DSA-${parameter_set} private key. - struct InternalPrivateKey: @unchecked Sendable { - private var backing: Backing - - /// Initialize a ML-DSA-${parameter_set} private key from a random seed. - init() throws { - self.backing = try Backing() - } - - /// Initialize a ML-DSA-${parameter_set} private key from a seed. - /// - /// - Parameter seedRepresentation: The seed to use to generate the private key. - /// - /// - Throws: `CryptoKitError.incorrectKeySize` if the seed is not 32 bytes long. - init(seedRepresentation: some DataProtocol) throws { - self.backing = try Backing(seedRepresentation: seedRepresentation) - } - - /// The seed from which this private key was generated. - var seedRepresentation: Data { - self.backing.seed - } - - /// The public key associated with this private key. - var publicKey: InternalPublicKey { - self.backing.publicKey - } - - /// Generate a signature for the given data. - /// - /// - Parameter data: The message to sign. - /// - /// - Returns: The signature of the message. - func signature(for data: D) throws -> Data { - let context: Data? = nil - return try self.backing.signature(for: data, context: context) - } - - /// Generate a signature for the given data. - /// - /// - Parameters: - /// - data: The message to sign. - /// - context: The context to use for the signature. - /// - /// - Returns: The signature of the message. - func signature(for data: D, context: C) throws -> Data { - try self.backing.signature(for: data, context: context) - } - - /// The size of the private key in bytes. - static let byteCount = Backing.byteCount - - fileprivate final class Backing { - fileprivate var key: MLDSA${parameter_set}_private_key - var seed: Data - - /// Initialize a ML-DSA-${parameter_set} private key from a random seed. - init() throws { - // We have to initialize all members before `self` is captured by the closure - self.key = .init() - self.seed = Data() - - self.seed = try withUnsafeTemporaryAllocation( - of: UInt8.self, - capacity: MLDSA.seedByteCount - ) { seedPtr in - try withUnsafeTemporaryAllocation( - of: UInt8.self, - capacity: MLDSA${parameter_set}.InternalPublicKey.Backing.byteCount - ) { publicKeyPtr in - guard - CCryptoBoringSSL_MLDSA${parameter_set}_generate_key( - publicKeyPtr.baseAddress, - seedPtr.baseAddress, - &self.key - ) == 1 - else { - throw CryptoKitError.internalBoringSSLError() - } - - return Data(bytes: seedPtr.baseAddress!, count: MLDSA.seedByteCount) - } - } - } - - /// Initialize a ML-DSA-${parameter_set} private key from a seed. - /// - /// - Parameter seedRepresentation: The seed to use to generate the private key. - /// - /// - Throws: `CryptoKitError.incorrectKeySize` if the seed is not 32 bytes long. - init(seedRepresentation: some DataProtocol) throws { - guard seedRepresentation.count == MLDSA.seedByteCount else { - throw CryptoKitError.incorrectKeySize - } - - self.key = .init() - self.seed = Data(seedRepresentation) - - guard - self.seed.withUnsafeBytes({ seedPtr in - CCryptoBoringSSL_MLDSA${parameter_set}_private_key_from_seed( - &self.key, - seedPtr.baseAddress, - MLDSA.seedByteCount - ) - }) == 1 - else { - throw CryptoKitError.internalBoringSSLError() - } - } - - /// The public key associated with this private key. - var publicKey: InternalPublicKey { - InternalPublicKey(privateKeyBacking: self) - } - - /// Generate a signature for the given data. - /// - /// - Parameters: - /// - data: The message to sign. - /// - context: The context to use for the signature. - /// - /// - Returns: The signature of the message. - func signature(for data: D, context: C?) throws -> Data { - var signature = Data(repeating: 0, count: MLDSA${parameter_set}.signatureByteCount) - - let rc: CInt = signature.withUnsafeMutableBytes { signaturePtr in - let bytes: ContiguousBytes = data.regions.count == 1 ? data.regions.first! : Array(data) - return bytes.withUnsafeBytes { dataPtr in - context.withUnsafeBytes { contextPtr in - CCryptoBoringSSL_MLDSA${parameter_set}_sign( - signaturePtr.baseAddress, - &self.key, - dataPtr.baseAddress, - dataPtr.count, - contextPtr.baseAddress, - contextPtr.count - ) - } - } - } - - guard rc == 1 else { - throw CryptoKitError.internalBoringSSLError() - } - - return signature - } - - /// The size of the private key in bytes. - static let byteCount = Int(MLDSA${parameter_set}_PRIVATE_KEY_BYTES) - } - } -} - -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -extension MLDSA${parameter_set} { - /// A ML-DSA-${parameter_set} public key. - struct InternalPublicKey: @unchecked Sendable { - private var backing: Backing - - fileprivate init(privateKeyBacking: InternalPrivateKey.Backing) { - self.backing = Backing(privateKeyBacking: privateKeyBacking) - } - - /// Initialize a ML-DSA-${parameter_set} public key from a raw representation. - /// - /// - Parameter rawRepresentation: The public key bytes. - /// - /// - Throws: `CryptoKitError.incorrectKeySize` if the raw representation is not the correct size. - init(rawRepresentation: some DataProtocol) throws { - self.backing = try Backing(rawRepresentation: rawRepresentation) - } - - /// The raw binary representation of the public key. - var rawRepresentation: Data { - self.backing.rawRepresentation - } - - /// Verify a signature for the given data. - /// - /// - Parameters: - /// - signature: The signature to verify. - /// - data: The message to verify the signature against. - /// - /// - Returns: `true` if the signature is valid, `false` otherwise. - func isValidSignature(_ signature: S, for data: D) -> Bool { - let context: Data? = nil - return self.backing.isValidSignature(signature, for: data, context: context) - } - - /// Verify a signature for the given data. - /// - /// - Parameters: - /// - signature: The signature to verify. - /// - data: The message to verify the signature against. - /// - context: The context to use for the signature verification. - /// - /// - Returns: `true` if the signature is valid, `false` otherwise. - func isValidSignature( - _ signature: S, - for data: D, - context: C - ) -> Bool { - self.backing.isValidSignature(signature, for: data, context: context) - } - - /// The size of the public key in bytes. - static let byteCount = Backing.byteCount - - fileprivate final class Backing { - private var key: MLDSA${parameter_set}_public_key - - init(privateKeyBacking: InternalPrivateKey.Backing) { - self.key = .init() - CCryptoBoringSSL_MLDSA${parameter_set}_public_from_private(&self.key, &privateKeyBacking.key) - } - - /// Initialize a ML-DSA-${parameter_set} public key from a raw representation. - /// - /// - Parameter rawRepresentation: The public key bytes. - /// - /// - Throws: `CryptoKitError.incorrectKeySize` if the raw representation is not the correct size. - init(rawRepresentation: some DataProtocol) throws { - guard rawRepresentation.count == MLDSA${parameter_set}.InternalPublicKey.Backing.byteCount else { - throw CryptoKitError.incorrectKeySize - } - - self.key = .init() - - let bytes: ContiguousBytes = - rawRepresentation.regions.count == 1 - ? rawRepresentation.regions.first! - : Array(rawRepresentation) - try bytes.withUnsafeBytes { rawBuffer in - try rawBuffer.withMemoryRebound(to: UInt8.self) { buffer in - var cbs = CBS(data: buffer.baseAddress, len: buffer.count) - guard CCryptoBoringSSL_MLDSA${parameter_set}_parse_public_key(&self.key, &cbs) == 1 else { - throw CryptoKitError.internalBoringSSLError() - } - } - } - } - - /// The raw binary representation of the public key. - var rawRepresentation: Data { - var cbb = CBB() - // The following BoringSSL functions can only fail on allocation failure, which we define as impossible. - CCryptoBoringSSL_CBB_init(&cbb, MLDSA${parameter_set}.InternalPublicKey.Backing.byteCount) - defer { CCryptoBoringSSL_CBB_cleanup(&cbb) } - CCryptoBoringSSL_MLDSA${parameter_set}_marshal_public_key(&cbb, &self.key) - return Data(bytes: CCryptoBoringSSL_CBB_data(&cbb), count: CCryptoBoringSSL_CBB_len(&cbb)) - } - - /// Verify a signature for the given data. - /// - /// - Parameters: - /// - signature: The signature to verify. - /// - data: The message to verify the signature against. - /// - context: The context to use for the signature verification. - /// - /// - Returns: `true` if the signature is valid, `false` otherwise. - func isValidSignature( - _ signature: S, - for data: D, - context: C? - ) -> Bool { - let signatureBytes: ContiguousBytes = - signature.regions.count == 1 ? signature.regions.first! : Array(signature) - return signatureBytes.withUnsafeBytes { signaturePtr in - let dataBytes: ContiguousBytes = data.regions.count == 1 ? data.regions.first! : Array(data) - let rc: CInt = dataBytes.withUnsafeBytes { dataPtr in - context.withUnsafeBytes { contextPtr in - CCryptoBoringSSL_MLDSA${parameter_set}_verify( - &self.key, - signaturePtr.baseAddress, - signaturePtr.count, - dataPtr.baseAddress, - dataPtr.count, - contextPtr.baseAddress, - contextPtr.count - ) - } - } - return rc == 1 - } - } - - /// The size of the public key in bytes. - static let byteCount = Int(MLDSA${parameter_set}_PUBLIC_KEY_BYTES) - } - } -} - -@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) -extension MLDSA${parameter_set} { - /// The size of the signature in bytes. - private static let signatureByteCount = Int(MLDSA${parameter_set}_SIGNATURE_BYTES) -} -% end - -enum MLDSA { - /// The size of the seed in bytes. - static let seedByteCount = 32 -} - -#endif // CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API From ccde93d50e66b8e33f495cc53b50fa498663bd1e Mon Sep 17 00:00:00 2001 From: Francesco Paolo Severino Date: Wed, 8 Oct 2025 11:20:28 +0200 Subject: [PATCH 44/47] Remove old `Optional+withUnsafeBytes` --- .../Optional+withUnsafeBytes_boring.swift | 30 ------------------- 1 file changed, 30 deletions(-) delete mode 100644 Sources/Crypto/Util/BoringSSL/Optional+withUnsafeBytes_boring.swift diff --git a/Sources/Crypto/Util/BoringSSL/Optional+withUnsafeBytes_boring.swift b/Sources/Crypto/Util/BoringSSL/Optional+withUnsafeBytes_boring.swift deleted file mode 100644 index 8d8aabaca..000000000 --- a/Sources/Crypto/Util/BoringSSL/Optional+withUnsafeBytes_boring.swift +++ /dev/null @@ -1,30 +0,0 @@ -//===----------------------------------------------------------------------===// -// -// This source file is part of the SwiftCrypto open source project -// -// Copyright (c) 2024 Apple Inc. and the SwiftCrypto project authors -// Licensed under Apache License v2.0 -// -// See LICENSE.txt for license information -// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors -// -// SPDX-License-Identifier: Apache-2.0 -// -//===----------------------------------------------------------------------===// - -#if canImport(FoundationEssentials) -import FoundationEssentials -#else -import Foundation -#endif - -extension Optional where Wrapped: DataProtocol { - func withUnsafeBytes(_ body: (UnsafeRawBufferPointer) throws -> ReturnValue) rethrows -> ReturnValue { - if let self { - let bytes: ContiguousBytes = self.regions.count == 1 ? self.regions.first! : Array(self) - return try bytes.withUnsafeBytes { try body($0) } - } else { - return try body(UnsafeRawBufferPointer(start: nil, count: 0)) - } - } -} From e754aae95ca033c6814bc30363f77c568374bb6d Mon Sep 17 00:00:00 2001 From: Francesco Paolo Severino Date: Thu, 23 Oct 2025 11:47:01 +0200 Subject: [PATCH 45/47] Update CMakeLists --- Sources/Crypto/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/Sources/Crypto/CMakeLists.txt b/Sources/Crypto/CMakeLists.txt index ed22804c9..f8bc0fc52 100644 --- a/Sources/Crypto/CMakeLists.txt +++ b/Sources/Crypto/CMakeLists.txt @@ -98,7 +98,6 @@ add_library(Crypto "Signatures/MLDSA.swift" "Signatures/Signature.swift" "Util/BoringSSL/CryptoKitErrors_boring.swift" - "Util/BoringSSL/Optional+withUnsafeBytes_boring.swift" "Util/BoringSSL/RNG_boring.swift" "Util/BoringSSL/SafeCompare_boring.swift" "Util/BoringSSL/Zeroization_boring.swift" From 44633a320a0ee9e742f4dfa59537a6546437079d Mon Sep 17 00:00:00 2001 From: Francesco Paolo Severino Date: Thu, 23 Oct 2025 11:48:39 +0200 Subject: [PATCH 46/47] Add ML-DSA-44 --- .../MLDSA/BoringSSLMLDSA.swift | 404 ++++++++++++++++++ .../MLDSA/BoringSSLMLDSA.swift.gyb | 2 +- Sources/CryptoExtras/CMakeLists.txt | 1 + Sources/CryptoExtras/Docs.docc/index.md | 1 + .../CryptoExtras/MLDSA/MLDSA+externalMu.swift | 52 +++ .../MLDSA/MLDSA+externalMu.swift.gyb | 2 +- Sources/CryptoExtras/MLDSA/MLDSA44.swift | 171 ++++++++ Tests/CryptoExtrasTests/MLDSATests.swift | 45 ++ 8 files changed, 676 insertions(+), 2 deletions(-) create mode 100644 Sources/CryptoExtras/MLDSA/MLDSA44.swift diff --git a/Sources/CryptoBoringWrapper/MLDSA/BoringSSLMLDSA.swift b/Sources/CryptoBoringWrapper/MLDSA/BoringSSLMLDSA.swift index a342a06aa..7791bc977 100644 --- a/Sources/CryptoBoringWrapper/MLDSA/BoringSSLMLDSA.swift +++ b/Sources/CryptoBoringWrapper/MLDSA/BoringSSLMLDSA.swift @@ -832,6 +832,410 @@ extension BoringSSLMLDSA87 { private static let signatureByteCount = Int(MLDSA87_SIGNATURE_BYTES) } +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +package enum BoringSSLMLDSA44: Sendable {} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension BoringSSLMLDSA44 { + /// A ML-DSA-44 private key. + package struct InternalPrivateKey: @unchecked Sendable { + private var backing: Backing + + /// Initialize a ML-DSA-44 private key from a random seed. + package init() throws { + self.backing = try Backing() + } + + /// Initialize a ML-DSA-44 private key from a seed. + /// + /// - Parameter seedRepresentation: The seed to use to generate the private key. + /// + /// - Throws: `CryptoBoringWrapperError.incorrectKeySize` if the seed is not 32 bytes long. + package init(seedRepresentation: some DataProtocol) throws { + self.backing = try Backing(seedRepresentation: seedRepresentation) + } + + /// The seed from which this private key was generated. + package var seedRepresentation: Data { + self.backing.seed + } + + /// The public key associated with this private key. + package var publicKey: InternalPublicKey { + self.backing.publicKey + } + + /// Generate a signature for the given data. + /// + /// - Parameter data: The message to sign. + /// + /// - Returns: The signature of the message. + package func signature(for data: D) throws -> Data { + let context: Data? = nil + return try self.backing.signature(for: data, context: context) + } + + /// Generate a signature for the given data. + /// + /// - Parameters: + /// - data: The message to sign. + /// - context: The context to use for the signature. + /// + /// - Returns: The signature of the message. + package func signature(for data: D, context: C) throws -> Data { + try self.backing.signature(for: data, context: context) + } + + /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). + /// + /// > Note: The message representative should be obtained via calls to ``BoringSSLMLDSA44/PublicKey/prehash(for:context:)``. + /// + /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). + /// + /// - Returns: The signature of the prehashed message representative. + package func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { + try self.backing.signature(forPrehashedMessageRepresentative: mu) + } + + /// The size of the private key in bytes. + static let byteCount = Backing.byteCount + + fileprivate final class Backing { + fileprivate var key: MLDSA44_private_key + var seed: Data + + /// Initialize a ML-DSA-44 private key from a random seed. + init() throws { + // We have to initialize all members before `self` is captured by the closure + self.key = .init() + self.seed = Data() + + self.seed = try withUnsafeTemporaryAllocation( + of: UInt8.self, + capacity: BoringSSLMLDSA.seedByteCount + ) { seedPtr in + try withUnsafeTemporaryAllocation( + of: UInt8.self, + capacity: BoringSSLMLDSA44.InternalPublicKey.Backing.byteCount + ) { publicKeyPtr in + guard + CCryptoBoringSSL_MLDSA44_generate_key( + publicKeyPtr.baseAddress, + seedPtr.baseAddress, + &self.key + ) == 1 + else { + throw CryptoBoringWrapperError.internalBoringSSLError() + } + + return Data(bytes: seedPtr.baseAddress!, count: BoringSSLMLDSA.seedByteCount) + } + } + } + + /// Initialize a ML-DSA-44 private key from a seed. + /// + /// - Parameter seedRepresentation: The seed to use to generate the private key. + /// + /// - Throws: `CryptoBoringWrapperError.incorrectKeySize` if the seed is not 32 bytes long. + init(seedRepresentation: some DataProtocol) throws { + guard seedRepresentation.count == BoringSSLMLDSA.seedByteCount else { + throw CryptoBoringWrapperError.incorrectKeySize + } + + self.key = .init() + self.seed = Data(seedRepresentation) + + guard + self.seed.withUnsafeBytes({ seedPtr in + CCryptoBoringSSL_MLDSA44_private_key_from_seed( + &self.key, + seedPtr.baseAddress, + BoringSSLMLDSA.seedByteCount + ) + }) == 1 + else { + throw CryptoBoringWrapperError.internalBoringSSLError() + } + } + + /// The public key associated with this private key. + var publicKey: InternalPublicKey { + InternalPublicKey(privateKeyBacking: self) + } + + /// Generate a signature for the given data. + /// + /// - Parameters: + /// - data: The message to sign. + /// - context: The context to use for the signature. + /// + /// - Returns: The signature of the message. + func signature(for data: D, context: C?) throws -> Data { + var signature = Data(repeating: 0, count: BoringSSLMLDSA44.signatureByteCount) + + let rc: CInt = signature.withUnsafeMutableBytes { signaturePtr in + let bytes: ContiguousBytes = data.regions.count == 1 ? data.regions.first! : Array(data) + return bytes.withUnsafeBytes { dataPtr in + context.withUnsafeBytes { contextPtr in + CCryptoBoringSSL_MLDSA44_sign( + signaturePtr.baseAddress, + &self.key, + dataPtr.baseAddress, + dataPtr.count, + contextPtr.baseAddress, + contextPtr.count + ) + } + } + } + + guard rc == 1 else { + throw CryptoBoringWrapperError.internalBoringSSLError() + } + + return signature + } + + /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). + /// + /// > Note: The message representative should be obtained via calls to ``BoringSSLMLDSA44/PublicKey/prehash(for:context:)``. + /// + /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). + /// + /// - Returns: The signature of the prehashed message representative. + func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { + guard mu.count == BoringSSLMLDSA.muByteCount else { + throw CryptoBoringWrapperError.incorrectParameterSize + } + + var signature = Data(repeating: 0, count: BoringSSLMLDSA44.signatureByteCount) + + let rc: CInt = signature.withUnsafeMutableBytes { signaturePtr in + let muBytes: ContiguousBytes = mu.regions.count == 1 ? mu.regions.first! : Array(mu) + return muBytes.withUnsafeBytes { muPtr in + CCryptoBoringSSL_MLDSA44_sign_message_representative( + signaturePtr.baseAddress, + &self.key, + muPtr.baseAddress + ) + } + } + + guard rc == 1 else { + throw CryptoBoringWrapperError.internalBoringSSLError() + } + + return signature + } + + /// The size of the private key in bytes. + static let byteCount = Int(MLDSA44_PRIVATE_KEY_BYTES) + } + } +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension BoringSSLMLDSA44 { + /// A ML-DSA-44 public key. + package struct InternalPublicKey: @unchecked Sendable { + private var backing: Backing + + fileprivate init(privateKeyBacking: InternalPrivateKey.Backing) { + self.backing = Backing(privateKeyBacking: privateKeyBacking) + } + + /// Initialize a ML-DSA-44 public key from a raw representation. + /// + /// - Parameter rawRepresentation: The public key bytes. + /// + /// - Throws: `CryptoBoringWrapperError.incorrectKeySize` if the raw representation is not the correct size. + package init(rawRepresentation: some DataProtocol) throws { + self.backing = try Backing(rawRepresentation: rawRepresentation) + } + + /// The raw binary representation of the public key. + package var rawRepresentation: Data { + self.backing.rawRepresentation + } + + /// Verify a signature for the given data. + /// + /// - Parameters: + /// - signature: The signature to verify. + /// - data: The message to verify the signature against. + /// + /// - Returns: `true` if the signature is valid, `false` otherwise. + package func isValidSignature(_ signature: S, for data: D) -> Bool { + let context: Data? = nil + return self.backing.isValidSignature(signature, for: data, context: context) + } + + /// Verify a signature for the given data. + /// + /// - Parameters: + /// - signature: The signature to verify. + /// - data: The message to verify the signature against. + /// - context: The context to use for the signature verification. + /// + /// - Returns: `true` if the signature is valid, `false` otherwise. + package func isValidSignature( + _ signature: S, + for data: D, + context: C + ) -> Bool { + self.backing.isValidSignature(signature, for: data, context: context) + } + + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameter data: The message to prehash. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + package func prehash(for data: D) throws -> Data { + let context: Data? = nil + return try self.backing.prehash(for: data, context: context) + } + + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameters: + /// - data: The message to prehash. + /// - context: The context of the message. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + package func prehash(for data: D, context: C) throws -> Data { + try self.backing.prehash(for: data, context: context) + } + + /// The size of the public key in bytes. + static let byteCount = Backing.byteCount + + fileprivate final class Backing { + private var key: MLDSA44_public_key + + init(privateKeyBacking: InternalPrivateKey.Backing) { + self.key = .init() + CCryptoBoringSSL_MLDSA44_public_from_private(&self.key, &privateKeyBacking.key) + } + + /// Initialize a ML-DSA-44 public key from a raw representation. + /// + /// - Parameter rawRepresentation: The public key bytes. + /// + /// - Throws: `CryptoBoringWrapperError.incorrectKeySize` if the raw representation is not the correct size. + init(rawRepresentation: some DataProtocol) throws { + guard rawRepresentation.count == BoringSSLMLDSA44.InternalPublicKey.Backing.byteCount else { + throw CryptoBoringWrapperError.incorrectKeySize + } + + self.key = .init() + + let bytes: ContiguousBytes = + rawRepresentation.regions.count == 1 + ? rawRepresentation.regions.first! + : Array(rawRepresentation) + try bytes.withUnsafeBytes { rawBuffer in + try rawBuffer.withMemoryRebound(to: UInt8.self) { buffer in + var cbs = CBS(data: buffer.baseAddress, len: buffer.count) + guard CCryptoBoringSSL_MLDSA44_parse_public_key(&self.key, &cbs) == 1 else { + throw CryptoBoringWrapperError.internalBoringSSLError() + } + } + } + } + + /// The raw binary representation of the public key. + var rawRepresentation: Data { + var cbb = CBB() + // The following BoringSSL functions can only fail on allocation failure, which we define as impossible. + CCryptoBoringSSL_CBB_init(&cbb, BoringSSLMLDSA44.InternalPublicKey.Backing.byteCount) + defer { CCryptoBoringSSL_CBB_cleanup(&cbb) } + CCryptoBoringSSL_MLDSA44_marshal_public_key(&cbb, &self.key) + return Data(bytes: CCryptoBoringSSL_CBB_data(&cbb), count: CCryptoBoringSSL_CBB_len(&cbb)) + } + + /// Verify a signature for the given data. + /// + /// - Parameters: + /// - signature: The signature to verify. + /// - data: The message to verify the signature against. + /// - context: The context to use for the signature verification. + /// + /// - Returns: `true` if the signature is valid, `false` otherwise. + func isValidSignature( + _ signature: S, + for data: D, + context: C? + ) -> Bool { + let signatureBytes: ContiguousBytes = + signature.regions.count == 1 ? signature.regions.first! : Array(signature) + return signatureBytes.withUnsafeBytes { signaturePtr in + let dataBytes: ContiguousBytes = data.regions.count == 1 ? data.regions.first! : Array(data) + let rc: CInt = dataBytes.withUnsafeBytes { dataPtr in + context.withUnsafeBytes { contextPtr in + CCryptoBoringSSL_MLDSA44_verify( + &self.key, + signaturePtr.baseAddress, + signaturePtr.count, + dataPtr.baseAddress, + dataPtr.count, + contextPtr.baseAddress, + contextPtr.count + ) + } + } + return rc == 1 + } + } + + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameters: + /// - data: The message to prehash. + /// - context: The context of the message. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + func prehash(for data: D, context: C?) throws -> Data { + var mu = Data(repeating: 0, count: BoringSSLMLDSA.muByteCount) + + let dataBytes: ContiguousBytes = data.regions.count == 1 ? data.regions.first! : Array(data) + let rc: CInt = mu.withUnsafeMutableBytes { muPtr in + dataBytes.withUnsafeBytes { dataPtr in + context.withUnsafeBytes { contextPtr in + var prehash = MLDSA44_prehash() + let rc = CCryptoBoringSSL_MLDSA44_prehash_init( + &prehash, + &key, + contextPtr.baseAddress, + contextPtr.count + ) + CCryptoBoringSSL_MLDSA44_prehash_update(&prehash, dataPtr.baseAddress, dataPtr.count) + CCryptoBoringSSL_MLDSA44_prehash_finalize(muPtr.baseAddress, &prehash) + return rc + } + } + } + + guard rc == 1 else { + throw CryptoBoringWrapperError.internalBoringSSLError() + } + + return mu + } + + /// The size of the public key in bytes. + static let byteCount = Int(MLDSA44_PUBLIC_KEY_BYTES) + } + } +} + +@available(macOS 10.15, iOS 13, watchOS 6, tvOS 13, macCatalyst 13, visionOS 1.0, *) +extension BoringSSLMLDSA44 { + /// The size of the signature in bytes. + private static let signatureByteCount = Int(MLDSA44_SIGNATURE_BYTES) +} + package enum BoringSSLMLDSA { /// The size of the seed in bytes. package static let seedByteCount = 32 diff --git a/Sources/CryptoBoringWrapper/MLDSA/BoringSSLMLDSA.swift.gyb b/Sources/CryptoBoringWrapper/MLDSA/BoringSSLMLDSA.swift.gyb index ce60b7da5..a9a527a28 100644 --- a/Sources/CryptoBoringWrapper/MLDSA/BoringSSLMLDSA.swift.gyb +++ b/Sources/CryptoBoringWrapper/MLDSA/BoringSSLMLDSA.swift.gyb @@ -24,7 +24,7 @@ import Foundation // any edits of this file WILL be overwritten and thus discarded // see section `gyb` in `README` for details. %{ - parameter_sets = ["65", "87"] + parameter_sets = ["65", "87", "44"] }% % for parameter_set in parameter_sets: diff --git a/Sources/CryptoExtras/CMakeLists.txt b/Sources/CryptoExtras/CMakeLists.txt index b060c4313..6e6b7afb9 100644 --- a/Sources/CryptoExtras/CMakeLists.txt +++ b/Sources/CryptoExtras/CMakeLists.txt @@ -47,6 +47,7 @@ add_library(CryptoExtras "Key Derivation/Scrypt/BoringSSL/Scrypt_boring.swift" "Key Derivation/Scrypt/Scrypt.swift" "MLDSA/MLDSA+externalMu.swift" + "MLDSA/MLDSA44.swift" "OPRFs/OPRF.swift" "OPRFs/OPRFClient.swift" "OPRFs/OPRFServer.swift" diff --git a/Sources/CryptoExtras/Docs.docc/index.md b/Sources/CryptoExtras/Docs.docc/index.md index 9bda3af77..aa5059661 100644 --- a/Sources/CryptoExtras/Docs.docc/index.md +++ b/Sources/CryptoExtras/Docs.docc/index.md @@ -15,6 +15,7 @@ Provides additional cryptographic APIs that are not available in CryptoKit (and ### Public key cryptography - ``_RSA`` +- ``MLDSA44`` ### Key derivation functions diff --git a/Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift b/Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift index ba0d555ba..a9f593c82 100644 --- a/Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift +++ b/Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift @@ -128,3 +128,55 @@ extension MLDSA87.PublicKey { #endif } } + +@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, macCatalyst 26.0, visionOS 26.0, *) +extension MLDSA44.PrivateKey { + /// Generate a signature for the prehashed message representative (a.k.a. "external mu"). + /// + /// > Note: The message representative should be obtained via calls to ``MLDSA44/PublicKey/prehash(for:context:)``. + /// + /// - Parameter mu: The prehashed message representative (a.k.a. "external mu"). + /// + /// - Returns: The signature of the prehashed message representative. + public func signature(forPrehashedMessageRepresentative mu: some DataProtocol) throws -> Data { + #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API + try BoringSSLMLDSA44.InternalPrivateKey(seedRepresentation: self.seedRepresentation) + .signature(forPrehashedMessageRepresentative: mu) + #else + try self.signature_boring(forPrehashedMessageRepresentative: mu) + #endif + } +} + +@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, macCatalyst 26.0, visionOS 26.0, *) +extension MLDSA44.PublicKey { + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameter data: The message to prehash. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + public func prehash(for data: D) throws -> Data { + #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API + try BoringSSLMLDSA44.InternalPublicKey(rawRepresentation: self.rawRepresentation) + .prehash(for: data) + #else + try self.prehash_boring(for: data) + #endif + } + + /// Generate a prehashed message representative (a.k.a. "external mu") for the given message. + /// + /// - Parameters: + /// - data: The message to prehash. + /// - context: The context of the message. + /// + /// - Returns: The prehashed message representative (a.k.a. "external mu"). + public func prehash(for data: D, context: C) throws -> Data { + #if CRYPTO_IN_SWIFTPM && !CRYPTO_IN_SWIFTPM_FORCE_BUILD_API + try BoringSSLMLDSA44.InternalPublicKey(rawRepresentation: self.rawRepresentation) + .prehash(for: data, context: context) + #else + try self.prehash_boring(for: data, context: context) + #endif + } +} diff --git a/Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb b/Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb index daa9a4d6a..83a500245 100644 --- a/Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb +++ b/Sources/CryptoExtras/MLDSA/MLDSA+externalMu.swift.gyb @@ -25,7 +25,7 @@ import FoundationEssentials import Foundation #endif %{ - parameter_sets = ["65", "87"] + parameter_sets = ["65", "87", "44"] }% % for parameter_set in parameter_sets: diff --git a/Sources/CryptoExtras/MLDSA/MLDSA44.swift b/Sources/CryptoExtras/MLDSA/MLDSA44.swift new file mode 100644 index 000000000..a8a92b2f5 --- /dev/null +++ b/Sources/CryptoExtras/MLDSA/MLDSA44.swift @@ -0,0 +1,171 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftCrypto open source project +// +// Copyright (c) 2025 Apple Inc. and the SwiftCrypto project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftCrypto project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +import Crypto +import CryptoBoringWrapper + +#if canImport(FoundationEssentials) +import FoundationEssentials +#else +import Foundation +#endif + +/// The MLDSA44 Digital Signature Algorithm +@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, macCatalyst 26.0, visionOS 26.0, *) +public enum MLDSA44: Sendable {} + +@available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, macCatalyst 26.0, visionOS 26.0, *) +extension MLDSA44 { + /// The public key for MLDSA44. + @available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, macCatalyst 26.0, visionOS 26.0, *) + public struct PublicKey: Sendable { + private let impl: BoringSSLMLDSA44.InternalPublicKey + + fileprivate init(_ impl: BoringSSLMLDSA44.InternalPublicKey) { + self.impl = impl + } + + /// Parses a public key from a serialized representation. + /// + /// - Parameter rawRepresentation: The public key, in the FIPS 204 standard serialization format. + /// - Returns: The deserialized public key. + public init(rawRepresentation: D) throws { + self.impl = try BoringSSLMLDSA44.InternalPublicKey(rawRepresentation: rawRepresentation) + } + + /// A serialized representation of the public key. + /// + /// This property provides a representation of the public key in the FIPS 204 standard serialization format. + public var rawRepresentation: Data { + get { + return self.impl.rawRepresentation + } + } + + /// Verifies a MLDSA44 signature. + /// - Parameters: + /// - signature: The MLDSA44 signature to verify. + /// - data: The signed data. + /// - Returns: `true` if the signature is valid, `false` otherwise. + public func isValidSignature(_ signature: S, for data: D) -> Bool { + return self.impl.isValidSignature(signature, for: data) + } + + /// Verifies a MLDSA44 signature, in a specific context. + /// - Parameters: + /// - signature: The MLDSA44 signature to verify. + /// - data: The signed data. + /// - context: Context for the signature. + /// - Returns: `true` if the signature is valid in the specified context, `false` otherwise. + public func isValidSignature(_ signature: S, for data: D, context: C) -> Bool { + return self.impl.isValidSignature(signature, for: data, context: context) + } + } + + /// The private key for MLDSA44. + @available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, macCatalyst 26.0, visionOS 26.0, *) + public struct PrivateKey: Sendable { + private let impl: BoringSSLMLDSA44.InternalPrivateKey + private let publicKeyHash: SHA3_256Digest + + /// Initializes a new random private key. + public init() throws { + self.impl = try BoringSSLMLDSA44.InternalPrivateKey() + self.publicKeyHash = SHA3_256.hash(data: self.impl.publicKey.rawRepresentation) + } + + /// Initializes a private key from the seed representation. + /// + /// - Parameter seedRepresentation: The seed representation of the private key. This parameter needs to be 32 bytes long. + /// - Parameter publicKey: The public key associated with the secret key. + /// + /// This initializer implements the `ML-DSA.KeyGen_internal` algorithm (Algorithm 16) of FIPS 204. + /// + /// If a public key is provided, a consistency check is performed between it and the derived public key. + public init(seedRepresentation: D, publicKey: MLDSA44.PublicKey?) throws { + self.impl = try BoringSSLMLDSA44.InternalPrivateKey(seedRepresentation: seedRepresentation) + if let publicKey { + guard self.impl.publicKey.rawRepresentation == publicKey.rawRepresentation else { + throw CryptoError.authenticationFailure + } + } + self.publicKeyHash = SHA3_256.hash(data: self.impl.publicKey.rawRepresentation) + } + + /// The seed representation of the private key. + /// + /// The seed representation is 32 bytes long, and is the parameter + /// for the `ML-DSA.KeyGen_internal` algorithm (Algorithm 16) of FIPS 204. + public var seedRepresentation: Data { + self.impl.seedRepresentation + } + + /// Generates a MLDSA65 signature. + /// - Parameters: + /// - data: The data to sign. + /// - Returns: The MLDSA65 signature. + /// This method throws if CryptoKit encounters an error producing the signature. + public func signature(for data: D) throws -> Data { + try impl.signature(for: data) + } + + /// Generates a MLDSA65 signature, with context. + /// - Parameters: + /// - data: The data to sign. + /// - context: Context for the signature. + /// - Returns: The MLDSA65 signature. + /// This method throws if CryptoKit encounters an error producing the signature. + public func signature(for data: D, context: C) throws -> Data { + try impl.signature(for: data, context: context) + } + + /// The associated public key. + public var publicKey: PublicKey { + PublicKey(self.impl.publicKey) + } + + /// Initializes a private key from an integrity-checked data representation. + /// + /// - Parameter integrityCheckedRepresentation: The integrity-checked data representation of the private key. + /// The parameter needs to be 64 bytes long, and contain the seed and a hash of the public key. + public init(integrityCheckedRepresentation: D) throws { + let seedSize = BoringSSLMLDSA.seedByteCount + guard integrityCheckedRepresentation.count == seedSize + 32 else { + throw CryptoError.incorrectParameterSize + } + + let seed = Data(integrityCheckedRepresentation).subdata(in: 0.. Date: Thu, 23 Oct 2025 12:10:56 +0200 Subject: [PATCH 47/47] Add KeyGen KATs --- Tests/CryptoExtrasTests/MLDSATests.swift | 93 ++++++++----- .../mldsa_nist_keygen_44_tests.json | 129 ++++++++++++++++++ 2 files changed, 186 insertions(+), 36 deletions(-) create mode 100644 Tests/CryptoExtrasVectors/mldsa_nist_keygen_44_tests.json diff --git a/Tests/CryptoExtrasTests/MLDSATests.swift b/Tests/CryptoExtrasTests/MLDSATests.swift index d195b2634..c837bb28d 100644 --- a/Tests/CryptoExtrasTests/MLDSATests.swift +++ b/Tests/CryptoExtrasTests/MLDSATests.swift @@ -210,39 +210,6 @@ final class MLDSATests: XCTestCase { } } - private struct NISTKeyGenTestVector: Decodable { - let seed: String - let pub: String - let priv: String - } - - private struct NISTTestFile: Decodable { - let testVectors: [Vector] - } - - @available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) - private func nistTest( - jsonName: String, - file: StaticString = #filePath, - line: UInt = #line, - testFunction: (Vector) throws -> Void - ) throws { - var fileURL = URL(fileURLWithPath: "\(#filePath)") - for _ in 0..<2 { - fileURL.deleteLastPathComponent() - } - fileURL = fileURL.appendingPathComponent("CryptoExtrasVectors", isDirectory: true) - fileURL = fileURL.appendingPathComponent("\(jsonName).json", isDirectory: false) - - let data = try Data(contentsOf: fileURL) - - let testFile = try JSONDecoder().decode(NISTTestFile.self, from: data) - - for vector in testFile.testVectors { - try testFunction(vector) - } - } - func testMLDSA65WycheproofVerifyFile() throws { guard #available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) else { throw XCTSkip("MLDSA is only available on iOS 19.0+, macOS 16.0+, watchOS 12.0+, tvOS 19.0+, visionOS 3.0+") @@ -405,11 +372,22 @@ final class MLDSA44Tests: XCTestCase { let publicKey = privateKey.publicKey // Test Public Key Serialization - try XCTAssert(publicKey.rawRepresentation == MLDSA44.PublicKey(rawRepresentation: publicKey.rawRepresentation).rawRepresentation) + try XCTAssert( + publicKey.rawRepresentation + == MLDSA44.PublicKey(rawRepresentation: publicKey.rawRepresentation).rawRepresentation + ) // Test Private Key serialization - try XCTAssert(privateKey.seedRepresentation == MLDSA44.PrivateKey(seedRepresentation: privateKey.seedRepresentation, publicKey: publicKey).seedRepresentation) - try XCTAssert(privateKey.integrityCheckedRepresentation == MLDSA44.PrivateKey(integrityCheckedRepresentation: privateKey.integrityCheckedRepresentation).integrityCheckedRepresentation) + try XCTAssert( + privateKey.seedRepresentation + == MLDSA44.PrivateKey(seedRepresentation: privateKey.seedRepresentation, publicKey: publicKey) + .seedRepresentation + ) + try XCTAssert( + privateKey.integrityCheckedRepresentation + == MLDSA44.PrivateKey(integrityCheckedRepresentation: privateKey.integrityCheckedRepresentation) + .integrityCheckedRepresentation + ) // Test signing without a context let message = Data("ML-DSA test message".utf8) @@ -428,4 +406,47 @@ final class MLDSA44Tests: XCTestCase { XCTAssertFalse(publicKey.isValidSignature(signature, for: message, context: context)) XCTAssertFalse(publicKey.isValidSignature(signatureWithContext, for: message)) } + + func testMLDSA44NISTKeyGenFile() throws { + try nistTest(jsonName: "mldsa_nist_keygen_44_tests") { (testVector: NISTKeyGenTestVector) in + let seed = try Data(hexString: testVector.seed) + let publicKey = try MLDSA44.PublicKey(rawRepresentation: Data(hexString: testVector.pub)) + + let expectedkey = try MLDSA44.PrivateKey(seedRepresentation: seed, publicKey: nil).publicKey + XCTAssertEqual(publicKey.rawRepresentation, expectedkey.rawRepresentation) + } + } +} + +private struct NISTKeyGenTestVector: Decodable { + let seed: String + let pub: String + let priv: String +} + +private struct NISTTestFile: Decodable { + let testVectors: [Vector] +} + +@available(iOS 19.0, macOS 16.0, watchOS 12.0, tvOS 19.0, visionOS 3.0, *) +private func nistTest( + jsonName: String, + file: StaticString = #filePath, + line: UInt = #line, + testFunction: (Vector) throws -> Void +) throws { + var fileURL = URL(fileURLWithPath: "\(#filePath)") + for _ in 0..<2 { + fileURL.deleteLastPathComponent() + } + fileURL = fileURL.appendingPathComponent("CryptoExtrasVectors", isDirectory: true) + fileURL = fileURL.appendingPathComponent("\(jsonName).json", isDirectory: false) + + let data = try Data(contentsOf: fileURL) + + let testFile = try JSONDecoder().decode(NISTTestFile.self, from: data) + + for vector in testFile.testVectors { + try testFunction(vector) + } } diff --git a/Tests/CryptoExtrasVectors/mldsa_nist_keygen_44_tests.json b/Tests/CryptoExtrasVectors/mldsa_nist_keygen_44_tests.json new file mode 100644 index 000000000..2446e1969 --- /dev/null +++ b/Tests/CryptoExtrasVectors/mldsa_nist_keygen_44_tests.json @@ -0,0 +1,129 @@ +{ + "testVectors": [ + { + "seed": "d71361c000f9a7bc99dfb425bcb6bb27c32c36ab444ff3708b2d93b4e66d5b5b", + "pub": "b845fa2881407a59183071629b08223128116014fb58ff6bb4c8c9fe19cf5b0bd77b16648a344ffe486bc3e3cb5fab9abc4cc2f1c34901692bec5d290d815a6cdf7e9710a3388247a7e0371615507a572c9835e6737bf30b92a796fff3a10a730c7b550924eb1fb6d56195f02de6d3746f9f330bebe990c90c4d676ad415f4268d2d6b548a8bcdf27fdd467e6749c0f87b71e85c2797694772bba88d4f1ac06c7c0e91786472cd76353708d6bbc5c28e9db891c3940e879052d30c8fd10965cbb8ee1bd79b060d37fb839098552aabdd3a57ab1c6a82b0911d1cf148654aa5613b07014b21e4a1182b4a5501671d112f5975fb0c8a2ac45d575dc42f48977ff37fff421db27c45e79f8a9472007023df0b64205cd9f57c02ce9d1f61f2ae24f7139f5641984ee8df783b9ea43e997c6e19d09e062afca56e4f76aaab8f66600fc78f6ab4f6785690d185816ee35a939458b60324eefc60e64b11fa0d20317acb6cb29aa03c775f151672952689fa4f8f838329cb9e6dc9945b6c7ade4e7b663578f87d3935f2a1522097ad5042a0d990a628510b6103cb242cd8a3afc1a5ada52331f4df461bc1da51d1d224094e7abed3d87d98f0d817084780ee80370f397631ecb75d4264b6b5e2e66c0586b5fb743516399165837a0fdff7c6134f033bfa69c1b2416965c6e578592f40e258cb6dfb29fb8e0f54355b6e24a65f67abae3193d007115cc0b9ff94cb911a93b1a76c0e7662f5e2b20139e0159ed929cb932d4895f89a02e55c59df2dbb8f6e5dd7d5b1f3cec37b4a9166b381c5440e23e67368cde0a29d59aa05a3c9be24a4dc8dd75be30e82bc635d36aac66de880c6701a987d7e05f0f2ff287828bec30595089d8ab9aa390ed719caa6e576cdbbe9b184a322e5e2dabb69c23cc696d54fc32ff57001b6b64e2a837f3062d85aeb50b3510f7edfc34df38e083d4d9b94ffab0de15d73d9af30b9f31cc4f41c9c24f2d618b2a7c3c4bdfb745d52d3eb54589c8bda8ac05dad14ec744505575a0988eec651c1715439fdfb29923380a43c1a66a86c982a841f11820a6a0e1e2f2fff5108ecae51a6aabc9b949226d228ff84c4e5e5d63114d80359c4931e612dced1838b7d066ac9182cecfa223a21a4c8e155aefa780373bcc15098aee40c033af22f8e7c67a0d2526da7475e830308c04aed9d32bccc72e719ee70a8d13f09ac11e26ea237d5cc8f98b5ae0e54f933bd0507942ed900d056fd32f8e6e81777912fd482746029b71cce3ba69b8fc2d03eb441027c387bc2f95031a0ae7052215eb24b9ea8fb0a961b0f80bfa80d0d6257c1c22b508c5d31b97fcdfe1d1766e8a9c8771932dd598adb7e717743f45fc571f21e4a516249f81d747f15329790f0f70a0b8e461a4edf50504af03f30ddf8a8818e38761e1681d6ddef0b1dd326b2ec228ce48570f285b49d29d7c2ef37866d5446df82b8e43b34cb248962a21a9a3946159740f8aee8e6a16a4eb2b42d143fe2612e05ef4b5e646d813248444556a2a8bf92ce10badecb6b8a40b080dd42d53346fefcc4b9b40b1e4998991ec753c95aa2f2a506f311e710b0f1d36c1dca6644ee6d1d4ae9cea5666ef4b3e888dbdbb95a77ecfe1e8b477de7cb07639d682d53020ec14ea6c7dd7e715389d10938429fab8a068a1466a4cd891359f8074e0f5a142add731b87878d985e4fa6ecb3b73d298553418273e9503aa84092c080e5f2902f90f5c59944d24ca0271d11d0d6734606d039550a37fca2b735850e63f540f2f06b79144b5c4ed2c700bb51c33d265b3d037389c99efd597642d829db1eb58643cfcd07f4dec60b8f727d97bd7c4b59bda1", + "priv": "b845fa2881407a59183071629b08223128116014fb58ff6bb4c8c9fe19cf5b0b28965f58d99ee0de7bfb7840f59f65414289e259e05e8a18d47ec06d7900284ad7a0ae404b93b0498945abd07638920fc7f8c21282031eeceb0cc48d71fb0ad1ce84b9b3ddd1b3a2a40a15d5bfe0be23fc4757137c6c8feb7f8055677ba4af2814242a9aa0108a4046981800042130a2340a99140e01a931e1300a1a136959486601c111140451244206e4c848a1b80008b2490121901224500b03306112025c144912b30049424d14470e93342023898803238ca1c081cc0411184545c1c20862465210300d52b870a3b004dca20d4a386511214a01b48c43104809461253068161348618a00920878ca0168682208e41188e52a29021014652184521a42902132ed0b8248816710ab245818480942670dc126c1bc16c4016246236008996108b124e1b3721639225e1c88ca346285a32111c856110b9295990910493651cc40063b810c1184a52900c1cb20d2380090a4021d4188043a64d0835060c98650cb4890c8661d804601c0789d09231d8081100881119294e48b661d8962dd2b04121a1051226860349301a246d99483001200c5cc2840128900a298850340e1804640ab409d1968413196dd91031133689808025e300294a06304448109b429008858902a20d13461110120edc380c4c468842c004131490c1462248b82d48c80d64346c02348109136842a4211b26511c302a6328688b18609c922c22c9000031058ac08c894430d0142189424c4c106400b64dd2a8246306308bb4289b246ec34262a0c00c0c2050e112444a360ad122320c36014836804c00400c16090c9569a19829110602cc982d08c811498445d20290014942c1062e42c000a2902d9810711a054008058608b2651b36441109402107100b3306d298858148088034305c3844dc266eca947004394a442841e1464898862d113621221509530826213088da94804a80601425321295641b02120a92241a4422230624cc12818922600036608a32820cc368a1a04d5b286a110744589851c42831a4064ec0c831cab46810b669132488840462a3c421e0920523303050b6105942285c3005102286cc260e2226450003928a242c9c024e40b20400148c4a086e4ba6444cc84924464d4946821aa4690a316e21408c22964949044618b72c12b864d1c851c3366e5c2008e3328513198564c2019a4822111300a4b64960c06d1944628c086119b761021570ea732640984f68143d81ab95763698dcd02625a980994c19b7d47626409370f87e45d39b76b6762f7827b2779ba44046f54228a7b1bac9d8e751ac2dd248521564f81d028ad671db6a3a5ba3a9463597a519ae0c1da435fef7c421cde7f8483782c4334993192923796ddc3e5803f6c86cf2b37e39bbcb53775e5e9d2bdc65e84395b01af95c4398503a7e63a8d72f7e9bc58d7655cb86bafa0b679d1d791f09703f6e4b333a51dfb14b36eac9a3582f795afcecc2a67a42c7bc43b447b73ec8b73c9164b2d9ef4f767d607e975738e1d871fe61b7bb9570516959b9e7d8155455fc91590d84bd430921568b718241ccd09c989ddf75f529c4f15818969216ec0fbabec64f184832bfe428be44849c42f13ca84a5ce6ca628044cb9da3fd9cb5ebc776ba0e12683b98253b213b286593779eacc489c985beb734a7506791be1a6e6e03b557cfef2069091b846cdbbb72d36a89fd5c45c7c7fbfaed956ec9d8f3025225d6fef811b1cc3c6705f056388bbfbba1febf4d072281dc792ada048216d60d0d6044150909b70a4753336f4d5d3fdb8baca62946db28332ec778a76f96577baf868bf896773c200637495098b0f7749835915348d37641ec74d5a78e565d8100627468b0b5d05c2937618a98e5a12476533ce9d699e0f4f23b3127ee1f8d3cde3851a94beb8d606d836d47a9f090581b660ff8ec31e3ef4e45db530dd88a44d48f84b6bd3ced53be935efbce9930dd83bd004f086a064b3260b7211ba0547cb29e56603b922597b31a30a5ffcbd8a7ad2f3f05372dcea89048c683164410e56a6e5b7ec2ea6e3b0176db1ebf9258c97c297e752a202b1b4b02da47235873cc3e4a376b655779afffc9aef2e30b62be022aeff5e34b468507c921a00f1110b2cc1bc99b2ee295a31eac141ab4d87edc11d7fee22a07d69b7008c107ebe47dd2f215d074868c8b929a3df6614b5e95cc8a52f96c57e1697cee332f45b1980e6ca372574bdb51825654e6ff31d8e755cfc15b602f46a0570d3bd0d65e43bde8f792e7d526b3d362fe33638b3870e1c29e1030d3dba43c3d0db6e5f501ea3441b709e54fca1fd3e8654b1a9301ad151a36c8fa1513d0229de6e94d02a97b9d6f2ee8078a5d1228e783b8fdac46102a19600c531276b447f3900ef8f723fc3b60d7bbbbda9f949e4460b2f1103315ace25b3497ca4b4674a6052304609a16e90d064b0f6a9eae8d8e4be38e3b781f9173654e876ce6cc00578171fd9cfdba5704af2e60cf84fd02ebef19aed140287d195023000568e8d908edeadc76bca3e7fe8fe1f4b201c2a15603c025a61917ae664b4294c57030ac988d7967364a8bb5857e98218c2943e8cf1cb8c719daccfae8f42aa7dde9b4130170068a9cc86b0552d1dd0a48f63ddb8f8a51b3c0e10f3174a87d18f96533cf0c30c0be33d37c25cd3ebf8f5f10e66464ac2fb8260ba8b5bd443abc6ae0d5f89daa42bc71b2a9bc2d10140b117e32f41353fa1ecec9dbccb621350806c4e4ebfc966aa7122d85532728ef26aa40e55e2e1739790ffa157efa4e2a68da1ea4c9e3273cde11db7da47220123c40d50b73b8460cd93cb449783ead8a58f6ff272275a4f6c0437daf3df1d8d9617743d9302e73b715aa7caa139cdd07edad2de7b32b3f11e3c2b6a96d4630632c6d1de21473a287d42b52d210cd4ef808a998148817bb5083bdab3a3354b084c5773970b15da56f755e1f25354efeff89fdf4e307998d623ced32c7b9e942b6816a87a233867e2beb84582fff61af612be6e521ab3005e17d471a5c67a0a927211802ca4a0c2fedc01a12af5e8a6e8ff7bd08883af1d35c2f8570091d9e5fcd9d720644f0a45042443d2fac309fa7a15b2dbba1517ea19407b17caf7e9ea81fbce42f35a0568b2f70b279e12da48858f0e0ff0b5cb3a3012308ab83db627f5439e3a424d83f9e0b7750f2cbd9ca4afb9ba77765a1ea590ce9e37bc7eabe1ef099765ce59ea74c2776eccbceb895997f577733c609b9e853cf03010c5b9cc4e819c041abf11a9b3866502bf6ac0354e6ce1060d5155e6e5a1ac4fadf73080b20569317f9e118b97c78d7273300e329373e5b64a4181c4ac7b8933f82ade505d52cddceba373a54d072bc04a8d83273586615addc4d6f258bfd75ae94efd120f20b721a1cac33ff3446e554d6cfe266b05e4cd44de77d263a9d347f53b282a7bcb1511dd405a67ac05e7233f5ebb40d38f953ac903f90e96f17a6357eb59ed7900ffd82f54c3043d37f7774a0f4defaf65887eb53fe156fb26794982b1249bad27c89c136097aa2268347fc9c5e5be79e23c923215353a850e63748e766" + }, + { + "seed": "ab611f971c44d1b755d289e0fcfee70f0eb5d9fdfb1bc31ca894a75794235af8", + "pub": "d712599a161ecd99ef5b7a04313d5507d612565f03aa9695ed7c2df1cfa18056264432056c416013f5afe21adb7f4a5ceca1ee694e580301b47eb634e18c25bc0c964470bebf10afdf7587bae7fc40d45f94519a661a7cd04f7aa0d95aaee797027d8cbfaee682add859106cca978f5311a3b53a1699691c1e9e8bf9d2118b23bb1b33c5e9a02f968c800560a865fb826289fb34c936c825d1d0a7db566b9f30b8e42e7a9ae8f325e51c197cea36ddb79df537d1f4102dd44c01b59401770bccf4d5e8329121863929c91dfca9c00f862ed7dbf3cf7558f6150b2b05d32f04c1e6e775350248dbfc0aee58681b5b177ca7ba17ed6c7b4ba7302dc0f349564db0d83c7f7d1afe502e27dc465704aa9b7aa50d8f5a14ccc5701fae3505d3ae11ead8142af9ee7991b3b216686126627c60e1769ec805000a6d94076905630d385b7cda7195b54522a81e8855f3d6dac03e686cadf72a9142363770283915034ecdf9047f80a8f9594273c7637b514baf9ace79a7b5d28f8b0efd63a1f8b17301f499fd37e448f5e99f118fc7b2a4bfd7dada350456ce5cc72c5646c57229ecd91082a85efa259e2aaff761f0a101a2269c8b88d94f7a8e4f87e7b9f977396e71bcd2b2bf89ab8b829a345d37fe5240ce7216c64efb01ba8a13700d4bfc9856eace22fb763bec7d1e02f0f49b45f587ba6b3f571be7aebea88557492c6c766d7ae298c7902f346deda494eeac39c8767199252c9ce18825385596956f1f41b2bb534f761fa0c89917077b23f8056aa7405f8ae4271b11df284d4ff50afcdbfdcbe880131b60e3534091a759531fbe6e14d6057bdb458449ae4bcec26580877331359e794e9d75bf454122264ccd13f9349c8250f0bb586b5bb482eb74524fd12f0f61edd28411d072fcec556bbc5569afcef1a62c26078088a77ada5976e6a2a99e98c898e5789de786b45708271957d88594db7fbabe23ddbf1abb12e715bd576483ead259ba6553e95ae65aedb55751532b98f32376baddd2532e5801a255fa6dfc3fccd5fc5110ee231450dda25c4e09b89b577b8589c7179b06d62aba652bd6dad5159e8d7b84a5879f075ebd31ecce03d2f1e508fb229665b4232b905638176afcf232d4c19af38a812c8d2af2776cd444e94d46816ee68e7b5cd5ac1622518682eee88e0f64358181ef35a8ec71e00e70f1222f494615a4fdf7c769cadb0e13b2f15b5eda38809a5960d25090c1513636de242bbd9a79f77cb45c81557d6f1d18991b37becd4cad9707b1f88920b69a55cd52cdac2318287d4b13bc9cba6884f9a38054493bdf91b29c2b7a71e2dd8ecfcdd0259bfff402251ca2c95042af917ebb669ace5b354dc393a10f66847d546c47eda695ad3a985834292e68a024ab6045adf36dd2a58993a292b24837f61711cb59ea8deb103f63f971e385ce0490a0709c890caf57ed86991aca729dbefeb023d4356b7144485b7af45559c3ff722ec8fcd8befbaf41119a24c9b686a79c38356f3fc55720f03ac89b3187cecc0c1247b9f8ddd82b8b415baa6bc7a25e2529c41cc9765c768dc6a555d6114707879e810bc4c7472a07e8b90b0f41b8b4cabd5326b190572b664127e2fb476d88db32d42d50bcd7f637ab2b7d13e0a7d03dfa30b0b81f7d2917c1ca5260bf71230f7342a5bb9f9261d966cdee85f768a9b8b509f094c60e0c08bac278827e84e6590141ff8c10e9b51fbf6e7724030eeb8b59731e47fa3d130407f833455386b66cbc453ff4bacc0467d747a1037ea57b3de4421c3050dc6d33268cabe633c6e54c13d64973751798a99d8c53a2132e5bbbf8b2961b9e800f01940c700e47e4e1", + "priv": "d712599a161ecd99ef5b7a04313d5507d612565f03aa9695ed7c2df1cfa180565499f298e78451161f0e9ff4b862815f3d5d33393af3e677ee2460df7bf3ae6e9a80f12a9b349dfdb9b3d0513bffe620394a80a2883bcc69f1847057ac3bf35e63a72e60d5267d606c524ab847bcbc1113874755248dfbe583a2f0db0fcbc8cd9c9008128028ca962ca038680919464c008acc084d00466093002a541631d9a890d21200dca8515418655c2005c8306a0c01204b040e1c913001418c11448c1a3206cc060c50b27058244593a0119822012426260b402603090e5a12020301611a14010119625222200ca3650b09904ab44d80264d5a366263906d1207320339491036111223041888202421880ac82819806c492629c4922062188993367204220282086558945018b32823335263a20112498c91b428e4c645db82694b021101270a09397220314042a44dd23092913444c134091946200c210d4b36101026111437699440895308204324019b464152b8854286891b11880c41449c3252d2200520320c13948510930582c6480211865b262ccc884444b42dd2088e601062cca66d8344451b3765c8b05180066922040ca40489514424a3404162965019c78160320d9816921220101915016248051c362e59308a13126aa3444610a52900c98c93c4100ba04508170558486201086c183392dcb86dccb08d59906420026014b309104945a3a60012472e1c005203c91003492c1c92811b396613465001294650208462106900255043b8201cc68d981284a03204220821dbc46ca10622a09071e4204d213984d4b44023432401b6001a318289188209067112b131c3b624ca126c90066201036c0825909b3669e28044982428c4b0100b384159986d4b220118382618332e11150c49a8088c48898bc62862864c00461224a681c3c681e0c60d19046e9c9441c1283203466e1321251cb5854aa084a424319cb02048946014b7404814501319691ab00012b12413c880628410c31061d94040db4806898869119289149700c204241cb7058422284b3646130132cb406160140ce0005218010a50228118278013329004269110a32c99b42c5c44464b3632dc468a49b04858884961c44102a2650302624326410b9885a11426481092da962898c8006028104386688342254412102343511c326a09884511c5654010065ba001cc32889922258a1666420611898241120165c3140621446c09450149424c99948c0045022c7b04ef5ad7d8fd0179fc8afda5dcada47cf7926345f6cd5f072625345a613c92d8d1ea7cfd213dfcd7896567194767da47e3b3bed4e3f2cf727c78f7fd63855cc68efea538728cb803830b6fc646a865b93a46cb4ee30968c8a61d913dacc0483cc19dd790acec8e07ba8f5e924d7f024b69552eceb588a94dc2bf11be97a59a8065043525c628b59ce423ccf8293c78363c98662ee883f8b46a243ab2ab8ed3eb24c4afdf383b2e9f0f969d4e6de19b06bf6837abdf751725b97d45389138edb253a78c78de841224fd7cffae2d8d58ff5d9b9ecd9c209f77cca5d167b1a93ec5a9b891e1e4dbf1741da1c4aae7622b15f040da03350cecf2649e309d38a8d5f8aa218900f321557c593dcb83a6a5a2c3c13129a07236e6f50864e4e9e11b840f3d6e6b74acfe7394dad62167e1cae165b9207596b1c7cd3de62558c24723c8f74bb4203f0f5272d0e1e8ec631bec8ed97e9dc58fc843a901329d566a3a230d138b3aac9b29ccdbefdd2a6aaa7ac2c57a4850ab0ae2425d5a1f572848755d8894222f37885c8d7d34c02fa95457c7ebcf1d56b3361daaf75f43399ca1958609bf9654a0e50c6ac0b405014ab252767a8c31f9d23bf9dae2fc6a2548215b9e77f2fd28d049232763109367b1ab9a25dbae50abda2422a8f262a5a19d4035fda91433072e5e1dc927425ea3d1de222230889373ef0d08e475662b6bebdf6c4e48ae442331d9c7fcbca2c41901543aefecb866d132090aa366a358939ef9afa92b533a60444c95bb50ec36dc0478f4511948e34a4a2ee53b439eeca84b53b3470e86413c04822cb6209ffb97c777da0be08f46f629dd64be853901bcf32d1bb5efc5512b0ac678154e98e862a9df088243a1e279c55253aa3666ab343909b2421917faf7fb4ab09a0268d3be0cc9dea933375975ec7e3ac22e50ceb3be9fb3549edf77d129fe75b1d24c2becdbcd734f6a03349a4ebe17323985a9ffe33c1f68e99f321b3eb918c0bde1a53a79906bd5704351693aaf92804310df2a4f05e1eaafc241c308ece274b9b09935d5889ea1f58f580d2cadd2f9f9712279f0fa1f8ae4aea4d993c55ce420ddfe5527fd0abcee4fc8f547f6c335bf6bd6827cca513567cf4744caac1c373b8f8e12e2234b0341f7f3974bd9a2079eb5c48f25cf6400a1299e42f2d77804433e182f8ee02a1966846152fdaa949b9979260d1b511faa2a705a2282e3955b6b906a2faa28fd054a9b78e424fa5895650e60a2b1beb1aa6480ebcc0a01657a8344ab896dfa7c023deda05ef642134a3ab9a783da9ae6d189d2e2c2574ed909d757230885c0155644f25166a0474f618fbb5066446c7091d6e6e7efaa6890d3704f8ff5170f2e2f656fc7825c2f1175a8de14ec4cdc9f7d4d0996199d63c44e53d8adb961335c954462b19b9bf52a67e3de2be220156e4dc9445904fa9cf42c2de922231ff1be379830abf6f00b46a79f470e2a4471730cb8c29a000ebebe10a2789a714f07f432962827af53b321b8f7de08a95d47ffc223df9a44ee0fed3d5bcccd948420e4e8d452af900d49c022a3fb6c0d6887c836393597e40d36613e77ccd8a306a21cf826d20d9f823513815d885eb74f04adeda4051bd0998f7c9a48015bf662d72f6a99aed192c283d936e65f48e9748ecf2e0325518ef4f4b6991bc3956f3954535218b3727a721e31dae286ab9947f13cd59e8f0fe7214dfb1540731049216d8069df7a2be167623684d142f721444204ddbaa851629a43dd9f75554ecac9bc397c497b9097f85403db3f6dd8ae83e4b0de698f5e0aef23fbcc21167e10ef554791f87dc9bd58f8ee82af76b0846510873159a534e129daf7b567bc17d5ee78c9630ea506dbedba84e2d1fc5df9154903038a0fe8ef6c3af6028d71cb2cf593596316a989a28db6cf1814999de9f597abd1abc20a168e2f2fc12f5c3d04d3581e0df9cc2f890c207f97861790e0d1cdc67590deec5c6e9ba3ec2fb2aa3f0f047fe210cbe8eb03cc5f976a74df9ec1086cd4d1a9b8e47888bd77095c305852e02c85f5b9bcdd6ff1c2b79e299ee6352a83ff2a32d5f71e8dcfd05167a9f6de8bce131602a83b998a45fc64ad3163d8b4673defbe8ea91b0a4e181347d60bcb00db9dd6a7d1e2553cb7ddcb62586d5d914e5c4db82ceacb38834f9b2681d81a5d6dced5304496a84e5137982e6da1b215701d50a77e22356bac7734883e19bbd4a619a8730c24c6c45b575b49747cdace2f081545115c2a4b2ad772bdf51ae4a6f2e7152dd076fb2d8f4c068a08720f4f6230578475fc0a5f0b86fa56d01c7e5d1c310a61d947df93ec69fd96a5996a3b65f7" + }, + { + "seed": "e0264f45d58ea02c8738c006caed00f3ed9296e2f6bbf4d158fe71c2983fdf38", + "pub": "8a0ddd293eea646f5a09a0513991ceaf8f5d7d458cf40f7c1f18f6dba8f4c2f885cfea936e806adbe9ae7625c61929e78dc507a78f1fcad6e6a2b242a51f625fa590e86db8e41598bf24a73981203304422e48650f22579a72190bb5ff198dc4c4863ba1c9736dbdc5154c0d0cbdfc9e2fe4a74249c4145d45f92c592543b28798f753ddc21f40720fedb33a5ef135ff8a63a4b5b82485ec02f8922671207581ee5c9337cbac296ffac53a4c4aca973f8128274be29e569ba66cb62fdf1c6f7d3de041520d13180a24ef11a8ce0ada2558dc5c7956f96886942476f8dc24531ac8576f8ee465915c4d2e3caa384043d84ee97e641cb9611b119a3bc19a4b6fb0fc65ab582b3e815e4891bba28b3c3a800e3aabeedde28db45e21e5ff0b39f3fbffac8d58fcebf984ec694d0e04ff8307d9cb20efa6991e9438a2bf11fc28e316cf5463fd72bba4b96704c55c9f9ebe2375f20cc01cb7469ca0f0fb7ebe1b7961d21098e83e6d7e01123dde46fa3dc6a5ae6b534eb902049ba2446fc7b9285ebcfe808cbce653efef932f172a2184354f48f92f0b51b52a7c9b8081ec3b22aab3de727ba9379c0ea44850566a113b47298ed70296b5ab94c7dca097603c907ee7ae9c0f024f978e837250a89cdb3adf0f27b005a0f4e2375f3a533908b2c7f95159ac9f1eb9672ea0e9f346921a16ce6585469eb325690cd1ccabdec1c1026a0c8d8090bb82c9cf5fdc7e1a772a9585ec8dcf8b9215ff2aa56e14a7be604ad84848f589316f57bf074b61749597dcf21a62ae6802eda4afb1ae2804b60d465266f1dbd879c2116b45971a01c340ffbe9db1ec8f9de9673202d585a1f636427fb1ed7b0aa4d430636511234e5543f6bdf737f9ecad4c6e2330d04a3f3a2c95bf2ad97c624e0f7420d91df006572c9fed5104913eb4b204722109495c232511151f13f5d90b4d29cd441694694680e8ca07d70a6855e32b3a69f2c65ecfac6f024d98aec7b864c877117ea3c0b996c6ad47f7d431d526c651ea5565b35d36d7b4be5838115f1470fd19870b4d071e061d22fb7406d458f8d106081680b362010de913d192367856f9fd3f233809796ae483329b11b51c4c24adfce763df4857af3803617bd75a5c3bb8b72ae2a0dcf6089a4b73d8e7ff55c3dbe0ac8e1df953ac350ec9f081c3bbb419cbe99bd752d2408ead2e5bc94312af51efefa21834b8bf4a4428580273875a0d56a77b16d524429e656084dc245f95c8f3091784f5d3ab553b0fbecfc5bf02e2f38705adda936697266634e5aacd8ce0b72b898a14dba1986dc71a5236c64b983eb8bce599d1d8a39d85af5194f08a9874515490c9789c08f0595946c6f5878996938efcadc8fb5abec5a626f80bcc06416fafb650b72eaa995a811dacf45362187de6481567f488ea687c85c49219057ee73b1f29bd7a2f91e4942f84f8fc26cf8d08f52888dfa460eaab41cf76dcd6a44561fbd10825cc233e0eded7e570671a2aca2ef0579314e8887f8cf3e0d2ff4da11b6a520b7354515a8b6101638a3892cbae53cbf2e7ab4ec714e2c12c2e2126d8d2d677b12a51a32bc4f68be70c064cb9974469b336c03fa403d5c787bf11ae0d770f012bb9fca35fbc7bc38334f50632a380ba4cd703ff4b1efba99af3757881aeca48ba56b58ed7a7f7fbc2e01bc8a96486a52c996741ab194e67f53636bb6c7b6aed61c714756ae13bee63078f81b984c816b42691d0233613cb10ac484739ec71723978ef7501bd598146ec34f1b3d738968d176b2199a2537cd4d7c4cf18dddb930db700b40f1de4712057a38dae22ba8177ef49a859f919e282a0c911b38077e989a0ff", + "priv": "8a0ddd293eea646f5a09a0513991ceaf8f5d7d458cf40f7c1f18f6dba8f4c2f8daed2429e22b8341baaec98bfb96e5bbcd87b0b137725294fa461aa5f576e384f4850c85a3e57765ee815679ec01d7c91b973de21b4464d0e83739c584cb7d075d349a52d69c16f8daa0a10608e3407d2cdb74cf3ddee8ded5f9565d531e0fd7d2b4510c12045bc46cdb024dc4b26494c4305c465293a8651bb5809808450ba32524b90920c3001c2861a21650632472d3a46823858480c0611ca285141942db4651a114455bb685cb16208c822012c564da06282283510b4588e342110cc461d830808c266624c93059a6111223845388681a015061061094225100243010914d233742022006c2b42d00c77094840d93a01081c64d982889d8b8058ab4051c090c1b3941424286c8102a83264c2040244a24020946805828400404715a386904848953800112840001b28493328c93243012002ae4182259488dc9488dcb98310c928010a54019426d1a0452c212458926491cb3310046728c442424918123a02053042e5b446194948400b5690a1761831425482265d2328a6084040c8941db38615aa0919a22244c406d59446d02348219140d01b40cc9a86d23480a1c223059a88444268a13c8114840861487902426685b14840140440c124a23878c93008a41044aa000499822482128929b444a10868d02240952882024900594346c1a136154481114200c8cb28c1014629926688a40065b80111b28129b009050488ca2082c139201221546e1408a1c16012192685a48415b006dc9288e93226d13425154b86108b3801ab784c0183099163198142ed10246dab030482620c8b008d99008594811a0a860188391e1904c64a6254aa81104904181c804d1386640c68c583268e034628318624b906549882919041152340e14342c59422e8a42841bc30d021026d9400a0a27889898308926648a8410c1b40c51b08894440520c810c032120885281a8968c1842120a204e2c024dc4684a0a0890a92851c128ddb826919196261984de0a84d48068452b245c842822402001c3250c0828de4c804cc968d8b428608184e03b72101a2112300851b3885a0100d40364511c0259334618bb005d4262980024492888cc3843001061208106620226c0c026842c47122934582466a90928121a124181408e132614896414a368ea0406800392621918d54442c4c369259c20c1a202088c21104242d0b904d43380120076ad3342d0a264a44ce3a2935e913f0aa8fd1fe89b01594667fcc774bb0ec82d1e1e03cbf65dd7effd4dd4dd18c18958e2fb63df54d04e63e0e1f5d72bbde611adccf96118eba603bf134375061a0e1918a6e7acbd137f1b461c7bf52697b851f40543c1ad5387776d89b30e3c947439b2211fa76ab41d3653277569ef2bfe364b01778e05985e91748c3266908f15122cd87dfd937f1537f1cc5de054fae47e9e9fc0b1dafbf312c35452cc2970aeddd096cb7e5cce202a5a6627d154099c45d33dcb6f71868039a0b83ab91fc50615115aec4281d88534904b8b2e28900e7f2574c4f28dfce80d74b6f667158dad9b778f837efb6e05d7ad3a43437b997ea54770544859128a557b898435ee293568b8b4efeaf0758986b5407faba47d112c25b716d2413adb61c8de997b59aabf3623c1c63d6150502c172a05c051078ec00ac827a97708458e44b92c02fb8dc00b717e7ce782fd194fbbaf1fd00416bde8ad8387431315ddf7ee604bd4340b14929c98d4bf11fd6756a806cdd426b09a57c8e4d5a08355ab63ff26a1b27e946dd63429aa4e2418a0af81cfebc2dd57191cf241ed3a8127c2f2a21a6e05a3f9d3675ec22a8978ca28d8baf19eb87e1326f1bd6f66e301ee1ab2b420bd70c32738862dce524bff5de1d45c8f0a8aa412e879a0edfd7fc89925cd997bb37699f4fb56d2fd4e45094090abd6017b2197fbbab1141c90c1cd4992e2347e2115f5c1f31541231ccd9ad5716da9782f085603a4bda84f6e252e20a2ef55bf80657e94e420cc77e0c9413c3865117c7cbc62a443a4a469d1de8ee6403c8fe3a3755743a20e5570462b07e96b97f92b5fd096fabca77b1b6fa724e12e65519436d679b9ecb00a71c4d49c56c74707f36448ecc11d35a767c90c0935d3f15cbb10f8db92deabe6d7bf67007300c2b7ccb57eb8933017e874ac812f303ea30b21713b37be3cdca516387f4bc3f9b9167d78fcb230331152242b85c358798e56072f6c82895691c8cfd275412d49217a14a63930c6cf063f16ab88027975ad5f83779d068874490a7637c9a74c9c973af80b6194ecabd2b9db9a51e66364179d52730f98c2883f2d2599961f16244f0f313a4470bd2424a996609c55ff8a98b6a886273fceb66ec29d1873494ba5afb927cf1383c3933ae0e85aff3ee715f42d0a8f407760c3c76a2a9d1880e4411c5377036ba3ac8f2102554abbf3a5e259ef71a5c21e20f92b272fae361fa8646a84729ae6b07a422a63db49c46343c8c9bb288c1c46caaa58a53072648615eb52ca7750029003912fae77cbf1c2304225376cb9aff6bf9569fb16e84a2f8b3b6622e990e761b8d28e93dc384fce56208c86356e1ea50d5e399d1aee0cdd5ef504a77deda14cd46468ba70358085a7c84ce15af4519bc645f544be18049dbd8aa46d4c7ffac2a9bb3d7a61d239eda5f2e8278f583e99c27b8551e70fbcd6900af24721fd2eeea84d552c79e92bf8dc329dcd87b95fc618fd0c848dcc236e947f0635fecf9ba9a12148796f4cf0121b32c220b370f565c05903688690e476a53a323d9bf221539fe30513a8c7a43d83a0d251b311e6f37fc13b3fc7f7b97de636de5fb21b748db3c2d841702cb1c930b3275ded78b4bea2f9849347d28058473f99aba265569b354b1cf4145616c65f7afa48dd0149413c2987e08af13880b6d65b7974f7b5495d307f172903ea2036bc2c7f76df653ec8b98974d4a552e3f28da26c7f2f4cea758332142e5d7e3e70191220b7c6ae1f59f80cc8dd02ac3ea99e9bacbfe8d98225818d04c318ab302a109d799c0b01da7fbd20c0ba76729b900e09df0bcaceca2762796d8e8d2b4245eb34670f34b14ce3c08ba39a130c43c48f817bee437380f1262de3acf4344a2da9fd586e2a2d582f1ec4cc0ccd5719c51052bdb9c69858757ca80d5bfc2ae1a7eb39a4ebe4eff998c1a4b42d7540de9b170f1c735fbadfd82a4b7e5f9db6453e2119a325339dfb15a1c7f5b4aaec375fbb96aca925042f6688fb6713131883eede8359912e356222edf7637ec9fb357f3ab2b0a525d8ecd50ecb9a5d3b83bb22946e7bdd325aec720f3cb9b5da1bef1ca8c80dd0d4fa4273a0cfdf2c92906a6570da294c853b48465c80a2e215493602a1eb72e1f8d4b23acc963c5b93c18d927077db33c34a310557c57e6cb2a25d4ee4fbf9d16093222b7e371ca95090eb17a3fbf86d9cdaaae129b57e3c6a5aed0476a46957991729dfd7345ac8f3395fe33c4ea42bc82ec5710e9d62d9ad1c59e47f21af867f861db64c8c25aaf22002dcaf05670a8fb7065c48c66edcdeee05260babaa9c6bec8716536dbf832b7700cdd9c" + }, + { + "seed": "912a7661fe0e8ee0e8340cd82ea2c8679375b9dc8c41109d62100689f4eaa919", + "pub": "7e1a382b8034ceb81734504f32bbbef326a0600b043289adc5921fbd1ee1a4bf784cf7a5149d8bf3784c6145c50168437c1ad404e91acecd39f25ded0c2334222bd72806a6c8278725d71abe6d1c3b5c7f7cb255c21713b5d3c178114e48e0248693e18df84c69ff4a580ffa0a87fad3fbf6886e1c6a651643d1689e590154c43f6ec6285ce4d4e1803e2f1a4ee1210d658664f243145472a39b9ecd39ebfe902c61d05d8046bfcbe0674ad05f723aebc765a6d7d90c548fbe098933e647873984c57df940bfd734e4e1d821995993fea8d768490d6da3ce8924148758935616c8d6297bf6db936976efdec7acc4394182fa002e38274e615198218b8b4e9fdbcf7f1f177f3c954cf4a026e732b0d7621ed646130d96ce93464170b128e34b90fda234f5d5257d28b95348571be63217593384521e0412fe2b1691cd3f7181f8a856baf00933f7c8b0634990c595e11d2339ffb6ad012b11ed0302c70eef648e1023180d354bcd9b0c0d5ae9c525684f40cfa2a8572438780c5c8505e456e1ba13810d5cd486cb4e763256a9f15227699705f4f172b1ab25994a6b1cd0d77c291d2f479390816d3787c62b8cbaca908dde4f938bd1c00fe342283245dd6d606b4e396cb37b696c91cb386ca3af6ad98e6e49b66530be77825fc4be2e0677dd2497b249a67f2b5a03aecd8313ed4f1f29af4c58f1509bc2621d9fffed3404d6b0556653e6798c17bb496754b1a8d9d4bc64c805d32f7182d00a95580ea4d18fc5533f8dabadfb4b23fd54faff768ccfcd968408d64bae13d68cb0f4bbaad354e4c0ec760a11c3ad69fe4d692ea328a509a11214f711728cd9ff0c4032002897ed2c4a80f3f40267ea0f29a2662948d472d553c9aee015fc4b3fe554910d6d1c04cc8d90da1b14523a1d55f3b907a715d6aec33c97229a8c6613cdc60d9ecb2903f762b2f03f966666a3cab8487aa708fa24ae72b9a88e7ba514ab99960a31bf68841a5c6c8c164da50c2d3bda2b6b0d62bca98a3f01203cdbb3f5196cd51814e606f6fac34bdfa35097d55998646d14492bbe5b4b2ba5fa7b506ea6b50266f3e3d59cb321bc4c6e69b888db60a90bbab585e965d116651779617eb30e4be0b14ce78bb28c7ad7e796dc7a8698777257a712816461d271f3285e5e6fd2d951f555b66c6daaf5dd0e6db11ad8fcdc7d47ceb54aa25f657feb4af37676c04b48d27cee00b9e48f29dc2424667a3890cc3cf0e39d384ad3f54380c983fd1f8293f3d6e64dd013152aeef3040f6d93fcc23e7de02f5fedddecbbf3c002d19129bf86073d89f4082185ed91a9b90577bba8d54a362fc74bb7e4cf8c001de6e5f303421d5bfae75ccf4ea107d8646f23f2cfb13fe244bf0dc395ca41bc504867305ad20058367b949c5a71833bd2df37f0a9b9baa37692561d4803d8bd839b52e9da448724522f4f6db2189420eb581ead53f3bf1a1807a442af71916616107539dbba2adaaf0eb9a9cc95bcc1cfae818a7c142a88408c531ef5e8b4554902b008ad52d6ae375ef2ac8e565cf5803bcab6d98fdbd55a86016f63eb4e63b57b65daa9e1ae4dd08abe8fe05c9af815b6fc1af33d502e3fcc1871b985aa31e1d6a655c94f4c9c6443c01f6f3ada3c81677b54f9bb66a655b8b2b3c8397f9ca06ec4cb008e040d9ef8ce01ca8d2ea3ef7a2d8ec75d4fd6e5d172f4d7414c45c6caa6c7253013df765685b4a27d2d44ed76b289ed24c7efe0caa329d677dadc18b65af60db0d38670ff3223018bb0bc3be59e69c6141408d56d581185f4cd0079d561cc7d8a2221c65cc3d8341e65b4cbb8429c40a62df806a66c0900773f8597e510c09ad290", + "priv": "7e1a382b8034ceb81734504f32bbbef326a0600b043289adc5921fbd1ee1a4bf71d0dbfcc2117b81e118efdd1ae322004c61a8aff62cdea0cfe3df844b614e30f86f91baf9685984e5844f082ff3242916831a297e051947f5337746638e23cc5cae095576d1c96355f663e2dc2d5c48f36673851c4a2420975d1847a0b327eba1b82051160821c75100187204314152026aa2168214212ddb042e2486695a223204470054068ddc840c59842903a451138671dbc62c01402c4c2872c88408dc428c914865e22010a496499a82249a862c0b938482002698960492a42d821848ca869010c931d83030e1066e8344410323840cb88c11b58c12062d14847009a129a2b84dc290880b01102420529c187151b62020c14d2490305b066884160e21c220a13292494281c1366951200218a86901a40441c42c00a58063040d89246e53946d62c60808304e9938212421650cb66011b749da200192c29118a04858c25110019159064ca2045141a0912228828cb870c4080e8bb28c02148294924061b645c9923084440dc2288ac9128a20334d44a84521274202804de31480c13821d0000d500288592846224526091144c1204ee238701ac86848c00149168d43326412812c18498c91148c92920412b108499090a4384dcbb46ce036900c332883242019a44109a75183446d1031001ca06c62b009082085441451612005229401224450d40672d9c0680c94244c4281d41609ca908151248d22294a24406ad3302ce1a648e1c4601398800cc7910a100d14996959c06dd4b8291cc36dd3200e8b28108a2489d2c4298b08091b1491091145a2c42c0ca680a1020100846d53b6200c804559c08090344102460e52086cd40848c4147140148c0bb7801b25041987701449094bb205a39060d9300518024d09a64014014d8c820c0a06654a1668e0b80d84860d038201a2a68d423202e384715938421a264e00c8490c868000374dda4248a1886d89a4885b062184208522418d2012006024421c242820c311d3b2810089202118849036848320405438921c472542346a58482c0498680c9649144451103660884482ccc0459c406c94124112496cc0368a080865098808803645c8224d1cc34c20a751d8088a1491216496216422901c957093408a81b20013880c0b0042102209cb0806242432202948623684d32891008100c808894a384d19024a51247154200050486a0a3842d1a62508c805c808011b9145c09200d30471b77ca8d9029eadf93d3f8b966391d8bedc7c26946390622d1fbdf03fc1d7f09e6b09d9ecab13155798fa73c9af3af5d65e1332d6d9252a4763b72b2c397c379c5c808cf9134b0528e3da402ae95bd4c1550bc63a2467c8b95285a70c4bece907ecd92b2d720d9342d365cf185417aad3ac8b43945ff9ffc0f17ed661eebd606ac84ad4139c9da296391fbeee6fd4690951f99daf4092a985fefc9f572e7d5bae1831118e79d9b91b84dd540dece105e1991657737c44e84f4e4e71c71bd2affc2d71125e13cc9db7fa947f0f9668bada3228801b0c6ab5c6816134e8708a11cc4957e69ef5c4277b6776293d969adb3ae793c436394827fb57f8c576a71a71407093137b0c2629e17025f5f5049acfe9617fe5fa67a426715b963ec92e48416b14a235c17259f6fafa98e096589c3d559060652fc6164df542d5d6b5dc3f83658fd9f9a8b286216d6e67f987e9f7f35299cca0cfa03dbae1b83a29fac7f4f3a58b7612a04eccb65154b33a5af5cce37f118489bc06afa6139ce4627aaa742bfc1ceb778ce7ba03328098848aef290900e2736002fafaf1ea7c85387159d391e9e916524bd9ca0e03039ebcfec05988f1ff62623b28bb2dedfd0f870b6d8096f32ba88aa53c96d78764a779467274f2e273b3f2cf610722bba65faee6790c0785c303d20a2e518cc5a2e8537c21f8532f485ec7f1a9ce6bd07d34a0e2f6717106a9ea7b5cae3bf4ab96d0c30bbd85921d0af85739eb90050e2e010de234136cf44e184490310cd06d38008cb1e82da59d28d4f727e12f50eafc0d6da277188c8e0fe99320850219c1595f9fd93a1e12ba5f3d144117a6e229cd1e8eef208e0008df3342767c970d01fa43ca99a82d13f7ff514579d9225e434caf73ade1f15f7c12c62f4d3e4d78057d9b624965d20573de107c7b75306a7bd62349b66e1ccfba69fe4913c20cd8bfe1241f6ea8ef41bf3708cf3091c34fe4e540a35f0cae09a4eb745e443dd7558d43a7f9ade9e7b887fb2146e78b966b1d558b2c96ba12717e89c0f06a90a7bf76df7768ece0dcdf9d04e832da091a3accdd30c3770c605cb71f3b0a2a41d4be3228415779550ee3503be9189d5eb5ccb29c046f4f23c5b6341b781b7bb44dc778c20b0e8ebd7cc804b90b680274c01687087b60a14f73d5acce93ded3f2bb2dca53e6212964bb89aa2ca289fb610c0c9584154bb2a9d57f8a944657578e96deba6bb8237bf3232cee4bbd7c5a19b00d84c3f8c935a6e890beaf4b670998b18f3cb2d47f6835b4180c6e43a096bfbbe8a509271abe2fa7485102942dbf5e55eebfa78e3b8a7b46de394e9fc76f6364d79b373db5ecc9fcca18f978e7ea5537ce7e7389dc48264813fc61c2bd1b928347960db1283bd11f98f9a1d9de47e3c367a95e85f06acf5dafe150badade5b562d48ff49a821f004d73ff38bab9dbf1088f5027befe7af2b68aaffe1f836a15ee1170b80456f0df1857dcb691d15442c95b3bea0107babd69823f71a41d7553e6f80ebaf05d0ab37666408740a8f9f09b444895e85f3dfff17cfba2172f01fd22abc33303b36c783bad3070a1f179146dbda5b471b34ef8a256e7738260c0dae8bd824867d19ae04aafe15b5807352fd91bcdd702d647cb62335d95b7c2b5b826b53f5d2ae0b9409cc61d8ecc6487070d6a9061d6b464b419e57f813db5791d7d1662dca079107d161d311dddc7e54ae823f8f523de265948e68f21837f68f01b494cdbae2bcc938ad6aa4e1eb53af5797bf01b21ca2a3351eb1e88d6d5ef47ba3d37a5af3350127845c9365ccd0b64462ecf1d0a416048c3d62cc8a37606200675ee6133ac74a47f7c0fb82e0b9fc0e63b0bb2df28f2988940e1bfc39fdb836173ef5a4969a48530586e7f53cff1eeb2d0b16ea3652b4a58865955e93676eb911eb5ea2e3d0a94ab22d186f2e70463bf2e7dffe40f6fb5123c0edce83d2f0473cf312c13a54705b391a171d72697f7f74e06d2e9767dd50d5e624f164ab33d701932699e7087ceb017368fc1ec683b9764ad8c5cec324b54e1dc903431f81032a45a5c61f85381593e5e3bfb74a5c1a248d5441a226760c8de4fdbfa0bf13e3064ff187242ed189690151351cf28a2b3d40cbb5b3d880c3f2d797635135767f55349ed3f4a4e279b12701f9650807a4fa5cb9100be67bd5c6f8260dc8933346539128091b831359863943faba2bf92240003845c2a871d4f4585e9bfbfd34a6b5d097d0f16086bf146e2e33aa24e3d75c3425bfab50966577605b481d9fef718d235c28eeca058f658289ce2897c66401ffe3537dc6d90bf5a4e4786b274b1d3cfaed61f8d4f89a5454" + }, + { + "seed": "885b7df7cf6695f30aa3f1bc6a3840b8ca3101734118ae619166838aa3efdbcd", + "pub": "e657ea5cb1ce08341d2e59c0426796a8315c8c0373c89c2f5a10fd5667b2885bfe5e31a1e0339bf83f848092b623761c8deada4b6139ea700a1a91e5164b99357fad504b095a74ad684e4de51471d0976ed23e6d8164f7469e50478a91d45ea9caf0dea00a618fd60756ab09e617293db9859c82eddff4e5274af10019a233309073ed469f8e438ccd82894f6d1f095c2a40f05bba63b58984458a202016849fa2a963ff6b7eb55c3d881aaa46399e76e2ecb8ed8f05f15dc60694690b1e7687608d5b97684f2ef59a24625c4ffa0ea6c3cf410c275e37b6fd936c29a803f3f1e90ea53b7516785aac68c7ab89ef15562aec97e258b30d7b3947e655228a5073232142fb96d4cd64c562c2d0803d109db76a2828e0a90cf87ea097e3791105008b015e236fbbb1e45a19c8a46132ee13b651b81702c2d19a41fb3feee728bc5e67dceb3236ee5689e9eddc9201ea91670459596a35de88552a3d18f47f24ca86717b77702808398238d59642a38fa10f6d17bf28de18184075e6c4ce4b50ae2ae0d59d080694e13fd6500f96ab34b4e2882755a11abb9f4f56a275f43329a6cdc6fea7220f63d6060aa389e5328b4de152a17575369a62ec41cae80f4f7fe22ee78225485de16af283024604d979fbe7567c8a6184ae0c967ba5a8d8245e8cf9623b36574aa27e0e3f8f2f5d8a1466d4c45d17df60ffc6cfcd9c7b029763c3139087d7ae8b61f0bf34a1e03261b44106a5a18c8655ad7740b335564b2c2ddaa81a52307d0ed0dd777d955c90db55682f7a5563d68dce388a41e65503fa2b5fca33f636062dc97bf3cdd9201dc1b973a4eae1b7a45a72573dcab1029e221e9efa2863440c4a41b5bb23fd457cc5847e80628b8d6f5e713789df20350b7bb295344843023d06c793ba30f9c4552bc7579e484119472f3153d2621c948ddb9701a205e9b56acbf08684ca237afab9dc9894b885b24aabb86bc22b8afa248dfb776eebacee5719e93e8455132ee28b6c9f716bae0b91f22c14a658ac1cc6d15bbfe1184890d5b0573ca167bf3f3531637f0be6700e5d8b279650cce11d5246097bca3b43722396708cd0a4970db56263fb8c04934ab7edb97613276dd5ecc5555f45c1bf0405e83655d09a79e179c877b7b53750b2d6862a6d96b2e3112a81d52bd3a96d233e6b9825cc48205b344b3844d1b10469c4472d2545f9594eef1340400a9634848dc5714f21bba6b3d12df8596032ce265954890b71239ccdd141872b4652f32b861a5e01b2e441d2d7765e489e202f79d6dabb09c082fbef56a3d32ac30dd76434be495ae13fcab1e9cd16cbd5fd3e9cc50c25503c5141068966db483dcff107a0505aa3dde60c66ff638c7f84bff86f3bc5c2f8daff19bc8ed84a2df6f39c04e61f77b0fdf1d9abf204795ad545d80e7524508f221c9b80b244a396aa46ff0dce813e704bd9c402a5317253e481a8742ae6b99a5d7f5bfc0d5a266b3ee57a84588f7e825419fad1d30bf7f856585bb6cb22e7639cb6f02dd52cccf9502cf30f4c9fb7a54291058f81faa4b1525c9aa6c5dc798263c07922c428e43027eb4f4db3e41120ded9a74cf1324b5e9a4612676134e650c22300dc078dd5b84611bf105703edb7d64ad68af62efa52d8cd684dd93599adf15eb2a0a51edc60633741ad1c9cbc15c092c2717c619d01fc6e2483b6831dd8672b97fc0cc7e86fe8689d30c02d2b710aecec599e0c706b7284e13174b1c1d4c4f5f88335157dd837a823488d0e1219a2d92f9ebfe7b4347c687a4da3ea6026f96712632cf9abe869812f6f12f5200c22c5f52e12e1a08dec556acad92ae79fdb4073146d133c000e", + "priv": "e657ea5cb1ce08341d2e59c0426796a8315c8c0373c89c2f5a10fd5667b2885b04ec298f3aa93654e01a33009c14a0e4185cbd4245ce8b5a2685df7e24976d3a709bf64d5baaa1791d413f8da075a552705c11cba7404420c31a291fac5824c9176539015c3f03ad5e63646a93314ea25909acf0c95f7015dc8446d063fac8d6199650191125cb848122c83104a3092434615b442e48922452000019c160222484122700cc322d02c9408994292109428a42494a0262100252c01801081040a0c6908242001c2530c2340963986c14c90c18294a0a870104a99082a04548108889167093322a98288dd1a42801286142486219a8441ba5248120302222080a139109b2240226410b2888a228919c0892dc420c9802051aa92c04b35151168e18c044c4c66041808844b04de488280042868188409142461c812c12286510250e18a60921220a14c44918b18401c70c80a684a2a06024468e18c12d82902c89b68914198e80148511c790d2c82918093009a170d1948c929061a0026c5426508a26821b494c92022d89305002886990184cd498491949268020889b40110c3584a2b26d9280450112485a288d82480c9a02898a846cdbb87022272521b5841216421b840ddaa64063146dc4c69184c8299236020a220d032445081385903409028089c8880022238a5a8050d310854a124ec9b46103122d8ba44dcc149160128840b6201cb9015904040433890b0802c18209a1468aa13289c8a611e0143199b00981462100b9611396441a982023258a4312489c36680c0670e43626e11290d8b64591b22918136a049501241942249471201628404662432848441801c12848a42092420425dc8449db124e0a468c03274420322d0cb06c0b81110aa70c1b83710a312221497061a4609c3222238664d2c28d0c92259a94315a442222088e8a3690c8186859364c08438810226d22144c8122840b22520a2620a28048dc128091904dc1381252848413b771e382909a2602e4b0714b186022a5889ab6514cc80161c200cb465284c801c82865d230268b100620310dda184ad0a208a23891c8028141162958b068432671c224658ca2614280290ac24920401042c68002444164846018a76020021013924814272d8b160a13c510d9347080a00dd9380843968192a24019b16d40423184a031d2442020988892947098064a0cb94592422c840084db202213928000a38d94986812140694326914488194168289a46412a760b8aa3d5dec680e7b2d97ed475a39eeabed483b48ba9b453a7d9d8ae851ef1f82fa57bd3f05d03180b744766f3132d868f1e61bb3529523f85c90e7071137bcc54ff472b378e664a0117451ce47f7234575082e8b66941db645d27aca53df4056c6a79d41d8efc3a27c676e83c43019cb56c8676ffabe1f924456fb102c2a1059113a1d049ce6063a56d7b0ea8eec76674cb36152c599d78b6b9adbd11fca00f0b3e2165c6130029913addbdb64e5cffcaa65eddc272205949a0fc601ed6b31cbc710cd4881e4f51d3489bd97342fa8ccacf9b03f07d952c37217c057efd8348534d0834b6537d14b1898d5c6644d20285a4269fb7d20585019acac0634c9a7a0bc91e595637f9b16dc454f38a1cb39a66e9d8bba5c496644d0584ca0ed14a03f4b03901c82d6ccfc5151c84103eebc22f2d190766c60c31f3f80aecf8e3caf750e02d2745f4224c4f4390be9ba43da82b5b3270bcfc448aecafc87eb2065c0d4c169609b78b3c4531be26a84a4957a5e40037c4ba223ea5f19837ac3078cc5219770445a57a23b2255751a654a84a95983bfe09290a058646184a4019a678e0cfcc3169ef5ce169956a27cd987172efa8f635b81bca50c1f12577e126d7ac0fbcb0356220da0bd2f3ebb2c0474cab6cce48d9ff58743eca8bf0e3c6a85d045edd4426cc33f86093bb76d946e36779d7e8c6d451027a826e8a8c2a1dc6ec5658df8804c25f17d7c5bb4b8598d495a8e198bc43aa9b75d85f5abe22d95788a59ece32f4eee60d30980cbee238b314d520918e0fc73bab0b8242ebf523b9cbfb606a68d7f8884da73979bf826507f7a348266925c8d1168272f7851d5610034e97dacd3b014e0ac6a04873d1d1700e76231cdeb7e8abc18ef36ed950744bdf888f958fd7a3955aeff2016ec2d6c1896ccb4a6fb558f07ff180d786925ee1e818bed17889f7d3b0ceea8d5ce41f477c4b6b4bbc17d1251a0e4fcd8f42ab3f0b95a2e060c688a6b912e4b7438c4cd144fa4dd2b3d7e6212497cccd111033523bbc907eb29c7674a80d0ba4c27e24ce74998475a64c0fd82a45b3bfdf70971cef736b1bb457f30d918337d7ea5845b97c1e3232440dc9c82140e63cf88eeec3ea4b5bccc898ef909a556fce59d1d4fd6893d3f075dbc37f1d25e54a5fad6b647d2eafba16cc4c47e253ebc0885e5587bcbdba3770082864899654722f29058b8bd14c739463b340962556e9fab20f1b81fc799d083bd2839c9fb220fd28f0319f64512eae81dec1952cb9a74976f42e67b72533e68651d1d4437dcecd21840318e4ba3989a965c8671bbb2594f32797efa3ec720cea86b456361819e9dc13c54381a03339f35856d31785ca4b863c0e896aced0016fb4f0c7abd5c6bbd0ecc8be62a87589df02b6aaf03acadce4b7b72b9f60b9b1aa662b96a13e10c2bae862f9630c9cfe1fea119bae1aaf0c7df95fc08933923addbc483d134c60ba303fceb4096a389a333381dd8355fd3f39f9d9d6a79dee51282a153e55e5823759f4b2258e7cc0dcf0d41b40f76e3435a68dd7e92a27bce126eaaadd224a049fe4f920bbcafe1a057b29e9b9e64e64455ba54140bb4f0e4d4d20507c493e17ae36c6b6a36dd3853894ffb44729721714abb859908d84982071137bf5b359e3019a7a267ddb333d506db8a918c2522f267b5f4700a9179c7c0668cfb0be412ea7f4b36c74a1761c50e15c5d292b59e9c1e90bfafadc8c05d7146fdc9df78777e886a0402423072381fee790f5a0a5f6b64f3bebe02ccc98ec0205d30a471ef69cfc22cfc1c529ffc3959d2c57ca744170f3e95ef0a9166c67a4bb41ba66a9d46556ebdd2e8c6044eadb0bd49e298d806456062cfde32c017d881629381bb0b93c14f70fcb9a48e7714b9de2e3f636bfd1167e1e3476928882b333968af9f3953fe40c51df6eedfe056cf71a962d936a821fbfb9191d60096c27cfd8f92bb64ba4d7b47ec12dfe0bde1ce9e25ba50b33622bf347cf09c607a60c9ae80646b6958b8a5873551b4f927653ed379349d3382d856602722dbed05dcd0999cb88a20e04006b3e302e165b5aa421e1c4226c19ee0c75f7f6cd46de0f243f3367886ce804e57ce16a3db51304dc2492649cff16731fc748516020c7b2ac3134b75ebd685088d177b7bfe1eba595c798619476b8b2f626d3837a0397a777a84aaab4e998ce5d1174399bcfe5c5241e5288a241c4b34036f8b30c0862dfba419ac96de6f4a0a5e3eedb0532baa2defece28b912d6f50707f5cf743dde5bd33d98e9108fad9e83812f0bb143fb0f82cee14db90531ae1738978bb69c30e7488fda9232e6baf117fa45601e300" + }, + { + "seed": "658828b30ffc0d7eadf8cf3e754c0b40b6d9f70f415688b9de865e0c8c3bd9b8", + "pub": "3c7d4b0add86db54db40b76f8f0b54c62901f52708849adea8dcbfac2031a4f8a8c5e0649ebf447c68927db564000ca468108a33097737e66b43744b0bd8b9c8d1851d8d95ac30ca888fede8f3d7de2d0a36a8ad2067e6d37df99329187d17c0aee7d9c4cfd3fcf9bc00ef4de08ebe6fad356f7f0493826f2bb73ed1919d3cff36efe633fbff5876c516ddcbf1dc2b6216a74af1a7dfcbe9c10054e68ac30890de8f56e52cd89307cdfee2d0c7cb46cedb0cf9a07ab0c00e0a09c59077104a525abefc57d4f2d97fe0da2c11c469c9a68ab584514975670dfcfdd2369f91d8ece9bd6500dbf95d1d0edd179a968b5f07a46c0add1f476939c9e1f28f7a26a3bde80f710cc5ef23840494961a14145fc92126b2992d6024c1a2c4929416fcf4a3c3e2149ca0dd38163e7bf3bfc268bb840f1e5430ecc973136517ad23ef9bf98ed180db59c81a1f77d4bbfbabebfe72d4f625761b741fb4ba8464905fed4242ff4349a2d63b605d25dcc79b0b6cebf3c94522e8cc87e55ad6b53e79264da61e2cd5f713d064a0849dbd3607dccb2f4598d2a7fb6a878161137875db4d35dcfe5264c8a8b34bb2f3b5099a738abf0b7c295da1497c8620b28fdb48c2d6a7396873670944c61477220a400ee5618e8e4fdccb30f76ec7591003a6bca221bff10aee5ba8ac04512c29037c05eedee6d6adb3106aa3e6ccb4d5d567fb693a46bbfad9b555a2640a9984df3ec324158e49c8ccec771f9219df4fa86c62ff1962dd99174c6739a428918fd2ca7d66b7d54f983bfd542a612c71e99bcbb9b09011a6c11aa89a872b18c6ef6c28d87a068eb4bedc22e4312febc6f6169a195baa07499755110e43b64895d348589c01c54831775c843a4dc18564942a53d1ae2e5913d18f2852d0e1dc880fc78fb01668f99a77c58c1f642fed6504c11bc5fcae9757596f884d7b83521f07b3ce8c3e33f8422d2621c414b1b32250398a97235e79f86408ce2c82923901bb317f7a399bc17e05353fc0b02886422a33dcdb22b42d31d01458675a43a0c0d532a2b4debce202bcb5d9386521ffcd2b4556eb07914ac2f3b1cba224fb9ec5c47afafc8d2eaea24accde7a18db8f9dc7b2bc5e90d69d4b41ffae5f811b724a8ca6ea7fed987c9266b0a3c40e59bde7232edca46b4b4a12648fb146f0192d24e341cc07b214f75f2d6d7e828356711dd4fd9f5e9db7fa984ac3fac6c904f8bbdb2af1522708ffb7e7e85b925cf180713b526b90b4149ab22de5bd25a5c5ff4ada3dd4dbf3600f2c7a909956ba31e36575d34b1ab9c899090e061d4e999df6ad50c95d4ccf79ce1e39e513a13aaa9713f08787ed40f6ea11e4bc44175fad4510c67c5d1b07110316db3e7bc63efe64faa2504b14a4db19b97c123d7c20f25c483fce98cf7aa749fe9465a067be82807c00b9b6f709714274d64208b2d44b50a06d9856cb89eab677539dd9b595eed410f581d99a733d1e5158b8ef1488f08160f99d34613bb4cf04d115976fd04f190033c8c3881c2ae6c4c63f03390f0cfdf6564f1992e628525d25c8a55d3cd2f9f2ccca0f31c1fcfbafff97e493edc42ae8223c891ec989d17c5fe85b5ef1fe2c2c5df38b17a8dab26fd2f85865351f21ea261ec96f8609c9ee91f67da0eb6356f461d0d1b6cdb7c27d6b2d47666c14a11bbf5f4c5adc7c5d86ad04eb2e46261d6725ed55a2ce49caf880722d3a8bacc10bf8bdcd20cad0bc8f9fe700eda211bf8e1d0cc65cbd663737eedb7843e956801520f7b800ee75778930e0ae91f127330ecb8d3a0dc28ef39c2cfd6659ec2db93e30999fbd59cfdc3ae39c423eedd2609fd8df475f03cc1b624ef1", + "priv": "3c7d4b0add86db54db40b76f8f0b54c62901f52708849adea8dcbfac2031a4f8a7aa9f102b413b49b27f8002ed446629d365c4241b4c83e0a8e2623c787a149dd1e31b8fa7bce228106a87726516e4cb5c4e608bbaef80368b8dbb33b9d991fa293d86c08456f0f92d40f7f1b592339c98df48650b7ebcce9317810bac44236844a270110184024212d3488a98c448e1a001092125c832461a37420aa331ca366dd24822c300111929690c0124030350100924a4982d9920240b417054084219b70821454952b26158040c99126e12215022370160844082144c9ab4085b2042142206db4882d01251d202484c360850b251e3362859426918b208092972d3266512000e4030085a84415ab63010a724a42829c41251532441d22651444670cb36449c866894860900814510b141d9a42882860114338c1014801c216441366c51c8289b0452d4162a24918c03864894826004a70c424292884051210885d4288880a4648ab60d92464609a54da0c22858040024336c09852d032625a0a60543a66199300e08b52c1214511c446cca0662228904c2b421134762c248320c12414c3491d0905009100d140231a33268ca1804e110024b346c0a974041128a6382908c307061c44c0c1065d086619824728290501b104a1b38624c2484cb446a8320700b180e22432d5a242d198290cb84851a9121c0148100018a4194601094051009441882092342041b44890a04885330648a400c993820983241103704c3424098347002a62c224044dc466498442894344999468cc3b64823256258088209016290120582a428631241d24868224029528824ca406c8ac08401322d081709544682d3b289a3844453a869d9046ee0b631c4b64d612281218101e3084ac8382458082e10370e031408e04012d4b864d4046cd14290d016001c95652310021381010100650a0520db1870a410114b1071cb941140184c8b222a99388e60b2256144911a2480c0208da41072e4064963c88dd3926c13334e40a809938025134264c2368dd1a800421260ccb6484b1491122589e3120e1b1406d322921b413014432ad1c288c8b29099b66da412806202120b1428a4c084c8b884c8b64de3c88491180a22a40d203192d2c68040a6818a9001149171cb2846dc12010c864c1927110c480980c03003354011b76ccb266cd0b6481b842558909022a94c94085220945142b8311a146d992062c4a28c89b22cc98029492630e4842863360d0b094c88d115f40af75591f4ff17c2a85675d2f9e25895555c6fbf63fe3f6f5385464996441505bd91fe85e98d912297cd38029047a412b036f1860eb35dc1a7f967e7cada292762fee43b1c833036751902e4bc1b6f7aaa241cd3ae5266739476095ec7bc4cb71f8348f705a5baffff836d77d8bbe46e5605c29c1f474a5c89193e88d4f2dc019026e667a82cb94edf89664860863f33d616928efee0b8d7e29f4e5b7cffe99326d8c6f397fd21400ba6d3934d6a0752974272d957eec328f37798486a508d2c78d65652782539fe03ba9f640199832f97f4667e655cb958ce1f66e8536b4a2e77f7e81400ab56ba853726d50b059c2061e359acace131085a26b6f4876f98962bdbbc81c6e21f958d18f58653ca3506e7dc1c80a9b94312120d89f66ca4bba57ca9e9ef8d8ac01a89716eb613b66b071895003c55dedbb5ed6f7d923337b14e8b839f14a816f731a8b79bd1647a0346574ebc1c99ec7a651152e6162f9f2f0ba0e0a007b9301cb082f22759f2b57e400bfe69271a5325f6215e9144a0f6f6f0edb0b2203c9a77596dc5bce2a3adc7a895431edb956bfb91076509f1b99fca9ad3cae4f4b7159bc5c99872c0d267b9a81cd87b3690a739e26b8d15067715c5a86a0f7e4179468aa8941b999e1bb2b9d8e8fc040ecd0b869815d32dd9b11a41f2edd724a18800977903da991191713e2e098ac750dc697ecfe4fc43487b38a5c2733dc0d842716e856673a1ce3ed046a5daf03ead9a18514b27a2713cff3742abce3b6b85ec6c494d94f655f7089d1da7fa6d18d82bc8f443a67b00bcab82964a0b377f595896dc8195ae8fa2fcbfa71be62f23b802256a6fb07237971276fcf88ee15e41eaa263f958d19c9e7b7ffca6b30fa91a304601f439786313364a03e73d115cddb89eee9fc7104d223f7afa582a1d0ea8daa9e706240239840b4a154107d0e5848f428a67d14e8c87a7685c3de8e1bc896ada3b67e97186fc75e5fb8fbfb9febd0d68f2c7945406c56e574aef3a9739a96710bf8ca7235185f065ca059d75b3cfeea0b049bafcebbffd67f63d66262271a3ff6f5c115f58e523b0474fa9130108e93f4b7e44e084bd2b35d41af8436405d0f8df3b9f780964e6d552f09735e58e74e567833d0753645199a39c1e98040b5ef86d388a93036c4908dde0021d2b70085a3b3652220358e44851cbc3b4f35b6a246573528177c6fd231181a24d9479329b76fdf416117cc2852a6ec4daaf4f6058ce99b8348375937647de52bb0b3d3b136fa632e708c8c5119c6085d89da0b98f14255bc61b1a308bf38d8ba61da39d7b5b5d3e68cedc12d4a7ba42438e5663fbce1c3bbac9faac4635f2740602e29d2845b7460c5e965dafc618cf6d1afc0497317c044a2adea76bd851f9a81c7a659dc152ecfd94687cb446c1c3c0e4a094b4fb71a035f5d1bff6b6ff3633c9deb6b2fb37d309a67050521d6d2bf7a6a43a48e20176837b2e571e6ee5caf4f001b7abc11c431d5d8c0d0fecfcb9685c5827302bafe15528936449a741c749d3d1d544daa4c0bfe982ed274d13cc00ce91d40c0876f4e5fd3ecacd5b836e1321cf862951e4177c528a56ee0259e61da4b8f1dc5ec786269749508ee6c83f86fea11863a99ab8add986eaa8a822c644134bd1e13e248d74595ae1409e79035afb7caf640f6689b49c5c0f3800257e4e163dc9c2b57a672593365ba3cbbdc0c5d683da3908b0a98f3d8456f9db786578d2ae605fc1cf1a9d11e598915f70cb75f6094cd38ba8a5a830468d262ddb6aa08238c5ed1d9b4213d3234d9ad19270f84560cb4a8b95f8b9aaf42b7da406f7d915443c37efc2e6cdd7da922976ade9d06b449bf966f9644e3cad50697f671e985656e99f116b0bb4ec254fd9be5c1d12f66213521d8d02fe264ab4e64e5162eba7dd239d191791bb8d08b7f0201c02256e33770aa2fc68c24ba0c5a370600cb7990b5eb8d0c5b5b401b71914b86df50c647cf32d98891cfa9918cb3a141a9117b6bf6f58bafab4c5b3e947d31854a094fa79069817fb2e779ad650fba85081dcb0c5ea416a850fb4e93459cf79c4c6c0207582c2b17043fe87208dab93ac589ee63e41531dc6c662217bc9275b2a746ea8f6f231248cebcffb8ce3788a7e00dde53f8c1faae36d72aafc225e10026b67f2e82f986b457145d4efa8282a84ee0b1361696aa2002ccc0ad84c65622cf8b2e6e2b56fa426720df75df76c01da2fbd90625f848b88e261f09583d9b950fe3141fd272f31633d0630466a90653864d52b0cbd641f5950af58292cf21bb77dc033194d81c6cc070ec1731fda5951698ec8c8788e2a66459e62fd" + }, + { + "seed": "03834ca530ee44dee4ebc059283cd8c8154871efe5fc84a7cf945e4e084bc080", + "pub": "c4680260b24be4bc2914d5d459c3d433675f87bbff91115df1109d37fb7439725c410693613c00a1c1b0f9c1c5a5df21877c4b3c4edbfd388b3a17d9aa6ca5882fd1a1bdcc0be7e3f3f8c0144fb9d4a591ac6778b4e2a0b03e70edac16cdffd57eeece41072b801ddfadebd38f1a888b59299eb13d638336b54405127d31e82b6dc3dca0860f6150f3d5f22f69ab0834e4207efa5956d5ecb74d6f9a6ddd9e7e6522d4333dcc1f4706a4d4cf1772a2b1b88cf36bfacafdd15f6799d53adc98fedc40fa5958e78804c2ed1be76706faae0671d9544ce64c0f15632820b822103153a764eef265d870a35207289f18ecc5af08da9705d89f3cda09814de4b9a1a8b698ef2010ecf6487feea73240d7611e52f206a7b9351dbb13f3d9720b9e67332866c89f25bcb248af99c2dced21b44f595facbc25e594655f922c430dfb8d5158d70261a785cb861011b919faf10b5e338d33a4a0852c5ab4e3233a78f85a3788e11663ce4903033313f8654ce1df2a95c28bde03d7a00a58f45a5d9bf865d8226a23f78aeb3d606036e039856918ea5664c60f11c5bbe065afb870485391bf41035ae9262bd3d98791a69541ed4679300904963796b77c4e8f0be88e0f7ccc3914640873a83cd5047fc61af2cbba2f7d359850e5df3291ccc3e9d0c3a87d34fdcdbcc2abe10be5254699e510cbcc20723a8ef243a30a6c6bc7927e1920b80de860dcfc4679c0c0a60ce5637260192be9016ae6c1715cec2f0254b121017f3b2145e55d00a9fecfe40518904f39e8c7b2084e04c42417870f473fe1e0950c61418bcc7b87fec86177b9b52c704f542d7e8dca57b44380c459a69f8cfe38ef6c250bf1ab8afdb36773605fb1aad72f735be7c2425aa4c5514bbf0752d8c23a7e1188d67cc5117c078d53d98567da7e1a1bc2cba7e1a929f175211645af78964f97e52eeeb73ed6004e2edb147a424c84a49c9f8cc5fc1161fff5aacc7b6f5ee6703a8d324f6cd0c31bd1a8b10801a2da191f534b2cef2010960db26c0a7b3a80bdcec1f96b0285696b5c42dfb902b16a6dbffa60fd5fa36d1da5b93a46bfb3a634d0a97bafcfd47c73dd83b9dc14ec7255b33dff9199d3506a2338db5389c999d63580776d4e4d84333d8c2d1768ed4689e4655efe46ebca710e81da5d751eac1022025a5a394db2d43c74d1a572417f6f1967caed9ed36916f077473d1d7929cb25ca85ee0769b0fc7acd53ce36d5d281b8eb4c905a122b70edbed753c28db4a0873a2cb1f74be1df54f73cfd743acb9e4aa328eaedeb45ca25714d26ad0b389fedcfce3226d32c1ac624dd565d8a6162b1ea7edd3f275067376620339e77c6555d93abd3f2944d27da11623f43647e88005cd8ddd6fa9cdcbe0d1622e337520f75df5f3455f9a1cfff579d2fd225f57097b7296be79ec58ca42273b1af623b083fe526d7528b25abb7b9f721617ffe720541b8d7366dfd519c4c55950d16949839825a9371df7fd2d45e56162732753846040cff66bb26b6be9c9c08c517cb25c466c8bd9dbdb5b55f33c5250a2109198e8267918fce4f82f3d9cfc251f09d59dfb9f3379ba8eedb505b5456580317684cfb26a4b8e82d1d6d8a7f7600edc063c269aaf20ba3dc2b9ff8c1fcf4222a561c9146dbb17ba8c285a776f90b5b201a28373bc45e2a711e5030427e45c8ac6f4b9e959670bb07a1613e01b507734b17766a1440a8aed9b0d3a353efbaa04cb4211d1c60b0b47bc43db9a07f1d636383d0d4db2a39c04b5c9d6494ed59dea6e24d01085829948d12af4876f1f6ef1322a684e3e433ff25446a70de4aaf2e1b70eb2d22c55c47a44d3f1727304e8255", + "priv": "c4680260b24be4bc2914d5d459c3d433675f87bbff91115df1109d37fb7439725bd11ae9c4181c64d8323de0767ff237a4ddca6475cbaec564779523d955ca35ed814b25076b9cae11898c6eca01837b0d37e88aadefccec1f9bb6e34224b9ed4c64f10efd771a8df76c6e82793e7434f856b5d37127180df2d83d9245ad3f5de3220e12104aa3946592908150360e01362c481232118031e330604ba8209ba005543652923620089944022021941431c44871c4c0001c2062c886051b094981b229c23068d3968514910d98a24d9118201a468e8c345014a490422265cc80898c30420a26109a0444c12485612688082569e01004021126e0802409c340c130724b222d632029440630a2c0719b02421007720ba285c024280327259b30090c082d94044a0239291249705b801023966c1b462c89386a041786c4062ea3366023806880960d02a13021927109104ae0104849a42822a645e3a02418c900ca1029e2268a13c564443850128451d18620911065e42668233531002324c98070c204644b96304808281302080225248a347280348402c7290a849008393119c08c2009601b891009b72808384d4a48210ba0318418824b288c60046de3388902102248a0858800125a96299c846c93b43003486a61007200280e4c140652a2401821111c2326a4048acb042adc105243b8501837824c1442894448c4346691c049512212a0142600a70504c5601b434ac000228282210435616344481b2244da4432caa6258ba64401410c889804e1b625db188ee1b8805a3406120188cb1080043332cc86855886044bb69182440ce034600ac50dd00680c8166603a50d213926832869c90425d2284c20412844c0085ac86944c4814a0621c40630031171a2028549a40013c525182382cc14215ba21193440a5b282251924c82909112b2105a308e6444501b448208a06818318e4a06256038091481108882610a1549e0402593880d98468e9c1030632431e3b468d1980c411212013510d994601125918b8240d2188e53829082863183328a408690c102465908911cc270a1020200153081487184926824132c62c65020396ad9068459281083406d89108e0b08516208214a0028032621c2226e0413242213321c214208364c8c126893340a5990281c379112865060262cc9908d11462903a2244c1866a4c8682282710a41664290305b1010c400860b934d480200909484cb929010034291306a810684993080843086fbce9345af7d3fe2b562b840ff0b6c709d8b097d8a760821cd6a5c9065652386b8f7ea3181241c55a43750a2c610a9c2d7266578cee9ce788ee9f0dacf01bdbe35a90cc433ea92f79fcba7734ed5a3ccc8b86220ca283bcaa30c40c00b3ed47ef75910deeb4620a9db27a9b6a7e94569927d13d3ef68ec07a3a2dc4441d6d53c7afae417fb099ce354726f1e1edf45128bb25126599f29ebdc8e9abbaa57f14bac51d678555ff069c67ec65894065ae8ab6ff6573e7feb96567f55c3f0f96ea898424c9109cedf46a962f577549f0900fba979b842fa2879e0431b9d45c5903018eb9594f90124b54002777a18fe963ef1d76df30fed1b5b71d567001197ff397a2eec7682da4b0545a20ecb05deeb622ecf97a9d9c334f7a070f1e52c8de008e207db24bee58f2257a0407222e880f4d7ba72a2a6ebfa0fa480b3c6db702ebd07a35fbd58086d4a39f0f861bae7fc7eb632836cfd7fb8cd88cb9f68427572f3440882a7f4a7d9e5c0c312e4ab2576a73fe80ca958479cb370c13b73da750d87eaf0e01c57afc4914a2f1f27453937fcf5aa8b6d5eaa1112fe82e5dbbf210ec95273a6b602fda0832ab8f388944451a47b00e7b67616fde0a00f8c91e60df8b4fe41d5f852d1eef09aa7b5e7f0c3fc89961047bb5fc03a5d2b47606b1a101b3bdc925891cc963a41a0c6902b7c0350af6c82a130ee7dabed433082603c58417360bbf27171a48f3086d36c0ec029cebef8c1fa70aa824be6ddbd7ea6391cdbff285caf55647b72d1b739726219999f968e2494b545d8d23bfd896b5506cf8f893bd84cd8ecf766acc4ce7ceb1050def0ee8fae404f074bef71c715117b03c4e312331905d48e305de5f9d71a05d588f1dbf000ad9d160be21382bca1dcdcf7579e105ee2e6a1d744a0404b70358c39a8422d5c43a622661009f0a187a049b12230fcce7bd764541db9e889d820aed7fea9ace59d63293c6eb62ff6c0812978ab4b45efbbb5f6be84139304b0586c3afeec169402d27e3847dc0fa09f5b2c26f7fc97d85963acc86204dbd96a6bacd8c3406165442c01da97accc49dd78c102071ff47df7e1c300530651c65d60688f85c7247576e2f975850565f5f4cc42696b47777d112b5174bf82385eb9a22fe1d5ed2ef3a23fb8eaab62b21e921e1ce79b5422dbf21e51efe29723bedf0a53768097c6b031863c9e41a75eac1b8b8c9e1ecead9220dedb3d5eef913d3081ddf98b82cba5f98943740bd1b0037e6e44d61b27d51a53300e8aa5dbbe653c29b70481877c6d81ee5b9086812db3f178bb1007bb4eec5cef62e2e4a123a7baf6c9c5ff0bf5a8a666f1be1fa001cebb8292034348dd9c4cd1d72fc1b0adf20fb94daa19ff7af829d5e7111b4b2cbcb8fc235a57e6c61875949234098dbde1c5df1512982d1cf2a29205de7094bdfcf2cdf6bdf2faff4360347f6d7a2419afb3ff24be4eccf8e95912752f63301d04c93192e36cfe04ae90bd0f71e149968b9cc68e0474c71365efc1dd16e023d1b65e3b92392a1f13746d823f1662b298719627c31cfcfeda4a4a3ca8ecf3868f4399e0e732d9f929040ba7ed82d9ca8d00dfe271634e92c8b3592176fa04b8d7aed0bb5e24c6591725dbe2fc1f91e3b5be6c7947409201e585d047177786bb548f51f74c2ebda560913168062a7428addad7fb1a868b1cd66abc94e797b989e70db375729091a37eed37cfe46e56dcd5bbf0d3fbdc51d3877ef31e6771a81abba5fc65bbe533c1c83853ed696545e0ebb4df98710ad40a56b0ffe87f911d58a727bdf5d31a23627282c512ad9fdd87960c2b2e0568039f58ac5691df4656d034aa2ffd3abf4f739dd6cc06a624cb15ff475b73886fffd703010a2798605b38d8f18a156368be1ec206bd7daac27fc9f828571ebcfa142b04ec5228420d0a31e8562ee001af6e9ef2a7f585a3685bce59cefa010a7995bd6edd14e8a29d7556b149061aae464ef2db99beee91360d093b13032f2fb55694a14ac82eeb7a0e3eb53788cbe9938373a972fafdd9223f00b7ade5ec5d80860b6ec8b76e4643b44783b254805dce916a813814ff350b4408da3881d12714ece20bf344f3fe2266ed3042785092cbb4d6433c5d47c012dfc2a32fa551f9a94673a1cacbab0ae0b3c96b46a4f4ab25defc974fc9dcc0b12d98f5c9df4923b0f1f59c899d7e1e5290280ada678b0158b734a67329712a82183009300dcba9021ebb44baadc87b1180ee017128ccf21d042b45473f19a6542c5d233642904f690e00fbe5706bf2746a916a2edda363b8d14c81327799042f3c1c7252d3ebb8023d5eacbe1edae22b77cc8f8220eb5fa445" + }, + { + "seed": "9305119ec76eca4d7241ab89a182730b4256c60a3731c6bdffe705e69143f901", + "pub": "8c13f3bc3c30694acc7b56fdb9a0f23831f059d56e6d547c7e2aca9f3f95061a8452ac21768474f5da5952451b59939bd5e8c5940fee74dc96752b1f3ac342677f9c540d9587feb7b83290605273ef9fd970c84ae94dbf95dea507694e7059b8ba0c10fe73e2db5fe7c157677e96b04cc5ba72e490141f779049829f42c0cd5c3471a0fb400a4f30d5adb522119d55be115d513f229eea2a203203b0246eee70b876623b5d1a89b2e7606fe892099832e38d50cf84fcfcab9e0d14485cc8074c1937e6dff101d3f70bdf834c9677f16dbb587db5313e5e9777d86b7a6f803e9b0af2833c48e86195f914be6df28316716dad5708a2860d014ffa58c4d3ac98c5eb9de08984de7e378beddf2a687bf9ecd4903bb36665f722cb47e15b422684f29cf6d3882e885d0372634788e28197c4d66e7240fcaa76bf63796ee1a1982685bdbed44d33163da88ac25ef37d4664f89057a8df8b9df3b8fccb1b2e935578af528701ef7290c8b1a746b6fa7c4c7b4ea965fc6c19a7c66e8ecd2f24743941868f2e32adfd18776d9f8074d79accea40f418a97ab5c9b26c154c515623ea36cbb7d04e23973c86edbeac41cf808bd745a46d41bcbce34a414065afa3372ac064f3477c89865284d2688594b6a4c825c338db7725930db78cee7b877ad055ef1c09dfb2d50f0e2904c59c7575aff389ac533cf4a8cd2a0586c3eae6bea2e9c049a480cc5f85969cbb02de7db179e67d2275b98a295bd07e9dc7130c341354a46597831b37f586c6cf94a9004ecc19a4aa73d9214894f5f8d0f68b9995f3930fcb26e7fda727e589194fdf8ebdfd1076f48fcc6f709895c653be10bd09c71518262656d03b965a8c4cf2c83ad8cf49813d2a98690e0188f3d12d48e4794d8ef1ed9b89dcfed08acbebbe2c9e364fded4f8558c9414a224fe1eff9516b280f1e42fac28cce0a47a528f0cc43ffdabc78a97bec58620c576a1029cd5b63caae58590abef422c1fd33ca1912c37057ee54f6cb8ab84512ea59a5e9892d7f7737a78797a00cc16f46a53128d0b40d7cd215d0e8f810cd27253d1f8f879652e6a67cf1ed6f2d907f785249bad4e78dd537d85364b88ce95caf4fec0d1a6fa937c6dad5f6e50de3b519636b879df9a2d5758303d7d2205778d6df8f5ebe21e8449893a93244a2b1c550f1aae9a25f955b8542816719137d7dfc19c40edd75fd0cd6ec8c3a1839e7260cd3cb8cc3f85e60959805fb2ee8251b5793da4a907a8bc5b110b8c0d9cb22efbb799b5c77cc909b02ccbd07307a6ba6c3964414e8308932390dd3afed2aec841616d7fb418d863b7785d9e6b9146fb6e0c21cf5b429dd34d34396647dd82aa736850c59a8e823a09a6f5d6caa4fb2e6146e61e93a6fdd85d9f5efaab1e3e6c097672bfe8b6a0c83d757b5bc2d71a2972793d0314d3ed3d58a73deb35347d79dbe1429bf41a4de1a0657afd31457f402e29992b8c5b7bccea49d4684347d54d7e5b240ecf83051d25643af82955b556bd1713ec9e200c4c5c2ac7b89e29a1a7b4f8f9bf4510438631897e5a9e2d2ecba60da2561a9ea67147924926f43f62712b595bbb4ff0cb343a70cda5ad621ee57b5b4f2989f22446ce4fd33d37805b9a02f1e67ab7c7d62f8a47d9dd4af65abf938214a4a0a7e03cef3a97ffe6effdec3d66d1596e7cfac1d9c574f49a0a4490e71b42fc3ac9b4a844aba585bc05d54dc72f23f84f02fe2b6e09179ab2e2af9702fa5ccd9be0cba8748c84543b7e2e064ea792bea0381fedb3b53cfd6ebd4885a2f5e02f3d8f671786129075f600cf386755fa0ab8817a7ac235d22883dab2905bc9d906105c5309f99f8870", + "priv": "8c13f3bc3c30694acc7b56fdb9a0f23831f059d56e6d547c7e2aca9f3f95061af9a0dbf8dac8ce4d103f40a918ed27d4f964df9e2c2df9b00581e88a636856de6f383b9c48ed863a6b6783e0ba3f21f4934ea94d4c43984f9f4e9c2191453490eb1938c2b7600f57c84e6195286cb2e88b153b194c98c53eb0e0ce47a6a08c95a400689b142463143181944c8a382821b4645cb89154440094a60920b66921950099a4250b4301130086d8c0890ab58910040a12926ccac64d1bb18100170c11128614c87158a83018456094b871ca8008148890d9c848d386305ca02d00862464904982c26521976c93244810352114b34812960420872009406880c6445b1665821026e43691a3b424229549dbb2808006860a1388500609ca002664c0844a202d5cc6289ab668c20044141444cc126a09b42c1ba171c4486d1a16726344728bc40888c69058164111842c64c64c920420d80222c1c409130860012405a2c24c43c40114366c5b802422477022b74cc9806922366d12b9200827088c223214871040466e22b631c4b869d1406c1a83286042485c102da3b62118b02da0c231da16884c900459348801c44980068062908852960d9b483213b48d1bc55041940da4002058146e1bc750518605d036252040415ba0440a8585241744d23031133204dc989154226513428610236a0b022e4038309102121b4930a0327108c5604a8430c38665933491d09009530449d214204cc40d82c4841327500b032e18480a61362909396184a0809b82401438012129441b072214352e5c280a03126dc3923054262ac92406148088c1280598c224c9042d54a4881845710a42010024640434062393659bb241e3264c58484c9b243262048ed0a2701a803184240c4046804b106454c04008c669811212d2c40912338020196a0ab84d21071250482a529888d4c890dc082c03036903b284818624c9802091200080468e6244465948401a13491a802053b02198c48c0a4141d9945102a1048c4240038621db460442145022a64803c93022a930043344d3b80c63941059a8448326241a89881c019144242dd900064048240299219414480437640a180891202188b664490820a49080c3286c50b89101a11002b33113952d01b30119323224c221e0860c1c836553a0418a3685d240720ba44cd9b681e0462194b24c04104ca01206540249e19001c1360400370a02258ecba64d8c088121296ce382011243314c822d2300850ca43094aaa0a97b4b77cb1e8b994c285e9ef8dcde6d5fbd2b111e9deeb3468ed229ff6260558c6b725a4acd5eb86d9371787393cee4800cbcf92c73a8f9d0398d92695faa0750792d1ba7c350fbd3a67b34a7dbea1ef4da34d93c72d7d6e36a6dc541b86ff4b864deb38d50156a71b402a2c6fd648e8f7766be43ca860b99d64321aa7055ef376d1fd778d6353beb51e771ece65631e2df278382d941d74f8491f406859de34333043ea8fae13a80f0423cf8e43f1921b70e0fb567611b77eca605017c644a42762d4452bab72dbce895c6b591ccac652b97622849e544f6f623a0b7b3c83dca67e03951ef90b789da2a9e2a792f9299300167a0d581f82a4a0acffb98f5d12f501cc1f067f54f60e373510b5c237b9710122932a57011e259d8e07035820e338b6a2c7fa2a9568a3a94d23d9e4c0df05906d54ef7d7f45b3bdc0c299191098b0a45ff066eb053951b8ba02f9c7938bb9e8f2237a0247ddd277f89809ddcab5770275a9cd53341e867d5b8a4936459374d29ea066c677ae06a468bf393db5dc498d0e02efbbac992092a956917ce2061537119ee6514e4ccb76c42b75b6d42d646f45b00b940621bfb86f9653a90d5dac6a6d8a2197d6549686f0fc6dbfa29965f8186de38ced9defadeffb292a1b10d8d9f6ee8994588c8ed0f12dea432c2a5fb246d9a2b847f3cf44a1930b593ec46e71c158cfa97a0e77784ad944531d2302a21ac0ddc1d0850d05f35316eaf64fea20bad6744674b9758ded8cd13c1d15107e34abe101354ec4243c2ef6c698269aade798efb0bf39d6f6a3e3cdd9cdeedd44b152a625213acce5b5dcb03336d5c407c31744f2aaed26824219076cf8d19ba2d6a6240ae54b113244f64e812396b75ee72289d6fa82e3221a148e128c70f941b959203760f5b27a39b931e2bd63ce6cf96f24bf1deddb99f5ad23b60ce6d79e6a5148e83b7fdcfb7a048b883aa2121433dcbf72d3875cf1fb3dff091862e6e0688b1f9b8254799e8e35a35fdd991780ba7813d104937701c90707110fe91282c306d87f0064d9db7907e2d686f6916100018806c35493cc93501d748c722b06c30f685cbdcb3803925a761a677713fec964029b33dfeac14a85fb9e1ef9ea64d1c92ef901c4e2d174a1dc158148da32fc5bdfe276af6c0a09aa00f2ed7fbb7842fdbf13103285631aa0b556ba0df298058d5a980e343e31c07d92dec13fd41f3966c3e632bad6bd5614ff5c8ebfbf006c3a136732f9a7f20a5a93cca3e2211cfa8636260f56705ae5c451003d557af584cbae0d540fe6b3f1e19d332fb31cd385f77fce7c506e1964f8038cf025a86ab76715d1ee3330038d6eeff8bf50f7969da650ca3df040ce95b99c3f67940579ebe3c05a894fc8069236bb12601afe8416c37a4dfed2a192bd8783d0a42e0028e972c3a3ecd41404a9c3491cf15bcec17f64d0ecfda8effce8cf59a35426840759162d1e2496877274c9831aa1f7064ee493c13860a8402b363730096e3cc388240170f164972beffba2def4920bbad39fc3238f319b703e073addc4d5451c02b2e39d01a4ecc56802613411491904f01691d74cc5cfe6c1c9b89d4540347b800947ace8d93b5e980c28b5848b41b4c80b3adca35e5f252cec267a021560e5ec0b163f4d8d46ff20c15efc49c9eecf9de63c6d630a39c4e94a09f714041b7aa4883b0a852fd887e9445d05d657d6967379ffab5bf59d9ad50fb147342d3c969e16f0716a38e33dd507e1d2f0444d25c02cf112616737098a12cb7e102b867258e713909c8a4d895087b2bd39e525ff4fdbc6d48fc03489c295f248556561eb140f35087d815b90f2d8e791ccb12546737447138c2c62b08e34b3d99579b0b38a82683fc7c5b5d169f3a5845c3704627c4e2a7596f601204857c8a74beed96b6da9f4f0153fcc96261744be58d11afe11a449ad371f9b9f8ad19b64b215d1ddfa3f18452b6374fe7ab20b2504c9360ba9d8417b56ea0ce11ec05fa4a8d05516e4e7472f5f9da3526f7af99cb41a74036cb7f46797633f05938af0d0c2bf649b3eaef4c634211a394254890ea153c541a128601c5f124fc070386d2566891382a97f704a358469283f1e013f598129a428be0e6eb33bb6a8ca3979a8637601577a35a7cd438487936fad05a739eb9d4fc27b5fa013aa9f225936967b7a775288ac893ac08e52a4ae3ba6ace0767171c6d9d3967597a9ab00c91cecc00350931a6f729cc03398f859fea9427ba40157afc02e645ba703ff76ec91f485e04de9f91fa708c8399bc0e37167ac9c9327aa78b8f97722ffac72cb08d211963987b69c0ec86d0bc4672e90f1825b7" + }, + { + "seed": "4457dcc0944a1d2b4bcaf855446c30ab2eaa96acdbc48d068d0da044e0472dde", + "pub": "6ab15fae6c60943de527e98204d967b41cb1ca3ad5d03ab091faaa11364997a4576dcd2d69516923a280541425f385fb89167844e497e7c07d6e143e05e0a755e22b7bdbc870f662f88ddab790b9d74fe1507240d8869802d197c075fa85d32ff4f73654f47632458284279ee75a91ff87b42cf5647ad4af328d0fc121448d2a4ae4fa676d0a924f36f641296c0639e4dab85ba34075f713308347cb18eb9fe4b1a5a576d1fdd771eaa91e3d969b1efd3c84342f2c4a3e1662737fcad14dda17400ccb76a7a4b6be842fd3cc49aae973f930230ea922c329646126cc9d68b82d8686f41a96f52fb062395d99d1200c4213fa76cb499161afcb5ba7df3aaab60b163d1ff71555c551e1353170e29f19a46bd788ede62e7bac4ba26743354dd7b1d9c4244acb1cb290309fc9fb534b8007061d193ed7713194b9f3e0bee9d816850162d7bada35fd85de50dd6aab001646e6b7af288ca93594a40b2b373fb4b6b1a118ce1b19ae812b92ee8e375e034ffadafb1ccf3ddffafef254c688fa3bfee4ba67332ed4a1250f122d9f5280c57d4e9184dd71aa7de7487c68a4234b62eb473cfc0e6cca2599887b2c9685202bcada8e469123a9ab14e4ea041a2b782080ea8cfc39d2ec91e6a771590b0efaced11fd61da887cff7d777eb35162de6b88af9d507db59fdb9bf1a5bcd5c884763f3df57f1cb43176346a3ffc63d222eb0f6c967372994e8227bfabcf469ff850b7d25d99acfdf39c07a1f990cb4e76040c07ec499d84d7d69559e7581f004666f56607ae5cbfb110d3d57df65fd027b3084ab977d1c51c39133aee2f4031695cf88b0cf09e26a72aebce572df80a7ddc943be1a377402ea94707b73e4929df064641f4dfb5da81b8b9d33245e1f28e67e5407e37178c3caa2fa20b7c14757aafd721e2563e7ab8f5a67a33026c6097fdbd9b788a60bb070fca9c9dc286c5a1d4aeddb1336e501a235b828dab92f680724e84beca6183f1d781b1805c9d17ac138a1f75fdbc99f2c300714b44a57210c4c871a214a01e9d44a22ac83460f1cf003e5e7274aafc6d6af605d58793c9ed328688c1c4b23f9b6d80e9efa1ad25dc5eb53bba15c8d766de5d0da7664df70ad8b41bd9b1e1633ffe120dd21705af3e7accaf32363ec3bd5acb993478e5a3c768af4e5fc7426b2c5cc30ea98915572af5abfc43de75378409976943b4b4d5b24a26a386695cc76746afc414d9201fa44de1771a792401e3fcb8e9b83d53be1dc4850bb7e18d06acbcd64c4346cdee387b6b3986adfe80a48800109d6a490237048ffaf8f8fefa692682b0f31409719c22a3c946f320df0dc546bbb9dc30b502a556dd59969eb695608468486c822536f9f87ed03f901800750a44c788433ca10633a92f324077b1dbdadf04e24c2f69b45a4cc3e9a9e8e344580e0bb80105045b59e2742e0c630e4cdae182284cef66a09beb7e6254281028bb0a733cedbfe3fe5ff6d5a367f00b24e3dcc54c6a8fe035b470a8c6ec9a32111235d35f0253896eb8d7ace47c0bef88e66120b5355ef168937274cf6e296e1be5d9917cb26a3d2777e49212f027e72e65af160241c78041330ffb0727152e8ab68a85a6118326519bc9bf00829509b1debd69512e67cb8615113d1ad5efca6db01c417ca0d12bb1ccf5e8c5c6ca7f5e1d8510c8867bd6e1c4b390138536442163663c29e6348a61e3ecb68dd0a4c6d8d306cffb180dabab2b1ea0448514ed22090544781dc3d5633996e489ff9496531b7bdf195266cea4b1f9f015a3d01e88e33f291c95371c23c9d046aeb6deb2a6b966acfd8c821c6cb2b935d57975703d9ae1b3f987515bdd6eeba", + "priv": "6ab15fae6c60943de527e98204d967b41cb1ca3ad5d03ab091faaa11364997a4beb8dfe3471e054264d03ed3ff003f26e31899a2c34f7ea324dc66e5dec8cdaa1ec38e586878883497e0f3a3f11fba337b1cc4fa50e8a01748d13a65796718c2d511363ccc2263dfd9938cca77a49eee3cff045088fb00cbb861d2d7cf4a18d602294143048814a4408b0850044202d3902d2107124c3472d2848c84b440d2a04508324183322292488463360ac80608caa8048b086448886992a43081482ea4146e1a9608c8c290990405890245a3082609257060084410810c24a71018172a00b2040426419ba0014c96911a3470999281e38821242345213071204049a4a840c1b48ca0486c1b086e51860493906410308d4c121249942d9c10099c264219958049c8491b26854a426e0400504b320a490622648600c1b820d9184881266118b2085b10089034715140705c823064440e881230421292ca366691a24960b42d9330124340882427114ba42864862c40c490dc1401e0180e84a41000960448223008a3319308105b14849cc68188340e2403484ba46013c588191041a2c66c92408942c44990208558288914c63059b8051bc830e4326c54b48063222e022044dc244d14278eda00711a414d62c49103b62d404030db2048dc022881c6000c4665d92800dab80d21390063a805c03221020350c2a48d4c324d2101658934211a08701a032a1c496d5b08902131400a25260199105c206821b5649a164a13398ec094511a828d134305843449d3986d01a4711a2400414610242286d9108422002a824690643225819484e12224d0c684dc320d00070800824919836de4120e8a044511a62804a884c1a4208320104280301c467121180864a04d80202209b531e30886e23261014166ccb46813a52412c24913049062140ec2388463308d52283058c4904b8690c204728890240bc3418430259b96248c442ad91209c32468c096480303251346429a92849cb6241c436122a901a2b601093392431208a0b66cc2808122946c82b66411012e123584d2248cd3002e5042649c36481415495a20049028000010850917684026841bc70852328619317213178002b42c623840628604e28630a3006e01982444166ad1128e8b0269dca080c40220c3386160869019807118162403228aa1422ec188658a288580a66c00082dda126192080019a95112184e13176e844671a134251888451011469106301816804a0681a0800540833b904553355fe354f64266798d98ab950628f8c77712f6ab7b94eaf24d97e26e52f9df50a2fa17e455ef6026ba84be5fc06b8043994ba75183ca73f852b132f3ee2e70f31bd4458bb338a30a20a1783ef5947bc42ee9a00b90d1f0428fb9e7d1240b43133b6923d1f564c0f8e0c15f5950bdb2f6c4b7eb57a8ef1b3bc88757e28c5519932ee8b7130378ad9986f692179bd7b7cd68892d3af3c3fb1aec1b4c6c7fcc39e8dd77d43bf9cc6c0de875018370a593aa101818435b6b8d9affca98d29c6e31698366ffa2d87c32fd0e2453bb582caa16c053147217e0b9f3429146fbf24df8280567cbaf793fec7298c61fd97c3ab2b9dfb561640bbf84f02b65cd02a5d947a52f243ce8d245634bab43047a2e9679393f7b0b7e9b1a1bffea5bfd8b17e8406c7a01bc6599857a0d3a3741de638da9f4e140276f290b9b916a0bb29e22960495b1ede8471ed32d7c377c03845d239f576833ecea76257c654e1e997683752e59d95201991bcf428d9243842426c057041731c768e0694ac9a6c1ffbf4c717ff51686b03dbf11f66ec20a9bd5beeb1f22fc7a403fd98c9392465225a4df8cda2a755eeaf42071307535a225020f2de8b29c85d55345a1a80acdd840609eafa62ad83b98986b824aa8599350f1d34f1661bd58d17a6bdc8cd80439e6c152ff87e6e3bce01bf6bd160c7cd05bdfa505d5ac305980c9156bd88b991673e13accc520959aa8a294b9a0e2c9b85c21233fdb413f25c99a7ebc007eeb4a893743710375cf175d91ecdf917fb5c58f1ba576a3d9b889e4c33e548d46083c321a7585616dd441eeef3481c917dd0ea0686127e97d8754735b1dcc51f81b600cc8427be5c33489c852149826ad79aae2dc4b856053f22c60e41b694d8481c09c3fdf257dc79b1e959af42306025bf5f8acf63f8c0e5eca7eb321f8f03cb865c1e53b8fc315281d975589b1f3f2ead84a564a9c677717ffab2600320cea6c8aa73a7ee63d16f2e7efb07c8c7031a321592a930faf1d33faad3985b5e0a5aae3502321523dfabf33c374f06e1fe736070d292c6b2828d0871547854d4424bbbf3ff360a958f473b88f2fbf78c65c9e89905db974c1e1dbdfa7f75e6f9a9ec9317a0e17c4ef5612d45d7d0816f1177e85b1c5b39bbf3f98112d7f07e0eb95dc804b981c408c72cde1962596184bc22d70cbb748781f498a0ffc85014abe2d6b9c013e6e60434c6d53e4fb0f4534854711dd1aadcd7abe9ee341cee17da1ea16935953c63f603289593835242cfc17f471a339dff0a2cfef7746b392d5e9f0c666009a9f9114fc479e2a991b4a2376caba8a7ad362bc73baadade3548625516c469677b73a99ed14bc3d4835f875d6f82bb9d9d1e796a9c7b4597daecfb63eafb990f6a5dcc79b1a1645473bf2d8fe8f1abae8d35d506dd388b6177ea2facb41611d24ae70da8c4c9521a335a77678000b64d2e1de8372249314ef9c7eb454f4d0ca9f75cbf280df81e37e22a6d8785f44bbe9e78e0851b0d2836c03f138e173948c6d0f79f531ef353420fbc7b905cd5f64c4fde1f0a255f62a5c2ef1ca88cc24b3d45b868c3218e34400def9d57df8c4f0c78011ec924405835d35b15f64ea7cb634732e721cc5c432412bc0399d5009b70b8f38cd1d71d085c5b3877f44ea4b2100eedc629cb2bb39567663fc355ff93ad538da612a70072ff506bb02d4ef8366581d92e5b2d1a09e9b6eb89f3a4e56648992c028a8161bdae57f8c15540b68e4d65f7cf6d10bcd9751a9b27274b4c107baa00d72ae6090b6a66669322e5c99bafb91b1eace7b29dd6c2dfd161d12642c5ed1f912c08290bf39439f48edf2c2049ced6521b1f23c87e18f418f959ba245613af90facf179dbfc5b92eaf4f8bb4398b9f8b40815c5389cdec74c704aa1ce32cdd322b60edb92a420acaea1808074a4e33f5f06c390cd1fe2b9fbd2a4e42d3fb57fd76fbe032b19540b00120446eea4b3562f1535815238b397eb42d0ddd8c1155088c38b0c214fb859b9be53b8c1dc4188ed2458d7219972b369eff0045b4995f9c39b4d6adc92d4cb24d076c4c62beba68c807e226bdd07bd9a07e92a87e22da4caa25cda1f1267da53bd76fba31f2e57667a17b54d19ed7e6222b103265539462868fbb5abb952fdc8190817c1b8dbd7f13ed713df8241c2b448a176fc7e9e693960801fe8b001b9a15fefc50f171dd5ea7c09987ec89f1650c597b10c79fb394a51bc89dcec66764ca218085352c2f6d52eb9abba42143544c1afc632108f5e617158a6239f3ed5c86eefb00b13e6734f056d781705cf6194f35980819cd8edbcef44c3865ea090bb260a4c" + }, + { + "seed": "51c6293686c82ee4ca58112b1e1cafb062fbc5ee4490cd095dd60e03726a8599", + "pub": "d1c7959381c9362551792dfaf9cf15a56fbb60f6f695dd0b24a1c53bf9cf146f92fc19ae36889e62633ea219b530a43c568db7bfc4f27a77e25ff85de6c9e69256bc0ef6a3305ee1ea3bff8140306af91ca22e856d3a1fb73e52f97e78ffd83773b39bf83852f78d21b68ef91ce966d2b6f12e80cb88dc572ed0575a3c7a672ca48cc916349aee9a6a77233772a7bc466a6da7e227342ea84eb3b027caa0c1f73ecf0a91dc1b0c3cca9af355f84a1a97e0b491d7d608cc149cd7c2d91294397feb936a5156219cb9ecd97ed52d3d751ef430d5fceeab57cca2f0e3d13f55cf49a04d1abf38cd81a2cf67aef0915ff275c9ac711ba42968681b8a3256c9e1cc00b567f8951b0b4122abf6d8531aa40ec6353e25202022137eec412b8e957be9af93f8fe5889ca8c1ea043d1bd7ea9678f35ff362115a4cc43ca75a85629f698152e6c854ffb823156aecffcb4c27c992f2d4b52d865747572ea33153207b0bfa698babfbc21c1a76578ffd5fe8d53fbee3fa660c0748643898677a5e8408c1cb455e0366fe3e05db9eb88f5e09b8e6bd95c903a8560075bcff5e9f8dd470c2cf3cb10cfe98e7b2672e6d5ed699725598a597385a50f6f98bf91d9306962aaa3a2f2f1277977c5c056a7b4627e0ca20f97751dd4d4159f374d5fb6671f51bb5f871779ef88fdc339aef77099c5141255d7fcb0b4856fd0ab4f267d53c7f8ea31d6cc35abf1fceb2c3208d9a00581879e102fff9a5c103cd81caa8435c6da55c33684e202346545fcb161c144ac6eee40122c562603f28c8b931d871a0cc2691b36546310b01c33df8d7385862b58282ffbe617349a5a6279295c4a04b3a495788b0672706301f4b136fdd25b0970390229b2f8ab92e2e880347ba37f863afb02433c3995d6d050fc0fa8f4622bddde6cad3cd0eacd86da594d977bf68633cd89f5cc8315fbb1b7e89ffb5fc8b37c26b8d9e9b1c7ffad57fc87520c6308a17c316ce24162bbd4577e97187694d677145261ea62391205798f54b300916c685cc6c8121476da60501c6e04ddf236c50f52789e93b40368d0035eb1b194e03c5779775ea456dd15c103725d84e6cddaca863d93b7cd1dde733a09c7652f37f98c9f4dc30a811ee4565fbf3f7b7db9a291dcdba6d19c431e57018b9f5ef4b6b596145161b3e8f993876836b8a37d3e806fd3d3ed7e3cae95892dbc236823ae953cf3005d46974022aa382c357db4bf25be73de128e96f487ec4ec29648c803c98772756321623c94b50ce31da6e630078229400e67378a2697895e6628e6ae6e8b9dd9b04619bc14e3da63bab4a83ff4a8d1851af8f3ba132ac2e218477c29dc9b4922a2c7734271477450acace8861ad7828fa29bad43c735525c82ad67dcb480e6e42192fa5d6ab315dd4b8e2891b4fae7f087013cd6136654298c4c3f194224817045b1f7c0679071badcf13e1cccc58fcea6e819f9b6d06dc2855573b52c8dc81b8b5c03d8ea7658fdd1b913a70aef71aebd4cb416badbec6cbe989e5cb36abe6b1e373cfc7214781259e90db28e4d3659f73edaefbfbc4a440235c8d64ff40d389b2a808fb9005635124a857aba2b734396b11819a5eae996314f5715a482758161b661196508fca63f73e5dee97e2b86c07a5315d3924a040679d750ca376a3b0f2b9cfd14aa04d92266915a55e3bd68b5a70d6b2adc8a99060e7b5c741b5fa9bb50d5c50b49886502b4a195f1ff7f00a64bb8948aeba3303eb0b24c8888988653ea1012f9333dcb6544a75cb5a26fa2a089a1b6a4eff72cd17fc35aa0277572284fa6477716a0f024b43939d56fd207f1cd51c27af2e6bfed36f1686b0777ab", + "priv": "d1c7959381c9362551792dfaf9cf15a56fbb60f6f695dd0b24a1c53bf9cf146f0bc522bfb5f5f0aacf232c9b66d399671cad5eca9cc532062be58e9e1703eb365d36d806f98933d7b99bb7fb509670675ba9af34e99de4c2604bc2537c51fec97dd4afdc3a100bb507741a520ebe75d928641c4b6d067e03bdbf704597c874daa2320a88902413498212111280a6510949510c8368da3801243066e234250b144dc0980c58945120a4654a142c5a3880d04648190965114870a4a210a4b800028644234290da164e99042114114623274901c04448966c1404124b80008834429946508218284ac02da13085c436690118920c46511ba200234321ca946823017200180e48b86113436d0b122821199008b8612421680c310a8012860b8708a12205c3860dd80490a0941118a24493b64518a62dd092644c080e89c260d9145089103082366c94a06d99289109066250480e1ca580042149a2486a18991159002a08808d4a242d8a849003006cda48450ca285181664833252a3b86159362a13442d503262d02025d2804dc49244c2440289b230218380cbc045c2168522340224a049a0a0099a3869d0c6308bc46800c26801862400c04964a00dd198501c0164c8304cd402321b348499064da14608a0068e0c464449a62422150618404da49210993286da844d1427680ba029c4b28102278558920920b98d84a064098511839890a1b09122190c183251e4164e99c284523081dbc64540082191867112092a9138261c088a0b028411900100a74d63204cd032281218064bc2048bc2609212880202801cb54c09a609e1324904880589b66c14a16510b00c189665d0c8000b962163048024898822042d640069a490401145860b022593266064040144c6459cb66c80b429940020cb44658c302023c2410b342649166d121469db36649a02080a10701a8831d3808c934092e3346dd840518a442da2b285901046db84304c002e6216324a104ae408718a285293108501268453287024a1040103869a144ca0084e5908825c060c10c51110904521290859926484460560046c58c66d184440019108991204c8442513a061a2300c21206a4496515cc008d4982d021522d23440202144202006e1328c0b40861145884c4486031688d11409a4042dc382690c060202c51104222c1b2981a2b2854a908401008d0a010999086d083428800208920250c9227020216263c80191340888a4201a280658202863020ecc0625850966c7a593486d5b7062c40afe8ce872d34f0d303b072bfc4f8d678558e46a9cc95fa409063b26c46e7af5c4d86a2e2d972198c87289d2d491112bb32b5efbb135533bec89d60a519ba33994dff9789b3b0110b22a6008200cac2e3a4a2b64a23fa3a48cb4c03cc6d3c0493381ea542dfcead1256c2da541dadc9507adc6937c034ead8cbf63b2359c50d78361db1bcda99305725155def5a373310e9b88c847424dc1a58dca464f0c4a83431a90852309b7f83e46dd6e487fa1941f06bb275c9ee3c7da12e39d22b3660197179c722a7adf04b2bd926e1fa70cf9f4a5f7bd32073a9c5e446269a58da3fe5810f5bd1b9f6bc0c94e21087468ebd04486caa92c5a21a2db2180be2e6f01113a9e06e834c924b214c5b90006ae33a84ffeb991a81cb65bff1dd27cd323cb16829c671412b4c5d3dd5ff3d769ed9ed4a36f7996e06f402b1f4ea6716a22f567ec78da7ca7191a45b8ae195a4a3a4af2add658000a282a69933db8f3b488264ced3d018aac7d54f0d7641393c4dc237c30836cc983950644ae2f6440ed0a411b946d59ffe713deb44c85b6c3d4f7f2e64d94a39a39bb38af327ac270d7f19beaad0edc2ef80aac5c24b4aa5161fa462b4dd9eb13bd3d58c8a402d36dac19fbaa887c72a386d529a0868c52654fb2c2f9cc95d87ce792559390e1a4043b935185d2066e7c2aaae92e0e72019eed7cd2c3cd71e78addb4ab51a702d0894cb65b268e64670a7f93dc88d5e5753f4461bd73dc4c44b0695d6e5b8dcc1d6697f51367f02fae9379b85b9dec7c75ba83811158164367973de07457edf35da8dcfee8943e09c5225038312ae3513b55b582c7f331625a8ac70664d349a8b4749b4471e95e614d9873788b6d41603fdcd2613d9cb62807909213875e5649d494394823a3394ad37fe7aec3e984c2cced229304df24ed93e3e090c14e15efaa90f60b70a94fb4d7a6f0f43a163aea1718d10d9bd98dc3e658e17e7ee2fbd94a556388b50cf9defd8c47e13ca35befae145bf37c35c18d93e62c88e2833be02e52a7880dfe83a09f45fe6bdb6a735b87243cd45f4b02149866b8a566f3798c0cffc08f90281c4e222f6179b95c860a5483258ce1aaa09753cf04c7d8f5da99ce4648944eea39e0bd992858b3b0c048aec907289f5a435946446e8636911ee75e4d7e610a8cca05f0603329f194a437762eaad6697597a80c710ef449a4a647d628cd78dddcfddef6d6842db9e3ce74818b3438c4a1e9623d14b27e5999e1aeae33267501f2b5c941a2265a1dfa7e36d248521a7d1c99a86b2d9caeceb47a9e85302286257d1123b0a7f0f3e3ea9107b9cc4848fc155e03c3aa42809bd84a55ac394c6d076c953f42bedcf1b08dd668800d25405a81d04bf55fba609c655c82677635647edfdfbbdc427208446f29059f5e8a438c9653dd696b827604ab619a4574e7000fab119c468fa9770de8b294d1db16f50bd6b846fc55ef79fd764ceccc666becf71912ef187341682f5cd569a667973aa42489ab67bffc29af1b27733d1c4debef83001953eac16d08dce068099ac7b7a8805f9f69b7e4ca9cdf4e73630d40ce546646c2869b524bd90e30f002120f896bb6dfd3be89e22935b22e9fd70b517cda6c0ab281f265d2d33e38695fb4c386336f63f6f8f041a7b756a8bc758e3e959e7f52ad0996570eb7b152b07f37fc04ec573fd11b47ef34d55608766564aef2d5e6ef48aaac1f3ca92d2c50725a3f96cc4aa624a4469640f7f152713ddbf87eb068c10b4f56f4fff8fe58ff2b71ffaeed38886f6b03d538645ef331c2ecaf844270175bfe11db13ea8da833fed30f996b466ca53c018571db62423ffbed94329f8ddccff2e1bfe8a34d213b8569d63479fb0d78bc47d9783b4d20fbe67cadcda4397d0391d0c55db3d76f0ab5f5be01ea7e6a6d51269c90653dd3177bad7d5cca9b901fda1c39c50c8506b3fdcc83519383e9a1c31a6cfb31aac5c013d1b77f639130c04960a040d40a2b4fc817287f596823a46a9d12e666976c82e954df452d388fe860eefec92161a566de935ffeaccc02ff90b6ca68cbe58b3bef65b63e94fb157ea5fdd977045f1140d8f2d5651b64c684dc67c265523306c57e205565d3361bda5461228e201a70a050691cb0bba2161de9220b9c2ce565b08e0ff9ee3103e422c42ee4c19ea6f22e4ff8f8c05411b16c6334532fb24a22e5add3183ae8bfe802e353335854301a6c076e93bafbe75ada5a1e593e3485db3145f61e2ba8b000d4d381fbca0ffef8e0beff1eddd1f38529364b0762ccd9c851f6048af2d9af895d76a95067a4ede445acd1e6cfcf600bcfd14a" + }, + { + "seed": "96dfc5764fa6c029374e7fb68a82905b539fe8afb0b2af70b22cd824b2728288", + "pub": "521c611025e7710fc3dd4a129814bf3899b7ae91b5d7c99753463fed5c04a242df76c4fe4c20cb2f24ffe5e58e5617ef54b1fe8b7ab4d2783fb485210636d8aaa2217a4731d9f3d31a9c89976f39d2bae6a439a42abaec930268931c2afa3d3f3032387a0ec8ca28bd3de1ef91557f42170ab50e4514e329b09386debd358b1786e66b4449bb57d9c2190014050fba32b34ef5a8b95eea3c01e7c905c11ca5ef7de2052711dec8af1740f091f7a2f69e92800430ccd48c6b9341d8575f8f8b7031eaf07c1af5225715e7086afb0a57bd3b4622d87411f39d6a4c508808494d18481e7ae15713ec90766f44d21abaa3a468f96470a81b54afa9756d61d116a3412c52d3c8214e3d382be943f642537788b1e7b1a017b8d4b684cefe14777d5f136190de46e59938b412b226b3409b583c9eaaa38637269fc094f17f95907092529a1925f68c18bce125d71583203e46da1c5d342a92dc24390f28d86745fd511f518c0a48cdc05c249f38d4029f08fbde4ed2b2c02b5fe01a17eba2bed94b333665334fde45f10e9756b2964b9afc4fb97131337a6b7ca56b4791d7d616c3a6dcca62b83e0b91f8dc30896730aed01582544a0be4a185e5a768473694e500192a49ff6c32230ba5765751aa106e6105a4e03ce2a92e3d2b8927437cbe0585e859ed938ce3a9ca581702d8b5fef840bdc240e0f9d063ec22626e47ded2ba588a5c579e05e51807aad23046e9298a7be18a71c37582a931165a6394d881b6700b7f39d9c12f9bbb0fa7f1c1ac46d630ee202e161d9c6681d2bf68ea2e722aa71592558d3616b3dbf67462348e03bb8329a34ab47ab0e2d2c7d3f98f616920867fea15507f3889dbbe909200220b101ed6473bf6baf68dce4cd2f91c8705166668509226dac6630d8bd2b41c7f133097ad72a15f1498e79df7f228668682e9d5f64a12fe17a9b0f0b5b24c1960ae49d96ec1a86db26501bd75a6cb14455e62c5d9c361edb80a031480ac028b8ba1fe03648989216e068c3e29ae9d2b7db90b138a85b7b32100ca48a980f6455f8433fc7609e10e06d915d9d307719f115e0c65346aef62a9425a17fd3bbaaaedd646435536dcd55aa295de0ef57dae9b180a94722ebd2635ba66cff06f5b57e255535f687ea0cb3d5a87518287fced61d801922e2caaa76156028131703875fe80f002b2c71a76077fea41f64225c7cc65b6680b07e16257ff86c3cdf2194339bd8f92c84b9034f86793da857f7efa9197ba06264f28fac145af4baaf49c6acaecb7f1068fd9db8174727d950863352010565570512ff48461cdd6bf13a30d5dcaee0af2f5785dbcd2f1c9e741097ac614fdab47da2e67545d5a33f6bbcf6a2c87f3a48130e77a53b8748b80b3f1c1fc335f1072676310ab441cd212e752b59c48bc5f04a3cd212b6fdd0405bc48a6724b31978c829ec244908cd0fb2ff9ff12419518c276be15e9bbaac0f7ea4240998429a75c3dc9a791c38542d96a50aeb31e94bfce70d8614e3dc22bff7584472c1d57b772f26dfaf7da6aa1aa74f89643c12de08cee2aacf6b14005ba0bfb67860e78c53c6ca38d225f4846928c90ad2c2b65799eaabdd23ca19b3e30954a0dd52d7aa1810de54da118d9bae90017d85564067d15a22efe486229f38c7a0599922f8d63b0c95b7d07c8f63ad91e861dfaf0713fb2bb10aca713ae6507da47c6eb8b2242dba61cdc333070fadde288cec15363bf6db38441c50b72f04c706165f52be589054f23bee1b2d9d626dcd8689be376e0b68bf030f30e740be62d8fadfa9d1b083596bd725025e3cbb566f08e6b8bbdc28a97818d3a13d341297845ea7d0cf27bd2fb", + "priv": "521c611025e7710fc3dd4a129814bf3899b7ae91b5d7c99753463fed5c04a24246f2229bf83b6d7b8b7abf422f5f867e09ecb6f78192bd4c4be7a64cdff4861c226841bae6d97802031bbd36d091ff746cf03bc2512b813a5a233791c7fb2bda3b967a5589a1e3371001be0d694d4f11928326b5793da4249e7c71b6f92ef12d4b0686c1862504974809256413078e4a82851c3642d0822d49a44c6408468194102296450b0466082289c106005a440108284583284d82a824e120889422406306452124310b110d19b088c4962462126c213412a410719c3012181128d1b208e3b42804096402478d6240045c347081088c8c162d840065922211e41860dc164694b870da340802c584e4b800840084d1840d919670dcb86554c289dc2209221062e4489102220d21162a44060c1932328ca4444c184254386819448258b8495a304249146ac4244ae0b280c8b88122156eda086111012200b97104a130499870a2282010237213988401264581b60454b805a1466c5c801044324d202731e4a42ce1324922046c90a06da20029a3c02803346ca404300498841cb3451cb5080103644b228e92160d101789a2466ccc0864001191e4864111256408854889088c52c841a29264c9403063c608d490059102658c246503432dd9c22803a844a4064618a281022548642882dc064e63240d08c68c61980941266e1a222e0927449b322c81a0604c964c1bb20ca092250b340540c20dc14872e10424a30440da10624bc08dd1c645d8944812076a6212090013680b866412a63109c63014476810c51148b0105c9825c4869062462a4ca62524c941594684a13691c89284d0a40c54c4689020251a472cc918824aa8914416704aa63188c22d0c4031602444a312608416250ca764dbb40923921163348454388c83864d5bc604081064180461091912e09065012380408200d924310903525b326eca862520258e09220c91460c01b32921487204b92993c610104091d8867118842da290904022845a146dd414124cb641991220c3120902900060b8418bc484a24411da128ca2b4051193855aa411c11802e3884880c849018270cc148d24b824c900016132814c881119332c01358e09b12d12012d91285209a70c4908894c362d5814028a82401a20689a24914422229aa64da4a62d4948860ab001e4065210230cda02702245419b000adca2080a04058a140aa0b2700c441199b2684ba42c984685cc94008b988593164915e62de3080492f8955f1f4b42d6067199b111ed13e92d45ed748c83d892abbb3d4cf047a00d8b29de503ed6f050af8c2954a3033b27cc2ca58ea7704fcaf6ea0fe0eeba018473353fea855e27d111ef46221f05703118d281f9049b3b701bd85bd6f942ef4c5793f89476045c229454a4fd14eb444fd360342315e3f5fcbeea55b5e16d0eb8d753e3bcf6b4b0f99e09ed6382f9dfa6a58476fa359a41fd1ab6a397adc0cf99192546ca51ea105964e6b9080b94861964aa6d8151050fc413edd025af12e5b977b968e21fdd2f2ef79f2d7af1157e1d015d51250ca6f3291a80aaa2d063e29a4e989b3eb4ae7354e3bad6ed04140604e9c85dff4144e7717e23c871f907c38bc012207c6bce30832798783fb076c90a7dfb05d2920a88ad2c4558a2badad8ec21c870a7437b2caf26608b48080ac5f20d1829c0e5486907965a2c433a788fa4d774dde972f3694d6e465d020155b92781034e511176d3b5e7b971b11dfb4c1bb5717fe723f9f555031e52b21f748fd141fcde6aa394ca5abf6677040de951e35bfb729e07034eece499cc41126343579287cb2fb590da627e2f1f6ac180962fa917f61f79477a8fa83768fbb2b6d68e12ba513174de189eb88975fb0be4098a42bf9f542220da49c875c50b9a13f5d26613154b85103d29e397f3cbf61820693b89c46feb57171d83ebebcbb8ac400422ff77c3b2a4b58908a374a2c44026ce6fe277efafb3f3052d6476c5093dc4c7670d7d835ce09a173af0ed3701c4b2f7a6136898bb9ab6987a0e05a8e46250693082f6acdf54759dc99c856d39aabb0a2196170419c858380e97c50d52f69425edd670944a7b1e5fc186b8c102cb768af20c95dc166a665d10839478ceefcc0d6d008cf49a9c6892482b6691b9420ebfd5de8cc38104940aead3380e23b330d86265047290921a36a7e73b78b13cdf5539b8b49f6a3f06f77af9be1aa96d76542580ef8ede5f44371247caba95d8c2c1bc3588b08b93461d1c627b7723e402e8b9affc616e1610b66a1641782ef95a4e0b969dad6a94d7a7d2df9a1c971c4f6b9308065d5c8cf56857574e4858fa8c0269bf26647ee404172aca0aa8595a5f845a5b96342bf86fa7f564641d2286082cd40ccfc46eefe3c311214639f61dc941d0940d78200b24c6580ceb499f1725d1d6fdbd66d78cfbc8ca8bb051c953d3d053b25ae6e4faf7ffb3f2f6d0f5a7fb72e3adfce347d43c673bcabff21c8a28854575462946a31ecb7f96397e3de8c189f85a19341f0eba6c98d4984f645e5a5acf125c3f8e5ffbff9826364b3afab5f6dd0ace76ca78f4697c91b88dd663f9b23a9074d346a07af0dfee15dc898bd9c79fc41924ca68d3714dcfc825a2598f8be97fb7d9ddf96b8ca10628cf8c7c3b27b01af676eee6f6afa3747f91bcbb3f56ffaa1206722370f464e99c00003012dc53583e3ad661d309a7a4ab11b2e994caf11412e10a7da775bd28bd0c94f14f2de7881cd5f56f1f62a9e0bff702d5eeb9a0dd63325a3817477846cadc06cd01451be5ff50caaf1d185a4e12d80e63d1a0a9abf80b3626b59eb3b89748acc942430b5a79e8b5defa6f4ba131d037711889c7957ff3e60d94a2633c3a357a736eba4103e78eae3b2139bf3ea35d8ff2c71e030121d57bc892df4113b32408d0f71cac300f12bde481174e5403f0487c3d2fcf5f2d74fcd1e9f938269a11cd5dc97f5d519e3e65d6cffb92500fa9a58367f6361a7899d04b878b29b248477eaa839b6d689017777b8ea89004f0b422ccbdde25da7be1f9dd9026e3872005811398aa0f7260c64fd30b9335d19eb58c85358772b49bd491821779efd768cf844f9b374519ef6ea9f9c4ec56b1cc7b696a9e7ffcc1385ed3fcff85c7a668f8598ef78af3caf04d889799a4e8816d5a3a6fae659d6f8e71b0a4e55a93d9eb4e6033d7568a00f78769dff3082eabc643917f1388d8001f615f2451fa52dc57f39d357787ad0963e81df77497693ec8959afc8a18dafb02c0c0fbdb8ccc8520cdb28d45b57bbd0e969b730219db5ea3838f4660eeb08a951d7bbd7520b26f2d3cf5ed050fe75eeb318efef4ec42b489363fe2ef68bb0596b551c4e2eed841a1a32b4e0e681ac92d5394d92e32992138557544308d427cffb81737d03db10b44c81c73b091d1ec827e14d156e7a7f75ad1c505025ffcbbe63ba6049ab190d7555754ef478246ed64c13b8348accca30c988ef0919a5a5213695ed0f9315074e5ac0e13fdfe2ef37d94039ae0563d1ee6531c44dc4d7a34584439ec976556f8ed9597e1c308fe3eebe8fc00b901c70884edb2d55dc75b86114a4bd4b92ed0af" + }, + { + "seed": "0c5ed6fcd0195c183df1c0c79b0df4a437a12e596b8fe77d5f22981a94f91309", + "pub": "86d3642ade7c1e83f33eb83eda74664396cf666a969982352f091e2d16116dbb44a33d32badd201d6191ac57da8ab5483f8ee5cec7018b5dce6ed3f1050eae22195294eec5f803c8c77da0affc6bb9ffb9e80bc613b2db7d095ad037a30f6eda572f44c5d8083de990373828cf5f130a515024e2c38960d03a109015c6a65153058ca3b88cfadfe446d72c5be5fcd393fbe7a51ad2f94ffb13b0031f960f8c0ebff66048e08db1cd25d7fd4cb3babcd9f52040c1d87a8a54b254e53ef0042a352e4d97b879bb60f07a99e50734655e5a208e2b5b17427b0610449fc1929242abeb54bce504f492aaf3fa857a3a8a0af4182bdbec330107704064b3eecd20e3ac5acc0d0cb687d18705d48d9fba7027e80675848c30764b3f0a0342eea8f17b091294f1357b3c5b60ac8626422e87927b4f50998924aca879c11473e614ba9f8aee8443b512a96453b59294b18d9f4f0020bd6e7e232219f50171a07e05624b87cc7074aae9f8aa55fbac882c18eda8c5649523aa08d2e6558a33132ca99a71b285940c01b15819ea72d4a67942d4d9e251d4c4d93e742ed3a674dafe95c5e06ef493a46c8728d5b6e32d52135053b769dbf7eb9593aa1e8fc25cc1efc67daa11bf2124fae65f986894a1e583077a30dfef9f562a9e56bd32c908722e7c838ad6217f3e7dc5bfb7a20984b98349394a42d0bed5d4a84c62eef53dd782a78d16871a79456d89fbcb885eae4975306ce2d0e10891989001cb0f06051f9601ad2ffe4b3d9db4c5c7d503ca1a42215b2c2d87b85000e78b6a8b03291dcb48e237960a9383dfaa6d1f2cc6cbf0370e13f7af53d5bf5aa069f433c6ef3b42e5c953083bea10248932104f08e30ab3895fae1167fd294401855786206f6e479fe1ed841e6f57ba04d5d56a1af1d20dbe777bc7312dd2aad0a9fa4cd55122e97b98e8035e0747b143f6b8a388ddb6d42b84ef1c5c0ed860cfddec0a5ec3a44cb8d649225afb4a1eb1b0fc9ceb13a202a8425ae238077c07f98f4ddf09252c8e9742781697b1204c9c2040ec005c0118251df7b6b9c172103f8fb5caf1f40f809cc16bbc91ba257aed35374c7f34c4847313a0e81d89afe45f60a3c2c128580f47908f69986f13fed38ec91b4fceab6f0e5f3811177cd7e752851c532a6c9ad94c90ccf9f086beb3a3ef841b3766cf7e34dc584d07fe54a57d6de9dd8c76d0975790acd7bb8912c5cafb020b59f3f1892300fe30f141fe03226609a1c267bd22091f94e1bc3c41d1e8567ab7972a372f6ada696cd305b5ac0e71f4aa74cef1ef3ec5b074f7ca2b9a94b8af0c7f0227014d419017a245ac305209a4eaebb4db98803c3e208a3d40e34e12d3875842b2e6eefb64067d4cf9b59464c295153b8813029a269c9223984e7cebf8b6d243ec525a3ad1583d0508234ab72d737e7bb881f380cf76b55149966b6d600d03b09ef5bae793c65af6ca1cdcebf539f7e1db466ffe7b2de4d0e79f924155d2d5fa50dd3dfdba7e289efaaaf221a170c3b43547bc40d05a02ff77742c7f7d157db6cf8054d4ef1fa4c565eeebf03c0e79791e680e7411389e0c235b7d4214b450bb00b41409bdd35b3850ebc317786e3aec137e5aff9e522ab46231a5db108921248a4e56159d1e64a722d439b10563933dbee5d50c218702967f5b8eba27f8f63e4e97f2b0d3c30479f128092412701348dd19d44973bd58d5fcb23844e871ac21c1dfa19d30153b5f20d0224dd8f529dae7832d41db18e2138f8967c9fbe4f3f37cacbdc79b727f2cad15b38db2a03a96ba18314f0e2148aa7ca7d2524d546274cd64ae02add152265af3484c0236e381367da7b56d5147", + "priv": "86d3642ade7c1e83f33eb83eda74664396cf666a969982352f091e2d16116dbbd0e1eb7c7469ef747610eebe57b0d5629564746531db34ed75fdf1ee4fc4ec3345b51a73ffed20a80dede9fee6aeb601dc87aff835a3e4a0a50d604c5cce3783599d32e28839ed1cfbf959850933abfbec7d87710fb29c3685370a0e9db8e2741ba25198960954b06c99466cc2b02c8130200242112321060914621c9071118271219530d08644881401e4b631d0162c24300d633041cc4664da1290d0248859362e8912101b39211bc04c9ab46400c781db2221ca064a19b4618cc86449402a43a86440009209012292c40c138501184160c2382cd2a4711a3446cb000a81c84820c845da16115ca08d201310a036326036069bc06d19014cd332280c274dc8c40004c06843b849a2346002b74993306a98488024c84c144532e206012303684a944d8a166519398594006e493232e336251bb924d9340063104a9134220b1684214331044561830606a1b46440224dc0900519249219b30542160e63440ed0b8080230428ac8885802410b240a18888d9b822d51047024c83122189061086ce4488802c36013192619416913c82819a00018a70d08201151386194108c1cb165224931044444cba60994222a4bb484a142401aa501cba83124067119a7495c048508256653c261583850e3b06462302e198624e0964922938404060919c040630000a39284c0b0705ac2444a8060982024dca07144262a09440ae3b6400ca2211a492aa48865d4424c943246c9a2290c18129a442cc2c81012c481a3240c1a166a23904c24348ec4146d908629891469d1920508274a5bc42c9b047008b78063326a4412016044811994311ba88503452a24494851386c1c200c0a364dd8b0702089896388644428129b82300041068c282688044843b67023178ca408481c802cca206d9484841028240c414e0208242238321b184ce2c28992a44918170e60a86092c04c239751dbb4215b18850c3400810604d4804020074202922918995113908d52b22dc188449840842049221a959108a984caa231dba071618071009825d20088c402059136725208411208285c102ad0802da22022cb068ec016310c44252319725c202dcc40698a164103462e20262e8026821395051a2672e2386e132961d1c46490126458202261b68c24a491594229529200c8308250968401916911330963280da1a608531832d2c00d004200091320244266620246d9482ec9d3007ecae3a74154f6a5a09e4b70174d911539ce165e48d92bcf550a0ff49f770b6deed1b6c0e6e1f2c6561d5c99f26875b6391b7d23222412e3ab38e7408b6f244692ef9123dc672c1eeea18a608ef7d6fba47a9ba7311e6cc2393efa3c3aa2b767641303ecba436ed9cc3479375208444809793080e087ce0cf37a09241f74488adc0f5dbfe7e01c9ee6e2f6f2a48b8b4ab21b453be096e073f8e1521f581dbf1d5a5970152d4cb133bcfe40352b6d9d7bd6bb7af125015575ec185d2e353ae80c10d48da46ac3396d71fb2ab97b5a39bef4d1b620554f99dc5619acd431898d2a996e07a57ffa2b2cf5b111e12ad5981e19939e7a54d5f305276fcb43c6c66f4c75c71bddb5157538ff6e2b7c4b30321ffe8d002f619eb5087e1403e55f8233b293f8190695fe145a39013635664de69f8a26ee790e58f9c8181b69783777d4a3181c7fc8eecacd92e1367dfd36827bcd97df821cbbb3287db1fa370fde6b74f207293054e3a75c03871e344327277c8b39b3198daf3aa993b61368725c704115d455a66a66134a59ab93bc3682b3e3d8645e0eaeeb91208e025c456c9589e147ff9480f451af5b1d1970d2ad06d37029dc379fe694c75910d78cfbe044aac3cb3b71c9186c643a7f3af596fb6acc999268756e85a63c3f0cdcc9c830a7814b1471fe1759ca26f38800468ba6acc27b1fc6c1c4dbf676f48b34718a3b6fa02a637d10bbd5be4d45c2a39cc92a72f535f50bad84b6fe5e95261b80998e39d0b42d7d920ffbdfd837164b703b018b20f12f60f86ec7681b15be77c1e25de0ce1e0dd3395e02631e8db3497f1f2a1061580a634a76ec03b43f5f9821ca3179f74eaef6ceed4802d900be5eb8ccf1008b50693cbd33043085825112aa32ddfe4c8d21fa4c6ed80ff2c2b20966a14e475a661dbfa583221d77133dfe7ad2e6e872d0f0fb2d3ab2e3e06d16d7548af94c5f1b976142d8670218baf21b2fd08eeb58783cabb9b09e5bd96cda814e22051b37b1874e0a621baf3eb87bd8c178757abf4ae2f2a7af5abd6f7ba8365426288c4ad6d0f84e8a4e9abfc8217baaa0f2f40001cb5a68a1cc9d9b2d28ea097c92fea8bb8a81947f3948c141b3c0a638a80aa8030eaf9ebb0bf10f52eea5a06498e4f630624d8a5e42682c48d6cef411ebd32ff05afef7c2d51929b05d8cabac1a876dad4c6101530d608a7bad029b83534d322ca8abefeda00ee0baa8fabc403bd4a241b60a325b15d2d607c9694a9e72f726ebe0738bd4f457153b6835da5dc1755427cc6bf4e46689e78a69218d711167935914a94319f6cb1f98a5bc6849bc6d255684261f9b987891508745b8d3494845d98bfdf2025f6fde2a0e268a3c7792d36ecc53e42c1a358a8fd9b95b2fdf14ef48a5deadf6256f2341f315b9eeae46df7f6bcaa97d0700fd673ab7e05fdf1320bd8a6171c319dbc46cb40084c706ce184a9ca07390aa0cffb5a0add0209506ceb6029eef1562f55b97f77ddad0aeaf179f77e07d5643ed64e0bc3641bc51cdf09b4de63d366759c2451537bbbcb5a718946a8828955fb280788d27cbe7c168aaddec5881904550666288ce2a919c54c54cbd8da95b09a9e15030966eeecf8c94674156403fdc974c924bfa0a3f135de8a9c5157d9c43ab089dc36e77680d04433ce9b2767f7268bc0a6fd3ceaa6d3676260f45239aec9c65d86711c23e03ca86c661401e23d9027dad571a52dff1b669e97d3125326d16684e855847dd55f0393070cdd842d34e28305596163068c7b3cc709947b89392a07494a8b944ceb6911b04a7bcb5f226ffba4ef4beeef4dac3ccc95edb3b3ef688cbbd948e61f091d21697990a86dde51ce6ef2142822508f778f3b43179e02decff25995ac8ed5e2b134504d5606e6f3e67356eff26eece69b90ec332d27bb8ee29ee0c4aecb711560cbc8cfbb0ccdfbdaaacb938cdd28eab3f4e826d71ba81abce1549da60c1a97bf74893a2c058221560512af040bb906122ca86e39971ee940ed66f65d79ad816d71ecc28b3a0c12d876cd0f907d8a4133ac33fe63149de322cd5d47ddeb187507ff647795e5f59a085ebed655e5867ec3d8cecea694302b3ff0f50bf1080d3f3590553d25783ab92ccb0807d53d98f293e359cfc73edd37c1c448f5d9043a72dce2588d4542c5f6caaee21fa4cb5f798d9a4bc7df12cdd5d03b58c0641b0be07b426dcabd03770340820cd77e0bdd281279a860e878842482ee299169de90f7a6319d63d224c74c7b01030aed8de9c7539431ee2b01ad940d340de959a3b9596c7b00a4be5914c91166d56e025e08b9dfcaad5311cafd86d3739f71a5cb0e8" + }, + { + "seed": "fd11776286ddcd876fb30913b6b75f1473744590c584d9df63ebc2a2af3e9dc1", + "pub": "bd642a283645774dc3c46ca748a73256871347b6e8da3cecaddce63c4274823dd6f388a9e085b877048151171b078e5b3cb5a4e82f6fac16b1e161441bc07dd747b5b674dad2d556f2a40bab693b686238bca837c132b14a80468b769189e38fc953ade9870c276f613d1c09fd1e65cbadcd65a56eb6e5a2913686270ba1f4f356e4b865fd430a996e0543dd0558b71af3581fed521802a602a639505616918285bbf079d98f7cbad6e0f84ec979dfa359ec3f30e47fde4d0b18243a2f8c1b45814eb3e98a6630769a646c7c17d51963b3a7f1efd0b940a778f8aff595ca71a87ff2a5a8ca9a097f16d6c66eaf3a3a21b7ba011f45cb993048c5c6fc32c2e3ca5e4dc7c0204f932aa0f01eebc002f2ae56e7cb6a6c2b113927df0e7394cca0890774f8973abf924643cd85e494087287e767da9894b4daafd8013cda66f198743a4e89c09d461f93c33bc28a6157edb87584bd0bc953f65685e02e4e7d72521c5096ac729f7990025db925bb549f4f42454804fa6c0c558c737b829d99ebb44c3e3dc782d11d601af682ff1ba08dc962108f259303f762501f01daf54dc15fbfb5706f27bb6540906afc4fd6d5a0634ceeb347ab4f0cdbb06f55cba678e3aa810d67245f67b14f9c7fbad9fa9f817a955af151e3794f125c994cf7bcc01e980b9cfb0f130ed1bb4a588cea66768fd050f21d0ccca4a903f1fc01d040b1782afb3b6d948fe02282a5c1b8487a4f3edf4a5cc6b96abc44777d0dedcc018b76ffddddaea2fd414fd3ecb51e6782858f4ebc4e3b508f823cb1f262f4135bd19a7df03a18cc162b3574cfe21f549155135205ac7532933f092348858ac1ac018f10058f28b784feca816d4bcb3deb721e58ecbccd2274f9fd575d89995eda6c0690b08bdbe81263aec448c5485ee856acb76993cbaba2bc3b6d56f01a9c136e3ca87a7b795e8b24a44e049c2975baf73bf5e379c6acee2198119f803c3f9bde0f7877ba922049e22cb16299142896b23e5ab45c32d496e2c97dc3f500dc529362f3eab9139f7421359285f4d9711b53c248d8ae50d036fc1efa150615eab78521adb46ef70fdbce1485960987c616aa542baf3ec54eb23996910c784fefb41fa389a2410e5ab1034dcd1265d2f116bb2bdf61dc229510962b1ae3b52c045aa894a3756d22040ec9d1a989c6c110c75cf26dd369541963b2799436ed412f636a57c2a1b65ea77b0e8314b3c9a6268495d2899ee62caacaf16af1bfbfaa66487bed0dec53c1b9e91ee0f6d9cc7562960a4a37b8266c4854164f708d11bad0a5fa1443321d7d52e38fad8b42b90fa70004e5a493499515fa9c10d66a74c5eebd7931fb1122be6d07902ced23674fcf8cc80babdf1cd2e26d0911e81dc74dad426cda179dad8971f6b9e1b4017a227b093332a3849668ff1c26c9582306450a6fb078b03a1ef7efc70b31bc063c7b410c8199a37134c9f7b764abe62dacc6cbe4ccf7defa3aa23ff38e79bd34bd99506cfccaf4cf4b3f3e6a1cd453db9255ddab516049145ce1cac8ffc690adc8f339d1794da06b1c35b98bf13eb09a028bc288c5238107afd73aae60b9d4de26cce4ff961033bcbb278072f20222e386210fd50574c8c85b2b13129e88200095bddb623da86cffc1636bd89f39167af3b1fa5977c815c7d9834ba804aaab5bbac75c41a79df8182dc49392af1dc8a2667c395ef21561c601fdbb7ad2d5009bf203d7394789256e6ddea7890e281c09375024d4853a8a092470736b2f481cc73e8ddff0d1d8fd9c168008444bd5ae28cc651d40be735b506a7e201bb7d2216d15c178de1bb55c5168df2f7ba9da7fd790a3be536ef5a854", + "priv": "bd642a283645774dc3c46ca748a73256871347b6e8da3cecaddce63c4274823d2cdf4f5af97a1c4faab2e3e85b6d6fe1d8d2c5fb3daac92fdcf67c0660405f559c53866cba0c5a02dcac42d2b0dcef85c60721341d6a0b0a3a618413d2c5b068a5271cf72acc5dee6ba57b40f54bfb521861b1e599953ea3ea8f3692e2dd4d311211910bc38590220cd3486c1201501c3000a048649ca86d10234411296edc20021a39081b2246d0162502c92453261158268d1c10454a104943282682a62992388a64124521c149e1906922084c0324518b904901a54191062014956114264449442a54048e233469e2b24153008e80367121482a04942d5a022010196a4394259b9450428825e30804e402801b396298044d10a050c9a88ca2a44c9932261b486418389213052e2485604a248a00272059b62003366589c86d11b161430411a3a86d02374123207221404452446a63c6411c188d23c42c5aa4648c202a1b392582c2258c86210187401b0805dcc649033352c0088200425098c40514c5301a2711649811094721d406501a9648c9340608469102a10d144970004751d2286cd1862552482aa3207120824914454e03080903818d93146c24089118b4010ab7401886099402881303909812410cc00ce2a60d22307299c02888300c9b208c9ac62191c6889340094390695b2282203164509831a1800c1c294992442ac4146d0346922331624cb40d8bc889618448cb802d243750130465d4382603020691284dc4442a14062ed38029924271e29889209780d3a028ccc001191762a2c45144068ed3848c019411a4024812a66888046544c421101548d0b24148486664022801358ce1300221496d50922cc8302ca0842952048e134471a4160d4b842894b425d926298a4222411002d9180e4ab661444002182420a4c0040c3271e040611990899aa62c03a24993044122156054424688868489842513326a24a291c0468221328094348ce10262d12404e22664109140db424e201661c41620c9a0710c4100d4a041431404c3226d92b08420928d20b73052464222052e4c046918161260462402c650a1c484c34660500689129221111624e4262881349189006189920d42020c9c886c40c44823386e94426edca44910472614859119b1418036051ac1095494899c001280a88558b86c23b661611005e0344c11a401c3964d9a042023b8705b128a91227023214861c46919a744dbc46cd1146dd24888d9a0258cb48868fd61b8393beae887f8bf8a08331e296d43fc0c7af5cd3e6029909866421471eb66618a7aee0ef77b928b1ceebbfe53dac8edf7c9c675b5fa70eba1f581eb0c018d7b47df541e8a5d5fcc261650b18296bc4ca75852bd17566be6b20236b427ff0fc7e092c5b9e2120c7da0a7a2f040c10b77ed3676efe339fc46c199ae4989dc629a4ea8aa20d36c0601663ba57c062a54302375686e1189cc5edca38aa4a71e9de23e8a1440e54028e73528fbe4890dd11a459fa9ecc1a9d3ecb06546bb29a6bb124e4661db84077eaad73ae80ab4259070221967f71f46a89e81e94b8944b4ab86775b9f66767512272fc5b8a6f16a89aa8782f9ff68793883ff97114c447dbb649860a3b4025edc2d9409408c35c8101247269b83e0506f77c65647b88a0dda89e1d069cda5148a050d13f0fc6e4016ce89fdd30b7aae9512e4aecb1c74f6ee50daaabc827d78a1bbb85f9491f75ca0f16822cdfe543e084b6263dd7c918bd51f006410a5814b7e938873d2d40bfc508914ccb44c8890c316010f3ddd50ec07b3c59c39a000174856f524c62aa2e9929ec2241cf2cb1c68be9f2645c75150e3a1415d0806742e2b4d36da5569c0e81146d2b3033049591b63f0263acfd97186cfd022361dd43e5854701832867eeb55656a716e3f6c559f04b43f2d759d4841d27fa6a39f90877175c90b006e2c0124d762bc253df05c6ad7707ee276b20f68b1cbd4d7b6e51c7fe7fefe44253c2d2fce25a614588ebe6277e3ea0182b03466b8d2c998f458a2c3bcc55e3b71fac76416e4990d24bb1d13b6853aab2204e9eb8ccf5c54c534c1a84c9474480c959ec5f91169072841c0fd6d5ec6d87b2011a5c73e58f18c462ce585c52c0dcbbe071145132cae1199205f65efcc0e2f163d966e38d0a98a6fc872bbd527fcedee8b661191a5304b2f56e0c1066e07715b2825c58057887a73b6d23af031747160ef6c73178bf46a50dbdd80fa3a226052e6ea7db19868eb4289c11fea83bd15bd511bce5782082341f01b5599644878d621f52a02edb9ddb52f8a1dc5b151ec151365d94e7a8e35e0079e7d3dc9d44755cf036abdbe17b8e0cc42a5273a8ed8841b573e1da802361887d647eb2dfa5256936b4004734088a586be1ad1c07dedf4c35f05b922a26dc71f3b3ca40ddb39f0d16ee51f5a2af50de60d1dc2014e3d673397482180ccb83f39044d37f064f63de80719c6f2ed235a35cb79f5e5a7c8a31ab4d6ee867d7451eb514891f77988308fd269e816229e3f812e02fb2bdf717d22fc7046defa8d4da8a95d37c8d077e82b2dddef9ef371bca1569839d5d7315c9121580d3ce67e6591ebae8bf2e4783e71673f1d558f0cec4765e354299ec09e77eaa9364b213e4c4eabb84d070f801e3691f4ee76c18a4ca69422aaaa8234fbacd09749e9ed55c97d89ceddcb86171bc8b2fa2618b40bde9766d3688bd8dc7fb958c24b0117206fb689c391dfa75f2e1d7039b09cd815064485faac8bbbbe3c52df12743a9758b5f721d3d4a811dbd2a7c3bda42a9fdf02fc440489519f2bb39a4ff36f92f229d2cc609d2d2bdf5a39489a71a5d06206db564f515fc0dfd989307b4976ea972e9180e64ae3942d16ea63ff9b5f4aea48b7d29eb78fd5062517c7390e385ab19fef65da3ef887facda423e6ac26936ab62e5df0cbe2d406f816cd87b032566b7cc186ec98e434337b057913266a792a4276d9cf2ab0f25ac88468b9738d239d9a495a4983a7cba223528f07d0d00c23f8954ecd9fb4f4b07597124b84301505b8d5773bd23f0a1bcbd2af7b6406a69c2f9e2916ca58226c6ad909fc8427b3b446a883b50f9ce59f7ef45b0ae24266dc13f13c51b1e1ebfb62878a508e64eccd4e1bd8715842e97b2eecf8e89e352cb52bfcd4ebde4caf54d406c850b23f8768723f003011e10d93173839e4f0ca58d2fcbf648c5b8b3d39d443f87f13ab4b98e8952a8ba66de70d49442a7b88f47b5bbedc357e9cda1f702fcda75a546989dffa2656ef061c9da7000241044b97497475a538e9b3511a61b6f18fe46455615845090a1e899a66bd86c50c7a19c136a21af39bb91cc46458a1239478324b7d713d9508ab902f1fe8d5fde20aa91371351c44a6d971da2a9d8c665a2b0b637f2997167788cf2bb5f15fae794194881becbdfa37e302b0da2dc42753b6645717a98f95fa6bfb61c3c32c2dacc26b18bf08ecb9a04aeed892bcf186b34f4b5004562ef91c8492095ded5b4627605414b6f74b00c22966de5fc21d003ba3519d0df0e2812471126135c08d80606cdd8ac249a8fe034cf065962714eeb59e455d12993945e6d6f1ae257fbf5a" + }, + { + "seed": "f49409a67dec616f636ad26b725ca897898d2ccb583d00ebf5bc9367028da751", + "pub": "9f79626b93b2f0a7e8f56617a00e6d22315294667dde4942e77bbb512362359d406e5743909bf2d103191e25de7730950eb2a18bee5aec97c406f4caccf0dc35c7863d9a4385044a4709587b6c0a552d7af40fca36aebba036921bc6485369a4668a21eb22cdcb540988738f50ce11e7b56b865cbd9f53890f56215c07aac2a48f7aa5399debd331108f1138b6e80e18fa802bc7a8c7f433f964ae1510aa9529a3b2f170adeb5a6917264a8cf77ce5ae6bea799afd21bcd73a957c190cac924fdbbcc9c68844df671cce8761170c148f22eee9828dc45e25f9aa08bd0a6d60a32f2bc0283674f8ce37a62d8c90f55d4436096c645e38fd1ab833c5586c39c5ad191318389b54d3828be1437a1a4f12665f563f6ad5a41389011ca574878a42c9d181db26814ad441af8146a3b9e8e5f78fb38c1c3bb122f0bbdf80466355be08070b1a60661c711e9042299055d0747a6da483088adb9262a3e93d7834bc277c4816a966724ce1ea3a5cae2bd54726bb1c231def8478e02fcb35ee572dcef1f5cd921e5fcf142d5fbf3ffa98d1770c0edf328ad6066b3884098bd3258a1e03676071279db1d01e1debdb0617b6f07a6e14858fa1c7790a66ea721a365c30aeb8fda3960f8a8e2d52c56a5b0c9b73f9177a3a553cc631dd35cbed7bc7c91cf317426a20f3fb01a9f4fd1557d2e11e02b964857d90d434b664706905cf3c9576749a313dbcd2d5a25ebe2ca752a30179b5b9163f9de7cc66accfc58e42b51830dd72e0e04b8f8ed8fdbe2d8e0c930d9b17cc27e9b58136bd847ff708d148ffdacbd84c4a7c31b4714cf196c38bc1d4e6c5e4e6512d76d14b166d85a2df7e741cc581923c1977dd95fb1dfad0b0226e3d7b85e124d9b92d414b1425235a861403b70e0d007a82bc40fc50700c18e9b0f30c4ffda85282b86eb476bbc1312349006e2c916de486800ba5adca0a3a550f07cf29c4f38e9f8b2998f56a2578648e167dd37351852c067bfd7924f713712c6107ca39bc7d278242e4708456510f8487a3517aad131cc9bec0472fce741f21a7d46f011b3295d304c464af294d580baf2447b3c47157cc44b7ff6c3f2fcc4781fc0c23eb2d0437b541efe4af9ce8f51598914120dcf4a4d9b38bf0002a862c476c84ea01c973ee8307f95c3d902d025520c08499ef9c337a4d4406bdd7d5a7e2b0d489ef307205a271e6312b5049fba2400af79be6bbbf0a87893518d8c4f479a1b8dad5e1a5653f61579ba1f535a0e3aac54df1aa0c62d82f9f243080f3b8b43763c0909b5a9c33c313fdd18561d7476027267127d675fde37efc3ab88b36d4ef347905eb62561932a0151e593c270f12f2a54f1624fc7aa3d28fd7541eeaa061640a6e3a81b9380ea0f9cd539ed2472579a30c2a6b6ab287c9ce2844b8c9f23a4d9db2f5bd78b2e10935821f3aef5798fc59049275522c08fd49f7e5e9b8b9befb6466b8fe5b3c401b8bba29526f5e9abe442aadb40ee418d3f4f4274bba4209c6aa71be2d4ac4cec7e60b3d1b0314447805f0adaf26b7624984c66e7440f13158998b9c097d46e7055021f65aa44ecf865f592f3b8d23b5899834aec1ac6e6e6a3deed65daecbbbeebf94b64f9ac23d1661d10b077b186eabc0ebe477554a36ab8c6a6e7f85efaba4803b6be3b6b010cfb09c89eb2a1c41f2a5fd9e5ee68c58bfa9f9da0e12eef4b185a6995d42d4145a1cee87560bbec1d818da13fdd955522407f5194bf1552a9f5c4403cf5e799cddae6a2bfb480b22258bcec8a5d118d34e7f98a1b1f22cc88b5f53ad0e7f9a02b92259c975ce46a8bfa5e2c8b288b1e2387c49770a9ad6ff93fdf92334578bad", + "priv": "9f79626b93b2f0a7e8f56617a00e6d22315294667dde4942e77bbb512362359d7a85e6e5e14d4891abbd7389147a4fc963ca7c641f0895fb68e1b1248b4edeb894bfdca0c92ceb7d3a1f6a5a9a0aa74e03338c9fd2ceb808a1f818754c48417beba3ba3025d2b0dab378934f3ce0f78fec3839ad5c46fb2cc2a67cb5e76473f5019621e0c82063c04842486a93020024082992886009484d91288d5a18480304010cc949e4244103276983a029d42669dc02611cc5815446241a84442230601bc84d12b8700ac34c010968544610d8b608d4a2499c106c04241003928511b58804c9414c2260dc9480d2125059264810a484d8c60022272119986962260ac3c428d2864401b631a038814c34650c192660306ed3282c892665c2308902486ce2b20ce3100498a22909a161c2146849064a20b64459c05120062e619429010944e49071414822a2204d12a35003110849b04c23154a8a0068882851222206d20265920450133681929004944201db308224c44dd824061c256951926c0028250a0971612829e2806993180c23160621148d5b064d083545db4069d148485312485b164ad9b011c3226cc43889d4886548a440133370d102426428329a4625011651e0c82888263040063141048ce0c010d18420c0a628614290e1946101976553340c1832694322450cc00412c53163942542b43158c48583888814a78c11298cc39200803246022464d4c22413a271c3082620258ea0a66158886908080288346de482841a064e0b058488188658386154124e90c06dd2264a1b2546a220894218661015625996249a9080119921ca466ca488804a106821800d23190dc222481ca2880a128c5c32449bc8810a4711888025cca031ca2271c3460e08a141124308db000d43b24122916941a4042340315204050009662018050916490a172e1cc64103a449512805d8068618c53110344601014acbc89014134d88161288904d0c3366429060a4b48958c40d22078889264a12a04c1a2705124129c3488a4a282da1120491100e5b004c88148518a304214452122989023320592422cc2860d2022099040250202c21280960a65002442298c26510406e03b96ce412525a0432cbb0704a306dd3b001090152120632534445d812721b91841c404898066818c66421b85001036299341292328e51a28999046a84c20d2138600a48694234729b98495aa20d931801d424645b3486e08281092404c1863121c065430046090722a2b0dea587c09484796608c5e4d7eb90c2dd53437f8bdbc9c283e48dd02e8fed46d9022f4c0a77c50136ecf9f79ca812d27f534bce467abc3fd1383dc36e60abc24fd6edacc4c0698e4c463042e0bea0d29325ede51c7352fbc5fdac60bf0d878ba1545d592094c2f17382b8d836554fb2deb424b933178f0abc8c5a921858cd981a9d8de7879ee74498409d4310b50fdb77d81ca40548d986ea5cea8e4d8680ed864568a0aabadb6aeabe82237b99f5d1274c726ebd0199dd630ae81416857088c51e9bd06e217c373e1a73a7c4d442b371acdfabb7b08af6117937e48fba70f61046259a4c34d2e3b912c136364ce086e1b9ec49b5aed018f92d5455084f858a50dd9cf8cd8c906d2775079aa0c3768fcfb9fdc6029c7b0a73b6c9bb89e8e424cf8f56b8435247e36b2c073b6187ca1c632f0735d9a1c26332a399a349e1b8b87e304b5dc4fb643cec55205be224d5beeca8468fedfa3ed79514a8fab31fbbfdfe7e7be6d3da99b6d83b48bdc68483b803f4681c9de7d470b23ae4c345a23dfae9c1db14024f2ae775858813ba375222997207e6bcd6030aee6f8cb75e8c5ae5db55695995b99045d43b1bd85738db93dfab5de5cffd56410ed76a3717996070ebb0c2f7b4dad13358604db1bcb479d0e13308098eb375a8cd989b8cb16d92f4fff776a9b542680302c3288034410a141242f6338d1906fedbf7a369c0a2d2571060c11a94cea8de591404d0bfceee97ae547ce266b0bfe4d087029f3dfd0493e0d6fbe30342959ea1d4a97c3e8f6dbe7f754f76cbfed489f0d8ca90a4d872014fbbd01de99db63dc14d0748afa2e289700e0258cc074e810e40ad79a47d02cf285157689d1632893b94a60e1db93365f53180426e9b771b23d49383faf25a00c70aa934f139480df16e0fd44b361eff25e199d213dcbdaf4ca6aa1d262464beb774ac2a0adfac84789fbefffd6e6986b91dec5445b6112cdd438c991a9a701819ca2894a2533e48f9adb0a6e4342799d251217825558cc6dc75cc4bd69c49bb7f40f454ce407f98b23134628c7f2fa56bfafb4c96434c7b610e3e24ae64a79c66934ebbea70f5c4ff626f46d28bacd59b6967f176c11758f0c88f8323b85d7b9b391627145cb2af62860769ff3b2b3b26d0823bb974a740c189c0bc1788e644d20b815400f499e993587351140eb90f935e840e0559805370ffbcbbb6ff880951d0d32527bb6b49db4b79a713cc81cba000b01f3ab0f84733e8c6cf1fcbbb4b35b56d1dcb4555310ed89e8d7f3340202a017f2d08ab6fd33b381c14a3c8806fd7f469a2a8e76cb3f018903def317bdf5a22945f3b6806fc1648d731d4ae5a97c22af65dafd578ae80b8c088abb553d644f08f6db569d411857535b831b171689e96c38b1b176731a8891938d508fbfa2e139a8b98c1f5f358465294a616b7610627edfe8ca75307f0859dc56a8f006b53a2f090475e19a5cd67478b52f13fc5eba409f00b23804144e61f022ec2cd6340a3a374447f72ff47c8286e462e44042a52df31b80a6cbf256b1ee03139a2efc5e34cd70a7125b9895f04c0621e2b85f93cec68d6f68de74b501b64c826dbe69046d1a388462bf4ccb2541c23058f0d52085b6ef1198ba966dcb7e0b408edd73f0741eb5978a6c397c4aa286464e122602eb5465c5724c2a7286dc3539db789ecb5fd4276e84b8f6ce6a25c43e35bee39e71476a2b10d3dcda9aedaef22e351347a932a194b2aafb2942cee2ea0c8d64b06a197f22374263197e2a907f28ddfb698238396950a592c7003c928a2c4cfc2435382ec2b30a791c6cab305253ea8ee10c74df9549d616d10571d816ae4628c4935f22cef71dde4ba9d57e3670341f20df9dd799e12d9cb96a83633dd9ecaed723e26ee73a4851c310d3b52d25c8b41942d4e281d2edd5c1ca0ba0f7d84762b315a88bc11c9d7ee9fde4eb9d17c0137212b42a42b8980b07ae0988747d28edad0fd315d7dba8c1a41d8fa461b66b0b50e72df7c52929be6037195819d787b09697204d4c3956672629f384da37cbde504812f99273c013a4d8052c8df51755718fad9325cf99360d79bd89243dd01583d41e71876d2e08791b364c9f73a173a1516a0599475d83820b049cb2a21d654baeafd9576efd431627a70ae3fbe3d65b9d43629867650cb38dffe8e379f058571ba18c90641a9f0536d4d3494e635ac2f0163e4c81bc8765643b425692f00224cc6f108c5daf96778ecf07f153807745fedbd55287d9b6fc06c3e9e1af0ab61b168febcd048a8e310a4a678e62fc5dcd8a96c2d47108677f42cbc1d8c66c999f2fe42118d0726082b6f78df439b" + }, + { + "seed": "5b2a6370092a66d4c0102fc2d8c303ad7a399b8d25b622f7751bc82e428a5ea1", + "pub": "ef8af6ee13d4d939e10018a4bf851c592bfdc8ff22cf2a9774062f72fdbd621eebd8daafa5c8bd71392b2448db27c13f0b3596800fd5651e2b5d3eb0c85bbcb14bbdbd846090ab50c57b0312d131c0f2202720b01cd6bc9527429e5e08ae14e99aa05b2341b812a29548f9ae9b43c1a73e3b4856a5c7169287b15b21f47b5c946f65ddace867969786c81c770a091644fb7c9463b14724f09e63b3dab13c3c6ef5073ec4f4b5ef2fde2daa40a5f56fabc433c32875c0a03a44861ff658c2ec3dd628715a273ed66c8d9e03f0445ce7959004f88fb0db79783ecd73fbe736c3f7a96736903c292e2bba633ef7d7702e32a947f35d28d24fa002bd1a8c886ea9478cae9f2a6593c3dd872739a29cf01fca465c7bdd1719cb27814297be1f8c53007dd5491ed25fedda293124ee6887449073ac6ac193b8d2e6170bdf7b9272337da31dea3971fdbffdd3dca75cf6cc50cae6a449eee04f87367938d040811a0d375f51898ede2314cae7fcf2670a69c7364599e9bd883c055f7f23187faaae33e1189d07dee91d8fef793b0e75faaefd44e6724444f236ab05ca88349f15451adf90dc68911fbe2d7afc7867d321bc5450e0d089c079ac97485709f22fa0b938a00278359b63eb469114b478af677ba35571f0addbf6dbfea9b487d8bf39b099615000c4aecc245657b7822ff54d14df262fdc3deedbd3c7a55c499ecc45d67b29d0cfb1e2427de6e11b6534da23d358ca3a2867039ac6d7937e2d241d9356ed5126d4f7b78094875592843c09f03662b32be54ccc4067e05348886856d272227b2396abc52f728b063bb25929fea9b81d59ed69d621fe97816b441dd94667b921f85b7999dd9fe1aa5ecb01b5edcaf1a8dc033f56921dbddc7cded1cb3d42ac0f090b57a0a1ee371ab65e89ab9f05cab1d5a74867196aa489d944f79743ea2b935cfe0104c196e544639b22c7656b2cf79f7918ba12f80b14166785fb5c2f0572f066cb745e5cc16827bb147adc7b51783c8ae2687a815575995f923bb42a275255aed8ac630e37dca4953b9c1bc79e6f94e0404e140164f995d8f8672d42def349f4c019f77af837584891726a4806f0f920faea65acc393562affc738678229edda62418a76ccd33bd4fe2a5394b792a7f7549065ce9a99afced4925211fd5581d4c67e03973c44d0fd8fe310dfb847dd7bca25b48b14b94081d513164da60f81d4c9af874cbdd3d7a4c443f458c1c05879f0c576f5724e33abf738a086aeb482a5af0ee45ad472bc54e50b7f471bf1cd272a53012176374bbad97b8be83bd997149e03c401cf3c1a541990c4a632716e7e16012a946d6c6893c366768d5e5a57d732cec2dc47d6b2e4090e6c7293d0129d2af31eb941c55398d003b906b329581f8735284f238dc33f0d0327a08265eb2665d1a7971c61075a7529079176460760c6c36d877ab0590e8dcc639d92fc0ce1ed2cee85af984cfaf52e5c57a05884be359a04ca67056e6e90112a5c1a79dc7db9e4508010cd0f9a3f90ca5769fb4c1a31337ffb5e85154a0add475c1b712aeb7929e2f7908d98b6d25ffb16ce5ca4b2d7dc87839990ba66e4135ce1c0ca727bfa51f1a407c790e6331446f6b54365e3c7bd130069090b252d363ec3f2c8caea466dee10b89e1f0537552b4c73cc7be8faba6c73504ef2798d949cd20f277793c0f9879409b1a43d6f2d0ce6e9eae2033e9582d34f1e4f70ab03080c3723f6c01bc55ccbe6445f51a2468bbead7e0acdc518a7916cb9300284784dffd9d25ad680ce071b8af4badf2efb6ea9d2124dfcab5ae3aaf0f9e72b704a563c2656308074c77a41c9d58f07a8ecc3b93897", + "priv": "ef8af6ee13d4d939e10018a4bf851c592bfdc8ff22cf2a9774062f72fdbd621e9a447b65367f4ecb1b750e44b0ee8769c30e14e76b80149375b7b4472950cdbc63c69880b088245abdf23f7f1fbebc0a81d9910f76289c4483be3abf5014576b04d81ef931ce01b508e9a37a5ad8efbc1b80b6ba3ea2ef0a1975429f7f963dfe6182519a9044218761d2948513398403b7718a406890128219464e11b3652436281206802386810ac088a2b20900128124880420272508324861304d1b808891324198c651988868da444ec2468113470de10820899009d0c82c94b82c83482a800071dc102ae4c2410cc860e4800d22206983062c90068a814406d9222da3c02062c48951484599c0450a15241112319c844909972158082e8c4289e01609102669219404c8b20819206c21c2842126118ac8241c29404c924822334454125114a211d4864420b34059b621c1220298124898a665c14004d4404c592261244992db206d094400d4986020198452c24009800023434c23a00100c6316390499800201329524b3492022888609665a0c62dc4080544368d91b8491907255ba044512829901825238268a3a02162b6895b08008ac408a3b28d11a2411b034a5212911089848a8841e14291902040d4a64584082012492c522684c3060919c86cda360012b125c0c82020106d639484480861080180a48630210712024382e00828d10241d1306022882d9ba24c14a071881852980404230521c0846513242261089244408d0b4362d84062d4428d1007718a468e50228ca4828454a68981c4101a126ec096300b474518304a14030c02000ec0168019132c62a46ca244045334640c0380412825d94801214770d8108c09242dc8c06910a7712196218ab4719344688bc22102056064080209a4089b386de0482609a940a10248e3b22858004d139740e0a44d43246188a88d92c860189630e494840a1192a0305184446099b04991c4291b30084a08045a160024156ec4106163b47141308d4982208aa20c921804c9904524426de3921142080182006504970190304a129989d9422d52a20d5b322524210c1308209148406342828c48611b8270e034041a238d4c0090a2a06d60166640162514428602b808000869c8004203852c1b2810e492690b468e2023114cb800e382240b0822cc4024489640131661c806725a18510ab04822c8719832919b1651240672db3066d4a051219400dc0281140920a09680228980521011d91d699e20757c2a8faff52d78ef4d500d5496a4c554434e7bb5b3445957241991cef60d776a91c753155e24ac9a2a904b67427953b8cbd2e019feb398e06b67c8bc722fe68542abc7dd37e51d442b9be301e10ba336b80babc081aebcff29c6f9076ea6496fe6b943d3f41009254c644ea0f44a133bf27b06fa41e78c49266607f7dcc9787e24eaafdb74c6912644faff379499aa48c5286de49c7dcc8dabe01f9ea49e69c4ab247c56a7be601afd4b2f224e7cba484f4b9f69ace32218c847eb3e2b4d3292ccd298b3465529a1115602dae0df14a1f0730ec85a80b970466a850af6a2529363efd78634bd4af0e4ab7606ddc57202b9d5fbecf7e97ce23f8e19af023c2739bd656972c03b94a8979614624b58d2d70bb9f09407e8281350a46630b7efe1e4f55b4baef5b53193b9818b5380a49dae65eefb1d02ad82acf66f182aa5fbb97645a7d4eccaa3c4450d1f8914aa1a7d37025ab198ba69b884d7907341ba7fe259fcff0c1e760061daac6b3d9a57fa3123604a9e8ef8cb45d4b1af5fe7fb6d8f047771476933abc9daf871ca79f8f04106a543e4e72da05ead3b63f8cb9df01b656799f2fad52d1977328211fe362ae78e361c93b4aec9e1c8d8cf3a2bb0cb495634833df82aa5702e22047286e3812ad5395b5f053d0e9f530e344e69b12b574133b25021a03995ff453dac416c82c082410b3d4f31bab63d2b3aa8244f6930043cadc179405bedfa7f7983f3e8343a6b04a63a59dbb8f83dd3eb6be35adde7a5709f347b98c37d8e2957a7d1f4724622b7d51bff1fbb5e93641990b09b7b90c57edeb5a59280b207da0a71c7cc5d9cdcbeb356a997e77aa1b47bbde9fc468c92694d9d414839c7d1b1218388b3eb96c234ca65825e1ce268848af303e34c22dd597202c5bbcd81d7091e4ca0d0480609d648f409a7759fcbadf4113fdb832c0dc66351dd000f87a69a06051a1bb952281e200654ee366a746ea13cb1cbc7603e7e1e9d18fc366da8405c0b589819f136850264474cafc5ecb6bd1c255498cb46765bce0693f1bc010ece3270b0c1ac3d086ec66a8813e9d98b1cb81630572972c2e473ac0d3f291dfad56a2fe1c02b7e1bc01b9937f6616d73960a88735d4368e7430c4ab75d1c9e4e0abc06864595c6e9f3420691e74831fc70e62fe7ae5610eefa42d76cb74af71098e48493e478ab8699c1e77a0eb5b7b3f05b4baf521c7a2ef02301382446d76f0da501b9dae131b142405ab340890a5d7cf917b1bfa722e4952a9b2673733dce37e4a633c08911d8dfa87eca362c5081bdb4e48a80a779850dea15d99322b11c3609fd0218f446fb187f998b94f0bf71507a10f5c1114df95a56650f0fc484ab31472e45fa71b37e31df3708cafe6276b18fcdb28f06cc1f82523ae49f66af37f8256a43a842fe489f04d6e620096fa3305503bfe268936e0ae5c2daeea27e50cf1aed12e94fbcefc8232e9fd7af8dd2eb695900a63b99fb65e944536ba1c94414d0cd6d01c249ac9cd55199daac2ed4b3cfba2e1aa421c9833c9f57268b316725b8ba17e0cfff5ac83026a091832aa18a730df6aeef27a8c9fcfb01fb59140e5e80501de8ceda329e35c57c71cb6d37dd707d470c38df972710845f202c6f8ea7c7c2c21c1edb884874d9484065a243245ba81ec24563f0e9a5d9a112afd67e82d018bb7afd7a3b07aecb15c9818522443df2660c6c67fb936ce1f32f9b7d1e33b3cb061e4679ca980d444de5919e3b0e78ce7b46336df2583c12a220ab27c27d5158a3f23131667707882b0a92df25a96da72405cace3b6b06afa2c6a0c903e8e6b581811bcd8880b15a7fe4815d5bdfaa98081c3065c1b809089816f88d68fe0bc520a34ca1d5823bddece839d149417add8ee39b385ff208918bb60bc168c5c73e3ff3419e0e4abb4c2b2c2b75f35aed97adac0e8ba4443d31bc06ec1f68359bb0948127b2fcb546f02de2869aecc5c4e2c3833a6490de2d41f2091f77edd2d9c53c270592d4517ce8dbce1124788e3f812a9f26a25156574b3e1238dc5c6fbb543689c52245d3189628232fa369dc0589a6afe2efd64c8f025b9df60e2d10b09e1105e9864b37be62d2e36f4b99cb6718fb938a3800c87566ff5a46773cf1a9a2d08319250338f094659be9db4201d04784c9d911b485bfcedf4e4822425c0b3d99527d230e84bb325a705362242fefcb067486c63c626b435ee15588ac39d25948ed00fc1fef8c26edc13746535dc7c576a4bd0f46384029e82b58cd8b6839239bb0577f682947fa971ca94cbfcbf5326c92a2b7f7b5c307c1b98886413e96abab7519cfe9a32340e145c35cd479" + }, + { + "seed": "986897ddcc7582d8b695da6f912a6b087b6aaced78ba6af30ed8140b206487c8", + "pub": "a9145e8eabe23a73668adfd6182ba69e8cc1b0f1fc90cdafc617ce173099768f2d33486dbb851b392b3edb03f23a481b05821880d957a87def28d1e7f82ac0bcfee5169c80648e2a63edbae8d1a2df2df186025daed43b2e9df0ef3db4c25546c6ed4181aa45fd9fd76fb753b2bee8758a7e2faf40bb10abb894657c041fb3b4ba24bad5a1d22081871789880c0a1d2eeb536688d77ec316b8082f65e5e61e569a3b932caa5319095001056ccaad3ebfa1df38401127cf303febcd12071b6141777c0cb4ce736f4d19c3e33c8d98207d4a5ffc0a48cdea345f2b8cb7c97352d000f15093c57cdde8ec261df712019f8093c7ed6033b10a07cf938d589f61b6212a69f28bdd05e32d83f9961d15a01aaa3617f3526e370961e4dbe5b3c9d4a220398c54a5c1a77bad6ba60d40c3bb49c3f1645379d403332d78e785a590b469e34d1b6f13912ccb1e7dd4d8c3cdf4b13c4f41a9d7d0f23f3cee4925f6eaf3fda87e5f5396a673cc53c53ea5acf3bde3443546c5d25354a9b3f82016b875a74652fdd4aadecd56089ca5af8f99d04804786fd8a97803c24a1498a59b2ac4e7cc28845ac0db7884e4362891a66ed6a29ebbcbd8d3eb6302082320309c3a75c363cad55bb7fe33c90d94103ed69700985a84c8c3cfe2d678d9536277b0dec7d645f2bb072866bf0f1bf6b6b81312f6c09dc1a68cf0fe3416300ccbad115c9db573fc842f0fa5def49c4c77dcca008d88b8e531f60d84324590f75f6f319b393fb03a99bd53e0e1a4eebf72161db6a33a5c873f2b3fe50d35f9c750ab7328727ceec207804b96decb376ecbe259c9994ad98096f27de3dde285bef27f66cb86c4a09fc2be0647e5227e7e54fe10661cc2dde4bde47f0cfc04dfccb0a8c7f40553f455968bfcd355e07d963a1e3208661dedb9dc996f090bacb1d123336df5b47b184810c0907b9f5b2220c0e192fb839b625d48ca876d5d71b5eb83e13f744602b0d02c8bf54d3b9bf3fda643a6c75ccfd3e89c4a23973c14c7aa10a60bb5f4652b90dfd612678d6e3c8243cfe0222a8a87ad52f2a72159dba19d41fe0bfbf5a42db81e3776f595f1288ef4eceda2f1ed696669032a18b45a6ef8f3c775ea6f0e0fa98123c24558443df1e225fa1518ed8d8bb617d5e5a0574f4706aa8c34a0b9f6822f8eb5bf3722cf2d9f77ef76bf184bbbf7090a98907b74f9a55d89a5b404f6fafb267d923f46539690f7b924c65a6076467d0cc94c43330b99bff084b7b9718b4451346ff427ed3cc82621e46bbeca950a509fd5567d3ec61b2d5f54996adf375dada1525a21360e7c4677e8798cabe8883c588fc1c18b0c78d3196b379602b2cd0cabf5f49bbd35ba6683889cb07250488a382fb368cba0d97964370b89b3df2eb3ef4695f2b040cca25d69b3f5b84a5a62665e6a7c7c8e1b2e5562f032d244c1c5384d7baa0aebc53c3fee831adc4efc6a032eb87c6aed6233c7bae163556e7afd154d3e7c01dc05adcf09480cadcefedab21edde2c1cab541902e533d81bbbb333dec191fceddde16877662018780db78558c162f0f0b75f747d4753470ec6035bc4ed04316ee5b097b4f63702728eeb1c72d524772e1d593b9b3aa78dfd9324ece2298efcec92d6ea3aef819d1f90dcff2553911c56f4462fad018846359162de3215a8dbc104e9ab8bfa8b821cd6b49cddb7899df46ecc90923c857269fc0335090dd3ea12752fef5f1739ddcf7790ee3e8ea93826c19b2a7b547c07163bf18111c5cfa7370fd97e1215108c1a4292f06f596c9ae94de70c1be8251f585c5c7d94c43a23cca1bc396d668a4803503af2e4f74bd6898577b1ecbfae114be", + "priv": "a9145e8eabe23a73668adfd6182ba69e8cc1b0f1fc90cdafc617ce173099768fef9edfaad381b043ca17955c592b0b55912c63fc49ba2d54282c715252829312ff3c34567943e2c69bbc7427195cf525c81b25709040d38b6f2e34a08794f1c6f4f73023957788b958cd002c41165a1c01a85ac8ea3f50de849bbec47064fd448898699a1471d3142adb0005a330421189851c8208191171c0288e9a0264d3328e2126800cc80ccc2882481072cba4241b482c13284519000600a8480923049b060d23816812c4411bb08d48022c10022509188d528870c1049203976c233808113900e1188c622851e3b60803a18190322a41c470a3160119419260b825db4805d0a06011b48508a3098186602005869ab84d0cc088409890ca968d2135490cb6449892856126318ba82d11250edb80695a006d4b0682c1162d2133319416828c404803c7281991918c462419c209d1448c2110314b14880ac65121406d1c28912005680a11651b084d0b96908896650a41421aa5691c202218394522930049224512326d1330050303508bc8105a384894182aa4226c18294554382c649401e3466a5ba4510b430c5c008e0b90690c470e08830c421002d9400c10998958966c9830641214801c934d8a189154340a88184803340853845084b284c1a02563c4010a198a22269041c244d0b271428210c20811a1064500c9410b816110b26c4a344ae42449d89288824204023226918824090492e1104d94381023448ee036689a9011601866d24089829611a42844633021e3302541800c1419008b264e1208304c1881e38205c920880ca82c61140e09c624e0368e13388edac464484200e108415898000b806c90b4412118328c0432d90620cbb04c5834125194681c4206e3246690222819b7000a03258c0270212272523021d1a20101119122c969d1b44064202809454518b38159b82042480458004ee4140110c1294a168964380801c3840a90490c11640ca7451c3010d1102da324525ac82c58904d9318691013411c058e4a480c4a4884d012480b2925a0c48d10b661db324519198e0ac0855a422de3a00dd0228a201740a03812c3004620c8600b4781d4926494207012336ad0182442c06811490544c068d4884d5082281a420ed2a42d1117401b884513492a040370029880cc30510348224cc48c02b18c22b18d09416ad9080ca1000ce21030938420a10226098925e4021021a885194405c4326598b0218bb2518c226cfeccd44860d30fff92179c99338931eaa25729b8a8f09148d8dd101028b9e1aa590e5bd111f02aefcbe07e47e8dba00b2e41bde7f62f0f825deff3a9ec93cb1112369065e23f50124e45160b4092a44c8d2c93bfbf79d509a34ef0d62e5d8b5fe312de4156f6b35431cdf9ac0ea0d97fbbfa021b3fa76fb6d8b5c25f80e8a14136df6fb95764db1890a3eb2cb51f7b2947439681e8f8999bc951429e5382d543fc995f23b674985f5229f77ba8c583763174cd43af3aa06f100de14815f6c0dbcc03d198fccff532f8fc66d5c3df324364a423f6df6355625037a46b89fdc3c431f1d8ae9bddcc211d46340d3ab21c5df54ee1e128c9d1baca76ed4bb57b63d4eb5ae97bc90eb7138517ad11ad1da3b408e6cce15ba06f8c88db2bae00dda23d7af43cf7f467c797540152b2f3d5eb132d04bb133704b2c31ff5f0dc20b4ff60668151d9345cdf8250a5d379f4680f9bbe49943f4da7fa0180515e19bcbe0016475c01b93a446919cd4296961a1fa777698431630ebd065551940b6a35596ab29f9c0b4b51ed29e9b1bc5f3d66b5aa91e824a210de839a96e8dd1ce1b21f5b2c41cf47b3cdf29797647cee3a6c0b3b3f982780fbdb1d5e2030e9cecfd75d7e3681c06f381b288bb0c51ac97353bf2a875574329cb725cb194f533274b8aae48d9033d7d78d459627bf0a7cbb39d6d8949c0ad43354de13167ef16fdfb3ebb0e8405d93ea9b451524d7a4295d5f814726285b08e842db5b6809e4c3e51bac5e940e9b621d0698edf44bf868cbc68c734dd512a33ddbcf6b59c526b509820dd2d5f78b90cda9b39d6a70ebc221864175be11d732aba56ca4439a85516b48ecb51d860863a7e95de4874427d4055dc5f0f8d987dc9115059772c8b799efffc9d0d8be9df373269982896222451793bd9513fa47cf8b65687f9c6d035878e0c3084941a35dc754c7fe58a1425efafe5384256a88b63ca7b388d7f4df3a13f16e19c78a61168d5e55d38951b1380e765d7620920f09b3420b8a431f819dc1fa8a9a9de5d53d288fd9204efe23df0d059f24e18b9ce4f5cf5321caf12fe4faa88dff2ed5db7ae3b74dba83cea23f5f510fdbd90256802e1901a4fae839a9ddd7a51302e8f9b9920549fca7367c3e65dcce963bbac7e85eceef42e88bf57b5acb1caf59b2af94ce6aaa92e32a14eec8cac77ec83535080659782322f60e336db5ecefade9b5822a114b4951f40f42be9faeb6a5700775e8e03c05eaf799ef76db5d70db9e3dd93309e75c7662e70d51da6a383a9768b454fd3134cc8dc0e903ea94e7d1e1ea95ccfa1d0a9322bd993a44280a1047a553dc4c44867d08bc21d4f9be26bb64d18e9b3a932efae37532ccf5f3cd8e5cf5f8463a2e4a336a98bbbe2a1b9e981f7fd47ffedb11e95fabc1a0a198eb9a1c8070a7854802ea774690d309e8dbbd4fff320534ddf5f4a9cf398dd6e46a657e156818cc073f03bacc8ec159de3e08ab8280cda69cfe201d0dbd00dca9fc907029899076a1f7a136a52ce710d9c62f5d9111d7b75c5d27a2b299c7918e233af8848e54321022e67b54d8f3aebe04e2a517a18f1b9377521780205662a41c718161b6226abb2db442f7ae66b616c6be32df37e3884485c50710d0edfa3aff37d611e445a5dddb9768eb4e66277d87dbc2c27388f7336bb920019d7883da747820279532a31497005dc9f87b69d8f14a011a9d2086278a8dc8b9d9a4696df86a7c562233e10b7e6a5aa9800671464589a1d07be9fbc581cb38e518d114a48e6969700bbb5577ca6baf8f8d3549b4e90dce2df74af70ce0199b79e12f29af91d2f93bf9b2a109a1e48dd9190e0c8d975774344e5a6621fafc8c2b5d012d71209801dbdd66f0c47cf9302da6582e67c9ac88618be010e7e88df2852749eb7208914ffe11a2b0ed753cf55335d99eeacdcd79343bb421d00eab20bf8fb6db2d850fb4976b3d9a7a3815c064d69ce63a1785d725a7ca5aa8fedd6c812f0b7645bf311930d154546f13c774b533b5a0f09a5034b25309fab82b312f47f7ba278e291f819e1a3b66621d938abbe1e34b864f8dd124448d10cfe40b2ce203e583b2fc033deb980fb47c3e5c2d008b7be6f113f8e00d83c47effdec098763be46e7dfdb4ed9f4b7af27e2567e928693088ae6a87af3320b51b5c1815ae89f33fa30e77f30254147d4db7414c98fcebcd7d83429c21b911b0b2abda32905ba9b6be55815bd267199aca5b52328b6c7e5e76743a63214c180db2f85aaedfc7ceb5d18f3256ffe94e133b54a8aaa09fbffecd607b229a4f2569a01ebb190279a3903fec9560e55ae27369095836b2fec6928e14ed31" + }, + { + "seed": "e499971cf4b0e437dcc5a8f0a36aa085a60309e38dd4027418c344727a69cab1", + "pub": "5fb43de33652c891f885e3891e8ceeb3f751ab92944e3a6eb03ef647c39f54e0fc94f5ce6fc1ff853ba1bbf815bb803e23212b76bde775ae80543b3b1d71fc9324c0423c5eebf1773ad897faba985b9a359d62c0e4fff4c5ae12d62989f3bb4b53c92abde858f28f35aae82b908c27e6f75e312ebb0c0601969a567d98f71d6a88e37e571d346cc4ad0562a8a880975ea835df998ddaec158c15145e944eff448618fd279c8a5a75a85774a4765ed3b8e1c371fb8cda9f1a1a03d770ad79539d6b3063bbe25af2bd2e444b8ed76b4300d70dc0bdb5f0dfc3c9645a0ffb0681d7261db4f59331e9349a9d43f0f0c03a414fdb49bb902793fcd7245bf12afcc42d5cd0d13fd06585e85a354352701633090244323433e6d1cc61bfded734104248a125495e86f651aeba57b8428de4b80173ae1a11d898f3ff8e099eec2026a3bbb6188a8be0481d32eda7339dbedd5234aa61e98c6676b6650f223814cfd0ec9f3bbe9aa20e8693bff79e76c204f5170303f2f94c4558ff5d8502947cecb4e142c622a4462cd58e332d754f611df37854ac77ee5926da9eb979b684cbe69e1a03ca2e46d28d63376633c835ccb2c9c4484ffe6e488c7eb77047c7ef19fae32f78ad181cdd8e77926c5eee531405afc61f6c24497a13a3ec0f00d131bbf722f9e1250f6312d28d03e56db1ee50d1134c000a411ef33ef315bd2f7289ac3e6036b5288bc2a3560cac8634e87412bdf3494c32a24938c24c09e420af4273013e9fe01c4719ed67b2b47b6c55629bd6a34aa422d7e097497578d007ac7cbd3cf8455ca1b94e953f4d4c2eb31ffcb5dce3d0527585298e9f5b8c32f404e14b7f5c30a985283ced4ac3d18248be8ad29a0f8916ca43b27ed21c4f1149ef2ae70509953a39cb3b494c8bf0e159f8bb62c3930f998365a446e97a8b16b5f0af23ca610bec67cdc5827e7f012745be8ad1ab6ef4b51ce75cbd1d065588293e2dfaa6e9ffe6f8addbfa183c15721d3688c51205f7acf899b4bc69c0d6724bf22ed9ef4781c54966e85e42741f8f64756a9665c0c8aed2fd59cd069c3341a3514457540913d10d75b9c32d32c72de2710f695c1e5da3b4d135668b792c58d6ba8ef06fc069a13fa64ce1a461f510200f7839d7e702d34ed3455db4b39974937f4ad948e4087099c0e55606fb136f7de920934cdeb78c10e7e2e299707b216f8b8d3cfc17117e5d499bb8f45d90af3c73e7375ecc041c8c04d5308ae6d24d0754bbac70fcd082a2ef7d9545cc2b0dd4d5bd9d3a62772b01b8c1e5b525171a9556fc18269c936f024cf8a1640e2190647775bbaa5df26034d5e139b7b9743f79182b7e4f761cca78bfa00237c1c2d04433bbbcf57544d45528c33bed41761a52d4e0b465db2542b5940bc7ad4119201563cbaf917d5e586b2ac31db9e90558facd251db04bf8c5f985cfe7215d2f6addb70c5436a75a773708c71cb10efeae7fbdba37b28154eafcb6d2cb167e8b941ecbe11db566359ce32bcd9fe1cf925204c5f56349bb4baf7a820a0bf8ca8c540a0e3f27abfdef19479471eb9d829ac835afe2843d78b5c97c72164350d0d77bafc2b20bffcfc3c5518a3dc53adf00aceb3348805abc79a675e6af4f767dc8e2f5d3dfd239b9f1871e36b83ad751ad5561a7757c9154518d5d0463ed3c88fc0b1122ea8055572b4a03fe860ed5ecf44b41358a94bfc73bc79aa2f1aaf6a479a70f3263c6ae9edf0b70c65a8ffd77bf1e614c4253e9d75e369211f41829a30f5e6c42a31146a4353a345008355cb0cf3e14668510a1af1a2647e1c13231a9c469eeb09a0809b5a277b6fb6b34c6acb99b4652d346ea565321", + "priv": "5fb43de33652c891f885e3891e8ceeb3f751ab92944e3a6eb03ef647c39f54e040106c77babde1afa5f1d37e648d59407f41fb834221f0a62b0b42d38dfde62beceb8fb9ad680f8921141dfd6c8f9cb92986a9bb3b9020297b27fbba970da5cb45b0603a60d4bd3822ad96e7e3bb787596caaecc8318d2256a8e4037a7a3450612311003216a62280e23a0610ab084218140129108141171c1824419a23184c641039508dc10415a0828924892d2044c08176dc9806d5286484c282e820024c1300e5a189118a16dc2086ce1248921b931cb086148344404088cd2224ec0062c1b8591d8046c63965119a320c4288a8c246e80242490804551b22414a4114c38850a084c022151c1200a2430228140091c428e1a40459c162a51b88111246241026e2312721203429bc06cdc9884d148414cb24022a5119138448024011a028d98a46d210981822221d84412981680483470120064e130091cc500dab2514914224b96801b0789900410922226030251133041dc928888866d54224659440014174a1c498d0907812234511c4231ca42024c264800a2848a300a64044aca424d12078d4a0209da44644c84291a352811922103a5680834916394680ca2695ba684d2202e58a22948004d0b04401b454c62166948a611c3a84011822c181628a0c2491144228c94659a402294288002883160160e94844158282a50240952c88010816c50088e4c12844826129cc411dbc428ca280518314500401103c764c844450aa564d94466c4463094484242082604a7111984011294201cb80103126521a284211108dc026ec0143011310442c6711bc0900bc804e0080e1985841ba048c0046e20226999162c8830488b46524cc88c2494455c1266581672534666d31000143301511400e4b864239209a2a01121331184222c01b70410044d18157114435011080053286c89b0900bb80c5c168c20486c502060d8288898422559b2300b8265d8c840248980e2b26188b404dc38400a07128000601b9631e146649398680c192c02c68d48c4498a928563388ea1002900a78c59b4884204011817080a278e012061a2160c88b480a34805d8280981868111b101140464014928a1b06898a0485918500c303160a24853469110252c123272db00501c279123a86dc038065b1440a2006e0bb46191422c5c38499a046d22b3400c41881034295b16448a102d034828db886922494e0a0722099910cbb890801468ccc62860428200a360bc48536b90a842e75b4b1a085777d2ceccb04a4aab96a288a61e577e9ccb9d6500211c3d9211b969128fad92280898b360398717357ccd3ea7b2e49eb3b21b6fc3db4d1ec94de81efc86b16ed370b68857fa022f7316dac51f81a108605827be45385bd2fb0b74e1737db4bcdd1c19797d77a167882c9eba054c1413700fde74b47697b9a9a4cb4bb80abadc4e7292cdaa4532c9a247db326d5694b8aa554c61f11deca4cc01ac9a314f53abcfe461771ba8a2272fd5a095a4a58a5521b1a67b7b54a1ac289f71d337b0be3d17bf55ead10cb74bb6cde4945d4345bfa5d9c6f9b4d2ceeaf0fb2b61027883e939d640e0d6d62672f6bc6cd6f042b655e0299cfea9ec60cc0bcc376994c6511edcca4fb75baab48aed38e6d21ad96b9e5e2808a69df8690b931c8ecc7f4d175d4440ab05b3df475578eb5081bc26c0f5810a8b9811077595f8305f39c450cb62bd055f290966a7935971759acf68b9593243a98556abf7ba9b8992cc3f3e4ab89de0b739fe38fae74ed107c6326ddb5e85cf385452bd5533becd28cc27506ce2742506113272afa8c26e143e4f401ccf2e215fa6c29320ade82de29cd98489e23e25e1ccff1137ccab5be7bedc3888873d9a7fa13a3ee24f6b1a143393ad252d2c8415e1146272ab2146e75ac50b4d742ae8dac8eb394877722ece7d34c41a406bd706ad02c0609e21550c9cc5947f674d6aa63d95eb1bdf537eb9fcc7d03295f4b42aa122e32db6ae75fdddf228a88c729a27f007e3b38c0ad9c9df186df2e515628f6237133fb742318bb49b13c253d0f8440ad97afc421cef579513abcc5c3299bf582ee54381c7dfac8c7b0fbb64185e24312c28cfcd016f7872042cc9e323f40217598dd7fbf7a38d8f3b94e266c92a2d9ff82099b2b2ccfe82d38b9a552b2d814c4da251bfda62ad426efaa1b15b204497d242b293507f7b33cc25491797ecb7efa8c4c966bc9a8312261c0b7d806c159024572209724e53918b6dff06b8a2fd153bab5e33b53f129f157b37e3d4ccf563832942a608cdd3e9895dbb26a04ddaa5de94e9be11c547b640035d6876f8aa6c76bf2fedc5d06647549001feab5363886459cfdbc11f8f4ece1e5452a0f8bf0daa6dc9a81d678585da611652ecf2a3cc0fb997fb95fd9d386326aeb2931c59812217d816d7690144ea48b2fd6907032ede8a9c08544157e306d5dc2e90bcd9082b9e482fcf078406fd3e16d9ca67d03b6297d5416fab36e4c1f3d91397496764453e81ebaf41b58c5f0b8a9c3f7e5b812193e338ff082851db36077f3776720881573950dc065413ff1af8d52fbee8f1f0bbc7252d28731628d15a66f9d88ed69e07f5c05f397782355407722dcaca6d0e60c2bd0fa27ccbccb1a65871cc93fabb4b37804456155f05d6c886c37476ce3a7b6474a51359e8b99bd2a30f9e4bb3328a91af77556efe76ba458d96ba689b332fdefde161f9dfb8b341a131a0c6577c3fcd746dafe4c35691dd234e200be3e7369aae47dacb2e8a45dfeed430eb525e2b0797a9137cf3aba1aca48853ba10385f42ceeb95e122ee34ed1d2470e90215058bf31243223bc8d399abf0fb39cc675f2d4e8e1078e1e5bf207e7d926694cc9d3a8cf5c3409e228ae582759af803fc3e29a6d3fac2601b42d2efbf31257064357ac39ca8381f77bdfe8ae8ebbed11cf638cc49e53261bcf3f2b81163d0f447e90994ae4adb702fda568b992288b2aa51fb4d37cf22745dfd5c3fec3125061715c853cd888c65641f2fba56ccf37369ed300e2cb6e17a864f12b5486fd22781285b5817ff2be496010f46a3b940d72d9444d96da723970176f740b81857e6aa00537204cffd5239e4e49778549aa8bb9b9ce50749c61369d6677108fc221fdad8ac2697b1fd4419e2a85681c85a7638bcf1e3c756616c5f3e73913738113583d8e1c92a67d6d6c61ec72385a4fa5b584d8c8ce847658b7502483db02023e362a03f128b8fc135bafeaedb6b5f2dfd40b9421c7f6ad07b4768f3b881fd904f346c360be1414227a003db59e93b9349e1e63eb279be817a569afbd0d8fad8141f383429553dacb4af99d088521a67f08451b0122aeb21655557b238286cd37c4c49e5eddb2230b9f6877b06a8582059f4efa6140b17154d36dcec92423f414a7d8b6efe22cef3aafc54ee11baef443514e9a23dd6a432b96005a24888cf66fa6605d25969e53cca615e07a7f6dc15b85cfe2107eaf886dd889355fef8a132ede7008cca21d15f9b4f0e154ff63af91bffcd8b5319c93eaa23a94b73ede4719220076d68c67c8af17cb914729af440d606296b0f7ee1654106a37a7ef3e9a5e8" + }, + { + "seed": "aa3bdc3263883b3309f0d9cfee62281c3999cd0f0e6d6e4574644e521b8068b4", + "pub": "441cd75aeeb6f30317c646b8704ed699000c27f7fd8c942dd443150599e2bff709ae386b834ff685961f328b9092f433d077a684fb67fbab4cc36b50a3eafb21ecdab55b19522d82afc735d06da2a151668997f8ec87b012d5ef67828f00278a434953ff3e6576f86f8faefcdf63468da0a9a2edeb069300db7e81e58c4d070ea64f39a11ad3bd78d0edb432292f6f7143d822a53657cf1d7fa0936b948e52244dd305a7096ef5a2527f748fa75f47817475b3af05cd440ad7d9398ea9a5b6df845e9fcdc1535626cf726c12e75a8f37289315c018392b95f604efba82778bc6248ccf22e4aba0aab9ca17e0cdbd81c0c5ddbfb59ba326af041fa49f0921cbfdbbf9f4cd5500ea8f6bbcd6c3dc58d8fedcb8e50c89f5e092e3ddb612216e660bccd6b6a53c30153b0e55051526b2fcbb862b1d28bc43cb63ca42ed6f7b6f1acd67f4296a32690a9fd5b851e75e9afd70c74ccfd80806c66a1a9baec7962572e42336626ec455d578d72fc34565adfaa8a3978c69804e820ff5fa9c70cc4a5aea8c6ade16041ab7d24a43a762202ec61f14d5b6831b25e7799543bcc6f38ea9e1e9ae2be9f0408396f5ddcc32d3cc7d35ba26c4820f51405e3dd11dce57b207fdb30c73b468a75d86bb1880811c4b6d3bd85d90cfbfa7880e9adc8ba252f9b41c9de9345b32d1429b9bf0b72a08e96302a2c6a337e70129d68078a30124d3a532554f5b8915449ef044e856e321c515fa3707a22f53a5d5ae201d8cbb90595150735ed15cfcb6812e269bdb118f93bcc09f07cbfbbbb7fc2cb855ce8e9760977ce97e10c6b1f68b2431be5d9b943b782619fc48f484463c3432c96a66a8ecce7a19f79e5c6e73911b558d6d643a68d8836e6f1140429dd9d8a24cc3c2f619d318779789aa93a3b1cb224545360f35300b0a3cfb102dbab697d6f26e29f89f18370892c809d88b54ebdbbc2e28594d65f91fba7b6f8e7ab4c040a0a34903b9d242f6d299c514baa1b313492d79ef2a677fb626e68569563f5cd53250b8388688d68b28a522e3203a168b378595fac564865f4c978995e63558871d992682756879b7181eab3f9074fa44506e1cdcdd7f53b66a3e92016b8aa769f094fd459b580514762524168ba2833bd1c2cc15648cec268d376d4238fccadb891dc20856e3b86591ac76250b19b02806a0520fa5ba9c529c6da3419d049c6149ff02107dffc88481cfe7c0be63dba9ea4dfee6a61abc2884b95ec05c8adf3c8eda8a2a3dc65fa8568039d014f9ccaf51980298b2d4efff741510f980775bd167e0857e875af349a4e58769676f8de1318d070b85808c568ea78bbeae2b47bfabc546649d057a30d374fe4e298c432a96b827fb3ecc3b9139cf8bf9ce0fa0380ac484709d009e60660fc848d458edbd356609c73fab090b02d3c2b3f1c9b5e1921fa8f793dec20e0977afd3622d5d79815eaf6489077da1f4ab660ac347b60a69576cd0fde6637390c641bf93666595fd8c24b20508d150284a28a3f6370b37e7daac0dc5af425ec85d2d22c3ffc8c780975d6d488c97e0543147a20fad2191c189fc71cbfadb570c2e16bf430d723208719161e1ecb26cf9524ab590788ae3a1d9398270a4fcfeaeb3a1d98ae7dbdb674c987e6efbee154a0276fe584091045a3115284e30c607ae9043630b543a04b9a1791a9a01292c45efe8dac82a3f06c71f1075951f372226b278f9766ba19b33cdf9c9eefe09954cfeafe38b34c03a09750f0a0b5a425b308d3cab887a56c3c4d5c02ce283e1c75dfa59bbb495aa8cb2e5f77795bf1c5633e2d2e3b79d298ef8895f85ff3ba399abd71fc9576cd855976e703bfa3bb1", + "priv": "441cd75aeeb6f30317c646b8704ed699000c27f7fd8c942dd443150599e2bff73a9e830fbc3962248234c8b83db4bf60478b48f1ccda1390dc9ce671f7184d8bb37016cf55e817f5209f3494deb3e7d235d9aeb02a80091aca4b516483b5492b561a74706a5da70efdea308e92b6156a478e73b72f628d40f2a1685ed118b8025ca201042525e4388c190729a0046201058094921094c001a1240904c88c0392418c948d0b320e13853018944921b6608230690b130612a7305008065a060c22b86840146a20170a82b48840046a003345643022d19249e31044002686c1806d24c70913246c44b000d2128a64389014288449824c54a6508cc62c1ab485001861111510d2b660c8c40424c485d800801ca90d5b18414a20094bc409d4244241b46c481660c912815c04251211720bc9240314884a226c83b610104400830269a4026882b240d3c0458884700149021b4552e3022e18044a188285ca104e93a06844c2090a446cd8c24d19c1081a28211cb03114104819a02c02127210226e63204d8492710b220210c421cc120e6328612320604844900b992121c931a3a08808830d88066d61c464cc32711a454e9b38880188700b28301a290e98a031a30288a18000cb3031092045d0008053806d60980822044a08321163021261a48119224d0b328913346902392604314e62186000256484921010238cc0282142a88da0c661a0c251d90620c1188cd0028519a42113b86909120662c8845b446e6244051c980d432010d2402443188e649261cc300e13b85024384ec23620e2c401a2c86091384dc846211c40210a0532c342051c34499212692210681b944894264de3004681288c43b08c00b8905b1468402245c2b22141248e89347104417092320d20c48184928452069009a025d1220984848c031766d0c46199468949c26104064e09c04d034604cab8890c262601334953024263100ac4346e00386d03850844424d44889122c5259a1070e1b87189b4216208284bc025d2343018a25109812cd2141209a881008291c8a868130505d2424408258024154803234242204e93800064342c8ab82909079249b40482108014250a1a4551c0423223c8855ab68042c0819c446892102624c80d98166954366124c590e416650ab16d6202485328325084291992858cb488dc26484c14705a40022333001bb3200024891c9750c482248a8430981224e21072434671c42885cb3212239808c4924c50022982362d283aa241878b6687550a11e78269f16aa6730caab4b34ba8b020845b8c589897ba009c589e978d7cd3f93a259501ea47f237d8d148449e06bf6fcf05deee1e2a9ba6325e44de536ed1eacb3796b8a79be666fcf34e4d788fb450f75d150dc561bbb69ee4b261fbc9367735d4b111b21651f8b2223c49bc6fdc7f576dbb52982b39da6c97dd19ee0ff5799524f340d0c98b38fc6a8ff89ce9374e2aed2eadaa1527a5350c16af3f2ce1a2b520a9e380926ffd325f3f49c743aaf2d3677ac8e58c652efcb3f560ee4b4552692d2f035ac4a8dc001785b41aa348ff8886c92f052748b295990a15268e6b0c46f6143f0395bb3cfab88cc1056626b0ca8f65a6c5918c81ac5f0129c77cccfe98705e52ce263f3526d782b8e04240fd777a3e06376ea9870bc023214cfcfd18dbd70fe3e3100c4d5a60d6d24aaddb53d37e8a589ca677a9b0ecfd377712f37144cde55cb6b0465d26ab14016d1c096e8926bf2d03ac4f444841d350230b43a34929f4478f2d9f475c407e310f421f7037bf3c32f9af202ab22bf58225ca9bf959529c3fde457beecd71debef8c7d7bf790fafeb26d4f00eaf8c45690d4484f81894ebc047288f842e864ae5dd717e63f30fe0f7e9099d78e20267eb9014eeec1aa9cbfa1c29a764e8857ddc046c472571c76a7180935e7bd1751a6da3a385c717de193dc618ab3d82d0a62a5d1c78ef9ce3c4c21d828b17a92153b082d55bf26fe8ee405ba25812a2059ef3e2d5b3c08e1e4e2254f6aa3d00a3adec52dbfe381c871be58e34f3e12daa2c770cd5f22d862941d561255cf9febe4278e9537e26bda5f98de5a05ba522d6b32b9a871206717471e9d356c7c217b79a9b74027a005e99ed497d8ced0c1d2be0f128b636fb48d62b94435912076a3a6af0661e988334a811bf16f14ec11c5d1ec97105995d75a6c749b7b60867b936f25eef0d9c625a23d68cb8d1cd4091eff1376ab2fd73ff2f378939a61ac86029537033a309b55503cfc71a37c9c8bb520d490558ef43e7ee2f9989e768a116a59bab433e40916dca3b1a006c656df3c35fcee2d63a72274b18e4d00be3df8d8862be8fcb5267ec96dec0e9b3d92197df5b7149dc4499ff5ecb98dad37d8a09beada0811eea509675f3ef31543a3c13be9605ba1a4589f958415b83e2caf252dbcec250b0fc161d9d375a0bc8a9683ca5f85c5e6f4d5aaa1b910b9967b3f8192985730958549247f343f0890dbdf70a3d3762d5bf0557e6ca8f742925934a4bbabb9bd8d27e16026518998ca7fa82ae87beef501ac3edc07a870691796d596f219ab681e875ab51d839a4505bafa83e2bed1dedd49fdb264d517529be32fcd715ef17d80ec8ae358279ed81b6f1183394740840a0b2ad2030557cf316de275d681e3337012effe5190ce21b9430db222edc13acd35f375a0ae77772ddb6f2ccd6787eaaf0c990f5ad8fae7e173bad8f245d5e8549dfb8c029fbbd9b7b5c2df77c2426ed4b5d60da0a5fae8e1d76751fa037d0553e1880220f8bcaa8f64a3f56680422b2a974f497e98afa400495e9732076a4ae8c98255f9275e42e208342d6f246138995d9ac7c79b228526a9ab27abafe27c6511208e590aa337a9a103b160b4f813088d181c4c5705a38aadcea33cd03c91031795d3aae64bd1941b4fea2ca9756c68aeec60fc29157ae079287d91228aad35dfef783f1f0023cd5f2802388d3fbfe90f7a55f4808a944588fec7d32d33ed61307187edfa11785550bdd865ae1d4f6e8fc2bed56c18c8d47d12ae938acae5ee97d3ba214e6f436ec572f91571c7992874407f19f905a73a215283ff9d757cefbbf830b133b56e894c8509c44dea4500d4edc91d1359a36b4993e1aa95be9e465ccceeb7f58f330168517ad399b4dd6333521c283df6af65671a68a3a9b05784fc3a407ab387781345b993e658624495b1e7fc6d0e3c2b729fa780c770dde12dc0b032dbcf82dd34bb505374e9f484d4c106d561f7571539549aad9c822db5864660b6104ee1b9da543b2d2ee6abb0b590f78669af49bdbe53935ff54cee30db72af7f92396f1220bb10ae1c4b0c5fb673e47f6556b4e7aea580ca110bf5cac5953f8880a50f4548f16962a833b46154603acbfdddffa7f31def536954efdeacc2a50507d4d842fc5423df11723b71178cb4cca490dd423d4568eb060945524b41a78e6fbf271480bca18c7fdb9405e91a42f99e94e9de5b8a79b96c3b8fa995bba5546e9605f85bc8a4fcccc846f14d58ee5d51295d9ea76d4600749333caac56362c9796c4bd07a8c666b10018a1a777e3bf30688bdc214941d86cd919a3a52e9a836a52e6beaa5" + }, + { + "seed": "7281243ae37e408a85fa3215fbef23c01d93c4cda21c9b8ac30b324f879278df", + "pub": "369c0d9ccc87e5d75f32ecfa5bb28d1808e90d2c424f217941fdceac4d45990ce226a21683f91056d0e91876e83e4cdb6e3bb0a4cfa3e6a9a362e027df322ae25817572035ac364e0094a05c56df4d4dd985813cc0dc1d867c2f977aa21c1a9b382de750887066b519eac94f6c781e2cebd92cf7bb01c2f18cdc53296b733ca3903590238fbdb5e12048707098ecbff93dfee306fc9a350ab1b57ef88267946ad21bf3dc007efe13b15b1f74a15b92314c52b5d2cf34018d137b99d6a77ce1eef6a32878ad1fea92121a24b7b13a56d01cd5b0566786aa53ba897dbc16f43520122af7adabd4c7a4bd7a5161ab01d18f8cd2bfbac06bb68919c8f08d77573754da925ea818f2443dead9aae3f3be8ddca266ee3417a9539024760ef5ed3441ea6e0bfdf4f56b747510361464a51b782e3daeda80addb8e964595f9814079f170e8b90fd67e6bf714a2b1e17060e0c810586aed3120c65bd1eb4a2e72f54d432bb1d2faa2e11252577ce450101a2a3cc642104ab6a7138826f6c18aee994c4215406ecdcd65d4d8b34477afef4bc5c3ccb63de054a68a141be12812a2225716a7ebe57a48eb911d54878d6509388364973e7e6341c82325440eae82690eacbc4a746a671cea6883d3112a6809876a22645092c2fdd0e3a13ebabb704f845c24fdd5841d2576e925524339a7503062bdb61f3389619d98c23def95e3eed8c1cba8afe3856adf912796eeeebf9764b40799decc2a108b58b9a3cb14c8f8d816828e97d6c2cd21481eefa60883145ca87c7666ac8cce3015c5f02cbcfe4360aea42f3712a8969bb4bb36600dd04502726a1e2e056c184358ba2fe7d0392ad02f65c9039616d02d14847b94277184ff36910fc6cdff0938025e8b6ee52ff03e164bca31f69396cd8de22c5f38b7b031c72bd4c08da4fbba3b731191c78bbb4e54ebfbab905e12896c3a2eef1ad74c54e45c5a14a803166bb945767e5ad8d8e734984acc2059d47899a7efc9b42df7cb8a525a12039b00de623082e10f665410231537bcda899a9e9c3ff34efa45664391dcd578a18ad410638c50f91e3021bd7408c469c03f7f9039a8e2c94aa1862a6759140e08a77b72f617c0d768a4d05c8895ae85369e1e5768f8e0cfe1a3e46197815c893d722a41e622015fdcddcde472963d49ae96c504eceda30999ef8ef6d969a850fe929303b46f7079163e967cca1ebba3a6538b7adea38d9f9853b1000059c037e79b15b2a1ec75f1615f42d945adb15a35b0dd51df037bb63514d5d8e2fa8fdd85c30cd428d29df0823bfd0027f5b382c7221013989ebaf24ef2a1b96a5da29c3add160a910aa20ee838e2a92540c0763d7557da32d7e36f7e757bacebad9e0a5c6e1f5ceec14609202d241f65d94b1b06c856fa0931a3d0a0cbde9a39332c3272aacb8ae73f5e72d519e1f18f51ecb7968d67bb644578d7a7dbb579cb41cb98a2fcf69bb0f4b42e791054af752c5902901a7bd70551d33af9ca0522588d545efa60f5a5ece363dcb5ba6fbe9060e47fd3da95f7aa07b10ade2e5b97d12e765f6a052a03477160220975d57e02a9072961badc5a94e752335329e9cb8b28f00a3bd9c47709e0561221246c713831f77f8c349588ca8826f023f5f7b3a839f5ded929623f290afc202cf5c52dd053694ab59ba267ff3e355363e6b22e40a250e964ceb5e869c36161ef1ea2f33668fba2a35879f6fe207b6c99f48a020f67df87c83cb44a5509f3cd4162bf18a8334ee923c4e1b396cac249077be939a16cc71114eca94f411e48ce334abcbd97f52837c61617874007fe852520a75f644015a504cb7aec3188732c1a26fd2b74bfbc", + "priv": "369c0d9ccc87e5d75f32ecfa5bb28d1808e90d2c424f217941fdceac4d45990c7f843beacff15c1822d9b2b6824dec81a230101c6fe668e8923c394b7f53912d852572db1453b969a6cf2fa57d5f39ec5430b2b5cb328fb2be3a7a431c2a376a3357d12aeecfedcf845ab60d3e6ec702c35873b2936f00a6ec2ec76e9f6b95d30b21844b828c10b210cc324e202204d03250224951a48491e196315a30104210401943860121515318909cc8281b24489c961120a388c3863084902844100c6126008a1405c4380198b62cd9326da2802c841082183462083146cb4888c3143241a0809a0482da266d44128de4200520b27152c844034689432249c4c04c4a424dc9104244406960c460c1c44919486621a62004c00d08023104384e8116718832481012690bb74809988984865182228d59c60564402ac84670a3482ed8b05010c37100230553068e2325215346241006901b8580c01289c4220cd9c62c80342118b10513205103474149484663106e0229909cc46cd0a06c119769124569938825c01272889881cc204e584824c2883000a925998601d0443292384e0a9124a0164a02a8315b088dc93401501665d2482962242614184aa196058b4886042270448665d2b6684004464c022d4a8240033029202741939491db328213250e9c120de2080912260ee2b080dcc861a1c040033961803411c8c2851ab35148004dd0144c900684882284a222695922500416018148111a088921b080948249110225023692a0323009b60c023185003730a1082d54326ee0383181420a49828c1ac700039528dca24d04b48941940c21a161223186802484100791094286e082050a8110943652ca940850306e0380315930040aa56101842cc336829802464ca24dd4940c6206641a217262a2290c088864346023284881b40dd3c664984229a0006a82425180120801850cd12206d9042c63028d22936d1c4851049388c4822408c168040188c9405023c46503294e22120102182883a24902297021978463207224472123210e0812241b4530e4420a24430d1b848961185214350004a00592c09011167248b02c59265212182810058d03c271903061641069cb28090814408c9488193412989004d142720930841a35028cc268880286a2828518c7905c92684414810b2986208305109161c48284140761209701dab60d11444458008c8c3024204922138868e0848420990ce210519aa2480aa65061260563442c0103611d9516c41ab99b91656c201da81367a60db93d042b8dc93fc34fd7b7cc32941278a352f59d78ad6909b5ed50661985207f5ec31bec64ad46a105e31741dcd901ea8c8d695f7fd9459a3bdc4836d993675126e05cf9dc82e0999510d27a11b8cde2398c3f3b6f730373dd0cfea39a1c107a5904b38c50614287a3ff6c837eabd71f489e76756752f4ad9e62e8437dde8e70a5dbf3e6cd88df7b01a41628745c99b66ddb12e2461c6041e219c617dc39bfd6caea7556451308ffadeb28c8c3f5eb43f6f95c56742de1847d7efb513b5b2d9a014ab4c5589bebbe57733b828706c9d3a1b5b58a3b280a2d350d559631da8441655d61bdf10f0cf10271cdd9a92bfcc8504b7758461b8199966019f0d38fc2aeb3f1b88b22609c1fd693a9f383f742bfcf66d13ed26e6f9020b20bab66ca5fa9d49496f3c9ac017a1974f8d66969a6bcc5624934f917a17f8c115ee01653f1d856d86f998f4329c3e65da2953edd904ee89fd5177fcdf7d397d12f62e192cc769fe37a1efca4f453df26726d8ae7bcb0001ed56d4f2935752e571258d0020c8c4d742afa802d6efd039a8349bfbe91850d50cc96f687f548b3cbf94bf664116a12bcce04fac2ee6c44cf47e5420cd31dcd52bd9de4717fba584810e39a2887eec163f81f48fa9cd927f65516ba7fa8c188fd6915e383a81e3cccf9590281a5ef62beef96393d53d9643aae13955522e377f9506e0f11bdece484679f65fccd7e538f78696f391eb0caff97c9a42025d52f0350a9473c3c8dcd8d9a81bd25175ddf72cffc35f8c55dfc864f2f34299309148206afad79992324d4617d8ed7e28df1ab927f24237c966dda94d4915dfb25e7d2a5475b2804240852b230b5d60f26aeb722efe39e93a5f00ba95f2d5724c51356a0ddbd188b14fdca17f958d8bd47d214808b5dede4b91da79d489b3bf32c5c21f81f66e1046a88e90ff278bd72d184aa47ca23c90f31d9d5ed7e739fc02c62f162307e46a1fc9694bd9300c7209043df135c0fc7989a8c4f59fcbbbbd98f7c81bbaabd41bcfa8d5b937dbed7fdebdcea3534045fa4ceaaf091400691b35587a3844dcbd73b7435670cd1805ceee0909ee69a47ab2a08efd2544399f5957ba41505bdf69dde4213349e5f14866022ecb88d9b9df3b724587b924744cb7c126dab2613b16ab76967effa8208c1f10b123bb1dac7bb3656ac129e5ef50fcb3f374c0ab436168e5c636c6674c87179449c40533bf4774818b2bfecdc92db403e765a93fe340d5d71175460d67696e3cfe15e00ea72e5cd3e3ab77207f0aaf769c95ac6664904bf1027777217a9586aa12dabbb62ba4b4d5b8910cc78f7e0a1a49c025629e301ee46e50b1e3f5cff59702a288bfad92f4a0b4356db15089cc75de8c29fbabec6061ce0352edd8f44599a6be82e53cf2a581cf5e6d3cc1cd37a7128087f26c64fb38bebfa1943f5af74b94313b914288198eda934c80d0f8494a9ee51781c86e3aae09eb61e461daa0d26d70e14ee2a339a65f01c4d74de633922cc51350e19bfae401950a8e439c6385ac3b6ad4314d905a7cc6e65c775bbd594519331c5633f4e4bc4ea78e2fb0a4ed08af87515b1561a22d40db1be0576b85508ed0d362724f1aa161e1c9f11fc57dce78354e094d7a57eed25539198965703072c7589f88352fd9e20ef4a5bd420534f5b08a30e73144b293ce93034e4f2ffc909b036a85dd3842981432cc8b0f9a2ff6dcf81451c7c01ae120d2b05262e558ac449d26a2ab27d767114067943dd1b5f709870a4b846d4da72ff169c6160da5de1bf51cc4b16b1cb2641067cdd9779f283326dd060b1da9998616d898830965c46af9db26777b87bf39f7c09e6f24d9980111e19b497299c8e32f9f3a12d0ffde23e003faa7009f0a86b119070ff9987fa06e04b557417b67dedf5b03d41efe8c37de023e5edbf3e9515c0ee3492709f575c5e9c35a5550c01e20c371104539a5c3879928badbb4fecda05592b9767070e56c211ad1587c595654738f6a2daca2a101a4e654af5e107fbc9176e462f9601d8b8e6541fa2807323d470d771818d9f0e85aa5cbe734b71b1d04e4f3d95ebb72d8c8964dd357a0676f9e5da9f432ac61dbfe1c051a56fe8d50624f9ff46007935b22db908cd18be33c192f64f316f4a3adb438cb85c3c7f03609a69ee6512e10e8bd97ac978260e7eca9617c8a5316877c1b7792891e20da55a93bef621129973033e21feafa742899cabc86db320a31444670c0bf1e34f6b80923c4de05c6f304913c03b129b0e9d0c187f5092b059d591324f675350075f56f34fa4c0a77a3925576a494b927f74671d2ab8" + }, + { + "seed": "2364ec1c9100926a264bea5ae8110c38a7b727dee2a886ae2b429d78a46e21bb", + "pub": "dfd2974dbf8336bdcd77f988f5e598a1cd246c3449e0faac6e9f5567ffd216b791fe2035758cf5f65a2ed353d8aac58bcd96d0ad6a5288fdad24046989379d4625056b3b1960a198d005f77096f34799ceac84cfc65627376ff9d0018bee8ee16c6feeea01c7028935aa9dccc343b85f7d4d3e7d73e2211d6edfeb20572910f59f663622202d3f55862e969b263da037d7259514ade7f6be27fac0df5b20fdb28ac536e22bac2b60a36c58ac1743e96cb3e0d97a05509147413a40feea3212d77178653838c88863788d08be9b12b53e15e78e425bac4d08b162da08c31e87c65b775c308da2070fd9a181a83c0520d1f2c05502144295894d7a00f1beb6243c3e119448fcba17bcfdc89bed4ff0a0b37cbc508b7fe0e99288b99588a339d7954574b6c65e2b4254d10d549b2fc9969799b3891d14b7cdb802914788744f3dd2626009bc2dcc5421491ffbc1c57329d59d1fe7e5e34c67c4fd7ef91dafe24c18fe56504ebd1e0052a13f2b9ea14ba55ed73f2d662dd31cf0c67795f56e5150a896431cf1bbb04fc19dc967dcfe361af8f2d14a5a0be95631512b5777e9da80ac91039089d04555c87bd4e3ab0f8a4d5f7a72993ffd16625b457286af6c6dc5ad172fc8eda6985d2c0e3cf3ff5c69eff8d862414835ff3d23a420c49faa5db4c1dff884bd7df82a37d680e609a2ac44f7e773c6108895b8cebe12b4ed89071bca0c4049907ae92610db9bd42e41282a52a68c7004c8cf9eb514574616574d7ea7745c87e26b1fa18f15337d13613dd72957c033608b1579fa67c7cbd561e99d62a799827768eb536847ab97412aa3760e28df577b77525032df710a70014d369837a4b536066c200bc458ee06ab1ec222f8557f152bca1af20dde19f5642ceaa0f583ca7f464668f940fe75c29f4504e639bd550f35be51a08e3d0d55faa89ebe0e87308cc6109d3a5be4ba7cfe89c8866f806a262aaa60d12016f1e2d158931ab215760453543836875f3cf96fa80e410da1b991ee9c59a3f5a5305f5fb6813be4fe53f2c1fb487f814ea45ca388d51ef9868830135bdda1b860740aafc15b8a27ff05a83af6af4377fb11728900ebcf3c4129fd3eb43aa4fa968cafcc6c60b00e53b3c908d70a2624f1326ca1b83d21eada254a23444990a91f1324515913d4737b12f659418132e3df667024c4083728fff3e76a83801adcaceeb9bb03f8862e5318c13ef9fa3f21b173fc71b13b2de21faadac95bed821ebccff8701e45b323504d31a162a2997d46cbe676c8ab74c3c832b0e2b86ddba51b68865ccf171a5fb56749b317be4ab447e62b8769a63620d91419ee2b27c9102ce19558289b724fb62d15cf61111efd3cebe388876778dc7eee85cfa2356f47d6342201e303fe6b60f1c20d456fc64696d141e996c361adc190739b9979826e220e92312e1a42bf32103a5490b1cff191340c0f3c6dfa414a29cb0fca6165645921d07f63c3eb6064cbafb1222e8f773aac392189822fa81608d350cbd0ca33bb36c1368931dc81d6e410ed983f05186ca379ea355122f495ed70a2cf13bfb8266d1a614d84f69f3d55c172fe161eea713e42130e3dd06a141225923ff5074bf250b7c37ef9fccfe56809f21dc35b42d80bbee1e791aefd1ebeffd33e642670c19fcd7ae449138fb52c6495592d4756a1a7332978d95100149069165a4e3a2e6b004d738216604b6dda0d8622bf1f4e008ebe4c18e1216410cf70cb1814e2b8b7b0bce33475218d6c1fa51d7e57e50a637e6b0a2445f37598aeb860ebf0f19c5f335c71965b4e0d2a659c2c9207c39df1956ce5ba8732deb694df9962331f08cc9d295d322075", + "priv": "dfd2974dbf8336bdcd77f988f5e598a1cd246c3449e0faac6e9f5567ffd216b7921af9e633839156e4c53d6b0e84b71c6de7e0266931b3f10326263f74c8eb026991c77539a275fd8b612f929f40a4cd0b26d45b48592b186a8af5a116c35f30613f9f637866438e1feab9f26ba9cb5699edab2371d5883e46633b9c00c4d29c18a685181762cbb44444426d12c809183701490260d4420243062d54108c63200e13a8891442904a16810015700ba88563b820d414259b482813099023b161d010295212016110320a1166e0b4091217908208121aa88d92c069c144405c328694b28414032511378200446d98186562963064963162380198325082c40c11217011276113483184366ca1b8080449120c36021cc46d5a96844220919a362a092689cb380d0885050a154e640285a38249001489548220d3868c59361252406a0c06654886205c16018030695b8285c0000d5b2621049291229789c024220a262c63482919900893c404e3428909856c190268db14801934891ba10d0b406e1a3590a0064ce012829380055ba64dd2b050dc22815ba6481819011b4329d9b46c14b469d0c22450342d42a044234931012792a1b0481b27924018110344415c248162b88d084846e1381119406c084049c3025193c020dba48cc1a0401408650c908598022892140202b4201a874c0c09465990491002400a268c22b0659a149064146c11a73104341249444a9c1291a104028cc87151160e140980dc883162286ee30862108460939860d39280838288144270d3944cd0446008078a120290cb040d810460e42012613285a2b6419b1665a23892c41270cc9610004240d286059446665428868312328ba4109b98305c880d23975009a7295a343103a16d23b22413060d143120a4a82d1b89600309721238295b02660cb90903b9801bb86d22c990da2629db040a042942d3b631c32485d0b0301b3509220064a3460d10a5684a282dd8406e81a80c1ac30563464e200849d3328413968d12c270cb086acc36091bc808a41892903212dc4822c24242a2088980c2281a124819807081102d5448660b037108a38922164c53300e44c231539021224188e030028c9801a3180100254e62124622251221426422b34c11442009a909130325139349122425a0826cc0b42142107212c109980005da36640cc64c98088509806502267054b6714c8830c206688b880da2206c6342605c246621324ae1288493308a6230320ac251a3087294cdbadf1dedc042174ae5fe4823776b52bf8bd2b3f4a007de28b3fa1a9c3bb8b6961fefd9163d024fdaa8a700b34f32da2a8d72e64b09bc1c1d37101c9813d9fbcfad2154d37689de21ed3fab1051463affebe040a3d0587e9c62c8b628ecc317ad53970a56a4d9436d15c15c47c2b1c1477830cab461c3ba2631c0521b848304deeac12349052fffdd44171769d41ff8237c2622eae633cf3a36f2b563a8fda59fcca4292d4c2aed72259f6cf33b89a0843e6ed703ced3391301aa879e86ec920371e2413095a8e2ce6f2792e01bad7e4014f3c4396e2ac88c0525f56eaecec05ed5455afe0bc8430d344c4799fcb580687ab848edaa42bb301700e2d10e592aacdc5f2b871fef42b7958dbd391104ba3b9bb33e5b23647338f5d3795c25ee532ba638bc4ba71448aefbae32c7db33cab9c3a20020775800d8775d0885edbfb03149cbd6deabadec00644f2109f373bdca74fecf77465e2be41570199ff65bec45f5973f367245fb51a50e0a551074777230f12a13fb694cdb31925b3bf33a62811b26eca50ab64dcff5b9db599430fca5eef60357cfd7b15239437c308c90ce08ba3da25b95c4f1e72f07e36746e3598272269a259a8c4c78ce848e39204b6656e1ad5538e4285ac23a8c2fce93e5b8557ed8a7d15e991f675534cd0a3eb1e52da1482a5e214c22a995a60734e7f493cec48f53e192468cf80964c017b037f7488d7fc135a5c65200cb797e94dbc791a38a94db9d938ae56faa25231a634aacea8da1be0e78c105f2d6897aee15b6fbd21ec013c69bd215dae73f9e242fdefc69bf9124dcbebef1b1b9eba499e9cca131712cf2750dea81bb2861c038889314a33bf0c9b1feb29c3b66bec8c9427f310f8f22ed9d2cdc2dfda34d2e4f44ba661b7c9da0b7e65fc6fdae97c8daf6c91bbf1d28bf6e8a02de261cf9572631b1ee941732c54df6d8adee1b82bd788bb608b5bd63c2435fbc3a2c7b7123e3cb6e63acc1cbcb80372cc4044dd59a73d570cf1f6ae011ade02bb59151dc08e7ee4deb1d839d41cfd1a75f02efeb9b99df88e4fc4b9977caf95a0101660e23f5ec501aa1fdb0c7ca61ae9931d1588b4353e684f047661c5e20c549e902bcdc4dea9631434978b352321e9afdae50057401efa7fbbe23468c3077c64afe2dc27f725e167caf3fadbcd31a1a0f0b59d1cac0ca2969fca6537699de9a05648694224ff1b118f22d9b9cfd24cdab13dd20f7e1936c484e9c9fdc3662cb8748dfcea001a50e6ad8e460fe34a1ad31093f8182dbd9ef0537bb6ed2101c2ebd90e5f4d7bf10fc65f6a5af886acd262eac207317701585ee358661251aee01414ef3977fb1e97e24d095480764ecb783255eecd1588c76300d9fa8987047e63bc2d9e96525b7cd0242742b50ca014fdcd1d0a238eedd91b4e698ec5fa54fe16b90371803ae3e6eaa759c23e52190e9ff1156580a2835672380492c2a058161b972e78c1d3261e79bd0273db1ed90a694b8a26599203cd2c633e15461fb25fef3ead91083006f070e84f598142acb5fb7af3233352147747b60c113fa0fbced5a732f2aaa572393fa14516b0d30fccf1e8d69dea38821a7d71276ca349677b14467fbb736b7cb30463c643ad62b140c6ae6f06a94ec45c71d7cb5d13bc3a10020af35fe1923deeeb5b98464b96664bab7a6aa71ce53ca05205e3530a5c159b9cd21519e642510bee23d265e291c62d39795d838c07667d37de0bbb72a649fe83e64583d2f5640cd5dd699f8cd5e74924cdea58f1ea2173b832057f304b03a859f2ffda51735bd525b26db07549c74ddc354564b6340a8f08fd2af97e8898586c24641bfd3459d5a9384d3d9d50f34d66367272dc4659eb1cccc1730e73237a0b85ab6a3c70be7b02cfd917c005b0cf4a9310aaa8e5d3578f39929f7ff07cfde274cf9af90378e959db1c6dab767785cb87da4dae0b882884e6d8fffdb3caef8a5ce421e25b82a438042eea8f6aa714e0495ad00c698dc2a865fafe4e0c5069d25304fd06e7507dd3acd08614642cf5ccae52557fcfa77069d81798d6dc2272ed00e766f802d62fb2b194f26036a0390d40614cda0dd3a32878a0ef49ac08e8e2409da902dbf79d2564b330739e4d286c0f15778b6bd152088fb3b8ed1fcea0d6cfdf0c0f2d61c30c73497655132c8ddaa9ccf3ad5ef15ed166d4c068c7e016572ab5cf315a368d029ef8d55655658bcb9ff93c784bba2f99431334d21143049bb72495d58814b6ecd46be0955a64ab8dc1b2f003741faf16511490e44a005dfd0e5937b4362f69a668f4298ebd1c1d5ab4ef3e15d9b00f4020860b04fc947be833364fd" + }, + { + "seed": "c20fb09de53a48d6d0829faad50d62eebabcfe8b5b63fe9ea919c5ae78426c21", + "pub": "2026a06b4cb341851ca99f57409b1f9dc65395dd1f994d71a0fbdeeb387b7570bbd415bd802533b3a2866367a2a4ed2c54185363f43c3cc51f2a589953802dadfc11de53b393800bdb6a08854ede56f9b7fcf9be32d5439ceb6ce06565551fac47b63de0e71f6ae78b1cd875c0736cfd81ca619fc8f9770ba18061f9c432b507add2a7ea359aa6c8719ef40c8bbf3ed0c1f0705b9fccb6af791fab8e544b11001aac57979c6ac8ae4f935e10f2ba32811a0f80ce6afe464f512727fb5c2f58e0fdb328368088cd94f8caa32ae1a32323ed0dbe813058131bbf85667110b58575279ef8137190b5084210a42810bc7a829225123ff50d0d032cc2de748ceaf86c0b0ad797b368e6ac26de6835270e8b9a60f648e3d1e658af8fbb09622ed1c03ecb72dad6c9d9be39210c5f16083a7445a452960eff8ceb87eef49b06b9cfc130f21653b08f83421a7fcd8b41f4295187179d93aab17148a7e8c5bf1268804440b5cb05c381c0dcb986e264894e17921e3719b0609f39ad83fda5f540bcfc6024940764d40e2e125bf61510b83e3a363cc5f4e75b77debf3b2c56d0ddcb8ad50f149fdd4b1a3a764b71a9d69c3df77c34e881ab2d1726a6b4de3e02da13bd661e3291613f3f0dbabb8fdd98c3b853c5ed31f5bac6b2988d2f3c70ac0879bbcc82ca6810bc60564c85058ec2d16de1d6bc72de9f1bf4f68f6a5339220b2bbfeee73d66a8ca67e8ddc35673af60db490b01cd92b1da6f3f2e040bfd65f020451463c5ad12007a6cc2e8e41543a3d193acc5f4d1073e152da76926061884b903da45447fd000dea2e7d5d95a35a7834491cded0df8e3b18044430e6ec82aea23efe6aa6068840612e44f77926905d9508e0e298596d740fbc8ea3b0c6de4499729be9bdea7b29d200f872eb2b646880b3204cd5d800b728dba9822b16c3723a1e6bfe0e0425318388b4aa82d3e8f8004ce98924d42b8b10d5af391988b1899279ad244534ef949c35e721fc32217509faeba18602f5611bc0f305e8566c9b1ede3be5ad9adc5fae0ddf4137ab164a2bc2aed4a3004af9b1e8917401711921ccecec8f08523f259cf59a4b15963cf63a442fdb1c19093cd718073d00b46e98576688b9991eed45f04f9554050938baf9efcf7575c5adf894efd3f8621ce78272d39551e2ffb1a4ee1f08ee7c575f68f0f9e4f34495953c146bdd01936006acf8408fd372634e787784aca4f33b3709135cc7e4b85b7a45dcf034fcc87d3a1b846b6438146885a1e0a5bde2f5e2a4f88e3525dd27ba49fa0fc95112fa160e181a0a0938ab14da27281fe49fc439dd515a30b9d8f6e13159c46ca24c16c7150ad6624bb11c1ed440ba5a2626fde76fcf4ab71b90e0466c06b2d125e08a1b56d734a15d13c6c555ab57faa608b5fd2948229ea2e7f457875f8e90357f996699eaa7d21d3412cfcf99c9f55501264a7364678e8088962c1413afd5af47da8d449088eba76af5acb57ca27951dea5b1b288d69b79d16633f69784bae98041f3161a4b3e5d4d8ce2f7b247eb5e51681ab9efa19affa4b368da0d493c33b71a2ca8cf73a61a218f48e530416950b944085c8959b938e7436044b9230eb5a3254d4322cffd60bb950b7f9ea6679502057bc1f88cf624a936450f6619d7424c3b4e9b760a987ce29e85b8f394bf875e300a116232f772bdd1e53b10fac7f576a97746d7e654b05c8fd9e37243cb356a15d7d3dbe4fe9c8d7aefce8378bbbb92e4f3831df9a2ba0997149d10fc27e4f3fcc74bd45ab77ba7bf12b39b199d79a4bc9e05d47116e1725620b0053c7c2cdaf120cde871c41ace21d185f8cc11aabb6a70204639d72ef", + "priv": "2026a06b4cb341851ca99f57409b1f9dc65395dd1f994d71a0fbdeeb387b75705eb488b5c6049fd1d29e8e980982c8c03981d1dffbf190bb377de0aa6df490e1958923ec87ae5c17bde39574169a3030d0bf3088d0b81420891f3fc2ba4da846d5319fd93c39d09a726ea607cbfa8fa688bfa8cb67fff3d28e18712242ea00d1912285e3b830113805e4288a63a6011b10824246414a244e0b262492422a0041720433200c9004da064a50026a08a820c33000c9928858c80940b60402a77148c60008176610422180086c21a9441818821b18080cb56580c60914222dc0301111a12c59220548c61014a680404604803428c3200119270991b6254804301b45894a421211432ed0408401a10c88860d142290198305c08490d9c6691a0608c8048948926d53b22cc41208039405ca942920274140300e0cc03099069240b22d8196491a1571a1888dd004401191041cc40412220954b8080025101916661c2900c1c425123760419048981840923401c1b41050344453442101258a92162aa1247141882820c8240185290041209b008558246ca136011b31685bb68540124812480a2408664bc88d448205181448e22406091360d3c6450b31424a98709c1631c8b4911403098cb04d9a045163262c0c1372010428cc4830e0884419356ad2a60893000281b0841c9084101890800486d3386224b068912222a0101043b204000272044426d4c20451488c0c3130c2224e1b908419056a2301221bc124a1022119818899340ac4a60c00053011c13012206d5c240c88300a0c370e23378119c62521a64011316d53008ac4220dd3a0205948114022450c392201211288a66961206a44b829098105984871a1104e03b1404ba48582b665628289c3400a18c86dc136880a37494c362d1b300910a7910b2226222362028170182141a01868a412311a074a8b06905b166523126ac0282e10808d19c229a442609ca08d5ba848d8a41142306249a4090b11402048649a44850c125142408e14924dd2382822c12480328e41984d110872e3b20d6490850116425888049cb60991804503924951066400248600896d4b862c5b268e5840251a826c14a011131980da32680a140054a2255c260c0233041022499cc821db16819ab808d89848904249da12700b422403132e9b1642d02621da042653a60c0bc600934629a0240622900080382558320189264484007150940c0c410919091019052c13999140b44c4336211c072d85a410c5e8fe076829394bd74c77c20fb70564ac016b635a7391c0a7095d730c82b0270f500c3181411a11ce30043cbaa6dfd7a8de2d6a5a93096c19babcf25c2de297b9b0ce13f0de1c867b1f45c2576b09e9cbc7d172ba245cd797487891d0cd55cddcdadfac311f95c78e465c6b7ddd70356af3f73ba73db07224f80038ffabd5865fda4f822cb45dd503c17db5d0610be05479335ec4c23ece5213fde8b2cd62c866a92374f57274d692adcb455035f6fe87f31826502ea74ab82824fe97cc67ad512e2bd1a039bfbcb0c4be810b137a58bb582d04961818a60d850f99eb38630227b779714742b89ac9f39fc362d6352b64fc17ebf292a4a8436abaa21d8ee7a0baf37a2e26a3ae7182aa59a6901529b06280f0fc504bb864066b92aa485ae1dd94aa06c81afb05365547604bb72c0d3d21602f5f0c283e29339fd129339ebb5b87abe7d6310c8aaaf7b34b94084eacc2706ed860bf0932da8084e959a4aabaf352e18c25e3cdbe8fb23754c9c0eb9981d839ff35c53196b81b80ae969de58ac7a0fca36a27e6b083f38b582715c566809dbd53672a49c08123994a4166a8f8ffe92883f0cd943b7c36fe54cd92fa6cd2575a55887805792cfcfa3c2c0d1abfdb5a02acb68bdf2e5958b3724c6cd9bc630e1fc8d51316ac7904b303e7eb1e819118993557079ccfaef0abf2803dfaaf0766f0c45374bc6ed6475ea8b91c08d89e0f4452aa500739e3a2229ec282f96ed6972c5143729ff36447daebcc9ad87238fc6d32ab7b7dbe027fe8f59c79eb5e2120dd4d5be7c3a413cb3bf339ec2edd74951902ca68f40e54a97b983103077a4d312b78244462d2ac675abe4e4ae67edf9c637d50d35bae58b8c0cdff2c8c97f4d8c78c7cee2c6c969ccec23cf6a0867cd821d1a4dd6545c715aaab46399b9869956da6fe0afe0a90af9cc6b2b7f3322f38944e3385c96dbf851fcbb4dafde6a649c4dd2980f2b2e07e2b91f2a50a6d0512fbe0a21d24da3ebc3332a70a327ed84ceeef3a84b148ecb67612964106b4d76eb6d4782714b696571d1814bf8253fe26c4a6ac4f8c977d48f18eee97b326f50a53c3b6d8eae1d37771ae4e2f8a62799c44f18db324e324552e2d41dd67b7078182c8ddbbb9f8d4cb3d6d711362e374ad48121d9aabd09756cf9f38436037ae91179ae288183752c65dff8774695d2ed67b4c5f598a0dfaafe860252fc424aa0bd0c997e6e5daf8610d137c521d75eca5d6ba82243d9a5e6d2c1fdf2674a4c61a03368f70243001ec5f97929a7dc669dd08e8272104246feb1b773fc4a7c16f3e74c649b931243d2b080a90368178f999a28f4f606c1749eaeef3320ca91f4f6049454747847da0b59e43b7cd1b156ae3a61b86a2cc5c5bfaadad30554460fbd8f0a6fbec2ce07a1fdd621de3a01f48af8e512bbe1e02403d54c4fdaaf9e64d173de655a53390f13bcec423899362370f1aae1f182a555f9292569c9ee54c18f9d786d41a68ed94d2c2f53f4edeaa1e8b8fbd3eb5faab48ca1e848f713ee7855753c437ed2ea0aaedb30ea9e904bad1dc618b4bcdb3a5c12c856846f950541037212045b8c06160e51f5ffd759e5f4ac4218e9b645d91894334e9f11b1037226e378cef117a18ca99604d29f3aa35be58f015d99b7c4a6a7c975c730ea5f0abc212176d96551310adc8807012536a5d766f7b1869ef4d67f1b03327d6107a13395827d3e361db67d2d7c9a51e06467c4cc915ef0b005ecae73b2c249d2cb7fbe55486e7542a34d781ed5a0e3f857fbb9eadee17cebbd03e28c86e561ba6f040af8ca094d072ef0eeaa4f705c49698a368cd2f1782efd5ba74052585dc4e8125649fbcafc76b79da9637b5a78b6982ce583348c920b045b3bc3268d2880c0e9e14eed9e147b14e56b2f27f0a8ea1a0e314cd89c2bfdf532b446748d04f3e0483a5771faf9337fd12cf6eb7a5a2cda2c5d6f380673598ba52a0c720bf0e40890091e4e2abae8ca55e9940613429cb27a9e03e3347594b679627ea8052fcd8eff8403e031c46dfc19ab176fc1a9cf77e985fcf7943e6103f45e87f0fbb0910b1a28523e36835a8e6dcce9e6b4e3689cb5480bcd34c55b518776db7ac11e2c3adae92ee578be59eea300b858ff0d293a4a555f29befa378b6f4f96f3dbb5bf79495361087c18c57e3460b9d108eb43517b1e694f9230b068f6f4ff2c5a605ba8d6f16b10e599ecec8ee3cf562d1dcff4535d5193928979c8d8ca719429534ff90b4a790f26847922ff9babcbfb1b78d4f1859a053fc9f96733791a53c80d2da3aac2b1eec0121d6921afbae3b7a978ca8184cc9fc3303aed6c8e35e3d3b35" + }, + { + "seed": "dcfbcf948e428c050997b712564ac092e927161cbaf6207c7357b798a98f9053", + "pub": "119fdac84acf828332c9ac840d2cee7a94104aa6080ab485441666e9a7828bf3d2529794c64f209e96653207145261de851a89ddaf0c075c9ed137a7ac46b3ae531f0e5384e296d0cb69ebfb26c0ca07fcdbb2d2178840be223b1128833ad0bdbe464e7882ad41b288ce553e28e2cbc078de78ebfd6e4e11523a31fb1323875b12c5f7d2c6f34f7325ea9214c6107a35b7ab94654eda101144eda5bf1ad6d18c011c5025b56b468e13ede987636a2cf02106239daba0cb3be202dc748e2168f718da235407172f065c2438dac719e1a0ffe8cdd6d2eb2e2fb8b2a979c0afbbc0dbc14fe38400cce683e25b40710163fa8c41bf3d7665ca86253c44602b9c0f69e9301531943498547e21d88133ba8d7da421235c22bdbcb6fbfab28f1abc42fef7bbfee3d0a8384fa4087e23e5dab799ae057d8810abe9e1b9606353c91d9ea6eca649a02e23a7d456ba915a8ff1fbd8e106d48161aba8689f179c73840998d17080ad2b564e459f998c11aa5d37a93042d351c11a0dd4a41c8a7bbf1ecba0b47afad8a8f975e36374d2436cdf6dc08ab2903b40510727e1969b300a2cfb796507ea25a8e6b33a7b869954329dea44d3de65903afd6fc9e042d81bc147de707e99c6ba52c37c058f9ae1ea0c76b2304442edcc8922b0a65f964da55bd54857ba09a129cc50f3cb95d7614d9aa7273e37a7d87d9d8dda1f8aa84146f5b4e0351e3c3d9901e50ca0e65b4f67c8b0370dd370d744d3bf3bd3f8309b29a67c3841d9ca609d4d45552901f6a16c50d3364171ae7203965936f0037e9d8a12079604424247903056e8762643d86738b50c348da557627c635c0ae5f282a46c04daebdb66899e22d7bc40cc42d3c5ce7d02c7025666fc950a70662ab01364bf71bc9f45d360f9059b90a6d7d876fdb83976cc9d9dafa9de77ad701944321fdc9c7d7977cbd44b3f7818d2b2c9183914beee22d0abd1518d369202f83207ea9d274e159adaff04bd8f223c6d77957b7f9c3ac0702aecb8c16ae836f4cf43d55d8a0d776dae993161fe0fe62514b172821efdf5c804b260eabc657c891de0d6c80f4e09e48e62e80930b600cc8af77583bb16dafdac66eaef0c91cd370db29ea86325c98fc019d03094234cbd53e809844686cb11bffd28d66f5d358fd1076907fee9f999e8e4afb1a639c88ac8418e6d24fd9f1de8ff7d23256520f411b74ec77f4f3c16465eab779614c1058fb5eb7834457e7a10e4981f0c731235cfa7100805ae5d609962eeef4652a85bedb56fa0069107a3b8467b6b96bccda20a6fad71a2057b3d32ccc3a4ab4d8786d7cf5adaf45b3acca8ed5c230d100314fe2e405db78462963a37e2700e6f6c7292539c58df0ed36735ee2a67e215073293c427dd84199b24e24daeeab0e89deb8a179c9740502adcf45fcff42d327acefbbebe3bf613320d455bdb1d95aac066ff96bffe6642674d970cd0e2c6972f351dc8688a95e27e3e34fef40787477cc9b2f986886c1eda45c5c695832a15e1885926cb139d55168ad29984a00bdb989e69e11fa4013acf328b0f89d565c66adab4319dc17e43f2e2328d9c0854ac11e6067cc206b309eeed5c12b0d2fc2a3dc3de857b2ac4fb96f554cf97f1f97287b72f118ad8d3f96ee321c37c9ae617972b7584178924e67a2a0f05819cbda7e100c5366678768a29d21153d2d8f707ef7920f5ce8c8b7b78700b9aa4d87345e8e13a0ffd39acd51d508f30f3d1d710675624b19a65a03c00b21dcbcec6b3be2a81f9c654001d7e085ed7be1ffd0891f859ffaffac7a631c5d0cafe98d8aea1ba0e8d6f5a1350bd00574404466d1457b9f93ed257d367a65cc3", + "priv": "119fdac84acf828332c9ac840d2cee7a94104aa6080ab485441666e9a7828bf32701fba9a530fe070df5c4be4a07d0ccfb1f1acc157082166c977e831b5ea713dd906ee739a506031f463456cc9af229c9f93f28afddfe04c6e0aed9023d51bc08b44290d3d3775134bb6b1b820aa8e217927430b0a83607449afeef5e17ec9fc9b47113c8058b40880c934449c66d12236c4294291406605b208c23c98094c8810b428162484c43a06da2084e1893309a0010d9847101060012989019b16d8298014c120e600429c2a06d219964e328281440849a00861ba90012251083368a21124198a87010376e20920c2401600a39715b40201c23860c822151900dd1b0608c082290802419174c62364012208608c1408c920d22420e81049294344e04868562266582308810034522332e64808123002a0a4700d898095186441ba36119036cdb8480e2c8289290411ba591580472a3c20c98148de2186450206584c20860920164b630488201a3805004809024c7109a966da4b65142b224d1a84062409004966ddc464a19c4011c2382cb0668029911100480c2226009963011c800d920491cb1454a2611ca040e20c0880a340511932183a28199a02c22174e1ba5495b480011286ccb86211403400ab89113c680da9665d4902823838d1b1928d3828c1c300c8b34520b2140c80068232085c40285d0245293c06892180a08b5600bb38020c40cdc0824118205dc448c013865da38321bc20d12364042820590049003a50c0382244b16001a2641a114421325910131884326819c0049e2300054a8655c1244d4b4840a808484b0004c342a913029a096240a122a4a340609456e0193710c1164883280c14682dc006222014101422091444a03132901a685da82880843820b360481941120b50ccc0465e4c28159b6246210060bc33180a09049c444d9842808b584c280610a3144d40886990261dac885234340c8140e190066233205913261581422d8924c63100d58c62000478811988024906013132e8a1266611230d1008911c00518a731604061cc30252228121b264e09c220ca9865d3c48509a5405bc4841206068330210c434d203529503492221145580400239611a44820123405e238514b066c9b301203952c1ba66122196184c80504b80cccb830d1927082107021b16da3486a0939611191001ab40d94a4250821004c326d90142e201632c11288e1804503269024a46404338a1a856583249114b64101216a623d2c6bd9f37b757f061e3cfd7dcef757f2e7a45b21acbcfc13f6d976bb3b2af088dc37c776c944bd714285265b43e0b803236fff47f41eaac6cd0c5e141d6303db26a4f814edd55df1ea2b242bbfe6b2cfba1256eea1b5033afdafd7214834afd43cb7c7d4cfe2bc7801200d1704f5499ae38491a2396b0e35fd552355341c53118b4e115cf0d0cecab72574ed192a4ca1856224a9cae6c453c3a7151da831a69637158f155d3cb7ad0fb3d812871e407158a987cdbcb789acd4885332e285dff9e45a05dbebdeeeb0032ee9e72ef9ae3ede34b6bbedf9ca55a6c0e87eca4e66caf28c5dc19b2a4d9fe2d74e14abea2aa8920931ccb367e00375b9cd9f4312dc565b7e156a54552ff3c8b77ba83165769c2c29468b1fcfab649d3047d1e727a9604ad6217fdd2d6408fe6aa5565b55ece248cf369503303a935c9c37c508dddeb6b5378a8a95f4db557b1562ea16f1e79b1ba682510c4adb65220800a87de71e101c4b3654a52f50839fc02ec9b422cd5d8f553d2c65d4b06710b7d6ddcb7a3a5383dc575eaa0b48210f041ae23752af4dbd9ac595d6624464cbbc2bc888c06f9143906cf93894dfe2864d16db6c6aa9937c4e87c40de1bf4e639ce27d637d21ec9cf452c6a8bddd9f0b9bbc2cec1f80e7e6b8e0bf5ed0f82a95b0b6eb8faf4583734237a506b7981e269cdf97a6ee91b209fa7cb53c4aae4d140b9b58aeed1e4ffbc6f8282f6f0f63c34bee0affaffa1edb14a8f6d9a75123051f4b4d6434b5c0b0cf3f3bebc4dea7376ee8cd45daa311e1cf1f4e6078472e542d93dbe986d3fb182c1b67fd913e2eaa64f02dce1ab1a64145781922bbeaeff9e0815899dabcc9c2a4af263b0bdb26578eec6318909d685138fa78a80ce6f5c7df64c1ec24b5ae07390711ff5b3fb92f591a29bf2b28529757f6e0fd34e52d7842b2437d9acf7f07aa62192482233af509f16776c7dd0849bf2a32eb917eec35a9c037164777a38a214f813d67383534ba1096b9511dac61f33b17da4371212b4b9397546a55ce32b3701d43389025c1dc8777a6104959a9c95a06fc3505641eff2028f0916960c3b9e4ee4e5a369f413864c8c0049e98ca5a36f4d8d49eeada5f8cdfca0409208fb2f56c9ee772a7fe7090cac245abf2717dc5656da97d9edfd90a39d3f88a5b4eb604dc2c9e1e01df68a3c3664dd29360c8bc8dc30f7d7c9650782d996b9e80505f75ec8f38dfab8f513ba22a6ba77d783d20cd452c37731f7eef184639974ece0203b04575fdddf4e27e3286fdc85061889543a1c36e0a06815c8cd715c725ced5ed21e986666f9e123679ef3900a2445ce360a7dd58665c21ddc18e6ffb6afbac617fe1d7c10fa3a8d01917d3571f77bf07f2affda086e4faeb229a11ff3ca3be788b9eea5c2e31a9a634f0f06cbf0b14cf41b3f53d5399a332a0ef0016bb28f9130722ed52dc90d127f4197f5d5e7ab22f2bffd3ad4d48265b30ae2abd4cfdbf60b71cbeebea0efbd5f61ddcea1ea836e08f5019e934ac7df9eee81180d9d4172a2838296d71e9e62b37957e96fc6f2071f6714129b989c423217484bdc9bfd906c4eca171df450f5ba53c357e6df10ee74aa627970bd69ff0eb213f24d14a5fa9de99443e08ac68a78b93c48dfd53a1c7065ab01462218efcc210a6dc7bff8f171e20f3008be1463667e63fbdde47c3e9a5ab6698962d494fbc554bd14fd55937c26ff7ba0d54300ade2286126cc32601ec6c5a37057cad22cd105455c1b68280d639591a941bc4a4246365eca2109e10ed1870d50b21f1692d215b79c05a01c1ec073084e42f6a7b42cae174b501d6e8d37ddf55631d9f6cf5e7fe974d8fc145673c41ff991ecf571fc741c6a3d77ee4b01bf66aca240ae84d96d88d241a1a8029fb4c1a7134dd018f2dba7e607840810cc2044743530a3850fb6736e73acc8b598415eeb8665b12d89971d3f9c611688892a3a8576c7d16678051fc099cd7185cc7c8072e6a289a52b8305e9481d66d5ac752b5a736a21cb8d45a80425aaa5796e7a1faad7771b1a2a219e71b3b8331b5d68a7285c97dce41d53230c59ae4322c63cc3f13e8d171bbc26bbed3c05e09245a706954ec7f71b5dcdaf6461442a552ccca667056465a169fe74a6af24e77525642a9ba5f978aefefb825f5c0c52bbd8516ee1d5fe103e432d4e4c362110d4a5c22ba1771a2ac3167d0de90dc2261aba06484f78d405e4ca14963c3ca52193abcfe253b8ca0609e700f24c87b5687a562b1724c60128b968f5f5b2f82811469d5bae3b8cd2eda6b90164699476933859538d99bec39a8a4a2258d61a3e23129d5477124c2ecc63d08c5" + }, + { + "seed": "0ecb2d990d29d47ba6992cdce04cc510d6e69f051ae783a01b3163b7fae624b1", + "pub": "ef1d38e549cde7be0a196571a05001987cdd91e24ae270b41556cf1fbcc476d976979199d8b5a06a2eb9a46b95b5efd23cce72e272ca76911805957b216e02f43f750e098e12c0b1454769f433f3e229c09b35de6e34e3de158e734a14e0c101b8713601d1d227fd4e6e3ef0638cdfef84b0982ef3d2cf04658bfa52fa7155b2b490a413252f4fe4782b4f7a1df983cd912377f7861f6d078069ce07d8ead93870006835832674ec624132c3c4800008f26130c5dbffb6dd2dbe45cf32d1af5506e21733b1dc516a84af97b33c35764dbd3a3dc64112dce9cecb539a5fb560b411e7526879df5c280ff5aae4acc8654766517243a095b8a0afb72aa5577580c460e1c432dc5d117b9b400791108ef78359df2ad4047d4e012ee26bf76a0b0cebea23b252b6535a13c40c2a5d0a4a04413484b24c13a583bfc93894f0f07ea461ad4ed693605419cc7ad31b42d5f9d3395ab5999b02c896bc48ef1f22f853f1730bbebfeb0cc564007154593b5ab0ec9e81913f29098042e47371e41d6bbb2290af162ee08626dc7abeaeb7a634dae68895f8d8c20b8763d587f47968bbcfd3e28a58a80275ef6dd7561d28927d98f9984859eb1660dc584d2e1820d3c3264a0a50a0b7d0b15e2295f83d149325c5e1d51234e12514a3a0a353d5bc2dac4ac9e9ff8b38caba710aa2c4c177baed021f6a9cec9918d466925033fc09d286fdf78cc64fdf7b6d06b6cdcfbc773c136476619ddc77c0592f0c7fdb2a9c6d733520c6b417b690e97197ae6be58a3e20dd449ee7ce44a6f0c948cf9c665e35e08f3e9ca5fc46523e1a070cf98480d0406581e3be16d3ddbffbedc7916ec4c35e7f655c8761ca0d2718b5c32d76fd84f6dd3254b4b6ac18cddfcf07ab551278f981947aa9a05461f8addd00697d61d535a5c934ff9f86172aa0349052eba67d5fbaf0385399bdc6a8f6e95179e115a61e65407093b0a8e63938d772896146f0b3830d12eea22bf6ca1aa5fccdd9fcf73187564c2a96453d6277e8ad7a35cce93498ca6722ceb532ac4e564ced41b7bc891e7b1de3b32d0df8f96286d8994c883fd5d515270c9544851fcc43aaac2fba1fc3dac97dd231d0a35475261f64e8dd6a261cdcaee519f59d4c8e9784db11ad966f331bc35bcf2a79443c128fa6e52241ea44e46c24ee556e60526e0fab75b007550ed71a6bdcb649a1c780181ebf7e58c2f7eb8e9eeaf20cd461a3e20b676301eb08302c9b3aacc2196921bd451795c09bc579efc18b088fd2d2b2b20cc6ddc9e9c85ac863141f7c1a360ffc7603ea2d9ca1f5f5e20db34494f3c20477072f0f65922cfa0580c72472b28e4f7dc1c97ad949e9abd45da4a006a3abfdc990a5a060e45dfb50cebb8d98672c4aff7fbea13feffbca4ea5023f1447e2c1cc46b864b75cfc2bf3fc5ebe408397287a565d3cc746963d9e5e09f78d8da1fad877bdc6da6565933ed7950ddcd147ad9d7aae99b7516e4d55601af7892373415bb68ab3a461c1c4565869b07d8b06f81146ae685372e983cbf8e8886d30b231015d25a8ce970acf1a3ac855542b227741835d769abc6e5c290fbb0103ff1f17ce789101d7cb9d3037baaf4d839a584f7abc0f4b7fa79d798c13d799582fa151e72c655a26a2efd9da52776513c24a6e8b8cbc2fc6589b2eb668177f149ac70e246b9e61e02938c35cb5ec1589c17ea27b598ce70938486d9297944a2aea7087acb09f0ecb94d9b5b90251b0b7363a537494b2f4cd08442537f89c79383305d570776bdca36d5fc886e75674ce8783c62e0ad4c8cd575854fb6dc01f5bfb10bb72117e8f8370f0fb6b781c41e7d6c8e34ef651faf414f6", + "priv": "ef1d38e549cde7be0a196571a05001987cdd91e24ae270b41556cf1fbcc476d93b4411b33aa8efa9387310ecdcda0fd189749c27853dd11781103f8457081168cc791fd5bc4290df3dc45b434cff48ffda2be882d4c6b349a1ac02cb8ec51712e124f5b8b46beaffc26fac4ccaed6f919ddb07b4217bb2a1af343f2c00170352893846532045ca00041a42818b2468ca32844a828894a404da20710010095ac2451ba10d08428d9c200de20425a3128640926592b08cc9c0251ca9292218726138284b342ac0b40412915050222c18c024e0a44d48368a61c42d13320ec3082c92806d0b192993a6401c89245814421aa2608246891a440813890443442940162861a60c08228022a041002462d0b630c3247199c240a416248b4409522866980680c11462504866e236444b406e0cc16414a581d23492420269c190611242024ba210c946690aa5210b47441c05724a28011c0410c1402a59882c1c394a0a05444b182589b20942362d221448c9b40424c14412972c8bb22d030604e2c084d2a00508352902920852a471c4a205500212db9681088368ca442292385214344920204494a091dc9605d23845a1024640168018c44cdba68da0869042a48064048591c80191220a19b929d830251c106d88263113490e8b988de12468da920143280119452a0422299c3465c4086a8418298b34725a368e8110618c322d24b16814360ae3a289d2000a028110d0000a08384243440124980c59303243445242188d91024a58124ee4924cc2421213c9085a380a04b870d4168edb94854ac069d1046ca0164e493849a4441003282e99086a43b8111a21511ac56509486de0c845d2c42008810c083586c0462984848911b6900a472148066ecc84089c84289cc28cc8408d01c4111b8620193445e34806e1888454304119b9091c1650cc3271cb2051e0c40da3926d1c1345e3b020dc248c51986d1c238501856c09466209a02810386813186223040e90122122348cc330088486109bb0658c861043320404894998c4619182045c064d9b368d92b84848c4094cc02c53084e4a0404a0362ca4146944c42d8a801094906194945002120818218541168299424160866c12496221298e04014401176540b4900a038d143468cc8270e422818492251ba42dd9b4206406255848704a04511bb86c22114d2014918c92880a8609d340645c2088094331d3102ec1480604032d4cb00450224924482d8a26009c0061040485e2a48530148057e2a20c1be1d8a21b4b0f991a4e630aaa596ef202f4508bb34277d5bde52690dff5eb2253b088829d2b98d7f164f500e018b45e6129fe994ba611242dd8cf8b28595e4bb24e3274fcb7cd4f771de8e4b5fc36c0f26274abca7fbfb9a561b8c4076f21aa31307e4f40327b83d4d3f530516965b972def034fd3a2881ed6c50c49171662c6a649115c86f0f9ac445601ebc98801480cc6b79a3f6226690d0588b54002e3e86653e003bc77388b2e43568cc3a76a78181c3806711fefec1f3179e605f15d9b6fa8e49fe93ea68685ada9bf657ce1340d231202b627509bf468f64eb4ab3a0937f001c4d12c4980f2b35aca31f1e253eca2ddac1cf69c91db940183afcc98219bb9b7b2af6d0065e8274cac3e04b9869bcdcc1366c76989a0c1b177918bf6123d10c787a527b1416555bd07892a5e052cc83b91c770cf4f0b4ca94c2f47ab3d1dc3a2eed208f7253fc46428cb728618afcc1137114be4d524848b7c3636bcee764986a3d872303f715dc38eb4bffab92dfa2ea62670b073e8dc155c057a421bc86a5a1301081c348df17bdc3b78122c691362434c79bd24d45e52c9a25b972023230cd0b779028d73f11077f0f38c44b041db1e7cbc5b4787cd97a98073b57b785e60ca2b531ae9d84f5e9837ad4d61b95d9f1e4e01ca65c778279f0faac1034b49c0424bd7b9dceb6a87fe8cbffe97032b59f16a821230eb2a9cfb4139eace0341d330e82c4b90d68bbd8d425e3cc463ea77577580a655fc89e394f26652388a1f7dd3e440127964a75582086a88f5b0add29fe589318cd935860b60f13044317fd52ad13a912dc5acb5d71a5a9ae622eecc7d970e295496e8f0f5f403fbb9198efe003279c964310592587f2d28d94f47d33776efe3740c31e814acd9484115cfc5e943d9609b882eaf8c3670059b1a41fd13e816d9fc05a6abf7d632f15be8ab4309a1636431dae4e99baf93bb7c570dd2a30307677039f24391c9b308e386245342ffe559d5b2eb484bcf4b93d2315eec9feccdbac817c4ab391e5e6bf5f1901c743c405361e94761cb25e21585827a891bed73551898251f6437c469656558001a5e14987f19ad20d196b92b6ed66493f25653edf6759c5d4fba2023261b86055116b9f460259365eb3f6904dd07909a967fe36fe2cd3190204578c4b3679abc33d096808d9105ccedff99dde3bd573f2662796664b247b6e86fd8410fff9332217691b9155128c33652f7a6cf743bb0ab50eb788cca19595f71de3cecc1e0785273dad36fc41a8bbc990ca533e077bd5b2692a690ad97690e13a67091deca3cf4808055355ad24e42605e39ab65188200384cab0259ee0657736249dea551925dc288179bfeaf532280a649d4cbf028b0ea4b44772123d8cae78d4e35aad24c1bec579c7ed8016c2100728395a1f989f8083552bdead81405cfd64ce0e847a768522fad74b739121a0fa5311c030c944de270b19c6fb009ab42d5dbb63d045903f8041c78e5c5fb81ac0a43adba14ed07cd0045c9df1fb5dead3cce937316cec2f43d71d597de2bb750df96754b9d53fdd0bca21247ca3e369e32a8ef986fca78f702cafac81993bed92f2e48727b49488fe7f91ba4dea397261319629c7eb8203752a0d884b908302881c4ce38295e700595480f87b52921ece5ce79e0696860d07e53e4595b241a9a2f2844452d75d7eb88271cdaa6121072ce19032036b8dd17bfbdc4816af74e5a863d474d5a868a701967de963f94356ed6eaaef05def1644876da76f8efa0552b6cd455821c2cc821c053441ebabb070ad88925e9910f8e028d7c1451f3ad86ed16800c0a2ebbe0033d31709f6cc9f83a4328992ab69656945ee6d1338c84682183441571bdf1e782bd85fc215f71610277d577ed70ce494e72306a479c61184ac52a822845054c1aeabf1026efbe5b3018b7ac9a587c8fc2e59ea86af90da4aec0ba8a27565fc4a64320829d122e789980a41473332d4a006d67ba37ddf2881b7692321c9f446bc30db87364c245745249a46877dd0896bcb433d07410234b1433a8f8bb56ec9d0119ba30ac7d76f1fc47989a2c9c3d9c7491092fea1ddcac5684929eaca0ec9deead335c6b1203274517fd50150d8e4057e38cbfd071c92723e6ceff7fd59f9f4d31ddcef3dd5b77300080bb278ba576bdf3868b18e1426b2a9ba26d5885a416c7168a66bb09692dbdf4ac7596e050793701baefbf8d356c07ca1036550ccbf1a49162e27197b7781ac555a9df2a167479a62abe3ee19d032fceda508d13694345c8bd772dccb0fc01010e62a067e3e28a14161d973b7ec124171702bc85fe810320e3ab" + }, + { + "seed": "3dfae184b19c5e7b44bf7dc59903f480cf46042d0f279b9ad48934024f16dccb", + "pub": "389f174343c9a7e98d47638a97d7e9771706007efe4d87ae002bf802e51e79a5d75f0f18f14359c66098173ea32cc5d54e470253a1d8cd0203459e15245167c7ccf2679f5e3374f842856ae11a68b09b5afc5c4e2bb310d68a734181645f85eb217cdcecc3b149bcbd27d5df7ae8bd8dbc9ac01543f7d3111dded409f1aac53968c781be497497f0d9a50dcab76158ebdcda232421194a9a81f63ebf6ac406e5d59df7de4edb391ffd0d45e117351f26576702e55061559c9445bec4a17706ed9de17b5879b32cece5e4c23d2a221a2db42f5dcbc7e1057fb97f9369b9b97210347b175d16342882b89ad6ccae4062a068e37eee891ebcd745f77e09ea942c62e1832ba850c20a59bc1c7482112717437da8ce9a0ce48105bea8f2ec816577dc1f88566c764e1eda9b155525056026e56db3410ed1c6e24294e0e10df5ed05a3d5614b1fdb76c386575ad6b94f9d5f61d5b37a445f2f21cbb10db212573b47e32c634496506672c3564daa7efa53297be70ce01c653fbdf977672da8e6544248a7aec0d07e19e0744788867ef85928879904472239fa4cc9aa11d068bfaf455a8accf7852b42d83244db916e0ea3cedf366b675f1b047f41dfe5fabce944bd2f63ad714fe2ed9513235962e0f071119b90f9c2714571542184f83120ace05106bdfaf7359882c74c287a430f5fe15cccae2c52a0a6aedd0dd4d97aebe1bda6277ad4ab6272c1ca4d1de004d6f5a4bf6cace14bf56e5b64d54f57f2f3df07b10f5d032b57b023a9c31cf07077ff075eb7199b5aa8b277ed62113141cf0d9baabb0adcbdcc362ad0ba269eb73f2b50afafb8dc188f52572288ebe367eb64cabd5a049b39673fb89c1f47112d35f15e53665abee143161d7d09f02b6d0611981700dfc800ba8b61bea8fa30727b2ce5a229fef68ac63f01e1092d2dbbb220a20757bc8a4717818f5b43d0003d1e824b44943c97875f2477073f090f2585dd3e5f23db756f46ccdf0e7e1267d13a3320f10dbe7b8c07441c021d84b400512db41c286e268126a6be93e6b4ec47b80e604d4355f2c32bf8885dfb24d9033bf71b9a00422ec6ed356dac04f59db8f31aba54c00082372298248cde2d73576d247b5c5793f09f3f68f2c142f89a1dc8c58a7db91d82b00098331591eed39f30ea82c5a81d95b82cb2a9272ae629708a74a3896058acee21bfb7f9707e5488ea69119f36c0a1f5ae3df33c341a41ad1dc9e88c17c5664ac5c773fc6084880cfc9286b61ee51a870a4aaf0f70bb3f6eceb633c1181926b28fd2affbb06ea90b9e2ddd6ac48d2a25868a6c0b8cdeda8d35d505ee3b0b852d4f06bdf32f16d1d8e44e29ee3c2a51433d550aa0dc88b1336d2ba287a610898ed2c5a92d4b183cd395e84593087f96260f913748cb6e536cfabb38543502f65b6770830fc2577fe4ba876c6b9c875b4e2e95a52c3cb1aa00436630760663c69ea2e437d49f13a6625573d6ed93de1cd05379595ce209759f497fec00c2b94fd9b1948c3bbd89031dad8fb265002c41a81c3949f023edfdf620f33590e2af4ee4fcfa4f9dc5c4c196d41233bde6c4ad002974ec097783a80937f00204b5159b6d7a7ce79a0e926e21cd43befe57c8d42b6f008015a8ba410146b097a63c081eb3537957a32cc048f7b57c44194f8f80d6580f52a369b9a4a0e4e6ca03e67dce3eb45f404739a7065e30cb97eb0d98b60f43209d1d22ac69d889afad6af630f0471e15bb123c9f205e3f373a55ee188a54109d648ebd4824d6e88f01ca4ce4d7e0b12037a251dc0343ef99db3b04e389f48416eb36ecedcac389c2edcfe6ef3e4159ce7a2cdffbd822bde7cedb87", + "priv": "389f174343c9a7e98d47638a97d7e9771706007efe4d87ae002bf802e51e79a54fc92d4c67243d9501b5d5bb3bacc367c973dae95bb621c178bc46efa8d0142469b9ae65edd2c3cc65495d8133a4a0b5176c927c2aba8637e8505f51f0c809eadbabb4ab2e537bf717418860691d5eb547da7b1adac22ee68224ff937639289742940dd4b8490249711c36729c348603171194406902410de3162ee3167112345022a40808b4686140319c482960a04840320e6334320bc370148789d3142da4280cdc844d61b0416214025c100998908418856889b405a3107012b48408c869c1964c88442c8b040a5ab42c9b86811a98405a148ee2188c1a31322206681b060a2313665c126d5308124a4620e0162084a40cd2280ed2042803068d01c56d5212409ca2811c032a02466812a7051847051a85258882419c22691c428514159164440c41140020964dc2107283388408b34d8c40011b0069a0b82188c04d03c62d5046529c226a20484013c78021b771d8242e11c761e3324c542289c9468ee1182994c891e448480827925288859c0282d1900901056dd12012ca340a9108108b329080224824247048c0690b32268304300ca0654ab66da0941064c669d2829003852020062821934c038161e0068223218d59a22550280560244148a42d08138d1cc6118b2828d1404581088920332a51960d82348a5bb8711b304a94046e13068663340c1a96850b260a021246120424d88845a4469111286059b269a446850c927014b04c209511028061c9166c9c34500cb3840a907118004d1aa965c8246882144ed1166662029019328ad9206812062c4a927151241000096e934440a3408661b4500136510c0944131885091948114005dac0911407080b0329cb882409c389d914061c1830c9022cd196059b9884143470522826c22029a0a61118224a49060112406dcb006003138a603492010604e1348149b67091c4650b838d033500019520cca041104321daa64c1cc285c3322a1a152a00984560424d229441039660cb9665541209a410640a0061d4102e84b0050104849928060cc08810170aca462ce2244ae412459a2801a3b208c9302919b32802b068da128800276e59328ae3067062445189166d1216019180682047311bc609448661cc408a0003461941218a86841ac86c89440912078a0b830c820602913029dbc04c11304801236a92966021946991348290346410197141986421b94c044661042591a4a625d6d1acb4b67eecd1bbe15a6dd5c82d5051685006ede6fedc225b94ceacb71633eeac8bd1b050f49ded46deb127b34174fa6f3850a4270f1c2aa165492864be6b12766c5fd216c216160f3f8d69691d8b837c338bc178be83f7d741952f066d8c8a38c19981d8b4b7fdfcb10f649aab588fc88316130ff2d5c50192bd3ea358d8a6c18585ba8471b21c962badc204113e87eec05b3942791a16c5871702e74f00705447278e7ba346e83df28b1591c5a9d4bb01244c26ae513da0a055d81721b7e66bc14a26930436fcba8d22536a13bf4ee84836b1f5b0b7eb7da9aac5fce0800b2b57abe742063be76496f3a31e9239c15f6a447f7893f3ea018fbb415c5e3f1540b631f2a8cb16ea2aa46dff00e64a9f411f8ba4de1f67a0072ffa843004ee00e02f1dc9ea5f28540b31fa95ebff4f42daf3d006c2c91d16d581db050eea461968bcf59e4e781af4c68a181c4ae60a954e9f2779dbfe4a03acb93f68ad2c5680d09bf4141a6bbca65b12f8f9b5641bbc73f56d8fe849cd6898d94ef712747118b406e00f534f60841ff5b0ee16b42b2484b85c73ff80b6bc197a93c8f843873f407c3d5b2855efdd0fc49add2911afb9836272b885873f38eddb3adb336744b379789bbfce9f9d6b52c91b2368ad134009f35ec8c15401e05c6286b4f662e2e460197ef80ac05e67be6824036b0eadc0b1f0657cd384c50f73dbcae14b30389f5c03343ecaf97c1ea438ed713fb116106c589321e21ea24280342339483aa0959fa49384a30ff7d81a6b59cf71311156e5da28b69d51181bdcf955d3a85d84d2734d7cd4ef825db8b3bbc4b7367df28e950a27b94b10c192d51e90a6cd5b3d6ef7dc7f310d671699842d75646c8477edfed05ecfd3a20fe56fa786ddc1c1f0b5ccbf1486057b3bbf4fced7114e67994d44386842fde37fc19ddacdffd8b67356a954eced5c4f7c77d1728eb60b6ff66b61c038177c1f992d65e7abced6bbf5bafb8571de86b18fe7181d688729d4a03549e199ffdb85062320a19fa829bcefd6639be5e43e8b60a7b7fbb3a7fa7cf57f66c3f973b4066da6f0dfa5dd8fb4af125998d5f808938aab11b24561c9e042981d8235dbbca51b4a130e7b9f3c60e5d1edc5c191b1f6407025dbe1146f804bd9ea9270b0b6d4b9dce4dfac9c42d9c75e744f2ea8432c69b35346988d9e625aa4ca3fd20c72aa98a59be5309e99418984fef2df4ed9b54e78887e4505ae0e6f286d24668c765a30325368511f6d756ff37a0152d48d942d3ae32f2f6ef18003d2666be3375adc7e3ced8782b71535da716234f9d074e6d6d49c17f22dd9ee1e1cf3911ce64777147ce2ea4dd0962295ebd49b0f4a57aeec5826146d58398ce55b1f5804901df60ab6ebfaabc612933ba5e40ce4824430616b68e47baa9ffddcebcdd03a8400487c75ec1a1b1e507ba5484f5e4bd347f03d8e57acf5004b5333788087ae22d6868643b4803a99243214754c8cce8a2f0c014c52d2000ce26a08c62c6fc5b45f0ae45b6d3b431f83ea38eb47d34ea0f4b666e8abacfc1b5e8f5759dc5c93694ce33fd498ffa0a505b30394fbb9f953737608e8defdc8369d000cbe1c0912bb0243c42e4b7d48b36d15357334d3b456714d0082798e03758c8ca8177ff0763f80f57639eda9b05fe3d6d36ba427223895f49c46c12334b1ef1f324ededf3e5c413d6e1628c0d481f86809a5e8f32bc7e5da7ee88afdfd1d59e510a99ac70d75ae633abe1979ce17f24b8f3726c9cdc7c09d4d9f1059cb8e657b026f18eb04130282922501b2255c874fdf19299a44d00d8e83a6cac9a126f6ff04e4cdf5674e6e2b040248d1afcc8d97db4bbf062d080230aaeb8fc1ddd9f86d2069ff6cf8a1eafe919cdf6d1ae66479cf50bd08f6941475d2a819ee1f58e972324d6730f9b908259035bb89316814cf45aef0099f2a9b21c77dba9c71b3badc6ab5e50a379d2383df56d6ba855245462b1148761ad09eaa29ea4546d7d91852fa28439bac4dccc6b07f361ee0d1e2d6b8542717a7bd43377931b82020a8166d99c5eca6278404fc68c3c1397b146176ef15a5440684b436f6738e987d2df052285a1381af09d5f4adf14872a53cfb11c8d168be37deb859bd6db65c593f67ddf2d737ecb53d8c8250719621c19090afb70505e2becc2ffcf3ffb0b3b56b909390b7ee6655a155a4f49f24692bb02e1c259301add2314b9b3cc07ed0ba4a90ae9ec2be69d7405f8775df8d040ae8c0f656420a6a2e83ac4fce515cf27e0a5b5d0c1e76cd1d08eab7e8cc390ce32ae17be28c365599e51c45d1d9927ad8ffc3d3f6a800ef0ba91f42adce90cccc64b46686" + }, + { + "seed": "821229e3226bb7a7774bfc3c3593da9c4de76255374cc4b13f9f62860e0c3e06", + "pub": "d56225f685bff9271174e8b1e87c7d5717848a0a5dc1b7a463d55027a7e0c0c6ab64771db20d5302deab324cf9a45172d5143b85ae0628535c404fd1d18b20dc9e8c3203b846574c28dc138fd54f3971f64c2dca154bb1760ca34153474dfe15ed30d653c508669f88f77d25eaa27d3e5bea76d86468e317a874fb245b4d8aa645f3fc3f84ca741be38bd25ca82d17e0c522cb6afdd1f4ccc5aed8ce7b8dddad205ea450699e82c31486cf8c629dbd50bf5c22c9e0e6d46135f6afd5500b4b6494fca1446f8fa796314fef71cf0f3537ed4da25cfaa1b8d7d04780f0073d2fc8e93aa779ac849d5fab2959589d988e82c675dfa440713ec87854fdb20b58290e798305e337629d9c1a73a950dd23fca16482a35b672ec6b3b6699023f26e9fa5d10bc5c42ea491a52fabc3504fca7d3e6368360b894c89b9fdef1df96714d2c467f634a01426973f6185409087c3fb650aa5543de1e7682088f492b0b34f86708914b5ed033632bcf832322d34f9aeb402bd2ee5d8ee860e1544355bb080a5a344fb9e19543d5e10448b997d1e5a0f63b264439dfdcb2203cdc66f96302769b7ea237a078aa6c735a0f72675d74022d0bc66c3620ea92f90d012f611940c5c9b2b2adaacd2211e11343a1301ed9071aa561c129565627d60c538fef847aaa434b13034d91179d66ab75a6d5651535fd8a9c76a4f40fe24c1950cd74b40d14ba7f3c30b71610f3d04e3e4829e8109cd322e43eb0ed9c34ab8975b310f11c87aced092ecc183f8e4544a6e762832afecbcedce21fb0a61f899dbc0c5de2b9f682d43129a23ecd9f09b7296ed785575ee607050e498e33235199b45d96635c0cc7beea6dbe9deac915785106a0c0a4bc8bdb1fa2a04a893abcfc9bb544f21f86f643346d446fda8d6684689c412ab537615ee70afffc070c3cb90d5991cee41c0c8e032d45be3cd241009b6e27f9ece9ab8804e263f3c558b7952b2554e352f310765a907106e6b85b81125e8ca13d5e1c2f80c252793be931fd84b6c74e1b647636d085ecb2a85be8abcaed676fbf61da7eb189659b11594464d9d675cbd1c1a4a5668aeb2e5d467effed9abb72aa41e1b775fc8e0681043c7e44b0de5297fa7c6d45b44a7fd93e082545712b1a0ba3b2f859652fa16649c18005f43662d81b7917231d85105179305eba5748cfcbca8f75aa9c9577913eed325221dea1683790629c991034b91781f10a8d95033b77ee30155e66b6ab913105a534393151988a8f34cacd2d675b93203a1cc24f1dfb3db70e03bed92b6b388989b5086e233ba8587f27fbc497433ba77a083c462203898cbffc5686b8e7f331ab1cba43fb2f4f2caeb1af101d2d5aea49bd843a9531bafad4d7ad563860c2ac2f57bc48da216dac140f28302debc7f7c8d508a04d5d380a5ece965d1a4c2abc6435082f503310fd0388c9a35e96335bdd5e7b02d58633a889ef2731e248cc0f8b5b022cd671a77b055e3c012417a45d48987553101703b81012cf131fe1fd686790569579dfeef9773e58e554bb898cd171b41cc0d593f0a0bf370555d3d84a04d99069ba964f5c5b09599a6fa175e449f5b39a9a42c9480ef7d6cfaca68a67eeab49cede9478e5f3fa48d9d4bca0b1153e903584148ad1114ad22da94da5aedd63b526f6559cd4fc73f95ae1c79a8f4fca429dc0c5d0bf4be7a6dcb36245f9c51f6775fbbe1a53895112afeaa4acfec96c80818d00b658e8d3b9d5f7bff820a2be8d20ed95bb14e9410a5473360f3d8112415b873d82253eae8417ed29f66ba8b44fb0cedf4d73fd757c97691ed0ebf685e3e266cd1e4cc8a31857d585239d2b8c45b369b7514", + "priv": "d56225f685bff9271174e8b1e87c7d5717848a0a5dc1b7a463d55027a7e0c0c631029a583d4ec308d185c5ca1a535d0de55012f63013a7b74cf941ca069bb010a2e604b882ad9a6fcb9822f9b0f08efef0fc8bc2808da6e1bde9b1c8d54fe8486b43eb5b64cc5262ab2ecad6685964fe9b131480c386104eaac804ac7629702251264994c8409106011c448d63846d83000d011770e3204e53828d03910c23814d14c50813285013300453b411a1188d831632c9424553166e14082809030080144421a21020342d52422e4348408b244c4ac89164164dc1902502c8690888101c0012a0040e11b160d93680e11432883088241272a0a48d13842c51340114138ac0a20d8b90401b4165180589e0c26422a7095226469a362593886d01410563c68909a70161106e8bb48d21b7719c282e0947080941710b99889cc40801392e80842114070418b064cca408c82652ca2681d9b08892366c12c960cc3220ca926dc29228a012689b3246223580999401c3022ecb3470c1440ec9244d4110400006051214865898014a428a12358ed22080e3b6440bc551d832681a09510838021248221285800bb0918b345089b00080a00d09b645913824c3b0444044268a9260e3c28980c090ca906522124a8848648b985020972c20222650066544a6210a078618132ec42871202726d1b844cb2002e4a6119418411a3828a14410014230190426e02628c2884419040408078511224de3367091a82c0c374e8a082e19c690532830d2c271d400518cc04998244841260192b65011256d0c352802338c94b430da101099484a4ba86d5ab02981c8880c264dcaa6511b155213374ea40024c9209248144c18018cd01652504668e33609e1b6715a36444a94209ca62909b348d3b471a0486202050e812266dc404840422ee1280411c364a1148d81c89019296d8b460a62348cc4084ecb004003410e419461632640093149a314728b186d122348119250d1a6908bc6610ca4510a340808924d1cc01090468688485012b55160a485c4b44dd2380c184909da12619a8801db209204929092206cd10429dcc0650c0942d400691b2505c0a4719286606244601b956d21326094164813106659480621234d1c894451c4605a1289c0084583800c8c988002168993224e1933125c882402072a08342991408aa0b8892148124138218488640934504c325010a088e1386908462a60942103c4654848665a208664427009b6511449804b8880063a2ac026a3394c43b5226567228896fd2cbb52d02f8df3f2e893c880cfa06d6c46f8b32714815af86ff48422e54c684587a1d882d39ce4e8333b5480a367b7cb879a67ec170db468ef94146241ea286663a2833ceb75fd301ad6869c75ed748f7b0d890a82fe1cd9c7e32475f60f4d4cf8e222e60900278f5d8821dcbd9f17cdaab7b43807e7947828559969083f973674f054faf64d4506adf9d36d35a82ac942aff596834dd4482dcf7a80643f3bb5eb7a8eaf744c2a68e9f71fb17ea7f2feafdf659a247b1368c50c30d19d68fd9ed923ed035089a67f7cce25ab62fb33afbfb48affcaa0b1890c0c3cca4c2504b70e8badc9a87957ebba3e4fd80cf96aaac2eec6de60e015813f1eeb4fcc0d77ffd1e293549e6f579460a5921f794538271344d34143c1d699e5df15871c8a03a5bc77951b374656017539c6abc7677e9d2a9ad37ebd8e032a7454eb3ccd9194e6f2b47a4b5f3b48aaec1abf166a3f81d5f533a8b189e92199307d983d1cb2c1282f48509a05c56db952e39584d0028b0a6fcf94ce096d8687123937b84272d48d7720d8d0385b17ba624863efe0f008857306ae44da5d1cb8a98380b6e52db920f1a4c942c634b87db67e559cfb8ed1b43908c6dced9f00fb185389cddc1adf787c1df06522b74801541a310bdd2fed22270e04f433b387e016e1ec5e5a9996e82b6e5bce9e417ac799130ae90a261de9c7d50e69f1a85c269d9a59f1514fa350441213e2780fafa76468340cb349342a2e37f780bb32ff3ce1e981e00f7aab78c1e2e81adc6327f2dfa9d4513e9f5b6404b933ce8d4d65efa4750905606e4515b5073b6a5041c643ecad0cbe83af72c844295cca158c7527b2fbd21010858b8fa72db16b165cb51b3d071c25e51f192341881fef2e5ab2f7dd7398d1fe76c59f0bc35db5e529428919c35ff49be2ce5378db81c290fbbfbd719d2a71048d0c5da78c9b21f8907cd7a319f92730381afb6dd229fbc58bc10a56c55d43de4864bdb04b4fa8113da209a39ff914014eea30befe582798bf8edaf7fe55e52d1710a728dea2a7c2eff0dc69c39c43ed26d5c314b4d34367acc055aefbcd7f995c0fe310e1f5654395862e498fff488467bfc56bef1ed761ba4233bbcde8d2d4c1ad15e68299fae4f037e4e49f6dc49095bcee4fc4fd83cdfe715230c9f763f904f250abf93b25b9a08d69fa257da73d81403ac195154c0ad02364e1f284f144157259be6574269035cba5a1dafbe04c2625597adda138f1e7d769a1b05c4ba72f452c732ce1286f13b995f0c111ba700589ffb143b10d58bf48555be55a9ce6325934e3247ffb22aaaa1fe89d57a6669a689a033d53b8f2383096c14b22e6b7be3056b19277fa01565a79cb97f207ae55b935c011f68cd395e865af7be570a17575ad92acc454936b5beb748312925dafad96f073790d00b9fca86a4a3671637c9b4826d1ec2f59678526b0f4c9dbde27f34193f6b53e488cf6ccad9561f4ea0b575b9ea4322e3690a826bd3ac718602f01f91e903414254e7221a84ea764d3a95b7428fbeb2ab2da0ffe079c7aa788e367bad8fae71f0f83498dc36e8db57fddfc3ea5e53ea0878c2cc9b36cc4d5619239cd1f526ae625bac5fa2413688d6615becd2ba322efc5a066759087ee3862307630781cac102a7fb772d8c90c9233a4451a63c1009121b00ea0a6d3af4612fb7faeeec4e100fa44fb23c6cdfdd2666d55815e7170d934b9c26e3945dc6d0355b598886e0cc399a789e47a8cf8ed4ffa1a1f86f7ee6b6b535ca26acc5ebeb3262ad40cd4bb330b1fc926ba202a65faa42252a78da797caa822e4fa45f5e449b10dbf0654482292dd29db11b5dc1d2ced5814c373d94de7bb64098ed3101ebfd847c51c4c90d5ae8e5f07636cac1950cf4eeeb191c329ffc95f3d3767b56e65991039fb7ac6786d573c56273aae78e53d4a642e020b27d2c961305bfef66d5818d504fb4533c4faba7fd594919b96f20a44baca34173aa9bfe115ed6b5bf6f03ecbd004d3417d6dedfbeb7508612bdb90afa7f61e838ced2a13c6e5bcdad3a3d4377bacaa20835352d71f6e7722bfc61a8430a82afe4ee3acebe407aec930fefbfd387f696ac1021325f5a5792b9fd5ad2c5d57acc496a9b0fb264ae2e0d5c37b1b719d7a6b1077e3fa531c2a584562764b1a76409c3421c8d6a40a80a55d49da80a5e9afcdc6766f1721408dfd5ac34b1301128d374e085456e2831c7c7fdde3cb4698708ed8f447d59201e017ea7552f53c4e62d61e4a69cbd3116c193b4304f80f828068fb3e47e704c1c62f9f4c0baf5cd69e6c113afd90cf1238ce8c7c783d" + } + ] +} \ No newline at end of file